diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py index 0ed81688..6a863fcb 100644 --- a/src/Model/Geometry/ProfileXYZ.py +++ b/src/Model/Geometry/ProfileXYZ.py @@ -92,6 +92,7 @@ class ProfileXYZ(Profile, SQLSubModel): self.station_up_to_date = False self._get_water_limits_cache = {} + self._get_water_limits_ac_cache = {} @classmethod def _db_create(cls, execute, ext=""): @@ -621,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) @@ -672,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: @@ -712,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): @@ -734,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: @@ -810,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: @@ -822,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: @@ -858,10 +865,19 @@ 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] + + return self.get_water_limits_compute(z) + + def get_water_limits_compute(self, z): """ Determine left and right limits of water elevation. """ @@ -870,9 +886,6 @@ class ProfileXYZ(Profile, SQLSubModel): i_left = -1 i_right = -1 - if z in self._get_water_limits_cache: - return self._get_water_limits_cache[z] - for i in range(self.number_points): if self.point(i).z <= z: i_left = i @@ -919,15 +932,20 @@ class ProfileXYZ(Profile, SQLSubModel): # Create a generator to improve results data reading speed yield pt_left, pt_right + @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