From cdcca9185c5e3d057dd7ba0afef7e94134d01dd6 Mon Sep 17 00:00:00 2001 From: David Hensle Date: Fri, 15 Dec 2023 17:12:02 -0800 Subject: [PATCH 1/4] mode choice logsum extraction --- activitysim/abm/models/location_choice.py | 48 +++++++++++++++++++---- activitysim/core/configuration/logit.py | 5 ++- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/activitysim/abm/models/location_choice.py b/activitysim/abm/models/location_choice.py index 937721c05..5200bc2d8 100644 --- a/activitysim/abm/models/location_choice.py +++ b/activitysim/abm/models/location_choice.py @@ -833,6 +833,24 @@ def run_location_choice( ) state.tracing.trace_df(choices_df, estimation_trace_label) + if want_logsums & (not skip_choice): + # grabbing index, could be person_id or proto_person_id + index_name = choices_df.index.name + # merging mode choice logsum of chosen alternative to choices + choices_df = ( + pd.merge( + choices_df.reset_index(), + location_sample_df.reset_index()[ + [index_name, model_settings["ALT_DEST_COL_NAME"], ALT_LOGSUM] + ], + how="left", + left_on=[index_name, "choice"], + right_on=[index_name, model_settings["ALT_DEST_COL_NAME"]], + ) + .drop(columns=model_settings["ALT_DEST_COL_NAME"]) + .set_index(index_name) + ) + choices_list.append(choices_df) if want_sample_table: @@ -850,7 +868,7 @@ def run_location_choice( else: # this will only happen with small samples (e.g. singleton) with no (e.g.) school segs logger.warning("%s no choices", trace_label) - choices_df = pd.DataFrame(columns=["choice", "logsum"]) + choices_df = pd.DataFrame(columns=["choice", "logsum", ALT_LOGSUM]) if len(sample_list) > 0: save_sample_df = pd.concat(sample_list) @@ -893,7 +911,8 @@ def iterate_location_choice( Returns ------- adds choice column model_settings['DEST_CHOICE_COLUMN_NAME'] - adds logsum column model_settings['DEST_CHOICE_LOGSUM_COLUMN_NAME']- if provided + adds destination choice logsum column model_settings['DEST_CHOICE_LOGSUM_COLUMN_NAME']- if provided + adds mode choice logsum to selected destination column model_settings['MODE_CHOICE_LOGSUM_COLUMN_NAME']- if provided adds annotations to persons table """ @@ -903,7 +922,11 @@ def iterate_location_choice( chooser_filter_column = model_settings.CHOOSER_FILTER_COLUMN_NAME dest_choice_column_name = model_settings.DEST_CHOICE_COLUMN_NAME - logsum_column_name = model_settings.DEST_CHOICE_LOGSUM_COLUMN_NAME + dc_logsum_column_name = model_settings.DEST_CHOICE_LOGSUM_COLUMN_NAME + mc_logsum_column_name = model_settings.MODE_CHOICE_LOGSUM_COLUMN_NAME + want_logsums = (dc_logsum_column_name is not None) | ( + mc_logsum_column_name is not None + ) sample_table_name = model_settings.DEST_CHOICE_SAMPLE_TABLE_NAME want_sample_table = ( @@ -954,7 +977,7 @@ def iterate_location_choice( persons_merged_df_, network_los, shadow_price_calculator=spc, - want_logsums=logsum_column_name is not None, + want_logsums=want_logsums, want_sample_table=want_sample_table, estimator=estimator, model_settings=model_settings, @@ -1029,10 +1052,15 @@ def iterate_location_choice( ) # add the dest_choice_logsum column to persons dataframe - if logsum_column_name: - persons_df[logsum_column_name] = ( + if dc_logsum_column_name: + persons_df[dc_logsum_column_name] = ( choices_df["logsum"].reindex(persons_df.index).astype("float") ) + # add the mode choice logsum column to persons dataframe + if mc_logsum_column_name: + persons_df[mc_logsum_column_name] = ( + choices_df[ALT_LOGSUM].reindex(persons_df.index).astype("float") + ) if save_sample_df is not None: # might be None for tiny samples even if sample_table_name was specified @@ -1072,9 +1100,13 @@ def iterate_location_choice( if state.settings.trace_hh_id: state.tracing.trace_df(households_df, label=trace_label, warn_if_empty=True) - if logsum_column_name: + if dc_logsum_column_name: + tracing.print_summary( + dc_logsum_column_name, choices_df["logsum"], value_counts=True + ) + if mc_logsum_column_name: tracing.print_summary( - logsum_column_name, choices_df["logsum"], value_counts=True + mc_logsum_column_name, choices_df[ALT_LOGSUM], value_counts=True ) return persons_df diff --git a/activitysim/core/configuration/logit.py b/activitysim/core/configuration/logit.py index c01187eeb..170a1fbfc 100644 --- a/activitysim/core/configuration/logit.py +++ b/activitysim/core/configuration/logit.py @@ -175,8 +175,11 @@ class TourLocationComponentSettings(LocationComponentSettings, extra="forbid"): annotate_tours: PreprocessorSettings | None = None CHOOSER_FILTER_COLUMN_NAME: str | None = None - DEST_CHOICE_COLUMN_NAME: str | None = None + DEST_CHOICE_COLUMN_NAME: str | None = Nones DEST_CHOICE_LOGSUM_COLUMN_NAME: str | None = None + """Column name for logsum calculated across all sampled destinations.""" + MODE_CHOICE_LOGSUM_COLUMN_NAME: str | None = None + """Column name for logsum calculated across all sampled modes to selected destination.""" DEST_CHOICE_SAMPLE_TABLE_NAME: str | None = None CHOOSER_TABLE_NAME: str | None = None CHOOSER_SEGMENT_COLUMN_NAME: str | None = None From b955295166836374d37d9e59618cf22e54af54e7 Mon Sep 17 00:00:00 2001 From: David Hensle Date: Mon, 18 Dec 2023 11:56:54 -0800 Subject: [PATCH 2/4] blacken --- activitysim/abm/models/location_choice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activitysim/abm/models/location_choice.py b/activitysim/abm/models/location_choice.py index 5200bc2d8..359b23d6e 100644 --- a/activitysim/abm/models/location_choice.py +++ b/activitysim/abm/models/location_choice.py @@ -850,7 +850,7 @@ def run_location_choice( .drop(columns=model_settings["ALT_DEST_COL_NAME"]) .set_index(index_name) ) - + choices_list.append(choices_df) if want_sample_table: From fe0c284f9d1edc2a4219e26aff77325214c0544d Mon Sep 17 00:00:00 2001 From: David Hensle Date: Fri, 8 Mar 2024 14:11:35 -0800 Subject: [PATCH 3/4] fix Nones to None typo --- activitysim/core/configuration/logit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activitysim/core/configuration/logit.py b/activitysim/core/configuration/logit.py index 170a1fbfc..cb6cf0432 100644 --- a/activitysim/core/configuration/logit.py +++ b/activitysim/core/configuration/logit.py @@ -175,7 +175,7 @@ class TourLocationComponentSettings(LocationComponentSettings, extra="forbid"): annotate_tours: PreprocessorSettings | None = None CHOOSER_FILTER_COLUMN_NAME: str | None = None - DEST_CHOICE_COLUMN_NAME: str | None = Nones + DEST_CHOICE_COLUMN_NAME: str | None = None DEST_CHOICE_LOGSUM_COLUMN_NAME: str | None = None """Column name for logsum calculated across all sampled destinations.""" MODE_CHOICE_LOGSUM_COLUMN_NAME: str | None = None From d1f4db82fb6f10d36ecb2cbbb773bd43ac9bdac5 Mon Sep 17 00:00:00 2001 From: David Hensle Date: Fri, 8 Mar 2024 15:09:38 -0800 Subject: [PATCH 4/4] call ALT_DEST_COL_NAME as attribute --- activitysim/abm/models/location_choice.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/activitysim/abm/models/location_choice.py b/activitysim/abm/models/location_choice.py index 359b23d6e..6b11f8522 100644 --- a/activitysim/abm/models/location_choice.py +++ b/activitysim/abm/models/location_choice.py @@ -841,13 +841,13 @@ def run_location_choice( pd.merge( choices_df.reset_index(), location_sample_df.reset_index()[ - [index_name, model_settings["ALT_DEST_COL_NAME"], ALT_LOGSUM] + [index_name, model_settings.ALT_DEST_COL_NAME, ALT_LOGSUM] ], how="left", left_on=[index_name, "choice"], - right_on=[index_name, model_settings["ALT_DEST_COL_NAME"]], + right_on=[index_name, model_settings.ALT_DEST_COL_NAME], ) - .drop(columns=model_settings["ALT_DEST_COL_NAME"]) + .drop(columns=model_settings.ALT_DEST_COL_NAME) .set_index(index_name) )