arup-group / gelato

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

Mobility Space Usage #71

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 Looking at the implementation of Mobility Space Usage, I'm not able to validate that it's capturing the maximum occupancy within a facility throughout the day.

This was my approach to try and capture the occupancy of each facility:

  1. Filter to all people that arrive at a facility in a car
  2. Sum the cumulative arrivals for each person to each facility_id
  3. Sum the cumulative number of departures for each new entry into a facility
  4. The difference is the occupancy at each new event for a facility_id.
  5. The maximum occupancy for each facility is computed, and multiplied by the average parking space size.

Code below (note: my implemented logic doesn't work well for trips beyond 24 hours...)

# filter activities to the people that arrived by car
car_activities = activities[(activities['access_mode']=='car')|(activities['egress_mode']=='car')]
car_activities = car_activities.sort_values(by=['facility_id', 'start_time'])

# count number of arrivals
car_activities['arrival'] = 1
car_activities['arrival'] = car_activities.groupby(['facility_id'])['arrival'].cumsum()
# count departures each time someone new enters
car_activities['departure'] = car_activities.apply(
    lambda row: (car_activities[car_activities['facility_id']==row['facility_id']]['end_time_s'] \
    < row['start_time_s']).sum(), axis=1)

# parking demand is arrivals less departures
car_activities['parking_demand'] = car_activities['arrival'] - car_activities['departure']
car_activities['max_demand'] = car_activities.groupby('facility_id')['parking_demand'].transform('max')
car_activities['max_demand_m2'] = car_activities['max_demand']*11.5`

Looking at an example here, I believe the max occupancy should be 2 people, as there are three arrivals by car and one person departs before the next one arrives. However, the KPI (mob_space_demand) states the occupancy is 3. I'm not sure if the departures is accounted for accurately, perhaps.

Screenshot 2024-03-15 at 10 56 10

Below is another example where I think the car arrivals come one after another, so there's only demand for one space. Here, my logic vs the implemented KPI is much further off. Screenshot 2024-03-15 at 11 00 57

Enhancement Theo and I discussed, and decided the weighting by number of trips to each facility is not necessary. We can instead report that total parking demand divided by the number of people, as below: print(f'Final KPI: {car_activities.groupby(["activity_type"])["max_demand_m2"].max().sum()/len(scenario.persons}')