Allen Institute Visual Behavior 2P dataset overview¶
This dataset consists of neural activity measured with 2-photon calcium imaging in the visual cortex of mice performing an image change detection task.¶
In this task, mice learn to report changes in stimulus identity by licking a spout to earn a water reward.¶
(Figure “CD Task.png” is omitted from this example to keep the repository small; see the original notebook.)
In some sessions, the mice perform the task with familiar images they have seen many times during training. In other sessions, mice perform the task with novel images.¶
During 2-photon imaging sessions, 5% of stimulus presentations are randomly omitted, allowing us to examine the effect of unexpected events on neural activity.¶
The same population of cells is imaged over multiple days with varying sensory and behavioral conditions.¶
(Figure “experimental_design_matched.png” is omitted from this example to keep the repository small; see the original notebook.)
Multiple cortical areas and depths were measured concurrently in each session, at a sample rate of 11Hz.¶
Data was collected from excitatory and inhibitory neural populations.¶
(Figure “optical_physiology.png” is omitted from this example to keep the repository small; see the original notebook.)
You can learn more about this dataset, behavioral task, and find other useful tools here:¶
Overview page and Allen Brain Atlas¶
This example will focus on the activity of the two inhibitory types - VIP and SST neurons.¶
Loading the data¶
Source
# @title Install dependencies
import sys, subprocess
if sys.platform == "emscripten":
import micropip
await micropip.install(["seaborn", "pyarrow"])
else:
subprocess.run([sys.executable, "-m", "pip", "install", "-q", "pandas", "seaborn", "pyarrow"])# Imports
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_context('notebook', font_scale=1.5, rc={'lines.markeredgewidth': 2})For this example, we have pre-computed event triggered responses and saved them to figshare.¶
To access the full dataset, see Allen_neuromatch_example_2.ipynb, or go to the links at the bottom of this notebook¶
###This cell will download the responses.
Source
# @title Data retrieval
import os, requests
fname = "allen_visual_behavior_2p_change_detection_familiar_novel_image_sets.parquet"
url = "https://ndownloader.figshare.com/files/28470255"
if not os.path.isfile(fname):
try:
r = requests.get(url)
except requests.ConnectionError:
print("!!! Failed to download data !!!")
else:
if r.status_code != requests.codes.ok:
print("!!! Failed to download data !!!")
else:
with open(fname, "wb") as fid:
fid.write(r.content)Then we open it using the pandas read_parquet method¶
(parquet is just another file format)
filename = "allen_visual_behavior_2p_change_detection_familiar_novel_image_sets.parquet"
data = pd.read_parquet(filename)The data is organized as a pandas dataframe.¶
Each row contains all data for a given cell on a given trial¶
data.sample(5)Available data includes:¶
The cell
tracealigned to stimulus (or omission) onset in a [-1.25, 1.5] second window around onset timeCell traces are in units of delta F/F, the change in fluorescence relative to baseline
The
trace_timestampsfor each trial, aligned to stimulus or omission onsetThe
mean_responseon a given trial in a 500ms window after stimulus onsetThe
baseline_responseon a given trial in a 500ms window before stimulus onsetThe
image_namefor each trial. Trials where the stimulus was omitted haveimage_name=omittedThe
mean_running_speedin a 500ms window after stimulus onsetThe
mean_pupil_areain a 500ms window after stimulus onsetThe
response_latencywhen the mouse licked after stimulus onsetWhether or not the trial was
rewardedWhether or not the trial
is_changeWhether or not the trial was
omitted
Cell and session level metadata includes:¶
The
stimulus_presentations_idindicating the trial number within the sessionThe
cell_specimen_idwhich is the unique identifier for each cell (note that a cell can be imaged in multiple sessions; if that’s the case, the same cell_specimen_id appears in multiple sessions)The
cre_lineindicating the cell typeSst-IRES-Crelabels SST inhibitory cellsVip-IRES-Crelabels VIP inhibitory cellsSlc17a7-IRES-Crelabels excitatory cellsThe
imaging_depthindicating the cortical depth where the cell was locatedThe
targeted_structureindicating the cortical area the cell was fromThe
session_typeindicating the session order and image setThe
exposure_levelwhich tells you whether the image set was familiar or novelThe
mouse_idindicating which mouse the cell came fromThe
ophys_session_idindicating the recording day for that trialThe
ophys_experiment_idindicating which imaging plane within the session that the cell came fromThe
ophys_container_idwhich links the same imaging plane recorded across multiple sessions. Cells that are imaged across multiple sessions will have the samecell_specimen_id.
Let’s check what is available¶
print('exposure_levels:', data.exposure_level.unique())print('stimulus presentations can be changes:', data.is_change.unique())print('stimulus presentations can be omitted:', data.omitted.unique())print('cre lines (cell types) included in this dataset are:', data.cre_line.unique())print('there are', len(data.mouse_id.unique()), 'mice in this dataset')print('there are', len(data.ophys_session_id.unique()), 'sessions in this dataset')How are VIP and SST cells affected by stimulus novelty?¶
Plot the population average change response for familiar and novel images for each cre line¶
Get trials where the image identity changed, for SST and VIP cells
sst_data = data[(data.cre_line == 'Sst-IRES-Cre')&(data.is_change == True)]
vip_data = data[(data.cre_line == 'Vip-IRES-Cre')&(data.is_change == True)]Plot the population average change response of SST cells for familiar and novel images
timestamps = sst_data.trace_timestamps.values[0]
for exposure_level in sst_data.exposure_level.unique():
traces = sst_data[sst_data.exposure_level==exposure_level].trace.values
plt.plot(timestamps, np.mean(traces), label=exposure_level)
plt.title('SST population average')
plt.xlabel('time after change (sec)')
plt.ylabel('dF/F')
plt.legend()
plt.show()Plot the population average change response of VIP cells for familiar and novel images
timestamps = vip_data.trace_timestamps.values[0]
for exposure_level in vip_data.exposure_level.unique():
traces = vip_data[vip_data.exposure_level==exposure_level].trace.values
plt.plot(timestamps, np.mean(traces), label=exposure_level)
plt.title('VIP population average')
plt.xlabel('time after change (sec)')
plt.ylabel('dF/F')
plt.legend()
plt.show()Can you find cells that were imaged across multiple sessions? How do single cells change depending on the image set?¶
# which cells are in more than one session? make a list
cells_in_multiple_sessions = []
for cell_specimen_id in vip_data.cell_specimen_id.unique():
if len(vip_data[vip_data.cell_specimen_id == cell_specimen_id].ophys_session_id.unique()) > 1:
cells_in_multiple_sessions.append(cell_specimen_id)
print(cells_in_multiple_sessions)# this one looks like the population average
example_cell_specimen_id = cells_in_multiple_sessions[6]
cell_data = vip_data[vip_data.cell_specimen_id == example_cell_specimen_id]
timestamps = cell_data.trace_timestamps.values[0]
for exposure_level in cell_data.exposure_level.unique():
mean_trace = cell_data[cell_data.exposure_level == exposure_level].trace.mean()
plt.plot(timestamps, mean_trace, label=exposure_level)
plt.title(f'cell_specimen_id:{example_cell_specimen_id}')
plt.xlabel('time after change (sec)')
plt.ylabel('dF/F')
plt.legend()
plt.show()# this one does not look like the population average
example_cell_specimen_id = cells_in_multiple_sessions[0]
cell_data = vip_data[vip_data.cell_specimen_id==example_cell_specimen_id]
timestamps = cell_data.trace_timestamps.values[0]
for exposure_level in cell_data.exposure_level.unique():
mean_trace = cell_data[cell_data.exposure_level == exposure_level].trace.mean()
plt.plot(timestamps, mean_trace, label=exposure_level)
plt.title(f'cell_specimen_id:{example_cell_specimen_id}')
plt.xlabel('time after change (sec)')
plt.ylabel('dF/F')
plt.legend()
plt.show()What about trial to trial variability? How does the response of a single cell vary across a session?¶
# let's pick a cell from a novel image session
example_cell_specimen_id = vip_data[vip_data.exposure_level=='novel'].cell_specimen_id.unique()[7]
cell_data = vip_data[vip_data.cell_specimen_id == example_cell_specimen_id]
cell_data = cell_data[(cell_data.image_name == cell_data.image_name.unique()[2])]
offset = 1 / len(cell_data.stimulus_presentations_id.unique())
color = [0, 0, 0]
for i, stimulus_presentations_id in enumerate(cell_data.stimulus_presentations_id.unique()):
trial_data = cell_data[cell_data.stimulus_presentations_id == stimulus_presentations_id]
timestamps = trial_data.trace_timestamps.values[0]
trace = trial_data.trace.values[0]
plt.plot(timestamps, trace, color = color)
color = [color[0] + offset, color[1] + offset, color[2] + offset]
plt.title(f'cell_specimen_id:{example_cell_specimen_id}')
plt.xlabel('time after change (sec)')
plt.ylabel('dF/F')
plt.show()How do SST and VIP cells respond when stimuli are omitted?¶¶
Plot the population average response to stimulus omission¶
Get trials where the stimulus was omitted, for SST and VIP cells
sst_data = data[(data.cre_line == 'Sst-IRES-Cre')&(data.omitted == True)]
vip_data = data[(data.cre_line == 'Vip-IRES-Cre')&(data.omitted == True)]Plot the population average omission response of SST cells for familiar and novel images
timestamps = sst_data.trace_timestamps.values[0]
for exposure_level in sst_data.exposure_level.unique():
traces = sst_data[sst_data.exposure_level == exposure_level].trace.values
plt.plot(timestamps, np.mean(traces), label=exposure_level)
plt.title('SST population average')
plt.xlabel('time after omission (sec)')
plt.ylabel('dF/F')
plt.legend()
plt.show()Plot population average omission response of VIP cells for familiar and novel images
timestamps = vip_data.trace_timestamps.values[0] # trace timestamps are relative to stimulus onset
for exposure_level in vip_data.exposure_level.unique():
traces = vip_data[vip_data.exposure_level == exposure_level].trace.values
plt.plot(timestamps, np.mean(traces), label=exposure_level)
plt.title('VIP population average')
plt.xlabel('time after omission (sec)')
plt.ylabel('dF/F')
plt.legend()
plt.show()Does the omission response correlate with behavior?
How do the dynamics of image and omission evoked activity change over time during the novel image session?
To learn how to use the AllenSDK to access the full dataset, and see more in depth examples of how to interact with the data, check out the additional tutorials here:¶
https://
and in the ‘Getting Started’ section here:
https://