code: def read_events(
      filename,
      include=None,
      exclude=None,
      mask=None,
      mask_type="and",
      return_event_id=False,
      verbose=None,
  ):
      """Read :term:`events` from fif or text file.
  
      See :ref:`tut-events-vs-annotations` and :ref:`tut-event-arrays`
      for more information about events.
  
      Parameters
      ----------
      filename : path-like
          Name of the input file.
          If the extension is ``.fif``, events are read assuming
          the file is in FIF format, otherwise (e.g., ``.eve``,
          ``.lst``, ``.txt``) events are read as coming from text.
          Note that new format event files do not contain
          the ``"time"`` column (used to be the second column).
      include : int | list | None
          A event id to include or a list of them.
          If None all events are included.
      exclude : int | list | None
          A event id to exclude or a list of them.
          If None no event is excluded. If include is not None
          the exclude parameter is ignored.
      mask : int | None
          The value of the digital mask to apply to the stim channel values.
          If None (default), no masking is performed.
      mask_type : ``'and'`` | ``'not_and'``
          The type of operation between the mask and the trigger.
          Choose 'and' (default) for MNE-C masking behavior.
  
          .. versionadded:: 0.13
      return_event_id : bool
          If True, ``event_id`` will be returned. This is only possible for
          ``-annot.fif`` files produced with MNE-C ``mne_browse_raw``.
  
          .. versionadded:: 0.20
      %(verbose)s
  
      Returns
      -------
      %(events)s
      event_id : dict
          Dictionary of ``{str: int}`` mappings of event IDs.
  
      See Also
      --------
      find_events, write_events
  
      Notes
      -----
      This function will discard the offset line (i.e., first line with zero
      event number) if it is present in a text file.
  
      For more information on ``mask`` and ``mask_type``, see
      :func:`mne.find_events`.
      """
      check_fname(
          filename,
          "events",
          (
              ".eve",
              "-eve.fif",
              "-eve.fif.gz",
              "-eve.lst",
              "-eve.txt",
              "_eve.fif",
              "_eve.fif.gz",
              "_eve.lst",
              "_eve.txt",
              "-annot.fif",  # MNE-C annot
          ),
      )
      filename = Path(filename)
      if filename.suffix in (".fif", ".gz"):
          fid, tree, _ = fiff_open(filename)
          with fid as f:
              event_list, event_id = _read_events_fif(f, tree)
          # hack fix for windows to avoid bincount problems
          event_list = event_list.astype(int)
      else:
          #  Have to read this in as float64 then convert because old style
          #  eve/lst files had a second float column that will raise errors
          lines = np.loadtxt(filename, dtype=np.float64).astype(int)
          if len(lines) == 0:
              raise ValueError("No text lines found")
  
          if lines.ndim == 1:  # Special case for only one event
              lines = lines[np.newaxis, :]
  
          if len(lines[0]) == 4:  # Old format eve/lst
              goods = [0, 2, 3]  # Omit "time" variable
          elif len(lines[0]) == 3:
              goods = [0, 1, 2]
          else:
              raise ValueError(
                  "Unknown number of columns in event text file"
              )
  
          event_list = lines[:, goods]
          if (
              mask is not None
              and event_list.shape[0] > 0
              and event_list[0, 2] == 0
          ):
              event_list = event_list[1:]
              warn("first row of event file discarded (zero-valued)")
          event_id = None
  
      event_list = pick_events(event_list, include, exclude)
      unmasked_len = event_list.shape[0]
      if mask is not None:
          event_list = _mask_trigs(event_list, mask, mask_type)
          masked_len = event_list.shape[0]
          if masked_len < unmasked_len:
              warn(
                  f"{unmasked_len - masked_len} of {unmasked_len} events masked"
              )
      out = event_list
      if return_event_id:
          if event_id is None:
              raise RuntimeError("No event_id found in the file")
          out = (out, event_id)
      return out
  
imports: from collections.abc import Sequence
  from pathlib import Path
  import numpy
  from ._fiff.constants import FIFF
  from ._fiff.open import fiff_open
  from ._fiff.pick import pick_channels
  from ._fiff.tag import read_tag
  from ._fiff.tree import dir_tree_find
  from ._fiff.write import end_block, start_and_end_file, start_block, write_int
  from .utils import _check_fname, _check_integer_or_list, _check_on_missing, _check_option, _get_stim_channel, _on_missing, _pl, _validate_type, check_fname, fill_doc, logger, verbose, warn
label_desc: Use image node_id 4 for calling a global function with example usage: read_events(filename, include, exclude, mask, mask_type, return_event_id, verbose) and returns: out