Win.flip() causes flickers in my static stimulus

Hi all, I’m finishing programming an experiment with EEG, but I’m having problems with the win.flip(). The code sends the triggers, the problem is that I have a static image during a loop and every time I pass the code through the win.flip() this image flickers. This could interfere with my EEG signal. If I remove the win.flip() it stops flickering, but of course it doesn’t send me the triggers for the EEG.

if key_resp_2.keys =='m':
     if key_resp_2.rt < 1.8 and amcuevoiceright == 'audios/mam.wav':
        trigger.setData(1)
        ThisResp = "Fast"
        print("rt", key_resp_2.rt)
        thisExp.addData("Fast", ThisResp)
if key_resp_2.keys =='m':
    if key_resp_2.rt >= 1.8 and key_resp_2.rt <= 3.0 and amcuevoiceright == 'audios/mam.wav':
        trigger.setData(2)
        ThisResp = "Norm"
        print("rt", key_resp_2.rt)
        thisExp.addData("Norm", ThisResp)
if key_resp_2.keys =='m':
     if key_resp_2.rt > 3.0 and amcuevoiceright == 'audios/mam.wav':
         trigger.setData(3)
         ThisResp = "Slow"
         print("rt", key_resp_2.rt)
         thisExp.addData("Slow", ThisResp)
if key_resp_2.keys =='m':
      if key_resp_2.rt < 1.8 and amcuevoiceright == 'audios/mal.wav':
          trigger.setData(10)
          ThisResp = "Fast"
          print("rt", key_resp_2.rt)
          thisExp.addData("Fast", ThisResp)
if key_resp_2.keys =='m':
       if key_resp_2.rt >= 1.8 and key_resp_2.rt <= 3.0 and amcuevoiceright == 'audios/mal.wav':
           trigger.setData(20)
           ThisResp = "Norm"
           print("rt", key_resp_2.rt)
           thisExp.addData("Norm", ThisResp)
if key_resp_2.keys =='m':
        if key_resp_2.rt > 3.0 and amcuevoiceright == 'audios/mal.wav':
            trigger.setData(30)
            ThisResp = "Slow"
            print("rt", key_resp_2.rt)
            thisExp.addData("Slow", ThisResp)

win.flip()
trigger.setData(0)
win.flip()

This is my routine in the loop!! How can I stop the image from blinking?

Thanks

You should never call win.flip() in a Builder script. Builder has its own drawing cycle and expects to control the moment of drawing itself, once every screen refresh. By issuing two extra win.flip() calls per cycle, you will be seriously messing with Builder’s own timing and drawing (and hence why you will be seeing strange flickers - but many other timing-related issues will also be going haywire).

So delete this:

win.flip()
trigger.setData(0)
win.flip()

and instead just tell Builder what to do when it flips the screen itself on the current cycle:

win.callOnFlip(trigger.setData, 0)

https://psychopy.org/api/visual/window.html#psychopy.visual.Window.callOnFlip

Now there could still be issues of timing. The fact that you are not seeing the triggers without calling win.flip() has nothing to do with flipping the window per se but simply due to the pause this causes in your code. i.e. there needs to be some temporal interval between the lines where you do things like trigger.setData(2) (starting the pulse) and then set the line to 0 again (ending the pulse). The reason you don’t see the trigger without an intervening win.flip() is simply because that call takes one screen refresh cycle (typically 16.66 ms) to complete. If you just removed those calls from your code above, the triggers would still be sent, but because the interval between setting the value and then zeroing it would be tiny (potentially microseconds), it would be very hard for your hardware to detect it.

So scheduling the value to be zeroed on the next screen refresh will hopefully give you a long enough pulse duration (i.e. ideally there will be a few milliseconds spare between running your “each frame” code and the actual update of the next frame). Test it out and see how reliable it is - if some pulses seem to be missed, then you might need to do some coding that spans successive refreshes (although now that I think of it, simply calling trigger.setData(0) at the start of your code should guarantee pulse widths of at least 16.66 ms).

Lastly, recording data like this: thisExp.addData("Slow", ThisResp) may not be optimal. Currently you are creating four different columns, but each column contains only either an empty value or a value which is the same as the column header.

You could probably delete all those lines and just have a single line like this outside of all all the if clauses:

thisExp.addData("Response", ThisResp)

That way you would get a single column that describes the sort of response, which contains all the various values. This will almost always be much easier to work with at the analysis stage. Otherwise it’s likely that you’d need to construct a column like this by combining the four separate columns anyways, so you might as well save yourself the effort.

2 Likes

Dear Michael, thank you very much, I followed your recommendations and it works great! The problem is solved!!

Thank again!