TVPB Design - ActivitySim/activitysim GitHub Wiki

Design specification for Support for Three Zone Systems and Transit Virtual Path Building (TVPB). This design makes use of previous Multiple Zone Systems Design work.

Example Data

There are two example data sets for testing:

  • ActivitySim TM1 test example with a few small revisions. This data set is used to develop the functionality, but it is too small to be useful for performance testing and verification of reasonable results. The 25 zone test example are downtown San Francisco zones and they are converted to 25 MAZs. Each TAZ is also converted to a TAP numbered 10000+. MAZs 1,2,3,4 are small and adjacent and assigned to TAZ 2 and TAP 10002. MAZs 13,14,15 are small and adjacent and assigned to TAZ 14 and TAP 10014. TAZs 1,3,4,13,15 are removed from the final data set. TAPs 10001,10003,10004,10013,10015 are removed from the final data set. See the Jupyter notebook for the data transformation steps.
  • TM2 tour mode choice inputs and outputs. This includes the synthetic households and persons, zone land use, output tours, and three zone system network LOS data. This data set is full scale so it can be used for performance testing and verification against TM2 results. See MTC TVPB test data for the data specification.

In both cases, submodel expression files need to be reconfigured to support the three zone system approach to network LOS.

New Settings

To enable three zone systems and TVPB, the user specifies a new file (tvpb.yaml) with the following settings:

  • DEMOGRAPHIC_SEGMENTS - user configured list of demographic segments for TVPB path calculations. These are like user classes in assignment, each with their own path utility. Persons are assigned a DEMOGRAPHIC_SEGMENT using expression pre-processors.
  • MAZ_TAP_MODES - user configured list of transit access/egress modes from MAZs to TAPs for TVPB path calculations, each with their own input data table for costs and path utility expression file.
  • TAP_TAP_SETS - user configured list of transit TAP to TAP skims for TVPB path calculations, each with their own set of skims and path utility calculation in the expression file. The user can specify multiple sets of skims, known as tap_tap_sets. These correspond to different sets of transit skims, each one created with different network skimming path weights (for example for finding the fastest route versus the cheapest route).
  • TVPB_SETTINGS - user configured list of path sets (which are combinations of access MAZ_TAP_MODE, TAP_TAP_SET, and egress MAZ_TAP_MODE) with path utility calculation settings. The TVPB calculates N best paths for each path set, with the ability to calculate the logsum across path sets and the ability to pick one using logit math and to retain the choice of (access-tap, tap-to-tap-skim-set, egress-tap) to write to the output files.

An example of the settings file is below.

# transit virtual path builder (tvpb.yaml)

DEMOGRAPHIC_SEGMENTS:
  high_income:
    CONSTANTS:
      c_ivt_high_income: -0.028
      c_cost_high_income: -0.00112
  low_income:
    CONSTANTS:
      c_ivt_low_income: -0.028
      c_cost_low_income: -0.00112

MAZ_TAP_MODES:
  walk:
    maz_taps_file: walk_maz_taps.csv
    SPEC: tvpb_walk_maz_tap.csv
    CHOOSER_COLUMNS:
      - walk_time
  drive:
    maz_taps_file: drive_maz_taps.csv
    SPEC: tvpb_drive_maz_tap.csv
    CHOOSER_COLUMNS:
      - drive_time
      - DIST

TAP_TAP_SETS:
  skims: tap_skims.omx
  SPEC: tvpb_tap_tap.csv
  tap_tap_sets:
    - fastest
    - cheapest
    - shortest
  PREPROCESSOR:
    SPEC: tvpb_tap_tap_annotate_choosers_preprocessor.csv
    DF: df

TVPB_SETTINGS:
  PATH_SETS:
    WTW:
      access: walk
      egress: walk
      max_best_paths_across_tap_sets: 3
      max_paths_for_logsum_per_tap_set: 1
      path_nesting_coefficient: 0.24
    DTW:
      access: drive
      egress: walk
      max_best_paths_across_tap_sets: 1
      max_paths_for_logsum_per_tap_set: 1
      path_nesting_coefficient: 0.24
    WTD:
      access: walk
      egress: drive
      max_best_paths_across_tap_sets: 1
      max_paths_for_logsum_per_tap_set: 1
      path_nesting_coefficient: 0.24
  CONSTANTS:
    c_wait: 1.5
    c_walk: 1.7
    c_drive: 1.5
    c_auto_operating_cost_per_mile: 18.29
    C_UNAVAILABLE: -999

Revised Tour Mode Choice Model Expressions

To make use of the new TVPB functionality, the tour mode choice expression file and trip mode choice setting and expression file are revised as follows:

  • The line-haul specific transit submodes in the TRANSIT entries in NESTS in tour_mode_choice.yaml and trip_mode_choice.yaml are replaced by simpler walk-transit and drive-transit modes consistent with the tvpb.yaml
      - name: TRANSIT
        coefficient:  coef_nest_TRANSIT
        alternatives:
          - WALK_TRANSIT
          - DRIVE_TRANSIT
  • Revised mode columns and expressions in tour_mode_choice.csv and trip_mode_choice.csv. Transit LOS expressions now use los.get_tvpb_logsum_odt(DEMOGRAPHIC_SEGMENT, PATH_SETS), for example los.get_tvpb_logsum_odt("high_income", "WTW"). For walk in tour mode choice, we'll have los.get_tvpb_logsum_odt(DEMOGRAPHIC_SEGMENT, WTW) + los.get_tvpb_logsum_dot(DEMOGRAPHIC_SEGMENT, WTW). For drive in tour mode choice, we'll have los.get_tvpb_logsum_odt(DEMOGRAPHIC_SEGMENT, DTW) + los.get_tvpb_logsum_dot(DEMOGRAPHIC_SEGMENT, WTD). For walk in trip mode choice, we'll have los.get_tvpb_logsum_odt(DEMOGRAPHIC_SEGMENT, WTW). For drive in trip mode choice, we'll have los.get_tvpb_logsum_odt(DEMOGRAPHIC_SEGMENT, DTW). The example used for development is shown below.
Label Description Expression WALK_TRANSIT DRIVE_TRANSIT
# Walk to Local
util_WALK_TRANSIT_Unavailable WALK_TRANSIT - Unavailable walk_local_available == False -999
util_WALK_TRANSIT_Paths_logsums WALK_TRANSIT - Path logsums los.get_tvpb_logsum_odt(df.demographic_segment, WTW) + los.get_tvpb_logsum_dot(df.demographic_segment, WTW) coeff_one
util_WALK_TRANSIT_Destination_zone_densityIndex WALK_TRANSIT - Destination zone densityIndex @density_index_multiplier * df.dest_density_index coef_ivt
util_WALK_TRANSIT_Topology WALK_TRANSIT - Topology @coef_topology_trn_multiplier * df.dest_topology coef_ivt
util_WALK_TRANSIT_Person_is_less_than_10_years_old WALK_TRANSIT - Person is less than 10 years old @(df.age <= 10) coef_age010_trn_multiplier
# Drive to Local
util_DRIVE_TRANSIT_Unavailable DRIVE_TRANSIT - Unavailable drive_local_available == False -999
util_DRIVE_TRANSIT_Unavailable_for_zero_auto_households DRIVE_TRANSIT - Unavailable for zero auto households auto_ownership == 0 -999
util_DRIVE_TRANSIT_Unavailable_for_persons_less_than_16 DRIVE_TRANSIT - Unavailable for persons less than 16 age < 16 -999
util_DRIVE_TRANSIT_Paths_logsums DRIVE_TRANSIT - Path logsums los.get_tvpb_logsum_odt(df.demographic_segment, DTW) + los.get_tvpb_logsum_dot(df.demographic_segment, WTD) coeff_one
util_DRIVE_TRANSIT_Destination_zone_densityIndex DRIVE_TRANSIT - Destination zone densityIndex @density_index_multiplier * df.dest_density_index coef_ivt
util_DRIVE_TRANSIT_Topology DRIVE_TRANSIT - Topology @coef_topology_trn_multiplier * df.dest_topology coef_ivt
util_DRIVE_TRANSIT_Person_is_less_than_10_years_old DRIVE_TRANSIT - Person is less than 10 years old @(df.age < 10) coef_age010_trn_multiplier

Pre-Computing / Caching

To be determined soon

Users should trim the set of taps for each maz to remove maz-tap pairs that serve the same transit lines in order to avoid unnecessary calculations. For example, line 5 serves MAZ 100 via TAP 1000 and TAP 1010 and TAP 1000 is closer to MAZ 100.