From 37d3ac27a96f34650299996b2d739de3a0d9cf22 Mon Sep 17 00:00:00 2001 From: Oweda Date: Wed, 12 Jun 2024 17:18:47 +0200 Subject: [PATCH 1/4] Solved Issue #3654: added no surface measure (no ROI) option to cat12 interface --- nipype/interfaces/cat12/preprocess.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/nipype/interfaces/cat12/preprocess.py b/nipype/interfaces/cat12/preprocess.py index ebc436c674..e13e591f71 100644 --- a/nipype/interfaces/cat12/preprocess.py +++ b/nipype/interfaces/cat12/preprocess.py @@ -525,6 +525,13 @@ def _format_arg(self, opt, spec, val): return scans_for_fname(val) elif opt in ["tpm", "shooting_tpm"]: return Cell2Str(val) + + if opt == "surface_measures": + if not self.inputs.surface_measures: + self.inputs.neuromorphometrics = False + self.inputs.lpba40 = False + self.inputs.cobra = False + self.inputs.hammers = False return super()._format_arg(opt, spec, val) @@ -583,12 +590,14 @@ def _list_outputs(self): str(label) for label in Path(pth).glob("label/*") if label.is_file() ] - outputs["label_rois"] = fname_presuffix( - f, prefix=os.path.join("label", "catROIs_"), suffix=".xml", use_ext=False - ) - outputs["label_roi"] = fname_presuffix( - f, prefix=os.path.join("label", "catROI_"), suffix=".xml", use_ext=False - ) + if self.inputs.surface_measures: + outputs["label_rois"] = fname_presuffix( + f, prefix=os.path.join("label", "catROIs_"), suffix=".xml", use_ext=False + ) + else: + outputs["label_roi"] = fname_presuffix( + f, prefix=os.path.join("label", "catROI_"), suffix=".xml", use_ext=False + ) return outputs From 511ea71058382f296e9d6ea88d6681c122d3cc45 Mon Sep 17 00:00:00 2001 From: Oweda Date: Fri, 14 Jun 2024 17:02:46 +0200 Subject: [PATCH 2/4] FIX Issue #3654: added missing input traits for templates, corrected if statements for when no surface or ROI estimations are desired --- nipype/interfaces/cat12/preprocess.py | 92 ++++++++++++++++++--------- 1 file changed, 62 insertions(+), 30 deletions(-) diff --git a/nipype/interfaces/cat12/preprocess.py b/nipype/interfaces/cat12/preprocess.py index e13e591f71..a8d7405765 100644 --- a/nipype/interfaces/cat12/preprocess.py +++ b/nipype/interfaces/cat12/preprocess.py @@ -226,39 +226,73 @@ class CAT12SegmentInputSpec(SPMCommandInputSpec): " are not available as batch dependencies objects. " ) surface_and_thickness_estimation = traits.Int( - 1, field="surface", desc=_help_surf, usedefault=True + 1, field="output.surface", desc=_help_surf, usedefault=True ) surface_measures = traits.Int( 1, field="output.surf_measures", - usedefault=True, + # usedefault=True, desc="Extract surface measures", + # requires=["neuromorphometrics", "lpba40", "cobra", "hammers", "thalamus", "thalamic_nuclei", "suit", "ibsr"], + # xor=["noROI"], ) # Templates neuromorphometrics = traits.Bool( True, field="output.ROImenu.atlases.neuromorphometrics", - usedefault=True, + # usedefault=True, desc="Extract brain measures for Neuromorphometrics template", + xor=["noROI"], ) lpba40 = traits.Bool( True, field="output.ROImenu.atlases.lpba40", - usedefault=True, + # usedefault=True, desc="Extract brain measures for LPBA40 template", + xor=["noROI"], ) cobra = traits.Bool( True, field="output.ROImenu.atlases.hammers", - usedefault=True, + # usedefault=True, desc="Extract brain measures for COBRA template", + xor=["noROI"], ) hammers = traits.Bool( - True, + False, field="output.ROImenu.atlases.cobra", - usedefault=True, + # usedefault=True, desc="Extract brain measures for Hammers template", + xor=["noROI"], + ) + thalamus = traits.Bool( + True, + field="output.ROImenu.atlases.thalamus", + # usedefault=True, + desc="Extract brain measures for Thalamus template", + xor=["noROI"], + ) + thalamic_nuclei = traits.Bool( + True, + field="output.ROImenu.atlases.thalamaic_nuclei", + # usedefault=True, + desc="Extract brain measures for Thalamic Nuclei template", + xor=["noROI"], + ) + suit = traits.Bool( + True, + field="output.ROImenu.atlases.suit", + # usedefault=True, + desc="Extract brain measures for Suit template", + xor=["noROI"], + ) + ibsr = traits.Bool( + False, + field="output.ROImenu.atlases.ibsr", + # usedefault=True, + desc="Extract brain measures for IBSR template", + xor=["noROI"], ) own_atlas = InputMultiPath( ImageFileSPM(exists=True), @@ -266,6 +300,12 @@ class CAT12SegmentInputSpec(SPMCommandInputSpec): desc="Extract brain measures for a given template", mandatory=False, copyfile=False, + xor=["noROI"], + ) + noROI = traits.Bool( + field="output.ROImenu.noROI", + desc="Select if no ROI analysis needed", + xor=["neuromorphometrics", "lpba40", "cobra", "hammers", "thalamus", "thalamic_nuclei", "suit", "ibsr"], ) # Grey matter @@ -525,13 +565,6 @@ def _format_arg(self, opt, spec, val): return scans_for_fname(val) elif opt in ["tpm", "shooting_tpm"]: return Cell2Str(val) - - if opt == "surface_measures": - if not self.inputs.surface_measures: - self.inputs.neuromorphometrics = False - self.inputs.lpba40 = False - self.inputs.cobra = False - self.inputs.hammers = False return super()._format_arg(opt, spec, val) @@ -561,22 +594,22 @@ def _list_outputs(self): if self.inputs.save_bias_corrected: outputs["bias_corrected_image"] = fname_presuffix( - f, prefix=os.path.join("mri", "wmi") + f, prefix=os.path.join("mri", "wm") ) - outputs["surface_files"] = [ - str(surf) for surf in Path(pth).glob("surf/*") if surf.is_file() - ] - - for hemisphere in ["rh", "lh"]: - for suffix in ["central", "sphere"]: - outfield = f"{hemisphere}_{suffix}_surface" - outputs[outfield] = fname_presuffix( - f, - prefix=os.path.join("surf", f"{hemisphere}.{suffix}."), - suffix=".gii", - use_ext=False, - ) + if self.inputs.surface_and_thickness_estimation: + outputs["surface_files"] = [ + str(surf) for surf in Path(pth).glob("surf/*") if surf.is_file() + ] + for hemisphere in ["rh", "lh"]: + for suffix in ["central", "sphere"]: + outfield = f"{hemisphere}_{suffix}_surface" + outputs[outfield] = fname_presuffix( + f, + prefix=os.path.join("surf", f"{hemisphere}.{suffix}."), + suffix=".gii", + use_ext=False, + ) outputs["report_files"] = outputs["report_files"] = [ str(report) for report in Path(pth).glob("report/*") if report.is_file() @@ -590,11 +623,10 @@ def _list_outputs(self): str(label) for label in Path(pth).glob("label/*") if label.is_file() ] - if self.inputs.surface_measures: + if self.inputs.noROI: outputs["label_rois"] = fname_presuffix( f, prefix=os.path.join("label", "catROIs_"), suffix=".xml", use_ext=False ) - else: outputs["label_roi"] = fname_presuffix( f, prefix=os.path.join("label", "catROI_"), suffix=".xml", use_ext=False ) From 035bf8d0979aa4af2ac96cd9a3088abe0f4d117c Mon Sep 17 00:00:00 2001 From: Oweda Date: Mon, 24 Jun 2024 13:44:31 +0200 Subject: [PATCH 3/4] FIX #3653: added option for using compressed files as inputs in CAT12 interface --- nipype/interfaces/cat12/preprocess.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nipype/interfaces/cat12/preprocess.py b/nipype/interfaces/cat12/preprocess.py index a8d7405765..96f608163b 100644 --- a/nipype/interfaces/cat12/preprocess.py +++ b/nipype/interfaces/cat12/preprocess.py @@ -9,6 +9,7 @@ isdefined, File, Str, + ImageFile, ) from nipype.interfaces.cat12.base import Cell @@ -24,7 +25,7 @@ class CAT12SegmentInputSpec(SPMCommandInputSpec): in_files = InputMultiPath( - ImageFileSPM(exists=True), + ImageFile(exists=True), field="data", desc="file to segment", mandatory=True, @@ -560,6 +561,8 @@ def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm""" if opt == "in_files": if isinstance(val, list): + if '.nii.gz' in val[0]: + return scans_for_fnames(val, keep4d=True) return scans_for_fnames(val) else: return scans_for_fname(val) @@ -572,7 +575,8 @@ def _list_outputs(self): outputs = self._outputs().get() f = self.inputs.in_files[0] pth, base, ext = split_filename(f) - + if '.nii.gz' in f: + f = f[:-3] outputs["mri_images"] = [ str(mri) for mri in Path(pth).glob("mri/*") if mri.is_file() ] From 6afc8b5c0f468f060cb741f3596b4d22cc5e672c Mon Sep 17 00:00:00 2001 From: Oweda Date: Mon, 1 Jul 2024 16:13:30 +0200 Subject: [PATCH 4/4] Fix #3654: corrected if statement for saving ROI and ROIs files --- nipype/interfaces/cat12/preprocess.py | 44 ++++++++++++++------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/nipype/interfaces/cat12/preprocess.py b/nipype/interfaces/cat12/preprocess.py index 96f608163b..7f20e3211c 100644 --- a/nipype/interfaces/cat12/preprocess.py +++ b/nipype/interfaces/cat12/preprocess.py @@ -113,9 +113,9 @@ class CAT12SegmentInputSpec(SPMCommandInputSpec): 'rhe "Optimized Shooting - superlarge ventricles" option for "Spatial registration" is ! ' "required Values: \nnone: 0;\nlight: 1;\nfull: 2;\ndefault: 1070." ) - initial_segmentation = traits.Int( - 0, field="extopts.spm_kamap", desc=_help_initial_seg, usedefault=True - ) + # initial_segmentation = traits.Int( + # 0, field="extopts.spm_kamap", desc=_help_initial_seg, usedefault=True + # ) _help_las = ( "Additionally to WM-inhomogeneities, GM intensity can vary across different regions such as the motor" @@ -232,10 +232,8 @@ class CAT12SegmentInputSpec(SPMCommandInputSpec): surface_measures = traits.Int( 1, field="output.surf_measures", - # usedefault=True, + usedefault=True, desc="Extract surface measures", - # requires=["neuromorphometrics", "lpba40", "cobra", "hammers", "thalamus", "thalamic_nuclei", "suit", "ibsr"], - # xor=["noROI"], ) # Templates @@ -244,56 +242,56 @@ class CAT12SegmentInputSpec(SPMCommandInputSpec): field="output.ROImenu.atlases.neuromorphometrics", # usedefault=True, desc="Extract brain measures for Neuromorphometrics template", - xor=["noROI"], + xor=["noROI"] ) lpba40 = traits.Bool( True, field="output.ROImenu.atlases.lpba40", # usedefault=True, desc="Extract brain measures for LPBA40 template", - xor=["noROI"], + xor=["noROI"] ) cobra = traits.Bool( True, field="output.ROImenu.atlases.hammers", # usedefault=True, desc="Extract brain measures for COBRA template", - xor=["noROI"], + xor=["noROI"] ) hammers = traits.Bool( False, field="output.ROImenu.atlases.cobra", # usedefault=True, desc="Extract brain measures for Hammers template", - xor=["noROI"], + xor=["noROI"] ) thalamus = traits.Bool( True, field="output.ROImenu.atlases.thalamus", # usedefault=True, desc="Extract brain measures for Thalamus template", - xor=["noROI"], + xor=["noROI"] ) thalamic_nuclei = traits.Bool( True, - field="output.ROImenu.atlases.thalamaic_nuclei", + field="output.ROImenu.atlases.thalamic_nuclei", # usedefault=True, desc="Extract brain measures for Thalamic Nuclei template", - xor=["noROI"], + xor=["noROI"] ) suit = traits.Bool( True, field="output.ROImenu.atlases.suit", # usedefault=True, desc="Extract brain measures for Suit template", - xor=["noROI"], + xor=["noROI"] ) ibsr = traits.Bool( False, field="output.ROImenu.atlases.ibsr", # usedefault=True, desc="Extract brain measures for IBSR template", - xor=["noROI"], + xor=["noROI"] ) own_atlas = InputMultiPath( ImageFileSPM(exists=True), @@ -301,7 +299,7 @@ class CAT12SegmentInputSpec(SPMCommandInputSpec): desc="Extract brain measures for a given template", mandatory=False, copyfile=False, - xor=["noROI"], + xor=["noROI"] ) noROI = traits.Bool( field="output.ROImenu.noROI", @@ -574,9 +572,10 @@ def _format_arg(self, opt, spec, val): def _list_outputs(self): outputs = self._outputs().get() f = self.inputs.in_files[0] - pth, base, ext = split_filename(f) if '.nii.gz' in f: f = f[:-3] + pth, base, ext = split_filename(f) + outputs["mri_images"] = [ str(mri) for mri in Path(pth).glob("mri/*") if mri.is_file() ] @@ -626,14 +625,17 @@ def _list_outputs(self): outputs["label_files"] = [ str(label) for label in Path(pth).glob("label/*") if label.is_file() ] + + if self.inputs.neuromorphometrics or self.inputs.lpba40 or self.inputs.cobra or self.inputs.hammers or self.inputs.thalamus or self.inputs.thalamic_nuclei or self.inputs.suit or self.inputs.ibsr: + outputs["label_roi"] = fname_presuffix( + f, prefix=os.path.join("label", "catROI_"), suffix=".xml", use_ext=False + ) - if self.inputs.noROI: + if self.inputs.surface_and_thickness_estimation: outputs["label_rois"] = fname_presuffix( f, prefix=os.path.join("label", "catROIs_"), suffix=".xml", use_ext=False ) - outputs["label_roi"] = fname_presuffix( - f, prefix=os.path.join("label", "catROI_"), suffix=".xml", use_ext=False - ) + return outputs