Classify sleep episodes as main or secondary (native pipeline)
Source:R/sleep_classify.R
classify_sleep_episodes.RdApplies the JRSV classification rule set to a raw episode table from
extract_sleep_episodes(), assigning each episode a sleep_type of
"main" or "secondary". The execution order follows Fix 27:
Usage
classify_sleep_episodes(
episodes,
data,
max_tib_h = 16,
max_main_tib_h = 14,
min_main_tib_h = 4,
nocturnal_onset_start = 18,
nocturnal_onset_end = 6,
temp_thresh = 28,
light_thresh_window = 5,
light_thresh_recovery = 10,
min_fragment_tib_h = 1,
rolling_window_min = 15L,
max_split_iterations = 3L,
collision_gap_h = 4,
verbose = FALSE
)Arguments
- episodes
A tibble as returned by
extract_sleep_episodes().- data
A tibble as returned by
detect_sleep_crespo(), containing at minimumdatetime,state,activity. The ActTrust channelsint_temp(wrist temperature) andlight(ambient lux) must be present for Fix 26a/c; the function falls back to defaults when absent.- max_tib_h
numeric(1). Episodes with TBT > this value are excluded directly. Default16.- max_main_tib_h
numeric(1). Episodes with TBT in(max_main_tib_h, max_tib_h]are split first. Default14.- min_main_tib_h
numeric(1). Minimum TBT (hours) for a main episode. Default4.- nocturnal_onset_start
numeric(1). Default nocturnal window start (decimal hours). Overridden by Fix 26a. Default18.- nocturnal_onset_end
numeric(1). Default nocturnal window end. Overridden by Fix 26a. Default6.- temp_thresh
numeric(1). Minimum wrist temperature (degC) for candidate episodes in Fix 26a/c. Default28.- light_thresh_window
numeric(1). Maximum ambient light (lux) for the nocturnal window inference (Fix 26a). Default5.- light_thresh_recovery
numeric(1). Maximum ambient light (lux) for gap merging in fragment recovery (Fix 26c). Default10.- min_fragment_tib_h
numeric(1). Minimum TBT (hours) for each fragment produced by an episode split (Fix 29). Default1.- rolling_window_min
integer(1). Smoothing window (epochs) for the activity signal used to locate episode split points. Default15L.- max_split_iterations
integer(1). Maximum recursive splits per episode. Default3L.- collision_gap_h
numeric(1). Minimum gap (hours) between two same-date main episodes to trigger sleep-date reassignment (Fix 26b). Default4.- verbose
logical(1). Print step-by-step diagnostics. DefaultFALSE.
Value
A tibble with the same columns as episodes plus sleep_type
("main" or "secondary") and is_nap (logical, TRUE when
sleep_type == "secondary", for backwards compatibility with the
zeitr_result$nights schema).
Details
Fix 25 – exclude truncated episodes at the recording end.
Fix 26a – infer adaptive nocturnal window from
int_tempandlight. Falls back tonocturnal_onset_start/nocturnal_onset_endif fewer than 2 candidate episodes pass the temperature and light filter.Fix 29 / Rule 1 – split TBT 14–16 h episodes at their activity peak (recursive, up to
max_split_iterations). Fragments still exceedingmax_main_tib_hafter splitting are excluded.Rule 2 – exclude episodes with TBT >
max_tib_h(16 h) directly, without attempting a split.Fix 26c – recover sleep nights missed by the scorer for dates with no classified main episode. Sleep and wake within the candidate window are determined by Cole-Kripke epoch scoring on ZCMn (not the period-level CSPD state). Adjacent sleep runs are merged when the intervening gap has wrist temperature >=
temp_threshand ambient light <=light_thresh_recovery.Rules 3–5 – classify each episode as
"main"or"secondary"using the nocturnal window andmin_main_tib_h.Fix 26b – resolve sleep-date collisions: when two main episodes share a noon-threshold sleep date and are separated by >=
collision_gap_hhours, reassign the later one to the next calendar date.Rule 6 – keep the longest main episode per sleep date; demote all others to
"secondary".Rule 7 – exclude all episodes (main and secondary) on dates that have no valid main sleep after Rule 6.