def test_save_vols():
    # setup
    n_scans = 10
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # create 4D film
    film = create_random_image(ndim=4, n_scans=n_scans)
    threeD_vols = nibabel.four_to_three(film)

    # save vols manually
    film_filename = os.path.join(output_dir, "film.nii.gz")
    threeD_vols_filenames = [os.path.join(output_dir, "fMETHODS-%06i" % i) for i in range(len(threeD_vols))]

    # check saving seperate 3D vols
    for stuff in [film, threeD_vols]:
        if isinstance(stuff, list):
            basenames = [os.path.basename(x) for x in threeD_vols_filenames]
        else:
            basenames = os.path.basename(film_filename)
        for concat in [False, True]:
            for bn in [None, basenames]:
                saved_vols_filenames = save_vols(stuff, output_dir, ext=".nii.gz", concat=concat, basenames=bn)
                if not concat and isinstance(stuff, list):
                    assert_true(isinstance(saved_vols_filenames, list))
                    assert_equal(len(saved_vols_filenames), n_scans)
                    if not bn is None:
                        assert_equal(os.path.basename(saved_vols_filenames[7]), "fMETHODS-000007.nii.gz")
                else:
                    assert_true(isinstance(saved_vols_filenames, basestring))
                    assert_true(saved_vols_filenames.endswith(".nii.gz"), msg=saved_vols_filenames)
                    assert_true(is_4D(check_niimg_4d(saved_vols_filenames)))
Exemple #2
0
def load_vols(niimgs):
    """Loads a nifti image (or a bail of) into a list qof 3D volumes.

    Parameters
    ----------
    niimgs: 3 or 4D Niimg-like object
        If niimgs is an iterable, checks if data is really 4D. Then,
        considering that it is a list of niimg and load them one by one.
        If niimg is a string, consider it as a path to Nifti image and
        call nibabel.load on it. If it is an object, check if get_data
        and get_affine methods are present, raise an Exception otherwise.

    Returns
    -------
    niimgs_: list of nifti image objects
        The loaded volumes.
    """
    # try loading 4d
    try:
        niimgs = list(check_niimg_4d(niimgs, return_iterator=True))
    except TypeError:
        # probably not 4d
        niimgs = [check_niimg(niimgs)]
    except ValueError:
        # probably inconsisten affines
        pass
    try:
        # try loading volumes one-by-one
        if isinstance(niimgs, _basestring):
            niimgs = [niimgs]
        return [check_niimg(niimg, ensure_ndim=3) for niimg in niimgs]
    except TypeError:
        pass

    # collect the loaded volumes into a list
    if is_niimg(niimgs):
        # should be 3d, squash 4th dimension otherwise
        if niimgs.shape[-1] == 1:
            return [
                nibabel.Nifti1Image(niimgs.get_data()[:, :, :, 0],
                                    niimgs.get_affine())
            ]
        else:
            return list(iter_img(niimgs))
    else:
        niimgs = list(niimgs)
        if len(niimgs) == 1:
            niimgs = niimgs[0]
        return list(iter_img(niimgs))
Exemple #3
0
def load_vols(niimgs):
    """Loads a nifti image (or a bail of) into a list qof 3D volumes.

    Parameters
    ----------
    niimgs: 3 or 4D Niimg-like object
        If niimgs is an iterable, checks if data is really 4D. Then,
        considering that it is a list of niimg and load them one by one.
        If niimg is a string, consider it as a path to Nifti image and
        call nibabel.load on it. If it is an object, check if get_data
        and get_affine methods are present, raise an Exception otherwise.

    Returns
    -------
    niimgs_: list of nifti image objects
        The loaded volumes.
    """
    # try loading 4d
    try:
        niimgs = list(check_niimg_4d(niimgs, return_iterator=True))
    except TypeError:
        # probably not 4d
        niimgs = [check_niimg(niimgs)]
    except ValueError:
        # probably inconsisten affines
        pass
    try:
        # try loading volumes one-by-one
        if isinstance(niimgs, _basestring): niimgs = [niimgs]
        return [check_niimg(niimg, ensure_ndim=3) for niimg in niimgs]
    except TypeError:
        pass

    # collect the loaded volumes into a list
    if is_niimg(niimgs):
        # should be 3d, squash 4th dimension otherwise
        if niimgs.shape[-1] == 1:
            return [nibabel.Nifti1Image(niimgs.get_data()[:, :, :, 0],
                                        niimgs.get_affine())]
        else:
            return list(iter_img(niimgs))
    else:
        niimgs = list(niimgs)
        if len(niimgs) == 1: niimgs = niimgs[0]
        return list(iter_img(niimgs))
def test_save_vols():
    # setup
    n_scans = 10
    output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3])
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # create 4D film
    film = create_random_image(ndim=4, n_scans=n_scans)
    threeD_vols = nibabel.four_to_three(film)

    # save vols manually
    film_filename = os.path.join(output_dir, 'film.nii.gz')
    threeD_vols_filenames = [os.path.join(output_dir, 'fMETHODS-%06i' % i)
                             for i in range(len(threeD_vols))]

    # check saving seperate 3D vols
    for stuff in [film, threeD_vols]:
        if isinstance(stuff, list):
            basenames = [os.path.basename(x)
                         for x in threeD_vols_filenames]
        else:
            basenames = os.path.basename(film_filename)
        for concat in [False, True]:
            for bn in [None, basenames]:
                saved_vols_filenames = save_vols(stuff,
                                                 output_dir,
                                                 ext='.nii.gz',
                                                 concat=concat,
                                                 basenames=bn
                                                 )
                if not concat and isinstance(stuff, list):
                    assert_true(isinstance(
                        saved_vols_filenames, list))
                    assert_equal(len(saved_vols_filenames),
                                 n_scans)
                    if not bn is None:
                        assert_equal(os.path.basename(saved_vols_filenames[7]),
                                     'fMETHODS-000007.nii.gz')
                else:
                    assert_true(isinstance(saved_vols_filenames, basestring))
                    assert_true(saved_vols_filenames.endswith('.nii.gz'),
                                msg=saved_vols_filenames)
                    assert_true(is_4D(check_niimg_4d(
                                saved_vols_filenames)))
Exemple #5
0
def time_slice_diffs(img):
    ''' Time-point to time-point differences over volumes and slices

    We think of the passed array as an image.
    The last dimension is assumed to be time.

    Parameters
    ----------
    img: 4D Niimg-like
         the input (4D) image

    Returns
    -------
    results : dict

        ``T`` is the number of time points (``arr.shape[time_axis]``)

        ``S`` is the number of slices (``arr.shape[slice_axis]``)

        ``v`` is the shape of a volume (``rollimg(arr, time_axis)[0].shape``)

        ``d2[t]`` is the volume of squared differences between voxels at
        time point ``t`` and time point ``t+1``

        `results` has keys:

        * 'volume_mean_diff2' : (T-1,) array
           array containing the mean (over voxels in volume) of the
           squared difference from one time point to the next
        * 'slice_mean_diff2' : (T-1, S) array
           giving the mean (over voxels in slice) of the squared difference
           from one time point to the next, one value per slice, per
           timepoint
        * 'volume_means' : (T,) array
           mean over voxels for each volume ``vol[t] for t in 0:T``
        * 'slice_diff2_max_vol' : v[:] array
           volume, of same shape as input time point volumes, where each slice
           is is the slice from ``d2[t]`` for t in 0:T-1, that has the largest
           variance across ``t``. Thus each slice in the volume may well result
           from a different difference time point.
        * 'diff2_mean_vol`` : v[:] array
           volume with the mean of ``d2[t]`` across t for t in 0:T-1.

    '''
    img = check_niimg_4d(img)
    shape = img.shape
    T = shape[-1]
    S = shape[-2]  # presumably the slice axis -- to be reconsidered ?

    # loop over time points to save memory
    # initialize the results
    slice_squared_differences = np.empty((T - 1, S))
    vol_mean = np.empty((T,))
    diff_mean_vol = np.zeros(shape[:3])
    slice_diff_max_vol = np.zeros(shape[:3])
    slice_diff_max = np.zeros(S)
    arr = img.get_data()  # inefficient ??
    last_vol = arr[..., 0]
    vol_mean[0] = np.nanmean(last_vol)

    # loop over scans: increment statistics
    for vol_index in range(0, T - 1):
        current_vol = arr[..., vol_index + 1]  # shape vol_shape
        vol_mean[vol_index + 1] = np.nanmean(current_vol)
        squared_diff = (current_vol - last_vol) ** 2
        mask = np.isfinite(squared_diff)
        diff_mean_vol[mask] += squared_diff[mask]
        slice_squared_differences[vol_index] = np.nanmean(
            np.nanmean(squared_diff, 0), 0)
        # check whether we have found a highest-diff slice
        larger_diff = slice_squared_differences[vol_index] > slice_diff_max
        if any(larger_diff):
            slice_diff_max[larger_diff] =\
                slice_squared_differences[vol_index][larger_diff]
            slice_diff_max_vol[..., larger_diff] =\
                squared_diff[..., larger_diff]
        last_vol = current_vol
    vol_squared_differences = np.nanmean(slice_squared_differences, 1)
    diff_mean_vol /= (T - 1)

    # Remove remaining Nans
    # Nans may legitimally remain in slice_squared_differences
    slice_squared_differences[np.isnan(slice_squared_differences)] = 0
    # and also in slice_diff_max_vol
    slice_diff_max_vol[np.isnan(slice_diff_max_vol)] = 0

    # Return the outputs as images
    affine = img.get_affine()
    diff2_mean_vol = nib.Nifti1Image(diff_mean_vol, affine)
    slice_diff2_max_vol = nib.Nifti1Image(slice_diff_max_vol, affine)
    return {'volume_mean_diff2': vol_squared_differences,
            'slice_mean_diff2': slice_squared_differences,
            'volume_means': vol_mean,
            'diff2_mean_vol': diff2_mean_vol,
            'slice_diff2_max_vol': slice_diff2_max_vol,
            'session_length': T}
Exemple #6
0
def time_slice_diffs(img):
    ''' Time-point to time-point differences over volumes and slices

    We think of the passed array as an image.
    The last dimension is assumed to be time.

    Parameters
    ----------
    img: 4D Niimg-like
         the input (4D) image

    Returns
    -------
    results : dict

        ``T`` is the number of time points (``arr.shape[time_axis]``)

        ``S`` is the number of slices (``arr.shape[slice_axis]``)

        ``v`` is the shape of a volume (``rollimg(arr, time_axis)[0].shape``)

        ``d2[t]`` is the volume of squared differences between voxels at
        time point ``t`` and time point ``t+1``

        `results` has keys:

        * 'volume_mean_diff2' : (T-1,) array
           array containing the mean (over voxels in volume) of the
           squared difference from one time point to the next
        * 'slice_mean_diff2' : (T-1, S) array
           giving the mean (over voxels in slice) of the squared difference
           from one time point to the next, one value per slice, per
           timepoint
        * 'volume_means' : (T,) array
           mean over voxels for each volume ``vol[t] for t in 0:T``
        * 'slice_diff2_max_vol' : v[:] array
           volume, of same shape as input time point volumes, where each slice
           is is the slice from ``d2[t]`` for t in 0:T-1, that has the largest
           variance across ``t``. Thus each slice in the volume may well result
           from a different difference time point.
        * 'diff2_mean_vol`` : v[:] array
           volume with the mean of ``d2[t]`` across t for t in 0:T-1.

    '''
    img = check_niimg_4d(img)
    shape = img.shape
    T = shape[-1]
    S = shape[-2]  # presumably the slice axis -- to be reconsidered ?

    # loop over time points to save memory
    # initialize the results
    slice_squared_differences = np.empty((T - 1, S))
    vol_mean = np.empty((T,))
    diff_mean_vol = np.zeros(shape[:3])
    slice_diff_max_vol = np.zeros(shape[:3])
    slice_diff_max = np.zeros(S)
    arr = img.get_data()  # inefficient ??
    last_vol = arr[..., 0]
    vol_mean[0] = last_vol.mean()

    # loop over scans: increment statistics
    for vol_index in range(0, T - 1):
        current_vol = arr[..., vol_index + 1]  # shape vol_shape
        vol_mean[vol_index + 1] = current_vol.mean()
        squared_diff = (current_vol - last_vol) ** 2
        diff_mean_vol += squared_diff
        slice_squared_differences[vol_index] = squared_diff.mean(0).mean(0)
        # check whether we have found a highest-diff slice
        larger_diff = slice_squared_differences[vol_index] > slice_diff_max
        if any(larger_diff):
            slice_diff_max[larger_diff] =\
                slice_squared_differences[vol_index][larger_diff]
            slice_diff_max_vol[..., larger_diff] =\
                squared_diff[..., larger_diff]
        last_vol = current_vol
    vol_squared_differences = slice_squared_differences.mean(1)
    diff_mean_vol /= (T - 1)

    # Return the outputs as images
    affine = img.get_affine()
    diff2_mean_vol = nib.Nifti1Image(diff_mean_vol, affine)
    slice_diff2_max_vol = nib.Nifti1Image(slice_diff_max_vol, affine)
    return {'volume_mean_diff2': vol_squared_differences,
            'slice_mean_diff2': slice_squared_differences,
            'volume_means': vol_mean,
            'diff2_mean_vol': diff2_mean_vol,
            'slice_diff2_max_vol': slice_diff2_max_vol,
            'session_length': T}