wolfhece 2.2.28__py3-none-any.whl → 2.2.29__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.
@@ -0,0 +1,36 @@
1
+ # be_ign_README.txt
2
+
3
+ The files in this section result from the conversion of datasets originating
4
+ from [IGN Belgium](http://www.ngi.be)
5
+
6
+ ## Included grids
7
+
8
+ ### Belgium: BD72 -> ETRS89
9
+
10
+ Grid transformation from Belgium Datum 72 to ETRS89 in Belgium.
11
+
12
+ *Source*: [IGN](http://www.ngi.be/Common/Lambert2008/NTv2.zip)
13
+ *Format*: GeoTIFF converted from NTv2
14
+ *License*: [Creative Commons Attribution 4.0](https://creativecommons.org/licenses/by/4.0/)
15
+ *Credit*: (c)2014-2016 Grid created by Nicolas SIMON.
16
+
17
+ It provides an accuracy better than 5mm in 99.6% of validation points and a
18
+ worst case of 1.3 cm outside the border.
19
+ Recommended to transform from Belgian Lambert 72 (EPSG:31370) to Belgian Lambert 2008 (EPSG:3812)
20
+ Documentation in French: (http://www.ngi.be/FR/FR2-1-7.shtm)
21
+ Documentation in Dutch: (http://www.ngi.be/NL/NL2-1-7.shtm)
22
+
23
+ * be_ign_bd72lb72_etrs89lb08.tif
24
+
25
+ ### Belgium vertical grid:
26
+
27
+ *Source*: [IGN](https://www.ngi.be/website/wp-content/uploads/2020/07/hBG18_fr.zip)
28
+ *Format*: GeoTIFF converted from 'XYZ ASCII Grid'
29
+ *License*: [Creative Commons Attribution 4.0](https://creativecommons.org/licenses/by/4.0/)
30
+ *Credit*: C. Slobbe, R. Klees, H.H. Farahani, L. Huisman, B. Alberts, P. Voet, F. De Doncker (2018). The Belgian hybrid quasi-geoid: hBG18. V. 1.0. GFZ Data Services. http://doi.org/10.5880/isg.2018.003
31
+ *Horizontal CRS*: EPSG:4937 (ETRS89)
32
+
33
+ Vertical transformation for Geoid model hGB18. Used to make the transitions
34
+ from heights in vertical CRS (EPSG:5710 - Ostend height) to heights above the ellipsoid in ETRS89 (EPSG:4937).
35
+
36
+ * be_ign_hBG18.tif
Binary file
wolfhece/mesh2d/gpu_2d.py CHANGED
@@ -88,8 +88,17 @@ class Sim_2D_GPU():
88
88
  self.magnetic_grid:header_wolf = None
89
89
 
90
90
  if (self.dir /'parameters.json').exists():
91
- self._sim = SimpleSimulation.load(self.dir)
92
- self.infiltration = infiltration_GPU(self)
91
+ try:
92
+ self._sim = SimpleSimulation.load(self.dir)
93
+ except Exception as e:
94
+ logging.error(_("Error loading simulation from directory {dir}: {error}").format(dir=self.dir, error=str(e)))
95
+ logging.error(_("Please check your files and try again."))
96
+ return
97
+
98
+ try:
99
+ self.infiltration = infiltration_GPU(self)
100
+ except Exception as e:
101
+ logging.error(_("Error initializing infiltration GPU: {error}").format(error=str(e)))
93
102
 
94
103
  # Fine arrays with type
95
104
  self.files_array={'Characteristics':[
@@ -4,13 +4,17 @@ import numpy.ma as ma
4
4
  from pathlib import Path
5
5
  import matplotlib.pyplot as plt
6
6
  from enum import Enum
7
- from scipy.ndimage import label, sum_labels
7
+ from scipy.ndimage import label, sum_labels, find_objects
8
8
  import pymupdf as pdf
9
+ import wx
10
+ from tqdm import tqdm
11
+ from matplotlib import use, get_backend
9
12
 
10
13
  from .common import A4_rect, rect_cm, list_to_html, list_to_html_aligned, get_rect_from_text
11
14
  from .common import inches2cm, pts2cm, cm2pts, cm2inches, DefaultLayoutA4, NamedTemporaryFile, pt2inches, TemporaryDirectory
12
15
  from ..wolf_array import WolfArray, header_wolf, vector, zone, Zones, wolfvertex as wv, wolfpalette
13
16
  from ..PyTranslate import _
17
+ from .pdf import PDFViewer
14
18
 
15
19
  class ArrayDifferenceLayout(DefaultLayoutA4):
16
20
  """
@@ -98,8 +102,16 @@ class ArrayDifference():
98
102
 
99
103
  self._background = 'IGN'
100
104
 
105
+ self._contour = None
106
+ self._external_border = None
107
+
101
108
  @property
102
109
  def contour(self) -> vector:
110
+ """ Get the contour of the difference part. """
111
+
112
+ if self._contour is not None and isinstance(self._contour, vector):
113
+ return self._contour
114
+
103
115
  ret = self.reference.suxsuy_contour(abs=True)
104
116
  ret = ret[2]
105
117
 
@@ -111,8 +123,11 @@ class ArrayDifference():
111
123
  @property
112
124
  def external_border(self) -> vector:
113
125
  """
114
- Get the bounds of the reference array.
126
+ Get the bounds of the difference part.
115
127
  """
128
+ if self._external_border is not None and isinstance(self._external_border, vector):
129
+ return self._external_border
130
+
116
131
  ret = vector(name=_("External border"))
117
132
  (xmin, xmax), (ymin, ymax) = self.reference.get_bounds()
118
133
  ret.add_vertex(wv(xmin, ymin))
@@ -194,6 +209,13 @@ class ArrayDifference():
194
209
  Walonmap= True,
195
210
  cat = 'IMAGERIE/ORTHO_2022_ETE',
196
211
  )
212
+ else:
213
+ self.reference.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
214
+ first_mask_data=False, with_legend=False,
215
+ update_palette= False,
216
+ Walonmap= False,
217
+ )
218
+
197
219
 
198
220
  self.reference.array.mask[:,:] = old_mask
199
221
 
@@ -225,11 +247,23 @@ class ArrayDifference():
225
247
  new = WolfArray(srcheader=h)
226
248
  new.array.mask[:,:] = True
227
249
 
228
- new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
229
- first_mask_data=False, with_legend=False,
230
- update_palette= False,
231
- Walonmap= True,
232
- cat = 'IMAGERIE/ORTHO_2022_ETE')
250
+ if self._background.upper() == 'IGN' or self._background.upper() == 'NGI':
251
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
252
+ first_mask_data=False, with_legend=False,
253
+ update_palette= False,
254
+ IGN= True,
255
+ cat = 'orthoimage_coverage')
256
+ elif self._background.upper() == 'WALONMAP':
257
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
258
+ first_mask_data=False, with_legend=False,
259
+ update_palette= False,
260
+ Walonmap= True,
261
+ cat = 'IMAGERIE/ORTHO_2022_ETE')
262
+ else:
263
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
264
+ first_mask_data=False, with_legend=False,
265
+ update_palette= False,
266
+ Walonmap= False)
233
267
 
234
268
  self.external_border.plot_matplotlib(ax=ax)
235
269
 
@@ -295,7 +329,8 @@ class ArrayDifference():
295
329
 
296
330
  fig, ax = figax
297
331
 
298
- ax.hist(self.reference.array.compressed(), density=density, alpha = alpha, **kwargs)
332
+ data = self.reference.array.compressed()
333
+ ax.hist(data, bins = min(100, int(len(data)/4)), density=density, alpha = alpha, **kwargs)
299
334
  # ax.set_xlabel("Value")
300
335
  # ax.set_ylabel("Frequency")
301
336
  return fig, ax
@@ -309,7 +344,8 @@ class ArrayDifference():
309
344
 
310
345
  fig, ax = figax
311
346
 
312
- ax.hist(self.to_compare.array.compressed(), density=density, alpha = alpha, **kwargs)
347
+ data = self.to_compare.array.compressed()
348
+ ax.hist(data, bins= min(100, int(len(data)/4)), density=density, alpha = alpha, **kwargs)
313
349
  # ax.set_xlabel("Value")
314
350
  # ax.set_ylabel("Frequency")
315
351
  return fig, ax
@@ -349,7 +385,7 @@ class ArrayDifference():
349
385
  fig, ax = figax
350
386
 
351
387
  difference_data = self.difference.array.compressed()
352
- ax.hist(difference_data, density=density, alpha=alpha, **kwargs)
388
+ ax.hist(difference_data, bins= min(100, int(len(difference_data)/4)), density=density, alpha=alpha, **kwargs)
353
389
 
354
390
  # ax.set_xlabel("Value")
355
391
  # ax.set_ylabel("Frequency")
@@ -396,7 +432,6 @@ class ArrayDifference():
396
432
  if 'Histogram' in key:
397
433
  fig.tight_layout()
398
434
 
399
-
400
435
  # convert canvas to PNG and insert it into the PDF
401
436
  temp_file = NamedTemporaryFile(delete=False, suffix='.png')
402
437
  fig.savefig(temp_file, format='png', bbox_inches='tight', dpi=self._dpi)
@@ -419,6 +454,7 @@ class ArrayDifference():
419
454
  def create_report(self, output_file: str | Path = None) -> Path:
420
455
  """ Create a page report for the array difference. """
421
456
 
457
+ from time import sleep
422
458
  if output_file is None:
423
459
  output_file = Path(f"array_difference_{self.index}.pdf")
424
460
 
@@ -429,6 +465,7 @@ class ArrayDifference():
429
465
  layout.create_report()
430
466
  self._complete_report(layout)
431
467
  layout.save_report(output_file)
468
+ sleep(0.2) # Ensure the file is saved before returning
432
469
 
433
470
  return output_file
434
471
 
@@ -459,6 +496,10 @@ class CompareArrays:
459
496
 
460
497
  self.difference_parts:dict[int, ArrayDifference] = {}
461
498
 
499
+ self._pdf_path = None
500
+
501
+ self._background = 'IGN'
502
+
462
503
  @property
463
504
  def difference(self) -> WolfArray:
464
505
 
@@ -467,6 +508,24 @@ class CompareArrays:
467
508
 
468
509
  return self.array_to_compare - self.array_reference
469
510
 
511
+ def get_zones(self):
512
+ """
513
+ Get a Zones object containing the differences.
514
+ """
515
+
516
+ ret_zones = Zones()
517
+ exterior = zone(name=_("External border"))
518
+ contours = zone(name=_("Contours"))
519
+
520
+ ret_zones.add_zone(exterior, forceparent=True)
521
+ ret_zones.add_zone(contours, forceparent=True)
522
+
523
+ for diff in self.difference_parts.values():
524
+ exterior.add_vector(diff.external_border, forceparent=True)
525
+ contours.add_vector(diff.contour, forceparent=True)
526
+
527
+ return ret_zones
528
+
470
529
  def plot_position(self, figax:tuple[plt.Figure, plt.Axes]=None) -> tuple[plt.Figure, plt.Axes]:
471
530
  """
472
531
  Plot the reference array with a background.
@@ -487,14 +546,27 @@ class CompareArrays:
487
546
  new = WolfArray(srcheader=h)
488
547
  new.array.mask[:,:] = True
489
548
 
549
+ if self._background.upper() == 'IGN' or self._background.upper() == 'NGI':
490
550
 
491
- new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
492
- first_mask_data=False, with_legend=False,
493
- update_palette= False,
494
- IGN= True,
495
- cat = 'orthoimage_coverage',
496
- )
497
-
551
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
552
+ first_mask_data=False, with_legend=False,
553
+ update_palette= False,
554
+ IGN= True,
555
+ cat = 'orthoimage_coverage',
556
+ )
557
+ elif self._background.upper() == 'WALONMAP':
558
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
559
+ first_mask_data=False, with_legend=False,
560
+ update_palette= False,
561
+ Walonmap= True,
562
+ cat = 'IMAGERIE/ORTHO_2022_ETE',
563
+ )
564
+ else:
565
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
566
+ first_mask_data=False, with_legend=False,
567
+ update_palette= False,
568
+ Walonmap= False,
569
+ )
498
570
  return fig, ax
499
571
 
500
572
  def plot_cartoweb(self, figax:tuple[plt.Figure, plt.Axes]=None) -> tuple[plt.Figure, plt.Axes]:
@@ -517,14 +589,20 @@ class CompareArrays:
517
589
  new = WolfArray(srcheader=h)
518
590
  new.array.mask[:,:] = True
519
591
 
520
-
521
- new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
522
- first_mask_data=False, with_legend=False,
523
- update_palette= False,
524
- Cartoweb= True,
525
- cat = 'overlay',
526
- )
527
-
592
+ if self._background.upper() == 'IGN' or self._background.upper() == 'NGI':
593
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
594
+ first_mask_data=False, with_legend=False,
595
+ update_palette= False,
596
+ Cartoweb= True,
597
+ cat = 'overlay',
598
+ )
599
+ else:
600
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
601
+ first_mask_data=False, with_legend=False,
602
+ update_palette= False,
603
+ Cartoweb= False,
604
+ cat = 'overlay',
605
+ )
528
606
  return fig, ax
529
607
 
530
608
  def plot_topo_grey(self, figax:tuple[plt.Figure, plt.Axes]=None) -> tuple[plt.Figure, plt.Axes]:
@@ -547,14 +625,20 @@ class CompareArrays:
547
625
  new = WolfArray(srcheader=h)
548
626
  new.array.mask[:,:] = True
549
627
 
550
-
551
- new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
552
- first_mask_data=False, with_legend=False,
553
- update_palette= False,
554
- Cartoweb= True,
555
- cat = 'topo_grey',
556
- )
557
-
628
+ if self._background.upper() == 'IGN' or self._background.upper() == 'NGI':
629
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
630
+ first_mask_data=False, with_legend=False,
631
+ update_palette= False,
632
+ Cartoweb= True,
633
+ cat = 'topo_grey',
634
+ )
635
+ else:
636
+ new.plot_matplotlib(figax=figax, figsize = self.default_size_arrays,
637
+ first_mask_data=False, with_legend=False,
638
+ update_palette= False,
639
+ Cartoweb= False,
640
+ cat = 'topo_grey',
641
+ )
558
642
  return fig, ax
559
643
 
560
644
  def plot_reference(self, figax:tuple[plt.Figure, plt.Axes]=None) -> tuple[plt.Figure, plt.Axes]:
@@ -568,7 +652,7 @@ class CompareArrays:
568
652
 
569
653
  self.array_reference.plot_matplotlib(figax=figax, figsize = self.default_size_arrays, first_mask_data=False, with_legend=True, update_palette= False)
570
654
 
571
- for diff in self.difference_parts.values():
655
+ for diff in tqdm(self.difference_parts.values(), desc="Plotting external borders"):
572
656
  diff.external_border.plot_matplotlib(ax=ax)
573
657
 
574
658
  return fig, ax
@@ -584,7 +668,7 @@ class CompareArrays:
584
668
 
585
669
  self.array_to_compare.plot_matplotlib(figax=figax, figsize = self.default_size_arrays, first_mask_data=False, with_legend=True, update_palette= False)
586
670
 
587
- for diff in self.difference_parts.values():
671
+ for diff in tqdm(self.difference_parts.values(), desc="Plotting contours"):
588
672
  diff.contour.plot_matplotlib(ax=ax)
589
673
 
590
674
  return fig, ax
@@ -606,11 +690,22 @@ class CompareArrays:
606
690
  diff.plot_matplotlib(figax=figax, figsize = self.default_size_arrays, first_mask_data=False, with_legend=True, update_palette= False)
607
691
  return fig, ax
608
692
 
609
- def localize_differences(self, threshold: float = 0.0) -> np.ndarray:
693
+ def localize_differences(self, threshold: float = 0.0,
694
+ ignored_patche_area:float = 1.) -> np.ndarray:
695
+ """ Localize the differences between the two arrays and label them.
696
+
697
+ :param threshold: The threshold value to consider a difference significant.
698
+ :param ignored_patche_area: The area of patches to ignore (in m²).
699
+ """
700
+
701
+ assert threshold >= 0, "Threshold must be a non-negative value."
610
702
 
611
703
  labeled_array = self.difference.array.data.copy()
612
704
  labeled_array[self.array_reference.array.mask] = 0
613
705
 
706
+ # apply threshold
707
+ labeled_array[np.abs(labeled_array) < threshold] = 0
708
+
614
709
  self.labeled_array, self.num_features = label(labeled_array)
615
710
 
616
711
  self.nb_cells = []
@@ -620,13 +715,29 @@ class CompareArrays:
620
715
 
621
716
  self.nb_cells.sort(key=lambda x: x[0], reverse=True)
622
717
 
718
+ # find features where nb_cells is lower than ignored_patche_area / (dx * dy)
719
+ ignored_patche_cells = int(ignored_patche_area / (self.array_reference.dx * self.array_reference.dy))
720
+ self.last_features = self.num_features
721
+ for idx, (nb_cell, idx_feature) in enumerate(self.nb_cells):
722
+ if nb_cell <= ignored_patche_cells:
723
+ self.last_features = idx
724
+ break
725
+
726
+ all_slices = find_objects(self.labeled_array)
727
+
728
+ logging.info(f"Total number of features found: {self.last_features}")
729
+
623
730
  # find xmin, ymin, xmax, ymax for each feature
624
- for idx_feature in range(1, self.num_features + 1):
625
- mask = self.labeled_array == idx_feature
626
- i, j = np.where(mask)
731
+ for idx_feature, slices in tqdm(zip(range(1, self.num_features+1), all_slices), desc="Processing features", unit="feature"):
732
+ mask = self.labeled_array[slices] == idx_feature
733
+ nb_in_patch = np.count_nonzero(mask)
734
+
735
+ if nb_in_patch <= ignored_patche_cells:
736
+ logging.debug(f"Feature {idx_feature} has too few cells ({np.count_nonzero(mask)}) and will be ignored.")
737
+ continue
627
738
 
628
- imin, imax = i.min(), i.max()
629
- jmin, jmax = j.min(), j.max()
739
+ imin, imax = slices[0].start, slices[0].stop - 1
740
+ jmin, jmax = slices[1].start, slices[1].stop - 1
630
741
 
631
742
  imin = int(max(imin - 1, 0))
632
743
  imax = int(min(imax + 1, self.labeled_array.shape[0] - 1))
@@ -635,17 +746,25 @@ class CompareArrays:
635
746
 
636
747
  ref_crop = self.array_reference.crop(imin, jmin, imax-imin+1, jmax-jmin+1)
637
748
  to_compare_crop = self.array_to_compare.crop(imin, jmin, imax-imin+1, jmax-jmin+1)
749
+ label_crop = self.labeled_array[imin:imax+1, jmin:jmax+1].copy()
638
750
 
639
- ref_crop.array.mask[:,:] = ~mask[imin:imax+1, jmin:jmax+1]
640
- ref_crop.set_nullvalue_in_mask()
641
751
 
642
- to_compare_crop.array.mask[:,:] = ~mask[imin:imax+1, jmin:jmax+1]
752
+ to_compare_crop.array.mask[:,:] = ref_crop.array.mask[:,:] = self.labeled_array[imin:imax+1, jmin:jmax+1] != idx_feature
753
+
754
+ ref_crop.set_nullvalue_in_mask()
643
755
  to_compare_crop.set_nullvalue_in_mask()
756
+ label_crop[label_crop != idx_feature] = 0
644
757
 
645
- ref_crop.count()
646
- to_compare_crop.nbnotnull = ref_crop.nbnotnull
758
+ ref_crop.nbnotnull = nb_in_patch
759
+ to_compare_crop.nbnotnull = nb_in_patch
647
760
 
648
- self.difference_parts[idx_feature] = ArrayDifference(ref_crop, to_compare_crop, idx_feature, self.labeled_array[imin:imax+1, jmin:jmax+1].copy())
761
+ self.difference_parts[idx_feature] = ArrayDifference(ref_crop, to_compare_crop, idx_feature, label_crop)
762
+
763
+ assert self.last_features == len(self.difference_parts), \
764
+ f"Last feature index {self.last_features} does not match the number of differences found"
765
+
766
+ self.num_features = self.last_features
767
+ logging.info(f"Number of features after filtering: {self.num_features}")
649
768
 
650
769
  return self.labeled_array
651
770
 
@@ -721,9 +840,10 @@ class CompareArrays:
721
840
  surf = self.array_reference.dx * self.array_reference.dy
722
841
 
723
842
  # Extract the number of cells for each feature
724
- nb_cells = [item[0] * surf for item in self.nb_cells]
843
+ nb_cells = [item[0] * surf for item in self.nb_cells[:self.last_features]]
725
844
 
726
- ax.hist(nb_cells, density=density, alpha=alpha, **kwargs)
845
+ if len(nb_cells) > 0:
846
+ ax.hist(nb_cells, bins= min(100, int(len(nb_cells)/4)), density=density, alpha=alpha, **kwargs)
727
847
 
728
848
  ax.set_title(_("Histogram of surface in each feature [m²]"))
729
849
 
@@ -748,13 +868,22 @@ class CompareArrays:
748
868
 
749
869
  fig, ax = figax
750
870
 
751
- # Calculate the difference between the two arrays
752
- diff = self.difference
871
+ # # Calculate the difference between the two arrays
872
+ # diff = self.difference
753
873
 
754
- volumes = np.bincount(self.labeled_array.ravel(), weights=diff.array.ravel()) * self.array_reference.dx * self.array_reference.dy
874
+ volumes = []
875
+ for idx in tqdm(self.nb_cells[:self.last_features], desc="Calculating volumes"):
876
+ # Get the feature index
877
+ feature_index = idx[1]
878
+ part = self.difference_parts[feature_index]
879
+ # Create a mask for the feature
880
+ mask = part.label == feature_index
881
+ # Calculate the volume for this feature
882
+ volumes.append(np.ma.sum(part.difference.array[mask]) * self.array_reference.dx * self.array_reference.dy)
755
883
 
756
884
  # Create a histogram of the differences
757
- ax.hist(volumes, density=density, alpha=alpha, **kwargs)
885
+ if len(volumes) > 0:
886
+ ax.hist(volumes, bins= min(100, int(len(volumes)/4)), density=density, alpha=alpha, **kwargs)
758
887
 
759
888
  ax.set_title(_("Histogram of net volumes [m³]"))
760
889
 
@@ -809,7 +938,9 @@ class CompareArrays:
809
938
 
810
939
 
811
940
 
812
- def create_report(self, output_file: str | Path = None, append_all_differences: bool = True) -> None:
941
+ def create_report(self, output_file: str | Path = None,
942
+ append_all_differences: bool = True,
943
+ nb_max_differences:int = -1) -> None:
813
944
  """ Create a page report for the array comparison. """
814
945
 
815
946
  if output_file is None:
@@ -822,6 +953,14 @@ class CompareArrays:
822
953
  layout.create_report()
823
954
  self._complete_report(layout)
824
955
 
956
+ if nb_max_differences < 0:
957
+ nb_max_differences = len(self.difference_parts)
958
+ elif nb_max_differences > len(self.difference_parts):
959
+ logging.warning(f"Requested {nb_max_differences} differences, but only {len(self.difference_parts)} are available. Using all available differences.")
960
+ elif nb_max_differences < len(self.difference_parts):
961
+ logging.info(f"Limiting to {nb_max_differences} differences.")
962
+
963
+ features_to_treat = [feature[1] for feature in self.nb_cells[:nb_max_differences]]
825
964
 
826
965
  with TemporaryDirectory() as temp_dir:
827
966
 
@@ -833,12 +972,83 @@ class CompareArrays:
833
972
 
834
973
  if append_all_differences:
835
974
  # Add each difference report to the main layout
836
- all_pdfs.extend([diff.create_report(Path(temp_dir) / f"array_difference_{idx}.pdf") for idx, diff in self.difference_parts.items()])
975
+ all_pdfs.extend([self.difference_parts[idx].create_report(Path(temp_dir) / f"array_difference_{idx}.pdf") for idx in tqdm(features_to_treat, desc="Creating individual difference reports")])
837
976
 
838
- for pdf_file in all_pdfs:
977
+ for pdf_file in tqdm(all_pdfs, desc="Compiling PDFs"):
839
978
  layout._doc.insert_file(pdf_file)
840
979
 
841
980
  # create a TOC
842
981
  layout._doc.set_toc(layout._doc.get_toc())
843
982
 
844
- layout.save_report(output_file)
983
+ layout.save_report(output_file)
984
+ self._pdf_path = output_file
985
+
986
+ @property
987
+ def pdf_path(self) -> Path:
988
+ """ Return the path to the generated PDF report. """
989
+ if hasattr(self, '_pdf_path'):
990
+ return self._pdf_path
991
+ else:
992
+ raise AttributeError("PDF path not set. Please create the report first.")
993
+
994
+ class CompareArrays_wx(PDFViewer):
995
+
996
+ def __init__(self, reference: WolfArray | str | Path,
997
+ to_compare: WolfArray | str | Path,
998
+ ignored_patche_area:float = 2.0,
999
+ nb_max_patches:int = 10,
1000
+ threshold: float = 0.01,
1001
+ dpi=200, **kwargs):
1002
+ """ Initialize the Simple Simulation GPU Report Viewer for comparison """
1003
+
1004
+ super(CompareArrays_wx, self).__init__(None, **kwargs)
1005
+
1006
+ use('agg')
1007
+
1008
+ if isinstance(reference, WolfArray) and isinstance(to_compare, WolfArray):
1009
+ if np.any(reference.array.mask != to_compare.array.mask):
1010
+ logging.warning("The masks of the two arrays are not identical. This may lead to unexpected results.")
1011
+ dlg = wx.MessageDialog(self,
1012
+ _("The masks of the two arrays are not identical.\nThis may lead to unexpected results.\n\nWe will use the reference mask for the comparison."),
1013
+ _("Warning"),
1014
+ wx.OK | wx.ICON_WARNING)
1015
+ dlg.ShowModal()
1016
+ dlg.Destroy()
1017
+ to_compare = WolfArray(mold=to_compare)
1018
+ to_compare.array.mask[:,:] = reference.array.mask[:,:]
1019
+
1020
+ self._report = CompareArrays(reference, to_compare)
1021
+
1022
+ self._report._dpi = dpi
1023
+ self._report.localize_differences(threshold=threshold,
1024
+ ignored_patche_area=ignored_patche_area)
1025
+ self._report.create_report(nb_max_differences=nb_max_patches)
1026
+
1027
+ # Load the PDF into the viewer
1028
+ if self._report.pdf_path is None:
1029
+ logging.error("No report created. Cannot load PDF.")
1030
+ return
1031
+
1032
+ self.load_pdf(self._report.pdf_path)
1033
+ self.viewer.SetZoom(-1) # Fit to width
1034
+
1035
+ # Set the title of the frame
1036
+ self.SetTitle("Simple Simulation GPU Comparison Report")
1037
+
1038
+ self.Bind(wx.EVT_CLOSE, self.on_close)
1039
+
1040
+ use('wxagg')
1041
+
1042
+ def on_close(self, event):
1043
+ """ Handle the close event to clean up resources """
1044
+ self.viewer.pdfdoc.pdfdoc.close()
1045
+ self.Destroy()
1046
+
1047
+ def get_zones(self) -> Zones:
1048
+ """
1049
+ Get the zones from the report.
1050
+ """
1051
+ ret = self._report.get_zones()
1052
+ ret.prep_listogl()
1053
+
1054
+ return ret