Skip to content

Script reference

Jip Claassens edited this page Apr 1, 2026 · 1 revision

Code architecture: public transport scripts

This page is a reference for developers working on or extending the model. It describes how the GeoDMS scripts are structured, which containers and templates they define, and how they relate to each other. For the conceptual methodology, see the Public transport page.


File overview

File Role
PublicTransport_Prep.dms Top-level preparation container. Defines the two network subsets (Set_R, Set_L), includes MakeODs.dms, builds the global unique time-stop indices, includes Transfers.dms, instantiates KetenGeneratie_PerBlock_T for each block, writes the union of block results to FSS, and defines the read-back unit PT. Also builds the pre- and post-transport OSM networks and the Direct_OD unit. Includes KetenRijger_T.dms, CreateTransfers_T.dms, and Get_Windowed_Agency_Set_T.dms.
Get_Windowed_Agency_Set_T.dms Template that applies a time-window filter and an agency/mode filter to the full GTFS network, then builds the NodeSet of unique (time, stop, route) triples and the F1/F2 keys for Dijkstra.
MakeODs.dms Included by PublicTransport_Prep. Defines OD_L and OD_R as impedance_matrix calls. Includes OD_extra_attributen.dms for shared attribute definitions and OD_traveldist.dms for per-mode distance accumulation.
OD_extra_attributen.dms Shared attribute fragment included inside both OD_L and OD_R. Defines stop and time attributes derived from NodeSet, the price table lookup chain for regional transport, and the NS station pair key for NS pricing.
OD_traveldist.dms Shared attribute fragment included inside OD_L/Result and OD_R/Result. Defines per-mode distance attributes (TravelDist_Bus, TravelDist_Metro, TravelDist_Tram, TravelDist_Rail, TravelDist_Ferry).
OD_uq_attributen.dms Shared unique time-place index attributes (used in PerVetrekMoment_T).
Transfers.dms Instantiates CreateTransfers_T for the four operator-pair combinations: Transfers_R_R, Transfers_R_L, Transfers_L_L, Transfers_L_R.
CreateTransfers_T.dms Template that performs a spatial join of unique exit stops against unique entry stops, computes walking and waiting times, checks validity, and computes transfer costs.
KetenRijger_T.dms Template that joins a left OD set, a transfer set, and a right OD set; computes combined travel time and prices; applies the level-crossing penalty; and performs two-stage Pareto filtering.
PerVetrekMoment_T.dms Template instantiated once per departure moment. Filters the cached PT result to the voortransport window, joins pre-transport, validates each combination, joins post-transport, appends direct connections, and condenses in two Pareto steps before exporting.
PublicTransport.dms Top-level output container. Defines V (pre-transport union), N (post-transport union), and instantiates PerVetrekMoment_T via for_each_ne over MeasureMoments.
Classifications.dms Defines Agencies (including IsNS and IsRO flags), Ketens (the algorithmic chain combination generator), TimeInvariantTypes (pre- and post-transport connection types), KetenRijgerParetoAttr, CandidateParetoAttr, and FinalParetoAttr.

Key data types and index units

c_Time_Stops (uint64)

The central join key for all time-expanded lookups. It encodes a time index and a stop index as:

c_Time_Stop = uint64(time_index) * uint64(#Stops) + uint64(stop_index)

Decoding:

time_index := c_Time_Stop / uint64(#Stops)
stop_index := c_Time_Stop % uint64(#Stops)

This encoding is used in the NodeSet, in OD_L and OD_R, in the transfer sets, in the chain joiner, and in the PT read-back unit. It is defined globally as /SourceData/Infrastructuur/GTFS/c_Time_Stops.

uq_c_FromTime_Stop and uq_c_ToTime_Stop

These are units of unique c_Time_Stop values, computed in PublicTransport_Prep from the union of OD_L/Result and OD_R/Result:

uq_c_FromTime_Stop := unique_uint64(All_Time_Stops/c_FromTime_Stop_rel)
uq_c_ToTime_Stop   := unique_uint64(All_Time_Stops/c_ToTime_Stop_rel)

Every OD result row has a uq_c_FromTime_Stop_rel and a uq_c_ToTime_Stop_rel attribute that index into these units. The transfer sets have uq_c_Exit_rel (into uq_c_ToTime_Stop) and uq_c_Reboard_rel (into uq_c_FromTime_Stop). The chain joiner uses equality of these indices as its join keys, which is what makes join_equal_values_uint64 efficient.

c_Time_Places (uint64)

Analogous to c_Time_Stops but operating at the Places level. Places is the union of PT_net/SL_Places, the origin set (org), and the destination set (dest). The c_Time_Places unit is defined as:

c_Time_Places := combine_unit_uint64(Time, Places)

and decoded as:

place_index := c_Time_Place % uint64(#Places)
time_index  := c_Time_Place / uint64(#Places)

This index is used in PerVetrekMoment_T for joining the PT result (which operates at the stop level) with the pre- and post-transport results (which operate at the places level). The PT unit provides c_FromTime_Place_rel and c_ToTime_Place_rel derived from its stop-level indices via Stops/Place_rel.

c_NS_start_end

A combined unit for NS station pairs, defined as:

c_NS_start_end := /SourceData/Infrastructuur/OVprijzen/NS/NS_tariefeenheden_matrix/c_NS_start_end

Used to look up prices in TariefEenhedenMatrix/ODMatrix. Both OD_L and the NS-through-pricing logic in KetenRijger_T use combine_data(c_NS_start_end, First_NS_Station, Last_NS_Station) to construct the lookup key.


Template: Get_Windowed_Agency_Set_T

Parameter: selection_str, a string that is appended to the filter condition for the GTFS network.

The two instantiations in PublicTransport_Prep/impl are:

Set_R := Get_Windowed_Agency_Set_T(
    ' && PTnet/Agency_rel->IsRO && PTnet/Duration > 0f')

Set_L := Get_Windowed_Agency_Set_T(
    ' && (PTnet/Agency_rel == Agencies/V/ns
         || (PTnet/Mode_rel == impl/Modes/V/Waiting
             && IsDefined(PTnet/c_NS_start_end_rel)))
         && PTnet/Duration > 0f')

The base filter applied regardless of selection_str is that the link falls within the time window: From_Time_rel >= EersteVertrekMoment and To_Time_rel < LaatsteAankomstMoment and duration <= MaxOVTime.

After filtering, the template:

  1. Computes c_fromTime_Stop_rel and c_toTime_Stop_rel for each link.
  2. Constructs doubledLinks by unioning the from-events and to-events of all links.
  3. Takes NodeSet := unique(doubledLinks/c_Time_Stop_Route_rel), the set of unique (time, stop, route) triples.
  4. Computes F1 := rlookup(c_fromTime_Stop_rel, NodeSet/c_Time_Stop_rel) and F2 := rlookup(c_toTime_Stop_rel, NodeSet/c_Time_Stop_rel), the from-node and to-node references passed to impedance_matrix.

Output: the Set sub-container with all filtered links plus F1, F2, and NodeSet.


Template: CreateTransfers_T

Parameters: FromDomain and ToDomain, both OD result units.

Steps:

  1. Uq_From := unique_uint32(FromDomain/c_ToTime_Stop_rel): the unique set of arrival events in FromDomain.
  2. Uq_To := unique_uint32(ToDomain/c_FromTime_Stop_rel): the unique set of departure events in ToDomain.
  3. Transfers := join_near_values_uint32(Uq_From/To_Point, Uq_To/From_Point, MaxTransferDist): spatial join, yielding all stop pairs within the configured crow-fly distance.
  4. For each candidate pair: compute Walking_Dist, Walking_Time_rel, Transfer_Time_rel, WaitingAtStop_Time_rel.
  5. Apply IsValidTransfer: all four conditions described on the Public transport page must hold.
  6. For each valid transfer: compute Walking_Time_cost, Waiting_Time_cost, Time_cost.
  7. Assign uq_c_Exit_rel (into uq_c_ToTime_Stop) and uq_c_Reboard_rel (into uq_c_FromTime_Stop).

Output: Result := Transfers/ValidTransfers.


Template: KetenRijger_T

Parameters: Left (OD result unit), Right (OD result unit), Transfers (transfer result unit), LeftStr (string like 'R' or 'RL'), RightStr (string like 'L' or 'R').

The LeftStr and RightStr parameters are used to derive compile-time Boolean flags:

  • HasLeft_RO, HasRight_RO: whether the left or right chain contains any non-NS legs.
  • HasLeft_NS, HasRight_NS: whether the left or right chain contains any NS legs (L or K designation).
  • NS_overstap_mogelijk: both sides have NS legs; a through-price may be possible.
  • NS_overstap_zeker: the left string ends with 'L' and the right string starts with 'L'; the through-price is always used.
  • RO_overstap_mogelijk: both sides have non-NS legs; the R-to-O discount may apply.

These flags control conditional expressions that are constructed as strings and evaluated at runtime using GeoDMS's expression evaluation mechanism (=-prefixed attributes). This pattern is used because GeoDMS does not have if-expressions at the type level; instead, the appropriate expression string is selected at template instantiation time.

Joining:

  • Join_Left_Transf: join_equal_values_uint64(Left/uq_c_ToTime_Stop_rel, Transfers/uq_c_Exit_rel).
  • Join_LeftT_Right: join_equal_values_uint64(Join_Left_Transf/Transfers_rel->uq_c_Reboard_rel, Right/uq_c_FromTime_Stop_rel).

Combined travel time:

Traveltime_wo_Penalty := Left/traveltime + Transfers/Transfer_Time + Right/traveltime
Traveltime := NeedsTranferTimePenalty
              ? Traveltime_wo_Penalty + OngelijkvloersPenalty
              : Traveltime_wo_Penalty

Validity and Pareto filtering (see Public transport page for the conceptual explanation). The Pareto attributes used here are KetenRijgerParetoAttr: Price_augm, resttijd_zonder_RO_overstap, and resttijd_zonder_NS_overstap.

Output: Result := Fence/Result, a uint32 unit of Pareto-optimal paths through the full Left/Transfer/Right combination.

The Fence container (PhaseContainer) is used to signal progress and also to separate the result from the intermediate computation graph, which is necessary to avoid a deadlock in the GeoDMS dependency resolver (see issue 965).


Template: KetenGeneratie_PerBlock_T

Parameter: BlockDomain_id, a reference into impl/BlockDomain.

Steps:

  1. Selects the block-specific subset of OD_L/Result and OD_R/Result based on the random permutation (BlockSelections/rnd_rel[From_Stop_rel] / MaxStopBlockSize == BlockDomain_id).
  2. Instantiates all ToBeCalculated chains via for_each_ne over impl/ToBeCalculated_Ketens/name, calling KetenRijger_T for each.
  3. Unions all Toegestane_Ketens results.
  4. Applies a final Pareto selection over the OD key (uq_c_FromTime_Stop_rel, To_Stop_rel) using FinalParetoAttr.
  5. Returns the Pareto-optimal set as BlockResultContainer/Result.

Note that the block OD key uses To_Stop_rel (the destination stop) rather than uq_c_ToTime_Stop_rel (the destination time-stop event). This means the model collapses across different arrival times at the same destination stop, retaining only Pareto-optimal options. The arrival time is still known from uq_c_ToTime_Stop_rel and is preserved on the result for the per-departure-moment step.


Template: PerVetrekMoment_T

Parameters: inTime (departure moment as uint32 time index) and inTime_string (human-readable label).

Main containers and units:

  • Within_VW_Window: subset of PublicTransport_Prep/PT with From_Time_rel <= inTime + Max_V_Time + MaxWachttijdThuis.
  • Add_V_to_PT: join_equal_values_uint64(V/To_Place_rel, Within_VW_Window/From_Place_rel), with validity filtering.
  • Add_V_to_PT/Result: the valid V+PT combinations.
  • Add_N_to_VPT: join_equal_values_uint64(Add_V_to_PT/Result/To_Place_rel, N/From_Place_rel), with validity filtering.
  • Add_N_to_VPT/Result: the valid V+PT+N combinations.
  • Union_with_DirectOD: union of Add_N_to_VPT/Result and Direct_OD.
  • First condensation: Pareto over (uq_c_FromTime_Place_rel, To_Place_rel), producing Result_AfterFirstCondensation.
  • Second condensation: Pareto over (From_Place_rel, To_Place_rel), producing Result_AfterSecondCondensation.
  • CreateExports: generates the output CSV via StorageName-based string parameters, with content depending on Export_AfgelegdeAfstand and Export_Prijsinformatie.

The ModeUsed string is built up by concatenating mode abbreviations at each join step: pre-transport mode, PT modes (from OD_R/R or OD_L/L), and post-transport mode, separated by underscores.


Pareto attribute configuration

Pareto attributes are configured in two places in Classifications.dms:

KetenRijgerParetoAttr: used inside KetenRijger_T. Always fixed to three attributes: Price_augm, resttijd_zonder_RO_overstap, resttijd_zonder_NS_overstap. The rest-time attributes ensure that the chain joiner does not prematurely discard options that are slightly more expensive but retain eligibility for favourable pricing at the next transfer.

CandidateParetoAttr: the configurable pool of candidate attributes, containing Price, Price_augm, and TravelTime. Which of these are active for the final Pareto selection is determined by ModelParameters/MinimiseCriteria, a string that may contain any combination of the FileNameElement values (Price, Price_augm, Time). The FinalParetoAttr unit is derived from CandidateParetoAttr by selecting only those rows for which IsFinalParetoSelection is true.

Note: if both Price and Price_augm are in MinimiseCriteria, Price is excluded from FinalParetoAttr (because Price_augm already dominates it as a criterion), unless Price_augm is not present.


Important model parameters

Parameter Location Meaning
MaxOVTime ModelParameters Maximum total PT journey time, in minutes.
MaxTravelTime ModelParameters Maximum total journey time including pre- and post-transport.
MaxTransferDist ModelParameters/Advanced Maximum crow-fly distance for a transfer walk, in metres.
TransferEffectiveSpeed ModelParameters/Advanced Walking speed used to compute transfer walking time, in m per time step.
Transfer_Walking_Time_Costs ModelParameters Cost per minute of transfer walking, in Ct/min.
Transfer_Waiting_Time_Costs ModelParameters Cost per minute of waiting at a transfer stop, in Ct/min.
MaxOverstapTijdVoorBasistarief ModelParameters/Advanced Maximum time between non-NS check-out and next non-NS check-in to qualify for the O (continuation) discount.
OngelijkvloersPenalty ModelParameters/Advanced Extra time penalty (in minutes) for transfers involving elevated or underground modes.
Max_overstappen ModelParameters/Advanced Maximum number of transfers allowed, which also controls how many chain combination lengths are generated by Classifications/Ketens.
MaxStopBlockSize ModelParameters/Advanced Maximum number of origin stops per processing block.
NumberOfStopBlocks ModelParameters/Advanced Number of processing blocks (must satisfy MaxStopBlockSize * NumberOfStopBlocks > #Stops).
MaxWachttijdThuis ModelParameters/Advanced Maximum waiting time at home (at the origin) before departing.
WachttijdThuisMeetellen ModelParameters/Advanced Whether waiting time at home is included in the total travel time.
FietsVoortransport_Penalty ModelParameters/Advanced Extra time penalty (in minutes) added to cycling pre-transport legs.
AllowDirectCyclingOverWalking ModelParameters/Advanced If true, Direct_OD uses the cycling OD matrix; otherwise the walking OD matrix.
IncludeCyclingCostsInPrice ModelParameters/Advanced Whether cycling costs are included in the monetary Price (as opposed to only Price_augm).
MinimiseCriteria ModelParameters String controlling which Pareto attributes are active in the final condensation steps.
Analysis_date ModelParameters Date string included in the intermediate FSS file name for cache invalidation.
PrijsExportsAndIntegrityChecksNodig ModelParameters/Advanced If false, price calculations and integrity checks are skipped for faster iteration.