Single-component cosinor#
In many studies of circadian rhythms, it is reasonable (and often advantageous) to assume that the underlying period is known and approximately synchronized to a 24-hour cycle. Under this assumption, rhythmic patterns can be modeled using a periodic regression approaches.
In this tutorial, we refer to the comprehensive review of cosinor regression by Cornelissen (2014), which offers a detailed overview of both the theoretical foundations and practical considerations for rhythm analysis using single-component cosinor.
We begin by importing the required libraries:
import circstudio as cs
import os
import plotly.io as pio
pio.templates.default = "plotly_white"
pio.renderers.default = "notebook"
Open sample RPX file:
# Create file path for sample files within the circStudio package
fpath = os.path.join(os.path.dirname(cs.__file__))
# Create a new Raw instance using awd RPX adaptor
raw = cs.io.read_rpx(os.path.join(fpath, 'data', 'test_sample_rpx_eng.csv'),
start_time='2015-07-04 12:00:00',
light_mode='White Light',
period='6 days',
language='ENG_UK')
Single-component cosinor analysis models rhythmic biological signals by fitting a sinusoidal function to time-series data (e.g., activity, light exposure, or temperature). This approach enables the quantitative estimation of key rhythm parameters. The regression model is expressed as:
$$Y(t) = M + A \cos\left(\frac{2\pi t}{\tau} + \phi\right) + \varepsilon(t)$$
Where:
M is the MESOR (Midline Estimating Statistic Of Rhythm), representing the rhythm-adjusted mean,
A is the amplitude, defined as the half the peak-to-trough variation of the fitted curve,
τ is the assumed period (the duration of one cycle, typically ~24h),
φ is the acrophase, representing the timing of the peak of the fitted rhythm within each cycle,
ε(t) is the residual error term.
In circStudio, the cosinor model is implemented following the same principles as in pyActigraphy and is consistent with the general design philosophy of other circadian models in the package. Specifically, the workflow involves instantiating a cosinor model and fitting it to an actigraphy-derived time series:
# Create a cosinor instance:
cosinor = cs.Cosinor()
# Fit cosinor to raw activity data
results = cosinor.fit(data=raw.activity, verbose=False)
You can access individual best fit parameter values using the following syntax:
# Mesor
mesor = results.params['Mesor'].value
# Acrophase
acrophase = results.params['Acrophase'].value
# Period
period = results.params['Period'].value
# Amplitude
amplitude = results.params['Amplitude'].value
# Goodness-of-fit metrics (Akaike information criterium and Reduced Chi^2)
aic = results.aic
redchi = results.redchi
Additionally, you can also retrieve best fit parameters as a dictionary:
results.params.valuesdict()
{'Amplitude': 30.322920387106763,
'Acrophase': 3.6510311567437586,
'Period': 1626.5421519980782,
'Mesor': 168.643472986661}
Finally, you can also plot the resulting curve:
cosinor.plot(data=raw.activity, best_params=results.params)
Next steps#
In the next tutorial, you will learn how to perform Singular Spectrum Analysis (SSA), a data-driven decomposition technique for time series that is closely related to principal component analysis (PCA). SSA enables the separation of trends, oscillatory components, and noise in rhythmic biological signals.