Skip to content

Commit

Permalink
Add hs64 stimulation pages and data loading script
Browse files Browse the repository at this point in the history
- Conform hardware guides to a standard and fix data loading scripts
 - Bno055 CsvWriter should be consistent
 - memory monitor template + pages for np1 & np2
 -  Change timestamp to filecount for file suffixes
- Change Load Data titles
  • Loading branch information
cjsha committed Dec 4, 2024
1 parent 303c1dc commit e2a23be
Show file tree
Hide file tree
Showing 57 changed files with 620 additions and 276 deletions.
20 changes: 11 additions & 9 deletions articles/getting-started/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ title: Software Reference
---

The following table provides information about which operators correspond to which hardware and the "Shift" and "Scale"
values to convert the ADC value to μV. For more information, refer to the
[Basic Ephys Data Processing in Bonsai](xref:basic-ephys-processing).
values to convert the ADC value to μV. "Shift" refers to the value required to subtract from unsigned data to center its
dynamic range around zero. The "Shift" value is typically $2^{(bit depth - 1)}$. "Scale" refers to the scalar required to
multiply to your data to convert it from units of DAC step size to μV.

| Hardware | Configuration Operator | Ephys Device | Ephys Data Operator | Data Frame | Shift | Scale |
|----------------------------------|-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|----------------------------------------------------|--------|--------------------|
| Headstage64 | <xref:OpenEphys.Onix1.ConfigureHeadstage64> | [Intan Rhd2164 (amplifier channels)](https://intantech.com/files/Intan_RHD2164_datasheet.pdf) | <xref:OpenEphys.Onix1.Rhd2164Data> | <xref:OpenEphys.Onix1.Rhd2164DataFrame> | -32768 | 0.195 |
| HeadstageRhs2116 | <xref:OpenEphys.Onix1.ConfigureHeadstageRhs2116> | [Intan Rhs2116](https://intantech.com/files/Intan_RHS2116_datasheet.pdf) | <xref:OpenEphys.Onix1.Rhs2116Data> | <xref:OpenEphys.Onix1.Rhs2116DataFrame> | -32768 | 0.195 |
| NeuropixelsV1e<wbr>Headstage | <xref:OpenEphys.Onix1.ConfigureNeuropixelsV1eHeadstage> | [Neuropixels 1.0 probe (AP)](https://www.neuropixels.org/_files/ugd/328966_c5e4d31e8a974962b5eb8ec975408c9f.pdf) | <xref:OpenEphys.Onix1.NeuropixelsV1eData> | <xref:OpenEphys.Onix1.NeuropixelsV1DataFrame> | -512 | $1.2e6/1024/gain$* |
| NeuropixelsV2e<wbr>Headstage | <xref:OpenEphys.Onix1.ConfigureNeuropixelsV2eHeadstage> | [Neuropixels 2.0 probe](https://www.neuropixels.org/_files/ugd/328966_2b39661f072d405b8d284c3c73588bc6.pdf) | <xref:OpenEphys.Onix1.NeuropixelsV2eData> | <xref:OpenEphys.Onix1.NeuropixelsV2eDataFrame> | -2048 | 3.05176 |
| NeuropixelsV2eBeta<wbr>Headstage | <xref:OpenEphys.Onix1.ConfigureNeuropixelsV2eBetaHeadstage> | Neuropixels 2.0 Beta probe | <xref:OpenEphys.Onix1.NeuropixelsV2eBetaData> | <xref:OpenEphys.Onix1.NeuropixelsV2eBetaDataFrame> | -8192 | 0.7629 |
| Hardware | Configuration Operator | Analog Input Device | Ephys Data Operator | Data Frame | Shift | Scale |
|----------------------------------|-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|----------------------------------------------------|--------|--------------------|
| Headstage64 | <xref:OpenEphys.Onix1.ConfigureHeadstage64> | [Intan Rhd2164 (amplifier & auxiliary)](https://intantech.com/files/Intan_RHD2164_datasheet.pdf) | <xref:OpenEphys.Onix1.Rhd2164Data> | <xref:OpenEphys.Onix1.Rhd2164DataFrame> | -32768 | 0.195 |
| HeadstageRhs2116 | <xref:OpenEphys.Onix1.ConfigureHeadstageRhs2116> | [Intan Rhs2116](https://intantech.com/files/Intan_RHS2116_datasheet.pdf) | <xref:OpenEphys.Onix1.Rhs2116Data> | <xref:OpenEphys.Onix1.Rhs2116DataFrame> | -32768 | 0.195 |
| NeuropixelsV1e<wbr>Headstage | <xref:OpenEphys.Onix1.ConfigureNeuropixelsV1eHeadstage> | [Neuropixels 1.0 probe (AP & LFP)](https://www.neuropixels.org/_files/ugd/328966_c5e4d31e8a974962b5eb8ec975408c9f.pdf) | <xref:OpenEphys.Onix1.NeuropixelsV1eData> | <xref:OpenEphys.Onix1.NeuropixelsV1DataFrame> | -512 | $1.2e6/1024/gain$* |
| NeuropixelsV2e<wbr>Headstage | <xref:OpenEphys.Onix1.ConfigureNeuropixelsV2eHeadstage> | [Neuropixels 2.0 probe](https://www.neuropixels.org/_files/ugd/328966_2b39661f072d405b8d284c3c73588bc6.pdf) | <xref:OpenEphys.Onix1.NeuropixelsV2eData> | <xref:OpenEphys.Onix1.NeuropixelsV2eDataFrame> | -2048 | 3.05176 |
<!-- | NeuropixelsV2eBeta<wbr>Headstage | <xref:OpenEphys.Onix1.ConfigureNeuropixelsV2eBetaHeadstage> | Neuropixels 2.0 Beta probe | <xref:OpenEphys.Onix1.NeuropixelsV2eBetaData> | <xref:OpenEphys.Onix1.NeuropixelsV2eBetaDataFrame> | -8192 | 0.7629 |
| BreakoutBoard | <xref:OpenEphys.Onix1.ConfigureBreakoutBoard> | [Breakout Board Analog Input]() in | <xref:OpenEphys.Onix1.AnalogInput> | <xref:OpenEphys.Onix1.AnalogInputDataFrame> | -8192 | 0.7629 | -->

\* The Neuropixels 1.0 probes have selectable gain which has an effect on the multiplier for scaling the signal to μV,
so the $1.2e6/1024/gain$ formula must be used to calculate the correct "Scale" value. The Gain is set by the user in the
Expand Down
4 changes: 2 additions & 2 deletions articles/hardware/breakout/analog-io.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ operators each select a member from the `AnalogInputDataFrame`, `Clock` and `Ana
contain the <xref:OpenEphys.Onix1.ContextTask.AcquisitionClockHz>-based sample times and sample
values, respectively. The
[MatrixWriter](https://bonsai-rx.org/docs/api/Bonsai.Dsp.MatrixWriter.html) operators saves the
selected members to files with the following format: `analog-clock_<timestamp>.raw` and
`analog-data_<timestamp>.raw`, respectively.
selected members to files with the following format: `analog-clock_<filecount>.raw` and
`analog-data_<filecount>.raw`, respectively.

> [!Tip]
> The easiest way to add a
Expand Down
2 changes: 1 addition & 1 deletion articles/hardware/breakout/digital-inputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ The following excerpt from the Breakout Board [example workflow](xref:breakout_w

The <xref:OpenEphys.Onix1.DigitalInput> operator generates a sequence of <xref:OpenEphys.Onix1.DigitalInputDataFrame>s. Although the digital inputs are sampled at 4 Mhz, these data frames are only emitted when the port status changes (i.e., when a pin, button, or switch is toggled). The digital input ports on the Breakout Board operate at a 3.3V logic levels but are also 5V tolerant. In the Breakout Board example workflow, the `DigitalInput`'s `DeviceName` property is set to "BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to the corresponding configuration operator.

The [CsvWriter](https://bonsai-rx.org/docs/api/Bonsai.IO.CsvWriter.html) operator writes the `Clock`, `DigitalInputs`, and `Buttons` members from the `DigitalInputDataFrame` to a file with the following name format: `digital-input_<timestamp>.csv`. Because `CsvWriter` is a _sink_ operator, its output sequence is equivalent to its input sequence. In other words, its output is equivalent to `DigitalInput`'s output. Therefore, it's possible to use [MemberSelector](https://bonsai-rx.org/docs/api/Bonsai.Expressions.MemberSelectorBuilder.html) operators on the `CsvWriter` to select members from `DigitalInputDataFrame`. This is most easily performed by clicking the relevant members that appear by hovering over the "Output" option that appears in the context menu that appears after right-clicking the `CsvWriter` node. The members selected in the workflow, <xref:OpenEphys.Onix1.DigitalPortState> and <xref:OpenEphys.Onix1.BreakoutButtonState>, are enumerators with values that correspond to bit positions of the breakout board's digital ports. When `DigitalPortState` or `OpenEphys.Onix1.BreakoutButtonState` is connected to a `HasFlags` operator, the names that appear in the `HasFlags`'s `Value` property's dropdown menu correspond to bit positions in the respective digital input port. In this workflow, the top `HasFlags` operator checks if `Triangle` or `X` are `True`.
The [CsvWriter](https://bonsai-rx.org/docs/api/Bonsai.IO.CsvWriter.html) operator writes the `Clock`, `DigitalInputs`, and `Buttons` members from the `DigitalInputDataFrame` to a file with the following name format: `digital-input_<filecount>.csv`. Because `CsvWriter` is a _sink_ operator, its output sequence is equivalent to its input sequence. In other words, its output is equivalent to `DigitalInput`'s output. Therefore, it's possible to use [MemberSelector](https://bonsai-rx.org/docs/api/Bonsai.Expressions.MemberSelectorBuilder.html) operators on the `CsvWriter` to select members from `DigitalInputDataFrame`. This is most easily performed by clicking the relevant members that appear by hovering over the "Output" option that appears in the context menu that appears after right-clicking the `CsvWriter` node. The members selected in the workflow, <xref:OpenEphys.Onix1.DigitalPortState> and <xref:OpenEphys.Onix1.BreakoutButtonState>, are enumerators with values that correspond to bit positions of the breakout board's digital ports. When `DigitalPortState` or `OpenEphys.Onix1.BreakoutButtonState` is connected to a `HasFlags` operator, the names that appear in the `HasFlags`'s `Value` property's dropdown menu correspond to bit positions in the respective digital input port. In this workflow, the top `HasFlags` operator checks if `Triangle` or `X` are `True`.
2 changes: 1 addition & 1 deletion articles/hardware/breakout/load-data.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
uid: breakout_load-data
title: Load Breakout Board Data
title: Load Data
---

The following python script can be used to load and plot the data produced by the Breakout Board [example workflow](xref:breakout_workflow).
Expand Down
32 changes: 5 additions & 27 deletions articles/hardware/breakout/memory-monitor.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,8 @@
---
uid: breakout_memory-monitor
title: Breakout Board Memory Monitor
device: memory monitor
title: Memory Monitor
memoryMonitor: true
hardware: Breakout Board
hardwareOperator: BreakoutBoard
workflowDirectory: breakout/workflow
---

The following excerpt from the Breakout Board [example workflow](xref:breakout_workflow) demonstrates memory monitor functionality and saves memory monitor data.

::: workflow
![/workflows/hardware/breakout/memory-monitor.bonsai workflow](../../../workflows/hardware/breakout/memory-monitor.bonsai)
:::

The <xref:OpenEphys.Onix1.MemoryMonitorData> operator generates a sequence of <xref:OpenEphys.Onix1.MemoryMonitorDataFrame>s. `MemoryMonitorData` emits `MemoryMonitorDataFrame`s at a regular interval defined during <xref:breakout_configuration> using the <xref:OpenEphys.Onix1.ConfigureBreakoutBoard>'s `MemoryMonitor SamplesPerSecond` property (in our case 10 Hz). In the Breakout Board example workflow, the `MemoryMonitorData`'s `DeviceName` property is set to "BreakoutBoard/MemoryMonitor". This links the `MemoryMonitorData` operator to the corresponding configuration operator. The [CsvWriter](https://bonsai-rx.org/docs/api/Bonsai.IO.CsvWriter.html) operator saves the `Clock`, `BytesUsed`, and `PercentUsed` members to a file with the following format: `memory-use_<timestamp>.csv`. Because `CsvWriter` is a _sink_ operator, its output sequence is equivalent to its input sequence. In other words, its output is equivalent to `MemoryMonitorData`'s output. Therefore, it's possible to use a [MemberSelector](https://bonsai-rx.org/docs/api/Bonsai.Expressions.MemberSelectorBuilder.html) operator on the `CsvWriter` to select members from the `MemoryMonitorDataFrame`. The `MemberSelector` operator selects the `PercentUsed` member from the `MemoryMonitorDataFrame` so the user can visualize `PercentUsed` data from the `MemoryMonitorDataFrame`.

> [!NOTE]
> The `MemoryMonitorDataFrame` operator generates a
> data stream that is most useful in the context of closed-loop performance. It tells the user if data
> is being consumed rapidly enough by the host PC to keep up with data production by the hardware. The
> hardware FIFO is a buffer that is required to deal with the fact that computers with normal
> operating systems cannot perform operations with strict regularity. When there are hiccups in
> acquisition, the hardware FIFO picks up the slack, but should then be cleared immediately. To get
> the lowest latencies, the `BlockReadSize` should be as small as possible *while the memory use
> percentage remains around 0%*.
> [!WARNING]
> If the hardware FIFO's `PercentUsed` is non-zero for long time periods, or is increasing, the
> `StartAcquisition`'s `BlockReadSize` setting is too small (see the [breakout board configuration](xref:breakout_configuration)). A small
> `BlockReadSize` will mean that the host computer does not have to wait long for enough data to
> become available to propagate it forward, but will reduce overall bandwidth by increasing the
> frequency at which the host computer checks if data is available and performs hardware reads.
5 changes: 3 additions & 2 deletions articles/hardware/hs64/bno055.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
uid: hs64_bno055
title: Headstage 64 Bno055
hardware: Headstage 64
bno055: true
hardware: Headstage 64
bnoOperator: Bno055Data
hardwareOperator: Headstage 64
hardwareOperator: Headstage64
workflowDirectory: hs64/workflow
---
19 changes: 18 additions & 1 deletion articles/hardware/hs64/estim.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,25 @@ uid: hs64_estim
title: Headstage 64 Electrical Stimulation
---

The following excerpt from the Headstage64 [example workflow](xref:hs64_hs64) demonstrates electrical stimulation.
The following excerpt from the Headstage64 [example workflow](xref:hs64_workflow) demonstrates electrical stimulation by
triggering a train of pulses following a press of the △ key on the breakout board.

::: workflow
![/workflows/hardware/hs64/estim.bonsai workflow](../../../workflows/hardware/hs64/estim.bonsai)
:::

The <xref:OpenEphys.Onix1.DigitalInput> operator generates a sequence of <xref:OpenEphys.Onix1.DigitalInputDataFrame>s.
Although the digital inputs are sampled at 4 Mhz, these data frames are only emitted when the port status changes (i.e.,
when a pin, button, or switch is toggled). In the Breakout Board example workflow, the `DigitalInput`'s `DeviceName`
property is set to "BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to the corresponding
configuration operator.

<xref:OpenEphys.Onix1.BreakoutButtonState> is selected from the `DigitalInputDataFrame`. It is an enumerator with values
that correspond to bit positions of the breakout board's digital port. When this type is connected to a `HasFlags`
operator, the enumerated values appear in the `HasFlags`'s `Value` property's dropdown menu. Because `HasFlags`'s
`Value` is set to "Triangle", its output is "True" when the selected `BreakoutButtonState` bit field contains the
"Triangle" flag.

When the <xref:OpenEphys.Onix1.Headstage64ElectricalStimulatorTrigger> operator receives a "True" value in its input
sequence, a stimulus waveform is triggered. The waveform can be modified by editing the
`Headstage64ElectricalStimulatorTrig` operator's properties.
14 changes: 14 additions & 0 deletions articles/hardware/hs64/load-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
uid: hs64_load-data
title: Load Data
---

The following python script can be used to load and plot the data produced by the Headstage64 [example workflow](xref:hs64_workflow).

[!code-python[](../../../workflows/hardware/hs64/load-hs64.py)]

> [!NOTE]
> This script will attempt to load entire files into arrays. For long recordings, data will need to
> be split into more manageable chunks by:
> - Modifying this script to partially load files
> - Modifying the workflow to cyclically create new files after a certain duration
31 changes: 5 additions & 26 deletions articles/hardware/hs64/memory-monitor.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
---
uid: hs64_memory-monitor
title: Headstage64 Memory Monitor
title: Memory Monitor
memoryMonitor: true
hardware: Headstage 64
hardwareOperator: Headstage64
workflowDirectory: hs64/workflow
---

The following excerpt from the Breakout Board [example workflow](xref:breakout_workflow) demonstrates memory monitor functionality and saves memory monitor data.

::: workflow
![/workflows/hardware/breakout/memory-monitor.bonsai workflow](../../../workflows/hardware/breakout/memory-monitor.bonsai)
:::

The <xref:OpenEphys.Onix1.MemoryMonitorData> operator generates a sequence of <xref:OpenEphys.Onix1.MemoryMonitorDataFrame>s. `MemoryMonitorData` emits `MemoryMonitorDataFrame`s at a regular interval defined during <xref:breakout_configuration> using the <xref:OpenEphys.Onix1.ConfigureBreakoutBoard>'s `MemoryMonitor SamplesPerSecond` property (in our case 10 Hz). In the Breakout Board example workflow, the `MemoryMonitorData`'s `DeviceName` property is set to "BreakoutBoard/MemoryMonitor". This links the `MemoryMonitorData` operator to the corresponding configuration operator. The [CsvWriter](https://bonsai-rx.org/docs/api/Bonsai.IO.CsvWriter.html) operator saves the `Clock`, `BytesUsed`, and `PercentUsed` members to a file with the following format: `memory-use_<timestamp>.csv`. Because `CsvWriter` is a _sink_ operator, its output sequence is equivalent to its input sequence. In other words, its output is equivalent to `MemoryMonitorData`'s output. Therefore, it's possible to use a [MemberSelector](https://bonsai-rx.org/docs/api/Bonsai.Expressions.MemberSelectorBuilder.html) operator on the `CsvWriter` to select members from the `MemoryMonitorDataFrame`. The `MemberSelector` operator selects the `PercentUsed` member from the `MemoryMonitorDataFrame` so the user can visualize `PercentUsed` data from the `MemoryMonitorDataFrame`.

> [!NOTE]
> The `MemoryMonitorDataFrame` operator generates a
> data stream that is most useful in the context of closed-loop performance. It tells the user if data
> is being consumed rapidly enough by the host PC to keep up with data production by the hardware. The
> hardware FIFO is a buffer that is required to deal with the fact that computers with normal
> operating systems cannot perform operations with strict regularity. When there are hiccups in
> acquisition, the hardware FIFO picks up the slack, but should then be cleared immediately. To get
> the lowest latencies, the `BlockReadSize` should be as small as possible *while the memory use
> percentage remains around 0%*.
> [!WARNING]
> If the hardware FIFO's `PercentUsed` is non-zero for long time periods, or is increasing, the
> `StartAcquisition`'s `BlockReadSize` setting is too small (see the [breakout board configuration](xref:breakout_configuration)). A small
> `BlockReadSize` will mean that the host computer does not have to wait long for enough data to
> become available to propagate it forward, but will reduce overall bandwidth by increasing the
> frequency at which the host computer checks if data is available and performs hardware reads.
Loading

0 comments on commit e2a23be

Please sign in to comment.