psychopy.org | Reference | Downloads | Github

Create a looming

Hello!
I am a starter with PsychoPy and I don’t have much experience with coding, so I’m trying to use only the builder.
I need to male a looming stimulus appear on the screen from 2 degrees to 20 degrees in size over 250ms. I was able to make it as a group of shapes with increasding sizes appearing over time, but it doesn’t look continuous and smooth as I need it.
I believe it must be a simple thing to do, but I am not able to figure it out by myself.
Thank you for your help!

Please tell us what you did exactly, so we can suggest improvements.

I did it as 10 images with sizes 2, 4, 6, …, 20 appearing during 25ms each (maling the total of 250ms of looming that I need). What happens is I can discriminate the appearance of each cirle, it is not a smooth transition. I also started doing it with 20 images appearing during 12,5ms each, but the same thing happened.

Hi, a much better (and easier) way to do it is to use a single image image that can be scaled. The way to do this is to put a mathematical expression in its size field that uses the variable t, which Builder updates continually to provide the current time in the routine, in seconds.

e.g.

50 + (t / 0.25 * 500)

would scale it from a starting size of 50 pixels to a final size of 550 pixels over the course of 0.25 seconds. Make sure you set that field to update “every frame”.

If using this sort of approach, you need to take account of the refresh rate of the screen. 25 ms increments would be very difficult to achieve on most displays. e.g. typical LCDs update at 60 Hz, meaning that stimuli can only be displayed for multiples of 16.666 ms. Even a faster screen, running at say, 144 Hz, could not give stimulus increments of this exact amount.

So using the time-based approach takes care of this for you, but you should also check if the total duration matches what your screen is drawing. In this case 250 ms does work on a 60 Hz screen, as 250 ms is exactly 15 refreshes of 16.666 ms each.

This might still happen even with using a time-based scaling. You need to take into account what the transition in size would be between successive screen refreshes. Over 250 ms, you will still only get 15 successive scaling steps with a 60 Hz display. This is certainly an improvement on your current scheme that uses just 10 images, and in that current scheme, the temporal intervals between stimuli will not be regular (as the screen is likely not actually updating at 25 ms intervals), so some intervals will be longer and others shorter than you intend.

But it might still appear jerky, depending on the extend of the looming involved. If so, you might want to use a faster display, that would give you more steps within the same total duration.

Thank you very much for your answer!
I tried doing it as you suggested, with the mathematical expression, and I got an error message: ZeroDivisionError: float division by zero.

Sorry, I didn’t notice this reply. It is not clear to me that this error is actually due to that expression.

  • What happens if you replace that expression with a constant value like 50? Does the error disappear?

  • If so, then insert a code component, and in its “each frame” tab, put:

print(str(50 + (t / 0.25 * 500)))

After the experiment has run, what does that stream of values look like?

I could do it right now! I don’t know exactly why, some setting parameter was probably not okay. I re-did the trial with the mathematical expression you suggested in the previous message, and it was fine, jus like I needed it. Thank you very much again :slight_smile: