psychopy.org | Reference | Downloads | Github

Sample task: Cross-bounce illusion

Hi,

I wonder if somebody already has a coded example task of the cross-bounce (or bounce-pass) illusion. (https://www.nature.com/articles/srep40123) It’s a common experiment, so I thought that maybe it already exists and I don’t need to reinvent the wheel. Thank you!

Kind regards,
Kata

Hi There,

I have never used this task but was super interested in what it was !! So I coded myself up a draft version. Some things you might want to change as this is a super basic one trial demo… but maybe some of this will help ! Slight disclaimer this is super basic so sorry if it isn’t what you needed!

from psychopy import visual, core, sound


win = visual.Window([1000,1000], monitor='testMonitor', units='cm')
x1=-5
y1=0
x2=5
y2=0
duration=0.1

for i in range(10):
    x1=x1+1
    x2=x2-1
    position1=[x1,y1]
    position2=[x2,y2]
    print position1, position2
    circle1=visual.Circle(win, radius=1, fillColor=[-1,-1,-1],lineColor=[-1,-1,-1], edges=32, pos=position1)#change visual stimuli here
    circle2=visual.Circle(win, radius=1, fillColor=[-1,-1,-1],lineColor=[-1,-1,-1], edges=32, pos=position2)
    if position1==position2:
        highA = sound.Sound('A',octave=3, sampleRate=500, secs=duration, bits=10)#Change sounds details to be what you want here
        highA.setVolume(0.8)
        highA.play()
    circle1.draw()
    circle2.draw()
    win.flip()
    core.wait(duration)

Thanks for showing me this cool task ! very relevant to my research interests! :slight_smile:

Becca

edit:

Sort of got a bit more carried aways with this. New code below. Only issue is the sound sometimes crackles potentially won’t be a problem if you import sound as a wav file:

from __future__ import division
from psychopy import visual, core, sound, event


win = visual.Window([1000,1000], monitor='testMonitor', units='cm')
StartingPos=20
monitorsRefreshRate=60
duration=100#duration in ms
trials=5

#--------------------------------------------------------
x1=-StartingPos
y1=0
x2=StartingPos
y2=0

durationFrames=int(duration/(1000/monitorsRefreshRate))
highA = sound.SoundPyo('A',octave=3, sampleRate=1000, secs=(duration/1000), bits=10)#Change sounds details to be what you want here
highA.setVolume(0.8)

Q = visual.TextStim(win, 
                        units='norm',height = 0.1,
                        pos=(0, 0), text='cross or bounce?\nC=cross\nB=bounce')
Keys=[]
bounceJudgements=0
for i in range(trials):
  #  highA = sound.Sound('A',octave=3, sampleRate=500, secs=duration, bits=10)
    for frameN in range(StartingPos*2):
        x1=x1+1
        x2=x2-1
        position1=[x1,y1]
        position2=[x2,y2]
        circle1=visual.Circle(win, radius=1, fillColor=[-1,-1,-1],lineColor=[-1,-1,-1], edges=32, pos=position1)#change visual stimuli here
        circle2=visual.Circle(win, radius=1, fillColor=[-1,-1,-1],lineColor=[-1,-1,-1], edges=32, pos=position2)
        if frameN==StartingPos:#i.e. if half way through - when the circles overlap
            highA.play()
        circle1.draw()
        circle2.draw()
        win.flip()
    highA.stop()
   #     core.wait(duration)
    x1=-StartingPos
    x2=StartingPos
    Q.draw()
    highA.stop()
    win.flip()
    thisKey=event.waitKeys()
    if thisKey==['b']:
        print 'bounce'
        bounceJudgements=bounceJudgements+1
    Keys.append(thisKey)

End = visual.TextStim(win, 
                        units='norm',height = 0.1,
                        pos=(0, 0), text='TheEnd\nTotal bounce judgements=%s %%'%((bounceJudgements/trials)*100))
End.draw()
win.flip()
event.waitKeys()
4 Likes

Hi Rebecca, @Becca

That was great to get such a nice complete working example: a good example of how this forum connects people who need and who can provide help while also helping us learn about different phenomena and techniques. I accidentally had the sound muted on my computer when I first ran your code, and found the perception was completely changed when I ran it again with the sound on. Nice.

One small optimisation tip: it’s a good idea to strive to avoid re-creating objects multiple times. e.g. your circle stimuli should be created just once, before the drawing loop (as you do with the sound object). Then, inside the loop, just update the existing object’s properties rather than create it again from scratch. e.g. in this case, this would be sufficient:

circle1.pos = position1  
circle2.pos = position2 

Creating objects comes with quite a time overhead, compared to the (usually) very quick process of updating the attributes of an existing object. Probably not much of an issue for a couple of simple stimuli, but it’s a good habit to get into to avoid performance bottlenecks. i.e. it is possible that the time taken to re-create a set of objects might exceed the time available during one screen refresh, leading to timing problems, whereas updating existing objects will (often) be able to be done quite quickly.

1 Like

Thanks Michael! This actually stopped the sound from crackling (Probably because I was trying to do a lot within the space of one frame!)- thanks for the tips!!:slight_smile:

Becca

1 Like