diff --git a/wetb/hawc2/htc_contents.py b/wetb/hawc2/htc_contents.py index 7bbe2c4548aec27ad8c6ca1f6fd633f83465ed5f..0681b0049f59756a75a3b187c92cffabfb43f53a 100644 --- a/wetb/hawc2/htc_contents.py +++ b/wetb/hawc2/htc_contents.py @@ -218,6 +218,8 @@ class HTCOutputSection(HTCSection): def line_from_line(self, lines): + while lines[0].strip() == "": + lines.pop(0) name = lines[0].split()[0].strip() if name in ['filename', 'data_format', 'buffer', 'time']: return HTCLine.from_lines(lines) @@ -242,6 +244,8 @@ class HTCOutputAtTimeSection(HTCOutputSection): type = None time = None def __init__(self, name, begin_comments="", end_comments=""): + if len(name.split()) < 3: + raise ValueError('"keyword" and "time" arguments required for output_at_time command:\n%s' % name) name, self.type, time = name.split() self.time = float(time) HTCOutputSection.__init__(self, name, begin_comments=begin_comments, end_comments=end_comments) @@ -270,9 +274,11 @@ class HTCSensor(HTCLine): if len(line.split()) > 2: _3to2list5 = list(line.split()) type, sensor, values, = _3to2list5[:2] + [_3to2list5[2:]] - else: + elif len(line.split()) == 2: type, sensor = line.split() values = [] + else: + type, sensor, values = "", "", [] def fmt(v): try: if int(float(v)) == float(v): diff --git a/wetb/hawc2/htc_file.py b/wetb/hawc2/htc_file.py index 0a58d861b490e8f8865517e9de4ea8a653891e12..69d2c741fc761e30292243a439c3a2d1fadc9b4a 100644 --- a/wetb/hawc2/htc_file.py +++ b/wetb/hawc2/htc_file.py @@ -14,6 +14,7 @@ from io import open from builtins import str from future import standard_library from wetb.utils.process_exec import pexec + standard_library.install_aliases() from collections import OrderedDict @@ -210,7 +211,14 @@ class HTCFile(HTCContents, HTCDefaults): hawc2exe = exe errorcode, stdout, stderr, cmd = pexec([hawc2exe, htcfile], self.modelpath) - if errorcode or 'Elapsed time' not in stderr: + if "logfile" in self.simulation: + with open(os.path.join(self.modelpath, self.simulation.logfile[0])) as fid: + log = fid.read() + else: + log = stderr + + + if errorcode or 'Elapsed time' not in log: raise Exception (str(stdout) + str(stderr)) if "__main__" == __name__: diff --git a/wetb/hawc2/log_file.py b/wetb/hawc2/log_file.py index 0316f709232bf56a7f97e26dbd1a01bc17ba57e2..b72e756b80446469826291f9307ece82be88de81 100644 --- a/wetb/hawc2/log_file.py +++ b/wetb/hawc2/log_file.py @@ -150,8 +150,11 @@ class LogFile(LogInterpreter): # exist_ok does not exist in Python27 if not os.path.exists(os.path.dirname(self.filename)): os.makedirs(os.path.dirname(self.filename)) #, exist_ok=True) - with open(self.filename, 'w', encoding='utf-8'): - pass + try: + with open(self.filename, 'w', encoding='utf-8'): + pass + except PermissionError as e: + raise PermissionError(str(e) + "\nLog file cannot be cleared. Check if it is open in another program") LogInterpreter.clear(self) def update_status(self): diff --git a/wetb/hawc2/simulation.py b/wetb/hawc2/simulation.py index 9874f3e81f7e950ed6ae5a995dcfd2cdb9d727f2..4dc2455d23bfdfd6cac95132ab8a6b536e759bce 100755 --- a/wetb/hawc2/simulation.py +++ b/wetb/hawc2/simulation.py @@ -79,6 +79,7 @@ class Simulation(object): status = QUEUED def __init__(self, modelpath, htcfilename, hawc2exe="HAWC2MB.exe", copy_turbulence=True): self.modelpath = os.path.abspath(modelpath) + "/" + self.tmp_modelpath = self.modelpath self.folder = os.path.dirname(htcfilename) if not os.path.isabs(htcfilename): htcfilename = os.path.join(modelpath, htcfilename) @@ -106,7 +107,8 @@ class Simulation(object): self.non_blocking_simulation_thread = Thread(target=self.simulate_distributed) self.updateStatusThread = UpdateStatusThread(self) self.host = LocalSimulationHost(self) - + self.stdout = "" + self.returncode = 0 def start(self, update_interval=1): """Start non blocking distributed simulation""" @@ -207,7 +209,7 @@ class Simulation(object): self.update_status() self.is_simulating = False if self.host.returncode or self.errors: - raise Exception("Simulation error:\n" + "\n".join(self.errors)) + raise Exception("Simulation error:\nReturn code: %d\n%s" % (self.host.returncode, "\n".join(self.errors))) elif self.logFile.status != log_file.DONE or self.logFile.errors: raise Warning("Simulation succeded with errors:\nLog status:%s\nErrors:\n%s" % (self.logFile.status, "\n".join(self.logFile.errors))) else: @@ -325,7 +327,7 @@ class Simulation(object): def show_message(self, msg, title="Information"): print (msg) - def set_id(self): + def set_id(self, *args, **kwargs): pass @@ -401,6 +403,7 @@ class LocalSimulationHost(SimulationResource): #must be called through simulation object self.returncode, self.stdout = 1, "Simulation failed" self.simulationThread.start() + self.sim.set_id(self.sim.simulation_id, "Localhost(pid:%d)" % self.simulationThread.process.pid, self.tmp_modelpath) self.simulationThread.join() self.returncode, self.stdout = self.simulationThread.res self.logFile.update_status()