diff --git a/src/Model/SedimentLayer/SedimentLayer.py b/src/Model/SedimentLayer/SedimentLayer.py index 4ec52541..d0db12ee 100644 --- a/src/Model/SedimentLayer/SedimentLayer.py +++ b/src/Model/SedimentLayer/SedimentLayer.py @@ -426,30 +426,31 @@ class SedimentLayer(SQLSubModel): f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))}) " ) - for row in table: - it = iter(row) + if table is not None: + for row in table: + it = iter(row) - pid = next(it) - deleted = (next(it) == 1) - name = next(it) - comment = next(it) - owner_scenario = next(it) + pid = next(it) + deleted = (next(it) == 1) + name = next(it) + comment = next(it) + owner_scenario = next(it) - sl = cls( - id=pid, - name=name, - comment=comment, - status=data['status'], - owner_scenario=owner_scenario - ) - if deleted: - sl.set_as_deleted() + sl = cls( + id=pid, + name=name, + comment=comment, + status=data['status'], + owner_scenario=owner_scenario + ) + if deleted: + sl.set_as_deleted() - data["sl"] = sl - sl._layers = Layer._db_load(execute, data) + data["sl"] = sl + sl._layers = Layer._db_load(execute, data) - loaded.add(pid) - new.append(sl) + loaded.add(pid) + new.append(sl) data["scenario"] = scenario.parent new += cls._db_load(execute, data) diff --git a/src/Solver/RubarBE.py b/src/Solver/RubarBE.py index 98251299..e30cbc4d 100644 --- a/src/Solver/RubarBE.py +++ b/src/Solver/RubarBE.py @@ -74,10 +74,10 @@ class Rubar3(CommandLineSolver): ("rubarbe_tf_5", "y"), ("rubarbe_tf_6", "n"), ("rubarbe_trased", "y"), - ("rubarbe_optfpc", "0"), - ("rubarbe_ros", "2650.0"), - ("rubarbe_dm", "0.1"), - ("rubarbe_segma", "1.0"), + # ("rubarbe_optfpc", "0"), + # ("rubarbe_ros", "2650.0"), + # ("rubarbe_dm", "0.1"), + # ("rubarbe_segma", "1.0"), # Sediment parameters ("rubarbe_sediment_ros", "2650.0"), ("rubarbe_sediment_por", "0.4"), @@ -167,7 +167,7 @@ class Rubar3(CommandLineSolver): it = iter(params) line = 0 - while line < 29: + while line < 25: param = next(it) name = param.name value = param.value @@ -277,19 +277,20 @@ class Rubar3(CommandLineSolver): f.write(f"{ind:>4} {rk:>11.3f} {n_points:>4}\n") - for point in profile.points: + station = profile.get_station() + for i, point in enumerate(profile.points): label = point.name.lower() if label != "": if label[0] == "r": label = label[1].upper() else: - label = label[1].upper() + label = " " else: label = " " - y = point.y + y = station[i] z = point.z - dcs = 0.001 + dcs = 1.0 scs = 1.0 tmcs = 0.0 @@ -444,10 +445,10 @@ class Rubar3(CommandLineSolver): z = data[profile.rk][0] q = data[profile.rk][1] - # height = z - profile.z_min() + height = z - profile.z_min() speed = profile.speed(q, z) - return z, speed + return height, speed def _export_hydro(self, study, repertory, qlog, name="0"): if qlog is not None: @@ -470,7 +471,7 @@ class Rubar3(CommandLineSolver): for bc in bcs: f.write(f"{len(bc)}\n") for d0, d1 in bc.data: - f.write(f"{d0} {d1}\n") + f.write(f"{d1} {d0}\n") def _export_condav(self, study, repertory, qlog, name="0"): if qlog is not None: @@ -493,7 +494,7 @@ class Rubar3(CommandLineSolver): for bc in bcs: f.write(f"{len(bc)}\n") for d0, d1 in bc.data: - f.write(f"{d0} {d1}\n") + f.write(f"{d1} {d0}\n") class RubarBE(Rubar3): diff --git a/src/View/BoundaryCondition/Edit/Table.py b/src/View/BoundaryCondition/Edit/Table.py index 02b48d68..601a09ac 100644 --- a/src/View/BoundaryCondition/Edit/Table.py +++ b/src/View/BoundaryCondition/Edit/Table.py @@ -250,7 +250,10 @@ class TableModel(PamhyrTableModel): line.startswith("*") or line.startswith("$")): line = line.split() - data0.append(float(line[0]) * mult) + if bctype == "ZD": + data0.append(float(line[0])) + else: + data0.append(old_pamhyr_date_to_timestamp(line[0])) data1.append(line[1]) self.replace_data(data0, data1) diff --git a/src/View/BoundaryCondition/Edit/translate.py b/src/View/BoundaryCondition/Edit/translate.py index bec95728..de4ab4d6 100644 --- a/src/View/BoundaryCondition/Edit/translate.py +++ b/src/View/BoundaryCondition/Edit/translate.py @@ -41,7 +41,7 @@ class BCETranslate(BCTranslate): "BoundaryCondition", "Mage hydrograph file (*.HYD)") self._dict["file_lim"] = _translate( "BoundaryCondition", "Mage limnigraph file (*.LIM)") - self._dict["file_lim"] = _translate( + self._dict["file_ava"] = _translate( "BoundaryCondition", "Mage rating curve file (*.AVA)") self._dict["file_all"] = _translate( "BoundaryCondition", "All files (*)") diff --git a/src/View/Frictions/UndoCommand.py b/src/View/Frictions/UndoCommand.py index b428ae84..0f9c3c93 100644 --- a/src/View/Frictions/UndoCommand.py +++ b/src/View/Frictions/UndoCommand.py @@ -153,6 +153,7 @@ class ReplaceDataCommand(QUndoCommand): self._new_data = new_data self._old_rows = list(range(len(frictions))) self._new_rows = list(range(len(new_data))) + self._new = [] self._old_friction = [] for row in self._old_rows: @@ -164,15 +165,20 @@ class ReplaceDataCommand(QUndoCommand): self._frictions.insert(row, el) def redo(self): - self._frictions.delete_i(self._old_rows) - for row in self._new_rows: - new = self._frictions.new(row) - d = self._new_data[row] - new.edge = d[0] - new.begin_rk = d[1] - new.end_rk = d[2] - new.begin_strickler = d[3] - new.end_strickler = d[4] + if len(self._new) == 0: + self._frictions.delete_i(self._old_rows) + for row in self._new_rows: + new = self._frictions.new(row) + d = self._new_data[row] + new.edge = d[0] + new.begin_rk = d[1] + new.end_rk = d[2] + new.begin_strickler = d[3] + new.end_strickler = d[4] + self._new.append((row, new)) + else: + for row, el in self._new: + self._frictions.insert(row, el) class DelCommand(QUndoCommand): diff --git a/src/View/InitialConditions/Window.py b/src/View/InitialConditions/Window.py index b78c07b4..93e06d46 100644 --- a/src/View/InitialConditions/Window.py +++ b/src/View/InitialConditions/Window.py @@ -319,9 +319,10 @@ class InitialConditionsWindow(PamhyrWindow): def _import_from_results(self, results): logger.debug(f"import from results: {results}") - self._table.import_from_results(row, results) + self._table.import_from_results(results) def _import_from_ini_file(self, file_name): + logger.debug(f"import from INI file: {file_name}") self._table.read_from_ini(file_name) def move_up(self): diff --git a/src/View/LateralContribution/Table.py b/src/View/LateralContribution/Table.py index 6b3573c4..d55a1848 100644 --- a/src/View/LateralContribution/Table.py +++ b/src/View/LateralContribution/Table.py @@ -19,7 +19,7 @@ import logging import traceback -from tools import trace, timer +from tools import trace, timer, old_pamhyr_date_to_timestamp from PyQt5.QtCore import ( Qt, QVariant, QAbstractTableModel, @@ -38,7 +38,7 @@ from View.LateralContribution.UndoCommand import ( SetNameCommand, SetEdgeCommand, SetTypeCommand, SetBeginCommand, SetEndCommand, AddCommand, DelCommand, SortCommand, - MoveCommand, PasteCommand, DuplicateCommand, + MoveCommand, PasteCommand, DuplicateCommand, ImportCommand, ) from Model.LateralContribution.LateralContributionTypes import ( @@ -116,17 +116,20 @@ class ComboBoxDelegate(QItemDelegate): def setModelData(self, editor, model, index): text = str(editor.currentText()) - if self._mode == "rk": - profiles = list( - filter( - lambda p: p.display_name() == text, - self._data.reach.profiles - ) - ) - - value = profiles[0].rk if len(profiles) > 0 else None - else: + if self._data is None: value = text + else: + if self._mode == "rk" and self._data.reach is not None: + profiles = list( + filter( + lambda p: p.display_name() == text, + self._data.reach.profiles + ) + ) + + value = profiles[0].rk if len(profiles) > 0 else None + else: + value = text model.setData(index, value) editor.close() @@ -319,3 +322,44 @@ class TableModel(PamhyrTableModel): self.endMoveRows() self.layoutChanged.emit() + + def read_from_lat(self, file_name): + logger.debug(f"Import lateral contributions from {file_name}") + data = [] + current_reach = -1 + with open(file_name, encoding="utf-8") as lat_file: + for line in lat_file: + if not (line.startswith("#") or + line.startswith("*") or + len(line) < 1): + line = line.split() + if line[0] == "$": + current_reach = int(line[1]) - 1 + if (current_reach <= len(self._data.enable_edges()) and + current_reach >= 0): + data.append( + [self._data.enable_edges()[current_reach], + float(line[2]), + float(line[3]) + ] + ) + else: + if (current_reach <= len(self._data.enable_edges()) and + current_reach >= 0): + data[-1].append( + [ + old_pamhyr_date_to_timestamp(line[0]), + float(line[1]) + ] + ) + + self.layoutAboutToBeChanged.emit() + + self._undo.push( + ImportCommand( + self._lst, self._tab, data + ) + ) + + self.layoutAboutToBeChanged.emit() + self.layoutChanged.emit() diff --git a/src/View/LateralContribution/UndoCommand.py b/src/View/LateralContribution/UndoCommand.py index fc9c0164..e320216a 100644 --- a/src/View/LateralContribution/UndoCommand.py +++ b/src/View/LateralContribution/UndoCommand.py @@ -28,6 +28,10 @@ from Model.LateralContribution.LateralContributionList import ( LateralContributionList ) +from Model.LateralContribution.LateralContributionTypes import ( + NotDefined, LateralContrib, +) + class SetNameCommand(QUndoCommand): def __init__(self, lcs, tab, index, new_value): @@ -143,12 +147,12 @@ class DelCommand(QUndoCommand): self._tab = tab self._rows = rows - self._bc = [] + self._lc = [] for row in rows: - self._bc.append(self._lcs.get_tab(self._tab)[row]) + self._lc.append(self._lcs.get_tab(self._tab)[row]) def undo(self): - for el in self._bc: + for el in self._lc: el.set_as_not_deleted() def redo(self): @@ -214,36 +218,73 @@ class MoveCommand(QUndoCommand): class PasteCommand(QUndoCommand): - def __init__(self, lcs, tab, row, bc): + def __init__(self, lcs, tab, row, lc): QUndoCommand.__init__(self) self._lcs = lcs self._tab = tab self._row = row - self._bc = deepcopy(bc) - self._bc.reverse() + self._lc = deepcopy(lc) + self._lc.reverse() def undo(self): - self._lcs.delete(self._tab, self._bc) + self._lcs.delete(self._tab, self._lc) def redo(self): - for bc in self._bc: - self._lcs.insert(self._tab, self._row, bc) + for lc in self._lc: + self._lcs.insert(self._tab, self._row, lc) + + +class ImportCommand(QUndoCommand): + def __init__(self, lcs, tab, data): + QUndoCommand.__init__(self) + + self._tab = tab + self._lcs = lcs + self._data = data + self._old_rows = list(range(len(self._lcs.get_tab(self._tab)))) + self._new_rows = list(range(len(self._data))) + + self._new_lc = None + self._old_lc = [] + for row in self._old_rows: + self._old_lc.append((row, self._lcs.get(self._tab, row))) + + def undo(self): + self._lcs.delete_i(self._tab, self._new_rows) + for row, el in self._old_lc: + self._lcs.insert(self._tab, row, el) + + def redo(self): + self._lcs.delete_i(self._tab, self._old_rows) + if self._new_lc is None: + self._new_lc = [] + for row, data in enumerate(self._data): + new = LateralContrib(status=self._lcs._status) + new.edge = data[0] + new.begin_rk = data[1] + new.end_rk = data[2] + for i, val in enumerate(data[3:]): + new.insert(i, val) + self._new_lc.append(new) + + for row, el in enumerate(self._new_lc): + self._lcs.insert(self._tab, row, el) class DuplicateCommand(QUndoCommand): - def __init__(self, lcs, tab, rows, bc): + def __init__(self, lcs, tab, rows, lc): QUndoCommand.__init__(self) self._lcs = lcs self._tab = tab self._rows = rows - self._bc = deepcopy(bc) - self._bc.reverse() + self._lc = deepcopy(lc) + self._lc.reverse() def undo(self): - self._lcs.delete(self._tab, self._bc) + self._lcs.delete(self._tab, self._lc) def redo(self): - for bc in self._lcs: - self._lcs.insert(self._tab, self._rows[0], bc) + for lc in self._lcs: + self._lcs.insert(self._tab, self._rows[0], lc) diff --git a/src/View/LateralContribution/Window.py b/src/View/LateralContribution/Window.py index c08ad991..b28fe4c1 100644 --- a/src/View/LateralContribution/Window.py +++ b/src/View/LateralContribution/Window.py @@ -22,6 +22,7 @@ from tools import trace, timer from View.Tools.PamhyrWindow import PamhyrWindow +from PyQt5 import QtWidgets from PyQt5.QtGui import ( QKeySequence, ) @@ -29,7 +30,7 @@ from PyQt5.QtGui import ( from PyQt5.QtCore import ( Qt, QVariant, QAbstractTableModel, QCoreApplication, QModelIndex, pyqtSlot, - QRect, + QRect, QSettings, ) from PyQt5.QtWidgets import ( @@ -158,6 +159,8 @@ class LateralContributionWindow(PamhyrWindow): def setup_connections(self): if self._study.is_editable(): + self.find(QAction, "action_import").triggered.connect( + self.import_from_file) 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) @@ -302,3 +305,26 @@ class LateralContributionWindow(PamhyrWindow): parent=self ) win.show() + + def import_from_file(self): + options = QFileDialog.Options() + settings = QSettings(QSettings.IniFormat, + QSettings.UserScope, 'MyOrg', ) + options |= QFileDialog.DontUseNativeDialog + + file_types = [ + self._trad["file_lat"], + self._trad["file_all"], + ] + + filename, _ = QtWidgets.QFileDialog.getOpenFileName( + self, + self._trad["open_file"], + "", + ";; ".join(file_types), + options=options + ) + + if filename != "": + tab = self.current_tab() + self._table[tab].read_from_lat(filename) diff --git a/src/View/LateralContribution/translate.py b/src/View/LateralContribution/translate.py index 57f521aa..ed04fbd3 100644 --- a/src/View/LateralContribution/translate.py +++ b/src/View/LateralContribution/translate.py @@ -52,6 +52,10 @@ class LCTranslate(MainTranslate): self._dict["x"] = _translate("Geometry", "X (m)") self._dict["y"] = _translate("Geometry", "Y (m)") self._dict["z"] = _translate("Geometry", "Z (m)") + self._dict["file_lat"] = _translate( + "LateralContribution", "Shapefile (*.LAT *.lat)") + self._dict["file_all"] = _translate( + "LateralContribution", "All files (*)") self._sub_dict["table_headers"] = { "name": self._dict["name"], diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py index 999648fa..66eab274 100644 --- a/src/View/Results/Window.py +++ b/src/View/Results/Window.py @@ -495,7 +495,7 @@ class ResultsWindow(PamhyrWindow): table = self.find(QTableView, f"tableView_profile") indexes = table.selectedIndexes() if len(indexes) == 0: - return 0 + return [] return [i.row() for i in indexes] diff --git a/src/View/ui/EditLateralContribution.ui b/src/View/ui/EditLateralContribution.ui index 21736a6b..2e739f88 100644 --- a/src/View/ui/EditLateralContribution.ui +++ b/src/View/ui/EditLateralContribution.ui @@ -112,6 +112,18 @@ Sort points + + + + ressources/import.pngressources/import.png + + + Import + + + Import from file + + diff --git a/src/View/ui/LateralContributions.ui b/src/View/ui/LateralContributions.ui index 32f4f60a..5d44cba2 100644 --- a/src/View/ui/LateralContributions.ui +++ b/src/View/ui/LateralContributions.ui @@ -97,6 +97,7 @@ false + @@ -162,6 +163,18 @@ Sort by names + + + + ressources/import.pngressources/import.png + + + Import + + + Import from file + + diff --git a/src/tools.py b/src/tools.py index 02a783de..9ea2fb80 100644 --- a/src/tools.py +++ b/src/tools.py @@ -264,7 +264,10 @@ def date_dmy_to_timestamp(date: str): def old_pamhyr_date_to_timestamp(date: str): v = date.split(":") if len(v) != 4: - return 0 + if len(v) == 1: # minutes + return int(float(v[0]) * 60) # Minute to sec + else: + return 0 m = [ (24 * 60 * 60), # Day to sec diff --git a/tests_cases/HHLab/HHLab.pamhyr b/tests_cases/HHLab/HHLab.pamhyr new file mode 100644 index 00000000..f2b713ab Binary files /dev/null and b/tests_cases/HHLab/HHLab.pamhyr differ