diff --git a/Model/GrainSizeTools.py b/Model/GrainSizeTools.py index 0783f82..ca69b42 100644 --- a/Model/GrainSizeTools.py +++ b/Model/GrainSizeTools.py @@ -155,15 +155,33 @@ class demodul_granulo: self.cumul_interpolated = f_logsize(self.sizes_log_resampled) # Computing volume and number probability from interpolated data - self.resampled_proba_vol = np.diff(self.cumul_interpolated) + self.resampled_proba_vol = np.abs(np.diff(self.cumul_interpolated)) # np.abs is added because probability p + # must be positive in np.random.choice + # used in function below "demodulate" # Computing number probability, ss = np.sum(self.resampled_proba_vol /(np.exp(self.sizes_log_resampled[:-1]))**3) self.resampled_proba_num = (self.resampled_proba_vol / (np.exp(self.sizes_log_resampled[:-1]))**3) / ss - + + # fig, ax = plt.subplots(1, 2) + # ax[0].plot(list(range(len(self.cumul_interpolated))), self.cumul_interpolated) + # ax[0].set_xlabel("n° point") + # ax[0].set_ylabel("cumul interpolated") + # + # ax[1].plot(list(range(len(self.cumul_interpolated)-1)), self.resampled_proba_vol) + # ax[1].set_xlabel("n° point") + # ax[1].set_ylabel("diff cumul interpolated") + # + # plt.show() def demodulate(self): """This function demodulates the interpolated probability distribution""" # Sampling the size classes. Need to normalize the probability to get sum = 1.0 + # print("**************************") + # for i in range(self.resampled_proba_vol.shape[0]): + # print(f"vol = {self.resampled_proba_vol[i]}, sum = {np.sum(self.resampled_proba_vol)}, " + # f" p = {self.resampled_proba_vol[i] / np.sum(self.resampled_proba_vol)}") + # print("**************************") + ech_demod = np.random.choice(self.sizes_log_resampled[:-1], (10000,1), p=(self.resampled_proba_vol / np.sum(self.resampled_proba_vol))) # fitting models from 1 to 10 components @@ -182,7 +200,7 @@ class demodul_granulo: def plot_interpolation(self): """This method plots the cumulative probability interpolation""" # ------- Plotting interpolation----------- # - fig,(ax)=plt.subplots(1, 2, figsize = (11,4), dpi=100) + fig, ax = plt.subplots(1, 2, figsize = (11,4), dpi=100) # Data ax[0].plot(np.log(self.size_classes), self.proba_cumul_vol, linestyle='', marker='+') diff --git a/Model/acoustic_data_loader.py b/Model/acoustic_data_loader.py index 4decd2a..91d52ef 100644 --- a/Model/acoustic_data_loader.py +++ b/Model/acoustic_data_loader.py @@ -7,7 +7,7 @@ from matplotlib.colors import LogNorm # path_BS_raw_data = "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/" \ # "Data/Acoustic_data/20180107123500.aqa" -# path_noise_data = "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/" \ +# path_BS_raw_data = "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/" \ # "Data/AcousticNoise_data/20180107121600.aqa" @@ -15,7 +15,7 @@ class AcousticDataLoader: 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 # --- Load Backscatter acoustic raw data with RawAquascatData class --- @@ -65,11 +65,13 @@ class AcousticDataLoader: # 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[0]), self._BS_raw_data[:, 1, :], cmap='viridis', + # # 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 --- diff --git a/Model/acoustic_data_loader_UBSediFlow.py b/Model/acoustic_data_loader_UBSediFlow.py index b5c3487..78ee24e 100644 --- a/Model/acoustic_data_loader_UBSediFlow.py +++ b/Model/acoustic_data_loader_UBSediFlow.py @@ -30,7 +30,10 @@ from Model.udt_extract.raw_extract import raw_extract # "Rhone_20210519/Rhone_20210519/record/") # path_BS_raw_data0 = ("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Raw_data_udt/") -# filename0 = "raw_20210519_130000.udt" +# filename0 = "raw_20210519_130643.udt" + +# path_BS_raw_data0 = ("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Raw_data_udt/") +# filename0 = "raw_20210520_085958.udt" # filename = "raw_20210519_115128.udt" # "raw_20210526_153310.udt" @@ -177,12 +180,15 @@ class AcousticDataLoaderUBSediFlow: if config == 1: BS_data = np.array([data_us_dicts[config][channel]['echo_avg_profile']['data'][0]]) # print("BS_data shape ", BS_data.shape) - print("******************************") - date_list = [np.abs(datetime.datetime(2021, 5, 19, 13, 10, 00).timestamp() - - date.timestamp()) for date in data_us_dicts[config][channel]['echo_avg_profile']['time']] - print(np.where(date_list == np.min(date_list))) - # == datetime.datetime(2021, 5, 19, 14, 10, 2, 644000)) - print("******************************") + # print("******************************") + # date_list = [np.abs(datetime.datetime(2021, 5, 19, 14, 10, 00).timestamp() + # - date.timestamp()) for date in data_us_dicts[config][channel]['echo_avg_profile']['time']] + # print(date_list) + # print(np.where(date_list == np.min(date_list))) + # print((data_us_dicts[config][channel]['echo_avg_profile']['time'][np.where(date_list == np.min(date_list))[0][0]] - + # data_us_dicts[config][channel]['echo_avg_profile']['time'][0]).total_seconds()) + # # == datetime.datetime(2021, 5, 19, 14, 10, 2, 644000)) + # print("******************************") for i in range(self._time.shape[1]): BS_data = np.append(BS_data, @@ -282,6 +288,11 @@ class AcousticDataLoaderUBSediFlow: self._time = self._time[:, :self._BS_raw_data.shape[2]] print("self._time.shape ", self._time.shape) + # print(f"time : {self._time}") + # print("****************************") + # for i in range(len(self._time[0, :])-1): + # print(self._time[0, i+1] - self._time[0, i]) + # print("****************************") print("self._r.shape ", self._r.shape) @@ -345,7 +356,7 @@ class AcousticDataLoaderUBSediFlow: # --- Plot Backscatter US data --- # fig, ax = plt.subplots(nrows=1, ncols=1, layout="constrained") - # pcm = ax.pcolormesh(self._time[0, :], -self._r[0, 2:], np.log(self._BS_raw_data[0, 2:, :]), + # pcm = ax.pcolormesh(self._time[0, :], -self._r[0, :], np.log(self._BS_raw_data[0, :, :]), # cmap='plasma')#, shading='gouraud') # # pcm = ax.pcolormesh(list(range(self._BS_raw_data.shape[2])), list(range(self._BS_raw_data.shape[1])), # # np.log(self._BS_raw_data[0, :, :]), diff --git a/Model/acoustic_inversion_method_high_concentration.py b/Model/acoustic_inversion_method_high_concentration.py index cefb418..94d1836 100644 --- a/Model/acoustic_inversion_method_high_concentration.py +++ b/Model/acoustic_inversion_method_high_concentration.py @@ -83,10 +83,10 @@ class AcousticInversionMethodHighConcentration(): 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))) / ( 42 + 28 * x ** 2) - print(f"form factor = {f}") + # print(f"form factor = {f}") return f - def ks(self, freq, pdf): + def ks(self, num_sample, freq, pdf): # --- Calcul de la fonction de form --- # form_factor = self.form_factor_function_MoateThorne2012(a, freq) # print(f"form_factor shape = {form_factor}") @@ -95,7 +95,7 @@ class AcousticInversionMethodHighConcentration(): #--- Particle size distribution --- proba_num = ( self.compute_particle_size_distribution_in_number_of_particles( - num_sample=2, r_grain=stg.radius_grain, frac_vol_cumul=stg.frac_vol_sand_cumul)) + num_sample=num_sample, r_grain=stg.radius_grain, frac_vol_cumul=stg.frac_vol_sand_cumul)) print(f"proba_num : {proba_num}") @@ -228,9 +228,13 @@ class AcousticInversionMethodHighConcentration(): # 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 @@ -247,20 +251,24 @@ class AcousticInversionMethodHighConcentration(): if stg.r_bottom.size != 0: res[np.where(range_cells > r_bottom)] = np.nan - # print(f"res.shape = {res.shape}") + # print(f"2. res.shape = {res.shape}") # print(f"res = {res}") 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)], c="blue") - # ax.plot(sample_depth, M_profile, color="k", marker="o") - # plt.show() + 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) @@ -270,6 +278,7 @@ class AcousticInversionMethodHighConcentration(): delta_r = r[1] - r[0] zeta = alpha_s / (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]) @@ -335,6 +344,9 @@ class AcousticInversionMethodHighConcentration(): (freq2 ** X))) / (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)) - @@ -348,8 +360,8 @@ class AcousticInversionMethodHighConcentration(): return np.exp(logVBI) # ------------- Computing SSC fine ------------- # - def SSC_fine(self, zeta, r2D, VBI, freq, X, j_cross_section): - SSC_fine = (1/zeta) * ( 1/(4 * r2D) * np.log((VBI * freq**X) / j_cross_section) ) + 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) print("compute SSC fine finished") return SSC_fine diff --git a/Model/granulo_loader.py b/Model/granulo_loader.py index c67b4ca..442c494 100644 --- a/Model/granulo_loader.py +++ b/Model/granulo_loader.py @@ -42,9 +42,8 @@ class GranuloLoader: # ============================================================================================================== # ============================================================================================================== -# print(self._r_grain.shape) -# N_sample = 2 -# +# N_sample = 0 +# # # fig, ax = plt.subplots(1, 2) # ax[0].plot(self._r_grain, self._frac_vol[N_sample, :], color="k", marker='.') # ax[0].set_xscale('log') @@ -57,17 +56,20 @@ class GranuloLoader: # # plt.show() # +# print(f"self._r_grain.shape : {self._r_grain.shape}") # print(f"self._r_grain : {self._r_grain}") +# print(f"self._frac_vol_cumul.shape : {self._frac_vol_cumul[N_sample, :].shape}") # print(f"self._frac_vol_cumul[N_sample, :] : {self._frac_vol_cumul[N_sample, :]}") -# +# print(np.where(self._frac_vol_cumul[N_sample, :] > 0)) +# # # min_demodul = 1e-6 # max_demodul = 500e-6 -# sample_demodul = demodul_granulo(self._r_grain, +# sample_demodul = demodul_granulo(self._r_grain[:], # self._frac_vol_cumul[N_sample, :], # min_demodul, max_demodul) # # print(f"sample_demodul : {sample_demodul.demodul_data_list}") -# + # N_modes = 3 # sample_demodul.print_mode_data(N_modes) # sample_demodul.plot_interpolation() @@ -120,10 +122,14 @@ class GranuloLoader: # if __name__ == "__main__": -# # GranuloLoader("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Granulo_data/" -# # "fine_sample_file.ods") -# GranuloLoader("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Granulo_data/" -# "sand_sample_file.ods") + # GranuloLoader("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Granulo_data/" + # "fine_sample_file.ods") + # GranuloLoader("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Granulo_data/" + # "sand_sample_file.ods") + # GranuloLoader("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/" + # "pt_acoused_cnr_7nov2023/echantil/fine_new_file_acoused_101RDS 3.ods") + # GranuloLoader("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/" + # "pt_acoused_cnr_7nov2023/echantil/sand_new_file_acoused_101RDS 3.ods") diff --git a/View/acoustic_inversion_tab.py b/View/acoustic_inversion_tab.py index 3305ac5..8585970 100644 --- a/View/acoustic_inversion_tab.py +++ b/View/acoustic_inversion_tab.py @@ -1,7 +1,7 @@ import sys from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication, QVBoxLayout, QHBoxLayout, QGroupBox, QComboBox, \ - QGridLayout, QLabel, QPushButton, QSpinBox + QGridLayout, QLabel, QPushButton, QSpinBox, QDoubleSpinBox from PyQt5.QtCore import QCoreApplication, Qt from PyQt5.QtGui import QStandardItemModel @@ -15,6 +15,10 @@ from matplotlib.colors import LogNorm, BoundaryNorm, CSS4_COLORS from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar +import datetime + +from scipy import stats + import Translation.constant_string as cs from View.checkable_combobox import CheckableComboBox @@ -88,14 +92,52 @@ class AcousticInversionTab(QWidget): self.combobox_acoustic_inversion_method_choice.addItems([" ", "Acoustic inversion method 1"]) self.combobox_acoustic_inversion_method_choice.currentIndexChanged.connect( self.acoustic_inversion_method_choice) + # self.combobox_acoustic_inversion_method_choice.currentIndexChanged.connect( + # self.plot_transect_with_sample_position) - self.label_sample_choice = QLabel() - self.gridLayout_groupbox_acoustic_inversion_options.addWidget(self.label_sample_choice, 1, 0, 1, 1) - self.label_sample_choice.setText("Calibration samples : ") + self.groupbox_calibration_samples = QGroupBox() + self.groupbox_calibration_samples.setTitle("Sample choice for calibration") + self.gridLayout_groupbox_acoustic_inversion_options.addWidget(self.groupbox_calibration_samples, 1, 0, 1, 2) - self.combobox_calibration_samples = QComboBox() - self.gridLayout_groupbox_acoustic_inversion_options.addWidget(self.combobox_calibration_samples, 1, 1, 1, 1) - self.combobox_calibration_samples.currentIndexChanged.connect(self.sample_choice) + self.gridLayout_groupbox_calibration_samples = QGridLayout(self.groupbox_calibration_samples) + + self.label_frequency = QLabel() + self.label_frequency.setText("Frequency :") + self.gridLayout_groupbox_calibration_samples.addWidget(self.label_frequency, 0, 0, 1, 1) + + self.combobox_frequency = QComboBox() + self.gridLayout_groupbox_calibration_samples.addWidget(self.combobox_frequency, 0, 1, 1, 1) + self.combobox_frequency.currentIndexChanged.connect(self.update_plot_transect_with_sample_position) + + self.label_sand_sample_choice = QLabel() + self.label_sand_sample_choice.setText("Sand sediments :") + self.gridLayout_groupbox_calibration_samples.addWidget(self.label_sand_sample_choice, 0, 2, 1, 1) + + self.combobox_calibration_sand_sample = CheckableComboBox() + self.gridLayout_groupbox_calibration_samples.addWidget(self.combobox_calibration_sand_sample, 0, 3, 1, 1) + # self.combobox_calibration_sand_sample.currentData.connect(self.update_plot_transect_with_sample_position) + self.combobox_calibration_sand_sample.currentIndexChanged.connect( + self.update_plot_transect_with_sample_position) + # self.combobox_calibration_sand_sample.currentIndexChanged.connect(self.sample_choice) + + self.label_fine_sample_choice = QLabel() + self.label_fine_sample_choice.setText("Fine sediments :") + self.gridLayout_groupbox_calibration_samples.addWidget(self.label_fine_sample_choice, 0, 4, 1, 1) + + self.combobox_calibration_fine_sample = CheckableComboBox() + self.gridLayout_groupbox_calibration_samples.addWidget(self.combobox_calibration_fine_sample, 0, 5, 1, 1) + # self.combobox_calibration_fine_sample.currentData.connect(self.update_plot_transect_with_sample_position) + self.combobox_calibration_fine_sample.currentIndexChanged.connect( + self.update_plot_transect_with_sample_position) + + # self.combobox_calibration_fine_sample.currentIndexChanged.connect(self.sample_choice) + + self.groupbox_plot_sample_position_on_transect = QGroupBox() + self.gridLayout_groupbox_calibration_samples.addWidget(self.groupbox_plot_sample_position_on_transect, 1, 0, 1, 6) + self.verticalLayout_groupbox_plot_sample_position_on_transect = QVBoxLayout(self.groupbox_plot_sample_position_on_transect) + + self.canvas_plot_sample_position_on_transect = None + # self.verticalLayout_groupbox_plot_sample_position_on_transect.addWidget(self.canvas_plot_sample_position_on_transect) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -107,41 +149,111 @@ class AcousticInversionTab(QWidget): self.groupbox_acoustic_inversion_settings_parameter.setTitle("Acoustic inversion method settings parameter") + self.groupbox_parameter = QGroupBox() + self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.groupbox_parameter, 0, 0, 1, 2) + + self.gridLayout_groupbox_parameter = QGridLayout(self.groupbox_parameter) + self.label_temperature = QLabel() self.label_temperature.setText("Temperature : ") - self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.label_temperature, 0, 0, 1, 1) - self.spinbox_temperature = QSpinBox() - self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.spinbox_temperature, 0, 1, 1, 1) + # self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.label_temperature, 0, 0, 1, 1) + self.gridLayout_groupbox_parameter.addWidget(self.label_temperature, 0, 0, 1, 1) + self.spinbox_temperature = QDoubleSpinBox() + # self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.spinbox_temperature, 0, 1, 1, 1) + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_temperature, 0, 1, 1, 1) self.spinbox_temperature.valueChanged.connect(self.temperature_value) self.label_frequencies_pairs_to_compute_VBI = QLabel() - self.label_frequencies_pairs_to_compute_VBI.setText("frequencies for VBI : ") - self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget( - self.label_frequencies_pairs_to_compute_VBI, 1, 0, 1, 1) + self.label_frequencies_pairs_to_compute_VBI.setText("Frequencies for VBI") + self.gridLayout_groupbox_parameter.addWidget( + self.label_frequencies_pairs_to_compute_VBI, 1, 1, 1, 1) - self.combobox_frequencies_VBI = QComboBox() - self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget( - self.combobox_frequencies_VBI, 1, 1, 1, 1) - self.combobox_frequencies_VBI.currentIndexChanged.connect(self.frequencies_pair_choice_to_compute_VBI) + # self.combobox_frequencies_VBI = QComboBox() + # self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget( + # self.combobox_frequencies_VBI, 1, 1, 1, 1) + # self.combobox_frequencies_VBI.currentIndexChanged.connect(self.frequencies_pair_choice_to_compute_VBI) - self.label_frequency_to_compute_SSC = QLabel() - self.label_frequency_to_compute_SSC.setText("frequencies for SSC : ") - self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget( - self.label_frequency_to_compute_SSC, 2, 0, 1, 1) + self.label_ks = QLabel() + self.label_ks.setText("ks") + self.gridLayout_groupbox_parameter.addWidget(self.label_ks, 1, 2, 1, 1) - self.combobox_frequency_SSC = QComboBox() - self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget( - self.combobox_frequency_SSC, 2, 1, 1, 1) - self.combobox_frequency_SSC.currentIndexChanged.connect(self.frequency_choice_to_compute_SSC) + self.label_sv = QLabel() + self.label_sv.setText("sv") + self.gridLayout_groupbox_parameter.addWidget(self.label_sv, 1, 3, 1, 1) + + self.label_X = QLabel() + self.label_X.setText("X") + self.gridLayout_groupbox_parameter.addWidget(self.label_X, 1, 4, 1, 1) + + self.label_alphas = QLabel() + self.label_alphas.setText("\u03B1s") + self.gridLayout_groupbox_parameter.addWidget(self.label_alphas, 1, 5, 1, 1) + + self.label_zeta = QLabel() + self.label_zeta.setText("\u03B6") + self.gridLayout_groupbox_parameter.addWidget(self.label_zeta, 1, 6, 1, 1) + + self.label_freq1 = QLabel() + self.label_freq1.setText("Frequency 1 : ") + self.gridLayout_groupbox_parameter.addWidget(self.label_freq1, 2, 0, 1, 1) + + self.label_freq2 = QLabel() + self.label_freq2.setText("Frequency 2 : ") + self.gridLayout_groupbox_parameter.addWidget(self.label_freq2, 3, 0, 1, 1) + + self.combobox_freq1 = QComboBox() + self.gridLayout_groupbox_parameter.addWidget(self.combobox_freq1, 2, 1, 1, 1) + + self.combobox_freq2 = QComboBox() + self.gridLayout_groupbox_parameter.addWidget(self.combobox_freq2, 3, 1, 1, 1) + + self.spinbox_ks_freq1 = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_ks_freq1, 2, 2, 1, 1) + + self.spinbox_ks_freq2 = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_ks_freq2, 3, 2, 1, 1) + + self.spinbox_sv_freq1 = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_sv_freq1, 2, 3, 1, 1) + + self.spinbox_sv_freq2 = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_sv_freq2, 3, 3, 1, 1) + + self.spinbox_X = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_X, 2, 4, 1, 1) + + self.spinbox_alphas_freq1 = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_alphas_freq1, 2, 5, 1, 1) + + self.spinbox_alphas_freq2 = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_alphas_freq2, 3, 5, 1, 1) + + self.spinbox_zeta_freq1 = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_zeta_freq1, 2, 6, 1, 1) + + self.spinbox_zeta_freq2 = QDoubleSpinBox() + self.gridLayout_groupbox_parameter.addWidget(self.spinbox_zeta_freq2, 3, 6, 1, 1) + + # self.label_frequency_to_compute_SSC = QLabel() + # self.label_frequency_to_compute_SSC.setText("frequencies for SSC : ") + # # self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget( + # # self.label_frequency_to_compute_SSC, 2, 0, 1, 1) + # self.gridLayout_groupbox_parameter.addWidget(self.label_frequency_to_compute_SSC, 3, 0, 1, 1) + + # self.combobox_frequency_SSC = QComboBox() + # # self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget( + # # self.combobox_frequency_SSC, 2, 1, 1, 1) + # self.gridLayout_groupbox_parameter.addWidget(self.combobox_frequency_SSC, 3, 1, 1, 1) + # self.combobox_frequency_SSC.currentIndexChanged.connect(self.frequency_choice_to_compute_SSC) self.pushbutton_run = QPushButton() self.pushbutton_run.setText("RUN") - self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.pushbutton_run, 3, 0, 1, 1) + self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.pushbutton_run, 1, 0, 1, 1) self.pushbutton_run.clicked.connect(self.compute_acoustic_inversion_method_high_concentration) self.pushbutton_plot = QPushButton() self.pushbutton_plot.setText("PLOT") - self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.pushbutton_plot, 3, 1, 1, 1) + self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.pushbutton_plot, 1, 1, 1, 1) self.pushbutton_plot.clicked.connect(self.plot_SSC_2D_fields) self.pushbutton_plot.clicked.connect(self.plot_SSC_inverse_VS_measured) @@ -217,37 +329,197 @@ class AcousticInversionTab(QWidget): def acoustic_inversion_method_choice(self): if self.combobox_acoustic_inversion_method_choice.currentIndex() == 1: - # --- add items in combobox of samples to calibrate acoustic inversion method --- - samples_vertical_line = np.split(stg.samples, np.where(np.diff(stg.sample_time) != 0)[0]+1) + self.plot_transect_with_sample_position() + + # --- add items in combobox of samples (sand and vertical fine) to calibrate acoustic inversion method --- + + # samples_vertical_line = np.split(stg.samples, np.where(np.diff(stg.sample_time) != 0)[0]+1) + + # self.combobox_calibration_sand_sample.addItem(" ") + # for s in samples_vertical_line: + # self.combobox_calibration_sand_sample.addItem(" - ".join([i for i in s])) + + self.combobox_frequency.addItems(stg.freq_text) + + self.combobox_calibration_sand_sample.addItems(stg.samples) + # self.combobox_calibration_sand_sample.currentData.connect(self.update_plot_transect_with_sample_position) + + self.combobox_calibration_fine_sample.addItems(stg.samples) + # self.combobox_calibration_fine_sample.currentData.connect(self.update_plot_transect_with_sample_position) + + self.combobox_freq1.addItems(stg.freq_text) + self.combobox_freq2.addItems(stg.freq_text) - self.combobox_calibration_samples.addItem(" ") - for s in samples_vertical_line: - self.combobox_calibration_samples.addItem(" - ".join([i for i in s])) # for i in range(len(samples_vertical_line)): # self.combobox_calibration_samples.setItemChecked(i, False) # --- add items in combobox of frequencies for VBI computation --- - self.combobox_frequencies_VBI.addItem(" ") - for k in combinations(stg.freq_text, 2): - self.combobox_frequencies_VBI.addItem(k[0] + " - " + k[1]) + # self.combobox_frequencies_VBI.addItem(" ") + # for k in combinations(stg.freq_text, 2): + # self.combobox_frequencies_VBI.addItem(k[0] + " - " + k[1]) # print(k) # for i in range(len(list(combinations(stg.freq_text, 2)))): # self.combobox_frequencies_VBI.setItemChecked(i, False) - print(f"stg.fine_sediment_columns length : {len(stg.fine_sediment_columns)}") - print(f"stg.fine_sediment_columns : {stg.fine_sediment_columns}") - print(f"stg.frac_vol_fine.shape : {stg.frac_vol_fine.shape}") - print(f"stg.frac_vol_fine : {stg.frac_vol_fine}") + # print(f"stg.fine_sediment_columns length : {len(stg.fine_sediment_columns)}") + # print(f"stg.fine_sediment_columns : {stg.fine_sediment_columns}") + # print(f"stg.frac_vol_fine.shape : {stg.frac_vol_fine.shape}") + # print(f"stg.frac_vol_fine : {stg.frac_vol_fine}") + + def plot_transect_with_sample_position(self): + if self.canvas_plot_sample_position_on_transect == None: + + self.verticalLayout_groupbox_plot_sample_position_on_transect.removeWidget(self.canvas_plot_sample_position_on_transect) + self.figure_plot_sample_position_on_transect, self.axis_plot_sample_position_on_transect = \ + plt.subplots(nrows=1, ncols=1, layout="constrained") + self.canvas_plot_sample_position_on_transect = FigureCanvas(self.figure_plot_sample_position_on_transect) + self.verticalLayout_groupbox_plot_sample_position_on_transect.addWidget(self.canvas_plot_sample_position_on_transect) + + if stg.BS_stream_bed.size == 0: + + val_min = np.nanmin(stg.BS_cross_section[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_cross_section[stg.freq_bottom_detection, :, :]) + if val_min == 0: + val_min = 1e-5 + + self.axis_plot_sample_position_on_transect.pcolormesh( + stg.t[stg.freq_bottom_detection, :], + -stg.r[stg.freq_bottom_detection, :], + stg.BS_cross_section[stg.freq_bottom_detection, :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + + if stg.r_bottom.size != 0: + self.axis_plot_sample_position_on_transect.plot( + stg.t[stg.freq_bottom_detection, :], + -stg.r_bottom, color='black', linewidth=1, linestyle="solid") + + else: + + val_min = np.nanmin(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) + if val_min == 0: + val_min = 1e-5 + + self.axis_plot_sample_position_on_transect.pcolormesh( + stg.t[stg.freq_bottom_detection, :], + -stg.r[stg.freq_bottom_detection, :], + stg.BS_stream_bed[stg.freq_bottom_detection, :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + + if stg.r_bottom.size != 0: + self.axis_plot_sample_position_on_transect.plot( + stg.t[stg.freq_bottom_detection, :], -stg.r_bottom, + color='black', linewidth=1, linestyle="solid") + + self.axis_plot_sample_position_on_transect.set_xticks([]) + self.axis_plot_sample_position_on_transect.set_yticks([]) + self.figure_plot_sample_position_on_transect.canvas.draw_idle() + + def update_plot_transect_with_sample_position(self): + + # --- List selected sand and fine samples --- + sand_position_list, fine_position_list = self.sample_choice() + + # --- Create canvas of Matplotlib figure --- + if stg.BS_raw_data.size == 0: + + self.verticalLayout_groupbox_plot_sample_position_on_transect.removeWidget( + self.canvas_plot_sample_position_on_transect) + self.figure_plot_sample_position_on_transect, self.axis_plot_sample_position_on_transect = \ + plt.subplots(nrows=1, ncols=1, layout="constrained") + self.canvas_plot_sample_position_on_transect = FigureCanvas(self.figure_plot_sample_position_on_transect) + self.verticalLayout_groupbox_plot_sample_position_on_transect.addWidget( + self.canvas_plot_sample_position_on_transect) + + if sand_position_list: + self.axis_plot_sample_position_on_transect.scatter(stg.sample_time[sand_position_list], + stg.sample_depth[sand_position_list], + marker="o", s=20) + + if fine_position_list: + self.axis_plot_sample_position_on_transect.scatter(stg.sample_time[fine_position_list], + stg.sample_depth[fine_position_list], + marker="o", s=14) + + self.axis_plot_sample_position_on_transect.set_xticks([]) + self.axis_plot_sample_position_on_transect.set_yticks([]) + self.figure_plot_sample_position_on_transect.canvas.draw_idle() + + elif stg.BS_stream_bed.size == 0: + + val_min = np.nanmin(stg.BS_cross_section[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_cross_section[stg.freq_bottom_detection, :, :]) + if val_min == 0: + val_min = 1e-5 + + self.axis_plot_sample_position_on_transect.pcolormesh( + stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], + stg.BS_cross_section[self.combobox_frequency.currentIndex(), :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + + if stg.r_bottom.size != 0: + self.axis_plot_sample_position_on_transect.plot( + stg.t[stg.freq_bottom_detection, :], -stg.r_bottom, + color='black', linewidth=1, linestyle="solid") + + if sand_position_list: + self.axis_plot_sample_position_on_transect.scatter(stg.sample_time[sand_position_list], + stg.sample_depth[sand_position_list], + marker="o", s=20) + # markeredgecolor='k', markerfacecolor='none') + + if fine_position_list: + self.axis_plot_sample_position_on_transect.scatter(stg.sample_time[fine_position_list], + stg.sample_depth[fine_position_list], + marker="o", s=14) + # markeredgecolor='k', markerfacecolor='k') + + self.axis_plot_sample_position_on_transect.set_xticks([]) + self.axis_plot_sample_position_on_transect.set_yticks([]) + self.figure_plot_sample_position_on_transect.canvas.draw_idle() + + else: + + val_min = np.nanmin(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) + val_max = np.nanmax(stg.BS_stream_bed[stg.freq_bottom_detection, :, :]) + if val_min == 0: + val_min = 1e-5 + + self.axis_plot_sample_position_on_transect.pcolormesh( + stg.t[stg.freq_bottom_detection, :], -stg.r[stg.freq_bottom_detection, :], + stg.BS_stream_bed[self.combobox_frequency.currentIndex(), :, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + + if stg.r_bottom.size != 0: + self.axis_plot_sample_position_on_transect.plot( + stg.t[stg.freq_bottom_detection, :], -stg.r_bottom, color='black', linewidth=1, linestyle="solid") + + if sand_position_list: + self.axis_plot_sample_position_on_transect.scatter(stg.sample_time[sand_position_list], + stg.sample_depth[sand_position_list], + marker="o", s=20) + + if fine_position_list: + self.axis_plot_sample_position_on_transect.scatter(stg.sample_time[fine_position_list], + stg.sample_depth[fine_position_list], + marker="o", s=14) + + self.axis_plot_sample_position_on_transect.set_xticks([]) + self.axis_plot_sample_position_on_transect.set_yticks([]) + self.figure_plot_sample_position_on_transect.canvas.draw_idle() def sample_choice(self): - sample_position = [] - # for i in range(self.combobox_calibration_samples.count()): - # if self.combobox_calibration_samples.itemChecked(i): - sample_position.append(self.combobox_calibration_samples.currentIndex()) - # elif (i in sample_position) and (not self.combobox_calibration_samples.itemChecked(i)): - # sample_position.remove(i) - print(f"sample position : {sample_position}") + # --- List selected sand samples --- + sand_position_list = [int(s[1:])-1 for s in self.combobox_calibration_sand_sample.currentData()] + print(f"sand_position_list : {sand_position_list}") + # print(f"sand samples checked : {sand_samples_checked}") + + # --- List selected fine samples --- + fine_position_list = [int(s[1:])-1 for s in self.combobox_calibration_fine_sample.currentData()] + print(f"fine_position_list : {fine_position_list}") + # print(f"fine samples checked : {fine_samples_checked}") + return sand_position_list, fine_position_list def frequencies_pair_choice_to_compute_VBI(self): freq_combination = list(combinations(stg.freq, 2)) @@ -496,7 +768,7 @@ class AcousticInversionTab(QWidget): print("1/ stg.BS_cross_section_averaged") stg.J_cross_section = ( self.inv_hc.j_cross_section(stg.BS_cross_section_averaged[freq_ind, :, :], - stg.r_2D[0, :, :stg.BS_cross_section_averaged.shape[2]], + stg.r_2D[freq_ind, :, :stg.BS_cross_section_averaged.shape[2]], kt[freq_ind, :, :])) elif stg.BS_cross_section_SNR_filter.size != 0: @@ -625,14 +897,40 @@ class AcousticInversionTab(QWidget): # print(int(self.combobox_frequency_SSC.currentIndex())) # print(stg.zeta[int(self.combobox_frequency_SSC.currentIndex())]) + 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.value()) + # Real cell size + real_cell_size = cel * tau / 2 # voir fig 2.9 + + # Converting to real cell profile + real_r = np.zeros((stg.freq.shape[0], stg.r.shape[1])) + for i in range(stg.freq.shape[0]): + real_r[i, :] = stg.r[i, :] / 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) + print(f"R_real = {R_real.shape}") + + return R_real + def compute_acoustic_inversion_method_high_concentration(self): self.temperature_value() + # --- List selected sand and fine samples --- + sand_position_list, fine_position_list = self.sample_choice() if stg.ABS_name == "Aquascat 1000R": - freq1 = 0 # 0 = 300kHz et 1 = 500kHz - freq2 = 2 # 2 = 1MHz + freq1 = int(self.combobox_freq1.currentIndex()) # 0 = 300kHz et 1 = 500kHz + freq2 = int(self.combobox_freq2.currentIndex()) # 2 = 1MHz + print(f"freq1 = {freq1}, freq2 = {freq2}") stg.water_velocity = self.inv_hc.water_velocity(stg.temperature) @@ -644,9 +942,12 @@ class AcousticInversionTab(QWidget): # print("ks value : ", self.inv_hc.ks(a_s=stg.sand_sediment_columns[5:], rho_s=2500, freq=stg.freq[0], pdf=stg.frac_vol_sand[2, :])) + # ks_freq1, ks_freq2 = ( + # self.inv_hc.ks(num_sample=2, freq=stg.freq[freq1], pdf=stg.frac_vol_sand_cumul[2, :]), + # self.inv_hc.ks(num_sample=2, freq=stg.freq[freq2], pdf=stg.frac_vol_sand_cumul[2, :])) ks_freq1, ks_freq2 = ( - self.inv_hc.ks(freq=stg.freq[freq1], pdf=stg.frac_vol_sand_cumul[2, :]), - self.inv_hc.ks(freq=stg.freq[freq2], pdf=stg.frac_vol_sand_cumul[2, :])) + self.inv_hc.ks(num_sample=sand_position_list[0], freq=stg.freq[freq1], pdf=stg.frac_vol_sand_cumul[sand_position_list[0], :]), + self.inv_hc.ks(num_sample=sand_position_list[0], freq=stg.freq[freq2], pdf=stg.frac_vol_sand_cumul[sand_position_list[0], :])) # 6 = V11 , 10 = V12 sur le notebook d'Adrien # ks_freq1, ks_freq2 = self.inv_hc.ks()[0], self.inv_hc.ks()[2] print(f"ks_freq1 = {ks_freq1}, ks_freq2 = {ks_freq2}") @@ -656,8 +957,12 @@ class AcousticInversionTab(QWidget): # ax.plot(list(range(len(np.log(np.logspace(-10, -2, 3000))))), f, color="k", ls="solid") # plt.show() + # sv_freq1, sv_freq2 = ( + # self.inv_hc.sv(ks=ks_freq1, M_sand=stg.Ctot_sand[2]), + # self.inv_hc.sv(ks=ks_freq2, M_sand=stg.Ctot_sand[2])) sv_freq1, sv_freq2 = ( - self.inv_hc.sv(ks=ks_freq1, M_sand=stg.Ctot_sand[2]), self.inv_hc.sv(ks=ks_freq2, M_sand=stg.Ctot_sand[2])) + self.inv_hc.sv(ks=ks_freq1, M_sand=stg.Ctot_sand[sand_position_list[0]]), + self.inv_hc.sv(ks=ks_freq2, M_sand=stg.Ctot_sand[sand_position_list[0]])) print(f"sv_freq1 = {sv_freq1}, sv_freq2 = {sv_freq2}") X_exponent = self.inv_hc.X_exponent(freq1=stg.freq[freq1], freq2=stg.freq[freq2], sv_freq1=sv_freq1, sv_freq2=sv_freq2) @@ -717,7 +1022,8 @@ class AcousticInversionTab(QWidget): r_sample_ind = [] t_sample_ind = [] - for i in range(len(stg.sample_depth[:3])): + for i in range(len(stg.sample_depth[fine_position_list])): #:3 + # for i in range(len(stg.sample_depth[:3])): #:3 # print(-stg.sample_depth[i]) # print(-stg.sample_time[i]) r_sample_ind.append(np.where(np.abs(stg.r[0, :] - (-stg.sample_depth[i])) == @@ -738,6 +1044,8 @@ class AcousticInversionTab(QWidget): # ind_t_max = int(ind_r_max_around_sample[p, k]) # print(f"ind_t_max = {ind_t_max}") + print(f"stg.BS freq1 = {stg.BS_stream_bed_averaged[freq1, r_sample_ind[-1], t_sample_ind[-1]]}") + print(f"stg.BS freq2 = {stg.BS_stream_bed_averaged[freq2, r_sample_ind[-1], t_sample_ind[-1]]}") print(f"J_freq1[r_sample_ind[-1], t_sample_ind[-1]] {J_freq1[r_sample_ind[-1], t_sample_ind[-1]]}") print(f"J_freq2[r_sample_ind[-1], t_sample_ind[-1]] {J_freq2[r_sample_ind[-1], t_sample_ind[-1]]}") @@ -750,15 +1058,22 @@ class AcousticInversionTab(QWidget): self.inv_hc.alpha_s(sv=sv_freq2, j_cross_section=J_freq2[r_sample_ind[-1], t_sample_ind[-1]], depth=stg.r[freq2, r_sample_ind[-1]], alpha_w=alpha_w_freq2)) print(f"alpha_s_freq1 = {alpha_s_freq1}, alpha_s_freq2 = {alpha_s_freq2}") - range_lin_interp, M_profile_fine = self.inv_hc.M_profile_SCC_fine_interpolated(sample_depth=-stg.sample_depth[:3], - M_profile=stg.Ctot_fine[:3], + # range_lin_interp, M_profile_fine = self.inv_hc.M_profile_SCC_fine_interpolated( + # sample_depth=-stg.sample_depth[:3], #:3 + # M_profile=stg.Ctot_fine[:3], #:3 + # range_cells=stg.r[0, :], + # r_bottom=stg.r_bottom[t_sample_ind[0][0]]) + range_lin_interp, M_profile_fine = self.inv_hc.M_profile_SCC_fine_interpolated(sample_depth=-stg.sample_depth[fine_position_list], #:3 + M_profile=stg.Ctot_fine[fine_position_list], #:3 range_cells=stg.r[0, :], r_bottom=stg.r_bottom[t_sample_ind[0][0]]) - M_profile_fine = M_profile_fine[:len(range_lin_interp)] - print(f"range_lin_interp : {range_lin_interp}") print(f"M_profile_fine : {M_profile_fine}") + M_profile_fine = M_profile_fine[:len(range_lin_interp)] + print(f"M_profile_fine : {M_profile_fine}") + + # print("----------------------") # print(f"r_sample_ind[-1][0] = {r_sample_ind[-1][0][0]}") # print(f"M_profile_fine[:r_sample_ind[-1][0]] = ", M_profile_fine[:r_sample_ind[-1][0][0]]) @@ -775,6 +1090,30 @@ class AcousticInversionTab(QWidget): # plt.plot(stg.r[0, :], Mprofile, 'b.', -stg.sample_depth[:3], stg.Ctot_fine[:3], 'ko') # plt.show() + # --- Fill spinboxes with values of parameters --- + self.spinbox_ks_freq1.setValue(ks_freq1) + self.spinbox_ks_freq2.setValue(ks_freq2) + self.spinbox_sv_freq1.setValue(sv_freq1) + self.spinbox_sv_freq2.setValue(sv_freq2) + self.spinbox_X.setValue(X_exponent) + self.spinbox_alphas_freq1.setValue(alpha_s_freq1) + self.spinbox_alphas_freq2.setValue(alpha_s_freq2) + self.spinbox_zeta_freq1.setValue(zeta_freq1) + self.spinbox_zeta_freq2.setValue(zeta_freq2) + + # fig, ax = plt.subplots(nrows=2, ncols=1) + # pcm1 = ax[0].pcolormesh(stg.t[0, :], -stg.r[0, :], J_freq1, + # cmap='rainbow', vmin=0, vmax=1e-5, shading='gouraud') + # cbar1 = fig.colorbar(pcm1, ax=ax[0], shrink=1, location='right') + # cbar1.set_label(label='J (/m', rotation=270, labelpad=15) + # pcm2 = ax[1].pcolormesh(stg.t[0, :], -stg.r[0, :], J_freq2, + # cmap='rainbow', vmin=0, vmax=1e-4, shading='gouraud') + # cbar2 = fig.colorbar(pcm2, ax=ax[1], shrink=1, location='right') + # cbar2.set_label(label='J (/m', rotation=270, labelpad=15) + # fig.supxlabel("Time (sec)", fontsize=10) + # fig.supylabel("Depth (m)", fontsize=10) + # plt.show() + stg.VBI_cross_section = self.inv_hc.VBI_cross_section(stg.freq[freq1], stg.freq[freq2], zeta_freq1, zeta_freq2, J_freq1, J_freq2, @@ -783,14 +1122,15 @@ class AcousticInversionTab(QWidget): X_exponent) stg.SSC_fine = self.inv_hc.SSC_fine(zeta_freq2, stg.r_2D[freq2, :, :stg.t.shape[1]], - stg.VBI_cross_section, stg.freq[freq2], X_exponent, J_freq2) + stg.VBI_cross_section, stg.freq[freq2], X_exponent, J_freq2, + np.full(shape=(stg.r.shape[1], stg.t.shape[1]), fill_value=alpha_w_freq2)) stg.SSC_sand = self.inv_hc.SSC_sand(stg.VBI_cross_section, stg.freq[freq2], X_exponent, ks_freq2) elif stg.ABS_name == "UB-SediFlow": - freq1 = 0 # 0 = 500kHz - freq2 = 1 # 1 = 1MHz + freq1 = int(self.combobox_freq1.currentIndex()) # 0 = 500kHz + freq2 = int(self.combobox_freq2.currentIndex()) # 1 = 1MHz stg.water_velocity = self.inv_hc.water_velocity(stg.temperature) @@ -801,29 +1141,46 @@ class AcousticInversionTab(QWidget): self.compute_sound_velocity() # ks_freq1, ks_freq2 = 0.11373812635175432, 0.35705575378038723 - ks_freq1, ks_freq2 = (self.inv_hc.form_factor_function_MoateThorne2012(a=100e-6, freq=stg.freq[freq1])/np.sqrt(2500*100e-6), - self.inv_hc.form_factor_function_MoateThorne2012(a=100e-6, freq=stg.freq[freq2])/np.sqrt(2500*100e-6)) + # ks_freq1, ks_freq2 = (self.inv_hc.form_factor_function_MoateThorne2012(a=100e-6, freq=stg.freq[freq1])/np.sqrt(2500*100e-6), + # self.inv_hc.form_factor_function_MoateThorne2012(a=100e-6, freq=stg.freq[freq2])/np.sqrt(2500*100e-6)) + + ks_freq1, ks_freq2 = ( + self.inv_hc.ks(num_sample=sand_position_list[0], freq=stg.freq[freq1], pdf=stg.frac_vol_sand_cumul[sand_position_list[0], :]), + self.inv_hc.ks(num_sample=sand_position_list[0], freq=stg.freq[freq2], pdf=stg.frac_vol_sand_cumul[sand_position_list[0], :])) + # ks_freq1 = 0.05261498026985425 + # ks_freq2 = 0.19303997854869764 print(f"ks_freq1 = {ks_freq1}, ks_freq2 = {ks_freq2}") + # Fine sediments 19/05/2021 15h11 - 15h42 (locale) = 13h10 - 13h42 (UTC) --> 6 samples + # 52 to 428 / fixed at 234 + # 14h10 = position 766 + # Sand sediments 20/05/2021 12h04 - 12h20 (locale) = 10h04 - 10h20 (UTC) --> 2 samples + # 777 to 972 / fixed at 777 + sv_freq1, sv_freq2 = ( - self.inv_hc.sv(ks=ks_freq1, M_sand=stg.Ctot_sand[-1]), - self.inv_hc.sv(ks=ks_freq2, M_sand=stg.Ctot_sand[-1])) + self.inv_hc.sv(ks=ks_freq1, M_sand=stg.Ctot_sand[sand_position_list[0]]), + self.inv_hc.sv(ks=ks_freq2, M_sand=stg.Ctot_sand[sand_position_list[0]])) + # sv_freq1 = 0.0004956686799986783 + # sv_freq2 = 0.006672171109602389 print(f"sv_freq1 = {sv_freq1}, sv_freq2 = {sv_freq2}") - X_exponent = self.inv_hc.X_exponent(freq1=stg.freq[freq1], freq2=stg.freq[freq2], sv_freq1=sv_freq1, - sv_freq2=sv_freq2) - # X_exponent = self.inv_hc.X_exponent(ind=2) + X_exponent = self.inv_hc.X_exponent(freq1=stg.freq[freq1], freq2=stg.freq[freq2], + sv_freq1=sv_freq1, sv_freq2=sv_freq2) + # X_exponent = 3.750708280862506 print(f"X_exponent = {X_exponent}") - stg.kt = np.array([[1.38e-3], [6.02e-4]]) # Values of kt for 500kHz and 1MHz - kt = np.array([]) - for i, v in enumerate(stg.kt): - kt = np.append(kt, self.inv_hc.kt_corrected(r=stg.r[i, :], - water_velocity=stg.water_velocity, - RxGain=0, - TxGain=0, - kt_ref=stg.kt[i])) - kt = np.reshape(kt, (len(kt), 1)) + # stg.kt = np.array([[1.38e-3], [6.02e-4]]) # Values of kt for 500kHz and 1MHz + stg.kt = np.array([[0.5], [0.5]]) + + kt = stg.kt + # kt = np.array([]) + # for i, v in enumerate(stg.kt): + # kt = np.append(kt, self.inv_hc.kt_corrected(r=stg.r[i, :], + # water_velocity=stg.water_velocity, + # RxGain=0, + # TxGain=0, + # kt_ref=stg.kt[i])) + # kt = np.reshape(kt, (len(kt), 1)) print(f"kt = {kt}, kt.shape = {kt.shape}") kt2D = np.repeat(np.array(kt), stg.r.shape[1], axis=1) print(f"kt2D.shape = {kt2D.shape}") @@ -836,7 +1193,7 @@ class AcousticInversionTab(QWidget): r_sample_ind = [] t_sample_ind = [] - for i in range(len(stg.sample_depth[:])): + for i in range(len(stg.sample_depth[fine_position_list])): # print(-stg.sample_depth[i]) # print(-stg.sample_time[i]) r_sample_ind.append(np.where(np.abs(stg.r[freq1, :] - (-stg.sample_depth[i])) == @@ -847,35 +1204,128 @@ class AcousticInversionTab(QWidget): print(f"r_sample_ind = {r_sample_ind}") print(f"t_sample_ind = {t_sample_ind}") + print(f"stg.BS freq1 = {stg.BS_cross_section[freq1, r_sample_ind[-1], t_sample_ind[-1]]}") + print(f"stg.BS freq2 = {stg.BS_cross_section[freq2, r_sample_ind[-1], t_sample_ind[-1]]}") + + print(f"J_freq1[r_sample_ind[-1], t_sample_ind[-1]] : {J_freq1[r_sample_ind[-1][0][0], t_sample_ind[-1][0][0]]}") + # print(f"J_freq1[r_sample_ind[-1]+-n, t_sample_ind[-1]+-n] : {J_freq1[r_sample_ind[-1][0][0], t_sample_ind[-1][0][0]:t_sample_ind[-1][0][0]].mean(axis=0)}") + + # delta_t = 0 alpha_s_freq1, alpha_s_freq2 = ( - self.inv_hc.alpha_s(sv=sv_freq1, j_cross_section=J_freq1[r_sample_ind[-1], t_sample_ind[-1]], - depth=stg.r[freq1, r_sample_ind[-1]], alpha_w=alpha_w_freq1), - self.inv_hc.alpha_s(sv=sv_freq2, j_cross_section=J_freq2[r_sample_ind[-1], t_sample_ind[-1]], - depth=stg.r[freq2, r_sample_ind[-1]], alpha_w=alpha_w_freq2)) + self.inv_hc.alpha_s(sv=sv_freq1, + j_cross_section=np.mean(J_freq1[r_sample_ind[-1][0][0], t_sample_ind[-1][0][0]]), + depth=stg.r[freq1, r_sample_ind[-1][0][0]], alpha_w=alpha_w_freq1), + self.inv_hc.alpha_s(sv=sv_freq2, + j_cross_section=np.mean(J_freq2[r_sample_ind[-1][0][0], t_sample_ind[-1][0][0]]), + # j_cross_section=J_freq2[r_sample_ind[-1], t_sample_ind[-1]], + depth=stg.r[freq2, r_sample_ind[-1][0][0]], alpha_w=alpha_w_freq2)) + + # avec J (alpha_w = 0.03578217234512747) + # alpha_s_freq1 = -0.12087339 + # alpha_s_freq2 = -0.01437704 + + # avec log(J) + # alpha_s_freq1 = -1.91967628 + # alpha_s_freq2 = -1.87942544 + + # --- Calculation of alpha_s with FCB slope --- + + # R_real = np.repeat(self.range_cells_function()[:, :, np.newaxis], stg.t.shape[1], axis=2) + # water_attenuation = np.full((2, stg.r.shape[1], stg.t.shape[1]), 1) + # water_attenuation[0, :, :] = alpha_w_freq1*water_attenuation[0, :, :] + # water_attenuation[1, :, :] = alpha_w_freq2*water_attenuation[1, :, :] + # if stg.BS_stream_bed.size == 0: + # stg.FCB = (np.log(stg.BS_cross_section[[freq1, freq2], :, :]) + np.log(R_real[[freq1, freq2], :, :]) + + # 2 * water_attenuation * R_real[[freq1, freq2], :, :]) + # elif (stg.BS_stream_bed_averaged.size == 0) and (stg.BS_stream_bed_SNR_filter.size == 0): + # stg.FCB = (np.log(stg.BS_stream_bed[[freq1, freq2], :, :]) + np.log(R_real[[freq1, freq2], :, :]) + + # 2 * water_attenuation * R_real[[freq1, freq2], :, :]) + # elif stg.BS_stream_bed_SNR_filter.size == 0: + # stg.FCB = (np.log(stg.BS_stream_bed_averaged[[freq1, freq2], :, :]) + np.log(R_real[[freq1, freq2], :, :]) + + # 2 * water_attenuation * R_real[[freq1, freq2], :, :]) + # else: + # stg.FCB = (np.log(stg.BS_stream_bed_SNR_filter[[freq1, freq2], :, :]) + np.log(R_real[[freq1, freq2], :, :]) + + # 2 * water_attenuation * R_real[[freq1, freq2], :, :]) + # + # print(f"FCB shape : {stg.FCB.shape}") + # + # y1 = stg.FCB[freq1, 5:138, t_sample_ind[-1][0][0]] + # x1 = stg.r[freq1, 5:138] + # lin_reg_compute1 = stats.linregress(x1, y1) + # + # y2 = stg.FCB[freq2, 5:138, t_sample_ind[-1][0][0]] + # x2 = stg.r[freq2, 5:138] + # lin_reg_compute2 = stats.linregress(x2, y2) + # + # print(f"lin_reg_compute1 : {lin_reg_compute1}") + # print(f"lin_reg_compute2 : {lin_reg_compute2}") + # + # fig, ax = plt.subplots(nrows=1, ncols=2) + # ax[0].plot(x1, y1, ls='solid', c='k') + # ax[0].plot(x1, x1*lin_reg_compute1.slope + lin_reg_compute1.intercept, ls='dashed', c='b') + # ax[0].set_xlabel("Distance from transducer (m)") + # ax[0].set_ylabel("FCB") + # ax[0].set_title("Frequency 500kHz") + # ax[1].plot(x2, y2, ls='solid', c='k') + # ax[1].plot(x2, x2*lin_reg_compute2.slope + lin_reg_compute2.intercept, ls='solid', c='r') + # ax[1].set_xlabel("Distance from transducer (m)") + # ax[1].set_ylabel("FCB") + # ax[1].set_title("Frequency 1MHz") + # plt.show() + # + # alpha_s_freq1 , alpha_s_freq2 = -0.5*lin_reg_compute1.slope, -0.5*lin_reg_compute2.slope + # alpha_s_freq1 = 0.35107724188865586 + # alpha_s_freq2 = 0.37059368399238274 print(f"alpha_s_freq1 = {alpha_s_freq1}, alpha_s_freq2 = {alpha_s_freq2}") - # range_lin_interp, M_profile_fine = self.inv_hc.M_profile_SCC_fine_interpolated( - # sample_depth=-stg.sample_depth[:], - # M_profile=stg.Ctot_sand[:], - # range_cells=stg.r[0, :], - # r_bottom=np.array([])) # stg.r_bottom[t_sample_ind[0][0]] is empty + range_lin_interp, M_profile_fine = self.inv_hc.M_profile_SCC_fine_interpolated( + sample_depth=-stg.sample_depth[:], + M_profile=stg.Ctot_fine[:], + range_cells=stg.r[0, :], + r_bottom=np.array([])) # stg.r_bottom[t_sample_ind[0][0]] is empty # M_profile_fine = M_profile_fine[:len(range_lin_interp)] - range_lin_interp, M_profile_fine = 3.2, 1 + # range_lin_interp, M_profile_fine = 3.2, 6.5 print(f"range_lin_interp : {range_lin_interp}") print(f"M_profile_fine : {M_profile_fine}") - zeta_freq1, zeta_freq2 = (alpha_s_freq1 / (M_profile_fine*(3.19127224 - 0.52102404)), - alpha_s_freq2 / (M_profile_fine*(3.19127224 - 0.52102404))) - # zeta_freq1, zeta_freq2 = ( - # self.inv_hc.zeta(alpha_s=alpha_s_freq1, r=stg.r[freq1, :], M_profile_fine=M_profile_fine), - # self.inv_hc.zeta(alpha_s=alpha_s_freq2, r=stg.r[freq2, :], M_profile_fine=M_profile_fine)) - + # zeta_freq1, zeta_freq2 = (alpha_s_freq1 / (M_profile_fine[0]*(3.19127224 - 0.52102404)), + # alpha_s_freq2 / (M_profile_fine[0]*(3.19127224 - 0.52102404))) + zeta_freq1, zeta_freq2 = ( + self.inv_hc.zeta(alpha_s=alpha_s_freq1, r=stg.r[freq1, :], M_profile_fine=M_profile_fine), + self.inv_hc.zeta(alpha_s=alpha_s_freq2, r=stg.r[freq2, :], M_profile_fine=M_profile_fine)) + # zeta_freq1, zeta_freq2 = zeta_freq1*1e-8, zeta_freq2*1e-8 + # zeta_freq1 = 0.06417348381928434 + # zeta_freq2 = 0.06774089842814904 + # zeta_freq1, zeta_freq2 = 0.03018602, 0.05496619 print(f"zeta_freq1 = {zeta_freq1}, zeta_freq2 = {zeta_freq2}") # zeta_freq1, zeta_freq2 = 1e-10*self.inv_hc.zeta(ind=1), 1e1*self.inv_hc.zeta(ind=2) # print(f"zeta_freq1 = {zeta_freq1}, zeta_freq2 = {zeta_freq2}") + # --- Fill spinboxes with values of parameters --- + self.spinbox_ks_freq1.setValue(ks_freq1) + self.spinbox_ks_freq2.setValue(ks_freq2) + self.spinbox_sv_freq1.setValue(sv_freq1) + self.spinbox_sv_freq2.setValue(sv_freq2) + self.spinbox_X.setValue(X_exponent) + self.spinbox_alphas_freq1.setValue(alpha_s_freq1) + self.spinbox_alphas_freq2.setValue(alpha_s_freq2) + self.spinbox_zeta_freq1.setValue(zeta_freq1) + self.spinbox_zeta_freq2.setValue(zeta_freq2) + + # fig, ax = plt.subplots(nrows=2, ncols=1) + # pcm1 = ax[0].pcolormesh(stg.t[0, :], -stg.r[0, :], J_freq1, + # cmap='rainbow', shading='gouraud') + # cbar1 = fig.colorbar(pcm1, ax=ax[0], shrink=1, location='right') + # cbar1.set_label(label='J (/m', rotation=270, labelpad=15) + # pcm2 = ax[1].pcolormesh(stg.t[0, :], -stg.r[0, :], J_freq2, + # cmap='rainbow', shading='gouraud') + # cbar2 = fig.colorbar(pcm2, ax=ax[1], shrink=1, location='right') + # cbar2.set_label(label='J (/m', rotation=270, labelpad=15) + # fig.supxlabel("Time (sec)", fontsize=10) + # fig.supylabel("Depth (m)", fontsize=10) + # plt.show() stg.VBI_cross_section = self.inv_hc.VBI_cross_section(stg.freq[freq1], stg.freq[freq2], zeta_freq1, zeta_freq2, @@ -884,8 +1334,11 @@ class AcousticInversionTab(QWidget): alpha_w_freq1, alpha_w_freq2, X_exponent) + + stg.SSC_fine = self.inv_hc.SSC_fine(zeta_freq2, stg.r_2D[freq2, :, :stg.t.shape[1]], - stg.VBI_cross_section, stg.freq[freq2], X_exponent, J_freq2) + stg.VBI_cross_section, stg.freq[freq2], X_exponent, J_freq2, + np.full(shape=(stg.r.shape[1], stg.t.shape[1]), fill_value=alpha_w_freq2)) # stg.SSC_fine = self.inv_hc.SSC_fine(stg.zeta[int(self.combobox_frequency_SSC.currentIndex())], # stg.r_2D[int(stg.frequency_to_compute_SSC[0]), :, :stg.t.shape[1]], # stg.VBI_cross_section, @@ -913,6 +1366,14 @@ class AcousticInversionTab(QWidget): self.plot_SSC_fine() self.plot_SSC_sand() + else: + + self.verticalLayout_groupbox_SSC_2D_field.removeWidget(self.canvas_SSC_2D_field) + self.verticalLayout_groupbox_SSC_2D_field.addWidget(self.canvas_SSC_2D_field) + + self.plot_SSC_fine() + self.plot_SSC_sand() + def plot_SSC_fine(self): # val_min = 1e-2 @@ -941,7 +1402,7 @@ class AcousticInversionTab(QWidget): -stg.r[0, :], stg.SSC_fine, cmap='rainbow', - norm=LogNorm(vmin=1e-2, vmax=15), + norm=LogNorm(vmin=1e0, vmax=15), shading='gouraud') # pcm_SSC_fine = self.axis_SSC_2D_field[0].pcolormesh(stg.t[int(stg.frequency_to_compute_SSC[0]), :], # -stg.r[int(stg.frequency_to_compute_SSC[0]), :], @@ -954,7 +1415,7 @@ class AcousticInversionTab(QWidget): -stg.r[0, :], stg.SSC_fine, cmap='rainbow', - norm=LogNorm(vmin=1e-2, vmax=1), + norm=LogNorm(vmin=1e-2, vmax=10), shading='gouraud') @@ -1005,14 +1466,21 @@ class AcousticInversionTab(QWidget): elif stg.ABS_name == "UB-SediFlow": pcm_SSC_sand = self.axis_SSC_2D_field[1].pcolormesh(stg.t[0, :], - -stg.r[0, :], - (stg.SSC_sand), - cmap='rainbow', - # vmin=-60, vmax=-45) + -stg.r[0, 5:155], + (stg.SSC_sand[5:155, :]), + cmap="plasma", + # cmap='rainbow', + vmin=0, vmax=10, # vmin=1e-2, vmax=10) # vmin=val_min, vmax=val_max, - norm=LogNorm(vmin=1e-2, vmax=1), + # norm=LogNorm(vmin=1e-2, vmax=1), shading='gouraud') + # self.axis_SSC_2D_field[1].plot(stg.t[1, 52] * np.ones(len(stg.r[1, 5:152])), -stg.r[1, 5:152], + # c='b', ls='solid', lw=2) + # self.axis_SSC_2D_field[1].plot(stg.t[1, ] * np.ones(len(stg.r[1, 5:152])), -stg.r[1, 5:152], + # c='red', ls='solid', lw=2) + self.axis_SSC_2D_field[1].plot(stg.t[1, 777] * np.ones(len(stg.r[1, 5:152])), -stg.r[1, 5:152], + c='red', ls='solid', lw=2) # pcm_SSC_sand = self.axis_SSC_2D_field[1].pcolormesh(stg.t[int(stg.frequency_to_compute_SSC[0]), :], # -stg.r[int(stg.frequency_to_compute_SSC[0]), :], @@ -1062,20 +1530,35 @@ class AcousticInversionTab(QWidget): self.canvas_SSC_sample_vs_inversion = FigureCanvas(self.figure_SSC_sample_vs_inversion) self.verticalLayout_groupbox_SSC_sample_vs_inversion.addWidget(self.canvas_SSC_sample_vs_inversion) - if stg.ABS_name == "Aquascat 1000R": - self.axis_SSC_sample_vs_inversion.plot(stg.Ctot_fine, stg.SSC_fine[sample_depth_position, sample_time_position], ls=" ", marker='v', color='black', label='Fine SSC') - self.axis_SSC_sample_vs_inversion.plot(stg.Ctot_sand, - stg.SSC_sand[sample_depth_position, sample_time_position], - ls=" ", marker='x', color='black', label='Sand SSC') + else: - self.axis_SSC_sample_vs_inversion.set_xscale('log') - self.axis_SSC_sample_vs_inversion.set_yscale('log') - self.axis_SSC_sample_vs_inversion.plot([0, 10], [0, 10], color='black', lw=1) - self.axis_SSC_sample_vs_inversion.set_xlabel('Measured SSC (g/l)', weight='bold') - self.axis_SSC_sample_vs_inversion.set_ylabel('Inverse SSC (g/l)', weight='bold') - self.axis_SSC_sample_vs_inversion.legend() + self.verticalLayout_groupbox_SSC_sample_vs_inversion.removeWidget(self.canvas_SSC_sample_vs_inversion) - elif stg.ABS_name == "UB-SediFlow": + print("Ctot fine : ", stg.Ctot_fine) + print("SCC fine : ", stg.SSC_fine[sample_depth_position, sample_time_position]) + print("Ctot sand : ", stg.Ctot_sand) + print("SCC sand : ", stg.SSC_sand[sample_depth_position, sample_time_position]) + + self.figure_SSC_sample_vs_inversion, self.axis_SSC_sample_vs_inversion = plt.subplots(nrows=1, ncols=1, + layout="constrained") + self.canvas_SSC_sample_vs_inversion = FigureCanvas(self.figure_SSC_sample_vs_inversion) + self.verticalLayout_groupbox_SSC_sample_vs_inversion.addWidget(self.canvas_SSC_sample_vs_inversion) + + + if stg.ABS_name == "Aquascat 1000R": + self.axis_SSC_sample_vs_inversion.plot(stg.Ctot_fine, stg.SSC_fine[sample_depth_position, sample_time_position], ls=" ", marker='v', color='black', label='Fine SSC') + self.axis_SSC_sample_vs_inversion.plot(stg.Ctot_sand, + stg.SSC_sand[sample_depth_position, sample_time_position], + ls=" ", marker='x', color='black', label='Sand SSC') + + self.axis_SSC_sample_vs_inversion.set_xscale('log') + self.axis_SSC_sample_vs_inversion.set_yscale('log') + self.axis_SSC_sample_vs_inversion.plot([0, 10], [0, 10], color='black', lw=1) + self.axis_SSC_sample_vs_inversion.set_xlabel('Measured SSC (g/l)', weight='bold') + self.axis_SSC_sample_vs_inversion.set_ylabel('Inverse SSC (g/l)', weight='bold') + self.axis_SSC_sample_vs_inversion.legend() + + elif stg.ABS_name == "UB-SediFlow": # self.axis_SSC_sample_vs_inversion.plot(stg.Ctot_sand, # stg.SSC_sand[sample_depth_position, sample_time_position], # ls=" ", marker='x', color='black', label='Sand SSC') @@ -1091,10 +1574,14 @@ class AcousticInversionTab(QWidget): # plt.show() # self.axis_SSC_sample_vs_inversion.plot(stg.r[1, :145], stg.SSC_sand[:145, 40], color='blue', ls='solid') - self.axis_SSC_sample_vs_inversion.plot(stg.r[1, 2:145], stg.SSC_sand[2:145, 762], - color='red', ls='solid', marker='o', mec='k', mfc='k', ms=3) - self.axis_SSC_sample_vs_inversion.set_xlabel('Depth (m)', weight='bold') - self.axis_SSC_sample_vs_inversion.set_ylabel('Sand concentration (g/l)', weight='bold') + # self.axis_SSC_sample_vs_inversion.plot(stg.r[1, 5:152], stg.SSC_sand[5:152, 52], + # color='blue', ls='solid') #, marker='o', mec='k', mfc='k', ms=3) + # self.axis_SSC_sample_vs_inversion.plot(stg.r[1, 5:152], stg.SSC_sand[5:152, 766], + # color='red', ls='solid') + self.axis_SSC_sample_vs_inversion.plot(stg.r[1, 5:138], stg.SSC_sand[5:138, 777], color='red', ls='solid') + + self.axis_SSC_sample_vs_inversion.set_xlabel('Depth (m)', weight='bold') + self.axis_SSC_sample_vs_inversion.set_ylabel('Sand concentration (g/l)', weight='bold') diff --git a/View/checkable_combobox.py b/View/checkable_combobox.py index d0f31b1..2cda583 100644 --- a/View/checkable_combobox.py +++ b/View/checkable_combobox.py @@ -1,33 +1,154 @@ -from PyQt5.QtWidgets import QComboBox -from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QComboBox, QStyledItemDelegate, qApp +from PyQt5.QtCore import Qt, QEvent +from PyQt5.QtGui import QPalette, QStandardItem, QFontMetrics + class CheckableComboBox(QComboBox): - def __init__(self): - super().__init__() - self._changed = False - self.view().pressed.connect(self.handleItemPressed) - def setItemChecked(self, index, checked=False): - item = self.model().item(index, self.modelColumn()) # QStandardItem object - if checked: - item.setCheckState(Qt.Checked) - else: - item.setCheckState(Qt.Unchecked) + # Subclass Delegate to increase item height + class Delegate(QStyledItemDelegate): + def sizeHint(self, option, index): + size = super().sizeHint(option, index) + size.setHeight(20) + return size - def handleItemPressed(self, index): - item = self.model().itemFromIndex(index) - if item.checkState() == Qt.Checked: - item.setCheckState(Qt.Unchecked) - else: - item.setCheckState(Qt.Checked) - self._changed = True + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Make the combo editable to set a custom text, but readonly + self.setEditable(True) + self.lineEdit().setReadOnly(True) + # Make the lineedit the same color as QPushButton + palette = qApp.palette() + palette.setBrush(QPalette.Base, palette.button()) + self.lineEdit().setPalette(palette) + + # Use custom delegate + self.setItemDelegate(CheckableComboBox.Delegate()) + + # Update the text when an item is toggled + self.model().dataChanged.connect(self.updateText) + + # Hide and show popup when clicking the line edit + self.lineEdit().installEventFilter(self) + self.closeOnLineEditClick = False + + # Prevent popup from closing when clicking on an item + self.view().viewport().installEventFilter(self) + + def resizeEvent(self, event): + # Recompute text to elide as needed + self.updateText() + super().resizeEvent(event) + + def eventFilter(self, object, event): + + if object == self.lineEdit(): + if event.type() == QEvent.MouseButtonRelease: + if self.closeOnLineEditClick: + self.hidePopup() + else: + self.showPopup() + return True + return False + + if object == self.view().viewport(): + if event.type() == QEvent.MouseButtonRelease: + index = self.view().indexAt(event.pos()) + item = self.model().item(index.row()) + + if item.checkState() == Qt.Checked: + item.setCheckState(Qt.Unchecked) + else: + item.setCheckState(Qt.Checked) + return True + return False + + def showPopup(self): + super().showPopup() + # When the popup is displayed, a click on the lineedit should close it + self.closeOnLineEditClick = True def hidePopup(self): - if not self._changed: - super().hidePopup() - self._changed = False + super().hidePopup() + # Used to prevent immediate reopening when clicking on the lineEdit + self.startTimer(100) + # Refresh the display text when closing + self.updateText() + + def timerEvent(self, event): + # After timeout, kill timer, and reenable click on line edit + self.killTimer(event.timerId()) + self.closeOnLineEditClick = False + + def updateText(self): + texts = [] + for i in range(self.model().rowCount()): + if self.model().item(i).checkState() == Qt.Checked: + texts.append(self.model().item(i).text()) + text = ", ".join(texts) + + # Compute elided text (with "...") + metrics = QFontMetrics(self.lineEdit().font()) + elidedText = metrics.elidedText(text, Qt.ElideRight, self.lineEdit().width()) + self.lineEdit().setText(elidedText) + + def addItem(self, text, data=None): + item = QStandardItem() + item.setText(text) + if data is None: + item.setData(text) + else: + item.setData(data) + item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) + item.setData(Qt.Unchecked, Qt.CheckStateRole) + self.model().appendRow(item) + + def addItems(self, texts, datalist=None): + for i, text in enumerate(texts): + try: + data = datalist[i] + except (TypeError, IndexError): + data = None + self.addItem(text, data) + + def currentData(self): + # Return the list of selected items data + res = [] + for i in range(self.model().rowCount()): + if self.model().item(i).checkState() == Qt.Checked: + res.append(self.model().item(i).data()) + return res + + +# class CheckableComboBox(QComboBox): +# def __init__(self): +# super().__init__() +# self._changed = False +# self.view().pressed.connect(self.handleItemPressed) +# +# def setItemChecked(self, index, checked=False): +# item = self.model().item(index, self.modelColumn()) # QStandardItem object +# if checked: +# item.setCheckState(Qt.Checked) +# else: +# item.setCheckState(Qt.Unchecked) +# +# def handleItemPressed(self, index): +# item = self.model().itemFromIndex(index) +# if item.checkState() == Qt.Checked: +# item.setCheckState(Qt.Unchecked) +# else: +# item.setCheckState(Qt.Checked) +# self._changed = True +# +# def hidePopup(self): +# if not self._changed: +# super().hidePopup() +# self._changed = False +# +# def itemChecked(self, index): +# item = self.model().item(index, self.modelColumn()) +# return item.checkState() == Qt.Checked - def itemChecked(self, index): - item = self.model().item(index, self.modelColumn()) - return item.checkState() == Qt.Checked \ No newline at end of file diff --git a/View/signal_processing_tab.py b/View/signal_processing_tab.py index 7b0a48c..5d840ec 100644 --- a/View/signal_processing_tab.py +++ b/View/signal_processing_tab.py @@ -655,7 +655,7 @@ class SignalProcessingTab(QWidget): # --- Fix maximum value of slider + Edit Label Profile number --- self.slider.setMaximum(stg.t.shape[1]) self.label_profile_number.clear() - self.label_profile_number.setText("Profile " + str(self.slider.value()) + " / " + str(self.slider.maximum())) + self.label_profile_number.setText("Vertical " + str(self.slider.value()) + " / " + str(self.slider.maximum())) self.plot_profile_position_on_transect() self.plot_profile() @@ -883,7 +883,7 @@ class SignalProcessingTab(QWidget): # (* real_cell_size) pour remettre les échelles spatiales sur la taille réelle des cellules # R with right shape (numpy array) - R_real = np.repeat(real_r, len(stg.freq), axis=1) + R_real = real_r # np.repeat(real_r, len(stg.freq), axis=1) return R_real @@ -896,7 +896,10 @@ class SignalProcessingTab(QWidget): msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() else: - R_real = np.repeat(self.range_cells_function()[:, :, np.newaxis], stg.t.shape[0], axis=2) + 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_averaged.size == 0) and (stg.BS_stream_bed_SNR_filter.size == 0): stg.FCB = (np.log(stg.BS_stream_bed) + np.log(R_real) + 2 * stg.water_attenuation * R_real) @@ -919,10 +922,10 @@ class SignalProcessingTab(QWidget): msgBox.exec() else: try: - y0 = stg.FCB[:, self.combobox_frequency_compute_alphaS.currentIndex(), self.slider.value()] + y0 = stg.FCB[self.combobox_frequency_compute_alphaS.currentIndex(), :, self.slider.value()] y = y0[np.where(np.isnan(y0) == False)] - x0 = stg.r.reshape(-1) + x0 = stg.r[0, :].reshape(-1) x = x0[np.where(np.isnan(y0) == False)] value1 = np.where(np.round(np.abs(x - self.spinbox_alphaS_computation_from.value()), 2) @@ -1040,7 +1043,7 @@ class SignalProcessingTab(QWidget): # --- Update label "Profile N / max(N)" --- self.label_profile_number.clear() - self.label_profile_number.setText("Profile " + str(self.slider.value()) + " / " + str(self.slider.maximum())) + self.label_profile_number.setText("Vertical " + str(self.slider.value()) + " / " + str(self.slider.maximum())) # --- Update transect plot --- @@ -1411,7 +1414,7 @@ class SignalProcessingTab(QWidget): self.axis_FCB_profile[f].cla() - self.axis_FCB_profile[f].plot(stg.r, stg.FCB[:, f, self.slider.value()], linestyle="solid", linewidth=1, color="k") + self.axis_FCB_profile[f].plot(stg.r[f, :], stg.FCB[f, :, self.slider.value()], linestyle="solid", linewidth=1, color="k") # self.axis_FCB_profile[f].set_ylim(np.max(stg.r), np.min(stg.r)) self.axis_FCB_profile[f].text(.95, .05, stg.freq_text[f], @@ -1422,7 +1425,7 @@ class SignalProcessingTab(QWidget): if len(stg.lin_reg) != 0: self.axis_FCB_profile[self.combobox_frequency_compute_alphaS.currentIndex()]. \ - plot(stg.r, stg.lin_reg[0]*stg.r + stg.lin_reg[1], linestyle="dashed", linewidth=1, color="b") + plot(stg.r[f, :], stg.lin_reg[0]*stg.r[f, :] + stg.lin_reg[1], linestyle="dashed", linewidth=1, color="b") self.figure_FCB_profile.supylabel("FCB") self.figure_FCB_profile.supxlabel("Depth (m)") @@ -1436,7 +1439,7 @@ class SignalProcessingTab(QWidget): self.axis_FCB_profile[f].cla() - self.axis_FCB_profile[f].plot(stg.r, stg.FCB[:, f, self.slider.value()], linestyle="solid", linewidth=1, color="k") + self.axis_FCB_profile[f].plot(stg.r[f, :], stg.FCB[f, :, self.slider.value()], linestyle="solid", linewidth=1, color="k") # self.axis_FCB_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) diff --git a/main.py b/main.py index e4bec1f..c40f9ea 100644 --- a/main.py +++ b/main.py @@ -13,7 +13,7 @@ from View.note_tab import NoteTab from View.user_manual_tab import UserManualTab import matplotlib.pyplot as plt -plt.close("all") +# plt.close("all") # Check encoding used # print(sys.getdefaultencoding()) @@ -35,7 +35,6 @@ class MainApplication(QMainWindow): width = size.width() height = size.height() self.resize(int(PERCENT_SCREEN_SIZE*width), int(PERCENT_SCREEN_SIZE*height)) - try: # ************************************************** @@ -50,7 +49,7 @@ class MainApplication(QMainWindow): self.signal_processing_tab = SignalProcessingTab(self.ui_mainwindow.tab2) - # ************************************************** + # **************************************************. # --------------- Sample data tab ---------------- self.sample_data_tab = SampleDataTab(self.ui_mainwindow.tab3)