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
14 import re
15
17 """Base class for all analyzers
18
19 Administrates and calls a number of LogLineAnlayzers for each
20 line"""
21
42
44 """Remove reference to self in children (hoping to remove
45 circular dependencies)"""
46
47 for a in list(self.analyzers.values()):
48 a.tearDown()
49 a.setParent(None)
50
52 """Collect dictionaries of collected data (current state)
53 from the analyzers
54 @return: the dictionary"""
55
56 result={}
57
58 for nm in self.analyzers:
59 data=self.analyzers[nm].getCurrentData()
60 if len(data)>0:
61 m=self.customExpr.match(nm)
62 if m:
63 if not "Custom" in result:
64 result["Custom"]={}
65 nr,name=m.groups()
66 result["Custom"][name]=data
67
68
69
70 result[nm]=data
71
72 return result
73
75 """Sets the time and alert all the LineAnalyzers that the time has changed
76 @param time: the new value of the time
77 """
78 if time!=self.time:
79 if self.progressOut:
80 self.progressOut.reset()
81
82 self.time=time
83 for listener in self.timeListeners:
84 listener.timeChanged()
85 for nm in self.analyzers:
86 self.analyzers[nm].timeChanged()
87 self.checkTriggers()
88
89 data=self.collectData()
90 for listener in self.timeListeners:
91 try:
92
93 listener.setDataSet(deepcopy(data))
94 except AttributeError:
95
96 pass
97
99 """Write a message to the progress output"""
100 if self.progressOut:
101 self.progressOut(msg)
102
104 """@param listener: An object that is notified when the time changes. Has to
105 implement a timeChanged method"""
106 if not 'timeChanged' in dir(listener):
107 error("Error. Object has no timeChanged-method:"+str(listener))
108 else:
109 self.timeListeners.append(listener)
110
112 """@returns: A list with the names of the Analyzers"""
113 return list(self.analyzers.keys())
114
116 """Is this LogLineAnalyzer name there"""
117 return name in self.analyzers
118
120 """Get the LogLineAnalyzer name"""
121 if name in self.analyzers:
122 return self.analyzers[name]
123 else:
124 return None
125
127 """Adds an analyzer
128
129 obj - A LogLineAnalyzer
130 name - the name of the analyzer"""
131
132 obj.setParent(self)
133 self.analyzers[name]=obj
134
136 """Calls all the anlyzers for a line"""
137 for nm in self.analyzers:
138 self.analyzers[nm].doAnalysis(line)
139
141 """Analyzes a file (one line at a time)
142
143 fh - handle of the file"""
144 while(self.line.read(fh)):
145 self.analyzeLine(self.line.line)
146
148 """Checks with all the analyzers
149
150 If one analyzer returns False it returns False"""
151 result=True
152
153 for nm in self.analyzers:
154
155 result=result and self.analyzers[nm].goOn()
156
157 return result
158
160 """Gets the current time"""
161 return str(self.time)
162
164 """Sets the output directory for all the analyzers"""
165 self.oDir=d
166 for nm in self.analyzers:
167 self.analyzers[nm].setDirectory(self.oDir)
168
170 """Gets the output directory"""
171 return self.oDir
172
173 - def addTrigger(self,time,func,once=True,until=None):
174 """Adds a trigger function that is to be called as soon as
175 the simulation time exceeds a certain value
176 @param time: the time at which the function should be triggered
177 @param func: the trigger function
178 @param once: Should this function be called once or at every time-step
179 @param until: The time until which the trigger should be called"""
180
181 data={}
182 data["time"]=float(time)
183 data["func"]=func
184 if until!=None:
185 data["until"]=float(until)
186 once=False
187 data["once"]=once
188
189 self.timeTriggers.append(data)
190
192 """Check for and execute the triggered functions"""
193
194 remove=[]
195 for i in range(len(self.timeTriggers)):
196 t=self.timeTriggers[i]
197 if t["time"]<=self.time:
198 t["func"]()
199 if t["once"]:
200 remove.append(i)
201 elif "until" in t:
202 if t["until"]<=self.time:
203 remove.append(i)
204
205 remove.reverse()
206
207 for i in remove:
208 self.timeTriggers.pop(i)
209
210
211