New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script changes #1449

Open
wants to merge 51 commits into
base: dev
from
Commits
File filter...
Filter file types
Jump to file or symbol
Failed to load files and symbols.
+59 −10
Diff settings

Always

Just for now

dwipreproc: Run and export eddyqc

If -eddyqc_text or -eddyqc_all options are specificed, additionally check for the presence of script 'eddy_quad' in the PATH, and if it is installed, execute it and export the resulting directory to the path specified by the user.
  • Loading branch information...
Lestropie committed Oct 10, 2018
commit 35ac775829b1ade54c14952b271fd4e78b280caf
Copy path View file
@@ -44,8 +44,8 @@ def usage(cmdline): #pylint: disable=unused-variable
options.add_argument('-json_import', metavar=('file'), help='Import image header information from an associated JSON file (may be necessary to determine phase encoding information)')
options.add_argument('-topup_options', metavar=('TopupOptions'), help='Manually provide additional command-line options to the topup command (provide a string within quotation marks that contains at least one space, even if only passing a single command-line option to topup)')
options.add_argument('-eddy_options', metavar=('EddyOptions'), help='Manually provide additional command-line options to the eddy command (provide a string within quotation marks that contains at least one space, even if only passing a single command-line option to eddy)')
options.add_argument('-eddyqc_text', metavar=('directory'), help='Copy the various text-based statistical outputs generated by eddy into an output directory')
options.add_argument('-eddyqc_all', metavar=('directory'), help='Copy ALL outputs generated by eddy (including images) into an output directory')
options.add_argument('-eddyqc_text', metavar=('directory'), help='Copy the various text-based statistical outputs generated by eddy, and the output of eddy_qc (if installed), into an output directory')
options.add_argument('-eddyqc_all', metavar=('directory'), help='Copy ALL outputs generated by eddy (including images), and the output of eddy_qc (if installed), into an output directory')
rpe_options = cmdline.add_argument_group('Options for specifying the acquisition phase-encoding design; note that one of the -rpe_* options MUST be provided')
rpe_options.add_argument('-rpe_none', action='store_true', help='Specify that no reversed phase-encoding image data is being provided; eddy will perform eddy current and motion correction only')
rpe_options.add_argument('-rpe_pair', action='store_true', help='Specify that a set of images (typically b=0 volumes) will be provided for use in inhomogeneity field estimation only (using the -se_epi option). It is assumed that the FIRST volume(s) of this image has the SAME phase-encoding direction as the input DWIs, and the LAST volume(s) has precisely the OPPOSITE phase encoding')
@@ -65,6 +65,7 @@ def usage(cmdline): #pylint: disable=unused-variable

def execute(): #pylint: disable=unused-variable
import itertools, json, math, shutil
from distutils.spawn import find_executable
from mrtrix3 import config, fsl, fsys, image, isWindows, MRtrixError, phaseEncoding, run

if isWindows():
@@ -862,20 +863,15 @@ def execute(): #pylint: disable=unused-variable
else:
eddy_output = run.command(eddy_openmp_cmd + ' ' + eddy_all_options)
if app.verbosity > 2:
app.console('Output of OpenMP eddy command:\n' + eddy_output.stdout + '\n' + eddy_output.stderr)
app.console('Output of eddy command:\n' + eddy_output.stdout + '\n' + eddy_output.stderr)
fsys.delTemporary('eddy_in.nii')
fsys.delTemporary('eddy_mask.nii')
if do_topup:
fsys.delTemporary(fsl.findImage('field_fieldcoef'))


with open('eddy_output.txt', 'w') as f:
f.write(eddy_output.stdout + '\n' + eddy_output.stderr)
eddy_output_image_path = fsl.findImage('dwi_post_eddy')


# Get the axis strides from the input series, so the output image can be modified to match
stride_option = ' -strides ' + ','.join([str(i) for i in dwi_header.strides()])


# Check to see whether or not eddy has provided a rotated bvecs file;
# if it has, import this into the output image
bvecs_path = 'dwi_post_eddy.eddy_rotated_bvecs'
@@ -884,6 +880,52 @@ def execute(): #pylint: disable=unused-variable
bvecs_path = 'bvecs'


# Run eddy qc tool QUAD if installed and one of -eddyqc_text or -eddyqc_all is specified
if eddyqc_path:
eddyqc_cmd = find_executable('eddy_quad')
if eddyqc_cmd:
# The eddy_quad script is not compatible with Python 2; try to explicitly invoke Python 3
if sys.version_info[0] == 2:
if find_executable('python3'):
eddyqc_cmd = 'python3 ' + eddyqc_cmd
else:
eddyqc_cmd = 'eddy_quad'
eddyqc_options = '-idx eddy_indices.txt -par eddy_config.txt -m eddy_mask.nii -b bvals'
if os.path.isfile('dwi_post_eddy.eddy_residuals'):
eddyqc_options += ' -g ' + bvecs_path
if do_topup:
eddyqc_options += ' -f ' + fsl.findImage('field_fieldcoef')
if eddy_mporder:
eddyqc_options += ' -s slspec.txt'
if app.verbosity > 2:
eddyqc_options += ' -v'
try:
run.command(eddyqc_cmd + ' dwi_post_eddy ' + eddyqc_options)
except run.MRtrixCmdError as e:
app.warn('Error running automated eddy qc tool QUAD; data will not be provided')
app.debug(str(e))
# Delete the directory if the script only made it partway through
try:
shutil.rmtree('dwi_post_eddy.qc')
except OSError:
pass
else:
app.console('Command \'eddy_quad\' not found in PATH; not running automated eddy qc tool QUAD')


# Have to retain these images until after eddyQC is run
# If using -eddyqc_all, also write the mask provided to eddy to the output directory;
# therefore don't delete it yet here
if not app.args.eddyqc_all:
fsys.delTemporary('eddy_mask.nii')
if do_topup:
fsys.delTemporary(fsl.findImage('field_fieldcoef'))


# Get the axis strides from the input series, so the output image can be modified to match
stride_option = ' -strides ' + ','.join([str(i) for i in dwi_header.strides()])


# Determine whether or not volume recombination should be performed
# This could be either due to use of -rpe_all option, or just due to the data provided with -rpe_header
# Rather than trying to re-use the code that was used in the case of -rpe_all, run fresh code
@@ -1064,6 +1106,13 @@ def execute(): #pylint: disable=unused-variable
for filename in eddyqc_files:
if os.path.exists('dwi_post_eddy.' + filename):
run.function(shutil.copy, 'dwi_post_eddy.' + filename, os.path.join(eddyqc_path, filename))
# Also grab any files generated by the eddy qc tool QUAD
if os.path.isdir('dwi_post_eddy.qc'):
run.function(shutil.copytree, 'dwi_post_eddy.qc', os.path.join(eddyqc_path, 'quad'))
# Also grab the brain mask that was provided to eddy if -eddyqc_all was specified
if app.args.eddyqc_all:
run.function(shutil.copy, 'eddy_mask.nii', os.path.join(eddyqc_path, 'eddy_mask.nii'))
fsys.delTemporary('eddy_mask.nii')


keys_to_remove = [ 'EchoTime', 'FlipAngle', 'MultibandAccelerationFactor', 'PhaseEncodingDirection', 'RepetitionTime', 'SliceEncodingDirection', 'SliceTiming', 'TotalReadoutTime', 'pe_scheme' ]
ProTip! Use n and p to navigate between commits in a pull request.