info.py revision 1987
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 2571987Sbinkertn@umich.edu try: 2581987Sbinkertn@umich.edu return self.op(val0, val1) 2591987Sbinkertn@umich.edu except ZeroDivisionError: 2601987Sbinkertn@umich.edu return None 2611929Sbinkertn@umich.edu 2621929Sbinkertn@umich.edu def __vectorvalue__(self, run, index): 2631929Sbinkertn@umich.edu if scalar(self.arg0): 2641929Sbinkertn@umich.edu val0 = value(self.arg0, run) 2651929Sbinkertn@umich.edu if vector(self.arg0): 2661929Sbinkertn@umich.edu val0 = value(self.arg0, run, index) 2671929Sbinkertn@umich.edu if scalar(self.arg1): 2681929Sbinkertn@umich.edu val1 = value(self.arg1, run) 2691929Sbinkertn@umich.edu if vector(self.arg1): 2701929Sbinkertn@umich.edu val1 = value(self.arg1, run, index) 2711929Sbinkertn@umich.edu 2721929Sbinkertn@umich.edu if val0 is None or val1 is None: 2731929Sbinkertn@umich.edu return None 2741929Sbinkertn@umich.edu 2751987Sbinkertn@umich.edu try: 2761987Sbinkertn@umich.edu return self.op(val0, val1) 2771987Sbinkertn@umich.edu except ZeroDivisionError: 2781987Sbinkertn@umich.edu return None 2791929Sbinkertn@umich.edu 2801929Sbinkertn@umich.edu def __vectorlen__(self): 2811929Sbinkertn@umich.edu if vector(self.arg0) and scalar(self.arg1): 2821929Sbinkertn@umich.edu return len(self.arg0) 2831929Sbinkertn@umich.edu if scalar(self.arg0) and vector(self.arg1): 2841929Sbinkertn@umich.edu return len(self.arg1) 2851929Sbinkertn@umich.edu 2861929Sbinkertn@umich.edu len0 = len(self.arg0) 2871929Sbinkertn@umich.edu len1 = len(self.arg1) 2881929Sbinkertn@umich.edu 2891929Sbinkertn@umich.edu if len0 != len1: 2901929Sbinkertn@umich.edu raise AttributeError, \ 2911929Sbinkertn@umich.edu "vectors of different lengths %d != %d" % (len0, len1) 2921929Sbinkertn@umich.edu 2931929Sbinkertn@umich.edu return len0 2941929Sbinkertn@umich.edu 2951986Sbinkertn@umich.edu def __str__(self): 2961986Sbinkertn@umich.edu ops = { operator.__add__ : '+', 2971986Sbinkertn@umich.edu operator.__sub__ : '-', 2981986Sbinkertn@umich.edu operator.__mul__ : '*', 2991986Sbinkertn@umich.edu operator.__div__ : '/', 3001986Sbinkertn@umich.edu operator.__truediv__ : '/', 3011986Sbinkertn@umich.edu operator.__floordiv__ : '//' } 3021986Sbinkertn@umich.edu 3031986Sbinkertn@umich.edu return '(%s %s %s)' % (str(self.arg0), ops[self.op], str(self.arg1)) 3041986Sbinkertn@umich.edu 3051929Sbinkertn@umich.educlass Proxy(Value): 3061929Sbinkertn@umich.edu def __init__(self, name, dict): 3071929Sbinkertn@umich.edu self.name = name 3081929Sbinkertn@umich.edu self.dict = dict 3091929Sbinkertn@umich.edu 3101929Sbinkertn@umich.edu def __unproxy__(self): 3111929Sbinkertn@umich.edu return unproxy(self.dict[self.name]) 3121929Sbinkertn@umich.edu 3131929Sbinkertn@umich.edu def __getitem__(self, index): 3141929Sbinkertn@umich.edu return ItemProxy(self, index) 3151929Sbinkertn@umich.edu 3161929Sbinkertn@umich.edu def __getattr__(self, attr): 3171929Sbinkertn@umich.edu return AttrProxy(self, attr) 3181929Sbinkertn@umich.edu 3191986Sbinkertn@umich.edu def __str__(self): 3201986Sbinkertn@umich.edu return str(self.dict[self.name]) 3211986Sbinkertn@umich.edu 3221929Sbinkertn@umich.educlass ItemProxy(Proxy): 3231929Sbinkertn@umich.edu def __init__(self, proxy, index): 3241929Sbinkertn@umich.edu self.proxy = proxy 3251929Sbinkertn@umich.edu self.index = index 3261929Sbinkertn@umich.edu 3271929Sbinkertn@umich.edu def __unproxy__(self): 3281929Sbinkertn@umich.edu return unproxy(unproxy(self.proxy)[self.index]) 3291929Sbinkertn@umich.edu 3301986Sbinkertn@umich.edu def __str__(self): 3311986Sbinkertn@umich.edu return '%s[%s]' % (self.proxy, self.index) 3321986Sbinkertn@umich.edu 3331929Sbinkertn@umich.educlass AttrProxy(Proxy): 3341929Sbinkertn@umich.edu def __init__(self, proxy, attr): 3351929Sbinkertn@umich.edu self.proxy = proxy 3361929Sbinkertn@umich.edu self.attr = attr 3371929Sbinkertn@umich.edu 3381929Sbinkertn@umich.edu def __unproxy__(self): 3391929Sbinkertn@umich.edu return unproxy(getattr(unproxy(self.proxy), self.attr)) 3401929Sbinkertn@umich.edu 3411986Sbinkertn@umich.edu def __str__(self): 3421986Sbinkertn@umich.edu return '%s.%s' % (self.proxy, self.attr) 3431986Sbinkertn@umich.edu 3441929Sbinkertn@umich.educlass ProxyGroup(object): 3451929Sbinkertn@umich.edu def __init__(self, dict=None, **kwargs): 3461929Sbinkertn@umich.edu self.__dict__['dict'] = {} 3471929Sbinkertn@umich.edu 3481929Sbinkertn@umich.edu if dict is not None: 3491929Sbinkertn@umich.edu self.dict.update(dict) 3501929Sbinkertn@umich.edu 3511929Sbinkertn@umich.edu if kwargs: 3521929Sbinkertn@umich.edu self.dict.update(kwargs) 3531929Sbinkertn@umich.edu 3541929Sbinkertn@umich.edu def __getattr__(self, name): 3551929Sbinkertn@umich.edu return Proxy(name, self.dict) 3561929Sbinkertn@umich.edu 3571929Sbinkertn@umich.edu def __setattr__(self, attr, value): 3581929Sbinkertn@umich.edu self.dict[attr] = value 3591929Sbinkertn@umich.edu 3601929Sbinkertn@umich.educlass ScalarStat(Statistic,Scalar): 3611929Sbinkertn@umich.edu def __value__(self, run): 3621929Sbinkertn@umich.edu if run not in self.data: 3631929Sbinkertn@umich.edu return None 3641929Sbinkertn@umich.edu return self.data[run][0][0] 3651929Sbinkertn@umich.edu 3661929Sbinkertn@umich.edu def display(self, run=None): 3671049Sbinkertn@umich.edu import display 3681049Sbinkertn@umich.edu p = display.Print() 3691049Sbinkertn@umich.edu p.name = self.name 3701049Sbinkertn@umich.edu p.desc = self.desc 3711929Sbinkertn@umich.edu p.value = value(self, run) 3721049Sbinkertn@umich.edu p.flags = self.flags 3731049Sbinkertn@umich.edu p.precision = self.precision 3741049Sbinkertn@umich.edu if display.all or (self.flags & flags.printable): 3751049Sbinkertn@umich.edu p.display() 3761049Sbinkertn@umich.edu 3771929Sbinkertn@umich.educlass VectorStat(Statistic,Vector): 3781929Sbinkertn@umich.edu def __value__(self, run, item): 3791929Sbinkertn@umich.edu if run not in self.data: 3801929Sbinkertn@umich.edu return None 3811929Sbinkertn@umich.edu return self.data[run][item][0] 3821049Sbinkertn@umich.edu 3831929Sbinkertn@umich.edu def __len__(self): 3841929Sbinkertn@umich.edu return self.x 3851049Sbinkertn@umich.edu 3861929Sbinkertn@umich.edu def display(self, run=None): 3871049Sbinkertn@umich.edu import display 3881049Sbinkertn@umich.edu d = display.VectorDisplay() 3891929Sbinkertn@umich.edu d.name = self.name 3901929Sbinkertn@umich.edu d.desc = self.desc 3911929Sbinkertn@umich.edu d.value = [ value(self, run, i) for i in xrange(len(self)) ] 3921929Sbinkertn@umich.edu d.flags = self.flags 3931929Sbinkertn@umich.edu d.precision = self.precision 3941049Sbinkertn@umich.edu d.display() 3951049Sbinkertn@umich.edu 3961929Sbinkertn@umich.educlass Formula(Value): 3971929Sbinkertn@umich.edu def __getattribute__(self, attr): 3981929Sbinkertn@umich.edu if attr not in ( '__scalar__', '__vector__', '__value__', '__len__' ): 3991929Sbinkertn@umich.edu return super(Formula, self).__getattribute__(attr) 4001049Sbinkertn@umich.edu 4011929Sbinkertn@umich.edu formula = re.sub(':', '__', self.formula) 4021929Sbinkertn@umich.edu value = eval(formula, self.source.stattop) 4031929Sbinkertn@umich.edu return getattr(value, attr) 4041049Sbinkertn@umich.edu 4051986Sbinkertn@umich.edu def __str__(self): 4061986Sbinkertn@umich.edu return self.name 4071986Sbinkertn@umich.edu 4081929Sbinkertn@umich.educlass SimpleDist(Statistic): 4091049Sbinkertn@umich.edu def __init__(self, sums, squares, samples): 4101049Sbinkertn@umich.edu self.sums = sums 4111049Sbinkertn@umich.edu self.squares = squares 4121049Sbinkertn@umich.edu self.samples = samples 4131049Sbinkertn@umich.edu 4141049Sbinkertn@umich.edu def display(self, name, desc, flags, precision): 4151049Sbinkertn@umich.edu import display 4161049Sbinkertn@umich.edu p = display.Print() 4171049Sbinkertn@umich.edu p.flags = flags 4181049Sbinkertn@umich.edu p.precision = precision 4191049Sbinkertn@umich.edu 4201049Sbinkertn@umich.edu if self.samples > 0: 4211049Sbinkertn@umich.edu p.name = name + ".mean" 4221049Sbinkertn@umich.edu p.value = self.sums / self.samples 4231049Sbinkertn@umich.edu p.display() 4241049Sbinkertn@umich.edu 4251049Sbinkertn@umich.edu p.name = name + ".stdev" 4261049Sbinkertn@umich.edu if self.samples > 1: 4271049Sbinkertn@umich.edu var = (self.samples * self.squares - self.sums ** 2) \ 4281049Sbinkertn@umich.edu / (self.samples * (self.samples - 1)) 4291049Sbinkertn@umich.edu if var >= 0: 4301049Sbinkertn@umich.edu p.value = math.sqrt(var) 4311049Sbinkertn@umich.edu else: 4321049Sbinkertn@umich.edu p.value = 'NaN' 4331049Sbinkertn@umich.edu else: 4341049Sbinkertn@umich.edu p.value = 0.0 4351049Sbinkertn@umich.edu p.display() 4361049Sbinkertn@umich.edu 4371049Sbinkertn@umich.edu p.name = name + ".samples" 4381049Sbinkertn@umich.edu p.value = self.samples 4391049Sbinkertn@umich.edu p.display() 4401049Sbinkertn@umich.edu 4411049Sbinkertn@umich.edu def comparable(self, other): 4421049Sbinkertn@umich.edu return True 4431049Sbinkertn@umich.edu 4441049Sbinkertn@umich.edu def __eq__(self, other): 4451049Sbinkertn@umich.edu return self.sums == other.sums and self.squares == other.squares and \ 4461049Sbinkertn@umich.edu self.samples == other.samples 4471049Sbinkertn@umich.edu 4481049Sbinkertn@umich.edu def __isub__(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 __iadd__(self, other): 4551049Sbinkertn@umich.edu self.sums += other.sums 4561049Sbinkertn@umich.edu self.squares += other.squares 4571049Sbinkertn@umich.edu self.samples += other.samples 4581049Sbinkertn@umich.edu return self 4591049Sbinkertn@umich.edu 4601049Sbinkertn@umich.edu def __itruediv__(self, other): 4611049Sbinkertn@umich.edu if not other: 4621049Sbinkertn@umich.edu return self 4631049Sbinkertn@umich.edu self.sums /= other 4641049Sbinkertn@umich.edu self.squares /= other 4651049Sbinkertn@umich.edu self.samples /= other 4661049Sbinkertn@umich.edu return self 4671049Sbinkertn@umich.edu 4681049Sbinkertn@umich.educlass FullDist(SimpleDist): 4691049Sbinkertn@umich.edu def __init__(self, sums, squares, samples, minval, maxval, 4701049Sbinkertn@umich.edu under, vec, over, min, max, bsize, size): 4711049Sbinkertn@umich.edu self.sums = sums 4721049Sbinkertn@umich.edu self.squares = squares 4731049Sbinkertn@umich.edu self.samples = samples 4741049Sbinkertn@umich.edu self.minval = minval 4751049Sbinkertn@umich.edu self.maxval = maxval 4761049Sbinkertn@umich.edu self.under = under 4771049Sbinkertn@umich.edu self.vec = vec 4781049Sbinkertn@umich.edu self.over = over 4791049Sbinkertn@umich.edu self.min = min 4801049Sbinkertn@umich.edu self.max = max 4811049Sbinkertn@umich.edu self.bsize = bsize 4821049Sbinkertn@umich.edu self.size = size 4831049Sbinkertn@umich.edu 4841049Sbinkertn@umich.edu def display(self, name, desc, flags, precision): 4851049Sbinkertn@umich.edu import display 4861049Sbinkertn@umich.edu p = display.Print() 4871049Sbinkertn@umich.edu p.flags = flags 4881049Sbinkertn@umich.edu p.precision = precision 4891049Sbinkertn@umich.edu 4901049Sbinkertn@umich.edu p.name = name + '.min_val' 4911049Sbinkertn@umich.edu p.value = self.minval 4921049Sbinkertn@umich.edu p.display() 4931049Sbinkertn@umich.edu 4941049Sbinkertn@umich.edu p.name = name + '.max_val' 4951049Sbinkertn@umich.edu p.value = self.maxval 4961049Sbinkertn@umich.edu p.display() 4971049Sbinkertn@umich.edu 4981049Sbinkertn@umich.edu p.name = name + '.underflow' 4991049Sbinkertn@umich.edu p.value = self.under 5001049Sbinkertn@umich.edu p.display() 5011049Sbinkertn@umich.edu 5021049Sbinkertn@umich.edu i = self.min 5031049Sbinkertn@umich.edu for val in self.vec[:-1]: 5041049Sbinkertn@umich.edu p.name = name + '[%d:%d]' % (i, i + self.bsize - 1) 5051049Sbinkertn@umich.edu p.value = val 5061049Sbinkertn@umich.edu p.display() 5071049Sbinkertn@umich.edu i += self.bsize 5081049Sbinkertn@umich.edu 5091049Sbinkertn@umich.edu p.name = name + '[%d:%d]' % (i, self.max) 5101049Sbinkertn@umich.edu p.value = self.vec[-1] 5111049Sbinkertn@umich.edu p.display() 5121049Sbinkertn@umich.edu 5131049Sbinkertn@umich.edu 5141049Sbinkertn@umich.edu p.name = name + '.overflow' 5151049Sbinkertn@umich.edu p.value = self.over 5161049Sbinkertn@umich.edu p.display() 5171049Sbinkertn@umich.edu 5181049Sbinkertn@umich.edu SimpleDist.display(self, name, desc, flags, precision) 5191049Sbinkertn@umich.edu 5201049Sbinkertn@umich.edu def comparable(self, other): 5211049Sbinkertn@umich.edu return self.min == other.min and self.max == other.max and \ 5221049Sbinkertn@umich.edu self.bsize == other.bsize and self.size == other.size 5231049Sbinkertn@umich.edu 5241049Sbinkertn@umich.edu def __eq__(self, other): 5251049Sbinkertn@umich.edu return self.sums == other.sums and self.squares == other.squares and \ 5261049Sbinkertn@umich.edu self.samples == other.samples 5271049Sbinkertn@umich.edu 5281049Sbinkertn@umich.edu def __isub__(self, other): 5291049Sbinkertn@umich.edu self.sums -= other.sums 5301049Sbinkertn@umich.edu self.squares -= other.squares 5311049Sbinkertn@umich.edu self.samples -= other.samples 5321049Sbinkertn@umich.edu 5331049Sbinkertn@umich.edu if other.samples: 5341049Sbinkertn@umich.edu self.minval = min(self.minval, other.minval) 5351049Sbinkertn@umich.edu self.maxval = max(self.maxval, other.maxval) 5361049Sbinkertn@umich.edu self.under -= under 5371049Sbinkertn@umich.edu self.vec = map(lambda x,y: x - y, self.vec, other.vec) 5381049Sbinkertn@umich.edu self.over -= over 5391049Sbinkertn@umich.edu return self 5401049Sbinkertn@umich.edu 5411049Sbinkertn@umich.edu def __iadd__(self, other): 5421049Sbinkertn@umich.edu if not self.samples and other.samples: 5431049Sbinkertn@umich.edu self = other 5441049Sbinkertn@umich.edu return self 5451049Sbinkertn@umich.edu 5461049Sbinkertn@umich.edu self.sums += other.sums 5471049Sbinkertn@umich.edu self.squares += other.squares 5481049Sbinkertn@umich.edu self.samples += other.samples 5491049Sbinkertn@umich.edu 5501049Sbinkertn@umich.edu if other.samples: 5511049Sbinkertn@umich.edu self.minval = min(self.minval, other.minval) 5521049Sbinkertn@umich.edu self.maxval = max(self.maxval, other.maxval) 5531049Sbinkertn@umich.edu self.under += other.under 5541049Sbinkertn@umich.edu self.vec = map(lambda x,y: x + y, self.vec, other.vec) 5551049Sbinkertn@umich.edu self.over += other.over 5561049Sbinkertn@umich.edu return self 5571049Sbinkertn@umich.edu 5581049Sbinkertn@umich.edu def __itruediv__(self, other): 5591049Sbinkertn@umich.edu if not other: 5601049Sbinkertn@umich.edu return self 5611049Sbinkertn@umich.edu self.sums /= other 5621049Sbinkertn@umich.edu self.squares /= other 5631049Sbinkertn@umich.edu self.samples /= other 5641049Sbinkertn@umich.edu 5651049Sbinkertn@umich.edu if self.samples: 5661049Sbinkertn@umich.edu self.under /= other 5671049Sbinkertn@umich.edu for i in xrange(len(self.vec)): 5681049Sbinkertn@umich.edu self.vec[i] /= other 5691049Sbinkertn@umich.edu self.over /= other 5701049Sbinkertn@umich.edu return self 5711049Sbinkertn@umich.edu 5721049Sbinkertn@umich.educlass Dist(Statistic): 5731049Sbinkertn@umich.edu def display(self): 5741049Sbinkertn@umich.edu import display 5751049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 5761049Sbinkertn@umich.edu return 5771049Sbinkertn@umich.edu 5781049Sbinkertn@umich.edu self.dist.display(self.name, self.desc, self.flags, self.precision) 5791049Sbinkertn@umich.edu 5801049Sbinkertn@umich.edu def comparable(self, other): 5811049Sbinkertn@umich.edu return self.name == other.name and \ 5821049Sbinkertn@umich.edu self.dist.compareable(other.dist) 5831049Sbinkertn@umich.edu 5841049Sbinkertn@umich.edu def __eq__(self, other): 5851049Sbinkertn@umich.edu return self.dist == other.dist 5861049Sbinkertn@umich.edu 5871049Sbinkertn@umich.edu def __isub__(self, other): 5881049Sbinkertn@umich.edu self.dist -= other.dist 5891049Sbinkertn@umich.edu return self 5901049Sbinkertn@umich.edu 5911049Sbinkertn@umich.edu def __iadd__(self, other): 5921049Sbinkertn@umich.edu self.dist += other.dist 5931049Sbinkertn@umich.edu return self 5941049Sbinkertn@umich.edu 5951049Sbinkertn@umich.edu def __itruediv__(self, other): 5961049Sbinkertn@umich.edu if not other: 5971049Sbinkertn@umich.edu return self 5981049Sbinkertn@umich.edu self.dist /= other 5991049Sbinkertn@umich.edu return self 6001049Sbinkertn@umich.edu 6011049Sbinkertn@umich.educlass VectorDist(Statistic): 6021049Sbinkertn@umich.edu def display(self): 6031049Sbinkertn@umich.edu import display 6041049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 6051049Sbinkertn@umich.edu return 6061049Sbinkertn@umich.edu 6071049Sbinkertn@umich.edu if isinstance(self.dist, SimpleDist): 6081049Sbinkertn@umich.edu return 6091049Sbinkertn@umich.edu 6101049Sbinkertn@umich.edu for dist,sn,sd,i in map(None, self.dist, self.subnames, self.subdescs, 6111049Sbinkertn@umich.edu range(len(self.dist))): 6121049Sbinkertn@umich.edu if len(sn) > 0: 6131049Sbinkertn@umich.edu name = '%s.%s' % (self.name, sn) 6141049Sbinkertn@umich.edu else: 6151049Sbinkertn@umich.edu name = '%s[%d]' % (self.name, i) 6161049Sbinkertn@umich.edu 6171049Sbinkertn@umich.edu if len(sd) > 0: 6181049Sbinkertn@umich.edu desc = sd 6191049Sbinkertn@umich.edu else: 6201049Sbinkertn@umich.edu desc = self.desc 6211049Sbinkertn@umich.edu 6221049Sbinkertn@umich.edu dist.display(name, desc, self.flags, self.precision) 6231049Sbinkertn@umich.edu 6241049Sbinkertn@umich.edu if (self.flags & flags.total) or 1: 6251049Sbinkertn@umich.edu if isinstance(self.dist[0], SimpleDist): 6261049Sbinkertn@umich.edu disttotal = SimpleDist( \ 6271049Sbinkertn@umich.edu reduce(sums, [d.sums for d in self.dist]), 6281049Sbinkertn@umich.edu reduce(sums, [d.squares for d in self.dist]), 6291049Sbinkertn@umich.edu reduce(sums, [d.samples for d in self.dist])) 6301049Sbinkertn@umich.edu else: 6311049Sbinkertn@umich.edu disttotal = FullDist( \ 6321049Sbinkertn@umich.edu reduce(sums, [d.sums for d in self.dist]), 6331049Sbinkertn@umich.edu reduce(sums, [d.squares for d in self.dist]), 6341049Sbinkertn@umich.edu reduce(sums, [d.samples for d in self.dist]), 6351049Sbinkertn@umich.edu min([d.minval for d in self.dist]), 6361049Sbinkertn@umich.edu max([d.maxval for d in self.dist]), 6371049Sbinkertn@umich.edu reduce(sums, [d.under for d in self.dist]), 6381049Sbinkertn@umich.edu reduce(sums, [d.vec for d in self.dist]), 6391049Sbinkertn@umich.edu reduce(sums, [d.over for d in self.dist]), 6401049Sbinkertn@umich.edu dist[0].min, 6411049Sbinkertn@umich.edu dist[0].max, 6421049Sbinkertn@umich.edu dist[0].bsize, 6431049Sbinkertn@umich.edu dist[0].size) 6441049Sbinkertn@umich.edu 6451049Sbinkertn@umich.edu name = '%s.total' % (self.name) 6461049Sbinkertn@umich.edu desc = self.desc 6471049Sbinkertn@umich.edu disttotal.display(name, desc, self.flags, self.precision) 6481049Sbinkertn@umich.edu 6491049Sbinkertn@umich.edu def comparable(self, other): 6501049Sbinkertn@umich.edu return self.name == other.name and \ 6511049Sbinkertn@umich.edu alltrue(map(lambda x, y : x.comparable(y), 6521049Sbinkertn@umich.edu self.dist, 6531049Sbinkertn@umich.edu other.dist)) 6541049Sbinkertn@umich.edu 6551049Sbinkertn@umich.edu def __eq__(self, other): 6561049Sbinkertn@umich.edu return alltrue(map(lambda x, y : x == y, self.dist, other.dist)) 6571049Sbinkertn@umich.edu 6581049Sbinkertn@umich.edu def __isub__(self, other): 6591547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)) and \ 6601547Sbinkertn@umich.edu isinstance(other.dist, (list, tuple)): 6611049Sbinkertn@umich.edu for sd,od in zip(self.dist, other.dist): 6621049Sbinkertn@umich.edu sd -= od 6631049Sbinkertn@umich.edu else: 6641049Sbinkertn@umich.edu self.dist -= other.dist 6651049Sbinkertn@umich.edu return self 6661049Sbinkertn@umich.edu 6671049Sbinkertn@umich.edu def __iadd__(self, other): 6681547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)) and \ 6691547Sbinkertn@umich.edu isinstance(other.dist, (list, tuple)): 6701049Sbinkertn@umich.edu for sd,od in zip(self.dist, other.dist): 6711049Sbinkertn@umich.edu sd += od 6721049Sbinkertn@umich.edu else: 6731049Sbinkertn@umich.edu self.dist += other.dist 6741049Sbinkertn@umich.edu return self 6751049Sbinkertn@umich.edu 6761049Sbinkertn@umich.edu def __itruediv__(self, other): 6771049Sbinkertn@umich.edu if not other: 6781049Sbinkertn@umich.edu return self 6791547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)): 6801049Sbinkertn@umich.edu for dist in self.dist: 6811049Sbinkertn@umich.edu dist /= other 6821049Sbinkertn@umich.edu else: 6831049Sbinkertn@umich.edu self.dist /= other 6841049Sbinkertn@umich.edu return self 6851049Sbinkertn@umich.edu 6861049Sbinkertn@umich.educlass Vector2d(Statistic): 6871049Sbinkertn@umich.edu def display(self): 6881049Sbinkertn@umich.edu import display 6891049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 6901049Sbinkertn@umich.edu return 6911049Sbinkertn@umich.edu 6921049Sbinkertn@umich.edu d = display.VectorDisplay() 6931049Sbinkertn@umich.edu d.__dict__.update(self.__dict__) 6941049Sbinkertn@umich.edu 6951049Sbinkertn@umich.edu if self.__dict__.has_key('ysubnames'): 6961049Sbinkertn@umich.edu ysubnames = list(self.ysubnames) 6971049Sbinkertn@umich.edu slack = self.x - len(ysubnames) 6981049Sbinkertn@umich.edu if slack > 0: 6991049Sbinkertn@umich.edu ysubnames.extend(['']*slack) 7001049Sbinkertn@umich.edu else: 7011049Sbinkertn@umich.edu ysubnames = range(self.x) 7021049Sbinkertn@umich.edu 7031049Sbinkertn@umich.edu for x,sname in enumerate(ysubnames): 7041049Sbinkertn@umich.edu o = x * self.y 7051049Sbinkertn@umich.edu d.value = self.value[o:o+self.y] 7061049Sbinkertn@umich.edu d.name = '%s[%s]' % (self.name, sname) 7071049Sbinkertn@umich.edu d.display() 7081049Sbinkertn@umich.edu 7091049Sbinkertn@umich.edu if self.flags & flags.total: 7101049Sbinkertn@umich.edu d.value = [] 7111049Sbinkertn@umich.edu for y in range(self.y): 7121049Sbinkertn@umich.edu xtot = 0.0 7131049Sbinkertn@umich.edu for x in range(self.x): 7141049Sbinkertn@umich.edu xtot += self.value[y + x * self.x] 7151049Sbinkertn@umich.edu d.value.append(xtot) 7161049Sbinkertn@umich.edu 7171049Sbinkertn@umich.edu d.name = self.name + '.total' 7181049Sbinkertn@umich.edu d.display() 7191049Sbinkertn@umich.edu 7201049Sbinkertn@umich.edu def comparable(self, other): 7211049Sbinkertn@umich.edu return self.name == other.name and self.x == other.x and \ 7221049Sbinkertn@umich.edu self.y == other.y 7231049Sbinkertn@umich.edu 7241049Sbinkertn@umich.edu def __eq__(self, other): 7251049Sbinkertn@umich.edu return True 7261049Sbinkertn@umich.edu 7271049Sbinkertn@umich.edu def __isub__(self, other): 7281049Sbinkertn@umich.edu return self 7291049Sbinkertn@umich.edu 7301049Sbinkertn@umich.edu def __iadd__(self, other): 7311049Sbinkertn@umich.edu return self 7321049Sbinkertn@umich.edu 7331049Sbinkertn@umich.edu def __itruediv__(self, other): 7341049Sbinkertn@umich.edu if not other: 7351049Sbinkertn@umich.edu return self 7361049Sbinkertn@umich.edu return self 7371049Sbinkertn@umich.edu 7381929Sbinkertn@umich.edudef NewStat(source, data): 7391049Sbinkertn@umich.edu stat = None 7401049Sbinkertn@umich.edu if data.type == 'SCALAR': 7411929Sbinkertn@umich.edu stat = ScalarStat() 7421049Sbinkertn@umich.edu elif data.type == 'VECTOR': 7431929Sbinkertn@umich.edu stat = VectorStat() 7441049Sbinkertn@umich.edu elif data.type == 'DIST': 7451929Sbinkertn@umich.edu stat = Dist() 7461049Sbinkertn@umich.edu elif data.type == 'VECTORDIST': 7471929Sbinkertn@umich.edu stat = VectorDist() 7481049Sbinkertn@umich.edu elif data.type == 'VECTOR2D': 7491929Sbinkertn@umich.edu stat = Vector2d() 7501049Sbinkertn@umich.edu elif data.type == 'FORMULA': 7511929Sbinkertn@umich.edu stat = Formula() 7521929Sbinkertn@umich.edu 7531929Sbinkertn@umich.edu stat.__dict__['source'] = source 7541929Sbinkertn@umich.edu stat.__dict__['bins'] = None 7551929Sbinkertn@umich.edu stat.__dict__['ticks'] = None 7561929Sbinkertn@umich.edu stat.__dict__.update(data.__dict__) 7571049Sbinkertn@umich.edu 7581049Sbinkertn@umich.edu return stat 7591049Sbinkertn@umich.edu 760