mirror of https://gitlab.com/pamhyr/pamhyr2
Results: Prepare result save.
parent
9c69f2ce6d
commit
3a3c4d9d73
|
|
@ -14,7 +14,9 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import struct
|
||||
import logging
|
||||
import itertools
|
||||
import numpy as np
|
||||
|
||||
from copy import deepcopy
|
||||
|
|
@ -28,12 +30,10 @@ logger = logging.getLogger()
|
|||
|
||||
|
||||
class Results(SQLSubModel):
|
||||
_SQL_TABLE = "solver_results"
|
||||
|
||||
def __init__(self, study=None, solver=None,
|
||||
def __init__(self, id=-1, study=None, solver=None,
|
||||
repertory="", name="0"):
|
||||
super(Results, self).__init__(
|
||||
status=study.status,
|
||||
id=id, status=study.status,
|
||||
owner_scenario=study.status.scenario.id
|
||||
)
|
||||
|
||||
|
|
@ -78,3 +78,122 @@ class Results(SQLSubModel):
|
|||
self._repertory,
|
||||
qlog=None,
|
||||
)
|
||||
|
||||
def timestamps_to_struct(self):
|
||||
ts = self._meta_data["timestamps"]
|
||||
sf = ">" + ''.join(itertools.repeat("d", len(ts)))
|
||||
|
||||
return struct.pack(sf, ts)
|
||||
|
||||
@classmethod
|
||||
def _db_create(cls, execute, ext=""):
|
||||
execute(f"""
|
||||
CREATE TABLE results{ext} (
|
||||
{cls.create_db_add_pamhyr_id()},
|
||||
solver TEXT NOT NULL,
|
||||
study_revision INTEGER NOT NULL,
|
||||
creation_data DATE NOT NULL,
|
||||
nb_timestamps INTEGER NOT NULL,
|
||||
timestamps BLOB NOT NULL,
|
||||
{Scenario.create_db_add_scenario()},
|
||||
{Scenario.create_db_add_scenario_fk()},
|
||||
PRIMARY KEY(pamhyr_id, scenario)
|
||||
)
|
||||
""")
|
||||
|
||||
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)
|
||||
|
||||
return cls._update_submodel(execute, version, data)
|
||||
|
||||
@classmethod
|
||||
def _db_load(cls, execute, data=None):
|
||||
new = []
|
||||
|
||||
study = data['study']
|
||||
status = data['status']
|
||||
scenario = data["scenario"]
|
||||
loaded = data['loaded_pid']
|
||||
|
||||
values = execute(
|
||||
"SELECT pamhyr_id, solver_name, solver_type, " +
|
||||
"study_revision, creation_data, nb_timestamps, timestamps, " +
|
||||
"scenario " +
|
||||
"FROM results " +
|
||||
f"WHERE scenario = {scenario.id} " +
|
||||
f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))}) " +
|
||||
"ORDER BY ind ASC"
|
||||
)
|
||||
|
||||
for v in values:
|
||||
it = iter(v)
|
||||
|
||||
pid = next(it)
|
||||
solver = next(it)
|
||||
revision = next(it)
|
||||
creation_date = next(it)
|
||||
nb_timestamps = next(it)
|
||||
timestamps_bytes = next(it)
|
||||
owner_scenario = next(it)
|
||||
|
||||
new_results = cls(
|
||||
id=pid, status=status,
|
||||
owner_scenario=owner_scenario
|
||||
)
|
||||
new_results.set("solver_name", solver_name)
|
||||
new_results.set("solver_type", solver_type)
|
||||
new_results.set("study_revision", revision)
|
||||
new_results.set("creation_date", creation_date)
|
||||
|
||||
sf = ">" + ''.join(itertools.repeat("d", len(nb_timestamps)))
|
||||
ts = struct.unpack(sf, timestamp_bytes)
|
||||
new_results.set("timestamps", ts)
|
||||
|
||||
new_results._river = River._db_load(execute, data)
|
||||
|
||||
loaded.add(pid)
|
||||
new.append(new_results)
|
||||
|
||||
return new
|
||||
|
||||
def _db_save(self, execute, data=None):
|
||||
execute(
|
||||
"DELETED FROM results " +
|
||||
f"WHERE scenario = {self._owner_scenario}"
|
||||
)
|
||||
execute(
|
||||
"DELETED FROM results_data " +
|
||||
f"WHERE scenario = {self._owner_scenario}"
|
||||
)
|
||||
|
||||
pid = self._pamhyr_id
|
||||
if self._solver is None:
|
||||
solver_name = self.get("solver_name")
|
||||
solver_type = self.get("solver_type")
|
||||
else:
|
||||
solver_name = self._solver._name
|
||||
solver_type = self._solver._type
|
||||
|
||||
ts = self.get("timestamps")
|
||||
sf = ">" + ''.join(itertools.repeat("d", len(ts)))
|
||||
|
||||
execute(
|
||||
"INSERT INTO " +
|
||||
"results (pamhyr_id, solver_name, solver_type, " +
|
||||
"study_revision, creation_data, nb_timestamps, timestamps, " +
|
||||
"scenario) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
self._pamhyr_id, solver_name, solver_type,
|
||||
self._owner_scenario.revision, self.get("creation_data"),
|
||||
len(ts), struct.pack(sf, ts), self._owner_scenario
|
||||
)
|
||||
|
||||
data["result"] = self._pamhyr_id
|
||||
self._river._db_save(execute, data)
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -14,15 +14,25 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import struct
|
||||
import logging
|
||||
import itertools
|
||||
|
||||
from functools import reduce
|
||||
from datetime import datetime
|
||||
|
||||
from Model.Tools.PamhyrDB import SQLSubModel
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Profile(object):
|
||||
class Profile(SQLSubModel):
|
||||
def __init__(self, profile, study):
|
||||
super(Profile, self).__init__(
|
||||
id=-1, status=study.status,
|
||||
owner_scenario=study.status.scenario.id
|
||||
)
|
||||
|
||||
self._study = study
|
||||
self._profile = profile # Source profile in the study
|
||||
self._data = {} # Dict of dict {<ts>: {<key>: <value>, ...}, ...}
|
||||
|
|
@ -65,9 +75,122 @@ class Profile(object):
|
|||
def has_sediment(self):
|
||||
return any(map(lambda ts: "sl" in self._data[ts], self._data))
|
||||
|
||||
@classmethod
|
||||
def _db_create(cls, execute, ext=""):
|
||||
execute(f"""
|
||||
CREATE TABLE results_data{ext}(
|
||||
{cls.create_db_add_pamhyr_id()},
|
||||
result INTEGER NOT NULL,
|
||||
key TEXT NOT NULL,
|
||||
reach INTEGER NOT NULL,
|
||||
section INTEGER NOT NULL,
|
||||
len_data INTEGER NOT NULL,
|
||||
data BLOB NOT NULL,
|
||||
{Scenario.create_db_add_scenario()},
|
||||
{Scenario.create_db_add_scenario_fk()},
|
||||
FOREIGN KEY(result) REFERENCES results(pamhyr_id),
|
||||
FOREIGN KEY(reach) REFERENCES river_reach(pamhyr_id),
|
||||
FOREIGN KEY(section)
|
||||
REFERENCES geometry_profileXYZ(pamhyr_id),
|
||||
PRIMARY KEY(pamhyr_id, result, key, scenario)
|
||||
)
|
||||
""")
|
||||
|
||||
class Reach(object):
|
||||
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)
|
||||
|
||||
return cls._update_submodel(execute, version, data)
|
||||
|
||||
@classmethod
|
||||
def _db_load(cls, execute, data=None):
|
||||
new = []
|
||||
|
||||
study = data['study']
|
||||
status = data['status']
|
||||
scenario = data["scenario"]
|
||||
loaded = data['loaded_pid']
|
||||
timestamps = data['timestamps']
|
||||
|
||||
values = execute(
|
||||
"SELECT pamhyr_id, result, key, " +
|
||||
"reach, section, len_data, data, scenario " +
|
||||
"FROM results_data " +
|
||||
f"WHERE scenario = {scenario.id} " +
|
||||
f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))})"
|
||||
)
|
||||
|
||||
for v in values:
|
||||
it = iter(v)
|
||||
|
||||
pid = next(it)
|
||||
result = next(it)
|
||||
key = next(it)
|
||||
reach = next(it)
|
||||
section = next(it)
|
||||
len_data = next(it)
|
||||
data = next(it)
|
||||
owner_scenario = next(it)
|
||||
|
||||
new_data = cls(
|
||||
id=pid, status=status,
|
||||
owner_scenario=owner_scenario
|
||||
)
|
||||
|
||||
sf = ">" + ''.join(itertools.repeat("f", len_data))
|
||||
values = struct.unpack(sf, data)
|
||||
|
||||
for timestamp, value in zip(timestamps, values):
|
||||
new_data.set(timestamp, key, value)
|
||||
|
||||
loaded.add(pid)
|
||||
new.append(new_data)
|
||||
|
||||
return new
|
||||
|
||||
def get_keys(self):
|
||||
return reduce(
|
||||
lambda acc, ts: acc.union(d[ts].keys())
|
||||
)
|
||||
|
||||
def _db_save(self, execute, data=None):
|
||||
pid = self._pamhyr_id
|
||||
result = data["result"]
|
||||
|
||||
for key in self.get_keys():
|
||||
data = self.get_key(key)
|
||||
|
||||
sf = ">" + ''.join(itertools.repeat("f", len(data)))
|
||||
data_bytes = struct.pack(sf, data)
|
||||
|
||||
execute(
|
||||
"INSERT INTO " +
|
||||
"results_data (pamhyr_id, result, , " +
|
||||
"study_revision, key, len_data, data, " +
|
||||
"scenario) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
pid, result, self._owner_scenario.revision,
|
||||
key, len(data), data_bytes,
|
||||
self._owner_scenario
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class Reach(SQLSubModel):
|
||||
def __init__(self, reach, study):
|
||||
super(Reach, self).__init__(
|
||||
id=-1, status=study.status,
|
||||
owner_scenario=study.status.scenario.id
|
||||
)
|
||||
|
||||
self._study = study
|
||||
self._reach = reach # Source reach in the study
|
||||
self._profiles = list(
|
||||
|
|
@ -101,9 +224,31 @@ class Reach(object):
|
|||
def has_sediment(self):
|
||||
return any(map(lambda profile: profile.has_sediment(), self._profiles))
|
||||
|
||||
@classmethod
|
||||
def _db_create(cls, execute, ext=""):
|
||||
return cls._create_submodel(execute)
|
||||
|
||||
class River(object):
|
||||
@classmethod
|
||||
def _db_update(cls, execute, version, data=None):
|
||||
return cls._update_submodel(execute, version, data)
|
||||
|
||||
@classmethod
|
||||
def _db_load(cls, execute, data=None):
|
||||
return cls._db_load(execute, data)
|
||||
|
||||
def _db_save(self, execute, data=None):
|
||||
for profile in self._profiles:
|
||||
data["profile"] = profile.geometry.pamhyr_id
|
||||
profile._db_save(execute, data)
|
||||
|
||||
|
||||
class River(SQLSubModel):
|
||||
def __init__(self, study):
|
||||
super(River, self).__init__(
|
||||
id=-1, status=study.status,
|
||||
owner_scenario=study.status.scenario.id
|
||||
)
|
||||
|
||||
self._study = study
|
||||
|
||||
# Dict with timestamps as key
|
||||
|
|
@ -137,3 +282,20 @@ class River(object):
|
|||
self._reachs
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _db_create(cls, execute, ext=""):
|
||||
return cls._create_submodel(execute)
|
||||
|
||||
@classmethod
|
||||
def _db_update(cls, execute, version, data=None):
|
||||
return cls._update_submodel(execute, version, data)
|
||||
|
||||
@classmethod
|
||||
def _db_load(cls, execute, data=None):
|
||||
return cls._db_load(execute, data)
|
||||
|
||||
def _db_save(self, execute, data=None):
|
||||
for reach in self._reachs:
|
||||
data["reach"] = reach.geometry.pamhyr_id
|
||||
reach._db_save(execute, data)
|
||||
|
|
|
|||
Loading…
Reference in New Issue