Use more semantic handling of the format string specifier, and try to avoid using constructs not available in SLC5's native Python pyslha-1.2.1

Mon, 07 Mar 2011 10:48:37 +0000

author
Andy Buckley <andy@insectnation.org>
date
Mon, 07 Mar 2011 10:48:37 +0000
changeset 134
323754f1d261
parent 133
5e27f4121fd1
child 135
ebd8cd36aeec

Use more semantic handling of the format string specifier, and try to avoid using constructs not available in SLC5's native Python

pyslha.py file | annotate | diff | comparison | revisions
slhaplot file | annotate | diff | comparison | revisions
     1.1 --- a/pyslha.py	Sun Mar 06 23:44:39 2011 +0000
     1.2 +++ b/pyslha.py	Mon Mar 07 10:48:37 2011 +0000
     1.3 @@ -23,7 +23,7 @@
     1.4  """
     1.5  
     1.6  __author__ = "Andy Buckley <andy.buckley@cern.ch"
     1.7 -__version__ = "1.2.0"
     1.8 +__version__ = "1.2.1"
     1.9  
    1.10  
    1.11  def _autotype(var):
     2.1 --- a/slhaplot	Sun Mar 06 23:44:39 2011 +0000
     2.2 +++ b/slhaplot	Mon Mar 07 10:48:37 2011 +0000
     2.3 @@ -17,8 +17,6 @@
     2.4    * Merge labels if shifting fails (cf. "poi" test spectrum file).
     2.5    * Avoid overlap/too-tight clustering of y-axis ticks. Looks fine for *most*
     2.6      spectra I've seen with 100 GeV intervals, but it should be handled properly.
     2.7 -  * Use object wrapper for format strings, to centralise "needs pdflatex?"-type
     2.8 -    questions and provide UI case-insensitivity
     2.9    * Allow user to provide a file which defines the particle line x-positions, labels, etc.
    2.10    * Allow use of --outname to specify a list of output base names for multiple inputs.
    2.11    * Use proper distinction between physical, plot-logical, and plot output coords.
    2.12 @@ -82,10 +80,80 @@
    2.13          self.color = color
    2.14  
    2.15  
    2.16 +# ## Python version workaround
    2.17 +# if not "any" in dir():
    2.18 +#     def any(*args):
    2.19 +#         for i in args:
    2.20 +#             if i: return True
    2.21 +#         return False
    2.22 +
    2.23 +
    2.24  class OutputFormatSpec(object):
    2.25      """Object to abstract translation of semi-arbitrary format strings into
    2.26      something more semantically queryable."""
    2.27 -    pass
    2.28 +
    2.29 +    def __init__(self, fmtstr):
    2.30 +        self.format_string = fmtstr.lower()
    2.31 +        if "tikz" not in self.format_string:
    2.32 +            self.format_string = "tikz" + self.format_string
    2.33 +        if self.format_string == "tikz":
    2.34 +            self.format_string = "tikztex"
    2.35 +        elif self.format_string == "tikzfrag":
    2.36 +            self.format_string = "tikztexfrag"
    2.37 +        if "frag" in self.format_string and any(f in self.format_string for f in ["pdf", "eps", "png"]):
    2.38 +            logging.error("Oops! You can't currently use LaTeX fragment output together with graphics "
    2.39 +                          "formats, since the graphics can't be built from the incomplete LaTeX "
    2.40 +                          "file. We'll fix this, but for now you will have to run slhaplot twice: "
    2.41 +                          "once for the LaTeX fragment, and another time for the graphical output "
    2.42 +                          "formats. Exiting...")
    2.43 +            sys.exit(1)
    2.44 +
    2.45 +    def make_tex(self):
    2.46 +        return ("tex" in self.format_string and not "frag" in self.format_string)
    2.47 +
    2.48 +    def make_texfrag(self):
    2.49 +        return ("texfrag" in self.format_string)
    2.50 +
    2.51 +    def make_pdf(self):
    2.52 +        return ("pdf" in self.format_string)
    2.53 +
    2.54 +    def make_eps(self):
    2.55 +        return ("eps" in self.format_string)
    2.56 +
    2.57 +    def make_png(self):
    2.58 +        return ("png" in self.format_string)
    2.59 +
    2.60 +
    2.61 +    def need_tikz(self):
    2.62 +        for f in ["pdf", "eps", "png"]:
    2.63 +            if f in self.format_string:
    2.64 +                return True
    2.65 +        return False
    2.66 +
    2.67 +    def need_epslatex(self):
    2.68 +        for f in ["eps"]:
    2.69 +            if f in self.format_string:
    2.70 +                return True
    2.71 +        return False
    2.72 +
    2.73 +    def need_pdflatex(self):
    2.74 +        for f in ["pdf", "png"]:
    2.75 +            if f in self.format_string:
    2.76 +                return True
    2.77 +        return False
    2.78 +
    2.79 +    def need_convert(self):
    2.80 +        for f in ["png"]:
    2.81 +            if f in self.format_string:
    2.82 +                return True
    2.83 +        return False
    2.84 +
    2.85 +    def need_compilation(self):
    2.86 +        return self.need_epslatex() or self.need_pdflatex()
    2.87 +
    2.88 +    def file_extensions(self):
    2.89 +        return [f for f in ["tex", "pdf", "eps", "png"] if f in self.format_string]
    2.90 +
    2.91  
    2.92  
    2.93  import pyslha
    2.94 @@ -154,20 +222,8 @@
    2.95  else:
    2.96      opts.DECAYS_MINBR = float(opts.DECAYS_MINBR)
    2.97  
    2.98 -## Output format wrangling
    2.99 -if "tikz" not in opts.FORMAT:
   2.100 -    opts.FORMAT = "tikz" + opts.FORMAT
   2.101 -if opts.FORMAT == "tikz":
   2.102 -    opts.FORMAT = "tikztex"
   2.103 -elif opts.FORMAT == "tikzfrag":
   2.104 -    opts.FORMAT = "tikztexfrag"
   2.105 -if "frag" in opts.FORMAT and any(f in opts.FORMAT for f in ["pdf", "eps", "png"]):
   2.106 -    logging.error("Oops! You can't currently use LaTeX fragment output together with graphics "
   2.107 -                  "formats, since the graphics can't be built from the incomplete LaTeX "
   2.108 -                  "file. We'll fix this, but for now you will have to run slhaplot twice: "
   2.109 -                  "once for the LaTeX fragment, and another time for the graphical output "
   2.110 -                  "formats. Exiting...")
   2.111 -    sys.exit(1)
   2.112 +## Output format handling: convert string arg to a more semantically queryable type
   2.113 +opts.FORMAT = OutputFormatSpec(opts.FORMAT)
   2.114  
   2.115  
   2.116  ## Check non-optional arguments
   2.117 @@ -184,7 +240,7 @@
   2.118  import subprocess
   2.119  
   2.120  ## Test for tikz package if rendering the LaTeX source
   2.121 -if not any(f in opts.FORMAT for f in ["pdf", "eps", "png"]):
   2.122 +if opts.FORMAT.need_tikz():
   2.123      p = subprocess.Popen(["which", "kpsewhich"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
   2.124      rtn = p.wait()
   2.125      if rtn != 0:
   2.126 @@ -197,7 +253,7 @@
   2.127              sys.exit(3)
   2.128  
   2.129  ## Test for pdflatex if we need to make a PDF
   2.130 -if "pdf" in opts.FORMAT or "png" in opts.FORMAT:
   2.131 +if opts.FORMAT.need_pdflatex():
   2.132      p = subprocess.Popen(["which", "pdflatex"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
   2.133      rtn = p.wait()
   2.134      if rtn != 0:
   2.135 @@ -205,7 +261,7 @@
   2.136          sys.exit(3)
   2.137  
   2.138      ## Test for convert if we need to make a bitmap format
   2.139 -    if "png" in opts.FORMAT:
   2.140 +    if opts.FORMAT.need_convert():
   2.141          p = subprocess.Popen(["which", "convert"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
   2.142          rtn = p.wait()
   2.143          if rtn != 0:
   2.144 @@ -213,7 +269,7 @@
   2.145              sys.exit(3)
   2.146  
   2.147  ## Test for latex, dvips and ps2eps if making an EPS
   2.148 -if "eps" in opts.FORMAT:
   2.149 +if opts.FORMAT.need_epslatex():
   2.150      p = subprocess.Popen(["which", "latex"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
   2.151      rtn = p.wait()
   2.152      if rtn != 0:
   2.153 @@ -246,8 +302,7 @@
   2.154          outname = o
   2.155  
   2.156      ## Info for the user
   2.157 -    # TODO: Print all output filenames explicitly?
   2.158 -    extlist = [f for f in ["tex", "pdf", "eps", "png"] if f in opts.FORMAT]
   2.159 +    extlist = opts.FORMAT.file_extensions()
   2.160      extstr = ",".join(extlist)
   2.161      if len(extlist) > 1:
   2.162          extstr = "{" + extstr + "}"
   2.163 @@ -437,11 +492,12 @@
   2.164      out = ""
   2.165  
   2.166      ## TIKZ FORMAT
   2.167 -    if "tikz" in opts.FORMAT:
   2.168 +    # TODO: Remove this test?
   2.169 +    if "tikz" in opts.FORMAT.format_string:
   2.170  
   2.171          ## Comment out the preamble etc. if only the TikZ fragment is wanted
   2.172          c = ""
   2.173 -        if opts.FORMAT == "tikztexfrag":
   2.174 +        if opts.FORMAT.make_texfrag():
   2.175              c = "%"
   2.176  
   2.177          ## Write LaTeX header
   2.178 @@ -563,10 +619,10 @@
   2.179  
   2.180  
   2.181          ## Write output
   2.182 -        if "tex" in opts.FORMAT:
   2.183 +        if opts.FORMAT.make_tex():
   2.184              writeout(out, outname+".tex")
   2.185  
   2.186 -        if any(f in opts.FORMAT for f in ["pdf", "eps", "png"]):
   2.187 +        if opts.FORMAT.need_compilation():
   2.188              ## Run LaTeX
   2.189              import tempfile, shutil, subprocess
   2.190              tmpdir = tempfile.mkdtemp()
   2.191 @@ -578,11 +634,11 @@
   2.192                                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
   2.193  
   2.194              ## Processing via PDF
   2.195 -            if any(f in opts.FORMAT for f in ["pdf", "png"]):
   2.196 +            if opts.FORMAT.need_pdflatex():
   2.197                  try:
   2.198                      p = mktmpprocess(["pdflatex", r"\scrollmode\input", "mytmp.tex"])
   2.199                      p.wait()
   2.200 -                    if "pdf" in opts.FORMAT:
   2.201 +                    if opts.FORMAT.make_pdf():
   2.202                          shutil.copyfile(os.path.join(tmpdir, "mytmp.pdf"), outname+".pdf")
   2.203                  except Exception, e:
   2.204                      logging.error("pdflatex could not be run: PDF and/or PNG format mode cannot work")
   2.205 @@ -591,7 +647,7 @@
   2.206                      # TODO: Can we use a finally block to make sure that the tmpdir is cleared up, despite the 'sys.exit's?
   2.207  
   2.208                  ## Turning the PDF into a PNG if required
   2.209 -                if "png" in opts.FORMAT:
   2.210 +                if opts.FORMAT.make_png():
   2.211                      try:
   2.212                          p = mktmpprocess(["convert", "-density", "150", "-flatten", "mytmp.pdf", "mytmp.png"])
   2.213                          p.wait()
   2.214 @@ -602,7 +658,7 @@
   2.215                          sys.exit(3)
   2.216  
   2.217              ## Making a PS or EPS
   2.218 -            if any(f in opts.FORMAT for f in ["eps"]):
   2.219 +            if opts.FORMAT.make_eps():
   2.220                  try:
   2.221                      p = mktmpprocess(["latex", r"\scrollmode\input", "mytmp.tex"])
   2.222                      p.wait()

mercurial