DSURQE atlas hierarchical downsample - CoBrALab/documentation GitHub Wiki

A downsampled version of the Dorr_2008_Steadman_2013_Ullmann_2013_Richards_2011_Qiu_2016_Egan_2015_40micron (DSURQE) atlas was generated by merging labels that were part of the same hierarchical ontology, based on the Allen Brain Institute adult mouse annotations for hierarchical ontology (found at /data/chamal/projects/Gabriel_DG/atlases/AllenBrain/structures.csv).

The following ROI were generated for this downsampled atlas (acronym names in the ABI terminology):

cerebral_cortex=['MOp', 'MOs', 'FRP', 'SSs', 'SSp', 'AUD', 'VIS', 'ACA', 'PL', 'ILA', 'ORB','AI', 'RSP', 'PTLp', 'TEa', 'PERI', 'ECT', 'CA', 'DG', 'RHP', 'CTXsp']

olfactory_areas=['AON', 'PIR', 'COA', 'PAA']

cerebral_nuclei=['STRd', 'STRv', 'LSX', 'sAMY', 'PALd', 'PALv', 'PALm', 'PALc']

brainstem=['TH', 'HY', 'MB', 'HB']

cerebellum=['VERM', 'HEM', 'CBN']

Further notes: the olfactory bulb was omitted, and the PL together with the ILA, and the ORB together with the AI were merged due to insufficient EPI voxels for the ILA and AI ROIs.

The ABI labels can be viewed at any hierarchical level at http://atlas.brain-map.org/

All files are in /data/chamal/projects/Gabriel_DG/atlases/DSURQE_atlas/hierarchical_downsample

  • atlas_downsample.py - the script which was run to generate the downsampled atlas
  • DSURQE_downsample_info.csv - A csv file with the info about the atlas labels, id, and original DSURQE id that were merged for each new ROI
  • DSURQE_downsample_labels.pkl - A dictionary with the info about the atlas labels, id, and original DSURQE id that were merged for each new ROI
  • DSURQE_downsample.nii.gz - The atlas labels

Details on the process

  1. Every DSURQE label was associated to its corresponding ABI label. Based on this association, every grey matter (GM) DSURQE label was given its corresponding ABI hierarchy. The ABI hierarchy of a given ABI label consists of a list of ABI label ids, separated by a '/' in the csv file, which describes the hierarchical path from the root (whole atlas) to the leaf (the given ABI label) of the hierarchical tree (e.g. /997/8/567/688/695/315/500/985/320/ for the label with the id 320).
  2. For each ABI ROI selected, its corresponding id was identified, and all GM DSURQE labels were assigned the ROI which was part of their hierarchy.
  3. Finally, for each ROI, its assigned DSURQE labels from the original atlas were merged and given a new id to create the downsampled atlas.

atlas_downsample.py


import numpy as np
import pandas as pd

#load info from the ABI annotation csv file
ABI_info='/data/chamal/projects/Gabriel_DG/atlases/AllenBrain/structures.csv'
ABI_df=pd.read_csv(ABI_info)
ABI_names=list(ABI_df['name'])
ABI_acronyms=list(ABI_df['acronym'])
ABI_ids=list(ABI_df['id'])
ABI_hierarchy=list(ABI_df['structure_id_path'])

#load the DSURQE annotation csv info file
DSURQE_info='/opt/quarantine/resources/Dorr_2008_Steadman_2013_Ullmann_2013_Richards_2011_Qiu_2016_Egan_2015_40micron/mappings/DSURQE_40micron_R_mapping.csv'
DSURQE_df=pd.read_csv(DSURQE_info)
DSURQE_ABI=list(DSURQE_df['ABI'])

#add a hierarchy column to the DSURQE info dataframe
DSURQE_ABI_hierarchy=[]
for ABI_term in DSURQE_ABI:
    term_index=ABI_names.index(ABI_term)
    DSURQE_ABI_hierarchy.append(ABI_hierarchy[term_index])
DSURQE_df['ABI_hierarchy'] = pd.Series(DSURQE_ABI_hierarchy, index=DSURQE_df.index)


#get index for areas that are GM regions from the DSURQE atlas
DSURQE_tissue=list(DSURQE_df['tissue type'])
index=[]
i=0
for tissue in DSURQE_tissue:
    if tissue=='GM':
        index.append(i)
    i+=1
index=np.asarray(index)

#keep only labels that are GM
DSURQE_hierarchy=list(DSURQE_df['ABI_hierarchy'][index])
DSURQE_ABI=list(DSURQE_df['ABI'][index])
right_label=list(DSURQE_df['right label'][index])
left_label=list(DSURQE_df['left label'][index])


#make a list of the selected ABI annotations that will be the new downsampled ROIs
custom_roi_cerebral_cortex=['MOp', 'MOs', 'FRP', 'SSs', 'SSp', 'AUD', 'VIS', 'ACA', 'PL', 'ILA', 'ORB',
                  'AI', 'RSP', 'PTLp', 'TEa', 'PERI', 'ECT', 'CA', 'DG', 'RHP', 'CTXsp']
custom_roi_olfactory_areas=['AON', 'PIR', 'COA', 'PAA']
custom_roi_cerebral_nuclei=['STRd', 'STRv', 'LSX', 'sAMY', 'PALd', 'PALv', 'PALm', 'PALc']
custom_roi_brainstem=['TH', 'HY', 'MB', 'HB']
custom_roi_cerebellum=['VERM', 'HEM', 'CBN']

custom_rois=custom_roi_cerebral_cortex+custom_roi_olfactory_areas+custom_roi_cerebral_nuclei+custom_roi_brainstem+custom_roi_cerebellum



#make list of the ids for each of the selected roi to have the ontological reference to merge the DSURQE labels part of each ROI
ABI_acronyms=list(ABI_df['acronym'])
ABI_ids=list(ABI_df['id'])
selected_rois=[]
for roi in custom_rois:
    index=ABI_acronyms.index(roi)
    selected_rois.append(ABI_ids[index])


#then loop through GM regions of DSURQE then put them in the associated ABI ROI based on hierarchy
i=0
DSURQE_roi_annotations=[]
for hierarchy in DSURQE_hierarchy:
    hierarchy_annotations=[]
    for id in selected_rois:
        if str(id) in hierarchy.split('/'):
            hierarchy_annotations.append(selected_rois.index(id))
    if len(hierarchy_annotations)==0:
        print(str(i)+' '+DSURQE_ABI[i]+' not included.')
    DSURQE_roi_annotations.append(hierarchy_annotations)
    i+=1



selected_roi_annotations={}
for roi in custom_rois:
    #merge AI with ORB and ILA with PL since AI and ILA tended to have 0 voxels included
    if roi=='AI' or roi=='ORB':
        selected_roi_annotations['AI-ORB']=[]
    elif roi=='ILA' or roi=='PL':
        selected_roi_annotations['ILA-PL']=[]
    else:
        selected_roi_annotations[roi]=[]


i=0
for annotation in DSURQE_roi_annotations:
    if len(annotation)>0:
        if len(annotation)>1: #make sure every label is associated to only 1 ROI
            print('ERROR: a label has more than one ROI associated.')
        roi=custom_rois[annotation[0]]
        if roi=='AI' or roi=='ORB':
            selected_roi_annotations['AI-ORB']+=[right_label[i], left_label[i](/CoBrALab/documentation/wiki/right_label[i],-left_label[i)]
        elif roi=='ILA' or roi=='PL':
            selected_roi_annotations['ILA-PL']+=[right_label[i], left_label[i](/CoBrALab/documentation/wiki/right_label[i],-left_label[i)]
        else:
            selected_roi_annotations[roi]+=[right_label[i], left_label[i](/CoBrALab/documentation/wiki/right_label[i],-left_label[i)]
    i+=1


#now for each roi, merge all voxels with an id falling in the possible labels of that roi
import nibabel as nb
atlas_file='/data/chamal/projects/Gabriel_DG/atlases/DSURQE_atlas/labels/DSURQE_40micron_labels.nii.gz'
atlas=nb.load(atlas_file)
data=np.asarray(atlas.dataobj)
downsample_atlas=np.zeros(data.shape)
DSURQE_downsample_info=['roi', 'rh', 'lh', 'DSURQE RH/LH label pairs'](/CoBrALab/documentation/wiki/'roi',-'rh',-'lh',-'DSURQE-RH/LH-label-pairs')
i=1
for key in selected_roi_annotations.keys():
    labels=selected_roi_annotations[key]
    if len(labels)==0:
        print(key+' has no labels associated.')
        continue
    rh_voxels=np.zeros(data.shape)
    lh_voxels=np.zeros(data.shape)
    for rh, lh in labels:
        rh_voxels+=(data==rh)
        lh_voxels+=(data==lh)
    if ((rh_voxels*lh_voxels)>0).max(): #we assume no overlap between hemisphere labels
        print('Overlap between hemispheres for '+key+' ROI.')
        downsample_atlas+=((rh_voxels+lh_voxels)>0)*i
        i+=1
        DSURQE_downsample_info.append([key, i-1, i-1, labels])
    else:
        downsample_atlas+=(rh_voxels>0)*i
        i+=1
        downsample_atlas+=(lh_voxels>0)*i
        i+=1
        DSURQE_downsample_info.append([key, i-2, i-1, labels])


nb.Nifti1Image(downsample_atlas, atlas.affine, atlas.header).to_filename('DSURQE_downsample.nii.gz')

downsample_df=pd.DataFrame(DSURQE_downsample_info[1:], columns=DSURQE_downsample_info[0])
downsample_df.to_csv('DSURQE_downsample_info.csv')

DSURQE_downsample_labels={}
DSURQE_downsample_labels[DSURQE_downsample_info[0][0]]=[]
DSURQE_downsample_labels[DSURQE_downsample_info[0][1]]=[]
DSURQE_downsample_labels[DSURQE_downsample_info[0][2]]=[]
DSURQE_downsample_labels[DSURQE_downsample_info[0][3]]=[]
for roi,rh,lh,labels in DSURQE_downsample_info[1:]:
    DSURQE_downsample_labels[DSURQE_downsample_info[0][0]].append(roi)
    DSURQE_downsample_labels[DSURQE_downsample_info[0][1]].append(rh)
    DSURQE_downsample_labels[DSURQE_downsample_info[0][2]].append(lh)
    DSURQE_downsample_labels[DSURQE_downsample_info[0][3]].append(labels)

import pickle
filename='DSURQE_downsample_labels.pkl'
with open(filename,'wb') as handle:
    pickle.dump(DSURQE_downsample_labels, handle)