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
38
40 """Remove reference to self in children (hoping to remove
41 circular dependencies)"""
42
43 for a in list(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 list(self.analyzers.keys())
101
103 """Is this LogLineAnalyzer name there"""
104 return name in self.analyzers
105
107 """Get the LogLineAnalyzer name"""
108 if name in self.analyzers:
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
197
198