1
2 """Common stuff for classes that use analyzers"""
3
4 from os import path,mkdir
5 from shutil import move
6
7 from PyFoam.Basics.PlotTimelinesFactory import createPlotTimelines,createPlotTimelinesDirect
8 from PyFoam.Basics.TimeLineCollection import signedMax
9 from PyFoam.LogAnalysis.RegExpLineAnalyzer import RegExpLineAnalyzer
10
11 from PyFoam.Error import error
12
13
14 import cPickle as pickle
15 from PyFoam.Basics.GeneralPlotTimelines import allPlots
16 from PyFoam.Basics.TimeLineCollection import allLines
17
18 from threading import Lock
19
21 """This class collects information and methods that are needed for
22 handling analyzers"""
23
24 - def __init__(self,
25 filename,
26 analyzer,
27 doPickling=True):
28 """@param filename: name of the file that is being analyzed
29 @param analyzer: the analyzer itself
30 @param doPickling: write the pickled plot data"""
31
32 self.analyzer=analyzer
33
34 if 'dir' in dir(self):
35 self.logDir=path.join(self.dir,filename+".analyzed")
36 else:
37 self.logDir=filename+".analyzed"
38
39 if not path.exists(self.logDir):
40 mkdir(self.logDir)
41
42 self.doPickling=doPickling
43 if self.doPickling:
44 self.pickleLock=Lock()
45
46 self.reset()
47
49 self.analyzer.tearDown()
50 if hasattr(self,"data"):
51 pickleFile=path.join(self.logDir,"pickledData")
52 pick=pickle.Pickler(open(pickleFile,"w"))
53 pick.dump(self.data)
54
56 """@returns: A list with the names of the analyzers"""
57 return self.analyzer.listAnalyzers()
58
60 """@param name: name of the LineAnalyzer to get"""
61 return self.analyzer.getAnalyzer(name)
62
64 """@param name: name of the LineAnalyzer we ask for"""
65 return self.analyzer.hasAnalyzer(name)
66
68 """@param name: name of the LineAnalyzer to add
69 @param analyzer: the analyzer to add"""
70 analyzer.setDirectory(self.logDir)
71 return self.analyzer.addAnalyzer(name,analyzer)
72
74 """Not to be called: calls the analyzer for the current line"""
75 self.analyzer.analyzeLine(line)
76
78 """reset the analyzer"""
79 self.analyzer.setDirectory(self.logDir)
80
82 """Get the name of the directory where the data is written to"""
83 return self.logDir
84
86 """Get the execution time"""
87 return self.analyzer.getTime()
88
89 - def addTrigger(self,time,func,once=True,until=None):
90 """Adds a timed trigger to the Analyzer
91 @param time: the time at which the function should be triggered
92 @param func: the trigger function
93 @param once: Should this function be called once or at every time-step
94 @param until: The time until which the trigger should be called"""
95
96 self.analyzer.addTrigger(time,func,once=once,until=until)
97
98 - def createPlots(self,
99 persist=None,
100 raiseit=False,
101 splitThres=2048,
102 plotLinear=True,
103 plotCont=True,
104 plotBound=True,
105 plotIterations=True,
106 plotCourant=True,
107 plotExecution=True,
108 plotDeltaT=True,
109 start=None,
110 end=None,
111 writeFiles=False,
112 customRegexp=None,
113 plottingImplementation="dummy"):
114
115 plots={}
116
117 if plotLinear and self.hasAnalyzer("Linear"):
118 plots["linear"]=createPlotTimelinesDirect("linear",
119 self.getAnalyzer("Linear").lines,
120 persist=persist,
121 raiseit=raiseit,
122 forbidden=["final","iterations"],
123 start=start,
124 end=end,
125 logscale=True,
126 implementation=plottingImplementation)
127 self.getAnalyzer("Linear").lines.setSplitting(splitThres=splitThres,
128 splitFun=max,
129 advancedSplit=True)
130
131 plots["linear"].setTitle("Residuals")
132
133 if plotCont and self.hasAnalyzer("Continuity"):
134 plots["cont"]=createPlotTimelinesDirect("continuity",
135 self.getAnalyzer("Continuity").lines,
136 persist=persist,
137 alternateAxis=["Global"],
138 raiseit=raiseit,
139 start=start,
140 end=end,
141 implementation=plottingImplementation)
142 plots["cont"].setYLabel("Cumulative")
143 plots["cont"].setYLabel2("Global")
144 self.getAnalyzer("Continuity").lines.setSplitting(splitThres=splitThres,
145 advancedSplit=True)
146
147 plots["cont"].setTitle("Continuity")
148
149 if plotBound and self.hasAnalyzer("Bounding"):
150 plots["bound"]=createPlotTimelinesDirect("bounding",
151 self.getAnalyzer("Bounding").lines,
152 persist=persist,
153 raiseit=raiseit,
154 start=start,
155 end=end,
156 implementation=plottingImplementation)
157 self.getAnalyzer("Bounding").lines.setSplitting(splitThres=splitThres,
158 splitFun=signedMax,
159 advancedSplit=True)
160 plots["bound"].setTitle("Bounded variables")
161
162 if plotIterations and self.hasAnalyzer("Iterations"):
163 plots["iter"]=createPlotTimelinesDirect("iterations",
164 self.getAnalyzer("Iterations").lines,
165 persist=persist,
166 with_="steps",
167 raiseit=raiseit,
168 start=start,
169 end=end,
170 implementation=plottingImplementation)
171 self.getAnalyzer("Iterations").lines.setSplitting(splitThres=splitThres,
172 advancedSplit=True)
173
174 plots["iter"].setTitle("Iterations")
175
176 if plotCourant and self.hasAnalyzer("Courant"):
177 plots["courant"]=createPlotTimelinesDirect("courant",
178 self.getAnalyzer("Courant").lines,
179 persist=persist,
180 raiseit=raiseit,
181 start=start,
182 end=end,
183 implementation=plottingImplementation)
184 self.getAnalyzer("Courant").lines.setSplitting(splitThres=splitThres,
185 advancedSplit=True)
186
187 plots["courant"].setTitle("Courant")
188
189 if plotDeltaT and self.hasAnalyzer("DeltaT"):
190 plots["deltaT"]=createPlotTimelinesDirect("timestep",
191 self.getAnalyzer("DeltaT").lines,
192 persist=persist,
193 raiseit=raiseit,
194 start=start,
195 end=end,
196 logscale=True,
197 implementation=plottingImplementation)
198 self.getAnalyzer("DeltaT").lines.setSplitting(splitThres=splitThres,
199 advancedSplit=True)
200
201 plots["deltaT"].setTitle("DeltaT")
202
203 if plotExecution and self.hasAnalyzer("Execution"):
204 plots["execution"]=createPlotTimelinesDirect("execution",
205 self.getAnalyzer("Execution").lines,
206 persist=persist,
207 with_="steps",
208 raiseit=raiseit,
209 start=start,
210 end=end,
211 implementation=plottingImplementation)
212 self.getAnalyzer("Execution").lines.setSplitting(splitThres=splitThres,
213 advancedSplit=True)
214
215 plots["execution"].setTitle("Execution Time")
216
217 if customRegexp:
218 self.plotCustom=[]
219 masters={}
220 slaves=[]
221 for i,custom in enumerate(customRegexp):
222 if not custom.enabled:
223 continue
224
225 if persist!=None:
226 custom.persist=persist
227 if start!=None:
228 custom.start=start
229 if end!=None:
230 custom.end=end
231 custom.raiseit=raiseit
232
233 if custom.type=="dynamic":
234 self.addAnalyzer(custom.name,
235 RegExpLineAnalyzer(custom.name.lower(),
236 custom.expr,
237 titles=custom.titles,
238 doTimelines=True,
239 doFiles=writeFiles,
240 accumulation=custom.accumulation,
241 progressTemplate=custom.progress,
242 singleFile=True,
243 idNr=custom.idNr,
244 startTime=custom.start,
245 endTime=custom.end))
246
247 else:
248 self.addAnalyzer(custom.name,
249 RegExpLineAnalyzer(custom.name.lower(),
250 custom.expr,
251 titles=custom.titles,
252 doTimelines=True,
253 doFiles=writeFiles,
254 accumulation=custom.accumulation,
255 progressTemplate=custom.progress,
256 singleFile=True,
257 startTime=custom.start,
258 endTime=custom.end))
259
260 if custom.master==None:
261 masters[custom.id]=custom
262 plotCustom=createPlotTimelines(self.getAnalyzer(custom.name).lines,
263 custom=custom,
264 implementation=plottingImplementation)
265 self.getAnalyzer(custom.name).lines.setSplitting(splitThres=splitThres,
266 advancedSplit=True)
267 plotCustom.setTitle(custom.theTitle)
268 plots["custom%04d" % i]=plotCustom
269 else:
270 slaves.append(custom)
271
272 for s in slaves:
273 if s.master not in masters:
274 error("The custom plot",s.id,"wants the master plot",s.master,"but it is not found in the list of masters",masters.keys())
275 else:
276 slave=self.getAnalyzer(s.name)
277 master=self.getAnalyzer(masters[s.master].name)
278 slave.setMaster(master)
279
280 self.reset()
281
282 return plots
283
285 """Writes the necessary information for the plots permanently to disc,
286 so that it doesn't have to be generated again
287 @param wait: wait for the lock to be allowed to pickle"""
288
289
290
291 lines=allLines()
292 plots=allPlots()
293 if lines and plots:
294 gotIt=self.pickleLock.acquire(wait)
295 if not gotIt:
296 return
297
298 pickleFile=path.join(self.logDir,"pickledPlots")
299 pick=pickle.Pickler(open(pickleFile+".tmp","w"))
300 pick.dump(lines.prepareForTransfer())
301 pick.dump(plots.prepareForTransfer())
302 move(pickleFile+".tmp",pickleFile)
303
304 self.pickleLock.release()
305
307 if hasattr(self,"data"):
308 self.data["analyzed"]=data
309