Alternating between ROIs: task rules and changing the values of multiple integers for branching

241 views
Skip to first unread message

margot.t...@ucl.ac.uk

unread,
Feb 12, 2018, 12:42:30 PM2/12/18
to Bonsai Users
Hello,

We are trying to get a rat to run back and forth on a linear track to get rewards. We want to force the animal to travel from one end to the other, and avoid it learning going just outside the ROI and back to get a reward faster.

For example, after the animal has been rewarded in A, only entering the opposite ROI B should trigger a reward. Rewards will be dispensed when TTL pulses are sent to the arduino on different pins.

To this end, we have tried to create a bonsai workflow with two ROIs: one at each end of the linear track. Entering the ROI should trigger 1) a change in a dynamic variable (e.g. SideA and SideB) from 0 to 1 to keep track of the visited ROI and 2) a TTL pulse to an arduino.

We want this change of variable from 0 to 1 to prevent a TTL activation in the previously visited ROI by "blocking" that workflow branch.

Example:
Variables SideA and SideB are initialised to 0 (neither branch visited yet).
The animal goes to ROI A, and gets a reward. SideA= 1 and SideB= 0
Program waits until animal enters ROI B, entering ROI A should not trigger anything.
Animal goes to ROI B, gets a reward, updating to SideA= 0 and SideB= 1.
etc...

We are stuck at trying to update the integer values after each ROI activation and making it loop back around. Maybe there is a more efficient and logical way of doing this ?

We have looked at previously answered question on slightly different tasks, but condition expressions are quite difficult to understand for beginners (and to write!).

Also, Bonsai crashes when we attempt to run our code.

Thank you very much in advance for your help !
 






BackandForth_12022018_v2.bonsai
Auto Generated Inline Image 1

Gonçalo Lopes

unread,
Feb 12, 2018, 8:24:11 PM2/12/18
to margot.t...@ucl.ac.uk, Bonsai Users
Hi Margot and welcome to the forums!

First, a couple of general hints:
 - You can use the Equal operator instead of a PythonTransform to test whether an input is equal to a particular value (faster and more readable).
 - You can use the Int operator (and others) to create fixed values of a particular type (again, this will be both faster and more readable).

Regarding your workflow, it looks mostly all right, but you have inadvertently created an infinite loop. Remember that Bonsai has no concept of "loops" and "states" unless you make them. Execution follows the data flow, usually immediately. In this case what happened is that when you write a value to "sideA", for example, the corresponding SubscribeSubject "sideA" is activated. This activates the CombineLatest which in turn writes again to "sideA" and so on. You need some guard to prevent the infinite writing of values. You can use Sample after CombineLatest to ensure that only the first branch can propagate the values.

Such infinite loops used to be impossible due to the feedforward nature of Bonsai graphs, but the introduction of variables and memory changed that guarantee. With great power comes great responsibility, I guess. All sufficiently powerful programming languages are doomed to loop forever on some programs.

Hope this helps.



--
You received this message because you are subscribed to the Google Groups "Bonsai Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bonsai-users+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/bonsai-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/bonsai-users/711db06c-ed82-473a-9eef-42dbab028b3e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Marta Huelin

unread,
Feb 14, 2018, 9:03:14 AM2/14/18
to Bonsai Users
Hi Gonçalo,

Thanks for your quick reply! 
Margot and I haven been working on the workflow for the last couple of days and trying out different things, but we are still having some issues. On the one hand, we've tried adding Sample after CombineLatest but what it seems to be doing is blocking the flow on the first branch. Would you mind explaining what Sample is doing? We might be using it wrong.

On the other hand, we still haven't managed to update the integer values of side A and side B. We've made some changes (please, see photo below) so that after the ROI is activated, a TTL is sent to Arduino, and this should trigger a change on the values for both side A and side B. However, we're stuck with a few things:

1) The TTL triggers a change in (e.g.) side A value from 0 to 1 through ExpressionTransform. However, the value comes back to 0 as soon as the ROI is inactivated.
2) The change of value from 0 to 1 is not updated at the start of the flow (in CombineLatest). Therefore, that same ROI can be activated repeatedly.
3) We haven't figured out how to change both side values in a same branch (for now, only the correspondent side value is changing through ExpressionTransform).


We've added some notes on the photo, hope that helps making it clear.
Many thanks in advance!


El dimarts, 13 febrer de 2018 1:24:11 UTC, goncaloclopes va escriure:
To unsubscribe from this group and stop receiving emails from it, send an email to bonsai-users...@googlegroups.com.
BackandForth_12022018_v7.bonsai

Gonçalo Lopes

unread,
Feb 14, 2018, 5:03:28 PM2/14/18
to Marta Huelin, Bonsai Users
Hi Marta,

I'm thinking it may be better to design the task in two different steps:

1. Compute the activation of both ROIs for all frames, independent of the task state and store it in two variables (this may also be useful for data recording, since you may be interested when something happens in either ROIs, even if nothing happens in the task).

2. Design a state machine simply to advance through the task and repeat.

You can separate both parts independently, with something like this (also attached):

Main Workflow

Inline images 1

State (RoiA / RoiB)

Inline images 2

I'll leave the calibration and testing up to you, but hopefully it will make things a bit more clear. The trick is to use SelectMany as a way to start "states" in the task. In each state, you simply wait for the corresponding ROI to be activated and trigger an output.

At the end, you Repeat. I think in this way, the specification is much more readable and follows the intuitive logic.

Hope this helps.

To unsubscribe from this group and stop receiving emails from it, send an email to bonsai-users+unsubscribe@googlegroups.com.
BackandForth_12022018_v8_states.bonsai
Reply all
Reply to author
Forward
0 new messages