예제 #1
0
def execute(): #pylint: disable=unused-variable
  shells = [ int(round(float(x))) for x in image.mrinfo('dwi.mif', 'shell_bvalues').split() ]

  # Get lmax information (if provided)
  lmax = [ ]
  if app.ARGS.lmax:
    lmax = [ int(x.strip()) for x in app.ARGS.lmax.split(',') ]
    if not len(lmax) == len(shells):
      raise MRtrixError('Number of manually-defined lmax\'s (' + str(len(lmax)) + ') does not match number of b-value shells (' + str(len(shells)) + ')')
    for shell_l in lmax:
      if shell_l % 2:
        raise MRtrixError('Values for lmax must be even')
      if shell_l < 0:
        raise MRtrixError('Values for lmax must be non-negative')

  # Do we have directions, or do we need to calculate them?
  if not os.path.exists('dirs.mif'):
    run.command('dwi2tensor dwi.mif - -mask in_voxels.mif | tensor2metric - -vector dirs.mif')

  # Get response function
  bvalues_option = ' -shells ' + ','.join(map(str,shells))
  lmax_option = ''
  if lmax:
    lmax_option = ' -lmax ' + ','.join(map(str,lmax))
  run.command('amp2response dwi.mif in_voxels.mif dirs.mif response.txt' + bvalues_option + lmax_option)

  run.function(shutil.copyfile, 'response.txt', path.from_user(app.ARGS.output, False))
  if app.ARGS.voxels:
    run.command('mrconvert in_voxels.mif ' + path.from_user(app.ARGS.voxels), mrconvert_keyval=path.from_user(app.ARGS.input, False), force=app.FORCE_OVERWRITE)
예제 #2
0
def check_gif_input(image_path):
  from mrtrix3 import image, MRtrixError
  dim = image.Header(image_path).size()
  if len(dim) < 4:
    raise MRtrixError('Image \'' + image_path + '\' does not look like GIF segmentation (less than 4 spatial dimensions)')
  if min(dim[:4]) == 1:
    raise MRtrixError('Image \'' + image_path + '\' does not look like GIF segmentation (axis with size 1)')
예제 #3
0
def dot(input_a, input_b):  #pylint: disable=unused-variable
    from mrtrix3 import MRtrixError
    if not input_a:
        if input_b:
            raise MRtrixError('Dimension mismatch (0 vs. ' +
                              str(len(input_b)) + ')')
        return []
    if is_2d_matrix(input_a):
        if not is_2d_matrix(input_b):
            raise MRtrixError(
                'Both inputs must be either 1D vectors or 2D matrices')
        if len(input_a[0]) != len(input_b):
            raise MRtrixError('Invalid dimensions for matrix dot product(' + \
                                  str(len(input_a)) + 'x' + str(len(input_a[0])) + ' vs. ' + \
                                  str(len(input_b)) + 'x' + str(len(input_b[0])) + ')')
        return [[
            sum(x * y for x, y in zip(a_row, b_col)) for b_col in zip(*input_b)
        ] for a_row in input_a]
    if is_2d_matrix(input_b):
        raise MRtrixError(
            'Both inputs must be either 1D vectors or 2D matrices')
    if len(input_a) != len(input_b):
        raise MRtrixError('Dimension mismatch (' + str(len(input_a)) +
                          ' vs. ' + str(len(input_b)) + ')')
    return sum([x * y for x, y in zip(input_a, input_b)])
예제 #4
0
def execute(): #pylint: disable=unused-variable
  if utils.is_windows():
    raise MRtrixError('Script cannot run using FSL on Windows due to FSL dependency')

  if not os.environ.get('FSLDIR', ''):
    raise MRtrixError('Environment variable FSLDIR is not set; please run appropriate FSL configuration script')

  fast_cmd = fsl.exe_name('fast')

  app.warn('Use of fsl algorithm in dwibiascorrect script is discouraged due to its strong dependence ' + \
           'on brain masking (specifically its inability to correct voxels outside of this mask).' + \
           'Use of the ants algorithm is recommended for quantitative DWI analyses.')

  # Generate a mean b=0 image
  run.command('dwiextract in.mif - -bzero | mrmath - mean mean_bzero.mif -axis 3')

  # FAST doesn't accept a mask input; therefore need to explicitly mask the input image
  run.command('mrcalc mean_bzero.mif mask.mif -mult - | mrconvert - mean_bzero_masked.nii -strides -1,+2,+3')
  run.command(fast_cmd + ' -t 2 -o fast -n 3 -b mean_bzero_masked.nii')
  bias_path = fsl.find_image('fast_bias')

  # Rather than using a bias field estimate of 1.0 outside the brain mask, zero-fill the
  #   output image outside of this mask
  run.command('mrcalc in.mif ' + bias_path + ' -div mask.mif -mult result.mif')
  run.command('mrconvert result.mif ' + path.from_user(app.ARGS.output), mrconvert_keyval=path.from_user(app.ARGS.input, False), force=app.FORCE_OVERWRITE)
  if app.ARGS.bias:
    run.command('mrconvert ' + bias_path + ' ' + path.from_user(app.ARGS.bias), mrconvert_keyval=path.from_user(app.ARGS.input, False), force=app.FORCE_OVERWRITE)
예제 #5
0
def execute():  #pylint: disable=unused-variable
    lut_input_path = 'LUT.txt'
    if not os.path.exists('LUT.txt'):
        freesurfer_home = os.environ.get('FREESURFER_HOME', '')
        if not freesurfer_home:
            raise MRtrixError(
                'Environment variable FREESURFER_HOME is not set; please run appropriate FreeSurfer configuration script, set this variable manually, or provide script with path to file FreeSurferColorLUT.txt using -lut option'
            )
        lut_input_path = os.path.join(freesurfer_home,
                                      'FreeSurferColorLUT.txt')
        if not os.path.isfile(lut_input_path):
            raise MRtrixError(
                'Could not find FreeSurfer lookup table file (expected location: '
                + lut_input_path + '), and none provided using -lut')

    if app.ARGS.sgm_amyg_hipp:
        lut_output_file_name = 'FreeSurfer2ACT_sgm_amyg_hipp.txt'
    else:
        lut_output_file_name = 'FreeSurfer2ACT.txt'
    lut_output_path = os.path.join(path.shared_data_path(),
                                   path.script_subdir_name(),
                                   lut_output_file_name)
    if not os.path.isfile(lut_output_path):
        raise MRtrixError(
            'Could not find lookup table file for converting FreeSurfer parcellation output to tissues (expected location: '
            + lut_output_path + ')')

    # Initial conversion from FreeSurfer parcellation to five principal tissue types
    run.command('labelconvert input.mif ' + lut_input_path + ' ' +
                lut_output_path + ' indices.mif')

    # Crop to reduce file size
    if app.ARGS.nocrop:
        image = 'indices.mif'
    else:
        image = 'indices_cropped.mif'
        run.command(
            'mrthreshold indices.mif - -abs 0.5 | mrgrid indices.mif crop ' +
            image + ' -mask -')

    # Convert into the 5TT format for ACT
    run.command('mrcalc ' + image + ' 1 -eq cgm.mif')
    run.command('mrcalc ' + image + ' 2 -eq sgm.mif')
    run.command('mrcalc ' + image + ' 3 -eq  wm.mif')
    run.command('mrcalc ' + image + ' 4 -eq csf.mif')
    run.command('mrcalc ' + image + ' 5 -eq path.mif')

    run.command(
        'mrcat cgm.mif sgm.mif wm.mif csf.mif path.mif - -axis 3 | mrconvert - result.mif -datatype float32'
    )

    run.command('mrconvert result.mif ' + path.from_user(app.ARGS.output),
                mrconvert_keyval=path.from_user(app.ARGS.input, False),
                force=app.FORCE_OVERWRITE)
예제 #6
0
def check_3d_nonunity(image_in): #pylint: disable=unused-variable
  from mrtrix3 import app #pylint: disable=import-outside-toplevel
  if not isinstance(image_in, Header):
    if not isinstance(image_in, STRING_TYPES):
      raise MRtrixError('Error trying to test \'' + str(image_in) + '\': Not an image header or file path')
    image_in = Header(image_in)
  if len(image_in.size()) < 3:
    raise MRtrixError('Image \'' + image_in.name() + '\' does not contain 3 spatial dimensions')
  if min(image_in.size()[:3]) == 1:
    raise MRtrixError('Image \'' + image_in.name() + '\' does not contain 3D spatial information (has axis with size 1)')
  app.debug('Image \'' + image_in.name() + '\' is >= 3D, and does not contain a unity spatial dimension')
예제 #7
0
파일: matrix.py 프로젝트: bcdarwin/mrtrix3
def load_transform(filename, **kwargs): #pylint: disable=unused-variable
  data = load_matrix(filename, **kwargs)
  if len(data) == 4:
    if any(a!=b for a, b in zip(data[3], _TRANSFORM_LAST_ROW)):
      raise MRtrixError('File "' + filename + '" does not contain a valid transform (fourth line contains values other than "0,0,0,1")')
  elif len(data) == 3:
    data.append(_TRANSFORM_LAST_ROW)
  else:
    raise MRtrixError('File "' + filename + '" does not contain a valid transform (must contain 3 or 4 lines)')
  if len(data[0]) != 4:
    raise MRtrixError('File "' + filename + '" does not contain a valid transform (must contain 4 columns)')
  return data
예제 #8
0
def match(image_one, image_two, **kwargs): #pylint: disable=unused-variable, too-many-return-statements
  from mrtrix3 import app #pylint: disable=import-outside-toplevel
  up_to_dim = kwargs.pop('up_to_dim', 0)
  check_transform = kwargs.pop('check_transform', True)
  if kwargs:
    raise TypeError('Unsupported keyword arguments passed to image.match(): ' + str(kwargs))
  if not isinstance(image_one, Header):
    if not isinstance(image_one, STRING_TYPES):
      raise MRtrixError('Error trying to test \'' + str(image_one) + '\': Not an image header or file path')
    image_one = Header(image_one)
  if not isinstance(image_two, Header):
    if not isinstance(image_two, STRING_TYPES):
      raise MRtrixError('Error trying to test \'' + str(image_two) + '\': Not an image header or file path')
    image_two = Header(image_two)
  debug_prefix = '\'' + image_one.name() + '\' \'' + image_two.name() + '\''
  # Handle possibility of only checking up to a certain axis
  if up_to_dim:
    if up_to_dim > min(len(image_one.size()), len(image_two.size())):
      app.debug(debug_prefix + ' dimensionality less than specified maximum (' + str(up_to_dim) + ')')
      return False
  else:
    if len(image_one.size()) != len(image_two.size()):
      app.debug(debug_prefix + ' dimensionality mismatch (' + str(len(image_one.size())) + ' vs. ' + str(len(image_two.size())) + ')')
      return False
    up_to_dim = len(image_one.size())
  # Image dimensions
  if not image_one.size()[:up_to_dim] == image_two.size()[:up_to_dim]:
    app.debug(debug_prefix + ' axis size mismatch (' + str(image_one.size()) + ' ' + str(image_two.size()) + ')')
    return False
  # Voxel size
  for one, two in zip(image_one.spacing()[:up_to_dim], image_two.spacing()[:up_to_dim]):
    if one and two and not math.isnan(one) and not math.isnan(two):
      if (abs(two-one) / (0.5*(one+two))) > 1e-04:
        app.debug(debug_prefix + ' voxel size mismatch (' + str(image_one.spacing()) + ' ' + str(image_two.spacing()) + ')')
        return False
  # Image transform
  if check_transform:
    for line_one, line_two in zip(image_one.transform(), image_two.transform()):
      for one, two in zip(line_one[:3], line_two[:3]):
        if abs(one-two) > 1e-4:
          app.debug(debug_prefix + ' transform (rotation) mismatch (' + str(image_one.transform()) + ' ' + str(image_two.transform()) + ')')
          return False
      if abs(line_one[3]-line_two[3]) > 1e-2:
        app.debug(debug_prefix + ' transform (translation) mismatch (' + str(image_one.transform()) + ' ' + str(image_two.transform()) + ')')
        return False
  # Everything matches!
  app.debug(debug_prefix + ' image match')
  return True
예제 #9
0
파일: fsl.py 프로젝트: MRtrix3/mrtrix3
def suffix():  #pylint: disable=unused-variable
    from mrtrix3 import app  #pylint: disable=import-outside-toplevel
    global _SUFFIX
    if _SUFFIX:
        return _SUFFIX
    fsl_output_type = os.environ.get('FSLOUTPUTTYPE', '')
    if fsl_output_type == 'NIFTI':
        app.debug('NIFTI -> .nii')
        _SUFFIX = '.nii'
    elif fsl_output_type == 'NIFTI_GZ':
        app.debug('NIFTI_GZ -> .nii.gz')
        _SUFFIX = '.nii.gz'
    elif fsl_output_type == 'NIFTI_PAIR':
        app.debug('NIFTI_PAIR -> .img')
        _SUFFIX = '.img'
    elif fsl_output_type == 'NIFTI_PAIR_GZ':
        raise MRtrixError(
            'MRtrix3 does not support compressed NIFTI pairs; please change FSLOUTPUTTYPE environment variable'
        )
    elif fsl_output_type:
        app.warn(
            'Unrecognised value for environment variable FSLOUTPUTTYPE (\"' +
            fsl_output_type +
            '\"): Expecting compressed NIfTIs, but FSL commands may fail')
        _SUFFIX = '.nii.gz'
    else:
        app.warn(
            'Environment variable FSLOUTPUTTYPE not set; FSL commands may fail, or script may fail to locate FSL command outputs'
        )
        _SUFFIX = '.nii.gz'
    return _SUFFIX
예제 #10
0
파일: matrix.py 프로젝트: bcdarwin/mrtrix3
def load_matrix(filename, **kwargs): #pylint: disable=unused-variable
  data = load_numeric(filename, **kwargs)
  columns = len(data[0])
  for line in data[1:]:
    if len(line) != columns:
      raise MRtrixError('Inconsistent number of columns in matrix text file "' + filename + '"')
  return data
예제 #11
0
def execute(): #pylint: disable=unused-variable
  if not find_executable('N4BiasFieldCorrection'):
    raise MRtrixError('Could not find ANTS program N4BiasFieldCorrection; please check installation')

  for key in sorted(OPT_N4_BIAS_FIELD_CORRECTION):
    if hasattr(app.ARGS, 'ants.' + key):
      val = getattr(app.ARGS, 'ants.' + key)
      if val is not None:
        OPT_N4_BIAS_FIELD_CORRECTION[key] = (val, 'user defined')
  ants_options = ' '.join(['-%s %s' %(k, v[0]) for k, v in OPT_N4_BIAS_FIELD_CORRECTION.items()])

  # Generate a mean b=0 image
  run.command('dwiextract in.mif - -bzero | mrmath - mean mean_bzero.mif -axis 3')

  # Use the brain mask as a weights image rather than a mask; means that voxels at the edge of the mask
  #   will have a smoothly-varying bias field correction applied, rather than multiplying by 1.0 outside the mask
  run.command('mrconvert mean_bzero.mif mean_bzero.nii -strides +1,+2,+3')
  run.command('mrconvert mask.mif mask.nii -strides +1,+2,+3')
  init_bias_path = 'init_bias.nii'
  corrected_path = 'corrected.nii'
  run.command('N4BiasFieldCorrection -d 3 -i mean_bzero.nii -w mask.nii -o [' + corrected_path + ',' + init_bias_path + '] ' + ants_options)

  # N4 can introduce large differences between subjects via a global scaling of the bias field
  # Estimate this scaling based on the total integral of the pre- and post-correction images within the brain mask
  input_integral  = float(run.command('mrcalc mean_bzero.mif mask.mif -mult - | mrmath - sum - -axis 0 | mrmath - sum - -axis 1 | mrmath - sum - -axis 2 | mrdump -').stdout)
  output_integral = float(run.command('mrcalc ' + corrected_path + ' mask.mif -mult - | mrmath - sum - -axis 0 | mrmath - sum - -axis 1 | mrmath - sum - -axis 2 | mrdump -').stdout)
  multiplier = output_integral / input_integral
  app.debug('Integrals: Input = ' + str(input_integral) + '; Output = ' + str(output_integral) + '; resulting multiplier = ' + str(multiplier))
  run.command('mrcalc ' + init_bias_path + ' ' + str(multiplier) + ' -mult bias.mif')

  # Common final steps for all algorithms
  run.command('mrcalc in.mif bias.mif -div result.mif')
  run.command('mrconvert result.mif ' + path.from_user(app.ARGS.output), mrconvert_keyval=path.from_user(app.ARGS.input, False), force=app.FORCE_OVERWRITE)
  if app.ARGS.bias:
    run.command('mrconvert bias.mif ' + path.from_user(app.ARGS.bias), mrconvert_keyval=path.from_user(app.ARGS.input, False), force=app.FORCE_OVERWRITE)
예제 #12
0
def execute(): #pylint: disable=unused-variable

  grad_option = ''
  if app.ARGS.grad:
    grad_option = ' -grad ' + path.from_user(app.ARGS.grad)
  elif app.ARGS.fslgrad:
    grad_option = ' -fslgrad ' + path.from_user(app.ARGS.fslgrad[0]) + ' ' + path.from_user(app.ARGS.fslgrad[1])

  if app.ARGS.percentile:
    if app.ARGS.percentile < 0.0 or app.ARGS.percentile > 100.0:
      raise MRtrixError('-percentile value must be between 0 and 100')
    intensities = [float(value) for value in run.command('dwiextract ' + path.from_user(app.ARGS.input_dwi) + grad_option + ' -bzero - | ' + \
                                                         'mrmath - mean - -axis 3 | ' + \
                                                         'mrdump - -mask ' + path.from_user(app.ARGS.input_mask)).stdout.splitlines()]
    intensities = sorted(intensities)
    float_index = 0.01 * app.ARGS.percentile * len(intensities)
    lower_index = int(math.floor(float_index))
    if app.ARGS.percentile == 100.0:
      reference_value = intensities[-1]
    else:
      interp_mu = float_index - float(lower_index)
      reference_value = (1.0-interp_mu)*intensities[lower_index] + interp_mu*intensities[lower_index+1]
  else:
    reference_value = float(run.command('dwiextract ' + path.from_user(app.ARGS.input_dwi) + grad_option + ' -bzero - | ' + \
                                        'mrmath - mean - -axis 3 | ' + \
                                        'mrstats - -mask ' + path.from_user(app.ARGS.input_mask) + ' -output median').stdout)
  multiplier = app.ARGS.intensity / reference_value

  run.command('mrcalc ' + path.from_user(app.ARGS.input_dwi) + ' ' + str(multiplier) + ' -mult - | ' + \
              'mrconvert - ' + path.from_user(app.ARGS.output_dwi) + grad_option, \
              mrconvert_keyval=path.from_user(app.ARGS.input_dwi, False), \
              force=app.FORCE_OVERWRITE)
예제 #13
0
파일: matrix.py 프로젝트: bcdarwin/mrtrix3
def load_vector(filename, **kwargs): #pylint: disable=unused-variable
  data = load_matrix(filename, **kwargs)
  if len(data) == 1:
    return data[0]
  for line in data:
    if len(line) != 1:
      raise MRtrixError('File "' + filename + '" does not contain vector data (multiple columns detected)')
  return [ line[0] for line in data ]
예제 #14
0
 def __init__(self, image_path):
     from mrtrix3 import app, path, run  #pylint: disable=import-outside-toplevel
     filename = path.name_temporary('json')
     command = [
         run.exe_name(run.version_match('mrinfo')), image_path, '-json_all',
         filename
     ]
     if app.VERBOSITY > 1:
         app.console('Loading header for image file \'' + image_path + '\'')
     app.debug(str(command))
     result = subprocess.call(command, stdout=None, stderr=None)
     if result:
         raise MRtrixError(
             'Could not access header information for image \'' +
             image_path + '\'')
     try:
         with open(filename, 'r') as json_file:
             data = json.load(json_file)
     except UnicodeDecodeError:
         with open(filename, 'r') as json_file:
             data = json.loads(json_file.read().decode('utf-8',
                                                       errors='replace'))
     os.remove(filename)
     try:
         #self.__dict__.update(data)
         # Load the individual header elements manually, for a couple of reasons:
         # - So that pylint knows that they'll be there
         # - Write to private members, and give read-only access
         self._name = data['name']
         self._size = data['size']
         self._spacing = data['spacing']
         self._strides = data['strides']
         self._format = data['format']
         self._datatype = data['datatype']
         self._intensity_offset = data['intensity_offset']
         self._intensity_scale = data['intensity_scale']
         self._transform = data['transform']
         if not 'keyval' in data or not data['keyval']:
             self._keyval = {}
         else:
             self._keyval = data['keyval']
     except:
         raise MRtrixError(
             'Error in reading header information from file \'' +
             image_path + '\'')
     app.debug(str(vars(self)))
예제 #15
0
def direction(string):  #pylint: disable=unused-variable
    from mrtrix3 import app  #pylint: disable=import-outside-toplevel
    pe_dir = ''
    try:
        pe_axis = abs(int(string))
        if pe_axis > 2:
            raise MRtrixError(
                'When specified as a number, phase encode axis must be either 0, 1 or 2 (positive or negative)'
            )
        reverse = (string.contains('-'))  # Allow -0
        pe_dir = [0, 0, 0]
        if reverse:
            pe_dir[pe_axis] = -1
        else:
            pe_dir[pe_axis] = 1
    except:
        string = string.lower()
        if string == 'lr':
            pe_dir = [1, 0, 0]
        elif string == 'rl':
            pe_dir = [-1, 0, 0]
        elif string == 'pa':
            pe_dir = [0, 1, 0]
        elif string == 'ap':
            pe_dir = [0, -1, 0]
        elif string == 'is':
            pe_dir = [0, 0, 1]
        elif string == 'si':
            pe_dir = [0, 0, -1]
        elif string == 'i':
            pe_dir = [1, 0, 0]
        elif string == 'i-':
            pe_dir = [-1, 0, 0]
        elif string == 'j':
            pe_dir = [0, 1, 0]
        elif string == 'j-':
            pe_dir = [0, -1, 0]
        elif string == 'k':
            pe_dir = [0, 0, 1]
        elif string == 'k-':
            pe_dir = [0, 0, -1]
        else:
            raise MRtrixError(
                'Unrecognized phase encode direction specifier: ' + string)
    app.debug(string + ' -> ' + str(pe_dir))
    return pe_dir
예제 #16
0
def save(filename, scheme, **kwargs):  #pylint: disable=unused-variable
    from mrtrix3 import matrix  #pylint: disable=import-outside-toplevel
    add_to_command_history = bool(kwargs.pop('add_to_command_history', True))
    header = kwargs.pop('header', {})
    if kwargs:
        raise TypeError(
            'Unsupported keyword arguments passed to phaseencoding.save(): ' +
            str(kwargs))

    if not scheme:
        raise MRtrixError(
            'phaseencoding.save() cannot be run on an empty scheme')
    if not matrix.is_2d_matrix(scheme):
        raise TypeError('Input to phaseencoding.save() must be a 2D matrix')
    if len(scheme[0]) != 4:
        raise MRtrixError('Input to phaseencoding.save() not a valid scheme '
                          '(contains ' + str(len(scheme[0])) +
                          ' columns rather than 4)')

    if header:
        if isinstance(header, STRING_TYPES):
            header = {'comments': header}
        elif isinstance(header, list):
            header = {'comments': '\n'.join(str(entry) for entry in header)}
        elif isinstance(header, dict):
            header = dict((key, str(value)) for key, value in header.items())
        else:
            raise TypeError(
                'Unrecognised input to matrix.save_numeric() using "header=" option'
            )
    else:
        header = {}

    if add_to_command_history and COMMAND_HISTORY_STRING:
        if 'command_history' in header:
            header['command_history'] += '\n' + COMMAND_HISTORY_STRING
        else:
            header['command_history'] = COMMAND_HISTORY_STRING

    with open(filename, 'w') as outfile:
        for key, value in sorted(header.items()):
            for line in value.splitlines():
                outfile.write('# ' + key + ': ' + line + '\n')
        for line in scheme:
            outfile.write('{:.0f} {:.0f} {:.0f} {:.15g}\n'.format(*line))
예제 #17
0
파일: fsl.py 프로젝트: MRtrix3/mrtrix3
def get_inputs(): #pylint: disable=unused-variable
  image.check_3d_nonunity(path.from_user(app.ARGS.input, False))
  run.command('mrconvert ' + path.from_user(app.ARGS.input) + ' ' + path.to_scratch('input.mif'))
  if app.ARGS.mask:
    run.command('mrconvert ' + path.from_user(app.ARGS.mask) + ' ' + path.to_scratch('mask.mif') + ' -datatype bit -strides -1,+2,+3')
  if app.ARGS.t2:
    if not image.match(path.from_user(app.ARGS.input, False), path.from_user(app.ARGS.t2, False)):
      raise MRtrixError('Provided T2 image does not match input T1 image')
    run.command('mrconvert ' + path.from_user(app.ARGS.t2) + ' ' + path.to_scratch('T2.nii') + ' -strides -1,+2,+3')
예제 #18
0
def _shebang(item):
    import os
    from distutils.spawn import find_executable
    from mrtrix3 import app, MRtrixError, utils

    # If a complete path has been provided rather than just a file name, don't perform any additional file search
    if os.sep in item:
        path = item
    else:
        path = version_match(item)
        if path == item:
            path = find_executable(exe_name(item))
    if not path:
        app.debug('File \"' + item + '\": Could not find file to query')
        return []
    # Read the first 1024 bytes of the file
    with open(path, 'rb') as file_in:
        data = file_in.read(1024)
    # Try to find the shebang line
    for line in data.splitlines():
        # Are there any non-text characters? If so, it's a binary file, so no need to looking for a shebang
        try:
            line = str(line.decode('utf-8'))
        except:
            app.debug('File \"' + item + '\": Not a text file')
            return []
        line = line.strip()
        if len(line) > 2 and line[0:2] == '#!':
            # Need to strip first in case there's a gap between the shebang symbol and the interpreter path
            shebang = line[2:].strip().split(' ')
            if utils.is_windows():
                # On Windows, /usr/bin/env can't be easily found, and any direct interpreter path will have a similar issue.
                #   Instead, manually find the right interpreter to call using distutils
                if os.path.basename(shebang[0]) == 'env':
                    new_shebang = [
                        os.path.abspath(find_executable(exe_name(shebang[1])))
                    ]
                    new_shebang.extend(shebang[2:])
                    shebang = new_shebang
                else:
                    new_shebang = [
                        os.path.abspath(
                            find_executable(
                                exe_name(os.path.basename(shebang[0]))))
                    ]
                    new_shebang.extend(shebang[1:])
                    shebang = new_shebang
                if not shebang or not shebang[0]:
                    raise MRtrixError('malformed shebang in file \"' + item +
                                      '\": \"' + line + '\"')
            app.debug('File \"' + item + '\": string \"' + line + '\": ' +
                      str(shebang))
            return shebang
    app.debug('File \"' + item + '\": No shebang found')
    return []
예제 #19
0
def exe_name(name): #pylint: disable=unused-variable
  from mrtrix3 import app, MRtrixError
  from distutils.spawn import find_executable
  if find_executable(name):
    output = name
  elif find_executable('fsl5.0-' + name):
    output = 'fsl5.0-' + name
  else:
    raise MRtrixError('Could not find FSL program \"' + name + '\"; please verify FSL install')
  app.debug(output)
  return output
예제 #20
0
def check_first(prefix, structures): #pylint: disable=unused-variable
  import os
  from mrtrix3 import app, MRtrixError, path
  vtk_files = [ prefix + '-' + struct + '_first.vtk' for struct in structures ]
  existing_file_count = sum([ os.path.exists(filename) for filename in vtk_files ])
  if existing_file_count != len(vtk_files):
    if 'SGE_ROOT' in os.environ and os.environ['SGE_ROOT']:
      app.console('FSL FIRST job may have been run via SGE; awaiting completion')
      app.console('(note however that FIRST may fail silently, and hence this script may hang indefinitely)')
      path.wait_for(vtk_files)
    else:
      raise MRtrixError('FSL FIRST has failed; ' + ('only ' if existing_file_count else '') + str(existing_file_count) + ' of ' + str(len(vtk_files)) + ' structures were segmented successfully (check ' + path.to_scratch('first.logs', False) + ')')
예제 #21
0
def find_image(name): #pylint: disable=unused-variable
  import os
  from mrtrix3 import app, MRtrixError
  prefix = os.path.join(os.path.dirname(name), os.path.basename(name).split('.')[0])
  if os.path.isfile(prefix + suffix()):
    app.debug('Image at expected location: \"' + prefix + suffix() + '\"')
    return prefix + suffix()
  for suf in ['.nii', '.nii.gz', '.img']:
    if os.path.isfile(prefix + suf):
      app.debug('Expected image at \"' + prefix + suffix() + '\", but found at \"' + prefix + suf + '\"')
      return prefix + suf
  raise MRtrixError('Unable to find FSL output file for path \"' + name + '\"')
예제 #22
0
파일: fsl.py 프로젝트: MRtrix3/mrtrix3
def exe_name(name):  #pylint: disable=unused-variable
    from mrtrix3 import app  #pylint: disable=import-outside-toplevel
    if find_executable(name):
        output = name
    elif find_executable('fsl5.0-' + name):
        output = 'fsl5.0-' + name
        app.warn('Using FSL binary \"' + output + '\" rather than \"' + name +
                 '\"; suggest checking FSL installation')
    else:
        raise MRtrixError('Could not find FSL program \"' + name +
                          '\"; please verify FSL install')
    app.debug(output)
    return output
예제 #23
0
def version_match(item):
  from mrtrix3 import app #pylint: disable=import-outside-toplevel
  if not item in EXE_LIST:
    app.debug('Command ' + item + ' not found in MRtrix3 bin/ directory')
    return item
  exe_path_manual = os.path.join(BIN_PATH, exe_name(item))
  if os.path.isfile(exe_path_manual):
    app.debug('Version-matched executable for ' + item + ': ' + exe_path_manual)
    return exe_path_manual
  exe_path_sys = find_executable(exe_name(item))
  if exe_path_sys and os.path.isfile(exe_path_sys):
    app.debug('Using non-version-matched executable for ' + item + ': ' + exe_path_sys)
    return exe_path_sys
  raise MRtrixError('Unable to find executable for MRtrix3 command ' + item)
예제 #24
0
def statistics(image_path, **kwargs):  #pylint: disable=unused-variable
    from mrtrix3 import app, run  #pylint: disable=import-outside-toplevel
    mask = kwargs.pop('mask', None)
    allvolumes = kwargs.pop('allvolumes', False)
    ignorezero = kwargs.pop('ignorezero', False)
    if kwargs:
        raise TypeError(
            'Unsupported keyword arguments passed to image.statistics(): ' +
            str(kwargs))

    command = [run.exe_name(run.version_match('mrstats')), image_path]
    for stat in IMAGE_STATISTICS:
        command.extend(['-output', stat])
    if mask:
        command.extend(['-mask', mask])
    if allvolumes:
        command.append('-allvolumes')
    if ignorezero:
        command.append('-ignorezero')
    if app.VERBOSITY > 1:
        app.console('Command: \'' + ' '.join(command) +
                    '\' (piping data to local storage)')

    try:
        from subprocess import DEVNULL  #pylint: disable=import-outside-toplevel
    except ImportError:
        DEVNULL = open(os.devnull, 'wb')
    proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=DEVNULL)
    stdout = proc.communicate()[0]
    if proc.returncode:
        raise MRtrixError(
            'Error trying to calculate statistics from image \'' + image_path +
            '\'')
    stdout_lines = [
        line.strip() for line in stdout.decode('cp437').splitlines()
    ]
    result = []
    for line in stdout_lines:
        line = line.replace('N/A', 'nan').split()
        assert len(line) == len(IMAGE_STATISTICS)
        result.append(
            ImageStatistics(float(line[0]), float(line[1]), float(line[2]),
                            float(line[3]), float(line[4]), float(line[5]),
                            int(line[6])))
    if len(result) == 1:
        result = result[0]
    if app.VERBOSITY > 1:
        app.console('Result: ' + str(result))
    return result
예제 #25
0
def check_output_path(item): #pylint: disable=unused-variable
  global ARGS, FORCE_OVERWRITE, WORKING_DIR
  if not item:
    return
  abspath = os.path.abspath(os.path.join(WORKING_DIR, item))
  if os.path.exists(abspath):
    item_type = ''
    if os.path.isfile(abspath):
      item_type = ' file'
    elif os.path.isdir(abspath):
      item_type = ' directory'
    if FORCE_OVERWRITE:
      warn('Output' + item_type + ' \'' + item + '\' already exists; will be overwritten at script completion')
    else:
      raise MRtrixError('Output' + item_type + ' \'' + item + '\' already exists (use -force to override)')
예제 #26
0
def axis2dir(string): #pylint: disable=unused-variable
  from mrtrix3 import app #pylint: disable=import-outside-toplevel
  if string == 'i':
    direction = [1,0,0]
  elif string == 'i-':
    direction = [-1,0,0]
  elif string == 'j':
    direction = [0,1,0]
  elif string == 'j-':
    direction = [0,-1,0]
  elif string == 'k':
    direction = [0,0,1]
  elif string == 'k-':
    direction = [0,0,-1]
  else:
    raise MRtrixError('Unrecognized NIfTI axis & direction specifier: ' + string)
  app.debug(string + ' -> ' + str(direction))
  return direction
예제 #27
0
def get_scheme(arg):  #pylint: disable=unused-variable
    from mrtrix3 import app, image, MRtrixError
    if not isinstance(arg, image.Header):
        if not isinstance(arg, str):
            raise MRtrixError(
                'Error trying to derive phase-encoding scheme from \'' +
                str(arg) + '\': Not an image header or file path')
        arg = image.Header(arg)
    if 'pe_scheme' in arg.keyval():
        app.debug(str(arg.keyval()['pe_scheme']))
        return arg.keyval()['pe_scheme']
    if 'PhaseEncodingDirection' not in arg.keyval():
        return None
    line = direction(arg.keyval()['PhaseEncodingDirection'])
    if 'TotalReadoutTime' in arg.keyval():
        line = [float(value) for value in line]
        line.append(float(arg.keyval()['TotalReadoutTime']))
    num_volumes = 1 if len(arg.size()) < 4 else arg.size()[3]
    app.debug(str(line) + ' x ' + str(num_volumes) + ' rows')
    return [line] * num_volumes
예제 #28
0
def version_match(item):
    import os
    from distutils.spawn import find_executable
    from mrtrix3 import app, BIN_PATH, EXE_LIST, MRtrixError

    if not item in EXE_LIST:
        app.debug('Command ' + item + ' not found in MRtrix3 bin/ directory')
        return item

    exe_path_manual = os.path.join(BIN_PATH, exe_name(item))
    if os.path.isfile(exe_path_manual):
        app.debug('Version-matched executable for ' + item + ': ' +
                  exe_path_manual)
        return exe_path_manual

    exe_path_sys = find_executable(exe_name(item))
    if exe_path_sys and os.path.isfile(exe_path_sys):
        app.debug('Using non-version-matched executable for ' + item + ': ' +
                  exe_path_sys)
        return exe_path_sys
    raise MRtrixError('Unable to find executable for MRtrix3 command ' + item)
예제 #29
0
def statistic(image_path, stat, options=''): #pylint: disable=unused-variable
  import shlex, subprocess
  from mrtrix3 import app, MRtrixError, run
  command = [ run.exe_name(run.version_match('mrstats')), image_path, '-output', stat ]
  if options:
    command.extend(shlex.split(options))
  if app.VERBOSITY > 1:
    app.console('Command: \'' + ' '.join(command) + '\' (piping data to local storage)')
  proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
  result = [ line.strip() for line in proc.communicate()[0].decode('cp437').splitlines() ]
  if stat == 'count':
    result = [ int(i) for i in result ]
  else:
    result = [ float(f) for f in result ]
  if len(result) == 1:
    result = result[0]
  if app.VERBOSITY > 1:
    app.console('Result: ' + str(result))
  if proc.returncode:
    raise MRtrixError('Error trying to calculate statistic \'' + stat + '\' from image \'' + image_path + '\'')
  return result
예제 #30
0
def execute():  #pylint: disable=unused-variable
    import shutil
    from mrtrix3 import app, image, MRtrixError, path, run
    bvalues = [
        int(round(float(x)))
        for x in image.mrinfo('dwi.mif', 'shell_bvalues').split()
    ]
    if len(bvalues) < 2:
        raise MRtrixError('Need at least 2 unique b-values (including b=0).')
    lmax_option = ''
    if app.ARGS.lmax:
        lmax_option = ' -lmax ' + app.ARGS.lmax
    if not app.ARGS.mask:
        run.command('maskfilter mask.mif erode mask_eroded.mif -npass ' +
                    str(app.ARGS.erode))
        mask_path = 'mask_eroded.mif'
    else:
        mask_path = 'mask.mif'
    run.command('dwi2tensor dwi.mif -mask ' + mask_path + ' tensor.mif')
    run.command(
        'tensor2metric tensor.mif -fa fa.mif -vector vector.mif -mask ' +
        mask_path)
    if app.ARGS.threshold:
        run.command('mrthreshold fa.mif voxels.mif -abs ' +
                    str(app.ARGS.threshold))
    else:
        run.command('mrthreshold fa.mif voxels.mif -top ' +
                    str(app.ARGS.number))
    run.command(
        'dwiextract dwi.mif - -singleshell -no_bzero | amp2response - voxels.mif vector.mif response.txt'
        + lmax_option)

    run.function(shutil.copyfile, 'response.txt',
                 path.from_user(app.ARGS.output, False))
    if app.ARGS.voxels:
        run.command('mrconvert voxels.mif ' + path.from_user(app.ARGS.voxels),
                    mrconvert_keyval=path.from_user(app.ARGS.input),
                    force=app.FORCE_OVERWRITE)