1from __future__ import division 2import operator, re, types 3 4source = None 5display_run = 0 6global globalTicks 7globalTicks = None 8 9def total(f): 10 if isinstance(f, FormulaStat): 11 v = f.value 12 else: 13 v = f 14 15 f = FormulaStat() 16 if isinstance(v, (list, tuple)): 17 f.value = reduce(operator.add, v) 18 else: 19 f.value = v 20 21 return f 22 23def unaryop(op, f): 24 if isinstance(f, FormulaStat): 25 v = f.value 26 else: 27 v = f 28 29 if isinstance(v, (list, tuple)): 30 return map(op, v) 31 else: 32 return op(v) 33 34def zerodiv(lv, rv): 35 if rv == 0.0: 36 return 0.0 37 else: 38 return operator.truediv(lv, rv) 39 40def wrapop(op, lv, rv): 41 if isinstance(lv, str): 42 return lv 43 44 if isinstance(rv, str): 45 return rv 46 47 return op(lv, rv) 48 49def same(lrun, rrun): 50 for lx,rx in zip(lrun.keys(),rrun.keys()): 51 if lx != rx: 52 print 'lx != rx' 53 print lx, rx 54 print lrun.keys() 55 print rrun.keys() 56 return False 57 for ly,ry in zip(lrun[lx].keys(),rrun[rx].keys()): 58 if ly != ry: 59 print 'ly != ry' 60 print ly, ry 61 print lrun[lx].keys() 62 print rrun[rx].keys() 63 return False 64 return True 65 66 67def binaryop(op, lf, rf): 68 result = {} 69 70 if isinstance(lf, FormulaStat) and isinstance(rf, FormulaStat): 71 lv = lf.value 72 rv = rf.value 73 74 theruns = [] 75 for r in lv.keys(): 76 if rv.has_key(r): 77 if same(lv[r], rv[r]): 78 theruns.append(r) 79 else: 80 raise AttributeError 81 82 for run in theruns: 83 result[run] = {} 84 for x in lv[run].keys(): 85 result[run][x] = {} 86 for y in lv[run][x].keys(): 87 result[run][x][y] = wrapop(op, lv[run][x][y], 88 rv[run][x][y]) 89 elif isinstance(lf, FormulaStat): 90 lv = lf.value 91 for run in lv.keys(): 92 result[run] = {} 93 for x in lv[run].keys(): 94 result[run][x] = {} 95 for y in lv[run][x].keys(): 96 result[run][x][y] = wrapop(op, lv[run][x][y], rf) 97 elif isinstance(rf, FormulaStat): 98 rv = rf.value 99 for run in rv.keys(): 100 result[run] = {} 101 for x in rv[run].keys(): 102 result[run][x] = {} 103 for y in rv[run][x].keys(): 104 result[run][x][y] = wrapop(op, lf, rv[run][x][y]) 105 106 return result 107 108def sums(x, y): 109 if isinstance(x, (list, tuple)): 110 return map(lambda x, y: x + y, x, y) 111 else: 112 return x + y 113 114def alltrue(seq): 115 return reduce(lambda x, y: x and y, seq) 116 117def allfalse(seq): 118 return not reduce(lambda x, y: x or y, seq) 119 120def enumerate(seq): 121 return map(None, range(len(seq)), seq) 122 123def cmp(a, b): 124 if a < b: 125 return -1 126 elif a == b: 127 return 0 128 else: 129 return 1 130 131class Statistic(object): 132 133 def __init__(self, data): 134 self.__dict__.update(data.__dict__) 135 if not self.__dict__.has_key('value'): 136 self.__dict__['value'] = None 137 if not self.__dict__.has_key('bins'): 138 self.__dict__['bins'] = None 139 if not self.__dict__.has_key('ticks'): 140 self.__dict__['ticks'] = None 141 if 'vc' not in self.__dict__: 142 self.vc = {} 143 144 def __getattribute__(self, attr): 145 if attr == 'ticks': 146 if self.__dict__['ticks'] != globalTicks: 147 self.__dict__['value'] = None 148 self.__dict__['ticks'] = globalTicks 149 return self.__dict__['ticks'] 150 if attr == 'value': 151 if self.__dict__['ticks'] != globalTicks: 152 if self.__dict__['ticks'] != None and \ 153 len(self.__dict__['ticks']) == 1: 154 self.vc[self.__dict__['ticks'][0]] = self.__dict__['value'] 155 self.__dict__['ticks'] = globalTicks 156 if len(globalTicks) == 1 and self.vc.has_key(globalTicks[0]): 157 self.__dict__['value'] = self.vc[globalTicks[0]] 158 else: 159 self.__dict__['value'] = None 160 if self.__dict__['value'] == None: 161 self.__dict__['value'] = self.getValue() 162 return self.__dict__['value'] 163 else: 164 return super(Statistic, self).__getattribute__(attr) 165 166 def __setattr__(self, attr, value): 167 if attr == 'bins' or attr == 'ticks': 168 if attr == 'bins': 169 if value is not None: 170 value = source.getBin(value) 171 #elif attr == 'ticks' and type(value) is str: 172 # value = [ int(x) for x in value.split() ] 173 174 self.__dict__[attr] = value 175 self.__dict__['value'] = None 176 self.vc = {} 177 else: 178 super(Statistic, self).__setattr__(attr, value) 179 180 def getValue(self): 181 raise AttributeError, 'getValue() must be defined' 182 183 def zero(self): 184 return False 185 186 def __ne__(self, other): 187 return not (self == other) 188 189 def __str__(self): 190 return '%f' % (float(self)) 191 192class FormulaStat(object): 193 def __add__(self, other): 194 f = FormulaStat() 195 f.value = binaryop(operator.add, self, other) 196 return f 197 def __sub__(self, other): 198 f = FormulaStat() 199 f.value = binaryop(operator.sub, self, other) 200 return f 201 def __mul__(self, other): 202 f = FormulaStat() 203 f.value = binaryop(operator.mul, self, other) 204 return f 205 def __truediv__(self, other): 206 f = FormulaStat() 207 f.value = binaryop(zerodiv, self, other) 208 return f 209 def __mod__(self, other): 210 f = FormulaStat() 211 f.value = binaryop(operator.mod, self, other) 212 return f 213 def __radd__(self, other): 214 f = FormulaStat() 215 f.value = binaryop(operator.add, other, self) 216 return f 217 def __rsub__(self, other): 218 f = FormulaStat() 219 f.value = binaryop(operator.sub, other, self) 220 return f 221 def __rmul__(self, other): 222 f = FormulaStat() 223 f.value = binaryop(operator.mul, other, self) 224 return f 225 def __rtruediv__(self, other): 226 f = FormulaStat() 227 f.value = binaryop(zerodiv, other, self) 228 return f 229 def __rmod__(self, other): 230 f = FormulaStat() 231 f.value = binaryop(operator.mod, other, self) 232 return f 233 def __neg__(self): 234 f = FormulaStat() 235 f.value = unaryop(operator.neg, self) 236 return f 237 def __getitem__(self, idx): 238 f = FormulaStat() 239 f.value = {} 240 for key in self.value.keys(): 241 f.value[key] = {} 242 f.value[key][0] = {} 243 f.value[key][0][0] = self.value[key][idx][0] 244 return f 245 246 def __float__(self): 247 if isinstance(self.value, FormulaStat): 248 return float(self.value) 249 if not self.value.has_key(display_run): 250 return (1e300*1e300) 251 if len(self.value[display_run]) == 1: 252 return self.value[display_run][0][0] 253 else: 254 #print self.value[display_run] 255 return self.value[display_run][4][0] 256 #raise ValueError 257 258 def display(self): 259 import display 260 d = display.VectorDisplay() 261 d.flags = 0 262 d.precision = 1 263 d.name = 'formula' 264 d.desc = 'formula' 265 val = self.value[display_run] 266 d.value = [ val[x][0] for x in val.keys() ] 267 d.display() 268 269 270class Scalar(Statistic,FormulaStat): 271 def getValue(self): 272 return source.data(self, self.bins, self.ticks) 273 274 def display(self): 275 import display 276 p = display.Print() 277 p.name = self.name 278 p.desc = self.desc 279 p.value = float(self) 280 p.flags = self.flags 281 p.precision = self.precision 282 if display.all or (self.flags & flags.printable): 283 p.display() 284 285 def comparable(self, other): 286 return self.name == other.name 287 288 def __eq__(self, other): 289 return self.value == other.value 290 291 def __isub__(self, other): 292 self.value -= other.value 293 return self 294 295 def __iadd__(self, other): 296 self.value += other.value 297 return self 298 299 def __itruediv__(self, other): 300 if not other: 301 return self 302 self.value /= other 303 return self 304 305class Vector(Statistic,FormulaStat): 306 def getValue(self): 307 return source.data(self, self.bins, self.ticks); 308 309 def display(self): 310 import display 311 if not display.all and not (self.flags & flags.printable): 312 return 313 314 d = display.VectorDisplay() 315 d.__dict__.update(self.__dict__) 316 d.display() 317 318 def comparable(self, other): 319 return self.name == other.name and \ 320 len(self.value) == len(other.value) 321 322 def __eq__(self, other): 323 if isinstance(self.value, (list, tuple)) != \ 324 isinstance(other.value, (list, tuple)): 325 return False 326 327 if isinstance(self.value, (list, tuple)): 328 if len(self.value) != len(other.value): 329 return False 330 else: 331 for v1,v2 in zip(self.value, other.value): 332 if v1 != v2: 333 return False 334 return True 335 else: 336 return self.value == other.value 337 338 def __isub__(self, other): 339 self.value = binaryop(operator.sub, self.value, other.value) 340 return self 341 342 def __iadd__(self, other): 343 self.value = binaryop(operator.add, self.value, other.value) 344 return self 345 346 def __itruediv__(self, other): 347 if not other: 348 return self 349 if isinstance(self.value, (list, tuple)): 350 for i in xrange(len(self.value)): 351 self.value[i] /= other 352 else: 353 self.value /= other 354 return self 355 356class Formula(Vector): 357 def getValue(self): 358 formula = re.sub(':', '__', self.formula) 359 x = eval(formula, source.stattop) 360 return x.value 361 362 def comparable(self, other): 363 return self.name == other.name and \ 364 compare(self.dist, other.dist) 365 366 def __eq__(self, other): 367 return self.value == other.value 368 369 def __isub__(self, other): 370 return self 371 372 def __iadd__(self, other): 373 return self 374 375 def __itruediv__(self, other): 376 if not other: 377 return self 378 return self 379 380class SimpleDist(object): 381 def __init__(self, sums, squares, samples): 382 self.sums = sums 383 self.squares = squares 384 self.samples = samples 385 386 def getValue(self): 387 return 0.0 388 389 def display(self, name, desc, flags, precision): 390 import display 391 p = display.Print() 392 p.flags = flags 393 p.precision = precision 394 395 if self.samples > 0: 396 p.name = name + ".mean" 397 p.value = self.sums / self.samples 398 p.display() 399 400 p.name = name + ".stdev" 401 if self.samples > 1: 402 var = (self.samples * self.squares - self.sums ** 2) \ 403 / (self.samples * (self.samples - 1)) 404 if var >= 0: 405 p.value = math.sqrt(var) 406 else: 407 p.value = 'NaN' 408 else: 409 p.value = 0.0 410 p.display() 411 412 p.name = name + ".samples" 413 p.value = self.samples 414 p.display() 415 416 def comparable(self, other): 417 return True 418 419 def __eq__(self, other): 420 return self.sums == other.sums and self.squares == other.squares and \ 421 self.samples == other.samples 422 423 def __isub__(self, other): 424 self.sums -= other.sums 425 self.squares -= other.squares 426 self.samples -= other.samples 427 return self 428 429 def __iadd__(self, other): 430 self.sums += other.sums 431 self.squares += other.squares 432 self.samples += other.samples 433 return self 434 435 def __itruediv__(self, other): 436 if not other: 437 return self 438 self.sums /= other 439 self.squares /= other 440 self.samples /= other 441 return self 442 443class FullDist(SimpleDist): 444 def __init__(self, sums, squares, samples, minval, maxval, 445 under, vec, over, min, max, bsize, size): 446 self.sums = sums 447 self.squares = squares 448 self.samples = samples 449 self.minval = minval 450 self.maxval = maxval 451 self.under = under 452 self.vec = vec 453 self.over = over 454 self.min = min 455 self.max = max 456 self.bsize = bsize 457 self.size = size 458 459 def getValue(self): 460 return 0.0 461 462 def display(self, name, desc, flags, precision): 463 import display 464 p = display.Print() 465 p.flags = flags 466 p.precision = precision 467 468 p.name = name + '.min_val' 469 p.value = self.minval 470 p.display() 471 472 p.name = name + '.max_val' 473 p.value = self.maxval 474 p.display() 475 476 p.name = name + '.underflow' 477 p.value = self.under 478 p.display() 479 480 i = self.min 481 for val in self.vec[:-1]: 482 p.name = name + '[%d:%d]' % (i, i + self.bsize - 1) 483 p.value = val 484 p.display() 485 i += self.bsize 486 487 p.name = name + '[%d:%d]' % (i, self.max) 488 p.value = self.vec[-1] 489 p.display() 490 491 492 p.name = name + '.overflow' 493 p.value = self.over 494 p.display() 495 496 SimpleDist.display(self, name, desc, flags, precision) 497 498 def comparable(self, other): 499 return self.min == other.min and self.max == other.max and \ 500 self.bsize == other.bsize and self.size == other.size 501 502 def __eq__(self, other): 503 return self.sums == other.sums and self.squares == other.squares and \ 504 self.samples == other.samples 505 506 def __isub__(self, other): 507 self.sums -= other.sums 508 self.squares -= other.squares 509 self.samples -= other.samples 510 511 if other.samples: 512 self.minval = min(self.minval, other.minval) 513 self.maxval = max(self.maxval, other.maxval) 514 self.under -= under 515 self.vec = map(lambda x,y: x - y, self.vec, other.vec) 516 self.over -= over 517 return self 518 519 def __iadd__(self, other): 520 if not self.samples and other.samples: 521 self = other 522 return self 523 524 self.sums += other.sums 525 self.squares += other.squares 526 self.samples += other.samples 527 528 if other.samples: 529 self.minval = min(self.minval, other.minval) 530 self.maxval = max(self.maxval, other.maxval) 531 self.under += other.under 532 self.vec = map(lambda x,y: x + y, self.vec, other.vec) 533 self.over += other.over 534 return self 535 536 def __itruediv__(self, other): 537 if not other: 538 return self 539 self.sums /= other 540 self.squares /= other 541 self.samples /= other 542 543 if self.samples: 544 self.under /= other 545 for i in xrange(len(self.vec)): 546 self.vec[i] /= other 547 self.over /= other 548 return self 549 550class Dist(Statistic): 551 def getValue(self): 552 return 0.0 553 554 def display(self): 555 import display 556 if not display.all and not (self.flags & flags.printable): 557 return 558 559 self.dist.display(self.name, self.desc, self.flags, self.precision) 560 561 def comparable(self, other): 562 return self.name == other.name and \ 563 self.dist.compareable(other.dist) 564 565 def __eq__(self, other): 566 return self.dist == other.dist 567 568 def __isub__(self, other): 569 self.dist -= other.dist 570 return self 571 572 def __iadd__(self, other): 573 self.dist += other.dist 574 return self 575 576 def __itruediv__(self, other): 577 if not other: 578 return self 579 self.dist /= other 580 return self 581 582class VectorDist(Statistic): 583 def getValue(self): 584 return 0.0 585 586 def display(self): 587 import display 588 if not display.all and not (self.flags & flags.printable): 589 return 590 591 if isinstance(self.dist, SimpleDist): 592 return 593 594 for dist,sn,sd,i in map(None, self.dist, self.subnames, self.subdescs, 595 range(len(self.dist))): 596 if len(sn) > 0: 597 name = '%s.%s' % (self.name, sn) 598 else: 599 name = '%s[%d]' % (self.name, i) 600 601 if len(sd) > 0: 602 desc = sd 603 else: 604 desc = self.desc 605 606 dist.display(name, desc, self.flags, self.precision) 607 608 if (self.flags & flags.total) or 1: 609 if isinstance(self.dist[0], SimpleDist): 610 disttotal = SimpleDist( \ 611 reduce(sums, [d.sums for d in self.dist]), 612 reduce(sums, [d.squares for d in self.dist]), 613 reduce(sums, [d.samples for d in self.dist])) 614 else: 615 disttotal = FullDist( \ 616 reduce(sums, [d.sums for d in self.dist]), 617 reduce(sums, [d.squares for d in self.dist]), 618 reduce(sums, [d.samples for d in self.dist]), 619 min([d.minval for d in self.dist]), 620 max([d.maxval for d in self.dist]), 621 reduce(sums, [d.under for d in self.dist]), 622 reduce(sums, [d.vec for d in self.dist]), 623 reduce(sums, [d.over for d in self.dist]), 624 dist[0].min, 625 dist[0].max, 626 dist[0].bsize, 627 dist[0].size) 628 629 name = '%s.total' % (self.name) 630 desc = self.desc 631 disttotal.display(name, desc, self.flags, self.precision) 632 633 def comparable(self, other): 634 return self.name == other.name and \ 635 alltrue(map(lambda x, y : x.comparable(y), 636 self.dist, 637 other.dist)) 638 639 def __eq__(self, other): 640 return alltrue(map(lambda x, y : x == y, self.dist, other.dist)) 641 642 def __isub__(self, other): 643 if isinstance(self.dist, (list, tuple)) and \ 644 isinstance(other.dist, (list, tuple)): 645 for sd,od in zip(self.dist, other.dist): 646 sd -= od 647 else: 648 self.dist -= other.dist 649 return self 650 651 def __iadd__(self, other): 652 if isinstance(self.dist, (list, tuple)) and \ 653 isinstance(other.dist, (list, tuple)): 654 for sd,od in zip(self.dist, other.dist): 655 sd += od 656 else: 657 self.dist += other.dist 658 return self 659 660 def __itruediv__(self, other): 661 if not other: 662 return self 663 if isinstance(self.dist, (list, tuple)): 664 for dist in self.dist: 665 dist /= other 666 else: 667 self.dist /= other 668 return self 669 670class Vector2d(Statistic): 671 def getValue(self): 672 return 0.0 673 674 def display(self): 675 import display 676 if not display.all and not (self.flags & flags.printable): 677 return 678 679 d = display.VectorDisplay() 680 d.__dict__.update(self.__dict__) 681 682 if self.__dict__.has_key('ysubnames'): 683 ysubnames = list(self.ysubnames) 684 slack = self.x - len(ysubnames) 685 if slack > 0: 686 ysubnames.extend(['']*slack) 687 else: 688 ysubnames = range(self.x) 689 690 for x,sname in enumerate(ysubnames): 691 o = x * self.y 692 d.value = self.value[o:o+self.y] 693 d.name = '%s[%s]' % (self.name, sname) 694 d.display() 695 696 if self.flags & flags.total: 697 d.value = [] 698 for y in range(self.y): 699 xtot = 0.0 700 for x in range(self.x): 701 xtot += self.value[y + x * self.x] 702 d.value.append(xtot) 703 704 d.name = self.name + '.total' 705 d.display() 706 707 def comparable(self, other): 708 return self.name == other.name and self.x == other.x and \ 709 self.y == other.y 710 711 def __eq__(self, other): 712 return True 713 714 def __isub__(self, other): 715 return self 716 717 def __iadd__(self, other): 718 return self 719 720 def __itruediv__(self, other): 721 if not other: 722 return self 723 return self 724 725def NewStat(data): 726 stat = None 727 if data.type == 'SCALAR': 728 stat = Scalar(data) 729 elif data.type == 'VECTOR': 730 stat = Vector(data) 731 elif data.type == 'DIST': 732 stat = Dist(data) 733 elif data.type == 'VECTORDIST': 734 stat = VectorDist(data) 735 elif data.type == 'VECTOR2D': 736 stat = Vector2d(data) 737 elif data.type == 'FORMULA': 738 stat = Formula(data) 739 740 return stat 741
| 47from __future__ import division 48import operator, re, types 49 50source = None 51display_run = 0 52global globalTicks 53globalTicks = None 54 55def total(f): 56 if isinstance(f, FormulaStat): 57 v = f.value 58 else: 59 v = f 60 61 f = FormulaStat() 62 if isinstance(v, (list, tuple)): 63 f.value = reduce(operator.add, v) 64 else: 65 f.value = v 66 67 return f 68 69def unaryop(op, f): 70 if isinstance(f, FormulaStat): 71 v = f.value 72 else: 73 v = f 74 75 if isinstance(v, (list, tuple)): 76 return map(op, v) 77 else: 78 return op(v) 79 80def zerodiv(lv, rv): 81 if rv == 0.0: 82 return 0.0 83 else: 84 return operator.truediv(lv, rv) 85 86def wrapop(op, lv, rv): 87 if isinstance(lv, str): 88 return lv 89 90 if isinstance(rv, str): 91 return rv 92 93 return op(lv, rv) 94 95def same(lrun, rrun): 96 for lx,rx in zip(lrun.keys(),rrun.keys()): 97 if lx != rx: 98 print 'lx != rx' 99 print lx, rx 100 print lrun.keys() 101 print rrun.keys() 102 return False 103 for ly,ry in zip(lrun[lx].keys(),rrun[rx].keys()): 104 if ly != ry: 105 print 'ly != ry' 106 print ly, ry 107 print lrun[lx].keys() 108 print rrun[rx].keys() 109 return False 110 return True 111 112 113def binaryop(op, lf, rf): 114 result = {} 115 116 if isinstance(lf, FormulaStat) and isinstance(rf, FormulaStat): 117 lv = lf.value 118 rv = rf.value 119 120 theruns = [] 121 for r in lv.keys(): 122 if rv.has_key(r): 123 if same(lv[r], rv[r]): 124 theruns.append(r) 125 else: 126 raise AttributeError 127 128 for run in theruns: 129 result[run] = {} 130 for x in lv[run].keys(): 131 result[run][x] = {} 132 for y in lv[run][x].keys(): 133 result[run][x][y] = wrapop(op, lv[run][x][y], 134 rv[run][x][y]) 135 elif isinstance(lf, FormulaStat): 136 lv = lf.value 137 for run in lv.keys(): 138 result[run] = {} 139 for x in lv[run].keys(): 140 result[run][x] = {} 141 for y in lv[run][x].keys(): 142 result[run][x][y] = wrapop(op, lv[run][x][y], rf) 143 elif isinstance(rf, FormulaStat): 144 rv = rf.value 145 for run in rv.keys(): 146 result[run] = {} 147 for x in rv[run].keys(): 148 result[run][x] = {} 149 for y in rv[run][x].keys(): 150 result[run][x][y] = wrapop(op, lf, rv[run][x][y]) 151 152 return result 153 154def sums(x, y): 155 if isinstance(x, (list, tuple)): 156 return map(lambda x, y: x + y, x, y) 157 else: 158 return x + y 159 160def alltrue(seq): 161 return reduce(lambda x, y: x and y, seq) 162 163def allfalse(seq): 164 return not reduce(lambda x, y: x or y, seq) 165 166def enumerate(seq): 167 return map(None, range(len(seq)), seq) 168 169def cmp(a, b): 170 if a < b: 171 return -1 172 elif a == b: 173 return 0 174 else: 175 return 1 176 177class Statistic(object): 178 179 def __init__(self, data): 180 self.__dict__.update(data.__dict__) 181 if not self.__dict__.has_key('value'): 182 self.__dict__['value'] = None 183 if not self.__dict__.has_key('bins'): 184 self.__dict__['bins'] = None 185 if not self.__dict__.has_key('ticks'): 186 self.__dict__['ticks'] = None 187 if 'vc' not in self.__dict__: 188 self.vc = {} 189 190 def __getattribute__(self, attr): 191 if attr == 'ticks': 192 if self.__dict__['ticks'] != globalTicks: 193 self.__dict__['value'] = None 194 self.__dict__['ticks'] = globalTicks 195 return self.__dict__['ticks'] 196 if attr == 'value': 197 if self.__dict__['ticks'] != globalTicks: 198 if self.__dict__['ticks'] != None and \ 199 len(self.__dict__['ticks']) == 1: 200 self.vc[self.__dict__['ticks'][0]] = self.__dict__['value'] 201 self.__dict__['ticks'] = globalTicks 202 if len(globalTicks) == 1 and self.vc.has_key(globalTicks[0]): 203 self.__dict__['value'] = self.vc[globalTicks[0]] 204 else: 205 self.__dict__['value'] = None 206 if self.__dict__['value'] == None: 207 self.__dict__['value'] = self.getValue() 208 return self.__dict__['value'] 209 else: 210 return super(Statistic, self).__getattribute__(attr) 211 212 def __setattr__(self, attr, value): 213 if attr == 'bins' or attr == 'ticks': 214 if attr == 'bins': 215 if value is not None: 216 value = source.getBin(value) 217 #elif attr == 'ticks' and type(value) is str: 218 # value = [ int(x) for x in value.split() ] 219 220 self.__dict__[attr] = value 221 self.__dict__['value'] = None 222 self.vc = {} 223 else: 224 super(Statistic, self).__setattr__(attr, value) 225 226 def getValue(self): 227 raise AttributeError, 'getValue() must be defined' 228 229 def zero(self): 230 return False 231 232 def __ne__(self, other): 233 return not (self == other) 234 235 def __str__(self): 236 return '%f' % (float(self)) 237 238class FormulaStat(object): 239 def __add__(self, other): 240 f = FormulaStat() 241 f.value = binaryop(operator.add, self, other) 242 return f 243 def __sub__(self, other): 244 f = FormulaStat() 245 f.value = binaryop(operator.sub, self, other) 246 return f 247 def __mul__(self, other): 248 f = FormulaStat() 249 f.value = binaryop(operator.mul, self, other) 250 return f 251 def __truediv__(self, other): 252 f = FormulaStat() 253 f.value = binaryop(zerodiv, self, other) 254 return f 255 def __mod__(self, other): 256 f = FormulaStat() 257 f.value = binaryop(operator.mod, self, other) 258 return f 259 def __radd__(self, other): 260 f = FormulaStat() 261 f.value = binaryop(operator.add, other, self) 262 return f 263 def __rsub__(self, other): 264 f = FormulaStat() 265 f.value = binaryop(operator.sub, other, self) 266 return f 267 def __rmul__(self, other): 268 f = FormulaStat() 269 f.value = binaryop(operator.mul, other, self) 270 return f 271 def __rtruediv__(self, other): 272 f = FormulaStat() 273 f.value = binaryop(zerodiv, other, self) 274 return f 275 def __rmod__(self, other): 276 f = FormulaStat() 277 f.value = binaryop(operator.mod, other, self) 278 return f 279 def __neg__(self): 280 f = FormulaStat() 281 f.value = unaryop(operator.neg, self) 282 return f 283 def __getitem__(self, idx): 284 f = FormulaStat() 285 f.value = {} 286 for key in self.value.keys(): 287 f.value[key] = {} 288 f.value[key][0] = {} 289 f.value[key][0][0] = self.value[key][idx][0] 290 return f 291 292 def __float__(self): 293 if isinstance(self.value, FormulaStat): 294 return float(self.value) 295 if not self.value.has_key(display_run): 296 return (1e300*1e300) 297 if len(self.value[display_run]) == 1: 298 return self.value[display_run][0][0] 299 else: 300 #print self.value[display_run] 301 return self.value[display_run][4][0] 302 #raise ValueError 303 304 def display(self): 305 import display 306 d = display.VectorDisplay() 307 d.flags = 0 308 d.precision = 1 309 d.name = 'formula' 310 d.desc = 'formula' 311 val = self.value[display_run] 312 d.value = [ val[x][0] for x in val.keys() ] 313 d.display() 314 315 316class Scalar(Statistic,FormulaStat): 317 def getValue(self): 318 return source.data(self, self.bins, self.ticks) 319 320 def display(self): 321 import display 322 p = display.Print() 323 p.name = self.name 324 p.desc = self.desc 325 p.value = float(self) 326 p.flags = self.flags 327 p.precision = self.precision 328 if display.all or (self.flags & flags.printable): 329 p.display() 330 331 def comparable(self, other): 332 return self.name == other.name 333 334 def __eq__(self, other): 335 return self.value == other.value 336 337 def __isub__(self, other): 338 self.value -= other.value 339 return self 340 341 def __iadd__(self, other): 342 self.value += other.value 343 return self 344 345 def __itruediv__(self, other): 346 if not other: 347 return self 348 self.value /= other 349 return self 350 351class Vector(Statistic,FormulaStat): 352 def getValue(self): 353 return source.data(self, self.bins, self.ticks); 354 355 def display(self): 356 import display 357 if not display.all and not (self.flags & flags.printable): 358 return 359 360 d = display.VectorDisplay() 361 d.__dict__.update(self.__dict__) 362 d.display() 363 364 def comparable(self, other): 365 return self.name == other.name and \ 366 len(self.value) == len(other.value) 367 368 def __eq__(self, other): 369 if isinstance(self.value, (list, tuple)) != \ 370 isinstance(other.value, (list, tuple)): 371 return False 372 373 if isinstance(self.value, (list, tuple)): 374 if len(self.value) != len(other.value): 375 return False 376 else: 377 for v1,v2 in zip(self.value, other.value): 378 if v1 != v2: 379 return False 380 return True 381 else: 382 return self.value == other.value 383 384 def __isub__(self, other): 385 self.value = binaryop(operator.sub, self.value, other.value) 386 return self 387 388 def __iadd__(self, other): 389 self.value = binaryop(operator.add, self.value, other.value) 390 return self 391 392 def __itruediv__(self, other): 393 if not other: 394 return self 395 if isinstance(self.value, (list, tuple)): 396 for i in xrange(len(self.value)): 397 self.value[i] /= other 398 else: 399 self.value /= other 400 return self 401 402class Formula(Vector): 403 def getValue(self): 404 formula = re.sub(':', '__', self.formula) 405 x = eval(formula, source.stattop) 406 return x.value 407 408 def comparable(self, other): 409 return self.name == other.name and \ 410 compare(self.dist, other.dist) 411 412 def __eq__(self, other): 413 return self.value == other.value 414 415 def __isub__(self, other): 416 return self 417 418 def __iadd__(self, other): 419 return self 420 421 def __itruediv__(self, other): 422 if not other: 423 return self 424 return self 425 426class SimpleDist(object): 427 def __init__(self, sums, squares, samples): 428 self.sums = sums 429 self.squares = squares 430 self.samples = samples 431 432 def getValue(self): 433 return 0.0 434 435 def display(self, name, desc, flags, precision): 436 import display 437 p = display.Print() 438 p.flags = flags 439 p.precision = precision 440 441 if self.samples > 0: 442 p.name = name + ".mean" 443 p.value = self.sums / self.samples 444 p.display() 445 446 p.name = name + ".stdev" 447 if self.samples > 1: 448 var = (self.samples * self.squares - self.sums ** 2) \ 449 / (self.samples * (self.samples - 1)) 450 if var >= 0: 451 p.value = math.sqrt(var) 452 else: 453 p.value = 'NaN' 454 else: 455 p.value = 0.0 456 p.display() 457 458 p.name = name + ".samples" 459 p.value = self.samples 460 p.display() 461 462 def comparable(self, other): 463 return True 464 465 def __eq__(self, other): 466 return self.sums == other.sums and self.squares == other.squares and \ 467 self.samples == other.samples 468 469 def __isub__(self, other): 470 self.sums -= other.sums 471 self.squares -= other.squares 472 self.samples -= other.samples 473 return self 474 475 def __iadd__(self, other): 476 self.sums += other.sums 477 self.squares += other.squares 478 self.samples += other.samples 479 return self 480 481 def __itruediv__(self, other): 482 if not other: 483 return self 484 self.sums /= other 485 self.squares /= other 486 self.samples /= other 487 return self 488 489class FullDist(SimpleDist): 490 def __init__(self, sums, squares, samples, minval, maxval, 491 under, vec, over, min, max, bsize, size): 492 self.sums = sums 493 self.squares = squares 494 self.samples = samples 495 self.minval = minval 496 self.maxval = maxval 497 self.under = under 498 self.vec = vec 499 self.over = over 500 self.min = min 501 self.max = max 502 self.bsize = bsize 503 self.size = size 504 505 def getValue(self): 506 return 0.0 507 508 def display(self, name, desc, flags, precision): 509 import display 510 p = display.Print() 511 p.flags = flags 512 p.precision = precision 513 514 p.name = name + '.min_val' 515 p.value = self.minval 516 p.display() 517 518 p.name = name + '.max_val' 519 p.value = self.maxval 520 p.display() 521 522 p.name = name + '.underflow' 523 p.value = self.under 524 p.display() 525 526 i = self.min 527 for val in self.vec[:-1]: 528 p.name = name + '[%d:%d]' % (i, i + self.bsize - 1) 529 p.value = val 530 p.display() 531 i += self.bsize 532 533 p.name = name + '[%d:%d]' % (i, self.max) 534 p.value = self.vec[-1] 535 p.display() 536 537 538 p.name = name + '.overflow' 539 p.value = self.over 540 p.display() 541 542 SimpleDist.display(self, name, desc, flags, precision) 543 544 def comparable(self, other): 545 return self.min == other.min and self.max == other.max and \ 546 self.bsize == other.bsize and self.size == other.size 547 548 def __eq__(self, other): 549 return self.sums == other.sums and self.squares == other.squares and \ 550 self.samples == other.samples 551 552 def __isub__(self, other): 553 self.sums -= other.sums 554 self.squares -= other.squares 555 self.samples -= other.samples 556 557 if other.samples: 558 self.minval = min(self.minval, other.minval) 559 self.maxval = max(self.maxval, other.maxval) 560 self.under -= under 561 self.vec = map(lambda x,y: x - y, self.vec, other.vec) 562 self.over -= over 563 return self 564 565 def __iadd__(self, other): 566 if not self.samples and other.samples: 567 self = other 568 return self 569 570 self.sums += other.sums 571 self.squares += other.squares 572 self.samples += other.samples 573 574 if other.samples: 575 self.minval = min(self.minval, other.minval) 576 self.maxval = max(self.maxval, other.maxval) 577 self.under += other.under 578 self.vec = map(lambda x,y: x + y, self.vec, other.vec) 579 self.over += other.over 580 return self 581 582 def __itruediv__(self, other): 583 if not other: 584 return self 585 self.sums /= other 586 self.squares /= other 587 self.samples /= other 588 589 if self.samples: 590 self.under /= other 591 for i in xrange(len(self.vec)): 592 self.vec[i] /= other 593 self.over /= other 594 return self 595 596class Dist(Statistic): 597 def getValue(self): 598 return 0.0 599 600 def display(self): 601 import display 602 if not display.all and not (self.flags & flags.printable): 603 return 604 605 self.dist.display(self.name, self.desc, self.flags, self.precision) 606 607 def comparable(self, other): 608 return self.name == other.name and \ 609 self.dist.compareable(other.dist) 610 611 def __eq__(self, other): 612 return self.dist == other.dist 613 614 def __isub__(self, other): 615 self.dist -= other.dist 616 return self 617 618 def __iadd__(self, other): 619 self.dist += other.dist 620 return self 621 622 def __itruediv__(self, other): 623 if not other: 624 return self 625 self.dist /= other 626 return self 627 628class VectorDist(Statistic): 629 def getValue(self): 630 return 0.0 631 632 def display(self): 633 import display 634 if not display.all and not (self.flags & flags.printable): 635 return 636 637 if isinstance(self.dist, SimpleDist): 638 return 639 640 for dist,sn,sd,i in map(None, self.dist, self.subnames, self.subdescs, 641 range(len(self.dist))): 642 if len(sn) > 0: 643 name = '%s.%s' % (self.name, sn) 644 else: 645 name = '%s[%d]' % (self.name, i) 646 647 if len(sd) > 0: 648 desc = sd 649 else: 650 desc = self.desc 651 652 dist.display(name, desc, self.flags, self.precision) 653 654 if (self.flags & flags.total) or 1: 655 if isinstance(self.dist[0], SimpleDist): 656 disttotal = SimpleDist( \ 657 reduce(sums, [d.sums for d in self.dist]), 658 reduce(sums, [d.squares for d in self.dist]), 659 reduce(sums, [d.samples for d in self.dist])) 660 else: 661 disttotal = FullDist( \ 662 reduce(sums, [d.sums for d in self.dist]), 663 reduce(sums, [d.squares for d in self.dist]), 664 reduce(sums, [d.samples for d in self.dist]), 665 min([d.minval for d in self.dist]), 666 max([d.maxval for d in self.dist]), 667 reduce(sums, [d.under for d in self.dist]), 668 reduce(sums, [d.vec for d in self.dist]), 669 reduce(sums, [d.over for d in self.dist]), 670 dist[0].min, 671 dist[0].max, 672 dist[0].bsize, 673 dist[0].size) 674 675 name = '%s.total' % (self.name) 676 desc = self.desc 677 disttotal.display(name, desc, self.flags, self.precision) 678 679 def comparable(self, other): 680 return self.name == other.name and \ 681 alltrue(map(lambda x, y : x.comparable(y), 682 self.dist, 683 other.dist)) 684 685 def __eq__(self, other): 686 return alltrue(map(lambda x, y : x == y, self.dist, other.dist)) 687 688 def __isub__(self, other): 689 if isinstance(self.dist, (list, tuple)) and \ 690 isinstance(other.dist, (list, tuple)): 691 for sd,od in zip(self.dist, other.dist): 692 sd -= od 693 else: 694 self.dist -= other.dist 695 return self 696 697 def __iadd__(self, other): 698 if isinstance(self.dist, (list, tuple)) and \ 699 isinstance(other.dist, (list, tuple)): 700 for sd,od in zip(self.dist, other.dist): 701 sd += od 702 else: 703 self.dist += other.dist 704 return self 705 706 def __itruediv__(self, other): 707 if not other: 708 return self 709 if isinstance(self.dist, (list, tuple)): 710 for dist in self.dist: 711 dist /= other 712 else: 713 self.dist /= other 714 return self 715 716class Vector2d(Statistic): 717 def getValue(self): 718 return 0.0 719 720 def display(self): 721 import display 722 if not display.all and not (self.flags & flags.printable): 723 return 724 725 d = display.VectorDisplay() 726 d.__dict__.update(self.__dict__) 727 728 if self.__dict__.has_key('ysubnames'): 729 ysubnames = list(self.ysubnames) 730 slack = self.x - len(ysubnames) 731 if slack > 0: 732 ysubnames.extend(['']*slack) 733 else: 734 ysubnames = range(self.x) 735 736 for x,sname in enumerate(ysubnames): 737 o = x * self.y 738 d.value = self.value[o:o+self.y] 739 d.name = '%s[%s]' % (self.name, sname) 740 d.display() 741 742 if self.flags & flags.total: 743 d.value = [] 744 for y in range(self.y): 745 xtot = 0.0 746 for x in range(self.x): 747 xtot += self.value[y + x * self.x] 748 d.value.append(xtot) 749 750 d.name = self.name + '.total' 751 d.display() 752 753 def comparable(self, other): 754 return self.name == other.name and self.x == other.x and \ 755 self.y == other.y 756 757 def __eq__(self, other): 758 return True 759 760 def __isub__(self, other): 761 return self 762 763 def __iadd__(self, other): 764 return self 765 766 def __itruediv__(self, other): 767 if not other: 768 return self 769 return self 770 771def NewStat(data): 772 stat = None 773 if data.type == 'SCALAR': 774 stat = Scalar(data) 775 elif data.type == 'VECTOR': 776 stat = Vector(data) 777 elif data.type == 'DIST': 778 stat = Dist(data) 779 elif data.type == 'VECTORDIST': 780 stat = VectorDist(data) 781 elif data.type == 'VECTOR2D': 782 stat = Vector2d(data) 783 elif data.type == 'FORMULA': 784 stat = Formula(data) 785 786 return stat 787
|