Published July 11, 2026
| Version v0.1.1
Software
Open
circadia-bio/hypnoR: v0.1.1
Description
β¨ New features
- Added
new_hypnogram(), the constructor underlying all other hypnoR functions. Accepts either a bare tibble withepoch/stagecolumns (e.g.zeitR::export_hypnogram()output) or anmrpheus_hypnogramobject (mrpheus::export_hypnogram()output), normalising both into a singlehypnor_hypnogramrepresentation. Staging resolution (AASM vs coarse) is auto-detected from the stage labels present. - Implemented
compute_sleep_architecture(): TST, TIB, SE, SOL, WASO, REM/SWS latency, and stage percentages, all resolution-agnostic. Sleep onset is defined as the first non-"W"epoch for both AASM and coarse hypnograms.epoch_secand staging resolution are read automatically from thehypnor_hypnogramobject rather than passed as arguments. - Implemented
compute_transitions(): stage-to-stage transition matrix (counts or row-normalised probabilities) plus fragmentation index and wake-transition count. Newinclude_wakeargument controls whether Wake is included as a state in the matrix; fragmentation metrics always use the full epoch sequence regardless of this setting. - Implemented
compute_cycles(): NREM/REM cycle segmentation for full AASM hypnograms, with two selectable algorithms.method = "feinberg_floyd"(default) treats any maximal contiguous REM run of at leastmin_rem_epochsas a REM period, with no tolerance for interruption.method = "aasm"merges REM runs separated by a gap of at mostrem_gap_minminutes (default 15) into a single REM period before applying themin_rem_epochsthreshold. Errors on coarse hypnograms, which have no REM stage to segment on. - Added
smooth_hypnogram(), a hypnogram-level cleanup step for raw unsmoothed per-epoch staging (e.g.mrpheus::stage_epochs(), which has no temporal continuity constraint and can produce isolated single-epoch stage flips). Two label-only rules, applicable independently or in sequence:"aasm_isolated"(default) reassigns a single epoch flanked identically on both sides;"min_run"merges any run shorter thanmin_run_epochsinto whichever flanking run is longer, regardless of whether the flanks agree. The original labels are preserved in a newstage_rawcolumn. - Added
window_hypnogram(): restricts a hypnogram to a time (lights_off/lights_on) or epoch (from_epoch/to_epoch) window, correctly preservingepoch_secandresolutionon the result rather than re-detecting them from the (possibly much smaller) subset. This is the single place windowing logic lives --compute_cycles()andcompute_transitions()have nolights_off/lights_onarguments of their own; window first, then pass the windowed hypnogram in.
π Visualisation
- Implemented
plot_hypnogram(),plot_architecture(), andplot_transition_matrix(). All three use a runtimeggplot2check rather than a hard dependency (consistent with the rest of the ecosystem) and share the built-in Circadia Lab stage colour palette.plot_hypnogram()takes an optionalcyclesargument (the tibble fromcompute_cycles()) to overlay cycle-boundary lines;plot_architecture()facets on anight/idcolumn when present, for comparing nights. plot_hypnogram()gains anx_axisargument ("auto"(default),"time", or"hours"). When the hypnogram carries real timestamps (i.e.start_timewas supplied tonew_hypnogram()ormrpheus::export_hypnogram()), the x-axis now shows actual clock time by default instead of always using elapsed hours since the first epoch.plot_hypnogram()gains astyleargument:"step"(default, unchanged) or"capsule"-- rounded-pill bars per contiguous stage run, one lane per stage, loosely modelled on the Apple Watch sleep chart's visual language (Circadia Lab palette, full AASM lane ordering, light theme rather than Apple's dark coarse 4-stage scheme). ggplot2 has no native rounded-rect geom, so pills are hand-traced polygons (corner radius scales with each bar's own width, via the newcorner_minargument).- Rotated the stage colour palette:
N1 -> Wake -> REM -> N1.Wis now cream (was N1's),REMis now amber (was wake's),N1is now teal (was REM's);N2/N3/Sleep/Quiet sleepunchanged.
π Bug fixes
compute_cycles()'sstart_epoch/end_epochcolumns were reporting row position withinhypnogram, not the actual values inhypnogram$epoch-- identical wheneverepochruns1:n(true of every fixture in the test suite so far), but wrong for any hypnogram that doesn't start at epoch 1, e.g. after subsetting a longer recording down to a sleep-period window. Durations (nrem_min/rem_min/cycle_min) were unaffected, since those were already computed from row-position differences rather than the epoch column.- Behaviour change:
compute_sleep_architecture()'slights_off/lights_onarguments now restrict every metric viawindow_hypnogram(), not justTIB/SEas before -- previouslyTST,SOL,WASO, and stage percentages were computed over the entire hypnogram regardless of the window, which was inconsistent. Requireshypnogramto carry real timestamps; errors iftimeis entirelyNA.
π CI
- Fixed mrpheus/zeitR dependency resolution in CI: added
Additional_repositories: https://circadia-bio.r-universe.devand a repo-root.Rprofilesettingoptions(repos = ...)directly.Additional_repositoriesalone doesn't automatically wire intopak's dependency resolution during CI -- it's mainly a documentation/NOTE- suppression field -- so the.Rprofileis what actually makes both packages resolvable. - Added a
covr-based coverage step to thepkgdown.yamlworkflow, writing a coverage badge (docs/badges/coverage.json) togh-pageson pushes tomain/master/release (matching zeitR's setup).covradded toSuggests; newdev/check_coverage.Rfor running coverage locally. README gainsR CMD CHECKandCoveragebadges.
π Documentation
- Rewrote
vignette("getting-started")to reflect the actual current API (the previous version referencedread_hypnogram(), which doesn't exist yet), and to run against real recordings from both staging sources rather than hypothetical placeholder code: mrpheus's bundledSC4001E0example for the AASM path, and zeitR's bundledinput1.txtActTrust recording (via its full rest-activity pipeline) for the coarse path -- demonstrating the staging-agnostic contract concretely:compute_sleep_architecture()returnsNAfor AASM-only fields on coarse hypnograms and populates the coarse-only ones instead,compute_transitions()works over a 3x3 matrix instead of 5x5, andcompute_cycles()errors clearly on coarse staging (no REM stage to segment cycles on). Both mrpheus- and zeitR-dependent chunks are guarded withrequireNamespace(); both packages added toSuggests. Newdev/test_mrpheus_pipeline.Randdev/test_zeitR_pipeline.R. - Added two worked-example articles ("Worked examples" on the pkgdown
site), cross-linked to each other:
vignette("mrpheus-integration"), a warts-and-all walkthrough of diagnosing scattered raw REM calls, smoothing, windowing to the real sleep period, and comparingcompute_cycles()'s two methods; andvignette("zeitR-integration"), the coarse-staging counterpart -- timestamp-gap inspection, why off-wrist time is folded into"W", picking the right night out of a multi-day recording, and checking (rather than assuming) whether smoothing matters as much for actigraphy-derived staging as it did for mrpheus's raw automatic staging.
Files
circadia-bio/hypnoR-v0.1.1.zip
Files
(221.4 kB)
| Name | Size | Download all |
|---|---|---|
|
md5:0a60d24714d1d3ba96c26c5f9200f56b
|
221.4 kB | Preview Download |
Additional details
Related works
- Is supplement to
- Software: https://github.com/circadia-bio/hypnoR/tree/v0.1.1 (URL)
Software
- Repository URL
- https://github.com/circadia-bio/hypnoR