Example #1
0
 def rawToNifti(infile, sizefile=None, outfile=None, dimorder=None, diskorder='F', dtype=None, split4=False):
   """Converts a raw file to a NIfTI file.
   
   Arguments:
     infile:    Filename of a raw file.
     sizefile:  Filename of a size_info config file.  If None, attempts to find
                this file in the same directory as infile.
     outfile:   Filename (including .nii) of the NIfTI file to generate.
                If None, it will be generated from infile.
     dimorder:  Four-character string that is a permutation of "XYZI",
                indicating the dimension order of the image in "infile".
                  The purpose of this argument is to rearrange the order of the
                dimensions in the infile to match the NIfTI canonical order of
                (X, Y, Z, I), where I is the dimension along which multiple
                acquisitions are concatenated.
                  The default value, None, is equivalent to "XYZI".
                  Note that this argument will be overridden if the size_info
                file contains a "dimension_order" value.
     diskorder: A string, 'F' or 'C', representing the order in which the data
                values are stored in the raw file.
     dtype:     The numpy dtype for the infile.  If None, it is inferred from
                infile's extension.
     split4:    If True, output numbered 3-D images from 4-D input.
   """
   (raw, cfg) = readRawWithSizeInfo(infile, sizefile=sizefile, dtype=dtype,
                                    dimorder=dimorder, diskorder=diskorder,
                                    memorder='C')
   vox_sz = cfg['voxel_size_(mm)']
   
   # Rearrange dimensions.
   try:
     dimorder = cfg['dimension_order']
   except KeyError:
     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))
   raw_transp = raw.transpose(_miraw_helpers.dimorderToReverseDimmap(dimorder))
   
   if split4 and len(raw_transp.shape) == 4:
     raw_stack = [raw_transp[:,:,:,i] for i in range(raw_transp.shape[3])]
   else:
     raw_stack = [raw_transp]
   i = 0
   for img in raw_stack:
     nii = nifti1.Nifti1Pair(img, np.diag(vox_sz + [0.0]))
     nii.get_header().set_xyzt_units('mm')
     outfname = outfile
     if outfname is None:
       outfname = os.path.splitext(infile)[0] + '.nii'
     if split4:
       outfname = os.path.splitext(outfname)[0] + ('_%03i.nii' % i)
       i += 1
     nifti1.save(nii, outfname)
Example #2
0
def undoDimOrderOnList(L, dimorder):
  """Permutes the values in L to restore them to a default dimorder.
  
  Arguments:
    L:        A list of four values, corresponding (in order) to the dimensions
              of some dataset.
    dimorder: Four-character string that is a permutation of "XYZI",
              indicating the current dimension order of the dataset.
  
  Returns a permuted version of L, with values corresponding (respectively) to
  the X, Y, Z, and I.
  """
  return [L[i] for i in _miraw_helpers.dimorderToReverseDimmap(dimorder)]
Example #3
0
def undoDimOrder(img, dimorder):
  """Permutes the data dimensions of img, which currently has the given
  dimension order, to match the default "XYZI" dimension order.
  
  Arguments:
    img:      numpy ndarray with four dimensions.
    dimorder: Four-character string that is a permutation of "XYZI",
              indicating the current dimension order of img.
  
  Returns new_img:
    new_img:  numpy ndarray with four dimensions.  The values in new_img will
              be rearranged so that the dimension order is XYZI.
  """
  return img.transpose(_miraw_helpers.dimorderToReverseDimmap(dimorder))
Example #4
0
def saveSizeInfo(f, img, vox_sz=(1,1,1), dimorder=None, size_cfg={}, infer_name=False):
  """Writes a size_info metadata file to disk for a given array.
  
  A size_info file stores image (array) dimensions for raw images, as well as
  voxel size and cropping information (indicating that the array is cropped
  from a larger volume).  Note that size_info is designed for 3-D or 4-D
  arrays only, and stores the extents of the first three dimensions
  separately from that of the fourth.
  
  Arguments:
    f:          An open file handle or a filename for the destination file.
    img:        A numpy.ndarray.
    vox_sz:     Optional array-like object with 2 or 3 entries.
    dimorder:   Four-character string that is a permutation of "XYZI",
                indicating the dimension order of the image "img".
                  The purpose of this argument is to map from the dimension
                extents represented in img.shape to the extents stored in the
                size_info file, which are always stored in a canonical "XYZI"
                order.  Namely, if we create a 4-tuple "dimmap" by converting
                each character X->0, Y->1, Z->2, I->3, then
                   sz[dimmap[i]] = img.shape[i]
                for i from 0 to 3, where sz is the volume size, in (X,Y,Z,I)
                order, that will be stored in the size_info.
                  The default value, None, is equivalent to "XYZI".
    size_cfg:   Optional dictionary of other config key-value pairs.  The data
                stored in this dictionary override all values computed by or
                passed into this function, even if they're inconsistent with
                the size of the image.  Be careful!  This includes the
                "dimension_order" value, which overrides the dimorder argument
                above.
    infer_name: Optional boolean.  If True, and f is a filename, then the
                file actually written will be in the same directory as f
                (or in f if f is a path ending with a slash), and named
                "size_info".  If f is not a string, this option has no effect.
  """
  # Deal with filenames and open a file for writing, if necessary.
  if isinstance(f, str):
    if infer_name:
      f = os.path.join(os.path.dirname(f), 'size_info')
    fid = open(f, 'w')
    close_after = True
  else:
    fid = f
    close_after = False
  
  # Set up dimension mapping.
  shape = list(img.shape) + [1]*4
  try:
    dimorder = size_cfg['dimension_order']
  except KeyError:
    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))
  shape = np.take(shape, _miraw_helpers.dimorderToReverseDimmap(dimorder), axis=0).tolist()
  
  # Extract metadata from the arguments.
  base_keys = ['voxel_size_(mm)', 'full_image_size_(voxels)',
               'low_end_crop_(voxels)', 'cropped_image_size_(voxels)',
               'num_dwis', 'dimension_order']
  auto_cfg = {
    base_keys[0] : vox_sz,
    base_keys[1] : shape[:3],
    base_keys[2] : [0, 0, 0],
    base_keys[3] : shape[:3],
    base_keys[4] : shape[3],
    base_keys[5] : dimorder
  }
  
  # Overwrite metadata with what the user gave us.
  for (k,v) in size_cfg.items():
    auto_cfg[k] = v
  
  # Now write the key-value pairs and we're done!
  def spaceSepStr(a):
    if isinstance(a, list) or isinstance(a, tuple):
      return ' '.join([str(x) for x in a])
    return str(a)
  
  for k in base_keys:
    fid.write(k + ': ' + spaceSepStr(auto_cfg[k]) + '\n')
    del(auto_cfg[k])
  for (k, v) in auto_cfg.items():
    fid.write(k + ': ' + spaceSepStr(v) + '\n')
  
  if close_after:
    fid.close()