code: def compute_fine_calibration(
      raw,
      n_imbalance=3,
      t_window=10.0,
      ext_order=2,
      origin=(0.0, 0.0, 0.0),
      cross_talk=None,
      calibration=None,
      verbose=None,
  ):
      """Compute fine calibration from empty-room data.
  
      Parameters
      ----------
      raw : instance of Raw
          The raw data to use. Should be from an empty-room recording,
          and all channels should be good.
      n_imbalance : int
          Can be 1 or 3 (default), indicating the number of gradiometer
          imbalance components. Only used if gradiometers are present.
      t_window : float
          Time window to use for surface normal rotation in seconds.
          Default is 10.
      %(ext_order_maxwell)s
          Default is 2, which is lower than the default (3) for
          :func:`mne.preprocessing.maxwell_filter` because it tends to yield
          more stable parameter estimates.
      %(origin_maxwell)s
      %(cross_talk_maxwell)s
      calibration : dict | None
          Dictionary with existing calibration. If provided, the magnetometer
          imbalances and adjusted normals will be used and only the gradiometer
          imbalances will be estimated (see step 2 in Notes below).
      %(verbose)s
  
      Returns
      -------
      calibration : dict
          Fine calibration data.
      count : int
          The number of good segments used to compute the magnetometer
          parameters.
  
      See Also
      --------
      mne.preprocessing.maxwell_filter
  
      Notes
      -----
      This algorithm proceeds in two steps, both optimizing the fit between the
      data and a reconstruction of the data based only on an external multipole
      expansion:
  
      1. Estimate magnetometer normal directions and scale factors. All
         coils (mag and matching grad) are rotated by the adjusted normal
         direction.
      2. Estimate gradiometer imbalance factors. These add point magnetometers
         in just the gradiometer difference direction or in all three directions
         (depending on ``n_imbalance``).
  
      Magnetometer normal and coefficient estimation (1) is typically the most
      time consuming step. Gradiometer imbalance parameters (2) can be
      iteratively reestimated (for example, first using ``n_imbalance=1`` then
      subsequently ``n_imbalance=3``) by passing the previous ``calibration``
      output to the ``calibration`` input in the second call.
  
      MaxFilter processes at most 120 seconds of data, so consider cropping
      your raw instance prior to processing. It also checks to make sure that
      there were some minimal usable ``count`` number of segments (default 5)
      that were included in the estimate.
  
      .. versionadded:: 0.21
      """
      n_imbalance = _ensure_int(n_imbalance, "n_imbalance")
      _check_option("n_imbalance", n_imbalance, (1, 3))
      _validate_type(raw, BaseRaw, "raw")
      ext_order = _ensure_int(ext_order, "ext_order")
      origin = _check_origin(origin, raw.info, "meg", disp=True)
      _check_option("raw.info['bads']", raw.info["bads"], ([],))
      picks = pick_types(raw.info, meg=True, ref_meg=False)
      if raw.info["dev_head_t"] is not None:
          raise ValueError(
              'info["dev_head_t"] is not None, suggesting that the '
              "data are not from an empty-room recording"
          )
  
      info = pick_info(
          raw.info, picks
      )  # make a copy and pick MEG channels
      mag_picks = pick_types(info, meg="mag", exclude=())
      grad_picks = pick_types(info, meg="grad", exclude=())
  
      # Get cross-talk
      ctc, _ = _read_cross_talk(cross_talk, info["ch_names"])
  
      # Check fine cal
      _validate_type(calibration, (dict, None), "calibration")
  
      #
      # 1. Rotate surface normals using magnetometer information (if present)
      #
      cals = np.ones(len(info["ch_names"]))
      time_idxs = raw.time_as_index(
          np.arange(0.0, raw.times[-1], t_window)
      )
      if len(time_idxs) <= 1:
          time_idxs = np.array([0, len(raw.times)], int)
      else:
          time_idxs[-1] = len(raw.times)
      count = 0
      locs = np.array([ch["loc"] for ch in info["chs"]])
      zs = locs[mag_picks, -3:].copy()
      if calibration is not None:
          _, calibration, _ = _prep_fine_cal(info, calibration)
          for pi, pick in enumerate(mag_picks):
              idx = calibration["ch_names"].index(
                  info["ch_names"][pick]
              )
              cals[pick] = calibration["imb_cals"][idx].item()
              zs[pi] = calibration["locs"][idx][-3:]
      elif len(mag_picks) > 0:
          cal_list = list()
          z_list = list()
          logger.info(
              "Adjusting normals for %s magnetometers "
              "(averaging over %s time intervals)"
              % (len(mag_picks), len(time_idxs) - 1)
          )
          for start, stop in zip(time_idxs[:-1], time_idxs[1:]):
              logger.info(
                  "    Processing interval %0.3f - %0.3f s"
                  % (start / info["sfreq"], stop / info["sfreq"])
              )
              data = raw[picks, start:stop][0]
              if ctc is not None:
                  data = ctc.dot(data)
              z, cal, good = _adjust_mag_normals(
                  info, data, origin, ext_order
              )
              if good:
                  z_list.append(z)
                  cal_list.append(cal)
          count = len(cal_list)
          if count == 0:
              raise RuntimeError("No usable segments found")
          cals[:] = np.mean(cal_list, axis=0)
          zs[:] = np.mean(z_list, axis=0)
      if len(mag_picks) > 0:
          for ii, new_z in enumerate(zs):
              z_loc = locs[mag_picks[ii]]
              # Find sensors with same NZ and R0 (should be three for VV)
              idxs = _matched_loc_idx(z_loc, locs)
              # Rotate the direction vectors to the plane defined by new normal
              _rotate_locs(locs, idxs, new_z)
      for ci, loc in enumerate(locs):
          info["chs"][ci]["loc"][:] = loc
      del calibration, zs
  
      #
      # 2. Estimate imbalance parameters (always done)
      #
      if len(grad_picks) > 0:
          extra = (
              "X direction" if n_imbalance == 1 else ("XYZ directions")
          )
          logger.info(
              "Computing imbalance for %s gradimeters (%s)"
              % (len(grad_picks), extra)
          )
          imb_list = list()
          for start, stop in zip(time_idxs[:-1], time_idxs[1:]):
              logger.info(
                  "    Processing interval %0.3f - %0.3f s"
                  % (start / info["sfreq"], stop / info["sfreq"])
              )
              data = raw[picks, start:stop][0]
              if ctc is not None:
                  data = ctc.dot(data)
              out = _estimate_imbalance(
                  info, data, cals, n_imbalance, origin, ext_order
              )
              imb_list.append(out)
          imb = np.mean(imb_list, axis=0)
      else:
          imb = np.zeros((len(info["ch_names"]), n_imbalance))
  
      #
      # Put in output structure
      #
      assert len(np.intersect1d(mag_picks, grad_picks)) == 0
      imb_cals = [
          cals[ii : ii + 1] if ii in mag_picks else imb[ii]
          for ii in range(len(info["ch_names"]))
      ]
      calibration = dict(
          ch_names=info["ch_names"], locs=locs, imb_cals=imb_cals
      )
      return calibration, count
  
imports: from collections import defaultdict
  from functools import partial
  import numpy
  from scipy.optimize import fmin_cobyla
  from .._fiff.pick import pick_info, pick_types
  from .._fiff.tag import _coil_trans_to_loc, _loc_to_coil_trans
  from ..bem import _check_origin
  from ..io import BaseRaw
  from ..transforms import _find_vector_rotation
  from ..utils import _check_fname, _check_option, _ensure_int, _pl, _reg_pinv, _validate_type, check_fname, logger, verbose
  from .maxwell import _col_norm_pinv, _get_grad_point_coilsets, _prep_fine_cal, _prep_mf_coils, _read_cross_talk, _trans_sss_basis
label_desc: Use image node_id 1 for calling a global function with example usage: compute_fine_calibration(raw, n_imbalance, t_window, ext_order, origin, cross_talk, calibration, verbose) and returns: calibration,  count