Ejemplo n.º 1
0
 def niftiToRaw(infile, outfile=None, sizefile=None, dimorder=None, diskorder='F', dtype=None, dtype_as_ext=False):
   """Converts a NIfTI file (or set of files) to a raw file.
   
   Arguments:
     infile:       Filename of a NIfTI file, or a list of strings.  The list
                   indicates a sequence of files to be concatenated together,
                   in the order given, along dimension 4 (where 1 is the
                   fastest-changing).
     outfile:      Filename of a raw file to generate.  If None, the filename
                   will be copied from infile, but with an extension indicating
                   the dtype.  See also dtype_as_ext.
     sizefile:     Filename of a size_info metadata file.  If None, it will go
                   in the same directory as outfile.  If empty string, no
                   size_info file will be generated.
     dimorder:     Four-character string that is a permutation of "XYZI",
                   indicating the desired dimension order of the output image.
                     The default value, None, is equivalent to "XYZI".
     diskorder:    'F' or 'C' --- the order for storage on disk.
     dtype:        A numpy data type to cast to.  If None, the data type
                   either remains whatever the NIfTI header specifies, or is
                   cast to the type specified by the extension on outfile.
     dtype_as_ext: If True, and if outfile is not None, then this appends the
                   dtype to the end of outfile.
   """
   if dimorder is None:
     dimorder = _miraw_helpers.DIM_DEFAULT_ORDER
   if not _miraw_helpers.isValidDimorder(dimorder):
     raise ValueError('"%s" is not a valid dimorder argument.' % repr(dimorder))
   
   # Figure out the desired dtype.
   fname_dtype = None
   try:
     fname_dtype = _miraw_helpers.inferDtypeFromFilename(outfile)
   except:
     pass
   
   if dtype is not None and fname_dtype is not None:
     if fname_dtype != np.dtype(dtype):
       raise ValueError("Arguments specify contradictory dtypes:\n  outfile: {}\n  dtype:   {}".format(outfile, dtype))
   elif dtype is None:
     dtype = fname_dtype
   
   # Now either dtype is None, because both the outfile and dtype arguments
   # failed to set it, or it and the outfile agree.  If it's None, then we'll
   # just keep the dtype from the NIfTI file.
   
   # Read the file and set the dtype once and for all.
   (img, cfg, header) = readNifti(infile, dtype)
   dtype = img.dtype
   
   # Apply any dimension flips or permutations according to the header.
   (img, xform, vox_sz) = applyNiftiXform(img, niftiGetXform(header), cfg)
   
   # And finally put the data in the requested storage order.
   img = applyDimOrder(img, dimorder)
   
   # Generate new names for the output files as necessary.
   if outfile is None:
     if not isinstance(infile, str):
       raise ValueError("No outfile specified, but infile %s is not a string!" % repr(infile))
     (base, ext) = os.path.splitext(infile)
     if ext == ".gz":
       (base, ext) = os.path.splitext(base)
     outfile = base + "." + str(dtype)
   elif dtype_as_ext:
     outfile += "." + str(dtype)
   
   if sizefile is None:
     sizefile = os.path.join(os.path.dirname(outfile), "size_info")
   
   # Write the size_info file.
   if len(sizefile) > 0:
     saveSizeInfo(sizefile, img, size_cfg=cfg, infer_name=False)
   
   # And finally write the raw file.
   saveRaw(outfile, img, diskorder, dtype_as_ext)
Ejemplo n.º 2
0
def readRaw(f, shape, dtype=None, diskorder='F', memorder='C'):
  """Loads array data from a raw binary file on disk.
  
  This is a wrapper around numpy.fromfile, and returns a numpy.ndarray that
  owns its own memory.  Its particular purpose is to work with differing
  dimension orderings on disk and in memory.  The default is to interpret
  the file as "Fortran-ordered" (Matlab's default; column-major; first index
  is fastest-changing) and to produce an ndarray that is "C-ordered" (numpy's
  default; row-major; last index is fastest-changing).
  
  This function does not support memory mapping (yet), so it's not
  appropriate to use if your array is too big to fit comfortably in memory.
  numpy.load() and the h5py package are alternatives, but they put
  restrictions on the file format.  numpy.memmap() may be the right option.
  
  Arguments:
    f:         An open file object or a filename.
    shape:     A tuple of dimension extents.  One dimension may be given
               extent -1; if so, this dimension stretches to fit all the
               voxel values.
    dtype:     A numpy data type (like numpy.float32).  If None, dtype is
               inferred from the filename.
    diskorder: 'F' or 'C', default 'F'.
    memorder:  'F' or 'C', default 'C'.
  
  Throws a ValueError if shape does not match the number of voxels stored on
  disk, or if the product of the non-negative values in shape does not divide
  the number of voxels evenly.
  
  Returns a numpy.ndarray with the given shape and order=memorder.
  """
  # Read the data into a flat array.
  if dtype is None:
    dtype = _miraw_helpers.inferDtypeFromFilename(f)
  raw = np.fromfile(f, dtype=dtype)
  
  # Resolve the shape argument.
  shape = np.array(shape)
  num_voxels = np.prod(shape)
  if num_voxels < 0:
    num_voxels = -num_voxels
    missing_dim = int(raw.shape[0] / num_voxels)
    if num_voxels * missing_dim != raw.shape[0]:
      err = (('File has %i voxels; you gave me shape = %s = %i voxels,\n' +
              'which does not divide evenly.') %
             (raw.shape[0], repr(shape.tolist()), num_voxels))
      raise ValueError(err)
    # Replace the missing dimension.
    shape = np.where(shape < 0, missing_dim, shape)
  
  # Reshape the flat array, interpreting according to the disk order.
  try:
    X = np.ndarray(shape=shape, dtype=dtype, buffer=raw.data, order=diskorder)
  except TypeError:
    num_voxels = np.prod(shape)
    if num_voxels != raw.shape[0]:
      err = ('File has %i voxels; you gave me shape = %s = %i voxels.' %
             (raw.shape[0], repr(shape.tolist()), num_voxels))
      raise ValueError(err)
    else:
      raise
  
  # Now convert to the memory order and return.
  return _miraw_helpers.ndcopyWithOrder(X, memorder)