Advertisement
Guest User

Untitled

a guest
May 22nd, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.06 KB | None | 0 0
  1. from datetime import datetime, timedelta
  2. from matplotlib.collections import LineCollection
  3. from numpy import array
  4. from pylab import subplot, figure, show
  5.  
  6. gpuFileNames = ['GPU.txt']
  7. cpuFileNames = ['CPU.txt']
  8. fpsFileNames = ['3DMark06 2010-05-01 12-26-51-93 fps.csv',
  9.                 '3DMark06 2010-05-01 12-28-47-27 fps.csv',
  10.                 '3DMark06 2010-05-01 12-32-00-08 fps.csv',
  11.                 '3DMark06 2010-05-01 12-33-33-37 fps.csv']
  12.  
  13. # Translation of GPU-Z's field names
  14. gpuFields = {
  15.     u'GPU Core Clock [MHz]'    : ('Core', 'MHz'),
  16.     u'GPU Memory Clock [MHz]'  : ('Memory', 'MHz'),
  17.     u'GPU Temperature [\xb0C]' : ('?', u'\xb0C'),
  18.     u'Fan Speed [%]'           : ('Fan Speed', '%'),
  19.     u'GPU Load [%]'            : ('Load', '%'),
  20.     u'Fan Speed [RPM]'         : ('Fan Speed', 'RPM'),
  21.     u'GPU Temp. #1 [\xb0C]'    : ('DispIO', u'\xb0C'),
  22.     u'GPU Temp. #2 [\xb0C]'    : ('MemIO', u'\xb0C'),
  23.     u'GPU Temp. #3 [\xb0C]'    : ('Shader', u'\xb0C')
  24. }
  25. def gpuHeads(heads, count):
  26.     return [gpuFields[unicode(head, 'latin')] for head in heads]
  27.  
  28. # Generates CPU headings
  29. def cpuHeads(heads, count):
  30.     heads = []
  31.     heads.append(('', u'MHz'))
  32.     for i in xrange(count - 4):
  33.         heads.append(('Core #{0}'.format(i), u'\xb0C'))
  34.     heads.append(('Load', u'%'))
  35.     return heads
  36.  
  37. # Generates FPS headings
  38. def fpsHeads(heads, count):
  39.     return [('', u'FPS')]
  40.  
  41. colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k']
  42.  
  43. class DataSet(object):
  44.     """ Data set - corresponds to a single set of data """
  45.     def __init__(self, heads, data):
  46.         self.heads = heads
  47.         self.data = array(data)
  48.        
  49.     def __len__(self):
  50.         return len(self.data)
  51.  
  52. class DataLog(object):
  53.     """ Data log - corresponds to a single data file """
  54.     def __init__(self, name, dataSets, start, end):
  55.         self.name = name
  56.         self.dataSets = dataSets
  57.         self.start = start
  58.         self.end = end
  59.         self.len = 0
  60.         for dataSet in dataSets:
  61.             self.len += len(dataSet)
  62.            
  63.     def __len__(self):
  64.         return self.len
  65.  
  66. def main():
  67.     """ Main function. Loads and plots the data """
  68.     global gpu, cpu, fps
  69.     gpu = loadData(gpuFileNames, 'GPU', ',', 'Date', gpuHeads, 1, '%Y-%m-%d %H:%M:%S')
  70.     cpu = loadData(cpuFileNames, 'CPU', None, 'DATE', cpuHeads, 2, '%m/%d/%y %H:%M:%S')
  71.     fps = loadData(fpsFileNames, 'Frame rate', None, 'FPS', fpsHeads, 0, '%Y-%m-%d %H-%M-%S')
  72.  
  73.     # Draw the graph
  74.     draw(gpu, cpu, fps)
  75.  
  76. def loadData(fileNames, logName, sep, firstHead, headsFun, dateLen, dateFormat):
  77.     """ Loads data sets from a file into a DataLog """
  78.     dataSets = []
  79.     data = []
  80.     firstDate = None
  81.     prev = None
  82.  
  83.     try:
  84.         for fileName in fileNames:
  85.             date = None
  86.             f = open(fileName)
  87.  
  88.             for line in f:
  89.                
  90.                 toks = line.split(sep)
  91.                 if not toks: continue # Empty line
  92.                 toks = [tok.strip() for tok in toks] # Strip empty space
  93.                 if toks[-1] == '': toks = toks[:-1]
  94.  
  95.                 # Read and interpret data headings
  96.                 if toks[0] == firstHead:
  97.                     if data:
  98.                         dataSets.append(DataSet(heads, data))
  99.                     heads, data = None, []
  100.                     headToks = toks[dateLen:]
  101.                     continue
  102.                 if heads is None:
  103.                     heads = headsFun(headToks, len(toks))
  104.  
  105.                 # Read or calculate date/time
  106.                 if dateLen > 0:
  107.                     date = datetime.strptime(' '.join(toks[0:dateLen]), dateFormat)
  108.                 elif date is None:
  109.                     dstr = ' '.join(fileName.rsplit(None, 3)[1:-1]).rsplit('-', 1)[0]
  110.                     date = datetime.strptime(dstr, dateFormat)
  111.                 else:
  112.                     date += timedelta(0,1,0)
  113.                 if firstDate is None: firstDate = date
  114.                 time = (date - firstDate).seconds
  115.                 if prev is None: prev = time - 1
  116.  
  117.                 # Leave gaps where appropriate
  118.                 if time - prev > 1 and data:
  119.                     dataSets.append(DataSet(heads, data))
  120.                     data = []
  121.                    
  122.                 # Read sensor values
  123.                 for i in xrange(dateLen, len(toks)):
  124.                     toks[i] = float(toks[i])
  125.  
  126.                 # Catch anomalous data
  127.                 valid = True
  128.                 for i, v in enumerate(toks[dateLen:]):
  129.                     if v < 0 or v > 10000:
  130.                         print "Anomalous reading for {0}[{1}]: {2} at {3}".format(
  131.                             heads[i][0], heads[i][1], v, date)
  132.                         valid = False
  133.                 if valid:
  134.                     data.append([time] + toks[dateLen:])
  135.                     prev = time
  136.                    
  137.             if data:
  138.                 dataSets.append(DataSet(heads, data))
  139.                 data = []
  140.  
  141.             f.close()
  142.  
  143.     except IOError:
  144.         print fileName + " could not be loaded"
  145.        
  146.     return DataLog(logName, dataSets, firstDate, date)
  147.        
  148. def draw(gpu, cpu, fps):
  149.     """ Plotting function.
  150.    Takes three DataLogs, for the GPU, CPU and FPS data."""
  151.    
  152.     # Summarize time period of data
  153.     ss = "{1} lines of {0} data from {2} to {3}"
  154.     start, end = None, None
  155.     for log in [gpu, cpu, fps]:
  156.         if log:
  157.             print ss.format(log.name, len(log), log.start, log.end)
  158.             if not start or start > log.start: start = log.start
  159.             if not end or end < log.end: end = log.end
  160.     for log in [gpu, cpu, fps]:
  161.         offset(start, log)
  162.    
  163.     # Maximum value, leaving some room for the legend
  164.     xmax = (end-start).seconds * 1.15
  165.  
  166.     print
  167.     print "{0:17}: Min/Avg/Max".format('Measurement')
  168.    
  169.     tempFilt = lambda x: x[0] != '?' and x[1] == u'\xb0C'
  170.     clockFilt = lambda x: x[1] == u'MHz'
  171.     loadFilt = lambda x: 'Fan' not in x[0] and x[1] == u'%'
  172.     fpsFilt = lambda x: x[1] == u'FPS'
  173.     graphConds = [([cpu], tempFilt, u'Temperature [\xb0C]'),
  174.                   ([gpu], tempFilt, u'Temperature [\xb0C]'),
  175.                   ([cpu, gpu], clockFilt, u'Clock speed [MHz]'),
  176.                   ([cpu, gpu], loadFilt, u'Load [%]'),
  177.                   ([fps], fpsFilt, u'Frame rate [FPS]')
  178.                   ]
  179.     graphInfo = []
  180.     for cond in graphConds:
  181.         ret = makeLines(cond[0], cond[1])
  182.         if ret:
  183.             graphInfo.append(ret + (cond[2],))
  184.     np = len(graphInfo)
  185.  
  186.     fig = figure()
  187.     for i in xrange(np):
  188.         lcs, mn, mx, ylabel = graphInfo[i]
  189.         ax = subplot(np, 1, i+1)
  190.         for lc in lcs:
  191.             ax.add_collection(lc)
  192.         ax.grid(True)
  193.         if i == 0:
  194.             ax.set_title('Status from {0} to {1}'.format(start, end))
  195.         ax.set_ylabel(ylabel)
  196.         if i == np-1:
  197.             ax.set_xlabel('Time [s]')
  198.         ax.axis([0, xmax, mn, mx])
  199.         ax.legend()
  200.    
  201.     show()
  202.  
  203. def makeLines(dataLogs, filt):
  204.     """ Create line collections from the data logs """
  205.     mn, mx = None, None
  206.     uids, liness = [], []
  207.     hasData = False
  208.    
  209.     for log in dataLogs:
  210.         for dataSet in log.dataSets:
  211.             curHeads = filter(filt, dataSet.heads)
  212.             if curHeads: hasData = True
  213.            
  214.             for head in curHeads:
  215.                 uid = (log.name, head)
  216.                 if uid not in uids:
  217.                     uids.append(uid)
  218.                     liness.append([])
  219.                 i = uids.index(uid)
  220.                 j = dataSet.heads.index(head)
  221.                 liness[i].append(dataSet.data[:, (0, j+1)])
  222.  
  223.     if not hasData:
  224.         return None
  225.  
  226.     for i in xrange(len(uids)):
  227.         uid = uids[i]
  228.         cmn, cavg, cmx = doStats(uid, liness[i])
  229.         if mn is None or cmn < mn:
  230.             mn = cmn
  231.         if mx is None or cmx > mx:
  232.             mx = cmx
  233.         liness[i] = LineCollection(liness[i])
  234.         liness[i].set_label(uid[0] + " " + uid[1][0])
  235.         liness[i].set_color(colors[i])
  236.        
  237.     return liness, mn, mx
  238.  
  239. def offset(start, dataLog):
  240.     """ Change start date of the log """
  241.     if dataLog:
  242.         delta = (dataLog.start - start).seconds
  243.         for dataSet in dataLog.dataSets:
  244.             dataSet.data[:, 0] += delta
  245.         dataLog.start = start
  246.  
  247. def doStats(uid, lines):
  248.     """ Return and print min/avg/max stats"""
  249.     mn, mx = None, None
  250.     count, tot = 0, 0
  251.    
  252.     for line in lines:
  253.         vals = line[:, 1]
  254.         cmn = vals.min()
  255.         if mn is None or cmn < mn:
  256.             mn = cmn
  257.         cmx = vals.max()
  258.         if mx is None or cmx > mx:
  259.             mx = cmx
  260.         tot += vals.sum()
  261.         count += len(vals)
  262.     if count > 0:
  263.         avg = float(tot) / count
  264.     else:
  265.         avg = 0
  266.  
  267.     title = uid[0]
  268.     if uid[1][0]:
  269.         if title:
  270.             title += " "
  271.         title += uid[1][0]
  272.     units = "[" + uid[1][1] + "]"
  273.     print u"{0:11}{1:>6}: {2:.1f}/{3:.1f}/{4:.1f}".format(title, units, mn, avg, mx)
  274.     return mn, avg, mx
  275.  
  276. if __name__ == '__main__':
  277.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement