Force-plate analysis toolkit for vertical jump testing, built around an engineer-friendly pipeline for detecting events, segmenting movement phases, computing biomechanics metrics, and exporting explainable results for APIs and visualization tools.
At a high level, this repository takes raw vertical ground reaction force (vGRF) data from force plates and turns it into structured outputs for three common jump-test families:
- Countermovement Jump (
CMJ) - Drop Jump (
DJ) - Squat Jump (
SJ)
For readers who want the sports-science context first:
- Vertical jump overview (Wikipedia)
- Countermovement jump overview and monitoring use case (PubMed meta-analysis)
- Drop jump / Reactive Strength Index context (PubMed)
- Drop jump performance validity against force plate measures (PubMed)
In practice:
CMJis used to assess jump performance, neuromuscular status, and force-time strategy during a countermovement.SJisolates concentric intent more cleanly by removing the preparatory dip.DJis commonly used for reactive strength and stretch-shortening-cycle assessment, especially through contact-time and RSI-style metrics.
This project sits at the intersection of biomechanics and software engineering. The goal is not just to "calculate jump height," but to build a reusable analysis system that:
- accepts raw force-plate exports or in-memory payloads,
- detects meaningful biomechanical events robustly from noisy real-world data,
- computes physics-based metrics from those detections,
- packages results into a consistent JSON contract for downstream apps,
- supports debugging and interpretation through visualization and explainable outputs.
That design makes the repo useful both as an analysis engine and as a portfolio example of applied engineering in signal processing, numerical computing, API-oriented backend design, and domain-specific algorithm development.
- Modular analysis architecture: data loading, detection, kinematics, metrics, export, and visualization are separated into focused modules under
src/. - Single API-style entry point:
src/run_analysis.pydispatches bytest_typeand returns a unified payload shape acrossCMJ,DJ, andSJ. - Typed domain models: dataclasses in
src/data/types.pygive the pipeline explicit structures for trials, events, and validity state. - Robust detection logic: event detection uses sustained-threshold rules, morphology-aware peak/valley logic, and phase-aware validation rather than naive single-sample thresholding.
- Physics-based computation: metrics are derived from force, impulse, velocity, displacement, RFD, and bodyweight-normalized quantities instead of relying only on simple summary statistics.
- Explainable output contract: the exported payload includes both raw values and human-readable explanations via
src/analysis_response.py. - Tooling around the core pipeline: this repo includes CLI workflows, JSON export, a browser viewer, batch processing scripts, and synced video rendering for analysis/debugging.
- Research-to-code translation: the codebase captures domain rules such as contact timing, take-off/landing thresholds, structural peak logic, and classification heuristics in configurable, inspectable Python modules.
The core pipeline is:
- Load raw trial data from JSON or an in-memory dict.
- Estimate baseline bodyweight and sample rate.
- Detect biomechanical events from the force-time signal.
- Derive phase boundaries from those events.
- Compute kinematics and performance metrics.
- Build a normalized visualization/API payload with phases, key points, metrics, validity flags, and explanations.
That flow is implemented most directly in src/run_analysis.py.
CMJ: detects movement onset, minimum force, eccentric end, velocity-zero transition, take-off, and landing; computes jump height, power, RFD, impulses, displacement, and asymmetry metrics.DJ: detects contact episodes, drop landing, peak impact, contact through point, start of concentric, peak drive-off, take-off, second landing, and landing peak; computes contact-time, RSI, braking/propulsive metrics, and reactive classification.SJ: detects quiet standing, contraction onset, optional countermovement contamination, peak force, take-off, landing, and landing peak; computes concentric-force metrics and classifies execution quality.
src/data/load.py: tolerant loaders for raw JSON and in-memory request payloads.src/data/types.py: typed dataclasses for trials, events, phases, and validity.src/detect/: event detection, baseline estimation, validity checks, and test-specific logic.src/physics/: kinematics, metrics, and left/right asymmetry calculations.src/export_viz.py: builds the JSON payload used by the viewer and by API consumers.src/analysis_response.py: attaches explanations and display ordering to outputs.src/config.py: configurable thresholds and detection settings.
script/main.py: mainCMJCLI workflow.script/export_dj_viz.py: batch export forDJtrials.script/export_sj_viz.py: batch export forSJtrials.script/serve_viewer.py: local HTTP server for browsing generated viewer JSON.script/render_sync_video.py: renders synchronized video + force-chart output.
web/viewer.html: standalone visualization UI for exported trials.docs/DETECTION_AND_METRICS.md: detailedCMJdetection and metric definitions.docs/DROP_JUMP_ANALYSIS.md: overview of theDJpipeline and outputs.docs/DROP_JUMP_DETECTION_ALGORITHM.md: deeper algorithm notes forDJ.docs/SQUAT_JUMP_METRICS_AND_STATISTICS.md: squat-jump metrics and interpretation.
The pipeline expects JSON exports containing:
athlete_idornametest_typetest_durationforceortotal_forceleft_forceright_force- optional
sample_count
The loader is intentionally tolerant:
forceandtotal_forceare both accepted.sample_countis inferred if missing.- arrays are trimmed to a consistent minimum length when needed.
This behavior is implemented in src/data/load.py, which reflects a backend-focused design: the code is written to absorb imperfect payloads without making integration fragile.
Each analysis returns a structured payload containing:
time_s,force_N,left_force_N,right_force_Nphaseskey_pointseventsmetricsvalidityanalysis
The analysis block is especially useful for frontend or product integration because it maps phases, key points, and metrics to { value, explanation }, which makes the output easier to display, annotate, and debug.
python3 -m venv .venv
.venv/bin/pip install -r requirements.txtPYTHONPATH=. .venv/bin/python script/main.py path/to/trial.json --export output/cmj_viz.jsonUseful options:
--no-plot--save chart.png--filter 50--take-off-threshold <N>--landing-threshold <N>--onset-below-bw <fraction>
PYTHONPATH=. .venv/bin/python script/export_dj_viz.py saved_raw_data/dj-dataPYTHONPATH=. .venv/bin/python script/export_sj_viz.py saved_raw_data/sj-dataPYTHONPATH=. .venv/bin/python script/serve_viewer.py --port 8000Then open http://localhost:8000.
The cleanest integration point is src/run_analysis.py:
from src.run_analysis import run_analysis
payload = run_analysis({
"athlete_id": "example-athlete",
"test_type": "DJ",
"test_duration": 2.5,
"total_force": [...],
"left_force": [...],
"right_force": [...],
})This returns a ready-to-serve JSON-like dict and avoids file I/O, which is exactly the kind of interface you want when connecting force-plate hardware or analysis services to a web or mobile application.
One of the strongest engineering aspects of this repo is that the analysis does not stop at metric computation. It also provides tooling for inspection:
- JSON exports for browser-based review
- phase shading and key-point overlays in the viewer
- comparison-friendly payloads
- synced video rendering for force-data verification
That is valuable in real engineering settings because signal-processing systems are hard to trust if they cannot be visualized and debugged against the underlying waveform.
This project showcases practical engineering skills in:
- numerical computing with
NumPyandSciPy - signal-processing-oriented algorithm design
- thresholding and morphology-based event detection
- clean pipeline decomposition and separation of concerns
- API-first backend design
- typed Python data modeling with dataclasses
- explainable analytics output design
- domain-driven module organization
- CLI and visualization tooling for developer workflows
- translating biomechanics concepts into reproducible software logic
If you are reviewing the repo as an engineer, this order gives the fastest understanding:
src/run_analysis.pysrc/data/load.pysrc/detect/src/physics/metrics.pysrc/export_viz.pyweb/viewer.htmldocs/DETECTION_AND_METRICS.md
- The repo currently contains sample raw data and generated output under
saved_raw_data/andoutput/. - The main CLI path is centered on
CMJ, whileDJandSJare exported through dedicated scripts and all three are supported through the in-memory API entry point. - The existing documentation in
docs/goes deeper into the biomechanics details; this README is intended to make the repository easy to understand quickly for engineering reviewers, recruiters, collaborators, or portfolio visitors.
