diff --git a/src/Model/Saved.py b/src/Model/Saved.py
index a1b91fd5..60013cde 100644
--- a/src/Model/Saved.py
+++ b/src/Model/Saved.py
@@ -33,5 +33,5 @@ class SavedStatus(object):
self._saved = True
def modified(self):
- logger.debug("model status set as modified")
+ # logger.debug("model status set as modified")
self._saved = False
diff --git a/src/Solver/ASolver.py b/src/Solver/ASolver.py
index 300bb36c..64cc01cb 100644
--- a/src/Solver/ASolver.py
+++ b/src/Solver/ASolver.py
@@ -19,6 +19,8 @@
import os
import logging
+from tools import timer
+
try:
from signal import SIGTERM, SIGSTOP, SIGCONT
_signal = True
@@ -29,6 +31,9 @@ from enum import Enum
from Model.Except import NotImplementedMethodeError
+from Model.Results.Results import Results
+from Model.Results.River.River import River, Reach, Profile
+
logger = logging.getLogger()
class STATUS(Enum):
@@ -164,6 +169,15 @@ class AbstractSolver(object):
"""
raise NotImplementedMethodeError(self, self.log_file)
+ ###########
+ # RESULTS #
+ ###########
+
+ @timer
+ def results(self, study, repertory, qlog = None):
+ results = Results(study = study)
+ return results
+
#######
# Run #
#######
diff --git a/src/Solver/Mage.py b/src/Solver/Mage.py
index 0d43d2ef..f4e5254f 100644
--- a/src/Solver/Mage.py
+++ b/src/Solver/Mage.py
@@ -17,12 +17,19 @@
# -*- coding: utf-8 -*-
import os
+import logging
+import numpy as np
from tools import timer
from Solver.ASolver import AbstractSolver
from Checker.Mage import MageNetworkGraphChecker
+from Model.Results.Results import Results
+from Model.Results.River.River import River, Reach, Profile
+
+logger = logging.getLogger()
+
def mage_file_open(filepath, mode):
f = open(filepath, mode)
@@ -337,6 +344,21 @@ class Mage(AbstractSolver):
return True
+ ###########
+ # RESULTS #
+ ###########
+
+ def read_bin(self, study, repertory, results, qlog = None):
+ return
+
+ @timer
+ def results(self, study, repertory, qlog = None):
+ results = Results(study = study)
+
+ self.read_bin(study, repertory, results, qlog)
+
+ return results
+
##########
# MAGE 7 #
##########
@@ -450,3 +472,124 @@ class Mage8(Mage):
self._export_REP(study, repertory, files, qlog)
return True
+
+ ###########
+ # RESULTS #
+ ###########
+
+ def read_bin(self, study, repertory, results, qlog = None):
+ with mage_file_open(os.path.join(repertory, f"0.BIN"), "r") as f:
+ logger.info("read_bin: Start ...")
+
+ newline = lambda: np.fromfile(f, dtype=np.int32, count=1)
+ endline = lambda: np.fromfile(f, dtype=np.int32, count=1)
+
+ read_int = lambda size: np.fromfile(f, dtype=np.int32, count=size)
+ read_float = lambda size: np.fromfile(f, dtype=np.float32, count=size)
+ read_float64 = lambda size: np.fromfile(f, dtype=np.float64, count=size)
+
+ # Meta data (1st line)
+ newline()
+
+ data = read_int(3)
+
+ nb_reach = data[0]
+ nb_profile = data[1]
+ mage_version = data[2]
+
+ logger.debug(f"read_bin: nb_reach = {nb_reach}")
+ logger.debug(f"read_bin: nb_profile = {nb_profile}")
+ logger.debug(f"read_bin: mage_version = {mage_version}")
+
+ if mage_version <= 80:
+ msg = (
+ "Read BIN files: " +
+ f"Possible incompatible mage version '{mage_version}', " +
+ "please check your solver configuration..."
+ )
+ logger.warning(msg)
+
+ if qlog is not None:
+ qlog.put("[WARNING] " + msg)
+
+ results.set("solver_version", f"Mage8 ({mage_version})")
+ results.set("nb_reach", f"{nb_reach}")
+ results.set("nb_profile", f"{nb_profile}")
+
+ endline()
+
+ # Reach information (2nd line)
+ newline()
+
+ reachs = []
+ iprofiles = {}
+ reach_offset = {}
+
+ ip_to_r = lambda i: iprofiles[
+ next(
+ filter(
+ lambda k: k[0] <= i <= k[1],
+ iprofiles
+ )
+ )
+ ]
+ ip_to_ri = lambda r, i: i - reach_offset[r]
+
+ data = read_int(2*nb_reach)
+
+ for i in range(nb_reach):
+ # Add results reach to reach list
+ r = results.river.add(i)
+ reachs.append(r)
+
+ # ID of first and last reach profiles
+ i1 = data[2*i] - 1
+ i2 = data[2*i+1] - 1
+
+ # Add profile id correspondance to reach
+ key = (i1, i2)
+ iprofiles[key] = r
+
+ # Profile ID offset
+ reach_offset[r] = i1
+
+ logger.debug(f"read_bin: iprofiles = {iprofiles}")
+
+ endline()
+
+ # X (3rd line)
+ newline()
+ _ = read_float(nb_profile)
+ endline()
+
+ # Z and Y (4th line)
+ newline()
+ _ = read_float(3*nb_profile)
+ endline()
+
+ # Data
+ newline()
+
+ end = False
+ while not end:
+ n = read_int(1)[0]
+ timestamp = read_float64(1)[0]
+ key = bytearray(np.fromfile(f, dtype=np.byte, count=1)).decode()
+ data = read_float(n)
+
+ if key in ['Z', 'Q']:
+ logger.debug(f"read_bin: timestamp = {timestamp} sec")
+
+ for i, d in enumerate(data):
+ # Get reach corresponding to profile ID
+ reach = ip_to_r(i)
+ # Get profile id in reach
+ ri = ip_to_ri(reach, i)
+
+ # Set data for profile RI
+ reach.set(ri, timestamp, key, d)
+
+ endline()
+ end = newline().size <= 0
+
+ logger.info("read_bin: ... end")
diff --git a/src/View/RunSolver/Window.py b/src/View/RunSolver/Window.py
index 4f915950..b03a4603 100644
--- a/src/View/RunSolver/Window.py
+++ b/src/View/RunSolver/Window.py
@@ -16,8 +16,9 @@
# -*- coding: utf-8 -*-
-import tempfile
import os
+import logging
+import tempfile
from queue import Queue
from tools import trace, timer
@@ -53,6 +54,8 @@ except:
_translate = QCoreApplication.translate
+logger = logging.getLogger()
+
class SelectSolverWindow(ASubWindow, ListedSubWindow):
def __init__(self, title="Select solver",
study=None, config=None,
@@ -110,6 +113,8 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self._config = config
self._solver = solver
+ self._results = None
+
super(SolverLogWindow, self).__init__(
name=self._title, ui="SolverLog", parent=parent
)
@@ -169,6 +174,7 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self.find(QAction, "action_pause").triggered.connect(self.pause)
self.find(QAction, "action_stop").triggered.connect(self.stop)
self.find(QAction, "action_log_file").triggered.connect(self.log_file)
+ self.find(QAction, "action_results").triggered.connect(self.results)
self._alarm.timeout.connect(self.update)
@@ -193,6 +199,7 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self.find(QAction, "action_start").setEnabled(True)
self.find(QAction, "action_pause").setEnabled(False)
self.find(QAction, "action_stop").setEnabled(False)
+ self.find(QAction, "action_results").setEnabled(True)
if self._solver.log_file() != "":
self.find(QAction, "action_log_file").setEnabled(True)
@@ -221,6 +228,7 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self.find(QAction, "action_pause").setEnabled(False)
self.find(QAction, "action_stop").setEnabled(True)
self.find(QAction, "action_log_file").setEnabled(False)
+ self.find(QAction, "action_results").setEnabled(False)
def pause(self):
self._log(" *** Pause", color="blue")
@@ -229,6 +237,7 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self.find(QAction, "action_start").setEnabled(True)
self.find(QAction, "action_pause").setEnabled(False)
self.find(QAction, "action_stop").setEnabled(True)
+ self.find(QAction, "action_results").setEnabled(False)
def stop(self):
self._log(" *** Stop", color="blue")
@@ -237,9 +246,13 @@ class SolverLogWindow(ASubMainWindow, ListedSubWindow):
self.find(QAction, "action_start").setEnabled(True)
self.find(QAction, "action_pause").setEnabled(False)
self.find(QAction, "action_stop").setEnabled(False)
+ self.find(QAction, "action_results").setEnabled(True)
if self._solver.log_file() != "":
self.find(QAction, "action_log_file").setEnabled(True)
+ def results(self):
+ self._results = self._solver.results(self._study, self._workdir, qlog = self._output)
+
def log_file(self):
file_name = os.path.join(self._workdir, self._solver.log_file())
log = SolverLogFileWindow(
diff --git a/src/View/ui/SolverLog.ui b/src/View/ui/SolverLog.ui
index bbbc3edb..c94c57db 100644
--- a/src/View/ui/SolverLog.ui
+++ b/src/View/ui/SolverLog.ui
@@ -63,6 +63,7 @@
+
@@ -100,6 +101,11 @@
LogFile
+
+
+ results
+
+