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