import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from allensdk.core.brain_observatory_cache import BrainObservatoryCache
manifest_file = '../../../data/allen-brain-observatory/visual-coding-2p/manifest.json'
boc = BrainObservatoryCache(manifest_file=manifest_file)

Visual stimuli#

As we saw in the overview, there were a range of visual stimuli presented to the mice in these experiments.

boc.get_all_stimuli()
['drifting_gratings',
 'locally_sparse_noise',
 'locally_sparse_noise_4deg',
 'locally_sparse_noise_8deg',
 'natural_movie_one',
 'natural_movie_three',
 'natural_movie_two',
 'natural_scenes',
 'spontaneous',
 'static_gratings']

Here we will look at each stimulus, and what information we have about its presentation.

Drifting gratings#

The drifting gratings stimulus consists of a sinusoidal grating that is presented on the monitor that moves orthogonal to the orientation of the grating, moving in one of 8 directions (called orientation) and at one of 5 temporal frequencies. The directions are specified in units of degrees and temporal frequency in Hz. The grating has a spatial frequency of 0.04 cycles per degree and a contrast of 80%. Each trial is presented for 2 seconds with 1 second of mean luminance gray in between trials.

Let’s find the session in the experiment container we’re exploring that contains the drifting gratings stimulus.

experiment_container_id = 511510736
session_id = boc.get_ophys_experiments(experiment_container_ids=[experiment_container_id], stimuli=['drifting_gratings'])[0]['id']
data_set = boc.get_ophys_experiment_data(ophys_experiment_id=session_id)

Let’s look at the stimulus table for the drifting gratings stimulus

drifting_gratings_table = data_set.get_stimulus_table('drifting_gratings')
drifting_gratings_table.head(n=10)
temporal_frequency orientation blank_sweep start end
0 8.0 270.0 0.0 747 807
1 2.0 135.0 0.0 837 897
2 2.0 315.0 0.0 927 987
3 15.0 315.0 0.0 1018 1077
4 1.0 270.0 0.0 1108 1168
5 15.0 315.0 0.0 1198 1258
6 1.0 315.0 0.0 1289 1348
7 15.0 180.0 0.0 1379 1439
8 2.0 135.0 0.0 1469 1529
9 NaN NaN 1.0 1560 1619
start

The 2p imaging frame during which the trial starts. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

end

The 2p imaging frame during which the trial ends. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

orientation

The direction of the drifting grating trial in degrees. Value of NaN indicates a blanksweep.

temporal_frequency

The temporal frequency of the drifting grating trial in Hz. This refers to how many complete periods the signal goes through for a given unit of time. Value of NaN indicates a blanksweep.

blank_sweep

A boolean indicating whether the trial is a blank sweep during which no grating is presented and the monitor remains at mean luminance gray.

What are the orientation and temporal frequency values used in this stimulus?

orivals = drifting_gratings_table.orientation.dropna().unique()
print("orientations: ", np.sort(orivals))
tfvals = drifting_gratings_table.temporal_frequency.dropna().unique()
print("temporal frequencies: ", np.sort(tfvals))
orientations:  [  0.  45.  90. 135. 180. 225. 270. 315.]
temporal frequencies:  [ 1.  2.  4.  8. 15.]

How many blank sweep trials are there?

len(drifting_gratings_table[np.isnan(drifting_gratings_table.orientation)])
30

How many trials are there for any one stimulus condition?

ori=45
tf=2
len(drifting_gratings_table[(drifting_gratings_table.orientation==ori)&(drifting_gratings_table.temporal_frequency==2)])
15

What is the duration of a trial?

plt.figure(figsize=(6,3))
durations = drifting_gratings_table.end - drifting_gratings_table.start
plt.hist(durations);
../_images/1abe328afd6fd2f9ad4817727a59b1d99ec0106681c446dcff88d5153663e6cb.png

Most trials have a duration of 60 imaging frames. As the two photon microscope we use has a frame rate of 30Hz this is 2 seconds. But you can see that there is some jitter across trials as to the precise duration.

What is the inter trial interval? Let’s look at the first 100 trials:

intervals = np.empty((100))
for i in range(100):
  intervals[i] = drifting_gratings_table.start[i+1] - drifting_gratings_table.end[i]
  plt.hist(intervals);
../_images/ad3ab775c7f4684e186738626cc816c1b12b6e78d032e0e4869af0371fc9af0d.png

Static gratings#

The static gratings stimulus consists of a stationary sinusoidal grating that is flasshed on the monitor at one of 6 orientations, one of 5 spatial frequencies, and one of 4 phases. The grating has a contrast of 80%. Each trial is presented for 0.25 seconds and followed immediately by the next trial without any intertrial interval. There are blanksweeps, where the grating is replaced by the mean luminance gray, interleaved among the trials.

Let’s find the session in the experiment container we’re exploring that contains the static gratings stimulus.

session_id = boc.get_ophys_experiments(experiment_container_ids=[experiment_container_id], stimuli=['static_gratings'])[0]['id']
data_set = boc.get_ophys_experiment_data(ophys_experiment_id=session_id)

Let’s look at the stimulus table for the static gratings stimulus

static_gratings_table = data_set.get_stimulus_table('static_gratings')
static_gratings_table.head(n=10)
orientation spatial_frequency phase start end
0 90.0 0.04 0.50 747 754
1 150.0 0.04 0.50 754 761
2 30.0 0.02 0.00 762 769
3 0.0 0.32 0.50 769 776
4 150.0 0.16 0.75 777 784
5 150.0 0.08 0.25 784 791
6 90.0 0.32 0.50 792 799
7 60.0 0.04 0.25 799 806
8 30.0 0.08 0.75 807 814
9 90.0 0.32 0.50 814 821
start

The 2p imaging frame during which the trial starts. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

end

The 2p imaging frame during which the trial ends. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

orientation

The orientation of the grating trial in degrees. Value of NaN indicates a blanksweep.

spatial_frequency

The spatial frequency of the grating trial in cycles per degree (cpd). This refers to how many complete periods the signal goes through for a given unit of distance. Value of NaN indicates a blanksweep.

phase

The phase of the grating trial, indicating the position of the grating. Value of NaN indicates a blanksweep.

What are the orientation, spatial frequency, and phase values used in this stimulus?

print("orientations: ", np.sort(static_gratings_table.orientation.dropna().unique()))
print("spatial frequencies: ", np.sort(static_gratings_table.spatial_frequency.dropna().unique()))
print("phases: ", np.sort(static_gratings_table.phase.dropna().unique()))
orientations:  [  0.  30.  60.  90. 120. 150.]
spatial frequencies:  [0.02 0.04 0.08 0.16 0.32]
phases:  [0.   0.25 0.5  0.75]

What is the phase of the grating?

The phase refers to the relative position of the grating. Phase 0 and Phase 0.5 are 180° apart so that the peak of the grating of phase 0 lines up with the rought of phase 0.5.

phase

How many blank sweep trials are there?

len(static_gratings_table[np.isnan(static_gratings_table.orientation)])
192

How many trials are there of any one stimulus codition?

ori=30
sf=0.04
phase=0.0
len(static_gratings_table[(static_gratings_table.orientation==ori)&(static_gratings_table.spatial_frequency==sf)&(static_gratings_table.phase==phase)])
49

Note

There are roughly 50 trials fo each stimulus condition, but not precisely. Some conditions have fewer than 50 trials but none have more than 50 trials.

What is the duration of a trial?

plt.figure(figsize=(6,3))
durations = static_gratings_table.end - static_gratings_table.start
plt.hist(durations);
../_images/fbd6b1cff16715626a24a0a7415e000efa14e17dd16ac6cd5edc9129db25e8a2.png

What is the inter trial interval?

#intervals = np.empty((50))
#for i in range(50):
  #intervals[i] = static_gratings_table.start[i+1] - #static_gratings_table.end[i]
  #plt.hist(intervals);

Natural scenes#

The natural scenes stimulus consists of a 118 black and whiteimages that are flashed on the monitor. Each trial is presented for 0.25 seconds and followed immediately by the next trial without any intertrial interval. There are blanksweeps, where the images are replaced by the mean luminance gray, interleaved in among the trials. The images are taken from three different image sets including CITATIONS HERE

Let’s find the session in the experiment container we’re exploring that contains the natural scenes stimulus.

session_id = boc.get_ophys_experiments(experiment_container_ids=[experiment_container_id], stimuli=['natural_scenes'])[0]['id']
data_set = boc.get_ophys_experiment_data(ophys_experiment_id=session_id)

Let’s look at the stimulus table for the natural scenes stimulus

natural_scenes_table = data_set.get_stimulus_table('natural_scenes')
natural_scenes_table.head(n=10)
frame start end
0 81 16100 16107
1 33 16108 16115
2 76 16115 16122
3 13 16123 16130
4 56 16130 16137
5 30 16138 16145
6 44 16145 16152
7 93 16153 16160
8 65 16160 16167
9 60 16168 16175
start

The 2p imaging frame during which the trial starts. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

end

The 2p imaging frame during which the trial ends. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

frame

Which image was presented in the trial. This indexes into the stimulus template.

Note

The blanksweeps in the natural scene stimulus table are identified by having a frame value of -1

How many blank sweep trials are there?

len(natural_scenes_table[natural_scenes_table.frame==-1])
50

How many trials are there of any one image?

len(natural_scenes_table[natural_scenes_table.frame==22])
50

Stimulus template#

The stimulus template is an array that contains the images that were presented to the mouse. This can be accessed using get_stimulus_template().

natural_scene_template = data_set.get_stimulus_template('natural_scenes')
scene_number=22
plt.imshow(natural_scene_template[scene_number,:,:], cmap='gray')
plt.axis('off');
../_images/01a68b4dd76f25f9c02850bb956ccfe36b1d22ee86f6190e152483ec53271fde.png

Natural movies#

There are three different natural movie stimuli:

  • natural_movie_one

  • natural_movie_two

  • natural_movie_three

Natural movie one is presented in every session. It is 30 seconds long and is repeated 10 times in each session. Natural movie two is presented in three_session_B. It is 30 seconds long and is repeated 10 times. Natural movie three is presented in three_session_A. It is 2 minutes long and is presented a total of 10 times, but in two epochs. All of these movies are from the opening scene of Touch of Evil, and Orson Welles film. This was selected because it is a continuous shot with no camera cuts and with a variety of different motion signals.

session_id = boc.get_ophys_experiments(experiment_container_ids=[experiment_container_id], stimuli=['natural_movie_one'])[0]['id']
data_set = boc.get_ophys_experiment_data(ophys_experiment_id=session_id)

Let’s look at the stimulus table for the natural movie stimulus

natural_movie_table = data_set.get_stimulus_table('natural_movie_one')
natural_movie_table.head(n=10)
frame start end repeat
0 0 70307 70307 0
1 1 70308 70308 0
2 2 70309 70309 0
3 3 70310 70310 0
4 4 70311 70311 0
5 5 70312 70312 0
6 6 70313 70314 0
7 7 70314 70315 0
8 8 70315 70316 0
9 9 70316 70317 0
start

The 2p imaging frame during which the trial starts. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

end

The 2p imaging frame during which the trial ends. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

frame

Which frame of the movie was presented in the trial. This indexes into the stimulus template.

repeat

The number of the repeat of the movie.

The movies are different from the previous stimuli where the different trials pertained to distinct images or stimulus conditions. Here each “trial” is a frame of the movie, and the trial duration closely matches the 2p imaging frames. But the movie is repeated 10 times, and you might want to identify the start of each repeat.

natural_movie_table[natural_movie_table.frame==0] 
frame start end repeat
0 0 70307 70307 0
900 0 71210 71211 1
1800 0 72113 72114 2
2700 0 73016 73017 3
3600 0 73919 73920 4
4500 0 74822 74823 5
5400 0 75725 75726 6
6300 0 76629 76630 7
7200 0 77532 77533 8
8100 0 78435 78436 9

Stimulus template#

The stimulus template is an array that contains the images of the natural movie stimulus that were presented to the mouse. This can be accessed using get_stimulus_template. Let’s look at the first frame:

natural_movie_template = data_set.get_stimulus_template('natural_movie_one')
plt.imshow(natural_movie_template[0,:,:], cmap='gray')
plt.axis('off');
../_images/cc0ed38e4237e43d004c614d04faff46f115fe8ad0688ca8b1cbd051a60aa4dc.png

Locally sparse noise#

The locally sparse noise stimulus is used to map the spatial receptive field of the neurons. There are three stimuli that are used. For the data published in June 2016 and October 2016, the locally_sparse_noise stimulus was used, and these were presented in the session called three_session_C. For the data published after that, both locally_sparse_noise_4deg and locally_sparse_noise_8deg were used and these were presented in three_session_C2.

The locally_sparse_noise and locally_sparse_noise_4deg stimulus consisted of a 16 x 28 array of pixels, each 4.65 degrees on a side. Please note, while this stimulus is called locally_sparse_noise_4deg, the pixel size is in fact 4.65 degrees. For each frame of the stimulus a small number of pixels were white and a small number were black, while the rest were mean luminance gray. In total there were ~11 white and black spots in each frame. The white and black spots were distributed such that no two spots were within 5 pixels of each other. Each time a given pixel was occupied by a black (or white) spot, there was a different array of other pixels occupied by either black or white spots. As a result, when all of the frames when that pixel was occupied by the black spot were averaged together, there was no significant structure surrounding the specified pixel. Further, the stimulus was well balanced with regards to the contrast of the pixels, such that while there was a slightly higher probability of a pixel being occupied just outside of the 5-pixel exclusion zone, the probability was equal for pixels of both contrast. Each pixel was occupied by either a white or black spot a variable number of times. The only difference between locally_sparse_noise and locally_sparse_noise_4deg is that the latter is roughly half the trials as the former.

The locally_sparse_noise_8deg stimulus consists of an 8 x 14 array made simply by scaling the 16 x 28 array used for the 4 degree stimulus. Please note, while the name of the stimulus is locally_sparse_noise_4deg, the actual pixel size is 9.3 degrees. The exclusions zone of 5 pixels was 46.5 degrees. This larger pixel size was found to be more effective at eliciting responses in the HVAs.

experiment_container_id = 511510736
session_id = boc.get_ophys_experiments(experiment_container_ids=[experiment_container_id], stimuli=['locally_sparse_noise'])[0]['id']
data_set = boc.get_ophys_experiment_data(ophys_experiment_id=session_id)
lsn_table = data_set.get_stimulus_table('locally_sparse_noise')
lsn_table.head(n=10)
frame start end
0 0 746 753
1 1 753 760
2 2 761 768
3 3 768 776
4 4 776 783
5 5 784 791
6 6 791 798
7 7 799 806
8 8 806 813
9 9 814 821
start

The 2p imaging frame during which the trial starts. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

end

The 2p imaging frame during which the trial ends. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

frame

Which frame of the locally sparse noise movie was presented in the trial. This indexes into the stimulus template.

What is the duration of a trial?

plt.figure(figsize=(6,3))
durations = lsn_table.end - lsn_table.start
plt.hist(durations);
../_images/4d98a25d16ebf6f16e241feb545deb7663fe5095a3abf36bb30e64150711c272.png

The locally sparse noise stimuli have the same temporal structure as the natural scenes and static gratings. Each image is presented for 0.25s (~7 frames) and is followed immediately by the next image.

Stimulus template#

The stimulus template is an array that contains the images of the locally sparse noice stimulus that were presented to the mouse. This can be accessed using get_stimulus_template(). Let’s look at the first frame:

lsn_template = data_set.get_stimulus_template('locally_sparse_noise')
plt.imshow(lsn_template[0,:,:], cmap='gray')
plt.axis('off');
../_images/e374ee829d74dd094b68a3a64e54a105c27221d29999722cc4f4cbde08270523.png

Spontaneous activity#

In each session there is at least one five-minute epoch of spontaneous activity. During this epoch the monitor is held at mean luminance gray and there is no patterned stimulus presented. This provides a valuable time that can be used as a baseline comparison for visually evoked activity.

spont_table = data_set.get_stimulus_table('spontaneous')
spont_table
start end
0 22575 31456
1 73155 82035
start

The 2p imaging frame during which the spontaneous activity starts. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

end

The 2p imaging frame during which the spontaneous activity ends. This indexes directly into the activity traces (e.g. dff or extracted events) and behavior traces (e.g. running speed).

This is a session that has two epochs of spontaneous activity. What is their duration?

durations = spont_table.end - spont_table.start
durations
0    8881
1    8880
dtype: int64