diff --git a/AUTHORS b/AUTHORS
index 1451eb9c..3da36069 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,4 +1,4 @@
Sylvain COULIBALY, INRAE, 2020 - 2022
Théophile TERRAZ, INRAE, 2022 - 2024
-Pierre-Antoine ROUBY, INRAE, 2023 - 2025
+Pierre-Antoine ROUBY, INRAE, 2023 - 2026
Dylan JEANNIN, INRAE, 2026
\ No newline at end of file
diff --git a/src/Checker/Adists.py b/src/Checker/Adists.py
index eae7df0a..68e37824 100644
--- a/src/Checker/Adists.py
+++ b/src/Checker/Adists.py
@@ -1,5 +1,5 @@
# Adists.py -- Pamhyr study checkers
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Checker/Checker.py b/src/Checker/Checker.py
index d311fde5..fcb85de4 100644
--- a/src/Checker/Checker.py
+++ b/src/Checker/Checker.py
@@ -1,5 +1,5 @@
# Checker.py -- Pamhyr abstract checker class
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Checker/Mage.py b/src/Checker/Mage.py
index 62c5342b..949e61ae 100644
--- a/src/Checker/Mage.py
+++ b/src/Checker/Mage.py
@@ -1,5 +1,5 @@
# Mage.py -- Pamhyr MAGE checkers
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Checker/Study.py b/src/Checker/Study.py
index 09c223d4..bddfa4a7 100644
--- a/src/Checker/Study.py
+++ b/src/Checker/Study.py
@@ -1,5 +1,5 @@
# Study.py -- Pamhyr study checkers
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Meshing/AMeshingTool.py b/src/Meshing/AMeshingTool.py
index f5d5cff2..42bfdd62 100644
--- a/src/Meshing/AMeshingTool.py
+++ b/src/Meshing/AMeshingTool.py
@@ -1,5 +1,5 @@
# AMeshingTool.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Meshing/Internal.py b/src/Meshing/Internal.py
index c5999fb1..e597a339 100644
--- a/src/Meshing/Internal.py
+++ b/src/Meshing/Internal.py
@@ -1,5 +1,5 @@
# Internal.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Meshing/Mage.py b/src/Meshing/Mage.py
index 94ef5385..c7eb33c1 100644
--- a/src/Meshing/Mage.py
+++ b/src/Meshing/Mage.py
@@ -1,5 +1,5 @@
# Mage.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Meshing/__init__.py b/src/Meshing/__init__.py
index bf12a7a6..761264ea 100644
--- a/src/Meshing/__init__.py
+++ b/src/Meshing/__init__.py
@@ -1,5 +1,5 @@
# __init__.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Meshing/test_Meshing.py b/src/Meshing/test_Meshing.py
index 22c52707..a8f9cac6 100644
--- a/src/Meshing/test_Meshing.py
+++ b/src/Meshing/test_Meshing.py
@@ -1,5 +1,5 @@
# test_Model.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/BoundaryCondition/BoundaryCondition.py b/src/Model/BoundaryCondition/BoundaryCondition.py
index fdc9c0a5..844ca8f6 100644
--- a/src/Model/BoundaryCondition/BoundaryCondition.py
+++ b/src/Model/BoundaryCondition/BoundaryCondition.py
@@ -1,5 +1,5 @@
# BoundaryCondition.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/BoundaryCondition/BoundaryConditionList.py b/src/Model/BoundaryCondition/BoundaryConditionList.py
index 20c1a791..29a23c5a 100644
--- a/src/Model/BoundaryCondition/BoundaryConditionList.py
+++ b/src/Model/BoundaryCondition/BoundaryConditionList.py
@@ -1,5 +1,5 @@
# BoundaryConditionList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/BoundaryCondition/BoundaryConditionTypes.py b/src/Model/BoundaryCondition/BoundaryConditionTypes.py
index e9f2bcaa..b74e9f6b 100644
--- a/src/Model/BoundaryCondition/BoundaryConditionTypes.py
+++ b/src/Model/BoundaryCondition/BoundaryConditionTypes.py
@@ -1,5 +1,5 @@
# BoundaryConditionTypes.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/BoundaryConditionsAdisTS/BoundaryConditionAdisTS.py b/src/Model/BoundaryConditionsAdisTS/BoundaryConditionAdisTS.py
index d5b7bcd4..f8387adc 100644
--- a/src/Model/BoundaryConditionsAdisTS/BoundaryConditionAdisTS.py
+++ b/src/Model/BoundaryConditionsAdisTS/BoundaryConditionAdisTS.py
@@ -1,5 +1,5 @@
# BoundaryConditionsAdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/BoundaryConditionsAdisTS/BoundaryConditionsAdisTSList.py b/src/Model/BoundaryConditionsAdisTS/BoundaryConditionsAdisTSList.py
index 4bb90dbc..cf031d76 100644
--- a/src/Model/BoundaryConditionsAdisTS/BoundaryConditionsAdisTSList.py
+++ b/src/Model/BoundaryConditionsAdisTS/BoundaryConditionsAdisTSList.py
@@ -1,5 +1,5 @@
# BoundaryConditionsAdisTSList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/D90AdisTS/D90AdisTS.py b/src/Model/D90AdisTS/D90AdisTS.py
index bfc4c103..5c222f65 100644
--- a/src/Model/D90AdisTS/D90AdisTS.py
+++ b/src/Model/D90AdisTS/D90AdisTS.py
@@ -1,5 +1,5 @@
# D90AdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/D90AdisTS/D90AdisTSList.py b/src/Model/D90AdisTS/D90AdisTSList.py
index 51fa8d7b..ce4f6ef6 100644
--- a/src/Model/D90AdisTS/D90AdisTSList.py
+++ b/src/Model/D90AdisTS/D90AdisTSList.py
@@ -1,5 +1,5 @@
# D90AdisTSList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/D90AdisTS/D90AdisTSSpec.py b/src/Model/D90AdisTS/D90AdisTSSpec.py
index eb1611a0..8d8252bb 100644
--- a/src/Model/D90AdisTS/D90AdisTSSpec.py
+++ b/src/Model/D90AdisTS/D90AdisTSSpec.py
@@ -1,5 +1,5 @@
# D90AdisTSSpec.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/DIFAdisTS/DIFAdisTS.py b/src/Model/DIFAdisTS/DIFAdisTS.py
index 0af3f1e8..b642f7d6 100644
--- a/src/Model/DIFAdisTS/DIFAdisTS.py
+++ b/src/Model/DIFAdisTS/DIFAdisTS.py
@@ -1,5 +1,5 @@
# DIFAdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/DIFAdisTS/DIFAdisTSList.py b/src/Model/DIFAdisTS/DIFAdisTSList.py
index 0238e97d..a765547c 100644
--- a/src/Model/DIFAdisTS/DIFAdisTSList.py
+++ b/src/Model/DIFAdisTS/DIFAdisTSList.py
@@ -1,5 +1,5 @@
# DIFAdisTSList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/DIFAdisTS/DIFAdisTSSpec.py b/src/Model/DIFAdisTS/DIFAdisTSSpec.py
index 6baec9b3..fe185dfa 100644
--- a/src/Model/DIFAdisTS/DIFAdisTSSpec.py
+++ b/src/Model/DIFAdisTS/DIFAdisTSSpec.py
@@ -1,5 +1,5 @@
# DIFAdisTSSpec.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Except.py b/src/Model/Except.py
index 7c147070..c5025400 100644
--- a/src/Model/Except.py
+++ b/src/Model/Except.py
@@ -1,5 +1,5 @@
# Except.py -- Pamhyr model exceptions
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Friction/Friction.py b/src/Model/Friction/Friction.py
index 28722255..dc7dab8b 100644
--- a/src/Model/Friction/Friction.py
+++ b/src/Model/Friction/Friction.py
@@ -1,5 +1,5 @@
# Friction.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Friction/FrictionList.py b/src/Model/Friction/FrictionList.py
index e24d0e60..963c3316 100644
--- a/src/Model/Friction/FrictionList.py
+++ b/src/Model/Friction/FrictionList.py
@@ -1,5 +1,5 @@
# FrictionList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Geometry/Point.py b/src/Model/Geometry/Point.py
index 5de3b058..86ccf639 100644
--- a/src/Model/Geometry/Point.py
+++ b/src/Model/Geometry/Point.py
@@ -1,5 +1,5 @@
# Point.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Geometry/PointXY.py b/src/Model/Geometry/PointXY.py
index 020d8962..cbefd9c7 100644
--- a/src/Model/Geometry/PointXY.py
+++ b/src/Model/Geometry/PointXY.py
@@ -1,5 +1,5 @@
# PointXY.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Geometry/PointXYZ.py b/src/Model/Geometry/PointXYZ.py
index af18bf0b..08e1f0c3 100644
--- a/src/Model/Geometry/PointXYZ.py
+++ b/src/Model/Geometry/PointXYZ.py
@@ -1,5 +1,5 @@
# PointXYZ.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Geometry/Profile.py b/src/Model/Geometry/Profile.py
index c4f7903b..6d910b44 100644
--- a/src/Model/Geometry/Profile.py
+++ b/src/Model/Geometry/Profile.py
@@ -1,5 +1,5 @@
# Profile.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py
index 1b513447..905b2701 100644
--- a/src/Model/Geometry/ProfileXYZ.py
+++ b/src/Model/Geometry/ProfileXYZ.py
@@ -1,5 +1,5 @@
# ProfileXYZ.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -91,6 +91,9 @@ class ProfileXYZ(Profile, SQLSubModel):
self._station = []
self.station_up_to_date = False
+ self._get_water_limits_cache = {}
+ self._get_water_limits_ac_cache = {}
+
@classmethod
def _db_create(cls, execute, ext=""):
execute(f"""
@@ -619,6 +622,7 @@ class ProfileXYZ(Profile, SQLSubModel):
"""
return [x for x in lst if not np.isnan(x)]
+ @timer
def speed(self, q, z):
area = self.wet_area(z)
@@ -670,6 +674,7 @@ class ProfileXYZ(Profile, SQLSubModel):
length += line.length
return length
+ @timer
def compute_wet_area(self, z):
area = 0.0
if len(self.tab.L) > 0:
@@ -710,6 +715,7 @@ class ProfileXYZ(Profile, SQLSubModel):
if len(line.coords) > 2:
poly = geometry.Polygon(line)
area += poly.area
+
return area
def wet_radius(self, z):
@@ -732,6 +738,7 @@ class ProfileXYZ(Profile, SQLSubModel):
line = geometry.LineString(list(zip(station, zz)))
return line
+ @timer
def wet_lines(self, z):
points = self._points
if len(points) < 3:
@@ -808,7 +815,6 @@ class ProfileXYZ(Profile, SQLSubModel):
return points
def get_nb_wet_areas(self, z):
-
n_zones = 0
points = self._points
if points[0].z <= z:
@@ -820,10 +826,13 @@ class ProfileXYZ(Profile, SQLSubModel):
return n_zones
+ @timer
def get_all_water_limits_ac(self, z):
"""
Determine all water limits for z elevation.
"""
+ if z in self._get_water_limits_ac_cache:
+ return self._get_water_limits_ac_cache[z]
points = self._points
if len(points) < 3:
@@ -856,69 +865,94 @@ class ProfileXYZ(Profile, SQLSubModel):
logger.error(f"ERROR in get_all_water_limits_ac")
return [], []
- return start, list(reversed(end))
+ res = start, list(reversed(end))
+ self._get_water_limits_ac_cache[z] = res
+ return res
+
+ @timer
def get_water_limits(self, z):
+ if z in self._get_water_limits_cache:
+ return self._get_water_limits_cache[z]
+
+ v = self.get_water_limits_compute(z)
+
+ return v
+
+ def get_water_limits_compute(self, z):
"""
Determine left and right limits of water elevation.
"""
-
# Get the index of first point with elevation lesser than water
# elevation (for the right and left river side)
- i_left = -1
- i_right = -1
+ i_left = next(
+ filter(
+ lambda i: self.point(i).z <= z,
+ range(self.number_points)
+ ),
+ -1
+ )
- for i in range(self.number_points):
- if self.point(i).z <= z:
- i_left = i
- break
-
- for i in reversed(range(self.number_points)):
- if self.point(i).z <= z:
- i_right = i
- break
+ i_right = next(
+ filter(
+ lambda i: self.point(i).z <= z,
+ reversed(range(self.number_points))
+ ),
+ -1
+ )
# Interpolate points at river left side
if (i_left > 0):
- if abs(self.point(i_left - 1).z - self.point(i_left).z) < 1e-20:
- pt_left = self.point(i_left)
+ pi = self.point(i_left)
+ pim1 = self.point(i_left - 1)
+
+ if abs(pim1.z - pi.z) < 1e-20:
+ pt_left = pi
else:
- fact = (z - self.point(i_left).z) / \
- (self.point(i_left - 1).z - self.point(i_left).z)
- x = self.point(i_left).x + fact * \
- (self.point(i_left - 1).x - self.point(i_left).x)
- y = self.point(i_left).y + fact * \
- (self.point(i_left - 1).y - self.point(i_left).y)
+ fact = (z - pi.z) / (pim1.z - pi.z)
+ x = pi.x + fact * (pim1.x - pi.x)
+ y = pi.y + fact * (pim1.y - pi.y)
pt_left = PointXYZ(x=x, y=y, z=z, name="wl_left")
else:
pt_left = self.point(0)
# Interpolate points at river right side
if (i_right < self.number_points - 1):
- if abs(self.point(i_right + 1).z - self.point(i_right).z) < 1e-20:
- pt_right = self.point(i_right)
+ pi = self.point(i_right)
+ pip1 = self.point(i_right + 1)
+
+ if abs(pip1.z - pi.z) < 1e-20:
+ pt_right = pi
else:
- fact = (z - self.point(i_right).z) / \
- (self.point(i_right + 1).z - self.point(i_right).z)
- x = self.point(i_right).x + fact * \
- (self.point(i_right + 1).x - self.point(i_right).x)
- y = self.point(i_right).y + fact * \
- (self.point(i_right + 1).y - self.point(i_right).y)
+ fact = (z - pi.z) / (pip1.z - pi.z)
+ x = pi.x + fact * (pip1.x - pi.x)
+ y = pi.y + fact * (pip1.y - pi.y)
pt_right = PointXYZ(x=x, y=y, z=z, name="wl_right")
else:
pt_right = self.point(self.number_points - 1)
- return pt_left, pt_right
+ v = (pt_left, pt_right)
+ # Put results in cache
+ self._get_water_limits_cache[z] = v
+
+ # Create a generator to improve results data reading speed
+ yield v
+
+ @timer
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
diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py
index 05b48d33..3a618552 100644
--- a/src/Model/Geometry/Reach.py
+++ b/src/Model/Geometry/Reach.py
@@ -1,5 +1,5 @@
# Reach.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Geometry/Vector_1d.py b/src/Model/Geometry/Vector_1d.py
index 57687d77..292967b6 100644
--- a/src/Model/Geometry/Vector_1d.py
+++ b/src/Model/Geometry/Vector_1d.py
@@ -1,5 +1,5 @@
# Vector_1d.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/HydraulicStructures/Basic/HydraulicStructures.py b/src/Model/HydraulicStructures/Basic/HydraulicStructures.py
index 757d8bfb..fcffeddf 100644
--- a/src/Model/HydraulicStructures/Basic/HydraulicStructures.py
+++ b/src/Model/HydraulicStructures/Basic/HydraulicStructures.py
@@ -1,5 +1,5 @@
# HydraulicStructures.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/HydraulicStructures/Basic/Types.py b/src/Model/HydraulicStructures/Basic/Types.py
index 6e14742e..27f236a2 100644
--- a/src/Model/HydraulicStructures/Basic/Types.py
+++ b/src/Model/HydraulicStructures/Basic/Types.py
@@ -1,5 +1,5 @@
# Types.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/HydraulicStructures/Basic/Value.py b/src/Model/HydraulicStructures/Basic/Value.py
index 7d894f82..bdf03de5 100644
--- a/src/Model/HydraulicStructures/Basic/Value.py
+++ b/src/Model/HydraulicStructures/Basic/Value.py
@@ -1,5 +1,5 @@
# Value.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/HydraulicStructures/HydraulicStructures.py b/src/Model/HydraulicStructures/HydraulicStructures.py
index aa390c5b..f07150c5 100644
--- a/src/Model/HydraulicStructures/HydraulicStructures.py
+++ b/src/Model/HydraulicStructures/HydraulicStructures.py
@@ -1,5 +1,5 @@
# HydraulicStructures.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/HydraulicStructures/HydraulicStructuresList.py b/src/Model/HydraulicStructures/HydraulicStructuresList.py
index 56984478..1c66dabf 100644
--- a/src/Model/HydraulicStructures/HydraulicStructuresList.py
+++ b/src/Model/HydraulicStructures/HydraulicStructuresList.py
@@ -1,5 +1,5 @@
# HydraulicStructuresList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/InitialConditions/InitialConditions.py b/src/Model/InitialConditions/InitialConditions.py
index fc299a77..c295e24e 100644
--- a/src/Model/InitialConditions/InitialConditions.py
+++ b/src/Model/InitialConditions/InitialConditions.py
@@ -1,5 +1,5 @@
# InitialConditions.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/InitialConditions/InitialConditionsDict.py b/src/Model/InitialConditions/InitialConditionsDict.py
index 5039b1a5..15403e90 100644
--- a/src/Model/InitialConditions/InitialConditionsDict.py
+++ b/src/Model/InitialConditions/InitialConditionsDict.py
@@ -1,5 +1,5 @@
# InitialConditionsDict.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py
index 845d9bc3..5dac7d8d 100644
--- a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py
+++ b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTS.py
@@ -1,5 +1,5 @@
# InitialConditionsAdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSList.py b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSList.py
index da151fe5..1d5c6726 100644
--- a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSList.py
+++ b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSList.py
@@ -1,5 +1,5 @@
# InitialConditionsAdisTSList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSSpec.py b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSSpec.py
index 85628c40..8cd963d1 100644
--- a/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSSpec.py
+++ b/src/Model/InitialConditionsAdisTS/InitialConditionsAdisTSSpec.py
@@ -1,5 +1,5 @@
# InitialConditionsAdisTSSpec.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/LateralContribution/LateralContribution.py b/src/Model/LateralContribution/LateralContribution.py
index 559ec4fa..557f7374 100644
--- a/src/Model/LateralContribution/LateralContribution.py
+++ b/src/Model/LateralContribution/LateralContribution.py
@@ -1,5 +1,5 @@
# LateralContribution.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/LateralContribution/LateralContributionList.py b/src/Model/LateralContribution/LateralContributionList.py
index 1a081029..49bffef1 100644
--- a/src/Model/LateralContribution/LateralContributionList.py
+++ b/src/Model/LateralContribution/LateralContributionList.py
@@ -1,5 +1,5 @@
# LateralContributionList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/LateralContribution/LateralContributionTypes.py b/src/Model/LateralContribution/LateralContributionTypes.py
index 35ffca3e..630f7c00 100644
--- a/src/Model/LateralContribution/LateralContributionTypes.py
+++ b/src/Model/LateralContribution/LateralContributionTypes.py
@@ -1,5 +1,5 @@
# LateralContributionTypes.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/LateralContributionsAdisTS/LateralContributionAdisTS.py b/src/Model/LateralContributionsAdisTS/LateralContributionAdisTS.py
index 15b82df0..b0deda44 100644
--- a/src/Model/LateralContributionsAdisTS/LateralContributionAdisTS.py
+++ b/src/Model/LateralContributionsAdisTS/LateralContributionAdisTS.py
@@ -1,5 +1,5 @@
# LateralContributionAdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/LateralContributionsAdisTS/LateralContributionsAdisTSList.py b/src/Model/LateralContributionsAdisTS/LateralContributionsAdisTSList.py
index 8ec86012..2baad522 100644
--- a/src/Model/LateralContributionsAdisTS/LateralContributionsAdisTSList.py
+++ b/src/Model/LateralContributionsAdisTS/LateralContributionsAdisTSList.py
@@ -1,5 +1,5 @@
# LateralContributionsAdisTSList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Network/Edge.py b/src/Model/Network/Edge.py
index 3251832c..61d49fc6 100644
--- a/src/Model/Network/Edge.py
+++ b/src/Model/Network/Edge.py
@@ -1,5 +1,5 @@
# Edge.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Network/Graph.py b/src/Model/Network/Graph.py
index f678ed89..12a50520 100644
--- a/src/Model/Network/Graph.py
+++ b/src/Model/Network/Graph.py
@@ -1,5 +1,5 @@
# Graph.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Network/Node.py b/src/Model/Network/Node.py
index dc3f0a2d..d4843958 100644
--- a/src/Model/Network/Node.py
+++ b/src/Model/Network/Node.py
@@ -1,5 +1,5 @@
# Node.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Network/Point.py b/src/Model/Network/Point.py
index df441aac..fc15d342 100644
--- a/src/Model/Network/Point.py
+++ b/src/Model/Network/Point.py
@@ -1,5 +1,5 @@
# Point.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Network/__init__.py b/src/Model/Network/__init__.py
index bf12a7a6..761264ea 100644
--- a/src/Model/Network/__init__.py
+++ b/src/Model/Network/__init__.py
@@ -1,5 +1,5 @@
# __init__.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Network/test_network.py b/src/Model/Network/test_network.py
index badb744e..f5748e0d 100644
--- a/src/Model/Network/test_network.py
+++ b/src/Model/Network/test_network.py
@@ -1,5 +1,5 @@
# test_Network.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/OutputRKAdists/OutputRKAdists.py b/src/Model/OutputRKAdists/OutputRKAdists.py
index b64af320..e428b8f7 100644
--- a/src/Model/OutputRKAdists/OutputRKAdists.py
+++ b/src/Model/OutputRKAdists/OutputRKAdists.py
@@ -1,5 +1,5 @@
# OutputRKAdists.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Pollutants/Pollutants.py b/src/Model/Pollutants/Pollutants.py
index 55408b8d..2cdc3683 100644
--- a/src/Model/Pollutants/Pollutants.py
+++ b/src/Model/Pollutants/Pollutants.py
@@ -1,5 +1,5 @@
# Pollutants.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Reservoir/Reservoir.py b/src/Model/Reservoir/Reservoir.py
index 6137122c..43d4e80e 100644
--- a/src/Model/Reservoir/Reservoir.py
+++ b/src/Model/Reservoir/Reservoir.py
@@ -1,5 +1,5 @@
# Reservoir.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Reservoir/ReservoirList.py b/src/Model/Reservoir/ReservoirList.py
index ecd4b597..527d0617 100644
--- a/src/Model/Reservoir/ReservoirList.py
+++ b/src/Model/Reservoir/ReservoirList.py
@@ -1,5 +1,5 @@
# ReservoirList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Results/Results.py b/src/Model/Results/Results.py
index 2e92767e..2ea30e03 100644
--- a/src/Model/Results/Results.py
+++ b/src/Model/Results/Results.py
@@ -1,5 +1,5 @@
# Results.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -22,6 +22,8 @@ import numpy as np
from copy import deepcopy
from datetime import datetime
+from tools import timer
+
from Model.Scenario import Scenario
from Model.Tools.PamhyrDB import SQLSubModel
from Model.Results.River.River import River
@@ -155,8 +157,185 @@ class AdditionalData(SQLSubModel):
return True
+class TableData(SQLSubModel):
+ _sub_classes = []
+
+ def __init__(self, id=-1, study=None,
+ legend="", data=None,
+ owner_scenario=-1):
+ super(TableData, self).__init__(
+ id=id, status=study.status,
+ owner_scenario=owner_scenario
+ )
+
+ self._study = study
+ self._legend = legend
+ self._data = data
+
+ @property
+ def data(self):
+ return self._data
+
+ @classmethod
+ def _db_create(cls, execute, ext=""):
+ execute(f"""
+ CREATE TABLE results_table_data{ext} (
+ {cls.create_db_add_pamhyr_id()},
+ result INTEGER NOT NULL,
+ legend TEXT NOT NULL,
+ unit TEXT NOT NULL,
+ data_shape_x INTEGER NOT NULL,
+ data_shape_y INTEGER NOT NULL,
+ data_shape_z INTEGER DEFAULT -1,
+ data BLOB NOT NULL,
+ {Scenario.create_db_add_scenario()},
+ {Scenario.create_db_add_scenario_fk()},
+ FOREIGN KEY(result) REFERENCES results(pamhyr_id),
+ PRIMARY KEY(pamhyr_id, result, legend, scenario)
+ )
+ """)
+
+ if ext != "":
+ return True
+
+ return cls._create_submodel(execute)
+
+ @classmethod
+ def _db_update(cls, execute, version, data=None):
+ major, minor, release = version.strip().split(".")
+ create = False
+
+ if major == "0" and int(minor) == 2:
+ if int(release) < 7 and not create:
+ cls._db_create(execute)
+ create = True
+
+ return cls._update_submodel(execute, version, data)
+
+ @classmethod
+ def _db_load(cls, execute, data=None):
+ res = {}
+
+ study = data['study']
+ status = data['status']
+ scenario = data["scenario"]
+ result = data["result"]
+ rid = data["result_pid"]
+
+ table = execute(
+ "SELECT pamhyr_id, " +
+ "legend, unit, " +
+ "data_shape_x, data_shape_y, data_shape_z, " +
+ "data, " +
+ "scenario " +
+ "FROM results_table_data " +
+ f"WHERE scenario = {scenario.id} " +
+ f"AND result = {rid}"
+ )
+
+ for v in table:
+ it = iter(v)
+
+ pid = next(it)
+ legend = next(it)
+ unit = next(it)
+ data_shape_x = next(it)
+ data_shape_y = next(it)
+ data_shape_z = next(it)
+ data = next(it)
+ owner_scenario = next(it)
+
+ dtype = cls._unit_to_dtype(unit)
+
+ np_data = np.frombuffer(data, dtype=dtype)
+ if data_shape_y == -1:
+ np_data = np.reshape(np_data, data_shape_x)
+ elif data_shape_z == -1:
+ np_data = np.reshape(np_data, (data_shape_x,
+ data_shape_y))
+ else:
+ np_data = np.reshape(np_data, (data_shape_x,
+ data_shape_y,
+ data_shape_z))
+
+ new_table = cls(study=study,
+ legend=legend, data=np_data,
+ owner_scenario=owner_scenario)
+
+ res[legend] = new_table
+
+ return res
+
+ def _db_save(self, execute, data=None):
+ if self._status.scenario.id != self._owner_scenario:
+ return
+
+ shape_x = -1
+ shape_y = -1
+ shape_z = -1
+ shape = self._data.shape
+
+ if len(shape) == 2:
+ shape_x, shape_y = shape
+ elif len(shape == 1):
+ shape_x, = shape
+ elif len(shape == 3):
+ shape_x, shape_y, shape_z = shape
+ else:
+ logger.error(
+ f"Failed to parse numpy shape: {shape}"
+ )
+
+ execute(
+ "INSERT INTO " +
+ "results_table_data (pamhyr_id, result, " +
+ "legend, unit, " +
+ "data_shape_x, data_shape_y, data_shape_z, " +
+ "data, " +
+ "scenario) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ self._pamhyr_id, data["result"],
+ self._legend, self._dtype_to_unit(self._data.dtype),
+ shape_x, shape_y, shape_z,
+ self._data,
+ self._owner_scenario
+ )
+
+ return True
+
+ @classmethod
+ def _unit_to_dtype(cls, unit):
+ t = {
+ "i32": np.int32, "i64": np.int64,
+ "u32": np.uint32, "u64": np.uint64,
+ "f32": np.float32, "f64": np.float64,
+ }
+
+ return t[unit]
+
+ def _dtype_to_unit(self, dtype):
+ t = {
+ np.dtype(np.int32): "i32", np.dtype(np.int64): "i64",
+ np.dtype(np.uint32): "u32", np.dtype(np.uint64): "u64",
+ np.dtype(np.float32): "f32", np.dtype(np.float64): "f64",
+ }
+
+ return t[dtype]
+
+ def table(self):
+ return self._data
+
+ def __len__(self):
+ return len(self._data)
+
+ def __getitem__(self, key):
+ if isinstance(key, tuple):
+ return self._data[key[0], key[1]]
+
+ self._date[key]
+
+
class Results(SQLSubModel):
- _sub_classes = [River, AdditionalData]
+ _sub_classes = [River, TableData, AdditionalData]
def __init__(self, id=-1, study=None, solver=None,
repertory="", name="0"):
@@ -167,7 +346,7 @@ class Results(SQLSubModel):
self._name = name
self._study = study
- self._river = River(self._study)
+ self._river = River(self._study, self)
self._solver = solver
self._repertory = repertory
@@ -177,8 +356,11 @@ class Results(SQLSubModel):
"creation_date": datetime.now(),
"study_revision": study.status.version,
"additional_data": [],
+ "table": {},
}
+ self._ts_index = {}
+
if solver is not None:
self.set("solver_type", solver._type)
@@ -195,6 +377,7 @@ class Results(SQLSubModel):
def study(self):
return self._study
+ @timer
def set(self, key, value):
self._meta_data[key] = value
@@ -212,6 +395,16 @@ class Results(SQLSubModel):
def get(self, key):
return self._meta_data[key]
+ def set_timestamp_index(self, index):
+ self._ts_index = index
+
+ def get_timestamp_id(self, ts):
+ return self._ts_index[ts]
+
+ def compute_timestamp_index(self):
+ for i, ts in enumerate(self._meta_data["timestamps"]):
+ self._ts_index[ts] = i
+
def reload(self):
return self._solver.results(
self._study,
@@ -309,11 +502,20 @@ class Results(SQLSubModel):
new_results.set("study_revision", revision)
new_results.set("creation_date", creation_date)
+ data["result_pid"] = pid
+ data["result"] = new_results
+
+ table_data = TableData._db_load(execute, data)
+ new_results.set("table", table_data)
+
sf = ">" + ''.join(itertools.repeat("d", nb_timestamps))
ts = struct.unpack(sf, timestamps_bytes)
new_results.set("timestamps", ts)
data["timestamps"] = sorted(ts)
+ new_results.compute_timestamp_index()
+
+ data["parent"] = new_results
new_results._river = River._db_load(execute, data)
new_results.set(
@@ -321,6 +523,20 @@ class Results(SQLSubModel):
AdditionalData._db_load(execute, data)
)
+ # Update global index
+ i = 0
+ for reach in new_results._river.reachs:
+ nb = len(reach.profiles)
+ reach.set_global_index(range(i, i + nb + 1))
+ i += nb
+
+ if "Z" in table_data:
+ for ts in data["timestamps"]:
+ new_results._river.update_water_limits(
+ ts,
+ table_data["Z"][new_results.get_timestamp_id(ts), :]
+ )
+
yield (solver_type, new_results)
def _db_save_clear(self, execute, solver_type, data=None):
@@ -343,6 +559,11 @@ class Results(SQLSubModel):
f"WHERE scenario = {self._owner_scenario} " +
f"AND result = {pid}"
)
+ execute(
+ "DELETE FROM results_table_data " +
+ f"WHERE scenario = {self._owner_scenario} " +
+ f"AND result = {pid}"
+ )
execute(
"DELETE FROM results_add_data " +
f"WHERE scenario = {self._owner_scenario} " +
@@ -386,7 +607,19 @@ class Results(SQLSubModel):
data["result"] = self._pamhyr_id
self._river._db_save(execute, data)
+ tables = self.get("table")
+ for legend in tables:
+ tables[legend]._db_save(execute, data)
+
for add_data in self.get("additional_data"):
add_data._db_save(execute, data)
return True
+
+ def new_table_data(self, legend, data):
+ return TableData(
+ study=self._study,
+ legend=legend,
+ data=data,
+ owner_scenario=self._owner_scenario
+ )
diff --git a/src/Model/Results/ResultsAdisTS.py b/src/Model/Results/ResultsAdisTS.py
index d5672e57..1aad7873 100644
--- a/src/Model/Results/ResultsAdisTS.py
+++ b/src/Model/Results/ResultsAdisTS.py
@@ -1,5 +1,5 @@
# Results.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Results/River/River.py b/src/Model/Results/River/River.py
index d1d3027b..6e32b7a3 100644
--- a/src/Model/Results/River/River.py
+++ b/src/Model/Results/River/River.py
@@ -1,5 +1,5 @@
# River.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -14,12 +14,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+import types
import struct
import logging
import itertools
import numpy as np
-from tools import flatten
+from tools import flatten, timer
from functools import reduce
from datetime import datetime
@@ -30,15 +31,17 @@ logger = logging.getLogger()
class Profile(SQLSubModel):
- def __init__(self, profile, study):
+ def __init__(self, profile, study, parent):
super(Profile, self).__init__(
id=-1, status=study.status,
owner_scenario=study.status.scenario.id
)
+ self._parent = parent
self._study = study
self._profile = profile # Source profile in the study
self._data = {} # Dict of dict {: {: , ...}, ...}
+ self._global_index = -1
def __len__(self):
return len(self._data)
@@ -55,15 +58,26 @@ class Profile(SQLSubModel):
def geometry(self):
return self._profile
+ @property
+ def global_index(self):
+ return self._global_index
+
+ @global_index.setter
+ def global_index(self, id):
+ self._global_index = id
+
+ @timer
def set(self, timestamp, key, data):
if timestamp not in self._data:
self._data[timestamp] = {}
self._data[timestamp][key] = data
+ @timer
def get_ts(self, timestamp):
return self._data[timestamp]
+ @timer
def get_key(self, key):
res = list(
map(lambda ts: self._data[ts][key],
@@ -71,17 +85,26 @@ class Profile(SQLSubModel):
)
return res
+ @timer
def get_ts_key(self, timestamp, key):
if timestamp in self._data:
if key in self._data[timestamp]:
- return self._data[timestamp][key]
+ v = self._data[timestamp][key]
+
+ # If is a generator, compute value(s)
+ if isinstance(v, types.GeneratorType):
+ v = next(v)
+ self._data[timestamp][key] = v
+
+ return v
+
return None
def has_sediment_layers(self):
return any(map(lambda ts: "sl" in self._data[ts], self._data))
def has_bedload(self):
- return any(map(lambda ts: "zfd" in self._data[ts], self._data))
+ return any(map(lambda ts: "sl" in self._data[ts], self._data))
@classmethod
def _db_create(cls, execute, ext=""):
@@ -114,9 +137,9 @@ class Profile(SQLSubModel):
@classmethod
def _db_load(cls, execute, data=None):
- new = {}
status = data['status']
+ parent = data['parent']
study = data['study']
reach = data['reach']
profile = data['profile']
@@ -124,6 +147,8 @@ class Profile(SQLSubModel):
loaded = data['loaded_pid']
timestamps = data['timestamps']
+ new = cls(profile, study, parent)
+
values = execute(
"SELECT pamhyr_id, result, key, " +
"len_data, data, scenario " +
@@ -143,12 +168,6 @@ class Profile(SQLSubModel):
data = next(it)
owner_scenario = next(it)
- if profile not in new:
- new_data = cls(profile, study)
- new[profile] = new_data
- else:
- new_data = new[profile]
-
if key in ["Z", "Q", "V"]:
sf = ">" + ''.join(itertools.repeat("f", len_data))
len_values = len(values)
@@ -161,11 +180,11 @@ class Profile(SQLSubModel):
)
for timestamp, value in zip(timestamps, values):
- new_data.set(timestamp, key, value)
+ new.set(timestamp, key, value)
if key == "Z":
- new_data.update_water_limits(timestamp, value)
+ new.update_water_limits(timestamp, value)
- return list(new.values())
+ return new
@classmethod
def _db_load_data_sl_format(cls, values, len_data, timestamps):
@@ -257,19 +276,20 @@ class Profile(SQLSubModel):
class Reach(SQLSubModel):
_sub_classes = [Profile]
- def __init__(self, reach, study, with_init=True):
+ def __init__(self, reach, study, parent, with_init=True):
super(Reach, self).__init__(
id=-1, status=study.status,
owner_scenario=study.status.scenario.id
)
+ self._parent = parent
self._study = study
self._reach = reach # Source reach in the study
self._profiles = []
if with_init:
self._profiles = list(
map(
- lambda p: Profile(p, self._study),
+ lambda p: Profile(p, self._study, self._parent),
reach.profiles
)
)
@@ -279,6 +299,9 @@ class Reach(SQLSubModel):
lambda p: p.name[0:8] != 'interpol', self._profiles
)
)
+
+ self._global_index = (-1, -1)
+
self._buffers = {}
def __len__(self):
@@ -307,6 +330,17 @@ class Reach(SQLSubModel):
def profile(self, id):
return self._profiles[id]
+ def set_global_index(self, indexs):
+ self._global_index = (indexs[0], indexs[-1])
+
+ for profile, ind in zip(self._profiles, indexs):
+ profile.global_index = ind
+
+ @property
+ def global_index(self):
+ return self._global_index
+
+ @timer
def set(self, profile_id, timestamp, key, data):
self._profiles[profile_id].set(timestamp, key, data)
@@ -322,6 +356,10 @@ class Reach(SQLSubModel):
for i, p in enumerate(self._profiles):
self._buffers[key][:, i] = p.get_key(key)
+ def update_water_limits(self, timestamp, z_data):
+ for profile, z in zip(self._profiles, z_data):
+ profile.update_water_limits(timestamp, z)
+
@classmethod
def _db_create(cls, execute, ext=""):
return cls._create_submodel(execute)
@@ -335,12 +373,13 @@ class Reach(SQLSubModel):
reach = data["reach"]
new_reach = cls(
- data["reach"], data["study"], with_init=False
+ data["reach"], data["study"], data["parent"],
+ with_init=False
)
for i, profile in enumerate(reach.profiles):
data["profile"] = profile
- new_reach._profiles += Profile._db_load(execute, data)
+ new_reach._profiles += [Profile._db_load(execute, data)]
return new_reach
@@ -354,13 +393,14 @@ class Reach(SQLSubModel):
class River(SQLSubModel):
_sub_classes = [Reach]
- def __init__(self, study):
+ def __init__(self, study, parent):
super(River, self).__init__(
id=-1, status=study.status,
owner_scenario=study.status.scenario.id
)
self._study = study
+ self._parent = parent
# Dict with timestamps as key
self._reachs = []
@@ -381,7 +421,7 @@ class River(SQLSubModel):
def add(self, reach_id):
reachs = self._study.river.enable_edges()
- new = Reach(reachs[reach_id].reach, self._study)
+ new = Reach(reachs[reach_id].reach, self._study, self._parent)
self._reachs.append(new)
return new
@@ -394,6 +434,15 @@ class River(SQLSubModel):
)
)
+ def update_water_limits(self, timestamp, data):
+ for reach in self._reachs:
+ ind = reach.global_index
+
+ reach.update_water_limits(
+ timestamp,
+ data[ind[0]:ind[1]]
+ )
+
@classmethod
def _db_create(cls, execute, ext=""):
return cls._create_submodel(execute)
@@ -405,7 +454,9 @@ class River(SQLSubModel):
@classmethod
def _db_load(cls, execute, data=None):
study = data["study"]
- new_river = cls(study)
+ parent = data["parent"]
+
+ new_river = cls(study, parent)
for reach in study.river.reachs():
data["reach"] = reach.reach
diff --git a/src/Model/Results/River/RiverAdisTS.py b/src/Model/Results/River/RiverAdisTS.py
index 58e73bd8..91ffcc14 100644
--- a/src/Model/Results/River/RiverAdisTS.py
+++ b/src/Model/Results/River/RiverAdisTS.py
@@ -1,5 +1,5 @@
# River.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/River.py b/src/Model/River.py
index 58d93cd5..ce16b7ea 100644
--- a/src/Model/River.py
+++ b/src/Model/River.py
@@ -1,5 +1,5 @@
# River.py -- Pamhyr river model
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Serializable.py b/src/Model/Serializable.py
index 42e8c2f6..e8c613a1 100644
--- a/src/Model/Serializable.py
+++ b/src/Model/Serializable.py
@@ -1,5 +1,5 @@
# Serializable.py -- Pamhyr pickle abstract class
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/SolverParameters/SolverParametersList.py b/src/Model/SolverParameters/SolverParametersList.py
index 94bae66a..a0054d8b 100644
--- a/src/Model/SolverParameters/SolverParametersList.py
+++ b/src/Model/SolverParameters/SolverParametersList.py
@@ -1,5 +1,5 @@
# SolverParametersList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Status.py b/src/Model/Status.py
index a0714c28..eaa1e1a7 100644
--- a/src/Model/Status.py
+++ b/src/Model/Status.py
@@ -1,5 +1,5 @@
# Status.py -- Pamhyr model status class
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Stricklers/Stricklers.py b/src/Model/Stricklers/Stricklers.py
index ed69eade..1f6568e2 100644
--- a/src/Model/Stricklers/Stricklers.py
+++ b/src/Model/Stricklers/Stricklers.py
@@ -1,5 +1,5 @@
# Stricklers.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Stricklers/StricklersList.py b/src/Model/Stricklers/StricklersList.py
index 805bf799..2c379d90 100644
--- a/src/Model/Stricklers/StricklersList.py
+++ b/src/Model/Stricklers/StricklersList.py
@@ -1,5 +1,5 @@
# StricklersList.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Study.py b/src/Model/Study.py
index 2be1069c..ded212ba 100644
--- a/src/Model/Study.py
+++ b/src/Model/Study.py
@@ -1,5 +1,5 @@
# Study.py -- Pamhyr Study class
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@ logger = logging.getLogger()
class Study(SQLModel):
- _version = "0.2.6"
+ _version = "0.2.7"
_sub_classes = [
Scenario,
diff --git a/src/Model/Tools/PamhyrDB.py b/src/Model/Tools/PamhyrDB.py
index 1db1e36d..a9d95cfe 100644
--- a/src/Model/Tools/PamhyrDB.py
+++ b/src/Model/Tools/PamhyrDB.py
@@ -1,5 +1,5 @@
# PamhyrDB.py -- Pamhyr abstract model database classes
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Tools/PamhyrDict.py b/src/Model/Tools/PamhyrDict.py
index 7bddc1c8..fbff4994 100644
--- a/src/Model/Tools/PamhyrDict.py
+++ b/src/Model/Tools/PamhyrDict.py
@@ -1,5 +1,5 @@
# PamhyrDict.py -- Pamhyr abstract dict for model classes
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Tools/PamhyrList.py b/src/Model/Tools/PamhyrList.py
index a97f869a..4497463a 100644
--- a/src/Model/Tools/PamhyrList.py
+++ b/src/Model/Tools/PamhyrList.py
@@ -1,5 +1,5 @@
# PamhyrList.py -- Pamhyr Abstract List object for the Model
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/Tools/PamhyrListExt.py b/src/Model/Tools/PamhyrListExt.py
index f27ce1e8..d7c68586 100644
--- a/src/Model/Tools/PamhyrListExt.py
+++ b/src/Model/Tools/PamhyrListExt.py
@@ -1,5 +1,5 @@
# PamhyrList.py -- Pamhyr Abstract List object for the Model
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/__init__.py b/src/Model/__init__.py
index bf12a7a6..761264ea 100644
--- a/src/Model/__init__.py
+++ b/src/Model/__init__.py
@@ -1,5 +1,5 @@
# __init__.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Model/test_Model.py b/src/Model/test_Model.py
index c9d1835b..4b8e77a0 100644
--- a/src/Model/test_Model.py
+++ b/src/Model/test_Model.py
@@ -1,5 +1,5 @@
# test_Model.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/SQL.py b/src/SQL.py
index 7c07d0dc..71987314 100644
--- a/src/SQL.py
+++ b/src/SQL.py
@@ -1,5 +1,5 @@
# SQL.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Scripts/AScript.py b/src/Scripts/AScript.py
index ca985e2f..e5fc33ea 100644
--- a/src/Scripts/AScript.py
+++ b/src/Scripts/AScript.py
@@ -1,5 +1,5 @@
# AScript.py -- Pamhyr abstract script class
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Scripts/Hello.py b/src/Scripts/Hello.py
index c51a8c32..c2bac118 100644
--- a/src/Scripts/Hello.py
+++ b/src/Scripts/Hello.py
@@ -1,5 +1,5 @@
# Hello.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Scripts/ListSolver.py b/src/Scripts/ListSolver.py
index 00056a6e..3e4f1d79 100644
--- a/src/Scripts/ListSolver.py
+++ b/src/Scripts/ListSolver.py
@@ -1,5 +1,5 @@
# ListSolver.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Scripts/MageMesh.py b/src/Scripts/MageMesh.py
index 92f4d162..ed0a4d6d 100644
--- a/src/Scripts/MageMesh.py
+++ b/src/Scripts/MageMesh.py
@@ -1,5 +1,5 @@
# MageMesh.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Scripts/P3DST.py b/src/Scripts/P3DST.py
index 7457a540..735999cc 100644
--- a/src/Scripts/P3DST.py
+++ b/src/Scripts/P3DST.py
@@ -1,5 +1,5 @@
# P3DST.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Scripts/Run.py b/src/Scripts/Run.py
index 24359a7d..04cb28d7 100644
--- a/src/Scripts/Run.py
+++ b/src/Scripts/Run.py
@@ -1,5 +1,5 @@
# Run.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Scripts/mage_to_mascaret.py b/src/Scripts/mage_to_mascaret.py
index cbc40325..d25ee3a3 100755
--- a/src/Scripts/mage_to_mascaret.py
+++ b/src/Scripts/mage_to_mascaret.py
@@ -1,3 +1,20 @@
+# mage_to_mascaret.py -- Pamhyr
+# Copyright (C) 2026 INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# -*- coding: utf-8 -*-
#!/bin/env python3
import sys
@@ -336,6 +353,3 @@ if __name__ == "__main__":
print( 'Number of arguments:', len(sys.argv), 'arguments.')
print( 'Argument List:', str(sys.argv))
mage_to_mascaret(sys.argv[1])
-
-
-
diff --git a/src/Scripts/mascaret_to_mage.py b/src/Scripts/mascaret_to_mage.py
index 9942132b..274fe39b 100755
--- a/src/Scripts/mascaret_to_mage.py
+++ b/src/Scripts/mascaret_to_mage.py
@@ -1,3 +1,20 @@
+# mascaret_to_mage.py -- Pamhyr
+# Copyright (C) 2026 INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# -*- coding: utf-8 -*-
#!/bin/env python3
import sys
diff --git a/src/Solver/ASolver.py b/src/Solver/ASolver.py
index 5d0578d2..aeea0b1b 100644
--- a/src/Solver/ASolver.py
+++ b/src/Solver/ASolver.py
@@ -1,5 +1,5 @@
# ASolver.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Solver/AdisTS.py b/src/Solver/AdisTS.py
index 309153a7..6f2580bf 100644
--- a/src/Solver/AdisTS.py
+++ b/src/Solver/AdisTS.py
@@ -1,5 +1,5 @@
# AdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Solver/CommandLine.py b/src/Solver/CommandLine.py
index 0c08244d..c908ffce 100644
--- a/src/Solver/CommandLine.py
+++ b/src/Solver/CommandLine.py
@@ -1,5 +1,5 @@
# CommandLine.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Solver/GenericSolver.py b/src/Solver/GenericSolver.py
index d20e5e66..d47c34be 100644
--- a/src/Solver/GenericSolver.py
+++ b/src/Solver/GenericSolver.py
@@ -1,5 +1,5 @@
# GenericSolver.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/Solver/Mage.py b/src/Solver/Mage.py
index f78bbdbc..3ad490ae 100644
--- a/src/Solver/Mage.py
+++ b/src/Solver/Mage.py
@@ -1,5 +1,5 @@
# Mage.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -1083,7 +1083,7 @@ class Mage8(Mage):
newline()
reachs = []
- iprofiles = {}
+ iprofiles = []
profile_len = []
reach_offset = {}
@@ -1098,15 +1098,18 @@ class Mage8(Mage):
i1 = data[2*i] - 1
i2 = data[2*i+1] - 1
+ # Keep profiles index of all river
+ r.set_global_index(range(i1, i2 + 1))
+
# Add profile id correspondance to reach
- key = (i1, i2)
- iprofiles[key] = r
+ for key in range(i1, i2 + 1):
+ iprofiles.append(i)
# Profile ID offset
reach_offset[r] = i1
- profile_len.append(i2-i1+1)
+ profile_len.append(i2 - i1 + 1)
- logger.debug(f"read_bin: iprofiles = {iprofiles}")
+ logger.debug(f"read_bin: iprofiles = {len(iprofiles)}")
endline()
@@ -1124,16 +1127,6 @@ class Mage8(Mage):
# Data
newline()
- def ip_to_r(i): return iprofiles[
- next(
- filter(
- lambda k: k[0] <= i <= k[1],
- iprofiles
- )
- )
- ]
- def ip_to_ri(r, i): return i - reach_offset[r]
-
# check results and geometry consistency
for i, r in enumerate(reachs):
lp = len(r.profiles)
@@ -1144,6 +1137,8 @@ class Mage8(Mage):
return
ts = set()
+ tmp_table = {}
+
end = False
while not end:
n = read_int(1)[0]
@@ -1152,18 +1147,21 @@ class Mage8(Mage):
f, dtype=np.byte, count=1)).decode()
data = read_float(n)
- # logger.debug(f"read_bin: timestamp = {timestamp} sec")
+ if key not in tmp_table:
+ tmp_table[key] = []
+
+ tmp_table[key].append(data)
ts.add(timestamp)
if key in ["Z", "Q"]:
for i, d in enumerate(data):
# Get reach corresponding to profile ID
- reach = ip_to_r(i)
+ reach = reachs[iprofiles[i]]
# Get profile id in reach
- ri = ip_to_ri(reach, i)
+ ri = i - reach_offset[reach]
# Set data for profile RI
- reach.set(ri, timestamp, key, d)
+ # reach.set(ri, timestamp, key, d)
if key == "Z":
profile = reach.profile(ri)
limits = profile.geometry.get_water_limits(d)
@@ -1176,6 +1174,15 @@ class Mage8(Mage):
endline()
end = newline().size <= 0
+ ts_index = {}
+ for i, t in enumerate(sorted(ts)):
+ ts_index[t] = i
+ results.set_timestamp_index(ts_index)
+
+ table = {}
+ for k in tmp_table:
+ table[k] = np.array(tmp_table[k])
+
results.set("timestamps", ts)
ts_list = sorted(ts)
logger.info(f"compute tab...")
@@ -1185,19 +1192,33 @@ class Mage8(Mage):
logger.info(f"compute velocity...")
- for r in reachs:
- for t in ts_list:
- for i, p in enumerate(r.profiles):
+ velocity_arr = np.zeros((len(ts), len(iprofiles)))
+ for ti, t in enumerate(ts_list):
+ j = 0
+ for r in reachs:
+ for pi, p in enumerate(r.profiles):
v = p.geometry.speed(
- p.get_ts_key(t, "Q"),
- p.get_ts_key(t, "Z")
+ table["Q"][ti, p.global_index],
+ table["Z"][ti, p.global_index],
)
- r.set(i, t, "V", v)
+ # r.set(pi, t, "V", v)
+ velocity_arr[ti, j] = v
+ j += 1
+
+ table["V"] = velocity_arr
+
+ for legend in table:
+ table[legend] = results.new_table_data(
+ legend, table[legend]
+ )
+
+ results.set("table", table)
+
logger.info(f"read_bin: ... end with {len(ts)} timestamp read")
- results.bufferize("Z")
- results.bufferize("Q")
- results.bufferize("V")
+ # results.bufferize("Z")
+ # results.bufferize("Q")
+ # results.bufferize("V")
logger.info(f"reading time: '{time.time() - start}'")
@timer
@@ -1267,8 +1288,8 @@ class Mage8(Mage):
reachs.append(r)
# ID of first and last reach profiles
- i1 = data[2*i] - 1
- i2 = data[2*i+1] - 1
+ i1 = data[2 * i] - 1
+ i2 = data[2 * i + 1] - 1
# Add profile id correspondance to reach
key = (i1, i2)
@@ -1322,6 +1343,7 @@ class Mage8(Mage):
newline()
npts = read_int(n)
endline()
+
sum_npts = sum(npts)
logger.debug(f"read_gra: Number of points: {sum_npts}")
@@ -1371,35 +1393,42 @@ class Mage8(Mage):
logger.info(f"compute river bed elevation...")
+ zfd_lst = []
+
for r in reachs:
z_min = r.geometry.get_z_min()
- sls = list(map(
+ sls = map(
lambda p: p.get_ts_key(ts_list[0], "sl")[0],
r.profiles
- ))
+ )
z_br = list(map(
- lambda z, sl: reduce(
- lambda z, h: z - h[0],
- sl, z
- ),
- z_min, # Original geometry
- sls # Original sediment layers
- ))
- for t in ts_list:
- sls = list(map(
+ lambda z, sl: reduce(
+ lambda z, h: z - h[0],
+ sl, z
+ ),
+ z_min, # Original geometry
+ sls # Original sediment layers
+ ))
+ for its, t in enumerate(ts_list):
+ sls = map(
lambda p: p.get_ts_key(t, "sl")[0],
r.profiles
- ))
+ )
zfd = list(map(
- lambda z, sl: reduce(
- lambda z, h: z + h[0],
- sl, z
- ),
- z_br, # bedrock
- sls # Original sediment layers
- ))
- for i, p in enumerate(r.profiles):
- r.set(i, t, "zfd", zfd[i])
+ lambda z, sl: reduce(
+ lambda z, h: z + h[0],
+ sl, z
+ ),
+ z_br, # bedrock
+ sls # Original sediment layers
+ ))
+
+ zfd_lst.append(np.array(zfd))
+
+ table = results.get("table")
+ table["zfd"] = results.new_table_data(
+ "zfd", np.array(zfd_lst)
+ )
results.set("sediment_timestamps", ts)
logger.info(f"read_gra: ... end with {len(ts)} timestamp read")
diff --git a/src/Solver/Solvers.py b/src/Solver/Solvers.py
index f6fb93b6..e33b3203 100644
--- a/src/Solver/Solvers.py
+++ b/src/Solver/Solvers.py
@@ -1,5 +1,5 @@
# Solvers.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/About/Window.py b/src/View/About/Window.py
index ffc2db8e..c10f8a03 100644
--- a/src/View/About/Window.py
+++ b/src/View/About/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/Edit/GenerateDialog.py b/src/View/BoundaryCondition/Edit/GenerateDialog.py
index 1c1faab0..62267c45 100644
--- a/src/View/BoundaryCondition/Edit/GenerateDialog.py
+++ b/src/View/BoundaryCondition/Edit/GenerateDialog.py
@@ -1,5 +1,5 @@
# GenerateDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/Edit/Plot.py b/src/View/BoundaryCondition/Edit/Plot.py
index 31b25f9b..badcb96a 100644
--- a/src/View/BoundaryCondition/Edit/Plot.py
+++ b/src/View/BoundaryCondition/Edit/Plot.py
@@ -1,5 +1,5 @@
# Plot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/Edit/Table.py b/src/View/BoundaryCondition/Edit/Table.py
index eec7cbcd..5a73fd78 100644
--- a/src/View/BoundaryCondition/Edit/Table.py
+++ b/src/View/BoundaryCondition/Edit/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/Edit/UndoCommand.py b/src/View/BoundaryCondition/Edit/UndoCommand.py
index 986b4b73..06b598a1 100644
--- a/src/View/BoundaryCondition/Edit/UndoCommand.py
+++ b/src/View/BoundaryCondition/Edit/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/Edit/Window.py b/src/View/BoundaryCondition/Edit/Window.py
index d86eb4ac..29281d6f 100644
--- a/src/View/BoundaryCondition/Edit/Window.py
+++ b/src/View/BoundaryCondition/Edit/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/Edit/translate.py b/src/View/BoundaryCondition/Edit/translate.py
index de4ab4d6..d4beb7f9 100644
--- a/src/View/BoundaryCondition/Edit/translate.py
+++ b/src/View/BoundaryCondition/Edit/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/Table.py b/src/View/BoundaryCondition/Table.py
index a1fa14cb..2c9fa7df 100644
--- a/src/View/BoundaryCondition/Table.py
+++ b/src/View/BoundaryCondition/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/UndoCommand.py b/src/View/BoundaryCondition/UndoCommand.py
index c9c110f3..69891557 100644
--- a/src/View/BoundaryCondition/UndoCommand.py
+++ b/src/View/BoundaryCondition/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/Window.py b/src/View/BoundaryCondition/Window.py
index 199d15e3..c905fb49 100644
--- a/src/View/BoundaryCondition/Window.py
+++ b/src/View/BoundaryCondition/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryCondition/translate.py b/src/View/BoundaryCondition/translate.py
index 30afd90f..0c9d3348 100644
--- a/src/View/BoundaryCondition/translate.py
+++ b/src/View/BoundaryCondition/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/Edit/Plot.py b/src/View/BoundaryConditionsAdisTS/Edit/Plot.py
index b320be27..ca7a1197 100644
--- a/src/View/BoundaryConditionsAdisTS/Edit/Plot.py
+++ b/src/View/BoundaryConditionsAdisTS/Edit/Plot.py
@@ -1,5 +1,5 @@
# Plot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/Edit/Table.py b/src/View/BoundaryConditionsAdisTS/Edit/Table.py
index a61aabfc..eeba2689 100644
--- a/src/View/BoundaryConditionsAdisTS/Edit/Table.py
+++ b/src/View/BoundaryConditionsAdisTS/Edit/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/Edit/UndoCommand.py b/src/View/BoundaryConditionsAdisTS/Edit/UndoCommand.py
index 1319a105..c831660c 100644
--- a/src/View/BoundaryConditionsAdisTS/Edit/UndoCommand.py
+++ b/src/View/BoundaryConditionsAdisTS/Edit/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/Edit/Window.py b/src/View/BoundaryConditionsAdisTS/Edit/Window.py
index fac2cf4a..5db1f226 100644
--- a/src/View/BoundaryConditionsAdisTS/Edit/Window.py
+++ b/src/View/BoundaryConditionsAdisTS/Edit/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/Edit/translate.py b/src/View/BoundaryConditionsAdisTS/Edit/translate.py
index 64cf8fea..341533e8 100644
--- a/src/View/BoundaryConditionsAdisTS/Edit/translate.py
+++ b/src/View/BoundaryConditionsAdisTS/Edit/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/Table.py b/src/View/BoundaryConditionsAdisTS/Table.py
index 5f78881d..9af02ff4 100644
--- a/src/View/BoundaryConditionsAdisTS/Table.py
+++ b/src/View/BoundaryConditionsAdisTS/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/UndoCommand.py b/src/View/BoundaryConditionsAdisTS/UndoCommand.py
index 63a340ee..84398088 100644
--- a/src/View/BoundaryConditionsAdisTS/UndoCommand.py
+++ b/src/View/BoundaryConditionsAdisTS/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/Window.py b/src/View/BoundaryConditionsAdisTS/Window.py
index 202c2367..8db0e072 100644
--- a/src/View/BoundaryConditionsAdisTS/Window.py
+++ b/src/View/BoundaryConditionsAdisTS/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/BoundaryConditionsAdisTS/translate.py b/src/View/BoundaryConditionsAdisTS/translate.py
index 590c3511..1513f490 100644
--- a/src/View/BoundaryConditionsAdisTS/translate.py
+++ b/src/View/BoundaryConditionsAdisTS/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/CheckList/Table.py b/src/View/CheckList/Table.py
index abbe1388..5681a9db 100644
--- a/src/View/CheckList/Table.py
+++ b/src/View/CheckList/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/CheckList/Translate.py b/src/View/CheckList/Translate.py
index 17ff68bd..8f9ddac2 100644
--- a/src/View/CheckList/Translate.py
+++ b/src/View/CheckList/Translate.py
@@ -1,5 +1,5 @@
# Translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/CheckList/Window.py b/src/View/CheckList/Window.py
index 7ff6f657..70802d9f 100644
--- a/src/View/CheckList/Window.py
+++ b/src/View/CheckList/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/CheckList/WindowAdisTS.py b/src/View/CheckList/WindowAdisTS.py
index dfd40b57..b0780801 100644
--- a/src/View/CheckList/WindowAdisTS.py
+++ b/src/View/CheckList/WindowAdisTS.py
@@ -1,5 +1,5 @@
# WindowAdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/CheckList/Worker.py b/src/View/CheckList/Worker.py
index 465f85b8..ab501732 100644
--- a/src/View/CheckList/Worker.py
+++ b/src/View/CheckList/Worker.py
@@ -1,5 +1,5 @@
# Worker.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Configure/Solver/Window.py b/src/View/Configure/Solver/Window.py
index e15b1f1e..06b015af 100644
--- a/src/View/Configure/Solver/Window.py
+++ b/src/View/Configure/Solver/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Configure/Translate.py b/src/View/Configure/Translate.py
index 3f28fa67..89db54f4 100644
--- a/src/View/Configure/Translate.py
+++ b/src/View/Configure/Translate.py
@@ -1,5 +1,5 @@
# Translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Configure/Window.py b/src/View/Configure/Window.py
index 35eed9fa..394ddf8b 100644
--- a/src/View/Configure/Window.py
+++ b/src/View/Configure/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/D90AdisTS/Table.py b/src/View/D90AdisTS/Table.py
index 674f2aca..7435ddad 100644
--- a/src/View/D90AdisTS/Table.py
+++ b/src/View/D90AdisTS/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/D90AdisTS/TableDefault.py b/src/View/D90AdisTS/TableDefault.py
index 6ce75396..3bccbf7b 100644
--- a/src/View/D90AdisTS/TableDefault.py
+++ b/src/View/D90AdisTS/TableDefault.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/D90AdisTS/UndoCommand.py b/src/View/D90AdisTS/UndoCommand.py
index 23a2b6ac..33a7b544 100644
--- a/src/View/D90AdisTS/UndoCommand.py
+++ b/src/View/D90AdisTS/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/D90AdisTS/Window.py b/src/View/D90AdisTS/Window.py
index 0f659cf9..20ababb1 100644
--- a/src/View/D90AdisTS/Window.py
+++ b/src/View/D90AdisTS/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/D90AdisTS/translate.py b/src/View/D90AdisTS/translate.py
index c8940272..13303918 100644
--- a/src/View/D90AdisTS/translate.py
+++ b/src/View/D90AdisTS/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/DIFAdisTS/Table.py b/src/View/DIFAdisTS/Table.py
index 33a93e78..5f00da7d 100644
--- a/src/View/DIFAdisTS/Table.py
+++ b/src/View/DIFAdisTS/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/DIFAdisTS/TableDefault.py b/src/View/DIFAdisTS/TableDefault.py
index b16ba796..864e7892 100644
--- a/src/View/DIFAdisTS/TableDefault.py
+++ b/src/View/DIFAdisTS/TableDefault.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/DIFAdisTS/UndoCommand.py b/src/View/DIFAdisTS/UndoCommand.py
index 0939beeb..c6693bd1 100644
--- a/src/View/DIFAdisTS/UndoCommand.py
+++ b/src/View/DIFAdisTS/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/DIFAdisTS/Window.py b/src/View/DIFAdisTS/Window.py
index 1af13eb3..718cc1c3 100644
--- a/src/View/DIFAdisTS/Window.py
+++ b/src/View/DIFAdisTS/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/DIFAdisTS/translate.py b/src/View/DIFAdisTS/translate.py
index 7ed2048c..3f153841 100644
--- a/src/View/DIFAdisTS/translate.py
+++ b/src/View/DIFAdisTS/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Debug/Table.py b/src/View/Debug/Table.py
new file mode 100644
index 00000000..cd9e9d5e
--- /dev/null
+++ b/src/View/Debug/Table.py
@@ -0,0 +1,82 @@
+# Table.py -- Pamhyr
+# Copyright (C) 2026 INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# -*- coding: utf-8 -*-
+
+import logging
+
+from functools import reduce
+from tools import trace, timer, _timers, _calls, reset_timers
+
+from PyQt5.QtCore import (
+ Qt, QVariant, QAbstractTableModel,
+ QCoreApplication, QModelIndex, pyqtSlot,
+ QRect,
+)
+
+from PyQt5.QtWidgets import (
+ QDialogButtonBox, QPushButton, QLineEdit,
+ QFileDialog, QTableView, QAbstractItemView,
+ QUndoStack, QShortcut, QAction, QItemDelegate,
+ QComboBox,
+)
+
+from Modules import Modules
+from View.Tools.PamhyrTable import PamhyrTableModel
+
+logger = logging.getLogger()
+
+
+class TableModel(PamhyrTableModel):
+ def _setup_lst(self):
+ self._lst = sorted(
+ map(
+ lambda f: (
+ f"{f.__module__}.{f.__qualname__}",
+ _timers[f],
+ _calls[f]
+ ),
+ _timers
+ ),
+ key=lambda f: f[1],
+ reverse=True
+ )
+
+ def update_lst(self):
+ self._setup_lst()
+ self.layoutChanged.emit()
+
+ def reset_timers(self):
+ reset_timers()
+ self.update_lst()
+
+ def data(self, index, role):
+ row = index.row()
+ column = index.column()
+
+ if role == Qt.DisplayRole:
+ if self._headers[column] == "name":
+ return self._lst[row][0]
+ elif self._headers[column] == "time":
+ return self._lst[row][1]
+ elif self._headers[column] == "calls":
+ return self._lst[row][2]
+
+ return QVariant()
+
+ def to_csv(self):
+ data = "\n".join(map(lambda x: f"{x[0]},{x[1]},{x[2]}", self._lst))
+ return f"""name,time,calls\n{data}\n"""
diff --git a/src/View/Debug/Window.py b/src/View/Debug/Window.py
index c5f4c720..06931938 100644
--- a/src/View/Debug/Window.py
+++ b/src/View/Debug/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@ from tools import trace, timer
from View.Tools.PamhyrWindow import PamhyrWindow
from View.Tools.PamhyrPythonEditor import PamhyrPythonEditor
+from View.Debug.Table import TableModel
from PyQt5.QtGui import (
QKeySequence,
@@ -31,7 +32,7 @@ from PyQt5.QtGui import (
from PyQt5.QtCore import (
Qt, QVariant, QAbstractTableModel,
QCoreApplication, QModelIndex, QRect, QThread,
- pyqtSlot, pyqtSignal,
+ QTimer, pyqtSlot, pyqtSignal,
)
from PyQt5.QtWidgets import (
@@ -101,3 +102,66 @@ class ReplWindow(PamhyrWindow):
self.find(QTextEdit, "textEdit").append(msg)
# Display results
self.find(QTextEdit, "textEdit").append(str(value))
+
+
+class TimerWindow(PamhyrWindow):
+ _pamhyr_ui = "DebugTimer"
+ _pamhyr_name = "Debug Timer"
+
+ def __init__(self, study=None, config=None,
+ solver=None, parent=None):
+ title = _translate("Debug", "Debug Timer")
+
+ super(TimerWindow, self).__init__(
+ title=title,
+ study=study,
+ config=config,
+ options=[],
+ parent=parent
+ )
+
+ self.setup_table()
+ self.setup_alarm()
+ self.setup_connections()
+
+ def setup_table(self):
+ table = self.find(QTableView, f"tableView")
+ self._table = TableModel(
+ table_view=table,
+ table_headers={
+ "name": "Function name",
+ "time": "Time (sec)",
+ "calls": "Number of calls"
+ },
+ data=None,
+ )
+
+ def setup_alarm(self):
+ self._alarm = QTimer()
+ self._alarm.start(2000)
+
+ def setup_connections(self):
+ # self.find(QAction, "action_reset").triggered.connect(self.reset)
+ self.find(QAction, "action_export").triggered.connect(self.export)
+
+ self._alarm.timeout.connect(self.update)
+
+ def update(self):
+ self._table.update_lst()
+
+ # def reset(self):
+ # self._table.reset_timers()
+
+ def export(self):
+ self.file_dialog(
+ select_file="AnyFile",
+ callback=lambda f: self.export_to(f[0]),
+ default_suffix=".csv",
+ file_filter=["CSV file (*.csv)"],
+ )
+
+ def export_to(self, filename):
+ csv = self._table.to_csv()
+
+ with open(filename, 'w', newline='') as csvfile:
+ csvfile.write(csv)
diff --git a/src/View/Doc/Window.py b/src/View/Doc/Window.py
index 950903c8..41796e93 100644
--- a/src/View/Doc/Window.py
+++ b/src/View/Doc/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/DummyWindow.py b/src/View/DummyWindow.py
index eb24c8e7..371a8f4b 100644
--- a/src/View/DummyWindow.py
+++ b/src/View/DummyWindow.py
@@ -1,5 +1,5 @@
# DummyWindow.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Frictions/PlotRKZ.py b/src/View/Frictions/PlotRKZ.py
index 9e787cbc..751e3514 100644
--- a/src/View/Frictions/PlotRKZ.py
+++ b/src/View/Frictions/PlotRKZ.py
@@ -1,5 +1,5 @@
# PlotRKC.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Frictions/PlotStricklers.py b/src/View/Frictions/PlotStricklers.py
index 9abef064..67341530 100644
--- a/src/View/Frictions/PlotStricklers.py
+++ b/src/View/Frictions/PlotStricklers.py
@@ -1,5 +1,5 @@
# PlotStricklers.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Frictions/Table.py b/src/View/Frictions/Table.py
index c31a85f5..55a42add 100644
--- a/src/View/Frictions/Table.py
+++ b/src/View/Frictions/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Frictions/UndoCommand.py b/src/View/Frictions/UndoCommand.py
index 0f9c3c93..f28ec784 100644
--- a/src/View/Frictions/UndoCommand.py
+++ b/src/View/Frictions/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Frictions/Window.py b/src/View/Frictions/Window.py
index cb3b0827..21018566 100644
--- a/src/View/Frictions/Window.py
+++ b/src/View/Frictions/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Frictions/translate.py b/src/View/Frictions/translate.py
index 3de25fc9..3d094580 100644
--- a/src/View/Frictions/translate.py
+++ b/src/View/Frictions/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/MeshingDialog.py b/src/View/Geometry/MeshingDialog.py
index 4ecb1862..432671d8 100644
--- a/src/View/Geometry/MeshingDialog.py
+++ b/src/View/Geometry/MeshingDialog.py
@@ -1,5 +1,5 @@
# MeshingDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/PlotAC.py b/src/View/Geometry/PlotAC.py
index 9e7127d4..b86ecb0a 100644
--- a/src/View/Geometry/PlotAC.py
+++ b/src/View/Geometry/PlotAC.py
@@ -1,5 +1,5 @@
# PlotAC.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/PlotRKZ.py b/src/View/Geometry/PlotRKZ.py
index c222fdda..3de5ebac 100644
--- a/src/View/Geometry/PlotRKZ.py
+++ b/src/View/Geometry/PlotRKZ.py
@@ -1,5 +1,5 @@
# PlotRKC.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/PlotXY.py b/src/View/Geometry/PlotXY.py
index 5e18a3a0..ecc479a5 100644
--- a/src/View/Geometry/PlotXY.py
+++ b/src/View/Geometry/PlotXY.py
@@ -1,5 +1,5 @@
# PlotXY.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/Profile/Plot.py b/src/View/Geometry/Profile/Plot.py
index c8a948ba..e2829d05 100644
--- a/src/View/Geometry/Profile/Plot.py
+++ b/src/View/Geometry/Profile/Plot.py
@@ -1,5 +1,5 @@
# Plot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/Profile/Table.py b/src/View/Geometry/Profile/Table.py
index e03c4d92..171bc006 100644
--- a/src/View/Geometry/Profile/Table.py
+++ b/src/View/Geometry/Profile/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/Profile/Translate.py b/src/View/Geometry/Profile/Translate.py
index c8dad7d6..46392db1 100644
--- a/src/View/Geometry/Profile/Translate.py
+++ b/src/View/Geometry/Profile/Translate.py
@@ -1,5 +1,5 @@
# Translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/Profile/UndoCommand.py b/src/View/Geometry/Profile/UndoCommand.py
index 9a12e243..92cdaef0 100644
--- a/src/View/Geometry/Profile/UndoCommand.py
+++ b/src/View/Geometry/Profile/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/Profile/Window.py b/src/View/Geometry/Profile/Window.py
index c5a00737..bcafc75c 100644
--- a/src/View/Geometry/Profile/Window.py
+++ b/src/View/Geometry/Profile/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/PurgeDialog.py b/src/View/Geometry/PurgeDialog.py
index eaef3130..1a281621 100644
--- a/src/View/Geometry/PurgeDialog.py
+++ b/src/View/Geometry/PurgeDialog.py
@@ -1,5 +1,5 @@
# PurgeDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/ShiftDialog.py b/src/View/Geometry/ShiftDialog.py
index abc23590..3cfe365b 100644
--- a/src/View/Geometry/ShiftDialog.py
+++ b/src/View/Geometry/ShiftDialog.py
@@ -1,5 +1,5 @@
# ShiftDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/Table.py b/src/View/Geometry/Table.py
index a337624d..a27dd360 100644
--- a/src/View/Geometry/Table.py
+++ b/src/View/Geometry/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/Translate.py b/src/View/Geometry/Translate.py
index 879022eb..10f93bd9 100644
--- a/src/View/Geometry/Translate.py
+++ b/src/View/Geometry/Translate.py
@@ -1,5 +1,5 @@
# Translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/UndoCommand.py b/src/View/Geometry/UndoCommand.py
index 62c5acf6..71e9c313 100644
--- a/src/View/Geometry/UndoCommand.py
+++ b/src/View/Geometry/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/UpdateRKDialog.py b/src/View/Geometry/UpdateRKDialog.py
index 5107f30b..03cd3418 100644
--- a/src/View/Geometry/UpdateRKDialog.py
+++ b/src/View/Geometry/UpdateRKDialog.py
@@ -1,5 +1,5 @@
# UpdateRKDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Geometry/Window.py b/src/View/Geometry/Window.py
index 6eadc4d3..987245a4 100644
--- a/src/View/Geometry/Window.py
+++ b/src/View/Geometry/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py
index 224c2e5b..11ac9696 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py
index 02ac027b..227415d9 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py b/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py
index 69a46547..d729fc90 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py b/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
index 7030360c..9c2644b9 100644
--- a/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
+++ b/src/View/HydraulicStructures/BasicHydraulicStructures/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/PlotAC.py b/src/View/HydraulicStructures/PlotAC.py
index 7a51f66b..7c39ec19 100644
--- a/src/View/HydraulicStructures/PlotAC.py
+++ b/src/View/HydraulicStructures/PlotAC.py
@@ -1,5 +1,5 @@
# PlotAC.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/PlotRKC.py b/src/View/HydraulicStructures/PlotRKC.py
index c36cafaa..4c4a982b 100644
--- a/src/View/HydraulicStructures/PlotRKC.py
+++ b/src/View/HydraulicStructures/PlotRKC.py
@@ -1,5 +1,5 @@
# PlotRKC.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/Table.py b/src/View/HydraulicStructures/Table.py
index a362bf57..5947b9b0 100644
--- a/src/View/HydraulicStructures/Table.py
+++ b/src/View/HydraulicStructures/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/Translate.py b/src/View/HydraulicStructures/Translate.py
index 29730838..9e6bb397 100644
--- a/src/View/HydraulicStructures/Translate.py
+++ b/src/View/HydraulicStructures/Translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/UndoCommand.py b/src/View/HydraulicStructures/UndoCommand.py
index 471be746..3cecf091 100644
--- a/src/View/HydraulicStructures/UndoCommand.py
+++ b/src/View/HydraulicStructures/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/HydraulicStructures/Window.py b/src/View/HydraulicStructures/Window.py
index c7bc0cf4..3cb4a126 100644
--- a/src/View/HydraulicStructures/Window.py
+++ b/src/View/HydraulicStructures/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/DialogDepth.py b/src/View/InitialConditions/DialogDepth.py
index 5cc559b9..68608b95 100644
--- a/src/View/InitialConditions/DialogDepth.py
+++ b/src/View/InitialConditions/DialogDepth.py
@@ -1,5 +1,5 @@
# DialogDepth.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/DialogDischarge.py b/src/View/InitialConditions/DialogDischarge.py
index 24285969..cbab2d5e 100644
--- a/src/View/InitialConditions/DialogDischarge.py
+++ b/src/View/InitialConditions/DialogDischarge.py
@@ -1,5 +1,5 @@
# DialogDischarge.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/DialogHeight.py b/src/View/InitialConditions/DialogHeight.py
index 8cff08ff..f25d7f13 100644
--- a/src/View/InitialConditions/DialogHeight.py
+++ b/src/View/InitialConditions/DialogHeight.py
@@ -1,5 +1,5 @@
# DialogHeight.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/PlotDRK.py b/src/View/InitialConditions/PlotDRK.py
index 76125391..51b639c0 100644
--- a/src/View/InitialConditions/PlotDRK.py
+++ b/src/View/InitialConditions/PlotDRK.py
@@ -1,5 +1,5 @@
# PlotDRK.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/PlotDischarge.py b/src/View/InitialConditions/PlotDischarge.py
index 5dad6092..01a793b7 100644
--- a/src/View/InitialConditions/PlotDischarge.py
+++ b/src/View/InitialConditions/PlotDischarge.py
@@ -1,5 +1,5 @@
# PlotDischarge.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/Table.py b/src/View/InitialConditions/Table.py
index b715dea9..0290f817 100644
--- a/src/View/InitialConditions/Table.py
+++ b/src/View/InitialConditions/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/UndoCommand.py b/src/View/InitialConditions/UndoCommand.py
index f8a54f4a..d5af00f5 100644
--- a/src/View/InitialConditions/UndoCommand.py
+++ b/src/View/InitialConditions/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/Window.py b/src/View/InitialConditions/Window.py
index 92941909..2d7157e1 100644
--- a/src/View/InitialConditions/Window.py
+++ b/src/View/InitialConditions/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditions/translate.py b/src/View/InitialConditions/translate.py
index 19655f02..89d7386e 100644
--- a/src/View/InitialConditions/translate.py
+++ b/src/View/InitialConditions/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditionsAdisTS/Table.py b/src/View/InitialConditionsAdisTS/Table.py
index d6524528..e1019ffc 100644
--- a/src/View/InitialConditionsAdisTS/Table.py
+++ b/src/View/InitialConditionsAdisTS/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditionsAdisTS/TableDefault.py b/src/View/InitialConditionsAdisTS/TableDefault.py
index cf113299..25814baf 100644
--- a/src/View/InitialConditionsAdisTS/TableDefault.py
+++ b/src/View/InitialConditionsAdisTS/TableDefault.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditionsAdisTS/UndoCommand.py b/src/View/InitialConditionsAdisTS/UndoCommand.py
index 984be6e7..d5defc0a 100644
--- a/src/View/InitialConditionsAdisTS/UndoCommand.py
+++ b/src/View/InitialConditionsAdisTS/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditionsAdisTS/Window.py b/src/View/InitialConditionsAdisTS/Window.py
index f25a942f..c4938d2b 100644
--- a/src/View/InitialConditionsAdisTS/Window.py
+++ b/src/View/InitialConditionsAdisTS/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/InitialConditionsAdisTS/translate.py b/src/View/InitialConditionsAdisTS/translate.py
index a8373490..32b34711 100644
--- a/src/View/InitialConditionsAdisTS/translate.py
+++ b/src/View/InitialConditionsAdisTS/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/Edit/Plot.py b/src/View/LateralContribution/Edit/Plot.py
index 31b25f9b..badcb96a 100644
--- a/src/View/LateralContribution/Edit/Plot.py
+++ b/src/View/LateralContribution/Edit/Plot.py
@@ -1,5 +1,5 @@
# Plot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/Edit/Table.py b/src/View/LateralContribution/Edit/Table.py
index d46848b5..2c1e87ce 100644
--- a/src/View/LateralContribution/Edit/Table.py
+++ b/src/View/LateralContribution/Edit/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/Edit/UndoCommand.py b/src/View/LateralContribution/Edit/UndoCommand.py
index b023c462..41d3eb08 100644
--- a/src/View/LateralContribution/Edit/UndoCommand.py
+++ b/src/View/LateralContribution/Edit/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/Edit/Window.py b/src/View/LateralContribution/Edit/Window.py
index 2f4ac248..79bdc638 100644
--- a/src/View/LateralContribution/Edit/Window.py
+++ b/src/View/LateralContribution/Edit/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/Edit/translate.py b/src/View/LateralContribution/Edit/translate.py
index 08ecd97f..01f9e739 100644
--- a/src/View/LateralContribution/Edit/translate.py
+++ b/src/View/LateralContribution/Edit/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/PlotXY.py b/src/View/LateralContribution/PlotXY.py
index 243af38a..fbcb1867 100644
--- a/src/View/LateralContribution/PlotXY.py
+++ b/src/View/LateralContribution/PlotXY.py
@@ -1,5 +1,5 @@
# PlotXY.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/Table.py b/src/View/LateralContribution/Table.py
index 78c03543..a7319cf0 100644
--- a/src/View/LateralContribution/Table.py
+++ b/src/View/LateralContribution/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/UndoCommand.py b/src/View/LateralContribution/UndoCommand.py
index 25d3aa64..7e8170cd 100644
--- a/src/View/LateralContribution/UndoCommand.py
+++ b/src/View/LateralContribution/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/Window.py b/src/View/LateralContribution/Window.py
index b28fe4c1..e69fd58e 100644
--- a/src/View/LateralContribution/Window.py
+++ b/src/View/LateralContribution/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContribution/translate.py b/src/View/LateralContribution/translate.py
index 24fe45d2..4adad04b 100644
--- a/src/View/LateralContribution/translate.py
+++ b/src/View/LateralContribution/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/Edit/Plot.py b/src/View/LateralContributionsAdisTS/Edit/Plot.py
index 31b25f9b..badcb96a 100644
--- a/src/View/LateralContributionsAdisTS/Edit/Plot.py
+++ b/src/View/LateralContributionsAdisTS/Edit/Plot.py
@@ -1,5 +1,5 @@
# Plot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/Edit/Table.py b/src/View/LateralContributionsAdisTS/Edit/Table.py
index 482c5f05..5975c875 100644
--- a/src/View/LateralContributionsAdisTS/Edit/Table.py
+++ b/src/View/LateralContributionsAdisTS/Edit/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/Edit/UndoCommand.py b/src/View/LateralContributionsAdisTS/Edit/UndoCommand.py
index 86005e98..a4cc21f1 100644
--- a/src/View/LateralContributionsAdisTS/Edit/UndoCommand.py
+++ b/src/View/LateralContributionsAdisTS/Edit/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/Edit/Window.py b/src/View/LateralContributionsAdisTS/Edit/Window.py
index 820b81c6..9be0490d 100644
--- a/src/View/LateralContributionsAdisTS/Edit/Window.py
+++ b/src/View/LateralContributionsAdisTS/Edit/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/Edit/translate.py b/src/View/LateralContributionsAdisTS/Edit/translate.py
index e8e613d0..effd7aea 100644
--- a/src/View/LateralContributionsAdisTS/Edit/translate.py
+++ b/src/View/LateralContributionsAdisTS/Edit/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/Table.py b/src/View/LateralContributionsAdisTS/Table.py
index a51ae3bd..952458b3 100644
--- a/src/View/LateralContributionsAdisTS/Table.py
+++ b/src/View/LateralContributionsAdisTS/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/UndoCommand.py b/src/View/LateralContributionsAdisTS/UndoCommand.py
index 8366f927..a7bef5be 100644
--- a/src/View/LateralContributionsAdisTS/UndoCommand.py
+++ b/src/View/LateralContributionsAdisTS/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/Window.py b/src/View/LateralContributionsAdisTS/Window.py
index 1103506e..56a7b777 100644
--- a/src/View/LateralContributionsAdisTS/Window.py
+++ b/src/View/LateralContributionsAdisTS/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/LateralContributionsAdisTS/translate.py b/src/View/LateralContributionsAdisTS/translate.py
index c5206bd1..1b7c715a 100644
--- a/src/View/LateralContributionsAdisTS/translate.py
+++ b/src/View/LateralContributionsAdisTS/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/MainWindow.py b/src/View/MainWindow.py
index 70a70f5c..fb1bb215 100644
--- a/src/View/MainWindow.py
+++ b/src/View/MainWindow.py
@@ -1,5 +1,5 @@
# MainWindow.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -100,7 +100,7 @@ from View.CheckList.WindowAdisTS import CheckListWindowAdisTS
from View.Results.WindowAdisTS import ResultsWindowAdisTS
from View.Results.ReadingResultsDialog import ReadingResultsDialog
-from View.Debug.Window import ReplWindow
+from View.Debug.Window import ReplWindow, TimerWindow
from View.OutputRKAdisTS.Window import OutputRKAdisTSWindow
from View.Pollutants.Window import PollutantsWindow
from View.D90AdisTS.Window import D90AdisTSWindow
@@ -409,21 +409,28 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
self.debug_action.setToolTip(self._trad["open_debug"])
self.debug_action.triggered.connect(self.open_debug)
+ self.debug_timer_action = QAction("Timers", self)
+ self.debug_timer_action.setToolTip(self._trad["open_debug_timer"])
+ self.debug_timer_action.triggered.connect(self.open_debug_timer)
+
self.debug_sqlite_action = QAction("Debug SQLite", self)
self.debug_sqlite_action.setToolTip(self._trad["open_debug_sql"])
self.debug_sqlite_action.triggered.connect(self.open_sqlite)
if self.conf.debug:
menu.addAction(self.debug_action)
+ menu.addAction(self.debug_timer_action)
menu.addAction(self.debug_sqlite_action)
self.set_debug_lvl(debug=True)
else:
if self.conf.debug:
menu.addAction(self.debug_action)
+ menu.addAction(self.debug_timer_action)
menu.addAction(self.debug_sqlite_action)
self.set_debug_lvl(debug=True)
else:
menu.removeAction(self.debug_action)
+ menu.removeAction(self.debug_timer_action)
menu.removeAction(self.debug_sqlite_action)
self.set_debug_lvl(debug=False)
@@ -2143,6 +2150,14 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
)
repl.show()
+ def open_debug_timer(self):
+ repl = TimerWindow(
+ study=self._study,
+ config=self.conf,
+ parent=self
+ )
+ repl.show()
+
def open_sqlite(self):
if self._study is None:
logger.debug("No study open for sql debuging...")
diff --git a/src/View/Network/GraphWidget.py b/src/View/Network/GraphWidget.py
index 160c1f45..114053a4 100644
--- a/src/View/Network/GraphWidget.py
+++ b/src/View/Network/GraphWidget.py
@@ -1,5 +1,5 @@
# GraphWidget.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Network/ProfileDialog.py b/src/View/Network/ProfileDialog.py
index eff601a9..28caa99d 100644
--- a/src/View/Network/ProfileDialog.py
+++ b/src/View/Network/ProfileDialog.py
@@ -1,5 +1,5 @@
# ProfileDialog.py -- Pamhyr
-# Copyright (C) 2025 INRAE
+# Copyright (C) 2025-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Network/Table.py b/src/View/Network/Table.py
index d91b775a..a52177e0 100644
--- a/src/View/Network/Table.py
+++ b/src/View/Network/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Network/UndoCommand.py b/src/View/Network/UndoCommand.py
index d3c1a44f..5e9b41f4 100644
--- a/src/View/Network/UndoCommand.py
+++ b/src/View/Network/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Network/Window.py b/src/View/Network/Window.py
index 1346e0c8..d58fba4b 100644
--- a/src/View/Network/Window.py
+++ b/src/View/Network/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Network/translate.py b/src/View/Network/translate.py
index fe82e19e..7254bf84 100644
--- a/src/View/Network/translate.py
+++ b/src/View/Network/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/OutputRKAdisTS/Table.py b/src/View/OutputRKAdisTS/Table.py
index 994510da..0768ed4b 100644
--- a/src/View/OutputRKAdisTS/Table.py
+++ b/src/View/OutputRKAdisTS/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/OutputRKAdisTS/Translate.py b/src/View/OutputRKAdisTS/Translate.py
index 069d3361..a5b7bfbb 100644
--- a/src/View/OutputRKAdisTS/Translate.py
+++ b/src/View/OutputRKAdisTS/Translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/OutputRKAdisTS/UndoCommand.py b/src/View/OutputRKAdisTS/UndoCommand.py
index 3ed0d924..b6833bfb 100644
--- a/src/View/OutputRKAdisTS/UndoCommand.py
+++ b/src/View/OutputRKAdisTS/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/OutputRKAdisTS/Window.py b/src/View/OutputRKAdisTS/Window.py
index 378ac309..54e79692 100644
--- a/src/View/OutputRKAdisTS/Window.py
+++ b/src/View/OutputRKAdisTS/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/PlotXY.py b/src/View/PlotXY.py
index b498f3d4..e26d7a5a 100644
--- a/src/View/PlotXY.py
+++ b/src/View/PlotXY.py
@@ -1,5 +1,5 @@
# PlotXY.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Pollutants/Edit/Table.py b/src/View/Pollutants/Edit/Table.py
index 87c6b808..d8fd6361 100644
--- a/src/View/Pollutants/Edit/Table.py
+++ b/src/View/Pollutants/Edit/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Pollutants/Edit/Translate.py b/src/View/Pollutants/Edit/Translate.py
index 22a97294..07f07793 100644
--- a/src/View/Pollutants/Edit/Translate.py
+++ b/src/View/Pollutants/Edit/Translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Pollutants/Edit/UndoCommand.py b/src/View/Pollutants/Edit/UndoCommand.py
index 4eb6959c..8914eac3 100644
--- a/src/View/Pollutants/Edit/UndoCommand.py
+++ b/src/View/Pollutants/Edit/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Pollutants/Edit/Window.py b/src/View/Pollutants/Edit/Window.py
index c07e3c68..2679d92a 100644
--- a/src/View/Pollutants/Edit/Window.py
+++ b/src/View/Pollutants/Edit/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Pollutants/Table.py b/src/View/Pollutants/Table.py
index f1de40dd..df450095 100644
--- a/src/View/Pollutants/Table.py
+++ b/src/View/Pollutants/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Pollutants/Translate.py b/src/View/Pollutants/Translate.py
index 397e60a9..a515f7c2 100644
--- a/src/View/Pollutants/Translate.py
+++ b/src/View/Pollutants/Translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Pollutants/UndoCommand.py b/src/View/Pollutants/UndoCommand.py
index 2526efb4..c59c3519 100644
--- a/src/View/Pollutants/UndoCommand.py
+++ b/src/View/Pollutants/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Pollutants/Window.py b/src/View/Pollutants/Window.py
index 5419c5ef..70a6dacf 100644
--- a/src/View/Pollutants/Window.py
+++ b/src/View/Pollutants/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/Edit/Plot.py b/src/View/Reservoir/Edit/Plot.py
index 9709c668..585b2df1 100644
--- a/src/View/Reservoir/Edit/Plot.py
+++ b/src/View/Reservoir/Edit/Plot.py
@@ -1,5 +1,5 @@
# Plot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/Edit/Table.py b/src/View/Reservoir/Edit/Table.py
index b96988ed..95d51cca 100644
--- a/src/View/Reservoir/Edit/Table.py
+++ b/src/View/Reservoir/Edit/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/Edit/Translate.py b/src/View/Reservoir/Edit/Translate.py
index 15723b23..bb17c503 100644
--- a/src/View/Reservoir/Edit/Translate.py
+++ b/src/View/Reservoir/Edit/Translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/Edit/UndoCommand.py b/src/View/Reservoir/Edit/UndoCommand.py
index 7a9763c2..8041f1a4 100644
--- a/src/View/Reservoir/Edit/UndoCommand.py
+++ b/src/View/Reservoir/Edit/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/Edit/Window.py b/src/View/Reservoir/Edit/Window.py
index 7fa98e13..d837696a 100644
--- a/src/View/Reservoir/Edit/Window.py
+++ b/src/View/Reservoir/Edit/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/Table.py b/src/View/Reservoir/Table.py
index b0e646b7..34e3d7d6 100644
--- a/src/View/Reservoir/Table.py
+++ b/src/View/Reservoir/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/Translate.py b/src/View/Reservoir/Translate.py
index 845f45a0..af12b522 100644
--- a/src/View/Reservoir/Translate.py
+++ b/src/View/Reservoir/Translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/UndoCommand.py b/src/View/Reservoir/UndoCommand.py
index 97150424..a6b0373a 100644
--- a/src/View/Reservoir/UndoCommand.py
+++ b/src/View/Reservoir/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Reservoir/Window.py b/src/View/Reservoir/Window.py
index 6517fd5a..8f1f723d 100644
--- a/src/View/Reservoir/Window.py
+++ b/src/View/Reservoir/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/CompareDialog.py b/src/View/Results/CompareDialog.py
index 62949c9e..f144e052 100644
--- a/src/View/Results/CompareDialog.py
+++ b/src/View/Results/CompareDialog.py
@@ -1,3 +1,20 @@
+# CompareDialog.py -- Pamhyr
+# Copyright (C) 2026 INRAE
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# -*- coding: utf-8 -*-
import os
import logging
import tempfile
diff --git a/src/View/Results/CoordinatesDialog.py b/src/View/Results/CoordinatesDialog.py
index 1be4bbcd..a26ba302 100644
--- a/src/View/Results/CoordinatesDialog.py
+++ b/src/View/Results/CoordinatesDialog.py
@@ -1,5 +1,5 @@
# ShiftDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/CustomExport/CustomExport.py b/src/View/Results/CustomExport/CustomExport.py
index 93efae93..9f81461c 100644
--- a/src/View/Results/CustomExport/CustomExport.py
+++ b/src/View/Results/CustomExport/CustomExport.py
@@ -1,5 +1,5 @@
# CustomExport.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/CustomExport/CustomExportAdis.py b/src/View/Results/CustomExport/CustomExportAdis.py
index ec3fd68a..5553457d 100644
--- a/src/View/Results/CustomExport/CustomExportAdis.py
+++ b/src/View/Results/CustomExport/CustomExportAdis.py
@@ -1,5 +1,5 @@
# CustomExportAdis.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py b/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py
index c9b8fa17..c56669f4 100644
--- a/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py
+++ b/src/View/Results/CustomPlot/CustomPlotValuesSelectionDialog.py
@@ -1,5 +1,5 @@
# CustomPlotValuesSelectionDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/CustomPlot/Plot.py b/src/View/Results/CustomPlot/Plot.py
index ddbeb72b..4ef0d4f4 100644
--- a/src/View/Results/CustomPlot/Plot.py
+++ b/src/View/Results/CustomPlot/Plot.py
@@ -1,5 +1,5 @@
# Plot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -20,6 +20,9 @@ import logging
from functools import reduce
from datetime import datetime
+
+import numpy as np
+
from numpy import sqrt
from numpy import asarray
@@ -88,13 +91,14 @@ class CustomPlot(PamhyrPlot):
self.lines = {}
def draw_bottom_with_bedload(self, reach):
+ results = self.data[self._current_res_id]
+ table = results.get("table")["zfd"]
+ ts = results.get_timestamp_id(self._current_timestamp)
- rk = reach.geometry.get_rk()
+ # rk = reach.geometry.get_rk()
z = list(
map(
- lambda p: p.get_ts_key(
- self._current_timestamp, "zfd"
- ),
+ lambda p: table[ts, p.global_index],
reach.profiles
)
)
@@ -104,7 +108,10 @@ class CustomPlot(PamhyrPlot):
def get_ts_zmin(self, profile, res_id):
results = self.data[res_id]
reach = results.river.reach(self._current_reach)
- zfd = reach.profile(profile).get_key("zfd")
+
+ table = results.get("table")["zfd"]
+
+ zfd = table[:, reach.profile(profile).global_index]
return zfd
def _draw_rk(self):
@@ -119,21 +126,24 @@ class CustomPlot(PamhyrPlot):
else:
z_min = reach.geometry.get_z_min()
+ table = results.get("table")
+ id_ts = results.get_timestamp_id(self._current_timestamp)
+
q = list(
map(
- lambda p: p.get_ts_key(self._current_timestamp, "Q"),
+ lambda p: table["Q"][id_ts, p.global_index],
reach.profiles
)
)
z = list(
map(
- lambda p: p.get_ts_key(self._current_timestamp, "Z"),
+ lambda p: table["Z"][id_ts, p.global_index],
reach.profiles
)
)
v = list(
map(
- lambda p: p.get_ts_key(self._current_timestamp, "V"),
+ lambda p: table["V"][id_ts, p.global_index],
reach.profiles
)
)
@@ -150,36 +160,29 @@ class CustomPlot(PamhyrPlot):
if len(self.lines) != 0:
self.lines = {}
- if "bed_elevation" in self._y:
+ if "bed_elevation" in self._y:
ax = self._axes[unit["bed_elevation"]]
if self._current_res_id < 2:
if reach.has_bedload():
dz = self.draw_bottom_with_bedload(reach)
else:
dz = z_min
+
line = ax.plot(
rk, dz,
color='grey', lw=1.,
)
else:
if reach.has_bedload():
- z_min1 = list(
- map(
- lambda p: p.get_ts_key(
- self._current_timestamp, "zfd"
- ),
- reach1.profiles
- )
- )
- z_min2 = list(
- map(
- lambda p: p.get_ts_key(
- self._current_timestamp, "zfd"
- ),
- reach2.profiles
- )
- )
+ z_min1 = list(map(
+ lambda p: table["zfd"][id_ts, p.global_index],
+ reach1.profiles
+ ))
+ z_min2 = list(map(
+ lambda p: table["zfd"][id_ts, p.global_index],
+ reach2.profiles
+ ))
else:
z_min1 = reach1.geometry.get_z_min()
z_min2 = reach2.geometry.get_z_min()
@@ -199,7 +202,6 @@ class CustomPlot(PamhyrPlot):
if (self._envelop and
reach.has_bedload() and
self._current_res_id < 2):
-
ax = self._axes[unit["bed_elevation_envelop"]]
e = list(
@@ -231,7 +233,6 @@ class CustomPlot(PamhyrPlot):
# self.lines["bed_elevation_envelop"] = line2
if "water_elevation" in self._y:
-
ax = self._axes[unit["water_elevation"]]
line = ax.plot(
rk, z, lw=1.,
@@ -246,12 +247,11 @@ class CustomPlot(PamhyrPlot):
)
if self._envelop:
-
ax = self._axes[unit["water_elevation_envelop"]]
d = list(
map(
- lambda p: max(p.get_key("Z")),
+ lambda p: np.max(table["Z"][:, p.global_index]),
reach.profiles
)
)
@@ -265,7 +265,7 @@ class CustomPlot(PamhyrPlot):
d = list(
map(
- lambda p: min(p.get_key("Z")),
+ lambda p: np.min(table["Z"][:, p.global_index]),
reach.profiles
)
)
@@ -278,7 +278,6 @@ class CustomPlot(PamhyrPlot):
# self.lines["water_elevation_envelop2"] = line2
if "discharge" in self._y:
-
ax = self._axes[unit["discharge"]]
line = ax.plot(
rk, q, lw=1.,
@@ -287,12 +286,11 @@ class CustomPlot(PamhyrPlot):
self.lines["discharge"] = line
if self._envelop:
-
ax = self._axes[unit["discharge_envelop"]]
q1 = list(
map(
- lambda p: max(p.get_key("Q")),
+ lambda p: np.max(table["Q"][:, p.global_index]),
reach.profiles
)
)
@@ -305,7 +303,7 @@ class CustomPlot(PamhyrPlot):
q2 = list(
map(
- lambda p: min(p.get_key("Q")),
+ lambda p: np.min(table["Q"][:, p.global_index]),
reach.profiles
)
)
@@ -317,7 +315,6 @@ class CustomPlot(PamhyrPlot):
# self.lines["discharge_envelop2"] = line2
if "velocity" in self._y:
-
ax = self._axes[unit["velocity"]]
line = ax.plot(
@@ -330,7 +327,7 @@ class CustomPlot(PamhyrPlot):
velocities = list(
map(
- lambda p: p.get_key("V"),
+ lambda p: table["V"][:, p.global_index],
reach.profiles
)
)
@@ -340,8 +337,7 @@ class CustomPlot(PamhyrPlot):
line1 = ax.plot(
rk, vmax, lw=1.,
- color='g',
- linestyle='dotted',
+ color='g', linestyle='dotted',
)
self.lines["velocity_envelop"] = line1
vmin = [min(v) for v in velocities]
@@ -354,13 +350,13 @@ class CustomPlot(PamhyrPlot):
# self.lines["velocity_envelop2"] = line2
if "depth" in self._y:
-
ax = self._axes[unit["depth"]]
if self._current_res_id < 2:
d = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -368,23 +364,22 @@ class CustomPlot(PamhyrPlot):
d1 = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach1.profiles
)
)
d2 = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]),
reach2.profiles
)
)
- d = list(
- map(
- lambda x, y: x - y,
- d1, d2
- )
- )
+ d = list(map(
+ lambda x, y: x - y,
+ d1, d2
+ ))
line = ax.plot(
rk, d,
@@ -393,12 +388,11 @@ class CustomPlot(PamhyrPlot):
self.lines["depth"] = line
if self._envelop and self._current_res_id < 2:
-
ax = self._axes[unit["depth_envelop"]]
d = list(map(
lambda p1, p2: p1 - p2, map(
- lambda p: max(p.get_key("Z")),
+ lambda p: np.max(table["Z"][:, p.global_index]),
reach.profiles
), z_min)
)
@@ -411,7 +405,7 @@ class CustomPlot(PamhyrPlot):
d = list(map(
lambda p1, p2: p1 - p2, map(
- lambda p: min(p.get_key("Z")),
+ lambda p: np.min(table["Z"][:, p.global_index]),
reach.profiles
), z_min)
)
@@ -423,13 +417,13 @@ class CustomPlot(PamhyrPlot):
# self.lines["depth_envelop2"] = line2
if "mean_depth" in self._y:
-
ax = self._axes[unit["mean_depth"]]
if self._current_res_id < 2:
d = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -437,23 +431,23 @@ class CustomPlot(PamhyrPlot):
d1 = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach1.profiles
)
)
d2 = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach2.profiles
)
)
- d = list(
- map(
- lambda x, y: x - y,
- d1, d2
- )
- )
+ d = list(map(
+ lambda x, y: x - y,
+ d1, d2
+ ))
line = ax.plot(
rk, d,
@@ -462,19 +456,21 @@ class CustomPlot(PamhyrPlot):
self.lines["mean_depth"] = line
if "froude" in self._y:
-
ax = self._axes[unit["froude"]]
+
if self._current_res_id < 2:
fr = list(
map(
lambda p:
- p.get_ts_key(self._current_timestamp, "V") /
+ table["V"][id_ts, p.global_index] /
sqrt(9.81 * (
- p.geometry.wet_area(p.get_ts_key(
- self._current_timestamp, "Z")) /
- p.geometry.wet_width(p.get_ts_key(
- self._current_timestamp, "Z"))
- )),
+ p.geometry.wet_area(
+ table["Z"][id_ts, p.global_index]
+ ) /
+ p.geometry.wet_width(
+ table["Z"][id_ts, p.global_index]
+ )
+ )),
reach.profiles
)
)
@@ -482,26 +478,30 @@ class CustomPlot(PamhyrPlot):
fr1 = list(
map(
lambda p:
- p.get_ts_key(self._current_timestamp, "V") /
+ table["V"][id_ts, p.global_index] /
sqrt(9.81 * (
- p.geometry.wet_area(p.get_ts_key(
- self._current_timestamp, "Z")) /
- p.geometry.wet_width(p.get_ts_key(
- self._current_timestamp, "Z"))
- )),
+ p.geometry.wet_area(
+ table["Z"][id_ts, p.global_index]
+ ) /
+ p.geometry.wet_width(
+ table["Z"][id_ts, p.global_index]
+ )
+ )),
reach1.profiles
)
)
fr2 = list(
map(
lambda p:
- p.get_ts_key(self._current_timestamp, "V") /
+ table["V"][id_ts, p.global_index] /
sqrt(9.81 * (
- p.geometry.wet_area(p.get_ts_key(
- self._current_timestamp, "Z")) /
- p.geometry.wet_width(p.get_ts_key(
- self._current_timestamp, "Z"))
- )),
+ p.geometry.wet_area(
+ table["Z"][id_ts, p.global_index]
+ ) /
+ p.geometry.wet_width(
+ table["Z"][id_ts, p.global_index]
+ )
+ )),
reach2.profiles
)
)
@@ -524,7 +524,8 @@ class CustomPlot(PamhyrPlot):
d = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -532,14 +533,16 @@ class CustomPlot(PamhyrPlot):
d1 = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach1.profiles
)
)
d2 = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach2.profiles
)
)
@@ -566,6 +569,9 @@ class CustomPlot(PamhyrPlot):
reach1 = self.data[0].river.reach(self._current_reach)
reach2 = self.data[1].river.reach(self._current_reach)
+ table = results.get("table")
+ id_ts = results.get_timestamp_id(self._current_timestamp)
+
rk = reach.geometry.get_rk()
z_min = reach.geometry.get_z_min()
if reach.has_bedload():
@@ -575,19 +581,19 @@ class CustomPlot(PamhyrPlot):
q = list(
map(
- lambda p: p.get_ts_key(self._current_timestamp, "Q"),
+ lambda p: table["Q"][id_ts, p.global_index],
reach.profiles
)
)
z = list(
map(
- lambda p: p.get_ts_key(self._current_timestamp, "Z"),
+ lambda p: table["Z"][id_ts, p.global_index],
reach.profiles
)
)
v = list(
map(
- lambda p: p.get_ts_key(self._current_timestamp, "V"),
+ lambda p: table["Z"][id_ts, p.global_index],
reach.profiles
)
)
@@ -634,7 +640,8 @@ class CustomPlot(PamhyrPlot):
d = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -642,14 +649,16 @@ class CustomPlot(PamhyrPlot):
d1 = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach1.profiles
)
)
d2 = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach2.profiles
)
)
@@ -667,7 +676,8 @@ class CustomPlot(PamhyrPlot):
d = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -675,14 +685,16 @@ class CustomPlot(PamhyrPlot):
d1 = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach1.profiles
)
)
d2 = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach2.profiles
)
)
@@ -699,41 +711,50 @@ class CustomPlot(PamhyrPlot):
if self._current_res_id < 2:
fr = list(
map(
- lambda p:
- p.get_ts_key(self._current_timestamp, "V") /
+ lambda p: (
+ table["V"][id_ts, p.global_index] /
sqrt(9.81 * (
- p.geometry.wet_area(p.get_ts_key(
- self._current_timestamp, "Z")) /
- p.geometry.wet_width(p.get_ts_key(
- self._current_timestamp, "Z"))
- )),
+ p.geometry.wet_area(
+ table["Z"][id_ts, p.global_index]
+ ) /
+ p.geometry.wet_width(
+ table["Z"][id_ts, p.global_index]
+ )
+ ))
+ ),
reach.profiles
)
)
else:
fr1 = list(
map(
- lambda p:
- p.get_ts_key(self._current_timestamp, "V") /
+ lambda p: (
+ table["V"][id_ts, p.global_index] /
sqrt(9.81 * (
- p.geometry.wet_area(p.get_ts_key(
- self._current_timestamp, "Z")) /
- p.geometry.wet_width(p.get_ts_key(
- self._current_timestamp, "Z"))
- )),
+ p.geometry.wet_area(
+ table["Z"][id_ts, p.global_index]
+ ) /
+ p.geometry.wet_width(
+ table["Z"][id_ts, p.global_index]
+ )
+ ))
+ ),
reach1.profiles
)
)
fr2 = list(
map(
- lambda p:
- p.get_ts_key(self._current_timestamp, "V") /
+ lambda p: (
+ table["V"][id_ts, p.global_index] /
sqrt(9.81 * (
- p.geometry.wet_area(p.get_ts_key(
- self._current_timestamp, "Z")) /
- p.geometry.wet_width(p.get_ts_key(
- self._current_timestamp, "Z"))
- )),
+ p.geometry.wet_area(
+ table["Z"][id_ts, p.global_index]
+ ) /
+ p.geometry.wet_width(
+ table["Z"][id_ts, p.global_index]
+ )
+ ))
+ ),
reach2.profiles
)
)
@@ -751,7 +772,8 @@ class CustomPlot(PamhyrPlot):
d = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -759,14 +781,16 @@ class CustomPlot(PamhyrPlot):
d1 = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach1.profiles
)
)
d2 = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(self._current_timestamp, "Z")),
+ table["Z"][id_ts, p.global_index]
+ ),
reach2.profiles
)
)
@@ -837,6 +861,7 @@ class CustomPlot(PamhyrPlot):
shift += 60
ts = self._parent._timestamps
+ table = results.get("table")
if self._current_res_id == 2: # compare results
reach1 = self.data[0].river.reach(self._current_reach)
@@ -844,17 +869,18 @@ class CustomPlot(PamhyrPlot):
profile1 = reach1.profile(self._current_profile_id)
profile2 = reach2.profile(self._current_profile_id)
- q1 = profile1.get_key("Q")
- z1 = profile1.get_key("Z")
- v1 = profile1.get_key("V")
+ q1 = table["Q"][:, profile1.global_index]
+ z1 = table["Z"][:, profile1.global_index]
+ v1 = table["V"][:, profile1.global_index]
- q2 = profile2.get_key("Q")
- z2 = profile2.get_key("Z")
- v2 = profile2.get_key("V")
+ q2 = table["Q"][:, profile2.global_index]
+ z2 = table["Z"][:, profile2.global_index]
+ v2 = table["V"][:, profile2.global_index]
+
+ q = table["Q"][:, profile.global_index]
+ z = table["Z"][:, profile.global_index]
+ v = table["V"][:, profile.global_index]
- q = profile.get_key("Q")
- z = profile.get_key("Z")
- v = profile.get_key("V")
z_min = profile.geometry.z_min()
if self._current_res_id < 2:
if reach.has_bedload():
@@ -1062,30 +1088,32 @@ class CustomPlot(PamhyrPlot):
self.update_legend()
def _redraw_time(self):
-
results = self.data[self._current_res_id]
reach = results.river.reach(self._current_reach)
profile = reach.profile(self._current_profile_id)
ts = list(results.get("timestamps"))
ts.sort()
+ table = results.get("table")
+
if self._current_res_id == 2: # compare results
reach1 = self.data[0].river.reach(self._current_reach)
reach2 = self.data[1].river.reach(self._current_reach)
profile1 = reach1.profile(self._current_profile_id)
profile2 = reach2.profile(self._current_profile_id)
- q1 = profile1.get_key("Q")
- z1 = profile1.get_key("Z")
- v1 = profile1.get_key("V")
+ q1 = table["Q"][:, profile1.global_index]
+ z1 = table["Z"][:, profile1.global_index]
+ v1 = table["V"][:, profile1.global_index]
- q2 = profile2.get_key("Q")
- z2 = profile2.get_key("Z")
- v2 = profile2.get_key("V")
+ q2 = table["Q"][:, profile2.global_index]
+ z2 = table["Z"][:, profile2.global_index]
+ v2 = table["V"][:, profile2.global_index]
+
+ q = table["Q"][:, profile.global_index]
+ z = table["Z"][:, profile.global_index]
+ v = table["V"][:, profile.global_index]
- q = profile.get_key("Q")
- z = profile.get_key("Z")
- v = profile.get_key("V")
if self._current_res_id < 2:
if reach.has_bedload():
ts_z_min = self.get_ts_zmin(
diff --git a/src/View/Results/CustomPlot/Translate.py b/src/View/Results/CustomPlot/Translate.py
index a6edcff7..9f53dfd6 100644
--- a/src/View/Results/CustomPlot/Translate.py
+++ b/src/View/Results/CustomPlot/Translate.py
@@ -1,5 +1,5 @@
# Translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/PlotAC.py b/src/View/Results/PlotAC.py
index b2324a9b..2774a7b8 100644
--- a/src/View/Results/PlotAC.py
+++ b/src/View/Results/PlotAC.py
@@ -1,5 +1,5 @@
# PlotAC.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,6 +16,8 @@
# -*- coding: utf-8 -*-
+import numpy as np
+
from tools import timer
from View.Tools.PamhyrPlot import PamhyrPlot
from matplotlib import pyplot as plt
@@ -103,11 +105,20 @@ class PlotAC(PamhyrPlot):
color=self.color_plot_river_bottom,
)
+ @timer
def draw_water_elevation(self, reach, profile):
+ result = self.results[self._current_res_id]
+
x = profile.geometry.get_station()
z = profile.geometry.z()
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(
[min(x), max(x)], [water_z, water_z],
@@ -123,11 +134,18 @@ class PlotAC(PamhyrPlot):
)
self.liste_chemins = self.collection.get_paths()
+ @timer
def draw_water_elevation_max(self, reach, profile):
+ result = self.results[self._current_res_id]
+
x = profile.geometry.get_station()
z = profile.geometry.z()
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(
[min(x), max(x)], [water_z, water_z],
@@ -230,8 +248,8 @@ class PlotAC(PamhyrPlot):
if not self._init:
self.draw()
- reach = self.results[self._current_res_id].river.reach(
- self._current_reach_id)
+ reach = self.results[self._current_res_id]\
+ .river.reach(self._current_reach_id)
profile = reach.profile(self._current_profile_id)
x = profile.geometry.get_station()
z = profile.geometry.z()
@@ -262,7 +280,15 @@ class PlotAC(PamhyrPlot):
self.line_rk.set_data(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(
[min(x), max(x)],
[water_z, water_z]
@@ -277,7 +303,12 @@ class PlotAC(PamhyrPlot):
)
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(
[min(x), max(x)],
[water_z, water_z]
diff --git a/src/View/Results/PlotH.py b/src/View/Results/PlotH.py
index e40c132b..88a720d8 100644
--- a/src/View/Results/PlotH.py
+++ b/src/View/Results/PlotH.py
@@ -1,5 +1,5 @@
# PlotH.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -128,14 +128,19 @@ class PlotH(PamhyrPlot):
self.draw_current()
self._init = True
+ @timer
def draw_data(self, res_id):
results = self.results[res_id]
reach = results.river.reach(self._current_reach_id)
+
+ q = results.get("table")["Q"]
+
for i, p in enumerate(self._current_profile_id):
profile = reach.profile(p)
x = self._timestamps
- y = profile.get_key("Q")
+ y = q[:, profile.global_index]
+ # y = profile.get_key("Q")
if res_id == 2:
label = "Δ " + self.label_discharge + f" {profile.name}"
@@ -187,6 +192,7 @@ class PlotH(PamhyrPlot):
lw=1.,
)
+ @timer
def draw_max(self, res_id):
results = self.results[res_id]
reach = results.river.reach(self._current_reach_id)
@@ -198,16 +204,21 @@ class PlotH(PamhyrPlot):
x = self._timestamps
y = []
+ q_table = results.get("table")["Q"]
+
if res_id == 2:
label = "Δ " + self.label_discharge_max
else:
label = self.label_discharge_max
- for ts in x:
+ for i, ts in enumerate(x):
ts_y = -9999
+
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)
+
y.append(ts_y)
m, = self.canvas.axes.plot(
diff --git a/src/View/Results/PlotRKC.py b/src/View/Results/PlotRKC.py
index 744dc7e3..dc658c65 100644
--- a/src/View/Results/PlotRKC.py
+++ b/src/View/Results/PlotRKC.py
@@ -1,5 +1,5 @@
# PlotRKC.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,6 +17,7 @@
# -*- coding: utf-8 -*-
import logging
+import numpy as np
from functools import reduce
@@ -102,12 +103,15 @@ class PlotRKC(PamhyrPlot):
self.draw_bottom_geometry(reach)
def draw_bottom_with_bedload(self, reach):
+ results = self.results[self._current_res_id]
rk = reach.geometry.get_rk()
+
+ table = results.get("table")["zfd"]
+ ts = results.get_timestamp_id(self._current_timestamp)
+
zfd = list(
map(
- lambda p: p.get_ts_key(
- self._current_timestamp, "zfd"
- ),
+ lambda p: table[ts, p.global_index],
reach.profiles
)
)
@@ -167,14 +171,18 @@ class PlotRKC(PamhyrPlot):
def draw_water_elevation(self, reach):
if len(reach.geometry.profiles) != 0:
+ result = self.results[self._current_res_id]
rk = reach.geometry.get_rk()
z_min = reach.geometry.get_z_min()
+ table = result.get("table")["Z"]
+ ts = result.get_timestamp_id(self._current_timestamp)
+
water_z = list(
map(
- lambda p: p.get_ts_key(
- self._current_timestamp, "Z"
- ),
+ lambda p: table[
+ ts, p.global_index
+ ],
reach.profiles
)
)
@@ -194,12 +202,20 @@ class PlotRKC(PamhyrPlot):
def draw_water_elevation_max(self, reach):
if len(reach.geometry.profiles) != 0:
+ result = self.results[self._current_res_id]
rk = reach.geometry.get_rk()
z_min = reach.geometry.get_z_min()
+ table = result.get("table")["Z"]
+ ts = result.get_timestamp_id(self._current_timestamp)
+
water_z = list(
map(
- lambda p: max(p.get_key("Z")),
+ lambda p: np.max(
+ table[
+ :, p.global_index
+ ]
+ ),
reach.profiles
)
)
@@ -253,12 +269,14 @@ class PlotRKC(PamhyrPlot):
def draw_water_elevation_overflow(self, reach):
overflow = []
+ result = self.results[self._current_res_id]
+ table = result.get("table")["Z"]
for profile in reach.profiles:
- z_max = max(profile.get_key("Z"))
+ z_max = np.max(table[:, profile.global_index])
z_max_ts = 0
- for ts in self._timestamps:
- z = profile.get_ts_key(ts, "Z")
+ for i, ts in enumerate(self._timestamps):
+ z = table[i, profile.global_index]
if z == z_max:
z_max_ts = ts
break
@@ -329,16 +347,18 @@ class PlotRKC(PamhyrPlot):
self.update()
def update_water_elevation(self):
- results = self.results[self._current_res_id]
- reach = results.river.reach(self._current_reach_id)
+ result = self.results[self._current_res_id]
+ reach = result.river.reach(self._current_reach_id)
rk = reach.geometry.get_rk()
z_min = reach.geometry.get_z_min()
+ table = result.get("table")["Z"]
+ ts = result.get_timestamp_id(self._current_timestamp)
water_z = list(
map(
- lambda p: p.get_ts_key(
- self._current_timestamp, "Z"
- ),
+ lambda p: table[
+ ts, p.global_index
+ ],
reach.profiles
)
)
@@ -379,14 +399,13 @@ class PlotRKC(PamhyrPlot):
rk = reach.geometry.get_rk()
# z = self.sl_compute_current_z(reach)
- zfd = list(
- map(
- lambda p: p.get_ts_key(
- self._current_timestamp, "zfd"
- ),
- reach.profiles
- )
- )
+ table = results.get("table")["zfd"]
+ ts = results.get_timestamp_id(self._current_timestamp)
+
+ zfd = list(map(
+ lambda p: table[ts, p.global_index],
+ reach.profiles
+ ))
self.line_bottom.remove()
diff --git a/src/View/Results/PlotSedAdis.py b/src/View/Results/PlotSedAdis.py
index f3097b6f..c22c3ad5 100644
--- a/src/View/Results/PlotSedAdis.py
+++ b/src/View/Results/PlotSedAdis.py
@@ -1,5 +1,5 @@
# PlotSedAdisDx.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/PlotXY.py b/src/View/Results/PlotXY.py
index 6696ff55..1845660d 100644
--- a/src/View/Results/PlotXY.py
+++ b/src/View/Results/PlotXY.py
@@ -1,5 +1,5 @@
# PlotXY.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -20,9 +20,10 @@ import logging
from functools import reduce
+import numpy as np
+
from tools import timer, trace, logger_exception
from View.Tools.PamhyrPlot import PamhyrPlot
-import numpy as np
from matplotlib import collections
from PyQt5.QtCore import (
@@ -239,14 +240,20 @@ class PlotXY(PamhyrPlot):
)
def draw_water_elevation_max(self, reach):
+ result = self.results[self._current_res_id]
+
l_x, l_y, r_x, r_y = [], [], [], []
overflow = []
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
- 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:
z_max_ts = ts
break
@@ -304,10 +311,6 @@ class PlotXY(PamhyrPlot):
poly_l_x, poly_l_y, poly_r_x, poly_r_y = [], [], [], []
for profile in reach.profiles:
- water_z = profile.get_ts_key(
- self._current_timestamp, "Z"
- )
-
pt_left, pt_right = profile.get_ts_key(
self._current_timestamp,
"water_limits"
@@ -435,9 +438,6 @@ class PlotXY(PamhyrPlot):
poly_l_x, poly_l_y, poly_r_x, poly_r_y = [], [], [], []
for profile in reach.profiles:
- water_z = profile.get_ts_key(
- self._current_timestamp, "Z"
- )
pt_left, pt_right = profile.get_ts_key(
self._current_timestamp,
"water_limits"
diff --git a/src/View/Results/ReadingResultsDialog.py b/src/View/Results/ReadingResultsDialog.py
index 4461bc8c..f7f37b0f 100644
--- a/src/View/Results/ReadingResultsDialog.py
+++ b/src/View/Results/ReadingResultsDialog.py
@@ -1,5 +1,5 @@
# ReadingResultsDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/Table.py b/src/View/Results/Table.py
index 668619f0..b730ce12 100644
--- a/src/View/Results/Table.py
+++ b/src/View/Results/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -74,78 +74,84 @@ class TableModel(PamhyrTableModel):
row = index.row()
column = index.column()
+ p = self._lst[row]
+
if self._opt_data == "reach":
if self._headers[column] == "name":
- v = self._lst[row].name
+ v = p.name
return str(v)
elif self._opt_data == "profile":
if self._headers[column] == "name":
- v = self._lst[row].name
+ v = p.name
return str(v)
elif self._headers[column] == "rk":
- v = self._lst[row].rk
+ v = p.rk
return f"{v:.4f}"
elif self._opt_data == "solver":
if self._headers[column] == "solver":
- v = self._lst[row]
+ v = p
if v is None:
v = self._data[0].solver_name
return str(v)
elif self._opt_data == "raw_data":
- p = self._lst[row]
+ table = self._data[0].get("table")
+ ts = self._data[0].get_timestamp_id(self._timestamp)
+
if self._headers[column] == "name":
if p.name == "":
return f"{p.rk:.4f}"
return f"{p.name}"
elif self._headers[column] == "water_elevation":
- v = self._lst[row].get_ts_key(self._timestamp, "Z")
+ v = table["Z"][ts, p.global_index]
if v is None:
v = 0.0
return f"{v:.4f}"
elif self._headers[column] == "discharge":
- v = self._lst[row].get_ts_key(self._timestamp, "Q")
+ v = table["Q"][ts, p.global_index]
if v is None:
v = 0.0
return f"{v:.4f}"
elif self._headers[column] == "velocity":
- v = self._lst[row].get_ts_key(self._timestamp, "V")
+ v = table["V"][ts, p.global_index]
if v is None:
v = 0.0
return f"{v:.4f}"
elif self._headers[column] == "width":
- z = self._lst[row].get_ts_key(self._timestamp, "Z")
- v = self._lst[row].geometry.wet_width(z)
+ z = table["Z"][ts, p.global_index]
+ v = p.geometry.wet_width(z)
return f"{v:.4f}"
elif self._headers[column] == "depth":
- z = self._lst[row].get_ts_key(self._timestamp, "Z")
- v = self._lst[row].geometry.max_water_depth(z)
+ z = table["Z"][ts, p.global_index]
+ v = p.geometry.max_water_depth(z)
return f"{v:.4f}"
elif self._headers[column] == "mean_depth":
- z = self._lst[row].get_ts_key(self._timestamp, "Z")
- v = self._lst[row].geometry.mean_water_depth(z)
+ z = table["Z"][ts, p.global_index]
+ v = p.geometry.mean_water_depth(z)
return f"{v:.4f}"
elif self._headers[column] == "wet_area":
- z = self._lst[row].get_ts_key(self._timestamp, "Z")
- v = self._lst[row].geometry.wet_area(z)
+ z = table["Z"][ts, p.global_index]
+ v = p.geometry.wet_area(z)
return f"{v:.4f}"
elif self._headers[column] == "wet_perimeter":
- z = self._lst[row].get_ts_key(self._timestamp, "Z")
- v = self._lst[row].geometry.wet_perimeter(z)
+ z = table["Z"][ts, p.global_index]
+ v = p.geometry.wet_perimeter(z)
return f"{v:.4f}"
elif self._headers[column] == "hydraulic_radius":
- z = self._lst[row].get_ts_key(self._timestamp, "Z")
- v = self._lst[row].geometry.wet_radius(z)
+ z = table["Z"][ts, p.global_index]
+ v = p.geometry.wet_radius(z)
return f"{v:.4f}"
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].get_ts_key(self._timestamp, "V")
- a = self._lst[row].geometry.wet_area(z)
- b = self._lst[row].geometry.wet_width(z)
+ q = table["Q"][ts, p.global_index]
+ z = table["Z"][ts, p.global_index]
+ v = table["V"][ts, p.global_index]
+ a = p.geometry.wet_area(z)
+ b = p.geometry.wet_width(z)
+
if b == 0.0 or a == 0.0:
froude = 0.0
else:
froude = v / sqrt(9.81 * (a / b))
+
return f"{froude:.4f}"
else:
v = 0.0
diff --git a/src/View/Results/TableAdisTS.py b/src/View/Results/TableAdisTS.py
index 78ae9eaa..1ba45c14 100644
--- a/src/View/Results/TableAdisTS.py
+++ b/src/View/Results/TableAdisTS.py
@@ -1,5 +1,5 @@
# TableAdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/UndoCommand.py b/src/View/Results/UndoCommand.py
index c9d0a55b..f1282313 100644
--- a/src/View/Results/UndoCommand.py
+++ b/src/View/Results/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/Window.py b/src/View/Results/Window.py
index c67df06e..9dcc0bec 100644
--- a/src/View/Results/Window.py
+++ b/src/View/Results/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -33,6 +33,7 @@ except Exception as e:
from functools import reduce
+import numpy as np
from numpy import sqrt
from datetime import datetime
@@ -872,24 +873,32 @@ class ResultsWindow(PamhyrWindow):
reach = results.river.reachs[self._get_current_reach()]
dict_x = self._trad.get_dict("values_x")
dict_y = self._trad.get_dict("values_y")
+
if self._current_results == 2:
envelop = False
reach1 = results[0].river.reachs[self._get_current_reach()]
reach2 = results[1].river.reachs[self._get_current_reach()]
+
if envelop:
dict_y.update(self._trad.get_dict("values_y_envelop"))
+
my_dict = {}
my_dict[dict_x["rk"]] = reach.geometry.get_rk()
+
+ table = results.get("table")
+ id_ts = results.get_timestamp_id(timestamp)
+
+ z = table["Z"]
+ q = table["Q"]
+ v = table["V"]
+ zfd = table["zfd"]
+
if "bed_elevation" in y:
if reach.has_bedload():
- zmin = list(
- map(
- lambda p: p.get_ts_key(
- timestamp, "zfd"
- ),
- reach.profiles
- )
- )
+ zmin = list(map(
+ lambda p: zfd[id_ts, p.global_index],
+ reach.profiles
+ ))
else:
zmin = reach.geometry.get_z_min()
my_dict[dict_y["bed_elevation"]] = zmin
@@ -897,40 +906,40 @@ class ResultsWindow(PamhyrWindow):
if "discharge" in y:
my_dict[dict_y["discharge"]] = list(
map(
- lambda p: p.get_ts_key(timestamp, "Q"),
+ lambda p: q[id_ts, p.global_index],
reach.profiles
)
)
if envelop:
my_dict[dict_y["min_discharge"]] = list(
map(
- lambda p: min(p.get_key("Q")),
+ lambda p: np.min(q[:, p.global_index]),
reach.profiles
)
)
my_dict[dict_y["max_discharge"]] = list(
map(
- lambda p: max(p.get_key("Q")),
+ lambda p: np.max(q[:, p.global_index]),
reach.profiles
)
)
if "water_elevation" in y:
my_dict[dict_y["water_elevation"]] = list(
map(
- lambda p: p.get_ts_key(timestamp, "Z"),
+ lambda p: z[id_ts, p.global_index],
reach.profiles
)
)
if envelop:
my_dict[dict_y["min_water_elevation"]] = list(
map(
- lambda p: min(p.get_key("Z")),
+ lambda p: np.min(z[:, p.global_index]),
reach.profiles
)
)
my_dict[dict_y["max_water_elevation"]] = list(
map(
- lambda p: max(p.get_key("Z")),
+ lambda p: np.max(z[:, p.global_index]),
reach.profiles
)
)
@@ -938,16 +947,15 @@ class ResultsWindow(PamhyrWindow):
if "velocity" in y:
my_dict[dict_y["velocity"]] = list(
map(
- lambda p: p.get_ts_key(timestamp, "V"),
+ lambda p: v[id_ts, p.global_index],
reach.profiles
)
)
if envelop:
velocities = list(map(
- lambda p: p.get_key("V"),
- reach.profiles
- )
- )
+ lambda p: v[:, p.global_index],
+ 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]
@@ -956,7 +964,8 @@ class ResultsWindow(PamhyrWindow):
d = my_dict[dict_y["depth"]] = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -964,14 +973,16 @@ class ResultsWindow(PamhyrWindow):
d1 = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach1.profiles
)
)
d2 = list(
map(
lambda p: p.geometry.max_water_depth(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach2.profiles
)
)
@@ -985,14 +996,14 @@ class ResultsWindow(PamhyrWindow):
if envelop:
my_dict[dict_y["min_depth"]] = list(map(
lambda p1, p2: p1 - p2, map(
- lambda p: min(p.get_key("Z")),
+ lambda p: np.min(z[:, p.global_index]),
reach.profiles
), reach.geometry.get_z_min()
)
)
my_dict[dict_y["max_depth"]] = list(map(
lambda p1, p2: p1 - p2, map(
- lambda p: max(p.get_key("Z")),
+ lambda p: np.max(z[:, p.global_index]),
reach.profiles
), reach.geometry.get_z_min()
)
@@ -1003,7 +1014,8 @@ class ResultsWindow(PamhyrWindow):
d = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -1011,14 +1023,16 @@ class ResultsWindow(PamhyrWindow):
d1 = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach1.profiles
)
)
d2 = list(
map(
lambda p: p.geometry.mean_water_depth(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach2.profiles
)
)
@@ -1033,57 +1047,65 @@ class ResultsWindow(PamhyrWindow):
if self._current_results != 2:
fr = my_dict[dict_y["froude"]] = list(
map(
- lambda p:
- p.get_ts_key(timestamp, "V") /
+ lambda p: (
+ v[id_ts, p.global_index] /
sqrt(9.81 * (
p.geometry.wet_area(
- p.get_ts_key(timestamp, "Z")) /
+ z[id_ts, p.global_index]
+ ) /
p.geometry.wet_width(
- p.get_ts_key(timestamp, "Z"))
- )),
+ z[id_ts, p.global_index]
+ )
+ ))
+ ),
reach.profiles
)
)
else:
fr1 = list(
map(
- lambda p:
- p.get_ts_key(timestamp, "V") /
+ lambda p: (
+ v[id_ts, p.global_index] /
sqrt(9.81 * (
p.geometry.wet_area(
- p.get_ts_key(timestamp, "Z")) /
+ z[id_ts, p.global_index]
+ ) /
p.geometry.wet_width(
- p.get_ts_key(timestamp, "Z"))
- )),
+ z[id_ts, p.global_index]
+ )
+ ))
+ ),
reach1.profiles
)
)
fr2 = list(
map(
- lambda p:
- p.get_ts_key(timestamp, "V") /
+ lambda p: (
+ v[id_ts, p.global_index] /
sqrt(9.81 * (
p.geometry.wet_area(
- p.get_ts_key(timestamp, "Z")) /
+ z[id_ts, p.global_index]
+ ) /
p.geometry.wet_width(
- p.get_ts_key(timestamp, "Z"))
- )),
+ z[id_ts, p.global_index]
+ )
+ ))
+ ),
reach2.profiles
)
)
- fr = list(
- map(
- lambda x, y: x - y,
- fr1, fr2
- )
- )
+ fr = list(map(
+ lambda x, y: x - y,
+ fr1, fr2
+ ))
my_dict[dict_y["froude"]] = fr
if "wet_area" in y:
if self._current_results != 2:
wa = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach.profiles
)
)
@@ -1091,23 +1113,24 @@ class ResultsWindow(PamhyrWindow):
wa1 = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach1.profiles
)
)
wa2 = list(
map(
lambda p: p.geometry.wet_area(
- p.get_ts_key(timestamp, "Z")),
+ z[id_ts, p.global_index]
+ ),
reach2.profiles
)
)
- wa = list(
- map(
- lambda x, y: x - y,
- wa1, wa2
- )
- )
+ wa = list(map(
+ lambda x, y: x - y,
+ wa1, wa2
+ ))
+
my_dict[dict_y["wet_area"]] = wa
return my_dict
@@ -1118,24 +1141,39 @@ class ResultsWindow(PamhyrWindow):
profile = reach.profile(profile)
dict_x = self._trad.get_dict("values_x")
dict_y = self._trad.get_dict("values_y")
+
my_dict = {}
my_dict[dict_x["time"]] = self._timestamps
- z = profile.get_key("Z")
- q = profile.get_key("Q")
- v = profile.get_key("V")
+
+ table = results.get("table")
+
+ z = table["Z"][:, profile.global_index]
+ q = table["Q"][:, profile.global_index]
+ v = table["V"][:, profile.global_index]
+ zfd = table["zfd"][:, profile.global_index]
+
if self._current_results == 2:
reach1 = self._results[0].river.reach(self._reach)
reach2 = self._results[1].river.reach(self._reach)
reach3 = self._results[2].river.reach(self._reach)
profile1 = reach1.profile(self._profile)
profile2 = reach2.profile(self._profile)
- profile3 = reach3.profile(self._profile)
+ # profile3 = reach3.profile(self._profile)
+
+ z1 = table["Z"][:, profile1.global_index]
+ q1 = table["Q"][:, profile1.global_index]
+ v1 = table["V"][:, profile1.global_index]
+
+ z2 = table["Z"][:, profile2.global_index]
+ q2 = table["Q"][:, profile2.global_index]
+ v2 = table["V"][:, profile2.global_index]
if "bed_elevation" in y:
if reach.has_bedload():
- z_min = profile.get_key("zfd")
+ z_min = zfd
else:
z_min = [profile.geometry.z_min()] * len(self._timestamps)
+
my_dict[dict_y["bed_elevation"]] = z_min
if "discharge" in y:
my_dict[dict_y["discharge"]] = q
@@ -1146,14 +1184,14 @@ class ResultsWindow(PamhyrWindow):
if "depth" in y:
if self._current_results != 2:
d = list(
- map(lambda z: profile.geometry.max_water_depth(z), z)
+ map(lambda x: profile.geometry.max_water_depth(x), z)
)
else:
d1 = list(
- map(lambda z: profile1.geometry.max_water_depth(z), z1)
+ map(lambda x: profile1.geometry.max_water_depth(x), z1)
)
d2 = list(
- map(lambda z: profile2.geometry.max_water_depth(z), z2)
+ map(lambda x: profile2.geometry.max_water_depth(x), z2)
)
d = list(
map(
@@ -1165,21 +1203,19 @@ class ResultsWindow(PamhyrWindow):
if "mean_depth" in y:
if self._current_results != 2:
d = list(
- map(lambda z: profile.geometry.mean_water_depth(z), z)
+ map(lambda x: profile.geometry.mean_water_depth(x), z)
)
else:
d1 = list(
- map(lambda z: profile1.geometry.mean_water_depth(z), z1)
+ map(lambda x: profile1.geometry.mean_water_depth(x), z1)
)
d2 = list(
- map(lambda z: profile2.geometry.mean_water_depth(z), z2)
+ map(lambda x: profile2.geometry.mean_water_depth(x), z2)
)
- d = list(
- map(
- lambda x, y: x - y,
- d1, d2
- )
- )
+ d = list(map(
+ lambda x, y: x - y,
+ d1, d2
+ ))
my_dict[dict_y["mean_depth"]] = d
if "froude" in y:
if self._current_results != 2:
@@ -1188,7 +1224,8 @@ class ResultsWindow(PamhyrWindow):
v / sqrt(9.81 * (
profile.geometry.wet_area(z) /
profile.geometry.wet_width(z))
- ), z, v)
+ ),
+ z, v)
)
else:
fr1 = list(
@@ -1197,7 +1234,8 @@ class ResultsWindow(PamhyrWindow):
sqrt(9.81 * (
profile1.geometry.wet_area(z) /
profile1.geometry.wet_width(z))
- ), z1, v1)
+ ),
+ z1, v1)
)
fr2 = list(
map(lambda z, v:
@@ -1205,33 +1243,30 @@ class ResultsWindow(PamhyrWindow):
sqrt(9.81 * (
profile2.geometry.wet_area(z) /
profile2.geometry.wet_width(z))
- ), z2, v2)
- )
- fr = list(
- map(
- lambda x, y: x - y,
- fr1, fr2
- )
+ ),
+ z2, v2)
)
+ fr = list(map(
+ lambda x, y: x - y,
+ fr1, fr2
+ ))
my_dict[dict_y["froude"]] = fr
if "wet_area" in y:
if self._current_results != 2:
wa = list(
- map(lambda z: profile.geometry.wet_area(z), z)
+ map(lambda x: profile.geometry.wet_area(x), z)
)
else:
wa1 = list(
- map(lambda z: profile1.geometry.wet_area(z), z1)
+ map(lambda x: profile1.geometry.wet_area(x), z1)
)
wa2 = list(
- map(lambda z: profile2.geometry.wet_area(z), z2)
+ map(lambda x: profile2.geometry.wet_area(x), z2)
)
- wa = list(
- map(
- lambda x, y: x - y,
- wa1, wa2
- )
- )
+ wa = list(map(
+ lambda x, y: x - y,
+ wa1, wa2
+ ))
my_dict[dict_y["wet_area"]] = wa
return my_dict
diff --git a/src/View/Results/WindowAdisTS.py b/src/View/Results/WindowAdisTS.py
index 74b4cd8d..8cae42b8 100644
--- a/src/View/Results/WindowAdisTS.py
+++ b/src/View/Results/WindowAdisTS.py
@@ -1,5 +1,5 @@
# WindowAdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Results/translate.py b/src/View/Results/translate.py
index df4c26dd..6e6b855e 100644
--- a/src/View/Results/translate.py
+++ b/src/View/Results/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/RunSolver/Log/Window.py b/src/View/RunSolver/Log/Window.py
index 217275a7..571f9fbc 100644
--- a/src/View/RunSolver/Log/Window.py
+++ b/src/View/RunSolver/Log/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/RunSolver/Window.py b/src/View/RunSolver/Window.py
index 64134c7d..65e8546b 100644
--- a/src/View/RunSolver/Window.py
+++ b/src/View/RunSolver/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/RunSolver/WindowAdisTS.py b/src/View/RunSolver/WindowAdisTS.py
index 1c162760..a768e4d6 100644
--- a/src/View/RunSolver/WindowAdisTS.py
+++ b/src/View/RunSolver/WindowAdisTS.py
@@ -1,5 +1,5 @@
# WindowAdisTS.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Scenarios/GraphWidget.py b/src/View/Scenarios/GraphWidget.py
index bba78edd..9756a8f0 100644
--- a/src/View/Scenarios/GraphWidget.py
+++ b/src/View/Scenarios/GraphWidget.py
@@ -1,5 +1,5 @@
# GraphWidget.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Scenarios/Table.py b/src/View/Scenarios/Table.py
index d7fceaad..4fe701bc 100644
--- a/src/View/Scenarios/Table.py
+++ b/src/View/Scenarios/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Scenarios/UndoCommand.py b/src/View/Scenarios/UndoCommand.py
index ae3e0449..dd6631e7 100644
--- a/src/View/Scenarios/UndoCommand.py
+++ b/src/View/Scenarios/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Scenarios/Window.py b/src/View/Scenarios/Window.py
index 7f97b1f6..db77785e 100644
--- a/src/View/Scenarios/Window.py
+++ b/src/View/Scenarios/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Scenarios/translate.py b/src/View/Scenarios/translate.py
index 99bc5b25..8c7f0c9d 100644
--- a/src/View/Scenarios/translate.py
+++ b/src/View/Scenarios/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/SedimentLayers/Edit/Window.py b/src/View/SedimentLayers/Edit/Window.py
index 82eaec2e..511040b0 100644
--- a/src/View/SedimentLayers/Edit/Window.py
+++ b/src/View/SedimentLayers/Edit/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/SedimentLayers/Window.py b/src/View/SedimentLayers/Window.py
index 7fe027af..0c100e28 100644
--- a/src/View/SedimentLayers/Window.py
+++ b/src/View/SedimentLayers/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/SelectReach/Window.py b/src/View/SelectReach/Window.py
index 001d0a5b..991c9d56 100644
--- a/src/View/SelectReach/Window.py
+++ b/src/View/SelectReach/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/SolverParameters/Table.py b/src/View/SolverParameters/Table.py
index df11ac40..67034ceb 100644
--- a/src/View/SolverParameters/Table.py
+++ b/src/View/SolverParameters/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/SolverParameters/UndoCommand.py b/src/View/SolverParameters/UndoCommand.py
index e146ace0..b4b1e94d 100644
--- a/src/View/SolverParameters/UndoCommand.py
+++ b/src/View/SolverParameters/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/SolverParameters/Window.py b/src/View/SolverParameters/Window.py
index e8f53bd1..72d0438d 100644
--- a/src/View/SolverParameters/Window.py
+++ b/src/View/SolverParameters/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/SolverParameters/translate.py b/src/View/SolverParameters/translate.py
index 26c00934..05e141f1 100644
--- a/src/View/SolverParameters/translate.py
+++ b/src/View/SolverParameters/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Stricklers/Table.py b/src/View/Stricklers/Table.py
index 071b4e0d..75fcff84 100644
--- a/src/View/Stricklers/Table.py
+++ b/src/View/Stricklers/Table.py
@@ -1,5 +1,5 @@
# Table.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Stricklers/UndoCommand.py b/src/View/Stricklers/UndoCommand.py
index 97737917..7e55874d 100644
--- a/src/View/Stricklers/UndoCommand.py
+++ b/src/View/Stricklers/UndoCommand.py
@@ -1,5 +1,5 @@
# UndoCommand.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Stricklers/Window.py b/src/View/Stricklers/Window.py
index 01d8d521..534f0469 100644
--- a/src/View/Stricklers/Window.py
+++ b/src/View/Stricklers/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Stricklers/translate.py b/src/View/Stricklers/translate.py
index 7bf4d245..de77d569 100644
--- a/src/View/Stricklers/translate.py
+++ b/src/View/Stricklers/translate.py
@@ -1,5 +1,5 @@
# translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Study/Window.py b/src/View/Study/Window.py
index e598cc1f..768152f0 100644
--- a/src/View/Study/Window.py
+++ b/src/View/Study/Window.py
@@ -1,5 +1,5 @@
# Window.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/ASubWindow.py b/src/View/Tools/ASubWindow.py
index c6ef85c3..01f2cd25 100644
--- a/src/View/Tools/ASubWindow.py
+++ b/src/View/Tools/ASubWindow.py
@@ -1,5 +1,5 @@
# ASubWindow.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/FlexibleDoubleSpinBox.py b/src/View/Tools/FlexibleDoubleSpinBox.py
index 155f9016..e84011ea 100644
--- a/src/View/Tools/FlexibleDoubleSpinBox.py
+++ b/src/View/Tools/FlexibleDoubleSpinBox.py
@@ -1,5 +1,5 @@
# PamhyrWindow.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/ListedSubWindow.py b/src/View/Tools/ListedSubWindow.py
index 78c021a7..dfee57f4 100644
--- a/src/View/Tools/ListedSubWindow.py
+++ b/src/View/Tools/ListedSubWindow.py
@@ -1,5 +1,5 @@
# ListedSubWindow.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/PamhyrDelegate.py b/src/View/Tools/PamhyrDelegate.py
index 1000ca2c..d8003937 100644
--- a/src/View/Tools/PamhyrDelegate.py
+++ b/src/View/Tools/PamhyrDelegate.py
@@ -1,5 +1,5 @@
# PamhyrDelegate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/PamhyrPlot.py b/src/View/Tools/PamhyrPlot.py
index 78edc38d..5f373b23 100644
--- a/src/View/Tools/PamhyrPlot.py
+++ b/src/View/Tools/PamhyrPlot.py
@@ -1,5 +1,5 @@
# PamhyrPlot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/PamhyrPythonEditor.py b/src/View/Tools/PamhyrPythonEditor.py
index fec04371..40f1f042 100644
--- a/src/View/Tools/PamhyrPythonEditor.py
+++ b/src/View/Tools/PamhyrPythonEditor.py
@@ -1,5 +1,5 @@
# PamhyrPythonEditor.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/PamhyrTable.py b/src/View/Tools/PamhyrTable.py
index e81c8477..dc8920fb 100644
--- a/src/View/Tools/PamhyrTable.py
+++ b/src/View/Tools/PamhyrTable.py
@@ -1,5 +1,5 @@
# PamhyrTable.py -- Pamhyr abstract table model
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/PamhyrTranslate.py b/src/View/Tools/PamhyrTranslate.py
index 31c1dafe..2964e0bb 100644
--- a/src/View/Tools/PamhyrTranslate.py
+++ b/src/View/Tools/PamhyrTranslate.py
@@ -1,5 +1,5 @@
# PamhyrTranslate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/PamhyrWidget.py b/src/View/Tools/PamhyrWidget.py
index a3ffd1cc..5b820f08 100644
--- a/src/View/Tools/PamhyrWidget.py
+++ b/src/View/Tools/PamhyrWidget.py
@@ -1,5 +1,5 @@
# PamhyrWidget.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/PamhyrWindow.py b/src/View/Tools/PamhyrWindow.py
index ffa0e90f..fe91e0a1 100644
--- a/src/View/Tools/PamhyrWindow.py
+++ b/src/View/Tools/PamhyrWindow.py
@@ -1,5 +1,5 @@
# PamhyrWindow.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/Plot/APlot.py b/src/View/Tools/Plot/APlot.py
index e650f1ec..cb4ebf8d 100644
--- a/src/View/Tools/Plot/APlot.py
+++ b/src/View/Tools/Plot/APlot.py
@@ -1,5 +1,5 @@
# APlot.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/Plot/PamhyrCanvas.py b/src/View/Tools/Plot/PamhyrCanvas.py
index 7c3d47df..cebb1d5c 100644
--- a/src/View/Tools/Plot/PamhyrCanvas.py
+++ b/src/View/Tools/Plot/PamhyrCanvas.py
@@ -1,5 +1,5 @@
# MplCanvas.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Tools/Plot/PamhyrToolbar.py b/src/View/Tools/Plot/PamhyrToolbar.py
index 593049a0..213407f2 100644
--- a/src/View/Tools/Plot/PamhyrToolbar.py
+++ b/src/View/Tools/Plot/PamhyrToolbar.py
@@ -1,5 +1,5 @@
# PamhyrToolbar.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/Translate.py b/src/View/Translate.py
index c0872a74..7e5b70e5 100644
--- a/src/View/Translate.py
+++ b/src/View/Translate.py
@@ -1,5 +1,5 @@
# Translate.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/WaitingDialog.py b/src/View/WaitingDialog.py
index 0cba3072..581d8b2e 100644
--- a/src/View/WaitingDialog.py
+++ b/src/View/WaitingDialog.py
@@ -1,5 +1,5 @@
# WaitingDialog.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/View/ui/DebugTimer.ui b/src/View/ui/DebugTimer.ui
new file mode 100644
index 00000000..cc8a2132
--- /dev/null
+++ b/src/View/ui/DebugTimer.ui
@@ -0,0 +1,67 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 800
+ 600
+
+
+
+ MainWindow
+
+
+
+ -
+
+
+
+
+
+
+
+
+ toolBar
+
+
+ TopToolBarArea
+
+
+ false
+
+
+
+
+
+
+ ressources/export.pngressources/export.png
+
+
+ Export
+
+
+
+
+
+ ressources/reload.pngressources/reload.png
+
+
+ Reset
+
+
+
+
+
+
diff --git a/src/View/ui/about.ui b/src/View/ui/about.ui
index 1af73c2a..f8de5808 100644
--- a/src/View/ui/about.ui
+++ b/src/View/ui/about.ui
@@ -91,7 +91,7 @@
-
- Copyright © 2022-2025 INRAE
+ Copyright © 2022-2026 INRAE
diff --git a/src/config.py b/src/config.py
index d94b39ca..0b8cf1fe 100644
--- a/src/config.py
+++ b/src/config.py
@@ -1,5 +1,5 @@
# config.py -- Pamhyr configuration manager
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/init.py b/src/init.py
index c7396069..c1a1d871 100644
--- a/src/init.py
+++ b/src/init.py
@@ -1,5 +1,5 @@
# init.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -82,7 +82,7 @@ def legal_info():
logger.info(
f"version: {logger_color_green()}{version}{logger_color_reset()}")
- logger.info("license: pamhyr Copyright (C) 2023-2025 INRAE")
+ logger.info("license: pamhyr Copyright (C) 2023-2026 INRAE")
logger.info("license: This program comes with ABSOLUTELY NO WARRANTY.")
logger.info(
"license: This is free software," +
diff --git a/src/lang/constant_string.py b/src/lang/constant_string.py
index d89808f3..fae99333 100644
--- a/src/lang/constant_string.py
+++ b/src/lang/constant_string.py
@@ -1,5 +1,5 @@
# constant_string.py -- Pamhyr constant string definition for translate
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/pamhyr.py b/src/pamhyr.py
index 4193ee21..25821248 100755
--- a/src/pamhyr.py
+++ b/src/pamhyr.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# pamhyr.py -- Pamhyr entrypoint
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/test_pamhyr.py b/src/test_pamhyr.py
index d230132f..1403cee1 100644
--- a/src/test_pamhyr.py
+++ b/src/test_pamhyr.py
@@ -1,5 +1,5 @@
# test_pamhyr.py -- Pamhyr
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/src/tools.py b/src/tools.py
index b4de6800..fe214a93 100644
--- a/src/tools.py
+++ b/src/tools.py
@@ -1,5 +1,5 @@
# tools.py -- Pamhyr tools function collection
-# Copyright (C) 2023-2025 INRAE
+# Copyright (C) 2023-2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/tools/license.el b/tools/license.el
index b391de9c..d6b1ac1f 100644
--- a/tools/license.el
+++ b/tools/license.el
@@ -1,5 +1,5 @@
;; license.el -- Pamhyr
-;; Copyright (C) 2023-2025 INRAE
+;; Copyright (C) 2023-2026 INRAE
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@
(let ((filename (pamhyr-current-filename)))
(insert (format
"# %s -- Pamhyr
-# Copyright (C) 2025 INRAE
+# Copyright (C) 2026 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -47,9 +47,13 @@
(let ((pos (point)))
(goto-char (point-min))
(while (re-search-forward "Copyright (C) 2023-2025 INRAE" nil t)
- (replace-match "Copyright (C) 2023-2025 INRAE"))
+ (replace-match "Copyright (C) 2023-2026 INRAE"))
+ (while (re-search-forward "Copyright (C) 2023 INRAE" nil t)
+ (replace-match "Copyright (C) 2023-2026 INRAE"))
(while (re-search-forward "Copyright (C) 2024 INRAE" nil t)
- (replace-match "Copyright (C) 2024-2025 INRAE"))
+ (replace-match "Copyright (C) 2024-2026 INRAE"))
+ (while (re-search-forward "Copyright (C) 2025 INRAE" nil t)
+ (replace-match "Copyright (C) 2025-2026 INRAE"))
(goto-char pos)))
(defun pamhyr-root-dir-rec-aux (dir)