Skip to main content

A package for computing the CosinorAge from raw accelerometer data.

Project description

CosinorAge

Documentation Status PyPI version Python 3.11 License: Apache 2.0 GitHub Actions DOI

An open-source Python package for estimating biological age based on circadian rhythms derived from accelerometer data. The package offers a unified framework that integrates data preprocessing, feature extraction, and predictive modeling of biological age using the CosinorAge biomarker.

Getting Started

Prerequisites

Where to run commands: Run all pip, git, and python -m venv commands below in a terminal — on Windows, use PowerShell or Command Prompt; on macOS/Linux, use Terminal. The Python code examples further down belong in a .py script, a Jupyter notebook, or an IDE such as VS Code — not in the terminal directly.

Python version notes

We recommend Python 3.11 (e.g. 3.11.9). Installation may fail on Python 3.13+ because some dependencies (notably claid and its grpcio requirement) do not yet support the latest Python releases.

On Windows, enabling long path support can be required when installing claid.

Installation Steps

Option 1: Quick Installation via pip (Recommended)

From your terminal:

pip install cosinorage

For full functionality (wear detection, sleep analysis, cosinor fitting, dashboards), also install:

pip install claid scikit-digital-health CosinorPy seaborn pytz

If pip install cosinorage fails, try installing with Python 3.11 in a fresh virtual environment (see Option 2, steps 2–3) before running the commands above.

Option 2: Manual Installation from Source

  1. Clone the Repository

    git clone https://github.com/ADAMMA-CDHI-ETH-Zurich/CosinorAge.git
    cd CosinorAge
    
  2. Set Up Virtual Environment

    # Create a new virtual environment (requires Python 3.11)
    python -m venv venv
    
    # Activate the virtual environment
    # On Windows (PowerShell):
    venv\Scripts\activate
    # On macOS/Linux:
    source venv/bin/activate
    
  3. Install Dependencies

    # Upgrade pip
    pip install --upgrade pip
    
    # Install required packages
    pip install -r requirements.txt
    
  4. Install the Package

    # Install in development mode
    pip install -e .
    

Quick Start

After installation, save the following code as a Python script (e.g. quickstart.py) or run it in a Jupyter notebook / VS Code, then execute it with python quickstart.py:

import cosinorage
from cosinorage.datahandlers import GalaxyDataHandler

# Initialize a data handler using the sample CSV included in the repository
handler = GalaxyDataHandler(
    galaxy_file_path='data/smartwatch/sample1.csv',
    data_format='csv',
    verbose=True,
)

# Compute features
from cosinorage.features import WearableFeatures, dashboard
features = WearableFeatures(handler)
dashboard(features)

# Compute CosinorAge (dummy data)
from cosinorage.bioages import CosinorAge
records = [
    {'handler': handler, 
     'age': 60, 
     'gender': 'male', 
    }
]
predictions = CosinorAge(records)
predictions.get_predictions()

For more detailed examples, please refer to the examples directory.

Package Functionalities

For detailed examples of how to use the package, please refer to the examples folder. The package's theoretical background, including references to the underlying research papers, is documented in our Read the Docs theoretical background section. For comprehensive API documentation, please see the package reference.

Modular Scheme

Package Data Scheme

Data Loading

Depending on the data source, different data handlers are used to perform the necessary preprocessing and data conversion steps. These handlers ensure that the data is consistently formatted as minute-level ENMO data.

The figure below illustrates the supported data sources and the required file types for each DataHandler:

Supported Data Sources

Below, you will find a detailed description of each supported data source and its corresponding DataHandler.

[!NOTE] Not all data files can be made publicly available in this repository due to privacy regulations governing personal health data. Some datasets (such as UK Biobank data) require specific access permissions and cannot be distributed publicly.

GalaxyDataHandler

[!NOTE] Signal scaling factors have been calibrated through internal validation experiments. Use with caution.

The GalaxyDataHandler is used to load and preprocess data from the Galaxy Smartwatch. The data is expected to be located in a directory with the following structure:

Samsung Galaxy Smartwatch Data Directory Structure

For each day a seperate subdirectory is expected to be present - within each day's subdirectory, the data is expected to be located in seperate hourly .binary files (file names need to start with "acceleration_data"). The binary files need to have the following 4 columns: unix_timestamp_in_ms, acceleration_x, acceleration_y, acceleration_z. The data can then be loaded into the corresponding GalaxyDataHandler object as follows.

galaxy_handler = GalaxyDataHandler(gw_file_dir='../data/smartwatch/GalaxyWatch_Case1/', preprocess=True, preprocess_args=preprocess_args, verbose=True)

NHANESDataHandler

The NHANESDataHandler is used to load and preprocess data from the NHANES study. The data is expected to be located in a directory with the following structure:

NHANES Data Directory Structure

It is expected that for a specific version of the dataset (e.g., G or H) three files are present: PAXDAY_<version>.xpt, PAXMIN_<version>.xpt and PAXHD_<version>.xpt. The files follow a very specific format, containing a wide range of different data fields. Thus, please use the files as they are provided by NHANES - they can be downloaded via this link. The data can then be loaded into the corresponding NHANESDataHandler object as follows.

nhanes_handler = NHANESDataHandler(nhanes_file_dir='../data/nhanes/', seqn=62164, verbose=True)

[!NOTE] Loading time: PAXMIN_*.xpt files contain minute-level accelerometer data for the entire NHANES cohort. Even when you request a single participant (seqn), the handler must scan the full file chunk by chunk. Depending on hardware and the NHANES cycle, this step commonly takes several minutes (sometimes 20–60 minutes on slower systems). This is expected behavior. With verbose=True, a single progress bar labelled Reading minute-level data (version …) shows chunk processing; it may appear stuck at 0% briefly while the first large chunk is read.

UKBDataHandler

The UKBDataHandler is used to load and preprocess data from the UK Biobank. The data is expected to be located in a directory with the following structure - however, please note that the data is not publicly available:

UKB Data Directory Structure

The .csv files containing the ENMO data are expected to be in a common directory - the .csv files also contain the information needed by the UKBDataHandler to correctly determine the timestamps of the ENMO data. Below, please find an example of the content of the .csv files (made up data):

UKB ENMO Data Example

In addition to that, the UKBDataHandler also expects a path to a Quality Control .csv file which contains flags for each measured ENMO series indicating whether the data is of acceptable quality. The file needs to have the following columns.

UKB Quality Control File Columns

The data can then be loaded into the corresponding UKBDataHandler object as follows.

ukb_handler = UKBDataHandler(qa_file_path='../data/ukb/UKB Acc Quality Control.csv', ukb_file_dir='../data/ukb/UKB Sample Data/1_raw5sec_long', eid=1234567, verbose=True)

GenericDataHandler

The GenericDataHandler is a flexible data handler for processing various types of accelerometer and ENMO data from CSV files. It supports multiple data formats and automatically handles data preprocessing, filtering, and ENMO calculation.

The handler supports three main data types:

  • ENMO data: Pre-calculated ENMO (Euclidean Norm Minus One) values
  • Accelerometer data: Raw 3-axis accelerometer data (x, y, z)
  • Alternative count data: Activity count data

Example usage for ENMO data:

generic_handler = GenericDataHandler(
    file_path='data/enmo_data.csv',
    data_type='enmo-mg',
    time_column='timestamp',
    data_columns=['enmo'],
    preprocess_args=preprocess_args,
    verbose=True
)

Example usage for accelerometer data:

generic_handler = GenericDataHandler(
    file_path='data/accel_data.csv',
    data_type='accelerometer-mg',
    time_column='time',
    data_columns=['x', 'y', 'z'],
    preprocess_args=preprocess_args,
    verbose=True
)

The GenericDataHandler automatically:

  • Loads data from CSV files with customizable column names
  • Detects sampling frequency from timestamps
  • Filters incomplete days and selects longest consecutive sequence
  • Resamples data to minute-level
  • Applies preprocessing (wear detection, noise removal, etc.)
  • Calculates minute-level ENMO values

Wearable Feature Computation

The WearableFeatures object can be used to compute various features from the minute-level ENMO data.

features = WearableFeatures(smartwatch_handler)
features.run()

In the following sections the different wearable features are described in detail. To generate all the visualizations at once you can run the following function.

dashboard(features)

Circadian Rhythm Analysis - Cosinor Analysis

The WearableFeatures module performs a cosinor analysis to determine the acrophase, amplitude, and MESOR of the ENMO signal over a multiday period (see below). The example shown below is based on an individual from the NHANES study.

Cosinor Analysis

Circadian Rhythm Analysis - Non-parametric Analysis

In addition, the module performs non-parametric analyses of the circadian rhythm, generating various metrics, including L5, M10, IS, IV, and RA. For a more detailed description of these metrics, please refer to the documentation. Below, you can see an example of the visualized results.

M10 & L5

IS and IV

RA

Sleep Analysis

The module is also capable of predicting sleep phases based on the provided ENMO signal. Using the predicted sleep phases, various metrics—including TST, WASO, PTA, NWB, and SOL—are computed. Exemplary results are visualized below.

Sleep Phases Sleep Metrics

CosinorAge Prediction

The CosinorAge object can be used to compute CosinorAge. It is capable of processing multiple datahandlers at the same time.

Each record must include the participant's chronological age and gender ('male', 'female', or 'unknown'). These are not stored in the accelerometer files themselves; you need to obtain them from the appropriate source for your dataset (e.g. NHANES demographic files, study questionnaires, or electronic health records).

NHANES example: download the demographic file for the same cycle as the accelerometer data (e.g. DEMO_G.xpt for cycle G) from the NHANES data portal, then look up age and sex for your SEQN:

import pandas as pd

demo = pd.read_sas('path/to/DEMO_G.xpt')
row = demo[demo['SEQN'].astype(int) == 62177].iloc[0]
age = int(row['RIDAGEYR'])
gender = 'male' if row['RIAGENDR'] == 1 else 'female' if row['RIAGENDR'] == 2 else 'unknown'

records = [
    {'handler': nhanes_handler, 'age': age, 'gender': gender}
]
cosinor_age = CosinorAge(records)
cosinor_age.get_predictions()

For other data sources, provide age and gender from the corresponding metadata in the same way:

records = [
    {'handler': data_handler, 
     'age': 51, 
     'gender': 'male'
    }
]

cosinor_age = CosinorAge(records)
cosinor_age.get_predictions()

The plot below visualizes the CosinorAge advance of a patient, showing a CosinorAge of approximately 54 years, which is higher than the patient's chronological age of 51.

CosinorAge Prediction

Open Source Development

The package is developed in an open-source manner. We welcome contributions to the package.

Improve the Package

Any kind of contribution is welcome! In order to make new data sources compatible with the package, you can implement a new datahandler class - the package offers a DataHandler class that should be used as a base class.

Implement and Execute Tests

To make sure that the changes you made are not breaking the package, you should implement new and execute the new and old tests. To do so, go to the root directory of the repository and execute the following command to run the tests:

pytest

Upon push to github, the tests will be executed automatically by the CI/CD pipeline and the commit will only be accepted if all the tests pass.

Deploy Package

Build the package:

pip install build
python -m build

Upload the package to the PyPI repository:

pip install twine
twine upload dist/*

Citation

Shim, J., Fleisch, E. & Barata, F. Circadian rhythm analysis using wearable-based accelerometry as a digital biomarker of aging and healthspan. npj Digit. Med. 7, 146 (2024). https://doi.org/10.1038/s41746-024-01111-x

Acknowledgments

This project is developed in collaboration with ADAMMA - the Core for AI and Digital Biomarker Research at ETH Zurich. ADAMMA innovates at the intersection of technology, medicine, and data science to revolutionize health monitoring and disease prevention.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cosinorage-1.0.8.tar.gz (75.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cosinorage-1.0.8-py3-none-any.whl (104.8 kB view details)

Uploaded Python 3

File details

Details for the file cosinorage-1.0.8.tar.gz.

File metadata

  • Download URL: cosinorage-1.0.8.tar.gz
  • Upload date:
  • Size: 75.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.6

File hashes

Hashes for cosinorage-1.0.8.tar.gz
Algorithm Hash digest
SHA256 43c75bd4b4b1df5d7441d8c51549f2b2958f6205cfb418e63b9331324bcef53e
MD5 8d6ca6cefd187faa67c2977c06d45db9
BLAKE2b-256 d4a8106a78b3b0db0c8c5c384ab25f2cc703b15ea73389c9083c433acd24cd6a

See more details on using hashes here.

File details

Details for the file cosinorage-1.0.8-py3-none-any.whl.

File metadata

  • Download URL: cosinorage-1.0.8-py3-none-any.whl
  • Upload date:
  • Size: 104.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.6

File hashes

Hashes for cosinorage-1.0.8-py3-none-any.whl
Algorithm Hash digest
SHA256 e4b9870154da26fa85cebb432ea18640ae615cb57d92a1ec3f62203eaa7c19f0
MD5 4775a1123e096282b42961f217ae5dc3
BLAKE2b-256 04b766545ef0e5e40973a488161c0161c6338f850e49da3fe49f33eb18727d3d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page