Adding a top-level Doc class and restructuring to use it. default tip

Thu, 26 Sep 2013 00:03:52 +0200

author
Andy Buckley <andy@insectnation.org>
date
Thu, 26 Sep 2013 00:03:52 +0200
changeset 245
ca52fe2c0d71
parent 244
269bc4611cdd

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)

mercurial