CITA Traffic Platform / Documentation
Reproducing the Evaluation
Choose a public aggregate check, corrected-CSV reproduction, or archived-database workflow.
Jump to a section
A. Check the public aggregate
Download the A3 JSON and the verification helper into an empty folder. Python 3 is enough; no packages, source checkout, dump, or university account are needed.
python3 verify-a3.py a3-hourly.jsonExpected: PASS for 48 ordered points. Weekday 08:00: 68.3 km/h (n=4600); weekend 08:00: 101.2 km/h (n=1706). Weekend 14:00: 91.9 km/h. The helper checks the window, units, shape, and declared corrected-CSV hash.
This checks published structure and reference assertions. Without the CSV it cannot independently verify that hash or recompute means. The JSON cannot establish raw measurement completeness, collection success rates, or the seven load windows: it lacks flow, occupancy, date-level observations, and fetch logs.
B. Rebuild every point from the corrected CSV
Download the exporter beside the CSV, public JSON, and verification helper.
python3 - <<'PY'
from pathlib import Path
import hashlib
expected = 'c81c7dbeb5a8a0cedad6a2be9f9ba4ebc10b76df853a11af6dc00a116e683f9c'
assert hashlib.sha256(Path('evaluation_hourly_profile.csv').read_bytes()).hexdigest() == expected
print('PASS: corrected figure input hash')
PY
python3 export-a3.py evaluation_hourly_profile.csv --output reproduced-a3.json
python3 verify-a3.py a3-hourly.json --compare reproduced-a3.jsonExpected: Hash matches; exporter writes 48 points; all speeds and observation counts match the public export. This entire 48-point comparison was verified locally.
Select A3 / outboundFromTown. For each local hour combine ISO weekdays 1–5 and 6–7 separately, using sum(mean_speed × observations) / sum(observations). Round only the final mean to one decimal, decimal half-up. Source SQL retains positive speed, flow, and occupancy.
The older evaluation_hourly_profile_2026-09-03.csv differs in five Thursday evening buckets. Do not substitute it for the corrected input. The original generate_corrected_evaluation_figures.py has hardcoded workspace paths; its weighted_profile and save_weekday_weekend functions document the method, but it is not a portable unmodified CLI. This exporter accepts explicit paths.
C. Restore the archived database
Use the fresh .env from Quickstart and a new Compose project. Restore replaces objects in that review database; do not target a working collection installation. Keep the collector stopped.
export COMPOSE_PROJECT_NAME=cita-evaluation-review
docker compose up -d --wait postgres
docker compose stop collector
docker compose cp cita_prod_2026-09-03.dump postgres:/tmp/cita-evaluation.dump
docker compose exec -T postgres pg_restore \
--clean --if-exists --no-owner --no-privileges \
-U cita -d cita /tmp/cita-evaluation.dump
docker compose exec -T postgres psql -U cita -d cita -c "
SET TIME ZONE 'Europe/Luxembourg';
SELECT min(measurement_time),max(measurement_time),count(*) FROM measurements;"Expected: The supplied README reports 2026-07-23 16:23:00+02 through 2026-09-03 19:13:00+02, with 2,802,792 measurements. Different bounds/counts mean a different data state. The restore is source-reviewed, not locally reverified against the unavailable dump.
D. Export and compare the database profile
Requires C’s archived database. Download the hourly-profile SQL, the exporter, the verifier, and the public JSON beside compose.yaml. Keep COMPOSE_PROJECT_NAME=cita-evaluation-review from step C in this terminal. It adapts load_rush_hour_profile to the fixed thesis cutoff.
docker compose exec -T postgres psql -X -q -v ON_ERROR_STOP=1 \
-U cita -d cita < evaluation-hourly.sql > database-hourly.csv
python3 export-a3.py database-hourly.csv --output database-a3.json
python3 verify-a3.py a3-hourly.json --compare database-a3.jsonExpected: The archived profile is expected to have 2,352 groups, including 168 selected A3 rows, and the same 48 aggregate points. CSV bytes/hashes can differ with formatting/order: compare values and investigate differences against the corrected figure input. Only the SQL execution path was smoke-tested on the isolated fixture database, not these full-dump outputs.
To run the application’s load-window rule on the same archived period:
docker compose run --rm -T collector python - <<'PY'
from datetime import datetime
from database.db import load_rush_hour_profile
from traffic.rush_hour import detect_rush_hours_from_profile
profile = load_rush_hour_profile(
datetime.fromisoformat('2026-07-23T16:23:00+02:00'),
datetime.fromisoformat('2026-09-03T19:13:00+02:00'),
directions=['inboundTowardsTown', 'outboundFromTown'],
)
windows = detect_rush_hours_from_profile(profile)
print(windows)
print('windows:', windows.height)
PYExpected: The thesis reports seven multi-hour windows, all A3, under default thresholds. This requires the archive and was not locally reproduced. End hours are exclusive; these are uncalibrated project rules, not official CITA classifications.
The dump does not include the raw XML volume. Reprocessing or checking raw bytes additionally requires that archive. The public JSON and hourly CSV cannot replace it.
Source files
Paths identify the relevant files and symbols in the inspected source distribution; they are not links to an assumed public repository. See access requirements.
README.md- Dump name, access, size, reported bounds/counts
database/db.py- load_rush_hour_profile
traffic/rush_hour.py- detect_rush_hours_from_profile
config/settings.py- 8 observations, 3 dates, 2 hours, 75/900/10 thresholds
Figures: generate_corrected_evaluation_figures.py- weighted_profile / save_weekday_weekend
Portfolio: scripts/export-traffic.py / scripts/verify-a3.py- Public reproduction helpers
Portfolio: public/data/cita/evaluation-hourly.sql- Fixed-window database export