Exploring an NWB File#
It can get cumbersome to manually dissect an NWB file with print statements. There are a few ways to view an NWB file graphically instead. A great way to do this in a Jupyter notebook is with NWBWidgets. Here, you can use NWBWidgets to view a file from a location on your machine. If you don’t want to download a file just to view it, you can still use NWBWidgets to view it remotely. Check out Streaming an NWB File with remfile to learn how to do this. Another way to explore an NWB file, that doesn’t require Jupyter, is with HDFView.
Environment Setup#
⚠️Note: If running on a new environment, run this cell once and then restart the kernel⚠️
import warnings
warnings.filterwarnings('ignore')
try:
from databook_utils.dandi_utils import dandi_stream_open
except:
!git clone https://github.com/AllenInstitute/openscope_databook.git
%cd openscope_databook
%pip install -e .
from dandi import dandiapi
from nwbwidgets import nwb2widget
from pynwb import NWBHDF5IO
from nwbwidgets.view import default_neurodata_vis_spec
import pynwb
Downloading an NWB File#
To examine an NWB File locally, it must first be downloaded. dandiset_id
and dandi_filepath
may be changed to select a different file off of DANDI. If the file of interest already downloaded, you don’t need to run the download cell again. When trying to download an embargoed file, refer to the code from the Downloading an NWB File notebook. In the cells below, the DANDI API is used to facilitate the download. The get_dandiset()
methods retrieves a specific dataset within DANDI while the get_asset_by_path()
method retrieves a specific file within that dataset.
dandiset_id = "000021"
dandi_filepath = "sub-699733573/sub-699733573_ses-715093703.nwb"
download_loc = "."
filename = dandi_filepath.split("/")[-1]
filepath = f"{download_loc}/{filename}"
print(filename)
print(filepath)
sub-699733573_ses-715093703.nwb
./sub-699733573_ses-715093703.nwb
client = dandiapi.DandiAPIClient()
my_dandiset = client.get_dandiset(dandiset_id)
file = my_dandiset.get_asset_by_path(dandi_filepath)
# this may take awhile, especially if the file to download is large
file.download(filepath)
print(f"Downloaded file to {filepath}")
Downloaded file to ./sub-699733573_ses-715093703.nwb
Displaying an NWB file#
When passing in the NWB object, the nwb2widget
function will display the NWB file embedded in the notebook with each of the fields and subfields as a widget. NWB Files can vary a lot in their specific structure, so it can be important to familiarize yourself with the structure of the data you’re working with.
io = NWBHDF5IO(filepath, mode="r", load_namespaces=True)
nwb = io.read()
print(nwb)
root pynwb.file.NWBFile at 0x1933891341664
Fields:
acquisition: {
raw_running_wheel_rotation <class 'pynwb.base.TimeSeries'>,
running_wheel_signal_voltage <class 'pynwb.base.TimeSeries'>,
running_wheel_supply_voltage <class 'pynwb.base.TimeSeries'>
}
devices: {
probeA <class 'abc.EcephysProbe'>,
probeB <class 'abc.EcephysProbe'>,
probeC <class 'abc.EcephysProbe'>,
probeD <class 'abc.EcephysProbe'>,
probeE <class 'abc.EcephysProbe'>,
probeF <class 'abc.EcephysProbe'>
}
electrode_groups: {
probeA <class 'abc.EcephysElectrodeGroup'>,
probeB <class 'abc.EcephysElectrodeGroup'>,
probeC <class 'abc.EcephysElectrodeGroup'>,
probeD <class 'abc.EcephysElectrodeGroup'>,
probeE <class 'abc.EcephysElectrodeGroup'>,
probeF <class 'abc.EcephysElectrodeGroup'>
}
electrodes: electrodes <class 'hdmf.common.table.DynamicTable'>
file_create_date: [datetime.datetime(2020, 5, 26, 0, 53, 26, 986608, tzinfo=tzoffset(None, -25200))]
identifier: 715093703
institution: Allen Institute for Brain Science
intervals: {
drifting_gratings_presentations <class 'pynwb.epoch.TimeIntervals'>,
flashes_presentations <class 'pynwb.epoch.TimeIntervals'>,
gabors_presentations <class 'pynwb.epoch.TimeIntervals'>,
invalid_times <class 'pynwb.epoch.TimeIntervals'>,
natural_movie_one_presentations <class 'pynwb.epoch.TimeIntervals'>,
natural_movie_three_presentations <class 'pynwb.epoch.TimeIntervals'>,
natural_scenes_presentations <class 'pynwb.epoch.TimeIntervals'>,
spontaneous_presentations <class 'pynwb.epoch.TimeIntervals'>,
static_gratings_presentations <class 'pynwb.epoch.TimeIntervals'>
}
invalid_times: invalid_times <class 'pynwb.epoch.TimeIntervals'>
processing: {
eye_tracking_rig_metadata <class 'pynwb.base.ProcessingModule'>,
optotagging <class 'pynwb.base.ProcessingModule'>,
running <class 'pynwb.base.ProcessingModule'>,
stimulus <class 'pynwb.base.ProcessingModule'>
}
session_description: Data and metadata for an Ecephys session
session_id: 715093703
session_start_time: 2019-01-19 00:54:18-08:00
stimulus_notes: brain_observatory_1.1
subject: subject abc.EcephysSpecimen at 0x1933891341856
Fields:
age: P118D
age_in_days: 118.0
genotype: Sst-IRES-Cre/wt;Ai32(RCL-ChR2(H134R)_EYFP)/wt
sex: M
species: Mus musculus
specimen_name: Sst-IRES-Cre;Ai32-386129
subject_id: 699733573
timestamps_reference_time: 2019-01-19 00:54:18-08:00
units: units <class 'pynwb.misc.Units'>
# hide the error options in the nwbwidget
neurodata_vis_spec = default_neurodata_vis_spec
units_display = default_neurodata_vis_spec[pynwb.misc.Units]
keys_to_delete = {'Raster Grid','Tuning Curves','Combined','Grouped PSTH'}
for key in keys_to_delete:
if key in units_display:
del units_display[key]
neurodata_vis_spec[pynwb.misc.Units] = units_display
nwb2widget(nwb, neurodata_vis_spec)