Source code for PyFoam.Applications.RedoPlot

#! /usr/bin/env python
"""A test utility that ghets all the information necessary for plotting from a remote machine and writes some plots<<"""

import sys

from PyFoam.Applications.PyFoamApplication import PyFoamApplication

from PyFoam.ThirdParty.six import PY3
if PY3:
    from xmlrpc.client import Fault,ProtocolError
else:
    from xmlrpclib import Fault,ProtocolError

from PyFoam.Infrastructure.ServerBase import getServerProxy

import socket

from optparse import OptionGroup
from PyFoam.ThirdParty.six.moves import cPickle as pickle
from time import sleep

from PyFoam.Basics.TimeLineCollection import TimeLineCollection,TimeLinesRegistry
from PyFoam.Basics.PlotTimelinesFactory import createPlotTimelines
from PyFoam.Basics.GeneralPlotTimelines import PlotLinesRegistry
from PyFoam.Basics.CustomPlotInfo import CustomPlotInfo
from PyFoam.Error import error,warning

from PyFoam.ThirdParty.six import print_,iteritems

[docs]class RedoPlot(PyFoamApplication): def __init__(self, args=None, **kwargs): description="""\ Either connects to a running pyFoam-Server and gets all the information for plotting or reads the relevant data from a pickle file and either displays the plot or writes the plots to file """ if args: self.quiet=True else: self.quiet=False PyFoamApplication.__init__(self, args=args, description=description, usage="%prog [options] (<host> <port>|<pickleFile>)", interspersed=True, nr=1, exactNr=False, **kwargs)
[docs] def addOptions(self): mode=OptionGroup(self.parser, "Input mode", "How we get the data") mode.add_option("--server", dest="server", action="store_true", default=False, help="Get the data from a FoamServer") mode.add_option("--pickle-file", dest="pickle", action="store_true", default=False, help="Get the data from a pickle-file") self.parser.add_option_group(mode) output=OptionGroup(self.parser, "Output", "Output of the data") output.add_option("--csv-files", dest="csvFiles", action="store_true", default=False, help="Write CSV-files instead of plotting") output.add_option("--excel-files", dest="excelFiles", action="store_true", default=False, help="Write Excel-files (using pandas) instead of plotting") output.add_option("--pandas-data", dest="pandasData", action="store_true", default=False, help="Pass the raw data in pandas-format") output.add_option("--pandas-series", dest="pandasSeries", action="store_true", default=False, help="Pass the raw data in pandas-series") output.add_option("--numpy-data", dest="numpyData", action="store_true", default=False, help="Pass the raw data in numpy") output.add_option("--file-prefix", dest="filePrefix", default="", help="Prefix to add to the names of the data files") output.add_option("--raw-lines", dest="rawLines", action="store_true", default=False, help="Write the raw line data (not the way it is plotted)") self.parser.add_option_group(output) plot=OptionGroup(self.parser, "Plot mode", "How the data should be plotted") plot.add_option("--implementation", default="matplotlib", dest="implementation", help="The implementation that should be used for plotting") plot.add_option("--terminal-options", default="", dest="terminalOptions", help="Terminal options that should be sent to the implementation (for instance 'size 1280,960' for gnuplot). Not all implementations will use this") plot.add_option("--show-window", dest="showWindow", action="store_true", default=False, help="Show the window with the plot") plot.add_option("--no-write-pictures", dest="writePictures", action="store_false", default=True, help="Do not write picture files") plot.add_option("--picture-prefix", dest="prefix", default="", help="Prefix to add to the names of the picture files") plot.add_option("--sleep-time", dest="sleepTime", action="store", default=0.1, type="float", help="How long to wait to allow gnuplot to finish. Default: %default") plot.add_option("--insert-titles", dest="insertTitles", action="store_true", default=False, help="Add the title to the plots") plot.add_option("--start", dest="start", action="store", default=None, type="float", help="Start the plot at this time. If undefined starts at the beginning of the data") plot.add_option("--end", dest="end", action="store", default=None, type="float", help="End the plot at this time. If undefined ends at the end of the data") self.parser.add_option_group(plot)
[docs] def run(self): if not self.opts.server and not self.opts.pickle: error("No mode selected") if self.opts.server and self.opts.pickle: error("Both modes selected") doPandas=self.opts.pandasData or self.opts.pandasSeries if self.opts.server: if len(self.parser.getArgs())!=2: error("Need a server and a port to be specified") host=self.parser.getArgs()[0] port=int(self.parser.getArgs()[1]) try: self.server=getServerProxy(host,port) methods=self.server.system.listMethods() except socket.error: reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' self.error("Socket error while connecting:",reason) except ProtocolError: reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' self.error("XMLRPC-problem",reason) plotInfo=self.executeCommand("getPlots()") lineInfo=self.executeCommand("getPlotData()") else: if len(self.parser.getArgs())!=1: warning("Only the first parameter is used") fName=self.parser.getArgs()[0] unpick=pickle.Unpickler(open(fName,"rb")) lineInfo=unpick.load() plotInfo=unpick.load() if not self.quiet: print_("Found",len(plotInfo),"plots and",len(lineInfo),"data sets") registry=TimeLinesRegistry() for nr,line in iteritems(lineInfo): if not self.quiet: print_("Adding line",nr) TimeLineCollection(preloadData=line,registry=registry) registry.resolveCollectors() if (self.opts.csvFiles or self.opts.excelFiles or doPandas or self.opts.numpyData) and self.opts.rawLines: rawData={} rawSeries={} rawNumpy={} for k,l in iteritems(registry.lines): name=str(k) if type(k)==int: name="Line%d" % k csvName=self.opts.filePrefix+name+".csv" if self.opts.csvFiles: if not self.quiet: print_("Writing",k,"to",csvName) l.getData().writeCSV(csvName) if self.opts.excelFiles: xlsName=self.opts.filePrefix+name+".xls" if not self.quiet: print_("Writing",k,"to",xlsName) l.getData().getData().to_excel(xlsName) if self.opts.pandasData: rawData[k]=l.getData().getData() if self.opts.numpyData: rawNumpy[k]=l.getData().data.copy() if self.opts.pandasSeries: rawSeries[k]=l.getData().getSeries() if self.opts.numpyData: self.setData({"rawNumpy":rawNumpy}) if self.opts.pandasData: self.setData({"rawData":rawData}) if self.opts.pandasSeries: self.setData({"rawSeries":rawSeries}) if self.opts.csvFiles or self.opts.excelFiles: return pRegistry=PlotLinesRegistry() plotNumpy={} plotData={} plotSeries={} for i,p in iteritems(plotInfo): theId=p["id"] if not self.quiet: print_("Plotting",i,":",theId,end=" ") spec=CustomPlotInfo(raw=p["spec"]) if len(registry.get(p["data"]).getTimes())>0 and len(registry.get(p["data"]).getValueNames())>0: if self.opts.csvFiles or self.opts.excelFiles or doPandas or self.opts.numpyData: dataSet=registry.get(p["data"]).getData() if self.opts.csvFiles: dataSet.writeCSV(self.opts.filePrefix+theId+".csv") if self.opts.excelFiles: dataSet.getData().to_excel(self.opts.filePrefix+theId+".xls") if self.opts.numpyData: plotNumpy[theId]=dataSet.data.copy() if self.opts.pandasData: plotData[theId]=dataSet.getData() if self.opts.pandasSeries: plotSeries[theId]=dataSet.getSeries() else: if self.opts.start or self.opts.end: # rewrite CustomPlotInfo one of these days if "start" in spec.getDict(): self.warning("Overriding plot start",spec["start"], "with",self.opts.start) spec.set("start",self.opts.start) if "end" in spec.getDict(): self.warning("Overriding plot end",spec["end"], "with",self.opts.end) spec.set("end",self.opts.end) mp=createPlotTimelines(registry.get(p["data"]), spec, implementation=self.opts.implementation, showWindow=self.opts.showWindow, registry=pRegistry) if self.opts.insertTitles: mp.actualSetTitle(p["spec"]["theTitle"]) if self.opts.writePictures: if mp.hasData(): mp.doHardcopy(self.opts.prefix+theId, "png", termOpts=self.opts.terminalOptions) else: if not self.quiet: print_("has no data",end=" ") if not self.quiet: print_() else: if not self.quiet: print_("No data - skipping") if not(self.opts.csvFiles or doPandas): sleep(self.opts.sleepTime) # there seems to be a timing issue with Gnuplot if self.opts.numpyData: self.setData({"plotNumpy":plotNumpy}) if self.opts.pandasData: self.setData({"plotData":plotData}) if self.opts.pandasSeries: self.setData({"plotSeries":plotSeries})
[docs] def executeCommand(self,cmd): result=None try: result=eval("self.server."+cmd) if result==None: # this needed to catch the unmarschalled-None-exception return None except Fault: reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' if not self.quiet: print_("XMLRPC-problem:",reason.faultString) except socket.error: reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' if not self.quiet: print_("Problem with socket (server propably dead):",reason) except TypeError: reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' if not self.quiet: print_("Type error: ",reason) result=None except SyntaxError: reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' if not self.quiet: print_("Syntax Error in:",cmd) return result
# Should work with Python3 and Python2