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 persist!=None:
219 custom.persist=persist
220 if start!=None:
221 custom.start=start
222 if end!=None:
223 custom.end=end
224 custom.raiseit=raiseit
225
226 if custom.type=="dynamic":
227 self.addAnalyzer(custom.name,
228 RegExpLineAnalyzer(custom.name.lower(),
229 custom.expr,
230 titles=custom.titles,
231 doTimelines=True,
232 doFiles=writeFiles,
233 accumulation=custom.accumulation,
234 singleFile=True,
235 idNr=custom.idNr,
236 startTime=custom.start,
237 endTime=custom.end))
238
239 else:
240 self.addAnalyzer(custom.name,
241 RegExpLineAnalyzer(custom.name.lower(),
242 custom.expr,
243 titles=custom.titles,
244 doTimelines=True,
245 doFiles=writeFiles,
246 accumulation=custom.accumulation,
247 singleFile=True,
248 startTime=custom.start,
249 endTime=custom.end))
250
251 if custom.master==None:
252 masters[custom.id]=custom
253 plotCustom=createPlotTimelines(self.getAnalyzer(custom.name).lines,
254 custom=custom,
255 implementation=plottingImplementation)
256 self.getAnalyzer(custom.name).lines.setSplitting(splitThres=splitThres,
257 advancedSplit=True)
258 plotCustom.setTitle(custom.theTitle)
259 plots["custom%04d" % i]=plotCustom
260 else:
261 slaves.append(custom)
262
263 for s in slaves:
264 if s.master not in masters:
265 error("The custom plot",s.id,"wants the master plot",s.master,"but it is not found in the list of masters",masters.keys())
266 else:
267 slave=self.getAnalyzer(s.name)
268 master=self.getAnalyzer(masters[s.master].name)
269 slave.setMaster(master)
270
271 self.reset()
272
273 return plots
274
276 """Writes the necessary information for the plots permanently to disc,
277 so that it doesn't have to be generated again
278 @param wait: wait for the lock to be allowed to pickle"""
279
280
281
282 lines=allLines()
283 plots=allPlots()
284 if lines and plots:
285 gotIt=self.pickleLock.acquire(wait)
286 if not gotIt:
287 return
288
289 pickleFile=path.join(self.logDir,"pickledPlots")
290 pick=pickle.Pickler(open(pickleFile+".tmp","w"))
291 pick.dump(lines.prepareForTransfer())
292 pick.dump(plots.prepareForTransfer())
293 move(pickleFile+".tmp",pickleFile)
294
295 self.pickleLock.release()
296