pyslha.py

Tue, 03 Aug 2010 01:27:48 +0200

author
Andy Buckley <andy@insectnation.org>
date
Tue, 03 Aug 2010 01:27:48 +0200
changeset 7
a28827356061
parent 6
1e9ee18259e2
child 8
c97f2f581685
permissions
-rw-r--r--

Tweaks to particle mass and width printout

andy@1 1 #! /usr/bin/env python
andy@1 2
andy@1 3 import re
andy@1 4
andy@4 5 def _autotype(var):
andy@4 6 if type(var) != str:
andy@4 7 return var
andy@4 8 if var.isdigit():
andy@4 9 return int(var)
andy@4 10 try:
andy@4 11 f = float(var)
andy@4 12 return f
andy@4 13 except ValueError:
andy@4 14 return var
andy@4 15
andy@4 16
andy@1 17 class Block:
andy@5 18 def __init__(self, name, q=None):
andy@1 19 self.name = name
andy@1 20 self.entries = {}
andy@5 21 self.q = _autotype(q)
andy@1 22
andy@1 23 def add_entry(self, entry):
andy@1 24 #print entry
andy@1 25 nextparent = self.entries
andy@1 26 if len(entry) < 2:
andy@1 27 raise Exception("Block entries must be at least a 2-tuple")
andy@4 28 #print "in", entry
andy@4 29 entry = map(_autotype, entry)
andy@4 30 #print "out", entry
andy@1 31 for e in entry[:-2]:
andy@1 32 if e is not entry[-1]:
andy@1 33 nextparent = nextparent.setdefault(e, {})
andy@1 34 nextparent[entry[-2]] = entry[-1]
andy@1 35 #print self.entries
andy@1 36
andy@1 37 def __cmp__(self, other):
andy@1 38 return self.name < other.name
andy@1 39
andy@1 40 def __str__(self):
andy@1 41 s = self.name
andy@5 42 if self.q is not None:
andy@5 43 s += " (Q=%s)" % self.q
andy@1 44 s += "\n"
andy@1 45 s += str(self.entries)
andy@1 46 return s
andy@1 47
andy@1 48
andy@1 49 class Decay:
andy@6 50 def __init__(self, br, nda, ids):
andy@6 51 self.br = br
andy@6 52 self.nda = nda
andy@6 53 self.ids = ids
andy@6 54
andy@6 55 def __cmp__(self, other):
andy@6 56 return self.br < other.br
andy@6 57
andy@6 58 def __str__(self):
andy@6 59 return "%e %d %s" % (self.br, self.nda, self.ids)
andy@6 60
andy@6 61
andy@6 62 class Particle:
andy@6 63 def __init__(self, pid, totalwidth=None, mass=None):
andy@6 64 self.pid = pid
andy@6 65 self.totalwidth = totalwidth
andy@6 66 self.mass = mass
andy@6 67 self.decays = []
andy@6 68
andy@6 69 def add_decay(self, br, nda, ids):
andy@6 70 self.decays.append(Decay(br, nda, ids))
andy@6 71 self.decays.sort()
andy@6 72
andy@6 73 def __cmp__(self, other):
andy@6 74 if abs(self.pid) == abs(other.pid):
andy@6 75 return self.pid < other.pid
andy@6 76 return abs(self.pid) < abs(other.pid)
andy@6 77
andy@6 78 def __str__(self):
andy@6 79 s = str(self.pid)
andy@7 80 if self.mass is not None:
andy@7 81 s += " : mass = %e GeV" % self.mass
andy@6 82 if self.totalwidth is not None:
andy@7 83 s += " : total width = %e GeV" % self.totalwidth
andy@6 84 for d in self.decays:
andy@6 85 s += "\n %s" % d
andy@6 86 return s
andy@1 87
andy@1 88
andy@1 89 def readSpcFile(filename):
andy@1 90 ## TODO: Use new file handling from future
andy@1 91 blocks = {}
andy@1 92 decays = {}
andy@1 93 f = open(filename, "r")
andy@1 94 currentblock = None
andy@6 95 currentdecay = None
andy@1 96 for l in f:
andy@1 97 line = l.strip()[:-1]
andy@1 98 ## Handle (ignore) comment lines
andy@1 99 if line.startswith("#"):
andy@1 100 continue
andy@1 101 if "#" in line:
andy@1 102 line = line[:line.index("#")]
andy@1 103
andy@1 104 ## Handle BLOCK/DECAY start lines
andy@3 105 if line.upper().startswith("BLOCK"):
andy@5 106 match = re.match(r"BLOCK\s+(\w+)\s+(Q=\s*.+)?", line.upper())
andy@5 107 if not match:
andy@5 108 continue
andy@5 109 blockname = match.group(1)
andy@5 110 qstr = match.group(2)
andy@5 111 if qstr is not None:
andy@5 112 qstr = qstr[2:].strip()
andy@1 113 currentblock = blockname
andy@6 114 currentdecay = None
andy@5 115 blocks[blockname] = Block(blockname, q=qstr)
andy@3 116 elif line.upper().startswith("DECAY"):
andy@6 117 match = re.match(r"DECAY\s+(\d+)\s+([\d\.E+-]+).*", line.upper())
andy@6 118 if not match:
andy@6 119 continue
andy@6 120 pdgid = int(match.group(1))
andy@6 121 width = float(match.group(2))
andy@1 122 currentblock = "DECAY"
andy@6 123 currentdecay = pdgid
andy@6 124 decays[pdgid] = Particle(pdgid, width)
andy@6 125 else:
andy@6 126 ## In-block line
andy@6 127 if currentblock is not None:
andy@6 128 items = line.split()
andy@6 129 if len(items) < 2:
andy@6 130 continue
andy@6 131 # TODO: Sort out tuple item types: autoconvert integers and floats
andy@6 132 if currentblock != "DECAY":
andy@6 133 #print currentblock
andy@6 134 blocks[currentblock].add_entry(items)
andy@6 135 else:
andy@6 136 br = float(items[0])
andy@6 137 nda = int(items[1])
andy@6 138 ids = map(int, items[2:])
andy@6 139 decays[currentdecay].add_decay(br, nda, ids)
andy@1 140
andy@1 141 f.close()
andy@1 142 return blocks, decays
andy@1 143
andy@1 144
andy@1 145 if __name__ == "__main__":
andy@1 146 import sys
andy@1 147 for a in sys.argv[1:]:
andy@1 148 blocks, decays = readSpcFile(a)
andy@3 149
andy@5 150 for bname, b in sorted(blocks.iteritems()):
andy@5 151 print b
andy@5 152 print
andy@3 153
andy@4 154 print blocks["MASS"].entries[25]
andy@6 155 print
andy@6 156
andy@6 157 for p in sorted(decays.values()):
andy@6 158 print p
andy@6 159 print

mercurial