Skip to content

Commit 7e5202e

Browse files
authored
Patch sharrow sandag (#1009)
* descriptive error * allow partial success in setting up skims - if there is no time period we should still be able to get time-agnostic values * comments for better context on why * require sharrow 2.15 * update lock file * blacken * update docstring * address whitespace
1 parent c57e032 commit 7e5202e

File tree

4 files changed

+66
-24
lines changed

4 files changed

+66
-24
lines changed

activitysim/abm/models/trip_destination.py

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,23 +1496,42 @@ def run_trip_destination(
14961496
for primary_purpose, trips_segment in nth_trips.groupby(
14971497
"primary_purpose", observed=True
14981498
):
1499-
choices, destination_sample = choose_trip_destination(
1500-
state,
1501-
primary_purpose,
1502-
trips_segment,
1503-
alternatives,
1504-
tours_merged,
1505-
model_settings,
1506-
want_logsums,
1507-
want_sample_table,
1508-
size_term_matrix,
1509-
skim_hotel,
1510-
estimator,
1511-
chunk_size,
1512-
trace_label=tracing.extend_trace_label(
1513-
nth_trace_label, primary_purpose
1514-
),
1515-
)
1499+
try:
1500+
choices, destination_sample = choose_trip_destination(
1501+
state,
1502+
primary_purpose,
1503+
trips_segment,
1504+
alternatives,
1505+
tours_merged,
1506+
model_settings,
1507+
want_logsums,
1508+
want_sample_table,
1509+
size_term_matrix,
1510+
skim_hotel,
1511+
estimator,
1512+
chunk_size,
1513+
trace_label=tracing.extend_trace_label(
1514+
nth_trace_label, primary_purpose
1515+
),
1516+
)
1517+
except KeyError as err:
1518+
if err.args[0] == "purpose_index_num":
1519+
logger.error(
1520+
"""
1521+
1522+
When using the trip destination model with sharrow, it is necessary
1523+
to set a value for `purpose_index_num` in the trip destination
1524+
annotate trips preprocessor. This allows for an optimized compiled
1525+
lookup of the size term from the array of size terms. The value of
1526+
`purpose_index_num` should be the integer column position in the size
1527+
matrix, with usual zero-based numpy indexing semantics (i.e. the first
1528+
column is zero). The preprocessor expression most likely needs to be
1529+
"size_terms.get_cols(df.purpose)" unless some unusual transform of
1530+
size terms has been employed.
1531+
1532+
"""
1533+
)
1534+
raise
15161535

15171536
choices_list.append(choices)
15181537
if want_sample_table:

activitysim/core/simulate.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ def to_array(x):
989989
# return utilities
990990

991991

992-
def set_skim_wrapper_targets(df, skims):
992+
def set_skim_wrapper_targets(df, skims, allow_partial_success: bool = True):
993993
"""
994994
Add the dataframe to the SkimWrapper object so that it can be dereferenced
995995
using the parameters of the skims object.
@@ -1007,6 +1007,11 @@ def set_skim_wrapper_targets(df, skims):
10071007
dataframe that comes back from interacting choosers with
10081008
alternatives. See the skims module for more documentation on how
10091009
the skims object is intended to be used.
1010+
allow_partial_success : bool, optional
1011+
If True (default), failures to set skim targets for some skim objects
1012+
(for example due to missing required columns in `df`) will be collected
1013+
and logged as warnings but will not raise an exception. If False, any
1014+
such failure will be raised immediately, preventing partial success.
10101015
"""
10111016

10121017
skims = (
@@ -1016,13 +1021,31 @@ def set_skim_wrapper_targets(df, skims):
10161021
if isinstance(skims, dict)
10171022
else [skims]
10181023
)
1024+
problems = []
10191025

10201026
# assume any object in skims can be treated as a skim
10211027
for skim in skims:
10221028
try:
10231029
skim.set_df(df)
10241030
except AttributeError:
1031+
# sometimes when passed as a dict, the skims have a few keys given as
1032+
# settings or constants, which are not actually "skim" objects and have
1033+
# no `set_df` attribute. This is fine and we just let them pass.
10251034
pass
1035+
except AssertionError as e:
1036+
# An assertion error will get triggered if the columns of `df` are
1037+
# missing one of the required keys needed to look up values in the
1038+
# skims. This may not be a problem, if this particular set of skims
1039+
# is not actually used in this model component. So we'll warn about
1040+
# it but usually not raise a showstopping error.
1041+
problems.append(e)
1042+
if not allow_partial_success:
1043+
raise
1044+
1045+
if problems:
1046+
# if problems were discovered, log them as warnings
1047+
for problem in problems:
1048+
logger.warning(str(problem))
10261049

10271050

10281051
#

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ dependencies = [
2626
"requests >= 2.7",
2727
"scikit-learn >= 1.2",
2828
"setuptools>=80.9.0",
29-
"sharrow >= 2.9.1",
29+
"sharrow>=2.15",
3030
"sparse",
3131
"tables >= 3.9", # pytables is tables in pypi
3232
"xarray >= 2024.05",

uv.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)