Skip to content

Commit

Permalink
functionality for dumping translation log files for failed simulation… (
Browse files Browse the repository at this point in the history
#293)

* functionality for dumping translation log files for failed simulations only (#292)

see #285

* Run autopep

* Run autopep with version 1.4.4
  • Loading branch information
mwetter authored Sep 17, 2019
1 parent 1f1c5b9 commit 10ea43c
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 38 deletions.
54 changes: 39 additions & 15 deletions buildingspy/development/regressiontest.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ def runSimulation(worDir, cmd):
else:
return 0
except OSError as e:
sys.stderr.write("Execution of '" + " ".join(map(str, cmd)) + " failed.\n" +
"Working directory is '" + worDir + "'.")
sys.stderr.write("Execution of '" + " ".join(map(str, cmd)) + " failed.\n"
+ "Working directory is '" + worDir + "'.")
raise(e)
except KeyboardInterrupt as e:
pro.kill()
Expand Down Expand Up @@ -259,8 +259,10 @@ def __init__(
else:
raise ValueError(
"Value of 'tool' of constructor 'Tester' must be 'dymola', 'omc' or 'jmodelica'. Received '{}'.".format(tool))
# File to which the console output of the simulator is written to
# File to which the console output of the simulator is written
self._simulator_log_file = "simulator-{}.log".format(tool)
# File to which the console output of the simulator of failed simulations is written
self._failed_simulator_log_file = "failed-simulator-{}.log".format(tool)
# File to which statistics is written to
self._statistics_log = "statistics.json"
self._nPro = multiprocessing.cpu_count()
Expand Down Expand Up @@ -1398,9 +1400,9 @@ def legacy_comp(self, tOld, yOld, tNew, yNew, tGriOld, tGriNew, varNam, filNam,
for i in range(len(yInt)):
errAbs[i] = abs(yOld[i] - yInt[i])
if np.isnan(errAbs[i]):
raise ValueError('NaN in errAbs ' + varNam + " " + str(yOld[i]) +
" " + str(yInt[i]) + " i, N " + str(i) + " --:" + str(yInt[i - 1]) +
" ++:", str(yInt[i + 1]))
raise ValueError('NaN in errAbs ' + varNam + " " + str(yOld[i])
+ " " + str(yInt[i]) + " i, N " + str(i) + " --:" + str(yInt[i - 1])
+ " ++:", str(yInt[i + 1]))
if (abs(yOld[i]) > 10 * tol):
errRel[i] = errAbs[i] / abs(yOld[i])
else:
Expand Down Expand Up @@ -1713,8 +1715,8 @@ def _isParameter(self, dataSeries):
"""
import numpy as np
if not (isinstance(dataSeries, np.ndarray) or isinstance(dataSeries, list)):
raise TypeError("Program error: dataSeries must be a numpy.ndarr or a list. Received type " +
str(type(dataSeries)) + ".\n")
raise TypeError("Program error: dataSeries must be a numpy.ndarr or a list. Received type "
+ str(type(dataSeries)) + ".\n")
return (len(dataSeries) == 2)

def format_float(self, value):
Expand Down Expand Up @@ -2555,12 +2557,21 @@ def _checkSimulationError(self, errorFile):
iCom = 0
iSim = 0
iFMU = 0

# Header for dump file
with open(self._failed_simulator_log_file, "w") as f:
f.write("Automatically generated BuildingsPy dump file for failed translations.\n\n")

# Check for errors
hasTranslationErrors = False
for ele in stat:
hasTranslationError = False
if 'check' in ele and ele['check']['result'] is False:
hasTranslationError = True
iChe = iChe + 1
self._reporter.writeError("Model check failed for '%s'." % ele["model"])
if 'simulate' in ele and ele['simulate']['result'] is False:
hasTranslationError = True
iSim = iSim + 1
self._reporter.writeError("Simulation failed for '%s'." %
ele["simulate"]["command"])
Expand All @@ -2585,13 +2596,26 @@ def _checkSimulationError(self, errorFile):
self._reporter.writeWarning(v["model_message"].format(ele[key]["command"]))
self._error_dict.increment_counter(k)

if hasTranslationError:
hasTranslationErrors = True
with open(self._failed_simulator_log_file, "a") as f:
f.write("===============================\n")
f.write("=====START OF NEW LOG FILE=====\n")
f.write("===============================\n")
with open(logFil, "r") as f2:
f.write(f2.read())
f.write("\n\n\n")

if iChe > 0:
print("Number of models that failed check : {}".format(iChe))
if iSim > 0:
print("Number of models that failed to simulate : {}".format(iSim))
if iFMU > 0:
print("Number of models that failed to export as an FMU : {}".format(iFMU))

if hasTranslationErrors:
print(
"Check or simulation failed, see {} for more details about the failed models.".format(
self._failed_simulator_log_file))
return self._writeSummaryMessages()

def _writeSummaryMessages(self, silent=True):
Expand Down Expand Up @@ -2724,8 +2748,8 @@ def _write_runscripts(self):
def _write_translation_stats(runFil, values):

# Close the bracket for the JSON object
runFil.write("""Modelica.Utilities.Streams.print(" }", """ +
'"' + values['statisticsLog'] + '"' + ");\n")
runFil.write("""Modelica.Utilities.Streams.print(" }", """
+ '"' + values['statisticsLog'] + '"' + ");\n")

def _print_end_of_json(isLastItem, fileHandle, logFileName):
if isLastItem:
Expand Down Expand Up @@ -2849,8 +2873,8 @@ def _print_end_of_json(isLastItem, fileHandle, logFileName):
"translationLog": os.path.join(
self._temDir[iPro],
self.getLibraryName(),
self._data[i]['model_name'] +
".translation.log").replace(
self._data[i]['model_name']
+ ".translation.log").replace(
"\\",
"/"),
"simulatorLog": self._simulator_log_file.replace(
Expand Down Expand Up @@ -3523,8 +3547,8 @@ def test_OpenModelica(self, cmpl=True, simulate=False,
return retcode

except OSError as e:
raise OSError("Execution of omc +d=initialization " + mosfile + " failed.\n" +
"Working directory is '" + worDir + "'.")
raise OSError("Execution of omc +d=initialization " + mosfile + " failed.\n"
+ "Working directory is '" + worDir + "'.")
else:
# process the log file
print("Logfile created: {}".format(logFilNam))
Expand Down
46 changes: 23 additions & 23 deletions buildingspy/development/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ def _check_experiment(self, name, val, value, model_path, mos_file):

if (delta > 0):
s = ("Found mo file={!s} with experiment annotation {!s}.\n" +
"The value of {!s}={!s} is different from the (default) value={!s}"
+ " found in the mos file={!s}.\n").format(model_path,
self._capitalize_first(name),
self._capitalize_first(name),
val, value, mos_file)
"The value of {!s}={!s} is different from the (default) value={!s}" +
" found in the mos file={!s}.\n").format(model_path,
self._capitalize_first(name),
self._capitalize_first(name),
val, value, mos_file)
raise ValueError(s)

def _missing_parameter(self, name, value, model_path, mos_file):
Expand All @@ -246,9 +246,9 @@ def _missing_parameter(self, name, value, model_path, mos_file):
"""

s = (
"Found mo file={!s} without parameter {!s} defined.\n"
+ "The parameter name {!s} is defined in the mos file={!s}"
+ " with the value {!s}. It must hence be defined in the mo file.\n").format(
"Found mo file={!s} without parameter {!s} defined.\n" +
"The parameter name {!s} is defined in the mos file={!s}" +
" with the value {!s}. It must hence be defined in the mo file.\n").format(
model_path,
self._capitalize_first(name),
name,
Expand Down Expand Up @@ -350,8 +350,8 @@ def _separate_mos_files(self, mos_files):
f.close()

if (found_sim and not found_tol):
s = ("Found mos file={!s} without tolerance defined.\n"
+ "A minimum tolerance of 1e-6 is required for JModelica.\n").format(itr)
s = ("Found mos file={!s} without tolerance defined.\n" +
"A minimum tolerance of 1e-6 is required for JModelica.\n").format(itr)
raise ValueError(s)

return n_tols, mos_non_fmus, mos_fmus
Expand Down Expand Up @@ -456,12 +456,12 @@ def _wrong_literal(self, mos_file, name):
"""

s = (
"Found mos file={!s} with invalid expression={!s}.\n"
+ "This is not allowed for cross validation with JModelica.\n").format(
"Found mos file={!s} with invalid expression={!s}.\n" +
"This is not allowed for cross validation with JModelica.\n").format(
mos_file,
name
+ '='
+ name)
name +
'=' +
name)
raise ValueError(s)

def _validate_experiment_setup(self, name, mos_files):
Expand Down Expand Up @@ -552,13 +552,13 @@ def _validate_experiment_setup(self, name, mos_files):
self._missing_parameter(name, value, model_path, mos_file)

# Check if attributes StopTime/stopTime are defined in mos and mo
if (name + "=" == "stopTime=" and abs(eval(value) - 1.0)
> 0.0 and (not foundStopExp_mo)):
if (name + "=" == "stopTime=" and abs(eval(value) - 1.0) >
0.0 and (not foundStopExp_mo)):
self._missing_parameter(name, value, model_path, mos_file)

# Check if attributes Tolerance/tolerance are defined in mos and mo
if (name + "=" == "tolerance=" and abs(eval(value))
> 0.0 and (not foundToleranceExp_mo)):
if (name + "=" == "tolerance=" and abs(eval(value)) >
0.0 and (not foundToleranceExp_mo)):
self._missing_parameter(name, value, model_path, mos_file)

for i in range(Nlines - 1, 0, -1):
Expand Down Expand Up @@ -588,8 +588,8 @@ def validateExperimentSetup(self, root_dir):
# Make sure that the parameter root_dir points to a Modelica package.
topPackage = os.path.join(root_dir, "package.mo")
if not os.path.isfile(topPackage):
s = ("Argument root_dir={!s} is not a Modelica package.\n"
+ "Expected file={!s}.\n").format(root_dir, topPackage)
s = ("Argument root_dir={!s} is not a Modelica package.\n" +
"Expected file={!s}.\n").format(root_dir, topPackage)
raise ValueError(s)

# Get the path to the mos files
Expand All @@ -609,6 +609,6 @@ def validateExperimentSetup(self, root_dir):
self._validate_experiment_setup(i, mos_non_fmus)

if(n_tols != n_mo_files):
s = ("The number of tolerances in the mos files={!s} does no match "
+ "the number of mo files={!s}.\n").format(n_tols, n_mo_files)
s = ("The number of tolerances in the mos files={!s} does no match " +
"the number of mo files={!s}.\n").format(n_tols, n_mo_files)
raise ValueError(s)

0 comments on commit 10ea43c

Please sign in to comment.