info.py revision 1986
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. 261758Ssaidi@eecs.umich.edu 271049Sbinkertn@umich.edufrom __future__ import division 281049Sbinkertn@umich.eduimport operator, re, types 291049Sbinkertn@umich.edu 301929Sbinkertn@umich.edudef unproxy(proxy): 311929Sbinkertn@umich.edu if hasattr(proxy, '__unproxy__'): 321929Sbinkertn@umich.edu return proxy.__unproxy__() 331049Sbinkertn@umich.edu 341929Sbinkertn@umich.edu return proxy 351049Sbinkertn@umich.edu 361929Sbinkertn@umich.edudef scalar(stat): 371929Sbinkertn@umich.edu stat = unproxy(stat) 381929Sbinkertn@umich.edu assert(stat.__scalar__() != stat.__vector__()) 391929Sbinkertn@umich.edu return stat.__scalar__() 401049Sbinkertn@umich.edu 411929Sbinkertn@umich.edudef vector(stat): 421929Sbinkertn@umich.edu stat = unproxy(stat) 431929Sbinkertn@umich.edu assert(stat.__scalar__() != stat.__vector__()) 441929Sbinkertn@umich.edu return stat.__vector__() 451049Sbinkertn@umich.edu 461929Sbinkertn@umich.edudef value(stat, *args): 471929Sbinkertn@umich.edu stat = unproxy(stat) 481929Sbinkertn@umich.edu return stat.__value__(*args) 491049Sbinkertn@umich.edu 501929Sbinkertn@umich.edudef values(stat, run): 511929Sbinkertn@umich.edu stat = unproxy(stat) 521929Sbinkertn@umich.edu result = [] 531929Sbinkertn@umich.edu for i in xrange(len(stat)): 541934Sbinkertn@umich.edu val = value(stat, run, i) 551929Sbinkertn@umich.edu if val is None: 561929Sbinkertn@umich.edu return None 571929Sbinkertn@umich.edu result.append(val) 581049Sbinkertn@umich.edu return result 591049Sbinkertn@umich.edu 601929Sbinkertn@umich.edudef total(stat, run): 611929Sbinkertn@umich.edu return sum(values(stat, run)) 621049Sbinkertn@umich.edu 631929Sbinkertn@umich.edudef len(stat): 641929Sbinkertn@umich.edu stat = unproxy(stat) 651929Sbinkertn@umich.edu return stat.__len__() 661049Sbinkertn@umich.edu 671929Sbinkertn@umich.educlass Value(object): 681929Sbinkertn@umich.edu def __scalar__(self): 691929Sbinkertn@umich.edu raise AttributeError, "must define __scalar__ for %s" % (type (self)) 701929Sbinkertn@umich.edu def __vector__(self): 711929Sbinkertn@umich.edu raise AttributeError, "must define __vector__ for %s" % (type (self)) 721049Sbinkertn@umich.edu 731929Sbinkertn@umich.edu def __add__(self, other): 741929Sbinkertn@umich.edu return BinaryProxy(operator.__add__, self, other) 751929Sbinkertn@umich.edu def __sub__(self, other): 761929Sbinkertn@umich.edu return BinaryProxy(operator.__sub__, self, other) 771929Sbinkertn@umich.edu def __mul__(self, other): 781929Sbinkertn@umich.edu return BinaryProxy(operator.__mul__, self, other) 791929Sbinkertn@umich.edu def __div__(self, other): 801929Sbinkertn@umich.edu return BinaryProxy(operator.__div__, self, other) 811929Sbinkertn@umich.edu def __truediv__(self, other): 821929Sbinkertn@umich.edu return BinaryProxy(operator.__truediv__, self, other) 831929Sbinkertn@umich.edu def __floordiv__(self, other): 841929Sbinkertn@umich.edu return BinaryProxy(operator.__floordiv__, self, other) 851049Sbinkertn@umich.edu 861929Sbinkertn@umich.edu def __radd__(self, other): 871929Sbinkertn@umich.edu return BinaryProxy(operator.__add__, other, self) 881929Sbinkertn@umich.edu def __rsub__(self, other): 891929Sbinkertn@umich.edu return BinaryProxy(operator.__sub__, other, self) 901929Sbinkertn@umich.edu def __rmul__(self, other): 911929Sbinkertn@umich.edu return BinaryProxy(operator.__mul__, other, self) 921929Sbinkertn@umich.edu def __rdiv__(self, other): 931929Sbinkertn@umich.edu return BinaryProxy(operator.__div__, other, self) 941929Sbinkertn@umich.edu def __rtruediv__(self, other): 951929Sbinkertn@umich.edu return BinaryProxy(operator.__truediv__, other, self) 961929Sbinkertn@umich.edu def __rfloordiv__(self, other): 971929Sbinkertn@umich.edu return BinaryProxy(operator.__floordiv__, other, self) 981929Sbinkertn@umich.edu 991929Sbinkertn@umich.edu def __neg__(self): 1001929Sbinkertn@umich.edu return UnaryProxy(operator.__neg__, self) 1011929Sbinkertn@umich.edu def __pos__(self): 1021929Sbinkertn@umich.edu return UnaryProxy(operator.__pos__, self) 1031929Sbinkertn@umich.edu def __abs__(self): 1041929Sbinkertn@umich.edu return UnaryProxy(operator.__abs__, self) 1051929Sbinkertn@umich.edu 1061929Sbinkertn@umich.educlass Scalar(Value): 1071929Sbinkertn@umich.edu def __scalar__(self): 1081929Sbinkertn@umich.edu return True 1091929Sbinkertn@umich.edu 1101929Sbinkertn@umich.edu def __vector__(self): 1111929Sbinkertn@umich.edu return False 1121929Sbinkertn@umich.edu 1131929Sbinkertn@umich.edu def __value__(self, run): 1141929Sbinkertn@umich.edu raise AttributeError, '__value__ must be defined' 1151929Sbinkertn@umich.edu 1161929Sbinkertn@umich.educlass VectorItemProxy(Value): 1171929Sbinkertn@umich.edu def __init__(self, proxy, index): 1181929Sbinkertn@umich.edu self.proxy = proxy 1191929Sbinkertn@umich.edu self.index = index 1201929Sbinkertn@umich.edu 1211929Sbinkertn@umich.edu def __scalar__(self): 1221929Sbinkertn@umich.edu return True 1231929Sbinkertn@umich.edu 1241929Sbinkertn@umich.edu def __vector__(self): 1251929Sbinkertn@umich.edu return False 1261929Sbinkertn@umich.edu 1271929Sbinkertn@umich.edu def __value__(self, run): 1281929Sbinkertn@umich.edu return value(self.proxy, run, self.index) 1291929Sbinkertn@umich.edu 1301929Sbinkertn@umich.educlass Vector(Value): 1311929Sbinkertn@umich.edu def __scalar__(self): 1321929Sbinkertn@umich.edu return False 1331929Sbinkertn@umich.edu 1341929Sbinkertn@umich.edu def __vector__(self): 1351929Sbinkertn@umich.edu return True 1361929Sbinkertn@umich.edu 1371929Sbinkertn@umich.edu def __value__(self, run, index): 1381929Sbinkertn@umich.edu raise AttributeError, '__value__ must be defined' 1391929Sbinkertn@umich.edu 1401929Sbinkertn@umich.edu def __getitem__(self, index): 1411929Sbinkertn@umich.edu return VectorItemProxy(self, index) 1421929Sbinkertn@umich.edu 1431929Sbinkertn@umich.educlass ScalarConstant(Scalar): 1441929Sbinkertn@umich.edu def __init__(self, constant): 1451929Sbinkertn@umich.edu self.constant = constant 1461929Sbinkertn@umich.edu def __value__(self, run): 1471929Sbinkertn@umich.edu return self.constant 1481986Sbinkertn@umich.edu def __str__(self): 1491986Sbinkertn@umich.edu return str(self.constant) 1501929Sbinkertn@umich.edu 1511929Sbinkertn@umich.educlass VectorConstant(Vector): 1521929Sbinkertn@umich.edu def __init__(self, constant): 1531929Sbinkertn@umich.edu self.constant = constant 1541929Sbinkertn@umich.edu def __value__(self, run, index): 1551929Sbinkertn@umich.edu return self.constant[index] 1561929Sbinkertn@umich.edu def __len__(self): 1571929Sbinkertn@umich.edu return len(self.constant) 1581986Sbinkertn@umich.edu def __str__(self): 1591986Sbinkertn@umich.edu return str(self.constant) 1601929Sbinkertn@umich.edu 1611929Sbinkertn@umich.edudef WrapValue(value): 1621929Sbinkertn@umich.edu if isinstance(value, (int, long, float)): 1631929Sbinkertn@umich.edu return ScalarConstant(value) 1641929Sbinkertn@umich.edu if isinstance(value, (list, tuple)): 1651929Sbinkertn@umich.edu return VectorConstant(value) 1661929Sbinkertn@umich.edu if isinstance(value, Value): 1671929Sbinkertn@umich.edu return value 1681929Sbinkertn@umich.edu 1691929Sbinkertn@umich.edu raise AttributeError, 'Only values can be wrapped' 1701049Sbinkertn@umich.edu 1711049Sbinkertn@umich.educlass Statistic(object): 1721929Sbinkertn@umich.edu def __getattr__(self, attr): 1731929Sbinkertn@umich.edu if attr in ('data', 'x', 'y'): 1741929Sbinkertn@umich.edu result = self.source.data(self, self.bins, self.ticks) 1751929Sbinkertn@umich.edu self.data = result.data 1761929Sbinkertn@umich.edu self.x = result.x 1771929Sbinkertn@umich.edu self.y = result.y 1781929Sbinkertn@umich.edu return super(Statistic, self).__getattribute__(attr) 1791049Sbinkertn@umich.edu 1801049Sbinkertn@umich.edu def __setattr__(self, attr, value): 1811929Sbinkertn@umich.edu if attr == 'stat': 1821929Sbinkertn@umich.edu raise AttributeError, '%s is read only' % stat 1831929Sbinkertn@umich.edu if attr in ('source', 'bins', 'ticks'): 1841929Sbinkertn@umich.edu if getattr(self, attr) != value: 1851929Sbinkertn@umich.edu if hasattr(self, 'data'): 1861929Sbinkertn@umich.edu delattr(self, 'data') 1871049Sbinkertn@umich.edu 1881929Sbinkertn@umich.edu super(Statistic, self).__setattr__(attr, value) 1891049Sbinkertn@umich.edu 1901986Sbinkertn@umich.edu def __str__(self): 1911986Sbinkertn@umich.edu return self.name 1921986Sbinkertn@umich.edu 1931929Sbinkertn@umich.educlass ValueProxy(Value): 1941929Sbinkertn@umich.edu def __getattr__(self, attr): 1951929Sbinkertn@umich.edu if attr == '__value__': 1961929Sbinkertn@umich.edu if scalar(self): 1971929Sbinkertn@umich.edu return self.__scalarvalue__ 1981929Sbinkertn@umich.edu if vector(self): 1991929Sbinkertn@umich.edu return self.__vectorvalue__ 2001929Sbinkertn@umich.edu if attr == '__len__': 2011929Sbinkertn@umich.edu if vector(self): 2021929Sbinkertn@umich.edu return self.__vectorlen__ 2031929Sbinkertn@umich.edu return super(ValueProxy, self).__getattribute__(attr) 2041049Sbinkertn@umich.edu 2051929Sbinkertn@umich.educlass UnaryProxy(ValueProxy): 2061929Sbinkertn@umich.edu def __init__(self, op, arg): 2071929Sbinkertn@umich.edu self.op = op 2081929Sbinkertn@umich.edu self.arg = WrapValue(arg) 2091049Sbinkertn@umich.edu 2101929Sbinkertn@umich.edu def __scalar__(self): 2111929Sbinkertn@umich.edu return scalar(self.arg) 2121049Sbinkertn@umich.edu 2131929Sbinkertn@umich.edu def __vector__(self): 2141929Sbinkertn@umich.edu return vector(self.arg) 2151049Sbinkertn@umich.edu 2161929Sbinkertn@umich.edu def __scalarvalue__(self, run): 2171929Sbinkertn@umich.edu val = value(self.arg, run) 2181929Sbinkertn@umich.edu if val is None: 2191929Sbinkertn@umich.edu return None 2201929Sbinkertn@umich.edu return self.op(val) 2211049Sbinkertn@umich.edu 2221929Sbinkertn@umich.edu def __vectorvalue__(self, run, index): 2231929Sbinkertn@umich.edu val = value(self.arg, run, index) 2241929Sbinkertn@umich.edu if val is None: 2251929Sbinkertn@umich.edu return None 2261929Sbinkertn@umich.edu return self.op(val) 2271049Sbinkertn@umich.edu 2281929Sbinkertn@umich.edu def __vectorlen__(self): 2291929Sbinkertn@umich.edu return len(unproxy(self.arg)) 2301049Sbinkertn@umich.edu 2311986Sbinkertn@umich.edu def __str__(self): 2321986Sbinkertn@umich.edu if self.op == operator.__neg__: 2331986Sbinkertn@umich.edu return '-%s' % str(self.arg) 2341986Sbinkertn@umich.edu if self.op == operator.__pos__: 2351986Sbinkertn@umich.edu return '+%s' % str(self.arg) 2361986Sbinkertn@umich.edu if self.op == operator.__abs__: 2371986Sbinkertn@umich.edu return 'abs(%s)' % self.arg 2381986Sbinkertn@umich.edu 2391929Sbinkertn@umich.educlass BinaryProxy(ValueProxy): 2401929Sbinkertn@umich.edu def __init__(self, op, arg0, arg1): 2411929Sbinkertn@umich.edu super(BinaryProxy, self).__init__() 2421929Sbinkertn@umich.edu self.op = op 2431929Sbinkertn@umich.edu self.arg0 = WrapValue(arg0) 2441929Sbinkertn@umich.edu self.arg1 = WrapValue(arg1) 2451049Sbinkertn@umich.edu 2461929Sbinkertn@umich.edu def __scalar__(self): 2471929Sbinkertn@umich.edu return scalar(self.arg0) and scalar(self.arg1) 2481049Sbinkertn@umich.edu 2491929Sbinkertn@umich.edu def __vector__(self): 2501929Sbinkertn@umich.edu return vector(self.arg0) or vector(self.arg1) 2511929Sbinkertn@umich.edu 2521929Sbinkertn@umich.edu def __scalarvalue__(self, run): 2531929Sbinkertn@umich.edu val0 = value(self.arg0, run) 2541929Sbinkertn@umich.edu val1 = value(self.arg1, run) 2551929Sbinkertn@umich.edu if val0 is None or val1 is None: 2561929Sbinkertn@umich.edu return None 2571929Sbinkertn@umich.edu return self.op(val0, val1) 2581929Sbinkertn@umich.edu 2591929Sbinkertn@umich.edu def __vectorvalue__(self, run, index): 2601929Sbinkertn@umich.edu if scalar(self.arg0): 2611929Sbinkertn@umich.edu val0 = value(self.arg0, run) 2621929Sbinkertn@umich.edu if vector(self.arg0): 2631929Sbinkertn@umich.edu val0 = value(self.arg0, run, index) 2641929Sbinkertn@umich.edu if scalar(self.arg1): 2651929Sbinkertn@umich.edu val1 = value(self.arg1, run) 2661929Sbinkertn@umich.edu if vector(self.arg1): 2671929Sbinkertn@umich.edu val1 = value(self.arg1, run, index) 2681929Sbinkertn@umich.edu 2691929Sbinkertn@umich.edu if val0 is None or val1 is None: 2701929Sbinkertn@umich.edu return None 2711929Sbinkertn@umich.edu 2721929Sbinkertn@umich.edu return self.op(val0, val1) 2731929Sbinkertn@umich.edu 2741929Sbinkertn@umich.edu def __vectorlen__(self): 2751929Sbinkertn@umich.edu if vector(self.arg0) and scalar(self.arg1): 2761929Sbinkertn@umich.edu return len(self.arg0) 2771929Sbinkertn@umich.edu if scalar(self.arg0) and vector(self.arg1): 2781929Sbinkertn@umich.edu return len(self.arg1) 2791929Sbinkertn@umich.edu 2801929Sbinkertn@umich.edu len0 = len(self.arg0) 2811929Sbinkertn@umich.edu len1 = len(self.arg1) 2821929Sbinkertn@umich.edu 2831929Sbinkertn@umich.edu if len0 != len1: 2841929Sbinkertn@umich.edu raise AttributeError, \ 2851929Sbinkertn@umich.edu "vectors of different lengths %d != %d" % (len0, len1) 2861929Sbinkertn@umich.edu 2871929Sbinkertn@umich.edu return len0 2881929Sbinkertn@umich.edu 2891986Sbinkertn@umich.edu def __str__(self): 2901986Sbinkertn@umich.edu ops = { operator.__add__ : '+', 2911986Sbinkertn@umich.edu operator.__sub__ : '-', 2921986Sbinkertn@umich.edu operator.__mul__ : '*', 2931986Sbinkertn@umich.edu operator.__div__ : '/', 2941986Sbinkertn@umich.edu operator.__truediv__ : '/', 2951986Sbinkertn@umich.edu operator.__floordiv__ : '//' } 2961986Sbinkertn@umich.edu 2971986Sbinkertn@umich.edu return '(%s %s %s)' % (str(self.arg0), ops[self.op], str(self.arg1)) 2981986Sbinkertn@umich.edu 2991929Sbinkertn@umich.educlass Proxy(Value): 3001929Sbinkertn@umich.edu def __init__(self, name, dict): 3011929Sbinkertn@umich.edu self.name = name 3021929Sbinkertn@umich.edu self.dict = dict 3031929Sbinkertn@umich.edu 3041929Sbinkertn@umich.edu def __unproxy__(self): 3051929Sbinkertn@umich.edu return unproxy(self.dict[self.name]) 3061929Sbinkertn@umich.edu 3071929Sbinkertn@umich.edu def __getitem__(self, index): 3081929Sbinkertn@umich.edu return ItemProxy(self, index) 3091929Sbinkertn@umich.edu 3101929Sbinkertn@umich.edu def __getattr__(self, attr): 3111929Sbinkertn@umich.edu return AttrProxy(self, attr) 3121929Sbinkertn@umich.edu 3131986Sbinkertn@umich.edu def __str__(self): 3141986Sbinkertn@umich.edu return str(self.dict[self.name]) 3151986Sbinkertn@umich.edu 3161929Sbinkertn@umich.educlass ItemProxy(Proxy): 3171929Sbinkertn@umich.edu def __init__(self, proxy, index): 3181929Sbinkertn@umich.edu self.proxy = proxy 3191929Sbinkertn@umich.edu self.index = index 3201929Sbinkertn@umich.edu 3211929Sbinkertn@umich.edu def __unproxy__(self): 3221929Sbinkertn@umich.edu return unproxy(unproxy(self.proxy)[self.index]) 3231929Sbinkertn@umich.edu 3241986Sbinkertn@umich.edu def __str__(self): 3251986Sbinkertn@umich.edu return '%s[%s]' % (self.proxy, self.index) 3261986Sbinkertn@umich.edu 3271929Sbinkertn@umich.educlass AttrProxy(Proxy): 3281929Sbinkertn@umich.edu def __init__(self, proxy, attr): 3291929Sbinkertn@umich.edu self.proxy = proxy 3301929Sbinkertn@umich.edu self.attr = attr 3311929Sbinkertn@umich.edu 3321929Sbinkertn@umich.edu def __unproxy__(self): 3331929Sbinkertn@umich.edu return unproxy(getattr(unproxy(self.proxy), self.attr)) 3341929Sbinkertn@umich.edu 3351986Sbinkertn@umich.edu def __str__(self): 3361986Sbinkertn@umich.edu return '%s.%s' % (self.proxy, self.attr) 3371986Sbinkertn@umich.edu 3381929Sbinkertn@umich.educlass ProxyGroup(object): 3391929Sbinkertn@umich.edu def __init__(self, dict=None, **kwargs): 3401929Sbinkertn@umich.edu self.__dict__['dict'] = {} 3411929Sbinkertn@umich.edu 3421929Sbinkertn@umich.edu if dict is not None: 3431929Sbinkertn@umich.edu self.dict.update(dict) 3441929Sbinkertn@umich.edu 3451929Sbinkertn@umich.edu if kwargs: 3461929Sbinkertn@umich.edu self.dict.update(kwargs) 3471929Sbinkertn@umich.edu 3481929Sbinkertn@umich.edu def __getattr__(self, name): 3491929Sbinkertn@umich.edu return Proxy(name, self.dict) 3501929Sbinkertn@umich.edu 3511929Sbinkertn@umich.edu def __setattr__(self, attr, value): 3521929Sbinkertn@umich.edu self.dict[attr] = value 3531929Sbinkertn@umich.edu 3541929Sbinkertn@umich.educlass ScalarStat(Statistic,Scalar): 3551929Sbinkertn@umich.edu def __value__(self, run): 3561929Sbinkertn@umich.edu if run not in self.data: 3571929Sbinkertn@umich.edu return None 3581929Sbinkertn@umich.edu return self.data[run][0][0] 3591929Sbinkertn@umich.edu 3601929Sbinkertn@umich.edu def display(self, run=None): 3611049Sbinkertn@umich.edu import display 3621049Sbinkertn@umich.edu p = display.Print() 3631049Sbinkertn@umich.edu p.name = self.name 3641049Sbinkertn@umich.edu p.desc = self.desc 3651929Sbinkertn@umich.edu p.value = value(self, run) 3661049Sbinkertn@umich.edu p.flags = self.flags 3671049Sbinkertn@umich.edu p.precision = self.precision 3681049Sbinkertn@umich.edu if display.all or (self.flags & flags.printable): 3691049Sbinkertn@umich.edu p.display() 3701049Sbinkertn@umich.edu 3711929Sbinkertn@umich.educlass VectorStat(Statistic,Vector): 3721929Sbinkertn@umich.edu def __value__(self, run, item): 3731929Sbinkertn@umich.edu if run not in self.data: 3741929Sbinkertn@umich.edu return None 3751929Sbinkertn@umich.edu return self.data[run][item][0] 3761049Sbinkertn@umich.edu 3771929Sbinkertn@umich.edu def __len__(self): 3781929Sbinkertn@umich.edu return self.x 3791049Sbinkertn@umich.edu 3801929Sbinkertn@umich.edu def display(self, run=None): 3811049Sbinkertn@umich.edu import display 3821049Sbinkertn@umich.edu d = display.VectorDisplay() 3831929Sbinkertn@umich.edu d.name = self.name 3841929Sbinkertn@umich.edu d.desc = self.desc 3851929Sbinkertn@umich.edu d.value = [ value(self, run, i) for i in xrange(len(self)) ] 3861929Sbinkertn@umich.edu d.flags = self.flags 3871929Sbinkertn@umich.edu d.precision = self.precision 3881049Sbinkertn@umich.edu d.display() 3891049Sbinkertn@umich.edu 3901929Sbinkertn@umich.educlass Formula(Value): 3911929Sbinkertn@umich.edu def __getattribute__(self, attr): 3921929Sbinkertn@umich.edu if attr not in ( '__scalar__', '__vector__', '__value__', '__len__' ): 3931929Sbinkertn@umich.edu return super(Formula, self).__getattribute__(attr) 3941049Sbinkertn@umich.edu 3951929Sbinkertn@umich.edu formula = re.sub(':', '__', self.formula) 3961929Sbinkertn@umich.edu value = eval(formula, self.source.stattop) 3971929Sbinkertn@umich.edu return getattr(value, attr) 3981049Sbinkertn@umich.edu 3991986Sbinkertn@umich.edu def __str__(self): 4001986Sbinkertn@umich.edu return self.name 4011986Sbinkertn@umich.edu 4021929Sbinkertn@umich.educlass SimpleDist(Statistic): 4031049Sbinkertn@umich.edu def __init__(self, sums, squares, samples): 4041049Sbinkertn@umich.edu self.sums = sums 4051049Sbinkertn@umich.edu self.squares = squares 4061049Sbinkertn@umich.edu self.samples = samples 4071049Sbinkertn@umich.edu 4081049Sbinkertn@umich.edu def display(self, name, desc, flags, precision): 4091049Sbinkertn@umich.edu import display 4101049Sbinkertn@umich.edu p = display.Print() 4111049Sbinkertn@umich.edu p.flags = flags 4121049Sbinkertn@umich.edu p.precision = precision 4131049Sbinkertn@umich.edu 4141049Sbinkertn@umich.edu if self.samples > 0: 4151049Sbinkertn@umich.edu p.name = name + ".mean" 4161049Sbinkertn@umich.edu p.value = self.sums / self.samples 4171049Sbinkertn@umich.edu p.display() 4181049Sbinkertn@umich.edu 4191049Sbinkertn@umich.edu p.name = name + ".stdev" 4201049Sbinkertn@umich.edu if self.samples > 1: 4211049Sbinkertn@umich.edu var = (self.samples * self.squares - self.sums ** 2) \ 4221049Sbinkertn@umich.edu / (self.samples * (self.samples - 1)) 4231049Sbinkertn@umich.edu if var >= 0: 4241049Sbinkertn@umich.edu p.value = math.sqrt(var) 4251049Sbinkertn@umich.edu else: 4261049Sbinkertn@umich.edu p.value = 'NaN' 4271049Sbinkertn@umich.edu else: 4281049Sbinkertn@umich.edu p.value = 0.0 4291049Sbinkertn@umich.edu p.display() 4301049Sbinkertn@umich.edu 4311049Sbinkertn@umich.edu p.name = name + ".samples" 4321049Sbinkertn@umich.edu p.value = self.samples 4331049Sbinkertn@umich.edu p.display() 4341049Sbinkertn@umich.edu 4351049Sbinkertn@umich.edu def comparable(self, other): 4361049Sbinkertn@umich.edu return True 4371049Sbinkertn@umich.edu 4381049Sbinkertn@umich.edu def __eq__(self, other): 4391049Sbinkertn@umich.edu return self.sums == other.sums and self.squares == other.squares and \ 4401049Sbinkertn@umich.edu self.samples == other.samples 4411049Sbinkertn@umich.edu 4421049Sbinkertn@umich.edu def __isub__(self, other): 4431049Sbinkertn@umich.edu self.sums -= other.sums 4441049Sbinkertn@umich.edu self.squares -= other.squares 4451049Sbinkertn@umich.edu self.samples -= other.samples 4461049Sbinkertn@umich.edu return self 4471049Sbinkertn@umich.edu 4481049Sbinkertn@umich.edu def __iadd__(self, other): 4491049Sbinkertn@umich.edu self.sums += other.sums 4501049Sbinkertn@umich.edu self.squares += other.squares 4511049Sbinkertn@umich.edu self.samples += other.samples 4521049Sbinkertn@umich.edu return self 4531049Sbinkertn@umich.edu 4541049Sbinkertn@umich.edu def __itruediv__(self, other): 4551049Sbinkertn@umich.edu if not other: 4561049Sbinkertn@umich.edu return self 4571049Sbinkertn@umich.edu self.sums /= other 4581049Sbinkertn@umich.edu self.squares /= other 4591049Sbinkertn@umich.edu self.samples /= other 4601049Sbinkertn@umich.edu return self 4611049Sbinkertn@umich.edu 4621049Sbinkertn@umich.educlass FullDist(SimpleDist): 4631049Sbinkertn@umich.edu def __init__(self, sums, squares, samples, minval, maxval, 4641049Sbinkertn@umich.edu under, vec, over, min, max, bsize, size): 4651049Sbinkertn@umich.edu self.sums = sums 4661049Sbinkertn@umich.edu self.squares = squares 4671049Sbinkertn@umich.edu self.samples = samples 4681049Sbinkertn@umich.edu self.minval = minval 4691049Sbinkertn@umich.edu self.maxval = maxval 4701049Sbinkertn@umich.edu self.under = under 4711049Sbinkertn@umich.edu self.vec = vec 4721049Sbinkertn@umich.edu self.over = over 4731049Sbinkertn@umich.edu self.min = min 4741049Sbinkertn@umich.edu self.max = max 4751049Sbinkertn@umich.edu self.bsize = bsize 4761049Sbinkertn@umich.edu self.size = size 4771049Sbinkertn@umich.edu 4781049Sbinkertn@umich.edu def display(self, name, desc, flags, precision): 4791049Sbinkertn@umich.edu import display 4801049Sbinkertn@umich.edu p = display.Print() 4811049Sbinkertn@umich.edu p.flags = flags 4821049Sbinkertn@umich.edu p.precision = precision 4831049Sbinkertn@umich.edu 4841049Sbinkertn@umich.edu p.name = name + '.min_val' 4851049Sbinkertn@umich.edu p.value = self.minval 4861049Sbinkertn@umich.edu p.display() 4871049Sbinkertn@umich.edu 4881049Sbinkertn@umich.edu p.name = name + '.max_val' 4891049Sbinkertn@umich.edu p.value = self.maxval 4901049Sbinkertn@umich.edu p.display() 4911049Sbinkertn@umich.edu 4921049Sbinkertn@umich.edu p.name = name + '.underflow' 4931049Sbinkertn@umich.edu p.value = self.under 4941049Sbinkertn@umich.edu p.display() 4951049Sbinkertn@umich.edu 4961049Sbinkertn@umich.edu i = self.min 4971049Sbinkertn@umich.edu for val in self.vec[:-1]: 4981049Sbinkertn@umich.edu p.name = name + '[%d:%d]' % (i, i + self.bsize - 1) 4991049Sbinkertn@umich.edu p.value = val 5001049Sbinkertn@umich.edu p.display() 5011049Sbinkertn@umich.edu i += self.bsize 5021049Sbinkertn@umich.edu 5031049Sbinkertn@umich.edu p.name = name + '[%d:%d]' % (i, self.max) 5041049Sbinkertn@umich.edu p.value = self.vec[-1] 5051049Sbinkertn@umich.edu p.display() 5061049Sbinkertn@umich.edu 5071049Sbinkertn@umich.edu 5081049Sbinkertn@umich.edu p.name = name + '.overflow' 5091049Sbinkertn@umich.edu p.value = self.over 5101049Sbinkertn@umich.edu p.display() 5111049Sbinkertn@umich.edu 5121049Sbinkertn@umich.edu SimpleDist.display(self, name, desc, flags, precision) 5131049Sbinkertn@umich.edu 5141049Sbinkertn@umich.edu def comparable(self, other): 5151049Sbinkertn@umich.edu return self.min == other.min and self.max == other.max and \ 5161049Sbinkertn@umich.edu self.bsize == other.bsize and self.size == other.size 5171049Sbinkertn@umich.edu 5181049Sbinkertn@umich.edu def __eq__(self, other): 5191049Sbinkertn@umich.edu return self.sums == other.sums and self.squares == other.squares and \ 5201049Sbinkertn@umich.edu self.samples == other.samples 5211049Sbinkertn@umich.edu 5221049Sbinkertn@umich.edu def __isub__(self, other): 5231049Sbinkertn@umich.edu self.sums -= other.sums 5241049Sbinkertn@umich.edu self.squares -= other.squares 5251049Sbinkertn@umich.edu self.samples -= other.samples 5261049Sbinkertn@umich.edu 5271049Sbinkertn@umich.edu if other.samples: 5281049Sbinkertn@umich.edu self.minval = min(self.minval, other.minval) 5291049Sbinkertn@umich.edu self.maxval = max(self.maxval, other.maxval) 5301049Sbinkertn@umich.edu self.under -= under 5311049Sbinkertn@umich.edu self.vec = map(lambda x,y: x - y, self.vec, other.vec) 5321049Sbinkertn@umich.edu self.over -= over 5331049Sbinkertn@umich.edu return self 5341049Sbinkertn@umich.edu 5351049Sbinkertn@umich.edu def __iadd__(self, other): 5361049Sbinkertn@umich.edu if not self.samples and other.samples: 5371049Sbinkertn@umich.edu self = other 5381049Sbinkertn@umich.edu return self 5391049Sbinkertn@umich.edu 5401049Sbinkertn@umich.edu self.sums += other.sums 5411049Sbinkertn@umich.edu self.squares += other.squares 5421049Sbinkertn@umich.edu self.samples += other.samples 5431049Sbinkertn@umich.edu 5441049Sbinkertn@umich.edu if other.samples: 5451049Sbinkertn@umich.edu self.minval = min(self.minval, other.minval) 5461049Sbinkertn@umich.edu self.maxval = max(self.maxval, other.maxval) 5471049Sbinkertn@umich.edu self.under += other.under 5481049Sbinkertn@umich.edu self.vec = map(lambda x,y: x + y, self.vec, other.vec) 5491049Sbinkertn@umich.edu self.over += other.over 5501049Sbinkertn@umich.edu return self 5511049Sbinkertn@umich.edu 5521049Sbinkertn@umich.edu def __itruediv__(self, other): 5531049Sbinkertn@umich.edu if not other: 5541049Sbinkertn@umich.edu return self 5551049Sbinkertn@umich.edu self.sums /= other 5561049Sbinkertn@umich.edu self.squares /= other 5571049Sbinkertn@umich.edu self.samples /= other 5581049Sbinkertn@umich.edu 5591049Sbinkertn@umich.edu if self.samples: 5601049Sbinkertn@umich.edu self.under /= other 5611049Sbinkertn@umich.edu for i in xrange(len(self.vec)): 5621049Sbinkertn@umich.edu self.vec[i] /= other 5631049Sbinkertn@umich.edu self.over /= other 5641049Sbinkertn@umich.edu return self 5651049Sbinkertn@umich.edu 5661049Sbinkertn@umich.educlass Dist(Statistic): 5671049Sbinkertn@umich.edu def display(self): 5681049Sbinkertn@umich.edu import display 5691049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 5701049Sbinkertn@umich.edu return 5711049Sbinkertn@umich.edu 5721049Sbinkertn@umich.edu self.dist.display(self.name, self.desc, self.flags, self.precision) 5731049Sbinkertn@umich.edu 5741049Sbinkertn@umich.edu def comparable(self, other): 5751049Sbinkertn@umich.edu return self.name == other.name and \ 5761049Sbinkertn@umich.edu self.dist.compareable(other.dist) 5771049Sbinkertn@umich.edu 5781049Sbinkertn@umich.edu def __eq__(self, other): 5791049Sbinkertn@umich.edu return self.dist == other.dist 5801049Sbinkertn@umich.edu 5811049Sbinkertn@umich.edu def __isub__(self, other): 5821049Sbinkertn@umich.edu self.dist -= other.dist 5831049Sbinkertn@umich.edu return self 5841049Sbinkertn@umich.edu 5851049Sbinkertn@umich.edu def __iadd__(self, other): 5861049Sbinkertn@umich.edu self.dist += other.dist 5871049Sbinkertn@umich.edu return self 5881049Sbinkertn@umich.edu 5891049Sbinkertn@umich.edu def __itruediv__(self, other): 5901049Sbinkertn@umich.edu if not other: 5911049Sbinkertn@umich.edu return self 5921049Sbinkertn@umich.edu self.dist /= other 5931049Sbinkertn@umich.edu return self 5941049Sbinkertn@umich.edu 5951049Sbinkertn@umich.educlass VectorDist(Statistic): 5961049Sbinkertn@umich.edu def display(self): 5971049Sbinkertn@umich.edu import display 5981049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 5991049Sbinkertn@umich.edu return 6001049Sbinkertn@umich.edu 6011049Sbinkertn@umich.edu if isinstance(self.dist, SimpleDist): 6021049Sbinkertn@umich.edu return 6031049Sbinkertn@umich.edu 6041049Sbinkertn@umich.edu for dist,sn,sd,i in map(None, self.dist, self.subnames, self.subdescs, 6051049Sbinkertn@umich.edu range(len(self.dist))): 6061049Sbinkertn@umich.edu if len(sn) > 0: 6071049Sbinkertn@umich.edu name = '%s.%s' % (self.name, sn) 6081049Sbinkertn@umich.edu else: 6091049Sbinkertn@umich.edu name = '%s[%d]' % (self.name, i) 6101049Sbinkertn@umich.edu 6111049Sbinkertn@umich.edu if len(sd) > 0: 6121049Sbinkertn@umich.edu desc = sd 6131049Sbinkertn@umich.edu else: 6141049Sbinkertn@umich.edu desc = self.desc 6151049Sbinkertn@umich.edu 6161049Sbinkertn@umich.edu dist.display(name, desc, self.flags, self.precision) 6171049Sbinkertn@umich.edu 6181049Sbinkertn@umich.edu if (self.flags & flags.total) or 1: 6191049Sbinkertn@umich.edu if isinstance(self.dist[0], SimpleDist): 6201049Sbinkertn@umich.edu disttotal = SimpleDist( \ 6211049Sbinkertn@umich.edu reduce(sums, [d.sums for d in self.dist]), 6221049Sbinkertn@umich.edu reduce(sums, [d.squares for d in self.dist]), 6231049Sbinkertn@umich.edu reduce(sums, [d.samples for d in self.dist])) 6241049Sbinkertn@umich.edu else: 6251049Sbinkertn@umich.edu disttotal = FullDist( \ 6261049Sbinkertn@umich.edu reduce(sums, [d.sums for d in self.dist]), 6271049Sbinkertn@umich.edu reduce(sums, [d.squares for d in self.dist]), 6281049Sbinkertn@umich.edu reduce(sums, [d.samples for d in self.dist]), 6291049Sbinkertn@umich.edu min([d.minval for d in self.dist]), 6301049Sbinkertn@umich.edu max([d.maxval for d in self.dist]), 6311049Sbinkertn@umich.edu reduce(sums, [d.under for d in self.dist]), 6321049Sbinkertn@umich.edu reduce(sums, [d.vec for d in self.dist]), 6331049Sbinkertn@umich.edu reduce(sums, [d.over for d in self.dist]), 6341049Sbinkertn@umich.edu dist[0].min, 6351049Sbinkertn@umich.edu dist[0].max, 6361049Sbinkertn@umich.edu dist[0].bsize, 6371049Sbinkertn@umich.edu dist[0].size) 6381049Sbinkertn@umich.edu 6391049Sbinkertn@umich.edu name = '%s.total' % (self.name) 6401049Sbinkertn@umich.edu desc = self.desc 6411049Sbinkertn@umich.edu disttotal.display(name, desc, self.flags, self.precision) 6421049Sbinkertn@umich.edu 6431049Sbinkertn@umich.edu def comparable(self, other): 6441049Sbinkertn@umich.edu return self.name == other.name and \ 6451049Sbinkertn@umich.edu alltrue(map(lambda x, y : x.comparable(y), 6461049Sbinkertn@umich.edu self.dist, 6471049Sbinkertn@umich.edu other.dist)) 6481049Sbinkertn@umich.edu 6491049Sbinkertn@umich.edu def __eq__(self, other): 6501049Sbinkertn@umich.edu return alltrue(map(lambda x, y : x == y, self.dist, other.dist)) 6511049Sbinkertn@umich.edu 6521049Sbinkertn@umich.edu def __isub__(self, other): 6531547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)) and \ 6541547Sbinkertn@umich.edu isinstance(other.dist, (list, tuple)): 6551049Sbinkertn@umich.edu for sd,od in zip(self.dist, other.dist): 6561049Sbinkertn@umich.edu sd -= od 6571049Sbinkertn@umich.edu else: 6581049Sbinkertn@umich.edu self.dist -= other.dist 6591049Sbinkertn@umich.edu return self 6601049Sbinkertn@umich.edu 6611049Sbinkertn@umich.edu def __iadd__(self, other): 6621547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)) and \ 6631547Sbinkertn@umich.edu isinstance(other.dist, (list, tuple)): 6641049Sbinkertn@umich.edu for sd,od in zip(self.dist, other.dist): 6651049Sbinkertn@umich.edu sd += od 6661049Sbinkertn@umich.edu else: 6671049Sbinkertn@umich.edu self.dist += other.dist 6681049Sbinkertn@umich.edu return self 6691049Sbinkertn@umich.edu 6701049Sbinkertn@umich.edu def __itruediv__(self, other): 6711049Sbinkertn@umich.edu if not other: 6721049Sbinkertn@umich.edu return self 6731547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)): 6741049Sbinkertn@umich.edu for dist in self.dist: 6751049Sbinkertn@umich.edu dist /= other 6761049Sbinkertn@umich.edu else: 6771049Sbinkertn@umich.edu self.dist /= other 6781049Sbinkertn@umich.edu return self 6791049Sbinkertn@umich.edu 6801049Sbinkertn@umich.educlass Vector2d(Statistic): 6811049Sbinkertn@umich.edu def display(self): 6821049Sbinkertn@umich.edu import display 6831049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 6841049Sbinkertn@umich.edu return 6851049Sbinkertn@umich.edu 6861049Sbinkertn@umich.edu d = display.VectorDisplay() 6871049Sbinkertn@umich.edu d.__dict__.update(self.__dict__) 6881049Sbinkertn@umich.edu 6891049Sbinkertn@umich.edu if self.__dict__.has_key('ysubnames'): 6901049Sbinkertn@umich.edu ysubnames = list(self.ysubnames) 6911049Sbinkertn@umich.edu slack = self.x - len(ysubnames) 6921049Sbinkertn@umich.edu if slack > 0: 6931049Sbinkertn@umich.edu ysubnames.extend(['']*slack) 6941049Sbinkertn@umich.edu else: 6951049Sbinkertn@umich.edu ysubnames = range(self.x) 6961049Sbinkertn@umich.edu 6971049Sbinkertn@umich.edu for x,sname in enumerate(ysubnames): 6981049Sbinkertn@umich.edu o = x * self.y 6991049Sbinkertn@umich.edu d.value = self.value[o:o+self.y] 7001049Sbinkertn@umich.edu d.name = '%s[%s]' % (self.name, sname) 7011049Sbinkertn@umich.edu d.display() 7021049Sbinkertn@umich.edu 7031049Sbinkertn@umich.edu if self.flags & flags.total: 7041049Sbinkertn@umich.edu d.value = [] 7051049Sbinkertn@umich.edu for y in range(self.y): 7061049Sbinkertn@umich.edu xtot = 0.0 7071049Sbinkertn@umich.edu for x in range(self.x): 7081049Sbinkertn@umich.edu xtot += self.value[y + x * self.x] 7091049Sbinkertn@umich.edu d.value.append(xtot) 7101049Sbinkertn@umich.edu 7111049Sbinkertn@umich.edu d.name = self.name + '.total' 7121049Sbinkertn@umich.edu d.display() 7131049Sbinkertn@umich.edu 7141049Sbinkertn@umich.edu def comparable(self, other): 7151049Sbinkertn@umich.edu return self.name == other.name and self.x == other.x and \ 7161049Sbinkertn@umich.edu self.y == other.y 7171049Sbinkertn@umich.edu 7181049Sbinkertn@umich.edu def __eq__(self, other): 7191049Sbinkertn@umich.edu return True 7201049Sbinkertn@umich.edu 7211049Sbinkertn@umich.edu def __isub__(self, other): 7221049Sbinkertn@umich.edu return self 7231049Sbinkertn@umich.edu 7241049Sbinkertn@umich.edu def __iadd__(self, other): 7251049Sbinkertn@umich.edu return self 7261049Sbinkertn@umich.edu 7271049Sbinkertn@umich.edu def __itruediv__(self, other): 7281049Sbinkertn@umich.edu if not other: 7291049Sbinkertn@umich.edu return self 7301049Sbinkertn@umich.edu return self 7311049Sbinkertn@umich.edu 7321929Sbinkertn@umich.edudef NewStat(source, data): 7331049Sbinkertn@umich.edu stat = None 7341049Sbinkertn@umich.edu if data.type == 'SCALAR': 7351929Sbinkertn@umich.edu stat = ScalarStat() 7361049Sbinkertn@umich.edu elif data.type == 'VECTOR': 7371929Sbinkertn@umich.edu stat = VectorStat() 7381049Sbinkertn@umich.edu elif data.type == 'DIST': 7391929Sbinkertn@umich.edu stat = Dist() 7401049Sbinkertn@umich.edu elif data.type == 'VECTORDIST': 7411929Sbinkertn@umich.edu stat = VectorDist() 7421049Sbinkertn@umich.edu elif data.type == 'VECTOR2D': 7431929Sbinkertn@umich.edu stat = Vector2d() 7441049Sbinkertn@umich.edu elif data.type == 'FORMULA': 7451929Sbinkertn@umich.edu stat = Formula() 7461929Sbinkertn@umich.edu 7471929Sbinkertn@umich.edu stat.__dict__['source'] = source 7481929Sbinkertn@umich.edu stat.__dict__['bins'] = None 7491929Sbinkertn@umich.edu stat.__dict__['ticks'] = None 7501929Sbinkertn@umich.edu stat.__dict__.update(data.__dict__) 7511049Sbinkertn@umich.edu 7521049Sbinkertn@umich.edu return stat 7531049Sbinkertn@umich.edu 754