code: def annotations_from_events(
      events,
      sfreq,
      event_desc=None,
      first_samp=0,
      orig_time=None,
      verbose=None,
  ):
      """Convert an event array to an Annotations object.
  
      Parameters
      ----------
      events : ndarray, shape (n_events, 3)
          The events.
      sfreq : float
          Sampling frequency.
      event_desc : dict | array-like | callable | None
          Events description. Can be:
  
          - **dict**: map integer event codes (keys) to descriptions (values).
            Only the descriptions present will be mapped, others will be ignored.
          - **array-like**: list, or 1d array of integers event codes to include.
            Only the event codes present will be mapped, others will be ignored.
            Event codes will be passed as string descriptions.
          - **callable**: must take a integer event code as input and return a
            string description or None to ignore it.
          - **None**: Use integer event codes as descriptions.
      first_samp : int
          The first data sample (default=0). See :attr:`mne.io.Raw.first_samp`
          docstring.
      orig_time : float | str | datetime | tuple of int | None
          Determines the starting time of annotation acquisition. If None
          (default), starting time is determined from beginning of raw data
          acquisition. For details, see :meth:`mne.Annotations` docstring.
      %(verbose)s
  
      Returns
      -------
      annot : instance of Annotations
          The annotations.
  
      See Also
      --------
      mne.events_from_annotations
  
      Notes
      -----
      Annotations returned by this function will all have zero (null) duration.
  
      Creating events from annotations via the function
      `mne.events_from_annotations` takes in event mappings with
      key→value pairs as description→ID, whereas `mne.annotations_from_events`
      takes in event mappings with key→value pairs as ID→description.
      If you need to use these together, you can invert the mapping by doing::
  
          event_desc = {v: k for k, v in event_id.items()}
      """
      event_desc = _check_event_description(event_desc, events)
      event_sel, event_desc_ = _select_events_based_on_id(
          events, event_desc
      )
      events_sel = events[event_sel]
      onsets = (events_sel[:, 0] - first_samp) / sfreq
      descriptions = [event_desc_[e[2]] for e in events_sel]
      durations = np.zeros(len(events_sel))  # dummy durations
  
      # Create annotations
      annots = Annotations(
          onset=onsets,
          duration=durations,
          description=descriptions,
          orig_time=orig_time,
      )
  
      return annots
  
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 22 for calling a global function with example usage: annotations_from_events(events, sfreq, event_desc, first_samp, orig_time, verbose) and returns: annots