11758Ssaidi@eecs.umich.edu# Copyright (c) 2003-2004 The Regents of The University of Michigan 21758Ssaidi@eecs.umich.edu# All rights reserved. 31758Ssaidi@eecs.umich.edu# 41758Ssaidi@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 51758Ssaidi@eecs.umich.edu# modification, are permitted provided that the following conditions are 61758Ssaidi@eecs.umich.edu# met: redistributions of source code must retain the above copyright 71758Ssaidi@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 81758Ssaidi@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 91758Ssaidi@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 101758Ssaidi@eecs.umich.edu# documentation and/or other materials provided with the distribution; 111758Ssaidi@eecs.umich.edu# neither the name of the copyright holders nor the names of its 121758Ssaidi@eecs.umich.edu# contributors may be used to endorse or promote products derived from 131758Ssaidi@eecs.umich.edu# this software without specific prior written permission. 141758Ssaidi@eecs.umich.edu# 151758Ssaidi@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161758Ssaidi@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171758Ssaidi@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 181758Ssaidi@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 191758Ssaidi@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 201758Ssaidi@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 211758Ssaidi@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 221758Ssaidi@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 231758Ssaidi@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 241758Ssaidi@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 251758Ssaidi@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262665Ssaidi@eecs.umich.edu# 272665Ssaidi@eecs.umich.edu# Authors: Nathan Binkert 281758Ssaidi@eecs.umich.edu 291049Sbinkertn@umich.eduimport MySQLdb, re, string 301049Sbinkertn@umich.edu 311049Sbinkertn@umich.edudef statcmp(a, b): 321049Sbinkertn@umich.edu v1 = a.split('.') 331049Sbinkertn@umich.edu v2 = b.split('.') 341049Sbinkertn@umich.edu 351049Sbinkertn@umich.edu last = min(len(v1), len(v2)) - 1 361049Sbinkertn@umich.edu for i,j in zip(v1[0:last], v2[0:last]): 371049Sbinkertn@umich.edu if i != j: 381049Sbinkertn@umich.edu return cmp(i, j) 391049Sbinkertn@umich.edu 401049Sbinkertn@umich.edu # Special compare for last element. 411049Sbinkertn@umich.edu if len(v1) == len(v2): 421049Sbinkertn@umich.edu return cmp(v1[last], v2[last]) 431049Sbinkertn@umich.edu else: 441049Sbinkertn@umich.edu return cmp(len(v1), len(v2)) 451049Sbinkertn@umich.edu 461049Sbinkertn@umich.educlass RunData: 471049Sbinkertn@umich.edu def __init__(self, row): 481049Sbinkertn@umich.edu self.run = int(row[0]) 491049Sbinkertn@umich.edu self.name = row[1] 501049Sbinkertn@umich.edu self.user = row[2] 511049Sbinkertn@umich.edu self.project = row[3] 521049Sbinkertn@umich.edu 531049Sbinkertn@umich.educlass SubData: 541049Sbinkertn@umich.edu def __init__(self, row): 551049Sbinkertn@umich.edu self.stat = int(row[0]) 561049Sbinkertn@umich.edu self.x = int(row[1]) 571049Sbinkertn@umich.edu self.y = int(row[2]) 581049Sbinkertn@umich.edu self.name = row[3] 591049Sbinkertn@umich.edu self.descr = row[4] 601049Sbinkertn@umich.edu 611049Sbinkertn@umich.educlass Data: 621049Sbinkertn@umich.edu def __init__(self, row): 631049Sbinkertn@umich.edu if len(row) != 5: 641049Sbinkertn@umich.edu raise 'stat db error' 651049Sbinkertn@umich.edu self.stat = int(row[0]) 661049Sbinkertn@umich.edu self.run = int(row[1]) 671049Sbinkertn@umich.edu self.x = int(row[2]) 681049Sbinkertn@umich.edu self.y = int(row[3]) 691049Sbinkertn@umich.edu self.data = float(row[4]) 701049Sbinkertn@umich.edu 711049Sbinkertn@umich.edu def __repr__(self): 721049Sbinkertn@umich.edu return '''Data(['%d', '%d', '%d', '%d', '%f'])''' % ( self.stat, 731049Sbinkertn@umich.edu self.run, self.x, self.y, self.data) 741049Sbinkertn@umich.edu 751049Sbinkertn@umich.educlass StatData(object): 761049Sbinkertn@umich.edu def __init__(self, row): 771049Sbinkertn@umich.edu self.stat = int(row[0]) 781049Sbinkertn@umich.edu self.name = row[1] 791049Sbinkertn@umich.edu self.desc = row[2] 801049Sbinkertn@umich.edu self.type = row[3] 811049Sbinkertn@umich.edu self.prereq = int(row[5]) 821049Sbinkertn@umich.edu self.precision = int(row[6]) 831049Sbinkertn@umich.edu 841049Sbinkertn@umich.edu import flags 851049Sbinkertn@umich.edu self.flags = 0 861049Sbinkertn@umich.edu if int(row[4]): self.flags |= flags.printable 871049Sbinkertn@umich.edu if int(row[7]): self.flags |= flags.nozero 881049Sbinkertn@umich.edu if int(row[8]): self.flags |= flags.nonan 891049Sbinkertn@umich.edu if int(row[9]): self.flags |= flags.total 901049Sbinkertn@umich.edu if int(row[10]): self.flags |= flags.pdf 911049Sbinkertn@umich.edu if int(row[11]): self.flags |= flags.cdf 921049Sbinkertn@umich.edu 931049Sbinkertn@umich.edu if self.type == 'DIST' or self.type == 'VECTORDIST': 941049Sbinkertn@umich.edu self.min = float(row[12]) 951049Sbinkertn@umich.edu self.max = float(row[13]) 961049Sbinkertn@umich.edu self.bktsize = float(row[14]) 971049Sbinkertn@umich.edu self.size = int(row[15]) 981049Sbinkertn@umich.edu 991049Sbinkertn@umich.edu if self.type == 'FORMULA': 1001049Sbinkertn@umich.edu self.formula = self.db.allFormulas[self.stat] 1011049Sbinkertn@umich.edu 1021049Sbinkertn@umich.educlass Node(object): 1031049Sbinkertn@umich.edu def __init__(self, name): 1041049Sbinkertn@umich.edu self.name = name 1051049Sbinkertn@umich.edu def __str__(self): 1061881Sbinkertn@umich.edu return self.name 1071049Sbinkertn@umich.edu 1081929Sbinkertn@umich.educlass Result(object): 1091929Sbinkertn@umich.edu def __init__(self, x, y): 1101929Sbinkertn@umich.edu self.data = {} 1111929Sbinkertn@umich.edu self.x = x 1121929Sbinkertn@umich.edu self.y = y 1131929Sbinkertn@umich.edu 1141929Sbinkertn@umich.edu def __contains__(self, run): 1151929Sbinkertn@umich.edu return run in self.data 1161929Sbinkertn@umich.edu 1171929Sbinkertn@umich.edu def __getitem__(self, run): 1181929Sbinkertn@umich.edu if run not in self.data: 1191929Sbinkertn@umich.edu self.data[run] = [ [ 0.0 ] * self.y for i in xrange(self.x) ] 1201929Sbinkertn@umich.edu return self.data[run] 1211929Sbinkertn@umich.edu 1221049Sbinkertn@umich.educlass Database(object): 1231049Sbinkertn@umich.edu def __init__(self): 1241049Sbinkertn@umich.edu self.host = 'zizzer.pool' 1251049Sbinkertn@umich.edu self.user = '' 1261049Sbinkertn@umich.edu self.passwd = '' 1271049Sbinkertn@umich.edu self.db = 'm5stats' 1281049Sbinkertn@umich.edu self.cursor = None 1291049Sbinkertn@umich.edu 1301049Sbinkertn@umich.edu self.allStats = [] 1311049Sbinkertn@umich.edu self.allStatIds = {} 1321049Sbinkertn@umich.edu self.allStatNames = {} 1331049Sbinkertn@umich.edu 1341049Sbinkertn@umich.edu self.allSubData = {} 1351049Sbinkertn@umich.edu 1361049Sbinkertn@umich.edu self.allRuns = [] 1371049Sbinkertn@umich.edu self.allRunIds = {} 1381049Sbinkertn@umich.edu self.allRunNames = {} 1391049Sbinkertn@umich.edu 1401049Sbinkertn@umich.edu self.allFormulas = {} 1411049Sbinkertn@umich.edu 1421049Sbinkertn@umich.edu self.stattop = {} 1431049Sbinkertn@umich.edu self.statdict = {} 1441049Sbinkertn@umich.edu self.statlist = [] 1451049Sbinkertn@umich.edu 1461049Sbinkertn@umich.edu self.mode = 'sum'; 1471049Sbinkertn@umich.edu self.runs = None 1481049Sbinkertn@umich.edu self.ticks = None 1491929Sbinkertn@umich.edu self.method = 'sum' 1501929Sbinkertn@umich.edu self._method = type(self).sum 1511929Sbinkertn@umich.edu 1522014Sbinkertn@umich.edu def get(self, job, stat, system=None): 1532014Sbinkertn@umich.edu run = self.allRunNames.get(str(job), None) 1541929Sbinkertn@umich.edu if run is None: 1551929Sbinkertn@umich.edu return None 1561929Sbinkertn@umich.edu 1572014Sbinkertn@umich.edu from info import ProxyError, scalar, vector, value, values, total, len 1582183Sbinkertn@umich.edu if system is None and hasattr(job, 'system'): 1592014Sbinkertn@umich.edu system = job.system 1602014Sbinkertn@umich.edu 1612014Sbinkertn@umich.edu if system is not None: 1622014Sbinkertn@umich.edu stat.system = self[system] 1632014Sbinkertn@umich.edu try: 1642014Sbinkertn@umich.edu if scalar(stat): 1652014Sbinkertn@umich.edu return value(stat, run.run) 1662014Sbinkertn@umich.edu if vector(stat): 1672014Sbinkertn@umich.edu return values(stat, run.run) 1682014Sbinkertn@umich.edu except ProxyError: 1692014Sbinkertn@umich.edu return None 1701929Sbinkertn@umich.edu 1711929Sbinkertn@umich.edu return None 1721049Sbinkertn@umich.edu 1731049Sbinkertn@umich.edu def query(self, sql): 1741049Sbinkertn@umich.edu self.cursor.execute(sql) 1751049Sbinkertn@umich.edu 1761049Sbinkertn@umich.edu def update_dict(self, dict): 1771049Sbinkertn@umich.edu dict.update(self.stattop) 1781049Sbinkertn@umich.edu 1791049Sbinkertn@umich.edu def append(self, stat): 1801049Sbinkertn@umich.edu statname = re.sub(':', '__', stat.name) 1811049Sbinkertn@umich.edu path = string.split(statname, '.') 1821049Sbinkertn@umich.edu pathtop = path[0] 1831049Sbinkertn@umich.edu fullname = '' 1841049Sbinkertn@umich.edu 1851049Sbinkertn@umich.edu x = self 1861049Sbinkertn@umich.edu while len(path) > 1: 1871049Sbinkertn@umich.edu name = path.pop(0) 1881049Sbinkertn@umich.edu if not x.__dict__.has_key(name): 1891049Sbinkertn@umich.edu x.__dict__[name] = Node(fullname + name) 1901049Sbinkertn@umich.edu x = x.__dict__[name] 1911049Sbinkertn@umich.edu fullname = '%s%s.' % (fullname, name) 1921049Sbinkertn@umich.edu 1931049Sbinkertn@umich.edu name = path.pop(0) 1941049Sbinkertn@umich.edu x.__dict__[name] = stat 1951049Sbinkertn@umich.edu 1961049Sbinkertn@umich.edu self.stattop[pathtop] = self.__dict__[pathtop] 1971049Sbinkertn@umich.edu self.statdict[statname] = stat 1981049Sbinkertn@umich.edu self.statlist.append(statname) 1991049Sbinkertn@umich.edu 2001049Sbinkertn@umich.edu def connect(self): 2011049Sbinkertn@umich.edu # connect 2021049Sbinkertn@umich.edu self.thedb = MySQLdb.connect(db=self.db, 2031049Sbinkertn@umich.edu host=self.host, 2041049Sbinkertn@umich.edu user=self.user, 2051049Sbinkertn@umich.edu passwd=self.passwd) 2061049Sbinkertn@umich.edu 2071049Sbinkertn@umich.edu # create a cursor 2081049Sbinkertn@umich.edu self.cursor = self.thedb.cursor() 2091049Sbinkertn@umich.edu 2101049Sbinkertn@umich.edu self.query('''select rn_id,rn_name,rn_sample,rn_user,rn_project 2111049Sbinkertn@umich.edu from runs''') 2121049Sbinkertn@umich.edu for result in self.cursor.fetchall(): 2131049Sbinkertn@umich.edu run = RunData(result); 2141049Sbinkertn@umich.edu self.allRuns.append(run) 2151049Sbinkertn@umich.edu self.allRunIds[run.run] = run 2161049Sbinkertn@umich.edu self.allRunNames[run.name] = run 2171049Sbinkertn@umich.edu 2181049Sbinkertn@umich.edu self.query('select sd_stat,sd_x,sd_y,sd_name,sd_descr from subdata') 2191049Sbinkertn@umich.edu for result in self.cursor.fetchall(): 2201049Sbinkertn@umich.edu subdata = SubData(result) 2211049Sbinkertn@umich.edu if self.allSubData.has_key(subdata.stat): 2221049Sbinkertn@umich.edu self.allSubData[subdata.stat].append(subdata) 2231049Sbinkertn@umich.edu else: 2241049Sbinkertn@umich.edu self.allSubData[subdata.stat] = [ subdata ] 2251049Sbinkertn@umich.edu 2261049Sbinkertn@umich.edu self.query('select * from formulas') 2271049Sbinkertn@umich.edu for id,formula in self.cursor.fetchall(): 2281306Sbinkertn@umich.edu self.allFormulas[int(id)] = formula.tostring() 2291049Sbinkertn@umich.edu 2301049Sbinkertn@umich.edu StatData.db = self 2311049Sbinkertn@umich.edu self.query('select * from stats') 2321049Sbinkertn@umich.edu import info 2331049Sbinkertn@umich.edu for result in self.cursor.fetchall(): 2341929Sbinkertn@umich.edu stat = info.NewStat(self, StatData(result)) 2351049Sbinkertn@umich.edu self.append(stat) 2361049Sbinkertn@umich.edu self.allStats.append(stat) 2371049Sbinkertn@umich.edu self.allStatIds[stat.stat] = stat 2381049Sbinkertn@umich.edu self.allStatNames[stat.name] = stat 2391049Sbinkertn@umich.edu 2401049Sbinkertn@umich.edu # Name: listruns 2411049Sbinkertn@umich.edu # Desc: Prints all runs matching a given user, if no argument 2421049Sbinkertn@umich.edu # is given all runs are returned 2431049Sbinkertn@umich.edu def listRuns(self, user=None): 2441049Sbinkertn@umich.edu print '%-40s %-10s %-5s' % ('run name', 'user', 'id') 2451049Sbinkertn@umich.edu print '-' * 62 2461049Sbinkertn@umich.edu for run in self.allRuns: 2471049Sbinkertn@umich.edu if user == None or user == run.user: 2481049Sbinkertn@umich.edu print '%-40s %-10s %-10d' % (run.name, run.user, run.run) 2491049Sbinkertn@umich.edu 2501049Sbinkertn@umich.edu # Name: listTicks 2511049Sbinkertn@umich.edu # Desc: Prints all samples for a given run 2521309Ssaidi@eecs.umich.edu def listTicks(self, runs=None): 2531049Sbinkertn@umich.edu print "tick" 2541049Sbinkertn@umich.edu print "----------------------------------------" 2551309Ssaidi@eecs.umich.edu sql = 'select distinct dt_tick from data where dt_stat=1180 and (' 2561309Ssaidi@eecs.umich.edu if runs != None: 2571309Ssaidi@eecs.umich.edu first = True 2581309Ssaidi@eecs.umich.edu for run in runs: 2591309Ssaidi@eecs.umich.edu if first: 2601309Ssaidi@eecs.umich.edu # sql += ' where' 2611309Ssaidi@eecs.umich.edu first = False 2621309Ssaidi@eecs.umich.edu else: 2631309Ssaidi@eecs.umich.edu sql += ' or' 2641309Ssaidi@eecs.umich.edu sql += ' dt_run=%s' % run.run 2651309Ssaidi@eecs.umich.edu sql += ')' 2661049Sbinkertn@umich.edu self.query(sql) 2671049Sbinkertn@umich.edu for r in self.cursor.fetchall(): 2681049Sbinkertn@umich.edu print r[0] 2691049Sbinkertn@umich.edu 2701309Ssaidi@eecs.umich.edu # Name: retTicks 2711309Ssaidi@eecs.umich.edu # Desc: Prints all samples for a given run 2721309Ssaidi@eecs.umich.edu def retTicks(self, runs=None): 2731309Ssaidi@eecs.umich.edu sql = 'select distinct dt_tick from data where dt_stat=1180 and (' 2741309Ssaidi@eecs.umich.edu if runs != None: 2751309Ssaidi@eecs.umich.edu first = True 2761309Ssaidi@eecs.umich.edu for run in runs: 2771309Ssaidi@eecs.umich.edu if first: 2781309Ssaidi@eecs.umich.edu first = False 2791309Ssaidi@eecs.umich.edu else: 2801309Ssaidi@eecs.umich.edu sql += ' or' 2811309Ssaidi@eecs.umich.edu sql += ' dt_run=%s' % run.run 2821309Ssaidi@eecs.umich.edu sql += ')' 2831309Ssaidi@eecs.umich.edu self.query(sql) 2841309Ssaidi@eecs.umich.edu ret = [] 2851309Ssaidi@eecs.umich.edu for r in self.cursor.fetchall(): 2861309Ssaidi@eecs.umich.edu ret.append(r[0]) 2871309Ssaidi@eecs.umich.edu return ret 2881309Ssaidi@eecs.umich.edu 2891049Sbinkertn@umich.edu # Name: liststats 2901049Sbinkertn@umich.edu # Desc: Prints all statistics that appear in the database, 2911049Sbinkertn@umich.edu # the optional argument is a regular expression that can 2921049Sbinkertn@umich.edu # be used to prune the result set 2931049Sbinkertn@umich.edu def listStats(self, regex=None): 2941049Sbinkertn@umich.edu print '%-60s %-8s %-10s' % ('stat name', 'id', 'type') 2951049Sbinkertn@umich.edu print '-' * 80 2961049Sbinkertn@umich.edu 2971049Sbinkertn@umich.edu rx = None 2981049Sbinkertn@umich.edu if regex != None: 2991049Sbinkertn@umich.edu rx = re.compile(regex) 3001049Sbinkertn@umich.edu 3011049Sbinkertn@umich.edu stats = [ stat.name for stat in self.allStats ] 3021049Sbinkertn@umich.edu stats.sort(statcmp) 3031049Sbinkertn@umich.edu for stat in stats: 3041049Sbinkertn@umich.edu stat = self.allStatNames[stat] 3051049Sbinkertn@umich.edu if rx == None or rx.match(stat.name): 3061049Sbinkertn@umich.edu print '%-60s %-8s %-10s' % (stat.name, stat.stat, stat.type) 3071049Sbinkertn@umich.edu 3081049Sbinkertn@umich.edu # Name: liststats 3091049Sbinkertn@umich.edu # Desc: Prints all statistics that appear in the database, 3101049Sbinkertn@umich.edu # the optional argument is a regular expression that can 3111049Sbinkertn@umich.edu # be used to prune the result set 3121049Sbinkertn@umich.edu def listFormulas(self, regex=None): 3131049Sbinkertn@umich.edu print '%-60s %s' % ('formula name', 'formula') 3141049Sbinkertn@umich.edu print '-' * 80 3151049Sbinkertn@umich.edu 3161049Sbinkertn@umich.edu rx = None 3171049Sbinkertn@umich.edu if regex != None: 3181049Sbinkertn@umich.edu rx = re.compile(regex) 3191049Sbinkertn@umich.edu 3201049Sbinkertn@umich.edu stats = [ stat.name for stat in self.allStats ] 3211049Sbinkertn@umich.edu stats.sort(statcmp) 3221049Sbinkertn@umich.edu for stat in stats: 3231049Sbinkertn@umich.edu stat = self.allStatNames[stat] 3241049Sbinkertn@umich.edu if stat.type == 'FORMULA' and (rx == None or rx.match(stat.name)): 3251049Sbinkertn@umich.edu print '%-60s %s' % (stat.name, self.allFormulas[stat.stat]) 3261049Sbinkertn@umich.edu 3271049Sbinkertn@umich.edu def getStat(self, stats): 3281049Sbinkertn@umich.edu if type(stats) is not list: 3291049Sbinkertn@umich.edu stats = [ stats ] 3301049Sbinkertn@umich.edu 3311049Sbinkertn@umich.edu ret = [] 3321049Sbinkertn@umich.edu for stat in stats: 3331049Sbinkertn@umich.edu if type(stat) is int: 3341049Sbinkertn@umich.edu ret.append(self.allStatIds[stat]) 3351049Sbinkertn@umich.edu 3361049Sbinkertn@umich.edu if type(stat) is str: 3371049Sbinkertn@umich.edu rx = re.compile(stat) 3381049Sbinkertn@umich.edu for stat in self.allStats: 3391049Sbinkertn@umich.edu if rx.match(stat.name): 3401049Sbinkertn@umich.edu ret.append(stat) 3411049Sbinkertn@umich.edu return ret 3421049Sbinkertn@umich.edu 3431049Sbinkertn@umich.edu ######################################### 3441049Sbinkertn@umich.edu # get the data 3451049Sbinkertn@umich.edu # 3462343Sbinkertn@umich.edu def query(self, op, stat, ticks, group=False): 3471049Sbinkertn@umich.edu sql = 'select ' 3481049Sbinkertn@umich.edu sql += 'dt_stat as stat, ' 3491049Sbinkertn@umich.edu sql += 'dt_run as run, ' 3501049Sbinkertn@umich.edu sql += 'dt_x as x, ' 3511049Sbinkertn@umich.edu sql += 'dt_y as y, ' 3521049Sbinkertn@umich.edu if group: 3531049Sbinkertn@umich.edu sql += 'dt_tick as tick, ' 3541049Sbinkertn@umich.edu sql += '%s(dt_data) as data ' % op 3551049Sbinkertn@umich.edu sql += 'from data ' 3561049Sbinkertn@umich.edu sql += 'where ' 3571049Sbinkertn@umich.edu 3581049Sbinkertn@umich.edu if isinstance(stat, list): 3591049Sbinkertn@umich.edu val = ' or '.join([ 'dt_stat=%d' % s.stat for s in stat ]) 3601049Sbinkertn@umich.edu sql += ' (%s)' % val 3611049Sbinkertn@umich.edu else: 3621049Sbinkertn@umich.edu sql += ' dt_stat=%d' % stat.stat 3631049Sbinkertn@umich.edu 3641049Sbinkertn@umich.edu if self.runs != None and len(self.runs): 3651049Sbinkertn@umich.edu val = ' or '.join([ 'dt_run=%d' % r for r in self.runs ]) 3661049Sbinkertn@umich.edu sql += ' and (%s)' % val 3671049Sbinkertn@umich.edu 3681049Sbinkertn@umich.edu if ticks != None and len(ticks): 3691049Sbinkertn@umich.edu val = ' or '.join([ 'dt_tick=%d' % s for s in ticks ]) 3701049Sbinkertn@umich.edu sql += ' and (%s)' % val 3711049Sbinkertn@umich.edu 3721049Sbinkertn@umich.edu sql += ' group by dt_stat,dt_run,dt_x,dt_y' 3731049Sbinkertn@umich.edu if group: 3741049Sbinkertn@umich.edu sql += ',dt_tick' 3751049Sbinkertn@umich.edu return sql 3761049Sbinkertn@umich.edu 3771049Sbinkertn@umich.edu # Name: sum 3782343Sbinkertn@umich.edu # Desc: given a run, a stat and an array of samples, total the samples 3792343Sbinkertn@umich.edu def sum(self, *args, **kwargs): 3802343Sbinkertn@umich.edu return self.query('sum', *args, **kwargs) 3811049Sbinkertn@umich.edu 3821049Sbinkertn@umich.edu # Name: avg 3832343Sbinkertn@umich.edu # Desc: given a run, a stat and an array of samples, average the samples 3842343Sbinkertn@umich.edu def avg(self, stat, ticks): 3852343Sbinkertn@umich.edu return self.query('avg', *args, **kwargs) 3861049Sbinkertn@umich.edu 3871049Sbinkertn@umich.edu # Name: stdev 3882343Sbinkertn@umich.edu # Desc: given a run, a stat and an array of samples, get the standard 3892343Sbinkertn@umich.edu # deviation 3902343Sbinkertn@umich.edu def stdev(self, stat, ticks): 3912343Sbinkertn@umich.edu return self.query('stddev', *args, **kwargs) 3921049Sbinkertn@umich.edu 3931049Sbinkertn@umich.edu def __setattr__(self, attr, value): 3941929Sbinkertn@umich.edu super(Database, self).__setattr__(attr, value) 3951929Sbinkertn@umich.edu if attr != 'method': 3961049Sbinkertn@umich.edu return 3971049Sbinkertn@umich.edu 3981049Sbinkertn@umich.edu if value == 'sum': 3991929Sbinkertn@umich.edu self._method = self.sum 4001049Sbinkertn@umich.edu elif value == 'avg': 4011929Sbinkertn@umich.edu self._method = self.avg 4021049Sbinkertn@umich.edu elif value == 'stdev': 4031929Sbinkertn@umich.edu self._method = self.stdev 4041049Sbinkertn@umich.edu else: 4051049Sbinkertn@umich.edu raise AttributeError, "can only set get to: sum | avg | stdev" 4061049Sbinkertn@umich.edu 4072343Sbinkertn@umich.edu def data(self, stat, ticks=None): 4081049Sbinkertn@umich.edu if ticks is None: 4091049Sbinkertn@umich.edu ticks = self.ticks 4102343Sbinkertn@umich.edu sql = self._method(self, stat, ticks) 4111049Sbinkertn@umich.edu self.query(sql) 4121049Sbinkertn@umich.edu 4131049Sbinkertn@umich.edu runs = {} 4141929Sbinkertn@umich.edu xmax = 0 4151929Sbinkertn@umich.edu ymax = 0 4161049Sbinkertn@umich.edu for x in self.cursor.fetchall(): 4171049Sbinkertn@umich.edu data = Data(x) 4181049Sbinkertn@umich.edu if not runs.has_key(data.run): 4191049Sbinkertn@umich.edu runs[data.run] = {} 4201049Sbinkertn@umich.edu if not runs[data.run].has_key(data.x): 4211049Sbinkertn@umich.edu runs[data.run][data.x] = {} 4221049Sbinkertn@umich.edu 4231929Sbinkertn@umich.edu xmax = max(xmax, data.x) 4241929Sbinkertn@umich.edu ymax = max(ymax, data.y) 4251049Sbinkertn@umich.edu runs[data.run][data.x][data.y] = data.data 4261929Sbinkertn@umich.edu 4271929Sbinkertn@umich.edu results = Result(xmax + 1, ymax + 1) 4281929Sbinkertn@umich.edu for run,data in runs.iteritems(): 4291929Sbinkertn@umich.edu result = results[run] 4301929Sbinkertn@umich.edu for x,ydata in data.iteritems(): 4311929Sbinkertn@umich.edu for y,data in ydata.iteritems(): 4321929Sbinkertn@umich.edu result[x][y] = data 4331929Sbinkertn@umich.edu return results 4341881Sbinkertn@umich.edu 4351881Sbinkertn@umich.edu def __getitem__(self, key): 4361881Sbinkertn@umich.edu return self.stattop[key] 437