diff --git a/Model/acoustic_inversion_method_high_concentration.py b/Model/acoustic_inversion_method_high_concentration.py index 4e5e727..e7d7164 100644 --- a/Model/acoustic_inversion_method_high_concentration.py +++ b/Model/acoustic_inversion_method_high_concentration.py @@ -51,7 +51,7 @@ class AcousticInversionMethodHighConcentration(): min_demodul = 1e-6 max_demodul = 500e-6 - sample_demodul = demodul_granulo(r_grain, frac_vol_cumul[num_sample, :], min_demodul, max_demodul) + sample_demodul = demodul_granulo(r_grain, frac_vol_cumul[num_sample], min_demodul, max_demodul) resampled_log_array = np.log(np.logspace(-10, -2, 3000)) proba_vol_demodul = mix_gaussian_model(resampled_log_array, @@ -64,9 +64,9 @@ class AcousticInversionMethodHighConcentration(): # 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}") + # 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) ss = np.sum(proba_vol_demodul / np.exp(resampled_log_array) ** 3) @@ -75,7 +75,7 @@ class AcousticInversionMethodHighConcentration(): return proba_num # ------------- Computing ks ------------- # - def form_factor_function_MoateThorne2012(self, a, freq, C=1500): + def form_factor_function_MoateThorne2012(self, a, freq, C): """This function computes the form factor based on the equation of Moate and Thorne (2012)""" # computing the wave number @@ -86,18 +86,19 @@ class AcousticInversionMethodHighConcentration(): # print(f"form factor = {f}") return f - def ks(self, num_sample, freq, pdf): + # def ks(self, num_sample_sand, radius_grain_sand, frac_vol_sand_cumul, 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, r_grain=stg.radius_grain, frac_vol_cumul=stg.frac_vol_sand_cumul)) + # 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}") + # print(f"proba_num : {proba_num}") # --- Compute k_s by dividing two integrals --- resampled_log_array = np.log(np.logspace(-10, -2, 3000)) @@ -105,11 +106,12 @@ class AcousticInversionMethodHighConcentration(): a3pdf = 0 for i in range(len(resampled_log_array)): a = np.exp(resampled_log_array)[i] - a2f2pdf += a**2 * self.form_factor_function_MoateThorne2012(a, freq)**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] - print(f"a2f2pdf = {a2f2pdf}") - print(f"a3pdf = {a3pdf}") + # print("form factor ", self.form_factor_function_MoateThorne2012(a, freq, C)) + # print(f"a2f2pdf = {a2f2pdf}") + # print(f"a3pdf = {a3pdf}") ks = np.sqrt(a2f2pdf / a3pdf) @@ -176,8 +178,8 @@ class AcousticInversionMethodHighConcentration(): # print("BS min : ", np.nanmin(BS)) # print("BS max : ", np.nanmax(BS)) # print("r2D : ", r2D) - print("kt shape : ", kt.shape) - print("kt : ", kt) + # 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) @@ -247,12 +249,13 @@ class AcousticInversionMethodHighConcentration(): while np.isnan(res[i]): res[i] = M_profile[-1] i += -1 - - if stg.r_bottom.size != 0: - res[np.where(range_cells > r_bottom)] = np.nan - - # print(f"2. res.shape = {res.shape}") + # 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}") @@ -276,9 +279,9 @@ class AcousticInversionMethodHighConcentration(): def zeta(self, alpha_s, r, M_profile_fine): delta_r = r[1] - r[0] - zeta = alpha_s / (np.sum(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)}") + # 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]) diff --git a/Model/granulo_loader.py b/Model/granulo_loader.py index 08a628e..8870afc 100644 --- a/Model/granulo_loader.py +++ b/Model/granulo_loader.py @@ -16,7 +16,7 @@ class GranuloLoader: self._y = self._data.iloc[:, 1].tolist() # distance from left bank (m) self._z = self._data.iloc[:, 2].tolist() # depth (m) - self._r_grain = 1e-6 * self._data.columns.values[5:] / 2 + self._r_grain = 1e-6 * np.array(self._data.columns.values)[5:].astype(float) / 2 # self._r_grain = 1e-6 * np.array(self._data.columns.values)[5:].astype(float) / 2 # grain radius (m) self._Ctot = self._data.iloc[:, 3].tolist() # Total concentration (g/L) diff --git a/View/sediment_calibration_tab.py b/View/sediment_calibration_tab.py index cdbdd1d..01b9d2d 100644 --- a/View/sediment_calibration_tab.py +++ b/View/sediment_calibration_tab.py @@ -54,6 +54,8 @@ class SedimentCalibrationTab(QWidget): # ++++++++++++++++++++++++++++++ # +++ Groupbox acoustic data +++ + self.groupbox_acoustic_data.setTitle("Step 1 : acoustic and sample data choice") + self.verticalLayout_groupbox_acoustic_data = QVBoxLayout(self.groupbox_acoustic_data) # self.horizontalLayout_acoustic_data_choice = QHBoxLayout() @@ -111,8 +113,14 @@ class SedimentCalibrationTab(QWidget): # +++++++++++++++++++++++++++++++++++++++++++ # +++ Groupbox Fine concentration profile +++ + self.groupbox_Mfine_profile.setTitle("Step 2 : profile of the fine sediment concentration") + self.verticalLayout_groupbox_Mfine_profile = QVBoxLayout(self.groupbox_Mfine_profile) + self.pushbutton_interpolate_Mfine_profile = QPushButton() + self.pushbutton_interpolate_Mfine_profile.setText("Interpolate") + self.verticalLayout_groupbox_Mfine_profile.addWidget(self.pushbutton_interpolate_Mfine_profile) + self.canvas_Mfine = FigureCanvas() self.toolbar_Mfine = NavigationToolBar(self.canvas_Mfine, self) @@ -130,6 +138,8 @@ class SedimentCalibrationTab(QWidget): # ++++++++++++++++++++ # +++ Groupbox FCB +++ + self.groupbox_FCB.setTitle("Step 3 : Fluid Corrected Backscatter") + self.verticalLayout_groupbox_FCB = QVBoxLayout(self.groupbox_FCB) self.canvas_FCB = FigureCanvas() @@ -141,35 +151,83 @@ class SedimentCalibrationTab(QWidget): # +++++++++++++++++++++++++++++++++++++ # +++ Groupbox sediment calibration +++ - self.groupbox_sediment_calibration.setTitle("Sediment calibration") + self.groupbox_sediment_calibration.setTitle("Step 4 : Compute Calibration") self.gridLayout_groupbox_sediment_calibration = QGridLayout(self.groupbox_sediment_calibration) - self.label_freq1 = QLabel("freq1") - self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_freq1, 0, 1, 1, 1) + self.pushbutton_compute_calibration = QPushButton() + self.pushbutton_compute_calibration.setText("Compute Calibration") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.pushbutton_compute_calibration, 0, 0, 1, 1) - self.label_freq2 = QLabel("freq2") - self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_freq2, 0, 2, 1, 1) + self.label_freq1 = QLabel("Frequency 1") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_freq1, 1, 1, 1, 1) + + self.label_freq2 = QLabel("Frequency 2") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_freq2, 1, 2, 1, 1) self.label_ks = QLabel() self.label_ks.setText("ks") - self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_ks, 1, 0, 1, 1) + self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_ks, 2, 0, 1, 1) + + self.spinbox_ks_freq1 = QDoubleSpinBox() + self.spinbox_ks_freq1.setDecimals(8) + self.spinbox_ks_freq1.setSuffix(" m/kg^0.5") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_ks_freq1, 2, 1, 1, 1) + + self.spinbox_ks_freq2 = QDoubleSpinBox() + self.spinbox_ks_freq2.setDecimals(8) + self.spinbox_ks_freq2.setSuffix(" m/kg^0.5") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_ks_freq2, 2, 2, 1, 1) self.label_sv = QLabel() self.label_sv.setText("sv") - self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_sv, 2, 0, 1, 1) + self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_sv, 3, 0, 1, 1) + + self.spinbox_sv_freq1 = QDoubleSpinBox() + self.spinbox_sv_freq1.setDecimals(8) + self.spinbox_sv_freq1.setSuffix(" /m") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_sv_freq1, 3, 1, 1, 1) + + self.spinbox_sv_freq2 = QDoubleSpinBox() + self.spinbox_sv_freq2.setDecimals(8) + self.spinbox_sv_freq2.setSuffix(" /m") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_sv_freq2, 3, 2, 1, 1) self.label_X = QLabel() self.label_X.setText("X") - self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_X, 3, 0, 1, 1) + self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_X, 4, 0, 1, 1) + + self.spinbox_X = QDoubleSpinBox() + self.spinbox_X.setDecimals(2) + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_X, 4, 1, 1, 2) self.label_alphas = QLabel() self.label_alphas.setText("\u03B1s") - self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_alphas, 4, 0, 1, 1) + self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_alphas, 5, 0, 1, 1) + + self.spinbox_alphas_freq1 = QDoubleSpinBox() + self.spinbox_alphas_freq1.setDecimals(4) + self.spinbox_alphas_freq1.setSuffix(" /m") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_alphas_freq1, 5, 1, 1, 1) + + self.spinbox_alphas_freq2 = QDoubleSpinBox() + self.spinbox_alphas_freq2.setDecimals(4) + self.spinbox_alphas_freq2.setSuffix(" /m") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_alphas_freq2, 5, 2, 1, 1) self.label_zeta = QLabel() self.label_zeta.setText("\u03B6") - self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_zeta, 5, 0, 1, 1) + self.gridLayout_groupbox_sediment_calibration.addWidget(self.label_zeta, 6, 0, 1, 1) + + self.spinbox_zeta_freq1 = QDoubleSpinBox() + self.spinbox_zeta_freq1.setDecimals(4) + self.spinbox_zeta_freq1.setSuffix(" /m") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_zeta_freq1, 6, 1, 1, 1) + + self.spinbox_zeta_freq2 = QDoubleSpinBox() + self.spinbox_zeta_freq2.setDecimals(4) + self.spinbox_zeta_freq2.setSuffix(" /m") + self.gridLayout_groupbox_sediment_calibration.addWidget(self.spinbox_zeta_freq2, 6, 2, 1, 1) # ============================================================================================================== # ---------------------------------------- Connect signal of widget -------------------------------------------- @@ -179,6 +237,10 @@ class SedimentCalibrationTab(QWidget): self.pushbutton_plot_sample.clicked.connect(self.function_pushbutton_plot_sample) + self.pushbutton_interpolate_Mfine_profile.clicked.connect(self.interpolate_Mfine_profile) + + self.pushbutton_compute_calibration.clicked.connect(self.function_pushbutton_compute_calibration) + # ============================================================================================================== # ----------------------------------- Functions for Signal processing Tab -------------------------------------- # ============================================================================================================== @@ -220,7 +282,7 @@ class SedimentCalibrationTab(QWidget): self.verticalLayout_groupbox_acoustic_data.addWidget(self.canvas_BS) if stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): - + print("totototototototoott") val_min = np.nanmin( stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :, :]) @@ -325,8 +387,101 @@ class SedimentCalibrationTab(QWidget): stg.sand_sample_target = [(s, int(s[1:]) - 1) for s in self.combobox_sand_sample_choice.currentData()] print(f"stg.sand_sample_target : {stg.sand_sample_target}") + # --- Find index in time (along acoustic recording) of sand sample target --- + if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): + t1 = ( + np.where(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()] - stg.time_sand[stg.sand_sample_target[0][1]]) == + np.nanmin(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()] - stg.time_sand[stg.sand_sample_target[0][1]])))[0][0] + ) + t2 = ( + np.where(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()] - stg.time_sand[stg.sand_sample_target[0][1]]) == + np.nanmin(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()] - stg.time_sand[stg.sand_sample_target[0][1]])))[0][0] + ) + else: + t1 = ( + np.where(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()] - stg.time_sand[ + stg.sand_sample_target[0][1]]) == + np.nanmin(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()] - stg.time_sand[ + stg.sand_sample_target[0][1]])))[0][0] + ) + t2 = ( + np.where(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()] - stg.time_sand[ + stg.sand_sample_target[0][1]]) == + np.nanmin(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()] - stg.time_sand[ + stg.sand_sample_target[0][1]])))[0][0] + ) + + # --- Find index in depth (along acoustic recording) of sand sample target --- + if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): + d1 = ( + np.where(np.abs(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()] - (-stg.depth_sand[stg.sand_sample_target[0][1]]) ) == + np.nanmin(np.abs(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()] - (-stg.depth_sand[stg.sand_sample_target[0][1]]) )))[0][0] + ) + d2 = ( + np.where(np.abs(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()] - (-stg.depth_sand[stg.sand_sample_target[0][1]]) ) == + np.nanmin(np.abs(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()] - (-stg.depth_sand[stg.sand_sample_target[0][1]]) )))[0][0] + ) + else: + d1 = ( + np.where(np.abs(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()] - (-stg.depth_sand[ + stg.sand_sample_target[0][1]]) ) == + np.nanmin(np.abs(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()] - (-stg.depth_sand[ + stg.sand_sample_target[0][1]]) )))[0][0] + ) + d2 = ( + np.where(np.abs(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()] - (-stg.depth_sand[ + stg.sand_sample_target[0][1]]) ) == + np.nanmin(np.abs(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()] - (-stg.depth_sand[ + stg.sand_sample_target[0][1]]) )))[0][0] + ) + + stg.sand_sample_target_indice = [(d1, t1), (d2, t2)] + print("stg.sand_sample_target_indice ", stg.sand_sample_target_indice) + def plot_profile_of_concentration_fine(self): + # --- Plot profile of the concentration of the fine sediments --- + self.verticalLayout_groupbox_Mfine_profile.removeWidget(self.canvas_Mfine) + self.verticalLayout_groupbox_Mfine_profile.removeWidget(self.toolbar_Mfine) + self.fig_Mfine, self.ax_Mfine = plt.subplots(1, 1, layout="constrained") + self.canvas_Mfine = FigureCanvas(self.fig_Mfine) + self.toolbar_Mfine = NavigationToolBar(self.canvas_Mfine, self) + self.verticalLayout_groupbox_Mfine_profile.addWidget(self.toolbar_Mfine) + self.verticalLayout_groupbox_Mfine_profile.addWidget(self.canvas_Mfine) + + for t, c in stg.fine_sample_profile: + + self.ax_Mfine.plot(stg.Ctot_fine[c], stg.depth_fine[c], + marker="o", mfc="k", mec="k", ms=10, ls="None") + + self.ax_Mfine.text(stg.Ctot_fine[c] + 0.05 * stg.Ctot_fine[c], stg.depth_fine[c], t, + fontstyle="normal", fontweight="light", fontsize=12) + + self.ax_Mfine.set_xlabel("Concentration fine sediments (g/L)") + self.ax_Mfine.set_ylabel("Depth (m)") + + if stg.M_profile_fine: + self.ax_Mfine.plot(stg.M_profile_fine, [-r for r in stg.range_lin_interp], + marker="*", mfc="b", mec="b", ms=8, ls="None") + + def interpolate_Mfine_profile(self): + if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): print("test find indice of time ", np.where( np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :] @@ -336,7 +491,7 @@ class SedimentCalibrationTab(QWidget): print(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :]) print(stg.time_fine[stg.fine_sample_profile[-1][1]]) - range_lin_interp, M_profile_fine = ( + stg.range_lin_interp, stg.M_profile_fine = ( self.inv_hc.M_profile_SCC_fine_interpolated( sample_depth=[-stg.depth_fine[k[1]] for k in stg.fine_sample_profile], M_profile=[stg.Ctot_fine[k[1]] for k in stg.fine_sample_profile], @@ -353,80 +508,58 @@ class SedimentCalibrationTab(QWidget): # print(f"range_lin_interp : {range_lin_interp}") # print(f"M_profile_fine : {M_profile_fine}") else: - range_lin_interp, M_profile_fine = ( + stg.range_lin_interp, stg.M_profile_fine = ( self.inv_hc.M_profile_SCC_fine_interpolated( sample_depth=[-stg.depth_fine[k[1]] for k in stg.fine_sample_profile], M_profile=[stg.Ctot_fine[k[1]] for k in stg.fine_sample_profile], range_cells=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :], r_bottom=stg.depth_bottom[self.combobox_acoustic_data_choice.currentIndex()])) + print(f"1 M_profile_fine : {stg.M_profile_fine}") + stg.range_lin_interp = stg.range_lin_interp.tolist() + stg.M_profile_fine = stg.M_profile_fine.tolist() + stg.M_profile_fine = stg.M_profile_fine[:len(stg.range_lin_interp)] + print(f"2 M_profile_fine : {stg.M_profile_fine}") - M_profile_fine = M_profile_fine[:len(range_lin_interp)] - print(f"M_profile_fine : {M_profile_fine}") + self.plot_profile_of_concentration_fine() - # --- Plot profile of the concentration of the fine sediments --- - self.verticalLayout_groupbox_Mfine_profile.removeWidget(self.canvas_Mfine) - self.verticalLayout_groupbox_Mfine_profile.removeWidget(self.toolbar_Mfine) - self.fig_Mfine, self.ax_Mfine = plt.subplots(1, 1, layout="constrained") - self.canvas_Mfine = FigureCanvas(self.fig_Mfine) - self.toolbar_Mfine = NavigationToolBar(self.canvas_Mfine, self) - self.verticalLayout_groupbox_Mfine_profile.addWidget(self.toolbar_Mfine) - self.verticalLayout_groupbox_Mfine_profile.addWidget(self.canvas_Mfine) - - self.ax_Mfine.plot([stg.Ctot_fine[c] for _, c in stg.fine_sample_profile], - [stg.depth_fine[c] for _, c in stg.fine_sample_profile], - marker="o", mfc="k", mec="k", ms=12, ls="None") - - self.ax_Mfine.plot(M_profile_fine[:len(range_lin_interp)], -range_lin_interp, - marker="*", mfc="b", mec="b", ms=8, ls="None") - - self.ax_Mfine.set_xlabel("Concentration fine sediments (g/L)") - self.ax_Mfine.set_ylabel("Depth (m)") - - for i in stg.fine_sample_profile: - self.ax_Mfine.text(stg.time_fine[i[1]], stg.depth_fine[i[1]] - .05, i[0], - fontstyle="normal", fontweight="light", fontsize=12) - - self.ax_Mfine.set_xlabel("Fine sediments concentration (g/L)") - self.ax_Mfine.set_ylabel("Depth (m)") - - def range_cells_function(self): - """ Computing the real cell size, that depends on the temperature """ - - # defaut Aquascat cell size - aquascat_cell_size = stg.r[0, 1] - stg.r[0, 0] - # Pulse duration - tau = aquascat_cell_size * 2 / 1500 # figure 2.9 1500 vitesse du son entrée pour le paramètrage des mesures aquascat - # Sound speed - cel = self.inv_hc.water_velocity(self.spinbox_temperature_water_attenuation.value()) - # Real cell size - real_cell_size = cel * tau / 2 # voir fig 2.9 - - # Converting to real cell profile - real_r = stg.r / aquascat_cell_size * real_cell_size # (/ aquascat_cell_size) pour ramener BS.r entre 0 et 1 - # (* real_cell_size) pour remettre les échelles spatiales sur la taille réelle des cellules - - # R with right shape (numpy array) - R_real = real_r # np.repeat(real_r, len(stg.freq), axis=1) - - return R_real + # def range_cells_function(self): + # """ Computing the real cell size, that depends on the temperature """ + # + # # defaut Aquascat cell size + # aquascat_cell_size = stg.r[0, 1] - stg.r[0, 0] + # # Pulse duration + # tau = aquascat_cell_size * 2 / 1500 # figure 2.9 1500 vitesse du son entrée pour le paramètrage des mesures aquascat + # # Sound speed + # cel = self.inv_hc.water_velocity(self.spinbox_temperature_water_attenuation.value()) + # # Real cell size + # real_cell_size = cel * tau / 2 # voir fig 2.9 + # + # # Converting to real cell profile + # real_r = stg.r / aquascat_cell_size * real_cell_size # (/ aquascat_cell_size) pour ramener BS.r entre 0 et 1 + # # (* real_cell_size) pour remettre les échelles spatiales sur la taille réelle des cellules + # + # # R with right shape (numpy array) + # R_real = real_r # np.repeat(real_r, len(stg.freq), axis=1) + # + # return R_real - def compute_FCB(self): - - print(f"self.range_cells_function() : {self.range_cells_function()}") - print(f"self.range_cells_function() shape : {self.range_cells_function().shape}") - R_real = np.repeat(self.range_cells_function()[:, :, np.newaxis], stg.t.shape[1], axis=2) - print(f"R_real shape : {R_real.shape}") - if (stg.BS_stream_bed_pre_process_average.size == 0) and (stg.BS_stream_bed_pre_process_SNR.size == 0): - stg.FCB = (np.log(stg.BS_stream_bed) + np.log(R_real) + - 2 * stg.water_attenuation * R_real) - elif stg.BS_stream_bed_pre_process_SNR.size == 0: - stg.FCB = (np.log(stg.BS_stream_bed_pre_process_average) + np.log(R_real) + - 2 * stg.water_attenuation * R_real) - else: - stg.FCB = (np.log(stg.BS_stream_bed_pre_process_SNR) + np.log(R_real) + - 2 * stg.water_attenuation * R_real) - self.plot_FCB() + # def compute_FCB(self): + # + # print(f"self.range_cells_function() : {self.range_cells_function()}") + # print(f"self.range_cells_function() shape : {self.range_cells_function().shape}") + # R_real = np.repeat(self.range_cells_function()[:, :, np.newaxis], stg.t.shape[1], axis=2) + # print(f"R_real shape : {R_real.shape}") + # if (stg.BS_stream_bed_pre_process_average.size == 0) and (stg.BS_stream_bed_pre_process_SNR.size == 0): + # stg.FCB = (np.log(stg.BS_stream_bed) + np.log(R_real) + + # 2 * stg.water_attenuation * R_real) + # elif stg.BS_stream_bed_pre_process_SNR.size == 0: + # stg.FCB = (np.log(stg.BS_stream_bed_pre_process_average) + np.log(R_real) + + # 2 * stg.water_attenuation * R_real) + # else: + # stg.FCB = (np.log(stg.BS_stream_bed_pre_process_SNR) + np.log(R_real) + + # 2 * stg.water_attenuation * R_real) + # self.plot_FCB() # def fit_FCB_profile_with_linear_regression_and_compute_alphaS(self): # @@ -493,65 +626,262 @@ class SedimentCalibrationTab(QWidget): # # print("lin_reg length ", len(stg.lin_reg)) # # print("lin_reg ", stg.lin_reg) + # ------------------------------------------------------------------ + # --------------- Functions for sediment calibration --------------- + # ------------------------------------------------------------------ + def function_pushbutton_compute_calibration(self): + # --- Compute frequency --- + self.label_freq1.clear() + self.label_freq1.setText(str(self.combobox_freq1.currentText())) - # print([stg.time_fine[c] for _, c in stg.fine_sample_profile]) - # print([stg.depth_fine[c] for _, c in stg.fine_sample_profile]) + self.label_freq2.clear() + self.label_freq2.setText(str(self.combobox_freq2.currentText())) - # --- Plot positions of the samples selected in comboboxes --- - # self.scat.set_array(np.array([[stg.time_fine[c] for _, c in stg.fine_sample_profile], - # [stg.depth_fine[c] for _, c in stg.fine_sample_profile]]).transpose()) - # self.scat.set_array(np.array([[stg.time_fine[c] for _, c in stg.fine_sample_profile], - # [stg.depth_fine[c] for _, c in stg.fine_sample_profile]]).transpose()) + # --- Compute ks --- + psd_number_of_particles = ( + self.inv_hc.compute_particle_size_distribution_in_number_of_particles( + num_sample=stg.sand_sample_target[0][1], r_grain=stg.radius_grain_sand, + frac_vol_cumul=stg.frac_vol_sand_cumul)) - # self.gridLayout_groupbox_data_choice = QGridLayout(self.groupbox_acoustic_data_choice) - # - # self.gridLayout_groupbox_data_choice.addWidget(self.combobox_acoustic_data_choice, 0, 0, 1, 4) - # self.combobox_acoustic_data_choice.addItems(["acoustic data 1", "acoustic data 2", "acoustic data 3"]) - # - # self.label_temperature = QLabel("Temperature = ") - # self.gridLayout_groupbox_data_choice.addWidget(self.label_temperature, 1, 0, 1, 1) - # - # self.label_temperature_value = QLabel("7 °C") - # self.gridLayout_groupbox_data_choice.addWidget(self.label_temperature_value, 1, 1, 1, 1) - # - # self.label_sound_velocity = QLabel("Sound velocity (m/s) = ") - # self.gridLayout_groupbox_data_choice.addWidget(self.label_sound_velocity, 1, 2, 1, 1) - # - # self.spinbox_sound_velocity_value = QSpinBox() - # self.gridLayout_groupbox_data_choice.addWidget(self.spinbox_sound_velocity_value, 1, 3, 1, 1) - # - # self.label_freq1 = QLabel("freq 1:") - # self.gridLayout_groupbox_data_choice.addWidget(self.label_freq1, 2, 0, 1, 1) - # self.combobox_freq1 = QComboBox() - # self.combobox_freq1.addItems(["0.3 MHz", "0.5 MHz", "1 MHz", "5 MHz"]) - # self.gridLayout_groupbox_data_choice.addWidget(self.combobox_freq1, 2, 1, 1, 1) - # - # self.label_freq2 = QLabel("freq 2:") - # self.gridLayout_groupbox_data_choice.addWidget(self.label_freq2, 2, 2, 1, 1) - # self.combobox_freq2 = QComboBox() - # self.combobox_freq2.addItems(["0.3 MHz", "0.5 MHz", "1 MHz", "5 MHz"]) - # self.gridLayout_groupbox_data_choice.addWidget(self.combobox_freq2, 2, 3, 1, 1) - # - # self.label_kt = QLabel("kt = :") - # self.gridLayout_groupbox_data_choice.addWidget(self.label_kt, 3, 0, 1, 1) - # - # self.spinbox_kt_freq1 = QDoubleSpinBox() - # self.spinbox_kt_freq1.setDecimals(5) - # self.gridLayout_groupbox_data_choice.addWidget(self.spinbox_kt_freq1, 3, 1, 1, 1) - # - # self.spinbox_kt_freq2 = QDoubleSpinBox() - # self.spinbox_kt_freq2.setDecimals(5) - # self.gridLayout_groupbox_data_choice.addWidget(self.spinbox_kt_freq2, 3, 3, 1, 1) - # - # self.groupbox_acoustic_data_plot = QGroupBox() - # self.verticalLayout_groupbox_acoustic_data_plot = QVBoxLayout(self.groupbox_acoustic_data_plot) - # self.gridLayout_groupbox_data_choice.addWidget(self.groupbox_acoustic_data_plot, 4, 0, 1, 4) - # - # self.fig_acoustic, self.ax_acoustic = plt.subplots(nrows=1, ncols=1, layout="constrained") - # self.canvas_fig_acoustic = FigureCanvas(self.fig_acoustic) - # self.verticalLayout_groupbox_acoustic_data_plot.addWidget(self.canvas_fig_acoustic) + ks_freq1 = self.inv_hc.ks(proba_num=psd_number_of_particles, + freq=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()], + C=stg.water_velocity[self.combobox_acoustic_data_choice.currentIndex()]) + ks_freq2 = self.inv_hc.ks(proba_num=psd_number_of_particles, + freq=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()], + C=stg.water_velocity[self.combobox_acoustic_data_choice.currentIndex()]) + print("\n************************************************************** \n") + print(f"ks for frequency of {stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex()]} : {ks_freq1} m/kg^0.5 \n") + print(f"ks for frequency of {stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()]} : {ks_freq2} m/kg^0.5") + self.spinbox_ks_freq1.clear() + self.spinbox_ks_freq1.setValue(ks_freq1) + + self.spinbox_ks_freq2.clear() + self.spinbox_ks_freq2.setValue(ks_freq2) + + # --- Compute sv --- + sv_freq1 = self.inv_hc.sv(ks=ks_freq1, M_sand=stg.Ctot_sand[stg.sand_sample_target[0][1]]) + sv_freq2 = self.inv_hc.sv(ks=ks_freq2, M_sand=stg.Ctot_sand[stg.sand_sample_target[0][1]]) + + print(f"sv for frequency of {stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex()]} : {sv_freq1:.8f} /m \n") + print(f"sv for frequency of {stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()]} : {sv_freq2:.8f} /m") + + self.spinbox_sv_freq1.clear() + self.spinbox_sv_freq1.setValue(sv_freq1) + + self.spinbox_sv_freq2.clear() + self.spinbox_sv_freq2.setValue(sv_freq2) + + # --- Compute exponent X --- + X_exponent = self.inv_hc.X_exponent(freq1=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex()], + freq2=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()], + sv_freq1=sv_freq1, sv_freq2=sv_freq2) + + print(f"Exponent X = {X_exponent:.2f}\n") + + self.spinbox_X.clear() + self.spinbox_X.setValue(X_exponent) + + # --- Compute J --- + if stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): + + depth_2D = np.zeros(stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape) + for f, _ in enumerate(stg.freq[self.combobox_acoustic_data_choice.currentIndex()]): + depth_2D[f, :, :] = np.repeat(np.transpose(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()] + [self.combobox_freq1.currentIndex()])[:, np.newaxis], + stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + + print("kt cor ", stg.kt_corrected) + print("kt read", stg.kt_read) + + if (stg.kt_corrected[self.combobox_acoustic_data_choice.currentIndex()] != + stg.kt_read[self.combobox_acoustic_data_choice.currentIndex()]): + kt2D = np.repeat(np.array([stg.kt_corrected[self.combobox_acoustic_data_choice.currentIndex()]]).transpose(), + stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + kt3D = np.repeat(kt2D[:, np.newaxis, :], + stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], axis=1) + else: + kt2D = np.repeat(np.array([stg.kt_read[self.combobox_acoustic_data_choice.currentIndex()]]).transpose(), + stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + print(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape) + print("kt2D shape ", kt2D.shape) + print("kt2D ", kt2D) + kt3D = np.repeat(kt2D[:, np.newaxis, :], + stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], axis=1) + print("kt3D shape ", kt3D.shape) + print("kt3D ", kt3D) + + J_cross_section_freq1 = self.inv_hc.j_cross_section( + BS=stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex(), :, :], + r2D=depth_2D[self.combobox_freq1.currentIndex(), :, :], + kt=kt3D[self.combobox_freq1.currentIndex(), :, :]) + + J_cross_section_freq2 = self.inv_hc.j_cross_section( + BS=stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex(), :, :], + r2D=depth_2D[self.combobox_freq2.currentIndex(), :, :], + kt=kt3D[self.combobox_freq2.currentIndex(), :, :]) + + elif stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): + + depth_2D = np.zeros(stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape) + for f, _ in enumerate(stg.freq[self.combobox_acoustic_data_choice.currentIndex()]): + depth_2D[f, :, :] = np.repeat( + np.transpose(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()] + [self.combobox_freq1.currentIndex()])[:, np.newaxis], + stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + + if stg.kt_corrected[self.combobox_acoustic_data_choice.currentIndex()]: + kt2D = np.repeat(np.array(stg.kt_corrected[self.combobox_acoustic_data_choice.currentIndex()]), + stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + kt3D = np.repeat(kt2D[:, :, np.newaxis], + stg.freq[self.combobox_acoustic_data_choice.currentIndex()].shape[0], axis=2) + else: + kt2D = np.repeat(np.array(stg.kt_read[self.combobox_acoustic_data_choice.currentIndex()]), + stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + kt3D = np.repeat(kt2D[:, :, np.newaxis], + stg.freq[self.combobox_acoustic_data_choice.currentIndex()].shape[0], axis=2) + + J_cross_section_freq1 = self.inv_hc.j_cross_section( + BS=stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex(), :, :], + r2D=depth_2D[self.combobox_freq1.currentIndex(), :, :], + kt=kt3D[self.combobox_freq1.currentIndex(), :, :]) + + J_cross_section_freq2 = self.inv_hc.j_cross_section( + BS=stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex(), :, :], + r2D=depth_2D[self.combobox_freq2.currentIndex(), :, :], + kt=kt3D[self.combobox_freq2.currentIndex(), :, :]) + + else: + + depth_2D = np.zeros(stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()].shape) + for f, _ in enumerate(stg.freq[self.combobox_acoustic_data_choice.currentIndex()]): + depth_2D[f, :, :] = np.repeat( + np.transpose(stg.depth[self.combobox_acoustic_data_choice.currentIndex()] + [self.combobox_freq1.currentIndex()])[:, np.newaxis], + stg.time[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + + if stg.kt_corrected[self.combobox_acoustic_data_choice.currentIndex()]: + kt2D = np.repeat(np.array(stg.kt_corrected[self.combobox_acoustic_data_choice.currentIndex()]), + stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + kt3D = np.repeat(kt2D[:, :, np.newaxis], + stg.freq[self.combobox_acoustic_data_choice.currentIndex()].shape[0], axis=2) + else: + kt2D = np.repeat(np.array(stg.kt_read[self.combobox_acoustic_data_choice.currentIndex()]), + stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1], + axis=1) + kt3D = np.repeat(kt2D[:, :, np.newaxis], + stg.freq[self.combobox_acoustic_data_choice.currentIndex()].shape[0], axis=2) + + J_cross_section_freq1 = self.inv_hc.j_cross_section( + BS=stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex(), :, :], + r2D=depth_2D[self.combobox_freq1.currentIndex(), :, :], + kt=kt3D[self.combobox_freq1.currentIndex(), :, :]) + + J_cross_section_freq2 = self.inv_hc.j_cross_section( + BS=stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex(), :, :], + r2D=depth_2D[self.combobox_freq2.currentIndex(), :, :], + kt=kt3D[self.combobox_freq2.currentIndex(), :, :]) + + print("J_cross_section_freq1.shape ", J_cross_section_freq1.shape) + print("J_cross_section_freq2.shape ", J_cross_section_freq2.shape) + + # --- Compute alpha_s --- + if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): + + alpha_s_freq1 = self.inv_hc.alpha_s( + sv=sv_freq1, + j_cross_section=J_cross_section_freq1[stg.sand_sample_target_indice[0][0], + stg.sand_sample_target_indice[0][1]], + depth=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex(), stg.sand_sample_target_indice[0][0]], + alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()]) + + alpha_s_freq2 = self.inv_hc.alpha_s( + sv=sv_freq2, + j_cross_section=J_cross_section_freq2[stg.sand_sample_target_indice[1][0], + stg.sand_sample_target_indice[1][1]], + depth=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[1][0]], + alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()]) + + else: + + alpha_s_freq1 = self.inv_hc.alpha_s( + sv=sv_freq1, + j_cross_section=J_cross_section_freq1[stg.sand_sample_target_indice[0][0], + stg.sand_sample_target_indice[0][1]], + depth=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex(), stg.sand_sample_target_indice[0][0]], + alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex()]) + + alpha_s_freq2 = self.inv_hc.alpha_s( + sv=sv_freq2, + j_cross_section=J_cross_section_freq2[stg.sand_sample_target_indice[1][0], + stg.sand_sample_target_indice[1][1]], + depth=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[1][0]], + alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex()]) + + print(f"\u03B1s for frequency of freq1 : {alpha_s_freq1:.2f} /m \n") + print(f"\u03B1s for frequency of freq2 : {alpha_s_freq2:.2f} /m") + + self.spinbox_alphas_freq1.clear() + self.spinbox_alphas_freq1.setValue(alpha_s_freq1) + + self.spinbox_alphas_freq2.clear() + self.spinbox_alphas_freq2.setValue(alpha_s_freq2) + + # --- Compute zeta --- + + if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): + + zeta_freq1 = self.inv_hc.zeta(alpha_s=alpha_s_freq1, + r=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex(), :], + M_profile_fine=stg.M_profile_fine) + zeta_freq2 = self.inv_hc.zeta(alpha_s=alpha_s_freq2, + r=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex(), :], + M_profile_fine=stg.M_profile_fine) + + else: + zeta_freq1 = self.inv_hc.zeta(alpha_s=alpha_s_freq1, + r=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq1.currentIndex(), :], + M_profile_fine=stg.M_profile_fine) + zeta_freq2 = self.inv_hc.zeta(alpha_s=alpha_s_freq2, + r=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][ + self.combobox_freq2.currentIndex(), :], + M_profile_fine=stg.M_profile_fine) + + print(f"\u03B6 for frequency of freq1 : {zeta_freq1:.3f} /m \n") + print(f"\u03B6 for frequency of freq2 : {zeta_freq2:.3f} /m") + + self.spinbox_zeta_freq1.clear() + self.spinbox_zeta_freq1.setValue(zeta_freq1) + + self.spinbox_zeta_freq2.clear() + self.spinbox_zeta_freq2.setValue(zeta_freq2) diff --git a/settings.py b/settings.py index ff67fc6..3d6f03e 100644 --- a/settings.py +++ b/settings.py @@ -148,10 +148,14 @@ frac_vol_sand = [] # Volume fraction (%) frac_vol_sand_cumul = [] # Cumulated volume fraction (%) sand_sample_target = [] # Sand sample target for calibration +sand_sample_target_indice = [] Ctot_fine_per_cent = [] Ctot_sand_per_cent = [] +range_lin_interp = [] +M_profile_fine = [] + # --- Acoustic inversion method --- temperature = []