Loading Fiber Photometry Data

Calcium activity recorded using a fiber photometry.

Relevant ALF objects

  • photometry

  • photometryROI

More details

Finding sessions with photometry data

Sessions that contain photometry data can be found by searching for sessions with a corresponding photometry dataset

[2]:
from one.api import ONE
one = ONE()
sessions = one.search(dataset='photometry.signal.pqt')
print(f'{len(sessions)} sessions with photometry data found')
546 sessions with photometry data found

Loading photometry data

The photometry data for a single session can be loaded in the following way

[3]:
# Get the first returned sessions with photometry data
eid = sessions[0]
# Load the photometry signal dataset
photometry = one.load_dataset(eid, 'photometry.signal.pqt')
print(photometry.columns)
Index(['Region0G', 'Region1G', 'Region2G', 'times', 'wavelength', 'name',
       'color', 'include'],
      dtype='object')

The data returned is a table that contains photometry data for all ROIS (Region0G, Region1G, …) recorded simultaneously in a single session. The number of rows in the table give the number of imaging frames in the dataset. The timestamps for each frame is stored in the times column are in seconds from session start and are aligned to other times from the session, e.g behavioral or video events.

The wavelength of light used to collect each imaging frame can be found using either the wavelength or the name column. For example if we want to limit our table to only frames collected at 470 nm we can do the following

[4]:
# Limit signal to frames collected at 470 nm
photometry = photometry[photometry['wavelength'] == 470]

The photometry data also contains a column called include which contains a manually selected interval of the signal that is free from artefacts

[5]:
# Restrict signal to artefact free intervals
photometry = photometry[photometry['include']]

Associating ROIs to Brain Regions

We can associate each Region with a brain region by loading in the photometryROI dataset. This contains a lookup table from ROI to a fiber stored on the openalyx database and a brain_region

[6]:
rois = one.load_dataset(eid, 'photometryROI.locations.pqt')
rois
Out[6]:
fiber brain_region
ROI
Region0G fiber00 DMS
Region1G fiber01 DLS
Region2G fiber02 NAcc

We can rename our columns in our photometry data with the brain regions

[7]:
photometry = photometry.rename(columns=rois.to_dict()['brain_region'])
print(photometry.columns)
Index(['DMS', 'DLS', 'NAcc', 'times', 'wavelength', 'name', 'color',
       'include'],
      dtype='object')

Please see the associated publication for these datasets for more information about the definition of the given brain regions.

QC of the ROIs

Each ROI has an associated fiber insertion registered on the openalyx database. The fiber contains information about the brain region targeted and also a QC value indicating if the signal is good or not. The associated publication contains more information about the defintion of a passing QC value.

For a session we can find the QC for each ROI in the following way

[8]:
from iblutil.util import Bunch

QC = Bunch()
for roi, info in rois.iterrows():
    fiber = one.alyx.rest('insertions', 'list', session=eid, name=info.fiber)[0]
    QC[info.brain_region] = fiber['json']['qc']

print(QC)
{'DMS': 'PASS', 'DLS': 'PASS', 'NAcc': 'PASS'}

Computing dF / F

Here we show an example of how to compute the dF/F signal from the photometry data using the defintion in associated publication

[9]:
# Compute df/F signal for brain region DMS
# Baseline signal is the +- 30s rolling average of the raw signal

# Get the frame rate of the data
fr = (1 / photometry.times.diff().mean()).round()
# Define rolling average window of 30 s
window = 30

F = photometry['DMS']
F0 = F.rolling(int(fr * window), center=True).mean()
dF = (F - F0) / F0