From 554e78d96a9813d6f68dd5d5bc6d49d4f26f0f7f Mon Sep 17 00:00:00 2001 From: Steph Prince <40640337+stephprince@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:44:36 -0800 Subject: [PATCH] update tutorial and documentation --- docs/gallery/domain/plot_icephys.py | 40 +++++++++++++++++++++-------- src/pynwb/base.py | 13 +++++----- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/docs/gallery/domain/plot_icephys.py b/docs/gallery/domain/plot_icephys.py index 162714845..2e7f51a23 100644 --- a/docs/gallery/domain/plot_icephys.py +++ b/docs/gallery/domain/plot_icephys.py @@ -459,16 +459,31 @@ ) ##################################################################### +# Adding stimulus templates +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# # One predefined subcategory column is the ``stimulus_template`` column in the stimuli table. This column is # used to store template waveforms of stimuli in addition to the actual recorded stimulus that is stored in the -# ``stimulus`` column. Similar to the ``stimulus`` and ``response`` columns, we can specify a relevant -# time range. +# ``stimulus`` column. The ``stimulus_template`` column contains an idealized version of the template waveform used as +# the stimulus. This can be useful as a noiseless version of the stimulus for data analysis or to validate that the +# recorded stimulus matches the expected waveform of the template. Similar to the ``stimulus`` and ``response`` +# columns, we can specify a relevant time range. + +stimulus_template = VoltageClampStimulusSeries( + name="ccst", + data=[0, 1, 2, 3, 4], + starting_time=0.0, + rate=10e3, + electrode=electrode, + gain=0.02, +) +nwbfile.add_stimulus_template(stimulus_template) nwbfile.intracellular_recordings.add_column( name="stimulus_template", - data=[TimeSeriesReference(0, 5, stimulus), # (start_index, index_count, stimulus_template) - TimeSeriesReference(1, 3, stimulus), - TimeSeriesReference.empty(stimulus)], # if there was no data for that recording, use an empty reference + data=[TimeSeriesReference(0, 5, stimulus_template), # (start_index, index_count, stimulus_template) + TimeSeriesReference(1, 3, stimulus_template), + TimeSeriesReference.empty(stimulus_template)], # if there was no data for that recording, use empty reference description="Column storing the reference to the stimulus template for the recording (rows).", category="stimuli", col_cls=TimeSeriesReferenceVectorData @@ -478,7 +493,7 @@ rowindex = nwbfile.add_intracellular_recording( electrode=electrode, stimulus=stimulus, - stimulus_template=stimulus, # the full time range of the stimulus template will be used unless specified + stimulus_template=stimulus_template, # the full time range of the stimulus template will be used unless specified recording_tag='A4', recording_lab_data={'location': 'Isengard'}, electrode_metadata={'voltage_threshold': 0.14}, @@ -486,10 +501,15 @@ ) ##################################################################### -# .. note:: If a stimulus template column exists but there is no stimulus template data for that recording, then the -# stimulus template will be internally set to the provided stimulus or response TimeSeries and the start_index -# and index_count for the missing parameter are set to -1. The missing values will be represented via masked -# numpy arrays. +# .. note:: If a stimulus template column exists but there is no stimulus template data for that recording, then +# :py:meth:`~pynwb.file.NWBFile.add_intracellular_recording` will internally set the stimulus template to the +# provided stimulus or response TimeSeries and the start_index and index_count for the missing parameter are +# set to -1. The missing values will be represented via masked numpy arrays. + +##################################################################### +# .. note:: Since stimulus templates are often reused across many recordings, the timestamps in the templates are not +# usually aligned with the recording nor with the reference time of the file. The timestamps often start +# at 0 and are relative to the time of the application of the stimulus. ##################################################################### # Add a simultaneous recording diff --git a/src/pynwb/base.py b/src/pynwb/base.py index f47414328..d1ca74a2f 100644 --- a/src/pynwb/base.py +++ b/src/pynwb/base.py @@ -505,13 +505,12 @@ def empty(cls, timeseries): When missing data needs to be represented, NWB defines ``None`` for the complex data type ``(idx_start, count, TimeSeries)`` as (-1, -1, TimeSeries) for storage. The exact timeseries object will technically not - matter since the empty reference is a way of indicating a NaN value. in a - :py:class:`~pynwb.base.TimeSeriesReferenceVectorData` column. - - An example, where this functionality is used is :py:class:`~pynwb.icephys.IntracellularRecordingsTable` - where only one of stimulus or response data was recorded. In such cases, the timeseries object for the - empty stimulus :py:class:`~pynwb.base.TimeSeriesReference` could be set to the response series, or - vice versa. + matter since the empty reference is a way of indicating a NaN value in a + :py:class:`~pynwb.base.TimeSeriesReferenceVectorData` column. + + An example where this functionality is used is :py:class:`~pynwb.icephys.IntracellularRecordingsTable` + where only one of stimulus or response data was recorded. In such cases, the timeseries object for the + empty stimulus :py:class:`~pynwb.base.TimeSeriesReference` could be set to the response series, or vice versa. :returns: Returns :py:class:`~pynwb.base.TimeSeriesReference` """