Ensemble: Put ensemble results data into results obj.

scenario-dev-pa
Pierre-Antoine 2026-08-28 10:37:46 +02:00
parent e7b9bc92a2
commit a1d85274b9
4 changed files with 79 additions and 8 deletions

View File

@ -165,7 +165,6 @@ class Uniform(Function):
return r
class Custom(Function):
_sub_classes = []

View File

@ -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"]

View File

@ -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"

View File

@ -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()