Exemplo n.º 1
0
def _make_label_connectivity():
    labels = [Label(vertices=np.arange(3), hemi='lh', name='Label1'),
              Label(vertices=np.arange(3, 6), hemi='lh', name='Label2'),
              Label(vertices=np.arange(6, 9), hemi='lh', name='Label3')]

    pairs = [[0, 0, 1], [1, 2, 2]]
    data = np.arange(len(pairs[1]))

    return LabelConnectivity(data, pairs, labels)
Exemplo n.º 2
0
def _generate_labels(vertices, n_labels):
    vert_lh, vert_rh = vertices
    n_lh_chunck = len(vert_lh)//(n_labels // 2)
    n_rh_chunck = len(vert_rh)//(n_labels - n_labels // 2)

    labels_lh = [Label(vertices=vert_lh[x:x+n_lh_chunck], hemi='lh',
                       name='Label' + str(x))
                 for x in range(0, len(vert_lh), n_lh_chunck)]

    labels_rh = [Label(vertices=vert_rh[x:x+n_rh_chunck], hemi='rh',
                       name='Label' + str(x))
                 for x in range(0, len(vert_rh), n_lh_chunck)]

    return labels_lh + labels_rh
Exemplo n.º 3
0
def test_vert_ind_from_Label():
    """Test _get_vert_ind_from_label"""
    label_lh = Label(np.arange(10), hemi='lh', name='Label1-lh')
    label_rh = Label(np.arange(10), hemi='rh', name='Label1-rh')
    bilabel = BiHemiLabel(label_lh, label_rh, name='Label1')
    vertices = [np.arange(5), np.arange(5, 10)]

    inds_lh = _get_vert_ind_from_label(vertices, label_lh)
    inds_rh = _get_vert_ind_from_label(vertices, label_rh)
    assert_array_equal(inds_lh, np.arange(5))
    assert_array_equal(inds_rh, np.arange(5, 10))

    inds = _get_vert_ind_from_label(vertices, bilabel)
    assert_array_equal(inds, np.arange(10))

    # Incorrect input
    with pytest.raises(TypeError):
        _get_vert_ind_from_label(vertices, 'label')
Exemplo n.º 4
0
def plot_roi(
    hemi,
    labels,
    color,
    annotation="HCPMMP1",
    view="parietal",
    fs_dir=os.environ["SUBJECTS_DIR"],
    subject_id="S04",
    surf="inflated",
):
    import matplotlib
    import os
    import glob
    from surfer import Brain
    from mne import Label

    color = np.array(matplotlib.colors.to_rgba(color))

    brain = Brain(subject_id, hemi, surf, offscreen=False)
    labels = [label.replace("-rh", "").replace("-lh", "") for label in labels]
    # First select all label files

    label_names = glob.glob(
        os.path.join(fs_dir, subject_id, "label", "lh*.label"))
    label_names = [
        label for label in label_names if any([l in label for l in labels])
    ]

    for label in label_names:
        brain.add_label(label, color=color)

    # Now go for annotations
    from nibabel.freesurfer import io

    ids, colors, annot_names = io.read_annot(
        os.path.join(fs_dir, subject_id, "label", "lh.%s.annot" % annotation),
        orig_ids=True,
    )

    for i, alabel in enumerate(annot_names):
        if any([label in alabel.decode("utf-8") for label in labels]):
            label_id = colors[i, -1]
            vertices = np.where(ids == label_id)[0]
            l = Label(np.sort(vertices), hemi="lh")
            brain.add_label(l, color=color)
    brain.show_view(view)
    return brain.screenshot()
Exemplo n.º 5
0
 def img2imgcoord_by_surf(self, target_subject, wf_base_dir=None, source_surface = 'pial', source_map_surface='pial', target_surface='pial'):
     
     if wf_base_dir is None and self.working_dir is not None:
         wf_base_dir = self.working_dir
         
     elif wf_base_dir is None and self.working_dir is None:
         print('Working dir has not been specified, results will be stored in:  ', os.path.abspath('.'))             
         wf_base_dir = os.path.abspath('.')
     
     rois,rois_paths = self.create_surf_roi(extents=2, wf_base_dir= wf_base_dir, wf_name='img2imgcoord_by_surf_roi', surface=source_surface, map_surface=source_map_surface, label2vol=False)
     
     wf = pe.Workflow(name='label2label',base_dir=wf_base_dir)
     for i in range(self.npoints):
         l2l = Label2Label()
         l2l.inputs.hemisphere = self.hemi[i]
         l2l.inputs.subject_id = target_subject
         l2l.inputs.sphere_reg = os.path.join(self.freesurfer_dir, target_subject, 'surf', self.hemi[i]+'.'+'sphere.reg')
         l2l.inputs.white = os.path.join(self.freesurfer_dir, target_subject, 'surf', self.hemi[i]+'.'+'white')
         
         l2l.inputs.source_subject = self.subject
         l2l.inputs.source_label = rois_paths[i]
         l2l.inputs.source_white = os.path.join(self.freesurfer_dir, self.subject, 'surf', self.hemi[i]+'.'+'white')
         l2l.inputs.source_sphere_reg = os.path.join(self.freesurfer_dir, self.subject, 'surf', self.hemi[i]+'.'+'sphere.reg')
         l2l.subjects_dir = self.freesurfer_dir
         l2l_node = pe.Node(l2l,'label2label_{i}'.format(i=i))
         wf.add_nodes([l2l_node])
     try:
         wf.run()
     except RuntimeError:
         pass
   
     for i in range(self.npoints):
         out_label_file = os.path.join(self.freesurfer_dir, target_subject, 'label', os.path.basename(rois_paths[i]).split('.label')[0]+'_converted'+'.label')
         shutil.move(out_label_file, os.path.join(wf_base_dir, 'label2label','label2label_{i}'.format(i=i)))
      
     new_coords = np.zeros((self.npoints,3))    
     for i in range(self.npoints):
         label_file = os.path.join(wf_base_dir, 'label2label','label2label_{i}'.format(i=i),os.path.basename(rois_paths[i]).split('.label')[0]+'_converted'+'.label')
         label_vertices = read_label(label_file)
         label_vertices.sort()
         label = Label(label_vertices,hemi=self.hemi[i],subject=target_subject)
         vertex = label.center_of_mass()
         targ_surf = FreesurferSurf(hemi=label.hemi, surf=target_surface, subject = target_subject, subjects_dir=self.freesurfer_dir)
         new_coords[i,:] = targ_surf.get_coords(vertex)
     return new_coords
Exemplo n.º 6
0
def read_connectivity(fname):
    """Read a Connectivity object from an HDF5 file.

    Parameters
    ----------
    fname : str
        The name of the file to read the connectivity from. The extension '.h5'
        will be appended if the given filename doesn't have it already.

    Returns
    -------
    connectivity : instance of Connectivity
        The Connectivity object that was stored in the file.

    See Also
    --------
    Connectivity.save : For saving connectivity objects
    """
    if not fname.endswith('.h5'):
        fname += '.h5'

    con_dict = read_hdf5(fname, title='conpy')
    con_type = con_dict['type']
    del con_dict['type']

    if con_type == 'all-to-all':
        return VertexConnectivity(
            data=con_dict['data'],
            pairs=con_dict['pairs'],
            vertices=con_dict['vertices'],
            vertex_degree=con_dict['source_degree'],
            subject=con_dict['subject'],
        )
    elif con_type == 'label':
        labels = [Label(**l) for l in con_dict['labels']]
        return LabelConnectivity(
            data=con_dict['data'],
            pairs=con_dict['pairs'],
            labels=labels,
            label_degree=con_dict['source_degree'],
            subject=con_dict['subject'],
        )
Exemplo n.º 7
0
def test_extract_label_time_course():
    """Test extraction of label time courses from stc
    """
    n_stcs = 3
    n_times = 50

    src = read_inverse_operator(fname_inv)['src']
    vertices = [src[0]['vertno'], src[1]['vertno']]
    n_verts = len(vertices[0]) + len(vertices[1])

    # get some labels
    labels_lh = read_labels_from_annot('sample',
                                       hemi='lh',
                                       subjects_dir=subjects_dir)
    labels_rh = read_labels_from_annot('sample',
                                       hemi='rh',
                                       subjects_dir=subjects_dir)
    labels = list()
    labels.extend(labels_lh[:5])
    labels.extend(labels_rh[:4])

    n_labels = len(labels)

    label_means = np.arange(n_labels)[:, None] * np.ones((n_labels, n_times))
    label_maxs = np.arange(n_labels)[:, None] * np.ones((n_labels, n_times))

    # compute the mean with sign flip
    label_means_flipped = np.zeros_like(label_means)
    for i, label in enumerate(labels):
        label_means_flipped[i] = i * np.mean(label_sign_flip(label, src))

    # generate some stc's with known data
    stcs = list()
    for i in range(n_stcs):
        data = np.zeros((n_verts, n_times))
        # set the value of the stc within each label
        for j, label in enumerate(labels):
            if label.hemi == 'lh':
                idx = np.intersect1d(vertices[0], label.vertices)
                idx = np.searchsorted(vertices[0], idx)
            elif label.hemi == 'rh':
                idx = np.intersect1d(vertices[1], label.vertices)
                idx = len(vertices[0]) + np.searchsorted(vertices[1], idx)
            data[idx] = label_means[j]

        this_stc = SourceEstimate(data, vertices, 0, 1)
        stcs.append(this_stc)

    # test some invalid inputs
    assert_raises(ValueError,
                  extract_label_time_course,
                  stcs,
                  labels,
                  src,
                  mode='notamode')

    # have an empty label
    empty_label = labels[0].copy()
    empty_label.vertices += 1000000
    assert_raises(ValueError,
                  extract_label_time_course,
                  stcs,
                  empty_label,
                  src,
                  mode='mean')

    # but this works:
    tc = extract_label_time_course(stcs,
                                   empty_label,
                                   src,
                                   mode='mean',
                                   allow_empty=True)
    for arr in tc:
        assert_true(arr.shape == (1, n_times))
        assert_array_equal(arr, np.zeros((1, n_times)))

    # test the different modes
    modes = ['mean', 'mean_flip', 'pca_flip', 'max']

    for mode in modes:
        label_tc = extract_label_time_course(stcs, labels, src, mode=mode)
        label_tc_method = [
            stc.extract_label_time_course(labels, src, mode=mode)
            for stc in stcs
        ]
        assert_true(len(label_tc) == n_stcs)
        assert_true(len(label_tc_method) == n_stcs)
        for tc1, tc2 in zip(label_tc, label_tc_method):
            assert_true(tc1.shape == (n_labels, n_times))
            assert_true(tc2.shape == (n_labels, n_times))
            assert_true(np.allclose(tc1, tc2, rtol=1e-8, atol=1e-16))
            if mode == 'mean':
                assert_array_almost_equal(tc1, label_means)
            if mode == 'mean_flip':
                assert_array_almost_equal(tc1, label_means_flipped)
            if mode == 'max':
                assert_array_almost_equal(tc1, label_maxs)

    # test label with very few vertices (check SVD conditionals)
    label = Label(vertices=src[0]['vertno'][:2], hemi='lh')
    x = label_sign_flip(label, src)
    assert_true(len(x) == 2)
    label = Label(vertices=[], hemi='lh')
    x = label_sign_flip(label, src)
    assert_true(x.size == 0)
Exemplo n.º 8
0
 def __setstate__(self, state):  # noqa: D105
     super(LabelConnectivity, self).__setstate__(state)
     self.labels = [Label(*l) for l in state['labels']]
Exemplo n.º 9
0
def get_surface_areas_old(surface, texture, subject='S4', hemi='lh',
                      fname_atlas=None, fname_color=None):
    """get areas on the surface

    Parameters
    ----------
    surface : instance of Surface
    texture : str | array
        Array to get areas or the filename to get this
    subject : str
        Name of the subject
    hemi : 'lh' | 'rh'
        Name of the hemisphere
    fname_atlas : str | None
        Filename for area atlas
    fname_color : str | None
        Filename for area color

    Returns
    -------
    areas : list of Surface object
    -------
    Author : Alexandre Fabre
    """

    areas = []

    rr = surface.pos
    normals = surface.normals

    # Gt texture with gifti format (BainVisa)= labels of MarsAtlas
    if isinstance(texture, str):
        giftiImage = gifti.giftiio.read(texture)
        base_values = giftiImage.darrays[0].data

    else:
        base_values = texture

    # sort indices thanks to texture
    argsort = np.argsort(base_values, kind='mergesort', axis=0)

    values = base_values[argsort]

    # get parcels and count the number of nodes in each parcel (count)
    parcels, counts = np.unique(values, return_counts=True)

    vertices = argsort

    rr = rr[argsort, :]
    normals = normals[argsort, :]

    # get parcels information
    info = read_texture_info(fname_atlas, hemi)
    color = read_color_area(fname_color, index=np.unique(values))

    parcels_length = len(parcels)
    cour = 0

    # number of points in a mesh face
    nb_iter = 3

    triangles = surface.triangles

    for pos, val in enumerate(counts):

        name_process = info.get(parcels[pos], False)
        if not name_process:
            name = 'no_name'
            lobe = 'no_name'
        else:
            name = name_process[0]
            lobe = name_process[1]

        end = cour + val

        vertices_cour = vertices[cour:end]

        # Keep only those nodes and pos of parcel that is associated with a face (triangle) in its parcel.
        # This remo

        # get triangles where points of the parcel are
        triangles_bool = []
        for i in range(nb_iter):
            triangles_bool += [np.logical_or.reduce([triangles[:, i] == val_vertices
                                                     for val_vertices in vertices_cour])]
        triangles_bool = np.transpose(triangles_bool)

        # counting the number of True per lines --> True : 1 , False : 0
        # to know how many points of the parcel are in each face
        counts = triangles_bool.sum(1)

        # indices of each triangles that contains 3 points of the parcel
        ind_all = np.where(counts == 3)
        tris_cour = triangles[ind_all]

        # indices of each faces that contains 2 points of the parcel
        ind = np.where(counts == 2)

        # Just take those links that form triangles
        tris_modif = triangles[ind]
        triangles_bool = triangles_bool[ind]

        delete = np.append(ind_all, ind)
        triangles = np.delete(triangles, delete, axis=0)

        lines, cols = tris_modif.shape

        # for the case of a triangle that contains 2 points of the parcel
        # replace the bad point (not in the parcel) with one of the two good points
        for i in range(lines):
            ind = np.where(triangles_bool[i, :] == False)[0]
            tris_modif[i, ind] = tris_modif[i, (ind + 1) % cols]

        triangles_cour = np.vstack((tris_cour, tris_modif))

        # to associate triangles to the new index of point positions in the area
        triangles_cour = rankdata(triangles_cour, method='dense').reshape(-1, 3) - 1

        if color is None:
            color_cour = (0.8, 0.2, 0.1)
        else:
            color_cour = color[pos]

        rr_cour = rr[cour:end]

        # locations in meters
        rr_label = rr_cour * 1e-3

        label = Label(vertices_cour, rr_label, values=values[cour:end], hemi=hemi,
                      comment=name, subject=subject, name=name,
                      color=color_cour, verbose=None)

        cour_surface = Surface(rr_cour, triangles_cour, subject=subject, label=label, hemi=hemi,
                               name=name, lobe=lobe, color=color_cour,
                               normals=normals[cour:end], surface_master=surface)

        areas.append(cour_surface)
        cour += val

    return areas
Exemplo n.º 10
0
def get_surface_areas(surface, texture, subject='S4', hemi='lh',
                      fname_atlas=None, fname_color=None):
    """get areas on the surface

    Parameters
    ----------
    surface : instance of Surface
    texture : str | array
        Array to get areas or the filename to get this
    subject : str
        Name of the subject
    hemi : 'lh' | 'rh'
        Name of the hemisphere
    fname_atlas : str | None
        Filename for area atlas
    fname_color : str | None
        Filename for area color

    Returns
    -------
    areas : list of Surface object
    -------
    Author : Alexandre Fabre
    """

    areas = []

    rr = surface.pos
    normals = surface.normals

    # Gt texture with gifti format (BainVisa)= labels of MarsAtlas
    if isinstance(texture, str):
        giftiImage = gifti.giftiio.read(texture)
        base_values = giftiImage.darrays[0].data

    else:
        base_values = texture

    values = base_values

    # get parcels and count the number of nodes in each parcel (count)
    parcels, counts = np.unique(values, return_counts=True)

    # get parcels information
    info = read_texture_info(fname_atlas, hemi)
    color = read_color_area(fname_color, index=np.unique(values))

    parcels_length = len(parcels)

    # number of points in a mesh face
    nb_iter = 3

    # get triangles for whole surface
    triangles = surface.triangles
    total_nodes = 0
    for pos, val in enumerate(parcels):

        name_process = info.get(parcels[pos], False)
        if not name_process:
            name = 'no_name'
            lobe = 'no_name'
        else:
            name = name_process[0]
            lobe = name_process[1]

        # Find index for nodes of the parcel
        ind = np.where(values == val)

        # Keep only those nodes and pos of parcel that are associated with a face (triangle) in its parcel
        # get triangles where points of the parcel are
        ix = np.in1d(triangles.ravel(), ind).reshape(triangles.shape)

        # Counting the number of True per lines --> True : 1 , False : 0
        # to know how many points of the parcel are in each face
        counts = ix.sum(1)

        # Indices of each triangles that contains 3 points of the parcel
        ind_all = np.where(counts == 3)
        tris_cour = triangles[ind_all]

        # Associate triangles to the new index of point positions in the area
        triangles_parcel = rankdata(tris_cour, method='dense').reshape(-1, 3) - 1

        if color is None:
            color_cour = (0.8, 0.2, 0.1)
        else:
            color_cour = color[pos]

        # Select nodes that are connected through triangles
        nodes = np.unique(tris_cour)
        iy = np.in1d(ind, nodes)
        ind_n = np.where(iy)
        ind_n = ind_n[0]
        ind   = ind[0]
        # Positions and normals
        rr_parcel = rr[ind[ind_n]]
        normals_parcel = normals[ind[ind_n]]
        # Textures (values)
        values_parcel = values[ind[ind_n]]

        # locations in meters
        # rr_parcel = rr_parcel * 1e-3

        # Number of nodes
        nodes, tmp = rr_parcel.shape
        vertex_ind = np.arange(total_nodes, total_nodes+nodes, 1)
        total_nodes =+ nodes

        label = Label(vertex_ind, rr_parcel, values=values_parcel, hemi=hemi,
                      comment=name, subject=subject, name=name,
                      color=color_cour, verbose=None)

        cour_surface = Surface(rr_parcel, triangles_parcel, subject=subject, label=label, hemi=hemi,
                               name=name, lobe=lobe, color=color_cour,
                               normals=normals_parcel, surface_master=surface)

        areas.append(cour_surface)

    return areas
Exemplo n.º 11
0
def test_parcellate():
    """Test VertexConnectivity.parcellate()"""
    vertices = [np.arange(10), np.arange(10)]
    pairs = [
        np.array([0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 6]),
        np.array([1, 2, 3, 4, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
    ]

    all_con = VertexConnectivity(np.ones(15, ), pairs, vertices)

    labels = _generate_labels(vertices, 4)

    # Test incorrect input: Labels not a list
    with pytest.raises(ValueError):
        label_con1 = all_con.parcellate(labels[0], weight_by_degree=False)

    # Subjects don't match
    all_con2 = _make_alltoall_connectivity()
    all_con2.subject = 'Test1'
    labels2 = _generate_labels(vertices, 4)
    labels2[0].subject = 'Test2'
    with pytest.raises(RuntimeError):
        all_con2.parcellate(labels2, weight_by_degree=False)

    # No weighting, degree
    label_con1 = all_con.parcellate(labels, weight_by_degree=False)
    assert_array_equal(label_con1.pairs[0], np.array([0, 0, 1, 1]))
    assert_array_equal(label_con1.data, np.array([3, 3, 2, 2]))

    # Weighting and degree
    label_con2 = all_con.parcellate(labels, weight_by_degree=True)
    assert_array_equal(label_con2.data,
                       np.array([3. / 14, 3. / 16, 2. / 9, 2. / 6]))

    # Labels that doesn't have vertices in all_con
    labels2 = [
        Label(vertices=np.array([20, 21, 22, 23]), hemi='lh', name='Label1'),
        Label(vertices=np.array([11, 12, 13, 14]), hemi='lh', name='Label2')
    ]
    label_con2 = all_con.parcellate(labels2, weight_by_degree=True)
    assert label_con2.data.size == 0
    # Sum
    label_con3 = all_con.parcellate(labels,
                                    summary='sum',
                                    weight_by_degree=False)
    assert_array_equal(label_con3.data, np.array([3, 3, 2, 2]))
    label_con4 = all_con.parcellate(labels, summary='sum')
    assert_array_equal(label_con4.data,
                       np.array([3. / 14, 3. / 16, 2. / 9, 2. / 6]))

    # Absmax
    label_con5 = all_con.parcellate(labels,
                                    summary='absmax',
                                    weight_by_degree=False)
    assert_array_equal(label_con5.data, np.array([1., 1., 1., 1.]))
    label_con5 = all_con.parcellate(labels2,
                                    summary='absmax',
                                    weight_by_degree=True)
    assert label_con5.data.size == 0

    # Other function
    def summary(c, f, t):
        return c[f, :][:, t].mean()

    label_con6 = all_con.parcellate(labels,
                                    summary=summary,
                                    weight_by_degree=False)
    assert_array_equal(label_con6.data,
                       np.array([3. / 25, 3. / 25, 2. / 25, 2. / 25]))

    # Incorrect input
    with pytest.raises(ValueError):
        all_con.parcellate(labels, summary='incorrect', weight_by_degree=False)
Exemplo n.º 12
0
def extract_roi(stc, src, label=None, thresh=0.5):
    """Extract a functional ROI.

    Parameters
    ----------
    stc : instance of SourceEstimate
        The source estimate data. The maximum positive peak will be selected.
        If you want the maximum negative peak, consider passing
        abs(stc) or -stc.
    src : instance of SourceSpaces
        The associated source space.
    label : instance of Label | None
        The label within which to select the peak.
        Can be None to use the entire STC.
    thresh : float
        Threshold value (relative to the peak value) above which vertices
        will be taken.

    Returns
    -------
    roi : instance of Label
        The functional ROI.
    """
    assert isinstance(stc, SourceEstimate)
    if label is None:
        stc_label = stc.copy()
    else:
        stc_label = stc.in_label(label)
    del label
    max_vidx, max_tidx = np.unravel_index(np.argmax(stc_label.data),
                                          stc_label.data.shape)
    max_val = stc_label.data[max_vidx, max_tidx]
    if max_vidx < len(stc_label.vertices[0]):
        hemi = 'lh'
        max_vert = stc_label.vertices[0][max_vidx]
        max_vidx = list(stc.vertices[0]).index(max_vert)
    else:
        hemi = 'rh'
        max_vert = stc_label.vertices[1][max_vidx - len(stc_label.vertices[0])]
        max_vidx = list(stc.vertices[1]).index(max_vert)
        max_vidx += len(stc.vertices[0])
    del stc_label
    assert max_val == stc.data[max_vidx, max_tidx]

    # Get contiguous vertices within 50%
    threshold = max_val * thresh
    connectivity = spatial_src_adjacency(src, verbose='error')  # holes
    _, clusters, _, _ = spatio_temporal_cluster_1samp_test(
        np.array([stc.data]), threshold, n_permutations=1,
        stat_fun=lambda x: x.mean(0), tail=1,
        connectivity=connectivity)
    for cluster in clusters:
        if max_vidx in cluster[0] and max_tidx in cluster[1]:
            break  # found our cluster
    else:  # in case we did not "break"
        raise RuntimeError('Clustering failed somehow!')
    if hemi == 'lh':
        verts = stc.vertices[0][cluster]
    else:
        verts = stc.vertices[1][cluster - len(stc.vertices[0])]
    func_label = Label(verts, hemi=hemi, subject=stc.subject)
    func_label = func_label.fill(src)
    return func_label, max_vert, max_vidx, max_tidx
Exemplo n.º 13
0
def get_surface_labels(surface, texture, subject, hemi):
    """get areas on the surface

    Parameters
    ----------
    surface : instance of Surface
    texture : str | array
        Array to get areas or the filename to get this
    subject : str
        Name of the subject
    hemi : 'lh' | 'rh'
        Name of the hemisphere
    fname_atlas : str | None
        Filename for area atlas
    fname_color : str | None
        Filename for area color

    Returns
    -------
    labels : instance of mne.Labels
        MarsAtlas labels for surface sources
    """

    labels = []

    rr = surface['rr']
    # normals = surface['nn']

    # Get texture with gifti format (BainVisa)= labels of MarsAtlas
    if isinstance(texture, str):
        giftiImage = gifti.giftiio.read(texture)
        base_values = giftiImage.darrays[0].data

    else:
        base_values = texture

    values = base_values

    # Get parcels and count the number of nodes in each parcel (count)
    parcels, counts = np.unique(values, return_counts=True)

    # Get parcels information
    # info = read_texture_info(fname_atlas, hemi)
    from bv2mne.marsatlas_parcels import ma_parcels
    info = ma_parcels

    # Get triangles for whole surface
    triangles = surface['tris']
    total_nodes = 0
    for pos, val in enumerate(parcels):

        name_process = info.get(parcels[pos], False)
        if not name_process:
            name = 'no_name'
            # lobe = 'no_name'
        else:
            name = name_process[0]
            # lobe = name_process[1]

        # Find index for nodes of the parcel
        ind = np.where(values == val)

        # Keep only those nodes and pos of parcel that are associated with a
        # face (triangle) in its parcel
        # get triangles where points of the parcel are
        ix = np.in1d(triangles.ravel(), ind).reshape(triangles.shape)

        # Counting the number of True per lines --> True : 1 , False : 0
        # to know how many points of the parcel are in each face
        counts = ix.sum(1)

        # Indices of each triangles that contains 3 points of the parcel
        ind_all = np.where(counts == 3)
        tris_cour = triangles[ind_all]

        # Select nodes that are connected through triangles
        nodes = np.unique(tris_cour)
        iy = np.in1d(ind, nodes)
        ind_n = np.where(iy)
        ind_n = ind_n[0]
        ind = ind[0]

        # Positions and normals
        rr_parcel = rr[ind[ind_n]]
        # normals_parcel = normals[ind[ind_n]]

        # Textures (values)
        values_parcel = values[ind[ind_n]]
        # values_parcel = ind                 ############check#############

        # Locations in meters
        # rr_parcel = rr_parcel * 1e-3

        # Number of nodes
        nodes, tmp = rr_parcel.shape
        # vertex_ind = np.arange(total_nodes, total_nodes + nodes, 1)
        vertex_ind = ind[ind_n]
        total_nodes = total_nodes + nodes  # (was =+???)

        label = Label(vertices=vertex_ind,
                      pos=rr_parcel,
                      values=values_parcel,
                      hemi=hemi,
                      comment=name,
                      name=name,
                      filename=None,
                      subject=subject,
                      verbose=None)

        labels.append(label)

    return labels
Exemplo n.º 14
0
def test_extract_label_time_course(kind, vector):
    """Test extraction of label time courses from (Mixed)SourceEstimate."""
    n_stcs = 3
    n_times = 50

    src = read_inverse_operator(fname_inv)['src']
    if kind == 'mixed':
        label_names = ('Left-Cerebellum-Cortex', 'Right-Cerebellum-Cortex')
        src += setup_volume_source_space('sample',
                                         pos=20.,
                                         volume_label=label_names,
                                         subjects_dir=subjects_dir,
                                         add_interpolator=False)
        klass = MixedVectorSourceEstimate
    else:
        klass = VectorSourceEstimate
    if not vector:
        klass = klass._scalar_class
    vertices = [s['vertno'] for s in src]
    n_verts = np.array([len(v) for v in vertices])
    vol_means = np.arange(-1, 1 - len(src), -1)
    vol_means_t = np.repeat(vol_means[:, np.newaxis], n_times, axis=1)

    # get some labels
    labels_lh = read_labels_from_annot('sample',
                                       hemi='lh',
                                       subjects_dir=subjects_dir)
    labels_rh = read_labels_from_annot('sample',
                                       hemi='rh',
                                       subjects_dir=subjects_dir)
    labels = list()
    labels.extend(labels_lh[:5])
    labels.extend(labels_rh[:4])

    n_labels = len(labels)

    label_tcs = dict(mean=np.arange(n_labels)[:, None] *
                     np.ones((n_labels, n_times)))
    label_tcs['max'] = label_tcs['mean']

    # compute the mean with sign flip
    label_tcs['mean_flip'] = np.zeros_like(label_tcs['mean'])
    for i, label in enumerate(labels):
        label_tcs['mean_flip'][i] = i * np.mean(label_sign_flip(
            label, src[:2]))

    # generate some stc's with known data
    stcs = list()
    pad = (((0, 0), (2, 0), (0, 0)), 'constant')
    for i in range(n_stcs):
        data = np.zeros((n_verts.sum(), n_times))
        # set the value of the stc within each label
        for j, label in enumerate(labels):
            if label.hemi == 'lh':
                idx = np.intersect1d(vertices[0], label.vertices)
                idx = np.searchsorted(vertices[0], idx)
            elif label.hemi == 'rh':
                idx = np.intersect1d(vertices[1], label.vertices)
                idx = len(vertices[0]) + np.searchsorted(vertices[1], idx)
            data[idx] = label_tcs['mean'][j]
        for j in range(len(vol_means)):
            offset = n_verts[:2 + j].sum()
            data[offset:offset + n_verts[j]] = vol_means[j]

        if vector:
            # the values it on the Z axis
            data = np.pad(data[:, np.newaxis], *pad)
        this_stc = klass(data, vertices, 0, 1)
        stcs.append(this_stc)

    if vector:
        for key in label_tcs:
            label_tcs[key] = np.pad(label_tcs[key][:, np.newaxis], *pad)
        vol_means_t = np.pad(vol_means_t[:, np.newaxis], *pad)

    # test some invalid inputs
    with pytest.raises(ValueError, match="Invalid value for the 'mode'"):
        extract_label_time_course(stcs, labels, src, mode='notamode')

    # have an empty label
    empty_label = labels[0].copy()
    empty_label.vertices += 1000000
    with pytest.raises(ValueError, match='does not contain any vertices'):
        extract_label_time_course(stcs, empty_label, src)

    # but this works:
    with pytest.warns(RuntimeWarning, match='does not contain any vertices'):
        tc = extract_label_time_course(stcs,
                                       empty_label,
                                       src,
                                       allow_empty=True)
    end_shape = (3, n_times) if vector else (n_times, )
    for arr in tc:
        assert arr.shape == (1 + len(vol_means), ) + end_shape
        assert_array_equal(arr[:1], np.zeros((1, ) + end_shape))
        if len(vol_means):
            assert_array_equal(arr[1:], vol_means_t)

    # test the different modes
    modes = ['mean', 'mean_flip', 'pca_flip', 'max', 'auto']

    for mode in modes:
        if vector and mode not in ('mean', 'max', 'auto'):
            with pytest.raises(ValueError, match='when using a vector'):
                extract_label_time_course(stcs, labels, src, mode=mode)
            continue
        label_tc = extract_label_time_course(stcs, labels, src, mode=mode)
        label_tc_method = [
            stc.extract_label_time_course(labels, src, mode=mode)
            for stc in stcs
        ]
        assert (len(label_tc) == n_stcs)
        assert (len(label_tc_method) == n_stcs)
        for tc1, tc2 in zip(label_tc, label_tc_method):
            assert tc1.shape == (n_labels + len(vol_means), ) + end_shape
            assert tc2.shape == (n_labels + len(vol_means), ) + end_shape
            assert_allclose(tc1, tc2, rtol=1e-8, atol=1e-16)
            if mode == 'auto':
                use_mode = 'mean' if vector else 'mean_flip'
            else:
                use_mode = mode
            # XXX we don't check pca_flip, probably should someday...
            if use_mode in ('mean', 'max', 'mean_flip'):
                assert_array_almost_equal(tc1[:n_labels], label_tcs[use_mode])
            assert_array_almost_equal(tc1[n_labels:], vol_means_t)

    # test label with very few vertices (check SVD conditionals)
    label = Label(vertices=src[0]['vertno'][:2], hemi='lh')
    x = label_sign_flip(label, src[:2])
    assert (len(x) == 2)
    label = Label(vertices=[], hemi='lh')
    x = label_sign_flip(label, src[:2])
    assert (x.size == 0)