import sys from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QPushButton, QComboBox, QLineEdit, QLabel, \ QGridLayout, QSpinBox, QDoubleSpinBox, QTableView, QTableWidget, QSpacerItem, QSizePolicy, \ QAbstractScrollArea, QFileDialog, QTableWidgetItem, QMessageBox, QScrollBar, QScrollArea from PyQt5.QtGui import QPixmap, QIcon from PyQt5.QtCore import Qt, QCoreApplication, pyqtSignal, pyqtSlot, QEvent import numpy as np import pandas as pd import matplotlib.pyplot as plt # import matplotlib # matplotlib.use("Qt5Agg") from matplotlib.colors import LogNorm, CSS4_COLORS, BoundaryNorm from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar from os import path from copy import deepcopy import locale locale.setlocale(locale.LC_ALL, '') # import Translation.biblio_string as bs import Translation.constant_string as cs from Model.TableModel import TableModel from Model.AquascatDataLoader import RawAquascatData from Model.acoustic_data_loader import AcousticDataLoader from View.window_noise_level_averaged_profile import WindowNoiseLevelTailAveragedProfile from View.sample_data_tab import SampleDataTab _translate = QCoreApplication.translate class AcousticDataTab(QWidget): ''' This class generates the Acoustic Data Tab ''' def __init__(self, tab_widget): super().__init__() path_icon = "./icons/" icon_folder = QIcon(path_icon + "folder.png") ### --- General layout of widgets --- self.verticalLayoutMain = QVBoxLayout(tab_widget) self.horizontalLayoutTop = QHBoxLayout() self.verticalLayoutMain.addLayout(self.horizontalLayoutTop, 4) # 1O units is 100% , 1 units is 10% self.horizontalLayoutBottom = QHBoxLayout() self.verticalLayoutMain.addLayout(self.horizontalLayoutBottom, 6) ### --- Layout of groupbox in the Top horizontal layout box # Download | Measurement information | Table of values | Display options self.groupbox_download = QGroupBox() self.horizontalLayoutTop.addWidget(self.groupbox_download, 3) self.groupbox_info = QGroupBox() self.horizontalLayoutTop.addWidget(self.groupbox_info, 3) self.groupbox_table = QGroupBox() self.horizontalLayoutTop.addWidget(self.groupbox_table, 4) self.groupbox_display_option = QGroupBox() self.horizontalLayoutTop.addWidget(self.groupbox_display_option, 3) ### --- Layout of groupbox in the Bottom horizontal layout box # 2D field of raw acoustic backscatter data | 2D field of Signal to Noise ratio self.groupbox_transect_2Dplot_raw_BS_data = QGroupBox() self.horizontalLayoutBottom.addWidget(self.groupbox_transect_2Dplot_raw_BS_data) self.groupbox_transect_2Dplot_snr_data = QGroupBox() self.horizontalLayoutBottom.addWidget(self.groupbox_transect_2Dplot_snr_data) # ===================================================== # TOP HORIZONTAL BOX LAYOUT # ===================================================== # +++++++++++++++++++++++++++ # | Group box Download file | # +++++++++++++++++++++++++++ self.verticalLayout_groupbox_download = QVBoxLayout(self.groupbox_download) # --- Group box acoustic file --- self.groupbox_acoustic_file = QGroupBox() self.gridLayout_groupbox_acoustic_file = QGridLayout(self.groupbox_acoustic_file) self.combobox_ABS_system_choice = QComboBox() self.combobox_ABS_system_choice.addItems([" ", "Aquascat 1000R", "UB-SediFlow"]) self.gridLayout_groupbox_acoustic_file.addWidget(self.combobox_ABS_system_choice, 0, 0, 1, 1) self.pushbutton_acoustic_file = QPushButton() self.pushbutton_acoustic_file.setObjectName("pushbutton_acoustic_file") self.pushbutton_acoustic_file.setIcon(icon_folder) self.gridLayout_groupbox_acoustic_file.addWidget(self.pushbutton_acoustic_file, 0, 1, 1, 1) self.lineEdit_acoustic_file = QLineEdit() self.gridLayout_groupbox_acoustic_file.addWidget(self.lineEdit_acoustic_file, 0, 2, 1, 1) self.label_date_groupbox_acoustic_file = QLabel() self.gridLayout_groupbox_acoustic_file.addWidget(self.label_date_groupbox_acoustic_file, 1, 0, 1, 2) self.label_hour_groupbox_acoustic_file = QLabel() self.gridLayout_groupbox_acoustic_file.addWidget(self.label_hour_groupbox_acoustic_file, 1, 2, 1, 1) # Download Push Button event : connect button clicked signal to open file slot self.pushbutton_acoustic_file.clicked.connect(self.open_dialog_box) self.verticalLayout_groupbox_download.addWidget(self.groupbox_acoustic_file) # --- Group box noise file --- self.groupbox_noise_file = QGroupBox() self.gridLayout_groupbox_noise_file = QGridLayout(self.groupbox_noise_file) self.pushbutton_noise_level_with_tail_of_mean_profile = QPushButton() self.gridLayout_groupbox_noise_file.addWidget(self.pushbutton_noise_level_with_tail_of_mean_profile, 0, 0, 1, 1) self.pushbutton_noise_file = QPushButton() self.pushbutton_noise_file.setObjectName("pushbutton_noise_file") self.pushbutton_noise_file.setIcon(icon_folder) self.gridLayout_groupbox_noise_file.addWidget(self.pushbutton_noise_file, 0, 1, 1, 1) self.lineEdit_noise_file = QLineEdit() self.gridLayout_groupbox_noise_file.addWidget(self.lineEdit_noise_file, 0, 2, 1, 1) self.label_date_groupbox_noise_file = QLabel() self.gridLayout_groupbox_noise_file.addWidget(self.label_date_groupbox_noise_file, 1, 0, 1, 2) self.label_hour_groupbox_noise_file = QLabel() self.gridLayout_groupbox_noise_file.addWidget(self.label_hour_groupbox_noise_file, 1, 2, 1, 1) # Download Push Button event : connect button clicked signal to open file slot self.pushbutton_noise_file.clicked.connect(self.open_dialog_box) self.verticalLayout_groupbox_download.addWidget(self.groupbox_noise_file) # --- Group box GPS file --- self.groupbox_gps_file = QGroupBox() self.gridLayout_groupbox_gps_file = QGridLayout(self.groupbox_gps_file) self.combobox_gps_system_choice = QComboBox() self.combobox_gps_system_choice.addItems([" ", "GPS1", "GPS2", "no GPS"]) self.gridLayout_groupbox_gps_file.addWidget(self.combobox_gps_system_choice, 0, 0, 1, 1) self.pushbutton_gps_file = QPushButton() self.pushbutton_gps_file.setIcon(icon_folder) self.gridLayout_groupbox_gps_file.addWidget(self.pushbutton_gps_file, 0, 1, 1, 1) self.lineEdit_gps_file = QLineEdit() self.gridLayout_groupbox_gps_file.addWidget(self.lineEdit_gps_file, 0, 2, 1, 1) self.label_date_groupbox_gps_file = QLabel() self.gridLayout_groupbox_gps_file.addWidget(self.label_date_groupbox_gps_file, 1, 0, 1, 2) self.label_hour_groupbox_gps_file = QLabel() self.gridLayout_groupbox_gps_file.addWidget(self.label_hour_groupbox_gps_file, 1, 2, 1, 1) # Download Push Button event : connect button clicked signal to open file slot # self.pushButton_gpsfile.clicked.connect(self.open_dialog_box) self.verticalLayout_groupbox_download.addWidget(self.groupbox_gps_file) # --- Time offset line between ABS system time and GPS time --- self.gridLayout_time_offset = QGridLayout() self.label_time_offset = QLabel() self.gridLayout_time_offset.addWidget(self.label_time_offset, 0, 0, 1, 1) self.label_acoustic_gps_time = QLabel() self.label_acoustic_gps_time.setText( "Tacoustic =" + " Tgps") self.gridLayout_time_offset.addWidget(self.label_acoustic_gps_time, 0, 1, 1, 1) self.combobox_plus_minus = QComboBox() self.combobox_plus_minus.addItem("+") self.combobox_plus_minus.addItem("-") self.gridLayout_time_offset.addWidget(self.combobox_plus_minus, 0, 2, 1, 1) self.spinbox_time_offset_value = QSpinBox() self.gridLayout_time_offset.addWidget(self.spinbox_time_offset_value, 0, 3, 1, 1) self.label_seconds = QLabel() self.label_seconds.setText("sec") self.gridLayout_time_offset.addWidget(self.label_seconds, 0, 4, 1, 1) self.verticalLayout_groupbox_download.addLayout(self.gridLayout_time_offset) # ++++++++++++++++++++++++++++++++++++++ # | Group Box Measurements information | # ++++++++++++++++++++++++++++++++++++++ self.gridLayout_goupbox_info = QGridLayout(self.groupbox_info) self.label_profiles = QLabel() self.label_profiles_per_sec = QLabel() self.label_cells = QLabel() self.label_cell_size = QLabel() self.label_pulse_length = QLabel() self.label_pings_per_sec = QLabel() self.label_pings_per_profile = QLabel() self.label_freq = QLabel() self.label_kt = QLabel() self.label_rx = QLabel() self.label_tx = QLabel() self.label_to_do = QLabel() self.label_to_do.setText("UBSediFlow data : to do for Oct. 20th") # self.groupbox_measurement_information_Aquascat() self.combobox_ABS_system_choice.currentTextChanged.connect(self.ABS_system_choice) # +++++++++++++++++++++++++++++ # | Group Box Table of values | # +++++++++++++++++++++++++++++ self.verticalLayout_groupbox_table = QVBoxLayout(self.groupbox_table) self.horizontalLayout_pushbutton_fill_export_table = QHBoxLayout() self.pushbutton_fill_table = QPushButton() self.horizontalLayout_pushbutton_fill_export_table.addWidget(self.pushbutton_fill_table) self.pushbutton_fill_table.clicked.connect(self.fill_table) self.horizontalSpacerItem_between_pushbutton_fill_export_table = QSpacerItem(50, 10, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_pushbutton_fill_export_table.addItem( self.horizontalSpacerItem_between_pushbutton_fill_export_table) self.pushbutton_export_table = QPushButton() self.horizontalLayout_pushbutton_fill_export_table.addWidget(self.pushbutton_export_table) self.pushbutton_export_table.clicked.connect(self.export_table) self.verticalLayout_groupbox_table.addLayout(self.horizontalLayout_pushbutton_fill_export_table) # self.tableWidget = QTableWidget() # self.tableWidget.setRowCount(10) # self.tableWidget.setColumnCount(10) self.tableView = QTableView() data = pd.DataFrame(np.zeros((10, 10))) self.tableModel = TableModel(data) self.tableView.setModel(self.tableModel) self.verticalLayout_groupbox_table.addWidget(self.tableView) # #------------------------------------ # # self.tableView = QTableView() # # self.tableView.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContentsOnFirstShow) # # self.tableView.horizontalHeader().setStretchLastSection(True) # # # # df, tension, freq, depth = self._model.acoustic_data() # # print(np.zeros(len(tension), dtype=int)) # # print("dimension", list(tension)) # # self.data = pd.DataFrame({'Time (sec)': np.zeros(10, dtype=int), # # 'y (m)': np.zeros(10, dtype=int), # # 'z (m)': np.zeros(10, dtype=int), # # 'Frequency (MHz)': np.zeros(10, dtype=int), # # 'Voltage (V)': np.zeros(10, dtype=int), # # 'SNR': np.zeros(10, dtype=int)}) # # self.data = pd.DataFrame({'Time (sec)': np.zeros(len(tension), dtype=int), # # 'y (m)': np.zeros(len(tension), dtype=int), # # 'z (m)': np.zeros(len(tension), dtype=int), # # 'Frequency (Hz)': df['freq'], # # 'Voltage (V)': df['tension'], # # 'SNR': np.zeros(len(tension), dtype=int)}) # # self.data.reset_index(drop=True, inplace=True) # # self.data = self._model.acoustic_data_table # # # # self.tableModel = TableModel(self.data) # # self.tableView.setModel(self.tableModel) # # self.verticalLayout_groupboxtable.addWidget(self.tableView) # # ------------------------------------ # # self.tableWidget = QTableWidget() # self.tableWidget.setRowCount(10) # self.tableWidget.setColumnCount(10) # # # # print("tablewidget = ", self.tableWidget) # # # # self.tableWidget2 = TableWidget(3, 3) # # print("tablewidget2 = ", self.tableWidget2) # # # for i in range(10): # # for j in range(10): # # item_v = QTableWidgetItem() # # self.tableWidget.setVerticalHeaderItem(i, item_v) # # item_h = QTableWidgetItem() # # self.tableWidget.setHorizontalHeaderItem(j, item_h) # # # Fill table Push Button event # # 1st : connect widgets to controllers = fill table # self.pushbutton_fill_table_acousic.clicked.connect(self.fill_table) # self.on_pushButtonFillTable_clicked # # 2nd : listen for model event signals = table is filled # # self._model.BS_data_updated.connect(self.on_BS_data_updated) # # self.verticalLayout_groupboxtable.addWidget(self.tableWidget) # # self.verticalLayout_groupboxtable.addWidget(self.tableView) # ++++++++++++++++++++++++++++ # | Group Box Display option | # ++++++++++++++++++++++++++++ self.verticalLayout_display_option = QVBoxLayout(self.groupbox_display_option) # --- Push buttons to trigger plot of transect with Backscatter acoustic raw data and SNR --- self.horizontalLayout_pushbutton_plot_BS_SNR_data = QHBoxLayout() self.verticalLayout_display_option.addLayout(self.horizontalLayout_pushbutton_plot_BS_SNR_data) self.pushbutton_plot_transect_with_BS_raw_data = QPushButton() self.horizontalLayout_pushbutton_plot_BS_SNR_data.addWidget(self.pushbutton_plot_transect_with_BS_raw_data) self.pushbutton_plot_transect_with_BS_raw_data.clicked.connect(self.plot_transect_with_BS_raw_data) self.pushbutton_plot_transect_with_SNR_data = QPushButton() self.horizontalLayout_pushbutton_plot_BS_SNR_data.addWidget(self.pushbutton_plot_transect_with_SNR_data) self.pushbutton_plot_transect_with_SNR_data.clicked.connect(self.plot_transect_with_SNR_data) # --- Group Box Plot x-axis in time --- self.groupbox_xaxis_time = QGroupBox() # self.groupbox_xaxis_time.setCheckable(True) # self.groupbox_xaxis_time.setChecked(True) # self.groupbox_xaxis_time.clicked.connect(self.transect_xaxis_choice) self.verticalLayout_display_option.addWidget(self.groupbox_xaxis_time) self.gridLayout_groupbox_xaxis_time = QGridLayout(self.groupbox_xaxis_time) self.label_from = QLabel() self.label_from.setText("From") self.gridLayout_groupbox_xaxis_time.addWidget(self.label_from, 0, 0, 1, 1) self.label_tmin = QLabel() self.label_tmin.setText("tmin = ") self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmin, 0, 1, 1, 1) self.spinbox_tmin = QDoubleSpinBox() self.spinbox_tmin.setRange(0, 9999) self.gridLayout_groupbox_xaxis_time.addWidget(self.spinbox_tmin, 0, 2, 1, 1) self.spinbox_tmin.valueChanged.connect(self.update_xaxis_transect_with_BS_raw_data) self.spinbox_tmin.valueChanged.connect(self.update_xaxis_transect_with_SNR_data) self.label_tmin_unit = QLabel() self.label_tmin_unit.setText("sec") self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmin_unit, 0, 3, 1, 1) self.label_to = QLabel() self.label_to.setText("to") self.gridLayout_groupbox_xaxis_time.addWidget(self.label_to, 0, 4, 1, 1) self.label_tmax = QLabel() self.label_tmax.setText("tmax = ") self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmax, 0, 5, 1, 1) self.spinbox_tmax = QDoubleSpinBox() self.spinbox_tmax.setRange(0, 9999) self.gridLayout_groupbox_xaxis_time.addWidget(self.spinbox_tmax, 0, 6, 1, 1) self.spinbox_tmax.valueChanged.connect(self.update_xaxis_transect_with_BS_raw_data) self.spinbox_tmax.valueChanged.connect(self.update_xaxis_transect_with_SNR_data) self.label_tmax_unit = QLabel() self.label_tmax_unit.setText("sec") self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmax_unit, 0, 7, 1, 1) # --- Group Box Plot x-axis in space --- self.groupbox_xaxis_space = QGroupBox() # self.groupbox_xaxis_space.setCheckable(True) # self.groupbox_xaxis_space.setChecked(False) # self.groupbox_xaxis_space.clicked.connect(self.transect_xaxis_choice) self.verticalLayout_display_option.addWidget(self.groupbox_xaxis_space) self.gridLayout_groupbox_xaxis_space = QGridLayout(self.groupbox_xaxis_space) self.label_from = QLabel() self.label_from.setText("From") self.gridLayout_groupbox_xaxis_space.addWidget(self.label_from, 0, 0, 1, 1) self.label_xmin = QLabel() self.label_xmin.setText("xmin = ") self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmin, 0, 1, 1, 1) self.spinbox_xmin = QSpinBox() self.spinbox_xmin.setRange(0, 9999) self.gridLayout_groupbox_xaxis_space.addWidget(self.spinbox_xmin, 0, 2, 1, 1) self.label_xmin_m = QLabel() self.label_xmin_m.setText("m") self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmin_m, 0, 3, 1, 1) self.label_to = QLabel() self.label_to.setText("to") self.gridLayout_groupbox_xaxis_space.addWidget(self.label_to, 0, 4, 1, 1) self.label_xmax = QLabel() self.label_xmax.setText("xmax = ") self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmax, 0, 5, 1, 1) self.spinbox_xmax = QSpinBox() self.spinbox_xmax.setRange(0, 9999) self.gridLayout_groupbox_xaxis_space.addWidget(self.spinbox_xmax, 0, 6, 1, 1) self.label_xmax_m = QLabel() self.label_xmax_m.setText("m") self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmax_m, 0, 7, 1, 1) # --- Group Box bathymetry computation algorithm to detect and plot bottom of transect--- self.groupbox_compute_bathymetry = QGroupBox() # # self.groupbox_crosssectionbottom.setTitle("Plot bottom of cross section") # self.groupbox_crosssectionbottom.setCheckable(True) # self.groupbox_crosssectionbottom.setChecked(False) self.verticalLayout_display_option.addWidget(self.groupbox_compute_bathymetry) self.gridlayout_compute_bathymetry = QGridLayout(self.groupbox_compute_bathymetry) self.combobox_freq_choice = QComboBox() self.combobox_freq_choice.addItems(['', '0.3 MHz', '0.5 Mhz', '1 MHz', '5 MHz']) self.gridlayout_compute_bathymetry.addWidget(self.combobox_freq_choice, 0, 0, 2, 1) self.gridlayout_compute_bathymetry.addWidget(self.label_from, 0, 1, 1, 1) self.spinbox_depth_min = QSpinBox() self.spinbox_depth_min.setRange(0, 9999) self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_min, 0, 2, 1, 1) self.label_depth_min_unit = QLabel() self.label_depth_min_unit.setText("m") self.gridlayout_compute_bathymetry.addWidget(self.label_depth_min_unit, 0, 3, 1, 1) self.gridlayout_compute_bathymetry.addWidget(self.label_to, 0, 4, 1, 1) self.spinbox_depth_max = QSpinBox() self.spinbox_depth_max.setRange(0, 99999) self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_max, 0, 5, 1, 1) self.label_depth_max_unit = QLabel() self.label_depth_max_unit.setText("m") self.gridlayout_compute_bathymetry.addWidget(self.label_depth_max_unit, 0, 6, 1, 1) self.label_next_cell = QLabel() self.label_next_cell.setText("Next cell : +/-") self.gridlayout_compute_bathymetry.addWidget(self.label_next_cell, 1, 1, 1, 1) self.doublespinbox_next_cell = QDoubleSpinBox() self.doublespinbox_next_cell.setRange(0, 99999) self.doublespinbox_next_cell.setDecimals(2) self.gridlayout_compute_bathymetry.addWidget(self.doublespinbox_next_cell, 1, 2, 1, 1) self.label_next_cell_unit = QLabel() self.label_next_cell_unit.setText("m") self.gridlayout_compute_bathymetry.addWidget(self.label_next_cell_unit, 1, 3, 1, 1) self.pushbutton_compute_bathymetry_algorithm = QPushButton() self.pushbutton_compute_bathymetry_algorithm.setText("Compute \n&& \nPlot") self.gridlayout_compute_bathymetry.addWidget(self.pushbutton_compute_bathymetry_algorithm, 0, 7, 2, 1) self.pushbutton_compute_bathymetry_algorithm.clicked.connect(self.detect_bottom) # ===================================================== # BOTTOM HORIZONTAL BOX LAYOUT # ===================================================== # +++++++++++++++++++++++++++++++++++++************+++ # | Group Box Backscatter Acoustic Raw Data 2D field | # ++++++++++++++++++++++++++************++++++++++++++ self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data = QVBoxLayout(self.groupbox_transect_2Dplot_raw_BS_data) self.canvas_BS = None # self.fig_BS, self.axis_BS = plt.subplots(nrows=4, ncols=1, sharex=True, sharey=False, layout="constrained") # self.fig, self.ax = plt.subplots(4, 1) # self.canvas_BS = FigureCanvas(self.fig_BS) # self.canvas_BS = FigureCanvas() # self.plotToolbar_rawdata = NavigationToolBar(self.canvas_rawdata, self) # self.plot_acoustic_raw_data() # self.verticalLayout_plotrawdata.addWidget(self.plotToolbar_rawdata) # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.canvas_BS) # ++++++++++++++++++++++++++++++++++++++++++++ # | Group Box Signal to Noise ratio 2D field | # ++++++++++++++++++++++++++++++++++++++++++++ self.verticalLayout_groupbox_transect_2Dplot_snr_data = QVBoxLayout(self.groupbox_transect_2Dplot_snr_data) self.canvas_SNR = None # self.figure, self.axis = plt.subplots(nrows=4, ncols=1, sharex=True, sharey=False, layout="constrained") # # self.canvas_snrdata = FigureCanvas(self.figure) # # self.canvas_snrdata = FigureCanvas() # # self.plotToolbar_snrdata = NavigationToolBar(self.canvas_snrdata, self) # # self.plot_snr_data() # # self.verticalLayout_plotsnrdata.addWidget(self.plotToolbar_snrdata) # self.verticalLayout_plotsnrdata.addWidget(self.canvas_snrdata) # # self.horizontalLayoutBottom.addWidget(self.groupbox_transect_2Dplot_snr_data) self.retranslate_acoustic_data_tab() # -------------------- Functions for Acoustic dataTab -------------------- def retranslate_acoustic_data_tab(self): self.groupbox_download.setTitle(_translate("CONSTANT_STRING", cs.DOWNLOAD)) self.groupbox_acoustic_file.setTitle(_translate("CONSTANT_STRING", cs.ACOUSTIC_FILE)) self.label_date_groupbox_acoustic_file.setText(_translate("CONSTANT_STRING", cs.DATE) + ":") self.label_hour_groupbox_acoustic_file.setText(_translate("CONSTANT_STRING", cs.HOUR) + ":") self.groupbox_noise_file.setTitle(_translate("CONSTANT_STRING", cs.NOISE_FILE)) self.pushbutton_noise_level_with_tail_of_mean_profile.setText(_translate("CONSTANT_STRING", cs.NOISE_LEVEL)) self.label_date_groupbox_noise_file.setText(_translate("CONSTANT_STRING", cs.DATE) + ":") self.label_hour_groupbox_noise_file.setText(_translate("CONSTANT_STRING", cs.HOUR) + ":") self.groupbox_gps_file.setTitle(_translate("CONSTANT_STRING", cs.GPS_FILE)) self.label_date_groupbox_gps_file.setText(_translate("CONSTANT_STRING", cs.DATE) + ":") self.label_hour_groupbox_gps_file.setText(_translate("CONSTANT_STRING", cs.HOUR) + ":") self.label_time_offset.setText(_translate("CONSTANT_STRING", cs.TIME_OFFSET)) self.groupbox_info.setTitle(_translate("CONSTANT_STRING", cs.MEASUREMENTS_INFORMATION)) self.label_profiles.setText(_translate("CONSTANT_STRING", cs.NB_PROFILES) + ":") self.label_profiles.setToolTip(_translate("CONSTANT_STRING", cs.NB_PROFILES_TOOLTIP)) self.label_profiles_per_sec.setText(_translate("CONSTANT_STRING", cs.NB_PROFILES_PER_SEC) + ":") self.label_profiles_per_sec.setToolTip(_translate("CONSTANT_STRING", cs.NB_PROFILES_PER_SEC_TOOLTIP)) self.label_cells.setText(_translate("CONSTANT_STRING", cs.NB_CELLS) + ":") self.label_cells.setToolTip(_translate("CONSTANT_STRING", cs.NB_CELLS_TOOLTIP)) self.label_cell_size.setText(_translate("CONSTANT_STRING", cs.CELL_SIZE) + ":") self.label_cell_size.setToolTip(_translate("CONSTANT_STRING", cs.CELL_SIZE_TOOLTIP)) self.label_pulse_length.setText(_translate("CONSTANT_STRING", cs.PULSE_LENGHT) + ":") self.label_pulse_length.setToolTip(_translate("CONSTANT_STRING", cs.PULSE_LENGHT_TOOLTIP)) self.label_pings_per_sec.setText(_translate("CONSTANT_STRING", cs.NB_PINGS_PER_SEC)) self.label_pings_per_sec.setToolTip(_translate("CONSTANT_STRING", cs.NB_PINGS_PER_SEC_TOOLTIP)) self.label_pings_per_profile.setText(_translate("CONSTANT_STRING", cs.NB_PINGS_PER_PROFILE) + ":") self.label_pings_per_profile.setToolTip(_translate("CONSTANT_STRING", cs.NB_PINGS_PER_PROFILE_TOOLTIP)) self.label_freq.setText(_translate("CONSTANT_STRING", cs.FREQUENCY) + ":") self.label_freq.setToolTip(_translate("CONSTANT_STRING", cs.FREQUENCY_TOOLTIP)) self.label_kt.setText(_translate("CONSTANT_STRING", cs.KT) + ":") self.label_kt.setToolTip(_translate("CONSTANT_STRING", cs.KT_TOOLTIP)) self.label_rx.setText(_translate("CONSTANT_STRING", cs.GAIN_RX) + ":") self.label_rx.setToolTip(_translate("CONSTANT_STRING", cs.GAIN_RX_TOOLTIP)) self.label_tx.setText(_translate("CONSTANT_STRING", cs.GAIN_TX) + ":") self.label_tx.setToolTip(_translate("CONSTANT_STRING", cs.GAIN_TX_TOOLTIP)) self.groupbox_table.setTitle(_translate("CONSTANT_STRING", cs.TABLE_VALUES)) self.pushbutton_fill_table.setText(_translate("CONSTANT_STRING", cs.SYNCHRONIZE_AND_FILL_TABLE)) self.pushbutton_export_table.setText(_translate("CONSTANT_STRING", cs.EXPORT_TABLE)) self.groupbox_display_option.setTitle(_translate("CONSTANT_STRING", cs.DISPLAY_OPTIONS)) self.pushbutton_plot_transect_with_BS_raw_data.setText(_translate("CONSTANT_STRING", cs.PLOT_TRANSECT)) self.pushbutton_plot_transect_with_SNR_data.setText(_translate("CONSTANT_STRING", cs.PLOT_SNR)) self.groupbox_xaxis_time.setTitle(_translate("CONSTANT_STRING", cs.PLOT_XAXIS_IN_TIME)) # self.label_tmin.setText(_translate("CONSTANT_STRING", cs.FROM) + " tmin = ") # self.label_tmax.setText(_translate("CONSTANT_STRING", cs.TO) + " tmax = ") # self.pushButton_plot_acoustic_transect_in_time.setText(_translate("CONSTANT_STRING", cs.PLOT_TRANSECT)) self.groupbox_xaxis_space.setTitle(_translate("CONSTANT_STRING", cs.PLOT_XAXIS_IN_SPACE)) # self.label_zmin.setText(_translate("CONSTANT_STRING", cs.FROM) + " zmin = ") # self.label_zmax.setText(_translate("CONSTANT_STRING", cs.TO) + " zmax = ") # self.pushButton_plot_acoustic_transect_in_space.setText(_translate("CONSTANT_STRING", cs.PLOT_TRANSECT)) self.groupbox_compute_bathymetry.setTitle(_translate("CONSTANT_STRING", cs.PLOT_BOTTOM_CROSS_SECTION)) # self.label_depthmin.setText(_translate("CONSTANT_STRING", cs.INITIAL_DEPTH_RANGE) + ":") # self.label_depthmin.setText(_translate("CONSTANT_STRING", cs.FROM)) # self.label_to.setText(_translate("CONSTANT_STRING", cs.TO)) # self.pushButton_bottom_transect.setText(_translate("CONSTANT_STRING", cs.PLOT_BOTTOM)) self.groupbox_transect_2Dplot_raw_BS_data.setTitle(_translate("CONSTANT_STRING", cs.RAW_ACOUSTIC_DATA_2D_FIELD)) self.groupbox_transect_2Dplot_snr_data.setTitle(_translate("CONSTANT_STRING", cs.SIGNAL_TO_NOISE_RATIO_2D_FIELD)) def ABS_system_choice(self): if self.combobox_ABS_system_choice.currentText() == "Aquascat 1000R": self.groupbox_measurement_information_Aquascat() self.lineEdit_acoustic_file.clear() self.label_date_groupbox_acoustic_file.clear() self.label_date_groupbox_acoustic_file.setText(_translate("CONSTANT_STRING", cs.DATE) + ": ") self.label_hour_groupbox_acoustic_file.setText(_translate("CONSTANT_STRING", cs.HOUR) + ": ") elif self.combobox_ABS_system_choice.currentText() == "UB-SediFlow": self.groupbox_measurement_information_UBSediFlow() self.lineEdit_acoustic_file.clear() self.label_date_groupbox_acoustic_file.setText(_translate("CONSTANT_STRING", cs.DATE) + ": ") self.label_hour_groupbox_acoustic_file.setText(_translate("CONSTANT_STRING", cs.HOUR) + ": ") def groupbox_measurement_information_Aquascat(self): # self.gridLayout_goupbox_info.itemAt(0).widget().deleteLater() self.label_to_do.hide() self.label_profiles.show() self.label_profiles_per_sec.show() self.label_cells.show() self.label_cell_size.show() self.label_pulse_length.show() self.label_pings_per_sec.show() self.label_pings_per_profile.show() self.label_freq.show() self.label_kt.show() self.label_rx.show() self.label_tx.show() self.gridLayout_goupbox_info.addWidget(self.label_profiles, 0, 0, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_profiles_per_sec, 0, 1, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_cells, 1, 0, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_cell_size, 1, 1, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_pulse_length, 2, 0, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_pings_per_sec, 3, 0, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_pings_per_profile, 3, 1, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_freq, 4, 0, 1, 2) self.gridLayout_goupbox_info.addWidget(self.label_kt, 5, 0, 1, 2) self.gridLayout_goupbox_info.addWidget(self.label_rx, 6, 0, 1, 2) self.gridLayout_goupbox_info.addWidget(self.label_tx, 7, 0, 1, 2) def groupbox_measurement_information_UBSediFlow(self): # self.gridLayout_goupbox_info.itemAt(0).widget().deleteLater() self.label_profiles.hide() self.label_profiles_per_sec.hide() self.label_cells.hide() self.label_cell_size.hide() self.label_pulse_length.hide() self.label_pings_per_sec.hide() self.label_pings_per_profile.hide() self.label_freq.hide() self.label_kt.hide() self.label_rx.hide() self.label_tx.hide() self.label_to_do.show() self.gridLayout_goupbox_info.addWidget(self.label_to_do, 0, 0, 1, 1) def clicked_pushbutton_noise_level(self): self.WindowNoiseLevelTailAveragedProfile().show() def open_dialog_box(self): if self.combobox_ABS_system_choice.currentIndex() == 0: msgBox = QMessageBox() msgBox.setWindowTitle("Download Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Choose ABS system before download acoustic files") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() elif self.combobox_ABS_system_choice.currentIndex() == 1: filename = QFileDialog.getOpenFileName(self, "Open file", "/home/bmoudjed/Documents/3 SSC acoustic meas project/Graphical interface project/Data", "Aquascat file (*.aqa)") dir_name = path.dirname(filename[0]) name = path.basename(filename[0]) elif self.combobox_ABS_system_choice.currentIndex() == 2: filename = QFileDialog.getOpenFileName(self, "Open file", "", "UBSediFlow file (*.udt)") dir_name = path.dirname(filename[0]) name = path.basename(filename[0]) if self.combobox_ABS_system_choice.currentIndex() != 0: if self.sender().objectName() == "pushbutton_acoustic_file": self.lineEdit_acoustic_file.setText(name) self.lineEdit_acoustic_file.setToolTip(dir_name) acoustic_data = self.load_BS_acoustic_raw_data() self.label_date_groupbox_acoustic_file.setText( _translate("CONSTANT_STRING", cs.DATE) + ": " + str(acoustic_data._date)) self.label_hour_groupbox_acoustic_file.setText( _translate("CONSTANT_STRING", cs.HOUR) + ": " + str(acoustic_data._hour)) self.fill_measurements_information_groupbox() if self.sender().objectName() == "pushbutton_noise_file": self.lineEdit_noise_file.setText(name) self.lineEdit_noise_file.setToolTip(dir_name) noise_data = self.load_noise_data() self.label_date_groupbox_noise_file.setText( _translate("CONSTANT_STRING", cs.DATE) + ": " + str(noise_data._date)) self.label_hour_groupbox_noise_file.setText( _translate("CONSTANT_STRING", cs.HOUR) + ": " + str(noise_data._hour)) # return filename[0] def load_BS_acoustic_raw_data(self): acoustic_data = \ AcousticDataLoader(self.lineEdit_acoustic_file.toolTip() + "/" + self.lineEdit_acoustic_file.text()) return acoustic_data def load_noise_data(self): noise_data = AcousticDataLoader(self.lineEdit_noise_file.toolTip() + "/" + self.lineEdit_noise_file.text()) return noise_data def compute_SNR(self): acoustic_data = self.load_BS_acoustic_raw_data() noise_data = self.load_noise_data() noise = np.zeros(acoustic_data._BS_raw_data.shape) for f in range(noise_data._freq.shape[0]): # print(np.mean(self.V_noise[:, f, :], axis=(0, 1))) # BS_noise_section[0:BS_noise_section.shape[0], f, 0:BS_noise_section.shape[2]] = \ 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") return noise_data def fill_measurements_information_groupbox(self): acoustic_data = self.load_BS_acoustic_raw_data() self.label_profiles.setText( _translate("CONSTANT_STRING", cs.NB_PROFILES) + ": " + str(acoustic_data._nb_profiles)) self.label_profiles_per_sec.setText( _translate("CONSTANT_STRING", cs.NB_PROFILES_PER_SEC) + ": " + str(acoustic_data._nb_profiles_per_sec) + " Hz") self.label_freq.setText( _translate("CONSTANT_STRING", cs.FREQUENCY) + ": " + ', '.join(acoustic_data._freq_text)) self.label_cells.setText( _translate("CONSTANT_STRING", cs.NB_CELLS) + ": " + str(acoustic_data._nb_cells)) self.label_cell_size.setText( _translate("CONSTANT_STRING", cs.CELL_SIZE) + ": " + str(100*round(acoustic_data._cell_size, 3)) + " cm") self.label_pulse_length.setText( _translate("CONSTANT_STRING", cs.PULSE_LENGHT) + ": " + str(round(acoustic_data._pulse_length,6)) + "sec") self.label_pings_per_sec.setText( _translate("CONSTANT_STRING", cs.NB_PINGS_PER_SEC) + ": " + str(acoustic_data._nb_pings_per_sec) + " Hz") self.label_pings_per_profile.setText( _translate("CONSTANT_STRING", cs.NB_PINGS_PER_PROFILE) + ": " + str(acoustic_data._nb_pings_averaged_per_profile)) self.label_kt.setText( _translate("CONSTANT_STRING", cs.KT) + ": " + ', '.join(map(str, acoustic_data._kt))) self.label_rx.setText( _translate("CONSTANT_STRING", cs.GAIN_RX) + ": " + ', '.join(map(str, acoustic_data._gain_rx))) self.label_tx.setText( _translate("CONSTANT_STRING", cs.GAIN_TX) + ": " + ', '.join(map(str, acoustic_data._gain_tx))) def fill_table(self): if ((self.lineEdit_acoustic_file.text()) and (self.lineEdit_noise_file.text())): # --- Load data --- acoustic_data = self.load_BS_acoustic_raw_data() noise_data = self.compute_SNR() # --- Fill table with data --- data = pd.DataFrame( np.concatenate((acoustic_data.reshape_t(), acoustic_data.reshape_BS_raw_cross_section(), noise_data._snr_reshape), axis=1), columns=list(map(str, ["Time"] + ["BS - " + f for f in acoustic_data._freq_text] + ["SNR - " + f for f in acoustic_data._freq_text]))) self.tableModel = TableModel(data) self.tableView.setModel(self.tableModel) elif self.lineEdit_acoustic_file.text(): # --- Load data --- acoustic_data = self.load_BS_acoustic_raw_data() # --- Fill table with data --- data = pd.DataFrame( np.concatenate((acoustic_data.reshape_t(), acoustic_data.reshape_BS_raw_cross_section()), axis=1), columns=list(map(str, ["Time"] + ["BS - " + f for f in acoustic_data._freq_text]))) self.tableModel = TableModel(data) self.tableView.setModel(self.tableModel) else: msgBox = QMessageBox() msgBox.setWindowTitle("Fill table Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Download files before fill table") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() def export_table(self): if self.tableWidget.columnCount() == 10: msgBox = QMessageBox() msgBox.setWindowTitle("Export table Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Fill table before export table") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() else: print("export table") def transect_xaxis_choice(self): if self.groupbox_xaxis_time.isChecked() == True: # self.groupbox_xaxis_time.setDisabled(True) self.groupbox_xaxis_space.setChecked(False) # self.groupbox_xaxis_space.setDisabled(False) elif self.groupbox_xaxis_space.isChecked() == True: self.groupbox_xaxis_time.setChecked(False) # self.groupbox_xaxis_time.setDisabled(False) # self.groupbox_xaxis_space.setDisabled(True) # def fill_lineEdit(self, dir_name, name): # if self.pushbutton_acousticfile.isChecked(): # self.lineEdit_acousticfile.setText(name) # self.lineEdit_acousticfile.setToolTip(dir_name) # self.fill_label_acoustic_file() # self.fill_measurements_information_groupbox() # self.pushbutton_acousticfile.setChecked(False) # elif self.pushButton_noisefile.isChecked(): # self.lineEdit_noisefile.setText(name) # self.lineEdit_noisefile.setToolTip(dir_name) # self.fill_label_noise_file() # self.pushButton_noisefile.setChecked(False) # elif self.pushButton_gpsfile.isChecked(): # self.lineEdit_gpsfile.setText(name) # self.lineEdit_gpsfile.setToolTip(dir_name) # self.fill_label_gps_file() # self.pushButton_gpsfile.setChecked(False) # # def fill_label_acoustic_file(self): # self.label_date_acousticfile.setText( # _translate("CONSTANT_STRING", cs.DATE) + ": " + str(self._model.data.date.date())) # self.label_hour_acousticfile.setText( # _translate("CONSTANT_STRING", cs.HOUR) + ": " + str(self._model.data.date.time())) # # def fill_label_noise_file(self): # self.label_date_noise_file.setText( # _translate("CONSTANT_STRING", cs.DATE) + ": " + str(self._model.data.date.date())) # self.label_hour_noise_file.setText( # _translate("CONSTANT_STRING", cs.HOUR) + ": " + str(self._model.data.date.time())) # # def fill_label_gps_file(self): # pass # # self.label_date_gps_file.setText( # # _translate("CONSTANT_STRING", cs.DATE) + ": " + str(self._model.gps_load_date_hour.date())) # # self.label_hour_gps_file.setText( # # _translate("CONSTANT_STRING", cs.HOUR) + ": " + str(self._model.gps_load_date_hour.time())) # def fill_table(self): # print("it's clicked") # print(AcousticData.concatenate_data(self)) # # if event.type() == QEvent.MouseButtonPress: # # print("Fill table") # # print("event = ", event) # # print("QEvent.MouseButtonPress ", QEvent.MouseButtonPress) # # super(AcousticDataTab, self).mousePressEvent(event) # # print("1 : connect widget to controller - fill table") # # self._controller.update_table_data() # # data = self._model.acoustic_data_table # # tableModel = TableModel(data) # # self.tableView.setModel(tableModel) # # print("open dialog box ", self.open_dialog_box()) # # def on_BS_data_updated(self, value): # pass def plot_transect_with_BS_raw_data(self): if self.tableModel.rowCount(1) > 11: acoustic_data = self.load_BS_acoustic_raw_data() # print(np.max(acoustic_data._time)) # print("tmin value ", self.spinbox_tmin.value()) # print("tmin index ", np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]) # print("tmax value ", self.spinbox_tmax.value()) # print("tmax index ", np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]) self.fig_BS, self.axis_BS = plt.subplots(nrows=acoustic_data._freq.shape[0], ncols=1, sharex=True, sharey=False, layout="constrained") self.canvas_BS = FigureCanvas(self.fig_BS) self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.canvas_BS) # self.scroll_BS = QScrollArea() # self.scroll_BS.setWidget(self.canvas_BS) self.spinbox_tmin.setValue(np.min(acoustic_data._time)) self.spinbox_tmax.setValue(np.round(np.max(acoustic_data._time), 2)) for f in range(acoustic_data._freq.shape[0]): # self.ax = self.fig.add_subplot((4, 1, f+1), sharex=True, sharey=False) # val_min = np.min(self.model.V[:, f, :2300]) val_min = np.min(acoustic_data._BS_raw_data[:, f, :]) # val_max = np.max(self.model.V[:, f, :2300]) val_max = np.max(acoustic_data._BS_raw_data[:, f, :]) if val_min == 0: val_min = 1e-5 # if val_min == 0: # val_min = 1e-5 # self.ax[f].imshow(np.asarray(np.array(self.model.BS_raw_cross_section.V[:, f, :], dtype=float)), aspect='auto', # extent=[0, 1912, self.model.depth[-1][0], self.model.depth[0][0]], # cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) # self.ax[f].plot(self.model.r_bottom_cross_section, color='red', linewidth=2) pcm = self.axis_BS[f].pcolormesh( acoustic_data._time[np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]], acoustic_data._r , np.flipud(acoustic_data._BS_raw_data[:, f, np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]]), cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))#, shading='gouraud') # self.axis_BS[f].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='red', linewidth=2) # x, y = np.meshgrid(self.model.dist_BS_section, self.model.BS_raw_cross_section.r) # z = np.cos(x) + np.sin(y) # self.ax[f].contour(x, y, z, levels = 0, colors='k') # self.ax[f].plot([25, 200], [5, 5], '-k') self.axis_BS[f].text(1, .70, acoustic_data._freq_text[f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_BS[f].transAxes) self.fig_BS.supxlabel('Distance from left bank (m)', fontsize=10) self.fig_BS.supylabel('Depth (m)', fontsize=10) # plt.subplots_adjust(bottom=0.125, top=0.98, right=1.03, left=0.08, hspace=0.1) # self.fig.tight_layout() cbar = self.fig_BS.colorbar(pcm, ax=self.axis_BS[:], shrink=1, location='right') cbar.set_label(label='Backscatter acoustic signal (V)', rotation=270, labelpad=10) self.fig_BS.canvas.draw_idle() else: msgBox = QMessageBox() msgBox.setWindowTitle("Plot transect Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Fill table before plot transect 2D field") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() def plot_transect_with_SNR_data(self): if self.tableModel.rowCount(1) == 10: msgBox = QMessageBox() msgBox.setWindowTitle("Plot transect Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Fill table before plot SNR 2D field") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() elif self.canvas_BS == None: msgBox = QMessageBox() msgBox.setWindowTitle("Plot transect Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Plot backscatter acoustic raw data 2D field before plot SNR 2D field") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() elif self.tableModel.rowCount(1) > 11: noise_data = self.compute_SNR() self.fig_SNR, self.axis_SNR = plt.subplots(nrows=noise_data._freq.shape[0] , ncols=1, sharex=True, sharey=False, layout="constrained") self.canvas_SNR = FigureCanvas(self.fig_SNR) self.verticalLayout_groupbox_transect_2Dplot_snr_data.addWidget(self.canvas_SNR) # self.spinbox_tmin.setValue(np.min(noise_data._time_snr)) # self.spinbox_tmax.setValue(np.round(np.max(noise_data._time_snr), 2)) x, y = np.meshgrid( noise_data._time_snr[np.where(np.round(noise_data._time_snr, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(noise_data._time_snr, 2) == self.spinbox_tmax.value())[0][0]], noise_data._r) for f in range(noise_data._freq.shape[0]): val_min = np.min(noise_data._snr[:, f, :]) val_max = np.max(noise_data._snr[:, f, :]) if val_min == 0: val_min = 1e-5 if val_max > 1000: levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) else: levels = np.array([00.1, 1, 2, 10, 100, val_max]) bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2] norm = BoundaryNorm(boundaries=bounds, ncolors=300) cf = self.axis_SNR[f].contourf(x, y, np.flipud(noise_data._snr[:, f, np.where(np.round(noise_data._time_snr, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(noise_data._time_snr, 2) == self.spinbox_tmax.value())[0][0]]), levels, cmap='gist_rainbow', norm=norm)#, shading='gouraud') self.axis_SNR[f].text(1, .70, noise_data._freq_text[f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_SNR[f].transAxes) self.fig_SNR.supxlabel('Distance from left bank (m)', fontsize=10) self.fig_SNR.supylabel('Depth (m)', fontsize=10) # plt.subplots_adjust(bottom=0.125, top=0.98, right=1.03, left=0.08, hspace=0.1) # self.fig.tight_layout() cbar = self.fig_SNR.colorbar(cf, ax=self.axis_SNR[:], shrink=1, location='right') cbar.set_label(label='Signal to Noise Ratio', rotation=270, labelpad=10) cbar.set_ticklabels(['0', '1', '2', '10', '100', r'10$^3$', r'10$^6$']) self.fig_SNR.canvas.draw_idle() def update_xaxis_transect_with_BS_raw_data(self): if self.canvas_BS == None: msgBox = QMessageBox() msgBox.setWindowTitle("Plot transect Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Plot transect before change x-axis value") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() else: # print(self.axis_BS.cla()) # self.fig_BS.clf() acoustic_data = self.load_BS_acoustic_raw_data() # self.fig_BS, self.axis_BS = plt.subplots(nrows=acoustic_data._freq.shape[0], ncols=1, sharex=True, # sharey=False, layout="constrained") # self.canvas_BS = FigureCanvas(self.fig_BS) # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.canvas_BS) for f in range(acoustic_data._freq.shape[0]): self.axis_BS[f].cla() val_min = np.min(acoustic_data._BS_raw_data[:, f, :]) val_max = np.max(acoustic_data._BS_raw_data[:, f, :]) if val_min == 0: val_min = 1e-5 pcm = self.axis_BS[f].pcolormesh( acoustic_data._time[np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]], acoustic_data._r , np.flipud(acoustic_data._BS_raw_data[:, f, np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]]), cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))#, shading='gouraud') self.axis_BS[f].text(1, .70, acoustic_data._freq_text[f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_BS[f].transAxes) self.fig_BS.supxlabel('Distance from left bank (m)', fontsize=10) self.fig_BS.supylabel('Depth (m)', fontsize=10) # cbar = self.fig_BS.colorbar(pcm, ax=self.axis_BS[:], shrink=1, location='right') # cbar.set_label(label='Backscatter acoustic signal (V)', rotation=270, labelpad=10) self.fig_BS.canvas.draw_idle() def update_xaxis_transect_with_SNR_data(self): noise_data = self.compute_SNR() if ((self.canvas_BS != None) and (self.canvas_SNR != None)): x, y = np.meshgrid( noise_data._time_snr[np.where(np.round(noise_data._time_snr, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(noise_data._time_snr, 2) == self.spinbox_tmax.value())[0][0]], noise_data._r) for f in range(noise_data._freq.shape[0]): self.axis_SNR[f].cla() val_min = np.min(noise_data._snr[:, f, :]) val_max = np.max(noise_data._snr[:, f, :]) if val_min == 0: val_min = 1e-5 if val_max > 1000: levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6]) else: levels = np.array([00.1, 1, 2, 10, 100, val_max]) bounds = [00.1, 1, 2, 10, 100, 1000, val_max, val_max * 1.2] norm = BoundaryNorm(boundaries=bounds, ncolors=300) cf = self.axis_SNR[f].contourf(x, y, np.flipud(noise_data._snr[:, f, np.where(np.round(noise_data._time_snr, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(noise_data._time_snr, 2) == self.spinbox_tmax.value())[0][0]]), levels, cmap='gist_rainbow', norm=norm) # , shading='gouraud') self.axis_SNR[f].text(1, .70, noise_data._freq_text[f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_SNR[f].transAxes) self.fig_SNR.supxlabel('Distance from left bank (m)', fontsize=10) self.fig_SNR.supylabel('Depth (m)', fontsize=10) # plt.subplots_adjust(bottom=0.125, top=0.98, right=1.03, left=0.08, hspace=0.1) # self.fig.tight_layout() # cbar = self.fig_SNR.colorbar(cf, ax=self.axis_SNR[:], shrink=1, location='right') # cbar.set_label(label='Signal to Noise Ratio', rotation=270, labelpad=10) # cbar.set_ticklabels(['0', '1', '2', '10', '100', r'10$^3$', r'10$^6$']) self.fig_SNR.canvas.draw_idle() def detect_bottom(self): if self.lineEdit_acoustic_file.text() == "": msgBox = QMessageBox() msgBox.setWindowTitle("Detect bottom Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Load data before compute bathymety algorithm") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() elif self.tableModel.rowCount(1) == 10: msgBox = QMessageBox() msgBox.setWindowTitle("Detect bottom Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Fill table before compute bathymety algorithm") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() elif self.canvas_BS == None: msgBox = QMessageBox() msgBox.setWindowTitle("Detect bottom Error") msgBox.setIcon(QMessageBox.Warning) msgBox.setText("Plot transect before compute bathymety algorithm") msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec() else: acoustic_data = self.load_BS_acoustic_raw_data() # Selecting the range in which we look for the bottom reflection rmin = np.int(self.spinbox_depth_min.text()) # 4 rmax = np.int(self.spinbox_depth_max.text()) # 8 # empty result arrays r_bottom = np.zeros(acoustic_data._nb_profiles) val_bottom = np.zeros(acoustic_data._nb_profiles) r_bottom_ind = [] # ----------- Detecting the bottom ------------- for d in range(acoustic_data._nb_profiles): # Index of the range where we look for the peak ind_min = np.where(acoustic_data._r >= rmin)[0][0] ind_max = np.where(acoustic_data._r <= rmax)[0][-1] # Getting the peak val_bottom[d] = np.nanmax(acoustic_data._BS_raw_data[ind_min:ind_max, self.combobox_freq_choice.currentIndex() - 1, d]) # Getting the range cell of the peak ind_bottom = np.where(acoustic_data._BS_raw_data[ind_min:ind_max, self.combobox_freq_choice.currentIndex() - 1, d] == val_bottom[d])[0][0] r_bottom[d] = acoustic_data._r[ind_bottom + ind_min] r_bottom_ind.append(ind_bottom + ind_min) # Updating the range where we will look for the peak (in the next cell) rmin = r_bottom[d] - locale.atof(self.doublespinbox_next_cell.text()) # 0.75 rmax = r_bottom[d] + locale.atof(self.doublespinbox_next_cell.text()) # 0.75 BS_section_bottom = np.zeros((acoustic_data._BS_raw_data.shape[0], acoustic_data._BS_raw_data.shape[2])) for i in range(BS_section_bottom.shape[0]): # print(r_bottom_temp_ind[i]) # print(i) BS_section_bottom[r_bottom_ind[i]][i] = 1 # print(BS_section_bottom[r_bottom_temp_ind[i]][i]) # --- Plot transect with bathymetry --- for f in range(acoustic_data._freq.shape[0]): self.axis_BS[f].cla() val_min = np.min(acoustic_data._BS_raw_data[:, f, :]) val_max = np.max(acoustic_data._BS_raw_data[:, f, :]) if val_min == 0: val_min = 1e-5 pcm = self.axis_BS[f].pcolormesh( acoustic_data._time[np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]], acoustic_data._r , np.flipud(acoustic_data._BS_raw_data[:, f, np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]]), cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))#, shading='gouraud') self.axis_BS[f].plot( acoustic_data._time[np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]], np.max(r_bottom[np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]]) - r_bottom[np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]] + np.min(r_bottom[np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmin.value())[0][0]: np.where(np.round(acoustic_data._time, 2) == self.spinbox_tmax.value())[0][0]]), # np.max(self._model.r_bottom_cross_section) - self._model.r_bottom_cross_section + np.min(self._model.r_bottom_cross_section), color='black', linewidth=1, linestyle="--") # self.axis_BS[f].text(1, .70, acoustic_data._freq_text[f], # fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, # horizontalalignment='right', verticalalignment='bottom', transform=self.axis_BS[f].transAxes) # self.fig_BS.supxlabel('Distance from left bank (m)', fontsize=10) # self.fig_BS.supylabel('Depth (m)', fontsize=10) # # plt.subplots_adjust(bottom=0.125, top=0.98, right=1.03, left=0.08, hspace=0.1) # # self.fig.tight_layout() # cbar = self.fig_BS.colorbar(pcm, ax=self.axis_BS[:], shrink=1, location='right') # cbar.set_label(label='Backscatter acoustic signal (V)', rotation=270, labelpad=10) self.fig_BS.canvas.draw_idle() return r_bottom, val_bottom, r_bottom_ind, BS_section_bottom