Retrieving Calcium Imaging Data#

This section will serve as an introdution to retrieving two-photon fluorescence imaging data from the Allen Brain Observatory. By the end of this section you will know how to obtain a two-photon imaging dataset for a particular cell type in a specific visual area.

Setup#

We need a variety of standard Python packages in addition to two different allensdk toolboxes. If you have not yet installed the allensdk, run the cell below. Otherwise, you can skip to the cell that imports our toolboxes.

# This will ensure that the AllenSDK is installed.
# If not, it will install it for you.
try:
    import allensdk
    if allensdk.__version__ == '2.11.2':
        print('allensdk already installed.')
    else:
        print('incompatible version of allensdk installed')
except ImportError as e:
    !pip install allensdk
Collecting allensdk
  Using cached allensdk-2.15.1-py3-none-any.whl (4.0 MB)
Collecting psycopg2-binary
  Using cached psycopg2_binary-2.9.6-cp311-cp311-macosx_10_9_x86_64.whl (2.2 MB)
Collecting hdmf<=3.4.7
  Using cached hdmf-3.4.7-py3-none-any.whl (187 kB)
Requirement already satisfied: h5py in /Users/ashley/anaconda3/envs/jb/lib/python3.11/site-packages (from allensdk) (3.9.0)
Collecting matplotlib<3.4.3,>=1.4.3
  Using cached matplotlib-3.4.2.tar.gz (37.3 MB)
  Preparing metadata (setup.py) ... ?25l-
 \
 |
 done
?25hRequirement already satisfied: numpy in /Users/ashley/anaconda3/envs/jb/lib/python3.11/site-packages (from allensdk) (1.25.0)
Requirement already satisfied: pandas>=1.1.5 in /Users/ashley/anaconda3/envs/jb/lib/python3.11/site-packages (from allensdk) (2.0.3)
Requirement already satisfied: jinja2>=3.0.0 in /Users/ashley/anaconda3/envs/jb/lib/python3.11/site-packages (from allensdk) (3.1.2)
Requirement already satisfied: scipy<2.0.0,>=1.4.0 in /Users/ashley/anaconda3/envs/jb/lib/python3.11/site-packages (from allensdk) (1.11.1)
Requirement already satisfied: six<2.0.0,>=1.9.0 in /Users/ashley/anaconda3/envs/jb/lib/python3.11/site-packages (from allensdk) (1.16.0)
Collecting pynrrd<1.0.0,>=0.2.1
  Using cached pynrrd-0.4.3-py2.py3-none-any.whl (18 kB)
Collecting future<1.0.0,>=0.14.3
  Using cached future-0.18.3.tar.gz (840 kB)
  Preparing metadata (setup.py) ... ?25l-
 done
?25hRequirement already satisfied: requests<3.0.0 in /Users/ashley/anaconda3/envs/jb/lib/python3.11/site-packages (from allensdk) (2.31.0)
Collecting requests-toolbelt<1.0.0
  Using cached requests_toolbelt-0.10.1-py2.py3-none-any.whl (54 kB)
Collecting simplejson<4.0.0,>=3.10.0
  Using cached simplejson-3.19.1-cp311-cp311-macosx_10_9_x86_64.whl (75 kB)
Collecting scikit-image>=0.14.0
  Using cached scikit_image-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl (12.9 MB)
Collecting scikit-build<1.0.0
  Using cached scikit_build-0.17.6-py3-none-any.whl (84 kB)
Collecting statsmodels<=0.13.0
  Using cached statsmodels-0.13.0.tar.gz (17.8 MB)
  Installing build dependencies ... ?25l-
 \
 |
 /
 -
 \
 |
 done
?25h  Getting requirements to build wheel ... ?25l-
 \
^C
?25h canceled
ERROR: Operation cancelled by user

# Import our toolboxes
import allensdk.brain_observatory.stimulus_info as stim_info
from allensdk.core.brain_observatory_cache import BrainObservatoryCache
import pandas as pd 
import matplotlib.pyplot as plt
print('Packages installed.')
/Users/ashley/anaconda3/lib/python3.7/site-packages/dask/config.py:168: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  data = yaml.load(f.read()) or {}
Packages installed.

Get a list of all possible transgenic mouse lines and brain areas, and choose which to work with.#

Below, we’ll create an instance of the BrainObservatoryCache. This object will allow us to retrieve and analyze the Allen Brain Observatory data.

# We will create an instance of the Brain Observatory Cache as an object, "boc."
boc = BrainObservatoryCache(manifest_file='manifest.json')

Next, we’ll use get_all_cre_lines() on our boc object to return all of the possible Cre lines and brain areas are that we can analyze. We can also use the get_all_targeted_structures() method to return all brain areas in our dataset.

You can find more info about the Cre-lines on the Allen Brain Atlas Transgenic Mouse Lines page. Refer back to the Brain Observatory landing page to learn more about the different visual areas. Make sure to visit the BrainObservatoryCache doucumentation for additional help with the methods used in this notebook.

# We'll assign the list of cre lines to a variable, 'cre-lines'.
cre_lines = boc.get_all_cre_lines()
print(f"all cre lines: {cre_lines} \n")

# We'll assign the list of possible structures to a variable, 'brain_areas'.
brain_areas = boc.get_all_targeted_structures()
print("all brain regions: " + str(brain_areas))
all cre lines: ['Cux2-CreERT2', 'Emx1-IRES-Cre', 'Fezf2-CreER', 'Nr5a1-Cre', 'Ntsr1-Cre_GN220', 'Pvalb-IRES-Cre', 'Rbp4-Cre_KL100', 'Rorb-IRES2-Cre', 'Scnn1a-Tg3-Cre', 'Slc17a7-IRES2-Cre', 'Sst-IRES-Cre', 'Tlx3-Cre_PL56', 'Vip-IRES-Cre'] 

all brain regions: ['VISal', 'VISam', 'VISl', 'VISp', 'VISpm', 'VISrl']

Extract an experiment session#

With access to the cre lines and brain regions from the dataset, we can construct a dataframe of experiement containers from our desired cre lines and brain regions. Each experiment container has a group of experiments that share the same targeted brain area, cre line, and depth. However, the stimuli conditions may differ across experiments for a given contianer.

We can use the get_experiment_containers() method of our boc object to return a list of dictionaries with data on the available experiment contianers. The method takes in the arguments cre_lines and targeted_structures which both require lists as inputs.

Note: Not every cre line and brain region combination will have data. If no data is availabe for a certain combindation, an empty dataframe will be created. You can use the empty attribute on your new datafram to check if it is empty.

# Assign visual area and cre line of interest for analysis 
visual_area = 'VISp'
cre_line = 'Tlx3-Cre_PL56'

# Get experiment contianers for visual area and cre line of interest 
exp_cont = boc.get_experiment_containers(targeted_structures = [visual_area], 
                                     cre_lines = [cre_line])

# Create an experiment dataframe 
exp_cont_df = pd.DataFrame(exp_cont)

# Check if dataframe is empty 
if exp_cont_df.empty:
    print('Data frame is empty, choose another cre line & visual area combination.')

# Assign the ID column as the index and return dataframe
exp_cont_df = exp_cont_df.set_index('id')
exp_cont_df
imaging_depth targeted_structure cre_line reporter_line donor_name specimen_name tags failed
id
637671552 375 VISp Tlx3-Cre_PL56 Ai148(TIT2L-GC6f-ICL-tTA2) 340430 Tlx3-Cre_PL56;Ai148-340430 [] False
617381603 375 VISp Tlx3-Cre_PL56 Ai148(TIT2L-GC6f-ICL-tTA2) 336824 Tlx3-Cre_PL56;Ai148(CAM)-336824 [] False
627823571 375 VISp Tlx3-Cre_PL56 Ai148(TIT2L-GC6f-ICL-tTA2) 337458 Tlx3-Cre_PL56;Ai148-337458 [] False
648377366 375 VISp Tlx3-Cre_PL56 Ai148(TIT2L-GC6f-ICL-tTA2) 352889 Tlx3-Cre_PL56;Ai148-352889 [] False
657016265 375 VISp Tlx3-Cre_PL56 Ai148(TIT2L-GC6f-ICL-tTA2) 357093 Tlx3-Cre_PL56;Ai148-357093 [] False
637669268 375 VISp Tlx3-Cre_PL56 Ai148(TIT2L-GC6f-ICL-tTA2) 340427 Tlx3-Cre_PL56;Ai148-340427 [] False

Let’s look into one of these experiment containers, most of which have three different sessions for different types of visual stimuli. We can call get_ophys_experiments() on our boc object to return the experiments within a container. This method takes in the arguments experiment_container_ids and stimuli which both require lists. We can select an id from our dataframe and choose a stimuli. In our case, we’ll filter for experiments with the natural_scenes stimuli.

# Assign experiment container id and stimuli 
exp_container_id = 627823571
stim = ['natural_scenes']

# Call experiment container for our id and stimuli of interest
experiments = boc.get_ophys_experiments(experiment_container_ids = [exp_container_id],
                                   stimuli = stim)

# Print out our container 
print(experiments)
[{'id': 644660705, 'imaging_depth': 375, 'targeted_structure': 'VISp', 'cre_line': 'Tlx3-Cre_PL56', 'reporter_line': 'Ai148(TIT2L-GC6f-ICL-tTA2)', 'acquisition_age_days': 133, 'experiment_container_id': 627823571, 'session_type': 'three_session_B', 'donor_name': '337458', 'specimen_name': 'Tlx3-Cre_PL56;Ai148-337458', 'fail_eye_tracking': False}]

Note: You can execute get_all_stimuli() on the boc object if you are unsure of what stimuli are available. Not all experiments or experiment contiainers will have every stimuli in their datasets.

print('Stimuli found in Brain Observatory:')
boc.get_all_stimuli()
Stimuli found in Brain Observatory:
['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']

Now, let’s download the experiment data using the get_ophys_experiment_data method. If you look closley above, you can see that experiments is a list of dictionaries for each experiment in our assigned container. We will need to input the session id of our experiment into this method.

Note: The cell below downloads some data, and make take a minute or so to run. It is important that you do not interrupt the download of the data or else the file will become corrupted and you will have to delete it and try again.

# Note: This id is different from our experiment container id 
session_id = experiments[0]['id']
data = boc.get_ophys_experiment_data(session_id)

# Take a look at the kind of object data is 
print(data)
<allensdk.core.brain_observatory_nwb_data_set.BrainObservatoryNwbDataSet object at 0x7f8b101641d0>

The returned output is data accessor object that can be used to perform analyses that we will discuss in the next section.

That’s how you retrieve an experiment from the Allen Brain Observatory! If you want to retrieve multiple experiments across multiple brain areas or cell types, you can use the get_experiment_containers method without specifying a targeted structure or brain area, and then subset your dataframe. There are many different types of analyses that can be done with this data. For example, we can creat a maximum projection image of the data to see how our cells respond to certain stimuli. We can also find out if our cells, if any, are direction selective. We will go over how to perform these analyses, and more, in the next two sections.