Compare commits

..

16 Commits

Author SHA1 Message Date
Pierre-Antoine 8c7c4cafbc Inversion: Excel export: Fix depth column shape and filename extention. 2025-03-11 16:15:06 +01:00
Pierre-Antoine 8dd50f9373 Inversion: Fix #13. 2025-03-11 15:12:31 +01:00
Pierre-Antoine bcdae43d10 SQL: Remove unused logs. 2025-03-11 14:39:22 +01:00
Pierre-Antoine 0c141b8d24 SQL: Minor fix. 2025-03-11 14:28:49 +01:00
Pierre-Antoine ba0557294e Inversion: Refactoring 'save_result_in_excel_file' method. 2025-03-11 14:19:18 +01:00
Pierre-Antoine 12fea4e182 Merge branch 'dev-parouby' into dev 2025-03-11 11:37:22 +01:00
Pierre-Antoine a5268c6214 Sample data: Fix #29. 2025-03-11 11:35:52 +01:00
Pierre-Antoine 2697acddfe Sample data: Refactoring some functions. 2025-03-11 10:20:18 +01:00
brahim 6de578a07e time noise and depth noise variable are used instead of time and depth to avoid size incompatibility #9 2025-03-10 15:12:49 +01:00
brahim 320971160d Plot of SNR field is corrected when the user set a profile tail level #4 2025-03-10 14:30:45 +01:00
brahim 190c0f0b80 The readme file is modified and will be completed by Brahim. 2025-03-10 11:38:47 +01:00
brahim 2ffb9a21e6 read table for open cleaned 2025-03-10 10:16:03 +01:00
MOUDJED Brahim 2ec5584860 Update README.md 2025-03-07 17:19:16 +01:00
MOUDJED Brahim 6d4fb5fae6 Update README.md 2025-03-07 12:14:46 +01:00
brahim 65a9422f71 acoustic inversion method high concentration file is cleaned from useless commented lines and useless print 2025-03-06 10:23:27 +01:00
brahim cea9e35498 acoustic data loader file is cleaned from useless commented lines and useless print 2025-03-06 10:18:46 +01:00
8 changed files with 313 additions and 562 deletions

View File

@ -5,35 +5,25 @@ import pandas as pd
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm from matplotlib.colors import LogNorm
# path_BS_raw_data = "/home/bmoudjed/Documents/2 Data/Confluence_Rhône_Isere_2018/Acoustic_data/20180107123500.aqa"
# path_BS_raw_data = "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/" \
# "Data/AcousticNoise_data/20180107121600.aqa"
class AcousticDataLoader: class AcousticDataLoader:
def __init__(self, path_BS_raw_data: str): def __init__(self, path_BS_raw_data: str):
self.path_BS_raw_data = path_BS_raw_data self.path_BS_raw_data = path_BS_raw_data
print(self.path_BS_raw_data)
# --- Load Backscatter acoustic raw data with RawAquascatData class --- # --- Load Backscatter acoustic raw data with RawAquascatData class ---
self._data_BS = RawAquascatData(self.path_BS_raw_data) self._data_BS = RawAquascatData(self.path_BS_raw_data)
print(self._data_BS.V.shape)
self._BS_raw_data = np.swapaxes(self._data_BS.V, 0, 1) self._BS_raw_data = np.swapaxes(self._data_BS.V, 0, 1)
print(f"BS raw data shape = {self._BS_raw_data.shape}")
self._freq = self._data_BS.Freq self._freq = self._data_BS.Freq
print(f"freq shape = {self._freq.shape}")
self._freq_text = self._data_BS.freqText self._freq_text = self._data_BS.freqText
self._r = np.repeat(np.transpose(self._data_BS.r), self._freq.shape[0], axis=0) self._r = np.repeat(np.transpose(self._data_BS.r), self._freq.shape[0], axis=0)
print(f"r shape = {self._r.shape}")
self._time = np.repeat( self._time = np.repeat(
np.transpose(np.array([t / self._data_BS.PingRate for t in range(self._data_BS.NumProfiles)])[:, np.newaxis]), np.transpose(np.array([t / self._data_BS.PingRate for t in range(self._data_BS.NumProfiles)])[:, np.newaxis]),
self._freq.shape[0], axis=0) self._freq.shape[0], axis=0)
print(f"time shape = {self._time.shape}")
self._date = self._data_BS.date.date() self._date = self._data_BS.date.date()
self._hour = self._data_BS.date.time() self._hour = self._data_BS.date.time()
@ -48,97 +38,30 @@ class AcousticDataLoader:
self._gain_rx = self._data_BS.RxGain.tolist() self._gain_rx = self._data_BS.RxGain.tolist()
self._gain_tx = self._data_BS.TxGain.tolist() self._gain_tx = self._data_BS.TxGain.tolist()
# print((self._cell_size))
# print((self._nb_pings_averaged_per_profile))
# print(self._r[0, :][1] - self._r[1, :][0])
# print(type(self._nb_cells), self._nb_cells)
# self._snr = np.array([])
# self._snr_reshape = np.array([])
# self._time_snr = np.array([])
# print(type(self._gain_tx))
# print(["BS - " + f for f in self._freq_text])
# print(self._time.shape[0]*self._r.shape[0]*4)
# print(self._time[np.where(np.floor(self._time) == 175)])
# print(np.where((self._time) == 155)[0][0])
# fig, ax = plt.subplots(nrows=1, ncols=1)
# # ax.pcolormesh(self._time[0, :2200], -self._r[0, :], (self._BS_raw_data[0, :, :2200]),
# # cmap='viridis',
# # norm=LogNorm(vmin=1e-5, vmax=np.max(self._BS_raw_data[0, :, :2200]))) # , shading='gouraud')
# ax.pcolormesh(range(self._BS_raw_data.shape[2]), range(self._BS_raw_data.shape[1]), self._BS_raw_data[2, :, :], cmap='viridis',
# norm=LogNorm(vmin=1e-5, vmax=np.max(self._BS_raw_data[:, 0, :]))) # , shading='gouraud')
# ax.set_xticks([])
# ax.set_yticks([])
# plt.show()
# --- Plot vertical profile for bottom detection ---
# fig2, ax2 = plt.subplots(nrows=1, ncols=1, layout="constrained")
# ax2.plot(self._BS_raw_data[0, :, 1], -self._r[0], "k.-")
# plt.show()
# fig, ax = plt.subplots(nrows=1, ncols=1)
# ax.plot(self._BS_raw_data[:, 0, 100] , self._r)
# ax.set_ylim(2, 20)
# plt.show()
# print(self.reshape_BS_raw_cross_section()[0, 0])
# self.reshape_BS_raw_cross_section()
# self.reshape_r()
# self.reshape_t()
# self.compute_r_2D()
def reshape_BS_raw_data(self): def reshape_BS_raw_data(self):
BS_raw_cross_section = np.reshape(self._BS_raw_data, BS_raw_cross_section = np.reshape(self._BS_raw_data,
(self._r.shape[1] * self._time.shape[1], self._freq.shape[0]), (self._r.shape[1] * self._time.shape[1], self._freq.shape[0]),
order="F") order="F")
print(BS_raw_cross_section.shape)
return BS_raw_cross_section return BS_raw_cross_section
def reshape_r(self): def reshape_r(self):
# r = np.reshape(np.repeat(self._r[0, :], self._time.shape[0], axis=1),
# self._r.shape[0]*self._time.shape[0],
# order="F")
r = np.zeros((self._r.shape[1] * self._time.shape[1], self._freq.shape[0])) r = np.zeros((self._r.shape[1] * self._time.shape[1], self._freq.shape[0]))
for i, _ in enumerate(self._freq): for i, _ in enumerate(self._freq):
for j in range(self._time.shape[1]): for j in range(self._time.shape[1]):
r[j*self._r.shape[1]:(j+1)*self._r.shape[1], i] = self._r[i, :] r[j*self._r.shape[1]:(j+1)*self._r.shape[1], i] = self._r[i, :]
# r[:, i] = np.repeat(self._r[i, :], self._time.shape[1])
print(r.shape)
return r return r
def compute_r_2D(self): def compute_r_2D(self):
r2D = np.zeros((self._freq.shape[0], self._r.shape[1], self._time.shape[1])) r2D = np.zeros((self._freq.shape[0], self._r.shape[1], self._time.shape[1]))
for f, _ in enumerate(self._freq): for f, _ in enumerate(self._freq):
r2D[f, :, :] = np.repeat(np.transpose(self._r[f, :])[:, np.newaxis], self._time.shape[1], axis=1) r2D[f, :, :] = np.repeat(np.transpose(self._r[f, :])[:, np.newaxis], self._time.shape[1], axis=1)
print(r2D.shape)
return r2D return r2D
def reshape_t(self): def reshape_t(self):
# t = np.reshape(np.repeat(self._time, self._r.shape[0]), (self._time.shape[0]*self._r.shape[0], 1))
t = np.zeros((self._r.shape[1] * self._time.shape[1], self._freq.shape[0])) t = np.zeros((self._r.shape[1] * self._time.shape[1], self._freq.shape[0]))
for i, _ in enumerate(self._freq): for i, _ in enumerate(self._freq):
t[:, i] = np.repeat(self._time[i, :], self._r.shape[1]) t[:, i] = np.repeat(self._time[i, :], self._r.shape[1])
print(t.shape)
return t return t
# def concatenate_data(self):
# self.reshape_t()
# self.reshape_BS_raw_cross_section()
# # print(self.reshape_t().shape)
# # print(se.lf.reshape_BS_raw_cross_section().shape)
# df = pd.DataFrame(np.concatenate((self.reshape_t(), self.reshape_BS_raw_cross_section()), axis=1),
# columns=["time"] + self._freq_text)
# return df
# if __name__ == "__main__":
# AcousticDataLoader(path_BS_raw_data)

View File

@ -21,7 +21,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np import numpy as np
import settings as stg import settings as stg
from Model.GrainSizeTools import demodul_granulo, mix_gaussian_model from Model.GrainSizeTools import demodul_granulo, mix_gaussian_model
@ -58,17 +57,6 @@ class AcousticInversionMethodHighConcentration():
(np.log(10) / 20) * (freq * 1e-3) ** 2 (np.log(10) / 20) * (freq * 1e-3) ** 2
return alpha return alpha
# ---------- Conmpute FBC ----------
# def compute_FCB(self):
# # print(self.BS_averaged_cross_section_corr.V.shape)
# # print(self.r_2D.shape)
# FCB = np.zeros((256, 4, 1912))
# for f in range(4):
# # print(self.alpha_w_function(self.Freq[f], self.temperature))
# FCB[:, f, :] = np.log(self.BS_averaged_cross_section_corr.V[:, f, :]) + np.log(self.r_3D[:, f, :]) + \
# np.log(2 * self.alpha_w_function(self.Freq[f], self.temperature) * self.r_3D[:, f, :])
# return FCB
# --- Gaussian mixture --- # --- Gaussian mixture ---
def compute_particle_size_distribution_in_number_of_particles(self, num_sample, r_grain, frac_vol_cumul): def compute_particle_size_distribution_in_number_of_particles(self, num_sample, r_grain, frac_vol_cumul):
min_demodul = 1e-6 min_demodul = 1e-6
@ -82,15 +70,6 @@ class AcousticInversionMethodHighConcentration():
sample_demodul.demodul_data_list[2].sigma_list, sample_demodul.demodul_data_list[2].sigma_list,
sample_demodul.demodul_data_list[2].w_list) sample_demodul.demodul_data_list[2].w_list)
# N_modes = 3
# sample_demodul.print_mode_data(N_modes)
# sample_demodul.plot_interpolation()
# sample_demodul.plot_modes(N_modes)
# print(f"mu_list : {sample_demodul.demodul_data_list[3 - 1].mu_list}")
# print(f"sigma_list : {sample_demodul.demodul_data_list[3 - 1].sigma_list}")
# print(f"w_list : {sample_demodul.demodul_data_list[3 - 1].w_list}")
proba_vol_demodul = proba_vol_demodul / np.sum(proba_vol_demodul) proba_vol_demodul = proba_vol_demodul / np.sum(proba_vol_demodul)
ss = np.sum(proba_vol_demodul / np.exp(resampled_log_array) ** 3) ss = np.sum(proba_vol_demodul / np.exp(resampled_log_array) ** 3)
proba_num = proba_vol_demodul / np.exp(resampled_log_array) ** 3 / ss proba_num = proba_vol_demodul / np.exp(resampled_log_array) ** 3 / ss
@ -106,23 +85,9 @@ class AcousticInversionMethodHighConcentration():
x = k * a x = k * a
f = (x ** 2 * (1 - 0.25 * np.exp(-((x - 1.5) / 0.35) ** 2)) * (1 + 0.6 * np.exp(-((x - 2.9) / 1.15) ** 2))) / ( f = (x ** 2 * (1 - 0.25 * np.exp(-((x - 1.5) / 0.35) ** 2)) * (1 + 0.6 * np.exp(-((x - 2.9) / 1.15) ** 2))) / (
42 + 28 * x ** 2) 42 + 28 * x ** 2)
# print(f"form factor = {f}")
return f return f
# def ks(self, num_sample_sand, radius_grain_sand, frac_vol_sand_cumul, freq, C):
def ks(self, proba_num, freq, C): def ks(self, proba_num, freq, C):
# --- Calcul de la fonction de form ---
# form_factor = self.form_factor_function_MoateThorne2012(a, freq)
# print(f"form_factor shape = {form_factor}")
# print(f"form_factor = {form_factor}")
#--- Particle size distribution ---
# proba_num = (
# self.compute_particle_size_distribution_in_number_of_particles(
# num_sample=num_sample_sand, r_grain=radius_grain_sand, frac_vol_cumul=frac_vol_sand_cumul[num_sample_sand]))
# print(f"proba_num : {proba_num}")
# --- Compute k_s by dividing two integrals --- # --- Compute k_s by dividing two integrals ---
resampled_log_array = np.log(np.logspace(-10, -2, 3000)) resampled_log_array = np.log(np.logspace(-10, -2, 3000))
a2f2pdf = 0 a2f2pdf = 0
@ -132,28 +97,17 @@ class AcousticInversionMethodHighConcentration():
a2f2pdf += a**2 * self.form_factor_function_MoateThorne2012(a, freq, C)**2 * proba_num[i] a2f2pdf += a**2 * self.form_factor_function_MoateThorne2012(a, freq, C)**2 * proba_num[i]
a3pdf += a**3 * proba_num[i] a3pdf += a**3 * proba_num[i]
# print("form factor ", self.form_factor_function_MoateThorne2012(a, freq, C))
# print(f"a2f2pdf = {a2f2pdf}")
# print(f"a3pdf = {a3pdf}")
ks = np.sqrt(a2f2pdf / a3pdf) ks = np.sqrt(a2f2pdf / a3pdf)
# ks = np.array([0.04452077, 0.11415143, 0.35533713, 2.47960051])
# ks = ks0[ind]
return ks return ks
# ------------- Computing sv ------------- # # ------------- Computing sv ------------- #
def sv(self, ks, M_sand): def sv(self, ks, M_sand):
# print(f"ks = {ks}")
# print(f"M_sand = {M_sand}")
sv = (3 / (16 * np.pi)) * (ks ** 2) * M_sand sv = (3 / (16 * np.pi)) * (ks ** 2) * M_sand
# sv = np.full((stg.r.shape[1], stg.t.shape[1]), sv0)
return sv return sv
# ------------- Computing X ------------- # # ------------- Computing X ------------- #
def X_exponent(self, freq1, freq2, sv_freq1, sv_freq2): def X_exponent(self, freq1, freq2, sv_freq1, sv_freq2):
# X0 = [3.450428714146802, 3.276478927777019, 3.6864638665972893, 0]
# X = X0[ind]
X = np.log(sv_freq1 / sv_freq2) / np.log(freq1 / freq2) X = np.log(sv_freq1 / sv_freq2) / np.log(freq1 / freq2)
return X return X
@ -174,165 +128,43 @@ class AcousticInversionMethodHighConcentration():
gain = 10 ** ((RxGain + TxGain) / 20) gain = 10 ** ((RxGain + TxGain) / 20)
# Computing Kt # Computing Kt
kt = kt_ref * gain * np.sqrt(tau * cel / (tau_ref * c_ref)) # 1D numpy array kt = kt_ref * gain * np.sqrt(tau * cel / (tau_ref * c_ref)) # 1D numpy array
# kt = np.reshape(kt0, (1, 2)) # convert to 2d numpy array to compute J_cross_section
# print(f"kt = {kt}")
# kt_2D = np.repeat(np.array([kt]), stg.r.shape[1], axis=0)
# print("kt 2D ", kt_2D)
# print("kt 2D shape ", kt_2D.shape)
# # kt_3D = np.zeros((kt_2D.shape[1], kt_2D.shape[0], stg.t.shape[1]))
# # for k in range(kt_2D.shape[1]):
# # kt_3D[k, :, :] = np.repeat(kt_2D, stg.t.shape[1], axis=1)[:, k * stg.t.shape[1]:(k + 1) * stg.t.shape[1]]
# kt_3D = np.repeat(kt_2D.transpose()[:, :, np.newaxis], stg.t.shape[1], axis=2)
# # print("kt 3D ", kt_3D)
# print("kt 3D shape ", kt_3D.shape)
return kt return kt
# ------------- Computing J_cross_section ------------- # # ------------- Computing J_cross_section ------------- #
def j_cross_section(self, BS, r2D, kt): def j_cross_section(self, BS, r2D, kt):
# J_cross_section = np.zeros((1, BS.shape[1], BS.shape[2])) # 2 because it's a pair of frequencies
# print("BS.shape", BS.shape)
# print("r2D.shape", r2D.shape)
# print("kt.shape", kt.shape)
# if stg.ABS_name == "Aquascat 1000R":
# print("--------------------------------")
# print("BS : ", BS)
# print("BS min : ", np.nanmin(BS))
# print("BS max : ", np.nanmax(BS))
# print("r2D : ", r2D)
# print("kt shape : ", kt.shape)
# print("kt : ", kt)
# print("--------------------------------")
# for k in range(1):
# J_cross_section[k, :, :] = (3 / (16 * np.pi)) * ((BS[k, :, :]**2 * r2D[k, :, :]**2) / kt[k, :, :]**2)
J_cross_section = (3 / (16 * np.pi)) * ((BS**2 * r2D**2) / kt**2) J_cross_section = (3 / (16 * np.pi)) * ((BS**2 * r2D**2) / kt**2)
# J_cross_section[J_cross_section == 0] = np.nan
# print("J_cross_section.shape", J_cross_section.shape)
# elif stg.ABS_name == "UB-SediFlow":
# for k in range(1):
# J_cross_section[k, :, :] = (3 / (16 * np.pi)) * ((BS[k, :, :]**2 * r2D[0, :, :]**2) / kt[k, :, :]**2)
# print("compute j_cross_section finished")
return J_cross_section return J_cross_section
# ------------- Computing alpha_s ------------- # # ------------- Computing alpha_s ------------- #
def alpha_s(self, sv, j_cross_section, depth, alpha_w): def alpha_s(self, sv, j_cross_section, depth, alpha_w):
alpha_s = (np.log(sv / j_cross_section) / (4 * depth)) - alpha_w alpha_s = (np.log(sv / j_cross_section) / (4 * depth)) - alpha_w
print("----------------------------")
print(f"sv = {sv}")
print(f"j_cross_section = {j_cross_section}")
print(f"depth = {depth}")
print(f"alpha_w = {alpha_w}")
print(f"(np.log(sv / j_cross_section) / (4 * depth)) = {(np.log(sv / j_cross_section) / (4 * depth))}")
print(f"alpha_s {alpha_s}")
return alpha_s return alpha_s
# ------------- Computing interpolation of fine SSC data obtained from water sampling ------------- # ------------- Computing interpolation of fine SSC -------------
# ------------- collected at various depth in the vertical sample -------------
# def M_profile_SCC_fine_interpolated(self, sample_depth, M_profile, range_cells, r_bottom):
# res = np.zeros((len(range_cells),)) * np.nan
# for i in range(len(M_profile) - 1):
# # print(f"i = {i}")
# r_ini = sample_depth[i]
# # print(f"r_ini = {r_ini}")
# c_ini = M_profile[i]
# # print(f"c_ini = {c_ini}")
# r_end = sample_depth[i + 1]
# # print(f"r_end = {r_end}")
# c_end = M_profile[i + 1]
# # print(f"c_end = {c_end}")
#
# # Computing the linear equation
# a = (c_end - c_ini) / (r_end - r_ini)
# # print(f"a = {a}")
# b = c_ini - a * r_ini
# # print(f"b = {b}")
#
# # Finding the indices of r_ini and r_end in the interpolated array
# # print(f"range_cells = {range_cells}")
# loc = (range_cells >= r_ini) * (range_cells < r_end)
# # print(f"loc = {loc}")
# # print(f"loc shape = {len(loc)}")
#
# # Filling the array with interpolation values
# res[loc] = range_cells[loc] * a + b
# # print(res.shape)
# # print(f"res = {res}")
# # print(f"1. res.shape = {res.shape}")
#
# # Filling first and last values
# i = 0
# while np.isnan(res[i]):
# res[i] = M_profile[0]
# i += 1
#
# # Filling the last values
# i = -1
# while np.isnan(res[i]):
# res[i] = M_profile[-1]
# i += -1
# # print(f"res.shape = {res.shape}")
# # print(f"res = {res}")
# # print(f"r_bottom.shape = {r_bottom.shape}")
# # print(f" = {res}")
#
# if r_bottom.shape != (0,):
# res[np.where(range_cells > r_bottom)] = np.nan
#
# loc_point_lin_interp0 = range_cells[np.where((range_cells > sample_depth[0]) & (range_cells < sample_depth[-1]))]
# # print(f"range_cells : {range_cells}")
# # print(f"loc_point_lin_interp0 shape : {len(loc_point_lin_interp0)}")
# # print(f"loc_point_lin_interp0 : {loc_point_lin_interp0}")
# res0 = res[np.where((range_cells > sample_depth[0]) & (range_cells < sample_depth[-1]))]
#
# loc_point_lin_interp = loc_point_lin_interp0[np.where(loc_point_lin_interp0 > range_cells[0])]
# # print(f"loc_point_lin_interp shape : {len(loc_point_lin_interp)}")
# # print(f"loc_point_lin_interp : {loc_point_lin_interp}")
# res = res0[np.where(loc_point_lin_interp0 > range_cells[0])]
#
# # fig, ax = plt.subplots(nrows=1, ncols=1)
# # ax.plot(loc_point_lin_interp, res[:len(loc_point_lin_interp)], marker="*", mfc="blue")
# # ax.plot(sample_depth, M_profile, marker="o", mfc="k", mec="k")
# # plt.show()
#
# return (loc_point_lin_interp, res)
def M_profile_SCC_fine_interpolated(self, sample_depth, M_profile, range_cells, r_bottom): def M_profile_SCC_fine_interpolated(self, sample_depth, M_profile, range_cells, r_bottom):
'''Computing interpolation of fine SSC data obtained from water sampling
collected at various depth in the vertical sample'''
res = np.zeros((len(range_cells),)) * np.nan res = np.zeros((len(range_cells),)) * np.nan
print("range_cells ", range_cells.shape)
l0 = sample_depth l0 = sample_depth
print("l0 = ", l0)
l1 = [l0.index(x) for x in sorted(l0)] l1 = [l0.index(x) for x in sorted(l0)]
print("l1 = ", l1)
l2 = [l0[k] for k in l1] l2 = [l0[k] for k in l1]
print("l2 = ", l2)
c1 = [list(M_profile)[j] for j in l1] c1 = [list(M_profile)[j] for j in l1]
print("c1 = ", c1)
for i in range(len(c1) - 1): for i in range(len(c1) - 1):
# print("i = ", i) # print("i = ", i)
r_ini = l2[i] r_ini = l2[i]
c_ini = c1[i] c_ini = c1[i]
r_end = l2[i + 1] r_end = l2[i + 1]
c_end = c1[i + 1] c_end = c1[i + 1]
print("r_ini ", r_ini, "c_ini ", c_ini, "r_end ", r_end, "c_end ", c_end)
# Computing the linear equation # Computing the linear equation
a = (c_end - c_ini) / (r_end - r_ini) a = (c_end - c_ini) / (r_end - r_ini)
b = c_ini - a * r_ini b = c_ini - a * r_ini
print("range_cells ", (range_cells))
# Finding the indices of r_ini and r_end in the interpolated array # Finding the indices of r_ini and r_end in the interpolated array
loc = (range_cells >= r_ini) * (range_cells < r_end) loc = (range_cells >= r_ini) * (range_cells < r_end)
print("range_cells >= r_ini ", range_cells >= r_ini)
print("range_cells < r_end ", range_cells < r_end)
print("loc ", loc)
# Filling the array with interpolation values # Filling the array with interpolation values
res[loc] = range_cells[loc] * a + b res[loc] = range_cells[loc] * a + b
print("a = ", a, "b = ", b)
print("res ", res)
# Filling first and last values # Filling first and last values
i = 0 i = 0
while np.isnan(res[i]): while np.isnan(res[i]):
@ -346,9 +178,6 @@ class AcousticInversionMethodHighConcentration():
i += -1 i += -1
if r_bottom.size != 0: if r_bottom.size != 0:
print("res ", res.shape)
print("range_cells ", len(range_cells))
# print("r_bottom ", len(r_bottom))
res[np.where(range_cells > r_bottom)] = np.nan res[np.where(range_cells > r_bottom)] = np.nan
loc_point_lin_interp0 = range_cells[np.where((range_cells > l2[0]) & (range_cells < l2[-1]))] loc_point_lin_interp0 = range_cells[np.where((range_cells > l2[0]) & (range_cells < l2[-1]))]
@ -357,13 +186,6 @@ class AcousticInversionMethodHighConcentration():
loc_point_lin_interp = loc_point_lin_interp0[np.where(loc_point_lin_interp0 > l2[0])] loc_point_lin_interp = loc_point_lin_interp0[np.where(loc_point_lin_interp0 > l2[0])]
res = res0[np.where(loc_point_lin_interp0 > l2[0])] res = res0[np.where(loc_point_lin_interp0 > l2[0])]
# fig, ax = plt.subplots(nrows=1, ncols=1)
# ax.plot(res[:len(loc_point_lin_interp)], -loc_point_lin_interp, marker="*", mfc="blue")
# ax.plot(c1, [-x for x in l2], marker="o", mfc="k", mec="k", ls="None")
# ax.set_xlabel("Concentration (g/L)")
# ax.set_ylabel("Depth (m)")
# plt.show()
return (loc_point_lin_interp, res) return (loc_point_lin_interp, res)
# ------------- Computing zeta ------------- # # ------------- Computing zeta ------------- #
@ -372,39 +194,6 @@ class AcousticInversionMethodHighConcentration():
delta_r = r[1] - r[0] delta_r = r[1] - r[0]
zeta = alpha_s / (np.sum(np.array(M_profile_fine)*delta_r)) zeta = alpha_s / (np.sum(np.array(M_profile_fine)*delta_r))
# print(f"np.sum(M_profile_fine*delta_r) : {np.sum(M_profile_fine*delta_r)}")
# zeta0 = np.array([0.021, 0.035, 0.057, 0.229])
# zeta = zeta0[ind]
# zeta0 = np.array([0.04341525, 0.04832906, 0.0847188, np.nan])
# zeta = zeta0[[ind1, ind2]]
# for k in range(3):
# for p in range(3):
# if np.isnan(ind_X_min_around_sample[p, k]):
# zeta_list_exp.append(np.nan)
# else:
# ind_X_min = int(ind_X_min_around_sample[p, k])
# ind_X_max = int(ind_X_max_around_sample[p, k])
# ind_r_min = int(ind_r_min_around_sample[p, k])
# ind_r_max = int(ind_r_max_around_sample[p, k])
#
# R_temp = R_cross_section[ind_r_min:ind_r_max, :, ind_X_min:ind_X_max]
# J_temp = J_cross_section[ind_r_min:ind_r_max, :, ind_X_min:ind_X_max]
# aw_temp = aw_cross_section[ind_r_min:ind_r_max, :, ind_X_min:ind_X_max]
# sv_temp_1 = np.repeat([sv_list_temp[3 * k + p]], np.shape(R_temp)[0], axis=0)
# sv_temp = np.swapaxes(np.swapaxes(np.repeat([sv_temp_1], np.shape(R_temp)[2], axis=0), 1, 0), 2, 1)
# ind_depth = np.where(R_cross_section[:, 0, 0] >= M_list_temp[k][0, p + 1])[0][0]
# # Using concentration profile
# zeta_temp = alpha_s / ((1 / M_list_temp[k][0, p + 1]) * (R_cross_section[0, 0, 0] * M_list_temp[k][1, 0] +
# delta_r * np.sum(M_interpolate_list[k][:ind_depth])))
# zeta_temp = (1 / (4 * R_temp) *
# np.log(sv_temp / J_temp) - aw_temp) / ((1 / M_list_temp[k][0, p + 1]) *
# (R_cross_section[0, 0, 0] * M_list_temp[k][
# 1, 0] +
# delta_r * np.sum(
# M_interpolate_list[k][:ind_depth])))
# zeta_list_exp.append(np.mean(np.mean(zeta_temp, axis=0), axis=1))
return zeta return zeta
# ------------- Computing VBI ------------- # # ------------- Computing VBI ------------- #
@ -415,21 +204,6 @@ class AcousticInversionMethodHighConcentration():
water_attenuation_freq1, water_attenuation_freq2, water_attenuation_freq1, water_attenuation_freq2,
X): X):
# print('self.zeta_exp[ind_j].shape', self.zeta_exp[ind_j])
# print('np.log(self.j_cross_section[:, ind_i, :]).shape', np.log(self.j_cross_section[:, ind_i, :]).shape)
# print('self.r_3D[:, ind_i, :]', self.r_3D[:, ind_i, :].shape)
# print('self.water_attenuation[ind_i]', self.water_attenuation[ind_i])
# print('self.x_exp[0.3-1 MHz]', self.x_exp['0.3-1 MHz'].values[0])
# print("start computing VBI")
# print("================================")
# print(f"zeta_freq2 : {zeta_freq2}")
# print(f"j_cross_section_freq1 : {j_cross_section_freq1.shape}")
# print(f"r2D : {r2D.shape}")
# print(f"water_attenuation_freq1 : {water_attenuation_freq1}")
# print(f"freq1 : {freq1}")
# print(f"X : {X}")
# print("================================")
logVBI = ((zeta_freq2 * logVBI = ((zeta_freq2 *
np.log(j_cross_section_freq1 * np.exp(4 * r2D * water_attenuation_freq1) / np.log(j_cross_section_freq1 * np.exp(4 * r2D * water_attenuation_freq1) /
(freq1 ** X)) - (freq1 ** X)) -
@ -438,31 +212,16 @@ class AcousticInversionMethodHighConcentration():
(freq2 ** X))) / (freq2 ** X))) /
(zeta_freq2 - zeta_freq1)) (zeta_freq2 - zeta_freq1))
# logVBI = (freq2**2 * np.log(j_cross_section_freq1 / freq1**X) -
# freq1**2 * np.log(j_cross_section_freq2 / freq2**X)) / (freq2**2 - freq1**2)
# logVBI = (( np.full((stg.r.shape[1], stg.t.shape[1]), zeta_freq2) *
# np.log(j_cross_section_freq1 * np.exp(4 * r2D * np.full((stg.r.shape[1], stg.t.shape[1]), water_attenuation_freq1)) /
# (freq1 ** X)) -
# np.full((stg.r.shape[1], stg.t.shape[1]), zeta_freq1) *
# np.log(j_cross_section_freq2 * np.exp(4 * r2D * np.full((stg.r.shape[1], stg.t.shape[1]), water_attenuation_freq2)) /
# (freq2 ** X))) /
# (zeta_freq2 - zeta_freq1))
print("compute VBI finished")
return np.exp(logVBI) return np.exp(logVBI)
# ------------- Computing SSC fine ------------- # # ------------- Computing SSC fine ------------- #
def SSC_fine(self, zeta, r2D, VBI, freq, X, j_cross_section, alpha_w): def SSC_fine(self, zeta, r2D, VBI, freq, X, j_cross_section, alpha_w):
SSC_fine = (1/zeta) * ( 1/(4 * r2D) * np.log((VBI * freq**X) / j_cross_section) - alpha_w) SSC_fine = (1/zeta) * ( 1/(4 * r2D) * np.log((VBI * freq**X) / j_cross_section) - alpha_w)
print("compute SSC fine finished")
return SSC_fine return SSC_fine
# ------------- Computing SSC sand ------------- # # ------------- Computing SSC sand ------------- #
def SSC_sand(self, VBI, freq, X, ks): def SSC_sand(self, VBI, freq, X, ks):
SSC_sand = (16 * np.pi * VBI * freq ** X) / (3 * ks**2) SSC_sand = (16 * np.pi * VBI * freq ** X) / (3 * ks**2)
print("compute SSC sand finished")
return SSC_sand return SSC_sand

View File

@ -389,10 +389,6 @@ class CreateTableForSaveAs:
) )
) )
logger.debug(f"stg.ind_bottom: {stg.ind_bottom[i]}")
logger.debug(np.array([stg.ind_bottom[i]]),
np.array(stg.ind_bottom[i]).shape)
# Commit the transaction after executing INSERT. # Commit the transaction after executing INSERT.
cnx.commit() cnx.commit()
@ -446,7 +442,7 @@ class CreateTableForSaveAs:
cur.execute(self.create_SedimentsFile) cur.execute(self.create_SedimentsFile)
if stg.path_fine != "" and path_sand != "": if stg.path_fine != "" and stg.path_sand != "":
cur.execute( cur.execute(
""" """
INSERT into SedimentsFile( INSERT into SedimentsFile(

View File

@ -1,8 +1,17 @@
# AcouSed # AcouSed
**TODO** short description AcouSed for **Acou**stic Backscattering for Concentration of Suspended **Sed**iments in Rivers is a software developped by INRAE, in collaboation with CNR.
## Getting started ![](icons/Logo-INRAE.jpg)
It is divided in six tabs:
- Acoustic data : acoustic raw data are downloaded and visualised
- Signal preprocessing : acoustic raw signal is preprocessed with filters
- Sample data : fine and sand sediments samples data are downloaded and visualised
- Calibration : calibration parameter are computed
- Inversion : inversion method is calculated to provide fine and sand sediments fields
## Software documentation
### Installation ### Installation
@ -11,8 +20,9 @@ greater. By default, Acoused is developped with Pypi package
dependencies, but is also possible to use Guix package manager to run dependencies, but is also possible to use Guix package manager to run
Acoused. Acoused.
### **TODO** Windows ## Development documentation
### **TODO** Windows
### Linux ### Linux
@ -39,33 +49,34 @@ script `guix.sh` to run the program.
guix shell sqlitebrowser -- ./guix.sh guix shell sqlitebrowser -- ./guix.sh
``` ```
## **TODO** Documentation
## Authors and acknowledgment
### Development
- Brahim MOUDJED ????-2025 ([INRAE](https://www.inrae.fr/))
- Pierre-Antoine ROUBY 2025 ([TECC](https://parouby.fr))
### **TODO** Funding
- [INRAE](https://www.inrae.fr/)
- CNR
## License ## License
Copyright (C) ????-2025 INRAE AcouSed
Copyright (C) 2024 - INRAE
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
GNU General Public License for more details.
## Authors & Contacts
- Brahim MOUDJED 2022-2025 ([INRAE](https://www.inrae.fr/))
- Pierre-Antoine ROUBY 2025 ([TECC](https://parouby.fr))
If you have any questions or suggestions, please contact us to celine.berni@inrae.fr and/or jerome.lecoz@inrae.fr.
## Acknowledgment (Funding)
This study was conducted within the [Rhône Sediment Observatory](https://observatoire-sediments-rhone.fr/) (OSR), a multi-partner research program funded through the Plan Rhône by the European Regional Development Fund (ERDF), Agence de lEau RMC, CNR, EDF and three regional councils (Auvergne-Rhône-Alpes, PACA and Occitanie). It was also support by CNR.
## Support files & References
- [ ] [Acoustic inversion method diagram](https://forgemia.inra.fr/theophile.terraz/acoused/-/blob/main/Acoustic_Inversion_theory.pdf?ref_type=heads)
- [ ] [Tutorial AQUAscat software : AQUAtalk](https://forgemia.inra.fr/theophile.terraz/acoused/-/blob/main/Tutorial_AQUAscat_software.pdf?ref_type=heads)
- [ ] [Adrien Vergne thesis (2018)](https://theses.fr/2018GREAU046)
- [ ] [Vergne A., Le Coz J., Berni C., & Pierrefeu G. (2020), Water Resources Research, 56(2)](https://doi.org/10.1029/2019WR024877)
- [ ] [Vergne A., Berni C., Le Coz J., & Tencé F., (2021), Water Resources Research, 57(9)](https://doi.org/10.1029/2021WR029589)
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -20,16 +20,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
import pandas as pd
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QComboBox,
QLabel, QPushButton, QSpacerItem,
QSlider, QLineEdit, QMessageBox, QFileDialog)
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import QIcon, QPixmap
import numpy as np import numpy as np
import pandas as pd
from copy import deepcopy
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
@ -37,9 +32,14 @@ from matplotlib.colors import LogNorm
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
from os import chdir from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QComboBox,
QLabel, QPushButton, QSpacerItem, QSlider, QLineEdit,
QMessageBox, QFileDialog
)
from copy import deepcopy from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import QIcon, QPixmap
from View.checkable_combobox import CheckableComboBox from View.checkable_combobox import CheckableComboBox
@ -1671,96 +1671,81 @@ class AcousticInversionTab(QWidget):
self.figure_measured_vs_inverted_sand.canvas.draw_idle() self.figure_measured_vs_inverted_sand.canvas.draw_idle()
def save_result_in_excel_file(self): def save_result_in_excel_file(self):
if self.combobox_acoustic_data_choice.count() > 0: if self.combobox_acoustic_data_choice.count() > 0:
name = QFileDialog.getSaveFileName( name = QFileDialog.getSaveFileName(
caption="Save As - Inversion results", directory="", filter="Excel Files (*.xlsx)", caption="Save As - Inversion results",
options=QFileDialog.DontUseNativeDialog) directory="",
filter="Excel Files (*.xlsx)",
options=QFileDialog.DontUseNativeDialog
)
if name[0]: if name[0]:
dirname = "/".join(name[0].split("/")[:-1]) + "/" dirname = os.path.dirname(name[0])
filename = name[0].split("/")[-1] filename = os.path.basename(name[0])
chdir(dirname) os.chdir(dirname)
results = []
for k in range(self.combobox_acoustic_data_choice.count()): for k in range(self.combobox_acoustic_data_choice.count()):
if stg.time_cross_section[k].shape != (0,): if stg.time_cross_section[k].shape != (0,):
time_data = stg.time_cross_section
if stg.depth_cross_section[k].shape != (0,):
t = np.repeat(stg.time_cross_section[k][stg.frequency_for_inversion[1]],
stg.depth_cross_section[k].shape[1])
r = np.zeros((stg.depth_cross_section[k].shape[1] *stg.time_cross_section[k].shape[1],1))
for i in range(stg.time_cross_section[k].shape[1]):
for j in range(stg.depth_cross_section[k].shape[1]):
r[i * stg.depth_cross_section[k].shape[1] + j] = (
stg.depth_cross_section[k][int(stg.frequency_for_inversion[1]), j])
if stg.SSC_fine[k].shape == (0,):
stg.SSC_fine[k] = np.zeros(r.shape[0])
if stg.SSC_sand[k].shape == (0,):
stg.SSC_sand[k] = np.zeros(r.shape[0])
else:
t = np.repeat(stg.time_cross_section[k][stg.frequency_for_inversion[1]], stg.depth[k].shape[1])
r = np.zeros((stg.depth[k].shape[1] * stg.time_cross_section[k].shape[1], 1))
for i in range(stg.time_cross_section[k].shape[1]):
for j in range(stg.depth[k].shape[1]):
r[i * stg.depth[k].shape[1] + j] = (
stg.depth[k][int(stg.frequency_for_inversion[1]), j])
if stg.SSC_fine[k].shape == (0,):
stg.SSC_fine[k] = np.zeros(r.shape[0])
if stg.SSC_sand[k].shape == (0,):
stg.SSC_sand[k] = np.zeros(r.shape[0])
else: else:
time_data = stg.time
if stg.depth_cross_section[k].shape != (0,): if stg.depth_cross_section[k].shape != (0,):
depth_data = stg.depth_cross_section
t = np.repeat(stg.time[k][stg.frequency_for_inversion[1]], stg.depth_cross_section[k].shape[1]) else:
depth_data = stg.depth
r = np.zeros((stg.depth_cross_section[k].shape[1] * stg.time[k].shape[1], 1))
for i in range(stg.time[k].shape[1]):
for j in range(stg.depth_cross_section[k].shape[1]):
r[i * stg.depth_cross_section[k].shape[1] + j] = (
stg.depth_cross_section[k][int(stg.frequency_for_inversion[1]), j])
if stg.SSC_fine[k].shape == (0,):
stg.SSC_fine[k] = np.zeros(r.shape[0])
if stg.SSC_sand[k].shape == (0,):
stg.SSC_sand[k] = np.zeros(r.shape[0])
else:
t = np.repeat(stg.time[k][stg.frequency_for_inversion[1]], stg.depth[k].shape[1])
r = np.zeros(stg.depth[k].shape[1] * stg.time[k].shape[1])
for i in range(stg.time[k].shape[1]):
for j in range(stg.depth[k].shape[1]):
r[i * stg.depth[k].shape[1] + j] = (
stg.depth[k][int(stg.frequency_for_inversion[1]), j])
if stg.SSC_fine[k].shape == (0,):
stg.SSC_fine[k] = np.zeros(r.shape[0])
if stg.SSC_sand[k].shape == (0,):
stg.SSC_sand[k] = np.zeros(r.shape[0])
exec("result_" + str(k) + "= pd.DataFrame({'Time (sec)': t," +
"'Depth (m)': r," +
"'SSC_fine (g/L)': stg.SSC_fine[" + str(k) + "].reshape(t.shape[0])," +
"'SSC_sand (g/L)': stg.SSC_sand[" + str(k) + "].reshape(t.shape[0])})")
t = np.repeat(
time_data[k][stg.frequency_for_inversion[1]],
depth_data[k].shape[1]
)
with pd.ExcelWriter(dirname + filename + '.xlsx') as writer: r = np.zeros(
depth_data[k].shape[1] * time_data[k].shape[1]
)
for i in range(time_data[k].shape[1]):
for j in range(depth_data[k].shape[1]):
r_id = i * depth_data[k].shape[1] + j
r[r_id] = (
depth_data[k][
int(stg.frequency_for_inversion[1]), j
]
)
if stg.SSC_fine[k].shape == (0,):
stg.SSC_fine[k] = np.zeros(r.shape[0])
if stg.SSC_sand[k].shape == (0,):
stg.SSC_sand[k] = np.zeros(r.shape[0])
results.append(
pd.DataFrame(
{
'Time (sec)': list(t),
'Depth (m)': list(r),
'SSC_fine (g/L)': list(
stg.SSC_fine[k].reshape(t.shape[0])
),
'SSC_sand (g/L)': list(
stg.SSC_sand[k].reshape(t.shape[0])
),
}
)
)
if os.path.splitext(filename)[1] != ".xlsx":
filename += ".xlsx"
with pd.ExcelWriter(
os.path.join(dirname, filename)
) as writer:
for k in range(self.combobox_acoustic_data_choice.count()): for k in range(self.combobox_acoustic_data_choice.count()):
eval("result_" + str(k) + ".to_excel(writer, index=False, " + results[k].to_excel(
"engine='xlsxwriter', na_rep='NA', " + writer, index=False,
"sheet_name=stg.data_preprocessed[" + str(k) + "])") engine='xlsxwriter', na_rep='NA',
sheet_name=stg.data_preprocessed[k],
)

View File

@ -1,8 +1,7 @@
from PyQt5.QtGui import QIcon, QPixmap from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import (QWidget, QLabel, QHBoxLayout, QVBoxLayout, QApplication, QMainWindow, QGridLayout, from PyQt5.QtWidgets import (QWidget, QLabel, QHBoxLayout, QVBoxLayout, QApplication, QMainWindow, QGridLayout,
QDialog, QDialogButtonBox, QPushButton, QTextEdit, QFrame, QTabWidget, QScrollArea) QDialog, QFrame, QTabWidget, QScrollArea)
from PyQt5.QtCore import Qt
import numpy as np import numpy as np
@ -11,13 +10,8 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
from matplotlib.colors import LogNorm, BoundaryNorm from matplotlib.colors import LogNorm, BoundaryNorm
import datetime
import settings as stg import settings as stg
from Translation.constant_string import HORIZONTAL
from settings import depth_cross_section
class PlotNoiseWindow(QDialog): class PlotNoiseWindow(QDialog):
@ -55,12 +49,10 @@ class PlotNoiseWindow(QDialog):
val_min = np.nanmin(stg.BS_noise_raw_data[i][freq_ind, :, :]) val_min = np.nanmin(stg.BS_noise_raw_data[i][freq_ind, :, :])
val_max = np.nanmax(stg.BS_noise_raw_data[i][freq_ind, :, :]) val_max = np.nanmax(stg.BS_noise_raw_data[i][freq_ind, :, :])
print("val_min = ", val_min, "val_max = ", val_max)
if val_min == val_max: if val_min == val_max:
exec("pcm = self.ax" + str(i) + "[" + str(freq_ind) + "]" + ".pcolormesh(" + exec("pcm = self.ax" + str(i) + "[" + str(freq_ind) + "]" + ".pcolormesh(" +
"stg.time[" + str(i) + "][" + str(freq_ind) + ", :]," + "stg.time_noise[" + str(i) + "][" + str(freq_ind) + ", :]," +
"-stg.depth[" + str(i) + "][" + str(freq_ind) + ", :]," + "-stg.depth_noise[" + str(i) + "][" + str(freq_ind) + ", :]," +
"stg.BS_noise_raw_data[" + str(i) + "][" + str(freq_ind) + ", :, :]," + "stg.BS_noise_raw_data[" + str(i) + "][" + str(freq_ind) + ", :, :]," +
"cmap='hsv')") "cmap='hsv')")
else: else:

View File

@ -20,12 +20,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel, QSpacerItem, QSizePolicy, import logging
QTableWidget, QPushButton, QLineEdit,
QTableWidgetItem, QComboBox, QFileDialog, QGridLayout, QMessageBox)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QCoreApplication, pyqtSignal
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@ -36,7 +32,13 @@ from matplotlib.colors import LogNorm, BASE_COLORS
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
from os import path from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel,
QSpacerItem, QSizePolicy, QTableWidget, QPushButton, QLineEdit,
QTableWidgetItem, QComboBox, QFileDialog, QGridLayout, QMessageBox
)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QCoreApplication, pyqtSignal
from Model.granulo_loader import GranuloLoader from Model.granulo_loader import GranuloLoader
@ -48,6 +50,7 @@ import settings as stg
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
logger = logging.getLogger()
class SampleDataTab(QWidget): class SampleDataTab(QWidget):
@ -57,8 +60,7 @@ class SampleDataTab(QWidget):
def __init__(self, widget_tab): def __init__(self, widget_tab):
super().__init__() super().__init__()
path_icon = "./icons/" icon_folder = QIcon(os.path.join("icons", "folder.png"))
icon_folder = QIcon(path_icon + "folder.png")
### --- General layout of widgets --- ### --- General layout of widgets ---
@ -269,20 +271,36 @@ class SampleDataTab(QWidget):
self.groupbox_plot_PSD.setTitle(_translate("CONSTANT_STRING", cs.DISTRIBUTION_PLOT)) self.groupbox_plot_PSD.setTitle(_translate("CONSTANT_STRING", cs.DISTRIBUTION_PLOT))
# ------------------------------------------------------------------------------------------------------------------
# --- Function to select directory and file name of fine sediments sample data ---
def open_dialog_box_fine_sediment(self):
def last_opened_file_path(self, priority="sand"):
lst = []
if priority == "sand":
lst += [stg.path_sand]
lst += [stg.path_fine]
else:
lst += [stg.path_fine]
lst += [stg.path_sand]
lst += stg.path_BS_raw_data
for path in lst:
if path != "":
return path
return ""
def open_dialog_box_fine_sediment(self):
filename_fine_sediment = QFileDialog.getOpenFileName( filename_fine_sediment = QFileDialog.getOpenFileName(
self, "Fine sediment file", self, "Fine sediment file",
[stg.path_fine if stg.path_fine else stg.path_sand if stg.path_sand self.last_opened_file_path(priority="fine"),
else stg.path_BS_raw_data[-1] if self.combobox_acoustic_data.count() > 0 else ""][0],
"Fine sediment file (*.xlsx, *xls, *.ods)", "Fine sediment file (*.xlsx, *xls, *.ods)",
options=QFileDialog.DontUseNativeDialog) options=QFileDialog.DontUseNativeDialog
)
try: try:
stg.path_fine = path.dirname(filename_fine_sediment[0]) stg.path_fine = os.path.dirname(filename_fine_sediment[0])
stg.filename_fine = path.basename(filename_fine_sediment[0]) stg.filename_fine = os.path.basename(filename_fine_sediment[0])
self.load_fine_sediment_data() self.load_fine_sediment_data()
except IsADirectoryError: except IsADirectoryError:
msgBox = QMessageBox() msgBox = QMessageBox()
@ -291,25 +309,24 @@ class SampleDataTab(QWidget):
msgBox.setText("Please select a file") msgBox.setText("Please select a file")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
except Exception as e:
logger.error(e)
else: else:
self.lineEdit_fine_sediment.clear() self.lineEdit_fine_sediment.clear()
self.lineEdit_fine_sediment.setText(stg.filename_fine) self.lineEdit_fine_sediment.setText(stg.filename_fine)
self.lineEdit_fine_sediment.setToolTip(stg.path_fine) self.lineEdit_fine_sediment.setToolTip(stg.path_fine)
self.fill_table_fine() self.fill_table_fine()
# --- Function to select directory and file name of sand sediments sample data ---
def open_dialog_box_sand_sediment(self): def open_dialog_box_sand_sediment(self):
filename_sand_sediment = QFileDialog.getOpenFileName( filename_sand_sediment = QFileDialog.getOpenFileName(
self, "Sand sediment file", self, "Sand sediment file",
[stg.path_sand if stg.path_sand else stg.path_fine if stg.path_fine self.last_opened_file_path(priority="sand"),
else stg.path_BS_raw_data[-1] if self.combobox_acoustic_data.count() > 0 else ""][0],
"Sand sediment file (*.xlsx, *xls, *.ods)", "Sand sediment file (*.xlsx, *xls, *.ods)",
options=QFileDialog.DontUseNativeDialog) options=QFileDialog.DontUseNativeDialog)
try: try:
stg.path_sand = path.dirname(filename_sand_sediment[0]) stg.path_sand = os.path.dirname(filename_sand_sediment[0])
stg.filename_sand = path.basename(filename_sand_sediment[0]) stg.filename_sand = os.path.basename(filename_sand_sediment[0])
self.load_sand_sediment_data() self.load_sand_sediment_data()
except IsADirectoryError: except IsADirectoryError:
msgBox = QMessageBox() msgBox = QMessageBox()
@ -318,13 +335,17 @@ class SampleDataTab(QWidget):
msgBox.setText("Please select a file") msgBox.setText("Please select a file")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
except Exception as e:
logger.error(e)
else: else:
self.lineEdit_sand_sediment.setText(stg.filename_sand) self.lineEdit_sand_sediment.setText(stg.filename_sand)
self.lineEdit_sand_sediment.setToolTip(stg.path_sand) self.lineEdit_sand_sediment.setToolTip(stg.path_sand)
self.fill_table_sand() self.fill_table_sand()
def load_fine_sediment_data(self): def load_fine_sediment_data(self):
fine_granulo_data = GranuloLoader(stg.path_fine + "/" + stg.filename_fine) fine_granulo_data = GranuloLoader(
os.path.join(stg.path_fine, stg.filename_fine)
)
stg.columns_fine = fine_granulo_data._data.columns stg.columns_fine = fine_granulo_data._data.columns
stg.time_fine = fine_granulo_data._time stg.time_fine = fine_granulo_data._time
stg.distance_from_bank_fine = fine_granulo_data._y stg.distance_from_bank_fine = fine_granulo_data._y
@ -336,7 +357,9 @@ class SampleDataTab(QWidget):
stg.frac_vol_fine_cumul = fine_granulo_data._frac_vol_cumul stg.frac_vol_fine_cumul = fine_granulo_data._frac_vol_cumul
def load_sand_sediment_data(self): def load_sand_sediment_data(self):
sand_granulo_data = GranuloLoader(stg.path_sand + "/" + stg.filename_sand) sand_granulo_data = GranuloLoader(
os.path.join(stg.path_sand, stg.filename_sand)
)
stg.columns_sand = sand_granulo_data._data.columns stg.columns_sand = sand_granulo_data._data.columns
stg.time_sand = sand_granulo_data._time stg.time_sand = sand_granulo_data._time
stg.distance_from_bank_sand = sand_granulo_data._y stg.distance_from_bank_sand = sand_granulo_data._y
@ -359,36 +382,57 @@ class SampleDataTab(QWidget):
# ------------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------------
# --- Function to fill table of values --- # --- Function to fill table of values ---
def fill_table_fine(self): def fill_table_fine(self):
if self.lineEdit_fine_sediment.text(): self.tableWidget_fine.blockSignals(True)
self.row_fine = self.tableWidget_fine.setRowCount(len(stg.depth_fine)) if self.lineEdit_fine_sediment.text():
self.column_fine = self.tableWidget_fine.setColumnCount(6 + stg.radius_grain_fine.shape[0]) self.row_fine = self.tableWidget_fine.setRowCount(
len(stg.depth_fine)
)
self.column_fine = self.tableWidget_fine.setColumnCount(
6 + stg.radius_grain_fine.shape[0]
)
# --- Set horizontal header --- # --- Set horizontal header ---
horizontal_header = list(
horizontal_header = list(itertools.chain(["Color", "Sample"], itertools.chain(
list(map(str, stg.columns_fine[[0, 2]])), ["Color", "Sample"],
list(map(str, stg.columns_fine[3:])))) list(map(str, stg.columns_fine[[0, 2]])),
list(map(str, stg.columns_fine[3:]))
)
)
for horizontal_header_text in horizontal_header: for horizontal_header_text in horizontal_header:
self.horizontal_header_item_fine = QTableWidgetItem() self.horizontal_header_item_fine = QTableWidgetItem()
self.tableWidget_fine.setHorizontalHeaderItem(horizontal_header.index(horizontal_header_text), self.tableWidget_fine.setHorizontalHeaderItem(
self.horizontal_header_item_fine) horizontal_header.index(horizontal_header_text),
self.horizontal_header_item_fine
)
self.horizontal_header_item_fine.setText(horizontal_header_text) self.horizontal_header_item_fine.setText(horizontal_header_text)
# --- Set vertical header (color) --- # --- Set vertical header (color) ---
self.tableWidget_fine.verticalHeader().setVisible(False) self.tableWidget_fine.verticalHeader().setVisible(False)
color_list = BASE_COLORS color_list = BASE_COLORS
self.comboBox_sample_table_fine = []
for i in range(self.tableWidget_fine.rowCount()): for i in range(self.tableWidget_fine.rowCount()):
exec("self.comboBox_sample_table_fine" + str(i) + "= QComboBox()") self.comboBox_sample_table_fine.append(
exec("self.comboBox_sample_table_fine" + str(i) + ".addItems(color_list)") QComboBox()
eval(f"self.tableWidget_fine.setCellWidget(i, 0, self.comboBox_sample_table_fine{i})") )
eval(f"self.comboBox_sample_table_fine{i}.currentTextChanged."
f"connect(self.plot_total_concentration)") self.comboBox_sample_table_fine[i].addItems(color_list)
eval(f"self.comboBox_sample_table_fine{i}.currentTextChanged." self.tableWidget_fine.setCellWidget(
f"connect(self.plot_PSD_fine_and_sand_sediments)") i, 0, self.comboBox_sample_table_fine[i]
eval(f"self.comboBox_sample_table_fine{i}.currentTextChanged." )
f"connect(self.update_plot_sample_position_on_transect)")
self.comboBox_sample_table_fine[i]\
.currentTextChanged\
.connect(self.plot_total_concentration)
self.comboBox_sample_table_fine[i]\
.currentTextChanged\
.connect(self.plot_PSD_fine_and_sand_sediments)
self.comboBox_sample_table_fine[i]\
.currentTextChanged\
.connect(self.update_plot_sample_position_on_transect)
# --- Fill Sample column with checkbox --- # --- Fill Sample column with checkbox ---
for i in range(self.tableWidget_fine.rowCount()): for i in range(self.tableWidget_fine.rowCount()):
@ -401,12 +445,21 @@ class SampleDataTab(QWidget):
# --- Fill table with data --- # --- Fill table with data ---
for i in range(stg.frac_vol_fine.shape[0]): for i in range(stg.frac_vol_fine.shape[0]):
for j in range(stg.frac_vol_fine.shape[1]): for j in range(stg.frac_vol_fine.shape[1]):
self.tableWidget_fine.setItem(i, 2, QTableWidgetItem(str(stg.time_fine[i]))) self.tableWidget_fine.setItem(
self.tableWidget_fine.setItem(i, 3, QTableWidgetItem(str(stg.depth_fine[i]))) i, 2, QTableWidgetItem(str(stg.time_fine[i]))
)
self.tableWidget_fine.setItem(i, 4, QTableWidgetItem(str(stg.Ctot_fine[i]))) self.tableWidget_fine.setItem(
self.tableWidget_fine.setItem(i, 5, QTableWidgetItem(str(stg.D50_fine[i]))) i, 3, QTableWidgetItem(str(stg.depth_fine[i]))
self.tableWidget_fine.setItem(i, j + 6, QTableWidgetItem(str(stg.frac_vol_fine[i, j]))) )
self.tableWidget_fine.setItem(
i, 4, QTableWidgetItem(str(stg.Ctot_fine[i]))
)
self.tableWidget_fine.setItem(
i, 5, QTableWidgetItem(str(stg.D50_fine[i]))
)
self.tableWidget_fine.setItem(
i, j + 6, QTableWidgetItem(str(stg.frac_vol_fine[i, j]))
)
# --- Connect checkbox to all checkboxes of tableWidget --- # --- Connect checkbox to all checkboxes of tableWidget ---
# self.allChkBox.stateChanged.connect(self.check_allChkBox) # self.allChkBox.stateChanged.connect(self.check_allChkBox)
@ -423,6 +476,7 @@ class SampleDataTab(QWidget):
self.plot_total_concentration() self.plot_total_concentration()
self.plot_PSD_fine_and_sand_sediments() self.plot_PSD_fine_and_sand_sediments()
self.tableWidget_fine.blockSignals(False)
else: else:
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.setWindowTitle("Fill table Error") msgBox.setWindowTitle("Fill table Error")
@ -432,36 +486,50 @@ class SampleDataTab(QWidget):
msgBox.exec() msgBox.exec()
def fill_table_sand(self): def fill_table_sand(self):
if self.lineEdit_sand_sediment.text(): self.tableWidget_sand.blockSignals(True)
if self.lineEdit_sand_sediment.text():
self.row_sand = self.tableWidget_sand.setRowCount(len(stg.depth_sand)) self.row_sand = self.tableWidget_sand.setRowCount(len(stg.depth_sand))
self.column_sand = self.tableWidget_sand.setColumnCount(6 + stg.radius_grain_sand.shape[0]) self.column_sand = self.tableWidget_sand.setColumnCount(6 + stg.radius_grain_sand.shape[0])
# --- Set horizontal header --- # --- Set horizontal header ---
horizontal_header = list(
horizontal_header = list(itertools.chain(["Color", "Sample"], itertools.chain(
list(map(str, stg.columns_sand[[0, 2]])), ["Color", "Sample"],
list(map(str, stg.columns_sand[3:])))) list(map(str, stg.columns_sand[[0, 2]])),
list(map(str, stg.columns_sand[3:]))
)
)
for horizontal_header_text in horizontal_header: for horizontal_header_text in horizontal_header:
self.horizontal_header_item_sand = QTableWidgetItem() self.horizontal_header_item_sand = QTableWidgetItem()
self.tableWidget_sand.setHorizontalHeaderItem(horizontal_header.index(horizontal_header_text), self.tableWidget_sand.setHorizontalHeaderItem(
self.horizontal_header_item_sand) horizontal_header.index(horizontal_header_text),
self.horizontal_header_item_sand
)
self.horizontal_header_item_sand.setText(horizontal_header_text) self.horizontal_header_item_sand.setText(horizontal_header_text)
# --- Set vertical header (color) --- # --- Set vertical header (color) ---
self.tableWidget_sand.verticalHeader().setVisible(False) self.tableWidget_sand.verticalHeader().setVisible(False)
color_list = BASE_COLORS color_list = BASE_COLORS
self.comboBox_sample_table_sand = []
for i in range(self.tableWidget_sand.rowCount()): for i in range(self.tableWidget_sand.rowCount()):
exec("self.comboBox_sample_table_sand" + str(i) + "= QComboBox()") self.comboBox_sample_table_sand.append(QComboBox())
exec("self.comboBox_sample_table_sand" + str(i) + ".addItems(color_list)")
eval(f"self.tableWidget_sand.setCellWidget(i, 0, self.comboBox_sample_table_sand{i})") self.comboBox_sample_table_sand[i].addItems(color_list)
eval(f"self.comboBox_sample_table_sand{i}.currentTextChanged." self.tableWidget_sand.setCellWidget(
f"connect(self.plot_total_concentration)") i, 0, self.comboBox_sample_table_sand[i]
eval(f"self.comboBox_sample_table_sand{i}.currentTextChanged." )
f"connect(self.plot_PSD_fine_and_sand_sediments)")
eval(f"self.comboBox_sample_table_sand{i}.currentTextChanged." self.comboBox_sample_table_sand[i]\
f"connect(self.update_plot_sample_position_on_transect)") .currentTextChanged\
.connect(self.plot_total_concentration)
self.comboBox_sample_table_sand[i]\
.currentTextChanged\
.connect(self.plot_PSD_fine_and_sand_sediments)
self.comboBox_sample_table_sand[i]\
.currentTextChanged\
.connect(self.update_plot_sample_position_on_transect)
# --- Fill Sample column with checkbox --- # --- Fill Sample column with checkbox ---
for i in range(self.tableWidget_sand.rowCount()): for i in range(self.tableWidget_sand.rowCount()):
@ -474,25 +542,44 @@ class SampleDataTab(QWidget):
# --- Fill table with data --- # --- Fill table with data ---
for i in range(stg.frac_vol_sand.shape[0]): for i in range(stg.frac_vol_sand.shape[0]):
for j in range(stg.frac_vol_sand.shape[1]): for j in range(stg.frac_vol_sand.shape[1]):
self.tableWidget_sand.setItem(i, 2, QTableWidgetItem(str(stg.time_sand[i]))) self.tableWidget_sand.setItem(
self.tableWidget_sand.setItem(i, 3, QTableWidgetItem(str(stg.depth_sand[i]))) i, 2, QTableWidgetItem(str(stg.time_sand[i]))
)
self.tableWidget_sand.setItem(i, 4, QTableWidgetItem(str(stg.Ctot_sand[i]))) self.tableWidget_sand.setItem(
self.tableWidget_sand.setItem(i, 5, QTableWidgetItem(str(stg.D50_sand[i]))) i, 3, QTableWidgetItem(str(stg.depth_sand[i]))
self.tableWidget_sand.setItem(i, j + 6, QTableWidgetItem(str(stg.frac_vol_sand[i, j]))) )
self.tableWidget_sand.setItem(
i, 4, QTableWidgetItem(str(stg.Ctot_sand[i]))
)
self.tableWidget_sand.setItem(
i, 5, QTableWidgetItem(str(stg.D50_sand[i]))
)
self.tableWidget_sand.setItem(
i, j + 6, QTableWidgetItem(str(stg.frac_vol_sand[i, j]))
)
# --- Connect checkbox items of tableWidget to update plots --- # --- Connect checkbox items of tableWidget to update plots ---
self.tableWidget_sand.itemChanged.connect(self.update_plot_sample_position_on_transect) self.tableWidget_sand\
self.tableWidget_sand.itemChanged.connect(self.plot_total_concentration) .itemChanged\
self.tableWidget_sand.itemChanged.connect(self.plot_PSD_fine_and_sand_sediments) .connect(self.update_plot_sample_position_on_transect)
self.tableWidget_sand\
.itemChanged\
.connect(self.plot_total_concentration)
self.tableWidget_sand\
.itemChanged\
.connect(self.plot_PSD_fine_and_sand_sediments)
self.combobox_x_axis.currentIndexChanged.connect(self.plot_total_concentration) self.combobox_x_axis.currentIndexChanged\
self.combobox_y_axis.currentIndexChanged.connect(self.plot_total_concentration) .connect(self.plot_total_concentration)
self.combobox_y_axis.currentIndexChanged\
.connect(self.plot_total_concentration)
self.plot_sample_position_on_transect() self.plot_sample_position_on_transect()
self.plot_total_concentration() self.plot_total_concentration()
self.plot_PSD_fine_and_sand_sediments() self.plot_PSD_fine_and_sand_sediments()
self.tableWidget_sand.blockSignals(False)
# --- Function to extract position of sample from table checkboxes to update plots --- # --- Function to extract position of sample from table checkboxes to update plots ---
def extract_position_list_and_color_list_from_table_checkboxes_fine(self): def extract_position_list_and_color_list_from_table_checkboxes_fine(self):
position = [] position = []
@ -502,7 +589,7 @@ class SampleDataTab(QWidget):
if self.tableWidget_fine.item(i, 1).checkState() == 2: if self.tableWidget_fine.item(i, 1).checkState() == 2:
if self.tableWidget_fine.item(i, 1).checkState() == Qt.Checked: if self.tableWidget_fine.item(i, 1).checkState() == Qt.Checked:
position.append(i) position.append(i)
eval(f"color_list.append(self.comboBox_sample_table_fine{i}.currentText())") color_list.append(self.comboBox_sample_table_fine[i].currentText())
sample_checkbox[0, i] = 2 sample_checkbox[0, i] = 2
return position, color_list return position, color_list
@ -570,7 +657,9 @@ class SampleDataTab(QWidget):
if self.tableWidget_sand.item(i, 1).checkState() == 2: if self.tableWidget_sand.item(i, 1).checkState() == 2:
if self.tableWidget_sand.item(i, 1).checkState() == Qt.Checked: if self.tableWidget_sand.item(i, 1).checkState() == Qt.Checked:
position.append(i) position.append(i)
eval(f"color_list.append(self.comboBox_sample_table_sand{i}.currentText())") color_list.append(
self.comboBox_sample_table_sand[i].currentText()
)
sample_checkbox[0, i] = 2 sample_checkbox[0, i] = 2
return position, color_list return position, color_list
@ -646,7 +735,6 @@ class SampleDataTab(QWidget):
self.combobox_acoustic_data.showPopup() self.combobox_acoustic_data.showPopup()
def fill_comboboxes_and_plot_transect(self): def fill_comboboxes_and_plot_transect(self):
self.combobox_acoustic_data.clear() self.combobox_acoustic_data.clear()
for n, m in enumerate(stg.noise_method): for n, m in enumerate(stg.noise_method):
if stg.noise_method[n] == 0: if stg.noise_method[n] == 0:
@ -659,19 +747,23 @@ class SampleDataTab(QWidget):
self.combobox_frequencies.currentIndexChanged.connect(self.update_plot_sample_position_on_transect) self.combobox_frequencies.currentIndexChanged.connect(self.update_plot_sample_position_on_transect)
def plot_sample_position_on_transect(self): def plot_sample_position_on_transect(self):
self.verticalLayout_groupbox_plot_transect\
.removeWidget(self.canvas_plot_sample_position_on_transect)
self.verticalLayout_groupbox_plot_transect.removeWidget(self.canvas_plot_sample_position_on_transect) fig, axis = plt.subplots(nrows=1, ncols=1, layout="constrained")
self.figure_plot_sample_position_on_transect, self.axis_plot_sample_position_on_transect = \ self.figure_plot_sample_position_on_transect = fig
plt.subplots(nrows=1, ncols=1, layout="constrained") self.axis_plot_sample_position_on_transect = axis
self.canvas_plot_sample_position_on_transect = FigureCanvas(self.figure_plot_sample_position_on_transect)
self.verticalLayout_groupbox_plot_transect.addWidget(self.canvas_plot_sample_position_on_transect) self.canvas_plot_sample_position_on_transect = FigureCanvas(
self.figure_plot_sample_position_on_transect
)
self.verticalLayout_groupbox_plot_transect\
.addWidget(self.canvas_plot_sample_position_on_transect)
if self.combobox_acoustic_data.count() == 0: if self.combobox_acoustic_data.count() == 0:
if self.tableWidget_fine.columnCount() > 10: if self.tableWidget_fine.columnCount() > 10:
position_list_fine, color_list_fine = self.extract_position_list_and_color_list_from_table_checkboxes_fine() position_list_fine, color_list_fine = self.extract_position_list_and_color_list_from_table_checkboxes_fine()
self.axis_plot_sample_position_on_transect.scatter( self.axis_plot_sample_position_on_transect.scatter(
@ -1696,4 +1788,3 @@ class SampleDataTab(QWidget):
self.axis_plot_PSD[1].set_ylabel('Cumulative size volume fraction') self.axis_plot_PSD[1].set_ylabel('Cumulative size volume fraction')
self.figure_plot_PSD.canvas.draw_idle() self.figure_plot_PSD.canvas.draw_idle()

View File

@ -1090,23 +1090,20 @@ class SignalProcessingTab(QWidget):
val_max = np.nanmax(stg.SNR_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][f, :, :]) val_max = np.nanmax(stg.SNR_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][f, :, :])
if val_min == val_max: if val_min == val_max:
levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1.2]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
else: else:
if val_min == 0: if val_min == 0:
val_min = 1e-5 val_min = 1e-5
if val_max > 1000: if val_max > 1000:
levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1.2]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
else: else:
levels = np.array([00.1, 1, 2, 10, 100, val_max]) levels = np.array([00.1, 1, 2, 10, 100, 1000, val_max * 1000 + 1])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1000] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1000 + 1]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2]
norm = BoundaryNorm(boundaries=bounds, ncolors=300)
cf = (self.axis_SNR[f].contourf(x, -y, cf = (self.axis_SNR[f].contourf(x, -y,
stg.SNR_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][f, :, :], stg.SNR_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][f, :, :],
levels, cmap='gist_rainbow', levels, cmap='gist_rainbow',
@ -1146,24 +1143,21 @@ class SignalProcessingTab(QWidget):
val_max = np.nanmax(stg.SNR_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, :, :]) val_max = np.nanmax(stg.SNR_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, :, :])
if val_min == val_max: if val_min == val_max:
levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1.2]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
else: else:
if val_min == 0: if val_min == 0:
val_min = 1e-5 val_min = 1e-5
if val_max > 1000: if val_max > 1000:
levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1.2]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
else: else:
levels = np.array([00.1, 1, 2, 10, 100, val_max]) levels = np.array([00.1, 1, 2, 10, 100, 1000, val_max * 1000 + 1])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1000] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1000 + 1]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2]
norm = BoundaryNorm(boundaries=bounds, ncolors=300)
cf = (self.axis_SNR[f].contourf(x, -y, cf = (self.axis_SNR[f].contourf(x, -y,
stg.SNR_cross_section[ stg.SNR_cross_section[
self.combobox_acoustic_data_choice.currentIndex()][f, :, :], self.combobox_acoustic_data_choice.currentIndex()][f, :, :],
@ -1178,18 +1172,18 @@ class SignalProcessingTab(QWidget):
val_max = np.nanmax(stg.SNR_raw_data[self.combobox_acoustic_data_choice.currentIndex()][f, :, :]) val_max = np.nanmax(stg.SNR_raw_data[self.combobox_acoustic_data_choice.currentIndex()][f, :, :])
if val_min == val_max: if val_min == val_max:
levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1.2]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
else: else:
if val_min == 0: if val_min == 0:
val_min = 1e-5 val_min = 1e-5
if val_max > 1000: if val_max > 1000:
levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1.2]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
else: else:
levels = np.array([00.1, 1, 2, 10, 100, val_max]) levels = np.array([00.1, 1, 2, 10, 100, 1000, val_max*1000 + 1])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1000] bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1000 + 1]
norm = BoundaryNorm(boundaries=bounds, ncolors=300) norm = BoundaryNorm(boundaries=bounds, ncolors=300)
cf = (self.axis_SNR[f].contourf(x, -y, cf = (self.axis_SNR[f].contourf(x, -y,