arup-group / gelato

Gelato turns MATSim outputs into transport sustainability KPI metrics
GNU General Public License v3.0
10 stars 1 forks source link

Accessibility to Mobility Services: Duplicate Values & potentially altered def #70

Open divyasharma-arup opened 8 months ago

divyasharma-arup commented 8 months ago

Using gelato alpha 0.03, with outputs saved here: /mnt/efs/analysis/ds/gelato_outputs/baseline_30pct

Bug: Currently, the intermediate table for access appears to be producing duplicates. Different values for the used_pt calculation may be driving some of these duplicates (screenshot below):

Screenshot 2024-03-14 at 14 50 49

I think right now used_pt may be measuring who used PT regardless of their access to it, not sure? I just know that sometimes I see both bus_access_400m = False and rail_acccess_800m = False but the used_pt flag is True, screenshot below.

Screenshot 2024-03-14 at 14 55 43

Enhancement: On reflection, we want to capture the used_pt flag a bit differently: the definition is meant to be, of those who live near a PT service, how many people use PT? However, I think we need to modify this further: Of those who have a home witihn 800m of a PT service, how many people travelled within 800m to use PT? This effectively highlights the gap between having access to a service and actually utilising it. I think we need to use the leg_logs table to determine this. We only want to look at walking legs that accessed PT, as the measure is meant to capture those within walking distance. Below is an example weaving through a few of the available tables to calculate this.

# get list of trip_ids where agents used PT to either get to or go home
used_pt_from_home = list(scenario.trip_logs[(scenario.trip_logs['longest_distance_mode']=='pt')& .\
((scenario.trip_logs['start_activity_type']=='home')|(scenario.trip_logs['end_activity_type']=='home'))]['trip_id'].unique())
pt_walk_legs = scenario.leg_logs[(scenario.leg_logs['trip_id'].isin(used_pt_from_home))&(scenario.leg_logs['mode']=='walk')].copy()

# get the total distance travelled to access PT..a risk here in that we may care most about the "access leg" vs an "interchange leg"
pt_walk_legs = pt_walk_legs.groupby(['person', 'trip_id']).agg({'distance':'sum'}).reset_index()
# filter to those who walked less than 800m total for that trip
pt_user_800m = list(pt_walk_legs[pt_walk_legs['distance']<=800]['person'].unique())
scenario.int_access['pt_used_800m'] = np.where(scenario.int_access['person'].isin(pt_user_800m), True, False)

print(f'Used PT Current Measure: {scenario.int_access["used_pt"].sum()/scenario.int_access["person"].count()}')
print(f'Used PT New Measure: {scenario.int_access["pt_used_800m"].sum()/scenario.int_access["person"].count()}')

Therefore, this KPI would be interpreted as follows: 98.4% of agents in the Paris East sim have access (within 400m) to bus, 53.35% have access (within 800m) to rail. Of these agents, 14.3% used a PT service within 800m of their home.

Screenshot 2024-03-14 at 15 20 34