AnchorBar

From CCN Wiki
Jump to navigation Jump to search

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