code: def make_forward_dipole(
      dipole, bem, info, trans=None, n_jobs=None, *, verbose=None
  ):
      """Convert dipole object to source estimate and calculate forward operator.
  
      The instance of Dipole is converted to a discrete source space,
      which is then combined with a BEM or a sphere model and
      the sensor information in info to form a forward operator.
  
      The source estimate object (with the forward operator) can be projected to
      sensor-space using :func:`mne.simulation.simulate_evoked`.
  
      .. note:: If the (unique) time points of the dipole object are unevenly
                spaced, the first output will be a list of single-timepoint
                source estimates.
  
      Parameters
      ----------
      %(dipole)s
      bem : str | dict
          The BEM filename (str) or a loaded sphere model (dict).
      info : instance of Info
          The measurement information dictionary. It is sensor-information etc.,
          e.g., from a real data file.
      trans : str | None
          The head<->MRI transform filename. Must be provided unless BEM
          is a sphere model.
      %(n_jobs)s
      %(verbose)s
  
      Returns
      -------
      fwd : instance of Forward
          The forward solution corresponding to the source estimate(s).
      stc : instance of VolSourceEstimate | list of VolSourceEstimate
          The dipoles converted to a discrete set of points and associated
          time courses. If the time points of the dipole are unevenly spaced,
          a list of single-timepoint source estimates are returned.
  
      See Also
      --------
      mne.simulation.simulate_evoked
  
      Notes
      -----
      .. versionadded:: 0.12.0
      """
      if isinstance(dipole, list):
          from ..dipole import (
              _concatenate_dipoles,
          )  # To avoid circular import
  
          dipole = _concatenate_dipoles(dipole)
  
      # Make copies to avoid mangling original dipole
      times = dipole.times.copy()
      pos = dipole.pos.copy()
      amplitude = dipole.amplitude.copy()
      ori = dipole.ori.copy()
  
      # Convert positions to discrete source space (allows duplicate rr & nn)
      # NB information about dipole orientation enters here, then no more
      sources = dict(rr=pos, nn=ori)
      # Dipole objects must be in the head frame
      src = _complete_vol_src(
          [_make_discrete_source_space(sources, coord_frame="head")]
      )
  
      # Forward operator created for channels in info (use pick_info to restrict)
      # Use defaults for most params, including min_dist
      fwd = make_forward_solution(
          info, trans, src, bem, n_jobs=n_jobs, verbose=verbose
      )
      # Convert from free orientations to fixed (in-place)
      convert_forward_solution(
          fwd,
          surf_ori=False,
          force_fixed=True,
          copy=False,
          use_cps=False,
          verbose=None,
      )
  
      # Check for omissions due to proximity to inner skull in
      # make_forward_solution, which will result in an exception
      if fwd["src"][0]["nuse"] != len(pos):
          inuse = fwd["src"][0]["inuse"].astype(bool)
          head = "The following dipoles are outside the inner skull boundary"
          msg = len(head) * "#" + "\n" + head + "\n"
          for t, pos in zip(
              times[np.logical_not(inuse)], pos[np.logical_not(inuse)]
          ):
              msg += "    t={:.0f} ms, pos=({:.0f}, {:.0f}, {:.0f}) mm\n".format(
                  t * 1000.0,
                  pos[0] * 1000.0,
                  pos[1] * 1000.0,
                  pos[2] * 1000.0,
              )
          msg += len(head) * "#"
          logger.error(msg)
          raise ValueError(
              "One or more dipoles outside the inner skull."
          )
  
      # multiple dipoles (rr and nn) per time instant allowed
      # uneven sampling in time returns list
      timepoints = np.unique(times)
      if len(timepoints) > 1:
          tdiff = np.diff(timepoints)
          if not np.allclose(tdiff, tdiff[0]):
              warn(
                  "Unique time points of dipoles unevenly spaced: returned "
                  "stc will be a list, one for each time point."
              )
              tstep = -1.0
          else:
              tstep = tdiff[0]
      elif len(timepoints) == 1:
          tstep = 0.001
  
      # Build the data matrix, essentially a block-diagonal with
      # n_rows: number of dipoles in total (dipole.amplitudes)
      # n_cols: number of unique time points in dipole.times
      # amplitude with identical value of times go together in one col (others=0)
      data = np.zeros((len(amplitude), len(timepoints)))  # (n_d, n_t)
      row = 0
      for tpind, tp in enumerate(timepoints):
          amp = amplitude[np.isin(times, tp)]
          data[row : row + len(amp), tpind] = amp
          row += len(amp)
  
      if tstep > 0:
          stc = VolSourceEstimate(
              data,
              vertices=[fwd["src"][0]["vertno"]],
              tmin=timepoints[0],
              tstep=tstep,
              subject=None,
          )
      else:  # Must return a list of stc, one for each time point
          stc = []
          for col, tp in enumerate(timepoints):
              stc += [
                  VolSourceEstimate(
                      data[:, col][:, np.newaxis],
                      vertices=[fwd["src"][0]["vertno"]],
                      tmin=tp,
                      tstep=0.001,
                      subject=None,
                  )
              ]
      return fwd, stc
  
imports: import os
  import os.path
  from contextlib import contextmanager
  from copy import deepcopy
  from pathlib import Path
  import numpy
  from .._fiff.compensator import get_current_comp, make_compensator
  from .._fiff.constants import FIFF, FWD
  from .._fiff.meas_info import Info, read_info
  from .._fiff.pick import _has_kit_refs, pick_info, pick_types
  from .._fiff.tag import _loc_to_coil_trans, _loc_to_eeg_loc
  from ..bem import ConductorModel, _bem_find_surface, read_bem_solution
  from ..source_estimate import VolSourceEstimate
  from ..source_space._source_space import _complete_vol_src, _ensure_src, _filter_source_spaces, _make_discrete_source_space
  from ..surface import _CheckInside, _normalize_vectors
  from ..transforms import Transform, _coord_frame_name, _ensure_trans, _get_trans, _print_coord_trans, apply_trans, invert_transform, transform_surface_to
  from ..utils import _check_fname, _pl, _validate_type, logger, verbose, warn
  from ._compute_forward import _compute_forwards
  from .forward import _FWD_ORDER, Forward, _merge_fwds, convert_forward_solution
label_desc: Use image node_id 13 for calling a global function with example usage: make_forward_dipole(dipole, bem, info, trans, n_jobs) and returns: fwd,  stc