info.py revision 2015
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 302015Sbinkertn@umich.educlass ProxyError(Exception): 312015Sbinkertn@umich.edu pass 322015Sbinkertn@umich.edu 331929Sbinkertn@umich.edudef unproxy(proxy): 341929Sbinkertn@umich.edu if hasattr(proxy, '__unproxy__'): 351929Sbinkertn@umich.edu return proxy.__unproxy__() 361049Sbinkertn@umich.edu 371929Sbinkertn@umich.edu return proxy 381049Sbinkertn@umich.edu 391929Sbinkertn@umich.edudef scalar(stat): 401929Sbinkertn@umich.edu stat = unproxy(stat) 411929Sbinkertn@umich.edu assert(stat.__scalar__() != stat.__vector__()) 421929Sbinkertn@umich.edu return stat.__scalar__() 431049Sbinkertn@umich.edu 441929Sbinkertn@umich.edudef vector(stat): 451929Sbinkertn@umich.edu stat = unproxy(stat) 461929Sbinkertn@umich.edu assert(stat.__scalar__() != stat.__vector__()) 471929Sbinkertn@umich.edu return stat.__vector__() 481049Sbinkertn@umich.edu 491929Sbinkertn@umich.edudef value(stat, *args): 501929Sbinkertn@umich.edu stat = unproxy(stat) 511929Sbinkertn@umich.edu return stat.__value__(*args) 521049Sbinkertn@umich.edu 531929Sbinkertn@umich.edudef values(stat, run): 541929Sbinkertn@umich.edu stat = unproxy(stat) 551929Sbinkertn@umich.edu result = [] 561929Sbinkertn@umich.edu for i in xrange(len(stat)): 571934Sbinkertn@umich.edu val = value(stat, run, i) 581929Sbinkertn@umich.edu if val is None: 591929Sbinkertn@umich.edu return None 601929Sbinkertn@umich.edu result.append(val) 611049Sbinkertn@umich.edu return result 621049Sbinkertn@umich.edu 631929Sbinkertn@umich.edudef total(stat, run): 641929Sbinkertn@umich.edu return sum(values(stat, run)) 651049Sbinkertn@umich.edu 661929Sbinkertn@umich.edudef len(stat): 671929Sbinkertn@umich.edu stat = unproxy(stat) 681929Sbinkertn@umich.edu return stat.__len__() 691049Sbinkertn@umich.edu 701929Sbinkertn@umich.educlass Value(object): 711929Sbinkertn@umich.edu def __scalar__(self): 721929Sbinkertn@umich.edu raise AttributeError, "must define __scalar__ for %s" % (type (self)) 731929Sbinkertn@umich.edu def __vector__(self): 741929Sbinkertn@umich.edu raise AttributeError, "must define __vector__ for %s" % (type (self)) 751049Sbinkertn@umich.edu 761929Sbinkertn@umich.edu def __add__(self, other): 771929Sbinkertn@umich.edu return BinaryProxy(operator.__add__, self, other) 781929Sbinkertn@umich.edu def __sub__(self, other): 791929Sbinkertn@umich.edu return BinaryProxy(operator.__sub__, self, other) 801929Sbinkertn@umich.edu def __mul__(self, other): 811929Sbinkertn@umich.edu return BinaryProxy(operator.__mul__, self, other) 821929Sbinkertn@umich.edu def __div__(self, other): 831929Sbinkertn@umich.edu return BinaryProxy(operator.__div__, self, other) 841929Sbinkertn@umich.edu def __truediv__(self, other): 851929Sbinkertn@umich.edu return BinaryProxy(operator.__truediv__, self, other) 861929Sbinkertn@umich.edu def __floordiv__(self, other): 871929Sbinkertn@umich.edu return BinaryProxy(operator.__floordiv__, self, other) 881049Sbinkertn@umich.edu 891929Sbinkertn@umich.edu def __radd__(self, other): 901929Sbinkertn@umich.edu return BinaryProxy(operator.__add__, other, self) 911929Sbinkertn@umich.edu def __rsub__(self, other): 921929Sbinkertn@umich.edu return BinaryProxy(operator.__sub__, other, self) 931929Sbinkertn@umich.edu def __rmul__(self, other): 941929Sbinkertn@umich.edu return BinaryProxy(operator.__mul__, other, self) 951929Sbinkertn@umich.edu def __rdiv__(self, other): 961929Sbinkertn@umich.edu return BinaryProxy(operator.__div__, other, self) 971929Sbinkertn@umich.edu def __rtruediv__(self, other): 981929Sbinkertn@umich.edu return BinaryProxy(operator.__truediv__, other, self) 991929Sbinkertn@umich.edu def __rfloordiv__(self, other): 1001929Sbinkertn@umich.edu return BinaryProxy(operator.__floordiv__, other, self) 1011929Sbinkertn@umich.edu 1021929Sbinkertn@umich.edu def __neg__(self): 1031929Sbinkertn@umich.edu return UnaryProxy(operator.__neg__, self) 1041929Sbinkertn@umich.edu def __pos__(self): 1051929Sbinkertn@umich.edu return UnaryProxy(operator.__pos__, self) 1061929Sbinkertn@umich.edu def __abs__(self): 1071929Sbinkertn@umich.edu return UnaryProxy(operator.__abs__, self) 1081929Sbinkertn@umich.edu 1091929Sbinkertn@umich.educlass Scalar(Value): 1101929Sbinkertn@umich.edu def __scalar__(self): 1111929Sbinkertn@umich.edu return True 1121929Sbinkertn@umich.edu 1131929Sbinkertn@umich.edu def __vector__(self): 1141929Sbinkertn@umich.edu return False 1151929Sbinkertn@umich.edu 1161929Sbinkertn@umich.edu def __value__(self, run): 1171929Sbinkertn@umich.edu raise AttributeError, '__value__ must be defined' 1181929Sbinkertn@umich.edu 1191929Sbinkertn@umich.educlass VectorItemProxy(Value): 1201929Sbinkertn@umich.edu def __init__(self, proxy, index): 1211929Sbinkertn@umich.edu self.proxy = proxy 1221929Sbinkertn@umich.edu self.index = index 1231929Sbinkertn@umich.edu 1241929Sbinkertn@umich.edu def __scalar__(self): 1251929Sbinkertn@umich.edu return True 1261929Sbinkertn@umich.edu 1271929Sbinkertn@umich.edu def __vector__(self): 1281929Sbinkertn@umich.edu return False 1291929Sbinkertn@umich.edu 1301929Sbinkertn@umich.edu def __value__(self, run): 1311929Sbinkertn@umich.edu return value(self.proxy, run, self.index) 1321929Sbinkertn@umich.edu 1331929Sbinkertn@umich.educlass Vector(Value): 1341929Sbinkertn@umich.edu def __scalar__(self): 1351929Sbinkertn@umich.edu return False 1361929Sbinkertn@umich.edu 1371929Sbinkertn@umich.edu def __vector__(self): 1381929Sbinkertn@umich.edu return True 1391929Sbinkertn@umich.edu 1401929Sbinkertn@umich.edu def __value__(self, run, index): 1411929Sbinkertn@umich.edu raise AttributeError, '__value__ must be defined' 1421929Sbinkertn@umich.edu 1431929Sbinkertn@umich.edu def __getitem__(self, index): 1441929Sbinkertn@umich.edu return VectorItemProxy(self, index) 1451929Sbinkertn@umich.edu 1461929Sbinkertn@umich.educlass ScalarConstant(Scalar): 1471929Sbinkertn@umich.edu def __init__(self, constant): 1481929Sbinkertn@umich.edu self.constant = constant 1491929Sbinkertn@umich.edu def __value__(self, run): 1501929Sbinkertn@umich.edu return self.constant 1511986Sbinkertn@umich.edu def __str__(self): 1521986Sbinkertn@umich.edu return str(self.constant) 1531929Sbinkertn@umich.edu 1541929Sbinkertn@umich.educlass VectorConstant(Vector): 1551929Sbinkertn@umich.edu def __init__(self, constant): 1561929Sbinkertn@umich.edu self.constant = constant 1571929Sbinkertn@umich.edu def __value__(self, run, index): 1581929Sbinkertn@umich.edu return self.constant[index] 1591929Sbinkertn@umich.edu def __len__(self): 1601929Sbinkertn@umich.edu return len(self.constant) 1611986Sbinkertn@umich.edu def __str__(self): 1621986Sbinkertn@umich.edu return str(self.constant) 1631929Sbinkertn@umich.edu 1641929Sbinkertn@umich.edudef WrapValue(value): 1651929Sbinkertn@umich.edu if isinstance(value, (int, long, float)): 1661929Sbinkertn@umich.edu return ScalarConstant(value) 1671929Sbinkertn@umich.edu if isinstance(value, (list, tuple)): 1681929Sbinkertn@umich.edu return VectorConstant(value) 1691929Sbinkertn@umich.edu if isinstance(value, Value): 1701929Sbinkertn@umich.edu return value 1711929Sbinkertn@umich.edu 1721929Sbinkertn@umich.edu raise AttributeError, 'Only values can be wrapped' 1731049Sbinkertn@umich.edu 1741049Sbinkertn@umich.educlass Statistic(object): 1751929Sbinkertn@umich.edu def __getattr__(self, attr): 1761929Sbinkertn@umich.edu if attr in ('data', 'x', 'y'): 1771929Sbinkertn@umich.edu result = self.source.data(self, self.bins, self.ticks) 1781929Sbinkertn@umich.edu self.data = result.data 1791929Sbinkertn@umich.edu self.x = result.x 1801929Sbinkertn@umich.edu self.y = result.y 1811929Sbinkertn@umich.edu return super(Statistic, self).__getattribute__(attr) 1821049Sbinkertn@umich.edu 1831049Sbinkertn@umich.edu def __setattr__(self, attr, value): 1841929Sbinkertn@umich.edu if attr == 'stat': 1851929Sbinkertn@umich.edu raise AttributeError, '%s is read only' % stat 1861929Sbinkertn@umich.edu if attr in ('source', 'bins', 'ticks'): 1871929Sbinkertn@umich.edu if getattr(self, attr) != value: 1881929Sbinkertn@umich.edu if hasattr(self, 'data'): 1891929Sbinkertn@umich.edu delattr(self, 'data') 1901049Sbinkertn@umich.edu 1911929Sbinkertn@umich.edu super(Statistic, self).__setattr__(attr, value) 1921049Sbinkertn@umich.edu 1931986Sbinkertn@umich.edu def __str__(self): 1941986Sbinkertn@umich.edu return self.name 1951986Sbinkertn@umich.edu 1961929Sbinkertn@umich.educlass ValueProxy(Value): 1971929Sbinkertn@umich.edu def __getattr__(self, attr): 1981929Sbinkertn@umich.edu if attr == '__value__': 1991929Sbinkertn@umich.edu if scalar(self): 2001929Sbinkertn@umich.edu return self.__scalarvalue__ 2011929Sbinkertn@umich.edu if vector(self): 2021929Sbinkertn@umich.edu return self.__vectorvalue__ 2031929Sbinkertn@umich.edu if attr == '__len__': 2041929Sbinkertn@umich.edu if vector(self): 2051929Sbinkertn@umich.edu return self.__vectorlen__ 2061929Sbinkertn@umich.edu return super(ValueProxy, self).__getattribute__(attr) 2071049Sbinkertn@umich.edu 2081929Sbinkertn@umich.educlass UnaryProxy(ValueProxy): 2091929Sbinkertn@umich.edu def __init__(self, op, arg): 2101929Sbinkertn@umich.edu self.op = op 2111929Sbinkertn@umich.edu self.arg = WrapValue(arg) 2121049Sbinkertn@umich.edu 2131929Sbinkertn@umich.edu def __scalar__(self): 2141929Sbinkertn@umich.edu return scalar(self.arg) 2151049Sbinkertn@umich.edu 2161929Sbinkertn@umich.edu def __vector__(self): 2171929Sbinkertn@umich.edu return vector(self.arg) 2181049Sbinkertn@umich.edu 2191929Sbinkertn@umich.edu def __scalarvalue__(self, run): 2201929Sbinkertn@umich.edu val = value(self.arg, run) 2211929Sbinkertn@umich.edu if val is None: 2221929Sbinkertn@umich.edu return None 2231929Sbinkertn@umich.edu return self.op(val) 2241049Sbinkertn@umich.edu 2251929Sbinkertn@umich.edu def __vectorvalue__(self, run, index): 2261929Sbinkertn@umich.edu val = value(self.arg, run, index) 2271929Sbinkertn@umich.edu if val is None: 2281929Sbinkertn@umich.edu return None 2291929Sbinkertn@umich.edu return self.op(val) 2301049Sbinkertn@umich.edu 2311929Sbinkertn@umich.edu def __vectorlen__(self): 2321929Sbinkertn@umich.edu return len(unproxy(self.arg)) 2331049Sbinkertn@umich.edu 2341986Sbinkertn@umich.edu def __str__(self): 2351986Sbinkertn@umich.edu if self.op == operator.__neg__: 2361986Sbinkertn@umich.edu return '-%s' % str(self.arg) 2371986Sbinkertn@umich.edu if self.op == operator.__pos__: 2381986Sbinkertn@umich.edu return '+%s' % str(self.arg) 2391986Sbinkertn@umich.edu if self.op == operator.__abs__: 2401986Sbinkertn@umich.edu return 'abs(%s)' % self.arg 2411986Sbinkertn@umich.edu 2421929Sbinkertn@umich.educlass BinaryProxy(ValueProxy): 2431929Sbinkertn@umich.edu def __init__(self, op, arg0, arg1): 2441929Sbinkertn@umich.edu super(BinaryProxy, self).__init__() 2451929Sbinkertn@umich.edu self.op = op 2461929Sbinkertn@umich.edu self.arg0 = WrapValue(arg0) 2471929Sbinkertn@umich.edu self.arg1 = WrapValue(arg1) 2481049Sbinkertn@umich.edu 2491929Sbinkertn@umich.edu def __scalar__(self): 2501929Sbinkertn@umich.edu return scalar(self.arg0) and scalar(self.arg1) 2511049Sbinkertn@umich.edu 2521929Sbinkertn@umich.edu def __vector__(self): 2531929Sbinkertn@umich.edu return vector(self.arg0) or vector(self.arg1) 2541929Sbinkertn@umich.edu 2551929Sbinkertn@umich.edu def __scalarvalue__(self, run): 2561929Sbinkertn@umich.edu val0 = value(self.arg0, run) 2571929Sbinkertn@umich.edu val1 = value(self.arg1, run) 2581929Sbinkertn@umich.edu if val0 is None or val1 is None: 2591929Sbinkertn@umich.edu return None 2601987Sbinkertn@umich.edu try: 2611987Sbinkertn@umich.edu return self.op(val0, val1) 2621987Sbinkertn@umich.edu except ZeroDivisionError: 2631987Sbinkertn@umich.edu return None 2641929Sbinkertn@umich.edu 2651929Sbinkertn@umich.edu def __vectorvalue__(self, run, index): 2661929Sbinkertn@umich.edu if scalar(self.arg0): 2671929Sbinkertn@umich.edu val0 = value(self.arg0, run) 2681929Sbinkertn@umich.edu if vector(self.arg0): 2691929Sbinkertn@umich.edu val0 = value(self.arg0, run, index) 2701929Sbinkertn@umich.edu if scalar(self.arg1): 2711929Sbinkertn@umich.edu val1 = value(self.arg1, run) 2721929Sbinkertn@umich.edu if vector(self.arg1): 2731929Sbinkertn@umich.edu val1 = value(self.arg1, run, index) 2741929Sbinkertn@umich.edu 2751929Sbinkertn@umich.edu if val0 is None or val1 is None: 2761929Sbinkertn@umich.edu return None 2771929Sbinkertn@umich.edu 2781987Sbinkertn@umich.edu try: 2791987Sbinkertn@umich.edu return self.op(val0, val1) 2801987Sbinkertn@umich.edu except ZeroDivisionError: 2811987Sbinkertn@umich.edu return None 2821929Sbinkertn@umich.edu 2831929Sbinkertn@umich.edu def __vectorlen__(self): 2841929Sbinkertn@umich.edu if vector(self.arg0) and scalar(self.arg1): 2851929Sbinkertn@umich.edu return len(self.arg0) 2861929Sbinkertn@umich.edu if scalar(self.arg0) and vector(self.arg1): 2871929Sbinkertn@umich.edu return len(self.arg1) 2881929Sbinkertn@umich.edu 2891929Sbinkertn@umich.edu len0 = len(self.arg0) 2901929Sbinkertn@umich.edu len1 = len(self.arg1) 2911929Sbinkertn@umich.edu 2921929Sbinkertn@umich.edu if len0 != len1: 2931929Sbinkertn@umich.edu raise AttributeError, \ 2941929Sbinkertn@umich.edu "vectors of different lengths %d != %d" % (len0, len1) 2951929Sbinkertn@umich.edu 2961929Sbinkertn@umich.edu return len0 2971929Sbinkertn@umich.edu 2981986Sbinkertn@umich.edu def __str__(self): 2991986Sbinkertn@umich.edu ops = { operator.__add__ : '+', 3001986Sbinkertn@umich.edu operator.__sub__ : '-', 3011986Sbinkertn@umich.edu operator.__mul__ : '*', 3021986Sbinkertn@umich.edu operator.__div__ : '/', 3031986Sbinkertn@umich.edu operator.__truediv__ : '/', 3041986Sbinkertn@umich.edu operator.__floordiv__ : '//' } 3051986Sbinkertn@umich.edu 3061986Sbinkertn@umich.edu return '(%s %s %s)' % (str(self.arg0), ops[self.op], str(self.arg1)) 3071986Sbinkertn@umich.edu 3081929Sbinkertn@umich.educlass Proxy(Value): 3091929Sbinkertn@umich.edu def __init__(self, name, dict): 3101929Sbinkertn@umich.edu self.name = name 3111929Sbinkertn@umich.edu self.dict = dict 3121929Sbinkertn@umich.edu 3131929Sbinkertn@umich.edu def __unproxy__(self): 3141929Sbinkertn@umich.edu return unproxy(self.dict[self.name]) 3151929Sbinkertn@umich.edu 3161929Sbinkertn@umich.edu def __getitem__(self, index): 3171929Sbinkertn@umich.edu return ItemProxy(self, index) 3181929Sbinkertn@umich.edu 3191929Sbinkertn@umich.edu def __getattr__(self, attr): 3201929Sbinkertn@umich.edu return AttrProxy(self, attr) 3211929Sbinkertn@umich.edu 3221986Sbinkertn@umich.edu def __str__(self): 3231986Sbinkertn@umich.edu return str(self.dict[self.name]) 3241986Sbinkertn@umich.edu 3251929Sbinkertn@umich.educlass ItemProxy(Proxy): 3261929Sbinkertn@umich.edu def __init__(self, proxy, index): 3271929Sbinkertn@umich.edu self.proxy = proxy 3281929Sbinkertn@umich.edu self.index = index 3291929Sbinkertn@umich.edu 3301929Sbinkertn@umich.edu def __unproxy__(self): 3311929Sbinkertn@umich.edu return unproxy(unproxy(self.proxy)[self.index]) 3321929Sbinkertn@umich.edu 3331986Sbinkertn@umich.edu def __str__(self): 3341986Sbinkertn@umich.edu return '%s[%s]' % (self.proxy, self.index) 3351986Sbinkertn@umich.edu 3361929Sbinkertn@umich.educlass AttrProxy(Proxy): 3371929Sbinkertn@umich.edu def __init__(self, proxy, attr): 3381929Sbinkertn@umich.edu self.proxy = proxy 3391929Sbinkertn@umich.edu self.attr = attr 3401929Sbinkertn@umich.edu 3411929Sbinkertn@umich.edu def __unproxy__(self): 3422015Sbinkertn@umich.edu proxy = unproxy(self.proxy) 3432015Sbinkertn@umich.edu try: 3442015Sbinkertn@umich.edu attr = getattr(proxy, self.attr) 3452015Sbinkertn@umich.edu except AttributeError, e: 3462015Sbinkertn@umich.edu raise ProxyError, e 3472015Sbinkertn@umich.edu return unproxy(attr) 3481929Sbinkertn@umich.edu 3491986Sbinkertn@umich.edu def __str__(self): 3501986Sbinkertn@umich.edu return '%s.%s' % (self.proxy, self.attr) 3511986Sbinkertn@umich.edu 3521929Sbinkertn@umich.educlass ProxyGroup(object): 3531929Sbinkertn@umich.edu def __init__(self, dict=None, **kwargs): 3541929Sbinkertn@umich.edu self.__dict__['dict'] = {} 3551929Sbinkertn@umich.edu 3561929Sbinkertn@umich.edu if dict is not None: 3571929Sbinkertn@umich.edu self.dict.update(dict) 3581929Sbinkertn@umich.edu 3591929Sbinkertn@umich.edu if kwargs: 3601929Sbinkertn@umich.edu self.dict.update(kwargs) 3611929Sbinkertn@umich.edu 3621929Sbinkertn@umich.edu def __getattr__(self, name): 3631929Sbinkertn@umich.edu return Proxy(name, self.dict) 3641929Sbinkertn@umich.edu 3651929Sbinkertn@umich.edu def __setattr__(self, attr, value): 3661929Sbinkertn@umich.edu self.dict[attr] = value 3671929Sbinkertn@umich.edu 3681929Sbinkertn@umich.educlass ScalarStat(Statistic,Scalar): 3691929Sbinkertn@umich.edu def __value__(self, run): 3701929Sbinkertn@umich.edu if run not in self.data: 3711929Sbinkertn@umich.edu return None 3721929Sbinkertn@umich.edu return self.data[run][0][0] 3731929Sbinkertn@umich.edu 3741929Sbinkertn@umich.edu def display(self, run=None): 3751049Sbinkertn@umich.edu import display 3761049Sbinkertn@umich.edu p = display.Print() 3771049Sbinkertn@umich.edu p.name = self.name 3781049Sbinkertn@umich.edu p.desc = self.desc 3791929Sbinkertn@umich.edu p.value = value(self, run) 3801049Sbinkertn@umich.edu p.flags = self.flags 3811049Sbinkertn@umich.edu p.precision = self.precision 3821049Sbinkertn@umich.edu if display.all or (self.flags & flags.printable): 3831049Sbinkertn@umich.edu p.display() 3841049Sbinkertn@umich.edu 3851929Sbinkertn@umich.educlass VectorStat(Statistic,Vector): 3861929Sbinkertn@umich.edu def __value__(self, run, item): 3871929Sbinkertn@umich.edu if run not in self.data: 3881929Sbinkertn@umich.edu return None 3891929Sbinkertn@umich.edu return self.data[run][item][0] 3901049Sbinkertn@umich.edu 3911929Sbinkertn@umich.edu def __len__(self): 3921929Sbinkertn@umich.edu return self.x 3931049Sbinkertn@umich.edu 3941929Sbinkertn@umich.edu def display(self, run=None): 3951049Sbinkertn@umich.edu import display 3961049Sbinkertn@umich.edu d = display.VectorDisplay() 3971929Sbinkertn@umich.edu d.name = self.name 3981929Sbinkertn@umich.edu d.desc = self.desc 3991929Sbinkertn@umich.edu d.value = [ value(self, run, i) for i in xrange(len(self)) ] 4001929Sbinkertn@umich.edu d.flags = self.flags 4011929Sbinkertn@umich.edu d.precision = self.precision 4021049Sbinkertn@umich.edu d.display() 4031049Sbinkertn@umich.edu 4041929Sbinkertn@umich.educlass Formula(Value): 4051929Sbinkertn@umich.edu def __getattribute__(self, attr): 4061929Sbinkertn@umich.edu if attr not in ( '__scalar__', '__vector__', '__value__', '__len__' ): 4071929Sbinkertn@umich.edu return super(Formula, self).__getattribute__(attr) 4081049Sbinkertn@umich.edu 4091929Sbinkertn@umich.edu formula = re.sub(':', '__', self.formula) 4101929Sbinkertn@umich.edu value = eval(formula, self.source.stattop) 4111929Sbinkertn@umich.edu return getattr(value, attr) 4121049Sbinkertn@umich.edu 4131986Sbinkertn@umich.edu def __str__(self): 4141986Sbinkertn@umich.edu return self.name 4151986Sbinkertn@umich.edu 4161929Sbinkertn@umich.educlass SimpleDist(Statistic): 4171049Sbinkertn@umich.edu def __init__(self, sums, squares, samples): 4181049Sbinkertn@umich.edu self.sums = sums 4191049Sbinkertn@umich.edu self.squares = squares 4201049Sbinkertn@umich.edu self.samples = samples 4211049Sbinkertn@umich.edu 4221049Sbinkertn@umich.edu def display(self, name, desc, flags, precision): 4231049Sbinkertn@umich.edu import display 4241049Sbinkertn@umich.edu p = display.Print() 4251049Sbinkertn@umich.edu p.flags = flags 4261049Sbinkertn@umich.edu p.precision = precision 4271049Sbinkertn@umich.edu 4281049Sbinkertn@umich.edu if self.samples > 0: 4291049Sbinkertn@umich.edu p.name = name + ".mean" 4301049Sbinkertn@umich.edu p.value = self.sums / self.samples 4311049Sbinkertn@umich.edu p.display() 4321049Sbinkertn@umich.edu 4331049Sbinkertn@umich.edu p.name = name + ".stdev" 4341049Sbinkertn@umich.edu if self.samples > 1: 4351049Sbinkertn@umich.edu var = (self.samples * self.squares - self.sums ** 2) \ 4361049Sbinkertn@umich.edu / (self.samples * (self.samples - 1)) 4371049Sbinkertn@umich.edu if var >= 0: 4381049Sbinkertn@umich.edu p.value = math.sqrt(var) 4391049Sbinkertn@umich.edu else: 4401049Sbinkertn@umich.edu p.value = 'NaN' 4411049Sbinkertn@umich.edu else: 4421049Sbinkertn@umich.edu p.value = 0.0 4431049Sbinkertn@umich.edu p.display() 4441049Sbinkertn@umich.edu 4451049Sbinkertn@umich.edu p.name = name + ".samples" 4461049Sbinkertn@umich.edu p.value = self.samples 4471049Sbinkertn@umich.edu p.display() 4481049Sbinkertn@umich.edu 4491049Sbinkertn@umich.edu def comparable(self, other): 4501049Sbinkertn@umich.edu return True 4511049Sbinkertn@umich.edu 4521049Sbinkertn@umich.edu def __eq__(self, other): 4531049Sbinkertn@umich.edu return self.sums == other.sums and self.squares == other.squares and \ 4541049Sbinkertn@umich.edu self.samples == other.samples 4551049Sbinkertn@umich.edu 4561049Sbinkertn@umich.edu def __isub__(self, other): 4571049Sbinkertn@umich.edu self.sums -= other.sums 4581049Sbinkertn@umich.edu self.squares -= other.squares 4591049Sbinkertn@umich.edu self.samples -= other.samples 4601049Sbinkertn@umich.edu return self 4611049Sbinkertn@umich.edu 4621049Sbinkertn@umich.edu def __iadd__(self, other): 4631049Sbinkertn@umich.edu self.sums += other.sums 4641049Sbinkertn@umich.edu self.squares += other.squares 4651049Sbinkertn@umich.edu self.samples += other.samples 4661049Sbinkertn@umich.edu return self 4671049Sbinkertn@umich.edu 4681049Sbinkertn@umich.edu def __itruediv__(self, other): 4691049Sbinkertn@umich.edu if not other: 4701049Sbinkertn@umich.edu return self 4711049Sbinkertn@umich.edu self.sums /= other 4721049Sbinkertn@umich.edu self.squares /= other 4731049Sbinkertn@umich.edu self.samples /= other 4741049Sbinkertn@umich.edu return self 4751049Sbinkertn@umich.edu 4761049Sbinkertn@umich.educlass FullDist(SimpleDist): 4771049Sbinkertn@umich.edu def __init__(self, sums, squares, samples, minval, maxval, 4781049Sbinkertn@umich.edu under, vec, over, min, max, bsize, size): 4791049Sbinkertn@umich.edu self.sums = sums 4801049Sbinkertn@umich.edu self.squares = squares 4811049Sbinkertn@umich.edu self.samples = samples 4821049Sbinkertn@umich.edu self.minval = minval 4831049Sbinkertn@umich.edu self.maxval = maxval 4841049Sbinkertn@umich.edu self.under = under 4851049Sbinkertn@umich.edu self.vec = vec 4861049Sbinkertn@umich.edu self.over = over 4871049Sbinkertn@umich.edu self.min = min 4881049Sbinkertn@umich.edu self.max = max 4891049Sbinkertn@umich.edu self.bsize = bsize 4901049Sbinkertn@umich.edu self.size = size 4911049Sbinkertn@umich.edu 4921049Sbinkertn@umich.edu def display(self, name, desc, flags, precision): 4931049Sbinkertn@umich.edu import display 4941049Sbinkertn@umich.edu p = display.Print() 4951049Sbinkertn@umich.edu p.flags = flags 4961049Sbinkertn@umich.edu p.precision = precision 4971049Sbinkertn@umich.edu 4981049Sbinkertn@umich.edu p.name = name + '.min_val' 4991049Sbinkertn@umich.edu p.value = self.minval 5001049Sbinkertn@umich.edu p.display() 5011049Sbinkertn@umich.edu 5021049Sbinkertn@umich.edu p.name = name + '.max_val' 5031049Sbinkertn@umich.edu p.value = self.maxval 5041049Sbinkertn@umich.edu p.display() 5051049Sbinkertn@umich.edu 5061049Sbinkertn@umich.edu p.name = name + '.underflow' 5071049Sbinkertn@umich.edu p.value = self.under 5081049Sbinkertn@umich.edu p.display() 5091049Sbinkertn@umich.edu 5101049Sbinkertn@umich.edu i = self.min 5111049Sbinkertn@umich.edu for val in self.vec[:-1]: 5121049Sbinkertn@umich.edu p.name = name + '[%d:%d]' % (i, i + self.bsize - 1) 5131049Sbinkertn@umich.edu p.value = val 5141049Sbinkertn@umich.edu p.display() 5151049Sbinkertn@umich.edu i += self.bsize 5161049Sbinkertn@umich.edu 5171049Sbinkertn@umich.edu p.name = name + '[%d:%d]' % (i, self.max) 5181049Sbinkertn@umich.edu p.value = self.vec[-1] 5191049Sbinkertn@umich.edu p.display() 5201049Sbinkertn@umich.edu 5211049Sbinkertn@umich.edu 5221049Sbinkertn@umich.edu p.name = name + '.overflow' 5231049Sbinkertn@umich.edu p.value = self.over 5241049Sbinkertn@umich.edu p.display() 5251049Sbinkertn@umich.edu 5261049Sbinkertn@umich.edu SimpleDist.display(self, name, desc, flags, precision) 5271049Sbinkertn@umich.edu 5281049Sbinkertn@umich.edu def comparable(self, other): 5291049Sbinkertn@umich.edu return self.min == other.min and self.max == other.max and \ 5301049Sbinkertn@umich.edu self.bsize == other.bsize and self.size == other.size 5311049Sbinkertn@umich.edu 5321049Sbinkertn@umich.edu def __eq__(self, other): 5331049Sbinkertn@umich.edu return self.sums == other.sums and self.squares == other.squares and \ 5341049Sbinkertn@umich.edu self.samples == other.samples 5351049Sbinkertn@umich.edu 5361049Sbinkertn@umich.edu def __isub__(self, other): 5371049Sbinkertn@umich.edu self.sums -= other.sums 5381049Sbinkertn@umich.edu self.squares -= other.squares 5391049Sbinkertn@umich.edu self.samples -= other.samples 5401049Sbinkertn@umich.edu 5411049Sbinkertn@umich.edu if other.samples: 5421049Sbinkertn@umich.edu self.minval = min(self.minval, other.minval) 5431049Sbinkertn@umich.edu self.maxval = max(self.maxval, other.maxval) 5441049Sbinkertn@umich.edu self.under -= under 5451049Sbinkertn@umich.edu self.vec = map(lambda x,y: x - y, self.vec, other.vec) 5461049Sbinkertn@umich.edu self.over -= over 5471049Sbinkertn@umich.edu return self 5481049Sbinkertn@umich.edu 5491049Sbinkertn@umich.edu def __iadd__(self, other): 5501049Sbinkertn@umich.edu if not self.samples and other.samples: 5511049Sbinkertn@umich.edu self = other 5521049Sbinkertn@umich.edu return self 5531049Sbinkertn@umich.edu 5541049Sbinkertn@umich.edu self.sums += other.sums 5551049Sbinkertn@umich.edu self.squares += other.squares 5561049Sbinkertn@umich.edu self.samples += other.samples 5571049Sbinkertn@umich.edu 5581049Sbinkertn@umich.edu if other.samples: 5591049Sbinkertn@umich.edu self.minval = min(self.minval, other.minval) 5601049Sbinkertn@umich.edu self.maxval = max(self.maxval, other.maxval) 5611049Sbinkertn@umich.edu self.under += other.under 5621049Sbinkertn@umich.edu self.vec = map(lambda x,y: x + y, self.vec, other.vec) 5631049Sbinkertn@umich.edu self.over += other.over 5641049Sbinkertn@umich.edu return self 5651049Sbinkertn@umich.edu 5661049Sbinkertn@umich.edu def __itruediv__(self, other): 5671049Sbinkertn@umich.edu if not other: 5681049Sbinkertn@umich.edu return self 5691049Sbinkertn@umich.edu self.sums /= other 5701049Sbinkertn@umich.edu self.squares /= other 5711049Sbinkertn@umich.edu self.samples /= other 5721049Sbinkertn@umich.edu 5731049Sbinkertn@umich.edu if self.samples: 5741049Sbinkertn@umich.edu self.under /= other 5751049Sbinkertn@umich.edu for i in xrange(len(self.vec)): 5761049Sbinkertn@umich.edu self.vec[i] /= other 5771049Sbinkertn@umich.edu self.over /= other 5781049Sbinkertn@umich.edu return self 5791049Sbinkertn@umich.edu 5801049Sbinkertn@umich.educlass Dist(Statistic): 5811049Sbinkertn@umich.edu def display(self): 5821049Sbinkertn@umich.edu import display 5831049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 5841049Sbinkertn@umich.edu return 5851049Sbinkertn@umich.edu 5861049Sbinkertn@umich.edu self.dist.display(self.name, self.desc, self.flags, self.precision) 5871049Sbinkertn@umich.edu 5881049Sbinkertn@umich.edu def comparable(self, other): 5891049Sbinkertn@umich.edu return self.name == other.name and \ 5901049Sbinkertn@umich.edu self.dist.compareable(other.dist) 5911049Sbinkertn@umich.edu 5921049Sbinkertn@umich.edu def __eq__(self, other): 5931049Sbinkertn@umich.edu return self.dist == other.dist 5941049Sbinkertn@umich.edu 5951049Sbinkertn@umich.edu def __isub__(self, other): 5961049Sbinkertn@umich.edu self.dist -= other.dist 5971049Sbinkertn@umich.edu return self 5981049Sbinkertn@umich.edu 5991049Sbinkertn@umich.edu def __iadd__(self, other): 6001049Sbinkertn@umich.edu self.dist += other.dist 6011049Sbinkertn@umich.edu return self 6021049Sbinkertn@umich.edu 6031049Sbinkertn@umich.edu def __itruediv__(self, other): 6041049Sbinkertn@umich.edu if not other: 6051049Sbinkertn@umich.edu return self 6061049Sbinkertn@umich.edu self.dist /= other 6071049Sbinkertn@umich.edu return self 6081049Sbinkertn@umich.edu 6091049Sbinkertn@umich.educlass VectorDist(Statistic): 6101049Sbinkertn@umich.edu def display(self): 6111049Sbinkertn@umich.edu import display 6121049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 6131049Sbinkertn@umich.edu return 6141049Sbinkertn@umich.edu 6151049Sbinkertn@umich.edu if isinstance(self.dist, SimpleDist): 6161049Sbinkertn@umich.edu return 6171049Sbinkertn@umich.edu 6181049Sbinkertn@umich.edu for dist,sn,sd,i in map(None, self.dist, self.subnames, self.subdescs, 6191049Sbinkertn@umich.edu range(len(self.dist))): 6201049Sbinkertn@umich.edu if len(sn) > 0: 6211049Sbinkertn@umich.edu name = '%s.%s' % (self.name, sn) 6221049Sbinkertn@umich.edu else: 6231049Sbinkertn@umich.edu name = '%s[%d]' % (self.name, i) 6241049Sbinkertn@umich.edu 6251049Sbinkertn@umich.edu if len(sd) > 0: 6261049Sbinkertn@umich.edu desc = sd 6271049Sbinkertn@umich.edu else: 6281049Sbinkertn@umich.edu desc = self.desc 6291049Sbinkertn@umich.edu 6301049Sbinkertn@umich.edu dist.display(name, desc, self.flags, self.precision) 6311049Sbinkertn@umich.edu 6321049Sbinkertn@umich.edu if (self.flags & flags.total) or 1: 6331049Sbinkertn@umich.edu if isinstance(self.dist[0], SimpleDist): 6341049Sbinkertn@umich.edu disttotal = SimpleDist( \ 6351049Sbinkertn@umich.edu reduce(sums, [d.sums for d in self.dist]), 6361049Sbinkertn@umich.edu reduce(sums, [d.squares for d in self.dist]), 6371049Sbinkertn@umich.edu reduce(sums, [d.samples for d in self.dist])) 6381049Sbinkertn@umich.edu else: 6391049Sbinkertn@umich.edu disttotal = FullDist( \ 6401049Sbinkertn@umich.edu reduce(sums, [d.sums for d in self.dist]), 6411049Sbinkertn@umich.edu reduce(sums, [d.squares for d in self.dist]), 6421049Sbinkertn@umich.edu reduce(sums, [d.samples for d in self.dist]), 6431049Sbinkertn@umich.edu min([d.minval for d in self.dist]), 6441049Sbinkertn@umich.edu max([d.maxval for d in self.dist]), 6451049Sbinkertn@umich.edu reduce(sums, [d.under for d in self.dist]), 6461049Sbinkertn@umich.edu reduce(sums, [d.vec for d in self.dist]), 6471049Sbinkertn@umich.edu reduce(sums, [d.over for d in self.dist]), 6481049Sbinkertn@umich.edu dist[0].min, 6491049Sbinkertn@umich.edu dist[0].max, 6501049Sbinkertn@umich.edu dist[0].bsize, 6511049Sbinkertn@umich.edu dist[0].size) 6521049Sbinkertn@umich.edu 6531049Sbinkertn@umich.edu name = '%s.total' % (self.name) 6541049Sbinkertn@umich.edu desc = self.desc 6551049Sbinkertn@umich.edu disttotal.display(name, desc, self.flags, self.precision) 6561049Sbinkertn@umich.edu 6571049Sbinkertn@umich.edu def comparable(self, other): 6581049Sbinkertn@umich.edu return self.name == other.name and \ 6591049Sbinkertn@umich.edu alltrue(map(lambda x, y : x.comparable(y), 6601049Sbinkertn@umich.edu self.dist, 6611049Sbinkertn@umich.edu other.dist)) 6621049Sbinkertn@umich.edu 6631049Sbinkertn@umich.edu def __eq__(self, other): 6641049Sbinkertn@umich.edu return alltrue(map(lambda x, y : x == y, self.dist, other.dist)) 6651049Sbinkertn@umich.edu 6661049Sbinkertn@umich.edu def __isub__(self, other): 6671547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)) and \ 6681547Sbinkertn@umich.edu isinstance(other.dist, (list, tuple)): 6691049Sbinkertn@umich.edu for sd,od in zip(self.dist, other.dist): 6701049Sbinkertn@umich.edu sd -= od 6711049Sbinkertn@umich.edu else: 6721049Sbinkertn@umich.edu self.dist -= other.dist 6731049Sbinkertn@umich.edu return self 6741049Sbinkertn@umich.edu 6751049Sbinkertn@umich.edu def __iadd__(self, other): 6761547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)) and \ 6771547Sbinkertn@umich.edu isinstance(other.dist, (list, tuple)): 6781049Sbinkertn@umich.edu for sd,od in zip(self.dist, other.dist): 6791049Sbinkertn@umich.edu sd += od 6801049Sbinkertn@umich.edu else: 6811049Sbinkertn@umich.edu self.dist += other.dist 6821049Sbinkertn@umich.edu return self 6831049Sbinkertn@umich.edu 6841049Sbinkertn@umich.edu def __itruediv__(self, other): 6851049Sbinkertn@umich.edu if not other: 6861049Sbinkertn@umich.edu return self 6871547Sbinkertn@umich.edu if isinstance(self.dist, (list, tuple)): 6881049Sbinkertn@umich.edu for dist in self.dist: 6891049Sbinkertn@umich.edu dist /= other 6901049Sbinkertn@umich.edu else: 6911049Sbinkertn@umich.edu self.dist /= other 6921049Sbinkertn@umich.edu return self 6931049Sbinkertn@umich.edu 6941049Sbinkertn@umich.educlass Vector2d(Statistic): 6951049Sbinkertn@umich.edu def display(self): 6961049Sbinkertn@umich.edu import display 6971049Sbinkertn@umich.edu if not display.all and not (self.flags & flags.printable): 6981049Sbinkertn@umich.edu return 6991049Sbinkertn@umich.edu 7001049Sbinkertn@umich.edu d = display.VectorDisplay() 7011049Sbinkertn@umich.edu d.__dict__.update(self.__dict__) 7021049Sbinkertn@umich.edu 7031049Sbinkertn@umich.edu if self.__dict__.has_key('ysubnames'): 7041049Sbinkertn@umich.edu ysubnames = list(self.ysubnames) 7051049Sbinkertn@umich.edu slack = self.x - len(ysubnames) 7061049Sbinkertn@umich.edu if slack > 0: 7071049Sbinkertn@umich.edu ysubnames.extend(['']*slack) 7081049Sbinkertn@umich.edu else: 7091049Sbinkertn@umich.edu ysubnames = range(self.x) 7101049Sbinkertn@umich.edu 7111049Sbinkertn@umich.edu for x,sname in enumerate(ysubnames): 7121049Sbinkertn@umich.edu o = x * self.y 7131049Sbinkertn@umich.edu d.value = self.value[o:o+self.y] 7141049Sbinkertn@umich.edu d.name = '%s[%s]' % (self.name, sname) 7151049Sbinkertn@umich.edu d.display() 7161049Sbinkertn@umich.edu 7171049Sbinkertn@umich.edu if self.flags & flags.total: 7181049Sbinkertn@umich.edu d.value = [] 7191049Sbinkertn@umich.edu for y in range(self.y): 7201049Sbinkertn@umich.edu xtot = 0.0 7211049Sbinkertn@umich.edu for x in range(self.x): 7221049Sbinkertn@umich.edu xtot += self.value[y + x * self.x] 7231049Sbinkertn@umich.edu d.value.append(xtot) 7241049Sbinkertn@umich.edu 7251049Sbinkertn@umich.edu d.name = self.name + '.total' 7261049Sbinkertn@umich.edu d.display() 7271049Sbinkertn@umich.edu 7281049Sbinkertn@umich.edu def comparable(self, other): 7291049Sbinkertn@umich.edu return self.name == other.name and self.x == other.x and \ 7301049Sbinkertn@umich.edu self.y == other.y 7311049Sbinkertn@umich.edu 7321049Sbinkertn@umich.edu def __eq__(self, other): 7331049Sbinkertn@umich.edu return True 7341049Sbinkertn@umich.edu 7351049Sbinkertn@umich.edu def __isub__(self, other): 7361049Sbinkertn@umich.edu return self 7371049Sbinkertn@umich.edu 7381049Sbinkertn@umich.edu def __iadd__(self, other): 7391049Sbinkertn@umich.edu return self 7401049Sbinkertn@umich.edu 7411049Sbinkertn@umich.edu def __itruediv__(self, other): 7421049Sbinkertn@umich.edu if not other: 7431049Sbinkertn@umich.edu return self 7441049Sbinkertn@umich.edu return self 7451049Sbinkertn@umich.edu 7461929Sbinkertn@umich.edudef NewStat(source, data): 7471049Sbinkertn@umich.edu stat = None 7481049Sbinkertn@umich.edu if data.type == 'SCALAR': 7491929Sbinkertn@umich.edu stat = ScalarStat() 7501049Sbinkertn@umich.edu elif data.type == 'VECTOR': 7511929Sbinkertn@umich.edu stat = VectorStat() 7521049Sbinkertn@umich.edu elif data.type == 'DIST': 7531929Sbinkertn@umich.edu stat = Dist() 7541049Sbinkertn@umich.edu elif data.type == 'VECTORDIST': 7551929Sbinkertn@umich.edu stat = VectorDist() 7561049Sbinkertn@umich.edu elif data.type == 'VECTOR2D': 7571929Sbinkertn@umich.edu stat = Vector2d() 7581049Sbinkertn@umich.edu elif data.type == 'FORMULA': 7591929Sbinkertn@umich.edu stat = Formula() 7601929Sbinkertn@umich.edu 7611929Sbinkertn@umich.edu stat.__dict__['source'] = source 7621929Sbinkertn@umich.edu stat.__dict__['bins'] = None 7631929Sbinkertn@umich.edu stat.__dict__['ticks'] = None 7641929Sbinkertn@umich.edu stat.__dict__.update(data.__dict__) 7651049Sbinkertn@umich.edu 7661049Sbinkertn@umich.edu return stat 7671049Sbinkertn@umich.edu 768