Building applications on processed data#
Typical scenarios#
Aggregate the performance indices by intersection, corridor or region;
diagnose signal timing (offsets, splits, coordination) from trajectories and SPaT;
develop and evaluate signal control algorithms;
design offline signal plans.
Applications only need mtldp-meta-utils and the processed data of a region.
Step 1: Create the configuration file#
(mtldp) $ create_config_file -n my_corridor -c oakland -m application \
-s 2025-03-03 -e 2025-03-09 -j 62590214,62590221
Configuration file generated at: `configs/my_corridor.json`
The dates become date_str_list and the junctions junction_id_list; both are the defaults
used when loading trajectories. When the data comes from a sub-region of a processed master
region, the sub-region configuration produced by the pipeline can be used directly instead
(configs/<master>_subs/<tile>.json); its mode is preprocessing but AppRegion
accepts it as long as the processed files exist.
Step 2: Create the directory tree#
(mtldp) $ create_region -c configs/my_corridor.json
Directory tree and template files generated.
For an application region only the processed tree is created:
processed_data/my_corridor/
├── calibration/cache
├── figures/pi
├── network/{csv,shapefile}
├── spat
├── tables/{pi,spat_est}
├── trajectories/{raw_pts,points,trajectories/cache}
└── ui
Step 3: Obtain the processed data#
Copy the processed files of the region into the tree: network/traffic_network.pickle (and the
GeoJSON files), spat/spat.pickle and trajectories/trajectories/<date>_*.csv. Contact
henryliu@umich.edu for access to the processed data sets.
When the region of interest is a corridor spread over several processed regions or sub-regions,
copy_regions assembles it (see Command line tools of mtldp-meta-utils); the network then has to be rebuilt with
build_traffic_network.
Step 4: Load the region in Python#
from mtldp.utils.config import AppRegion
region = AppRegion('configs/my_corridor.json') # loads the signalized network and the SPaT
network = region.network # SignalizedNetwork
spat = region.spat # HistoryRegionSPaT
# trajectories of the configured dates and junctions, as objects ...
trajs_dict = region.load_trajs_dict(signalized=True)
# ... or as one table
trajs_df = region.load_trajs_df(date_str_list=['2025-03-03'], junction_id_list=['62590214'],
signalized=True)
print(network, spat, trajs_dict)
load_trajs_dict caches each day as a pickle in trajectories/trajectories/cache/ on the
first call, so that later runs start fast; pass overwrite_buffer=True after the trajectory
files have been re-processed. load_points=False skips the per-point lists when only the
indices are needed, and load_row_num loads a few rows for debugging.
From here the utilities of Utilities: mtldp.utils apply: mtldp.utils.filter to select
trajectories, mtldp.utils.aggregation to aggregate the indices, mtldp.utils.visualizer to
draw time-space diagrams with the signal timing, and the SPaT query methods of
Data structures: mtldp.meta to get the plan in effect for a movement and a period.