From 8e77d31a5a1298cb31f295b449fd71936d50e109 Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Thu, 10 Sep 2026 14:57:48 +0200 Subject: [PATCH] Ensemble: Add normal low and generalise minmaxdialog. --- src/Model/Ensembles/Function.py | 36 +++++++++++++++-- src/Model/Ensembles/FunctionList.py | 1 + src/View/Ensembles/Window.py | 40 +++++++++++-------- src/View/Translate.py | 6 +++ ...nMaxDialog.ui => Ensemble2ParamsDialog.ui} | 12 +++--- 5 files changed, 69 insertions(+), 26 deletions(-) rename src/View/ui/{MinMaxDialog.ui => Ensemble2ParamsDialog.ui} (89%) diff --git a/src/Model/Ensembles/Function.py b/src/Model/Ensembles/Function.py index 12843892..23c58072 100644 --- a/src/Model/Ensembles/Function.py +++ b/src/Model/Ensembles/Function.py @@ -44,11 +44,16 @@ class Function(SQLSubModel): self._name = name self._type = "generic" self._script = script + self._labels = [] @property def name(self): return self._name + @property + def labels(self): + return self._labels + @classmethod def _db_create(cls, execute, ext=""): execute(f""" @@ -154,13 +159,35 @@ class Uniform(Function): name=name, script=script ) - def random(self, ens_range, nb): - lst = ens_range.copy() + self._labels = ["low", "high"] + + def random(self, params, nb): + lst = params.copy() lst.append(nb) return np.random.uniform(*lst) +class Normal(Function): + _sub_classes = [] + + def __init__(self, id: int = -1, + name: str = "normal", script: str = "", + status=None): + super(Normal, self).__init__( + id=id, status=status, + name=name, script=script + ) + + self._labels = ["loc", "scale"] + + def random(self, params, nb): + lst = params.copy() + lst.append(nb) + + return np.random.normal(*lst) + + class Custom(Function): _sub_classes = [] @@ -172,13 +199,14 @@ class Custom(Function): name=name, script=script ) + self._labels = ["custom"] self._type = "custom" - def random(self, ens_range, nb): + def random(self, params, nb): try: # Run script to (re)define the sample function f = eval(self._script) - return f(ens_range, nb) + return f(params, nb) except Exception as e: logger_exception(e) return None # TODO: Raise helpful exception diff --git a/src/Model/Ensembles/FunctionList.py b/src/Model/Ensembles/FunctionList.py index f609c89f..cb614afd 100644 --- a/src/Model/Ensembles/FunctionList.py +++ b/src/Model/Ensembles/FunctionList.py @@ -32,6 +32,7 @@ class FunctionList(PamhyrModelList): # Default functions new._lst = [ Uniform(status=data['status']), + Normal(status=data['status']), ] # DB custom functions diff --git a/src/View/Ensembles/Window.py b/src/View/Ensembles/Window.py index c0df0c1d..86caef66 100644 --- a/src/View/Ensembles/Window.py +++ b/src/View/Ensembles/Window.py @@ -184,25 +184,26 @@ class EnsemblesWindow(PamhyrWindow): for row in rows: try: - dlg = MinMaxDialog( - ensemble=self._ensembles.get(row), + ens = self._ensembles.get(row) + dlg = Ensemble2ParamsDialog( + ensemble=ens, trad=self._trad, parent=self ) if dlg.exec(): - self._ensembles.get(row).params = dlg._minmax + self._ensembles.get(row).params = dlg._values except Exception as e: logger_exception(e) return -class MinMaxDialog(PamhyrDialog): - _pamhyr_ui = "MinMaxDialog" - _pamhyr_name = "Minmax" +class Ensemble2ParamsDialog(PamhyrDialog): + _pamhyr_ui = "Ensemble2ParamsDialog" + _pamhyr_name = "Parameters" def __init__(self, ensemble=None, trad=None, parent=None): - super(MinMaxDialog, self).__init__( + super(Ensemble2ParamsDialog, self).__init__( title=trad[self._pamhyr_name], trad=trad, options=[], @@ -210,23 +211,30 @@ class MinMaxDialog(PamhyrDialog): ) self._ensemble = ensemble + self._labels = ensemble.function.labels + self._init_default_labels() self._init_default_values() + def _init_default_labels(self): + self.set_label_text("label_0", self._trad[self._labels[0]]) + self.set_label_text("label_1", self._trad[self._labels[1]]) + + def _init_default_values(self): - self._minmax = self._ensemble.params - if len(self._minmax) > 0: - self.set_double_spin_box("doubleSpinBox_min", self._minmax[0]) - self.set_double_spin_box("doubleSpinBox_max", self._minmax[1]) + self._values = self._ensemble.params + if len(self._values) > 0: + self.set_double_spin_box("doubleSpinBox_0", self._values[0]) + self.set_double_spin_box("doubleSpinBox_1", self._values[1]) @property - def minmax(self): - return self._minmax + def values(self): + return self._values def accept(self): - self._minmax = [ - self.get_double_spin_box("doubleSpinBox_min"), - self.get_double_spin_box("doubleSpinBox_max") + self._values = [ + self.get_double_spin_box("doubleSpinBox_0"), + self.get_double_spin_box("doubleSpinBox_1") ] super().accept() diff --git a/src/View/Translate.py b/src/View/Translate.py index 7e5b70e5..db86ed3d 100644 --- a/src/View/Translate.py +++ b/src/View/Translate.py @@ -40,6 +40,12 @@ class CommonWordTranslate(PamhyrTranslate): self._dict["time"] = _translate("CommonWord", "Time") self._dict["date"] = _translate("CommonWord", "Date") + self._dict["low"] = _translate("CommonWord", "Low") + self._dict["high"] = _translate("CommonWord", "High") + + self._dict["loc"] = _translate("CommonWord", "Loc") + self._dict["scale"] = _translate("CommonWord", "Scale") + self._dict["reach"] = _translate("CommonWord", "Reach") self._dict["reaches"] = _translate("CommonWord", "Reaches") self._dict["Select reach"] = _translate("CommonWord", "Select reach") diff --git a/src/View/ui/MinMaxDialog.ui b/src/View/ui/Ensemble2ParamsDialog.ui similarity index 89% rename from src/View/ui/MinMaxDialog.ui rename to src/View/ui/Ensemble2ParamsDialog.ui index 1eaab5a3..138067bb 100644 --- a/src/View/ui/MinMaxDialog.ui +++ b/src/View/ui/Ensemble2ParamsDialog.ui @@ -17,14 +17,14 @@ - + - Low: + @param0 - + -100000.000000000000000 @@ -38,14 +38,14 @@ - + - High: + @param1 - + -100000.000000000000000