From b9867c9084509ad6d4be88ff2b8e239b08bf1878 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Fri, 16 Aug 2024 16:24:40 -0400 Subject: [PATCH 01/37] :heavy_plus_sign: orientation checks for resources added to PipeConfigs --- CPAC/pipeline/engine.py | 18 ++++++++++++++++-- CPAC/pipeline/utils.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index d7f53f7029..2890c9e858 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -35,7 +35,7 @@ from CPAC.pipeline import nipype_pipeline_engine as pe from CPAC.pipeline.check_outputs import ExpectedOutputs from CPAC.pipeline.nodeblock import NodeBlockFunction -from CPAC.pipeline.utils import MOVEMENT_FILTER_KEYS, name_fork, source_set +from CPAC.pipeline.utils import MOVEMENT_FILTER_KEYS, name_fork, source_set, check_all_orientations from CPAC.registration.registration import transform_derivative from CPAC.resources.templates.lookup_table import lookup_identifier from CPAC.utils.bids_utils import res_in_filename @@ -65,6 +65,7 @@ ) + class ResourcePool: def __init__(self, rpool=None, name=None, cfg=None, pipe_list=None): if not rpool: @@ -2409,9 +2410,11 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): import pandas as pd import pkg_resources as p + import sys template_csv = p.resource_filename("CPAC", "resources/cpac_templates.csv") template_df = pd.read_csv(template_csv, keep_default_na=False) + templates = [] for row in template_df.itertuples(): key = row.Key @@ -2511,6 +2514,18 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): "", f"{key}_config_ingress", ) + #check if val is a nifti file .nii.gz + if val.endswith('.nii.gz'): + templates.append([key, val]) + + table = check_all_orientations(templates,"RPI") + df = pd.DataFrame(table, columns = ['Resource', 'Path', 'Orientation']) + + # check if any of the values in Orientation column are not RPI + if not df[df['Orientation'] != 'RPI'].empty: + WFLOGGER.info(f"The following templates are not in RPI orientation: {df}") + sys.exit() + # templates, resampling from config """ template_keys = [ @@ -2596,7 +2611,6 @@ def _set_nested(attr, keys): ) cfg.set_nested(cfg, key, node) """ - return rpool diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index 39acb6429f..a01e1a65d5 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -20,10 +20,41 @@ from CPAC.func_preproc.func_motion import motion_estimate_filter from CPAC.utils.bids_utils import insert_entity +from nipype import Node, Workflow, Function +from CPAC.pipeline import nipype_pipeline_engine as pe +from nipype.interfaces import afni +from nipype.interfaces.afni import Info +import os +import pandas as pd MOVEMENT_FILTER_KEYS = motion_estimate_filter.outputs +def find_orientation(input_file): + import subprocess + cmd_3dinfo = [ + "3dinfo", + "-orient", input_file + ] + + orientation = subprocess.run(cmd_3dinfo, capture_output=True, text=True).stdout.strip().upper() + return orientation + +def check_all_orientations(input_images:list, desired_orientation:str="RPI"): + desired_orientation = desired_orientation.upper() + orientations = [] + find_orient = Node(Function(input_names=["input_file"], + output_names=["orientation"], + function=find_orientation), + name="find_orient") + + for key, image in input_images: + find_orient.inputs.input_file = image + orientation = find_orient.run().outputs.orientation + orientations.append([key, image, orientation]) + return orientations + + def name_fork(resource_idx, cfg, json_info, out_dct): """Create and insert entities for forkpoints. From 81869e23c3ba41c32c3b05f1b478c2203a094389 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:29:02 -0400 Subject: [PATCH 02/37] Update CPAC/pipeline/utils.py Co-authored-by: Jon Clucas --- CPAC/pipeline/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index a01e1a65d5..252cb075c5 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -53,7 +53,7 @@ def check_all_orientations(input_images:list, desired_orientation:str="RPI"): orientation = find_orient.run().outputs.orientation orientations.append([key, image, orientation]) return orientations - + def name_fork(resource_idx, cfg, json_info, out_dct): """Create and insert entities for forkpoints. From 0a32a32d0fbb92fe047bdc2e0c40c9269cebeab1 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:29:16 -0400 Subject: [PATCH 03/37] Update CPAC/pipeline/engine.py Co-authored-by: Jon Clucas --- CPAC/pipeline/engine.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 2890c9e858..27b5ead94c 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -35,7 +35,12 @@ from CPAC.pipeline import nipype_pipeline_engine as pe from CPAC.pipeline.check_outputs import ExpectedOutputs from CPAC.pipeline.nodeblock import NodeBlockFunction -from CPAC.pipeline.utils import MOVEMENT_FILTER_KEYS, name_fork, source_set, check_all_orientations +from CPAC.pipeline.utils import ( + check_all_orientations, + MOVEMENT_FILTER_KEYS, + name_fork, + source_set, +) from CPAC.registration.registration import transform_derivative from CPAC.resources.templates.lookup_table import lookup_identifier from CPAC.utils.bids_utils import res_in_filename From d005b01d174a7588bd64207456865a509c98d56c Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:29:25 -0400 Subject: [PATCH 04/37] Update CPAC/pipeline/engine.py Co-authored-by: Jon Clucas --- CPAC/pipeline/engine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 27b5ead94c..42f2d22a19 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -2413,9 +2413,10 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): # ingress config file paths # TODO: may want to change the resource keys for each to include one level up in the YAML as well + import sys + import pandas as pd import pkg_resources as p - import sys template_csv = p.resource_filename("CPAC", "resources/cpac_templates.csv") template_df = pd.read_csv(template_csv, keep_default_na=False) From d31b1d9b18c248a6336e16c405a39161c461ebbc Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:29:41 -0400 Subject: [PATCH 05/37] Update CPAC/pipeline/engine.py Co-authored-by: Jon Clucas --- CPAC/pipeline/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 42f2d22a19..d11a4b6800 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -2520,8 +2520,8 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): "", f"{key}_config_ingress", ) - #check if val is a nifti file .nii.gz - if val.endswith('.nii.gz'): + # check if val is a nifti file .nii.gz + if val.endswith(".nii.gz"): templates.append([key, val]) table = check_all_orientations(templates,"RPI") From 548067824b3e595286701b98892d37182bcfbdd9 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:29:57 -0400 Subject: [PATCH 06/37] Update CPAC/pipeline/engine.py Co-authored-by: Jon Clucas --- CPAC/pipeline/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index d11a4b6800..66567e61ec 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -2524,8 +2524,8 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): if val.endswith(".nii.gz"): templates.append([key, val]) - table = check_all_orientations(templates,"RPI") - df = pd.DataFrame(table, columns = ['Resource', 'Path', 'Orientation']) + table = check_all_orientations(templates, "RPI") + df = pd.DataFrame(table, columns=["Resource", "Path", "Orientation"]) # check if any of the values in Orientation column are not RPI if not df[df['Orientation'] != 'RPI'].empty: From b9659522ce6f5073c73449f6e71ac00ed2f4daa2 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:30:06 -0400 Subject: [PATCH 07/37] Update CPAC/pipeline/engine.py Co-authored-by: Jon Clucas --- CPAC/pipeline/engine.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 66567e61ec..60b2eaf470 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -2528,9 +2528,10 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): df = pd.DataFrame(table, columns=["Resource", "Path", "Orientation"]) # check if any of the values in Orientation column are not RPI - if not df[df['Orientation'] != 'RPI'].empty: - WFLOGGER.info(f"The following templates are not in RPI orientation: {df}") - sys.exit() + other_orientation = df[df["Orientation"] != "RPI"] + if not other_orientation.empty: + msg = f"The following templates are not in RPI orientation: {other_orientation}" + OrientationError(msg) # templates, resampling from config """ From 9df6ab58e0a823d39dfa2508da55b717074e53fb Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:32:09 -0400 Subject: [PATCH 08/37] Update CPAC/pipeline/utils.py Co-authored-by: Jon Clucas --- CPAC/pipeline/utils.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index 252cb075c5..e95e7ac8b7 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -43,10 +43,14 @@ def find_orientation(input_file): def check_all_orientations(input_images:list, desired_orientation:str="RPI"): desired_orientation = desired_orientation.upper() orientations = [] - find_orient = Node(Function(input_names=["input_file"], - output_names=["orientation"], - function=find_orientation), - name="find_orient") + find_orient = Node( + Function( + input_names=["input_file"], + output_names=["orientation"], + function=find_orientation, + ), + name="find_orient", + ) for key, image in input_images: find_orient.inputs.input_file = image From c0006cd686983eaf257d7982c316366fab55be03 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:32:17 -0400 Subject: [PATCH 09/37] Update CPAC/pipeline/utils.py Co-authored-by: Jon Clucas --- CPAC/pipeline/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index e95e7ac8b7..2d8a1ed34c 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -39,7 +39,8 @@ def find_orientation(input_file): orientation = subprocess.run(cmd_3dinfo, capture_output=True, text=True).stdout.strip().upper() return orientation - + + def check_all_orientations(input_images:list, desired_orientation:str="RPI"): desired_orientation = desired_orientation.upper() orientations = [] From edf6d991df545583915439f0ac02e8ba4fc48afc Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:32:26 -0400 Subject: [PATCH 10/37] Update CPAC/pipeline/utils.py Co-authored-by: Jon Clucas --- CPAC/pipeline/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index 2d8a1ed34c..55491c80c6 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -37,7 +37,11 @@ def find_orientation(input_file): "-orient", input_file ] - orientation = subprocess.run(cmd_3dinfo, capture_output=True, text=True).stdout.strip().upper() + orientation = ( + subprocess.run(cmd_3dinfo, capture_output=True, text=True, check=False) + .stdout.strip() + .upper() + ) return orientation From 57d61334bbf7cbf64eb16afcac472750fccf1e16 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:32:36 -0400 Subject: [PATCH 11/37] Update CPAC/pipeline/utils.py Co-authored-by: Jon Clucas --- CPAC/pipeline/utils.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index 55491c80c6..b9b5a43f74 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -18,14 +18,10 @@ from itertools import chain +from nipype import Function, Node + from CPAC.func_preproc.func_motion import motion_estimate_filter from CPAC.utils.bids_utils import insert_entity -from nipype import Node, Workflow, Function -from CPAC.pipeline import nipype_pipeline_engine as pe -from nipype.interfaces import afni -from nipype.interfaces.afni import Info -import os -import pandas as pd MOVEMENT_FILTER_KEYS = motion_estimate_filter.outputs From 0f190d8faa5b21d61c5c4d59f872b35c647c0ad7 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:32:44 -0400 Subject: [PATCH 12/37] Update CPAC/pipeline/utils.py Co-authored-by: Jon Clucas --- CPAC/pipeline/utils.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index b9b5a43f74..90279c550d 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -28,10 +28,7 @@ def find_orientation(input_file): import subprocess - cmd_3dinfo = [ - "3dinfo", - "-orient", input_file - ] + cmd_3dinfo = ["3dinfo", "-orient", input_file] orientation = ( subprocess.run(cmd_3dinfo, capture_output=True, text=True, check=False) From c5b4a1ef777d0f813ad533e8ce2e257f7913b9e8 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 9 Sep 2024 13:04:03 -0400 Subject: [PATCH 13/37] adding desired-orientation as a config key --- CPAC/pipeline/engine.py | 16 +++++---- CPAC/pipeline/schema.py | 1 + CPAC/pipeline/utils.py | 33 +++++++++++++++++-- .../configs/pipeline_config_blank.yml | 4 +++ 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 60b2eaf470..f56826a1d6 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -70,7 +70,6 @@ ) - class ResourcePool: def __init__(self, rpool=None, name=None, cfg=None, pipe_list=None): if not rpool: @@ -2413,14 +2412,14 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): # ingress config file paths # TODO: may want to change the resource keys for each to include one level up in the YAML as well - import sys - import pandas as pd import pkg_resources as p + from nibabel.orientations import OrientationError template_csv = p.resource_filename("CPAC", "resources/cpac_templates.csv") template_df = pd.read_csv(template_csv, keep_default_na=False) templates = [] + desired_orientation = cfg.pipeline_setup["desired_orientation"] for row in template_df.itertuples(): key = row.Key @@ -2524,11 +2523,11 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): if val.endswith(".nii.gz"): templates.append([key, val]) - table = check_all_orientations(templates, "RPI") + table = check_all_orientations(templates, desired_orientation) df = pd.DataFrame(table, columns=["Resource", "Path", "Orientation"]) - + # check if any of the values in Orientation column are not RPI - other_orientation = df[df["Orientation"] != "RPI"] + other_orientation = df[df["Orientation"] != desired_orientation] if not other_orientation.empty: msg = f"The following templates are not in RPI orientation: {other_orientation}" OrientationError(msg) @@ -2692,7 +2691,10 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): rpool = ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path) # output files with 4 different scans - + for x in rpool.get_entire_pool().keys(): + print(x) + import sys + sys.exit() return (wf, rpool) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 915cb47045..c47025bf3b 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -423,6 +423,7 @@ def sanitize(filename): "skip env check": Maybe(bool), # flag for skipping an environment check "pipeline_setup": { "pipeline_name": All(str, Length(min=1), sanitize), + "desired_orientation": In({"RPI", "LPI", "RAI", "LAI", "RAS", "LAS", "RPS", "LPS"}), "output_directory": { "path": str, "source_outputs_dir": Maybe(str), diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index 90279c550d..2353d36158 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -27,18 +27,45 @@ def find_orientation(input_file): + """Find the orientation of the input file. + + Parameters + ---------- + input_file : str + Input file path + + Returns + ------- + orientation : str + Orientation of the input file + """ import subprocess + cmd_3dinfo = ["3dinfo", "-orient", input_file] - orientation = ( + return ( subprocess.run(cmd_3dinfo, capture_output=True, text=True, check=False) .stdout.strip() .upper() ) - return orientation -def check_all_orientations(input_images:list, desired_orientation:str="RPI"): +def check_all_orientations(input_images: list, desired_orientation: str = "RPI"): + """Check the orientation of all input images. + + Parameters + ---------- + input_images : list + List of input images + desired_orientation : str + Desired orientation of the input images + + Returns + ------- + orientations : list + List of orientations of the input images + + """ desired_orientation = desired_orientation.upper() orientations = [] find_orient = Node( diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 7f09680fc6..b3cd9863c5 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -11,6 +11,10 @@ pipeline_setup: # Name for this pipeline configuration - useful for identification. # This string will be sanitized and used in filepaths pipeline_name: cpac-blank-template + + # Desired orientation for the output data. "RPI", "LPI", "RAI", "LAI", "RAS", "LAS", "RPS", "LPS" + desired_orientation: RPI + output_directory: # Quality control outputs From a04d47d1526719295964849ad5f4f32fd170cce6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:11:59 +0000 Subject: [PATCH 14/37] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- CPAC/pipeline/engine.py | 1 + CPAC/pipeline/schema.py | 4 +++- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index f56826a1d6..0cb9517576 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -2694,6 +2694,7 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): for x in rpool.get_entire_pool().keys(): print(x) import sys + sys.exit() return (wf, rpool) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index c47025bf3b..997c6267b8 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -423,7 +423,9 @@ def sanitize(filename): "skip env check": Maybe(bool), # flag for skipping an environment check "pipeline_setup": { "pipeline_name": All(str, Length(min=1), sanitize), - "desired_orientation": In({"RPI", "LPI", "RAI", "LAI", "RAS", "LAS", "RPS", "LPS"}), + "desired_orientation": In( + {"RPI", "LPI", "RAI", "LAI", "RAS", "LAS", "RPS", "LPS"} + ), "output_directory": { "path": str, "source_outputs_dir": Maybe(str), diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index b3cd9863c5..454d8add59 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -11,7 +11,7 @@ pipeline_setup: # Name for this pipeline configuration - useful for identification. # This string will be sanitized and used in filepaths pipeline_name: cpac-blank-template - + # Desired orientation for the output data. "RPI", "LPI", "RAI", "LAI", "RAS", "LAS", "RPS", "LPS" desired_orientation: RPI From f2be81a6c1a99d9897db761bff03dbe546e5b795 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Mon, 9 Sep 2024 17:03:42 -0400 Subject: [PATCH 15/37] reorienting all files before rpool initialization --- CPAC/pipeline/engine.py | 35 +++++++++++++++++++++++++------- CPAC/pipeline/utils.py | 44 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 0cb9517576..6a6e631cee 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -68,7 +68,7 @@ read_json, write_output_json, ) - +from nibabel.orientations import OrientationError class ResourcePool: def __init__(self, rpool=None, name=None, cfg=None, pipe_list=None): @@ -2414,7 +2414,7 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): import pandas as pd import pkg_resources as p - from nibabel.orientations import OrientationError + template_csv = p.resource_filename("CPAC", "resources/cpac_templates.csv") template_df = pd.read_csv(template_csv, keep_default_na=False) @@ -2523,7 +2523,7 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): if val.endswith(".nii.gz"): templates.append([key, val]) - table = check_all_orientations(templates, desired_orientation) + table = check_all_orientations(templates, desired_orientation, reorient=True) df = pd.DataFrame(table, columns=["Resource", "Path", "Orientation"]) # check if any of the values in Orientation column are not RPI @@ -2660,8 +2660,33 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): creds_path = None rpool = ResourcePool(name=unique_id, cfg=cfg) + + desired_orientation = cfg.pipeline_setup["desired_orientation"] if data_paths: + # check all data_paths and convert it to the desired_orientations + #Convert all anat to desired_orientation + if "anat" in data_paths: + anat = [] + for key in data_paths["anat"]: + anat.append([key, data_paths["anat"][key]]) + if anat: + try: + orientation = check_all_orientations(anat, desired_orientation, reorient=True) + except OrientationError as e: + raise e("Anatomical data is not in the desired orientation") + + #Convert all func to desired_orientation + if "func" in data_paths: + func = [] + for key in data_paths["func"]: + func.append([key, data_paths["func"][key]["scan"]]) + if func: + try: + orientation = check_all_orientations(func, desired_orientation, reorient=True) + except : + raise OrientationError("Functional data is not in the desired orientation") + # ingress outdir try: if ( @@ -2691,11 +2716,7 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): rpool = ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path) # output files with 4 different scans - for x in rpool.get_entire_pool().keys(): - print(x) - import sys - sys.exit() return (wf, rpool) diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index 2353d36158..ff373423e2 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -49,8 +49,48 @@ def find_orientation(input_file): .upper() ) +def reorient_image(input_file, orientation): + """Reorient the input image to the desired orientation. Replaces the original input_file with the reoriented image. -def check_all_orientations(input_images: list, desired_orientation: str = "RPI"): + Parameters + ---------- + input_file : str + Input image file path + orientation : str + Desired orientation of the input image + + """ + import os + import subprocess + + output_file = os.path.join( + os.path.dirname(input_file), + f"reoriented_{os.path.basename(input_file)}", + ) + cmd_3drefit = ["3drefit", "-deoblique", input_file] + cmd_3dresample = [ + "3dresample", + "-orient", + orientation, + "-prefix", + output_file, + "-inset", + input_file, + ] + cmd_mv = ["mv", output_file, input_file] + print(f"""+++ +Reorienting : {input_file} +to : {orientation} ++++""") + subprocess.run(cmd_3drefit, check=True) + subprocess.run(cmd_3dresample, check=True) + print(f"""+++Replacing {input_file} with reoriented image + """) + subprocess.run(cmd_mv, check=True) + return + + +def check_all_orientations(input_images: list, desired_orientation: str = "RPI", reorient=True): """Check the orientation of all input images. Parameters @@ -80,6 +120,8 @@ def check_all_orientations(input_images: list, desired_orientation: str = "RPI") for key, image in input_images: find_orient.inputs.input_file = image orientation = find_orient.run().outputs.orientation + if reorient and orientation != desired_orientation: + reorient_image(image, desired_orientation) orientations.append([key, image, orientation]) return orientations From 995163c3c0d561b0ae8908f5d94480a377d59ea9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:03:55 +0000 Subject: [PATCH 16/37] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- CPAC/pipeline/engine.py | 26 ++++++++++++++++---------- CPAC/pipeline/utils.py | 7 +++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 6a6e631cee..ec7bbd0ff7 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -70,6 +70,7 @@ ) from nibabel.orientations import OrientationError + class ResourcePool: def __init__(self, rpool=None, name=None, cfg=None, pipe_list=None): if not rpool: @@ -2414,7 +2415,6 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): import pandas as pd import pkg_resources as p - template_csv = p.resource_filename("CPAC", "resources/cpac_templates.csv") template_df = pd.read_csv(template_csv, keep_default_na=False) @@ -2660,33 +2660,39 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): creds_path = None rpool = ResourcePool(name=unique_id, cfg=cfg) - + desired_orientation = cfg.pipeline_setup["desired_orientation"] if data_paths: # check all data_paths and convert it to the desired_orientations - #Convert all anat to desired_orientation + # Convert all anat to desired_orientation if "anat" in data_paths: anat = [] for key in data_paths["anat"]: anat.append([key, data_paths["anat"][key]]) if anat: try: - orientation = check_all_orientations(anat, desired_orientation, reorient=True) + orientation = check_all_orientations( + anat, desired_orientation, reorient=True + ) except OrientationError as e: raise e("Anatomical data is not in the desired orientation") - - #Convert all func to desired_orientation + + # Convert all func to desired_orientation if "func" in data_paths: func = [] for key in data_paths["func"]: func.append([key, data_paths["func"][key]["scan"]]) if func: try: - orientation = check_all_orientations(func, desired_orientation, reorient=True) - except : - raise OrientationError("Functional data is not in the desired orientation") - + orientation = check_all_orientations( + func, desired_orientation, reorient=True + ) + except: + raise OrientationError( + "Functional data is not in the desired orientation" + ) + # ingress outdir try: if ( diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index ff373423e2..cd6856a20f 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -49,6 +49,7 @@ def find_orientation(input_file): .upper() ) + def reorient_image(input_file, orientation): """Reorient the input image to the desired orientation. Replaces the original input_file with the reoriented image. @@ -79,7 +80,7 @@ def reorient_image(input_file, orientation): ] cmd_mv = ["mv", output_file, input_file] print(f"""+++ -Reorienting : {input_file} +Reorienting : {input_file} to : {orientation} +++""") subprocess.run(cmd_3drefit, check=True) @@ -90,7 +91,9 @@ def reorient_image(input_file, orientation): return -def check_all_orientations(input_images: list, desired_orientation: str = "RPI", reorient=True): +def check_all_orientations( + input_images: list, desired_orientation: str = "RPI", reorient=True +): """Check the orientation of all input images. Parameters From 5aeebbb05b6b0e4870d9531375ff3247aa341865 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Tue, 17 Sep 2024 16:34:43 -0400 Subject: [PATCH 17/37] moved orientation check and reorient if necessary to the wf --- CPAC/pipeline/engine.py | 102 ++++++++++++------------------------- CPAC/pipeline/utils.py | 108 +++++++++++++++------------------------- 2 files changed, 72 insertions(+), 138 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index ec7bbd0ff7..f1188b3b2b 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -36,7 +36,7 @@ from CPAC.pipeline.check_outputs import ExpectedOutputs from CPAC.pipeline.nodeblock import NodeBlockFunction from CPAC.pipeline.utils import ( - check_all_orientations, + check_orientation, MOVEMENT_FILTER_KEYS, name_fork, source_set, @@ -68,7 +68,6 @@ read_json, write_output_json, ) -from nibabel.orientations import OrientationError class ResourcePool: @@ -2409,7 +2408,7 @@ def strip_template(data_label, dir_path, filename): return data_label, json -def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): +def ingress_pipeconfig_paths(wf, cfg, rpool, unique_id, creds_path=None): # ingress config file paths # TODO: may want to change the resource keys for each to include one level up in the YAML as well @@ -2418,7 +2417,6 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): template_csv = p.resource_filename("CPAC", "resources/cpac_templates.csv") template_df = pd.read_csv(template_csv, keep_default_na=False) - templates = [] desired_orientation = cfg.pipeline_setup["desired_orientation"] for row in template_df.itertuples(): @@ -2489,19 +2487,9 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): resampled_template.inputs.template_name = key resampled_template.inputs.tag = tag - # the set_data below is set up a little differently, because we are - # injecting and also over-writing already-existing entries - # other alternative would have been to ingress into the - # resampled_template node from the already existing entries, but we - # didn't do that here - rpool.set_data( - key, - resampled_template, - "resampled_template", - json_info, - "", - "template_resample", - ) # pipe_idx (after the blank json {}) should be the previous strat that you want deleted! because you're not connecting this the regular way, you have to do it manually + node = resampled_template + output = "resampled_template" + node_name = f"{key}_resampled_template" elif val: config_ingress = create_general_datasource(f"gather_{key}") @@ -2511,27 +2499,31 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): creds_path=creds_path, dl_dir=cfg.pipeline_setup["working_directory"]["path"], ) - rpool.set_data( - key, - config_ingress, - "outputspec.data", - json_info, - "", - f"{key}_config_ingress", - ) - # check if val is a nifti file .nii.gz - if val.endswith(".nii.gz"): - templates.append([key, val]) - - table = check_all_orientations(templates, desired_orientation, reorient=True) - df = pd.DataFrame(table, columns=["Resource", "Path", "Orientation"]) - - # check if any of the values in Orientation column are not RPI - other_orientation = df[df["Orientation"] != desired_orientation] - if not other_orientation.empty: - msg = f"The following templates are not in RPI orientation: {other_orientation}" - OrientationError(msg) - + node = config_ingress + output = "outputspec.data" + node_name = f"{key}_config_ingress" + + # check if the output is in desired orientation, if not reorient it + check_orient = pe.Node( + Function( + input_names=["input_file", "desired_orientation", "reorient"], + output_names=["orientation"], + function=check_orientation, + ), + name=f"check_orientation_{key}", + ) + wf.connect(node, output, check_orient, "input_file") + check_orient.inputs.desired_orientation = desired_orientation + check_orient.inputs.reorient = True + + rpool.set_data( + key, + check_orient, + "output_file", + json_info, + "", + f"check_orient-{node_name}-{key}", + ) # templates, resampling from config """ template_keys = [ @@ -2617,7 +2609,7 @@ def _set_nested(attr, keys): ) cfg.set_nested(cfg, key, node) """ - return rpool + return wf, rpool def initiate_rpool(wf, cfg, data_paths=None, part_id=None): @@ -2661,38 +2653,8 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): rpool = ResourcePool(name=unique_id, cfg=cfg) - desired_orientation = cfg.pipeline_setup["desired_orientation"] if data_paths: - # check all data_paths and convert it to the desired_orientations - # Convert all anat to desired_orientation - if "anat" in data_paths: - anat = [] - for key in data_paths["anat"]: - anat.append([key, data_paths["anat"][key]]) - if anat: - try: - orientation = check_all_orientations( - anat, desired_orientation, reorient=True - ) - except OrientationError as e: - raise e("Anatomical data is not in the desired orientation") - - # Convert all func to desired_orientation - if "func" in data_paths: - func = [] - for key in data_paths["func"]: - func.append([key, data_paths["func"][key]["scan"]]) - if func: - try: - orientation = check_all_orientations( - func, desired_orientation, reorient=True - ) - except: - raise OrientationError( - "Functional data is not in the desired orientation" - ) - # ingress outdir try: if ( @@ -2719,7 +2681,7 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): ) # grab any file paths from the pipeline config YAML - rpool = ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path) + wf, rpool = ingress_pipeconfig_paths(wf, cfg, rpool, unique_id, creds_path) # output files with 4 different scans diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index cd6856a20f..cafbf3d686 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -18,21 +18,24 @@ from itertools import chain -from nipype import Function, Node - from CPAC.func_preproc.func_motion import motion_estimate_filter from CPAC.utils.bids_utils import insert_entity +from CPAC.utils.monitoring import IFLOGGER MOVEMENT_FILTER_KEYS = motion_estimate_filter.outputs -def find_orientation(input_file): - """Find the orientation of the input file. +def check_orientation(input_file, desired_orientation, reorient=False): + """Find the orientation of the input file and reorient it if necessary. Parameters ---------- input_file : str Input file path + desired_orientation : str + Desired orientation of the input file + reorient : bool + Reorient the input file to the desired orientation Returns ------- @@ -43,11 +46,16 @@ def find_orientation(input_file): cmd_3dinfo = ["3dinfo", "-orient", input_file] - return ( + orientation = ( subprocess.run(cmd_3dinfo, capture_output=True, text=True, check=False) .stdout.strip() .upper() ) + if orientation != desired_orientation and reorient: + output_file = reorient_image(input_file, desired_orientation) + else: + output_file = input_file + return output_file def reorient_image(input_file, orientation): @@ -60,73 +68,37 @@ def reorient_image(input_file, orientation): orientation : str Desired orientation of the input image - """ - import os - import subprocess - - output_file = os.path.join( - os.path.dirname(input_file), - f"reoriented_{os.path.basename(input_file)}", - ) - cmd_3drefit = ["3drefit", "-deoblique", input_file] - cmd_3dresample = [ - "3dresample", - "-orient", - orientation, - "-prefix", - output_file, - "-inset", - input_file, - ] - cmd_mv = ["mv", output_file, input_file] - print(f"""+++ -Reorienting : {input_file} -to : {orientation} -+++""") - subprocess.run(cmd_3drefit, check=True) - subprocess.run(cmd_3dresample, check=True) - print(f"""+++Replacing {input_file} with reoriented image - """) - subprocess.run(cmd_mv, check=True) - return - - -def check_all_orientations( - input_images: list, desired_orientation: str = "RPI", reorient=True -): - """Check the orientation of all input images. - - Parameters - ---------- - input_images : list - List of input images - desired_orientation : str - Desired orientation of the input images - Returns ------- - orientations : list - List of orientations of the input images - + output_file : str + Reoriented image file path """ - desired_orientation = desired_orientation.upper() - orientations = [] - find_orient = Node( - Function( - input_names=["input_file"], - output_names=["orientation"], - function=find_orientation, - ), - name="find_orient", - ) + try: + import os + import subprocess + + output_file = os.path.join( + os.path.dirname(input_file), + f"reoriented_{os.path.basename(input_file)}", + ) + cmd_3drefit = ["3drefit", "-deoblique", input_file] + cmd_3dresample = [ + "3dresample", + "-orient", + orientation, + "-prefix", + output_file, + "-inset", + input_file, + ] - for key, image in input_images: - find_orient.inputs.input_file = image - orientation = find_orient.run().outputs.orientation - if reorient and orientation != desired_orientation: - reorient_image(image, desired_orientation) - orientations.append([key, image, orientation]) - return orientations + IFLOGGER.info(f"""+++\nReorienting : {input_file}\nto : {orientation}\n+++""") + subprocess.run(cmd_3drefit, check=True) + subprocess.run(cmd_3dresample, check=True) + return output_file + except Exception as e: + IFLOGGER.error(f"Reorienting failed for {input_file} with error: {e}") + return input_file def name_fork(resource_idx, cfg, json_info, out_dct): From e8baa282476829d813de42e628d4b6b4580df26c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 20:35:00 +0000 Subject: [PATCH 18/37] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- CPAC/pipeline/engine.py | 1 - 1 file changed, 1 deletion(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index f1188b3b2b..586690ce72 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -2653,7 +2653,6 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): rpool = ResourcePool(name=unique_id, cfg=cfg) - if data_paths: # ingress outdir try: From ef10e36db930fdaf1bfdd8d8440a81beb1583577 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Tue, 17 Sep 2024 16:51:16 -0400 Subject: [PATCH 19/37] renaming output name correctly --- CPAC/pipeline/engine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 586690ce72..77825a2d10 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -2507,10 +2507,10 @@ def ingress_pipeconfig_paths(wf, cfg, rpool, unique_id, creds_path=None): check_orient = pe.Node( Function( input_names=["input_file", "desired_orientation", "reorient"], - output_names=["orientation"], + output_names=["output_file"], function=check_orientation, ), - name=f"check_orientation_{key}", + name=f"check_orient_{key}", ) wf.connect(node, output, check_orient, "input_file") check_orient.inputs.desired_orientation = desired_orientation From 6bfd6806e47bf3394bb22f0f3eb8a35b96190f44 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Wed, 18 Sep 2024 13:23:58 -0400 Subject: [PATCH 20/37] handle for read-only template files --- CPAC/pipeline/engine.py | 46 +++++++++------- CPAC/pipeline/utils.py | 119 ++++++++++++++++++++++++---------------- 2 files changed, 96 insertions(+), 69 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 77825a2d10..ac81436f57 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -2503,27 +2503,31 @@ def ingress_pipeconfig_paths(wf, cfg, rpool, unique_id, creds_path=None): output = "outputspec.data" node_name = f"{key}_config_ingress" - # check if the output is in desired orientation, if not reorient it - check_orient = pe.Node( - Function( - input_names=["input_file", "desired_orientation", "reorient"], - output_names=["output_file"], - function=check_orientation, - ), - name=f"check_orient_{key}", - ) - wf.connect(node, output, check_orient, "input_file") - check_orient.inputs.desired_orientation = desired_orientation - check_orient.inputs.reorient = True - - rpool.set_data( - key, - check_orient, - "output_file", - json_info, - "", - f"check_orient-{node_name}-{key}", - ) + if val.endswith(".nii.gz"): + # check if the output is in desired orientation, if not reorient it + check_orient = pe.Node( + Function( + input_names=["input_file", "desired_orientation", "reorient"], + output_names=["output_file"], + function=check_orientation, + imports=["from CPAC.pipeline.utils import reorient_image"], + ), + name=f"check_orient_{key}", + ) + wf.connect(node, output, check_orient, "input_file") + check_orient.inputs.desired_orientation = desired_orientation + check_orient.inputs.reorient = True + + rpool.set_data( + key, + check_orient, + "output_file", + json_info, + "", + f"check_orient-{node_name}-{key}", + ) + else: + rpool.set_data(key, node, output, json_info, "", node_name) # templates, resampling from config """ template_keys = [ diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index cafbf3d686..251eece667 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -25,80 +25,103 @@ MOVEMENT_FILTER_KEYS = motion_estimate_filter.outputs -def check_orientation(input_file, desired_orientation, reorient=False): - """Find the orientation of the input file and reorient it if necessary. +def reorient_image(input_file, orientation): + """Reorient the input image to the desired orientation. Replaces the original input_file with the reoriented image. Parameters ---------- input_file : str - Input file path - desired_orientation : str - Desired orientation of the input file - reorient : bool - Reorient the input file to the desired orientation + Input image file path + orientation : str + Desired orientation of the input image Returns ------- - orientation : str - Orientation of the input file + output_file : str + Reoriented image file path """ + import os + import shutil import subprocess - cmd_3dinfo = ["3dinfo", "-orient", input_file] - - orientation = ( - subprocess.run(cmd_3dinfo, capture_output=True, text=True, check=False) - .stdout.strip() - .upper() + output_file = os.path.join( + os.getcwd(), + f"reoriented_{os.path.basename(input_file)}", ) - if orientation != desired_orientation and reorient: - output_file = reorient_image(input_file, desired_orientation) - else: - output_file = input_file + # if output file exist delete it + if os.path.exists(output_file): + os.remove(output_file) + + # make a copy of the input file as temp file so that the original file is not modified + temp_file = os.path.join( + os.getcwd(), + f"temp_{os.path.basename(input_file)}", + ) + shutil.copy(input_file, temp_file) + + cmd_3drefit = ["3drefit", "-deoblique", temp_file] + cmd_3dresample = [ + "3dresample", + "-orient", + orientation, + "-prefix", + output_file, + "-inset", + temp_file, + ] + subprocess.run(cmd_3drefit, check=True) + subprocess.run(cmd_3dresample, check=True) + + # remove the temporary file + os.remove(temp_file) + return output_file -def reorient_image(input_file, orientation): - """Reorient the input image to the desired orientation. Replaces the original input_file with the reoriented image. +def check_orientation(input_file, desired_orientation, reorient=True): + """Find the orientation of the input file and reorient it if necessary. Does not modify the original input file. Parameters ---------- input_file : str - Input image file path - orientation : str - Desired orientation of the input image + Input file path + desired_orientation : str + Desired orientation of the input file + reorient : bool + Reorient the input file to the desired orientation Returns ------- output_file : str Reoriented image file path """ - try: - import os - import subprocess + import subprocess - output_file = os.path.join( - os.path.dirname(input_file), - f"reoriented_{os.path.basename(input_file)}", - ) - cmd_3drefit = ["3drefit", "-deoblique", input_file] - cmd_3dresample = [ - "3dresample", - "-orient", - orientation, - "-prefix", - output_file, - "-inset", - input_file, - ] + cmd_3dinfo = ["3dinfo", "-orient", input_file] - IFLOGGER.info(f"""+++\nReorienting : {input_file}\nto : {orientation}\n+++""") - subprocess.run(cmd_3drefit, check=True) - subprocess.run(cmd_3dresample, check=True) - return output_file - except Exception as e: - IFLOGGER.error(f"Reorienting failed for {input_file} with error: {e}") - return input_file + orientation = ( + subprocess.run(cmd_3dinfo, capture_output=True, text=True, check=False) + .stdout.strip() + .upper() + ) + if orientation != desired_orientation and reorient: + IFLOGGER.info( + f"+++ Reorienting {input_file} from {orientation} to {desired_orientation} +++" + ) + try: + output_file = reorient_image(input_file, desired_orientation) + except Exception as e: + IFLOGGER.error( + f"Error in reorienting the image: {input_file}.\nCould not reorient the image to {desired_orientation}" + ) + IFLOGGER.error(f"Error: {e}") + output_file = input_file # return the original file ? + else: + IFLOGGER.info( + f"+++ Orientation of {input_file} is already {desired_orientation} +++" + ) + output_file = input_file + return output_file def name_fork(resource_idx, cfg, json_info, out_dct): From e454cec6623459724d4cf6fe3797061a44b84e49 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Thu, 26 Sep 2024 14:46:28 -0400 Subject: [PATCH 21/37] adding reorient nodes in anat, func, freesurfer and template ingress nodes --- CPAC/anat_preproc/anat_preproc.py | 17 +---- CPAC/func_preproc/func_preproc.py | 16 +--- CPAC/pipeline/engine.py | 117 +++++++++++++++++++++--------- CPAC/pipeline/utils.py | 101 -------------------------- CPAC/utils/datasource.py | 3 +- 5 files changed, 91 insertions(+), 163 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 0f4e770f97..7d2c7db767 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -1454,21 +1454,10 @@ def anatomical_init(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data("T1w") wf.connect(node, out, anat_deoblique, "in_file") - anat_reorient = pe.Node( - interface=afni.Resample(), - name=f"anat_reorient_{pipe_num}", - mem_gb=0, - mem_x=(0.0115, "in_file", "t"), - ) - anat_reorient.inputs.orientation = "RPI" - anat_reorient.inputs.outputtype = "NIFTI_GZ" - - wf.connect(anat_deoblique, "out_file", anat_reorient, "in_file") - outputs = { - "desc-preproc_T1w": (anat_reorient, "out_file"), - "desc-reorient_T1w": (anat_reorient, "out_file"), - "desc-head_T1w": (anat_reorient, "out_file"), + "desc-preproc_T1w": (anat_deoblique, "out_file"), + "desc-reorient_T1w": (anat_deoblique, "out_file"), + "desc-head_T1w": (anat_deoblique, "out_file"), } return (wf, outputs) diff --git a/CPAC/func_preproc/func_preproc.py b/CPAC/func_preproc/func_preproc.py index 7004b4f025..2007591c84 100644 --- a/CPAC/func_preproc/func_preproc.py +++ b/CPAC/func_preproc/func_preproc.py @@ -521,21 +521,9 @@ def func_reorient(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data("bold") wf.connect(node, out, func_deoblique, "in_file") - func_reorient = pe.Node( - interface=afni_utils.Resample(), - name=f"func_reorient_{pipe_num}", - mem_gb=0, - mem_x=(0.0115, "in_file", "t"), - ) - - func_reorient.inputs.orientation = "RPI" - func_reorient.inputs.outputtype = "NIFTI_GZ" - - wf.connect(func_deoblique, "out_file", func_reorient, "in_file") - outputs = { - "desc-preproc_bold": (func_reorient, "out_file"), - "desc-reorient_bold": (func_reorient, "out_file"), + "desc-preproc_bold": (func_deoblique, "out_file"), + "desc-reorient_bold": (func_deoblique, "out_file"), } return (wf, outputs) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index ac81436f57..b1c05190a5 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -25,6 +25,7 @@ import warnings from nipype import config, logging +from nipype.interfaces import afni from nipype.interfaces.utility import Rename from CPAC.image_utils.spatial_smoothing import spatial_smoothing @@ -36,7 +37,6 @@ from CPAC.pipeline.check_outputs import ExpectedOutputs from CPAC.pipeline.nodeblock import NodeBlockFunction from CPAC.pipeline.utils import ( - check_orientation, MOVEMENT_FILTER_KEYS, name_fork, source_set, @@ -1908,6 +1908,7 @@ def wrap_block(node_blocks, interface, wf, cfg, strat_pool, pipe_num, opt): def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id): + desired_orientation = cfg.pipeline_setup["desired_orientation"] if "anat" not in data_paths: WFLOGGER.warning("No anatomical data present.") return rpool @@ -1931,7 +1932,17 @@ def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id dl_dir=cfg.pipeline_setup["working_directory"]["path"], img_type="anat", ) - rpool.set_data("T1w", anat_flow, "outputspec.anat", {}, "", "anat_ingress") + reorient = pe.Node( + interface=afni.Resample(), + name=f"reorient_T1w_{part_id}_{ses_id}", + ) + + reorient.inputs.orientation = desired_orientation + reorient.inputs.outputtype = "NIFTI_GZ" + + wf.connect(anat_flow, "outputspec.anat", reorient, "in_file") + + rpool.set_data("T1w", reorient, "out_file", {}, "", "anat_ingress") if "T2w" in data_paths["anat"]: anat_flow_T2 = create_anat_datasource(f"anat_T2w_gather_{part_id}_{ses_id}") @@ -1942,7 +1953,17 @@ def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id dl_dir=cfg.pipeline_setup["working_directory"]["path"], img_type="anat", ) - rpool.set_data("T2w", anat_flow_T2, "outputspec.anat", {}, "", "anat_ingress") + reorient = pe.Node( + interface=afni.Resample(), + name=f"reorient_T1w_{part_id}_{ses_id}", + ) + + reorient.inputs.orientation = desired_orientation + reorient.inputs.outputtype = "NIFTI_GZ" + + wf.connect(anat_flow_T2, "outputspec.anat", reorient, "in_file") + + rpool.set_data("T2w", reorient, "out_file", {}, "", "anat_ingress") if cfg.surface_analysis["freesurfer"]["ingress_reconall"]: rpool = ingress_freesurfer( @@ -1989,13 +2010,28 @@ def ingress_freesurfer(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id): creds_path=data_paths["creds_path"], dl_dir=cfg.pipeline_setup["working_directory"]["path"], ) + node = fs_ingress + out = "outputspec.data" + node_name = "freesurfer_config_ingress" + + if fs_path.endswith(".nii.gz" or ".nii"): + reorient = pe.Node( + interface=afni.Resample(), + name=f"reorient_fs_{part_id}_{ses_id}", + ) + reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] + reorient.inputs.outputtype = "NIFTI_GZ" + wf.connect(fs_ingress, "outputspec.data", reorient, "in_file") + node = reorient + out = "out_file" + node_name = "reorient_fs" rpool.set_data( "freesurfer-subject-dir", - fs_ingress, - "outputspec.data", + node, + out, {}, "", - "freesurfer_config_ingress", + node_name, ) recon_outs = { @@ -2058,8 +2094,18 @@ def ingress_raw_func_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id func_wf.get_node("inputnode").iterables = ("scan", list(func_paths_dct.keys())) rpool.set_data("subject", func_wf, "outputspec.subject", {}, "", "func_ingress") - rpool.set_data("bold", func_wf, "outputspec.rest", {}, "", "func_ingress") + reorient = pe.Node( + interface=afni.Resample(), + name=f"reorient_func_{part_id}_{ses_id}", + ) + reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] + reorient.inputs.outputtype = "NIFTI_GZ" + wf.connect(func_wf, "outputspec.rest", reorient, "in_file") + rpool.set_data("bold", reorient, "out_file", {}, "", "func_ingress") + # rpool.set_data("bold", func_wf, "outputspec.rest", {}, "", "func_ingress") + rpool.set_data("scan", func_wf, "outputspec.scan", {}, "", "func_ingress") + rpool.set_data( "scan-params", func_wf, "outputspec.scan_params", {}, "", "scan_params_ingress" ) @@ -2474,7 +2520,13 @@ def ingress_pipeconfig_paths(wf, cfg, rpool, unique_id, creds_path=None): resampled_template = pe.Node( Function( - input_names=["resolution", "template", "template_name", "tag"], + input_names=[ + "orientation", + "resolution", + "template", + "template_name", + "tag", + ], output_names=["resampled_template"], function=resolve_resolution, as_module=True, @@ -2482,6 +2534,7 @@ def ingress_pipeconfig_paths(wf, cfg, rpool, unique_id, creds_path=None): name="resampled_" + key, ) + resampled_template.inputs.orientation = desired_orientation resampled_template.inputs.resolution = resolution resampled_template.inputs.template = val resampled_template.inputs.template_name = key @@ -2489,7 +2542,7 @@ def ingress_pipeconfig_paths(wf, cfg, rpool, unique_id, creds_path=None): node = resampled_template output = "resampled_template" - node_name = f"{key}_resampled_template" + node_name = "template_resample" elif val: config_ingress = create_general_datasource(f"gather_{key}") @@ -2503,31 +2556,29 @@ def ingress_pipeconfig_paths(wf, cfg, rpool, unique_id, creds_path=None): output = "outputspec.data" node_name = f"{key}_config_ingress" - if val.endswith(".nii.gz"): - # check if the output is in desired orientation, if not reorient it - check_orient = pe.Node( - Function( - input_names=["input_file", "desired_orientation", "reorient"], - output_names=["output_file"], - function=check_orientation, - imports=["from CPAC.pipeline.utils import reorient_image"], - ), - name=f"check_orient_{key}", - ) - wf.connect(node, output, check_orient, "input_file") - check_orient.inputs.desired_orientation = desired_orientation - check_orient.inputs.reorient = True + if val.endswith(".nii" or ".nii.gz"): + check_reorient = pe.Node( + interface=afni.Resample(), + name=f"reorient_{key}", + ) + + check_reorient.inputs.orientation = desired_orientation + check_reorient.inputs.outputtype = "NIFTI_GZ" + + wf.connect(node, output, check_reorient, "in_file") + node = check_reorient + output = "out_file" + node_name = f"{key}_reorient" + + rpool.set_data( + key, + node, + output, + json_info, + "", + node_name, + ) - rpool.set_data( - key, - check_orient, - "output_file", - json_info, - "", - f"check_orient-{node_name}-{key}", - ) - else: - rpool.set_data(key, node, output, json_info, "", node_name) # templates, resampling from config """ template_keys = [ diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index 251eece667..f3b08be1ba 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -20,110 +20,9 @@ from CPAC.func_preproc.func_motion import motion_estimate_filter from CPAC.utils.bids_utils import insert_entity -from CPAC.utils.monitoring import IFLOGGER MOVEMENT_FILTER_KEYS = motion_estimate_filter.outputs - -def reorient_image(input_file, orientation): - """Reorient the input image to the desired orientation. Replaces the original input_file with the reoriented image. - - Parameters - ---------- - input_file : str - Input image file path - orientation : str - Desired orientation of the input image - - Returns - ------- - output_file : str - Reoriented image file path - """ - import os - import shutil - import subprocess - - output_file = os.path.join( - os.getcwd(), - f"reoriented_{os.path.basename(input_file)}", - ) - # if output file exist delete it - if os.path.exists(output_file): - os.remove(output_file) - - # make a copy of the input file as temp file so that the original file is not modified - temp_file = os.path.join( - os.getcwd(), - f"temp_{os.path.basename(input_file)}", - ) - shutil.copy(input_file, temp_file) - - cmd_3drefit = ["3drefit", "-deoblique", temp_file] - cmd_3dresample = [ - "3dresample", - "-orient", - orientation, - "-prefix", - output_file, - "-inset", - temp_file, - ] - subprocess.run(cmd_3drefit, check=True) - subprocess.run(cmd_3dresample, check=True) - - # remove the temporary file - os.remove(temp_file) - - return output_file - - -def check_orientation(input_file, desired_orientation, reorient=True): - """Find the orientation of the input file and reorient it if necessary. Does not modify the original input file. - - Parameters - ---------- - input_file : str - Input file path - desired_orientation : str - Desired orientation of the input file - reorient : bool - Reorient the input file to the desired orientation - - Returns - ------- - output_file : str - Reoriented image file path - """ - import subprocess - - cmd_3dinfo = ["3dinfo", "-orient", input_file] - - orientation = ( - subprocess.run(cmd_3dinfo, capture_output=True, text=True, check=False) - .stdout.strip() - .upper() - ) - if orientation != desired_orientation and reorient: - IFLOGGER.info( - f"+++ Reorienting {input_file} from {orientation} to {desired_orientation} +++" - ) - try: - output_file = reorient_image(input_file, desired_orientation) - except Exception as e: - IFLOGGER.error( - f"Error in reorienting the image: {input_file}.\nCould not reorient the image to {desired_orientation}" - ) - IFLOGGER.error(f"Error: {e}") - output_file = input_file # return the original file ? - else: - IFLOGGER.info( - f"+++ Orientation of {input_file} is already {desired_orientation} +++" - ) - output_file = input_file - return output_file - - def name_fork(resource_idx, cfg, json_info, out_dct): """Create and insert entities for forkpoints. diff --git a/CPAC/utils/datasource.py b/CPAC/utils/datasource.py index 008e674c2d..eedc171561 100644 --- a/CPAC/utils/datasource.py +++ b/CPAC/utils/datasource.py @@ -1156,7 +1156,7 @@ def res_string_to_tuple(resolution): return (float(resolution.replace("mm", "")),) * 3 -def resolve_resolution(resolution, template, template_name, tag=None): +def resolve_resolution(orientation, resolution, template, template_name, tag=None): """Resample a template to a given resolution.""" from nipype.interfaces import afni @@ -1203,6 +1203,7 @@ def resolve_resolution(resolution, template, template_name, tag=None): resample.inputs.resample_mode = "Cu" resample.inputs.in_file = local_path resample.base_dir = "." + resample.orientation = orientation resampled_template = resample.run() local_path = resampled_template.outputs.out_file From d47defb156b7a50b82c22c929a04f48dbd59492c Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Tue, 1 Oct 2024 10:13:10 -0400 Subject: [PATCH 22/37] fix a typo in orientation flag for resample --- CPAC/anat_preproc/anat_preproc.py | 17 +++-------------- CPAC/utils/datasource.py | 2 +- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 7d2c7db767..300eb6b878 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -2251,21 +2251,10 @@ def anatomical_init_T2(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data("T2w") wf.connect(node, out, T2_deoblique, "in_file") - T2_reorient = pe.Node( - interface=afni.Resample(), - name=f"T2_reorient_{pipe_num}", - mem_gb=0, - mem_x=(0.0115, "in_file", "t"), - ) - T2_reorient.inputs.orientation = "RPI" - T2_reorient.inputs.outputtype = "NIFTI_GZ" - - wf.connect(T2_deoblique, "out_file", T2_reorient, "in_file") - outputs = { - "desc-preproc_T2w": (T2_reorient, "out_file"), - "desc-reorient_T2w": (T2_reorient, "out_file"), - "desc-head_T2w": (T2_reorient, "out_file"), + "desc-preproc_T2w": (T2_deoblique, "out_file"), + "desc-reorient_T2w": (T2_deoblique, "out_file"), + "desc-head_T2w": (T2_deoblique, "out_file"), } return (wf, outputs) diff --git a/CPAC/utils/datasource.py b/CPAC/utils/datasource.py index eedc171561..25adb1eeca 100644 --- a/CPAC/utils/datasource.py +++ b/CPAC/utils/datasource.py @@ -1203,7 +1203,7 @@ def resolve_resolution(orientation, resolution, template, template_name, tag=Non resample.inputs.resample_mode = "Cu" resample.inputs.in_file = local_path resample.base_dir = "." - resample.orientation = orientation + resample.inputs.orientation = orientation resampled_template = resample.run() local_path = resampled_template.outputs.out_file From c9b69b93c2bc6d6eb11d55baabd4a82d75fa5d39 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 14:15:15 +0000 Subject: [PATCH 23/37] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- CPAC/pipeline/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py index f3b08be1ba..39acb6429f 100644 --- a/CPAC/pipeline/utils.py +++ b/CPAC/pipeline/utils.py @@ -23,6 +23,7 @@ MOVEMENT_FILTER_KEYS = motion_estimate_filter.outputs + def name_fork(resource_idx, cfg, json_info, out_dct): """Create and insert entities for forkpoints. From d0a7c2aef02964eaada90680fee78c37b162823b Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Tue, 1 Oct 2024 10:59:49 -0400 Subject: [PATCH 24/37] updating the orientation flag at other places where resolve_resolution is being used --- CPAC/longitudinal_pipeline/longitudinal_workflow.py | 1 + CPAC/registration/tests/mocks.py | 1 + CPAC/utils/test_mocks.py | 1 + 3 files changed, 3 insertions(+) diff --git a/CPAC/longitudinal_pipeline/longitudinal_workflow.py b/CPAC/longitudinal_pipeline/longitudinal_workflow.py index 4229fc30c6..9134769d6c 100644 --- a/CPAC/longitudinal_pipeline/longitudinal_workflow.py +++ b/CPAC/longitudinal_pipeline/longitudinal_workflow.py @@ -1204,6 +1204,7 @@ def func_longitudinal_template_wf(subject_id, strat_list, config): resampled_template.inputs.template = template resampled_template.inputs.template_name = template_name resampled_template.inputs.tag = tag + resampled_template.inputs.orientation = config['desired_orientation'] strat_init.update_resource_pool( {template_name: (resampled_template, "resampled_template")} diff --git a/CPAC/registration/tests/mocks.py b/CPAC/registration/tests/mocks.py index 18501c5a9a..4f35595abd 100644 --- a/CPAC/registration/tests/mocks.py +++ b/CPAC/registration/tests/mocks.py @@ -151,6 +151,7 @@ def configuration_strategy_mock(method="FSL"): resampled_template.inputs.template = template resampled_template.inputs.template_name = template_name resampled_template.inputs.tag = tag + resampled_template.inputs.orientation = "RPI" strat.update_resource_pool( {template_name: (resampled_template, "resampled_template")} diff --git a/CPAC/utils/test_mocks.py b/CPAC/utils/test_mocks.py index 336488f318..ea16c0be36 100644 --- a/CPAC/utils/test_mocks.py +++ b/CPAC/utils/test_mocks.py @@ -235,6 +235,7 @@ def configuration_strategy_mock(method="FSL"): resampled_template.inputs.template = template resampled_template.inputs.template_name = template_name resampled_template.inputs.tag = tag + resampled_template.inputs.orientation = "RPI" strat.update_resource_pool( {template_name: (resampled_template, "resampled_template")} From 7246e449ae56ba116203bead402b95fa84629d17 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Tue, 1 Oct 2024 14:37:35 -0400 Subject: [PATCH 25/37] reverting adding reorient node at the very begining and passing orientation set in config in the existing nodes for reorientations --- CPAC/anat_preproc/anat_preproc.py | 38 ++++++++++++++++----- CPAC/func_preproc/func_preproc.py | 16 +++++++-- CPAC/pipeline/engine.py | 56 ++++--------------------------- 3 files changed, 51 insertions(+), 59 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 300eb6b878..a561f8e077 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -1233,7 +1233,7 @@ def freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): mem_gb=0, mem_x=(0.0115, "in_file", "t"), ) - reorient_fs_brainmask.inputs.orientation = "RPI" + reorient_fs_brainmask.inputs.orientation = cfg.pipeline_setup["desired_orientation"] reorient_fs_brainmask.inputs.outputtype = "NIFTI_GZ" wf.connect( @@ -1255,7 +1255,7 @@ def freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): mem_gb=0, mem_x=(0.0115, "in_file", "t"), ) - reorient_fs_T1.inputs.orientation = "RPI" + reorient_fs_T1.inputs.orientation = cfg.pipeline_setup["desired_orientation"] reorient_fs_T1.inputs.outputtype = "NIFTI_GZ" wf.connect(convert_fs_T1_to_nifti, "out_file", reorient_fs_T1, "in_file") @@ -1454,10 +1454,21 @@ def anatomical_init(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data("T1w") wf.connect(node, out, anat_deoblique, "in_file") + anat_reorient = pe.Node( + interface=afni.Resample(), + name=f"anat_reorient_{pipe_num}", + mem_gb=0, + mem_x=(0.0115, "in_file", "t"), + ) + anat_reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] + anat_reorient.inputs.outputtype = "NIFTI_GZ" + + wf.connect(anat_deoblique, "out_file", anat_reorient, "in_file") + outputs = { - "desc-preproc_T1w": (anat_deoblique, "out_file"), - "desc-reorient_T1w": (anat_deoblique, "out_file"), - "desc-head_T1w": (anat_deoblique, "out_file"), + "desc-preproc_T1w": (anat_reorient, "out_file"), + "desc-reorient_T1w": (anat_reorient, "out_file"), + "desc-head_T1w": (anat_reorient, "out_file"), } return (wf, outputs) @@ -2251,10 +2262,21 @@ def anatomical_init_T2(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data("T2w") wf.connect(node, out, T2_deoblique, "in_file") + T2_reorient = pe.Node( + interface=afni.Resample(), + name=f"T2_reorient_{pipe_num}", + mem_gb=0, + mem_x=(0.0115, "in_file", "t"), + ) + T2_reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] + T2_reorient.inputs.outputtype = "NIFTI_GZ" + + wf.connect(T2_deoblique, "out_file", T2_reorient, "in_file") + outputs = { - "desc-preproc_T2w": (T2_deoblique, "out_file"), - "desc-reorient_T2w": (T2_deoblique, "out_file"), - "desc-head_T2w": (T2_deoblique, "out_file"), + "desc-preproc_T2w": (T2_reorient, "out_file"), + "desc-reorient_T2w": (T2_reorient, "out_file"), + "desc-head_T2w": (T2_reorient, "out_file"), } return (wf, outputs) diff --git a/CPAC/func_preproc/func_preproc.py b/CPAC/func_preproc/func_preproc.py index 2007591c84..672bd2c985 100644 --- a/CPAC/func_preproc/func_preproc.py +++ b/CPAC/func_preproc/func_preproc.py @@ -521,9 +521,21 @@ def func_reorient(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data("bold") wf.connect(node, out, func_deoblique, "in_file") + func_reorient = pe.Node( + interface=afni_utils.Resample(), + name=f"func_reorient_{pipe_num}", + mem_gb=0, + mem_x=(0.0115, "in_file", "t"), + ) + + func_reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] + func_reorient.inputs.outputtype = "NIFTI_GZ" + + wf.connect(func_deoblique, "out_file", func_reorient, "in_file") + outputs = { - "desc-preproc_bold": (func_deoblique, "out_file"), - "desc-reorient_bold": (func_deoblique, "out_file"), + "desc-preproc_bold": (func_reorient, "out_file"), + "desc-reorient_bold": (func_reorient, "out_file"), } return (wf, outputs) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index b1c05190a5..187888284b 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1932,17 +1932,7 @@ def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id dl_dir=cfg.pipeline_setup["working_directory"]["path"], img_type="anat", ) - reorient = pe.Node( - interface=afni.Resample(), - name=f"reorient_T1w_{part_id}_{ses_id}", - ) - - reorient.inputs.orientation = desired_orientation - reorient.inputs.outputtype = "NIFTI_GZ" - - wf.connect(anat_flow, "outputspec.anat", reorient, "in_file") - - rpool.set_data("T1w", reorient, "out_file", {}, "", "anat_ingress") + rpool.set_data("T1w", anat_flow, "outputspec.anat", {}, "", "anat_ingress") if "T2w" in data_paths["anat"]: anat_flow_T2 = create_anat_datasource(f"anat_T2w_gather_{part_id}_{ses_id}") @@ -1953,17 +1943,7 @@ def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id dl_dir=cfg.pipeline_setup["working_directory"]["path"], img_type="anat", ) - reorient = pe.Node( - interface=afni.Resample(), - name=f"reorient_T1w_{part_id}_{ses_id}", - ) - - reorient.inputs.orientation = desired_orientation - reorient.inputs.outputtype = "NIFTI_GZ" - - wf.connect(anat_flow_T2, "outputspec.anat", reorient, "in_file") - - rpool.set_data("T2w", reorient, "out_file", {}, "", "anat_ingress") + rpool.set_data("T2w", anat_flow_T2, "outputspec.anat", {}, "", "anat_ingress") if cfg.surface_analysis["freesurfer"]["ingress_reconall"]: rpool = ingress_freesurfer( @@ -2010,28 +1990,13 @@ def ingress_freesurfer(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id): creds_path=data_paths["creds_path"], dl_dir=cfg.pipeline_setup["working_directory"]["path"], ) - node = fs_ingress - out = "outputspec.data" - node_name = "freesurfer_config_ingress" - - if fs_path.endswith(".nii.gz" or ".nii"): - reorient = pe.Node( - interface=afni.Resample(), - name=f"reorient_fs_{part_id}_{ses_id}", - ) - reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] - reorient.inputs.outputtype = "NIFTI_GZ" - wf.connect(fs_ingress, "outputspec.data", reorient, "in_file") - node = reorient - out = "out_file" - node_name = "reorient_fs" rpool.set_data( "freesurfer-subject-dir", - node, - out, + fs_ingress, + "outputspec.data", {}, "", - node_name, + "freesurfer_config_ingress", ) recon_outs = { @@ -2094,15 +2059,8 @@ def ingress_raw_func_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id func_wf.get_node("inputnode").iterables = ("scan", list(func_paths_dct.keys())) rpool.set_data("subject", func_wf, "outputspec.subject", {}, "", "func_ingress") - reorient = pe.Node( - interface=afni.Resample(), - name=f"reorient_func_{part_id}_{ses_id}", - ) - reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] - reorient.inputs.outputtype = "NIFTI_GZ" - wf.connect(func_wf, "outputspec.rest", reorient, "in_file") - rpool.set_data("bold", reorient, "out_file", {}, "", "func_ingress") - # rpool.set_data("bold", func_wf, "outputspec.rest", {}, "", "func_ingress") + + rpool.set_data("bold", func_wf, "outputspec.rest", {}, "", "func_ingress") rpool.set_data("scan", func_wf, "outputspec.scan", {}, "", "func_ingress") From f3f3f98405f35c3b54b1d72b703dee5aece5d234 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:44:29 +0000 Subject: [PATCH 26/37] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- CPAC/longitudinal_pipeline/longitudinal_workflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/longitudinal_pipeline/longitudinal_workflow.py b/CPAC/longitudinal_pipeline/longitudinal_workflow.py index 9134769d6c..5c989675c1 100644 --- a/CPAC/longitudinal_pipeline/longitudinal_workflow.py +++ b/CPAC/longitudinal_pipeline/longitudinal_workflow.py @@ -1204,7 +1204,7 @@ def func_longitudinal_template_wf(subject_id, strat_list, config): resampled_template.inputs.template = template resampled_template.inputs.template_name = template_name resampled_template.inputs.tag = tag - resampled_template.inputs.orientation = config['desired_orientation'] + resampled_template.inputs.orientation = config["desired_orientation"] strat_init.update_resource_pool( {template_name: (resampled_template, "resampled_template")} From 1a43750f59c3cadc1a91be37b0e19531663b5f56 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Tue, 1 Oct 2024 14:48:39 -0400 Subject: [PATCH 27/37] empty --- CPAC/pipeline/engine.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 187888284b..bf31c957f7 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1908,7 +1908,6 @@ def wrap_block(node_blocks, interface, wf, cfg, strat_pool, pipe_num, opt): def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id): - desired_orientation = cfg.pipeline_setup["desired_orientation"] if "anat" not in data_paths: WFLOGGER.warning("No anatomical data present.") return rpool @@ -2059,11 +2058,8 @@ def ingress_raw_func_data(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id func_wf.get_node("inputnode").iterables = ("scan", list(func_paths_dct.keys())) rpool.set_data("subject", func_wf, "outputspec.subject", {}, "", "func_ingress") - rpool.set_data("bold", func_wf, "outputspec.rest", {}, "", "func_ingress") - rpool.set_data("scan", func_wf, "outputspec.scan", {}, "", "func_ingress") - rpool.set_data( "scan-params", func_wf, "outputspec.scan_params", {}, "", "scan_params_ingress" ) From 939c7a55ce70b26770b2b45e387a3cd6ce18259a Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Wed, 2 Oct 2024 13:08:39 -0400 Subject: [PATCH 28/37] updated tests --- CPAC/pipeline/test/test_engine.py | 2 +- CPAC/resources/tests/test_templates.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CPAC/pipeline/test/test_engine.py b/CPAC/pipeline/test/test_engine.py index c228fc3640..cf85f50dbe 100644 --- a/CPAC/pipeline/test/test_engine.py +++ b/CPAC/pipeline/test/test_engine.py @@ -90,7 +90,7 @@ def test_ingress_pipeconfig_data(pipe_config, bids_dir, test_dir): rpool = ResourcePool(name=unique_id, cfg=cfg) - rpool = ingress_pipeconfig_paths(cfg, rpool, sub_data_dct, unique_id) + wf, rpool = ingress_pipeconfig_paths(wf, cfg, rpool, sub_data_dct, unique_id) rpool.gather_pipes(wf, cfg, all=True) diff --git a/CPAC/resources/tests/test_templates.py b/CPAC/resources/tests/test_templates.py index 13a4f72745..0d041930cb 100644 --- a/CPAC/resources/tests/test_templates.py +++ b/CPAC/resources/tests/test_templates.py @@ -32,8 +32,8 @@ def test_packaged_path_exists(pipeline): Check that all local templates are included in image at at least one resolution. """ - rpool = ingress_pipeconfig_paths( - Preconfiguration(pipeline), ResourcePool(), "pytest" + wf, rpool = ingress_pipeconfig_paths( + wf, Preconfiguration(pipeline), ResourcePool(), "pytest" ) for resource in rpool.rpool.values(): node = next(iter(resource.values())).get("data")[0] From 9df743cf3d1fa8f01a71d0f1f60aa96febb3a976 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Wed, 2 Oct 2024 14:19:02 -0400 Subject: [PATCH 29/37] updated the changelog --- CHANGELOG.md | 3 +++ CPAC/resources/tests/test_templates.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb0f5a96b7..0fa0347214 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,10 +20,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `pyproject.toml` file with `[build-system]` defined. - [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/FCP-INDI/C-PAC/main.svg)](https://results.pre-commit.ci/latest/github/FCP-INDI/C-PAC/main) badge to [`README`](./README.md). +- `desired_orientation` key in the blank config under `pipeline_setup`. +- Workflow (`wf`) parameter in input and output of `ingress_pipeconfig_paths` function, where a node to reorient templates is added to the `wf` ### Changed - Moved `pygraphviz` from requirements to `graphviz` optional dependencies group. +- Fixed-orientation-parameter `RPI` in resolve_resolution `freesurfer_fs_brain_connector`, `anatomical_init_T1`, `anatomical_init_T2`, `func_reorient` to take in whatever is set in the config `desired_orientation` field. ### Fixed diff --git a/CPAC/resources/tests/test_templates.py b/CPAC/resources/tests/test_templates.py index 0d041930cb..341bde6c27 100644 --- a/CPAC/resources/tests/test_templates.py +++ b/CPAC/resources/tests/test_templates.py @@ -24,6 +24,7 @@ from CPAC.pipeline.engine import ingress_pipeconfig_paths, ResourcePool from CPAC.utils.configuration import Preconfiguration from CPAC.utils.datasource import get_highest_local_res +import nipype.pipeline.engine as pe @pytest.mark.parametrize("pipeline", ALL_PIPELINE_CONFIGS) @@ -32,6 +33,7 @@ def test_packaged_path_exists(pipeline): Check that all local templates are included in image at at least one resolution. """ + wf = pe.Workflow(name="test") wf, rpool = ingress_pipeconfig_paths( wf, Preconfiguration(pipeline), ResourcePool(), "pytest" ) From 079b1f06a35848a79f26b3ee82e84d2848a81932 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Wed, 2 Oct 2024 15:48:57 -0400 Subject: [PATCH 30/37] replaced RPI to take in config value in few more places --- CPAC/anat_preproc/lesion_preproc.py | 3 ++- CPAC/func_preproc/func_preproc.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CPAC/anat_preproc/lesion_preproc.py b/CPAC/anat_preproc/lesion_preproc.py index 07871ae32d..7a31bc3e2b 100644 --- a/CPAC/anat_preproc/lesion_preproc.py +++ b/CPAC/anat_preproc/lesion_preproc.py @@ -19,6 +19,7 @@ import nipype.interfaces.utility as util from CPAC.pipeline import nipype_pipeline_engine as pe +from CPAC.utils.configuration import Configuration as cfg from CPAC.utils.interfaces import Function @@ -133,7 +134,7 @@ def create_lesion_preproc(wf_name="lesion_preproc"): mem_x=(0.0115, "in_file", "t"), ) - lesion_reorient.inputs.orientation = "RPI" + lesion_reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] lesion_reorient.inputs.outputtype = "NIFTI_GZ" preproc.connect(lesion_deoblique, "out_file", lesion_reorient, "in_file") diff --git a/CPAC/func_preproc/func_preproc.py b/CPAC/func_preproc/func_preproc.py index 672bd2c985..3bac53cc87 100644 --- a/CPAC/func_preproc/func_preproc.py +++ b/CPAC/func_preproc/func_preproc.py @@ -1290,7 +1290,7 @@ def bold_mask_anatomical_refined(wf, cfg, strat_pool, pipe_num, opt=None): mem_x=(0.0115, "in_file", "t"), ) - func_reorient.inputs.orientation = "RPI" + func_reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] func_reorient.inputs.outputtype = "NIFTI_GZ" wf.connect(func_deoblique, "out_file", func_reorient, "in_file") From 35ed398e167f0800d21928e9b14abb67f0a37f0d Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Wed, 2 Oct 2024 20:18:07 -0400 Subject: [PATCH 31/37] adding cfg as parameter in lesion_preproc --- CHANGELOG.md | 2 +- CPAC/anat_preproc/lesion_preproc.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fa0347214..2850e0460c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Moved `pygraphviz` from requirements to `graphviz` optional dependencies group. -- Fixed-orientation-parameter `RPI` in resolve_resolution `freesurfer_fs_brain_connector`, `anatomical_init_T1`, `anatomical_init_T2`, `func_reorient` to take in whatever is set in the config `desired_orientation` field. +- Fixed-orientation-parameter `RPI` in resolve_resolution `freesurfer_fs_brain_connector`, `anatomical_init_T1`, `lesion_preproc`, `anatomical_init_T2`, `func_reorient` to take in whatever is set in the config `desired_orientation` field. ### Fixed diff --git a/CPAC/anat_preproc/lesion_preproc.py b/CPAC/anat_preproc/lesion_preproc.py index 7a31bc3e2b..97a6828e59 100644 --- a/CPAC/anat_preproc/lesion_preproc.py +++ b/CPAC/anat_preproc/lesion_preproc.py @@ -19,7 +19,6 @@ import nipype.interfaces.utility as util from CPAC.pipeline import nipype_pipeline_engine as pe -from CPAC.utils.configuration import Configuration as cfg from CPAC.utils.interfaces import Function @@ -59,7 +58,7 @@ def inverse_lesion(lesion_path): return lesion_out -def create_lesion_preproc(wf_name="lesion_preproc"): +def create_lesion_preproc(wf_name="lesion_preproc", cfg="RPI"): """Process lesions masks. Lesion mask file is deobliqued and reoriented in the same way as the T1 in From b36808361ac082950368237b2bfe38e1e1a6022e Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Wed, 2 Oct 2024 20:22:21 -0400 Subject: [PATCH 32/37] sending only orientation not all cfg --- CPAC/anat_preproc/lesion_preproc.py | 4 ++-- CPAC/registration/registration.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CPAC/anat_preproc/lesion_preproc.py b/CPAC/anat_preproc/lesion_preproc.py index 97a6828e59..c10f057954 100644 --- a/CPAC/anat_preproc/lesion_preproc.py +++ b/CPAC/anat_preproc/lesion_preproc.py @@ -58,7 +58,7 @@ def inverse_lesion(lesion_path): return lesion_out -def create_lesion_preproc(wf_name="lesion_preproc", cfg="RPI"): +def create_lesion_preproc(wf_name="lesion_preproc", orientation="RPI"): """Process lesions masks. Lesion mask file is deobliqued and reoriented in the same way as the T1 in @@ -133,7 +133,7 @@ def create_lesion_preproc(wf_name="lesion_preproc", cfg="RPI"): mem_x=(0.0115, "in_file", "t"), ) - lesion_reorient.inputs.orientation = cfg.pipeline_setup["desired_orientation"] + lesion_reorient.inputs.orientation = orientation lesion_reorient.inputs.outputtype = "NIFTI_GZ" preproc.connect(lesion_deoblique, "out_file", lesion_reorient, "in_file") diff --git a/CPAC/registration/registration.py b/CPAC/registration/registration.py index da63e694e4..2214585d9c 100644 --- a/CPAC/registration/registration.py +++ b/CPAC/registration/registration.py @@ -1736,7 +1736,7 @@ def ANTs_registration_connector( "ANTs" ]["use_lesion_mask"]: # Create lesion preproc node to apply afni Refit and Resample - lesion_preproc = create_lesion_preproc(wf_name=f"lesion_preproc{symm}") + lesion_preproc = create_lesion_preproc(wf_name=f"lesion_preproc{symm}", cfg.pipeline_setup["desired_orientation"]) wf.connect(inputNode, "lesion_mask", lesion_preproc, "inputspec.lesion") wf.connect( lesion_preproc, From 71dd070a699ceae56bf85d72b5ef45ddb33734ab Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Wed, 2 Oct 2024 20:32:00 -0400 Subject: [PATCH 33/37] fixed positions of args in lesion_preproc and added default RPI --- CPAC/anat_preproc/lesion_preproc.py | 6 ++++-- CPAC/registration/registration.py | 2 +- CPAC/registration/tests/test_registration.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CPAC/anat_preproc/lesion_preproc.py b/CPAC/anat_preproc/lesion_preproc.py index c10f057954..21628c97f0 100644 --- a/CPAC/anat_preproc/lesion_preproc.py +++ b/CPAC/anat_preproc/lesion_preproc.py @@ -58,7 +58,7 @@ def inverse_lesion(lesion_path): return lesion_out -def create_lesion_preproc(wf_name="lesion_preproc", orientation="RPI"): +def create_lesion_preproc(cfg=None, wf_name="lesion_preproc"): """Process lesions masks. Lesion mask file is deobliqued and reoriented in the same way as the T1 in @@ -133,7 +133,9 @@ def create_lesion_preproc(wf_name="lesion_preproc", orientation="RPI"): mem_x=(0.0115, "in_file", "t"), ) - lesion_reorient.inputs.orientation = orientation + lesion_reorient.inputs.orientation = ( + cfg.pipeline_setup["desired_orientation"] if cfg else "RPI" + ) lesion_reorient.inputs.outputtype = "NIFTI_GZ" preproc.connect(lesion_deoblique, "out_file", lesion_reorient, "in_file") diff --git a/CPAC/registration/registration.py b/CPAC/registration/registration.py index 2214585d9c..1c6b6fa71a 100644 --- a/CPAC/registration/registration.py +++ b/CPAC/registration/registration.py @@ -1736,7 +1736,7 @@ def ANTs_registration_connector( "ANTs" ]["use_lesion_mask"]: # Create lesion preproc node to apply afni Refit and Resample - lesion_preproc = create_lesion_preproc(wf_name=f"lesion_preproc{symm}", cfg.pipeline_setup["desired_orientation"]) + lesion_preproc = create_lesion_preproc(cfg, wf_name=f"lesion_preproc{symm}") wf.connect(inputNode, "lesion_mask", lesion_preproc, "inputspec.lesion") wf.connect( lesion_preproc, diff --git a/CPAC/registration/tests/test_registration.py b/CPAC/registration/tests/test_registration.py index 58741da445..d8e8228497 100755 --- a/CPAC/registration/tests/test_registration.py +++ b/CPAC/registration/tests/test_registration.py @@ -130,7 +130,7 @@ def test_registration_lesion(): anat_preproc.inputs.inputspec.anat = anat_file - lesion_preproc = create_lesion_preproc(wf_name="lesion_preproc") + lesion_preproc = create_lesion_preproc(cfg, wf_name="lesion_preproc") lesion_preproc.inputs.inputspec.lesion = lesion_file From 3f1e1093d40726433d51cc7ca56a013fae5059f0 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Wed, 9 Oct 2024 13:34:17 -0400 Subject: [PATCH 34/37] Update CHANGELOG.md Co-authored-by: Jon Clucas --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2850e0460c..01716d45d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `pyproject.toml` file with `[build-system]` defined. - [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/FCP-INDI/C-PAC/main.svg)](https://results.pre-commit.ci/latest/github/FCP-INDI/C-PAC/main) badge to [`README`](./README.md). - `desired_orientation` key in the blank config under `pipeline_setup`. -- Workflow (`wf`) parameter in input and output of `ingress_pipeconfig_paths` function, where a node to reorient templates is added to the `wf` +- Required positional parameter "wf" in input and output of `ingress_pipeconfig_paths` function, where a node to reorient templates is added to the `wf`. +- Required positional parameter "orientation" to `resolve_resolution`. +- Optional positional argument "cfg" to `create_lesion_preproc`. ### Changed From d24fae671606d7a734e803822f87a107581473ef Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Wed, 9 Oct 2024 13:34:53 -0400 Subject: [PATCH 35/37] Update CHANGELOG.md Co-authored-by: Jon Clucas --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01716d45d9..998749381e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `pyproject.toml` file with `[build-system]` defined. - [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/FCP-INDI/C-PAC/main.svg)](https://results.pre-commit.ci/latest/github/FCP-INDI/C-PAC/main) badge to [`README`](./README.md). -- `desired_orientation` key in the blank config under `pipeline_setup`. +- `desired_orientation` key in participant-level pipeline config under `pipeline_setup`. - Required positional parameter "wf" in input and output of `ingress_pipeconfig_paths` function, where a node to reorient templates is added to the `wf`. - Required positional parameter "orientation" to `resolve_resolution`. - Optional positional argument "cfg" to `create_lesion_preproc`. From 408d87120218fb1ccd054949b1b613f4177bf385 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:06:58 -0400 Subject: [PATCH 36/37] Update CHANGELOG.md Co-authored-by: Jon Cluce --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 998749381e..359a62fb37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Moved `pygraphviz` from requirements to `graphviz` optional dependencies group. -- Fixed-orientation-parameter `RPI` in resolve_resolution `freesurfer_fs_brain_connector`, `anatomical_init_T1`, `lesion_preproc`, `anatomical_init_T2`, `func_reorient` to take in whatever is set in the config `desired_orientation` field. +- Made orientation configurable (was hard-coded as "RPI"). ### Fixed From 2895e8c4cda5f861c1719ca25e325691844e7655 Mon Sep 17 00:00:00 2001 From: "birajstha:construction_worker::penguin" Date: Thu, 10 Oct 2024 11:28:17 -0400 Subject: [PATCH 37/37] fixing pre-commit suggestions --- CPAC/resources/tests/test_templates.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CPAC/resources/tests/test_templates.py b/CPAC/resources/tests/test_templates.py index 341bde6c27..048cbe9b1c 100644 --- a/CPAC/resources/tests/test_templates.py +++ b/CPAC/resources/tests/test_templates.py @@ -19,19 +19,18 @@ import os import pytest +import nipype.pipeline.engine as pe from CPAC.pipeline import ALL_PIPELINE_CONFIGS from CPAC.pipeline.engine import ingress_pipeconfig_paths, ResourcePool from CPAC.utils.configuration import Preconfiguration from CPAC.utils.datasource import get_highest_local_res -import nipype.pipeline.engine as pe @pytest.mark.parametrize("pipeline", ALL_PIPELINE_CONFIGS) def test_packaged_path_exists(pipeline): """ - Check that all local templates are included in image at at - least one resolution. + Check that all local templates are included in image at atleast one resolution. """ wf = pe.Workflow(name="test") wf, rpool = ingress_pipeconfig_paths(