Finding out the actual display refresh rate

1,044 views
Skip to first unread message

Richard Höchenberger

unread,
Oct 8, 2014, 10:45:38 AM10/8/14
to psychop...@googlegroups.com
I am wondering which is the best way to find out the 'actual' display
refresh rate/frame duration. Apparently right now there are several
different approaches:

o check out win.monitorFramePeriod

o invoke win.getActualFrameRate()

o invoke win.getMsPerFrame()


win.monitorFramePeriod is only set once, on creation of the Window
object (derived from win._monitorFrameRate) and never updated after
that. It could be outdated by the time one is querying it (which would
probably imply some serious timing issues on the computer itself...).

getActualFrameRate() flips several times and returns the current frame
rate (not the one at window creation time).

getMsPerFrame() seems to do pretty much the same, except for also
returning some descriptive statistics and using the rush() function.

So... which one should I use? I am also wondering whether a call to
getActualFrameRate() should maybe update win.monitorFramePeriod... But
this would probably have other side-effects too.

Richard

Mario Reutter

unread,
Oct 8, 2014, 5:58:58 PM10/8/14
to psychop...@googlegroups.com
Hello Richard,

I myself just finished programming a flicker paradigm paired with EEG which is why I had to make sure that the timing of the frames is as accurate as possible during stimulus presentation and not during a blank period since that is when the frame-rate might drop due to hardware limitations. I used a Clock object and printed the time after every win.flip() for the duration of one trial. I compared these timestamps with the expected times given the i-th frame under the set up frame rate Hz (i.e. i / Hz seconds). The difference between the expected and the actual times shows a systematic bias (for me between 2 and 3 ms) since there is code to be executed between the clock.reset() and the main loop resulting in the first win.flip(). The most important value to check the stability of your frame rate, however, is the standard deviation of said differences, which is independent of a transformation by a constant (see attached Excel file).

Here is the code of this simple yet useful procedure:
        frameCounter = 0
        self.clock.reset() #clock = core.Clock() was called earlier
        while (self.clock.getTime() < self.maxResponseTime):
            if (frameCounter % pic1Rate) == 0 :
                ##print "pic1"
                if (pic1Pos < 0): self.LeftImage.draw(self.window)
                else: self.RightImage.draw(self.window)
            if (frameCounter % pic2Rate) == 0 :
                ##print "pic2"
                if (pic1Pos < 0): self.RightImage.draw(self.window)
                else: self.LeftImage.draw(self.window)
           
            self.window.flip()
            print "Frame %.0f : %.3f sec" %(frameCounter, self.clock.getTime())
            frameCounter += 1
            #The "self." prior to some variables / objects is due to object oriented programming with python and can be ignored.

Hope this helps you.
Mario

Mario Reutter

unread,
Oct 8, 2014, 6:05:19 PM10/8/14
to psychop...@googlegroups.com
Of course, I forgot the file attachment. Here it is ;)


On Wednesday, October 8, 2014 4:45:38 PM UTC+2, Richard Höchenberger wrote:
Benchmark (english).xlsx

Richard Höchenberger

unread,
Oct 9, 2014, 9:27:10 AM10/9/14
to psychop...@googlegroups.com
Hi Mario,

On Wed, Oct 8, 2014 at 11:58 PM, Mario Reutter <mario....@gmail.com> wrote:
> make sure that the timing of the frames is as accurate as possible during
> stimulus presentation and not during a blank period since that is when the
> frame-rate might drop due to hardware limitations. I used a Clock object and
> printed the time after every win.flip() for the duration of one trial. I
> compared these timestamps with the expected times given the i-th frame under
> the set up frame rate Hz (i.e. i / Hz seconds).

nice idea! I think I will do that, too. Thanks for the code example.

> The difference between the
> expected and the actual times shows a systematic bias (for me between 2 and
> 3 ms) since there is code to be executed between the clock.reset() and the
> main loop resulting in the first win.flip().

Are you sure about this? You measure the 'actual' time immediately
after the flip().
Since the actually measured refresh times systematically differ by
about 2.8 ms from your expected ('nominal') times, and because this
difference is less than the expected duration of an additional frame
while PsychoPy blocks script execution when flip() is called until the
flip has actually been executed, I would suggest from the measurements
you provided that your display is not refreshing at 75 Hz, but instead
at approx. 62 Hz:

In [3]: 1.0 / (1.0/75 + 0.0028)
Out[3]: 61.98347107438017

What do you think?

All the best,

Richard

Richard Höchenberger

unread,
Oct 9, 2014, 9:31:54 AM10/9/14
to psychop...@googlegroups.com
On Thu, Oct 9, 2014 at 3:26 PM, Richard Höchenberger
<richard.ho...@gmail.com> wrote:
> I would suggest from the measurements
> you provided that your display is not refreshing at 75 Hz, but instead
> at approx. 62 Hz:

Ah no, this cannot be right, since you don't accumulate timing
differences from frame to frame, but rather carry with you a constant
offset. Sorry for the confusion :)

Cheers,

Richard

Jonathan Peirce

unread,
Oct 9, 2014, 9:54:08 AM10/9/14
to psychop...@googlegroups.com
getActualRefreshRate() is the simplest way to test what your monitor is achieving, but not a good way to test for dropped frames during your experiment. ie. it will tell you the rate of your monitor and whether or not you're managing to sync

To test whether you're dropping any frames you could, indeed, use code like Mario's but PsychoPy can also do this for you and should be slightly more precise, because it gets its time-stamp closer to the actual point of the window flip (with less code in-between the flip and the time check). To do that you should set
    win.recordFrameIntervals = True
and then examine
    win.frameIntervals which is a list of each frame interval.
You can see these in action in demos>timeByFrames.py

Note that you should set
    win.recordFrameIntervals = False
anytime that you are *not* needing frame intervals, notably when you expect there to be a pause with no flipping of the window.

cheers,
Jon
--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/psychopy-users/20eb220c-e8e3-4d3a-93fc-3535d2f25e49%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

-- 
Jon Peirce
http://www.peirce.org.uk

Richard Höchenberger

unread,
Oct 13, 2014, 4:27:57 AM10/13/14
to psychop...@googlegroups.com
On Thu, Oct 9, 2014 at 3:51 PM, Jonathan Peirce <jon.p...@gmail.com> wrote:
> To test whether you're dropping any frames you could, indeed, use code like
> Mario's but PsychoPy can also do this for you and should be slightly more
> precise, because it gets its time-stamp closer to the actual point of the
> window flip (with less code in-between the flip and the time check). To do
> that you should set
> win.recordFrameIntervals = True
> and then examine
> win.frameIntervals which is a list of each frame interval.
> You can see these in action in demos>timeByFrames.py

Absolutely, thank you very much. Of course it's also in the docs
(http://www.psychopy.org/general/timing/detectingFrameDrops.html),
somehow I overlooked it there :)

Richard
Reply all
Reply to author
Forward
0 new messages