diff --git a/.github/workflows/core_tests.yml b/.github/workflows/core_tests.yml index 61c55299c..2f43642f1 100644 --- a/.github/workflows/core_tests.yml +++ b/.github/workflows/core_tests.yml @@ -49,7 +49,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -149,7 +149,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -247,7 +247,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -344,7 +344,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -411,7 +411,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -477,7 +477,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ diff --git a/activitysim/abm/models/atwork_subtour_destination.py b/activitysim/abm/models/atwork_subtour_destination.py index c80175297..d0d7fd991 100644 --- a/activitysim/abm/models/atwork_subtour_destination.py +++ b/activitysim/abm/models/atwork_subtour_destination.py @@ -89,11 +89,21 @@ def atwork_subtour_destination( estimator.end_estimation() subtours[destination_column_name] = choices_df["choice"] - assign_in_place(tours, subtours[[destination_column_name]]) + assign_in_place( + tours, + subtours[[destination_column_name]], + state.settings.downcast_int, + state.settings.downcast_float, + ) if want_logsums: subtours[logsum_column_name] = choices_df["logsum"] - assign_in_place(tours, subtours[[logsum_column_name]]) + assign_in_place( + tours, + subtours[[logsum_column_name]], + state.settings.downcast_int, + state.settings.downcast_float, + ) state.add_table("tours", tours) diff --git a/activitysim/abm/models/atwork_subtour_frequency.py b/activitysim/abm/models/atwork_subtour_frequency.py index e574ddc17..f73346d10 100644 --- a/activitysim/abm/models/atwork_subtour_frequency.py +++ b/activitysim/abm/models/atwork_subtour_frequency.py @@ -24,7 +24,15 @@ def add_null_results(state, trace_label, tours): logger.info("Skipping %s: add_null_results", trace_label) - tours["atwork_subtour_frequency"] = np.nan + cat_type = pd.api.types.CategoricalDtype( + [""], + ordered=False, + ) + choices = choices.astype(cat_type) + tours["atwork_subtour_frequency"] = "" + tours["atwork_subtour_frequency"] = tours["atwork_subtour_frequency"].astype( + cat_type + ) state.add_table("tours", tours) @@ -117,6 +125,11 @@ def atwork_subtour_frequency( # convert indexes to alternative names choices = pd.Series(model_spec.columns[choices.values], index=choices.index) + cat_type = pd.api.types.CategoricalDtype( + alternatives.index.tolist() + [""], + ordered=False, + ) + choices = choices.astype(cat_type) if estimator: estimator.write_choices(choices) @@ -137,6 +150,12 @@ def atwork_subtour_frequency( subtours = process_atwork_subtours(state, work_tours, alternatives) + # convert purpose to pandas categoricals + purpose_type = pd.api.types.CategoricalDtype( + alternatives.columns.tolist() + ["atwork"], ordered=False + ) + subtours["tour_type"] = subtours["tour_type"].astype(purpose_type) + tours = state.extend_table("tours", subtours) state.tracing.register_traceable_table("tours", subtours) diff --git a/activitysim/abm/models/atwork_subtour_mode_choice.py b/activitysim/abm/models/atwork_subtour_mode_choice.py index 61972f191..4e1949dc0 100644 --- a/activitysim/abm/models/atwork_subtour_mode_choice.py +++ b/activitysim/abm/models/atwork_subtour_mode_choice.py @@ -190,7 +190,9 @@ def atwork_subtour_mode_choice( "%s choices" % trace_label, choices_df[mode_column_name], value_counts=True ) - assign_in_place(tours, choices_df) + assign_in_place( + tours, choices_df, state.settings.downcast_int, state.settings.downcast_float + ) state.add_table("tours", tours) # - annotate tours table diff --git a/activitysim/abm/models/atwork_subtour_scheduling.py b/activitysim/abm/models/atwork_subtour_scheduling.py index 8057d2c43..1eec282f2 100644 --- a/activitysim/abm/models/atwork_subtour_scheduling.py +++ b/activitysim/abm/models/atwork_subtour_scheduling.py @@ -111,7 +111,9 @@ def atwork_subtour_scheduling( choices.to_frame("tdd"), tdd_alts, left_on=["tdd"], right_index=True, how="left" ) - assign_in_place(tours, tdd_choices) + assign_in_place( + tours, tdd_choices, state.settings.downcast_int, state.settings.downcast_float + ) state.add_table("tours", tours) if trace_hh_id: diff --git a/activitysim/abm/models/cdap.py b/activitysim/abm/models/cdap.py index d9449f3a3..e10763730 100644 --- a/activitysim/abm/models/cdap.py +++ b/activitysim/abm/models/cdap.py @@ -219,6 +219,8 @@ def cdap_simulate( estimator.end_estimation() choices = choices.reindex(persons.index) + cap_cat_type = pd.api.types.CategoricalDtype(["", "M", "N", "H"], ordered=False) + choices = choices.astype(cap_cat_type) persons["cdap_activity"] = choices expressions.assign_columns( diff --git a/activitysim/abm/models/joint_tour_composition.py b/activitysim/abm/models/joint_tour_composition.py index df0b944f4..ab57298e0 100644 --- a/activitysim/abm/models/joint_tour_composition.py +++ b/activitysim/abm/models/joint_tour_composition.py @@ -24,6 +24,10 @@ def add_null_results(state, trace_label, tours): logger.info("Skipping %s: add_null_results" % trace_label) tours["composition"] = "" + cat_type = pd.api.types.CategoricalDtype( + ["", "adults", "children", "mixed"], ordered=False + ) + tours["composition"] = tours["composition"].astype(cat_type) state.add_table("tours", tours) @@ -123,6 +127,10 @@ def joint_tour_composition( # convert indexes to alternative names choices = pd.Series(model_spec.columns[choices.values], index=choices.index) + cat_type = pd.api.types.CategoricalDtype( + model_spec.columns.tolist() + [""], ordered=False + ) + choices = choices.astype(cat_type) if estimator: estimator.write_choices(choices) @@ -134,7 +142,7 @@ def joint_tour_composition( joint_tours["composition"] = choices # reindex since we ran model on a subset of households - tours["composition"] = choices.reindex(tours.index).fillna("").astype(str) + tours["composition"] = choices.reindex(tours.index).fillna("") state.add_table("tours", tours) tracing.print_summary( diff --git a/activitysim/abm/models/joint_tour_destination.py b/activitysim/abm/models/joint_tour_destination.py index cb4e2756e..b214e0982 100644 --- a/activitysim/abm/models/joint_tour_destination.py +++ b/activitysim/abm/models/joint_tour_destination.py @@ -87,12 +87,22 @@ def joint_tour_destination( # add column as we want joint_tours table for tracing. joint_tours["destination"] = choices_df.choice - assign_in_place(tours, joint_tours[["destination"]]) + assign_in_place( + tours, + joint_tours[["destination"]], + state.settings.downcast_int, + state.settings.downcast_float, + ) state.add_table("tours", tours) if want_logsums: joint_tours[logsum_column_name] = choices_df["logsum"] - assign_in_place(tours, joint_tours[[logsum_column_name]]) + assign_in_place( + tours, + joint_tours[[logsum_column_name]], + state.settings.downcast_int, + state.settings.downcast_float, + ) tracing.print_summary("destination", joint_tours.destination, describe=True) diff --git a/activitysim/abm/models/joint_tour_frequency.py b/activitysim/abm/models/joint_tour_frequency.py index 656434b16..93a8aa475 100644 --- a/activitysim/abm/models/joint_tour_frequency.py +++ b/activitysim/abm/models/joint_tour_frequency.py @@ -116,6 +116,11 @@ def joint_tour_frequency( # convert indexes to alternative names choices = pd.Series(model_spec.columns[choices.values], index=choices.index) + cat_type = pd.api.types.CategoricalDtype( + model_spec.columns.tolist(), + ordered=False, + ) + choices = choices.astype(cat_type) if estimator: estimator.write_choices(choices) @@ -138,6 +143,12 @@ def joint_tour_frequency( joint_tours = process_joint_tours(state, choices, alternatives, temp_point_persons) + # convert purpose to pandas categoricals + purpose_type = pd.api.types.CategoricalDtype( + alternatives.columns.tolist(), ordered=False + ) + joint_tours["tour_type"] = joint_tours["tour_type"].astype(purpose_type) + tours = state.extend_table("tours", joint_tours) state.tracing.register_traceable_table("tours", joint_tours) @@ -147,8 +158,8 @@ def joint_tour_frequency( # we expect there to be an alt with no tours - which we can use to backfill non-travelers no_tours_alt = (alternatives.sum(axis=1) == 0).index[0] - households["joint_tour_frequency"] = ( - choices.reindex(households.index).fillna(no_tours_alt).astype(str) + households["joint_tour_frequency"] = choices.reindex(households.index).fillna( + no_tours_alt ) households["num_hh_joint_tours"] = ( diff --git a/activitysim/abm/models/joint_tour_participation.py b/activitysim/abm/models/joint_tour_participation.py index dad275704..4c6691ec1 100644 --- a/activitysim/abm/models/joint_tour_participation.py +++ b/activitysim/abm/models/joint_tour_participation.py @@ -92,7 +92,7 @@ def get_tour_satisfaction(candidates, participate): x = ( candidates[cols] - .groupby(["tour_id", "composition"]) + .groupby(["tour_id", "composition"], observed=True) .agg( participants=("adult", "size"), adults=("adult", "sum"), @@ -475,7 +475,12 @@ def joint_tour_participation( # update number_of_participants which was initialized to 1 joint_tours["number_of_participants"] = participants.groupby("tour_id").size() - assign_in_place(tours, joint_tours[["person_id", "number_of_participants"]]) + assign_in_place( + tours, + joint_tours[["person_id", "number_of_participants"]], + state.settings.downcast_int, + state.settings.downcast_float, + ) state.add_table("tours", tours) diff --git a/activitysim/abm/models/joint_tour_scheduling.py b/activitysim/abm/models/joint_tour_scheduling.py index 465b22b96..260abedc7 100644 --- a/activitysim/abm/models/joint_tour_scheduling.py +++ b/activitysim/abm/models/joint_tour_scheduling.py @@ -161,7 +161,9 @@ def joint_tour_scheduling( choices.to_frame("tdd"), tdd_alts, left_on=["tdd"], right_index=True, how="left" ) - assign_in_place(tours, choices) + assign_in_place( + tours, choices, state.settings.downcast_int, state.settings.downcast_float + ) state.add_table("tours", tours) # updated df for tracing diff --git a/activitysim/abm/models/mandatory_scheduling.py b/activitysim/abm/models/mandatory_scheduling.py index 2e5401bf1..64fc26215 100644 --- a/activitysim/abm/models/mandatory_scheduling.py +++ b/activitysim/abm/models/mandatory_scheduling.py @@ -62,7 +62,9 @@ def mandatory_tour_scheduling( tour_segment_col, ) - assign_in_place(tours, choices) + assign_in_place( + tours, choices, state.settings.downcast_int, state.settings.downcast_float + ) state.add_table("tours", tours) # updated df for tracing diff --git a/activitysim/abm/models/mandatory_tour_frequency.py b/activitysim/abm/models/mandatory_tour_frequency.py index 413390b6e..a80b82904 100644 --- a/activitysim/abm/models/mandatory_tour_frequency.py +++ b/activitysim/abm/models/mandatory_tour_frequency.py @@ -30,7 +30,11 @@ def add_null_results(state, trace_label, mandatory_tour_frequency_settings): logger.info("Skipping %s: add_null_results", trace_label) persons = state.get_dataframe("persons") - persons["mandatory_tour_frequency"] = "" + persons["mandatory_tour_frequency"] = pd.categorical( + "", + categories=["", "work1", "work2", "school1", "school2", "work_and_school"], + ordered=False, + ) tours = pd.DataFrame() tours["tour_category"] = None @@ -134,6 +138,10 @@ def mandatory_tour_frequency( # convert indexes to alternative names choices = pd.Series(model_spec.columns[choices.values], index=choices.index) + cat_type = pd.api.types.CategoricalDtype( + model_spec.columns.tolist() + [""], ordered=False + ) + choices = choices.astype(cat_type) if estimator: estimator.write_choices(choices) @@ -158,6 +166,12 @@ def mandatory_tour_frequency( state, persons=choosers, mandatory_tour_frequency_alts=alternatives ) + # convert purpose to pandas categoricals + purpose_type = pd.api.types.CategoricalDtype( + alternatives.columns.tolist() + ["univ", "home", "escort"], ordered=False + ) + mandatory_tours["tour_type"] = mandatory_tours["tour_type"].astype(purpose_type) + tours = state.extend_table("tours", mandatory_tours) state.tracing.register_traceable_table("tours", mandatory_tours) state.get_rn_generator().add_channel("tours", mandatory_tours) @@ -166,9 +180,7 @@ def mandatory_tour_frequency( persons = state.get_dataframe("persons") # need to reindex as we only handled persons with cdap_activity == 'M' - persons["mandatory_tour_frequency"] = ( - choices.reindex(persons.index).fillna("").astype(str) - ) + persons["mandatory_tour_frequency"] = choices.reindex(persons.index).fillna("") expressions.assign_columns( state, diff --git a/activitysim/abm/models/non_mandatory_destination.py b/activitysim/abm/models/non_mandatory_destination.py index 808501197..496c734cd 100644 --- a/activitysim/abm/models/non_mandatory_destination.py +++ b/activitysim/abm/models/non_mandatory_destination.py @@ -107,11 +107,21 @@ def non_mandatory_tour_destination( [pure_school_escort_tours, non_mandatory_tours] ).set_index(nm_tour_index) - assign_in_place(tours, non_mandatory_tours[["destination"]]) + assign_in_place( + tours, + non_mandatory_tours[["destination"]], + state.settings.downcast_int, + state.settings.downcast_float, + ) if want_logsums: non_mandatory_tours[logsum_column_name] = choices_df["logsum"] - assign_in_place(tours, non_mandatory_tours[[logsum_column_name]]) + assign_in_place( + tours, + non_mandatory_tours[[logsum_column_name]], + state.settings.downcast_int, + state.settings.downcast_float, + ) assert all( ~tours["destination"].isna() diff --git a/activitysim/abm/models/non_mandatory_scheduling.py b/activitysim/abm/models/non_mandatory_scheduling.py index d8cb9e187..4e444107b 100644 --- a/activitysim/abm/models/non_mandatory_scheduling.py +++ b/activitysim/abm/models/non_mandatory_scheduling.py @@ -47,7 +47,9 @@ def non_mandatory_tour_scheduling( tour_segment_col, ) - assign_in_place(tours, choices) + assign_in_place( + tours, choices, state.settings.downcast_int, state.settings.downcast_float + ) state.add_table("tours", tours) # updated df for tracing diff --git a/activitysim/abm/models/non_mandatory_tour_frequency.py b/activitysim/abm/models/non_mandatory_tour_frequency.py index f54d5b120..b300b0e88 100644 --- a/activitysim/abm/models/non_mandatory_tour_frequency.py +++ b/activitysim/abm/models/non_mandatory_tour_frequency.py @@ -3,6 +3,7 @@ from __future__ import annotations import logging +import warnings from pathlib import Path from typing import Any @@ -200,12 +201,24 @@ def non_mandatory_tour_frequency( model_settings_file_name, ) - # FIXME kind of tacky both that we know to add this here and del it below - # 'tot_tours' is used in model_spec expressions alternatives = simulate.read_model_alts( state, "non_mandatory_tour_frequency_alternatives.csv", set_index=None ) - alternatives["tot_tours"] = alternatives.sum(axis=1) + if "tot_tours" not in alternatives.columns: + # add a column for total tours + alternatives["tot_tours"] = alternatives.sum(axis=1) + warnings.warn( + "The 'tot_tours' column may not be automatically added in the future.", + FutureWarning, + ) + else: + # tot_tours already exists, check if it is consistent with legacy behavior + if not (alternatives["tot_tours"] == alternatives.sum(axis=1)).all(): + warnings.warn( + "The 'tot_tours' column in non_mandatory_tour_frequency_alternatives.csv " + "does not match the sum of the other columns.", + RuntimeWarning, + ) # filter based on results of CDAP choosers = persons_merged @@ -391,6 +404,14 @@ def non_mandatory_tour_frequency( ) assert len(non_mandatory_tours) == extended_tour_counts.sum().sum() + # convert purpose to pandas categoricals + purpose_type = pd.api.types.CategoricalDtype( + alternatives.columns.tolist(), ordered=False + ) + non_mandatory_tours["tour_type"] = non_mandatory_tours["tour_type"].astype( + purpose_type + ) + if estimator: # make sure they created the right tours survey_tours = estimation.manager.get_survey_table("tours").sort_index() diff --git a/activitysim/abm/models/parking_location_choice.py b/activitysim/abm/models/parking_location_choice.py index f3fd9674d..2c9b5097c 100644 --- a/activitysim/abm/models/parking_location_choice.py +++ b/activitysim/abm/models/parking_location_choice.py @@ -276,7 +276,12 @@ def run_parking_destination( if fail_some_trips_for_testing: parking_df = parking_df.drop(parking_df.index[0]) - assign_in_place(trips, parking_df.to_frame(parking_location_column_name)) + assign_in_place( + trips, + parking_df.to_frame(parking_location_column_name), + state.settings.downcast_int, + state.settings.downcast_float, + ) trips[parking_location_column_name] = trips[ parking_location_column_name ].fillna(-1) @@ -398,7 +403,12 @@ def parking_location( trace_label=trace_label, ) - assign_in_place(trips_df, parking_locations.to_frame(alt_destination_col_name)) + assign_in_place( + trips_df, + parking_locations.to_frame(alt_destination_col_name), + state.settings.downcast_int, + state.settings.downcast_float, + ) state.add_table("trips", trips_df) diff --git a/activitysim/abm/models/school_escorting.py b/activitysim/abm/models/school_escorting.py index 88bf42617..ed4e15bb3 100644 --- a/activitysim/abm/models/school_escorting.py +++ b/activitysim/abm/models/school_escorting.py @@ -69,9 +69,9 @@ def determine_escorting_participants( ] chaperones["chaperone_weight"] = ( - (persontype_weight * chaperones[ptype_col]) - + (gender_weight * np.where(chaperones[sex_col] == 1, 1, 2)) - + (age_weight * np.where(chaperones[age_col] > 25, 1, 0)) + (persontype_weight * chaperones[ptype_col].astype("int64")) + + (gender_weight * np.where(chaperones[sex_col].astype("int64") == 1, 1, 2)) + + (age_weight * np.where(chaperones[age_col].astype("int64") > 25, 1, 0)) ) chaperones["chaperone_num"] = ( @@ -226,6 +226,14 @@ def create_school_escorting_bundles_table(choosers, tours, stage): ) bundles["bundle_num"] = bundles.groupby("household_id").cumcount() + 1 + # school escorting direction category + escort_direction_cat = pd.api.types.CategoricalDtype( + ["outbound", "inbound"], ordered=False + ) + bundles["school_escort_direction"] = bundles["school_escort_direction"].astype( + escort_direction_cat + ) + # initialize values bundles["chauf_type_num"] = 0 @@ -291,9 +299,13 @@ def create_school_escorting_bundles_table(choosers, tours, stage): # odd chauf_type_num means ride share, even means pure escort # this comes from the way the alternatives file is constructed where chauf_id is # incremented for each possible chauffeur and for each tour type + escort_type_cat = pd.api.types.CategoricalDtype( + ["pure_escort", "ride_share"], ordered=False + ) bundles["escort_type"] = np.where( bundles["chauf_type_num"].mod(2) == 1, "ride_share", "pure_escort" ) + bundles["escort_type"] = bundles["escort_type"].astype(escort_type_cat) # This is just pulled from the pre-processor. Will break if removed or renamed in pre-processor # I think this is still a better implmentation than re-calculating here... @@ -596,6 +608,13 @@ def school_escorting( escort_bundles ) + school_escort_trips["primary_purpose"] = school_escort_trips[ + "primary_purpose" + ].astype(state.get_dataframe("tours")["tour_type"].dtype) + school_escort_trips["purpose"] = school_escort_trips["purpose"].astype( + state.get_dataframe("tours")["tour_type"].dtype + ) + # update pipeline state.add_table("households", households) state.add_table("tours", tours) diff --git a/activitysim/abm/models/stop_frequency.py b/activitysim/abm/models/stop_frequency.py index 7e27ae08a..3a9903179 100644 --- a/activitysim/abm/models/stop_frequency.py +++ b/activitysim/abm/models/stop_frequency.py @@ -142,7 +142,12 @@ def stop_frequency( trace_label=trace_label, ) - assign_in_place(tours_merged, annotations) + assign_in_place( + tours_merged, + annotations, + state.settings.downcast_int, + state.settings.downcast_float, + ) tracing.print_summary( "stop_frequency segments", tours_merged.primary_purpose, value_counts=True @@ -213,6 +218,10 @@ def stop_frequency( # convert indexes to alternative names choices = pd.Series(segment_spec.columns[choices.values], index=choices.index) + cat_type = pd.api.types.CategoricalDtype( + segment_spec.columns.tolist(), ordered=False + ) + choices = choices.astype(cat_type) if estimator: estimator.write_choices(choices) @@ -229,13 +238,23 @@ def stop_frequency( tracing.print_summary("stop_frequency", choices, value_counts=True) # add stop_frequency choices to tours table - assign_in_place(tours, choices.to_frame("stop_frequency")) + assign_in_place( + tours, + choices.to_frame("stop_frequency"), + state.settings.downcast_int, + state.settings.downcast_float, + ) # FIXME should have added this when tours created? assert "primary_purpose" not in tours if "primary_purpose" not in tours.columns: # if not already there, then it will have been added by stop_freq_annotate_tours_preprocessor - assign_in_place(tours, tours_merged[["primary_purpose"]]) + assign_in_place( + tours, + tours_merged[["primary_purpose"]], + state.settings.downcast_int, + state.settings.downcast_float, + ) state.add_table("tours", tours) diff --git a/activitysim/abm/models/telecommute_frequency.py b/activitysim/abm/models/telecommute_frequency.py index 300c81454..19bd850f8 100755 --- a/activitysim/abm/models/telecommute_frequency.py +++ b/activitysim/abm/models/telecommute_frequency.py @@ -102,6 +102,11 @@ def telecommute_frequency( ) choices = pd.Series(model_spec.columns[choices.values], index=choices.index) + telecommute_frequency_cat = pd.api.types.CategoricalDtype( + model_spec.columns.tolist() + [""], + ordered=False, + ) + choices = choices.astype(telecommute_frequency_cat) if estimator: estimator.write_choices(choices) @@ -111,9 +116,7 @@ def telecommute_frequency( estimator.write_override_choices(choices) estimator.end_estimation() - persons["telecommute_frequency"] = ( - choices.reindex(persons.index).fillna("").astype(str) - ) + persons["telecommute_frequency"] = choices.reindex(persons.index).fillna("") state.add_table("persons", persons) diff --git a/activitysim/abm/models/tour_mode_choice.py b/activitysim/abm/models/tour_mode_choice.py index bc117be5a..c6b8a5e00 100644 --- a/activitysim/abm/models/tour_mode_choice.py +++ b/activitysim/abm/models/tour_mode_choice.py @@ -77,11 +77,16 @@ def create_logsum_trips( Table of trips: 2 per tour, with O/D and purpose inherited from tour """ stop_frequency_alts = state.get_injectable("stop_frequency_alts") + stop_freq_cat_type = pd.api.types.CategoricalDtype( + stop_frequency_alts.index.tolist() + [""], ordered=False + ) stop_freq = "0out_0in" # no intermediate stops tours["stop_frequency"] = stop_freq + tours["stop_frequency"] = tours["stop_frequency"].astype(stop_freq_cat_type) tours["primary_purpose"] = tours["tour_purpose"] trips = trip.initialize_from_tours(state, tours, stop_frequency_alts) trips["stop_frequency"] = stop_freq + outbound = trips["outbound"] trips["depart"] = reindex(tours.start, trips.tour_id) trips.loc[~outbound, "depart"] = reindex(tours.end, trips.loc[~outbound, "tour_id"]) @@ -93,10 +98,12 @@ def create_logsum_trips( state, model_settings, segment_name, trace_label ) + mode_cat_type = pd.api.types.CategoricalDtype(tour_mode_alts + [""], ordered=False) # repeat rows from the trips table iterating over tour mode logsum_trips = pd.DataFrame() for tour_mode in tour_mode_alts: trips["tour_mode"] = tour_mode + trips["tour_mode"] = trips["tour_mode"].astype(mode_cat_type) logsum_trips = pd.concat((logsum_trips, trips), ignore_index=True) assert len(logsum_trips) == len(trips) * len(tour_mode_alts) logsum_trips.index.name = "trip_id" @@ -330,7 +337,7 @@ def tour_mode_choice_simulate( choices_list = [] for tour_purpose, tours_segment in primary_tours_merged.groupby( - segment_column_name + segment_column_name, observed=True ): logger.info( "tour_mode_choice_simulate tour_type '%s' (%s tours)" @@ -413,11 +420,21 @@ def tour_mode_choice_simulate( ) # so we can trace with annotations - assign_in_place(primary_tours, choices_df) + assign_in_place( + primary_tours, + choices_df, + state.settings.downcast_int, + state.settings.downcast_float, + ) # update tours table with mode choice (and optionally logsums) all_tours = tours - assign_in_place(all_tours, choices_df) + assign_in_place( + all_tours, + choices_df, + state.settings.downcast_int, + state.settings.downcast_float, + ) if ( state.is_table("school_escort_tours") diff --git a/activitysim/abm/models/trip_destination.py b/activitysim/abm/models/trip_destination.py index 210479121..f4413e00f 100644 --- a/activitysim/abm/models/trip_destination.py +++ b/activitysim/abm/models/trip_destination.py @@ -906,11 +906,18 @@ def trip_destination_simulate( skims = skim_hotel.sample_skims(presample=False) - if not np.issubdtype(trips["trip_period"].dtype, np.integer): + if isinstance(trips["trip_period"].dtype, pd.api.types.CategoricalDtype): if hasattr(skims["odt_skims"], "map_time_periods"): trip_period_idx = skims["odt_skims"].map_time_periods(trips) if trip_period_idx is not None: trips["trip_period"] = trip_period_idx + elif not np.issubdtype(trips["trip_period"].dtype, np.integer): + if hasattr(skims["odt_skims"], "map_time_periods"): + trip_period_idx = skims["odt_skims"].map_time_periods(trips) + if trip_period_idx is not None: + trips["trip_period"] = trip_period_idx + else: + None locals_dict = model_settings.CONSTANTS.copy() locals_dict.update( @@ -1356,7 +1363,17 @@ def run_trip_destination( trace_label=nth_trace_label, ) - if not np.issubdtype(nth_trips["trip_period"].dtype, np.integer): + if isinstance( + nth_trips["trip_period"].dtype, pd.api.types.CategoricalDtype + ): + skims = network_los.get_default_skim_dict() + if hasattr(skims, "map_time_periods_from_series"): + trip_period_idx = skims.map_time_periods_from_series( + nth_trips["trip_period"] + ) + if trip_period_idx is not None: + nth_trips["trip_period"] = trip_period_idx + elif not np.issubdtype(nth_trips["trip_period"].dtype, np.integer): skims = network_los.get_default_skim_dict() if hasattr(skims, "map_time_periods_from_series"): trip_period_idx = skims.map_time_periods_from_series( @@ -1364,12 +1381,16 @@ def run_trip_destination( ) if trip_period_idx is not None: nth_trips["trip_period"] = trip_period_idx + else: + None logger.info("Running %s with %d trips", nth_trace_label, nth_trips.shape[0]) # - choose destination for nth_trips, segmented by primary_purpose choices_list = [] - for primary_purpose, trips_segment in nth_trips.groupby("primary_purpose"): + for primary_purpose, trips_segment in nth_trips.groupby( + "primary_purpose", observed=True + ): choices, destination_sample = choose_trip_destination( state, primary_purpose, @@ -1422,18 +1443,31 @@ def run_trip_destination( # - assign choices to this trip's destinations # if estimator, then the choices will already have been overridden by trip_destination_simulate # because we need to overwrite choices before any failed choices are suppressed - assign_in_place(trips, destinations_df.choice.to_frame("destination")) + assign_in_place( + trips, + destinations_df.choice.to_frame("destination"), + state.settings.downcast_int, + state.settings.downcast_float, + ) if want_logsums: assert "logsum" in destinations_df.columns assign_in_place( - trips, destinations_df.logsum.to_frame(logsum_column_name) + trips, + destinations_df.logsum.to_frame(logsum_column_name), + state.settings.downcast_int, + state.settings.downcast_float, ) # - assign choice to next trip's origin destinations_df.index = nth_trips.next_trip_id.reindex( destinations_df.index ) - assign_in_place(trips, destinations_df.choice.to_frame("origin")) + assign_in_place( + trips, + destinations_df.choice.to_frame("origin"), + state.settings.downcast_int, + state.settings.downcast_float, + ) del trips["next_trip_id"] diff --git a/activitysim/abm/models/trip_mode_choice.py b/activitysim/abm/models/trip_mode_choice.py index 25f20cc05..b9091522c 100644 --- a/activitysim/abm/models/trip_mode_choice.py +++ b/activitysim/abm/models/trip_mode_choice.py @@ -208,7 +208,9 @@ def trip_mode_choice( choices_list = [] cols_to_keep_list = [] - for primary_purpose, trips_segment in trips_merged.groupby("primary_purpose"): + for primary_purpose, trips_segment in trips_merged.groupby( + "primary_purpose", observed=True + ): segment_trace_label = tracing.extend_trace_label(trace_label, primary_purpose) logger.info( @@ -287,7 +289,12 @@ def trip_mode_choice( ) # so we can trace with annotations - assign_in_place(trips_segment, choices) + assign_in_place( + trips_segment, + choices, + state.settings.downcast_int, + state.settings.downcast_float, + ) state.tracing.trace_df( trips_segment, @@ -338,7 +345,9 @@ def trip_mode_choice( cols_to_keep_df = pd.concat(cols_to_keep_list) choices_df = pd.concat([choices_df, cols_to_keep_df], axis=1) - assign_in_place(trips_df, choices_df) + assign_in_place( + trips_df, choices_df, state.settings.downcast_int, state.settings.downcast_float + ) if ( state.is_table("school_escort_tours") diff --git a/activitysim/abm/models/trip_purpose.py b/activitysim/abm/models/trip_purpose.py index 1570d672c..5f208f514 100644 --- a/activitysim/abm/models/trip_purpose.py +++ b/activitysim/abm/models/trip_purpose.py @@ -161,6 +161,11 @@ def choose_intermediate_trip_purpose( state.tracing.trace_df(rands, "%s.rands" % trace_label, columns=[None, "rand"]) choices = choices.map(pd.Series(purpose_cols)) + # expand the purpose categorical + for p in purpose_cols: + if not p in trips.primary_purpose.cat.categories: + trips.primary_purpose = trips.primary_purpose.cat.add_categories([p]) + choices = choices.astype(trips["primary_purpose"].dtype) return choices @@ -222,17 +227,25 @@ def run_trip_purpose( result_list = [] + # add home to purpose categorical + # check if parking_name is in the purpose category + if not "home" in trips_df.primary_purpose.cat.categories: + trips_df.primary_purpose = trips_df.primary_purpose.cat.add_categories(["home"]) + # - last trip of outbound tour gets primary_purpose last_trip = trips_df.trip_num == trips_df.trip_count purpose = trips_df.primary_purpose[last_trip & trips_df.outbound] + print(purpose.value_counts(dropna=False)) result_list.append(purpose) logger.info("assign purpose to %s last outbound trips", purpose.shape[0]) # - last trip of inbound tour gets home (or work for atwork subtours) purpose = trips_df.primary_purpose[last_trip & ~trips_df.outbound] + print(purpose.value_counts(dropna=False)) purpose = pd.Series( np.where(purpose == "atwork", "work", "home"), index=purpose.index - ) + ).astype(trips_df.primary_purpose.dtype) + print(purpose.value_counts(dropna=False)) result_list.append(purpose) logger.info("assign purpose to %s last inbound trips", purpose.shape[0]) @@ -270,7 +283,7 @@ def run_trip_purpose( trace_label=chunk_trace_label, chunk_sizer=chunk_sizer, ) - + print(choices.value_counts(dropna=False)) result_list.append(choices) chunk_sizer.log_df(trace_label, "result_list", result_list) diff --git a/activitysim/abm/models/trip_purpose_and_destination.py b/activitysim/abm/models/trip_purpose_and_destination.py index 146588088..d32703ca0 100644 --- a/activitysim/abm/models/trip_purpose_and_destination.py +++ b/activitysim/abm/models/trip_purpose_and_destination.py @@ -231,7 +231,12 @@ def trip_purpose_and_destination( ) trips_df = trips - assign_in_place(trips_df, processed_trips) + assign_in_place( + trips_df, + processed_trips, + state.settings.downcast_int, + state.settings.downcast_float, + ) trips_df = cleanup_failed_trips(trips_df) diff --git a/activitysim/abm/models/util/canonical_ids.py b/activitysim/abm/models/util/canonical_ids.py index 0ca1a1d3b..ab2623916 100644 --- a/activitysim/abm/models/util/canonical_ids.py +++ b/activitysim/abm/models/util/canonical_ids.py @@ -182,7 +182,7 @@ def determine_flavors_from_alts_file( flavors = { c: int(alts[c].max() + max_extension) for c in alts.columns - if all(alts[c].astype(str).str.isnumeric()) + if all(alts[c].astype(str).str.isnumeric()) and (c != "tot_tours") } valid_flavors = all( [(isinstance(flavor, str) & (num >= 0)) for flavor, num in flavors.items()] @@ -383,7 +383,7 @@ def set_tour_index( assert tour_num_col in tours.columns # create string tour_id corresonding to keys in possible_tours (e.g. 'work1', 'j_shopping2') - tours["tour_id"] = tours.tour_type + tours[tour_num_col].map(str) + tours["tour_id"] = tours.tour_type.astype(str) + tours[tour_num_col].map(str) if parent_tour_num_col: # we need to distinguish between subtours of different work tours diff --git a/activitysim/abm/models/util/logsums.py b/activitysim/abm/models/util/logsums.py index b92045fa8..328957965 100644 --- a/activitysim/abm/models/util/logsums.py +++ b/activitysim/abm/models/util/logsums.py @@ -84,9 +84,9 @@ def compute_location_choice_logsums( computed logsums with same index as choosers """ if isinstance(model_settings, dict): - model_settings = TourLocationComponentSettings.parse_obj(model_settings) + model_settings = TourLocationComponentSettings.model_validate(model_settings) if isinstance(logsum_settings, dict): - logsum_settings = TourModeComponentSettings.parse_obj(logsum_settings) + logsum_settings = TourModeComponentSettings.model_validate(logsum_settings) trace_label = tracing.extend_trace_label(trace_label, "compute_logsums") logger.debug(f"Running compute_logsums with {choosers.shape[0]:d} choosers") diff --git a/activitysim/abm/models/util/mode.py b/activitysim/abm/models/util/mode.py index 341cf7391..b6e6bbb23 100644 --- a/activitysim/abm/models/util/mode.py +++ b/activitysim/abm/models/util/mode.py @@ -84,6 +84,8 @@ def mode_choice_simulate( choices[mode_column_name] = choices[mode_column_name].map( dict(list(zip(list(range(len(alts))), alts))) ) + cat_type = pd.api.types.CategoricalDtype([""] + alts.tolist(), ordered=True) + choices[mode_column_name] = choices[mode_column_name].astype(cat_type) return choices diff --git a/activitysim/abm/models/util/school_escort_tours_trips.py b/activitysim/abm/models/util/school_escort_tours_trips.py index 64101c45e..42108dfbd 100644 --- a/activitysim/abm/models/util/school_escort_tours_trips.py +++ b/activitysim/abm/models/util/school_escort_tours_trips.py @@ -315,6 +315,14 @@ def add_pure_escort_tours(tours, school_escort_tours): def add_school_escorting_type_to_tours_table(escort_bundles, tours): school_tour = (tours.tour_type == "school") & (tours.tour_num == 1) + escort_type_cat = pd.api.types.CategoricalDtype( + ["pure_escort", "ride_share"], ordered=False + ) + tours["school_esc_outbound"] = pd.NA + tours["school_esc_inbound"] = pd.NA + tours["school_esc_outbound"] = tours["school_esc_outbound"].astype(escort_type_cat) + tours["school_esc_inbound"] = tours["school_esc_inbound"].astype(escort_type_cat) + for school_escort_direction in ["outbound", "inbound"]: for escort_type in ["ride_share", "pure_escort"]: bundles = escort_bundles[ @@ -438,6 +446,19 @@ def merge_school_escort_trips_into_pipeline(state: workflow.State): # for better merge with trips created in stop frequency school_escort_trips["failed"] = False + # make sure the pandas categorical columns share the same categories before cancat + # union categoricals + for c in trips.columns.intersection(school_escort_trips.columns): + if isinstance(trips[c].dtype, pd.api.types.CategoricalDtype): + if isinstance(school_escort_trips[c].dtype, pd.api.types.CategoricalDtype): + from pandas.api.types import union_categoricals + + uc = union_categoricals([trips[c], school_escort_trips[c]]) + trips[c] = pd.Categorical(trips[c], categories=uc.categories) + school_escort_trips[c] = pd.Categorical( + school_escort_trips[c], categories=uc.categories + ) + trips = pd.concat( [ trips, @@ -466,6 +487,12 @@ def merge_school_escort_trips_into_pipeline(state: workflow.State): trips["origin"] = trips["origin"].astype(int) trips["destination"] = trips["destination"].astype(int) + # converting to categoricals + trips["school_escort_direction"] = trips["school_escort_direction"].astype( + "category" + ) + trips["escort_participants"] = trips["escort_participants"].astype("category") + # updating trip_id now that we have all trips trips = canonical_ids.set_trip_index(state, trips) school_escort_trip_id_map = { @@ -526,6 +553,12 @@ def recompute_tour_count_statistics(state: workflow.State): tours["tour_num"] = grouped.cumcount() + 1 tours["tour_count"] = tours["tour_num"] + grouped.cumcount(ascending=False) + # downcast + tours["tour_count"] = tours["tour_count"].astype("int8") + tours["tour_num"] = tours["tour_num"].astype("int8") + tours["tour_type_num"] = tours["tour_type_num"].astype("int8") + tours["tour_type_count"] = tours["tour_type_count"].astype("int8") + state.add_table("tours", tours) @@ -554,8 +587,16 @@ def create_pure_school_escort_tours(state: workflow.State, bundles): pe_tours["person_id"] = pe_tours["chauf_id"] pe_tours["tour_category"] = "non_mandatory" + # convert tour category to categorical + pe_tours["tour_category"] = pe_tours["tour_category"].astype( + state.get_dataframe("tours").tour_category.dtype + ) pe_tours["number_of_participants"] = 1 pe_tours["tour_type"] = "escort" + # convert tour type to categorical + pe_tours["tour_type"] = pe_tours["tour_type"].astype( + state.get_dataframe("tours").tour_type.dtype + ) pe_tours["school_esc_outbound"] = np.where( pe_tours["school_escort_direction"] == "outbound", "pure_escort", pd.NA ) diff --git a/activitysim/abm/models/util/test/test_mandatory_tour_frequency.py b/activitysim/abm/models/util/test/test_mandatory_tour_frequency.py index 0fdb5e1e6..8f2df86e8 100644 --- a/activitysim/abm/models/util/test/test_mandatory_tour_frequency.py +++ b/activitysim/abm/models/util/test/test_mandatory_tour_frequency.py @@ -56,29 +56,44 @@ def test_mtf(): pdt.assert_series_equal( mandatory_tours.person_id, pd.Series([10, 20, 20, 30, 30, 40, 40], index=idx, name="person_id"), + check_dtype=False, ) - pdt.assert_series_equal( - mandatory_tours.tour_type, - pd.Series( - ["work", "work", "school", "work", "school", "school", "school"], - index=idx, - name="tour_type", - ), - ) + # check if the tour_type variable is pandas categorical + if isinstance(mandatory_tours.tour_type.dtype, pd.api.types.CategoricalDtype): + pdt.assert_series_equal( + mandatory_tours.tour_type.astype(str), + pd.Series( + ["work", "work", "school", "work", "school", "school", "school"], + index=idx, + name="tour_type", + ), + ) + else: + pdt.assert_series_equal( + mandatory_tours.tour_type, + pd.Series( + ["work", "work", "school", "work", "school", "school", "school"], + index=idx, + name="tour_type", + ), + ) # tour_nums for work_and_school non-worker should be flipped pdt.assert_series_equal( mandatory_tours.tour_num, pd.Series([1, 1, 2, 2, 1, 1, 2], index=idx, name="tour_num"), + check_dtype=False, ) pdt.assert_series_equal( mandatory_tours.destination, pd.Series([10, 20, 2, 30, 3, 4, 4], index=idx, name="destination"), + check_dtype=False, ) pdt.assert_series_equal( mandatory_tours.origin, pd.Series([100, 200, 200, 300, 300, 400, 400], index=idx, name="origin"), + check_dtype=False, ) diff --git a/activitysim/abm/models/util/test/test_non_mandatory_tour_frequency.py b/activitysim/abm/models/util/test/test_non_mandatory_tour_frequency.py index 6f25a8735..6dc8f591e 100644 --- a/activitysim/abm/models/util/test/test_non_mandatory_tour_frequency.py +++ b/activitysim/abm/models/util/test/test_non_mandatory_tour_frequency.py @@ -40,9 +40,22 @@ def test_nmtf(): nmt.person_id, pd.Series([0, 2, 2, 3], index=idx, name="person_id") ) - pdt.assert_series_equal( - nmt.tour_type, - pd.Series( - ["shopping", "escort", "escort", "othmaint"], index=idx, name="tour_type" - ), - ) + # check if the tour_type variable is pandas categorical + if isinstance(nmt.tour_type.dtype, pd.api.types.CategoricalDtype): + pdt.assert_series_equal( + nmt.tour_type.astype(str), + pd.Series( + ["shopping", "escort", "escort", "othmaint"], + index=idx, + name="tour_type", + ), + ) + else: + pdt.assert_series_equal( + nmt.tour_type, + pd.Series( + ["shopping", "escort", "escort", "othmaint"], + index=idx, + name="tour_type", + ), + ) diff --git a/activitysim/abm/models/util/test/test_vehicle_type_alts.py b/activitysim/abm/models/util/test/test_vehicle_type_alts.py new file mode 100644 index 000000000..d9cf1c176 --- /dev/null +++ b/activitysim/abm/models/util/test/test_vehicle_type_alts.py @@ -0,0 +1,59 @@ +# ActivitySim +# See full license in LICENSE.txt. + +import pandas as pd +import pandas.testing as pdt + +from activitysim.abm.models.vehicle_type_choice import ( + get_combinatorial_vehicle_alternatives, + construct_model_alternatives, + VehicleTypeChoiceSettings, +) +from activitysim.core import workflow + + +def test_vehicle_type_alts(): + state = workflow.State.make_default(__file__) + + alts_cats_dict = { + "body_type": ["Car", "SUV"], + "fuel_type": ["Gas", "BEV"], + "age": [1, 2, 3], + } + + alts_wide, alts_long = get_combinatorial_vehicle_alternatives(alts_cats_dict) + + # alts are initially constructed combinatorially + assert len(alts_long) == 12, "alts_long should have 12 rows" + assert len(alts_wide) == 12, "alts_wide should have 12 rows" + + model_settings = VehicleTypeChoiceSettings.model_construct() + model_settings.combinatorial_alts = alts_cats_dict + model_settings.PROBS_SPEC = None + model_settings.WRITE_OUT_ALTS_FILE = False + + # constructing veh type data with missing alts + vehicle_type_data = pd.DataFrame( + data={ + "body_type": ["Car", "Car", "Car", "SUV", "SUV"], + "fuel_type": ["Gas", "Gas", "BEV", "Gas", "BEV"], + "age": ["1", "2", "3", "1", "2"], + "dummy_data": [1, 2, 3, 4, 5], + }, + index=[0, 1, 2, 3, 4], + ) + + alts_wide, alts_long = construct_model_alternatives( + state, model_settings, alts_cats_dict, vehicle_type_data + ) + + # should only have alts left that are in the file + assert len(alts_long) == 5, "alts_long should have 5 rows" + + # indexes need to be the same to choices match alts + pdt.assert_index_equal(alts_long.index, alts_wide.index) + + # columns need to be in correct order for downstream configs + pdt.assert_index_equal( + alts_long.columns, pd.Index(["body_type", "age", "fuel_type"]) + ) diff --git a/activitysim/abm/models/util/tour_frequency.py b/activitysim/abm/models/util/tour_frequency.py index 8c5c9ff04..eff354965 100644 --- a/activitysim/abm/models/util/tour_frequency.py +++ b/activitysim/abm/models/util/tour_frequency.py @@ -101,6 +101,10 @@ def create_tours(tour_counts, tour_category, parent_col="person_id"): # do not enforce this here, other categories are possible # assert tour_category in ["mandatory", "non_mandatory", "atwork", "joint"] tours["tour_category"] = tour_category + cat_tour_category = pd.api.types.CategoricalDtype( + ["mandatory", "joint", "non_mandatory", "atwork"], ordered=False + ) + tours["tour_category"] = tours["tour_category"].astype(cat_tour_category) # for joint tours, the correct number will be filled in after participation step tours["number_of_participants"] = 1 @@ -108,6 +112,13 @@ def create_tours(tour_counts, tour_category, parent_col="person_id"): # index is arbitrary but don't want any duplicates in index tours.reset_index(drop=True, inplace=True) + # downcast + tours["tour_count"] = tours["tour_count"].astype("int8") + tours["tour_num"] = tours["tour_num"].astype("int8") + tours["tour_type_num"] = tours["tour_type_num"].astype("int8") + tours["tour_type_count"] = tours["tour_type_count"].astype("int8") + tours["number_of_participants"] = tours["number_of_participants"].astype("int8") + return tours @@ -718,6 +729,10 @@ def create_joint_tours( tours_comp.columns = [parent_col, "tour_id_temp", "composition"] tours_comp["tour_id_temp"] = range(1, 1 + len(tours_comp)) tours_comp["composition"] = tours_comp["composition"].map(tour_comp_dict) + cat_tour_comp = pd.api.types.CategoricalDtype( + ["adults", "children", "mixed"], ordered=False + ) + tours_comp["composition"] = tours_comp["composition"].astype(cat_tour_comp) """ tour_id_temp tour_composition @@ -759,6 +774,10 @@ def create_joint_tours( # set these here to ensure consistency across different tour categories assert tour_category in ["mandatory", "non_mandatory", "atwork", "joint"] tours["tour_category"] = tour_category + cat_tour_category = pd.api.types.CategoricalDtype( + ["mandatory", "joint", "non_mandatory", "atwork"], ordered=False + ) + tours["tour_category"] = tours["tour_category"].astype(cat_tour_category) # for joint tours, the correct number will be filled in after participation step tours["number_of_participants"] = 1 @@ -766,4 +785,11 @@ def create_joint_tours( # index is arbitrary but don't want any duplicates in index tours.reset_index(drop=True, inplace=True) + # downcast + tours["tour_count"] = tours["tour_count"].astype("int8") + tours["tour_num"] = tours["tour_num"].astype("int8") + tours["tour_type_num"] = tours["tour_type_num"].astype("int8") + tours["tour_type_count"] = tours["tour_type_count"].astype("int8") + tours["number_of_participants"] = tours["number_of_participants"].astype("int8") + return tours diff --git a/activitysim/abm/models/util/trip.py b/activitysim/abm/models/util/trip.py index 08b4e737d..2ffb8750b 100644 --- a/activitysim/abm/models/util/trip.py +++ b/activitysim/abm/models/util/trip.py @@ -84,7 +84,12 @@ def cleanup_failed_trips(trips): ascending=False ) - assign_in_place(trips, patch_trips[["trip_num", "trip_count"]]) + assign_in_place( + trips, + patch_trips[["trip_num", "trip_count"]], + state.settings.downcast_int, + state.settings.downcast_float, + ) # origin needs to match the previous destination # (leaving first origin alone as it's already set correctly) @@ -171,6 +176,7 @@ def initialize_from_tours( """ OUTBOUND_ALT = "out" + direction_cat_type = pd.api.types.CategoricalDtype(["out", "in"], ordered=False) assert OUTBOUND_ALT in stop_frequency_alts.columns # get the actual alternatives for each person - have to go back to the diff --git a/activitysim/abm/models/util/vectorize_tour_scheduling.py b/activitysim/abm/models/util/vectorize_tour_scheduling.py index 0d65ab0fa..17425d75b 100644 --- a/activitysim/abm/models/util/vectorize_tour_scheduling.py +++ b/activitysim/abm/models/util/vectorize_tour_scheduling.py @@ -3,6 +3,7 @@ from __future__ import annotations import logging +from collections import OrderedDict from pathlib import Path from typing import Any @@ -189,7 +190,9 @@ def _compute_logsums( if preprocessor_settings: simulate.set_skim_wrapper_targets(choosers, skims) - + logger.info( + f"{trace_label} start preprocessing prior to compute_logsums for {choosers.shape[0]} choosers {alt_tdd.shape[0]} alts" + ) expressions.assign_columns( state, df=choosers, @@ -197,6 +200,9 @@ def _compute_logsums( locals_dict=locals_dict, trace_label=trace_label, ) + logger.info( + f"{trace_label} end preprocessing prior to compute_logsums for {choosers.shape[0]} choosers {alt_tdd.shape[0]} alts" + ) # - compute logsums logsum_spec = state.filesystem.read_model_spec(file_name=logsum_settings.SPEC) @@ -239,6 +245,10 @@ def dedupe_alt_tdd(state: workflow.State, alt_tdd, tour_purpose, trace_label): state, tracing.extend_trace_label(trace_label, "dedupe_alt_tdd") ) as chunk_sizer: if tdd_segments is not None: + tdd_segments["time_period"] = tdd_segments["time_period"].astype( + alt_tdd["out_period"].dtype + ) + dedupe_columns = ["out_period", "in_period"] # tdd_alt_segments is optionally segmented by tour purpose diff --git a/activitysim/abm/models/vehicle_allocation.py b/activitysim/abm/models/vehicle_allocation.py index e4cb13489..e4129e106 100644 --- a/activitysim/abm/models/vehicle_allocation.py +++ b/activitysim/abm/models/vehicle_allocation.py @@ -254,6 +254,7 @@ def vehicle_allocation( # creating a column for choice of each occupancy level tours_veh_occup_col = f"vehicle_occup_{occup}" tours[tours_veh_occup_col] = choices["choice"] + tours[tours_veh_occup_col] = tours[tours_veh_occup_col].astype("category") tours_veh_occup_cols.append(tours_veh_occup_col) if estimator: diff --git a/activitysim/abm/models/vehicle_type_choice.py b/activitysim/abm/models/vehicle_type_choice.py index a2ea7b0bd..6b17d9e35 100644 --- a/activitysim/abm/models/vehicle_type_choice.py +++ b/activitysim/abm/models/vehicle_type_choice.py @@ -244,7 +244,19 @@ def construct_model_alternatives( ), f"missing vehicle data for alternatives:\n {missing_alts}" else: # eliminate alternatives if no vehicle type data + num_alts_before_filer = len(alts_wide) alts_wide = alts_wide[alts_wide._merge != "left_only"] + logger.warning( + f"Removed {num_alts_before_filer - len(alts_wide)} alternatives not included in input vehicle type data." + ) + # need to also remove any alts from alts_long + alts_long.set_index(["body_type", "age", "fuel_type"], inplace=True) + alts_long = alts_long[ + alts_long.index.isin( + alts_wide.set_index(["body_type", "age", "fuel_type"]).index + ) + ].reset_index() + alts_long.index = alts_wide.index alts_wide.drop(columns="_merge", inplace=True) # converting age to integer to allow interactions in utilities @@ -358,6 +370,8 @@ def iterate_vehicle_type_choice( else: vehicle_type_data = None + # initialize categorical type for vehicle_type + vehicle_type_cat = "category" # - Preparing alternatives # create alts on-the-fly as cartesian product of categorical values if alts_cats_dict: @@ -365,11 +379,34 @@ def iterate_vehicle_type_choice( alts_wide, alts_long = construct_model_alternatives( state, model_settings, alts_cats_dict, vehicle_type_data ) + # convert alternative names to categoricals + # body_type, fuel_type, vehicle_type + # age should be a int becuase it is used as a numeric value in utilities + body_type_cat = pd.api.types.CategoricalDtype( + alts_cats_dict["body_type"], ordered=False + ) + fuel_type_cat = pd.api.types.CategoricalDtype( + alts_cats_dict["fuel_type"], ordered=False + ) + vehicle_type_cat = pd.api.types.CategoricalDtype( + list(set(alts_wide["vehicle_type"])) + [""], ordered=False + ) + + alts_wide["body_type"] = alts_wide["body_type"].astype(body_type_cat) + alts_wide["fuel_type"] = alts_wide["fuel_type"].astype(fuel_type_cat) + alts_wide["vehicle_type"] = alts_wide["vehicle_type"].astype(vehicle_type_cat) else: alts_wide = alts_long = None + alts = model_spec.columns + vehicle_type_cat = pd.api.types.CategoricalDtype( + list(set(alts)) + [""], ordered=False + ) # - preparing choosers for iterating vehicles_merged["already_owned_veh"] = "" + vehicles_merged["already_owned_veh"] = vehicles_merged["already_owned_veh"].astype( + vehicle_type_cat + ) logger.info("Running %s with %d vehicles", trace_label, len(vehicles_merged)) all_choosers = [] all_choices = [] @@ -455,11 +492,11 @@ def iterate_vehicle_type_choice( alts = ( alts_long[alts_long.columns] .apply(lambda row: "_".join(row.values.astype(str)), axis=1) - .values + .to_dict() ) else: - alts = model_spec.columns - choices["vehicle_type"] = choices["vehicle_type"].map(dict(enumerate(alts))) + alts = enumerate(dict(model_spec.columns)) + choices["vehicle_type"] = choices["vehicle_type"].map(alts) # STEP II: append probabilistic vehicle type attributes if probs_spec_file is not None: @@ -467,6 +504,9 @@ def iterate_vehicle_type_choice( state, choices, model_settings, trace_label ) + # convert vehicle_type to categorical + choices["vehicle_type"] = choices["vehicle_type"].astype(vehicle_type_cat) + vehicles_merged.loc[choices.index, "already_owned_veh"] = choices[ "vehicle_type" ] @@ -481,6 +521,9 @@ def iterate_vehicle_type_choice( additional_cols = model_settings.COLS_TO_INCLUDE_IN_VEHICLE_TABLE if additional_cols: additional_cols.append("vehicle_type") + vehicle_type_data["vehicle_type"] = vehicle_type_data["vehicle_type"].astype( + vehicle_type_cat + ) all_choices = ( all_choices.reset_index() .merge(vehicle_type_data[additional_cols], how="left", on="vehicle_type") diff --git a/activitysim/abm/tables/shadow_pricing.py b/activitysim/abm/tables/shadow_pricing.py index 6b06a9d58..1b28883df 100644 --- a/activitysim/abm/tables/shadow_pricing.py +++ b/activitysim/abm/tables/shadow_pricing.py @@ -1233,7 +1233,7 @@ def load_shadow_price_calculator( spc : ShadowPriceCalculator """ if not isinstance(model_settings, TourLocationComponentSettings): - model_settings = TourLocationComponentSettings.parse_obj(model_settings) + model_settings = TourLocationComponentSettings.model_validate(model_settings) num_processes = state.get_injectable("num_processes", 1) diff --git a/activitysim/abm/test/test_misc/test_load_cached_accessibility.py b/activitysim/abm/test/test_misc/test_load_cached_accessibility.py index b19d13646..60288d67c 100644 --- a/activitysim/abm/test/test_misc/test_load_cached_accessibility.py +++ b/activitysim/abm/test/test_misc/test_load_cached_accessibility.py @@ -58,7 +58,7 @@ def test_load_cached_accessibility(): settings = state.settings input_table_list = settings.input_table_list input_table_list.append( - configuration.InputTable.parse_obj( + configuration.InputTable.model_validate( { "tablename": "accessibility", "filename": "cached_accessibility.csv", diff --git a/activitysim/abm/test/test_pipeline/test_pipeline.py b/activitysim/abm/test/test_pipeline/test_pipeline.py index 6afb7cb8f..d5b4253b6 100644 --- a/activitysim/abm/test/test_pipeline/test_pipeline.py +++ b/activitysim/abm/test/test_pipeline/test_pipeline.py @@ -151,7 +151,7 @@ def regress_mini_mtf(state: workflow.State): Name: mandatory_tour_frequency, dtype: object """ pdt.assert_series_equal( - mtf_choice.reindex(per_ids), expected_choice, check_dtype=False + mtf_choice.astype(str).reindex(per_ids), expected_choice, check_dtype=False ) @@ -332,6 +332,8 @@ def regress_tour_modes(tours_df): mode_cols = ["tour_mode", "person_id", "tour_type", "tour_num", "tour_category"] tours_df = tours_df[tours_df.household_id == HH_ID] + # convert tour_category from categorical to string for comparison + tours_df.tour_category = tours_df.tour_category.astype(str) tours_df = tours_df.sort_values(by=["person_id", "tour_category", "tour_num"]) print("mode_df\n%s" % tours_df[mode_cols]) @@ -369,8 +371,8 @@ def regress_tour_modes(tours_df): assert len(tours_df) == len(EXPECT_PERSON_IDS) assert (tours_df.person_id.values == EXPECT_PERSON_IDS).all() - assert (tours_df.tour_type.values == EXPECT_TOUR_TYPES).all() - assert (tours_df.tour_mode.values == EXPECT_MODES).all() + assert (tours_df.tour_type.astype(str).values == EXPECT_TOUR_TYPES).all() + assert (tours_df.tour_mode.astype(str).values == EXPECT_MODES).all() def regress(state: workflow.State): diff --git a/activitysim/core/assign.py b/activitysim/core/assign.py index 1160c571c..19693f2ab 100644 --- a/activitysim/core/assign.py +++ b/activitysim/core/assign.py @@ -358,17 +358,21 @@ def rng_lognormal(random_draws, mu, sigma, broadcast=True, scale=False): globals_dict = {} expr_values = to_series(eval(expression, globals_dict, _locals_dict)) - if ( - sharrow_enabled - and np.issubdtype(expr_values.dtype, np.floating) - and expr_values.dtype.itemsize < 4 - ): - # promote to float32, numba is not presently compatible with - # any float less than 32 (i.e., float16) - # see https://github.com/numba/numba/issues/4402 - # note this only applies to floats, signed and unsigned - # integers are readily supported down to 1 byte - expr_values = expr_values.astype(np.float32) + if sharrow_enabled: + if isinstance(expr_values.dtype, pd.api.types.CategoricalDtype): + None + elif ( + np.issubdtype(expr_values.dtype, np.floating) + and expr_values.dtype.itemsize < 4 + ): + # promote to float32, numba is not presently compatible with + # any float less than 32 (i.e., float16) + # see https://github.com/numba/numba/issues/4402 + # note this only applies to floats, signed and unsigned + # integers are readily supported down to 1 byte + expr_values = expr_values.astype(np.float32) + else: + None np.seterr(**save_err) np.seterrcall(saved_handler) @@ -392,7 +396,8 @@ def rng_lognormal(random_draws, mu, sigma, broadcast=True, scale=False): # just keeping track of temps so we can chunk.log_df if is_temp(target): - temps[target] = expr_values + if chunk_log: + temps[target] = expr_values else: variables[target] = expr_values @@ -419,4 +424,11 @@ def rng_lognormal(random_draws, mu, sigma, broadcast=True, scale=False): # we stored result in dict - convert to df variables = util.df_from_dict(variables, index=df.index) + util.auto_opt_pd_dtypes( + variables, + downcast_int=state.settings.downcast_int, + downcast_float=state.settings.downcast_float, + inplace=True, + ) + return variables, trace_results, trace_assigned_locals diff --git a/activitysim/core/configuration/base.py b/activitysim/core/configuration/base.py index 9a3f7b7cd..754865dc1 100644 --- a/activitysim/core/configuration/base.py +++ b/activitysim/core/configuration/base.py @@ -118,7 +118,7 @@ class PreprocessorSettings(PydanticBase): The preprocessor will emit rows to a temporary table that match the rows in this table from the pipeline.""" - TABLES: list[str] | None + TABLES: list[str] | None = None """Names of the additional tables to be merged for the preprocessor. Data from these tables will be merged into the primary table, according diff --git a/activitysim/core/configuration/filesystem.py b/activitysim/core/configuration/filesystem.py index 0f398c8fa..ce50becd4 100644 --- a/activitysim/core/configuration/filesystem.py +++ b/activitysim/core/configuration/filesystem.py @@ -639,7 +639,7 @@ def read_settings_file( include_stack: bool = False, configs_dir_list: tuple[Path] | None = None, validator_class: type[PydanticBase] | None = None, - ) -> dict | PydanticBase: + ) -> PydanticBase | dict: """ Load settings from one or more yaml files. @@ -817,7 +817,7 @@ def backfill_settings(settings, backfill): settings.pop("include_settings", None) if validator_class is not None: - settings = validator_class.parse_obj(settings) + settings = validator_class.model_validate(settings) if include_stack: # if we were called recursively, return an updated list of source_file_paths diff --git a/activitysim/core/configuration/top.py b/activitysim/core/configuration/top.py index d5e1addeb..c24861138 100644 --- a/activitysim/core/configuration/top.py +++ b/activitysim/core/configuration/top.py @@ -642,6 +642,24 @@ class Settings(PydanticBase, extra="allow", validate_assignment=True): the results from the previous time that step was run. """ + downcast_int: bool = False + """ + automatically downcasting integer variables. + + Use of this setting should be tested by the region to confirm result consistency. + + .. versionadded:: 1.3 + """ + + downcast_float: bool = False + """ + automatically downcasting float variables. + + Use of this setting should be tested by the region to confirm result consistency. + + .. versionadded:: 1.3 + """ + other_settings: dict[str, Any] = None def _get_attr(self, attr): diff --git a/activitysim/core/estimation.py b/activitysim/core/estimation.py index ae8edeb84..f6a6ebc7c 100644 --- a/activitysim/core/estimation.py +++ b/activitysim/core/estimation.py @@ -701,6 +701,23 @@ def get_survey_values(self, model_values, table_name, column_names): values[c] = survey_values + # if the categorical column exists in the model data, use the same data type + if isinstance(model_values, pd.Series): + if isinstance(model_values.dtype, pd.api.types.CategoricalDtype): + for v in values[c].dropna().unique(): + if not v in model_values.cat.categories: + model_values = model_values.cat.add_categories([v]) + values[c] = values[c].astype(model_values.dtype) + elif isinstance(model_values, pd.DataFrame): + if c in model_values.columns: + if isinstance(model_values[c].dtype, pd.api.types.CategoricalDtype): + for v in values[c].dropna().unique(): + if not v in model_values[c].cat.categories: + model_values[c] = model_values[c].cat.add_categories( + [v] + ) + values[c] = values[c].astype(model_values[c].dtype) + return values[column_name] if column_name else values diff --git a/activitysim/core/expressions.py b/activitysim/core/expressions.py index 9ee3ac20e..413636d3f 100644 --- a/activitysim/core/expressions.py +++ b/activitysim/core/expressions.py @@ -171,7 +171,9 @@ def assign_columns( results = compute_columns(state, df, model_settings, locals_dict, trace_label) - assign_in_place(df, results) + assign_in_place( + df, results, state.settings.downcast_int, state.settings.downcast_float + ) # ################################################################################################## @@ -212,7 +214,9 @@ def annotate_preprocessors( trace_label=trace_label, ) - assign_in_place(df, results) + assign_in_place( + df, results, state.settings.downcast_int, state.settings.downcast_float + ) def filter_chooser_columns(choosers, chooser_columns): diff --git a/activitysim/core/interaction_sample_simulate.py b/activitysim/core/interaction_sample_simulate.py index c69880c7b..b42eb2683 100644 --- a/activitysim/core/interaction_sample_simulate.py +++ b/activitysim/core/interaction_sample_simulate.py @@ -131,8 +131,13 @@ def _interaction_sample_simulate( # assert alternatives.index.name == choosers.index.name # asserting the index names are the same tells us nothing about the underlying data so why? - + logger.info( + f"{trace_label} start merging choosers and alternatives to create interaction_df" + ) interaction_df = alternatives.join(choosers, how="left", rsuffix="_chooser") + logger.info( + f"{trace_label} end merging choosers and alternatives to create interaction_df" + ) if log_alt_losers: # logit.interaction_dataset adds ALT_CHOOSER_ID column if log_alt_losers is True diff --git a/activitysim/core/interaction_simulate.py b/activitysim/core/interaction_simulate.py index f1ae6e7ea..451345f2f 100644 --- a/activitysim/core/interaction_simulate.py +++ b/activitysim/core/interaction_simulate.py @@ -411,13 +411,15 @@ def to_series(x): # if sh_flow is not None and trace_rows is not None and trace_rows.any(): assert type(trace_rows) == np.ndarray + logger.info("sh_flow load dataarray") sh_utility_fat = sh_flow.load_dataarray( sh_tree.replace_datasets( df=df.iloc[trace_rows], ), dtype=np.float32, ) - # sh_utility_fat = sh_utility_fat[trace_rows, :] + logger.info("finish sh_flow load dataarray") + sh_utility_fat = sh_utility_fat[trace_rows, :] sh_utility_fat = sh_utility_fat.to_dataframe("vals") try: sh_utility_fat = sh_utility_fat.unstack("expressions") diff --git a/activitysim/core/logit.py b/activitysim/core/logit.py index 053c46e4a..9d282ddda 100644 --- a/activitysim/core/logit.py +++ b/activitysim/core/logit.py @@ -574,7 +574,7 @@ def each_nest(nest_spec: dict | LogitNestSpec, type=None, post_order=False): raise RuntimeError("Unknown nest type '%s' in call to each_nest" % type) if isinstance(nest_spec, dict): - nest_spec = LogitNestSpec.parse_obj(nest_spec) + nest_spec = LogitNestSpec.model_validate(nest_spec) for _node, nest in _each_nest(nest_spec, parent_nest=Nest(), post_order=post_order): if type is None or (type == nest.type): diff --git a/activitysim/core/mp_tasks.py b/activitysim/core/mp_tasks.py index 7d1ffc30e..db92be1da 100644 --- a/activitysim/core/mp_tasks.py +++ b/activitysim/core/mp_tasks.py @@ -887,7 +887,6 @@ def setup_injectables_and_logging(injectables, locutor: bool = True) -> workflow state = workflow.State() state = state.initialize_filesystem(**injectables) state.settings = injectables.get("settings", Settings()) - # state.settings = Settings.parse_obj(injectables.get("settings_package", {})) # register abm steps and other abm-specific injectables # by default, assume we are running activitysim.abm diff --git a/activitysim/core/simulate.py b/activitysim/core/simulate.py index aff2c53e3..133a8b1dc 100644 --- a/activitysim/core/simulate.py +++ b/activitysim/core/simulate.py @@ -467,7 +467,7 @@ def replace_coefficients(nest: LogitNestSpec): coefficients = coefficients["value"].to_dict() if not isinstance(nest_spec, LogitNestSpec): - nest_spec = LogitNestSpec.parse_obj(nest_spec) + nest_spec = LogitNestSpec.model_validate(nest_spec) replace_coefficients(nest_spec) diff --git a/activitysim/core/test/__init__.py b/activitysim/core/test/__init__.py index 9b942d5d2..487f43a34 100644 --- a/activitysim/core/test/__init__.py +++ b/activitysim/core/test/__init__.py @@ -14,4 +14,5 @@ assert_equal, assert_frame_substantively_equal, run_if_exists, + progressive_checkpoint_test, ) diff --git a/activitysim/core/test/_tools.py b/activitysim/core/test/_tools.py index 930f25d40..b8f338ce9 100644 --- a/activitysim/core/test/_tools.py +++ b/activitysim/core/test/_tools.py @@ -139,3 +139,43 @@ def assert_equal(x, y): # pytest.approx() does not support nested data structures for x_, y_ in zip(x, y): assert x_ == pytest.approx(y_) + + +def progressive_checkpoint_test( + state, ref_target: Path, expected_models: list[str], name: str = "unnamed-example" +) -> None: + """ + Compare the results of a pipeline to a reference pipeline. + + Parameters + ---------- + state : workflow.State + ref_target : Path + Location of the reference pipeline file. If this file does not exist, + it will be created (and the test will fail). + expected_models : list[str] + List of model names to run and compare results against the reference + pipeline. + name : str, optional + Name of the test example used in logging, by default "unnamed-example" + """ + + for step_name in expected_models: + state.run.by_name(step_name) + if ref_target.exists(): + try: + state.checkpoint.check_against(ref_target, checkpoint_name=step_name) + except Exception: + print(f"> {name} {step_name}: ERROR") + raise + else: + print(f"> {name} {step_name}: ok") + else: + print(f"> {name} {step_name}: regenerated") + + # generate the reference pipeline if it did not exist + if not ref_target.exists(): + state.checkpoint.store.make_zip_archive(ref_target) + raise RuntimeError( + f"Reference pipeline {ref_target} did not exist, so it was created." + ) diff --git a/activitysim/core/test/test_input.py b/activitysim/core/test/test_input.py index d0cfc24e2..bedf100d7 100644 --- a/activitysim/core/test/test_input.py +++ b/activitysim/core/test/test_input.py @@ -69,7 +69,7 @@ def test_csv_reader(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("households.csv") @@ -94,7 +94,7 @@ def test_hdf_reader1(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("households.h5") @@ -120,7 +120,7 @@ def test_hdf_reader2(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("households.h5") @@ -145,7 +145,7 @@ def test_hdf_reader3(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("input_data.h5") @@ -169,7 +169,7 @@ def test_missing_filename(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings with pytest.raises(AssertionError) as excinfo: @@ -191,7 +191,7 @@ def test_create_input_store(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("households.csv") diff --git a/activitysim/core/test/test_util.py b/activitysim/core/test/test_util.py index ae9b4fa83..415ec1f9e 100644 --- a/activitysim/core/test/test_util.py +++ b/activitysim/core/test/test_util.py @@ -7,7 +7,7 @@ import pandas.testing as pdt import pytest -from ..util import other_than, quick_loc_df, quick_loc_series, reindex +from ..util import other_than, quick_loc_df, quick_loc_series, reindex, df_from_dict @pytest.fixture(scope="module") @@ -62,3 +62,30 @@ def test_quick_loc_series(): assert list(quick_loc_series(loc_list, series)) == attrib_list assert list(quick_loc_series(loc_list, series)) == list(series.loc[loc_list]) + + +def test_df_from_dict(): + + index = [1, 2, 3, 4, 5] + df = pd.DataFrame({"attrib": [1, 2, 2, 3, 1]}, index=index) + + # scramble index order for one expression and not the other + sorted = df.eval("attrib.sort_values()") + not_sorted = df.eval("attrib * 1") + + # check above expressions + pdt.assert_series_equal( + sorted, pd.Series([1, 1, 2, 2, 3], index=[1, 5, 2, 3, 4]), check_names=False + ) + pdt.assert_series_equal(not_sorted, df.attrib, check_names=False) + + # create a new dataframe from the above expressions + values = {"sorted": sorted, "not_sorted": not_sorted} + new_df = df_from_dict(values, index) + + # index should become unscrambed and back to the same order as before + expected_df = pd.DataFrame( + {"sorted": [1, 2, 2, 3, 1], "not_sorted": [1, 2, 2, 3, 1]}, index=index + ) + + pdt.assert_frame_equal(new_df, expected_df) diff --git a/activitysim/core/util.py b/activitysim/core/util.py index ce2439a9b..3130b18f5 100644 --- a/activitysim/core/util.py +++ b/activitysim/core/util.py @@ -6,11 +6,12 @@ import collections import itertools import logging +import numbers import os from collections.abc import Iterable from operator import itemgetter from pathlib import Path -from typing import TypeVar +from typing import Optional, TypeVar import cytoolz as tz import cytoolz.curried @@ -26,7 +27,6 @@ def si_units(x, kind="B", digits=3, shift=1000): - # nano micro milli kilo mega giga tera peta exa zeta yotta tiers = ["n", "µ", "m", "", "K", "M", "G", "T", "P", "E", "Z", "Y"] @@ -314,7 +314,7 @@ def quick_loc_series(loc_list, target_series): return df.right -def assign_in_place(df, df2): +def assign_in_place(df, df2, downcast_int=False, downcast_float=False): """ update existing row values in df from df2, adding columns to df if they are not there @@ -324,6 +324,10 @@ def assign_in_place(df, df2): assignment left-hand-side (dest) df2: pd.DataFrame assignment right-hand-side (source) + downcast_int: bool + if True, downcast int columns if possible + downcast_float: bool + if True, downcast float columns if possible Returns ------- @@ -342,7 +346,6 @@ def assign_in_place(df, df2): # this is a hack fix for a bug in pandas.update # github.com/pydata/pandas/issues/4094 for c, old_dtype in zip(common_columns, old_dtypes): - # if both df and df2 column were same type, but result is not if (old_dtype == df2[c].dtype) and (df[c].dtype != old_dtype): try: @@ -353,6 +356,9 @@ def assign_in_place(df, df2): % (old_dtype, c, df[c].dtype) ) + if isinstance(old_dtype, pd.api.types.CategoricalDtype): + continue + # if both df and df2 column were ints, but result is not if ( np.issubdtype(old_dtype, np.integer) @@ -372,8 +378,92 @@ def assign_in_place(df, df2): df[new_columns] = df2[new_columns] + for c in new_columns: + if pd.api.types.is_object_dtype(df[c]): + df[c] = df[c].astype("category") + + auto_opt_pd_dtypes(df, downcast_int, downcast_float, inplace=True) + + +def auto_opt_pd_dtypes( + df_: pd.DataFrame, downcast_int=False, downcast_float=False, inplace=False +) -> Optional[pd.DataFrame]: + """ + Automatically downcast Number dtypes for minimal possible, + will not touch other (datetime, str, object, etc) + + Parameters + ---------- + df_ : pd.DataFrame + assignment left-hand-side (dest) + downcast_int: bool + if True, downcast int columns if possible + downcast_float: bool + if True, downcast float columns if possible + inplace: bool + if False, will return a copy of input dataset + + Returns + ------- + `None` if `inplace=True` or dataframe if `inplace=False` + + """ + df = df_ if inplace else df_.copy() + + for col in df.columns: + dtype = df[col].dtype + # Skip optimizing floats for precision concerns + if pd.api.types.is_float_dtype(dtype): + if not downcast_float: + continue + else: + # there is a bug in pandas to_numeric + # when convert int and floats gt 16777216 + # https://github.com/pandas-dev/pandas/issues/43693 + # https://github.com/pandas-dev/pandas/issues/23676#issuecomment-438488603 + if df[col].max() >= 16777216: + continue + else: + df[col] = pd.to_numeric(df[col], downcast="float") + # Skip if the column is already categorical + if pd.api.types.is_categorical_dtype(dtype): + continue + # Handle integer types + if pd.api.types.is_integer_dtype(dtype): + if not downcast_int: + continue + # there is a bug in pandas to_numeric + # when convert int and floats gt 16777216 + # https://github.com/pandas-dev/pandas/issues/43693 + # https://github.com/pandas-dev/pandas/issues/23676#issuecomment-438488603 + if df[col].max() >= 16777216: + continue + else: + df[col] = pd.to_numeric(df[col], downcast="integer") + continue + # Initially thought of using unsigned integers, BUT: + # There are calculations in asim (e.g., UECs) that expect results in negative values, + # and operations on two unsigned types will not produce negative values, + # therefore, we did not use unsigned integers. + + if not inplace: + return df + + +def reindex_if_series(values, index): + if index is not None: + return values + + if isinstance(values, pd.Series): + assert len(set(values.index).intersection(index)) == len(index) + + if all(values.index != index): + return values.reindex(index=index) + def df_from_dict(values, index=None): + # If value object is a series and has out of order index, reindex it + values = {k: reindex_if_series(v, index) for k, v in values.items()} df = pd.DataFrame.from_dict(values) if index is not None: @@ -443,7 +533,7 @@ def suffix_tables_in_settings( model_settings = recursive_replace(model_settings, k, suffix + k) if model_settings_type is not None: - model_settings = model_settings_type.parse_obj(model_settings) + model_settings = model_settings_type.model_validate(model_settings) return model_settings diff --git a/activitysim/core/workflow/checkpoint.py b/activitysim/core/workflow/checkpoint.py index b553460a2..b7fe5900a 100644 --- a/activitysim/core/workflow/checkpoint.py +++ b/activitysim/core/workflow/checkpoint.py @@ -958,7 +958,9 @@ def restore_from(self, location: Path, checkpoint_name: str = LAST_CHECKPOINT): self.load(checkpoint_name, store=from_store) logger.debug(f"checkpoint.restore_from of {checkpoint_name} complete") - def check_against(self, location: Path, checkpoint_name: str): + def check_against( + self, location: Path, checkpoint_name: str, strict_categoricals: bool = False + ): """ Check that the tables in this State match those in an archived pipeline. @@ -966,6 +968,11 @@ def check_against(self, location: Path, checkpoint_name: str): ---------- location : Path-like checkpoint_name : str + strict_categoricals : bool, default False + If True, check that categorical columns have the same categories + in both the current state and the checkpoint. Otherwise, the dtypes + of categorical columns are ignored, and only the values themselves are + checked to confirm they match. Raises ------ @@ -1033,9 +1040,27 @@ def check_against(self, location: Path, checkpoint_name: str): local_table[ref_table.columns], ref_table, check_dtype=False ) except Exception as err: - raise AssertionError( - f"checkpoint {checkpoint_name!r} table {table_name!r}, {str(err)}" - ) + if not strict_categoricals: + try: + pd.testing.assert_frame_equal( + local_table[ref_table.columns], + ref_table, + check_dtype=False, + check_categorical=False, + ) + except Exception as err2: + raise AssertionError( + f"checkpoint {checkpoint_name!r} table {table_name!r}, {str(err)}\nfrom: {str(err2)}" + ) + else: + warnings.warn( + f"checkpoint {checkpoint_name!r} table {table_name!r}, " + f"values match but categorical dtype does not" + ) + else: + raise AssertionError( + f"checkpoint {checkpoint_name!r} table {table_name!r}, {str(err)}" + ) else: logger.info(f"table {table_name!r}: ok") diff --git a/activitysim/core/workflow/state.py b/activitysim/core/workflow/state.py index 77c07180f..f21810bb5 100644 --- a/activitysim/core/workflow/state.py +++ b/activitysim/core/workflow/state.py @@ -437,7 +437,7 @@ def initialize_filesystem( if cache_dir is not None: fs["cache_dir"] = cache_dir try: - self.filesystem: FileSystem = FileSystem.parse_obj(fs) + self.filesystem: FileSystem = FileSystem.model_validate(fs) except Exception as err: print(err) raise @@ -485,7 +485,7 @@ def load_settings(self) -> State: logger.warning(f"settings file changes cache_dir to {cache_dir}") self.filesystem.cache_dir = cache_dir settings_class = self.__class__.settings.member_type - self.settings: Settings = settings_class.parse_obj(raw_settings) + self.settings: Settings = settings_class.model_validate(raw_settings) extra_settings = set(self.settings.__dict__) - set(settings_class.__fields__) @@ -1084,6 +1084,25 @@ def extend_table(self, table_name, df, axis=0): df = df[new_df_columns] missing_df_str_columns = [] + # union categoricals + for c in table_df.columns: + if c in df.columns: + if isinstance(table_df[c].dtype, pd.api.types.CategoricalDtype): + if isinstance(df[c].dtype, pd.api.types.CategoricalDtype): + from pandas.api.types import union_categoricals + + uc = union_categoricals([table_df[c], df[c]]) + table_df[c] = pd.Categorical( + table_df[c], categories=uc.categories + ) + df[c] = pd.Categorical(df[c], categories=uc.categories) + else: + # when the existing categorical type has an empty string as a category, + # we will use that as the missing value instead of NaN + if isinstance(table_df[c].dtype, pd.api.types.CategoricalDtype): + if "" in table_df[c].cat.categories: + missing_df_str_columns.append(c) + # preserve existing column order df = pd.concat([table_df, df], sort=False, axis=axis) diff --git a/activitysim/estimation/larch/location_choice.py b/activitysim/estimation/larch/location_choice.py index fd61aea3d..bade2ef35 100644 --- a/activitysim/estimation/larch/location_choice.py +++ b/activitysim/estimation/larch/location_choice.py @@ -3,6 +3,8 @@ import os from pathlib import Path from typing import Collection +import pickle +from datetime import datetime import numpy as np import pandas as pd @@ -46,6 +48,8 @@ def location_choice_model( settings_file="{name}_model_settings.yaml", landuse_file="{name}_landuse.csv", return_data=False, + alt_values_to_feather=False, + chunking_size=None, ): model_selector = name.replace("_location", "") model_selector = model_selector.replace("_destination", "") @@ -59,12 +63,42 @@ def _read_csv(filename, **kwargs): filename = filename.format(name=name) return pd.read_csv(os.path.join(edb_directory, filename), **kwargs) + def _read_feather(filename, **kwargs): + filename = filename.format(name=name) + return pd.read_feather(os.path.join(edb_directory, filename), **kwargs) + + def _to_feather(df, filename, **kwargs): + filename = filename.format(name=name) + return df.to_feather(os.path.join(edb_directory, filename), **kwargs) + + def _read_pickle(filename, **kwargs): + filename = filename.format(name=name) + return pd.read_pickle(os.path.join(edb_directory, filename)) + + def _to_pickle(df, filename, **kwargs): + filename = filename.format(name=name) + return df.to_pickle(os.path.join(edb_directory, filename)) + + def _file_exists(filename): + filename = filename.format(name=name) + return os.path.exists(os.path.join(edb_directory, filename)) + coefficients = _read_csv( coefficients_file, index_col="coefficient_name", ) spec = _read_csv(spec_file, comment="#") - alt_values = _read_csv(alt_values_file) + + # read alternative values either as csv or feather file + alt_values_fea_file = alt_values_file.replace(".csv", ".fea") + if os.path.exists( + os.path.join(edb_directory, alt_values_fea_file.format(name=name)) + ): + alt_values = _read_feather(alt_values_fea_file) + else: + alt_values = _read_csv(alt_values_file) + if alt_values_to_feather: + _to_feather(df=alt_values, filename=alt_values_fea_file) chooser_data = _read_csv(chooser_file) landuse = _read_csv(landuse_file, index_col="zone_id") master_size_spec = _read_csv(size_spec_file) @@ -152,7 +186,48 @@ def _read_csv(filename, **kwargs): chooser_index_name = chooser_data.columns[0] x_co = chooser_data.set_index(chooser_index_name) - x_ca = cv_to_ca(alt_values.set_index([chooser_index_name, alt_values.columns[1]])) + + def split(a, n): + k, m = divmod(len(a), n) + return (a[i * k + min(i, m) : (i + 1) * k + min(i + 1, m)] for i in range(n)) + + # process x_ca with cv_to_ca with or without chunking + x_ca_pickle_file = "{name}_x_ca.pkl" + if chunking_size == None: + x_ca = cv_to_ca( + alt_values.set_index([chooser_index_name, alt_values.columns[1]]) + ) + elif _file_exists(x_ca_pickle_file): + # if pickle file from previous x_ca processing exist, load it to save time + time_start = datetime.now() + x_ca = _read_pickle(x_ca_pickle_file) + print( + f"x_ca data loaded from {name}_x_ca.fea - time elapsed {(datetime.now() - time_start).total_seconds()}" + ) + else: + time_start = datetime.now() + # calculate num_chunks based on chunking_size (or max number of rows per chunk) + num_chunks = int(len(alt_values) / chunking_size) + all_person_ids = list(alt_values["person_id"].unique()) + split_ids = list(split(all_person_ids, num_chunks)) + x_ca_list = [] + i = 0 + for chunk_ids in split_ids: + alt_values_i = alt_values[alt_values["person_id"].isin(chunk_ids)] + x_ca_i = cv_to_ca( + alt_values_i.set_index([chooser_index_name, alt_values_i.columns[1]]) + ) + x_ca_list.append(x_ca_i) + print( + f"\rx_ca_i compute done for chunk {i}/{num_chunks} - time elapsed {(datetime.now() - time_start).total_seconds()}" + ) + i = i + 1 + x_ca = pd.concat(x_ca_list, axis=0) + # save final x_ca result as pickle file to save time for future data loading + _to_pickle(df=x_ca, filename=x_ca_pickle_file) + print( + f"x_ca compute done - time elapsed {(datetime.now() - time_start).total_seconds()}" + ) if CHOOSER_SEGMENT_COLUMN_NAME is not None: # label segments with names diff --git a/activitysim/examples/placeholder_psrc/configs/non_mandatory_tour_frequency_alternatives.csv b/activitysim/examples/placeholder_psrc/configs/non_mandatory_tour_frequency_alternatives.csv index b9765aa75..09e89fae3 100755 --- a/activitysim/examples/placeholder_psrc/configs/non_mandatory_tour_frequency_alternatives.csv +++ b/activitysim/examples/placeholder_psrc/configs/non_mandatory_tour_frequency_alternatives.csv @@ -1,97 +1,97 @@ -escort,shopping,othmaint,othdiscr,eatout,social -0,0,0,0,0,0 -0,0,0,1,0,0 -0,0,0,0,0,1 -0,0,0,1,0,1 -0,0,0,0,1,0 -0,0,0,1,1,0 -0,0,0,0,1,1 -0,0,0,1,1,1 -0,0,1,0,0,0 -0,0,1,1,0,0 -0,0,1,0,0,1 -0,0,1,1,0,1 -0,0,1,0,1,0 -0,0,1,1,1,0 -0,0,1,0,1,1 -0,0,1,1,1,1 -0,1,0,0,0,0 -0,1,0,1,0,0 -0,1,0,0,0,1 -0,1,0,1,0,1 -0,1,0,0,1,0 -0,1,0,1,1,0 -0,1,0,0,1,1 -0,1,0,1,1,1 -0,1,1,0,0,0 -0,1,1,1,0,0 -0,1,1,0,0,1 -0,1,1,1,0,1 -0,1,1,0,1,0 -0,1,1,1,1,0 -0,1,1,0,1,1 -0,1,1,1,1,1 -1,0,0,0,0,0 -1,0,0,1,0,0 -1,0,0,0,0,1 -1,0,0,1,0,1 -1,0,0,0,1,0 -1,0,0,1,1,0 -1,0,0,0,1,1 -1,0,0,1,1,1 -1,0,1,0,0,0 -1,0,1,1,0,0 -1,0,1,0,0,1 -1,0,1,1,0,1 -1,0,1,0,1,0 -1,0,1,1,1,0 -1,0,1,0,1,1 -1,0,1,1,1,1 -1,1,0,0,0,0 -1,1,0,1,0,0 -1,1,0,0,0,1 -1,1,0,1,0,1 -1,1,0,0,1,0 -1,1,0,1,1,0 -1,1,0,0,1,1 -1,1,0,1,1,1 -1,1,1,0,0,0 -1,1,1,1,0,0 -1,1,1,0,0,1 -1,1,1,1,0,1 -1,1,1,0,1,0 -1,1,1,1,1,0 -1,1,1,0,1,1 -1,1,1,1,1,1 -2,0,0,0,0,0 -2,0,0,1,0,0 -2,0,0,0,0,1 -2,0,0,1,0,1 -2,0,0,0,1,0 -2,0,0,1,1,0 -2,0,0,0,1,1 -2,0,0,1,1,1 -2,0,1,0,0,0 -2,0,1,1,0,0 -2,0,1,0,0,1 -2,0,1,1,0,1 -2,0,1,0,1,0 -2,0,1,1,1,0 -2,0,1,0,1,1 -2,0,1,1,1,1 -2,1,0,0,0,0 -2,1,0,1,0,0 -2,1,0,0,0,1 -2,1,0,1,0,1 -2,1,0,0,1,0 -2,1,0,1,1,0 -2,1,0,0,1,1 -2,1,0,1,1,1 -2,1,1,0,0,0 -2,1,1,1,0,0 -2,1,1,0,0,1 -2,1,1,1,0,1 -2,1,1,0,1,0 -2,1,1,1,1,0 -2,1,1,0,1,1 -2,1,1,1,1,1 +escort,shopping,othmaint,othdiscr,eatout,social,tot_tours +0,0,0,0,0,0,0 +0,0,0,1,0,0,1 +0,0,0,0,0,1,1 +0,0,0,1,0,1,2 +0,0,0,0,1,0,1 +0,0,0,1,1,0,2 +0,0,0,0,1,1,2 +0,0,0,1,1,1,3 +0,0,1,0,0,0,1 +0,0,1,1,0,0,2 +0,0,1,0,0,1,2 +0,0,1,1,0,1,3 +0,0,1,0,1,0,2 +0,0,1,1,1,0,3 +0,0,1,0,1,1,3 +0,0,1,1,1,1,4 +0,1,0,0,0,0,1 +0,1,0,1,0,0,2 +0,1,0,0,0,1,2 +0,1,0,1,0,1,3 +0,1,0,0,1,0,2 +0,1,0,1,1,0,3 +0,1,0,0,1,1,3 +0,1,0,1,1,1,4 +0,1,1,0,0,0,2 +0,1,1,1,0,0,3 +0,1,1,0,0,1,3 +0,1,1,1,0,1,4 +0,1,1,0,1,0,3 +0,1,1,1,1,0,4 +0,1,1,0,1,1,4 +0,1,1,1,1,1,5 +1,0,0,0,0,0,1 +1,0,0,1,0,0,2 +1,0,0,0,0,1,2 +1,0,0,1,0,1,3 +1,0,0,0,1,0,2 +1,0,0,1,1,0,3 +1,0,0,0,1,1,3 +1,0,0,1,1,1,4 +1,0,1,0,0,0,2 +1,0,1,1,0,0,3 +1,0,1,0,0,1,3 +1,0,1,1,0,1,4 +1,0,1,0,1,0,3 +1,0,1,1,1,0,4 +1,0,1,0,1,1,4 +1,0,1,1,1,1,5 +1,1,0,0,0,0,2 +1,1,0,1,0,0,3 +1,1,0,0,0,1,3 +1,1,0,1,0,1,4 +1,1,0,0,1,0,3 +1,1,0,1,1,0,4 +1,1,0,0,1,1,4 +1,1,0,1,1,1,5 +1,1,1,0,0,0,3 +1,1,1,1,0,0,4 +1,1,1,0,0,1,4 +1,1,1,1,0,1,5 +1,1,1,0,1,0,4 +1,1,1,1,1,0,5 +1,1,1,0,1,1,5 +1,1,1,1,1,1,6 +2,0,0,0,0,0,2 +2,0,0,1,0,0,3 +2,0,0,0,0,1,3 +2,0,0,1,0,1,4 +2,0,0,0,1,0,3 +2,0,0,1,1,0,4 +2,0,0,0,1,1,4 +2,0,0,1,1,1,5 +2,0,1,0,0,0,3 +2,0,1,1,0,0,4 +2,0,1,0,0,1,4 +2,0,1,1,0,1,5 +2,0,1,0,1,0,4 +2,0,1,1,1,0,5 +2,0,1,0,1,1,5 +2,0,1,1,1,1,6 +2,1,0,0,0,0,3 +2,1,0,1,0,0,4 +2,1,0,0,0,1,4 +2,1,0,1,0,1,5 +2,1,0,0,1,0,4 +2,1,0,1,1,0,5 +2,1,0,0,1,1,5 +2,1,0,1,1,1,6 +2,1,1,0,0,0,4 +2,1,1,1,0,0,5 +2,1,1,0,0,1,5 +2,1,1,1,0,1,6 +2,1,1,0,1,0,5 +2,1,1,1,1,0,6 +2,1,1,0,1,1,6 +2,1,1,1,1,1,7 diff --git a/activitysim/examples/placeholder_psrc/configs/stop_frequency_annotate_tours_preprocessor.csv b/activitysim/examples/placeholder_psrc/configs/stop_frequency_annotate_tours_preprocessor.csv index d7b2f1d61..faa80422a 100755 --- a/activitysim/examples/placeholder_psrc/configs/stop_frequency_annotate_tours_preprocessor.csv +++ b/activitysim/examples/placeholder_psrc/configs/stop_frequency_annotate_tours_preprocessor.csv @@ -45,3 +45,6 @@ AccesibilityADestination off-peak transit,_dest_trOpRetail,"reindex(accessibilit AccesibilityAtDestination if transit,pracc,"pracc.where(~tour_mode_is_transit, _dest_trPkRetail.where(_tour_starts_in_peak, _dest_trOpRetail))" AccesibilityAtDestination if non_motorized,pracc,"pracc.where(~tour_mode_is_non_motorized, reindex(accessibility.nmRetail, df.destination))" ,destination_area_type,"reindex(land_use.area_type, df.destination)" +,is_mixed,df.composition=='mixed' +,is_adults_tour,df.composition=='adults' +,is_social,primary_purpose=='social' diff --git a/activitysim/examples/placeholder_psrc/configs/stop_frequency_eatout.csv b/activitysim/examples/placeholder_psrc/configs/stop_frequency_eatout.csv index bd0174ceb..75480c187 100644 --- a/activitysim/examples/placeholder_psrc/configs/stop_frequency_eatout.csv +++ b/activitysim/examples/placeholder_psrc/configs/stop_frequency_eatout.csv @@ -27,7 +27,7 @@ util_number_of_visit_tours_tours_undertaken_by_the_person,Number of visit tours util_number_of_shop_tours_undertaken_by_the_houshold,Number of shop tours undertaken by the houshold,num_hh_shop_tours,,,,,,,,,,,,,,,, util_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,Number of persons participating in the tour.Outgoing stops interaction,is_joint * number_of_participants,,,,,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction util_number_of_persons_participating_in_the_tour_return_stops_interaction,Number of persons participating in the tour.Return stops interaction,is_joint * number_of_participants,,,,,,,,,,,,,,,, -util_at_least_one_kid_and_one_adult_participate_in_the_tour,At least one kid and one adult participate in the tour,composition=='mixed',,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour +util_at_least_one_kid_and_one_adult_participate_in_the_tour,At least one kid and one adult participate in the tour,is_mixed,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour util_am_peak_departure_between_6am_and_7_am_including_interacted_with_outbound_tours,AM Peak departure between 6AM and 7 AM (including) Interacted with outbound tours,(start>5) & (start<8),,,,,,,,,,,,,,,, util_arrival_later_than_17_00_,Arrival later than 17:00.,(end > 16),,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_ util_evening_arrival_19_00_interacted_with_return_tours,Evening Arrival (>=19:00) Interacted with return tours,(end > 18),,,,,,,,,,,,,,,, @@ -47,6 +47,6 @@ util_alternative_specific_constant_for_the_total_number_of_stops,Alternative spe util_alternative_specific_constant_for_outbound_stops_on_joint_tours,Alternative specific constant for outbound stops on joint tours,is_joint,,,,,-1.783,-1.783,-1.783,-1.783,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in util_alternative_specific_constant_for_return_stops_on_joint_tours,Alternative specific constant for return stops on joint tours,is_joint,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,-3.379,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,-3.379,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,-3.379,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,-3.379 util_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours,Alternative specific constant for the total number of stops on joint tours,is_joint,,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,1.497,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,1.497,1.497 -util_dummy_for_an_outbound_visiting_tour,Dummy for an outbound visiting tour,primary_purpose == 'social',,,,,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour -util_dummy_for_a_return_visiting_tour,Dummy for a return visiting tour,primary_purpose == 'social',,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour -util_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,Dummy for a visiting tour with both outbound and return leg,primary_purpose == 'social',,,,,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg +util_dummy_for_an_outbound_visiting_tour,Dummy for an outbound visiting tour,is_social,,,,,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour +util_dummy_for_a_return_visiting_tour,Dummy for a return visiting tour,is_social,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour +util_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,Dummy for a visiting tour with both outbound and return leg,is_social,,,,,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg diff --git a/activitysim/examples/placeholder_psrc/configs/stop_frequency_shopping.csv b/activitysim/examples/placeholder_psrc/configs/stop_frequency_shopping.csv index bf7d02ede..80b8e285a 100644 --- a/activitysim/examples/placeholder_psrc/configs/stop_frequency_shopping.csv +++ b/activitysim/examples/placeholder_psrc/configs/stop_frequency_shopping.csv @@ -27,7 +27,7 @@ util_number_of_visit_tours_tours_undertaken_by_the_person,Number of visit tours util_number_of_shop_tours_undertaken_by_the_houshold,Number of shop tours undertaken by the houshold,num_hh_shop_tours,,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold util_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,Number of persons participating in the tour.Outgoing stops interaction,is_joint * number_of_participants,,,,,,,,,,,,,,,, util_number_of_persons_participating_in_the_tour_return_stops_interaction,Number of persons participating in the tour.Return stops interaction,is_joint * number_of_participants,,,,,,,,,,,,,,,, -util_dummy_for_only_adults_participate_in_the_tour,Dummy for only adults participate in the tour,composition=='adults',,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour +util_dummy_for_only_adults_participate_in_the_tour,Dummy for only adults participate in the tour,is_adults_tour,,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour util_am_peak_departure_between_6am_and_7_am_including_interacted_with_outbound_tours,AM Peak departure between 6AM and 7 AM (including) Interacted with outbound tours,(start>5) & (start<8),,,,,,,,,,,,,,,, util_arrival_later_than_17_00_,Arrival later than 17:00.,(end > 16),,,,,,,,,,,,,,,, util_evening_arrival_19_00_interacted_with_return_tours,Evening Arrival (>=19:00) Interacted with return tours,(end > 18),,,,,,,,,,,,,,,, diff --git a/activitysim/examples/placeholder_psrc/configs/stop_frequency_social.csv b/activitysim/examples/placeholder_psrc/configs/stop_frequency_social.csv index f331514b0..0d64a60c6 100644 --- a/activitysim/examples/placeholder_psrc/configs/stop_frequency_social.csv +++ b/activitysim/examples/placeholder_psrc/configs/stop_frequency_social.csv @@ -27,7 +27,7 @@ util_number_of_visit_tours_tours_undertaken_by_the_person,Number of visit tours util_number_of_shop_tours_undertaken_by_the_houshold,Number of shop tours undertaken by the houshold,num_hh_shop_tours,,,,,,,,,,,,,,,, util_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,Number of persons participating in the tour.Outgoing stops interaction,is_joint * number_of_participants,,,,,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction util_number_of_persons_participating_in_the_tour_return_stops_interaction,Number of persons participating in the tour.Return stops interaction,is_joint * number_of_participants,,,,,,,,,,,,,,,, -util_at_least_one_kid_and_one_adult_participate_in_the_tour,At least one kid and one adult participate in the tour,composition=='mixed',,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour +util_at_least_one_kid_and_one_adult_participate_in_the_tour,At least one kid and one adult participate in the tour,is_mixed,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour util_am_peak_departure_between_6am_and_7_am_including_interacted_with_outbound_tours,AM Peak departure between 6AM and 7 AM (including) Interacted with outbound tours,(start>5) & (start<8),,,,,,,,,,,,,,,, util_arrival_later_than_17_00_,Arrival later than 17:00.,(end > 16),,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_ util_evening_arrival_19_00_interacted_with_return_tours,Evening Arrival (>=19:00) Interacted with return tours,(end > 18),,,,,,,,,,,,,,,, @@ -47,6 +47,6 @@ util_alternative_specific_constant_for_the_total_number_of_stops,Alternative spe util_alternative_specific_constant_for_outbound_stops_on_joint_tours,Alternative specific constant for outbound stops on joint tours,is_joint,,,,,-1.783,-1.783,-1.783,-1.783,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in util_alternative_specific_constant_for_return_stops_on_joint_tours,Alternative specific constant for return stops on joint tours,is_joint,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,-3.379,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,-3.379,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,-3.379,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,-3.379 util_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours,Alternative specific constant for the total number of stops on joint tours,is_joint,,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,1.497,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,1.497,1.497 -util_dummy_for_an_outbound_visiting_tour,Dummy for an outbound visiting tour,primary_purpose == 'social',,,,,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour -util_dummy_for_a_return_visiting_tour,Dummy for a return visiting tour,primary_purpose == 'social',,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour -util_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,Dummy for a visiting tour with both outbound and return leg,primary_purpose == 'social',,,,,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg +util_dummy_for_an_outbound_visiting_tour,Dummy for an outbound visiting tour,is_social,,,,,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour +util_dummy_for_a_return_visiting_tour,Dummy for a return visiting tour,is_social,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour +util_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,Dummy for a visiting tour with both outbound and return leg,is_social,,,,,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg diff --git a/activitysim/examples/production_semcog/configs/non_mandatory_tour_frequency_alternatives.csv b/activitysim/examples/production_semcog/configs/non_mandatory_tour_frequency_alternatives.csv index b9765aa75..09e89fae3 100644 --- a/activitysim/examples/production_semcog/configs/non_mandatory_tour_frequency_alternatives.csv +++ b/activitysim/examples/production_semcog/configs/non_mandatory_tour_frequency_alternatives.csv @@ -1,97 +1,97 @@ -escort,shopping,othmaint,othdiscr,eatout,social -0,0,0,0,0,0 -0,0,0,1,0,0 -0,0,0,0,0,1 -0,0,0,1,0,1 -0,0,0,0,1,0 -0,0,0,1,1,0 -0,0,0,0,1,1 -0,0,0,1,1,1 -0,0,1,0,0,0 -0,0,1,1,0,0 -0,0,1,0,0,1 -0,0,1,1,0,1 -0,0,1,0,1,0 -0,0,1,1,1,0 -0,0,1,0,1,1 -0,0,1,1,1,1 -0,1,0,0,0,0 -0,1,0,1,0,0 -0,1,0,0,0,1 -0,1,0,1,0,1 -0,1,0,0,1,0 -0,1,0,1,1,0 -0,1,0,0,1,1 -0,1,0,1,1,1 -0,1,1,0,0,0 -0,1,1,1,0,0 -0,1,1,0,0,1 -0,1,1,1,0,1 -0,1,1,0,1,0 -0,1,1,1,1,0 -0,1,1,0,1,1 -0,1,1,1,1,1 -1,0,0,0,0,0 -1,0,0,1,0,0 -1,0,0,0,0,1 -1,0,0,1,0,1 -1,0,0,0,1,0 -1,0,0,1,1,0 -1,0,0,0,1,1 -1,0,0,1,1,1 -1,0,1,0,0,0 -1,0,1,1,0,0 -1,0,1,0,0,1 -1,0,1,1,0,1 -1,0,1,0,1,0 -1,0,1,1,1,0 -1,0,1,0,1,1 -1,0,1,1,1,1 -1,1,0,0,0,0 -1,1,0,1,0,0 -1,1,0,0,0,1 -1,1,0,1,0,1 -1,1,0,0,1,0 -1,1,0,1,1,0 -1,1,0,0,1,1 -1,1,0,1,1,1 -1,1,1,0,0,0 -1,1,1,1,0,0 -1,1,1,0,0,1 -1,1,1,1,0,1 -1,1,1,0,1,0 -1,1,1,1,1,0 -1,1,1,0,1,1 -1,1,1,1,1,1 -2,0,0,0,0,0 -2,0,0,1,0,0 -2,0,0,0,0,1 -2,0,0,1,0,1 -2,0,0,0,1,0 -2,0,0,1,1,0 -2,0,0,0,1,1 -2,0,0,1,1,1 -2,0,1,0,0,0 -2,0,1,1,0,0 -2,0,1,0,0,1 -2,0,1,1,0,1 -2,0,1,0,1,0 -2,0,1,1,1,0 -2,0,1,0,1,1 -2,0,1,1,1,1 -2,1,0,0,0,0 -2,1,0,1,0,0 -2,1,0,0,0,1 -2,1,0,1,0,1 -2,1,0,0,1,0 -2,1,0,1,1,0 -2,1,0,0,1,1 -2,1,0,1,1,1 -2,1,1,0,0,0 -2,1,1,1,0,0 -2,1,1,0,0,1 -2,1,1,1,0,1 -2,1,1,0,1,0 -2,1,1,1,1,0 -2,1,1,0,1,1 -2,1,1,1,1,1 +escort,shopping,othmaint,othdiscr,eatout,social,tot_tours +0,0,0,0,0,0,0 +0,0,0,1,0,0,1 +0,0,0,0,0,1,1 +0,0,0,1,0,1,2 +0,0,0,0,1,0,1 +0,0,0,1,1,0,2 +0,0,0,0,1,1,2 +0,0,0,1,1,1,3 +0,0,1,0,0,0,1 +0,0,1,1,0,0,2 +0,0,1,0,0,1,2 +0,0,1,1,0,1,3 +0,0,1,0,1,0,2 +0,0,1,1,1,0,3 +0,0,1,0,1,1,3 +0,0,1,1,1,1,4 +0,1,0,0,0,0,1 +0,1,0,1,0,0,2 +0,1,0,0,0,1,2 +0,1,0,1,0,1,3 +0,1,0,0,1,0,2 +0,1,0,1,1,0,3 +0,1,0,0,1,1,3 +0,1,0,1,1,1,4 +0,1,1,0,0,0,2 +0,1,1,1,0,0,3 +0,1,1,0,0,1,3 +0,1,1,1,0,1,4 +0,1,1,0,1,0,3 +0,1,1,1,1,0,4 +0,1,1,0,1,1,4 +0,1,1,1,1,1,5 +1,0,0,0,0,0,1 +1,0,0,1,0,0,2 +1,0,0,0,0,1,2 +1,0,0,1,0,1,3 +1,0,0,0,1,0,2 +1,0,0,1,1,0,3 +1,0,0,0,1,1,3 +1,0,0,1,1,1,4 +1,0,1,0,0,0,2 +1,0,1,1,0,0,3 +1,0,1,0,0,1,3 +1,0,1,1,0,1,4 +1,0,1,0,1,0,3 +1,0,1,1,1,0,4 +1,0,1,0,1,1,4 +1,0,1,1,1,1,5 +1,1,0,0,0,0,2 +1,1,0,1,0,0,3 +1,1,0,0,0,1,3 +1,1,0,1,0,1,4 +1,1,0,0,1,0,3 +1,1,0,1,1,0,4 +1,1,0,0,1,1,4 +1,1,0,1,1,1,5 +1,1,1,0,0,0,3 +1,1,1,1,0,0,4 +1,1,1,0,0,1,4 +1,1,1,1,0,1,5 +1,1,1,0,1,0,4 +1,1,1,1,1,0,5 +1,1,1,0,1,1,5 +1,1,1,1,1,1,6 +2,0,0,0,0,0,2 +2,0,0,1,0,0,3 +2,0,0,0,0,1,3 +2,0,0,1,0,1,4 +2,0,0,0,1,0,3 +2,0,0,1,1,0,4 +2,0,0,0,1,1,4 +2,0,0,1,1,1,5 +2,0,1,0,0,0,3 +2,0,1,1,0,0,4 +2,0,1,0,0,1,4 +2,0,1,1,0,1,5 +2,0,1,0,1,0,4 +2,0,1,1,1,0,5 +2,0,1,0,1,1,5 +2,0,1,1,1,1,6 +2,1,0,0,0,0,3 +2,1,0,1,0,0,4 +2,1,0,0,0,1,4 +2,1,0,1,0,1,5 +2,1,0,0,1,0,4 +2,1,0,1,1,0,5 +2,1,0,0,1,1,5 +2,1,0,1,1,1,6 +2,1,1,0,0,0,4 +2,1,1,1,0,0,5 +2,1,1,0,0,1,5 +2,1,1,1,0,1,6 +2,1,1,0,1,0,5 +2,1,1,1,1,0,6 +2,1,1,0,1,1,6 +2,1,1,1,1,1,7 diff --git a/activitysim/examples/production_semcog/extensions/stop_frequency_university_parking.py b/activitysim/examples/production_semcog/extensions/stop_frequency_university_parking.py index 7264fed35..10573ba98 100644 --- a/activitysim/examples/production_semcog/extensions/stop_frequency_university_parking.py +++ b/activitysim/examples/production_semcog/extensions/stop_frequency_university_parking.py @@ -124,6 +124,11 @@ def stop_frequency_university_parking( park_trips = park_to_campus | park_from_campus + # check if parking_name is in the purpose category + if not parking_name in trip_choosers.purpose.cat.categories: + trip_choosers.purpose = trip_choosers.purpose.cat.add_categories( + [parking_name] + ) trip_choosers.loc[park_trips, "purpose"] = parking_name trip_choosers.loc[park_trips, "destination_logsum"] = pd.NA trip_choosers.loc[park_trips, "destination"] = trip_choosers.loc[ diff --git a/activitysim/examples/prototype_arc/configs/non_mandatory_tour_frequency_alternatives.csv b/activitysim/examples/prototype_arc/configs/non_mandatory_tour_frequency_alternatives.csv index b9765aa75..09e89fae3 100644 --- a/activitysim/examples/prototype_arc/configs/non_mandatory_tour_frequency_alternatives.csv +++ b/activitysim/examples/prototype_arc/configs/non_mandatory_tour_frequency_alternatives.csv @@ -1,97 +1,97 @@ -escort,shopping,othmaint,othdiscr,eatout,social -0,0,0,0,0,0 -0,0,0,1,0,0 -0,0,0,0,0,1 -0,0,0,1,0,1 -0,0,0,0,1,0 -0,0,0,1,1,0 -0,0,0,0,1,1 -0,0,0,1,1,1 -0,0,1,0,0,0 -0,0,1,1,0,0 -0,0,1,0,0,1 -0,0,1,1,0,1 -0,0,1,0,1,0 -0,0,1,1,1,0 -0,0,1,0,1,1 -0,0,1,1,1,1 -0,1,0,0,0,0 -0,1,0,1,0,0 -0,1,0,0,0,1 -0,1,0,1,0,1 -0,1,0,0,1,0 -0,1,0,1,1,0 -0,1,0,0,1,1 -0,1,0,1,1,1 -0,1,1,0,0,0 -0,1,1,1,0,0 -0,1,1,0,0,1 -0,1,1,1,0,1 -0,1,1,0,1,0 -0,1,1,1,1,0 -0,1,1,0,1,1 -0,1,1,1,1,1 -1,0,0,0,0,0 -1,0,0,1,0,0 -1,0,0,0,0,1 -1,0,0,1,0,1 -1,0,0,0,1,0 -1,0,0,1,1,0 -1,0,0,0,1,1 -1,0,0,1,1,1 -1,0,1,0,0,0 -1,0,1,1,0,0 -1,0,1,0,0,1 -1,0,1,1,0,1 -1,0,1,0,1,0 -1,0,1,1,1,0 -1,0,1,0,1,1 -1,0,1,1,1,1 -1,1,0,0,0,0 -1,1,0,1,0,0 -1,1,0,0,0,1 -1,1,0,1,0,1 -1,1,0,0,1,0 -1,1,0,1,1,0 -1,1,0,0,1,1 -1,1,0,1,1,1 -1,1,1,0,0,0 -1,1,1,1,0,0 -1,1,1,0,0,1 -1,1,1,1,0,1 -1,1,1,0,1,0 -1,1,1,1,1,0 -1,1,1,0,1,1 -1,1,1,1,1,1 -2,0,0,0,0,0 -2,0,0,1,0,0 -2,0,0,0,0,1 -2,0,0,1,0,1 -2,0,0,0,1,0 -2,0,0,1,1,0 -2,0,0,0,1,1 -2,0,0,1,1,1 -2,0,1,0,0,0 -2,0,1,1,0,0 -2,0,1,0,0,1 -2,0,1,1,0,1 -2,0,1,0,1,0 -2,0,1,1,1,0 -2,0,1,0,1,1 -2,0,1,1,1,1 -2,1,0,0,0,0 -2,1,0,1,0,0 -2,1,0,0,0,1 -2,1,0,1,0,1 -2,1,0,0,1,0 -2,1,0,1,1,0 -2,1,0,0,1,1 -2,1,0,1,1,1 -2,1,1,0,0,0 -2,1,1,1,0,0 -2,1,1,0,0,1 -2,1,1,1,0,1 -2,1,1,0,1,0 -2,1,1,1,1,0 -2,1,1,0,1,1 -2,1,1,1,1,1 +escort,shopping,othmaint,othdiscr,eatout,social,tot_tours +0,0,0,0,0,0,0 +0,0,0,1,0,0,1 +0,0,0,0,0,1,1 +0,0,0,1,0,1,2 +0,0,0,0,1,0,1 +0,0,0,1,1,0,2 +0,0,0,0,1,1,2 +0,0,0,1,1,1,3 +0,0,1,0,0,0,1 +0,0,1,1,0,0,2 +0,0,1,0,0,1,2 +0,0,1,1,0,1,3 +0,0,1,0,1,0,2 +0,0,1,1,1,0,3 +0,0,1,0,1,1,3 +0,0,1,1,1,1,4 +0,1,0,0,0,0,1 +0,1,0,1,0,0,2 +0,1,0,0,0,1,2 +0,1,0,1,0,1,3 +0,1,0,0,1,0,2 +0,1,0,1,1,0,3 +0,1,0,0,1,1,3 +0,1,0,1,1,1,4 +0,1,1,0,0,0,2 +0,1,1,1,0,0,3 +0,1,1,0,0,1,3 +0,1,1,1,0,1,4 +0,1,1,0,1,0,3 +0,1,1,1,1,0,4 +0,1,1,0,1,1,4 +0,1,1,1,1,1,5 +1,0,0,0,0,0,1 +1,0,0,1,0,0,2 +1,0,0,0,0,1,2 +1,0,0,1,0,1,3 +1,0,0,0,1,0,2 +1,0,0,1,1,0,3 +1,0,0,0,1,1,3 +1,0,0,1,1,1,4 +1,0,1,0,0,0,2 +1,0,1,1,0,0,3 +1,0,1,0,0,1,3 +1,0,1,1,0,1,4 +1,0,1,0,1,0,3 +1,0,1,1,1,0,4 +1,0,1,0,1,1,4 +1,0,1,1,1,1,5 +1,1,0,0,0,0,2 +1,1,0,1,0,0,3 +1,1,0,0,0,1,3 +1,1,0,1,0,1,4 +1,1,0,0,1,0,3 +1,1,0,1,1,0,4 +1,1,0,0,1,1,4 +1,1,0,1,1,1,5 +1,1,1,0,0,0,3 +1,1,1,1,0,0,4 +1,1,1,0,0,1,4 +1,1,1,1,0,1,5 +1,1,1,0,1,0,4 +1,1,1,1,1,0,5 +1,1,1,0,1,1,5 +1,1,1,1,1,1,6 +2,0,0,0,0,0,2 +2,0,0,1,0,0,3 +2,0,0,0,0,1,3 +2,0,0,1,0,1,4 +2,0,0,0,1,0,3 +2,0,0,1,1,0,4 +2,0,0,0,1,1,4 +2,0,0,1,1,1,5 +2,0,1,0,0,0,3 +2,0,1,1,0,0,4 +2,0,1,0,0,1,4 +2,0,1,1,0,1,5 +2,0,1,0,1,0,4 +2,0,1,1,1,0,5 +2,0,1,0,1,1,5 +2,0,1,1,1,1,6 +2,1,0,0,0,0,3 +2,1,0,1,0,0,4 +2,1,0,0,0,1,4 +2,1,0,1,0,1,5 +2,1,0,0,1,0,4 +2,1,0,1,1,0,5 +2,1,0,0,1,1,5 +2,1,0,1,1,1,6 +2,1,1,0,0,0,4 +2,1,1,1,0,0,5 +2,1,1,0,0,1,5 +2,1,1,1,0,1,6 +2,1,1,0,1,0,5 +2,1,1,1,1,0,6 +2,1,1,0,1,1,6 +2,1,1,1,1,1,7 diff --git a/activitysim/examples/prototype_mtc/configs/non_mandatory_tour_frequency_alternatives.csv b/activitysim/examples/prototype_mtc/configs/non_mandatory_tour_frequency_alternatives.csv index b9765aa75..09e89fae3 100644 --- a/activitysim/examples/prototype_mtc/configs/non_mandatory_tour_frequency_alternatives.csv +++ b/activitysim/examples/prototype_mtc/configs/non_mandatory_tour_frequency_alternatives.csv @@ -1,97 +1,97 @@ -escort,shopping,othmaint,othdiscr,eatout,social -0,0,0,0,0,0 -0,0,0,1,0,0 -0,0,0,0,0,1 -0,0,0,1,0,1 -0,0,0,0,1,0 -0,0,0,1,1,0 -0,0,0,0,1,1 -0,0,0,1,1,1 -0,0,1,0,0,0 -0,0,1,1,0,0 -0,0,1,0,0,1 -0,0,1,1,0,1 -0,0,1,0,1,0 -0,0,1,1,1,0 -0,0,1,0,1,1 -0,0,1,1,1,1 -0,1,0,0,0,0 -0,1,0,1,0,0 -0,1,0,0,0,1 -0,1,0,1,0,1 -0,1,0,0,1,0 -0,1,0,1,1,0 -0,1,0,0,1,1 -0,1,0,1,1,1 -0,1,1,0,0,0 -0,1,1,1,0,0 -0,1,1,0,0,1 -0,1,1,1,0,1 -0,1,1,0,1,0 -0,1,1,1,1,0 -0,1,1,0,1,1 -0,1,1,1,1,1 -1,0,0,0,0,0 -1,0,0,1,0,0 -1,0,0,0,0,1 -1,0,0,1,0,1 -1,0,0,0,1,0 -1,0,0,1,1,0 -1,0,0,0,1,1 -1,0,0,1,1,1 -1,0,1,0,0,0 -1,0,1,1,0,0 -1,0,1,0,0,1 -1,0,1,1,0,1 -1,0,1,0,1,0 -1,0,1,1,1,0 -1,0,1,0,1,1 -1,0,1,1,1,1 -1,1,0,0,0,0 -1,1,0,1,0,0 -1,1,0,0,0,1 -1,1,0,1,0,1 -1,1,0,0,1,0 -1,1,0,1,1,0 -1,1,0,0,1,1 -1,1,0,1,1,1 -1,1,1,0,0,0 -1,1,1,1,0,0 -1,1,1,0,0,1 -1,1,1,1,0,1 -1,1,1,0,1,0 -1,1,1,1,1,0 -1,1,1,0,1,1 -1,1,1,1,1,1 -2,0,0,0,0,0 -2,0,0,1,0,0 -2,0,0,0,0,1 -2,0,0,1,0,1 -2,0,0,0,1,0 -2,0,0,1,1,0 -2,0,0,0,1,1 -2,0,0,1,1,1 -2,0,1,0,0,0 -2,0,1,1,0,0 -2,0,1,0,0,1 -2,0,1,1,0,1 -2,0,1,0,1,0 -2,0,1,1,1,0 -2,0,1,0,1,1 -2,0,1,1,1,1 -2,1,0,0,0,0 -2,1,0,1,0,0 -2,1,0,0,0,1 -2,1,0,1,0,1 -2,1,0,0,1,0 -2,1,0,1,1,0 -2,1,0,0,1,1 -2,1,0,1,1,1 -2,1,1,0,0,0 -2,1,1,1,0,0 -2,1,1,0,0,1 -2,1,1,1,0,1 -2,1,1,0,1,0 -2,1,1,1,1,0 -2,1,1,0,1,1 -2,1,1,1,1,1 +escort,shopping,othmaint,othdiscr,eatout,social,tot_tours +0,0,0,0,0,0,0 +0,0,0,1,0,0,1 +0,0,0,0,0,1,1 +0,0,0,1,0,1,2 +0,0,0,0,1,0,1 +0,0,0,1,1,0,2 +0,0,0,0,1,1,2 +0,0,0,1,1,1,3 +0,0,1,0,0,0,1 +0,0,1,1,0,0,2 +0,0,1,0,0,1,2 +0,0,1,1,0,1,3 +0,0,1,0,1,0,2 +0,0,1,1,1,0,3 +0,0,1,0,1,1,3 +0,0,1,1,1,1,4 +0,1,0,0,0,0,1 +0,1,0,1,0,0,2 +0,1,0,0,0,1,2 +0,1,0,1,0,1,3 +0,1,0,0,1,0,2 +0,1,0,1,1,0,3 +0,1,0,0,1,1,3 +0,1,0,1,1,1,4 +0,1,1,0,0,0,2 +0,1,1,1,0,0,3 +0,1,1,0,0,1,3 +0,1,1,1,0,1,4 +0,1,1,0,1,0,3 +0,1,1,1,1,0,4 +0,1,1,0,1,1,4 +0,1,1,1,1,1,5 +1,0,0,0,0,0,1 +1,0,0,1,0,0,2 +1,0,0,0,0,1,2 +1,0,0,1,0,1,3 +1,0,0,0,1,0,2 +1,0,0,1,1,0,3 +1,0,0,0,1,1,3 +1,0,0,1,1,1,4 +1,0,1,0,0,0,2 +1,0,1,1,0,0,3 +1,0,1,0,0,1,3 +1,0,1,1,0,1,4 +1,0,1,0,1,0,3 +1,0,1,1,1,0,4 +1,0,1,0,1,1,4 +1,0,1,1,1,1,5 +1,1,0,0,0,0,2 +1,1,0,1,0,0,3 +1,1,0,0,0,1,3 +1,1,0,1,0,1,4 +1,1,0,0,1,0,3 +1,1,0,1,1,0,4 +1,1,0,0,1,1,4 +1,1,0,1,1,1,5 +1,1,1,0,0,0,3 +1,1,1,1,0,0,4 +1,1,1,0,0,1,4 +1,1,1,1,0,1,5 +1,1,1,0,1,0,4 +1,1,1,1,1,0,5 +1,1,1,0,1,1,5 +1,1,1,1,1,1,6 +2,0,0,0,0,0,2 +2,0,0,1,0,0,3 +2,0,0,0,0,1,3 +2,0,0,1,0,1,4 +2,0,0,0,1,0,3 +2,0,0,1,1,0,4 +2,0,0,0,1,1,4 +2,0,0,1,1,1,5 +2,0,1,0,0,0,3 +2,0,1,1,0,0,4 +2,0,1,0,0,1,4 +2,0,1,1,0,1,5 +2,0,1,0,1,0,4 +2,0,1,1,1,0,5 +2,0,1,0,1,1,5 +2,0,1,1,1,1,6 +2,1,0,0,0,0,3 +2,1,0,1,0,0,4 +2,1,0,0,0,1,4 +2,1,0,1,0,1,5 +2,1,0,0,1,0,4 +2,1,0,1,1,0,5 +2,1,0,0,1,1,5 +2,1,0,1,1,1,6 +2,1,1,0,0,0,4 +2,1,1,1,0,0,5 +2,1,1,0,0,1,5 +2,1,1,1,0,1,6 +2,1,1,0,1,0,5 +2,1,1,1,1,0,6 +2,1,1,0,1,1,6 +2,1,1,1,1,1,7 diff --git a/activitysim/examples/prototype_mtc/configs/stop_frequency_annotate_tours_preprocessor.csv b/activitysim/examples/prototype_mtc/configs/stop_frequency_annotate_tours_preprocessor.csv index d7b2f1d61..675fe4c2d 100644 --- a/activitysim/examples/prototype_mtc/configs/stop_frequency_annotate_tours_preprocessor.csv +++ b/activitysim/examples/prototype_mtc/configs/stop_frequency_annotate_tours_preprocessor.csv @@ -4,6 +4,7 @@ Description,Target,Expression # e.g. univ segment means there will be a spec called stop_frequency_univ.csv,, # so the 'school' tour_type can treat univ and non-univ school tours differently,, ,primary_purpose,"df.tour_type.where((df.tour_type != 'school') | ~df.is_university, 'univ')" +# assigning category columns a new value can be problematic,, ,primary_purpose,"primary_purpose.where(df.tour_category!='atwork', 'atwork')" #,, ,distance_in_miles,od_skims['DIST'] @@ -45,3 +46,6 @@ AccesibilityADestination off-peak transit,_dest_trOpRetail,"reindex(accessibilit AccesibilityAtDestination if transit,pracc,"pracc.where(~tour_mode_is_transit, _dest_trPkRetail.where(_tour_starts_in_peak, _dest_trOpRetail))" AccesibilityAtDestination if non_motorized,pracc,"pracc.where(~tour_mode_is_non_motorized, reindex(accessibility.nmRetail, df.destination))" ,destination_area_type,"reindex(land_use.area_type, df.destination)" +,is_mixed,df.composition=='mixed' +,is_adults_tour,df.composition=='adults' +,is_social,primary_purpose=='social' diff --git a/activitysim/examples/prototype_mtc/configs/stop_frequency_eatout.csv b/activitysim/examples/prototype_mtc/configs/stop_frequency_eatout.csv index f3a1d8505..5765af299 100644 --- a/activitysim/examples/prototype_mtc/configs/stop_frequency_eatout.csv +++ b/activitysim/examples/prototype_mtc/configs/stop_frequency_eatout.csv @@ -27,7 +27,7 @@ util_number_of_visit_tours_tours_undertaken_by_the_person,Number of visit tours util_number_of_shop_tours_undertaken_by_the_houshold,Number of shop tours undertaken by the houshold,num_hh_shop_tours,,,,,,,,,,,,,,,, util_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,Number of persons participating in the tour.Outgoing stops interaction,is_joint * number_of_participants,,,,,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction util_number_of_persons_participating_in_the_tour_return_stops_interaction,Number of persons participating in the tour.Return stops interaction,is_joint * number_of_participants,,,,,,,,,,,,,,,, -util_at_least_one_kid_and_one_adult_participate_in_the_tour,At least one kid and one adult participate in the tour,composition=='mixed',,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour +util_at_least_one_kid_and_one_adult_participate_in_the_tour,At least one kid and one adult participate in the tour,is_mixed,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour util_am_peak_departure_between_6am_and_7_am_including_interacted_with_outbound_tours,AM Peak departure between 6AM and 7 AM (including) Interacted with outbound tours,(start>5) & (start<8),,,,,,,,,,,,,,,, util_arrival_later_than_17_00_,Arrival later than 17:00.,(end > 16),,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_ util_evening_arrival_19_00_interacted_with_return_tours,Evening Arrival (>=19:00) Interacted with return tours,(end > 18),,,,,,,,,,,,,,,, @@ -47,6 +47,6 @@ util_alternative_specific_constant_for_the_total_number_of_stops,Alternative spe util_alternative_specific_constant_for_outbound_stops_on_joint_tours,Alternative specific constant for outbound stops on joint tours,is_joint,,,,,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_1out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_1out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_1out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_1out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in util_alternative_specific_constant_for_return_stops_on_joint_tours,Alternative specific constant for return stops on joint tours,is_joint,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in util_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours,Alternative specific constant for the total number of stops on joint tours,is_joint,,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in -util_dummy_for_an_outbound_visiting_tour,Dummy for an outbound visiting tour,primary_purpose == 'social',,,,,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour -util_dummy_for_a_return_visiting_tour,Dummy for a return visiting tour,primary_purpose == 'social',,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour -util_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,Dummy for a visiting tour with both outbound and return leg,primary_purpose == 'social',,,,,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg +util_dummy_for_an_outbound_visiting_tour,Dummy for an outbound visiting tour,is_social,,,,,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour +util_dummy_for_a_return_visiting_tour,Dummy for a return visiting tour,is_social,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour +util_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,Dummy for a visiting tour with both outbound and return leg,is_social,,,,,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg diff --git a/activitysim/examples/prototype_mtc/configs/stop_frequency_shopping.csv b/activitysim/examples/prototype_mtc/configs/stop_frequency_shopping.csv index 195c6504b..5150da4be 100644 --- a/activitysim/examples/prototype_mtc/configs/stop_frequency_shopping.csv +++ b/activitysim/examples/prototype_mtc/configs/stop_frequency_shopping.csv @@ -27,7 +27,7 @@ util_number_of_visit_tours_tours_undertaken_by_the_person,Number of visit tours util_number_of_shop_tours_undertaken_by_the_houshold,Number of shop tours undertaken by the houshold,num_hh_shop_tours,,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold,coef_number_of_shop_tours_undertaken_by_the_houshold util_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,Number of persons participating in the tour.Outgoing stops interaction,is_joint * number_of_participants,,,,,,,,,,,,,,,, util_number_of_persons_participating_in_the_tour_return_stops_interaction,Number of persons participating in the tour.Return stops interaction,is_joint * number_of_participants,,,,,,,,,,,,,,,, -util_dummy_for_only_adults_participate_in_the_tour,Dummy for only adults participate in the tour,composition=='adults',,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour +util_dummy_for_only_adults_participate_in_the_tour,Dummy for only adults participate in the tour,is_adults_tour,,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour,coef_dummy_for_only_adults_participate_in_the_tour util_am_peak_departure_between_6am_and_7_am_including_interacted_with_outbound_tours,AM Peak departure between 6AM and 7 AM (including) Interacted with outbound tours,(start>5) & (start<8),,,,,,,,,,,,,,,, util_arrival_later_than_17_00_,Arrival later than 17:00.,(end > 16),,,,,,,,,,,,,,,, util_evening_arrival_19_00_interacted_with_return_tours,Evening Arrival (>=19:00) Interacted with return tours,(end > 18),,,,,,,,,,,,,,,, diff --git a/activitysim/examples/prototype_mtc/configs/stop_frequency_social.csv b/activitysim/examples/prototype_mtc/configs/stop_frequency_social.csv index 3a0e2eda9..84e6f6ef7 100644 --- a/activitysim/examples/prototype_mtc/configs/stop_frequency_social.csv +++ b/activitysim/examples/prototype_mtc/configs/stop_frequency_social.csv @@ -27,7 +27,7 @@ util_number_of_visit_tours_tours_undertaken_by_the_person,Number of visit tours util_number_of_shop_tours_undertaken_by_the_houshold,Number of shop tours undertaken by the houshold,num_hh_shop_tours,,,,,,,,,,,,,,,, util_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,Number of persons participating in the tour.Outgoing stops interaction,is_joint * number_of_participants,,,,,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction,coef_number_of_persons_participating_in_the_tour_outgoing_stops_interaction util_number_of_persons_participating_in_the_tour_return_stops_interaction,Number of persons participating in the tour.Return stops interaction,is_joint * number_of_participants,,,,,,,,,,,,,,,, -util_at_least_one_kid_and_one_adult_participate_in_the_tour,At least one kid and one adult participate in the tour,composition=='mixed',,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour +util_at_least_one_kid_and_one_adult_participate_in_the_tour,At least one kid and one adult participate in the tour,is_mixed,,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour,coef_at_least_one_kid_and_one_adult_participate_in_the_tour util_am_peak_departure_between_6am_and_7_am_including_interacted_with_outbound_tours,AM Peak departure between 6AM and 7 AM (including) Interacted with outbound tours,(start>5) & (start<8),,,,,,,,,,,,,,,, util_arrival_later_than_17_00_,Arrival later than 17:00.,(end > 16),,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_,coef_arrival_later_than_17_00_ util_evening_arrival_19_00_interacted_with_return_tours,Evening Arrival (>=19:00) Interacted with return tours,(end > 18),,,,,,,,,,,,,,,, @@ -47,6 +47,6 @@ util_alternative_specific_constant_for_the_total_number_of_stops,Alternative spe util_alternative_specific_constant_for_outbound_stops_on_joint_tours,Alternative specific constant for outbound stops on joint tours,is_joint,,,,,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_1out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_1out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_1out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_1out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_2out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in,coef_alternative_specific_constant_for_outbound_stops_on_joint_tours_3out_0in util_alternative_specific_constant_for_return_stops_on_joint_tours,Alternative specific constant for return stops on joint tours,is_joint,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in util_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours,Alternative specific constant for the total number of stops on joint tours,is_joint,,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in -util_dummy_for_an_outbound_visiting_tour,Dummy for an outbound visiting tour,primary_purpose == 'social',,,,,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour -util_dummy_for_a_return_visiting_tour,Dummy for a return visiting tour,primary_purpose == 'social',,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour -util_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,Dummy for a visiting tour with both outbound and return leg,primary_purpose == 'social',,,,,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg +util_dummy_for_an_outbound_visiting_tour,Dummy for an outbound visiting tour,is_social,,,,,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour,coef_dummy_for_an_outbound_visiting_tour +util_dummy_for_a_return_visiting_tour,Dummy for a return visiting tour,is_social,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour,coef_dummy_for_a_return_visiting_tour +util_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,Dummy for a visiting tour with both outbound and return leg,is_social,,,,,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg,coef_dummy_for_a_visiting_tour_with_both_outbound_and_return_leg diff --git a/activitysim/examples/prototype_mtc_extended/configs/non_mandatory_tour_frequency_alternatives.csv b/activitysim/examples/prototype_mtc_extended/configs/non_mandatory_tour_frequency_alternatives.csv index 0bea47c6f..be633e649 100644 --- a/activitysim/examples/prototype_mtc_extended/configs/non_mandatory_tour_frequency_alternatives.csv +++ b/activitysim/examples/prototype_mtc_extended/configs/non_mandatory_tour_frequency_alternatives.csv @@ -1,100 +1,100 @@ -escort,shopping,othmaint,othdiscr,eatout,social -0,0,0,0,0,0 -0,0,0,1,0,0 -0,0,0,0,0,1 -0,0,0,1,0,1 -0,0,0,0,1,0 -0,0,0,1,1,0 -0,0,0,0,1,1 -0,0,0,1,1,1 -0,0,1,0,0,0 -0,0,1,1,0,0 -0,0,1,0,0,1 -0,0,1,1,0,1 -0,0,1,0,1,0 -0,0,1,1,1,0 -0,0,1,0,1,1 -0,0,1,1,1,1 -0,1,0,0,0,0 -0,1,0,1,0,0 -0,1,0,0,0,1 -0,1,0,1,0,1 -0,1,0,0,1,0 -0,1,0,1,1,0 -0,1,0,0,1,1 -0,1,0,1,1,1 -0,1,1,0,0,0 -0,1,1,1,0,0 -0,1,1,0,0,1 -0,1,1,1,0,1 -0,1,1,0,1,0 -0,1,1,1,1,0 -0,1,1,0,1,1 -0,1,1,1,1,1 -1,0,0,0,0,0 -1,0,0,1,0,0 -1,0,0,0,0,1 -1,0,0,1,0,1 -1,0,0,0,1,0 -1,0,0,1,1,0 -1,0,0,0,1,1 -1,0,0,1,1,1 -1,0,1,0,0,0 -1,0,1,1,0,0 -1,0,1,0,0,1 -1,0,1,1,0,1 -1,0,1,0,1,0 -1,0,1,1,1,0 -1,0,1,0,1,1 -1,0,1,1,1,1 -1,1,0,0,0,0 -1,1,0,1,0,0 -1,1,0,0,0,1 -1,1,0,1,0,1 -1,1,0,0,1,0 -1,1,0,1,1,0 -1,1,0,0,1,1 -1,1,0,1,1,1 -1,1,1,0,0,0 -1,1,1,1,0,0 -1,1,1,0,0,1 -1,1,1,1,0,1 -1,1,1,0,1,0 -1,1,1,1,1,0 -1,1,1,0,1,1 -1,1,1,1,1,1 -2,0,0,0,0,0 -2,0,0,1,0,0 -2,0,0,0,0,1 -2,0,0,1,0,1 -2,0,0,0,1,0 -2,0,0,1,1,0 -2,0,0,0,1,1 -2,0,0,1,1,1 -2,0,1,0,0,0 -2,0,1,1,0,0 -2,0,1,0,0,1 -2,0,1,1,0,1 -2,0,1,0,1,0 -2,0,1,1,1,0 -2,0,1,0,1,1 -2,0,1,1,1,1 -2,1,0,0,0,0 -2,1,0,1,0,0 -2,1,0,0,0,1 -2,1,0,1,0,1 -2,1,0,0,1,0 -2,1,0,1,1,0 -2,1,0,0,1,1 -2,1,0,1,1,1 -2,1,1,0,0,0 -2,1,1,1,0,0 -2,1,1,0,0,1 -2,1,1,1,0,1 -2,1,1,0,1,0 -2,1,1,1,1,0 -2,1,1,0,1,1 -2,1,1,1,1,1 -# extension for flexible ids demonstration,,,,, -# should be removed for actual model run,,,,, -0,0,0,2,0,0 +escort,shopping,othmaint,othdiscr,eatout,social,tot_tours +0,0,0,0,0,0,0 +0,0,0,1,0,0,1 +0,0,0,0,0,1,1 +0,0,0,1,0,1,2 +0,0,0,0,1,0,1 +0,0,0,1,1,0,2 +0,0,0,0,1,1,2 +0,0,0,1,1,1,3 +0,0,1,0,0,0,1 +0,0,1,1,0,0,2 +0,0,1,0,0,1,2 +0,0,1,1,0,1,3 +0,0,1,0,1,0,2 +0,0,1,1,1,0,3 +0,0,1,0,1,1,3 +0,0,1,1,1,1,4 +0,1,0,0,0,0,1 +0,1,0,1,0,0,2 +0,1,0,0,0,1,2 +0,1,0,1,0,1,3 +0,1,0,0,1,0,2 +0,1,0,1,1,0,3 +0,1,0,0,1,1,3 +0,1,0,1,1,1,4 +0,1,1,0,0,0,2 +0,1,1,1,0,0,3 +0,1,1,0,0,1,3 +0,1,1,1,0,1,4 +0,1,1,0,1,0,3 +0,1,1,1,1,0,4 +0,1,1,0,1,1,4 +0,1,1,1,1,1,5 +1,0,0,0,0,0,1 +1,0,0,1,0,0,2 +1,0,0,0,0,1,2 +1,0,0,1,0,1,3 +1,0,0,0,1,0,2 +1,0,0,1,1,0,3 +1,0,0,0,1,1,3 +1,0,0,1,1,1,4 +1,0,1,0,0,0,2 +1,0,1,1,0,0,3 +1,0,1,0,0,1,3 +1,0,1,1,0,1,4 +1,0,1,0,1,0,3 +1,0,1,1,1,0,4 +1,0,1,0,1,1,4 +1,0,1,1,1,1,5 +1,1,0,0,0,0,2 +1,1,0,1,0,0,3 +1,1,0,0,0,1,3 +1,1,0,1,0,1,4 +1,1,0,0,1,0,3 +1,1,0,1,1,0,4 +1,1,0,0,1,1,4 +1,1,0,1,1,1,5 +1,1,1,0,0,0,3 +1,1,1,1,0,0,4 +1,1,1,0,0,1,4 +1,1,1,1,0,1,5 +1,1,1,0,1,0,4 +1,1,1,1,1,0,5 +1,1,1,0,1,1,5 +1,1,1,1,1,1,6 +2,0,0,0,0,0,2 +2,0,0,1,0,0,3 +2,0,0,0,0,1,3 +2,0,0,1,0,1,4 +2,0,0,0,1,0,3 +2,0,0,1,1,0,4 +2,0,0,0,1,1,4 +2,0,0,1,1,1,5 +2,0,1,0,0,0,3 +2,0,1,1,0,0,4 +2,0,1,0,0,1,4 +2,0,1,1,0,1,5 +2,0,1,0,1,0,4 +2,0,1,1,1,0,5 +2,0,1,0,1,1,5 +2,0,1,1,1,1,6 +2,1,0,0,0,0,3 +2,1,0,1,0,0,4 +2,1,0,0,0,1,4 +2,1,0,1,0,1,5 +2,1,0,0,1,0,4 +2,1,0,1,1,0,5 +2,1,0,0,1,1,5 +2,1,0,1,1,1,6 +2,1,1,0,0,0,4 +2,1,1,1,0,0,5 +2,1,1,0,0,1,5 +2,1,1,1,0,1,6 +2,1,1,0,1,0,5 +2,1,1,1,1,0,6 +2,1,1,0,1,1,6 +2,1,1,1,1,1,7 +# extension for flexible ids demonstration,,,,,,0 +# should be removed for actual model run,,,,,,0 +0,0,0,2,0,0,2 diff --git a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_annotate_tours_preprocessor.csv b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_annotate_tours_preprocessor.csv new file mode 100644 index 000000000..bc9a798e3 --- /dev/null +++ b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_annotate_tours_preprocessor.csv @@ -0,0 +1,53 @@ +Description,Target,Expression +#,, +# define primary_purpose to use for slicing choosers with a value that identifies the spec to be used ,, +# e.g. univ segment means there will be a spec called stop_frequency_univ.csv,, +# so the 'school' tour_type can treat univ and non-univ school tours differently,, +,primary_purpose,"df.tour_type.where((df.tour_type != 'school') | ~df.is_university, 'univ')" +# assigning category columns a new value can be problematic +,primary_purpose,"primary_purpose.where(df.tour_category!='atwork', 'atwork')" +#,, +,distance_in_miles,od_skims['DIST'] +#,, +,is_joint,df.tour_category=='joint' +,_HH_PERSON_COUNT,"lambda exp, persons: persons.query(exp).groupby('household_id').size()" +,num_full,"reindex_i(_HH_PERSON_COUNT('ptype == %s' % PEMPLOY_FULL, persons), df.household_id)" +,num_part,"reindex_i(_HH_PERSON_COUNT('ptype == %s' % PEMPLOY_PART, persons), df.household_id)" +,num_student,"reindex_i(_HH_PERSON_COUNT('pstudent != %s' % PSTUDENT_NOT, persons), df.household_id)" +Num Kids between 0 and 4 (including) years old,num_age_0_4,"reindex_i(_HH_PERSON_COUNT('age < 5', persons), df.household_id)" +Num kids between 4 and 15 (including) years old,num_age_5_15,"reindex_i(_HH_PERSON_COUNT('(age >= 5) & (age <16)', persons), df.household_id)" +Number of Adults (>= 16 years old),num_adult,"reindex_i(_HH_PERSON_COUNT('age >= 16', persons), df.household_id)" +,more_cars_than_workers,df.auto_ownership >= (num_full + num_part) +,tour_mode_is_transit,df.tour_mode.isin(TRANSIT_MODES) +,tour_mode_is_drive_transit,df.tour_mode.isin(DRIVE_TO_TRANSIT_MODES) +,tour_mode_is_non_motorized,df.tour_mode.isin(NONMOTORIZED_MODES) +#,, +#num_work_tours already defined,, +school but not university,num_school_tours,"reindex_i(df[primary_purpose==SCHOOL_TOUR].groupby('person_id').size(), df.person_id)" +,num_univ_tours,(df.is_university) * num_school_tours +#num_escort_tours already defined,, +# indiv tour counts should not include joint tours by point_person,, +,num_shop_tours,"reindex_i(df[~is_joint & (df.tour_type==SHOP_TOUR)].groupby('person_id').size(), df.person_id)" +,num_maint_tours,"reindex_i(df[~is_joint & (df.tour_type==MAINT_TOUR)].groupby('person_id').size(), df.person_id)" +,num_eatout_tours,"reindex_i(df[~is_joint & (df.tour_type==EATOUT_TOUR)].groupby('person_id').size(), df.person_id)" +,num_social_tours,"reindex_i(df[~is_joint & (df.tour_type==SOCIAL_TOUR)].groupby('person_id').size(), df.person_id)" +#,, +Number of subtours in the tour,num_atwork_subtours,"df.atwork_subtour_frequency.map(num_atwork_subtours_map, na_action='ignore').fillna(0).astype(np.int8)" +#,, +Number of hh shop tours including joint,num_hh_shop_tours,"reindex_i(df[df.tour_type==SHOP_TOUR].groupby('household_id').size(), df.person_id)" +Number of hh maint tours including joint,num_hh_maint_tours,"reindex_i(df[df.tour_type==MAINT_TOUR].groupby('household_id').size(), df.person_id)" +tourStartsInPeakPeriod,_tour_starts_in_peak,(network_los.skim_time_period_label(df.start) == 'AM') | (network_los.skim_time_period_label(df.start) == 'PM') +AccesibilityAtOrigin fallback,hhacc,0 +AccesibilityAtOrigin if transit,hhacc,"hhacc.where(~tour_mode_is_transit, df.trPkRetail.where(_tour_starts_in_peak, df.trOpRetail))" +AccesibilityAtOrigin if non_motorized,hhacc,"hhacc.where(~tour_mode_is_non_motorized, df.nmRetail)" +AccesibilityADestination fallback,pracc,0 +AccesibilityADestination peak transit,_dest_trPkRetail,"reindex(accessibility.trPkRetail, df.destination)" +AccesibilityADestination off-peak transit,_dest_trOpRetail,"reindex(accessibility.trOpRetail, df.destination)" +AccesibilityAtDestination if transit,pracc,"pracc.where(~tour_mode_is_transit, _dest_trPkRetail.where(_tour_starts_in_peak, _dest_trOpRetail))" +AccesibilityAtDestination if non_motorized,pracc,"pracc.where(~tour_mode_is_non_motorized, reindex(accessibility.nmRetail, df.destination))" +,destination_area_type,"reindex(land_use.area_type, df.destination)" +,is_mixed,df.composition=='mixed' +,is_adults_tour,df.composition=='adults' +,is_social,primary_purpose=='social' +,is_outbound_school_escort,"(df.school_esc_outbound.isin(['ride_share', 'pure_escort']))" +,is_inbound_school_escort,"(df.school_esc_inbound.isin(['ride_share', 'pure_escort']))" \ No newline at end of file diff --git a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_escort.csv b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_escort.csv index e522097e5..1f67721f4 100644 --- a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_escort.csv +++ b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_escort.csv @@ -45,5 +45,5 @@ util_alternative_specific_constant_for_outbound_stops_on_joint_tours,Alternative util_alternative_specific_constant_for_return_stops_on_joint_tours,Alternative specific constant for return stops on joint tours,is_joint,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in,,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_1in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_return_stops_on_joint_tours_0out_3in util_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours,Alternative specific constant for the total number of stops on joint tours,is_joint,,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_on_joint_tours_2out_3in # added for school escorting,,,,,,,,,,,,,,,,,, -util_no_stops_to_school_escorting,Do not allow stops for school escort half-tour -- outbound,"(school_esc_outbound.isin(['ride_share', 'pure_escort']))",,,,,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail -util_no_stops_from_school_escorting,Do not allow stops for school escort half-tour -- inbound,"(school_esc_inbound.isin(['ride_share', 'pure_escort']))",,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail +util_no_stops_to_school_escorting,Do not allow stops for school escort half-tour -- outbound,is_outbound_school_escort,,,,,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail +util_no_stops_from_school_escorting,Do not allow stops for school escort half-tour -- inbound,is_inbound_school_escort,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail diff --git a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_school.csv b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_school.csv index 9aa97f549..28b5c594c 100644 --- a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_school.csv +++ b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_school.csv @@ -42,5 +42,5 @@ util_alternative_specific_constant_for_outbound_stops,Alternative specific const util_alternative_specific_constant_for_return_stops,Alternative specific constant for return stops,1,,coef_alternative_specific_constant_for_return_stops_0out_1in,coef_alternative_specific_constant_for_return_stops_0out_2in,coef_alternative_specific_constant_for_return_stops_0out_3in,,coef_alternative_specific_constant_for_return_stops_0out_1in,coef_alternative_specific_constant_for_return_stops_0out_2in,coef_alternative_specific_constant_for_return_stops_0out_3in,,coef_alternative_specific_constant_for_return_stops_0out_1in,coef_alternative_specific_constant_for_return_stops_0out_2in,coef_alternative_specific_constant_for_return_stops_0out_3in,,coef_alternative_specific_constant_for_return_stops_0out_1in,coef_alternative_specific_constant_for_return_stops_0out_2in,coef_alternative_specific_constant_for_return_stops_0out_3in util_alternative_specific_constant_for_the_total_number_of_stops,Alternative specific constant for the total number of stops,1,,,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in # No stops for half tour that includes school escorting,,,,,,,,,,,,,,,,,, -util_no_stops_to_school_escorting,Do not allow stops for school escort half-tour -- outbound,"(school_esc_outbound.isin(['ride_share', 'pure_escort']))",,,,,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail -util_no_stops_from_school_escorting,Do not allow stops for school escort half-tour -- inbound,"(school_esc_inbound.isin(['ride_share', 'pure_escort']))",,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail +util_no_stops_to_school_escorting,Do not allow stops for school escort half-tour -- outbound,is_outbound_school_escort,,,,,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail +util_no_stops_from_school_escorting,Do not allow stops for school escort half-tour -- inbound,is_inbound_school_escort,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail diff --git a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_univ.csv b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_univ.csv index 8b4b53031..001ff9b37 100644 --- a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_univ.csv +++ b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_univ.csv @@ -42,5 +42,5 @@ util_alternative_specific_constant_for_outbound_stops,Alternative specific const util_alternative_specific_constant_for_return_stops,Alternative specific constant for return stops,1,,coef_alternative_specific_constant_for_return_stops_0out_1in,coef_alternative_specific_constant_for_return_stops_0out_2in,coef_alternative_specific_constant_for_return_stops_0out_3in,,coef_alternative_specific_constant_for_return_stops_0out_1in,coef_alternative_specific_constant_for_return_stops_0out_2in,coef_alternative_specific_constant_for_return_stops_0out_3in,,coef_alternative_specific_constant_for_return_stops_0out_1in,coef_alternative_specific_constant_for_return_stops_0out_2in,coef_alternative_specific_constant_for_return_stops_0out_3in,,coef_alternative_specific_constant_for_return_stops_0out_1in,coef_alternative_specific_constant_for_return_stops_0out_2in,coef_alternative_specific_constant_for_return_stops_0out_3in util_alternative_specific_constant_for_the_total_number_of_stops,Alternative specific constant for the total number of stops,1,,,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_1out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in # No stops for half tour that includes school escorting,,,,,,,,,,,,,,,,,, -util_no_stops_to_school_escorting,Do not allow stops for school escort half-tour -- outbound,"(school_esc_outbound.isin(['ride_share', 'pure_escort']))",,,,,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail -util_no_stops_from_school_escorting,Do not allow stops for school escort half-tour -- inbound,"(school_esc_inbound.isin(['ride_share', 'pure_escort']))",,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail +util_no_stops_to_school_escorting,Do not allow stops for school escort half-tour -- outbound,is_outbound_school_escort,,,,,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail +util_no_stops_from_school_escorting,Do not allow stops for school escort half-tour -- inbound,is_inbound_school_escort,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail diff --git a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_work.csv b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_work.csv index 764064c83..3357951c5 100644 --- a/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_work.csv +++ b/activitysim/examples/prototype_mtc_extended/configs/stop_frequency_work.csv @@ -43,5 +43,5 @@ util_alternative_specific_constant_for_return_stops,Alternative specific constan util_alternative_specific_constant_for_the_total_number_of_stops,Alternative specific constant for the total number of stops,1,,,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_0out_2in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in,coef_alternative_specific_constant_for_the_total_number_of_stops_2out_3in util_number_of_subtours_in_the_tour,Number of subtours in the tour,num_atwork_subtours,,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour,coef_number_of_subtours_in_the_tour # No stops for half tour that includes school escorting,,,,,,,,,,,,,,,,,, -util_no_stops_to_school_escorting,Do not allow stops for school escort half-tour -- outbound,"(school_esc_outbound.isin(['ride_share', 'pure_escort']))",,,,,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail -util_no_stops_from_school_escorting,Do not allow stops for school escort half-tour -- inbound,"(school_esc_inbound.isin(['ride_share', 'pure_escort']))",,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail +util_no_stops_to_school_escorting,Do not allow stops for school escort half-tour -- outbound,is_outbound_school_escort,,,,,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail,coef_unavail +util_no_stops_from_school_escorting,Do not allow stops for school escort half-tour -- inbound,is_inbound_school_escort,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail,,coef_unavail,coef_unavail,coef_unavail diff --git a/activitysim/examples/prototype_mtc_extended/configs/vehicle_type_choice_annotate_choosers_preprocessor.csv b/activitysim/examples/prototype_mtc_extended/configs/vehicle_type_choice_annotate_choosers_preprocessor.csv index d0a98ff3c..c190f781f 100644 --- a/activitysim/examples/prototype_mtc_extended/configs/vehicle_type_choice_annotate_choosers_preprocessor.csv +++ b/activitysim/examples/prototype_mtc_extended/configs/vehicle_type_choice_annotate_choosers_preprocessor.csv @@ -1,6 +1,6 @@ Description,Target,Expression total household distance to work,total_hh_dist_to_work,persons.groupby('household_id')['distance_to_work'].sum().reindex(df.household_id).fillna(0) -total household distance to work capped at 100 mi per worker,total_hh_dist_to_work_cap,"np.where(total_hh_dist_to_work > (100*df.num_workers.values), 100*df.num_workers.values, total_hh_dist_to_work)" +total household distance to work capped at 100 mi per worker,total_hh_dist_to_work_cap,"np.where(total_hh_dist_to_work > (100*df.num_workers.astype('int64').values), 100*df.num_workers.astype('int64').values, total_hh_dist_to_work)" average household distance to work,avg_hh_dist_to_work,persons.groupby('household_id')['distance_to_work'].mean().reindex(df.household_id).fillna(0) household density per square mile,hh_per_mi,(df.TOTHH.values / df.TOTACRE.values) * 640 number of vehicles is greater than the number of drivers,hh_veh_gt_drivers,"np.where(df.auto_ownership > df.num_drivers, 1, 0)" diff --git a/activitysim/examples/prototype_mtc_extended/test/prototype_mtc_extended_reference_pipeline.zip b/activitysim/examples/prototype_mtc_extended/test/prototype_mtc_extended_reference_pipeline.zip index d53f41c28..9dda15936 100644 Binary files a/activitysim/examples/prototype_mtc_extended/test/prototype_mtc_extended_reference_pipeline.zip and b/activitysim/examples/prototype_mtc_extended/test/prototype_mtc_extended_reference_pipeline.zip differ diff --git a/activitysim/examples/prototype_mtc_extended/test/test_mtc_extended.py b/activitysim/examples/prototype_mtc_extended/test/test_mtc_extended.py index b3ec258ba..f78b7f8b9 100644 --- a/activitysim/examples/prototype_mtc_extended/test/test_mtc_extended.py +++ b/activitysim/examples/prototype_mtc_extended/test/test_mtc_extended.py @@ -219,7 +219,6 @@ def test_prototype_mtc_extended_mp_shadow_pricing(): ] -@test.run_if_exists("prototype_mtc_extended_reference_pipeline.zip") def test_prototype_mtc_extended_progressive(): import activitysim.abm # register components @@ -251,20 +250,13 @@ def test_prototype_mtc_extended_progressive(): assert state.settings.chunk_size == 0 assert state.settings.sharrow == False - for step_name in EXPECTED_MODELS: - state.run.by_name(step_name) - try: - state.checkpoint.check_against( - Path(__file__).parent.joinpath( - "prototype_mtc_extended_reference_pipeline.zip" - ), - checkpoint_name=step_name, - ) - except Exception: - print(f"> prototype_mtc_extended {step_name}: ERROR") - raise - else: - print(f"> prototype_mtc_extended {step_name}: ok") + ref_target = Path(__file__).parent.joinpath( + "prototype_mtc_extended_reference_pipeline.zip" + ) + + test.progressive_checkpoint_test( + state, ref_target, EXPECTED_MODELS, name="prototype_mtc_extended" + ) @pytest.mark.parametrize( @@ -307,20 +299,12 @@ def test_prototype_mtc_extended_with_chunking(chunksize): assert state.settings.sharrow == False assert state.settings.chunk_size == chunksize - for step_name in EXPECTED_MODELS: - state.run.by_name(step_name) - try: - state.checkpoint.check_against( - Path(__file__).parent.joinpath( - "prototype_mtc_extended_reference_pipeline.zip" - ), - checkpoint_name=step_name, - ) - except Exception: - print(f"> prototype_mtc_extended {step_name}: ERROR") - raise - else: - print(f"> prototype_mtc_extended {step_name}: ok") + test.progressive_checkpoint_test( + state, + Path(__file__).parent.joinpath("prototype_mtc_extended_reference_pipeline.zip"), + EXPECTED_MODELS, + name="prototype_mtc_extended_with_chunking", + ) if __name__ == "__main__": diff --git a/activitysim/examples/prototype_mwcog/configs/non_mandatory_tour_frequency_alternatives.csv b/activitysim/examples/prototype_mwcog/configs/non_mandatory_tour_frequency_alternatives.csv index b9765aa75..09e89fae3 100644 --- a/activitysim/examples/prototype_mwcog/configs/non_mandatory_tour_frequency_alternatives.csv +++ b/activitysim/examples/prototype_mwcog/configs/non_mandatory_tour_frequency_alternatives.csv @@ -1,97 +1,97 @@ -escort,shopping,othmaint,othdiscr,eatout,social -0,0,0,0,0,0 -0,0,0,1,0,0 -0,0,0,0,0,1 -0,0,0,1,0,1 -0,0,0,0,1,0 -0,0,0,1,1,0 -0,0,0,0,1,1 -0,0,0,1,1,1 -0,0,1,0,0,0 -0,0,1,1,0,0 -0,0,1,0,0,1 -0,0,1,1,0,1 -0,0,1,0,1,0 -0,0,1,1,1,0 -0,0,1,0,1,1 -0,0,1,1,1,1 -0,1,0,0,0,0 -0,1,0,1,0,0 -0,1,0,0,0,1 -0,1,0,1,0,1 -0,1,0,0,1,0 -0,1,0,1,1,0 -0,1,0,0,1,1 -0,1,0,1,1,1 -0,1,1,0,0,0 -0,1,1,1,0,0 -0,1,1,0,0,1 -0,1,1,1,0,1 -0,1,1,0,1,0 -0,1,1,1,1,0 -0,1,1,0,1,1 -0,1,1,1,1,1 -1,0,0,0,0,0 -1,0,0,1,0,0 -1,0,0,0,0,1 -1,0,0,1,0,1 -1,0,0,0,1,0 -1,0,0,1,1,0 -1,0,0,0,1,1 -1,0,0,1,1,1 -1,0,1,0,0,0 -1,0,1,1,0,0 -1,0,1,0,0,1 -1,0,1,1,0,1 -1,0,1,0,1,0 -1,0,1,1,1,0 -1,0,1,0,1,1 -1,0,1,1,1,1 -1,1,0,0,0,0 -1,1,0,1,0,0 -1,1,0,0,0,1 -1,1,0,1,0,1 -1,1,0,0,1,0 -1,1,0,1,1,0 -1,1,0,0,1,1 -1,1,0,1,1,1 -1,1,1,0,0,0 -1,1,1,1,0,0 -1,1,1,0,0,1 -1,1,1,1,0,1 -1,1,1,0,1,0 -1,1,1,1,1,0 -1,1,1,0,1,1 -1,1,1,1,1,1 -2,0,0,0,0,0 -2,0,0,1,0,0 -2,0,0,0,0,1 -2,0,0,1,0,1 -2,0,0,0,1,0 -2,0,0,1,1,0 -2,0,0,0,1,1 -2,0,0,1,1,1 -2,0,1,0,0,0 -2,0,1,1,0,0 -2,0,1,0,0,1 -2,0,1,1,0,1 -2,0,1,0,1,0 -2,0,1,1,1,0 -2,0,1,0,1,1 -2,0,1,1,1,1 -2,1,0,0,0,0 -2,1,0,1,0,0 -2,1,0,0,0,1 -2,1,0,1,0,1 -2,1,0,0,1,0 -2,1,0,1,1,0 -2,1,0,0,1,1 -2,1,0,1,1,1 -2,1,1,0,0,0 -2,1,1,1,0,0 -2,1,1,0,0,1 -2,1,1,1,0,1 -2,1,1,0,1,0 -2,1,1,1,1,0 -2,1,1,0,1,1 -2,1,1,1,1,1 +escort,shopping,othmaint,othdiscr,eatout,social,tot_tours +0,0,0,0,0,0,0 +0,0,0,1,0,0,1 +0,0,0,0,0,1,1 +0,0,0,1,0,1,2 +0,0,0,0,1,0,1 +0,0,0,1,1,0,2 +0,0,0,0,1,1,2 +0,0,0,1,1,1,3 +0,0,1,0,0,0,1 +0,0,1,1,0,0,2 +0,0,1,0,0,1,2 +0,0,1,1,0,1,3 +0,0,1,0,1,0,2 +0,0,1,1,1,0,3 +0,0,1,0,1,1,3 +0,0,1,1,1,1,4 +0,1,0,0,0,0,1 +0,1,0,1,0,0,2 +0,1,0,0,0,1,2 +0,1,0,1,0,1,3 +0,1,0,0,1,0,2 +0,1,0,1,1,0,3 +0,1,0,0,1,1,3 +0,1,0,1,1,1,4 +0,1,1,0,0,0,2 +0,1,1,1,0,0,3 +0,1,1,0,0,1,3 +0,1,1,1,0,1,4 +0,1,1,0,1,0,3 +0,1,1,1,1,0,4 +0,1,1,0,1,1,4 +0,1,1,1,1,1,5 +1,0,0,0,0,0,1 +1,0,0,1,0,0,2 +1,0,0,0,0,1,2 +1,0,0,1,0,1,3 +1,0,0,0,1,0,2 +1,0,0,1,1,0,3 +1,0,0,0,1,1,3 +1,0,0,1,1,1,4 +1,0,1,0,0,0,2 +1,0,1,1,0,0,3 +1,0,1,0,0,1,3 +1,0,1,1,0,1,4 +1,0,1,0,1,0,3 +1,0,1,1,1,0,4 +1,0,1,0,1,1,4 +1,0,1,1,1,1,5 +1,1,0,0,0,0,2 +1,1,0,1,0,0,3 +1,1,0,0,0,1,3 +1,1,0,1,0,1,4 +1,1,0,0,1,0,3 +1,1,0,1,1,0,4 +1,1,0,0,1,1,4 +1,1,0,1,1,1,5 +1,1,1,0,0,0,3 +1,1,1,1,0,0,4 +1,1,1,0,0,1,4 +1,1,1,1,0,1,5 +1,1,1,0,1,0,4 +1,1,1,1,1,0,5 +1,1,1,0,1,1,5 +1,1,1,1,1,1,6 +2,0,0,0,0,0,2 +2,0,0,1,0,0,3 +2,0,0,0,0,1,3 +2,0,0,1,0,1,4 +2,0,0,0,1,0,3 +2,0,0,1,1,0,4 +2,0,0,0,1,1,4 +2,0,0,1,1,1,5 +2,0,1,0,0,0,3 +2,0,1,1,0,0,4 +2,0,1,0,0,1,4 +2,0,1,1,0,1,5 +2,0,1,0,1,0,4 +2,0,1,1,1,0,5 +2,0,1,0,1,1,5 +2,0,1,1,1,1,6 +2,1,0,0,0,0,3 +2,1,0,1,0,0,4 +2,1,0,0,0,1,4 +2,1,0,1,0,1,5 +2,1,0,0,1,0,4 +2,1,0,1,1,0,5 +2,1,0,0,1,1,5 +2,1,0,1,1,1,6 +2,1,1,0,0,0,4 +2,1,1,1,0,0,5 +2,1,1,0,0,1,5 +2,1,1,1,0,1,6 +2,1,1,0,1,0,5 +2,1,1,1,1,0,6 +2,1,1,0,1,1,6 +2,1,1,1,1,1,7 diff --git a/conda-environments/activitysim-dev-base.yml b/conda-environments/activitysim-dev-base.yml index 7a94ae4e1..ec1f2e0f2 100644 --- a/conda-environments/activitysim-dev-base.yml +++ b/conda-environments/activitysim-dev-base.yml @@ -49,7 +49,7 @@ dependencies: - psutil = 5.9.* - pyarrow = 11.* - pycodestyle -- pydantic = 1.10.* +- pydantic = 2.6.* - pydata-sphinx-theme - pyinstrument = 4.4 - pypyr = 5.8.* @@ -75,4 +75,4 @@ dependencies: - zstandard - pip: - - autodoc_pydantic >=1.9,<2.0 + - autodoc_pydantic diff --git a/conda-environments/activitysim-dev.yml b/conda-environments/activitysim-dev.yml index dd1437581..f805b6e36 100644 --- a/conda-environments/activitysim-dev.yml +++ b/conda-environments/activitysim-dev.yml @@ -31,6 +31,7 @@ dependencies: - myst-parser # allows markdown in sphinx - nbconvert - nbformat +- nbmake - numba = 0.56.* - numexpr - numpy = 1.23.* @@ -44,7 +45,7 @@ dependencies: - psutil = 5.9.* - pyarrow = 11.* - pycodestyle -- pydantic = 1.10.* +- pydantic = 2.6.* - pydata-sphinx-theme - pyinstrument = 4.4 - pypyr = 5.8.* @@ -71,5 +72,5 @@ dependencies: - zstandard - pip: - - autodoc_pydantic >=1.9,<2.0 + - autodoc_pydantic - -e .. diff --git a/conda-environments/docbuild.yml b/conda-environments/docbuild.yml index 2e289fa9f..c738ab3a1 100644 --- a/conda-environments/docbuild.yml +++ b/conda-environments/docbuild.yml @@ -36,7 +36,7 @@ dependencies: - platformdirs - psutil >= 4.1 - pyarrow >= 2.0 -- pydantic = 1.10.* +- pydantic = 2.6.* - pypyr >= 5.3 - pytables >=3.7 - pytest @@ -56,5 +56,5 @@ dependencies: - zarr - pip: - - autodoc_pydantic >=1.9,<2.0 + - autodoc_pydantic - -e .. diff --git a/conda-environments/github-actions-tests.yml b/conda-environments/github-actions-tests.yml index 3636f4bc0..5edb8fef7 100644 --- a/conda-environments/github-actions-tests.yml +++ b/conda-environments/github-actions-tests.yml @@ -22,7 +22,7 @@ dependencies: - platformdirs = 3.2.* - psutil = 5.9.* - pyarrow = 11.* -- pydantic = 1.10.* +- pydantic = 2.6.* - pypyr = 5.8.* - pytables >= 3.7 - pytest = 7.2.* diff --git a/setup.cfg b/setup.cfg index a33f1b3d8..6051b75af 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,6 +33,7 @@ install_requires = platformdirs psutil >= 4.1 pyarrow >= 2.0 + pydantic >= 2.6 pypyr >= 5.3 pyyaml >= 5.1 requests >= 2.7