Repository navigation
Description
network_los is not available in expression files run through expressions.annotate_tables (e.g. trip_mode_choice postprocessor)
Describe the bug
Expression specs evaluated through expressions.compute_columns / expressions.annotate_tables (preprocessors and annotate-table specs) cannot reference network_los. For example, a trip_mode_choice annotate_trips spec that labels trips with their skim time period fails with a NameError, because network_los is not in the locals dictionary used to evaluate the expressions.
compute_columns already exposes skim_dict (and skim_dataset_dict when sharrow is on), but not the Network_LOS object, so helpers such as network_los.skim_time_period_label() and network_los.skim_time_periods cannot be used from these specs unless the calling model happens to add network_los to locals_dict itself. trip_mode_choice does not.
To Reproduce
-
Add the following row to the
annotate_tripsspec referenced by theannotate_tripssetting intrip_mode_choice.yaml(a CSV liketrip_mode_choice_annotate_trips_postprocessor.csv):Description,Target,Expression trip time period label,time_period,network_los.skim_time_period_label(df.depart)The accompanying
network_los.yamlhas the usualskim_time_periodsblock, for example:skim_time_periods: time_window: 1440 period_minutes: 30 periods: [0, 4, 14, 24, 36, 48] labels: ["EA", "AM", "MD", "PM", "NI"]
-
Run a model that includes
trip_mode_choice(for example the TransLink model, ActivitySim v1.6.0 tag8ca6741). -
The run fails at the end of
trip_mode_choice, when the annotate-trips spec is evaluated.
Log output:
ERROR: assign_variables - NameError (name 'network_los' is not defined) evaluating: network_los.skim_time_period_label(mid_hour_bin)
Traceback (most recent call last):
File ".../activitysim/core/assign.py", line 397, in assign_variables
expr_values = to_series(eval(expression, globals_dict, _locals_dict))
File "<string>", line 1, in <module>
NameError: name 'network_los' is not defined
ERROR: ===== ERROR IN trip_mode_choice =====
ERROR: name 'network_los' is not defined
Traceback (most recent call last):
File ".../activitysim/abm/models/trip_mode_choice.py", line 338, in trip_mode_choice
expressions.annotate_tables(
File ".../activitysim/core/expressions.py", line 327, in annotate_tables
results = compute_columns(
File ".../activitysim/core/expressions.py", line 136, in compute_columns
results, trace_results, trace_assigned_locals = assign.assign_variables(
NameError: name 'network_los' is not defined
Expected behavior
network_los should be available in every expression evaluated by compute_columns, alongside skim_dict, so a spec can use network_los.skim_time_period_label(...) without each model having to pass network_los explicitly. The time period labels and bounds then come from network_los.yaml, the single place they are defined, and do not have to be duplicated as constants in each spec.
Screenshots
Not applicable.
Additional context
- Workaround without a code change: hard-code the period bounds and labels in the spec, for example
pd.cut(df.depart, [0, 4, 14, 24, 36, 48], labels=[...]). This duplicatesnetwork_los.yamland silently goes stale ifskim_time_periodschanges. - Other models, such as
trip_destination, passnetwork_losexplicitly in their ownlocals_dict, which is why the same kind of expression works there.
Activity
janzill commentedon Oct 31, 2026
resolved by #1134