From 82fb2bcc48c649c7e8efdd9d90d8d7fafe279f4b Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Rouby Date: Tue, 28 Jul 2026 16:16:02 +0200 Subject: [PATCH] Ensemble: Change function to id and name, minor change and fix. --- src/Model/Ensembles/Ensemble.py | 42 +++++++++++++++-------------- src/Model/Ensembles/EnsembleList.py | 3 --- src/Model/Ensembles/Function.py | 9 ++++++- src/Model/Ensembles/FunctionList.py | 7 ++++- src/Model/Study.py | 11 +++++--- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/Model/Ensembles/Ensemble.py b/src/Model/Ensembles/Ensemble.py index fe851a39..f3225d27 100644 --- a/src/Model/Ensembles/Ensemble.py +++ b/src/Model/Ensembles/Ensemble.py @@ -31,10 +31,7 @@ class Ensemble(SQLSubModel): def __init__(self, id: int = -1, name: str = "", - prob_dist="generic", - function="generic", - range=[], - data_pid=-1, + function=-1, range=[], data_pid=-1, status=None, owner_scenario=-1): super(Ensemble, self).__init__( id=id, status=status, @@ -43,7 +40,6 @@ class Ensemble(SQLSubModel): self._name = name self._type = "generic" - self._prob_dist = prob_dist self._function = function self._range = range self._data_pid = data_pid @@ -56,8 +52,8 @@ class Ensemble(SQLSubModel): deleted BOOLEAN NOT NULL DEFAULT FALSE, name TEXT NOT NULL, type VARCHAR(8) NOT NULL, - prob_dist VARCHAR(8) NOT NULL, - function VARCHAR(8) NOT NULL, + function INTEGER NOT NULL, + function_name VARCHAR(32) NOT NULL, range BLOB NOT NULL, range_len INTEGER NOT NULL, data_pid INTEGER NOT NULL, @@ -87,11 +83,12 @@ class Ensemble(SQLSubModel): def _db_load(cls, execute, data=None): new = [] scenario = data["scenario"] + functions = data["ens_functions"] loaded = data['loaded_pid'] table = execute( "SELECT pamhyr_id, deleted, name, type, " + - "prob_dist, function, range, range_len, data_pid, " + + "function, function_name, range, range_len, data_pid, " + "scenario " + "FROM ensemble " + f"WHERE scenario = {scenario.id} " + @@ -105,18 +102,26 @@ class Ensemble(SQLSubModel): deleted = (next(it) == 1) name = next(it) type = next(it) - prob_dist = next(it) - function = next(it) + fid = next(it) + fname = next(it) range = next(it) range_len = next(it) data_pid = next(it) owner_scenario = next(it) + def fn(f): f.name == fname + if fid != -1: + def fn(f): f.pamhyr_id == fid + + function = next( + filter(fn, functions), + None + ) + rdata = cls._decode_range(range, range_len) new_ensemble = cls( id, name=name, - prob_dist=prob_dist, function=function, range=rdata, status=data["status"], @@ -142,27 +147,24 @@ class Ensemble(SQLSubModel): brange, length = self._encode_range() + fid = self._function.pamhyr_id + if self._function._type == "generic": + fid = -1 + execute( "INSERT INTO " + "ensemble(pamhyr_id, deleted, name, type, " + - " prob_dist, function, range, range_len, " + + " function, function_name, range, range_len, " + " data_pid, scenario) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", self.pamhyr_id, self.is_deleted(), self._name, self._type, - self._prob_dist, self._function, brange, length, + fid, self._function.name, brange, length, self._data_pid, self._status.scenario_id ) return True - def _data_traversal(self, - predicate=lambda obj, data: True, - modifier=lambda obj, data: None, - data={}): - if predicate(self, data): - modifier(self, data) - def _encode_range(self): length = len(self._range) data_format = ">" + ''.join(itertools.repeat("d", length)) diff --git a/src/Model/Ensembles/EnsembleList.py b/src/Model/Ensembles/EnsembleList.py index 14041a84..fde6b5b3 100644 --- a/src/Model/Ensembles/EnsembleList.py +++ b/src/Model/Ensembles/EnsembleList.py @@ -41,9 +41,6 @@ class EnsembleList(PamhyrModelList): f"WHERE scenario = {self._status.scenario_id}" ) - if data is None: - data = {} - for ens in self._lst: ens._db_save(execute, data=data) diff --git a/src/Model/Ensembles/Function.py b/src/Model/Ensembles/Function.py index 9db824bd..ae6d2818 100644 --- a/src/Model/Ensembles/Function.py +++ b/src/Model/Ensembles/Function.py @@ -19,6 +19,7 @@ import struct import logging import itertools +import numpy as np from tools import logger_exception @@ -150,7 +151,13 @@ class Uniform(Function): ) def get_sample(self, dist, ens_range): - return range(ens_range[0], ens_range[1]) + b = ens_range[0] + t = ens_range[1] + n = ens_range[2] + + step = (t - b) / n + + return np.arange(b, t, step) class Custom(Function): diff --git a/src/Model/Ensembles/FunctionList.py b/src/Model/Ensembles/FunctionList.py index 0e04ffbc..7a4f3d8a 100644 --- a/src/Model/Ensembles/FunctionList.py +++ b/src/Model/Ensembles/FunctionList.py @@ -29,7 +29,12 @@ class FunctionList(PamhyrModelList): def _db_load(cls, execute, data=None): new = cls(status=data['status']) - new._lst = [Uniform(status=data['status'])] + # Default functions + new._lst = [ + Uniform(status=data['status']), + ] + + # DB custom functions new._lst += Function._db_load( execute, data ) diff --git a/src/Model/Study.py b/src/Model/Study.py index cb834d8d..2fe1eb44 100644 --- a/src/Model/Study.py +++ b/src/Model/Study.py @@ -87,7 +87,7 @@ class Study(SQLModel): self.scenarios[0] = s0 self.status.scenario = s0 - self._ens_function = FunctionList(status=self.status) + self._ens_functions = FunctionList(status=self.status) self._river = River(status=self.status) else: @@ -400,10 +400,12 @@ class Study(SQLModel): data["loaded_pid"] = set() # Get ensemble function - new._ens_function = FunctionList._db_load( + new._ens_functions = FunctionList._db_load( sql_exec, data=data ) + data["ens_functions"] = new._ens_functions + # Load river data new._river = River._db_load( sql_exec, data=data @@ -466,7 +468,7 @@ class Study(SQLModel): self._save_submodel( [ - self.scenarios, self._ens_function, + self.scenarios, self._ens_functions, self._river ], data=progress @@ -586,7 +588,8 @@ class Study(SQLModel): data = { "status": self.status, "loaded_pid": set(), - "scenario": scenario + "scenario": scenario, + "ens_functions": self._ens_functions, } self.status.start_loading()