Compare commits

..

24 Commits

Author SHA1 Message Date
Pierre-Antoine 662a218e41 Results: Reach: Keep profiles global min and max. 2026-06-26 16:51:58 +02:00
Pierre-Antoine 0501ae9bec Solver: Mage: read_bin: Use np table for velocity computation. 2026-06-26 16:20:32 +02:00
Pierre-Antoine 7fd38eec00 Results: Table: Minor change. 2026-06-26 14:54:55 +02:00
Pierre-Antoine 4bab4580ad Results: PlotXY: Use table Z to display max elevation. 2026-06-26 14:41:24 +02:00
Pierre-Antoine 21d2e6ad20 Results: PlotAC: Use Z table. 2026-06-26 14:23:00 +02:00
Pierre-Antoine d0a8f369ef Results: PlotH: Use np table. 2026-06-26 14:05:29 +02:00
Pierre-Antoine fef2e1a40c Results: PlotXY: Minor change. 2026-06-26 10:51:36 +02:00
Pierre-Antoine 20c2cb7ea4 Merge branch 'master' into opt-result 2026-06-26 09:29:39 +02:00
Pierre-Antoine 64a26e987e ci: Fix again. 2026-06-25 15:48:41 +02:00
Pierre-Antoine eb233847de ci: Fix pipeline for release. 2026-06-25 15:42:46 +02:00
Pierre-Antoine 7bb810d427 Pollutants: Fix 'enabled' column update version. 2026-06-25 15:00:41 +02:00
Dylan Jeannin e49724072b Merge branch 'dev_dylan' into scenarios 2026-06-25 14:41:24 +02:00
Dylan Jeannin 3664ba93e9 Results: Fix open mage results from AdisTS solver 2026-06-25 14:39:45 +02:00
Dylan Jeannin a9903e987b AdisTS: Resolve bug with node ids not matching in config files 2026-06-25 14:05:04 +02:00
Dylan Jeannin f9a88a211c Fix pep8 2026-06-22 17:10:57 +02:00
Dylan Jeannin 32535af3e6 UpdateRK: avoid crash when updating RK with missing points on a section, warning message instead 2026-06-22 17:04:39 +02:00
Dylan Jeannin fa8948c1b6 Meshing: Debug error caused by index out of range when adding an empty transect on a reach 2026-06-22 15:18:08 +02:00
Dylan Jeannin 2d5455c09d Meshing: Debug crashing case when divide by 0 2026-06-22 14:16:33 +02:00
Dylan Jeannin 83680bbe57 Pollutant: quickfix, back to previous version 2026-06-22 12:12:02 +02:00
Dylan Jeannin 1d1a00a0ff Pollutants: merge conflicts 2026-06-22 10:42:29 +02:00
Dylan Jeannin ffd95b9fdf Pollutants: merge conflicts 2026-06-22 10:42:07 +02:00
Dylan Jeannin 48d6728e1e Enable pollutant: fix the list to browse to enable a pol 2026-05-28 15:11:06 +02:00
Dylan Jeannin c51c06e6ec DB version: Upgrade to add enabled in pollutants db 2026-05-28 15:02:40 +02:00
Dylan Jeannin a425c9a6ac BoundaryConditions: delete setter/getter duplicated for d50 and sigma 2026-05-28 15:01:36 +02:00
19 changed files with 240 additions and 165 deletions

View File

@ -638,7 +638,7 @@ shadow-release:
- job: pkg-hash - job: pkg-hash
artifacts: true artifacts: true
rules: rules:
- if: $CI_COMMIT_BRANCH != 'master' && $CI_COMMIT_TAG - if: $CI_COMMIT_TAG && $CI_COMMIT_TAG !~ /^v/
artifacts: artifacts:
paths: paths:
- linux/pamhyr-gnulinux.tar.xz - linux/pamhyr-gnulinux.tar.xz
@ -672,7 +672,7 @@ tag-release:
- job: pkg-hash - job: pkg-hash
artifacts: true artifacts: true
rules: rules:
- if: $CI_COMMIT_BRANCH == 'master' && $CI_COMMIT_TAG - if: $CI_COMMIT_TAG =~ /^v/
artifacts: artifacts:
paths: paths:
- linux/pamhyr-gnulinux.tar.xz - linux/pamhyr-gnulinux.tar.xz

View File

@ -166,7 +166,6 @@ class InternalMeshing(AMeshingTool):
for i in range(len1): for i in range(len1):
ltot1 += sect1.point(start1+i).dist(sect1.point(start1+i+1)) ltot1 += sect1.point(start1+i).dist(sect1.point(start1+i+1))
alpha.append(ltot1) alpha.append(ltot1)
alpha = list(map(lambda x: x/ltot1, alpha)) # target ratios
for i in range(len2): for i in range(len2):
ltot2 += sect2.point(start2+i).dist(sect2.point(start2+i+1)) ltot2 += sect2.point(start2+i).dist(sect2.point(start2+i+1))
beta.append(ltot2) beta.append(ltot2)
@ -181,6 +180,7 @@ class InternalMeshing(AMeshingTool):
sect2.add_npoints(len1-len2) sect2.add_npoints(len1-len2)
len2 = len1 len2 = len1
else: # regular case else: # regular case
alpha = list(map(lambda x: x/ltot1, alpha)) # target ratios
beta = list(map(lambda x: x/ltot2, beta)) # current ratios beta = list(map(lambda x: x/ltot2, beta)) # current ratios
for i in range(len1 - len2): for i in range(len1 - len2):
beta.append(1.0) beta.append(1.0)

View File

@ -514,42 +514,6 @@ class BoundaryCondition(SQLSubModel):
self._sigma = float(value) self._sigma = float(value)
self.modified() self.modified()
@property
def d50(self):
return self._d50
@d50.setter
def d50(self, value):
self._d50 = float(value)
self.modified()
@property
def sigma(self):
return self._sigma
@sigma.setter
def sigma(self, value):
self._sigma = float(value)
self.modified()
@property
def d50(self):
return self._d50
@d50.setter
def d50(self, value):
self._d50 = float(value)
self.modified()
@property
def sigma(self):
return self._sigma
@sigma.setter
def sigma(self, value):
self._sigma = float(value)
self.modified()
@property @property
def header(self): def header(self):
return self._header.copy() return self._header.copy()

View File

@ -350,6 +350,7 @@ class Pollutants(SQLSubModel):
CREATE TABLE pollutants{ext}( CREATE TABLE pollutants{ext}(
{cls.create_db_add_pamhyr_id()}, {cls.create_db_add_pamhyr_id()},
deleted BOOLEAN NOT NULL DEFAULT FALSE, deleted BOOLEAN NOT NULL DEFAULT FALSE,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
name TEXT NOT NULL, name TEXT NOT NULL,
{Scenario.create_db_add_scenario()}, {Scenario.create_db_add_scenario()},
{Scenario.create_db_add_scenario_fk()} {Scenario.create_db_add_scenario_fk()}
@ -373,6 +374,14 @@ class Pollutants(SQLSubModel):
cls._db_create(execute) cls._db_create(execute)
created = True created = True
if major == "0" and minor == "2":
if int(release) < 6:
execute(f"ALTER TABLE pollutants " +
f"ADD COLUMN enabled BOOLEAN NOT NULL DEFAULT TRUE")
# cls._db_update_to_0_2_5(execute, data)
# # created = True
if not created: if not created:
return cls._update_submodel(execute, version, data) return cls._update_submodel(execute, version, data)
@ -410,7 +419,8 @@ class Pollutants(SQLSubModel):
return new return new
table = execute( table = execute(
"SELECT pamhyr_id, deleted, name, scenario FROM pollutants " + "SELECT pamhyr_id, deleted, enabled, name, scenario " +
"FROM pollutants " +
f"WHERE scenario = {scenario.id} " + f"WHERE scenario = {scenario.id} " +
f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))})" f"AND pamhyr_id NOT IN ({', '.join(map(str, loaded))})"
) )
@ -421,6 +431,7 @@ class Pollutants(SQLSubModel):
pid = next(it) pid = next(it)
deleted = (next(it) == 1) deleted = (next(it) == 1)
enabled = (next(it) == 1)
name = next(it) name = next(it)
owner_scenario = next(it) owner_scenario = next(it)
@ -431,6 +442,8 @@ class Pollutants(SQLSubModel):
) )
if deleted: if deleted:
new_pollutant.set_as_deleted() new_pollutant.set_as_deleted()
if not enabled:
new_pollutant.enabled = False
data["pollutant"] = new_pollutant data["pollutant"] = new_pollutant
new_pollutant._data = PollutantCharacteristics._db_load( new_pollutant._data = PollutantCharacteristics._db_load(
@ -472,9 +485,10 @@ class Pollutants(SQLSubModel):
execute( execute(
"INSERT INTO " + "INSERT INTO " +
"pollutants(pamhyr_id, deleted, name, scenario) " + "pollutants(pamhyr_id, deleted, enabled, name, scenario) " +
"VALUES (" + "VALUES (" +
f"{self.id}, {self._db_format(self.is_deleted())}, " + f"{self.id}, {self._db_format(self.is_deleted())}, " +
f"{self._db_format(self._enabled)}, " +
f"'{self._db_format(self._name)}', " + f"'{self._db_format(self._name)}', " +
f"{self._status.scenario_id}" + f"{self._status.scenario_id}" +
")" ")"

View File

@ -304,6 +304,9 @@ class Reach(SQLSubModel):
lambda p: p.name[0:8] != 'interpol', self._profiles lambda p: p.name[0:8] != 'interpol', self._profiles
) )
) )
self._global_index = (-1, -1)
self._buffers = {} self._buffers = {}
def __len__(self): def __len__(self):
@ -333,9 +336,15 @@ class Reach(SQLSubModel):
return self._profiles[id] return self._profiles[id]
def set_global_index(self, indexs): def set_global_index(self, indexs):
self._global_index = (indexs[0], indexs[-1])
for profile, ind in zip(self._profiles, indexs): for profile, ind in zip(self._profiles, indexs):
profile.global_index = ind profile.global_index = ind
@property
def global_index(self):
return self._global_index
@timer @timer
def set(self, profile_id, timestamp, key, data): def set(self, profile_id, timestamp, key, data):
self._profiles[profile_id].set(timestamp, key, data) self._profiles[profile_id].set(timestamp, key, data)

View File

@ -46,7 +46,7 @@ logger = logging.getLogger()
class Study(SQLModel): class Study(SQLModel):
_version = "0.2.5" _version = "0.2.6"
_sub_classes = [ _sub_classes = [
Scenario, Scenario,

View File

@ -280,8 +280,8 @@ class AdisTS(CommandLineSolver):
name = f"Reach_{e.id + 1:>3}".replace(" ", "0") name = f"Reach_{e.id + 1:>3}".replace(" ", "0")
id = name id = name
n1 = f"{e.node1.id:3}".replace(" ", "x") n1 = f"{self.get_node_name(e.node1):3}".replace(" ", "x")
n2 = f"{e.node2.id:3}".replace(" ", "x") n2 = f"{self.get_node_name(e.node2):3}".replace(" ", "x")
file = os.path.join("net", name + ".ST") file = os.path.join("net", name + ".ST")
f.write(f"{id} {n1} {n2} {file}\n") f.write(f"{id} {n1} {n2} {file}\n")
@ -455,47 +455,6 @@ class AdisTS(CommandLineSolver):
def get_reach_name(self, reach): def get_reach_name(self, reach):
return f"Reach_{reach.pamhyr_id:>3}".replace(" ", "0") return f"Reach_{reach.pamhyr_id:>3}".replace(" ", "0")
def get_node_name(self, node):
"""Generate a 3 char name for node
Args:
node: The node
Returns:
A 3 char name string
"""
n = node.pamhyr_id
# print("node name id: ", n)
# if n in self._nodes_names:
# return self._nodes_names[n]
name = ""
checked_new = False
while not checked_new:
self._nodes_cnt += 1
nc = self._nodes_cnt
name = "".join(
map(
lambda i: self._alph[i % self._l_alph],
[
int(nc / (self._l_alph * self._l_alph)),
int(nc / self._l_alph),
nc
]
)
)
checked_new = name not in self._nodes_views
self._nodes_views.add(name)
self._nodes_names[n] = name
return name
################################# #################################
# Adis-TS in weak coupling mode # # Adis-TS in weak coupling mode #
################################# #################################

View File

@ -1198,8 +1198,8 @@ class Mage8(Mage):
for r in reachs: for r in reachs:
for pi, p in enumerate(r.profiles): for pi, p in enumerate(r.profiles):
v = p.geometry.speed( v = p.geometry.speed(
p.get_ts_key(t, "Q"), table["Q"][ti, p.global_index],
p.get_ts_key(t, "Z") table["Z"][ti, p.global_index],
) )
r.set(pi, t, "V", v) r.set(pi, t, "V", v)
velocity_arr[ti, j] = v velocity_arr[ti, j] = v

View File

@ -143,7 +143,7 @@ class PlotAC(PamhyrPlot):
] ]
else: else:
color = self.color_incomplete_gl[ color = self.color_incomplete_gl[
lincomplete.index(txt) lincomplete.index(txt) % len(self.color_incomplete_gl)
] ]
annotation = self.canvas.axes.annotate( annotation = self.canvas.axes.annotate(

View File

@ -97,3 +97,15 @@ class GeometryTranslate(MainTranslate):
self._dict["format_not_exportable"] = _translate( self._dict["format_not_exportable"] = _translate(
"Geometry", "The format of the file is not exportable." "Geometry", "The format of the file is not exportable."
) )
self._dict["update_rk_error"] = _translate(
"Geometry",
"RK update can't be executed."
)
self._dict["update_rk_empty_profiles"] = _translate(
"Geometry",
"Some profiles don't contain any point."
)
self._dict["update_rk_empty_profiles_info"] = _translate(
"Geometry",
"Profiles concerned:"
)

View File

@ -371,6 +371,29 @@ class GeometryWindow(PamhyrWindow):
parent=self parent=self
) )
if dlg.exec(): if dlg.exec():
empty_profiles = [
profile for profile in self._reach.profiles
if profile.number_points == 0
]
if empty_profiles:
profile_names = ", ".join(
profile.name or str(profile.num)
for profile in empty_profiles
)
self.message_box(
(
self._trad["update_rk_error"] +
"\n" +
self._trad["update_rk_empty_profiles"]
),
(
self._trad["update_rk_empty_profiles_info"] +
f" {profile_names}"
),
window_title=self._trad["warning"]
)
return
data = { data = {
"origin": dlg.origin, "origin": dlg.origin,
"directrices": [dlg.begin_dir, dlg.end_dir], "directrices": [dlg.begin_dir, dlg.end_dir],

View File

@ -128,7 +128,7 @@ class TableModel(PamhyrTableModel):
def enabled(self, row, enabled, parent=QModelIndex()): def enabled(self, row, enabled, parent=QModelIndex()):
self._undo.push( self._undo.push(
SetEnabledCommand( SetEnabledCommand(
self._data._Pollutants, row, enabled self._lst, row, enabled
) )
) )
self.layoutChanged.emit() self.layoutChanged.emit()

View File

@ -16,6 +16,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import numpy as np
from tools import timer from tools import timer
from View.Tools.PamhyrPlot import PamhyrPlot from View.Tools.PamhyrPlot import PamhyrPlot
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
@ -103,11 +105,20 @@ class PlotAC(PamhyrPlot):
color=self.color_plot_river_bottom, color=self.color_plot_river_bottom,
) )
@timer
def draw_water_elevation(self, reach, profile): def draw_water_elevation(self, reach, profile):
result = self.results[self._current_res_id]
x = profile.geometry.get_station() x = profile.geometry.get_station()
z = profile.geometry.z() z = profile.geometry.z()
rk = reach.geometry.get_rk() rk = reach.geometry.get_rk()
water_z = profile.get_ts_key(self._current_timestamp, "Z") water_z = result.get("table")["Z"][
result.get_timestamp_id(
self._current_timestamp
),
profile.global_index
]
# water_z = profile.get_ts_key(self._current_timestamp, "Z")
self.water, = self.canvas.axes.plot( self.water, = self.canvas.axes.plot(
[min(x), max(x)], [water_z, water_z], [min(x), max(x)], [water_z, water_z],
@ -123,11 +134,18 @@ class PlotAC(PamhyrPlot):
) )
self.liste_chemins = self.collection.get_paths() self.liste_chemins = self.collection.get_paths()
@timer
def draw_water_elevation_max(self, reach, profile): def draw_water_elevation_max(self, reach, profile):
result = self.results[self._current_res_id]
x = profile.geometry.get_station() x = profile.geometry.get_station()
z = profile.geometry.z() z = profile.geometry.z()
rk = reach.geometry.get_rk() rk = reach.geometry.get_rk()
water_z = max(profile.get_key("Z"))
water_z = np.max(
result.get("table")["Z"][:, profile.global_index]
)
# water_z = max(profile.get_key("Z"))
self.water_max, = self.canvas.axes.plot( self.water_max, = self.canvas.axes.plot(
[min(x), max(x)], [water_z, water_z], [min(x), max(x)], [water_z, water_z],
@ -262,7 +280,15 @@ class PlotAC(PamhyrPlot):
self.line_rk.set_data(x, z) self.line_rk.set_data(x, z)
def update_water(self, reach, profile, x, z): def update_water(self, reach, profile, x, z):
water_z = profile.get_ts_key(self._current_timestamp, "Z") result = self.results[self._current_res_id]
water_z = result.get("table")["Z"][
result.get_timestamp_id(
self._current_timestamp
),
profile.global_index
]
# water_z = profile.get_ts_key(self._current_timestamp, "Z")
self.water.set_data( self.water.set_data(
[min(x), max(x)], [min(x), max(x)],
[water_z, water_z] [water_z, water_z]
@ -277,7 +303,12 @@ class PlotAC(PamhyrPlot):
) )
def update_water_max(self, reach, profile, x, z): def update_water_max(self, reach, profile, x, z):
water_z = max(profile.get_key("Z")) result = self.results[self._current_res_id]
water_z = np.max(
result.get("table")["Z"][:, profile.global_index]
)
# water_z = max(profile.get_key("Z"))
self.water_max.set_data( self.water_max.set_data(
[min(x), max(x)], [min(x), max(x)],
[water_z, water_z] [water_z, water_z]

View File

@ -128,14 +128,19 @@ class PlotH(PamhyrPlot):
self.draw_current() self.draw_current()
self._init = True self._init = True
@timer
def draw_data(self, res_id): def draw_data(self, res_id):
results = self.results[res_id] results = self.results[res_id]
reach = results.river.reach(self._current_reach_id) reach = results.river.reach(self._current_reach_id)
q = results.get("table")["Q"]
for i, p in enumerate(self._current_profile_id): for i, p in enumerate(self._current_profile_id):
profile = reach.profile(p) profile = reach.profile(p)
x = self._timestamps x = self._timestamps
y = profile.get_key("Q") y = q[:, profile.global_index]
# y = profile.get_key("Q")
if res_id == 2: if res_id == 2:
label = "Δ " + self.label_discharge + f" {profile.name}" label = "Δ " + self.label_discharge + f" {profile.name}"
@ -187,6 +192,7 @@ class PlotH(PamhyrPlot):
lw=1., lw=1.,
) )
@timer
def draw_max(self, res_id): def draw_max(self, res_id):
results = self.results[res_id] results = self.results[res_id]
reach = results.river.reach(self._current_reach_id) reach = results.river.reach(self._current_reach_id)
@ -198,16 +204,21 @@ class PlotH(PamhyrPlot):
x = self._timestamps x = self._timestamps
y = [] y = []
q_table = results.get("table")["Q"]
if res_id == 2: if res_id == 2:
label = "Δ " + self.label_discharge_max label = "Δ " + self.label_discharge_max
else: else:
label = self.label_discharge_max label = self.label_discharge_max
for ts in x: for i, ts in enumerate(x):
ts_y = -9999 ts_y = -9999
for profile in reach.profiles: for profile in reach.profiles:
q = profile.get_ts_key(ts, "Q") q = q_table[i, profile.global_index]
# q = profile.get_ts_key(ts, "Q")
ts_y = max(ts_y, q) ts_y = max(ts_y, q)
y.append(ts_y) y.append(ts_y)
m, = self.canvas.axes.plot( m, = self.canvas.axes.plot(

View File

@ -20,9 +20,10 @@ import logging
from functools import reduce from functools import reduce
import numpy as np
from tools import timer, trace, logger_exception from tools import timer, trace, logger_exception
from View.Tools.PamhyrPlot import PamhyrPlot from View.Tools.PamhyrPlot import PamhyrPlot
import numpy as np
from matplotlib import collections from matplotlib import collections
from PyQt5.QtCore import ( from PyQt5.QtCore import (
@ -239,14 +240,20 @@ class PlotXY(PamhyrPlot):
) )
def draw_water_elevation_max(self, reach): def draw_water_elevation_max(self, reach):
result = self.results[self._current_res_id]
l_x, l_y, r_x, r_y = [], [], [], [] l_x, l_y, r_x, r_y = [], [], [], []
overflow = [] overflow = []
for profile in reach.profiles: for profile in reach.profiles:
z_max = max(profile.get_key("Z")) zs = result.get("table")["Z"][
:, profile.global_index
]
z_max = np.max(zs)
z_max_ts = 0 z_max_ts = 0
for ts in self._timestamps:
z = profile.get_ts_key(ts, "Z") for i, ts in enumerate(self._timestamps):
z = zs[i]
if z == z_max: if z == z_max:
z_max_ts = ts z_max_ts = ts
break break
@ -304,10 +311,6 @@ class PlotXY(PamhyrPlot):
poly_l_x, poly_l_y, poly_r_x, poly_r_y = [], [], [], [] poly_l_x, poly_l_y, poly_r_x, poly_r_y = [], [], [], []
for profile in reach.profiles: for profile in reach.profiles:
water_z = profile.get_ts_key(
self._current_timestamp, "Z"
)
pt_left, pt_right = profile.get_ts_key( pt_left, pt_right = profile.get_ts_key(
self._current_timestamp, self._current_timestamp,
"water_limits" "water_limits"
@ -435,9 +438,6 @@ class PlotXY(PamhyrPlot):
poly_l_x, poly_l_y, poly_r_x, poly_r_y = [], [], [], [] poly_l_x, poly_l_y, poly_r_x, poly_r_y = [], [], [], []
for profile in reach.profiles: for profile in reach.profiles:
water_z = profile.get_ts_key(
self._current_timestamp, "Z"
)
pt_left, pt_right = profile.get_ts_key( pt_left, pt_right = profile.get_ts_key(
self._current_timestamp, self._current_timestamp,
"water_limits" "water_limits"

View File

@ -53,7 +53,7 @@ class Worker(QObject):
class ReadingResultsDialog(PamhyrDialog): class ReadingResultsDialog(PamhyrDialog):
_pamhyr_ui = "DialogReadingResults" _pamhyr_ui = "WaitingDialog"
_pamhyr_name = "Reading results" _pamhyr_name = "Reading results"
_spin = ["-", "\\", "|", "/"] _spin = ["-", "\\", "|", "/"]

View File

@ -74,74 +74,75 @@ class TableModel(PamhyrTableModel):
row = index.row() row = index.row()
column = index.column() column = index.column()
p = self._lst[row]
if self._opt_data == "reach": if self._opt_data == "reach":
if self._headers[column] == "name": if self._headers[column] == "name":
v = self._lst[row].name v = p.name
return str(v) return str(v)
elif self._opt_data == "profile": elif self._opt_data == "profile":
if self._headers[column] == "name": if self._headers[column] == "name":
v = self._lst[row].name v = p.name
return str(v) return str(v)
elif self._headers[column] == "rk": elif self._headers[column] == "rk":
v = self._lst[row].rk v = p.rk
return f"{v:.4f}" return f"{v:.4f}"
elif self._opt_data == "solver": elif self._opt_data == "solver":
if self._headers[column] == "solver": if self._headers[column] == "solver":
v = self._lst[row] v = p
if v is None: if v is None:
v = self._data[0].solver_name v = self._data[0].solver_name
return str(v) return str(v)
elif self._opt_data == "raw_data": elif self._opt_data == "raw_data":
p = self._lst[row]
if self._headers[column] == "name": if self._headers[column] == "name":
if p.name == "": if p.name == "":
return f"{p.rk:.4f}" return f"{p.rk:.4f}"
return f"{p.name}" return f"{p.name}"
elif self._headers[column] == "water_elevation": elif self._headers[column] == "water_elevation":
v = self._lst[row].get_ts_key(self._timestamp, "Z") v = p.get_ts_key(self._timestamp, "Z")
if v is None: if v is None:
v = 0.0 v = 0.0
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "discharge": elif self._headers[column] == "discharge":
v = self._lst[row].get_ts_key(self._timestamp, "Q") v = p.get_ts_key(self._timestamp, "Q")
if v is None: if v is None:
v = 0.0 v = 0.0
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "velocity": elif self._headers[column] == "velocity":
v = self._lst[row].get_ts_key(self._timestamp, "V") v = p.get_ts_key(self._timestamp, "V")
if v is None: if v is None:
v = 0.0 v = 0.0
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "width": elif self._headers[column] == "width":
z = self._lst[row].get_ts_key(self._timestamp, "Z") z = p.get_ts_key(self._timestamp, "Z")
v = self._lst[row].geometry.wet_width(z) v = p.geometry.wet_width(z)
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "depth": elif self._headers[column] == "depth":
z = self._lst[row].get_ts_key(self._timestamp, "Z") z = p.get_ts_key(self._timestamp, "Z")
v = self._lst[row].geometry.max_water_depth(z) v = p.geometry.max_water_depth(z)
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "mean_depth": elif self._headers[column] == "mean_depth":
z = self._lst[row].get_ts_key(self._timestamp, "Z") z = p.get_ts_key(self._timestamp, "Z")
v = self._lst[row].geometry.mean_water_depth(z) v = p.geometry.mean_water_depth(z)
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "wet_area": elif self._headers[column] == "wet_area":
z = self._lst[row].get_ts_key(self._timestamp, "Z") z = p.get_ts_key(self._timestamp, "Z")
v = self._lst[row].geometry.wet_area(z) v = p.geometry.wet_area(z)
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "wet_perimeter": elif self._headers[column] == "wet_perimeter":
z = self._lst[row].get_ts_key(self._timestamp, "Z") z = p.get_ts_key(self._timestamp, "Z")
v = self._lst[row].geometry.wet_perimeter(z) v = p.geometry.wet_perimeter(z)
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "hydraulic_radius": elif self._headers[column] == "hydraulic_radius":
z = self._lst[row].get_ts_key(self._timestamp, "Z") z = p.get_ts_key(self._timestamp, "Z")
v = self._lst[row].geometry.wet_radius(z) v = p.geometry.wet_radius(z)
return f"{v:.4f}" return f"{v:.4f}"
elif self._headers[column] == "froude": elif self._headers[column] == "froude":
q = self._lst[row].get_ts_key(self._timestamp, "Q") q = p.get_ts_key(self._timestamp, "Q")
z = self._lst[row].get_ts_key(self._timestamp, "Z") z = p.get_ts_key(self._timestamp, "Z")
v = self._lst[row].get_ts_key(self._timestamp, "V") v = p.get_ts_key(self._timestamp, "V")
a = self._lst[row].geometry.wet_area(z) a = p.geometry.wet_area(z)
b = self._lst[row].geometry.wet_width(z) b = p.geometry.wet_width(z)
if b == 0.0 or a == 0.0: if b == 0.0 or a == 0.0:
froude = 0.0 froude = 0.0
else: else:

View File

@ -474,10 +474,10 @@ class SolverLogWindowAdisTS(PamhyrWindow):
self._solver.has_results_loaded() self._solver.has_results_loaded()
def resultsMage(self): def resultsMage(self):
mage_solver = next(filter(
lambda x: x._name == self._mage_rep, self._config.solvers
))
if self._results_mage is None: if self._results_mage is None:
mage_solver = next(filter(
lambda x: x._name == self._mage_rep, self._config.solvers
))
workdir_mage = self._workdir_mage workdir_mage = self._workdir_mage
def reading_fn(): def reading_fn():

View File

@ -771,12 +771,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>Dernière modification :</translation> <translation>Dernière modification :</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/CustomPlotValuesSelectionDialog.ui" line="27"/> <location filename="../View/ui/CustomPlotValuesSelectionDialog.ui" line="37"/>
<source>X axis:</source> <source>X axis:</source>
<translation>Axe X :</translation> <translation>Axe X :</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/CustomPlotValuesSelectionDialog.ui" line="38"/> <location filename="../View/ui/CustomPlotValuesSelectionDialog.ui" line="48"/>
<source>Y axis:</source> <source>Y axis:</source>
<translation>Axe Y :</translation> <translation>Axe Y :</translation>
</message> </message>
@ -943,12 +943,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<message> <message>
<location filename="../View/ui/InitialConditions_Dialog_Generator_Height.ui" line="25"/> <location filename="../View/ui/InitialConditions_Dialog_Generator_Height.ui" line="25"/>
<source>Upstream height (m)</source> <source>Upstream height (m)</source>
<translation>Cote à l'amont (m)</translation> <translation type="obsolete">Cote à l'amont (m)</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/InitialConditions_Dialog_Generator_Height.ui" line="73"/> <location filename="../View/ui/InitialConditions_Dialog_Generator_Height.ui" line="73"/>
<source>Downstream height (m)</source> <source>Downstream height (m)</source>
<translation>Cote à l'aval (m)</translation> <translation type="obsolete">Cote à l'aval (m)</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/InitialConditions_Dialog_Generator_Height.ui" line="107"/> <location filename="../View/ui/InitialConditions_Dialog_Generator_Height.ui" line="107"/>
@ -991,7 +991,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>Débit (m³/s)</translation> <translation>Débit (m³/s)</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/CustomExportAdisDialog.ui" line="59"/> <location filename="../View/ui/CustomExportAdisDialog.ui" line="49"/>
<source>Pollutant:</source> <source>Pollutant:</source>
<translation>Polluant:</translation> <translation>Polluant:</translation>
</message> </message>
@ -1040,6 +1040,21 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<source>Image coordinates</source> <source>Image coordinates</source>
<translation type="obsolete">Coordonnées de l'image</translation> <translation type="obsolete">Coordonnées de l'image</translation>
</message> </message>
<message>
<location filename="../View/ui/CustomPlotValuesSelectionDialog.ui" line="59"/>
<source>TextLabel</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../View/ui/InitialConditions_Dialog_Generator_Height.ui" line="25"/>
<source>Upstream elevation (m)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../View/ui/InitialConditions_Dialog_Generator_Height.ui" line="73"/>
<source>Downstream elevation (m)</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Documentation</name> <name>Documentation</name>
@ -1557,12 +1572,33 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<message> <message>
<location filename="../View/Geometry/Translate.py" line="94"/> <location filename="../View/Geometry/Translate.py" line="94"/>
<source>Warning</source> <source>Warning</source>
<translation type="unfinished">Avertissement</translation> <translation>Avertissement</translation>
</message> </message>
<message> <message>
<location filename="../View/Geometry/Translate.py" line="97"/> <location filename="../View/Geometry/Translate.py" line="97"/>
<source>The format of the file is not exportable.</source> <source>The format of the file is not exportable.</source>
<translation type="unfinished"></translation> <translation>Le format de fichier n'est pas exportable.</translation>
</message>
<message>
<location filename="../View/Geometry/Translate.py" line="100"/>
<source>RK update can&apos;t be executed
Some profiles don&apos;t contain any point.</source>
<translation type="obsolete">La mise à jour du PK ne peut pas être exécutée\nDes profils ne contiennent aucun points.</translation>
</message>
<message>
<location filename="../View/Geometry/Translate.py" line="108"/>
<source>Profiles concerned:</source>
<translation>Profils concernés:</translation>
</message>
<message>
<location filename="../View/Geometry/Translate.py" line="100"/>
<source>RK update can&apos;t be executed.</source>
<translation>La mise à jour du PK ne peut pas être exécutée.</translation>
</message>
<message>
<location filename="../View/Geometry/Translate.py" line="104"/>
<source>Some profiles don&apos;t contain any point.</source>
<translation>Des profils ne contiennent aucun points.</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1647,12 +1683,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>Évaporation</translation> <translation>Évaporation</translation>
</message> </message>
<message> <message>
<location filename="../View/LateralContribution/translate.py" line="64"/> <location filename="../View/LateralContribution/translate.py" line="65"/>
<source>Start (m)</source> <source>Start (m)</source>
<translation>PK de départ (m)</translation> <translation>PK de départ (m)</translation>
</message> </message>
<message> <message>
<location filename="../View/LateralContribution/translate.py" line="65"/> <location filename="../View/LateralContribution/translate.py" line="66"/>
<source>End (m)</source> <source>End (m)</source>
<translation>PK de fin (m)</translation> <translation>PK de fin (m)</translation>
</message> </message>
@ -1674,13 +1710,18 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<message> <message>
<location filename="../View/LateralContribution/translate.py" line="55"/> <location filename="../View/LateralContribution/translate.py" line="55"/>
<source>Shapefile (*.LAT *.lat)</source> <source>Shapefile (*.LAT *.lat)</source>
<translation>Shapefile (*.LAT *.lat)</translation> <translation type="obsolete">Shapefile (*.LAT *.lat)</translation>
</message> </message>
<message> <message>
<location filename="../View/LateralContribution/translate.py" line="57"/> <location filename="../View/LateralContribution/translate.py" line="58"/>
<source>All files (*)</source> <source>All files (*)</source>
<translation>Tous les fichiers (*)</translation> <translation>Tous les fichiers (*)</translation>
</message> </message>
<message>
<location filename="../View/LateralContribution/translate.py" line="55"/>
<source>Mage lateral contributions file (*.LAT *.lat)</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>LateralContributionAdisTS</name> <name>LateralContributionAdisTS</name>
@ -2858,32 +2899,32 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>AdisTS</translation> <translation>AdisTS</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/MainWindow.ui" line="761"/> <location filename="../View/ui/MainWindow.ui" line="758"/>
<source>Output RK</source> <source>Output RK</source>
<translation>Pk de sortie</translation> <translation>Pk de sortie</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/MainWindow.ui" line="770"/> <location filename="../View/ui/MainWindow.ui" line="767"/>
<source>Run AdisTS</source> <source>Run AdisTS</source>
<translation>Lancer AdisTS</translation> <translation>Lancer AdisTS</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/MainWindow.ui" line="775"/> <location filename="../View/ui/MainWindow.ui" line="772"/>
<source>Pollutants</source> <source>Pollutants</source>
<translation>Polluants</translation> <translation>Polluants</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/MainWindow.ui" line="780"/> <location filename="../View/ui/MainWindow.ui" line="777"/>
<source>D90</source> <source>D90</source>
<translation>D90</translation> <translation>D90</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/MainWindow.ui" line="785"/> <location filename="../View/ui/MainWindow.ui" line="782"/>
<source>DIF</source> <source>DIF</source>
<translation>DIF</translation> <translation>DIF</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/MainWindow.ui" line="801"/> <location filename="../View/ui/MainWindow.ui" line="798"/>
<source>Open results AdisTS</source> <source>Open results AdisTS</source>
<translation>Ouvrir des résultats AdisTS</translation> <translation>Ouvrir des résultats AdisTS</translation>
</message> </message>
@ -3008,7 +3049,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>Non</translation> <translation>Non</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/MainWindow.ui" line="809"/> <location filename="../View/ui/MainWindow.ui" line="806"/>
<source>Compare results</source> <source>Compare results</source>
<translation>Comparaison de résultats</translation> <translation>Comparaison de résultats</translation>
</message> </message>
@ -3168,7 +3209,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>Editer l'arbre des scénarios</translation> <translation>Editer l'arbre des scénarios</translation>
</message> </message>
<message> <message>
<location filename="../View/ui/MainWindow.ui" line="814"/> <location filename="../View/ui/MainWindow.ui" line="811"/>
<source>GeoTIFF</source> <source>GeoTIFF</source>
<translation>GeoTIFF</translation> <translation>GeoTIFF</translation>
</message> </message>
@ -3432,22 +3473,22 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<context> <context>
<name>Results</name> <name>Results</name>
<message> <message>
<location filename="../View/Results/Window.py" line="324"/> <location filename="../View/Results/Window.py" line="362"/>
<source>days</source> <source>days</source>
<translation>jours</translation> <translation>jours</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/Window.py" line="325"/> <location filename="../View/Results/Window.py" line="363"/>
<source>day</source> <source>day</source>
<translation>jour</translation> <translation>jour</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/PlotXY.py" line="78"/> <location filename="../View/Results/PlotXY.py" line="81"/>
<source>X (m)</source> <source>X (m)</source>
<translation>X (m)</translation> <translation>X (m)</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/PlotXY.py" line="79"/> <location filename="../View/Results/PlotXY.py" line="82"/>
<source>Y (m)</source> <source>Y (m)</source>
<translation>Y (m)</translation> <translation>Y (m)</translation>
</message> </message>
@ -3477,7 +3518,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>Lecture des résultats</translation> <translation>Lecture des résultats</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/translate.py" line="151"/> <location filename="../View/Results/translate.py" line="158"/>
<source>Water elevation</source> <source>Water elevation</source>
<translation>Cote de l'eau</translation> <translation>Cote de l'eau</translation>
</message> </message>
@ -3487,12 +3528,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>Cote maximum de l'eau</translation> <translation>Cote maximum de l'eau</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/translate.py" line="61"/> <location filename="../View/Results/translate.py" line="68"/>
<source>Reach name</source> <source>Reach name</source>
<translation>Nom du bief</translation> <translation>Nom du bief</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/translate.py" line="157"/> <location filename="../View/Results/translate.py" line="164"/>
<source>Profile</source> <source>Profile</source>
<translation>Profil</translation> <translation>Profil</translation>
</message> </message>
@ -3547,12 +3588,12 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation>Masse min</translation> <translation>Masse min</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/translate.py" line="65"/> <location filename="../View/Results/translate.py" line="72"/>
<source>Variables names</source> <source>Variables names</source>
<translation>Noms des variables</translation> <translation>Noms des variables</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/translate.py" line="78"/> <location filename="../View/Results/translate.py" line="85"/>
<source>Pollutant name</source> <source>Pollutant name</source>
<translation>Nom des polluants</translation> <translation>Nom des polluants</translation>
</message> </message>
@ -3562,7 +3603,7 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<translation type="obsolete">enveloppe</translation> <translation type="obsolete">enveloppe</translation>
</message> </message>
<message> <message>
<location filename="../View/Results/translate.py" line="69"/> <location filename="../View/Results/translate.py" line="76"/>
<source>Profile name</source> <source>Profile name</source>
<translation>Nom du profil</translation> <translation>Nom du profil</translation>
</message> </message>
@ -3591,6 +3632,16 @@ Cette fonctionnalité nécessite un bief muni d'une géométrie.</translation>
<source>All files (*)</source> <source>All files (*)</source>
<translation type="obsolete">Tous les fichiers (*)</translation> <translation type="obsolete">Tous les fichiers (*)</translation>
</message> </message>
<message>
<location filename="../View/Results/translate.py" line="59"/>
<source>An error occured when writing to file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="62"/>
<source>If the file is in use, close it and try again</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Scenarios</name> <name>Scenarios</name>