Advertisement
smathot

Check drift for high-resolution system timer

Sep 9th, 2013
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.45 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. from time import time as getTickTime, sleep as tickSleep
  4. from ctypes import byref, c_int64, windll
  5. from matplotlib import pyplot as plt
  6. import numpy as np
  7.  
  8. # The number of samples to get
  9. N = 1000
  10. # The sleep period between samples (in sec.)
  11. sleep = .1
  12.  
  13. def getQPCTime():
  14.  
  15.     """
  16.     Uses the Windows QueryPerformanceFrequency API to get the system time. This
  17.     implements the high-resolution timer as used for example by PsychoPy and
  18.     PsychoPhysics toolbox.
  19.  
  20.     Returns:
  21.     A timestamp (float)
  22.     """
  23.  
  24.     _winQPC(byref(_fcounter))
  25.     return  _fcounter.value/_qpfreq
  26.  
  27. # Complicated ctypes magic to initialize the Windows QueryPerformanceFrequency
  28. # API. Adapted from the psychopy.core.clock source code.
  29. _fcounter = c_int64()
  30. _qpfreq = c_int64()
  31. windll.Kernel32.QueryPerformanceFrequency(byref(_qpfreq))
  32. _qpfreq = float(_qpfreq.value)
  33. _winQPC = windll.Kernel32.QueryPerformanceCounter
  34. # Create empty numpy arrays to store the results
  35. aQPC = np.empty(N, dtype=float)
  36. aTick = np.empty(N, dtype=float)
  37. aDrift = np.empty(N, dtype=float)
  38. # Wait for a minute to allow the Python interpreter to settle down.
  39. tickSleep(1)
  40. # Get the onset timestamps for the timers.
  41. onsetQPCTime, onsetTickTime = getQPCTime(), getTickTime()
  42. # Repeatedly check both timers
  43. print "QPC\ttick\tdrift"
  44. for i in range(N):
  45.     # Get the QPC time and the tickTime
  46.     QPCTime = getQPCTime()
  47.     tickTime = getTickTime()
  48.     # Subtract the onset time
  49.     QPCTime -= onsetQPCTime
  50.     tickTime -= onsetTickTime
  51.     # Determine the drift, such that > 1 is a relatively slowed QPC timer.
  52.     drift = tickTime / QPCTime
  53.     # Sleep to avoid too many samples.
  54.     tickSleep(sleep)
  55.     # Print output
  56.     print "%.4f\t%.4f\t%.4f" % (QPCTime, tickTime, drift)
  57.     # Save the results in the arrays
  58.     aQPC[i] = QPCTime
  59.     aTick[i] = tickTime
  60.     aDrift[i] = drift
  61.  
  62. # The first drift sample should be discarded
  63. aDrift = aDrift[1:]
  64. # Create a nice plot of the results
  65. plt.figure(figsize=(6.4, 3.2))
  66. plt.rc('font', size=10)
  67. plt.subplots_adjust(wspace=.4, bottom=.2)
  68. plt.subplot(121)
  69. plt.plot(aQPC, color='#f57900', label='QPC timer')
  70. plt.plot(aTick, color='#3465a4', label='Tick timer')
  71. plt.xlabel('Sample')
  72. plt.ylabel('Timestamp (sec)')
  73. plt.legend(loc='upper left')
  74. plt.subplot(122)
  75. plt.plot(aDrift, color='#3465a4', label='Timer drift')
  76. plt.axhline(1, linestyle='--', color='black')
  77. plt.xlabel('Sample')
  78. plt.ylabel('tick / QPC')
  79. plt.savefig('systemTimerDrift.png')
  80. plt.savefig('systemTimerDrift.svg')
  81. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement