Skip to content

Commit 3f1ae40

Browse files
authored
Merge pull request #477 from mgxd/fix/cifti-orientation
BF: Ensure BOLD and label orientations are equal
2 parents bfffaf8 + e1a8a12 commit 3f1ae40

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

niworkflows/interfaces/cifti.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ def _create_cifti_image(bold_file, label_file, bold_surfs, annotation_files, tr,
318318
warnings.warn("Resampling bold volume to match label dimensions")
319319
bold_img = resample_to_img(bold_img, label_img)
320320

321+
bold_img = _reorient_image(bold_img, target_img=label_img)
322+
321323
bold_data = bold_img.get_fdata(dtype='float32')
322324
timepoints = bold_img.shape[3]
323325
label_data = np.asanyarray(label_img.dataobj).astype('int16')
@@ -422,3 +424,66 @@ def _create_cifti_image(bold_file, label_file, bold_surfs, annotation_files, tr,
422424
out_file = "{}.dtseries.nii".format(split_filename(bold_file)[1])
423425
ci.save(img, out_file)
424426
return Path.cwd() / out_file
427+
428+
429+
def _reorient_image(img, *, target_img=None, orientation=None):
430+
"""
431+
Coerce an image to a target orientation.
432+
433+
.. note::
434+
Only RAS -> LAS conversion is currently supported
435+
436+
Parameters
437+
----------
438+
img : :obj:`SpatialImage`
439+
image to be reoriented
440+
target_img : :obj:`SpatialImage`, optional
441+
target in desired orientation
442+
orientation : :obj:`str` or :obj:`tuple`, optional
443+
desired orientation, if no target image is provided
444+
445+
.. testsetup::
446+
>>> img = nb.load(Path(test_data) / 'testRobustMNINormalizationRPTMovingWarpedImage.nii.gz')
447+
>>> las_img = img.as_reoriented([[0, -1], [1, 1], [2, 1]])
448+
449+
Examples
450+
--------
451+
>>> nimg = _reorient_image(img, target_img=img)
452+
>>> nb.aff2axcodes(nimg.affine)
453+
('R', 'A', 'S')
454+
455+
>>> nimg = _reorient_image(img, target_img=las_img)
456+
>>> nb.aff2axcodes(nimg.affine)
457+
('L', 'A', 'S')
458+
459+
>>> nimg = _reorient_image(img, orientation='LAS')
460+
>>> nb.aff2axcodes(nimg.affine)
461+
('L', 'A', 'S')
462+
463+
>>> _reorient_image(img, orientation='LPI')
464+
Traceback (most recent call last):
465+
...
466+
NotImplementedError: Cannot reorient ...
467+
468+
>>> _reorient_image(img)
469+
Traceback (most recent call last):
470+
...
471+
RuntimeError: No orientation ...
472+
473+
"""
474+
orient0 = nb.aff2axcodes(img.affine)
475+
if target_img is not None:
476+
orient1 = nb.aff2axcodes(target_img.affine)
477+
elif orientation is not None:
478+
orient1 = tuple(orientation)
479+
else:
480+
raise RuntimeError("No orientation to reorient to!")
481+
482+
if orient0 == orient1: # already in desired orientation
483+
return img
484+
elif orient0 == tuple('RAS') and orient1 == tuple('LAS'): # RAS -> LAS
485+
return img.as_reoriented([[0, -1], [1, 1], [2, 1]])
486+
else:
487+
raise NotImplementedError(
488+
"Cannot reorient {0} to {1}.".format(orient0, orient1)
489+
)

0 commit comments

Comments
 (0)