Skip to content
Snippets Groups Projects
Commit fb842346 authored by mads's avatar mads
Browse files

status enum changes

parent 812965da
No related branches found
No related tags found
No related merge requests found
...@@ -13,11 +13,7 @@ MISSING = "Log file cannot be found" ...@@ -13,11 +13,7 @@ MISSING = "Log file cannot be found"
PENDING = "Simulation not started yet" PENDING = "Simulation not started yet"
INITIALIZATION = 'Initializing simulation' INITIALIZATION = 'Initializing simulation'
SIMULATING = "Simulating" SIMULATING = "Simulating"
ABORTED = ""
DONE = "Simulation succeded" DONE = "Simulation succeded"
INITIALIZATION_ERROR = "Initialization error"
SIMULATION_ERROR = "Simulation error"
ERROR = "Error"
def is_file_open(filename): def is_file_open(filename):
try: try:
...@@ -64,16 +60,19 @@ class LogFile(object): ...@@ -64,16 +60,19 @@ class LogFile(object):
pass pass
self.reset() self.reset()
def extract_time(self, time_line): def extract_time(self, txt):
time_line = time_line.strip() i1 = txt.rfind("Global time")
if 'Starting simulation' == time_line: if i1 == -1:
return 0 return self.current_time
else:
time_line = txt[i1:].strip()
if time_line == "": if time_line == "":
return self.current_time return self.current_time
try: try:
return float(time_line[time_line.index('=') + 1:time_line.index('Iter')]) return float(time_line[time_line.index('=') + 1:time_line.index('Iter')])
except: except:
print ("#" + time_line + "#") print ("Cannot extract time from #" + time_line + "#")
pass pass
def update_status(self): def update_status(self):
...@@ -91,7 +90,8 @@ class LogFile(object): ...@@ -91,7 +90,8 @@ class LogFile(object):
self.status = INITIALIZATION self.status = INITIALIZATION
if len(txt) > 0: if len(txt) > 0:
self.lastline = (txt.strip()[max(0, txt.strip().rfind("\n")):]).strip() if len(txt.strip()):
self.lastline = (txt.strip()[max(0, txt.strip().rfind("\n")):]).strip()
if self.status == INITIALIZATION: if self.status == INITIALIZATION:
init_txt, *rest = txt.split("Starting simulation") init_txt, *rest = txt.split("Starting simulation")
if "*** ERROR ***" in init_txt: if "*** ERROR ***" in init_txt:
...@@ -100,18 +100,23 @@ class LogFile(object): ...@@ -100,18 +100,23 @@ class LogFile(object):
txt = rest[0] txt = rest[0]
self.status = SIMULATING self.status = SIMULATING
if not 'Elapsed time' in self.lastline: if not 'Elapsed time' in self.lastline:
self.start_time = (self.extract_time(self.lastline), time.time()) i1 = txt.rfind("Global time")
if i1 > -1:
self.start_time = (self.extract_time(txt[i1:]), time.time())
if self.status == SIMULATING: if self.status == SIMULATING:
simulation_txt, *rest = txt.split('Elapsed time') simulation_txt, *rest = txt.split('Elapsed time')
if "*** ERROR ***" in simulation_txt: if "*** ERROR ***" in simulation_txt:
self.errors.extend([l.strip() for l in simulation_txt.strip().split("\n") if "error" in l.lower()]) self.errors.extend([l.strip() for l in simulation_txt.strip().split("\n") if "error" in l.lower()])
i1 = simulation_txt.rfind("Global time") i1 = simulation_txt.rfind("Global time")
i2 = simulation_txt[:i1].rfind('Global time') if i1 > -1:
self.current_time = self.extract_time(simulation_txt[i1:]) self.current_time = self.extract_time(simulation_txt[i1:])
self.pct = int(100 * self.current_time // self.time_stop) if self.time_stop > 0:
if self.current_time is not None and self.start_time is not None and (self.current_time - self.start_time[0]) > 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.remaining_time = (time.time() - self.start_time[1]) / (self.current_time - self.start_time[0]) * (self.time_stop - self.current_time)
except:
pass
if rest: if rest:
self.status = DONE self.status = DONE
self.pct = 100 self.pct = 100
......
import os import os
from wetb.hawc2.htc_file import HTCFile from wetb.hawc2.htc_file import HTCFile
from wetb.hawc2.log_file import LogFile, SIMULATING from wetb.hawc2.log_file import LogFile
from threading import Timer, Thread from threading import Timer, Thread
import sys import sys
from multiprocessing.process import Process from multiprocessing.process import Process
...@@ -10,10 +10,17 @@ import subprocess ...@@ -10,10 +10,17 @@ import subprocess
import shutil import shutil
import json import json
import glob import glob
from wetb.hawc2 import log_file
QUEUED = "queued" #until start
INITIALIZING = "initializing" #when starting
SIMULATING = "SIMULATING" # when logfile.status=simulating
FINISH = "finish" # when finish
ERROR = "error" # when hawc2 returns error
ABORTED = "aborted" # when stopped and logfile.status != Done
CLEANED = "cleaned" # after copy back
class Simulation(object): class Simulation(object):
is_simulating = False is_simulating = False
...@@ -22,24 +29,35 @@ class Simulation(object): ...@@ -22,24 +29,35 @@ class Simulation(object):
self.folder = os.path.dirname(htcfilename) self.folder = os.path.dirname(htcfilename)
if not os.path.isabs(htcfilename): if not os.path.isabs(htcfilename):
htcfilename = os.path.join(modelpath, htcfilename) htcfilename = os.path.join(modelpath, htcfilename)
self.htcfilename = htcfilename
self.filename = os.path.basename(htcfilename) self.filename = os.path.basename(htcfilename)
self.htcFile = HTCFile(htcfilename) self.htcFile = HTCFile(htcfilename)
self.time_stop = self.htcFile.simulation.time_stop[0] self.time_stop = self.htcFile.simulation.time_stop[0]
self.copy_turbulence = True
self.log_filename = self.htcFile.simulation.logfile[0] self.log_filename = self.htcFile.simulation.logfile[0]
if os.path.isabs(self.log_filename): if os.path.isabs(self.log_filename):
self.log_filename = os.path.relpath(self.log_filename, self.modelpath) self.log_filename = os.path.relpath(self.log_filename, self.modelpath)
self.logFile = LogFile(os.path.join(self.modelpath, self.log_filename), self.time_stop) self.logFile = LogFile(os.path.join(self.modelpath, self.log_filename), self.time_stop)
self.logFile.clear() self.logFile.clear()
self.last_status = (0, "Pending", []) self._status = QUEUED
self.thread = Thread(target=self.simulate) self.thread = Thread(target=self.simulate)
self.simulationThread = SimulationThread(self.modelpath, self.htcFile.filename, hawc2exe) self.simulationThread = SimulationThread(self.modelpath, self.htcFile.filename, hawc2exe)
self.timer = RepeatedTimer(1, self.update_status) self.timer = RepeatedTimer(1, self.update_status)
def __str__(self):
return "Simulation(%s)" % self.filename
def update_status(self, *args, **kwargs): def update_status(self, *args, **kwargs):
if self.status in [INITIALIZING, SIMULATING]:
self.logFile.update_status()
if self.logFile.status == log_file.SIMULATING:
self._status = SIMULATING
if self.logFile.status == log_file.DONE:
self._status = FINISH
def show_status(self):
status = self.logFile.status() status = self.logFile.status()
if status[1] == SIMULATING: if status[1] == SIMULATING:
if self.last_status[1] != SIMULATING: if self.last_status[1] != SIMULATING:
...@@ -83,54 +101,66 @@ class Simulation(object): ...@@ -83,54 +101,66 @@ class Simulation(object):
def finish_simulation(self, copy_turbulence): def finish_simulation(self):
if self.status == CLEANED: return
files = self.htcFile.output_files() files = self.htcFile.output_files()
if copy_turbulence: if self.copy_turbulence:
files.extend(self.htcFile.turbulence_files()) files.extend(self.htcFile.turbulence_files())
for dst in files: for dst in files:
if not os.path.isabs(dst): if not os.path.isabs(dst):
dst = os.path.join(self.modelpath, dst) dst = os.path.join(self.modelpath, dst)
src = os.path.join(self.tmp_modelpath, os.path.relpath(dst, self.modelpath)) src = os.path.join(self.tmp_modelpath, os.path.relpath(dst, self.modelpath))
if os.path.isfile(src):
os.makedirs(os.path.dirname(dst), exist_ok=True) for src_file in glob.glob(src):
if not os.path.isfile(dst) or os.path.getmtime(dst) != os.path.getmtime(src): dst_file = os.path.join(self.modelpath, os.path.relpath(src_file, self.tmp_modelpath))
shutil.copy(src, dst) os.makedirs(os.path.dirname(dst_file), exist_ok=True)
if not os.path.isfile(dst_file) or os.path.getmtime(dst_file) != os.path.getmtime(src_file):
shutil.copy(src_file, dst_file)
self.logFile.filename = os.path.join(self.modelpath, self.log_filename) self.logFile.filename = os.path.join(self.modelpath, self.log_filename)
try:
shutil.rmtree(self.tmp_modelpath)
except (PermissionError, OSError) as e:
raise Warning(str(e))
shutil.rmtree(self.tmp_modelpath) self.status = CLEANED
def simulate(self): def simulate(self):
self.is_simulating = True self.is_simulating = True
self.timer.start() self.logFile.clear()
self.status = INITIALIZING
self.simulationThread.start() self.simulationThread.start()
self.simulationThread.join() self.simulationThread.join()
self.returncode, self.stderr, self.stdout = self.simulationThread.res
errorcode, stdout, stderr, cmd = self.simulationThread.res if self.returncode or 'error' in self.stderr.lower() or 'error' in self.stdout.lower():
if errorcode: print (self.returncode)
print (errorcode) print ("stdout:\n", self.stdout)
print (stdout) print ("-"*50)
print (stderr) print ("stderr:\n", self.stderr)
print (cmd) print ("#"*50)
self.timer.stop() self.logFile.errors(list(set([l for l in self.stderr.split("\n") if 'error' in l.lower()])))
self.status = ERROR
# else:
# self.stop()
# self.finish_simulation()
# self.controller.update_queues()
self.is_simulating = False self.is_simulating = False
self.update_status()
def start(self): def start(self):
self.thread.start() self.thread.start()
def terminate(self): def stop(self):
self.timer.stop() self.timer.stop()
self.simulationThread.process.kill() self.simulationThread.process.kill()
self.simulationThread.join() self.finish_simulation()
if self.logFile.status not in [log_file.DONE]:
self.logFile.status = ABORTED
class SimulationProcess(Process): class SimulationProcess(Process):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment