code: def test_make_forward_dipole(tmp_path):
      """Test forward-projecting dipoles."""
      rng = np.random.RandomState(0)
  
      evoked = read_evokeds(fname_evo)[0]
      cov = read_cov(fname_cov)
      cov["projs"] = []  # avoid proj warning
      dip_c = read_dipole(fname_dip)
  
      # Only use magnetometers for speed!
      picks = pick_types(evoked.info, meg="mag", eeg=False)[::8]
      evoked.pick([evoked.ch_names[p] for p in picks])
      evoked.info.normalize_proj()
      info = evoked.info
  
      # Make new Dipole object with n_test_dipoles picked from the dipoles
      # in the test dataset.
      n_test_dipoles = (
          3  # minimum 3 needed to get uneven sampling in time
      )
      dipsel = np.sort(
          rng.permutation(np.arange(len(dip_c)))[:n_test_dipoles]
      )
      dip_test = Dipole(
          times=dip_c.times[dipsel],
          pos=dip_c.pos[dipsel],
          amplitude=dip_c.amplitude[dipsel],
          ori=dip_c.ori[dipsel],
          gof=dip_c.gof[dipsel],
      )
  
      sphere = make_sphere_model(head_radius=0.1)
  
      # Warning emitted due to uneven sampling in time
      with pytest.warns(RuntimeWarning, match="unevenly spaced"):
          fwd, stc = make_forward_dipole(
              dip_test, sphere, info, trans=fname_trans
          )
  
      # stc is list of VolSourceEstimate's
      assert isinstance(stc, list)
      for n_dip in range(n_test_dipoles):
          assert isinstance(stc[n_dip], VolSourceEstimate)
  
      # Now simulate evoked responses for each of the test dipoles,
      # and fit dipoles to them (sphere model, MEG and EEG)
      times, pos, amplitude, ori, gof = [], [], [], [], []
      nave = 400  # add a tiny amount of noise to the simulated evokeds
      for s in stc:
          evo_test = simulate_evoked(
              fwd, s, info, cov, nave=nave, random_state=rng
          )
          # evo_test.add_proj(make_eeg_average_ref_proj(evo_test.info))
          dfit, resid = fit_dipole(evo_test, cov, sphere, None)
          times += dfit.times.tolist()
          pos += dfit.pos.tolist()
          amplitude += dfit.amplitude.tolist()
          ori += dfit.ori.tolist()
          gof += dfit.gof.tolist()
  
      # Create a new Dipole object with the dipole fits
      dip_fit = Dipole(times, pos, amplitude, ori, gof)
  
      # check that true (test) dipoles and fits are "close"
      # cf. mne/tests/test_dipole.py
      diff = dip_test.pos - dip_fit.pos
      corr = np.corrcoef(dip_test.pos.ravel(), dip_fit.pos.ravel())[
          0, 1
      ]
      dist = np.sqrt(np.mean(np.sum(diff * diff, axis=1)))
      gc_dist = (
          180
          / np.pi
          * np.mean(
              np.arccos(np.sum(dip_test.ori * dip_fit.ori, axis=1))
          )
      )
      amp_err = np.sqrt(
          np.mean((dip_test.amplitude - dip_fit.amplitude) ** 2)
      )
  
      # Make sure each coordinate is close to reference
      # NB tolerance should be set relative to snr of simulated evoked!
      assert_allclose(
          dip_fit.pos,
          dip_test.pos,
          rtol=0,
          atol=1e-2,
          err_msg="position mismatch",
      )
      assert dist < 1e-2  # within 1 cm
      assert corr > 0.985
      assert gc_dist < 20  # less than 20 degrees
      assert amp_err < 10e-9  # within 10 nAm
  
      # Make sure rejection works with BEM: one dipole at z=1m
      # NB _make_forward.py:_prepare_for_forward will raise a RuntimeError
      # if no points are left after min_dist exclusions, hence 2 dips here!
      dip_outside = Dipole(
          times=[0.0, 0.001],
          pos=[[0.0, 0.0, 1.0], [0.0, 0.0, 0.040]],
          amplitude=[100e-9, 100e-9],
          ori=[[1.0, 0.0, 0.0], [1.0, 0.0, 0.0]],
          gof=1,
      )
      with pytest.raises(ValueError, match="outside the inner skull"):
          make_forward_dipole(dip_outside, fname_bem, info, fname_trans)
      # if we get this far, can safely assume the code works with BEMs too
      # -> use sphere again below for speed
  
      # Now make an evenly sampled set of dipoles, some simultaneous,
      # should return a VolSourceEstimate regardless
      times = [0.0, 0.0, 0.0, 0.001, 0.001, 0.002]
      pos = (
          np.random.rand(6, 3) * 0.020
          + np.array([0.0, 0.0, 0.040])[np.newaxis, :]
      )
      amplitude = np.random.rand(6) * 100e-9
      ori = np.eye(6, 3) + np.eye(6, 3, -3)
      gof = np.arange(len(times)) / len(times)  # arbitrary
  
      dip_even_samp = Dipole(times, pos, amplitude, ori, gof)
  
      # I/O round-trip
      fname = str(tmp_path / "test-fwd.fif")
      with pytest.warns(RuntimeWarning, match="free orientation"):
          write_forward_solution(fname, fwd)
      fwd_read = convert_forward_solution(
          read_forward_solution(fname), force_fixed=True
      )
      assert_forward_allclose(fwd, fwd_read, rtol=1e-6)
  
      fwd, stc = make_forward_dipole(
          dip_even_samp, sphere, info, trans=fname_trans
      )
      assert isinstance(stc, VolSourceEstimate)
      assert_allclose(stc.times, np.arange(0.0, 0.003, 0.001))
  
      # Test passing a list of Dipoles instead of a single Dipole object
      fwd2, stc2 = make_forward_dipole(
          [dip_even_samp[0], dip_even_samp[1:]],
          sphere,
          info,
          trans=fname_trans,
      )
      assert_array_equal(fwd["sol"]["data"], fwd2["sol"]["data"])
      assert_array_equal(stc.data, stc2.data)
  
imports: from itertools import product
  from pathlib import Path
  import numpy
  import pytest
  from numpy.testing import assert_allclose, assert_array_equal, assert_array_less
  from mne import convert_forward_solution, create_info, get_volume_labels_from_aseg, make_forward_solution, make_sphere_model, pick_info, pick_types, pick_types_forward, read_cov, read_dipole, read_evokeds, read_forward_solution, read_source_spaces, setup_volume_source_space, write_forward_solution
  from mne._fiff.constants import FIFF
  from mne.bem import make_bem_solution, read_bem_surfaces
  from mne.channels import make_standard_montage
  from mne.datasets import testing
  from mne.dipole import Dipole, fit_dipole
  from mne.forward import Forward, _do_forward_solution, use_coil_def
  from mne.forward._compute_forward import _magnetic_dipole_field_vec
  from mne.forward._make_forward import _create_meg_coils, make_forward_dipole
  from mne.forward.tests.test_forward import assert_forward_allclose
  from mne.io import read_info, read_raw_bti, read_raw_fif, read_raw_kit
  from mne.simulation import simulate_evoked
  from mne.source_estimate import VolSourceEstimate
  from mne.source_space._source_space import _compare_source_spaces, setup_source_space, write_source_spaces
  from mne.surface import _get_ico_surface
  from mne.transforms import Transform
  from mne.utils import catch_logging, requires_mne, requires_mne_mark, requires_openmeeg_mark, run_subprocess
label_desc: Use image node_id 15 for calling a global function with example usage: test_make_forward_dipole(tmp_path) without return types