Metadata-Version: 2.5
Name: micromotion
Version: 1.14.0
Summary: Micromotion analysis of motion time series: mocap, IMU and force plate
Project-URL: Homepage, https://github.com/fourMs/micromotion
Project-URL: Documentation, https://fourms.github.io/micromotion/
Project-URL: Repository, https://github.com/fourMs/micromotion
Project-URL: Changelog, https://github.com/fourMs/micromotion/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/fourMs/micromotion/issues
Author-email: Alexander Refsum Jensenius <a.r.jensenius@imv.uio.no>
License-Expression: GPL-3.0-or-later
License-File: LICENSE
Keywords: accelerometer,micromotion,motion capture,quantity of motion,standstill
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Requires-Python: >=3.10
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=2.0
Requires-Dist: scipy>=1.10
Provides-Extra: mixed
Requires-Dist: statsmodels>=0.14.6; extra == 'mixed'
Provides-Extra: test
Requires-Dist: pytest>=7; extra == 'test'
Requires-Dist: statsmodels>=0.14.6; extra == 'test'
Description-Content-Type: text/markdown

# micromotion

[![tests](https://github.com/fourMs/micromotion/actions/workflows/tests.yml/badge.svg)](https://github.com/fourMs/micromotion/actions/workflows/tests.yml)
[![docs](https://github.com/fourMs/micromotion/actions/workflows/docs.yml/badge.svg)](https://fourms.github.io/micromotion/)
[![PyPI](https://img.shields.io/pypi/v/micromotion.svg)](https://pypi.org/project/micromotion/)
[![Python](https://img.shields.io/pypi/pyversions/micromotion.svg)](https://pypi.org/project/micromotion/)
[![License](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg)](LICENSE)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.21953120.svg)](https://doi.org/10.5281/zenodo.21953120)

A Python package for measuring human micromotion: the small movement of a body that is
standing, sitting or otherwise trying to stay still. It reads optical marker data, body-worn
accelerometers, respiration belts and force plates, and reduces all of them to one measure.

That measure is quantity of motion: the average speed of a body part, band-limited to
0.2–5 Hz, in millimetres per second.

![Band-limited speed of a synthetic head marker, with the median, the mean, and the same series in five-second bins](docs/img/qom-standstill.png)

It can be computed from every sensor family, because the shared abstraction is the frequency
band rather than the instrument. One synthetic body motion, read three ways — as optical
position at 100 Hz, as the acceleration a worn sensor would report, and as position sampled at
50 Hz — gives medians of 2.29, 2.35 and 2.29 mm/s, a spread of 2.6 per cent.

![The same body motion read as optical position at 100 Hz, as worn acceleration, and as position at 50 Hz: three bars at 2.29, 2.35 and 2.29 mm/s](docs/img/one-measure.png)

Both figures are real output, regenerated by `docs/img/make_figures.py` on synthetic signals
whose answer is known.

## Install

```bash
pip install micromotion
```

Python 3.10 or newer, with numpy, scipy and pandas. There is no computer-vision or audio stack
to install.

## Quickstart

```python
import micromotion as mm

rec = mm.read("mocap_data/A0001.tsv")      # dispatches on content, not on the extension
head = rec.marker("P01")                   # (n_samples, 3), gaps already NaN
result = mm.qom(head, rec.fs, kind="position", unit=rec.unit)

print(result.median_mm_s, result.mean_mm_s)
```

Report the median, and say that it is the median. The mean and the median can rank the same
recordings differently, so both are returned and neither is chosen for the caller.

Do not name a local variable `mm`. The conventional alias collides with a mean and with a value
in millimetres, and rebinding it replaces the package for the rest of the file.

## Documentation

| | |
|---|---|
| [Reference documentation](https://fourms.github.io/micromotion/) | how to use it, every function, the conventions |
| [Wiki](https://github.com/fourMs/micromotion/wiki) | traps, worked recipes, design decisions |
| [Changelog](CHANGELOG.md) | what changed between releases |

Read [Getting started](https://fourms.github.io/micromotion/quickstart/) first, then
[The three bands](https://fourms.github.io/micromotion/conventions/), which is the one
convention that cannot be skipped. [Reading files](https://fourms.github.io/micromotion/formats/)
covers what each reader handles, which axis is vertical in which system, and the traps that
produce plausible numbers rather than errors.

## What is in it

| Module | Contents |
|---|---|
| `qom` | quantity of motion from position or acceleration, in three named variants |
| `filters` | the band definitions—`BAND`, `WIDEBAND`, `OPTICAL_LEGACY_BAND`—with band-pass, low-pass, high-pass and notch |
| `resample` | rate measurement, downsample-only resampling, irregular-to-regular gridding, gap handling |
| `io` | one reader per file layout, a content sniffer, and the per-channel rate and resolution checks |
| `record` | `MotionRecord`, the common type every reader returns |
| `validate` | checks that fail loudly on silently-wrong data |
| `posture`, `balance` | sway geometry, spatial extent, centre-of-pressure measures |
| `spectral`, `physio` | cardiac and respiratory peaks, band power, breathing rate and breath phase |
| `dynamics` | detrended fluctuation analysis, multifractality, recurrence, entropy, surrogates |
| `group` | whether several people moved at the same moments |
| `align` | offsets between instruments that share no clock |
| `circular` | directional statistics, including the axial tests postural sway needs |
| `features` | `feature_vector`, one fixed set of eleven descriptors per recording |
| `equivalence` | stating that an effect is absent rather than failing to show it is present |
| `descriptors` | how many independent dimensions a descriptor set holds, and whether a measure is a trait |

Readers: Qualisys and Qualisys-style TSV in all three header shapes, Sverm, Axivity AX3,
Physics Toolbox phone logs, Equivital, Wii balance board, and Artinis fNIRS. `read` dispatches
on content rather than on extension, because in this field the extension is frequently wrong.

## Licence and credit

GPL-3.0-or-later. Built at the [fourMs lab](https://github.com/fourMs), RITMO Centre for
Interdisciplinary Studies in Rhythm, Time and Motion, University of Oslo. If you use the
package, please cite it—see [CITATION.cff](CITATION.cff)—and cite the underlying methods too,
since the [Methods](https://fourms.github.io/micromotion/methods/) page gives a reference for
each.

Issues and pull requests are welcome at
[fourMs/micromotion](https://github.com/fourMs/micromotion/issues). A case where a default here
gives a misleading answer is the most useful kind of issue to file.

## The four toolboxes

Four packages from the fourMs lab, each released separately on PyPI. Which one you want is
decided by what you have in hand rather than by what you want to know:

| you have | use | it gives you |
|---|---|---|
| a motion time series from a body — optical markers, an accelerometer, a respiration belt, a force plate | micromotion (this one) | quantity of motion, posture, balance, and the band conventions the others follow |
| a video file, with or without its sound | [musicalgestures](https://github.com/fourMs/MGT-python) | motiongrams, videograms, motion analysis from ordinary video |
| a recording of a place — mono, stereo, binaural or ambisonic | [ambiscape](https://github.com/fourMs/ambiscape) | the sonic ambience of that place: level, spectrum, space, rhythm, sources |
| a folder of music, or a concert recording | [musiscape](https://github.com/fourMs/musiscape) | many tracks and albums compared at a glance |

Where a measure appears in more than one package it has a single owner and a single
implementation, so the answer does not depend on which package you called. This package is the
owner for filtering, lag estimation and circular statistics, and it is the root of the family:
it depends on none of the others, needing only numpy, scipy and pandas. musicalgestures and
musiscape both require it. ambiscape does not, keeping its own copy of six short
circular-statistics primitives so that it installs alone, held equal to this package's by a test
on its side.

Being the owner is a responsibility rather than a rank. `align.xcorr_lag` returned the opposite
of the sign it documented until 1.13.0, and what caught it was comparing against
`musicalgestures.xcorr_lag`, which had been right all along.

## Citing

Cite the CONCEPT DOI, which always resolves to the newest version:

> Jensenius, A. R., Upham, F., Zelechowska, A., Gonzalez-Sanchez, V. E., Swarbrick, D., & Riaz, M.
> (2026). *micromotion: analysis of human micromotion in motion time series* (Version 1.12.2)
> [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.21953120

Where the exact behaviour matters, cite the version you ran instead. This package HAS changed
behaviour at releases — `read_phone` at 0.15.0, `group_qom` at 1.0.0, `to_rate` at 1.2.2 — so which
version produced a number is part of the method. Version 1.12.2 is
https://doi.org/10.5281/zenodo.21953121.

An older concept DOI, https://doi.org/10.5281/zenodo.21948988, is frozen at 1.12.1. It was created
by a hand deposit made before the Zenodo GitHub integration was archiving this repository, and
Zenodo cannot merge two concepts; that record says so itself and points here. Cite the DOI above.

`CITATION.cff` in this repository carries the same information in machine-readable form.
