This release is a pre-release and may not be stable for production use.
TAPLite4MPO — open C++ static traffic assignment for MPOs
Pre-release channel: this branch is packaged on PyPI as
taplite4mpo-pre-releaseand currently reports version0.4.0rc1. It keeps the public Python importtaplite4mpo, so install it in a clean environment and do not install it alongside the stabletaplite4mpodistribution.
New here? One entry: open notebooks/03_arc_atlanta_end_to_end.ipynb — it walks you into the flagship ARC Atlanta reproduction (validated, %RMSE 22 %). Prefer text? The same one page is START_HERE.md.
A single-file, reproducible C++ (CMake) static user-equilibrium traffic-assignment kernel (Frank–Wolfe) for GMNS networks — with the VDF library, generalized cost, peak-load-factor, and solver options that MPO/DOT static highway assignments need — plus a Python QA/automation package, open benchmark networks, and a two-volume user guide. Built for teaching and for reproducing agency assignments (ARC, SERPM, TRPA, MTC, SANDAG, MWCOG, VDOT, ODOT).
The whole pipeline at a glance. Start with docs/GOLDEN_PATH_CHECKLIST.md. (Figure generated from
docs/IMAGE_PROMPTS.md.)
⚙️ Which part solves the assignment?
The C++ kernel (
bin/DTALite.exe,kernel/src/TAPLite.cpp) is the solver — Frank–Wolfe equilibrium, the VDF library, OpenMP, the scale. Thedtalite_qaPython package is QA/orchestration only: it validates inputs, builds scenarios, and invokes the kernel — it does not compute the assignment. So you must build the kernel (bash build.sh); running only Python assigns nothing. This is not a pure-Python solver. Full explanation, environment matrix, and how to call the kernel from Python: docs/ARCHITECTURE.md.
Features
- Frank–Wolfe with an exact cost-based line search; conjugate / bi-conjugate FW
(
assignment_method) for faster convergence on congested networks. - VDF library: BPR, modified-BPR (linear term), conical (Spiess), QVDF (queue),
BPR2, INRETS, Akcelik, SANDAG signal-delay, SCAG piecewise-BPR, SCAG ramp-meter
(
vdf_type0–8). - QVDF congestion duration — a D/C-consistent queue output (
P, severe-congestion duration, queue speeds), calibrated from corridor speeds by the CBI sister project. - Multiclass: per-mode demand, VOT, PCE, occupancy, per-mode toll + distance
operating cost (generalized cost),
allowed_use(HOV/truck/managed lanes). - Peak-Load-Factor / period-capacity convention (
vdf_plf = φ/L). - Relative-gap stop (N consecutive iters), binary demand fast-load, OpenMP parallel.
Start with the flagship example →
examples/arc_atlanta/: a complete end-to-end MPO run — reproduce the Atlanta Regional Commission's AM highway assignment and validate it against ARC's own count benchmark (region %RMSE 22 %, target ~38 %; re-baselined 2026-07 from 23 % after the Dijkstra-default and gap-metric kernel updates). It shows every MPO feature wired up, with a clean ARC-requirement → kernel-setting mapping. Background:docs/mpo_spec/(the design spec
- multi-agency survey).
One front door runs all of it:
cd examples/arc_atlanta && python arc_pipeline.py all --full(auto-detects raw-ARC vs in-repo data, verifies the encoded calibration, builds the kernel if needed, live-streams the run, ends with a PASS/FAIL summary;checkandall --quickare the seconds/minutes-sized versions) — or open the one-click notebookexamples/arc_atlanta/ARC_END_TO_END.ipynb.
Self-demonstrating installation
Verify that the installed package, bundled public data, native assignment kernel, validation gate, reporting pipeline, and regression baseline all work:
pip install --pre taplite4mpo-pre-release
taplite self-demo
$ taplite self-demo --case arc-superzone
[PASS] bundled data -- 9 files from the installed package
[PASS] intake gate -- GATE: READY (0 blockers)
[PASS] crosswalk -- 6031 zones -> 151 superzones (39.94x), sha256-pinned
[PASS] demand conservation -- 3,398,701 == 2,275,731 loaded + 1,122,970 intrazonal (audited)
[PASS] superzone connectivity-- all 151 superzones connected both directions
[PASS] native assignment -- C++ kernel rc=0 (deterministic FW, 1 processor)
[PASS] output checks -- 145,969 rows finite and physical
[PASS] corridor extraction -- I-285=26,489; I-85=26,806; I-75=22,868; GA-400=18,918; I-20=15,064
[PASS] golden regression -- VMT/VHT/volumes at rel 0.00e+00 vs the reviewed baseline
TAPLite4MPO self-demo: PASS
Full walkthrough, artifact tree, and guarantees: docs/SELF_DEMO.md.
The command copies the bundled Chicago Sketch scenario to a writable run
folder, validates its model declarations through the no-guessing intake gate,
executes the native TAPLite kernel (deterministic Frank-Wolfe, one processor),
generates an HTML dashboard, and compares VMT, VHT, convergence, and link
volumes with the reviewed golden baseline. A successful run exits with code 0;
numerical or packaging drift exits nonzero — the same check gates every
release. Variants: taplite self-demo --quick (Sioux Falls kernel smoke),
--output my_demo, --json. The baseline is never rewritten by a normal run
(--record-baseline is an explicit maintainer action).
Optional visualization: pip install gui4gmns (the same *4gmns family) and every
self-demo / pipeline run additionally produces an interactive network dashboard
(network_dashboard.html: pan/zoom map with an OSM basemap on lon/lat networks,
volume-tiered links, OD desire lines, and QC layers). Also available per run as
pytaplite.assign(...).dashboard(). Purely additive — nothing requires it.
Two complementary cases:
| Case | Command | Purpose |
|---|---|---|
| Chicago Sketch (default) | taplite self-demo |
fast deterministic kernel + packaging regression — every PR and release |
| ARC Superzone | taplite self-demo --case arc-superzone (alias taplite demo arc-superzone) |
MPO-scale workflow demonstration: 6,031 ARC zones superzoned to 151 (demand conserved, intrazonal audited), the full recognizable regional freeway network, corridor checks on I-75/I-85/I-20/I-285/GA-400, a superzone map in the dashboard — scheduled CI and user validation (~1–3 min) |
1. Build the kernel (the solver — required)
bin/DTALite.exe is the C++ engine that actually runs the assignment; the Python tools just
drive it. Build it first:
bash build.sh # -> bin/DTALite.exe (CMake + g++/MinGW, OpenMP, Release)
Requires CMake, a C++17 compiler (g++/clang/MSVC), and OpenMP. Output: bin/DTALite.exe.
(See docs/ARCHITECTURE.md for why this is mandatory.)
Install the Python packages
pip install . # installs dtalite_qa + pytaplite; compiles the in-process kernel binding
This builds pytaplite._native from the bundled kernel source (falls back to subprocess if no
compiler). Multi-platform PyPI wheels (pip install --pre taplite4mpo-pre-release) are produced by cibuildwheel
on a version tag — see RELEASE.md.
Then call the kernel from Python:
import pytaplite
r = pytaplite.assign("kernel/data_sets/02_Sioux_Falls") # runs the C++ kernel
print(r.summary()) # links, VMT, VHT, returncode
Runnable demo: examples/pytaplite_quickstart.py
(python examples/pytaplite_quickstart.py).
The two front doors for a QA-gated run
Installing the package also gives you two ways to drive a gated, manifested run (both go through the no-guessing intake gate and write a reproducibility manifest — neither can bypass the gate):
-
Python API (developer):
from dtalite_qa.api import Network, Scenario, AssignmentEngine net = Network.read_gmns("kernel/data_sets/03_chicago_sketch") res = AssignmentEngine().run(Scenario(net, settings={"iterations": 20}), exe="bin/DTALite.exe") print(res.moe())
-
TAPCI (preview) — a stable, tiered "build-on-top" surface for GMNS assignment, so tools and AI workflows call the kernel instead of forking it.
TAPCI.categories()returns the three tiers:from taplite4mpo import TAPCI sim = TAPCI.open("project.yml", exe="bin/DTALite.exe") sim.set_time_period(7, 9).set_setting(route_output=1, column_output=2) sim.run_until_converged(max_iter=50, gap=0.001) sim.observe_links(["volume", "speed", "vc"]) # + observe_od / observe_system sim.query_paths(o_zone=12, d_zone=87) # Path4GMNS-style external query sim.save_routing_policy("policy.dtac") # the theta-share routing policy # ...later: reuse that policy on new demand and execute in ~1 iteration TAPCI.open("project.yml", exe="...").load_routing_policy("policy.dtac").run_until_converged()
Category 1 (core run/observe/export) and Category 2 — the one-period environment: time period, OD/system/path performance, OD skims for a Choice-Graph/ABM caller (
observe_skims/query_skim), save & reload the routing policy, and next-run scenario edits (set_link_closure/set_link_capacity/set_toll/set_od_multiplier, applied to a working copy — the source network is never touched) — are real and backed by the audited API + kernel. There's also an offline day-to-day / information-provision loop (run_day_to_day, driven by an external policy function) and an assignment-based RL environment (dtalite_qa.tapci_env.TAPCIEnv,reset/step;reward=accepts a MOE shortcut string, a KPI-weighted objective dict e.g.{"vht_hours": -1.0, "co2_proxy_kg": -1e-4}, or a callable). A separate, kernel-independent KPI4MPO/NPO layer (dtalite_qa.kpi) turns any run into decision KPIs (VMT, VHT, delay, speed, max V/C, OD-skim time, + CO2/person-delay proxies), KPI deltas, and a weighted objective/reward. Category 3 (step-stylerun_iteration, live mid-solve control, externalload_paths,run_day_to_day/ information provision) raises a clear roadmap error rather than faking a no-op. Auto-tested in CI (.github/workflows/tapci-ci.yml: a no-kernel contract job + a kernel-loop job). -
tapliteCLI (analyst) — installed as a console script; four verbs:taplite validate <scenario> # intake gate + schema/accessibility taplite run configs/chicago_sketch_baseline.yml # gate -> kernel -> manifest -> report taplite report <run_dir> # fused self-contained HTML report taplite compare <run_a> <run_b> # manifest diff + side-by-side MOE
If the
taplitescript is not on your PATH (e.g. a--userinstall), run it aspython -m dtalite_qa.taplite_cli <verb> ....pip users: the examples above assume a repo clone —
configs/, the sample networks, and the kernel exe (bash build.sh->bin/DTALite.exe) live in the repo, not in the wheel. With onlypip install --pre taplite4mpo-pre-release, pointtaplite runat your own scenario + config and setassignment.exe(or--exe) to your kernel build.
2. Reproduce a run (open benchmark networks — no extra data needed)
cd kernel/data_sets/02_Sioux_Falls # or 03_chicago_sketch, 04_chicago_regional
cp ../../../bin/DTALite.exe .
./DTALite.exe # reads node/link/demand/settings, writes link_performance.csv
Or via the Python QA wrapper (validates inputs first, then runs):
pip install -e .
python -m dtalite_qa run kernel/data_sets/02_Sioux_Falls --exe bin/DTALite.exe
3. Regression / self-test
python test_networks/run_regression.py # builds & checks BPR/conic/QVDF, multimodal, turn restrictions
4. Documentation
- HANDOFF/ — ⭐ new engineer? start here. The onboarding & handoff folder: the ordered reading path, the runs to reproduce, the "which agency taught us this" issue index, a BPR/VDF/PLF config-rules card, and a hands-on lab that trips each classic conversion error on the open networks so you learn to recognize it.
- docs/CONVERSION_ERRORS_CATALOG.md — the lessons-learned / error-source reference: every way an MPO hand-off goes wrong (capacity, PLF, units, demand, zones, VDF, truncation, allowed-use, count basis, build), symptom → cause → fix → which agency.
- docs/ARCHITECTURE.md — the C++ kernel solves; the Python package orchestrates. Which part runs what, the environment matrix, and how to call the kernel from Python. Read it if you're unsure what's doing the assignment.
- docs/GOLDEN_PATH_CHECKLIST.md — ⭐ READ THIS FIRST. The Golden Path: from agency files to a trusted assignment, in 6 stages, framed by three questions — can I run? can I trust it? can I improve it? Simple first, advanced later.
- docs/DATASET_LADDER.md — which example to start with (Chicago Sketch → Chicago Regional → ARC Atlanta → OSM quick start).
- docs/onboarding_guide.html — the visual onboarding guide:
open in a browser for the staged journey (GIS field-map → declare → convert → intake →
quality → run → traceable workflow), each with its gate and a progress tracker. Generate
it anytime with
python -m dtalite_qa guide. - docs/MPO_ONBOARDING_GUIDE.md — start here for a new
agency model. The process to turn a raw hand-off (shapefile + matrix + "alpha/beta")
into a trustworthy run: declare → convert → intake audit → resolve → validate. The
intake (
dtalite_qa intake) never guesses a convention — it blocks on anything the MPO didn't declare (capacity basis/period, PLF, units, trip kind) and produces an issue report + conversion log + a guided HTML dashboard. The MPO fillssubmission.yml(the README for the data; ARC's is inexamples/arc_atlanta/gmns/). - USER_GUIDE.md — Volume 1: kernel reference (input schema, settings, VDFs, outputs).
- USER_GUIDE_VOL2_MPO.md — Volume 2: static highway assignment for MPOs (period capacity / PLF, generalized cost, convergence/solver, validation, per-agency recipes).
examples/arc_atlanta/— complete worked MPO example (ARC AM assignment, calibrate → run → validate vs the agency benchmark) with the ARC→kernel mapping.docs/mpo_spec/— design spec + multi-agency survey/conformance (ARC, SERPM, TRPA, MTC, SANDAG, MWCOG, VDOT, ODOT): requirement → kernel feature → how to verify.docs/qvdf_congestion_duration.md— QVDF as the D/C-consistent congestion-duration output, and the CBI sister-project pipeline (corridor speeds → QVDF params → kernel).docs/— methodology notes (peak load factor, super-zone aggregation, 4-step integration, OD-compression operators).docs/IMAGE_PROMPTS.md— copy-paste prompts for GPT image tools to generate the easy-to-follow figures (Golden Path, the 3 gates, super-zones, the skim advantage)..claude/skills/taplite4mpo-pipeline/— a Claude Code skill encoding the whole pipeline (gates, stages, conventions, the ARC loop) for agent-assisted work in this repo.dtalite_qa/— Python package:guide,intake,workflow,validate,fill,inventory,accessibility,report,demand-bin,plf,adapt,run(seepython -m dtalite_qa -h).pytaplite/— Python interface that drives the C++ kernel:pytaplite.assign(scenario)→ runsDTALite.exe, returnslink_performance(subprocess, or the in-process_nativebinding fromkernel/python/if built).
5. Folder map
TAPLite4MPO/
├── kernel/ C++ kernel (src/TAPLite.cpp, CMakeLists.txt) + open data_sets/
├── examples/
│ └── arc_atlanta/ complete end-to-end MPO example (ARC AM, validated)
├── dtalite_qa/ Python QA / control package
├── test_networks/ open test/benchmark networks + regression harness
├── schemas/ GMNS field schema (JSON)
├── docs/ methodology docs
│ └── mpo_spec/ design spec + multi-agency survey & conformance mapping
├── nvta_run/ NVTA run-configs + helper scripts (bring-your-own-data, §6)
├── USER_GUIDE.md Volume 1 (kernel)
├── USER_GUIDE_VOL2_MPO.md Volume 2 (MPOs)
└── build.sh
6. NVTA reproduction (bring-your-own-data)
The NVTA dataset is agency-restricted and is NOT included in this repository.
nvta_run/ ships the run-configs and helper scripts (network prep, settings, conic/QVDF
staging). To run it, point the scripts at your own copy of the data:
# option A: environment variable
export DTALITE_NVTA_INTERNAL=/path/to/nvta/_internal
# option B: nvta_run/local_config.json -> {"internal": "...", "subarea": "..."}
# option C: place the data in data/nvta_internal/
python nvta_run/run_nvta.py
If unconfigured, the runner prints a clear message. All of §2–§3 reproduces fully without it using the open benchmark networks.
Course note: instructors distribute the NVTA data to students through a separate channel (not this public repo); students set one of the options above.
Continuous integration
.github/workflows/ci.yml builds the kernel (CMake + MSVC on windows-latest) and runs
the full regression suite on every push / pull request.
License & citation
MIT — see LICENSE. If you use this kernel in research or coursework, please cite the
DTALite / TAPLite project. (Some docs/ notes reference internal companion files that are
not part of this public release.)
Metadata
Release files for taplite4mpo-pre-release 0.4.0rc1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| taplite4mpo_pre_release-0.4.0rc1.tar.gz | 4.7 MB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| taplite4mpo_pre_release-0.4.0rc1-cp311-cp311-win_amd64.whl | CPython 3.11 | CPython 3.11 | Windows x86-64 | Details |
| taplite4mpo_pre_release-0.4.0rc1-cp39-cp39-win_amd64.whl | CPython 3.9 | CPython 3.9 | Windows x86-64 | Details |
Total release size: 14.6 MB
Release files / taplite4mpo_pre_release-0.4.0rc1.tar.gz
| Download URL | taplite4mpo_pre_release-0.4.0rc1.tar.gz |
|---|---|
| Size | 4.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b6748331a7d1ca605935bbdc00570a709b72a66e8d21fc6899124e663a4d9039
|
|
BLAKE2b-256 checksum How to use checksums |
d253169b9c9daa9a8ba8974917ae52dde674ada3fee31a8fb0d4c07efa81ef98
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.12
|
Release files / taplite4mpo_pre_release-0.4.0rc1-cp311-cp311-win_amd64.whl
| Download URL | taplite4mpo_pre_release-0.4.0rc1-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 4.9 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
4ed012d7db6446d13bda7345523061693f540ba17087968a61bffc112faafc09
|
|
BLAKE2b-256 checksum How to use checksums |
b463badc646f250245cf18b7401fc6ed9d3c898d6fb541908861883a3eaef9e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.12
|
Release files / taplite4mpo_pre_release-0.4.0rc1-cp39-cp39-win_amd64.whl
| Download URL | taplite4mpo_pre_release-0.4.0rc1-cp39-cp39-win_amd64.whl |
|---|---|
| Size | 4.9 MB |
| Tags | CPython 3.9 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
2b17a7f4e81e8308cab770588ee0aaa7e5e2f02492d6ca3048e1a3612c78b298
|
|
BLAKE2b-256 checksum How to use checksums |
e06463f025c4556209e5530412db6e069f9ea6908ad26634ea95db0eb203ce6b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.12
|