Skip to content

Commit 59f9b5e

Browse files
committed
Apply suggestions from @bruno-f-cruz review
- Change Equal for response condition to HasFlag - Change plot from boxplot to histogram - Add prerequisite for bonsai.numerics
1 parent 1a7f700 commit 59f9b5e

5 files changed

Lines changed: 15 additions & 10 deletions

tutorials/hobgoblin-reaction.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ stateDiagram-v2
1919

2020
The task begins with an inter-trial interval (`ITI`), followed by stimulus presentation (`ON`). After stimulus onset, advancement to the next state can happen only when the subject presses the button (`success`) or a timeout elapses (`miss`). Depending on which event is triggered first, the task advances either to the `Reward` state, or `Fail` state. At the end, the task goes back to the beginning of the ITI state for the next trial.
2121

22+
## Prerequisites
23+
24+
- Install the [`Bonsai.Numerics`](https://bonsai-rx.org/numerics/) package from the [Bonsai package manager](https://bonsai-rx.org/docs/articles/packages.html).
25+
2226
### Exercise 1: Generating a fixed-interval stimulus
2327

2428
In this first exercise, you will assemble the basic hardware and software components required to implement the reaction time task. Connect the LED to digital output channel `GP15` on the `Hobgoblin`. Connect the push button to digital input channel `GP2` on the `Hobgoblin`.
@@ -96,7 +100,7 @@ digital_input_state = device.DigitalInputState.read()
96100
print(digital_output_set.head())
97101
print(digital_input_state.head())
98102

99-
# Discard_unused_channels
103+
# Discard unused channels
100104
digital_output_set = digital_output_set["GP15"]
101105
digital_input_state = digital_input_state["GP2"]
102106

@@ -119,7 +123,7 @@ hit_percentage = num_valid_responses / num_total_trials * 100
119123
print(f"There were {num_valid_responses} valid responses out of {num_total_trials} trials, giving a hit rate of {hit_percentage}%")
120124

121125
# Plot valid response times
122-
pd.Series(valid_response_times).plot(kind="box", ylim=(0,1))
126+
pd.Series(valid_response_times).plot(kind="hist")
123127
```
124128

125129
### Exercise 4: Driving state transitions with external behaviour events
@@ -155,13 +159,13 @@ In order to translate our simple reaction time task in the previous exercises in
155159
- Insert a [`SubscribeSubject`] operator. Configure the `Name` property to `Hobgoblin Events`.
156160
- Insert a [`Parse`] operator after `Hobgoblin Events`. Configure the `Register` property to [`DigitalInputState`].
157161
- Insert a [`Condition`] operator after the [`Parse`] operator.
158-
- Double-click on the [`Condition`] operator and add an [`Equal`] operator after the `Source1` operator. Set the `Value` property to `GP2`.
162+
- Double-click on the [`Condition`] operator and add a [`HasFlag`] operator after the `Source1` operator. Set the `Value` property to `GP2`.
159163
- Insert a [`Take`] operator and set its `Count` property to 1.
160164
- Connect the [`Take`] operator to `WorkflowOutput`.
161165
- Run the workflow a couple of times and validate the state machine is responding to the button press.
162166

163167
> [!Note]
164-
> The [`Condition`] operator allows you to specify arbitrary rules for accepting or rejecting inputs. The `WorkflowOutput` node always needs to be specified with a `bool` input, the result of whether the input is accepted (`True`) or rejected (`False`). Only inputs which pass the filter specified inside the [`Condition`] are allowed to proceed. Using an [`Equal`] operator here allows us to filter only messages from that pin and also has the beneficial side effect of only detecting a button press (when the value changes fron `None` > `GP2`) instead of a button release (`GP2`>`None`).
168+
> The [`Condition`] operator allows you to specify arbitrary rules for accepting or rejecting inputs. The `WorkflowOutput` node always needs to be specified with a `bool` input, the result of whether the input is accepted (`True`) or rejected (`False`). Only inputs which pass the filter specified inside the [`Condition`] are allowed to proceed. Using a [`HasFlag`] operator here allows us to filter only messages from that pin and also has the beneficial side effect of only detecting a button press (when the value changes fron `None` > `GP2`) instead of a button release (`GP2`>`None`).
165169
166170
### Exercise 5: Timeout and choice
167171

@@ -207,7 +211,7 @@ _Why did we need to specify something for the `Miss` condition?_
207211
_Why did we not need to specify anything for the `Success` condition?_
208212

209213
> [!Note]
210-
> The [`Condition`] operator is often used to represent choice points in the task. Other than [`Equal`], you can use operators such as [`NotEqual`], [`GreaterThan`], etc for specifying such tests.
214+
> The [`Condition`] operator is often used to represent choice points in the task. You can use operators such as [`Equal`], [`NotEqual`], [`GreaterThan`], etc for specifying such tests.
211215
212216
Inside the `Reward` and `Fail` node you can specify your own logic to signal the state of the trial.
213217
For example, to make the LED blink three times in rapid succession for the `Reward` node:
@@ -253,7 +257,7 @@ stateDiagram-v2
253257
NoGo --> CorrectReject
254258
```
255259

256-
- Trials should be sampled from a uniform distribution using the `Numerics` package (install from `Tools` > `Manage Packages`).
260+
- Trials should be sampled from a uniform distribution using the `Bonsai.Numerics` package.
257261
- Response events should be based on a button press, and reject events on a timeout.
258262
- Make sure to implement different visual or auditory feedback for either the cue or reward/failure states.
259263

@@ -300,6 +304,7 @@ stateDiagram-v2
300304
[`Equal`]: xref:Bonsai.Expressions.EqualBuilder
301305
[`GreaterThan`]: xref:Bonsai.Expressions.GreaterThanBuilder
302306
[`HarpMessage`]: xref:Bonsai.Harp.HarpMessage
307+
[`HasFlag`]: xref:Bonsai.Expressions.HasFlagBuilder
303308
[`Last`]: xref:Bonsai.Reactive.Last
304309
[`Merge`]: xref:Bonsai.Reactive.Merge
305310
[`MulticastSubject`]: xref:Bonsai.Expressions.MulticastSubject

workflows/hobgoblin-reactiontime-stimulus-response-input.bonsai

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<Expression xsi:type="WorkflowInput">
2020
<Name>Source1</Name>
2121
</Expression>
22-
<Expression xsi:type="Equal">
22+
<Expression xsi:type="HasFlag">
2323
<Operand xsi:type="WorkflowProperty" TypeArguments="p1:DigitalInputs">
2424
<Value>GP2</Value>
2525
</Operand>

workflows/hobgoblin-reactiontime-stimulus-response-outcomes.bonsai

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<Expression xsi:type="WorkflowInput">
5555
<Name>Source1</Name>
5656
</Expression>
57-
<Expression xsi:type="Equal">
57+
<Expression xsi:type="HasFlag">
5858
<Operand xsi:type="WorkflowProperty" TypeArguments="p1:DigitalInputs">
5959
<Value>GP2</Value>
6060
</Operand>

workflows/hobgoblin-reactiontime-stimulus-response-timeout.bonsai

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<Expression xsi:type="WorkflowInput">
2020
<Name>Source1</Name>
2121
</Expression>
22-
<Expression xsi:type="Equal">
22+
<Expression xsi:type="HasFlag">
2323
<Operand xsi:type="WorkflowProperty" TypeArguments="p1:DigitalInputs">
2424
<Value>GP2</Value>
2525
</Operand>

workflows/hobgoblin-reactiontime-stimulus-response.bonsai

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
<Expression xsi:type="WorkflowInput">
5555
<Name>Source1</Name>
5656
</Expression>
57-
<Expression xsi:type="Equal">
57+
<Expression xsi:type="HasFlag">
5858
<Operand xsi:type="WorkflowProperty" TypeArguments="p1:DigitalInputs">
5959
<Value>GP2</Value>
6060
</Operand>

0 commit comments

Comments
 (0)