db.py revision 2183:4420c8fadbf5
17322Sgblack@eecs.umich.edu# Copyright (c) 2003-2004 The Regents of The University of Michigan 27322Sgblack@eecs.umich.edu# All rights reserved. 37322Sgblack@eecs.umich.edu# 47322Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 57322Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are 67322Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright 77322Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 87322Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 97322Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 107322Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution; 117322Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its 127322Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 137322Sgblack@eecs.umich.edu# this software without specific prior written permission. 147322Sgblack@eecs.umich.edu# 157322Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 167322Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 177322Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 187322Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 197322Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 207322Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 217322Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 227322Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 237322Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 247322Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 257322Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 267322Sgblack@eecs.umich.edu 277322Sgblack@eecs.umich.eduimport MySQLdb, re, string 287322Sgblack@eecs.umich.edu 297322Sgblack@eecs.umich.edudef statcmp(a, b): 307322Sgblack@eecs.umich.edu v1 = a.split('.') 317322Sgblack@eecs.umich.edu v2 = b.split('.') 327322Sgblack@eecs.umich.edu 337322Sgblack@eecs.umich.edu last = min(len(v1), len(v2)) - 1 347322Sgblack@eecs.umich.edu for i,j in zip(v1[0:last], v2[0:last]): 357322Sgblack@eecs.umich.edu if i != j: 367322Sgblack@eecs.umich.edu return cmp(i, j) 377322Sgblack@eecs.umich.edu 387322Sgblack@eecs.umich.edu # Special compare for last element. 397322Sgblack@eecs.umich.edu if len(v1) == len(v2): 407376Sgblack@eecs.umich.edu return cmp(v1[last], v2[last]) 417376Sgblack@eecs.umich.edu else: 427376Sgblack@eecs.umich.edu return cmp(len(v1), len(v2)) 437376Sgblack@eecs.umich.edu 447376Sgblack@eecs.umich.educlass RunData: 457376Sgblack@eecs.umich.edu def __init__(self, row): 467376Sgblack@eecs.umich.edu self.run = int(row[0]) 477376Sgblack@eecs.umich.edu self.name = row[1] 487376Sgblack@eecs.umich.edu self.user = row[2] 497376Sgblack@eecs.umich.edu self.project = row[3] 507376Sgblack@eecs.umich.edu 517376Sgblack@eecs.umich.educlass SubData: 527376Sgblack@eecs.umich.edu def __init__(self, row): 537376Sgblack@eecs.umich.edu self.stat = int(row[0]) 547376Sgblack@eecs.umich.edu self.x = int(row[1]) 557376Sgblack@eecs.umich.edu self.y = int(row[2]) 567376Sgblack@eecs.umich.edu self.name = row[3] 577376Sgblack@eecs.umich.edu self.descr = row[4] 587376Sgblack@eecs.umich.edu 597376Sgblack@eecs.umich.educlass Data: 607376Sgblack@eecs.umich.edu def __init__(self, row): 617376Sgblack@eecs.umich.edu if len(row) != 5: 627376Sgblack@eecs.umich.edu raise 'stat db error' 637376Sgblack@eecs.umich.edu self.stat = int(row[0]) 647376Sgblack@eecs.umich.edu self.run = int(row[1]) 657376Sgblack@eecs.umich.edu self.x = int(row[2]) 667376Sgblack@eecs.umich.edu self.y = int(row[3]) 677376Sgblack@eecs.umich.edu self.data = float(row[4]) 687376Sgblack@eecs.umich.edu 697376Sgblack@eecs.umich.edu def __repr__(self): 707376Sgblack@eecs.umich.edu return '''Data(['%d', '%d', '%d', '%d', '%f'])''' % ( self.stat, 717376Sgblack@eecs.umich.edu self.run, self.x, self.y, self.data) 727376Sgblack@eecs.umich.edu 737376Sgblack@eecs.umich.educlass StatData(object): 747376Sgblack@eecs.umich.edu def __init__(self, row): 757376Sgblack@eecs.umich.edu self.stat = int(row[0]) 767376Sgblack@eecs.umich.edu self.name = row[1] 777376Sgblack@eecs.umich.edu self.desc = row[2] 787376Sgblack@eecs.umich.edu self.type = row[3] 797376Sgblack@eecs.umich.edu self.prereq = int(row[5]) 807376Sgblack@eecs.umich.edu self.precision = int(row[6]) 817376Sgblack@eecs.umich.edu 827376Sgblack@eecs.umich.edu import flags 837376Sgblack@eecs.umich.edu self.flags = 0 847376Sgblack@eecs.umich.edu if int(row[4]): self.flags |= flags.printable 857376Sgblack@eecs.umich.edu if int(row[7]): self.flags |= flags.nozero 867376Sgblack@eecs.umich.edu if int(row[8]): self.flags |= flags.nonan 877376Sgblack@eecs.umich.edu if int(row[9]): self.flags |= flags.total 887376Sgblack@eecs.umich.edu if int(row[10]): self.flags |= flags.pdf 897376Sgblack@eecs.umich.edu if int(row[11]): self.flags |= flags.cdf 907376Sgblack@eecs.umich.edu 917376Sgblack@eecs.umich.edu if self.type == 'DIST' or self.type == 'VECTORDIST': 927376Sgblack@eecs.umich.edu self.min = float(row[12]) 937376Sgblack@eecs.umich.edu self.max = float(row[13]) 947376Sgblack@eecs.umich.edu self.bktsize = float(row[14]) 957376Sgblack@eecs.umich.edu self.size = int(row[15]) 967376Sgblack@eecs.umich.edu 977376Sgblack@eecs.umich.edu if self.type == 'FORMULA': 987376Sgblack@eecs.umich.edu self.formula = self.db.allFormulas[self.stat] 997376Sgblack@eecs.umich.edu 1007376Sgblack@eecs.umich.educlass Node(object): 1017376Sgblack@eecs.umich.edu def __init__(self, name): 1027376Sgblack@eecs.umich.edu self.name = name 1037376Sgblack@eecs.umich.edu def __str__(self): 1047376Sgblack@eecs.umich.edu return self.name 1057376Sgblack@eecs.umich.edu 1067376Sgblack@eecs.umich.educlass Result(object): 1077376Sgblack@eecs.umich.edu def __init__(self, x, y): 1087376Sgblack@eecs.umich.edu self.data = {} 1097376Sgblack@eecs.umich.edu self.x = x 1107376Sgblack@eecs.umich.edu self.y = y 1117376Sgblack@eecs.umich.edu 1127376Sgblack@eecs.umich.edu def __contains__(self, run): 1137376Sgblack@eecs.umich.edu return run in self.data 1147376Sgblack@eecs.umich.edu 1157376Sgblack@eecs.umich.edu def __getitem__(self, run): 1167376Sgblack@eecs.umich.edu if run not in self.data: 1177376Sgblack@eecs.umich.edu self.data[run] = [ [ 0.0 ] * self.y for i in xrange(self.x) ] 1187376Sgblack@eecs.umich.edu return self.data[run] 1197376Sgblack@eecs.umich.edu 1207376Sgblack@eecs.umich.educlass Database(object): 1217376Sgblack@eecs.umich.edu def __init__(self): 1227376Sgblack@eecs.umich.edu self.host = 'zizzer.pool' 1237376Sgblack@eecs.umich.edu self.user = '' 1247376Sgblack@eecs.umich.edu self.passwd = '' 1257376Sgblack@eecs.umich.edu self.db = 'm5stats' 1267376Sgblack@eecs.umich.edu self.cursor = None 1277376Sgblack@eecs.umich.edu 1287376Sgblack@eecs.umich.edu self.allStats = [] 1297376Sgblack@eecs.umich.edu self.allStatIds = {} 1307376Sgblack@eecs.umich.edu self.allStatNames = {} 1317376Sgblack@eecs.umich.edu 1327376Sgblack@eecs.umich.edu self.allSubData = {} 1337376Sgblack@eecs.umich.edu 1347376Sgblack@eecs.umich.edu self.allRuns = [] 1357376Sgblack@eecs.umich.edu self.allRunIds = {} 1367376Sgblack@eecs.umich.edu self.allRunNames = {} 1377376Sgblack@eecs.umich.edu 1387376Sgblack@eecs.umich.edu self.allBins = [] 1397376Sgblack@eecs.umich.edu self.allBinIds = {} 1407376Sgblack@eecs.umich.edu self.allBinNames = {} 1417376Sgblack@eecs.umich.edu 1427376Sgblack@eecs.umich.edu self.allFormulas = {} 1437376Sgblack@eecs.umich.edu 1447376Sgblack@eecs.umich.edu self.stattop = {} 1457376Sgblack@eecs.umich.edu self.statdict = {} 1467376Sgblack@eecs.umich.edu self.statlist = [] 1477376Sgblack@eecs.umich.edu 1487376Sgblack@eecs.umich.edu self.mode = 'sum'; 1497376Sgblack@eecs.umich.edu self.runs = None 1507376Sgblack@eecs.umich.edu self.bins = None 1517376Sgblack@eecs.umich.edu self.ticks = None 1527376Sgblack@eecs.umich.edu self.method = 'sum' 1537376Sgblack@eecs.umich.edu self._method = type(self).sum 1547376Sgblack@eecs.umich.edu 1557376Sgblack@eecs.umich.edu def get(self, job, stat, system=None): 1567376Sgblack@eecs.umich.edu run = self.allRunNames.get(str(job), None) 1577376Sgblack@eecs.umich.edu if run is None: 1587376Sgblack@eecs.umich.edu return None 1597376Sgblack@eecs.umich.edu 1607376Sgblack@eecs.umich.edu from info import ProxyError, scalar, vector, value, values, total, len 1617376Sgblack@eecs.umich.edu if system is None and hasattr(job, 'system'): 1627376Sgblack@eecs.umich.edu system = job.system 1637376Sgblack@eecs.umich.edu 1647376Sgblack@eecs.umich.edu if system is not None: 1657376Sgblack@eecs.umich.edu stat.system = self[system] 1667376Sgblack@eecs.umich.edu try: 1677376Sgblack@eecs.umich.edu if scalar(stat): 1687376Sgblack@eecs.umich.edu return value(stat, run.run) 1697376Sgblack@eecs.umich.edu if vector(stat): 1707376Sgblack@eecs.umich.edu return values(stat, run.run) 1717376Sgblack@eecs.umich.edu except ProxyError: 1727376Sgblack@eecs.umich.edu return None 1737376Sgblack@eecs.umich.edu 1747376Sgblack@eecs.umich.edu return None 1757376Sgblack@eecs.umich.edu 1767376Sgblack@eecs.umich.edu def query(self, sql): 1777376Sgblack@eecs.umich.edu self.cursor.execute(sql) 1787376Sgblack@eecs.umich.edu 1797376Sgblack@eecs.umich.edu def update_dict(self, dict): 1807376Sgblack@eecs.umich.edu dict.update(self.stattop) 1817376Sgblack@eecs.umich.edu 1827376Sgblack@eecs.umich.edu def append(self, stat): 1837376Sgblack@eecs.umich.edu statname = re.sub(':', '__', stat.name) 1847376Sgblack@eecs.umich.edu path = string.split(statname, '.') 1857376Sgblack@eecs.umich.edu pathtop = path[0] 1867376Sgblack@eecs.umich.edu fullname = '' 1877376Sgblack@eecs.umich.edu 1887322Sgblack@eecs.umich.edu x = self 1897322Sgblack@eecs.umich.edu while len(path) > 1: 1907322Sgblack@eecs.umich.edu name = path.pop(0) 1917322Sgblack@eecs.umich.edu if not x.__dict__.has_key(name): 1927322Sgblack@eecs.umich.edu x.__dict__[name] = Node(fullname + name) 1937322Sgblack@eecs.umich.edu x = x.__dict__[name] 1947396Sgblack@eecs.umich.edu fullname = '%s%s.' % (fullname, name) 1957322Sgblack@eecs.umich.edu 1967322Sgblack@eecs.umich.edu name = path.pop(0) 1977396Sgblack@eecs.umich.edu x.__dict__[name] = stat 1987396Sgblack@eecs.umich.edu 1997322Sgblack@eecs.umich.edu self.stattop[pathtop] = self.__dict__[pathtop] 2007324Sgblack@eecs.umich.edu self.statdict[statname] = stat 2017396Sgblack@eecs.umich.edu self.statlist.append(statname) 2027324Sgblack@eecs.umich.edu 2037324Sgblack@eecs.umich.edu def connect(self): 2047396Sgblack@eecs.umich.edu # connect 2057396Sgblack@eecs.umich.edu self.thedb = MySQLdb.connect(db=self.db, 2067324Sgblack@eecs.umich.edu host=self.host, 2077333Sgblack@eecs.umich.edu user=self.user, 2087392Sgblack@eecs.umich.edu passwd=self.passwd) 2097396Sgblack@eecs.umich.edu 2107392Sgblack@eecs.umich.edu # create a cursor 2117392Sgblack@eecs.umich.edu self.cursor = self.thedb.cursor() 2127396Sgblack@eecs.umich.edu 2137396Sgblack@eecs.umich.edu self.query('''select rn_id,rn_name,rn_sample,rn_user,rn_project 2147392Sgblack@eecs.umich.edu from runs''') 2157392Sgblack@eecs.umich.edu for result in self.cursor.fetchall(): 2167333Sgblack@eecs.umich.edu run = RunData(result); 2177333Sgblack@eecs.umich.edu self.allRuns.append(run) 2187333Sgblack@eecs.umich.edu self.allRunIds[run.run] = run 2197396Sgblack@eecs.umich.edu self.allRunNames[run.name] = run 2207333Sgblack@eecs.umich.edu 2217333Sgblack@eecs.umich.edu self.query('select * from bins') 2227396Sgblack@eecs.umich.edu for id,name in self.cursor.fetchall(): 2237396Sgblack@eecs.umich.edu self.allBinIds[int(id)] = name 2247333Sgblack@eecs.umich.edu self.allBinNames[name] = int(id) 2257333Sgblack@eecs.umich.edu 2267333Sgblack@eecs.umich.edu self.query('select sd_stat,sd_x,sd_y,sd_name,sd_descr from subdata') 2277333Sgblack@eecs.umich.edu for result in self.cursor.fetchall(): 2287333Sgblack@eecs.umich.edu subdata = SubData(result) 2297333Sgblack@eecs.umich.edu if self.allSubData.has_key(subdata.stat): 2307396Sgblack@eecs.umich.edu self.allSubData[subdata.stat].append(subdata) 2317333Sgblack@eecs.umich.edu else: 2327333Sgblack@eecs.umich.edu self.allSubData[subdata.stat] = [ subdata ] 2337396Sgblack@eecs.umich.edu 2347396Sgblack@eecs.umich.edu self.query('select * from formulas') 2357333Sgblack@eecs.umich.edu for id,formula in self.cursor.fetchall(): 2367333Sgblack@eecs.umich.edu self.allFormulas[int(id)] = formula.tostring() 2377333Sgblack@eecs.umich.edu 2387333Sgblack@eecs.umich.edu StatData.db = self 2397333Sgblack@eecs.umich.edu self.query('select * from stats') 2407333Sgblack@eecs.umich.edu import info 2417333Sgblack@eecs.umich.edu for result in self.cursor.fetchall(): 2427333Sgblack@eecs.umich.edu stat = info.NewStat(self, StatData(result)) 2437396Sgblack@eecs.umich.edu self.append(stat) 2447333Sgblack@eecs.umich.edu self.allStats.append(stat) 2457333Sgblack@eecs.umich.edu self.allStatIds[stat.stat] = stat 2467396Sgblack@eecs.umich.edu self.allStatNames[stat.name] = stat 2477396Sgblack@eecs.umich.edu 2487333Sgblack@eecs.umich.edu # Name: listbins 2497333Sgblack@eecs.umich.edu # Desc: Prints all bins matching regex argument, if no argument 2507333Sgblack@eecs.umich.edu # is given all bins are returned 2517333Sgblack@eecs.umich.edu def listBins(self, regex='.*'): 2527333Sgblack@eecs.umich.edu print '%-50s %-10s' % ('bin name', 'id') 2537396Sgblack@eecs.umich.edu print '-' * 61 2547333Sgblack@eecs.umich.edu names = self.allBinNames.keys() 2557333Sgblack@eecs.umich.edu names.sort() 2567396Sgblack@eecs.umich.edu for name in names: 2577396Sgblack@eecs.umich.edu id = self.allBinNames[name] 2587333Sgblack@eecs.umich.edu print '%-50s %-10d' % (name, id) 2597333Sgblack@eecs.umich.edu 2607333Sgblack@eecs.umich.edu # Name: listruns 2617333Sgblack@eecs.umich.edu # Desc: Prints all runs matching a given user, if no argument 2627333Sgblack@eecs.umich.edu # is given all runs are returned 2637333Sgblack@eecs.umich.edu def listRuns(self, user=None): 2647396Sgblack@eecs.umich.edu print '%-40s %-10s %-5s' % ('run name', 'user', 'id') 2657333Sgblack@eecs.umich.edu print '-' * 62 2667333Sgblack@eecs.umich.edu for run in self.allRuns: 2677396Sgblack@eecs.umich.edu if user == None or user == run.user: 2687396Sgblack@eecs.umich.edu print '%-40s %-10s %-10d' % (run.name, run.user, run.run) 2697333Sgblack@eecs.umich.edu 2707333Sgblack@eecs.umich.edu # Name: listTicks 2717333Sgblack@eecs.umich.edu # Desc: Prints all samples for a given run 2727333Sgblack@eecs.umich.edu def listTicks(self, runs=None): 2737333Sgblack@eecs.umich.edu print "tick" 2747333Sgblack@eecs.umich.edu print "----------------------------------------" 2757333Sgblack@eecs.umich.edu sql = 'select distinct dt_tick from data where dt_stat=1180 and (' 2767333Sgblack@eecs.umich.edu if runs != None: 2777396Sgblack@eecs.umich.edu first = True 2787333Sgblack@eecs.umich.edu for run in runs: 2797333Sgblack@eecs.umich.edu if first: 2807396Sgblack@eecs.umich.edu # sql += ' where' 2817396Sgblack@eecs.umich.edu first = False 2827333Sgblack@eecs.umich.edu else: 2837333Sgblack@eecs.umich.edu sql += ' or' 2847333Sgblack@eecs.umich.edu sql += ' dt_run=%s' % run.run 2857333Sgblack@eecs.umich.edu sql += ')' 2867333Sgblack@eecs.umich.edu self.query(sql) 2877396Sgblack@eecs.umich.edu for r in self.cursor.fetchall(): 2887333Sgblack@eecs.umich.edu print r[0] 2897333Sgblack@eecs.umich.edu 2907396Sgblack@eecs.umich.edu # Name: retTicks 2917396Sgblack@eecs.umich.edu # Desc: Prints all samples for a given run 2927333Sgblack@eecs.umich.edu def retTicks(self, runs=None): 2937333Sgblack@eecs.umich.edu sql = 'select distinct dt_tick from data where dt_stat=1180 and (' 2947333Sgblack@eecs.umich.edu if runs != None: 2957333Sgblack@eecs.umich.edu first = True 2967333Sgblack@eecs.umich.edu for run in runs: 2977396Sgblack@eecs.umich.edu if first: 2987333Sgblack@eecs.umich.edu first = False 2997333Sgblack@eecs.umich.edu else: 3007396Sgblack@eecs.umich.edu sql += ' or' 3017396Sgblack@eecs.umich.edu sql += ' dt_run=%s' % run.run 3027333Sgblack@eecs.umich.edu sql += ')' 3037333Sgblack@eecs.umich.edu self.query(sql) 3047333Sgblack@eecs.umich.edu ret = [] 3057333Sgblack@eecs.umich.edu for r in self.cursor.fetchall(): 3067333Sgblack@eecs.umich.edu ret.append(r[0]) 3077396Sgblack@eecs.umich.edu return ret 3087333Sgblack@eecs.umich.edu 3097333Sgblack@eecs.umich.edu # Name: liststats 3107396Sgblack@eecs.umich.edu # Desc: Prints all statistics that appear in the database, 3117396Sgblack@eecs.umich.edu # the optional argument is a regular expression that can 3127333Sgblack@eecs.umich.edu # be used to prune the result set 3137333Sgblack@eecs.umich.edu def listStats(self, regex=None): 3147333Sgblack@eecs.umich.edu print '%-60s %-8s %-10s' % ('stat name', 'id', 'type') 3157333Sgblack@eecs.umich.edu print '-' * 80 3167333Sgblack@eecs.umich.edu 3177396Sgblack@eecs.umich.edu rx = None 3187333Sgblack@eecs.umich.edu if regex != None: 3197333Sgblack@eecs.umich.edu rx = re.compile(regex) 3207396Sgblack@eecs.umich.edu 3217396Sgblack@eecs.umich.edu stats = [ stat.name for stat in self.allStats ] 3227333Sgblack@eecs.umich.edu stats.sort(statcmp) 3237333Sgblack@eecs.umich.edu for stat in stats: 3247333Sgblack@eecs.umich.edu stat = self.allStatNames[stat] 3257333Sgblack@eecs.umich.edu if rx == None or rx.match(stat.name): 3267333Sgblack@eecs.umich.edu print '%-60s %-8s %-10s' % (stat.name, stat.stat, stat.type) 3277396Sgblack@eecs.umich.edu 3287333Sgblack@eecs.umich.edu # Name: liststats 3297333Sgblack@eecs.umich.edu # Desc: Prints all statistics that appear in the database, 3307396Sgblack@eecs.umich.edu # the optional argument is a regular expression that can 3317396Sgblack@eecs.umich.edu # be used to prune the result set 3327333Sgblack@eecs.umich.edu def listFormulas(self, regex=None): 3337333Sgblack@eecs.umich.edu print '%-60s %s' % ('formula name', 'formula') 3347333Sgblack@eecs.umich.edu print '-' * 80 3357333Sgblack@eecs.umich.edu 3367333Sgblack@eecs.umich.edu rx = None 3377396Sgblack@eecs.umich.edu if regex != None: 3387333Sgblack@eecs.umich.edu rx = re.compile(regex) 3397333Sgblack@eecs.umich.edu 3407396Sgblack@eecs.umich.edu stats = [ stat.name for stat in self.allStats ] 3417396Sgblack@eecs.umich.edu stats.sort(statcmp) 3427333Sgblack@eecs.umich.edu for stat in stats: 3437333Sgblack@eecs.umich.edu stat = self.allStatNames[stat] 3447333Sgblack@eecs.umich.edu if stat.type == 'FORMULA' and (rx == None or rx.match(stat.name)): 3457333Sgblack@eecs.umich.edu print '%-60s %s' % (stat.name, self.allFormulas[stat.stat]) 3467333Sgblack@eecs.umich.edu 3477396Sgblack@eecs.umich.edu def getStat(self, stats): 3487333Sgblack@eecs.umich.edu if type(stats) is not list: 3497333Sgblack@eecs.umich.edu stats = [ stats ] 3507396Sgblack@eecs.umich.edu 3517396Sgblack@eecs.umich.edu ret = [] 3527333Sgblack@eecs.umich.edu for stat in stats: 3537333Sgblack@eecs.umich.edu if type(stat) is int: 3547333Sgblack@eecs.umich.edu ret.append(self.allStatIds[stat]) 3557333Sgblack@eecs.umich.edu 3567333Sgblack@eecs.umich.edu if type(stat) is str: 3577396Sgblack@eecs.umich.edu rx = re.compile(stat) 3587333Sgblack@eecs.umich.edu for stat in self.allStats: 3597333Sgblack@eecs.umich.edu if rx.match(stat.name): 3607396Sgblack@eecs.umich.edu ret.append(stat) 3617396Sgblack@eecs.umich.edu return ret 3627333Sgblack@eecs.umich.edu 3637333Sgblack@eecs.umich.edu def getBin(self, bins): 3647333Sgblack@eecs.umich.edu if type(bins) is not list: 3657333Sgblack@eecs.umich.edu bins = [ bins ] 3667333Sgblack@eecs.umich.edu 3677333Sgblack@eecs.umich.edu ret = [] 3687396Sgblack@eecs.umich.edu for bin in bins: 3697333Sgblack@eecs.umich.edu if type(bin) is int: 3707333Sgblack@eecs.umich.edu ret.append(bin) 3717396Sgblack@eecs.umich.edu elif type(bin) is str: 3727396Sgblack@eecs.umich.edu ret.append(self.allBinNames[bin]) 3737333Sgblack@eecs.umich.edu else: 3747333Sgblack@eecs.umich.edu for name,id in self.allBinNames.items(): 3757333Sgblack@eecs.umich.edu if bin.match(name): 3767333Sgblack@eecs.umich.edu ret.append(id) 3777333Sgblack@eecs.umich.edu 3787333Sgblack@eecs.umich.edu return ret 3797396Sgblack@eecs.umich.edu 3807333Sgblack@eecs.umich.edu def getNotBin(self, bin): 3817333Sgblack@eecs.umich.edu map = {} 3827396Sgblack@eecs.umich.edu for bin in getBin(bin): 3837396Sgblack@eecs.umich.edu map[bin] = 1 3847333Sgblack@eecs.umich.edu 3857381Sgblack@eecs.umich.edu ret = [] 3867381Sgblack@eecs.umich.edu for bin in self.allBinIds.keys(): 3877381Sgblack@eecs.umich.edu if not map.has_key(bin): 3887381Sgblack@eecs.umich.edu ret.append(bin) 3897381Sgblack@eecs.umich.edu 3907381Sgblack@eecs.umich.edu return ret 3917381Sgblack@eecs.umich.edu 3927364Sgblack@eecs.umich.edu ######################################### 3937396Sgblack@eecs.umich.edu # get the data 3947396Sgblack@eecs.umich.edu # 3957396Sgblack@eecs.umich.edu def inner(self, op, stat, bins, ticks, group=False): 3967396Sgblack@eecs.umich.edu sql = 'select ' 3977364Sgblack@eecs.umich.edu sql += 'dt_stat as stat, ' 3987396Sgblack@eecs.umich.edu sql += 'dt_run as run, ' 3997396Sgblack@eecs.umich.edu sql += 'dt_x as x, ' 4007396Sgblack@eecs.umich.edu sql += 'dt_y as y, ' 4017396Sgblack@eecs.umich.edu if group: 4027396Sgblack@eecs.umich.edu sql += 'dt_tick as tick, ' 4037396Sgblack@eecs.umich.edu sql += '%s(dt_data) as data ' % op 4047396Sgblack@eecs.umich.edu sql += 'from data ' 4057396Sgblack@eecs.umich.edu sql += 'where ' 4067396Sgblack@eecs.umich.edu 4077396Sgblack@eecs.umich.edu if isinstance(stat, list): 4087396Sgblack@eecs.umich.edu val = ' or '.join([ 'dt_stat=%d' % s.stat for s in stat ]) 4097396Sgblack@eecs.umich.edu sql += ' (%s)' % val 4107396Sgblack@eecs.umich.edu else: 4117396Sgblack@eecs.umich.edu sql += ' dt_stat=%d' % stat.stat 4127396Sgblack@eecs.umich.edu 4137396Sgblack@eecs.umich.edu if self.runs != None and len(self.runs): 4147396Sgblack@eecs.umich.edu val = ' or '.join([ 'dt_run=%d' % r for r in self.runs ]) 4157396Sgblack@eecs.umich.edu sql += ' and (%s)' % val 4167396Sgblack@eecs.umich.edu 4177364Sgblack@eecs.umich.edu if bins != None and len(bins): 4187396Sgblack@eecs.umich.edu val = ' or '.join([ 'dt_bin=%d' % b for b in bins ]) 4197396Sgblack@eecs.umich.edu sql += ' and (%s)' % val 4207365Sgblack@eecs.umich.edu 4217396Sgblack@eecs.umich.edu if ticks != None and len(ticks): 4227396Sgblack@eecs.umich.edu val = ' or '.join([ 'dt_tick=%d' % s for s in ticks ]) 4237396Sgblack@eecs.umich.edu sql += ' and (%s)' % val 4247396Sgblack@eecs.umich.edu 4257396Sgblack@eecs.umich.edu sql += ' group by dt_stat,dt_run,dt_x,dt_y' 4267396Sgblack@eecs.umich.edu if group: 4277396Sgblack@eecs.umich.edu sql += ',dt_tick' 4287396Sgblack@eecs.umich.edu return sql 4297365Sgblack@eecs.umich.edu 4307396Sgblack@eecs.umich.edu def outer(self, op_out, op_in, stat, bins, ticks): 4317396Sgblack@eecs.umich.edu sql = self.inner(op_in, stat, bins, ticks, True) 4327366Sgblack@eecs.umich.edu sql = 'select stat,run,x,y,%s(data) from (%s) as tb ' % (op_out, sql) 4337396Sgblack@eecs.umich.edu sql += 'group by stat,run,x,y' 4347396Sgblack@eecs.umich.edu return sql 4357396Sgblack@eecs.umich.edu 4367396Sgblack@eecs.umich.edu # Name: sum 4377366Sgblack@eecs.umich.edu # Desc: given a run, a stat and an array of samples and bins, 4387396Sgblack@eecs.umich.edu # sum all the bins and then get the standard deviation of the 4397396Sgblack@eecs.umich.edu # samples for non-binned runs. This will just return the average 4407396Sgblack@eecs.umich.edu # of samples, however a bin array still must be passed 4417396Sgblack@eecs.umich.edu def sum(self, stat, bins, ticks): 4427367Sgblack@eecs.umich.edu return self.inner('sum', stat, bins, ticks) 4437396Sgblack@eecs.umich.edu 4447396Sgblack@eecs.umich.edu # Name: avg 4457396Sgblack@eecs.umich.edu # Desc: given a run, a stat and an array of samples and bins, 4467396Sgblack@eecs.umich.edu # sum all the bins and then average the samples for non-binned 4477367Sgblack@eecs.umich.edu # runs this will just return the average of samples, however 4487396Sgblack@eecs.umich.edu # a bin array still must be passed 4497396Sgblack@eecs.umich.edu def avg(self, stat, bins, ticks): 4507396Sgblack@eecs.umich.edu return self.outer('avg', 'sum', stat, bins, ticks) 4517396Sgblack@eecs.umich.edu 4527396Sgblack@eecs.umich.edu # Name: stdev 4537396Sgblack@eecs.umich.edu # Desc: given a run, a stat and an array of samples and bins, 4547396Sgblack@eecs.umich.edu # sum all the bins and then get the standard deviation of the 4557396Sgblack@eecs.umich.edu # samples for non-binned runs. This will just return the average 4567368Sgblack@eecs.umich.edu # of samples, however a bin array still must be passed 4577396Sgblack@eecs.umich.edu def stdev(self, stat, bins, ticks): 4587396Sgblack@eecs.umich.edu return self.outer('stddev', 'sum', stat, bins, ticks) 4597368Sgblack@eecs.umich.edu 4607396Sgblack@eecs.umich.edu def __setattr__(self, attr, value): 4617396Sgblack@eecs.umich.edu super(Database, self).__setattr__(attr, value) 4627396Sgblack@eecs.umich.edu if attr != 'method': 4637396Sgblack@eecs.umich.edu return 4647369Sgblack@eecs.umich.edu 4657396Sgblack@eecs.umich.edu if value == 'sum': 4667369Sgblack@eecs.umich.edu self._method = self.sum 4677396Sgblack@eecs.umich.edu elif value == 'avg': 4687396Sgblack@eecs.umich.edu self._method = self.avg 4697396Sgblack@eecs.umich.edu elif value == 'stdev': 4707396Sgblack@eecs.umich.edu self._method = self.stdev 4717369Sgblack@eecs.umich.edu else: 4727396Sgblack@eecs.umich.edu raise AttributeError, "can only set get to: sum | avg | stdev" 4737396Sgblack@eecs.umich.edu 4747396Sgblack@eecs.umich.edu def data(self, stat, bins=None, ticks=None): 4757396Sgblack@eecs.umich.edu if bins is None: 4767396Sgblack@eecs.umich.edu bins = self.bins 4777396Sgblack@eecs.umich.edu if ticks is None: 4787369Sgblack@eecs.umich.edu ticks = self.ticks 4797396Sgblack@eecs.umich.edu sql = self._method(self, stat, bins, ticks) 4807396Sgblack@eecs.umich.edu self.query(sql) 4817396Sgblack@eecs.umich.edu 4827396Sgblack@eecs.umich.edu runs = {} 4837396Sgblack@eecs.umich.edu xmax = 0 4847396Sgblack@eecs.umich.edu ymax = 0 4857396Sgblack@eecs.umich.edu for x in self.cursor.fetchall(): 4867396Sgblack@eecs.umich.edu data = Data(x) 4877396Sgblack@eecs.umich.edu if not runs.has_key(data.run): 4887396Sgblack@eecs.umich.edu runs[data.run] = {} 4897396Sgblack@eecs.umich.edu if not runs[data.run].has_key(data.x): 4907396Sgblack@eecs.umich.edu runs[data.run][data.x] = {} 4917381Sgblack@eecs.umich.edu 4927381Sgblack@eecs.umich.edu xmax = max(xmax, data.x) 4937381Sgblack@eecs.umich.edu ymax = max(ymax, data.y) 4947381Sgblack@eecs.umich.edu runs[data.run][data.x][data.y] = data.data 4957381Sgblack@eecs.umich.edu 4967381Sgblack@eecs.umich.edu results = Result(xmax + 1, ymax + 1) 4977381Sgblack@eecs.umich.edu for run,data in runs.iteritems(): 4987370Sgblack@eecs.umich.edu result = results[run] 4997370Sgblack@eecs.umich.edu for x,ydata in data.iteritems(): 5007396Sgblack@eecs.umich.edu for y,data in ydata.iteritems(): 5017396Sgblack@eecs.umich.edu result[x][y] = data 5027396Sgblack@eecs.umich.edu return results 5037396Sgblack@eecs.umich.edu 5047396Sgblack@eecs.umich.edu def __getitem__(self, key): 5057370Sgblack@eecs.umich.edu return self.stattop[key] 5067396Sgblack@eecs.umich.edu