diff --git a/.zenodo.json b/.zenodo.json index 6e884e7594..bc34c33939 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -891,16 +891,6 @@ "name": "Mihai, Paul Glad", "orcid": "0000-0001-5715-6442" }, - { - "affiliation": "Department of Psychology, Stanford University", - "name": "Gorgolewski, Krzysztof J.", - "orcid": "0000-0003-3321-7583" - }, - { - "affiliation": "MIT, HMS", - "name": "Ghosh, Satrajit", - "orcid": "0000-0002-5312-6729" - }, { "affiliation": "University of Tübingen and MPI for Biological Cybernertics", "name": "Bannert, Michael M.", @@ -909,13 +899,27 @@ { "affiliation": "Research Centre Juelich", "name": "Wu, Jianxiao", - "orcid": "0000-0002-4866-272X", + "orcid": "0000-0002-4866-272X" + }, + { + "affiliation": "Department of Neurology, BG-University Hospital Bergmannsheil Bochum, Germany", + "name": "Butry, Lionel" }, { "affiliation": "Lund University", "name": "Anijärv, Toomas Erik", - "orcid": "0000-0002-3650-4230", + "orcid": "0000-0002-3650-4230" + }, + { + "affiliation": "Department of Psychology, Stanford University", + "name": "Gorgolewski, Krzysztof J.", + "orcid": "0000-0003-3321-7583" }, + { + "affiliation": "MIT, HMS", + "name": "Ghosh, Satrajit", + "orcid": "0000-0002-5312-6729" + } ], "keywords": [ "neuroimaging", diff --git a/nipype/interfaces/mrtrix3/__init__.py b/nipype/interfaces/mrtrix3/__init__.py index 0ff8daa510..3bd9f55250 100644 --- a/nipype/interfaces/mrtrix3/__init__.py +++ b/nipype/interfaces/mrtrix3/__init__.py @@ -30,4 +30,7 @@ SHConv, TensorMetrics, TransformFSLConvert, + MaskFilter, + MTNormalise, + Generate5tt2gmwmi, ) diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt.py b/nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt.py index 2e9a36c502..949fa26280 100644 --- a/nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt.py +++ b/nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt.py @@ -37,7 +37,6 @@ def test_Generate5tt_inputs(): ), in_file=dict( argstr="%s", - extensions=None, mandatory=True, position=-2, ), diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt2gmwmi.py b/nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt2gmwmi.py new file mode 100644 index 0000000000..2f4fc24e5d --- /dev/null +++ b/nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt2gmwmi.py @@ -0,0 +1,79 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ..utils import Generate5tt2gmwmi + + +def test_Generate5tt2gmwmi_inputs(): + input_map = dict( + args=dict( + argstr="%s", + ), + bval_scale=dict( + argstr="-bvalue_scaling %s", + ), + environ=dict( + nohash=True, + usedefault=True, + ), + grad_file=dict( + argstr="-grad %s", + extensions=None, + xor=["grad_fsl"], + ), + grad_fsl=dict( + argstr="-fslgrad %s %s", + xor=["grad_file"], + ), + in_bval=dict( + extensions=None, + ), + in_bvec=dict( + argstr="-fslgrad %s %s", + extensions=None, + ), + in_file=dict( + argstr="%s", + extensions=None, + mandatory=True, + position=-2, + ), + mask_in=dict( + argstr="-mask_in %s", + extensions=None, + position=-3, + ), + mask_out=dict( + argstr="%s", + extensions=None, + mandatory=True, + position=-1, + ), + nthreads=dict( + argstr="-nthreads %d", + nohash=True, + ), + out_bval=dict( + extensions=None, + ), + out_bvec=dict( + argstr="-export_grad_fsl %s %s", + extensions=None, + ), + ) + inputs = Generate5tt2gmwmi.input_spec() + + for key, metadata in list(input_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(inputs.traits()[key], metakey) == value + + +def test_Generate5tt2gmwmi_outputs(): + output_map = dict( + mask_out=dict( + extensions=None, + ), + ) + outputs = Generate5tt2gmwmi.output_spec() + + for key, metadata in list(output_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(outputs.traits()[key], metakey) == value diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_MTNormalise.py b/nipype/interfaces/mrtrix3/tests/test_auto_MTNormalise.py new file mode 100644 index 0000000000..8463e5a64a --- /dev/null +++ b/nipype/interfaces/mrtrix3/tests/test_auto_MTNormalise.py @@ -0,0 +1,103 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ..utils import MTNormalise + + +def test_MTNormalise_inputs(): + input_map = dict( + args=dict( + argstr="%s", + ), + bval_scale=dict( + argstr="-bvalue_scaling %s", + ), + csf_fod=dict( + argstr="%s", + extensions=None, + position=5, + ), + environ=dict( + nohash=True, + usedefault=True, + ), + gm_fod=dict( + argstr="%s", + extensions=None, + position=3, + ), + grad_file=dict( + argstr="-grad %s", + extensions=None, + xor=["grad_fsl"], + ), + grad_fsl=dict( + argstr="-fslgrad %s %s", + xor=["grad_file"], + ), + in_bval=dict( + extensions=None, + ), + in_bvec=dict( + argstr="-fslgrad %s %s", + extensions=None, + ), + mask=dict( + argstr="-mask %s", + extensions=None, + position=-1, + ), + nthreads=dict( + argstr="-nthreads %d", + nohash=True, + ), + out_bval=dict( + extensions=None, + ), + out_bvec=dict( + argstr="-export_grad_fsl %s %s", + extensions=None, + ), + out_file_csf=dict( + argstr="%s", + extensions=None, + position=6, + ), + out_file_gm=dict( + argstr="%s", + extensions=None, + position=4, + ), + out_file_wm=dict( + argstr="%s", + extensions=None, + position=2, + ), + wm_fod=dict( + argstr="%s", + extensions=None, + position=1, + ), + ) + inputs = MTNormalise.input_spec() + + for key, metadata in list(input_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(inputs.traits()[key], metakey) == value + + +def test_MTNormalise_outputs(): + output_map = dict( + out_file_csf=dict( + extensions=None, + ), + out_file_gm=dict( + extensions=None, + ), + out_file_wm=dict( + extensions=None, + ), + ) + outputs = MTNormalise.output_spec() + + for key, metadata in list(output_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(outputs.traits()[key], metakey) == value diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_MaskFilter.py b/nipype/interfaces/mrtrix3/tests/test_auto_MaskFilter.py new file mode 100644 index 0000000000..5443c09e15 --- /dev/null +++ b/nipype/interfaces/mrtrix3/tests/test_auto_MaskFilter.py @@ -0,0 +1,54 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ..utils import MaskFilter + + +def test_MaskFilter_inputs(): + input_map = dict( + args=dict( + argstr="%s", + ), + environ=dict( + nohash=True, + usedefault=True, + ), + filter=dict( + argstr="%s", + mandatory=True, + position=-2, + ), + in_file=dict( + argstr="%s", + extensions=None, + mandatory=True, + position=-3, + ), + npass=dict( + argstr="-npass %d", + position=1, + ), + out_file=dict( + argstr="%s", + extensions=None, + mandatory=True, + name_source=["input_image"], + position=-1, + ), + ) + inputs = MaskFilter.input_spec() + + for key, metadata in list(input_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(inputs.traits()[key], metakey) == value + + +def test_MaskFilter_outputs(): + output_map = dict( + out_file=dict( + extensions=None, + ), + ) + outputs = MaskFilter.output_spec() + + for key, metadata in list(output_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(outputs.traits()[key], metakey) == value diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index ed6846cea7..41d8ab6fdd 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1185,3 +1185,184 @@ def _list_outputs(self): outputs = self.output_spec().get() outputs["out_file"] = op.abspath(self.inputs.out_file) return outputs + + +class MaskFilterInputSpec(CommandLineInputSpec): + in_file = File( + exists=True, + mandatory=True, + argstr="%s", + position=-3, + desc="Input mask", + ) + filter = traits.Str( + mandatory=True, + argstr="%s", + position=-2, + desc="Filter to perform (e.g. dilate, erode)", + ) + out_file = File( + name_source=["input_image"], + mandatory=True, + argstr="%s", + position=-1, + desc="Output mask", + ) + npass = traits.Int(argstr="-npass %d", position=1, desc="Number of passes") + + +class MaskFilterOutputSpec(TraitedSpec): + out_file = File(exists=True, desc="the filtered output mask") + + +class MaskFilter(CommandLine): + """ + Perform filtering operations on 3D / 4D mask images. + Only supports dilate / erode filters at the moment. + For more information see: https://mrtrix.readthedocs.io/en/latest/reference/commands/maskfilter.html + + + Example + ------- + + >>> import nipype.interfaces.mrtrix3 as mrt + >>> mf = mrt.MaskFilter() + >>> mf.inputs.in_file = 'mask.mif' + >>> mf.inputs.filter = 'dilate' + >>> mf.inputs.npass = 2 + >>> mf.inputs.out_file = 'mask_filtered.mif' + >>> mf.cmdline + 'maskfilter -npass 2 mask.mif dilate mask_filtered.mif' + >>> mf.run() # doctest: +SKIP + """ + + _cmd = "maskfilter" + input_spec = MaskFilterInputSpec + output_spec = MaskFilterOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs["out_file"] = op.abspath(self.inputs.out_file) + return outputs + + +class MTNormaliseInputSpec(MRTrix3BaseInputSpec): + wm_fod = File( + argstr="%s", + exists=True, + position=1, + desc="input fod of white matter tissue compartment", + ) + out_file_wm = File( + argstr="%s", position=2, desc="output file of white matter tissue compartment" + ) + gm_fod = File( + argstr="%s", + exists=True, + position=3, + desc="input fod of grey matter tissue compartment", + ) + out_file_gm = File( + argstr="%s", position=4, desc="output file of grey matter tissue compartment" + ) + csf_fod = File( + argstr="%s", exists=True, position=5, desc="input fod of CSF tissue compartment" + ) + out_file_csf = File( + argstr="%s", position=6, desc="output file of CSF tissue compartment 3" + ) + mask = File(argstr="-mask %s", exists=True, position=-1, desc="input brain mask") + + +class MTNormaliseOutputSpec(TraitedSpec): + out_file_wm = File(exists=True, desc="the normalized white matter fod") + out_file_gm = File(exists=True, desc="the normalized grey matter fod") + out_file_csf = File(exists=True, desc="the normalized csf fod") + + +class MTNormalise(CommandLine): + """ + Multi-tissue informed log-domain intensity normalisation + + + Example + ------- + + >>> import nipype.interfaces.mrtrix3 as mrt + >>> mtn = mrt.MTNormalise() + >>> mtn.inputs.wm_fod = 'wmfod.mif' + >>> mtn.inputs.gm_fod = 'gmfod.mif' + >>> mtn.inputs.csf_fod = 'csffod.mif' + >>> mtn.inputs.out_file_wm = 'wmfod_norm.mif' + >>> mtn.inputs.out_file_gm = 'gmfod_norm.mif' + >>> mtn.inputs.out_file_csf = 'csffod_norm.mif' + >>> mtn.inputs.mask = 'mask.mif' + >>> mtn.cmdline + 'mtnormalise wmfod.mif wmfod_norm.mif gmfod.mif gmfod_norm.mif csffod.mif csffod_norm.mif -mask mask.mif' + >>> mtn.run() # doctest: +SKIP + """ + + _cmd = "mtnormalise" + input_spec = MTNormaliseInputSpec + output_spec = MTNormaliseOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs["out_file_wm"] = op.abspath(self.inputs.out_file_wm) + outputs["out_file_gm"] = op.abspath(self.inputs.out_file_gm) + outputs["out_file_csf"] = op.abspath(self.inputs.out_file_csf) + return outputs + + +class Generate5tt2gmwmiInputSpec(MRTrix3BaseInputSpec): + in_file = File( + exists=True, + argstr="%s", + mandatory=True, + position=-2, + desc="the input 5TT segmented anatomical image", + ) + mask_out = File( + "mask_gmwmi.mif", + argstr="%s", + mandatory=True, + position=-1, + desc="the output mask image", + ) + mask_in = File( + argstr="-mask_in %s", + position=-3, + desc="filter an input mask image according to those voxels that lie upon the grey matter - white matter boundary", + ) + + +class Generate5tt2gmwmiOutputSpec(TraitedSpec): + mask_out = File(exists=True, desc="the output mask file") + + +class Generate5tt2gmwmi(CommandLine): + """ + Generate a mask image appropriate for seeding streamlines on + the grey matter-white matter interface + + + Example + ------- + + >>> import nipype.interfaces.mrtrix3 as mrt + >>> gmwmi = mrt.Generate5tt2gmwmi() + >>> gmwmi.inputs.in_file = '5tt_in.mif' + >>> gmwmi.inputs.mask_out = 'mask_gmwmi.mif' + >>> gmwmi.cmdline + '5tt2gmwmi 5tt_in.mif mask_gmwmi.mif' + >>> gmwmi.run() # doctest: +SKIP + """ + + _cmd = "5tt2gmwmi" + input_spec = Generate5tt2gmwmiInputSpec + output_spec = Generate5tt2gmwmiOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs["mask_out"] = op.abspath(self.inputs.mask_out) + return outputs diff --git a/nipype/testing/data/5tt_in.mif b/nipype/testing/data/5tt_in.mif new file mode 100644 index 0000000000..e69de29bb2 diff --git a/nipype/testing/data/csffod.mif b/nipype/testing/data/csffod.mif new file mode 100644 index 0000000000..e69de29bb2 diff --git a/nipype/testing/data/gmfod.mif b/nipype/testing/data/gmfod.mif new file mode 100644 index 0000000000..e69de29bb2 diff --git a/nipype/testing/data/wmfod.mif b/nipype/testing/data/wmfod.mif new file mode 100644 index 0000000000..e69de29bb2