-
Notifications
You must be signed in to change notification settings - Fork 182
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #785 from MRtrix3/tag_0.3.16
Tag 0.3.16
- Loading branch information
Showing
1,123 changed files
with
49,587 additions
and
47,550 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/usr/bin/env python | ||
|
||
# Script that generates a five-tissue-type (5TT) segmented image: the format appropriate for ACT | ||
# | ||
# In this script, major stages of processing can be performed in one of two ways: | ||
# - Using FSL tools: BET for brain extraction, FAST for tissue segmentation, FIRST for sub-cortical grey matter segmentation | ||
# - Using segmentations from FreeSurfer | ||
# Alternative algorithms for performing this conversion can be added by creating a new file in lib/mrtrix3/_5ttgen/ and | ||
# defining the appropriate functions; 5ttgen will automatically make that algorithm available at the command-line | ||
|
||
|
||
# Make the corresponding MRtrix3 Python libraries available | ||
import inspect, os, sys | ||
lib_folder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile(inspect.currentframe()))[0], os.pardir, 'lib'))) | ||
if not os.path.isdir(lib_folder): | ||
sys.stderr.write('Unable to locate MRtrix3 Python libraries') | ||
sys.exit(1) | ||
sys.path.insert(0, lib_folder) | ||
|
||
|
||
from mrtrix3 import algorithm, app, path, run | ||
|
||
app.init('Robert E. Smith (robert.smith@florey.edu.au)', 'Generate a 5TT image suitable for ACT') | ||
app.cmdline.addCitation('', 'Smith, R. E.; Tournier, J.-D.; Calamante, F. & Connelly, A. Anatomically-constrained tractography: Improved diffusion MRI streamlines tractography through effective use of anatomical information. NeuroImage, 2012, 62, 1924-1938', False) | ||
app.cmdline.addDescription('5ttgen acts as a \'master\' script for generating a five-tissue-type (5TT) segmented tissue image suitable for use in Anatomically-Constrained Tractography (ACT). A range of different algorithms are available for completing this task. When using this script, the name of the algorithm to be used must appear as the first argument on the command-line after \'5ttgen\'. The subsequent compulsory arguments and options available depend on the particular algorithm being invoked.') | ||
app.cmdline.addDescription('Each algorithm available also has its own help page, including necessary references; e.g. to see the help page of the \'fsl\' algorithm, type \'5ttgen fsl\'.') | ||
|
||
common_options = app.cmdline.add_argument_group('Options common to all 5ttgen algorithms') | ||
common_options.add_argument('-nocrop', action='store_true', default=False, help='Do NOT crop the resulting 5TT image to reduce its size (keep the same dimensions as the input image)') | ||
common_options.add_argument('-sgm_amyg_hipp', action='store_true', default=False, help='Represent the amygdalae and hippocampi as sub-cortical grey matter in the 5TT image') | ||
|
||
# Import the command-line settings for all algorithms found in the relevant directory | ||
algorithm.initialise() | ||
|
||
app.parse() | ||
|
||
# Find out which algorithm the user has requested | ||
alg = algorithm.getModule(app.args.algorithm) | ||
|
||
app.checkOutputPath(app.args.output) | ||
alg.checkOutputPaths() | ||
|
||
app.makeTempDir() | ||
run.command('mrconvert ' + path.fromUser(app.args.input, True) + ' ' + path.toTemp('input.mif', True)) | ||
alg.getInputs() | ||
|
||
app.gotoTempDir() | ||
|
||
alg.execute() | ||
|
||
(stdout,stderr) = run.command('5ttcheck result.mif', False) | ||
if len(stderr) and 'ERROR' in stderr: | ||
app.warn('Generated image does not perfectly conform to 5TT format') | ||
|
||
run.command('mrconvert result.mif ' + path.fromUser(app.args.output, True) + (' -force' if app.force else '')) | ||
app.complete() | ||
|
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
#!/usr/bin/env python | ||
|
||
# Script for estimating response functions for spherical deconvolution | ||
# A number of different approaches are available within this script for performing response function estimation. | ||
|
||
|
||
# Make the corresponding MRtrix3 Python libraries available | ||
import inspect, os, sys | ||
lib_folder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile(inspect.currentframe()))[0], os.pardir, 'lib'))) | ||
if not os.path.isdir(lib_folder): | ||
sys.stderr.write('Unable to locate MRtrix3 Python libraries') | ||
sys.exit(1) | ||
sys.path.insert(0, lib_folder) | ||
|
||
|
||
from mrtrix3 import algorithm, app, image, path, run | ||
|
||
|
||
app.init('Robert E. Smith (robert.smith@florey.edu.au) and Thijs Dhollander (thijs.dhollander@gmail.com)', | ||
'Estimate response function(s) for spherical deconvolution') | ||
app.cmdline.addDescription('dwi2response acts as a \'master\' script for performing various types of response function estimation; a range of different algorithms are available for completing this task. When using this script, the name of the algorithm to be used must appear as the first argument on the command-line after \'dwi2response\'. The subsequent compulsory arguments and options available depend on the particular algorithm being invoked.') | ||
app.cmdline.addDescription('Each algorithm available also has its own help page, including necessary references; e.g. to see the help page of the \'fa\' algorithm, type \'dwi2response fa\'.') | ||
|
||
# General options | ||
common_options = app.cmdline.add_argument_group('Options common to all dwi2response algorithms') | ||
common_options.add_argument('-shell', help='The b-value shell(s) to use in response function estimation (single value for single-shell response, comma-separated list for multi-shell response)') | ||
common_options.add_argument('-lmax', help='The maximum harmonic degree(s) of response function estimation (single value for single-shell response, comma-separated list for multi-shell response)') | ||
common_options.add_argument('-mask', help='Provide an initial mask for response voxel selection') | ||
common_options.add_argument('-voxels', help='Output an image showing the final voxel selection(s)') | ||
common_options.add_argument('-grad', help='Pass the diffusion gradient table in MRtrix format') | ||
common_options.add_argument('-fslgrad', nargs=2, metavar=('bvecs', 'bvals'), help='Pass the diffusion gradient table in FSL bvecs/bvals format') | ||
app.cmdline.flagMutuallyExclusiveOptions( [ 'grad', 'fslgrad' ] ) | ||
|
||
# Import the command-line settings for all algorithms found in the relevant directory | ||
algorithm.initialise() | ||
|
||
|
||
app.parse() | ||
|
||
|
||
# Find out which algorithm the user has requested | ||
alg = algorithm.getModule(app.args.algorithm) | ||
|
||
|
||
# Check for prior existence of output files, and grab any input files, used by the particular algorithm | ||
if app.args.voxels: | ||
app.checkOutputPath(app.args.voxels) | ||
alg.checkOutputPaths() | ||
|
||
|
||
# Sanitise some inputs, and get ready for data import | ||
if app.args.lmax: | ||
try: | ||
lmax = [ int(x) for x in app.args.lmax.split(',') ] | ||
if any([lmax_value%2 for lmax_value in lmax]): | ||
app.error('Value of lmax must be even') | ||
except: | ||
app.error('Parameter lmax must be a number') | ||
if alg.needsSingleShell() and not len(lmax) == 1: | ||
app.error('Can only specify a single lmax value for single-shell algorithms') | ||
shell_option = '' | ||
if app.args.shell: | ||
try: | ||
shell_values = [ int(x) for x in app.args.shell.split(',') ] | ||
except: | ||
app.error('-shell option should provide a comma-separated list of b-values') | ||
if alg.needsSingleShell() and not len(shell_values) == 1: | ||
app.error('Can only specify a single b-value shell for single-shell algorithms') | ||
shell_option = ' -shell ' + app.args.shell | ||
singleshell_option = '' | ||
if alg.needsSingleShell(): | ||
singleshell_option = ' -singleshell -no_bzero' | ||
|
||
grad_import_option = '' | ||
if app.args.grad: | ||
grad_import_option = ' -grad ' + path.fromUser(app.args.grad, True) | ||
elif app.args.fslgrad: | ||
grad_import_option = ' -fslgrad ' + path.fromUser(app.args.fslgrad[0], True) + ' ' + path.fromUser(app.args.fslgrad[1], True) | ||
elif not image.headerField(path.fromUser(app.args.input, False), 'dwgrad'): | ||
app.error('Script requires diffusion gradient table: either in image header, or using -grad / -fslgrad option') | ||
|
||
app.makeTempDir() | ||
|
||
# Get standard input data into the temporary directory | ||
if alg.needsSingleShell() or shell_option: | ||
run.command('mrconvert ' + path.fromUser(app.args.input, True) + ' - -stride 0,0,0,1' + grad_import_option + ' | dwiextract - ' + path.toTemp('dwi.mif', True) + shell_option + singleshell_option) | ||
else: # Don't discard b=0 in multi-shell algorithms | ||
run.command('mrconvert ' + path.fromUser(app.args.input, True) + ' ' + path.toTemp('dwi.mif', True) + ' -stride 0,0,0,1' + grad_import_option) | ||
if app.args.mask: | ||
run.command('mrconvert ' + path.fromUser(app.args.mask, True) + ' ' + path.toTemp('mask.mif', True) + ' -datatype bit') | ||
|
||
alg.getInputs() | ||
|
||
app.gotoTempDir() | ||
|
||
|
||
# Generate a brain mask (if necessary) | ||
# Otherwise, check that the mask provided is appropriate | ||
if os.path.exists('mask.mif'): | ||
dwi_size = [ int(x) for x in image.headerField('dwi.mif', 'size').split() ] | ||
mask_size = [ int(x) for x in image.headerField('mask.mif', 'size').split() ] | ||
if not mask_size[:3] == dwi_size[:3]: | ||
app.error('Dimensions of provided mask image do not match DWI') | ||
if int(image.statistic('mask.mif', 'count', 'mask.mif')) == 0: | ||
app.error('Input mask does not contain any voxels') | ||
else: | ||
run.command('dwi2mask dwi.mif mask.mif') | ||
|
||
|
||
# From here, the script splits depending on what estimation algorithm is being used | ||
alg.execute() | ||
|
||
|
||
# Finalize for all algorithms | ||
if app.args.voxels: | ||
run.command('mrconvert voxels.mif ' + path.fromUser(app.args.voxels, True) + (' -force' if app.force else '')) | ||
app.complete() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#!/usr/bin/env python | ||
|
||
# Script that performs B1 field inhomogeneity correction for a DWI volume series | ||
# Bias field is estimated using the mean b=0 image, and subsequently used to correct all volumes | ||
|
||
|
||
# Make the corresponding MRtrix3 Python libraries available | ||
import inspect, os, sys | ||
lib_folder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile(inspect.currentframe()))[0], os.pardir, 'lib'))) | ||
if not os.path.isdir(lib_folder): | ||
sys.stderr.write('Unable to locate MRtrix3 Python libraries') | ||
sys.exit(1) | ||
sys.path.insert(0, lib_folder) | ||
|
||
|
||
from distutils.spawn import find_executable | ||
from mrtrix3 import app, fsl, image, path, run | ||
|
||
|
||
app.init('Robert E. Smith (robert.smith@florey.edu.au)', | ||
'Perform B1 field inhomogeneity correction for a DWI volume series') | ||
app.cmdline.addCitation('If using -fast option', 'Zhang, Y.; Brady, M. & Smith, S. Segmentation of brain MR images through a hidden Markov random field model and the expectation-maximization algorithm. IEEE Transactions on Medical Imaging, 2001, 20, 45-57', True) | ||
app.cmdline.addCitation('If using -fast option', 'Smith, S. M.; Jenkinson, M.; Woolrich, M. W.; Beckmann, C. F.; Behrens, T. E.; Johansen-Berg, H.; Bannister, P. R.; De Luca, M.; Drobnjak, I.; Flitney, D. E.; Niazy, R. K.; Saunders, J.; Vickers, J.; Zhang, Y.; De Stefano, N.; Brady, J. M. & Matthews, P. M. Advances in functional and structural MR image analysis and implementation as FSL. NeuroImage, 2004, 23, S208-S219', True) | ||
app.cmdline.addCitation('If using -ants option', 'Tustison, N.; Avants, B.; Cook, P.; Zheng, Y.; Egan, A.; Yushkevich, P. & Gee, J. N4ITK: Improved N3 Bias Correction. IEEE Transactions on Medical Imaging, 2010, 29, 1310-1320', True) | ||
app.cmdline.add_argument('input', help='The input image series to be corrected') | ||
app.cmdline.add_argument('output', help='The output corrected image series') | ||
options = app.cmdline.add_argument_group('Options for the dwibiascorrect script') | ||
options.add_argument('-mask', help='Manually provide a mask image for bias field estimation') | ||
options.add_argument('-bias', help='Output the estimated bias field') | ||
options.add_argument('-ants', action='store_true', help='Use ANTS N4 to estimate the inhomogeneity field') | ||
options.add_argument('-fsl', action='store_true', help='Use FSL FAST to estimate the inhomogeneity field') | ||
app.cmdline.flagMutuallyExclusiveOptions( [ 'ants', 'fsl' ] ) | ||
options.add_argument('-grad', help='Pass the diffusion gradient table in MRtrix format') | ||
options.add_argument('-fslgrad', nargs=2, metavar=('bvecs', 'bvals'), help='Pass the diffusion gradient table in FSL bvecs/bvals format') | ||
app.cmdline.flagMutuallyExclusiveOptions( [ 'grad', 'fslgrad' ] ) | ||
app.parse() | ||
|
||
if app.args.fsl: | ||
|
||
if app.isWindows(): | ||
app.error('Script cannot run using FSL on Windows due to FSL dependency') | ||
|
||
fsl_path = os.environ.get('FSLDIR', '') | ||
if not fsl_path: | ||
app.error('Environment variable FSLDIR is not set; please run appropriate FSL configuration script') | ||
|
||
fast_cmd = 'fast' | ||
if not find_executable(fast_cmd): | ||
fast_cmd = 'fsl5.0-fast' | ||
if not find_executable(fast_cmd): | ||
app.error('Could not find FSL program fast; please verify FSL install') | ||
|
||
fsl_suffix = fsl.suffix() | ||
if fast_cmd == 'fast': | ||
fast_suffix = fsl_suffix | ||
else: | ||
fast_suffix = '.nii.gz' | ||
|
||
elif app.args.ants: | ||
|
||
if not find_executable('N4BiasFieldCorrection'): | ||
app.error('Could not find ANTS program N4BiasFieldCorrection; please check installation') | ||
|
||
else: | ||
app.error('No bias field estimation algorithm specified') | ||
|
||
grad_import_option = '' | ||
if app.args.grad: | ||
grad_import_option = ' -grad ' + path.fromUser(app.args.grad, True) | ||
elif app.args.fslgrad: | ||
grad_import_option = ' -fslgrad ' + path.fromUser(app.args.fslgrad[0], True) + ' ' + path.fromUser(app.args.fslgrad[1], True) | ||
|
||
app.checkOutputPath(app.args.output) | ||
app.checkOutputPath(app.args.bias) | ||
|
||
app.makeTempDir() | ||
|
||
run.command('mrconvert ' + path.fromUser(app.args.input, True) + ' ' + path.toTemp('in.mif', True) + grad_import_option) | ||
if app.args.mask: | ||
run.command('mrconvert ' + path.fromUser(app.args.mask, True) + ' ' + path.toTemp('mask.mif', True)) | ||
|
||
app.gotoTempDir() | ||
|
||
# Make sure it's actually a DWI that's been passed | ||
dwi_sizes = image.headerField('in.mif', 'size').split() | ||
if len(dwi_sizes) != 4: | ||
app.error('Input image must be a 4D image') | ||
DW_scheme = image.headerField('in.mif', 'dwgrad').split('\n') | ||
if len(DW_scheme) != int(dwi_sizes[3]): | ||
app.error('Input image does not contain valid DW gradient scheme') | ||
|
||
# Generate a brain mask if required, or check the mask if provided | ||
if app.args.mask: | ||
mask_sizes = image.headerField('mask.mif', 'size').split() | ||
if not mask_sizes[:3] == dwi_sizes[:3]: | ||
app.error('Provided mask image does not match input DWI') | ||
else: | ||
run.command('dwi2mask in.mif mask.mif') | ||
|
||
# Generate a mean b=0 image | ||
run.command('dwiextract in.mif - -bzero | mrmath - mean mean_bzero.mif -axis 3') | ||
|
||
if app.args.fsl: | ||
# 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 -stride -1,+2,+3') | ||
run.command(fast_cmd + ' -t 2 -o fast -n 3 -b mean_bzero_masked.nii') | ||
bias_path = 'fast_bias' + fast_suffix | ||
elif app.args.ants: | ||
|
||
# If the mask image was provided manually, and doesn't match the input image perfectly | ||
# (i.e. also transform and voxel sizes), N4 will fail | ||
if app.args.mask: | ||
if not image.match('mean_bzero.mif', 'mask.mif'): | ||
app.error('Input mask header does not perfectly match DWI as required by N4') | ||
|
||
# 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 -stride +1,+2,+3') | ||
run.command('mrconvert mask.mif mask.nii -stride +1,+2,+3') | ||
bias_path = 'bias.nii' | ||
run.command('N4BiasFieldCorrection -d 3 -i mean_bzero.nii -w mask.nii -o [corrected.nii,' + bias_path + '] -s 2 -b [150] -c [200x200,0.0]') | ||
|
||
run.command('mrcalc in.mif ' + bias_path + ' -div result.mif') | ||
run.command('mrconvert result.mif ' + path.fromUser(app.args.output, True) + (' -force' if app.force else '')) | ||
if app.args.bias: | ||
run.command('mrconvert ' + bias_path + ' ' + path.fromUser(app.args.bias, True) + (' -force' if app.force else '')) | ||
app.complete() | ||
|
Oops, something went wrong.