-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: extract ROI time series #9
base: main
Are you sure you want to change the base?
Conversation
JD-Zhu
commented
Jul 1, 2024
•
edited
Loading
edited
- MNI305to152.py: utility to help read out anatomical labels from source localisation results.
- traditional_source_analysis_and_ROIs.py: run source analysis and save the STCs, then extract source timecourses from predefined ROIs.
#labels = [labels_parc[60], labels_parc[61]] # 60: left STG; 61: right STG | ||
|
||
# or use 'aparc.a2009s' parcellation (150 labels) | ||
labels_parc = mne.read_labels_from_annot(subject, parc='aparc.a2009s', subjects_dir=subjects_dir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a2009s
is fine but nowadays I recommend HCPMMP1 like
mne.datasets.fetch_hcpmmp1_parcellation(subjects_dir=subjects_dir)
then here you can use the fine-grained (~360 labels) "HCPMMP1"
or coarse (~44 labels) "HCPMMP1_combined"
atlas
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I'll take a look into this :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@larsoner Could HCPMMP1 be used with volumetric source results? The 'extract_label_time_course' method requires a string path to an atlas (e.g. ‘aparc.a2009s+aseg.mgz’) when working with volumetric source - the atlases are located in 'freesurfer/subjects/fsaverage/mri' and there doesn't seem to be a HCPMMP option available. Is this only used for surface source space? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JD-Zhu no not directly, but some years ago I did write this
https://gist.github.com/larsoner/8e664205cd8285ca7c46211403ad12ce
the code comments at the top allow you to create a volumetric atlas that uses HCPMMP1 for the cortical regions and aseg
for the subcortical regions, then that script creates an ID lookup that can be used with extract_label_time_course
in volumetric mode. Want to take a look and give it a shot?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@larsoner Thanks, I'll have a go at it!
We were also hoping to run the ROI analysis with MEG-only for comparison - would the covariance matrix need to be recreated in this case (or could I just regenerate the fwd model and inverse solution based on MEG channels only)? If so, how do you make the cov matrix from the resting state data (I think this is what was done in the pipeline)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also quick question about the volumetric atlas for HCPMMP1 - there are some labels that sound very similar to each other, e.g.
'ctx-lh-precuneus' and 'ctx-lh-G_precuneus',
'ctx-lh-temporalpole' and 'ctx-lh-Pole_temporal'.
What is the difference between them and which ones should we use? Thanks so much!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference between them and which ones should we use? Thanks so much!
For stuff like this I first try to check by loading the labels and doing brain.add_label
, e.g.:
import mne
brain = mne.viz.Brain("fsaverage", hemi="lh")
labels = mne.read_labels_from_annot("fsaverage", "HCPMMP1")
labels = [label for label in labels if label.hemi == "lh" and "precuneus" in label.name]
for label in labels:
brain.add_label(label, borders=True)
But this plots no labels! And checking we see len(labels) == 0
, i.e, HCPMMP1 does not have labels by this name.
I suspect that you are seeing these names when processing FreeSurferColorLUT
(right?) -- this is because that file has labels for a bunch of possible different existing FreeSurfer parcellations, some of which overlap. So for example looking at the two possible builting cortical parcellations you could use we see:
>>> mne.read_labels_from_annot("fsaverage", "aparc", regexp="precuneus", hemi="lh")
[<Label | fsaverage, 'precuneus-lh', lh : 7308 vertices>]
>>> mne.read_labels_from_annot("fsaverage", "aparc.a2005s", regexp="precuneus", hemi="lh")
[<Label | fsaverage, 'G_precuneus-lh', lh : 3558 vertices>]
And if you want to see where they are and/or how they overlap you can adapt the code above:
import mne
brain = mne.viz.Brain("fsaverage", hemi="lh", surf="inflated", views="medial")
label = mne.read_labels_from_annot("fsaverage", "aparc", regexp="precuneus", hemi="lh")
assert len(label) == 1, len(label)
brain.add_label(label[0], alpha=0.8)
label_a2005 = mne.read_labels_from_annot("fsaverage", "aparc.a2005s", regexp="precuneus", hemi="lh")
assert len(label_a2005) == 1, len(label_a2005)
brain.add_label(label_a2005[0], borders=True)
you can see that they are similar but the a2005 one sticks more to the gyral parts of the label (as implied by its G_
prefix).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I was able to replicate your plot and could see how those two labels differ slightly. However, I'm still a bit confused as to how these labels from "aparc" and "aparc.a2005s" match with the labels in the .mgz file generated from your script linked above.
When I read in the .mgz file like this:
fname_aseg = subjects_dir / subject / 'mri' / 'HCPMMP1+aseg.mgz'
label_names = mne.get_volume_labels_from_aseg(fname_aseg)
I get a list of label names (strings, not actual Label objects). Is there a way to plot certain labels from this list to see where they are (similar to the plot you did above)? Sorry if I sound totally confused - still trying to grasp how these atlases and ROIs work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, I'm still a bit confused as to how these labels from "aparc" and "aparc.a2005s"
So aparc
, aparc.a2005s
, HCPMMP1
, HCPMMP1_combined
, etc. are all cortical parcellations. These can be combined with aseg.mgz
to create a volumetric atlas for the brain. freesurfer
does this automatically for its built-in parcellations, e.g. aparc+aseg.mgz
and aparc.a2005s+aseg.mgz
are two volumetric atlases that are created for every recon-all
'ed subject (including fsaverage
) that correspend to two different cortical parcellations, each with aseg
tacked on to handle subcortical regions.
So when you look at / think about HCPMMP1+aseg.mgz
, you can view this in whatever MRI viewer you like using to look at volumetric atlases. One way is to use freeview
the way you would any volumetric atlas. For aparc+aseg
you can do:
freeview -v T1.mgz -v aparc+aseg.mgz:colormap=lut:opacity=1
For HCPMMP
you'll probably need to pass a filename to the :lut
option:
':lut=name' Set lookup table to the given name. Name can be the name of
a stock color table or the filename of a color table file.
If you do this, you should see that the labels show up in the same places in the volumetric space that they do when you plot them on the inflated brain using FreeView or mne.viz.Brain(...)
+ brain.add_parcellation("HCPMMP1")
for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation! I can now load the HCPMMP1+aseg.mgz into freeview with the LUT file from your script to see the locations.
Also, when I was reading in the label names previously, I was using the incorrect LUT file (the freesurfer default) so the label names were all incorrect which caused part of my confusion. I have now changed it to the following, which should load the labels correctly (I think):
fname_aseg = subjects_dir / subject / 'mri' / 'HCPMMP1+aseg.mgz'
fname_lut = subjects_dir / subject / 'mri' / 'HCPMMP1ColorLUT.txt'
lut = mne.read_freesurfer_lut(fname_lut)
label_names = mne.get_volume_labels_from_aseg(fname_aseg, atlas_ids=lut[0])
Hi @larsoner , I think I'm still having some trouble with the volumetric version of the HCPMMP1 atlas. The label names load correctly when using the proper LUT file, but I still run into a problem when trying to use these labels with mne.extract_label_time_course(). Apparently the label name cannot be found in the atlas even though it shows up in the list: Does the custom lut file need to be supplied to mne.extract_label_time_course()? I checked the documentation but couldn't find a way to do so. Thanks in advance for any advice. |
Not exactly, this one is a bit tricky -- unpacking the It looks like you have passed a two-element tuple, the secend element being a You are in the "use of other atlases" part, so instead of passing a |
This update may not be needed, depending on the properties of the saved source files, but it does no damage to have the updated version.
All works now - thank you! |