merge master

This commit is contained in:
Theophile Terraz committed 2025-01-27 09:35:08 +01:00
commit c3d732b426
106 files changed
+61703 -430

No files matched your search

BIN
View File
Binary file not shown.
+1 -1
View File
@@ -410,7 +410,7 @@ class MeshingWithMageMailleurTT(AMeshingTool):
str,
[
st_file, m_file,
"update_rk", step,
"update_kp", step,
limites[0], limites[1],
directrices[0], directrices[1],
orientation, lm, linear, origin, origin_value
+97 -13
View File
@@ -20,6 +20,7 @@ import logging
import numpy as np
from typing import List
from functools import reduce
from dataclasses import dataclass
from tools import timer
from shapely import geometry
@@ -33,6 +34,13 @@ from Model.Geometry.Vector_1d import Vector1d
logger = logging.getLogger()
@dataclass
class Tabulation:
z: np.array([])
A: np.array([])
L: np.array([])
class ProfileXYZ(Profile, SQLSubModel):
_sub_classes = [
PointXYZ,
@@ -70,6 +78,14 @@ class ProfileXYZ(Profile, SQLSubModel):
status=status,
)
self.tab = Tabulation([], [], [])
self.tab_up_to_date = False
self.time_z = 0.0
self.time_A = 0.0
self.time_l = 0.0
self._station = []
self.station_up_to_date = False
@classmethod
def _db_create(cls, execute):
execute("""
@@ -305,6 +321,8 @@ class ProfileXYZ(Profile, SQLSubModel):
pt = PointXYZ(*point, profile=self, status=self._status)
self.points.append(pt)
self._status.modified()
self.tab_up_to_date = False
self.station_up_to_date = False
def get_point_i(self, index: int) -> PointXYZ:
"""Get point at index.
@@ -366,6 +384,8 @@ class ProfileXYZ(Profile, SQLSubModel):
point_xyz = PointXYZ(0., 0., 0., profile=self, status=self._status)
self.points.append(point_xyz)
self._status.modified()
self.tab_up_to_date = False
self.station_up_to_date = False
def insert(self, index: int):
"""Insert a new point at index.
@@ -379,6 +399,8 @@ class ProfileXYZ(Profile, SQLSubModel):
point = PointXYZ(0., 0., 0., profile=self, status=self._status)
self.points.insert(index, point)
self._status.modified()
self.tab_up_to_date = False
self.station_up_to_date = False
return point
def filter_isnan(self, lst):
@@ -410,7 +432,7 @@ class ProfileXYZ(Profile, SQLSubModel):
return abs(rg.dist(rd))
def wet_width(self, z):
def compute_wet_width(self, z):
start, end = self.get_all_water_limits_ac(z)
if len(start) == 0:
@@ -421,6 +443,17 @@ class ProfileXYZ(Profile, SQLSubModel):
length += abs(s - e)
return length
def wet_width(self, z):
if self.tab_up_to_date:
if z > self.tab.z[-1]:
return self.tab.L[-1]
elif z < self.tab.z[0]:
return 0.0
else:
return np.interp(z, self.tab.z, self.tab.L)
else:
return self.compute_wet_width(z)
def wet_perimeter(self, z):
lines = self.wet_lines(z)
@@ -432,17 +465,46 @@ class ProfileXYZ(Profile, SQLSubModel):
length += line.length
return length
def wet_area(self, z):
lines = self.wet_lines(z)
if lines is None:
return 0
def compute_wet_area(self, z):
area = 0.0
for line in lines:
if len(line.coords) > 2:
poly = geometry.Polygon(line)
area += poly.area
if len(self.tab.L) > 0:
if z < self.tab.z[0]:
return 0.0
i = np.searchsorted([z], self.tab.z, side='right')[0]
for j in range(i-1):
area += (self.tab.L[j] + self.tab.L[j+1]) * (
self.tab.z[j+1] - self.tab.z[j]) / 2.0
area += (self.tab.L[i-1] + self.wet_width(z))
else:
lines = self.wet_lines(z)
if lines is None:
return 0.0
for line in lines:
if len(line.coords) > 2:
poly = geometry.Polygon(line)
area += poly.area
return area
def wet_area(self, z):
if self.tab_up_to_date:
if z > self.tab.z[-1]:
return self.tab.A[-1] + self.tab.L[-1] * (z - self.tab.z[-1])
elif z < self.tab.z[0]:
return 0.0
else:
return np.interp(z, self.tab.z, self.tab.A)
else:
lines = self.wet_lines(z)
if lines is None:
return 0.0
area = 0.0
for line in lines:
if len(line.coords) > 2:
poly = geometry.Polygon(line)
area += poly.area
return area
def wet_radius(self, z):
@@ -563,7 +625,7 @@ class ProfileXYZ(Profile, SQLSubModel):
return None
zz = list(map(lambda p: p.z, points))
station = self._get_station(points)
station = self.get_station()
start = []
if points[0].z <= z:
@@ -651,6 +713,19 @@ class ProfileXYZ(Profile, SQLSubModel):
return pt_left, pt_right
def compute_tabulation(self):
sorted_points = sorted(self._points, key=lambda p: p.z)
self.tab.z = np.array([p.z for p in sorted_points], np.float64)
self.tab.L = np.zeros(len(self.tab.z), np.float64)
self.tab.A = np.zeros(len(self.tab.z), np.float64)
for i in range(1, len(self.tab.z)):
self.tab.L[i] = self.compute_wet_width(self.tab.z[i])
dx = (self.tab.L[i] + self.tab.L[i-1])/2
dz = self.tab.z[i] - self.tab.z[i-1]
self.tab.A[i] = self.tab.A[i-1] + dz * dx
self.tab_up_to_date = True
def get_station(self):
"""Projection of the points of the profile on a plane.
@@ -663,7 +738,12 @@ class ProfileXYZ(Profile, SQLSubModel):
if self.nb_points < 2:
return [0.0]
else:
return self._get_station(self.points)
if self.station_up_to_date:
return self._station
else:
self._station = self._get_station(self.points)
self.station_up_to_date = True
return self._station
@timer
def _get_station(self, points):
@@ -799,3 +879,7 @@ class ProfileXYZ(Profile, SQLSubModel):
p.x = p.x + x
p.y = p.y + y
p.z = p.z + z
def modified(self):
self.tab_up_to_date = False
self.station_up_to_date = False
+15 -1
View File
@@ -128,7 +128,7 @@ class Pollutants(SQLSubModel):
if table is not None:
for t in table:
new_data = t[1:]
new_data = t[1:-1]
new_pollutant._data.append(new_data)
@@ -177,5 +177,19 @@ class Pollutants(SQLSubModel):
def is_define(self):
return len(self._data) != 0
def new_from_data(self, data):
print("from_data before : ", data)
try:
new = [int(data[0])]
new += [float(d) for d in data[1:]]
except Exception as e:
logger.error(e)
new = None
print("from_data after : ", new)
return new
def __len__(self):
return len(self._data)
+3
View File
@@ -46,6 +46,9 @@ class Results(object):
el.split("/")[-1][0:-4]
for el in glob.glob(repertory_results + "/*.bin")
]
self._pollutants_list.insert(0, self._pollutants_list.pop(
self._pollutants_list.index("total_sediment"))
)
self._phys_var_list = ["C", "G", "M", "D", "L", "N", "R"]
+37 -24
View File
@@ -410,10 +410,16 @@ class AdisTSwc(AdisTS):
def _export_ICs_AdisTS_Spec(self, study, pol_ics_spec_data,
f, qlog, name="0"):
edges = study.river.enable_edges()
for ic_spec in pol_ics_spec_data:
id_reach = ic_spec.reach
reach = next((x for x in edges if x.id == id_reach), None)
if reach is None:
continue
f.write(" ".join((f"{ic_spec.name}",
"=",
f"{ic_spec.reach}",
f"{study.river.get_edge_id(reach)+1}",
f"{ic_spec.start_rk}",
f"{ic_spec.end_rk}",
f"{ic_spec.concentration}",
@@ -429,7 +435,7 @@ class AdisTSwc(AdisTS):
list_characteristics = ["type", "diametre", "rho", "porosity",
"cdc_riv", "cdc_cas", "apd", "ac", "bc"]
if len(list_characteristics) == (len(pol_data[0])-1):
if len(list_characteristics) <= (len(pol_data[0])):
for i in range(len(list_characteristics)):
f.write(f"{list_characteristics[i]} = {pol_data[0][i]}\n")
@@ -470,13 +476,14 @@ class AdisTSwc(AdisTS):
id_edges = list(map(lambda x: x.id, edges))
id_reach = d90_spec.reach
reach = next((x for x in edges if x.id == id_reach), None)
if id_reach not in id_edges:
if reach is None:
return
f.write(" ".join((f"{d90_spec.name}",
"=",
f"{id_reach}",
f"{study.river.get_edge_id(reach)+1}",
f"{d90_spec.start_rk}",
f"{d90_spec.end_rk}",
f"{d90_spec.d90}\n")))
@@ -526,23 +533,22 @@ class AdisTSwc(AdisTS):
edges = study.river.enable_edges()
id_edges = list(map(lambda x: x.id, edges))
id_reach = dif_spec.reach
reach = next((x for x in edges if x.id == id_reach), None)
if id_reach not in id_edges:
if reach is None:
return
if dif_spec.method != "generique":
f.write(" ".join((f"{dif_spec.method}",
"=",
f"{id_reach}",
f"{study.river.get_edge_id(reach)+1}",
f"{dif_spec.start_rk}",
f"{dif_spec.end_rk}",
f"{dif_spec.dif}\n")))
else:
f.write(" ".join((f"{dif_spec.method}",
f"=" f"{id_reach}",
f"=" f"{study.river.get_edge_id(reach)+1}",
f"{dif_spec.start_rk}",
f"{dif_spec.end_rk}",
f"{dif_spec.dif}",
@@ -602,27 +608,30 @@ class AdisTSwc(AdisTS):
id_edges = list(map(lambda x: x.id, edges))
id_reach = outputrk.reach
reach = next((x for x in edges if x.id == id_reach), None)
rk = outputrk.rk
title = outputrk.title
if id_reach not in id_edges:
if reach is None:
return
f.write(f"output = {id_reach} {rk} {title}\n")
f.write(f"output = {study.river.get_edge_id(reach)+1} {rk} {title}\n")
@timer
def read_bin(self, study, repertory, results, qlog=None, name="0"):
repertory_results = os.path.join(repertory, "resultats")
files_bin_names = [el.split("/")[-1]
for el in glob.glob(repertory_results+"/*.bin")]
print("files names resultats: ", files_bin_names)
files_bin_names.insert(0, files_bin_names.pop(
files_bin_names.index("total_sediment.bin"))
)
ifilename = os.path.join(repertory_results, files_bin_names[0])
logger.info(f"read_bin: Start reading '{ifilename}' ...")
print("reading ", ifilename)
with open(ifilename, 'rb') as f:
# header
# first line
@@ -641,7 +650,6 @@ class AdisTSwc(AdisTS):
data = np.fromfile(f, dtype=np.int32, count=2 * ibmax)
is1 = np.zeros(ibmax, dtype=np.int32)
is2 = np.zeros(ibmax, dtype=np.int32)
print("nombre de biefs : ", ibmax)
logger.debug(f"read_bin: nb_reach = {ibmax}")
logger.debug(f"read_bin: nb_profile = {ismax}")
@@ -803,15 +811,6 @@ class AdisTSwc(AdisTS):
[timestamps_keys[0]].keys())
type_pol_index = len(phys_data_names)
# ##print("pol keys: ", pollutants_keys)
# ##print("t keys: ", timestamps_keys)
# ##print("phys var: ", phys_data_names)
# ##print("phys data names mass zero:",
# list(data_tmp[pollutants_keys[1]][timestamps_keys[0]].keys()))
# print("set timestamps keys: ", set(timestamps_keys))
# print("isma")
# ##print("iprofiles: ", iprofiles)
for r, reach in enumerate(reachs):
for i in range(is1[r]-1, is2[r]):
p_i = ip_to_ri(reach, i)
@@ -851,15 +850,29 @@ class AdisTSwc(AdisTS):
self._export_POLs,
]
def rm_previous_results(self, study, repertory, qlog):
if "resultats" not in os.listdir(repertory):
return
repertory_results = os.path.join(repertory, "resultats")
files_bin_names = [el.split("/")[-1]
for el in glob.glob(repertory_results+"/*.bin")]
for el in glob.glob(repertory_results+"/*.bin"):
os.remove(el)
@timer
def export(self, study, repertory, mage_rep, qlog=None, name="0"):
print("cmd solver adistswc : ", self._cmd_solver)
logger.debug(f"cmd solver adistswc : {self._cmd_solver}")
self._study = study
name = study.name.replace(" ", "_")
# Generate files
files = []
self.rm_previous_results(study, repertory, qlog)
try:
for func in self.export_func_dict():
files = files + func(study, repertory, qlog, name=name)
+17 -4
View File
@@ -1001,7 +1001,6 @@ class Mage8(Mage):
# Add profile id correspondance to reach
key = (i1, i2)
print("mage keys reachs: ", key)
iprofiles[key] = r
# Profile ID offset
@@ -1034,8 +1033,6 @@ class Mage8(Mage):
]
def ip_to_ri(r, i): return i - reach_offset[r]
print("mage iprofiles: ", iprofiles)
ts = set()
end = False
while not end:
@@ -1071,7 +1068,23 @@ class Mage8(Mage):
logger.debug(reachs[0].profiles[0]._data)
results.set("timestamps", ts)
print("set timestamps mage: ", ts)
ts_list = sorted(ts)
logger.info(f"compute tab...")
for r in reachs:
for p in r.profiles:
if not p.geometry.tab_up_to_date:
p.geometry.compute_tabulation()
logger.info(f"compute velocily...")
for r in reachs:
for t in ts_list:
for i, p in enumerate(r.profiles):
v = p.geometry.speed(
p.get_ts_key(t, "Q"),
p.get_ts_key(t, "Z")
)
r.set(i, t, "V", v)
logger.info(f"read_bin: ... end with {len(ts)} timestamp read")
@timer
+1 -1
View File
@@ -55,7 +55,7 @@ class AboutWindow(PamhyrDialog):
label = self.get_label_text("label_version")
label = label.replace("@version", version)
label = label.replace("@codename", "(Tahiti)")
label = label.replace("@codename", "(Adis-TS)")
self.set_label_text("label_version", label)
# Authors
@@ -88,13 +88,13 @@ class EditBoundaryConditionWindow(PamhyrWindow):
self.setup_connections()
def setup_table(self):
table_headers = self._trad.get_dict("table_headers")
if self._data.type == "Concentration":
self._data.header = ["time", "concentration"]
else:
self._data.header = ["time", "rate"]
self._data.header = ["time", "mass"]
headers = {}
table_headers = self._trad.get_dict("table_headers")
for h in self._data.header:
headers[h] = table_headers[h]
@@ -30,13 +30,13 @@ class BCETranslate(BCTranslate):
super(BCETranslate, self).__init__()
self._dict["Edit Boundary Conditions AdisTS"] = _translate(
"BoundaryConditionAdisTS", "Edit boundary conditions AdisTS"
"BoundaryConditionsAdisTS", "Edit boundary conditions AdisTS"
)
self._sub_dict["table_headers"] = {
"time": self._dict["time"],
"date": self._dict["date"],
"rate": _translate("BoundaryConditionAdisTS", "Rate"),
"concentration": _translate("BoundaryConditionAdisTS",
"mass": _translate("BoundaryConditionsAdisTS", "Mass"),
"concentration": _translate("BoundaryConditionsAdisTS",
"Concentration"),
}
+24 -10
View File
@@ -70,7 +70,7 @@ class ComboBoxDelegate(QItemDelegate):
self.editor = QComboBox(parent)
if self._mode == "type":
lst = [self._trad["not_associated"], "Concentration", "Rate"]
lst = [self._trad["not_associated"], "Concentration", "Mass"]
self.editor.addItems(
lst
)
@@ -146,8 +146,7 @@ class TableModel(PamhyrTableModel):
n = data[row].node
if n is None:
return self._trad["not_associated"]
tmp = next(filter(lambda x: x.id == n, self._data._nodes),
None)
tmp = next(filter(lambda x: x.id == n, self._data._nodes), None)
if tmp is not None:
return tmp.name
else:
@@ -156,7 +155,14 @@ class TableModel(PamhyrTableModel):
n = data[row].pollutant
if n is None or n == "not_associated" or n == "":
return self._trad["not_associated"]
return self._data._Pollutants.Pollutants_List[n].name
tmp = next(filter(lambda x: x.id == n,
self._data._Pollutants.Pollutants_List
),
None)
if tmp is not None:
return tmp.name
else:
return self._trad["not_associated"]
return QVariant()
@@ -181,13 +187,21 @@ class TableModel(PamhyrTableModel):
)
)
elif self._headers[column] == "pol":
pol = next(filter(lambda x: x.name == value,
self._data._Pollutants.Pollutants_List))
self._undo.push(
SetPolCommand(
self._lst, row, pol.id
if value == self._trad["not_associated"]:
self._undo.push(
SetPolCommand(
self._lst, row, None
)
)
else:
pol = next(filter(lambda x: x.name == value,
self._data._Pollutants.Pollutants_List)
)
self._undo.push(
SetPolCommand(
self._lst, row, pol.id
)
)
)
except Exception as e:
logger.info(e)
logger.debug(traceback.format_exc())
@@ -68,9 +68,8 @@ class SetPolCommand(QUndoCommand):
self._bcs = bcs
self._index = index
self._pollutant = pollutant
self._old = self._bcs[self._index].pollutant
self._new = self._pollutant
self._new = pollutant
def undo(self):
self._bcs[self._index].pollutant = self._old
+1 -6
View File
@@ -74,7 +74,6 @@ class BoundaryConditionAdisTSWindow(PamhyrWindow):
)
self._pollutants_lst = self._study._river._Pollutants
self._bcs = self._study.river.boundary_conditions_adists
self.setup_graph()
@@ -157,11 +156,7 @@ class BoundaryConditionAdisTSWindow(PamhyrWindow):
)
def add(self):
rows = self.index_selected_rows()
if len(self._bcs) == 0 or len(rows) == 0:
self._table.add(0)
else:
self._table.add(rows[0])
self._table.add(len(self._bcs))
def delete(self):
rows = self.index_selected_rows()
-1
View File
@@ -187,7 +187,6 @@ class DIFTableModel(PamhyrTableModel):
)
)
elif self._headers[column] == "reach":
print(self._river.edge(value).id)
self._undo.push(
SetCommandSpec(
self._lst,
-2
View File
@@ -287,9 +287,7 @@ class DIFAdisTSWindow(PamhyrWindow):
self._table_spec.add(rows[0])
def delete(self):
print("del")
rows = self.index_selected_rows()
if len(rows) == 0:
print("len 0")
return
self._table_spec.delete(rows)
+52 -83
View File
@@ -66,11 +66,9 @@ class Plot(PamhyrPlot):
self._isometric_axis = False
self.hl_points = []
self.highlight = (
[], # Points list to highlight
None # Hydrolic values (z, wet_area,
# wet_preimeter, water_width)
)
self.highlight = None # (z, wet_area, wet_preimeter, water_width)
self._colors = []
self._onpickevent = None
self._rect_select = RectangleSelector(
ax=self.canvas.axes,
@@ -87,36 +85,25 @@ class Plot(PamhyrPlot):
# we need to do that to prevent conflicst
# between onpick and rect_select_callback
modifiers = QApplication.keyboardModifiers()
points, hyd = self.highlight
if self._onpickevent is not None:
ind, point = self._closest_point(self._onpickevent)
if modifiers == Qt.ControlModifier:
rows = self._parent.index_selected_rows()
if ind in rows:
rows.remove(ind)
del (points[ind])
self.highlight = (points, hyd)
self._select_in_table(rows)
else:
self.highlight = (points+[point], hyd)
self._select_in_table(rows+[ind])
elif modifiers == Qt.ShiftModifier:
rows = self._parent.index_selected_rows()
if len(rows) > 0:
i1 = min(rows[0], rows[-1], ind)
i2 = max(rows[0], rows[-1], ind)
p = [
[self.data.points[i].x, self.data.points[i].y]
for i in range(i1, i2)
]
else:
i1 = ind
i2 = ind
p = [point]
self.highlight = (p, hyd)
self._select_range_in_table(i1, i2)
else:
self.highlight = ([point], hyd)
self._select_in_table([ind])
self._onpickevent = None
@@ -142,41 +129,26 @@ class Plot(PamhyrPlot):
if event.button.value == 1:
return
points, _ = self.highlight
z = self._get_z_from_click(event)
if z < self.data.z_min() or event.button.value == 2:
self.highlight = (points, None)
self.update()
self.highlight = None
self.draw_highligth()
self.update_idle()
return
a, p, w = self._compute_hydraulics(z)
logger.debug(f"{z, a, p, w}")
self.highlight = (points, (z, a, p, w))
self.highlight = (z, a, p, w)
self.update()
self.draw_highligth()
self.update_idle()
return
def select_points_from_indices(self, indices):
data = self.data
_, hyd = self.highlight
points = list(
map(
lambda e: e[1],
filter(
lambda e: e[0] in indices,
enumerate(
zip(data.get_station(), data.z())
)
)
)
)
self.highlight = (points, hyd)
self.update()
self.draw_highligth()
# self.update()
def _select_in_table(self, ind):
if self._table is not None:
@@ -224,11 +196,6 @@ class Plot(PamhyrPlot):
x = event.artist.get_xdata()
y = event.artist.get_ydata()
# points = filter(
# lambda e: e[0] in points_ind,
# enumerate(zip(x, y))
# )
points = enumerate(zip(x, y))
mx = event.mouseevent.xdata
@@ -250,7 +217,7 @@ class Plot(PamhyrPlot):
def rect_select_callback(self, eclick, erelease):
points, hyd = self.highlight
hyd = self.highlight
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata
@@ -268,14 +235,13 @@ class Plot(PamhyrPlot):
if all(i in rows for i in inds):
for ind in sorted(inds, reverse=True):
rows.remove(ind)
del (points[ind])
self.highlight = (points, hyd)
self.highlight = hyd
self._select_in_table(rows)
else:
self.highlight = (points+points2, hyd)
self.highlight = hyd
self._select_in_table(rows+inds)
else:
self.highlight = (points2, hyd)
self.highlight = hyd
self._select_in_table(inds)
return
@@ -319,13 +285,16 @@ class Plot(PamhyrPlot):
picker=10
)
self.draw_annotation(x, y)
self.draw_annotation()
self.highlight = None
self.draw_highligth()
self.idle()
def draw_annotation(self, x, y):
def draw_annotation(self):
gl = map(lambda p: p.name, self.data.points)
x = self.data.get_station()
y = self.data.z()
# Add label on graph
self.annotation = []
@@ -363,16 +332,18 @@ class Plot(PamhyrPlot):
self.canvas.figure.patch.set_facecolor('white')
def draw_highligth(self):
points, hyd = self.highlight
hyd = self.highlight
for p in self.hl_points:
p[0].set_data([], [])
self.hl_points = []
x = self.data.get_station()
y = self.data.z()
for x, y in points:
for i in self._parent.index_selected_rows():
self.hl_points.append(
self.canvas.axes.plot(
x, y,
x[i], y[i],
color=self.color_plot_highlight,
lw=1.5, markersize=7, marker='+',
)
@@ -383,8 +354,9 @@ class Plot(PamhyrPlot):
else:
if self._z_note is not None:
self._z_note.set_visible(False)
self._z_line[0].set_visible(False)
self._z_line.set_visible(False)
self._z_fill_between.set_visible(False)
self.idle()
def draw_highligth_z_line(self, z, a, p, w):
text = (
@@ -396,40 +368,37 @@ class Plot(PamhyrPlot):
x = self.data.get_station()
xlim = (x[0], x[-1])
ylim = self.canvas.axes.get_ylim()
pos = (
xlim[0] + (abs(xlim[0] - xlim[1]) * 0.05),
z + 0.8
z + + (abs(ylim[0] - ylim[1]) * 0.08)
)
y = self.data.z()
if self._z_note is None:
self.draw_highligth_z_line_fill(x, y, z)
if self._z_note is not None:
self._z_note.remove()
if self._z_line is not None:
self._z_line.remove()
self.draw_highligth_z_line_fill(x, y, z)
self._z_line = self.canvas.axes.plot(
xlim, [z, z],
color=self.color_plot_river_water
)
self._z_line[0].set_visible(True)
self._z_line, = self.canvas.axes.plot(
xlim, [z, z],
color=self.color_plot_river_water
)
self._z_line.set_visible(True)
self._z_fill_between.set_visible(True)
self._z_note = self.canvas.axes.annotate(
text, pos,
horizontalalignment='left',
verticalalignment='top',
annotation_clip=True,
color=self.color_plot_river_water,
fontsize=9,
fontweight='bold',
alpha=0.7
)
self._z_note.set_visible(True)
else:
self.draw_highligth_z_line_fill(x, y, z)
self._z_line[0].set_data(xlim, [z, z])
self._z_note.set_position(pos)
self._z_note.set_text(text)
self._z_line[0].set_visible(True)
self._z_note.set_visible(True)
self._z_note = self.canvas.axes.annotate(
text, pos,
horizontalalignment='left',
verticalalignment='top',
annotation_clip=True,
color=self.color_plot_river_water,
fontsize=9,
fontweight='bold',
alpha=0.7
)
self._z_note.set_visible(True)
def draw_highligth_z_line_fill(self, x, y, z):
if self._z_fill_between is not None:
@@ -444,6 +413,6 @@ class Plot(PamhyrPlot):
@timer
def update(self):
self.draw_highligth()
self.draw()
self.update_idle()
+20
View File
@@ -42,9 +42,11 @@ class SetXCommand(SetDataCommand):
def undo(self):
self._profile.point(self._index).x = self._old
self._profile.modified()
def redo(self):
self._profile.point(self._index).x = self._new
self._profile.modified()
class SetYCommand(SetDataCommand):
@@ -54,9 +56,11 @@ class SetYCommand(SetDataCommand):
def undo(self):
self._profile.point(self._index).y = self._old
self._profile.modified()
def redo(self):
self._profile.point(self._index).y = self._new
self._profile.modified()
class SetZCommand(SetDataCommand):
@@ -66,9 +70,11 @@ class SetZCommand(SetDataCommand):
def undo(self):
self._profile.point(self._index).z = self._old
self._profile.modified()
def redo(self):
self._profile.point(self._index).z = self._new
self._profile.modified()
class SetNameCommand(SetDataCommand):
@@ -94,12 +100,14 @@ class AddCommand(QUndoCommand):
def undo(self):
self._profile.delete_i([self._index])
self._profile.modified()
def redo(self):
if self._point is None:
self._point = self._profile.insert(self._index)
else:
self._profile.insert_point(self._index, self._point)
self._profile.modified()
class DelCommand(QUndoCommand):
@@ -117,9 +125,11 @@ class DelCommand(QUndoCommand):
def undo(self):
for row, point in self._points:
self._profile.insert_point(row, point)
self._profile.modified()
def redo(self):
self._profile.delete_i(self._rows)
self._profile.modified()
class SortCommand(QUndoCommand):
@@ -143,9 +153,11 @@ class SortCommand(QUndoCommand):
def undo(self):
self._profile.sort_with_indexes(self._indexes)
self._profile.modified()
def redo(self):
self._profile.sort(self._column, self._reverse)
self._profile.modified()
class MoveCommand(QUndoCommand):
@@ -161,12 +173,14 @@ class MoveCommand(QUndoCommand):
self._profile.move_up_point(self._i)
else:
self._profile.move_down_point(self._i)
self._profile.modified()
def redo(self):
if self._up:
self._profile.move_up_point(self._i)
else:
self._profile.move_down_point(self._i)
self._profile.modified()
class ReverseCommand(QUndoCommand):
@@ -177,9 +191,11 @@ class ReverseCommand(QUndoCommand):
def undo(self):
self._profile.reverse()
self._profile.modified()
def redo(self):
self._profile.reverse()
self._profile.modified()
class PurgeCommand(QUndoCommand):
@@ -192,9 +208,11 @@ class PurgeCommand(QUndoCommand):
def undo(self):
self._profile._points = self._old.copy()
self._profile.modified()
def redo(self):
self._profile.purge(self._np_purge)
self._profile.modified()
class PasteCommand(QUndoCommand):
@@ -210,7 +228,9 @@ class PasteCommand(QUndoCommand):
def undo(self):
for ind in range(len(self._points)):
self._profile.delete_i([self._row])
self._profile.modified()
def redo(self):
for point in self._points:
self._profile.insert_point(self._row, point)
self._profile.modified()
+1 -1
View File
@@ -63,7 +63,7 @@ class ComboBoxDelegate(QItemDelegate):
reach_id = self._ic_spec_lst[index.row()].reach
reach = next(filter(lambda edge: edge.id == reach_id,
self._data.edges()))
self._data.edges()), None)
if reach_id is not None:
val = list(
@@ -28,7 +28,7 @@ class LCTranslate(MainTranslate):
super(LCTranslate, self).__init__()
self._dict["Lateral contribution AdisTS"] = _translate(
"LateralContribution1adisTS", "Lateral contribution AdisTS"
"LateralContributionAdisTS", "Lateral contribution AdisTS"
)
self._sub_dict["long_types"] = {
+2 -2
View File
@@ -194,10 +194,10 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
title = "(dbg) " if self.conf.debug else ""
if self._study is not None:
title += f"Pamhyr2 (Tahiti 🌴) - {self._study.name}"
title += f"Pamhyr2 - {self._study.name}"
self.setWindowTitle(title)
else:
title += "Pamhyr2 (Tahiti 🌴)"
title += "Pamhyr2"
self.setWindowTitle(title)
def setup_tab(self):
+7 -10
View File
@@ -90,17 +90,14 @@ class TableModel(PamhyrTableModel):
self.layoutAboutToBeChanged.emit()
self._undo.push(
PasteCommand(
self._data, row,
list(
map(
lambda d: self._data.new_from_data(d),
data
)
)
self._undo.push(PasteCommand(self._data, row,
list(
map(
lambda d: self._data.new_from_data(d),
data
)
)
)
)
self.layoutAboutToBeChanged.emit()
self.layoutChanged.emit()
+1 -1
View File
@@ -35,7 +35,7 @@ class EditPollutantTranslate(PollutantsTranslate):
self._sub_dict["table_headers"] = {
"type": self._dict["type"],
"diametre": self._dict["unit_area"],
"diameter": self._dict["unit_diameter"],
"rho": self._dict["unit_rho"],
"porosity": self._dict["unit_porosity"],
"cdc_riv": self._dict["unit_cdc_riv"],
+24 -25
View File
@@ -31,36 +31,35 @@ logger = logging.getLogger()
class SetDataCommand(QUndoCommand):
def __init__(self, data, index, column, new_value):
QUndoCommand.__init__(self)
self._data = data
self._index = index
self._column = column
self._old = self._data.data[self._index][self._column]
self._new = new_value
def undo(self):
self._data.data[self._index][self._column] = self._old
def redo(self):
self._data.data[self._index][self._column] = self._new
class PasteCommand(QUndoCommand):
def __init__(self, data, row, hs):
def __init__(self, data, row, column, new_value):
QUndoCommand.__init__(self)
self._data = data
self._row = row
self._h = hs
self._h.reverse()
self._column = column
self._old = self._data.data[self._row][self._column]
self._new = new_value
def undo(self):
self._data.delete_i(
range(self._row, self._row + len(self._h))
)
self._data.data[self._row][self._column] = self._old
def redo(self):
for h in self._h:
self._data.insert(self._row, h)
self._data.data[self._row][self._column] = self._new
class PasteCommand(QUndoCommand):
def __init__(self, data, row, new_data):
QUndoCommand.__init__(self)
self._data = data
self._row = row
self._new = [n for n in new_data[row]]
self._old = [o for o in self._data.data[row]]
def undo(self):
for i in range(9):
self._data.data[self._row][i] = self._old[i]
def redo(self):
for i in range(9):
self._data.data[self._row][i] = self._new[i]
+1 -1
View File
@@ -129,7 +129,7 @@ class EditPolluantWindow(PamhyrWindow):
def _paste(self):
header, data = self.parseClipboardTable()
logger.debug(f"paste: h:{header}, d:{data}")
logger.debug(f"paste: header:{header}, data:{data}")
if len(data) == 0:
return
+1 -1
View File
@@ -103,7 +103,7 @@ class TableModel(PamhyrTableModel):
self._undo.push(
DelCommand(
self._lst, rows, self._data.initial_conditions_adists
self._lst, rows, self._data.ic_adists
)
)
+3 -1
View File
@@ -101,7 +101,9 @@ class DelCommand(QUndoCommand):
for row in rows:
self._pollutants.append((row, self._pollutants_lst.get(row)))
self._inc_pollutants.append((row, self._inc_pollutants_lst))
self._inc_pollutants.append(
(row, self._inc_pollutants_lst.get(row))
)
self._pollutants.sort()
self._inc_pollutants.sort()
+12 -13
View File
@@ -154,11 +154,7 @@ class PollutantsWindow(PamhyrWindow):
)
def add(self):
rows = self.index_selected_rows()
if len(self._pollutants_lst) == 0 or len(rows) == 0:
self._table.add(0)
else:
self._table.add(rows[-1])
self._table.add(len(self._pollutants_lst))
def delete(self):
rows = self.index_selected_rows()
@@ -181,6 +177,9 @@ class PollutantsWindow(PamhyrWindow):
def edit(self):
rows = self.index_selected_rows()
if len(rows) == 0:
return
for row in rows:
data = self._pollutants_lst.get(row)
@@ -199,12 +198,15 @@ class PollutantsWindow(PamhyrWindow):
def initial_conditions(self):
rows = self.index_selected_rows()
if len(rows) == 0:
return
for row in rows:
pollutant_id = self._pollutants_lst.get(row).id
iclist = self._study.river.ic_adists.Initial_Conditions_List
ics_adists = next(filter(lambda x: x.pollutant == pollutant_id,
self._study.river.ic_adists.lst))
iclist))
if self.sub_window_exists(
InitialConditionsAdisTSWindow,
@@ -219,11 +221,7 @@ class PollutantsWindow(PamhyrWindow):
)
initial.show()
def boundary_conditions(self, tab=0):
rows = self.index_selected_rows()
for row in rows:
pollutant_id = self._pollutants_lst.get(row).id
def boundary_conditions(self):
if self.sub_window_exists(
BoundaryConditionAdisTSWindow,
@@ -242,9 +240,10 @@ class PollutantsWindow(PamhyrWindow):
def lateral_contrib(self):
rows = self.index_selected_rows()
if len(rows) == 0:
return
for row in rows:
pollutant_id = self._pollutants_lst.get(row).id
pollutant_id = self._pollutants_lst.get(rows[0]).id
if self.sub_window_exists(
LateralContributionAdisTSWindow,
@@ -66,7 +66,7 @@ class CustomPlotValuesSelectionDialog(PamhyrDialog):
self._envelop = []
layout = self.find(QVBoxLayout, "verticalLayout_x")
self._envelop = QCheckBox(
"envelop",
self._trad["envelop"],
parent=self
)
layout.addWidget(self._envelop)
+27 -47
View File
@@ -188,6 +188,12 @@ class CustomPlot(PamhyrPlot):
reach.profiles
)
)
v = list(
map(
lambda p: p.get_ts_key(self._timestamp, "V"),
reach.profiles
)
)
shift = 0
compt = 0
@@ -328,14 +334,6 @@ class CustomPlot(PamhyrPlot):
if "velocity" in self._y:
ax = self._axes[unit["velocity"]]
v = list(
map(
lambda p: p.geometry.speed(
p.get_ts_key(self._timestamp, "Q"),
p.get_ts_key(self._timestamp, "Z")),
reach.profiles
)
)
line = ax.plot(
rk, v, lw=1.,
@@ -345,12 +343,10 @@ class CustomPlot(PamhyrPlot):
if self._envelop:
velocities = list(map(
lambda p: list(map(
lambda q, z:
p.geometry.speed(q, z),
p.get_key("Q"), p.get_key("Z")
)), reach.profiles
velocities = list(
map(
lambda p: p.get_key("V"),
reach.profiles
)
)
@@ -441,9 +437,7 @@ class CustomPlot(PamhyrPlot):
fr = list(
map(
lambda p:
p.geometry.speed(
p.get_ts_key(self._timestamp, "Q"),
p.get_ts_key(self._timestamp, "Z")) /
p.get_ts_key(self._timestamp, "V") /
sqrt(9.81 * (
p.geometry.wet_area(
p.get_ts_key(self._timestamp, "Z")) /
@@ -507,6 +501,12 @@ class CustomPlot(PamhyrPlot):
reach.profiles
)
)
v = list(
map(
lambda p: p.get_ts_key(self._timestamp, "V"),
reach.profiles
)
)
if "bed_elevation" in self._y:
self.lines["bed_elevation"][0].set_ydata(z_min)
@@ -525,15 +525,7 @@ class CustomPlot(PamhyrPlot):
self.lines["discharge"][0].set_ydata(q)
if "velocity" in self._y:
v = list(
map(
lambda p: p.geometry.speed(
p.get_ts_key(self._timestamp, "Q"),
p.get_ts_key(self._timestamp, "Z")),
reach.profiles
)
)
self.lines["discharge"][0].set_ydata(v)
self.lines["velocity"][0].set_ydata(v)
if "depth" in self._y:
d = list(
@@ -559,9 +551,7 @@ class CustomPlot(PamhyrPlot):
fr = list(
map(
lambda p:
p.geometry.speed(
p.get_ts_key(self._timestamp, "Q"),
p.get_ts_key(self._timestamp, "Z")) /
p.get_ts_key(self._timestamp, "V") /
sqrt(9.81 * (
p.geometry.wet_area(
p.get_ts_key(self._timestamp, "Z")) /
@@ -643,6 +633,7 @@ class CustomPlot(PamhyrPlot):
q = profile.get_key("Q")
z = profile.get_key("Z")
v = profile.get_key("V")
z_min = profile.geometry.z_min()
if reach.has_sediment():
ts_z_min = self.get_ts_zmin(self._profile)
@@ -694,12 +685,6 @@ class CustomPlot(PamhyrPlot):
if "velocity" in self._y:
ax = self._axes[unit["velocity"]]
v = list(
map(
lambda q, z: profile.geometry.speed(q, z),
q, z
)
)
line = ax.plot(
ts, v, lw=1.,
@@ -737,12 +722,12 @@ class CustomPlot(PamhyrPlot):
ax = self._axes[unit["froude"]]
d = list(
map(lambda z, q:
profile.geometry.speed(q, z) /
map(lambda z, v:
v /
sqrt(9.81 * (
profile.geometry.wet_area(z) /
profile.geometry.wet_width(z))
), z, q)
), z, v)
)
line = ax.plot(
@@ -783,6 +768,7 @@ class CustomPlot(PamhyrPlot):
q = profile.get_key("Q")
z = profile.get_key("Z")
v = profile.get_key("V")
if reach.has_sediment():
ts_z_min = self.get_ts_zmin(self._profile)
else:
@@ -811,12 +797,6 @@ class CustomPlot(PamhyrPlot):
self.lines["discharge"][0].set_ydata(q)
if "velocity" in self._y:
v = list(
map(
lambda q, z: profile.geometry.speed(q, z),
q, z
)
)
self.lines["velocity"][0].set_ydata(v)
if "depth" in self._y:
@@ -833,12 +813,12 @@ class CustomPlot(PamhyrPlot):
if "froude" in self._y:
d = list(
map(lambda z, q:
profile.geometry.speed(q, z) /
map(lambda z, v:
v /
sqrt(9.81 * (
profile.geometry.wet_area(z) /
profile.geometry.wet_width(z))
), z, q)
), z, v)
)
self.lines["froude"][0].set_ydata(d)
+2 -2
View File
@@ -97,7 +97,7 @@ class TableModel(PamhyrTableModel):
elif self._headers[column] == "velocity":
q = self._lst[row].get_ts_key(self._timestamp, "Q")
z = self._lst[row].get_ts_key(self._timestamp, "Z")
v = self._lst[row].geometry.speed(q, z)
v = self._lst[row].get_ts_key(self._timestamp, "V")
return f"{v:.4f}"
elif self._headers[column] == "width":
z = self._lst[row].get_ts_key(self._timestamp, "Z")
@@ -126,7 +126,7 @@ class TableModel(PamhyrTableModel):
elif self._headers[column] == "froude":
q = self._lst[row].get_ts_key(self._timestamp, "Q")
z = self._lst[row].get_ts_key(self._timestamp, "Z")
v = self._lst[row].geometry.speed(q, z)
v = self._lst[row].get_ts_key(self._timestamp, "V")
a = self._lst[row].geometry.wet_area(z)
b = self._lst[row].geometry.wet_width(z)
if b == 0.0 or a == 0.0:
+10 -22
View File
@@ -781,21 +781,16 @@ class ResultsWindow(PamhyrWindow):
if "velocity" in y:
my_dict[dict_y["velocity"]] = list(
map(
lambda p: p.geometry.speed(
p.get_ts_key(timestamp, "Q"),
p.get_ts_key(timestamp, "Z")),
lambda p: p.get_ts_key(timestamp, "V"),
reach.profiles
)
)
if envelop:
velocities = list(map(
lambda p: list(map(
lambda q, z:
p.geometry.speed(q, z),
p.get_key("Q"), p.get_key("Z")
)), reach.profiles
lambda p: p.get_key("V"),
reach.profiles
)
)
)
my_dict[dict_y["min_velocity"]] = [min(v) for v in velocities]
my_dict[dict_y["max_velocity"]] = [max(v) for v in velocities]
@@ -835,9 +830,7 @@ class ResultsWindow(PamhyrWindow):
my_dict[dict_y["froude"]] = list(
map(
lambda p:
p.geometry.speed(
p.get_ts_key(timestamp, "Q"),
p.get_ts_key(timestamp, "Z")) /
p.get_ts_key(timestamp, "V") /
sqrt(9.81 * (
p.geometry.wet_area(
p.get_ts_key(timestamp, "Z")) /
@@ -869,6 +862,7 @@ class ResultsWindow(PamhyrWindow):
my_dict[dict_x["time"]] = ts
z = profile.get_key("Z")
q = profile.get_key("Q")
v = profile.get_key("V")
if "bed_elevation" in y:
my_dict[dict_y["bed_elevation"]] = [
profile.geometry.z_min()] * len(ts)
@@ -877,12 +871,7 @@ class ResultsWindow(PamhyrWindow):
if "water_elevation" in y:
my_dict[dict_y["water_elevation"]] = z
if "velocity" in y:
my_dict[dict_y["velocity"]] = list(
map(
lambda q, z: profile.geometry.speed(q, z),
q, z
)
)
my_dict[dict_y["velocity"]] = v
if "depth" in y:
my_dict[dict_y["depth"]] = list(
map(lambda z: profile.geometry.max_water_depth(z), z)
@@ -893,12 +882,11 @@ class ResultsWindow(PamhyrWindow):
)
if "froude" in y:
my_dict[dict_y["froude"]] = list(
map(lambda z, q:
profile.geometry.speed(q, z) /
sqrt(9.81 * (
map(lambda z, v:
v / sqrt(9.81 * (
profile.geometry.wet_area(z) /
profile.geometry.wet_width(z))
), z, q)
), z, v)
)
if "wet_area" in y:
my_dict[dict_y["wet_area"]] = list(
+8 -8
View File
@@ -78,6 +78,7 @@ class ResultsWindowAdisTS(PamhyrWindow):
parent=None):
self._solver = solver
self._results = results
self.pollutant_label = ["None"]
pollutants_headers = self._results.pollutants_list.copy()
@@ -374,17 +375,14 @@ class ResultsWindowAdisTS(PamhyrWindow):
# Pollutant
table = self.find(QTableView, f"tableView_pollutants")
indexes = table.selectedIndexes()
if len(indexes) == 0:
pollutant = self._results.pollutants_list[0]
else:
pollutant = self._results.pollutants_list[indexes[0].row()]
if len(indexes) != 0:
self.pollutant_label = [
self._results.pollutants_list[i.row()+1] for i in indexes
]
#return (f"Reach: {reach.name} | " +
#f"Profile: {pname} | " +
#f"Pollutant: {pollutant}")
return (f"{self._trad['reach']}: {reach.name} | " +
f"{self._trad['cross_section']}: {pname} | " +
f"Pollutant: {pollutant} | " +
f"Pollutant: {', '.join(self.pollutant_label)} | " +
f"{self._trad['unit_time_s']} : {fts} ({ts} sec)")
def setup_statusbar(self):
@@ -404,6 +402,8 @@ class ResultsWindowAdisTS(PamhyrWindow):
"action_export": self.export,
}
self.find(QAction, "action_add").setEnabled(False)
for action in actions:
self.find(QAction, action).triggered.connect(
actions[action]
+2
View File
@@ -42,6 +42,8 @@ class ResultsTranslate(MainTranslate):
self._dict['day'] = _translate("Results", "day")
self._dict['days'] = _translate("Results", "days")
self._dict['envelop'] = _translate("Results", "envelop")
self._dict['x'] = _translate("Results", "X (m)")
self._dict['label_bottom'] = _translate("Results", "Bottom")
+1 -1
View File
@@ -91,7 +91,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Copyright © 2022-2024 INRAE</string>
<string>Copyright © 2022-2025 INRAE</string>
</property>
</widget>
</item>
+133 -128
View File
@@ -266,7 +266,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/BoundaryConditionsAdisTS/translate.py" line="37"/>
<source>Pollutant</source>
<translation type="unfinished"></translation>
<translation>Polluant</translation>
</message>
</context>
<context>
@@ -274,17 +274,12 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/BoundaryConditionsAdisTS/Edit/translate.py" line="32"/>
<source>Edit boundary conditions AdisTS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../View/BoundaryConditionsAdisTS/Edit/translate.py" line="39"/>
<source>Rate</source>
<translation type="unfinished"></translation>
<translation type="obsolete">Éditer les conditions aux limites AdisTS</translation>
</message>
<message>
<location filename="../View/BoundaryConditionsAdisTS/Edit/translate.py" line="40"/>
<source>Concentration</source>
<translation type="unfinished">Concentration</translation>
<translation type="obsolete">Concentration</translation>
</message>
</context>
<context>
@@ -300,7 +295,22 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/BoundaryConditionsAdisTS/translate.py" line="30"/>
<source>Boundary conditions AdisTS</source>
<translation type="unfinished"></translation>
<translation>Conditions aux limites AdisTS</translation>
</message>
<message>
<location filename="../View/BoundaryConditionsAdisTS/Edit/translate.py" line="32"/>
<source>Edit boundary conditions AdisTS</source>
<translation>Éditer les conditions aux limites AdisTS</translation>
</message>
<message>
<location filename="../View/BoundaryConditionsAdisTS/Edit/translate.py" line="39"/>
<source>Mass</source>
<translation>Masse</translation>
</message>
<message>
<location filename="../View/BoundaryConditionsAdisTS/Edit/translate.py" line="40"/>
<source>Concentration</source>
<translation>Concentration</translation>
</message>
</context>
<context>
@@ -391,12 +401,12 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../Checker/Adists.py" line="37"/>
<source>AdisTS output RK checker</source>
<translation type="unfinished"></translation>
<translation>Vérifie les PK de sortie AdisTS</translation>
</message>
<message>
<location filename="../Checker/Adists.py" line="38"/>
<source>Check output RK</source>
<translation type="unfinished"></translation>
<translation>Vérifie les PK de sortie</translation>
</message>
</context>
<context>
@@ -482,12 +492,12 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/Translate.py" line="31"/>
<source>Title</source>
<translation type="unfinished"></translation>
<translation>Titre</translation>
</message>
<message>
<location filename="../View/Translate.py" line="51"/>
<source>Method</source>
<translation type="unfinished">Méthode</translation>
<translation>Méthode</translation>
</message>
</context>
<context>
@@ -531,7 +541,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/D90AdisTS/translate.py" line="30"/>
<source>D90 AdisTS</source>
<translation type="unfinished"></translation>
<translation>D90 AdisTS</translation>
</message>
</context>
<context>
@@ -539,7 +549,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/DIFAdisTS/translate.py" line="30"/>
<source>DIF AdisTS</source>
<translation type="unfinished"></translation>
<translation>DIF AdisTS</translation>
</message>
</context>
<context>
@@ -945,17 +955,17 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/ui/CustomExportAdisDialog.ui" line="59"/>
<source>Pollutant:</source>
<translation type="unfinished"></translation>
<translation>Polluant:</translation>
</message>
<message>
<location filename="../View/ui/SelectSolverAdisTS.ui" line="23"/>
<source>AdisTS Solver:</source>
<translation type="unfinished"></translation>
<translation>Solveur AdisTS:</translation>
</message>
<message>
<location filename="../View/ui/SelectSolverAdisTS.ui" line="71"/>
<source>Mage Repertory:</source>
<translation type="unfinished"></translation>
<translation>Répertoire Mage:</translation>
</message>
</context>
<context>
@@ -1247,19 +1257,19 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<source>Errors summary</source>
<translation>Résumé des erreurs</translation>
</message>
<message>
<location filename="../View/ui/about.ui" line="94"/>
<source>Copyright &#xa9; 2022-2024 INRAE</source>
<translation type="obsolete">Copyright © 2022-2024 INRAE</translation>
</message>
<message>
<location filename="../View/ui/about.ui" line="131"/>
<source>Version: @version @codename</source>
<translation>Version : @version @codename</translation>
</message>
<message>
<location filename="../View/ui/about.ui" line="94"/>
<source>Copyright &#xa9; 2022-2025 INRAE</source>
<translation type="obsolete">Copyright © 2022-2025 INRAE</translation>
</message>
<message encoding="UTF-8">
<location filename="../View/ui/about.ui" line="94"/>
<source>Copyright © 2022-2024 INRAE</source>
<source>Copyright © 2022-2025 INRAE</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1497,7 +1507,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/InitialConditionsAdisTS/translate.py" line="30"/>
<source>Initial condition AdisTS</source>
<translation type="unfinished"></translation>
<translation>Conditions initiales AdisTS</translation>
</message>
</context>
<context>
@@ -1505,7 +1515,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/LateralContribution/Edit/translate.py" line="30"/>
<source>Edit lateral sources</source>
<translation>Modifier les contributions latérales</translation>
<translation>Éditer les apports latéraux</translation>
</message>
<message>
<location filename="../View/LateralContribution/Edit/translate.py" line="35"/>
@@ -1545,25 +1555,17 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/LateralContributionsAdisTS/translate.py" line="36"/>
<source>Lateral contribution</source>
<translation type="unfinished"></translation>
<translation>Apports latéraux</translation>
</message>
<message>
<location filename="../View/LateralContributionsAdisTS/translate.py" line="47"/>
<source>Begin rk (m)</source>
<translation type="unfinished"></translation>
<translation>Pk début</translation>
</message>
<message>
<location filename="../View/LateralContributionsAdisTS/translate.py" line="48"/>
<source>End rk (m)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>LateralContribution1adisTS</name>
<message>
<location filename="../View/LateralContributionsAdisTS/translate.py" line="30"/>
<source>Lateral contribution AdisTS</source>
<translation type="unfinished"></translation>
<translation>Pk fin</translation>
</message>
</context>
<context>
@@ -1571,12 +1573,17 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/LateralContributionsAdisTS/Edit/translate.py" line="30"/>
<source>Edit lateral contribution AdisTS</source>
<translation type="unfinished"></translation>
<translation>Éditer les apports latéraux AdisTS</translation>
</message>
<message>
<location filename="../View/LateralContributionsAdisTS/Edit/translate.py" line="37"/>
<source>Mass Flow</source>
<translation type="unfinished"></translation>
<translation>Flux massique</translation>
</message>
<message>
<location filename="../View/LateralContributionsAdisTS/translate.py" line="30"/>
<source>Lateral contribution AdisTS</source>
<translation>Apports latéraux AdisTS</translation>
</message>
</context>
<context>
@@ -2734,7 +2741,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/ui/Pollutants.ui" line="147"/>
<source>LateralContributions</source>
<translation type="unfinished"></translation>
<translation>Apports Latéraux</translation>
</message>
<message>
<location filename="../View/ui/MainWindow.ui" line="219"/>
@@ -2744,7 +2751,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/ui/MainWindow.ui" line="750"/>
<source>Output RK</source>
<translation type="unfinished"></translation>
<translation>Pk de sortie</translation>
</message>
<message>
<location filename="../View/ui/MainWindow.ui" line="759"/>
@@ -2769,47 +2776,47 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/ui/MainWindow.ui" line="782"/>
<source>Open results AdisTS</source>
<translation type="unfinished"></translation>
<translation>Ouvrir des résultats AdisTS</translation>
</message>
<message>
<location filename="../View/ui/OutputRKAdisTS.ui" line="49"/>
<source>Enable / Disable Output RK AdisTS</source>
<translation type="unfinished"></translation>
<translation>Activer / Désactiver la sortie AdisTS</translation>
</message>
<message>
<location filename="../View/ui/EditBoundaryConditionsAdisTS.ui" line="88"/>
<source>Add a new point in boundary condition or punctual contribution</source>
<translation type="unfinished"></translation>
<translation>Ajouter un nouveau point dans la condition limite</translation>
</message>
<message>
<location filename="../View/ui/SolverLogAdisTS.ui" line="116"/>
<source>results_Mage</source>
<translation type="unfinished"></translation>
<translation>Résultats Mage</translation>
</message>
<message>
<location filename="../View/ui/BoundaryConditionsAdisTS.ui" line="89"/>
<source>Add a new boundary condition or punctual contribution</source>
<translation type="unfinished"></translation>
<translation>Ajouter une condition limite ou apport ponctuel</translation>
</message>
<message>
<location filename="../View/ui/BoundaryConditionsAdisTS.ui" line="119"/>
<source>Edit boundary condition or punctual contribution</source>
<translation type="unfinished"></translation>
<translation>Éditer une condition limite ou un apport ponctuel</translation>
</message>
<message>
<location filename="../View/ui/EditLateralContributionAdisTS.ui" line="81"/>
<source>Add a new point in boundary condition or lateral contribution</source>
<translation type="unfinished"></translation>
<translation>Ajouter un point dans la condition limite ou l&apos;apport latéral</translation>
</message>
<message>
<location filename="../View/ui/LateralContributionsAdisTS.ui" line="85"/>
<source>Add a new boundary condition or lateral contribution</source>
<translation type="unfinished"></translation>
<translation>Ajouter une condition limite ou un apport latéral</translation>
</message>
<message>
<location filename="../View/ui/LateralContributionsAdisTS.ui" line="115"/>
<source>Edit boundary condition or lateral contribution</source>
<translation type="unfinished"></translation>
<translation>Éditer une condition limite ou un apport latéral</translation>
</message>
<message>
<location filename="../View/ui/ResultsAdisTS.ui" line="160"/>
@@ -2829,7 +2836,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/ui/ResultsAdisTS.ui" line="201"/>
<source>Linear mass density</source>
<translation type="unfinished"></translation>
<translation>Masse linéique</translation>
</message>
<message>
<location filename="../View/ui/ResultsAdisTS.ui" line="308"/>
@@ -2849,12 +2856,12 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/ui/ResultsAdisTS.ui" line="272"/>
<source>Linear mass density dx</source>
<translation type="unfinished"></translation>
<translation>Masse linéique dx</translation>
</message>
<message>
<location filename="../View/ui/ResultsAdisTS.ui" line="282"/>
<source>Linear mass density dt</source>
<translation type="unfinished"></translation>
<translation>Masse linéique dt</translation>
</message>
<message>
<location filename="../View/ui/ResultsAdisTS.ui" line="298"/>
@@ -2874,7 +2881,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/ui/ResultsAdisTS.ui" line="429"/>
<source>Add custom visualization</source>
<translation type="unfinished"></translation>
<translation>Ajouter une courbe personnalisée</translation>
</message>
<message>
<location filename="../View/ui/ResultsAdisTS.ui" line="450"/>
@@ -2998,12 +3005,12 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/OutputRKAdisTS/Translate.py" line="30"/>
<source>Output RK</source>
<translation type="unfinished"></translation>
<translation>Pk de sortie</translation>
</message>
<message>
<location filename="../View/OutputRKAdisTS/Translate.py" line="34"/>
<source>X (m)</source>
<translation type="unfinished">X (m)</translation>
<translation>X (m)</translation>
</message>
</context>
<context>
@@ -3019,17 +3026,17 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/Pollutants/Translate.py" line="30"/>
<source>Pollutants</source>
<translation type="unfinished">Polluants</translation>
<translation>Polluants</translation>
</message>
<message>
<location filename="../View/Pollutants/Translate.py" line="34"/>
<source>X (m)</source>
<translation type="unfinished">X (m)</translation>
<translation>X (m)</translation>
</message>
<message>
<location filename="../View/Pollutants/Edit/Translate.py" line="32"/>
<source>Edit Pollutant</source>
<translation type="unfinished"></translation>
<translation>Éditer le polluant</translation>
</message>
</context>
<context>
@@ -3076,7 +3083,7 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<translation>jour</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="45"/>
<location filename="../View/Results/translate.py" line="47"/>
<source>X (m)</source>
<translation>X (m)</translation>
</message>
@@ -3116,84 +3123,89 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<translation type="obsolete">Fond de la rivière</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="48"/>
<location filename="../View/Results/translate.py" line="50"/>
<source>Water elevation</source>
<translation>Cote de l&apos;eau</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="49"/>
<location filename="../View/Results/translate.py" line="51"/>
<source>Max water elevation</source>
<translation>Cote maximum de l&apos;eau</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="55"/>
<location filename="../View/Results/translate.py" line="57"/>
<source>Reach name</source>
<translation>Nom du bief</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="111"/>
<location filename="../View/Results/translate.py" line="113"/>
<source>Profile</source>
<translation>Profil</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="47"/>
<location filename="../View/Results/translate.py" line="49"/>
<source>Bottom</source>
<translation>Fond</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="63"/>
<source>Concentration</source>
<translation type="unfinished">Concentration</translation>
<translation>Concentration</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="64"/>
<source>Max Concentration</source>
<translation type="unfinished"></translation>
<translation>Concentration max</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="65"/>
<source>Min Concentration</source>
<translation type="unfinished"></translation>
<translation>Concentration min</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="67"/>
<source>Thickness</source>
<translation type="unfinished">Épaisseur</translation>
<translation>Épaisseur</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="68"/>
<source>Max Thickness</source>
<translation type="unfinished"></translation>
<translation>Épaisseur max</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="69"/>
<source>Min Thickness</source>
<translation type="unfinished"></translation>
<translation>Épaisseur min</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="72"/>
<source>Mass</source>
<translation type="unfinished"></translation>
<translation>Masse</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="73"/>
<source>Max Mass</source>
<translation type="unfinished"></translation>
<translation>Masse max</translation>
</message>
<message>
<location filename="../View/Results/PlotSedAdis.py" line="74"/>
<source>Min Mass</source>
<translation type="unfinished"></translation>
<translation>Masse min</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="59"/>
<location filename="../View/Results/translate.py" line="61"/>
<source>Variables names</source>
<translation type="unfinished"></translation>
<translation>Noms des variables</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="68"/>
<location filename="../View/Results/translate.py" line="70"/>
<source>Pollutant name</source>
<translation type="unfinished"></translation>
<translation>Nom des polluants</translation>
</message>
<message>
<location filename="../View/Results/translate.py" line="45"/>
<source>envelop</source>
<translation>enveloppe</translation>
</message>
</context>
<context>
@@ -3676,145 +3688,138 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<source>Discharge (m^3/s)</source>
<translation>Débit (m³/s)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="77"/>
<source>Wet Area (m^2)</source>
<translation type="obsolete">Aire mouillée (m²)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="76"/>
<source>Wet Area (m&#xb2;)</source>
<translation type="obsolete">Aire mouillée (m²)</translation>
</message>
<message>
<location filename="../View/InitialConditionsAdisTS/translate.py" line="49"/>
<source>EG (m)</source>
<translation type="unfinished"></translation>
<translation>Épaisseur lit
moyen gauche (m)</translation>
</message>
<message>
<location filename="../View/InitialConditionsAdisTS/translate.py" line="50"/>
<source>EM (m)</source>
<translation type="unfinished"></translation>
<translation>Épaisseur lit
mineur (m)</translation>
</message>
<message>
<location filename="../View/InitialConditionsAdisTS/translate.py" line="51"/>
<source>ED (m)</source>
<translation type="unfinished"></translation>
<translation>Épaisseur lit
moyen droit (m)</translation>
</message>
<message>
<location filename="../View/DIFAdisTS/translate.py" line="45"/>
<source>Start_RK (m)</source>
<translation type="unfinished"></translation>
<translation>Pk début</translation>
</message>
<message>
<location filename="../View/DIFAdisTS/translate.py" line="46"/>
<source>End_RK (m)</source>
<translation type="unfinished"></translation>
<translation>Pk fin</translation>
</message>
<message>
<location filename="../View/InitialConditionsAdisTS/translate.py" line="52"/>
<source>Rate</source>
<translation type="unfinished"></translation>
<translation>Taux</translation>
</message>
<message>
<location filename="../View/D90AdisTS/translate.py" line="45"/>
<source>D90</source>
<translation type="unfinished">D90</translation>
<translation>D90</translation>
</message>
<message>
<location filename="../View/Translate.py" line="60"/>
<source>Width Envelop (m)</source>
<translation type="unfinished"></translation>
<translation>Enveloppe de la argeur (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="63"/>
<source>Max Width (m)</source>
<translation type="unfinished"></translation>
<translation>Largeur max (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="64"/>
<source>Min Width (m)</source>
<translation type="unfinished"></translation>
<translation>Largeur min (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="67"/>
<source>Min Depth (m)</source>
<translation type="unfinished"></translation>
<translation>Profondeur min (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="68"/>
<source>Depth Envelop (m)</source>
<translation type="unfinished"></translation>
<translation>Enveloppe de la profondeur (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="75"/>
<source>Bed Elevation (m)</source>
<translation type="unfinished"></translation>
<translation>Cote du fond (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="78"/>
<source>Bed Elevation Envelop (m)</source>
<translation type="unfinished"></translation>
<translation>Enveloppe de la cote du fond (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="81"/>
<source>Max Bed Elevation (m)</source>
<translation type="unfinished"></translation>
<translation>Cote du fond max (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="84"/>
<source>Min Bed Elevation (m)</source>
<translation type="unfinished"></translation>
<translation>Cote du fond min (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="87"/>
<source>Water Elevation (m)</source>
<translation type="unfinished"></translation>
<translation>Cote de l&apos;eau (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="90"/>
<source>Water Elevation Envelop (m)</source>
<translation type="unfinished"></translation>
<translation>Enveloppe de la cote de l&apos;eau (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="93"/>
<source>Max Water Elevation (m)</source>
<translation type="unfinished"></translation>
<translation>Cote de l&apos;eau max (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="96"/>
<source>Min Water Elevation (m)</source>
<translation type="unfinished"></translation>
<translation>Cote de l&apos;eau min (m)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="100"/>
<source>Velocity Envelop (m/s)</source>
<translation type="unfinished"></translation>
<translation>Enveloppe de la vitesse (m/s)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="103"/>
<source>Max Velocity (m/s)</source>
<translation type="unfinished"></translation>
<translation>Vitesse max (m/s)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="106"/>
<source>Min Velocity (m/s)</source>
<translation type="unfinished"></translation>
<translation>Vitesse min (m/s)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="110"/>
<source>Discharge Envelop (m^3/s)</source>
<translation type="unfinished"></translation>
<translation>Enveloppe du débit (m³/s)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="113"/>
<source>Max Discharge (m^3/s)</source>
<translation type="unfinished"></translation>
<translation>Débit max (m³/s)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="116"/>
<source>Min Discharge (m^3/s)</source>
<translation type="unfinished"></translation>
<translation>Débit min (m³/s)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="127"/>
@@ -3824,72 +3829,72 @@ Cette fonctionnalité nécessite un bief muni d&apos;une géométrie.</translati
<message>
<location filename="../View/Translate.py" line="128"/>
<source>Rho</source>
<translation type="unfinished"></translation>
<translation>Rho</translation>
</message>
<message>
<location filename="../View/Translate.py" line="129"/>
<source>Porosity</source>
<translation type="unfinished"></translation>
<translation>Porosité</translation>
</message>
<message>
<location filename="../View/Translate.py" line="130"/>
<source>CDC_RIV</source>
<translation type="unfinished"></translation>
<translation>CDC_RIV</translation>
</message>
<message>
<location filename="../View/Translate.py" line="131"/>
<source>CDC_CAS</source>
<translation type="unfinished"></translation>
<translation>CDC_CAS</translation>
</message>
<message>
<location filename="../View/Translate.py" line="132"/>
<source>APD</source>
<translation type="unfinished"></translation>
<translation>APD</translation>
</message>
<message>
<location filename="../View/Translate.py" line="133"/>
<source>AC</source>
<translation type="unfinished"></translation>
<translation>AC</translation>
</message>
<message>
<location filename="../View/Translate.py" line="134"/>
<source>BC</source>
<translation type="unfinished"></translation>
<translation>BC</translation>
</message>
<message>
<location filename="../View/Translate.py" line="136"/>
<source>Concentration (g/l)</source>
<translation type="unfinished"></translation>
<translation>Concentration (g/l)</translation>
</message>
<message>
<location filename="../View/Translate.py" line="147"/>
<source>Mass (kg)</source>
<translation type="unfinished"></translation>
<translation>Masse</translation>
</message>
<message>
<location filename="../View/Translate.py" line="148"/>
<source>Concentration (kg/m^3)</source>
<translation type="unfinished"></translation>
<translation>Concentration (kg/m³)</translation>
</message>
<message>
<location filename="../View/DIFAdisTS/translate.py" line="47"/>
<source>DIF</source>
<translation type="unfinished">DIF</translation>
<translation>DIF</translation>
</message>
<message>
<location filename="../View/DIFAdisTS/translate.py" line="48"/>
<source>Coeff b</source>
<translation type="unfinished"></translation>
<translation>Coeff b</translation>
</message>
<message>
<location filename="../View/DIFAdisTS/translate.py" line="49"/>
<source>Coeff c</source>
<translation type="unfinished"></translation>
<translation>Coeff c</translation>
</message>
<message encoding="UTF-8">
<location filename="../View/Translate.py" line="139"/>
<source>Wet Area (m²)</source>
<translation type="unfinished"></translation>
<translation>Aire Mouillée (m²)</translation>
</message>
</context>
</TS>