Skip to content

Commit 51e298a

Browse files
committed
Fix discarded trip_period output by limiting cleanup to temporary columns
1 parent 2776bfd commit 51e298a

2 files changed

Lines changed: 35 additions & 16 deletions

File tree

activitysim/abm/models/trip_mode_choice.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,9 @@ def add_trip_period(choosers):
350350
# needed in the purpose-sized chooser frames above, but post-choice table
351351
# annotators may also use those skims. Add it to the full trips table only
352352
# for annotation, then restore the original table schema.
353-
add_trip_period(trips_df)
353+
temporary_trip_period = "trip_period" not in trips_df.columns
354+
if temporary_trip_period:
355+
add_trip_period(trips_df)
354356
try:
355357
expressions.annotate_tables(
356358
state,
@@ -360,7 +362,10 @@ def add_trip_period(choosers):
360362
trace_label=trace_label,
361363
)
362364
finally:
363-
trips_df.drop(columns="trip_period", inplace=True)
364-
state_trips = state.get_dataframe("trips", as_copy=False)
365-
if state_trips is not trips_df:
366-
state_trips.drop(columns="trip_period", inplace=True)
365+
# CHOOSER_COLS_TO_KEEP may have made trip_period an output column.
366+
# Remove it only when this annotation block created it temporarily.
367+
if temporary_trip_period:
368+
trips_df.drop(columns="trip_period", inplace=True)
369+
state_trips = state.get_dataframe("trips", as_copy=False)
370+
if state_trips is not trips_df:
371+
state_trips.drop(columns="trip_period", inplace=True)

activitysim/abm/test/test_trip_mode_choice.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from __future__ import annotations
22

33
import weakref
4+
from contextlib import nullcontext
45
from types import SimpleNamespace
56

67
import pandas as pd
8+
import pytest
79

810
from activitysim.abm.models import trip_mode_choice as trip_mode_choice_module
911

@@ -55,7 +57,12 @@ def is_table(self, _name):
5557
return False
5658

5759

58-
def test_post_choice_annotations_receive_full_trip_period_then_remove_it(monkeypatch):
60+
@pytest.mark.parametrize("keep_trip_period", [False, True])
61+
@pytest.mark.parametrize("copy_annotation_table", [False, True])
62+
@pytest.mark.parametrize("annotation_error", [False, True])
63+
def test_post_choice_annotations_preserve_requested_trip_period(
64+
monkeypatch, keep_trip_period, copy_annotation_table, annotation_error
65+
):
5966
trips = pd.DataFrame(
6067
{
6168
"tour_id": [11, 12, 13],
@@ -79,7 +86,7 @@ def test_post_choice_annotations_receive_full_trip_period_then_remove_it(monkeyp
7986
model_settings = SimpleNamespace(
8087
MODE_CHOICE_LOGSUM_COLUMN_NAME="mode_choice_logsum",
8188
TOURS_MERGED_CHOOSER_COLUMNS=[],
82-
CHOOSER_COLS_TO_KEEP=[],
89+
CHOOSER_COLS_TO_KEEP=["trip_period"] if keep_trip_period else [],
8390
FORCE_ESCORTEE_CHAUFFEUR_MODE_MATCH=False,
8491
SPEC="trip_mode_choice.csv",
8592
explicit_chunk=None,
@@ -132,26 +139,33 @@ def choose_mode(_state, choosers, **_kwargs):
132139
monkeypatch.setattr(trip_mode_choice_module, "mode_choice_simulate", choose_mode)
133140

134141
def annotate_tables(_state, **_kwargs):
135-
annotated = _state.get_dataframe("trips")
142+
annotated = _state.get_dataframe("trips", as_copy=copy_annotation_table)
136143
assert annotated.index.equals(trips.index)
137144
assert annotated["trip_period"].tolist() == [0, 1, 0]
138145
annotated["post_choice_skim_value"] = [10.0, 20.0, 30.0]
139146
_state.add_table("trips", annotated)
147+
if annotation_error:
148+
raise RuntimeError("annotation failed")
140149

141150
monkeypatch.setattr(
142151
trip_mode_choice_module.expressions, "annotate_tables", annotate_tables
143152
)
144153

145-
trip_mode_choice_module.trip_mode_choice(
146-
state,
147-
trips,
148-
network_los,
149-
model_settings=model_settings,
150-
)
154+
with pytest.raises(
155+
RuntimeError, match="annotation failed"
156+
) if annotation_error else nullcontext():
157+
trip_mode_choice_module.trip_mode_choice(
158+
state,
159+
trips,
160+
network_los,
161+
model_settings=model_settings,
162+
)
151163

152164
assert all(ref() is None for ref in chooser_refs)
153165
assert all(wrapper.df.empty for wrapper in wrappers)
154166
result = state.get_dataframe("trips", as_copy=False)
155-
assert "trip_period" not in trips
156-
assert "trip_period" not in result
167+
assert ("trip_period" in trips) == keep_trip_period
168+
assert ("trip_period" in result) == keep_trip_period
169+
if keep_trip_period:
170+
assert result["trip_period"].tolist() == [0, 1, 0]
157171
assert result["post_choice_skim_value"].tolist() == [10.0, 20.0, 30.0]

0 commit comments

Comments
 (0)