def space_time_realign(Images,TR=2,numslices=None,SliceTime='asc_alt_2',RefScan=None): ''' 4D simultaneous slice timing and spatial realignment. Adapted from Alexis Roche's example script, and extend to be used for multiplex imaging sequences Inputs: Images: list of images, input as a list of strings numslices: for non-multiplex sequence, default to be the number of slices in the image. For multiplex sequence, enter as a tuple, such that the first element is the number of planes acquired in parallel between each other, and the second element is the number of slices of each parallel plane/slab SliceTime:enter as a string to specify how the slices are ordered. Choices are the following 1).'ascending': sequential ascending acquisition 2).'descending': sequential descending acquisition 3).'asc_alt_2': ascending interleaved, starting at first slice 4).'asc_alt_2_1': ascending interleaved, starting at the second slice 5).'desc_alt_2': descending interleaved, starting at last slice 6).'asc_alt_siemens': ascending interleaved, starting at the first slice if odd number of slices, or second slice if even number of slices 7).'asc_alt_half': ascending interleaved by half the volume 8).'desc_alt_half': descending interleaved by half the volume RefScan: reference volume for spatial realignment movement estimation ''' # load images runs = [load_image(run) for run in Images] # parse data info if numslices is None: numslices = runs[0].shape[2] numplanes = 1 elif isinstance(numslices,tuple): numslices = numslices[0] numplanes = numplanes[1] # parse slice timing according to the input slice_timing = getattr(timefuncs,SliceTime)(TR,numslices) #repeat the slice timing for multiplex seqquence slice_timing = np.tile(slice_timing,numplanes) # Spatio-temporal realigner assuming interleaved ascending slice order R = SpaceTimeRealign(runs, tr=TR, slice_times=slice_timing, slice_info=2, affine_class='Rigid') print('Slice times: %s' % slice_timing) # Estimate motion within- and between-sessions R.estimate(refscan=RefScan) # Resample data on a regular space+time lattice using 4d interpolation print('Saving results ...') for i in range(len(runs)): corr_run = R.resample(i) fname = os.path.join(os.path.split(Images[i])[0],'ra' + os.path.split(Images[i])[1]) save_image(corr_run, fname) print(fname)
def time_space_realign(run_fnames, TR, slice_times, slice_axis): run_imgs = [load_image(run) for run in run_fnames] # Spatio-temporal realigner R = SpaceTimeRealign(run_imgs, tr=TR, slice_times=slice_times, slice_info=(slice_axis, 1)) # Estimate motion within- and between-sessions R.estimate(refscan=None) # Save back out for i, fname in enumerate(run_fnames): corr_run = R.resample(i) pth, name = os.path.split(fname) processed_fname = os.path.join(pth, 'ra' + name) save_image(corr_run, processed_fname)
def _run_interface(self, runtime): from nipy import save_image, load_image all_ims = [load_image(fname) for fname in self.inputs.in_file] if not isdefined(self.inputs.slice_times): from nipy.algorithms.registration.groupwise_registration import SpaceRealign R = SpaceRealign(all_ims) else: from nipy.algorithms.registration import SpaceTimeRealign R = SpaceTimeRealign( all_ims, tr=self.inputs.tr, slice_times=self.inputs.slice_times, slice_info=self.inputs.slice_info, ) R.estimate(refscan=None) corr_run = R.resample() self._out_file_path = [] self._par_file_path = [] for j, corr in enumerate(corr_run): self._out_file_path.append( os.path.abspath( "corr_%s.nii.gz" % (split_filename(self.inputs.in_file[j])[1]) ) ) save_image(corr, self._out_file_path[j]) self._par_file_path.append( os.path.abspath("%s.par" % (os.path.split(self.inputs.in_file[j])[1])) ) mfile = open(self._par_file_path[j], "w") motion = R._transforms[j] # nipy does not encode euler angles. return in original form of # translation followed by rotation vector see: # http://en.wikipedia.org/wiki/Rodrigues'_rotation_formula for i, mo in enumerate(motion): params = [ "%.10f" % item for item in np.hstack((mo.translation, mo.rotation)) ] string = " ".join(params) + "\n" mfile.write(string) mfile.close() return runtime
def space_time_realign(Images,TR=2,numslices=None,SliceTime='asc_alt_2',RefScan=0,Prefix='ra'): ''' 4D simultaneous slice timing and spatial realignment. Adapted from Alexis Roche's example script, and extend to be used for multiplex imaging sequences Inputs: Images: list of images, input as a list of strings/paths to images numslices: for non-multiplex sequence, default to be the number of slices in the image. For multiplex sequence, enter as a tuple, such that the first element is the number of planes acquired in parallel between each other, and the second element is the number of slices of each parallel plane/slab, i.e. (numplanes,numslices) SliceTime:enter as a string to specify how the slices are ordered. Choices are the following 1).'ascending': sequential ascending acquisition 2).'descending': sequential descending acquisition 3).'asc_alt_2': ascending interleaved, starting at first slice 4).'asc_alt_2_1': ascending interleaved, starting at the second slice 5).'desc_alt_2': descending interleaved, starting at last slice 6).'asc_alt_siemens': ascending interleaved, starting at the first slice if odd number of slices, or second slice if even number of slices 7).'asc_alt_half': ascending interleaved by half the volume 8).'desc_alt_half': descending interleaved by half the volume RefScan: reference volume for spatial realignment movement estimation. Note that scan 0 is the first scan. Prefix: prefix of the new corrected images. Default is 'ra' Author: Alexis Roche, 2009. Edward Cui, February 2014 ''' # Load images runs = [load_image(run) for run in Images] # Parse data info if numslices is None: numslices = runs[0].shape[2] numplanes = 1 elif isinstance(numslices,tuple): (numplanes,numslices) = numslices else: numplanes = 1 # Print image info if numplanes>1: print('Running multiplex: %s' % numplanes) print('Number of slices: %s' % numslices) # Parse slice timing according to the input slice_timing = getattr(timefuncs,SliceTime)(numslices,TR) # Repeat the slice timing for multiplex seqquence slice_timing = np.tile(slice_timing,numplanes) # Print slice timing info print('Slice times: %s' % slice_timing) # Spatio-temporal realigner R = SpaceTimeRealign(runs, tr=TR, slice_times=slice_timing, slice_info=2) # Estimate motion within- and between-sessions print('Estimating motion ...') R.estimate(refscan=RefScan) # Resample data on a regular space+time lattice using 4d interpolation fname=[None]*len(Images) # output images mfname=[None]*len(Images) # output motion parameter files print('Saving results ...') for n in range(len(Images)): # extract motion parameters motionparams = np.array([np.concatenate((M.translation,M.rotation),axis=1) for M in R._transforms[n]]) # set motion parameter file name mfname[n] = os.path.join(os.path.split(Images[n])[0], 'rp_a0001.txt') # write the motion parameters to file np.savetxt(mfname[n],motionparams,fmt='%10.7e',delimiter='\t') # resample data corr_run = R.resample(n) # set image name fname[n] = os.path.join(os.path.split(Images[n])[0], Prefix + os.path.split(Images[n])[1]) # save image save_image(corr_run, fname[n]) print(fname[n]) return(fname,mfname)
import os from os.path import split as psplit, abspath import numpy as np from nipy.algorithms.registration import SpaceTimeRealign from nipy import load_image, save_image from nipy.utils import example_data # Input images are provided with the nipy-data package runnames = [ example_data.get_filename('fiac', 'fiac0', run + '.nii.gz') for run in ('run1', 'run2') ] runs = [load_image(run) for run in runnames] # Spatio-temporal realigner assuming interleaved ascending slice order R = SpaceTimeRealign(runs, tr=2.5, slice_times='asc_alt_2', slice_info=2) # If you are not sure what the above is doing, you can alternatively # declare slice times explicitly using the following equivalent code """ tr = 2.5 nslices = runs[0].shape[2] slice_times = (tr / float(nslices)) *\ np.argsort(range(0, nslices, 2) + range(1, nslices, 2)) print('Slice times: %s' % slice_times) R = SpaceTimeRealign(runs, tr=tr, slice_times=slice_times, slice_info=2) """ # Estimate motion within- and between-sessions R.estimate(refscan=None)
from __future__ import print_function # Python 2/3 compatibility import os from os.path import split as psplit, abspath import numpy as np from nipy.algorithms.registration import SpaceTimeRealign from nipy import load_image, save_image from nipy.utils import example_data # Input images are provided with the nipy-data package runnames = [example_data.get_filename('fiac', 'fiac0', run + '.nii.gz') for run in ('run1', 'run2')] runs = [load_image(run) for run in runnames] # Spatio-temporal realigner assuming interleaved ascending slice order R = SpaceTimeRealign(runs, tr=2.5, slice_times='asc_alt_2', slice_info=2) # If you are not sure what the above is doing, you can alternatively # declare slice times explicitly using the following equivalent code """ tr = 2.5 nslices = runs[0].shape[2] slice_times = (tr / float(nslices)) *\ np.argsort(range(0, nslices, 2) + range(1, nslices, 2)) print('Slice times: %s' % slice_times) R = SpaceTimeRealign(runs, tr=tr, slice_times=slice_times, slice_info=2) """ # Estimate motion within- and between-sessions R.estimate(refscan=None)