wolfhece 2.2.26__py3-none-any.whl → 2.2.28__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wolfhece/PyDraw.py +10 -2
- wolfhece/PyPalette.py +18 -0
- wolfhece/PyVertexvectors.py +1 -4
- wolfhece/apps/version.py +1 -1
- wolfhece/report/common.py +496 -0
- wolfhece/report/compare_arrays.py +844 -0
- wolfhece/report/simplesimgpu.py +1 -95
- wolfhece/report/tools.py +143 -23
- wolfhece/scenario/config_manager.py +22 -1
- wolfhece/wolf_array.py +49 -2
- {wolfhece-2.2.26.dist-info → wolfhece-2.2.28.dist-info}/METADATA +1 -1
- {wolfhece-2.2.26.dist-info → wolfhece-2.2.28.dist-info}/RECORD +15 -13
- {wolfhece-2.2.26.dist-info → wolfhece-2.2.28.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.26.dist-info → wolfhece-2.2.28.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.26.dist-info → wolfhece-2.2.28.dist-info}/top_level.txt +0 -0
wolfhece/report/simplesimgpu.py
CHANGED
@@ -19,106 +19,12 @@ from wolfgpu.simple_simulation import InfiltrationChronology, SimulationDuration
|
|
19
19
|
from wolfgpu.simple_simulation import boundary_condition_2D, BoundaryConditionsTypes
|
20
20
|
|
21
21
|
from .pdf import PDFViewer
|
22
|
+
from .common import cm2pts, A4_rect, rect_cm, cm2inches, list_to_html, list_to_html_aligned, get_rect_from_text
|
22
23
|
from ..wolf_array import WolfArray, header_wolf
|
23
24
|
from ..PyTranslate import _
|
24
25
|
from .. import __version__ as wolfhece_version
|
25
26
|
from wolfgpu.version import __version__ as wolfgpu_version
|
26
27
|
|
27
|
-
def cm2pts(cm):
|
28
|
-
""" Convert centimeters to points for PyMuPDF.
|
29
|
-
|
30
|
-
One point equals 1/72 inches.
|
31
|
-
"""
|
32
|
-
return cm * 28.346456692913385 # 1 cm = 28.346456692913385 points = 72/2.54
|
33
|
-
|
34
|
-
def A4_rect():
|
35
|
-
""" Return the A4 rectangle in PyMuPDF units.
|
36
|
-
|
37
|
-
(0, 0) is the top-left corner in PyMuPDF coordinates.
|
38
|
-
"""
|
39
|
-
return pdf.Rect(0, 0, cm2pts(21), cm2pts(29.7)) # A4 size in points (PDF units)
|
40
|
-
|
41
|
-
def rect_cm(x, y, width, height):
|
42
|
-
""" Create a rectangle in PyMuPDF units from centimeters.
|
43
|
-
|
44
|
-
(0, 0) is the top-left corner in PyMuPDF coordinates.
|
45
|
-
"""
|
46
|
-
return pdf.Rect(cm2pts(x), cm2pts(y), cm2pts(x) + cm2pts(width), cm2pts(y) + cm2pts(height))
|
47
|
-
|
48
|
-
def get_rect_from_text(text, width, fontsize=10, padding=5):
|
49
|
-
""" Get a rectangle that fits the text in PyMuPDF units.
|
50
|
-
|
51
|
-
:param text: The text to fit in the rectangle.
|
52
|
-
:param width: The width of the rectangle in centimeters.
|
53
|
-
:param fontsize: The font size in points.
|
54
|
-
:param padding: Padding around the text in points.
|
55
|
-
:return: A PyMuPDF rectangle that fits the text.
|
56
|
-
"""
|
57
|
-
# Create a temporary PDF document to measure the text size
|
58
|
-
with NamedTemporaryFile(delete=True, suffix='.pdf') as temp_pdf:
|
59
|
-
doc = pdf.Document()
|
60
|
-
page = doc.new_page(A4_rect())
|
61
|
-
text_rect = page.insert_text((0, 0), text, fontsize=fontsize, width=cm2pts(width))
|
62
|
-
doc.save(temp_pdf.name)
|
63
|
-
|
64
|
-
# Get the size of the text rectangle
|
65
|
-
text_width = text_rect.width + padding * 2
|
66
|
-
text_height = text_rect.height + padding * 2
|
67
|
-
# Create a rectangle with the specified width and height
|
68
|
-
rect = pdf.Rect(0, 0, cm2pts(width), text_height)
|
69
|
-
# Adjust the rectangle to fit the text
|
70
|
-
rect.x0 -= padding
|
71
|
-
rect.y0 -= padding
|
72
|
-
rect.x1 += padding
|
73
|
-
rect.y1 += padding
|
74
|
-
return rect
|
75
|
-
|
76
|
-
|
77
|
-
def list_to_html(list_items, font_size="10pt", font_family="Helvetica"):
|
78
|
-
# Génère le CSS
|
79
|
-
css = f"""
|
80
|
-
ul.custom-list {{
|
81
|
-
font-size: {font_size};
|
82
|
-
font-family: {font_family};
|
83
|
-
color: #2C3E50;
|
84
|
-
padding-left: 20px;
|
85
|
-
}}
|
86
|
-
li {{
|
87
|
-
margin-bottom: 5px;
|
88
|
-
}}
|
89
|
-
"""
|
90
|
-
|
91
|
-
# Génère le HTML
|
92
|
-
html = "<ul class='custom-list'>\n"
|
93
|
-
for item in list_items:
|
94
|
-
html += f" <li>{item}</li>\n"
|
95
|
-
html += "</ul>"
|
96
|
-
|
97
|
-
return html, css
|
98
|
-
|
99
|
-
|
100
|
-
def list_to_html_aligned(list_items, font_size="10pt", font_family="Helvetica"):
|
101
|
-
# Génère le CSS
|
102
|
-
css = f"""
|
103
|
-
ul.custom-list {{
|
104
|
-
font-size: {font_size};
|
105
|
-
font-family: {font_family};
|
106
|
-
color: #2C3E50;
|
107
|
-
padding-left: 20px;
|
108
|
-
}}
|
109
|
-
li {{
|
110
|
-
margin-bottom: 5px;
|
111
|
-
}}
|
112
|
-
"""
|
113
|
-
|
114
|
-
# Génère le HTML
|
115
|
-
html = "<div class='custom-list'>\n"
|
116
|
-
html = " - ".join(list_items) # Join the items with a hyphen
|
117
|
-
html += "</div>"
|
118
|
-
|
119
|
-
return html, css
|
120
|
-
|
121
|
-
|
122
28
|
class SimpleSimGPU_Report():
|
123
29
|
|
124
30
|
def __init__(self, sim:SimpleSimulation | Path | str, **kwargs):
|
wolfhece/report/tools.py
CHANGED
@@ -376,34 +376,57 @@ class Analysis_Scenarios():
|
|
376
376
|
|
377
377
|
def __init__(self, base_directory: Path | str, storage_directory: Path | str = None, name:str = ''):
|
378
378
|
|
379
|
+
# Default figure size for plots
|
380
|
+
self._fig_size = (20, 10)
|
381
|
+
|
382
|
+
# Name of the analysis scenarios instance
|
379
383
|
self.name = name.strip() if name else 'Analysis_Scenarios'
|
384
|
+
|
385
|
+
# Base directory for the analysis scenarios
|
386
|
+
# Must contains the directories 'projets', 'rapports', 'vecteurs', 'nuages_de_points', 'images' and 'cache'
|
380
387
|
self.base_directory = Path(base_directory)
|
388
|
+
|
389
|
+
# Storage directory for the analysis scenarios - Default is the base directory
|
381
390
|
self.storage_directory = storage_directory if storage_directory is not None else self.base_directory
|
382
391
|
|
392
|
+
# Check if the base directory exists and contains the necessary directories
|
383
393
|
self.check_directories()
|
394
|
+
# Fill the directories attribute with the paths of the analysis directories
|
384
395
|
self.directories = get_directories_as_dict(self.base_directory)
|
385
396
|
|
397
|
+
# Initialize the scenarios directories
|
386
398
|
self.scenarios_directories:dict[str:Path]
|
387
399
|
self.scenarios_directories = {}
|
400
|
+
# List of scenario names
|
388
401
|
self.scenarios = []
|
389
402
|
|
390
403
|
self.current_scenario = None
|
391
|
-
self.
|
404
|
+
self._return_periods = []
|
405
|
+
|
406
|
+
# RapidReport associated with the analysis scenarios
|
407
|
+
self.report:RapidReport = None
|
392
408
|
self._report_name = 'analysis_report.docx'
|
393
409
|
self._report_saved_once = False
|
394
|
-
self.mapviewer = None
|
395
|
-
self._background_images = None
|
396
410
|
|
397
|
-
|
411
|
+
# Map viewer for the analysis scenarios
|
412
|
+
self.mapviewer:WolfMapViewer = None
|
398
413
|
|
399
|
-
|
414
|
+
# Name of the WMS service
|
415
|
+
self._background_images:str = None
|
400
416
|
|
417
|
+
# Polygons associated with the analysis scenarios
|
418
|
+
self._polygons:dict[str, Polygons_Analyze] = {}
|
419
|
+
|
420
|
+
self._reference_polygon:Polygons_Analyze = None
|
421
|
+
|
422
|
+
# Modifications associated with the analysis scenarios
|
401
423
|
self._modifications = {}
|
402
424
|
|
425
|
+
# MultiProjects associated with the analysis scenarios.
|
426
|
+
# One project contains multiple suimulations.
|
403
427
|
self._multiprojects = None
|
404
|
-
self._cached_date = False
|
405
428
|
|
406
|
-
|
429
|
+
# Landmarks and measures associated with the analysis
|
407
430
|
self._landmarks:Zones = None
|
408
431
|
self._landmarks_s_label = []
|
409
432
|
|
@@ -414,10 +437,32 @@ class Analysis_Scenarios():
|
|
414
437
|
self._cloud:list[tuple[float, float, str]] = [] # List of tuples (s, z, label) for point clouds
|
415
438
|
|
416
439
|
self._images = {}
|
417
|
-
|
440
|
+
|
441
|
+
# Zoom (smin, smax, zmin, zmax) for the analysis
|
442
|
+
self._zoom:dict[str, tuple[float,float,float,float]] = {}
|
418
443
|
|
419
444
|
logging.info(f"Analysis directories initialized: {self.directories}")
|
420
445
|
|
446
|
+
@property
|
447
|
+
def fig_size(self) -> tuple[float]:
|
448
|
+
""" Return the default figure size for plots.
|
449
|
+
|
450
|
+
:return: A tuple (width, height) representing the default figure size.
|
451
|
+
"""
|
452
|
+
return self._fig_size
|
453
|
+
|
454
|
+
@fig_size.setter
|
455
|
+
def fig_size(self, size:tuple[float]) -> None:
|
456
|
+
""" Set the default figure size for plots.
|
457
|
+
|
458
|
+
:param size: A tuple (width, height) representing the default figure size.
|
459
|
+
"""
|
460
|
+
if not isinstance(size, tuple) or len(size) != 2:
|
461
|
+
logging.error("Default figure size must be a tuple of (width, height).")
|
462
|
+
raise ValueError("Default figure size must be a tuple of (width, height).")
|
463
|
+
self._fig_size = size
|
464
|
+
logging.info(f"Default figure size set to {self._fig_size}.")
|
465
|
+
|
421
466
|
def add_zoom(self, label:str, bounds:tuple[float]) -> None:
|
422
467
|
""" Add a zoom level to the analysis.
|
423
468
|
|
@@ -669,7 +714,13 @@ class Analysis_Scenarios():
|
|
669
714
|
logging.info(f"Landmark '{label}' added at coordinates ({x}, {y}).")
|
670
715
|
|
671
716
|
def update_landmark(self, label: str, s_xy:float |tuple[float] = None, z: float = None) -> None:
|
672
|
-
""" Update a landmark in the analysis.
|
717
|
+
""" Update a landmark in the analysis.
|
718
|
+
|
719
|
+
:param label: The label of the landmark to update.
|
720
|
+
:param s_xy: The s-coordinate or a tuple (s, xy) to update the landmark's position.
|
721
|
+
:param z: The z-coordinate to update the landmark's elevation (optional).
|
722
|
+
"""
|
723
|
+
|
673
724
|
if self._landmarks is None:
|
674
725
|
logging.error("No landmarks have been added to the analysis.")
|
675
726
|
raise ValueError("No landmarks have been added to the analysis.")
|
@@ -701,7 +752,12 @@ class Analysis_Scenarios():
|
|
701
752
|
self._landmarks_s_label[i] = (s_xy, z, label)
|
702
753
|
|
703
754
|
def plot_cloud(self, ax: plt.Axes, bounds:tuple[float]) -> plt.Axes:
|
755
|
+
""" Trace the cloud of points on an axis Matplotlib
|
704
756
|
|
757
|
+
:param ax: axe Matplotlib
|
758
|
+
:param bounds: tuple (xmin, xmax, ymin, ymax) for the plot limits
|
759
|
+
:return: The Matplotlib Axes object with the cloud plotted.
|
760
|
+
"""
|
705
761
|
xmin, xmax, ymin, ymax = bounds
|
706
762
|
|
707
763
|
used_cloud = [(s, z, label) for s, z, label in self._cloud if s >= xmin and s <= xmax]
|
@@ -713,7 +769,16 @@ class Analysis_Scenarios():
|
|
713
769
|
return ax
|
714
770
|
|
715
771
|
def plot_measures(self, ax:plt.Axes, bounds:tuple[float], style:dict = None) -> plt.Axes:
|
772
|
+
""" Trace les mesures sur un axe Matplotlib
|
773
|
+
|
774
|
+
:param ax: axe Matplotlib
|
775
|
+
:param bounds: tuple (xmin, xmax, ymin, ymax) for the plot limits
|
776
|
+
:param style: Optional style dictionary for the measures. Available properties:
|
777
|
+
- 'color': The color of the line.
|
778
|
+
- 'linestyle': The style of the line (e.g., '-', '--', '-.', ':').
|
716
779
|
|
780
|
+
:return: The Matplotlib Axes object with the measures plotted.
|
781
|
+
"""
|
717
782
|
xmin, xmax, ymin, ymax = bounds
|
718
783
|
i=0
|
719
784
|
for key, measure in self._projected_measures.items():
|
@@ -777,13 +842,17 @@ class Analysis_Scenarios():
|
|
777
842
|
bounds:tuple[float] | str,
|
778
843
|
operator:operators = operators.MEDIAN,
|
779
844
|
plot_annex:bool = True,
|
780
|
-
save:bool = False
|
845
|
+
save:bool = False,
|
846
|
+
figsize:tuple[float] = None) -> tuple[plt.Figure, plt.Axes]:
|
781
847
|
""" Plot the waterlines for a specific scenario.
|
782
848
|
|
783
849
|
:param scenario: The name of the scenario to plot waterlines for or a list of scenarios for comparison.
|
784
850
|
:param bounds: A tuple (xmin, xmax, ymin, ymax) representing the zoom bounds or a string label for a zoom level.
|
785
851
|
:param operator: The operator to apply on the waterlines.
|
786
852
|
:param save: If True, save the plot as an image file.
|
853
|
+
:param figsize: A tuple (width, height) representing the size of the figure. If None, uses the default figure size.
|
854
|
+
:param plot_annex: If True, plot the cloud of points, measures, and landmarks.
|
855
|
+
:return: A tuple (fig, ax) where fig is the matplotlib Figure and ax is the matplotlib Axes object.
|
787
856
|
"""
|
788
857
|
|
789
858
|
if isinstance(bounds, str):
|
@@ -815,34 +884,49 @@ class Analysis_Scenarios():
|
|
815
884
|
raise ValueError("At least two scenarios are required to compare waterlines.")
|
816
885
|
|
817
886
|
ref, sim = scenario[0]
|
887
|
+
|
888
|
+
if isinstance(ref, tuple):
|
889
|
+
full_name = ref[1]
|
818
890
|
ref = _sanitize_scenario_name(ref)
|
819
891
|
|
820
892
|
# plot topography / bed elevation for the reference scenario
|
821
893
|
s, z = self.get_polygon(ref).get_s_values(stored_values_unk.TOPOGRAPHY, which_group=ref, operator=operator, which_sim=sim)
|
822
894
|
fig, ax = plt.subplots(1, 1)
|
823
|
-
ax.plot(s, z, label=f"{
|
895
|
+
ax.plot(s, z, label=f"{full_name} - {_('Bathymetry')}", color='black', linestyle='-', linewidth=2)
|
824
896
|
|
825
897
|
# plot water surface elevation for the reference scenario
|
826
898
|
s, z = self.get_polygon(ref).get_s_values(stored_values_unk.WATERLEVEL, which_group=ref, operator=operator, which_sim=sim)
|
827
|
-
ax.plot(s, z, label=f"{
|
899
|
+
ax.plot(s, z, label=f"{full_name} - {sim}", color='blue', linestyle='-', linewidth=2)
|
828
900
|
|
829
901
|
# plot topography / bed elevation for the simulation scenarios
|
830
902
|
for cur_scenario in scenario[1:]:
|
831
903
|
scen_name, sim_name = cur_scenario
|
904
|
+
|
905
|
+
if isinstance(scen_name, tuple):
|
906
|
+
full_name = scen_name[1]
|
832
907
|
scen_name = _sanitize_scenario_name(scen_name)
|
833
908
|
s, z = self.get_polygon(scen_name).get_s_values(stored_values_unk.TOPOGRAPHY, which_group=scen_name, operator=operator, which_sim=sim_name)
|
834
|
-
ax.plot(s, z, label=f"{
|
909
|
+
ax.plot(s, z, label=f"{full_name} - {_('Bathymetry')}", linestyle='--', linewidth=1.5)
|
835
910
|
|
836
911
|
# plot water surface elevation for the simulation scenarios
|
837
912
|
for cur_scenario in scenario[1:]:
|
838
913
|
scen_name, sim_name = cur_scenario
|
914
|
+
if isinstance(scen_name, tuple):
|
915
|
+
full_name = scen_name[1]
|
839
916
|
scen_name = _sanitize_scenario_name(scen_name)
|
840
917
|
s, z = self.get_polygon(scen_name).get_s_values(stored_values_unk.WATERLEVEL, which_group=scen_name, operator=operator, which_sim=sim_name)
|
841
|
-
ax.plot(s, z, label=f"{
|
918
|
+
ax.plot(s, z, label=f"{full_name} - {sim_name}", linestyle='--', linewidth=1.5)
|
842
919
|
|
843
920
|
filename = self.directories[Directory_Analysis.IMAGES] / f"{self.name}_{ref}_{str(xmin)}_{str(xmax)}_waterlines_comparison.png"
|
844
921
|
|
845
|
-
|
922
|
+
if figsize is not None:
|
923
|
+
if not isinstance(figsize, tuple) or len(figsize) != 2:
|
924
|
+
logging.error("Figure size must be a tuple of (width, height).")
|
925
|
+
raise ValueError("Figure size must be a tuple of (width, height).")
|
926
|
+
fig.set_size_inches(figsize)
|
927
|
+
else:
|
928
|
+
fig.set_size_inches(self.fig_size[0], self.fig_size[1]) # Use the default figure size
|
929
|
+
|
846
930
|
ax.legend()
|
847
931
|
#zoomA
|
848
932
|
ax.set_xlim(xmin, xmax)
|
@@ -871,7 +955,8 @@ class Analysis_Scenarios():
|
|
871
955
|
bounds:tuple[float] | str,
|
872
956
|
operator:operators = operators.MEDIAN,
|
873
957
|
plot_annex:bool = True,
|
874
|
-
save:bool = False
|
958
|
+
save:bool = False,
|
959
|
+
figsize:tuple[float] = None) -> tuple[plt.Figure, plt.Axes]:
|
875
960
|
""" Plot the heads for a specific scenario.
|
876
961
|
|
877
962
|
:param scenario: The name of the scenario to plot heads for or a list of scenarios for comparison.
|
@@ -879,6 +964,8 @@ class Analysis_Scenarios():
|
|
879
964
|
:param operator: The operator to apply on the heads.
|
880
965
|
:param plot_annex: If True, plot the cloud of points, measures, and landmarks.
|
881
966
|
:param save: If True, save the plot as an image file.
|
967
|
+
:param figsize: A tuple (width, height) representing the figure size. If None, use the default figure size.
|
968
|
+
:return: A tuple (fig, ax) representing the figure and axes of the plot
|
882
969
|
"""
|
883
970
|
if isinstance(bounds, str):
|
884
971
|
# If bounds is a string, assume it's a label for a zoom level
|
@@ -914,7 +1001,14 @@ class Analysis_Scenarios():
|
|
914
1001
|
ax.plot(s, z, label=f"{scen_name} - {sim_name}", linestyle='--', linewidth=1.5)
|
915
1002
|
filename = self.directories[Directory_Analysis.IMAGES] / f"{self.name}_{ref}_{str(xmin)}_{str(xmax)}_heads_comparison.png"
|
916
1003
|
|
917
|
-
|
1004
|
+
if figsize is not None:
|
1005
|
+
if not isinstance(figsize, tuple) or len(figsize) != 2:
|
1006
|
+
logging.error("Figure size must be a tuple of (width, height).")
|
1007
|
+
raise ValueError("Figure size must be a tuple of (width, height).")
|
1008
|
+
fig.set_size_inches(figsize)
|
1009
|
+
else:
|
1010
|
+
fig.set_size_inches(self.fig_size[0], self.fig_size[1]) # Use the default figure size
|
1011
|
+
|
918
1012
|
ax.legend()
|
919
1013
|
#zoomA
|
920
1014
|
ax.set_xlim(xmin, xmax)
|
@@ -940,13 +1034,17 @@ class Analysis_Scenarios():
|
|
940
1034
|
bounds:tuple[float] | str,
|
941
1035
|
operator:operators = operators.MEDIAN,
|
942
1036
|
plot_annex:bool = True,
|
943
|
-
save:bool = False
|
1037
|
+
save:bool = False,
|
1038
|
+
figsize:tuple[float] = None) -> tuple[plt.Figure, plt.Axes]:
|
944
1039
|
""" Plot the Froude for a specific scenario.
|
945
1040
|
|
946
1041
|
:param scenario: The name of the scenario to plot waterlines for or a list of scenarios for comparison.
|
947
1042
|
:param bounds: A tuple (xmin, xmax, ymin, ymax) representing the zoom bounds or a string label for a zoom level.
|
948
1043
|
:param operator: The operator to apply on the waterlines.
|
949
1044
|
:param save: If True, save the plot as an image file.
|
1045
|
+
:param figsize: A tuple (width, height) representing the figure size. If None, use the default figure size.
|
1046
|
+
:param plot_annex: If True, plot the cloud of points, measures, and landmarks.
|
1047
|
+
:return: A tuple (fig, ax) representing the figure and axes of the plot
|
950
1048
|
"""
|
951
1049
|
|
952
1050
|
if isinstance(bounds, str):
|
@@ -963,6 +1061,8 @@ class Analysis_Scenarios():
|
|
963
1061
|
|
964
1062
|
if isinstance(scenario, (str, tuple)):
|
965
1063
|
|
1064
|
+
if isinstance(scenario, tuple):
|
1065
|
+
full_name = scenario[1]
|
966
1066
|
scenario = _sanitize_scenario_name(scenario)
|
967
1067
|
|
968
1068
|
fig,ax = plt.subplots(1,1)
|
@@ -971,7 +1071,7 @@ class Analysis_Scenarios():
|
|
971
1071
|
for sim in self.list_sims_in_polygons(scenario):
|
972
1072
|
# plot Froude number for the reference scenario
|
973
1073
|
s, z = self.get_polygon(scenario).get_s_values(stored_values_unk.FROUDE, which_group=scenario, operator=operator, which_sim=sim)
|
974
|
-
ax.plot(s, z, label=f"{
|
1074
|
+
ax.plot(s, z, label=f"{sim}", linestyle='-', linewidth=1.5)
|
975
1075
|
|
976
1076
|
filename = self.directories[Directory_Analysis.IMAGES] / f"{self.name}_{scenario}_{str(xmin)}_{str(xmax)}_Froude.png"
|
977
1077
|
|
@@ -985,22 +1085,34 @@ class Analysis_Scenarios():
|
|
985
1085
|
fig,ax = plt.subplots(1,1)
|
986
1086
|
|
987
1087
|
ref, sim = scenario[0]
|
1088
|
+
|
1089
|
+
if isinstance(ref, tuple):
|
1090
|
+
full_name = ref[1]
|
988
1091
|
ref = _sanitize_scenario_name(ref)
|
989
1092
|
|
990
1093
|
# plot water surface elevation for the reference scenario
|
991
1094
|
s, z = self.get_polygon(ref).get_s_values(stored_values_unk.FROUDE, which_group=ref, operator=operator, which_sim=sim)
|
992
|
-
ax.plot(s, z, label=f"{
|
1095
|
+
ax.plot(s, z, label=f"{full_name} - {sim}", color='blue', linestyle='-', linewidth=2)
|
993
1096
|
|
994
1097
|
# plot water surface elevation for the simulation scenarios
|
995
1098
|
for cur_scenario in scenario[1:]:
|
996
1099
|
scen_name, sim_name = cur_scenario
|
1100
|
+
if isinstance(scen_name, tuple):
|
1101
|
+
full_name = scen_name[1]
|
997
1102
|
scen_name = _sanitize_scenario_name(scen_name)
|
998
1103
|
s, z = self.get_polygon(scen_name).get_s_values(stored_values_unk.FROUDE, which_group=scen_name, operator=operator, which_sim=sim_name)
|
999
|
-
ax.plot(s, z, label=f"{
|
1104
|
+
ax.plot(s, z, label=f"{full_name} - {sim_name}", linestyle='--', linewidth=1.5)
|
1000
1105
|
|
1001
1106
|
filename = self.directories[Directory_Analysis.IMAGES] / f"{self.name}_{ref}_{str(xmin)}_{str(xmax)}_Froude_comparison.png"
|
1002
1107
|
|
1003
|
-
|
1108
|
+
if figsize is not None:
|
1109
|
+
if not isinstance(figsize, tuple) or len(figsize) != 2:
|
1110
|
+
logging.error("Figure size must be a tuple of (width, height).")
|
1111
|
+
raise ValueError("Figure size must be a tuple of (width, height).")
|
1112
|
+
fig.set_size_inches(figsize)
|
1113
|
+
else:
|
1114
|
+
fig.set_size_inches(self.fig_size[0], self.fig_size[1]) # Use the default figure size
|
1115
|
+
|
1004
1116
|
ax.legend()
|
1005
1117
|
#zoomA
|
1006
1118
|
ax.set_xlim(xmin, xmax)
|
@@ -1724,6 +1836,8 @@ class Analysis_Scenarios():
|
|
1724
1836
|
|
1725
1837
|
:param scenario_name: The name of the scenario to set as current.
|
1726
1838
|
"""
|
1839
|
+
|
1840
|
+
scenario_name = _sanitize_scenario_name(scenario_name)
|
1727
1841
|
if scenario_name not in self.scenarios_directories:
|
1728
1842
|
logging.error(f"Scenario '{scenario_name}' not found in the analysis.")
|
1729
1843
|
raise ValueError(f"Scenario '{scenario_name}' not found in the analysis.")
|
@@ -1737,6 +1851,8 @@ class Analysis_Scenarios():
|
|
1737
1851
|
:param scenario_name: The name of the scenario to get.
|
1738
1852
|
:return: The path to the scenario directory.
|
1739
1853
|
"""
|
1854
|
+
|
1855
|
+
scenario_name = _sanitize_scenario_name(scenario_name)
|
1740
1856
|
if scenario_name not in self.scenarios_directories:
|
1741
1857
|
logging.error(f"Scenario '{scenario_name}' not found in the analysis.")
|
1742
1858
|
raise KeyError(f"Scenario '{scenario_name}' not found in the analysis.")
|
@@ -1848,7 +1964,11 @@ L'attention est toutefois attirée sur le fait que cette approche pourrait ne pa
|
|
1848
1964
|
return fig, ax
|
1849
1965
|
|
1850
1966
|
def load_modifications(self, ad2viewer:bool = True):
|
1851
|
-
""" Load modifications for scenarios from vecz files.
|
1967
|
+
""" Load modifications for scenarios from vecz files.
|
1968
|
+
|
1969
|
+
:param ad2viewer: If True, add the modifications to the map viewer.
|
1970
|
+
:raises ValueError: If the MapViewer is not initialized.
|
1971
|
+
"""
|
1852
1972
|
|
1853
1973
|
MODIF = 'bath_assembly.vecz'
|
1854
1974
|
|
@@ -671,7 +671,13 @@ class Config_Manager_2D_GPU:
|
|
671
671
|
ok &= (GPU_2D_file.PARAMETERS.value.name+GPU_2D_file.PARAMETERS.value.extension).lower() in [cur.name.lower() for cur in curdict[GPU_2D_file_extensions.JSON.value]]
|
672
672
|
|
673
673
|
if ok:
|
674
|
-
|
674
|
+
try:
|
675
|
+
json_data = json.load(open(curdict['path'] / (GPU_2D_file.PARAMETERS.value.name+GPU_2D_file.PARAMETERS.value.extension), 'r'))
|
676
|
+
except json.JSONDecodeError as e:
|
677
|
+
logging.error(_('Error decoding JSON file: {}').format(e))
|
678
|
+
curdict['missing'].append(GPU_2D_file_extensions.JSON.value)
|
679
|
+
ok = False
|
680
|
+
return
|
675
681
|
|
676
682
|
else:
|
677
683
|
curdict['missing'].append(GPU_2D_file_extensions.JSON.value)
|
@@ -1382,6 +1388,7 @@ class Config_Manager_2D_GPU:
|
|
1382
1388
|
logging.error(_('Infiltration .tif must be a full integer array ! -- The array will be ignored !'))
|
1383
1389
|
infiltration = WolfArray(srcheader=bat.get_header(), whichtype= WOLF_ARRAY_FULL_INTEGER)
|
1384
1390
|
infiltration.array.data[:,:] = 0
|
1391
|
+
|
1385
1392
|
else:
|
1386
1393
|
infiltration = WolfArray(srcheader=bat.get_header(), whichtype= WOLF_ARRAY_FULL_INTEGER)
|
1387
1394
|
infiltration.array.data[:,:] = 0
|
@@ -1494,6 +1501,20 @@ class Config_Manager_2D_GPU:
|
|
1494
1501
|
else:
|
1495
1502
|
cursim.qy = np.zeros((self._header.nbx, self._header.nby), dtype=np.float32)
|
1496
1503
|
|
1504
|
+
|
1505
|
+
# check if infiltration array is strictly inside nap
|
1506
|
+
if not np.all(cursim.nap[infiltration.array.data[infiltration.array.data > 0]] == 1):
|
1507
|
+
logging.warning(_('Infiltration zones must be strictly inside the NAP !'))
|
1508
|
+
logging.warning(_('Infiltration zones outside NAP will be set to 0 !'))
|
1509
|
+
|
1510
|
+
#count number of infiltration zones outside NAP
|
1511
|
+
nb_outside = np.sum(infiltration.array.data[(infiltration.array.data > 0) & (cursim.nap == 0)])
|
1512
|
+
logging.warning(_('Number of infiltration zones outside NAP: {}').format(nb_outside))
|
1513
|
+
# index infiltration zones outside NAP
|
1514
|
+
indices = list(set(infiltration.array.data[(infiltration.array.data > 0) & (cursim.nap == 0)]))
|
1515
|
+
logging.warning(_('Indices of infiltration zones outside NAP: {}').format(indices))
|
1516
|
+
infiltration.array.data[(infiltration.array.data > 0) & (cursim.nap == 0)] = 0
|
1517
|
+
|
1497
1518
|
cursim.infiltration_zones = np.asarray(infiltration.array.data, dtype=np.int32)
|
1498
1519
|
|
1499
1520
|
if roof.nbnotnull == 0:
|
wolfhece/wolf_array.py
CHANGED
@@ -987,7 +987,7 @@ class header_wolf():
|
|
987
987
|
if "base_coord_y" in params['parameters'].keys() :
|
988
988
|
self.origy = float(params['parameters']["base_coord_y"])
|
989
989
|
|
990
|
-
self.nullvalue = 99999.
|
990
|
+
self.nullvalue = 0 if 'nap.npy' in filename.lower() else 99999.
|
991
991
|
else:
|
992
992
|
|
993
993
|
self.dx = 1.
|
@@ -10459,7 +10459,9 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
10459
10459
|
Walonmap:bool=False,
|
10460
10460
|
cat:str='IMAGERIE/ORTHO_2022_ETE',
|
10461
10461
|
first_mask_data:bool=True,
|
10462
|
-
with_legend:bool=False
|
10462
|
+
with_legend:bool=False,
|
10463
|
+
IGN:bool=False,
|
10464
|
+
Cartoweb:bool=False):
|
10463
10465
|
"""
|
10464
10466
|
Plot the array - Matplotlib version
|
10465
10467
|
|
@@ -10555,6 +10557,51 @@ class WolfArray(Element_To_Draw, header_wolf):
|
|
10555
10557
|
except Exception as e:
|
10556
10558
|
logging.error(_('Error while fetching the map image from WalOnMap'))
|
10557
10559
|
logging.error(e)
|
10560
|
+
elif IGN:
|
10561
|
+
from .PyWMS import getNGI
|
10562
|
+
from PIL import Image
|
10563
|
+
try:
|
10564
|
+
bounds = self.get_bounds()
|
10565
|
+
scale_xovery = (bounds[0][1] - bounds[0][0]) / (bounds[1][1] - bounds[1][0])
|
10566
|
+
if scale_xovery > 1.:
|
10567
|
+
# x is larger than y
|
10568
|
+
w = 2000
|
10569
|
+
h = int(2000 / scale_xovery)
|
10570
|
+
else:
|
10571
|
+
# y is larger than x
|
10572
|
+
h = 2000
|
10573
|
+
w = int(2000 * scale_xovery)
|
10574
|
+
IO_image = getNGI(cat, bounds[0][0], bounds[1][0],
|
10575
|
+
bounds[0][1], bounds[1][1],
|
10576
|
+
w=w, h=h, tofile=False) # w=self.nbx, h=self.nby
|
10577
|
+
image = Image.open(IO_image)
|
10578
|
+
ax.imshow(image.transpose(Image.Transpose.FLIP_TOP_BOTTOM), extent=(bounds[0][0], bounds[0][1], bounds[1][0], bounds[1][1]), alpha=1, origin='lower')
|
10579
|
+
except Exception as e:
|
10580
|
+
logging.error(_('Error while fetching the map image from IGN'))
|
10581
|
+
logging.error(e)
|
10582
|
+
|
10583
|
+
elif Cartoweb:
|
10584
|
+
from .PyWMS import getCartoweb
|
10585
|
+
from PIL import Image
|
10586
|
+
try:
|
10587
|
+
bounds = self.get_bounds()
|
10588
|
+
scale_xovery = (bounds[0][1] - bounds[0][0]) / (bounds[1][1] - bounds[1][0])
|
10589
|
+
if scale_xovery > 1.:
|
10590
|
+
# x is larger than y
|
10591
|
+
w = 2000
|
10592
|
+
h = int(2000 / scale_xovery)
|
10593
|
+
else:
|
10594
|
+
# y is larger than x
|
10595
|
+
h = 2000
|
10596
|
+
w = int(2000 * scale_xovery)
|
10597
|
+
IO_image = getCartoweb(cat, bounds[0][0], bounds[1][0],
|
10598
|
+
bounds[0][1], bounds[1][1],
|
10599
|
+
w=w, h=h, tofile=False) # w=self.nbx, h=self.nby
|
10600
|
+
image = Image.open(IO_image)
|
10601
|
+
ax.imshow(image.transpose(Image.Transpose.FLIP_TOP_BOTTOM), extent=(bounds[0][0], bounds[0][1], bounds[1][0], bounds[1][1]), alpha=1, origin='lower')
|
10602
|
+
except Exception as e:
|
10603
|
+
logging.error(_('Error while fetching the map image from Cartoweb'))
|
10604
|
+
logging.error(e)
|
10558
10605
|
|
10559
10606
|
if vmin is None and vmax is not None:
|
10560
10607
|
vmin = self.mypal.values[0]
|
@@ -8,16 +8,16 @@ wolfhece/Model1D.py,sha256=snEmu8Uj2YGcp1ybPnly-4A389XRnuOujGduqInNcgw,477001
|
|
8
8
|
wolfhece/PandasGrid.py,sha256=YIleVkUkoP2MjtQBZ9Xgwk61zbgMj4Pmjj-clVTfPRs,2353
|
9
9
|
wolfhece/PyConfig.py,sha256=Y0wtSIFpAMYa7IByh7hbW-WEOVjNsQEduq7vhIYdZQw,16716
|
10
10
|
wolfhece/PyCrosssections.py,sha256=igU_ELrg5VrHU6RNbF5tHxPyVImpR3xdpfopJYc7haw,114711
|
11
|
-
wolfhece/PyDraw.py,sha256=
|
11
|
+
wolfhece/PyDraw.py,sha256=zK2k-KC1VpqYTTJIfO_CPEjHWBoQh1h2xXMafE4ECGY,662673
|
12
12
|
wolfhece/PyGui.py,sha256=DqMTDsC9GthnMdYOXvkMKfl5pNciExVzxG4ogptWf6g,146010
|
13
13
|
wolfhece/PyGuiHydrology.py,sha256=sKafpOopBg50L5llZCI_fZtbebVTDtxvoRI6-osUwhg,14745
|
14
14
|
wolfhece/PyHydrographs.py,sha256=1P5XAURNqCvtSsMQXhOn1ihjTpr725sRsZdlCEhhk6M,3730
|
15
|
-
wolfhece/PyPalette.py,sha256=
|
15
|
+
wolfhece/PyPalette.py,sha256=SiRngKml2EXsq1jwQvqh5pBZiV1yS0CY7QrRJGSZD1s,36281
|
16
16
|
wolfhece/PyParams.py,sha256=BgTAwxxq831rYEq_KLcFBX_upjiSUpVtfoQnCxCNWUI,100443
|
17
17
|
wolfhece/PyPictures.py,sha256=m1kY0saW6Y9Q0bDCo47lW6XxDkBrbQG-Fd8uVn8G5ic,2514
|
18
18
|
wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
|
19
19
|
wolfhece/PyVertex.py,sha256=a56oY1NB45QnwARg96Tbnq-z-mhZKFkYOkFOO1lNtlk,51056
|
20
|
-
wolfhece/PyVertexvectors.py,sha256=
|
20
|
+
wolfhece/PyVertexvectors.py,sha256=57-4vU-C8KIIf3iPjDzmNNqSKsIM3SRhSbT4V_md5TM,336874
|
21
21
|
wolfhece/PyWMS.py,sha256=-wU-oWS5il1z702gYd90xHx5O7PvGNr9nb693oue_cI,31412
|
22
22
|
wolfhece/RatingCurve.py,sha256=bUjIrQjvIjkD4V-z8bZmA6pe1ILtYNM0-3fT6YUY1RU,22498
|
23
23
|
wolfhece/RatingCurveData.py,sha256=5UvnIm89BwqjnEbLCcY3CA8WoFd_xHJbooNy62fX5iY,57660
|
@@ -60,7 +60,7 @@ wolfhece/rain_SPWMI.py,sha256=qCfcmF7LajloOaCwnTrrSMzyME03YyilmRUOqrPrv3U,13846
|
|
60
60
|
wolfhece/textpillow.py,sha256=map7HsGYML_o5NHRdFg2s_TVQed_lDnpYNDv27MM0Vw,14130
|
61
61
|
wolfhece/tools2d_dll.py,sha256=TfvvmyZUqEZIH0uHwUCJf0bdmCks_AiidDt23Unsp5w,13550
|
62
62
|
wolfhece/tools_mpl.py,sha256=gQ3Jg1iuZiecmMqa5Eli2ZLSkttu68VXL8YmMDBaEYU,564
|
63
|
-
wolfhece/wolf_array.py,sha256=
|
63
|
+
wolfhece/wolf_array.py,sha256=nkU6-pSin-OF5BvgDsdSg6aywsdCQdeNVXtFblriXsw,521716
|
64
64
|
wolfhece/wolf_hist.py,sha256=fTEb60Q4TEwobdZsRU4CFXAId1eOKdWAqF8lnF1xEWc,3590
|
65
65
|
wolfhece/wolf_texture.py,sha256=8BcVSezLEogTHYmtA4yfSPzaw6UpAeYYySVaAowIKtQ,20858
|
66
66
|
wolfhece/wolf_tiles.py,sha256=v-HohqaWuMYdn75XLnA22dlloAG90iwnIqrgnB0ASQ4,10488
|
@@ -88,7 +88,7 @@ wolfhece/apps/curvedigitizer.py,sha256=lEJJwgAfulrrWQc-U6ij6sj59hWN3SZl4Yu1kQxVz
|
|
88
88
|
wolfhece/apps/hydrometry.py,sha256=lhhJsFeb4zGL4bNQTs0co85OQ_6ssL1Oy0OUJCzhfYE,656
|
89
89
|
wolfhece/apps/isocurrent.py,sha256=dagmGR8ja9QQ1gwz_8fU-N052hIw-W0mWGVkzLu6C7I,4247
|
90
90
|
wolfhece/apps/splashscreen.py,sha256=EdGDN9NhudIiP7c3gVqj7dp4MWFB8ySizM_tpMnsgpE,3091
|
91
|
-
wolfhece/apps/version.py,sha256=
|
91
|
+
wolfhece/apps/version.py,sha256=pK3K0wU-fe8-W4tB4CsiRNctriME-0MPLh4L7BAsJEY,388
|
92
92
|
wolfhece/apps/wolf.py,sha256=mRnjYsUu4KIsRuamdQWAINFMuwN4eJgMo9erG-hkZ70,729
|
93
93
|
wolfhece/apps/wolf2D.py,sha256=4z_OPQ3IgaLtjexjMKX9ppvqEYyjFLt1hcfFABy3-jU,703
|
94
94
|
wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
|
@@ -265,14 +265,16 @@ wolfhece/rem/REMMaker.py,sha256=zkiAo36MmusPhgv1qJmpDgtoTWbh_eJ6qJqtCfeC1M8,3148
|
|
265
265
|
wolfhece/rem/RasterViz.py,sha256=fnyMfAJZDoS-rjagsNRGLndS-UYNUzMY4DgenjD3Y_4,29068
|
266
266
|
wolfhece/rem/__init__.py,sha256=S2-J5uEGK_VaMFjRUYFIdSScJjZyuXH4RmMmnG3OG7I,19
|
267
267
|
wolfhece/report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
268
|
+
wolfhece/report/common.py,sha256=7a6zQ-wLZ0ElUVodWCO08TyRBXrI7lnTrosJGcV5_tM,17619
|
269
|
+
wolfhece/report/compare_arrays.py,sha256=JuaSfRV0VXVirLfdCJzP2XSLtfRi0R73-vhtTI6fneg,33232
|
268
270
|
wolfhece/report/pdf.py,sha256=zrSSY1JPk59FxK9pFWQfhVKIQAoc_wjeTrXO3tSiEHo,1959
|
269
271
|
wolfhece/report/reporting.py,sha256=JUEXovx_S4jpYkJEBU0AC-1Qw2OkkWyV3VAp6iOfSHc,19494
|
270
|
-
wolfhece/report/simplesimgpu.py,sha256=
|
271
|
-
wolfhece/report/tools.py,sha256=
|
272
|
+
wolfhece/report/simplesimgpu.py,sha256=qwf8EZnSu_DEmxFNAxYLElvCgjEKcCm3_-tvX8wUvdk,57932
|
273
|
+
wolfhece/report/tools.py,sha256=ZA4PfHQXgvDtTnrSZh-oSwhQT_cQtb49LuZB8VI7nyI,96852
|
272
274
|
wolfhece/report/wolf_report.png,sha256=NoSV58LSwb-oxCcZScRiJno-kxDwRdm_bK-fiMsKJdA,592485
|
273
275
|
wolfhece/scenario/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
274
276
|
wolfhece/scenario/check_scenario.py,sha256=d-LWa_FxmPxTSc_H1lDHwqLB6TCqj1IUrRJhatfPMMA,5623
|
275
|
-
wolfhece/scenario/config_manager.py,sha256=
|
277
|
+
wolfhece/scenario/config_manager.py,sha256=00xo6e-mLxZEK1atiHKfr2MSuJ_n6QgO3fQsHDYf3mI,115588
|
276
278
|
wolfhece/scenario/imposebc_void.py,sha256=PqA_99hKcaqK5zsK6IRIc5Exgg3WVpgWU8xpwNL49zQ,5571
|
277
279
|
wolfhece/scenario/update_void.py,sha256=Yb7TMIUx9Gzm9_6qRMJnF39Uqi17dIkMmscSXo2WaTs,10033
|
278
280
|
wolfhece/shaders/fragment_shader_texture.glsl,sha256=w6h8d5mJqFaGbao0LGmjRcFFdcEQ3ICIl9JpuT71K5k,177
|
@@ -301,8 +303,8 @@ wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=8PlMYrb_8jI8h9F0_EagpM
|
|
301
303
|
wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=ORy7fz4dcp691qKzaOZHrRLZ0uXNhL-LIHxmpDGL6BI,5007
|
302
304
|
wolfhece/wintab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
303
305
|
wolfhece/wintab/wintab.py,sha256=8A-JNONV6ujgsgG3lM5Uw-pVgglPATwKs86oBzzljoc,7179
|
304
|
-
wolfhece-2.2.
|
305
|
-
wolfhece-2.2.
|
306
|
-
wolfhece-2.2.
|
307
|
-
wolfhece-2.2.
|
308
|
-
wolfhece-2.2.
|
306
|
+
wolfhece-2.2.28.dist-info/METADATA,sha256=9fInjN6bCfzKHTXS3cFPY_au-O9JrPLujBu3zYKLADE,2729
|
307
|
+
wolfhece-2.2.28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
308
|
+
wolfhece-2.2.28.dist-info/entry_points.txt,sha256=Jr187pyvA3EeJiQLjZK9yo6mJX7IAn6ygZU9T8qF_gQ,658
|
309
|
+
wolfhece-2.2.28.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
|
310
|
+
wolfhece-2.2.28.dist-info/RECORD,,
|
File without changes
|
File without changes
|