From 984b7e8c34c33aed7d2272f476f03d9f3dc8b90e Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 17 Oct 2023 15:46:49 +0200 Subject: [PATCH 01/18] added node maskfilter --- nipype/interfaces/mrtrix3/__init__.py | 1 + nipype/interfaces/mrtrix3/utils.py | 61 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/nipype/interfaces/mrtrix3/__init__.py b/nipype/interfaces/mrtrix3/__init__.py index 0ff8daa510..03bc807283 100644 --- a/nipype/interfaces/mrtrix3/__init__.py +++ b/nipype/interfaces/mrtrix3/__init__.py @@ -30,4 +30,5 @@ SHConv, TensorMetrics, TransformFSLConvert, + MaskFilter, ) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 2ec7eba909..f78a38457e 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1186,3 +1186,64 @@ 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. + + + 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.out_file = 'mask_filtered.mif' + >>> mf.cmdline + 'maskfilter -npass 2 mask.mif dilate mask_filtered.mif' + >>> mf.run() + """ + + _cmd = "maskfilter" + input_spec = MaskFilterInputSpec + output_spec = MaskFilterOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs = self.output_spec().get() + inputs = self.input_spec().get() + outputs["output_image"] = self._gen_filename(inputs["input_image"], suffix="_filtered") + return outputs \ No newline at end of file From a1ea55a13b653e0d2711b88b6c8d21f2198545ee Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 17 Oct 2023 15:57:38 +0200 Subject: [PATCH 02/18] fixed comma --- nipype/interfaces/mrtrix3/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index f78a38457e..c3d5da88ac 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1205,7 +1205,7 @@ class MaskFilterInputSpec(CommandLineInputSpec): name_source=["input_image"], mandatory=True, argstr="%s", - position=-1 + position=-1, desc="Output mask" ) npass = traits.Int( From fa70f4a824ac77f2a7d3292baa698f3e64335545 Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 17 Oct 2023 20:45:20 +0200 Subject: [PATCH 03/18] fixed _list_outputs --- nipype/interfaces/mrtrix3/utils.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index c3d5da88ac..7c6873e4db 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1243,7 +1243,5 @@ class MaskFilter(CommandLine): def _list_outputs(self): outputs = self.output_spec().get() - outputs = self.output_spec().get() - inputs = self.input_spec().get() - outputs["output_image"] = self._gen_filename(inputs["input_image"], suffix="_filtered") + outputs["out_file"] = op.abspath(self.inputs.out_file) return outputs \ No newline at end of file From a5afb280afc81da80e72fc18fbbd77aca89784be Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 17 Oct 2023 21:57:33 +0200 Subject: [PATCH 04/18] added url to mrtrix3 docu --- nipype/interfaces/mrtrix3/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 7c6873e4db..4e8745d11b 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1221,6 +1221,7 @@ 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 From a9161e2db75e3d7c00f9899a821a911e2c6d5270 Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Mon, 23 Oct 2023 19:59:02 +0200 Subject: [PATCH 05/18] added mtnormalise --- nipype/interfaces/mrtrix3/utils.py | 71 +++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 4e8745d11b..8d406d310a 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1245,4 +1245,73 @@ class MaskFilter(CommandLine): def _list_outputs(self): outputs = self.output_spec().get() outputs["out_file"] = op.abspath(self.inputs.out_file) - return outputs \ No newline at end of file + return outputs + +class MTNormaliseInputSpec(MRTrix3BaseInputSpec): + fod_wm = File( + argstr="%s", + mandatory=False, + position=1, + desc="input fod of white matter tissue compartment" + ) + out_file_wm = File( + argstr="%s", + mandatory=False, + position=2, + desc="output file of white matter tissue compartment" + ) + fod_gm = File( + argstr="%s", + mandatory=False, + position=3, + desc="input fod of grey matter tissue compartment" + ) + out_file_gm = File( + argstr="%s", + mandatory=False, + position=4, + desc="output file of grey matter tissue compartment" + ) + fod_tissue_csf = File( + argstr="%s", + mandatory=False, + position=5, + desc="input fod of CSF tissue compartment" + ) + out_file_csf = File( + argstr="%s", + mandatory=False, + position=6, + desc="output file of CSF tissue compartment 3" + ) + +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.fod_wm = 'wmfod.mif' + >>> mtn.inputs.fod_gm = 'gmfod.mif' + >>> mtn.inputs.fod_csf = '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.cmdline + 'mtnormalise wmfod.mif wmfod_norm.mif gmfod.mif gmfod_norm.mif csffod.mif csffod_norm.mif' + >>> mtn.run() + """ + + _cmd = "mtnormalise" + input_spec = MTNormaliseInputSpec + output_spec = MTNormaliseOutputSpec \ No newline at end of file From 4f04c14dffd58fee488185cfb387102c4de099be Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Mon, 23 Oct 2023 20:05:24 +0200 Subject: [PATCH 06/18] added mtnormalise --- nipype/interfaces/mrtrix3/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nipype/interfaces/mrtrix3/__init__.py b/nipype/interfaces/mrtrix3/__init__.py index 03bc807283..b9e45d0267 100644 --- a/nipype/interfaces/mrtrix3/__init__.py +++ b/nipype/interfaces/mrtrix3/__init__.py @@ -31,4 +31,5 @@ TensorMetrics, TransformFSLConvert, MaskFilter, + MTNormalise, ) From 25e8ec6d893fcfb9db7e8cb0cc3e94d5ec0a39a1 Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Mon, 23 Oct 2023 20:21:30 +0200 Subject: [PATCH 07/18] fixing mtnormalise --- nipype/interfaces/mrtrix3/utils.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 8d406d310a..2a3a926c86 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1250,6 +1250,7 @@ def _list_outputs(self): class MTNormaliseInputSpec(MRTrix3BaseInputSpec): fod_wm = File( argstr="%s", + exists=True, mandatory=False, position=1, desc="input fod of white matter tissue compartment" @@ -1262,6 +1263,7 @@ class MTNormaliseInputSpec(MRTrix3BaseInputSpec): ) fod_gm = File( argstr="%s", + exists=True, mandatory=False, position=3, desc="input fod of grey matter tissue compartment" @@ -1272,8 +1274,9 @@ class MTNormaliseInputSpec(MRTrix3BaseInputSpec): position=4, desc="output file of grey matter tissue compartment" ) - fod_tissue_csf = File( + fod_csf = File( argstr="%s", + exists=True, mandatory=False, position=5, desc="input fod of CSF tissue compartment" @@ -1284,6 +1287,12 @@ class MTNormaliseInputSpec(MRTrix3BaseInputSpec): position=6, desc="output file of CSF tissue compartment 3" ) + mask = File( + argstr="-mask %s", + exists=True, + position=0, + desc="input brain mask" + ) class MTNormaliseOutputSpec(TraitedSpec): out_file_wm = File(exists=True, desc="the normalized white matter fod") @@ -1307,8 +1316,9 @@ class MTNormalise(CommandLine): >>> 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' + 'mtnormalise -mask mask.mif wmfod.mif wmfod_norm.mif gmfod.mif gmfod_norm.mif csffod.mif csffod_norm.mif' >>> mtn.run() """ From bb3d352233b2c13815961361050d7146e31d7ee1 Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Mon, 23 Oct 2023 20:28:22 +0200 Subject: [PATCH 08/18] fixed: renaming --- nipype/interfaces/mrtrix3/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 2a3a926c86..e4e48c52ab 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1248,7 +1248,7 @@ def _list_outputs(self): return outputs class MTNormaliseInputSpec(MRTrix3BaseInputSpec): - fod_wm = File( + wm_fod = File( argstr="%s", exists=True, mandatory=False, @@ -1261,7 +1261,7 @@ class MTNormaliseInputSpec(MRTrix3BaseInputSpec): position=2, desc="output file of white matter tissue compartment" ) - fod_gm = File( + gm_fod = File( argstr="%s", exists=True, mandatory=False, @@ -1274,7 +1274,7 @@ class MTNormaliseInputSpec(MRTrix3BaseInputSpec): position=4, desc="output file of grey matter tissue compartment" ) - fod_csf = File( + csf_fod = File( argstr="%s", exists=True, mandatory=False, From 820d1c349768560600f8b68970abf5fb44b39969 Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 24 Oct 2023 09:45:13 +0200 Subject: [PATCH 09/18] fixed output of mtnormalise --- nipype/interfaces/mrtrix3/utils.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index e4e48c52ab..0ae2831837 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1290,7 +1290,7 @@ class MTNormaliseInputSpec(MRTrix3BaseInputSpec): mask = File( argstr="-mask %s", exists=True, - position=0, + position=-1, desc="input brain mask" ) @@ -1318,10 +1318,19 @@ class MTNormalise(CommandLine): >>> mtn.inputs.out_file_csf = 'csffod_norm.mif' >>> mtn.inputs.mask = 'mask.mif' >>> mtn.cmdline - 'mtnormalise -mask mask.mif wmfod.mif wmfod_norm.mif gmfod.mif gmfod_norm.mif csffod.mif csffod_norm.mif' + 'mtnormalise wmfod.mif wmfod_norm.mif gmfod.mif gmfod_norm.mif csffod.mif csffod_norm.mif -mask mask.mif' >>> mtn.run() """ _cmd = "mtnormalise" input_spec = MTNormaliseInputSpec - output_spec = MTNormaliseOutputSpec \ No newline at end of file + output_spec = MTNormaliseOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs["out_file_wm"] = op.abspath(self.inputs.out_file_wm) + if self.inputs.gm_file != Undefined: + outputs["out_file_gm"] = op.abspath(self.inputs.out_file_gm) + if self.inputs.csf_file != Undefined: + outputs["out_file_csf"] = op.abspath(self.inputs.out_file_csf) + return outputs \ No newline at end of file From c16cb3419a6827792b277cb5025beb458a21c2f7 Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 24 Oct 2023 09:58:50 +0200 Subject: [PATCH 10/18] fixing mtnormalise --- nipype/interfaces/mrtrix3/utils.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 0ae2831837..999527de79 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1329,8 +1329,6 @@ class MTNormalise(CommandLine): def _list_outputs(self): outputs = self.output_spec().get() outputs["out_file_wm"] = op.abspath(self.inputs.out_file_wm) - if self.inputs.gm_file != Undefined: - outputs["out_file_gm"] = op.abspath(self.inputs.out_file_gm) - if self.inputs.csf_file != Undefined: - outputs["out_file_csf"] = op.abspath(self.inputs.out_file_csf) + outputs["out_file_gm"] = op.abspath(self.inputs.out_file_gm) + outputs["out_file_csf"] = op.abspath(self.inputs.out_file_csf) return outputs \ No newline at end of file From 20c09951a5e681048c1608889427f01dd272ff51 Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 24 Oct 2023 14:39:44 +0200 Subject: [PATCH 11/18] added 5ttgmwmi --- nipype/interfaces/mrtrix3/__init__.py | 1 + nipype/interfaces/mrtrix3/utils.py | 54 +++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/nipype/interfaces/mrtrix3/__init__.py b/nipype/interfaces/mrtrix3/__init__.py index b9e45d0267..3bd9f55250 100644 --- a/nipype/interfaces/mrtrix3/__init__.py +++ b/nipype/interfaces/mrtrix3/__init__.py @@ -32,4 +32,5 @@ TransformFSLConvert, MaskFilter, MTNormalise, + Generate5tt2gmwmi, ) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 999527de79..0f4f4cb9cd 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1331,4 +1331,58 @@ def _list_outputs(self): 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 imput 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() + """ + + _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 \ No newline at end of file From a26c6b1be0a8521ec642b8a08ebb1f894975222f Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 24 Oct 2023 15:01:54 +0200 Subject: [PATCH 12/18] fixed comma --- nipype/interfaces/mrtrix3/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 0f4f4cb9cd..dbd7a8804b 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1343,7 +1343,7 @@ class Generate5tt2gmwmiInputSpec(MRTrix3BaseInputSpec): desc="the input 5TT segmented anatomical image", ) mask_out = File( - "mask_gmwmi.mif" + "mask_gmwmi.mif", argstr="%s", mandatory=True, position=-1, From bc595b85998fc62ae9106e41854b193080143a64 Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 24 Oct 2023 15:54:57 +0200 Subject: [PATCH 13/18] adding my name --- .zenodo.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.zenodo.json b/.zenodo.json index 4b8ae1f2a6..2b353a5e98 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -911,6 +911,10 @@ "name": "Wu, Jianxiao", "orcid": "0000-0002-4866-272X", }, + { + "affiliation": "Department of Neurology, BG-University Hospital Bergmannsheil Bochum, Germany", + "name": "Butry, Lionel" + }, ], "keywords": [ "neuroimaging", From 27d285a9bc113d5b9fd6948202129dd57d178c20 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Sun, 17 Mar 2024 10:52:08 -0400 Subject: [PATCH 14/18] Update nipype/interfaces/mrtrix3/utils.py --- nipype/interfaces/mrtrix3/utils.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 5aea20f004..94b0e782cc 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1250,39 +1250,33 @@ class MTNormaliseInputSpec(MRTrix3BaseInputSpec): wm_fod = File( argstr="%s", exists=True, - mandatory=False, position=1, desc="input fod of white matter tissue compartment" ) out_file_wm = File( argstr="%s", - mandatory=False, position=2, desc="output file of white matter tissue compartment" ) gm_fod = File( argstr="%s", exists=True, - mandatory=False, position=3, desc="input fod of grey matter tissue compartment" ) out_file_gm = File( argstr="%s", - mandatory=False, position=4, desc="output file of grey matter tissue compartment" ) csf_fod = File( argstr="%s", exists=True, - mandatory=False, position=5, desc="input fod of CSF tissue compartment" ) out_file_csf = File( argstr="%s", - mandatory=False, position=6, desc="output file of CSF tissue compartment 3" ) From 9720b95992b09d5fda374f36a75daee8a274d17f Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:06:37 -0400 Subject: [PATCH 15/18] MNT: Run codespell and black --- nipype/interfaces/mrtrix3/utils.py | 75 ++++++++++++------------------ 1 file changed, 31 insertions(+), 44 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 94b0e782cc..e7c31a816a 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1186,6 +1186,7 @@ def _list_outputs(self): outputs["out_file"] = op.abspath(self.inputs.out_file) return outputs + class MaskFilterInputSpec(CommandLineInputSpec): in_file = File( exists=True, @@ -1195,33 +1196,31 @@ class MaskFilterInputSpec(CommandLineInputSpec): desc="Input mask", ) filter = traits.Str( - mandatory=True, + mandatory=True, argstr="%s", position=-2, - desc="Filter to perform (e.g. dilate, erode)" + 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" + 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. + 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 ------- @@ -1240,52 +1239,40 @@ class MaskFilter(CommandLine): _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" + desc="input fod of white matter tissue compartment", ) out_file_wm = File( - argstr="%s", - position=2, - desc="output file of white matter tissue compartment" + 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" + desc="input fod of grey matter tissue compartment", ) out_file_gm = File( - argstr="%s", - position=4, - desc="output file of grey matter tissue compartment" + 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" + 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" + 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") @@ -1310,9 +1297,9 @@ class MTNormalise(CommandLine): >>> mtn.inputs.out_file_gm = 'gmfod_norm.mif' >>> mtn.inputs.out_file_csf = 'csffod_norm.mif' >>> mtn.inputs.mask = 'mask.mif' - >>> mtn.cmdline + >>> mtn.cmdline 'mtnormalise wmfod.mif wmfod_norm.mif gmfod.mif gmfod_norm.mif csffod.mif csffod_norm.mif -mask mask.mif' - >>> mtn.run() + >>> mtn.run() """ _cmd = "mtnormalise" @@ -1325,7 +1312,7 @@ def _list_outputs(self): 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( @@ -1334,19 +1321,19 @@ class Generate5tt2gmwmiInputSpec(MRTrix3BaseInputSpec): 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 imput mask image according to those voxels that lie upon the grey matter - white matter boundary", - ) + desc="filter an input mask image according to those voxels that lie upon the grey matter - white matter boundary", + ) class Generate5tt2gmwmiOutputSpec(TraitedSpec): @@ -1355,7 +1342,7 @@ class Generate5tt2gmwmiOutputSpec(TraitedSpec): class Generate5tt2gmwmi(CommandLine): """ - Generate a mask image appropriate for seeding streamlines on + Generate a mask image appropriate for seeding streamlines on the grey matter-white matter interface @@ -1366,9 +1353,9 @@ class Generate5tt2gmwmi(CommandLine): >>> gmwmi = mrt.Generate5TT2GMWMI() >>> gmwmi.inputs.in_file = '5tt_in.mif' >>> gmwmi.inputs.mask_out = 'mask_gmwmi.mif' - >>> gmwmi.cmdline + >>> gmwmi.cmdline '5tt2gmwmi 5tt_in.mif mask_gmwmi.mif' - >>> gmwmi.run() + >>> gmwmi.run() """ _cmd = "5tt2gmwmi" @@ -1378,4 +1365,4 @@ class Generate5tt2gmwmi(CommandLine): def _list_outputs(self): outputs = self.output_spec().get() outputs["mask_out"] = op.abspath(self.inputs.mask_out) - return outputs \ No newline at end of file + return outputs From 903dee5e7fc941b3272580970ed9dec006832cb7 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:07:47 -0400 Subject: [PATCH 16/18] TEST: make specs --- .../mrtrix3/tests/test_auto_Generate5tt.py | 1 - .../tests/test_auto_Generate5tt2gmwmi.py | 79 ++++++++++++++ .../mrtrix3/tests/test_auto_MTNormalise.py | 103 ++++++++++++++++++ .../mrtrix3/tests/test_auto_MaskFilter.py | 54 +++++++++ 4 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt2gmwmi.py create mode 100644 nipype/interfaces/mrtrix3/tests/test_auto_MTNormalise.py create mode 100644 nipype/interfaces/mrtrix3/tests/test_auto_MaskFilter.py 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 From 8c9c04152743a43a120ab540931410f5fb27abc7 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:09:27 -0400 Subject: [PATCH 17/18] DOCTEST: Resolve typos --- nipype/interfaces/mrtrix3/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index e7c31a816a..94939f350b 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1230,7 +1230,7 @@ class MaskFilter(CommandLine): >>> mf.inputs.in_file = 'mask.mif' >>> mf.inputs.filter = 'dilate' >>> mf.inputs.npass = 2 - >>> mf.out_file = 'mask_filtered.mif' + >>> mf.inputs.out_file = 'mask_filtered.mif' >>> mf.cmdline 'maskfilter -npass 2 mask.mif dilate mask_filtered.mif' >>> mf.run() @@ -1289,7 +1289,7 @@ class MTNormalise(CommandLine): ------- >>> import nipype.interfaces.mrtrix3 as mrt - >>> mtn = mrt.MTnormalise() + >>> mtn = mrt.MTNormalise() >>> mtn.inputs.fod_wm = 'wmfod.mif' >>> mtn.inputs.fod_gm = 'gmfod.mif' >>> mtn.inputs.fod_csf = 'csffod.mif' @@ -1350,7 +1350,7 @@ class Generate5tt2gmwmi(CommandLine): ------- >>> import nipype.interfaces.mrtrix3 as mrt - >>> gmwmi = mrt.Generate5TT2GMWMI() + >>> gmwmi = mrt.Generate5tt2gmwmi() >>> gmwmi.inputs.in_file = '5tt_in.mif' >>> gmwmi.inputs.mask_out = 'mask_gmwmi.mif' >>> gmwmi.cmdline From 5599348b432445044cd2f89b15e3f9cdc8868582 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:15:07 -0400 Subject: [PATCH 18/18] TEST: Fix doctests, add example file stubs --- nipype/interfaces/mrtrix3/utils.py | 12 ++++++------ nipype/testing/data/5tt_in.mif | 0 nipype/testing/data/csffod.mif | 0 nipype/testing/data/gmfod.mif | 0 nipype/testing/data/wmfod.mif | 0 5 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 nipype/testing/data/5tt_in.mif create mode 100644 nipype/testing/data/csffod.mif create mode 100644 nipype/testing/data/gmfod.mif create mode 100644 nipype/testing/data/wmfod.mif diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 94939f350b..41d8ab6fdd 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -1233,7 +1233,7 @@ class MaskFilter(CommandLine): >>> mf.inputs.out_file = 'mask_filtered.mif' >>> mf.cmdline 'maskfilter -npass 2 mask.mif dilate mask_filtered.mif' - >>> mf.run() + >>> mf.run() # doctest: +SKIP """ _cmd = "maskfilter" @@ -1290,16 +1290,16 @@ class MTNormalise(CommandLine): >>> import nipype.interfaces.mrtrix3 as mrt >>> mtn = mrt.MTNormalise() - >>> mtn.inputs.fod_wm = 'wmfod.mif' - >>> mtn.inputs.fod_gm = 'gmfod.mif' - >>> mtn.inputs.fod_csf = 'csffod.mif' + >>> 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() + >>> mtn.run() # doctest: +SKIP """ _cmd = "mtnormalise" @@ -1355,7 +1355,7 @@ class Generate5tt2gmwmi(CommandLine): >>> gmwmi.inputs.mask_out = 'mask_gmwmi.mif' >>> gmwmi.cmdline '5tt2gmwmi 5tt_in.mif mask_gmwmi.mif' - >>> gmwmi.run() + >>> gmwmi.run() # doctest: +SKIP """ _cmd = "5tt2gmwmi" 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