Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions brainles_preprocessing/modality.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ def register(
registration_dir: Union[str, Path],
moving_image_name: str,
step: PreprocessorSteps,
interpolator: Optional[str] = None,
) -> Path:
"""
Register the current modality to a fixed image using the specified registrator.
Expand All @@ -249,9 +250,13 @@ def register(
registration_dir (str or Path): Directory to store registration results.
moving_image_name (str): Name of the moving image.
step (PreprocessorSteps): The current preprocessing step.
interpolator (Optional[str]): Interpolation method used during registration. Only supported by ANTsRegistrator; omit it for other registrators to use the backend default.

Returns:
Path: Path to the registration matrix.

Raises:
ValueError: If an interpolator is passed for a registrator other than ANTsRegistrator.
"""
fixed_image_path = Path(fixed_image_path)
registration_dir = Path(registration_dir)
Expand All @@ -262,12 +267,21 @@ def register(
# Note, add file ending depending on registration backend!
registered_matrix = registration_dir / f"M_{moving_image_name}"

if interpolator is not None and not isinstance(registrator, ANTsRegistrator):
raise ValueError(
f"'interpolator' is only supported by ANTsRegistrator for registration, "
f"got {type(registrator).__name__}. Omit it to use the backend default."
)

interpolator_kwargs = {"interpolator": interpolator} if interpolator else {}

registrator.register(
fixed_image_path=fixed_image_path,
moving_image_path=self.current,
transformed_image_path=registered,
matrix_path=registered_matrix,
log_file_path=str(registered_log),
**interpolator_kwargs,
Comment thread
LMZimmer marked this conversation as resolved.
)
self.current = registered
self.steps[step] = registered
Expand Down Expand Up @@ -364,6 +378,7 @@ def transform(
moving_image_name: str,
transformation_matrix_path: Union[str, Path],
step: PreprocessorSteps,
interpolator: Optional[str] = None,
) -> None:
"""
Transform the current modality using the specified registrator and transformation matrix.
Expand All @@ -375,6 +390,7 @@ def transform(
moving_image_name (str): Name of the moving image.
transformation_matrix_path (str or Path): Path to the transformation matrix.
step (PreprocessorSteps): The current preprocessing step.
interpolator (Optional[str]): Interpolation method used during transformation. Available options depend on the chosen registrator.
Returns:
None
"""
Expand All @@ -385,6 +401,8 @@ def transform(
transformed = registration_dir_path / f"{moving_image_name}.nii.gz"
transformed_log = registration_dir_path / f"{moving_image_name}.log"

interpolator_kwargs = {"interpolator": interpolator} if interpolator else {}

if (
isinstance(registrator, (ANTsRegistrator, NiftyRegRegistrator))
and step == PreprocessorSteps.ATLAS_REGISTERED
Expand All @@ -406,6 +424,7 @@ def transform(
transformation_matrix_path, # atlas registration matrix
],
log_file_path=str(transformed_log),
**interpolator_kwargs,
)
else:
registrator.transform(
Expand All @@ -414,6 +433,7 @@ def transform(
transformed_image_path=str(transformed),
matrix_path=str(transformation_matrix_path),
log_file_path=str(transformed_log),
**interpolator_kwargs,
)

self.current = transformed
Expand Down Expand Up @@ -701,12 +721,22 @@ def deface(
mask_image_path=deface_mask_atlas,
)

if isinstance(registrator, ANTsRegistrator):
nn_interpolator = "nearestNeighbor"
elif isinstance(registrator, NiftyRegRegistrator):
nn_interpolator = "0"
else:
raise NotImplementedError(
f"Nearest-neighbour mask resampling is not configured for {type(registrator).__name__}."
)

registrator.inverse_transform(
fixed_image_path=self.steps[PreprocessorSteps.BET],
moving_image_path=deface_mask_atlas,
transformed_image_path=mask_path,
matrix_path=atlas_bet_M,
log_file_path=defaced_dir_path / "inverse_transform.log",
interpolator=nn_interpolator,
)
else:
defacer.deface(
Expand Down
23 changes: 15 additions & 8 deletions brainles_preprocessing/registration/ANTs/ANTs.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def register(
transformed_image_path: Union[str, Path],
matrix_path: Union[str, Path],
log_file_path: Union[str, Path],
interpolator: Optional[str] = None,
**kwargs,
) -> None:
"""
Expand All @@ -72,6 +73,7 @@ def register(
transformed_image_path (str or Path): Path to the transformed image (output).
matrix_path (str or Path): Path to the transformation matrix (output).
log_file_path (str or Path): Path to the log file.
interpolator (Optional[str]): Interpolator to use for the transformation. Defaults to the instantiated transformation parameters, or 'linear' if not set.
**kwargs: Additional registration parameters to update the instantiated defaults.

Raises:
Expand Down Expand Up @@ -123,6 +125,7 @@ def register(
transformed_image_path=transformed_image_path,
matrix_path=matrix_path,
log_file_path=log_file_path,
interpolator=interpolator,
)

end_time = datetime.datetime.now()
Expand All @@ -148,7 +151,7 @@ def transform(
transformed_image_path: Union[str, Path],
matrix_path: str | Path | List[str | Path],
log_file_path: Union[str, Path],
interpolator: str = "nearestNeighbor",
interpolator: Optional[str] = None,
**kwargs,
) -> None:
"""
Expand All @@ -161,23 +164,27 @@ def transform(
transformed_image_path (str or Path): Path to the transformed image (output).
matrix_path (str or Path or List[str | Path]): Path to the transformation matrix or a list of matrices.
log_file_path (str or Path): Path to the log file.
interpolator (str): Interpolator to use for the transformation. Default is 'nearestNeighbor'.
interpolator (Optional[str]): Interpolator to use for the transformation. Defaults to the instantiated transformation parameters, or 'linear' if not set.
**kwargs: Additional transformation parameters to update the instantiated defaults.
Raises:
AssertionError: If the interpolator is not valid.
FileNotFoundError: If the fixed or moving image paths do not exist.
"""
start_time = datetime.datetime.now()

# TODO - self.transformation_params
# we update the transformation parameters with the provided kwargs
transform_kwargs = {**self.transformation_params, **kwargs}

# the interpolator argument takes precedence over the instantiated defaults
default_interpolator = transform_kwargs.pop("interpolator", "linear")
interpolator = interpolator or default_interpolator

assert interpolator in VALID_INTERPOLATORS, (
f"Invalid interpolator: {interpolator}. "
f"Valid options are: {', '.join(VALID_INTERPOLATORS)}."
)

# TODO - self.transformation_params
# we update the transformation parameters with the provided kwargs
transform_kwargs = {**self.transformation_params, **kwargs}

# Convert all paths to Path objects
fixed_image_path = Path(fixed_image_path)
moving_image_path = Path(moving_image_path)
Expand Down Expand Up @@ -243,7 +250,7 @@ def inverse_transform(
transformed_image_path: Union[str, Path],
matrix_path: str | Path | List[str | Path],
log_file_path: Union[str, Path],
interpolator: str = "nearestNeighbor",
interpolator: Optional[str] = None,
Comment thread
LMZimmer marked this conversation as resolved.
**kwargs,
) -> None:
"""
Expand All @@ -255,7 +262,7 @@ def inverse_transform(
transformed_image_path (str or Path): Path to the transformed image (output).
matrix_path (str or Path or List[str | Path]): Path to the transformation matrix or a list of matrices.
log_file_path (str or Path): Path to the log file.
interpolator (str): Interpolator to use for the transformation. Default is 'nearestNeighbor'.
interpolator (Optional[str]): Interpolator to use for the transformation. Defaults to the instantiated transformation parameters, or 'linear' if not set.
**kwargs: Additional transformation parameters to update the instantiated defaults.
"""
if not isinstance(matrix_path, list):
Expand Down
4 changes: 2 additions & 2 deletions brainles_preprocessing/registration/niftyreg/niftyreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def transform(
transformed_image_path: str,
matrix_path: str | Path | List[str | Path],
log_file_path: str,
interpolator: str = "0",
interpolator: str = "1",
**kwargs: dict,
) -> None:
"""
Expand Down Expand Up @@ -236,7 +236,7 @@ def inverse_transform(
transformed_image_path: str,
matrix_path: str | Path | List[str | Path],
log_file_path: str,
interpolator: str = "0",
interpolator: str = "1",
) -> None:
"""
Apply inverse transformation using NiftyReg.
Expand Down
8 changes: 4 additions & 4 deletions brainles_preprocessing/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ def apply(
Available options depend on the chosen registrator:

- **ANTsRegistrator**:
- "linear"
- "nearestNeighbor" (default)
- "linear" (default)
- "nearestNeighbor"
- "multiLabel" (deprecated, prefer "genericLabel")
- "gaussian"
- "bSpline"
Expand All @@ -70,8 +70,8 @@ def apply(
- "genericLabel" (recommended for label images)

- **NiftyReg**:
- "0": nearest neighbor (default)
- "1": linear
- "0": nearest neighbor
- "1": linear (default)
- "3": cubic spline
- "4": sinc

Expand Down