Package PyFoam :: Package Applications :: Module RedoPlot
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Applications.RedoPlot

  1  #! /usr/bin/env python 
  2  """A test utility that ghets all the information necessary for plotting from a remote machine and writes some plots<<""" 
  3   
  4  import sys 
  5   
  6  from PyFoam.Applications.PyFoamApplication import PyFoamApplication 
  7   
  8  from PyFoam.ThirdParty.six import PY3 
  9  if PY3: 
 10      from xmlrpc.client import ServerProxy,Fault,ProtocolError 
 11  else: 
 12      from xmlrpclib import ServerProxy,Fault,ProtocolError 
 13   
 14  import socket 
 15   
 16  from optparse import OptionGroup 
 17  from PyFoam.ThirdParty.six.moves import cPickle as pickle 
 18  from time import sleep 
 19   
 20  from PyFoam.Basics.TimeLineCollection import TimeLineCollection,TimeLinesRegistry 
 21  from PyFoam.Basics.PlotTimelinesFactory import createPlotTimelines 
 22  from PyFoam.Basics.GeneralPlotTimelines import PlotLinesRegistry 
 23  from PyFoam.Basics.CustomPlotInfo import CustomPlotInfo 
 24  from PyFoam.Error import error,warning 
 25   
 26  from PyFoam.ThirdParty.six import print_,iteritems 
 27   
28 -class RedoPlot(PyFoamApplication):
29 - def __init__(self,args=None):
30 description="""\ 31 Either connects to a running pyFoam-Server and gets all the 32 information for plotting or reads the relevant data from a pickle file 33 and either displays the plot or writes the plots to file 34 """ 35 if args: 36 self.quiet=True 37 else: 38 self.quiet=False 39 40 PyFoamApplication.__init__(self, 41 args=args, 42 description=description, 43 usage="%prog [options] (<host> <port>|<pickleFile>)", 44 interspersed=True, 45 nr=1, 46 exactNr=False)
47
48 - def addOptions(self):
49 mode=OptionGroup(self.parser, 50 "Input mode", 51 "How we get the data") 52 mode.add_option("--server", 53 dest="server", 54 action="store_true", 55 default=False, 56 help="Get the data from a FoamServer") 57 mode.add_option("--pickle-file", 58 dest="pickle", 59 action="store_true", 60 default=False, 61 help="Get the data from a pickle-file") 62 63 self.parser.add_option_group(mode) 64 65 output=OptionGroup(self.parser, 66 "Output", 67 "Output of the data") 68 output.add_option("--csv-files", 69 dest="csvFiles", 70 action="store_true", 71 default=False, 72 help="Write CSV-files instead of plotting") 73 output.add_option("--excel-files", 74 dest="excelFiles", 75 action="store_true", 76 default=False, 77 help="Write Excel-files (using pandas) instead of plotting") 78 output.add_option("--pandas-data", 79 dest="pandasData", 80 action="store_true", 81 default=False, 82 help="Pass the raw data in pandas-format") 83 output.add_option("--pandas-series", 84 dest="pandasSeries", 85 action="store_true", 86 default=False, 87 help="Pass the raw data in pandas-series") 88 output.add_option("--numpy-data", 89 dest="numpyData", 90 action="store_true", 91 default=False, 92 help="Pass the raw data in numpy") 93 output.add_option("--file-prefix", 94 dest="filePrefix", 95 default="", 96 help="Prefix to add to the names of the data files") 97 output.add_option("--raw-lines", 98 dest="rawLines", 99 action="store_true", 100 default=False, 101 help="Write the raw line data (not the way it is plotted)") 102 self.parser.add_option_group(output) 103 104 plot=OptionGroup(self.parser, 105 "Plot mode", 106 "How the data should be plotted") 107 108 plot.add_option("--implementation", 109 default="matplotlib", 110 dest="implementation", 111 help="The implementation that should be used for plotting") 112 plot.add_option("--show-window", 113 dest="showWindow", 114 action="store_true", 115 default=False, 116 help="Show the window with the plot") 117 plot.add_option("--no-write-pictures", 118 dest="writePictures", 119 action="store_false", 120 default=True, 121 help="Do not write picture files") 122 plot.add_option("--picture-prefix", 123 dest="prefix", 124 default="", 125 help="Prefix to add to the names of the picture files") 126 plot.add_option("--sleep-time", 127 dest="sleepTime", 128 action="store", 129 default=0.1, 130 type="float", 131 help="How long to wait to allow gnuplot to finish. Default: %default") 132 plot.add_option("--insert-titles", 133 dest="insertTitles", 134 action="store_true", 135 default=False, 136 help="Add the title to the plots") 137 plot.add_option("--start", 138 dest="start", 139 action="store", 140 default=None, 141 type="float", 142 help="Start the plot at this time. If undefined starts at the beginning of the data") 143 plot.add_option("--end", 144 dest="end", 145 action="store", 146 default=None, 147 type="float", 148 help="End the plot at this time. If undefined ends at the end of the data") 149 150 self.parser.add_option_group(plot)
151
152 - def run(self):
153 if not self.opts.server and not self.opts.pickle: 154 error("No mode selected") 155 if self.opts.server and self.opts.pickle: 156 error("Both modes selected") 157 158 doPandas=self.opts.pandasData or self.opts.pandasSeries 159 160 if self.opts.server: 161 if len(self.parser.getArgs())!=2: 162 error("Need a server and a port to be specified") 163 164 host=self.parser.getArgs()[0] 165 port=int(self.parser.getArgs()[1]) 166 167 try: 168 self.server=ServerProxy("http://%s:%d" % (host,port)) 169 methods=self.server.system.listMethods() 170 except socket.error: 171 reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 172 self.error("Socket error while connecting:",reason) 173 except ProtocolError: 174 reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 175 self.error("XMLRPC-problem",reason) 176 177 plotInfo=self.executeCommand("getPlots()") 178 lineInfo=self.executeCommand("getPlotData()") 179 else: 180 if len(self.parser.getArgs())!=1: 181 warning("Only the first parameter is used") 182 183 fName=self.parser.getArgs()[0] 184 unpick=pickle.Unpickler(open(fName)) 185 186 lineInfo=unpick.load() 187 plotInfo=unpick.load() 188 189 if not self.quiet: 190 print_("Found",len(plotInfo),"plots and",len(lineInfo),"data sets") 191 192 registry=TimeLinesRegistry() 193 for nr,line in iteritems(lineInfo): 194 if not self.quiet: 195 print_("Adding line",nr) 196 TimeLineCollection(preloadData=line,registry=registry) 197 198 registry.resolveSlaves() 199 200 if (self.opts.csvFiles or self.opts.excelFiles or doPandas or self.opts.numpyData) and self.opts.rawLines: 201 rawData={} 202 rawSeries={} 203 rawNumpy={} 204 205 for k,l in iteritems(registry.lines): 206 name=str(k) 207 if type(k)==int: 208 name="Line%d" % k 209 csvName=self.opts.filePrefix+name+".csv" 210 if self.opts.csvFiles: 211 if not self.quiet: 212 print_("Writing",k,"to",csvName) 213 l.getData().writeCSV(csvName) 214 if self.opts.excelFiles: 215 xlsName=self.opts.filePrefix+name+".xls" 216 if not self.quiet: 217 print_("Writing",k,"to",xlsName) 218 l.getData().getData().to_excel(xlsName) 219 if self.opts.pandasData: 220 rawData[k]=l.getData().getData() 221 if self.opts.numpyData: 222 rawNumpy[k]=l.getData().data.copy() 223 if self.opts.pandasSeries: 224 rawSeries[k]=l.getData().getSeries() 225 226 if self.opts.numpyData: 227 self.setData({"rawNumpy":rawNumpy}) 228 if self.opts.pandasData: 229 self.setData({"rawData":rawData}) 230 if self.opts.pandasSeries: 231 self.setData({"rawSeries":rawSeries}) 232 233 if self.opts.csvFiles or self.opts.excelFiles: 234 return 235 236 pRegistry=PlotLinesRegistry() 237 238 plotNumpy={} 239 plotData={} 240 plotSeries={} 241 242 for i,p in iteritems(plotInfo): 243 theId=p["id"] 244 if not self.quiet: 245 print_("Plotting",i,":",theId,end=" ") 246 spec=CustomPlotInfo(raw=p["spec"]) 247 if len(registry.get(p["data"]).getTimes())>0 and registry.get(p["data"]).getValueNames()>0: 248 if self.opts.csvFiles or self.opts.excelFiles or doPandas or self.opts.numpyData: 249 dataSet=registry.get(p["data"]).getData() 250 if self.opts.csvFiles: 251 dataSet.writeCSV(self.opts.filePrefix+theId+".csv") 252 if self.opts.excelFiles: 253 dataSet.getData().to_excel(self.opts.filePrefix+theId+".xls") 254 if self.opts.numpyData: 255 plotNumpy[theId]=dataSet.data.copy() 256 if self.opts.pandasData: 257 plotData[theId]=dataSet.getData() 258 if self.opts.pandasSeries: 259 plotSeries[theId]=dataSet.getSeries() 260 else: 261 if self.opts.start or self.opts.end: 262 # rewrite CustomPlotInfo one of these days 263 if "start" in spec.getDict(): 264 self.warning("Overriding plot start",spec["start"], 265 "with",self.opts.start) 266 spec.set("start",self.opts.start) 267 if "end" in spec.getDict(): 268 self.warning("Overriding plot end",spec["end"], 269 "with",self.opts.end) 270 spec.set("end",self.opts.end) 271 272 mp=createPlotTimelines(registry.get(p["data"]), 273 spec, 274 implementation=self.opts.implementation, 275 showWindow=self.opts.showWindow, 276 registry=pRegistry) 277 if self.opts.insertTitles: 278 mp.actualSetTitle(p["spec"]["theTitle"]) 279 if self.opts.writePictures: 280 if mp.hasData(): 281 mp.doHardcopy(self.opts.prefix+theId,"png") 282 else: 283 if not self.quiet: 284 print_("has no data",end=" ") 285 if not self.quiet: 286 print_() 287 else: 288 if not self.quiet: 289 print_("No data - skipping") 290 291 if not(self.opts.csvFiles or doPandas): 292 sleep(self.opts.sleepTime) # there seems to be a timing issue with Gnuplot 293 294 if self.opts.numpyData: 295 self.setData({"plotNumpy":plotNumpy}) 296 if self.opts.pandasData: 297 self.setData({"plotData":plotData}) 298 if self.opts.pandasSeries: 299 self.setData({"plotSeries":plotSeries})
300 301
302 - def executeCommand(self,cmd):
303 result=None 304 try: 305 result=eval("self.server."+cmd) 306 if result==None: # this needed to catch the unmarschalled-None-exception 307 return None 308 except Fault: 309 reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 310 if not self.quiet: 311 print_("XMLRPC-problem:",reason.faultString) 312 except socket.error: 313 reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 314 if not self.quiet: 315 print_("Problem with socket (server propably dead):",reason) 316 except TypeError: 317 reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 318 if not self.quiet: 319 print_("Type error: ",reason) 320 result=None 321 except SyntaxError: 322 reason = sys.exc_info()[1] # Needed because python 2.5 does not support 'as e' 323 if not self.quiet: 324 print_("Syntax Error in:",cmd) 325 326 return result
327 328 # Should work with Python3 and Python2 329