Exemplo n.º 1
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
Exemplo n.º 2
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)
Exemplo n.º 3
0
def test_cifti2_metadata():
    md = ci.Cifti2MetaData(metadata={'a': 'aval'})
    assert len(md) == 1
    assert list(iter(md)) == ['a']
    assert md['a'] == 'aval'
    assert md.data == dict([('a', 'aval')])

    md = ci.Cifti2MetaData()
    assert len(md) == 0
    assert list(iter(md)) == []
    assert md.data == {}
    with pytest.raises(ValueError):
        md.difference_update(None)

    md['a'] = 'aval'
    assert md['a'] == 'aval'
    assert len(md) == 1
    assert md.data == dict([('a', 'aval')])

    del md['a']
    assert len(md) == 0

    metadata_test = [('a', 'aval'), ('b', 'bval')]
    md.update(metadata_test)
    assert md.data == dict(metadata_test)

    assert list(iter(md)) == list(iter(collections.OrderedDict(metadata_test)))

    md.update({'a': 'aval', 'b': 'bval'})
    assert md.data == dict(metadata_test)

    md.update({'a': 'aval', 'd': 'dval'})
    assert md.data == dict(metadata_test + [('d', 'dval')])

    md.difference_update({'a': 'aval', 'd': 'dval'})
    assert md.data == dict(metadata_test[1:])

    with pytest.raises(KeyError):
        md.difference_update({'a': 'aval', 'd': 'dval'})
    assert md.to_xml().decode(
        'utf-8'
    ) == '<MetaData><MD><Name>b</Name><Value>bval</Value></MD></MetaData>'
Exemplo n.º 4
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)
Exemplo n.º 5
0
def test_cifti2_metadata():
    md = ci.Cifti2MetaData(metadata={'a': 'aval'})
    assert_equal(len(md), 1)
    assert_equal(list(iter(md)), ['a'])
    assert_equal(md['a'], 'aval')
    assert_equal(md.data, dict([('a', 'aval')]))

    md = ci.Cifti2MetaData()
    assert_equal(len(md), 0)
    assert_equal(list(iter(md)), [])
    assert_equal(md.data, {})
    assert_raises(ValueError, md.difference_update, None)

    md['a'] = 'aval'
    assert_equal(md['a'], 'aval')
    assert_equal(len(md), 1)
    assert_equal(md.data, dict([('a', 'aval')]))

    del md['a']
    assert_equal(len(md), 0)

    metadata_test = [('a', 'aval'), ('b', 'bval')]
    md.update(metadata_test)
    assert_equal(md.data, dict(metadata_test))

    assert_equal(list(iter(md)),
                 list(iter(collections.OrderedDict(metadata_test))))

    md.update({'a': 'aval', 'b': 'bval'})
    assert_equal(md.data, dict(metadata_test))

    md.update({'a': 'aval', 'd': 'dval'})
    assert_equal(md.data, dict(metadata_test + [('d', 'dval')]))

    md.difference_update({'a': 'aval', 'd': 'dval'})
    assert_equal(md.data, dict(metadata_test[1:]))

    assert_raises(KeyError, md.difference_update, {'a': 'aval', 'd': 'dval'})
    assert_equal(
        md.to_xml().decode('utf-8'),
        '<MetaData><MD><Name>b</Name><Value>bval</Value></MD></MetaData>')
Exemplo n.º 6
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
Exemplo n.º 7
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
Exemplo n.º 8
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)
Exemplo n.º 9
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)
Exemplo n.º 10
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)