Metrics

Defines metrics to quantify circadian disruption

source

esri

 esri (time:numpy.ndarray, light_schedule:numpy.ndarray,
       analysis_days:int=4, esri_dt:float=1.0,
       initial_amplitude:float=0.1, phase_at_midnight:float=1.65238233)

Calculate the ESRI metric for a given light schedule. Follows the implementation from Moreno et al. 2023 ‘Validation of the Entrainment Signal Regularity Index and associations with children’s changes in BMI’

Type Default Details
time ndarray time in hours to use for the simulation
light_schedule ndarray light schedule in lux
analysis_days int 4 number of days used to calculate ESRI
esri_dt float 1.0 time resolution of the ESRI calculation in hours
initial_amplitude float 0.1 initial amplitude for the simulation. This is the ESRI value for constant darkness
phase_at_midnight float 1.65238233 phase at midnight. Default value corresponds to a 8 hour darkness and 16 hour light schedule with wake at 8 am.
Returns List list with ESRI timepoints and ESRI values. Negative ESRI values are turned into NaNs
def sleep_metrics(
    time: np.ndarray, # array of time values
    sleep_state: np.ndarray, # array of sleep state values
) -> List[np.ndarray]:
    "Calculate sleep duration and mid-sleep time"
    if not isinstance(time, np.ndarray):
        time = np.array(time)
        raise ValueError("time must be a numpy array")
    if not isinstance(sleep_state, np.ndarray):
        sleep_state = np.array(sleep_state)
        raise ValueError("sleep_state must be a numpy array")
    if len(time) != len(sleep_state):
        raise ValueError("time and sleep_state must have the same length")

    sleep_start_idxs = np.where(np.diff(sleep) == 1)[0]
    sleep_end_idxs = np.where(np.diff(sleep) == -1)[0] 
    # trim any incomplete sleep windows
    if sleep_start_idxs[0] > sleep_end_idxs[0]:
        sleep_end_idxs = sleep_end_idxs[1:]
    if sleep_start_idxs[-1] > sleep_end_idxs[-1]:
        sleep_start_idxs = sleep_start_idxs[:-1]

    sleep_duration = np.mean(time[sleep_end_idxs] - time[sleep_start_idxs])
    sleep_midpoints = (time[sleep_start_idxs] + time[sleep_end_idxs]) / 2.0
    mid_sleep_time = np.mean(np.mod(sleep_midpoints, 24.0))

    return sleep_duration, mid_sleep_time