Skip to content

Commit

Permalink
[MAINT] Delete clinica.utils.mri_registration module (#1139)
Browse files Browse the repository at this point in the history
  • Loading branch information
AliceJoubert authored Apr 12, 2024
1 parent 4dc5bbb commit e565fba
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 55 deletions.
20 changes: 10 additions & 10 deletions clinica/pipelines/dwi/connectome/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,10 @@ def _build_core_nodes(self):
)

from clinica.utils.exceptions import ClinicaCAPSError
from clinica.utils.mri_registration import (
convert_flirt_transformation_to_mrtrix_transformation,
)

from .tasks import (
convert_flirt_to_mrtrix_transformation_task,
)
from .utils import (
get_caps_filenames,
get_conversion_luts,
Expand Down Expand Up @@ -344,13 +344,13 @@ def _build_core_nodes(self):
name="Reg-2-FSL2MrtrixConversion",
interface=niu.Function(
input_names=[
"in_source_image",
"in_reference_image",
"in_flirt_matrix",
"source_image",
"reference_image",
"flirt_matrix",
"name_output_matrix",
],
output_names=["out_mrtrix_matrix"],
function=convert_flirt_transformation_to_mrtrix_transformation,
function=convert_flirt_to_mrtrix_transformation_task,
),
)

Expand Down Expand Up @@ -556,17 +556,17 @@ def _build_core_nodes(self):
(
t1_brain_conv_node,
fsl2mrtrix_conv_node,
[("out_file", "in_source_image")],
[("out_file", "source_image")],
),
(
mask_node,
fsl2mrtrix_conv_node,
[("out_file", "in_reference_image")],
[("out_file", "reference_image")],
),
(
t12b0_reg_node,
fsl2mrtrix_conv_node,
[("out_matrix_file", "in_flirt_matrix")],
[("out_matrix_file", "flirt_matrix")],
),
# Apply registration without resampling on parcellations
(
Expand Down
32 changes: 32 additions & 0 deletions clinica/pipelines/dwi/connectome/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""This module contains Nipype tasks used by the connectome pipeline.
Nipype tasks must be 'self-contained' such that only primitive type hints can be
used. The tasks are simple wrappers around a properly implemented Python function.
"""


def convert_flirt_to_mrtrix_transformation_task(
source_image: str,
reference_image: str,
flirt_matrix: str,
name_output_matrix=None,
) -> str:
"""Adapter for Nipype"""

from pathlib import Path

from clinica.pipelines.dwi.connectome.utils import (
convert_flirt_to_mrtrix_transformation,
)

if name_output_matrix is not None:
name_output_matrix = Path(name_output_matrix)

return str(
convert_flirt_to_mrtrix_transformation(
Path(source_image),
Path(reference_image),
Path(flirt_matrix),
name_output_matrix,
)
)
71 changes: 70 additions & 1 deletion clinica/pipelines/dwi/connectome/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""This module contains utilities used by the DWIConnectome pipeline."""

from pathlib import Path
from typing import List
from typing import List, Optional

__all__ = [
"get_luts",
Expand All @@ -10,6 +10,7 @@
"get_caps_filenames",
"print_begin_pipeline",
"print_end_pipeline",
"convert_flirt_to_mrtrix_transformation",
]


Expand Down Expand Up @@ -120,3 +121,71 @@ def print_end_pipeline(in_bids_or_caps_file: str, final_file: str) -> None:
from clinica.utils.ux import print_end_image

print_end_image(get_subject_id(in_bids_or_caps_file))


def _check_file_presence(
file: Path,
) -> None:
if not file.is_file():
raise FileNotFoundError(f"The file {file} was not found.")


def _get_transformation_cmd(
source_image: Path,
reference_image: Path,
flirt_matrix: Path,
mrtrix_matrix: Path,
) -> str:
for file in (source_image, reference_image, flirt_matrix):
_check_file_presence(file)

return f"transformconvert {flirt_matrix} {source_image} {reference_image} flirt_import {mrtrix_matrix}"


def convert_flirt_to_mrtrix_transformation(
source_image: Path,
reference_image: Path,
flirt_matrix: Path,
name_output_matrix: Optional[str] = None,
) -> Path:
"""Convert flirt matrix to mrtrix matrix.
This function converts a transformation matrix produced by FSL's flirt
command into a format usable by MRtrix. The output of this function
is usually for the mrtransform command.
Parameters
----------
source_image : Path
File containing the source image used in FSL flirt with the -in flag.
reference_image : Path
File containing the reference image used in FSL flirt with the -ref flag.
flirt_matrix : Path
File containing the transformation matrix obtained by FSL flirt.
name_output_matrix : Path, optional
Name of the output matrix. Defaults to "mrtrix_matrix.mat".
Returns
-------
mrtrix_matrix : Path
Transformation matrix in MRtrix format.
"""
import os

from clinica.utils.check_dependency import ThirdPartySoftware, check_software

check_software(ThirdPartySoftware.MRTRIX)

name_output_matrix = name_output_matrix or "mrtrix_matrix.mat"
mrtrix_matrix = Path(name_output_matrix)
mrtrix_matrix = mrtrix_matrix.resolve()

cmd = _get_transformation_cmd(
source_image, reference_image, flirt_matrix, mrtrix_matrix
)
os.system(cmd)

return mrtrix_matrix
44 changes: 0 additions & 44 deletions clinica/utils/mri_registration.py

This file was deleted.

71 changes: 71 additions & 0 deletions test/unittests/pipelines/dwi/test_connectome_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,74 @@ def test_get_containers(subjects, sessions, expected):
from clinica.pipelines.dwi.connectome.utils import get_containers

assert get_containers(subjects, sessions) == expected


def _create_files_helper(tmp_path: Path) -> tuple[Path, Path, Path, Path]:
flirt_matrix = tmp_path / "flirt.mat"
flirt_matrix.touch()

source_image = tmp_path / "src.nii.gz"
source_image.touch()

reference_image = tmp_path / "ref.nii.gz"
reference_image.touch()

mrtrix_matrix = tmp_path / "mrtrix_matrix.mat"
mrtrix_matrix.touch()

return source_image, reference_image, flirt_matrix, mrtrix_matrix


def test_get_transformation_cmd(tmp_path):
from clinica.pipelines.dwi.connectome.utils import _get_transformation_cmd

source_image, reference_image, flirt_matrix, mrtrix_matrix = _create_files_helper(
tmp_path
)

assert (
_get_transformation_cmd(
source_image, reference_image, flirt_matrix, mrtrix_matrix
)
== f"transformconvert {flirt_matrix} {source_image} {reference_image} flirt_import {mrtrix_matrix}"
)


def test_get_transformation_cmd_error(tmp_path):
from clinica.pipelines.dwi.connectome.utils import _get_transformation_cmd

with pytest.raises(
FileNotFoundError, match=f"The file {tmp_path / 'src.nii.gz'} was not found"
):
_get_transformation_cmd(
tmp_path / "src.nii.gz",
tmp_path / "ref.nii.gz",
tmp_path / "flirt.mat",
tmp_path / "mrtx.mat",
)


def test_convert_flirt_to_mrtrix_transformation(tmp_path, mocker):
from clinica.pipelines.dwi.connectome.utils import (
convert_flirt_to_mrtrix_transformation,
)

mocker.patch("clinica.utils.check_dependency.check_software", return_value=None)
mocker.patch("os.system", return_value=None)

source_image, reference_image, flirt_matrix, output_matrix = _create_files_helper(
tmp_path
)

assert (
convert_flirt_to_mrtrix_transformation(
source_image, reference_image, flirt_matrix, output_matrix.name
)
== Path(output_matrix.name).resolve()
)
assert (
convert_flirt_to_mrtrix_transformation(
source_image, reference_image, flirt_matrix, None
)
== Path("mrtrix_matrix.mat").resolve()
)

0 comments on commit e565fba

Please sign in to comment.