code: def test_dipole_fitting(tmp_path):
      """Test dipole fitting."""
      pytest.importorskip("nibabel")
      amp = 100e-9
      rng = np.random.RandomState(0)
      fname_dtemp = tmp_path / "test.dip"
      fname_sim = tmp_path / "test-ave.fif"
      fwd = convert_forward_solution(
          read_forward_solution(fname_fwd),
          surf_ori=False,
          force_fixed=True,
          use_cps=True,
      )
      evoked = read_evokeds(fname_evo)[0]
      cov = read_cov(fname_cov)
      n_per_hemi = 5
      vertices = [
          np.sort(rng.permutation(s["vertno"])[:n_per_hemi])
          for s in fwd["src"]
      ]
      nv = sum(len(v) for v in vertices)
      stc = SourceEstimate(amp * np.eye(nv), vertices, 0, 0.001)
      evoked = simulate_evoked(
          fwd, stc, evoked.info, cov, nave=evoked.nave, random_state=rng
      )
      # For speed, let's use a subset of channels (strange but works)
      picks = np.sort(
          np.concatenate(
              [
                  pick_types(evoked.info, meg=True, eeg=False)[::2],
                  pick_types(evoked.info, meg=False, eeg=True)[::2],
              ]
          )
      )
      evoked.pick([evoked.ch_names[p] for p in picks])
      evoked.add_proj(make_eeg_average_ref_proj(evoked.info))
      write_evokeds(fname_sim, evoked)
  
      # Run MNE-C version
      run_subprocess(
          [
              "mne_dipole_fit",
              "--meas",
              fname_sim,
              "--meg",
              "--eeg",
              "--noise",
              fname_cov,
              "--dip",
              fname_dtemp,
              "--mri",
              fname_fwd,
              "--reg",
              "0",
              "--tmin",
              "0",
          ]
      )
      dip_c = read_dipole(fname_dtemp)
  
      # Run mne-python version
      sphere = make_sphere_model(head_radius=0.1)
      with pytest.warns(RuntimeWarning, match="projection"):
          dip, residual = fit_dipole(
              evoked, cov, sphere, fname_fwd, rank="info"
          )  # just to test rank support
      assert isinstance(residual, Evoked)
  
      # Test conversion of dip.pos to MNI coordinates.
      dip_mni_pos = dip.to_mni(
          "sample", fname_trans, subjects_dir=subjects_dir
      )
      head_to_mni_dip_pos = head_to_mni(
          dip.pos,
          "sample",
          fwd["mri_head_t"],
          subjects_dir=subjects_dir,
      )
      assert_allclose(
          dip_mni_pos, head_to_mni_dip_pos, rtol=1e-3, atol=0
      )
  
      # Test finding label for dip.pos in an aseg, also tests `to_mri`
      target_labels = [
          "Left-Cerebral-Cortex",
          "Unknown",
          "Left-Cerebral-Cortex",
          "Right-Cerebral-Cortex",
          "Left-Cerebral-Cortex",
          "Unknown",
          "Unknown",
          "Unknown",
          "Right-Cerebral-White-Matter",
          "Right-Cerebral-Cortex",
      ]
      labels = dip.to_volume_labels(
          fname_trans,
          subject="fsaverage",
          aseg="aseg",
          subjects_dir=subjects_dir,
      )
      assert labels == target_labels
  
      # Sanity check: do our residuals have less power than orig data?
      data_rms = np.sqrt(np.sum(evoked.data**2, axis=0))
      resi_rms = np.sqrt(np.sum(residual.data**2, axis=0))
      assert (data_rms > resi_rms * 0.95).all(), "%s (factor: %s)" % (
          (data_rms / resi_rms).min(),
          0.95,
      )
  
      # Compare to original points
      transform_surface_to(fwd["src"][0], "head", fwd["mri_head_t"])
      transform_surface_to(fwd["src"][1], "head", fwd["mri_head_t"])
      assert fwd["src"][0]["coord_frame"] == FIFF.FIFFV_COORD_HEAD
      src_rr = np.concatenate(
          [s["rr"][v] for s, v in zip(fwd["src"], vertices)], axis=0
      )
      src_nn = np.concatenate(
          [s["nn"][v] for s, v in zip(fwd["src"], vertices)], axis=0
      )
  
      # MNE-C skips the last "time" point :(
      out = dip.crop(dip_c.times[0], dip_c.times[-1])
      assert dip is out
      src_rr, src_nn = src_rr[:-1], src_nn[:-1]
  
      # check that we did about as well
      corrs, dists, gc_dists, amp_errs, gofs = [], [], [], [], []
      for d in (dip_c, dip):
          new = d.pos
          diffs = new - src_rr
          corrs += [np.corrcoef(src_rr.ravel(), new.ravel())[0, 1]]
          dists += [np.sqrt(np.mean(np.sum(diffs * diffs, axis=1)))]
          gc_dists += [
              180
              / np.pi
              * np.mean(np.arccos(np.sum(src_nn * d.ori, axis=1)))
          ]
          amp_errs += [np.sqrt(np.mean((amp - d.amplitude) ** 2))]
          gofs += [np.mean(d.gof)]
      # XXX possibly some OpenBLAS numerical differences make
      # things slightly worse for us
      factor = 0.7
      assert dists[0] / factor >= dists[1], "dists: %s" % dists
      assert corrs[0] * factor <= corrs[1], "corrs: %s" % corrs
      assert gc_dists[0] / factor >= gc_dists[1] * 0.8, (
          "gc-dists (ori): %s" % gc_dists
      )
      assert amp_errs[0] / factor >= amp_errs[1], (
          "amplitude errors: %s" % amp_errs
      )
      # This one is weird because our cov/sim/picking is weird
      assert gofs[0] * factor <= gofs[1] * 2, "gof: %s" % gofs
  
imports: import os
  import matplotlib.pyplot
  import numpy
  import pytest
  from numpy.testing import assert_allclose, assert_array_equal, assert_array_less
  from mne import Dipole, DipoleFixed, Epochs, Evoked, EvokedArray, SourceEstimate, convert_forward_solution, fit_dipole, head_to_mni, make_ad_hoc_cov, make_fixed_length_events, make_forward_solution, make_sphere_model, pick_info, pick_types, read_cov, read_dipole, read_evokeds, read_forward_solution, read_source_spaces, transform_surface_to, write_evokeds
  from mne._fiff.constants import FIFF
  from mne.bem import _bem_find_surface, read_bem_solution
  from mne.datasets import testing
  from mne.dipole import _BDIP_ERROR_KEYS, get_phantom_dipoles
  from mne.io import read_raw_ctf, read_raw_fif
  from mne.proj import make_eeg_average_ref_proj
  from mne.simulation import simulate_evoked
  from mne.surface import _compute_nearest
  from mne.transforms import _get_trans, apply_trans
  from mne.utils import _record_warnings, requires_mne, run_subprocess
label_desc: Use image node_id 5 for calling a global function with example usage: test_dipole_fitting(tmp_path) without return types