SolverParameters: Switch to PamhyrID and add scenarios management.

scenarios
Pierre-Antoine Rouby 2024-08-27 09:32:41 +02:00
parent 237b2670f6
commit 8c99268bb8
1 changed files with 168 additions and 83 deletions

View File

@ -21,75 +21,34 @@ from tools import trace, timer
from Solver.Solvers import solver_type_list from Solver.Solvers import solver_type_list
from Model.Scenario import Scenario from Model.Scenario import Scenario
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Tools.PamhyrList import PamhyrModelList from Model.Tools.PamhyrList import PamhyrModelList
class Parameter(): class Parameter(SQLSubModel):
def __init__(self, def __init__(self, id: int = -1,
name="", value="", name="", value="",
status=None): status=None, owner_scenario=-1):
self._status = status super(Parameter, self).__init__(
id=id, status=status,
owner_scenario=owner_scenario
)
self._name = name self._name = name
self._value = value self._value = value
@property
def name(self):
return self._name
@property
def value(self):
return self._value
def __getitem__(self, key):
if key == "name":
return self._name
elif key == "value":
return self._value
return None
def __setitem__(self, key, value):
if key == "name":
self._name = str(value)
elif key == "value":
self._value = str(value)
self._status.modified()
@classmethod @classmethod
def from_tuple(cls, data, status): def _db_create(cls, execute, ext=""):
new = cls(status=status)
new["name"] = data[0]
new["value"] = data[1]
return new
class SolverParametersList(PamhyrModelList):
def __init__(self, solver_type=None, status=None):
super(SolverParametersList, self).__init__()
self._status = status
self._solver = solver_type
self._lst = list(
map(
lambda t: Parameter.from_tuple(t, self._status),
solver_type.default_parameters()
)
)
@classmethod
def _db_create(cls, execute):
execute(f""" execute(f"""
CREATE TABLE solver_parameter( CREATE TABLE solver_parameter{ext} (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, pamhyr_id INTEGER NOT NULL,
ind INTEGER NOT NULL, ind INTEGER NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
value TEXT NOT NULL, value TEXT NOT NULL,
solver TEXT NOT NULL, solver TEXT NOT NULL,
{Scenario.create_db_add_scenario()}, {Scenario.create_db_add_scenario()},
{Scenario.create_db_add_scenario_fk()} {Scenario.create_db_add_scenario_fk()},
PRIMARY KEY(pamhyr_id, scenario)
) )
""") """)
@ -130,7 +89,7 @@ class SolverParametersList(PamhyrModelList):
cls._db_update_to_0_0_7(execute, insert) cls._db_update_to_0_0_7(execute, insert)
if release < 14: if release < 14:
cls._db_update_to_0_0_14(execute) cls._db_update_to_0_0_14(execute, data)
return cls._update_submodel(execute, version, data) return cls._update_submodel(execute, version, data)
@ -193,15 +152,153 @@ class SolverParametersList(PamhyrModelList):
ind += 1 ind += 1
@classmethod @classmethod
def _db_update_to_0_0_14(cls, execute): def _db_update_to_0_0_14(cls, execute, data):
Scenario.update_db_add_scenario(execute, "solver_parameter") table = "solver_parameter"
cls.update_db_add_pamhyr_id(execute, table, data)
Scenario.update_db_add_scenario(execute, table)
cls._db_create(execute, ext="_tmp")
execute(
f"INSERT INTO {table}_tmp " +
"(pamhyr_id, ind, name, value, solver, scenario) " +
"SELECT pamhyr_id, ind, name, value, solver, scenario " +
f"FROM {table}"
)
execute(f"DROP TABLE {table}")
execute(f"ALTER TABLE {table}_tmp RENAME TO {table}")
@classmethod @classmethod
def _db_load(cls, execute, data=None): def _db_load(cls, execute, data=None):
status = data["status"] status = data["status"]
scenario = data["scenario"]
loaded = data['loaded_pid']
solver = data['solver']
new = []
if scenario is None:
return new
table = execute(
"SELECT pamhyr_id, ind, name, value, scenario " +
"FROM solver_parameter " +
f"WHERE solver = '{solver}' " +
f"AND scenario = {scenario.id} " +
f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))})"
)
for row in table:
it = iter(row)
pid = next(it)
ind = next(it)
name = next(it)
value = next(it)
owner = next(it)
new.append(
(
ind,
cls(
id=pid, name=name, value=value,
status=status, owner_scenario=owner
)
)
)
loaded.add(pid)
data["scenario"] = scenario.parent
new += cls._db_load(execute, data)
data["scenario"] = scenario
return new
def _db_save(self, execute, data=None):
ind = data["ind"]
solver = data["solver"]
execute(
"INSERT INTO " +
"solver_parameter(pamhyr_id, ind, " +
"name, value, solver, scenario) " +
"VALUES (" +
f"{self.pamhyr_id}, " +
f"{ind}, " +
f"'{self._db_format(self.name)}', " +
f"'{self._db_format(self.value)}', " +
f"'{self._db_format(solver)}', " +
f"{self._status.scenario_id}" +
")"
)
return True
@property
def name(self):
return self._name
@property
def value(self):
return self._value
def __getitem__(self, key):
if key == "name":
return self._name
elif key == "value":
return self._value
return None
def __setitem__(self, key, value):
if key == "name":
self._name = str(value)
elif key == "value":
self._value = str(value)
self.modified()
@classmethod
def from_tuple(cls, data, status):
new = cls(status=status)
new["name"] = data[0]
new["value"] = data[1]
return new
class SolverParametersList(PamhyrModelList):
_sub_classes = [Parameter]
def __init__(self, solver_type=None, status=None):
super(SolverParametersList, self).__init__()
self._status = status
self._solver = solver_type
self._lst = list(
map(
lambda t: Parameter.from_tuple(t, self._status),
solver_type.default_parameters()
)
)
@classmethod
def _db_create(cls, execute, ext=""):
return cls._create_submodel(execute)
@classmethod
def _db_load(cls, execute, data=None):
status = data["status"]
scenario = data["scenario"]
loaded = data['loaded_pid']
solvers = execute("SELECT DISTINCT solver FROM solver_parameter") solvers = execute("SELECT DISTINCT solver FROM solver_parameter")
new = {} new = {}
if scenario is None:
return new
for solver in solvers: for solver in solvers:
solver = solver[0] solver = solver[0]
if solver not in solver_type_list: if solver not in solver_type_list:
@ -210,18 +307,10 @@ class SolverParametersList(PamhyrModelList):
st = solver_type_list[solver] st = solver_type_list[solver]
n = cls(solver_type=st, status=status) n = cls(solver_type=st, status=status)
table = execute( data['solver'] = solver
"SELECT ind, name, value " + lst = Parameter._db_load(execute, data)
"FROM solver_parameter " +
f"WHERE solver = '{solver}'"
)
for row in table: n._lst = list(map(lambda t: t[1], sorted(lst)))
ind = row[0]
name = row[1]
value = row[2]
n.set_value(name, value)
new[solver] = n new[solver] = n
@ -231,22 +320,16 @@ class SolverParametersList(PamhyrModelList):
t = self._solver._type t = self._solver._type
execute( execute(
"DELETE FROM solver_parameter " + "DELETE FROM solver_parameter " +
f"WHERE solver = '{t}'" f"WHERE solver = '{t}' " +
f"AND scenario = {self._status.scenario_id}"
) )
data["solver"] = t
ind = 0 ind = 0
for param in self._lst: for param in self._lst:
sql = ( data["ind"] = ind
"INSERT INTO " + param._db_save(execute, data)
"solver_parameter(ind, name, value, solver) " +
"VALUES (" +
f"{ind}, " +
f"'{self._db_format(param.name)}', " +
f"'{self._db_format(param.value)}', " +
f"'{self._db_format(t)}'" +
")"
)
execute(sql)
ind += 1 ind += 1
return True return True
@ -271,9 +354,9 @@ class SolverParametersList(PamhyrModelList):
def set(self, index, new): def set(self, index, new):
self._lst[index] = new self._lst[index] = new
self._status.modified() new.modified()
def set_value(self, key, value): def set_value(self, pid, key, value, owner):
for p in self._lst: for p in self._lst:
if p["name"] == key: if p["name"] == key:
p["value"] = value p["value"] = value
@ -282,9 +365,11 @@ class SolverParametersList(PamhyrModelList):
self._lst.append( self._lst.append(
Parameter( Parameter(
id=-1,
name=key, name=key,
value=value, value=value,
status=self._status status=self._status,
owner_scenario=self._status.scenario_id
) )
) )
self._status.modified() self._status.modified()