Skip to content

Commit a78e776

Browse files
committed
Merge branch 'dev' into nwb_schema_2.8.0
2 parents 424e030 + 54c655f commit a78e776

File tree

2 files changed

+84
-45
lines changed

2 files changed

+84
-45
lines changed

docs/gallery/domain/ecephys.py

Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,27 @@
249249
)
250250
ecephys_module.add(lfp)
251251

252-
####################
252+
#######################
253+
# If the derived data is filtered but not downsampled, you can store the data in an
254+
# :py:class:`~pynwb.ecephys.ElectricalSeries` object in a :py:class:`~pynwb.ecephys.FilteredEphys` object
255+
# instead of a :py:class:`~pynwb.ecephys.LFP` object.
256+
257+
from pynwb.ecephys import FilteredEphys
258+
259+
filtered_data = np.random.randn(50, 12)
260+
filtered_electrical_series = ElectricalSeries(
261+
name="FilteredElectricalSeries",
262+
description="Filtered data",
263+
data=filtered_data,
264+
electrodes=all_table_region,
265+
starting_time=0.0,
266+
rate=200.0,
267+
)
268+
269+
filtered_ephys = FilteredEphys(electrical_series=filtered_electrical_series)
270+
ecephys_module.add(filtered_ephys)
271+
272+
################################
253273
# In some cases, you may want to further process the LFP data and decompose the signal into different frequency bands
254274
# to use for other downstream analyses. You can store the processed data from these spectral analyses using a
255275
# :py:class:`~pynwb.misc.DecompositionSeries` object. This object allows you to include metadata about the frequency
@@ -266,16 +286,23 @@
266286
gamma=(30.0, 80.0)) # in Hz
267287
phase_data = np.random.randn(50, 12, len(bands)) # 50 samples, 12 channels, 3 frequency bands
268288

269-
decomp_series = DecompositionSeries(name="theta",
270-
description="phase of bandpass filtered LFP data",
271-
data=phase_data,
272-
metric='phase',
273-
rate=200.0,
274-
source_channels=all_table_region,
275-
source_timeseries=lfp_electrical_series)
289+
decomp_series = DecompositionSeries(
290+
name="theta",
291+
description="phase of bandpass filtered LFP data",
292+
data=phase_data,
293+
metric='phase',
294+
rate=200.0,
295+
source_channels=all_table_region,
296+
source_timeseries=lfp_electrical_series,
297+
)
276298

277299
for band_name, band_limits in bands.items():
278-
decomp_series.add_band(band_name=band_name, band_limits=band_limits, band_mean=np.nan, band_stdev=np.nan)
300+
decomp_series.add_band(
301+
band_name=band_name,
302+
band_limits=band_limits,
303+
band_mean=np.nan,
304+
band_stdev=np.nan,
305+
)
279306

280307
ecephys_module.add(decomp_series)
281308

@@ -312,6 +339,10 @@
312339

313340
#######################
314341
# The :py:class:`~pynwb.misc.Units` table can also be converted to a pandas :py:class:`~pandas.DataFrame`.
342+
#
343+
# The :py:class:`~pynwb.misc.Units` table can contain simply the spike times of sorted units, or you can also include
344+
# individual and mean waveform information in some of the optional, predefined :py:class:`~pynwb.misc.Units` table
345+
# columns: ``waveform_mean``, ``waveform_sd``, or ``waveforms``.
315346

316347
nwbfile.units.to_dataframe()
317348

@@ -330,44 +361,50 @@
330361
description="shank0",
331362
)
332363

333-
334-
spike_events = SpikeEventSeries(name='SpikeEvents_Shank0',
335-
description="events detected with 100uV threshold",
336-
data=spike_snippets,
337-
timestamps=np.arange(20),
338-
electrodes=shank0)
364+
spike_events = SpikeEventSeries(
365+
name='SpikeEvents_Shank0',
366+
description="events detected with 100uV threshold",
367+
data=spike_snippets,
368+
timestamps=np.arange(20),
369+
electrodes=shank0,
370+
)
339371
nwbfile.add_acquisition(spike_events)
340372

341-
#######################
342-
# Designating electrophysiology data
343-
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
344-
#
345-
# As mentioned above, :py:class:`~pynwb.ecephys.ElectricalSeries` objects
346-
# are meant for storing specific types of extracellular recordings. In addition to this
347-
# :py:class:`~pynwb.base.TimeSeries` class, NWB provides some :ref:`modules_overview`
348-
# for designating the type of data you are storing. We will briefly discuss them here, and refer the reader to
349-
# :py:mod:`API documentation <pynwb.ecephys>` and :ref:`basics` for more details on
350-
# using these objects.
351-
#
352-
# For storing unsorted spiking data, there are two options. Which one you choose depends on what data you
353-
# have available. If you need to store the complete, continuous raw voltage traces, you should store the traces with
354-
# :py:class:`~pynwb.ecephys.ElectricalSeries` objects as :ref:`acquisition <basic_timeseries>` data, and use
355-
# the :py:class:`~pynwb.ecephys.EventDetection` class for identifying the spike events in your raw traces.
373+
############################################
374+
# If you need to store the complete, continuous raw voltage traces, along with unsorted spike times, you should store
375+
# the traces with :py:class:`~pynwb.ecephys.ElectricalSeries` objects as :ref:`acquisition <basic_timeseries>` data,
376+
# and use the :py:class:`~pynwb.ecephys.EventDetection` class to identify the spike events in your raw traces.
377+
378+
from pynwb.ecephys import EventDetection
379+
380+
event_detection = EventDetection(
381+
name="threshold_events",
382+
detection_method="thresholding, 1.5 * std",
383+
source_electricalseries=raw_electrical_series,
384+
source_idx=[1000, 2000, 3000],
385+
times=[.033, .066, .099],
386+
)
387+
388+
ecephys_module.add(event_detection)
389+
390+
######################################
356391
# If you do not want to store the raw voltage traces and only the waveform 'snippets' surrounding spike events,
357392
# you should store the snippets with :py:class:`~pynwb.ecephys.SpikeEventSeries` objects.
358393
#
359-
# The results of spike sorting (or clustering) should be stored in the top-level :py:class:`~pynwb.misc.Units` table.
360-
# The :py:class:`~pynwb.misc.Units` table can contain simply the spike times of sorted units, or you can also include
361-
# individual and mean waveform information in some of the optional, predefined :py:class:`~pynwb.misc.Units` table
362-
# columns: ``waveform_mean``, ``waveform_sd``, or ``waveforms``.
363-
#
364-
# For local field potential data, there are two options. Again, which one you choose depends on what data you
365-
# have available. With both options, you should store your traces with :py:class:`~pynwb.ecephys.ElectricalSeries`
366-
# objects. If you are storing unfiltered local field potential data, you should store
367-
# the :py:class:`~pynwb.ecephys.ElectricalSeries` objects in :py:class:`~pynwb.ecephys.LFP` data interface object(s).
368-
# If you have filtered LFP data, you should store the :py:class:`~pynwb.ecephys.ElectricalSeries` objects in
369-
# :py:class:`~pynwb.ecephys.FilteredEphys` data interface object(s).
394+
# NWB also provides a way to store features of spikes, such as principal components, using the
395+
# :py:class:`~pynwb.ecephys.FeatureExtraction` class.
396+
397+
from pynwb.ecephys import FeatureExtraction
398+
399+
feature_extraction = FeatureExtraction(
400+
name="PCA_features",
401+
electrodes=all_table_region,
402+
description=["PC1", "PC2", "PC3", "PC4"],
403+
times=[.033, .066, .099],
404+
features=np.random.rand(3, 12, 4), # time, channel, feature
405+
)
370406

407+
ecephys_module.add(feature_extraction)
371408

372409
####################
373410
# .. _ecephys_writing:

docs/gallery/general/plot_file.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,12 @@
295295
# object with text information about a stimulus and add it to the stimulus group in
296296
# the :py:class:`~pynwb.file.NWBFile`.
297297

298-
annotations = AnnotationSeries(name='airpuffs',
299-
data=['Left Airpuff', 'Right Airpuff', 'Right Airpuff'],
300-
description='Airpuff events delivered to the animal',
301-
timestamps=[1.0, 3.0, 8.0])
298+
annotations = AnnotationSeries(
299+
name='airpuffs',
300+
data=['Left Airpuff', 'Right Airpuff', 'Right Airpuff'],
301+
description='Airpuff events delivered to the animal',
302+
timestamps=[1.0, 3.0, 8.0],
303+
)
302304

303305
nwbfile.add_stimulus(annotations)
304306

0 commit comments

Comments
 (0)