docstr: Initializes the registration optimizer
  
  Initializes the optimizer by computing the scale space of the input
  images and allocating the required memory for the transformation models
  at the coarsest scale.
  
  Parameters
  ----------
  static : array, shape (S, R, C) or (R, C)
      the image to be used as reference during optimization. The
      displacement fields will have the same discretization as the static
      image.
  moving : array, shape (S, R, C) or (R, C)
      the image to be used as "moving" during optimization. Since the
      deformation fields' discretization is the same as the static image,
      it is necessary to pre-align the moving image to ensure its domain
      lies inside the domain of the deformation fields. This is assumed
      to be accomplished by "pre-aligning" the moving image towards the
      static using an affine transformation given by the 'prealign'
      matrix
  static_grid2world : array, shape (dim+1, dim+1)
      the voxel-to-space transformation associated to the static image
  moving_grid2world : array, shape (dim+1, dim+1)
      the voxel-to-space transformation associated to the moving image
  prealign : array, shape (dim+1, dim+1)
      the affine transformation (operating on the physical space)
      pre-aligning the moving image towards the static
code: def _init_optimizer(
      self,
      static,
      moving,
      static_grid2world,
      moving_grid2world,
      prealign,
  ):
      """Initializes the registration optimizer
  
      Initializes the optimizer by computing the scale space of the input
      images and allocating the required memory for the transformation models
      at the coarsest scale.
  
      Parameters
      ----------
      static : array, shape (S, R, C) or (R, C)
          the image to be used as reference during optimization. The
          displacement fields will have the same discretization as the static
          image.
      moving : array, shape (S, R, C) or (R, C)
          the image to be used as "moving" during optimization. Since the
          deformation fields' discretization is the same as the static image,
          it is necessary to pre-align the moving image to ensure its domain
          lies inside the domain of the deformation fields. This is assumed
          to be accomplished by "pre-aligning" the moving image towards the
          static using an affine transformation given by the 'prealign'
          matrix
      static_grid2world : array, shape (dim+1, dim+1)
          the voxel-to-space transformation associated to the static image
      moving_grid2world : array, shape (dim+1, dim+1)
          the voxel-to-space transformation associated to the moving image
      prealign : array, shape (dim+1, dim+1)
          the affine transformation (operating on the physical space)
          pre-aligning the moving image towards the static
  
      """
      self._connect_functions()
      # 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
      )
  
      # the images' directions don't change with scale
      self.static_direction = np.eye(self.dim + 1)
      self.moving_direction = np.eye(self.dim + 1)
      self.static_direction[: self.dim, : self.dim] = static_direction
      self.moving_direction[: self.dim, : self.dim] = moving_direction
  
      # Build the scale space of the input images
      if self.verbosity >= VerbosityLevels.DIAGNOSE:
          logger.info("Applying zero mask: " + str(self.mask0))
  
      if self.verbosity >= VerbosityLevels.STATUS:
          logger.info(
              "Creating scale space from the moving image."
              + " Levels: %d. Sigma factor: %f."
              % (self.levels, self.ss_sigma_factor)
          )
  
      self.moving_ss = ScaleSpace(
          moving,
          self.levels,
          moving_grid2world,
          moving_spacing,
          self.ss_sigma_factor,
          self.mask0,
      )
  
      if self.verbosity >= VerbosityLevels.STATUS:
          logger.info(
              "Creating scale space from the static image."
              + " Levels: %d. Sigma factor: %f."
              % (self.levels, self.ss_sigma_factor)
          )
  
      self.static_ss = ScaleSpace(
          static,
          self.levels,
          static_grid2world,
          static_spacing,
          self.ss_sigma_factor,
          self.mask0,
      )
  
      if self.verbosity >= VerbosityLevels.DEBUG:
          logger.info("Moving scale space:")
          for level in range(self.levels):
              self.moving_ss.print_level(level)
  
          logger.info("Static scale space:")
          for level in range(self.levels):
              self.static_ss.print_level(level)
  
      # Get the properties of the coarsest level from the static image. These
      # properties will be taken as the reference discretization.
      disp_shape = self.static_ss.get_domain_shape(self.levels - 1)
      disp_grid2world = self.static_ss.get_affine(self.levels - 1)
  
      # The codomain discretization of both diffeomorphic maps is
      # precisely the discretization of the static image
      codomain_shape = static.shape
      codomain_grid2world = static_grid2world
  
      # The forward model transforms points from the static image
      # to points on the reference (which is the static as well). So the
      # domain properties are taken from the static image. Since its the same
      # as the reference, we don't need to pre-align.
      domain_shape = static.shape
      domain_grid2world = static_grid2world
      self.static_to_ref = DiffeomorphicMap(
          self.dim,
          disp_shape,
          disp_grid2world,
          domain_shape,
          domain_grid2world,
          codomain_shape,
          codomain_grid2world,
          None,
      )
      self.static_to_ref.allocate()
  
      # The backward model transforms points from the moving image
      # to points on the reference (which is the static). So the input
      # properties are taken from the moving image, and we need to pre-align
      # points on the moving physical space to the reference physical space
      # by applying the inverse of pre-align. This is done this way to make
      # it clear for the user: the pre-align matrix is usually obtained by
      # doing affine registration of the moving image towards the static
      # image, which results in a matrix transforming points in the static
      # physical space to points in the moving physical space
      prealign_inv = None if prealign is None else npl.inv(prealign)
      domain_shape = moving.shape
      domain_grid2world = moving_grid2world
      self.moving_to_ref = DiffeomorphicMap(
          self.dim,
          disp_shape,
          disp_grid2world,
          domain_shape,
          domain_grid2world,
          codomain_shape,
          codomain_grid2world,
          prealign_inv,
      )
      self.moving_to_ref.allocate()
  
imports: import logging
  import abc
  import numpy
  import numpy.linalg
  import nibabel
  from nibabel.streamlines import ArraySequence
  from dipy.align import vector_fields
  from dipy.align import floating
  from dipy.align import VerbosityLevels
  from dipy.align import Bunch
  from dipy.align.scalespace import ScaleSpace
label_desc: Use image node_id 5 for calling the SymmetricDiffeomorphicRegistration obj's underlying member method code with example usage: obj._init_optimizer(static, moving, static_grid2world, moving_grid2world, prealign) without return types