code: def _test_raw_reader(
      reader,
      test_preloading=True,
      test_kwargs=True,
      boundary_decimal=2,
      test_scaling=True,
      test_rank=True,
      **kwargs,
  ):
      """Test reading, writing and slicing of raw classes.
  
      Parameters
      ----------
      reader : function
          Function to test.
      test_preloading : bool
          Whether not preloading is implemented for the reader. If True, both
          cases and memory mapping to file are tested.
      test_kwargs : dict
          Test _init_kwargs support.
      boundary_decimal : int
          Number of decimals up to which the boundary should match.
      **kwargs :
          Arguments for the reader. Note: Do not use preload as kwarg.
          Use ``test_preloading`` instead.
  
      Returns
      -------
      raw : instance of Raw
          A preloaded Raw object.
      """
      tempdir = _TempDir()
      rng = np.random.RandomState(0)
      montage = None
      if "montage" in kwargs:
          montage = kwargs["montage"]
          del kwargs["montage"]
      if test_preloading:
          raw = reader(preload=True, **kwargs)
          rep = repr(raw)
          assert rep.count("<") == 1
          assert rep.count(">") == 1
          if montage is not None:
              raw.set_montage(montage)
          # don't assume the first is preloaded
          buffer_fname = op.join(tempdir, "buffer")
          picks = rng.permutation(np.arange(len(raw.ch_names) - 1))[:10]
          picks = np.append(
              picks, len(raw.ch_names) - 1
          )  # test trigger channel
          bnd = min(
              int(round(raw.buffer_size_sec * raw.info["sfreq"])),
              raw.n_times,
          )
          slices = [
              slice(0, bnd),
              slice(bnd - 1, bnd),
              slice(3, bnd),
              slice(3, 300),
              slice(None),
              slice(1, bnd),
          ]
          if raw.n_times >= 2 * bnd:  # at least two complete blocks
              slices += [
                  slice(bnd, 2 * bnd),
                  slice(bnd, bnd + 1),
                  slice(0, bnd + 100),
              ]
          other_raws = [
              reader(preload=buffer_fname, **kwargs),
              reader(preload=False, **kwargs),
          ]
          for sl_time in slices:
              data1, times1 = raw[picks, sl_time]
              for other_raw in other_raws:
                  data2, times2 = other_raw[picks, sl_time]
                  assert_allclose(
                      data1, data2, err_msg="Data mismatch with preload"
                  )
                  assert_allclose(times1, times2)
  
          # test projection vs cals and data units
          other_raw = reader(preload=False, **kwargs)
          other_raw.del_proj()
          eeg = meg = fnirs = seeg = eyetrack = False
          if "eeg" in raw:
              eeg, atol = True, 1e-18
          elif "grad" in raw:
              meg, atol = "grad", 1e-24
          elif "mag" in raw:
              meg, atol = "mag", 1e-24
          elif "hbo" in raw:
              fnirs, atol = "hbo", 1e-10
          elif "hbr" in raw:
              fnirs, atol = "hbr", 1e-10
          elif "fnirs_cw_amplitude" in raw:
              fnirs, atol = "fnirs_cw_amplitude", 1e-10
          elif "eyegaze" in raw:
              eyetrack = "eyegaze", 1e-3
          else:
              # e.g., https://github.com/mne-tools/mne-python/pull/11432/files
              assert (
                  "seeg" in raw
              ), "New channel type necessary? See gh-11432 for example"
              seeg, atol = True, 1e-18
  
          picks = pick_types(
              other_raw.info,
              meg=meg,
              eeg=eeg,
              fnirs=fnirs,
              seeg=seeg,
              eyetrack=eyetrack,
          )
          col_names = [other_raw.ch_names[pick] for pick in picks]
          proj = np.ones((1, len(picks)))
          proj /= np.sqrt(proj.shape[1])
          proj = Projection(
              data=dict(
                  data=proj,
                  nrow=1,
                  row_names=None,
                  col_names=col_names,
                  ncol=len(picks),
              ),
              active=False,
          )
          assert len(other_raw.info["projs"]) == 0
          other_raw.add_proj(proj)
          assert len(other_raw.info["projs"]) == 1
          # Orders of projector application, data loading, and reordering
          # equivalent:
          # 1. load->apply->get
          data_load_apply_get = (
              other_raw.copy().load_data().apply_proj().get_data(picks)
          )
          # 2. apply->get (and don't allow apply->pick)
          apply = other_raw.copy().apply_proj()
          data_apply_get = apply.get_data(picks)
          data_apply_get_0 = apply.get_data(picks[0])[0]
          with pytest.raises(RuntimeError, match="loaded"):
              apply.copy().pick(picks[0]).get_data()
          # 3. apply->load->get
          data_apply_load_get = apply.copy().load_data().get_data(picks)
          data_apply_load_get_0, data_apply_load_get_1 = (
              apply.copy().load_data().pick(picks[:2]).get_data()
          )
          # 4. reorder->apply->load->get
          all_picks = np.arange(len(other_raw.ch_names))
          reord = np.concatenate(
              (picks[1::2], picks[0::2], np.setdiff1d(all_picks, picks))
          )
          rev = np.argsort(reord)
          assert_array_equal(reord[rev], all_picks)
          assert_array_equal(rev[reord], all_picks)
          reorder = other_raw.copy().pick(reord)
          assert reorder.ch_names == [
              other_raw.ch_names[r] for r in reord
          ]
          assert reorder.ch_names[0] == other_raw.ch_names[picks[1]]
          assert_allclose(
              reorder.get_data([0]), other_raw.get_data(picks[1])
          )
          reorder_apply = reorder.copy().apply_proj()
          assert reorder_apply.ch_names == reorder.ch_names
          assert reorder_apply.ch_names[0] == apply.ch_names[picks[1]]
          assert_allclose(
              reorder_apply.get_data([0]),
              apply.get_data(picks[1]),
              atol=1e-18,
          )
          data_reorder_apply_load_get = (
              reorder_apply.load_data().get_data(rev[: len(picks)])
          )
          data_reorder_apply_load_get_1 = (
              reorder_apply.copy().load_data().pick([0]).get_data()[0]
          )
          assert reorder_apply.ch_names[0] == apply.ch_names[picks[1]]
          assert (
              data_load_apply_get.shape
              == data_apply_get.shape
              == data_apply_load_get.shape
              == data_reorder_apply_load_get.shape
          )
          del apply
          # first check that our data are (probably) in the right units
          data = data_load_apply_get.copy()
          data = data - np.mean(
              data, axis=1, keepdims=True
          )  # can be offsets
          np.abs(data, out=data)
          if test_scaling:
              maxval = atol * 1e16
              assert_array_less(data, maxval)
              minval = atol * 1e6
              assert_array_less(minval, np.median(data))
          else:
              atol = 1e-7 * np.median(data)  # 1e-7 * MAD
          # ranks should all be reduced by 1
          if test_rank == "less":
              cmp = np.less
          elif test_rank is False:
              cmp = None
          else:  # anything else is like True or 'equal'
              assert (
                  test_rank is True or test_rank == "equal"
              ), test_rank
              cmp = np.equal
          rank_load_apply_get = np.linalg.matrix_rank(
              data_load_apply_get
          )
          rank_apply_get = np.linalg.matrix_rank(data_apply_get)
          rank_apply_load_get = np.linalg.matrix_rank(
              data_apply_load_get
          )
          if cmp is not None:
              assert cmp(rank_load_apply_get, len(col_names) - 1)
              assert cmp(rank_apply_get, len(col_names) - 1)
              assert cmp(rank_apply_load_get, len(col_names) - 1)
          # and they should all match
          t_kw = dict(
              atol=atol,
              err_msg="before != after, likely _mult_cal_one prob",
          )
          assert_allclose(data_apply_get[0], data_apply_get_0, **t_kw)
          assert_allclose(
              data_apply_load_get_1,
              data_reorder_apply_load_get_1,
              **t_kw,
          )
          assert_allclose(
              data_load_apply_get[0], data_apply_load_get_0, **t_kw
          )
          assert_allclose(data_load_apply_get, data_apply_get, **t_kw)
          assert_allclose(
              data_load_apply_get, data_apply_load_get, **t_kw
          )
          if "eeg" in raw:
              other_raw.del_proj()
              direct = (
                  other_raw.copy()
                  .load_data()
                  .set_eeg_reference()
                  .get_data()
              )
              other_raw.set_eeg_reference(projection=True)
              assert len(other_raw.info["projs"]) == 1
              this_proj = other_raw.info["projs"][0]["data"]
              assert this_proj["col_names"] == col_names
              assert (
                  this_proj["data"].shape == proj["data"]["data"].shape
              )
              assert_allclose(
                  np.linalg.norm(proj["data"]["data"]), 1.0, atol=1e-6
              )
              assert_allclose(
                  np.linalg.norm(this_proj["data"]), 1.0, atol=1e-6
              )
              assert_allclose(this_proj["data"], proj["data"]["data"])
              proj = other_raw.apply_proj().get_data()
              assert_allclose(
                  proj[picks], data_load_apply_get, atol=1e-10
              )
              assert_allclose(
                  proj, direct, atol=1e-10, err_msg=t_kw["err_msg"]
              )
      else:
          raw = reader(**kwargs)
      n_samp = len(raw.times)
      assert_named_constants(raw.info)
      assert_attributes(raw)
      # smoke test for gh #9743
      ids = [id(ch["loc"]) for ch in raw.info["chs"]]
      assert len(set(ids)) == len(ids)
  
      full_data = raw._data
      assert raw.__class__.__name__ in repr(raw)  # to test repr
      assert raw.info.__class__.__name__ in repr(raw.info)
      assert isinstance(raw.info["dig"], (type(None), list))
      data_max = np.nanmax(full_data)
      data_min = np.nanmin(full_data)
      # these limits could be relaxed if we actually find data with
      # huge values (in SI units)
      assert data_max < 1e5
      assert data_min > -1e5
      if isinstance(raw.info["dig"], list):
          for di, d in enumerate(raw.info["dig"]):
              assert isinstance(d, DigPoint), (di, d)
  
      # gh-5604
      meas_date = raw.info["meas_date"]
      assert meas_date is None or meas_date >= _stamp_to_dt((0, 0))
  
      # test repr_html
      assert "Good channels" in raw._repr_html_()
  
      # test resetting raw
      if test_kwargs:
          raw2 = reader(**raw._init_kwargs)
          assert set(raw.info.keys()) == set(raw2.info.keys())
          assert_array_equal(raw.times, raw2.times)
  
      # Test saving and reading
      out_fname = op.join(tempdir, "test_raw.fif")
      raw = concatenate_raws([raw])
      raw.save(
          out_fname,
          tmax=raw.times[-1],
          overwrite=True,
          buffer_size_sec=1,
      )
  
      # Test saving with not correct extension
      out_fname_h5 = op.join(tempdir, "test_raw.h5")
      with pytest.raises(
          OSError, match="raw must end with .fif or .fif.gz"
      ):
          raw.save(out_fname_h5)
  
      raw3 = read_raw_fif(out_fname)
      assert_named_constants(raw3.info)
      assert set(raw.info.keys()) == set(raw3.info.keys())
      assert_allclose(
          raw3[0:20][0], full_data[0:20], rtol=1e-6, atol=1e-20
      )  # atol is very small but > 0
      assert_allclose(raw.times, raw3.times, atol=1e-6, rtol=1e-6)
  
      assert not math.isnan(raw3.info["highpass"])
      assert not math.isnan(raw3.info["lowpass"])
      assert not math.isnan(raw.info["highpass"])
      assert not math.isnan(raw.info["lowpass"])
  
      assert raw3.info["kit_system_id"] == raw.info["kit_system_id"]
  
      # Make sure concatenation works
      first_samp = raw.first_samp
      last_samp = raw.last_samp
      concat_raw = concatenate_raws([raw.copy(), raw])
      assert concat_raw.n_times == 2 * raw.n_times
      assert concat_raw.first_samp == first_samp
      assert (
          concat_raw.last_samp - last_samp + first_samp == last_samp + 1
      )
      idx = np.where(
          concat_raw.annotations.description == "BAD boundary"
      )[0]
  
      expected_bad_boundary_onset = raw._last_time
  
      assert_array_almost_equal(
          concat_raw.annotations.onset[idx],
          expected_bad_boundary_onset,
          decimal=boundary_decimal,
      )
  
      if raw.info["meas_id"] is not None:
          for key in ["secs", "usecs", "version"]:
              assert (
                  raw.info["meas_id"][key] == raw3.info["meas_id"][key]
              )
          assert_array_equal(
              raw.info["meas_id"]["machid"],
              raw3.info["meas_id"]["machid"],
          )
  
      assert isinstance(raw.annotations, Annotations)
  
      # Make a "soft" test on units: They have to be valid SI units as in
      # mne.io.meas_info.valid_units, but we accept any lower/upper case for now.
      valid_units = _get_valid_units()
      valid_units_lower = [unit.lower() for unit in valid_units]
      if raw._orig_units is not None:
          assert isinstance(raw._orig_units, dict)
          for ch_name, unit in raw._orig_units.items():
              assert unit.lower() in valid_units_lower, ch_name
  
      # Test picking with and without preload
      if test_preloading:
          preload_kwargs = (dict(preload=True), dict(preload=False))
      else:
          preload_kwargs = (dict(),)
      n_ch = len(raw.ch_names)
      picks = rng.permutation(n_ch)
      for preload_kwarg in preload_kwargs:
          these_kwargs = kwargs.copy()
          these_kwargs.update(preload_kwarg)
          # don't use the same filename or it could create problems
          if isinstance(
              these_kwargs.get("preload", None), str
          ) and op.isfile(these_kwargs["preload"]):
              these_kwargs["preload"] += "-1"
          whole_raw = reader(**these_kwargs)
          print(whole_raw)  # __repr__
          assert n_ch >= 2
          picks_1 = picks[: n_ch // 2]
          picks_2 = picks[n_ch // 2 :]
          raw_1 = whole_raw.copy().pick(picks_1)
          raw_2 = whole_raw.copy().pick(picks_2)
          data, times = whole_raw[:]
          data_1, times_1 = raw_1[:]
          data_2, times_2 = raw_2[:]
          assert_array_equal(times, times_1)
          assert_array_equal(data[picks_1], data_1)
          assert_array_equal(
              times,
              times_2,
          )
          assert_array_equal(data[picks_2], data_2)
  
      # Make sure that writing info to h5 format
      # (all fields should be compatible)
      if check_version("h5io"):
          read_hdf5, write_hdf5 = _import_h5io_funcs()
          fname_h5 = op.join(tempdir, "info.h5")
          with _writing_info_hdf5(raw.info), _numpy_h5py_dep():
              write_hdf5(fname_h5, raw.info)
              new_info = Info(read_hdf5(fname_h5))
          assert object_diff(new_info, raw.info) == ""
  
      # Make sure that changing directory does not break anything
      if test_preloading:
          these_kwargs = kwargs.copy()
          key = None
          for key in (
              "fname",
              "input_fname",  # artemis123
              "vhdr_fname",  # BV
              "pdf_fname",  # BTi
              "directory",  # CTF
              "filename",  # nedf
          ):
              try:
                  fname = kwargs[key]
              except KeyError:
                  key = None
              else:
                  break
          # len(kwargs) == 0 for the fake arange reader
          if len(kwargs):
              assert key is not None, sorted(kwargs.keys())
              this_fname = (
                  fname[0] if isinstance(fname, list) else fname
              )
              dirname = op.dirname(this_fname)
              these_kwargs[key] = op.basename(this_fname)
              these_kwargs["preload"] = False
              orig_dir = os.getcwd()
              try:
                  os.chdir(dirname)
                  raw_chdir = reader(**these_kwargs)
              finally:
                  os.chdir(orig_dir)
              raw_chdir.load_data()
  
      # make sure that cropping works (with first_samp shift)
      if n_samp >= 50:  # we crop to this number of samples below
          for t_prop in (0.0, 0.5):
              _test_raw_crop(reader, t_prop, kwargs)
              if test_preloading:
                  use_kwargs = kwargs.copy()
                  use_kwargs["preload"] = True
                  _test_raw_crop(reader, t_prop, use_kwargs)
  
      # make sure electrode-like sensor locations show up as dig points
      eeg_dig = [
          d
          for d in (raw.info["dig"] or [])
          if d["kind"] == _dig_kind_dict["eeg"]
      ]
      pick_kwargs = dict()
      for t in _ELECTRODE_CH_TYPES + ("fnirs",):
          pick_kwargs[t] = True
      dig_picks = pick_types(raw.info, exclude=(), **pick_kwargs)
      dig_types = _ELECTRODE_CH_TYPES + _FNIRS_CH_TYPES_SPLIT
      assert (len(dig_picks) > 0) == any(t in raw for t in dig_types)
      if len(dig_picks):
          eeg_loc = np.array(
              [  # eeg_loc a bit of a misnomer to match eeg_dig
                  raw.info["chs"][pick]["loc"][:3] for pick in dig_picks
              ]
          )
          eeg_loc = eeg_loc[np.isfinite(eeg_loc).all(axis=1)]
          if len(eeg_loc):
              if "fnirs_cw_amplitude" in raw:
                  assert 2 * len(eeg_dig) >= len(eeg_loc)
              else:
                  assert len(eeg_dig) >= len(
                      eeg_loc
                  )  # could have some excluded
      # make sure that dig points in head coords implies that fiducials are
      # present
      if len(raw.info["dig"] or []) > 0:
          card_pts = [
              d
              for d in raw.info["dig"]
              if d["kind"] == _dig_kind_dict["cardinal"]
          ]
          eeg_dig_head = [
              d
              for d in eeg_dig
              if d["coord_frame"] == FIFF.FIFFV_COORD_HEAD
          ]
          if len(eeg_dig_head):
              assert len(card_pts) == 3, "Cardinal points missing"
          if (
              len(card_pts) == 3
          ):  # they should all be in head coords then
              assert len(eeg_dig_head) == len(eeg_dig)
  
      return raw
  
imports: import math
  import os
  import re
  from contextlib import redirect_stdout
  from io import StringIO
  from os import path
  from pathlib import Path
  import numpy
  import pytest
  from numpy.testing import assert_allclose, assert_array_almost_equal, assert_array_equal, assert_array_less
  import mne
  from mne import Annotations, concatenate_raws, create_info, pick_types
  from mne._fiff._digitization import DigPoint, _dig_kind_dict
  from mne._fiff.constants import FIFF
  from mne._fiff.meas_info import Info, _get_valid_units, _writing_info_hdf5
  from mne._fiff.pick import _ELECTRODE_CH_TYPES, _FNIRS_CH_TYPES_SPLIT
  from mne._fiff.proj import Projection
  from mne._fiff.utils import _mult_cal_one
  from mne.fixes import _numpy_h5py_dep
  from mne.io import BaseRaw, RawArray, read_raw_fif
  from mne.io.base import _get_scaling
  from mne.transforms import Transform
  from mne.utils import _import_h5io_funcs, _raw_annot, _stamp_to_dt, _TempDir, catch_logging, check_version, object_diff
label_desc: Use image node_id 4 for calling a global function with example usage: _test_raw_reader(reader, test_preloading, test_kwargs, boundary_decimal, test_scaling, test_rank) and returns: raw