From 75eaef9d65bbb69dad11cb5c2cc31e558aae1f18 Mon Sep 17 00:00:00 2001 From: cjsha Date: Thu, 30 Oct 2025 15:22:56 -0400 Subject: [PATCH 1/4] Documentation for GPO trigger and stimulator reports --- articles/hardware/hs64/estim.md | 44 ++-- articles/hardware/hs64/gpo-trigger.md | 49 ++++ articles/hardware/hs64/ostim.md | 46 ++-- articles/hardware/hs64/stimulator-data.md | 38 +++ articles/toc.yml | 4 + workflows/hardware/hs64/estim.bonsai | 33 ++- workflows/hardware/hs64/gpo-trigger.bonsai | 52 ++++ workflows/hardware/hs64/hs64.bonsai | 226 +++++++++++++++--- workflows/hardware/hs64/load-hs64.py | 59 ++++- workflows/hardware/hs64/ostim.bonsai | 30 ++- .../hardware/hs64/stimulator-data.bonsai | 41 ++++ ...Headstage64ElectricalStimulatorData.bonsai | 16 ++ ...dstage64ElectricalStimulatorTrigger.bonsai | 38 ++- .../operators/Headstage64GpoTrigger.bonsai | 52 ++++ .../Headstage64OpticalStimulatorData.bonsai | 16 ++ ...Headstage64OpticalStimulatorTrigger.bonsai | 35 ++- 16 files changed, 662 insertions(+), 117 deletions(-) create mode 100644 articles/hardware/hs64/gpo-trigger.md create mode 100644 articles/hardware/hs64/stimulator-data.md create mode 100644 workflows/hardware/hs64/gpo-trigger.bonsai create mode 100644 workflows/hardware/hs64/stimulator-data.bonsai create mode 100644 workflows/operators/Headstage64ElectricalStimulatorData.bonsai create mode 100644 workflows/operators/Headstage64GpoTrigger.bonsai create mode 100644 workflows/operators/Headstage64OpticalStimulatorData.bonsai diff --git a/articles/hardware/hs64/estim.md b/articles/hardware/hs64/estim.md index b9472976..3085aa34 100644 --- a/articles/hardware/hs64/estim.md +++ b/articles/hardware/hs64/estim.md @@ -3,26 +3,42 @@ uid: hs64_estim title: Headstage 64 Electrical Stimulation --- -The following excerpt from the Headstage 64 [example workflow](xref:hs64_workflow) demonstrates electrical stimulation by -triggering a train of pulses following a press of the △ key on the breakout board. +The following excerpt from the Headstage 64 [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 operator generates a sequence of -[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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. +[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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 +Headstage 64 example workflow, the `DigitalInput`'s `DeviceName` property is +set to "BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to +the corresponding configuration operator. - 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. + 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. The operator only +allows passes an item in its input sequence if it's different from the previous +item in the input sequence. The operator only +passes an item in its input sequence if `Condition`'s internal logic is "True". +In this case, `Condition` has no internal logic (which can be inspected by +selecting the node and pressing Ctrl+Enter), so it uses the value of +the Boolean in its input sequence to decide whether or not to pass a value. The + operator emits a value determined by +its `Value` property whenever it receives an item in its input sequence. T This +value is used to determine the delay between triggering the stimulus and +delivery of the stimulus. When `Double`'s `Value` property is set to zero, there +is no such delay. -When the operator receives a "True" value in its input -sequence, a stimulus waveform is triggered. The waveform can be modified by editing the +When the 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. \ No newline at end of file diff --git a/articles/hardware/hs64/gpo-trigger.md b/articles/hardware/hs64/gpo-trigger.md new file mode 100644 index 00000000..45ed07bd --- /dev/null +++ b/articles/hardware/hs64/gpo-trigger.md @@ -0,0 +1,49 @@ +--- +uid: hs64_gpo-trigger +title: Headstage 64 GPO Trigger +--- + +The following excerpt from the Headstage 64 [example +workflow](xref:hs64_workflow) demonstrates triggering a stimulus following a +press of the □ key on the breakout board. The GPO trigger uses a pin on the +headstage to trigger stimulus more instantaneously than other trigger methods +that write to a register on the hardware which takes more time. However, this +trigger operator does not provide stimulus feedback as discussed in + nor is it capable of distinguishing between applying +optical or electrical stimulus. If you want to use the GPO trigger to only +trigger electrical stimulus, the electrical stimulator should be the only +stimulator device armed on the headstage. If you want to use the GPO trigger to +only trigger optical stimulus, the optical stimulator should be the only +stimulator device armed on the headstage. + +::: workflow +![/workflows/hardware/hs64/gpo-trigger.bonsai workflow](../../../workflows/hardware/hs64/gpo-trigger.bonsai) +::: + +The operator generates a sequence of +[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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. + + 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 "Square", its +output is "True" when the selected `BreakoutButtonState` bit field contains the +"Square" flag. The operator only +allows passes an item in its input sequence if it's different from the previous +item in the input sequence. The operator only +passes an item in its input sequence if `Condition`'s internal logic +is "True". In this case, `Condition` has no internal logic (which can +be inspected by selecting the node and pressing Ctrl+Enter), so it +uses the value of the Boolean in its input sequence to decide whether or not to +pass a value. + +When the 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. \ No newline at end of file diff --git a/articles/hardware/hs64/ostim.md b/articles/hardware/hs64/ostim.md index 350e612d..d4b5caa1 100644 --- a/articles/hardware/hs64/ostim.md +++ b/articles/hardware/hs64/ostim.md @@ -3,26 +3,42 @@ uid: hs64_ostim title: Headstage 64 Optical Stimulation --- -The following excerpt from the Headstage64 [example workflow](xref:hs64_workflow) demonstrates optical stimulation by -triggering a train of pulses following a press of the ◯ key on the breakout board. +The following excerpt from the Headstage64 [example +workflow](xref:hs64_workflow) demonstrates optical stimulation by triggering a +train of pulses following a press of the ◯ key on the breakout board. ::: workflow ![/workflows/hardware/hs64/ostim.bonsai workflow](../../../workflows/hardware/hs64/ostim.bonsai) ::: The operator generates a sequence of -[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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. +[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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 +Headstage 64 example workflow, the `DigitalInput`'s `DeviceName` property is +set to "BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to +the corresponding configuration operator. - 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 "Circle", its output is "True" when the selected `BreakoutButtonState` bit field contains the -"Circle" flag. + 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 "Circle", its +output is "True" when the selected `BreakoutButtonState` bit field contains the +"Circle" flag. The operator only +allows passes an item in its input sequence if it's different from the previous +item in the input sequence. The operator only +passes an item in its input sequence if `Condition`'s internal logic is "True". +In this case, `Condition` has no internal logic (which can be inspected by +selecting the node and pressing Ctrl+Enter), so it uses the value of +the Boolean in its input sequence to decide whether or not to pass a value. The + operator emits a value determined by +its `Value` property whenever it receives an item in its input sequence. This +value is used to determine the delay between triggering the stimulus and +delivery of the stimulus. When `Double`'s `Value` property is set to zero, there +is no such delay. -When the operator receives a "True" value in its input -sequence, a stimulus waveform is triggered. The waveform can be modified by editing the -`Headstage64OpticalStimulatorTrig` operator's properties. \ No newline at end of file +When the operator +receives a "True" value in its input sequence, a stimulus waveform is triggered. +The waveform can be modified by editing the `Headstage64OpticalStimulatorTrig` +operator's properties. \ No newline at end of file diff --git a/articles/hardware/hs64/stimulator-data.md b/articles/hardware/hs64/stimulator-data.md new file mode 100644 index 00000000..94c8568d --- /dev/null +++ b/articles/hardware/hs64/stimulator-data.md @@ -0,0 +1,38 @@ +--- +uid: hs64_stimulator-data +title: Headstage 64 Stimulator Data +--- + +The following excerpt from the Headstage 64 [example +workflow](xref:hs64_workflow) demonstrates how to save the waveform parameters +and the hardware timestamp of every stimulus delivered as described in the +, , and articles. + +::: workflow +![/workflows/hardware/hs64/stimulator-data.bonsai workflow](../../../workflows/hardware/hs64/stimulator-data.bonsai) +::: + +The operator +generates a sequence of +[Headstage64ElectricalStimulatorDataFrames](xref:OpenEphys.Onix1.Headstage64ElectricalStimulatorDataFrame) +which contain data about when an electrical stimulus was delivered and the +corresponding electrical stimulation waveform. A frame is emitted when an +electrical stimulus is delivered. In the Headstage 64 example workflow, the +`Headstage64ElectricalStimulatorData`'s `DeviceName` property is set to +"Headstage64/Headstage64ElectricalStimulator". This links the +`Headstage64ElectricalStimulatorData` operator to the corresponding +configuration operator. Frames from this operators are saved to a file named +"estim_.csv" using a . + +The operator generates a +sequence of +[Headstage64OpticalStimulatorDataFrames](xref:OpenEphys.Onix1.Headstage64OpticalStimulatorDataFrame) +which contain data about when an optical stimulus was delivered and the +corresponding optical stimulation waveform. A frame is emitted when an optical +stimulus is delivered. In the Headstage 64 example workflow, the +`Headstage64OpticalStimulatorData`'s `DeviceName` property is set to +"Headstage64/Headstage64OpticalStimulator". This links the +`Headstage64OpticalStimulatorData` operator to the corresponding configuration +operator. Frames from this operators are saved to a file named "ostim_.csv" +using a `CsvWriter`. + diff --git a/articles/toc.yml b/articles/toc.yml index 470cbbcd..f4a5e7fa 100644 --- a/articles/toc.yml +++ b/articles/toc.yml @@ -75,6 +75,10 @@ href: hardware/hs64/estim.md - name: Optical Stimulation href: hardware/hs64/ostim.md + - name: GPO Trigger + href: hardware/hs64/gpo-trigger.md + - name: Stimulator Data + href: hardware/hs64/stimulator-data.md - name: Memory Monitor href: hardware/hs64/memory-monitor.md - href: hardware/hs64/load-data.md diff --git a/workflows/hardware/hs64/estim.bonsai b/workflows/hardware/hs64/estim.bonsai index a7c65271..e4671da1 100644 --- a/workflows/hardware/hs64/estim.bonsai +++ b/workflows/hardware/hs64/estim.bonsai @@ -22,22 +22,27 @@ + + + + + Source1 + + + + + + + + + + + 0 + + Headstage64/Headstage64ElectricalStimulator - true - true - 0 - 100 - 0 - -100 - 200 - 0 - 200 - 400 - 0 - 5 - 1 @@ -46,6 +51,8 @@ + + \ No newline at end of file diff --git a/workflows/hardware/hs64/gpo-trigger.bonsai b/workflows/hardware/hs64/gpo-trigger.bonsai new file mode 100644 index 00000000..13e7671f --- /dev/null +++ b/workflows/hardware/hs64/gpo-trigger.bonsai @@ -0,0 +1,52 @@ + + + + + + + BreakoutBoard/DigitalIO + + + + Buttons + + + + Square + + + + + + + + + + Source1 + + + + + + + + + + + Headstage64/Headstage64PortController + + + + + + + + + + + + \ No newline at end of file diff --git a/workflows/hardware/hs64/hs64.bonsai b/workflows/hardware/hs64/hs64.bonsai index 10d0b18c..e70b0d45 100644 --- a/workflows/hardware/hs64/hs64.bonsai +++ b/workflows/hardware/hs64/hs64.bonsai @@ -87,7 +87,7 @@ Headstage64/Rhd2164 256 true - Off + Dsp146mHz Low100mHz High10000Hz @@ -104,11 +104,39 @@ Headstage64/Headstage64ElectricalStimulator 259 + false + false + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 Headstage64/Headstage64OpticalStimulator 260 + false + false + false + 5.822 + 0 + 0 + 0.001 + 0.01 + 1 + 0 + 1 + + Headstage64/PersistentHeartbeat + 261 + 10 + PortA @@ -145,7 +173,7 @@ false false FileCount - false + true Timestamp,Value.Clock,Value.StatusCode @@ -170,7 +198,7 @@ - rhd2164-amplifier_.raw + rhd2164-ephys_.raw FileCount false ColumnMajor @@ -203,11 +231,71 @@ - ts4231_.csv + uncalibrated_ts4231_.csv + false + false + FileCount + true + Clock,Position + + + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + NaN + NaN + NaN + 1 + + NaN + NaN + NaN + + + + + + + calibrated-ts4231_.csv false false FileCount - false + true Clock,Position @@ -223,7 +311,7 @@ false false FileCount - false + true Clock,EulerAngle,Quaternion,Acceleration,Gravity,Temperature @@ -252,22 +340,27 @@ + + + + + Source1 + + + + + + + + + + + 0 + + Headstage64/Headstage64ElectricalStimulator - true - true - 0 - 100 - 0 - -100 - 200 - 0 - 200 - 400 - 0 - 5 - 1 @@ -278,21 +371,81 @@ + + + + + Source1 + + + + + + + + + + + 0 + + Headstage64/Headstage64OpticalStimulator - true - 0 - 100 - 50 - 50 - 10 - 50 - 20 - 0 - 1 + + + Square + + + + + + + + + + Source1 + + + + + + + + + + + Headstage64/Headstage64PortController + + + + + Headstage64/Headstage64OpticalStimulator + + + + ostim_.csv + false + false + FileCount + true + + + + + Headstage64/Headstage64ElectricalStimulator + + + + estim_.csv + false + false + FileCount + true + + BreakoutBoard/MemoryMonitor @@ -326,9 +479,22 @@ + + + - + + + + + + + + + + + \ No newline at end of file diff --git a/workflows/hardware/hs64/load-hs64.py b/workflows/hardware/hs64/load-hs64.py index 1eeff4df..5b020e8a 100644 --- a/workflows/hardware/hs64/load-hs64.py +++ b/workflows/hardware/hs64/load-hs64.py @@ -1,15 +1,16 @@ # Import necessary packages -import os import numpy as np import matplotlib.pyplot as plt +from matplotlib.lines import Line2D +from pathlib import Path #%% Set parameters for loading data -suffix = 0 # Change to match filenames' suffix -data_directory = 'C:/Users/open-ephys/Documents/data/hs64' # Change to match files' directory -plot_num_channels = 10 # Number of channels to plot -start_t = 3.0 # Plot start time (seconds) -dur = 2.0 # Plot time duration (seconds) +suffix = 0 # Change to match filenames' suffix +data_directory = Path('C:/Users/open-ephys/Documents/data/hs64') # Change to match files' directory +plot_num_channels = 10 # Number of channels to plot +start_t = 3.0 # Plot start time (seconds) +dur = 2.0 # Plot time duration (seconds) # RHD2164 constants ephys_uV_multiplier = 0.195 @@ -21,7 +22,7 @@ dt = {'names': ('time', 'acq_clk_hz', 'block_read_sz', 'block_write_sz'), 'formats': ('datetime64[us]', 'u4', 'u4', 'u4')} -meta = np.genfromtxt(os.path.join(data_directory, f'start-time_{suffix}.csv'), delimiter=',', dtype=dt, skip_header=1) +meta = np.genfromtxt(data_directory / f'start-time_{suffix}.csv', delimiter=',', dtype=dt, skip_header=1) print(f'Recording was started at {meta["time"]} GMT') print(f'Acquisition clock rate was {meta["acq_clk_hz"] / 1e6 } MHz') @@ -30,23 +31,40 @@ rhd2164 = {} # Load RHD2164 clock data and convert clock cycles to seconds -rhd2164['time'] = np.fromfile(os.path.join(data_directory, f'rhd2164-clock_{suffix}.raw'), dtype=np.uint64) / meta['acq_clk_hz'] +rhd2164['time'] = np.fromfile(data_directory / f'rhd2164-clock_{suffix}.raw', dtype=np.uint64) / meta['acq_clk_hz'] # Load and scale RHD2164 ephys data -ephys = np.reshape(np.fromfile(os.path.join(data_directory, f'rhd2164-ephys_{suffix}.raw'), dtype=np.uint16), (-1, num_channels)) +ephys = np.reshape(np.fromfile(data_directory / f'rhd2164-ephys_{suffix}.raw', dtype=np.uint16), (-1, num_channels)) rhd2164['ephys_uV'] = (ephys.astype(np.float32) - offset) * ephys_uV_multiplier # Load and scale RHD2164 aux data -aux = np.reshape(np.fromfile(os.path.join(data_directory, f'rhd2164-aux_{suffix}.raw'), dtype=np.uint16), (-1, 3)) +aux = np.reshape(np.fromfile(data_directory / f'rhd2164-aux_{suffix}.raw', dtype=np.uint16), (-1, 3)) rhd2164['aux_uV'] = (aux.astype(np.float32) - offset) * aux_uV_multiplier rhd2164_time_mask = np.bitwise_and(rhd2164['time'] >= start_t, rhd2164['time'] < start_t + dur) +#%% Load stimulator data + +dt = {'names': ('clock', 'hub_clock', 'origin', 'delay', 'rest_current', + 'phase_one_current', 'phase_two_current', 'phase_one_duration', 'inter_phase_interval', 'phase_two_duration', 'inter_pulse_interval', 'pulses_per_burst', 'inter_burst_interval', 'bursts_per_train'), + 'formats': ('u8', 'u8', 'B', 'u4', 'f8', + 'f8', 'f8', 'u4', 'u4', 'u4', + 'u4', 'u4', 'u4', 'u4')} +estim = np.genfromtxt(data_directory / f'estim_{suffix}.csv', delimiter=',', dtype=dt, skip_header=1) + +dt = {'names': ('clock', 'hub_clock', 'origin', 'delay', 'channel_one_current', + 'channel_two_current', 'pulse_duration', 'pulse_period', 'pulses_per_burst', 'inter_burst_interval', + 'bursts_per_train'), + 'formats': ('u8', 'u8', 'B', 'u4', 'f8', + 'f8', 'f8', 'f8', 'u4', 'f8', + 'u4')} +ostim = np.genfromtxt(data_directory / f'ostim_{suffix}.csv', delimiter=',', dtype=dt, skip_header=1) + #%% Load BNO055 data dt = {'names': ('clock', 'euler', 'quat', 'is_quat_id', 'accel', 'grav', 'temp'), 'formats': ('u8', '(1,3)f8', '(1,4)f8', '?', '(1,3)f8', '(1,3)f8', 'f8')} -bno055 = np.genfromtxt(os.path.join(data_directory, f'bno055_{suffix}.csv'), delimiter=',', dtype=dt) +bno055 = np.genfromtxt(data_directory / f'bno055_{suffix}.csv', delimiter=',', dtype=dt, skip_header=1) # Convert clock cycles to seconds bno055_time = bno055['clock'] / meta['acq_clk_hz'] @@ -58,7 +76,7 @@ # Load TS4231 data dt = {'names': ('clock', 'position'), 'formats': ('u8', '(1,3)f8')} -ts4231 = np.genfromtxt(os.path.join(data_directory, f'ts4231_{suffix}.csv'), delimiter=',', dtype=dt) +ts4231 = np.genfromtxt(data_directory / f'calibrated-ts4231_{suffix}.csv', delimiter=',', dtype=dt, skip_header=1) # Convert clock cycles to seconds ts4231_time = ts4231['clock'] / meta['acq_clk_hz'] @@ -76,6 +94,23 @@ plt.ylabel('Voltage (µV)') plt.title('RHD2164 Ephys Data') +# Plot stimulus delivery +ax = plt.gca() + +for stim_clock in estim['clock']: + stim_sec = stim_clock / meta['acq_clk_hz'] + if stim_sec > start_t and stim_sec < start_t + dur: + ax.axvline(x=stim_sec, color='k', alpha=0.5, ls='-') + +for stim_clock in ostim['clock']: + stim_sec = stim_clock / meta['acq_clk_hz'] + if stim_sec > start_t and stim_sec < start_t + dur: + ax.axvline(x=stim_sec, color='k', alpha=0.5, ls='--') + +ax.legend([Line2D([0], [0], color='k', alpha=0.5, ls='-'), + Line2D([0], [0], color='k', alpha=0.5, ls='--')], + ['estim', 'ostim']) + # Plot RHD2164 aux data plt.subplot(712) plt.plot(rhd2164['time'][rhd2164_time_mask], rhd2164['aux_uV'][rhd2164_time_mask]) diff --git a/workflows/hardware/hs64/ostim.bonsai b/workflows/hardware/hs64/ostim.bonsai index cf741bfc..578f1e3e 100644 --- a/workflows/hardware/hs64/ostim.bonsai +++ b/workflows/hardware/hs64/ostim.bonsai @@ -22,19 +22,27 @@ + + + + + Source1 + + + + + + + + + + + 0 + + Headstage64/Headstage64OpticalStimulator - true - 0 - 100 - 50 - 50 - 10 - 50 - 20 - 0 - 1 @@ -43,6 +51,8 @@ + + \ No newline at end of file diff --git a/workflows/hardware/hs64/stimulator-data.bonsai b/workflows/hardware/hs64/stimulator-data.bonsai new file mode 100644 index 00000000..cda3b3b8 --- /dev/null +++ b/workflows/hardware/hs64/stimulator-data.bonsai @@ -0,0 +1,41 @@ + + + + + + + Headstage64/Headstage64OpticalStimulator + + + + ostim-data_.csv + false + false + FileCount + true + + + + + Headstage64/Headstage64ElectricalStimulator + + + + estim-data_.csv + false + false + FileCount + true + + + + + + + + + \ No newline at end of file diff --git a/workflows/operators/Headstage64ElectricalStimulatorData.bonsai b/workflows/operators/Headstage64ElectricalStimulatorData.bonsai new file mode 100644 index 00000000..4171fc31 --- /dev/null +++ b/workflows/operators/Headstage64ElectricalStimulatorData.bonsai @@ -0,0 +1,16 @@ + + + + + + + Headstage64/Headstage64ElectricalStimulator + + + + + + \ No newline at end of file diff --git a/workflows/operators/Headstage64ElectricalStimulatorTrigger.bonsai b/workflows/operators/Headstage64ElectricalStimulatorTrigger.bonsai index 445adabe..e4671da1 100644 --- a/workflows/operators/Headstage64ElectricalStimulatorTrigger.bonsai +++ b/workflows/operators/Headstage64ElectricalStimulatorTrigger.bonsai @@ -2,6 +2,7 @@ @@ -18,22 +19,30 @@ Triangle + + + + + + + + Source1 + + + + + + + + + + + 0 + + Headstage64/Headstage64ElectricalStimulator - true - false - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 @@ -41,6 +50,9 @@ + + + \ No newline at end of file diff --git a/workflows/operators/Headstage64GpoTrigger.bonsai b/workflows/operators/Headstage64GpoTrigger.bonsai new file mode 100644 index 00000000..13e7671f --- /dev/null +++ b/workflows/operators/Headstage64GpoTrigger.bonsai @@ -0,0 +1,52 @@ + + + + + + + BreakoutBoard/DigitalIO + + + + Buttons + + + + Square + + + + + + + + + + Source1 + + + + + + + + + + + Headstage64/Headstage64PortController + + + + + + + + + + + + \ No newline at end of file diff --git a/workflows/operators/Headstage64OpticalStimulatorData.bonsai b/workflows/operators/Headstage64OpticalStimulatorData.bonsai new file mode 100644 index 00000000..3892d5b4 --- /dev/null +++ b/workflows/operators/Headstage64OpticalStimulatorData.bonsai @@ -0,0 +1,16 @@ + + + + + + + Headstage64/Headstage64OpticalStimulator + + + + + + \ No newline at end of file diff --git a/workflows/operators/Headstage64OpticalStimulatorTrigger.bonsai b/workflows/operators/Headstage64OpticalStimulatorTrigger.bonsai index 71f2fe8b..578f1e3e 100644 --- a/workflows/operators/Headstage64OpticalStimulatorTrigger.bonsai +++ b/workflows/operators/Headstage64OpticalStimulatorTrigger.bonsai @@ -2,6 +2,7 @@ @@ -18,19 +19,30 @@ Circle + + + + + + + + Source1 + + + + + + + + + + + 0 + + Headstage64/Headstage64OpticalStimulator - true - 0 - 100 - 100 - 0 - 5 - 50 - 20 - 0 - 1 @@ -38,6 +50,9 @@ + + + \ No newline at end of file From 000c997a1c0f2992d0230f1ca6ba826010571bb6 Mon Sep 17 00:00:00 2001 From: cjsha Date: Thu, 30 Oct 2025 16:04:36 -0400 Subject: [PATCH 2/4] Trigger GPO key using X key instead of square key - Add note GPO trigger on example workflow page --- articles/hardware/hs64/gpo-trigger.md | 2 +- articles/hardware/hs64/workflow.md | 1 + workflows/hardware/hs64/hs64.bonsai | 7 +++---- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/articles/hardware/hs64/gpo-trigger.md b/articles/hardware/hs64/gpo-trigger.md index 45ed07bd..5dc55de9 100644 --- a/articles/hardware/hs64/gpo-trigger.md +++ b/articles/hardware/hs64/gpo-trigger.md @@ -5,7 +5,7 @@ title: Headstage 64 GPO Trigger The following excerpt from the Headstage 64 [example workflow](xref:hs64_workflow) demonstrates triggering a stimulus following a -press of the □ key on the breakout board. The GPO trigger uses a pin on the +press of the X key on the breakout board. The GPO trigger uses a pin on the headstage to trigger stimulus more instantaneously than other trigger methods that write to a register on the hardware which takes more time. However, this trigger operator does not provide stimulus feedback as discussed in diff --git a/articles/hardware/hs64/workflow.md b/articles/hardware/hs64/workflow.md index e4b38d06..5974745a 100644 --- a/articles/hardware/hs64/workflow.md +++ b/articles/hardware/hs64/workflow.md @@ -10,6 +10,7 @@ The example workflow below can by copy/pasted into the Bonsai editor using the c - Automatically commutates the tether if there is a proper commutator connection. - Applies electrical stimulation triggered by pressing the breakout board's △ key. - Applies optical stimulation triggered by pressing the breakout board's ◯ key. +- Applies both stimulation types with a lower latency trigger mechanism by pressing the breakout board's X key. - Monitors memory usage data. ::: workflow diff --git a/workflows/hardware/hs64/hs64.bonsai b/workflows/hardware/hs64/hs64.bonsai index e70b0d45..128666ef 100644 --- a/workflows/hardware/hs64/hs64.bonsai +++ b/workflows/hardware/hs64/hs64.bonsai @@ -396,7 +396,7 @@ - Square + X @@ -471,12 +471,11 @@ + - + - - From 5e8047de3bbc9a3d3a6a88b32164592a49a932c8 Mon Sep 17 00:00:00 2001 From: cjsha Date: Thu, 30 Oct 2025 17:21:58 -0400 Subject: [PATCH 3/4] Address bparks feedback --- articles/hardware/breakout/digital-inputs.md | 15 ++++++----- articles/hardware/hs64/estim.md | 10 ++----- articles/hardware/hs64/gpo-trigger.md | 28 ++++++++------------ articles/hardware/hs64/ostim.md | 8 +----- articles/hardware/hs64/workflow.md | 4 ++- includes/breakout-digital-io.md | 8 ++++++ 6 files changed, 33 insertions(+), 40 deletions(-) create mode 100644 includes/breakout-digital-io.md diff --git a/articles/hardware/breakout/digital-inputs.md b/articles/hardware/breakout/digital-inputs.md index 8d30c0af..815afb20 100644 --- a/articles/hardware/breakout/digital-inputs.md +++ b/articles/hardware/breakout/digital-inputs.md @@ -14,15 +14,16 @@ functionality by responding to button presses and saves digital inputs data. ::: The operator generates a sequence of -[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). In this workflow, digital inputs -are configured to be asynchronous. This means that although the digital inputs -are sampled in hardware at 4 Mhz, data frames are only emitted when the port -status changes (i.e., when a pin, button, or switch is toggled). Digital inputs -can also be +[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). In this +workflow, digital inputs are configured to be asynchronous. This means that +although the digital inputs are sampled in hardware at 4 Mhz, data frames are +only emitted when the port status changes (i.e., when a pin, button, or switch +is toggled) when the `SampleRate` is left blank such as is done in this example +workflow. Digital inputs can also be [configured](xref:OpenEphys.Onix1.ConfigureBreakoutBoard#OpenEphys_Onix1_ConfigureBreakoutBoard_DigitalIO) to be sampled at regular intervals. The digital input ports on the Breakout -Board use 3.3V logic levels but are also 5V tolerant. In the Breakout -Board example workflow, the `DigitalInput`'s `DeviceName` property is set to +Board use 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. diff --git a/articles/hardware/hs64/estim.md b/articles/hardware/hs64/estim.md index 3085aa34..79d1de94 100644 --- a/articles/hardware/hs64/estim.md +++ b/articles/hardware/hs64/estim.md @@ -11,13 +11,7 @@ a train of pulses following a press of the △ key on the breakout board. ![/workflows/hardware/hs64/estim.bonsai workflow](../../../workflows/hardware/hs64/estim.bonsai) ::: -The operator generates a sequence of -[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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 -Headstage 64 example workflow, the `DigitalInput`'s `DeviceName` property is -set to "BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to -the corresponding configuration operator. +[!INCLUDE [](<../../../includes/breakout-digital-io.md>)] is selected from the `DigitalInputDataFrame`. It is an enumerator with values that correspond to bit @@ -33,7 +27,7 @@ In this case, `Condition` has no internal logic (which can be inspected by selecting the node and pressing Ctrl+Enter), so it uses the value of the Boolean in its input sequence to decide whether or not to pass a value. The operator emits a value determined by -its `Value` property whenever it receives an item in its input sequence. T This +its `Value` property whenever it receives an item in its input sequence. This value is used to determine the delay between triggering the stimulus and delivery of the stimulus. When `Double`'s `Value` property is set to zero, there is no such delay. diff --git a/articles/hardware/hs64/gpo-trigger.md b/articles/hardware/hs64/gpo-trigger.md index 5dc55de9..d1950819 100644 --- a/articles/hardware/hs64/gpo-trigger.md +++ b/articles/hardware/hs64/gpo-trigger.md @@ -5,28 +5,22 @@ title: Headstage 64 GPO Trigger The following excerpt from the Headstage 64 [example workflow](xref:hs64_workflow) demonstrates triggering a stimulus following a -press of the X key on the breakout board. The GPO trigger uses a pin on the -headstage to trigger stimulus more instantaneously than other trigger methods -that write to a register on the hardware which takes more time. However, this -trigger operator does not provide stimulus feedback as discussed in - nor is it capable of distinguishing between applying -optical or electrical stimulus. If you want to use the GPO trigger to only -trigger electrical stimulus, the electrical stimulator should be the only -stimulator device armed on the headstage. If you want to use the GPO trigger to -only trigger optical stimulus, the optical stimulator should be the only -stimulator device armed on the headstage. +press of the X key on the breakout board. The GPO trigger toggles a pin on the +headstage to trigger stimulus more instantaneously than writing to a register +which is how other Headstage 64 operators trigger stimulus. + +> [!NOTE] +> If you want to use the GPO trigger to only trigger electrical stimulus, the +> electrical stimulator should be the only stimulator device armed on the +> headstage. If you want to use the GPO trigger to only trigger optical +> stimulus, the optical stimulator should be the only stimulator device armed on +> the headstage. ::: workflow ![/workflows/hardware/hs64/gpo-trigger.bonsai workflow](../../../workflows/hardware/hs64/gpo-trigger.bonsai) ::: -The operator generates a sequence of -[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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. +[!INCLUDE [](<../../../includes/breakout-digital-io.md>)] is selected from the `DigitalInputDataFrame`. It is an enumerator with values that correspond to bit diff --git a/articles/hardware/hs64/ostim.md b/articles/hardware/hs64/ostim.md index d4b5caa1..b38e2c6c 100644 --- a/articles/hardware/hs64/ostim.md +++ b/articles/hardware/hs64/ostim.md @@ -11,13 +11,7 @@ train of pulses following a press of the ◯ key on the breakout board. ![/workflows/hardware/hs64/ostim.bonsai workflow](../../../workflows/hardware/hs64/ostim.bonsai) ::: -The operator generates a sequence of -[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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 -Headstage 64 example workflow, the `DigitalInput`'s `DeviceName` property is -set to "BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to -the corresponding configuration operator. +[!INCLUDE [](<../../../includes/breakout-digital-io.md>)] is selected from the `DigitalInputDataFrame`. It is an enumerator with values that correspond to bit diff --git a/articles/hardware/hs64/workflow.md b/articles/hardware/hs64/workflow.md index 5974745a..2f9c3e61 100644 --- a/articles/hardware/hs64/workflow.md +++ b/articles/hardware/hs64/workflow.md @@ -10,7 +10,9 @@ The example workflow below can by copy/pasted into the Bonsai editor using the c - Automatically commutates the tether if there is a proper commutator connection. - Applies electrical stimulation triggered by pressing the breakout board's △ key. - Applies optical stimulation triggered by pressing the breakout board's ◯ key. -- Applies both stimulation types with a lower latency trigger mechanism by pressing the breakout board's X key. +- Applies either electrical or optical stimulation (depending on which stimulators + are enabled and armed) using a lower latency trigger mechanism by pressing the breakout + board's X key. - Monitors memory usage data. ::: workflow diff --git a/includes/breakout-digital-io.md b/includes/breakout-digital-io.md new file mode 100644 index 00000000..28c0f1e1 --- /dev/null +++ b/includes/breakout-digital-io.md @@ -0,0 +1,8 @@ +The operator generates a sequence of +[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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) when +`DigitalInput`'s `SampleRate` property is left blank such as is done in the +example workflow. The `DigitalInput`'s `DeviceName` property is set to +"BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to the +corresponding configuration operator. \ No newline at end of file From 79d478254800bf252325f46194c4db3aedd867c4 Mon Sep 17 00:00:00 2001 From: cjsha Date: Sun, 2 Nov 2025 19:34:02 -0500 Subject: [PATCH 4/4] bparks feedback, second pass Also: - Add dotnet xrefmap in docfx.json so I can use ``. - Remove include for now, the long-term solution will be to add a template. - Remove `Condition` operator from Headstage64GpoTrigger branch This node's unnecessary bc only True values trigger stimulus anyway. --- articles/hardware/hs64/estim.md | 47 +++++++++----- articles/hardware/hs64/gpo-trigger.md | 43 +++++++------ articles/hardware/hs64/ostim.md | 46 +++++++++----- docfx.json | 3 +- includes/breakout-digital-io.md | 8 --- workflows/hardware/hs64/gpo-trigger.bonsai | 26 ++------ workflows/hardware/hs64/hs64.bonsai | 71 ++++++++-------------- 7 files changed, 118 insertions(+), 126 deletions(-) delete mode 100644 includes/breakout-digital-io.md diff --git a/articles/hardware/hs64/estim.md b/articles/hardware/hs64/estim.md index 79d1de94..a018c046 100644 --- a/articles/hardware/hs64/estim.md +++ b/articles/hardware/hs64/estim.md @@ -7,11 +7,26 @@ The following excerpt from the Headstage 64 [example workflow](xref:hs64_workflow) demonstrates electrical stimulation by triggering a train of pulses following a press of the △ key on the breakout board. +> [!NOTE] +> Only one (electrical or optical) stimulator can armed at a time. If both +> stimulators are armed, the electrical stimulator takes precedence, e.g. +> the electrical stimulator stays armed and the optical stimulator is +> automatically disarmed by the headstage firmware. If you want to interleave +> optical stimulation and electrical stimulation, you must coordinate the +> stimulators to be dynamically armed and disarmed. + ::: workflow ![/workflows/hardware/hs64/estim.bonsai workflow](../../../workflows/hardware/hs64/estim.bonsai) ::: -[!INCLUDE [](<../../../includes/breakout-digital-io.md>)] +The operator generates a sequence of +[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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) when +`DigitalInput`'s `SampleRate` property is left blank such as is done in the +example workflow. The `DigitalInput`'s `DeviceName` property is set to +"BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to the +corresponding configuration operator. is selected from the `DigitalInputDataFrame`. It is an enumerator with values that correspond to bit @@ -20,19 +35,19 @@ positions of the breakout board's digital port. When this type is connected to a 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. The operator only -allows passes an item in its input sequence if it's different from the previous -item in the input sequence. The operator only -passes an item in its input sequence if `Condition`'s internal logic is "True". -In this case, `Condition` has no internal logic (which can be inspected by -selecting the node and pressing Ctrl+Enter), so it uses the value of -the Boolean in its input sequence to decide whether or not to pass a value. The - operator emits a value determined by -its `Value` property whenever it receives an item in its input sequence. This -value is used to determine the delay between triggering the stimulus and -delivery of the stimulus. When `Double`'s `Value` property is set to zero, there -is no such delay. +passes an item in its input sequence if it's different from the previous item in +the input sequence. The operator only passes an +item in its input sequence if `Condition`'s internal logic is "True". In this +case, `Condition` has no internal logic (which can be inspected by selecting the +node and pressing Ctrl+Enter), so it uses the value of the Boolean in +its input sequence to decide whether or not to pass through an item in its input +sequence to its output sequence. -When the 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. \ No newline at end of file +The +operator emits a determined by `Double`'s `Value` property +whenever it receives an item in its input sequence. Each double in the input +sequence received by + triggers an +electrical stimulus waveform. The value of the double determines the delay +between triggering the stimulus and delivery of the stimulus. When `Double`'s +`Value` property is set to zero, there is no delay. \ No newline at end of file diff --git a/articles/hardware/hs64/gpo-trigger.md b/articles/hardware/hs64/gpo-trigger.md index d1950819..f55116cf 100644 --- a/articles/hardware/hs64/gpo-trigger.md +++ b/articles/hardware/hs64/gpo-trigger.md @@ -6,21 +6,32 @@ title: Headstage 64 GPO Trigger The following excerpt from the Headstage 64 [example workflow](xref:hs64_workflow) demonstrates triggering a stimulus following a press of the X key on the breakout board. The GPO trigger toggles a pin on the -headstage to trigger stimulus more instantaneously than writing to a register -which is how other Headstage 64 operators trigger stimulus. +headstage to trigger stimulus which occurs more instantaneously than writing to +a register on the headstage which is how the + and + operators trigger +stimuli. > [!NOTE] -> If you want to use the GPO trigger to only trigger electrical stimulus, the -> electrical stimulator should be the only stimulator device armed on the -> headstage. If you want to use the GPO trigger to only trigger optical -> stimulus, the optical stimulator should be the only stimulator device armed on -> the headstage. +> Only one (electrical or optical) stimulator can armed at a time. If both +> stimulators are armed, the electrical stimulator takes precedence, e.g. +> the electrical stimulator stays armed and the optical stimulator is +> automatically disarmed by the headstage firmware. If you want to interleave +> optical stimulation and electrical stimulation, you must coordinate the +> stimulators to be dynamically armed and disarmed. ::: workflow ![/workflows/hardware/hs64/gpo-trigger.bonsai workflow](../../../workflows/hardware/hs64/gpo-trigger.bonsai) ::: -[!INCLUDE [](<../../../includes/breakout-digital-io.md>)] +The operator generates a sequence of +[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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) when +`DigitalInput`'s `SampleRate` property is left blank such as is done in the +example workflow. The `DigitalInput`'s `DeviceName` property is set to +"BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to the +corresponding configuration operator. is selected from the `DigitalInputDataFrame`. It is an enumerator with values that correspond to bit @@ -29,15 +40,7 @@ positions of the breakout board's digital port. When this type is connected to a property's dropdown menu. Because `HasFlags`'s `Value` is set to "Square", its output is "True" when the selected `BreakoutButtonState` bit field contains the "Square" flag. The operator only -allows passes an item in its input sequence if it's different from the previous -item in the input sequence. The operator only -passes an item in its input sequence if `Condition`'s internal logic -is "True". In this case, `Condition` has no internal logic (which can -be inspected by selecting the node and pressing Ctrl+Enter), so it -uses the value of the Boolean in its input sequence to decide whether or not to -pass a value. - -When the 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. \ No newline at end of file +passes an item in its input sequence if it's different from the previous item in +the input sequence. When the +operator receives a "True" value in its input sequence, a stimulus waveform is +triggered. \ No newline at end of file diff --git a/articles/hardware/hs64/ostim.md b/articles/hardware/hs64/ostim.md index b38e2c6c..ba14838d 100644 --- a/articles/hardware/hs64/ostim.md +++ b/articles/hardware/hs64/ostim.md @@ -7,11 +7,26 @@ The following excerpt from the Headstage64 [example workflow](xref:hs64_workflow) demonstrates optical stimulation by triggering a train of pulses following a press of the ◯ key on the breakout board. +> [!NOTE] +> Only one (electrical or optical) stimulator can armed at a time. If both +> stimulators are armed, the electrical stimulator takes precedence, e.g. +> the electrical stimulator stays armed and the optical stimulator is +> automatically disarmed by the headstage firmware. If you want to interleave +> optical stimulation and electrical stimulation, you must coordinate the +> stimulators to be dynamically armed and disarmed. + ::: workflow ![/workflows/hardware/hs64/ostim.bonsai workflow](../../../workflows/hardware/hs64/ostim.bonsai) ::: -[!INCLUDE [](<../../../includes/breakout-digital-io.md>)] +The operator generates a sequence of +[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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) when +`DigitalInput`'s `SampleRate` property is left blank such as is done in the +example workflow. The `DigitalInput`'s `DeviceName` property is set to +"BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to the +corresponding configuration operator. is selected from the `DigitalInputDataFrame`. It is an enumerator with values that correspond to bit @@ -20,19 +35,18 @@ positions of the breakout board's digital port. When this type is connected to a property's dropdown menu. Because `HasFlags`'s `Value` is set to "Circle", its output is "True" when the selected `BreakoutButtonState` bit field contains the "Circle" flag. The operator only -allows passes an item in its input sequence if it's different from the previous -item in the input sequence. The operator only -passes an item in its input sequence if `Condition`'s internal logic is "True". -In this case, `Condition` has no internal logic (which can be inspected by -selecting the node and pressing Ctrl+Enter), so it uses the value of -the Boolean in its input sequence to decide whether or not to pass a value. The - operator emits a value determined by -its `Value` property whenever it receives an item in its input sequence. This -value is used to determine the delay between triggering the stimulus and -delivery of the stimulus. When `Double`'s `Value` property is set to zero, there -is no such delay. +passes an item in its input sequence if it's different from the previous item in +the input sequence. The operator only passes an +item in its input sequence if `Condition`'s internal logic is "True". In this +case, `Condition` has no internal logic (which can be inspected by selecting the +node and pressing Ctrl+Enter), so it uses the value of the Boolean in +its input sequence to decide whether or not to pass through an item in its input +sequence to its output sequence. -When the operator -receives a "True" value in its input sequence, a stimulus waveform is triggered. -The waveform can be modified by editing the `Headstage64OpticalStimulatorTrig` -operator's properties. \ No newline at end of file +The +operator emits a determined by `Double`'s `Value` property +whenever it receives an item in its input sequence. Each double in the input +sequence received by +triggers an optical stimulus. The value of the double determines the delay +between triggering the stimulus and delivery of the stimulus. When `Double`'s +`Value` property is set to zero, there is no delay. \ No newline at end of file diff --git a/docfx.json b/docfx.json index 324e2771..06e8dbbd 100644 --- a/docfx.json +++ b/docfx.json @@ -57,7 +57,8 @@ "xref": [ "https://bonsai-rx.org/docs/xrefmap.yml", "https://horizongir.github.io/opencv.net/xrefmap.yml", - "https://horizongir.github.io/reactive/xrefmap.yml" + "https://horizongir.github.io/reactive/xrefmap.yml", + "https://learn.microsoft.com/en-us/dotnet/.xrefmap.json" ] }, "rules": { diff --git a/includes/breakout-digital-io.md b/includes/breakout-digital-io.md deleted file mode 100644 index 28c0f1e1..00000000 --- a/includes/breakout-digital-io.md +++ /dev/null @@ -1,8 +0,0 @@ -The operator generates a sequence of -[DigitalInputDataFrames](xref:OpenEphys.Onix1.DigitalInputDataFrame). 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) when -`DigitalInput`'s `SampleRate` property is left blank such as is done in the -example workflow. The `DigitalInput`'s `DeviceName` property is set to -"BreakoutBoard/DigitalInput". This links the `DigitalInput` operator to the -corresponding configuration operator. \ No newline at end of file diff --git a/workflows/hardware/hs64/gpo-trigger.bonsai b/workflows/hardware/hs64/gpo-trigger.bonsai index 13e7671f..7767cc12 100644 --- a/workflows/hardware/hs64/gpo-trigger.bonsai +++ b/workflows/hardware/hs64/gpo-trigger.bonsai @@ -1,43 +1,30 @@  - - BreakoutBoard/DigitalIO + + BreakoutBoard/DigitalIO Buttons - + Square - - - - - Source1 - - - - - - - - - - Headstage64/Headstage64PortController + + Headstage64/Headstage64PortController @@ -46,7 +33,6 @@ - \ No newline at end of file diff --git a/workflows/hardware/hs64/hs64.bonsai b/workflows/hardware/hs64/hs64.bonsai index 128666ef..056a4687 100644 --- a/workflows/hardware/hs64/hs64.bonsai +++ b/workflows/hardware/hs64/hs64.bonsai @@ -104,39 +104,11 @@ Headstage64/Headstage64ElectricalStimulator 259 - false - false - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 Headstage64/Headstage64OpticalStimulator 260 - false - false - false - 5.822 - 0 - 0 - 0.001 - 0.01 - 1 - 0 - 1 - - Headstage64/PersistentHeartbeat - 261 - 10 - PortA @@ -361,6 +333,19 @@ Headstage64/Headstage64ElectricalStimulator + true + false + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 @@ -392,6 +377,16 @@ Headstage64/Headstage64OpticalStimulator + true + 0 + 100 + 100 + 0 + 5 + 50 + 20 + 0 + 1 @@ -402,19 +397,6 @@ - - - - - Source1 - - - - - - - - Headstage64/Headstage64PortController @@ -490,10 +472,9 @@ - - - - + + + \ No newline at end of file