20 KiB
Impakt -- Project Status
Date: 2026-04-11
Version: 0.1.0
Tests: 240 passing (69.7% coverage)
Source: ~10,300 lines (py) | ~2,700 lines tests
Quality: 78.3/100 (Grade B) -- see docs/QA-*.md
Tooling: uv (Python 3.12.12), hatchling build backend, ruff, mypy strict
Quick Start
cd /Users/noise/Code/impakt
uv sync --dev # install all dependencies
uv run pytest tests/ # run all 240 tests (with coverage)
uv run impakt info tests/mme_data/3239 # show test metadata
uv run impakt serve tests/mme_data/3239 # launch web UI on :8050
Scripting:
from impakt import Session
s = Session.open("tests/mme_data/3239")
s.plot("11HEAD0000H3ACXP", "11HEAD0000H3ACYP", "11HEAD0000H3ACZP", cfc=1000)
Repository Layout
impakt/
pyproject.toml # PEP 621 + uv dependency-groups
uv.lock # lockfile
.gitignore
README.md # Architecture docs with 16 Mermaid diagrams
BRAINSTORM.md # 80+ feature ideas
docs/
STATUS.md # <-- you are here
src/impakt/
__init__.py # exports Session, Template
channel/ # Data model layer
code.py # ISO channel code parser (14-char + 16-char auto-detect)
model.py # Channel, ChannelGroup, TestData, TestMetadata
group.py # Auto-grouping utilities
lookup.py # ISO naming lookup tables (150+ entries)
io/ # I/O layer
reader.py # ReaderProtocol, ReaderRegistry
mme.py # MMEReader (real ISO 13499 + synthetic INI)
transform/ # Signal processing
base.py # Transform protocol, TransformChain
cfc.py # SAE J211 CFC filter (60/180/600/1000)
align.py # X-align (time-zero), Y-align (offset)
resultant.py # Vector magnitude from X/Y/Z
math_expr.py # Free-form math expressions
resample.py # Trim, Resample
criteria/ # Injury criteria
base.py # CriterionResult, InjuryCriterion protocol
hic.py # HIC15, HIC36
clip3ms.py # 3ms chest clip
nij.py # Nij (4 modes, per-dummy intercepts)
chest.py # Chest deflection, Viscous criterion
femur.py # Femur load
tibia.py # Tibia index
protocol/ # Rating protocols
base.py # ProtocolResult, BodyRegionScore, Color, Rating
euro_ncap.py # Euro NCAP (color/points/stars, versioned)
us_ncap.py # US NCAP (injury probability/stars)
iihs.py # IIHS (G/A/M/P)
plot/ # Visualization engine
engine.py # PlotEngine (Plotly), cursor_values()
spec.py # PlotSpec, ChannelRef, Corridor, CursorValues
cursor.py # Dual X-cursor logic
export.py # PNG/SVG/PDF/HTML export
template/ # Templates & sessions
model.py # TemplateSpec, SessionState (YAML serializable)
library.py # TemplateLibrary (~/.impakt/templates/)
session.py # SessionManager (.impakt/ per test)
report/ # Report generation
engine.py # PDF/HTML via WeasyPrint + Jinja2
templates/ # 3 Jinja2 HTML templates
plot_sheet.html
injury_summary.html
protocol_report.html
web/ # Dash web application
app.py # App factory: create_app(), serve()
state.py # AppState: multi-test state, templates, sessions, corridors
layout.py # Top-level layout: Data tab + Analysis tab
components/ # Reusable layout components
header.py # Navbar, test info panel, open/overlay modals
channel_grid.py # Flat sortable DataTable with wildcard filter + facets
channel_values.py # Combined cursor + statistics table (live hover values)
transforms.py # CFC/align/resultant controls + per-channel overrides
plot_grid.py # Multi-pane plot area (1x1, 2x1, 1x2, 2x2, 3x1)
criteria.py # Auto-compute criteria, protocol scoring, results display
corridors.py # Corridor upload (CSV) and management
templates.py # Template library browser, save/apply/delete
math_builder.py # Math expression builder with variable binding
report.py # Export panel (PNG/SVG/PDF, CSV, protocol report)
callbacks/ # Feature-specific callback modules
__init__.py # Registration hub: register_callbacks()
channel_callbacks.py # Selection, filtering, badges, per-channel overrides
plot_callbacks.py # Plot rendering, transform pipeline, corridor display
cursor_callbacks.py # Channel values table (live hover + X1/X2)
criteria_callbacks.py # Compute All button, protocol scoring
template_callbacks.py # Apply/save/delete templates, session auto-save
corridor_callbacks.py # CSV upload, corridor state management
math_callbacks.py # Expression evaluation, derived channel injection
file_callbacks.py # Open test / add overlay modals
export_callbacks.py # CSV export, report generation
assets/ # Browser-side static files
style.css # Custom CSS (compact layout, splitter, scrollbars)
splitter.js # Draggable panel splitter (pure JS, no deps)
cursor_tracker.js # Live cursor tracking (mousemove -> pixel-to-data-X)
plugin/ # Plugin system
registry.py # PluginRegistry, discovery (entrypoints + dir)
script/ # Scripting API + CLI
api.py # Session, ChannelHandle, TransformProxy, Template
cli.py # argparse CLI (serve/info/channels/evaluate)
tests/
conftest.py # Synthetic channel fixtures
test_integration.py # Full pipeline against synthetic MME fixture
test_real_mme.py # 46 tests against 5 real ISO 13499 datasets
test_channel/ # ChannelCode parser, Channel model, TestData
test_criteria/ # HIC, Nij
test_io/ # MMEReader
test_protocol/ # Euro NCAP scoring
test_transform/ # CFC filter, alignment
test_web/ # AppState, app creation, channel grid, channel values, P2 features
fixtures/
generate_mme.py # Synthetic MME generator (26 channels, half-sine)
sample_mme/ # Generated synthetic test data
mme_data/ # REAL ISO 13499 test data (5 datasets)
3239/ # NHTSA/Calspan, VW Passat frontal, 133 channels
AK3T02FO/ # BASt, frontal 40% offset, 97 channels
AK3T02SI/ # BASt, side impact, 97 channels
VW1FGS15/ # Volkswagen, pedestrian headform, 10 channels
98_7707/ # UTAC, vehicle-to-vehicle (metadata only)
*.pdf, *.doc # ISO/TS 13499 reference documents
What Works
All modules fully implemented and tested:
| Module | Status | Notes |
|---|---|---|
| Channel code parser | Complete | Auto-detects 14-char (no dummy) vs 16-char (with dummy H3/P3/PC). |
| Channel model | Complete | Immutable channels, auto-grouping X/Y/Z, resultant computation. |
| MME reader | Complete | Real ISO 13499 (.mme + .chn index + .NNN data files) + simplified INI. Tested against 5 real datasets. |
| CFC filtering | Complete | SAE J211 compliant. 4th-order Butterworth, zero-phase. All 4 CFC classes. |
| Alignment transforms | Complete | X-align (manual/threshold/trigger), Y-align (baseline window). |
| Resultant | Complete | From ChannelGroup or arbitrary channels. |
| Math expressions | Complete | Safe eval with numpy functions. |
| HIC | Complete | HIC15/HIC36, cumulative integration, optimal window search. |
| 3ms clip | Complete | Cumulative exceedance method. |
| Nij | Complete | 4 modes (NTE/NTF/NCE/NCF), per-dummy intercepts. |
| Chest deflection | Complete | Peak sternal displacement with unit/sanity validation. |
| Viscous criterion | Complete | V(t)*C(t) with chest depth per dummy type. |
| Femur load | Complete | Left/right, unit conversion. |
| Tibia index | Complete | M/Mc + F/Fc with intercepts. |
| Euro NCAP | Complete | Sliding-scale color/points, percentage to stars. Versioned thresholds. |
| US NCAP | Complete | Logistic injury risk functions, combined probability, star rating. |
| IIHS | Complete | G/A/M/P per body region, worst-case overall. |
| Plot engine | Complete | Plotly rendering, corridors, cursor values, export. |
| Template model | Complete | YAML serialize/deserialize, library manager, session persistence. |
| Report engine | Complete | HTML+WeasyPrint PDF, 3 Jinja2 templates. |
| Plugin registry | Complete | Entry point + directory + API discovery. |
| CLI | Complete | impakt serve/info/channels/evaluate. |
| Web UI | Functional | See details below. |
Web UI -- Current State
Fully functional for daily crash test analysis:
Data Tab:
- Left panel (resizable via draggable splitter): channel grid + transform controls
- Channel grid: flat sortable DataTable (#, ISO Code, Description, Unit, Min, Max), wildcard filter bar, facet dropdowns (body region, measurement, direction), multi-select with selection persisted across filtering, selected rows colored with plot trace colors (tinted background + left border)
- Transform controls: global CFC filter, Y-align, X-align (manual/threshold), resultant toggle, per-channel CFC overrides
- Plot area (fills remaining width): no legend (info in tables), tight margins, compact axis labels, X1/X2 vertical reference lines
- Channel Values table (directly below plot, minimal gap): combined statistics + cursor in one table. Columns: #, ISO Code, Description, Unit, Min, @Time, Max, @Time, X1, X2, Cursor.
table-layout: fixedwith percentage widths — Description fills remaining space. Rows colored with same plot trace colors. Cursor column updates live on mouse hover via custom JS tracker.
Analysis Tab:
- Injury Criteria: auto-detect channels by ISO naming, compute HIC15/3ms clip/Nij/chest defl/femur/tibia, protocol scoring (Euro NCAP/US NCAP/IIHS) with color-coded results and star ratings
- Math Expression Builder: formula input, 3 variable bindings (a/b/c mapped to channel dropdowns), result injected into test data and auto-plotted
- Template Management: library browser, apply (resolves channel patterns + sets CFC), save current view as template, delete, session auto-save
- Corridors: CSV upload (time/lower/upper), rendered as filled band on plot
- Export: CSV of plotted data (with transforms), PNG/SVG/PDF buttons, protocol report generation
Consistent Color System: Every selected channel has a stable color index (position in selection order). The same color appears in:
- Plot traces
- Channel grid rows (tinted background + solid left border)
- Selected badges (colored dot)
- Channel Values table rows (tinted background + solid left border)
Key design decisions:
- Immutable channels -- transforms return new Channel objects; raw data never modified.
.impakt/subfolder -- session state stored alongside test data.- Template/session split -- templates are global recipes; sessions are per-test instances.
- AppState is server-side -- numpy arrays stay in Python memory; Dash stores hold only lightweight keys.
- Channel keys use
test_id::channel_name-- enables multi-test overlay. - Custom JS cursor tracking -- bypasses Plotly's hover system with raw mousemove + pixel-to-data conversion.
- table-layout: fixed on Channel Values -- percentage widths respected, Description column fills remaining space.
- Browser cache prevention -- meta tags with Cache-Control: no-cache to prevent stale layout issues during development.
- Separate single-output callbacks for DataTable properties -- avoids Dash KeyError when DataTable internally requests individual properties.
Roadmap
Informed by competitive landscape survey (research/landscape.md). No open-source web-based tool covers this domain end-to-end. See BRAINSTORM.md for full feature ideas with priority tiers.
Priority 3 — Performance & Rendering
Goal: handle large datasets (500+ channels, 100kHz sample rates) without lag.
- plotly-resampler integration -- Drop-in
FigureResamplerwrapper for Plotly figures. Handles 110M+ points via LTTB downsampling. Works natively with Dash. Repo cloned atresearch/repos/plotly-resampler/. This is the single highest-impact performance improvement. - Synchronized zoom/pan -- When plotting multiple subplots, zoom/pan syncs across all panes sharing an X axis. Most-requested feature in crash test visualization. Implement via shared
xaxisconfig or callback-based range sync. - Lazy channel loading -- Load
.datfiles on first access, not atSession.open(). Load headers eagerly, data lazily. Keeps startup fast for tests with 500+ channels. - Channel sparklines -- Tiny inline sparklines in the channel grid sidebar. Engineers visually scan 100+ channels before selecting. A 60px-wide sparkline column is transformative for signal browsing.
Priority 4 — Data Format Expansion
Goal: read the world's crash test data, not just ISO MME.
- UDS reader plugin -- NHTSA's proprietary binary format. Required to access the largest public crash test database. The NHTSA-Tools Fortran source (
research/repos/NHTSA-Tools/) documents the UDS spec. - ASAM MDF reader plugin -- Standard for ECU/CAN bus measurement data. Many labs record vehicle bus data alongside crash instrumentation. asammdf (
research/repos/asammdf/) is a mature library — add as optional dependency. - Flexible CSV reader -- Column mapping, delimiter detection, header conventions. Engineers frequently receive data as CSV exports from other tools.
Priority 5 — Comparison & Reporting
Goal: make multi-test comparison and deliverable generation effortless.
- Quick comparison mode -- Two tests side-by-side with synchronized cursors. One-click "compare" button. Color-by-test with channel differentiation via line dash.
- Multi-page PDF reports -- Combine plots + injury summary + protocol rating into a single PDF with table of contents. Currently each report type is standalone.
- Excel export -- Criteria results and cursor values to .xlsx. Engineers live in spreadsheets.
- Static HTML export -- Bundle data + Plotly.js into a self-contained HTML file. Opens in any browser without a Python server. Learned from FalCon's CustomerView distribution model.
Priority 6 — Video & Advanced Analysis
Goal: close the biggest remaining gap vs. commercial tools.
- Video synchronization -- Link high-speed camera footage with channel data. Scrubbing video moves the time cursor; moving the cursor seeks the video. Every major commercial competitor (measX, DIAdem, Kistler, FalCon) has this. Foxglove and Rerun demonstrate web-native approaches.
- Frequency spectrum viewer -- FFT / PSD alongside time-domain plots. Diagnose noise, verify CFC filter behavior.
- Integration / differentiation transforms -- Acceleration -> velocity -> displacement with cumulative unit tracking.
- Data quality dashboard -- Automated polarity check, sensor sanity, missing channel detection, completeness scoring. No commercial competitor is strong here — opportunity to differentiate.
Priority 7 — Simulation Correlation & Ecosystem
Goal: bridge the gap between physical test and CAE simulation.
- LS-DYNA data import via lasso-python (
research/repos/lasso-python/). Enables test-vs-simulation overlay — a premium feature in Altair HyperGraph and Siemens Simcenter. - ISO/TS 18571 CORA correlation -- Quantitative rating of test-vs-simulation agreement. Standard metric for model validation.
- Additional injury criteria -- BrIC, DAMAGE, TTI, pedestrian criteria, OLC. Required for broader Euro NCAP coverage.
- Additional NCAP programs -- J-NCAP, C-NCAP, K-NCAP, ANCAP, Latin NCAP as protocol plugins.
- Jupyter integration --
_repr_html_on Session, Channel, ProtocolResult for rich notebook output.
Validation (ongoing)
- Cross-validate CFC filter against PyAvia's J211_2pole (
research/repos/pyavia/) and NHTSA-Tools' BwFilt. PyAvia's author notes that scipy's genericsosfiltfiltmay differ from the SAE J211 Appendix C digital Butterworth algorithm for CFC 60 and 180. - Cross-validate injury criteria against NHTSA-Tools Fortran reference implementations, pyisomme, and EPFL crash-tests-service-robots. Four independent codebases available in
research/repos/.
Test Data Available
| Dataset | Lab | Type | Channels | Good for testing |
|---|---|---|---|---|
fixtures/sample_mme/ |
Synthetic | Frontal barrier | 26 | Unit tests, known values |
mme_data/3239/ |
NHTSA/Calspan | Frontal barrier (VW Passat) | 133 | Full pipeline, real data |
mme_data/AK3T02FO/ |
BASt | Frontal 40% offset | 97 | Multi-occupant |
mme_data/AK3T02SI/ |
BASt | Side impact | 97 | Side impact protocols |
mme_data/VW1FGS15/ |
Volkswagen | Pedestrian headform | 10 | Impactor codes (D0) |
mme_data/98_7707/ |
UTAC | Vehicle-to-vehicle | 0 | Metadata-only |
Dependencies
Core: numpy, scipy, plotly, dash, dash-bootstrap-components, pandas, pyyaml, jinja2, weasyprint, pydantic Dev: pytest, pytest-cov, ruff, mypy Optional: nptdms (TDMS reader plugin) Planned: plotly-resampler (P3), asammdf (P4), openpyxl (P5), lasso-python (P7)
Known Issues / Technical Debt
- VehicleInfo.year parsed as 0 for real MME data (.mme format embeds year in vehicle name string).
- Speed displayed as raw float (55.900001530350906 km/h) -- should round.
- DataTable deprecation warning -- Dash recommends migrating to dash-ag-grid.
- Cursor poll interval (80ms) -- slight latency in cursor grid updates.
- Chest deflection auto-detect skips DS channels with peak > 150mm to avoid steering column displacement.
- CFC filter implementation uses scipy
sosfiltfiltwhich may diverge from SAE J211 Appendix C for CFC 60/180. Needs cross-validation against PyAvia and NHTSA-Tools reference implementations.
Quality Assurance
Automated QA scoring is configured:
- Scoring agent:
.claude/agents/quality-scorer.md-- collects metrics, applies rubrics, writes report - Improvement agent:
.claude/agents/qa-improver.md-- reads QA report, auto-fixes mechanical issues - Methodology:
docs/QA-INSTRUCTIONS.md-- reproducible 8-dimension rubric - Reports:
docs/QA-*.md-- timestamped scorecards with deltas - Scripts:
scripts/qa-score.sh(score only),scripts/qa-improve.sh(score -> fix -> re-score)
Competitive Landscape
Full survey at research/landscape.md with 11 cloned open-source repos in research/repos/.
Key finding: No existing tool combines open-source + web-based + ISO-MME + CFC + injury criteria + protocol scoring + templates + reports. Commercial tools (measX X-Crash, NI DIAdem, Kistler) do this but are expensive and Windows-only. Impakt occupies a genuinely unserved niche.
Most actionable libraries:
- plotly-resampler (performance) --
research/repos/plotly-resampler/ - asammdf (MDF format) --
research/repos/asammdf/ - lasso-python (LS-DYNA) --
research/repos/lasso-python/ - PyAvia, NHTSA-Tools (validation) --
research/repos/pyavia/,research/repos/NHTSA-Tools/