Package PyFoam :: Package LogAnalysis :: Module FoamLogAnalyzer
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.LogAnalysis.FoamLogAnalyzer

  1  #  ICE Revision: $Id$ 
  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   
16 -class FoamLogAnalyzer(object):
17 """Base class for all analyzers 18 19 Administrates and calls a number of LogLineAnlayzers for each 20 line""" 21
22 - def __init__(self,progress=False):
23 """ 24 @param progress: Print time progress on console? 25 """ 26 self.analyzers={} 27 self.time="" 28 self.oDir="" 29 self.line=LineReader() 30 self.timeListeners=[] 31 self.timeTriggers=[] 32 33 self.customExpr=re.compile("Custom([0-9]+)_(.+)") 34 35 self.progressOut=None 36 if progress: 37 self.progressOut=ProgressOutput(stdout) 38 39 tm=TimeLineAnalyzer(progress=progress) 40 self.addAnalyzer("Time",tm) 41 tm.addListener(self.setTime)
42
43 - def tearDown(self):
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
51 - def collectData(self):
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 # this will store custom data twice. But we'll keep it 69 # for backward-compatibility 70 result[nm]=data 71 72 return result
73
74 - def setTime(self,time):
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 # make sure everyone gets a separate copy 93 listener.setDataSet(deepcopy(data)) 94 except AttributeError: 95 # seems that the listener doesn't want the data 96 pass
97
98 - def writeProgress(self,msg):
99 """Write a message to the progress output""" 100 if self.progressOut: 101 self.progressOut(msg)
102
103 - def addTimeListener(self,listener):
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
111 - def listAnalyzers(self):
112 """@returns: A list with the names of the Analyzers""" 113 return list(self.analyzers.keys())
114
115 - def hasAnalyzer(self,name):
116 """Is this LogLineAnalyzer name there""" 117 return name in self.analyzers
118
119 - def getAnalyzer(self,name):
120 """Get the LogLineAnalyzer name""" 121 if name in self.analyzers: 122 return self.analyzers[name] 123 else: 124 return None
125
126 - def addAnalyzer(self,name,obj):
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
135 - def analyzeLine(self,line):
136 """Calls all the anlyzers for a line""" 137 for nm in self.analyzers: 138 self.analyzers[nm].doAnalysis(line)
139
140 - def analyze(self,fh):
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
147 - def goOn(self):
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 # print nm,self.analyzers[nm].goOn() 155 result=result and self.analyzers[nm].goOn() 156 157 return result
158
159 - def getTime(self):
160 """Gets the current time""" 161 return str(self.time)
162
163 - def setDirectory(self,d):
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
169 - def getDirectory(self):
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
191 - def checkTriggers(self):
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 # Should work with Python3 and Python2 211