Newer
Older
'''
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'
SIMULATING = "Simulating"
DONE = "Simulation succeded"
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):
def __init__(self, log_filename, time_stop):
self.filename = log_filename
self.time_stop = time_stop
self.reset()
self.update_status()
@staticmethod
def from_htcfile(htcfile, modelpath):
logfilename = htcfile.simulation.logfile[0]
if not os.path.isabs(logfilename):
logfilename = os.path.join(modelpath, logfilename)
return LogFile(logfilename, htcfile.simulation.time_stop[0])
def reset(self):
self.lastline = ""
self.status = UNKNOWN
self.pct = 0
self.errors = []
self.info = []
self.start_time = None
self.current_time = 0
self.remaining_time = None
def clear(self):
os.makedirs(os.path.dirname(self.filename), exist_ok=True)
with open(self.filename, 'w'):
pass
def extract_time(self, txt):
i1 = txt.rfind("Global time")
if i1 == -1:
return self.current_time
else:
time_line = txt[i1:].strip()
if time_line == "":
return self.current_time
try:
return float(time_line[time_line.index('=') + 1:time_line.index('Iter')])
except:
if self.status == UNKNOWN or self.status == MISSING:
self.status = PENDING
with open(self.filename, 'rb') as fid:
fid.seek(self.position)
txt = fid.read()
self.position += len(txt)
txt = txt.decode(encoding='utf_8', errors='strict')
if self.status == PENDING and self.position > 0:
self.status = INITIALIZATION
if len(txt.strip()):
self.lastline = (txt.strip()[max(0, txt.strip().rfind("\n")):]).strip()
init_txt, *rest = txt.split("Starting simulation")
if "*** ERROR ***" in init_txt:
self.errors.extend([l.strip() for l in init_txt.strip().split("\n") if "error" in l.lower()])
self.status = SIMULATING
if not 'Elapsed time' in self.lastline:
i1 = txt.rfind("Global time")
if i1 > -1:
self.start_time = (self.extract_time(txt[i1:]), time.time())
simulation_txt, *rest = txt.split('Elapsed time')
if "*** ERROR ***" in simulation_txt:
self.errors.extend([l.strip() for l in simulation_txt.strip().split("\n") if "error" in l.lower()])
if i1 > -1:
self.current_time = self.extract_time(simulation_txt[i1:])
if self.time_stop > 0:
self.pct = int(100 * self.current_time // self.time_stop)
try:
self.remaining_time = (time.time() - self.start_time[1]) / (self.current_time - self.start_time[0]) * (self.time_stop - self.current_time)
self.status = DONE
self.pct = 100
self.elapsed_time = float(rest[0].replace(":", "").strip())
return "\n".join([("%d x %s" % (v, k), k)[v == 1] for k, v in error_dict.items()])
def remaining_time_str(self):
if self.remaining_time:
if self.remaining_time < 3600:
m, s = divmod(self.remaining_time, 60)
return "%02d:%02d" % (m, math.ceil(s))
else:
h, ms = divmod(self.remaining_time, 3600)
m, s = divmod(ms, 60)
return "%d:%02d:%02d" % (h, m, math.ceil(s))
else:
return "--:--"
def add_HAWC2_errors(self, errors):
if errors:
self.status = ERROR
self.errors.extend(errors)