Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions activitysim/abm/models/parking_location_choice.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ def choose_parking_location(
destination_sample = logit.interaction_dataset(trips, alternatives, alt_index_id=alt_dest_col_name)
destination_sample.index = np.repeat(trips.index.values, len(alternatives))
destination_sample.index.name = trips.index.name
destination_sample = destination_sample[[alt_dest_col_name]].copy()

# # - trip_destination_simulate
destinations = parking_destination_simulate(
Expand Down Expand Up @@ -199,9 +198,6 @@ def run_parking_destination(

alt_column_filter_name = model_settings.get('ALTERNATIVE_FILTER_COLUMN_NAME')
alternatives = land_use[land_use[alt_column_filter_name]]

# don't need size terms in alternatives, just TAZ index
alternatives = alternatives.drop(alternatives.columns, axis=1)
alternatives.index.name = parking_location_column_name

choices_list = []
Expand Down
62 changes: 62 additions & 0 deletions test/parking_location/compare-parking-location-results.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
library(tidyverse)
library(ggplot2)

trips_df <- read_csv("./output/trips_after_parking_choice.csv")

walk_dist_df <- read_csv("./data/ped_distance_maz_maz.csv")

landuse_df <- read_csv("./data/land_use.csv")

landuse_df <- landuse_df %>%
select(maz, maz_county_based, TAZ_ORIGINAL)

work_df <- trips_df %>%
rename(parking_maz_target = parking_mgra) %>%
rename(parking_maz_simulated = parking_zone) %>%
select(trip_id, household_id, person_id, person_num, stop_id, tour_purpose, orig_purpose, dest_purpose, orig_maz = origin, dest_maz = destination,
activity_duration_in_hours, parking_maz_target, parking_maz_simulated) %>%
left_join(landuse_df, by = c("orig_maz" = "maz")) %>%
rename(orig_maz_county_based = maz_county_based, orig_taz = TAZ_ORIGINAL) %>%
left_join(landuse_df, by = c("dest_maz" = "maz")) %>%
rename(dest_maz_county_based = maz_county_based, dest_taz = TAZ_ORIGINAL) %>%
left_join(landuse_df, by = c("parking_maz_target" = "maz")) %>%
rename(parking_maz_county_based_target = maz_county_based, parking_taz_target = TAZ_ORIGINAL) %>%
left_join(landuse_df, by = c("parking_maz_simulated" = "maz")) %>%
rename(parking_maz_county_based_simulated = maz_county_based, parking_taz_simulated = TAZ_ORIGINAL) %>%
left_join(walk_dist_df, by = c("parking_maz_simulated" = "OMAZ", "dest_maz" = "DMAZ")) %>%
rename(parking_distance_simulated = DISTWALK) %>%
left_join(walk_dist_df, by = c("parking_maz_target" = "OMAZ", "dest_maz" = "DMAZ")) %>%
rename(parking_distance_target = DISTWALK) %>%
left_join(walk_dist_df, by = c("parking_maz_target" = "OMAZ", "parking_maz_simulated" = "DMAZ")) %>%
rename(distance_target_simulation = DISTWALK) %>%
select(trip_id, household_id, person_id, stop_id, tour_purpose, orig_purpose, dest_purpose,
orig_maz, dest_maz, orig_maz_county_based, dest_maz_county_based, orig_taz, dest_taz,
parking_maz_target, parking_maz_simulated, parking_taz_target, parking_taz_simulated,
parking_distance_target, parking_distance_simulated, distance_target_simulation)


write.csv(work_df, "./output/parking-location-choice-results.csv", row.names = F)


summary_df <- work_df %>%
group_by(dest_purpose) %>%
summarise(
trips_count = n(),
min_distance_target = round(min(parking_distance_target, na.rm = T), 3),
min_distance_simulated = round(min(parking_distance_simulated, na.rm = T), 3),
max_distance_target = round(max(parking_distance_target, na.rm = T), 3),
max_distance_simulated = round(max(parking_distance_simulated, na.rm = T), 3),
mean_distance_target = round(mean(parking_distance_target, na.rm = T), 3),
mean_distance_simulated = round(mean(parking_distance_simulated, na.rm = T), 3),
median_distance_target = round(median(parking_distance_target, na.rm = T), 3),
median_distance_simulated = round(median(parking_distance_simulated, na.rm = T), 3)
)

#ggplot(work_df, aes(x=distance_target_simulation)) + geom_histogram(binwidth=0.025, color="black", fill="white")

#ggplot(work_df, aes(x=parking_distance_target)) + geom_histogram(binwidth=0.05, color="black", fill="white")

#ggplot(work_df, aes(x=parking_distance_simulated)) + geom_histogram(binwidth=0.05, color="black", fill="white")



Binary file not shown.
13 changes: 13 additions & 0 deletions test/parking_location/configs/annotate_households.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Description,Target,Expression
#,, annotate households table after import
,_PERSON_COUNT,"lambda query, persons, households: persons.query(query).groupby('household_id').size().reindex(households.index).fillna(0).astype(np.int8)"
number of fulltime workers,num_full_time_workers,"_PERSON_COUNT('ptype == 1', persons, households)"
number of parttime workers,num_part_time_workers,"_PERSON_COUNT('ptype == 2', persons, households)"
number of university student,num_university_students,"_PERSON_COUNT('ptype == 3', persons, households)"
number of non-workers,num_non_workers,"_PERSON_COUNT('ptype == 4', persons, households)"
number of retirees,num_retirees,"_PERSON_COUNT('ptype == 5', persons, households)"
number of driving age students,num_driving_age_students,"_PERSON_COUNT('ptype == 6', persons, households)"
number of pre-driving age school kids,num_pre_driving_age_school_kids,"_PERSON_COUNT('ptype == 7', persons, households)"
number of pre-school kids,num_pre_school_kids,"_PERSON_COUNT('ptype == 8', persons, households)"
number of pre-driving age school kids who go out,num_pre_driving_age_school_kids_go_out,"_PERSON_COUNT('(ptype == 7) & (cdap_activity != \'H\')', persons, households)"
number of pre-school kids who go out,num_pre_school_kids_go_out,"_PERSON_COUNT('(ptype == 8) & (cdap_activity != \'H\')', persons, households)"
7 changes: 7 additions & 0 deletions test/parking_location/configs/annotate_landuse.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Description,Target,Expression
#,, annotate landuse table after import
household_density,household_density,land_use.TOTHH / land_use.TOTACRE
employment_density,employment_density,land_use.TOTEMP / land_use.TOTACRE
population_density,population_density,land_use.TOTPOP / land_use.TOTACRE
density_index,density_index,(household_density *employment_density) / (household_density + employment_density).clip(lower=1)
is_parking_zone,is_parking_zone,"np.where(land_use.parkarea==1,True,False)"
16 changes: 16 additions & 0 deletions test/parking_location/configs/annotate_persons.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Description,Target,Expression
#,, annotate persons table after import
age_16_to_19,age_16_to_19,"persons.age.between(16, 19)"
age_16_p,age_16_p,persons.age >= 16
adult,adult,persons.age >= 18
male,male,persons.sex == 1
female,female,persons.sex == 2
,ptype,0
,ptype,"np.where(persons.type == 'Full-time worker', 1, ptype)"
,ptype,"np.where(persons.type == 'Part-time worker', 2, ptype)"
,ptype,"np.where(persons.type == 'University student', 3, ptype)"
,ptype,"np.where(persons.type == 'Non-worker', 4, ptype)"
,ptype,"np.where(persons.type == 'Retired', 5, ptype)"
,ptype,"np.where(persons.type == 'Student of driving age', 6, ptype)"
,ptype,"np.where(persons.type == 'Student of non-driving age', 7, ptype)"
,ptype,"np.where(persons.type == 'Child too young for school', 8, ptype)"
5 changes: 5 additions & 0 deletions test/parking_location/configs/annotate_persons_after_hh.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Description,Target,Expression
#,, annotate persons table after annotate_households
#,, adults get full hh_value_of_time and children get 60%
,_hh_vot,"reindex(households.hh_value_of_time, persons.household_id)"
,value_of_time,"_hh_vot.where(persons.age>=18, _hh_vot * 0.667)"
37 changes: 37 additions & 0 deletions test/parking_location/configs/initialize_households.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
annotate_tables:
- tablename: persons
column_map:
HHID: household_id
PERID: person_id
AGEP: age
SEX: sex
SCHL: education_attainment
OCCP: occupation
WKHP: hours_worked
WKW: weeks_worked
EMPLOYED: employment_status
ESR: esr
SCHG: grade_attending
activity_pattern: cdap_activity
annotate:
SPEC: annotate_persons
DF: persons
TABLES:
- households
- tablename: households
column_map:
HHID: household_id
HHINCADJ: income
NWRKRS_ESR: num_workers
VEH: auto_ownership
NP: hhsize
HHT: hh_type
BLD: building_size
TYPE: hh_unit_type
MTCCountyID: county_id
annotate:
SPEC: annotate_households
DF: households
TABLES:
- persons
- land_use
52 changes: 52 additions & 0 deletions test/parking_location/configs/initialize_landuse.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
annotate_tables:
- tablename: land_use
column_map:
CountyID: county_id
DistID: DISTRICT
HH: TOTHH
POP: TOTPOP
ACRES: TOTACRE
emp_total: TOTEMP
annotate:
SPEC: annotate_landuse
DF: land_use
- tablename: accessibility
column_map:
column_1: nonmandatory_auto_accessibility
column_2: nonmandatory_transit_accessibility
column_3: nonmandatory_nm_accessibility
column_4: nonmandatory_sov0_accessibility
column_5: nonmandatory_sov1_accessibility
column_6: nonmandatory_sov2_accessibility
column_7: nonmandatory_hov0_accessibility
column_8: nonmandatory_hov1_accessibility
column_9: nonmandatory_hov2_accessibility
column_10: shop_hov_insufficient_accessibility
column_11: shop_hov_sufficient_accessibility
column_12: shop_hov_oversufficient_accessibility
column_13: maint_hov_insufficient_accessibility
column_14: maint_hov_sufficient_accessibility
column_15: maint_hov_oversufficient_accessibility
column_16: eat_hov_insufficient_accessibility
column_17: eat_hov_sufficient_accessibility
column_18: eat_hov_oversufficient_accessibility
column_19: visit_hov_insufficient_accessibility
column_20: visit_hov_sufficient_accessibility
column_21: visit_hov_oversufficient_accessibility
column_22: discr_hov_insufficient_accessibility
column_23: discr_hov_sufficient_accessibility
column_24: discr_hov_oversufficient_accessibility
column_25: escort_hov_insufficient_accessibility
column_26: escort_hov_sufficient_accessibility
column_27: escort_hov_oversufficient_accessibility
column_28: shop_sov_insufficient_accessibility
column_29: shop_sov_sufficient_accessibility
column_30: shop_sov_oversufficient_accessibility
column_31: maint_sov_insufficient_accessibility
column_32: maint_sov_sufficient_accessibility
column_33: maint_sov_oversufficient_accessibility
column_40: discr_sov_insufficient_accessibility
column_41: discr_sov_sufficient_accessibility
column_42: discr_sov_oversufficient_accessibility
column_45: total_emp_accessibility
column_47: hh_walktransit_accessibility
24 changes: 24 additions & 0 deletions test/parking_location/configs/network_los.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# read cached skims (using numpy memmap) from output directory (memmap is faster than omx )
read_skim_cache: False
# write memmapped cached skims to output directory after reading from omx, for use in subsequent runs
write_skim_cache: False

zone_system: 2

taz_skims: skims.omx

maz: maz.csv

maz_to_maz:
tables:
- ped_distance_maz_maz.csv

# maz_to_maz blending distance (missing or 0 means no blending)
max_blend_distance:
DISTWALK: 0

skim_time_periods:
time_window: 1440
period_minutes: 60
periods: [0, 3, 5, 9, 14, 18, 24] # 3=3:00-3:59, 5=5:00-5:59, 9=9:00-9:59, 14=2:00-2:59, 18=6:00-6:59
labels: ['EA', 'EA', 'AM', 'MD', 'PM', 'EV']
34 changes: 34 additions & 0 deletions test/parking_location/configs/parking_location_choice.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Description,Expression,no_segmentation
Person is worker,_person_is_worker@((df.ptype == 1) | (df.ptype == 2)),1
Trip is work purpose,_work_trip@(df.purpose == 'work'),1
Number of hourly stalls,[email protected],1
Number of daily stalls,[email protected],1
Number of monthly stalls,[email protected],1
Hourly stalls available,_hourly_stalls_available@_hourly_stalls > 0,1
Daily stalls available,_daily_stalls_available@_daily_stalls > 0,1
Monthly stalls available,_monthly_stalls_available@_monthly_stalls > 0,1
Hourly parking cost cents,[email protected] * 100,1
Number of free parking hours,[email protected],1
Daily parking cost cents,[email protected] * 100,1
Monthly parking cost cents,[email protected] * 100,1
Monthly parking is allowed,_monthly_allowed@_monthly_stalls_available & _work_trip & _person_is_worker,1
Total hourly parking cost,_total_hourly_parking_cost@(_hourly_parking_cost * (df.activity_duration - _num_free_hours)),1
Hourly is cheaper than daily,"[email protected](_daily_stalls_available, _total_hourly_parking_cost < _daily_parking_cost,True)",1
Hourly is cheaper than monthly,"[email protected](_monthly_allowed, _total_hourly_parking_cost < _monthly_parking_cost,True)",1
Hourly parking is best,_hourly_best@(_hourly_stalls_available & _hourly_cheaper_than_daily & _hourly_cheaper_than_monthly),1
Daily is cheaper than hourly,"[email protected](_hourly_stalls_available, _daily_parking_cost < _total_hourly_parking_cost,True)",1
Daily is cheaper than monthly,"[email protected](_monthly_allowed, _daily_parking_cost < _monthly_parking_cost,True)",1
Daily parking is best,_daily_best@(_daily_stalls_available & _daily_cheaper_than_hourly & _daily_cheaper_than_monthly),1
Monthly is cheaper than hourly,"[email protected](_hourly_stalls_available, _monthly_parking_cost < _total_hourly_parking_cost,True)",1
Monthly is cheaper than daily,"[email protected](_daily_stalls_available, _monthly_parking_cost < _daily_stalls_available,True)",1
Monthly parking is best,_monthly_best@(_monthly_allowed & _monthly_cheaper_than_hourly & _monthly_cheaper_than_daily),1
Parking size,_parking_size@(_hourly_best * _hourly_stalls) + (_daily_best * _daily_stalls) + (_monthly_best * _monthly_stalls),1
Parking cost,_parking_cost@(_hourly_best * _total_hourly_parking_cost) + (_daily_best * _daily_parking_cost) + (_monthly_best * _monthly_parking_cost),1
Parking to destination distance skim,_walk_distance@pd_skims['DISTWALK'],1
# actual utility terms starts from here
Log of parking size,"@np.where(_parking_size>0,np.log(_parking_size),-9999)",1
Cost work trip,"@np.where(df.purpose == 'work', _parking_cost, 0)",coef_cost_work_trip
Cost other trip,"@np.where(df.purpose != 'work', _parking_cost, 0)",coef_cost_other_trip
Walk distance,@_walk_distance,coef_walk_distance
Walk Unavailability,"@np.where(_walk_distance == 0, 1, 0)",coef_unavailable
Require parking zone to be less than 0.75 mile from dest,"@np.where(_walk_distance > 0.75, 1, 0) * (df.destination != df.parking_zone)",coef_unavailable
22 changes: 22 additions & 0 deletions test/parking_location/configs/parking_location_choice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
SPECIFICATION: parking_location_choice.csv

COEFFICIENTS: parking_location_choice_coeffs.csv

PREPROCESSOR:
SPEC: parking_location_choice_annotate_trips_preprocessor
DF: trips_merged
TABLES:
- land_use
- persons

# boolean column to filter choosers (True means keep)
CHOOSER_FILTER_COLUMN_NAME: is_park_eligible
CHOOSER_SEGMENT_COLUMN_NAME: parking_segment

ALTERNATIVE_FILTER_COLUMN_NAME: is_parking_zone
ALT_DEST_COL_NAME: parking_zone

TRIP_DEPARTURE_PERIOD: 'stop_period'

TRIP_ORIGIN: origin
TRIP_DESTINATION: destination
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Description,Target,Expression
Person Type,ptype,"reindex(persons.ptype, df.person_id)"
Trip mode is drive,drive_trip,df.trip_mode <= 8
Parking segment,parking_segment,setting('segment')
Parking eligible trip,is_park_eligible,(drive_trip & (df.purpose != "home"))
Activity duration,activity_duration,df.activity_duration_in_hours
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
coefficient_name,value,constrain
coef_unavailable,-9999,T
coef_walk_distance,-11.8,F
coef_cost_work_trip,-0.0072,F
coef_cost_other_trip,-0.0041,F
62 changes: 62 additions & 0 deletions test/parking_location/configs/settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# input tables
input_table_list:
- tablename: households
filename: households.csv
index_col: household_id
rename_columns:
unique_hh_id: household_id
NP: hhsize
hh_workers_from_esr: num_workers
VEH: auto_ownership
MAZ: home_zone_id
HINCP: income
keep_columns:
- home_zone_id
- income
- hhsize
- HHT
- auto_ownership
- num_workers
- tablename: persons
filename: persons.csv
index_col: person_id
rename_columns:
unique_hh_id: household_id
AGEP: age
SPORDER: PNUM
SEX: sex
employed: pemploy
student_status: pstudent
person_type: ptype
keep_columns:
- household_id
- age
- PNUM
- sex
- pemploy
- pstudent
- ptype
- tablename: land_use
filename: land_use.csv
index_col: zone_id
rename_columns:
MAZ_ORIGINAL: zone_id
CountyID: county_id
TAZ_ORIGINAL: TAZ
DistID: DISTRICT
HH: TOTHH
POP: TOTPOP
ACRES: TOTACRE
emp_total: TOTEMP
keep_columns:
- TAZ
- DISTRICT
- SD
- county_id
- TOTHH
- TOTPOP
- TOTACRE

trace_hh_id: 5924

segment: "no_segmentation"
Loading