Editing labels/annotations in tksurfer
Index
Contents
Version applicability
This page covers features in tksurfer in FreeSurfer 4.0.1 and 4.0.2. Later versions may have updated behaviors.
Overview
This page describes the process of editing labels using tksurfer. Surface label data can be stored in individual label files, or the data of many labels can be stored in an annotation file. This page focuses on the annotation file way of doing things, though much of the following is relevant to the separate-label-files approach too.
Editing might be desired for a couple of reasons:
You have an individual subject where you don't like the region boundaries that FreeSurfer produced.
You are editing many cases on the way to producing a new atlas: SurfaceLabelAtlas
At any rate, you will want to know how to perform the following editing moves:
- Perhaps starting with an existing annotation, such as rh.aparc.annot...
- Expand the boundary of a region into a neighboring region (or vice versa).
- Create an entirely new label (ie: new structure Id number and caption), draw a region and label it with the new structure number.
- Merge two regions (and presumably apply a new structure number etc).
- ... and finally save your work in a new annotation file, eg: rh.myparc.annot.
Editing labels turns out to be reasonably straightforward, but there are a number of idiosyncratic features to work around in tksurfer.
Background
As a starting point, let us review what we are looking at in the following picture:
You can arrive at this picture by:
tksurfer -annot aparc subjectid rh inflated
In addition:
View > Information > Annotation to turn on display of the Annotation value in the Tool window.
View > Auto-redraw
Now, as you float the mouse over the surface, you will see the Label and Annotation fields update. These are the values attached to the individual vertex that the mouse is hovering over.
To select a region, click on it, and tksurfer redraws it with a yellow outline. We will later draw our own "outlines" (paths), and these can also be selected, which highlights then in yellow. (This requires paying some attention as to whether it's a region or an outline that's selected.)
Editing a region consists of changing the Label and/or Annotation values for the vertices of interest. Of course, editing vertices one at a time would be tedious, so instead tksurfer offers various tools to draw an outline "path" and then "fill" that shape with the desired Label value, or perform other editing operations on the outlined region.
- Annotation value is actually just an alternate representation of the color: Annot = (R) + (G * 256) + (B * 256^2).
- You might expect color and annotation value to follow from the structure number, via a color look-up table.
As it turns out, however, none of this is quite true in tksurfer:
A vertex can have more than one structure number attached to it (ie: be a "member of more than one label"). Is this a useful state? Not if saving data to an annotation file, as that kind of file prevents multi labels per vertex. For many purposes we are interested in counting each vertex just once, so a single label value per vertex is a fine restriction. But the multi-labels-per-vertex situation can arise during editing, so we have to handle it.
A vertex can have only one annotation value, which usually follows from the structure number but sometimes not.
- A vertex's color can actually diverge from the annotation value.
All that said, there is a way to proceed and get the desired results.
Edits
Change the label (structure number) of an existing region
- Click on region to select
Open Labels dialog. (View > Windows > Labels)
Resist playing around with all the possible options unless you first read gwissue_labeledit. Instead...
- Note that the region you selected on the surface is also selected in the left hand list of existing regions.
To apply a different label to that region, select the desired label from the list of structure numbers on the right. So far this only applies the color of the just-clicked structure (and the color changes immediately in the surface window)
Important: Also click "Set Name" to actually apply the desired structure number (as you can judge by mousing over the region and looking at the Label field in the Tool window).
Given an initial annotation from recon-all, this is not a very useful procedure, since it's unlikely you want to give a provided region a new label from the provided list. However, it will come in handy as part of the procedure for new regions that we create later.
Here's a picture of the Labels dialog, for reference:
Expand the boundary of an existing region
Supposed you want to expand inferiorparietal into supramarginal...
- Draw a complete outline path that encloses the desired "incursion" into supramarginal, and also encloses any amount of inferiorparietal.
- Create outline path:
Possibly start with Edit > Unmark all vertices
Make a series of clicks along the desired outline path. tksurfer shows marked vertices.
Press the "Make closed path" button: tksurfer draws path
- Click in the interior of the enclosed region
- Press the "Custom Fill" button to invoke the Custom Fill dialog.
- Set
- Fill conditions: Up to and including paths
- Fill from: Last clicked vertex
- Action: Here's the tricky part! You first remove the enclosed vertices from both labels before (re)applying the desired label. (Not doing so is discussed below):
Remove from label... dropdown > supramarginal... click Fill
Remove from label... dropdown > inferiorparietal ... click Fill
Add to existing label... dropdown > inferiorparietal ... click Fill
- Clean up:
Unmark the vertices: Edit > Unmark all vertices
- Remove the path: Click on the path to select it, then press the Remove Selected Path button
- Create outline path:
At this point the suface view should show the desired outcome.
Save the annotation: File > Label > Export Annotation. Probably choose a new name rather than writing over an existing file.
If you do not first remove the labels from the outlined vertices, tksurfer will add the new labels to the vertices resulting in two labels. In regular tksurfer, you see something like this:
We created a custom version of tksurfer that shows the actual labels. Within the "incursion" area of the outline, as perhaps expected you see this:
Unexpectedly, in the entire rest of the region (not just in the outline) you see this:
This appears to be a bug. It turns out to be relatively benign, because when the data is saved the annotation file only captures a single label per vertex.
Bottom line: to avoid confusion, remove all labels from region before applying new ones.
Create a brand new region
Conceptually this is really two operations:
- Introduce a new structure number, caption and color to tksurfer
- Create an outline path around the new region and Fill with the new label (ie: structure number).
You may have noticed that the Custom Fill dialog offers "Create a new label" as a possibility. However, this area of functionality is incomplete so this is not the way to proceed (details of why are here: gwissue_labeledit.
Preparation: new look-up table
Instead, we need an alternate way to augment the structures look-up table that tksurfer got from the annotation file. As it turns out, we can simply provide a replacement lookup-table file. This needs to be in the same format as the LUT provided with FreeSurfer: FreeSurferColorLUT.txt.
You probably want to add on to the info that's in the annotation file's LUT, rather than starting from scratch. We couldn't find a program to extract LUT info from an annotation file, so we created one (available: see below), which gave us, for lh.aparc.annot, the following output:
# Freesurfer LUT information extracted from annotation file: # lh.aparc.annot # 2008-02-29 23:58:32 # This file can be used as the basis for a new LUT file for annotations purposes # which can be loaded into tksurfer using File > Label > Load color table #No. Label Name: R G B A 0 unknown 25 5 25 0 1 bankssts 25 100 40 0 2 caudalanteriorcingulate 125 100 160 0 3 caudalmiddlefrontal 100 25 0 0 4 corpuscallosum 120 70 50 0 5 cuneus 220 20 100 0 6 entorhinal 220 20 10 0 7 fusiform 180 220 140 0 8 inferiorparietal 220 60 220 0 9 inferiortemporal 180 40 120 0 10 isthmuscingulate 140 20 140 0 11 lateraloccipital 20 30 140 0 12 lateralorbitofrontal 35 75 50 0 13 lingual 225 140 140 0 14 medialorbitofrontal 200 35 75 0 15 middletemporal 160 100 50 0 16 parahippocampal 20 220 60 0 17 paracentral 60 220 60 0 18 parsopercularis 220 180 140 0 19 parsorbitalis 20 100 50 0 20 parstriangularis 220 60 20 0 21 pericalcarine 120 100 60 0 22 postcentral 220 20 20 0 23 posteriorcingulate 220 180 220 0 24 precentral 60 20 220 0 25 precuneus 160 140 180 0 26 rostralanteriorcingulate 80 20 140 0 27 rostralmiddlefrontal 75 50 125 0 28 superiorfrontal 20 220 160 0 29 superiorparietal 20 180 140 0 30 superiortemporal 140 220 220 0 31 supramarginal 80 160 20 0 32 frontalpole 100 0 100 0 33 temporalpole 70 70 70 0 34 transversetemporal 150 150 200 0
You would add lines to this table. Suggestions:
Use numbers starting at, say, 70, so that if MGH adds more aparc regions in future versions of FreeSurfer you have some hope of avoiding a collision.
Choose colors that are not already used. This is mandatory as discussed here: LabelsClutsAnnotationFiles, section "Annotation file design surprise".
Actually creating the new region
- Load the surface and existing annotation file
Load the enhanced look-up-table: File > Label > Load Color Table
- Draw outline path:
Possibly start with Edit > Unmark all vertices
- Make a series of clicks along the desired outline path. tksurfer shows marked vertices.
- Press the "Make closed path" button: tksurfer draws path
- Click in the interior of the enclosed region
- Press the "Custom Fill" button to invoke the Custom Fill dialog.
- Set
- Fill conditions: Up to and including paths
- Fill from: Last clicked vertex
- Action: First remove the enclosed vertices from all labels that your outline encloses, before applying the new structure label.:
For each current label: Remove from label... dropdown > region-whatever... click Fill
Add to existing label... dropdown > your-new-label ... click Fill
At this point the surface view should be showing your outlined region containing the color of your new structure, and floating the mouse over that region should show the new label and annotation values.
Save the annotation: File > Label > Export Annotation. Probably choose a new name rather than writing over an existing file.
Creating a Region Made up of Specifically Selected Vertices
Possibly start with Edit > Deselect Label and then Edit > Unmark all vertices to be sure no other vertices are chosen
- Left click on each vertex you want to include
Go to Tools > Labels > New Label from Marked Vertices
Then to save these vertices as a label to get stats on do File > Label > Save Selected Label (save as something.label)
You can now get the average thickness of just the vertices you selected by doing:
mris_anatomical_stats -f something.stats -l something.label subjid ?h
The resulting stats file should list the number of vertices you chose under NumVert otherwise it didn't work. This is in contrast to creating a label from a closed path as the closed path will include all the vertices within it.
Merging Two Regions
Conceptually, this is two moves:
- Introduce a new label (structure entry) to be applied to the combo region. Follow the steps described above under "Preparation: new look-up table"
- Apply the new label to the two regions. Follow the instructions above under "Change the label (structure number) of an existing region"
Additional Comments
Alternate editing techniques
- As with most software, there are alternative menu choices or buttons for some of the actions discussed.
- There are also additional techniques for using paths in combination with existing region boundaries to specify the sets of vertices you want to affect.
Clarification of the role of provided LUT files
Since this article mentions lookup-table files, a clarification might be useful on the role of FreeSurferColorLUT.txt.
- FreeSurferColorLUT.txt might seem to be somehow the "authoritative LUT file". In a sense this is true, but indirectly...
- FreeSurferColorLUT.txt is not used by tksurfer; tksurfer doesn't secretly read it.
- The structure numbers (label numbers) in FreeSurferColorLUT.txt are numbers used in the voxel version of data, for example in aseg and aparc+aseg files.
The structure numbers used for surface parcellation, for example in a surface annotation file (like rh.aparc.annot), are numbers in the range of 0 to 34 (currently). These structure names do not corresepond to same-numbered structures in FreeSurferColorLUT.txt, but do correspond to FreeSurferColorLUT.txt's range 1000-1034 (lh) and 2000-2034 (rh).
- The process which maps surface-parcellation into voxel space (mri_aparc2aseg) is responsible for adding 1000 or 2000 to the parcellation numbers. (At least, I assume so, haven't actually checked -- GW). There is no other mechanism that enforces this relationship, so care is needed when adding parcellation regions to coordinate those with +1000 and +2000 number in your enhanced version of FreeSurferColorLUT.txt
Program to extract lookup-table from annotation file
For linux, Centos 5. Not tested on other versions.
Invocation: GWFSAnnotToLUT annot_file_path output_LUTfile_path
Download: GWFSAnnotToLUT
Related Articles
LabelsClutsAnnotationFiles: Overview of Labels, "color lookup tables" and Annotation files
gwissue_labeledit : Discussion of tksurfer label-editing issues.
Author(s)
Graham Wideman (GrahamWideman), Ari Dubin, Cyndi Schumann