mirror of
https://gitlab.com/pamhyr/pamhyr2.git
synced 2026-10-30 03:20:41 +01:00
Compare commits
No files matched your search
+62
-36
@@ -16,8 +16,9 @@
|
||||
|
||||
stages:
|
||||
- downloads
|
||||
- build
|
||||
- configure
|
||||
- test
|
||||
- build
|
||||
- package
|
||||
- release
|
||||
|
||||
@@ -59,12 +60,12 @@ dl-mage-windows:
|
||||
- mage-windows/mage_extraire.exe
|
||||
- mage-windows/mailleurPF.exe
|
||||
|
||||
#########
|
||||
# BUILD #
|
||||
#########
|
||||
#############
|
||||
# CONFIGURE #
|
||||
#############
|
||||
|
||||
set-version:
|
||||
stage: build
|
||||
stage: configure
|
||||
tags:
|
||||
- linux
|
||||
script:
|
||||
@@ -75,7 +76,7 @@ set-version:
|
||||
- VERSION
|
||||
|
||||
build-lang:
|
||||
stage: build
|
||||
stage: configure
|
||||
tags:
|
||||
- linux
|
||||
script:
|
||||
@@ -85,6 +86,49 @@ build-lang:
|
||||
paths:
|
||||
- src/lang/*.qm
|
||||
|
||||
#########
|
||||
# TESTS #
|
||||
#########
|
||||
|
||||
unittest:
|
||||
stage: test
|
||||
tags:
|
||||
- linux
|
||||
needs:
|
||||
- job: set-version
|
||||
artifacts: true
|
||||
script:
|
||||
- python3 -m venv venv
|
||||
- . venv/bin/activate
|
||||
- pip3 install -U pip
|
||||
- pip3 install -r ./full-requirements.txt
|
||||
- pip3 install -U -r ./full-requirements.txt
|
||||
- cd src
|
||||
- python3 -m unittest discover -t .
|
||||
|
||||
test-pep8:
|
||||
stage: test
|
||||
tags:
|
||||
- linux
|
||||
needs:
|
||||
- job: set-version
|
||||
artifacts: true
|
||||
- job: unittest
|
||||
script:
|
||||
# Setup virtual env
|
||||
- python3 -m venv venv
|
||||
- . venv/bin/activate
|
||||
- pip3 install -U pip
|
||||
- pip3 install -r ./requirements.txt
|
||||
- pip3 install -U -r ./requirements.txt
|
||||
- pip3 install pycodestyle
|
||||
- pycodestyle ./src
|
||||
allow_failure: true
|
||||
|
||||
#########
|
||||
# BUILD #
|
||||
#########
|
||||
|
||||
build-users-doc:
|
||||
stage: build
|
||||
tags:
|
||||
@@ -100,6 +144,7 @@ build-users-doc:
|
||||
- doc/users/documentation.pdf
|
||||
- doc/users/documentation.html
|
||||
- doc/users/images/
|
||||
allow_failure: true
|
||||
|
||||
build-developers-doc:
|
||||
stage: build
|
||||
@@ -113,6 +158,12 @@ build-developers-doc:
|
||||
- ./build.sh
|
||||
# Create html documentation
|
||||
- cd ../../src
|
||||
- python3 -m venv doc-venv
|
||||
- . doc-venv/bin/activate
|
||||
- pip3 install -U pip
|
||||
- pip3 install -r ../full-requirements.txt
|
||||
- pip3 install -U -r ../full-requirements.txt
|
||||
- pip3 install pdoc3
|
||||
- pdoc --html .
|
||||
# Create archive
|
||||
- tar cf html.tar ./html
|
||||
@@ -124,6 +175,7 @@ build-developers-doc:
|
||||
- doc/dev/documentation.html
|
||||
- doc/dev/html.tar
|
||||
- doc/dev/images/
|
||||
allow_failure: true
|
||||
|
||||
build-linux:
|
||||
stage: build
|
||||
@@ -148,6 +200,8 @@ build-linux:
|
||||
# Setup virtual env
|
||||
- python3 -m venv linux-venv
|
||||
- . linux-venv/bin/activate
|
||||
- pip3 install -U pip
|
||||
- pip3 install -r ../requirements.txt
|
||||
- pip3 install -U -r ../requirements.txt
|
||||
# Run Pyinstaller
|
||||
- pyinstaller -y --paths linux-venv/lib/python3.8/site-packages ../src/pamhyr.py
|
||||
@@ -159,6 +213,7 @@ build-linux:
|
||||
- cp -v ../VERSION pamhyr/pamhyr/_internal/
|
||||
- cp -v ../AUTHORS pamhyr/pamhyr/_internal/
|
||||
- cp -v ../LICENSE pamhyr/pamhyr/_internal/
|
||||
- cp -v ../src/motd.txt pamhyr/pamhyr/_internal/
|
||||
# Copy mage
|
||||
- mkdir -p pamhyr/mage
|
||||
- cp -v ../mage-linux/* pamhyr/mage/
|
||||
@@ -218,6 +273,7 @@ build-windows:
|
||||
- mkdir windows
|
||||
- cd windows
|
||||
# Setup env
|
||||
- python -m pip install -r ..\requirements.txt
|
||||
- python -m pip install -U -r ..\requirements.txt
|
||||
# Run Pyinstaller
|
||||
- pyinstaller -y ..\src\pamhyr.py
|
||||
@@ -230,36 +286,6 @@ build-windows:
|
||||
paths:
|
||||
- windows/pamhyr
|
||||
|
||||
#########
|
||||
# TESTS #
|
||||
#########
|
||||
|
||||
# test-windows:
|
||||
# stage: test
|
||||
# tags:
|
||||
# - wine
|
||||
# needs:
|
||||
# - job: set-version
|
||||
# artifacts: true
|
||||
# - job: build-windows
|
||||
# artifacts: true
|
||||
# script:
|
||||
# - cd windows\pamhyr
|
||||
# - pamhyr\pamhyr.exe hello
|
||||
|
||||
# test-linux:
|
||||
# stage: test
|
||||
# tags:
|
||||
# - linux
|
||||
# needs:
|
||||
# - job: set-version
|
||||
# artifacts: true
|
||||
# - job: build-linux
|
||||
# artifacts: true
|
||||
# script:
|
||||
# - cd linux/pamhyr
|
||||
# - ./Pamhyr2 hello
|
||||
|
||||
############
|
||||
# PACKAGES #
|
||||
############
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
PyQt5==5.15.4
|
||||
PyQt5-Qt5==5.15.2
|
||||
PyQt5-sip==12.12.2
|
||||
PyQtWebEngine==5.15.6
|
||||
QScintilla>=2.14.1
|
||||
pyqtgraph>=0.12.1
|
||||
matplotlib>=3.4.1
|
||||
numpy>=1.24.2
|
||||
colorama>=0.4.3
|
||||
pyinstaller>=5.11.0
|
||||
shapely>=2.0.1
|
||||
@@ -25,6 +25,7 @@ echo " *** SETUP ENV"
|
||||
|
||||
python3 -m venv linux-pamhyr-venv
|
||||
. linux-pamhyr-venv/bin/activate
|
||||
pip3 install -U pip
|
||||
pip3 install -r ../requirements.txt
|
||||
|
||||
echo " *** PYINSTALL"
|
||||
@@ -58,6 +59,7 @@ VERSION=$(cat ../VERSION)
|
||||
echo "local-build-$VERSION" > dist/pamhyr/_internal/VERSION
|
||||
cp ../AUTHORS dist/pamhyr/_internal/
|
||||
cp ../LICENSE dist/pamhyr/_internal/
|
||||
cp ../src/motd.txt dist/pamhyr/_internal/
|
||||
|
||||
mkdir -p dist/pamhyr/mage/
|
||||
cp ../mage/mage dist/pamhyr/mage/
|
||||
|
||||
@@ -36,6 +36,7 @@ rem Information
|
||||
copy /y ..\VERSION pamhyr\pamhyr\_internal
|
||||
copy /y ..\AUTHORS pamhyr\pamhyr\_internal
|
||||
copy /y ..\LICENSE pamhyr\pamhyr\_internal
|
||||
copy /y ..\src\motd.txt pamhyr\pamhyr\_internal
|
||||
|
||||
rem MAGE
|
||||
mkdir pamhyr\mage
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
PyQt5==5.15.4
|
||||
PyQt5-Qt5==5.15.2
|
||||
PyQt5-sip==12.12.2
|
||||
PyQtWebEngine==5.15.6
|
||||
#PyQtWebEngine==5.15.6
|
||||
QScintilla>=2.14.1
|
||||
pyqtgraph>=0.12.1
|
||||
matplotlib>=3.4.1
|
||||
numpy>=1.24.2
|
||||
|
||||
@@ -20,12 +20,14 @@ from enum import Enum
|
||||
|
||||
from Model.Except import NotImplementedMethodeError
|
||||
|
||||
|
||||
class STATUS(Enum):
|
||||
UNKNOWN = -1
|
||||
OK = 0
|
||||
WARNING = 1
|
||||
ERROR = 2
|
||||
|
||||
|
||||
class AbstractModelChecker(object):
|
||||
def __init__(self):
|
||||
self._name = ""
|
||||
@@ -62,6 +64,12 @@ class AbstractModelChecker(object):
|
||||
|
||||
# Abstract function
|
||||
|
||||
def _run(self, study):
|
||||
from Model.Study import Study
|
||||
|
||||
thread_study = Study.open(study._filename)
|
||||
self.run(thread_study)
|
||||
|
||||
def run(self, study):
|
||||
"""Run checker function
|
||||
|
||||
|
||||
+6
-3
@@ -27,8 +27,9 @@ from Checker.Checker import AbstractModelChecker, STATUS
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class MageNetworkGraphChecker(AbstractModelChecker):
|
||||
def __init__(self, connectivity = True):
|
||||
def __init__(self, connectivity=True):
|
||||
super(MageNetworkGraphChecker, self).__init__()
|
||||
|
||||
self._mode_conn = connectivity
|
||||
@@ -38,8 +39,10 @@ class MageNetworkGraphChecker(AbstractModelChecker):
|
||||
else:
|
||||
mode = "cycle"
|
||||
|
||||
self._name = _translate("Checker", f"Mage network graph {mode} checker")
|
||||
self._description = _translate("Checker", "Check if the network graph is valid")
|
||||
self._name = _translate(
|
||||
"Checker", f"Mage network graph {mode} checker")
|
||||
self._description = _translate(
|
||||
"Checker", "Check if the network graph is valid")
|
||||
|
||||
@timer
|
||||
def _connectivity(self, summary, status, graph):
|
||||
|
||||
@@ -30,7 +30,8 @@ class StudyNetworkReachChecker(AbstractModelChecker):
|
||||
super(StudyNetworkReachChecker, self).__init__()
|
||||
|
||||
self._name = _translate("Checker", "Study network reach checker")
|
||||
self._description = _translate("Checker", "Check if exists at least one reach for study")
|
||||
self._description = _translate(
|
||||
"Checker", "Check if exists at least one reach for study")
|
||||
|
||||
def run(self, study):
|
||||
if study is None:
|
||||
@@ -54,12 +55,14 @@ class StudyNetworkReachChecker(AbstractModelChecker):
|
||||
self._status = STATUS.OK
|
||||
return True
|
||||
|
||||
|
||||
class StudyGeometryChecker(AbstractModelChecker):
|
||||
def __init__(self):
|
||||
super(StudyGeometryChecker, self).__init__()
|
||||
|
||||
self._name = _translate("Checker", "Study geometry checker")
|
||||
self._description = _translate("Checker", "Check if exists geometry for each reach of study")
|
||||
self._description = _translate(
|
||||
"Checker", "Check if exists geometry for each reach of study")
|
||||
self._reachs = []
|
||||
|
||||
def run(self, study):
|
||||
@@ -128,6 +131,7 @@ class DummyWARNING(AbstractModelChecker):
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class DummyERROR(AbstractModelChecker):
|
||||
def __init__(self):
|
||||
super(DummyERROR, self).__init__()
|
||||
|
||||
@@ -25,12 +25,13 @@ from Model.Except import NotImplementedMethodeError
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class BoundaryCondition(SQLSubModel):
|
||||
_sub_classes = []
|
||||
_id_cnt = 0
|
||||
|
||||
def __init__(self, id:int = -1, name:str = "",
|
||||
status = None):
|
||||
def __init__(self, id: int = -1, name: str = "",
|
||||
status=None):
|
||||
super(BoundaryCondition, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -101,7 +102,7 @@ class BoundaryCondition(SQLSubModel):
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = []
|
||||
tab = data["tab"]
|
||||
|
||||
@@ -115,9 +116,9 @@ class BoundaryCondition(SQLSubModel):
|
||||
t = row[2]
|
||||
ctor = cls._get_ctor_from_type(t)
|
||||
bc = ctor(
|
||||
id = row[0],
|
||||
name = row[1],
|
||||
status = data['status']
|
||||
id=row[0],
|
||||
name=row[1],
|
||||
status=data['status']
|
||||
)
|
||||
|
||||
bc.node = None
|
||||
@@ -143,7 +144,7 @@ class BoundaryCondition(SQLSubModel):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
tab = data["tab"]
|
||||
|
||||
execute(f"DELETE FROM boundary_condition WHERE id = {self.id}")
|
||||
@@ -155,7 +156,7 @@ class BoundaryCondition(SQLSubModel):
|
||||
|
||||
sql = (
|
||||
"INSERT INTO " +
|
||||
"boundary_condition(id, name, type, tab, node) "+
|
||||
"boundary_condition(id, name, type, tab, node) " +
|
||||
"VALUES (" +
|
||||
f"{self.id}, '{self._sql_format(self._name)}', " +
|
||||
f"'{self._sql_format(self._type)}', '{tab}', {node}" +
|
||||
@@ -170,7 +171,7 @@ class BoundaryCondition(SQLSubModel):
|
||||
|
||||
sql = (
|
||||
"INSERT INTO " +
|
||||
"boundary_condition_data(ind, data0, data1, bc) "+
|
||||
"boundary_condition_data(ind, data0, data1, bc) " +
|
||||
f"VALUES ({ind}, '{data0}', {data1}, {self.id})"
|
||||
)
|
||||
execute(sql)
|
||||
@@ -187,7 +188,7 @@ class BoundaryCondition(SQLSubModel):
|
||||
|
||||
@classmethod
|
||||
def time_convert(cls, data):
|
||||
if type(data) == str and data.count(":") == 3:
|
||||
if data is str and data.count(":") == 3:
|
||||
return old_pamhyr_date_to_timestamp(data)
|
||||
|
||||
return int(data)
|
||||
@@ -246,7 +247,7 @@ class BoundaryCondition(SQLSubModel):
|
||||
new_1 = self._default_1
|
||||
|
||||
if len(header) != 0:
|
||||
for i in [0,1]:
|
||||
for i in [0, 1]:
|
||||
for j in range(len(header)):
|
||||
if self._header[i] == header[j]:
|
||||
if i == 0:
|
||||
@@ -259,13 +260,13 @@ class BoundaryCondition(SQLSubModel):
|
||||
|
||||
return (new_0, new_1)
|
||||
|
||||
def add(self, index:int):
|
||||
def add(self, index: int):
|
||||
value = (self._default_0, self._default_1)
|
||||
self._data.insert(index, value)
|
||||
self._status.modified()
|
||||
return value
|
||||
|
||||
def insert(self, index:int, value):
|
||||
def insert(self, index: int, value):
|
||||
self._data.insert(index, value)
|
||||
self._status.modified()
|
||||
|
||||
@@ -301,11 +302,10 @@ class BoundaryCondition(SQLSubModel):
|
||||
return self.data[index]
|
||||
|
||||
def get_range(self, _range):
|
||||
l = []
|
||||
lst = []
|
||||
for r in _range:
|
||||
l.append(r)
|
||||
return l
|
||||
|
||||
lst.append(r)
|
||||
return lst
|
||||
|
||||
def _set_i_c_v(self, index, column, value):
|
||||
v = list(self._data[index])
|
||||
@@ -313,22 +313,22 @@ class BoundaryCondition(SQLSubModel):
|
||||
self._data[index] = tuple(v)
|
||||
self._status.modified()
|
||||
|
||||
def set_i_0(self, index:int, value):
|
||||
def set_i_0(self, index: int, value):
|
||||
self._set_i_c_v(index, 0, value)
|
||||
|
||||
def set_i_1(self, index:int, value):
|
||||
def set_i_1(self, index: int, value):
|
||||
self._set_i_c_v(index, 1, value)
|
||||
|
||||
@timer
|
||||
def convert(self, cls):
|
||||
new = cls(name = self.name, status = self._status)
|
||||
new = cls(name=self.name, status=self._status)
|
||||
new.node = self.node
|
||||
|
||||
for i, _ in enumerate(self.data):
|
||||
new.add(i)
|
||||
|
||||
for i in [0,1]:
|
||||
for j in [0,1]:
|
||||
for i in [0, 1]:
|
||||
for j in [0, 1]:
|
||||
if self._header[i] == new.header[j]:
|
||||
for ind, v in self.data:
|
||||
try:
|
||||
|
||||
@@ -30,6 +30,7 @@ from Model.BoundaryCondition.BoundaryConditionTypes import (
|
||||
Solid,
|
||||
)
|
||||
|
||||
|
||||
class BoundaryConditionList(PamhyrModelListWithTab):
|
||||
_tabs_list = ["liquid", "solid", "suspenssion"]
|
||||
_sub_classes = [
|
||||
@@ -37,8 +38,8 @@ class BoundaryConditionList(PamhyrModelListWithTab):
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
new = cls(status = data['status'])
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(status=data['status'])
|
||||
|
||||
if data is None:
|
||||
data = {}
|
||||
@@ -51,7 +52,7 @@ class BoundaryConditionList(PamhyrModelListWithTab):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
execute("DELETE FROM boundary_condition")
|
||||
|
||||
if data is None:
|
||||
@@ -60,7 +61,7 @@ class BoundaryConditionList(PamhyrModelListWithTab):
|
||||
for tab in self._tabs:
|
||||
data["tab"] = tab
|
||||
for bc in self._tabs[tab]:
|
||||
bc._sql_save(execute, data = data)
|
||||
bc._sql_save(execute, data=data)
|
||||
|
||||
return True
|
||||
|
||||
@@ -73,16 +74,16 @@ class BoundaryConditionList(PamhyrModelListWithTab):
|
||||
def __copy__(self):
|
||||
new = BoundaryConditionList()
|
||||
|
||||
for l in self._tabs:
|
||||
new.tabs[l] = self._tabs[l].copy()
|
||||
for lst in self._tabs:
|
||||
new.tabs[lst] = self._tabs[lst].copy()
|
||||
|
||||
return new
|
||||
|
||||
def __deepcopy__(self):
|
||||
new = BoundaryConditionList()
|
||||
|
||||
for l in self._tabs:
|
||||
new.tabs[l] = self._tabs[l].deepcopy()
|
||||
for lst in self._tabs:
|
||||
new.tabs[lst] = self._tabs[lst].deepcopy()
|
||||
|
||||
return new
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
|
||||
|
||||
|
||||
class NotDefined(BoundaryCondition):
|
||||
def __init__(self, id:int = -1, name:str = "", status = None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(NotDefined, self).__init__(id=id, name=name, status=status)
|
||||
|
||||
self._type = "ND"
|
||||
@@ -32,9 +32,11 @@ class NotDefined(BoundaryCondition):
|
||||
def _default_0(self):
|
||||
return 0.0
|
||||
|
||||
|
||||
class PonctualContribution(BoundaryCondition):
|
||||
def __init__(self, id:int = -1, name:str = "", status = None):
|
||||
super(PonctualContribution, self).__init__(id=id, name=name, status=status)
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(PonctualContribution, self).__init__(
|
||||
id=id, name=name, status=status)
|
||||
|
||||
self._type = "PC"
|
||||
self._header = ["time", "discharge"]
|
||||
@@ -44,8 +46,9 @@ class PonctualContribution(BoundaryCondition):
|
||||
def compatibility(cls):
|
||||
return ["liquid"]
|
||||
|
||||
|
||||
class TimeOverZ(BoundaryCondition):
|
||||
def __init__(self, id:int = -1, name:str = "", status = None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(TimeOverZ, self).__init__(id=id, name=name, status=status)
|
||||
|
||||
self._type = "TZ"
|
||||
@@ -56,9 +59,11 @@ class TimeOverZ(BoundaryCondition):
|
||||
def compatibility(cls):
|
||||
return ["liquid"]
|
||||
|
||||
|
||||
class TimeOverDischarge(BoundaryCondition):
|
||||
def __init__(self, id:int = -1, name:str = "", status = None):
|
||||
super(TimeOverDischarge, self).__init__(id=id, name=name, status=status)
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(TimeOverDischarge, self).__init__(
|
||||
id=id, name=name, status=status)
|
||||
|
||||
self._type = "TD"
|
||||
self._header = ["time", "discharge"]
|
||||
@@ -68,8 +73,9 @@ class TimeOverDischarge(BoundaryCondition):
|
||||
def compatibility(cls):
|
||||
return ["liquid"]
|
||||
|
||||
|
||||
class ZOverDischarge(BoundaryCondition):
|
||||
def __init__(self, id:int = -1, name:str = "", status = None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(ZOverDischarge, self).__init__(id=id, name=name, status=status)
|
||||
|
||||
self._type = "ZD"
|
||||
@@ -86,7 +92,7 @@ class ZOverDischarge(BoundaryCondition):
|
||||
|
||||
|
||||
class Solid(BoundaryCondition):
|
||||
def __init__(self, id:int = -1, name:str = "", status = None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(Solid, self).__init__(id=id, name=name, status=status)
|
||||
|
||||
self.d50 = 0.002
|
||||
|
||||
+11
-5
@@ -45,8 +45,9 @@ def exception_message_box(exception):
|
||||
# Custom error #
|
||||
################
|
||||
|
||||
|
||||
class ExeceptionWithMessageBox(Exception):
|
||||
def __init__(self, title = "Exeception"):
|
||||
def __init__(self, title="Exeception"):
|
||||
self.title = title
|
||||
|
||||
def header(self):
|
||||
@@ -72,7 +73,7 @@ class ExeceptionWithMessageBox(Exception):
|
||||
class NotImplementedMethodeError(ExeceptionWithMessageBox):
|
||||
def __init__(self, obj, func):
|
||||
super(NotImplementedMethodeError, self).__init__(
|
||||
title = _translate("Exception", "Method not implemented")
|
||||
title=_translate("Exception", "Method not implemented")
|
||||
)
|
||||
|
||||
self.obj = obj
|
||||
@@ -81,12 +82,16 @@ class NotImplementedMethodeError(ExeceptionWithMessageBox):
|
||||
self.alert()
|
||||
|
||||
def __str__(self):
|
||||
class_type = self.obj
|
||||
if self.obj.__class__ != type:
|
||||
class_type = self.obj.__class__
|
||||
|
||||
return (
|
||||
_translate("Exception", "Method") +
|
||||
f" '{self.func.__name__}' " +
|
||||
_translate("Exception", "not implemented") +
|
||||
_translate("Exception", "for class") +
|
||||
f" '{self.obj.__class__ if self.obj.__class__ != type else self.obj}'"
|
||||
f" '{class_type}'"
|
||||
)
|
||||
|
||||
def header(self):
|
||||
@@ -104,10 +109,11 @@ class NotImplementedMethodeError(ExeceptionWithMessageBox):
|
||||
f" '{self.obj.__class__}'"
|
||||
)
|
||||
|
||||
|
||||
class FileFormatError(ExeceptionWithMessageBox):
|
||||
def __init__(self, filename, reason):
|
||||
super(FileFormatError, self).__init__(
|
||||
title = _translate("Exception", "FileFormatError")
|
||||
title=_translate("Exception", "FileFormatError")
|
||||
)
|
||||
|
||||
self.reason = reason
|
||||
@@ -137,7 +143,7 @@ class FileFormatError(ExeceptionWithMessageBox):
|
||||
class ClipboardFormatError(ExeceptionWithMessageBox):
|
||||
def __init__(self, mime=None, header=None, data=None):
|
||||
super(ClipboardFormatError, self).__init__(
|
||||
title = _translate("Exception", "Clipboard format error")
|
||||
title=_translate("Exception", "Clipboard format error")
|
||||
)
|
||||
|
||||
self._mime = mime
|
||||
|
||||
@@ -20,8 +20,9 @@ from tools import trace, timer
|
||||
|
||||
from Model.Tools.PamhyrDB import SQLSubModel
|
||||
|
||||
|
||||
class Friction(SQLSubModel):
|
||||
def __init__(self, name:str = "", status = None):
|
||||
def __init__(self, name: str = "", status=None):
|
||||
super(Friction, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -57,7 +58,7 @@ class Friction(SQLSubModel):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = []
|
||||
reach = data["parent"] # Reach object
|
||||
status = data["status"]
|
||||
@@ -78,22 +79,21 @@ class Friction(SQLSubModel):
|
||||
es = next(filter(lambda s: s.id == row[4], stricklers))
|
||||
|
||||
# Create friction
|
||||
sec = cls(status = status)
|
||||
sec = cls(status=status)
|
||||
sec.edge = reach
|
||||
sec.begin_kp = row[1]
|
||||
sec.end_kp = row[2]
|
||||
sec.begin_strickler = bs
|
||||
sec.end_strickler = es
|
||||
|
||||
new[ind] = sec
|
||||
yield ind, sec
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
ind = data["ind"]
|
||||
execute(
|
||||
"INSERT INTO " +
|
||||
"friction(ind, begin_kp, end_kp, reach, begin_strickler, end_strickler) " +
|
||||
"friction(ind, begin_kp, end_kp, " +
|
||||
"reach, begin_strickler, end_strickler) " +
|
||||
"VALUES (" +
|
||||
f"{ind}, {self._begin_kp}, {self._end_kp}, " +
|
||||
f"{self._edge.id}, " +
|
||||
@@ -121,7 +121,7 @@ class Friction(SQLSubModel):
|
||||
self._edge = edge
|
||||
if (edge is not None and
|
||||
self._begin_kp == 0.0 and
|
||||
self._end_kp == 0.0):
|
||||
self._end_kp == 0.0):
|
||||
self._begin_kp = self._edge.reach.get_kp_min()
|
||||
self._end_kp = self._edge.reach.get_kp_max()
|
||||
self._status.modified()
|
||||
|
||||
@@ -28,6 +28,7 @@ from Model.Friction.Friction import Friction
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class FrictionList(PamhyrModelList):
|
||||
_sub_classes = [
|
||||
Friction
|
||||
@@ -46,8 +47,8 @@ class FrictionList(PamhyrModelList):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
new = cls(status = data['status'])
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(status=data['status'])
|
||||
|
||||
new._lst = Friction._sql_load(
|
||||
execute, data
|
||||
@@ -55,7 +56,7 @@ class FrictionList(PamhyrModelList):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
reach = data["reach"]
|
||||
execute(f"DELETE FROM friction WHERE reach = {reach.id}")
|
||||
|
||||
@@ -63,17 +64,37 @@ class FrictionList(PamhyrModelList):
|
||||
ind = 0
|
||||
for friction in self._lst:
|
||||
data["ind"] = ind
|
||||
ok &= friction._sql_save(execute, data = data)
|
||||
ok &= friction._sql_save(execute, data=data)
|
||||
ind += 1
|
||||
|
||||
return ok
|
||||
|
||||
def _get_frictions_list(self):
|
||||
# Frictions list generator is type (int, Point) with the first
|
||||
# element the index of the Point in list
|
||||
return list(
|
||||
map(
|
||||
lambda p: p[1],
|
||||
sorted(
|
||||
self._lst,
|
||||
key=lambda p: p[0]
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def lst(self):
|
||||
if not isinstance(self._lst, list):
|
||||
self._lst = self._get_frictions_list()
|
||||
|
||||
return self._lst
|
||||
|
||||
@property
|
||||
def frictions(self):
|
||||
return self.lst
|
||||
|
||||
def new(self, index):
|
||||
n = Friction(status = self._status)
|
||||
n = Friction(status=self._status)
|
||||
self._lst.insert(index, n)
|
||||
self._status.modified()
|
||||
return n
|
||||
@@ -18,8 +18,9 @@
|
||||
|
||||
from Model.Except import NotImplementedMethodeError
|
||||
|
||||
|
||||
class Point(object):
|
||||
def __init__(self, name:str = "", profile=None, status = None):
|
||||
def __init__(self, name: str = "", profile=None, status=None):
|
||||
super(Point, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -28,7 +29,6 @@ class Point(object):
|
||||
self._profile = profile
|
||||
self._sl = None
|
||||
|
||||
|
||||
@property
|
||||
def sl(self):
|
||||
if self._sl is None:
|
||||
|
||||
@@ -20,10 +20,11 @@ from math import dist
|
||||
|
||||
from Model.Geometry.Point import Point
|
||||
|
||||
|
||||
class PointAC(Point):
|
||||
def __init__(self, a:float = 0.0, c:float = 0.0,
|
||||
name: str = "", status = None):
|
||||
super(PointXY, self).__init__(name = name, status = status)
|
||||
def __init__(self, a: float = 0.0, c: float = 0.0,
|
||||
name: str = "", status=None):
|
||||
super(PointXY, self).__init__(name=name, status=status)
|
||||
|
||||
self._a = float(a)
|
||||
self._c = float(c)
|
||||
|
||||
@@ -22,12 +22,14 @@ import numpy as np
|
||||
from Model.Tools.PamhyrDB import SQLSubModel
|
||||
from Model.Geometry.Point import Point
|
||||
|
||||
|
||||
class PointXYZ(Point, SQLSubModel):
|
||||
_sub_classes = []
|
||||
|
||||
def __init__(self, x:float = 0.0, y:float = 0.0, z:float = 0.0,
|
||||
name:str = "", profile = None, status = None):
|
||||
super(PointXYZ, self).__init__(name=name, profile=profile, status=status)
|
||||
def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0,
|
||||
name: str = "", profile=None, status=None):
|
||||
super(PointXYZ, self).__init__(
|
||||
name=name, profile=profile, status=status)
|
||||
|
||||
self._x = float(x)
|
||||
self._y = float(y)
|
||||
@@ -69,9 +71,7 @@ class PointXYZ(Point, SQLSubModel):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
points = []
|
||||
|
||||
def _sql_load(cls, execute, data=None):
|
||||
status = data["status"]
|
||||
profile = data["profile"]
|
||||
|
||||
@@ -81,10 +81,6 @@ class PointXYZ(Point, SQLSubModel):
|
||||
f"WHERE profile = {profile.id}"
|
||||
)
|
||||
|
||||
# Create points list
|
||||
for _ in table:
|
||||
points.append(None)
|
||||
|
||||
# Fill points list with new point
|
||||
for row in table:
|
||||
ind = row[0]
|
||||
@@ -95,13 +91,13 @@ class PointXYZ(Point, SQLSubModel):
|
||||
sl = row[5]
|
||||
|
||||
new = cls(
|
||||
name = name,
|
||||
x = x, y = y, z = z,
|
||||
profile = profile,
|
||||
status = status
|
||||
name=name,
|
||||
x=x, y=y, z=z,
|
||||
profile=profile,
|
||||
status=status
|
||||
)
|
||||
|
||||
if sl == -1 or sl == None:
|
||||
if sl == -1 or sl is None:
|
||||
new._sl = None
|
||||
else:
|
||||
new._sl = next(
|
||||
@@ -111,11 +107,9 @@ class PointXYZ(Point, SQLSubModel):
|
||||
)
|
||||
)
|
||||
|
||||
points[ind] = new
|
||||
yield ind, new
|
||||
|
||||
return points
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
profile = data["profile"]
|
||||
ind = data["ind"]
|
||||
|
||||
@@ -123,7 +117,7 @@ class PointXYZ(Point, SQLSubModel):
|
||||
|
||||
sql = (
|
||||
"INSERT OR REPLACE INTO " +
|
||||
"geometry_pointXYZ(ind, name, x, y, z, profile, sl) "+
|
||||
"geometry_pointXYZ(ind, name, x, y, z, profile, sl) " +
|
||||
"VALUES (" +
|
||||
f"{ind}, '{self._sql_format(self._name)}', " +
|
||||
f"{self.x}, {self.y}, {self.z}, " +
|
||||
@@ -134,7 +128,6 @@ class PointXYZ(Point, SQLSubModel):
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@classmethod
|
||||
def from_data(cls, header, data):
|
||||
point = None
|
||||
@@ -157,7 +150,6 @@ class PointXYZ(Point, SQLSubModel):
|
||||
|
||||
return point
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return f"({self._x}, {self._y}, {self._z}, {self._name})"
|
||||
|
||||
|
||||
@@ -25,14 +25,15 @@ from Model.Except import NotImplementedMethodeError
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Profile(object):
|
||||
_id_cnt = 0
|
||||
|
||||
def __init__(self, id:int = -1, num:int = 0,
|
||||
kp:float = 0.0, name:str = "",
|
||||
code1:int = 0, code2:int = 0,
|
||||
_type:str = "", reach = None,
|
||||
status = None):
|
||||
def __init__(self, id: int = -1, num: int = 0,
|
||||
kp: float = 0.0, name: str = "",
|
||||
code1: int = 0, code2: int = 0,
|
||||
_type: str = "", reach=None,
|
||||
status=None):
|
||||
super(Profile, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -57,18 +58,34 @@ class Profile(object):
|
||||
self._profile_type = _type
|
||||
|
||||
def __len__(self):
|
||||
return len(self._points)
|
||||
return len(self.points)
|
||||
|
||||
@property
|
||||
def number_points(self):
|
||||
return len(self._points)
|
||||
return len(self.points)
|
||||
|
||||
def _get_points_list(self):
|
||||
# Points list generator is type (int, Point) with the first
|
||||
# element the index of the Point in list
|
||||
return list(
|
||||
map(
|
||||
lambda p: p[1],
|
||||
sorted(
|
||||
self._points,
|
||||
key=lambda p: p[0]
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def points(self):
|
||||
return self._points.copy()
|
||||
if not isinstance(self._points, list):
|
||||
self._points = self._get_points_list()
|
||||
|
||||
return self._points
|
||||
|
||||
def point(self, index):
|
||||
return self._points[index]
|
||||
return self.points[index]
|
||||
|
||||
@property
|
||||
def reach(self):
|
||||
@@ -115,7 +132,7 @@ class Profile(object):
|
||||
|
||||
@property
|
||||
def nb_points(self):
|
||||
return len(self._points)
|
||||
return len(self.points)
|
||||
|
||||
@property
|
||||
def kp(self):
|
||||
@@ -169,9 +186,9 @@ class Profile(object):
|
||||
self._profile_type = value
|
||||
self._status.modified()
|
||||
|
||||
def point(self, i:int):
|
||||
if i < len(self._points):
|
||||
return self._points[i]
|
||||
def point(self, i: int):
|
||||
if i < len(self.points):
|
||||
return self.points[i]
|
||||
|
||||
return None
|
||||
|
||||
@@ -181,11 +198,10 @@ class Profile(object):
|
||||
Returns:
|
||||
The list of named point
|
||||
"""
|
||||
return [point for point in self._points
|
||||
return [point for point in self.points
|
||||
if point.point_is_named()]
|
||||
|
||||
|
||||
def insert_point(self, index: int, point:Point):
|
||||
def insert_point(self, index: int, point: Point):
|
||||
"""Insert point at index.
|
||||
|
||||
Args:
|
||||
@@ -195,10 +211,9 @@ class Profile(object):
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
self._points.insert(index, point)
|
||||
self.points.insert(index, point)
|
||||
self._status.modified()
|
||||
|
||||
|
||||
def delete(self, indexes: int):
|
||||
"""Delete points at index
|
||||
|
||||
@@ -218,7 +233,7 @@ class Profile(object):
|
||||
)
|
||||
)
|
||||
|
||||
self._points = list(
|
||||
self.points = list(
|
||||
filter(
|
||||
lambda p: p not in points,
|
||||
self.points
|
||||
@@ -235,7 +250,7 @@ class Profile(object):
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
self._points = list(
|
||||
self.points = list(
|
||||
filter(
|
||||
lambda p: p not in points,
|
||||
self.points
|
||||
@@ -246,10 +261,10 @@ class Profile(object):
|
||||
# Move
|
||||
|
||||
def move_up_point(self, index: int):
|
||||
if index < len(self._points):
|
||||
if index < len(self.points):
|
||||
next = index - 1
|
||||
|
||||
p = self._points
|
||||
p = self.points
|
||||
p[index], p[next] = p[next], p[index]
|
||||
self._status.modified()
|
||||
|
||||
@@ -257,7 +272,7 @@ class Profile(object):
|
||||
if index >= 0:
|
||||
prev = index + 1
|
||||
|
||||
p = self._points
|
||||
p = self.points
|
||||
p[index], p[prev] = p[prev], p[index]
|
||||
self._status.modified()
|
||||
|
||||
@@ -265,14 +280,14 @@ class Profile(object):
|
||||
|
||||
@timer
|
||||
def sort(self, column, is_reversed: bool = False):
|
||||
predicate = lambda p: p.x
|
||||
def predicate(p): return p.x
|
||||
if column == 'y':
|
||||
predicate = lambda p: p.y
|
||||
def predicate(p): return p.y
|
||||
elif column == 'z':
|
||||
predicate = lambda p: p.z
|
||||
def predicate(p): return p.z
|
||||
|
||||
self._points = sorted(
|
||||
self._points,
|
||||
self.points = sorted(
|
||||
self.points,
|
||||
key=predicate,
|
||||
reverse=is_reversed
|
||||
)
|
||||
@@ -280,10 +295,10 @@ class Profile(object):
|
||||
|
||||
@timer
|
||||
def sort_with_indexes(self, indexes: list):
|
||||
if len(self._points) != len(indexes):
|
||||
if len(self.points) != len(indexes):
|
||||
logger.critical("Indexes list do not correspond to point list")
|
||||
|
||||
self._points = list(
|
||||
self.points = list(
|
||||
map(
|
||||
lambda x: x[1],
|
||||
sorted(
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
import numpy as np
|
||||
from typing import List
|
||||
|
||||
@@ -27,6 +28,9 @@ from Model.Geometry.Profile import Profile
|
||||
from Model.Geometry.PointXYZ import PointXYZ
|
||||
from Model.Geometry.Vector_1d import Vector1d
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class ProfileXYZ(Profile, SQLSubModel):
|
||||
_sub_classes = [
|
||||
PointXYZ,
|
||||
@@ -36,11 +40,11 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
id: int = -1,
|
||||
name: str = "",
|
||||
kp: float = 0.,
|
||||
reach = None,
|
||||
num = 0,
|
||||
reach=None,
|
||||
num=0,
|
||||
nb_point: int = 0,
|
||||
code1: int = 0, code2: int = 0,
|
||||
status = None):
|
||||
status=None):
|
||||
"""ProfileXYZ constructor
|
||||
|
||||
Args:
|
||||
@@ -54,14 +58,14 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
Nothing.
|
||||
"""
|
||||
super(ProfileXYZ, self).__init__(
|
||||
id = id,
|
||||
num = num,
|
||||
name = name,
|
||||
kp = kp,
|
||||
code1 = code1, code2 = code2,
|
||||
_type = "XYZ",
|
||||
reach = reach,
|
||||
status = status,
|
||||
id=id,
|
||||
num=num,
|
||||
name=name,
|
||||
kp=kp,
|
||||
code1=code1, code2=code2,
|
||||
_type="XYZ",
|
||||
reach=reach,
|
||||
status=status,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -100,7 +104,7 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
profiles = []
|
||||
status = data["status"]
|
||||
reach = data["reach"]
|
||||
@@ -108,7 +112,7 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
table = execute(
|
||||
"SELECT id, ind, name, kp, num, code1, code2, sl " +
|
||||
"FROM geometry_profileXYZ " +
|
||||
f"WHERE reach = {reach}"
|
||||
f"WHERE reach = {reach.id}"
|
||||
)
|
||||
|
||||
for _ in table:
|
||||
@@ -125,14 +129,14 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
sl = row[7]
|
||||
|
||||
new = cls(
|
||||
id=id, num = num,
|
||||
name = name, kp = kp,
|
||||
code1 = code1, code2 = code2,
|
||||
reach = data["parent"],
|
||||
status = status
|
||||
id=id, num=num,
|
||||
name=name, kp=kp,
|
||||
code1=code1, code2=code2,
|
||||
reach=data["parent"],
|
||||
status=status
|
||||
)
|
||||
|
||||
if sl == -1 or sl == None:
|
||||
if sl == -1 or sl is None:
|
||||
new._sl = None
|
||||
else:
|
||||
new._sl = next(
|
||||
@@ -143,13 +147,15 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
)
|
||||
|
||||
data["profile"] = new
|
||||
new._points = PointXYZ._sql_load(execute, data)
|
||||
new._points = PointXYZ._sql_load(execute, data.copy())
|
||||
|
||||
profiles[ind] = new
|
||||
yield ind, new
|
||||
|
||||
return profiles
|
||||
# profiles[ind] = new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
# return profiles
|
||||
|
||||
def _sql_save(self, execute, data=None):
|
||||
ok = True
|
||||
ind = data["ind"]
|
||||
|
||||
@@ -157,7 +163,8 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
|
||||
sql = (
|
||||
"INSERT OR REPLACE INTO " +
|
||||
"geometry_profileXYZ(id, ind, name, reach, kp, num, code1, code2, sl) "+
|
||||
"geometry_profileXYZ(id, ind, name, reach, " +
|
||||
"kp, num, code1, code2, sl) " +
|
||||
"VALUES (" +
|
||||
f"{self.id}, {ind}, '{self._sql_format(self._name)}', " +
|
||||
f"{self.reach.id}, {self.kp}, {self.num}, " +
|
||||
@@ -170,7 +177,7 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
execute(f"DELETE FROM geometry_pointXYZ WHERE profile = {self.id}")
|
||||
|
||||
ind = 0
|
||||
for point in self._points:
|
||||
for point in self.points:
|
||||
data["ind"] = ind
|
||||
ok &= point._sql_save(execute, data)
|
||||
ind += 1
|
||||
@@ -220,18 +227,17 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
|
||||
return point
|
||||
|
||||
|
||||
def x(self):
|
||||
return [point.x for point in self._points]
|
||||
return [point.x for point in self.points]
|
||||
|
||||
def y(self):
|
||||
return [point.y for point in self._points]
|
||||
return [point.y for point in self.points]
|
||||
|
||||
def z(self):
|
||||
return [point.z for point in self._points]
|
||||
return [point.z for point in self.points]
|
||||
|
||||
def names(self):
|
||||
return [point.name for point in self._points]
|
||||
return [point.name for point in self.points]
|
||||
|
||||
def x_max(self):
|
||||
return max(self.filter_isnan(self.x()))
|
||||
@@ -262,7 +268,7 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
"""
|
||||
for point in list_points:
|
||||
pt = PointXYZ(*point, profile=self, status=self._status)
|
||||
self._points.append(pt)
|
||||
self.points.append(pt)
|
||||
self._status.modified()
|
||||
|
||||
def get_point_i(self, index: int) -> PointXYZ:
|
||||
@@ -275,7 +281,7 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
The point.
|
||||
"""
|
||||
try:
|
||||
return self._points[index]
|
||||
return self.points[index]
|
||||
except IndexError:
|
||||
raise IndexError(f"Invalid point index: {index}")
|
||||
|
||||
@@ -286,7 +292,7 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
Nothing.
|
||||
"""
|
||||
point_xyz = PointXYZ(0., 0., 0., profile=self, status=self._status)
|
||||
self._points.append(point_xyz)
|
||||
self.points.append(point_xyz)
|
||||
self._status.modified()
|
||||
|
||||
def insert(self, index: int):
|
||||
@@ -299,7 +305,7 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
The new point.
|
||||
"""
|
||||
point = PointXYZ(0., 0., 0., profile=self, status=self._status)
|
||||
self._points.insert(index, point)
|
||||
self.points.insert(index, point)
|
||||
self._status.modified()
|
||||
return point
|
||||
|
||||
@@ -315,9 +321,9 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
return [x for x in lst if not np.isnan(x)]
|
||||
|
||||
def _first_point_not_nan(self):
|
||||
first_point = self._points[0]
|
||||
first_point = self.points[0]
|
||||
|
||||
for point in self._points:
|
||||
for point in self.points:
|
||||
if not point.is_nan():
|
||||
first_point = point
|
||||
break
|
||||
@@ -325,9 +331,9 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
return first_point
|
||||
|
||||
def _last_point_not_nan(self):
|
||||
last_point = self._points[-1]
|
||||
last_point = self.points[-1]
|
||||
|
||||
for point in self._points[::-1]:
|
||||
for point in self.points[::-1]:
|
||||
if not point.is_nan():
|
||||
last_point = point
|
||||
break
|
||||
@@ -354,13 +360,13 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
first_point_not_nan = self._first_point_not_nan()
|
||||
last_point_not_nan = self._last_point_not_nan()
|
||||
|
||||
for index, point in enumerate(self._points):
|
||||
for index, point in enumerate(self.points):
|
||||
if point.point_is_named():
|
||||
index_first_named_point = index
|
||||
first_named_point = point
|
||||
break
|
||||
|
||||
for point in reversed(self._points):
|
||||
for point in reversed(self.points):
|
||||
if point.point_is_named():
|
||||
last_named_point = point
|
||||
break
|
||||
@@ -369,32 +375,32 @@ class ProfileXYZ(Profile, SQLSubModel):
|
||||
constant = 0.0
|
||||
|
||||
if (first_named_point is not None and
|
||||
last_named_point is not None):
|
||||
last_named_point is not None):
|
||||
if (first_named_point != last_named_point and
|
||||
first_named_point.x != last_named_point.x):
|
||||
first_named_point.x != last_named_point.x):
|
||||
vector = Vector1d(first_named_point, last_named_point)
|
||||
normalized_direction_vec = vector.normalized_direction_vector()
|
||||
norm_dir_vec = vector.normalized_direction_vector()
|
||||
else:
|
||||
vector = Vector1d(first_point_not_nan, last_point_not_nan)
|
||||
normalized_direction_vec = vector.normalized_direction_vector()
|
||||
norm_dir_vec = vector.normalized_direction_vector()
|
||||
|
||||
for point in self._points:
|
||||
for point in self.points:
|
||||
xi = point.x - first_named_point.x
|
||||
yi = point.y - first_named_point.y
|
||||
station_i = (normalized_direction_vec[0] * xi +
|
||||
normalized_direction_vec[1] * yi)
|
||||
station_i = (norm_dir_vec[0] * xi +
|
||||
norm_dir_vec[1] * yi)
|
||||
station.append(station_i)
|
||||
|
||||
constant = station[index_first_named_point]
|
||||
elif first_named_point is None:
|
||||
vector = Vector1d(first_point_not_nan, last_point_not_nan)
|
||||
normalized_direction_vec = vector.normalized_direction_vector()
|
||||
norm_dir_vec = vector.normalized_direction_vector()
|
||||
|
||||
for point in self._points:
|
||||
for point in self.points:
|
||||
xi = point.x - first_point_not_nan.x
|
||||
yi = point.y - first_point_not_nan.y
|
||||
station_i = (normalized_direction_vec[0] * xi +
|
||||
normalized_direction_vec[1] * yi)
|
||||
station_i = (norm_dir_vec[0] * xi +
|
||||
norm_dir_vec[1] * yi)
|
||||
station.append(station_i)
|
||||
|
||||
z_min = self.z_min()
|
||||
|
||||
+56
-35
@@ -36,6 +36,7 @@ from Model.Except import FileFormatError, exception_message_box
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Reach(SQLSubModel):
|
||||
_sub_classes = [
|
||||
ProfileXYZ,
|
||||
@@ -59,17 +60,17 @@ class Reach(SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
new = cls(status = data["status"], parent = data["parent"])
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(status=data["status"], parent=data["parent"])
|
||||
|
||||
new._profiles = ProfileXYZ._sql_load(
|
||||
execute,
|
||||
data = data
|
||||
data=data
|
||||
)
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
# Delete old data
|
||||
execute(f"DELETE FROM geometry_profileXYZ WHERE reach = {self.id}")
|
||||
# execute(f"DELETE FROM geometry_pointXYZ")
|
||||
@@ -78,7 +79,7 @@ class Reach(SQLSubModel):
|
||||
data = {}
|
||||
|
||||
ind = 0
|
||||
for profile in self._profiles:
|
||||
for profile in self.profiles:
|
||||
data["ind"] = ind
|
||||
profile._sql_save(execute, data)
|
||||
ind += 1
|
||||
@@ -94,29 +95,49 @@ class Reach(SQLSubModel):
|
||||
Returns:
|
||||
The profile at index i
|
||||
"""
|
||||
if i < len(self._profiles):
|
||||
return self._profiles[i]
|
||||
if i < len(self.profiles):
|
||||
return self.profiles[i]
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
if self._parent == None:
|
||||
if self._parent is None:
|
||||
return ""
|
||||
|
||||
return self._parent.name
|
||||
|
||||
def _get_profiles_list(self):
|
||||
# Profiles list generator is type (int, Point) with the first
|
||||
# element the index of the Point in list
|
||||
logger.info(f"Load profiles from reach {self.name}")
|
||||
return list(
|
||||
map(
|
||||
lambda p: p[1],
|
||||
sorted(
|
||||
self._profiles,
|
||||
key=lambda p: p[0]
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
def __len__(self):
|
||||
if not isinstance(self._profiles, list):
|
||||
self._profiles = self._get_profiles_list()
|
||||
|
||||
return len(self._profiles)
|
||||
|
||||
@property
|
||||
def profiles(self):
|
||||
return self._profiles.copy()
|
||||
if not isinstance(self._profiles, list):
|
||||
self._profiles = self._get_profiles_list()
|
||||
|
||||
return self._profiles
|
||||
|
||||
def get_profiles_from_kp(self, kp):
|
||||
return list(
|
||||
filter(
|
||||
lambda p: p.kp == kp, self._profiles
|
||||
lambda p: p.kp == kp, self.profiles
|
||||
)
|
||||
)
|
||||
|
||||
@@ -126,14 +147,14 @@ class Reach(SQLSubModel):
|
||||
Returns:
|
||||
Number of profiles
|
||||
"""
|
||||
return len(self._profiles)
|
||||
return len(self.profiles)
|
||||
|
||||
def get_geometry(self) -> List[Profile]:
|
||||
"""
|
||||
Returns:
|
||||
The profiles list.
|
||||
"""
|
||||
return self._profiles
|
||||
return self.profiles
|
||||
|
||||
def _update_profile_numbers(self):
|
||||
"""Update profiles index
|
||||
@@ -155,7 +176,7 @@ class Reach(SQLSubModel):
|
||||
"""
|
||||
profile = ProfileXYZ(reach=self, status=self._status)
|
||||
|
||||
self._profiles.insert(index, profile)
|
||||
self.profiles.insert(index, profile)
|
||||
self._update_profile_numbers()
|
||||
|
||||
self._status.modified()
|
||||
@@ -171,11 +192,10 @@ class Reach(SQLSubModel):
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
self._profiles.insert(index, profile)
|
||||
self.profiles.insert(index, profile)
|
||||
self._update_profile_numbers()
|
||||
self._status.modified()
|
||||
|
||||
|
||||
def delete(self, indexes):
|
||||
"""Delete some elements in profile list
|
||||
|
||||
@@ -195,7 +215,7 @@ class Reach(SQLSubModel):
|
||||
)
|
||||
)
|
||||
|
||||
self._profiles = list(
|
||||
self.profiles = list(
|
||||
filter(
|
||||
lambda p: p not in profiles,
|
||||
self.profiles
|
||||
@@ -213,7 +233,7 @@ class Reach(SQLSubModel):
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
self._profiles = list(
|
||||
self.profiles = list(
|
||||
filter(
|
||||
lambda p: p not in profiles,
|
||||
self.profiles
|
||||
@@ -222,12 +242,11 @@ class Reach(SQLSubModel):
|
||||
self._update_profile_numbers()
|
||||
self._status.modified()
|
||||
|
||||
|
||||
def move_up_profile(self, index: int):
|
||||
if index < len(self.profiles):
|
||||
next = index - 1
|
||||
|
||||
p = self._profiles
|
||||
p = self.profiles
|
||||
p[index], p[next] = p[next], p[index]
|
||||
self._status.modified()
|
||||
|
||||
@@ -235,7 +254,7 @@ class Reach(SQLSubModel):
|
||||
if index >= 0:
|
||||
prev = index + 1
|
||||
|
||||
p = self._profiles
|
||||
p = self.profiles
|
||||
p[index], p[prev] = p[prev], p[index]
|
||||
self._status.modified()
|
||||
|
||||
@@ -278,7 +297,6 @@ class Reach(SQLSubModel):
|
||||
def get_kp_max(self):
|
||||
return max(self.get_kp())
|
||||
|
||||
|
||||
# Sediment Layers
|
||||
|
||||
def get_sl(self):
|
||||
@@ -327,12 +345,12 @@ class Reach(SQLSubModel):
|
||||
for guide in guide_set:
|
||||
self._guidelines[guide] = flatten(
|
||||
map(
|
||||
lambda l: list(
|
||||
lambda lst: list(
|
||||
# Filter point with name (we assume we have
|
||||
# only one point by profile)
|
||||
filter(
|
||||
lambda p: p.name == guide,
|
||||
l
|
||||
lst
|
||||
)
|
||||
),
|
||||
named_points
|
||||
@@ -347,7 +365,7 @@ class Reach(SQLSubModel):
|
||||
Tuple of complete and incomplete guidelines name.
|
||||
"""
|
||||
# Get all point contains into a guideline
|
||||
named_points = [profile.named_points() for profile in self._profiles]
|
||||
named_points = [profile.named_points() for profile in self.profiles]
|
||||
points_name = list(
|
||||
map(
|
||||
lambda lst: list(map(lambda p: p.name, lst)),
|
||||
@@ -367,7 +385,9 @@ class Reach(SQLSubModel):
|
||||
reduce(
|
||||
lambda acc, h: acc + h,
|
||||
map(
|
||||
lambda l: list(set(l).symmetric_difference(guide_set)),
|
||||
lambda lst: list(
|
||||
set(lst).symmetric_difference(guide_set)
|
||||
),
|
||||
points_name
|
||||
),
|
||||
[]
|
||||
@@ -417,13 +437,12 @@ class Reach(SQLSubModel):
|
||||
def get_guidelines_z(self):
|
||||
return self._map_guidelines_points(lambda p: p.z)
|
||||
|
||||
|
||||
# Sort
|
||||
|
||||
@timer
|
||||
def sort(self, is_reversed: bool = False):
|
||||
self._profiles = sorted(
|
||||
self._profiles,
|
||||
self.profiles = sorted(
|
||||
self.profiles,
|
||||
key=lambda profile: profile.kp,
|
||||
reverse=is_reversed
|
||||
)
|
||||
@@ -431,10 +450,10 @@ class Reach(SQLSubModel):
|
||||
|
||||
@timer
|
||||
def sort_with_indexes(self, indexes: list):
|
||||
if len(self._profiles) != len(indexes):
|
||||
if len(self.profiles) != len(indexes):
|
||||
logger.critical("Indexes list do not correspond to profile list")
|
||||
|
||||
self._profiles = list(
|
||||
self.profiles = list(
|
||||
map(
|
||||
lambda x: x[1],
|
||||
sorted(
|
||||
@@ -452,7 +471,8 @@ class Reach(SQLSubModel):
|
||||
"""Import a geometry from file (.ST or .st)
|
||||
|
||||
Args:
|
||||
file_path_name: The absolute path of geometry file (.ST or .st) to import.
|
||||
file_path_name: The absolute path of geometry file (.ST or .st)
|
||||
to import.
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
@@ -462,7 +482,8 @@ class Reach(SQLSubModel):
|
||||
|
||||
try:
|
||||
list_profile, list_header = self.read_file_st(str(file_path_name))
|
||||
profile_header = ["num", "code1", "code2", "nb_point", "kp", "name"]
|
||||
profile_header = ["num", "code1",
|
||||
"code2", "nb_point", "kp", "name"]
|
||||
|
||||
if list_profile and list_header:
|
||||
for ind, profile in enumerate(list_profile):
|
||||
@@ -474,7 +495,7 @@ class Reach(SQLSubModel):
|
||||
**d, reach=self, status=self._status
|
||||
)
|
||||
prof.import_points(profile)
|
||||
self._profiles.append(prof)
|
||||
self.profiles.append(prof)
|
||||
self._update_profile_numbers()
|
||||
|
||||
self._status.modified()
|
||||
@@ -538,8 +559,8 @@ class Reach(SQLSubModel):
|
||||
# TODO: Move this function to model reach
|
||||
def export_reach(self, filename):
|
||||
with open(f"{filename}", "w") as file_st:
|
||||
for index in range(len(self._profiles)):
|
||||
profile = self._profiles[index]
|
||||
for index in range(len(self.profiles)):
|
||||
profile = self.profiles[index]
|
||||
|
||||
for v in profile.header:
|
||||
file_st.write(f"{v:>6}")
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import numpy as np
|
||||
from Model.Geometry.PointXYZ import PointXYZ
|
||||
|
||||
|
||||
class Vector1d:
|
||||
def __init__(self, a: PointXYZ, b: PointXYZ):
|
||||
self.A = a
|
||||
|
||||
@@ -22,12 +22,13 @@ from functools import reduce
|
||||
|
||||
from Model.Tools.PamhyrDB import SQLSubModel
|
||||
|
||||
|
||||
class Data(SQLSubModel):
|
||||
def __init__(self, name:str = "",
|
||||
comment:str = "", reach = None,
|
||||
kp:float = 0.0, discharge:float = 0.0,
|
||||
height:float = 0.0,
|
||||
status = None):
|
||||
def __init__(self, name: str = "",
|
||||
comment: str = "", reach=None,
|
||||
kp: float = 0.0, discharge: float = 0.0,
|
||||
height: float = 0.0,
|
||||
status=None):
|
||||
super(Data, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -73,7 +74,7 @@ class Data(SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
id = data["reach"].id
|
||||
table = execute(
|
||||
"SELECT ind, name, comment, kp, discharge, height " +
|
||||
@@ -95,25 +96,26 @@ class Data(SQLSubModel):
|
||||
height = row[5]
|
||||
|
||||
d = cls(
|
||||
reach = data["reach"],
|
||||
status = data["status"],
|
||||
name = name,
|
||||
comment = comment,
|
||||
kp = kp,
|
||||
discharge = discharge,
|
||||
height = height,
|
||||
reach=data["reach"],
|
||||
status=data["status"],
|
||||
name=name,
|
||||
comment=comment,
|
||||
kp=kp,
|
||||
discharge=discharge,
|
||||
height=height,
|
||||
)
|
||||
|
||||
new[ind] = d
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
ind = data["ind"]
|
||||
|
||||
execute(
|
||||
"INSERT INTO " +
|
||||
"initial_conditions(ind, name, comment, kp, discharge, height, reach) " +
|
||||
"initial_conditions(ind, name, comment, kp, " +
|
||||
"discharge, height, reach) " +
|
||||
"VALUES (" +
|
||||
f"{ind}, '{self._sql_format(self.name)}', " +
|
||||
f"'{self._sql_format(self._comment)}', " +
|
||||
@@ -124,16 +126,15 @@ class Data(SQLSubModel):
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def copy(self):
|
||||
new = Data(
|
||||
name = self.name,
|
||||
comment = self._comment,
|
||||
kp = self._kp,
|
||||
discharge = self._discharge,
|
||||
height = self._height,
|
||||
reach = self._reach,
|
||||
status = self._status,
|
||||
name=self.name,
|
||||
comment=self._comment,
|
||||
kp=self._kp,
|
||||
discharge=self._discharge,
|
||||
height=self._height,
|
||||
reach=self._reach,
|
||||
status=self._status,
|
||||
)
|
||||
|
||||
return new
|
||||
@@ -173,7 +174,7 @@ class Data(SQLSubModel):
|
||||
|
||||
def _update_from_kp(self):
|
||||
min = self._update_get_min()
|
||||
self._elevation = min - self._height
|
||||
self._elevation = min + self._height
|
||||
|
||||
def _update_from_elevation(self):
|
||||
min = self._update_get_min()
|
||||
@@ -216,7 +217,7 @@ class InitialConditions(SQLSubModel):
|
||||
Data
|
||||
]
|
||||
|
||||
def __init__(self, reach = None, status = None):
|
||||
def __init__(self, reach=None, status=None):
|
||||
super(InitialConditions, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -233,23 +234,21 @@ class InitialConditions(SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(
|
||||
reach = data["reach"],
|
||||
status = data["status"]
|
||||
reach=data["reach"],
|
||||
status=data["status"]
|
||||
)
|
||||
|
||||
new._data = Data._sql_load(
|
||||
execute,
|
||||
data = data
|
||||
data=data
|
||||
)
|
||||
|
||||
if new._data is None:
|
||||
return None
|
||||
if new._data is not None:
|
||||
yield new
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
ok = True
|
||||
|
||||
ind = 0
|
||||
@@ -288,7 +287,7 @@ class InitialConditions(SQLSubModel):
|
||||
self._status.modified()
|
||||
|
||||
def new(self, index):
|
||||
n = Data(reach = self._reach, status = self._status)
|
||||
n = Data(reach=self._reach, status=self._status)
|
||||
self._data.insert(index, n)
|
||||
self._status.modified()
|
||||
|
||||
@@ -321,7 +320,6 @@ class InitialConditions(SQLSubModel):
|
||||
self._data.sort(reverse=reverse, key=key)
|
||||
self._status.modified()
|
||||
|
||||
|
||||
def _data_get(self, key):
|
||||
return list(
|
||||
map(
|
||||
@@ -341,8 +339,8 @@ class InitialConditions(SQLSubModel):
|
||||
|
||||
def _sort_by_z_and_kp(self, profiles):
|
||||
profiles.sort(
|
||||
reverse = False,
|
||||
key = lambda p: p.kp
|
||||
reverse=False,
|
||||
key=lambda p: p.kp
|
||||
)
|
||||
|
||||
first_z = profiles[0].z()
|
||||
@@ -350,11 +348,11 @@ class InitialConditions(SQLSubModel):
|
||||
|
||||
if first_z > last_z:
|
||||
profiles.sort(
|
||||
reverse = True,
|
||||
key = lambda p: p.kp
|
||||
reverse=True,
|
||||
key=lambda p: p.kp
|
||||
)
|
||||
|
||||
def generate_growing_constante_height(self, height:float):
|
||||
def generate_growing_constante_height(self, height: float):
|
||||
self._data = []
|
||||
|
||||
profiles = self._reach.reach.profiles
|
||||
@@ -362,7 +360,7 @@ class InitialConditions(SQLSubModel):
|
||||
|
||||
prev = None
|
||||
for profile in profiles:
|
||||
new = Data(reach = self._reach, status = self._status)
|
||||
new = Data(reach=self._reach, status=self._status)
|
||||
new["kp"] = profile.kp
|
||||
|
||||
if prev is None:
|
||||
@@ -381,11 +379,11 @@ class InitialConditions(SQLSubModel):
|
||||
is_reverse = True
|
||||
|
||||
self._data.sort(
|
||||
reverse = not is_reverse,
|
||||
key = lambda d: d['kp']
|
||||
reverse=not is_reverse,
|
||||
key=lambda d: d['kp']
|
||||
)
|
||||
|
||||
def generate_discharge(self, discharge:float):
|
||||
def generate_discharge(self, discharge: float):
|
||||
self._new = []
|
||||
|
||||
for d in self._data:
|
||||
|
||||
@@ -16,27 +16,29 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import types
|
||||
from copy import copy
|
||||
from tools import trace, timer
|
||||
|
||||
from Model.Tools.PamhyrDict import PamhyrModelDict
|
||||
from Model.InitialConditions.InitialConditions import InitialConditions
|
||||
|
||||
|
||||
class InitialConditionsDict(PamhyrModelDict):
|
||||
_sub_classes = [
|
||||
InitialConditions,
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
new = cls(status = data["status"])
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(status=data["status"])
|
||||
|
||||
for reach in data["edges"]:
|
||||
data["reach"] = reach
|
||||
|
||||
ic = InitialConditions._sql_load(
|
||||
execute,
|
||||
data = data
|
||||
data=data
|
||||
)
|
||||
|
||||
if ic is not None:
|
||||
@@ -44,7 +46,7 @@ class InitialConditionsDict(PamhyrModelDict):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
ok = True
|
||||
if data is None:
|
||||
data = {}
|
||||
@@ -57,7 +59,19 @@ class InitialConditionsDict(PamhyrModelDict):
|
||||
|
||||
return ok
|
||||
|
||||
def get(self, key):
|
||||
if key in self._dict:
|
||||
v = self._dict[key]
|
||||
if isinstance(v, types.GeneratorType):
|
||||
self._dict[key] = list(v)[0]
|
||||
|
||||
return self._dict[key]
|
||||
|
||||
new = self.new(key)
|
||||
self.set(key, new)
|
||||
return new
|
||||
|
||||
def new(self, reach):
|
||||
new = InitialConditions(reach = reach, status = self._status)
|
||||
new = InitialConditions(reach=reach, status=self._status)
|
||||
self.set(reach, new)
|
||||
return new
|
||||
@@ -25,11 +25,12 @@ from Model.Except import NotImplementedMethodeError
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class LateralContribution(SQLSubModel):
|
||||
_sub_classes = []
|
||||
_id_cnt = 0
|
||||
|
||||
def __init__(self, id:int = -1, name:str = "", status = None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(LateralContribution, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -39,7 +40,6 @@ class LateralContribution(SQLSubModel):
|
||||
else:
|
||||
self.id = id
|
||||
|
||||
|
||||
self._name = name
|
||||
self._type = ""
|
||||
self._edge = None
|
||||
@@ -49,7 +49,8 @@ class LateralContribution(SQLSubModel):
|
||||
self._header = []
|
||||
self._types = [float, float]
|
||||
|
||||
LateralContribution._id_cnt = max(LateralContribution._id_cnt + 1, self.id)
|
||||
LateralContribution._id_cnt = max(
|
||||
LateralContribution._id_cnt + 1, self.id)
|
||||
|
||||
@classmethod
|
||||
def _sql_create(cls, execute):
|
||||
@@ -99,7 +100,7 @@ class LateralContribution(SQLSubModel):
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = []
|
||||
tab = data["tab"]
|
||||
|
||||
@@ -112,9 +113,9 @@ class LateralContribution(SQLSubModel):
|
||||
t = row[2]
|
||||
ctor = cls._get_ctor_from_type(t)
|
||||
lc = ctor(
|
||||
id = row[0],
|
||||
name = row[1],
|
||||
status = data['status']
|
||||
id=row[0],
|
||||
name=row[1],
|
||||
status=data['status']
|
||||
)
|
||||
lc.edge = None
|
||||
if row[3] != -1:
|
||||
@@ -141,7 +142,7 @@ class LateralContribution(SQLSubModel):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
tab = data["tab"]
|
||||
|
||||
execute(f"DELETE FROM lateral_contribution WHERE id = {self.id}")
|
||||
@@ -153,7 +154,8 @@ class LateralContribution(SQLSubModel):
|
||||
|
||||
sql = (
|
||||
"INSERT INTO " +
|
||||
"lateral_contribution(id, name, type, tab, edge, begin_kp, end_kp) "+
|
||||
"lateral_contribution(id, name, type, tab, " +
|
||||
"edge, begin_kp, end_kp) " +
|
||||
"VALUES (" +
|
||||
f"{self.id}, '{self._sql_format(self._name)}', " +
|
||||
f"'{self._sql_format(self._type)}', '{tab}', {edge}, " +
|
||||
@@ -169,7 +171,7 @@ class LateralContribution(SQLSubModel):
|
||||
|
||||
sql = (
|
||||
"INSERT INTO " +
|
||||
"lateral_contribution_data(ind, data0, data1, lc) "+
|
||||
"lateral_contribution_data(ind, data0, data1, lc) " +
|
||||
f"VALUES ({ind}, '{data0}', {data1}, {self.id})"
|
||||
)
|
||||
execute(sql)
|
||||
@@ -186,7 +188,7 @@ class LateralContribution(SQLSubModel):
|
||||
|
||||
@classmethod
|
||||
def time_convert(cls, data):
|
||||
if type(data) == str and data.count(":") == 3:
|
||||
if data is str and data.count(":") == 3:
|
||||
return old_pamhyr_date_to_timestamp(data)
|
||||
|
||||
return int(data)
|
||||
@@ -282,7 +284,7 @@ class LateralContribution(SQLSubModel):
|
||||
new_1 = self._default_1
|
||||
|
||||
if len(header) != 0:
|
||||
for i in [0,1]:
|
||||
for i in [0, 1]:
|
||||
for j in range(len(header)):
|
||||
if self._header[i] == header[j]:
|
||||
if i == 0:
|
||||
@@ -295,13 +297,13 @@ class LateralContribution(SQLSubModel):
|
||||
|
||||
return (new_0, new_1)
|
||||
|
||||
def add(self, index:int):
|
||||
def add(self, index: int):
|
||||
value = (self._default_0, self._default_1)
|
||||
self._data.insert(index, value)
|
||||
self._status.modified()
|
||||
return value
|
||||
|
||||
def insert(self, index:int, value):
|
||||
def insert(self, index: int, value):
|
||||
self._data.insert(index, value)
|
||||
self._status.modified()
|
||||
|
||||
@@ -337,11 +339,10 @@ class LateralContribution(SQLSubModel):
|
||||
return self.data[index]
|
||||
|
||||
def get_range(self, _range):
|
||||
l = []
|
||||
lst = []
|
||||
for r in _range:
|
||||
l.append(r)
|
||||
return l
|
||||
|
||||
lst.append(r)
|
||||
return lst
|
||||
|
||||
def _set_i_c_v(self, index, column, value):
|
||||
v = list(self._data[index])
|
||||
@@ -349,15 +350,15 @@ class LateralContribution(SQLSubModel):
|
||||
self._data[index] = tuple(v)
|
||||
self._status.modified()
|
||||
|
||||
def set_i_0(self, index:int, value):
|
||||
def set_i_0(self, index: int, value):
|
||||
self._set_i_c_v(index, 0, value)
|
||||
|
||||
def set_i_1(self, index:int, value):
|
||||
def set_i_1(self, index: int, value):
|
||||
self._set_i_c_v(index, 1, value)
|
||||
|
||||
@timer
|
||||
def convert(self, cls):
|
||||
new = cls(name = self.name, status = self._status)
|
||||
new = cls(name=self.name, status=self._status)
|
||||
new.edge = self.edge
|
||||
new.begin_kp = self.begin_kp
|
||||
new.end_kp = self.end_kp
|
||||
@@ -365,8 +366,8 @@ class LateralContribution(SQLSubModel):
|
||||
for i, _ in enumerate(self.data):
|
||||
new.add(i)
|
||||
|
||||
for i in [0,1]:
|
||||
for j in [0,1]:
|
||||
for i in [0, 1]:
|
||||
for j in [0, 1]:
|
||||
if self._header[i] == new.header[j]:
|
||||
for ind, v in self.data:
|
||||
try:
|
||||
|
||||
@@ -27,6 +27,7 @@ from Model.LateralContribution.LateralContributionTypes import (
|
||||
NotDefined, LateralContrib, Rain, Evaporation,
|
||||
)
|
||||
|
||||
|
||||
class LateralContributionList(PamhyrModelListWithTab):
|
||||
_tabs_list = ["liquid", "solid", "suspenssion"]
|
||||
_sub_classes = [
|
||||
@@ -34,8 +35,8 @@ class LateralContributionList(PamhyrModelListWithTab):
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
new = cls(status = data['status'])
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(status=data['status'])
|
||||
|
||||
if data is None:
|
||||
data = {}
|
||||
@@ -48,7 +49,7 @@ class LateralContributionList(PamhyrModelListWithTab):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
execute("DELETE FROM lateral_contribution")
|
||||
|
||||
if data is None:
|
||||
@@ -57,7 +58,7 @@ class LateralContributionList(PamhyrModelListWithTab):
|
||||
for tab in self._tabs:
|
||||
data["tab"] = tab
|
||||
for lc in self._tabs[tab]:
|
||||
lc._sql_save(execute, data = data)
|
||||
lc._sql_save(execute, data=data)
|
||||
|
||||
return True
|
||||
|
||||
@@ -70,16 +71,16 @@ class LateralContributionList(PamhyrModelListWithTab):
|
||||
def __copy__(self):
|
||||
new = LateralContributionList()
|
||||
|
||||
for l in self._tabs:
|
||||
new.tabs[l] = self._tabs[l].copy()
|
||||
for lst in self._tabs:
|
||||
new.tabs[lst] = self._tabs[lst].copy()
|
||||
|
||||
return new
|
||||
|
||||
def __deepcopy__(self):
|
||||
new = LateralContributionList()
|
||||
|
||||
for l in self._tabs:
|
||||
new.tabs[l] = self._tabs[l].deepcopy()
|
||||
for lst in self._tabs:
|
||||
new.tabs[lst] = self._tabs[lst].deepcopy()
|
||||
|
||||
return new
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ from Model.LateralContribution.LateralContribution import LateralContribution
|
||||
|
||||
|
||||
class NotDefined(LateralContribution):
|
||||
def __init__(self, id:int = -1, name:str = "", status=None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(NotDefined, self).__init__(id=id, name=name, status=status)
|
||||
|
||||
self._type = "ND"
|
||||
@@ -32,8 +32,9 @@ class NotDefined(LateralContribution):
|
||||
def _default_0(self):
|
||||
return 0.0
|
||||
|
||||
|
||||
class LateralContrib(LateralContribution):
|
||||
def __init__(self, id:int = -1, name:str = "", status=None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(LateralContrib, self).__init__(id=id, name=name, status=status)
|
||||
|
||||
self._type = "LC"
|
||||
@@ -44,8 +45,9 @@ class LateralContrib(LateralContribution):
|
||||
def compatibility(cls):
|
||||
return ["liquid"]
|
||||
|
||||
|
||||
class Rain(LateralContribution):
|
||||
def __init__(self, id:int = -1, name:str = "", status=None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(Rain, self).__init__(id=id, name=name, status=status)
|
||||
|
||||
self._type = "RA"
|
||||
@@ -56,8 +58,9 @@ class Rain(LateralContribution):
|
||||
def compatibility(cls):
|
||||
return ["liquid"]
|
||||
|
||||
|
||||
class Evaporation(LateralContribution):
|
||||
def __init__(self, id:int = -1, name:str = "", status=None):
|
||||
def __init__(self, id: int = -1, name: str = "", status=None):
|
||||
super(Evaporation, self).__init__(id=id, name=name, status=status)
|
||||
|
||||
self._type = "EV"
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
|
||||
from Model.Network.Node import Node
|
||||
|
||||
|
||||
class Edge(object):
|
||||
_id_cnt = 0
|
||||
|
||||
def __init__(self, id:int, name:str,
|
||||
node1:Node = None,
|
||||
node2:Node = None,
|
||||
status = None):
|
||||
def __init__(self, id: int, name: str,
|
||||
node1: Node = None,
|
||||
node2: Node = None,
|
||||
status=None):
|
||||
super(Edge, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -74,7 +75,10 @@ class Edge(object):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name if self._name != "" else f"{self.node1.name} -> {self.node2.name}"
|
||||
name = self._name
|
||||
if self._name == "":
|
||||
name = f"{self.node1.name} -> {self.node2.name}"
|
||||
return name
|
||||
|
||||
def is_enable(self):
|
||||
return self._enable
|
||||
|
||||
+15
-15
@@ -21,8 +21,9 @@ from functools import reduce
|
||||
from Model.Network.Node import Node
|
||||
from Model.Network.Edge import Edge
|
||||
|
||||
|
||||
class Graph(object):
|
||||
def __init__(self, status = None):
|
||||
def __init__(self, status=None):
|
||||
super(Graph, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -83,7 +84,7 @@ class Graph(object):
|
||||
False
|
||||
)
|
||||
|
||||
def node(self, node_name:str):
|
||||
def node(self, node_name: str):
|
||||
node = list(
|
||||
filter(
|
||||
lambda n: n.name == node_name,
|
||||
@@ -96,7 +97,7 @@ class Graph(object):
|
||||
|
||||
return node[0]
|
||||
|
||||
def edge(self, edge_name:str):
|
||||
def edge(self, edge_name: str):
|
||||
edge = list(
|
||||
filter(
|
||||
lambda e: e.name == edge_name,
|
||||
@@ -109,12 +110,12 @@ class Graph(object):
|
||||
|
||||
return edge[0]
|
||||
|
||||
def _create_node(self, x:float, y:float):
|
||||
def _create_node(self, x: float, y: float):
|
||||
node = self._node_ctor(
|
||||
-1,
|
||||
"",
|
||||
x = x, y = y,
|
||||
status = self._status
|
||||
x=x, y=y,
|
||||
status=self._status
|
||||
)
|
||||
return node
|
||||
|
||||
@@ -123,14 +124,14 @@ class Graph(object):
|
||||
self._status.modified()
|
||||
return node
|
||||
|
||||
def add_node(self, x:float = 0.0, y:float = 0.0):
|
||||
def add_node(self, x: float = 0.0, y: float = 0.0):
|
||||
node = self._create_node(x, y)
|
||||
return self._add_node(node)
|
||||
|
||||
def insert_node(self, node):
|
||||
return self._add_node(node)
|
||||
|
||||
def remove_node(self, node_name:str):
|
||||
def remove_node(self, node_name: str):
|
||||
self._nodes = list(
|
||||
filter(
|
||||
lambda n: n.name != node_name,
|
||||
@@ -139,19 +140,18 @@ class Graph(object):
|
||||
)
|
||||
self._status.modified()
|
||||
|
||||
def create_node(self, x:float = 0.0, y:float = 0.0):
|
||||
def create_node(self, x: float = 0.0, y: float = 0.0):
|
||||
node = self._create_node(x, y)
|
||||
return node
|
||||
|
||||
def _create_edge(self, n1:Node, n2:Node):
|
||||
def _create_edge(self, n1: Node, n2: Node):
|
||||
edge = self._edge_ctor(
|
||||
-1,
|
||||
"", n1, n2,
|
||||
status = self._status
|
||||
status=self._status
|
||||
)
|
||||
return edge
|
||||
|
||||
|
||||
def _add_edge(self, edge):
|
||||
# This edge already exists ?
|
||||
if any(filter(lambda e: (e.node1 == edge.node1 and
|
||||
@@ -164,17 +164,17 @@ class Graph(object):
|
||||
self._status.modified()
|
||||
return edge
|
||||
|
||||
def add_edge(self, n1:Node, n2:Node):
|
||||
def add_edge(self, n1: Node, n2: Node):
|
||||
edge = self._create_edge(n1, n2)
|
||||
return self._add_edge(edge)
|
||||
|
||||
def insert_edge(self, edge):
|
||||
return self._add_edge(edge)
|
||||
|
||||
def create_edge(self, n1:Node, n2:Node):
|
||||
def create_edge(self, n1: Node, n2: Node):
|
||||
return self._create_edge(n1, n2)
|
||||
|
||||
def remove_edge(self, edge_name:str):
|
||||
def remove_edge(self, edge_name: str):
|
||||
self._edges = list(
|
||||
filter(
|
||||
lambda e: e.name != edge_name,
|
||||
|
||||
@@ -18,12 +18,13 @@
|
||||
|
||||
from Model.Network.Point import Point
|
||||
|
||||
|
||||
class Node(object):
|
||||
_id_cnt = 0
|
||||
|
||||
def __init__(self, id:int, name:str,
|
||||
x:float = 0.0, y:float = 0.0,
|
||||
status = None):
|
||||
def __init__(self, id: int, name: str,
|
||||
x: float = 0.0, y: float = 0.0,
|
||||
status=None):
|
||||
super(Node, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -73,7 +74,6 @@ class Node(object):
|
||||
def y(self):
|
||||
return self.pos.y
|
||||
|
||||
|
||||
def setPos(self, x, y):
|
||||
self.pos.x = x
|
||||
self.pos.y = y
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
class Point(object):
|
||||
def __init__(self, x:float, y:float):
|
||||
def __init__(self, x: float, y: float):
|
||||
super(Point, self).__init__()
|
||||
|
||||
self.x = x
|
||||
|
||||
@@ -24,9 +24,15 @@ from Model.Results.River.River import River
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Results(object):
|
||||
def __init__(self, study = None):
|
||||
def __init__(self, study=None, solver=None,
|
||||
repertory="", name="0"):
|
||||
self._study = study
|
||||
self._solver = solver
|
||||
self._repertory = repertory
|
||||
self._name = name
|
||||
|
||||
self._river = River(self._study)
|
||||
|
||||
self._meta_data = {
|
||||
@@ -52,3 +58,10 @@ class Results(object):
|
||||
|
||||
def get(self, key):
|
||||
return self._meta_data[key]
|
||||
|
||||
def reload(self):
|
||||
return self._solver.results(
|
||||
self._study,
|
||||
self._repertory,
|
||||
qlog=None,
|
||||
)
|
||||
@@ -20,11 +20,12 @@ from datetime import datetime
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Profile(object):
|
||||
def __init__(self, profile, study):
|
||||
self._study = study
|
||||
self._profile = profile # Source profile in the study
|
||||
self._data = {} # Dict of dict {<ts>: {<key>: <value>, ...}, ...}
|
||||
self._profile = profile # Source profile in the study
|
||||
self._data = {} # Dict of dict {<ts>: {<key>: <value>, ...}, ...}
|
||||
|
||||
def __len__(self):
|
||||
return len(self._data)
|
||||
@@ -58,10 +59,11 @@ class Profile(object):
|
||||
def get_ts_key(self, timestamp, key):
|
||||
return self._data[timestamp][key]
|
||||
|
||||
|
||||
class Reach(object):
|
||||
def __init__(self, reach, study):
|
||||
self._study = study
|
||||
self._reach = reach # Source reach in the study
|
||||
self._reach = reach # Source reach in the study
|
||||
self._profiles = list(
|
||||
map(
|
||||
lambda p: Profile(p, self._study),
|
||||
@@ -90,6 +92,7 @@ class Reach(object):
|
||||
def set(self, profile_id, timestamp, key, data):
|
||||
self._profiles[profile_id].set(timestamp, key, data)
|
||||
|
||||
|
||||
class River(object):
|
||||
def __init__(self, study):
|
||||
self._study = study
|
||||
|
||||
+33
-29
@@ -28,7 +28,9 @@ from Model.Geometry.Profile import Profile
|
||||
from Model.Geometry.Reach import Reach
|
||||
|
||||
from Model.BoundaryCondition.BoundaryConditionList import BoundaryConditionList
|
||||
from Model.LateralContribution.LateralContributionList import LateralContributionList
|
||||
from Model.LateralContribution.LateralContributionList import (
|
||||
LateralContributionList
|
||||
)
|
||||
from Model.InitialConditions.InitialConditionsDict import InitialConditionsDict
|
||||
from Model.Stricklers.StricklersList import StricklersList
|
||||
from Model.Friction.FrictionList import FrictionList
|
||||
@@ -37,16 +39,17 @@ from Model.SedimentLayer.SedimentLayerList import SedimentLayerList
|
||||
|
||||
from Solver.Solvers import solver_type_list
|
||||
|
||||
|
||||
class RiverNode(Node, SQLSubModel):
|
||||
_sub_classes = []
|
||||
|
||||
def __init__(self, id:str, name:str,
|
||||
x:float, y:float,
|
||||
status = None):
|
||||
def __init__(self, id: str, name: str,
|
||||
x: float, y: float,
|
||||
status=None):
|
||||
super(RiverNode, self).__init__(
|
||||
id, name,
|
||||
x, y,
|
||||
status = status
|
||||
status=status
|
||||
)
|
||||
|
||||
self._locker = None
|
||||
@@ -70,7 +73,7 @@ class RiverNode(Node, SQLSubModel):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
nodes = []
|
||||
|
||||
table = execute("SELECT id, name, x, y FROM river_node")
|
||||
@@ -82,11 +85,11 @@ class RiverNode(Node, SQLSubModel):
|
||||
|
||||
return nodes
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
sql = (
|
||||
"INSERT OR REPLACE INTO river_node(id, name, x, y) VALUES (" +
|
||||
f"{self.id}, '{self._sql_format(self.name)}', " +
|
||||
f"{self.x}, {self.y}"+
|
||||
f"{self.x}, {self.y}" +
|
||||
")"
|
||||
)
|
||||
execute(sql)
|
||||
@@ -108,18 +111,18 @@ class RiverReach(Edge, SQLSubModel):
|
||||
FrictionList,
|
||||
]
|
||||
|
||||
def __init__(self, id:str, name:str,
|
||||
node1:RiverNode = None,
|
||||
node2:RiverNode = None,
|
||||
status = None):
|
||||
def __init__(self, id: str, name: str,
|
||||
node1: RiverNode = None,
|
||||
node2: RiverNode = None,
|
||||
status=None):
|
||||
super(RiverReach, self).__init__(
|
||||
id, name,
|
||||
node1, node2,
|
||||
status = status
|
||||
status=status
|
||||
)
|
||||
|
||||
self._reach = Reach(status=self._status, parent=self)
|
||||
self._frictions = FrictionList(status = self._status)
|
||||
self._frictions = FrictionList(status=self._status)
|
||||
|
||||
@classmethod
|
||||
def _sql_create(cls, execute):
|
||||
@@ -143,13 +146,14 @@ class RiverReach(Edge, SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
reachs = []
|
||||
|
||||
if data is None:
|
||||
data = {}
|
||||
|
||||
table = execute("SELECT id, name, enable, node1, node2 FROM river_reach")
|
||||
table = execute(
|
||||
"SELECT id, name, enable, node1, node2 FROM river_reach")
|
||||
for row in table:
|
||||
# Update id counter
|
||||
cls._id_cnt = max(cls._id_cnt, row[0])
|
||||
@@ -161,8 +165,8 @@ class RiverReach(Edge, SQLSubModel):
|
||||
node1 = next(filter(lambda n: n.id == row[3], data["nodes"]))
|
||||
node2 = next(filter(lambda n: n.id == row[4], data["nodes"]))
|
||||
|
||||
new = cls(id, name, node1, node2, status = data["status"])
|
||||
new.enable(enable = enable)
|
||||
new = cls(id, name, node1, node2, status=data["status"])
|
||||
new.enable(enable=enable)
|
||||
|
||||
data["reach"] = id
|
||||
data["parent"] = new
|
||||
@@ -174,14 +178,14 @@ class RiverReach(Edge, SQLSubModel):
|
||||
|
||||
return reachs
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
sql = (
|
||||
"INSERT OR REPLACE INTO " +
|
||||
"river_reach(id, name, enable, node1, node2) "+
|
||||
"river_reach(id, name, enable, node1, node2) " +
|
||||
"VALUES (" +
|
||||
f"{self.id}, '{self._sql_format(self._name)}', " +
|
||||
f"{self._sql_format(self.is_enable())},"
|
||||
f"{self.node1.id}, {self.node2.id}"+
|
||||
f"{self.node1.id}, {self.node2.id}" +
|
||||
")"
|
||||
)
|
||||
execute(sql)
|
||||
@@ -202,6 +206,7 @@ class RiverReach(Edge, SQLSubModel):
|
||||
def frictions(self):
|
||||
return self._frictions
|
||||
|
||||
|
||||
class River(Graph, SQLSubModel):
|
||||
_sub_classes = [
|
||||
RiverNode,
|
||||
@@ -223,7 +228,8 @@ class River(Graph, SQLSubModel):
|
||||
|
||||
self._current_reach = None
|
||||
self._boundary_condition = BoundaryConditionList(status=self._status)
|
||||
self._lateral_contribution = LateralContributionList(status=self._status)
|
||||
self._lateral_contribution = LateralContributionList(
|
||||
status=self._status)
|
||||
self._initial_conditions = InitialConditionsDict(status=self._status)
|
||||
self._stricklers = StricklersList(status=self._status)
|
||||
self._parameters = {}
|
||||
@@ -240,7 +246,7 @@ class River(Graph, SQLSubModel):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(data["status"])
|
||||
|
||||
# Stricklers (Stricklers is load in first because it's needed
|
||||
@@ -251,7 +257,6 @@ class River(Graph, SQLSubModel):
|
||||
)
|
||||
data["stricklers"] = new._stricklers
|
||||
|
||||
|
||||
# Initial conditions
|
||||
new._sediment_layers = SedimentLayerList._sql_load(
|
||||
execute,
|
||||
@@ -297,7 +302,7 @@ class River(Graph, SQLSubModel):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
objs = (self._nodes + self._edges)
|
||||
objs.append(self._boundary_condition)
|
||||
objs.append(self._initial_conditions)
|
||||
@@ -344,7 +349,6 @@ class River(Graph, SQLSubModel):
|
||||
|
||||
return ret[0]
|
||||
|
||||
|
||||
@property
|
||||
def parameters(self):
|
||||
return self._parameters
|
||||
@@ -354,8 +358,8 @@ class River(Graph, SQLSubModel):
|
||||
return self._parameters[solver]
|
||||
|
||||
new = SolverParametersList(
|
||||
solver_type = solver_type_list[solver],
|
||||
status = self._status
|
||||
solver_type=solver_type_list[solver],
|
||||
status=self._status
|
||||
)
|
||||
self._parameters[solver] = new
|
||||
self._status.modified()
|
||||
@@ -381,7 +385,7 @@ class River(Graph, SQLSubModel):
|
||||
has = len(self._sediment_layers) != 0
|
||||
has &= any(
|
||||
filter(
|
||||
lambda p: p.sl != None,
|
||||
lambda p: p.sl is not None,
|
||||
flatten(
|
||||
map(lambda e: e.reach.profiles, self.edges())
|
||||
)
|
||||
|
||||
@@ -20,6 +20,7 @@ import logging
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class SavedStatus(object):
|
||||
def __init__(self):
|
||||
super(SavedStatus, self).__init__()
|
||||
|
||||
@@ -5,16 +5,17 @@ from tools import trace, timer
|
||||
from Model.Tools.PamhyrDB import SQLSubModel
|
||||
from Model.Except import NotImplementedMethodeError
|
||||
|
||||
|
||||
class Layer(SQLSubModel):
|
||||
_sub_classes = []
|
||||
_id_cnt = 0
|
||||
|
||||
def __init__(self,
|
||||
id:int = -1, name:str = "",
|
||||
type = "",
|
||||
height = 0.0, d50 = 0.0, sigma = 0.0,
|
||||
critical_constraint = 0.0,
|
||||
sl = None, status = None):
|
||||
id: int = -1, name: str = "",
|
||||
type="",
|
||||
height=0.0, d50=0.0, sigma=0.0,
|
||||
critical_constraint=0.0,
|
||||
sl=None, status=None):
|
||||
super(Layer, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -111,12 +112,13 @@ class Layer(SQLSubModel):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = []
|
||||
sl = data["sl"]
|
||||
|
||||
table = execute(
|
||||
"SELECT id, ind, name, type, height, d50, sigma, critical_constraint " +
|
||||
"SELECT id, ind, name, type, height, " +
|
||||
"d50, sigma, critical_constraint " +
|
||||
"FROM sedimentary_layer_layer " +
|
||||
f"WHERE sl = {sl}"
|
||||
)
|
||||
@@ -128,24 +130,25 @@ class Layer(SQLSubModel):
|
||||
ind = row[1]
|
||||
|
||||
layer = cls(
|
||||
id = row[0], name = row[2],
|
||||
type = row[3], height = row[4],
|
||||
d50 = row[5], sigma = row[6],
|
||||
critical_constraint = row[7],
|
||||
sl = sl, status = data['status']
|
||||
id=row[0], name=row[2],
|
||||
type=row[3], height=row[4],
|
||||
d50=row[5], sigma=row[6],
|
||||
critical_constraint=row[7],
|
||||
sl=sl, status=data['status']
|
||||
)
|
||||
|
||||
new[ind] = layer
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
ind = data["ind"]
|
||||
sl = data["sl"]
|
||||
|
||||
sql = (
|
||||
"INSERT INTO " +
|
||||
"sedimentary_layer_layer(id, ind, name, type, height, d50, sigma, critical_constraint, sl) "+
|
||||
"sedimentary_layer_layer(id, ind, name, type, height, " +
|
||||
"d50, sigma, critical_constraint, sl) " +
|
||||
"VALUES (" +
|
||||
f"{self.id}, {ind}, '{self._sql_format(self._name)}', " +
|
||||
f"'{self._sql_format(self._type)}', {self._height}, " +
|
||||
@@ -162,9 +165,9 @@ class SedimentLayer(SQLSubModel):
|
||||
_sub_classes = [Layer]
|
||||
_id_cnt = 0
|
||||
|
||||
def __init__(self, id:int = -1,
|
||||
name:str = "", comment:str = "",
|
||||
status = None):
|
||||
def __init__(self, id: int = -1,
|
||||
name: str = "", comment: str = "",
|
||||
status=None):
|
||||
super(SedimentLayer, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -196,7 +199,7 @@ class SedimentLayer(SQLSubModel):
|
||||
|
||||
def height(self):
|
||||
return list(
|
||||
map(lambda l: l.height, self._layers)
|
||||
map(lambda layer: layer.height, self._layers)
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -209,7 +212,7 @@ class SedimentLayer(SQLSubModel):
|
||||
|
||||
def names(self):
|
||||
return list(
|
||||
map(lambda l: l.name, self._layers)
|
||||
map(lambda layer: layer.name, self._layers)
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -242,7 +245,7 @@ class SedimentLayer(SQLSubModel):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = []
|
||||
|
||||
table = execute(
|
||||
@@ -252,10 +255,10 @@ class SedimentLayer(SQLSubModel):
|
||||
|
||||
for row in table:
|
||||
sl = cls(
|
||||
id = row[0],
|
||||
name = row[1],
|
||||
comment = row[2],
|
||||
status = data['status']
|
||||
id=row[0],
|
||||
name=row[1],
|
||||
comment=row[2],
|
||||
status=data['status']
|
||||
)
|
||||
|
||||
data["sl"] = sl.id
|
||||
@@ -265,7 +268,7 @@ class SedimentLayer(SQLSubModel):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
if data is None:
|
||||
data = {}
|
||||
|
||||
@@ -279,9 +282,9 @@ class SedimentLayer(SQLSubModel):
|
||||
data["sl"] = self
|
||||
|
||||
ind = 0
|
||||
for l in self._layers:
|
||||
for layer in self._layers:
|
||||
data["ind"] = ind
|
||||
l._sql_save(execute, data)
|
||||
layer._sql_save(execute, data)
|
||||
ind += 1
|
||||
|
||||
return True
|
||||
@@ -298,7 +301,7 @@ class SedimentLayer(SQLSubModel):
|
||||
self._status.modified()
|
||||
|
||||
def new(self, index):
|
||||
n = Layer(sl=self, status = self._status)
|
||||
n = Layer(sl=self, status=self._status)
|
||||
self.insert(index, n)
|
||||
self._status.modified()
|
||||
return n
|
||||
@@ -324,8 +327,8 @@ class SedimentLayer(SQLSubModel):
|
||||
if index >= 0:
|
||||
next = index - 1
|
||||
|
||||
l = self._layers
|
||||
l[index], l[next] = l[next], l[index]
|
||||
lst = self._layers
|
||||
lst[index], lst[next] = lst[next], lst[index]
|
||||
|
||||
self._status.modified()
|
||||
|
||||
@@ -333,7 +336,7 @@ class SedimentLayer(SQLSubModel):
|
||||
if index + 1 < len(self._layers):
|
||||
prev = index + 1
|
||||
|
||||
l = self._layers
|
||||
l[index], l[prev] = l[prev], l[index]
|
||||
lst = self._layers
|
||||
lst[index], lst[prev] = lst[prev], lst[index]
|
||||
|
||||
self._status.modified()
|
||||
@@ -6,18 +6,19 @@ from Model.Except import NotImplementedMethodeError
|
||||
from Model.Tools.PamhyrList import PamhyrModelList
|
||||
from Model.SedimentLayer.SedimentLayer import SedimentLayer
|
||||
|
||||
|
||||
class SedimentLayerList(PamhyrModelList):
|
||||
_sub_classes = [SedimentLayer]
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
new = cls(status = data["status"])
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(status=data["status"])
|
||||
|
||||
new._lst = SedimentLayer._sql_load(execute, data)
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
ok = True
|
||||
|
||||
# Delete previous data
|
||||
@@ -34,7 +35,7 @@ class SedimentLayerList(PamhyrModelList):
|
||||
return self.lst
|
||||
|
||||
def new(self, index):
|
||||
n = SedimentLayer(status = self._status)
|
||||
n = SedimentLayer(status=self._status)
|
||||
self.insert(index, n)
|
||||
self._status.modified()
|
||||
return n
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import pickle
|
||||
|
||||
|
||||
class Serializable():
|
||||
def __init__(self):
|
||||
return
|
||||
|
||||
@@ -22,10 +22,11 @@ from Solver.Solvers import solver_type_list
|
||||
|
||||
from Model.Tools.PamhyrList import PamhyrModelList
|
||||
|
||||
|
||||
class Parameter():
|
||||
def __init__(self,
|
||||
name = "", value = "",
|
||||
status = None):
|
||||
name="", value="",
|
||||
status=None):
|
||||
self._status = status
|
||||
|
||||
self._name = name
|
||||
@@ -57,14 +58,15 @@ class Parameter():
|
||||
|
||||
@classmethod
|
||||
def from_tuple(cls, data, status):
|
||||
new = cls(status = status)
|
||||
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):
|
||||
def __init__(self, solver_type=None, status=None):
|
||||
super(SolverParametersList, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -76,7 +78,6 @@ class SolverParametersList(PamhyrModelList):
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@classmethod
|
||||
def _sql_create(cls, execute):
|
||||
execute("""
|
||||
@@ -97,35 +98,42 @@ class SolverParametersList(PamhyrModelList):
|
||||
|
||||
if major == minor == "0":
|
||||
if int(release) < 3:
|
||||
execute(f"UPDATE solver_parameter SET name='mage_implicitation' WHERE name='mage_implication'")
|
||||
execute(f"UPDATE solver_parameter SET name='mage_iteration_type' WHERE name='mage_iter_type'")
|
||||
execute(
|
||||
"UPDATE solver_parameter SET name='mage_implicitation' " +
|
||||
"WHERE name='mage_implication'"
|
||||
)
|
||||
execute(
|
||||
"UPDATE solver_parameter SET name='mage_iteration_type' " +
|
||||
"WHERE name='mage_iter_type'"
|
||||
)
|
||||
|
||||
if int(release) < 4:
|
||||
solvers = execute("SELECT DISTINCT solver FROM solver_parameter")
|
||||
solvers = execute(
|
||||
"SELECT DISTINCT solver FROM solver_parameter")
|
||||
|
||||
for solver in solvers:
|
||||
if solver != "mage8":
|
||||
continue
|
||||
|
||||
data = execute("SELECT ind, name, value " +
|
||||
"FROM solver_parameter "+
|
||||
f"WHERE solver = '{solver}' " +
|
||||
"ORDER BY ind ACS")
|
||||
"FROM solver_parameter " +
|
||||
f"WHERE solver = '{solver}' " +
|
||||
"ORDER BY ind ACS")
|
||||
|
||||
execute(
|
||||
"DELETE FROM solver_parameter " +
|
||||
f"WHERE solver = '{solver}'"
|
||||
)
|
||||
|
||||
insert = lambda name, value, ind: execute(
|
||||
"INSERT INTO " +
|
||||
"solver_parameter(ind, name, value, solver) "+
|
||||
"VALUES (" +
|
||||
f"{ind}, " +
|
||||
f"'{cls._sql_format(name)}', " +
|
||||
f"'{cls._sql_format(value)}', " +
|
||||
f"'{cls._sql_format(solver)}'" +
|
||||
")"
|
||||
def insert(name, value, ind): return execute(
|
||||
"INSERT INTO " +
|
||||
"solver_parameter(ind, name, value, solver) " +
|
||||
"VALUES (" +
|
||||
f"{ind}, " +
|
||||
f"'{cls._sql_format(name)}', " +
|
||||
f"'{cls._sql_format(value)}', " +
|
||||
f"'{cls._sql_format(solver)}'" +
|
||||
")"
|
||||
)
|
||||
|
||||
ind = 0
|
||||
@@ -156,7 +164,7 @@ class SolverParametersList(PamhyrModelList):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
status = data["status"]
|
||||
solvers = execute("SELECT DISTINCT solver FROM solver_parameter")
|
||||
new = {}
|
||||
@@ -167,7 +175,7 @@ class SolverParametersList(PamhyrModelList):
|
||||
continue
|
||||
|
||||
st = solver_type_list[solver]
|
||||
n = cls(solver_type = st, status = status)
|
||||
n = cls(solver_type=st, status=status)
|
||||
|
||||
table = execute(
|
||||
"SELECT ind, name, value " +
|
||||
@@ -186,7 +194,7 @@ class SolverParametersList(PamhyrModelList):
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
t = self._solver._type
|
||||
execute(
|
||||
"DELETE FROM solver_parameter " +
|
||||
@@ -197,7 +205,7 @@ class SolverParametersList(PamhyrModelList):
|
||||
for param in self._lst:
|
||||
sql = (
|
||||
"INSERT INTO " +
|
||||
"solver_parameter(ind, name, value, solver) "+
|
||||
"solver_parameter(ind, name, value, solver) " +
|
||||
"VALUES (" +
|
||||
f"{ind}, " +
|
||||
f"'{self._sql_format(param.name)}', " +
|
||||
@@ -225,7 +233,7 @@ class SolverParametersList(PamhyrModelList):
|
||||
self._lst
|
||||
)
|
||||
)["value"]
|
||||
except:
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def set(self, index, new):
|
||||
@@ -241,15 +249,15 @@ class SolverParametersList(PamhyrModelList):
|
||||
|
||||
self._lst.append(
|
||||
Parameter(
|
||||
name = key,
|
||||
value = value,
|
||||
status = self._status
|
||||
name=key,
|
||||
value=value,
|
||||
status=self._status
|
||||
)
|
||||
)
|
||||
self._status.modified()
|
||||
|
||||
def new(self, index):
|
||||
n = Parameter(status = self._status)
|
||||
n = Parameter(status=self._status)
|
||||
self._lst.insert(index, n)
|
||||
self._status.modified()
|
||||
return n
|
||||
@@ -20,16 +20,17 @@ from tools import trace, timer
|
||||
|
||||
from Model.Tools.PamhyrDB import SQLSubModel
|
||||
|
||||
|
||||
class Stricklers(SQLSubModel):
|
||||
_id_cnt = 0
|
||||
_sub_classes = []
|
||||
|
||||
def __init__(self, id:int = -1,
|
||||
name:str = "",
|
||||
comment:str = "",
|
||||
minor:float = 35.0,
|
||||
medium:float = 15.0,
|
||||
status = None):
|
||||
def __init__(self, id: int = -1,
|
||||
name: str = "",
|
||||
comment: str = "",
|
||||
minor: float = 35.0,
|
||||
medium: float = 15.0,
|
||||
status=None):
|
||||
super(Stricklers, self).__init__()
|
||||
self._status = status
|
||||
|
||||
@@ -46,7 +47,6 @@ class Stricklers(SQLSubModel):
|
||||
self._minor = minor
|
||||
self._medium = medium
|
||||
|
||||
|
||||
@classmethod
|
||||
def _sql_create(cls, execute):
|
||||
execute("""
|
||||
@@ -66,7 +66,7 @@ class Stricklers(SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
stricklers = []
|
||||
status = data["status"]
|
||||
|
||||
@@ -86,21 +86,21 @@ class Stricklers(SQLSubModel):
|
||||
medium = row[4]
|
||||
|
||||
new = cls(
|
||||
id = id,
|
||||
name = name,
|
||||
comment = comment,
|
||||
minor = minor, medium = medium,
|
||||
status = status
|
||||
id=id,
|
||||
name=name,
|
||||
comment=comment,
|
||||
minor=minor, medium=medium,
|
||||
status=status
|
||||
)
|
||||
|
||||
stricklers.append(new)
|
||||
|
||||
return stricklers
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
sql = (
|
||||
"INSERT INTO " +
|
||||
"stricklers(id, name, comment, minor, medium) "+
|
||||
"stricklers(id, name, comment, minor, medium) " +
|
||||
"VALUES (" +
|
||||
f"{self.id}, " +
|
||||
f"'{self._sql_format(self.name)}', " +
|
||||
|
||||
@@ -22,6 +22,7 @@ from Model.Saved import SavedStatus
|
||||
from Model.Tools.PamhyrList import PamhyrModelList
|
||||
from Model.Stricklers.Stricklers import Stricklers
|
||||
|
||||
|
||||
class StricklersList(PamhyrModelList):
|
||||
_sub_classes = [
|
||||
Stricklers,
|
||||
@@ -36,17 +37,17 @@ class StricklersList(PamhyrModelList):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
new = cls(status = data["status"])
|
||||
def _sql_load(cls, execute, data=None):
|
||||
new = cls(status=data["status"])
|
||||
|
||||
new._lst = Stricklers._sql_load(
|
||||
execute,
|
||||
data = data
|
||||
data=data
|
||||
)
|
||||
|
||||
return new
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
execute("DELETE FROM stricklers")
|
||||
|
||||
objs = self._lst
|
||||
@@ -57,19 +58,21 @@ class StricklersList(PamhyrModelList):
|
||||
return self.lst
|
||||
|
||||
def new(self, index):
|
||||
s = Stricklers(status = self._status)
|
||||
s = Stricklers(status=self._status)
|
||||
self.insert(index, s)
|
||||
return s
|
||||
|
||||
@timer
|
||||
def sort(self, reverse:bool = False, key=None):
|
||||
f = lambda st: st.name
|
||||
def sort(self, reverse: bool = False, key=None):
|
||||
def f(st): return st.name
|
||||
if key is not None:
|
||||
f = key
|
||||
|
||||
self._lst = sorted(
|
||||
self._lst,
|
||||
key = f,
|
||||
reverse = reverse,
|
||||
key=f,
|
||||
reverse=reverse,
|
||||
)
|
||||
self._status.modified()
|
||||
|
||||
if self._status is not None:
|
||||
self._status.modified()
|
||||
+64
-26
@@ -33,12 +33,13 @@ from Checker.Study import *
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Study(SQLModel):
|
||||
_sub_classes = [
|
||||
River,
|
||||
]
|
||||
|
||||
def __init__(self, filename = None, init_new = True):
|
||||
def __init__(self, filename=None, init_new=True):
|
||||
# Metadata
|
||||
self._version = "0.0.4"
|
||||
self.creation_date = datetime.now()
|
||||
@@ -46,7 +47,7 @@ class Study(SQLModel):
|
||||
self.last_save_date = datetime.now()
|
||||
|
||||
self._filename = filename
|
||||
super(Study, self).__init__(filename = filename)
|
||||
super(Study, self).__init__(filename=filename)
|
||||
|
||||
self.status = SavedStatus()
|
||||
|
||||
@@ -59,9 +60,9 @@ class Study(SQLModel):
|
||||
|
||||
if init_new:
|
||||
# Study data
|
||||
self._river = River(status = self.status)
|
||||
self._river = River(status=self.status)
|
||||
else:
|
||||
self._init_db_file(filename, is_new = False)
|
||||
self._init_db_file(filename, is_new=False)
|
||||
|
||||
self._old_save_id = 0
|
||||
|
||||
@@ -128,7 +129,7 @@ class Study(SQLModel):
|
||||
@filename.setter
|
||||
def filename(self, filename):
|
||||
self._filename = str(filename)
|
||||
self._init_db_file(filename, is_new = True)
|
||||
self._init_db_file(filename, is_new=True)
|
||||
self.status.modified()
|
||||
|
||||
@property
|
||||
@@ -139,7 +140,7 @@ class Study(SQLModel):
|
||||
self._time_system = "time"
|
||||
self.status.modified()
|
||||
|
||||
def use_date(self, date:datetime):
|
||||
def use_date(self, date: datetime):
|
||||
self._time_system = "date"
|
||||
self._date = date
|
||||
self.status.modified()
|
||||
@@ -158,7 +159,7 @@ class Study(SQLModel):
|
||||
# return cls()
|
||||
|
||||
@classmethod
|
||||
def new(cls, name, description, date = None):
|
||||
def new(cls, name, description, date=None):
|
||||
me = cls()
|
||||
me.name = name
|
||||
me.description = description
|
||||
@@ -178,14 +179,17 @@ class Study(SQLModel):
|
||||
|
||||
def _create(self):
|
||||
# Info (metadata)
|
||||
self.execute("CREATE TABLE info(key TEXT NOT NULL UNIQUE, value TEXT NOT NULL)")
|
||||
self.execute(
|
||||
f"INSERT INTO info VALUES ('version', '{self._sql_format(self._version)}')",
|
||||
commit = True
|
||||
"CREATE TABLE info(key TEXT NOT NULL UNIQUE, value TEXT NOT NULL)")
|
||||
self.execute(
|
||||
"INSERT INTO info VALUES ('version', " +
|
||||
f"'{self._sql_format(self._version)}')",
|
||||
commit=True
|
||||
)
|
||||
self.execute("INSERT INTO info VALUES ('name', '')")
|
||||
self.execute("INSERT INTO info VALUES ('description', '')")
|
||||
self.execute(f"INSERT INTO info VALUES ('time_system', '{self._time_system}')")
|
||||
self.execute(
|
||||
f"INSERT INTO info VALUES ('time_system', '{self._time_system}')")
|
||||
self.execute(
|
||||
f"INSERT INTO info VALUES ('date', " +
|
||||
"'{self._date.timestamp()}')"
|
||||
@@ -213,7 +217,8 @@ class Study(SQLModel):
|
||||
logger.info("Update database")
|
||||
|
||||
if self._update_submodel(version[0]):
|
||||
self.execute(f"UPDATE info SET value='{self._version}' WHERE key='version'")
|
||||
self.execute(
|
||||
f"UPDATE info SET value='{self._version}' WHERE key='version'")
|
||||
return True
|
||||
|
||||
logger.info("TODO: update failed")
|
||||
@@ -221,42 +226,75 @@ class Study(SQLModel):
|
||||
|
||||
@classmethod
|
||||
def _load(cls, filename):
|
||||
new = cls(init_new = False, filename = filename)
|
||||
new = cls(init_new=False, filename=filename)
|
||||
|
||||
# TODO: Load metadata
|
||||
new.name = new.execute("SELECT value FROM info WHERE key='name'")[0]
|
||||
new.description = new.execute("SELECT value FROM info WHERE key='description'")[0]
|
||||
new._time_system = new.execute("SELECT value FROM info WHERE key='time_system'")[0]
|
||||
new.description = new.execute(
|
||||
"SELECT value FROM info WHERE key='description'")[0]
|
||||
new._time_system = new.execute(
|
||||
"SELECT value FROM info WHERE key='time_system'")[0]
|
||||
new._date = datetime.fromtimestamp(
|
||||
float(new.execute("SELECT value FROM info WHERE key='date'")[0])
|
||||
)
|
||||
|
||||
new.creation_date = datetime.fromtimestamp(
|
||||
float(new.execute("SELECT value FROM info WHERE key='creation_date'")[0])
|
||||
float(new.execute(
|
||||
"SELECT value FROM info WHERE key='creation_date'")[0])
|
||||
)
|
||||
new.last_save_date = datetime.fromtimestamp(
|
||||
float(new.execute("SELECT value FROM info WHERE key='last_save_date'")[0])
|
||||
float(new.execute(
|
||||
"SELECT value FROM info WHERE key='last_save_date'")[0])
|
||||
)
|
||||
|
||||
# Load river data
|
||||
new._river = River._sql_load(
|
||||
lambda sql: new.execute(
|
||||
sql,
|
||||
fetch_one = False,
|
||||
commit = True
|
||||
fetch_one=False,
|
||||
commit=True
|
||||
),
|
||||
data = {"status": new.status}
|
||||
data={"status": new.status}
|
||||
)
|
||||
|
||||
return new
|
||||
|
||||
def _save(self):
|
||||
self.execute(f"UPDATE info SET value='{self._sql_format(self.name)}' WHERE key='name'")
|
||||
self.execute(f"UPDATE info SET value='{self._sql_format(self.description)}' WHERE key='description'")
|
||||
self.execute(f"UPDATE info SET value='{self._time_system}' WHERE key='time_system'")
|
||||
self.execute(f"UPDATE info SET value='{timestamp(self._date)}' WHERE key='date'")
|
||||
self.execute(f"UPDATE info SET value='{timestamp(self.creation_date)}' WHERE key='creation_date'")
|
||||
self.execute(f"UPDATE info SET value='{timestamp(self.last_save_date)}' WHERE key='last_save_date'")
|
||||
self.execute(
|
||||
f"UPDATE info SET " +
|
||||
f"value='{self._sql_format(self.name)}' WHERE key='name'"
|
||||
)
|
||||
self.execute(
|
||||
f"UPDATE info SET " +
|
||||
f"value='{self._sql_format(self.description)}' " +
|
||||
"WHERE key='description'"
|
||||
)
|
||||
self.execute(
|
||||
f"UPDATE info SET " +
|
||||
f"value='{self._time_system}' WHERE key='time_system'"
|
||||
)
|
||||
self.execute(
|
||||
f"UPDATE info SET " +
|
||||
f"value='{timestamp(self._date)}' WHERE key='date'"
|
||||
)
|
||||
self.execute(
|
||||
f"UPDATE info SET " +
|
||||
f"value='{timestamp(self.creation_date)}' " +
|
||||
"WHERE key='creation_date'"
|
||||
)
|
||||
self.execute(
|
||||
f"UPDATE info SET " +
|
||||
f"value='{timestamp(self.last_save_date)}' " +
|
||||
"WHERE key='last_save_date'"
|
||||
)
|
||||
|
||||
self._save_submodel([self._river])
|
||||
self.commit()
|
||||
|
||||
def close(self):
|
||||
"""Close db connection
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
self._close()
|
||||
+23
-20
@@ -28,10 +28,12 @@ from Model.Except import NotImplementedMethodeError
|
||||
logger = logging.getLogger()
|
||||
|
||||
# Top level model class
|
||||
|
||||
|
||||
class SQLModel(SQL):
|
||||
_sub_classes = []
|
||||
|
||||
def _init_db_file(self, db, is_new = True):
|
||||
def _init_db_file(self, db, is_new=True):
|
||||
exists = Path(db).exists()
|
||||
|
||||
if exists and is_new:
|
||||
@@ -48,15 +50,14 @@ class SQLModel(SQL):
|
||||
self._update() # Update db scheme if necessary
|
||||
# self._load() # Load data
|
||||
|
||||
|
||||
def __init__(self, filename = None):
|
||||
def __init__(self, filename=None):
|
||||
self._db = None
|
||||
|
||||
def _create_submodel(self):
|
||||
fn = lambda sql: self.execute(
|
||||
def fn(sql): return self.execute(
|
||||
sql,
|
||||
fetch_one = False,
|
||||
commit = False
|
||||
fetch_one=False,
|
||||
commit=False
|
||||
)
|
||||
|
||||
for cls in self._sub_classes:
|
||||
@@ -69,10 +70,10 @@ class SQLModel(SQL):
|
||||
raise NotImplementedMethodeError(self, self._create)
|
||||
|
||||
def _update_submodel(self, version):
|
||||
fn = lambda sql: self.execute(
|
||||
def fn(sql): return self.execute(
|
||||
sql,
|
||||
fetch_one = False,
|
||||
commit = False
|
||||
fetch_one=False,
|
||||
commit=False
|
||||
)
|
||||
|
||||
ok = True
|
||||
@@ -85,11 +86,11 @@ class SQLModel(SQL):
|
||||
def _update(self):
|
||||
raise NotImplementedMethodeError(self, self._update)
|
||||
|
||||
def _save_submodel(self, objs, data = None):
|
||||
fn = lambda sql: self.execute(
|
||||
def _save_submodel(self, objs, data=None):
|
||||
def fn(sql): return self.execute(
|
||||
sql,
|
||||
fetch_one = False,
|
||||
commit = False
|
||||
fetch_one=False,
|
||||
commit=False
|
||||
)
|
||||
|
||||
ok = True
|
||||
@@ -103,18 +104,20 @@ class SQLModel(SQL):
|
||||
raise NotImplementedMethodeError(self, self._save)
|
||||
|
||||
@classmethod
|
||||
def _load(cls, filename = None):
|
||||
def _load(cls, filename=None):
|
||||
raise NotImplementedMethodeError(cls, cls._load)
|
||||
|
||||
# Sub model class
|
||||
|
||||
|
||||
class SQLSubModel(object):
|
||||
_sub_classes = []
|
||||
|
||||
def _sql_format(self, value):
|
||||
# Replace ''' by ''' to preserve SQL injection
|
||||
if type(value) == str:
|
||||
if value is str:
|
||||
value = value.replace("'", "'")
|
||||
elif type(value) == bool:
|
||||
elif value is bool:
|
||||
value = 'TRUE' if value else 'FALSE'
|
||||
return value
|
||||
|
||||
@@ -154,7 +157,7 @@ class SQLSubModel(object):
|
||||
raise NotImplementedMethodeError(cls, cls._sql_update)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
"""Load instance of this class from SQL data base
|
||||
|
||||
Args:
|
||||
@@ -166,11 +169,11 @@ class SQLSubModel(object):
|
||||
"""
|
||||
raise NotImplementedMethodeError(cls, cls._sql_load)
|
||||
|
||||
def _save_submodel(self, execute, objs, data = None):
|
||||
def _save_submodel(self, execute, objs, data=None):
|
||||
for o in objs:
|
||||
o._sql_save(execute, data = data)
|
||||
o._sql_save(execute, data=data)
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
"""Save class data to data base
|
||||
|
||||
Args:
|
||||
|
||||
@@ -30,7 +30,7 @@ logger = logging.getLogger()
|
||||
class PamhyrModelDict(SQLSubModel):
|
||||
_sub_classes = []
|
||||
|
||||
def __init__(self, status = None):
|
||||
def __init__(self, status=None):
|
||||
super(PamhyrModelDict, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -46,10 +46,10 @@ class PamhyrModelDict(SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
raise NotImplementedMethodeError(cls, cls._sql_load)
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
raise NotImplementedMethodeError(self, self._sql_save)
|
||||
|
||||
def __len__(self):
|
||||
|
||||
@@ -26,11 +26,12 @@ from Model.Except import NotImplementedMethodeError
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class PamhyrModelList(SQLSubModel):
|
||||
_sub_classes = [
|
||||
]
|
||||
|
||||
def __init__(self, status = None):
|
||||
def __init__(self, status=None):
|
||||
super(PamhyrModelList, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -49,29 +50,30 @@ class PamhyrModelList(SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
raise NotImplementedMethodeError(cls, cls._sql_load)
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
raise NotImplementedMethodeError(self, self._sql_save)
|
||||
|
||||
################
|
||||
# MODEL METHOD #
|
||||
################
|
||||
|
||||
def __len__(self):
|
||||
return len(self._lst)
|
||||
|
||||
@property
|
||||
def lst(self):
|
||||
return self._lst.copy()
|
||||
return self._lst
|
||||
|
||||
def __len__(self):
|
||||
return len(self.lst)
|
||||
|
||||
def get(self, row):
|
||||
return self._lst[row]
|
||||
|
||||
def set(self, row, new):
|
||||
self._lst[row] = new
|
||||
self._status.modified()
|
||||
if self._status is not None:
|
||||
self._status.modified()
|
||||
|
||||
def new(self, index):
|
||||
"""Create new elements and add it to list
|
||||
@@ -86,12 +88,16 @@ class PamhyrModelList(SQLSubModel):
|
||||
|
||||
def insert(self, index, new):
|
||||
self._lst.insert(index, new)
|
||||
self._status.modified()
|
||||
|
||||
if self._status is not None:
|
||||
self._status.modified()
|
||||
|
||||
def delete(self, lst):
|
||||
for el in lst:
|
||||
self._lst.remove(el)
|
||||
self._status.modified()
|
||||
|
||||
if self._status is not None:
|
||||
self._status.modified()
|
||||
|
||||
def delete_i(self, indexes):
|
||||
lst = list(
|
||||
@@ -107,23 +113,29 @@ class PamhyrModelList(SQLSubModel):
|
||||
|
||||
def sort(self, reverse=False, key=None):
|
||||
self._lst.sort(reverse=reverse, key=key)
|
||||
self._status.modified()
|
||||
|
||||
if self._status is not None:
|
||||
self._status.modified()
|
||||
|
||||
def move_up(self, index):
|
||||
if index < len(self._lst):
|
||||
next = index - 1
|
||||
|
||||
l = self._lst
|
||||
l[index], l[next] = l[next], l[index]
|
||||
self._status.modified()
|
||||
lst = self._lst
|
||||
lst[index], lst[next] = lst[next], lst[index]
|
||||
|
||||
if self._status is not None:
|
||||
self._status.modified()
|
||||
|
||||
def move_down(self, index):
|
||||
if index >= 0:
|
||||
prev = index + 1
|
||||
|
||||
l = self._lst
|
||||
l[index], l[prev] = l[prev], l[index]
|
||||
self._status.modified()
|
||||
lst = self._lst
|
||||
lst[index], lst[prev] = lst[prev], lst[index]
|
||||
|
||||
if self._status is not None:
|
||||
self._status.modified()
|
||||
|
||||
|
||||
class PamhyrModelListWithTab(SQLSubModel):
|
||||
@@ -131,7 +143,7 @@ class PamhyrModelListWithTab(SQLSubModel):
|
||||
_sub_classes = [
|
||||
]
|
||||
|
||||
def __init__(self, status = None):
|
||||
def __init__(self, status=None):
|
||||
super(PamhyrModelListWithTab, self).__init__()
|
||||
|
||||
self._status = status
|
||||
@@ -152,10 +164,10 @@ class PamhyrModelListWithTab(SQLSubModel):
|
||||
return cls._update_submodel(execute, version)
|
||||
|
||||
@classmethod
|
||||
def _sql_load(cls, execute, data = None):
|
||||
def _sql_load(cls, execute, data=None):
|
||||
raise NotImplementedMethodeError(cls, cls._sql_load)
|
||||
|
||||
def _sql_save(self, execute, data = None):
|
||||
def _sql_save(self, execute, data=None):
|
||||
raise NotImplementedMethodeError(self, self._sql_save)
|
||||
|
||||
################
|
||||
@@ -216,14 +228,14 @@ class PamhyrModelListWithTab(SQLSubModel):
|
||||
if index < len(self._tabs[lst]):
|
||||
next = index - 1
|
||||
|
||||
l = self._tabs[lst]
|
||||
l[index], l[next] = l[next], l[index]
|
||||
lst = self._tabs[lst]
|
||||
lst[index], lst[next] = lst[next], lst[index]
|
||||
self._status.modified()
|
||||
|
||||
def move_down(self, lst, index):
|
||||
if index >= 0:
|
||||
prev = index + 1
|
||||
|
||||
l = self._tabs[lst]
|
||||
l[index], l[prev] = l[prev], l[index]
|
||||
lst = self._tabs[lst]
|
||||
lst[index], lst[prev] = lst[prev], lst[index]
|
||||
self._status.modified()
|
||||
@@ -0,0 +1,17 @@
|
||||
# __init__.py -- Pamhyr
|
||||
# Copyright (C) 2023 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 -*-
|
||||
@@ -0,0 +1,110 @@
|
||||
# test_Model.py -- Pamhyr
|
||||
# Copyright (C) 2023 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 os
|
||||
import unittest
|
||||
import tempfile
|
||||
|
||||
from Model.Saved import SavedStatus
|
||||
from Model.Study import Study
|
||||
from Model.River import River
|
||||
|
||||
|
||||
class StudyTestCase(unittest.TestCase):
|
||||
def test_create_study(self):
|
||||
study = Study.new("foo", "bar")
|
||||
self.assertEqual(study.name, "foo")
|
||||
self.assertEqual(study.description, "bar")
|
||||
|
||||
def test_open_study(self):
|
||||
study = Study.open("../tests_cases/Enlargement/Enlargement.pamhyr")
|
||||
self.assertNotEqual(study, None)
|
||||
self.assertEqual(study.name, "Enlargement")
|
||||
|
||||
def test_save_open_study(self):
|
||||
study = Study.new("foo", "bar")
|
||||
dir = tempfile.mkdtemp()
|
||||
f = os.path.join(dir, "foo.pamhyr")
|
||||
|
||||
# Save study
|
||||
study.filename = f
|
||||
study.save()
|
||||
study.close()
|
||||
|
||||
# Reopen study
|
||||
study = Study.open(f)
|
||||
|
||||
# Check
|
||||
self.assertNotEqual(study, None)
|
||||
self.assertEqual(study.name, "foo")
|
||||
self.assertEqual(study.description, "bar")
|
||||
|
||||
def test_create_study_river(self):
|
||||
study = Study.new("foo", "bar")
|
||||
self.assertNotEqual(study.river, None)
|
||||
|
||||
|
||||
class RiverTestCase(unittest.TestCase):
|
||||
def test_create_river(self):
|
||||
status = SavedStatus()
|
||||
river = River(status=status)
|
||||
|
||||
self.assertNotEqual(river, None)
|
||||
|
||||
def test_create_river_nodes(self):
|
||||
status = SavedStatus()
|
||||
river = River(status=status)
|
||||
|
||||
self.assertNotEqual(river, None)
|
||||
|
||||
# Add nodes
|
||||
n0 = river.add_node()
|
||||
n1 = river.add_node(x=1.0, y=0.0)
|
||||
n2 = river.add_node(x=0.0, y=1.0)
|
||||
|
||||
# Checks
|
||||
self.assertEqual(river.nodes_counts(), 3)
|
||||
|
||||
nodes = river.nodes()
|
||||
self.assertEqual(nodes[0], n0)
|
||||
self.assertEqual(nodes[1], n1)
|
||||
self.assertEqual(nodes[2], n2)
|
||||
|
||||
def test_create_river_edges(self):
|
||||
status = SavedStatus()
|
||||
river = River(status=status)
|
||||
|
||||
self.assertNotEqual(river, None)
|
||||
|
||||
# Add nodes
|
||||
n0 = river.add_node()
|
||||
n1 = river.add_node(x=1.0, y=0.0)
|
||||
n2 = river.add_node(x=0.0, y=1.0)
|
||||
|
||||
self.assertEqual(river.nodes_counts(), 3)
|
||||
|
||||
# Add edges
|
||||
e0 = river.add_edge(n0, n1)
|
||||
e1 = river.add_edge(n1, n2)
|
||||
|
||||
# Checks
|
||||
self.assertEqual(river.edges_counts(), 2)
|
||||
|
||||
edges = river.edges()
|
||||
self.assertEqual(edges[0], e0)
|
||||
self.assertEqual(edges[1], e1)
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
from Model.Except import NotImplementedMethodeError
|
||||
|
||||
|
||||
class AScript(object):
|
||||
name = ""
|
||||
description = ""
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# ListSolver.py -- Pamhyr
|
||||
# Copyright (C) 2023 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 os
|
||||
import logging
|
||||
|
||||
from Scripts.AScript import AScript
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class ScriptListSolver(AScript):
|
||||
name = "ListSolver"
|
||||
description = "List configured solver(s) for Pamhyr2"
|
||||
|
||||
def usage(self):
|
||||
logger.info(f"Usage : {self._args[0]} {self._args[1]}")
|
||||
|
||||
def run(self):
|
||||
for solver in self._conf.solvers:
|
||||
print(f"{solver.name:<16} ({solver.type}): {solver.description}")
|
||||
|
||||
return 0
|
||||
@@ -29,6 +29,7 @@ from Model.Geometry.Reach import Reach
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Script3DST(AScript):
|
||||
name = "3DST"
|
||||
description = "Display a 3D plot of a river reach from ST file"
|
||||
@@ -82,7 +83,7 @@ class Script3DST(AScript):
|
||||
try:
|
||||
status = SavedStatus()
|
||||
|
||||
my_reach = Reach(status = status)
|
||||
my_reach = Reach(status=status)
|
||||
my_reach.import_geometry(st_file)
|
||||
my_reach.compute_guidelines()
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# Run.py -- Pamhyr
|
||||
# Copyright (C) 2023 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 os
|
||||
import logging
|
||||
|
||||
from queue import Queue
|
||||
|
||||
from PyQt5.QtCore import QProcess
|
||||
|
||||
from Scripts.AScript import AScript
|
||||
from Model.Study import Study
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class ScriptRun(AScript):
|
||||
name = "Run"
|
||||
description = "Run solver on Pamhyr2 a study"
|
||||
|
||||
def usage(self):
|
||||
logger.info(
|
||||
f"Usage : {self._args[0]} {self._args[1]} " +
|
||||
"<SOLVER> <STUDY>"
|
||||
)
|
||||
|
||||
def run(self):
|
||||
if len(self._args) < 4:
|
||||
return 1
|
||||
|
||||
command = self._args[1]
|
||||
solver_name = self._args[2]
|
||||
study_file = os.path.abspath(
|
||||
self._args[3]
|
||||
)
|
||||
|
||||
try:
|
||||
solver = next(
|
||||
filter(
|
||||
lambda solver: solver.name == solver_name,
|
||||
self._conf.solvers
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"No solver found: {e}")
|
||||
return 2
|
||||
|
||||
study = Study.open(study_file)
|
||||
|
||||
self._solver = solver
|
||||
self._study = study
|
||||
|
||||
logger.info(
|
||||
f"Run {solver.name} ({solver.type}) " +
|
||||
"on study '{study.name}' ({study_file})"
|
||||
)
|
||||
|
||||
# Workdir
|
||||
workdir = os.path.join(
|
||||
os.path.dirname(study.filename),
|
||||
"_PAMHYR_",
|
||||
study.name.replace(" ", "_"),
|
||||
solver.name.replace(" ", "_")
|
||||
)
|
||||
os.makedirs(workdir, exist_ok=True)
|
||||
logger.info(f"Set working dir to {workdir}")
|
||||
|
||||
# Preparate process
|
||||
p = QProcess(None)
|
||||
p.setWorkingDirectory(workdir)
|
||||
|
||||
self._q = Queue()
|
||||
|
||||
# Export and Run
|
||||
logger.info(f"~Export~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
|
||||
solver.export(study, workdir, qlog=self._q)
|
||||
|
||||
while self._q.qsize() != 0:
|
||||
s = self._q.get()
|
||||
logger.info(s)
|
||||
|
||||
if command == "run":
|
||||
logger.info(f"~Run~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
|
||||
solver.run(
|
||||
study,
|
||||
process=p,
|
||||
output_queue=self._q
|
||||
)
|
||||
p.waitForFinished()
|
||||
|
||||
logger.info(f"~End~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
class ScriptExport(ScriptRun):
|
||||
name = "Export"
|
||||
description = "Export Pamhyr2 study for solver"
|
||||
+27
-12
@@ -25,7 +25,7 @@ try:
|
||||
# Installation allow Unix-like signal
|
||||
from signal import SIGTERM, SIGSTOP, SIGCONT
|
||||
_signal = True
|
||||
except:
|
||||
except Exception:
|
||||
_signal = False
|
||||
|
||||
from enum import Enum
|
||||
@@ -37,12 +37,14 @@ from Model.Results.River.River import River, Reach, Profile
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class STATUS(Enum):
|
||||
NOT_LAUNCHED = -1
|
||||
STOPED = 0
|
||||
RUNNING = 1
|
||||
PAUSED = 5
|
||||
|
||||
|
||||
class AbstractSolver(object):
|
||||
_type = ""
|
||||
|
||||
@@ -155,7 +157,7 @@ class AbstractSolver(object):
|
||||
# Export #
|
||||
##########
|
||||
|
||||
def export(self, study, repertory, qlog = None):
|
||||
def export(self, study, repertory, qlog=None):
|
||||
raise NotImplementedMethodeError(self, self.export)
|
||||
|
||||
def cmd_args(self, study):
|
||||
@@ -177,6 +179,14 @@ class AbstractSolver(object):
|
||||
"""
|
||||
raise NotImplementedMethodeError(self, self.input_param)
|
||||
|
||||
def output_param(self):
|
||||
"""Return output command line parameter(s)
|
||||
|
||||
Returns:
|
||||
Returns output parameter(s) string
|
||||
"""
|
||||
raise NotImplementedMethodeError(self, self.output_param)
|
||||
|
||||
def log_file(self):
|
||||
"""Return log file name
|
||||
|
||||
@@ -190,8 +200,8 @@ class AbstractSolver(object):
|
||||
###########
|
||||
|
||||
@timer
|
||||
def results(self, study, repertory, qlog = None):
|
||||
results = Results(study = study)
|
||||
def results(self, study, repertory, qlog=None):
|
||||
results = Results(study=study)
|
||||
return results
|
||||
|
||||
#######
|
||||
@@ -206,7 +216,7 @@ class AbstractSolver(object):
|
||||
)
|
||||
)
|
||||
|
||||
def _format_command(self, study, cmd, path = ""):
|
||||
def _format_command(self, study, cmd, path=""):
|
||||
"""Format command line
|
||||
|
||||
Args:
|
||||
@@ -218,8 +228,9 @@ class AbstractSolver(object):
|
||||
"""
|
||||
# HACK: Works in most case... Trust me i'm an engineer
|
||||
cmd = cmd.replace("@install_dir", self._install_dir())
|
||||
cmd = cmd.replace("@path", path.replace(" ", "\ "))
|
||||
cmd = cmd.replace("@path", path.replace(" ", "%20"))
|
||||
cmd = cmd.replace("@input", self.input_param())
|
||||
cmd = cmd.replace("@output", self.output_param())
|
||||
cmd = cmd.replace("@dir", self._process.workingDirectory())
|
||||
cmd = cmd.replace("@args", " ".join(self.cmd_args(study)))
|
||||
|
||||
@@ -228,7 +239,7 @@ class AbstractSolver(object):
|
||||
if cmd[0] == "\"":
|
||||
# Command line executable path is between " char
|
||||
cmd = cmd.split("\"")
|
||||
exe = cmd[1].replace("\ ", " ")
|
||||
exe = cmd[1].replace("%20", " ")
|
||||
args = list(
|
||||
filter(
|
||||
lambda s: s != "",
|
||||
@@ -237,12 +248,12 @@ class AbstractSolver(object):
|
||||
)
|
||||
else:
|
||||
# We suppose the command line executable path as no space char
|
||||
cmd = cmd.replace("\ ", "&_&").split(" ")
|
||||
cmd = cmd.replace("\\ ", "&_&").split(" ")
|
||||
exe = cmd[0].replace("&_&", " ")
|
||||
args = list(
|
||||
filter(
|
||||
lambda s: s != "",
|
||||
map(lambda s: s.replace("&_&", "\ "), cmd[1:])
|
||||
map(lambda s: s.replace("&_&", " "), cmd[1:])
|
||||
)
|
||||
)
|
||||
|
||||
@@ -284,6 +295,7 @@ class AbstractSolver(object):
|
||||
self._process.start(
|
||||
exe, args,
|
||||
)
|
||||
self._process.waitForStarted()
|
||||
|
||||
self._status = STATUS.RUNNING
|
||||
return True
|
||||
@@ -328,14 +340,17 @@ class AbstractSolver(object):
|
||||
|
||||
self._run_next(study)
|
||||
|
||||
def run(self, study, process = None, output_queue = None):
|
||||
def run(self, study, process=None, output_queue=None):
|
||||
self._study = study
|
||||
|
||||
if process is not None:
|
||||
self._process = process
|
||||
if output_queue is not None:
|
||||
self._output = output_queue
|
||||
|
||||
self._process.readyRead.connect(self._data_ready)
|
||||
self._process.finished.connect(lambda c, s: self._finished(study, c, s))
|
||||
self._process.finished.connect(
|
||||
lambda c, s: self._finished(study, c, s))
|
||||
|
||||
self._runs = [
|
||||
self.run_input_data_fomater,
|
||||
@@ -356,7 +371,7 @@ class AbstractSolver(object):
|
||||
self._status = STATUS.STOPED
|
||||
return True
|
||||
|
||||
def start(self, study, process = None):
|
||||
def start(self, study, process=None):
|
||||
if _signal:
|
||||
# Solver is PAUSED, so continue execution
|
||||
if self._status == STATUS.PAUSED:
|
||||
|
||||
@@ -20,6 +20,7 @@ from Solver.ASolver import (
|
||||
AbstractSolver, STATUS
|
||||
)
|
||||
|
||||
|
||||
class GenericSolver(AbstractSolver):
|
||||
_type = "generic"
|
||||
|
||||
|
||||
+107
-58
@@ -30,6 +30,7 @@ from Model.Results.River.River import River, Reach, Profile
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
def mage_file_open(filepath, mode):
|
||||
f = open(filepath, mode)
|
||||
|
||||
@@ -39,6 +40,7 @@ def mage_file_open(filepath, mode):
|
||||
|
||||
return f
|
||||
|
||||
|
||||
class Mage(AbstractSolver):
|
||||
_type = "mage"
|
||||
|
||||
@@ -51,7 +53,6 @@ class Mage(AbstractSolver):
|
||||
self._cmd_solver = "@path @input -o @output"
|
||||
self._cmd_output = ""
|
||||
|
||||
|
||||
@classmethod
|
||||
def default_parameters(cls):
|
||||
lst = super(Mage, cls).default_parameters()
|
||||
@@ -87,8 +88,8 @@ class Mage(AbstractSolver):
|
||||
@classmethod
|
||||
def checkers(cls):
|
||||
lst = [
|
||||
MageNetworkGraphChecker(connectivity = True),
|
||||
MageNetworkGraphChecker(connectivity = False)
|
||||
MageNetworkGraphChecker(connectivity=True),
|
||||
MageNetworkGraphChecker(connectivity=False)
|
||||
]
|
||||
|
||||
return lst
|
||||
@@ -98,16 +99,20 @@ class Mage(AbstractSolver):
|
||||
##########
|
||||
|
||||
def cmd_args(self, study):
|
||||
l = super(Mage, self).cmd_args(study)
|
||||
lst = super(Mage, self).cmd_args(study)
|
||||
|
||||
l.append("-r")
|
||||
lst.append("-r")
|
||||
|
||||
return l
|
||||
return lst
|
||||
|
||||
def input_param(self):
|
||||
name = self._study.name
|
||||
return f"{name}.REP"
|
||||
|
||||
def output_param(self):
|
||||
name = self._study.name
|
||||
return f"{name}.BIN"
|
||||
|
||||
def log_file(self):
|
||||
name = self._study.name
|
||||
return f"{name}.TRA"
|
||||
@@ -136,7 +141,10 @@ class Mage(AbstractSolver):
|
||||
if edge._name == "":
|
||||
name = f"Reach_{edge.id}"
|
||||
|
||||
with mage_file_open(os.path.join(repertory, "net", f"{name}.ST"), "w+") as f:
|
||||
with mage_file_open(
|
||||
os.path.join(repertory, "net", f"{name}.ST"),
|
||||
"w+"
|
||||
) as f:
|
||||
files.append(str(os.path.join("net", f"{name}.ST")))
|
||||
|
||||
cnt_num = 1
|
||||
@@ -145,42 +153,64 @@ class Mage(AbstractSolver):
|
||||
c1 = f"{profile.code1:>6}"
|
||||
c2 = f"{profile.code2:>6}"
|
||||
t = f"{len(profile.points):>6}"
|
||||
kp = f"{profile.kp:>13.4f}"
|
||||
kp = f"{profile.kp:>12f}"[0:12]
|
||||
pname = profile.name
|
||||
if profile.name == "":
|
||||
pname = f"p{profile.id:>3}".replace(" ", "p")
|
||||
name = f"{pname}"
|
||||
# Generate name from profile id prefixed with
|
||||
# 'p' (and replace space char with '0' char)
|
||||
pname = f"p{profile.id:>3}".replace(" ", "0")
|
||||
name = f"{pname:<19}"
|
||||
|
||||
# Generate sediment additional data if available
|
||||
sediment = ""
|
||||
if profile.sl is not None:
|
||||
if not any(filter(lambda f: ".GRA" in f, files)):
|
||||
files.append(gra_file)
|
||||
|
||||
# Number of layers
|
||||
nl = len(profile.sl)
|
||||
sediment = f" {nl:>3}"
|
||||
for l in profile.sl.layers:
|
||||
sediment += f" {l.height:>10} {l.d50:>10} {l.sigma:>10} {l.critical_constraint:>10}"
|
||||
|
||||
f.write(f"{num}{c1}{c2}{t}{kp} {name} {sediment}\n")
|
||||
# Layers data
|
||||
for layer in profile.sl.layers:
|
||||
sediment += (
|
||||
f" {layer.height:>10} {layer.d50:>10} " +
|
||||
f"{layer.sigma:>10} " +
|
||||
f"{layer.critical_constraint:>10}"
|
||||
)
|
||||
|
||||
# Profile header line
|
||||
f.write(f"{num}{c1}{c2}{t} {kp} {name} {sediment}\n")
|
||||
cnt_num += 1
|
||||
|
||||
# Points
|
||||
for point in profile.points:
|
||||
x = f"{point.x:>13.4f}"
|
||||
y = f"{point.y:>13.4f}"
|
||||
z = f"{point.z:>13.4f}"
|
||||
x = f"{point.x:<12f}"[0:12]
|
||||
y = f"{point.y:<12f}"[0:12]
|
||||
z = f"{point.z:<12f}"[0:12]
|
||||
n = f"{point.name:<3}"
|
||||
|
||||
# Generate sediment additional data if available
|
||||
sediment = ""
|
||||
prev = point.z
|
||||
if point.sl is not None:
|
||||
# Number of layers
|
||||
nl = len(point.sl)
|
||||
sediment = f"{nl:>3}"
|
||||
for l in point.sl.layers:
|
||||
prev = round(prev - l.height, 5)
|
||||
sediment += f" {prev:>10} {l.d50:>10} {l.sigma:>10} {l.critical_constraint:>10}"
|
||||
|
||||
f.write(f"{x}{y}{z} {n} {sediment}\n")
|
||||
# Layers data
|
||||
for layer in point.sl.layers:
|
||||
prev = round(prev - layer.height, 5)
|
||||
sediment += (
|
||||
f" {prev:>10} {layer.d50:>10} " +
|
||||
f"{layer.sigma:>10} " +
|
||||
f"{layer.critical_constraint:>10}"
|
||||
)
|
||||
|
||||
# Point line
|
||||
f.write(f"{x} {y} {z} {n} {sediment}\n")
|
||||
|
||||
# Profile last line
|
||||
f.write(f" 999.9990 999.9990 999.9990\n")
|
||||
|
||||
return files
|
||||
@@ -210,7 +240,7 @@ class Mage(AbstractSolver):
|
||||
v1 = d[1]
|
||||
|
||||
if t in ["HYD", "QSO", "LIM"]:
|
||||
v0 /= 60 # Convert first column to minute
|
||||
v0 /= 60 # Convert first column to minute
|
||||
|
||||
f.write(f"{v0:10}{v1:10}\n")
|
||||
|
||||
@@ -251,7 +281,10 @@ class Mage(AbstractSolver):
|
||||
# if qlog is not None:
|
||||
# qlog.put(f"Export LAT file")
|
||||
|
||||
# with mage_file_open(os.path.join(repertory, f"{name}.LAT"), "w+") as f:
|
||||
# with mage_file_open(
|
||||
# os.path.join(repertory, f"{name}.LAT"),
|
||||
# "w+"
|
||||
# ) as f:
|
||||
# files.append(f"{name}.LAT")
|
||||
|
||||
# name = f"{lateral.node.id:3}".replace(" ", "x")
|
||||
@@ -391,13 +424,12 @@ class Mage(AbstractSolver):
|
||||
if EXT in ["GRA"]:
|
||||
f.write(f"{EXT} {file}\n")
|
||||
|
||||
|
||||
@timer
|
||||
def export(self, study, repertory, qlog = None):
|
||||
def export(self, study, repertory, qlog=None):
|
||||
self._study = study
|
||||
name = study.name.replace(" ", "_")
|
||||
|
||||
self._export_ST(study, repertory, qlog, name = name)
|
||||
self._export_ST(study, repertory, qlog, name=name)
|
||||
|
||||
return True
|
||||
|
||||
@@ -405,13 +437,17 @@ class Mage(AbstractSolver):
|
||||
# RESULTS #
|
||||
###########
|
||||
|
||||
def read_bin(self, study, repertory, results, qlog = None, name="0"):
|
||||
def read_bin(self, study, repertory, results, qlog=None, name="0"):
|
||||
return
|
||||
|
||||
@timer
|
||||
def results(self, study, repertory, qlog = None, name="0"):
|
||||
results = Results(study = study)
|
||||
|
||||
def results(self, study, repertory, qlog=None, name="0"):
|
||||
results = Results(
|
||||
study=study,
|
||||
solver=self,
|
||||
repertory=repertory,
|
||||
name=name,
|
||||
)
|
||||
self.read_bin(study, repertory, results, qlog, name=name)
|
||||
|
||||
return results
|
||||
@@ -420,6 +456,7 @@ class Mage(AbstractSolver):
|
||||
# MAGE 7 #
|
||||
##########
|
||||
|
||||
|
||||
class Mage7(Mage):
|
||||
_type = "mage7"
|
||||
|
||||
@@ -438,6 +475,7 @@ class Mage7(Mage):
|
||||
# MAGE 8 #
|
||||
##########
|
||||
|
||||
|
||||
class Mage8(Mage):
|
||||
_type = "mage8"
|
||||
|
||||
@@ -476,15 +514,15 @@ class Mage8(Mage):
|
||||
##########
|
||||
|
||||
def cmd_args(self, study):
|
||||
l = super(Mage8, self).cmd_args(study)
|
||||
lst = super(Mage8, self).cmd_args(study)
|
||||
|
||||
if study.river.has_sediment():
|
||||
l.append("-c=3")
|
||||
lst.append("-c=3")
|
||||
|
||||
return l
|
||||
return lst
|
||||
|
||||
@timer
|
||||
def _export_PAR(self, study, repertory, qlog = None, name = "0"):
|
||||
def _export_PAR(self, study, repertory, qlog=None, name="0"):
|
||||
files = []
|
||||
|
||||
if qlog is not None:
|
||||
@@ -503,7 +541,7 @@ class Mage8(Mage):
|
||||
if name in ["command_line_arguments"]:
|
||||
continue
|
||||
|
||||
if name is "mage_compute_reach_volume_balance":
|
||||
if name == "mage_compute_reach_volume_balance":
|
||||
value = "O" if value == "y" else "N"
|
||||
|
||||
f.write(f"{name} {value}\n")
|
||||
@@ -511,7 +549,7 @@ class Mage8(Mage):
|
||||
return files
|
||||
|
||||
@timer
|
||||
def _export_NET(self, study, repertory, qlog = None, name="0"):
|
||||
def _export_NET(self, study, repertory, qlog=None, name="0"):
|
||||
files = []
|
||||
|
||||
if qlog is not None:
|
||||
@@ -579,9 +617,8 @@ class Mage8(Mage):
|
||||
|
||||
return files
|
||||
|
||||
|
||||
@timer
|
||||
def export(self, study, repertory, qlog = None, name="0"):
|
||||
def export(self, study, repertory, qlog=None, name="0"):
|
||||
self._study = study
|
||||
name = study.name.replace(" ", "_")
|
||||
|
||||
@@ -590,7 +627,8 @@ class Mage8(Mage):
|
||||
files = self._export_ST(study, repertory, qlog, name=name)
|
||||
files = files + self._export_PAR(study, repertory, qlog, name=name)
|
||||
files = files + self._export_NET(study, repertory, qlog, name=name)
|
||||
files = files + self._export_bound_cond(study, repertory, qlog, name=name)
|
||||
files = files + \
|
||||
self._export_bound_cond(study, repertory, qlog, name=name)
|
||||
files = files + self._export_RUG(study, repertory, qlog, name=name)
|
||||
files = files + self._export_INI(study, repertory, qlog, name=name)
|
||||
self._export_REP(study, repertory, files, qlog, name=name)
|
||||
@@ -602,17 +640,22 @@ class Mage8(Mage):
|
||||
###########
|
||||
|
||||
@timer
|
||||
def read_bin(self, study, repertory, results, qlog = None, name="0"):
|
||||
def read_bin(self, study, repertory, results, qlog=None, name="0"):
|
||||
fname = os.path.join(repertory, f"{name}.BIN")
|
||||
logger.info(f"read_bin: Start reading '{fname}' ...")
|
||||
|
||||
with mage_file_open(fname, "r") as f:
|
||||
newline = lambda: np.fromfile(f, dtype=np.int32, count=1)
|
||||
endline = lambda: np.fromfile(f, dtype=np.int32, count=1)
|
||||
def newline(): return np.fromfile(f, dtype=np.int32, count=1)
|
||||
def endline(): return 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)
|
||||
def read_int(size): return np.fromfile(
|
||||
f, dtype=np.int32, count=size)
|
||||
|
||||
def read_float(size): return np.fromfile(
|
||||
f, dtype=np.float32, count=size)
|
||||
|
||||
def read_float64(size): return np.fromfile(
|
||||
f, dtype=np.float64, count=size)
|
||||
|
||||
# Meta data (1st line)
|
||||
newline()
|
||||
@@ -686,7 +729,7 @@ class Mage8(Mage):
|
||||
# Data
|
||||
newline()
|
||||
|
||||
ip_to_r = lambda i: iprofiles[
|
||||
def ip_to_r(i): return iprofiles[
|
||||
next(
|
||||
filter(
|
||||
lambda k: k[0] <= i <= k[1],
|
||||
@@ -694,14 +737,15 @@ class Mage8(Mage):
|
||||
)
|
||||
)
|
||||
]
|
||||
ip_to_ri = lambda r, i: i - reach_offset[r]
|
||||
def ip_to_ri(r, i): return i - reach_offset[r]
|
||||
|
||||
ts = set()
|
||||
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()
|
||||
key = bytearray(np.fromfile(
|
||||
f, dtype=np.byte, count=1)).decode()
|
||||
data = read_float(n)
|
||||
|
||||
logger.debug(f"read_bin: timestamp = {timestamp} sec")
|
||||
@@ -725,7 +769,7 @@ class Mage8(Mage):
|
||||
logger.info(f"read_bin: ... end with {len(ts)} timestamp read")
|
||||
|
||||
@timer
|
||||
def read_gra(self, study, repertory, results, qlog = None, name="0"):
|
||||
def read_gra(self, study, repertory, results, qlog=None, name="0"):
|
||||
if not study.river.has_sediment():
|
||||
return
|
||||
|
||||
@@ -733,12 +777,17 @@ class Mage8(Mage):
|
||||
logger.info(f"read_gra: Start reading '{fname}' ...")
|
||||
|
||||
with mage_file_open(fname, "r") as f:
|
||||
newline = lambda: np.fromfile(f, dtype=np.int32, count=1)
|
||||
endline = lambda: np.fromfile(f, dtype=np.int32, count=1)
|
||||
def newline(): return np.fromfile(f, dtype=np.int32, count=1)
|
||||
def endline(): return 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)
|
||||
def read_int(size): return np.fromfile(
|
||||
f, dtype=np.int32, count=size)
|
||||
|
||||
def read_float(size): return np.fromfile(
|
||||
f, dtype=np.float32, count=size)
|
||||
|
||||
def read_float64(size): return np.fromfile(
|
||||
f, dtype=np.float64, count=size)
|
||||
|
||||
# Meta data (1st line)
|
||||
newline()
|
||||
@@ -810,7 +859,7 @@ class Mage8(Mage):
|
||||
endline()
|
||||
|
||||
# Data
|
||||
ip_to_r = lambda i: iprofiles[
|
||||
def ip_to_r(i): return iprofiles[
|
||||
next(
|
||||
filter(
|
||||
lambda k: k[0] <= i <= k[1],
|
||||
@@ -818,7 +867,7 @@ class Mage8(Mage):
|
||||
)
|
||||
)
|
||||
]
|
||||
ip_to_ri = lambda r, i: i - reach_offset[r]
|
||||
def ip_to_ri(r, i): return i - reach_offset[r]
|
||||
|
||||
ts = set()
|
||||
ind = 0
|
||||
@@ -878,11 +927,11 @@ class Mage8(Mage):
|
||||
logger.info(f"read_gra: ... end with {len(ts)} timestamp read")
|
||||
|
||||
@timer
|
||||
def results(self, study, repertory, qlog = None):
|
||||
def results(self, study, repertory, qlog=None):
|
||||
self._study = study
|
||||
name = study.name.replace(" ", "_")
|
||||
|
||||
results = super(Mage8, self).results(study, repertory, qlog, name = name)
|
||||
self.read_gra(study, repertory, results, qlog, name = name)
|
||||
results = super(Mage8, self).results(study, repertory, qlog, name=name)
|
||||
self.read_gra(study, repertory, results, qlog, name=name)
|
||||
|
||||
return results
|
||||
@@ -26,6 +26,7 @@ from PyQt5.QtCore import QCoreApplication
|
||||
_translate = QCoreApplication.translate
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class AboutWindow(PamhyrDialog):
|
||||
_pamhyr_ui = "about"
|
||||
_pamhyr_name = "About"
|
||||
@@ -38,13 +39,13 @@ class AboutWindow(PamhyrDialog):
|
||||
)
|
||||
)
|
||||
|
||||
def __init__(self, study = None, config = None, parent=None):
|
||||
def __init__(self, study=None, config=None, parent=None):
|
||||
super(AboutWindow, self).__init__(
|
||||
title = _translate("About", "About"),
|
||||
study = study,
|
||||
config = config,
|
||||
options = [],
|
||||
parent = parent
|
||||
title=_translate("About", "About"),
|
||||
study=study,
|
||||
config=config,
|
||||
options=[],
|
||||
parent=parent
|
||||
)
|
||||
|
||||
# Version
|
||||
|
||||
@@ -33,16 +33,17 @@ _translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Plot(PamhyrPlot):
|
||||
def __init__(self, mode = "time", data=None,
|
||||
def __init__(self, mode="time", data=None,
|
||||
trad=None, canvas=None, toolbar=None,
|
||||
parent=None):
|
||||
super(Plot, self).__init__(
|
||||
canvas = canvas,
|
||||
trad = trad,
|
||||
data = data,
|
||||
toolbar = toolbar,
|
||||
parent = parent
|
||||
canvas=canvas,
|
||||
trad=trad,
|
||||
data=data,
|
||||
toolbar=toolbar,
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._table_headers = self._trad.get_dict("table_headers")
|
||||
@@ -72,8 +73,8 @@ class Plot(PamhyrPlot):
|
||||
map(
|
||||
lambda v: str(
|
||||
datetime.fromtimestamp(v[0]) - t0
|
||||
).split(",")[0]\
|
||||
.replace("days", _translate("BoundaryCondition", "days"))\
|
||||
).split(",")[0]
|
||||
.replace("days", _translate("BoundaryCondition", "days"))
|
||||
.replace("day", _translate("BoundaryCondition", "day")),
|
||||
fx
|
||||
)
|
||||
@@ -88,7 +89,6 @@ class Plot(PamhyrPlot):
|
||||
|
||||
self.canvas.axes.set_xticks(ticks=xx, labels=xt, rotation=45)
|
||||
|
||||
|
||||
@timer
|
||||
def draw(self):
|
||||
self.canvas.axes.cla()
|
||||
@@ -122,13 +122,13 @@ class Plot(PamhyrPlot):
|
||||
self.canvas.axes.autoscale_view(True, True, True)
|
||||
self.canvas.figure.tight_layout()
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
#self.toolbar.update()
|
||||
# self.toolbar.update()
|
||||
|
||||
self._init = True
|
||||
|
||||
@timer
|
||||
def update(self, ind=None):
|
||||
if self._init == False:
|
||||
if not self._init:
|
||||
self.draw()
|
||||
return
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ _translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class TableModel(PamhyrTableModel):
|
||||
def data(self, index, role):
|
||||
if role == Qt.TextAlignmentRole:
|
||||
|
||||
@@ -29,6 +29,7 @@ from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class SetDataCommand(QUndoCommand):
|
||||
def __init__(self, data, index, column, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -46,6 +47,7 @@ class SetDataCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._data._set_i_c_v(self._index, self._column, self._new)
|
||||
|
||||
|
||||
class SetMetaDataCommand(QUndoCommand):
|
||||
def __init__(self, data, column, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -89,6 +91,7 @@ class AddCommand(QUndoCommand):
|
||||
else:
|
||||
self._data.insert(self._index, self._new)
|
||||
|
||||
|
||||
class DelCommand(QUndoCommand):
|
||||
def __init__(self, data, rows):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -108,6 +111,7 @@ class DelCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._data.delete_i(self._rows)
|
||||
|
||||
|
||||
class SortCommand(QUndoCommand):
|
||||
def __init__(self, data, _reverse):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
@@ -53,6 +53,7 @@ _translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class WD50Sigma(PamhyrWidget):
|
||||
_pamhyr_ui = "d50sigma"
|
||||
|
||||
@@ -94,6 +95,7 @@ class WD50Sigma(PamhyrWidget):
|
||||
def valueChangedSigma(self, value):
|
||||
self.sigmaChanged.emit(value)
|
||||
|
||||
|
||||
class EditBoundaryConditionWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "EditBoundaryConditions"
|
||||
_pamhyr_name = "Edit Boundary Conditions"
|
||||
@@ -115,13 +117,15 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
||||
)
|
||||
|
||||
super(EditBoundaryConditionWindow, self).__init__(
|
||||
title = name,
|
||||
study = study,
|
||||
config = config,
|
||||
trad = trad,
|
||||
parent = parent
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=trad,
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._hash_data.append(data)
|
||||
|
||||
self.setup_table()
|
||||
self.setup_plot()
|
||||
self.setup_data()
|
||||
@@ -132,7 +136,7 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
||||
|
||||
if self._is_solid:
|
||||
layout = self.find(QVBoxLayout, "verticalLayout_table")
|
||||
self._d50sigma = WD50Sigma(parent = self)
|
||||
self._d50sigma = WD50Sigma(parent=self)
|
||||
layout.addWidget(self._d50sigma)
|
||||
|
||||
self._d50sigma.set_d50(self._data.d50)
|
||||
@@ -145,22 +149,22 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
||||
headers[h] = table_headers[h]
|
||||
|
||||
self._delegate_time = PamhyrExTimeDelegate(
|
||||
data = self._data,
|
||||
mode = self._study.time_system,
|
||||
parent = self
|
||||
data=self._data,
|
||||
mode=self._study.time_system,
|
||||
parent=self
|
||||
)
|
||||
|
||||
table = self.find(QTableView, "tableView")
|
||||
self._table = TableModel(
|
||||
table_view = table,
|
||||
table_headers = headers,
|
||||
editable_headers = self._data.header,
|
||||
delegates = {
|
||||
table_view=table,
|
||||
table_headers=headers,
|
||||
editable_headers=self._data.header,
|
||||
delegates={
|
||||
"time": self._delegate_time,
|
||||
},
|
||||
data = self._data,
|
||||
undo = self._undo_stack,
|
||||
opt_data = self._study.time_system
|
||||
data=self._data,
|
||||
undo=self._undo_stack,
|
||||
opt_data=self._study.time_system
|
||||
)
|
||||
|
||||
table.setModel(self._table)
|
||||
@@ -178,11 +182,11 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
||||
self.verticalLayout.addWidget(self.canvas)
|
||||
|
||||
self.plot = Plot(
|
||||
canvas = self.canvas,
|
||||
data = self._data,
|
||||
mode = self._study.time_system,
|
||||
trad = self._trad,
|
||||
toolbar = self.toolbar,
|
||||
canvas=self.canvas,
|
||||
data=self._data,
|
||||
mode=self._study.time_system,
|
||||
trad=self._trad,
|
||||
toolbar=self.toolbar,
|
||||
)
|
||||
self.plot.draw()
|
||||
|
||||
@@ -270,7 +274,6 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
||||
self._table.move_down(row)
|
||||
self.plot.update()
|
||||
|
||||
|
||||
def _copy(self):
|
||||
rows = self.index_selected_rows()
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ from View.BoundaryCondition.translate import BCTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class BCETranslate(BCTranslate):
|
||||
def __init__(self):
|
||||
super(BCETranslate, self).__init__()
|
||||
|
||||
@@ -52,8 +52,10 @@ logger = logging.getLogger()
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class ComboBoxDelegate(QItemDelegate):
|
||||
def __init__(self, data=None, mode="type", tab="", trad=None, parent=None):
|
||||
def __init__(self, data=None, mode="type", tab="",
|
||||
trad=None, parent=None):
|
||||
super(ComboBoxDelegate, self).__init__(parent)
|
||||
|
||||
self._data = data
|
||||
@@ -102,8 +104,9 @@ class ComboBoxDelegate(QItemDelegate):
|
||||
|
||||
def updateEditorGeometry(self, editor, option, index):
|
||||
r = QRect(option.rect)
|
||||
if self.editor.windowFlags() & Qt.Popup and editor.parent() is not None:
|
||||
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
|
||||
if self.editor.windowFlags() & Qt.Popup:
|
||||
if editor.parent() is not None:
|
||||
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
|
||||
editor.setGeometry(r)
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -157,20 +160,21 @@ class TableModel(PamhyrTableModel):
|
||||
if self._headers[column] == "name":
|
||||
self._undo.push(
|
||||
SetNameCommand(
|
||||
self._lst, self._tab,row, value
|
||||
self._lst, self._tab, row, value
|
||||
)
|
||||
)
|
||||
elif self._headers[column] == "type":
|
||||
key = next(k for k, v in self._long_types.items() if v == value)
|
||||
key = next(k for k, v in self._long_types.items()
|
||||
if v == value)
|
||||
self._undo.push(
|
||||
SetTypeCommand(
|
||||
self._lst, self._tab,row, BC_types[key]
|
||||
self._lst, self._tab, row, BC_types[key]
|
||||
)
|
||||
)
|
||||
elif self._headers[column] == "node":
|
||||
self._undo.push(
|
||||
SetNodeCommand(
|
||||
self._lst, self._tab,row, self._data.node(value)
|
||||
self._lst, self._tab, row, self._data.node(value)
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -185,7 +189,7 @@ class TableModel(PamhyrTableModel):
|
||||
|
||||
self._undo.push(
|
||||
AddCommand(
|
||||
self._lst, self._tab,row
|
||||
self._lst, self._tab, row
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ from PyQt5.QtWidgets import (
|
||||
from Model.BoundaryCondition.BoundaryCondition import BoundaryCondition
|
||||
from Model.BoundaryCondition.BoundaryConditionList import BoundaryConditionList
|
||||
|
||||
|
||||
class SetNameCommand(QUndoCommand):
|
||||
def __init__(self, bcs, tab, index, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -42,6 +43,7 @@ class SetNameCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._bcs.get(self._tab, self._index).name = self._new
|
||||
|
||||
|
||||
class SetNodeCommand(QUndoCommand):
|
||||
def __init__(self, bcs, tab, index, node):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -58,6 +60,7 @@ class SetNodeCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._bcs.get(self._tab, self._index).node = self._new
|
||||
|
||||
|
||||
class SetTypeCommand(QUndoCommand):
|
||||
def __init__(self, bcs, tab, index, _type):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -76,6 +79,7 @@ class SetTypeCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._bcs.set(self._tab, self._index, self._new)
|
||||
|
||||
|
||||
class AddCommand(QUndoCommand):
|
||||
def __init__(self, bcs, tab, index):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -94,6 +98,7 @@ class AddCommand(QUndoCommand):
|
||||
else:
|
||||
self._bcs.insert(self._tab, self._index, self._new)
|
||||
|
||||
|
||||
class DelCommand(QUndoCommand):
|
||||
def __init__(self, bcs, tab, rows):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -114,6 +119,7 @@ class DelCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._bcs.delete_i(self._tab, self._rows)
|
||||
|
||||
|
||||
class SortCommand(QUndoCommand):
|
||||
def __init__(self, bcs, tab, _reverse):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
@@ -62,6 +62,7 @@ _translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class BoundaryConditionWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "BoundaryConditions"
|
||||
_pamhyr_name = "Boundary conditions"
|
||||
@@ -70,10 +71,10 @@ class BoundaryConditionWindow(PamhyrWindow):
|
||||
name = self._pamhyr_name + " - " + study.name
|
||||
|
||||
super(BoundaryConditionWindow, self).__init__(
|
||||
title = name,
|
||||
study = study,
|
||||
config = config,
|
||||
trad = BCTranslate(),
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=BCTranslate(),
|
||||
parent=parent
|
||||
)
|
||||
|
||||
@@ -90,33 +91,33 @@ class BoundaryConditionWindow(PamhyrWindow):
|
||||
|
||||
for t in ["liquid", "solid", "suspenssion"]:
|
||||
self._delegate_type = ComboBoxDelegate(
|
||||
trad = self._trad,
|
||||
data = self._study.river,
|
||||
mode = "type",
|
||||
tab = t,
|
||||
trad=self._trad,
|
||||
data=self._study.river,
|
||||
mode="type",
|
||||
tab=t,
|
||||
parent=self
|
||||
)
|
||||
self._delegate_node = ComboBoxDelegate(
|
||||
trad = self._trad,
|
||||
data = self._study.river,
|
||||
mode = "node",
|
||||
tab = t,
|
||||
trad=self._trad,
|
||||
data=self._study.river,
|
||||
mode="node",
|
||||
tab=t,
|
||||
parent=self
|
||||
)
|
||||
|
||||
table = self.find(QTableView, f"tableView_{t}")
|
||||
self._table[t] = TableModel(
|
||||
table_view = table,
|
||||
table_headers = self._trad.get_dict("table_headers"),
|
||||
editable_headers = ["name", "type", "node"],
|
||||
delegates = {
|
||||
table_view=table,
|
||||
table_headers=self._trad.get_dict("table_headers"),
|
||||
editable_headers=["name", "type", "node"],
|
||||
delegates={
|
||||
"type": self._delegate_type,
|
||||
"node": self._delegate_node,
|
||||
},
|
||||
trad = self._trad,
|
||||
data = self._study.river,
|
||||
undo = self._undo_stack,
|
||||
opt_data = t,
|
||||
trad=self._trad,
|
||||
data=self._study.river,
|
||||
undo=self._undo_stack,
|
||||
opt_data=t,
|
||||
)
|
||||
table.setModel(self._table[t])
|
||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
@@ -126,7 +127,7 @@ class BoundaryConditionWindow(PamhyrWindow):
|
||||
def setup_graph(self):
|
||||
self.graph_widget = GraphWidget(
|
||||
self._study.river,
|
||||
min_size=None, size=(200,200),
|
||||
min_size=None, size=(200, 200),
|
||||
only_display=True,
|
||||
parent=self
|
||||
)
|
||||
@@ -213,17 +214,17 @@ class BoundaryConditionWindow(PamhyrWindow):
|
||||
tab = self.current_tab()
|
||||
rows = self.index_selected_rows()
|
||||
for row in rows:
|
||||
win = self.sub_win_filter_first(
|
||||
"Edit boundary condition",
|
||||
contain = [f"({self._bcs.get(tab, row).id})"]
|
||||
)
|
||||
data = self._bcs.get(tab, row)
|
||||
|
||||
if win is None:
|
||||
win = EditBoundaryConditionWindow(
|
||||
data=self._bcs.get(tab, row),
|
||||
study=self._study,
|
||||
parent=self
|
||||
)
|
||||
win.show()
|
||||
else:
|
||||
win.activateWindow()
|
||||
if self.sub_window_exists(
|
||||
EditBoundaryConditionWindow,
|
||||
data=[self._study, None, data]
|
||||
):
|
||||
continue
|
||||
|
||||
win = EditBoundaryConditionWindow(
|
||||
data=data,
|
||||
study=self._study,
|
||||
parent=self
|
||||
)
|
||||
win.show()
|
||||
@@ -37,6 +37,7 @@ BC_types = {
|
||||
"SL": Solid,
|
||||
}
|
||||
|
||||
|
||||
class BCTranslate(PamhyrTranslate):
|
||||
def __init__(self):
|
||||
super(BCTranslate, self).__init__()
|
||||
|
||||
@@ -22,6 +22,7 @@ from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class CheckListTranslate(PamhyrTranslate):
|
||||
def __init__(self):
|
||||
super(CheckListTranslate, self).__init__()
|
||||
|
||||
@@ -44,13 +44,14 @@ from View.CheckList.Translate import CheckListTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class CheckListWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "CheckList"
|
||||
_pamhyr_name = "Check list"
|
||||
|
||||
signalStatus = pyqtSignal(str)
|
||||
|
||||
def __init__(self, autorun:bool=True,
|
||||
def __init__(self, autorun: bool = True,
|
||||
study=None, config=None,
|
||||
solver=None, parent=None):
|
||||
self._autorun = autorun
|
||||
@@ -59,14 +60,17 @@ class CheckListWindow(PamhyrWindow):
|
||||
name = self._pamhyr_name + " - " + study.name
|
||||
|
||||
super(CheckListWindow, self).__init__(
|
||||
title = name,
|
||||
study = study,
|
||||
config = config,
|
||||
trad = CheckListTranslate(),
|
||||
options = [],
|
||||
parent = parent
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=CheckListTranslate(),
|
||||
options=[],
|
||||
parent=parent
|
||||
)
|
||||
|
||||
# Add solver to hash computation data
|
||||
self._hash_data.append(self._solver)
|
||||
|
||||
self._checker_list = (
|
||||
self._study.checkers() +
|
||||
self._solver.checkers()
|
||||
@@ -81,9 +85,9 @@ class CheckListWindow(PamhyrWindow):
|
||||
def setup_table(self):
|
||||
table = self.find(QTableView, f"tableView")
|
||||
self._table = TableModel(
|
||||
table_view = table,
|
||||
table_headers = self._trad.get_dict("table_headers"),
|
||||
data = self._checker_list,
|
||||
table_view=table,
|
||||
table_headers=self._trad.get_dict("table_headers"),
|
||||
data=self._checker_list,
|
||||
)
|
||||
|
||||
def setup_progress_bar(self):
|
||||
@@ -96,7 +100,8 @@ class CheckListWindow(PamhyrWindow):
|
||||
def setup_connections(self):
|
||||
self.find(QPushButton, "pushButton_ok").clicked.connect(self.accept)
|
||||
self.find(QPushButton, "pushButton_retry").clicked.connect(self.retry)
|
||||
self.find(QPushButton, "pushButton_cancel").clicked.connect(self.reject)
|
||||
self.find(QPushButton, "pushButton_cancel")\
|
||||
.clicked.connect(self.reject)
|
||||
|
||||
def setup_thread(self):
|
||||
self._worker = Worker(self._study, self._checker_list)
|
||||
@@ -120,7 +125,8 @@ class CheckListWindow(PamhyrWindow):
|
||||
|
||||
def _compute_status(self):
|
||||
ok = len(list(filter(lambda c: c.is_ok(), self._checker_list)))
|
||||
warning = len(list(filter(lambda c: c.is_warning(), self._checker_list)))
|
||||
warning = len(
|
||||
list(filter(lambda c: c.is_warning(), self._checker_list)))
|
||||
error = len(list(filter(lambda c: c.is_error(), self._checker_list)))
|
||||
|
||||
return ok, warning, error
|
||||
@@ -164,7 +170,7 @@ class CheckListWindow(PamhyrWindow):
|
||||
|
||||
self.update_statusbar()
|
||||
|
||||
def update(self, key:str):
|
||||
def update(self, key: str):
|
||||
if key == "start":
|
||||
self.start_compute()
|
||||
self.info_compute("Starting ...")
|
||||
@@ -187,4 +193,4 @@ class CheckListWindow(PamhyrWindow):
|
||||
|
||||
def accept(self):
|
||||
self._parent.solver_log(self._solver)
|
||||
#self.end()
|
||||
# self.end()
|
||||
@@ -22,6 +22,7 @@ from PyQt5.QtCore import (
|
||||
Qt, QObject, pyqtSlot, pyqtSignal
|
||||
)
|
||||
|
||||
|
||||
class Worker(QObject):
|
||||
signalStatus = pyqtSignal(str)
|
||||
|
||||
@@ -42,6 +43,6 @@ class Worker(QObject):
|
||||
self.signalStatus.emit(checker.name)
|
||||
|
||||
# Run checker
|
||||
checker.run(self._study)
|
||||
checker._run(self._study)
|
||||
|
||||
self.signalStatus.emit("progress")
|
||||
@@ -24,6 +24,7 @@ from PyQt5.QtWidgets import (
|
||||
QPushButton,
|
||||
)
|
||||
|
||||
|
||||
class ConfigureSolverWindow(PamhyrDialog):
|
||||
_pamhyr_ui = "ConfigureAddSolverDialog"
|
||||
_pamhyr_name = "Add/Edit Solver"
|
||||
@@ -35,9 +36,9 @@ class ConfigureSolverWindow(PamhyrDialog):
|
||||
name = "Add a new Solver"
|
||||
|
||||
super(ConfigureSolverWindow, self).__init__(
|
||||
title = name,
|
||||
config = config,
|
||||
options = [],
|
||||
title=name,
|
||||
config=config,
|
||||
options=[],
|
||||
parent=parent
|
||||
)
|
||||
|
||||
@@ -67,16 +68,19 @@ class ConfigureSolverWindow(PamhyrDialog):
|
||||
# File button
|
||||
buttons = {
|
||||
"pushButton_input": (lambda: self.file_dialog(
|
||||
select_file = True,
|
||||
callback = lambda f: self.set_line_edit_text("lineEdit_input", f[0])
|
||||
select_file=True,
|
||||
callback=lambda f: self.set_line_edit_text(
|
||||
"lineEdit_input", f[0])
|
||||
)),
|
||||
"pushButton_solver": (lambda: self.file_dialog(
|
||||
select_file = True,
|
||||
callback = lambda f: self.set_line_edit_text("lineEdit_solver", f[0])
|
||||
select_file=True,
|
||||
callback=lambda f: self.set_line_edit_text(
|
||||
"lineEdit_solver", f[0])
|
||||
)),
|
||||
"pushButton_output": (lambda: self.file_dialog(
|
||||
select_file = True,
|
||||
callback = lambda f: self.set_line_edit_text("lineEdit_output", f[0])
|
||||
select_file=True,
|
||||
callback=lambda f: self.set_line_edit_text(
|
||||
"lineEdit_output", f[0])
|
||||
)),
|
||||
}
|
||||
|
||||
@@ -92,9 +96,11 @@ class ConfigureSolverWindow(PamhyrDialog):
|
||||
else:
|
||||
# Build new solver from selected type
|
||||
stype = self.get_combobox_text("comboBox_solver")
|
||||
self.data = solver_type_list[stype](self.get_line_edit_text("lineEdit_name"))
|
||||
self.data = solver_type_list[stype](
|
||||
self.get_line_edit_text("lineEdit_name"))
|
||||
|
||||
self.data.description = self.get_line_edit_text("lineEdit_description")
|
||||
self.data.description = self.get_line_edit_text(
|
||||
"lineEdit_description")
|
||||
self.data.set_input(
|
||||
self.get_line_edit_text("lineEdit_input"),
|
||||
self.get_line_edit_text("lineEdit_input_cmd")
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# Translate.py -- Pamhyr
|
||||
# Copyright (C) 2023 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 PyQt5.QtCore import QCoreApplication
|
||||
|
||||
from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class ConfigureTranslate(PamhyrTranslate):
|
||||
def __init__(self):
|
||||
super(ConfigureTranslate, self).__init__()
|
||||
|
||||
self._sub_dict["table_headers"] = {
|
||||
"name": _translate("Configure", "Name"),
|
||||
"type": _translate("Configure", "Type"),
|
||||
"description": _translate("Configure", "Description"),
|
||||
}
|
||||
@@ -22,11 +22,13 @@ from copy import deepcopy
|
||||
|
||||
from config import Config
|
||||
from View.Tools.PamhyrWindow import PamhyrDialog
|
||||
from View.Tools.PamhyrTable import PamhyrTableModel
|
||||
|
||||
from View.Stricklers.Table import TableModel
|
||||
from View.Stricklers.translate import *
|
||||
from View.Stricklers.translate import StricklersTranslate
|
||||
from View.Stricklers.UndoCommand import *
|
||||
|
||||
from View.Configure.Translate import ConfigureTranslate
|
||||
from View.Configure.Solver.Window import ConfigureSolverWindow
|
||||
|
||||
from PyQt5.QtGui import (
|
||||
@@ -47,50 +49,29 @@ from Solver.Solvers import solver_long_name
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
class SolverTableModel(QAbstractTableModel):
|
||||
def __init__(self, headers=[], rows=[]):
|
||||
super(QAbstractTableModel, self).__init__()
|
||||
self.rows = rows
|
||||
self.headers = headers
|
||||
|
||||
def rowCount(self, parent):
|
||||
return len(self.rows)
|
||||
|
||||
def columnCount(self, parent):
|
||||
return len(self.headers)
|
||||
|
||||
class SolverTableModel(PamhyrTableModel):
|
||||
def data(self, index, role):
|
||||
if role != Qt.ItemDataRole.DisplayRole:
|
||||
return QVariant()
|
||||
|
||||
ret = self.rows[index.row()][self.headers[index.column()]]
|
||||
ret = self._data[index.row()][self._headers[index.column()]]
|
||||
|
||||
if self.headers[index.column()] == "type":
|
||||
if self._headers[index.column()] == "type":
|
||||
ret = solver_long_name[ret]
|
||||
|
||||
return ret
|
||||
|
||||
def headerData(self, section, orientation, role):
|
||||
if (role == Qt.ItemDataRole.DisplayRole and
|
||||
orientation == Qt.Orientation.Horizontal):
|
||||
return self.headers[section].capitalize()
|
||||
|
||||
if (role == Qt.ItemDataRole.DisplayRole and
|
||||
orientation == Qt.Orientation.Vertical):
|
||||
return section + 1 # Start at 1
|
||||
|
||||
return QVariant()
|
||||
|
||||
def removeRow(self, index):
|
||||
del self.rows[index.row()]
|
||||
del self._data[index.row()]
|
||||
self.layoutChanged.emit()
|
||||
|
||||
def add_solver(self, solver):
|
||||
self.rows.append(solver)
|
||||
self._data.append(solver)
|
||||
self.layoutChanged.emit()
|
||||
|
||||
def change_solver(self, solver, index):
|
||||
self.rows[index.row()] = solver
|
||||
self._data[index.row()] = solver
|
||||
self.layoutChanged.emit()
|
||||
|
||||
|
||||
@@ -103,12 +84,15 @@ class ConfigureWindow(PamhyrDialog):
|
||||
config = Config()
|
||||
|
||||
super(ConfigureWindow, self).__init__(
|
||||
title = self._pamhyr_name,
|
||||
config = config,
|
||||
options = [],
|
||||
title=self._pamhyr_name,
|
||||
config=config,
|
||||
trad=ConfigureTranslate(),
|
||||
options=[],
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._trad_stricklers = StricklersTranslate()
|
||||
|
||||
self.setup_custom_sc()
|
||||
self.setup_solver()
|
||||
self.setup_stricklers()
|
||||
@@ -118,43 +102,43 @@ class ConfigureWindow(PamhyrDialog):
|
||||
def setup_solver(self):
|
||||
table = self.find(QTableView, "tableView_solver")
|
||||
self.solver_table_model = SolverTableModel(
|
||||
headers = ["name", "type", "description"],
|
||||
rows = self._config.solvers
|
||||
table_view=table,
|
||||
table_headers=self._trad.get_dict("table_headers"),
|
||||
data=self._config.solvers
|
||||
)
|
||||
table.setModel(self.solver_table_model)
|
||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||
table.setAlternatingRowColors(True)
|
||||
table.resizeColumnsToContents()
|
||||
|
||||
def setup_stricklers(self):
|
||||
table = self.find(QTableView, f"tableView_stricklers")
|
||||
self._stricklers = deepcopy(self._config.stricklers)
|
||||
self._stricklers_table = TableModel(
|
||||
data = self._stricklers,
|
||||
undo = self._undo_stack,
|
||||
table_view=table,
|
||||
table_headers=self._trad_stricklers.get_dict("table_headers"),
|
||||
editable_headers=["name", "comment", "minor", "medium"],
|
||||
data=self._stricklers,
|
||||
undo=self._undo_stack,
|
||||
)
|
||||
table.setModel(self._stricklers_table)
|
||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||
table.setAlternatingRowColors(True)
|
||||
|
||||
def setup_data(self):
|
||||
# Meshing_Tool
|
||||
self.set_line_edit_text("lineEdit_meshing_tool", self._config.meshing_tool)
|
||||
self.set_line_edit_text("lineEdit_meshing_tool",
|
||||
self._config.meshing_tool)
|
||||
|
||||
# Const
|
||||
self.set_line_edit_text("lineEdit_segment", str(self._config.segment))
|
||||
self.set_line_edit_text("lineEdit_max_listing", str(self._config.max_listing))
|
||||
self.set_line_edit_text("lineEdit_max_listing",
|
||||
str(self._config.max_listing))
|
||||
|
||||
# Backup
|
||||
self.set_check_box("checkBox_backup", self._config.backup_enable)
|
||||
self.set_line_edit_text("lineEdit_backup_path", self._config.backup_path)
|
||||
self.set_time_edit("timeEdit_backup_frequence", self._config.backup_frequence)
|
||||
self.set_line_edit_text("lineEdit_backup_path",
|
||||
self._config.backup_path)
|
||||
self.set_time_edit("timeEdit_backup_frequence",
|
||||
self._config.backup_frequence)
|
||||
self.set_spin_box("spinBox_backup_max", self._config.backup_max)
|
||||
|
||||
# Editor
|
||||
self.set_line_edit_text("lineEdit_editor_cmd", str(self._config.editor))
|
||||
self.set_line_edit_text("lineEdit_editor_cmd",
|
||||
str(self._config.editor))
|
||||
|
||||
# Language
|
||||
languages = Config.languages()
|
||||
@@ -179,14 +163,14 @@ class ConfigureWindow(PamhyrDialog):
|
||||
"pushButton_stricklers_sort": self.sort_stricklers,
|
||||
# Others
|
||||
"pushButton_backup_path": lambda: self.file_dialog(
|
||||
select_file = False,
|
||||
callback = lambda f: self.set_line_edit_text(
|
||||
select_file=False,
|
||||
callback=lambda f: self.set_line_edit_text(
|
||||
"lineEdit_backup_path", f[0]
|
||||
)
|
||||
),
|
||||
"pushButton_meshing_tool" : lambda: self.file_dialog(
|
||||
select_file = True,
|
||||
callback = lambda f: self.set_line_edit_text(
|
||||
"pushButton_meshing_tool": lambda: self.file_dialog(
|
||||
select_file=True,
|
||||
callback=lambda f: self.set_line_edit_text(
|
||||
"lineEdit_meshing_tool", f[0]
|
||||
)
|
||||
),
|
||||
@@ -197,19 +181,23 @@ class ConfigureWindow(PamhyrDialog):
|
||||
|
||||
def accept(self):
|
||||
# Solvers
|
||||
self._config.solvers = self.solver_table_model.rows.copy()
|
||||
self._config.solvers = self.solver_table_model._data.copy()
|
||||
|
||||
# Meshing_Tool
|
||||
self._config.meshing_tool = self.get_line_edit_text("lineEdit_meshing_tool")
|
||||
self._config.meshing_tool = self.get_line_edit_text(
|
||||
"lineEdit_meshing_tool")
|
||||
|
||||
# Const
|
||||
self._config.segment = self.get_line_edit_text("lineEdit_segment")
|
||||
self._config.max_listing = self.get_line_edit_text("lineEdit_max_listing")
|
||||
self._config.max_listing = self.get_line_edit_text(
|
||||
"lineEdit_max_listing")
|
||||
|
||||
# Backup
|
||||
self._config.backup_enable = self.get_check_box("checkBox_backup")
|
||||
self._config.backup_path = self.get_line_edit_text("lineEdit_backup_path")
|
||||
self._config.backup_frequence = self.get_time_edit("timeEdit_backup_frequence")
|
||||
self._config.backup_path = self.get_line_edit_text(
|
||||
"lineEdit_backup_path")
|
||||
self._config.backup_frequence = self.get_time_edit(
|
||||
"timeEdit_backup_frequence")
|
||||
self._config.backup_max = self.get_spin_box("spinBox_backup_max")
|
||||
|
||||
# Stricklers
|
||||
@@ -219,7 +207,8 @@ class ConfigureWindow(PamhyrDialog):
|
||||
self._config.editor = self.get_line_edit_text("lineEdit_editor_cmd")
|
||||
|
||||
# Language
|
||||
self._config.lang = Config.languages()[self.get_combobox_text("comboBox_language")]
|
||||
self._config.lang = Config.languages(
|
||||
)[self.get_combobox_text("comboBox_language")]
|
||||
|
||||
self.end()
|
||||
|
||||
@@ -232,6 +221,7 @@ class ConfigureWindow(PamhyrDialog):
|
||||
self.close()
|
||||
|
||||
# Debug
|
||||
|
||||
def set_debug(self):
|
||||
self._config.debug = not self._config.debug
|
||||
logger.info(f"Debug mode set : {self._config.debug}")
|
||||
@@ -240,15 +230,17 @@ class ConfigureWindow(PamhyrDialog):
|
||||
# Solvers
|
||||
|
||||
def edit_solver(self):
|
||||
indexes = self.find(QTableView, "tableView_solver").selectionModel().selectedRows()
|
||||
indexes = self.find(
|
||||
QTableView, "tableView_solver").selectionModel().selectedRows()
|
||||
for index in indexes:
|
||||
self.edit_solver = ConfigureSolverWindow(
|
||||
data=self.solver_table_model.rows[index.row()],
|
||||
data=self.solver_table_model._data[index.row()],
|
||||
config=self._config,
|
||||
parent=self
|
||||
)
|
||||
if self.edit_solver.exec_():
|
||||
self.solver_table_model.change_solver(self.edit_solver.data, index)
|
||||
self.solver_table_model.change_solver(
|
||||
self.edit_solver.data, index)
|
||||
|
||||
def add_solver(self):
|
||||
dialog_solver = ConfigureSolverWindow(parent=self)
|
||||
@@ -256,7 +248,8 @@ class ConfigureWindow(PamhyrDialog):
|
||||
self.solver_table_model.add_solver(dialog_solver.data)
|
||||
|
||||
def remove_solver(self):
|
||||
indices = self.find(QTableView, "tableView_solver").selectionModel().selectedRows()
|
||||
indices = self.find(
|
||||
QTableView, "tableView_solver").selectionModel().selectedRows()
|
||||
for index in sorted(indices):
|
||||
self.solver_table_model.removeRow(index)
|
||||
|
||||
|
||||
+22
-12
@@ -21,6 +21,7 @@ import logging
|
||||
from tools import trace, timer
|
||||
|
||||
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||
from View.Tools.PamhyrPythonEditor import PamhyrPythonEditor
|
||||
|
||||
from PyQt5.QtGui import (
|
||||
QKeySequence,
|
||||
@@ -37,13 +38,16 @@ from PyQt5.QtWidgets import (
|
||||
QFileDialog, QTableView, QAbstractItemView,
|
||||
QUndoStack, QShortcut, QAction, QItemDelegate,
|
||||
QComboBox, QVBoxLayout, QHeaderView, QTabWidget,
|
||||
QProgressBar, QLabel, QTextEdit,
|
||||
QProgressBar, QLabel, QTextEdit, QHBoxLayout,
|
||||
)
|
||||
|
||||
from PyQt5.Qsci import QsciScintilla, QsciLexerPython
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class ReplWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "DebugRepl"
|
||||
_pamhyr_name = "Debug REPL"
|
||||
@@ -51,19 +55,25 @@ class ReplWindow(PamhyrWindow):
|
||||
def __init__(self, study=None, config=None,
|
||||
solver=None, parent=None):
|
||||
super(ReplWindow, self).__init__(
|
||||
title = self._pamhyr_name,
|
||||
study = study,
|
||||
config = config,
|
||||
options = [],
|
||||
parent = parent
|
||||
title=self._pamhyr_name,
|
||||
study=study,
|
||||
config=config,
|
||||
options=[],
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self.__debug_exec_result__ = None
|
||||
self._history = []
|
||||
self._history_ind = 0
|
||||
|
||||
self.setup_editor()
|
||||
self.setup_connections()
|
||||
|
||||
def setup_editor(self):
|
||||
layout = self.find(QHBoxLayout, "horizontalLayout")
|
||||
self._editor = PamhyrPythonEditor()
|
||||
layout.insertWidget(0, self._editor)
|
||||
|
||||
def setup_connections(self):
|
||||
self._hup_sc = QShortcut(QKeySequence("ctrl+Up"), self)
|
||||
self._hdown_sc = QShortcut(QKeySequence("ctrl+Down"), self)
|
||||
@@ -75,19 +85,19 @@ class ReplWindow(PamhyrWindow):
|
||||
def history_up(self):
|
||||
if self._history_ind < len(self._history):
|
||||
self._history_ind += 1
|
||||
self.set_plaintext_edit_text("plainTextEdit", self._history[-self._history_ind])
|
||||
self._editor.setText(self._history[-self._history_ind])
|
||||
|
||||
def history_down(self):
|
||||
if self._history_ind > 0:
|
||||
self._history_ind -= 1
|
||||
self.set_plaintext_edit_text("plainTextEdit", self._history[-self._history_ind])
|
||||
self._editor.setText(self._history[-self._history_ind])
|
||||
else:
|
||||
self.set_plaintext_edit_text("plainTextEdit", "")
|
||||
self._editor.setText("")
|
||||
|
||||
def eval_python(self):
|
||||
code = self.get_plaintext_edit_text("plainTextEdit")
|
||||
code = self._editor.text()
|
||||
self._history.append(code)
|
||||
self.set_plaintext_edit_text("plainTextEdit", "")
|
||||
self._editor.setText("")
|
||||
self._history_ind = 0
|
||||
|
||||
# Code to rich_code
|
||||
@@ -95,7 +105,7 @@ class ReplWindow(PamhyrWindow):
|
||||
# Add return variable for results display at last row
|
||||
rich_code[-1] = "self.__debug_exec_result__ = " + rich_code[-1]
|
||||
rich_code = "\n".join(rich_code)
|
||||
logger.debug(f"User debug command : {rich_code}")
|
||||
logger.debug(f"User debug command : \n{rich_code}")
|
||||
try:
|
||||
value = exec(rich_code)
|
||||
value = self.__debug_exec_result__
|
||||
|
||||
+18
-22
@@ -16,22 +16,21 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os, sys
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtGui import QDesktopServices
|
||||
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QAction
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
|
||||
|
||||
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||
|
||||
from PyQt5.QtCore import QCoreApplication
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QAction
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
|
||||
|
||||
class DocWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "WebView"
|
||||
_pamhyr_name = "Doc"
|
||||
@@ -57,12 +56,11 @@ class DocWindow(PamhyrWindow):
|
||||
study=None, config=None,
|
||||
parent=None):
|
||||
super(DocWindow, self).__init__(
|
||||
title = self._pamhyr_name,
|
||||
study = study,
|
||||
config = config,
|
||||
options = [],
|
||||
parent = parent
|
||||
|
||||
title=self._pamhyr_name,
|
||||
study=study,
|
||||
config=config,
|
||||
options=[],
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._path = self._path_file(filename)
|
||||
@@ -73,10 +71,10 @@ class DocWindow(PamhyrWindow):
|
||||
|
||||
def setup_connection(self):
|
||||
self.findChild(QAction, "action_back").triggered.connect(self.back)
|
||||
self.findChild(QAction, "action_forward").triggered.connect(self.forward)
|
||||
|
||||
self.findChild(QAction, "action_firefox").triggered.connect(self.open_in_firefox)
|
||||
self.findChild(QAction, "action_forward").triggered.connect(
|
||||
self.forward)
|
||||
|
||||
self.findChild(QAction, "action_open").triggered.connect(self.open)
|
||||
|
||||
def setup_web_engine(self):
|
||||
vl = self.find(QVBoxLayout, "verticalLayout")
|
||||
@@ -99,8 +97,6 @@ class DocWindow(PamhyrWindow):
|
||||
def forward(self):
|
||||
self._web_view.forward()
|
||||
|
||||
def open_in_firefox(self):
|
||||
_ = subprocess.Popen(
|
||||
f"firefox {self._path}",
|
||||
shell = True
|
||||
)
|
||||
def open(self):
|
||||
url = QUrl(f"file://{self._path}")
|
||||
QDesktopServices.openUrl(url)
|
||||
@@ -18,12 +18,13 @@
|
||||
|
||||
from View.Tools.PamhyrWindow import PamhyrWindow
|
||||
|
||||
|
||||
class DummyWindow(PamhyrWindow):
|
||||
__ui = "Dummy"
|
||||
__name = "Pamhyr Dummy Window"
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(DummyWindow, self).__init__(
|
||||
title = self.__name,
|
||||
parent = parent,
|
||||
title=self.__name,
|
||||
parent=parent,
|
||||
)
|
||||
@@ -25,10 +25,11 @@ from PyQt5.QtCore import (
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class PlotStricklers(PamhyrPlot):
|
||||
def draw_frictions(self, frictions, color="r"):
|
||||
lst = frictions
|
||||
lst.sort(key = lambda s: s.begin_kp)
|
||||
lst.sort(key=lambda s: s.begin_kp)
|
||||
|
||||
coef = flatten(
|
||||
map(
|
||||
@@ -57,7 +58,6 @@ class PlotStricklers(PamhyrPlot):
|
||||
color=color, lw=1.
|
||||
)
|
||||
|
||||
|
||||
@timer
|
||||
def draw(self, highlight=None):
|
||||
self.canvas.axes.cla()
|
||||
@@ -77,7 +77,7 @@ class PlotStricklers(PamhyrPlot):
|
||||
|
||||
kp = self.data.reach.get_kp()
|
||||
self.canvas.axes.set_xlim(
|
||||
left = min(kp), right = max(kp)
|
||||
left=min(kp), right=max(kp)
|
||||
)
|
||||
|
||||
frictions = self.data.frictions
|
||||
@@ -108,6 +108,6 @@ class PlotStricklers(PamhyrPlot):
|
||||
|
||||
@timer
|
||||
def update(self, ind=None):
|
||||
if self._init == False:
|
||||
if not self._init:
|
||||
self.draw()
|
||||
return
|
||||
@@ -49,8 +49,10 @@ logger = logging.getLogger()
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class ComboBoxDelegate(QItemDelegate):
|
||||
def __init__(self, data=None, study=None, mode="stricklers", parent=None):
|
||||
def __init__(self, data=None, study=None,
|
||||
mode="stricklers", parent=None):
|
||||
super(ComboBoxDelegate, self).__init__(parent)
|
||||
|
||||
self._data = data
|
||||
@@ -86,8 +88,9 @@ class ComboBoxDelegate(QItemDelegate):
|
||||
|
||||
def updateEditorGeometry(self, editor, option, index):
|
||||
r = QRect(option.rect)
|
||||
if self.editor.windowFlags() & Qt.Popup and editor.parent() is not None:
|
||||
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
|
||||
if self.editor.windowFlags() & Qt.Popup:
|
||||
if editor.parent() is not None:
|
||||
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
|
||||
editor.setGeometry(r)
|
||||
|
||||
@pyqtSlot()
|
||||
@@ -115,12 +118,12 @@ class TableModel(PamhyrTableModel):
|
||||
return self._lst.get(row).end_kp
|
||||
elif self._headers[column] == "begin_strickler":
|
||||
value = self._lst.get(row).begin_strickler
|
||||
if value == None:
|
||||
if value is None:
|
||||
return _translate("Frictions", "Not defined")
|
||||
return str(value)
|
||||
elif self._headers[column] == "end_strickler":
|
||||
value = self._lst.get(row).end_strickler
|
||||
if value == None:
|
||||
if value is None:
|
||||
return _translate("Frictions", "Not defined")
|
||||
return str(value)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ from PyQt5.QtWidgets import (
|
||||
from Model.Friction.Friction import Friction
|
||||
from Model.Friction.FrictionList import FrictionList
|
||||
|
||||
|
||||
class SetNameCommand(QUndoCommand):
|
||||
def __init__(self, frictions, index, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -41,6 +42,7 @@ class SetNameCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._frictions.get(self._index).name = self._new
|
||||
|
||||
|
||||
class SetBeginCommand(QUndoCommand):
|
||||
def __init__(self, frictions, index, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -56,6 +58,7 @@ class SetBeginCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._frictions.get(self._index).begin_kp = float(self._new)
|
||||
|
||||
|
||||
class SetEndCommand(QUndoCommand):
|
||||
def __init__(self, frictions, index, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -87,6 +90,7 @@ class SetBeginStricklerCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._frictions.get(self._index).begin_strickler = self._new
|
||||
|
||||
|
||||
class SetEndStricklerCommand(QUndoCommand):
|
||||
def __init__(self, frictions, index, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -118,6 +122,7 @@ class SetEdgeCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._frictions.get(self._index).edge = self._new
|
||||
|
||||
|
||||
class AddCommand(QUndoCommand):
|
||||
def __init__(self, frictions, index, reach):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -137,6 +142,7 @@ class AddCommand(QUndoCommand):
|
||||
else:
|
||||
self._frictions.insert(self._index, self._new)
|
||||
|
||||
|
||||
class DelCommand(QUndoCommand):
|
||||
def __init__(self, frictions, rows):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -156,6 +162,7 @@ class DelCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._frictions.delete_i(self._rows)
|
||||
|
||||
|
||||
class SortCommand(QUndoCommand):
|
||||
def __init__(self, frictions, _reverse):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
@@ -56,6 +56,7 @@ from View.Stricklers.Window import StricklersWindow
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class FrictionsWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "Frictions"
|
||||
_pamhyr_name = "Edit frictions"
|
||||
@@ -75,43 +76,45 @@ class FrictionsWindow(PamhyrWindow):
|
||||
)
|
||||
|
||||
super(FrictionsWindow, self).__init__(
|
||||
title = name,
|
||||
study = study,
|
||||
config = config,
|
||||
trad = FrictionsTranslate(),
|
||||
parent = parent
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=FrictionsTranslate(),
|
||||
parent=parent
|
||||
)
|
||||
|
||||
# Add reach to hash computation data
|
||||
self._hash_data.append(self._reach)
|
||||
|
||||
self.setup_table()
|
||||
self.setup_graph()
|
||||
self.setup_connections()
|
||||
|
||||
|
||||
def setup_table(self):
|
||||
self._table = {}
|
||||
|
||||
self._delegate_stricklers = ComboBoxDelegate(
|
||||
data = self._reach,
|
||||
study = self._study,
|
||||
mode = "stricklers",
|
||||
data=self._reach,
|
||||
study=self._study,
|
||||
mode="stricklers",
|
||||
parent=self
|
||||
)
|
||||
|
||||
table = self.find(QTableView, f"tableView")
|
||||
self._table = TableModel(
|
||||
table_view = table,
|
||||
table_headers = self._trad.get_dict("table_headers"),
|
||||
editable_headers = [
|
||||
table_view=table,
|
||||
table_headers=self._trad.get_dict("table_headers"),
|
||||
editable_headers=[
|
||||
"name", "begin_kp", "end_kp",
|
||||
"begin_strickler", "end_strickler"
|
||||
],
|
||||
delegates = {
|
||||
delegates={
|
||||
"begin_strickler": self._delegate_stricklers,
|
||||
"end_strickler": self._delegate_stricklers,
|
||||
},
|
||||
data = self._reach,
|
||||
undo = self._undo_stack,
|
||||
opt_data = self._study
|
||||
data=self._reach,
|
||||
undo=self._undo_stack,
|
||||
opt_data=self._study
|
||||
)
|
||||
table.setModel(self._table)
|
||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
@@ -125,10 +128,10 @@ class FrictionsWindow(PamhyrWindow):
|
||||
self.plot_layout.addWidget(self.canvas)
|
||||
|
||||
self.plot = PlotKPZ(
|
||||
canvas = self.canvas,
|
||||
data = self._reach.reach,
|
||||
toolbar = None,
|
||||
display_current = False
|
||||
canvas=self.canvas,
|
||||
data=self._reach.reach,
|
||||
toolbar=None,
|
||||
display_current=False
|
||||
)
|
||||
self.plot.draw()
|
||||
|
||||
@@ -138,18 +141,18 @@ class FrictionsWindow(PamhyrWindow):
|
||||
self.plot_layout_2.addWidget(self.canvas_2)
|
||||
|
||||
self.plot_2 = PlotStricklers(
|
||||
canvas = self.canvas_2,
|
||||
data = self._reach,
|
||||
toolbar = None
|
||||
canvas=self.canvas_2,
|
||||
data=self._reach,
|
||||
toolbar=None
|
||||
)
|
||||
self.plot_2.draw()
|
||||
|
||||
|
||||
def setup_connections(self):
|
||||
self.find(QAction, "action_add").triggered.connect(self.add)
|
||||
self.find(QAction, "action_del").triggered.connect(self.delete)
|
||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||
self.find(QAction, "action_edit_stricklers").triggered.connect(self.edit_stricklers)
|
||||
self.find(QAction, "action_edit_stricklers").triggered.connect(
|
||||
self.edit_stricklers)
|
||||
|
||||
table = self.find(QTableView, f"tableView")
|
||||
table.selectionModel()\
|
||||
@@ -185,17 +188,17 @@ class FrictionsWindow(PamhyrWindow):
|
||||
highlight = (sec.begin_kp, sec.end_kp)
|
||||
|
||||
self.plot = PlotKPZ(
|
||||
canvas = self.canvas,
|
||||
data = reach,
|
||||
toolbar = None,
|
||||
display_current = False
|
||||
canvas=self.canvas,
|
||||
data=reach,
|
||||
toolbar=None,
|
||||
display_current=False
|
||||
)
|
||||
self.plot.draw(highlight=highlight)
|
||||
|
||||
self.plot = PlotStricklers(
|
||||
canvas = self.canvas_2,
|
||||
data = data,
|
||||
toolbar = None
|
||||
canvas=self.canvas_2,
|
||||
data=data,
|
||||
toolbar=None
|
||||
)
|
||||
self.plot.draw(highlight=highlight)
|
||||
|
||||
@@ -237,17 +240,15 @@ class FrictionsWindow(PamhyrWindow):
|
||||
self._table.redo()
|
||||
|
||||
def edit_stricklers(self):
|
||||
strick = self.sub_win_filter_first(
|
||||
"Stricklers",
|
||||
contain = []
|
||||
)
|
||||
if self.sub_window_exists(
|
||||
StricklersWindow,
|
||||
data=[self._study, self.parent.conf]
|
||||
):
|
||||
return
|
||||
|
||||
if strick is None:
|
||||
strick = StricklersWindow(
|
||||
study = self._study,
|
||||
config = self.parent.conf,
|
||||
parent = self
|
||||
)
|
||||
strick.show()
|
||||
else:
|
||||
strick.activateWindow()
|
||||
strick = StricklersWindow(
|
||||
study=self._study,
|
||||
config=self.parent.conf,
|
||||
parent=self
|
||||
)
|
||||
strick.show()
|
||||
@@ -22,6 +22,7 @@ from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class FrictionsTranslate(PamhyrTranslate):
|
||||
def __init__(self):
|
||||
super(FrictionsTranslate, self).__init__()
|
||||
|
||||
+29
-20
@@ -29,15 +29,16 @@ _translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class PlotAC(PamhyrPlot):
|
||||
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||
plot_xy=None, parent=None):
|
||||
super(PlotAC, self).__init__(
|
||||
canvas = canvas,
|
||||
trad = trad,
|
||||
data = data,
|
||||
toolbar = toolbar,
|
||||
parent = parent
|
||||
canvas=canvas,
|
||||
trad=trad,
|
||||
data=data,
|
||||
toolbar=toolbar,
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self.plot_xy = plot_xy
|
||||
@@ -71,17 +72,19 @@ class PlotAC(PamhyrPlot):
|
||||
|
||||
self.canvas.axes.set_xlabel(
|
||||
_translate("MainWindow_reach", "Transverse abscissa (m)"),
|
||||
color='green', fontsize=12
|
||||
color='green', fontsize=10
|
||||
)
|
||||
self.canvas.axes.set_ylabel(
|
||||
_translate("MainWindow_reach", "Height (m)"),
|
||||
color='green', fontsize=12
|
||||
color='green', fontsize=10
|
||||
)
|
||||
self.canvas.figure.tight_layout()
|
||||
|
||||
label_before_plot_selected = _translate("MainWindow_reach", "Previous cross-section")
|
||||
label_before_plot_selected = _translate(
|
||||
"MainWindow_reach", "Previous cross-section")
|
||||
label_plot_selected = _translate("MainWindow_reach", "Cross-section")
|
||||
label_after_plot_selected = _translate("MainWindow_reach", "Next cross-section")
|
||||
label_after_plot_selected = _translate(
|
||||
"MainWindow_reach", "Next cross-section")
|
||||
color_before_plot_selected = "k" # 'grey'
|
||||
color_plot_selected = 'b'
|
||||
color_after_plot_selected = 'm'
|
||||
@@ -133,10 +136,12 @@ class PlotAC(PamhyrPlot):
|
||||
|
||||
x_gl_complete.append(station[i])
|
||||
y_gl_complete.append(elevation[i])
|
||||
color_scat_complete_gl.append(self.color_complete_gl[lcomplete.index(txt)])
|
||||
color_scat_complete_gl.append(
|
||||
self.color_complete_gl[lcomplete.index(txt)])
|
||||
elif txt.strip() in self.incomplete_gl:
|
||||
annotate = self.canvas.axes.annotate(
|
||||
txt, (station[i], elevation[i]), horizontalalignment='left',
|
||||
txt, (station[i], elevation[i]
|
||||
), horizontalalignment='left',
|
||||
verticalalignment='top', annotation_clip=True, fontsize=11,
|
||||
color=self.color_incomplete_gl[
|
||||
lincomplete.index(txt)
|
||||
@@ -171,17 +176,20 @@ class PlotAC(PamhyrPlot):
|
||||
self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5)
|
||||
self.canvas.axes.set_xlabel(
|
||||
_translate("MainWindow_reach", "Abscisse en travers (m)"),
|
||||
color='green', fontsize=12
|
||||
color='green', fontsize=10
|
||||
)
|
||||
self.canvas.axes.set_ylabel(
|
||||
_translate("MainWindow_reach", "Cote (m)"),
|
||||
color='green', fontsize=12
|
||||
color='green', fontsize=10
|
||||
)
|
||||
self.canvas.figure.tight_layout()
|
||||
|
||||
label_before_plot_selected = _translate("MainWindow_reach", "Profil précédent")
|
||||
label_plot_selected = _translate("MainWindow_reach", "Profil sélectionné")
|
||||
label_after_plot_selected = _translate("MainWindow_reach", "Profil suivant")
|
||||
label_before_plot_selected = _translate(
|
||||
"MainWindow_reach", "Profil précédent")
|
||||
label_plot_selected = _translate(
|
||||
"MainWindow_reach", "Profil sélectionné")
|
||||
label_after_plot_selected = _translate(
|
||||
"MainWindow_reach", "Profil suivant")
|
||||
color_before_plot_selected = "k" # 'grey'
|
||||
color_plot_selected = 'b'
|
||||
color_after_plot_selected = 'm'
|
||||
@@ -233,10 +241,12 @@ class PlotAC(PamhyrPlot):
|
||||
|
||||
x_gl_complete.append(station[i])
|
||||
y_gl_complete.append(elevation[i])
|
||||
color_scat_complete_gl.append(self.color_complete_gl[lcomplete.index(txt)])
|
||||
color_scat_complete_gl.append(
|
||||
self.color_complete_gl[lcomplete.index(txt)])
|
||||
elif txt.strip() in self.incomplete_gl:
|
||||
annotate = self.canvas.axes.annotate(
|
||||
txt, (station[i], elevation[i]), horizontalalignment='left',
|
||||
txt, (station[i], elevation[i]
|
||||
), horizontalalignment='left',
|
||||
verticalalignment='top', annotation_clip=True, fontsize=11,
|
||||
color=self.color_incomplete_gl[
|
||||
lincomplete.index(txt)
|
||||
@@ -311,10 +321,9 @@ class PlotAC(PamhyrPlot):
|
||||
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
|
||||
|
||||
@timer
|
||||
def update(self, ind=None):
|
||||
if self._init == False:
|
||||
if not self._init:
|
||||
self.draw()
|
||||
return
|
||||
|
||||
|
||||
@@ -29,15 +29,16 @@ _translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class PlotKPZ(PamhyrPlot):
|
||||
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||
display_current=True, parent=None):
|
||||
super(PlotKPZ, self).__init__(
|
||||
canvas = canvas,
|
||||
trad = trad,
|
||||
data = data,
|
||||
toolbar = toolbar,
|
||||
parent = parent
|
||||
canvas=canvas,
|
||||
trad=trad,
|
||||
data=data,
|
||||
toolbar=toolbar,
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self.display_current = display_current
|
||||
@@ -63,11 +64,11 @@ class PlotKPZ(PamhyrPlot):
|
||||
|
||||
self.canvas.axes.set_xlabel(
|
||||
_translate("MainWindow_reach", "Kp (m)"),
|
||||
color='green', fontsize=12
|
||||
color='green', fontsize=10
|
||||
)
|
||||
self.canvas.axes.set_ylabel(
|
||||
_translate("MainWindow_reach", "Height (m)"),
|
||||
color='green', fontsize=12
|
||||
color='green', fontsize=10
|
||||
)
|
||||
|
||||
kp = self.data.get_kp()
|
||||
@@ -75,7 +76,7 @@ class PlotKPZ(PamhyrPlot):
|
||||
z_max = self.data.get_z_max()
|
||||
|
||||
self.canvas.axes.set_xlim(
|
||||
left = min(kp), right = max(kp)
|
||||
left=min(kp), right=max(kp)
|
||||
)
|
||||
|
||||
self.line_kp_zmin_zmax = self.canvas.axes.vlines(
|
||||
@@ -98,7 +99,7 @@ class PlotKPZ(PamhyrPlot):
|
||||
)
|
||||
)
|
||||
|
||||
indexes_filter = lambda data: list(
|
||||
def indexes_filter(data): return list(
|
||||
map(
|
||||
lambda x: x[1],
|
||||
filter(
|
||||
@@ -169,7 +170,7 @@ class PlotKPZ(PamhyrPlot):
|
||||
|
||||
@timer
|
||||
def update(self, ind=None):
|
||||
if self._init == False:
|
||||
if not self._init:
|
||||
self.draw()
|
||||
return
|
||||
|
||||
|
||||
+20
-15
@@ -25,15 +25,16 @@ from PyQt5.QtCore import (
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class PlotXY(PamhyrPlot):
|
||||
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||
display_current=True, parent=None):
|
||||
super(PlotXY, self).__init__(
|
||||
canvas = canvas,
|
||||
trad = trad,
|
||||
data = data,
|
||||
toolbar = toolbar,
|
||||
parent = parent
|
||||
canvas=canvas,
|
||||
trad=trad,
|
||||
data=data,
|
||||
toolbar=toolbar,
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self.display_current = display_current
|
||||
@@ -64,17 +65,17 @@ class PlotXY(PamhyrPlot):
|
||||
# Axes
|
||||
self.canvas.axes.set_xlabel(
|
||||
_translate("Geometry", "X (m)"),
|
||||
color='green', fontsize=12
|
||||
color='green', fontsize=10
|
||||
)
|
||||
self.canvas.axes.set_ylabel(
|
||||
_translate("Geometry", "Y (m)"),
|
||||
color='green', fontsize=12
|
||||
color='green', fontsize=10
|
||||
)
|
||||
self.canvas.axes.axis("equal")
|
||||
|
||||
kp = self.data.get_kp()
|
||||
self.canvas.axes.set_xlim(
|
||||
left = min(kp), right = max(kp)
|
||||
left=min(kp), right=max(kp)
|
||||
)
|
||||
|
||||
# Draw line for each profile
|
||||
@@ -85,8 +86,8 @@ class PlotXY(PamhyrPlot):
|
||||
markersize=3, marker='+'
|
||||
)
|
||||
for x, y, kp in zip(
|
||||
self.data.get_x(), self.data.get_y(),
|
||||
kp
|
||||
self.data.get_x(), self.data.get_y(),
|
||||
kp
|
||||
)
|
||||
]
|
||||
|
||||
@@ -140,7 +141,7 @@ class PlotXY(PamhyrPlot):
|
||||
|
||||
@timer
|
||||
def update(self, ind=None):
|
||||
if self._init == False:
|
||||
if not self._init:
|
||||
self.draw()
|
||||
return
|
||||
|
||||
@@ -190,8 +191,10 @@ class PlotXY(PamhyrPlot):
|
||||
self.after_plot_selected.set_visible(False)
|
||||
|
||||
if 0 <= before < self.data.number_profiles:
|
||||
self.before_plot_selected.set_data(self.data.profile(before).x(),
|
||||
self.data.profile(before).y())
|
||||
self.before_plot_selected.set_data(
|
||||
self.data.profile(before).x(),
|
||||
self.data.profile(before).y()
|
||||
)
|
||||
self.before_plot_selected.set_visible(True)
|
||||
|
||||
if 0 <= ind < self.data.number_profiles:
|
||||
@@ -200,8 +203,10 @@ class PlotXY(PamhyrPlot):
|
||||
self.plot_selected.set_visible(True)
|
||||
|
||||
if 0 <= after < self.data.number_profiles:
|
||||
self.after_plot_selected.set_data(self.data.profile(after).x(),
|
||||
self.data.profile(after).y())
|
||||
self.after_plot_selected.set_data(
|
||||
self.data.profile(after).x(),
|
||||
self.data.profile(after).y()
|
||||
)
|
||||
self.after_plot_selected.set_visible(True)
|
||||
|
||||
self.canvas.axes.relim()
|
||||
|
||||
@@ -30,15 +30,16 @@ _translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class Plot(PamhyrPlot):
|
||||
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||
table=None, parent=None):
|
||||
super(Plot, self).__init__(
|
||||
canvas = canvas,
|
||||
trad = trad,
|
||||
data = data,
|
||||
toolbar = toolbar,
|
||||
parent = parent
|
||||
canvas=canvas,
|
||||
trad=trad,
|
||||
data=data,
|
||||
toolbar=toolbar,
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._table = table
|
||||
@@ -63,7 +64,7 @@ class Plot(PamhyrPlot):
|
||||
y_carto = self.data.y()
|
||||
|
||||
if (len(x_carto) < 3 or len(y_carto) < 3 or
|
||||
len(x) < 3):
|
||||
len(x) < 3):
|
||||
# Noting to do in this case
|
||||
return
|
||||
|
||||
|
||||
@@ -106,9 +106,13 @@ class GeometryProfileTableModel(PamhyrTableModel):
|
||||
|
||||
if role == Qt.ToolTipRole:
|
||||
if value.strip().upper() == "RG":
|
||||
return _translate("MainWindowProfile", "Rive gauche")
|
||||
return _translate(
|
||||
"MainWindowProfile", "Rive gauche"
|
||||
)
|
||||
else:
|
||||
return _translate("MainWindowProfile", "Rive droite")
|
||||
return _translate(
|
||||
"MainWindowProfile", "Rive droite"
|
||||
)
|
||||
|
||||
return QVariant()
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ from View.Geometry.Translate import GeometryTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class GeometryProfileTranslate(GeometryTranslate):
|
||||
def __init__(self):
|
||||
super(GeometryProfileTranslate, self).__init__()
|
||||
|
||||
@@ -34,6 +34,7 @@ class SetDataCommand(QUndoCommand):
|
||||
self._old = old_value
|
||||
self._new = self.type(new_value)
|
||||
|
||||
|
||||
class SetXCommand(SetDataCommand):
|
||||
def __init__(self, reach, index, old_value, new_value):
|
||||
self.type = float
|
||||
@@ -45,6 +46,7 @@ class SetXCommand(SetDataCommand):
|
||||
def redo(self):
|
||||
self._profile.point(self._index).x = self._new
|
||||
|
||||
|
||||
class SetYCommand(SetDataCommand):
|
||||
def __init__(self, reach, index, old_value, new_value):
|
||||
self.type = float
|
||||
@@ -56,6 +58,7 @@ class SetYCommand(SetDataCommand):
|
||||
def redo(self):
|
||||
self._profile.point(self._index).y = self._new
|
||||
|
||||
|
||||
class SetZCommand(SetDataCommand):
|
||||
def __init__(self, reach, index, old_value, new_value):
|
||||
self.type = float
|
||||
@@ -67,10 +70,12 @@ class SetZCommand(SetDataCommand):
|
||||
def redo(self):
|
||||
self._profile.point(self._index).z = self._new
|
||||
|
||||
|
||||
class SetNameCommand(SetDataCommand):
|
||||
def __init__(self, reach, index, old_value, new_value):
|
||||
self.type = str
|
||||
super(SetNameCommand, self).__init__(reach, index, old_value, new_value)
|
||||
super(SetNameCommand, self).__init__(
|
||||
reach, index, old_value, new_value)
|
||||
|
||||
def undo(self):
|
||||
self._profile.point(self._index).name = self._old
|
||||
@@ -96,6 +101,7 @@ class AddCommand(QUndoCommand):
|
||||
else:
|
||||
self._profile.insert_point(self._index, self._point)
|
||||
|
||||
|
||||
class DelCommand(QUndoCommand):
|
||||
def __init__(self, profile, rows):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -115,6 +121,7 @@ class DelCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._profile.delete(self._rows)
|
||||
|
||||
|
||||
class SortCommand(QUndoCommand):
|
||||
def __init__(self, profile, column, _reverse):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
@@ -58,13 +58,15 @@ class ProfileWindow(PamhyrWindow):
|
||||
|
||||
name = f"{self._pamhyr_name} - {self._profile.name} {self._profile.kp}"
|
||||
super(ProfileWindow, self).__init__(
|
||||
title = name,
|
||||
study = study,
|
||||
config = config,
|
||||
trad = GeometryProfileTranslate(),
|
||||
parent = parent
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=GeometryProfileTranslate(),
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._hash_data.append(profile)
|
||||
|
||||
self.setup_table()
|
||||
self.setup_plot()
|
||||
self.setup_connections()
|
||||
@@ -74,11 +76,11 @@ class ProfileWindow(PamhyrWindow):
|
||||
|
||||
table = self.find(QTableView, "tableView")
|
||||
self._tablemodel = GeometryProfileTableModel(
|
||||
table_view = table,
|
||||
table_headers = table_headers,
|
||||
editable_headers = ["name", "x", "y", "z"],
|
||||
data = self._profile,
|
||||
undo = self._undo_stack
|
||||
table_view=table,
|
||||
table_headers=table_headers,
|
||||
editable_headers=["name", "x", "y", "z"],
|
||||
data=self._profile,
|
||||
undo=self._undo_stack
|
||||
)
|
||||
table.setModel(self._tablemodel)
|
||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
@@ -92,17 +94,17 @@ class ProfileWindow(PamhyrWindow):
|
||||
self._canvas.setObjectName("canvas")
|
||||
self._toolbar = PamhyrPlotToolbar(
|
||||
self._canvas, self,
|
||||
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||
items=["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||
)
|
||||
self._plot_layout = self.find(QVBoxLayout, "verticalLayout")
|
||||
self._plot_layout.addWidget(self._toolbar)
|
||||
self._plot_layout.addWidget(self._canvas)
|
||||
|
||||
self._plot = Plot(
|
||||
canvas = self._canvas,
|
||||
data = self._profile,
|
||||
toolbar = self._toolbar,
|
||||
table = self.find(QTableView, "tableView")
|
||||
canvas=self._canvas,
|
||||
data=self._profile,
|
||||
toolbar=self._toolbar,
|
||||
table=self.find(QTableView, "tableView")
|
||||
)
|
||||
self._plot.draw()
|
||||
|
||||
@@ -134,15 +136,15 @@ class ProfileWindow(PamhyrWindow):
|
||||
|
||||
def index_selected_row(self):
|
||||
rows = self._tablemodel\
|
||||
.selectionModel()\
|
||||
.selectedRows()
|
||||
.selectionModel()\
|
||||
.selectedRows()
|
||||
if len(rows) == 0:
|
||||
return 0
|
||||
|
||||
return self._tablemodel\
|
||||
.selectionModel()\
|
||||
.selectedRows()[0]\
|
||||
.row()
|
||||
.selectionModel()\
|
||||
.selectedRows()[0]\
|
||||
.row()
|
||||
|
||||
def add(self):
|
||||
table = self.find(QTableView, "tableView")
|
||||
@@ -213,8 +215,8 @@ class ProfileWindow(PamhyrWindow):
|
||||
|
||||
def copy(self):
|
||||
rows = self._tablemodel\
|
||||
.selectionModel()\
|
||||
.selectedRows()
|
||||
.selectionModel()\
|
||||
.selectedRows()
|
||||
table = []
|
||||
table.append(["x", "y", "z", "name"])
|
||||
|
||||
|
||||
@@ -66,10 +66,10 @@ class GeometryReachTableModel(PamhyrTableModel):
|
||||
|
||||
if role == Qt.ForegroundRole and index.column() == 0:
|
||||
name = self._data.profile(index.row()).name\
|
||||
.strip()\
|
||||
.lower()
|
||||
.strip()\
|
||||
.lower()
|
||||
if (name == "upstream" or name == "up" or
|
||||
name == _translate("Geometry", "upstream")):
|
||||
name == _translate("Geometry", "upstream")):
|
||||
return QColor("Green")
|
||||
elif (name == "downstream" or name == "down" or
|
||||
name == _translate("Geometry", "downstream")):
|
||||
@@ -97,7 +97,7 @@ class GeometryReachTableModel(PamhyrTableModel):
|
||||
SetKPCommand(
|
||||
self._data, index.row(),
|
||||
self._data.profile(index.row()).kp,
|
||||
value
|
||||
value
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -151,7 +151,6 @@ class GeometryReachTableModel(PamhyrTableModel):
|
||||
self.layoutAboutToBeChanged.emit()
|
||||
self.layoutChanged.emit()
|
||||
|
||||
|
||||
def move_up(self, row, parent=QModelIndex()):
|
||||
if row <= 0:
|
||||
return
|
||||
@@ -199,7 +198,6 @@ class GeometryReachTableModel(PamhyrTableModel):
|
||||
self.layoutAboutToBeChanged.emit()
|
||||
self.layoutChanged.emit()
|
||||
|
||||
|
||||
def paste(self, row, header, data):
|
||||
if row > self._data.number_profiles:
|
||||
return
|
||||
|
||||
@@ -22,13 +22,16 @@ from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class GeometryTranslate(PamhyrTranslate):
|
||||
def __init__(self):
|
||||
super(GeometryTranslate, self).__init__()
|
||||
|
||||
self._dict["open_file"] = _translate("Geometry", "Open a file")
|
||||
self._dict["file_st"] = _translate("Geometry", "File mage geometry (*.ST)")
|
||||
self._dict["file_m"] = _translate("Geometry", "File mage meshed geometry (*.M)")
|
||||
self._dict["file_st"] = _translate(
|
||||
"Geometry", "File mage geometry (*.ST)")
|
||||
self._dict["file_m"] = _translate(
|
||||
"Geometry", "File mage meshed geometry (*.M)")
|
||||
self._dict["file_all"] = _translate("Geometry", "All file (*)")
|
||||
|
||||
self._dict["reach"] = _translate("Geometry", "reach")
|
||||
|
||||
@@ -35,10 +35,12 @@ class SetDataCommand(QUndoCommand):
|
||||
self._old = old_value
|
||||
self._new = self.type(new_value)
|
||||
|
||||
|
||||
class SetNameCommand(SetDataCommand):
|
||||
def __init__(self, reach, index, old_value, new_value):
|
||||
self.type = str
|
||||
super(SetNameCommand, self).__init__(reach, index, old_value, new_value)
|
||||
super(SetNameCommand, self).__init__(
|
||||
reach, index, old_value, new_value)
|
||||
|
||||
def undo(self):
|
||||
self._reach.profile(self._index).name = self._old
|
||||
@@ -46,6 +48,7 @@ class SetNameCommand(SetDataCommand):
|
||||
def redo(self):
|
||||
self._reach.profile(self._index).name = self._new
|
||||
|
||||
|
||||
class SetKPCommand(SetDataCommand):
|
||||
def __init__(self, reach, index, old_value, new_value):
|
||||
self.type = float
|
||||
@@ -75,6 +78,7 @@ class AddCommand(QUndoCommand):
|
||||
else:
|
||||
self._reach.insert_profile(self._index, self._profile)
|
||||
|
||||
|
||||
class DelCommand(QUndoCommand):
|
||||
def __init__(self, reach, rows):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -94,6 +98,7 @@ class DelCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._reach.delete(self._rows)
|
||||
|
||||
|
||||
class SortCommand(QUndoCommand):
|
||||
def __init__(self, reach, _reverse):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
+54
-46
@@ -66,13 +66,16 @@ class GeometryWindow(PamhyrWindow):
|
||||
name = f"{self._pamhyr_name} - {self._reach.name}"
|
||||
|
||||
super(GeometryWindow, self).__init__(
|
||||
title = name,
|
||||
study = study,
|
||||
config = config,
|
||||
trad = GeometryTranslate(),
|
||||
parent = parent
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=GeometryTranslate(),
|
||||
parent=parent
|
||||
)
|
||||
|
||||
# Add reach to hash computation data
|
||||
self._hash_data.append(self._reach)
|
||||
|
||||
self._tablemodel = None
|
||||
self._profile_window = []
|
||||
|
||||
@@ -87,11 +90,11 @@ class GeometryWindow(PamhyrWindow):
|
||||
|
||||
table = self.find(QTableView, "tableView")
|
||||
self._tablemodel = GeometryReachTableModel(
|
||||
table_view = table,
|
||||
table_headers = table_headers,
|
||||
editable_headers = ["name", "kp"],
|
||||
data = self._reach,
|
||||
undo = self._undo_stack
|
||||
table_view=table,
|
||||
table_headers=table_headers,
|
||||
editable_headers=["name", "kp"],
|
||||
data=self._reach,
|
||||
undo=self._undo_stack
|
||||
)
|
||||
table.setModel(self._tablemodel)
|
||||
table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
@@ -103,7 +106,7 @@ class GeometryWindow(PamhyrWindow):
|
||||
self._canvas_xy.setObjectName("canvas_xy")
|
||||
self._toolbar_xy = PamhyrPlotToolbar(
|
||||
self._canvas_xy, self,
|
||||
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||
items=["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||
)
|
||||
self._plot_layout_xy = self.find(QVBoxLayout, "verticalLayout")
|
||||
self._plot_layout_xy.addWidget(self._toolbar_xy)
|
||||
@@ -114,7 +117,7 @@ class GeometryWindow(PamhyrWindow):
|
||||
self._canvas_kpc.setObjectName("canvas_kpc")
|
||||
self._toolbar_kpc = PamhyrPlotToolbar(
|
||||
self._canvas_kpc, self,
|
||||
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||
items=["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||
)
|
||||
self._plot_layout_kpc = self.find(QVBoxLayout, "verticalLayout_2")
|
||||
self._plot_layout_kpc.addWidget(self._toolbar_kpc)
|
||||
@@ -125,7 +128,7 @@ class GeometryWindow(PamhyrWindow):
|
||||
self._canvas_ac.setObjectName("canvas_ac")
|
||||
self._toolbar_ac = PamhyrPlotToolbar(
|
||||
self._canvas_ac, self,
|
||||
items = ["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||
items=["home", "zoom", "save", "iso", "back/forward", "move"]
|
||||
)
|
||||
self._plot_layout_ac = self.find(QVBoxLayout, "verticalLayout_3")
|
||||
self._plot_layout_ac.addWidget(self._toolbar_ac)
|
||||
@@ -139,7 +142,9 @@ class GeometryWindow(PamhyrWindow):
|
||||
name = profile.name + " " + str(profile.kp)
|
||||
|
||||
return (
|
||||
f"<font color=\"Grey\">{self._trad['reach']}: {self._reach.name}" + " - "
|
||||
"<font color=\"Grey\">" +
|
||||
f"{self._trad['reach']}: {self._reach.name}" +
|
||||
" - " +
|
||||
f"{self._trad['cross_section']}:</font> {name}"
|
||||
)
|
||||
|
||||
@@ -169,19 +174,22 @@ class GeometryWindow(PamhyrWindow):
|
||||
self.find(QAction, action)\
|
||||
.triggered.connect(actions[action])
|
||||
|
||||
self.find(QSlider, "verticalSlider").valueChanged.connect(self.changed_slider_value)
|
||||
self.find(QPushButton, "pushButton_up").clicked.connect(self.decrement_value_slider)
|
||||
self.find(QPushButton, "pushButton_down").clicked.connect(self.increment_value_slider)
|
||||
self.find(QSlider, "verticalSlider").valueChanged.connect(
|
||||
self.changed_slider_value)
|
||||
self.find(QPushButton, "pushButton_up").clicked.connect(
|
||||
self.decrement_value_slider)
|
||||
self.find(QPushButton, "pushButton_down").clicked.connect(
|
||||
self.increment_value_slider)
|
||||
|
||||
# Profile selection when line change in table
|
||||
self.find(QTableView, "tableView").selectionModel()\
|
||||
.selectionChanged\
|
||||
.connect(self.select_current_profile)
|
||||
|
||||
|
||||
def import_from_file(self):
|
||||
options = QFileDialog.Options()
|
||||
settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
|
||||
settings = QSettings(QSettings.IniFormat,
|
||||
QSettings.UserScope, 'MyOrg', )
|
||||
options |= QFileDialog.DontUseNativeDialog
|
||||
|
||||
file_types = [
|
||||
@@ -220,20 +228,18 @@ class GeometryWindow(PamhyrWindow):
|
||||
for row in rows:
|
||||
profile = self._reach.profile(row)
|
||||
|
||||
win = self.sub_win_filter_first(
|
||||
"Profile",
|
||||
contain = [self._reach.name, str(profile.kp)]
|
||||
)
|
||||
if self.sub_window_exists(
|
||||
ProfileWindow,
|
||||
data=[None, None, profile]
|
||||
):
|
||||
continue
|
||||
|
||||
if win is None:
|
||||
win = ProfileWindow(
|
||||
profile = profile,
|
||||
parent = self,
|
||||
)
|
||||
self._profile_window.append(win)
|
||||
win.show()
|
||||
else:
|
||||
win.activateWindow()
|
||||
win = ProfileWindow(
|
||||
profile=profile,
|
||||
parent=self,
|
||||
)
|
||||
self._profile_window.append(win)
|
||||
win.show()
|
||||
|
||||
self.tableView.model().blockSignals(False)
|
||||
|
||||
@@ -250,9 +256,9 @@ class GeometryWindow(PamhyrWindow):
|
||||
self.tableView.model().blockSignals(True)
|
||||
|
||||
self._plot_xy = PlotXY(
|
||||
canvas = self._canvas_xy,
|
||||
data = self._reach,
|
||||
toolbar = self._toolbar_xy
|
||||
canvas=self._canvas_xy,
|
||||
data=self._reach,
|
||||
toolbar=self._toolbar_xy
|
||||
)
|
||||
self._plot_xy.draw()
|
||||
|
||||
@@ -267,9 +273,9 @@ class GeometryWindow(PamhyrWindow):
|
||||
self.tableView.model().blockSignals(True)
|
||||
|
||||
self._plot_kpc = PlotKPZ(
|
||||
canvas = self._canvas_kpc,
|
||||
data = self._reach,
|
||||
toolbar = self._toolbar_kpc
|
||||
canvas=self._canvas_kpc,
|
||||
data=self._reach,
|
||||
toolbar=self._toolbar_kpc
|
||||
)
|
||||
self._plot_kpc.draw()
|
||||
|
||||
@@ -284,10 +290,10 @@ class GeometryWindow(PamhyrWindow):
|
||||
self.tableView.model().blockSignals(True)
|
||||
|
||||
self._plot_ac = PlotAC(
|
||||
canvas = self._canvas_ac,
|
||||
data = self._reach,
|
||||
toolbar = self._toolbar_ac,
|
||||
plot_xy = self._plot_xy
|
||||
canvas=self._canvas_ac,
|
||||
data=self._reach,
|
||||
toolbar=self._toolbar_ac,
|
||||
plot_xy=self._plot_xy
|
||||
)
|
||||
self._plot_ac.draw()
|
||||
|
||||
@@ -489,14 +495,16 @@ class GeometryWindow(PamhyrWindow):
|
||||
def export_to_file(self):
|
||||
options = QFileDialog.Options()
|
||||
DEFAULT_DIRECTORY = '/home/'
|
||||
settings = QSettings(QSettings.IniFormat, QSettings.UserScope, 'MyOrg', )
|
||||
current_dir = settings.value('current_directory', DEFAULT_DIRECTORY, type=str)
|
||||
settings = QSettings(QSettings.IniFormat,
|
||||
QSettings.UserScope, 'MyOrg', )
|
||||
current_dir = settings.value(
|
||||
'current_directory', DEFAULT_DIRECTORY, type=str)
|
||||
options |= QFileDialog.DontUseNativeDialog
|
||||
|
||||
filename, filters = QFileDialog.getSaveFileName(
|
||||
self,
|
||||
filter = self._trad["file_st"] + ";; " + self._trad["file_all"],
|
||||
options = options
|
||||
filter=self._trad["file_st"] + ";; " + self._trad["file_all"],
|
||||
options=options
|
||||
)
|
||||
|
||||
current_dir = os.path.split(filename)[0] or DEFAULT_DIRECTORY
|
||||
|
||||
@@ -31,15 +31,16 @@ from PyQt5.QtWidgets import (
|
||||
QDoubleSpinBox,
|
||||
)
|
||||
|
||||
|
||||
class DischargeDialog(PamhyrDialog):
|
||||
_pamhyr_ui = "InitialConditions_Dialog_Generator_Discharge"
|
||||
_pamhyr_name = "Discharge"
|
||||
|
||||
def __init__(self, title="Discharge", parent=None):
|
||||
super(DischargeDialog, self).__init__(
|
||||
title = self._pamhyr_name,
|
||||
options = [],
|
||||
parent = parent
|
||||
title=self._pamhyr_name,
|
||||
options=[],
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self.value = None
|
||||
|
||||
@@ -31,15 +31,16 @@ from PyQt5.QtWidgets import (
|
||||
QDoubleSpinBox,
|
||||
)
|
||||
|
||||
|
||||
class HeightDialog(PamhyrDialog):
|
||||
_pamhyr_ui = "InitialConditions_Dialog_Generator_Height"
|
||||
_pamhyr_name = "Height"
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(HeightDialog, self).__init__(
|
||||
title = self._pamhyr_name,
|
||||
options = [],
|
||||
parent = parent
|
||||
title=self._pamhyr_name,
|
||||
options=[],
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self.value = None
|
||||
|
||||
@@ -25,6 +25,7 @@ from PyQt5.QtCore import (
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class PlotDKP(PamhyrPlot):
|
||||
@timer
|
||||
def draw(self, highlight=None):
|
||||
@@ -47,7 +48,7 @@ class PlotDKP(PamhyrPlot):
|
||||
z_min = self.data.reach.reach.get_z_min()
|
||||
|
||||
self.canvas.axes.set_xlim(
|
||||
left = min(kp), right = max(kp)
|
||||
left=min(kp), right=max(kp)
|
||||
)
|
||||
|
||||
self.line_kp_zmin = self.canvas.axes.plot(
|
||||
@@ -73,6 +74,6 @@ class PlotDKP(PamhyrPlot):
|
||||
|
||||
@timer
|
||||
def update(self, ind=None):
|
||||
if self._init == False:
|
||||
if not self._init:
|
||||
self.draw()
|
||||
return
|
||||
@@ -19,6 +19,7 @@
|
||||
from tools import timer
|
||||
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||
|
||||
|
||||
class PlotDischarge(PamhyrPlot):
|
||||
@timer
|
||||
def draw(self, highlight=None):
|
||||
@@ -40,7 +41,7 @@ class PlotDischarge(PamhyrPlot):
|
||||
kp = self.data.reach.reach.get_kp()
|
||||
|
||||
self.canvas.axes.set_xlim(
|
||||
left = min(kp), right = max(kp)
|
||||
left=min(kp), right=max(kp)
|
||||
)
|
||||
|
||||
if len(self.data) != 0:
|
||||
@@ -61,6 +62,6 @@ class PlotDischarge(PamhyrPlot):
|
||||
|
||||
@timer
|
||||
def update(self, ind=None):
|
||||
if self._init == False:
|
||||
if not self._init:
|
||||
self.draw()
|
||||
return
|
||||
@@ -45,6 +45,7 @@ logger = logging.getLogger()
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class ComboBoxDelegate(QItemDelegate):
|
||||
def __init__(self, reach=None, parent=None):
|
||||
super(ComboBoxDelegate, self).__init__(parent)
|
||||
@@ -78,8 +79,9 @@ class ComboBoxDelegate(QItemDelegate):
|
||||
|
||||
def updateEditorGeometry(self, editor, option, index):
|
||||
r = QRect(option.rect)
|
||||
if self.editor.windowFlags() & Qt.Popup and editor.parent() is not None:
|
||||
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
|
||||
if self.editor.windowFlags() & Qt.Popup:
|
||||
if editor.parent() is not None:
|
||||
r.setTopLeft(self.editor.parent().mapToGlobal(r.topLeft()))
|
||||
editor.setGeometry(r)
|
||||
|
||||
@pyqtSlot()
|
||||
|
||||
@@ -26,6 +26,7 @@ from PyQt5.QtWidgets import (
|
||||
from Model.InitialConditions.InitialConditions import InitialConditions
|
||||
from Model.InitialConditions.InitialConditionsDict import InitialConditionsDict
|
||||
|
||||
|
||||
class SetCommand(QUndoCommand):
|
||||
def __init__(self, ics, row, column, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -47,6 +48,7 @@ class SetCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._ics.get(self._row)[self._column] = self._new
|
||||
|
||||
|
||||
class AddCommand(QUndoCommand):
|
||||
def __init__(self, ics, index):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -64,6 +66,7 @@ class AddCommand(QUndoCommand):
|
||||
else:
|
||||
self._ics.insert(self._index, self._new)
|
||||
|
||||
|
||||
class DelCommand(QUndoCommand):
|
||||
def __init__(self, ics, rows):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -83,6 +86,7 @@ class DelCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._ics.delete_i(self._rows)
|
||||
|
||||
|
||||
class SortCommand(QUndoCommand):
|
||||
def __init__(self, ics, _reverse):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -168,6 +172,7 @@ class DuplicateCommand(QUndoCommand):
|
||||
for ic in self._ics:
|
||||
self._ics.insert(self._rows[0], ic)
|
||||
|
||||
|
||||
class GenerateCommand(QUndoCommand):
|
||||
def __init__(self, ics, generator, param):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
@@ -45,7 +45,9 @@ from View.InitialConditions.UndoCommand import (
|
||||
DuplicateCommand,
|
||||
)
|
||||
|
||||
from View.InitialConditions.Table import InitialConditionTableModel, ComboBoxDelegate
|
||||
from View.InitialConditions.Table import (
|
||||
InitialConditionTableModel, ComboBoxDelegate,
|
||||
)
|
||||
|
||||
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||
@@ -60,6 +62,7 @@ _translate = QCoreApplication.translate
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
class InitialConditionsWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "InitialConditions"
|
||||
_pamhyr_name = "Initial condition"
|
||||
@@ -77,13 +80,16 @@ class InitialConditionsWindow(PamhyrWindow):
|
||||
)
|
||||
|
||||
super(InitialConditionsWindow, self).__init__(
|
||||
title = name,
|
||||
study = study,
|
||||
config = config,
|
||||
trad = ICTranslate(),
|
||||
parent = parent
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=ICTranslate(),
|
||||
parent=parent
|
||||
)
|
||||
|
||||
# Add reach to hash computation data
|
||||
self._hash_data.append(self._reach)
|
||||
|
||||
self._ics = study.river.initial_conditions.get(self._reach)
|
||||
|
||||
self.setup_table()
|
||||
@@ -95,19 +101,19 @@ class InitialConditionsWindow(PamhyrWindow):
|
||||
def setup_table(self):
|
||||
table = self.find(QTableView, f"tableView")
|
||||
self._delegate_kp = ComboBoxDelegate(
|
||||
reach = self._reach,
|
||||
parent = self
|
||||
reach=self._reach,
|
||||
parent=self
|
||||
)
|
||||
|
||||
self._table = InitialConditionTableModel(
|
||||
reach = self._reach,
|
||||
table_view = table,
|
||||
table_headers = self._trad.get_dict("table_headers"),
|
||||
editable_headers = ["kp", "discharge", "elevation", "height"],
|
||||
delegates = {"kp": self._delegate_kp},
|
||||
data = self._study,
|
||||
undo = self._undo_stack,
|
||||
trad = self._trad
|
||||
reach=self._reach,
|
||||
table_view=table,
|
||||
table_headers=self._trad.get_dict("table_headers"),
|
||||
editable_headers=["kp", "discharge", "elevation", "height"],
|
||||
delegates={"kp": self._delegate_kp},
|
||||
data=self._study,
|
||||
undo=self._undo_stack,
|
||||
trad=self._trad
|
||||
)
|
||||
|
||||
table.setModel(self._table)
|
||||
@@ -126,11 +132,11 @@ class InitialConditionsWindow(PamhyrWindow):
|
||||
self.plot_layout_1.addWidget(self.canvas_1)
|
||||
|
||||
self.plot_1 = PlotDKP(
|
||||
canvas = self.canvas_1,
|
||||
data = self._ics,
|
||||
trad = self._trad,
|
||||
toolbar = self.toolbar_1,
|
||||
parent = self
|
||||
canvas=self.canvas_1,
|
||||
data=self._ics,
|
||||
trad=self._trad,
|
||||
toolbar=self.toolbar_1,
|
||||
parent=self
|
||||
)
|
||||
self.plot_1.draw()
|
||||
|
||||
@@ -144,11 +150,11 @@ class InitialConditionsWindow(PamhyrWindow):
|
||||
self.plot_layout_2.addWidget(self.canvas_2)
|
||||
|
||||
self.plot_2 = PlotDischarge(
|
||||
canvas = self.canvas_2,
|
||||
data = self._ics,
|
||||
trad = self._trad,
|
||||
toolbar = self.toolbar_2,
|
||||
parent = self
|
||||
canvas=self.canvas_2,
|
||||
data=self._ics,
|
||||
trad=self._trad,
|
||||
toolbar=self.toolbar_2,
|
||||
parent=self
|
||||
)
|
||||
self.plot_2.draw()
|
||||
|
||||
|
||||
@@ -22,12 +22,15 @@ from View.Tools.PamhyrTranslate import PamhyrTranslate
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class ICTranslate(PamhyrTranslate):
|
||||
def __init__(self):
|
||||
super(ICTranslate, self).__init__()
|
||||
|
||||
self._dict["elevation"] = _translate("InitialCondition", "Elevation (m)")
|
||||
self._dict["discharge"] = _translate("InitialCondition", "Discharge (m³/s)")
|
||||
self._dict["elevation"] = _translate(
|
||||
"InitialCondition", "Elevation (m)")
|
||||
self._dict["discharge"] = _translate(
|
||||
"InitialCondition", "Discharge (m³/s)")
|
||||
self._dict["kp"] = _translate("InitialCondition", "KP (m)")
|
||||
|
||||
self._sub_dict["table_headers"] = {
|
||||
|
||||
@@ -29,16 +29,17 @@ from View.LateralContribution.Edit.translate import *
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class Plot(PamhyrPlot):
|
||||
def __init__(self, mode = "time", data=None,
|
||||
def __init__(self, mode="time", data=None,
|
||||
canvas=None, trad=None, toolbar=None,
|
||||
parent=None):
|
||||
super(Plot, self).__init__(
|
||||
canvas = canvas,
|
||||
trad = trad,
|
||||
data = data,
|
||||
toolbar = toolbar,
|
||||
parent = parent
|
||||
canvas=canvas,
|
||||
trad=trad,
|
||||
data=data,
|
||||
toolbar=toolbar,
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._table_headers = self._trad.get_dict("table_headers")
|
||||
@@ -68,8 +69,8 @@ class Plot(PamhyrPlot):
|
||||
map(
|
||||
lambda v: str(
|
||||
datetime.fromtimestamp(v[0]) - t0
|
||||
).split(",")[0]\
|
||||
.replace("days", _translate("LateralContribution", "days"))\
|
||||
).split(",")[0]
|
||||
.replace("days", _translate("LateralContribution", "days"))
|
||||
.replace("day", _translate("LateralContribution", "day")),
|
||||
fx
|
||||
)
|
||||
@@ -84,7 +85,6 @@ class Plot(PamhyrPlot):
|
||||
|
||||
self.canvas.axes.set_xticks(ticks=xx, labels=xt, rotation=45)
|
||||
|
||||
|
||||
@timer
|
||||
def draw(self):
|
||||
self.canvas.axes.cla()
|
||||
@@ -118,13 +118,13 @@ class Plot(PamhyrPlot):
|
||||
self.canvas.axes.autoscale_view(True, True, True)
|
||||
self.canvas.figure.tight_layout()
|
||||
self.canvas.figure.canvas.draw_idle()
|
||||
#self.toolbar.update()
|
||||
# self.toolbar.update()
|
||||
|
||||
self._init = True
|
||||
|
||||
@timer
|
||||
def update(self, ind=None):
|
||||
if self._init == False:
|
||||
if not self._init:
|
||||
self.draw()
|
||||
return
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ from PyQt5.QtWidgets import (
|
||||
|
||||
from Model.LateralContribution.LateralContribution import LateralContribution
|
||||
|
||||
|
||||
class SetDataCommand(QUndoCommand):
|
||||
def __init__(self, data, index, column, new_value):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -42,6 +43,7 @@ class SetDataCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._data._set_i_c_v(self._index, self._column, self._new)
|
||||
|
||||
|
||||
class AddCommand(QUndoCommand):
|
||||
def __init__(self, data, index):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -59,6 +61,7 @@ class AddCommand(QUndoCommand):
|
||||
else:
|
||||
self._data.insert(self._index, self._new)
|
||||
|
||||
|
||||
class DelCommand(QUndoCommand):
|
||||
def __init__(self, data, rows):
|
||||
QUndoCommand.__init__(self)
|
||||
@@ -78,6 +81,7 @@ class DelCommand(QUndoCommand):
|
||||
def redo(self):
|
||||
self._data.delete_i(self._rows)
|
||||
|
||||
|
||||
class SortCommand(QUndoCommand):
|
||||
def __init__(self, data, _reverse):
|
||||
QUndoCommand.__init__(self)
|
||||
|
||||
@@ -45,6 +45,7 @@ from View.LateralContribution.Edit.Plot import Plot
|
||||
|
||||
_translate = QCoreApplication.translate
|
||||
|
||||
|
||||
class EditLateralContributionWindow(PamhyrWindow):
|
||||
_pamhyr_ui = "EditLateralContribution"
|
||||
_pamhyr_name = "Edit lateral contribution"
|
||||
@@ -58,31 +59,35 @@ class EditLateralContributionWindow(PamhyrWindow):
|
||||
name = self._pamhyr_name
|
||||
if self._data is not None:
|
||||
edge_name = (self._data.edge.name if self._data.edge is not None
|
||||
else _translate("LateralContribution", "Not associate"))
|
||||
else _translate("LateralContribution",
|
||||
"Not associate"))
|
||||
name = (
|
||||
_translate("Edit lateral contribution", self._pamhyr_name) +
|
||||
f" - {study.name} " +
|
||||
f" - {self._data.name} ({self._data.id}) " +
|
||||
f"({trad.get_dict('long_types')[self._data.lctype]} - {edge_name})"
|
||||
f"({trad.get_dict('long_types')[self._data.lctype]} - " +
|
||||
f"{edge_name})"
|
||||
)
|
||||
|
||||
super(EditLateralContributionWindow, self).__init__(
|
||||
title = name,
|
||||
study = study,
|
||||
config = config,
|
||||
trad = trad,
|
||||
parent = parent
|
||||
title=name,
|
||||
study=study,
|
||||
config=config,
|
||||
trad=trad,
|
||||
parent=parent
|
||||
)
|
||||
|
||||
self._hash_data.append(data)
|
||||
|
||||
self.setup_table()
|
||||
self.setup_plot()
|
||||
self.setup_connections()
|
||||
|
||||
def setup_table(self):
|
||||
self._delegate_time = PamhyrExTimeDelegate(
|
||||
data = self._data,
|
||||
mode = self._study.time_system,
|
||||
parent = self
|
||||
data=self._data,
|
||||
mode=self._study.time_system,
|
||||
parent=self
|
||||
)
|
||||
|
||||
headers = {}
|
||||
@@ -92,16 +97,16 @@ class EditLateralContributionWindow(PamhyrWindow):
|
||||
|
||||
table = self.find(QTableView, "tableView")
|
||||
self._table = TableModel(
|
||||
table_view = table,
|
||||
table_headers = headers,
|
||||
editable_headers = self._data.header,
|
||||
delegates = {
|
||||
table_view=table,
|
||||
table_headers=headers,
|
||||
editable_headers=self._data.header,
|
||||
delegates={
|
||||
"time": self._delegate_time,
|
||||
},
|
||||
data = self._data,
|
||||
undo = self._undo_stack,
|
||||
trad = self._trad,
|
||||
opt_data = self._study.time_system
|
||||
data=self._data,
|
||||
undo=self._undo_stack,
|
||||
trad=self._trad,
|
||||
opt_data=self._study.time_system
|
||||
)
|
||||
|
||||
table.setModel(self._table)
|
||||
@@ -119,12 +124,12 @@ class EditLateralContributionWindow(PamhyrWindow):
|
||||
self.verticalLayout.addWidget(self.canvas)
|
||||
|
||||
self.plot = Plot(
|
||||
canvas = self.canvas,
|
||||
data = self._data,
|
||||
mode = self._study.time_system,
|
||||
toolbar = self.toolbar,
|
||||
trad = self._trad,
|
||||
parent = self
|
||||
canvas=self.canvas,
|
||||
data=self._data,
|
||||
mode=self._study.time_system,
|
||||
toolbar=self.toolbar,
|
||||
trad=self._trad,
|
||||
parent=self
|
||||
)
|
||||
self.plot.draw()
|
||||
|
||||
@@ -156,7 +161,6 @@ class EditLateralContributionWindow(PamhyrWindow):
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def add(self):
|
||||
rows = self.index_selected_rows()
|
||||
if len(self._data) == 0 or len(rows) == 0:
|
||||
|
||||
Loaded 100 of 174 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user