1
2 """Analyze OpenFOAM logs"""
3
4 from TimeLineAnalyzer import TimeLineAnalyzer
5 from PyFoam.Basics.LineReader import LineReader
6 from PyFoam.Error import error
7
8 from PyFoam.Basics.ProgressOutput import ProgressOutput
9
10 from sys import stdout
11
12 from copy import deepcopy
13
15 """Base class for all analyzers
16
17 Administrates and calls a number of LogLineAnlayzers for each
18 line"""
19
21 """
22 @param progress: Print time progress on console?
23 """
24 self.analyzers={}
25 self.time=""
26 self.oDir=""
27 self.line=LineReader()
28 self.timeListeners=[]
29 self.timeTriggers=[]
30
31 self.progressOut=None
32 if progress:
33 self.progressOut=ProgressOutput(stdout)
34
35 tm=TimeLineAnalyzer(progress=progress)
36 self.addAnalyzer("Time",tm)
37 tm.addListener(self.setTime)
38
40 """Remove reference to self in children (hoping to remove
41 circular dependencies)"""
42
43 for a in self.analyzers.values():
44 a.tearDown()
45 a.setParent(None)
46
48 """Collect dictionaries of collected data (current state)
49 from the analyzers
50 @return: the dictionary"""
51
52 result={}
53
54 for nm in self.analyzers:
55 data=self.analyzers[nm].getCurrentData()
56 if len(data)>0:
57 result[nm]=data
58
59 return result
60
62 """Sets the time and alert all the LineAnalyzers that the time has changed
63 @param time: the new value of the time
64 """
65 if time!=self.time:
66 if self.progressOut:
67 self.progressOut.reset()
68
69 self.time=time
70 for listener in self.timeListeners:
71 listener.timeChanged()
72 for nm in self.analyzers:
73 self.analyzers[nm].timeChanged()
74 self.checkTriggers()
75
76 data=self.collectData()
77 for listener in self.timeListeners:
78 try:
79
80 listener.setDataSet(deepcopy(data))
81 except AttributeError:
82
83 pass
84
86 """Write a message to the progress output"""
87 if self.progressOut:
88 self.progressOut(msg)
89
91 """@param listener: An object that is notified when the time changes. Has to
92 implement a timeChanged method"""
93 if not 'timeChanged' in dir(listener):
94 error("Error. Object has no timeChanged-method:"+str(listener))
95 else:
96 self.timeListeners.append(listener)
97
99 """@returns: A list with the names of the Analyzers"""
100 return self.analyzers.keys()
101
103 """Is this LogLineAnalyzer name there"""
104 return self.analyzers.has_key(name)
105
107 """Get the LogLineAnalyzer name"""
108 if self.analyzers.has_key(name):
109 return self.analyzers[name]
110 else:
111 return None
112
114 """Adds an analyzer
115
116 obj - A LogLineAnalyzer
117 name - the name of the analyzer"""
118
119 obj.setParent(self)
120 self.analyzers[name]=obj
121
123 """Calls all the anlyzers for a line"""
124 for nm in self.analyzers:
125 self.analyzers[nm].doAnalysis(line)
126
128 """Analyzes a file (one line at a time)
129
130 fh - handle of the file"""
131 while(self.line.read(fh)):
132 self.analyzeLine(self.line.line)
133
135 """Checks with all the analyzers
136
137 If one analyzer returns False it returns False"""
138 result=True
139
140 for nm in self.analyzers:
141
142 result=result and self.analyzers[nm].goOn()
143
144 return result
145
147 """Gets the current time"""
148 return str(self.time)
149
151 """Sets the output directory for all the analyzers"""
152 self.oDir=d
153 for nm in self.analyzers:
154 self.analyzers[nm].setDirectory(self.oDir)
155
157 """Gets the output directory"""
158 return self.oDir
159
160 - def addTrigger(self,time,func,once=True,until=None):
161 """Adds a trigger function that is to be called as soon as
162 the simulation time exceeds a certain value
163 @param time: the time at which the function should be triggered
164 @param func: the trigger function
165 @param once: Should this function be called once or at every time-step
166 @param until: The time until which the trigger should be called"""
167
168 data={}
169 data["time"]=float(time)
170 data["func"]=func
171 if until!=None:
172 data["until"]=float(until)
173 once=False
174 data["once"]=once
175
176 self.timeTriggers.append(data)
177
179 """Check for and execute the triggered functions"""
180
181 remove=[]
182 for i in range(len(self.timeTriggers)):
183 t=self.timeTriggers[i]
184 if t["time"]<=self.time:
185 t["func"]()
186 if t["once"]:
187 remove.append(i)
188 elif "until" in t:
189 if t["until"]<=self.time:
190 remove.append(i)
191
192 remove.reverse()
193
194 for i in remove:
195 self.timeTriggers.pop(i)
196