class_docstr: Mixin class for Annotations in Epochs.
class_docstr_tok: ["Mixin","class","for","Annotations","in","Epochs","."]
docstr: Get a list of annotations that occur during each epoch.
  
  Returns
  -------
  epoch_annots : list
      A list of lists (with length equal to number of epochs) where each
      inner list contains any annotations that overlap the corresponding
      epoch. Annotations are stored as a :class:`tuple` of onset,
      duration, description (not as a :class:`~mne.Annotations` object),
      where the onset is now relative to time=0 of the epoch, rather than
      time=0 of the original continuous (raw) data.
docstr_tok: ["Get","a","list","of","annotations","that","occur","during","each","epoch",".","Returns","--","--","--","-","epoch_annots",":","list","A","list","of","lists","(","with","length","equal","to","number","of","epochs",")","where","each","inner","list","contains","any","annotations","that","overlap","the","corresponding","epoch",".","Annotations","are","stored","as","a",":","class",":","`","tuple","`","of","onset",",","duration",",","description","(","not","as","a",":","class",":","`","~mne.Annotations","`","object",")",",","where","the","onset","is","now","relative","to","time=0","of","the","epoch",",","rather","than","time=0","of","the","original","continuous","(","raw",")","data","."]
code: def get_annotations_per_epoch(self):
      """Get a list of annotations that occur during each epoch.
  
      Returns
      -------
      epoch_annots : list
          A list of lists (with length equal to number of epochs) where each
          inner list contains any annotations that overlap the corresponding
          epoch. Annotations are stored as a :class:`tuple` of onset,
          duration, description (not as a :class:`~mne.Annotations` object),
          where the onset is now relative to time=0 of the epoch, rather than
          time=0 of the original continuous (raw) data.
      """
      # create a list of annotations for each epoch
      epoch_annot_list = [[] for _ in range(len(self.events))]
  
      # check if annotations exist
      if self.annotations is None:
          return epoch_annot_list
  
      # when each epoch and annotation starts/stops
      # no need to account for first_samp here...
      epoch_tzeros = self.events[:, 0] / self._raw_sfreq
      epoch_starts, epoch_stops = (
          np.atleast_2d(epoch_tzeros)
          + np.atleast_2d(self.times[[0, -1]]).T
      )
      # ... because first_samp isn't accounted for here either
      annot_starts = self._annotations.onset
      annot_stops = annot_starts + self._annotations.duration
  
      # the first two cases (annot_straddles_epoch_{start|end}) will both
      # (redundantly) capture cases where an annotation fully encompasses
      # an epoch (e.g., annot from 1-4s, epoch from 2-3s). The redundancy
      # doesn't matter because results are summed and then cast to bool (all
      # we care about is presence/absence of overlap).
      annot_straddles_epoch_start = np.logical_and(
          np.atleast_2d(epoch_starts) >= np.atleast_2d(annot_starts).T,
          np.atleast_2d(epoch_starts) < np.atleast_2d(annot_stops).T,
      )
  
      annot_straddles_epoch_end = np.logical_and(
          np.atleast_2d(epoch_stops) > np.atleast_2d(annot_starts).T,
          np.atleast_2d(epoch_stops) <= np.atleast_2d(annot_stops).T,
      )
  
      # this captures the only remaining case we care about: annotations
      # fully contained within an epoch (or exactly coextensive with it).
      annot_fully_within_epoch = np.logical_and(
          np.atleast_2d(epoch_starts) <= np.atleast_2d(annot_starts).T,
          np.atleast_2d(epoch_stops) >= np.atleast_2d(annot_stops).T,
      )
  
      # combine all cases to get array of shape (n_annotations, n_epochs).
      # Nonzero entries indicate overlap between the corresponding
      # annotation (row index) and epoch (column index).
      all_cases = (
          annot_straddles_epoch_start
          + annot_straddles_epoch_end
          + annot_fully_within_epoch
      )
  
      # for each Epoch-Annotation overlap occurrence:
      for annot_ix, epo_ix in zip(*np.nonzero(all_cases)):
          this_annot = self._annotations[annot_ix]
          this_tzero = epoch_tzeros[epo_ix]
          # adjust annotation onset to be relative to epoch tzero...
          annot = (
              this_annot["onset"] - this_tzero,
              this_annot["duration"],
              this_annot["description"],
          )
          # ...then add it to the correct sublist of `epoch_annot_list`
          epoch_annot_list[epo_ix].append(annot)
      return epoch_annot_list
  
imports: import json
  import os.path
  import re
  import warnings
  from collections import Counter, OrderedDict
  from collections.abc import Iterable
  from copy import deepcopy
  from datetime import datetime, timedelta, timezone
  from itertools import takewhile
  from textwrap import shorten
  import numpy
  from scipy.io import loadmat
  from ._fiff.constants import FIFF
  from ._fiff.open import fiff_open
  from ._fiff.tag import read_tag
  from ._fiff.tree import dir_tree_find
  from ._fiff.write import _safe_name_list, end_block, start_and_end_file, start_block, write_double, write_float, write_name_list_sanitized, write_string
  from .utils import _check_dict_keys, _check_dt, _check_fname, _check_option, _check_pandas_installed, _check_time_format, _convert_times, _DefaultEventParser, _dt_to_stamp, _is_numeric, _mask_to_onsets_offsets, _on_missing, _pl, _stamp_to_dt, _validate_type, check_fname, fill_doc, int_like, logger, verbose, warn
label_desc: Use image node_id 3 for calling the EpochAnnotationsMixin obj's underlying member method code with example usage: obj.get_annotations_per_epoch() and returns: epoch_annot_list, epoch_annot_list