AnchorBar
AnchorBar (aka "Analyzer") is a Python program developed to maintain and compute set operations on FreeSurfer annotation files. It's kind of like SPM's MarsBar plugin, but for FreeSurfer.
Requirements
AnchorBar has a few dependencies that might not be part of your base Python install:
- hashlib
- nibabel
Attempting to run the scripts will fail and report missing libraries. They can be installed using pip:
pip install nibabel
The utility is (currently) comprised of 3 scripts. Syntax help for each of these scripts can be obtained using the -h
switch:
$ AnchorBar_tools.py -h usage: AnchorBar_tools.py [-h] [--list] [--labels annot_id] [--db DB] [--rename annot_id new_shortname] [--relabel annot_id label_id new_label_name] [--abbrev annot_id label_id abbrev_label_name]
Querying Available Annotations
AnchorBar_tools.py provides tools to list, rename and relabel annotations. Each annotation has a unique ID and descriptors indicating the hemisphere, a shortname used for naming labels generated from set operations, and a path indicating the file path of the source .annot file. The default set of annotations stored in annot.db includes the 10 pairs of lhrh annotations from fsaverage/label:
AnchorBar_tools.py --db annot.db --list
The labels associated with a given annotation can be found using the --labels
switch:
#List all the labels in the lh.aparc_2009s.annot FreeSurfer annotation AnchorBar_tools.py --db annot.db --labels 2
Adding Annotations
The most common use-case for adding annotations is when working with functional ROIs from group analyses. AnchorBar_init.py is the tool that imports new .annot files into the database for later operations. Imported annotations are associated with a unique identifier based on the labels and vertices that make up an annotation. This allows the scripts to recognize and ignore duplicate annotations that might have been given different names, but also to differentiate distinct annotations that happen to have the same name (as is common when working with functional ROIs).
The import process infers the hemisphere from the filename. Functional cluster annotations are unlikely to have an lh/rh prefix, and so will require renaming prior to importing (I like to stick them in the project copy of the fsaverage folder):
cp $SUBJECTS_DIR/RFX/myanalysis.lh/a_vs_b/glm.wls/osgm/cache.th30.abs.sig.ocn.annot $SUBJECTS_DIR/fsaverage/label/lh.a_vs_b.cache.th30.abs.annot cp $SUBJECTS_DIR/RFX/myanalysis.rh/a_vs_b/glm.wls/osgm/cache.th30.abs.sig.ocn.annot $SUBJECTS_DIR/fsaverage/label/rh.a_vs_b.cache.th30.abs.annot
To add one or more new annotations (that you've renamed and saved to the fsaverage/label folder):
AnchorBar_init.py --db annot.db --annot $SUBJECTS_DIR/fsaverage/label/*.th30.abs.annot
Of course, the particular filename pattern in red in the above command may differ from what's shown here, depending on your file naming convention, but you get the idea. When this code executes, it will import all the files that end in "th30.abs.annot" that it finds. This is handy for importing annotations for multiple hemispheres and/or for multiple contrasts.
Renaming Imported Annotations
Imported annotations will be given a shortname that corresponds to the filename of the source annotation. These names can be unwieldy, so AnchorBar_tools.py allows you to assign a new shortname to stored annotations. First, list the annotations and note their shortnames and id values. Use the id when selecting the annotation for renaming. For example:
./AnchorBar_tools.py --db annot.db --list *** Annotation List *** id LR shortname path 1 lh aparc.a2005s /usr/local/freesurfer/subjects/fsaverage/label 2 lh aparc.a2009s /usr/local/freesurfer/subjects/fsaverage/label ... 25 lh a_v_b.th30.abs /home/projects/mystudy/fsaverage/label 26 rh a_v_b.th30.abs /home/projects/mystudy/fsaverage/label
If we wanted to remove the "th30.abs" part of the shortname for the annotations 25 and 26:
./AnchorBar_tools.py --db annot.db --rename 26 AvsB ./AnchorBar_tools.py --db annot.db --rename 25 AvsB
Now inspect the annotation database to see the shortname has been updated with the values you just provided:
./AnchorBar_tools.py --db annot.db --list *** Annotation List *** id LR shortname path 1 lh aparc.a2005s /usr/local/freesurfer/subjects/fsaverage/label 2 lh aparc.a2009s /usr/local/freesurfer/subjects/fsaverage/label ... 25 lh AvsB /home/projects/mystudy/fsaverage/label 26 rh AvsB /home/projects/mystudy/fsaverage/label
Set Operations on Annotations
Note that all set operations require pairs of annotations from the same hemisphere. If unsure, list the annotations and take careful note of the hemisphere noted for the ids of the annotations you're interested in. Using annotations from opposite hemispheres will result in an error message and produce no new output.
Intersection of Two Annotations
Example: We have a functional contrast (A vs Rest) and wish to divide the large clusters along Brodmann Area boundaries. By intersecting the clusters (which only cover some of the brain surface) with one of the anatomical atlas annotations (which cover all of the brain surface), we assign a new label to each vertex according to which cluster and which anatomical label it corresponds to. Vertices not belonging to functional clusters will be dropped. The end result is a new annotation where the clusters are subdivided along anatomical boundaries.
We first list the annotations in the database to find the corresponding id numbers. A vs Rest are annotations 23 (lh) and 24 (rh), and the Brodmann annotations are 5 (lh) and 15 (rh). We intersect the two corresponding annotations thus:
AnchorBar_sets.py --db annot.db --intersect 5 23 AnchorBar_sets.py --db annot.db --intersect 15 24
Merging (Union) of Two Annotations
Example: We have two tasks, A and B, and each task condition has been contrasted with rest (A vs Rest; B vs Rest). We wish to identify left-hemisphere regions that are involved in either task, so we compute the union. This functionality has been added to AnchorBar
#Assumes that lh.AnnotA and lh.AnnotB correspond to the annotations derived from the two task contrasts, #A vs Rest and B vs Rest, respectively, and that these annotations are numbered 23 and 25 AnchorBar_sets.py --db annot.db --union 23 25