Fri, 26 Apr 2013 20:57:42 +0200
Converting entries storage to avoid recursion, by using tuples as dict keys if necessary. Adding direct entry access via the [] operator to the Block class's entries. Improved SLHA output formatting.
ChangeLog | file | annotate | diff | comparison | revisions | |
pyslha.py | file | annotate | diff | comparison | revisions | |
testorder | file | annotate | diff | comparison | revisions |
1.1 --- a/ChangeLog Fri Apr 26 01:25:11 2013 +0200 1.2 +++ b/ChangeLog Fri Apr 26 20:57:42 2013 +0200 1.3 @@ -1,5 +1,11 @@ 1.4 2013-04-26 Andy Buckley <andy.buckley@cern.ch> 1.5 1.6 + * Improved SLHA output formatting. 1.7 + 1.8 + * Adding direct entry access via the [] operator to the Block class's entries. 1.9 + 1.10 + * Converting entries storage to avoid recursion, by using tuples as dict keys if necessary. 1.11 + 1.12 * Version 1.5.0, since the behaviour has significantly altered. 1.13 1.14 * Preserving the ordering of blocks, decays, and their their
2.1 --- a/pyslha.py Fri Apr 26 01:25:11 2013 +0200 2.2 +++ b/pyslha.py Fri Apr 26 20:57:42 2013 +0200 2.3 @@ -8,25 +8,32 @@ 2.4 use the interface, e.g. for conversion to and from the legacy ISAWIG format, or 2.5 to plot the mass spectrum and decay chains. 2.6 2.7 -The current release supports SLHA version 1, and as far as we're aware is also 2.8 +The current release supports SLHA version 1, and as far as I'm aware is also 2.9 fully compatible with SLHA2: the block structures are read and accessed 2.10 -completely generically. If you have any problems with SLHA2, please provide an 2.11 -example input file and we'll investigate. 2.12 +generically. If you have any problems, please provide an example input file and 2.13 +I'll investigate. 2.14 2.15 The plotting script provides output in PDF, EPS and PNG via LaTeX and the TikZ 2.16 graphics package, and as LaTeX/TikZ source for direct embedding into documents or 2.17 user-tweaking of the generated output. 2.18 2.19 TODOs: 2.20 - * Store dict entries as tuple keys, e.g. myblock.entries[1,2] rather than recursive dicts => v1.6.0 2.21 + 2.22 +For 1.6.0 (or 2.0.0 if changes are really sweeping): 2.23 + * Convert ISAWIG reader/writer to use new block entries access scheme 2.24 + * Direct [] access to decay info on Decay 2.25 + * Block (and Decay) to have __iter__/items() accesssors... or inherit direct from dict? 2.26 * Preserve comments from read -> write (needs full-line/inline comment separation?) 2.27 + * Output column alignment cosmetics 2.28 * Split writeSLHA into writeSLHA{Blocks,Decays} 2.29 + 2.30 +Later/maybe: 2.31 * Identify HERWIG decay matrix element to use in ISAWIG 2.32 * Handle RPV SUSY in ISAWIG 2.33 """ 2.34 2.35 __author__ = "Andy Buckley <andy.buckley@cern.ch" 2.36 -__version__ = "1.5.0" 2.37 +__version__ = "1.6.0a0" 2.38 2.39 2.40 def _mkdict(): 2.41 @@ -54,7 +61,7 @@ 2.42 return var 2.43 2.44 def _autostr(var, precision=8): 2.45 - """Automatically numerical types to the right sort of string.""" 2.46 + """Automatically format numerical types as the right sort of string.""" 2.47 if type(var) is float: 2.48 return ("%." + str(precision) + "e") % var 2.49 return str(var) 2.50 @@ -72,8 +79,8 @@ 2.51 class Block(object): 2.52 """ 2.53 Object representation of any BLOCK elements read from the SLHA file. Blocks 2.54 - have a name, may have an associated Q value, and then a collection of data 2.55 - entries, stored as a recursive dictionary. Types in the dictionary are 2.56 + have a name, may have an associated Q value, and contain a collection of data 2.57 + entries, each indexed by one or more keys. Types in the dictionary are 2.58 numeric (int or float) when a cast from the string in the file has been 2.59 possible. 2.60 """ 2.61 @@ -83,20 +90,18 @@ 2.62 self.q = _autotype(q) 2.63 2.64 def add_entry(self, entry): 2.65 - #print entry 2.66 - nextparent = self.entries 2.67 if type(entry) is str: 2.68 raise Exception("Block entries must be tuples or lists") 2.69 + entry = map(_autotype, entry) 2.70 if len(entry) < 2: 2.71 raise Exception("Block entry tuples must have at least two entries") 2.72 - #print "in", entry 2.73 - entry = map(_autotype, entry) 2.74 - #print "out", entry 2.75 - for e in entry[:-2]: 2.76 - if e is not entry[-1]: 2.77 - nextparent = nextparent.setdefault(e, _mkdict()) 2.78 - nextparent[entry[-2]] = entry[-1] 2.79 - #print self.entries 2.80 + elif len(entry) == 2: 2.81 + self.entries[entry[0]] = entry[1] 2.82 + else: 2.83 + self.entries[tuple(entry[:-1])] = entry[-1] 2.84 + 2.85 + def __getitem__(self, key): 2.86 + return self.entries[key] 2.87 2.88 def __cmp__(self, other): 2.89 return cmp(self.name, other.name) 2.90 @@ -203,6 +208,7 @@ 2.91 currentdecay = None 2.92 for line in spcstr.splitlines(): 2.93 ## Handle (ignore) comment lines 2.94 + # TODO: Store block/entry comments 2.95 if line.startswith("#"): 2.96 continue 2.97 if "#" in line: 2.98 @@ -271,35 +277,41 @@ 2.99 """ 2.100 Return an SLHA definition as a string, from the supplied blocks and decays dicts. 2.101 """ 2.102 + # TODO: Pay attention to space-padding and minus signs for column alignment 2.103 fmte = "%." + str(precision) + "e" 2.104 - 2.105 sep = " " 2.106 - out = "" 2.107 - def dict_hier_strs(d, s=""): 2.108 - if isinstance(d, dict): 2.109 - for k, v in d.iteritems(): 2.110 - for s2 in dict_hier_strs(v, s + sep + _autostr(k)): 2.111 - yield s2 2.112 - else: 2.113 - yield s + sep + _autostr(d) 2.114 + blockstrs = [] 2.115 ## Blocks 2.116 for bname, b in blocks.iteritems(): 2.117 namestr = b.name 2.118 if b.q is not None: 2.119 namestr += (" Q= " + fmte) % float(b.q) 2.120 - out += "BLOCK %s\n" % namestr 2.121 - for s in dict_hier_strs(b.entries): 2.122 - out += sep + s + "\n" 2.123 - out += "\n" 2.124 + blockstr = "BLOCK %s\n" % namestr 2.125 + entrystrs = [] 2.126 + for k, v in b.entries.iteritems(): 2.127 + entrystr = "" 2.128 + if type(k) == tuple: 2.129 + entrystr = sep.join(_autostr(i) for i in k) 2.130 + else: 2.131 + entrystr = _autostr(k) 2.132 + entrystr += sep + _autostr(v) # TODO: apply precision formatting for floats 2.133 + entrystrs.append(entrystr) 2.134 + blockstr += "\n".join(entrystrs) 2.135 + blockstrs.append(blockstr) 2.136 + ## 2.137 ## Decays 2.138 for pid, particle in decays.iteritems(): 2.139 - out += ("DECAY %d " + fmte + "\n") % (particle.pid, particle.totalwidth or -1) 2.140 + blockstr = ("DECAY %d " + fmte + "\n") % (particle.pid, particle.totalwidth or -1) 2.141 + decaystrs = [] 2.142 for d in particle.decays: 2.143 if d.br > 0.0 or not ignorenobr: 2.144 - products_str = " ".join(map(str, d.ids)) 2.145 - out += sep + fmte % d.br + sep + "%d" % len(d.ids) + sep + products_str + "\n" 2.146 - out += "\n" 2.147 - return out 2.148 + products_str = sep.join(map(str, d.ids)) 2.149 + decaystr = sep + (fmte % d.br) + sep + ("%d" % len(d.ids)) + sep + products_str 2.150 + decaystrs.append(decaystr) 2.151 + blockstr += "\n".join(decaystrs) 2.152 + blockstrs.append(blockstr) 2.153 + ## Total result 2.154 + return "\n\n".join(blockstrs) 2.155 2.156 2.157
3.1 --- a/testorder Fri Apr 26 01:25:11 2013 +0200 3.2 +++ b/testorder Fri Apr 26 20:57:42 2013 +0200 3.3 @@ -36,4 +36,5 @@ 3.4 1000001 5.68441109E+02 # ~d_L 3.5 """) 3.6 3.7 + 3.8 print pyslha.writeSLHA(blocks, decays)