예제 #1
0
def test_matrix():
    m = ci.Cifti2Matrix()
    assert_raises(TypeError, m, setattr, 'metadata', ci.Cifti2Parcel())
    assert_raises(TypeError, m.__setitem__, 0, ci.Cifti2Parcel())
    assert_raises(TypeError, m.insert, 0, ci.Cifti2Parcel())

    mim_none = ci.Cifti2MatrixIndicesMap(None, 'CIFTI_INDEX_TYPE_LABELS')
    mim_0 = ci.Cifti2MatrixIndicesMap(0, 'CIFTI_INDEX_TYPE_LABELS')
    mim_1 = ci.Cifti2MatrixIndicesMap(1, 'CIFTI_INDEX_TYPE_LABELS')
    mim_01 = ci.Cifti2MatrixIndicesMap([0, 1], 'CIFTI_INDEX_TYPE_LABELS')

    assert_raises(ci.Cifti2HeaderError, m.insert, 0, mim_none)
    assert_equal(m.mapped_indices, [])

    h = ci.Cifti2Header(matrix=m)
    assert_equal(m.mapped_indices, [])
    m.insert(0, mim_0)
    assert_equal(h.mapped_indices, [0])
    assert_equal(h.number_of_mapped_indices, 1)
    assert_raises(ci.Cifti2HeaderError, m.insert, 0, mim_0)
    assert_raises(ci.Cifti2HeaderError, m.insert, 0, mim_01)
    m[0] = mim_1
    assert_equal(list(m.mapped_indices), [1])
    m.insert(0, mim_0)
    assert_equal(list(sorted(m.mapped_indices)), [0, 1])
    assert_equal(h.number_of_mapped_indices, 2)
    assert_equal(h.get_index_map(0), mim_0)
    assert_equal(h.get_index_map(1), mim_1)
    assert_raises(ci.Cifti2HeaderError, h.get_index_map, 2)
예제 #2
0
def yeo_to_91k(dlabel, medial_wall, reference, out):
    """Convert Yeo-style dlabels (Yeo and Schaefer parcellations) to 91k 
    grayordinate space
    
    The Yeo lab generates dlabel's inclusive of medial wall vertices and only 
    for the cortical surfaces. This is different from how typical dlabels are 
    formatted, which exclude medial wall vertices and include voxels from all 
    subcortical and cerebellar structures (i.e. the full 91k grayordinate 
    space). This function corrects Yeo dlabels to proper 91k grayordinates.  

    Parameters
    ----------
    dlabel : str
        A Yeo-style .dlabel.nii atlas
    medial_wall : str
        HCP medial wall mask (.dlabel.nii)
    reference : str
        A reference .dlabel.nii file with 91k grayordinates and all brain 
        models included
    out : str
        Output 91k grayordinate .dlabel.nii file
    """
    dlabel = nib.load(dlabel)
    medial_wall = nib.load(medial_wall)
    ref = nib.load(reference)

    # remove medial wall vertices
    array = dlabel.get_fdata()
    corrected_array = array[np.logical_not(medial_wall.get_fdata())]

    # expand to 91k
    grayordinates = np.zeros(ref.shape)
    grayordinates[0, :corrected_array.shape[0]] = corrected_array

    # make header
    labels = dlabel.header.get_axis(index=0).label[0]
    label_table = ci.Cifti2LabelTable()
    for key, (tag, rgba) in labels.items():
        label_table[key] = ci.Cifti2Label(key, tag, *rgba)

    maps = [ci.Cifti2NamedMap('labels', ci.Cifti2MetaData({}), label_table)]
    label_map = ci.Cifti2MatrixIndicesMap(
        applies_to_matrix_dimension=(0, ),
        indices_map_to_data_type='CIFTI_INDEX_TYPE_LABELS',
        maps=maps)
    model_map = ci.Cifti2MatrixIndicesMap(
        applies_to_matrix_dimension=(1, ),
        indices_map_to_data_type='CIFTI_INDEX_TYPE_BRAIN_MODELS',
        maps=list(ref.header.get_index_map(1).brain_models))
    model_map.volume = ref.header.get_index_map(1).volume

    matrix = ci.Cifti2Matrix()
    matrix.append(label_map)
    matrix.append(model_map)
    hdr = ci.Cifti2Header(matrix)

    out_dtseries = ci.Cifti2Image(grayordinates, hdr)
    out_dtseries.to_filename(out)
    return out
예제 #3
0
def dlabel_to_dtseries(dlabel, out, n=10):
    """Create a mock .dtseries.nii from an .dlabel file

    All timepoints (rows) in .dtseries.nii are duplicates of the .dlabel array.
    This enables a way to verify that expected data is correctly extracted 
    (e.g., label 1 should extract a timeseries of all 1's, etc). 

    Parameters
    ----------
    dlabel : str
        File name of a .dlabel.nii file
    out : str
        File name of output .dtseries.nii
    n : int, optional
        Number of timepoints to generate, by default 100
    """

    dlabel = nib.load(dlabel)

    # imitate data with TR=2
    label_array = dlabel.get_fdata().ravel()
    tseries = np.tile(label_array, (n, 1))
    data_map = ci.Cifti2MatrixIndicesMap(
        applies_to_matrix_dimension=(0, ),
        indices_map_to_data_type='CIFTI_INDEX_TYPE_SERIES',
        number_of_series_points=tseries.shape[0],
        series_start=0,
        series_step=2,
        series_exponent=0,
        series_unit='SECOND')
    # take brain models from dlabel
    model_map = ci.Cifti2MatrixIndicesMap(
        applies_to_matrix_dimension=(1, ),
        indices_map_to_data_type='CIFTI_INDEX_TYPE_BRAIN_MODELS',
        maps=list(dlabel.header.get_index_map(1).brain_models))
    volume = dlabel.header.get_index_map(1).volume
    if volume is not None:
        model_map.volume = dlabel.header.get_index_map(1).volume

    # make header
    matrix = ci.Cifti2Matrix()
    matrix.append(data_map)
    matrix.append(model_map)
    hdr = ci.Cifti2Header(matrix)

    out_dtseries = ci.Cifti2Image(tseries, hdr)
    out_dtseries.to_filename(out)
    return out
예제 #4
0
def create_geometry_map(applies_to_matrix_dimension):
    voxels = ci.Cifti2VoxelIndicesIJK(brain_models[0][1])
    left_thalamus = ci.Cifti2BrainModel(index_offset=0,
                                        index_count=4,
                                        model_type='CIFTI_MODEL_TYPE_VOXELS',
                                        brain_structure=brain_models[0][0],
                                        voxel_indices_ijk=voxels)

    vertices = ci.Cifti2VertexIndices(np.array(brain_models[1][1]))
    left_cortex = ci.Cifti2BrainModel(index_offset=4,
                                      index_count=5,
                                      model_type='CIFTI_MODEL_TYPE_SURFACE',
                                      brain_structure=brain_models[1][0],
                                      vertex_indices=vertices)
    left_cortex.surface_number_of_vertices = number_of_vertices

    vertices = ci.Cifti2VertexIndices(np.array(brain_models[2][1]))
    right_cortex = ci.Cifti2BrainModel(index_offset=9,
                                       index_count=1,
                                       model_type='CIFTI_MODEL_TYPE_SURFACE',
                                       brain_structure=brain_models[2][0],
                                       vertex_indices=vertices)
    right_cortex.surface_number_of_vertices = number_of_vertices

    volume = ci.Cifti2Volume(
        dimensions,
        ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(-3, affine))
    return ci.Cifti2MatrixIndicesMap(
        applies_to_matrix_dimension,
        'CIFTI_INDEX_TYPE_BRAIN_MODELS',
        maps=[left_thalamus, left_cortex, right_cortex, volume])
예제 #5
0
    def to_mapping(self, dim):
        """
        Converts the parcels to a MatrixIndicesMap for storage in CIFTI format

        Parameters
        ----------
        dim : int
            which dimension of the CIFTI vector/matrix is described by this dataset (zero-based)

        Returns
        -------
        cifti2.Cifti2MatrixIndicesMap
        """
        mim = cifti2.Cifti2MatrixIndicesMap([dim], 'CIFTI_INDEX_TYPE_PARCELS')
        if self.affine is not None:
            affine = cifti2.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(-3, matrix=self.affine)
            mim.volume = cifti2.Cifti2Volume(self.volume_shape, affine)
        for name, nvertex in self.nvertices.items():
            mim.append(cifti2.Cifti2Surface(name, nvertex))
        for name, voxels, vertices in self.arr:
            cifti_voxels = cifti2.Cifti2VoxelIndicesIJK(voxels)
            element = cifti2.Cifti2Parcel(name, cifti_voxels)
            for name, idx_vertices in vertices.items():
                element.vertices.append(cifti2.Cifti2Vertices(name, idx_vertices))
            mim.append(element)
        return mim
예제 #6
0
    def to_mapping(self, dim):
        """
        Converts the brain model axis to a MatrixIndicesMap for storage in CIFTI format

        Parameters
        ----------
        dim : int
            which dimension of the CIFTI vector/matrix is described by this dataset (zero-based)

        Returns
        -------
        cifti2.Cifti2MatrixIndicesMap
        """
        mim = cifti2.Cifti2MatrixIndicesMap([dim], 'CIFTI_INDEX_TYPE_BRAIN_MODELS')
        for name, to_slice, bm in self.iter_structures():
            is_surface = name in self.nvertices.keys()
            if is_surface:
                voxels = None
                vertices = cifti2.Cifti2VertexIndices(bm.vertex)
                nvertex = self.nvertices[name]
            else:
                voxels = cifti2.Cifti2VoxelIndicesIJK(bm.voxel)
                vertices = None
                nvertex = None
                if mim.volume is None:
                    affine = cifti2.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(-3, matrix=self.affine)
                    mim.volume = cifti2.Cifti2Volume(self.volume_shape, affine)
            cifti_bm = cifti2.Cifti2BrainModel(to_slice.start, len(bm),
                                               'CIFTI_MODEL_TYPE_SURFACE' if is_surface else 'CIFTI_MODEL_TYPE_VOXELS',
                                               name, nvertex, voxels, vertices)
            mim.append(cifti_bm)
        return mim
예제 #7
0
def test_matrixindicesmap():
    mim = ci.Cifti2MatrixIndicesMap(0, 'CIFTI_INDEX_TYPE_LABELS')
    volume = ci.Cifti2Volume()
    volume2 = ci.Cifti2Volume()
    parcel = ci.Cifti2Parcel()

    assert mim.volume is None
    mim.append(volume)
    mim.append(parcel)

    assert mim.volume == volume
    with pytest.raises(ci.Cifti2HeaderError):
        mim.insert(0, volume)

    with pytest.raises(ci.Cifti2HeaderError):
        mim[1] = volume

    mim[0] = volume2
    assert mim.volume == volume2

    del mim.volume
    assert mim.volume is None
    with pytest.raises(ValueError):
        del mim.volume

    mim.volume = volume
    assert mim.volume == volume
    mim.volume = volume2
    assert mim.volume == volume2

    with pytest.raises(ValueError):
        mim.volume = parcel
예제 #8
0
def test_matrixindicesmap():
    mim = ci.Cifti2MatrixIndicesMap(0, 'CIFTI_INDEX_TYPE_LABELS')
    volume = ci.Cifti2Volume()
    volume2 = ci.Cifti2Volume()
    parcel = ci.Cifti2Parcel()

    assert_is_none(mim.volume)
    mim.append(volume)
    mim.append(parcel)

    assert_equal(mim.volume, volume)
    assert_raises(ci.Cifti2HeaderError, mim.insert, 0, volume)
    assert_raises(ci.Cifti2HeaderError, mim.__setitem__, 1, volume)

    mim[0] = volume2
    assert_equal(mim.volume, volume2)

    del mim.volume
    assert_is_none(mim.volume)
    assert_raises(ValueError, delattr, mim, 'volume')

    mim.volume = volume
    assert_equal(mim.volume, volume)
    mim.volume = volume2
    assert_equal(mim.volume, volume2)

    assert_raises(ValueError, setattr, mim, 'volume', parcel)
예제 #9
0
 def create_series_map():
     return ci.Cifti2MatrixIndicesMap((0, ),
                                      'CIFTI_INDEX_TYPE_SERIES',
                                      number_of_series_points=timepoints,
                                      series_exponent=0,
                                      series_start=0,
                                      series_step=1,
                                      series_unit='SECOND')
예제 #10
0
def create_series_map(applies_to_matrix_dimension):
    return ci.Cifti2MatrixIndicesMap(applies_to_matrix_dimension,
                                     'CIFTI_INDEX_TYPE_SERIES',
                                     number_of_series_points=13,
                                     series_exponent=-3,
                                     series_start=18.2,
                                     series_step=10.5,
                                     series_unit='SECOND')
예제 #11
0
def create_scalar_map(applies_to_matrix_dimension):
    maps = [
        ci.Cifti2NamedMap(name, ci.Cifti2MetaData(meta))
        for name, meta in scalars
    ]
    return ci.Cifti2MatrixIndicesMap(applies_to_matrix_dimension,
                                     'CIFTI_INDEX_TYPE_SCALARS',
                                     maps=maps)
예제 #12
0
 def make_imaker(self, arr, header=None, ni_header=None):
     for idx, sz in enumerate(arr.shape):
         maps = [ci.Cifti2NamedMap(str(value)) for value in range(sz)]
         mim = ci.Cifti2MatrixIndicesMap((idx, ),
                                         'CIFTI_INDEX_TYPE_SCALARS',
                                         maps=maps)
         header.matrix.append(mim)
     return lambda: self.image_maker(arr.copy(), header, ni_header)
예제 #13
0
def test_matrix():
    m = ci.Cifti2Matrix()

    with pytest.raises(ValueError):
        m.metadata = ci.Cifti2Parcel()

    with pytest.raises(TypeError):
        m[0] = ci.Cifti2Parcel()

    with pytest.raises(TypeError):
        m.insert(0, ci.Cifti2Parcel())

    mim_none = ci.Cifti2MatrixIndicesMap(None, 'CIFTI_INDEX_TYPE_LABELS')
    mim_0 = ci.Cifti2MatrixIndicesMap(0, 'CIFTI_INDEX_TYPE_LABELS')
    mim_1 = ci.Cifti2MatrixIndicesMap(1, 'CIFTI_INDEX_TYPE_LABELS')
    mim_01 = ci.Cifti2MatrixIndicesMap([0, 1], 'CIFTI_INDEX_TYPE_LABELS')

    with pytest.raises(ci.Cifti2HeaderError):
        m.insert(0, mim_none)

    assert m.mapped_indices == []

    h = ci.Cifti2Header(matrix=m)
    assert m.mapped_indices == []
    m.insert(0, mim_0)
    assert h.mapped_indices == [0]
    assert h.number_of_mapped_indices == 1
    with pytest.raises(ci.Cifti2HeaderError):
        m.insert(0, mim_0)

    with pytest.raises(ci.Cifti2HeaderError):
        m.insert(0, mim_01)

    m[0] = mim_1
    assert list(m.mapped_indices) == [1]
    m.insert(0, mim_0)
    assert list(sorted(m.mapped_indices)) == [0, 1]
    assert h.number_of_mapped_indices == 2
    assert h.get_index_map(0) == mim_0
    assert h.get_index_map(1) == mim_1
    with pytest.raises(ci.Cifti2HeaderError):
        h.get_index_map(2)
예제 #14
0
def create_label_map(applies_to_matrix_dimension):
    maps = []
    for name, meta, label in labels:
        label_table = ci.Cifti2LabelTable()
        for key, (tag, rgba) in label.items():
            label_table[key] = ci.Cifti2Label(key, tag, *rgba)
        maps.append(
            ci.Cifti2NamedMap(name, ci.Cifti2MetaData(meta), label_table))
    return ci.Cifti2MatrixIndicesMap(applies_to_matrix_dimension,
                                     'CIFTI_INDEX_TYPE_LABELS',
                                     maps=maps)
예제 #15
0
def create_parcel_map(applies_to_matrix_dimension, surfaces, volume, pinfo):
    """Creaters a pracel map

    PARAMETERS
    ---------
    applies_to_matrix_dimension : tuple
    surfaces                    : list of Cifti2Surface
    volume                      : Cifti2Volume
    pinfo                       : list of ParcelInfo
    """
    mapping = ci.Cifti2MatrixIndicesMap(applies_to_matrix_dimension,
                                        Map.PARCELS)
    for p in pinfo:
        mapping.append(create_parcel(p))
    mapping.extend(surfaces)
    mapping.volume = volume
    return mapping
예제 #16
0
    def to_mapping(self, dim):
        """
        Converts the hcp_labels to a MatrixIndicesMap for storage in CIFTI format

        Parameters
        ----------
        dim : int
            which dimension of the CIFTI vector/matrix is described by this dataset (zero-based)

        Returns
        -------
        cifti2.Cifti2MatrixIndicesMap
        """
        mim = cifti2.Cifti2MatrixIndicesMap([dim], 'CIFTI_INDEX_TYPE_SCALARS')
        for elem in self.arr:
            meta = None if len(elem['meta']) == 0 else elem['meta']
            named_map = cifti2.Cifti2NamedMap(elem['name'], cifti2.Cifti2MetaData(meta))
            mim.append(named_map)
        return mim
예제 #17
0
    def to_mapping(self, dim):
        """
        Converts the series to a MatrixIndicesMap for storage in CIFTI format

        Parameters
        ----------
        dim : int
            which dimension of the CIFTI vector/matrix is described by this dataset (zero-based)

        Returns
        -------
        cifti2.Cifti2MatrixIndicesMap
        """
        mim = cifti2.Cifti2MatrixIndicesMap([dim], 'CIFTI_INDEX_TYPE_SERIES')
        mim.series_exponent = 0
        mim.series_start = self.start
        mim.series_step = self.step
        mim.number_of_series_points = self.size
        return mim
예제 #18
0
def create_parcel_map(applies_to_matrix_dimension):
    mapping = ci.Cifti2MatrixIndicesMap(applies_to_matrix_dimension,
                                        'CIFTI_INDEX_TYPE_PARCELS')
    for name, elements in parcels:
        surfaces = []
        volume = None
        for element in elements:
            if isinstance(element[0], str):
                surfaces.append(ci.Cifti2Vertices(element[0], element[1]))
            else:
                volume = ci.Cifti2VoxelIndicesIJK(element)
        mapping.append(ci.Cifti2Parcel(name, volume, surfaces))

    mapping.extend([
        ci.Cifti2Surface('CIFTI_STRUCTURE_CORTEX_%s' % orientation,
                         number_of_vertices)
        for orientation in ['LEFT', 'RIGHT']
    ])
    mapping.volume = ci.Cifti2Volume(
        dimensions,
        ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(-3, affine))
    return mapping
예제 #19
0
    def to_mapping(self, dim):
        """
        Converts the hcp_labels to a MatrixIndicesMap for storage in CIFTI format

        Parameters
        ----------
        dim : int
            which dimension of the CIFTI vector/matrix is described by this dataset (zero-based)

        Returns
        -------
        cifti2.Cifti2MatrixIndicesMap
        """
        mim = cifti2.Cifti2MatrixIndicesMap([dim], 'CIFTI_INDEX_TYPE_LABELS')
        for elem in self.arr:
            label_table = cifti2.Cifti2LabelTable()
            for key, value in elem['label'].items():
                label_table[key] = (value[0],) + tuple(value[1])
            meta = None if len(elem['meta']) == 0 else elem['meta']
            named_map = cifti2.Cifti2NamedMap(elem['name'], cifti2.Cifti2MetaData(meta),
                                              label_table)
            mim.append(named_map)
        return mim
예제 #20
0
    def create_geometry_map():
        index_offset = 0
        brain_models = []
        timeseries = np.zeros((timepoints, 0))

        for name, data in models:
            if "CORTEX" in name:
                model_type = "CIFTI_MODEL_TYPE_SURFACE"
                attr = "vertex_indices"
                indices = ci.Cifti2VertexIndices(np.arange(len(data)))
            else:
                model_type = "CIFTI_MODEL_TYPE_VOXELS"
                attr = "voxel_indices_ijk"
                indices = ci.Cifti2VoxelIndicesIJK(np.arange(len(data)))
            bm = ci.Cifti2BrainModel(
                index_offset=index_offset,
                index_count=len(data),
                model_type=model_type,
                brain_structure=name,
            )
            setattr(bm, attr, indices)
            index_offset += len(data)
            brain_models.append(bm)
            timeseries = np.column_stack((timeseries, data.T))

        brain_models.append(
            ci.Cifti2Volume(
                (4, 4, 4),
                ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(
                    -3, np.eye(4)),
            ))

        return ci.Cifti2MatrixIndicesMap(
            (1, ),
            "CIFTI_INDEX_TYPE_BRAIN_MODELS",
            maps=brain_models,
        ), timeseries
예제 #21
0
def create_geometry_map(applies_to_matrix_dimension, brain_models):
    """Creates a geometry map"""
    return ci.Cifti2MatrixIndicesMap(applies_to_matrix_dimension,
                                     Map.BRAIN_MODELS,
                                     maps=brain_models)
예제 #22
0
def create_scalar_map(applies_to_matrix_dimension, info):
    """Creates a scalar map form a list of NamedMapInfo"""
    maps = [ci.Cifti2NamedMap(i.name, ci.Cifti2MetaData(i.meta)) for i in info]
    return ci.Cifti2MatrixIndicesMap(applies_to_matrix_dimension,
                                     Map.SCALARS,
                                     maps=maps)
예제 #23
0
    indices=cortex_left_indices, model_type=ch.ModelType.SURFACE,
    surface_number_of_vertices=ch.HCP_32K_FS_L)
right_thalamus = ch.MapInfo(brain_structure=ch.Structure.THALAMUS_LEFT,
    indices=voxels, model_type=ch.ModelType.VOXEL, 
    surface_number_of_vertices=None)
volume = ch.create_volume([50, 50, 50], affine, -3)

# create scalar maps
wrong_scalar_map = ch.create_scalar_map((0,), 
    [ch.NamedMapInfo(name="wrong", meta={})])
correct_scalar_map = ch.create_scalar_map((0,), 
    [ch.NamedMapInfo(name="right", meta={})])

# create series maps
series_map = ci.Cifti2MatrixIndicesMap((0, ), ch.Map.SERIES,
    number_of_series_points=40, series_exponent=0, series_start=0,
    series_step=0.5, series_unit="SECOND")

# create brain models
wrong_brain_models = ch.create_brain_models([wrong_right_cortex, left_cortex, 
    right_thalamus])
wrong_brain_models.append(volume)
correct_brain_models = ch.create_brain_models([right_cortex, left_cortex, 
    right_thalamus])
correct_brain_models.append(volume)
no_volume_brain_models = ch.create_brain_models([right_cortex, left_cortex])

# create geometry maps
wrong_geometry_map = ch.create_geometry_map((1,), wrong_brain_models)
correct_geometry_map = ch.create_geometry_map((1, ), correct_brain_models)
no_volume_geometry_map = ch.create_geometry_map((1, ), no_volume_brain_models)
예제 #24
0
def _create_cifti_image(bold_file, label_file, bold_surfs, annotation_files,
                        tr, targets):
    """
    Generate CIFTI image in target space.

    Parameters
    ----------
    bold_file : str
        BOLD volumetric timeseries
    label_file : str
        Subcortical label file
    bold_surfs : list
        BOLD surface timeseries [L,R]
    annotation_files : list
        Surface label files used to remove medial wall
    tr : float
        BOLD repetition time
    targets : tuple or list
        Surface and volumetric output spaces

    Returns
    -------
    out :
        BOLD data saved as CIFTI dtseries
    """
    bold_img = nb.load(bold_file)
    label_img = nb.load(label_file)
    if label_img.shape != bold_img.shape[:3]:
        warnings.warn("Resampling bold volume to match label dimensions")
        bold_img = resample_to_img(bold_img, label_img)

    bold_data = bold_img.get_fdata(dtype='float32')
    timepoints = bold_img.shape[3]
    label_data = np.asanyarray(label_img.dataobj).astype('int16')

    # Create brain models
    idx_offset = 0
    brainmodels = []
    bm_ts = np.empty((timepoints, 0))

    for structure, labels in CIFTI_STRUCT_WITH_LABELS.items():
        if labels is None:  # surface model
            model_type = "CIFTI_MODEL_TYPE_SURFACE"
            # use the corresponding annotation
            hemi = structure.split('_')[-1]
            # currently only supports L/R cortex
            surf = nb.load(bold_surfs[hemi == "RIGHT"])
            surf_verts = len(surf.darrays[0].data)
            if annotation_files[0].endswith('.annot'):
                annot = nb.freesurfer.read_annot(
                    annotation_files[hemi == "RIGHT"])
                # remove medial wall
                medial = np.nonzero(annot[0] != annot[2].index(b'unknown'))[0]
            else:
                annot = nb.load(annotation_files[hemi == "RIGHT"])
                medial = np.nonzero(annot.darrays[0].data)[0]
            # extract values across volumes
            ts = np.array([tsarr.data[medial] for tsarr in surf.darrays])

            vert_idx = ci.Cifti2VertexIndices(medial)
            bm = ci.Cifti2BrainModel(index_offset=idx_offset,
                                     index_count=len(vert_idx),
                                     model_type=model_type,
                                     brain_structure=structure,
                                     vertex_indices=vert_idx,
                                     n_surface_vertices=surf_verts)
            idx_offset += len(vert_idx)
            bm_ts = np.column_stack((bm_ts, ts))
        else:
            model_type = "CIFTI_MODEL_TYPE_VOXELS"
            vox = []
            ts = None
            for label in labels:
                ijk = np.nonzero(label_data == label)
                if ijk[0].size == 0:  # skip label if nothing matches
                    continue
                ts = (bold_data[ijk] if ts is None else np.concatenate(
                    (ts, bold_data[ijk])))
                vox += [[ijk[0][ix], ijk[1][ix], ijk[2][ix]]
                        for ix, row in enumerate(ts)]

            vox = ci.Cifti2VoxelIndicesIJK(vox)
            bm = ci.Cifti2BrainModel(index_offset=idx_offset,
                                     index_count=len(vox),
                                     model_type=model_type,
                                     brain_structure=structure,
                                     voxel_indices_ijk=vox)
            idx_offset += len(vox)
            bm_ts = np.column_stack((bm_ts, ts.T))
        # add each brain structure to list
        brainmodels.append(bm)

    # add volume information
    brainmodels.append(
        ci.Cifti2Volume(
            bold_img.shape[:3],
            ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(
                -3, bold_img.affine)))

    # generate Matrix information
    series_map = ci.Cifti2MatrixIndicesMap((0, ),
                                           'CIFTI_INDEX_TYPE_SERIES',
                                           number_of_series_points=timepoints,
                                           series_exponent=0,
                                           series_start=0.0,
                                           series_step=tr,
                                           series_unit='SECOND')
    geometry_map = ci.Cifti2MatrixIndicesMap((1, ),
                                             'CIFTI_INDEX_TYPE_BRAIN_MODELS',
                                             maps=brainmodels)
    # provide some metadata to CIFTI matrix
    meta = {
        "surface": targets[0],
        "volume": targets[1],
    }
    # generate and save CIFTI image
    matrix = ci.Cifti2Matrix()
    matrix.append(series_map)
    matrix.append(geometry_map)
    matrix.metadata = ci.Cifti2MetaData(meta)
    hdr = ci.Cifti2Header(matrix)
    img = ci.Cifti2Image(bm_ts, hdr)
    img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES')

    out_file = "{}.dtseries.nii".format(split_filename(bold_file)[1])
    ci.save(img, out_file)
    return os.path.join(os.getcwd(), out_file)
예제 #25
0
    def _create_cifti_image(bold_file, label_file, annotation_files, gii_files,
                            volume_target, surface_target, tr):
        """
        Generate CIFTI image in target space

        Parameters
            bold_file : 4D BOLD timeseries
            label_file : label atlas
            annotation_files : FreeSurfer annotations
            gii_files : 4D BOLD surface timeseries in GIFTI format
            volume_target : label atlas space
            surface_target : gii_files space
            tr : repetition timeseries

        Returns
            out_file : BOLD data as CIFTI dtseries
        """

        label_img = nb.load(label_file)
        bold_img = resample_to_img(bold_file, label_img)

        bold_data = bold_img.get_data()
        timepoints = bold_img.shape[3]
        label_data = label_img.get_data()

        # set up CIFTI information
        series_map = ci.Cifti2MatrixIndicesMap(
            (0, ),
            'CIFTI_INDEX_TYPE_SERIES',
            number_of_series_points=timepoints,
            series_exponent=0,
            series_start=0.0,
            series_step=tr,
            series_unit='SECOND')
        # Create CIFTI brain models
        idx_offset = 0
        brainmodels = []
        bm_ts = np.empty((timepoints, 0))

        for structure, labels in CIFTI_STRUCT_WITH_LABELS.items():
            if labels is None:  # surface model
                model_type = "CIFTI_MODEL_TYPE_SURFACE"
                # use the corresponding annotation
                hemi = structure.split('_')[-1]
                annot = nb.freesurfer.read_annot(
                    annotation_files[hemi == "RIGHT"])
                # currently only supports L/R cortex
                gii = nb.load(gii_files[hemi == "RIGHT"])
                # calculate total number of vertices
                surf_verts = len(annot[0])
                # remove medial wall for CIFTI format
                vert_idx = np.nonzero(
                    annot[0] != annot[2].index(b'unknown'))[0]
                # extract values across volumes
                ts = np.array([tsarr.data[vert_idx] for tsarr in gii.darrays])

                vert_idx = ci.Cifti2VertexIndices(vert_idx)
                bm = ci.Cifti2BrainModel(index_offset=idx_offset,
                                         index_count=len(vert_idx),
                                         model_type=model_type,
                                         brain_structure=structure,
                                         vertex_indices=vert_idx,
                                         n_surface_vertices=surf_verts)
                bm_ts = np.column_stack((bm_ts, ts))
                idx_offset += len(vert_idx)
                brainmodels.append(bm)
            else:
                model_type = "CIFTI_MODEL_TYPE_VOXELS"
                vox = []
                ts = None
                for label in labels:
                    ijk = np.nonzero(label_data == label)
                    ts = (bold_data[ijk] if ts is None else np.concatenate(
                        (ts, bold_data[ijk])))
                    vox += [[ijk[0][ix], ijk[1][ix], ijk[2][ix]]
                            for ix, row in enumerate(ts)]

                bm_ts = np.column_stack((bm_ts, ts.T))

                vox = ci.Cifti2VoxelIndicesIJK(vox)
                bm = ci.Cifti2BrainModel(index_offset=idx_offset,
                                         index_count=len(vox),
                                         model_type=model_type,
                                         brain_structure=structure,
                                         voxel_indices_ijk=vox)
                idx_offset += len(vox)
                brainmodels.append(bm)

        volume = ci.Cifti2Volume(
            bold_img.shape[:3],
            ci.Cifti2TransformationMatrixVoxelIndicesIJKtoXYZ(
                -3, bold_img.affine))
        brainmodels.append(volume)

        # create CIFTI geometry based on brainmodels
        geometry_map = ci.Cifti2MatrixIndicesMap(
            (1, ), 'CIFTI_INDEX_TYPE_BRAIN_MODELS', maps=brainmodels)
        # provide some metadata to CIFTI matrix
        meta = {
            "target_surface": surface_target,
            "target_volume": volume_target,
        }
        # generate and save CIFTI image
        matrix = ci.Cifti2Matrix()
        matrix.append(series_map)
        matrix.append(geometry_map)
        matrix.metadata = ci.Cifti2MetaData(meta)
        hdr = ci.Cifti2Header(matrix)
        img = ci.Cifti2Image(bm_ts, hdr)
        img.nifti_header.set_intent('NIFTI_INTENT_CONNECTIVITY_DENSE_SERIES')

        _, out_base, _ = split_filename(bold_file)
        out_file = "{}.dtseries.nii".format(out_base)
        ci.save(img, out_file)
        return os.path.join(os.getcwd(), out_file)