code: def test_affine_registration():
      moving = subset_b0
      static = subset_b0
      moving_affine = static_affine = np.eye(4)
      xformed, affine_mat = affine_registration(
          moving,
          static,
          moving_affine=moving_affine,
          static_affine=static_affine,
          level_iters=[5, 5],
          sigmas=[3, 1],
          factors=[2, 1],
      )
  
      # We don't ask for much:
      npt.assert_almost_equal(affine_mat[:3, :3], np.eye(3), decimal=1)
  
      # [center_of_mass] + ret_metric=True should raise an error
      with pytest.raises(ValueError):
          # For array input, must provide affines:
          xformed, affine_mat = affine_registration(
              moving,
              static,
              moving_affine=moving_affine,
              static_affine=static_affine,
              pipeline=["center_of_mass"],
              ret_metric=True,
          )
  
      # Define list of methods
      reg_methods = [
          "center_of_mass",
          "translation",
          "rigid",
          "rigid_isoscaling",
          "rigid_scaling",
          "affine",
          center_of_mass,
          translation,
          rigid,
          rigid_isoscaling,
          rigid_scaling,
          affine,
      ]
  
      # Test methods individually (without returning any metric)
      for func in reg_methods:
          xformed, affine_mat = affine_registration(
              moving,
              static,
              moving_affine=moving_affine,
              static_affine=static_affine,
              level_iters=[5, 5],
              sigmas=[3, 1],
              factors=[2, 1],
              pipeline=[func],
          )
          # We don't ask for much:
          npt.assert_almost_equal(
              affine_mat[:3, :3], np.eye(3), decimal=1
          )
  
      # Bad method
      with pytest.raises(
          ValueError, match=r"^pipeline\[0\] must be one.*foo.*"
      ):
          affine_registration(
              moving,
              static,
              moving_affine,
              static_affine,
              pipeline=["foo"],
          )
  
      # Test methods individually (returning quality metric)
      expected_nparams = [0, 3, 6, 7, 9, 12] * 2
      assert len(expected_nparams) == len(reg_methods)
      for i, func in enumerate(reg_methods):
          if func in ("center_of_mass", center_of_mass):
              # can't return metric
              with pytest.raises(
                  ValueError, match="cannot return any quality"
              ):
                  affine_registration(
                      moving,
                      static,
                      moving_affine,
                      static_affine,
                      pipeline=[func],
                      ret_metric=True,
                  )
              continue
  
          xformed, affine_mat, xopt, fopt = affine_registration(
              moving,
              static,
              moving_affine=moving_affine,
              static_affine=static_affine,
              level_iters=[5, 5],
              sigmas=[3, 1],
              factors=[2, 1],
              pipeline=[func],
              ret_metric=True,
          )
          # Expected number of optimization parameters
          npt.assert_equal(len(xopt), expected_nparams[i])
          # Optimization metric must be a single numeric value
          npt.assert_equal(isinstance(fopt, (int, float)), True)
  
      with pytest.raises(ValueError):
          # For array input, must provide affines:
          xformed, affine_mat = affine_registration(moving, static)
  
      # Not supported transform names should raise an error
      npt.assert_raises(
          ValueError,
          affine_registration,
          moving,
          static,
          moving_affine,
          static_affine,
          pipeline=["wrong_transform"],
      )
  
      # If providing nifti image objects, don't need to provide affines:
      moving_img = nib.Nifti1Image(moving, moving_affine)
      static_img = nib.Nifti1Image(static, static_affine)
      xformed, affine_mat = affine_registration(moving_img, static_img)
      npt.assert_almost_equal(affine_mat[:3, :3], np.eye(3), decimal=1)
  
      # Using strings with full paths as inputs also works:
      t1_name, b0_name = dpd.get_fnames("syn_data")
      moving = b0_name
      static = t1_name
      xformed, affine_mat = affine_registration(
          moving,
          static,
          level_iters=[5, 5],
          sigmas=[3, 1],
          factors=[4, 2],
      )
      npt.assert_almost_equal(affine_mat[:3, :3], np.eye(3), decimal=1)
  
imports: import os.path
  import pytest
  from tempfile import TemporaryDirectory
  import numpy
  import numpy.testing
  import nibabel
  import dipy.data
  import dipy.core.gradients
  from dipy.align import syn_registration, register_series, register_dwi_series, center_of_mass, translation, rigid_isoscaling, rigid_scaling, rigid, affine, motion_correction, affine_registration, streamline_registration, write_mapping, read_mapping, register_dwi_to_template
  from dipy.align.imwarp import DiffeomorphicMap
  from dipy.tracking.utils import transform_tracking_output
  from dipy.io.streamline import save_trk
  from dipy.io.stateful_tractogram import StatefulTractogram, Space
  from dipy.io.gradients import read_bvals_bvecs
  from dipy.io.image import load_nifti
  from dipy.testing.decorators import set_random_number_generator
label_desc: Use image node_id 4 for calling a global function with example usage: test_affine_registration() without return types