Changelog
Source:NEWS.md
PhysioMoCap 0.7.5
Documentation
- Runnable
@examplesadded or corrected across 114 help pages. Each runs offline in seconds, writes nothing outsidetempdir(), and is executed byR CMD check; anything needing a device, a download or an optional backend is fenced with the reason stated. - The README’s quick start runs as written: it attaches the package, builds its own inputs, and uses only hard dependencies.
PhysioMoCap 0.7.4
- Type checks in
writeC3D(), the C3D helpers andsegmentCohortCycles()accept the canonicalMultiPhysioExperiment. They previously tested forMultiRatePhysioExperimentonly, which would have rejected a container built by the current constructor.
PhysioMoCap 0.7.3
Bug Fixes
-
grfLandmarks()could return landmarks in a physiologically impossible order. The three search windows overlap by design (loading 5–40 %, mid-stance 30–60 %, push-off 45–80 % of stance) but each extremum was taken independently, with nothing constraining their sequence. On flat pathological curves this returned a mid-stance “trough” located before the “loading peak” — 6 of the 499 GaitRec knee-pathology curves did exactly that — and could place the push-off peak before the trough. The landmarks are now found in temporal order: each search starts strictly after the previous landmark, sopeak1 < trough < peak2always holds, and the function errors (rather than inventing an ordering) if a window leaves no admissible sample. - The default
pushoff_windowwas widened from45:80to45:90. The old bound truncated late propulsion and under-read the push-off peak by up to 2.2 % on gait peaking after ~80 % of stance. -
grfLandmarks()now warns when a landmark sits on the upper edge of its search window, which signals that the true extremum may lie outside the range, instead of silently returning the truncated value (it fires on 1.1 % of the 707 tracked GaitRec curves).
The defect was found by comparing grfLandmarks against an independent, window-free implementation (scipy.signal.find_peaks with prominence-based hump selection) — the first external comparator this operator has had. The group-mean landmarks it feeds are unchanged (bit-identical before and after). Adds ordering, edge-warning and error-path regression tests.
New Features
c3dEventTable()converts parameter events using an explicitly declared clock, retains source times and rounding residuals, and rejects missing origins, off-grid snapping and unsupported recording times. Point-grid snapping is opt-in.segmentCohortCycles()connects existing PhysioCohort subject/session identities and native MultiRate clocks to keyed cycle features, preserving session and trial IDs separately.segmentMultimodalCycles()extracts repeated keyed intervals on native modality grids with explicit incompleteness reports.summarizeCycleFeatures()carries complete-cycle identifiers into feature blocks and records explicitly requested exclusions.EMG alignment and integration now accept explicit start times (seconds on a shared clock) and an
outsidepolicy: legacy endpoint extension, missing values, or rejection of unsupported target times. Invalid time metadata and unrepresentable grids are rejected.integrateEMGMoCap()now extracts EMG envelopes at the native EMG sampling rate before resampling to the motion timeline. The rawemg_alignedfield is preserved.
PhysioMoCap 0.7.2
New grfLandmarks() reads the three classic stance-phase landmarks — the loading (weight-acceptance) peak, the mid-stance trough and the push-off peak — from a vertical GRF curve time-normalised to the stance phase. On a body-weight-normalised curve the landmarks are subject-mass independent, so the peak-trough-peak pattern can be contrasted across cohorts (the reduced weight-acceptance modulation of pathological gait). Complements filterGRF(), computeImpulse() and computeLoadingRate().
PhysioMoCap 0.7.1
The generic functional-PCA, waveform-reliability and circular-statistics implementations moved to PhysioCore (their single source of truth) and are re-exported here, so fPCA()/reconstructFPCA()/registerCurves(), waveformCMC()/waveformICC()/waveformReliability() and circularSummary()/ rayleighTest()/watsonWilliamsTest()/circularLinearCorrelation() behave exactly as before. The ggplot2 visualiser plotFPCA() stays in this package.
PhysioMoCap 0.7.0
Movement-disorder quantification: tremor, ataxia and instrumented spasticity.
- Tremor:
tremorSpectrum()(dependency-free Welch periodogram → dominant frequency, in-band power, half-power bandwidth, harmonic ratio in a 3-12 Hz band),tremorAmplitude()(band-limited RMS) andtremorMetrics()(combined, tagged rest/postural/kinetic). - Ataxia:
pathStraightness()(trajectory straightness / index of curvature) pluslimbAtaxiaIndex()andgaitAtaxiaIndex()— honest aggregators of the existing validated sub-metrics (endpointError,movementUnits,sparc/ldlj,summarizeGaitParametersCVs,swayMetrics) that standardise into a composite z only against a supplied healthy reference (no population weights/cut-offs are fabricated). - Instrumented spasticity (Tardieu):
tardieuStretch()locates the catch (EMG reflex onset and/or velocity arrest) → R1;tardieuScore()derives R2 and the dynamic component R2-R1;reflexThreshold()regresses catch angle on stretch velocity. Reuses the EMG↔︎MoCap alignment, envelope and angular-velocity primitives already in the package.
PhysioMoCap 0.6.2
Fixes to the OpenCap -> OpenSim pipeline (from a code review of 0.6.1).
-
runOpenSimFromMarkers()/runOpenSimFromOpenCap()now defaulttime_rangeto the whole trial (read from the marker file). Previously aNULLtime_rangeleft the tool templates’<time_range>0 1</time_range>in place, silently truncating every trial to its first second. -
toolsnow defaults to"ik"(matching the documentation); the previousc("ik","id","so")default made the bare call error on the ground-reaction requirement. - Inverse kinematics is run before the ID/SO setups are written, so their motion input is real rather than an empty placeholder; a failed IK is now reported instead of crashing the MOT reader on a 0-byte file, and reused-
workdirstale outputs are no longer attributed to the run. -
runOpenSimFromOpenCap()resolves the OpenCap session once (model and markers come from the same trial, no duplicate requests), validatessession_idand a suppliedexternal_loads_filebefore downloading, and records the resolved trial id. -
.opencap_model_urlhandling tolerates empty/NA/non-scalar session metadata; a partialtemplatesoverride keeps the bundled defaults for the other tools.
PhysioMoCap 0.6.1
OpenCap -> OpenSim -> downstream pipeline.
-
runOpenSimFromMarkers()wires a scaled model and marker.trcthrough OpenSim inverse kinematics and, optionally, inverse dynamics and static optimization: it writes the tool setup XMLs from the bundledPhysioOpenSimtemplates, runs them viarun_opensim_toolchain(), and parses the outputs withreadOpenSimOutputs(). ID/SO require anexternal_loads_file(markerless OpenCap has no ground reactions);dry_run = TRUEwrites the setups without a backend. -
runOpenSimFromOpenCap()runs that chain directly from an OpenCap session, anddownloadOpenCapModel()fetches the session’s scaled.osimmodel (the input the local OpenSim toolchain needs, since OpenCap does the scaling). - New vignette
opencap-opensim-pipelinedocuments both the cloud-kinematics route (no local OpenSim) and the local-OpenSim route, with its scope limits.
PhysioMoCap 0.5.0
Inter-joint coordination analysis.
-
continuousRelativePhase(): the phase-plane coordination measure (Hamill- between two joints, with the mean absolute relative phase (MARP).
-
vectorCoding(): the angle-angle coupling angle, classified per frame into in-phase / anti-phase / proximal-phase / distal-phase coordination (Chang 2008; Needham 2014). -
coordinationVariability(): trial-to-trial coordination variability – the deviation phase for CRP (linear SD) or the coupling-angle circular SD for vector coding – a motor-control marker.
PhysioMoCap 0.4.0
Upper-limb ADL task assessment.
-
adlReachTask(): assess an ADL arm transport (drinking / feeding / dressing / grooming / reaching) from its hand-speed profile – movement time, peak velocity, submovement count and SPARC/LDLJ smoothness – labelled with the ICF code it realises (d560 / d550 / d540 / d520 / d445). -
nhptDexterity(): instrumented Nine-Hole-Peg dexterity (ICF d440) from a hand-speed profile – transport count, rate, inter-transport consistency and smoothness – the sensor complement to the timed NHPT score.
PhysioMoCap 0.3.3
-
poseLengthCorrect()— segment-length standardisation (camera-distance correction): rescales each limb segment along the bone direction to a stable reference length, chained proximal to distal. Also available asposeFix(..., length_correct = TRUE). Generalised form of the length correction in PoseFixeR (Sugiyama, Uno & Matsui 2023).
PhysioMoCap 0.3.2
- New vignette “Markerless pose to gait: OpenPose -> poseFix -> analysis” — the end-to-end pose pipeline from ingestion through
poseFix()cleaning to joint angles and a gait metric.
PhysioMoCap 0.3.1
-
poseFix()gains left/right leg-swap correction (deswap = TRUE): leg-label swaps that pose estimators make as the legs cross during gait are corrected by restoring trajectory continuity, before the anomaly steps. The number of corrections is reported inmetadata()$poseFix$leg_swaps.
PhysioMoCap 0.3.0
-
poseFix()— pose-estimation anomaly detection and correction, connecting markerless pose input (readOpenPose()/readMediaPipe()/readDeepLabCut()) to the downstream joint-angle / gait / kinematics analysis. Flags keypoints on four criteria (low detector confidence, implausible segment lengths, frame-to-frame jumps, out-of-range joint angles), then interpolates and smooths them. Generalised, name-based, self-referential reimplementation of the method in PoseFixeR (Sugiyama, Uno & Matsui 2023, PLOS Comput Biol 19:e1009989).
PhysioMoCap 0.2.2
- Made the OpenSim MOT/TRC read/write round-trip tests portable to macOS: they now assert numerical equality (
expect_equal) of the recovered data rather than bit-identity (expect_identical). Writing numeric data through a decimal ASCII file (17 significant digits) recovers values exactly on a correctly- rounded libc (glibc) but to ~1 ULP on macOS’s printf/strtod, so a bit- identical round-trip is not a portable guarantee; the data is still preserved to full double precision. No writer/reader behaviour changed.
PhysioMoCap 0.2.1
Validation
- Bundled an independent OpenSim inverse-dynamics reference (
inst/extdata/gait2392_id_reference.rds) so theinverseDynamicsRNE()cross-tool test now runs instead of skipping. The fixture is derived from the OpenSim gait2392subject01_walk1trial (opensim-models, Apache-2.0) with OpenSim 4.6’s InverseDynamicsTool; the recursive Newton-Euler solver reproduces the OpenSim hip/knee/ankle moments at r > 0.99 and < 8% peak error. Generation is documented indata-raw/gait2392_id_reference*.
PhysioMoCap 0.2.0
New Features
- Added Venus3D CSV reader (
readVenus3D()) for OptiTrack -> Motive -> Venus3D pipeline exports with automatic header metadata parsing. - Added marker tracking module for resolving frame-by-frame label reassignment:
-
trackMarkers()— Hungarian algorithm (viaclue) or greedy assignment for establishing consistent marker identities across frames. -
detectSwaps()— velocity-spike-based swap detection with cross-over validation. -
correctSwaps()— automatic swap repair based on detection results.
-
-
readMoCapAuto()now auto-detects Venus3D CSV files (by#Venus3Dheader). - Added
clueto Suggests for optimal assignment in marker tracking.
PhysioMoCap 0.1.0
Major Improvements
- Added beginner-first onboarding utilities:
- Improved CSV robustness for quoted headers in auto/wide parsing.
- Added multi-plate force-plate workflows:
detectForcePlateContacts()analyzeForcePlatePE(..., plate_index = "auto" | "all")print.forceplate_analysis_multi()
- Added 3D inverse dynamics support:
inverseDynamics3D()- 3-axis moments and total joint power outputs.
- Expanded onboarding and kinetics test coverage.
- Added getting-started documentation improvements for first-time users.