<jupyter_start><jupyter_text>Adding TNCs The purpose of this notebook is to illustrate the steps to add a new mode - Transportation Network Companies (or Ride Hailing) - to ActivitySim.  This notebook assumes users are familiar with the [Getting Started](getting_started.ipynb) notebook.  The basic steps are as follows:  - Update the tour and trip mode choice model settings yaml file to include the mode  - Update the tour and trip mode choice model expression files to include the mode and the utility expressions  - Update the tour and trip mode choice model coefficients files to include any additional coefficients  - Update the tour and trip mode choice model pre-processor annotation files to include any additional chooser data processing  - Update the tour and trip mode choice model settings yaml file to include any additional constants to be referenced in the expressions  - Run the model, summarize results to confirm the results, and make any necessary revisions to fix errors and/or calibrate the results  This notebook assumes you have run the example model.    Specify an example model run for illustration<jupyter_code>example_dir = "example/"<jupyter_output><empty_output><jupyter_text>Load libraries<jupyter_code>import os
import pandas as pd
import openmatrix as omx
import yaml
import glob

import matplotlib.pyplot as plt # !pip install matplotlib # for charts
import geopandas as gpd # !conda install geopandas # for making maps
import descartes # !conda install descartes # for making maps

pd.set_option("display.max_rows", None)<jupyter_output><empty_output><jupyter_text>Matplot Default Chart Settings<jupyter_code>%matplotlib inline
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = (15,10)<jupyter_output><empty_output><jupyter_text>Update the tour and trip mode choice model settings yaml file to include the modeThe **NESTS** setting in the tour and trip mode choice model defines the available modes.  The RIDEHAIL alternative was added with the following alternatives - TAXI, TNC_SINGLE (single rider), and TNC_SHARED (2+ riders).  The coef_nest_RIDEHAIL was added to the relevant coefficient file, as discussed later.  The example below illustrates the tour mode choice yaml file.<jupyter_code>with open(example_dir + 'configs/tour_mode_choice.yaml') as file:
    file_contents = yaml.load(file, Loader=yaml.FullLoader)
    print(yaml.dump(file_contents))<jupyter_output>COEFFICIENTS: tour_mode_choice_coefficients.csv
COEFFICIENT_TEMPLATE: tour_mode_choice_coefficients_template.csv
CONSTANTS:
  TNC_shared_IVTFactor: 1.5
  TNC_shared_baseFare: 2.2
  TNC_shared_costMinimum: 3.0
  TNC_shared_costPerMile: 0.53
  TNC_shared_costPerMinute: 0.1
  TNC_shared_waitTime_mean:
    1: 5.0
    2: 8.0
    3: 11.0
    4: 15.0
    5: 15.0
  TNC_shared_waitTime_sd:
    1: 0
    2: 0
    3: 0
    4: 0
    5: 0
  TNC_single_baseFare: 2.2
  TNC_single_costMinimum: 7.2
  TNC_single_costPerMile: 1.33
  TNC_single_costPerMinute: 0.24
  TNC_single_waitTime_mean:
    1: 3.0
    2: 6.3
    3: 8.4
    4: 8.5
    5: 10.3
  TNC_single_waitTime_sd:
    1: 0
    2: 0
    3: 0
    4: 0
    5: 0
  Taxi_baseFare: 2.2
  Taxi_costPerMile: 2.3
  Taxi_costPerMinute: 0.1
  Taxi_waitTime_mean:
    1: 5.5
    2: 9.5
    3: 13.3
    4: 17.3
    5: 26.5
  Taxi_waitTime_sd:
    1: 0
    2: 0
    3: 0
    4: 0
    5: 0
  bikeSpeed: 12.0
  bikeThresh: 6.0
  biketimelong_multiplier: 20
  biketimesho[...]<jupyter_text>Update the tour and trip mode choice model expression files to include the mode and the utility expressionsThe next step is to add the modes to the expressions file and then add expressions to describe the mode utilities.  As shown below, columns were added for each new alternative in the mode choice file and rows for each relevant expression for each mode.  Refer to the original CSV file for the entire expressions since they are truncated in the output below. The tour and trip mode choice models make use of coefficient files, which are discussed next.  The tour and trip mode choice models may also depend on submodel annotation preprocessors, which are discussed afterwards.<jupyter_code>tour_mode_choice_expressions = pd.read_csv(example_dir + 'configs/tour_mode_choice.csv')

row_selector = (~tour_mode_choice_expressions.TAXI.isna() | ~tour_mode_choice_expressions.TNC_SINGLE.isna() | ~tour_mode_choice_expressions.TNC_SHARED.isna())

tour_mode_choice_expressions[row_selector]<jupyter_output><empty_output><jupyter_text>Update the tour and trip mode choice model coefficients files to include any additional coefficientsAs shown below for tour mode choice, several coefficients and/or constants were added when adding TNCs.  Example additional coefficients are the ridehail nesting coefficient and calibration constants by mode, auto sufficiency, and purpose.<jupyter_code>tour_mode_choice_coefficients = pd.read_csv(example_dir + 'configs/tour_mode_choice_coefficients.csv')

tour_mode_choice_coefficients<jupyter_output><empty_output><jupyter_text>Update the tour and trip mode choice model pre-processor annotation files to include any additional chooser data processingThe mode choice models also make use of chooser annotation preprocessors if needed.  As shown below, adding TNCs meant calculating the **origin_zone_singleTNC_wait_time_mean** variable for each chooser tour origin zone.  This was done by first calculating the origin zone density and density bin and then looking up the wait time mean for the origin zone from the tour mode choice settings yaml file constants.  The constants are discussed in more detail later.<jupyter_code>tour_mode_choice_preprocessor = pd.read_csv(example_dir + 'configs/tour_mode_choice_annotate_choosers_preprocessor.csv')

tour_mode_choice_preprocessor<jupyter_output><empty_output><jupyter_text>Update the tour and trip mode choice model settings yaml file to include any additional constants to be referenced in the expressionsAdditional constants can be defined in the tour and trip mode choice submodel settings yaml file and then referenced in the expression files.  The following example illustrates the **CONSTANTS** used for the additional TNC modes.<jupyter_code>with open(example_dir + 'configs/tour_mode_choice.yaml') as file:
    file_contents = yaml.load(file, Loader=yaml.FullLoader)
    print(yaml.dump(file_contents))<jupyter_output>COEFFICIENTS: tour_mode_choice_coefficients.csv
COEFFICIENT_TEMPLATE: tour_mode_choice_coefficients_template.csv
CONSTANTS:
  TNC_shared_IVTFactor: 1.5
  TNC_shared_baseFare: 2.2
  TNC_shared_costMinimum: 3.0
  TNC_shared_costPerMile: 0.53
  TNC_shared_costPerMinute: 0.1
  TNC_shared_waitTime_mean:
    1: 5.0
    2: 8.0
    3: 11.0
    4: 15.0
    5: 15.0
  TNC_shared_waitTime_sd:
    1: 0
    2: 0
    3: 0
    4: 0
    5: 0
  TNC_single_baseFare: 2.2
  TNC_single_costMinimum: 7.2
  TNC_single_costPerMile: 1.33
  TNC_single_costPerMinute: 0.24
  TNC_single_waitTime_mean:
    1: 3.0
    2: 6.3
    3: 8.4
    4: 8.5
    5: 10.3
  TNC_single_waitTime_sd:
    1: 0
    2: 0
    3: 0
    4: 0
    5: 0
  Taxi_baseFare: 2.2
  Taxi_costPerMile: 2.3
  Taxi_costPerMinute: 0.1
  Taxi_waitTime_mean:
    1: 5.5
    2: 9.5
    3: 13.3
    4: 17.3
    5: 26.5
  Taxi_waitTime_sd:
    1: 0
    2: 0
    3: 0
    4: 0
    5: 0
  bikeSpeed: 12.0
  bikeThresh: 6.0
  biketimelong_multiplier: 20
  biketimesho[...]<jupyter_text>Run the model, summarize outputs to confirm the results, and make any necessary revisions to fix errors and/or calibrate the resultsThe final step is to run the model, summarize outputs to confirm the results, and make any necessary revisions to fix errors and/or calibrate the results.  This entire sequence of steps to add a new mode is likely iterative as issues are identified and then fixed and the model re-run and results re-summarized until complete.  Tours by mode<jupyter_code>tours = pd.read_csv(example_dir + 'output/final_tours.csv')

tour_mode = tours.groupby(["tour_mode", "tour_category"]).count()["household_id"].reset_index()
tour_mode = tour_mode.pivot_table(index="tour_mode", columns="tour_category", fill_value=0)['household_id']
tour_mode
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, sharex=True)
fig.suptitle('Tour Mode Choice')
ax1.bar(tour_mode.index, tour_mode['atwork'])
ax1.set_title('At Work')
ax2.bar(tour_mode.index, tour_mode['joint'])
ax2.set_title('Joint')
ax3.bar(tour_mode.index, tour_mode['mandatory'])
ax3.set_title('Mandatory')
ax4.bar(tour_mode.index, tour_mode['non_mandatory'])
ax4.set_title('Non-mandatory')
_ = plt.xticks(rotation='vertical')<jupyter_output><empty_output><jupyter_text>TNC tours by time-of-day<jupyter_code>row_selector = ((tours.tour_mode == "TAXI") | (tours.tour_mode == "TNC_SINGLE") | (tours.tour_mode == "TNC_SHARED"))
tdd = tours[row_selector]
tdd = tdd.groupby(["start", "end"]).count()["household_id"].reset_index()
tdd = tdd.pivot_table(index="start", columns="end", fill_value=0)["household_id"]

plt.plot(tdd.sum(axis=1), label='Start')
plt.plot(tdd.sum(axis=0), label='End')
plt.title('TNC Tour Scheduling')
plt.ylabel('Frequency')
plt.xlabel('Time period')
_ = plt.legend(loc='best')<jupyter_output><empty_output><jupyter_text>TNC trips by origin zone<jupyter_code>SHAPE_FILE = os.path.join('zone_shapefile', 'bayarea_rtaz1454_rev1.shp')
SHAPES = gpd.read_file(SHAPE_FILE)
tours_by_zone = tours[row_selector].groupby(["origin", "tour_mode"]).count()
tnc_shapes = SHAPES.merge(tours_by_zone.reset_index(), how='left', left_on='TAZ1454', right_on='origin')
tnc_shapes.plot(column='tour_id', cmap='Blues',
                 legend=True,
                 legend_kwds={'label': "TNC trips"},
                 figsize=(20,20))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08158628524217701, 'fraction_numerical': 0.02757409893628008, 'mean_word_length': 4.869090909090909, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '220666', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 3425, 'n_tokens_neox': 3200, 'n_words': 980, 'path': 'activitysim/examples/example_mtc/notebooks/adding_tncs.ipynb', 'repo_name': 'mxndrwgrdnr/activitysim', 'size': '9683'}