netneurolab / neuromaps

A toolbox for comparing brain maps
https://netneurolab.github.io/neuromaps
Other
241 stars 55 forks source link

Applying neuromaps to subcortical segmentations #115

Closed Melissa1909 closed 10 months ago

Melissa1909 commented 1 year ago

Description of issue

Dear neuromaps developers, thank you for this really awesome tool! I want to spatially compare thalamic nuclei volumes (segmented in Freesurfer using the pipeline by Iglesias et al., 2018 with other brain maps restricted to the thalamus. As it was recommended to me before, I planned to use nulls.moran for brain maps restricted to some ROI, but I was wondering if "parcellation" is restricted to cortical ROIs. Is there a way to perform correlation between two brain maps restricted to the thalamus? Best, Melissa

Code of Conduct

VinceBaz commented 1 year ago

Hi @Melissa1909,

nulls.moran can indeed be used to correlate brain maps that are restricted to the thalamus. To do that, you would simply need to do:

from neuromaps import nulls
null_brain_maps = nulls.moran(nuclei_brain_map, atlas=`mni152`, density=`2mm`)

This would basically generate spatial nulls for the ROIs that don't have nan values. As long as all the voxels outside of the thalamic nuclei you want to look at have nan values, this should work. You actually do not need a parcellation: it is only needed when you have a parcellated brain map (i.e. a unique value for each parcel in a parcellation).

To compare your nuclei_brain_map to another brain map, all you need to do is then:

from neuromaps import stats
stats.compare_image(nuclei_brain_map, another_brain_map, nulls=null_brain_maps)

By default, compare_image ignores nan values, so the comparison would only be done between ROIs in the thalamus nuclei.

I hope I understood your question correctly and that my answer what helpful. If not, please let me know :)

Melissa1909 commented 1 year ago

Hi @VinceBaz, thanks for your quick response, that makes complete sense!

I am just wondering how to create an image that contains GMV values per voxel based on FreeSurfer's output? I have now generated an image with each voxel in one thalamic ROI containing the subject's volume of that ROI and would compare that with the gene expression map. Do you think that's a valid way to do it?

Thanks! Best, Melissa

Melissa1909 commented 1 year ago

Dockerfile_upload.txt

Hi, I actually ran into an issue with nulls.moran, raising an import error ("Cannot run moran null when 'brainspace' is not installed"). However, brainspace actually is installed inside my container and if I run docker run --rm -it neuromaps_mt:latest and then from brainspace.gradient import GradientMaps; gm = GradientMaps(n_components=2, approach='dm', kernel='normalized_angle'), it does not give me any error. Any idea what went wrong here? Thank you!! Best, Melissa

VinceBaz commented 1 year ago

For your first question:

If I understand correctly, you have a volumetric image and want to compare the volumes in one thalamic ROI to the gene expression map? If so, then what I proposed would indeed be a valid way to do it.

That being said, for the gene expression map, it might be a little bit tricky: in neuromaps, the gene expression map is available in fsaverage space (i.e. a surface-based coordinate system). Unfortunately, that means that in neuromaps, gene expression data is only available for the cortex (not the subcortex). If you want gene expression data for the thalamus, you would need to use abagen and since the gene expression dataset from the Allen Institute is not densely sampled, you would need to interpolate the data (and it very likely won't be perfect). If you're fine with this and still want gene expression data, you would need to use the abagen.get_interpolated_map function, with a list of genes you want to look at and a mask of the ROI of interest.

For your second question:

This is quite unexpected. I am not quite sure what is going on. Just by curiosity, does from brainspace.null_models.moran import MoranRandomization also works?

Melissa1909 commented 1 year ago

Q1: No, I have a volumetric image and want to compare the volumes of 26 ROIs per hemisphere, as parcellated with the [pipeline by Iglesias et al. 2018] (https://freesurfer.net/fswiki/ThalamicNuclei) to the gene expression map. Yes, I am aware that the gene expression data need to be extrapolated for that purpose.

Q2: This command gave an error regarding a missing Linux library (libXrender.so.1) - updated my Dockerfile, which will hopefully fix it.

VinceBaz commented 1 year ago

Hi Melissa. I see. So you basically have 26 values: one for each nuclei. In that case, you will indeed need a parcellation (sorry about my previous answers, I misunderstood what you were trying to do).

So, to answer your initial question: no, parcellation is not restricted to cortical ROIs. All you need is a parcellation (a nifti image in MNI space) where the background is set to 0 and each parcel is given an integer value ranging from 1 to 26. It does not matter whether the parcels are cortical or subcortical. So, your function call would look like this:

null_brain_maps = nulls.moran(nuclei_brain_map, atlas=`mni152`, density=`2mm`, parcellation=parcellation)

And for your second issue: let me know if updating your Dockerfile fixed it. If it didn't, I'll try to look into it further!

Best, Vince

Melissa1909 commented 12 months ago

Hi @VinceBaz, thanks for your quick response and sorry for the confusion!

So, I have (26-1 unused) * 2 hemispheres = 50 thalamic ROIs in total, with values 1-50 (otherwise, values are set to 0). They are depicted in "parcellation.nii.gz". I also have the volumetric outcomes in an array (vol_array="ThalamicNuclei.volumes.roi-ids.txt"), i.e., one volume value per ROI. I have used the code from above:

null_brain_maps = nulls.moran(nuclei_brain_map, atlas='mni152', density='2mm', parcellation=parcellation)

but it gives me the following error ValueError: Weight matrix has no zero eigenvalue.

parcellation_789373.nii.gz ThalamicNuclei.volumes_roi-ids_789373.txt error_docker_array.txt


I then followed a different strategy, namely creating an image that contains the subject's volume value per ROI inside the corresponding ROI (i.e., combining parcellation.nii and vol_array into an image) and ran nulls_thalamus = nulls.moran(vol_img, atlas='mni152', density='2mm') And it gave me results. Do you think that approach is valid?

Thanks!! Best, Melissa

thalamus_vols_per_roi_mnispace_789373.nii.gz compare_maps.py

VinceBaz commented 11 months ago

Hi @Melissa1909, Sorry for the delay!

You get the ValueError: Weight matrix has no zero eigenvalue error because you have nan values in your parcellation file. To fix this error, you simply need to replace the nan values with 0. Those 0 values will then be treated as background values and will be ignored.

But there will be another issue: it seems like there's only 38 parcels in your parcellation file (e.g. there's no parcels 3, 8, 12, 13, ...). This will raise an error since you have 50 volumes in vol_array and therefore want 50 parcels as well. You might want to look into this :open_mouth:

The alternative strategy also seems valid to me. But again, you only have 38 unique values, so you might want to look into this :smile:.

Best, Vince

Melissa1909 commented 10 months ago

Hi,

thanks for pointing that out - the thalamus segmentation on MNI space did not output anything for these regions actually. Fixed it thanks to your hint! Thank you for all the feedback! :)

Best, Melissa