Skip to content

Commit 3b356a0

Browse files
committed
Merge remote-tracking branch 'upstream/maint/1.4.x' into maint/1.5.x
2 parents 46bcbf6 + 95d62c9 commit 3b356a0

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

CHANGES.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ This release upgrades the Dockerfile to use FSL6, and includes some new interfac
4545
* FIX: Scipy docs path (#681)
4646
* TEST: Drop excessively long interface equivalence tests (#674)
4747

48+
1.4.8 (April 08, 2022)
49+
======================
50+
Bug-fix release in the 1.4.x series.
51+
52+
This change enables a bug-fix in sdcflows where images with slightly
53+
different affines were unable to be concatenated for use with TOPUP.
54+
55+
* ENH: Add ``affine_tolerance`` flag to ``MergeSeries`` (#706)
56+
4857
1.4.7 (March 31, 2022)
4958
======================
5059
Bug-fix release in the 1.4.x series.

niworkflows/interfaces/nibabel.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ class _MergeSeriesInputSpec(BaseInterfaceInputSpec):
186186
allow_4D = traits.Bool(
187187
True, usedefault=True, desc="whether 4D images are allowed to be concatenated"
188188
)
189+
affine_tolerance = traits.Float(desc="Absolute tolerance allowed between image affines")
189190

190191

191192
class _MergeSeriesOutputSpec(TraitedSpec):
@@ -200,8 +201,17 @@ class MergeSeries(SimpleInterface):
200201

201202
def _run_interface(self, runtime):
202203
nii_list = []
204+
aff0 = None
203205
for f in self.inputs.in_files:
204206
filenii = nb.squeeze_image(nb.load(f))
207+
if self.inputs.affine_tolerance:
208+
if aff0 is None:
209+
aff0 = filenii.affine
210+
elif not np.allclose(aff0, filenii.affine, atol=self.inputs.affine_tolerance):
211+
raise ValueError(
212+
"Difference in affines greater than allowed tolerance "
213+
f"{self.inputs.affine_tolerance}"
214+
)
205215
ndim = filenii.dataobj.ndim
206216
if ndim == 3:
207217
nii_list.append(filenii)
@@ -214,7 +224,10 @@ def _run_interface(self, runtime):
214224
"Input image has an incorrect number of dimensions" f" ({ndim})."
215225
)
216226

217-
img_4d = nb.concat_images(nii_list)
227+
img_4d = nb.concat_images(
228+
nii_list,
229+
check_affines=not bool(self.inputs.affine_tolerance)
230+
)
218231
out_file = fname_presuffix(
219232
self.inputs.in_files[0], suffix="_merged", newpath=runtime.cwd
220233
)

niworkflows/interfaces/tests/test_nibabel.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,24 @@ def test_MergeSeries(tmp_path):
230230
MergeSeries(in_files=[str(in_file)] + [str(in_4D)], allow_4D=False).run()
231231

232232

233+
def test_MergeSeries_affines(tmp_path):
234+
os.chdir(str(tmp_path))
235+
236+
files = ['img0.nii.gz', 'img1.nii.gz']
237+
data = np.ones((10, 10, 10), dtype=int)
238+
aff = np.eye(4)
239+
nb.Nifti1Image(data, aff, None).to_filename(files[0])
240+
# slightly alter affine
241+
aff[0][0] = 1.00005
242+
nb.Nifti1Image(data, aff, None).to_filename(files[1])
243+
244+
# affine mismatch will cause this to fail
245+
with pytest.raises(ValueError):
246+
MergeSeries(in_files=files).run()
247+
# but works if we set a tolerance
248+
MergeSeries(in_files=files, affine_tolerance=1e-04).run()
249+
250+
233251
LABEL_MAPPINGS = {5: 1, 6: 1, 7: 2}
234252
LABEL_INPUT = np.arange(8).reshape(2, 2, 2)
235253
LABEL_OUTPUT = np.asarray([0, 1, 2, 3, 4, 1, 1, 2]).reshape(2, 2, 2)

0 commit comments

Comments
 (0)