Skip to content

Commit e4dc5ac

Browse files
committed
reducing memory needs in parking_location_choice
1 parent 98713f3 commit e4dc5ac

2 files changed

Lines changed: 91 additions & 6 deletions

File tree

activitysim/abm/models/parking_location_choice.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
)
1717
from activitysim.core.interaction_sample_simulate import interaction_sample_simulate
1818
from activitysim.core.tracing import print_elapsed_time
19-
from activitysim.core.util import assign_in_place
19+
from activitysim.core.util import assign_in_place, drop_unused_chooser_columns
2020

2121
from .util import estimation
2222

@@ -99,6 +99,7 @@ def parking_destination_simulate(
9999
destination_sample,
100100
model_settings,
101101
skims,
102+
locals_dict,
102103
chunk_size,
103104
trace_hh_id,
104105
trace_label,
@@ -123,11 +124,6 @@ def parking_destination_simulate(
123124

124125
logger.info("Running trip_destination_simulate with %d trips", len(trips))
125126

126-
locals_dict = config.get_model_constants(model_settings).copy()
127-
locals_dict.update(skims)
128-
locals_dict["timeframe"] = "trip"
129-
locals_dict["PARKING"] = skims["op_skims"].dest_key
130-
131127
parking_locations = interaction_sample_simulate(
132128
choosers=trips,
133129
alternatives=destination_sample,
@@ -171,6 +167,19 @@ def choose_parking_location(
171167
t0 = print_elapsed_time()
172168

173169
alt_dest_col_name = model_settings["ALT_DEST_COL_NAME"]
170+
171+
# remove trips and alts columns that are not used in spec
172+
locals_dict = config.get_model_constants(model_settings).copy()
173+
locals_dict.update(skims)
174+
locals_dict["timeframe"] = "trip"
175+
locals_dict["PARKING"] = skims["op_skims"].dest_key
176+
177+
spec = get_spec_for_segment(model_settings, "SPECIFICATION", segment_name)
178+
trips = drop_unused_chooser_columns(trips, spec, locals_dict, custom_chooser=None)
179+
alternatives = drop_unused_chooser_columns(
180+
alternatives, spec, locals_dict, custom_chooser=None
181+
)
182+
174183
destination_sample = logit.interaction_dataset(
175184
trips, alternatives, alt_index_id=alt_dest_col_name
176185
)
@@ -184,6 +193,7 @@ def choose_parking_location(
184193
destination_sample=destination_sample,
185194
model_settings=model_settings,
186195
skims=skims,
196+
locals_dict=locals_dict,
187197
chunk_size=chunk_size,
188198
trace_hh_id=trace_hh_id,
189199
trace_label=trace_label,

activitysim/core/util.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,3 +468,78 @@ def nearest_node_index(node, nodes):
468468
deltas = nodes - node
469469
dist_2 = np.einsum("ij,ij->i", deltas, deltas)
470470
return np.argmin(dist_2)
471+
472+
473+
def drop_unused_chooser_columns(
474+
choosers, spec, locals_d, custom_chooser, sharrow_enabled=False
475+
):
476+
"""
477+
Drop unused columns from the chooser table, based on the spec and custom_chooser function.
478+
"""
479+
# keep only variables needed for spec
480+
import re
481+
482+
# define a regular expression to find variables in spec
483+
pattern = r"[a-zA-Z_][a-zA-Z0-9_]*"
484+
485+
unique_variables_in_spec = set(
486+
spec.reset_index()["Expression"].apply(lambda x: re.findall(pattern, x)).sum()
487+
)
488+
489+
if locals_d:
490+
unique_variables_in_spec.add(locals_d.get("orig_col_name", None))
491+
unique_variables_in_spec.add(locals_d.get("dest_col_name", None))
492+
if locals_d.get("timeframe") == "trip":
493+
orig_col_name = locals_d.get("ORIGIN", None)
494+
dest_col_name = locals_d.get("DESTINATION", None)
495+
stop_col_name = None
496+
parking_col_name = locals_d.get("PARKING", None)
497+
primary_origin_col_name = None
498+
if orig_col_name is None and "od_skims" in locals_d:
499+
orig_col_name = locals_d["od_skims"].orig_key
500+
if dest_col_name is None and "od_skims" in locals_d:
501+
dest_col_name = locals_d["od_skims"].dest_key
502+
if stop_col_name is None and "dp_skims" in locals_d:
503+
stop_col_name = locals_d["dp_skims"].dest_key
504+
if primary_origin_col_name is None and "dnt_skims" in locals_d:
505+
primary_origin_col_name = locals_d["dnt_skims"].dest_key
506+
unique_variables_in_spec.add(orig_col_name)
507+
unique_variables_in_spec.add(dest_col_name)
508+
unique_variables_in_spec.add(parking_col_name)
509+
unique_variables_in_spec.add(primary_origin_col_name)
510+
unique_variables_in_spec.add(stop_col_name)
511+
unique_variables_in_spec.add("trip_period")
512+
# when using trip_scheduling_choice for trup scheduling
513+
unique_variables_in_spec.add("last_outbound_stop")
514+
unique_variables_in_spec.add("last_inbound_stop")
515+
516+
# when sharrow mode, need to keep the following columns in the choosers table
517+
if sharrow_enabled:
518+
unique_variables_in_spec.add("out_period")
519+
unique_variables_in_spec.add("in_period")
520+
unique_variables_in_spec.add("purpose_index_num")
521+
522+
if custom_chooser:
523+
import inspect
524+
525+
custom_chooser_lines = inspect.getsource(custom_chooser)
526+
unique_variables_in_spec.update(re.findall(pattern, custom_chooser_lines))
527+
528+
logger.info("Dropping unused variables in chooser table")
529+
530+
logger.info(
531+
"before dropping, the choosers table has {} columns: {}".format(
532+
len(choosers.columns), choosers.columns
533+
)
534+
)
535+
536+
# keep only variables needed for spec
537+
choosers = choosers[[c for c in choosers.columns if c in unique_variables_in_spec]]
538+
539+
logger.info(
540+
"after dropping, the choosers table has {} columns: {}".format(
541+
len(choosers.columns), choosers.columns
542+
)
543+
)
544+
545+
return choosers

0 commit comments

Comments
 (0)