Case 2: Annotating optogenetic circuits

This examples shows how to translate mouse stimulated pattern to human and annotate the optogenetic circuits using Neurosynth.

Introduction

  • Optogenetic fMRI provides detailed maps of whole-brain responses to circuit-specific manipulations in mice (ref), yet translating these findings into human behavioral contexts remains challenging.

  • Conversely, human task-fMRI has identified robust task-related activation patterns linked to specific cognitive and behavioral states (ref), but lacks causal circuit-level evidence.

  • In this tutorial, you can learn how to use TransBrain to bridge this translational gap by mapping optogenetically-driven circuit patterns into human brain space and linking optogenetic findings with established human cognitive maps.

Data

  • Optogenetic fMRI data for the Insula (source)

  • Neurosynth meta-analytical activation map: (link)

  • Pre-saved data in tutorial directory(link)

[1]:
import pandas as pd
import numpy  as np
from nilearn import image,plotting
from scipy import stats
import glob
import warnings
warnings.filterwarnings('ignore')
import matplotlib.image as mpimg
from matplotlib import pyplot as plt
import transbrain as tb

View mouse stimulated pattern.

[2]:
#Process atlas mask
P56_annotation = '../../../../transbrain/atlas/mouse_atlas.nii.gz'
P56_annotation_data = np.asarray(image.load_img(P56_annotation).dataobj)
P56_annotation_data[P56_annotation_data!=0]=1
P56_mask = image.new_img_like(image.load_img(P56_annotation),P56_annotation_data)

opto_ai_in_p56 = image.load_img('./opto_ai_map_in_p56.nii.gz')
opto_ai_in_p56_data = np.asarray(opto_ai_in_p56.dataobj)

opto_ai_in_p56_data[P56_annotation_data!=1] = 0
opto_ai_in_p56_data[opto_ai_in_p56_data<0]=0
opto_ai_in_p56 = image.new_img_like(image.load_img(P56_annotation),opto_ai_in_p56_data)
[3]:
from transbrain.vis import plot_mouse_phenotype

# Use TransBrain's visualization function to view the mouse optogenetic stimulated pattern
plot_mouse_phenotype(opto_ai_in_p56, normalize_img = False, symmetric_cbar=True,vmax=5, threshold=1)
../../../../_images/tutorials_notebooks_translation_optogenetic_annotation_optogenetic_circuits_4_0.png

Load the regional data of mouse stimulated patterns

[4]:
AI_opto = pd.read_csv('ai_opto.csv',index_col=0)
AI_opto
[4]:
AI_opto
ACAd 0.604528
ACAv 0.369476
PL 1.139296
ILA 0.539155
ORBl 0.000000
... ...
MTN 4.848956
ILM 5.223949
GENv 0.211631
EPI 3.944129
RT 1.150901

68 rows × 1 columns

Translating mouse stimulated pattern to human

[5]:
Transformer = tb.trans.SpeciesTrans('bn')
INFO:root:Initialized for bn atlas.
[6]:
AI_trans_in_human = Transformer.mouse_to_human(AI_opto,region_type='all')
INFO:root:Successfully translated mouse all phenotypes to human.

We can print the top activated regions

[7]:
AI_trans_in_human.sort_values(by='AI_opto',ascending=False).head(10)
[7]:
AI_opto
rTtha 0.732512
mPFtha 0.568260
PPtha 0.469093
dIg 0.429137
vId/vIg 0.416277
G 0.389577
vIa 0.330202
Otha 0.286257
posterovemtral putamen 0.283502
dId 0.257844

Next, let’s check the activation pattern of the mouse in human brain.

[8]:
human_atlas = tb.atlas.fetch_human_atlas(atlas_type='bn', region_type='all')
[9]:
from transbrain.vis import map_phenotype_to_nifti, plot_human_phenotype

# map the region-level phenotype data to an image
AI_trans_in_human_zscore = stats.zscore(AI_trans_in_human,axis=0)
AI_trans_in_human_zscore[AI_trans_in_human_zscore < 0] = 0
Synthetic_ai_stimulated_img = map_phenotype_to_nifti(AI_trans_in_human_zscore, human_atlas)

# view the image
plot_human_phenotype(Synthetic_ai_stimulated_img, normalize_img=False, cut_coords=range(0, 50, 10), vmax=2, symmetric_cbar = True)
<Figure size 3000x300 with 0 Axes>
../../../../_images/tutorials_notebooks_translation_optogenetic_annotation_optogenetic_circuits_14_1.png

Annotating using NeuroSynth.

Next, we will annotate this optogenetic pattern using the human activation map from NeuroSynth and observe what terms it is related to.

[10]:
#Threshold the data
ai_thre = np.sort(stats.zscore(AI_trans_in_human['AI_opto'].values))[-20]
Synthetic_ai_img_data = np.asarray(Synthetic_ai_stimulated_img.dataobj)
Synthetic_ai_img_data[Synthetic_ai_img_data<ai_thre] = 0

Calculate the overlap between synthetic stimulated image and activation map for each term in the Neurosynth dataset.

[11]:
ai_dict_top_term = {}
for path in glob.glob('./neurosynth_data/*.nii.gz'):

    term_  =  path.split('/')[-1].split('_')[0]

    target_z_map_data = np.asarray(image.load_img(path).dataobj)
    target_z_map_data[target_z_map_data<0]=0

    stat_zero_data = np.zeros_like(target_z_map_data)
    stat_zero_data[(target_z_map_data!=0)&(Synthetic_ai_img_data!=0)] = 1

    try:
        overlap_rate = len(stat_zero_data.flatten()[stat_zero_data.flatten()!=0])/len(target_z_map_data.flatten()[target_z_map_data.flatten()!=0])
        ai_dict_top_term[term_] = overlap_rate
    except:
        print(term_)
[12]:
ai_top_term_dataframe = pd.DataFrame(ai_dict_top_term.values())
ai_top_term_dataframe.index = ai_dict_top_term.keys()

Print the regions with top overlap.

[13]:
ai_top_term_dataframe.sort_values(by=0,ascending=False).head(10)
[13]:
0
addiction 0.328380
decision making 0.276786
decision 0.266892
eating 0.264292
risk 0.244253
anticipation 0.223714
loss 0.218065
reinforcement learning 0.216023
selective attention 0.207113
pain 0.201087
[14]:
#Sort the dataframe
AI_trans_in_human_sorted = stats.zscore(AI_trans_in_human).sort_values(by='AI_opto',ascending=False)

View the rank.

[15]:
categories = list(AI_trans_in_human_sorted[AI_trans_in_human_sorted['AI_opto']>=ai_thre].index.values)
values = list(stats.zscore(AI_trans_in_human_sorted)[AI_trans_in_human_sorted['AI_opto']>=ai_thre]['AI_opto'].values)
[16]:
from matplotlib.colors import LinearSegmentedColormap,Normalize
from matplotlib.colors import LinearSegmentedColormap, rgb_to_hsv, hsv_to_rgb

#Set colors
colors = plt.get_cmap('viridis_r')(np.linspace(1, 0.4, 20))
custom_cmap = LinearSegmentedColormap.from_list('custom_cmap', colors)
norm = Normalize(vmin=min(values), vmax=max(values))
colors = custom_cmap(norm(values))

fig,ax = plt.subplots(1,1,figsize=(12,4),dpi=500)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
plt.bar(categories, values, color=colors,alpha=0.8)
plt.title('Activated brain regions (Insula stimulated top 20)',fontsize=15)
plt.ylabel('zscore',labelpad=10,fontsize=14)
plt.xticks(categories, rotation='vertical')
plt.show()
../../../../_images/tutorials_notebooks_translation_optogenetic_annotation_optogenetic_circuits_25_0.png