Skip to content
Snippets Groups Projects
log_file.py 3.66 KiB
Newer Older
mads's avatar
mads committed
'''
Created on 18/11/2015

@author: MMPE
'''
import os
from wetb.hawc2.htc_file import HTCFile
from collections import OrderedDict
MISSING = "Log file cannot be found"
PENDING = "Simulation not started yet"
INITIALIZATION = 'Initializing simulation'
GENERATING_TURBULENCE = "Generating turbulence"
SIMULATING = "Simulating"
ABORTED = ""
DONE = "Simulation succeded"
INITIALIZATION_ERROR = "Initialization error"
SIMULATION_ERROR = "Simulation error"
ERROR = "Error"

def is_file_open(filename):
    try:
        os.rename(filename, filename + "_")
        os.rename(filename + "_", filename)
        return False
    except OSError as e:
        if "The process cannot access the file because it is being used by another process" not in str(e):
            raise

        if os.path.isfile(filename + "_"):
            os.remove(filename + "_")
        return True

class LogFile(object):
    _status = (0, MISSING)
    def __init__(self, log_filename, time_stop):
        self.filename = log_filename
        self.time_stop = time_stop
        self.position = 0

    def clear(self):
        os.makedirs(os.path.dirname(self.filename), exist_ok=True)
        with open(self.filename, 'w'):
            pass
        self.position = 0

    def status(self):
        if not os.path.isfile(self.filename):
            self._status = (0, MISSING, [])
        else:
            if self._status[1] == MISSING:
                self._status = (0, PENDING, [])
            with open(self.filename) as fid:
                fid.seek(self.position)
                txt = fid.read()
            self.position += len(txt)
            if self._status[1] == PENDING and self.position > 0:
                self._status = (0, INITIALIZATION, [])
            error_lst = self._status[2]
            if len(txt) > 0:
                if self._status[1] == INITIALIZATION or self._status[1] == GENERATING_TURBULENCE:
                    init_txt, *rest = txt.split("Starting simulation")
                    if "*** ERROR ***" in init_txt:
                        error_lst.extend([l for l in init_txt.strip().split("\n") if "ERROR" in l])
                    if "Turbulence generation starts" in init_txt[init_txt.strip().rfind("\n"):]:
                        self._status = (0, GENERATING_TURBULENCE, error_lst)
                    if rest:
                        txt = rest[0]
                        self._status = (0, SIMULATING, error_lst)
                if self._status[1] == SIMULATING:

                    simulation_txt, *rest = txt.split('Elapsed time')
                    if "*** ERROR ***" in simulation_txt:
                        error_lst.extend([l for l in simulation_txt.strip().split("\n") if "ERROR" in l])
                    i1 = simulation_txt.rfind("Global time")
                    i2 = simulation_txt[:i1].rfind('Global time')
                    time_line = simulation_txt[i1:]
                    try:
                        time = float(time_line[time_line.index('=') + 1:time_line.index('Iter')])
                        self._status = (int(100 * time // self.time_stop), SIMULATING, error_lst)
                    except:
                        self._status = (self._status[0], SIMULATING, error_lst)
                    if rest:
                        self._status = (100, DONE, error_lst)
            #return self._status

        error_lst = self._status[2]
        error_dict = OrderedDict()
        for error in error_lst:
            error_dict[error] = error_dict.get(error, 0) + 1
        error_lst = [("%d x %s" % (v, k), k)[v == 1] for k, v in error_dict.items()]

        return (self._status[0], self._status[1], error_lst)