Micromotion
A Python toolbox for analysing human micromotion in various types of motion time series coming from optical marker data, body-worn accelerometers, respiration belts, and force plates.
The package is built around analysing quantity of motion (QoM), band-limited to velocities of 0.2–10 Hz, in millimetres per second. It applies equally to data from different sensor families because the shared abstraction is the frequency band, not the instrument.
Why it exists
The toolbox was built during construction of a unified analysis for all datasets in the Oslo Standstill Database. There were numerous scripts floating around and many different ways of filtering, thresholding and calculating QoM. To avoid further confusion, this toolbox aims to consolidate all of this into a single package.
Install
pip install micromotion
Requirements
Requires numpy, scipy and pandas.
Use
import micromotion as mm
rec = mm.read("Standstill2017/mocap_data/A0001.tsv") # dispatches on content
head = rec.marker("P01")
mm.qom(head, rec.fs, kind="position").mean_mm_s
read identifies the layout from the file itself rather than from its extension because not all TSV or CSV files are correctly formatted.
The two bands, and why it matters
There are two conventions in use:
-
micromotionis defined as being within the range 0.2–10 Hz. It is the only band that can be applied to every sensor, so it is the one any cross-collection comparison must use. -
optical_legacyis a 10 Hz low-pass with no lower edge. It keeps sub-0.3 Hz postural drift, which, for optical position, is real movement, and it is the convention by which earlier Championship of Standstill figures were computed. On the 2015 championship, it reads 15.5 per cent above the band-pass. A 10 Hz low-pass filter degenerates as the sampling rate approaches 20 Hz, where its cutoff reaches the Nyquist frequency, and it stops filtering entirely. On the 20 Hz origin dataset, it removed 0.0000 per cent of the signal energy while removing 27.9 per cent from 200 Hz recordings, so the two were never the same measure. It is kept to reproduce older results, not to produce new ones.
The lower edge is optional for position and mandatory for acceleration: gravity is a DC term, and integrating a signal with any residual offset produces a ramp that swamps the result. Asking for optical_legacy on accelerometer data raises an error rather than returning a plausible number.
Toolbox Rules
Here are some important principles to keep in mind:
Measure the rate, do not read it. measured_rate counts samples over the elapsed span rather than inverting the median interval. When timestamps are rounded to milliseconds, the median-interval route returns exactly 250 Hz for a recording that runs at 256 Hz, and 636 Hz for one arriving at 106 Hz.
Downsample, never upsample. to_rate raises rather than upsampling. Upsampling invents structure between samples, and every method that reads across scales treats the invention as real. An analysis that upsampled 20 Hz data to 25 Hz once produced multifractal widths up to 6.6 where the plausible range is about 1. Nothing failed; the numbers were simply wrong.
Gaps are NaN, never a sentinel. Readers convert the Qualisys zero triplet, the phone's exact-zero rows, the respiration belt's rails and the balance board's no-load (0.5, 0.5) centre of pressure. Each of those is a plausible-looking value that is not a measurement.
Say which end of the series you trust. QomResult.binned flags both the partial final bin and the filter transients at each end rather than dropping them silently. Including the partial bin, once inflated, increased the deposited series three- to fourteenfold.
What is in it
| Module | Contents |
|---|---|
filters |
the band definitions, band-pass, low-pass, high-pass, cardiac notch |
qom |
quantity of motion from position or acceleration; raw, compensated and tilt-corrected variants |
resample |
rate measurement, quality metrics, downsample-only resampling, irregular-to-regular gridding |
spectral |
cardiac and respiratory peaks, band power |
dynamics |
DFA, multifractal DFA, stabilogram diffusion, recurrence quantification, IAAFT and other surrogates, time reversal, sample entropy, phase locking |
io |
one reader per corpus layout, and a content sniffer |
record |
the common structure the readers return |
Validation
Every numerical claim the package makes is covered by a test against a process whose answer is known in advance: white noise, pink noise and Brownian motion for the scaling exponents, a binomial cascade for multifractality, an Ornstein–Uhlenbeck process for the diffusion crossover, and a sinusoid of known amplitude and frequency for quantity of motion itself, which both the position route and the acceleration route must recover.
Two of these restore a check that had been lost. A report stated that the time-reversal test returns z = +0.85 on an AR(1) process and z = −41 on a logistic map, but no script implementing it survived; those are now tests.
Against the corpus, the package reproduces the deposited Taqāsīm quantity of motion to within 0.1 per cent on four of five subjects, and the cardiac peak it finds in the StillStanding365 phone signal matches the wrist heart rate at a median ratio of 0.99.
python -m pytest micromotion/tests -q
Relationship to other packages
This toolbox builds on and connects with these packages:
musicalgesturestakes video in and produces visual featuresambiscapetakes spatial audio and produces soundscape featuresrespyhandles respiration belts.
Each of those either produces a time series or analyses one signal type. This package is the analysis layer several of them feed into. The interface is a pipe, not a merge: they produce time series; micromotion consumes them.
Licence
GPL-3.0-or-later.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file micromotion-0.6.0.tar.gz.
File metadata
- Download URL: micromotion-0.6.0.tar.gz
- Upload date:
- Size: 96.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed9d8a863535817b7ed8fdcd72b8604e0059840c653cb8948b120ebbdb4d8e2e
|
|
| MD5 |
3efaee7a49185694bdefc194b23d1bd5
|
|
| BLAKE2b-256 |
9d11b1bdb2f8d886ccdef0ebd56956b6967a9c304e2900a1dfcb985f8c0dbaf5
|
Provenance
The following attestation bundles were made for micromotion-0.6.0.tar.gz:
Publisher:
publish.yml on fourMs/micromotion
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
micromotion-0.6.0.tar.gz -
Subject digest:
ed9d8a863535817b7ed8fdcd72b8604e0059840c653cb8948b120ebbdb4d8e2e - Sigstore transparency entry: 2289812137
- Sigstore integration time:
-
Permalink:
fourMs/micromotion@dd45f7f13ed11bb50ec72ca7bc9687ecd999eefd -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/fourMs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@dd45f7f13ed11bb50ec72ca7bc9687ecd999eefd -
Trigger Event:
release
-
Statement type:
File details
Details for the file micromotion-0.6.0-py3-none-any.whl.
File metadata
- Download URL: micromotion-0.6.0-py3-none-any.whl
- Upload date:
- Size: 77.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8f884e0c15ae8188b3771dc437114a01f37bb0fe39377ace45e973d4377545d
|
|
| MD5 |
3e70fbf12410c92a3186b9304a1199d7
|
|
| BLAKE2b-256 |
04075bed3d78290b41f997a31e7ce2e0d995ea63c17f0dac8cfca0cd8333add0
|
Provenance
The following attestation bundles were made for micromotion-0.6.0-py3-none-any.whl:
Publisher:
publish.yml on fourMs/micromotion
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
micromotion-0.6.0-py3-none-any.whl -
Subject digest:
a8f884e0c15ae8188b3771dc437114a01f37bb0fe39377ace45e973d4377545d - Sigstore transparency entry: 2289812156
- Sigstore integration time:
-
Permalink:
fourMs/micromotion@dd45f7f13ed11bb50ec72ca7bc9687ecd999eefd -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/fourMs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@dd45f7f13ed11bb50ec72ca7bc9687ecd999eefd -
Trigger Event:
release
-
Statement type: