docs: def to_nifti(obj, like=None, header=None, affine=None, extensions=Ellipsis, version=1):
      '''
      to_nifti(obj) yields a Nifti2Image object that is as equivalent as possible to the given object
        obj. If obj is a Nifti2Image already, then it is returned unmolested; other deduction rules
        are described below.
  
      The following options are accepted:
        * like (default: None) may be provided to give a guide for the various header- and meta-data
          that is included in the image. If this is a nifti image object, its meta-data are used; if
          this is a subject, then the meta-data are deduced from the subject's voxel and native
          orientation matrices. All other specific options below override anything deduced from the
          like argument.
        * header (default: None) may be a Nifti1 or Niti2 image header to be used as the nifti header
          or to replace the header in a new image.
        * affine (default: None) may specify the affine transform to be given to the image object.
        * extensions (default: Ellipsis) may specify a nifti extensions object that should be included
          in the header. The default value, Ellipsis, indicates that the extensions should not be
          changed, and that None should be used if extensions are not implied in obj (if, for example,
          obj is a data array rather than an image object with a header already.
        * version (default: 2) may be specified as 1 or 2 for a Nifti1Image or Nifti2Image object,
          respectively.
      '''
      from neuropythy.mri import Subject
      obj0 = obj
      # First go from like to explicit versions of affine and header:
      if like is not None:
          if isinstance(like, nib.analyze.AnalyzeHeader) or \
             isinstance(like, nib.freesurfer.mghformat.MGHHeader):
              if header is None: header = like
          elif isinstance(like, nib.analyze.SpatialImage):
              if header is None: header = like.header
              if affine is None: affine = like.affine
          elif isinstance(like, Subject):
              if affine is None: affine = like.voxel_to_native_matrix
          else:
              raise ValueError('Could not interpret like argument with type %s' % type(like))
      # check to make sure that we have to change something:
      elif ((version == 1 and isinstance(obj, nib.nifti1.Nifti1Image)) or
            (version == 2 and isinstance(obj, nib.nifti2.Nifti2Image))):
          if ((header is None or obj.header is header) and
              (extensions is Ellipsis or extensions is obj.header.extensions or
               (extensions is None and len(obj.header.extensions) == 0))):
              return obj
      # okay, now look at the header and affine etc.
      if header is None:
          if isinstance(obj, nib.analyze.SpatialImage):
              header = obj.header
          else:
              header = nib.nifti1.Nifti1Header() if version == 1 else nib.nifti2.Nifti2Header()
      if affine is None:
          if isinstance(obj, nib.analyze.SpatialImage):
              affine = obj.affine
          else:
              affine = np.eye(4)
      if extensions is None:
          extensions = nib.nifti1.Nifti1Extensions()
      # Figure out what the data is
      if isinstance(obj, nib.analyze.SpatialImage):
          obj = obj.dataobj
      elif not pimms.is_nparray(obj):
          obj = np.asarray(obj)
      if len(obj.shape) < 3: obj = np.asarray([[obj]])
      # Okay, make a new object now...
      if version == 1:
          obj = nib.nifti1.Nifti1Image(obj, affine, header)
      elif version == 2:
          obj = nib.nifti2.Nifti2Image(obj, affine, header)
      else:
          raise ValueError('invalid version given (should be 1 or 2): %s' % version)
      # add the extensions if they're needed
      if extensions is not Ellipsis and (len(extensions) > 0 or len(obj.header.extensions) > 0):
          obj.header.extensions = extensions
      # Okay, that's it!
      return obj