Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

TAPLite4MPO — open C++ static traffic assignment for MPOs

build-and-test License: MIT

Pre-release channel: this branch is packaged on PyPI as taplite4mpo-pre-release and currently reports version 0.4.0rc1. It keeps the public Python import taplite4mpo, so install it in a clean environment and do not install it alongside the stable taplite4mpo distribution.

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).

TAPLite4MPO at a glance — the Golden Path (collect → GMNS → declare → run → validate → advanced), the three gates (can I run / trust / improve), why a shapefile is not yet a model, the dataset ladder (Sketch → Regional → ARC Atlanta → OSM), super-zone compression (~2× faster), and recovering the original-resolution zone-to-zone skim (R²=0.99).

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. The dtalite_qa Python 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_type 0–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; check and all --quick are the seconds/minutes-sized versions) — or open the one-click notebook examples/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

ARC Superzone self-demo — assigned AM volumes on the recognizable Atlanta freeway network, 6,031 zones superzoned to 151

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-style run_iteration, live mid-solve control, external load_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).

  • taplite CLI (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 taplite script is not on your PATH (e.g. a --user install), run it as python -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 only pip install --pre taplite4mpo-pre-release, point taplite run at your own scenario + config and set assignment.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 fills submission.yml (the README for the data; ARC's is in examples/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 (see python -m dtalite_qa -h).
  • pytaplite/ — Python interface that drives the C++ kernel: pytaplite.assign(scenario) → runs DTALite.exe, returns link_performance (subprocess, or the in-process _native binding from kernel/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)

Source distribution for taplite4mpo-pre-release 0.4.0rc1
File Size Uploaded
taplite4mpo_pre_release-0.4.0rc1.tar.gz 4.7 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for taplite4mpo-pre-release 0.4.0rc1
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.4.0rc1 This release

3 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page