mirror of https://gitlab.com/pamhyr/pamhyr2
Compare commits
5 Commits
1975ed7eaa
...
32e7413aad
| Author | SHA1 | Date |
|---|---|---|
|
|
32e7413aad | |
|
|
d87db5fd48 | |
|
|
388368adad | |
|
|
4d014d5a1d | |
|
|
181a6c226f |
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@ class Profile(SQLSubModel):
|
|||
|
||||
# If is a generator, compute value(s)
|
||||
if isinstance(v, types.GeneratorType):
|
||||
v = self._data[timestamp][key] = next(v)
|
||||
v = next(v)
|
||||
self._data[timestamp][key] = v
|
||||
|
||||
return v
|
||||
|
||||
|
|
|
|||
|
|
@ -1083,7 +1083,7 @@ class Mage8(Mage):
|
|||
newline()
|
||||
|
||||
reachs = []
|
||||
iprofiles = {}
|
||||
iprofiles = []
|
||||
profile_len = []
|
||||
reach_offset = {}
|
||||
|
||||
|
|
@ -1099,14 +1099,14 @@ class Mage8(Mage):
|
|||
i2 = data[2*i+1] - 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)
|
||||
|
||||
logger.debug(f"read_bin: iprofiles = {iprofiles}")
|
||||
logger.debug(f"read_bin: iprofiles = {len(iprofiles)}")
|
||||
|
||||
endline()
|
||||
|
||||
|
|
@ -1124,16 +1124,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 +1134,8 @@ class Mage8(Mage):
|
|||
return
|
||||
|
||||
ts = set()
|
||||
tmp_table = {}
|
||||
|
||||
end = False
|
||||
while not end:
|
||||
n = read_int(1)[0]
|
||||
|
|
@ -1152,15 +1144,18 @@ 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)
|
||||
|
|
@ -1176,6 +1171,10 @@ class Mage8(Mage):
|
|||
endline()
|
||||
end = newline().size <= 0
|
||||
|
||||
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,14 +1184,22 @@ class Mage8(Mage):
|
|||
|
||||
logger.info(f"compute velocity...")
|
||||
|
||||
velocity_arr = np.zeros((len(ts), len(iprofiles)))
|
||||
for ti, t in enumerate(ts_list):
|
||||
j = 0
|
||||
for r in reachs:
|
||||
for t in ts_list:
|
||||
for i, p in enumerate(r.profiles):
|
||||
for pi, p in enumerate(r.profiles):
|
||||
v = p.geometry.speed(
|
||||
p.get_ts_key(t, "Q"),
|
||||
p.get_ts_key(t, "Z")
|
||||
)
|
||||
r.set(i, t, "V", v)
|
||||
r.set(pi, t, "V", v)
|
||||
velocity_arr[ti, j] = v
|
||||
j += 1
|
||||
|
||||
table["V"] = velocity_arr
|
||||
results.set("table", table)
|
||||
|
||||
logger.info(f"read_bin: ... end with {len(ts)} timestamp read")
|
||||
|
||||
results.bufferize("Z")
|
||||
|
|
@ -1322,6 +1329,7 @@ class Mage8(Mage):
|
|||
newline()
|
||||
npts = read_int(n)
|
||||
endline()
|
||||
|
||||
sum_npts = sum(npts)
|
||||
logger.debug(f"read_gra: Number of points: {sum_npts}")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue