diff --git a/src/Model/Ensembles/Function.py b/src/Model/Ensembles/Function.py index 31ed6923..4725f56a 100644 --- a/src/Model/Ensembles/Function.py +++ b/src/Model/Ensembles/Function.py @@ -165,7 +165,6 @@ class Uniform(Function): return r - class Custom(Function): _sub_classes = [] diff --git a/src/Model/Results/Results.py b/src/Model/Results/Results.py index 2ea30e03..b47c180d 100644 --- a/src/Model/Results/Results.py +++ b/src/Model/Results/Results.py @@ -338,7 +338,7 @@ class Results(SQLSubModel): _sub_classes = [River, TableData, AdditionalData] def __init__(self, id=-1, study=None, solver=None, - repertory="", name="0"): + repertory="", name="0", is_ensemble=False): super(Results, self).__init__( id=id, status=study.status, owner_scenario=study.status.scenario.id @@ -351,6 +351,8 @@ class Results(SQLSubModel): self._solver = solver self._repertory = repertory + self._is_ensemble = is_ensemble + self._meta_data = { # Keep results creation date "creation_date": datetime.now(), @@ -364,6 +366,9 @@ class Results(SQLSubModel): if solver is not None: self.set("solver_type", solver._type) + def is_ensemble(self): + return self._is_ensemble + @property def date(self): date = self._meta_data["creation_date"] diff --git a/src/Solver/Mage.py b/src/Solver/Mage.py index 1ea9220d..d2659922 100644 --- a/src/Solver/Mage.py +++ b/src/Solver/Mage.py @@ -1033,24 +1033,26 @@ class Mage8(Mage): self._study = study name = study.name.replace(" ", "_") - self._export_ensemble_RUG( + var_samples = self._export_ensemble_RUG( study, repertory, qlog, name=name, samples=samples, ) - return True + return var_samples def _export_ensemble_RUG(self, study, repertory, qlog, name="0", samples={}): files = [] + var_samples = [] for ens in samples: if ens.target_data is None: continue x = next(samples[ens]) + var_samples.append(x) qlog.put(f"*** Variation " + f"'{ens.target_data}' - {ens.data_type} x {x}") @@ -1092,7 +1094,7 @@ class Mage8(Mage): id += 1 - return files + return var_samples ########### # RESULTS # @@ -1656,6 +1658,14 @@ class Mage8(Mage): return True + def get_ensemble_empty_results(self, study, repertory, name=None): + return Results( + study=study, + solver=self, + repertory=repertory, + name=name, + is_ensemble=True, + ) class MageFake7(Mage8): _type = "mage_fake7" diff --git a/src/View/RunSolver/Window.py b/src/View/RunSolver/Window.py index 99e9ccf8..2c9aa027 100644 --- a/src/View/RunSolver/Window.py +++ b/src/View/RunSolver/Window.py @@ -20,6 +20,8 @@ import os import logging import tempfile +import numpy as np + from queue import Queue from tools import trace, timer, logger_exception @@ -474,6 +476,8 @@ class SolverLogEnsWindow(SolverLogWindow): self._samples[ens] = ens.get_sample(self._run_number) + self._results = None + self._run_samples = [] self._results_tables = {} super(SolverLogEnsWindow, self).__init__( @@ -506,7 +510,7 @@ class SolverLogEnsWindow(SolverLogWindow): self.statusbar.showMessage( ("Done" if int_code == 0 else "Failed") - + f"#{self._last_run}", + + f" #{self._last_run}", 3000 ) @@ -520,38 +524,79 @@ class SolverLogEnsWindow(SolverLogWindow): if self._last_run < self._run_number: self.next() else: + self._results = self.fill_results_from_tables() + self._parent.set_results(self._solver, self._results) + self._progress_bar.setValue(self._last_run) + def fill_results_from_tables(self): + tables = self._results_tables + results = self._solver.get_ensemble_empty_results( + self._study, self._workdir + ) + + table = {} + + table["Z"] = results.new_table_data("Z", tables["z_mean"]) + table["Q"] = results.new_table_data("Q", tables["q_mean"]) + + table["z_min"] = results.new_table_data("z_min", tables["z_min"]) + table["q_min"] = results.new_table_data("q_min", tables["q_min"]) + table["z_max"] = results.new_table_data("z_max", tables["z_max"]) + table["q_max"] = results.new_table_data("q_max", tables["q_max"]) + + for nb, data in tables["traces"]: + name = f"{nb}_" + table[name + "z"] = results.new_table_data(name + "z", data["Z"]) + table[name + "q"] = results.new_table_data(name + "q", data["Q"]) + + table["samples"] = results.new_table_data( + "samples", np.array(self._run_samples) + ) + + results.set("table", table) + + return results + def next(self): self._process = self.new_process(self._parent) self._log(f" *** Run #{self._last_run}", color="blue") if self._solver._type in ["mage8"]: - self._solver.export_ensemble_variation( + samples = self._solver.export_ensemble_variation( self._study, self._workdir, qlog=self._output, samples=self._samples, ) else: - self.ensemble_variation() + samples = self.ensemble_variation() self._solver.export( self._study, self._workdir, qlog=self._output ) + # Keep samples generators results + self._run_samples.append(samples) + self._solver.run( self._study, process=self._process, output_queue=self._output ) + + self.set_running_button_status() + self._last_run += 1 self._progress_bar.setValue(self._last_run - 1) def ensemble_variation(self): + samples = [] + for ens in self._samples: if ens.target_data is None: continue x = next(self._samples[ens]) + samples.append(x) self._log(f"*** Variation #{self._last_run} " + f"'{ens.target_data}' - {ens.data_type} x {x}", @@ -562,6 +607,8 @@ class SolverLogEnsWindow(SolverLogWindow): elif ens.data_type == "strickler_medium": ens.target_data.medium = x + return samples + def run(self): self._log(f" *** Run solver {self._solver.name}", color="blue") self.next() @@ -587,6 +634,7 @@ class SolverLogEnsWindow(SolverLogWindow): self.next() + def set_running_button_status(self): self.find(QAction, "action_start").setEnabled(False) if _signal: self.find(QAction, "action_pause").setEnabled(True) @@ -606,3 +654,12 @@ class SolverLogEnsWindow(SolverLogWindow): self.find(QAction, "action_results").setEnabled(True) if self._solver.log_file() != "": self.find(QAction, "action_log_file").setEnabled(True) + + def results(self): + if self._results is None: + return + + self._parent.set_results(self._solver, self._results) + self._parent.open_solver_results(self._solver, self._results) + + self._solver.has_results_loaded()