227 lines
11 KiB
Markdown
227 lines
11 KiB
Markdown
# Impakt -- Project Status
|
|
|
|
**Date:** 2026-04-11
|
|
**Version:** 0.1.0
|
|
**Tests:** 258 passing (70.4% coverage)
|
|
**Quality:** 83.7/100 (Grade B+) -- see `docs/QA-*.md`
|
|
**Tooling:** uv (Python 3.12.12), hatchling build backend, ruff, mypy strict
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
cd /Users/noise/Code/impakt
|
|
uv sync --dev # install all dependencies
|
|
uv run pytest tests/ # run all 258 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:
|
|
```python
|
|
from impakt import Session
|
|
s = Session.open("tests/mme_data/3239")
|
|
result = s.evaluate("euro_ncap")
|
|
print(result.summary())
|
|
```
|
|
|
|
---
|
|
|
|
## Repository Layout
|
|
|
|
```
|
|
impakt/
|
|
pyproject.toml # PEP 621 + uv dependency-groups
|
|
uv.lock # lockfile
|
|
.gitignore
|
|
README.md # Architecture docs with Mermaid diagrams
|
|
BRAINSTORM.md # 80+ feature ideas
|
|
docs/
|
|
STATUS.md # <-- you are here
|
|
QA-*.md # Quality assessment scorecards
|
|
research/
|
|
landscape.md # Competitive landscape (15+ tools)
|
|
src/impakt/
|
|
__init__.py # exports Session, Template
|
|
config/ # Layered YAML configuration
|
|
__init__.py # exports Config
|
|
model.py # Config class, typed sections, deep merge, save/load
|
|
defaults/ # Package-level defaults (shipped with install)
|
|
config.yaml # All configurable fields, commented
|
|
protocols/ # Euro NCAP + IIHS threshold YAMLs
|
|
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 + simplified INI)
|
|
tdms.py # TDMSReader (stub)
|
|
csv.py # CSVReader (stub)
|
|
transform/ # Signal processing
|
|
base.py # Transform protocol, TransformChain (serializable)
|
|
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 (safe eval)
|
|
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 (YAML thresholds)
|
|
base.py # ProtocolResult, BodyRegionScore, Color, Rating
|
|
euro_ncap.py # Euro NCAP (loads thresholds from YAML, fallback to Python)
|
|
us_ncap.py # US NCAP (logistic injury risk)
|
|
iihs.py # IIHS (loads thresholds from YAML)
|
|
thresholds/ # Versioned YAML threshold files
|
|
plot/ # Visualization engine (single rendering path)
|
|
engine.py # PlotEngine: render(PlotSpec), resample, focus
|
|
spec.py # PlotSpec, ChannelRef, Corridor, focus_index
|
|
cursor.py # Cursor value computation
|
|
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 report templates
|
|
web/ # Dash web application
|
|
app.py # App factory: create_app(), serve()
|
|
state.py # AppState: holds Sessions, Config, resampler state
|
|
layout.py # Two-tab layout: Data + Analysis
|
|
components/ # 10 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 statistics + cursor table
|
|
transforms.py # CFC/align/resultant + per-channel overrides
|
|
plot_grid.py # Multi-pane plot area (1x1 through 3x1)
|
|
criteria.py # Auto-compute criteria, protocol scoring 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 (CSV, PNG/SVG/PDF, protocol report)
|
|
callbacks/ # 9 feature-specific callback modules
|
|
channel_callbacks.py # Selection, filtering, badges, per-channel overrides
|
|
plot_callbacks.py # PlotSpec construction → PlotEngine rendering
|
|
cursor_callbacks.py # Channel values table (live hover + X1/X2)
|
|
criteria_callbacks.py # Session.compute_criteria() + Session.evaluate()
|
|
template_callbacks.py # Apply/save/delete templates, session auto-save
|
|
corridor_callbacks.py # CSV upload, corridor state
|
|
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
|
|
splitter.js # Draggable panel splitter
|
|
cursor_tracker.js # Live cursor tracking (mousemove → data coords)
|
|
channel_nav.js # Keyboard navigation for channel grid
|
|
plugin/ # Plugin system
|
|
registry.py # PluginRegistry, discovery, reader forwarding
|
|
script/ # Scripting API + CLI
|
|
api.py # Session (with Config), ChannelHandle, TransformProxy, Template
|
|
cli.py # argparse CLI (serve/info/channels/evaluate)
|
|
tests/
|
|
conftest.py # Synthetic channel fixtures
|
|
test_config.py # Config layered resolution, save/load, round-trip
|
|
test_integration.py # Full pipeline against synthetic fixture
|
|
test_real_mme.py # 46 tests against 5 real ISO 13499 datasets
|
|
test_scripting_api.py # Session, fluent chaining, compute_criteria, evaluate
|
|
test_template.py # Template YAML round-trip, library CRUD, session manager
|
|
test_channel/ # ChannelCode parser, Channel model
|
|
test_criteria/ # HIC, Nij, chest/femur/tibia/clip3ms/viscous
|
|
test_io/ # MMEReader
|
|
test_plot/ # PlotEngine rendering (channels, corridors, focus, compact)
|
|
test_protocol/ # Euro NCAP, US NCAP, IIHS scoring
|
|
test_transform/ # CFC, alignment, math expressions, resultant, trim, resample
|
|
test_web/ # AppState, app creation, channel grid, channel values, P2 features
|
|
fixtures/
|
|
generate_mme.py # Synthetic MME generator (26 channels)
|
|
sample_mme/ # Generated fixture 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)
|
|
```
|
|
|
|
---
|
|
|
|
## What's Implemented
|
|
|
|
| Module | Status |
|
|
|---|---|
|
|
| Channel code parser | Complete — 14/16-char auto-detect, 150+ ISO codes |
|
|
| MME reader | Complete — real ISO 13499 + simplified INI, 5 real datasets |
|
|
| CFC filtering | Complete — SAE J211, all 4 classes |
|
|
| Alignment | Complete — X-align (manual/threshold/trigger), Y-align |
|
|
| Resultant | Complete — from groups or arbitrary channels |
|
|
| Math expressions | Complete — safe eval with numpy |
|
|
| HIC, 3ms clip, Nij, chest, femur, tibia, viscous | All complete |
|
|
| Euro NCAP, US NCAP, IIHS | Complete — YAML thresholds, versioned |
|
|
| PlotEngine | Complete — single rendering path, resampler, focus, corridors |
|
|
| Templates | Complete — YAML, library, save/apply/delete |
|
|
| Sessions | Complete — `.impakt/` persistence, auto-save |
|
|
| Configuration | Complete — 3-layer YAML, typed sections, save/load |
|
|
| Plugin system | Complete — entry points, directory, API discovery, reader forwarding |
|
|
| CLI | Complete — serve/info/channels/evaluate |
|
|
| Web UI | Functional — two tabs, channel grid, cursor tracking, criteria, templates, export |
|
|
|
|
---
|
|
|
|
## Key Design Decisions
|
|
|
|
1. **Immutable channels** — transforms return new Channel objects
|
|
2. **`.impakt/` subfolder** — session state + config alongside test data
|
|
3. **3-layer config** — package defaults → user → session (YAML)
|
|
4. **AppState holds Sessions** — web UI routes through the scripting API
|
|
5. **PlotEngine is the single rendering path** — both scripts and web build PlotSpec
|
|
6. **TransformChain used in web layer** — serializable, reproducible pipelines
|
|
7. **Custom JS cursor tracking** — mousemove + Plotly axis p2d for full-area coverage
|
|
8. **Protocol thresholds in YAML** — user-editable, copied to session on save
|
|
9. **Plugin readers forwarded to IO registry** — discoverable by Session.open()
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
**Priority 3 features:**
|
|
1. Annotations — text on plots, measurement lines, highlight regions
|
|
2. Comparison mode — delta channels, side-by-side tests, synced cursors
|
|
3. Report builder — template-based multi-page PDF composition
|
|
4. Keyboard shortcuts — Ctrl+O, Ctrl+S, R reset zoom, C cursor lock
|
|
|
|
**Quality targets:**
|
|
- Test coverage: 70% → 80%
|
|
- mypy errors: 34 → <10
|
|
- Files >300 lines: 8 → ≤5
|
|
|
|
---
|
|
|
|
## Test Data
|
|
|
|
| Dataset | Lab | Type | Channels |
|
|
|---|---|---|---|
|
|
| `fixtures/sample_mme/` | Synthetic | Frontal barrier | 26 |
|
|
| `mme_data/3239/` | NHTSA/Calspan | Frontal barrier (VW Passat) | 133 |
|
|
| `mme_data/AK3T02FO/` | BASt | Frontal 40% offset | 97 |
|
|
| `mme_data/AK3T02SI/` | BASt | Side impact | 97 |
|
|
| `mme_data/VW1FGS15/` | Volkswagen | Pedestrian headform | 10 |
|
|
| `mme_data/98_7707/` | UTAC | Vehicle-to-vehicle | 0 (metadata only) |
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
Core: numpy, scipy, plotly, plotly-resampler, dash, dash-bootstrap-components, pandas, pyyaml, jinja2, weasyprint, pydantic, pytz
|
|
Dev: pytest, pytest-cov, ruff, mypy
|
|
Optional: nptdms (TDMS reader plugin)
|