docstr: Composition of this DiffeomorphicMap with a given endomorphism
  
  Creates a new DiffeomorphicMap C with the same properties as self and
  composes its displacement fields with phi's corresponding fields.
  The resulting diffeomorphism is of the form C(x) = phi(self(x)) with
  inverse C^{-1}(y) = self^{-1}(phi^{-1}(y)). We assume that phi is an
  endomorphism with the same discretization and domain affine as self
  to ensure that the composition inherits self's properties (we also
  assume that the pre-aligning matrix of phi is None or identity).
  
  Parameters
  ----------
  phi : DiffeomorphicMap object
      the endomorphism to be warped by this diffeomorphic map
  
  Returns
  -------
  composition : the composition of this diffeomorphic map with the
      endomorphism given as input
  
  Notes
  -----
  The problem with our current representation of a DiffeomorphicMap is
  that the set of Diffeomorphism that can be represented this way (a
  pre-aligning matrix followed by a non-linear endomorphism given as a
  displacement field) is not closed under the composition operation.
  
  Supporting a general DiffeomorphicMap class, closed under composition,
  may be extremely costly computationally, and the kind of
  transformations we actually need for Avants' mid-point algorithm (SyN)
  are much simpler.
code: def warp_endomorphism(self, phi):
      """Composition of this DiffeomorphicMap with a given endomorphism
  
      Creates a new DiffeomorphicMap C with the same properties as self and
      composes its displacement fields with phi's corresponding fields.
      The resulting diffeomorphism is of the form C(x) = phi(self(x)) with
      inverse C^{-1}(y) = self^{-1}(phi^{-1}(y)). We assume that phi is an
      endomorphism with the same discretization and domain affine as self
      to ensure that the composition inherits self's properties (we also
      assume that the pre-aligning matrix of phi is None or identity).
  
      Parameters
      ----------
      phi : DiffeomorphicMap object
          the endomorphism to be warped by this diffeomorphic map
  
      Returns
      -------
      composition : the composition of this diffeomorphic map with the
          endomorphism given as input
  
      Notes
      -----
      The problem with our current representation of a DiffeomorphicMap is
      that the set of Diffeomorphism that can be represented this way (a
      pre-aligning matrix followed by a non-linear endomorphism given as a
      displacement field) is not closed under the composition operation.
  
      Supporting a general DiffeomorphicMap class, closed under composition,
      may be extremely costly computationally, and the kind of
      transformations we actually need for Avants' mid-point algorithm (SyN)
      are much simpler.
  
      """
      # Compose the forward deformation fields
      d1 = self.get_forward_field()
      d2 = phi.get_forward_field()
      d1_inv = self.get_backward_field()
      d2_inv = phi.get_backward_field()
  
      premult_disp = self.disp_world2grid
  
      if self.dim == 2:
          compose_f = vfu.compose_vector_fields_2d
      else:
          compose_f = vfu.compose_vector_fields_3d
  
      forward, stats = compose_f(d1, d2, None, premult_disp, 1.0, None)
      (
          backward,
          stats,
      ) = compose_f(d2_inv, d1_inv, None, premult_disp, 1.0, None)
  
      composition = self.shallow_copy()
      composition.forward = forward
      composition.backward = backward
      return composition
  
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 20 for calling the DiffeomorphicMap obj's underlying member method code with example usage: obj.warp_endomorphism(phi) and returns: composition