def test_scalar(): """ Test the introspection and creation of CIFTI-2 ScalarAxis axes """ sc = get_scalar() assert len(sc) == 3 assert isinstance(sc, axes.ScalarAxis) assert (sc.name == ['one', 'two', 'three']).all() assert (sc.meta == [{}] * 3).all() assert sc[1] == ('two', {}) sc2 = sc + sc assert len(sc2) == 6 assert (sc2.name == ['one', 'two', 'three', 'one', 'two', 'three']).all() assert (sc2.meta == [{}] * 6).all() assert sc2[:3] == sc assert sc2[3:] == sc sc.meta[1]['a'] = 3 assert 'a' not in sc.meta # test equalities assert sc != get_label() with assert_raises(Exception): sc + get_label() sc_other = deepcopy(sc) assert sc == sc_other assert sc != sc_other[:2] assert sc == sc_other[:] sc_other.name[0] = 'new_name' assert sc != sc_other sc_other = deepcopy(sc) sc_other.meta[0]['new_key'] = 'new_entry' assert sc != sc_other sc.meta[0]['new_key'] = 'new_entry' assert sc == sc_other # test constructor assert axes.ScalarAxis(['scalar_name'], [{}]) == axes.ScalarAxis(['scalar_name']) with assert_raises(ValueError): axes.ScalarAxis([['scalar_name']]) # wrong shape with assert_raises(ValueError): axes.ScalarAxis(['scalar_name'], [{}, {}]) # wrong size
def get_scalar(): """ Generates a practice ScalarAxis axis with names ('one', 'two', 'three') Returns ------- ScalarAxis axis """ return axes.ScalarAxis(['one', 'two', 'three'])
def bad_cifti(): import nibabel.cifti2.cifti2 as ncif import nibabel.cifti2.cifti2_axes as ncax np.random.seed(seed=1) data = np.random.uniform(size=(1, 50)) ser_ax = ncax.ScalarAxis(name=["Data"]) h = ncif.Cifti2Header.from_axes((ser_ax, ser_ax)) c = ncif.Cifti2Image(data, h) return c
def cifti(): import nibabel.cifti2.cifti2 as ncif import nibabel.cifti2.cifti2_axes as ncax np.random.seed(seed=1) verts = np.arange(0, 100, 2) data = np.random.uniform(size=(1, 50)) ser_ax = ncax.ScalarAxis(name=["Data"]) bm_ax = ncax.BrainModelAxis(name="CORTEX_LEFT", vertex=verts, affine=np.eye(4), nvertices={"CORTEX_LEFT": verts.shape[0]}) h = ncif.Cifti2Header.from_axes((ser_ax, bm_ax)) c = ncif.Cifti2Image(data, h) return c
def test_extract_dense(): vol_bm = volumetric_brain_model() surf_bm = surface_brain_model() for bm in (vol_bm + surf_bm, surf_bm + vol_bm): for ndim, no_other_axis in ((1, True), (2, False), (2, True)): if ndim == 1: data = cifti.DenseCifti(gen_data([bm]), [bm]) else: scl = cifti2_axes.ScalarAxis(['A', 'B', 'C']) data = cifti.DenseCifti(gen_data([scl, bm]), [None if no_other_axis else scl, bm]) # extract volume ref_arr = data.arr[..., data.brain_model_axis.volume_mask] vol_image = data.to_image(fill=np.nan) if ndim == 1: assert vol_image.shape == data.brain_model_axis.volume_shape else: assert vol_image.shape == data.brain_model_axis.volume_shape + ( 3, ) assert np.isfinite( vol_image.data).sum() == len(vol_bm) * (3 if ndim == 2 else 1) testing.assert_equal(vol_image.data[tuple(vol_bm.voxel.T)], ref_arr.T) from_image = cifti.DenseCifti.from_image(vol_image) assert from_image.brain_model_axis == vol_bm testing.assert_equal(from_image.arr, ref_arr) # extract surface ref_arr = data.arr[..., data.brain_model_axis.surface_mask] mask, surf_data = data.surface('cortex', partial=True) assert surf_data.shape[-1] < 100 testing.assert_equal(ref_arr, surf_data) testing.assert_equal(surf_bm.vertex, mask) surf_data_full = data.surface('cortex', fill=np.nan) assert surf_data_full.shape[-1] == 100 mask_full = np.isfinite(surf_data_full) if ndim == 2: assert (mask_full.any(0) == mask_full.all(0)).all() mask_full = mask_full[0] assert mask_full.sum() == len(surf_bm) assert mask_full[..., mask].sum() == len(surf_bm) testing.assert_equal(surf_data_full[..., mask_full], ref_arr)
def to_cifti(self, default_axis=None): """ Create a CIFTI image from the data :param default_axis: What to use as an axis along any undefined dimensions - By default an error is raised - if set to "scalar" a ScalarAxis is used with names of "default {index}" - if set to "series" a SeriesAxis is used :return: nibabel CIFTI image """ if any(ax is None for ax in self.axes): if default_axis is None: raise ValueError( "Can not store to CIFTI without defining what is stored along each dimension" ) elif default_axis == 'scalar': def get_axis(n: int): return cifti2_axes.ScalarAxis( [f'default {idx + 1}' for idx in range(n)]) elif default_axis == 'series': def get_axis(n: int): return cifti2_axes.SeriesAxis(0, 1, n) else: raise ValueError( f"default_axis should be set to None, 'scalar', or 'series', not {default_axis}" ) new_axes = [ get_axis(sz) if ax is None else ax for ax, sz in zip(self.axes, self.arr.shape) ] else: new_axes = list(self.axes) data = self.arr if data.ndim == 1: # CIFTI axes are always at least 2D data = data[None, :] new_axes.insert(0, cifti2_axes.ScalarAxis(['default'])) return nib.Cifti2Image(data, header=new_axes)
def test_io_cifti(): for cifti_class, cifti_type, main_axis_options in ( (cifti.DenseCifti, 'd', (volumetric_brain_model(), surface_brain_model(), volumetric_brain_model() + surface_brain_model())), (cifti.ParcelCifti, 'p', (volumetric_parcels(), surface_parcels(), volumetric_parcels() + surface_parcels())), ): for main_axis in main_axis_options: with tests.testdir(): data_1d = cifti_class(gen_data([main_axis]), [main_axis]) check_io(data_1d, f'{cifti_type}scalar') connectome = cifti_class(gen_data([main_axis, main_axis]), (main_axis, main_axis)) check_io(connectome, f'{cifti_type}conn') scalar_axis = cifti2_axes.ScalarAxis(['A', 'B', 'C']) scalar = cifti_class(gen_data([scalar_axis, main_axis]), (scalar_axis, main_axis)) check_io(scalar, f'{cifti_type}scalar') label_axis = cifti2_axes.LabelAxis( ['A', 'B', 'C'], {1: ('some parcel', (1, 0, 0, 1))}) label = cifti_class(gen_data([label_axis, main_axis]), (label_axis, main_axis)) check_io(label, f'{cifti_type}label') series_axis = cifti2_axes.SeriesAxis(10, 3, 50, unit='HERTZ') series = cifti_class(gen_data([series_axis, main_axis]), (series_axis, main_axis)) check_io(series, f'{cifti_type}tseries') if cifti_type == 'd': parcel_axis = surface_parcels() dpconn = cifti_class(gen_data([parcel_axis, main_axis]), (parcel_axis, main_axis)) check_io(dpconn, 'dpconn') else: dense_axis = surface_brain_model() pdconn = cifti_class(gen_data([dense_axis, main_axis]), (dense_axis, main_axis)) check_io(pdconn, 'pdconn')
def test_extract_parcel(): vol_parcel, vol_mask = volumetric_parcels(return_mask=True) surf_parcel, surf_mask = surface_parcels(return_mask=True) parcel = vol_parcel + surf_parcel for ndim, no_other_axis in ((1, True), (2, False), (2, True)): if ndim == 1: data = cifti.ParcelCifti(gen_data([parcel]), [parcel]) else: scl = cifti2_axes.ScalarAxis(['A', 'B', 'C']) data = cifti.ParcelCifti(gen_data([scl, parcel]), [None if no_other_axis else scl, parcel]) # extract volume vol_image = data.to_image(fill=np.nan) if ndim == 1: assert vol_image.shape == data.parcel_axis.volume_shape else: assert vol_image.shape == data.parcel_axis.volume_shape + (3, ) assert np.isfinite(vol_image.data).sum() == np.sum( vol_mask != 0) * (3 if ndim == 2 else 1) if ndim == 1: testing.assert_equal(vol_mask != 0, np.isfinite(vol_image.data)) for idx in range(1, 5): testing.assert_allclose(vol_image.data[vol_mask == idx], data.arr[..., idx - 1]) else: for idx in range(3): testing.assert_equal(vol_mask != 0, np.isfinite(vol_image.data[..., idx])) for idx2 in range(1, 5): testing.assert_allclose( vol_image.data[vol_mask == idx2, idx], data.arr[idx, idx2 - 1]) # extract surface mask, surf_data = data.surface('cortex', partial=True) assert surf_data.shape[-1] == (surf_mask != 0).sum() assert (surf_mask[mask] != 0).all() print(data.arr) for idx in range(1, 5): if ndim == 1: testing.assert_equal(surf_data.T[surf_mask[mask] == idx], data.arr[idx + 3]) else: for idx2 in range(3): testing.assert_equal( surf_data.T[surf_mask[mask] == idx, idx2], data.arr[idx2, idx + 3]) surf_data_full = data.surface('cortex', partial=False) assert surf_data_full.shape[-1] == 100 if ndim == 1: testing.assert_equal(np.isfinite(surf_data_full), surf_mask != 0) for idx in range(1, 5): testing.assert_equal(surf_data_full.T[surf_mask == idx], data.arr[idx + 3]) else: for idx2 in range(3): testing.assert_equal( np.isfinite(surf_data_full)[idx2], (surf_mask != 0)) for idx in range(1, 5): testing.assert_equal( surf_data_full.T[surf_mask == idx, idx2], data.arr[idx2, idx + 3])
def get_axis(n: int): return cifti2_axes.ScalarAxis( [f'default {idx + 1}' for idx in range(n)])