Thu, 26 Sep 2013 00:03:52 +0200
Adding a top-level Doc class and restructuring to use it.
ChangeLog | file | annotate | diff | comparison | revisions | |
pyslha.py | file | annotate | diff | comparison | revisions | |
slhaplot | file | annotate | diff | comparison | revisions |
1.1 --- a/ChangeLog Mon Jul 15 16:50:38 2013 +0200 1.2 +++ b/ChangeLog Thu Sep 26 00:03:52 2013 +0200 1.3 @@ -1,3 +1,7 @@ 1.4 +2013-09-26 Andy Buckley <andy.buckley@cern.ch> 1.5 + 1.6 + * Adding a top-level Doc class and restructuring to use it. 1.7 + 1.8 2013-07-15 Andy Buckley <andy.buckley@cern.ch> 1.9 1.10 * Version 2.1.3
2.1 --- a/pyslha.py Mon Jul 15 16:50:38 2013 +0200 2.2 +++ b/pyslha.py Thu Sep 26 00:03:52 2013 +0200 2.3 @@ -11,7 +11,9 @@ 2.4 The current release supports SLHA version 1, and as far as I'm aware is also 2.5 fully compatible with SLHA2: the block structures are read and accessed 2.6 generically. If you have any problems, please provide an example input file and 2.7 -I'll happily investigate. 2.8 +I'll happily investigate. SLHA3 is not yet supported (or standardised) but in 2.9 +recent releases the new structures will not crash the parser. Support will be 2.10 +added once the format is standardised (and in response to demand!) 2.11 2.12 The plotting script provides output in PDF, EPS and PNG via LaTeX and the TikZ 2.13 graphics package, and as LaTeX/TikZ source for direct embedding into documents or 2.14 @@ -33,31 +35,28 @@ 2.15 2.16 TODOs: 2.17 2.18 - For 2.1.4: 2.19 + For 3.0.x: 2.20 * In set_value, if first item is non-int, treat as None-indexed 2.21 * Refine value string heuristic for strings with ints in them? 2.22 + * Allow read* and write* functions to be called on file objects as well as filenames. 2.23 + * Use Doc to handle document-level header comments. 2.24 + * Add block and decay summary comments to the OrderedDict (wrap OrderedDict as DataStore?) 2.25 + * Provide a DataStore.__str__ which hides the uninteresting OrderedDict boilerplate. 2.26 + * Provide a Doc.__str__ method 2.27 2.28 - For 2.2.0: 2.29 - * Add Sphinx docs. 2.30 - * Preserve comments from read -> write (needs full-line/inline comment 2.31 + For 3.1.x: 2.32 + * Preserve inline comments from read -> write (needs full-line/inline comment 2.33 separation). Can use separate comment dicts in Block and Decay, and 2.34 attach a multiline .comment attr to the returned/written dicts. 2.35 2.36 - For 3.0.0: 2.37 - * Add a new Doc type which encapsulates the blocks, decays, xsections, 2.38 - etc. data sections and will act as a more robust single return value from 2.39 - the read commands / argument to the write commands. Can also handle 2.40 - document-level header comments this way and improve the __repr__ resulting 2.41 - from an interactive read() call without a target variable (i.e. hide the 2.42 - uninteresting OrderedDict boilerplate). 2.43 - 2.44 Later/maybe: 2.45 + * Add Sphinx docs. 2.46 * Identify HERWIG decay matrix element to use in ISAWIG 2.47 * Handle RPV SUSY in ISAWIG 2.48 """ 2.49 2.50 __author__ = "Andy Buckley <andy.buckley@cern.ch>" 2.51 -__version__ = "2.1.3" 2.52 +__version__ = "3.0.0a0" 2.53 2.54 2.55 2.56 @@ -123,6 +122,28 @@ 2.57 return self.msg 2.58 2.59 2.60 +############################################################################### 2.61 +## The Doc top-level container object 2.62 + 2.63 +class Doc(object): 2.64 + "Top level container for everything in an SLHA record" 2.65 + def __init__(self, blocks, decays=None, xsections=None): 2.66 + self.blocks = blocks 2.67 + self.decays = decays 2.68 + self.xsections = xsections 2.69 + self.comment = "" 2.70 + 2.71 + def slha(self, filename=None, ignorenobr=False, precision=8): 2.72 + """ 2.73 + Convenient method for converting an SLHA Doc object to SLHA format, 2.74 + either returned as a string or written to a file depending on whether 2.75 + the filename variable is None. 2.76 + """ 2.77 + if filename is None: 2.78 + return writeSLHA(self, ignorenobr, precision) 2.79 + else: 2.80 + writeSLHAFile(filename, self, ignorenobr, precision) 2.81 + 2.82 2.83 ############################################################################### 2.84 ## The data block, decay and particle classes 2.85 @@ -197,16 +218,21 @@ 2.86 'value()' attribute may be used in that case without an argument.""" 2.87 return len(self.entries) == 1 and self.entries.keys()[0] is None 2.88 2.89 - def value(self, key=None): 2.90 + def value(self, key=None, default=1): 2.91 """Get a value from the block with the supplied key. 2.92 2.93 If no key is given, then the block must contain only one non-indexed 2.94 value otherwise an AccessError exception will be raised.\ 2.95 """ 2.96 - if key == None and not self.is_single_valued(): 2.97 + if key is None and not self.is_single_valued(): 2.98 raise AccessError("Tried to access unique value of multi-value block") 2.99 + if not self.has_key(key): 2.100 + return default 2.101 return self.entries[key] 2.102 2.103 + "Alias" 2.104 + get = value 2.105 + 2.106 def set_value(self, *args): 2.107 """Set a value in the block via supplied key/value arguments. 2.108 2.109 @@ -238,6 +264,9 @@ 2.110 else: 2.111 self.entries[_autotuple(args[:i_first_nonint])] = _autotuple(args[i_first_nonint:]) 2.112 2.113 + "Alias" 2.114 + set = set_value 2.115 + 2.116 def has_key(self, key): 2.117 """Does the block have the given key?""" 2.118 return self.entries.has_key(key) 2.119 @@ -442,8 +471,8 @@ 2.120 if not ignorenomass: 2.121 raise ParseError("No MASS block found: cannot populate particle masses") 2.122 2.123 - return blocks, decays 2.124 - 2.125 + rtn = Doc(blocks, decays) 2.126 + return rtn 2.127 2.128 2.129 def writeSLHABlocks(blocks, precision=8): 2.130 @@ -488,9 +517,9 @@ 2.131 2.132 2.133 2.134 -def writeSLHA(blocks, decays, ignorenobr=False, precision=8): 2.135 +def writeSLHA(doc, ignorenobr=False, precision=8): 2.136 """Return an SLHA definition as a string, from the supplied blocks and decays dicts.""" 2.137 - ss = [x for x in (writeSLHABlocks(blocks, precision), writeSLHADecays(decays, ignorenobr, precision)) if x] 2.138 + ss = [x for x in (writeSLHABlocks(doc.blocks, precision), writeSLHADecays(doc.decays, ignorenobr, precision)) if x] 2.139 return "\n\n".join(ss) 2.140 2.141 2.142 @@ -829,10 +858,10 @@ 2.143 2.144 # TODO: Parse RPV boolean and couplings into SLHA2 blocks 2.145 2.146 - return blocks, decays 2.147 + return Doc(blocks, decays) 2.148 2.149 2.150 -def writeISAWIG(blocks, decays, ignorenobr=False, precision=8): 2.151 +def writeISAWIG(doc, ignorenobr=False, precision=8): 2.152 """ 2.153 Return a SUSY spectrum definition in the format produced by ISAWIG for inut to HERWIG 2.154 as a string, from the supplied SLHA blocks and decays dicts. 2.155 @@ -843,6 +872,10 @@ 2.156 If the ignorenobr parameter is True, do not write decay entries with a 2.157 branching ratio of zero. 2.158 """ 2.159 + 2.160 + blocks = doc.blocks 2.161 + decays = doc.decays 2.162 + 2.163 masses = blocks["MASS"] 2.164 2.165 ## Init output string 2.166 @@ -1092,6 +1125,23 @@ 2.167 ############################################################################### 2.168 ## File-level read/write functions 2.169 2.170 +def read(spcfilename, **kwargs): 2.171 + """ 2.172 + Read an SLHA or ISAWIG file (or stdin). 2.173 + 2.174 + The assumed file format is taken from the filename. 2.175 + 2.176 + Other keyword parameters are passed to readSLHA/readISAWIG. 2.177 + """ 2.178 + if spcfilename == "-": 2.179 + intext = sys.stdin.read() 2.180 + return readSLHA(intext, **kwargs) 2.181 + elif spcfilename.endswith(".isa"): 2.182 + return readISAWIGFile(spcfilename, **kwargs) 2.183 + else: 2.184 + return readSLHAFile(spcfilename, **kwargs) 2.185 + 2.186 + 2.187 def readSLHAFile(spcfilename, **kwargs): 2.188 """ 2.189 Read an SLHA file, returning dictionaries of blocks and decays. 2.190 @@ -1104,14 +1154,14 @@ 2.191 return rtn 2.192 2.193 2.194 -def writeSLHAFile(spcfilename, blocks, decays, **kwargs): 2.195 +def writeSLHAFile(spcfilename, doc, **kwargs): 2.196 """ 2.197 Write an SLHA file from the supplied blocks and decays dicts. 2.198 2.199 Other keyword parameters are passed to writeSLHA. 2.200 """ 2.201 f = open(spcfilename, "w") 2.202 - f.write(writeSLHA(blocks, decays, **kwargs)) 2.203 + f.write(writeSLHA(doc, **kwargs)) 2.204 f.close() 2.205 2.206 2.207 @@ -1122,7 +1172,7 @@ 2.208 informally supported as a useful mechanism for converting ISAWIG spectra to 2.209 SLHA. 2.210 2.211 - Other keyword parameters are passed to readSLHA. 2.212 + Other keyword parameters are passed to readISAWIG. 2.213 """ 2.214 f = open(isafilename, "r") 2.215 rtn = readISAWIG(f.read(), **kwargs) 2.216 @@ -1130,14 +1180,14 @@ 2.217 return rtn 2.218 2.219 2.220 -def writeISAWIGFile(isafilename, blocks, decays, **kwargs): 2.221 +def writeISAWIGFile(isafilename, doc, **kwargs): 2.222 """ 2.223 Write an ISAWIG file from the supplied blocks and decays dicts. 2.224 2.225 Other keyword parameters are passed to writeISAWIG. 2.226 """ 2.227 f = open(isafilename, "w") 2.228 - f.write(writeISAWIG(blocks, decays, **kwargs)) 2.229 + f.write(writeISAWIG(doc, **kwargs)) 2.230 f.close() 2.231 2.232 2.233 @@ -1149,21 +1199,21 @@ 2.234 import sys 2.235 for a in sys.argv[1:]: 2.236 if a.endswith(".isa"): 2.237 - blocks, decays = readISAWIGFile(a) 2.238 + doc = readISAWIGFile(a) 2.239 else: 2.240 - blocks, decays = readSLHAFile(a) 2.241 + doc = readSLHAFile(a) 2.242 2.243 - for bname, b in sorted(blocks.iteritems()): 2.244 + for bname, b in sorted(doc.blocks.iteritems()): 2.245 print b 2.246 print 2.247 2.248 - print blocks.keys() 2.249 + print doc.blocks.keys() 2.250 2.251 - print blocks["MASS"][25] 2.252 + print doc.blocks["MASS"].get(25) 2.253 print 2.254 2.255 - for p in sorted(decays.values()): 2.256 + for p in sorted(doc.decays.values()): 2.257 print p 2.258 print 2.259 2.260 - print writeSLHA(blocks, decays, ignorenobr=True) 2.261 + print writeSLHA(doc, ignorenobr=True)
3.1 --- a/slhaplot Mon Jul 15 16:50:38 2013 +0200 3.2 +++ b/slhaplot Thu Sep 26 00:03:52 2013 +0200 3.3 @@ -25,7 +25,7 @@ 3.4 do with decay arrows that would go outside the range. Eliminate --maxmass? 3.5 * Allow user to provide a file which defines the particle line x-positions, labels, etc. 3.6 * Use unit scaling to allow the y coordinates to be in units of 100 GeV in TikZ output. 3.7 - * Merge labels if shifting fails (cf. "poi" test spectrum file). 3.8 + * Merge labels if shifting fails (cf. 'poi' test spectrum file). 3.9 * Allow use of --outname to specify a list of output base names for multiple inputs. 3.10 * Use proper distinction between physical, plot-logical, and plot output coords. 3.11 * Allow more user control over the output geometry. 3.12 @@ -262,13 +262,8 @@ 3.13 ## Read spectrum file 3.14 BLOCKS, DECAYS = None, None 3.15 try: 3.16 - if infile == "-": 3.17 - intext = sys.stdin.read() 3.18 - BLOCKS, DECAYS = pyslha.readSLHA(intext) 3.19 - elif infile.endswith(".isa"): 3.20 - BLOCKS, DECAYS = pyslha.readISAWIGFile(infile) 3.21 - else: 3.22 - BLOCKS, DECAYS = pyslha.readSLHAFile(infile) 3.23 + doc = pyslha.read(infile) 3.24 + BLOCKS, DECAYS = doc.blocks, doc.decays 3.25 except pyslha.ParseError, pe: 3.26 logging.error(str(pe) + "... exiting") 3.27 sys.exit(1)