docstr: IsotropicScaleSpace.
  
  Computes the Scale Space representation of an image using isotropic
  smoothing kernels for all scales. The scale space is simply a list
  of images produced by smoothing the input image with a Gaussian
  kernel with different smoothing parameters.
  
  This specialization of ScaleSpace allows the user to provide custom
  scale and smoothing factors for all scales.
  
  Parameters
  ----------
  image : array, shape (r,c) or (s, r, c) where s is the number of
      slices, r is the number of rows and c is the number of columns of
      the input image.
  factors : list of floats
      custom scale factors to build the scale space (one factor for each
      scale).
  sigmas : list of floats
      custom smoothing parameter to build the scale space (one parameter
      for each scale).
  image_grid2world : array, shape (dim + 1, dim + 1), optional
      the grid-to-space transform of the image grid. The default is
      the identity matrix.
  input_spacing : array, shape (dim,), optional
      the spacing (voxel size) between voxels in physical space. The
      default if 1.0 along all axes.
  mask0 : Boolean, optional
      if True, all smoothed images will be zero at all voxels that are
      zero in the input image. The default is False.
docstr_tok: ["IsotropicScaleSpace",".","Computes","the","Scale","Space","representation","of","an","image","using","isotropic","smoothing","kernels","for","all","scales",".","The","scale","space","is","simply","a","list","of","images","produced","by","smoothing","the","input","image","with","a","Gaussian","kernel","with","different","smoothing","parameters",".","This","specialization","of","ScaleSpace","allows","the","user","to","provide","custom","scale","and","smoothing","factors","for","all","scales",".","Parameters","--","--","--","--","--","image",":","array",",","shape","(","r",",","c",")","or","(","s",",","r",",","c",")","where","s","is","the","number","of","slices",",","r","is","the","number","of","rows","and","c","is","the","number","of","columns","of","the","input","image",".","factors",":","list","of","floats","custom","scale","factors","to","build","the","scale","space","(","one","factor","for","each","scale",")",".","sigmas",":","list","of","floats","custom","smoothing","parameter","to","build","the","scale","space","(","one","parameter","for","each","scale",")",".","image_grid2world",":","array",",","shape","(","dim","+","1",",","dim","+","1",")",",","optional","the","grid-to-space","transform","of","the","image","grid",".","The","default","is","the","identity","matrix",".","input_spacing",":","array",",","shape","(","dim",",",")",",","optional","the","spacing","(","voxel","size",")","between","voxels","in","physical","space",".","The","default","if","1.0","along","all","axes",".","mask0",":","Boolean",",","optional","if","True",",","all","smoothed","images","will","be","zero","at","all","voxels","that","are","zero","in","the","input","image",".","The","default","is","False","."]
code: def __init__(
      self,
      image,
      factors,
      sigmas,
      image_grid2world=None,
      input_spacing=None,
      mask0=False,
  ):
      """IsotropicScaleSpace.
  
      Computes the Scale Space representation of an image using isotropic
      smoothing kernels for all scales. The scale space is simply a list
      of images produced by smoothing the input image with a Gaussian
      kernel with different smoothing parameters.
  
      This specialization of ScaleSpace allows the user to provide custom
      scale and smoothing factors for all scales.
  
      Parameters
      ----------
      image : array, shape (r,c) or (s, r, c) where s is the number of
          slices, r is the number of rows and c is the number of columns of
          the input image.
      factors : list of floats
          custom scale factors to build the scale space (one factor for each
          scale).
      sigmas : list of floats
          custom smoothing parameter to build the scale space (one parameter
          for each scale).
      image_grid2world : array, shape (dim + 1, dim + 1), optional
          the grid-to-space transform of the image grid. The default is
          the identity matrix.
      input_spacing : array, shape (dim,), optional
          the spacing (voxel size) between voxels in physical space. The
          default if 1.0 along all axes.
      mask0 : Boolean, optional
          if True, all smoothed images will be zero at all voxels that are
          zero in the input image. The default is False.
  
      """
      self.dim = len(image.shape)
      self.num_levels = len(factors)
      if len(sigmas) != self.num_levels:
          raise ValueError(
              "sigmas and factors must have the same length"
          )
      input_size = np.array(image.shape)
      if mask0:
          mask = np.asarray(image > 0, dtype=np.int32)
  
      # Normalize input image to [0,1]
      img = (image.astype(np.float64) - np.min(image)) / (
          np.max(image) - np.min(image)
      )
      if mask0:
          img *= mask
  
      # The properties are saved in separate lists. Insert input image
      # properties at the first level of the scale space
      self.images = [img.astype(floating)]
      self.domain_shapes = [input_size.astype(np.int32)]
      if input_spacing is None:
          input_spacing = np.ones((self.dim,), dtype=np.int32)
      self.spacings = [input_spacing]
      self.scalings = [np.ones(self.dim)]
      self.affines = [image_grid2world]
      self.sigmas = [np.ones(self.dim) * sigmas[self.num_levels - 1]]
  
      if image_grid2world is not None:
          self.affine_invs = [npl.inv(image_grid2world)]
      else:
          self.affine_invs = [None]
  
      # Compute the rest of the levels
      min_index = np.argmin(input_spacing)
      for i in range(1, self.num_levels):
          factor = factors[self.num_levels - 1 - i]
          shrink_factors = np.zeros(self.dim)
          new_spacing = np.zeros(self.dim)
          shrink_factors[min_index] = factor
          new_spacing[min_index] = input_spacing[min_index] * factor
          for j in range(self.dim):
              if j != min_index:
                  # Select the factor that maximizes isotropy
                  shrink_factors[j] = factor
                  new_spacing[j] = input_spacing[j] * factor
                  min_diff = np.abs(
                      new_spacing[j] - new_spacing[min_index]
                  )
                  for f in range(1, factor):
                      diff = (
                          input_spacing[j] * f - new_spacing[min_index]
                      )
                      diff = np.abs(diff)
                      if diff < min_diff:
                          shrink_factors[j] = f
                          new_spacing[j] = input_spacing[j] * f
                          min_diff = diff
  
          extended = np.append(shrink_factors, [1])
          if image_grid2world is not None:
              affine = image_grid2world.dot(np.diag(extended))
          else:
              affine = np.diag(extended)
          output_size = (input_size / shrink_factors).astype(np.int32)
          new_sigmas = (
              np.ones(self.dim) * sigmas[self.num_levels - i - 1]
          )
  
          # Filter along each direction with the appropriate sigma
          filtered = gaussian_filter(
              image.astype(np.float64), new_sigmas
          )
          filtered = (
              filtered.astype(np.float64) - np.min(filtered)
          ) / (np.max(filtered) - np.min(filtered))
          if mask0:
              filtered *= mask
  
          # Add current level to the scale space
          self.images.append(filtered.astype(floating))
          self.domain_shapes.append(output_size)
          self.spacings.append(new_spacing)
          self.scalings.append(shrink_factors)
          self.affines.append(affine)
          self.affine_invs.append(npl.inv(affine))
          self.sigmas.append(new_sigmas)
  
imports: import logging
  from dipy.align import floating
  import numpy
  import numpy.linalg
  from scipy.ndimage import gaussian_filter
label_desc: Use image node_id 1 to create a new IsotropicScaleSpace object from inherited base classes: ScaleSpace with example: obj = IsotropicScaleSpace(image, factors, sigmas, image_grid2world, input_spacing, mask0)