code: def _read_annotations_cnt(fname, data_format="int16"):
      """CNT Annotation File Reader.
  
      This method opens the .cnt files, searches all the metadata to construct
      the annotations and parses the event table. Notice that CNT files, can
      point to a different file containing the events. This case when the
      event table is separated from the main .cnt is not supported.
  
      Parameters
      ----------
      fname: path-like
          Path to CNT file containing the annotations.
      data_format : 'int16' | 'int32'
          Defines the data format the data is read in.
  
      Returns
      -------
      annot : instance of Annotations
          The annotations.
      """
      # Offsets from SETUP structure in http://paulbourke.net/dataformats/eeg/
      SETUP_NCHANNELS_OFFSET = 370
      SETUP_RATE_OFFSET = 376
  
      def _accept_reject_function(keypad_accept):
          accept_list = []
          for code in keypad_accept:
              if "xd0" in str(code):
                  accept_list.append("good")
              elif "xc0" in str(code):
                  accept_list.append("bad")
              else:
                  accept_list.append("NA")
          return np.array(accept_list)
  
      def _translating_function(
          offset, n_channels, event_type, data_format=data_format
      ):
          n_bytes = 2 if data_format == "int16" else 4
          if event_type == CNTEventType3:
              offset *= n_bytes * n_channels
          event_time = offset - 900 - (75 * n_channels)
          event_time //= n_channels * n_bytes
          event_time = event_time - 1
          # Prevent negative event times
          np.clip(event_time, 0, None, out=event_time)
          return event_time
  
      def _update_bad_span_onset(
          accept_reject, onset, duration, description
      ):
          accept_reject = accept_reject.tolist()
          onset = onset.tolist()
          duration = duration.tolist()
          description = description.tolist()
          # If there are no bad spans, return original parameters
          if "bad" not in accept_reject:
              return (
                  np.array(onset),
                  np.array(duration),
                  np.array(description),
              )
          # Create lists of bad and good span markers and onset
          bad_good_span_markers = [
              i for i in accept_reject if i in ["bad", "good"]
          ]
          bad_good_onset = [
              onset[i]
              for i, value in enumerate(accept_reject)
              if value in ["bad", "good"]
          ]
          # Calculate duration of bad span
          first_bad_index = bad_good_span_markers.index("bad")
          duration_list = [
              bad_good_onset[i + 1] - bad_good_onset[i]
              for i in range(
                  first_bad_index, len(bad_good_span_markers), 2
              )
          ]
          # Add bad event marker duration and description
          duration_list_index = 0
          for i in range(len(onset)):
              if accept_reject[i] == "bad":
                  duration[i] = duration_list[duration_list_index]
                  description[i] = "BAD_" + description[i]
                  duration_list_index += 1
          # Remove good span markers
          final_onset, final_duration, final_description = [], [], []
          for i in range(len(accept_reject)):
              if accept_reject[i] != "good":
                  final_onset.append(onset[i])
                  final_duration.append(duration[i])
                  final_description.append(description[i])
          return (
              np.array(final_onset),
              np.array(final_duration),
              np.array(final_description),
          )
  
      with open(fname, "rb") as fid:
          fid.seek(SETUP_NCHANNELS_OFFSET)
          (n_channels,) = np.frombuffer(fid.read(2), dtype="<u2")
  
          fid.seek(SETUP_RATE_OFFSET)
          (sfreq,) = np.frombuffer(fid.read(2), dtype="<u2")
  
          event_table_pos = _compute_robust_event_table_position(
              fid=fid, data_format=data_format
          )
  
      with open(fname, "rb") as fid:
          teeg = _read_teeg(fid, teeg_offset=event_table_pos)
  
      event_parser = _get_event_parser(event_type=teeg.event_type)
  
      with open(fname, "rb") as fid:
          fid.seek(event_table_pos + 9)  # the real table stats at +9
          buffer = fid.read(teeg.total_length)
  
      my_events = list(event_parser(buffer))
  
      if not my_events:
          return Annotations(list(), list(), list(), None)
      else:
          onset = _translating_function(
              np.array([e.Offset for e in my_events], dtype=float),
              n_channels=n_channels,
              event_type=type(my_events[0]),
              data_format=data_format,
          )
          # There is a Latency field but it's not useful for durations, see
          # https://github.com/mne-tools/mne-python/pull/11828
          duration = np.zeros(len(my_events), dtype=float)
          accept_reject = _accept_reject_function(
              np.array([e.KeyPad_Accept for e in my_events])
          )
  
          description = np.array([str(e.StimType) for e in my_events])
  
          onset, duration, description = _update_bad_span_onset(
              accept_reject, onset / sfreq, duration, description
          )
          return Annotations(
              onset=onset,
              duration=duration,
              description=description,
              orig_time=None,
          )
  
file_path: mne-python/mne/io/cnt/cnt.py
imports: from os import path
  import numpy
  from ..._fiff._digitization import _make_dig_points
  from ..._fiff.constants import FIFF
  from ..._fiff.meas_info import _empty_info
  from ..._fiff.utils import _create_chs, _find_channels, _mult_cal_one, read_str
  from ...annotations import Annotations
  from ...channels.layout import _topo_to_sphere
  from ...utils import _check_option, _validate_type, fill_doc, warn
  from ..base import BaseRaw
  from ._utils import CNTEventType3, _compute_robust_event_table_position, _get_event_parser, _read_teeg, _session_date_2_meas_date
label_desc: Use image node_id 1 for calling a global function with example usage: _read_annotations_cnt(fname, data_format) and returns: np, event_time, np,  np,  np, Annotations, Annotations, np,  np,  np