Presenting visual stimulus when animal is detected in ROI

692 views
Skip to first unread message

Elizabeth Crummy

unread,
Aug 16, 2021, 4:09:27 PM8/16/21
to Bonsai Users
Hi

I am trying to use Bonsai to present a looming disk whenever a mouse enters the center of an open field. I am able to draw and change the size of the stimulus as well as create a ROI for the center of the open field, but I haven't been able to figure out how to initiate disk presentations only when the mouse enters the ROI. Would anyone be able to suggest possible solutions? Thank you for your help!


BonsaiLoomingDisk.bonsai

brunocruz

unread,
Aug 16, 2021, 4:34:33 PM8/16/21
to Bonsai Users
Hi!

Not sure what the exact logic you are looking for is, but the general solution should be something along the lines of detecting the animal inside the ROI and define your trigger condition. 
In the attached example, I used a keypress that generates a "true" Boolean if you press "A" and a "False" if you press "S". "A" would correspond to your "Inside ROI" event and "S" to your "Outside ROI". Since you only want to trigger once the animal enters the ROI you are looking for a "False" -> "True" transition event (You would replace this part by your computer vision code and connect your "GreaterThan" to "DistinctUntilChanged"). To achieve this, we use  DistinctUntilChanged to solely propagate distinct contiguous elements, followed by a "Condition" that only propagates values that pass its condition (in this case if the incoming values are true, they will be propagated).  This info is then sent to your BehaviorSubject that will be used to trigger the stimulus.

On the stimulus side, a simple way to do this, assuming you are happy with the way your stim is working, is to just encapsulate your stim. logic inside a "SelectMany". This node will run the encapsulated code each time it receives any input (in this case your trigger). 
Hope it helps,

Bruno
BonsaiLoomingDisk.bonsai

Elizabeth Crummy

unread,
Aug 17, 2021, 5:48:27 PM8/17/21
to Bonsai Users
Thanks! Using the Greater than and DistinctUntilChanged did work!

If I would want to make the stimulus conditional to multiple factors, is the logic still the same? I tried mapping this out in Bonsai, but my stimulus SelectMany node can't take more than one subscribe subject. Making a second condition based on the time of the session does not seem to work either. 

Thanks again for your help!

Elizabeth

BonsaiLoomingDisk (1).bonsai

brunocruz

unread,
Aug 18, 2021, 3:52:31 AM8/18/21
to Bonsai Users
Hi  Elizabeth ,

When dealing with multiple conditions you have to decide how these interact. Using your example: Say you want to only deliver the stim after 1min within a session. Does this mean that the next time your ROI is visited you want to deliver the stimulus OR once the 1min elapsed and if the animal is inside the ROI you want to deliver the stimulus? Depending on the exact behavior you are looking for, the implementation might be different. 

Implementing the first solution:
Initialize your "InTestPhase" as False and change it to True using a "Timer" -> "Boolean(True)" wherein the DueTime property of Timer determines how long you want to reject entries in the ROI for.
Next, since you only want to check the value of the "InTestPhase" once the animal actually enters the ROI, we use "WithLatestFrom" where the first input is given by  "MouseInCenter" subject events. Basically, each time "MouseInCenter" emits a value, it will "pair" it with the latest value available in "InTestPhase". Finally, the only thing left to do is to check if both values are True by using a "BitwiseAnd" inside a Condition node (you could also just check the second one, since you are already making sure that MouseInCenter is True). This logic will only allow events to go in if this condition is passed which should trigger your stimulus.

Implementing the second solution requires few changes. We will replace "WithLatestFrom" by "CombineLatest". As the name implies, this node will emit an event whenever ANY of the sources emits a value and combines  it with the latest element of the second source. As a result, if the time elapses and the animal is in the ROI, the stimulus will be automatically triggered, instead of waiting for the next entry. However, for this to work, we need to stop filtering the MouseInCenter subject, since the latest value, by design, would always be True. Simply remove the Condition Node, and initialize the subject as False (Boolean(False))

Hope it helps!
Bruno
SecondSolution.bonsai
firstSolution.bonsai

Elizabeth Crummy

unread,
Sep 21, 2021, 3:08:50 PM9/21/21
to Bonsai Users
Hi Bruno,

Thank you! The second solution was what I was going for and worked. I've noticed though that the ROI detection with multiple entries can cause the stimulus to not render properly (i.e. it gets stuck on one diameter or can't expand to the full diameter range). I tried adding a delay after displaying the stimulus after several repetitions, but it hasn't fixed the rendering issue. Is this something I can control with further conditional statements within the Draw Disk node? Thanks again for all of your help! 

BonsaiLoomingDisk (1).bonsai

brunocruz

unread,
Sep 23, 2021, 3:07:01 AM9/23/21
to Bonsai Users
Hi Elizabeth
I am glad it worked!
RE: your problem, I think you were heading in the right direction by adding the delay :). Basically, your condition is triggering too quickly resulting in some weird rendering of the stim. Again, there are many ways to fix this depending on the exact behavior you are looking for. I opted to code the simplest one that came to mind, but let me know if you need something different and we can try to think about it a bit more!

I added an additional variable "RenderStim" that will determine whether a stim should be drawn or not. This means that the stimulus is now determined by the intersection of RenderStim InTestPhase MouseInCenter. Only when these 3 values are simultaneously true will the stim be drawn (this is being computed inside the "Condition" Node). RenderStim is initialized as True and it will be toggled for a given duration (sorta like a refractory period) inside the "ToggleStimAvailability" sink node. 
Inside this sink node you can define this refractory period by changing the DueTime property of the Timer. Since RenderStim is now False for a given period, all registered valid entries (i.e. RenderStim InTestPhase == 1) will be dropped, however, it will guarantee the uninterrupted drawing of your stim. I have tested the workflow with KeyDown events and it seems to be working as expected.

Cheers,
Bruno
BonsaiLoomingDisk (1).bonsai

Elizabeth Crummy

unread,
Sep 24, 2021, 12:05:03 PM9/24/21
to Bonsai Users
Yes, this worked great, thank you so much! I was able to tweak it a bit to also delay repetitions of the stimulus for set periods of time as well and it works as I was hoping it would.

The last thing I'm trying to figure out with the rendering of the stimulus is if I can pause it at it's maximum size for a second (or another set amount of time I can specify), before the window updates and the stimulus is removed. I've tried using the period and delay nodes for updating the subscription of the stimulus, but it hasn't worked. Also happy to ask this in a separate thread!

BonsaiLoomingDisk (1).bonsai

brunocruz

unread,
Sep 28, 2021, 3:58:47 AM9/28/21
to Bonsai Users
Hi Elizabeth

I think this is what you are looking for. Disclaimer I had to change the stimuli logic quite a bit for 2 reasons. 
1. I don't know how to make it work with the CreateObservable logic since it outputs events from "rangeAnimation" and not from each stimulus. If you really need to use this logic, I hope someone else more experienced can give you a hand! 
2. The stim logic was a bit hard to parse for me and it was super clear what the timers were trying to parameterize. I tried to make it more straightforward, but let me know if there is some sort of unintended behavior.

Finally, I added a node that draws the static stim at the end of stim presentation (drawStaticStim) for the duration of StayOnFor property.

Hope it is at least useful :P
Cheers
Bruno
BonsaiLoomingDisk (1) (1).bonsai

Elizabeth Crummy

unread,
Oct 11, 2021, 4:30:31 PM10/11/21
to Bonsai Users
Thank you so much! With some minor tweaks I was able to get it to work for what I need it to do. I really appreciate all of the help! 
Reply all
Reply to author
Forward
0 new messages