Neurodata Without Borders Extracellular Electrophysiology Tutorial

Table of Contents

This tutorial

Create fake data for a hypothetical extracellular electrophysiology experiment. The types of data we will convert are:
It is recommended to first work through the Introduction to MatNWB tutorial, which demonstrates installing MatNWB and creating an NWB file with subject information, animal position, and trials, as well as writing and reading NWB files in MATLAB.

Setting up the NWB File

An NWB file represents a single session of an experiment. Each file must have a session_description, identifier, and session start time. Create a new NWBFile object with those and additional metadata. For all MatNWB functions, we use the Matlab method of entering keyword argument pairs, where arguments are entered as name followed by value.
nwb = NwbFile( ...
'session_description', 'mouse in open exploration',...
'identifier', 'Mouse5_Day3', ...
'session_start_time', datetime(2018, 4, 25, 2, 30, 3, 'TimeZone', 'local'), ...
'timestamps_reference_time', datetime(2018, 4, 25, 3, 0, 45, 'TimeZone', 'local'), ...
'general_experimenter', 'Last Name, First Name', ... % optional
'general_session_id', 'session_1234', ... % optional
'general_institution', 'University of My Institution', ... % optional
'general_related_publications', {'DOI:10.1016/j.neuron.2016.12.011'}); % optional
nwb
nwb =
NwbFile with properties: nwb_version: '2.7.0' file_create_date: [] identifier: 'Mouse5_Day3' session_description: 'mouse in open exploration' session_start_time: {[2018-04-25T02:30:03.000000+02:00]} timestamps_reference_time: {[2018-04-25T03:00:45.000000+02:00]} acquisition: [0×1 types.untyped.Set] analysis: [0×1 types.untyped.Set] general: [0×1 types.untyped.Set] general_data_collection: '' general_devices: [0×1 types.untyped.Set] general_experiment_description: '' general_experimenter: 'Last Name, First Name' general_extracellular_ephys: [0×1 types.untyped.Set] general_extracellular_ephys_electrodes: [] general_institution: 'University of My Institution' general_intracellular_ephys: [0×1 types.untyped.Set] general_intracellular_ephys_experimental_conditions: [] general_intracellular_ephys_filtering: '' general_intracellular_ephys_intracellular_recordings: [] general_intracellular_ephys_repetitions: [] general_intracellular_ephys_sequential_recordings: [] general_intracellular_ephys_simultaneous_recordings: [] general_intracellular_ephys_sweep_table: [] general_keywords: '' general_lab: '' general_notes: '' general_optogenetics: [0×1 types.untyped.Set] general_optophysiology: [0×1 types.untyped.Set] general_pharmacology: '' general_protocol: '' general_related_publications: {'DOI:10.1016/j.neuron.2016.12.011'} general_session_id: 'session_1234' general_slices: '' general_source_script: '' general_source_script_file_name: '' general_stimulus: '' general_subject: [] general_surgery: '' general_virus: '' intervals: [0×1 types.untyped.Set] intervals_epochs: [] intervals_invalid_times: [] intervals_trials: [] processing: [0×1 types.untyped.Set] scratch: [0×1 types.untyped.Set] stimulus_presentation: [0×1 types.untyped.Set] stimulus_templates: [0×1 types.untyped.Set] units: []

Extracellular Electrophysiology

In order to store extracellular electrophysiology data, you first must create an electrodes table describing the electrodes that generated this data. Extracellular electrodes are stored in an electrodes table, which is also a DynamicTable. electrodes has several required fields: x, y, z, impedance, location, filtering, and electrode_group.

Electrodes Table

Since this is a DynamicTable, we can add additional metadata fields. We will be adding a "label" column to the table.
numShanks = 4;
numChannelsPerShank = 3;
 
ElectrodesDynamicTable = types.hdmf_common.DynamicTable(...
'colnames', {'location', 'group', 'group_name', 'label'}, ...
'description', 'all electrodes');
 
Device = types.core.Device(...
'description', 'the best array', ...
'manufacturer', 'Probe Company 9000' ...
);
nwb.general_devices.set('array', Device);
for iShank = 1:numShanks
shankGroupName = sprintf('shank%d', iShank);
EGroup = types.core.ElectrodeGroup( ...
'description', sprintf('electrode group for %s', shankGroupName), ...
'location', 'brain area', ...
'device', types.untyped.SoftLink(Device) ...
);
nwb.general_extracellular_ephys.set(shankGroupName, EGroup);
for iElectrode = 1:numChannelsPerShank
ElectrodesDynamicTable.addRow( ...
'location', 'unknown', ...
'group', types.untyped.ObjectView(EGroup), ...
'group_name', shankGroupName, ...
'label', sprintf('%s-electrode%d', shankGroupName, iElectrode));
end
end
ElectrodesDynamicTable.toTable() % Display the table
ans = 12×5 table
 idlocationgroupgroup_namelabel
10'unknown'1×1 ObjectView'shank1''shank1-electrode1'
21'unknown'1×1 ObjectView'shank1''shank1-electrode2'
32'unknown'1×1 ObjectView'shank1''shank1-electrode3'
43'unknown'1×1 ObjectView'shank2''shank2-electrode1'
54'unknown'1×1 ObjectView'shank2''shank2-electrode2'
65'unknown'1×1 ObjectView'shank2''shank2-electrode3'
76'unknown'1×1 ObjectView'shank3''shank3-electrode1'
87'unknown'1×1 ObjectView'shank3''shank3-electrode2'
98'unknown'1×1 ObjectView'shank3''shank3-electrode3'
109'unknown'1×1 ObjectView'shank4''shank4-electrode1'
1110'unknown'1×1 ObjectView'shank4''shank4-electrode2'
1211'unknown'1×1 ObjectView'shank4''shank4-electrode3'
 
nwb.general_extracellular_ephys_electrodes = ElectrodesDynamicTable;

Links

In the above loop, we create ElectrodeGroup objects. The electrodes table then uses an ObjectView in each row to link to the corresponding ElectrodeGroup object. An ObjectView is an object that allow you to create a link from one neurodata type referencing another.

ElectricalSeries

Voltage data are stored in ElectricalSeries objects. ElectricalSeries is a subclass of TimeSeries specialized for voltage data. In order to create our ElectricalSeries object, we will need to reference a set of rows in the electrodes table to indicate which electrodes were recorded. We will do this by creating a DynamicTableRegion, which is a type of link that allows you to reference specific rows of a DynamicTable, such as the electrodes table, by row indices.
Create a DynamicTableRegion that references all rows of the electrodes table.
electrode_table_region = types.hdmf_common.DynamicTableRegion( ...
'table', types.untyped.ObjectView(ElectrodesDynamicTable), ...
'description', 'all electrodes', ...
'data', (0:length(ElectrodesDynamicTable.id.data)-1)');
Now create an ElectricalSeries object to hold acquisition data collected during the experiment.
electrical_series = types.core.ElectricalSeries( ...
'starting_time', 0.0, ... % seconds
'starting_time_rate', 30000., ... % Hz
'data', randn(12, 3000), ...
'electrodes', electrode_table_region, ...
'data_unit', 'volts');
This is the voltage data recorded directly from our electrodes, so it goes in the acquisition group.
nwb.acquisition.set('ElectricalSeries', electrical_series);

LFP

Local field potential (LFP) refers in this case to data that has been downsampled and/or filtered from the original acquisition data and is used to analyze signals in the lower frequency range. Filtered and downsampled LFP data would also be stored in an ElectricalSeries. To help data analysis and visualization tools know that this ElectricalSeries object represents LFP data, store it inside an LFP object, then place the LFP object in a ProcessingModule named 'ecephys'. This is analogous to how we stored the SpatialSeries object inside of a Position object and stored the Position object in a ProcessingModule named 'behavior' earlier.
electrical_series = types.core.ElectricalSeries( ...
'starting_time', 0.0, ... % seconds
'starting_time_rate', 1000., ... % Hz
'data', randn(12, 100), ...
'electrodes', electrode_table_region, ...
'data_unit', 'volts');
 
lfp = types.core.LFP('ElectricalSeries', electrical_series);
 
ecephys_module = types.core.ProcessingModule(...
'description', 'extracellular electrophysiology');
 
ecephys_module.nwbdatainterface.set('LFP', lfp);
nwb.processing.set('ecephys', ecephys_module);

Sorted Spike Times

Ragged Arrays

Spike times are stored in another DynamicTable of subtype Units. The default Units table is at /units in the HDF5 file. You can add columns to the Units table just like you did for electrodes and trials. Here, we generate some random spike data and populate the table.
num_cells = 10;
firing_rate = 20;
spikes = cell(1, num_cells);
for iShank = 1:num_cells
spikes{iShank} = rand(1, randi([16, 28]));
end
spikes
spikes = 1×10 cell
 12345678910
11×21 double1×24 double1×18 double1×28 double1×25 double1×18 double1×21 double1×28 double1×16 double1×19 double
Spike times are an example of a ragged array- it's like a matrix, but each row has a different number of elements. We can represent this type of data as an indexed column of the units DynamicTable. These indexed columns have two components, the vector data object that holds the data and the vector index object that holds the indices in the vector that indicate the row breaks. You can use the convenience function util.create_indexed_column to create these objects.
[spike_times_vector, spike_times_index] = util.create_indexed_column(spikes);
 
nwb.units = types.core.Units( ...
'colnames', {'spike_times'}, ...
'description', 'units table', ...
'spike_times', spike_times_vector, ...
'spike_times_index', spike_times_index ...
);
 
nwb.units.toTable
ans = 10×2 table
 idspike_times
1121×1 double
2224×1 double
3318×1 double
4428×1 double
5525×1 double
6618×1 double
7721×1 double
8828×1 double
9916×1 double
101019×1 double

Unsorted Spike Times

In MATLAB, while the Units table is used to store spike times and waveform data for spike-sorted, single-unit activity, you may also want to store spike times and waveform snippets of unsorted spiking activity. This is useful for recording multi-unit activity detected via threshold crossings during data acquisition. Such information can be stored using SpikeEventSeries objects.
% In the SpikeEventSeries the dimensions should be ordered as
% [num_events, num_channels, num_samples].
% Define spike snippets: 20 events, 3 channels, 40 samples per event.
spike_snippets = rand(20, 3, 40);
% Permute spike snippets (See dimensionMapNoDataPipes tutorial)
spike_snippets = permute(spike_snippets, [3,2,1])
spike_snippets =
spike_snippets(:,:,1) = 0.2857 0.6608 0.4367 0.3600 0.1626 0.8400 0.5475 0.0764 0.6130 0.1149 0.6369 0.1302 0.0839 0.7551 0.8632 0.5529 0.3187 0.0518 0.0574 0.7624 0.8898 0.6274 0.6888 0.5444 0.0840 0.9389 0.8369 0.2149 0.7280 0.1379 0.9564 0.0906 0.6076 0.3179 0.7600 0.8335 0.1967 0.6754 0.0739 0.8329 0.0264 0.5930 0.5987 0.1428 0.5505 0.8641 0.5217 0.8748 0.9503 0.9436 0.6849 0.0988 0.6326 0.2984 0.8497 0.6740 0.0928 0.9513 0.1322 0.6433 0.7060 0.3816 0.9528 0.9193 0.2140 0.7737 0.6863 0.3327 0.0457 0.1618 0.8800 0.0862 0.0080 0.8270 0.6271 0.8749 0.5075 0.5516 0.5649 0.8422 0.1858 0.8480 0.8885 0.5991 0.4204 0.1576 0.2430 0.5801 0.3614 0.8714 0.2796 0.5922 0.5711 0.7843 0.8961 0.5321 0.3181 0.6451 0.6615 0.1203 0.4240 0.7307 0.5491 0.9083 0.7756 0.1166 0.2054 0.1056 0.2286 0.7850 0.2984 0.7974 0.3422 0.4096 0.6017 0.6665 0.8854 0.6872 0.0761 0.4004 spike_snippets(:,:,2) = 0.3537 0.5763 0.0558 0.3264 0.0852 0.3904 0.6326 0.9991 0.9243 0.0142 0.3299 0.1727 0.7906 0.1044 0.6286 0.5325 0.6482 0.3741 0.1618 0.3340 0.6112 0.1891 0.3239 0.9190 0.8035 0.1656 0.9514 0.8351 0.5910 0.6103 0.4504 0.8050 0.4005 0.6363 0.7321 0.7352 0.3229 0.4718 0.3551 0.5228 0.9125 0.7943 0.5838 0.8591 0.1924 0.1646 0.9811 0.3952 0.5876 0.7013 0.5506 0.6731 0.0672 0.7196 0.4278 0.2166 0.7300 0.3082 0.0349 0.0998 0.6421 0.0494 0.0303 0.8604 0.1456 0.3563 0.8400 0.7252 0.2455 0.1522 0.9904 0.1299 0.1487 0.3543 0.3340 0.7294 0.4209 0.4987 0.7297 0.4765 0.9868 0.5830 0.8183 0.6142 0.0503 0.9344 0.5153 0.1720 0.1192 0.9391 0.9381 0.5673 0.6301 0.2820 0.4955 0.2350 0.8668 0.6107 0.3925 0.6064 0.8543 0.9834 0.6108 0.4038 0.0298 0.3266 0.5498 0.5972 0.1845 0.5921 0.9274 0.6278 0.8075 0.1228 0.1886 0.3756 0.3849 0.0585 0.6472 0.9450 spike_snippets(:,:,3) = 0.0790 0.9798 0.3705 0.2565 0.3337 0.3708 0.4972 0.1644 0.8170 0.8341 0.4508 0.3991 0.4084 0.5430 0.4807 0.3439 0.6642 0.5703 0.9957 0.1053 0.1126 0.1819 0.7859 0.5963 0.1255 0.1200 0.8429 0.8847 0.4127 0.9843 0.8943 0.6678 0.0982 0.0207 0.9872 0.9731 0.2515 0.3483 0.4459 0.6889 0.5565 0.2033 0.3814 0.8721 0.6273 0.5217 0.2188 0.8595 0.9447 0.0148 0.1967 0.8213 0.0100 0.3596 0.5204 0.0630 0.8961 0.3929 0.7670 0.6272 0.0254 0.7624 0.0719 0.3342 0.8155 0.2478 0.5622 0.2468 0.7245 0.3886 0.1705 0.6961 0.6668 0.7717 0.4452 0.0322 0.9974 0.1323 0.6823 0.3939 0.0021 0.3614 0.2507 0.6621 0.7852 0.7651 0.5013 0.3042 0.7980 0.0191 0.0733 0.7833 0.2535 0.2063 0.2281 0.8499 0.4524 0.5881 0.5972 0.7459 0.2085 0.7855 0.7223 0.9363 0.3330 0.3031 0.0221 0.9362 0.0528 0.5472 0.0018 0.8966 0.7395 0.3072 0.0647 0.9329 0.9689 0.7266 0.1662 0.9855 spike_snippets(:,:,4) = 0.2545 0.1178 0.0623 0.1434 0.7919 0.9073 0.4296 0.1924 0.6309 0.5161 0.1803 0.0288 0.3179 0.7982 0.2427 0.2748 0.3133 0.0101 0.2930 0.1957 0.6955 0.6836 0.9551 0.2006 0.1638 0.1767 0.6102 0.9307 0.7772 0.1972 0.9277 0.5743 0.1019 0.7270 0.7339 0.1749 0.4948 0.2646 0.5360 0.8644 0.7049 0.4960 0.5880 0.8958 0.5753 0.0046 0.9635 0.3048 0.2872 0.7341 0.1214 0.0006 0.4956 0.6200 0.8845 0.5147 0.8833 0.1212 0.1808 0.5548 0.5224 0.7684 0.0541 0.6122 0.9229 0.9004 0.2470 0.2454 0.3503 0.4826 0.1955 0.2739 0.9240 0.7621 0.3529 0.1734 0.0407 0.7469 0.6788 0.3651 0.0434 0.1148 0.2578 0.8098 0.0898 0.4526 0.1006 0.2722 0.9148 0.1465 0.3516 0.7715 0.5164 0.6509 0.2735 0.4134 0.6057 0.5503 0.6118 0.7246 0.3308 0.9303 0.4009 0.2966 0.9465 0.8563 0.4760 0.5895 0.3833 0.8435 0.3921 0.1216 0.6948 0.9617 0.0278 0.8568 0.0843 0.2423 0.5999 0.6319 spike_snippets(:,:,5) = 0.5522 0.6140 0.5597 0.4872 0.7144 0.3502 0.4616 0.4691 0.4971 0.3555 0.4293 0.6880 0.0012 0.4328 0.0814 0.6816 0.5303 0.6519 0.5734 0.7206 0.2286 0.6116 0.0223 0.9631 0.0033 0.3719 0.2236 0.9431 0.1396 0.0793 0.4107 0.9010 0.0474 0.8080 0.4957 0.3896 0.0888 0.6888 0.4446 0.6716 0.0954 0.6248 0.9566 0.5706 0.0673 0.8721 0.6358 0.3166 0.2042 0.8066 0.7187 0.2414 0.9353 0.2232 0.5845 0.9186 0.1913 0.7381 0.7520 0.3618 0.9733 0.9983 0.0858 0.7678 0.0200 0.8217 0.0691 0.5319 0.3943 0.0594 0.5005 0.8020 0.2298 0.7428 0.3926 0.3677 0.9118 0.1565 0.6005 0.3140 0.8609 0.0459 0.6408 0.3229 0.2813 0.0560 0.4407 0.0798 0.9051 0.9379 0.5298 0.4222 0.8412 0.8171 0.5180 0.8489 0.9351 0.5550 0.4569 0.2314 0.2319 0.0156 0.9743 0.4728 0.9320 0.5814 0.4281 0.6112 0.7730 0.4871 0.8687 0.7774 0.5609 0.8990 0.6401 0.7684 0.9780 0.6937 0.3855 0.2773 spike_snippets(:,:,6) = 0.7563 0.7273 0.0133 0.3592 0.8510 0.3783 0.2910 0.2957 0.0741 0.2222 0.6956 0.2550 0.7024 0.7359 0.8882 0.7378 0.5554 0.4322 0.3820 0.1226 0.2407 0.7241 0.7887 0.3233 0.5451 0.4922 0.9290 0.8519 0.6864 0.1900 0.8484 0.4515 0.9817 0.7977 0.2750 0.3051 0.0746 0.6490 0.7667 0.0516 0.7495 0.5505 0.6045 0.0482 0.7680 0.1531 0.1959 0.0531 0.3139 0.2795 0.4414 0.0599 0.3964 0.1188 0.7404 0.0559 0.8768 0.9584 0.2563 0.1812 0.5370 0.5704 0.2613 0.3878 0.6127 0.9154 0.3381 0.5848 0.7191 0.6035 0.1744 0.6816 0.8049 0.4899 0.3228 0.4373 0.2797 0.0940 0.8263 0.6326 0.0613 0.6774 0.9938 0.4658 0.0273 0.3114 0.2264 0.5349 0.2503 0.0345 0.2270 0.1829 0.8232 0.1635 0.3015 0.7972 0.3778 0.3966 0.0747 0.7063 0.9485 0.0910 0.3828 0.1401 0.8424 0.3238 0.2967 0.7296 0.4243 0.0952 0.8124 0.4995 0.4657 0.7694 0.1477 0.7937 0.8987 0.4048 0.1036 0.0002 spike_snippets(:,:,7) = 0.4580 0.9207 0.2481 0.1836 0.6374 0.5111 0.0742 0.8433 0.9611 0.0159 0.8911 0.7889 0.2008 0.8055 0.7266 0.5994 0.8005 0.9522 0.4349 0.8104 0.8747 0.3428 0.7336 0.5881 0.1481 0.0946 0.9118 0.0831 0.5271 0.7814 0.0389 0.8958 0.8084 0.3233 0.3729 0.3681 0.4450 0.6990 0.3603 0.6181 0.9658 0.1873 0.5898 0.2502 0.0125 0.2308 0.2501 0.7988 0.8013 0.1657 0.0417 0.9670 0.8803 0.1257 0.0179 0.6742 0.8754 0.3485 0.9857 0.9407 0.2647 0.2288 0.6305 0.0033 0.4910 0.1960 0.9030 0.8703 0.3570 0.5235 0.2891 0.1002 0.2324 0.0010 0.2280 0.2612 0.3101 0.0855 0.5968 0.3174 0.4167 0.9640 0.7214 0.4913 0.1577 0.9385 0.1025 0.1977 0.5359 0.2251 0.3496 0.7907 0.7362 0.0281 0.6693 0.0673 0.2872 0.3925 0.5873 0.3650 0.4479 0.9278 0.8428 0.9876 0.6636 0.8083 0.6426 0.9633 0.5935 0.5707 0.7156 0.6495 0.7981 0.8620 0.4248 0.5334 0.1100 0.0895 0.6389 0.0086 spike_snippets(:,:,8) = 0.3173 0.7239 0.5842 0.9806 0.3725 0.7392 0.2726 0.0862 0.7087 0.7864 0.9975 0.8527 0.1554 0.4242 0.5882 0.7534 0.3430 0.0112 0.3874 0.5027 0.4471 0.3280 0.3424 0.3045 0.1938 0.7505 0.7932 0.2593 0.2949 0.4888 0.5396 0.1103 0.9481 0.1231 0.6017 0.7679 0.0303 0.7178 0.3082 0.6338 0.5286 0.1721 0.5765 0.0735 0.1011 0.4303 0.6201 0.7509 0.4182 0.1388 0.1476 0.2248 0.5659 0.0135 0.4919 0.7920 0.0609 0.2389 0.4693 0.8358 0.7148 0.3369 0.5812 0.1331 0.7267 0.6000 0.7245 0.4390 0.8241 0.5550 0.9808 0.7514 0.9064 0.5307 0.9582 0.8849 0.6957 0.7481 0.2192 0.9088 0.5844 0.2364 0.5855 0.7902 0.7584 0.0846 0.1370 0.7727 0.2945 0.2277 0.8112 0.0527 0.8338 0.3527 0.3030 0.9882 0.0002 0.2667 0.9848 0.2195 0.0832 0.4510 0.8938 0.0728 0.4832 0.8841 0.6265 0.6150 0.8769 0.5066 0.4031 0.6807 0.3424 0.9336 0.2345 0.0089 0.7260 0.2382 0.3721 0.6684 spike_snippets(:,:,9) = 0.7887 0.1178 0.4502 0.8269 0.3962 0.5211 0.9859 0.7808 0.8825 0.7219 0.9935 0.1152 0.0173 0.1858 0.4448 0.0044 0.2231 0.0820 0.8686 0.5382 0.2548 0.4520 0.9463 0.1562 0.5869 0.8375 0.2189 0.7871 0.7757 0.4243 0.1588 0.5478 0.6302 0.4440 0.3944 0.8391 0.3337 0.1684 0.5720 0.0759 0.9428 0.7316 0.2520 0.8726 0.6824 0.5137 0.2414 0.0452 0.8611 0.8641 0.2069 0.5499 0.9632 0.1246 0.3078 0.4369 0.9144 0.7565 0.7739 0.5479 0.3609 0.3100 0.5928 0.3456 0.5537 0.2476 0.6165 0.3551 0.7373 0.5038 0.6011 0.9023 0.9612 0.7047 0.1553 0.3012 0.6818 0.3364 0.7665 0.1590 0.6036 0.7387 0.1920 0.7323 0.6689 0.6163 0.1122 0.0597 0.1126 0.9075 0.4382 0.9988 0.5944 0.5352 0.5993 0.9150 0.0732 0.8298 0.4190 0.1000 0.1752 0.8498 0.2800 0.1332 0.4710 0.8509 0.2318 0.1789 0.0231 0.6613 0.9997 0.8469 0.7678 0.8919 0.7672 0.0896 0.8968 0.3195 0.3421 0.0274 spike_snippets(:,:,10) = 0.0246 0.1593 0.0619 0.1265 0.4231 0.4204 0.8991 0.6043 0.3761 0.9254 0.1290 0.2395 0.3477 0.0261 0.3631 0.4255 0.5196 0.4987 0.4745 0.6889 0.5786 0.6804 0.9587 0.7136 0.2899 0.7803 0.5361 0.4230 0.3868 0.5688 0.3492 0.5184 0.7157 0.3322 0.2954 0.5267 0.3834 0.0758 0.3822 0.3095 0.9617 0.0138 0.1127 0.2855 0.8902 0.4317 0.8442 0.9792 0.7420 0.0902 0.0456 0.7662 0.1624 0.1115 0.6543 0.3400 0.6864 0.6296 0.1255 0.5455 0.9029 0.0879 0.5006 0.6050 0.8464 0.5591 0.3601 0.3826 0.1305 0.8042 0.7910 0.4607 0.5606 0.6963 0.7884 0.3205 0.2410 0.7519 0.0024 0.6577 0.6181 0.1318 0.1590 0.2453 0.2791 0.1981 0.6390 0.2292 0.9181 0.1980 0.5690 0.9134 0.5699 0.0218 0.6615 0.1191 0.7396 0.8588 0.8290 0.4791 0.2304 0.7855 0.6231 0.5621 0.5530 0.2377 0.7269 0.4795 0.9498 0.7593 0.3992 0.4043 0.5552 0.6333 0.3988 0.1177 0.9016 0.6999 0.0590 0.5461 spike_snippets(:,:,11) = 0.2220 0.6161 0.5482 0.4123 0.1179 0.7582 0.7245 0.9598 0.6356 0.7210 0.6697 0.9592 0.5535 0.0940 0.7996 0.4417 0.4261 0.0502 0.4423 0.5592 0.2896 0.9676 0.3315 0.7111 0.6885 0.1419 0.4361 0.0655 0.0035 0.1327 0.3826 0.6864 0.3620 0.0971 0.4998 0.1317 0.6550 0.8911 0.7389 0.7726 0.3506 0.4817 0.9044 0.0072 0.4791 0.9699 0.5444 0.4785 0.0592 0.5717 0.1154 0.6694 0.8065 0.3114 0.0451 0.4908 0.5335 0.6083 0.8033 0.7573 0.4028 0.8962 0.7841 0.6808 0.6181 0.2081 0.7436 0.6448 0.3955 0.0222 0.5468 0.5692 0.5026 0.1176 0.5409 0.3683 0.6528 0.1630 0.3198 0.7608 0.0527 0.0307 0.6699 0.7209 0.9927 0.2533 0.7853 0.5352 0.7892 0.0157 0.4994 0.9594 0.8645 0.2182 0.8810 0.4853 0.0327 0.1107 0.5328 0.4987 0.8243 0.0942 0.3071 0.6421 0.3681 0.0825 0.2762 0.5065 0.7225 0.3783 0.5774 0.1505 0.5689 0.6437 0.2730 0.3795 0.4207 0.3812 0.3843 0.7570 spike_snippets(:,:,12) = 0.4536 0.0348 0.1280 0.0937 0.3153 0.8244 0.0254 0.7321 0.1776 0.5266 0.1378 0.7937 0.8184 0.4512 0.3127 0.2168 0.1070 0.4184 0.4308 0.8058 0.1924 0.2676 0.6272 0.4703 0.7924 0.5767 0.2068 0.6820 0.1100 0.2608 0.8025 0.4762 0.5039 0.5449 0.9441 0.8725 0.6045 0.0750 0.7539 0.3219 0.0809 0.9189 0.6374 0.1076 0.6818 0.6043 0.9807 0.2184 0.4737 0.8263 0.0113 0.4661 0.1748 0.3905 0.1515 0.5849 0.7402 0.0386 0.0491 0.0699 0.0451 0.8471 0.2438 0.9840 0.0645 0.1164 0.4521 0.4423 0.6804 0.3990 0.5811 0.2845 0.9404 0.8687 0.0697 0.7555 0.0850 0.2861 0.4284 0.9813 0.1606 0.1728 0.0667 0.2492 0.5687 0.0777 0.2709 0.2264 0.5504 0.8100 0.0541 0.0368 0.5259 0.4999 0.3839 0.5377 0.8043 0.5455 0.7418 0.2652 0.8362 0.7342 0.4792 0.8744 0.6765 0.3494 0.9809 0.9374 0.4120 0.9923 0.1729 0.8693 0.4478 0.9683 0.2047 0.0203 0.7611 0.2584 0.7700 0.7948 spike_snippets(:,:,13) = 0.0157 0.0647 0.6416 0.7638 0.1440 0.4338 0.3404 0.7033 0.9323 0.3327 0.2419 0.0158 0.1027 0.5447 0.9455 0.4155 0.5504 0.4124 0.4389 0.7090 0.1019 0.1135 0.1518 0.7802 0.1862 0.0991 0.9385 0.8108 0.3330 0.3703 0.8882 0.0429 0.0777 0.6938 0.3064 0.6495 0.3660 0.9739 0.9794 0.2094 0.1125 0.6123 0.9374 0.2039 0.4439 0.3380 0.0786 0.5313 0.6468 0.8286 0.6347 0.8093 0.9563 0.2979 0.2439 0.3000 0.7636 0.9876 0.4089 0.9489 0.0655 0.6382 0.4527 0.5187 0.1400 0.3417 0.4703 0.5862 0.9807 0.2048 0.6405 0.4133 0.7057 0.7886 0.9320 0.2141 0.2059 0.3750 0.5749 0.4097 0.0935 0.1075 0.7629 0.3086 0.7586 0.6562 0.2721 0.8715 0.4178 0.0318 0.7900 0.4142 0.5397 0.5306 0.9462 0.6588 0.4306 0.8370 0.4302 0.5899 0.5945 0.0762 0.8496 0.3275 0.7257 0.2751 0.2624 0.5545 0.1538 0.0924 0.3398 0.7160 0.0858 0.0901 0.9813 0.8219 0.6498 0.8121 0.5394 0.8237 spike_snippets(:,:,14) = 0.0221 0.8614 0.7634 0.3983 0.6727 0.3550 0.9539 0.1561 0.6813 0.5583 0.5885 0.9967 0.4075 0.0813 0.4429 0.2310 0.0248 0.7509 0.6427 0.7612 0.3196 0.7487 0.7756 0.8189 0.0629 0.4779 0.6550 0.8839 0.6752 0.3173 0.6077 0.3845 0.6331 0.3133 0.1429 0.8957 0.4345 0.7169 0.9520 0.0100 0.3340 0.6187 0.5361 0.1743 0.7057 0.7226 0.3522 0.6633 0.2896 0.4041 0.8869 0.7655 0.6235 0.4579 0.8103 0.0950 0.5008 0.8029 0.9529 0.8503 0.3489 0.9096 0.4176 0.6609 0.9922 0.3921 0.8915 0.3578 0.2378 0.3911 0.2561 0.2023 0.1938 0.1357 0.0510 0.5737 0.0948 0.8470 0.0540 0.6226 0.4725 0.2451 0.7750 0.8025 0.8169 0.3337 0.6998 0.2011 0.9325 0.9863 0.8228 0.7149 0.2157 0.9203 0.8141 0.3663 0.7566 0.7477 0.5670 0.8637 0.9622 0.7179 0.8148 0.6600 0.2051 0.4581 0.3688 0.0015 0.0350 0.1912 0.5752 0.5222 0.8343 0.5959 0.7374 0.5795 0.6809 0.9218 0.9206 0.8737 spike_snippets(:,:,15) = 0.7865 0.7816 0.6155 0.5372 0.8114 0.4325 0.3727 0.8911 0.7185 0.0353 0.0340 0.4635 0.5840 0.0862 0.1968 0.9519 0.5324 0.2445 0.3134 0.7084 0.1353 0.1848 0.7557 0.4126 0.0106 0.8252 0.7487 0.1224 0.7105 0.7313 0.8718 0.5462 0.9643 0.2917 0.9847 0.3488 0.5548 0.8527 0.6744 0.0908 0.7675 0.8040 0.1565 0.1608 0.3398 0.7158 0.9291 0.1652 0.6822 0.5056 0.6049 0.6157 0.1270 0.7319 0.8646 0.4195 0.5200 0.0489 0.9945 0.8455 0.8568 0.1741 0.1825 0.5738 0.0524 0.1239 0.8604 0.1834 0.0426 0.3432 0.0838 0.5858 0.1225 0.9384 0.2049 0.8457 0.1780 0.2640 0.0039 0.7270 0.9247 0.2992 0.3269 0.1270 0.9960 0.6671 0.7288 0.3351 0.2429 0.6398 0.5583 0.6861 0.2227 0.3737 0.3230 0.4208 0.0274 0.5645 0.2406 0.5473 0.4634 0.8339 0.6710 0.1899 0.1739 0.9775 0.4120 0.5454 0.3883 0.3817 0.5621 0.4033 0.6777 0.4225 0.7234 0.2555 0.9704 0.1591 0.4925 0.9903 spike_snippets(:,:,16) = 0.9601 0.4261 0.8380 0.4578 0.3814 0.9816 0.7650 0.7522 0.4094 0.0475 0.7618 0.2626 0.0517 0.4061 0.9587 0.3187 0.5696 0.0575 0.9259 0.4462 0.2033 0.5448 0.1725 0.5606 0.1203 0.7607 0.0725 0.8443 0.4323 0.7786 0.5015 0.6739 0.2669 0.0986 0.3635 0.6841 0.4879 0.6765 0.0829 0.9984 0.5124 0.1379 0.2017 0.6917 0.2215 0.2086 0.6594 0.5955 0.1700 0.9997 0.9314 0.2926 0.9844 0.1808 0.7029 0.1544 0.3578 0.1826 0.5482 0.9631 0.5764 0.0881 0.1198 0.2232 0.6394 0.1269 0.0194 0.4497 0.3601 0.7354 0.7041 0.9677 0.8830 0.4438 0.7886 0.5622 0.1308 0.8845 0.7777 0.6478 0.4099 0.9439 0.9918 0.3069 0.1511 0.8404 0.6417 0.3328 0.5915 0.7386 0.7354 0.3478 0.1711 0.5607 0.9615 0.8547 0.8202 0.1768 0.7434 0.9688 0.3658 0.0483 0.3226 0.4188 0.7442 0.6305 0.0570 0.8543 0.0882 0.8940 0.9014 0.2526 0.0621 0.0940 0.8808 0.3889 0.5883 0.6945 0.2075 0.9826 spike_snippets(:,:,17) = 0.2518 0.5818 0.5687 0.1692 0.2601 0.8900 0.9416 0.9621 0.9741 0.6602 0.8987 0.2570 0.1918 0.9138 0.1570 0.4492 0.2385 0.0065 0.2470 0.6987 0.7600 0.4756 0.2300 0.5099 0.7998 0.4087 0.1418 0.3431 0.9322 0.6007 0.6657 0.9061 0.4275 0.8680 0.5521 0.2827 0.2041 0.2542 0.1747 0.8590 0.0126 0.7438 0.9619 0.0740 0.6684 0.0479 0.9238 0.3660 0.0550 0.0913 0.3853 0.6281 0.2848 0.6150 0.7952 0.2270 0.6275 0.4146 0.8272 0.9834 0.7049 0.8764 0.7300 0.8926 0.7747 0.2170 0.0096 0.2669 0.7916 0.4492 0.9704 0.6413 0.2610 0.9420 0.6689 0.5655 0.8651 0.2311 0.7637 0.2866 0.1800 0.2147 0.0454 0.4293 0.2542 0.5383 0.2259 0.9819 0.8289 0.4630 0.6742 0.0134 0.3185 0.1221 0.7918 0.9145 0.1994 0.2983 0.8845 0.1645 0.5156 0.6800 0.0033 0.2655 0.0551 0.5693 0.5705 0.0326 0.2717 0.6311 0.1091 0.9801 0.3286 0.5908 0.5141 0.1275 0.6234 0.3310 0.6454 0.7261 spike_snippets(:,:,18) = 0.6792 0.1536 0.7686 0.4197 0.6222 0.3823 0.3714 0.4234 0.2509 0.7312 0.3902 0.0159 0.7945 0.9858 0.1467 0.5954 0.0416 0.6832 0.6992 0.2205 0.4558 0.5526 0.3969 0.6680 0.0647 0.0462 0.5156 0.0087 0.1158 0.5595 0.3502 0.2373 0.1293 0.3708 0.9807 0.5301 0.6378 0.8133 0.2024 0.3669 0.0297 0.6785 0.2471 0.4422 0.2760 0.2854 0.5070 0.9157 0.4780 0.8939 0.2641 0.0007 0.4187 0.1611 0.2343 0.2207 0.5019 0.3406 0.6748 0.8346 0.1625 0.8566 0.0020 0.5023 0.6093 0.5408 0.5373 0.5792 0.9837 0.4145 0.5383 0.3824 0.6758 0.0357 0.1393 0.2909 0.0263 0.2084 0.9296 0.4293 0.0568 0.1195 0.8615 0.3890 0.6217 0.4449 0.8288 0.2219 0.2328 0.2420 0.9573 0.7066 0.0879 0.3173 0.7592 0.4618 0.0770 0.2486 0.6727 0.3387 0.2439 0.4620 0.6189 0.2457 0.6979 0.4550 0.4702 0.6991 0.3922 0.4539 0.3660 0.1967 0.6131 0.1070 0.9190 0.3731 0.9881 0.6727 0.0177 0.8368 spike_snippets(:,:,19) = 0.5723 0.4162 0.5737 0.7365 0.7400 0.0192 0.3486 0.1283 0.5239 0.5596 0.0741 0.9627 0.7251 0.3255 0.9218 0.4888 0.2237 0.8870 0.2031 0.5954 0.6067 0.3191 0.4081 0.8511 0.4727 0.8630 0.4413 0.0459 0.9529 0.9355 0.0706 0.7296 0.7513 0.1063 0.2827 0.0582 0.9681 0.3477 0.4857 0.0197 0.6786 0.2709 0.5342 0.7845 0.3807 0.4403 0.9275 0.8690 0.1449 0.7715 0.0911 0.4528 0.3883 0.4938 0.2482 0.6608 0.2387 0.2375 0.4085 0.6854 0.4636 0.7216 0.3191 0.4088 0.6269 0.4242 0.6251 0.8265 0.3873 0.7480 0.9342 0.8437 0.7078 0.5361 0.7469 0.6856 0.5139 0.4963 0.9682 0.1418 0.5922 0.3966 0.6482 0.8709 0.6875 0.3060 0.4249 0.3703 0.8274 0.2291 0.7073 0.3335 0.8946 0.5328 0.5704 0.4358 0.3135 0.3453 0.4677 0.4190 0.8187 0.4792 0.4847 0.5276 0.9708 0.2647 0.7839 0.6610 0.4281 0.1247 0.1745 0.4473 0.1502 0.9363 0.5404 0.8297 0.3259 0.8203 0.1586 0.0542 spike_snippets(:,:,20) = 0.1943 0.5619 0.1293 0.9273 0.8478 0.7970 0.1930 0.3151 0.4309 0.7377 0.5235 0.5462 0.2804 0.0120 0.1150 0.1102 0.7948 0.4490 0.3471 0.2344 0.6634 0.9368 0.7492 0.8331 0.0338 0.8952 0.0004 0.3556 0.8802 0.2122 0.3900 0.4580 0.4061 0.3526 0.3209 0.9486 0.1045 0.3968 0.7268 0.3758 0.6132 0.2621 0.2642 0.8817 0.2963 0.5723 0.1138 0.3768 0.9351 0.0277 0.3637 0.1406 0.2203 0.2729 0.5997 0.5051 0.3468 0.2357 0.7267 0.0786 0.9923 0.6103 0.2772 0.1016 0.6222 0.8030 0.4693 0.7362 0.1926 0.7770 0.7613 0.1670 0.8043 0.4398 0.5129 0.5659 0.0116 0.4863 0.2755 0.4490 0.3219 0.9902 0.0969 0.6059 0.5231 0.5545 0.6418 0.6858 0.0013 0.3912 0.7352 0.1463 0.8434 0.3129 0.7567 0.2621 0.8429 0.9725 0.3036 0.0225 0.0850 0.6518 0.8738 0.2763 0.6083 0.9140 0.8860 0.5986 0.1661 0.6797 0.4139 0.0239 0.4074 0.7700 0.3080 0.5475 0.4765 0.7355 0.0164 0.3026
 
% Create electrode table region referencing electrodes 0, 1, and 2
shank0_table_region = types.hdmf_common.DynamicTableRegion( ...
'table', types.untyped.ObjectView(ElectrodesDynamicTable), ...
'description', 'shank0', ...
'data', (0:2)');
 
% Define spike event series for unsorted spike times
spike_events = types.core.SpikeEventSeries( ...
'data', spike_snippets, ...
'timestamps', (0:19)', ... % Timestamps for each event
'description', 'events detected with 100uV threshold', ...
'electrodes', shank0_table_region ...
);
 
% Add spike event series to NWB file acquisition
nwb.acquisition.set('SpikeEvents_Shank0', spike_events);

Designating Electrophysiology Data

As mentioned above, ElectricalSeries objects are meant for storing specific types of extracellular recordings. In addition to this TimeSeries class, NWB provides some Processing Modules for designating the type of data you are storing. We will briefly discuss them here, and refer the reader to the API documentation and Intro to NWB for more details on using these objects.
For storing unsorted spiking data, there are two options. Which one you choose depends on what data you have available. If you need to store complete and/or continuous raw voltage traces, you should store the traces with ElectricalSeries objects as acquisition data, and use the EventDetection class for identifying the spike events in your raw traces. If you do not want to store the raw voltage traces and only the waveform ‘snippets’ surrounding spike events, you should use SpikeEventSeries objects.
The results of spike sorting (or clustering) should be stored in the top-level Units table. The Units table can hold just the spike times of sorted units or, optionally, include additional waveform information. You can use the optional predefined columns waveform_mean, waveform_sd, and waveforms in the Units table to store individual and mean waveform data.
For local field potential data, there are two options. Again, which one you choose depends on what data you have available. With both options, you should store your traces with ElectricalSeries objects. If you are storing unfiltered local field potential data, you should store the ElectricalSeries objects in LFP data interface object(s). If you have filtered LFP data, you should store the ElectricalSeries objects in FilteredEphys data interface object(s).

Writing the NWB File

nwbExport(nwb, 'ecephys_tutorial.nwb')

Reading NWB Data

Data arrays are read passively from the file. Calling TimeSeries.data does not read the data values, but presents an HDF5 object that can be indexed to read data. This allows you to conveniently work with datasets that are too large to fit in RAM all at once. load with no input arguments reads the entire dataset:
nwb2 = nwbRead('ecephys_tutorial.nwb', 'ignorecache');
nwb2.processing.get('ecephys'). ...
nwbdatainterface.get('LFP'). ...
electricalseries.get('ElectricalSeries'). ...
data.load;

Accessing Data Regions

If all you need is a data region, you can index a DataStub object like you would any normal array in MATLAB, as shown below. When indexing the dataset this way, only the selected region is read from disk into RAM. This allows you to handle very large datasets that would not fit entirely into RAM.
% read section of LFP
nwb2.processing.get('ecephys'). ...
nwbdatainterface.get('LFP'). ...
electricalseries.get('ElectricalSeries'). ...
data(1:5, 1:10)
ans = 5×10
-1.0039 -0.5621 -1.1019 0.1768 0.2032 0.1612 -0.5518 0.8552 -1.3040 -0.5646 -0.3458 -1.2921 -0.1967 1.7260 -1.5245 1.3653 -0.6380 0.8438 -0.7094 0.7466 0.2758 -0.3401 0.3549 0.4890 -0.2288 0.1290 2.1648 0.1316 -0.2172 0.3036 -0.8548 -1.5282 -0.0919 -0.1388 1.7996 -0.2845 -1.1904 0.5773 -0.3059 -0.9745 0.1536 -0.2051 2.4873 1.0999 0.6398 -0.1086 -0.2511 -0.0993 1.3019 0.0095
 
% You can use the getRow method of the table to load spike times of a specific unit.
% To get the values, unpack from the returned table.
nwb.units.getRow(1).spike_times{1}
ans = 21×1
0.8383 0.6321 0.2418 0.2965 0.9865 0.2779 0.9945 0.5980 0.1216 0.1694

Learn more!

See the API documentation to learn what data types are available.

MATLAB tutorials

Python tutorials

See our tutorials for more details about your data type:
Check out other tutorials that teach advanced NWB topics: