From 37d3ac27a96f34650299996b2d739de3a0d9cf22 Mon Sep 17 00:00:00 2001
From: Oweda <jailan.oweda@zislrds0074.zi.local>
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 <jailan.oweda@zislrds0074.zi.local>
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 <jailan.oweda@zislrds0074.zi.local>
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 <jailan.oweda@zislrds0074.zi.local>
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