db.py revision 1306
11049Sbinkertn@umich.eduimport MySQLdb, re, string 21049Sbinkertn@umich.edu 31049Sbinkertn@umich.edudef statcmp(a, b): 41049Sbinkertn@umich.edu v1 = a.split('.') 51049Sbinkertn@umich.edu v2 = b.split('.') 61049Sbinkertn@umich.edu 71049Sbinkertn@umich.edu last = min(len(v1), len(v2)) - 1 81049Sbinkertn@umich.edu for i,j in zip(v1[0:last], v2[0:last]): 91049Sbinkertn@umich.edu if i != j: 101049Sbinkertn@umich.edu return cmp(i, j) 111049Sbinkertn@umich.edu 121049Sbinkertn@umich.edu # Special compare for last element. 131049Sbinkertn@umich.edu if len(v1) == len(v2): 141049Sbinkertn@umich.edu return cmp(v1[last], v2[last]) 151049Sbinkertn@umich.edu else: 161049Sbinkertn@umich.edu return cmp(len(v1), len(v2)) 171049Sbinkertn@umich.edu 181049Sbinkertn@umich.educlass RunData: 191049Sbinkertn@umich.edu def __init__(self, row): 201049Sbinkertn@umich.edu self.run = int(row[0]) 211049Sbinkertn@umich.edu self.name = row[1] 221049Sbinkertn@umich.edu self.user = row[2] 231049Sbinkertn@umich.edu self.project = row[3] 241049Sbinkertn@umich.edu 251049Sbinkertn@umich.educlass SubData: 261049Sbinkertn@umich.edu def __init__(self, row): 271049Sbinkertn@umich.edu self.stat = int(row[0]) 281049Sbinkertn@umich.edu self.x = int(row[1]) 291049Sbinkertn@umich.edu self.y = int(row[2]) 301049Sbinkertn@umich.edu self.name = row[3] 311049Sbinkertn@umich.edu self.descr = row[4] 321049Sbinkertn@umich.edu 331049Sbinkertn@umich.educlass Data: 341049Sbinkertn@umich.edu def __init__(self, row): 351049Sbinkertn@umich.edu if len(row) != 5: 361049Sbinkertn@umich.edu raise 'stat db error' 371049Sbinkertn@umich.edu self.stat = int(row[0]) 381049Sbinkertn@umich.edu self.run = int(row[1]) 391049Sbinkertn@umich.edu self.x = int(row[2]) 401049Sbinkertn@umich.edu self.y = int(row[3]) 411049Sbinkertn@umich.edu self.data = float(row[4]) 421049Sbinkertn@umich.edu 431049Sbinkertn@umich.edu def __repr__(self): 441049Sbinkertn@umich.edu return '''Data(['%d', '%d', '%d', '%d', '%f'])''' % ( self.stat, 451049Sbinkertn@umich.edu self.run, self.x, self.y, self.data) 461049Sbinkertn@umich.edu 471049Sbinkertn@umich.educlass StatData(object): 481049Sbinkertn@umich.edu def __init__(self, row): 491049Sbinkertn@umich.edu self.stat = int(row[0]) 501049Sbinkertn@umich.edu self.name = row[1] 511049Sbinkertn@umich.edu self.desc = row[2] 521049Sbinkertn@umich.edu self.type = row[3] 531049Sbinkertn@umich.edu self.prereq = int(row[5]) 541049Sbinkertn@umich.edu self.precision = int(row[6]) 551049Sbinkertn@umich.edu 561049Sbinkertn@umich.edu import flags 571049Sbinkertn@umich.edu self.flags = 0 581049Sbinkertn@umich.edu if int(row[4]): self.flags |= flags.printable 591049Sbinkertn@umich.edu if int(row[7]): self.flags |= flags.nozero 601049Sbinkertn@umich.edu if int(row[8]): self.flags |= flags.nonan 611049Sbinkertn@umich.edu if int(row[9]): self.flags |= flags.total 621049Sbinkertn@umich.edu if int(row[10]): self.flags |= flags.pdf 631049Sbinkertn@umich.edu if int(row[11]): self.flags |= flags.cdf 641049Sbinkertn@umich.edu 651049Sbinkertn@umich.edu if self.type == 'DIST' or self.type == 'VECTORDIST': 661049Sbinkertn@umich.edu self.min = float(row[12]) 671049Sbinkertn@umich.edu self.max = float(row[13]) 681049Sbinkertn@umich.edu self.bktsize = float(row[14]) 691049Sbinkertn@umich.edu self.size = int(row[15]) 701049Sbinkertn@umich.edu 711049Sbinkertn@umich.edu if self.type == 'FORMULA': 721049Sbinkertn@umich.edu self.formula = self.db.allFormulas[self.stat] 731049Sbinkertn@umich.edu 741049Sbinkertn@umich.educlass Node(object): 751049Sbinkertn@umich.edu def __init__(self, name): 761049Sbinkertn@umich.edu self.name = name 771049Sbinkertn@umich.edu def __str__(self): 781049Sbinkertn@umich.edu return name 791049Sbinkertn@umich.edu 801049Sbinkertn@umich.educlass Database(object): 811049Sbinkertn@umich.edu def __init__(self): 821049Sbinkertn@umich.edu self.host = 'zizzer.pool' 831049Sbinkertn@umich.edu self.user = '' 841049Sbinkertn@umich.edu self.passwd = '' 851049Sbinkertn@umich.edu self.db = 'm5stats' 861049Sbinkertn@umich.edu self.cursor = None 871049Sbinkertn@umich.edu 881049Sbinkertn@umich.edu self.allStats = [] 891049Sbinkertn@umich.edu self.allStatIds = {} 901049Sbinkertn@umich.edu self.allStatNames = {} 911049Sbinkertn@umich.edu 921049Sbinkertn@umich.edu self.allSubData = {} 931049Sbinkertn@umich.edu 941049Sbinkertn@umich.edu self.allRuns = [] 951049Sbinkertn@umich.edu self.allRunIds = {} 961049Sbinkertn@umich.edu self.allRunNames = {} 971049Sbinkertn@umich.edu 981049Sbinkertn@umich.edu self.allBins = [] 991049Sbinkertn@umich.edu self.allBinIds = {} 1001049Sbinkertn@umich.edu self.allBinNames = {} 1011049Sbinkertn@umich.edu 1021049Sbinkertn@umich.edu self.allFormulas = {} 1031049Sbinkertn@umich.edu 1041049Sbinkertn@umich.edu self.stattop = {} 1051049Sbinkertn@umich.edu self.statdict = {} 1061049Sbinkertn@umich.edu self.statlist = [] 1071049Sbinkertn@umich.edu 1081049Sbinkertn@umich.edu self.mode = 'sum'; 1091049Sbinkertn@umich.edu self.runs = None 1101049Sbinkertn@umich.edu self.bins = None 1111049Sbinkertn@umich.edu self.ticks = None 1121049Sbinkertn@umich.edu self.__dict__['get'] = type(self).sum 1131049Sbinkertn@umich.edu 1141049Sbinkertn@umich.edu def query(self, sql): 1151049Sbinkertn@umich.edu self.cursor.execute(sql) 1161049Sbinkertn@umich.edu 1171049Sbinkertn@umich.edu def update_dict(self, dict): 1181049Sbinkertn@umich.edu dict.update(self.stattop) 1191049Sbinkertn@umich.edu 1201049Sbinkertn@umich.edu def append(self, stat): 1211049Sbinkertn@umich.edu statname = re.sub(':', '__', stat.name) 1221049Sbinkertn@umich.edu path = string.split(statname, '.') 1231049Sbinkertn@umich.edu pathtop = path[0] 1241049Sbinkertn@umich.edu fullname = '' 1251049Sbinkertn@umich.edu 1261049Sbinkertn@umich.edu x = self 1271049Sbinkertn@umich.edu while len(path) > 1: 1281049Sbinkertn@umich.edu name = path.pop(0) 1291049Sbinkertn@umich.edu if not x.__dict__.has_key(name): 1301049Sbinkertn@umich.edu x.__dict__[name] = Node(fullname + name) 1311049Sbinkertn@umich.edu x = x.__dict__[name] 1321049Sbinkertn@umich.edu fullname = '%s%s.' % (fullname, name) 1331049Sbinkertn@umich.edu 1341049Sbinkertn@umich.edu name = path.pop(0) 1351049Sbinkertn@umich.edu x.__dict__[name] = stat 1361049Sbinkertn@umich.edu 1371049Sbinkertn@umich.edu self.stattop[pathtop] = self.__dict__[pathtop] 1381049Sbinkertn@umich.edu self.statdict[statname] = stat 1391049Sbinkertn@umich.edu self.statlist.append(statname) 1401049Sbinkertn@umich.edu 1411049Sbinkertn@umich.edu def connect(self): 1421049Sbinkertn@umich.edu # connect 1431049Sbinkertn@umich.edu self.thedb = MySQLdb.connect(db=self.db, 1441049Sbinkertn@umich.edu host=self.host, 1451049Sbinkertn@umich.edu user=self.user, 1461049Sbinkertn@umich.edu passwd=self.passwd) 1471049Sbinkertn@umich.edu 1481049Sbinkertn@umich.edu # create a cursor 1491049Sbinkertn@umich.edu self.cursor = self.thedb.cursor() 1501049Sbinkertn@umich.edu 1511049Sbinkertn@umich.edu self.query('''select rn_id,rn_name,rn_sample,rn_user,rn_project 1521049Sbinkertn@umich.edu from runs''') 1531049Sbinkertn@umich.edu for result in self.cursor.fetchall(): 1541049Sbinkertn@umich.edu run = RunData(result); 1551049Sbinkertn@umich.edu self.allRuns.append(run) 1561049Sbinkertn@umich.edu self.allRunIds[run.run] = run 1571049Sbinkertn@umich.edu self.allRunNames[run.name] = run 1581049Sbinkertn@umich.edu 1591049Sbinkertn@umich.edu self.query('select * from bins') 1601049Sbinkertn@umich.edu for id,name in self.cursor.fetchall(): 1611049Sbinkertn@umich.edu self.allBinIds[int(id)] = name 1621049Sbinkertn@umich.edu self.allBinNames[name] = int(id) 1631049Sbinkertn@umich.edu 1641049Sbinkertn@umich.edu self.query('select sd_stat,sd_x,sd_y,sd_name,sd_descr from subdata') 1651049Sbinkertn@umich.edu for result in self.cursor.fetchall(): 1661049Sbinkertn@umich.edu subdata = SubData(result) 1671049Sbinkertn@umich.edu if self.allSubData.has_key(subdata.stat): 1681049Sbinkertn@umich.edu self.allSubData[subdata.stat].append(subdata) 1691049Sbinkertn@umich.edu else: 1701049Sbinkertn@umich.edu self.allSubData[subdata.stat] = [ subdata ] 1711049Sbinkertn@umich.edu 1721049Sbinkertn@umich.edu self.query('select * from formulas') 1731049Sbinkertn@umich.edu for id,formula in self.cursor.fetchall(): 1741306Sbinkertn@umich.edu self.allFormulas[int(id)] = formula.tostring() 1751049Sbinkertn@umich.edu 1761049Sbinkertn@umich.edu StatData.db = self 1771049Sbinkertn@umich.edu self.query('select * from stats') 1781049Sbinkertn@umich.edu import info 1791049Sbinkertn@umich.edu for result in self.cursor.fetchall(): 1801049Sbinkertn@umich.edu stat = info.NewStat(StatData(result)) 1811049Sbinkertn@umich.edu self.append(stat) 1821049Sbinkertn@umich.edu self.allStats.append(stat) 1831049Sbinkertn@umich.edu self.allStatIds[stat.stat] = stat 1841049Sbinkertn@umich.edu self.allStatNames[stat.name] = stat 1851049Sbinkertn@umich.edu 1861049Sbinkertn@umich.edu # Name: listbins 1871049Sbinkertn@umich.edu # Desc: Prints all bins matching regex argument, if no argument 1881049Sbinkertn@umich.edu # is given all bins are returned 1891049Sbinkertn@umich.edu def listBins(self, regex='.*'): 1901049Sbinkertn@umich.edu print '%-50s %-10s' % ('bin name', 'id') 1911049Sbinkertn@umich.edu print '-' * 61 1921049Sbinkertn@umich.edu names = self.allBinNames.keys() 1931049Sbinkertn@umich.edu names.sort() 1941049Sbinkertn@umich.edu for name in names: 1951049Sbinkertn@umich.edu id = self.allBinNames[name] 1961049Sbinkertn@umich.edu print '%-50s %-10d' % (name, id) 1971049Sbinkertn@umich.edu 1981049Sbinkertn@umich.edu # Name: listruns 1991049Sbinkertn@umich.edu # Desc: Prints all runs matching a given user, if no argument 2001049Sbinkertn@umich.edu # is given all runs are returned 2011049Sbinkertn@umich.edu def listRuns(self, user=None): 2021049Sbinkertn@umich.edu print '%-40s %-10s %-5s' % ('run name', 'user', 'id') 2031049Sbinkertn@umich.edu print '-' * 62 2041049Sbinkertn@umich.edu for run in self.allRuns: 2051049Sbinkertn@umich.edu if user == None or user == run.user: 2061049Sbinkertn@umich.edu print '%-40s %-10s %-10d' % (run.name, run.user, run.run) 2071049Sbinkertn@umich.edu 2081049Sbinkertn@umich.edu # Name: listTicks 2091049Sbinkertn@umich.edu # Desc: Prints all samples for a given run 2101049Sbinkertn@umich.edu def listTicks(self, run=None): 2111049Sbinkertn@umich.edu print "tick" 2121049Sbinkertn@umich.edu print "----------------------------------------" 2131049Sbinkertn@umich.edu sql = 'select distinct dt_tick from data where dt_stat=1950' 2141049Sbinkertn@umich.edu #if run != None: 2151049Sbinkertn@umich.edu # sql += ' where dt_run=%d' % run 2161049Sbinkertn@umich.edu self.query(sql) 2171049Sbinkertn@umich.edu for r in self.cursor.fetchall(): 2181049Sbinkertn@umich.edu print r[0] 2191049Sbinkertn@umich.edu 2201049Sbinkertn@umich.edu # Name: liststats 2211049Sbinkertn@umich.edu # Desc: Prints all statistics that appear in the database, 2221049Sbinkertn@umich.edu # the optional argument is a regular expression that can 2231049Sbinkertn@umich.edu # be used to prune the result set 2241049Sbinkertn@umich.edu def listStats(self, regex=None): 2251049Sbinkertn@umich.edu print '%-60s %-8s %-10s' % ('stat name', 'id', 'type') 2261049Sbinkertn@umich.edu print '-' * 80 2271049Sbinkertn@umich.edu 2281049Sbinkertn@umich.edu rx = None 2291049Sbinkertn@umich.edu if regex != None: 2301049Sbinkertn@umich.edu rx = re.compile(regex) 2311049Sbinkertn@umich.edu 2321049Sbinkertn@umich.edu stats = [ stat.name for stat in self.allStats ] 2331049Sbinkertn@umich.edu stats.sort(statcmp) 2341049Sbinkertn@umich.edu for stat in stats: 2351049Sbinkertn@umich.edu stat = self.allStatNames[stat] 2361049Sbinkertn@umich.edu if rx == None or rx.match(stat.name): 2371049Sbinkertn@umich.edu print '%-60s %-8s %-10s' % (stat.name, stat.stat, stat.type) 2381049Sbinkertn@umich.edu 2391049Sbinkertn@umich.edu # Name: liststats 2401049Sbinkertn@umich.edu # Desc: Prints all statistics that appear in the database, 2411049Sbinkertn@umich.edu # the optional argument is a regular expression that can 2421049Sbinkertn@umich.edu # be used to prune the result set 2431049Sbinkertn@umich.edu def listFormulas(self, regex=None): 2441049Sbinkertn@umich.edu print '%-60s %s' % ('formula name', 'formula') 2451049Sbinkertn@umich.edu print '-' * 80 2461049Sbinkertn@umich.edu 2471049Sbinkertn@umich.edu rx = None 2481049Sbinkertn@umich.edu if regex != None: 2491049Sbinkertn@umich.edu rx = re.compile(regex) 2501049Sbinkertn@umich.edu 2511049Sbinkertn@umich.edu stats = [ stat.name for stat in self.allStats ] 2521049Sbinkertn@umich.edu stats.sort(statcmp) 2531049Sbinkertn@umich.edu for stat in stats: 2541049Sbinkertn@umich.edu stat = self.allStatNames[stat] 2551049Sbinkertn@umich.edu if stat.type == 'FORMULA' and (rx == None or rx.match(stat.name)): 2561049Sbinkertn@umich.edu print '%-60s %s' % (stat.name, self.allFormulas[stat.stat]) 2571049Sbinkertn@umich.edu 2581049Sbinkertn@umich.edu def getStat(self, stats): 2591049Sbinkertn@umich.edu if type(stats) is not list: 2601049Sbinkertn@umich.edu stats = [ stats ] 2611049Sbinkertn@umich.edu 2621049Sbinkertn@umich.edu ret = [] 2631049Sbinkertn@umich.edu for stat in stats: 2641049Sbinkertn@umich.edu if type(stat) is int: 2651049Sbinkertn@umich.edu ret.append(self.allStatIds[stat]) 2661049Sbinkertn@umich.edu 2671049Sbinkertn@umich.edu if type(stat) is str: 2681049Sbinkertn@umich.edu rx = re.compile(stat) 2691049Sbinkertn@umich.edu for stat in self.allStats: 2701049Sbinkertn@umich.edu if rx.match(stat.name): 2711049Sbinkertn@umich.edu ret.append(stat) 2721049Sbinkertn@umich.edu return ret 2731049Sbinkertn@umich.edu 2741049Sbinkertn@umich.edu def getBin(self, bins): 2751049Sbinkertn@umich.edu if type(bins) is not list: 2761049Sbinkertn@umich.edu bins = [ bins ] 2771049Sbinkertn@umich.edu 2781049Sbinkertn@umich.edu ret = [] 2791049Sbinkertn@umich.edu for bin in bins: 2801049Sbinkertn@umich.edu if type(bin) is int: 2811049Sbinkertn@umich.edu ret.append(bin) 2821049Sbinkertn@umich.edu elif type(bin) is str: 2831049Sbinkertn@umich.edu ret.append(self.allBinNames[bin]) 2841049Sbinkertn@umich.edu else: 2851049Sbinkertn@umich.edu for name,id in self.allBinNames.items(): 2861049Sbinkertn@umich.edu if bin.match(name): 2871049Sbinkertn@umich.edu ret.append(id) 2881049Sbinkertn@umich.edu 2891049Sbinkertn@umich.edu return ret 2901049Sbinkertn@umich.edu 2911049Sbinkertn@umich.edu def getNotBin(self, bin): 2921049Sbinkertn@umich.edu map = {} 2931049Sbinkertn@umich.edu for bin in getBin(bin): 2941049Sbinkertn@umich.edu map[bin] = 1 2951049Sbinkertn@umich.edu 2961049Sbinkertn@umich.edu ret = [] 2971049Sbinkertn@umich.edu for bin in self.allBinIds.keys(): 2981049Sbinkertn@umich.edu if not map.has_key(bin): 2991049Sbinkertn@umich.edu ret.append(bin) 3001049Sbinkertn@umich.edu 3011049Sbinkertn@umich.edu return ret 3021049Sbinkertn@umich.edu 3031049Sbinkertn@umich.edu ######################################### 3041049Sbinkertn@umich.edu # get the data 3051049Sbinkertn@umich.edu # 3061049Sbinkertn@umich.edu def inner(self, op, stat, bins, ticks, group=False): 3071049Sbinkertn@umich.edu sql = 'select ' 3081049Sbinkertn@umich.edu sql += 'dt_stat as stat, ' 3091049Sbinkertn@umich.edu sql += 'dt_run as run, ' 3101049Sbinkertn@umich.edu sql += 'dt_x as x, ' 3111049Sbinkertn@umich.edu sql += 'dt_y as y, ' 3121049Sbinkertn@umich.edu if group: 3131049Sbinkertn@umich.edu sql += 'dt_tick as tick, ' 3141049Sbinkertn@umich.edu sql += '%s(dt_data) as data ' % op 3151049Sbinkertn@umich.edu sql += 'from data ' 3161049Sbinkertn@umich.edu sql += 'where ' 3171049Sbinkertn@umich.edu 3181049Sbinkertn@umich.edu if isinstance(stat, list): 3191049Sbinkertn@umich.edu val = ' or '.join([ 'dt_stat=%d' % s.stat for s in stat ]) 3201049Sbinkertn@umich.edu sql += ' (%s)' % val 3211049Sbinkertn@umich.edu else: 3221049Sbinkertn@umich.edu sql += ' dt_stat=%d' % stat.stat 3231049Sbinkertn@umich.edu 3241049Sbinkertn@umich.edu if self.runs != None and len(self.runs): 3251049Sbinkertn@umich.edu val = ' or '.join([ 'dt_run=%d' % r for r in self.runs ]) 3261049Sbinkertn@umich.edu sql += ' and (%s)' % val 3271049Sbinkertn@umich.edu 3281049Sbinkertn@umich.edu if bins != None and len(bins): 3291049Sbinkertn@umich.edu val = ' or '.join([ 'dt_bin=%d' % b for b in bins ]) 3301049Sbinkertn@umich.edu sql += ' and (%s)' % val 3311049Sbinkertn@umich.edu 3321049Sbinkertn@umich.edu if ticks != None and len(ticks): 3331049Sbinkertn@umich.edu val = ' or '.join([ 'dt_tick=%d' % s for s in ticks ]) 3341049Sbinkertn@umich.edu sql += ' and (%s)' % val 3351049Sbinkertn@umich.edu 3361049Sbinkertn@umich.edu sql += ' group by dt_stat,dt_run,dt_x,dt_y' 3371049Sbinkertn@umich.edu if group: 3381049Sbinkertn@umich.edu sql += ',dt_tick' 3391049Sbinkertn@umich.edu return sql 3401049Sbinkertn@umich.edu 3411049Sbinkertn@umich.edu def outer(self, op_out, op_in, stat, bins, ticks): 3421049Sbinkertn@umich.edu sql = self.inner(op_in, stat, bins, ticks, True) 3431049Sbinkertn@umich.edu sql = 'select stat,run,x,y,%s(data) from (%s) as tb ' % (op_out, sql) 3441049Sbinkertn@umich.edu sql += 'group by stat,run,x,y' 3451049Sbinkertn@umich.edu return sql 3461049Sbinkertn@umich.edu 3471049Sbinkertn@umich.edu # Name: sum 3481049Sbinkertn@umich.edu # Desc: given a run, a stat and an array of samples and bins, 3491049Sbinkertn@umich.edu # sum all the bins and then get the standard deviation of the 3501049Sbinkertn@umich.edu # samples for non-binned runs. This will just return the average 3511049Sbinkertn@umich.edu # of samples, however a bin array still must be passed 3521049Sbinkertn@umich.edu def sum(self, stat, bins, ticks): 3531049Sbinkertn@umich.edu return self.inner('sum', stat, bins, ticks) 3541049Sbinkertn@umich.edu 3551049Sbinkertn@umich.edu # Name: avg 3561049Sbinkertn@umich.edu # Desc: given a run, a stat and an array of samples and bins, 3571049Sbinkertn@umich.edu # sum all the bins and then average the samples for non-binned 3581049Sbinkertn@umich.edu # runs this will just return the average of samples, however 3591049Sbinkertn@umich.edu # a bin array still must be passed 3601049Sbinkertn@umich.edu def avg(self, stat, bins, ticks): 3611049Sbinkertn@umich.edu return self.outer('avg', 'sum', stat, bins, ticks) 3621049Sbinkertn@umich.edu 3631049Sbinkertn@umich.edu # Name: stdev 3641049Sbinkertn@umich.edu # Desc: given a run, a stat and an array of samples and bins, 3651049Sbinkertn@umich.edu # sum all the bins and then get the standard deviation of the 3661049Sbinkertn@umich.edu # samples for non-binned runs. This will just return the average 3671049Sbinkertn@umich.edu # of samples, however a bin array still must be passed 3681049Sbinkertn@umich.edu def stdev(self, stat, bins, ticks): 3691049Sbinkertn@umich.edu return self.outer('stddev', 'sum', stat, bins, ticks) 3701049Sbinkertn@umich.edu 3711049Sbinkertn@umich.edu def __getattribute__(self, attr): 3721049Sbinkertn@umich.edu if attr != 'get': 3731049Sbinkertn@umich.edu return super(Database, self).__getattribute__(attr) 3741049Sbinkertn@umich.edu 3751049Sbinkertn@umich.edu if self.__dict__['get'] == type(self).sum: 3761049Sbinkertn@umich.edu return 'sum' 3771049Sbinkertn@umich.edu elif self.__dict__['get'] == type(self).avg: 3781049Sbinkertn@umich.edu return 'avg' 3791049Sbinkertn@umich.edu elif self.__dict__['get'] == type(self).stdev: 3801049Sbinkertn@umich.edu return 'stdev' 3811049Sbinkertn@umich.edu else: 3821049Sbinkertn@umich.edu return '' 3831049Sbinkertn@umich.edu 3841049Sbinkertn@umich.edu def __setattr__(self, attr, value): 3851049Sbinkertn@umich.edu if attr != 'get': 3861049Sbinkertn@umich.edu super(Database, self).__setattr__(attr, value) 3871049Sbinkertn@umich.edu return 3881049Sbinkertn@umich.edu 3891049Sbinkertn@umich.edu if value == 'sum': 3901049Sbinkertn@umich.edu self.__dict__['get'] = type(self).sum 3911049Sbinkertn@umich.edu elif value == 'avg': 3921049Sbinkertn@umich.edu self.__dict__['get'] = type(self).avg 3931049Sbinkertn@umich.edu elif value == 'stdev': 3941049Sbinkertn@umich.edu self.__dict__['get'] = type(self).stdev 3951049Sbinkertn@umich.edu else: 3961049Sbinkertn@umich.edu raise AttributeError, "can only set get to: sum | avg | stdev" 3971049Sbinkertn@umich.edu 3981049Sbinkertn@umich.edu def data(self, stat, bins=None, ticks=None): 3991049Sbinkertn@umich.edu if bins is None: 4001049Sbinkertn@umich.edu bins = self.bins 4011049Sbinkertn@umich.edu if ticks is None: 4021049Sbinkertn@umich.edu ticks = self.ticks 4031049Sbinkertn@umich.edu sql = self.__dict__['get'](self, stat, bins, ticks) 4041049Sbinkertn@umich.edu self.query(sql) 4051049Sbinkertn@umich.edu 4061049Sbinkertn@umich.edu runs = {} 4071049Sbinkertn@umich.edu for x in self.cursor.fetchall(): 4081049Sbinkertn@umich.edu data = Data(x) 4091049Sbinkertn@umich.edu if not runs.has_key(data.run): 4101049Sbinkertn@umich.edu runs[data.run] = {} 4111049Sbinkertn@umich.edu if not runs[data.run].has_key(data.x): 4121049Sbinkertn@umich.edu runs[data.run][data.x] = {} 4131049Sbinkertn@umich.edu 4141049Sbinkertn@umich.edu runs[data.run][data.x][data.y] = data.data 4151049Sbinkertn@umich.edu return runs 416