code: def events_from_annotations(
      raw,
      event_id="auto",
      regexp=r"^(?![Bb][Aa][Dd]|[Ee][Dd][Gg][Ee]).*$",
      use_rounding=True,
      chunk_duration=None,
      verbose=None,
  ):
      """Get :term:`events` and ``event_id`` from an Annotations object.
  
      Parameters
      ----------
      raw : instance of Raw
          The raw data for which Annotations are defined.
      event_id : dict | callable | None | ``'auto'``
          Can be:
  
          - **dict**: map descriptions (keys) to integer event codes (values).
            Only the descriptions present will be mapped, others will be ignored.
          - **callable**: must take a string input and return an integer event
            code, or return ``None`` to ignore the event.
          - **None**: Map descriptions to unique integer values based on their
            ``sorted`` order.
          - **'auto' (default)**: prefer a raw-format-specific parser:
  
            - Brainvision: map stimulus events to their integer part; response
              events to integer part + 1000; optic events to integer part + 2000;
              'SyncStatus/Sync On' to 99998; 'New Segment/' to 99999;
              all others like ``None`` with an offset of 10000.
            - Other raw formats: Behaves like None.
  
            .. versionadded:: 0.18
      regexp : str | None
          Regular expression used to filter the annotations whose
          descriptions is a match. The default ignores descriptions beginning
          ``'bad'`` or ``'edge'`` (case-insensitive).
  
          .. versionchanged:: 0.18
             Default ignores bad and edge descriptions.
      use_rounding : bool
          If True, use rounding (instead of truncation) when converting
          times to indices. This can help avoid non-unique indices.
      chunk_duration : float | None
          Chunk duration in seconds. If ``chunk_duration`` is set to None
          (default), generated events correspond to the annotation onsets.
          If not, :func:`mne.events_from_annotations` returns as many events as
          they fit within the annotation duration spaced according to
          ``chunk_duration``. As a consequence annotations with duration shorter
          than ``chunk_duration`` will not contribute events.
      %(verbose)s
  
      Returns
      -------
      %(events)s
      event_id : dict
          The event_id variable that can be passed to :class:`~mne.Epochs`.
  
      See Also
      --------
      mne.annotations_from_events
  
      Notes
      -----
      For data formats that store integer events as strings (e.g., NeuroScan
      ``.cnt`` files), passing the Python built-in function :class:`int` as the
      ``event_id`` parameter will do what most users probably want in those
      circumstances: return an ``event_id`` dictionary that maps event ``'1'`` to
      integer event code ``1``, ``'2'`` to ``2``, etc.
      """
      if len(raw.annotations) == 0:
          event_id = (
              dict() if not isinstance(event_id, dict) else event_id
          )
          return np.empty((0, 3), dtype=int), event_id
  
      annotations = raw.annotations
  
      event_id = _check_event_id(event_id, raw)
  
      event_sel, event_id_ = _select_annotations_based_on_description(
          annotations.description, event_id=event_id, regexp=regexp
      )
  
      if chunk_duration is None:
          inds = raw.time_as_index(
              annotations.onset,
              use_rounding=use_rounding,
              origin=annotations.orig_time,
          )
          if annotations.orig_time is not None:
              inds += raw.first_samp
          values = [
              event_id_[kk] for kk in annotations.description[event_sel]
          ]
          inds = inds[event_sel]
      else:
          inds = values = np.array([]).astype(int)
          for annot in annotations[event_sel]:
              annot_offset = annot["onset"] + annot["duration"]
              _onsets = np.arange(
                  start=annot["onset"],
                  stop=annot_offset,
                  step=chunk_duration,
              )
              good_events = annot_offset - _onsets >= chunk_duration
              if good_events.any():
                  _onsets = _onsets[good_events]
                  _inds = raw.time_as_index(
                      _onsets,
                      use_rounding=use_rounding,
                      origin=annotations.orig_time,
                  )
                  _inds += raw.first_samp
                  inds = np.append(inds, _inds)
                  _values = np.full(
                      shape=len(_inds),
                      fill_value=event_id_[annot["description"]],
                      dtype=int,
                  )
                  values = np.append(values, _values)
  
      events = np.c_[inds, np.zeros(len(inds)), values].astype(int)
  
      logger.info(
          f"Used Annotations descriptions: {list(event_id_.keys())}"
      )
  
      return events, event_id_
  
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 21 for calling a global function with example usage: events_from_annotations(raw, event_id, regexp, use_rounding, chunk_duration, verbose) and returns: events,  event_id_, np,  event_id