bioevents package
Submodules
bioevents.colors module
bioevents.event_handling module
- class bioevents.event_handling.Event(on, off=None, tolerances=None)[source]
Bases:
object- default_duration = 1
- property duration
- property off
- property on
- overlaps(other)[source]
Determines whether this event “overlaps” another, based on various criteria.
Notes
It’s important to note that this overlap is not necessarily a “symmetrical” operation. Because the duration and tolerances of THIS event are used, self.overlaps(other) may differ from other.overlaps(self). This is by design, given that a “reference” or “truth” event should govern the acceptance criteria of “predicted” event annotations, and not the other way around.
See also
- property tolerances
- class bioevents.event_handling.EventClassSeries(event_stack: Dict[IntEnum, EventSeries], missing_enum: IntEnum | None = None)[source]
Bases:
EventStackA special type of EventStack wherein every timestamp is expected to have one and only one class
Notes
Useful for performing class confusion or agreement analytic, such as with hypnogram annotations
- as_array(round_method_on=<ufunc 'ceil'>, round_method_off=<ufunc 'floor'>)[source]
Export all events as a list of classes
- epoch_confusion_matrix(other, normalize=None)[source]
Generates a confusion matrix with ‘other’, epoch-by-epoch via boolean logic
- Parameters:
other (EventClassSeries)
normalize (Optional(bool), default=False)
- Returns:
mat
- Return type:
pd.DataFrame
- event_confusion_matrix(other, assimilate_events=True)[source]
Generate a class-wise confusion matrix with ‘other’
- Parameters:
other (EventClassSeries)
assimilate_events (Optional(bool), default=True) – If true, any overlapping Events from either series will be counted as one.
- Returns:
mat
- Return type:
pd.DataFrame
- class bioevents.event_handling.EventSeries(events, duration=None, sampling_rate: float = 1.0)[source]
Bases:
list- append(item)[source]
Overrides built-in default to make sure the Event is concurrent with this series
- as_bools(round_method_on=<ufunc 'ceil'>, round_method_off=<ufunc 'floor'>)[source]
Converts the Events to a boolean array, using parameterizable rounding methods
- compute_agreement(other, normalize=False)[source]
Computes an agreement matrix with the given EventSeries
- Parameters:
other (EventSeries)
normalize (Optional(bool), default=False) – Normalize results rows by the number of events in the respective “reference” series
- Returns:
mat – 2 x 2 agreement matrix
- Return type:
pd.DataFrame
- debounce(persistence_period: float, min_duration: float) EventSeries[source]
Debounce the given signal to remove short events and merge close ones
- Parameters:
persistence_period (float) – merge any two events separated by less than this number (of samples)
min_duration (float) – after merging close events, remove all events under this duration (in samples)
- Returns:
debounced
- Return type:
References
Description of debouncing applied in engineering context: https://my.eng.utah.edu/~cs5780/debouncing.pdf
- property duration
- epoch_confusion_matrix(other, normalize=None)[source]
Generates a confusion matrix with the given EventSeries epoch-by-epoch via boolean logic
- Parameters:
other (EventSeries)
normalize (Optional(bool), default=False)
- Returns:
mat
- Return type:
pd.DataFrame
- event_confusion_matrix(other, normalize=None, assimilate_events=True)[source]
Generates a confusion matrix with the given EventSeries via Event-wise logic
- Parameters:
other (EventSeries)
normalize (Optional(bool), default=False)
assimilate_events (Optional(bool), default=True) – If true, any overlapping Events from either series will be counted as one.
- Returns:
mat
- Return type:
pd.DataFrame
- extend(item)[source]
Overrides built-in default to make sure the Events are concurrent with this series
- classmethod from_bools(bools, sampling_rate: float = 1.0)[source]
Converts the given boolean array into a series of discrete Events
- plot(bottom=0, top=1, color=None, as_seconds=True)[source]
Simple plot with events filled between the given y values
- property sampling_rate
- class bioevents.event_handling.EventStack(event_stack: Dict[IntEnum, EventSeries])[source]
Bases:
dict- KEY_ASSIGNED_ENUM = 'AssignedEnum'
- KEY_DURATION = 'duration'
- KEY_EVENT_STACK = 'event_stack'
- KEY_META = 'meta'
- KEY_SAMPLING_RATE = 'sampling_rate'
- property classes
- property duration
- classmethod from_dict(data: dict, intenum: IntEnum) EventStack[source]
- classmethod from_string_keys(event_stack: Dict[str, EventSeries])[source]
- property sampling_rate
- class bioevents.event_handling.MissingDataLabels(value)[source]
Bases:
IntEnumAn enumeration.
- ARTIFACT = -2
- DISAGREE = -3
- MISSING = 0
- UNSCORABLE = -1
- class bioevents.event_handling.OverlapTolerances(diff_on=inf, diff_off=inf, ratio_on=inf, ratio_off=inf)[source]
Bases:
object
bioevents.hypnogram module
- class bioevents.hypnogram.Hypnogram(event_stack)[source]
Bases:
EventClassSeries- generate_report() HypnogramReport[source]
- latency_to_first_persistent_sleep() float | None[source]
Latency to first epoch of persistent (10 minutes) sleep.
- Returns:
latency – If no persistent sleep occurs, returns None. If persistent sleep occurs, returns latency (in samples).
- Return type:
Optional(float)
Notes
This metric is traditionally reported in minutes. Please take note of the sample_rate to convert if needed.
- latency_to_stage(stage: SleepStages) float | None[source]
Time from lights off to first epoch of the given stage
- Parameters:
stage (SleepStages)
- Returns:
latency – If stage does not occur, returns None. Otherwise, returns latency (in samples).
- Return type:
Optional[float]
Notes
This metric is traditionally reported in minutes. Please take note of the sample_rate to convert if needed.
- plot(unit='seconds', ax=None, color=None, alpha=1, label=None, **plt_kwargs)[source]
Stacks individual series onto the same plot
- Parameters:
unit (str, Optional[default="seconds"]) – Must be one of the keyword args to datetime.timedelta This will affect the x-axis label’s units.
ax (plt.Axes, Optional)
color (plt.colors[Optional]) – Color to use for the hypnogram and any non-sleep labels
alpha (float, Optional[default=1]) – Alpha to use for hypnogram. A gradient thereof will be used for any non-sleep labels.
label (str, Optional) – Label to use for this hypnogram. Useful when plotting multiple hypnograms on the given axis “ax”
plt_kwargs (kwargs) – Any additional keyword args meant for plt.plot AND plt.fill_betweenx
Notes
This function is better aligned with the format of a hypnogram plot that is expected in sleep science.
- sleep_efficiency_percent(bedtime_series: EventSeries | None = None) float[source]
- sleep_onset_latency(n1_tolerance: float = 0) float | None[source]
Find sleep onset latency from a hypnogram (in samples). Assume the start of the hypnogram is the start of bedtime (light off).
- Parameters:
n1_tolerance (float, default 0) – If 0 (default), return latency to sleep onset as the first non-Wake stage (used for overnight sleep) If positive, units are samples, and more rules are followed (see Notes)
- Returns:
sleep_onset_latency – Time (in samples) from beginning of this hypnogram until the sleep onset. See Notes for more information on the definition of sleep onset.
- Return type:
Optional(float)
Notes
This metric is traditionally reported in minutes. Please take note of the sample_rate to convert if needed. There are multiple ways to report SOL:
The start of first scored epoch of any stage of sleep.
Typically used in overnight PSG.
The start of the first epoch of “unequivocal sleep”.
Typically used in MWT for assessment of daytime sleepiness. “Unequivocal sleep” is “defined as 3 consecutive epochs of stage 1 sleep, or 1 epoch of any other stage of sleep” (see Reference #1). Epochs, in this case, are 30 seconds long. Thus, the first epoch of any of the following would be considered unequivocal sleep onset:
[N1, N1, N1, …] three epochs of N1
[N1, N1, S, …] two epochs of N1, followed immediately by any other stage of sleep
[N1, S, …] one epoch of N1, followed immediately by any other stage of sleep
[S, …] one epoch of any other stage of sleep
For algorithmic purposes, this reduces to the observation that unequivocal sleep occurs at the onset of ANY sleep other than short, N1-only sleep episodes lasting less than 90 seconds.
References
Clinical study using SOL as a primary endpoint: https://clinicaltrials.gov/ct2/show/NCT03522506
- time_in_stage(stage: SleepStages) float[source]
Total time spent in the given stage, in samples.
- total_recording_time(bedtime_series: EventSeries | None = None) float[source]
Find total recording time, i.e., total time in bed, from a hypnogram (in samples)
- Parameters:
bedtime_series (Optional[event_handling.EventSeries]) – An event series derived from clinical lights off/on annotations. In the clinical setting, this is the period of time when subjects are expected to attempt sleep. If given, only compute recording time that occurs during bedtime.
Notes
This metric is traditionally reported in minutes. Please take note of the sample_rate to convert if needed.
- total_sleep_time(bedtime_series: EventSeries | None = None) float[source]
Find total sleep time (in samples) from a hypnogram
- Parameters:
bedtime_series (Optional[event_handling.EventSeries]) – An event series derived from clinical lights off/on annotations. In the clinical setting, this is the period of time when subjects are expected to attempt sleep. If given, only compute sleep time that occurs during bedtime.
Notes
This metric is traditionally reported in minutes. Please take note of the sample_rate to convert if needed.
- wake_after_sleep_onset() float | None[source]
Compute WASO (wake after sleep onset) from a hypnogram. Useful for overnight sleep
- Returns:
WASO – If SOL is None, returns None. If SOL is not None, returns wake after sleep onset (in samples).
- Return type:
Optional(float)
Notes
This metric is traditionally reported in minutes. Please take note of the sample_rate to convert if needed.
- class bioevents.hypnogram.HypnogramReport(*, duration_minutes: float, latency_minutes_rem: float | None = None, latency_minutes_n1: float | None = None, latency_minutes_n2: float | None = None, latency_minutes_n3: float | None = None, latency_minutes_persistent_sleep: float | None = None, latency_minutes_rem_with_persistence: float | None = None, latency_minutes_sleep_onset: float | None = None, latency_minutes_sleep_onset_unequivocal: float | None = None, total_minutes_rem: float, total_minutes_n1: float, total_minutes_n2: float, total_minutes_n3: float, total_minutes_nrem: float, total_minutes_sleep: float, efficiency_rem: float, efficiency_rem_first_two_hours: float, efficiency_sleep: float, event_count_rem: int, event_count_wake: int, event_count_wake_persistent: int, wake_after_sleep_onset_minutes: float | None = None)[source]
Bases:
BaseModel,ABCUsed for the EDS reports
- duration_minutes: float
- efficiency_rem: float
- efficiency_rem_first_two_hours: float
- efficiency_sleep: float
- event_count_rem: int
- event_count_wake: int
- event_count_wake_persistent: int
- latency_minutes_n1: float | None
- latency_minutes_n2: float | None
- latency_minutes_n3: float | None
- latency_minutes_persistent_sleep: float | None
- latency_minutes_rem: float | None
- latency_minutes_rem_with_persistence: float | None
- latency_minutes_sleep_onset: float | None
- latency_minutes_sleep_onset_unequivocal: float | None
- model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}
A dictionary of computed field names and their corresponding ComputedFieldInfo objects.
- model_config: ClassVar[ConfigDict] = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- model_fields: ClassVar[dict[str, FieldInfo]] = {'duration_minutes': FieldInfo(annotation=float, required=True, metadata=[Ge(ge=0)]), 'efficiency_rem': FieldInfo(annotation=float, required=True, metadata=[None, Interval(gt=None, ge=0, lt=None, le=1), None, None]), 'efficiency_rem_first_two_hours': FieldInfo(annotation=float, required=True, metadata=[None, Interval(gt=None, ge=0, lt=None, le=1), None, None]), 'efficiency_sleep': FieldInfo(annotation=float, required=True, metadata=[None, Interval(gt=None, ge=0, lt=None, le=1), None, None]), 'event_count_rem': FieldInfo(annotation=int, required=True, metadata=[Ge(ge=0)]), 'event_count_wake': FieldInfo(annotation=int, required=True, metadata=[Ge(ge=0)]), 'event_count_wake_persistent': FieldInfo(annotation=int, required=True, metadata=[Ge(ge=0)]), 'latency_minutes_n1': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None), 'latency_minutes_n2': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None), 'latency_minutes_n3': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None), 'latency_minutes_persistent_sleep': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None), 'latency_minutes_rem': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None), 'latency_minutes_rem_with_persistence': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None), 'latency_minutes_sleep_onset': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None), 'latency_minutes_sleep_onset_unequivocal': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None), 'total_minutes_n1': FieldInfo(annotation=float, required=True, metadata=[Ge(ge=0)]), 'total_minutes_n2': FieldInfo(annotation=float, required=True, metadata=[Ge(ge=0)]), 'total_minutes_n3': FieldInfo(annotation=float, required=True, metadata=[Ge(ge=0)]), 'total_minutes_nrem': FieldInfo(annotation=float, required=True, metadata=[Ge(ge=0)]), 'total_minutes_rem': FieldInfo(annotation=float, required=True, metadata=[Ge(ge=0)]), 'total_minutes_sleep': FieldInfo(annotation=float, required=True, metadata=[Ge(ge=0)]), 'wake_after_sleep_onset_minutes': FieldInfo(annotation=Union[Annotated[float, Ge(ge=0)], NoneType], required=False, default=None)}
Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].
This replaces Model.__fields__ from Pydantic V1.
- total_minutes_n1: float
- total_minutes_n2: float
- total_minutes_n3: float
- total_minutes_nrem: float
- total_minutes_rem: float
- total_minutes_sleep: float
- wake_after_sleep_onset_minutes: float | None
Module contents
Top-level package for BioEvents.