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