@examples added or corrected across 114 help pages. Each runs
offline in seconds, writes nothing outside tempdir(), and is executed by
R CMD check; anything needing a device, a download or an optional backend is
fenced with the reason stated.roxygenise() skipped them and
their documentation sat frozen while the source moved on. They are regenerated.writeC3D(), the C3D helpers and segmentCohortCycles() accept
the canonical MultiPhysioExperiment. They previously tested for
MultiRatePhysioExperiment only, which would have rejected a container built
by the current constructor.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,
so peak1 < trough < peak2 always holds, and the function errors (rather
than inventing an ordering) if a window leaves no admissible sample.pushoff_window was widened from 45:80 to 45: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.
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 outside policy: 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 raw emg_aligned field is preserved.
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().
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.
Movement-disorder quantification: tremor, ataxia and instrumented spasticity.
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) and tremorMetrics() (combined,
tagged rest/postural/kinetic).pathStraightness() (trajectory straightness / index of curvature) plus
limbAtaxiaIndex() and gaitAtaxiaIndex() — honest aggregators of the existing
validated sub-metrics (endpointError, movementUnits, sparc/ldlj,
summarizeGaitParameters CVs, swayMetrics) that standardise into a composite
z only against a supplied healthy reference (no population weights/cut-offs are
fabricated).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.Fixes to the OpenCap -> OpenSim pipeline (from a code review of 0.6.1).
runOpenSimFromMarkers()/runOpenSimFromOpenCap() now default time_range to
the whole trial (read from the marker file). Previously a NULL
time_range left the tool templates' <time_range>0 1</time_range> in place,
silently truncating every trial to its first second.tools now defaults to "ik" (matching the documentation); the previous
c("ik","id","so") default made the bare call error on the ground-reaction
requirement.workdir stale
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), validates session_id and a
supplied external_loads_file before downloading, and records the resolved
trial id..opencap_model_url handling tolerates empty/NA/non-scalar session metadata;
a partial templates override keeps the bundled defaults for the other tools.OpenCap -> OpenSim -> downstream pipeline.
runOpenSimFromMarkers() wires a scaled model and marker .trc through
OpenSim inverse kinematics and, optionally, inverse dynamics and static
optimization: it writes the tool setup XMLs from the bundled PhysioOpenSim
templates, runs them via run_opensim_toolchain(), and parses the outputs
with readOpenSimOutputs(). ID/SO require an external_loads_file (markerless
OpenCap has no ground reactions); dry_run = TRUE writes the setups without a
backend.runOpenSimFromOpenCap() runs that chain directly from an OpenCap session,
and downloadOpenCapModel() fetches the session's scaled .osim model (the
input the local OpenSim toolchain needs, since OpenCap does the scaling).opencap-opensim-pipeline documents both the cloud-kinematics
route (no local OpenSim) and the local-OpenSim route, with its scope limits.Inter-joint coordination analysis.
continuousRelativePhase(): the phase-plane coordination measure (Hamill
2000) 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.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.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 as
poseFix(..., length_correct = TRUE). Generalised form of the length
correction in PoseFixeR (Sugiyama, Uno & Matsui 2023).poseFix() cleaning to
joint angles and a gait metric.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 in metadata()$poseFix$leg_swaps.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).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.inst/extdata/gait2392_id_reference.rds) so the inverseDynamicsRNE()
cross-tool test now runs instead of skipping. The fixture is derived from the
OpenSim gait2392 subject01_walk1 trial (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 in data-raw/gait2392_id_reference*.readVenus3D()) for OptiTrack -> Motive -> Venus3D
pipeline exports with automatic header metadata parsing.trackMarkers() — Hungarian algorithm (via clue) 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 #Venus3D header).clue to Suggests for optimal assignment in marker tracking.demoMoCapData()quickStartMoCap()readMoCapAuto()assessMoCapReadiness()detectForcePlateContacts()analyzeForcePlatePE(..., plate_index = "auto" | "all")print.forceplate_analysis_multi()inverseDynamics3D()