|
80 | 80 | # The electrodes table references a required :py:class:`~pynwb.ecephys.ElectrodeGroup`, which is used to represent a |
81 | 81 | # group of electrodes. Before creating an :py:class:`~pynwb.ecephys.ElectrodeGroup`, you must define a |
82 | 82 | # :py:class:`~pynwb.device.Device` object using the method :py:meth:`.NWBFile.create_device`. The fields |
83 | | -# ``description``, ``manufacturer``, ``model_number``, ``model_name``, and ``serial_number`` are optional, but |
84 | | -# recommended. |
| 83 | +# ``description``, ``serial_number``, and ``model`` are optional, but recommended. The |
| 84 | +# :py:class:`~pynwb.device.DeviceModel` object stores information about the device model, which can be useful |
| 85 | +# when searching a set of NWB files or a data archive for all files that use a specific device model |
| 86 | +# (e.g., Neuropixels probe). |
| 87 | +device_model = nwbfile.create_device_model( |
| 88 | + name="Neurovoxels 0.99", |
| 89 | + manufacturer="Array Technologies", |
| 90 | + model_number="PRB_1_4_0480_123", |
| 91 | + description="A 12-channel array with 4 shanks and 3 channels per shank", |
| 92 | +) |
85 | 93 | device = nwbfile.create_device( |
86 | 94 | name="array", |
87 | 95 | description="A 12-channel array with 4 shanks and 3 channels per shank", |
88 | | - manufacturer="Array Technologies", |
89 | | - model_number="PRB_1_4_0480_123", |
90 | | - model_name="Neurovoxels 0.99", |
91 | 96 | serial_number="1234567890", |
| 97 | + model=device_model, |
92 | 98 | ) |
93 | 99 |
|
94 | 100 | ####################### |
|
238 | 244 | lfp = LFP(electrical_series=lfp_electrical_series) |
239 | 245 |
|
240 | 246 | #################### |
241 | | -# LFP refers to data that has been low-pass filtered, typically below 300 Hz. This data may also be downsampled. |
| 247 | +# LFP refers to data that has been low-pass filtered, typically below 300 Hz. This data may also be downsampled. |
242 | 248 | # Because it is filtered and potentially resampled, it is categorized as processed data. |
243 | 249 | # |
244 | 250 | # Create a processing module named ``"ecephys"`` and add the :py:class:`~pynwb.ecephys.LFP` object to it. |
|
252 | 258 |
|
253 | 259 | ####################### |
254 | 260 | # If your data is filtered for frequency ranges other than LFP — such as Gamma or Theta — you should store it in an |
255 | | -# :py:class:`~pynwb.ecephys.ElectricalSeries` and encapsulate it within a |
| 261 | +# :py:class:`~pynwb.ecephys.ElectricalSeries` and encapsulate it within a |
256 | 262 | # :py:class:`~pynwb.ecephys.FilteredEphys` object. |
257 | 263 |
|
258 | 264 | from pynwb.ecephys import FilteredEphys |
|
272 | 278 | ecephys_module.add(filtered_ephys) |
273 | 279 |
|
274 | 280 | ################################ |
275 | | -# In some cases, you may want to further process the LFP data and decompose the signal into different frequency bands |
| 281 | +# In some cases, you may want to further process the LFP data and decompose the signal into different frequency bands |
276 | 282 | # to use for other downstream analyses. You can store the processed data from these spectral analyses using a |
277 | 283 | # :py:class:`~pynwb.misc.DecompositionSeries` object. This object allows you to include metadata about the frequency |
278 | | -# bands and metric used (e.g., power, phase, amplitude), as well as link the decomposed data to the original |
| 284 | +# bands and metric used (e.g., power, phase, amplitude), as well as link the decomposed data to the original |
279 | 285 | # :py:class:`~pynwb.base.TimeSeries` signal the data was derived from. |
280 | 286 |
|
281 | 287 | ####################### |
282 | | -# .. note:: When adding data to :py:class:`~pynwb.misc.DecompositionSeries`, the ``data`` argument is assumed to be |
| 288 | +# .. note:: When adding data to :py:class:`~pynwb.misc.DecompositionSeries`, the ``data`` argument is assumed to be |
283 | 289 | # 3D where the first dimension is time, the second dimension is channels, and the third dimension is bands. |
284 | 290 |
|
285 | 291 |
|
286 | | -bands = dict(theta=(4.0, 12.0), |
287 | | - beta=(12.0, 30.0), |
| 292 | +bands = dict(theta=(4.0, 12.0), |
| 293 | + beta=(12.0, 30.0), |
288 | 294 | gamma=(30.0, 80.0)) # in Hz |
289 | | -phase_data = np.random.randn(50, 12, len(bands)) # 50 samples, 12 channels, 3 frequency bands |
| 295 | +phase_data = np.random.randn(50, 12, len(bands)) # 50 samples, 12 channels, 3 frequency bands |
290 | 296 |
|
291 | 297 | decomp_series = DecompositionSeries( |
292 | 298 | name="theta", |
|
353 | 359 | # While the :py:class:`~pynwb.misc.Units` table is used to store spike times and waveform data for |
354 | 360 | # spike-sorted, single-unit activity, you may also want to store spike times and waveform snippets of |
355 | 361 | # unsorted spiking activity (e.g., multi-unit activity detected via threshold crossings during data acquisition). |
356 | | -# This information can be stored using :py:class:`~pynwb.ecephys.SpikeEventSeries` objects. |
| 362 | +# This information can be stored using :py:class:`~pynwb.ecephys.SpikeEventSeries` objects. |
357 | 363 |
|
358 | 364 | spike_snippets = np.random.rand(40, 3, 30) # 40 events, 3 channels, 30 samples per event |
359 | 365 | shank0 = nwbfile.create_electrode_table_region( |
|
381 | 387 | name="threshold_events", |
382 | 388 | detection_method="thresholding, 1.5 * std", |
383 | 389 | source_electricalseries=raw_electrical_series, |
384 | | - source_idx=[1000, 2000, 3000], |
| 390 | + source_idx=[[1000, 0], [2000, 4], [3000, 8]], # indicates the time and channel indices |
385 | 391 | times=[.033, .066, .099], |
386 | 392 | ) |
387 | 393 |
|
|
0 commit comments