Hey there,
I am working on a Psychopy programm on a windows machine which presents similar stimuli in a row. So, the programm reads in a text file with some parameters about the shape of the stimulus (e.g. rectangle-shaped stripe with 10 degrees width at 90 degrees orientation) or the stimulus color and timing. I use the ShapeStim class for the stripes. The approx.10-20 different stripes should then be presented subsequently.
All of this works, but I have some timing issues. When finishing a presentation of a stripe and a new stripe is generated, the parameters are modified and then presented in the opened window. This takes about 30 ms of delay and this should not happen in a usual experimental flow.
I read the advices for better timing, so then I did not create a new ShapeStim for every stripe, instead I reused the old one and just modified the parameters. But this still caused the 3-5 ms delay.
So I tried doing Threading, instead of reusing the ShapeStim object. In a thread I prepare the next stripe while the current stripe is being presented (this usually takes 2-4 seconds, so there is plenty of time)
This is within my main() function:
def main():
# do a lot of initializing stuff, getting data aquisition started ....
...
if FIRST:
stripe = CylinderStripe(window,stripe_attributes,stripe_number)
First = False
else:
stripe = next_stripe.get()
# Threading, set the next stripes parameter within __init__ of class 'CylinderStripe'
pool = ThreadPool(processes = 1)
next_number = (stripe_number+1) % stripes_no
next_stripe = pool.apply_async(CylinderStripe, (window,stripe_attributes,next_number))
# Draw the current stripe
output_data = stripe.draw(global_clock)
There is a module called CylinderStripe which sets the stripe attributes in it’s init function:
import helper
class CylinderStripe(object):
def __init__(self,window, stripe_attributes, stripe_number):
# The same for all classes
self.win = window
self.number = stripe_number
self.attributes = stripe_attributes
self.win.color = helper.set_color(self.attributes.COLOR)
self.rect = visual.ShapeStim(self.win, units='',fillColorSpace='rgb', lineWidth=0)
# stripe attributes
self.rect.vertices = self.attributes.vertices
self.rect.pos = (self.attributes.xpos, self.attributes.ypos)
self.rect.fillColor = helper.set_fgcol(self.attributes.FGCOLOR)
self.rect.ori = self.attributes.orientation
# set timing
self.min_duration = self.attributes.min_duration
self.duration = self.attributes.duration
def draw(self,global_clock):
# As long as duration, draw the stimulus
for frameN in range(int(self.duration*FRAMERATE)):
# Move Stimulus for a certain time
if self.attributes.xvelocity != 0 and global_clock.getTime() <= self.min_duration:
self.rect.pos += (self.attributes.xvelocity,0)
# Finally, present stimulus
self.rect.draw()
# process some information for output_data
self.win.flip()
return output_data
But with this technique there is about 20 ms delay. I am confused, because I thought that threading could cure my problem via parallelization. Do I do something wrong ? I havent applied threading or multiprocessing before. Or maybe there is another idea to speed up the creation of another stripe ?
Thank you in advance!