Neurodata Without Borders (NWB) is a data standard for neurophysiology, providing a unified format for storing diverse neuroscience data types with rich metadata. Built on HDF5, NWB enables data sharing, reproducibility, and tool interoperability.
Key Features
- Standardized schema: Consistent structure for common neuroscience data types
- Comprehensive coverage: Supports electrophysiology, imaging, behavior, optogenetics, and more
- Rich metadata: Stores experimental protocols, subject information, and device specifications
- Tool ecosystem: Growing collection of analysis tools and visualization software
- FAIR principles: Designed for findable, accessible, interoperable, reusable data
Data Types Supported
- Electrophysiology: Spike times, LFP, intracellular recordings
- Optical physiology: Two-photon calcium imaging, fiber photometry
- Behavior: Trials, stimuli, behavioral events, video tracking
- Optogenetics: Stimulation parameters and timing
- Anatomical images: MRI, histology, fluorescence microscopy
Python Integration
from pynwb import NWBFile, NWBHDF5IO
from pynwb.ecephys import LFP, ElectricalSeries
from datetime import datetime
from dateutil.tz import tzlocal
# Create NWB file
nwbfile = NWBFile(
session_description='Visual stimulus experiment',
identifier='mouse_01_session_001',
session_start_time=datetime.now(tzlocal()),
experimenter=['Smith, J.'],
lab='iBOTS Lab',
institution='University',
experiment_description='V1 responses to drifting gratings',
subject={
'subject_id': 'M01',
'age': 'P90D',
'species': 'Mus musculus',
'sex': 'M',
}
)
# Add electrode information
device = nwbfile.create_device(
name='Neuropixels 1.0',
description='384-channel probe',
manufacturer='IMEC'
)
electrode_group = nwbfile.create_electrode_group(
name='V1',
description='Primary visual cortex',
location='V1',
device=device
)
# Add electrodes
for i in range(64):
nwbfile.add_electrode(
id=i,
x=0.0, y=0.0, z=float(i * 20),
imp=float('nan'),
location='V1',
filtering='300-6000 Hz',
group=electrode_group
)
# Add LFP data
electrode_table_region = nwbfile.create_electrode_table_region(
region=list(range(64)),
description='recorded electrodes'
)
lfp_electrical_series = ElectricalSeries(
name='LFP',
data=lfp_data, # shape: (n_time, n_channels)
electrodes=electrode_table_region,
starting_time=0.0,
rate=1000.0,
description='Local field potential'
)
lfp = LFP(electrical_series=lfp_electrical_series)
ecephys_module = nwbfile.create_processing_module(
name='ecephys',
description='Processed electrophysiology data'
)
ecephys_module.add(lfp)
# Write to file
with NWBHDF5IO('experiment.nwb', 'w') as io:
io.write(nwbfile)
# Read from file
with NWBHDF5IO('experiment.nwb', 'r') as io:
read_nwbfile = io.read()
lfp_data = read_nwbfile.processing['ecephys']['LFP']['LFP'].data[:]
When to Use NWB
Best for:
- Multi-modal neuroscience experiments
- Data intended for public sharing (e.g., DANDI Archive)
- Labs collaborating across institutions
- Long-term data archival
- Compliance with funding requirements (NIH BRAIN Initiative)
Consider alternatives for:
- Simple time-series analysis (use Parquet or HDF5)
- Custom data types not covered by NWB schema
- Rapid prototyping before standardization
Integration with Ecosystem
NWB integrates with major neuroscience tools:
- SpikeInterface: Spike sorting with NWB I/O
- Suite2p/CaImAn: Calcium imaging analysis
- DeepLabCut: Pose estimation tracking
- DANDI Archive: Cloud storage for NWB datasets
- NWB Explorer: Web-based visualization