ActivitySim / activitysim

An Open Platform for Activity-Based Travel Modeling
https://activitysim.github.io
BSD 3-Clause "New" or "Revised" License
194 stars 99 forks source link

Pydantic validator crashing model when logsum calculation done with MNL model #908

Open JoeJimFlood opened 2 weeks ago

JoeJimFlood commented 2 weeks ago

Describe the bug When trying to run SANDAG's airport access models using ActivitySim version 1.3.2, there was a crash in nonmandatory tour destination that happened when evaluating the logsums using the (dummy) tour mode choice MNL model. This was caused by the validator requiring the nest_spec to be either a LogitNestSpec object or a dictionary. However, if one looks at the function that gets the nest_spec, it returns None if the model is set to be MNL. This is later used as a flag to be MNL or NL when evaluating utilities, so having the nest_spec as a None type shouldn't be causing a crash.

To Reproduce Steps to reproduce the behavior:

  1. Using ActivitySim v1.3.2, run a destination choice model that calculates logsums with a MNL logit model such as tour mode choice in SANDAG's airport access models (NOTE--if using that example some other configs may need to be adjusted to account for changes made in version 1.3).
  2. The model should fail due to a ValidationError.

Expected behavior The logsums should have properly been evaluated without needing to check that the nonexistent nesting structure was valid.

Screenshots Full traceback from logfile:

Traceback (most recent call last):
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\core\mp_tasks.py", line 1098, in mp_run_simulation
    run_simulation(state, queue, step_info, resume_after, shared_data_buffer)
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\core\mp_tasks.py", line 1048, in run_simulation
    raise e
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\core\mp_tasks.py", line 1043, in run_simulation
    state.run.by_name(model)
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\core\workflow\runner.py", line 347, in by_name
    self._obj._context = run_named_step(
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\core\workflow\steps.py", line 83, in run_named_step
    step_func(context, **kwargs)
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\core\workflow\steps.py", line 367, in run_step
    outcome = error_logging(wrapped_func)(state, *args, **kwargs)
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\core\workflow\steps.py", line 46, in wrapper
    return func(*args, **kwargs)
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\abm\models\non_mandatory_destination.py", line 82, in non_mandatory_tour_destination
    choices_df, save_sample_df = tour_destination.run_tour_destination(
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\abm\models\util\tour_destination.py", line 856, in run_tour_destination
    location_sample_df = run_destination_logsums(
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\abm\models\util\tour_destination.py", line 660, in run_destination_logsums
    logsums = logsum.compute_location_choice_logsums(
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\abm\models\util\logsums.py", line 170, in compute_location_choice_logsums
    nest_spec = simulate.eval_nest_coefficients(nest_spec, coefficients, trace_label)
  File "\\JUPITER\ABM\user\jflo\repos\asim132\activitysim\core\simulate.py", line 470, in eval_nest_coefficients
    nest_spec = LogitNestSpec.model_validate(nest_spec)
  File "C:\Anaconda3\envs\asim_132\lib\site-packages\pydantic\main.py", line 596, in model_validate
    return cls.__pydantic_validator__.validate_python(
pydantic_core._pydantic_core.ValidationError: 1 validation error for LogitNestSpec
  Input should be a valid dictionary or instance of LogitNestSpec [type=model_type, input_value=None, input_type=NoneType]
    For further information visit https://errors.pydantic.dev/2.9/v/model_type
JoeJimFlood commented 2 weeks ago

909 proposes a potential solution

JoeJimFlood commented 2 weeks ago

Also, adding this to the tour mode choice settings appears to have been a sufficient workaround:

LOGIT_TYPE: NL

NESTS:
  name: root
  coefficient: 1
  alternatives:
    - DRIVEALONE
    - SHARED2
    - SHARED3
    - WALK
    - BIKE
    - WALK_TRANSIT
    - TAXI
    - TNC_SINGLE
    - TNC_SHARED