Skip to content

Parameters ​

input_params.countries ​

Country reference table with border polygons.

ParameterMeaningUnitUsed in
country_codeTwo-letter country code (ISO 3166-1 alpha-2). Primary key.——
country_nameFull English country name.——
country_geomCountry border polygon (SRID 4326) covering the country's land area AND its maritime zones (territorial sea, internal and archipelagic waters, EEZ) — seeded from the Marine Regions union of the ESRI country shapefile and the Exclusive Economic Zones, v4. The maritime coverage is what attributes belt, strait and tunnel crossings to a country instead of the UNK sentinel: this is a routing-attribution geometry, not a cartographic land border. NULL for countries with no rail network, which no route can transit.——

input_params.country_relations ​

Which pairs of countries are close enough to each other for one night train to plausibly connect them — the candidate set the proposal statistics rank top and flop relations over (GET /api/proposals/stats). One row per unordered country pair, measured between each country's reference station (the catalog stop closest to that country's stop centroid) and routed on real track, so sea crossings that force a long land detour drop out on their own. Derived, rebuildable data, NOT hand-maintained: scripts/build_country_relations.py rebuilds it from the pinned stop catalog, and countries with no stops in the catalog yet simply have no rows.

ParameterMeaningUnitUsed in
country_aFirst country of the pair — always the alphabetically smaller code, so each pair appears exactly once.——
country_bSecond country of the pair — always the alphabetically larger code.——
ref_stop_aReference station used for country_a: the catalog stop closest to that country's stop centroid.——
ref_stop_bReference station used for country_b.——
great_circle_kmStraight-line distance between the two reference stations. Only used to decide whether routing the pair is worth attempting.km—
rail_kmDistance on real track between the two reference stations. Empty when no rail path could be found.km—
rail_time_hTravel time on that rail path, for a future travel-time-based threshold. Empty when no rail path could be found.h—
routing_statusWhy this pair does or does not carry a rail distance: routed, prefiltered (too far apart to be worth routing), no_connection (no rail path exists), gauge_mismatch (the two reference stations share no track gauge, so no through service is possible), or snap_failed (a reference station could not be placed on the network).——
stop_infra_versionStop catalog snapshot the reference stations were picked from. Resolved via scenario.scenarios.stop_infrastructures_version — never inferred.——
built_atWhen this row was last rebuilt.——

input_params.sources ​

Registry of data sources. Every parameter row can point to the source its values came from, so every number in the tool stays traceable. One row per source document or dataset.

ParameterMeaningUnitUsed in
source_id———
source_descriptionHuman-readable description of the source (e.g. "DB Netz Trassenpreissystem 2025").——
source_urlOptional link to the source document or dataset.——
source_dateDate the source data was published or retrieved.——

input_params.ticket_vat_rates ​

VAT on rail passenger tickets, per country: the rate on a domestic ticket and the rate on the country's share of a cross-border ticket (0 where the international leg is exempt). Calibrated by models/demand/calib/vat/vat_calibration.py (VAT_CALIBRATION.md). Display-only: the cost/revenue model prices net; the frontend applies these rates distance-weighted over a route's country shares to show what a passenger pays. Not versioned — a rate change is a reseed, like the composition catalogue; a VAT-exemption measure (WP17) would override it per scenario, not rewrite it.

ParameterMeaningUnitUsed in
country_codeTwo-letter country code (ISO 3166-1 alpha-2). One row per country.——
vat_domestic_perVAT rate on a ticket that starts and ends in the country, as a fraction (0.070 = 7 %).——
vat_international_perVAT rate on the country's distance share of a ticket that crosses a border, as a fraction; 0 where the international leg is exempt (most member states).——
vat_statusProvenance: sourced / assumed / no_railway / blocked — see VAT_CALIBRATION.md.——
vat_noteWhat the rate is and where the international treatment comes from, in one line.——
vat_srcSource for both rates.——

input_params.service_classes ​

Accommodation class taxonomy. service_class_main groups the detailed classes into: Seat, Couchette, Sleeper, Capsule, Catering.

ParameterMeaningUnitUsed in
service_class_idDetailed class name (e.g. "couchette (6-berth)", "Sleeper (2-berth) with shower & WC").——
service_class_mainTop-level accommodation category: Seat, Couchette, Sleeper, Capsule, or Catering.——
service_class_is_night_accommodationWhether places of this class make the train count as carrying night accommodation for tariff purposes. Germany prices such a train at its night rate over the whole German run (see track_tac_night_full_if_accommodation). True for every class a passenger can lie down in; a dining car alone does not make a night train.——

input_params.operators ​

Train operating company and its cost rates. A catalog, not history: operator_id is a permanent natural key — changed rates mean adding a new operator_id, never editing a row in place (soft-referenced from coach_types and composition_types).

ParameterMeaningUnitUsed in
operator_row_id———
operator_idOperator identifier (e.g. STD-REF, STD-NEW).——
operator_nameFull operator name.——
operator_driver_costs_eur_hDriver pay per PRODUCTIVE hour, i.e. the raw wage rate before roster inefficiency. Evaluation divides it by the Dienstplanwirkungsgrad it computes per trip from the four roster columns below.€/hdriver_eur
operator_crew_costs_eur_hCabin crew pay per PRODUCTIVE hour, per attendant, before roster inefficiency (same treatment as the driver rate). The train manager is counted with a factor on the composition.€/hcrew_eur
operator_driver_max_duty_hLongest driving time one driver may work between daily rest periods. Directive 2005/47/EC sets 8 h on a night shift (9 h by day); national agreements may be stricter. A trip whose driving time exceeds it needs a relief driver, which lowers the roster efficiency.hroster_efficiency_driver
operator_crew_max_duty_hLongest working time one onboard attendant may work between daily rest periods, per the applicable collective agreement. Same relief mechanism as the driver column.h—
operator_driver_roster_eff_refDienstplanwirkungsgrad for a driver duty that needs no relief: the share of paid hours that is productive once sign-on/off, reserve cover and leave are absorbed.fractionroster_efficiency_driver
operator_crew_roster_eff_refDienstplanwirkungsgrad for an onboard duty that needs no relief. Higher than the driver value: onboard links position less and rest away from base more predictably.fraction—
operator_relief_allowance_hUnproductive hours added per relief event — positioning to and from the relief point, the extra sign-on/off, and away-base rest handling. Applied once per additional duty beyond the first, for both roles.hroster_efficiency_driver
operator_ebit_margin_perOperating profit the operator requires, as a share of ticket revenue.fraction of revenueebit_margin_eur
operator_financing_quota_perAnnual financing cost as a share of the capital tied up in coaches.fraction/yearfinancing_eur
operator_var_overhead_perVariable overhead — ticket sales, distribution, customer service — as a share of ticket revenue.fraction of revenuevar_overhead_eur
operator_fix_overhead_quota_perFixed overhead — administration, management, planning — as a share of all other operating costs.fraction of other costsfix_overhead_eur
source_idSource for all values in this row.——

input_params.operator_class_costs ​

Onboard service cost per operator and accommodation class.

ParameterMeaningUnitUsed in
operator_row_id———
service_class_id———
operator_class_svc_stockings_eur_placeOnboard service cost — bedding, breakfast, amenities — per sold place and trip, for this class.€/placesvc_stockings_eur
source_idSource for all values in this row.——

input_params.coach_types ​

Individual railcar/coach types. Capacity is derived from coach_type_classes, not stored here. A catalog, not history: coach_type_id is a permanent natural key — a changed spec means a new coach_type_id, never editing a row in place.

ParameterMeaningUnitUsed in
coach_type_row_id———
coach_type_idCoach type name (e.g. WLABmz, Bcmz, type1).——
coach_type_operator_idOperator this coach type belongs to (soft reference to operators.operator_id). Empty for generic/shared types.——
coach_type_weight_gross_tGross weight of one coach of this type.ttrain_weight, stop_dynamics_time_loss
coach_type_length_mCoach length over buffers — basis of the per-metre purchase price and of the composition's total length.m—
coach_type_has_wifiCoach offers WiFi. A composition offers an amenity if any of its coaches does.——
coach_type_length_wo_service_mCoach length excluding dining/shared service areas — the passenger-space basis of the class cost split.mclass_main_allocation
coach_type_weight_wo_service_tCoach weight excluding service areas.tclass_main_allocation
coach_type_bikesNumber of bicycle spaces in this coach type.——
coach_type_climatizationWhether this coach type has air conditioning.——
coach_type_plugsWhether this coach type has passenger power sockets.——
coach_type_crew_factorCabin crew this coach needs, as a fraction of an attendant (0.5 = one attendant covers two coaches).—crew_eur
coach_type_remarksFree-text remarks.——
source_idSource for all values in this row.——

input_params.coach_type_classes ​

Places per accommodation class within a coach type, with the class section's share of the coach.

ParameterMeaningUnitUsed in
coach_type_row_id———
service_class_id———
coach_type_class_placesNumber of places of this class in the coach type.placesclass_main_allocation
section_length_mLength of this class's section within the coach — basis of the class cost split and derived per-class densities.mclass_main_allocation
section_weight_tWeight of this class's section within the coach.tclass_main_allocation, station_charge_eur
section_crew_factorCabin crew this class section needs, as a fraction of an attendant.——
source_idSource for all values in this row.——

input_params.composition_types ​

Train composition blueprint: which coaches, at which speed, with which cost parameters. Capacity comes from the coach list (composition_type_coaches → coach_type_classes). Which locomotives it hauls comes from composition_type_locos; they are rented, not purchased, and the rate is per operator and machine (operator_loco_costs). A catalog, not history: composition_type_id is a permanent natural key — new settings mean a new composition_type_id, never editing a row in place.

ParameterMeaningUnitUsed in
composition_type_row_id———
composition_type_idComposition name (e.g. STD-3.1).——
composition_type_descriptionShort human-readable description of the composition.——
composition_type_operator_idOperator running this composition (soft reference to operators.operator_id).——
composition_type_hsr_allowedWhether this train may use high-speed lines at all (combined with each country's own permission).——
composition_type_max_speed_kmhMaximum operational speed.km/h—
composition_type_min_boarding_timeMinimum waiting time this train needs at stops where passengers board.interval (hh:mm:ss)dwell_time_boarding, dwell_time_both
composition_type_min_alighting_timeMinimum waiting time this train needs at stops where passengers get off.interval (hh:mm:ss)dwell_time_alighting, dwell_time_both
composition_type_purchase_coach_eurAverage purchase price per coach, from the per-metre price model (new 145 / refurbished 53 k€ per metre of coach, double-deck ×1.12) applied to this composition's coach lengths. Derivation: calib/CALIBRATION.md.€/coachcoach_amortisation_eur, financing_eur
composition_type_coach_avail_perShare of calendar days a coach is available for service (the rest it is in the workshop).fraction—
composition_type_coach_amort_yearsUseful life over which a coach is written off.yearscoach_amortisation_eur
composition_type_cleaning_eur_dayCleaning and preparation for the next night, per coach and operating day, at 2032 prices.€/coach/daycleaning_eur
composition_type_coach_maint_eur_kmCoach maintenance for the whole train per kilometre (per-coach rate × number of coaches; new 1.00 / refurbished 1.30 €/coach-km, 2032 prices).€/train-kmcoach_maintenance_eur
composition_type_driver_factorNumber of drivers required per trip (e.g. 1 or 2).personsdriver_eur
composition_type_zugchef_crew_factorTrain manager, counted in attendant-equivalents (1.19; 2.38 for trains with 10 or more coaches). Total crew = sum of coach crew factors + this factor.attendant-equivalents—
composition_type_length_cost_propWeighting X of the class cost split: X by length, (1−X) by weight, on passenger space; service areas are split per place. See calib/CALIBRATION.md.fractionclass_main_allocation
composition_type_food_and_beveragesCatering concept (e.g. 'dining car'). Coach amenities aggregate separately.——
composition_type_material_strategyRolling stock family: 'new' (230 km/h-capable, 30-year write-off, 0.909 availability) or 'refurbished' (200 km/h cap, 12 years, 0.80). Selects the matching operator row (STD-NEW / STD-REF) and parameter family — see calib/CALIBRATION.md.——
composition_type_indicative_cost_eur_train_kmIndicative operator cost per train-kilometre on the 1,000 km reference route (14.5 h trip, 350 operating days, 2 trainsets) at 2032 prices, excluding infrastructure charges, energy, variable overhead and profit — a comparison figure between compositions, not a route evaluation. Derivation: calib/CALIBRATION.md.€/train-km—
composition_type_indicative_cost_ct_place_kmThe same cost basis divided by the number of places.ct/place-km—
source_idSource for all values in this row.——

input_params.loco_types ​

Locomotive types — the physical machine, independent of who runs it. Weight and speed live here; the rental rate does not, because it is a commercial term that varies by operator (operator_loco_costs), exactly as onboard service cost varies by operator over service_classes. A catalog, not history: loco_type_id is a permanent natural key — a changed spec means a new loco_type_id, never editing a row in place.

ParameterMeaningUnitUsed in
loco_type_row_id———
loco_type_idStable natural key, e.g. VECTRON-MS-230.——
loco_type_descriptionMachine and configuration in plain words, including the national class designation where the calibration pins one and an explicit note where it does not.——
loco_type_tractionTraction system, e.g. 'electric multi-system'. Not yet read by any model — recorded so a future electrification or traction-change model has it.——
loco_type_weight_tMass of one locomotive. Completes the gross weight the weight-dependent track access charge and the traction dynamics both work on — coach weight alone is not what gets hauled or weighed.ttac_eur, stop_dynamics_time_loss
loco_type_max_speed_kmhDesign maximum speed. The composition's own max speed still governs the timetable; this records what the machine could do.km/h—
source_idSource for all values in this row.——
change_logFree-text description of what changed in this version and why.——

input_params.operator_loco_costs ​

Locomotive rental rate per operator and machine — the locomotive counterpart of operator_class_costs. A pairing with no row is not priced, and the loader refuses to resolve a composition that needs one rather than substituting a fallback: a missing pairing is a wiring error, and a silent default would hide exactly the mistake this table exists to catch.

ParameterMeaningUnitUsed in
operator_row_id———
loco_type_row_id———
operator_loco_lease_eur_hAll-inclusive rental rate (maintenance and insurance included), billed per hour the locomotive is in use.€/hloco_eur
source_idSource for all values in this row.——

input_params.composition_type_locos ​

Ordered locomotive slots per composition type — the locomotive counterpart of composition_type_coaches. The number of locomotives is the number of rows here, never a stored column, so the two cannot disagree. position expresses machines hauling TOGETHER (double heading); a traction change part-way along a route is route-dependent and cannot be expressed on a composition type at all — that belongs on the trip when it is modelled.

ParameterMeaningUnitUsed in
composition_type_row_id———
position1-based position in the consist.——
loco_type_row_id———

input_params.composition_type_coaches ​

Ordered coach slots per composition type.

ParameterMeaningUnitUsed in
composition_type_row_id———
positionPosition of the coach in the train (1 = first coach behind the locomotive).——
coach_type_row_id———

input_params.track_infrastructure_defaults ​

EU-average fallback track parameters, applied wherever a country's own field is empty. Version bumps are full-table snapshots, resolved via scenario.scenarios.track_infrastructure_defaults_version — see db/README.md for the versioning contract.

ParameterMeaningUnitUsed in
track_infra_default_id———
track_infra_default_keyIdentifier of the default set (e.g. 'EU').——
track_tac_eur_train_kmIndicative track access charge for the reference night train — a single headline number for display and comparison. The cost model does NOT read it: it prices track access from the calibrated component columns further down.€/train-km—
track_tac_srcSource for the track access charge.——
track_parking_eur_dayIndicative cost of one stabling occupation for the reference train — a single headline number for display and comparison. The cost model does NOT read it: it prices stabling from the basis and rate columns further down, against the actual layover and train length.€/occupation (EUR at 2032 prices)—
track_parking_srcSource for the parking cost.——
track_shunting_eur_eventAll-in cost of one shunting movement: what the infrastructure manager charges plus what it does not supply. Roughly nine tenths of the figure is the market cost of a shunting locomotive and crew where the IM sells only facility access — see the calibration document.€/event (EUR at 2032 prices)—
track_shunting_srcSource for the shunting cost.——
track_energy_price_eur_kwhTraction electricity price: the day rate, and the rate around the clock for the twenty-five countries whose tariff is not banded. Where a night band exists the cost model prices the in-band share at track_energy_price_night_eur_kwh instead.€/kWh (EUR at 2032 prices)—
track_energy_price_srcSource for the electricity price.——
track_terrain_categoryRough terrain classification: Flat, Hilly, or Mountainous.——
track_terrain_scoreTerrain difficulty score — hills and mountains increase energy use.1–100—
track_terrain_srcSource for terrain category and score.——
track_hsr_allowedWhether night trains may use the country's high-speed lines.——
track_hsr_srcSource for the high-speed permission.——
track_min_boarding_timeMinimum waiting time the country's stations need at stops where passengers board.interval (hh:mm:ss)—
track_min_boarding_srcSource for the minimum boarding time.——
track_min_alighting_timeMinimum waiting time the country's stations need at stops where passengers get off.interval (hh:mm:ss)—
track_min_alighting_srcSource for the minimum alighting time.——
track_buffer_quota_perSchedule buffer added on top of driving time, reflecting how congested and delay-prone the network is.fraction of driving time—
track_buffer_srcSource for the buffer quota.——
track_tac_b_dayBase day rate of the minimum access package. Empty means the country levies no distance-based day rate.€/train-km (EUR at 2032 prices)—
track_tac_b_nightNight rate of the minimum access package, charged on the share of a run falling inside the country's night band. Empty means the country has no separate night rate.€/train-km (EUR at 2032 prices)—
track_tac_gammaWeight-dependent term, charged on the whole consist — coaches plus locomotives.€/gross-tonne-km (EUR at 2032 prices)—
track_tac_seat_kmCapacity-dependent term, charged per place the train offers (Spanish corridor surcharge).€/seat-km (EUR at 2032 prices)—
track_tac_per_stopPer-stop element of the path price: stopping and restarting consumes path capacity (Swiss Haltezuschlag). NOT a station usage fee — those are stop_infrastructures.stop_charge_eur. Charged at each stop's own country rate.€/stop (EUR at 2032 prices)—
track_tac_revenue_shareShare of the traffic revenue earned in this country that the infrastructure manager takes on top of the distance charges (Swiss Deckungsbeitrag).fraction—
track_tac_fixed_per_train_kmFlat administrative add-on charged per kilometre alongside the base rate (Luxembourgish path administration).€/train-km (EUR at 2032 prices)—
track_tac_peak_multiplierFactor the day rate is multiplied by on the share of a run falling inside the country's peak bands (Swiss NZV: 2).factor—
track_tac_congestion_surcharge_eur_kmFlat surcharge on congested sections, charged on the share of a run falling inside the peak bands (Austrian überlastete Schienenwege). Kept apart from the multiplier above so a congestion charge can be shown as one.€/train-km (EUR at 2032 prices)—
track_tac_night_modeHow the country prices night traffic: 'none' (one rate around the clock) or 'time_band' (the night rate applies pro rata to the time a run spends inside the band below).——
track_tac_night_band_startStart of the national night tariff band, local clock. Bands may run across midnight (23:00–06:00).time of day—
track_tac_night_band_endEnd of the national night tariff band, local clock.time of day—
track_tac_night_full_if_accommodationGerman SPFV Nacht rule: when true, a train carrying night accommodation (couchette, sleeper or capsule) is priced at the night rate over its ENTIRE run in this country, not just the part inside the band.——
track_tac_peak_band1_startStart of the first daily peak band (morning commuter peak), local clock.time of day—
track_tac_peak_band1_endEnd of the first daily peak band.time of day—
track_tac_peak_band2_startStart of the second daily peak band (evening commuter peak), local clock.time of day—
track_tac_peak_band2_endEnd of the second daily peak band.time of day—
track_tac_peak_weekdays_onlyWhether the peak bands apply Monday to Friday only. The model knows a departure's clock time but not its weekday, so such a band is charged at its expected value — five sevenths of the overlap.——
track_energy_price_night_eur_kwhTraction electricity price inside the country's night tariff band, charged pro rata on the share of a run that falls in it. Empty means one rate around the clock (AT, CH and HR are the only banded tariffs). Never resolved from the defaults row, which leaves it empty: a banded tariff is a national particularity, not a gap to fill.€/kWh (EUR at 2032 prices)—
track_energy_night_band_startStart of the national electricity night tariff band, local clock. Bands may run across midnight (22:00–06:00). This is the ENERGY band and is independent of the track access night band (track_tac_night_band_start): Germany bands the track charge 23:00–06:00 and does not band electricity at all, Switzerland the reverse.time of day—
track_energy_night_band_endEnd of the national electricity night tariff band, local clock.time of day—
track_energy_catenary_eur_train_kmCharge for using the catenary and traction power-supply installations, where the infrastructure manager levies it per train-kilometre (FR, HR, HU, IT, LT, LU, LV, PL, RO). Empty means not levied in this unit — either not levied at all, or charged on weight in the column below, or already inside the energy price. Never resolved from the defaults row: roughly half of Europe's infrastructure managers levy this charge, so an uncalibrated country is priced without one rather than given an invented median.€/train-km (EUR at 2032 prices)—
track_energy_catenary_eur_gross_tonne_kmThe same supply-equipment charge where the infrastructure manager levies it on the weight moved instead (FI, GR, SK), charged on the whole consist — coaches plus locomotives.€/gross-tonne-km (EUR at 2032 prices)—
track_parking_basisHow the country prices one stabling occupation: per metre of train length per started 24 hours, per started hour (length-independent, as Germany's Anlagenpreissystem is by design), a flat charge per occupation with no time term, or 'none' where the network statement documents that no siding charge is levied.——
track_parking_eur_metre_dayStabling rate where the country prices by length and time. Empty means it prices in one of the other units.€/metre per started 24 h (EUR at 2032 prices)—
track_parking_eur_hourStabling rate where the country prices per started hour, independent of train length.€/started hour (EUR at 2032 prices)—
track_parking_eur_eventStabling charge where the country prices one occupation flat, with no time or length term.€/occupation (EUR at 2032 prices)—
track_parking_free_hoursFree stabling allowance before the charge starts. Material where it exceeds a layover: Norway's 48 h and Croatia's 24 h zero a twelve-hour turnaround entirely.hours—
track_parking_hotel_power_eur_hourPower the train draws while stabled, charged on ACTUAL stabled hours rather than on the billable hours after a free track allowance — the electricity flows whether or not the siding is free. One European proxy rate, from DB InfraGO's unmetered Elektrant flat charge.€/stabled hour (EUR at 2032 prices)—
change_logFree-text description of what changed in this version and why.——
track_infra_default_versionPer-table full-snapshot version number. Resolved via scenario.scenarios.track_infrastructure_defaults_version — never inferred.——

input_params.track_infrastructures ​

Country-level track parameters. Empty fields are resolved against track_infrastructure_defaults by the loader. Version bumps are full-table snapshots — every country's row is duplicated forward on any single-country edit — resolved via scenario.scenarios.track_infrastructures_version. See db/README.md for the versioning contract.

ParameterMeaningUnitUsed in
track_infra_row_id———
country_codeTwo-letter country code (ISO 3166-1 alpha-2).——
track_tac_eur_train_kmIndicative track access charge for the reference night train — a single headline number for display and comparison. The cost model does NOT read it: it prices track access from the calibrated component columns further down.€/train-km—
track_tac_srcSource for the track access charge.——
track_parking_eur_dayIndicative cost of one stabling occupation for the reference train — a single headline number for display and comparison. The cost model does NOT read it: it prices stabling from the basis and rate columns further down, against the actual layover and train length.€/occupation (EUR at 2032 prices)parking_eur
track_parking_srcSource for the parking cost.——
track_shunting_eur_eventAll-in cost of one shunting movement: what the infrastructure manager charges plus what it does not supply. Roughly nine tenths of the figure is the market cost of a shunting locomotive and crew where the IM sells only facility access — see the calibration document.€/event (EUR at 2032 prices)shunting_eur
track_shunting_srcSource for the shunting cost.——
track_energy_price_eur_kwhTraction electricity price: the day rate, and the rate around the clock for the twenty-five countries whose tariff is not banded. Where a night band exists the cost model prices the in-band share at track_energy_price_night_eur_kwh instead.€/kWh (EUR at 2032 prices)energy_eur
track_energy_price_srcSource for the electricity price.——
track_terrain_categoryRough terrain classification: Flat, Hilly, or Mountainous.——
track_terrain_scoreTerrain difficulty score — hills and mountains increase energy use.1–100—
track_terrain_srcSource for terrain category and score.——
track_hsr_allowedWhether night trains may use the country's high-speed lines.——
track_hsr_srcSource for the high-speed permission.——
track_min_boarding_timeMinimum waiting time the country's stations need at stops where passengers board.interval (hh:mm:ss)dwell_time_boarding, dwell_time_both
track_min_boarding_srcSource for the minimum boarding time.——
track_min_alighting_timeMinimum waiting time the country's stations need at stops where passengers get off.interval (hh:mm:ss)dwell_time_alighting, dwell_time_both
track_min_alighting_srcSource for the minimum alighting time.——
track_buffer_quota_perSchedule buffer added on top of driving time, reflecting how congested and delay-prone the network is.fraction of driving timebuffer_time
track_buffer_srcSource for the buffer quota.——
track_tac_b_dayBase day rate of the minimum access package. Empty means the country levies no distance-based day rate.€/train-km (EUR at 2032 prices)tac_eur
track_tac_b_nightNight rate of the minimum access package, charged on the share of a run falling inside the country's night band. Empty means the country has no separate night rate.€/train-km (EUR at 2032 prices)tac_eur
track_tac_gammaWeight-dependent term, charged on the whole consist — coaches plus locomotives.€/gross-tonne-km (EUR at 2032 prices)tac_eur
track_tac_seat_kmCapacity-dependent term, charged per place the train offers (Spanish corridor surcharge).€/seat-km (EUR at 2032 prices)tac_eur
track_tac_per_stopPer-stop element of the path price: stopping and restarting consumes path capacity (Swiss Haltezuschlag). NOT a station usage fee — those are stop_infrastructures.stop_charge_eur. Charged at each stop's own country rate.€/stop (EUR at 2032 prices)tac_eur
track_tac_revenue_shareShare of the traffic revenue earned in this country that the infrastructure manager takes on top of the distance charges (Swiss Deckungsbeitrag).fractiontac_eur
track_tac_fixed_per_train_kmFlat administrative add-on charged per kilometre alongside the base rate (Luxembourgish path administration).€/train-km (EUR at 2032 prices)tac_eur
track_tac_peak_multiplierFactor the day rate is multiplied by on the share of a run falling inside the country's peak bands (Swiss NZV: 2).factortac_eur
track_tac_congestion_surcharge_eur_kmFlat surcharge on congested sections, charged on the share of a run falling inside the peak bands (Austrian überlastete Schienenwege). Kept apart from the multiplier above so a congestion charge can be shown as one.€/train-km (EUR at 2032 prices)tac_eur
track_tac_night_modeHow the country prices night traffic: 'none' (one rate around the clock) or 'time_band' (the night rate applies pro rata to the time a run spends inside the band below).——
track_tac_night_band_startStart of the national night tariff band, local clock. Bands may run across midnight (23:00–06:00).time of daytac_night_share
track_tac_night_band_endEnd of the national night tariff band, local clock.time of day—
track_tac_night_full_if_accommodationGerman SPFV Nacht rule: when true, a train carrying night accommodation (couchette, sleeper or capsule) is priced at the night rate over its ENTIRE run in this country, not just the part inside the band.——
track_tac_peak_band1_startStart of the first daily peak band (morning commuter peak), local clock.time of daytac_peak_share
track_tac_peak_band1_endEnd of the first daily peak band.time of day—
track_tac_peak_band2_startStart of the second daily peak band (evening commuter peak), local clock.time of day—
track_tac_peak_band2_endEnd of the second daily peak band.time of day—
track_tac_peak_weekdays_onlyWhether the peak bands apply Monday to Friday only. The model knows a departure's clock time but not its weekday, so such a band is charged at its expected value — five sevenths of the overlap.——
track_energy_price_night_eur_kwhTraction electricity price inside the country's night tariff band, charged pro rata on the share of a run that falls in it. Empty means one rate around the clock (AT, CH and HR are the only banded tariffs). Never resolved from the defaults row, which leaves it empty: a banded tariff is a national particularity, not a gap to fill.€/kWh (EUR at 2032 prices)energy_eur
track_energy_night_band_startStart of the national electricity night tariff band, local clock. Bands may run across midnight (22:00–06:00). This is the ENERGY band and is independent of the track access night band (track_tac_night_band_start): Germany bands the track charge 23:00–06:00 and does not band electricity at all, Switzerland the reverse.time of dayenergy_night_share
track_energy_night_band_endEnd of the national electricity night tariff band, local clock.time of day—
track_energy_catenary_eur_train_kmCharge for using the catenary and traction power-supply installations, where the infrastructure manager levies it per train-kilometre (FR, HR, HU, IT, LT, LU, LV, PL, RO). Empty means not levied in this unit — either not levied at all, or charged on weight in the column below, or already inside the energy price. Never resolved from the defaults row: roughly half of Europe's infrastructure managers levy this charge, so an uncalibrated country is priced without one rather than given an invented median.€/train-km (EUR at 2032 prices)energy_eur
track_energy_catenary_eur_gross_tonne_kmThe same supply-equipment charge where the infrastructure manager levies it on the weight moved instead (FI, GR, SK), charged on the whole consist — coaches plus locomotives.€/gross-tonne-km (EUR at 2032 prices)energy_eur
track_parking_basisHow the country prices one stabling occupation: per metre of train length per started 24 hours, per started hour (length-independent, as Germany's Anlagenpreissystem is by design), a flat charge per occupation with no time term, or 'none' where the network statement documents that no siding charge is levied.——
track_parking_eur_metre_dayStabling rate where the country prices by length and time. Empty means it prices in one of the other units.€/metre per started 24 h (EUR at 2032 prices)—
track_parking_eur_hourStabling rate where the country prices per started hour, independent of train length.€/started hour (EUR at 2032 prices)—
track_parking_eur_eventStabling charge where the country prices one occupation flat, with no time or length term.€/occupation (EUR at 2032 prices)—
track_parking_free_hoursFree stabling allowance before the charge starts. Material where it exceeds a layover: Norway's 48 h and Croatia's 24 h zero a twelve-hour turnaround entirely.hours—
track_parking_hotel_power_eur_hourPower the train draws while stabled, charged on ACTUAL stabled hours rather than on the billable hours after a free track allowance — the electricity flows whether or not the siding is free. One European proxy rate, from DB InfraGO's unmetered Elektrant flat charge.€/stabled hour (EUR at 2032 prices)—
change_logFree-text description of what changed in this version and why.——
track_infra_versionPer-table full-snapshot version number. Resolved via scenario.scenarios.track_infrastructures_version — never inferred.——

input_params.passage_charges ​

Crossings that are charged per traverse instead of per kilometre — the Storebælt and Øresund fixed links and the Channel Tunnel. A crossing is its own entity rather than a country attribute because the charging party is the crossing's operator: Øresund is two rows over one polygon, each infrastructure manager billing its half. Which trip segment crosses which passage is decided at routing time by polygon intersection, so a crossing split by an intermediate stop is still paid for once. Version bumps are full-table snapshots, resolved via scenario.scenarios.passage_charges_version — see db/README.md for the versioning contract.

ParameterMeaningUnitUsed in
passage_row_id———
passage_idStable crossing identifier (STOREBAELT, OERESUND_DK, OERESUND_SE, CHANNEL_TUNNEL).——
passage_nameFull crossing name.——
passage_fixed_eurCharge per train crossing, one way.€/traverse (EUR at 2032 prices)tac_eur
passage_per_passenger_eurCharge per carried passenger, one way (Channel Tunnel). Evaluated against the passengers actually aboard on the crossing segment, so this term follows demand.€/passenger (EUR at 2032 prices)tac_eur
passage_srcSource for the crossing charges.——
passage_geomCrossing polygon (SRID 4326). A routed trip leg intersecting it owns the crossing. Static reference geometry — a tunnel does not move between scenarios; what the version pins are the charges.——
change_logFree-text description of what changed in this version and why.——
passage_versionPer-table full-snapshot version number. Resolved via scenario.scenarios.passage_charges_version — never inferred.——

input_params.stop_infrastructure_defaults ​

Fallback station charge per country (empty country = global default). Version bumps are full-table snapshots, resolved via scenario.scenarios.stop_infrastructure_defaults_version — see db/README.md for the versioning contract.

ParameterMeaningUnitUsed in
stop_infra_default_id———
country_codeCountry this default applies to. Empty = global fallback.——
stop_charge_eurFallback station fee per scheduled stop.€/stop—
stop_charge_srcSource for the station fee.——
change_logFree-text description of what changed in this version and why.——
stop_infra_default_versionPer-table full-snapshot version number. Resolved via scenario.scenarios.stop_infrastructure_defaults_version — never inferred.——

input_params.stop_infrastructures ​

Catalog of possible night train stops. An empty stop_charge_eur is resolved against stop_infrastructure_defaults by the loader. Version bumps are full-table snapshots — every stop's row is duplicated forward on any single-stop edit — resolved via scenario.scenarios.stop_infrastructures_version. See db/README.md for the versioning contract.

ParameterMeaningUnitUsed in
stop_infra_row_id———
stop_idUnique stop identifier.——
stop_nameOfficial station name.——
country_codeTwo-letter country code (ISO 3166-1 alpha-2).——
stop_timezoneIANA timezone identifier (e.g. Europe/Berlin).——
stop_latLatitude in WGS-84 decimal degrees.°—
stop_lonLongitude in WGS-84 decimal degrees.°—
stop_loc_srcSource for the coordinates.——
stop_charge_eurStation fee per scheduled stop. Empty = the country or global default applies.€/stopstation_charge_eur
stop_charge_per_tonne_eurMass-based part of the station fee, per tonne of train mass excluding non-carrying traction (CompositionType.total_weight_t). Added to stop_charge_eur per call; empty = none. Czechia prices stops this way (Správa železnic, Annex C II.5).€/stop/tstation_charge_eur
stop_charge_srcSource for the station fee.——
stop_charge_vat_rate_perVAT rate applying to the station charge, as a percentage (19.00 = 19%). NULL where no charge is calibrated.%—
stop_charge_incl_vat_eurThe station charge including VAT. The model prices from the net stop_charge_eur; this is carried so both figures can be compared against whichever one the tariff document printed.EUR—
stop_charge_basisWhat the charge is per — 'per_call' unless a country's tariff genuinely differs.——
stop_charge_price_basis_yearThe year the published figure applies to, before any escalation.——
stop_charge_classThe country's own category for the station ('Preisklasse 2'), which is why two stations in one country differ.——
stop_charge_sourcesource_id of the tariff document the charge was read from, in the charge pipeline's own register (models/infrastructure/stops/charges/01_source_extraction).——
stop_provenanceWhy the stop is in the catalog, as a human-readable category (step 10 PROVENANCE_LABELS: 'existing night train stop', 'urban area currently without night train service', ...). The detailed per-stop reasons stay in the pipeline's step 6 notebook.——
name_latinLatin-script form of the station name (transliterated where the original is Cyrillic/Greek, otherwise the name itself).——
name_asciiASCII fold of name_latin — the diacritic-free search form.——
uic_refUIC station code from OSM, where tagged — the tag verbatim, so a station holding more than one code carries them all, semicolon-separated (Paris CDG 2 TGV: 8727149;8700147). Intended join key for station-charge tariff documents, not normalised yet: split on the semicolon before matching, and note that a few stops carry a national number rather than the country-prefixed UIC code.——
country_enCountry name in 'en' (ISO 3166 translation catalogs via the pipeline).——
country_deCountry name in 'de' (ISO 3166 translation catalogs via the pipeline).——
country_frCountry name in 'fr' (ISO 3166 translation catalogs via the pipeline).——
country_nlCountry name in 'nl' (ISO 3166 translation catalogs via the pipeline).——
country_itCountry name in 'it' (ISO 3166 translation catalogs via the pipeline).——
country_esCountry name in 'es' (ISO 3166 translation catalogs via the pipeline).——
country_plCountry name in 'pl' (ISO 3166 translation catalogs via the pipeline).——
cityMunicipality the stop belongs to (Berlin Gesundbrunnen -> Berlin), resolved geographically against OSM place nodes. Empty for rural halts beyond any city/town radius.——
city_osm_idOSM node id of the resolved place — the stable key behind the localized city names.——
city_enCity name in 'en' from the place node's own name:* tags (exonyms as curated in OSM — an Italian search for 'Monaco' reaches München's stops here).——
city_deCity name in 'de' from the place node's own name:* tags (exonyms as curated in OSM — an Italian search for 'Monaco' reaches München's stops here).——
city_frCity name in 'fr' from the place node's own name:* tags (exonyms as curated in OSM — an Italian search for 'Monaco' reaches München's stops here).——
city_nlCity name in 'nl' from the place node's own name:* tags (exonyms as curated in OSM — an Italian search for 'Monaco' reaches München's stops here).——
city_itCity name in 'it' from the place node's own name:* tags (exonyms as curated in OSM — an Italian search for 'Monaco' reaches München's stops here).——
city_esCity name in 'es' from the place node's own name:* tags (exonyms as curated in OSM — an Italian search for 'Monaco' reaches München's stops here).——
city_plCity name in 'pl' from the place node's own name:* tags (exonyms as curated in OSM — an Italian search for 'Monaco' reaches München's stops here).——
gauges_mmNight-train-capable track gauges at the stop (railway=rail, >= 1435 mm; trams/Stadtbahn/narrow gauge are excluded by the pipeline). Several values at break-of-gauge stations (Kaunas 1435+1520). NULL = no usable tracks found nearby.mm—
gauge_evidenceHow the gauge set was established from OSM: tagged tracks, rail present but untagged, only sub-1435 rail nearby (review flag), no rail within the search radius, or a hand-verified override (step 8's GAUGE_OVERRIDES — the station node is right but OSM carries no gauge-tagged way within the radius).——
change_logFree-text description of what changed in this version and why.——
stop_infra_versionPer-table full-snapshot version number. Resolved via scenario.scenarios.stop_infrastructures_version — never inferred.——

scenario.scenarios ​

Container pinning one version of each versioned infrastructure table. Exactly one row has is_current_base = TRUE (the live default); exactly one row per scenario_key has is_current_scenario = TRUE (the head of that what-if lineage). All five *_version columns are per-table full-snapshot version numbers, resolved by exact match, and are NOT NULL — a scenario is always a complete, self-contained pin, never a partial diff. routing_graph_key pins the routing graph the same way (the one piece of infrastructure living outside the database). Compositions, coach types, and operators are catalogs, not scenario-versioned. Full versioning contract: db/README.md.

ParameterMeaningUnitUsed in
scenario_id———
scenario_keyStable identifier for one lineage of scenario edits, e.g. "base", "whatif-de-track-infra". Shared across every row belonging to that lineage; scenario_id changes on every edit, scenario_key does not.——
scenario_nameShort human-readable label, e.g. "2032 Base Line", "What-if: DE power tax -10%".——
descriptionFree-text explanation of what this scenario represents and why it exists.——
change_logFree-text summary of what changed relative to the scenario this was derived from — the batch-level narrative; per-value rationale lives in each parameter table's own change_log.——
editorUser who created this scenario.——
created_at———
is_current_baseTRUE for the single live default scenario, used whenever an API call is not given an explicit scenario_id.——
is_current_scenarioTRUE for the newest row within this scenario_key. Exactly one per key.——
track_infrastructures_versionPinned input_params.track_infrastructures version (full-table snapshot).——
track_infrastructure_defaults_versionPinned input_params.track_infrastructure_defaults version (full-table snapshot).——
stop_infrastructures_versionPinned input_params.stop_infrastructures version (full-table snapshot).——
stop_infrastructure_defaults_versionPinned input_params.stop_infrastructure_defaults version (full-table snapshot).——
passage_charges_versionPinned input_params.passage_charges version (full-table snapshot).——
routing_graph_keyRouting graph this scenario routes on — the physical rail network (OSM state) behind every distance and travel time, e.g. "infra_2026" or "infra_2032". Pinned like the *version columns but not itself a snapshot version: the graph lives outside the database, in an OpenRailRouting instance. Naming contract with the deployment: key <k> is served by the instance at env OPENRAILROUTING_URL<K>, the key uppercased — every graph alike, none implicit — see models/route/routing/rail_router.py. The TAC and passage changes an upgraded network implies are NOT carried here; they ride this same row's track_infrastructures_version and passage_charges_version pins.——

scenario.measure_sets ​

A named bundle of political measures an evaluation runs under — what the state DOES, where a scenario pins what the infrastructure IS. Unversioned definitions: the flags say which levers are pulled, never by how much. The rates themselves (VAT per country of sale, electricity tax share, direct-cost floor per infrastructure manager) get their own versioned input_params table with WP17 and are pinned by the scenario like every other calibrated parameter. One row today, 'none' — no lever pulled, which is what every evaluation before WP18 implicitly ran under.

ParameterMeaningUnitUsed in
measure_set_id———
keyStable identifier, e.g. "none", "vat-exempt". What the API and the frontend name a measure set by; ids are database-assigned and not portable between environments.——
vat_exemptNight train fares exempt from value-added tax. Raises the operator's retained revenue per ticket.——
energy_tax_exemptTraction electricity exempt from energy/electricity tax. Lowers the energy price the operator pays.——
tac_direct_costTrack access charged at the direct cost of running the train only, the floor Directive 2012/34/EU permits — not a discount on the full charge but a different component selection (models/infrastructure/tac/calc_tac.py).——
descriptionWhat this bundle of measures represents, in the words a reader of the results needs.——

scenario.scenario_variants ​

The flattened (scenario x measure set) axis the API and the frontend address by a single id — one dropdown value instead of two. Materialised as the full cross product (db/dev/seed.py materialise_scenario_variants(), re-run after every scenario or measure-set insert), so it is derived data: truncating and rebuilding it loses nothing except the ids themselves, which nothing persists.

ParameterMeaningUnitUsed in
scenario_variant_id———
scenario_idThe infrastructure pin this variant evaluates on.——
measure_set_idThe measures this variant evaluates under.——

Published by Back-on-Track. Every number on this site is generated from the model that produces the tool’s results. Text, figures and charts: CC BY 4.0 · code: GPL-3.0-or-later · map data © OpenStreetMap contributors.