diff --git a/Model/acoustic_data_loader.py b/Model/acoustic_data_loader.py index 569fc47..d9f6b9c 100644 --- a/Model/acoustic_data_loader.py +++ b/Model/acoustic_data_loader.py @@ -48,6 +48,9 @@ class AcousticDataLoader(): # print(["BS - " + f for f in self._freq_text]) # print(self._time.shape[0]*self._r.shape[0]*4) + # print(self._time[np.where(np.floor(self._time) == 175)]) + # print(np.where((self._time) == 155)[0][0]) + # fig, ax = plt.subplots(nrows=1, ncols=1) # ax.pcolormesh(self._time, self._r, (self._BS_raw_data[:, 1, :]), # cmap='viridis', diff --git a/Model/granulo_loader.py b/Model/granulo_loader.py index 828cb90..a0d8d24 100644 --- a/Model/granulo_loader.py +++ b/Model/granulo_loader.py @@ -6,41 +6,43 @@ class GranuloLoader: """ This class allows to load granulo data file """ - def __init__(self, path_fine: str, path_sand: str): + def __init__(self, path: str): - # --- Load fine sediments data file --- - self.path_fine = path_fine - self._data_fine = pd.read_excel(self.path_fine, engine="odf", header=0) + self._path = path + self._data = pd.read_excel(self._path, engine="odf", header=0) - self._y = np.array(self._data_fine.iloc[:, 0]) # distance from left bank (m) - self._z = np.array(self._data_fine.iloc[:, 1]) # depth (m) - self._r_grain = np.array(self._data_fine.columns.values)[4:] # grain radius (um) + self._time = np.array(self._data.iloc[:, 0]) + self._y = np.array(self._data.iloc[:, 1]) # distance from left bank (m) + self._z = np.array(self._data.iloc[:, 2]) # depth (m) - self._Ctot_fine = np.array(self._data_fine.iloc[:, 2]) # Total concentration (g/L) - self._D50_fine = np.array(self._data_fine.iloc[:, 3]) # median diameter (um) - self._frac_vol_fine = np.array(self._data_fine.iloc[:, 4:]) # Volume fraction (%) + self._r_grain = np.array(self._data.columns.values)[5:] # grain radius (um) - self._frac_vol_fine_cumul = np.cumsum(self._frac_vol_fine, axis=1) # Cumulated volume fraction (%) + self._Ctot = np.array(self._data.iloc[:, 3]) # Total concentration (g/L) + self._D50 = np.array(self._data.iloc[:, 4]) # median diameter (um) + self._frac_vol = np.array(self._data.iloc[:, 5:]) # Volume fraction (%) - # --- Load sand sediments data file --- - self.path_sand = path_sand - self._data_sand = pd.read_excel(self.path_sand, engine="odf", header=0) + self._frac_vol_cumul = np.cumsum(self._frac_vol, axis=1) # Cumulated volume fraction (%) - self._Ctot_sand = np.array(self._data_sand.iloc[:, 2]) # Total concentration (g/L) - self._D50_sand = np.array(self._data_sand.iloc[:, 3]) # median diameter (um) - self._frac_vol_sand = np.array(self._data_sand.iloc[:, 4:]) # Volume fraction (%) - - self._frac_vol_sand_cumul = np.cumsum(self._frac_vol_sand, axis=1) # Cumulated volume fraction (%) - - # --- Compute % of fine and % of sand sediment in total concentration --- - - self._Ctot_fine_per_cent = 100 * self._Ctot_fine / (self._Ctot_fine + self._Ctot_sand) - self._Ctot_sand_per_cent = 100 * self._Ctot_sand / (self._Ctot_fine + self._Ctot_sand) + # # --- Load sand sediments data file --- + # self.path_sand = path_sand + # self._data_sand = pd.read_excel(self.path_sand, engine="odf", header=0) + # + # self._Ctot_sand = np.array(self._data_sand.iloc[:, 2]) # Total concentration (g/L) + # self._D50_sand = np.array(self._data_sand.iloc[:, 3]) # median diameter (um) + # self._frac_vol_sand = np.array(self._data_sand.iloc[:, 4:]) # Volume fraction (%) + # + # self._frac_vol_sand_cumul = np.cumsum(self._frac_vol_sand, axis=1) # Cumulated volume fraction (%) + # + # # --- Compute % of fine and % of sand sediment in total concentration --- + # + # self._Ctot_fine_per_cent = 100 * self._Ctot_fine / (self._Ctot_fine + self._Ctot_sand) + # self._Ctot_sand_per_cent = 100 * self._Ctot_sand / (self._Ctot_fine + self._Ctot_sand) + # print(self._time) # if __name__ == "__main__": # GranuloLoader("/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Granulo_data/" -# "fine_sample_file.ods", +# "fine_sample_file.ods") # "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Granulo_data/" # "sand_sample_file.ods") diff --git a/Translation/biblio_string.pro b/Translation/biblio_string.pro new file mode 100755 index 0000000..dacb489 --- /dev/null +++ b/Translation/biblio_string.pro @@ -0,0 +1,8 @@ +SOURCES += ../View/mainwindow.py\ + ../Translation/constant_string.py\ + +TRANSLATIONS += en2fr.ts + +CODECFORTR = UTF-8 + +CODECFORSRC = UTF-8 diff --git a/Translation/en2fr.qm b/Translation/en2fr.qm new file mode 100755 index 0000000..678e833 Binary files /dev/null and b/Translation/en2fr.qm differ diff --git a/Translation/en2fr.ts b/Translation/en2fr.ts new file mode 100755 index 0000000..16dea95 --- /dev/null +++ b/Translation/en2fr.ts @@ -0,0 +1,569 @@ + + + + + Acoustic data tab + + + Acoustic data + Données acoustiques + + + + CCNSTANT_STRING + + + Plot total concentration + Tracé concentration totale + + + + CONSANT_STRING + + + Noise level + Niveau de bruit + + + + CONSTANT_STRING + + + Cell size + Taille cellule + + + + Size of the cells in m + Taille de la cellule en m + + + + Date + Date + + + + Date of measurements + Date des mesures sur le terrain + + + + Frequency + Fréquence + + + + Frequency in MHz + Fréquence en MHz + + + + Gain Rx + Gain Rx + + + + Gain at reception in dB + Gain en réception en dB + + + + Gain Tx + Gain Tx + + + + Gain at emission in dB + Gain à l'émission en dB + + + + Hour + Heure + + + + Hour of measurements + Heure des mesures sur le terrain + + + + Kt + Kt + + + + Kt constant + Constante Kt + + + + Nb cells + Nb cellules + + + + Number of cells along one profile + Nombre de cellules le long d'un profil + + + + Nb pings/sec + Nb echo/sec + + + + Number of pings per seconds, in Hz + Nombre d'écho par secondes en Hz + + + + Nb pings averaged/profile + Nb echo moyen/profil + + + + Number of pings averaged in one profile + Nombre d'écho moyénné sur un profil + + + + Nb profiles + Nb profils + + + + Number of profiles + Nombre de profils + + + + Nb profiles/sec + Nb profil/sec + + + + Number of profiles per seconds + Nombre de profil /secondes + + + + Pulse length + Durée écho + + + + Lenght of the pulse in seconds + Durée de l'écho acoustique par secondes + + + + Acoustic file + Fichier acoustique + + + + Display options + Options d'affichage + + + + Export table + Exporter tableau + + + + From + De + + + + GPS file + Fichier GPS + + + + Initial depth range + Intervalle initial de profondeur + + + + Measurements information + Information mesures + + + + Noise file + Fichier bruit + + + + Plot bottom + Tracé du fond + + + + Plot bottom of cross section + Tracé du fond de la section + + + + Plot x_axis in space + Tracé en espace de l'axe des abscisses + + + + Plot x_axis in time + Tracé en temps de l'axe des abscisses + + + + Plot transect + Tracé section + + + + Raw acoustic data 2D field + Champ 2D des données acoustiques brutes + + + + Signal to noise Ratio 2D field + Champ 2D du rapport signal sur bruit + + + + Table of values + Tableau de valeurs + + + + Time offset + Ecart en temps + + + + to + à + + + + Plot SNR + Tracé Signal/Bruit + + + + Synchronize && Fill table + Synchroniser & Compléter tableau + + + + Acoustic profile + Profile acoustique + + + + Averaged profile + Profile moyen + + + + cells + cellules + + + + Computing water attenuation + Calcul atténuation de l'eau + + + + Despiking + Filtrer les pics + + + + Display profile position + Visualisation position du profil + + + + FCB options + Options FCB + + + + FCB profile + Profil FCB + + + + Fit regression line + Ajuster la ligne de régression + + + + For homogeneous suspension + Pour une suspension homogène + + + + Horizontal + Horizontale + + + + Load data from acoustic data tab + Importer les données de l'onglet données acoustiques + + + + Post processing + Post traitement + + + + Profile + Profil + + + + Rayleigh criterion + Critère de Rayleigh + + + + SNR criterion + Critère du SNR + + + + Subtract the noise + Soustraire le bruit + + + + Temperature + Temperature + + + + Vertical + Verticale + + + + Window size + Taille fenêtre + + + + Check all + Tout sélectionner + + + + Class distribution + Distribution par classe + + + + Cumulative distribution + Distribution cumulée + + + + Distribution plot + Tracé des distributions + + + + Download + Importer + + + + Experimental data + + + + + Fill table + Compléter tableau + + + + Fine_sediments + Sédiments fins + + + + Options + Options + + + + Plot sample position + Tracé position échantillon + + + + Sand sediments + Sables + + + + Total concentration + Concentration totale + + + + Total concentration plot + Tracé concentration totale + + + + Vertical profile for calibration + Profil vertical pour calibration + + + + Fine sediments + Sédiments fins + + + + Particle size distribution file + Fichier distribution granulométrie + + + + Noise level + Niveau de bruit + + + + Plot total concentration + Tracé concentration totale + + + + Acoustic inversion options + Options pour l'inversion acoustique + + + + Fine and sand sediments concentration 2D field + Champ 2D de concentration des sédiments fins et sables + + + + Suspended sediment concentration plot : acoustic inversion theory VS measurements + Tracé concentration sédiments en suspension : théorie inversion acoustique VS mesures + + + + MainWindow + + + MainWindow + Fenêtre principale + + + + Acoustic data + Données acoustiques + + + + Signal processing + Traitement du signal + + + + Sample data + Données échantillons + + + + Acoustic inversion + Inversion acoustique + + + + Note + Observations + + + + User manual + Manuel d'utilisateur + + + + File + Fichier + + + + Settings + Paramètres + + + + Language + Langues + + + + Tools + Outils + + + + toolBar + Barre d'outils + + + + New + Nouveau + + + + Open + Ouvrir + + + + Save + Enregistrer + + + + Copy + Copier + + + + Cut + Couper + + + + Paste + Coller + + + + English + Anglais + + + + French + Français + + + diff --git a/View/acoustic_data_tab.py b/View/acoustic_data_tab.py index 4793f56..bc9db1d 100644 --- a/View/acoustic_data_tab.py +++ b/View/acoustic_data_tab.py @@ -914,6 +914,7 @@ class AcousticDataTab(QWidget): self.scroll_SNR.setWidget(self.canvas_SNR) self.scroll_SNR.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scroll_SNR.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) + self.scroll_SNR.setAlignment(Qt.AlignCenter) self.verticalLayout_groupbox_transect_2Dplot_snr_data.addWidget(self.scroll_SNR) # self.spinbox_tmin.setValue(np.min(noise_data._time_snr)) diff --git a/View/sample_data_tab.py b/View/sample_data_tab.py index 1bb1f44..ed9e406 100644 --- a/View/sample_data_tab.py +++ b/View/sample_data_tab.py @@ -7,6 +7,8 @@ from PyQt5.QtCore import Qt, QCoreApplication, pyqtSignal, pyqtSlot import numpy as np import pandas as pd +import itertools + import matplotlib.pyplot as plt from matplotlib.colors import CSS4_COLORS, LogNorm from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas @@ -21,6 +23,8 @@ from View.checkable_combobox import CheckableComboBox import Translation.constant_string as cs +import settings as stg + _translate = QCoreApplication.translate @@ -168,7 +172,7 @@ class SampleDataTab(QWidget): self.verticalLayout_groupbox_plot_sample_position = QVBoxLayout(self.groupbox_plot_sample_position) - self.canvas_transect_sample_position = None + self.canvas_plot_sample_position_on_transect = None # if self.canvas_transect_sample_position @@ -184,9 +188,19 @@ class SampleDataTab(QWidget): self.verticalLayout_groupbox_display_option = QVBoxLayout(self.groupbox_display_option) - # self.pushbutton_plot_transect = QPushButton() - # self.pushbutton_plot_transect.setText("Plot transect to visualise sample position") - # self.verticalLayout_groupbox_display_option.addWidget(self.pushbutton_plot_transect) + self.horizontalLayout_pushbutton_combobox_transect = QHBoxLayout() + self.verticalLayout_groupbox_display_option.addLayout(self.horizontalLayout_pushbutton_combobox_transect) + + self.pushbutton_plot_transect = QPushButton() + self.pushbutton_plot_transect.setText("Plot transect to visualise sample position") + self.horizontalLayout_pushbutton_combobox_transect.addWidget(self.pushbutton_plot_transect) + + self.pushbutton_plot_transect.clicked.connect(self.plot_sample_position_on_transect) + + self.combobox_frequencies = QComboBox() + self.horizontalLayout_pushbutton_combobox_transect.addWidget(self.combobox_frequencies) + + self.combobox_frequencies.currentTextChanged.connect(self.update_plot_sample_position_on_transect) self.horizontalLayout_Ctot_PSD_plot = QHBoxLayout() self.verticalLayout_groupbox_display_option.addLayout(self.horizontalLayout_Ctot_PSD_plot) @@ -343,40 +357,67 @@ class SampleDataTab(QWidget): filename_fine_sediment = QFileDialog.getOpenFileName(self, "Open file", "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Granulo_data", "Fine sediment file (*.xls, *.ods)") - path_name = path.dirname(filename_fine_sediment[0]) - file_name = path.basename(filename_fine_sediment[0]) - self.lineEdit_fine_sediment.setText(file_name) - self.lineEdit_fine_sediment.setToolTip(path_name) - return filename_fine_sediment[0] + stg.fine_sediment_path = path.dirname(filename_fine_sediment[0]) + stg.fine_sediment_filename = path.basename(filename_fine_sediment[0]) + self.load_fine_sediment_data() + self.lineEdit_fine_sediment.setText(stg.fine_sediment_filename) + self.lineEdit_fine_sediment.setToolTip(stg.fine_sediment_path) # --- Function to select directory and file name of sand sediments sample data --- def open_dialog_box_sand_sediment(self): filename_sand_sediment = QFileDialog.getOpenFileName(self, "Open file", "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data/Granulo_data", "Sand sediment file (*.xls, *.ods)") - path_name = path.dirname(filename_sand_sediment[0]) - file_name = path.basename(filename_sand_sediment[0]) - self.lineEdit_sand.setText(file_name) - self.lineEdit_sand.setToolTip(path_name) - return filename_sand_sediment[0] + stg.sand_sediment_path = path.dirname(filename_sand_sediment[0]) + stg.sand_sediment_filename = path.basename(filename_sand_sediment[0]) + self.load_sand_sediment_data() + + self.lineEdit_sand.setText(stg.sand_sediment_filename) + self.lineEdit_sand.setToolTip(stg.sand_sediment_path) + + def load_fine_sediment_data(self): + fine_granulo_data = GranuloLoader(stg.fine_sediment_path + "/" + stg.fine_sediment_filename) + stg.fine_sediment_columns = fine_granulo_data._data.columns + stg.sample_time = fine_granulo_data._time + stg.sample_distance_from_bank = fine_granulo_data._y + stg.sample_depth = fine_granulo_data._z + stg.radius_grain = fine_granulo_data._r_grain + stg.Ctot_fine = fine_granulo_data._Ctot + stg.D50_fine = fine_granulo_data._D50 + stg.frac_vol_fine = fine_granulo_data._frac_vol + stg.frac_vol_fine_cumul = fine_granulo_data._frac_vol_cumul + + def load_sand_sediment_data(self): + sand_granulo_data = GranuloLoader(stg.sand_sediment_path + "/" + stg.sand_sediment_filename) + stg.sand_sediment_columns = sand_granulo_data._data.columns + stg.sample_time = sand_granulo_data._time + stg.sample_distance_from_bank = sand_granulo_data._y + stg.sample_depth = sand_granulo_data._z + stg.radius_grain = sand_granulo_data._r_grain + stg.Ctot_sand = sand_granulo_data._Ctot + stg.D50_sand = sand_granulo_data._D50 + stg.frac_vol_sand = sand_granulo_data._frac_vol + stg.frac_vol_sand_cumul = sand_granulo_data._frac_vol_cumul + + def compute_Ctot_per_cent(self): + stg.Ctot_fine_per_cent = 100 * stg.Ctot_fine / (stg.Ctot_fine + stg.Ctot_sand) + stg.Ctot_sand_per_cent = 100 * stg.Ctot_sand / (stg.Ctot_fine + stg.Ctot_sand) # ------------------------------------------------------------------------------------------------------------------ # --- Function to fill table of values --- def fill_table(self): - if self.lineEdit_fine_sediment.text(): - # print("push button", self.pushbutton_fill_table.isChecked()) - # print("self.lineEdit_fine_sediment.text() ", self.lineEdit_fine_sediment.toolTip() + "/" + self.lineEdit_fine_sediment.text()) - # print("self.lineEdit_sand.text() ", self.lineEdit_sand.toolTip() + "/" + self.lineEdit_sand.text()) - granulo_data = deepcopy( - GranuloLoader(self.lineEdit_fine_sediment.toolTip() + "/" + self.lineEdit_fine_sediment.text(), - self.lineEdit_sand.toolTip() + "/" + self.lineEdit_sand.text())) - self.row = self.tableWidget_sample.setRowCount(granulo_data._data_fine.shape[0]) - self.col = self.tableWidget_sample.setColumnCount(2*granulo_data._data_fine.shape[1]) + if (self.lineEdit_fine_sediment.text()) and (self.lineEdit_sand.text()): + + self.row = self.tableWidget_sample.setRowCount(stg.sample_depth.shape[0]) + self.col = self.tableWidget_sample.setColumnCount(8+2*stg.radius_grain.shape[0]) # --- Set horizontal header --- - horizontal_header = list(map(str, ["Color", "Sample"] + granulo_data._data_fine.columns.values.tolist() + - granulo_data._data_sand.columns.values.tolist()[2:])) - # print(len(horizontal_header)) + # horizontal_header = list(map(str, ["Color", "Sample"] + stg.fine_sediment_columns + + # stg.sand_sediment_columns[2:])) + horizontal_header = list(itertools.chain(["Color", "Sample"], + list(map(str, stg.fine_sediment_columns.values)), + list(map(str, stg.sand_sediment_columns[2:])))) + for horizontal_header_text in horizontal_header: # print(horizontal_header_text) self.horizontal_header_item = QTableWidgetItem() @@ -398,6 +439,8 @@ class SampleDataTab(QWidget): f"connect(self.update_plot_total_concentration)") eval(f"self.comboBox_sample_table{i}.currentTextChanged." f"connect(self.update_plot_PSD_fine_and_sand_sediments)") + eval(f"self.comboBox_sample_table{i}.currentTextChanged." + f"connect(self.update_plot_sample_position_on_transect)") # --- Fill Sample column with checkbox --- for i in range(self.tableWidget_sample.rowCount()): @@ -408,19 +451,19 @@ class SampleDataTab(QWidget): # print(f"S{i+1} ", self.tableWidget_sample.item(i, 1).checkState()) # --- Fill table with data --- - for i in range(granulo_data._frac_vol_fine.shape[0]): - for j in range(granulo_data._frac_vol_fine.shape[1]): + for i in range(stg.frac_vol_fine.shape[0]): + for j in range(stg.frac_vol_fine.shape[1]): # self.tableWidget_sample.setItem(i, j + 2, QTableWidgetItem(str(granulo_data._data_fine.iloc[i, j]))) - self.tableWidget_sample.setItem(i, 2, QTableWidgetItem(str(granulo_data._y[i]))) - self.tableWidget_sample.setItem(i, 3, QTableWidgetItem(str(granulo_data._z[i]))) + self.tableWidget_sample.setItem(i, 2, QTableWidgetItem(str(stg.sample_time[i]))) + self.tableWidget_sample.setItem(i, 3, QTableWidgetItem(str(stg.sample_depth[i]))) - self.tableWidget_sample.setItem(i, 4, QTableWidgetItem(str(granulo_data._Ctot_fine[i]))) - self.tableWidget_sample.setItem(i, 5, QTableWidgetItem(str(granulo_data._D50_fine[i]))) - self.tableWidget_sample.setItem(i, j + 6, QTableWidgetItem(str(granulo_data._frac_vol_fine[i, j]))) + self.tableWidget_sample.setItem(i, 4, QTableWidgetItem(str(stg.Ctot_fine[i]))) + self.tableWidget_sample.setItem(i, 5, QTableWidgetItem(str(stg.D50_fine[i]))) + self.tableWidget_sample.setItem(i, j + 6, QTableWidgetItem(str(stg.frac_vol_fine[i, j]))) - self.tableWidget_sample.setItem(i, granulo_data._frac_vol_fine.shape[1] + 6, QTableWidgetItem(str(granulo_data._Ctot_sand[i]))) - self.tableWidget_sample.setItem(i, granulo_data._frac_vol_fine.shape[1] + 7, QTableWidgetItem(str(granulo_data._D50_sand[i]))) - self.tableWidget_sample.setItem(i, granulo_data._frac_vol_fine.shape[1] + 8 + j, QTableWidgetItem(str(granulo_data._frac_vol_sand[i, j]))) + self.tableWidget_sample.setItem(i, stg.frac_vol_fine.shape[1] + 6, QTableWidgetItem(str(stg.Ctot_sand[i]))) + self.tableWidget_sample.setItem(i, stg.frac_vol_fine.shape[1] + 7, QTableWidgetItem(str(stg.D50_sand[i]))) + self.tableWidget_sample.setItem(i, stg.frac_vol_fine.shape[1] + 8 + j, QTableWidgetItem(str(stg.frac_vol_sand[i, j]))) # --- Connect checkbox to all checkboxes of tableWidget --- # self.allChkBox.stateChanged.connect(self.check_allChkBox) @@ -430,6 +473,7 @@ class SampleDataTab(QWidget): self.extract_position_list_and_color_list_from_table_checkboxes) self.tableWidget_sample.itemChanged.connect(self.update_plot_total_concentration) self.tableWidget_sample.itemChanged.connect(self.update_plot_PSD_fine_and_sand_sediments) + self.tableWidget_sample.itemChanged.connect(self.update_plot_sample_position_on_transect) else: # print("PLease download first file") @@ -468,9 +512,6 @@ class SampleDataTab(QWidget): # ------------------------------------------------------------------------------------------------------------------ # --- Functions to plot samples positions on transect --- - # def empty_field_for_transect_plot(self): - # self.axis_sample_position.set_xticks([]) - # self.axis_sample_position.set_yticks([]) # def update_plots_from_table_checkboxes(self): # # color_value_row = self.tableWidget_sample.currentRow() @@ -557,41 +598,91 @@ class SampleDataTab(QWidget): # self.axis_sampleposition.set_xticks([]) # self.axis_sampleposition.set_yticks([]) # self.figure_sampleposition.canvas.draw_idle() - # - # def update_plot_transect_bottom_with_sample_position(self, position_value, color_list): - # frequency = self.model.Freq[0] - # val_min = 0 # np.nanmin(self.model.BS_averaged_cross_section_corr.V[:, 0, :]) - # val_max = np.nanmax(self.model.BS_averaged_cross_section_corr.V[:, 0, :]) - # if val_min == 0: - # val_min = 1e-5 - # # if val_min == 0: - # # val_min = 1e-5 - # # self.axis_sampleposition.imshow(np.asarray(np.array(self.model.V[:, 0, :2300], dtype=float)), aspect='auto', - # # extent=[0, 2300, self.model.depth[-1][0], self.model.depth[0][0]], - # # cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) - # self.axis_sampleposition.cla() - # self.plot_transect_bottom_with_sample_position() - # self.axis_sampleposition.pcolormesh(self.model.dist_BS_section, - # np.flipud(self.model.BS_raw_cross_section.r), - # self.model.BS_averaged_cross_section_corr.V[:, 0, :], - # cmap='viridis', - # norm=LogNorm(vmin=val_min, vmax=val_max), shading='gouraud') - # self.axis_sampleposition.plot(self.model.dist_BS_section, - # np.max(self.model.r_bottom_cross_section) - self.model.r_bottom_cross_section - # + np.min(self.model.r_bottom_cross_section), - # color='k', linewidth=2) - # # marker_color = ["orange", "green"] - # # for i in range(len(marker_color)): - # self.axis_sampleposition.scatter(self.model._fine_sediment_file.iloc[position_value]["y"], - # np.max(self.model.r_bottom_cross_section) - self.model._fine_sediment_file.iloc[position_value]["z"] - # + np.min(self.model.r_bottom_cross_section), - # linestyle='None', marker="o", s=14, c=color_list) - # # markerfacecolor=["orange", "green"], markeredgecolor=["orange", "green"]) - # # self.axis_sampleposition.set_axis_off() - # self.axis_sampleposition.set_xticks([]) - # self.axis_sampleposition.set_yticks([]) - # self.figure_sampleposition.canvas.draw_idle() - # # self.figure_sampleposition.tight_layout() + + def plot_sample_position_on_transect(self): + + self.combobox_frequencies.addItems(stg.freq_text) + + self.canvas_plot_sample_position_on_transect = FigureCanvas() + 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.addWidget(self.canvas_plot_sample_position_on_transect) + + val_min = np.min(stg.BS_data[:, stg.freq_bottom_detection, :]) + val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :]) + if val_min == 0: + val_min = 1e-5 + + self.axis_plot_sample_position_on_transect.pcolormesh( + stg.t, -stg.r, stg.BS_data[:, 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.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_sample_position_on_transect(self): + + # --- Read selected samples (checkboxes) --- + position_list, color_list = self.extract_position_list_and_color_list_from_table_checkboxes() + + # --- Create canvas of Matplotlib figure --- + if self.canvas_plot_sample_position_on_transect != None: + + val_min = np.min(stg.BS_data[:, stg.freq_bottom_detection, :]) + val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :]) + if val_min == 0: + val_min = 1e-5 + + self.axis_plot_sample_position_on_transect.pcolormesh( + stg.t, -stg.r, stg.BS_data[:, self.combobox_frequencies.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.r_bottom, color='black', linewidth=1, linestyle="solid") + + self.axis_plot_sample_position_on_transect.scatter(stg.sample_time[position_list], + stg.sample_depth[position_list], + linestyle='None', marker="o", s=14, c=color_list) + # self.axis_transect_sample_position.scatter(granulo_data._y[position_list], granulo_data._z + # self.model._fine_sediment_file.iloc[position_list]["y"], + # np.max(self.model.r_bottom_cross_section) - + # self.model._fine_sediment_file.iloc[position_list]["z"] + # + np.min(self.model.r_bottom_cross_section), + # linestyle='None', marker="o", s=14, c=color_list) + + 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() + + # self.plot_transect_bottom_with_sample_position() + # self.axis_sampleposition.pcolormesh(self.model.dist_BS_section, + # np.flipud(self.model.BS_raw_cross_section.r), + # self.model.BS_averaged_cross_section_corr.V[:, 0, :], + # cmap='viridis', + # norm=LogNorm(vmin=val_min, vmax=val_max), shading='gouraud') + # self.axis_sampleposition.plot(self.model.dist_BS_section, + # np.max(self.model.r_bottom_cross_section) - self.model.r_bottom_cross_section + # + np.min(self.model.r_bottom_cross_section), + # color='k', linewidth=2) + # marker_color = ["orange", "green"] + # for i in range(len(marker_color)): + # self.axis_sampleposition.scatter(self.model._fine_sediment_file.iloc[position_list]["y"], + # np.max(self.model.r_bottom_cross_section) - self.model._fine_sediment_file.iloc[position_list]["z"] + # + np.min(self.model.r_bottom_cross_section), + # linestyle='None', marker="o", s=14, c=color_list) + # markerfacecolor=["orange", "green"], markeredgecolor=["orange", "green"]) + # self.axis_sampleposition.set_axis_off() + # self.axis_sampleposition.set_xticks([]) + # self.axis_sampleposition.set_yticks([]) + # self.figure_sampleposition.canvas.draw_idle() + # self.figure_sampleposition.tight_layout() # ------------------------------------------------------------------------------------------------------------------ # --- Functions to plot total concentration --- @@ -604,14 +695,11 @@ class SampleDataTab(QWidget): def update_plot_total_concentration(self): if self.tableWidget_sample.columnCount() > 15: - # --- Read sample data --- - granulo_data = deepcopy( - GranuloLoader(self.lineEdit_fine_sediment.toolTip() + "/" + self.lineEdit_fine_sediment.text(), - self.lineEdit_sand.toolTip() + "/" + self.lineEdit_sand.text())) - # --- Read selected samples (checkboxes) --- position_list, color_list = self.extract_position_list_and_color_list_from_table_checkboxes() + self.compute_Ctot_per_cent() + if position_list == []: msgBox = QMessageBox() @@ -654,38 +742,50 @@ class SampleDataTab(QWidget): # self.canvas_total_concentration.draw() if (self.combobox_x_axis.currentIndex() == 0) and (self.combobox_y_axis.currentIndex() == 0): - self.axis_total_concentration.scatter(granulo_data._Ctot_fine[position_list], - granulo_data._z[position_list], + self.axis_total_concentration.scatter(stg.Ctot_fine[position_list], + stg.sample_depth[position_list], s=100, facecolor=color_list, edgecolor="None", alpha=0.5) - self.axis_total_concentration.scatter(granulo_data._Ctot_sand[position_list], - granulo_data._z[position_list], + self.axis_total_concentration.scatter(stg.Ctot_sand[position_list], + stg.sample_depth[position_list], s=300, facecolors="None", edgecolors=color_list) self.axis_total_concentration.set_xlabel(self.combobox_x_axis.currentText()) self.axis_total_concentration.set_ylabel(self.combobox_y_axis.currentText()) elif (self.combobox_x_axis.currentIndex() == 0) and (self. combobox_y_axis.currentIndex() == 1): - self.axis_total_concentration.scatter(granulo_data._Ctot_fine[position_list], - granulo_data._z[position_list] / np.max(granulo_data._z[position_list]), + indices = [] + for i in position_list: + print(i) + print(np.where(stg.t == stg.sample_time[i])[0][0]) + indices.append(np.where(stg.t == stg.sample_time[i])[0][0]) + print("indices : ", indices) + self.axis_total_concentration.scatter(stg.Ctot_fine[position_list], + -stg.sample_depth[position_list] / stg.r_bottom[indices], #np.max(stg.sample_depth[position_list]), s=100, facecolor=color_list, edgecolor="None", alpha=0.5) - self.axis_total_concentration.scatter(granulo_data._Ctot_sand[position_list], - granulo_data._z[position_list] / np.max(granulo_data._z[position_list]), + self.axis_total_concentration.scatter(stg.Ctot_sand[position_list], + -stg.sample_depth[position_list] / stg.r_bottom[indices], #np.max(stg.sample_depth[position_list]), s=300, facecolors="None", edgecolors=color_list) self.axis_total_concentration.set_xlabel(self.combobox_x_axis.currentText()) self.axis_total_concentration.set_ylabel(self.combobox_y_axis.currentText()) elif (self.combobox_x_axis.currentIndex() == 1) and (self. combobox_y_axis.currentIndex() == 0): - self.axis_total_concentration.scatter(granulo_data._Ctot_fine_per_cent[position_list], - granulo_data._z[position_list], + self.axis_total_concentration.scatter(stg.Ctot_fine_per_cent[position_list], + stg.sample_depth[position_list], s=100, facecolor=color_list, edgecolor="None", alpha=0.5) - self.axis_total_concentration.scatter(granulo_data._Ctot_sand_per_cent[position_list], - granulo_data._z[position_list], + self.axis_total_concentration.scatter(stg.Ctot_sand_per_cent[position_list], + stg.sample_depth[position_list], s=300, facecolors="None", edgecolors=color_list) self.axis_total_concentration.set_xlabel(self.combobox_x_axis.currentText()) self.axis_total_concentration.set_ylabel(self.combobox_y_axis.currentText()) elif (self.combobox_x_axis.currentIndex() == 1) and (self. combobox_y_axis.currentIndex() == 1): - self.axis_total_concentration.scatter(granulo_data._Ctot_fine_per_cent[position_list], - granulo_data._z[position_list] / np.max(granulo_data._z[position_list]), + indices = [] + for i in position_list: + print(i) + print(np.where(stg.t == stg.sample_time[i])[0][0]) + indices.append(np.where(stg.t == stg.sample_time[i])[0][0]) + print("indices : ", indices) + self.axis_total_concentration.scatter(stg.Ctot_fine_per_cent[position_list], + -stg.sample_depth[position_list] / stg.r_bottom[indices], #np.max(stg.sample_depth[position_list]), s=100, facecolor=color_list, edgecolor="None", alpha=0.5) - self.axis_total_concentration.scatter(granulo_data._Ctot_sand_per_cent[position_list], - granulo_data._z[position_list] / np.max(granulo_data._z[position_list]), + self.axis_total_concentration.scatter(stg.Ctot_sand_per_cent[position_list], + -stg.sample_depth[position_list] / stg.r_bottom[indices], #np.max(stg.sample_depth[position_list]), s=300, facecolors="None", edgecolors=color_list) self.axis_total_concentration.set_xlabel(self.combobox_x_axis.currentText()) self.axis_total_concentration.set_ylabel(self.combobox_y_axis.currentText()) @@ -819,11 +919,6 @@ class SampleDataTab(QWidget): def update_plot_PSD_fine_and_sand_sediments(self): if self.tableWidget_sample.columnCount() > 15: - # --- Read sample data --- - granulo_data = deepcopy( - GranuloLoader(self.lineEdit_fine_sediment.toolTip() + "/" + self.lineEdit_fine_sediment.text(), - self.lineEdit_sand.toolTip() + "/" + self.lineEdit_sand.text())) - # --- Read selected samples (checkboxes) --- position_list, color_list = self.extract_position_list_and_color_list_from_table_checkboxes() @@ -850,15 +945,15 @@ class SampleDataTab(QWidget): if self.combobox_PSD_plot.currentIndex() == 0: for profil_position_num, color_plot in zip(position_list, color_list): - self.axis_plot_PSD[0].plot(granulo_data._r_grain, - granulo_data._frac_vol_fine[profil_position_num, :], + self.axis_plot_PSD[0].plot(stg.radius_grain, + stg.frac_vol_fine[profil_position_num, :], color=color_plot) self.axis_plot_PSD[0].set_xscale('log') self.axis_plot_PSD[0].set_xlabel('Radius ($\mu m$)') self.axis_plot_PSD[0].set_ylabel('Class size volume fraction') - self.axis_plot_PSD[1].plot(granulo_data._r_grain, - granulo_data._frac_vol_sand[profil_position_num, :], + self.axis_plot_PSD[1].plot(stg.radius_grain, + stg.frac_vol_sand[profil_position_num, :], color=color_plot) self.axis_plot_PSD[1].set_xscale('log') self.axis_plot_PSD[1].set_xlabel('Radius ($\mu m$)') @@ -867,15 +962,15 @@ class SampleDataTab(QWidget): elif self.combobox_PSD_plot.currentIndex() == 1: for profil_position_num, color_plot in zip(position_list, color_list): - self.axis_plot_PSD[0].plot(granulo_data._r_grain, - granulo_data._frac_vol_fine_cumul[profil_position_num, :], + self.axis_plot_PSD[0].plot(stg.radius_grain, + stg.frac_vol_fine_cumul[profil_position_num, :], color=color_plot) self.axis_plot_PSD[0].set_xscale('log') self.axis_plot_PSD[0].set_xlabel('Radius ($\mu m$)') self.axis_plot_PSD[0].set_ylabel('Cumulative size volume fraction') - self.axis_plot_PSD[1].plot(granulo_data._r_grain, - granulo_data._frac_vol_sand_cumul[profil_position_num, :], + self.axis_plot_PSD[1].plot(stg.radius_grain, + stg.frac_vol_sand_cumul[profil_position_num, :], color=color_plot) self.axis_plot_PSD[1].set_xscale('log') self.axis_plot_PSD[1].set_xlabel('Radius ($\mu m$)') diff --git a/View/signal_processing_tab.py b/View/signal_processing_tab.py index ec69cd1..50aa9d3 100644 --- a/View/signal_processing_tab.py +++ b/View/signal_processing_tab.py @@ -6,6 +6,7 @@ from PyQt5.QtGui import QFont, QIcon, QPixmap from PyQt5.QtCore import Qt, QCoreApplication import numpy as np +from copy import deepcopy import matplotlib.pyplot as plt from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas @@ -84,9 +85,9 @@ class SignalProcessingTab(QWidget): self.pushbutton_load_data.clicked.connect(self.plot_profile_position_on_transect) self.pushbutton_load_data.clicked.connect(self.plot_profiles) - self.pushbutton_plot_bottom_line = QPushButton() - self.pushbutton_plot_bottom_line.setText("Plot bottom line") - self.horizontalLayout_pushbutton_load_data_plot_bottom_line.addWidget(self.pushbutton_plot_bottom_line) + self.combobox_frequency = QComboBox() + self.horizontalLayout_pushbutton_load_data_plot_bottom_line.addWidget(self.combobox_frequency) + self.combobox_frequency.currentTextChanged.connect(self.update_plot_profile_position_on_transect) # +++++++++++++++++++++++++++++++++++++++++++++++++ # +++ --- GroupBox Display Profile Position --- +++ @@ -100,7 +101,7 @@ class SignalProcessingTab(QWidget): # self.label_profile_number.setText("Profile 1 / " + str(stg.nb_profiles)) self.verticalLayout_groupbox_display_profile_position.addWidget(self.label_profile_number) - self.canvas_profile_position_on_transect = None + self.canvas_plot_profile_position_on_transect = None # self.figure_plot_profile_position_on_transect, self.axis_plot_profile_position_on_transect = \ # plt.subplots(nrows=1, ncols=1, layout="constrained") @@ -161,20 +162,28 @@ class SignalProcessingTab(QWidget): self.gridLayout_groupbox_acoustic_profile = QGridLayout(self.groupbox_acoustic_profile) - self.checkbox_substract_noise = QCheckBox() - self.gridLayout_groupbox_acoustic_profile.addWidget(self.checkbox_substract_noise, 0, 0, 1, 1) - - self.checkbox_substract_noise.clicked.connect(self.update_plot_profiles) - self.checkbox_SNR_criterion = QCheckBox() - self.gridLayout_groupbox_acoustic_profile.addWidget(self.checkbox_SNR_criterion, 1, 0, 1, 1) + self.gridLayout_groupbox_acoustic_profile.addWidget(self.checkbox_SNR_criterion, 0, 0, 1, 1) self.spinbox_SNR_criterion = QSpinBox() self.spinbox_SNR_criterion.setRange(0, 9999) self.spinbox_SNR_criterion.setValue(0) - self.gridLayout_groupbox_acoustic_profile.addWidget(self.spinbox_SNR_criterion, 1, 1, 1, 1) + self.spinbox_SNR_criterion.setDisabled(True) + self.gridLayout_groupbox_acoustic_profile.addWidget(self.spinbox_SNR_criterion, 0, 1, 1, 1) - self.checkbox_SNR_criterion.clicked.connect(self.update_plot_profiles) - self.spinbox_SNR_criterion.valueChanged.connect(self.update_plot_profiles) + self.checkbox_SNR_criterion.clicked.connect(self.enable_disable_spinbox_snr_value) + + self.pushbutton_snr_filter = QPushButton() + self.pushbutton_snr_filter.setText("Apply SNR") + self.pushbutton_snr_filter.setDisabled(True) + self.gridLayout_groupbox_acoustic_profile.addWidget(self.pushbutton_snr_filter, 0, 2, 1, 1) + + self.spinbox_SNR_criterion.valueChanged.connect(self.remove_point_with_snr_filter) + # self.spinbox_SNR_criterion.valueChanged.connect(self.update_plot_profiles) + # self.spinbox_SNR_criterion.valueChanged.connect(self.update_plot_profile_position_on_transect) + + self.pushbutton_snr_filter.clicked.connect(self.update_plot_profiles) + # self.pushbutton_snr_filter.clicked.connect(self.remove_point_with_snr_filter) + # self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile_position_on_transect) # --- Groupbox Window size --- @@ -573,7 +582,7 @@ class SignalProcessingTab(QWidget): self.groupbox_post_processing.setTitle(_translate("CONSTANT_STRING", cs.POST_PROCESSING)) self.groupbox_acoustic_profile.setTitle(_translate("CONSTANT_STRING", cs.ACOUSTIC_PROFILE)) - self.checkbox_substract_noise.setText(_translate("CONSTANT_STRING", cs.SUBTRACT_THE_NOISE)) + # self.checkbox_substract_noise.setText(_translate("CONSTANT_STRING", cs.SUBTRACT_THE_NOISE)) self.checkbox_SNR_criterion.setText(_translate("CONSTANT_STRING", cs.SNR_CRITERION)) # self.groupbox_window_size.setTitle(_translate("CONSTANT_STRING", cs.WINDOW_SIZE)) @@ -612,77 +621,146 @@ class SignalProcessingTab(QWidget): def update_lineEdit_by_moving_slider(self): self.lineEdit_slider.setText(str(self.slider.value())) + def enable_disable_spinbox_snr_value(self): + if self.checkbox_SNR_criterion.isChecked(): + self.spinbox_SNR_criterion.setEnabled(True) + self.pushbutton_snr_filter.setEnabled(True) + else: + self.spinbox_SNR_criterion.setDisabled(True) + self.pushbutton_snr_filter.setDisabled(True) + + def remove_point_with_snr_filter(self): + + stg.BS_data_filter_snr = deepcopy(stg.BS_data) + print("Before : ", np.sum(np.isnan(stg.BS_data_filter_snr[:, 0, :]))) + for f in range(stg.freq.shape[0]): + stg.BS_data_filter_snr[np.where(stg.SNR_data[:, 0, :] < self.spinbox_SNR_criterion.value())[0], + f, + np.where(stg.SNR_data[:, 0, :] < self.spinbox_SNR_criterion.value())[1]] \ + = np.nan + print("After : ", np.sum(np.isnan(stg.BS_data_filter_snr[:, 0, :]))) + def plot_profile_position_on_transect(self): + + self.combobox_frequency.addItems(stg.freq_text) + self.slider.setMaximum(stg.t.shape[0]) self.label_profile_number.clear() self.label_profile_number.setText("Profile " + str(self.slider.value()) + " / " + str(self.slider.maximum())) - self.canvas_profile_position_on_transect = FigureCanvas() + self.canvas_plot_profile_position_on_transect = FigureCanvas() self.figure_plot_profile_position_on_transect, self.axis_plot_profile_position_on_transect = \ plt.subplots(nrows=1, ncols=1, layout="constrained") self.canvas_plot_profile_position_on_transect = FigureCanvas(self.figure_plot_profile_position_on_transect) self.verticalLayout_groupbox_display_profile_position.addWidget(self.canvas_plot_profile_position_on_transect) + if stg.r_bottom.size == 0: - val_min = np.min(stg.BS_data[:, stg.freq_bottom_detection, :]) - val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :]) - if val_min == 0: - val_min = 1e-5 + val_min = np.min(stg.BS_data[:, stg.freq_bottom_detection, :]) + val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :]) + if val_min == 0: + val_min = 1e-5 - pcm = self.axis_plot_profile_position_on_transect.pcolormesh( - stg.t, -stg.r, stg.BS_data[:, stg.freq_bottom_detection, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + pcm = self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t, -stg.r, stg.BS_data[:, stg.freq_bottom_detection, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + + if stg.r_bottom.size != 0: + self.axis_plot_profile_position_on_transect.plot( + stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid") - if stg.r_bottom.size != 0: self.axis_plot_profile_position_on_transect.plot( - stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid") + stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r, + color='red', linestyle="solid", linewidth=2) - self.axis_plot_profile_position_on_transect.plot( - stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r, - color='red', linestyle="solid", linewidth=2) + self.figure_plot_profile_position_on_transect.canvas.draw_idle() - self.canvas_plot_profile_position_on_transect.draw() + else: - # def BS_signal_filtered(self): - # noise = np.zeros(acoustic_data._BS_raw_data.shape) - # for f in range(noise_data._freq.shape[0]): - # noise[:, f, :] = np.mean(noise_data._BS_raw_data[:, f, :], axis=(0, 1)) - # noise_data._time_snr = acoustic_data._time - # noise_data._snr = np.divide((acoustic_data._BS_raw_data - noise)**2, noise**2) - # noise_data._snr_reshape = np.reshape(noise_data._snr, - # (acoustic_data._r.shape[0] * acoustic_data._time.shape[0], - # noise_data._freq.shape[0]), - # order="F") - # BS_denoise = np.sqrt(acoustic_data._BS_raw_data**2 - noise**2) - # BS_snr_filter = BS_denoise[np.where(noise_data._snr < self.spinbox_SNR_criterion.value())] = np.nan - # return noise_data, BS_denoise, BS_snr_filter + stg.BS_data_section = deepcopy(stg.BS_data) + + for f in range(stg.freq.shape[0]): + for k in range(stg.r_bottom.shape[0]): + # print(k, np.where(stg.r >= stg.r_bottom[k])[0]) + stg.BS_data_section[np.where(stg.r >= stg.r_bottom[k])[0], f, k] \ + = np.nan + # print("----------------------------------------------------------") + + val_min = np.min(stg.BS_data_section[:, stg.freq_bottom_detection, :]) + val_max = np.max(stg.BS_data_section[:, stg.freq_bottom_detection, :]) + if val_min == 0: + val_min = 1e-5 + + pcm = self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t, -stg.r, stg.BS_data_section[:, stg.freq_bottom_detection, :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + + if stg.r_bottom.size != 0: + self.axis_plot_profile_position_on_transect.plot( + stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid") + + self.axis_plot_profile_position_on_transect.plot( + stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r, + color='red', linestyle="solid", linewidth=2) + + self.figure_plot_profile_position_on_transect.canvas.draw_idle() def update_plot_profile_position_on_transect(self): + # --- 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.axis_plot_profile_position_on_transect.cla() + # --- Update transect plot --- + if self.canvas_plot_profile_position_on_transect != None: - val_min = np.min(stg.BS_data[:, stg.freq_bottom_detection, :]) - val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :]) - if val_min == 0: - val_min = 1e-5 + if stg.r_bottom.size != 0: - pcm = self.axis_plot_profile_position_on_transect.pcolormesh( - stg.t, -stg.r, stg.BS_data[:, stg.freq_bottom_detection, :], - cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + self.axis_plot_profile_position_on_transect.cla() - if stg.r_bottom.size != 0: - self.axis_plot_profile_position_on_transect.plot( - stg.t, -stg.r_bottom, - color='black', linewidth=1, linestyle="solid") + val_min = np.min(stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :]) + val_max = np.max(stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :]) + if val_min == 0: + val_min = 1e-5 - self.axis_plot_profile_position_on_transect.plot( - stg.t[self.slider.value()-1] * np.ones(stg.r.shape[0]), -stg.r, - color='red', linestyle="solid", linewidth=2) + pcm = self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t, -stg.r, stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) - self.canvas_plot_profile_position_on_transect.draw() + if stg.r_bottom.size != 0: + self.axis_plot_profile_position_on_transect.plot( + stg.t, -stg.r_bottom, + color='black', linewidth=1, linestyle="solid") + + self.axis_plot_profile_position_on_transect.plot( + stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r, + color='red', linestyle="solid", linewidth=2) + + self.figure_plot_profile_position_on_transect.canvas.draw_idle() + + else: + + self.axis_plot_profile_position_on_transect.cla() + + val_min = np.min(stg.BS_data[:, self.combobox_frequency.currentIndex(), :]) + val_max = np.max(stg.BS_data[:, self.combobox_frequency.currentIndex(), :]) + if val_min == 0: + val_min = 1e-5 + + pcm = self.axis_plot_profile_position_on_transect.pcolormesh( + stg.t, -stg.r, stg.BS_data[:, self.combobox_frequency.currentIndex(), :], + cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) + + if stg.r_bottom.size != 0: + self.axis_plot_profile_position_on_transect.plot( + stg.t, -stg.r_bottom, + color='black', linewidth=1, linestyle="solid") + + self.axis_plot_profile_position_on_transect.plot( + stg.t[self.slider.value()-1] * np.ones(stg.r.shape[0]), -stg.r, + color='red', linestyle="solid", linewidth=2) + + self.figure_plot_profile_position_on_transect.canvas.draw_idle() def plot_profiles(self): @@ -706,6 +784,8 @@ class SignalProcessingTab(QWidget): self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) + self.figure_profile.canvas.draw_idle() + # --- Raw averaged profile --- self.figure_averaged_profile, self.axis_averaged_profile \ @@ -728,54 +808,39 @@ class SignalProcessingTab(QWidget): def update_plot_profiles(self): - BS_denoise = np.sqrt(stg.BS_data ** 2 - stg.Noise_data ** 2) + if self.checkbox_SNR_criterion.isChecked(): - BS_snr_filter = np.zeros((stg.r.shape[0], stg.freq.shape[0], stg.t.shape[0])) + # self.remove_point_with_snr_filter() - if (self.checkbox_substract_noise.isChecked() is True) and (self.checkbox_SNR_criterion.isChecked() is False): - print("Checkbox noise selected") - print("Checkbox SNR not selected") for f in range(stg.freq.shape[0]): self.axis_profile[f].cla() - self.axis_profile[f].plot(BS_denoise[:, f, self.slider.value()-1], -stg.r, - linestyle='solid', color='k', linewidth=1) - self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) - elif (self.checkbox_substract_noise.isChecked() is False) and (self.checkbox_SNR_criterion.isChecked() is True): - BS_snr_filter = stg.BS_data - BS_snr_filter[np.where(stg.SNR_data < self.spinbox_SNR_criterion.value())] = np.nan - for f in range(stg.freq.shape[0]): - self.axis_profile[f].cla() - self.axis_profile[f].plot(BS_snr_filter[:, f, self.slider.value()-1], -stg.r, - linestyle='solid', color='k', linewidth=1) - self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) - elif (self.checkbox_substract_noise.isChecked() is True) and (self.checkbox_SNR_criterion.isChecked() is True): - BS_snr_filter = BS_denoise - BS_snr_filter[np.where(stg.SNR_data < self.spinbox_SNR_criterion.value())] = np.nan - for f in range(stg.freq.shape[0]): - self.axis_profile[f].cla() - self.axis_profile[f].plot(BS_snr_filter[:, f, self.slider.value()-1], -stg.r, + self.axis_profile[f].plot(stg.BS_data_filter_snr[:, f, self.slider.value()-1], -stg.r, linestyle='solid', color='k', linewidth=1) + + # if stg.r_bottom.size != 0: + # self.axis_profile[f].plot( + # np.array([0, np.nanmax(stg.BS_data[:, stg.freq_bottom_detection, self.slider.value() - 1])]), + # -stg.r_bottom[self.slider.value() - 1] * np.ones(2), + # linestyle='dashed', color='red', linewidth=1) + self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) + else: + for f in range(stg.freq.shape[0]): self.axis_profile[f].cla() self.axis_profile[f].plot(stg.BS_data[:, f, self.slider.value()-1], -stg.r, linestyle='solid', color='k', linewidth=1) - if stg.r_bottom.size != 0: - self.axis_profile[f].plot( - np.array([0, np.nanmax(stg.BS_data[:, stg.freq_bottom_detection, self.slider.value() - 1])]), - -stg.r_bottom[self.slider.value() - 1] * np.ones(2), - linestyle='dashed', color='red', linewidth=1) + # if stg.r_bottom.size != 0: + # self.axis_profile[f].plot( + # np.array([0, np.nanmax(stg.BS_data[:, stg.freq_bottom_detection, self.slider.value() - 1])]), + # -stg.r_bottom[self.slider.value() - 1] * np.ones(2), + # linestyle='dashed', color='red', linewidth=1) self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) - self.canvas_profile.draw() - - # def remove_point_from_snr(self): - # noise_data, BS_denoise = self.remove_noise_from_signal() - # BS_snr_filter = BS_denoise[np.where(noise_data._snr < self.spinbox_SNR_criterion.value())] = np.nan - # return BS_snr_filter + self.figure_profile.canvas.draw_idle() def compute_averaged_profile(self): pass diff --git a/settings.py b/settings.py index 16ef3a7..785576d 100644 --- a/settings.py +++ b/settings.py @@ -46,6 +46,7 @@ DataFrame_acoustic = pd.DataFrame() # --- Processed data in Acoustic Data Tab and used in Acoustic processing tab --- BS_data = np.array([]) +BS_data_section = np.array([]) Noise_data = np.array([]) SNR_data = np.array([]) t = np.array([]) @@ -54,4 +55,39 @@ val_bottom = np.array([]) ind_bottom = np.array([]) freq_bottom_detection = 0 +BS_data_subtract_noise = np.array([]) +BS_data_filter_snr = np.array([]) +BS_data_averaged = np.array([]) + +# --- Sample Data --- + +fine_sediment_path = "" +fine_sediment_filename = "" +fine_sediment_columns = [] + +sample_distance_from_bank = np.array([]) # distance from left bank (m) +sample_depth = np.array([]) # depth (m) +sample_time = np.array([]) + +radius_grain = np.array([]) # grain radius (um) + +Ctot_fine = np.array([]) # Total concentration (g/L) +D50_fine = np.array([]) # median diameter (um) +frac_vol_fine = np.array([]) # Volume fraction (%) + +frac_vol_fine_cumul = np.array([]) # Cumulated volume fraction (%) + +sand_sediment_path = "" +sand_sediment_filename = "" +sand_sediment_columns = [] + +Ctot_sand = np.array([]) # Total concentration (g/L) +D50_sand = np.array([]) # median diameter (um) +frac_vol_sand = np.array([]) # Volume fraction (%) + +frac_vol_sand_cumul = np.array([]) # Cumulated volume fraction (%) + +Ctot_fine_per_cent = np.array([]) +Ctot_sand_per_cent = np.array([]) +