Skip to content

Commit f437f69

Browse files
committed
sty: add typing annotations and run black
1 parent 88405a1 commit f437f69

File tree

1 file changed

+59
-36
lines changed

1 file changed

+59
-36
lines changed

sdcflows/transform.py

+59-36
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#
2323
"""The :math:`B_0` unwarping transform formalism."""
2424
from pathlib import Path
25+
from typing import Sequence, Union
2526

2627
import attr
2728
import numpy as np
@@ -50,7 +51,12 @@ class B0FieldTransform:
5051
target image we want to correct).
5152
"""
5253

53-
def fit(self, target_reference, affine=None, approx=True):
54+
def fit(
55+
self,
56+
target_reference: nb.spatialimages.SpatialImage,
57+
affine: np.array = None,
58+
approx: bool = True,
59+
) -> bool:
5460
r"""
5561
Generate the interpolation matrix (and the VSM with it).
5662
@@ -59,7 +65,7 @@ def fit(self, target_reference, affine=None, approx=True):
5965
6066
Parameters
6167
----------
62-
target_reference : `spatialimage`
68+
target_reference : :obj:`~nibabel.spatialimages.SpatialImage`
6369
The image object containing a reference grid (same as that of the data
6470
to be resampled). If a 4D dataset is provided, then the fourth dimension
6571
will be dropped.
@@ -83,7 +89,9 @@ def fit(self, target_reference, affine=None, approx=True):
8389
if isinstance(target_reference, (str, bytes, Path)):
8490
target_reference = nb.load(target_reference)
8591

86-
approx = approx if affine is not None else False # Approximate iff affine is defined
92+
approx = (
93+
approx if affine is not None else False
94+
) # Approximate iff affine is defined
8795
affine = affine if affine is not None else np.eye(4)
8896
target_affine = target_reference.affine.copy()
8997

@@ -141,22 +149,22 @@ def fit(self, target_reference, affine=None, approx=True):
141149
hdr.set_intent("estimate", name="fieldmap Hz")
142150
hdr.set_data_dtype("float32")
143151
hdr["cal_max"] = max((abs(fmap.min()), fmap.max()))
144-
hdr["cal_min"] = - hdr["cal_max"]
152+
hdr["cal_min"] = -hdr["cal_max"]
145153
self.mapped = nb.Nifti1Image(fmap, target_affine, hdr)
146154
return True
147155

148156
def apply(
149157
self,
150-
moving,
151-
pe_dir,
152-
ro_time,
153-
xfms=None,
154-
order=3,
155-
mode="constant",
156-
cval=0.0,
157-
prefilter=True,
158-
output_dtype=None,
159-
num_threads=None,
158+
moving: nb.spatialimages.SpatialImage,
159+
pe_dir: str,
160+
ro_time: float,
161+
xfms: Sequence[np.array] = None,
162+
order: int = 3,
163+
mode: str = "constant",
164+
cval: float = 0.0,
165+
prefilter: bool = True,
166+
output_dtype: Union[str, np.dtype] = None,
167+
num_threads: int = None,
160168
):
161169
"""
162170
Apply a transformation to an image, resampling on the reference spatial object.
@@ -165,32 +173,41 @@ def apply(
165173
166174
Parameters
167175
----------
168-
moving : `spatialimage`
176+
moving : :obj:`~nibabel.spatialimages.SpatialImage`
169177
The image object containing the data to be resampled in reference
170178
space
171-
xfms : `None` or :obj:`list`
179+
pe_dir : :obj:`str`
180+
A valid ``PhaseEncodingDirection`` metadata value.
181+
ro_time : :obj:`float`
182+
The total readout time in seconds.
183+
xfms : :obj:`None` or :obj:`list`
172184
A list of rigid-body transformations previously estimated that will
173185
realign the dataset (that is, compensate for head motion) after resampling.
174-
order : int, optional
186+
order : :obj:`int`, optional
175187
The order of the spline interpolation, default is 3.
176188
The order has to be in the range 0-5.
177189
mode : {'constant', 'reflect', 'nearest', 'mirror', 'wrap'}, optional
178190
Determines how the input image is extended when the resamplings overflows
179191
a border. Default is 'constant'.
180192
cval : float, optional
181193
Constant value for ``mode='constant'``. Default is 0.0.
182-
prefilter: bool, optional
194+
prefilter : :obj:`bool`, optional
183195
Determines if the image's data array is prefiltered with
184196
a spline filter before interpolation. The default is ``True``,
185197
which will create a temporary *float64* array of filtered values
186198
if *order > 1*. If setting this to ``False``, the output will be
187199
slightly blurred if *order > 1*, unless the input is prefiltered,
188200
i.e. it is the result of calling the spline filter on the original
189201
input.
202+
output_dtype : :obj:`str` or :obj:`~numpy.dtype`
203+
Override the output data type, instead of propagating it from the
204+
moving image.
205+
num_threads : :obj:`int`
206+
Number of CPUs resampling can be parallelized on.
190207
191208
Returns
192209
-------
193-
resampled : `spatialimage` or ndarray
210+
resampled : :obj:`~nibabel.spatialimages.SpatialImage`
194211
The data imaged after resampling to reference space.
195212
196213
"""
@@ -249,9 +266,7 @@ def apply(
249266
prefilter=prefilter,
250267
).reshape(moving.shape)
251268

252-
moved = moving.__class__(
253-
resampled, moving.affine, moving.header
254-
)
269+
moved = moving.__class__(resampled, moving.affine, moving.header)
255270
moved.header.set_data_dtype(output_dtype)
256271
return reorient_image(moved, axcodes)
257272

@@ -368,11 +383,13 @@ def disp_to_fmap(xyz_nii, ro_time, pe_dir, itk_format=True):
368383
fmap_nii = nb.Nifti1Image(vsm / scale_factor, xyz_nii.affine)
369384
fmap_nii.header.set_intent("estimate", name="Delta_B0 [Hz]")
370385
fmap_nii.header.set_xyzt_units("mm")
371-
fmap_nii.header["cal_max"] = max((
372-
abs(np.asanyarray(fmap_nii.dataobj).min()),
373-
np.asanyarray(fmap_nii.dataobj).max(),
374-
))
375-
fmap_nii.header["cal_min"] = - fmap_nii.header["cal_max"]
386+
fmap_nii.header["cal_max"] = max(
387+
(
388+
abs(np.asanyarray(fmap_nii.dataobj).min()),
389+
np.asanyarray(fmap_nii.dataobj).max(),
390+
)
391+
)
392+
fmap_nii.header["cal_min"] = -fmap_nii.header["cal_max"]
376393
return fmap_nii
377394

378395

@@ -426,10 +443,14 @@ def grid_bspline_weights(target_nii, ctrl_nii, dtype="float32"):
426443
knots_shape = ctrl_nii.shape[:3]
427444

428445
# Ensure the cross-product of affines is near zero (i.e., both coordinate systems are aligned)
429-
if not np.allclose(np.linalg.norm(
430-
np.cross(ctrl_nii.affine[:-1, :-1].T, target_nii.affine[:-1, :-1].T),
431-
axis=1,
432-
), 0, atol=1e-3):
446+
if not np.allclose(
447+
np.linalg.norm(
448+
np.cross(ctrl_nii.affine[:-1, :-1].T, target_nii.affine[:-1, :-1].T),
449+
axis=1,
450+
),
451+
0,
452+
atol=1e-3,
453+
):
433454
warn("Image's and B-Spline's grids are not aligned.")
434455

435456
target_to_grid = np.linalg.inv(ctrl_nii.affine) @ target_nii.affine
@@ -481,9 +502,11 @@ def _move_coeff(in_coeff, fmap_ref, transform, fmap_target=None):
481502
hdr.set_sform(newaff, code=1)
482503

483504
# Make it easy on viz software to render proper range
484-
hdr["cal_max"] = max((
485-
abs(np.asanyarray(coeff.dataobj).min()),
486-
np.asanyarray(coeff.dataobj).max(),
487-
))
488-
hdr["cal_min"] = - hdr["cal_max"]
505+
hdr["cal_max"] = max(
506+
(
507+
abs(np.asanyarray(coeff.dataobj).min()),
508+
np.asanyarray(coeff.dataobj).max(),
509+
)
510+
)
511+
hdr["cal_min"] = -hdr["cal_max"]
489512
return coeff.__class__(coeff.dataobj, newaff, hdr)

0 commit comments

Comments
 (0)