1+ # ActivitySim
2+ # See full license in LICENSE.txt.
3+ from __future__ import annotations
4+
5+ import logging
6+
7+ import pandas as pd
8+
9+ from activitysim .core import (
10+ config ,
11+ estimation ,
12+ expressions ,
13+ simulate ,
14+ tracing ,
15+ workflow ,
16+ )
17+ from activitysim .core .configuration .base import PreprocessorSettings
18+ from activitysim .core .configuration .logit import LogitComponentSettings
19+
20+ logger = logging .getLogger ("activitysim" )
21+
22+ class BikeComfortSettings (LogitComponentSettings , extra = "forbid" ):
23+ """
24+ Settings for the 'bike_comfort' model.
25+ """
26+ CHOOSE_FILTER_COLUMN_NAME : str = "adult"
27+ """Column name in the dataframe to filter persons eligible for license holding status model."""
28+
29+ @workflow .steps
30+ def bike_comfort (
31+ state : workflow .State ,
32+ persons_merged : pd .DataFrame ,
33+ persons : pd .DataFrame ,
34+ model_settings : BikeComfortSettings | None = None ,
35+ model_settings_file_name : str = "bike_comfort.yaml" ,
36+ trace_label : str = "bike_comfort" ,
37+ ) -> None :
38+ """
39+ This model predicts the bike comfort level for each person.
40+ The alternatives of this model are NoWyNoHow, InterestedButConcerned, EnthsuedAndConfident, StrongAndFearless
41+ """
42+
43+ if model_settings is None :
44+ model_settings = BikeComfortSettings .read_settings_file (
45+ state .filesystem ,
46+ model_settings_file_name ,
47+ )
48+
49+ choosers = persons_merged
50+ chooser_filter_columun_name = model_settings .CHOOSE_FILTER_COLUMN_NAME
51+ choosers = choosers [(choosers [chooser_filter_columun_name ])]
52+ logger .info ("Running %s with %d persons" , trace_label , len (choosers ))
53+
54+ estimator = estimation .manager .begin_estimation (state , 'bike_comfort' )
55+
56+ constants = config .get_model_constants (model_settings )
57+
58+ # - processor
59+ expressions .annotate_preprocesors (
60+ state ,
61+ df = choosers ,
62+ locals_dict = constants ,
63+ skims = None ,
64+ model_settings = model_settings ,
65+ trace_label = trace_label ,
66+ )
67+
68+ model_spec = state .filesystem .read_model_spec (file_name = model_settings .SPEC )
69+ coefficients_df = state .filesystem .read_model_coefficients (model_settings )
70+ model_spec = simulate .eval_coefficients (
71+ state , model_spec , coefficients_df , estimator
72+ )
73+ nest_spec = config .get_logit_model_settings (model_settings )
74+
75+ if estimator :
76+ estimator .write_model_settings (model_settings , model_settings_file_name )
77+ estimator .write_spec (model_settings )
78+ estimator .write_coefficients (coefficients_df , model_settings )
79+ estimator .write_choosers (choosers )
80+
81+ choices = simulate .simple_simulate (
82+ state ,
83+ choosers = choosers ,
84+ spec = model_spec ,
85+ nest_spec = nest_spec ,
86+ locals_d = constants ,
87+ trace_label = trace_label ,
88+ trace_choice_name = "bike_comfort" ,
89+ estimator = estimator ,
90+ compute_settings = model_settings .compute_settings ,
91+ )
92+
93+ choices = pd .Series (model_spec .columns [choices .values ], index = choices .index )
94+ bike_comfort_cat = pd .api .types .CategoricalDtype (
95+ model_spec .columns .tolist () + ["" ],
96+ ordered = False ,
97+ )
98+
99+ choices = choices .astype (bike_comfort_cat )
100+
101+ if estimator :
102+ estimator .write_choices (choices )
103+ choices = estimator .get_survey_values (
104+ choices , "persons" , "bike_comfort" )
105+ estimator .write_override_choices (choices )
106+ estimator .end_estimation ()
107+
108+ persons ["bike_comfort" ] = choices .reindex (persons .index ).fillna ("" )
109+
110+ state .add_table ("persons" , persons )
111+
112+ tracing .print_summary (
113+ "bike_comfort" , persons .telecommute_frequency , value_counts = True
114+ )
115+
116+ if state .settings .trace_hh_id :
117+ state .tracing .trace_df (persons , label = trace_label , warn_if_empty = True )
118+
119+ expressions .annotate_tables (
120+ state ,
121+ locals_dict = constants ,
122+ skims = None ,
123+ model_settings = model_settings ,
124+ trace_label = trace_label ,
125+ )
0 commit comments