Beginner Question on ROI and Freesurfer labels, atlas, parcellation, and annotation for stc's

Hi all,
I have looked at many of the fine examples included in the MNE documentation, but the piece Iā€™m missing is how to I get from a named brain area to the label or annotation that mne handles? Iā€™ve looked at some of the freesurfer documentation and see that you can custom draw them, and that you can also use the freesurfer atlases for parcellation, but I didnā€™t find this exactly helpful as Iā€™m such a novice with MRI data.

Does anyone know of an example for using labels other than the 4 included in the MNE sample data?

Thanks,
Megan

@mschendel - Not sure exactly what you are asking? But freesurfer creates all of the default labels for you during processing (aparc2005 = Desikan/Killiany and aparc2009 = Destreaux). You can also create the aparc-sub, which chops up the DK atlas into ~450 parcels of approximately the same size.

recon-all -all -s NEW_SUBJECTID -i /Path/To/MRI.nii

All of the labels and parcels will be created in the subjects folder in the freesurfer subjects dir. This takes 10-24 hrs depending on computing hardware. But you can run several in parrallel. Once you have your subject processed, you can use labels=mne.read_labels_from_annot(SUBJECTID).

You can also create your own labels by hand drawing (but this seems painful): FsTutorial/AnatomicalROI - Free Surfer Wiki

Is that helpful or are you trying to figure out how to get other atlases into freesurfer?

-Jeff

Hi Jeff,
Thanks for your response.

I have the default labels from freesurfer. It is helpful to know about the aparc-sub, that might be useful.

I guess what Iā€™m curious about is how the label ā€˜Aud-lh.labelā€™ was created, which is used in an MNE example and included in the MNE sample data, but is not found in any of the freesurfer defaults.

Thanks,
Megan

Hi Megan,

I donā€™t know how that label was created - but there is mne.write_label that is maybe worth checking out. And freesurfer has several functions as well.

If you specifically want auditory cortex it is in the Destreaux atlas:

label = mne.read_labels_from_annot(fs_subjid, subjects_dir=subjects_dir, parc='aparc.a2009s')
heschles= [i for i in label  if 'G_T_transv' in i.name]

You could also use superior temporal gyrus from Desikan atlas - but that is rather large and encompasses regions outside of primary auditory cortex.

But other than that - I am not sure how to create labels from scratch.

-Jeff

Hi Jeff,
Thanks again for these ideas. I knew the atlases exist, but I think I need to look into them more. Thatā€™s probably where I need to start.

Thank you!
Megan

HCPMMP1_combined has some functional labels but I think the auditory one there is called primary_auditory or similar. Maybe @agramfort knows where this Aud-lh came from?

Meanwhile @mschendel you could try a sequence of brain.add_label('Aud-lh') and brain.add_parcellation calls, to see if you can determine whether, for example, Aud-lh is a conglomeration of a few adjacent labels from some parcellation.

Hi Dan,
Thanks for your suggestions.

I think my real issue is that I donā€™t really understand what a label object is and now to choose, combine, manipulate it. I am not working with auditory data, so really understanding that particular example is not quite what I need. There is an example here, which seems helpful, but Iā€™m having trouble implementing something similar from the pre-existing labels that freesurfer generates, which is what Iā€™d like to start with.

Thanks again for your response,
Megan

A label (when stored on disk) is a text file that contains the following info:

  • one ā€œcommentā€ line usually saying what software made the label
  • one line stating number of vertices in the label
  • one line for each vertex, with the structure: vertex_number x y z value

Where vertex_numbers correspond to the Source Space in which the label was defined, and x, y, z are in millimeters. Often the value is zero everywhere, but itā€™s possible for a label to contain estimated activity at each vertex (like youā€™d find in a SourceEstimate object); if a label did contain non-zero values then in principle your plotting software could take that into account (e.g., when deciding what color to make the label).

Labels are loaded into MNE-Python via mne.read_label(filename, ...). The resulting Label object has attributes comment, vertices, pos, and values with the only change from the on-disk format being that pos values are converted from millimeters to meters. You can also load several labels at once into a list, using mne.read_labels_from_annot(subject, parc=name_of_parcellation, ...) which has a regexp parameter for narrowing down which labels you want to load from the chosen parcellation. Iā€™m not sure if thatā€™s what you meant by ā€œhow to chooseā€ a label?

To combine labels, you can use the + operator: label1 + label2 will yield a new label that includes all the vertices from each of the original two. Note that they donā€™t have to be spatially adjacent (or even in the same hemisphere) to be combined this way. Note: you can also subtract one label from another (which only has an effect if they overlap).

To manipulate labels: you can label.split(...) into smaller labels (along its principle axis), you can label.morph(...) to another subject or to a template brain, you can label.compute_area(...), get label.center_of_mass(...), find out the distance from each vertex in the label to the edge of the label using label.distances_to_outside(...), or fill, restrict, or smooth it (so that its vertices match up with the set of vertices in use in a given source space).

Copying from what I said above: You can load several labels at once into a list, using mne.read_labels_from_annot(subject, parc=name_of_parcellation, ...) which has a regexp parameter for narrowing down which labels you want to load from the chosen parcellation. Hereā€™s a list of 8 tutorials/examples that use read_labels_from_annot: mne.read_labels_from_annot ā€” MNE 1.6.0 documentation. Probably this one is the most relevant starting point: Plot a cortical parcellation ā€” MNE 1.6.0 documentation

Final comment: perhaps part of the difficulty is that the example you linked to was doing something rather round-about in this block of code:

all_labels = mne.read_labels_from_annot(subject='sample',
                                        subjects_dir=subjects_dir)
labels = []
for select_label in ['parahippocampal-lh', 'postcentral-rh']:
    labels.append([lab for lab in all_labels if lab.name in select_label][0])
hiplab, postcenlab = labels

You could have done that in one line, like this:

hiplab, postcenlab = mne.read_labels_from_annot(
    subject='sample', subjects_dir=subjects_dir,
    regexp="parahippocampal-lh|postcentral-rh")

ā€¦although youā€™d have to be a bit careful about the order in which they got returned; here Iā€™m relying on the knowledge that we have one LH and one RH label, and the LH always gets read first.

1 Like

Hi Dan,
Thanks again for responding!

Right, I get what a label file is. I wasnā€™t sure about the python label object, so thank you for explaining that. Now I see the label.vertices, label.values and that all makes sense. Also the piece of the + operator is exactly what I was looking for! Thank you.

It is also very helpful to have that more simplified code for selecting labels from an annotation, as I found the example I linked very confusing.

I was trying to add mne.extract_label_time_course to some old code (using mne0.15), so I was getting confused about what could go in the labels parameter, but now I see that I can use a label_1+label_2 object or [label_1, label_2] list (for example). Now I just need to figure out how to use what comes out of mne.extract_label_time_course.

Thanks again very much for your help!
Megan

1 Like