@@ -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