Skip to content

Commit

Permalink
apply to pipelines using groups
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasGensollen committed Nov 8, 2024
1 parent d76bd6a commit 6325918
Show file tree
Hide file tree
Showing 21 changed files with 120 additions and 181 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ def cli(

parameters = {
# Clinica compulsory arguments
"group_label": group_label,
"orig_input_data_ml": orig_input_data_ml,
# Optional arguments for inputs from pet-volume pipeline
"acq_label": acq_label,
Expand All @@ -95,6 +94,7 @@ def cli(
base_dir=working_directory,
parameters=parameters,
name=pipeline_name,
group_label=group_label,
)

exec_pipeline = (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import List

from clinica.pipelines.engine import Pipeline
from clinica.pipelines.engine import GroupPipeline


class SpatialSVM(Pipeline):
class SpatialSVM(GroupPipeline):
"""SpatialSVM - Prepare input data for SVM with spatial and anatomical regularization.
Returns:
Expand All @@ -12,10 +12,6 @@ class SpatialSVM(Pipeline):

def _check_pipeline_parameters(self) -> None:
"""Check pipeline parameters."""
from clinica.utils.group import check_group_label

self.parameters.setdefault("group_label", None)
check_group_label(self.parameters["group_label"])
if "orig_input_data_ml" not in self.parameters.keys():
raise KeyError(
"Missing compulsory orig_input_data key in pipeline parameter."
Expand Down Expand Up @@ -70,12 +66,10 @@ def _build_input_node(self):
)
from clinica.utils.ux import print_groups_in_caps_directory

if not (
self.caps_directory / "groups" / f"group-{self.parameters['group_label']}"
).exists():
if not self.group_directory.exists():
print_groups_in_caps_directory(self.caps_directory)
raise ClinicaException(
f"Group {self.parameters['group_label']} does not exist. "
f"Group {self.group_label} does not exist. "
"Did you run pet-volume, t1-volume or t1-volume-create-dartel pipeline?"
)

Expand All @@ -93,7 +87,7 @@ def _build_input_node(self):
"t1",
"spm",
"dartel",
"group-" + self.parameters["group_label"],
str(self.group_id),
"*_T1w_segm-graymatter_space-Ixi549Space_modulated-on_probability.nii.gz",
),
"description": "graymatter tissue segmented in T1w MRI in Ixi549 space",
Expand Down Expand Up @@ -136,7 +130,7 @@ def _build_input_node(self):
try:
dartel_input = clinica_group_reader(
self.caps_directory,
t1_volume_final_group_template(self.parameters["group_label"]),
t1_volume_final_group_template(self.group_label),
)
except ClinicaException as e:
all_errors.append(e)
Expand Down Expand Up @@ -216,24 +210,17 @@ def _build_core_nodes(self):
datasink.inputs.regexp_substitutions = [
(
r"(.*)/regularized_image/.*/(.*(sub-(.*)_ses-(.*))_T1w(.*)_probability(.*))$",
r"\1/subjects/sub-\4/ses-\5/machine_learning/input_spatial_svm/group-"
+ self.parameters["group_label"]
rf"\1/subjects/sub-\4/ses-\5/machine_learning/input_spatial_svm/{self.group_id}"
+ r"/\3_T1w\6_spatialregularization\7",
),
(
r"(.*)json_file/(output_data.json)$",
r"\1/groups/group-"
+ self.parameters["group_label"]
+ r"/machine_learning/input_spatial_svm/group-"
+ self.parameters["group_label"]
rf"\1/groups/{self.group_id}/machine_learning/input_spatial_svm/{self.group_id}"
+ r"_space-Ixi549Space_parameters.json",
),
(
r"(.*)fisher_tensor_path/(output_fisher_tensor.npy)$",
r"\1/groups/group-"
+ self.parameters["group_label"]
+ r"/machine_learning/input_spatial_svm/group-"
+ self.parameters["group_label"]
rf"\1/groups/{self.group_id}/machine_learning/input_spatial_svm/{self.group_id}"
+ r"_space-Ixi549Space_gram.npy",
),
]
Expand All @@ -242,24 +229,17 @@ def _build_core_nodes(self):
datasink.inputs.regexp_substitutions = [
(
r"(.*)/regularized_image/.*/(.*(sub-(.*)_ses-(.*))_(task.*)_pet(.*))$",
r"\1/subjects/sub-\4/ses-\5/machine_learning/input_spatial_svm/group-"
+ self.parameters["group_label"]
rf"\1/subjects/sub-\4/ses-\5/machine_learning/input_spatial_svm/{self.group_id}"
+ r"/\3_\6_spatialregularization\7",
),
(
r"(.*)json_file/(output_data.json)$",
r"\1/groups/group-"
+ self.parameters["group_label"]
+ r"/machine_learning/input_spatial_svm/group-"
+ self.parameters["group_label"]
rf"\1/groups/{self.group_id}/machine_learning/input_spatial_svm/{self.group_id}"
+ r"_space-Ixi549Space_parameters.json",
),
(
r"(.*)fisher_tensor_path/(output_fisher_tensor.npy)$",
r"\1/groups/group-"
+ self.parameters["group_label"]
+ r"/machine_learning/input_spatial_svm/group-"
+ self.parameters["group_label"]
rf"\1/groups/{self.group_id}/machine_learning/input_spatial_svm/{self.group_id}"
+ r"_space-Ixi549Space_gram.npy",
),
]
Expand Down
2 changes: 1 addition & 1 deletion clinica/pipelines/pet/volume/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ def cli(
from .pipeline import PETVolume

parameters = {
"group_label": group_label,
"acq_label": acq_label,
"suvr_reference_region": suvr_reference_region,
"reconstruction_method": reconstruction_method,
Expand All @@ -117,6 +116,7 @@ def cli(
base_dir=working_directory,
parameters=parameters,
name=pipeline_name,
group_label=group_label,
)

exec_pipeline = (
Expand Down
24 changes: 10 additions & 14 deletions clinica/pipelines/pet/volume/pipeline.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import List
from typing import List, Optional

from nipype import config

from clinica.pipelines.engine import GroupPipeline
from clinica.pipelines.pet.engine import PETPipeline

# Use hash instead of parameters for iterables folder names
Expand All @@ -10,7 +11,7 @@
config.update_config(cfg)


class PETVolume(PETPipeline):
class PETVolume(GroupPipeline, PETPipeline):
"""PETVolume - Volume-based processing of PET images using SPM.
Returns:
Expand All @@ -20,11 +21,8 @@ class PETVolume(PETPipeline):
def _check_pipeline_parameters(self) -> None:
"""Check pipeline parameters."""
from clinica.utils.atlas import T1AndPetVolumeAtlasName
from clinica.utils.group import check_group_label

super()._check_pipeline_parameters()
self.parameters.setdefault("group_label", None)
check_group_label(self.parameters["group_label"])
self.parameters.setdefault("pvc_psf_tsv", None)
self.parameters.setdefault("mask_tissues", [1, 2, 3])
self.parameters.setdefault("mask_threshold", 0.3)
Expand Down Expand Up @@ -110,12 +108,10 @@ def _build_input_node(self):
)

# Check that group already exists
if not (
self.caps_directory / "groups" / f"group-{self.parameters['group_label']}"
).exists():
if not self.group_directory.exists():
print_groups_in_caps_directory(self.caps_directory)
raise ClinicaException(
f"Group {self.parameters['group_label']} does not exist. "
f"Group {self.group_label} does not exist. "
"Did you run t1-volume or t1-volume-create-dartel pipeline?"
)

Expand Down Expand Up @@ -170,21 +166,21 @@ def _build_input_node(self):
self.subjects,
self.sessions,
self.caps_directory,
t1_volume_deformation_to_template(self.parameters["group_label"]),
t1_volume_deformation_to_template(self.group_label),
)
if flowfields_errors:
all_errors.append(
format_clinica_file_reader_errors(
flowfields_errors,
t1_volume_deformation_to_template(self.parameters["group_label"]),
t1_volume_deformation_to_template(self.group_label),
)
)

# Dartel Template
try:
final_template = clinica_group_reader(
self.caps_directory,
t1_volume_final_group_template(self.parameters["group_label"]),
t1_volume_final_group_template(self.group_label),
)
except ClinicaException as e:
all_errors.append(e)
Expand Down Expand Up @@ -411,7 +407,7 @@ def _build_output_node(self):
fix_join,
"pet",
"preprocessing",
f"group-{self.parameters['group_label']}",
str(self.group_id),
),
"container",
)
Expand Down Expand Up @@ -450,7 +446,7 @@ def _build_output_node(self):
fix_join,
"pet",
"preprocessing",
f"group-{self.parameters['group_label']}",
str(self.group_id),
),
"container",
)
Expand Down
34 changes: 20 additions & 14 deletions clinica/pipelines/statistics_surface/_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from pathlib import Path
from typing import Optional

from clinica.utils.group import GroupID, GroupLabel

__all__ = [
"init_input_node",
"run_clinica_surfstat",
Expand Down Expand Up @@ -39,7 +41,7 @@ def get_pet_surface_custom_file(acq_label: str, suvr_reference_region: str) -> s
)


def init_input_node(parameters: dict, base_dir, subjects_visits_tsv):
def init_input_node(parameters: dict, group_id: GroupID, base_dir, subjects_visits_tsv):
"""Initialize the pipeline.
This function will:
Expand All @@ -53,6 +55,9 @@ def init_input_node(parameters: dict, base_dir, subjects_visits_tsv):
parameters : dict
The pipeline's parameters.
group_id: GroupID
The group ID.
base_dir : Path
The path to the pipeline's base directory.
This is a pathlib Path. No type hints because of Nipype.
Expand All @@ -63,9 +68,6 @@ def init_input_node(parameters: dict, base_dir, subjects_visits_tsv):
Returns
-------
group_label : str
The group label.
surfstat_results_dir : Path
The folder which will contain the results for SurfStat.
"""
Expand All @@ -75,8 +77,7 @@ def init_input_node(parameters: dict, base_dir, subjects_visits_tsv):
from clinica.pipelines.statistics_surface._utils import create_glm_info_dictionary
from clinica.utils.ux import print_begin_image

group_id = "group-" + parameters["group_label"]
surfstat_results_dir = base_dir / group_id
surfstat_results_dir = base_dir / str(group_id)
surfstat_results_dir.mkdir(parents=True, exist_ok=True)

# Save pipeline parameters in JSON file
Expand All @@ -97,10 +98,9 @@ def init_input_node(parameters: dict, base_dir, subjects_visits_tsv):
str(parameters["full_width_at_half_maximum"]),
str(parameters["cluster_threshold"]),
]
group_id = "group-" + parameters["group_label"]
print_begin_image(group_id, list_keys, list_values)

return parameters["group_label"], surfstat_results_dir
return surfstat_results_dir


def _get_string_format_from_tsv(tsv_file: Path) -> str:
Expand Down Expand Up @@ -189,6 +189,7 @@ def run_clinica_surfstat(
output_dir, # Path. no type hint because of Nipype self-contained requirement
subjects_visits_tsv, # Path. no type hint because of Nipype self-contained requirement
pipeline_parameters: dict,
group_label: GroupLabel,
):
"""Call clinica_surfstat function.
Expand All @@ -206,6 +207,9 @@ def run_clinica_surfstat(
pipeline_parameters : dict
Parameters of StatisticsSurface pipeline.
group_label: GroupLabel
The group label.
Returns
-------
output_dir : Path
Expand All @@ -224,7 +228,7 @@ def run_clinica_surfstat(
),
pipeline_parameters["contrast"],
pipeline_parameters["glm_type"],
pipeline_parameters["group_label"],
str(group_label),
get_freesurfer_home(),
pipeline_parameters["measure_label"],
surface_file=pipeline_parameters["custom_file"],
Expand All @@ -234,7 +238,9 @@ def run_clinica_surfstat(
return output_dir


def create_glm_info_dictionary(tsv_file: Path, pipeline_parameters: dict) -> dict:
def create_glm_info_dictionary(
tsv_file: Path, group_label: GroupLabel, pipeline_parameters: dict
) -> dict:
"""Create dictionary containing the GLM information that will be stored in a JSON file."""
glm_info = {
# Clinica compulsory arguments
Expand All @@ -245,7 +251,7 @@ def create_glm_info_dictionary(tsv_file: Path, pipeline_parameters: dict) -> dic
),
"StringFormatTSV": _get_string_format_from_tsv(tsv_file),
"Contrast": pipeline_parameters["contrast"],
"GroupLabel": pipeline_parameters["group_label"],
"GroupLabel": str(group_label),
# Optional arguments
"Covariates": pipeline_parameters["covariates"],
"FWHM": pipeline_parameters["full_width_at_half_maximum"],
Expand All @@ -272,7 +278,7 @@ def save_to_caps(
source_dir, # Path. no type hint because of Nipype self-contained requirement
caps_dir, # Path. no type hint because of Nipype self-contained requirement
overwrite_caps: bool,
group_label: str,
group_id: GroupID,
glm_type: str,
) -> None:
"""Save `source_dir`/ to CAPS folder.
Expand Down Expand Up @@ -307,12 +313,12 @@ def save_to_caps(
destination_dir = (
caps_dir.expanduser()
/ "groups"
/ f"group-{group_label}"
/ str(group_id)
/ "statistics"
/ surfstat_folder
)

if overwrite_caps:
raise NotImplementedError("save_to_caps(overwrite_caps=True) not implemented")
shutil.copytree(source_dir, destination_dir, symlinks=True)
print_end_image(f"group-{group_label}")
print_end_image(str(group_id))
2 changes: 1 addition & 1 deletion clinica/pipelines/statistics_surface/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ def cli(

parameters = {
# Clinica compulsory arguments
"group_label": group_label,
"orig_input_data": orig_input_data,
"glm_type": glm_type,
"contrast": contrast,
Expand All @@ -154,6 +153,7 @@ def cli(
tsv_file=subject_visits_with_covariates_tsv,
base_dir=working_directory,
parameters=parameters,
group_label=group_label,
name=pipeline_name,
)

Expand Down
Loading

0 comments on commit 6325918

Please sign in to comment.