psychopy.org | Reference | Downloads | Github

Is there a psychopy function that provides millisecond-precise measures of current time?

Hi, I am currently programming an eye-tracking experiment in opensesame with the psychopy back-end. I need to manually log some trial times by setting a ‘time’ variable before and after each trial. At the moment I’m using time.time() to do so, but I worry that’s imprecise. I have read on stack overflow that time.time() is only accurate to 16ms, and so if I called that twice I’d be introducing 32ms of error to my RT measurements…

My work requires modelling RTs and so I don’t want to include any variability that I could potentially squash out. Somebody told me that psychopy has great millisecond timing, similar to E-prime. I’m wondering how I could access this in my scripting. If I use psychopy.core.getTime() at the start and end of trials will I get more reliable RT measures?

Thanks

Luke

Don’t believe everything you read, even on StackOverflow. Computer timing functions are “precise” to microseconds, as far as that goes. The limiting factor on “accuracy” is really more about your coding and when you call that function with respect to the event you want to time.

Firstly, you need to be careful to distinguish between precision and accuracy: they are not synonyms.

Secondly, we can’t give you any guidance at all without knowing the details of your code.
It is true to say that PsychoPy has micro- (rather than milli-) second timing abilities. It is also true to say that you can write code in PsychoPy that will yield grossly inaccurate and imprecise timing.

Lastly, I’m not sure how many people here know much about OpenSesame. The PsychoPy advice we give here may or may not be useful to you in that environment.

So come back to us with more details and we’ll see what we can do.

The incorrect info about 16ms probably comes from the issue of checking the time once per screen refresh. There are ways to avoid that but, as Mike says, it depends on your code and on how that fits in the OpenSesame structure (which I also don’t know much about)

I have a lovely shiny new Benq XL2540 and was doing some benchmarking.

It run fine with a refresh rate of 240 and whilst my ‘Every Frame’ code block IS called on every frame (ie 240 times per second) the call to time.time() only updates every about every 3rd call ( ~16ms) so rather being updated every refresh it seems to be aligned to a different timer.

This is a problem if you want to time more precisely.

Does anyone have any suggestions to get around this problem with Builder? (I’ve not tried using datetime.datetime.now() yet - perhaps that doesn’t have the above problem?)

Incidently, calling time.time() from raw python in a loop typically gets through 3 loops on my laptop before the millisecond count increments (i.e. it doesn’t have the above problem) so I’m guessing that PsychPy is overriding the Python System time() library?

Thanks,
John

PsychoPy doesn’t do anything to override time.time()
Could you provide a minimal working example of your code so we can see the problem?

Python docs re time.time() “Return the time in seconds since the epoch as a floating point number. Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second.”

@jon and @sol seem to have done the heavy lifting here to deal with getting precise timing regardless of platform, so perhaps you should be using the PsychoPy-provided clock classes rather than time.time()?

I’ve tried the same code on two other machines and it’s fine on them both so it seems to just be a problem with one machine where time.time() is performing differently and I lose the fine grain differences between successive calls. Even factoring in Michaels comments about varying implementation of time() this is somewhat strange as all 3 boxes are running Windows 10 and from the same installation disk. Maybe its motherboard related?. Anyway, it’s my problem and not a psycholpy one.

Thanks anyway,

John

ps simple code to run is:on the each frame tab

print( “%0.4f” % time.time() )

and look for smoothly increasing values.

The print() itself can be an issue here: it doesn’t perform well in real-time like this. What about just appending all the values to a list, and printing the entire list at the end?

Hi Michael,

Thanks for the feedback, actually that is what I did (stored in a list and then wrote to disk at the end) however for simplicity for the post I used the print - sorry for not clarifying that up front.
cheers,
John