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

Source Code for Module PyFoam.Applications.SamplePlot

  1  #  ICE Revision: $Id: /local/openfoam/Python/PyFoam/PyFoam/Applications/SamplePlot.py 5985 2009-12-21T21:05:52.364284Z bgschaid  $  
  2  """ 
  3  Application class that implements pyFoamSamplePlot.py 
  4  """ 
  5   
  6  import sys,string 
  7  from os import path 
  8  from optparse import OptionGroup 
  9   
 10  from PyFoamApplication import PyFoamApplication 
 11  from PyFoam.RunDictionary.SampleDirectory import SampleDirectory 
 12   
 13  from PyFoam.Error import error,warning 
 14   
 15  from PlotHelpers import cleanFilename 
 16   
17 -class SamplePlot(PyFoamApplication):
18 - def __init__(self,args=None):
19 description=""" 20 Reads data from the sample-dictionary and generates appropriate 21 gnuplot-commands 22 """ 23 24 PyFoamApplication.__init__(self, 25 args=args, 26 description=description, 27 usage="%prog [options] <casedir>", 28 nr=1, 29 changeVersion=False, 30 interspersed=True)
31 32 modeChoices=["separate","timesInOne","fieldsInOne","complete"] 33
34 - def addOptions(self):
35 data=OptionGroup(self.parser, 36 "Data", 37 "Select the data to plot") 38 self.parser.add_option_group(data) 39 40 data.add_option("--line", 41 action="append", 42 default=None, 43 dest="line", 44 help="Thesample line from which data is plotted (can be used more than once)") 45 data.add_option("--field", 46 action="append", 47 default=None, 48 dest="field", 49 help="The fields that are plotted (can be used more than once). If none are specified all found fields are used") 50 data.add_option("--directory-name", 51 action="store", 52 default="samples", 53 dest="dirName", 54 help="Alternate name for the directory with the samples (Default: %default)") 55 data.add_option("--preferred-component", 56 action="store", 57 type="int", 58 default=None, 59 dest="component", 60 help="The component that should be used for vectors. Otherwise the absolute value is used") 61 62 time=OptionGroup(self.parser, 63 "Time", 64 "Select the times to plot") 65 self.parser.add_option_group(time) 66 67 time.add_option("--time", 68 action="append", 69 default=None, 70 dest="time", 71 help="The times that are plotted (can be used more than once). If none are specified all found times are used") 72 time.add_option("--min-time", 73 action="store", 74 type="float", 75 default=None, 76 dest="minTime", 77 help="The smallest time that should be used") 78 time.add_option("--max-time", 79 action="store", 80 type="float", 81 default=None, 82 dest="maxTime", 83 help="The biggest time that should be used") 84 time.add_option("--fuzzy-time", 85 action="store_true", 86 default=False, 87 dest="fuzzyTime", 88 help="Try to find the next timestep if the time doesn't match exactly") 89 90 output=OptionGroup(self.parser, 91 "Appearance", 92 "How it should be plotted") 93 self.parser.add_option_group(output) 94 95 output.add_option("--mode", 96 type="choice", 97 default="separate", 98 dest="mode", 99 action="store", 100 choices=self.modeChoices, 101 help="What kind of plots are generated: a) separate for every time and field b) all times of a field in one plot c) all fields of a time in one plot d) all lines in one plot. (Names: "+string.join(self.modeChoices,", ")+") Default: %default") 102 output.add_option("--unscaled", 103 action="store_false", 104 dest="scaled", 105 default=True, 106 help="Don't scale a value to the same range for all plots") 107 output.add_option("--scale-all", 108 action="store_true", 109 dest="scaleAll", 110 default=False, 111 help="Use the same scale for all fields (else use one scale for each field)") 112 output.add_option("--gnuplot-file", 113 action="store", 114 dest="gnuplotFile", 115 default=None, 116 help="Write the necessary gnuplot commands to this file. Else they are written to the standard output") 117 output.add_option("--picture-destination", 118 action="store", 119 dest="pictureDest", 120 default=None, 121 help="Directory the pictures should be stored to") 122 output.add_option("--name-prefix", 123 action="store", 124 dest="namePrefix", 125 default=None, 126 help="Prefix to the picture-name") 127 128 data.add_option("--info", 129 action="store_true", 130 dest="info", 131 default=False, 132 help="Print info about the sampled data and exit") 133 output.add_option("--style", 134 action="store", 135 default="lines", 136 dest="style", 137 help="Gnuplot-style for the data (Default: %default)") 138 output.add_option("--clean-filename", 139 action="store_true", 140 dest="cleanFilename", 141 default=False, 142 help="Clean filenames so that they can be used in HTML or Latex-documents")
143
144 - def run(self):
145 samples=SampleDirectory(self.parser.getArgs()[0],dirName=self.opts.dirName) 146 147 lines=samples.lines() 148 times=samples.times 149 values=samples.values() 150 151 if self.opts.info: 152 print "Times : ",samples.times 153 print "Lines : ",samples.lines() 154 print "Values: ",samples.values() 155 sys.exit(0) 156 157 if self.opts.line==None: 158 # error("At least one line has to be specified. Found were",samples.lines()) 159 self.opts.line=lines 160 else: 161 for l in self.opts.line: 162 if l not in lines: 163 error("The line",l,"does not exist in",lines) 164 165 if self.opts.maxTime or self.opts.minTime: 166 if self.opts.time: 167 error("Times",self.opts.time,"and range [",self.opts.minTime,",",self.opts.maxTime,"] set: contradiction") 168 self.opts.time=[] 169 if self.opts.maxTime==None: 170 self.opts.maxTime= 1e20 171 if self.opts.minTime==None: 172 self.opts.minTime=-1e20 173 174 for t in times: 175 if float(t)<=self.opts.maxTime and float(t)>=self.opts.minTime: 176 self.opts.time.append(t) 177 178 if len(self.opts.time)==0: 179 error("No times in range [",self.opts.minTime,",",self.opts.maxTime,"] found: ",times) 180 elif self.opts.time: 181 iTimes=self.opts.time 182 self.opts.time=[] 183 for t in iTimes: 184 if t in samples.times: 185 self.opts.time.append(t) 186 elif self.opts.fuzzyTime: 187 tf=float(t) 188 use=None 189 dist=1e20 190 for ts in samples.times: 191 if abs(tf-float(ts))<dist: 192 use=ts 193 dist=abs(tf-float(ts)) 194 if use and use not in self.opts.time: 195 self.opts.time.append(use) 196 else: 197 pass 198 # self.warning("Time",t,"not found in the sample-times. Use option --fuzzy") 199 200 plots=[] 201 202 if self.opts.mode=="separate": 203 if self.opts.time==None: 204 self.opts.time=samples.times 205 if self.opts.field==None: 206 self.opts.field=samples.values() 207 for t in self.opts.time: 208 for f in self.opts.field: 209 plots.append(samples.getData(line=self.opts.line, 210 value=[f], 211 time=[t])) 212 elif self.opts.mode=="timesInOne": 213 if self.opts.field==None: 214 self.opts.field=samples.values() 215 for f in self.opts.field: 216 plots.append(samples.getData(line=self.opts.line, 217 value=[f], 218 time=self.opts.time)) 219 elif self.opts.mode=="fieldsInOne": 220 if self.opts.scaled and not self.opts.scaleAll: 221 warning("In mode '",self.opts.mode,"' all fields are scaled to the same value") 222 self.opts.scaleAll=True 223 224 if self.opts.time==None: 225 self.opts.time=samples.times 226 for t in self.opts.time: 227 plots.append(samples.getData(line=self.opts.line, 228 value=self.opts.field, 229 time=[t])) 230 elif self.opts.mode=="complete": 231 if self.opts.scaled and not self.opts.scaleAll: 232 warning("In mode '",self.opts.mode,"' all fields are scaled to the same value") 233 self.opts.scaleAll=True 234 235 plots.append(samples.getData(line=self.opts.line, 236 value=self.opts.field, 237 time=self.opts.time)) 238 239 if self.opts.scaled: 240 if self.opts.scaleAll: 241 vRange=None 242 else: 243 vRanges={} 244 245 for p in plots: 246 for d in p: 247 mi,ma=d.range(component=self.opts.component) 248 nm=d.name 249 if not self.opts.scaleAll: 250 if nm in vRanges: 251 vRange=vRanges[nm] 252 else: 253 vRange=None 254 255 if vRange==None: 256 vRange=mi,ma 257 else: 258 vRange=min(vRange[0],mi),max(vRange[1],ma) 259 if not self.opts.scaleAll: 260 vRanges[nm]=vRange 261 262 result="set term png\n" 263 264 for p in plots: 265 if len(p)<1: 266 continue 267 268 name="" 269 if self.opts.namePrefix: 270 name+=self.opts.namePrefix+"_" 271 name+=self.opts.dirName 272 title=None 273 tIndex=times.index(p[0].time()) 274 275 name+="_"+string.join(self.opts.line,"_") 276 277 if self.opts.mode=="separate": 278 name+="_%s_%04d" % (p[0].name,tIndex) 279 title="%s at t=%f" % (p[0].name,float(p[0].time())) 280 elif self.opts.mode=="timesInOne": 281 if self.opts.time!=None: 282 name+="_"+string.join(self.opts.time,"_") 283 name+="_%s" % p[0].name 284 title="%s" % p[0].name 285 elif self.opts.mode=="fieldsInOne": 286 if self.opts.field!=None: 287 name+="_"+string.join(self.opts.field,"_") 288 name+="_%04d" % tIndex 289 title="t=%f" % float(p[0].time()) 290 elif self.opts.mode=="complete": 291 pass 292 293 name+=".png" 294 if self.opts.pictureDest: 295 name=path.join(self.opts.pictureDest,name) 296 297 if self.opts.cleanFilename: 298 name=cleanFilename(name) 299 300 result+='set output "%s"\n' % name 301 if title!=None: 302 result+='set title "%s"\n' % title 303 304 result+="plot " 305 if self.opts.scaled: 306 if not self.opts.scaleAll: 307 vRange=vRanges[p[0].name] 308 309 # only scale if extremas are sufficiently different 310 if abs(vRange[0]-vRange[1])>1e-5*max(abs(vRange[0]),abs(vRange[1])) and max(abs(vRange[0]),abs(vRange[1]))>1e-10: 311 result+="[][%g:%g] " % vRange 312 313 first=True 314 315 for d in p: 316 if first: 317 first=False 318 else: 319 result+=", " 320 321 colSpec="%s" % (d.index+1) 322 if d.isVector(): 323 if self.opts.component: 324 colSpec="%d" % (d.index+1+self.opts.component) 325 else: 326 colSpec="(sqrt($%d**2+$%d**2+$%d**2))" % (d.index+1,d.index+2,d.index+3) 327 328 result+='"%s" using 1:%s ' % (d.file,colSpec) 329 330 title=None 331 if self.opts.mode=="separate": 332 title="" 333 elif self.opts.mode=="timesInOne": 334 title="t=%f" % float(d.time()) 335 elif self.opts.mode=="fieldsInOne": 336 title="%s" % d.name 337 elif self.opts.mode=="complete": 338 title="%s at t=%f" % (d.name,float(d.time())) 339 340 if len(self.opts.line)>1: 341 title+=" on %s" % d.line() 342 343 if title=="": 344 result+="notitle " 345 else: 346 result+='title "%s" ' % title 347 348 result+="with %s " % self.opts.style 349 350 result+="\n" 351 352 dest=sys.stdout 353 if self.opts.gnuplotFile: 354 dest=open(self.opts.gnuplotFile,"w") 355 356 dest.write(result)
357