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?


@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?


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.


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]

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.


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!

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,

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.1.0 documentation. Probably this one is the most relevant starting point: Plot a cortical parcellation — MNE 1.1.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',
labels = []
for select_label in ['parahippocampal-lh', 'postcentral-rh']:
    labels.append([lab for lab in all_labels if 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,

…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!

1 Like