Note
Go to the end to download the full example code
Intracellular Electrophysiology Data using SweepTable¶
The following tutorial describes storage of intracellular electrophysiology data in NWB using the SweepTable to manage recordings.
Warning
The use of SweepTable has been deprecated as of PyNWB >v2.0 in favor of the new hierarchical intracellular electrophysiology metadata tables to allow for a more complete description of intracellular electrophysiology experiments. See the Intracellular electrophysiology tutorial for details.
Creating and Writing NWB files¶
When creating a NWB file, the first step is to create the NWBFile
. The first
argument is is a brief description of the dataset.
from datetime import datetime
from uuid import uuid4
import numpy as np
from dateutil.tz import tzlocal
from pynwb import NWBFile
nwbfile = NWBFile(
session_description="my first synthetic recording",
identifier=str(uuid4()),
session_start_time=datetime.now(tzlocal()),
experimenter=[
"Baggins, Bilbo",
],
lab="Bag End Laboratory",
institution="University of Middle Earth at the Shire",
experiment_description="I went on an adventure to reclaim vast treasures.",
session_id="LONELYMTN001",
)
Device metadata¶
Device metadata is represented by Device
objects.
To create a device, you can use the Device
instance method
create_device
.
device = nwbfile.create_device(name="Heka ITC-1600")
Electrode metadata¶
Intracellular electrode metadata is represented by IntracellularElectrode
objects.
To create an electrode group, you can use the NWBFile
instance method
create_icephys_electrode
.
elec = nwbfile.create_icephys_electrode(
name="elec0", description="a mock intracellular electrode", device=device
)
Stimulus data¶
Intracellular stimulus and response data are represented with subclasses of
PatchClampSeries
. There are two classes for representing stimulus
data
and three classes for representing response
Here, we will use CurrentClampStimulusSeries
to store current clamp stimulus
data and then add it to our NWBFile as stimulus data using the NWBFile
method
add_stimulus
.
from pynwb.icephys import CurrentClampStimulusSeries
ccss = CurrentClampStimulusSeries(
name="ccss",
data=[1, 2, 3, 4, 5],
starting_time=123.6,
rate=10e3,
electrode=elec,
gain=0.02,
sweep_number=0,
)
nwbfile.add_stimulus(ccss, use_sweep_table=True)
We now add another stimulus series but from a different sweep. TimeSeries having the same starting time belong to the same sweep.
from pynwb.icephys import VoltageClampStimulusSeries
vcss = VoltageClampStimulusSeries(
name="vcss",
data=[2, 3, 4, 5, 6],
starting_time=234.5,
rate=10e3,
electrode=elec,
gain=0.03,
sweep_number=1,
)
nwbfile.add_stimulus(vcss, use_sweep_table=True)
Here, we will use CurrentClampSeries
to store current clamp
data and then add it to our NWBFile as acquired data using the NWBFile
method
add_acquisition
.
from pynwb.icephys import CurrentClampSeries
ccs = CurrentClampSeries(
name="ccs",
data=[0.1, 0.2, 0.3, 0.4, 0.5],
conversion=1e-12,
resolution=np.nan,
starting_time=123.6,
rate=20e3,
electrode=elec,
gain=0.02,
bias_current=1e-12,
bridge_balance=70e6,
capacitance_compensation=1e-12,
sweep_number=0,
)
nwbfile.add_acquisition(ccs, use_sweep_table=True)
And voltage clamp data from the second sweep using
VoltageClampSeries
.
from pynwb.icephys import VoltageClampSeries
vcs = VoltageClampSeries(
name="vcs",
data=[0.1, 0.2, 0.3, 0.4, 0.5],
conversion=1e-12,
resolution=np.nan,
starting_time=234.5,
rate=20e3,
electrode=elec,
gain=0.02,
capacitance_slow=100e-12,
resistance_comp_correction=70.0,
sweep_number=1,
)
nwbfile.add_acquisition(vcs, use_sweep_table=True)
Once you have finished adding all of your data to the NWBFile
,
write the file with NWBHDF5IO
.
from pynwb import NWBHDF5IO
with NWBHDF5IO("icephys_example.nwb", "w") as io:
io.write(nwbfile)
For more details on NWBHDF5IO
, see the basic tutorial.
Reading electrophysiology data¶
Now that you have written some intracellular electrophysiology data, you can read it back in.
io = NWBHDF5IO("icephys_example.nwb", "r")
nwbfile = io.read()
For details on retrieving data from an NWBFile
, we refer the reader to the
basic tutorial. For this tutorial, we will just get back our the
CurrentClampStimulusSeries
object we added above.
First, get the CurrentClampStimulusSeries
we added as stimulus data.
ccss = nwbfile.get_stimulus("ccss")
Grabbing acquisition data can be done via get_acquisition
vcs = nwbfile.get_acquisition("vcs")
We can also get back the electrode we added.
elec = nwbfile.get_icephys_electrode("elec0")
Alternatively, we can also get this electrode from the CurrentClampStimulusSeries
we retrieved above. This is exposed via the electrode
attribute.
elec = ccss.electrode
And the device name via get_device
device = nwbfile.get_device("Heka ITC-1600")
If you have data from multiple electrodes and multiple sweeps, it can be
tedious and expensive to search all PatchClampSeries
for the
TimeSeries
with a given sweep.
Fortunately you don’t have to do that manually, instead you can just query
the SweepTable
which stores the mapping between the
PatchClampSeries which belongs to a certain sweep number via
get_series
.
The following call will return the voltage clamp data of two timeseries consisting of acquisition and stimulus, from sweep 1.
series = nwbfile.sweep_table.get_series(1)
# close the file
io.close()