Example #1
0
    def purgeFile(self):
        """Undo all the manipulations done by PyFOAM

        Goes through the file and removes all lines that were added"""
        if not self.name:
            error("File-handle", str(self.fh), "can not be purged")

        rmExp = re.compile("^" + self.removedString + "(.*)$")
        addExp = re.compile("^(.*)" + self.addedString + "$")

        l = LineReader()
        self.openFile()

        (fh, fn) = self.makeTemp()

        while l.read(self.fh):
            toPrint = l.line

            m = addExp.match(l.line)
            if m != None:
                continue

            m = rmExp.match(l.line)
            if m != None:
                toPrint = m.group(1)

            self.writeEncoded(fh, toPrint + "\n")

        self.closeFile()
        fh.close()
        os.rename(fn, self.name)
    def replaceParameter(self,parameter,newval):
        """writes the value of a parameter

        :param parameter: name of the parameter
        :param newval: the new value
        :return: old value of the parameter"""
        
        oldVal=self.readParameter(parameter)
        
        exp=self.parameterPattern(parameter)

        l=LineReader()
        self.openFile()

        (fh,fn)=self.makeTemp()

        while l.read(self.fh):
            toPrint=l.line

            m=exp.match(l.line)
            if m!=None:
                if m.group(1).find(self.removedString)<0:
                    toPrint =self.removedString+l.line+"\n"
                    toPrint+=parameter+" "+str(newval)+"; "+self.addedString
            fh.write(toPrint+"\n")

        self.closeFile()
        fh.close()
        os.rename(fn,self.name)

        return oldVal
Example #3
0
    def __init__(self, progress=False):
        """
        :param progress: Print time progress on console?
        """
        self.analyzers = {}
        self.time = ""
        self.oDir = ""
        self.line = LineReader(config().getboolean("SolverOutput",
                                                   "stripSpaces"))
        self.timeListeners = []
        self.timeTriggers = []
        self.resetFileTriggers = []

        self.customExpr = re.compile("Custom([0-9]+)_(.+)")

        if progress:
            self.progressOut = ProgressOutput(stdout)
        else:
            self.progressOut = ProgressOutput()

        # tm=CountLineAnalyzer()
        tm = TimeLineAnalyzer()
        self.addAnalyzer("Time", tm)
        tm.addListener(self.setTime)

        self.analyzedLines = 0
Example #4
0
    def purgeFile(self):
        """Undo all the manipulations done by PyFOAM

        Goes through the file and removes all lines that were added"""
        rmExp= re.compile("^"+self.removedString+"(.*)$")
        addExp=re.compile("^(.*)"+self.addedString+"$")

        l=LineReader()
        self.openFile()

        (fh,fn)=self.makeTemp()

        while l.read(self.fh):
            toPrint=l.line

            m=addExp.match(l.line)
            if m!=None:
                continue

            m=rmExp.match(l.line)
            if m!=None:
                toPrint=m.group(1)

            self.writeEncoded(fh,toPrint+"\n")

        self.closeFile()
        fh.close()
        os.rename(fn,self.name)
Example #5
0
    def replaceParameter(self,parameter,newval):
        """writes the value of a parameter

        :param parameter: name of the parameter
        :param newval: the new value
        :return: old value of the parameter"""

        oldVal=self.readParameter(parameter)

        exp=self.parameterPattern(parameter)

        l=LineReader()
        self.openFile()

        (fh,fn)=self.makeTemp()

        while l.read(self.fh):
            toPrint=l.line

            m=exp.match(l.line)
            if m!=None:
                if m.group(1).find(self.removedString)<0:
                    toPrint =self.removedString+l.line+"\n"
                    toPrint+=parameter+" "+str(newval)+"; "+self.addedString
            fh.write(toPrint+"\n")

        self.closeFile()
        fh.close()
        os.rename(fn,self.name)

        return oldVal
Example #6
0
    def __init__(self,
                 filename,
                 silent=False,
                 tailLength=1000,
                 sleep=0.1,
                 follow=True):
        """:param filename: name of the logfile to watch
        :param silent: if True no output is sent to stdout
        :param tailLength: number of bytes at the end of the fail that should be output.
        :param follow: if the end of the file is reached wait for further input
        Because data is output on a per-line-basis
        :param sleep: interval to sleep if no line is returned"""

        self.filename = filename
        self.silent = silent
        self.tail = tailLength
        self.sleep = sleep
        self.follow = follow
        self.isTailing = False

        if not path.exists(self.filename):
            print_("Error: Logfile ", self.filename, "does not exist")

        self.reader = LineReader(config().getboolean("SolverOutput",
                                                     "stripSpaces"))
Example #7
0
    def refineMesh(self,factors,offset=(0,0,0)):
        """Refine the Mesh by multiplying the number of cells in the blocks
        @param factors: either a scalar to scale in all directions or a
        tuple with the value for each direction
        @param offset: an optional tuple for an additionnal offset value
        for each direction"""

        if type(factors)!=tuple:
            f=(factors,factors,factors)
        else:
            f=factors

        startPattern=re.compile("^\s*blocks")
        endPattern=re.compile("^\s\);")
        hexPattern=re.compile("^(\s*hex\s*\(.+\)\s+\(\s*)(\d+)\s+(\d+)\s+(\d+)(\s*\).*)$")

        inBlock=False

        l=LineReader()
        self.openFile()

        (fh,fn)=self.makeTemp()

        while l.read(self.fh):
            toPrint=l.line

            if not inBlock:
                if startPattern.match(l.line):
                    inBlock=True
            else:
                if endPattern.match(l.line):
                    inBlock=False
                else:
                    m=hexPattern.match(l.line)
                    if m!=None:
                        g=m.groups()
                        toPrint =self.removedString+l.line+"\n"
                        toPrint+="%s%d %d %d%s" % (
                            g[0],
                            int(g[1])*f[0]+offset[0],
                            int(g[2])*f[1]+offset[1],
                            int(g[3])*f[2]+offset[2],
                            g[4])
                        toPrint+=" "+self.addedString

            fh.write(toPrint+"\n")

        self.closeFile()
        fh.close()
        os.rename(fn,self.name)
Example #8
0
    def __init__(self,
                 filenames,
                 silent=False,
                 tailLength=1000,
                 sleep=0.1,
                 endTime=None,
                 follow=True):
        """:param filename: name of the logfile to watch
        :param silent: if True no output is sent to stdout
        :param tailLength: number of bytes at the end of the fail that should be output.
        :param follow: if the end of the file is reached wait for further input
        Because data is output on a per-line-basis
        :param sleep: interval to sleep if no line is returned"""

        if type(filenames) is list:
            meshTimes = []
            createMesh = "Create mesh for time = "
            for fName in filenames:
                meshTime = None
                with open(fName) as f:
                    for l in f.readlines()[:100]:
                        if l.find(createMesh) == 0:
                            meshTime = float(l[len(createMesh):])
                            break
                meshTimes.append((fName, meshTime))
            meshTimes.sort(key=lambda x: 1e50 if x[1] is None else x[1])
            filenames = [m[0] for m in meshTimes]
            self.filename = filenames[0]
            self.nextFiles = filenames[1:]
            self.changeTimes = [m[1] for m in meshTimes[1:]]
        else:
            self.filename = filenames
            self.nextFiles = []
            self.changeTimes = []

        self._changeFileHooks = []

        self.silent = silent
        self.tail = tailLength
        self.sleep = sleep
        self.follow = follow
        self.endTime = endTime
        self.isTailing = False

        if not path.exists(self.filename):
            print_("Error: Logfile ", self.filename, "does not exist")

        self.reader = LineReader(config().getboolean("SolverOutput",
                                                     "stripSpaces"))
Example #9
0
    def replaceBoundary(self,name,newval):
        """write the value at a boundary

        :param name: the name of the boundary patch
        :param newval: the new value"""
        exp=self.valuePattern()

        l=LineReader()
        self.openFile()

        fh,fn=self.makeTemp()

        self.goTo(l,"boundaryField",out=fh,echoLast=True)
        self.goTo(l,name,out=fh,echoLast=True)

        m=self.goMatch(l,exp,out=fh,stop=self.stopPattern())

        if m!=None:
            if type(m)==str:
                self.writeEncoded(fh,"value uniform "+str(newval)+"; "+self.addedString+"\n")
                self.writeEncoded(fh,l.line+"\n")
            else:
                self.writeEncoded(fh,self.removedString+l.line+"\n")
                self.writeEncoded(fh,"value uniform "+str(newval)+"; "+self.addedString+"\n")
        else:
            self.writeEncoded(fh,l.line+"\n")

        self.copyRest(l,fh)

        self.closeFile()
        fh.close()
        os.rename(fn,self.realName())
Example #10
0
    def readInternalUniform(self):
        """read the value of the internal field"""
        exp=self.internalPatternUniform()
        erg=""

        l=LineReader()
        self.openFile()

        while l.read(self.fh):
            m=exp.match(l.line)
            if m!=None:
                erg=m.group(1)
                break

        self.closeFile()
        return erg
Example #11
0
    def readDimension(self):
        """read the dimension of the field"""
        exp=self.dimensionPattern()
        erg=""

        l=LineReader()
        self.openFile()

        while l.read(self.fh):
            m=exp.match(l.line)
            if m!=None:
                erg=m.group(1)
                break

        self.closeFile()
        return erg
    def getSize(self):
        """:return: the size of the list"""

        size=-1 # should be long

        l=LineReader()
        self.openFile()

        while l.read(self.fh):
            try:
                size=long(l.line)
                break
            except ValueError:
                pass

        self.closeFile()

        return size
Example #13
0
    def getSize(self):
        """:return: the size of the list"""

        size = -1  # should be long

        l = LineReader()
        self.openFile()

        while l.read(self.fh):
            try:
                size = long(l.line)
                break
            except ValueError:
                pass

        self.closeFile()

        return size
    def __init__(self, cmdline, runner):
        """:param cmdline:cmdline - Command line of the OpenFOAM command
        :param runner: the Runner-object that started this thread"""
        Thread.__init__(self)
        self.cmdline = cmdline
        self.runner = runner
        self.output = None
        self.reader = LineReader(config().getboolean("SolverOutput",
                                                     "stripSpaces"))
        self.keyboardInterupted = False

        self.isLinux = False
        self.isDarwin = False
        self.isWindows = False
        self.threadPid = -1
        self.who = RUSAGE_CHILDREN

        if uname()[0] == "Linux":
            self.isLinux = True
            self.linuxMaxMem = 0
        elif uname()[0] == "Darwin":
            self.isDarwin = True
        elif uname()[0] == "Windows":
            self.isWindows = True

        self.resStart = None
        self.resEnd = None

        self.timeStart = None
        self.timeEnd = None

        self.timerTime = 5.

        self.stateLock = Lock()
        self.setState(False)

        self.status = None
        self.returncode = None

        self.lineLock = Lock()
        self.line = ""

        self.stateLock.acquire()
    def readParameter(self,parameter):
        """reads the value of a parameter

        parameter - name of the parameter"""
        exp=self.parameterPattern(parameter)
        
        l=LineReader()
        self.openFile()

        erg=""
        
        while l.read(self.fh):
            m=exp.match(l.line)
            if m!=None:
                if m.group(1).find(self.removedString)<0:
                    erg=m.group(2)
                    break

        self.closeFile()
        return erg
Example #16
0
    def __init__(self, progress=False):
        """
        @param progress: Print time progress on console?
        """
        self.analyzers = {}
        self.time = ""
        self.oDir = ""
        self.line = LineReader()
        self.timeListeners = []
        self.timeTriggers = []

        self.customExpr = re.compile("Custom([0-9]+)_(.+)")

        self.progressOut = None
        if progress:
            self.progressOut = ProgressOutput(stdout)

        tm = TimeLineAnalyzer(progress=progress)
        self.addAnalyzer("Time", tm)
        tm.addListener(self.setTime)
Example #17
0
    def readParameter(self, parameter):
        """reads the value of a parameter

        parameter - name of the parameter"""
        exp = self.parameterPattern(parameter)

        l = LineReader()
        self.openFile()

        erg = ""

        while l.read(self.fh):
            m = exp.match(l.line)
            if m != None:
                if m.group(1).find(self.removedString) < 0:
                    erg = m.group(2)
                    break

        self.closeFile()
        return erg
    def __init__(self,filenames,
                 silent=False,
                 tailLength=1000,
                 sleep=0.1,
                 follow=True):
        """:param filename: name of the logfile to watch
        :param silent: if True no output is sent to stdout
        :param tailLength: number of bytes at the end of the fail that should be output.
        :param follow: if the end of the file is reached wait for further input
        Because data is output on a per-line-basis
        :param sleep: interval to sleep if no line is returned"""

        if type(filenames) is list:
            meshTimes=[]
            createMesh="Create mesh for time = "
            for fName in filenames:
                meshTime=None
                with open(fName) as f:
                    for l in f.readlines()[:100]:
                        if l.find(createMesh)==0:
                            meshTime=float(l[len(createMesh):])
                            break
                meshTimes.append((fName,meshTime))
            meshTimes.sort(key=lambda x:1e50 if x[1] is None else x[1])
            filenames=[m[0] for m in meshTimes]
            self.filename=filenames[0]
            self.nextFiles=filenames[1:]
            self.changeTimes=[m[1] for m in meshTimes[1:]]
        else:
            self.filename=filenames
            self.nextFiles=[]
            self.changeTimes=[]

        self._changeFileHooks=[]

        self.silent=silent
        self.tail=tailLength
        self.sleep=sleep
        self.follow=follow
        self.isTailing=False

        if not path.exists(self.filename):
            print_("Error: Logfile ",self.filename,"does not exist")

        self.reader=LineReader(config().getboolean("SolverOutput","stripSpaces"))
Example #19
0
    def __init__(self,progress=False):
        """
        @param progress: Print time progress on console?
        """
        self.analyzers={}
        self.time=""
        self.oDir=""
        self.line=LineReader()
        self.timeListeners=[]
        self.timeTriggers=[]

        self.progressOut=None
        if progress:
            self.progressOut=ProgressOutput(stdout)
        
        tm=TimeLineAnalyzer(progress=progress)
        self.addAnalyzer("Time",tm)
        tm.addListener(self.setTime)
Example #20
0
    def readBoundary(self,name):
        """read the value at a boundary

        name - the name of the boundary patch"""
        exp=self.valuePattern()
        erg=""

        l=LineReader()
        self.openFile()

        self.goTo(l,"boundaryField")
        self.goTo(l,name)

        m=self.goMatch(l,exp)
        if m!=None:
            erg=m.group(1)

        self.closeFile()
        return erg
    def __init__(self,cmdline,runner):
        """:param cmdline:cmdline - Command line of the OpenFOAM command
        :param runner: the Runner-object that started this thread"""
        Thread.__init__(self)
        self.cmdline=cmdline
        self.runner=runner
        self.output=None
        self.reader=LineReader(config().getboolean("SolverOutput","stripSpaces"))
        self.keyboardInterupted=False

        self.isLinux=False
        self.isDarwin=False
        self.isWindows=False
        self.threadPid=-1
        self.who=RUSAGE_CHILDREN

        if uname()[0]=="Linux":
            self.isLinux=True
            self.linuxMaxMem=0
        elif uname()[0]=="Darwin":
            self.isDarwin=True
        elif uname()[0]=="Windows":
            self.isWindows=True

        self.resStart=None
        self.resEnd=None

        self.timeStart=None
        self.timeEnd=None

        self.timerTime=5.

        self.stateLock=Lock()
        self.setState(False)

        self.status=None
        self.returncode=None

        self.lineLock=Lock()
        self.line=""

        self.stateLock.acquire()
    def __init__(self,progress=False):
        """
        @param progress: Print time progress on console?
        """
        self.analyzers={}
        self.time=""
        self.oDir=""
        self.line=LineReader(config().getboolean("SolverOutput","stripSpaces"))
        self.timeListeners=[]
        self.timeTriggers=[]

        self.customExpr=re.compile("Custom([0-9]+)_(.+)")

        self.progressOut=None
        if progress:
            self.progressOut=ProgressOutput(stdout)

        tm=TimeLineAnalyzer(progress=progress)
        self.addAnalyzer("Time",tm)
        tm.addListener(self.setTime)
Example #23
0
    def __init__(self,cmdline,runner):
        """@param cmdline:cmdline - Command line of the OpenFOAM command
        @param runner: the Runner-object that started this thread"""
        Thread.__init__(self)
        self.cmdline=cmdline
        self.runner=runner
        self.output=None
        self.reader=LineReader()

        self.isLinux=False
        self.isDarwin=False
        self.threadPid=-1
        self.who=RUSAGE_CHILDREN
        
        if uname()[0]=="Linux":
            self.isLinux=True
            self.linuxMaxMem=0
        elif uname()[0]=="Darwin":
            self.isDarwin=True
            
        self.resStart=None
        self.resEnd=None

        self.timeStart=None
        self.timeEnd=None
        
        self.timerTime=5.
        
        self.stateLock=Lock()
        self.setState(False)

        self.status=None
        self.returncode=None
        
        self.lineLock=Lock()
        self.line=""

        self.stateLock.acquire()
Example #24
0
    def __init__(self,filename,
                 silent=False,
                 tailLength=1000,
                 sleep=0.1,
                 follow=True):
        """@param filename: name of the logfile to watch
        @param silent: if True no output is sent to stdout
        @param tailLength: number of bytes at the end of the fail that should be output.
        @param follow: if the end of the file is reached wait for further input
        Because data is output on a per-line-basis
        @param sleep: interval to sleep if no line is returned"""

        self.filename=filename
        self.silent=silent
        self.tail=tailLength
        self.sleep=sleep
        self.follow=follow
        self.isTailing=False

        if not path.exists(self.filename):
            print_("Error: Logfile ",self.filename,"does not exist")

        self.reader=LineReader()
Example #25
0
    def replaceInternal(self,newval):
        """overwrite the value of the internal field

        newval - the new value"""
        exp=self.internalPatternGeneral()

        l=LineReader()
        self.openFile()

        fh,fn=self.makeTemp()

        m=self.goMatch(l,exp,out=fh)

        if m!=None:
            self.writeEncoded(fh,self.removedString+l.line+"\n")
            self.writeEncoded(fh,"internalField uniform "+str(newval)+"; "+self.addedString+"\n")
        else:
            self.writeEncoded(fh,l.line+"\n")

        self.copyRest(l,fh)

        self.closeFile()
        fh.close()
        os.rename(fn,self.realName())
Example #26
0
class FoamThread(Thread):
    """Thread running an OpenFOAM command

    The output of the command can be accessed in a thread-safe manner,
    line by line

    Designed to be used by the BasicRunner-class"""
    
    def __init__(self,cmdline,runner):
        """@param cmdline:cmdline - Command line of the OpenFOAM command
        @param runner: the Runner-object that started this thread"""
        Thread.__init__(self)
        self.cmdline=cmdline
        self.runner=runner
        self.output=None
        self.reader=LineReader()

        self.isLinux=False
        self.isDarwin=False
        self.threadPid=-1
        self.who=RUSAGE_CHILDREN
        
        if uname()[0]=="Linux":
            self.isLinux=True
            self.linuxMaxMem=0
        elif uname()[0]=="Darwin":
            self.isDarwin=True
            
        self.resStart=None
        self.resEnd=None

        self.timeStart=None
        self.timeEnd=None
        
        self.timerTime=5.
        
        self.stateLock=Lock()
        self.setState(False)

        self.status=None
        self.returncode=None
        
        self.lineLock=Lock()
        self.line=""

        self.stateLock.acquire()

    def run(self):
        """start the command"""
        # print "Starting ",self.cmdline
        self.resStart=getrusage(self.who)
        self.timeStart=time()

        if sys.version_info<(2,4):
            run=Popen4(self.cmdline)
            self.output=run.fromchild
        else:
            run=subprocess.Popen(self.cmdline,shell=True,bufsize=0,
                      stdin=subprocess.PIPE,stdout=subprocess.PIPE,
                      stderr=subprocess.STDOUT,close_fds=True)
            self.output=run.stdout
        self.run=run
        self.threadPid=run.pid
        foamLogger().info("Started with PID %d" % self.threadPid)
        if self.isLinux:
            #            print "Starting Timer"
            self.timer=Timer(0.1*self.timerTime,getLinuxMem,args=[self])
            self.timer.start()

        #            print "Starting Timer"
        self.timer2=Timer(0.5*self.timerTime,checkForStopFile,args=[self])
        self.timer2.start()
            
        self.hasSomethingToSay=True
        self.stateLock.release()

        try:
            # print "Waiting",time()
            self.status=run.wait()
            # Python 2.3 on Mac OS X never seems to reach this point
            # print "After wait",time()
            # print "Status:",self.status

            # to give a chance to read the remaining output
            if self.hasSomethingToSay:
                sleep(2.)
            while self.reader.read(self.output):
                print "Unused output:",self.reader.line
        except OSError,e:
            print "Exeption caught:",e

        self.stopTimer()
        
        self.threadPid=-1

        self.resEnd=getrusage(self.who)
        self.timeEnd=time()
        #        print "End:",self.timeEnd
        # print "Returned",self.status

        self.getReturnCode()
Example #27
0
class BasicWatcher(object):
    """Base class for watching the output of commands

    Works like the UNIX-command 'tail -f <file>': the last lines of the file are output.
    If the file grows then these lines are output as they arrive"""

    def __init__(self,filename,
                 silent=False,
                 tailLength=1000,
                 sleep=0.1,
                 follow=True):
        """@param filename: name of the logfile to watch
        @param silent: if True no output is sent to stdout
        @param tailLength: number of bytes at the end of the fail that should be output.
        @param follow: if the end of the file is reached wait for further input
        Because data is output on a per-line-basis
        @param sleep: interval to sleep if no line is returned"""

        self.filename=filename
        self.silent=silent
        self.tail=tailLength
        self.sleep=sleep
        self.follow=follow
        self.isTailing=False

        if not path.exists(self.filename):
            print_("Error: Logfile ",self.filename,"does not exist")

        self.reader=LineReader()

    def getSize(self):
        """@return: the current size (in bytes) of the file"""
        return os.stat(self.filename)[stat.ST_SIZE]

    def start(self):
        """Reads the file and does the processing"""

        currSize=self.getSize()

        fn,ext=path.splitext(self.filename)
        if ext=='.gz':
            fh=gzip.open(self.filename)
        else:
            fh=open(self.filename)

        self.startHandle()

        while self.follow or currSize>self.reader.bytesRead():
            try:
                status=self.reader.read(fh)
                if status:
                    line=self.reader.line
                    if (currSize-self.reader.bytesRead())<=self.tail:
                        if not self.isTailing:
                            self.isTailing=True
                            self.timeHandle()
                            self.tailingHandle()

                        if not self.silent:
                            print_(line)

                    self.lineHandle(line)
                else:
                    if self.reader.userSaidStop():
                        break
                    sleep(self.sleep)
            except KeyboardInterrupt:
                print_("Watcher: Keyboard interrupt")
                break

        self.stopHandle()

        fh.close()

    def startHandle(self):
        """to be called before the program is started"""
        pass

    def stopHandle(self):
        """called after the program has stopped"""
        pass

    def tailingHandle(self):
        """called when the first line is output"""
        pass

    def lineHandle(self,line):
        """called every time a new line is read"""
        pass
Example #28
0
class FoamLogAnalyzer(object):
    """Base class for all analyzers

    Administrates and calls a number of LogLineAnlayzers for each
    line"""
    def __init__(self, progress=False):
        """
        :param progress: Print time progress on console?
        """
        self.analyzers = {}
        self.time = ""
        self.oDir = ""
        self.line = LineReader(config().getboolean("SolverOutput",
                                                   "stripSpaces"))
        self.timeListeners = []
        self.timeTriggers = []
        self.resetFileTriggers = []

        self.customExpr = re.compile("Custom([0-9]+)_(.+)")

        if progress:
            self.progressOut = ProgressOutput(stdout)
        else:
            self.progressOut = ProgressOutput()

        # tm=CountLineAnalyzer()
        tm = TimeLineAnalyzer()
        self.addAnalyzer("Time", tm)
        tm.addListener(self.setTime)

        self.analyzedLines = 0

    def tearDown(self):
        """Remove reference to self in children (hoping to remove
        circular dependencies)"""

        for a in list(self.analyzers.values()):
            a.tearDown()
            a.setParent(None)

    def collectData(self, structured=False):
        """Collect dictionaries of collected data (current state)
        from the analyzers
        :return: the dictionary"""

        result = {}

        for nm in self.analyzers:
            data = self.analyzers[nm].getCurrentData(structured=structured)
            if len(data) > 0:
                m = self.customExpr.match(nm)
                if m:
                    if not "Custom" in result:
                        result["Custom"] = {}
                    nr, name = m.groups()
                    result["Custom"][name] = data

                # this will store custom data twice. But we'll keep it
                # for backward-compatibility
                result[nm] = data

        return result

    def summarizeData(self, col=80):
        """Get a summary of the data"""
        result = "=" * col
        result += "\nt = {:20}\n".format(self.getTime())

        data = self.collectData(structured=True)

        for k, v in iteritems(data):
            if k.find("Custom") == 0 and len(k) > 9 and k[8] == "_":
                kk = k[9:]
            elif k in ["Custom"]:
                continue
            else:
                kk = k

            if isinstance(v, (dict, )):
                result += kk + " " + "-" * (col - len(kk) - 1) + "\n"
                isDicts = True
                for k1, v1 in iteritems(v):
                    if not isinstance(v1, (dict, )):
                        isDicts = False
                        break
                if not isDicts:
                    maxLen = max([len(k1) for k1 in v.keys()])
                    wFormat = "{:%d} : {:8g}" % maxLen
                    chunks = [
                        wFormat.format(k1, v[k1]) for k1 in sorted(v.keys())
                    ]
                    maxLen = max([len(c) for c in chunks])
                    chunks = [
                        c if len(c) >= maxLen else c + " " * (maxLen - len(c))
                        for c in chunks
                    ]
                    nrChunks = col // (max([len(e) for e in chunks]) + 3)
                    for i in range(0, len(chunks), nrChunks):
                        result += " | ".join(chunks[i:(i + nrChunks)]) + "\n"
                else:
                    maxLen = 0

                    for k1, v1 in iteritems(v):
                        maxLen = max(
                            maxLen,
                            max([len(k1) + 2 - 8] +
                                [len(k2) for k2 in v1.keys()]))

                    wFormat = "{:%d} : {:8g}" % maxLen
                    chunks = {}
                    chunkLen = 0
                    for k1, v1 in iteritems(v):
                        chunks[k1] = [
                            wFormat.format(k2, v1[k2])
                            for k2 in sorted(v1.keys())
                        ]
                        chunkLen = max(chunkLen,
                                       max([len(e) for e in chunks[k1]]))

                    for k1 in sorted(v.keys()):
                        chunks[k1] = [
                            k1 + " " + "_" * (chunkLen - len(k1) - 1)
                        ] + chunks[k1]
                        chunks[k1] = [
                            c if len(c) >= chunkLen else c + " " *
                            (chunkLen - len(c)) for c in chunks[k1]
                        ]
                        nrChunks = col // (chunkLen + 3)
                        for i in range(0, len(chunks[k1]), nrChunks):
                            result += " | ".join(
                                chunks[k1][i:(i + nrChunks)]) + "\n"
            else:
                result += kk + ": " + v + " " + "-" * (col - len(k) - len(v) -
                                                       3) + "\n"
        return result

    def setTime(self, time):
        """Sets the time and alert all the LineAnalyzers that the time has changed
        :param time: the new value of the time
        """
        if time != self.time:
            self.progressOut.reset()

            self.time = time
            for listener in self.timeListeners:
                listener.timeChanged()
            for nm in self.analyzers:
                self.analyzers[nm].timeChanged()
            self.checkTriggers()

            data = self.collectData()
            for listener in self.timeListeners:
                try:
                    # make sure everyone gets a separate copy
                    listener.setDataSet(deepcopy(data))
                except AttributeError:
                    # seems that the listener doesn't want the data
                    pass

    def resetFile(self):
        """Propagate a reset to the actual analyzers"""
        for nm in self.analyzers:
            self.analyzers[nm].resetFile()

        for f in self.resetFileTriggers:
            f()

    def writeProgress(self, msg):
        """Write a message to the progress output"""
        self.progressOut(msg)

    def addTimeListener(self, listener):
        """:param listener: An object that is notified when the time changes. Has to
        implement a timeChanged method"""
        if not 'timeChanged' in dir(listener):
            error("Error. Object has no timeChanged-method:" + str(listener))
        else:
            self.timeListeners.append(listener)

    def addResetFileTrigger(self, f):
        self.resetFileTriggers.append(f)

    def listAnalyzers(self):
        """:returns: A list with the names of the Analyzers"""
        return list(self.analyzers.keys())

    def hasAnalyzer(self, name):
        """Is this LogLineAnalyzer name there"""
        return name in self.analyzers

    def getAnalyzer(self, name):
        """Get the LogLineAnalyzer name"""
        if name in self.analyzers:
            return self.analyzers[name]
        else:
            return None

    def addAnalyzer(self, name, obj):
        """Adds an analyzer

        obj - A LogLineAnalyzer
        name - the name of the analyzer"""

        obj.setParent(self)
        self.analyzers[name] = obj

    def analyzeLine(self, line):
        """Calls all the anlyzers for a line"""
        self.analyzedLines += 1

        for nm in self.analyzers:
            self.analyzers[nm].doAnalysis(line)

    def analyze(self, fh):
        """Analyzes a file (one line at a time)

        fh - handle of the file"""
        while (self.line.read(fh)):
            self.analyzeLine(self.line.line)

    def goOn(self):
        """Checks with all the analyzers

        If one analyzer returns False it returns False"""
        result = True

        for nm in self.analyzers:
            #            print nm,self.analyzers[nm].goOn()
            result = result and self.analyzers[nm].goOn()

        return result

    def getTime(self):
        """Gets the current time"""
        return str(self.time)

    def isPastTime(self, check):
        """Are we past a given Time?"""
        if check is None:
            return False
        try:
            t = float(self.getTime())
            return t > check
        except ValueError:
            return False

    def setDirectory(self, d):
        """Sets the output directory for all the analyzers"""
        self.oDir = d
        for nm in self.analyzers:
            self.analyzers[nm].setDirectory(self.oDir)

    def getDirectory(self):
        """Gets the output directory"""
        return self.oDir

    def addTrigger(self, time, func, once=True, until=None):
        """Adds a trigger function that is to be called as soon as
        the simulation time exceeds a certain value
        :param time: the time at which the function should be triggered
        :param func: the trigger function
        :param once: Should this function be called once or at every time-step
        :param until: The time until which the trigger should be called"""

        data = {}
        data["time"] = float(time)
        data["func"] = func
        if until != None:
            data["until"] = float(until)
            once = False
        data["once"] = once

        self.timeTriggers.append(data)

    def checkTriggers(self):
        """Check for and execute the triggered functions"""

        remove = []
        for i in range(len(self.timeTriggers)):
            t = self.timeTriggers[i]
            if t["time"] <= self.time:
                t["func"]()
                if t["once"]:
                    remove.append(i)
                elif "until" in t:
                    if t["until"] <= self.time:
                        remove.append(i)

        remove.reverse()

        for i in remove:
            self.timeTriggers.pop(i)
Example #29
0
class FoamLogAnalyzer(object):
    """Base class for all analyzers

    Administrates and calls a number of LogLineAnlayzers for each
    line"""

    def __init__(self,progress=False):
        """
        @param progress: Print time progress on console?
        """
        self.analyzers={}
        self.time=""
        self.oDir=""
        self.line=LineReader()
        self.timeListeners=[]
        self.timeTriggers=[]

        self.customExpr=re.compile("Custom([0-9]+)_(.+)")

        self.progressOut=None
        if progress:
            self.progressOut=ProgressOutput(stdout)

        tm=TimeLineAnalyzer(progress=progress)
        self.addAnalyzer("Time",tm)
        tm.addListener(self.setTime)

    def tearDown(self):
        """Remove reference to self in children (hoping to remove
        circular dependencies)"""

        for a in list(self.analyzers.values()):
            a.tearDown()
            a.setParent(None)

    def collectData(self):
        """Collect dictionaries of collected data (current state)
        from the analyzers
        @return: the dictionary"""

        result={}

        for nm in self.analyzers:
            data=self.analyzers[nm].getCurrentData()
            if len(data)>0:
                m=self.customExpr.match(nm)
                if m:
                    if not "Custom" in result:
                        result["Custom"]={}
                    nr,name=m.groups()
                    result["Custom"][name]=data

                # this will store custom data twice. But we'll keep it
                    # for backward-compatibility
                result[nm]=data

        return result

    def setTime(self,time):
        """Sets the time and alert all the LineAnalyzers that the time has changed
        @param time: the new value of the time
        """
        if time!=self.time:
            if self.progressOut:
                self.progressOut.reset()

            self.time=time
            for listener in self.timeListeners:
                listener.timeChanged()
            for nm in self.analyzers:
                self.analyzers[nm].timeChanged()
            self.checkTriggers()

            data=self.collectData()
            for listener in self.timeListeners:
                try:
                    # make sure everyone gets a separate copy
                    listener.setDataSet(deepcopy(data))
                except AttributeError:
                    # seems that the listener doesn't want the data
                    pass

    def writeProgress(self,msg):
        """Write a message to the progress output"""
        if self.progressOut:
            self.progressOut(msg)

    def addTimeListener(self,listener):
        """@param listener: An object that is notified when the time changes. Has to
        implement a timeChanged method"""
        if not 'timeChanged' in dir(listener):
            error("Error. Object has no timeChanged-method:"+str(listener))
        else:
            self.timeListeners.append(listener)

    def listAnalyzers(self):
        """@returns: A list with the names of the Analyzers"""
        return list(self.analyzers.keys())

    def hasAnalyzer(self,name):
        """Is this LogLineAnalyzer name there"""
        return name in self.analyzers

    def getAnalyzer(self,name):
        """Get the LogLineAnalyzer name"""
        if name in self.analyzers:
            return self.analyzers[name]
        else:
            return None

    def addAnalyzer(self,name,obj):
        """Adds an analyzer

        obj - A LogLineAnalyzer
        name - the name of the analyzer"""

        obj.setParent(self)
        self.analyzers[name]=obj

    def analyzeLine(self,line):
        """Calls all the anlyzers for a line"""
        for nm in self.analyzers:
            self.analyzers[nm].doAnalysis(line)

    def analyze(self,fh):
        """Analyzes a file (one line at a time)

        fh - handle of the file"""
        while(self.line.read(fh)):
            self.analyzeLine(self.line.line)

    def goOn(self):
        """Checks with all the analyzers

        If one analyzer returns False it returns False"""
        result=True

        for nm in self.analyzers:
            #            print nm,self.analyzers[nm].goOn()
            result=result and self.analyzers[nm].goOn()

        return result

    def getTime(self):
        """Gets the current time"""
        return str(self.time)

    def setDirectory(self,d):
        """Sets the output directory for all the analyzers"""
        self.oDir=d
        for nm in self.analyzers:
            self.analyzers[nm].setDirectory(self.oDir)

    def getDirectory(self):
        """Gets the output directory"""
        return self.oDir

    def addTrigger(self,time,func,once=True,until=None):
        """Adds a trigger function that is to be called as soon as
        the simulation time exceeds a certain value
        @param time: the time at which the function should be triggered
        @param func: the trigger function
        @param once: Should this function be called once or at every time-step
        @param until: The time until which the trigger should be called"""

        data={}
        data["time"]=float(time)
        data["func"]=func
        if until!=None:
            data["until"]=float(until)
            once=False
        data["once"]=once

        self.timeTriggers.append(data)

    def checkTriggers(self):
        """Check for and execute the triggered functions"""

        remove=[]
        for i in range(len(self.timeTriggers)):
            t=self.timeTriggers[i]
            if t["time"]<=self.time:
                t["func"]()
                if t["once"]:
                    remove.append(i)
                elif "until" in t:
                    if t["until"]<=self.time:
                        remove.append(i)

        remove.reverse()

        for i in remove:
            self.timeTriggers.pop(i)
Example #30
0
class FoamLogAnalyzer(object):
    """Base class for all analyzers

    Administrates and calls a number of LogLineAnlayzers for each
    line"""
    def __init__(self, progress=False):
        """
        @param progress: Print time progress on console?
        """
        self.analyzers = {}
        self.time = ""
        self.oDir = ""
        self.line = LineReader()
        self.timeListeners = []
        self.timeTriggers = []

        self.customExpr = re.compile("Custom([0-9]+)_(.+)")

        self.progressOut = None
        if progress:
            self.progressOut = ProgressOutput(stdout)

        tm = TimeLineAnalyzer(progress=progress)
        self.addAnalyzer("Time", tm)
        tm.addListener(self.setTime)

    def tearDown(self):
        """Remove reference to self in children (hoping to remove
        circular dependencies)"""

        for a in list(self.analyzers.values()):
            a.tearDown()
            a.setParent(None)

    def collectData(self):
        """Collect dictionaries of collected data (current state)
        from the analyzers
        @return: the dictionary"""

        result = {}

        for nm in self.analyzers:
            data = self.analyzers[nm].getCurrentData()
            if len(data) > 0:
                m = self.customExpr.match(nm)
                if m:
                    if not "Custom" in result:
                        result["Custom"] = {}
                    nr, name = m.groups()
                    result["Custom"][name] = data

                # this will store custom data twice. But we'll keep it
                # for backward-compatibility
                result[nm] = data

        return result

    def setTime(self, time):
        """Sets the time and alert all the LineAnalyzers that the time has changed
        @param time: the new value of the time
        """
        if time != self.time:
            if self.progressOut:
                self.progressOut.reset()

            self.time = time
            for listener in self.timeListeners:
                listener.timeChanged()
            for nm in self.analyzers:
                self.analyzers[nm].timeChanged()
            self.checkTriggers()

            data = self.collectData()
            for listener in self.timeListeners:
                try:
                    # make sure everyone gets a separate copy
                    listener.setDataSet(deepcopy(data))
                except AttributeError:
                    # seems that the listener doesn't want the data
                    pass

    def writeProgress(self, msg):
        """Write a message to the progress output"""
        if self.progressOut:
            self.progressOut(msg)

    def addTimeListener(self, listener):
        """@param listener: An object that is notified when the time changes. Has to
        implement a timeChanged method"""
        if not 'timeChanged' in dir(listener):
            error("Error. Object has no timeChanged-method:" + str(listener))
        else:
            self.timeListeners.append(listener)

    def listAnalyzers(self):
        """@returns: A list with the names of the Analyzers"""
        return list(self.analyzers.keys())

    def hasAnalyzer(self, name):
        """Is this LogLineAnalyzer name there"""
        return name in self.analyzers

    def getAnalyzer(self, name):
        """Get the LogLineAnalyzer name"""
        if name in self.analyzers:
            return self.analyzers[name]
        else:
            return None

    def addAnalyzer(self, name, obj):
        """Adds an analyzer

        obj - A LogLineAnalyzer
        name - the name of the analyzer"""

        obj.setParent(self)
        self.analyzers[name] = obj

    def analyzeLine(self, line):
        """Calls all the anlyzers for a line"""
        for nm in self.analyzers:
            self.analyzers[nm].doAnalysis(line)

    def analyze(self, fh):
        """Analyzes a file (one line at a time)

        fh - handle of the file"""
        while (self.line.read(fh)):
            self.analyzeLine(self.line.line)

    def goOn(self):
        """Checks with all the analyzers

        If one analyzer returns False it returns False"""
        result = True

        for nm in self.analyzers:
            #            print nm,self.analyzers[nm].goOn()
            result = result and self.analyzers[nm].goOn()

        return result

    def getTime(self):
        """Gets the current time"""
        return str(self.time)

    def setDirectory(self, d):
        """Sets the output directory for all the analyzers"""
        self.oDir = d
        for nm in self.analyzers:
            self.analyzers[nm].setDirectory(self.oDir)

    def getDirectory(self):
        """Gets the output directory"""
        return self.oDir

    def addTrigger(self, time, func, once=True, until=None):
        """Adds a trigger function that is to be called as soon as
        the simulation time exceeds a certain value
        @param time: the time at which the function should be triggered
        @param func: the trigger function
        @param once: Should this function be called once or at every time-step
        @param until: The time until which the trigger should be called"""

        data = {}
        data["time"] = float(time)
        data["func"] = func
        if until != None:
            data["until"] = float(until)
            once = False
        data["once"] = once

        self.timeTriggers.append(data)

    def checkTriggers(self):
        """Check for and execute the triggered functions"""

        remove = []
        for i in range(len(self.timeTriggers)):
            t = self.timeTriggers[i]
            if t["time"] <= self.time:
                t["func"]()
                if t["once"]:
                    remove.append(i)
                elif "until" in t:
                    if t["until"] <= self.time:
                        remove.append(i)

        remove.reverse()

        for i in remove:
            self.timeTriggers.pop(i)
class FoamThread(Thread):
    """Thread running an OpenFOAM command

    The output of the command can be accessed in a thread-safe manner,
    line by line

    Designed to be used by the BasicRunner-class"""

    def __init__(self,cmdline,runner):
        """:param cmdline:cmdline - Command line of the OpenFOAM command
        :param runner: the Runner-object that started this thread"""
        Thread.__init__(self)
        self.cmdline=cmdline
        self.runner=runner
        self.output=None
        self.reader=LineReader(config().getboolean("SolverOutput","stripSpaces"))
        self.keyboardInterupted=False

        self.isLinux=False
        self.isDarwin=False
        self.isWindows=False
        self.threadPid=-1
        self.who=RUSAGE_CHILDREN

        if uname()[0]=="Linux":
            self.isLinux=True
            self.linuxMaxMem=0
        elif uname()[0]=="Darwin":
            self.isDarwin=True
        elif uname()[0]=="Windows":
            self.isWindows=True

        self.resStart=None
        self.resEnd=None

        self.timeStart=None
        self.timeEnd=None

        self.timerTime=5.

        self.stateLock=Lock()
        self.setState(False)

        self.status=None
        self.returncode=None

        self.lineLock=Lock()
        self.line=""

        self.stateLock.acquire()

    def run(self):
        """start the command"""
        # print "Starting ",self.cmdline
        self.resStart=getrusage(self.who)
        self.timeStart=time()

        if sys.version_info<(2,4):
            run=Popen4(self.cmdline)
            self.output=run.fromchild
        else:
            run=subprocess.Popen(shellExecutionPrefix()+self.cmdline,
                                 shell=True,
                                 bufsize=0,
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT,
                                 close_fds=True)
            self.output=run.stdout
        self.run=run
        self.threadPid=run.pid
        foamLogger().info("Started with PID %d" % self.threadPid)
        if self.isLinux:
            #            print "Starting Timer"
            self.timer=Timer(0.1*self.timerTime,getLinuxMem,args=[self])
            self.timer.start()

        #            print "Starting Timer"
        self.timer2=Timer(0.5*self.timerTime,checkForStopFile,args=[self])
        self.timer2.start()

        self.hasSomethingToSay=True
        self.stateLock.release()

        try:
            # print "Waiting",time()
            self.status=run.wait()
            # Python 2.3 on Mac OS X never seems to reach this point
            # print "After wait",time()
            # print "Status:",self.status

            # to give a chance to read the remaining output
            if self.hasSomethingToSay:
                sleep(2.)
            while self.reader.read(self.output):
                print_("Unused output:",self.reader.line)
        except OSError:
            e = sys.exc_info()[1] # compatible with 2.x and 3.x
            print_("Exeption caught:",e)

        self.stopTimer()

        self.threadPid=-1

        self.resEnd=getrusage(self.who)
        self.timeEnd=time()
        #        print "End:",self.timeEnd
        # print "Returned",self.status

        self.getReturnCode()

    def getReturnCode(self):
        if sys.version_info<(2,4):
            # Don't know how to get the returncode from a Popen4-object
            self.returncode=0
        else:
            self.returncode=self.run.returncode
        return self.returncode

    def stopTimer(self):
        if self.isLinux:
            self.timer.cancel()
        self.timer2.cancel()

    def read(self):
        """read another line from the output"""
        self.setState(self.reader.read(self.output))
        self.lineLock.acquire()
        self.line=self.reader.line
        self.lineLock.release()

    def getLine(self):
        """gets the last line from the output"""
        self.lineLock.acquire()
        val=self.line
        self.lineLock.release()

        return val

    def interrupt(self):
        """A keyboard-interrupt is reported"""
        self.reader.wasInterupted=True
        self.setState(False)

    def setState(self,state):
        """sets the state of the thread (is there any more output)"""
        self.stateLock.acquire()
        self.hasSomethingToSay=state
        if not self.hasSomethingToSay and self.timeStart and self.reader.wasInterupted:
            self.keyboardInterupted=self.reader.keyboardInterupted

            if self.threadPid>0:
                msg="Killing PID %d" % self.threadPid
                print_(msg)
                foamLogger().warning(msg)
                try:
                    kill(self.threadPid,signal.SIGKILL)
                except OSError:
                    warning("Process",self.threadPid,"was already dead")

        #        print "Set: ",state
        self.stateLock.release()

    def check(self):
        """:return: False if there is no more output of the command"""
        self.stateLock.acquire()
        state=self.hasSomethingToSay
        #        print "Get: ",state
        self.stateLock.release()

        return state

    def cpuTime(self):
        """:return: number of seconds CPU-Time used"""
        return self.cpuUserTime()+self.cpuSystemTime()

    def cpuUserTime(self):
        """:return: number of seconds CPU-Time used in user mode"""
        if self.resEnd==None: # and self.isDarwin:
            # Mac OS X needs this (Ubuntu too?)
            self.resEnd=getrusage(self.who)
        if self.resStart==None or self.resEnd==None:
            return 0
        else:
            return self.resEnd.ru_utime-self.resStart.ru_utime

    def cpuSystemTime(self):
        """:return: number of seconds CPU-Time used in system mode"""
        if self.resEnd==None: #  and self.isDarwin:
            # Mac OS X needs this (Ubuntu too?)
            self.resEnd=getrusage(self.who)
        if self.resStart==None or self.resEnd==None:
            return 0
        else:
            return self.resEnd.ru_stime-self.resStart.ru_stime

    def usedMemory(self):
        """:return: maximum resident set size in MegaByte"""
        scale=1024.*1024.
        if self.isLinux:
            return self.linuxMaxMem/scale

        if self.resStart==None or self.resEnd==None:
            return 0.
        else:
            return getpagesize()*(self.resEnd.ru_maxrss-self.resStart.ru_maxrss)/scale

    def wallTime(self):
        """:return: the wall-clock-time needed by the process"""
        if self.timeEnd==None: #  and self.isDarwin:
            # Mac OS X needs this (Ubuntu too?)
            self.timeEnd=time()

        self.timeEnd=time()

        #        print "Wall:",self.timeEnd,self.timeStart
        if self.timeStart==None or self.timeEnd==None:
            return 0
        else:
            return self.timeEnd-self.timeStart
Example #32
0
class FoamThread(Thread):
    """Thread running an OpenFOAM command

    The output of the command can be accessed in a thread-safe manner,
    line by line

    Designed to be used by the BasicRunner-class"""

    def __init__(self,cmdline,runner):
        """:param cmdline:cmdline - Command line of the OpenFOAM command
        :param runner: the Runner-object that started this thread"""
        Thread.__init__(self)
        self.cmdline=cmdline
        self.runner=runner
        self.output=None
        self.reader=LineReader(config().getboolean("SolverOutput","stripSpaces"))
        self.keyboardInterupted=False

        self.isLinux=False
        self.isDarwin=False
        self.isWindows=False
        self.threadPid=-1
        self.who=RUSAGE_CHILDREN

        if uname()[0]=="Linux":
            self.isLinux=True
            self.linuxMaxMem=0
        elif uname()[0]=="Darwin":
            self.isDarwin=True
        elif uname()[0]=="Windows":
            self.isWindows=True

        self.resStart=None
        self.resEnd=None

        self.timeStart=None
        self.timeEnd=None

        self.timerTime=5.

        self.stateLock=Lock()
        self.setState(False)

        self.status=None
        self.returncode=None

        self.lineLock=Lock()
        self.line=""

        self.stateLock.acquire()

    def run(self):
        """start the command"""
        # print "Starting ",self.cmdline
        self.resStart=getrusage(self.who)
        self.timeStart=time()

        if sys.version_info<(2,4):
            run=Popen4(self.cmdline)
            self.output=run.fromchild
        else:
            run=subprocess.Popen(shellExecutionPrefix()+self.cmdline,
                                 shell=True,
                                 bufsize=0,
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT,
                                 close_fds=True)
            self.output=run.stdout
        self.run=run
        self.threadPid=run.pid
        foamLogger().info("Started with PID %d" % self.threadPid)
        if self.isLinux:
            #            print "Starting Timer"
            self.timer=Timer(0.1*self.timerTime,getLinuxMem,args=[self])
            self.timer.start()

        #            print "Starting Timer"
        self.timer2=Timer(0.5*self.timerTime,checkForStopFile,args=[self])
        self.timer2.start()

        self.hasSomethingToSay=True
        self.stateLock.release()

        try:
            # print "Waiting",time()
            self.status=run.wait()
            # Python 2.3 on Mac OS X never seems to reach this point
            # print "After wait",time()
            # print "Status:",self.status

            # to give a chance to read the remaining output
            if self.hasSomethingToSay:
                sleep(2.)
            while self.reader.read(self.output):
                print_("Unused output:",self.reader.line)
        except OSError:
            e = sys.exc_info()[1] # compatible with 2.x and 3.x
            print_("Exeption caught:",e)

        self.stopTimer()

        self.threadPid=-1

        self.resEnd=getrusage(self.who)
        self.timeEnd=time()
        #        print "End:",self.timeEnd
        # print "Returned",self.status

        self.getReturnCode()

    def getReturnCode(self):
        if sys.version_info<(2,4):
            # Don't know how to get the returncode from a Popen4-object
            self.returncode=0
        else:
            self.returncode=self.run.returncode
        return self.returncode

    def stopTimer(self):
        if self.isLinux:
            self.timer.cancel()
        self.timer2.cancel()

    def read(self):
        """read another line from the output"""
        self.setState(self.reader.read(self.output))
        self.lineLock.acquire()
        self.line=self.reader.line
        self.lineLock.release()

    def getLine(self):
        """gets the last line from the output"""
        self.lineLock.acquire()
        val=self.line
        self.lineLock.release()

        return val

    def interrupt(self):
        """A keyboard-interrupt is reported"""
#        print "Interrupt"
        self.reader.wasInterupted=True
        self.setState(False)

    def setState(self,state):
        """sets the state of the thread (is there any more output)"""
        self.stateLock.acquire()
        self.hasSomethingToSay=state
        if not self.hasSomethingToSay and self.timeStart and self.reader.wasInterupted:
            self.keyboardInterupted=self.reader.keyboardInterupted

            if self.threadPid>0:
                msg="Killing PID %d" % self.threadPid
                print_(msg)
                foamLogger().warning(msg)
                try:
                    kill(self.threadPid,signal.SIGKILL)
                except OSError:
                    warning("Process",self.threadPid,"was already dead")

        #        print "Set: ",state
        self.stateLock.release()

    def check(self):
        """:return: False if there is no more output of the command"""
        self.stateLock.acquire()
        state=self.hasSomethingToSay
        #        print "Get: ",state
        self.stateLock.release()

        return state

    def cpuTime(self):
        """:return: number of seconds CPU-Time used"""
        return self.cpuUserTime()+self.cpuSystemTime()

    def cpuUserTime(self):
        """:return: number of seconds CPU-Time used in user mode"""
        if self.resEnd==None: # and self.isDarwin:
            # Mac OS X needs this (Ubuntu too?)
            self.resEnd=getrusage(self.who)
        if self.resStart==None or self.resEnd==None:
            return 0
        else:
            return self.resEnd.ru_utime-self.resStart.ru_utime

    def cpuSystemTime(self):
        """:return: number of seconds CPU-Time used in system mode"""
        if self.resEnd==None: #  and self.isDarwin:
            # Mac OS X needs this (Ubuntu too?)
            self.resEnd=getrusage(self.who)
        if self.resStart==None or self.resEnd==None:
            return 0
        else:
            return self.resEnd.ru_stime-self.resStart.ru_stime

    def usedMemory(self):
        """:return: maximum resident set size in MegaByte"""
        scale=1024.*1024.
        if self.isLinux:
            return self.linuxMaxMem/scale

        if self.resStart==None or self.resEnd==None:
            return 0.
        else:
            return getpagesize()*(self.resEnd.ru_maxrss-self.resStart.ru_maxrss)/scale

    def wallTime(self):
        """:return: the wall-clock-time needed by the process"""
        if self.timeEnd==None: #  and self.isDarwin:
            # Mac OS X needs this (Ubuntu too?)
            self.timeEnd=time()

        self.timeEnd=time()

        #        print "Wall:",self.timeEnd,self.timeStart
        if self.timeStart==None or self.timeEnd==None:
            return 0
        else:
            return self.timeEnd-self.timeStart
class BasicWatcher(object):
    """Base class for watching the output of commands

    Works like the UNIX-command 'tail -f <file>': the last lines of the file are output.
    If the file grows then these lines are output as they arrive"""

    def __init__(self,filenames,
                 silent=False,
                 tailLength=1000,
                 sleep=0.1,
                 follow=True):
        """:param filename: name of the logfile to watch
        :param silent: if True no output is sent to stdout
        :param tailLength: number of bytes at the end of the fail that should be output.
        :param follow: if the end of the file is reached wait for further input
        Because data is output on a per-line-basis
        :param sleep: interval to sleep if no line is returned"""

        if type(filenames) is list:
            meshTimes=[]
            createMesh="Create mesh for time = "
            for fName in filenames:
                meshTime=None
                with open(fName) as f:
                    for l in f.readlines()[:100]:
                        if l.find(createMesh)==0:
                            meshTime=float(l[len(createMesh):])
                            break
                meshTimes.append((fName,meshTime))
            meshTimes.sort(key=lambda x:1e50 if x[1] is None else x[1])
            filenames=[m[0] for m in meshTimes]
            self.filename=filenames[0]
            self.nextFiles=filenames[1:]
            self.changeTimes=[m[1] for m in meshTimes[1:]]
        else:
            self.filename=filenames
            self.nextFiles=[]
            self.changeTimes=[]

        self._changeFileHooks=[]

        self.silent=silent
        self.tail=tailLength
        self.sleep=sleep
        self.follow=follow
        self.isTailing=False

        if not path.exists(self.filename):
            print_("Error: Logfile ",self.filename,"does not exist")

        self.reader=LineReader(config().getboolean("SolverOutput","stripSpaces"))

    def getSize(self,filename):
        """:return: the current size (in bytes) of the file"""
        return os.stat(filename)[stat.ST_SIZE]

    def addChangeFileHook(self,func):
        self._changeFileHooks.append(func)

    def changeFile(self,filename):
        currSize=self.getSize(filename)

        fn,ext=path.splitext(filename)
        if ext=='.gz':
            fh=gzip.open(filename)
        else:
            fh=open(filename)

        for f in self._changeFileHooks:
            f()

        return fh,currSize

    def start(self):
        """Reads the file and does the processing"""

        fh,currSize=self.changeFile(self.filename)
        switchTime=None if len(self.changeTimes)==0 else self.changeTimes[0]
        self.changeTimes=self.changeTimes[1:]

        self.startHandle()

        while self.follow or currSize>self.reader.bytesRead() or len(self.nextFiles)>0:
            if not currSize>self.reader.bytesRead() or self.analyzer.isPastTime(switchTime):
                if len(self.nextFiles)>0:
                    print_("\n\nSwitching from logfile",self.filename,
                           "to",self.nextFiles[0],"\n\n")
                    self.filename=self.nextFiles[0]
                    self.nextFiles=self.nextFiles[1:]
                    fh,currSize=self.changeFile(self.filename)
                    switchTime=None if len(self.changeTimes)==0 else self.changeTimes[0]
                    self.changeTimes=self.changeTimes[1:]
                    self.reader.reset()
                    self.analyzer.resetFile()
                    if currSize==0:
                        continue
                else:
                    if not self.follow:
                        break
            try:
                status=self.reader.read(fh)
                if status:
                    line=self.reader.line
                    if (currSize-self.reader.bytesRead())<=self.tail:
                        if not self.isTailing:
                            self.isTailing=True
                            self.timeHandle()
                            self.tailingHandle()

                        if not self.silent:
                            print_(line)

                    self.lineHandle(line)
                else:
                    if self.reader.userSaidStop():
                        break
                    sleep(self.sleep)
            except KeyboardInterrupt:
                print_("Watcher: Keyboard interrupt")
                break

        self.stopHandle()

        fh.close()

    def startHandle(self):
        """to be called before the program is started"""
        pass

    def stopHandle(self):
        """called after the program has stopped"""
        pass

    def tailingHandle(self):
        """called when the first line is output"""
        pass

    def lineHandle(self,line):
        """called every time a new line is read"""
        pass
Example #34
0
class BasicWatcher(object):
    """Base class for watching the output of commands

    Works like the UNIX-command 'tail -f <file>': the last lines of the file are output.
    If the file grows then these lines are output as they arrive"""
    def __init__(self,
                 filename,
                 silent=False,
                 tailLength=1000,
                 sleep=0.1,
                 follow=True):
        """:param filename: name of the logfile to watch
        :param silent: if True no output is sent to stdout
        :param tailLength: number of bytes at the end of the fail that should be output.
        :param follow: if the end of the file is reached wait for further input
        Because data is output on a per-line-basis
        :param sleep: interval to sleep if no line is returned"""

        self.filename = filename
        self.silent = silent
        self.tail = tailLength
        self.sleep = sleep
        self.follow = follow
        self.isTailing = False

        if not path.exists(self.filename):
            print_("Error: Logfile ", self.filename, "does not exist")

        self.reader = LineReader(config().getboolean("SolverOutput",
                                                     "stripSpaces"))

    def getSize(self):
        """:return: the current size (in bytes) of the file"""
        return os.stat(self.filename)[stat.ST_SIZE]

    def start(self):
        """Reads the file and does the processing"""

        currSize = self.getSize()

        fn, ext = path.splitext(self.filename)
        if ext == '.gz':
            fh = gzip.open(self.filename)
        else:
            fh = open(self.filename)

        self.startHandle()

        while self.follow or currSize > self.reader.bytesRead():
            try:
                status = self.reader.read(fh)
                if status:
                    line = self.reader.line
                    if (currSize - self.reader.bytesRead()) <= self.tail:
                        if not self.isTailing:
                            self.isTailing = True
                            self.timeHandle()
                            self.tailingHandle()

                        if not self.silent:
                            print_(line)

                    self.lineHandle(line)
                else:
                    if self.reader.userSaidStop():
                        break
                    sleep(self.sleep)
            except KeyboardInterrupt:
                print_("Watcher: Keyboard interrupt")
                break

        self.stopHandle()

        fh.close()

    def startHandle(self):
        """to be called before the program is started"""
        pass

    def stopHandle(self):
        """called after the program has stopped"""
        pass

    def tailingHandle(self):
        """called when the first line is output"""
        pass

    def lineHandle(self, line):
        """called every time a new line is read"""
        pass
Example #35
0
 def __startProcess(self):
     l = LineReader(False)
     self.openFile()
     return l