diff --git a/src/Model/Friction/Friction.py b/src/Model/Friction/Friction.py index 2ebd2b4e7b333b93c9bd3a0a60d784f951c346c7..7e29e93141f67a007308e886bcc206f66d95887d 100644 --- a/src/Model/Friction/Friction.py +++ b/src/Model/Friction/Friction.py @@ -85,9 +85,7 @@ class Friction(SQLSubModel): sec.begin_strickler = bs sec.end_strickler = es - new[ind] = sec - - return new + yield ind, sec def _sql_save(self, execute, data = None): ind = data["ind"] diff --git a/src/Model/Friction/FrictionList.py b/src/Model/Friction/FrictionList.py index 215f96ddcd2da2b67e1fd55d0cc02af3d3baa06b..777729c76fbcbe4178c3df0be586c5ad31dc2b82 100644 --- a/src/Model/Friction/FrictionList.py +++ b/src/Model/Friction/FrictionList.py @@ -68,6 +68,26 @@ class FrictionList(PamhyrModelList): return ok + def _get_frictions_list(self): + # Frictions list generator is type (int, Point) with the first + # element the index of the Point in list + return list( + map( + lambda p: p[1], + sorted( + self._lst, + key = lambda p: p[0] + ) + ) + ) + + @property + def lst(self): + if not isinstance(self._lst, list): + self._lst = self._get_frictions_list() + + return self._lst + @property def frictions(self): return self.lst diff --git a/src/Model/Geometry/PointXYZ.py b/src/Model/Geometry/PointXYZ.py index a8f19c8b3d3c0d130b73c04b3b55d45466a128be..6f1b57849d69873698de9afaf738a50661892088 100644 --- a/src/Model/Geometry/PointXYZ.py +++ b/src/Model/Geometry/PointXYZ.py @@ -70,8 +70,6 @@ class PointXYZ(Point, SQLSubModel): @classmethod def _sql_load(cls, execute, data = None): - points = [] - status = data["status"] profile = data["profile"] @@ -81,10 +79,6 @@ class PointXYZ(Point, SQLSubModel): f"WHERE profile = {profile.id}" ) - # Create points list - for _ in table: - points.append(None) - # Fill points list with new point for row in table: ind = row[0] @@ -111,9 +105,7 @@ class PointXYZ(Point, SQLSubModel): ) ) - points[ind] = new - - return points + yield ind, new def _sql_save(self, execute, data = None): profile = data["profile"] diff --git a/src/Model/Geometry/Profile.py b/src/Model/Geometry/Profile.py index 606b2e2959c6e6ba4baadf99602bcaccf19964ea..6290498cb32ce4106bdd623d58387299f2fe3e5c 100644 --- a/src/Model/Geometry/Profile.py +++ b/src/Model/Geometry/Profile.py @@ -57,18 +57,34 @@ class Profile(object): self._profile_type = _type def __len__(self): - return len(self._points) + return len(self.points) @property def number_points(self): - return len(self._points) + return len(self.points) + + def _get_points_list(self): + # Points list generator is type (int, Point) with the first + # element the index of the Point in list + return list( + map( + lambda p: p[1], + sorted( + self._points, + key = lambda p: p[0] + ) + ) + ) @property def points(self): - return self._points.copy() + if not isinstance(self._points, list): + self._points = self._get_points_list() + + return self._points def point(self, index): - return self._points[index] + return self.points[index] @property def reach(self): @@ -115,7 +131,7 @@ class Profile(object): @property def nb_points(self): - return len(self._points) + return len(self.points) @property def kp(self): @@ -170,8 +186,8 @@ class Profile(object): self._status.modified() def point(self, i:int): - if i < len(self._points): - return self._points[i] + if i < len(self.points): + return self.points[i] return None @@ -181,7 +197,7 @@ class Profile(object): Returns: The list of named point """ - return [point for point in self._points + return [point for point in self.points if point.point_is_named()] @@ -195,7 +211,7 @@ class Profile(object): Returns: Nothing. """ - self._points.insert(index, point) + self.points.insert(index, point) self._status.modified() @@ -218,7 +234,7 @@ class Profile(object): ) ) - self._points = list( + self.points = list( filter( lambda p: p not in points, self.points @@ -235,7 +251,7 @@ class Profile(object): Returns: Nothing. """ - self._points = list( + self.points = list( filter( lambda p: p not in points, self.points @@ -246,10 +262,10 @@ class Profile(object): # Move def move_up_point(self, index: int): - if index < len(self._points): + if index < len(self.points): next = index - 1 - p = self._points + p = self.points p[index], p[next] = p[next], p[index] self._status.modified() @@ -257,7 +273,7 @@ class Profile(object): if index >= 0: prev = index + 1 - p = self._points + p = self.points p[index], p[prev] = p[prev], p[index] self._status.modified() @@ -271,8 +287,8 @@ class Profile(object): elif column == 'z': predicate = lambda p: p.z - self._points = sorted( - self._points, + self.points = sorted( + self.points, key=predicate, reverse=is_reversed ) @@ -280,10 +296,10 @@ class Profile(object): @timer def sort_with_indexes(self, indexes: list): - if len(self._points) != len(indexes): + if len(self.points) != len(indexes): logger.critical("Indexes list do not correspond to point list") - self._points = list( + self.points = list( map( lambda x: x[1], sorted( diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py index 0652d1f3221fa6b0798fe66318363eef4d6e6889..7eb12ac5d0c14d986c094db230f5b3605c19f124 100644 --- a/src/Model/Geometry/ProfileXYZ.py +++ b/src/Model/Geometry/ProfileXYZ.py @@ -16,6 +16,7 @@ # -*- coding: utf-8 -*- +import logging import numpy as np from typing import List @@ -27,6 +28,8 @@ from Model.Geometry.Profile import Profile from Model.Geometry.PointXYZ import PointXYZ from Model.Geometry.Vector_1d import Vector1d +logger = logging.getLogger() + class ProfileXYZ(Profile, SQLSubModel): _sub_classes = [ PointXYZ, @@ -108,7 +111,7 @@ class ProfileXYZ(Profile, SQLSubModel): table = execute( "SELECT id, ind, name, kp, num, code1, code2, sl " + "FROM geometry_profileXYZ " + - f"WHERE reach = {reach}" + f"WHERE reach = {reach.id}" ) for _ in table: @@ -145,9 +148,11 @@ class ProfileXYZ(Profile, SQLSubModel): data["profile"] = new new._points = PointXYZ._sql_load(execute, data) - profiles[ind] = new + yield ind, new + + # profiles[ind] = new - return profiles + # return profiles def _sql_save(self, execute, data = None): ok = True @@ -170,7 +175,7 @@ class ProfileXYZ(Profile, SQLSubModel): execute(f"DELETE FROM geometry_pointXYZ WHERE profile = {self.id}") ind = 0 - for point in self._points: + for point in self.points: data["ind"] = ind ok &= point._sql_save(execute, data) ind += 1 @@ -222,16 +227,16 @@ class ProfileXYZ(Profile, SQLSubModel): def x(self): - return [point.x for point in self._points] + return [point.x for point in self.points] def y(self): - return [point.y for point in self._points] + return [point.y for point in self.points] def z(self): - return [point.z for point in self._points] + return [point.z for point in self.points] def names(self): - return [point.name for point in self._points] + return [point.name for point in self.points] def x_max(self): return max(self.filter_isnan(self.x())) @@ -262,7 +267,7 @@ class ProfileXYZ(Profile, SQLSubModel): """ for point in list_points: pt = PointXYZ(*point, profile=self, status=self._status) - self._points.append(pt) + self.points.append(pt) self._status.modified() def get_point_i(self, index: int) -> PointXYZ: @@ -275,7 +280,7 @@ class ProfileXYZ(Profile, SQLSubModel): The point. """ try: - return self._points[index] + return self.points[index] except IndexError: raise IndexError(f"Invalid point index: {index}") @@ -286,7 +291,7 @@ class ProfileXYZ(Profile, SQLSubModel): Nothing. """ point_xyz = PointXYZ(0., 0., 0., profile=self, status=self._status) - self._points.append(point_xyz) + self.points.append(point_xyz) self._status.modified() def insert(self, index: int): @@ -299,7 +304,7 @@ class ProfileXYZ(Profile, SQLSubModel): The new point. """ point = PointXYZ(0., 0., 0., profile=self, status=self._status) - self._points.insert(index, point) + self.points.insert(index, point) self._status.modified() return point @@ -315,9 +320,9 @@ class ProfileXYZ(Profile, SQLSubModel): return [x for x in lst if not np.isnan(x)] def _first_point_not_nan(self): - first_point = self._points[0] + first_point = self.points[0] - for point in self._points: + for point in self.points: if not point.is_nan(): first_point = point break @@ -325,9 +330,9 @@ class ProfileXYZ(Profile, SQLSubModel): return first_point def _last_point_not_nan(self): - last_point = self._points[-1] + last_point = self.points[-1] - for point in self._points[::-1]: + for point in self.points[::-1]: if not point.is_nan(): last_point = point break @@ -354,13 +359,13 @@ class ProfileXYZ(Profile, SQLSubModel): first_point_not_nan = self._first_point_not_nan() last_point_not_nan = self._last_point_not_nan() - for index, point in enumerate(self._points): + for index, point in enumerate(self.points): if point.point_is_named(): index_first_named_point = index first_named_point = point break - for point in reversed(self._points): + for point in reversed(self.points): if point.point_is_named(): last_named_point = point break @@ -378,7 +383,7 @@ class ProfileXYZ(Profile, SQLSubModel): vector = Vector1d(first_point_not_nan, last_point_not_nan) normalized_direction_vec = vector.normalized_direction_vector() - for point in self._points: + for point in self.points: xi = point.x - first_named_point.x yi = point.y - first_named_point.y station_i = (normalized_direction_vec[0] * xi + @@ -390,7 +395,7 @@ class ProfileXYZ(Profile, SQLSubModel): vector = Vector1d(first_point_not_nan, last_point_not_nan) normalized_direction_vec = vector.normalized_direction_vector() - for point in self._points: + for point in self.points: xi = point.x - first_point_not_nan.x yi = point.y - first_point_not_nan.y station_i = (normalized_direction_vec[0] * xi + diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py index 36fca25f6302e63a11f75c083f9d9b29ed0c5482..4fdc8c743196b2c2b82fbe7876dc0f5bb069a109 100644 --- a/src/Model/Geometry/Reach.py +++ b/src/Model/Geometry/Reach.py @@ -94,8 +94,8 @@ class Reach(SQLSubModel): Returns: The profile at index i """ - if i < len(self._profiles): - return self._profiles[i] + if i < len(self.profiles): + return self.profiles[i] return None @@ -106,12 +106,32 @@ class Reach(SQLSubModel): return self._parent.name + def _get_profiles_list(self): + # Profiles list generator is type (int, Point) with the first + # element the index of the Point in list + logger.info(f"Load profiles from reach {self.name}") + return list( + map( + lambda p: p[1], + sorted( + self._profiles, + key = lambda p: p[0] + ) + ) + ) + def __len__(self): + if not isinstance(self._profiles, list): + self._profiles = self._get_profiles_list() + return len(self._profiles) @property def profiles(self): - return self._profiles.copy() + if not isinstance(self._profiles, list): + self._profiles = self._get_profiles_list() + + return self._profiles def get_profiles_from_kp(self, kp): return list( @@ -126,14 +146,14 @@ class Reach(SQLSubModel): Returns: Number of profiles """ - return len(self._profiles) + return len(self.profiles) def get_geometry(self) -> List[Profile]: """ Returns: The profiles list. """ - return self._profiles + return self.profiles def _update_profile_numbers(self): """Update profiles index @@ -155,7 +175,7 @@ class Reach(SQLSubModel): """ profile = ProfileXYZ(reach=self, status=self._status) - self._profiles.insert(index, profile) + self.profiles.insert(index, profile) self._update_profile_numbers() self._status.modified() @@ -171,7 +191,7 @@ class Reach(SQLSubModel): Returns: Nothing. """ - self._profiles.insert(index, profile) + self.profiles.insert(index, profile) self._update_profile_numbers() self._status.modified() @@ -195,7 +215,7 @@ class Reach(SQLSubModel): ) ) - self._profiles = list( + self.profiles = list( filter( lambda p: p not in profiles, self.profiles @@ -213,7 +233,7 @@ class Reach(SQLSubModel): Returns: Nothing. """ - self._profiles = list( + self.profiles = list( filter( lambda p: p not in profiles, self.profiles @@ -227,7 +247,7 @@ class Reach(SQLSubModel): if index < len(self.profiles): next = index - 1 - p = self._profiles + p = self.profiles p[index], p[next] = p[next], p[index] self._status.modified() @@ -235,7 +255,7 @@ class Reach(SQLSubModel): if index >= 0: prev = index + 1 - p = self._profiles + p = self.profiles p[index], p[prev] = p[prev], p[index] self._status.modified() @@ -347,7 +367,7 @@ class Reach(SQLSubModel): Tuple of complete and incomplete guidelines name. """ # Get all point contains into a guideline - named_points = [profile.named_points() for profile in self._profiles] + named_points = [profile.named_points() for profile in self.profiles] points_name = list( map( lambda lst: list(map(lambda p: p.name, lst)), @@ -422,8 +442,8 @@ class Reach(SQLSubModel): @timer def sort(self, is_reversed: bool = False): - self._profiles = sorted( - self._profiles, + self.profiles = sorted( + self.profiles, key=lambda profile: profile.kp, reverse=is_reversed ) @@ -431,10 +451,10 @@ class Reach(SQLSubModel): @timer def sort_with_indexes(self, indexes: list): - if len(self._profiles) != len(indexes): + if len(self.profiles) != len(indexes): logger.critical("Indexes list do not correspond to profile list") - self._profiles = list( + self.profiles = list( map( lambda x: x[1], sorted( @@ -474,7 +494,7 @@ class Reach(SQLSubModel): **d, reach=self, status=self._status ) prof.import_points(profile) - self._profiles.append(prof) + self.profiles.append(prof) self._update_profile_numbers() self._status.modified() @@ -538,8 +558,8 @@ class Reach(SQLSubModel): # TODO: Move this function to model reach def export_reach(self, filename): with open(f"{filename}", "w") as file_st: - for index in range(len(self._profiles)): - profile = self._profiles[index] + for index in range(len(self.profiles)): + profile = self.profiles[index] for v in profile.header: file_st.write(f"{v:>6}") diff --git a/src/Model/InitialConditions/InitialConditions.py b/src/Model/InitialConditions/InitialConditions.py index 2c50d10c5adeb271325931d2504a5377aee49af0..a40e026176f052d9f0d5e1a1c365f455cddd86b7 100644 --- a/src/Model/InitialConditions/InitialConditions.py +++ b/src/Model/InitialConditions/InitialConditions.py @@ -244,10 +244,8 @@ class InitialConditions(SQLSubModel): data = data ) - if new._data is None: - return None - - return new + if new._data is not None: + yield new def _sql_save(self, execute, data = None): ok = True diff --git a/src/Model/InitialConditions/InitialConditionsDict.py b/src/Model/InitialConditions/InitialConditionsDict.py index 40fdca495412e1713fabb83760e02b192c502ff0..f2bd038f213ca1fdb3fb963719dabf40206f6276 100644 --- a/src/Model/InitialConditions/InitialConditionsDict.py +++ b/src/Model/InitialConditions/InitialConditionsDict.py @@ -16,6 +16,7 @@ # -*- coding: utf-8 -*- +import types from copy import copy from tools import trace, timer @@ -57,6 +58,19 @@ class InitialConditionsDict(PamhyrModelDict): return ok + + def get(self, key): + if key in self._dict: + v = self._dict[key] + if isinstance(v, types.GeneratorType): + self._dict[key] = list(v)[0] + + return self._dict[key] + + new = self.new(key) + self.set(key, new) + return new + def new(self, reach): new = InitialConditions(reach = reach, status = self._status) self.set(reach, new) diff --git a/src/Model/Tools/PamhyrList.py b/src/Model/Tools/PamhyrList.py index 6938343ff08c44e77a442f3bbf07eb20b773d961..f1896c901a0a1e807c1b3af9e04ed170608acb8b 100644 --- a/src/Model/Tools/PamhyrList.py +++ b/src/Model/Tools/PamhyrList.py @@ -59,12 +59,12 @@ class PamhyrModelList(SQLSubModel): # MODEL METHOD # ################ - def __len__(self): - return len(self._lst) - @property def lst(self): - return self._lst.copy() + return self._lst + + def __len__(self): + return len(self.lst) def get(self, row): return self._lst[row]