code: def test_fit_matched_points(quats, scaling, do_scale):
      """Test analytical least-squares matched point fitting."""
      if scaling != 1 and not do_scale:
          return  # no need to test this, it will not be good
      rng = np.random.RandomState(0)
      fro = rng.randn(10, 3)
      translation = rng.randn(3)
      for qi, quat in enumerate(quats):
          to = (
              scaling * np.dot(quat_to_rot(quat), fro.T).T + translation
          )
          for corrupted in (False, True):
              # mess up a point
              if corrupted:
                  to[0, 2] += 100
                  weights = np.ones(len(to))
                  weights[0] = 0
              else:
                  weights = None
              est, scale_est = _check_fit_matched_points(
                  fro, to, weights=weights, do_scale=do_scale
              )
              assert_allclose(scale_est, scaling, rtol=1e-5)
              assert_allclose(est[:3], quat, atol=1e-14)
              assert_allclose(est[3:], translation, atol=1e-14)
          # if we don't adjust for the corruption above, it should get worse
          angle = dist = None
          for weighted in (False, True):
              if not weighted:
                  weights = None
                  dist_bounds = (5, 20)
                  if scaling == 1:
                      angle_bounds = (5, 95)
                      angtol, dtol, stol = 1, 15, 3
                  else:
                      angle_bounds = (5, 105)
                      angtol, dtol, stol = 20, 15, 3
              else:
                  weights = np.ones(len(to))
                  weights[
                      0
                  ] = 10  # weighted=True here means "make it worse"
                  angle_bounds = (
                      angle,
                      180,
                  )  # unweighted values as new min
                  dist_bounds = (dist, 100)
                  if scaling == 1:
                      # XXX this angtol is not great but there is a hard to
                      # identify linalg/angle calculation bug on Travis...
                      angtol, dtol, stol = 180, 70, 3
                  else:
                      angtol, dtol, stol = 50, 70, 3
              est, scale_est = _check_fit_matched_points(
                  fro,
                  to,
                  weights=weights,
                  do_scale=do_scale,
                  angtol=angtol,
                  dtol=dtol,
                  stol=stol,
              )
              assert not np.allclose(est[:3], quat, atol=1e-5)
              assert not np.allclose(est[3:], translation, atol=1e-5)
              angle = np.rad2deg(_angle_between_quats(est[:3], quat))
              assert_array_less(angle_bounds[0], angle)
              assert_array_less(angle, angle_bounds[1])
              dist = np.linalg.norm(est[3:] - translation)
              assert_array_less(dist_bounds[0], dist)
              assert_array_less(dist, dist_bounds[1])
  
imports: import itertools
  import os
  from pathlib import Path
  import numpy
  import pytest
  from numpy.testing import assert_allclose, assert_almost_equal, assert_array_equal, assert_array_less, assert_equal
  import mne
  from mne import read_trans, write_trans
  from mne.datasets import testing
  from mne.fixes import _get_img_fdata
  from mne.io import read_info
  from mne.transforms import _angle_between_quats, _average_quats, _cart_to_sph, _compute_r2, _euler_to_quat, _find_trans, _find_vector_rotation, _fit_matched_points, _get_trans, _MatchedDisplacementFieldInterpolator, _pol_to_cart, _quat_real, _quat_to_affine, _quat_to_euler, _read_fs_xfm, _sph_to_cart, _topo_to_sph, _validate_pipeline, _write_fs_xfm, apply_trans, combine_transforms, get_ras_to_neuromag_trans, invert_transform, quat_to_rot, rot_to_quat, rotation, rotation3d, rotation3d_align_z_axis, rotation_angles, translation
  from mne.transforms import _SphericalSurfaceWarp
label_desc: Use image node_id 21 for calling a global function with example usage: test_fit_matched_points(quats, scaling, do_scale) without return types