code: def test_add_reference():
      """Test adding a reference."""
      raw = read_raw_fif(fif_fname, preload=True)
      picks_eeg = pick_types(raw.info, meg=False, eeg=True)
      # check if channel already exists
      pytest.raises(
          ValueError,
          add_reference_channels,
          raw,
          raw.info["ch_names"][0],
      )
      # add reference channel to Raw
      raw_ref = add_reference_channels(raw, "Ref", copy=True)
      assert_equal(raw_ref._data.shape[0], raw._data.shape[0] + 1)
      assert_array_equal(
          raw._data[picks_eeg, :], raw_ref._data[picks_eeg, :]
      )
      _check_channel_names(raw_ref, "Ref")
  
      orig_nchan = raw.info["nchan"]
      raw = add_reference_channels(raw, "Ref", copy=False)
      assert_array_equal(raw._data, raw_ref._data)
      assert_equal(raw.info["nchan"], orig_nchan + 1)
      _check_channel_names(raw, "Ref")
  
      # for Neuromag fif's, the reference electrode location is placed in
      # elements [3:6] of each "data" electrode location
      assert_allclose(
          raw.info["chs"][-1]["loc"][:3],
          raw.info["chs"][picks_eeg[0]]["loc"][3:6],
          1e-6,
      )
  
      ref_idx = raw.ch_names.index("Ref")
      ref_data, _ = raw[ref_idx]
      assert_array_equal(ref_data, 0)
  
      # add reference channel to Raw when no digitization points exist
      raw = read_raw_fif(fif_fname).crop(0, 1).load_data()
      picks_eeg = pick_types(raw.info, meg=False, eeg=True)
      del raw.info["dig"]
  
      raw_ref = add_reference_channels(raw, "Ref", copy=True)
  
      assert_equal(raw_ref._data.shape[0], raw._data.shape[0] + 1)
      assert_array_equal(
          raw._data[picks_eeg, :], raw_ref._data[picks_eeg, :]
      )
      _check_channel_names(raw_ref, "Ref")
  
      orig_nchan = raw.info["nchan"]
      raw = add_reference_channels(raw, "Ref", copy=False)
      assert_array_equal(raw._data, raw_ref._data)
      assert_equal(raw.info["nchan"], orig_nchan + 1)
      _check_channel_names(raw, "Ref")
  
      # Test adding an existing channel as reference channel
      pytest.raises(
          ValueError,
          add_reference_channels,
          raw,
          raw.info["ch_names"][0],
      )
  
      # add two reference channels to Raw
      raw_ref = add_reference_channels(raw, ["M1", "M2"], copy=True)
      _check_channel_names(raw_ref, ["M1", "M2"])
      assert_equal(raw_ref._data.shape[0], raw._data.shape[0] + 2)
      assert_array_equal(
          raw._data[picks_eeg, :], raw_ref._data[picks_eeg, :]
      )
      assert_array_equal(raw_ref._data[-2:, :], 0)
  
      raw = add_reference_channels(raw, ["M1", "M2"], copy=False)
      _check_channel_names(raw, ["M1", "M2"])
      ref_idx = raw.ch_names.index("M1")
      ref_idy = raw.ch_names.index("M2")
      ref_data, _ = raw[[ref_idx, ref_idy]]
      assert_array_equal(ref_data, 0)
  
      # add reference channel to epochs
      raw = read_raw_fif(fif_fname, preload=True)
      events = read_events(eve_fname)
      picks_eeg = pick_types(raw.info, meg=False, eeg=True)
      epochs = Epochs(
          raw,
          events=events,
          event_id=1,
          tmin=-0.2,
          tmax=0.5,
          picks=picks_eeg,
          preload=True,
      )
      # default: proj=True, after which adding a Ref channel is prohibited
      pytest.raises(RuntimeError, add_reference_channels, epochs, "Ref")
  
      # create epochs in delayed mode, allowing removal of CAR when re-reffing
      epochs = Epochs(
          raw,
          events=events,
          event_id=1,
          tmin=-0.2,
          tmax=0.5,
          picks=picks_eeg,
          preload=True,
          proj="delayed",
      )
      epochs_ref = add_reference_channels(epochs, "Ref", copy=True)
  
      assert_equal(epochs_ref._data.shape[1], epochs._data.shape[1] + 1)
      _check_channel_names(epochs_ref, "Ref")
      ref_idx = epochs_ref.ch_names.index("Ref")
      ref_data = epochs_ref.get_data(picks=[ref_idx])[:, 0]
      assert_array_equal(ref_data, 0)
      picks_eeg = pick_types(epochs.info, meg=False, eeg=True)
      assert_array_equal(
          epochs.get_data(picks_eeg), epochs_ref.get_data(picks_eeg)
      )
  
      # add two reference channels to epochs
      raw = read_raw_fif(fif_fname, preload=True)
      events = read_events(eve_fname)
      picks_eeg = pick_types(raw.info, meg=False, eeg=True)
      # create epochs in delayed mode, allowing removal of CAR when re-reffing
      epochs = Epochs(
          raw,
          events=events,
          event_id=1,
          tmin=-0.2,
          tmax=0.5,
          picks=picks_eeg,
          preload=True,
          proj="delayed",
      )
      with pytest.warns(
          RuntimeWarning, match="reference channels are ignored"
      ):
          epochs_ref = add_reference_channels(
              epochs, ["M1", "M2"], copy=True
          )
      assert_equal(epochs_ref._data.shape[1], epochs._data.shape[1] + 2)
      _check_channel_names(epochs_ref, ["M1", "M2"])
      ref_idx = epochs_ref.ch_names.index("M1")
      ref_idy = epochs_ref.ch_names.index("M2")
      assert_equal(epochs_ref.info["chs"][ref_idx]["ch_name"], "M1")
      assert_equal(epochs_ref.info["chs"][ref_idy]["ch_name"], "M2")
      ref_data = epochs_ref.get_data([ref_idx, ref_idy])
      assert_array_equal(ref_data, 0)
      picks_eeg = pick_types(epochs.info, meg=False, eeg=True)
      assert_array_equal(
          epochs.get_data(picks_eeg), epochs_ref.get_data(picks_eeg)
      )
  
      # add reference channel to evoked
      raw = read_raw_fif(fif_fname, preload=True)
      events = read_events(eve_fname)
      picks_eeg = pick_types(raw.info, meg=False, eeg=True)
      # create epochs in delayed mode, allowing removal of CAR when re-reffing
      epochs = Epochs(
          raw,
          events=events,
          event_id=1,
          tmin=-0.2,
          tmax=0.5,
          picks=picks_eeg,
          preload=True,
          proj="delayed",
      )
      evoked = epochs.average()
      evoked_ref = add_reference_channels(evoked, "Ref", copy=True)
      assert_equal(evoked_ref.data.shape[0], evoked.data.shape[0] + 1)
      _check_channel_names(evoked_ref, "Ref")
      ref_idx = evoked_ref.ch_names.index("Ref")
      ref_data = evoked_ref.data[ref_idx, :]
      assert_array_equal(ref_data, 0)
      picks_eeg = pick_types(evoked.info, meg=False, eeg=True)
      assert_array_equal(
          evoked.data[picks_eeg, :], evoked_ref.data[picks_eeg, :]
      )
  
      # add two reference channels to evoked
      raw = read_raw_fif(fif_fname, preload=True)
      events = read_events(eve_fname)
      picks_eeg = pick_types(raw.info, meg=False, eeg=True)
      # create epochs in delayed mode, allowing removal of CAR when re-reffing
      epochs = Epochs(
          raw,
          events=events,
          event_id=1,
          tmin=-0.2,
          tmax=0.5,
          picks=picks_eeg,
          preload=True,
          proj="delayed",
      )
      evoked = epochs.average()
      with pytest.warns(
          RuntimeWarning, match="reference channels are ignored"
      ):
          evoked_ref = add_reference_channels(
              evoked, ["M1", "M2"], copy=True
          )
      assert_equal(evoked_ref.data.shape[0], evoked.data.shape[0] + 2)
      _check_channel_names(evoked_ref, ["M1", "M2"])
      ref_idx = evoked_ref.ch_names.index("M1")
      ref_idy = evoked_ref.ch_names.index("M2")
      ref_data = evoked_ref.data[[ref_idx, ref_idy], :]
      assert_array_equal(ref_data, 0)
      picks_eeg = pick_types(evoked.info, meg=False, eeg=True)
      assert_array_equal(
          evoked.data[picks_eeg, :], evoked_ref.data[picks_eeg, :]
      )
  
      # Test invalid inputs
      raw = read_raw_fif(fif_fname, preload=False)
      with pytest.raises(RuntimeError, match="loaded"):
          add_reference_channels(raw, ["Ref"])
      raw.load_data()
      with pytest.raises(ValueError, match="Channel.*already.*"):
          add_reference_channels(raw, raw.ch_names[:1])
      with pytest.raises(TypeError, match="instance of"):
          add_reference_channels(raw, 1)
  
      # gh-10878
      raw = (
          read_raw_fif(raw_fname)
          .crop(0, 1, include_tmax=False)
          .load_data()
      )
      data = (
          raw.copy().add_reference_channels(["REF"]).pick(picks="eeg")
      )
      data = data.get_data()
      epochs = make_fixed_length_epochs(raw).load_data()
      data_2 = (
          epochs.copy()
          .add_reference_channels(["REF"])
          .pick(picks="eeg")
      )
      data_2 = data_2.get_data(copy=False)[0]
      assert_allclose(data, data_2)
      evoked = epochs.average()
      data_3 = (
          evoked.copy()
          .add_reference_channels(["REF"])
          .pick(picks="eeg")
      )
      data_3 = data_3.get_data()
      assert_allclose(data, data_3)
  
imports: import itertools
  from contextlib import nullcontext
  from pathlib import Path
  import numpy
  import pytest
  from numpy.testing import assert_allclose, assert_array_equal, assert_equal
  from mne import Epochs, Projection, add_reference_channels, create_info, find_events, make_forward_solution, make_sphere_model, pick_channels, pick_channels_forward, pick_types, read_events, read_evokeds, set_bipolar_reference, set_eeg_reference, setup_volume_source_space
  from mne._fiff.constants import FIFF
  from mne._fiff.proj import _has_eeg_average_ref_proj
  from mne._fiff.reference import _apply_reference
  from mne.datasets import testing
  from mne.epochs import BaseEpochs, make_fixed_length_epochs
  from mne.io import RawArray, read_raw_fif
  from mne.utils import _record_warnings, catch_logging
label_desc: Use image node_id 8 for calling a global function with example usage: test_add_reference() without return types