Git Product home page Git Product logo

brainspace's Introduction

BrainSpace

BrainSpace is a lightweight cross-platform toolbox primarily intended for macroscale gradient mapping and analysis of neuroimaging and connectome level data. The current version of BrainSpace is available in Python and MATLAB, programming languages widely used by the neuroimaging and network neuroscience communities. The toolbox also contains several maps that allow for exploratory analysis of gradient correspondence with other brain-derived features, together with tools to generate spatial null models.

For installation instructions, examples and documentation of BrainSpace see our documentation.

Happy gradient analysis!

License

The BrainSpace source code is available under the BSD (3-Clause) license.

Support

If you have problems installing the software or questions about usage and documentation, or something else related to BrainSpace, you can post to the Issues section of our repository.

Paper

If you consider using BrainSpace, please cite our manuscript: Vos de Wael R, Benkarim O, Paquola C, Lariviere S, Royer J, Tavakol S, Xu T, Hong S, Langs G, Valk S, Misic B, Milham M, Margulies D, Smallwood J, Bernhardt B (2020). BrainSpace: a toolbox for the analysis of macroscale gradients in neuroimaging and connectomics datasets. Commun Biol 3, 103.

Core development team

  • Reinder Vos de Wael, MICA Lab - Montreal Neurological Institute
  • Oualid Benkarim, MICA Lab - Montreal Neurological Institute
  • Boris Bernhardt, MICA Lab - Montreal Neurological Institute

brainspace's People

Contributors

anibalsolon avatar danjgale avatar ghisvail avatar htwangtw avatar josemariamoreira avatar manea006 avatar margulies avatar neuroimagingdatascience avatar oualidbenkarim avatar reindervosdewael avatar victoris93 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

brainspace's Issues

load_hemipheres is crashing python jupyter

Hi guys,

We've had problems with our jupyter kerner crashing when we try to run the load_hemipheres command. Is this a known issue? Are there any extra dependencies we are missing?

Too slow when running gm.fit on vertice

Hi,

Current version works fine (~minutes) when running gm.fit() with cosine/normalized_angle kernel for node-based connectivity matrix (e.g. 400 nodes for Schaefer atlas), but it could be really slow (~hours) when running on huge-size vertex-based connectivity matrix (e.g. 32k for fs_LR space, or 20k for fsaverage5 space).

One way for speedup is using gpu-torch methed torch.nn.functional.cosine_similarity(x[:, None, :], x[None, :, :], dim=-1), but CUDA out of memory becomes another problem.

I suggest to replace line 27 with 1 - sklearn.metrics.pairwise_distances(x, metric = 'cosine'). In my test of affinity matrix computing, sklearn method is more efficient than scipy method.

Chenfei

error handling of 0 rows

Trying to fit data that contains a row of entirely 0s currently returns all NaNs in the output gradients when kernel='cs' or kernel='na' (python version). Ideally, this should throw an error or perhaps rows containing all 0s should simply be discarded before this line:

x = 1 - squareform(pdist(x, metric='cosine'))

Odd Hemispheric Gradients

Hi Reinder, Oualid, and Boris,

I'm getting some odd outputs from running the diffusion embedding algorithm. I've attached images of the first three gradients. These are the mean gradient (mean of Procustes-aligned gradients) for n=82 healthy young adults. Each individual subject also had more or less similar gradients when looked at individually pre-alignment.

I've run this exact same code on a different dataset and have not gotten these odd results. The vertex-wise timeseries for the sessions, as well as the Z matrices, do not show any clearly discernible hemisphere differences. Our QC metrics on the data and the conversion from volume to surface space also don't shed light on the issue as far as I can tell. In addition, this data has been used for other projects and a clear hemispheric pattern was not observed.

Any thoughts on what might be going on? See below for the code that I used to compute these gradients.

Thanks in advance,
Manesh

G1_young
G2_young
G3_young

curr_Z = gradients_getZ(sess_folder, sess1_left, sess1_right, sess2_left, sess2_right);

young_toRemove(k,:)=all(curr_Z==0,2); % get columns that contain a zero
curr_remove=young_toRemove(k,:);
curr_Z(curr_remove',:)=[];
curr_Z(:,curr_remove)=[];

gm = GradientMaps();

curr_gm = gm.fit(curr_Z);
gradients_young{k,:}.gradients = curr_gm.gradients;
gradients_young{k,:}.lambda = curr_gm.lambda;

%% add back in removed values

for i=1:82 % for each subject

young_gradient_vectors=gradients_young{i, 1}.gradients{:, 1};
idx=find(young_toRemove(i,:));

for k=1:10 % for each gradient

curr_gradient_young(:,k)=single(zeros(10000,1));
c=0;

for j=1:10000 % for each vertex
    
    if ~ismember(j,idx)
        c=c+1;
        curr_gradient_young(j,k)=young_gradient_vectors(c,k); 
    else
        curr_gradient_young(j,k)=0;
    end
end
end
young_gradients_unaligned{1,i}=curr_gradient_young;
end
function Z = gradients_getZ(dataDir, fileName, fileName2, fileName3, fileName4)

mgh_name = [dataDir filesep  fileName];
data = MRIread(mgh_name);
TSleft1 = squeeze(data.vol)';

mgh_name = [dataDir filesep fileName2];
data = MRIread(mgh_name);
TSright1 = squeeze(data.vol)';

mgh_name = [dataDir filesep  fileName3];
data = MRIread(mgh_name);
TSleft2 = squeeze(data.vol)';

mgh_name = [dataDir filesep fileName4];
data = MRIread(mgh_name);
TSright2 = squeeze(data.vol)';

TS1=[TSleft1 TSright1];
TS2=[TSleft2 TSright2];
 
 %% downsample TS from fsa5 (20484) to fsa 10K
load('/lbc/lbc1/derivatives/MG/aging_gradients/fsa5_to_fsa10k/fsa5_to_fsa_10k.mat')
load('/lbc/lbc1/derivatives/MG/aging_gradients/fsa5_to_fsa10k/fsa_10k_mask.mat')

FSA10k_1=zeros(200,10000);
FSA10k_2=zeros(200,10000);

for i=1:20484
    if ~isempty(find(id_20k_to_10k==i))
        idx=find(id_20k_to_10k==i);
        FSA10k_1(:,idx)=TS1(:,i);
        FSA10k_2(:,idx)=TS2(:,i);   
    end
end
clear TS1 TS2 TSleft1 TSleft2 TSright1 TSright2

FSA10k_1(~mask_10k)=0;
FSA10k_2(~mask_10k)=0;

%%
R(:,:,1)= corr(single(FSA10k_1));
R(:,:,2)= corr(single(FSA10k_2));
R=nanmean(R,3);

Z = atan(R);
Z(isnan(Z)) = 0;
Z(isinf(Z)) = 0;

VTK error when running example data

Hi:
An error has occurred when I running the example data,
Traceback (most recent call last):
File "C:\Users\11481\PycharmProjects\untitled\venv\lib\site-packages\brainspace\vtk_interface\wrappers\base.py", line 203, in getattr
return VTKMethodWrapper(super().getattr(name))
File "C:\Users\11481\PycharmProjects\untitled\venv\lib\site-packages\vtkmodules\numpy_interface\dataset_adapter.py", line 130, in getattr
return getattr(self.VTKObject, name)
AttributeError: 'vtkmodules.vtkCommonDataModel.vtkPolyData' object has no attribute 'len'

My system is win10, and vtk version is 9.0.3. Could you tell me how to solve the problem

Thanks

Custom/other parcellations

Dear BrainSpace team,

Thank you for an amazing tool and really clear documentation!

Just a quick question that I wasnt able to resolve from the docs:
Is there a way to load a custom parcellation for visualisation purposes?

A more granular functional parcellation Schaefer 1000 as well as other anatomical parcellations such as Glasser might be useful and the current available parcellations are slightly limiting.

Thank you in advance for your help

Bw
Angelika

The gradients reversed when remove some features

Hi:
I used the genetic data to build my network and correlated it with the other MRI-based network gradients. 2000 genes were included in my network, and I want to estimate the importance of one gene. Thus, I removed the gene from my network. As a result, I found the gradients were changed from positive to negative, e.g. from 0.63 to -0.62. However, after Procrustes alignment, the alignment gradients return a positive result, such as 0.62. I want to know if the result is reasonable, and the alignment is necessary?
Thank you for providing such a convenient tool.

Ray

How to save the hemisphere plots from the plotter?

Hi,

Thanks for providing this useful toolkit. I have created a plotting.base.plotter using this code in python:

plotter = plot_hemispheres(surf_lh, surf_rh, array_name=grad, size=(1200, 400),
cmap='viridis_r', color_bar=True,
label_text=['Grad1', 'Grad2', 'Grad3', 'Grad4', 'Grad5',
'Grad6', 'Grad7', 'Grad8', 'Grad9', 'Grad10'],
zoom=1.5, embed_nb=False, return_plotter=True)

I wonder if and how I can save the plotter as an image.

Thanks
Rui

Some problems about schaefer_1000

  • What is the current behavior?
    I get functional connectivity matrix 1000*1000 and gradient matrix of dimension 1000.
    but {plot_hemispheres} function does not have schaefer_1000_conte69.csv. so I want to know that how to get file {schaefer_1000_conte69.csv} and plot gradient to surface.

Procrustes alignment may reorder the embedding components or/and change the gradient values locally

Hi!

Thank you for developing this awesome tool!

I am trying to map the gradients in individual connectivity and age-group-wise connectivity in a longitudinal dataset, and I used Procrustes alignment to align these gradients to a template (gradient computed based on averaged connectivities of all subjects). I found the alignment may reorder the embedding components or/and change the gradient values locally. Besides, I also found the eigenvalue vector 'lambda' didn't change after doing this alignment, Does it mean the vector still corresponds to the original gradients, not the aligned one? I'm puzzling whether this operation may weaken the age-related changes of the gradients. Can you give me some advice about that? any suggestions will be welcome. Thank you!

Have a good day!

Zeng

Very low eigenvalues when kernel is manually set to normalized_angle

When I follow this tutorial, I noticed that the default setting for kernel is actually None instead of normalised angle as stated in the tutorial.

If I manually set kernel = normalised angle instead of leaving it to the default then the lambdas have very low values. Is this expected?

This is the code from the tutorial when the kernel is set to default (None) and when the kernel is set to 'normalized_angle:

`

import warnings

warnings.simplefilter('ignore')

from brainspace.datasets import load_group_fc, load_parcellation, load_conte69

First load mean connectivity matrix and Schaefer parcellation

conn_matrix = load_group_fc('schaefer', scale=400)
labeling = load_parcellation('schaefer', scale=400, join=True)

and load the conte69 hemisphere surfaces

surf_lh, surf_rh = load_conte69()
from brainspace.gradient import GradientMaps

Ask for 10 gradients (default)

gm = GradientMaps(n_components=10, random_state=0)
gm.fit(conn_matrix)
import matplotlib.pyplot as plt
plt.scatter(range(gm.lambdas_.size), gm.lambdas_)

Ask for 10 gradients (normalized_angle)

gm = GradientMaps(n_components=10,kernel = 'normalized_angle', random_state=0)
gm.fit(conn_matrix)
import matplotlib.pyplot as plt
plt.scatter(range(gm.lambdas_.size), gm.lambdas_)
`
I have attached the figure which plots both the default (blue) and the normalized_angle (orange).

comparison_tutorial

Comparing groups and projecting to 3D/4D volumes/meshes in BrainSpace (Python)

Hello!

I am trying to figure out the best way to compare gradient maps between groups after determining gradient using BrainSpace in Python. My current implementation computes individual-level gradient maps, then aligns them with a Procrustes transformation. See the following code:

import numpy as np
from brainspace.gradient import GradientMaps
from brainspace.gradient.alignment import ProcrustesAlignment 

#conn_matrices is list of symmetrical functional connectivity 
#   matrices as np.arrays for each subject -- using 400 Schaefer atlas

subj_gradients = [] #init list for GradientMaps objects
for index, subj in enumerate(conn_matrices):
    print(index) #print subject index to screen
    g_ind = GradientMaps(kernel='normalized_angle', random_state=0)
    g_ind.fit(subj)
    subj_gradients.append(g_ind.gradients_)

# subj_gradients is now a list of n_subject numpy arrays with shape: 
#    n_parcels x n_components 

# Procrustes align all subjects
# using ProcrustesAlignment() because the method in `GradientMaps` class 
#   (setting alignment='procrustes') only works for two group-level 
#   functional connectivity matrices
align_class = ProcrustesAlignment()
aligned_subjs = align_class.fit(subj_gradients)

Now, aligned_subjs.aligned_ is also a list of n_subject numpy arrays (with shape: n_parcels x n_components). Upon visual inspection, this alignment method seems to work pretty well across individuals! Please let me know if there is another recommended approach though.

To compare groups at each parcel, can I just conduct a non-parametric independent-samples t-test (of sorts)? Do I need to account for the spatial autocorrelation that is resolved through a method similar to the spin permutation test?

Furthermore, I am wondering BrainSpace contains any functionality to easily save any of the above instances as 3D/4D volumes or meshes? For example, can I project a GradientMaps class computed in BrainSpace to a 4D volume with each volume containing data from one of the gradient maps?

Thanks so much for your help!

[DOC] Confusing MATLAB tutorial 2

MATLAB tutorial 2 is a bit confusing on the order of the aligned gradients in the aligned field. Specifically, the numbering of the input gradients is matrix 2, 1 but the labels of the plotted figure use the reverse numbers.

misalignment between left and right diffusion maps (matlab version)

Hi!

I' trying to generate diffussion maps for the left and right hemispheres using following codes:

gm = GradientMaps('kernel','na','approach','dm','n_components',2, 'alignment', 'pa', 'random_state', 10);
gm = gm.fit({left_fc_matrix, right_fc_matrix});

however, directions of the principal gradients between the two hemispheres are opposite.
Could you have any suggestions about how to align the two principal gradients? Thank you very much.

Best,
Luqi

G

The results for gradients 1 and 2 are reversed

Hi, Thank you for noticing this issue.
When I used the BrainSpace to compute the gradeint, I got and visualized the gradient 1 and gradient 2. Contrary to the canonical gradients established by Margulies(2016), it seems that my Gradient 1 is similar to canonical gradient2, while my Gradient 2 is similar to canonical gradient1. Has anything like that ever happened to you? Could you provide some suggestion to me ? My computing environment is Matlab 2018a and BranSpace 0.1.1

Alternative layout in plot_hemispheres

First off, thank you for such a great package. It has been helpful in my own studies!

I was wondering how I would go about plotting my surfaces in adifferent layout -- a 2x2 grid with the top row as lateral views and the bottom row as medial views. This is the default view in connectome workbench (see below) and it is used quite often:
S1200_midthickness_view

I noticed that the layout in plot_hemispheres is hardcoded, so I've been playing with the underlying code in plot_hemispheres with somewhat success, although I can't quite get the data to plot properly.

I am using a standalone example by taking these lines from plot_hemipsheres and making adjustments like so:

import numpy as np
from brainspace import plotting, datasets

lh, rh = datasets.load_conte69()
conn_matrix = datasets.load_group_fc('schaefer', scale=400)
labeling = datasets.load_parcellation('schaefer', scale=400, join=True)

# these are the inputs to `plot_hemispheres`
array_name = labeling
surf_lh = lh
surf_rh = rh


surfs = {'lh': surf_lh, 'rh': surf_rh}
layout = ['lh', 'lh', 'rh', 'rh']
view = ['lateral', 'medial', 'lateral', 'medial']


if isinstance(array_name, np.ndarray):
    if array_name.ndim == 2:
        array_name = [a for a in array_name]
    elif array_name.ndim == 1:
        array_name = [array_name]


if isinstance(array_name, list):
    layout = [layout] * len(array_name)
    array_name2 = []
    n_pts_lh = surf_lh.n_points
    for an in array_name:
        if isinstance(an, np.ndarray):
            name = surf_lh.append_array(an[:n_pts_lh], at='p')
            surf_rh.append_array(an[n_pts_lh:], name=name, at='p')
            array_name2.append(name)
        else:
            array_name2.append(an)
    array_name = np.asarray(array_name2)[:, None]
    
# reshape to 2x2
array_name = np.full((2, 2), fill_value=array_name[0][0], dtype='S50') 
layout = np.array(layout).reshape(2, 2).T.tolist()
view = view = [['lateral', 'medial'], ['medial', 'lateral']]

plotting.plot_surf({'lh': surf_lh, 'rh': surf_rh}, layout=layout, array_name=array_name, 
                   view=view, embed_nb=True, nan_color=(.6, .6, .6, 1), 
                   size=(400, 300), zoom=1.5)

Produces:

Screenshot from 2021-03-23 09-11-48

As you can see, none of the actual data is plotted, but the layout is correct. Thoughts?

Also, if you were interested in adding this layout as an option, I would be happy to work on it and submit a PR, as I think a lot of people would find it useful!

How to get the FC matrix from my own data?

I can run BrainSpace based on the example data, but I noted that the FC matirx used in Brainspace was different from which I usually used, I want to get the FC matrix from my own rs-fMRI data, would you please provide a guideline about the preprocessing of rs-fMRI data and construction of FC matrix ?

Matlab - out of memory error for matrix sparsification

For very large matrices I had an out of memory error at this line. Matlab memory usage was much lower than the total memory available. However, with the following replacement it worked.

p = prctile(data, p.Results.sparsity);
for i = 1: length(data)
	col = data(:, i);
	col(col<p) = 0;
	data(:, i) = col;
end

Difference between BrainSpace and original Margulies PNAS 2016 methods

Hi,

I have a curious question regarding the difference in the embedding calculations of Brain Space and the one used in the 2016 PNAS paper by Margulies et al. I have tried feeding the same z matrix into both set of codes. Both used the same methods and parameters for thresholding, affinity matrix calculation and embedding (alpha, diffusion time). However there are some variations in the gradient unit (-0.1->0.1 vs -10->15) and especially the amount of variance explained by the top 2 gradients (11% and 10.6% for Brainspace vs 30.9% and 19.2% for Margulies PNAS 2016). The correlation of the 2 gradients between the methods are relatively high (>0.9 for both) but I'm curious on why the component variance as calculated by the ratio of lambda differs so much. Any explaination would be much appreciated!

Have a good day!
Sophia

fsaverage6 plot_hemispheres

Thank you for the very helpful package for analysis. I am pretty new to this area so I have a question regarding the surface space. My connectivity matrix was formulated using the Schaefer 400 parcellation from data mapped onto the fsaverage6 surface. I noted that the labels and surfaces here are all Conte69 surface. I am just wondering if it is possible to plot the gradient with fsaverage6? Does that actually even matter at all? Much thanks!

integrating braincpace-plotting functionality in another package

I am tying to integrate the plotting functionality of brainspace into brainstat. Therefore, vtk_interface and plotting submodules are now copied in brainstat.

However, running the plot_hemispheres function with brainstat does not work the same way as for brainspace.

>>> import brainspace
>>> brainspace.__version__
'0.1.4'

>>> from brainspace.datasets import load_fsa5
>>> surf_lh, surf_rh = load_fsa5()


>>> from brainstat.tutorial.utils import fetch_mics_data

>>> thickness, demographics = fetch_mics_data(')
>>> values = np.mean(thickness, axis=0)

>>> from brainspace.plotting.surface_plotting import plot_hemispheres
>>> plot_hemispheres(surf_lh, surf_rh, array_name=values, size=(1200, 400), 
cmap='viridis_r',color_bar=True, zoom=1.5, interactive=True)

this works perfectly fine!

However, the same command does not work when I import plot_hemispheres from brainstat:

>>> from brainstat.plotting.surface_plotting import plot_hemispheres
>>> plot_hemispheres(surf_lh, surf_rh, array_name=values, size=(1200, 400), 
cmap='viridis_r',color_bar=True, zoom=1.5, interactive=True)

Here is the error:

...
  File "/data/u_bayrak_software/anaconda3/envs/bstat/lib/python3.8/site-packages/brainstat-0.3.6-py3.8.egg/brainstat/vtk_interface/wrappers/utils.py", line 160, in call_vtk
    return getattr(obj, method)(args)
  File "/data/u_bayrak_software/anaconda3/envs/bstat/lib/python3.8/site-packages/brainstat-0.3.6-py3.8.egg/brainstat/vtk_interface/wrappers/base.py", line 35, in __call__
    return _wrap_output_data(self.name(*args, **kwargs))
**TypeError: SetInputDataObject argument 1: method requires a VTK object**

Any help on solving this TypeError is appreciated!

overlaying arrays, separate color maps

Hi

I'm interested in overlaying arrays onto the same surface. Let's say I have two arrays, one corresponding to a resting-state network, and another corresponding to the areal boundaries of a cortical atlas / custom parcellation. For the resting-state network, we'd use some colormap like "hot" for continuous values, while for the boundaries, we'd use a separate binary color map like "gray", I can plot these two maps separately as

import nibabel as nb
from brainspace import plotting, mesh, utils
from brainspace.vtk_interface.wrappers import BSPolyData

boundary_file = './L.boundaries.func.gii'
boundaries = nb.load(boundary_file).darrays[0].data

network_file = './L.networks.func.gii'
network = nb.load(network_file).darrays[0].data

surface_file = './L.inflated.gii'
BSD = BSPolyData(mesh.mesh_io.read_surface(surface_file))
BSD.append_array(network, name='network')
BSD.append_array(boundaries, name='boundary')

P = plotting.plot_surf(surfs={1: BSD},
                           layout = [1,1],
                           array_name = ['network', 'boundary'],
                           embed_nb = True,
                           cmap = ['hot', 'gray'],
                           color_bar='bottom',
                           view = ['lateral', 'lateral'],
                           background = (0,0,0),
                           nan_color=(0.85, 0.85, 0.85, 1), 
                           zoom=1,
                           size=(1000, 1000),
                           share=False,
                           interactive=False, 
                           return_plotter=True)

P.show(embed_nb=True)

How can I overlay them instead on a single surface?

Thanks!

diffusion map embedding generates different results each run (python version)

Hi!

When running diffusion map embedding in the python version using a parcellation of 91 parcels, results are not reproducible, e.g. the numbers change every iteration. This is not the case when using PCA or le, or when using a parcellation with 400 parcels. Would you have any explanation for this behaviour?

cheers,
Sofie

Changing colorbar labels

Hi

Thank you for developing this package! I would like to change the tick labels on the colorbars, but I am not very familiar with VTK. I have found the 'cb__' kwargs parameter, and can change the colorbar size (width and height).

I would like to be able to specify what to display at the colorbar ticks i.e. instead of [max(scalar map), min(scalar map)], I would like to display ['some text', 'some other text']. How can I do this?

Thanks!

Subject list for group connectivity matrices

I was wondering if the list of HCP subjects used for the group functional connectivity matrices with load_group_fc/load_group_mpc was available. My understanding/assumption is that these subsets of HCP data are based on the selection procedures described in Vos de Wael et al (2018), but I'm not 100% certain in that.

I'm looking to compute similar connectivity matrices on the samples used in Vos de Wael et al (2018), but I also think it would be great if the documentation could clarify the source of the group connectivity matrices.

Plotting Gradient using plot_hemispheres

Hi,
Using the gradient_in_euclidean function, we can clearly note the area that has not been covered in the scan as seen by the grey mask. However, the plot_hemispheres mask uses dark blue which is the same color as other regions of the brain which has lower gradient value. Is there a way for me to customize so that the area where the label value = 0 (aka. not covered in scan/parcellation) can be set in gray/different color scheme?

Much thanks!

plot_hemispheres() crashes Google Colab

Hi everyone,

I am trying to use BrainSpace on Google Colab. However, Colab is getting crashed whenever I run plot_hemispheres() function. I tried the tutorial codes provided on https://brainspace.readthedocs.io/en/latest/python_doc/auto_examples/index.html

None of them is working on Colab, whereas they work on my local machine. Is there a way around solving this problem?

You can also access my code here: https://colab.research.google.com/drive/11RDqIxQQp0i6QMMx8L67C9G3IJ5yplen?usp=sharing

Kind regards.

Latest (0.1.3) not compatible with new vtk

  • What is the current behavior?
    The newest VTK release candidate (9.2.0rc1) is incompatible.

  • Please provide the steps to reproduce and if possible a minimal demo of the problem.

$ python -c "from brainspace.mesh.mesh_io import read_surface"

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/mathiasg/.pyenv/versions/nipreps/lib/python3.10/site-packages/brainspace/mesh/__init__.py", line 1, in <module>
    from . import (array_operations, mesh_elements, mesh_correspondence,
  File "/Users/mathiasg/.pyenv/versions/nipreps/lib/python3.10/site-packages/brainspace/mesh/array_operations.py", line 22, in <module>
    from . import mesh_elements as me
  File "/Users/mathiasg/.pyenv/versions/nipreps/lib/python3.10/site-packages/brainspace/mesh/mesh_elements.py", line 16, in <module>
    from ..vtk_interface import wrap_vtk, serial_connect
  File "/Users/mathiasg/.pyenv/versions/nipreps/lib/python3.10/site-packages/brainspace/vtk_interface/__init__.py", line 1, in <module>
    from .wrappers.base import (wrap_vtk, unwrap_vtk, wrap_vtk_array,
  File "/Users/mathiasg/.pyenv/versions/nipreps/lib/python3.10/site-packages/brainspace/vtk_interface/wrappers/__init__.py", line 1, in <module>
    from .base import BSVTKObjectWrapper
  File "/Users/mathiasg/.pyenv/versions/nipreps/lib/python3.10/site-packages/brainspace/vtk_interface/wrappers/base.py", line 15, in <module>
    from .utils import call_vtk, get_vtk_methods, is_numpy_string, is_vtk_string
  File "/Users/mathiasg/.pyenv/versions/nipreps/lib/python3.10/site-packages/brainspace/vtk_interface/wrappers/utils.py", line 15, in <module>
    from vtk.util.vtkConstants import VTK_BIT, VTK_STRING, VTK_UNICODE_STRING
ImportError: cannot import name 'VTK_UNICODE_STRING' from 'vtk.util.vtkConstants' (/Users/mathiasg/.pyenv/versions/nipreps/lib/python3.10/site-packages/vtkmodules/util/vtkConstants.py)
  • What is the expected behavior?
    No error

  • Please tell us about your computing environment:
    macOS 12.4
    Python 3.10 with vtk 9.2.0rc1, but extends down to py3.7

problem with VTK for plot_hemispheres

I'm stuck at the plot_hemispheres line

I get this error message, it seems like it's a problem with vtk and not brai space but would anyone know how to solve this VTK issue?

ERROR: In /work/standalone-x64-build/VTK-source/Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx,
line 273
vtkXOpenGLRenderWindow (0x3b33610): bad X server connection. DISPLAY=Aborted (core dumped)

Different dimensions of timeseries and atlas

Dear all,

I am using the fmriprep output which has the dimension of [325325, 238]. E.g. as in the example given using the atlas = datasets.fetch_atlas_surf_destrieux() only has 20484 regions.
What do you suggest to fit the timeseries fmriprep output to an surface atlas?

Best,

color_range option not able to specify

HI,
Cool toolbox!
I'm not able to set the color_range option for visualization in python.
The following line works.
plot_hemispheres(surf_lh, surf_rh, array_name=grad, cmap='viridis_r', color_bar=True, label_text=label_text)

But adding color_range= (-0.3, 0.3 ) gived vtk related errors.

Traceback (most recent call last):
File "", line 1, in
"... brainspace/vtk_interface/decorators.py", line 175, in _wrapper_wrap
data = func(*args, **kwds)
"... brainspace/plotting/surface_plotting.py", line 360, in plot_hemispheres
interactive=interactive, embed_nb=embed_nb, **kwargs)
"... brainspace/plotting/surface_plotting.py", line 204, in plot_surf
p = Plotter(**kwargs)
"... brainspace/plotting/base.py", line 437, in init
iren=iren, offscreen=offscreen, **kwargs)
"... brainspace/vtk_interface/decorators.py", line 175, in _wrapper_wrap
data = func(*args, **kwds)
"... brainspace/plotting/base.py", line 217, in init
self.ren_win.setVTK(**kwargs)
"... brainspace/vtk_interface/base.py", line 380, in setVTK
self._handle_call('set', k, v)
"... brainspace/vtk_interface/base.py", line 285, in _handle_call
method = self.vtk_map[key][name.lower()]

some problems About schaefer_1000

  • What is the current behavior?

  • What is the motivation / use case for changing the behavior?

  • If relevant, please tell us about your computing environment:

  • Other information

Parcellation text labels

Hi, I was trying to extract parcel labels with the Matlab package
labeling = labeling.vosdewael_100;
and the results are numeric parcel labels. I was wondering if there is a way to get the text labels for each ROI and the correspondence between the text and numeric labels.
Thanks!

Cannot plot in remote server

I'm trying to plot_hemishperes without showing the plots and just save the outputs in a remote server (connected via VScode). I get this error:

2021-12-21 13:35:42.964 (   2.130s) [        EEB5B740]vtkXOpenGLRenderWindow.:464    ERR| vtkXOpenGLRenderWindow (0x3d25310): bad X server connection. DISPLAY=
Aborted (core dumped)

I've tried the following. All of them work well in my local and all make the same error on the remote; I couldn't resolve the issue with VTK or make the rendering independent of it.

  • I get a brainspace.plotting.base.Plotter with return_plotter=True and then ._to_image(filename, scale=1, transparent_bg=True).
  • I get fig = plot_hemispheres(..., filename=filename, screenshot=True,
  • I tried fig = plot_hemispheres(..., embed_nb=True to get an ipython image, and then save it by open(fname, 'wb').write(fig.data)
  • I have also tried surfplot to employ savefig, and it's also dependent on VTK I guess.

The virtual environment is the same on both systems.

[Python] Workaround for plotting on remote server.

Many users have reported issues with using plot_hemispheres on a remote server. This issue stems from vtk, one of our dependencies, requiring a display to exist. If you are running into this issue, you may want to try this experimental workaround. If you do, please let us know whether this worked for you.

The workaround is as follows. First, install conda. Once installed, run the following:

conda config --add channels conda-forge
conda install mesalib --channel conda-forge --override-channels --freeze-installed
conda install vtk --channel conda-forge --override-channels --freeze-installed
# if conda tries to install a build of vtk that does not start with osmesa_* force this build using the following:
# Note that the exact vtk version and build may have to be adjusted in the future.
# conda install vtk==9.1.0=osmesa_py39h8ab48e2_107 --channel conda-forge --override-channels --freeze-installed

Bug in utils.py?

I am getting an error in this code BrainSpace/brainspace/gradient/utils.py
Here k is 1-.9 which is a float. But then it gets multiplied by nc and tuned into an int. That makes it a zero. I think you are missing *100 here?
if not is_thresh:
nr, nc = s.shape
if isinstance(k, float):
if not 0 < k < 1:
raise ValueError('When 'k' is float, it must be 0<k<1.')
k = int(nc * k)

    if k <= 0:
        raise ValueError('Cannot select 0 elements.')

diffusion time default value discrepancy

Hi,

The following may be on purpose (I find it a bit inconsistent though).

In gradient/embedding.py , the class DiffusionMaps has a default diffusion time value set to 1, I believe it should be 0.
The documentation of the class says the default is 0, also the function doing the work "diffusion_mapping" has default at 0.

A GradientMaps would inherit this time diffusion of 1, when doing something like in the documentation ie:

gm = GradientMaps(n_components=2, approach='dm', kernel='normalized_angle')
gm.fit(m) #this would have diffusion time of 1

--
Nicolas Ninin

Matlab - Diffusion mapping - eigs instead of eig

I have been working with the matlab version of BrainSpace for a few weeks now and I have encountered some memory problems. For reference, I am running voxel-wise rather than surface/parcellation-based analyses. I tried using eigs instead of eig for Diffusion Mapping and it seems the outcome is the same (and solved my memory issues). I saw that it's being used for Laplacian Eigenmaps so I was wondering whether there was any reason for not using it for Diffusion Mapping as well.

Thanks for your help!

Nifti to fsaverage surface

Hello,

First of all, thanks for this amazing repo.

I have a 3D nifti file that I would like to project to the fsaverage surface for a nice visualization output.
My nifti file is already in MNI space.

Is that possible using this tool?

Data:https://easyupload.io/260ldc
Pass: makis

0.1.4 release for VTK pre-release compatibility

A release (or pre-release) on PyPI that includes #75 would be appreciated. We run tests where we pip install --pre our whole dependency tree, and currently VTK having a pre-release is breaking with 0.1.3.

This would be easiest for me, but I know it's a chore for you, so if you don't have time to do it, we'll find a different solution.

[BUG] Failure in validation of graph edge properties

Some users are running into a bug in the graph function when running the tutorial scripts, however I have been unable to reproduce this bug.

For now I advise users with this bug to comment out the lines shown below of the GradientMaps script. Note that after commenting out these lines the toolbox will no longer check whether the affinity matrix is a connected graph. With resting-state data and default sparsity values it is unlikely for the affinity matrix to represent a disconnected graph, but be aware that this may be an issue with other types of data.

In a future update I'll remove the reliance on the graph function.

Comment out these lines:

if ~all(conncomp(graph(abs(data),'lower')) == 1) 
    error('Graph is not connected.')
end

Error log.

gm = GradientMaps();
gm = gm.fit(conn_matrix);
Launching BrainSpace, the gradient connectivity toolbox.
Set the kernel to: Normalized Angle.
Set the approach to: Diffusion Embedding.
Set the alignment to: None.
No random state initialization set.
Set the number of requested components to: 10.
 
Running gradient analysis...
Kernel: Normalized Angle
Approach: Diffusion Embedding
Alignment: None
Running with sparsity parameter: 90
Error using graph.validateEdgeProperties (line 375)
Edge properties must be a table.

Error in graph/set.EdgeProperties (line 330)
            G.EdgeProperties = graph.validateEdgeProperties(T);

Error in graph (line 278)
                    G.EdgeProperties = table(nonzeros(tril(A)), 'VariableNames',
                    {'Weight'});

Error in GradientMaps/approaches (line 275)
            if ~all(conncomp(graph(abs(data),'lower')) == 1)

Error in GradientMaps/fit (line 106)
            approaches(obj,kernel_data,approach_arg{:});

Question about 'procrustes'

Hi,
I'm learning to use BrainSpace for gradient calculation. And I have some questions about aligning the gradient components.
Usually, for fair comparisons, we need to align the gradient components of each individual to the group template. And "Procrustes alignment" seems a good choice. Should we put all individual data into this procedure at once? As an example in paper "BrainSpace: a toolbox for the analysis of macroscale gradients in neuroimaging and connectomics datasets", it appears that two subject data are added to the procedure at once (see figure below).
image
But I also find some papers that add the individual data, one by one. Importantly, the results of these two strategies are not consistent (.aligned_). I guess it because that reference template is associated with all individual data, as the figure below.
image
So which strategy is right or recommended?
Besides, if eigenvalue multiplicity or very close eigenvalues lead to different component orderings between individuals, could "Procrustes alignment" work this case out? would it realign the component orders?
Finally, I found some papers reported the explanation rate of component. In my opinion, it's the percentage of the lambda of that component to the total lambdas. If it is right, should we calculate all components (i.e., N-1, N is the size of similarity matrix) to obtain the total lambdas? Or the total lambdas are restricted by the component numbers that we set rather than the maximum component numbers. After "Procrustes alignment", is the explanation rate of component unchanged?

Thanks!

Inverse transform embedding value to surface, save as file

As BrainSpace currently supports plotting the embedding onto the surface, I wonder would it be helpful to have a inverse transform function so people can save the embedding as surface files. As BrainSpace currently supports plotting the embedding onto the surface, would it be possible to expose the private functions that does the inverse transformation?

Having a brief look I believe this function might be the core of it?

def _expand_arg(arg, name, shape, ref=None):
"""Broadcast arg and expand each entry according to ref.
Parameters
----------
arg : sequence
Sequence of elements to expand.
name : str
Argument name.
shape : tuple
The shape of the desired array.
ref : array of tuples, optional
Reference array of tuples. If None, only broadcast is used.
Returns
-------
expand : ndarray of tuples
An array with the new shape and with each entry having the same length
as its corresponding entry in the reference array.
"""

cc @anproulx

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.