docstr: Initialize the registration optimizer.
  
  Initializes the optimizer by computing the scale space of the input
  images
  
  Parameters
  ----------
  static : array, shape (S, R, C) or (R, C)
      the image to be used as reference during optimization.
  moving : array, shape (S', R', C') or (R', C')
      the image to be used as "moving" during optimization. The
      dimensions of the static (S, R, C) and moving (S', R', C') images
      do not need to be the same.
  transform : instance of Transform
      the transformation with respect to whose parameters the gradient
      must be computed
  params0 : array, shape (n,)
      parameters from which to start the optimization. If None, the
      optimization will start at the identity transform. n is the
      number of parameters of the specified transformation.
  static_grid2world : array, shape (dim+1, dim+1)
      the voxel-to-space transformation associated with the static image
  moving_grid2world : array, shape (dim+1, dim+1)
      the voxel-to-space transformation associated with the moving image
  starting_affine : string, or matrix, or None
      If string:
          'mass': align centers of gravity
          'voxel-origin': align physical coordinates of voxel (0,0,0)
          'centers': align physical coordinates of central voxels
      If matrix:
          array, shape (dim+1, dim+1)
      If None:
          Start from identity
  static_mask : array, shape (S, R, C) or (R, C), optional
      static image mask that defines which pixels in the static image
      are used to calculate the mutual information.
  moving_mask : array, shape (S', R', C') or (R', C'), optional
      moving image mask that defines which pixels in the moving image
      are used to calculate the mutual information.
docstr_tok: ["Initialize","the","registration","optimizer",".","Initializes","the","optimizer","by","computing","the","scale","space","of","the","input","images","Parameters","--","--","--","--","--","static",":","array",",","shape","(","S",",","R",",","C",")","or","(","R",",","C",")","the","image","to","be","used","as","reference","during","optimization",".","moving",":","array",",","shape","(","S","'",",","R","'",",","C","'",")","or","(","R","'",",","C","'",")","the","image","to","be","used","as","``","moving","''","during","optimization",".","The","dimensions","of","the","static","(","S",",","R",",","C",")","and","moving","(","S","'",",","R","'",",","C","'",")","images","do","not","need","to","be","the","same",".","transform",":","instance","of","Transform","the","transformation","with","respect","to","whose","parameters","the","gradient","must","be","computed","params0",":","array",",","shape","(","n",",",")","parameters","from","which","to","start","the","optimization",".","If","None",",","the","optimization","will","start","at","the","identity","transform",".","n","is","the","number","of","parameters","of","the","specified","transformation",".","static_grid2world",":","array",",","shape","(","dim+1",",","dim+1",")","the","voxel-to-space","transformation","associated","with","the","static","image","moving_grid2world",":","array",",","shape","(","dim+1",",","dim+1",")","the","voxel-to-space","transformation","associated","with","the","moving","image","starting_affine",":","string",",","or","matrix",",","or","None","If","string",":","'mass","'",":","align","centers","of","gravity","'voxel-origin","'",":","align","physical","coordinates","of","voxel","(","0,0,0",")","'centers","'",":","align","physical","coordinates","of","central","voxels","If","matrix",":","array",",","shape","(","dim+1",",","dim+1",")","If","None",":","Start","from","identity","static_mask",":","array",",","shape","(","S",",","R",",","C",")","or","(","R",",","C",")",",","optional","static","image","mask","that","defines","which","pixels","in","the","static","image","are","used","to","calculate","the","mutual","information",".","moving_mask",":","array",",","shape","(","S","'",",","R","'",",","C","'",")","or","(","R","'",",","C","'",")",",","optional","moving","image","mask","that","defines","which","pixels","in","the","moving","image","are","used","to","calculate","the","mutual","information","."]
code: def _init_optimizer(
      self,
      static,
      moving,
      transform,
      params0,
      static_grid2world,
      moving_grid2world,
      starting_affine,
      static_mask,
      moving_mask,
  ):
      r"""Initialize the registration optimizer.
  
      Initializes the optimizer by computing the scale space of the input
      images
  
      Parameters
      ----------
      static : array, shape (S, R, C) or (R, C)
          the image to be used as reference during optimization.
      moving : array, shape (S', R', C') or (R', C')
          the image to be used as "moving" during optimization. The
          dimensions of the static (S, R, C) and moving (S', R', C') images
          do not need to be the same.
      transform : instance of Transform
          the transformation with respect to whose parameters the gradient
          must be computed
      params0 : array, shape (n,)
          parameters from which to start the optimization. If None, the
          optimization will start at the identity transform. n is the
          number of parameters of the specified transformation.
      static_grid2world : array, shape (dim+1, dim+1)
          the voxel-to-space transformation associated with the static image
      moving_grid2world : array, shape (dim+1, dim+1)
          the voxel-to-space transformation associated with the moving image
      starting_affine : string, or matrix, or None
          If string:
              'mass': align centers of gravity
              'voxel-origin': align physical coordinates of voxel (0,0,0)
              'centers': align physical coordinates of central voxels
          If matrix:
              array, shape (dim+1, dim+1)
          If None:
              Start from identity
      static_mask : array, shape (S, R, C) or (R, C), optional
          static image mask that defines which pixels in the static image
          are used to calculate the mutual information.
      moving_mask : array, shape (S', R', C') or (R', C'), optional
          moving image mask that defines which pixels in the moving image
          are used to calculate the mutual information.
  
      """
      self.dim = len(static.shape)
      self.transform = transform
      n = transform.get_number_of_parameters()
      self.nparams = n
  
      # ensure that masks are not all zeros
      if np.all(static_mask == 0):
          warn(
              "static_mask is all zeros, setting to None (which means \
                    the entire volume will be used)",
              UserWarning,
          )
          static_mask = None
      if np.all(moving_mask == 0):
          warn("moving_mask is all zeros, setting to None", UserWarning)
          moving_mask = None
  
      # save masks for use elsewhere
      self.static_mask, self.moving_mask = static_mask, moving_mask
  
      # multiply images by masks for transform_centers_of_mass
      static_masked, moving_masked = static, moving
      if static_mask is not None:
          static_masked = static * static_mask
      if moving_mask is not None:
          moving_masked = moving * moving_mask
  
      if params0 is None:
          params0 = self.transform.get_identity_parameters()
      self.params0 = params0
      if starting_affine is None:
          self.starting_affine = np.eye(self.dim + 1)
      elif isinstance(starting_affine, str):
          if starting_affine == "mass":
              affine_map = transform_centers_of_mass(
                  static_masked,
                  static_grid2world,
                  moving_masked,
                  moving_grid2world,
              )
              self.starting_affine = affine_map.affine
              print(
                  "starting_affine in imaffine:", self.starting_affine
              )
          elif starting_affine == "voxel-origin":
              affine_map = transform_origins(
                  static, static_grid2world, moving, moving_grid2world
              )
              self.starting_affine = affine_map.affine
          elif starting_affine == "centers":
              affine_map = transform_geometric_centers(
                  static, static_grid2world, moving, moving_grid2world
              )
              self.starting_affine = affine_map.affine
          else:
              raise ValueError("Invalid starting_affine strategy")
      elif isinstance(
          starting_affine, np.ndarray
      ) and starting_affine.shape >= (self.dim, self.dim + 1):
          self.starting_affine = starting_affine
      else:
          raise ValueError("Invalid starting_affine matrix")
  
      # Extract information from affine matrices to create the scale space
      static_direction, static_spacing = get_direction_and_spacings(
          static_grid2world, self.dim
      )
      moving_direction, moving_spacing = get_direction_and_spacings(
          moving_grid2world, self.dim
      )
  
      # Scale the images by min and max values (where mask == 1)
      if static_mask is not None:
          smin = np.min(static[static_mask == 1])
          smax = np.max(static[static_mask == 1])
      else:
          smin, smax = np.min(static), np.max(static)
      static = (static.astype(np.float64) - smin) / (smax - smin)
      if moving_mask is not None:
          mmin = np.min(moving[moving_mask == 1])
          mmax = np.max(moving[moving_mask == 1])
      else:
          mmin, mmax = np.min(moving), np.max(moving)
      moving = (moving.astype(np.float64) - mmin) / (mmax - mmin)
  
      # Build the scale space of the input images
      if self.use_isotropic:
          self.moving_ss = IsotropicScaleSpace(
              moving,
              self.factors,
              self.sigmas,
              moving_grid2world,
              moving_spacing,
              False,
          )
  
          self.static_ss = IsotropicScaleSpace(
              static,
              self.factors,
              self.sigmas,
              static_grid2world,
              static_spacing,
              False,
          )
  
      else:
          self.moving_ss = ScaleSpace(
              moving,
              self.levels,
              moving_grid2world,
              moving_spacing,
              self.ss_sigma_factor,
              False,
          )
  
          self.static_ss = ScaleSpace(
              static,
              self.levels,
              static_grid2world,
              static_spacing,
              self.ss_sigma_factor,
              False,
          )
  
imports: from warnings import warn
  import numpy
  import numpy.linalg
  import scipy.ndimage
  from dipy.core.optimize import Optimizer
  from dipy.core.interpolation import interpolate_scalar_2d, interpolate_scalar_3d
  from dipy.align import vector_fields
  from dipy.align import VerbosityLevels
  from dipy.align.parzenhist import ParzenJointHistogram, sample_domain_regular, compute_parzen_mi
  from dipy.align.imwarp import get_direction_and_spacings, ScaleSpace
  from dipy.align.scalespace import IsotropicScaleSpace
  from dipy.utils.deprecator import deprecated_params
label_desc: Use image node_id 2 for calling the AffineRegistration obj's underlying member method code with example usage: obj._init_optimizer(static, moving, transform, params0, static_grid2world, moving_grid2world, starting_affine, static_mask, moving_mask) without return types