From f8c0abaff81ce43849cbac257b9db9c021280e91 Mon Sep 17 00:00:00 2001 From: Gensollen Date: Wed, 7 Feb 2024 13:50:21 +0100 Subject: [PATCH] [ENH] Simplify imports for DWI pipelines (#1072) --- clinica/pipelines/dwi_connectome/__init__.py | 2 +- .../{dwi_connectome_cli.py => cli.py} | 2 +- ...dwi_connectome_pipeline.py => pipeline.py} | 23 ++++++++---- .../{dwi_connectome_utils.py => utils.py} | 0 clinica/pipelines/dwi_dti/__init__.py | 2 +- .../dwi_dti/{dwi_dti_cli.py => cli.py} | 2 +- .../{dwi_dti_pipeline.py => pipeline.py} | 5 +-- .../dwi_dti/{dwi_dti_utils.py => utils.py} | 5 +-- .../dwi_preprocessing_using_fmap/__init__.py | 2 +- ...ing_using_phasediff_fmap_cli.py => cli.py} | 4 +- ...phasediff_fmap_pipeline.py => pipeline.py} | 14 ++----- ...using_phasediff_fmap_utils.py => utils.py} | 37 ++++++++----------- ...asediff_fmap_workflows.py => workflows.py} | 16 +++----- .../dwi_preprocessing_using_t1/__init__.py | 2 +- ...i_preprocessing_using_t1_cli.py => cli.py} | 2 +- ...ssing_using_t1_pipeline.py => pipeline.py} | 9 ++--- ...eprocessing_using_t1_utils.py => utils.py} | 22 +++++------ ...ing_using_t1_workflows.py => workflows.py} | 4 +- .../test_instantiate_all_pipelines.py | 13 +++---- .../dwi/preprocessing/test_phase_diff.py | 8 ++-- .../pipelines/dwi/preprocessing/test_t1.py | 18 +++------ .../pipelines/dwi/test_pipelines.py | 4 +- .../test_dwi_connectome_utils.py | 30 +++++---------- .../test_dwi_preprocessing_using_t1_utils.py | 24 ++++-------- 24 files changed, 101 insertions(+), 149 deletions(-) rename clinica/pipelines/dwi_connectome/{dwi_connectome_cli.py => cli.py} (96%) rename clinica/pipelines/dwi_connectome/{dwi_connectome_pipeline.py => pipeline.py} (97%) rename clinica/pipelines/dwi_connectome/{dwi_connectome_utils.py => utils.py} (100%) rename clinica/pipelines/dwi_dti/{dwi_dti_cli.py => cli.py} (97%) rename clinica/pipelines/dwi_dti/{dwi_dti_pipeline.py => pipeline.py} (99%) rename clinica/pipelines/dwi_dti/{dwi_dti_utils.py => utils.py} (97%) rename clinica/pipelines/dwi_preprocessing_using_fmap/{dwi_preprocessing_using_phasediff_fmap_cli.py => cli.py} (94%) rename clinica/pipelines/dwi_preprocessing_using_fmap/{dwi_preprocessing_using_phasediff_fmap_pipeline.py => pipeline.py} (97%) rename clinica/pipelines/dwi_preprocessing_using_fmap/{dwi_preprocessing_using_phasediff_fmap_utils.py => utils.py} (90%) rename clinica/pipelines/dwi_preprocessing_using_fmap/{dwi_preprocessing_using_phasediff_fmap_workflows.py => workflows.py} (97%) rename clinica/pipelines/dwi_preprocessing_using_t1/{dwi_preprocessing_using_t1_cli.py => cli.py} (96%) rename clinica/pipelines/dwi_preprocessing_using_t1/{dwi_preprocessing_using_t1_pipeline.py => pipeline.py} (98%) rename clinica/pipelines/dwi_preprocessing_using_t1/{dwi_preprocessing_using_t1_utils.py => utils.py} (95%) rename clinica/pipelines/dwi_preprocessing_using_t1/{dwi_preprocessing_using_t1_workflows.py => workflows.py} (99%) diff --git a/clinica/pipelines/dwi_connectome/__init__.py b/clinica/pipelines/dwi_connectome/__init__.py index 6bec22a76..f00831fce 100644 --- a/clinica/pipelines/dwi_connectome/__init__.py +++ b/clinica/pipelines/dwi_connectome/__init__.py @@ -1 +1 @@ -from . import dwi_connectome_cli +from . import cli diff --git a/clinica/pipelines/dwi_connectome/dwi_connectome_cli.py b/clinica/pipelines/dwi_connectome/cli.py similarity index 96% rename from clinica/pipelines/dwi_connectome/dwi_connectome_cli.py rename to clinica/pipelines/dwi_connectome/cli.py index 85204bcf6..884641c67 100644 --- a/clinica/pipelines/dwi_connectome/dwi_connectome_cli.py +++ b/clinica/pipelines/dwi_connectome/cli.py @@ -41,7 +41,7 @@ def cli( from clinica.utils.ux import print_end_pipeline - from .dwi_connectome_pipeline import DwiConnectome + from .pipeline import DwiConnectome parameters = {"n_tracks": n_tracks} diff --git a/clinica/pipelines/dwi_connectome/dwi_connectome_pipeline.py b/clinica/pipelines/dwi_connectome/pipeline.py similarity index 97% rename from clinica/pipelines/dwi_connectome/dwi_connectome_pipeline.py rename to clinica/pipelines/dwi_connectome/pipeline.py index cd9108470..9e35de1b4 100644 --- a/clinica/pipelines/dwi_connectome/dwi_connectome_pipeline.py +++ b/clinica/pipelines/dwi_connectome/pipeline.py @@ -192,7 +192,7 @@ def _build_output_node(self): import nipype.interfaces.utility as nutil import nipype.pipeline.engine as npe - import clinica.pipelines.dwi_connectome.dwi_connectome_utils as utils + from .utils import get_containers join_node = npe.JoinNode( name="JoinOutputs", @@ -212,7 +212,7 @@ def _build_output_node(self): ), ) write_node.inputs.base_directory = str(self.caps_directory) - write_node.inputs.container = utils.get_containers(self.subjects, self.sessions) + write_node.inputs.container = get_containers(self.subjects, self.sessions) write_node.inputs.substitutions = [("trait_added", "")] write_node.inputs.parameterization = False @@ -271,12 +271,19 @@ def _build_core_nodes(self): Tractography, ) - import clinica.pipelines.dwi_connectome.dwi_connectome_utils as utils from clinica.utils.exceptions import ClinicaCAPSError from clinica.utils.mri_registration import ( convert_flirt_transformation_to_mrtrix_transformation, ) + from .utils import ( + get_caps_filenames, + get_conversion_luts, + get_luts, + print_begin_pipeline, + print_end_pipeline, + ) + # Nodes # ===== # B0 Extraction (only if space=b0) @@ -328,8 +335,8 @@ def _build_core_nodes(self): iterfield=["in_file", "in_config", "in_lut", "out_file"], interface=mrtrix3.LabelConvert(), ) - label_convert_node.inputs.in_config = utils.get_conversion_luts() - label_convert_node.inputs.in_lut = utils.get_luts() + label_convert_node.inputs.in_config = get_conversion_luts() + label_convert_node.inputs.in_lut = get_luts() # FSL flirt matrix to MRtrix matrix Conversion (only if space=b0) # -------------------------------------------- @@ -391,7 +398,7 @@ def _build_core_nodes(self): print_begin_message = npe.MapNode( interface=niu.Function( input_names=["in_bids_or_caps_file"], - function=utils.print_begin_pipeline, + function=print_begin_pipeline, ), iterfield="in_bids_or_caps_file", name="WriteBeginMessage", @@ -402,7 +409,7 @@ def _build_core_nodes(self): print_end_message = npe.MapNode( interface=niu.Function( input_names=["in_bids_or_caps_file", "final_file"], - function=utils.print_end_pipeline, + function=print_end_pipeline, ), iterfield=["in_bids_or_caps_file"], name="WriteEndMessage", @@ -415,7 +422,7 @@ def _build_core_nodes(self): interface=niu.Function( input_names="dwi_file", output_names=self.get_output_fields(), - function=utils.get_caps_filenames, + function=get_caps_filenames, ), ) self.connect( diff --git a/clinica/pipelines/dwi_connectome/dwi_connectome_utils.py b/clinica/pipelines/dwi_connectome/utils.py similarity index 100% rename from clinica/pipelines/dwi_connectome/dwi_connectome_utils.py rename to clinica/pipelines/dwi_connectome/utils.py diff --git a/clinica/pipelines/dwi_dti/__init__.py b/clinica/pipelines/dwi_dti/__init__.py index 84b29cd50..f00831fce 100644 --- a/clinica/pipelines/dwi_dti/__init__.py +++ b/clinica/pipelines/dwi_dti/__init__.py @@ -1 +1 @@ -from . import dwi_dti_cli +from . import cli diff --git a/clinica/pipelines/dwi_dti/dwi_dti_cli.py b/clinica/pipelines/dwi_dti/cli.py similarity index 97% rename from clinica/pipelines/dwi_dti/dwi_dti_cli.py rename to clinica/pipelines/dwi_dti/cli.py index 3805c3bc6..7d4f8cde4 100644 --- a/clinica/pipelines/dwi_dti/dwi_dti_cli.py +++ b/clinica/pipelines/dwi_dti/cli.py @@ -33,7 +33,7 @@ def cli( from clinica.utils.ux import print_end_pipeline - from .dwi_dti_pipeline import DwiDti + from .pipeline import DwiDti pipeline = DwiDti( caps_directory=caps_directory, diff --git a/clinica/pipelines/dwi_dti/dwi_dti_pipeline.py b/clinica/pipelines/dwi_dti/pipeline.py similarity index 99% rename from clinica/pipelines/dwi_dti/dwi_dti_pipeline.py rename to clinica/pipelines/dwi_dti/pipeline.py index be659b8cb..70ba5be0c 100644 --- a/clinica/pipelines/dwi_dti/dwi_dti_pipeline.py +++ b/clinica/pipelines/dwi_dti/pipeline.py @@ -129,7 +129,7 @@ def _build_output_node(self): from clinica.utils.nipype import container_from_filename, fix_join - from .dwi_dti_utils import rename_into_caps + from .utils import rename_into_caps # Find container path from filename container_path = npe.Node( @@ -241,7 +241,6 @@ def _build_output_node(self): def _build_core_nodes(self): """Build and connect the core nodes of the pipeline.""" - import os from pathlib import Path import nipype.interfaces.fsl as fsl @@ -255,7 +254,7 @@ def _build_core_nodes(self): from clinica.utils.check_dependency import check_environment_variable from clinica.utils.dwi import extract_bids_identifier_from_filename - from .dwi_dti_utils import ( + from .utils import ( get_ants_transforms, get_caps_filenames, print_begin_pipeline, diff --git a/clinica/pipelines/dwi_dti/dwi_dti_utils.py b/clinica/pipelines/dwi_dti/utils.py similarity index 97% rename from clinica/pipelines/dwi_dti/dwi_dti_utils.py rename to clinica/pipelines/dwi_dti/utils.py index 833fe550a..87b014278 100644 --- a/clinica/pipelines/dwi_dti/dwi_dti_utils.py +++ b/clinica/pipelines/dwi_dti/utils.py @@ -10,7 +10,7 @@ def statistics_on_atlases(in_registered_map, name_map, prefix_file=None): Returns: List of paths leading to the statistics TSV files. """ - import os + from pathlib import Path from nipype.utils.filemanip import split_filename @@ -41,8 +41,7 @@ def statistics_on_atlases(in_registered_map, name_map, prefix_file=None): f"_res-{atlas.get_spatial_resolution()}_map-{name_map}_statistics.tsv" ) - out_atlas_statistics = os.path.abspath(os.path.join(os.getcwd(), filename)) - + out_atlas_statistics = str((Path.cwd() / filename).resolve()) statistics_on_atlas(in_registered_map, atlas, out_atlas_statistics) atlas_statistics_list.append(out_atlas_statistics) diff --git a/clinica/pipelines/dwi_preprocessing_using_fmap/__init__.py b/clinica/pipelines/dwi_preprocessing_using_fmap/__init__.py index 45168e337..f00831fce 100644 --- a/clinica/pipelines/dwi_preprocessing_using_fmap/__init__.py +++ b/clinica/pipelines/dwi_preprocessing_using_fmap/__init__.py @@ -1 +1 @@ -from . import dwi_preprocessing_using_phasediff_fmap_cli +from . import cli diff --git a/clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_cli.py b/clinica/pipelines/dwi_preprocessing_using_fmap/cli.py similarity index 94% rename from clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_cli.py rename to clinica/pipelines/dwi_preprocessing_using_fmap/cli.py index 6cdd3c602..80bc65ad0 100644 --- a/clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_cli.py +++ b/clinica/pipelines/dwi_preprocessing_using_fmap/cli.py @@ -41,9 +41,7 @@ def cli( from clinica.utils.ux import print_end_pipeline - from .dwi_preprocessing_using_phasediff_fmap_pipeline import ( - DwiPreprocessingUsingPhaseDiffFMap, - ) + from .pipeline import DwiPreprocessingUsingPhaseDiffFMap parameters = { "low_bval": low_bval, diff --git a/clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_pipeline.py b/clinica/pipelines/dwi_preprocessing_using_fmap/pipeline.py similarity index 97% rename from clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_pipeline.py rename to clinica/pipelines/dwi_preprocessing_using_fmap/pipeline.py index 1e9fd9ca4..890f042a8 100644 --- a/clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_pipeline.py +++ b/clinica/pipelines/dwi_preprocessing_using_fmap/pipeline.py @@ -175,7 +175,7 @@ def _build_output_node(self): from clinica.utils.nipype import container_from_filename, fix_join - from .dwi_preprocessing_using_phasediff_fmap_utils import rename_into_caps + from .utils import rename_into_caps container_path = npe.Node( nutil.Function( @@ -261,19 +261,13 @@ def _build_core_nodes(self): import nipype.interfaces.utility as nutil import nipype.pipeline.engine as npe - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_workflows import ( + from clinica.pipelines.dwi_preprocessing_using_t1.workflows import ( eddy_fsl_pipeline, ) from clinica.utils.dwi import compute_average_b0 - from .dwi_preprocessing_using_phasediff_fmap_utils import ( - init_input_node, - print_end_pipeline, - ) - from .dwi_preprocessing_using_phasediff_fmap_workflows import ( - calibrate_and_register_fmap, - compute_reference_b0, - ) + from .utils import init_input_node, print_end_pipeline + from .workflows import calibrate_and_register_fmap, compute_reference_b0 init_node = npe.Node( interface=nutil.Function( diff --git a/clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_utils.py b/clinica/pipelines/dwi_preprocessing_using_fmap/utils.py similarity index 90% rename from clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_utils.py rename to clinica/pipelines/dwi_preprocessing_using_fmap/utils.py index e7ed76c05..fd9ad6839 100644 --- a/clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_utils.py +++ b/clinica/pipelines/dwi_preprocessing_using_fmap/utils.py @@ -170,41 +170,39 @@ def rads2hz(in_file: str, delta_te: float, out_file: str = None) -> str: Path to output file. """ import math - import os import nibabel as nb import numpy as np - if out_file is None: - fname, fext = os.path.splitext(os.path.basename(in_file)) - if fext == ".gz": - fname, _ = os.path.splitext(fname) - out_file = os.path.abspath(f"./{fname}_radsec.nii.gz") - im = nb.load(in_file) + out_file = out_file or _get_output_file(in_file, "radsec") data = im.get_fdata().astype(np.float32) * (1.0 / (float(delta_te) * 2 * math.pi)) nb.Nifti1Image(data, im.affine, im.header).to_filename(out_file) return out_file +def _get_output_file(input_file: str, suffix: str) -> str: + from pathlib import Path + + input_file = Path(input_file) + filename = input_file.name + if input_file.suffix == ".gz": + filename = Path(filename).name + + return str(Path(f"./{filename}_{suffix}.nii.gz").resolve()) + + def demean_image(in_file: str, in_mask: str = None, out_file: str = None) -> str: """Demean image data inside mask. This function was taken from: https://github.com/niflows/nipype1-workflows/ """ - import os.path as op - import nibabel as nb import numpy as np - if out_file is None: - fname, fext = op.splitext(op.basename(in_file)) - if fext == ".gz": - fname, _ = op.splitext(fname) - out_file = op.abspath("./%s_demean.nii.gz" % fname) - im = nb.load(in_file) + out_file = out_file or _get_output_file(in_file, "demean") data = im.get_fdata().astype(np.float32) mask = np.ones_like(data) @@ -216,6 +214,7 @@ def demean_image(in_file: str, in_mask: str = None, out_file: str = None) -> str mean = np.median(data[mask == 1].reshape(-1)) data[mask == 1] = data[mask == 1] - mean nb.Nifti1Image(data, im.affine, im.header).to_filename(out_file) + return out_file @@ -225,17 +224,11 @@ def siemens2rads(in_file: str, out_file: str = None): This function was taken from: https://github.com/niflows/nipype1-workflows/ """ import math - import os.path as op import nibabel as nb import numpy as np - if out_file is None: - fname, fext = op.splitext(op.basename(in_file)) - if fext == ".gz": - fname, _ = op.splitext(fname) - out_file = op.abspath("./%s_rads.nii.gz" % fname) - + out_file = out_file or _get_output_file(in_file, "rads") in_file = np.atleast_1d(in_file).tolist() im = nb.load(in_file[0]) data = im.get_fdata().astype(np.float32) diff --git a/clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_workflows.py b/clinica/pipelines/dwi_preprocessing_using_fmap/workflows.py similarity index 97% rename from clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_workflows.py rename to clinica/pipelines/dwi_preprocessing_using_fmap/workflows.py index f3f0cd710..598651900 100644 --- a/clinica/pipelines/dwi_preprocessing_using_fmap/dwi_preprocessing_using_phasediff_fmap_workflows.py +++ b/clinica/pipelines/dwi_preprocessing_using_fmap/workflows.py @@ -110,15 +110,11 @@ def prepare_phasediff_fmap( import nipype.interfaces.utility as nutil import nipype.pipeline.engine as npe - from clinica.pipelines.dwi_preprocessing_using_fmap.dwi_preprocessing_using_phasediff_fmap_workflows import ( - cleanup_edge_pipeline, + from clinica.pipelines.dwi_preprocessing_using_fmap.workflows import ( + cleanup_edge_pipeline, # noqa ) - from .dwi_preprocessing_using_phasediff_fmap_utils import ( - demean_image, - rads2hz, - siemens2rads, - ) + from .utils import demean_image, rads2hz, siemens2rads input_node = npe.Node( nutil.IdentityInterface( @@ -271,12 +267,10 @@ def compute_reference_b0( import nipype.interfaces.utility as niu import nipype.pipeline.engine as npe - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_workflows import ( - eddy_fsl_pipeline, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.workflows import eddy_fsl_pipeline from clinica.utils.dwi import compute_average_b0 - from .dwi_preprocessing_using_phasediff_fmap_utils import get_grad_fsl + from .utils import get_grad_fsl inputnode = npe.Node( niu.IdentityInterface( diff --git a/clinica/pipelines/dwi_preprocessing_using_t1/__init__.py b/clinica/pipelines/dwi_preprocessing_using_t1/__init__.py index d65db5ea0..f00831fce 100644 --- a/clinica/pipelines/dwi_preprocessing_using_t1/__init__.py +++ b/clinica/pipelines/dwi_preprocessing_using_t1/__init__.py @@ -1 +1 @@ -from . import dwi_preprocessing_using_t1_cli +from . import cli diff --git a/clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_cli.py b/clinica/pipelines/dwi_preprocessing_using_t1/cli.py similarity index 96% rename from clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_cli.py rename to clinica/pipelines/dwi_preprocessing_using_t1/cli.py index 546a36184..22c652e25 100644 --- a/clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_cli.py +++ b/clinica/pipelines/dwi_preprocessing_using_t1/cli.py @@ -45,7 +45,7 @@ def cli( from clinica.utils.ux import print_end_pipeline - from .dwi_preprocessing_using_t1_pipeline import DwiPreprocessingUsingT1 + from .pipeline import DwiPreprocessingUsingT1 parameters = { "low_bval": low_bval, diff --git a/clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_pipeline.py b/clinica/pipelines/dwi_preprocessing_using_t1/pipeline.py similarity index 98% rename from clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_pipeline.py rename to clinica/pipelines/dwi_preprocessing_using_t1/pipeline.py index b38ab3fd0..6dc36d5f4 100644 --- a/clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_pipeline.py +++ b/clinica/pipelines/dwi_preprocessing_using_t1/pipeline.py @@ -148,7 +148,7 @@ def _build_output_node(self): from clinica.utils.nipype import container_from_filename, fix_join - from .dwi_preprocessing_using_t1_utils import rename_into_caps + from .utils import rename_into_caps container_path = npe.Node( nutil.Function( @@ -210,15 +210,12 @@ def _build_core_nodes(self): from clinica.utils.dwi import compute_average_b0_task - from .dwi_preprocessing_using_t1_utils import ( + from .utils import ( init_input_node, prepare_reference_b0_task, print_end_pipeline, ) - from .dwi_preprocessing_using_t1_workflows import ( - eddy_fsl_pipeline, - epi_pipeline, - ) + from .workflows import eddy_fsl_pipeline, epi_pipeline # Nodes creation # ============== diff --git a/clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_utils.py b/clinica/pipelines/dwi_preprocessing_using_t1/utils.py similarity index 95% rename from clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_utils.py rename to clinica/pipelines/dwi_preprocessing_using_t1/utils.py index bcd686592..d1fbbbdf0 100644 --- a/clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_utils.py +++ b/clinica/pipelines/dwi_preprocessing_using_t1/utils.py @@ -88,8 +88,8 @@ def broadcast_matrix_filename_to_match_b_vector_length( """Return a list of the matrix filename repeated as many times as there are B-vectors.""" import numpy as np - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import ( # noqa - broadcast_filename_into_list, + from clinica.pipelines.dwi_preprocessing_using_t1.utils import ( + broadcast_filename_into_list, # noqa ) b_vectors = np.loadtxt(b_vectors_filename).T @@ -102,10 +102,11 @@ def broadcast_filename_into_list(filename: str, desired_length: int) -> list: return [filename] * desired_length -def ants_warp_image_multi_transform(fix_image, moving_image, ants_warp_affine): +def ants_warp_image_multi_transform(fix_image, moving_image, ants_warp_affine) -> str: import os + from pathlib import Path - out_warp = os.path.abspath("warped_epi.nii.gz") + out_warp = Path("warped_epi.nii.gz").resolve() cmd = ( f"WarpImageMultiTransform 3 {moving_image} {out_warp} -R {fix_image} " @@ -113,7 +114,7 @@ def ants_warp_image_multi_transform(fix_image, moving_image, ants_warp_affine): ) os.system(cmd) - return out_warp + return str(out_warp) def rotate_b_vectors( @@ -145,7 +146,6 @@ def rotate_b_vectors( coordinates in the original image. Therefore, this matrix should be inverted first, as we want to know the target position of :math:`\\vec{r}`. """ - import os from pathlib import Path import numpy as np @@ -160,7 +160,7 @@ def rotate_b_vectors( if output_dir: rotated_b_vectors_filename = Path(output_dir) / rotated_b_vectors_filename.name else: - rotated_b_vectors_filename = os.path.abspath(rotated_b_vectors_filename.name) + rotated_b_vectors_filename = Path(rotated_b_vectors_filename.name).resolve() b_vectors = np.loadtxt(b_vectors_filename).T @@ -241,8 +241,8 @@ def prepare_reference_b0_task( """Task called be Nipype to execute prepare_reference_b0.""" from pathlib import Path - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import ( # noqa - prepare_reference_b0, + from clinica.pipelines.dwi_preprocessing_using_t1.utils import ( + prepare_reference_b0, # noqa ) from clinica.utils.dwi import DWIDataset @@ -448,9 +448,7 @@ def register_b0( If the pipeline ran successfully, this file should be located in : working_directory / b0_coregistration / concat_ref_moving / merged_files.nii.gz """ - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_workflows import ( - b0_flirt_pipeline, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.workflows import b0_flirt_pipeline b0_flirt = b0_flirt_pipeline(num_b0s=nb_b0s) b0_flirt.inputs.inputnode.in_file = str(extracted_b0_filename) diff --git a/clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_workflows.py b/clinica/pipelines/dwi_preprocessing_using_t1/workflows.py similarity index 99% rename from clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_workflows.py rename to clinica/pipelines/dwi_preprocessing_using_t1/workflows.py index d46f16c50..c2aa3c3ed 100644 --- a/clinica/pipelines/dwi_preprocessing_using_t1/dwi_preprocessing_using_t1_workflows.py +++ b/clinica/pipelines/dwi_preprocessing_using_t1/workflows.py @@ -387,7 +387,7 @@ def perform_ants_registration( import nipype.interfaces.utility as niu import nipype.pipeline.engine as pe - from .dwi_preprocessing_using_t1_utils import ( + from .utils import ( broadcast_matrix_filename_to_match_b_vector_length, change_itk_transform_type, rotate_b_vectors, @@ -595,8 +595,6 @@ def perform_dwi_epi_correction( This workflow benefits a lot from parallelization as most operations are done on single DWI direction. """ - import os - import nipype.interfaces.ants as ants import nipype.interfaces.fsl as fsl import nipype.interfaces.io as nio diff --git a/test/instantiation/test_instantiate_all_pipelines.py b/test/instantiation/test_instantiate_all_pipelines.py index bb7ef6b63..8627750bb 100644 --- a/test/instantiation/test_instantiate_all_pipelines.py +++ b/test/instantiation/test_instantiate_all_pipelines.py @@ -120,7 +120,7 @@ def test_instantiate_t1_volume_parcellation(cmdopt): def test_instantiate_dwi_preprocessing_using_t1(cmdopt): - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_pipeline import ( + from clinica.pipelines.dwi_preprocessing_using_t1.pipeline import ( DwiPreprocessingUsingT1, ) @@ -143,7 +143,7 @@ def test_instantiate_dwi_preprocessing_using_t1(cmdopt): def test_instantiate_dwi_preprocessing_using_phase_diff_field_map(cmdopt): - from clinica.pipelines.dwi_preprocessing_using_fmap.dwi_preprocessing_using_phasediff_fmap_pipeline import ( + from clinica.pipelines.dwi_preprocessing_using_fmap.pipeline import ( DwiPreprocessingUsingPhaseDiffFMap, ) @@ -164,7 +164,7 @@ def test_instantiate_dwi_preprocessing_using_phase_diff_field_map(cmdopt): def test_instantiate_dwi_dti(cmdopt): - from clinica.pipelines.dwi_dti.dwi_dti_pipeline import DwiDti + from clinica.pipelines.dwi_dti.pipeline import DwiDti input_dir = Path(cmdopt["input"]) root = input_dir / "DWIDTI" @@ -176,7 +176,7 @@ def test_instantiate_dwi_dti(cmdopt): def test_instantiate_dwi_connectome(cmdopt): - from clinica.pipelines.dwi_connectome.dwi_connectome_pipeline import DwiConnectome + from clinica.pipelines.dwi_connectome.pipeline import DwiConnectome input_dir = Path(cmdopt["input"]) root = input_dir / "DWIConnectome" @@ -370,10 +370,9 @@ def test_instantiate_workflows_ml(cmdopt): for inputs in voxel_input + region_input + vertex_input: for file in inputs.get_images(): if isinstance(file, str): - assert exists(file) + assert Path(file).exists() elif isinstance(file, list) and len(file) == 2: - assert exists(file[0]) - assert exists(file[1]) + assert all([Path(p).exists() for p in file]) else: raise ValueError("An error occurred...") diff --git a/test/nonregression/pipelines/dwi/preprocessing/test_phase_diff.py b/test/nonregression/pipelines/dwi/preprocessing/test_phase_diff.py index 3d1a9bd8b..dcb63444a 100644 --- a/test/nonregression/pipelines/dwi/preprocessing/test_phase_diff.py +++ b/test/nonregression/pipelines/dwi/preprocessing/test_phase_diff.py @@ -36,7 +36,7 @@ def test_dwi_compute_reference_b0(cmdopt, tmp_path): - The reference B0 volume - The brain mask computed on the B0 volume """ - from clinica.pipelines.dwi_preprocessing_using_fmap.dwi_preprocessing_using_phasediff_fmap_workflows import ( + from clinica.pipelines.dwi_preprocessing_using_fmap.workflows import ( compute_reference_b0, ) from clinica.utils.dwi import bids_dir_to_fsl_dir @@ -91,7 +91,7 @@ def test_prepare_phasediff_fmap(cmdopt, tmp_path): This is a fast test which should run in less than a minute. """ - from clinica.pipelines.dwi_preprocessing_using_fmap.dwi_preprocessing_using_phasediff_fmap_workflows import ( + from clinica.pipelines.dwi_preprocessing_using_fmap.workflows import ( prepare_phasediff_fmap, ) from clinica.utils.filemanip import extract_metadata_from_json @@ -136,7 +136,7 @@ def test_dwi_calibrate_and_register_fmap(cmdopt, tmp_path): This is a fast test which should run in about 1 minute. """ - from clinica.pipelines.dwi_preprocessing_using_fmap.dwi_preprocessing_using_phasediff_fmap_workflows import ( + from clinica.pipelines.dwi_preprocessing_using_fmap.workflows import ( calibrate_and_register_fmap, ) from clinica.utils.filemanip import extract_metadata_from_json @@ -201,7 +201,7 @@ def test_dwi_preprocessing_using_phase_diff_field_map(cmdopt, tmp_path): def run_dwi_preprocessing_using_phase_diff_field_map( input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path ) -> None: - from clinica.pipelines.dwi_preprocessing_using_fmap.dwi_preprocessing_using_phasediff_fmap_pipeline import ( + from clinica.pipelines.dwi_preprocessing_using_fmap.pipeline import ( DwiPreprocessingUsingPhaseDiffFMap, ) diff --git a/test/nonregression/pipelines/dwi/preprocessing/test_t1.py b/test/nonregression/pipelines/dwi/preprocessing/test_t1.py index fb5aeae1c..48b16856e 100644 --- a/test/nonregression/pipelines/dwi/preprocessing/test_t1.py +++ b/test/nonregression/pipelines/dwi/preprocessing/test_t1.py @@ -13,9 +13,7 @@ @pytest.mark.fast def test_dwi_b0_flirt(cmdopt, tmp_path): - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_workflows import ( - b0_flirt_pipeline, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.workflows import b0_flirt_pipeline base_dir = Path(cmdopt["input"]) input_dir, tmp_dir, ref_dir = configure_paths(base_dir, tmp_path, "DWIB0Flirt") @@ -39,9 +37,7 @@ def test_dwi_b0_flirt(cmdopt, tmp_path): @pytest.mark.slow def test_dwi_epi_pipeline(cmdopt, tmp_path): - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_workflows import ( - epi_pipeline, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.workflows import epi_pipeline base_dir = Path(cmdopt["input"]) input_dir, tmp_dir, ref_dir = configure_paths(base_dir, tmp_path, "DWIEPIPipeline") @@ -83,7 +79,7 @@ def test_dwi_epi_pipeline(cmdopt, tmp_path): @pytest.mark.slow def test_dwi_perform_ants_registration(cmdopt, tmp_path): - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_workflows import ( + from clinica.pipelines.dwi_preprocessing_using_t1.workflows import ( perform_ants_registration, ) @@ -140,7 +136,7 @@ def test_dwi_perform_ants_registration(cmdopt, tmp_path): @pytest.mark.slow def test_dwi_perform_dwi_epi_correction(cmdopt, tmp_path): - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_workflows import ( + from clinica.pipelines.dwi_preprocessing_using_t1.workflows import ( perform_dwi_epi_correction, ) @@ -180,9 +176,7 @@ def test_dwi_perform_dwi_epi_correction(cmdopt, tmp_path): @pytest.mark.slow def test_dwi_eddy_fsl(cmdopt, tmp_path): - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_workflows import ( - eddy_fsl_pipeline, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.workflows import eddy_fsl_pipeline base_dir = Path(cmdopt["input"]) input_dir, tmp_dir, ref_dir = configure_paths(base_dir, tmp_path, "DWIEddyFSL") @@ -238,7 +232,7 @@ def test_dwi_preprocessing_using_t1(cmdopt, tmp_path): def run_dwi_preprocessing_using_t1( input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path ) -> None: - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_pipeline import ( + from clinica.pipelines.dwi_preprocessing_using_t1.pipeline import ( DwiPreprocessingUsingT1, ) diff --git a/test/nonregression/pipelines/dwi/test_pipelines.py b/test/nonregression/pipelines/dwi/test_pipelines.py index d69971acb..22da85c5f 100644 --- a/test/nonregression/pipelines/dwi/test_pipelines.py +++ b/test/nonregression/pipelines/dwi/test_pipelines.py @@ -29,7 +29,7 @@ def test_dwi_connectome(cmdopt, tmp_path): def run_dwi_dti( input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path ) -> None: - from clinica.pipelines.dwi_dti.dwi_dti_pipeline import DwiDti + from clinica.pipelines.dwi_dti.pipeline import DwiDti from clinica.utils.dwi import DTIBasedMeasure caps_dir = output_dir / "caps" @@ -77,7 +77,7 @@ def run_dwi_dti( def run_dwi_connectome( input_dir: Path, output_dir: Path, ref_dir: Path, working_dir: Path ) -> None: - from clinica.pipelines.dwi_connectome.dwi_connectome_pipeline import DwiConnectome + from clinica.pipelines.dwi_connectome.pipeline import DwiConnectome caps_dir = output_dir / "caps" diff --git a/test/unittests/pipelines/dwi_connectome/test_dwi_connectome_utils.py b/test/unittests/pipelines/dwi_connectome/test_dwi_connectome_utils.py index 35c6fab2b..d45e33bab 100644 --- a/test/unittests/pipelines/dwi_connectome/test_dwi_connectome_utils.py +++ b/test/unittests/pipelines/dwi_connectome/test_dwi_connectome_utils.py @@ -2,7 +2,7 @@ def test_get_luts(mocker): - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import get_luts + from clinica.pipelines.dwi_connectome.utils import get_luts mocked_freesurfer_home = "/Applications/freesurfer/7.2.0" mocker.patch( @@ -26,17 +26,13 @@ def test_get_luts(mocker): ], ) def test_get_checksum_for_filename(filename, expected_checksum): - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import ( - _get_checksum_for_filename, - ) + from clinica.pipelines.dwi_connectome.utils import _get_checksum_for_filename assert _get_checksum_for_filename(filename) == expected_checksum def test_get_checksum_for_filename_error(): - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import ( - _get_checksum_for_filename, - ) + from clinica.pipelines.dwi_connectome.utils import _get_checksum_for_filename with pytest.raises(ValueError, match="File name foo.txt is not supported."): _get_checksum_for_filename("foo.txt") @@ -50,9 +46,7 @@ def test_download_mrtrix3_file(tmp_path, filename, expected_length): TODO: Use mocking in the fetch_file function to remove this necessity. """ - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import ( - _download_mrtrix3_file, - ) + from clinica.pipelines.dwi_connectome.utils import _download_mrtrix3_file _download_mrtrix3_file(filename, tmp_path) @@ -63,12 +57,10 @@ def test_download_mrtrix3_file(tmp_path, filename, expected_length): def test_download_mrtrix3_file_error(tmp_path, mocker): import re - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import ( - _download_mrtrix3_file, - ) + from clinica.pipelines.dwi_connectome.utils import _download_mrtrix3_file mocker.patch( - "clinica.pipelines.dwi_connectome.dwi_connectome_utils._get_checksum_for_filename", + "clinica.pipelines.dwi_connectome.utils._get_checksum_for_filename", return_value="foo", ) mocker.patch("clinica.utils.inputs.fetch_file", side_effect=IOError) @@ -85,9 +77,7 @@ def test_download_mrtrix3_file_error(tmp_path, mocker): def test_get_conversion_luts(): from pathlib import Path - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import ( - get_conversion_luts, - ) + from clinica.pipelines.dwi_connectome.utils import get_conversion_luts luts = [Path(_) for _ in get_conversion_luts()] @@ -107,14 +97,14 @@ def test_get_conversion_luts(): ], ) def test_get_caps_filenames_error(tmp_path, filename): - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import get_caps_filenames + from clinica.pipelines.dwi_connectome.utils import get_caps_filenames with pytest.raises(ValueError, match="is not in a CAPS compliant format."): get_caps_filenames(str(tmp_path / filename)) def test_get_caps_filenames(tmp_path): - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import get_caps_filenames + from clinica.pipelines.dwi_connectome.utils import get_caps_filenames dwi_caps = tmp_path / "dwi" / "preprocessing" dwi_caps.mkdir(parents=True) @@ -149,6 +139,6 @@ def test_get_caps_filenames(tmp_path): ], ) def test_get_containers(subjects, sessions, expected): - from clinica.pipelines.dwi_connectome.dwi_connectome_utils import get_containers + from clinica.pipelines.dwi_connectome.utils import get_containers assert get_containers(subjects, sessions) == expected diff --git a/test/unittests/pipelines/dwi_preprocessing_using_t1/test_dwi_preprocessing_using_t1_utils.py b/test/unittests/pipelines/dwi_preprocessing_using_t1/test_dwi_preprocessing_using_t1_utils.py index dc6c8543f..5a425bbd9 100644 --- a/test/unittests/pipelines/dwi_preprocessing_using_t1/test_dwi_preprocessing_using_t1_utils.py +++ b/test/unittests/pipelines/dwi_preprocessing_using_t1/test_dwi_preprocessing_using_t1_utils.py @@ -2,7 +2,7 @@ import pytest from numpy.testing import assert_array_almost_equal, assert_array_equal -from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import ( +from clinica.pipelines.dwi_preprocessing_using_t1.utils import ( broadcast_matrix_filename_to_match_b_vector_length, change_itk_transform_type, extract_sub_ses_folder_name, @@ -181,7 +181,7 @@ def test_rotate_b_vectors_wrong_content_in_vector_file(tmp_path): def test_configure_working_directory(tmp_path): import hashlib - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import ( + from clinica.pipelines.dwi_preprocessing_using_t1.utils import ( configure_working_directory, ) @@ -199,9 +199,7 @@ def test_configure_working_directory(tmp_path): def test_compute_reference_b0_errors(tmp_path): import numpy as np - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import ( - compute_reference_b0, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.utils import compute_reference_b0 (tmp_path / "b0.nii.gz").touch() np.savetxt(tmp_path / "foo.bval", [1000] * 9) @@ -221,9 +219,7 @@ def test_compute_reference_b0_with_single_b0(tmp_path): import numpy as np from numpy.testing import assert_array_equal - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import ( - compute_reference_b0, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.utils import compute_reference_b0 b0_data = 4.0 * np.ones((5, 5, 5, 1)) b0_img = nib.Nifti1Image(b0_data, affine=np.eye(4)) @@ -258,9 +254,7 @@ def test_compute_reference_b0_with_multiple_b0(tmp_path, mocker, clean_working_d import numpy as np from numpy.testing import assert_array_equal - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import ( - compute_reference_b0, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.utils import compute_reference_b0 working_directory = tmp_path / "tmp" working_directory.mkdir() @@ -273,7 +267,7 @@ def test_compute_reference_b0_with_multiple_b0(tmp_path, mocker, clean_working_d assert not mocked_output.exists() mocked_output.parent.mkdir(parents=True) mocker.patch( - "clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils.register_b0", + "clinica.pipelines.dwi_preprocessing_using_t1.utils.register_b0", return_value=mocked_output, ) # Build a dataset with 3 B0 volumes @@ -323,14 +317,12 @@ def test_prepare_reference_b0(tmp_path, mocker): import numpy as np from numpy.testing import assert_array_equal - from clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils import ( - prepare_reference_b0, - ) + from clinica.pipelines.dwi_preprocessing_using_t1.utils import prepare_reference_b0 from clinica.utils.dwi import DWIDataset mocked_output = tmp_path / "reference_b0_volume.nii.gz" mocker.patch( - "clinica.pipelines.dwi_preprocessing_using_t1.dwi_preprocessing_using_t1_utils.compute_reference_b0", + "clinica.pipelines.dwi_preprocessing_using_t1.utils.compute_reference_b0", return_value=mocked_output, ) ref_b0_data = 5.0 * np.ones((5, 5, 5, 1))