computeCPMFromRecorded.ts
Purpose
This module computes a Counts Per Minute (CPM) activity value from raw accelerometer samples recorded by the iOS CoreMotion coprocessor. It resamples irregularly-spaced samples to a fixed 30 Hz grid, applies a FIR bandpass filter, integrates the rectified signal, and applies a linear calibration before a final stepwise regression.
Its responsibilities include:
- Resampling variable-rate coprocessor samples to a uniform 30 Hz grid via linear interpolation
- Computing vector magnitude from the resampled XYZ channels
- Applying a FIR bandpass filter (imported from
accelerometer.ts) to isolate locomotion frequencies - Computing AUC via trapezoidal-equivalent rectangular integration at 30 Hz
- Applying a linear calibration (
629.9 + 1.33 × rawCPM) to the raw AUC - Applying a stepwise regression correction to produce the final CPM
- Returning a structured result with intermediate values for diagnostics
Invariants
Minimum Sample Count
At least 2 raw input samples are required to begin resampling.
Fewer than 2 samples return an ok: false result with reason "Not enough samples".
Minimum Resampled Length
After resampling, the grid must contain at least N30 = 1800 samples (60 seconds at 30 Hz) before the CPM pipeline runs.
Grids shorter than N30 return an ok: false result with the actual vs required count in the reason string.
Window Slicing
Only the last N30 samples of the resampled grid are used for filtering and AUC computation.
This ensures the computation always operates on exactly one 60-second window, discarding earlier data if the recording is longer.
Calibration Pipeline Order
The calibration steps are applied in a fixed order and must not be reordered:
rawCPM = AUC of rectified filtered signal
calibrated = 629.9 + 1.33 × rawCPM
cpm = stepwiseRegression(calibrated)
Resampling Interpolation
Resampling uses linear interpolation between the two bracketing samples for each grid point.
The input samples are sorted by timestamp before interpolation. The interpolation weight alpha is clamped to 0 when the two bracketing samples share the same timestamp.
Variants
Failure Result
All failure paths return the same zero-value structure with ok: false and a descriptive reason string:
{ ok: false, reason: string, cpm: 0, auc: 0, rawCPM: 0, calibrated: 0 }
Callers must check ok before using any numeric fields.
Exports
CPMResult
type CPMResult = {
ok: boolean;
reason?: string;
cpm: number;
auc: number;
rawCPM: number;
calibrated: number;
};
Contains the final CPM and all intermediate pipeline values:
| Field | Description |
|---|---|
ok | true if computation succeeded |
reason | Failure description when ok is false |
cpm | Final CPM after stepwise regression |
auc | Raw AUC of the rectified filtered signal |
rawCPM | Equal to auc; named for clarity in the pipeline |
calibrated | AUC after linear calibration, before regression |
computeCPMFromRecorded(...)
function computeCPMFromRecorded(samples: RecordedSample[]): CPMResult
Computes CPM from a set of coprocessor-recorded accelerometer samples.
Parameters
| Parameter | Description |
|---|---|
samples | Raw recorded samples from the CoreMotion coprocessor |
Returns
A CPMResult with ok: true and all pipeline values on success, or ok: false with a reason string on failure.