From 984b7e8c34c33aed7d2272f476f03d9f3dc8b90e Mon Sep 17 00:00:00 2001 From: Lionel Butry Date: Tue, 17 Oct 2023 15:46:49 +0200 Subject: [PATCH 01/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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 bd9d406edbdad3f86bb1dee1c977144f7ed625dc Mon Sep 17 00:00:00 2001 From: Martin Norgaard Date: Fri, 8 Sep 2023 09:59:52 +0200 Subject: [PATCH 14/28] GTMPVC: add extra outputs to outputspec and GTMPVC class --- nipype/interfaces/freesurfer/petsurfer.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/nipype/interfaces/freesurfer/petsurfer.py b/nipype/interfaces/freesurfer/petsurfer.py index 7536fac1a2..754ed48f7a 100644 --- a/nipype/interfaces/freesurfer/petsurfer.py +++ b/nipype/interfaces/freesurfer/petsurfer.py @@ -458,7 +458,21 @@ class GTMPVCOutputSpec(TraitedSpec): yhat_with_noise = File( desc="4D PET file with full FOV of signal estimate (yhat) with noise after PVC (smoothed with PSF)", ) - + eres = File( + desc="4D PET file of residual error after PVC (smoothed with PSF)", + ) + tissue_fraction = File( + desc="4D PET file of tissue fraction before PVC", + ) + tissue_fraction_psf = File( + desc="4D PET file of tissue fraction after PVC (smoothed with PSF)", + ) + seg = File( + desc="Segmentation file of regions used for PVC", + ) + seg_ctab = File( + desc="Color table file for segmentation file", + ) class GTMPVC(FSCommand): """create an anatomical segmentation for the geometric transfer matrix (GTM). @@ -536,6 +550,11 @@ def _list_outputs(self): outputs["gtm_stats"] = os.path.join(pvcdir, "gtm.stats.dat") outputs["reg_pet2anat"] = os.path.join(pvcdir, "aux", "bbpet2anat.lta") outputs["reg_anat2pet"] = os.path.join(pvcdir, "aux", "anat2bbpet.lta") + outputs["eres"] = os.path.join(pvcdir, "eres.nii.gz") + outputs["tissue_fraction"] = os.path.join(pvcdir, "aux", "tissue.fraction.nii.gz") + outputs["tissue_fraction_psf"] = os.path.join(pvcdir, "aux", "tissue.fraction.psf.nii.gz") + outputs["seg"] = os.path.join(pvcdir, "aux", "seg.nii.gz") + outputs["seg_ctab"] = os.path.join(pvcdir, "aux", "seg.ctab") # Assign the conditional outputs if self.inputs.save_input: From ad5e55922c9aeec77dc9b2ce46dcd7b039bd24a6 Mon Sep 17 00:00:00 2001 From: Martin Norgaard Date: Fri, 8 Sep 2023 10:02:07 +0200 Subject: [PATCH 15/28] FIX: update description of GTMPVC interface --- nipype/interfaces/freesurfer/petsurfer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/freesurfer/petsurfer.py b/nipype/interfaces/freesurfer/petsurfer.py index 754ed48f7a..5dac87c17d 100644 --- a/nipype/interfaces/freesurfer/petsurfer.py +++ b/nipype/interfaces/freesurfer/petsurfer.py @@ -475,7 +475,7 @@ class GTMPVCOutputSpec(TraitedSpec): ) class GTMPVC(FSCommand): - """create an anatomical segmentation for the geometric transfer matrix (GTM). + """Perform Partial Volume Correction (PVC) to PET Data. Examples -------- From f66b50ff84fb993b47b6493af83ecae4980dc9b6 Mon Sep 17 00:00:00 2001 From: Martin Norgaard Date: Fri, 8 Sep 2023 10:03:22 +0200 Subject: [PATCH 16/28] ENH: update naming of MRTM interface to MRTM1 (more clear definition) --- nipype/interfaces/freesurfer/petsurfer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nipype/interfaces/freesurfer/petsurfer.py b/nipype/interfaces/freesurfer/petsurfer.py index 5dac87c17d..2ae699d4b5 100644 --- a/nipype/interfaces/freesurfer/petsurfer.py +++ b/nipype/interfaces/freesurfer/petsurfer.py @@ -581,7 +581,7 @@ def _list_outputs(self): return outputs -class MRTMInputSpec(GLMFitInputSpec): +class MRTM1InputSpec(GLMFitInputSpec): mrtm1 = traits.Tuple( File(exists=True), File(exists=True), @@ -591,12 +591,12 @@ class MRTMInputSpec(GLMFitInputSpec): ) -class MRTM(GLMFit): +class MRTM1(GLMFit): """Perform MRTM1 kinetic modeling. Examples -------- - >>> mrtm = MRTM() + >>> mrtm = MRTM1() >>> mrtm.inputs.in_file = 'tac.nii' >>> mrtm.inputs.mrtm1 = ('ref_tac.dat', 'timing.dat') >>> mrtm.inputs.glm_dir = 'mrtm' @@ -604,7 +604,7 @@ class MRTM(GLMFit): 'mri_glmfit --glmdir mrtm --y tac.nii --mrtm1 ref_tac.dat timing.dat' """ - input_spec = MRTMInputSpec + input_spec = MRTM1InputSpec class MRTM2InputSpec(GLMFitInputSpec): From 4df6a4b17cc2c3c9156eb5d350bf379298e5c733 Mon Sep 17 00:00:00 2001 From: Martin Norgaard Date: Fri, 8 Sep 2023 10:05:02 +0200 Subject: [PATCH 17/28] ENH: update LoganRef interface to Logan (reference modeling is not used, so unclear definition) --- nipype/interfaces/freesurfer/petsurfer.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nipype/interfaces/freesurfer/petsurfer.py b/nipype/interfaces/freesurfer/petsurfer.py index 2ae699d4b5..45dbdbdce1 100644 --- a/nipype/interfaces/freesurfer/petsurfer.py +++ b/nipype/interfaces/freesurfer/petsurfer.py @@ -633,7 +633,7 @@ class MRTM2(GLMFit): input_spec = MRTM2InputSpec -class LoganRefInputSpec(GLMFitInputSpec): +class LoganInputSpec(GLMFitInputSpec): logan = traits.Tuple( File(exists=True), File(exists=True), @@ -644,11 +644,11 @@ class LoganRefInputSpec(GLMFitInputSpec): ) -class LoganRef(GLMFit): - """Perform Logan reference kinetic modeling. +class Logan(GLMFit): + """Perform Logan kinetic modeling. Examples -------- - >>> logan = LoganRef() + >>> logan = Logan() >>> logan.inputs.in_file = 'tac.nii' >>> logan.inputs.logan = ('ref_tac.dat', 'timing.dat', 2600) >>> logan.inputs.glm_dir = 'logan' @@ -656,4 +656,4 @@ class LoganRef(GLMFit): 'mri_glmfit --glmdir logan --y tac.nii --logan ref_tac.dat timing.dat 2600' """ - input_spec = LoganRefInputSpec + input_spec = LoganInputSpec From 15eb049841fabb0a05321a0ff27eb932db003ffe Mon Sep 17 00:00:00 2001 From: Martin Norgaard Date: Fri, 8 Sep 2023 10:09:37 +0200 Subject: [PATCH 18/28] ENH: add BP clipping arguments to mri_glmfit --- nipype/interfaces/freesurfer/model.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nipype/interfaces/freesurfer/model.py b/nipype/interfaces/freesurfer/model.py index 1ca0603144..8a5fc8715c 100644 --- a/nipype/interfaces/freesurfer/model.py +++ b/nipype/interfaces/freesurfer/model.py @@ -420,6 +420,14 @@ class GLMFitInputSpec(FSTraitedSpec): argstr="--logan %s %s %f", desc="RefTac TimeSec tstar : perform Logan kinetic modeling", ) + bp_clip_neg = traits.Bool( + argstr="--bp-clip-neg", + desc="set negative BP voxels to zero", + ) + bp_clip_max = traits.Float( + argstr="--bp-clip-max %f", + desc="set BP voxels above max to max", + ) force_perm = traits.Bool( argstr="--perm-force", desc="force perumtation test, even when design matrix is not orthog", From 27d285a9bc113d5b9fd6948202129dd57d178c20 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Sun, 17 Mar 2024 10:52:08 -0400 Subject: [PATCH 19/28] 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 0df01a757dbd7af25ab05aad5d14ff8c236683c9 Mon Sep 17 00:00:00 2001 From: Anthony Galassi <28850131+bendhouseart@users.noreply.github.com> Date: Tue, 19 Mar 2024 18:41:10 -0400 Subject: [PATCH 20/28] formatted with black --- nipype/interfaces/freesurfer/model.py | 2 +- nipype/interfaces/freesurfer/petsurfer.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/nipype/interfaces/freesurfer/model.py b/nipype/interfaces/freesurfer/model.py index 8a5fc8715c..a7e7e28868 100644 --- a/nipype/interfaces/freesurfer/model.py +++ b/nipype/interfaces/freesurfer/model.py @@ -421,7 +421,7 @@ class GLMFitInputSpec(FSTraitedSpec): desc="RefTac TimeSec tstar : perform Logan kinetic modeling", ) bp_clip_neg = traits.Bool( - argstr="--bp-clip-neg", + argstr="--bp-clip-neg", desc="set negative BP voxels to zero", ) bp_clip_max = traits.Float( diff --git a/nipype/interfaces/freesurfer/petsurfer.py b/nipype/interfaces/freesurfer/petsurfer.py index 45dbdbdce1..b6634a58c5 100644 --- a/nipype/interfaces/freesurfer/petsurfer.py +++ b/nipype/interfaces/freesurfer/petsurfer.py @@ -460,7 +460,7 @@ class GTMPVCOutputSpec(TraitedSpec): ) eres = File( desc="4D PET file of residual error after PVC (smoothed with PSF)", - ) + ) tissue_fraction = File( desc="4D PET file of tissue fraction before PVC", ) @@ -474,6 +474,7 @@ class GTMPVCOutputSpec(TraitedSpec): desc="Color table file for segmentation file", ) + class GTMPVC(FSCommand): """Perform Partial Volume Correction (PVC) to PET Data. @@ -551,8 +552,12 @@ def _list_outputs(self): outputs["reg_pet2anat"] = os.path.join(pvcdir, "aux", "bbpet2anat.lta") outputs["reg_anat2pet"] = os.path.join(pvcdir, "aux", "anat2bbpet.lta") outputs["eres"] = os.path.join(pvcdir, "eres.nii.gz") - outputs["tissue_fraction"] = os.path.join(pvcdir, "aux", "tissue.fraction.nii.gz") - outputs["tissue_fraction_psf"] = os.path.join(pvcdir, "aux", "tissue.fraction.psf.nii.gz") + outputs["tissue_fraction"] = os.path.join( + pvcdir, "aux", "tissue.fraction.nii.gz" + ) + outputs["tissue_fraction_psf"] = os.path.join( + pvcdir, "aux", "tissue.fraction.psf.nii.gz" + ) outputs["seg"] = os.path.join(pvcdir, "aux", "seg.nii.gz") outputs["seg_ctab"] = os.path.join(pvcdir, "aux", "seg.ctab") From 75f0ba0b4ed33c25189eabd7dc77ec4997563847 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:03:16 -0400 Subject: [PATCH 21/28] TEST: Update tests --- .../freesurfer/tests/test_auto_GLMFit.py | 6 ++++++ .../freesurfer/tests/test_auto_GTMPVC.py | 15 +++++++++++++++ ...{test_auto_LoganRef.py => test_auto_Logan.py} | 16 +++++++++++----- .../{test_auto_MRTM.py => test_auto_MRTM1.py} | 16 +++++++++++----- .../freesurfer/tests/test_auto_MRTM2.py | 6 ++++++ .../freesurfer/tests/test_auto_OneSampleTTest.py | 6 ++++++ 6 files changed, 55 insertions(+), 10 deletions(-) rename nipype/interfaces/freesurfer/tests/{test_auto_LoganRef.py => test_auto_Logan.py} (95%) rename nipype/interfaces/freesurfer/tests/{test_auto_MRTM.py => test_auto_MRTM1.py} (95%) diff --git a/nipype/interfaces/freesurfer/tests/test_auto_GLMFit.py b/nipype/interfaces/freesurfer/tests/test_auto_GLMFit.py index a950caa7af..4d62a03be6 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_GLMFit.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_GLMFit.py @@ -13,6 +13,12 @@ def test_GLMFit_inputs(): args=dict( argstr="%s", ), + bp_clip_max=dict( + argstr="--bp-clip-max %f", + ), + bp_clip_neg=dict( + argstr="--bp-clip-neg", + ), calc_AR1=dict( argstr="--tar1", ), diff --git a/nipype/interfaces/freesurfer/tests/test_auto_GTMPVC.py b/nipype/interfaces/freesurfer/tests/test_auto_GTMPVC.py index 7f7af1cdb4..99c0002be4 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_GTMPVC.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_GTMPVC.py @@ -207,6 +207,9 @@ def test_GTMPVC_inputs(): def test_GTMPVC_outputs(): output_map = dict( + eres=dict( + extensions=None, + ), gtm_file=dict( extensions=None, ), @@ -256,6 +259,18 @@ def test_GTMPVC_outputs(): reg_rbvpet2anat=dict( extensions=None, ), + seg=dict( + extensions=None, + ), + seg_ctab=dict( + extensions=None, + ), + tissue_fraction=dict( + extensions=None, + ), + tissue_fraction_psf=dict( + extensions=None, + ), yhat=dict( extensions=None, ), diff --git a/nipype/interfaces/freesurfer/tests/test_auto_LoganRef.py b/nipype/interfaces/freesurfer/tests/test_auto_Logan.py similarity index 95% rename from nipype/interfaces/freesurfer/tests/test_auto_LoganRef.py rename to nipype/interfaces/freesurfer/tests/test_auto_Logan.py index c66f460533..34c6dfa6c7 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_LoganRef.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_Logan.py @@ -1,8 +1,8 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT -from ..petsurfer import LoganRef +from ..petsurfer import Logan -def test_LoganRef_inputs(): +def test_Logan_inputs(): input_map = dict( allow_ill_cond=dict( argstr="--illcond", @@ -13,6 +13,12 @@ def test_LoganRef_inputs(): args=dict( argstr="%s", ), + bp_clip_max=dict( + argstr="--bp-clip-max %f", + ), + bp_clip_neg=dict( + argstr="--bp-clip-neg", + ), calc_AR1=dict( argstr="--tar1", ), @@ -214,14 +220,14 @@ def test_LoganRef_inputs(): xor=("weight_file", "weight_inv", "weight_sqrt"), ), ) - inputs = LoganRef.input_spec() + inputs = Logan.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_LoganRef_outputs(): +def test_Logan_outputs(): output_map = dict( beta_file=dict( extensions=None, @@ -271,7 +277,7 @@ def test_LoganRef_outputs(): extensions=None, ), ) - outputs = LoganRef.output_spec() + outputs = Logan.output_spec() for key, metadata in list(output_map.items()): for metakey, value in list(metadata.items()): diff --git a/nipype/interfaces/freesurfer/tests/test_auto_MRTM.py b/nipype/interfaces/freesurfer/tests/test_auto_MRTM1.py similarity index 95% rename from nipype/interfaces/freesurfer/tests/test_auto_MRTM.py rename to nipype/interfaces/freesurfer/tests/test_auto_MRTM1.py index 18e1dd6961..1637214b9e 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_MRTM.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_MRTM1.py @@ -1,8 +1,8 @@ # AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT -from ..petsurfer import MRTM +from ..petsurfer import MRTM1 -def test_MRTM_inputs(): +def test_MRTM1_inputs(): input_map = dict( allow_ill_cond=dict( argstr="--illcond", @@ -13,6 +13,12 @@ def test_MRTM_inputs(): args=dict( argstr="%s", ), + bp_clip_max=dict( + argstr="--bp-clip-max %f", + ), + bp_clip_neg=dict( + argstr="--bp-clip-neg", + ), calc_AR1=dict( argstr="--tar1", ), @@ -214,14 +220,14 @@ def test_MRTM_inputs(): xor=("weight_file", "weight_inv", "weight_sqrt"), ), ) - inputs = MRTM.input_spec() + inputs = MRTM1.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_MRTM_outputs(): +def test_MRTM1_outputs(): output_map = dict( beta_file=dict( extensions=None, @@ -271,7 +277,7 @@ def test_MRTM_outputs(): extensions=None, ), ) - outputs = MRTM.output_spec() + outputs = MRTM1.output_spec() for key, metadata in list(output_map.items()): for metakey, value in list(metadata.items()): diff --git a/nipype/interfaces/freesurfer/tests/test_auto_MRTM2.py b/nipype/interfaces/freesurfer/tests/test_auto_MRTM2.py index 71b200a600..dea4ca3a92 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_MRTM2.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_MRTM2.py @@ -13,6 +13,12 @@ def test_MRTM2_inputs(): args=dict( argstr="%s", ), + bp_clip_max=dict( + argstr="--bp-clip-max %f", + ), + bp_clip_neg=dict( + argstr="--bp-clip-neg", + ), calc_AR1=dict( argstr="--tar1", ), diff --git a/nipype/interfaces/freesurfer/tests/test_auto_OneSampleTTest.py b/nipype/interfaces/freesurfer/tests/test_auto_OneSampleTTest.py index eb199ddc50..51b2f2cd0b 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_OneSampleTTest.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_OneSampleTTest.py @@ -13,6 +13,12 @@ def test_OneSampleTTest_inputs(): args=dict( argstr="%s", ), + bp_clip_max=dict( + argstr="--bp-clip-max %f", + ), + bp_clip_neg=dict( + argstr="--bp-clip-neg", + ), calc_AR1=dict( argstr="--tar1", ), From 9720b95992b09d5fda374f36a75daee8a274d17f Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:06:37 -0400 Subject: [PATCH 22/28] 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 23/28] 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 24/28] 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 25/28] 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 From 0fe7a78cc7f1dc7fe1130d3bd5616abaf03e27b7 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:23:27 -0400 Subject: [PATCH 26/28] Test Python 3.12 support --- .github/workflows/tests.yml | 2 +- nipype/info.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1e99938ca6..97de293446 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -91,7 +91,7 @@ jobs: strategy: matrix: os: ['ubuntu-22.04'] - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] check: ['test'] pip-flags: [''] depends: ['REQUIREMENTS'] diff --git a/nipype/info.py b/nipype/info.py index 22290d1bc0..a550e4b389 100644 --- a/nipype/info.py +++ b/nipype/info.py @@ -58,6 +58,7 @@ def get_nipype_gitversion(): "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering", ] PYTHON_REQUIRES = ">= 3.8" From 7512d7c218651dd57a2b195b2c985e79fab5ee5b Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:27:01 -0400 Subject: [PATCH 27/28] CI: Restore nipy tests --- .github/workflows/tests.yml | 14 +++++++------- tools/ci/env.sh | 1 - 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 97de293446..22786ebb5f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -105,13 +105,13 @@ jobs: depends: REQUIREMENTS deb-depends: true nipype-extras: doc,tests,profiler,duecredit,ssh - # - os: ubuntu-20.04 - # python-version: 3.8 - # check: test - # pip-flags: '' - # depends: NUMPY123 - # deb-depends: true - # nipype-extras: doc,tests,nipy,profiler,duecredit,ssh + - os: ubuntu-20.04 + python-version: 3.8 + check: test + pip-flags: '' + depends: REQUIREMENTS + deb-depends: true + nipype-extras: doc,tests,nipy,profiler,duecredit,ssh env: DEPENDS: ${{ matrix.depends }} CHECK_TYPE: ${{ matrix.check }} diff --git a/tools/ci/env.sh b/tools/ci/env.sh index 84d76bfe8a..15e12275b6 100644 --- a/tools/ci/env.sh +++ b/tools/ci/env.sh @@ -4,7 +4,6 @@ SETUP_REQUIRES="pip setuptools>=30.3.0 wheel" REQUIREMENTS="-r requirements.txt" # Minimum versions of minimum requirements MIN_REQUIREMENTS="-r min-requirements.txt" -NUMPY123="numpy<1.24 -r requirements.txt" # Numpy and scipy upload nightly/weekly/intermittent wheels NIGHTLY_WHEELS="https://pypi.anaconda.org/scipy-wheels-nightly/simple" From 9c8e3cc45f36bbad8f1baa011574251746f98000 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Wed, 20 Mar 2024 16:29:22 -0400 Subject: [PATCH 28/28] [DATALAD RUNCMD] npx prettier -w '.github/**/*.yml' === Do not change lines below === { "chain": [], "cmd": "npx prettier -w '.github/**/*.yml'", "exit": 0, "extra_inputs": [], "inputs": [], "outputs": [], "pwd": "." } ^^^ Do not change lines above ^^^ --- .github/workflows/contrib.yml | 6 +++--- .github/workflows/tests.yml | 22 +++++++++++----------- .github/workflows/tutorials.yml | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/contrib.yml b/.github/workflows/contrib.yml index a0578d8a46..28f76cf3a0 100644 --- a/.github/workflows/contrib.yml +++ b/.github/workflows/contrib.yml @@ -31,10 +31,10 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: ['ubuntu-latest'] + os: ["ubuntu-latest"] python-version: [3.8] - nipype-extras: ['dev'] - check: ['specs', 'style'] + nipype-extras: ["dev"] + check: ["specs", "style"] env: DEPENDS: "" CHECK_TYPE: ${{ matrix.check }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 22786ebb5f..7f7859fae7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,7 +19,7 @@ on: - maint/* schedule: # 8am EST / 9am EDT Mondays - - cron: '0 13 * * 1' + - cron: "0 13 * * 1" defaults: run: @@ -57,7 +57,7 @@ jobs: needs: [build] strategy: matrix: - package: ['wheel', 'sdist'] + package: ["wheel", "sdist"] steps: - uses: actions/download-artifact@v4 with: @@ -90,25 +90,25 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: ['ubuntu-22.04'] - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] - check: ['test'] - pip-flags: [''] - depends: ['REQUIREMENTS'] + os: ["ubuntu-22.04"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + check: ["test"] + pip-flags: [""] + depends: ["REQUIREMENTS"] deb-depends: [false] - nipype-extras: ['doc,tests,profiler'] + nipype-extras: ["doc,tests,profiler"] include: - os: ubuntu-22.04 - python-version: '3.8' + python-version: "3.8" check: test - pip-flags: '' + pip-flags: "" depends: REQUIREMENTS deb-depends: true nipype-extras: doc,tests,profiler,duecredit,ssh - os: ubuntu-20.04 python-version: 3.8 check: test - pip-flags: '' + pip-flags: "" depends: REQUIREMENTS deb-depends: true nipype-extras: doc,tests,nipy,profiler,duecredit,ssh diff --git a/.github/workflows/tutorials.yml b/.github/workflows/tutorials.yml index 2e6093fde5..46aa42d25c 100644 --- a/.github/workflows/tutorials.yml +++ b/.github/workflows/tutorials.yml @@ -3,7 +3,7 @@ name: Test tutorials on: push: branches: - - 'rel/*' + - "rel/*" concurrency: group: tutorials-${{ github.ref }}