Compare commits

..

No commits in common. "6dc42b637a72e23a05061c83cfa4eb07fb934e52" and "9b1fb4e7d24c814ad7be877f4afa837df731a637" have entirely different histories.

4 changed files with 2 additions and 243 deletions

View File

@ -16,6 +16,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from copy import copy
from tools import trace, timer from tools import trace, timer
from Model.Tools.PamhyrListExt import PamhyrModelList from Model.Tools.PamhyrListExt import PamhyrModelList

View File

@ -1,176 +0,0 @@
# Function.py -- Pamhyr
# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
import struct
import logging
import itertools
from tools import logger_exception
from Model.Except import NotImplementedMethodeError
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Scenario import Scenario
logger = logging.getLogger()
class Function(SQLSubModel):
_sub_classes = []
def __init__(self, id: int = -1,
name: str = "", script: str = "",
status=None):
super(Function, self).__init__(
id=id, status=status,
owner_scenario=0
)
self._name = name
self._type = "generic"
self._script = script
@classmethod
def _db_create(cls, execute, ext=""):
execute(f"""
CREATE TABLE ensemble_function{ext} (
{cls.create_db_add_pamhyr_id()},
deleted BOOLEAN NOT NULL DEFAULT FALSE,
name TEXT NOT NULL,
script TEXT NOT NULL,
PRIMARY KEY(pamhyr_id)
)
""")
if ext == "_tmp":
return True
return cls._create_submodel(execute)
@classmethod
def _db_update(cls, execute, version, data=None):
major, minor, release = version.strip().split(".")
if major == "0" and int(minor) < 2:
cls._db_create(execute)
elif major == "0" and int(minor) == 2:
if int(release) < 8:
cls._db_create(execute)
return cls._update_submodel(execute, version, data)
@classmethod
def _db_load(cls, execute, data=None):
new = []
scenario = data["scenario"]
loaded = data['loaded_pid']
table = execute(
"SELECT pamhyr_id, deleted, name, script " +
"FROM ensemble_function " +
f"WHERE pamhyr_id NOT IN ({', '.join(map(str, loaded))})"
)
for row in table:
it = iter(row)
id = next(it)
deleted = (next(it) == 1)
name = next(it)
script = next(it)
new_function = cls(
id, name=name, script=script,
status=data["status"]
)
if deleted:
new_function.set_as_deleted()
loaded.add(id)
new.append(new_function)
return new
def _db_save(self, execute, data=None):
# Only save custom function
if self._type != "custom":
return True
if not self.must_be_saved():
return True
execute(
"INSERT INTO " +
"ensemble_function(pamhyr_id, deleted, " +
" name, script) " +
"VALUES (?, ?, ?, ?)",
self.pamhyr_id, self.is_deleted(),
self._name, self._script
)
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 get_sample(self, r):
raise NotImplementedMethodeError(cls, cls._load)
###########################
# FUNCTION IMPLEMENTATION #
###########################
class Uniform(Function):
_sub_classes = []
def __init__(self, id: int = -1,
name: str = "uniform", script: str = "",
status=None):
super(Uniform, self).__init__(
id=id, status=status,
name=name, script=script
)
def get_sample(self, dist, ens_range):
return range(ens_range[0], ens_range[1])
class Custom(Function):
_sub_classes = []
def __init__(self, id: int = -1,
name: str = "", script: str = "",
status=None):
super(Custom, self).__init__(
id=id, status=status,
name=name, script=script
)
self._type = "custom"
def get_sample(self, dist, ens_range):
try:
# Run script to (re)define the sample function
f = eval(self._script)
return f(dist, ens_range)
except Exception as e:
logger_exception(e)
return None # TODO: Raise helpful exception

View File

@ -1,53 +0,0 @@
# FunctionList.py -- Pamhyr
# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
from tools import trace, timer
from Model.Tools.PamhyrListExt import PamhyrModelList
from Model.Ensembles.Function import *
class FunctionList(PamhyrModelList):
_sub_classes = [Function]
@classmethod
def _db_load(cls, execute, data=None):
new = cls(status=data['status'])
new._lst = [Uniform(status=data['status'])]
new._lst += Function._db_load(
execute, data
)
return new
def _db_save(self, execute, data={}):
execute(
"DELETE FROM ensemble_function"
)
for fun in self._lst:
fun._db_save(execute, data)
return True
def new(self, index):
r = Custom(status=self._status)
self._lst.insert(index, r)
self._status.modified()
return r

View File

@ -33,7 +33,6 @@ from Model.Status import StudyStatus
from Model.Except import NotImplementedMethodeError from Model.Except import NotImplementedMethodeError
from Model.River import River from Model.River import River
from Model.Geometry.Reach import Reach from Model.Geometry.Reach import Reach
from Model.Ensembles.FunctionList import FunctionList
from Model.HydraulicStructures.HydraulicStructures import ( from Model.HydraulicStructures.HydraulicStructures import (
HydraulicStructure HydraulicStructure
) )
@ -51,7 +50,6 @@ class Study(SQLModel):
_sub_classes = [ _sub_classes = [
Scenario, Scenario,
FunctionList,
River, River,
] ]
@ -86,9 +84,6 @@ class Study(SQLModel):
self.scenarios = Scenarios(status=self.status) self.scenarios = Scenarios(status=self.status)
self.scenarios[0] = s0 self.scenarios[0] = s0
self.status.scenario = s0 self.status.scenario = s0
self._ens_function = FunctionList(status=self.status)
self._river = River(status=self.status) self._river = River(status=self.status)
else: else:
self._init_db_file(filename, is_new=False) self._init_db_file(filename, is_new=False)
@ -399,11 +394,6 @@ class Study(SQLModel):
data["scenario"] = scenario data["scenario"] = scenario
data["loaded_pid"] = set() data["loaded_pid"] = set()
# Get ensemble function
new._ens_function = FunctionList._db_load(
sql_exec, data=data
)
# Load river data # Load river data
new._river = River._db_load( new._river = River._db_load(
sql_exec, data=data sql_exec, data=data
@ -465,10 +455,7 @@ class Study(SQLModel):
progress() progress()
self._save_submodel( self._save_submodel(
[ [self.scenarios, self._river],
self.scenarios, self._ens_function,
self._river
],
data=progress data=progress
) )