from allensdk.core.brain_observatory_cache import BrainObservatoryCache
boc = BrainObservatoryCache(manifest_file='boc/manifest.json')
In this example, we'll show how you can plot a heatmap of a cell's response organized by orientation and temporal frequency. Here we start with a known experiment ID. Take a look at the other notebook to see how you can find experiments of interest. You can run the drifting grating analysis code on that experiment's NWB file as follows:
import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
%matplotlib inline
from allensdk.brain_observatory.drifting_gratings import DriftingGratings
data_set = boc.get_ophys_experiment_data(502376461)
dg = DriftingGratings(data_set)
If you know which cell you're interested in, here's how you can find out where it is in the NWB File.
import numpy as np
specimen_id = 517425074
cell_loc = data_set.get_cell_specimen_indices([specimen_id])[0]
print("Specimen ID:", specimen_id)
print("Cell loc:", cell_loc)
The response
property of the stimulus-specific analysis objects is 4-D array organized with the following dimensions:
0: num. grating directions
1: num. grating temporal frequencies + 1 (0=blank sweep)
2: num. cells + 1 (running speed)
3: 0=response mean, 1=response standard error of the mean, 2=number of signficant trials
Dimension 2 of the response
array has one index per cell in the experiment, plus one. The final index of that dimension is the running speed (response[:,:,-1,:]
). This organization allows users to examine whether the mouse ran more for some specific stimulus conditions.
# skip the blank sweep column of the temporal frequency dimension
plt.imshow(dg.response[:,1:,cell_loc,0], cmap='hot', interpolation='none')
plt.xticks(range(5), dg.tfvals[1:])
plt.yticks(range(8), dg.orivals)
plt.xlabel("Temporal frequency (Hz)", fontsize=20)
plt.ylabel("Direction (deg)", fontsize=20)
plt.tick_params(labelsize=14)
cbar= plt.colorbar()
cbar.set_label("DF/F (%)")
The peak
property of the analysis object is a Pandas DataFrame of peak conditions (direction and temporal frequency) as well as computed response metrics. For drifting gratings this includes:
ori_dg: preferred direction (index into dg.orivals)
tf_dg: preferred temporal frequency (index into tf.tfvals)
response_reliability_dg: response reliability
osi_dg: orientation selectivity index
dsi_dg: direction selectivity index
ptest_dg: number of signficant cells
p_run_dg: K-S statistic comparing running trials to stationary trials
run_modulation_dg: ratio of mean fluorescence during running vs static
cv_dg: circular variance
dg.peak.loc[cell_loc]
Next let's plot all trials for a given cell's preferred condition.
pref_ori = dg.orivals[dg.peak.ori_dg[cell_loc]]
pref_tf = dg.tfvals[dg.peak.tf_dg[cell_loc]]
print("Preferred direction:", pref_ori)
print("Preferred temporal frequency:", pref_tf)
pref_trials = dg.stim_table[(dg.stim_table.orientation==pref_ori)&(dg.stim_table.temporal_frequency==pref_tf)]
pref_trials
sweep_response
is a DataFrame that contains the DF/F of each cell during each stimulus trial. It shares its index with stim_table
. Each cell contains a timeseries that extends from 1 second prior to the start of the trial to 1 second after the end of the trial. The final column of sweep_response
, named dx
, is the running speed of the mouse during each trial. The data in this DataFrame is used to create another DataFrame called mean_sweep_response
that contains the mean DF/F during the trial for each cell (and the mean running speed in the last column).
subset = dg.sweep_response[(dg.stim_table.orientation==pref_ori)&(dg.stim_table.temporal_frequency==pref_tf)]
Here we look at the mean running speed during trials that presented the preferred condition.
subset_mean = dg.mean_sweep_response[(dg.stim_table.orientation==pref_ori)&(dg.stim_table.temporal_frequency==pref_tf)]
subset_mean['dx']
Plot the response to each trial of the preferred condition, labeled with the mean running speed during the trial
trial_timestamps = np.arange(-1*dg.interlength, dg.interlength+dg.sweeplength, 1.)/dg.acquisition_rate
plt.figure(figsize=(8,20))
for i in range(len(subset)):
plt.subplot(len(pref_trials),1,i+1)
plt.plot(trial_timestamps, subset[str(cell_loc)].iloc[i], color='k', lw=2)
plt.axvspan(0,2,color='red', alpha=0.3)
plt.ylabel("DF/F (%)")
plt.ylim(-10,600)
plt.yticks(range(0,700,200))
plt.text(2.5, 300, str(round(subset_mean['dx'].iloc[i],2))+" cm/s")
if i<(len(subset)-1):
plt.xticks([])
else:
plt.xticks([-1,0,1,2,3])
plt.xlabel("Time (s)")
The static gratings analysis object is quite similar to the drifting gratings analysis object. Here we'll just take a look at the peak
table, which contains information about the preferred orientation, spatial frequency, phase, as well as a number of other metrics.
from allensdk.brain_observatory.static_gratings import StaticGratings
# example loading drifing grating data
data_set = boc.get_ophys_experiment_data(510938357)
sg = StaticGratings(data_set)
sg.peak.head()
The natural scenes analysis object is again similar to the others. In addition to computing the sweep_response
and mean_sweep_response
arrays, NaturalScenes
reports the cell's preferred scene, running modulation, time to peak response, and other metrics.
from allensdk.brain_observatory.natural_scenes import NaturalScenes
data_set = boc.get_ophys_experiment_data(510938357)
ns = NaturalScenes(data_set)
print("done analyzing natural scenes")
ns.peak.head()
The locally sparse noise stimulus object is a bit different from the others. It does not have a peak condition table, instead providing a method to retrieve the "on" and "off" receptive fields of all cells. The receptive field of a cell is computed by averaging responses to trials in which a given sparse noise grid location is on/off.
from allensdk.brain_observatory.locally_sparse_noise import LocallySparseNoise
import allensdk.brain_observatory.stimulus_info as stim_info
specimen_id = 587179530
cell = boc.get_cell_specimens(ids=[specimen_id])[0]
exp = boc.get_ophys_experiments(experiment_container_ids=[cell['experiment_container_id']],
stimuli=[stim_info.LOCALLY_SPARSE_NOISE])[0]
data_set = boc.get_ophys_experiment_data(exp['id'])
lsn = LocallySparseNoise(data_set)
print("done analyzing locally sparse noise")
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
cell_idx = data_set.get_cell_specimen_indices([specimen_id])[0]
plt.imshow(lsn.receptive_field[:,:,cell_idx,0], interpolation='nearest', cmap='PuRd', origin='lower')
plt.title("on receptive field")
plt.show()
plt.imshow(lsn.receptive_field[:,:,cell_idx,1], interpolation='nearest', cmap='Blues', origin='lower')
plt.title("off receptive field")
plt.show()