code: def annotate_movement(
      raw,
      pos,
      rotation_velocity_limit=None,
      translation_velocity_limit=None,
      mean_distance_limit=None,
      use_dev_head_trans="average",
  ):
      """Detect segments with movement.
  
      Detects segments periods further from rotation_velocity_limit,
      translation_velocity_limit and mean_distance_limit. It returns an
      annotation with the bad segments.
  
      Parameters
      ----------
      raw : instance of Raw
          Data to compute head position.
      pos : array, shape (N, 10)
          The position and quaternion parameters from cHPI fitting. Obtained
          with `mne.chpi` functions.
      rotation_velocity_limit : float
          Head rotation velocity limit in degrees per second.
      translation_velocity_limit : float
          Head translation velocity limit in meters per second.
      mean_distance_limit : float
          Head position limit from mean recording in meters.
      use_dev_head_trans : 'average' (default) | 'info'
          Identify the device to head transform used to define the
          fixed HPI locations for computing moving distances.
          If ``average`` the average device to head transform is
          computed using ``compute_average_dev_head_t``.
          If ``info``, ``raw.info['dev_head_t']`` is used.
  
      Returns
      -------
      annot : mne.Annotations
          Periods with head motion.
      hpi_disp : array
          Head position over time with respect to the mean head pos.
  
      See Also
      --------
      compute_average_dev_head_t
      """
      sfreq = raw.info["sfreq"]
      hp_ts = pos[:, 0].copy() - raw.first_time
      dt = np.diff(hp_ts)
      hp_ts = np.concatenate([hp_ts, [hp_ts[-1] + 1.0 / sfreq]])
      orig_time = raw.info["meas_date"]
      annot = Annotations([], [], [], orig_time=orig_time)
  
      # Annotate based on rotational velocity
      t_tot = raw.times[-1]
      if rotation_velocity_limit is not None:
          assert rotation_velocity_limit > 0
          # Rotational velocity (radians / s)
          r = _angle_between_quats(pos[:-1, 1:4], pos[1:, 1:4])
          r /= dt
          bad_mask = r >= np.deg2rad(rotation_velocity_limit)
          onsets, offsets = _mask_to_onsets_offsets(bad_mask)
          onsets, offsets = hp_ts[onsets], hp_ts[offsets]
          bad_pct = 100 * (offsets - onsets).sum() / t_tot
          logger.info(
              "Omitting %5.1f%% (%3d segments): "
              "ω >= %5.1f°/s (max: %0.1f°/s)"
              % (
                  bad_pct,
                  len(onsets),
                  rotation_velocity_limit,
                  np.rad2deg(r.max()),
              )
          )
          annot += _annotations_from_mask(
              hp_ts, bad_mask, "BAD_mov_rotat_vel", orig_time=orig_time
          )
  
      # Annotate based on translational velocity limit
      if translation_velocity_limit is not None:
          assert translation_velocity_limit > 0
          v = np.linalg.norm(np.diff(pos[:, 4:7], axis=0), axis=-1)
          v /= dt
          bad_mask = v >= translation_velocity_limit
          onsets, offsets = _mask_to_onsets_offsets(bad_mask)
          onsets, offsets = hp_ts[onsets], hp_ts[offsets]
          bad_pct = 100 * (offsets - onsets).sum() / t_tot
          logger.info(
              "Omitting %5.1f%% (%3d segments): "
              "v >= %5.4fm/s (max: %5.4fm/s)"
              % (
                  bad_pct,
                  len(onsets),
                  translation_velocity_limit,
                  v.max(),
              )
          )
          annot += _annotations_from_mask(
              hp_ts, bad_mask, "BAD_mov_trans_vel", orig_time=orig_time
          )
  
      # Annotate based on displacement from mean head position
      disp = []
      if mean_distance_limit is not None:
          assert mean_distance_limit > 0
  
          # compute dev to head transform for fixed points
          use_dev_head_trans = use_dev_head_trans.lower()
          if use_dev_head_trans not in ["average", "info"]:
              raise ValueError(
                  "use_dev_head_trans must be either"
                  + " 'average' or 'info': got '%s'"
                  % (use_dev_head_trans,)
              )
  
          if use_dev_head_trans == "average":
              fixed_dev_head_t = compute_average_dev_head_t(raw, pos)
          elif use_dev_head_trans == "info":
              fixed_dev_head_t = raw.info["dev_head_t"]
  
          # Get static head pos from file, used to convert quat to cartesian
          chpi_pos = sorted(
              [d for d in raw.info["hpi_results"][-1]["dig_points"]],
              key=lambda x: x["ident"],
          )
          chpi_pos = np.array([d["r"] for d in chpi_pos])
  
          # Get head pos changes during recording
          chpi_pos_mov = np.array(
              [
                  apply_trans(_quat_to_affine(quat), chpi_pos)
                  for quat in pos[:, 1:7]
              ]
          )
  
          # get fixed position
          chpi_pos_fix = apply_trans(fixed_dev_head_t, chpi_pos)
  
          # get movement displacement from mean pos
          hpi_disp = chpi_pos_mov - np.tile(
              chpi_pos_fix, (pos.shape[0], 1, 1)
          )
  
          # get positions above threshold distance
          disp = np.sqrt((hpi_disp**2).sum(axis=2))
          bad_mask = np.any(disp > mean_distance_limit, axis=1)
          onsets, offsets = _mask_to_onsets_offsets(bad_mask)
          onsets, offsets = hp_ts[onsets], hp_ts[offsets]
          bad_pct = 100 * (offsets - onsets).sum() / t_tot
          logger.info(
              "Omitting %5.1f%% (%3d segments): "
              "disp >= %5.4fm (max: %5.4fm)"
              % (bad_pct, len(onsets), mean_distance_limit, disp.max())
          )
          annot += _annotations_from_mask(
              hp_ts, bad_mask, "BAD_mov_dist", orig_time=orig_time
          )
      _adjust_onset_meas_date(annot, raw)
      return annot, disp
  
file_path: mne-python/mne/preprocessing/artifact_detection.py
imports: import numpy
  from scipy.ndimage import distance_transform_edt, label
  from scipy.signal import find_peaks
  from scipy.stats import zscore
  from ..annotations import Annotations, _adjust_onset_meas_date, _annotations_starts_stops, annotations_from_events
  from ..filter import filter_data
  from ..io.base import BaseRaw
  from ..transforms import Transform, _angle_between_quats, _average_quats, _quat_to_affine, apply_trans, quat_to_rot
  from ..utils import _mask_to_onsets_offsets, _pl, _validate_type, logger, verbose
label_desc: Use image node_id 2 for calling a global function with example usage: annotate_movement(raw, pos, rotation_velocity_limit, translation_velocity_limit, mean_distance_limit, use_dev_head_trans) and returns: annot,  disp