algorithms.slicetiming.timefuncs

Module: algorithms.slicetiming.timefuncs

Utility functions for returning slice times from number of slices and TR

Slice timing routines in nipy need a vector of slice times.

Slice times are vectors \(t_i\) with \(i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.

We like these vectors because they are unambiguous; the indices \(i\) refer to positions in space, and the values \(t_i\) refer to times.

But, there are many common slice timing regimes for which it’s easy to get the slice times once you know the volume acquisition time (the TR) and the number of slices.

For example, if you acquired the slices in a simple ascending order, and you have 10 slices and the TR was 2.0, then the slice times are:

>>> import numpy as np
>>> np.arange(10) / 10.  * 2.0
array([ 0. ,  0.2,  0.4,  0.6,  0.8,  1. ,  1.2,  1.4,  1.6,  1.8])

These are small convenience functions that accept the number of slices and the TR as input, and return a vector of slice times:

>>> ascending(10, 2.)
array([ 0. ,  0.2,  0.4,  0.6,  0.8,  1. ,  1.2,  1.4,  1.6,  1.8])

Functions

nipy.algorithms.slicetiming.timefuncs.st_01234(n_slices, TR)

Simple ascending slice sequence

slice 0 first, slice 1 second etc.

For example, for 5 slices and a TR of 1:

>>> st_01234(5, 1.)
array([ 0. ,  0.2,  0.4,  0.6,  0.8])

Note: slice 0 is the first slice in the voxel data block

Parameters:

n_slices : int

Number of slices in volume

TR : float

Time to acquire one full volume

Returns:

slice_times : (n_slices,) ndarray

Vectors \(t_i i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.

nipy.algorithms.slicetiming.timefuncs.st_02413(n_slices, TR)

Ascend alternate every second slice, starting at first slice

Collect slice 0 first, slice 2 second up to top. Then return to collect slice 1, slice 3 etc.

For example, for 5 slices and a TR of 1:

>>> st_02413(5, 1.)
array([ 0. ,  0.6,  0.2,  0.8,  0.4])

Note: slice 0 is the first slice in the voxel data block

Parameters:

n_slices : int

Number of slices in volume

TR : float

Time to acquire one full volume

Returns:

slice_times : (n_slices,) ndarray

Vectors \(t_i i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.

nipy.algorithms.slicetiming.timefuncs.st_03142(n_slices, TR)

Ascend alternate, where alternation is by half the volume

Collect slice 0 then slice ceil(n_slices / 2.) then slice 1 then slice ceil(nslices / 2.) + 1 etc.

For example, for 5 slices and a TR of 1:

>>> st_03142(5, 1.)
array([ 0. ,  0.4,  0.8,  0.2,  0.6])

Note: slice 0 is the first slice in the voxel data block

Parameters:

n_slices : int

Number of slices in volume

TR : float

Time to acquire one full volume

Returns:

slice_times : (n_slices,) ndarray

Vectors \(t_i i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.

nipy.algorithms.slicetiming.timefuncs.st_13024(n_slices, TR)

Ascend alternate every second slice, starting at second slice

Collect slice 1 first, slice 3 second up to top (highest numbered slice). Then return to collect slice 0, slice 2 etc. This order is rare except on Siemens acquisitions with an even number of slices. See st_odd0_even1() for this logic.

For example, for 5 slices and a TR of 1:

>>> st_13024(5, 1.)
array([ 0.4,  0. ,  0.6,  0.2,  0.8])

Note: slice 0 is the first slice in the voxel data block

Parameters:

n_slices : int

Number of slices in volume

TR : float

Time to acquire one full volume

Returns:

slice_times : (n_slices,) ndarray

Vectors \(t_i i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.

nipy.algorithms.slicetiming.timefuncs.st_41302(n_slices, TR)

Descend alternate, where alternation is by half the volume

Collect slice (n_slices - 1) then slice floor(nslices / 2.) - 1 then slice (n_slices - 2) then slice floor(nslices / 2.) - 2 etc.

For example, for 5 slices and a TR of 1:

>>> st_41302(5, 1.)
array([ 0.6,  0.2,  0.8,  0.4,  0. ])

Note: slice 0 is the first slice in the voxel data block

Parameters:

n_slices : int

Number of slices in volume

TR : float

Time to acquire one full volume

Returns:

slice_times : (n_slices,) ndarray

Vectors \(t_i i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.

nipy.algorithms.slicetiming.timefuncs.st_42031(n_slices, TR)

Descend alternate every second slice, starting at last slice

Collect slice (n_slices - 1) first, slice (nslices - 3) second down to bottom (lowest numbered slice). Then return to collect slice (n_slices -2), slice (n_slices - 4) etc.

For example, for 5 slices and a TR of 1:

>>> st_42031(5, 1.)
array([ 0.4,  0.8,  0.2,  0.6,  0. ])

Note: slice 0 is the first slice in the voxel data block

Parameters:

n_slices : int

Number of slices in volume

TR : float

Time to acquire one full volume

Returns:

slice_times : (n_slices,) ndarray

Vectors \(t_i i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.

nipy.algorithms.slicetiming.timefuncs.st_43210(n_slices, TR)

Simple descending slice sequence

slice n_slices-1 first, slice n_slices - 2 second etc.

For example, for 5 slices and a TR of 1:

>>> st_43210(5, 1.)
array([ 0.8,  0.6,  0.4,  0.2,  0. ])

Note: slice 0 is the first slice in the voxel data block

Parameters:

n_slices : int

Number of slices in volume

TR : float

Time to acquire one full volume

Returns:

slice_times : (n_slices,) ndarray

Vectors \(t_i i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.

nipy.algorithms.slicetiming.timefuncs.st_odd0_even1(n_slices, TR)

Ascend alternate starting at slice 0 for odd, slice 1 for even n_slices

Acquisitions with alternating ascending slices from Siemens scanners often seem to have this behavior as default - see:

This means we use the st_02413() algorithm if n_slices is odd, and the st_13024() algorithm if n_slices is even.

For example, for 4 slices and a TR of 1:

>>> st_odd0_even1(4, 1.)
array([ 0.5 ,  0.  ,  0.75,  0.25])

5 slices and a TR of 1:

>>> st_odd0_even1(5, 1.)
array([ 0. ,  0.6,  0.2,  0.8,  0.4])

Note: slice 0 is the first slice in the voxel data block

Parameters:

n_slices : int

Number of slices in volume

TR : float

Time to acquire one full volume

Returns:

slice_times : (n_slices,) ndarray

Vectors \(t_i i = 0 ... N\) of times, one for each slice, where \(t_i\) gives the time at which slice number \(i\) was acquired, relative to the beginning of the volume acquisition.