Skip to content

Commit 516e84d

Browse files
author
Adam Richie-Halford
committed
Add EddyQuad interface
1 parent 35b58cd commit 516e84d

File tree

2 files changed

+215
-1
lines changed

2 files changed

+215
-1
lines changed

nipype/interfaces/fsl/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
WarpPointsFromStd, RobustFOV, CopyGeom, MotionOutliers)
2222

2323
from .epi import (PrepareFieldmap, TOPUP, ApplyTOPUP, Eddy, EPIDeWarp, SigLoss,
24-
EddyCorrect, EpiReg)
24+
EddyCorrect, EpiReg, EddyQuad)
2525
from .dti import (BEDPOSTX, XFibres, DTIFit, ProbTrackX, ProbTrackX2, VecReg,
2626
ProjThresh, FindTheBiggest, DistanceMap, TractSkeleton,
2727
MakeDyadicVectors, BEDPOSTX5, XFibres5)

nipype/interfaces/fsl/epi.py

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,3 +1232,217 @@ def _run_interface(self, runtime):
12321232
if runtime.stderr:
12331233
self.raise_exception(runtime)
12341234
return runtime
1235+
1236+
1237+
class EddyQuadInputSpec(FSLCommandInputSpec):
1238+
base_name = traits.Str(
1239+
'eddy_corrected',
1240+
argstr='%s',
1241+
desc="Basename (including path) specified when running EDDY",
1242+
position=0,
1243+
)
1244+
idx_file = File(
1245+
exists=True,
1246+
mandatory=True,
1247+
argstr="--eddyIdx=%s",
1248+
desc=("File containing indices for all volumes into acquisition "
1249+
"parameters")
1250+
)
1251+
param_file = File(
1252+
exists=True,
1253+
mandatory=True,
1254+
argstr="--eddyParams=%s",
1255+
desc="File containing acquisition parameters"
1256+
)
1257+
mask_file = File(
1258+
exists=True,
1259+
mandatory=True,
1260+
argstr="--mask=%s",
1261+
desc="Binary mask file"
1262+
)
1263+
bval_file = File(
1264+
exists=True,
1265+
mandatory=True,
1266+
argstr="--bvals=%s",
1267+
desc="b-values file"
1268+
)
1269+
bvec_file = File(
1270+
exists=True,
1271+
mandatory=False,
1272+
argstr="--bvecs=%s",
1273+
desc=("b-vectors file - only used when <base_name>.eddy_residuals "
1274+
"file is present")
1275+
)
1276+
output_dir = traits.Str(
1277+
'eddy_corrected.qc',
1278+
mandatory=False,
1279+
argstr='--output-dir=%s',
1280+
desc="Output directory - default = '<base_name>.qc'",
1281+
)
1282+
field = File(
1283+
mandatory=False,
1284+
argstr='--field=%s',
1285+
desc="TOPUP estimated field (in Hz)",
1286+
)
1287+
slspec = File(
1288+
mandatory=False,
1289+
argstr='--slspec=%s',
1290+
desc="Text file specifying slice/group acquisition",
1291+
)
1292+
verbose = traits.Bool(
1293+
False,
1294+
mandatory=False,
1295+
argstr='--verbose',
1296+
desc="Display debug messages",
1297+
)
1298+
1299+
1300+
class EddyQuadOutputSpec(TraitedSpec):
1301+
out_qc_json = File(
1302+
exists=True,
1303+
mandatory=True,
1304+
desc=("Single subject database containing quality metrics and data "
1305+
"info.")
1306+
)
1307+
out_qc_pdf = File(
1308+
exists=True,
1309+
mandatory=True,
1310+
desc="Single subject QC report."
1311+
)
1312+
out_avg_b_png = traits.List(
1313+
File(
1314+
exists=True,
1315+
mandatory=True,
1316+
desc=("Image showing mid-sagittal, -coronal and -axial slices of "
1317+
"each averaged b-shell volume.")
1318+
)
1319+
)
1320+
out_avg_b0_png = traits.List(
1321+
File(
1322+
exists=True,
1323+
mandatory=False,
1324+
desc=("Image showing mid-sagittal, -coronal and -axial slices of "
1325+
"each averaged pe-direction b0 volume. Generated when using "
1326+
"the -f option.")
1327+
)
1328+
)
1329+
out_cnr_png = traits.List(
1330+
File(
1331+
exists=True,
1332+
mandatory=False,
1333+
desc=("Image showing mid-sagittal, -coronal and -axial slices of "
1334+
"each b-shell CNR volume. Generated when CNR maps are "
1335+
"available.")
1336+
)
1337+
)
1338+
out_vdm_png = File(
1339+
exists=True,
1340+
mandatory=False,
1341+
desc=("Image showing mid-sagittal, -coronal and -axial slices of "
1342+
"the voxel displacement map. Generated when using the -f "
1343+
"option.")
1344+
)
1345+
out_residuals = File(
1346+
exists=True,
1347+
mandatory=False,
1348+
desc=("Text file containing the volume-wise mask-averaged squared "
1349+
"residuals. Generated when residual maps are available.")
1350+
)
1351+
out_clean_volumes = File(
1352+
exists=True,
1353+
mandatory=False,
1354+
desc=("Text file containing a list of clean volumes, based on "
1355+
"the eddy squared residuals. To generate a version of the "
1356+
"pre-processed dataset without outlier volumes, use: "
1357+
"`fslselectvols -i <eddy_corrected_data> -o "
1358+
"eddy_corrected_data_clean --vols=vols_no_outliers.txt`")
1359+
)
1360+
1361+
1362+
class EddyQuad(FSLCommand):
1363+
"""
1364+
Interface for FSL eddy_quad, a tool for generating single subject reports
1365+
and storing the quality assessment indices for each subject.
1366+
`User guide <https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/eddyqc/UsersGuide>`_
1367+
1368+
Examples
1369+
--------
1370+
1371+
>>> from nipype.interfaces.fsl import EddyQuad
1372+
>>> quad = EddyQuad()
1373+
>>> quad.inputs.in_file = 'epi.nii'
1374+
>>> quad.inputs.in_mask = 'epi_mask.nii'
1375+
>>> quad.inputs.in_index = 'epi_index.txt'
1376+
>>> quad.inputs.in_acqp = 'epi_acqp.txt'
1377+
>>> quad.inputs.in_bvec = 'bvecs.scheme'
1378+
>>> quad.inputs.in_bval = 'bvals.scheme'
1379+
>>> quad.inputs.use_cuda = True
1380+
>>> quad.cmdline # doctest: +ELLIPSIS
1381+
'eddy_cuda --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme \
1382+
--bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt \
1383+
--mask=epi_mask.nii --niter=5 --nvoxhp=1000 --out=.../eddy_corrected'
1384+
>>> quad.cmdline # doctest: +ELLIPSIS
1385+
'eddy_openmp --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme \
1386+
--bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt \
1387+
--mask=epi_mask.nii --niter=5 --nvoxhp=1000 --out=.../eddy_corrected'
1388+
>>> res = quad.run() # doctest: +SKIP
1389+
1390+
"""
1391+
_cmd = 'eddy_quad'
1392+
input_spec = EddyQuadInputSpec
1393+
output_spec = EddyQuadOutputSpec
1394+
1395+
def __init__(self, **inputs):
1396+
super(EddyQuad, self).__init__(**inputs)
1397+
1398+
def _list_outputs(self):
1399+
outputs = self.output_spec().get()
1400+
out_dir = self.inputs.output_dir
1401+
outputs['out_qc_json'] = os.path.abspath(
1402+
os.path.join(self.inputs.output_dir, 'out.json')
1403+
)
1404+
outputs['out_qc_json'] = os.path.abspath(
1405+
os.path.join(self.inputs.output_dir, 'out.json')
1406+
)
1407+
outputs['out_parameter'] = os.path.abspath(
1408+
'%s.eddy_parameters' % self.inputs.out_base)
1409+
1410+
# File generation might depend on the version of EDDY
1411+
out_rotated_bvecs = os.path.abspath(
1412+
'%s.eddy_rotated_bvecs' % self.inputs.out_base)
1413+
out_movement_rms = os.path.abspath(
1414+
'%s.eddy_movement_rms' % self.inputs.out_base)
1415+
out_restricted_movement_rms = os.path.abspath(
1416+
'%s.eddy_restricted_movement_rms' % self.inputs.out_base)
1417+
out_shell_alignment_parameters = os.path.abspath(
1418+
'%s.eddy_post_eddy_shell_alignment_parameters' %
1419+
self.inputs.out_base)
1420+
out_outlier_report = os.path.abspath(
1421+
'%s.eddy_outlier_report' % self.inputs.out_base)
1422+
if isdefined(self.inputs.cnr_maps) and self.inputs.cnr_maps:
1423+
out_cnr_maps = os.path.abspath(
1424+
'%s.eddy_cnr_maps.nii.gz' % self.inputs.out_base)
1425+
if os.path.exists(out_cnr_maps):
1426+
outputs['out_cnr_maps'] = out_cnr_maps
1427+
if isdefined(self.inputs.residuals) and self.inputs.residuals:
1428+
out_residuals = os.path.abspath(
1429+
'%s.eddy_residuals.nii.gz' % self.inputs.out_base)
1430+
if os.path.exists(out_residuals):
1431+
outputs['out_residuals'] = out_residuals
1432+
1433+
if os.path.exists(out_rotated_bvecs):
1434+
outputs['out_rotated_bvecs'] = out_rotated_bvecs
1435+
if os.path.exists(out_movement_rms):
1436+
outputs['out_movement_rms'] = out_movement_rms
1437+
if os.path.exists(out_restricted_movement_rms):
1438+
outputs['out_restricted_movement_rms'] = \
1439+
out_restricted_movement_rms
1440+
if os.path.exists(out_shell_alignment_parameters):
1441+
outputs['out_shell_alignment_parameters'] = \
1442+
out_shell_alignment_parameters
1443+
if os.path.exists(out_outlier_report):
1444+
outputs['out_outlier_report'] = out_outlier_report
1445+
1446+
return outputs
1447+
1448+

0 commit comments

Comments
 (0)