4. From Raw Data to Acceleration Metrics

Why do we need to extract metrics

Wearable accelerometers are widely used in health research to study physical activity, sleep, and other behaviours. Most modern accelerometers are able to collect and store at least 30 values per second expressed in units of gravitational acceleration (g). Once the data is collected, health researchers typically want to derive from this data:

  1. Activity types and body postures like sleep, walking, running, sitting, etc.

  2. Energy expenditure or a measure of body acceleration that can act as a good proxy for energy expenditure.

  3. Various other outcomes, i.e. gait, balance, circadian rhythm analysis, and falls.

A critical step in going from the high-resolution data to the classification of activity types or energy expenditure is to calculate metrics, also known as signal features. A metric allows us to extract information from the signal. One approach is to calculate statistical properties of the data like the mean, standard deviation, entropy, and skewness. Another approach is to design the data metrics with domain knowledge about the process that generated the data. I personally prefer the domain knowledge-driven approach because it allows us to narrow down the search space for a successful metric and it aims at a good understanding of what we calculate.

In the domain-driven approach, a distinction is made between three acceleration signal components:

  1. Acceleration related to gravitational acceleration and by that the orientation of the accelerometer relative to gravity.

  2. Accelerations and decelerations related to movement and by that a proxy of muscle contractions and the energy expenditure needed for them.

  3. Signal noise.

Finding a metric that can separate these three components will provide informative value in relation to posture and magnitude of acceleration as a proxy for muscle contraction related to body movement and associated energy expenditure.

Metric aggregation per epoch

Although most metrics are calculated per time point, which reflect a tiny fraction of a second, GGIR then continues to aggregate these values per epoch (e.g., 5 seconds) for the following reasons:

The epoch length is kept constant within GGIR to allow for consistent interpretation. The epoch length is set with the first value of parameter windowsizes and used throughout all steps of GGIR, with the following exceptions:

Acceleration metrics available in GGIR

Below you will find a list of all metrics that GGIR can apply. Multiple metrics can be derived in the same GGIR run. All acceleration metrics are derived in GGIR function g.applymetrics. Only for Neishabouri counts GGIR relies on the R package actifelifecounts. Please see the code in the respective package documentation for information on the exact calculations. To use the metrics, add the parameters to your GGIR call, e.g.:

GGIR(do.enmo = TRUE, do.mad = TRUE, do.bfen = TRUE, …)
Metric name Description (see internal code for exact calculation) Collapse to epoch Parameter to tell GGIR to derive this metric by setting it to TRUE or FALSE Separation of gravity
enmo Euclidean norm minus one with resulting negative values rounded to zero Average do.enmo Magnitude
lfenmo Same as enmo but with low-passed filtered signals as input Average do.lfenmo Magnitude
enmoa Same as enmo but with rectified negative values instead of rounded to zero Average do.enmoa Magnitude
en Euclidean norm (vector magnitude) Average do.en Not attempted
mad Absolute difference between Euclidean norm and epoch level average of the Euclidean norm Average do.mad Frequency
anglex 5-second rolling median of a 10 Hertz version of the signals followed by atan(x / (sqrt(y2 + z2))) / (pi/180) Average do.anglex Frequency
angley 5-second rolling median of a 10 Hertz version of the signals followed by atan(y / (sqrt(x2 + z2))) / (pi/180) Average do.angley Frequency
anglez 5-second rolling median of a 10 Hertz version of the signals followed by atan(z/ (sqrt(x2 + y2))) / (pi/180) Average do.anglez Frequency
roll_med_acc_x 5-second rolling median of a 10 Hertz version of x-axis Average do.roll_med_acc_x Frequency
roll_med_acc_y 5-second rolling median of a 10 Hertz version of y-axis Average do.roll_med_acc_y Frequency
roll_med_acc_z 5-second rolling median of a 10 Hertz version of z-axis Average do.roll_med_acc_z Frequency
dev_roll_med_acc_x Absolute difference between x-axis and 5-second rolling median of a 10 Hertz version of x-axis Average do.dev_roll_med_acc_x Frequency
dev_roll_med_acc_y Absolute difference between y-axis and 5-second rolling median of a 10 Hertz version of y-axis Average do.dev_roll_med_acc_y Frequency
dev_roll_med_acc_z Absolute difference between z-axis and 5-second rolling median of a 10 Hertz version of z-axis Average do.dev_roll_med_acc_z Frequency
lfen Euclidean norm of low-pass filtered x, y and z axis Average do.lfen Not attempted
hfx High-pass filtered x-axis Average do.hfx Frequency
hfy High-pass filtered y-axis Average do.hfy Frequency
hfz High-pass filtered z-axis Average do.hfz Frequency
hfen Euclidean norm of high-pass filtered signals Average do.hfen Frequency
hfenplus Euclidean norm of low-pass filtered signals minus gravity plus Euclidean norm of the high-pass filtered signals with resulting negative values rounded to zero Average do.hfenplus Frequency and magnitude
lfx Low-pass filtered x-axis Average do.lfx Not attempted
lfy Low-pass filtered y-axis Average do.lfy Not attempted
lfz Low-pass filtered z-axis Average do.lfz Not attempted
bfx Band-pass filtered x-axis Average do.bfx Frequency
bfy Band-pass filtered y-axis Average do.bfy Frequency
bfen Euclidean norm of the band-pass filtered signals Average do.bfz Frequency
zcx Zero crossing count x-axis (see notes below) Sum do.zcx Frequency
zcy Zero crossing count y-axis (see notes below) Sum do.zcy Frequency
zcz Zero crossing count z-axis (see notes below) Sum do.zcz Frequency
neishabouricounts Counts as described by Neishabouri et al. 2022 as used in the ActiLife software for raw ActiGraph data Sum do.neishabouricounts Frequency

Approach to removing the gravitational signal component

The table above indicates the approach used to separate the gravitation component from the acceleration signal. There are two approaches:

Both assumptions are known to not hold true under all conditions, which is why no acceleration metric is perfect.

Handling high frequency components in the signal

Some argue that high frequency components in the signal should be treated as noise and be removed. However, they more likely represent the harmonics of low frequency movements and are thus part of the description of movement. For a more elaborate reflection on this, please see this blog post.

All metrics that have the letter LF or BF in their name attempt to suppress the high frequency content of the signal.

Why GGIR uses ENMO as a default.

Only one metric can be the default. Acceleration metric ENMO (Euclidean Norm Minus One with negative values rounded to zero) has been the default metric since GGIR was created. In 2013, we investigated different ways of summarising the raw acceleration data (van Hees et al. PLoS ONE 2013). In short, different metrics exist and there is very little literature to support the superiority of any metric at the time. As long as different studies use different metrics, their findings will not be comparable. Therefore, the choice for metric ENMO has been partially pragmatic. GGIR uses ENMO as default because:

1. ENMO has demonstrated value in describing variance in daily energy expenditure, is correlated with questionnaire data, and able to describe patterns in physical activity.

2. ENMO is easy to describe mathematically and by that improves reproducibility across studies and software tools.

3. ENMO attempts to quantify the acceleration in universal units and does not collapse the signal to an abstract scale.

4. The 2013 paper showed that when ENMO is used in combination with auto-calibration, it has similar validity to filter-based metrics like HFEN and BFEN, which are conceptually similar to metrics proposed later such as MIMSunit, MAD, AI0.

5. Studies who have criticised ENMO consistently failed to apply auto-calibration, or attempted to apply auto-calibration in a lab setting, ignoring the fact that auto-calibration is not designed for short lab settings. It needs free-living data to work properly. Further, studies are often not clear about how the problematic zero imputation during the idle sleep mode in ActiGraph devices is dealt with.

Notes on implementation of zero crossing counts

The implementation of the zero-crossing count in GGIR is an attempt to imitate the zero-crossed counts previously described by Sadeh, Cole, Kripke and colleagues in the late 1980s and 1990s. However, it cannot be guaranteed to be an exact copy of the original approach, which used the AMA-32 Motionlogger Actigraph by Ambulatory-monitoring Inc. (“AMI”).

No complete publicly accessible description of that approach exists.

Missing information

The missing information about the calculation are:

  1. Sadeh specified that calculations were done based on data from the Y-axis but the direction of the Y-axis was not clarified. Therefore, it is unclear whether the Y-axis at that time corresponded to the Y-axis of modern sensors.
  2. A frequency filter was used, but properties of the filter are missing.
  3. Sensitivity of the sensor: We are now guessing that the Motionlogger had a sensitivity of 0.01 g but without direct proof.
  4. Relationship between piezo-electric acceleration signal used at that time and modern piezo-capacitive acceleration signals.

From personal correspondence with AMI, we learnt that the technique has been kept proprietary and has never been shared with or sold to other actigraphy manufacturers (time of correspondence October 2021). Based on the correspondence with AMI, we can conclude that even Actiwatch, ActiGraph, and other manufacturers, who have facilitated the use of 1990s sleep classification algorithms, cannot guarantee exact replication of the original studies.

Our guess on the missing information

Following the above challenges, the implementation of the zero-crossing count in GGIR is based on an educated guess where we used all information we could find in the literature and product documentation. In relation to the missing information listed above:

  1. We allow you to specify which axis you want to use with parameter Sadeh_axis but choose as default the second axis.
  2. We use a 0.25 - 3 Hertz band-pass filter with order 2, which you can modify with parameters zc.lb, zc.hb, and zc.order.
  3. We use a 0.01 g stop band, which you can change with parameter zc.sb.
  4. We assume that the band-passed signal is comparable in the absence of evidence on the contrary.

In our own evaluation, the zero-crossing count value range looks plausible when compared to the value range in the original publications.

As a note to ActiGraph users: If you decide to compare GGIR Cole-Kripke estimates with ActiLife’s Cole Kripke estimates, be aware that ActiLife may have adopted a different Cole-Kripke algorithm as the original publication presented four algorithms. This is a potential source of variation. Further, ActiLife may have used different educated guesses about how Motionlogger counts are calculated.

Embedding your own metrics

Some GGIR users may like to use metrics not covered by GGIR. To facilitate this, we allow for external function embedding as discussed in the vignette Embedding external functions in GGIR. In fact, this allows you to include entire algorithms such as the step detection or a new sleep classification algorithm that you would like to test inside GGIR.


We are aware that this chapter could be more informative if it had an even more detailed discussion of each of the metrics. However, given that our focus is on GGIR, we have compiled a list of related articles you may find useful: