1
2 """
3 Application class that implements pyFoamSamplePlot.py
4 """
5
6 import sys,string
7 from optparse import OptionGroup
8
9 from PyFoamApplication import PyFoamApplication
10 from PyFoam.RunDictionary.SampleDirectory import SampleDirectory
11
12 from PyFoam.Error import error,warning
13
28
29 modeChoices=["separate","timesInOne","fieldsInOne","complete"]
30
32 data=OptionGroup(self.parser,
33 "Data",
34 "Select the data to plot")
35 self.parser.add_option_group(data)
36
37 data.add_option("--line",
38 action="append",
39 default=None,
40 dest="line",
41 help="Thesample line from which data is plotted (can be used more than once)")
42 data.add_option("--field",
43 action="append",
44 default=None,
45 dest="field",
46 help="The fields that are plotted (can be used more than once). If none are specified all found fields are used")
47 data.add_option("--directory-name",
48 action="store",
49 default="samples",
50 dest="dirName",
51 help="Alternate name for the directory with the samples (Default: %default)")
52
53 time=OptionGroup(self.parser,
54 "Time",
55 "Select the times to plot")
56 self.parser.add_option_group(time)
57
58 time.add_option("--time",
59 action="append",
60 default=None,
61 dest="time",
62 help="The times that are plotted (can be used more than once). If none are specified all found times are used")
63 time.add_option("--min-time",
64 action="store",
65 type="float",
66 default=None,
67 dest="minTime",
68 help="The smallest time that should be used")
69 time.add_option("--max-time",
70 action="store",
71 type="float",
72 default=None,
73 dest="maxTime",
74 help="The biggest time that should be used")
75
76 output=OptionGroup(self.parser,
77 "Appearance",
78 "How it should be plotted")
79 self.parser.add_option_group(output)
80
81 output.add_option("--mode",
82 type="choice",
83 default="separate",
84 dest="mode",
85 action="store",
86 choices=self.modeChoices,
87 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")
88 output.add_option("--unscaled",
89 action="store_false",
90 dest="scaled",
91 default=True,
92 help="Don't scale a value to the same range for all plots")
93 output.add_option("--scale-all",
94 action="store_true",
95 dest="scaleAll",
96 default=False,
97 help="Use the same scale for all fields (else use one scale for each field)")
98 data.add_option("--info",
99 action="store_true",
100 dest="info",
101 default=False,
102 help="Print info about the sampled data and exit")
103 output.add_option("--style",
104 action="store",
105 default="lines",
106 dest="style",
107 help="Gnuplot-style for the data (Default: %default)")
108
110 samples=SampleDirectory(self.parser.getArgs()[0],dirName=self.opts.dirName)
111
112 lines=samples.lines()
113 times=samples.times
114 values=samples.values()
115
116 if self.opts.info:
117 print "Times : ",samples.times
118 print "Lines : ",samples.lines()
119 print "Values: ",samples.values()
120 sys.exit(0)
121
122 if self.opts.line==None:
123 error("At least one line has to be specified. Found were",samples.lines())
124 else:
125
126 for l in self.opts.line:
127 if l not in lines:
128 error("The line",l,"does not exist in",lines)
129
130 if self.opts.maxTime or self.opts.minTime:
131 if self.opts.time:
132 error("Times",self.opts.time,"and range [",self.opts.minTime,",",self.opts.maxTime,"] set: contradiction")
133 self.opts.time=[]
134 if self.opts.maxTime==None:
135 self.opts.maxTime= 1e20
136 if self.opts.minTime==None:
137 self.opts.minTime=-1e20
138
139 for t in times:
140 if float(t)<=self.opts.maxTime and float(t)>=self.opts.minTime:
141 self.opts.time.append(t)
142
143 if len(self.opts.time)==0:
144 error("No times in range [",self.opts.minTime,",",self.opts.maxTime,"] found: ",times)
145
146 plots=[]
147
148 if self.opts.mode=="separate":
149 if self.opts.time==None:
150 self.opts.time=samples.times
151 if self.opts.field==None:
152 self.opts.field=samples.values()
153 for t in self.opts.time:
154 for f in self.opts.field:
155 plots.append(samples.getData(line=self.opts.line,
156 value=[f],
157 time=[t]))
158 elif self.opts.mode=="timesInOne":
159 if self.opts.field==None:
160 self.opts.field=samples.values()
161 for f in self.opts.field:
162 plots.append(samples.getData(line=self.opts.line,
163 value=[f],
164 time=self.opts.time))
165 elif self.opts.mode=="fieldsInOne":
166 if self.opts.scaled and not self.opts.scaleAll:
167 warning("In mode '",self.opts.mode,"' all fields are scaled to the same value")
168 self.opts.scaleAll=True
169
170 if self.opts.time==None:
171 self.opts.time=samples.times
172 for t in self.opts.time:
173 plots.append(samples.getData(line=self.opts.line,
174 value=self.opts.field,
175 time=[t]))
176 elif self.opts.mode=="complete":
177 if self.opts.scaled and not self.opts.scaleAll:
178 warning("In mode '",self.opts.mode,"' all fields are scaled to the same value")
179 self.opts.scaleAll=True
180
181 plots.append(samples.getData(line=self.opts.line,
182 value=self.opts.field,
183 time=self.opts.time))
184
185 if self.opts.scaled:
186 if self.opts.scaleAll:
187 vRange=None
188 else:
189 vRanges={}
190
191 for p in plots:
192 for d in p:
193 mi,ma=d.range()
194 nm=d.name
195 if not self.opts.scaleAll:
196 if nm in vRanges:
197 vRange=vRanges[nm]
198 else:
199 vRange=None
200
201 if vRange==None:
202 vRange=mi,ma
203 else:
204 vRange=min(vRange[0],mi),max(vRange[1],ma)
205 if not self.opts.scaleAll:
206 vRanges[nm]=vRange
207
208 result="set term png\n"
209
210 for p in plots:
211 if len(p)<1:
212 continue
213
214 name=self.opts.dirName
215 title=None
216 tIndex=times.index(p[0].time())
217
218 name+="_"+string.join(self.opts.line,"_")
219
220 if self.opts.mode=="separate":
221 name+="_%s_%04d" % (p[0].name,tIndex)
222 title="%s at t=%f" % (p[0].name,float(p[0].time()))
223 elif self.opts.mode=="timesInOne":
224 if self.opts.time!=None:
225 name+="_"+string.join(self.opts.time,"_")
226 name+="_%s" % p[0].name
227 title="%s" % p[0].name
228 elif self.opts.mode=="fieldsInOne":
229 if self.opts.field!=None:
230 name+="_"+string.join(self.opts.field,"_")
231 name+="_%04d" % tIndex
232 title="t=%f" % float(p[0].time())
233 elif self.opts.mode=="complete":
234 pass
235
236 name+=".png"
237 result+='set output "%s"\n' % name
238 if title!=None:
239 result+='set title "%s"\n' % title
240
241 result+="plot "
242 if self.opts.scaled:
243 if not self.opts.scaleAll:
244 vRange=vRanges[p[0].name]
245
246
247 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:
248 result+="[][%g:%g] " % vRange
249
250 first=True
251
252 for d in p:
253 if first:
254 first=False
255 else:
256 result+=", "
257
258 result+='"%s" using 1:%d ' % (d.file,d.index+1)
259
260 title=None
261 if self.opts.mode=="separate":
262 title=""
263 elif self.opts.mode=="timesInOne":
264 title="t=%f" % float(d.time())
265 elif self.opts.mode=="fieldsInOne":
266 title="%s" % d.name
267 elif self.opts.mode=="complete":
268 title="%s at t=%f" % (d.name,float(d.time()))
269
270 if len(self.opts.line)>1:
271 title+=" on %s" % d.line()
272
273 if title=="":
274 result+="notitle "
275 else:
276 result+='title "%s" ' % title
277
278 result+="with %s " % self.opts.style
279
280 result+="\n"
281
282 print result
283