From 75eeac031077b7592430b8501c619df0468f2b60 Mon Sep 17 00:00:00 2001 From: brahim Date: Wed, 27 Mar 2024 17:36:48 +0100 Subject: [PATCH] The acoustic data tab has been updated, and the variables in the settings python file have been modified: all are python lists, allowing you to work with multiple acoustic data. Each list are filled with object with as many object as there are acoutic data. 1/ File list widget is added to add/clear/delete buttons. Measurement information is displayed in a scrolling text box. Table of backscatter values is added. Limits of dataset in display option box are displayed with double slider. Limits of dataset are displayed in Display options box with double sliders. Double sliders are also used for river bottom detection. --- Model/AquascatDataLoader.py | 2 +- Model/TableModel.py | 15 +- Model/acoustic_data_loader.py | 4 +- View/acoustic_data_tab.py | 1995 ++++++++++++++++++++++++--------- main.py | 16 +- settings.py | 65 +- 6 files changed, 1539 insertions(+), 558 deletions(-) diff --git a/Model/AquascatDataLoader.py b/Model/AquascatDataLoader.py index 0598855..700d1e2 100644 --- a/Model/AquascatDataLoader.py +++ b/Model/AquascatDataLoader.py @@ -687,7 +687,7 @@ class RawAquascatData: # --------------------------------------------------------------------- # Allocate Memory for the Data - AuxData = np.zeros((AuxNumSamples, NumAuxChans)) + AuxData = np.zeros((int(AuxNumSamples), NumAuxChans)) AbsData = np.zeros((int(AbsNumBins[0]), int(AbsNumProfiles[0]), int(NumAbsTimeSlots)), dtype=float, order='C') PressTempData = np.zeros((NumSerialSamples, 2)) diff --git a/Model/TableModel.py b/Model/TableModel.py index 54ac9b7..c4cd85a 100644 --- a/Model/TableModel.py +++ b/Model/TableModel.py @@ -13,14 +13,19 @@ class TableModel(QAbstractTableModel): # value = self._data.iloc[index.row(), index.column()] # if isinstance(value, int) or isinstance(value, float): # return Qt.AlignVCenter + Qt.AlignRight - return str(value) - # if isinstance(value, float): - # # Render float to 2 dp - # return "%.2f" % value + + if isinstance(value, float): + # Render float to 2 dp + if len(str(value).split(".")[1]) <= 3: + return "%.2f" % value + else: + return "%.2e" % value # if isinstance(value, str): # # Render strings with quotes # return '"%s"' % value + return value + def rowCount(self, index): # The length of the outer list. return self._data.shape[0] @@ -36,4 +41,4 @@ class TableModel(QAbstractTableModel): if orientation == Qt.Horizontal: return str(self._data.columns[section]) if orientation == Qt.Vertical: - return str(self._data.index[section]) + return str(self._data.index[section]) \ No newline at end of file diff --git a/Model/acoustic_data_loader.py b/Model/acoustic_data_loader.py index 478079b..a61cad9 100644 --- a/Model/acoustic_data_loader.py +++ b/Model/acoustic_data_loader.py @@ -90,7 +90,7 @@ class AcousticDataLoader: # self.reshape_t() # self.compute_r_2D() - def reshape_BS_raw_cross_section(self): + def reshape_BS_raw_data(self): BS_raw_cross_section = np.reshape(self._BS_raw_data, (self._r.shape[1] * self._time.shape[1], self._freq.shape[0]), order="F") @@ -114,7 +114,7 @@ class AcousticDataLoader: print(r2D.shape) return r2D - def reshape_t(self): + def reshape_time(self): # t = np.reshape(np.repeat(self._time, self._r.shape[0]), (self._time.shape[0]*self._r.shape[0], 1)) t = np.zeros((self._r.shape[1] * self._time.shape[1], self._freq.shape[0])) for i, _ in enumerate(self._freq): diff --git a/View/acoustic_data_tab.py b/View/acoustic_data_tab.py index 75c18ec..eef40e2 100644 --- a/View/acoustic_data_tab.py +++ b/View/acoustic_data_tab.py @@ -1,10 +1,11 @@ +import os.path 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, - QProgressBar, QRadioButton, QFormLayout, QSlider) -from PyQt5.QtGui import QPixmap, QIcon + QProgressBar, QRadioButton, QFormLayout, QSlider, QAbstractItemView, QMenu, QItemDelegate) +from PyQt5.QtGui import QPixmap, QIcon, QFont, QMouseEvent from PyQt5.QtCore import Qt, QCoreApplication, pyqtSignal, pyqtSlot, QEvent import numpy as np @@ -24,7 +25,10 @@ locale.setlocale(locale.LC_ALL, '') from scipy.signal import savgol_filter -from pyqt_top_left_right_file_list_widget.topLeftRightFileListWidget import TopLeftRightFileListWidget +from pyqt_svg_button import SvgButton +from pyqt_file_list_widget.fileListWidget import FileListWidget + +from qtrangeslider import QLabeledDoubleRangeSlider # import Translation.biblio_string as bs import Translation.constant_string as cs @@ -41,18 +45,42 @@ import settings as stg _translate = QCoreApplication.translate +class FloatDelegate(QItemDelegate): + def __init__(self, decimals, parent=None): + QItemDelegate.__init__(self, parent=parent) + self.nDecimals = decimals + + def paint(self, painter, option, index): + value = index.model().data(index, Qt.EditRole) + try: + number = float(value) + painter.drawText(option.rect, Qt.AlignLeft, "{:.{}f}".format(number, self.nDecimals)) + except : + QItemDelegate.paint(self, painter, option, index) + class AcousticDataTab(QWidget): - ''' This class generates the Acoustic Data Tab ''' + """ + This class generates the Acoustic Data Tab + """ + + fileAdded = pyqtSignal(list) + fileRemoved = pyqtSignal(list) + newValueChanged = pyqtSignal(float) def __init__(self, tab_widget): super().__init__() + # Utiliser os.path.split() OU os.path.join() + self.path_icon = "./icons/" self.icon_folder = QIcon(self.path_icon + "folder.png") self.icon_triangle_left = QIcon(self.path_icon + "triangle_left.png") self.icon_triangle_right = QIcon(self.path_icon + "triangle_right.png") + self.icon_add_svg = QIcon(self.path_icon + "add.png") + self.icon_delete_svg = QIcon(self.path_icon + "delete.png") + self.icon_clear_svg = QIcon(self.path_icon + "clear.png") ### --- General layout of widgets --- @@ -66,16 +94,22 @@ class AcousticDataTab(QWidget): ### --- Layout of groupbox in the Top horizontal layout box - # Download | Measurement information | Table of values | Display options + # Download | Measurement information | Display options + # | Table of values | self.groupbox_download = QGroupBox() self.horizontalLayoutTop.addWidget(self.groupbox_download, 3) - self.groupbox_info = QGroupBox() - self.horizontalLayoutTop.addWidget(self.groupbox_info, 3) + self.verticalLayout_goupbox_info_groupbox_table = QVBoxLayout() + self.horizontalLayoutTop.addLayout(self.verticalLayout_goupbox_info_groupbox_table, 4) - # self.groupbox_table = QGroupBox() - # self.horizontalLayoutTop.addWidget(self.groupbox_table, 4) + self.groupbox_info = QGroupBox() + # self.verticalLayout_goupbox_info_groupbox_table.addWidget(self.groupbox_info, 5) + self.scrollbar_measurement_information = QScrollArea() + self.verticalLayout_goupbox_info_groupbox_table.addWidget(self.scrollbar_measurement_information, 4) + + self.groupbox_table = QGroupBox() + self.verticalLayout_goupbox_info_groupbox_table.addWidget(self.groupbox_table, 6) self.groupbox_display_option = QGroupBox() self.horizontalLayoutTop.addWidget(self.groupbox_display_option, 4) @@ -87,8 +121,8 @@ class AcousticDataTab(QWidget): self.groupbox_transect_2Dplot_raw_BS_data = QGroupBox() self.horizontalLayoutBottom.addWidget(self.groupbox_transect_2Dplot_raw_BS_data, 6) - self.groupbox_plot_profile = QGroupBox() - self.horizontalLayoutBottom.addWidget(self.groupbox_plot_profile, 4) + self.groupbox_plot_the_vertical_profile_for_a_frequency = QGroupBox() + self.horizontalLayoutBottom.addWidget(self.groupbox_plot_the_vertical_profile_for_a_frequency, 4) # self.groupbox_transect_2Dplot_snr_data = QGroupBox() # self.horizontalLayoutBottom.addWidget(self.groupbox_transect_2Dplot_snr_data) @@ -123,15 +157,42 @@ class AcousticDataTab(QWidget): 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(self.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.spacerItem_FileList = QSpacerItem(5, 10, QSizePolicy.Expanding, QSizePolicy.Minimum) + self.gridLayout_groupbox_acoustic_file.addItem(self.spacerItem_FileList, 0, 1, 1, 1) + + self.addBtn = SvgButton() + self.addBtn.setIcon("../icons/add.svg") + # self.addBtn = QPushButton() + # # self.addBtn.setText("Add") + # self.pushbutton_add.setIcon(self.icon_add_svg) + self.delBtn = SvgButton() + self.delBtn.setIcon("../icons/delete.svg") + # self.delBtn = QPushButton() + # # self.delBtn.setText("Del") + # self.delBtn.setIcon(self.icon_delete_svg) + self.clearBtn = SvgButton() + self.clearBtn.setIcon("../icons/clear.svg") + # self.clearBtn = QPushButton() + # # self.clearBtn.setText("Clear") + # self.clearBtn.setIcon(self.icon_clear_svg) + + self.gridLayout_groupbox_acoustic_file.addWidget(self.addBtn, 0, 2, 1, 1) + self.gridLayout_groupbox_acoustic_file.addWidget(self.delBtn, 0, 3, 1, 1) + self.gridLayout_groupbox_acoustic_file.addWidget(self.clearBtn, 0, 4, 1, 1) + + self.fileListWidget = FileListWidget() + self.gridLayout_groupbox_acoustic_file.addWidget(self.fileListWidget, 1, 0, 1, 5) + + # self.pushbutton_acoustic_file = QPushButton() + # self.pushbutton_acoustic_file.setObjectName("pushbutton_acoustic_file") + # self.pushbutton_acoustic_file.setIcon(self.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) # Download Push Button event : connect button clicked signal to open file slot - self.pushbutton_acoustic_file.clicked.connect(self.open_dialog_box) + # self.pushbutton_acoustic_file.clicked.connect(self.open_dialog_box) self.verticalLayout_groupbox_download.addWidget(self.groupbox_acoustic_file) @@ -169,12 +230,10 @@ class AcousticDataTab(QWidget): self.radiobutton_value = QRadioButton("Value") self.radiobutton_value.setChecked(True) - self.radiobutton_value.toggled.connect(self.onClicked_radiobutton_gps) self.horizontalLayout_radiobutton_gps.addWidget(self.radiobutton_value) self.radiobutton_file = QRadioButton("File") # self.radiobutton_file.setChecked(False) - self.radiobutton_file.toggled.connect(self.onClicked_radiobutton_gps) self.horizontalLayout_radiobutton_gps.addWidget(self.radiobutton_file) self.groupbox_gps_value = QGroupBox() @@ -256,21 +315,43 @@ class AcousticDataTab(QWidget): # self.verticalLayout_groupbox_info.addLayout(self.gridLayout_goupbox_info) # --- Information for Aquascat --- - self.gridLayout_goupbox_info = QGridLayout(self.groupbox_info) + # self.verticalLayout_goupbox_info = QGridLayout(self.groupbox_info) + + self.gridLayout_goupbox_info = QGridLayout() + self.groupbox_info.setLayout(self.gridLayout_goupbox_info) + + self.scrollbar_measurement_information.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) + self.scrollbar_measurement_information.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) + self.scrollbar_measurement_information.setWidgetResizable(True) + + self.scrollbar_measurement_information.setWidget(self.groupbox_info) + # self.self.gridLayout_goupbox_info = QGridLayout() + # self.scrollbar_measurement_information.setLayout(self.gridLayout_goupbox_info) + # self.verticalLayout_goupbox_info.addWidget(self.scrollbar_measurement_information) + + # scroll = QtWidgets.QScrollArea() + # scroll.setWidget(mygroupbox) + # scroll.setWidgetResizable(True) + # scroll.setFixedHeight(200) + # layout = QtWidgets.QVBoxLayout(self) + # layout.addWidget(scroll) self.label_temperature = QLabel("Temperature : ") self.gridLayout_goupbox_info.addWidget(self.label_temperature, 0, 0, 1, 1) + # self.label_temperature.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.spinbox_temperature = QDoubleSpinBox() - self.spinbox_temperature.valueChanged.connect(self.temperature_value) + self.gridLayout_goupbox_info.addWidget(self.spinbox_temperature, 0, 1, 1, 1) self.label_degreCelsius = QLabel("°C") self.gridLayout_goupbox_info.addWidget(self.label_degreCelsius, 0, 2, 1, 1) - self.label_date_acoustic_file = QLabel() - self.gridLayout_goupbox_info.addWidget(self.label_date_acoustic_file, 1, 0, 1, 2) - self.label_hour_acoustic_file = QLabel() - self.gridLayout_goupbox_info.addWidget(self.label_hour_acoustic_file, 1, 1, 1, 1) + # self.label_date_acoustic_file = QLabel() + # self.gridLayout_goupbox_info.addWidget(self.label_date_acoustic_file, 1, 0, 1, 2) + # self.label_hour_acoustic_file = QLabel() + # self.gridLayout_goupbox_info.addWidget(self.label_hour_acoustic_file, 1, 1, 1, 1) + self.label_date_acoustic_file = QLabel() + self.label_hour_acoustic_file = QLabel() self.label_profiles = QLabel() self.label_profiles_per_sec = QLabel() self.label_cells = QLabel() # n_cell in UBSediFlow parameters @@ -292,14 +373,13 @@ class AcousticDataTab(QWidget): self.label_r_dcell.setText("Inter-cell distance : ") # 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.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) @@ -317,16 +397,17 @@ class AcousticDataTab(QWidget): # 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.tableWidget = QTableWidget() + # self.tableWidget.setRowCount(10) + # self.tableWidget.setColumnCount(10) + # self.verticalLayout_groupbox_table.addWidget(self.tableWidget) + + 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() @@ -387,6 +468,123 @@ class AcousticDataTab(QWidget): self.verticalLayout_display_option = QVBoxLayout(self.groupbox_display_option) + # o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o + + self.groupbox_display_option_limits = QGroupBox() + self.gridLayout_groupbox_display_option_limits = QGridLayout(self.groupbox_display_option_limits) + + self.verticalLayout_display_option.addWidget(self.groupbox_display_option_limits) + + self.label_depth = QLabel("Depth: ") + self.gridLayout_groupbox_display_option_limits.addWidget(self.label_depth, 0, 0, 1, 1) + + # self.spinbox_depth_min = QDoubleSpinBox() + # self.spinbox_depth_min.setRange(0, 100000) + # self.gridLayout_groupbox_display_option.addWidget(self.spinbox_depth_min, 0, 1, 1, 1) + + self.doubleRangeSlider_depth = QLabeledDoubleRangeSlider() + self.doubleRangeSlider_depth.setOrientation(Qt.Horizontal) + # self.doubleRangeSlider_depth.setMinimumWidth(350) + self.doubleRangeSlider_depth.setRange(min=0, max=50) + self.doubleRangeSlider_depth.setValue(value=(5, 40)) + # print(self.doubleRangeSlider_depth.value()[0]) + self.doubleRangeSlider_depth.setFont(QFont("Ubuntu", 5)) + self.gridLayout_groupbox_display_option_limits.addWidget(self.doubleRangeSlider_depth, 0, 1, 1, 1) + + # self.spinbox_depth_max = QDoubleSpinBox() + # self.spinbox_depth_max.setRange(0, 100000) + # self.gridLayout_groupbox_display_option.addWidget(self.spinbox_depth_max, 0, 3, 1, 1) + + self.label_depth_unit_meter = QLabel("meters") + self.gridLayout_groupbox_display_option_limits.addWidget(self.label_depth_unit_meter, 0, 2, 1, 1) + + self.pushbutton_apply_depth_limits = QPushButton() + self.gridLayout_groupbox_display_option_limits.addWidget(self.pushbutton_apply_depth_limits, 0, 3, 1, 1) + + # -------------------------------- + + self.label_recording_time = QLabel("Recording time: ") + self.gridLayout_groupbox_display_option_limits.addWidget(self.label_recording_time, 1, 0, 1, 1) + + # self.spinbox_recording_time_min = QDoubleSpinBox() + # self.spinbox_recording_time_min.setRange(0, 100000) + # self.gridLayout_groupbox_display_option.addWidget(self.spinbox_recording_time_min, 1, 1, 1, 1) + + self.doubleRangeSlider_recording_time = QLabeledDoubleRangeSlider() + self.doubleRangeSlider_recording_time.setOrientation(Qt.Horizontal) + # self.doubleRangeSlider_recording_time.setStyleSheet() + # self.doubleRangeSlider_recording_time.setMinimumWidth(350) + # self.doubleRangeSlider_recording_time.setRange(min=0, max=50) + # self.doubleRangeSlider_recording_time.setValue(value=(5, 40)) + self.gridLayout_groupbox_display_option_limits.addWidget(self.doubleRangeSlider_recording_time, 1, 1, 1, 1) + + # self.spinbox_recording_time_max = QDoubleSpinBox() + # self.spinbox_recording_time_max.setRange(0, 100000) + # self.gridLayout_groupbox_display_option.addWidget(self.spinbox_recording_time_max, 1, 3, 1, 1) + + self.label_recording_time_unit_meter = QLabel("seconds") + self.gridLayout_groupbox_display_option_limits.addWidget(self.label_recording_time_unit_meter, 1, 2, 1, 1) + + self.pushbutton_apply_recording_time_limits = QPushButton() + self.gridLayout_groupbox_display_option_limits.addWidget(self.pushbutton_apply_recording_time_limits, 1, 3, 1, 1) + + # --------------------------------- + + self.label_distance_from_bank = QLabel("Distance from bank: ") + self.gridLayout_groupbox_display_option_limits.addWidget(self.label_distance_from_bank, 2, 0, 1, 1) + + # self.spinbox_distance_from_bank_min = QDoubleSpinBox() + # self.spinbox_distance_from_bank_min.setRange(0, 100000) + # self.gridLayout_groupbox_display_option.addWidget(self.spinbox_distance_from_bank_min, 2, 1, 1, 1) + + self.doubleRangeSlider_distance_from_bank = QLabeledDoubleRangeSlider() + self.doubleRangeSlider_distance_from_bank.setOrientation(Qt.Horizontal) + # self.doubleRangeSlider_distance_from_bank.setMinimumWidth(350) + self.doubleRangeSlider_distance_from_bank.setRange(min=0, max=50) + self.doubleRangeSlider_distance_from_bank.setValue(value=(5, 40)) + self.gridLayout_groupbox_display_option_limits.addWidget(self.doubleRangeSlider_distance_from_bank, 2, 1, 1, 1) + + # self.spinbox_distance_from_bank_max = QDoubleSpinBox() + # self.spinbox_distance_from_bank_max.setRange(0, 100000) + # self.gridLayout_groupbox_display_option.addWidget(self.spinbox_distance_from_bank_max, 2, 3, 1, 1) + + self.label_distance_from_bank_unit_meter = QLabel("meters") + self.gridLayout_groupbox_display_option_limits.addWidget(self.label_distance_from_bank_unit_meter, 2, 2, 1, 1) + + self.pushbutton_apply_distance_from_bank__limits = QPushButton() + self.gridLayout_groupbox_display_option_limits.addWidget(self.pushbutton_apply_distance_from_bank__limits, 2, 3, 1, 1) + + # --------------------------------------- + + self.groupbox_display_option_bathymetry = QGroupBox() + self.gridLayout_groupbox_display_option_bathymetry = QGridLayout(self.groupbox_display_option_bathymetry) + + self.verticalLayout_display_option.addWidget(self.groupbox_display_option_bathymetry) + + self.combobox_frequency_bathymetry = QComboBox() + self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.combobox_frequency_bathymetry, 0, 0, 1, 1) + + self.label_1st_intg_area = QLabel("1st intg area") + self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.label_1st_intg_area, 0, 1, 1, 1) + + self.doubleRangeSlider_intg_area = QLabeledDoubleRangeSlider() + self.doubleRangeSlider_intg_area.setOrientation(Qt.Vertical) + # self.doubleRangeSlider_distance_from_bank.setMinimumWidth(350) + self.doubleRangeSlider_intg_area.setRange(min=0, max=50) + self.doubleRangeSlider_intg_area.setValue(value=(5, 40)) + self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.doubleRangeSlider_intg_area, 0, 2, 1, 1) + + self.label_offset = QLabel("Offset") + self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.label_offset, 0, 3, 1, 1) + + self.spinbox_offset_next_cell = QDoubleSpinBox() + self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.spinbox_offset_next_cell, 0, 4, 1, 1) + + self.pushbutton_apply_bathymetry = QPushButton() + self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.pushbutton_apply_bathymetry, 0, 5, 1, 1) + + # o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o + # --- Push buttons to trigger plot of transect with Backscatter acoustic raw data and SNR --- # self.gridLayout_plot_transect_frequency_profile = QGridLayout() @@ -412,165 +610,162 @@ class AcousticDataTab(QWidget): # 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_time = QLabel() - self.label_from_time.setText("From") - self.gridLayout_groupbox_xaxis_time.addWidget(self.label_from_time, 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_time = QLabel() - self.label_to_time.setText("to") - self.gridLayout_groupbox_xaxis_time.addWidget(self.label_to_time, 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) - - self.pushbutton_apply_transect_boundaries_in_time = QPushButton() - self.pushbutton_apply_transect_boundaries_in_time.setText("Apply") - self.gridLayout_groupbox_xaxis_time.addWidget(self.pushbutton_apply_transect_boundaries_in_time, 0, 7, 1, 1) - self.pushbutton_apply_transect_boundaries_in_time.clicked.connect(self.update_xaxis_transect_with_BS_raw_data) - # self.pushbutton_apply_transect_boundaries_in_time.clicked.connect(self.update_xaxis_transect_with_SNR_data) - self.pushbutton_apply_transect_boundaries_in_time.clicked.connect(self.update_plot_profile) - - # --- 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_space = QLabel() - self.label_from_space.setText("From ") - self.gridLayout_groupbox_xaxis_space.addWidget(self.label_from_space, 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_space = QLabel() - self.label_to_space.setText("to") - self.gridLayout_groupbox_xaxis_space.addWidget(self.label_to_space, 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) - - self.pushbutton_apply_transect_boundaries_in_space = QPushButton() - self.pushbutton_apply_transect_boundaries_in_space.setText("Apply") - self.gridLayout_groupbox_xaxis_space.addWidget(self.pushbutton_apply_transect_boundaries_in_space, 0, 8, 1, 1) - self.pushbutton_apply_transect_boundaries_in_space.clicked.connect(self.update_xaxis_transect_with_BS_raw_data) - # self.pushbutton_apply_transect_boundaries_in_space.clicked.connect(self.update_xaxis_transect_with_SNR_data) - - # --- 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.label_from_bathy = QLabel() - self.label_from_bathy.setText("From - ") - self.gridlayout_compute_bathymetry.addWidget(self.label_from_bathy, 0, 1, 1, 1) - - # self.spinbox_depth_min = QSpinBox() - self.spinbox_depth_min = QDoubleSpinBox() - self.spinbox_depth_min.setRange(0, 9999) - self.spinbox_depth_min.setDecimals(2) - 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.label_to_bathy = QLabel() - self.label_to_bathy.setText("to - ") - self.gridlayout_compute_bathymetry.addWidget(self.label_to_bathy, 0, 4, 1, 1) - - # self.spinbox_depth_max = QSpinBox() - self.spinbox_depth_max = QDoubleSpinBox() - self.spinbox_depth_max.setRange(0, 99999) - self.spinbox_depth_max.setDecimals(2) - 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) + # # --- Group Box Plot x-axis in time --- + # + # self.groupbox_xaxis_time = QGroupBox() + # # self.verticalLayout_groupbox_xaxis_time = QVBoxLayout(self.groupbox_xaxis_time) + # # 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_time = QLabel() + # self.label_from_time.setText("From") + # # self.gridLayout_groupbox_xaxis_time.addWidget(self.label_from_time, 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_time = QLabel() + # self.label_to_time.setText("to") + # self.gridLayout_groupbox_xaxis_time.addWidget(self.label_to_time, 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.spinbox_tmax.keyPressEvent.connect(self.onValueChanged) + # + # 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) + # + # self.pushbutton_apply_transect_boundaries_in_time = QPushButton() + # self.pushbutton_apply_transect_boundaries_in_time.setText("Apply") + # self.gridLayout_groupbox_xaxis_time.addWidget(self.pushbutton_apply_transect_boundaries_in_time, 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_space = QLabel() + # self.label_from_space.setText("From ") + # self.gridLayout_groupbox_xaxis_space.addWidget(self.label_from_space, 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_space = QLabel() + # self.label_to_space.setText("to") + # self.gridLayout_groupbox_xaxis_space.addWidget(self.label_to_space, 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) + # + # self.pushbutton_apply_transect_boundaries_in_space = QPushButton() + # self.pushbutton_apply_transect_boundaries_in_space.setText("Apply") + # self.gridLayout_groupbox_xaxis_space.addWidget(self.pushbutton_apply_transect_boundaries_in_space, 0, 8, 1, 1) + # # self.pushbutton_apply_transect_boundaries_in_space.clicked.connect(self.update_xaxis_transect_with_BS_raw_data) + # # self.pushbutton_apply_transect_boundaries_in_space.clicked.connect(self.update_xaxis_transect_with_SNR_data) + # + # # --- 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.label_from_bathy = QLabel() + # self.label_from_bathy.setText("From - ") + # self.gridlayout_compute_bathymetry.addWidget(self.label_from_bathy, 0, 1, 1, 1) + # + # # self.spinbox_depth_min = QSpinBox() + # self.spinbox_depth_min = QDoubleSpinBox() + # self.spinbox_depth_min.setRange(0, 9999) + # self.spinbox_depth_min.setDecimals(2) + # 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.label_to_bathy = QLabel() + # self.label_to_bathy.setText("to - ") + # self.gridlayout_compute_bathymetry.addWidget(self.label_to_bathy, 0, 4, 1, 1) + # + # # self.spinbox_depth_max = QSpinBox() + # self.spinbox_depth_max = QDoubleSpinBox() + # self.spinbox_depth_max.setRange(0, 99999) + # self.spinbox_depth_max.setDecimals(2) + # 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) # ===================================================== # BOTTOM HORIZONTAL BOX LAYOUT @@ -584,20 +779,21 @@ class AcousticDataTab(QWidget): # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.setContentsMargins(0, 0, 0, 0) # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.setSpacing(0) - self.canvas_BS = None - self.scroll_BS = None + # self.canvas_BS = None + # self.scroll_BS = None # self.fig_BS, self.axis_BS = plt.subplots(nrows=4, ncols=1, sharex=True, sharey=False, # layout="constrained") # self.canvas_BS = FigureCanvas(self.fig_BS) - # # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) - # self.scroll_BS = QScrollArea() - # self.scroll_BS.setWidget(self.canvas_BS) - # self.scroll_BS.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) - # self.scroll_BS.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) - # # self.scroll_BS.setWidgetResizable(True) - # self.scroll_BS.setAlignment(Qt.AlignCenter) - # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS) + self.canvas_BS = FigureCanvas() + # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) + self.scroll_BS = QScrollArea() + self.scroll_BS.setWidget(self.canvas_BS) + self.scroll_BS.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) + self.scroll_BS.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) + # self.scroll_BS.setWidgetResizable(True) + self.scroll_BS.setAlignment(Qt.AlignCenter) + self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS) # 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) @@ -632,22 +828,140 @@ class AcousticDataTab(QWidget): # | Group Box Plot profile from BS 2D field | # +++++++++++++++++++++++++++++++++++++++++++ - self.verticalLayout_groupbox_plot_profile = QVBoxLayout(self.groupbox_plot_profile) - self.groupbox_plot_profile.setTitle("Profiles") + self.verticalLayout_groupbox_plot_the_vertical_profile_for_a_frequency = QVBoxLayout(self.groupbox_plot_the_vertical_profile_for_a_frequency) + self.groupbox_plot_the_vertical_profile_for_a_frequency.setTitle("Plot the vertical profile for one frequency") self.horizontalLayout_spacerItem_combobox_frequency_profile = QHBoxLayout() - self.verticalLayout_groupbox_plot_profile.addLayout(self.horizontalLayout_spacerItem_combobox_frequency_profile) + self.verticalLayout_groupbox_plot_the_vertical_profile_for_a_frequency.addLayout(self.horizontalLayout_spacerItem_combobox_frequency_profile) self.spacerItem_frequency_profile = QSpacerItem(50, 10, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_spacerItem_combobox_frequency_profile.addSpacerItem(self.spacerItem_frequency_profile) self.combobox_frequency_profile = QComboBox() self.horizontalLayout_spacerItem_combobox_frequency_profile.addWidget(self.combobox_frequency_profile) - self.canvas_plot_profile = None + self.groupbox_plot_profile = QGroupBox() + self.groupbox_plot_profile.setTitle("Profile") + self.verticalLayout_groupbox_plot_profile = QVBoxLayout(self.groupbox_plot_profile) + self.verticalLayout_groupbox_plot_the_vertical_profile_for_a_frequency.addWidget(self.groupbox_plot_profile) + + # self.fig_profile, self.axis_profile = plt.subplots(nrows=1, ncols=1, layout="constrained") + # self.canvas_plot_profile = FigureCanvas(self.fig_profile) + self.canvas_plot_profile = FigureCanvas() + self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_plot_profile) + + # self.canvas_plot_profile = None + + # --- Slider for moving the profile --- + self.horizontalLayout_slider = QHBoxLayout() + self.verticalLayout_groupbox_plot_the_vertical_profile_for_a_frequency.addLayout(self.horizontalLayout_slider) + + self.pushbutton_slider_left = QPushButton() + self.pushbutton_slider_left.setIcon(self.icon_triangle_left) + self.horizontalLayout_slider.addWidget(self.pushbutton_slider_left) + + self.pushbutton_slider_right = QPushButton() + self.pushbutton_slider_right.setIcon(self.icon_triangle_right) + self.horizontalLayout_slider.addWidget(self.pushbutton_slider_right) + + self.lineEdit_slider = QLineEdit() + self.lineEdit_slider.setText("1") + self.lineEdit_slider.setFixedWidth(50) + self.horizontalLayout_slider.addWidget(self.lineEdit_slider) + + self.slider = QSlider() + self.horizontalLayout_slider.addWidget(self.slider, 9) + + self.slider.setOrientation(Qt.Horizontal) + self.slider.setCursor(Qt.OpenHandCursor) + self.slider.setMinimum(1) + self.slider.setMaximum(10) + self.slider.setTickInterval(1) + self.slider.setValue(1) + + # self.slider.valueChanged.connect(self.plot_transect_with_BS_raw_data) + # self.slider.valueChanged.connect(self.plot_profile) self.retranslate_acoustic_data_tab() + self.max_selected_file = 1 + # self.btnToggled() + + # -------------------------------------------------------------------------------------------------------------- + # --- Connect signal of widget --- + + self.combobox_ABS_system_choice.currentTextChanged.connect(self.ABS_system_choice) + + self.addBtn.clicked.connect(self.open_dialog_box) + self.delBtn.clicked.connect(self.remove_file_from_ListWidget) + self.clearBtn.clicked.connect(self.clear_files_from_ListWidget) + + self.fileListWidget.itemSelectionChanged.connect(self.print_selected_file) + self.fileListWidget.itemSelectionChanged.connect(self.fill_measurements_information_groupbox) + self.fileListWidget.itemSelectionChanged.connect(self.fill_table) + self.fileListWidget.itemSelectionChanged.connect(self.compute_time) + self.fileListWidget.itemSelectionChanged.connect(self.compute_depth) + self.fileListWidget.itemSelectionChanged.connect(self.compute_BS_cross_section) + self.fileListWidget.itemSelectionChanged.connect(self.update_frequency_combobox) + self.fileListWidget.itemSelectionChanged.connect(self.plot_backscattered_acoustic_signal_recording) + self.fileListWidget.itemSelectionChanged.connect(self.plot_profile) + self.fileListWidget.itemSelectionChanged.connect(self.update_plot_backscattered_acoustic_signal_recording) + self.fileListWidget.itemSelectionChanged.connect(self.update_plot_profile) + # self.fileListWidget.installEventFilter() + + # self.fileListWidget.clicked.connect(self.rename_file_in_ListWidget) + + self.radiobutton_value.toggled.connect(self.onClicked_radiobutton_gps) + self.radiobutton_file.toggled.connect(self.onClicked_radiobutton_gps) + + self.spinbox_temperature.valueChanged.connect(self.temperature_value) + + # self.spinbox_tmax.lineEdit().returnPressed.connect(self.time_spin_box_value) + # self.spinbox_tmax.lineEdit().returnPressed.connect(self.compute_time) + # self.spinbox_tmax.lineEdit().returnPressed.connect(self.compute_BS_cross_section) + # self.spinbox_tmax.lineEdit().returnPressed.connect(self.update_plot_backscattered_acoustic_signal_recording) + # self.spinbox_tmax.lineEdit().returnPressed.connect(self.update_plot_profile) + + # self.doubleRangeSlider_recording_time.lab .connect(self.print_value_doubleRangeSlider) + + self.pushbutton_apply_depth_limits.clicked.connect(self.set_rmin_rmax_for_doubleRangeSider_depth) + self.pushbutton_apply_depth_limits.clicked.connect(self.compute_depth) + self.pushbutton_apply_depth_limits.clicked.connect(self.compute_BS_cross_section) + self.pushbutton_apply_depth_limits.clicked.connect(self.update_plot_backscattered_acoustic_signal_recording) + self.pushbutton_apply_depth_limits.clicked.connect(self.update_plot_profile) + self.pushbutton_apply_depth_limits.clicked.connect(self.set_range_for_doubleRangeSlider_intg_area) + + self.pushbutton_apply_recording_time_limits.clicked.connect(self.set_tmin_tmax_for_doubleRangeSider_time) + self.pushbutton_apply_recording_time_limits.clicked.connect(self.compute_time) + self.pushbutton_apply_recording_time_limits.clicked.connect(self.compute_BS_cross_section) + self.pushbutton_apply_recording_time_limits.clicked.connect(self.update_plot_backscattered_acoustic_signal_recording) + self.pushbutton_apply_recording_time_limits.clicked.connect(self.update_plot_profile) + + # self.pushbutton_apply_transect_boundaries_in_time.clicked.connect(self.compute_time) + # self.pushbutton_apply_transect_boundaries_in_time.clicked.connect(self.compute_BS_cross_section) + # self.pushbutton_apply_transect_boundaries_in_time.clicked.connect( + # self.update_plot_backscattered_acoustic_signal_recording) + # self.pushbutton_apply_transect_boundaries_in_time.clicked.connect(self.update_plot_profile) + + self.pushbutton_apply_bathymetry.clicked.connect(self.detect_bottom) + + self.pushbutton_slider_left.clicked.connect(self.slide_profile_number_to_left) + + self.pushbutton_slider_right.clicked.connect(self.slide_profile_number_to_right) + + self.lineEdit_slider.returnPressed.connect(self.profile_number_on_lineEdit) + + self.slider.valueChanged.connect(self.update_lineEdit_by_moving_slider) + self.slider.valueChanged.connect(self.update_plot_profile) + self.slider.valueChanged.connect(self.update_plot_backscattered_acoustic_signal_recording) + # -------------------- Functions for Acoustic dataTab -------------------- + def print_value_doubleRangeSlider(self): + if Qt.Key_Return: + print(f"value of double range slider {self.doubleRangeSlider_recording_time.value()}") + + def print_range_changed(self): + print(f"tmax = {self.doubleRangeSlider_depth.value()[1]}") + def retranslate_acoustic_data_tab(self): self.groupbox_download.setTitle(_translate("CONSTANT_STRING", cs.DOWNLOAD)) @@ -712,17 +1026,17 @@ class AcousticDataTab(QWidget): # 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.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.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.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)) @@ -732,6 +1046,36 @@ class AcousticDataTab(QWidget): # self.groupbox_transect_2Dplot_snr_data.setTitle(_translate("CONSTANT_STRING", cs.SIGNAL_TO_NOISE_RATIO_2D_FIELD)) + # def currentItemChanged(self, i1, i2): + # self.btnToggled() + + # def btnToggled(self): + # # f1 = self.fileListWidget.count() > 0 + # # f2 = True if self.fileListWidget.currentItem() else False + # # print(f"f1 {f1}") + # # print(f"f2 {f2}") + # # self.delBtn.setEnabled(f1 and f2) + # # self.clearBtn.setEnabled(f1) + # print("self.fileListWidget.selectedItems()[1:] : ", self.fileListWidget.selectedItems()[1:]) + # if len(self.fileListWidget.selectedItems()) > self.max_selected_file: + # self.fileListWidget.selectedItems()[1:].setSelected(False) + + + def print_selected_file(self): + print(f"Selected file in list widget : {self.fileListWidget.selectedItems()}") + print("self.fileListWidget.selectedItems()[1:] : ", self.fileListWidget.selectedItems()[1:]) + if len(self.fileListWidget.selectedItems()) > self.max_selected_file: + self.fileListWidget.setSelectionMode(1) + + # def add(self): + # # ext_lst = self.__extensions if self.__extensions else 'All Files (*.*)' + # filenames = QFileDialog.getOpenFileNames(self, 'Open Files', '', ext_lst) + # if filenames[0]: + # filenames = filenames[0] + # self.fileListWidget.addFilenames(filenames) + # self.fileAdded.emit(filenames) + # # self.__btnToggled() + def onClicked_radiobutton_gps(self): radiobutton = self.sender() @@ -746,10 +1090,10 @@ class AcousticDataTab(QWidget): 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.lineEdit_acoustic_file.clear() elif self.combobox_ABS_system_choice.currentText() == "UB-SediFlow": self.groupbox_measurement_information_UBSediFlow() - self.lineEdit_acoustic_file.clear() + # 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.clear() @@ -761,6 +1105,8 @@ class AcousticDataTab(QWidget): self.label_freq.hide() + self.label_date_acoustic_file.show() + self.label_hour_acoustic_file.show() self.label_profiles.show() self.label_profiles_per_sec.show() self.label_cells.show() @@ -773,6 +1119,8 @@ class AcousticDataTab(QWidget): self.label_rx.show() self.label_tx.show() + self.gridLayout_goupbox_info.addWidget(self.label_date_acoustic_file, 1, 0, 1, 2) + self.gridLayout_goupbox_info.addWidget(self.label_hour_acoustic_file, 1, 1, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_profiles, 2, 0, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_profiles_per_sec, 2, 1, 1, 1) self.gridLayout_goupbox_info.addWidget(self.label_cells, 3, 0, 1, 1) @@ -788,6 +1136,8 @@ class AcousticDataTab(QWidget): def groupbox_measurement_information_UBSediFlow(self): # self.gridLayout_goupbox_info.itemAt(0).widget().deleteLater() + self.label_date_acoustic_file.hide() + self.label_hour_acoustic_file.hide() self.label_profiles.hide() self.label_profiles_per_sec.hide() self.label_cells.hide() @@ -844,36 +1194,57 @@ class AcousticDataTab(QWidget): # --- Fill lineEdit with path and file names + load acoustic data --- # --- fill date, hour and measurements information + fill frequency combobox for bottom detection --- if self.combobox_ABS_system_choice.currentIndex() != 0: - if self.sender().objectName() == "pushbutton_acoustic_file": + # if self.sender().objectName() == "pushbutton_acoustic_file": # if self.sender(): # stg.path_BS_raw_data = dir_name # stg.filename_BS_raw_data = name # self.load_BS_acoustic_raw_data() - try: - stg.path_BS_raw_data = dir_name - stg.filename_BS_raw_data = name - self.load_BS_acoustic_raw_data() - # print("0 Je suis sur la donnée BS") - except ValueError as e: - # print("error : ", e) - # print("1 Je suis sur la donnée BS") - msgBox = QMessageBox() - msgBox.setWindowTitle("Download Error") - msgBox.setIcon(QMessageBox.Warning) - msgBox.setText("Please select a file") - msgBox.setStandardButtons(QMessageBox.Ok) - msgBox.exec() + try: + if self.fileListWidget.count() == 0: + stg.path_BS_raw_data = [dir_name] + stg.filename_BS_raw_data = [name] else: - self.lineEdit_acoustic_file.setText(stg.filename_BS_raw_data) - self.lineEdit_acoustic_file.setToolTip(stg.path_BS_raw_data) - self.label_date_acoustic_file.setText( - _translate("CONSTANT_STRING", cs.DATE) + ": " + str(stg.date)) - self.label_hour_acoustic_file.setText( - _translate("CONSTANT_STRING", cs.HOUR) + ": " + str(stg.hour)) - self.fill_measurements_information_groupbox() - self.plot_transect_with_BS_raw_data() - self.combobox_freq_choice.addItems([f for f in stg.freq_text]) - self.combobox_frequency_profile.addItems([f for f in stg.freq_text]) + stg.path_BS_raw_data.append(dir_name) + stg.filename_BS_raw_data.append(name) + self.load_BS_acoustic_raw_data() + print("0 Lecture de la donnée BS") + except ValueError as e: + # print("error : ", e) + # print("1 Je suis sur la donnée BS") + msgBox = QMessageBox() + msgBox.setWindowTitle("Download Error") + msgBox.setIcon(QMessageBox.Warning) + msgBox.setText("Please select a file") + msgBox.setStandardButtons(QMessageBox.Ok) + msgBox.exec() + else: + print("1 Fill widget and plot graphs") + print(f"stg.path_BS_raw_data {stg.path_BS_raw_data}") + print(f"stg.filename_BS_raw_data {stg.filename_BS_raw_data}") + # self.lineEdit_acoustic_file.setText(stg.filename_BS_raw_data) + # self.lineEdit_acoustic_file.setToolTip(stg.path_BS_raw_data) + print("0. Number of filenames in fileListWidget : ", self.fileListWidget.count()) + self.fileListWidget.addFilenames([stg.filename_BS_raw_data[-1]]) + print("1. Number of filenames in fileListWidget : ", self.fileListWidget.count()) + # self.btnToggled() + self.fileListWidget.setToolTip(stg.path_BS_raw_data[-1]) + self.label_date_acoustic_file.clear() + self.label_date_acoustic_file.setText( + _translate("CONSTANT_STRING", cs.DATE) + ": " + str(stg.date[self.fileListWidget.currentRow()])) + self.label_hour_acoustic_file.clear() + self.label_hour_acoustic_file.setText( + _translate("CONSTANT_STRING", cs.HOUR) + ": " + str(stg.hour[self.fileListWidget.currentRow()])) + self.fill_measurements_information_groupbox() + self.fill_table() + self.set_range_for_doubleRangeSlider_time() + self.set_range_for_doubleRangeSlider_depth() + self.set_range_for_doubleRangeSlider_intg_area() + self.plot_backscattered_acoustic_signal_recording() + self.update_frequency_combobox() + # self.combobox_frequency_bathymetry.clear() + # self.combobox_frequency_bathymetry.addItems([f for f in stg.freq_text[self.fileListWidget.currentRow()]]) + # self.combobox_frequency_profile.clear() + # self.combobox_frequency_profile.addItems([f for f in stg.freq_text[self.fileListWidget.currentRow()]]) # if self.sender().objectName() == "pushbutton_noise_file": # print("--- 0. Je suis dans le push button noise file ---") @@ -901,48 +1272,179 @@ class AcousticDataTab(QWidget): # self.label_hour_groupbox_noise_file.setText( # _translate("CONSTANT_STRING", cs.HOUR) + ": " + str(stg.hour_noise)) + def rename_file_in_ListWidget(self, event): + print("souris cliqué !") + print(f"event = {event}") + if event == QEvent.MouseButtonPress: + print("c'est bon") + if event.button == Qt.RightButton: + print("Right button clicked") + elif event.button == Qt.LeftButton: + print("Left button clicked") + + if event.type() == QEvent.ContextMenu: + menu = QMenu() + menu.addAction('Rename') + + # if menu.exec_(event.globalPos()): + # item = self.fileListWidget.itemAt(event.pos()) + # print(item.text()) + # return True + # return super().eventFilter(source, event) + + def remove_file_from_ListWidget(self): + if self.fileListWidget.count() > 0: + current_row = self.fileListWidget.currentRow() + if current_row >= 0: + current_item = self.fileListWidget.takeItem(current_row) + del current_item + + stg.BS_raw_data.pop(current_row) + stg.time.pop(current_row) + + if len(stg.tmax) == len(stg.time): + stg.tmin.pop(current_row) + stg.tmax.pop(current_row) + stg.t_cross_section.pop(current_row) + stg.BS_cross_section.pop(current_row) + + def clear_files_from_ListWidget(self): + if self.fileListWidget.count() > 0: + self.fileListWidget.clear() + + stg.BS_raw_data.clear() + stg.time.clear() + stg.tmin.clear() + stg.tmax.clear() + stg.t_cross_section.clear() + stg.BS_cross_section.clear() + + # --- Clear measurmeents information --- + self.spinbox_temperature.clear() + self.ABS_system_choice() + + # --- Clear display options --- + self.spinbox_tmin.setValue(0) + self.spinbox_tmax.setValue(0) + self.spinbox_xmin.setValue(0) + self.spinbox_xmax.setValue(0) + self.combobox_frequency_bathymetry.clear() + self.spinbox_depth_min.setValue(0) + self.spinbox_depth_max.setValue(0) + self.doublespinbox_next_cell.setValue(0) + + # --- Clear figure area for backscattered acoutsic signal recording --- + self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) + self.canvas_BS = FigureCanvas() + self.scroll_BS.setWidget(self.canvas_BS) + self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS) + + # --- Clear figure area for profile --- + self.combobox_frequency_profile.clear() + + if self.fig_profile: + self.axis_profile.cla() + self.fig_profile.clf() + self.verticalLayout_groupbox_plot_profile.removeWidget(self.canvas_plot_profile) + self.canvas_plot_profile = FigureCanvas() + self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_plot_profile) + + self.slider.setValue(0) + self.slider.setMaximum(10) + def load_BS_acoustic_raw_data(self): if self.combobox_ABS_system_choice.currentIndex() == 1: - acoustic_data = AcousticDataLoader(stg.path_BS_raw_data + "/" + stg.filename_BS_raw_data) - stg.ABS_name = self.combobox_ABS_system_choice.currentText() - stg.BS_raw_data = acoustic_data._BS_raw_data - stg.BS_raw_data_reshape = acoustic_data.reshape_BS_raw_cross_section() - stg.r = acoustic_data._r - stg.r_2D = acoustic_data.compute_r_2D() - stg.r_reshape = acoustic_data.reshape_r() - stg.time = acoustic_data._time - stg.time_reshape = acoustic_data.reshape_t() - stg.freq = acoustic_data._freq - stg.freq_text = acoustic_data._freq_text - stg.date = acoustic_data._date - stg.hour = acoustic_data._hour - stg.nb_profiles = acoustic_data._nb_profiles - stg.nb_profiles_per_sec = acoustic_data._nb_profiles_per_sec - stg.nb_cells = acoustic_data._nb_cells - stg.cell_size = acoustic_data._cell_size - stg.pulse_length = acoustic_data._cell_size - stg.nb_pings_per_sec = acoustic_data._nb_pings_per_sec - stg.nb_pings_averaged_per_profile = acoustic_data._nb_pings_averaged_per_profile - stg.kt = acoustic_data._kt - stg.gain_rx = acoustic_data._gain_rx - stg.gain_tx = acoustic_data._gain_tx + + acoustic_data = AcousticDataLoader(stg.path_BS_raw_data[-1] + "/" + stg.filename_BS_raw_data[-1]) + + if self.fileListWidget.count() == 0: + + stg.ABS_name = [self.combobox_ABS_system_choice.currentText()] + stg.BS_raw_data = [acoustic_data._BS_raw_data] + print("len(stg.BS_raw_data) ", len(stg.BS_raw_data)) + print("stg.BS_raw_data[0].shape ", stg.BS_raw_data[0].shape) + stg.BS_raw_data_reshape = [acoustic_data.reshape_BS_raw_data()] + stg.depth = [acoustic_data._r] + stg.depth_2D = [acoustic_data.compute_r_2D()] + # stg.depth_reshape = [acoustic_data.reshape_r()] + stg.time = [acoustic_data._time] + stg.time_reshape = [acoustic_data.reshape_time()] + stg.freq = [acoustic_data._freq] + stg.freq_text = [acoustic_data._freq_text] + print("freq text ", stg.freq_text) + stg.date = [acoustic_data._date] + stg.hour = [acoustic_data._hour] + stg.nb_profiles = [acoustic_data._nb_profiles] + stg.nb_profiles_per_sec = [acoustic_data._nb_profiles_per_sec] + stg.nb_cells = [acoustic_data._nb_cells] + stg.cell_size = [acoustic_data._cell_size] + stg.pulse_length = [acoustic_data._cell_size] + stg.nb_pings_per_sec = [acoustic_data._nb_pings_per_sec] + stg.nb_pings_averaged_per_profile = [acoustic_data._nb_pings_averaged_per_profile] + stg.kt = [acoustic_data._kt] + stg.gain_rx = [acoustic_data._gain_rx] + stg.gain_tx = [acoustic_data._gain_tx] + + else: + + stg.ABS_name.append(self.combobox_ABS_system_choice.currentText()) + stg.BS_raw_data.append(acoustic_data._BS_raw_data) + stg.BS_raw_data_reshape.append(acoustic_data.reshape_BS_raw_data()) + stg.depth.append(acoustic_data._r) + stg.depth_2D.append(acoustic_data.compute_r_2D()) + # stg.depth_reshape = [acoustic_data.reshape_r()] + stg.time.append(acoustic_data._time) + stg.time_reshape.append(acoustic_data.reshape_time()) + stg.freq.append(acoustic_data._freq) + stg.freq_text.append(acoustic_data._freq_text) + stg.date.append(acoustic_data._date) + stg.hour.append(acoustic_data._hour) + stg.nb_profiles.append(acoustic_data._nb_profiles) + stg.nb_profiles_per_sec.append(acoustic_data._nb_profiles_per_sec) + stg.nb_cells.append(acoustic_data._nb_cells) + stg.cell_size.append(acoustic_data._cell_size) + stg.pulse_length.append(acoustic_data._cell_size) + stg.nb_pings_per_sec.append(acoustic_data._nb_pings_per_sec) + stg.nb_pings_averaged_per_profile.append(acoustic_data._nb_pings_averaged_per_profile) + stg.kt.append(acoustic_data._kt) + stg.gain_rx.append(acoustic_data._gain_rx) + stg.gain_tx.append(acoustic_data._gain_tx) + elif self.combobox_ABS_system_choice.currentIndex() == 2: - acoustic_data = AcousticDataLoaderUBSediFlow(stg.path_BS_raw_data + "/" + stg.filename_BS_raw_data) - stg.ABS_name = self.combobox_ABS_system_choice.currentText() - stg.date = acoustic_data._date - stg.hour = acoustic_data._hour - stg.freq = acoustic_data._freq - stg.time = acoustic_data._time - stg.r = acoustic_data._r - stg.r_2D = acoustic_data.compute_r_2D() - stg.freq_text = acoustic_data._freq_text - stg.BS_raw_data = acoustic_data._BS_raw_data - stg.BS_raw_data_reshape = acoustic_data.reshape_BS_raw_cross_section() - stg.r_reshape = acoustic_data.reshape_r() - stg.time_reshape = acoustic_data.reshape_t() + + acoustic_data = AcousticDataLoaderUBSediFlow(stg.path_BS_raw_data[-1] + "/" + stg.filename_BS_raw_data[-1]) + + if self.fileListWidget.count() == 0: + + stg.ABS_name = [self.combobox_ABS_system_choice.currentText()] + stg.date = [acoustic_data._date] + stg.hour = [acoustic_data._hour] + stg.freq = [acoustic_data._freq] + stg.time = [acoustic_data._time] + stg.depth = [acoustic_data._r] + stg.depth_2D = [acoustic_data.compute_r_2D()] + stg.freq_text = [acoustic_data._freq_text] + stg.BS_raw_data = [acoustic_data._BS_raw_data] + # stg.BS_raw_data_reshape = acoustic_data.reshape_BS_raw_cross_section() + # stg.depth_reshape = acoustic_data.reshape_r() + # stg.time_reshape = acoustic_data.reshape_t() + + else: + + stg.ABS_name.append(self.combobox_ABS_system_choice.currentText()) + stg.date.append(acoustic_data._date) + stg.hour.append(acoustic_data._hour) + stg.freq.append(acoustic_data._freq) + stg.time.append(acoustic_data._time) + stg.depth.append(acoustic_data._r) + stg.depth_2D.append(acoustic_data.compute_r_2D()) + stg.freq_text.append(acoustic_data._freq_text) + stg.BS_raw_data.append(acoustic_data._BS_raw_data) + + # stg.SNR_data = acoustic_data._SNR_data # stg.snr_reshape = acoustic_data.reshape_SNR_data() - # print(f"r = {stg.r}") + # print(f"r = {stg.depth}") # def load_noise_data_and_compute_SNR(self): # if self.combobox_ABS_system_choice.currentIndex() == 1: @@ -959,7 +1461,7 @@ class AcousticDataTab(QWidget): # noise[f, :, :] = np.mean(stg.BS_noise_raw_data[f, :, :], axis=(0, 1)) # stg.BS_noise_averaged_data = noise # stg.SNR_data = np.divide((stg.BS_raw_data - stg.BS_noise_averaged_data) ** 2, stg.BS_noise_averaged_data ** 2) - # stg.SNR_reshape = np.reshape(stg.SNR_data, (stg.r.shape[1] * stg.time.shape[1], stg.freq.shape[0]), order="F") + # stg.SNR_reshape = np.reshape(stg.SNR_data, (stg.depth.shape[1] * stg.time.shape[1], stg.freq.shape[0]), order="F") # # elif self.combobox_ABS_system_choice.currentIndex() == 2: # @@ -980,37 +1482,90 @@ class AcousticDataTab(QWidget): if self.combobox_ABS_system_choice.currentIndex() == 1: self.label_profiles.setText( - _translate("CONSTANT_STRING", cs.NB_PROFILES) + ": " + str(stg.nb_profiles)) + _translate("CONSTANT_STRING", cs.NB_PROFILES) + ": " + str(stg.nb_profiles[self.fileListWidget.currentRow()])) self.label_profiles_per_sec.setText( _translate("CONSTANT_STRING", cs.NB_PROFILES_PER_SEC) + ": " + - str(stg.nb_profiles_per_sec) + " Hz") + str(stg.nb_profiles_per_sec[self.fileListWidget.currentRow()]) + " Hz") + # print("OL ", self.fileListWidget.currentRow()) self.label_freq.setText( - _translate("CONSTANT_STRING", cs.FREQUENCY) + ": " + ', '.join(stg.freq_text)) + _translate("CONSTANT_STRING", cs.FREQUENCY) + ": " + ', '.join(stg.freq_text[self.fileListWidget.currentIndex().row()])) self.label_cells.setText( - _translate("CONSTANT_STRING", cs.NB_CELLS) + ": " + str(stg.nb_cells)) + _translate("CONSTANT_STRING", cs.NB_CELLS) + ": " + str(stg.nb_cells[self.fileListWidget.currentRow()])) self.label_cell_size.setText( - _translate("CONSTANT_STRING", cs.CELL_SIZE) + ": " + str(100*round(stg.cell_size, 3)) + " cm") + _translate("CONSTANT_STRING", cs.CELL_SIZE) + ": " + str(100*round(stg.cell_size[self.fileListWidget.currentRow()], 3)) + " cm") self.label_pulse_length.setText( - _translate("CONSTANT_STRING", cs.PULSE_LENGHT) + ": " + str(round(stg.pulse_length,6)) + "sec") + _translate("CONSTANT_STRING", cs.PULSE_LENGHT) + ": " + str(round(stg.pulse_length[self.fileListWidget.currentRow()], 6)) + "sec") self.label_pings_per_sec.setText( - _translate("CONSTANT_STRING", cs.NB_PINGS_PER_SEC) + ": " + str(stg.nb_pings_per_sec) + " Hz") + _translate("CONSTANT_STRING", cs.NB_PINGS_PER_SEC) + ": " + str(stg.nb_pings_per_sec[self.fileListWidget.currentRow()]) + " Hz") self.label_pings_per_profile.setText( _translate("CONSTANT_STRING", cs.NB_PINGS_PER_PROFILE) + ": " + - str(stg.nb_pings_averaged_per_profile)) + str(stg.nb_pings_averaged_per_profile[self.fileListWidget.currentRow()])) self.label_kt.setText( - _translate("CONSTANT_STRING", cs.KT) + ": " + ', '.join(map(str, stg.kt))) + _translate("CONSTANT_STRING", cs.KT) + ": " + ', '.join(map(str, stg.kt[self.fileListWidget.currentRow()]))) self.label_rx.setText( - _translate("CONSTANT_STRING", cs.GAIN_RX) + ": " + ', '.join(map(str, stg.gain_rx))) + _translate("CONSTANT_STRING", cs.GAIN_RX) + ": " + ', '.join(map(str, stg.gain_rx[self.fileListWidget.currentRow()]))) self.label_tx.setText( - _translate("CONSTANT_STRING", cs.GAIN_TX) + ": " + ', '.join(map(str, stg.gain_tx))) + _translate("CONSTANT_STRING", cs.GAIN_TX) + ": " + ', '.join(map(str, stg.gain_tx[self.fileListWidget.currentRow()]))) elif self.combobox_ABS_system_choice.currentIndex() == 2: self.label_freq.setText( _translate("CONSTANT_STRING", cs.FREQUENCY) + ": " + ', '.join(stg.freq_text)) - def fill_table(self): + + if self.fileListWidget.count() == 1: + + header_list = [] + for freq_ind, freq_value in enumerate(stg.freq_text[0]): + header_list.append("Time - " + freq_value) + header_list.append("BS - " + freq_value) + + if freq_ind == 0: + table_data = np.vstack((stg.time_reshape[0][:, freq_ind], stg.BS_raw_data_reshape[0][:, freq_ind])) + else: + table_data = np.vstack((table_data, + np.vstack((stg.time_reshape[0][:, freq_ind], + stg.BS_raw_data_reshape[0][:, freq_ind])) + )) + + print(header_list) + print(table_data.shape) + + stg.DataFrame_acoustic = pd.DataFrame(data=table_data.transpose(), columns=header_list) + + else: + + header_list = [] + header_list.clear() + for freq_ind, freq_value in enumerate(stg.freq_text[0]): + header_list.append("Time - " + freq_value) + header_list.append("BS - " + freq_value) + + if freq_ind == 0: + table_data = np.vstack((stg.time_reshape[self.fileListWidget.currentRow()][:, freq_ind], + stg.BS_raw_data_reshape[self.fileListWidget.currentRow()][:, freq_ind])) + else: + table_data = np.vstack((table_data, + np.vstack((stg.time_reshape[self.fileListWidget.currentRow()][:, freq_ind], + stg.BS_raw_data_reshape[self.fileListWidget.currentRow()][:, freq_ind])) + )) + + stg.DataFrame_acoustic = pd.DataFrame(data=table_data.transpose(), columns=header_list) + + print(header_list) + print(table_data.shape) + # stg.DataFrame_acoustic = ( + # pd.DataFrame(np.concatenate((stg.time_reshape[self.fileListWidget.currentRow()], + # stg.BS_raw_data_reshape[self.fileListWidget.currentRow()]), axis=1), + # columns=list(map(str, ["Time - " + f for f in stg.freq_text[self.fileListWidget.currentRow()]] + + # ["BS - " + f for f in stg.freq_text[self.fileListWidget.currentRow()]]))) + # ) + + self.tableModel = TableModel(stg.DataFrame_acoustic) + self.tableView.setModel(self.tableModel) + # self.tableView.setItemDelegate(FloatDelegate(3)) + # if self.combobox_ABS_system_choice.currentIndex() == 2: # if ((self.lineEdit_acoustic_file.text()) and (self.lineEdit_noise_file.text())): # stg.DataFrame_acoustic = pd.DataFrame( @@ -1043,19 +1598,19 @@ class AcousticDataTab(QWidget): # ["SNR - " + f for f in stg.freq_text]))) # self.tableModel = TableModel(stg.DataFrame_acoustic) # self.tableView.setModel(self.tableModel) - if self.lineEdit_acoustic_file.text(): - stg.DataFrame_acoustic = pd.DataFrame( - np.concatenate((stg.time_reshape, stg.BS_raw_data_reshape), axis=1), - columns=list(map(str, ["Time BS - " + f for f in stg.freq_text] + ["BS - " + f for f in stg.freq_text]))) - self.tableModel = TableModel(stg.DataFrame_acoustic) - 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() + # if self.lineEdit_acoustic_file.text(): + # stg.DataFrame_acoustic = pd.DataFrame( + # np.concatenate((stg.time_reshape, stg.BS_raw_data_reshape), axis=1), + # columns=list(map(str, ["Time BS - " + f for f in stg.freq_text] + ["BS - " + f for f in stg.freq_text]))) + # self.tableModel = TableModel(stg.DataFrame_acoustic) + # 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: @@ -1078,7 +1633,301 @@ class AcousticDataTab(QWidget): # self.groupbox_xaxis_time.setDisabled(False) # self.groupbox_xaxis_space.setDisabled(True) - def plot_transect_with_BS_raw_data(self): + def compute_time(self): + if ((self.fileListWidget.count() == 1) and (len(stg.tmax) == 0)): + + print("Config 1 : time") + + # --- tmim / tmax --- + tmin_indice = np.where(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmin( + stg.time[self.fileListWidget.currentRow()][0, :])) == + np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmin( + stg.time[self.fileListWidget.currentRow()][0, :]))))[0][0] + tmin_value = np.round(np.nanmin(stg.time[self.fileListWidget.currentRow()][0, :]), 2) + stg.tmin = [(tmin_indice, tmin_value)] + + tmax_indice = np.where(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmax( + stg.time[self.fileListWidget.currentRow()][0, :])) == + np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmax( + stg.time[self.fileListWidget.currentRow()][0, :]))))[0][0] + tmax_value = np.round(np.nanmax(stg.time[self.fileListWidget.currentRow()][0, :]), 2) + stg.tmax = [(tmax_indice+1, tmax_value)] + + print(f" tmin = {stg.tmin} , tmax = {stg.tmax}") + + # --- t_cross_section --- + stg.t_cross_section = [stg.time[self.fileListWidget.currentRow()][:, + stg.tmin[self.fileListWidget.currentRow()][0]:stg.tmax[self.fileListWidget.currentRow()][0]]] + print(f"t = {stg.t_cross_section}") + + # --- spinbox tmin / tmax --- + # self.spinbox_tmin.setValue(stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmin[self.fileListWidget.currentRow()][0]]) + # self.spinbox_tmax.setValue(stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmax[self.fileListWidget.currentRow()][0]-1]) + + # self.doubleRangeSlider_recording_time.update() + # self.doubleRangeSlider_recording_time.setValue((0, 500)) + # (stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmin[self.fileListWidget.currentRow()][0]], + # stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmax[self.fileListWidget.currentRow()][0]-1])) + + + print("self.doubleRangeSlider_recording_time ", self.doubleRangeSlider_recording_time.value()) + + elif len(stg.tmax) < self.fileListWidget.count(): + + print("Config 2 : time") + + # --- tmim / tmax --- + tmin_indice = np.where(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmin( + stg.time[self.fileListWidget.currentRow()][0, :])) == + np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmin( + stg.time[self.fileListWidget.currentRow()][0, :]))))[0][0] + tmin_value = np.round(np.nanmin(stg.time[self.fileListWidget.currentRow()][0, :]), 2) + print(f" tmin_indice = {tmin_indice} , tmin_value = {tmin_value}") + + tmax_indice = np.where(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmax( + stg.time[self.fileListWidget.currentRow()][0, :])) == + np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmax( + stg.time[self.fileListWidget.currentRow()][0, :]))))[0][0] + tmax_value = np.round(np.nanmax(stg.time[self.fileListWidget.currentRow()][0, :]), 2) + print(f" tmax_indice = {tmax_indice} , tmax_value = {tmax_value}") + + print(f" tmin = {stg.tmin} , tmax = {stg.tmax}") + stg.tmin.append((tmin_indice, tmin_value)) + stg.tmax.append((tmax_indice+1, tmax_value)) + print(f" tmin = {stg.tmin} , tmax = {stg.tmax}") + + # --- t_cross_section --- + stg.t_cross_section = stg.t_cross_section + [stg.time[self.fileListWidget.currentRow()][:, + stg.tmin[self.fileListWidget.currentRow()][0]: + stg.tmax[self.fileListWidget.currentRow()][0]]] + + # --- spinbox tmin / tmax --- + # self.spinbox_tmin.setValue(stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmin[self.fileListWidget.currentRow()][0]]) + # self.spinbox_tmax.setValue(stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmax[self.fileListWidget.currentRow()][0]-1]) + + # self.doubleRangeSlider_recording_time.setValue(value=( + # stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmin[self.fileListWidget.currentRow()][0]], + # stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmax[self.fileListWidget.currentRow()][0]-1])) + + print("self.doubleRangeSlider_recording_time ", self.doubleRangeSlider_recording_time.value()) + + else: + print("-----------------") + print("Config 3 : time") + print("-----------------") + + self.set_range_for_doubleRangeSlider_time() + + # --- spinbox tmin / tmax --- + # self.spinbox_tmin.setValue( + # stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmin[self.fileListWidget.currentRow()][0]]) + # self.spinbox_tmax.setValue(stg.t_cross_section[self.fileListWidget.currentRow()][ + # 0, stg.tmax[self.fileListWidget.currentRow()][0]-1]) + + # print("tmin = ", stg.tmin) + # print("tmax = ", stg.tmax) + # print("list Widget : ", self.fileListWidget.currentRow()) + # print("stg.tmin[self.fileListWidget.currentRow()][0] ", stg.tmin[self.fileListWidget.currentRow()][0]) + # print("stg.tmax[self.fileListWidget.currentRow()][0] - 1 ", stg.tmax[self.fileListWidget.currentRow()][0]-1) + # + # print("t_cross_section min ", stg.t_cross_section[self.fileListWidget.currentRow()][ + # 0, stg.tmin[self.fileListWidget.currentRow()][0]]) + # print("t_cross_section max ", stg.t_cross_section[self.fileListWidget.currentRow()][ + # 0, stg.tmax[self.fileListWidget.currentRow()][0]]) + # # self.doubleRangeSlider_recording_time.setValue(value=(stg.tmin[self.fileListWidget.currentRow()][1], stg.tmax[self.fileListWidget.currentRow()][1])) + # + # self.doubleRangeSlider_recording_time.setValue(value=( + # stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmin[self.fileListWidget.currentRow()][0]], + # stg.t_cross_section[self.fileListWidget.currentRow()][0, stg.tmax[self.fileListWidget.currentRow()][0]-1] + # )) + # + # print("self.doubleRangeSlider_recording_time ", self.doubleRangeSlider_recording_time.value()) + + def set_range_for_doubleRangeSlider_time(self): + + self.doubleRangeSlider_recording_time.setRange(min=stg.time[self.fileListWidget.currentRow()][0, 0], + max=stg.time[self.fileListWidget.currentRow()][0, -1]) + + self.doubleRangeSlider_recording_time.setValue(value=(stg.t_cross_section[self.fileListWidget.currentRow()][0, 0], + stg.t_cross_section[self.fileListWidget.currentRow()][0, -1])) + + def set_tmin_tmax_for_doubleRangeSider_time(self): + + stg.tmin[self.fileListWidget.currentRow()] = (( + np.where(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], 2) - + self.doubleRangeSlider_recording_time.value()[0]) == + np.nanmin(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], + 2) - self.doubleRangeSlider_recording_time.value()[0])))[0][0], + self.doubleRangeSlider_recording_time.value()[0] + )) + print("tmax = ", stg.tmax) + + stg.tmax[self.fileListWidget.currentRow()] = (( + np.where(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], 2) - self.doubleRangeSlider_recording_time.value()[1]) == + np.nanmin(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], + 2) - self.doubleRangeSlider_recording_time.value()[1])))[0][0]+1, + self.doubleRangeSlider_recording_time.value()[1] + )) + print("tmax = ", stg.tmax) + + stg.t_cross_section[self.fileListWidget.currentRow()] = ( + stg.time[self.fileListWidget.currentRow()][:, stg.tmin[self.fileListWidget.currentRow()][0]:stg.tmax[self.fileListWidget.currentRow()][0]] + ) + + # def time_spin_box_value(self): + # + # if Qt.Key_Return: + # + # stg.tmax[self.fileListWidget.currentRow()] = (( + # np.where(np.abs(np.round(stg.t_cross_section[self.fileListWidget.currentRow()][0, :], 2) - self.spinbox_tmax.value()) == + # np.nanmin(np.abs(np.round(stg.t_cross_section[self.fileListWidget.currentRow()][0, :], + # 2) - self.spinbox_tmax.value())))[0][0], + # self.spinbox_tmax.value() + # )) + # print("tmax = ", stg.tmax) + # + # stg.t_cross_section[self.fileListWidget.currentRow()] = ( + # stg.time[self.fileListWidget.currentRow()][:, stg.tmin[self.fileListWidget.currentRow()][0]:stg.tmax[self.fileListWidget.currentRow()][0]] + # ) + + def compute_depth(self): + if ((self.fileListWidget.count() == 1) and (len(stg.rmax) == 0)): + + # --- rmim / rmax --- + rmin_indice = np.where(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmin( + stg.depth[self.fileListWidget.currentRow()][0, :])) == + np.nanmin(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmin( + stg.depth[self.fileListWidget.currentRow()][0, :]))))[0][0] + rmin_value = np.round(np.nanmin(stg.depth[self.fileListWidget.currentRow()][0, :]), 2) + stg.rmin = [(rmin_indice, rmin_value)] + + rmax_indice = np.where(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmax( + stg.depth[self.fileListWidget.currentRow()][0, :])) == + np.nanmin(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmax( + stg.depth[self.fileListWidget.currentRow()][0, :]))))[0][0] + rmax_value = np.round(np.nanmax(stg.depth[self.fileListWidget.currentRow()][0, :]), 2) + stg.rmax = [(rmax_indice+1, rmax_value)] + + # --- depth_cross_section --- + stg.depth_cross_section = [stg.depth[self.fileListWidget.currentRow()][:, + stg.rmin[self.fileListWidget.currentRow()][0]: + stg.rmax[self.fileListWidget.currentRow()][0]]] + print("Config 1 : depth") + print("rmin ", stg.rmin) + print("rmax ", stg.rmax) + + elif len(stg.rmax) < self.fileListWidget.count(): + + # --- rmim / rmax --- + rmin_indice = np.where(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmin( + stg.depth[self.fileListWidget.currentRow()][0, :])) == + np.nanmin(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmin( + stg.depth[self.fileListWidget.currentRow()][0, :]))))[0][0] + rmin_value = np.round(np.nanmin(stg.depth[self.fileListWidget.currentRow()][0, :]), 2) + + rmax_indice = np.where(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmax( + stg.depth[self.fileListWidget.currentRow()][0, :])) == + np.nanmin(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmax( + stg.depth[self.fileListWidget.currentRow()][0, :]))))[0][0] + rmax_value = np.round(np.nanmax(stg.depth[self.fileListWidget.currentRow()][0, :]), 2) + + stg.rmin.append((rmin_indice, rmin_value)) + stg.rmax.append((rmax_indice+1, rmax_value)) + + # --- depth_cross_section --- + stg.depth_cross_section = stg.depth_cross_section + [stg.depth[self.fileListWidget.currentRow()][:, + stg.rmin[self.fileListWidget.currentRow()][0]: + stg.rmax[self.fileListWidget.currentRow()][0]]] + print("Config 2 : depth") + print("rmin ", stg.rmin) + print("rmax ", stg.rmax) + + else: + + self.set_range_for_doubleRangeSlider_depth() + print("Config 3 : depth") + print("rmin ", stg.rmin) + print("rmax ", stg.rmax) + + def set_range_for_doubleRangeSlider_depth(self): + self.doubleRangeSlider_depth.setRange(min=-stg.depth[self.fileListWidget.currentRow()][0, -1], + max=-stg.depth[self.fileListWidget.currentRow()][0, 0]) + + self.doubleRangeSlider_depth.setValue(value=(-stg.depth_cross_section[self.fileListWidget.currentRow()][0, -1], + -stg.depth_cross_section[self.fileListWidget.currentRow()][0, 0])) + + print("self.doubleRangeSlider_depth.value() ", self.doubleRangeSlider_depth.value()) + + def set_rmin_rmax_for_doubleRangeSider_depth(self): + stg.rmin[self.fileListWidget.currentRow()] = (( + np.where(np.abs(np.round(stg.depth[self.fileListWidget.currentRow()][0, :], 2) - + -self.doubleRangeSlider_depth.value()[1]) == + np.nanmin(np.abs(np.round(stg.depth[self.fileListWidget.currentRow()][0, :], + 2) - (-self.doubleRangeSlider_depth.value()[1]))))[0][0], + -self.doubleRangeSlider_depth.value()[1] + )) + + print("rmax before ", stg.rmax) + stg.rmax[self.fileListWidget.currentRow()] = (( + np.where(np.abs(np.round(stg.depth[self.fileListWidget.currentRow()][0, :], 2) - + -self.doubleRangeSlider_depth.value()[0]) == + np.nanmin(np.abs(np.round(stg.depth[self.fileListWidget.currentRow()][0, :], + 2) - (-self.doubleRangeSlider_depth.value()[0]))))[0][0]+1, + -self.doubleRangeSlider_depth.value()[0] + )) + print("rmax afer ", stg.rmax) + + stg.depth_cross_section[self.fileListWidget.currentRow()] = ( + stg.depth[self.fileListWidget.currentRow()][:, + stg.rmin[self.fileListWidget.currentRow()][0]:stg.rmax[self.fileListWidget.currentRow()][0]] + ) + print("Config 4 : depth") + print("rmin ", stg.rmin) + print("rmax ", stg.rmax) + + def compute_BS_cross_section(self): + if (self.fileListWidget.count() == 1) and (len(stg.BS_cross_section) == 0): + + print("Config 1 : BS_cross_section") + + stg.BS_cross_section = [stg.BS_raw_data[self.fileListWidget.currentRow()][:, + stg.rmin[self.fileListWidget.currentRow()][0]:stg.rmax[self.fileListWidget.currentRow()][0], + stg.tmin[self.fileListWidget.currentRow()][0]:stg.tmax[self.fileListWidget.currentRow()][0]]] + + elif len(stg.BS_cross_section) < self.fileListWidget.count(): + + print("Config 2 : BS_cross_section") + print("tmin for cross section ", stg.tmin) + stg.BS_cross_section = stg.BS_cross_section + [stg.BS_raw_data[self.fileListWidget.currentRow()][:, + stg.rmin[self.fileListWidget.currentRow()][0]:stg.rmax[self.fileListWidget.currentRow()][0], + stg.tmin[self.fileListWidget.currentRow()][0]:stg.tmax[self.fileListWidget.currentRow()][0]]] + + else: + + print("Config 3 : BS_cross_section") + + stg.BS_cross_section[self.fileListWidget.currentRow()] = ( + stg.BS_raw_data[self.fileListWidget.currentRow()] + [:, stg.rmin[self.fileListWidget.currentRow()][0]:stg.rmax[self.fileListWidget.currentRow()][0], + stg.tmin[self.fileListWidget.currentRow()][0]:stg.tmax[self.fileListWidget.currentRow()][0]]) + + print(f"BS_cross_section : {len(stg.BS_cross_section)}") + print(f"BS_cross_section shape : {stg.BS_cross_section[self.fileListWidget.currentRow()].shape}") + + def update_frequency_combobox(self): + self.combobox_frequency_bathymetry.clear() + self.combobox_frequency_bathymetry.addItems([f for f in stg.freq_text[self.fileListWidget.currentRow()]]) + self.combobox_frequency_profile.clear() + self.combobox_frequency_profile.addItems([f for f in stg.freq_text[self.fileListWidget.currentRow()]]) + + def set_range_for_doubleRangeSlider_intg_area(self): + self.doubleRangeSlider_intg_area.setRange(min=-stg.depth_cross_section[self.fileListWidget.currentRow()][0, -1], + max=-stg.depth_cross_section[self.fileListWidget.currentRow()][0, 0]) + + self.doubleRangeSlider_intg_area.setValue(value=(-stg.depth_cross_section[self.fileListWidget.currentRow()][0, -1], + -stg.depth_cross_section[self.fileListWidget.currentRow()][0, 0])) + + def plot_backscattered_acoustic_signal_recording(self): # --- Condition if table is not filled --- # if not self.lineEdit_acoustic_file.text(): # if not stg.filename_BS_raw_data: @@ -1111,81 +1960,67 @@ class AcousticDataTab(QWidget): # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS) - self.fig_BS, self.axis_BS = plt.subplots(nrows=stg.freq.shape[0], ncols=1, sharex=True, sharey=False, layout="constrained") + # plt.close(self.fig_BS) + self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) + + self.fig_BS, self.axis_BS = plt.subplots(nrows=stg.freq[self.fileListWidget.currentRow()].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.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) - self.scroll_BS = QScrollArea() + # self.scroll_BS = QScrollArea() self.scroll_BS.setWidget(self.canvas_BS) - self.scroll_BS.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) - self.scroll_BS.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) - # self.scroll_BS.setWidgetResizable(True) - self.scroll_BS.setAlignment(Qt.AlignCenter) + # self.scroll_BS.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) + # self.scroll_BS.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) + # # self.scroll_BS.setWidgetResizable(True) + # self.scroll_BS.setAlignment(Qt.AlignCenter) self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS) - self.spinbox_tmin.setValue(np.round(np.min(stg.time[0, :]), 2)) - self.spinbox_tmax.setValue(np.round(np.max(stg.time[0, :]), 2)) + for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): - stg.tmin = np.array([]) - stg.tmax = np.array([]) - - for f, _ in enumerate(stg.freq): - - val_min = np.nanmin(stg.BS_raw_data[f, :, :]) - val_max = np.nanmax(stg.BS_raw_data[f, :, :]) + val_min = np.nanmin(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) + val_max = np.nanmax(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) if val_min == 0: val_min = 1e-5 - stg.tmin = ( - np.append(stg.tmin, - np.where(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmin.value()) == - np.nanmin(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmin.value())))[0][0]) - ) - - stg.tmax = ( - np.append(stg.tmax, - np.where(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmax.value()) == - np.nanmin(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmax.value())))[0][0]) - ) - # print(f"freq = {f}") - print(f"tmin {stg.tmin}") - print(f"tmax {stg.tmax}") if self.combobox_ABS_system_choice.currentIndex() == 1: - pcm = self.axis_BS[f].pcolormesh(stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])], - -stg.r[f, :], - stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])], + pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :], + -stg.depth[self.fileListWidget.currentRow()][f, :], + stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :], + # stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])], cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) elif self.combobox_ABS_system_choice.currentIndex() == 2: - pcm = self.axis_BS[f].pcolormesh(stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])], - -stg.r[f, :], - np.log(stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]), + pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :], + -stg.depth[self.fileListWidget.currentRow()][f, :], + np.log(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]), + # np.log(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])]), cmap='Blues') - # --- Plot red solid line on transect to visualize position of plotted profile --- - self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot( - stg.time[self.combobox_frequency_profile.currentIndex(), 0] * np.ones( - stg.r.shape[1]), - -stg.r[self.combobox_frequency_profile.currentIndex(), :], - color='red', linestyle="solid", linewidth=2) - - self.axis_BS[f].text(1, .70, stg.freq_text[f], + self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_BS[f].transAxes) + # --- Plot red solid line on transect to visualize position of plotted profile --- + # print("on the 2D field ", self.combobox_freq_choice.currentIndex()) + self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot( + stg.time[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), + self.slider.value() - 1] * np.ones(stg.depth[self.fileListWidget.currentRow()].shape[1]), + -stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :], + color='red', linestyle="solid", linewidth=2) + self.fig_BS.supxlabel('Time (sec)', 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='Acoustic backscatter signal (V)', rotation=270, labelpad=10) self.fig_BS.canvas.draw_idle() - self.plot_profile() + # self.plot_profile() - def update_xaxis_transect_with_BS_raw_data(self): + def update_plot_backscattered_acoustic_signal_recording(self): # --- Condition if table is filled but transect is not plotted # --- => Error message if spin box values of tmin or tmax is change @@ -1211,20 +2046,20 @@ class AcousticDataTab(QWidget): # # if self.combobox_ABS_system_choice.currentIndex() == 1: # pcm = self.axis_BS[f].pcolormesh(stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])], - # -stg.r[f, :], + # -stg.depth[f, :], # stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])], # cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) # # elif self.combobox_ABS_system_choice.currentIndex() == 2: # pcm = self.axis_BS[f].pcolormesh(stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])], - # -stg.r[f, :], + # -stg.depth[f, :], # np.log(stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]), # cmap='Blues') # # # --- Plot red solid line on transect to visualize position of plotted profile --- # self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot( - # stg.time[self.combobox_frequency_profile.currentIndex(), self.slider.value()] * np.ones(stg.r.shape[1]), - # -stg.r[self.combobox_frequency_profile.currentIndex(), :], + # stg.time[self.combobox_frequency_profile.currentIndex(), self.slider.value()] * np.ones(stg.depth.shape[1]), + # -stg.depth[self.combobox_frequency_profile.currentIndex(), :], # color='red', linestyle="solid", linewidth=2) # # self.axis_BS[f].text(1, .70, stg.freq_text[f], @@ -1236,31 +2071,92 @@ class AcousticDataTab(QWidget): # self.fig_BS.supylabel('Depth (m)', fontsize=10) # self.fig_BS.canvas.draw_idle() - else: + elif len(stg.BS_cross_section) != 0: - self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) - self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS) + # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) + # self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS) # --- Backscatter acoustic signal is recorded for next tab --- - stg.BS_cross_section = np.array([[[]]]) - stg.t = np.array([[]]) - for f, _ in enumerate(stg.freq): + # stg.BS_cross_section = np.array([[[]]]) + # stg.t = np.array([[]]) - stg.tmin[f] = np.where(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmin.value()) == - np.nanmin(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmin.value())))[0][0] + # stg.tmin[self.fileListWidget.currentRow()] = ( + # np.where(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], + # 2) - self.spinbox_tmin.value()) == + # np.nanmin(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], + # 2) - self.spinbox_tmin.value())))[0][ + # 0] + # ) + # + # stg.tmax[self.fileListWidget.currentRow()] = ( + # np.where(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], + # 2) - self.spinbox_tmax.value()) == + # np.nanmin(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], + # 2) - self.spinbox_tmax.value())))[0][ + # 0] + # ) + # + # print(f"Update tmin {stg.tmin}") + # print(f"Update tmax {stg.tmax}") + # + # if (self.fileListWidget.count() == 1) and (len(stg.BS_cross_section) == 0): + # stg.BS_cross_section = [stg.BS_raw_data[self.fileListWidget.currentRow()][:, :, + # int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])]] + # elif (self.fileListWidget.count() > 1) and (len(stg.BS_cross_section) < self.fileListWidget.count()): + # stg.BS_cross_section = ( + # np.append(stg.BS_cross_section, + # stg.BS_raw_data[self.fileListWidget.currentRow()][:, :, + # int(stg.tmin[self.fileListWidget.currentRow()]):int( + # stg.tmax[self.fileListWidget.currentRow()])]) + # ) + # else: + # stg.BS_cross_section[self.fileListWidget.currentRow()] = ( + # stg.BS_raw_data[self.fileListWidget.currentRow()] + # [:, :, int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])]) + # + # + # if (self.fileListWidget.count() == 1) and (len(stg.t) == 0): + # stg.t = [stg.time[self.fileListWidget.currentRow()][:, + # int(stg.tmin[self.fileListWidget.currentRow()]):int( + # stg.tmax[self.fileListWidget.currentRow()])]] + # elif self.fileListWidget.count() > 1: + # stg.t = np.append(stg.t, + # stg.time[self.fileListWidget.currentRow()][:, + # int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])]) + # else: + # stg.t[self.fileListWidget.currentRow()] = stg.time[self.fileListWidget.currentRow()][:, + # int(stg.tmin[self.fileListWidget.currentRow()]):int( + # stg.tmax[self.fileListWidget.currentRow()])] + # # stg.t = np.append(stg.t, np.array([stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) + # + # # print("stg.t[self.fileListWidget.currentRow()].shape() ", stg.t[self.fileListWidget.currentRow()].shape()) - stg.tmax[f] = np.where(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmax.value()) == - np.nanmin(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmax.value())))[0][0] + for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): + + # print(f"f = {f}") + + # stg.tmin[f] = np.where(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][f, :], 2) - self.spinbox_tmin.value()) == + # np.nanmin(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmin.value())))[0][0] + # + # stg.tmax[f] = np.where(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmax.value()) == + # np.nanmin(np.abs(np.round(stg.time[f, :], 2) - self.spinbox_tmax.value())))[0][0] # print("stg.tmin[f] ", stg.tmin[f]) # print("stg.tmax[f] ", stg.tmax[f]) # print("shape of BS_raw_data ", np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]).shape) # print("BS_data shape ", stg.BS_cross_section.shape) - if stg.BS_cross_section.shape[2] == 0: - stg.BS_cross_section = np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]) - else: - stg.BS_cross_section = np.append(stg.BS_cross_section, np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) + + # print(self.fileListWidget.count()) + # print(stg.BS_cross_section[self.fileListWidget.currentRow()].shape) + # if stg.BS_cross_section[self.fileListWidget.currentRow()].shape[2] == 0: + # if self.fileListWidget.count() == 1: + # stg.BS_cross_section = np.array( + # [stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])]]) + # else: + # stg.BS_cross_section[self.fileListWidget.currentRow()] = ( + # np.append(stg.BS_cross_section[self.fileListWidget.currentRow()], + # np.array([stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])]]), axis=0)) # stg.BS_cross_section = np.stack(np.array([stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) @@ -1269,58 +2165,68 @@ class AcousticDataTab(QWidget): # print("stg.BS_cross_section.size ", stg.BS_cross_section.size) # print("stg.time shape ", stg.time.shape) # print("stg.t shape ", stg.t.shape) - if stg.t.shape[1] == 0: - stg.t = np.array([stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])]]) - else: - stg.t = np.append(stg.t, np.array([stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) + # if stg.t[self.fileListWidget.currentRow()].shape[1] == 0: + # if self.fileListWidget.count() == 1: + # stg.t = np.array([stg.time[self.fileListWidget.currentRow()][f, int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])]]) + # else: + # stg.t[self.fileListWidget.currentRow()] = np.append(stg.t[self.fileListWidget.currentRow()], + # np.array([stg.time[self.fileListWidget.currentRow()][f, int(stg.tmin[self.fileListWidget.currentRow()]):int(stg.tmax[self.fileListWidget.currentRow()])]]), axis=0) # stg.t = np.append(stg.t, np.array([stg.time[f, int(stg.tmin[f]):int(stg.tmax[f])]]), axis=0) - print("stg.t shape ", stg.t.shape) + # print("stg.t shape ", stg.t[self.fileListWidget.currentRow()].shape) # print(f"stg.t : {stg.t}") - # stg.r_2D = stg.r_2D[:, np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]: + # stg.depth_2D = stg.depth_2D[:, np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]: # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]] - # print("stg.r shape ", stg.r_2D.shape) + # print("stg.depth shape ", stg.depth_2D.shape) - print("self.combobox_frequency_profile.currentIndex() ", self.combobox_frequency_profile.currentIndex()) - - print("slider value = ", [ - self.slider.value() - 1 if self.slider.value() - 1 <= stg.t.shape[1] - 1 else np.max( - stg.t.shape[1] - 1)][0]) - - print(stg.t[0, - [self.slider.value() - 1 if self.slider.value() - 1 <= stg.t.shape[1] - 1 else np.max( - stg.t.shape[1] - 1)][0]]) + # print("self.combobox_frequency_profile.currentIndex() ", self.combobox_frequency_profile.currentIndex()) + # + # print("slider value = ", [ + # self.slider.value() - 1 if self.slider.value() - 1 <= stg.t.shape[1] - 1 else np.max( + # stg.t[self.fileListWidget.currentRow()].shape[1] - 1)][0]) + # + # print(stg.t[0, + # [self.slider.value() - 1 if self.slider.value() - 1 <= stg.t.shape[1] - 1 else np.max( + # stg.t.shape[1] - 1)][0]]) self.axis_BS[f].cla() - val_min = np.min(stg.BS_cross_section[f, :, :]) - val_max = np.max(stg.BS_cross_section[f, :, :]) + val_min = np.nanmin(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :]) + val_max = np.nanmax(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :]) if val_min == 0: val_min = 1e-5 # print("stg.t[f, :].shape ", stg.t[f]) - # print("stg.r[f, :].shape ", stg.r[f, :]) + # print("stg.depth[f, :].shape ", stg.depth[f, :]) if self.combobox_ABS_system_choice.currentIndex() == 1: - pcm = self.axis_BS[f].pcolormesh(stg.t[f, :], -stg.r[f, :], stg.BS_cross_section[f, :, :], + pcm = self.axis_BS[f].pcolormesh(stg.t_cross_section[self.fileListWidget.currentRow()][f, :], + -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :], + stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :], cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) elif self.combobox_ABS_system_choice.currentIndex() == 2: - pcm = self.axis_BS[f].pcolormesh(stg.t[f, :], -stg.r[f, :], np.log(stg.BS_cross_section[f, :, :]), + pcm = self.axis_BS[f].pcolormesh(stg.t_cross_section[self.fileListWidget.currentRow()][f, :], + -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :], + np.log(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :]), cmap='Blues') # --- Plot river bottom line --- - if stg.r_bottom.size != 0: - self.axis_BS[f].plot(stg.t[self.combobox_freq_choice.currentIndex(), :], -stg.r_bottom, + if (len(stg.depth_bottom) != 0) and (len(stg.depth_bottom) == self.fileListWidget.count()): + self.axis_BS[f].plot(stg.t_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :], + -stg.depth_bottom[self.fileListWidget.currentRow()], color='black', linewidth=1, linestyle="solid") # --- Plot red solid line on transect to visualize position of plotted profile --- + slider_value = [self.slider.value() - 1 if self.slider.value() -1 <= stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]-1 + else np.max(stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]-1)][0] + self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot( - stg.t[0, # self.combobox_frequency_profile.currentIndex(), - [self.slider.value() - 1 if self.slider.value() -1 <= stg.t.shape[1]-1 else np.max(stg.t.shape[1]-1)][0]] * np.ones(stg.r.shape[1]), - -stg.r[self.combobox_frequency_profile.currentIndex(), :], + stg.t_cross_section[self.fileListWidget.currentRow()][0, # self.combobox_frequency_profile.currentIndex(), + slider_value] * np.ones(stg.depth_cross_section[self.fileListWidget.currentRow()].shape[1]), + -stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :], color='red', linestyle="solid", linewidth=2) - self.axis_BS[f].text(1, .70, stg.freq_text[f], + self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_BS[f].transAxes) @@ -1331,109 +2237,107 @@ class AcousticDataTab(QWidget): def plot_profile(self): + self.combobox_frequency_profile.setCurrentIndex(0) + + self.combobox_frequency_profile.currentIndexChanged.connect(self.update_plot_profile) + self.combobox_frequency_profile.currentIndexChanged.connect( + self.update_plot_backscattered_acoustic_signal_recording) + + # self.slider.setMaximum(stg.BS_raw_data[self.fileListWidget.currentRow()].shape[2]) + self.slider.setMaximum(stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]) + + self.verticalLayout_groupbox_plot_profile.removeWidget(self.canvas_plot_profile) + # --- Figure to plot profiles --- self.fig_profile, self.axis_profile = plt.subplots(nrows=1, ncols=1, layout="constrained") self.canvas_plot_profile = FigureCanvas(self.fig_profile) self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_plot_profile) - # --- Slider for moving the profile --- - self.horizontalLayout_slider = QHBoxLayout() - self.verticalLayout_groupbox_plot_profile.addLayout(self.horizontalLayout_slider) - - self.pushbutton_slider_left = QPushButton() - self.pushbutton_slider_left.setIcon(self.icon_triangle_left) - self.horizontalLayout_slider.addWidget(self.pushbutton_slider_left) - - self.pushbutton_slider_left.clicked.connect(self.slide_profile_number_to_left) - - self.pushbutton_slider_right = QPushButton() - self.pushbutton_slider_right.setIcon(self.icon_triangle_right) - self.horizontalLayout_slider.addWidget(self.pushbutton_slider_right) - - self.pushbutton_slider_right.clicked.connect(self.slide_profile_number_to_right) - - self.lineEdit_slider = QLineEdit() - self.lineEdit_slider.setText("1") - self.lineEdit_slider.setFixedWidth(50) - self.horizontalLayout_slider.addWidget(self.lineEdit_slider) - - self.lineEdit_slider.returnPressed.connect(self.profile_number_on_lineEdit) - - self.slider = QSlider() - self.horizontalLayout_slider.addWidget(self.slider, 9) - - self.slider.setOrientation(Qt.Horizontal) - self.slider.setCursor(Qt.OpenHandCursor) - self.slider.setMinimum(1) - self.slider.setMaximum(stg.BS_raw_data.shape[2]) - self.slider.setTickInterval(1) - self.slider.setValue(1) - - self.slider.valueChanged.connect(self.update_lineEdit_by_moving_slider) - - # self.slider.valueChanged.connect(self.update_plot_profile_position_on_transect) - self.slider.valueChanged.connect(self.update_plot_profile) - self.slider.valueChanged.connect(self.update_xaxis_transect_with_BS_raw_data) - self.combobox_frequency_profile.currentIndexChanged.connect(self.update_xaxis_transect_with_BS_raw_data) - self.combobox_frequency_profile.currentIndexChanged.connect(self.update_plot_profile) - # for f, _ in enumerate(stg.freq[0]): - self.axis_profile.cla() - self.axis_profile.plot(stg.BS_raw_data[ + slider_value = [ + self.slider.value() - 1 if self.slider.value() - 1 <= stg.t_cross_section[self.fileListWidget.currentRow()].shape[ + 1] - 1 else np.max(stg.t_cross_section[self.fileListWidget.currentRow()].shape[1] - 1)][0] + + # --- Profile plot --- + # self.axis_profile.cla() + self.axis_profile.plot(stg.BS_cross_section[self.fileListWidget.currentRow()][ self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1], - -stg.r[self.combobox_frequency_profile.currentIndex(), :], + -stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :], linestyle='solid', color='k', linewidth=1) - self.axis_profile.text(.95, .05, stg.freq_text[self.combobox_frequency_profile.currentIndex()], + self.axis_profile.text(.95, .05, stg.freq_text[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()], fontsize=10, fontweight='bold', fontname="Ubuntu", fontstyle="normal", c="black", alpha=0.2, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_profile.transAxes) + # --- Plot bottom line --- + + if (len(stg.depth_bottom) != 0) and (len(stg.depth_bottom) == self.fileListWidget.count()): + self.axis_profile.plot([0, + np.nanmax(stg.BS_cross_section[self.fileListWidget.currentRow()][ + self.combobox_frequency_profile.currentIndex(), + :, slider_value])], + -stg.depth[self.fileListWidget.currentRow()][ + self.combobox_frequency_profile.currentIndex(), + stg.ind_bottom[self.fileListWidget.currentRow()][slider_value]] * np.ones(2), + linestyle='solid', color='r', linewidth=1) + + position_x = (stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), + stg.ind_bottom[self.fileListWidget.currentRow()][slider_value]] / + np.nanmax( + stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), + :])) + + self.axis_profile.text(.95, 1 - position_x + 0.05, "River bed", + fontsize=10, fontweight='normal', fontname="Times New Roman", + fontstyle="italic", c="red", alpha=0.2, + horizontalalignment='right', verticalalignment='bottom', + transform=self.axis_profile.transAxes) + self.fig_profile.supxlabel("Acoustic Backscatter Signal (V)") self.fig_profile.supylabel("Depth (m)") + self.fig_profile.canvas.draw_idle() - def slide_profile_number_to_right(self): - self.slider.setValue(int(self.slider.value()) + 1) - self.lineEdit_slider.setText(str(self.slider.value())) + # self.plot_transect_with_BS_raw_data() - def slide_profile_number_to_left(self): - self.slider.setValue(int(self.slider.value()) - 1) - self.lineEdit_slider.setText(str(self.slider.value())) - - def profile_number_on_lineEdit(self): - self.slider.setValue(int(self.lineEdit_slider.text())) - - def update_lineEdit_by_moving_slider(self): - self.lineEdit_slider.setText(str(self.slider.value())) + # self.slider.valueChanged.connect(self.update_plot_profile) + # self.slider.valueChanged.connect(self.update_xaxis_transect_with_BS_raw_data) + # self.combobox_frequency_profile.currentIndexChanged.connect(self.update_xaxis_transect_with_BS_raw_data) + # self.combobox_frequency_profile.currentIndexChanged.connect(self.update_plot_profile) def update_plot_profile(self): - - if stg.BS_cross_section.size == 0: + # print("len(stg.BS_cross_section) ", len(stg.BS_cross_section)) + if (len(stg.BS_cross_section) == 0) and (len(stg.BS_raw_data) != 0): self.axis_profile.cla() - self.axis_profile.plot(stg.BS_raw_data[ + self.axis_profile.plot(stg.BS_raw_data[self.fileListWidget.currentRow()][ self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1], - -stg.r[self.combobox_frequency_profile.currentIndex(), :], + -stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :], linestyle='solid', color='k', linewidth=1) - self.axis_profile.text(.95, .05, stg.freq_text[self.combobox_frequency_profile.currentIndex()], + self.axis_profile.text(.95, .05, stg.freq_text[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()], fontsize=10, fontweight='bold', fontname="Ubuntu", fontstyle="normal", c="black", alpha=0.2, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_profile.transAxes) - else: + self.fig_profile.supxlabel("Acoustic Backscatter Signal (V)") + self.fig_profile.supylabel("Depth (m)") + self.fig_profile.canvas.draw_idle() - self.slider.setMaximum(stg.t.shape[1]) + elif len(stg.BS_cross_section) != 0: - slider_value = [self.slider.value() - 1 if self.slider.value() -1 <= stg.t.shape[1]-1 else np.max(stg.t.shape[1]-1)][0] + self.slider.setMaximum(stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]) + + slider_value = [self.slider.value() - 1 if self.slider.value() -1 <= stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]-1 + else np.max(stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]-1)][0] self.axis_profile.cla() # --- Profile plot --- - self.axis_profile.plot(stg.BS_cross_section[self.combobox_frequency_profile.currentIndex(), :, slider_value], - -stg.r[self.combobox_frequency_profile.currentIndex(), :], + self.axis_profile.plot(stg.BS_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :, slider_value], + -stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :], linestyle='solid', color='k', linewidth=1) # --- Plot upper limit line --- @@ -1449,7 +2353,7 @@ class AcousticDataTab(QWidget): # --- Write frequency on graph --- - self.axis_profile.text(.95, .90, stg.freq_text[self.combobox_frequency_profile.currentIndex()], + self.axis_profile.text(.95, .90, stg.freq_text[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()], fontsize=14, fontweight='bold', fontname="Ubuntu", fontstyle="normal", c="black", alpha=0.2, horizontalalignment='right', verticalalignment='bottom', @@ -1457,27 +2361,42 @@ class AcousticDataTab(QWidget): # --- Plot bottom line --- - if stg.r_bottom.size != 0: + # print("len(stg.depth_bottom) ", len(stg.depth_bottom)) + # print("self.fileListWidget.currentRow() ", self.fileListWidget.count()) + if (len(stg.depth_bottom) != 0) and (len(stg.depth_bottom) == self.fileListWidget.count()): self.axis_profile.plot([0, - np.nanmax(stg.BS_cross_section[self.combobox_frequency_profile.currentIndex(), + np.nanmax(stg.BS_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :, slider_value])], - -stg.r[self.combobox_frequency_profile.currentIndex(), stg.ind_bottom[slider_value]]*np.ones(2), + -stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), stg.ind_bottom[self.fileListWidget.currentRow()][slider_value]]*np.ones(2), linestyle='solid', color='r', linewidth=1) - position_x = (stg.r[self.combobox_frequency_profile.currentIndex(), stg.ind_bottom[slider_value]] / - np.nanmax(stg.r[self.combobox_frequency_profile.currentIndex(), :])) + position_x = (stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), stg.ind_bottom[self.fileListWidget.currentRow()][slider_value]] / + np.nanmax(stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :])) self.axis_profile.text(.95, 1-position_x + 0.05, "River bed", - fontsize=10, fontweight='normal', fontname="Times New Roman", + fontsize=10, fontweight='normal', fontname="Ubuntu", fontstyle="italic", c="red", alpha=0.2, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_profile.transAxes) + self.fig_profile.supxlabel("Acoustic Backscatter Signal (V)") + self.fig_profile.supylabel("Depth (m)") + self.fig_profile.canvas.draw_idle() - self.fig_profile.supxlabel("Acoustic Backscatter Signal (V)") - self.fig_profile.supylabel("Depth (m)") - self.fig_profile.canvas.draw_idle() + def slide_profile_number_to_right(self): + self.slider.setValue(int(self.slider.value()) + 1) + self.lineEdit_slider.setText(str(self.slider.value())) + + def slide_profile_number_to_left(self): + self.slider.setValue(int(self.slider.value()) - 1) + self.lineEdit_slider.setText(str(self.slider.value())) + + def profile_number_on_lineEdit(self): + self.slider.setValue(int(self.lineEdit_slider.text())) + + def update_lineEdit_by_moving_slider(self): + self.lineEdit_slider.setText(str(self.slider.value())) # def plot_transect_with_SNR_data(self): # if not self.lineEdit_noise_file.text(): @@ -1524,7 +2443,7 @@ class AcousticDataTab(QWidget): # # x, y = np.meshgrid( # # stg.time[np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]: # # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]], - # # stg.r) + # # stg.depth) # # # # for f in range(stg.freq.shape[0]): # # @@ -1566,12 +2485,12 @@ class AcousticDataTab(QWidget): # for f, freq in enumerate(stg.freq): # # if x.shape[2] == 0: - # x, y = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) + # x, y = np.meshgrid(stg.time_snr[f, :], stg.depth[f, :]) # x = np.array([x]) # y = np.array([y]) # print(f"x : {x.shape}, y : {y.shape}") # else: - # x0, y0 = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) + # x0, y0 = np.meshgrid(stg.time_snr[f, :], stg.depth[f, :]) # x = np.append(x, np.array([x0]), axis=0) # y = np.append(y, np.array([y0]), axis=0) # print(f"x : {x.shape}, y : {y.shape}") @@ -1638,12 +2557,12 @@ class AcousticDataTab(QWidget): # for f, _ in enumerate(stg.freq): # # if x.shape[2] == 0: - # x, y = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) + # x, y = np.meshgrid(stg.time_snr[f, :], stg.depth[f, :]) # x = np.array([x]) # y = np.array([y]) # # print(f"x : {x.shape}, y : {y.shape}") # else: - # x0, y0 = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) + # x0, y0 = np.meshgrid(stg.time_snr[f, :], stg.depth[f, :]) # x = np.append(x, np.array([x0]), axis=0) # y = np.append(y, np.array([y0]), axis=0) # # print(f"x : {x.shape}, y : {y.shape}") @@ -1755,7 +2674,7 @@ class AcousticDataTab(QWidget): # self.fig_SNR.canvas.draw_idle() def detect_bottom(self): - if self.lineEdit_acoustic_file.text() == "": + if self.fileListWidget.count() == 0: msgBox = QMessageBox() msgBox.setWindowTitle("Detect bottom Error") msgBox.setIcon(QMessageBox.Warning) @@ -1786,25 +2705,33 @@ class AcousticDataTab(QWidget): elif self.canvas_BS != None: # else: # --- Record frequency choose for bottom detection --- - stg.freq_bottom_detection = self.combobox_freq_choice.currentIndex() + if ((self.fileListWidget.count() == 1) and (len(stg.freq_bottom_detection) == 0)): + + stg.freq_bottom_detection = [self.combobox_frequency_bathymetry.currentIndex()] + + elif len(stg.rmax) < self.fileListWidget.count(): + + stg.freq_bottom_detection.append(self.combobox_frequency_bathymetry.currentIndex()) # Selecting the range in which we look for the bottom reflection - rmin = np.float32(self.spinbox_depth_min.text().replace(",", ".")) - rmax = np.float32(self.spinbox_depth_max.text().replace(",", ".")) + # rmin = np.float32(self.doubleRangeSlider_intg_area.value()[0].text().replace(",", ".")) + # rmax = np.float32(self.doubleRangeSlider_intg_area.value()[1].text().replace(",", ".")) + rmin = -self.doubleRangeSlider_intg_area.value()[1] + rmax = -self.doubleRangeSlider_intg_area.value()[0] # print(f"rmin = {rmin}") # print(f"rmax = {rmax}") # empty result arrays # r_bottom = np.zeros(stg.nb_profiles) # val_bottom = np.zeros(stg.nb_profiles) - r_bottom = np.zeros(stg.t.shape[1]) - val_bottom = np.zeros(stg.t.shape[1]) + r_bottom = np.zeros(stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]) + val_bottom = np.zeros(stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]) r_bottom_ind = [] # print(f"r_bottom shape with zeros : {r_bottom.shape}") - BS_smooth = deepcopy(stg.BS_raw_data[self.combobox_freq_choice.currentIndex(), :, :]) + BS_smooth = deepcopy(stg.BS_raw_data[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :, :]) # print(f"BS_smooth shape : {BS_smooth.shape}") - for k in range(stg.time.shape[1]): + for k in range(stg.time[self.fileListWidget.currentRow()].shape[1]): BS_smooth[:, k] = savgol_filter(BS_smooth[:, k], 10, 2) # fig1, ax1 = plt.subplots(nrows=1, ncols=1, layout="constrained") @@ -1814,12 +2741,12 @@ class AcousticDataTab(QWidget): # ----------- Detecting the bottom ------------- # for d in range(stg.nb_profiles): - for d in range(stg.t.shape[1]): + for d in range(stg.t_cross_section[self.fileListWidget.currentRow()].shape[1]): # Index of the range where we look for the peak # print(f"self.combobox_freq_choice.currentIndex() : {self.combobox_freq_choice.currentIndex()}") # print(f"r = {stg.r}") - ind_min = np.where(stg.r[int(self.combobox_freq_choice.currentIndex()), :] >= rmin)[0][0] - ind_max = np.where(stg.r[int(self.combobox_freq_choice.currentIndex()), :] <= rmax)[0][-1] + ind_min = np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][int(self.combobox_frequency_bathymetry.currentIndex()), :] >= rmin)[0][0] + ind_max = np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][int(self.combobox_frequency_bathymetry.currentIndex()), :] <= rmax)[0][-1] # print(f"ind_min : {ind_min}") # print(f"ind_max : {ind_max}") @@ -1847,13 +2774,13 @@ class AcousticDataTab(QWidget): ind_bottom = np.where((BS_smooth[ind_min:ind_max, d]) == val_bottom[d])[0][0] np.append(stg.ind_bottom, ind_bottom) - r_bottom[d] = stg.r[self.combobox_freq_choice.currentIndex(), ind_bottom + ind_min] + r_bottom[d] = stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), 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()) # rmax = r_bottom[d] + locale.atof(self.doublespinbox_next_cell.text()) - rmin = r_bottom[d] - np.float32(self.doublespinbox_next_cell.text().replace(",", ".")) - rmax = r_bottom[d] + np.float32(self.doublespinbox_next_cell.text().replace(",", ".")) + rmin = r_bottom[d] - np.float32(self.spinbox_offset_next_cell.text().replace(",", ".")) + rmax = r_bottom[d] + np.float32(self.spinbox_offset_next_cell.text().replace(",", ".")) # --- Plot vertical profile for bottom detection --- # n = 60 @@ -1876,7 +2803,8 @@ class AcousticDataTab(QWidget): # print(f"r_bootom shape : {r_bottom.shape}") - BS_section_bottom = np.zeros((stg.r.shape[1], stg.t.shape[1])) + BS_section_bottom = np.zeros((stg.depth_cross_section[self.fileListWidget.currentRow()].shape[1], + stg.t_cross_section[self.fileListWidget.currentRow()].shape[1])) for i in range(BS_section_bottom.shape[0]): try: @@ -1899,30 +2827,61 @@ class AcousticDataTab(QWidget): # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]] # stg.val_bottom = val_bottom[np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]: # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]] - stg.r_bottom = r_bottom#[int(stg.tmin[self.combobox_freq_choice.currentIndex()]): - # int(stg.tmax[self.combobox_freq_choice.currentIndex()])] - stg.val_bottom = val_bottom#[int(stg.tmin[self.combobox_freq_choice.currentIndex()]): + + if ((self.fileListWidget.count() == 1) and (len(stg.depth_bottom) == 0)): + stg.depth_bottom = [r_bottom]#[int(stg.tmin[self.combobox_freq_choice.currentIndex()]): # int(stg.tmax[self.combobox_freq_choice.currentIndex()])] - stg.ind_bottom = r_bottom_ind + stg.val_bottom = [val_bottom]#[int(stg.tmin[self.combobox_freq_choice.currentIndex()]): + # int(stg.tmax[self.combobox_freq_choice.currentIndex()])] + stg.ind_bottom = [r_bottom_ind] - print("stg.ind_bottom : ", stg.ind_bottom) + elif len(stg.depth_bottom) < self.fileListWidget.count(): + + stg.depth_bottom.append(r_bottom) + + stg.val_bottom.append(val_bottom) + + stg.ind_bottom.append(r_bottom_ind) + + else: + + stg.depth_bottom[self.fileListWidget.currentRow()] = r_bottom + + stg.val_bottom[self.fileListWidget.currentRow()] = val_bottom + + stg.ind_bottom[self.fileListWidget.currentRow()] = r_bottom_ind + + print("stg.depth_bottom : ", stg.depth_bottom) print("stg.val_bottom : ", stg.val_bottom) + print("stg.ind_bottom : ", stg.ind_bottom) - stg.BS_stream_bed = deepcopy(stg.BS_cross_section) - for f, _ in enumerate(stg.freq): - for k, _ in enumerate(stg.r_bottom): + BS_stream_bed_copy = deepcopy(stg.BS_cross_section[self.fileListWidget.currentRow()]) + for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): + for k, _ in enumerate(stg.depth_bottom[self.fileListWidget.currentRow()]): # print(k, np.where(stg.r >= stg.r_bottom[k])[0]) - stg.BS_stream_bed[ - f, np.where(stg.r[self.combobox_freq_choice.currentIndex(), :] >= stg.r_bottom[k])[ + BS_stream_bed_copy[ + f, np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :] + >= stg.depth_bottom[self.fileListWidget.currentRow()][k])[ 0], k] = np.nan + if ((self.fileListWidget.count() == 1) and (len(stg.BS_stream_bed) == 0)): + + stg.BS_stream_bed = [BS_stream_bed_copy] + + elif len(stg.BS_stream_bed) < self.fileListWidget.count(): + + stg.BS_stream_bed.append(BS_stream_bed_copy) + + else: + + stg.BS_stream_bed[self.fileListWidget.currentRow()] = BS_stream_bed_copy # --- Plot transect BS with bathymetry --- - for f, _ in enumerate(stg.freq): + for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): self.axis_BS[f].cla() - val_min = np.min(stg.BS_raw_data[f, :, :]) - val_max = np.max(stg.BS_raw_data[f, :, :]) + val_min = np.min(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) + val_max = np.max(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) if val_min == 0: val_min = 1e-5 @@ -1936,10 +2895,14 @@ class AcousticDataTab(QWidget): # cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) if self.combobox_ABS_system_choice.currentIndex() == 1: - pcm = self.axis_BS[f].pcolormesh(stg.t[f, :], -stg.r[f, :], stg.BS_cross_section[f, :, :], + pcm = self.axis_BS[f].pcolormesh(stg.t_cross_section[self.fileListWidget.currentRow()][f, :], + -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :], + stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :], cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) elif self.combobox_ABS_system_choice.currentIndex() == 2: - pcm = self.axis_BS[f].pcolormesh(stg.t[f, :], -stg.r[f, :], np.log(stg.BS_cross_section[f, :, :]), + pcm = self.axis_BS[f].pcolormesh(stg.t_cross_section[self.fileListWidget.currentRow()][f, :], + -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :], + np.log(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :]), cmap='Blues') # self.axis_BS[f].plot( @@ -1951,10 +2914,11 @@ class AcousticDataTab(QWidget): # print("stg.t[self.combobox_freq_choice.currentIndex(), :] : ", stg.t[self.combobox_freq_choice.currentIndex(), :].shape) # print("-stg.r_bottom : ", stg.r_bottom.shape) - self.axis_BS[f].plot(stg.t[self.combobox_freq_choice.currentIndex(), :], -stg.r_bottom, + self.axis_BS[f].plot(stg.t_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :], + -stg.depth_bottom[self.fileListWidget.currentRow()], color='black', linewidth=1, linestyle="solid") - self.axis_BS[f].text(1, .70, stg.freq_text[f], + self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, horizontalalignment='right', verticalalignment='bottom', transform=self.axis_BS[f].transAxes) @@ -1965,12 +2929,13 @@ class AcousticDataTab(QWidget): self.fig_BS.canvas.draw_idle() + # # --- Plot transect SNR with bathymetry --- # if self.canvas_SNR != None: # # x, y = np.meshgrid( # # stg.time[np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]: # # np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]], - # # stg.r) + # # stg.depth) # # x = np.array([[[]]]) # y = np.array([[[]]]) @@ -1979,12 +2944,12 @@ class AcousticDataTab(QWidget): # for f, _ in enumerate(stg.freq): # # if x.shape[2] == 0: - # x, y = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) + # x, y = np.meshgrid(stg.time_snr[f, :], stg.depth[f, :]) # x = np.array([x]) # y = np.array([y]) # # print(f"x : {x.shape}, y : {y.shape}") # else: - # x0, y0 = np.meshgrid(stg.time_snr[f, :], stg.r[f, :]) + # x0, y0 = np.meshgrid(stg.time_snr[f, :], stg.depth[f, :]) # x = np.append(x, np.array([x0]), axis=0) # y = np.append(y, np.array([y0]), axis=0) # # print(f"x : {x.shape}, y : {y.shape}") @@ -2029,7 +2994,7 @@ class AcousticDataTab(QWidget): # horizontalalignment='right', verticalalignment='bottom', # transform=self.axis_SNR[f].transAxes) # - # self.axis_SNR[f].plot(stg.t[self.combobox_freq_choice.currentIndex(), :], -stg.r_bottom, + # self.axis_SNR[f].plot(stg.t[self.combobox_freq_choice.currentIndex(), :], -stg.depth_bottom, # color='black', linewidth=1, linestyle="solid") # # # self.axis_SNR[f].plot( diff --git a/main.py b/main.py index c40f9ea..969f408 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,7 @@ from View.mainwindow import Ui_MainWindow from View.acoustic_data_tab import AcousticDataTab from View.signal_processing_tab import SignalProcessingTab from View.sample_data_tab import SampleDataTab +from View.sediment_calibration_tab import SedimentCalibrationTab from View.acoustic_inversion_tab import AcousticInversionTab from View.note_tab import NoteTab from View.user_manual_tab import UserManualTab @@ -18,6 +19,8 @@ import matplotlib.pyplot as plt # Check encoding used # print(sys.getdefaultencoding()) +# python3 -m PyQt5.uic.pyuic -x QScrollbar.ui -o QScrollbar.py + PERCENT_SCREEN_SIZE = 0.85 _translate = QCoreApplication.translate @@ -45,7 +48,7 @@ class MainApplication(QMainWindow): # Connect push buttons to download data files22 # ************************************************** - # --------- Signal processing data tab ---------- + # --------- Signal pre-processing data tab ---------- self.signal_processing_tab = SignalProcessingTab(self.ui_mainwindow.tab2) @@ -54,20 +57,25 @@ class MainApplication(QMainWindow): self.sample_data_tab = SampleDataTab(self.ui_mainwindow.tab3) + # ************************************************** + # ------------ Sediment calibration tab ------------- + + self.sediment_calibration_tab = SedimentCalibrationTab(self.ui_mainwindow.tab4) + # ************************************************** # ------------ Acoustic inversion tab ------------- - self.acoustic_inversion_tab = AcousticInversionTab(self.ui_mainwindow.tab4) + self.acoustic_inversion_tab = AcousticInversionTab(self.ui_mainwindow.tab5) # ************************************************** # ------------------- Note tab -------------------- - self.note_tab = NoteTab(self.ui_mainwindow.tab5) + self.note_tab = NoteTab(self.ui_mainwindow.tab6) # ************************************************** # ---------------- User Manual tab ----------------- - self.user_manual_tab = UserManualTab(self.ui_mainwindow.tab6) + self.user_manual_tab = UserManualTab(self.ui_mainwindow.tab7) # ************************************************** # ---------------- Text File Error ----------------- diff --git a/settings.py b/settings.py index 02ce321..2238a6a 100644 --- a/settings.py +++ b/settings.py @@ -6,16 +6,16 @@ import datetime # --- load raw data --- -ABS_name = "" +ABS_name = [] -path_BS_raw_data = "" -filename_BS_raw_data = "" -BS_raw_data = np.array([]) # BS raw data : all measurement (go and back) -r = np.array([]) -r_2D = np.array([]) -freq = np.array([]) -freq_text = list() -time = np.array([]) +path_BS_raw_data = [] +filename_BS_raw_data = [] +BS_raw_data = [] # BS raw data : all measurement (go and back) +depth = [] +r_2D = [] +freq = [] +freq_text = [] +time = [] path_BS_noise_data = "" filename_BS_noise_data = "" @@ -26,45 +26,48 @@ date = [] date_noise = [] hour = [] hour_noise = [] -nb_profiles = 0 -nb_profiles_per_sec = 0.0 -nb_cells = 0 -cell_size = 0.0 -pulse_length = 0.0 -nb_pings_per_sec = 0 -nb_pings_averaged_per_profile = 0.0 -kt = np.array([]) -gain_rx = np.array([]) -gain_tx = np.array([]) +nb_profiles = [] +nb_profiles_per_sec = [] +nb_cells = [] +cell_size = [] +pulse_length = [] +nb_pings_per_sec = [] +nb_pings_averaged_per_profile = [] +kt = [] +gain_rx = [] +gain_tx = [] SNR_data = np.array([]) # SNR is computed with BS_noise_averaged_data time_snr = np.array([]) # --- reshape raw data for table of values in Acoustic Data tab --- -time_reshape = np.array([]) +time_reshape = [] time_snr_reshape = np.array([]) -r_reshape = np.array([]) -BS_raw_data_reshape = np.array([]) +r_reshape = [] +BS_raw_data_reshape = [] SNR_reshape = np.array([]) # snr is reshape to be included in table of values in acoustic data tab DataFrame_acoustic = pd.DataFrame() # --- Processed data in Acoustic Data Tab and used in Acoustic processing tab --- -tmin = np.array([]) # minimum boundary of time (spin box tmin) +tmin = [] # minimum boundary of time (spin box tmin) tmin_snr = np.array([]) -tmax = np.array([]) # maximum boundary of time (spin box tmin) +tmax = [] # maximum boundary of time (spin box tmin) tmax_snr = np.array([]) -BS_cross_section = np.array([]) # BS data limited with tmin and tmax values of spin box +rmin = [] +rmax = [] +BS_cross_section = [] # BS data limited with tmin and tmax values of spin box # BS_data = stg.BS_raw_data[f, :, int(stg.tmin[f]):int(stg.tmax[f])] -BS_stream_bed = np.array([]) # BS_data_section = BS data in the section. Values NaN outside the bottom of the section are deleted +BS_stream_bed = [] # BS_data_section = BS data in the section. Values NaN outside the bottom of the section are deleted BS_noise_cross_section = np.array([]) # BS_noise_cros_section = BS_noise_data[:, :, tmin:tmax] (former Noise_data) SNR_cross_section = np.array([]) # SNR_data = snr[:, :, tmin:tmax] SNR_stream_bed = np.array([]) -t = np.array([]) +t_cross_section = [] t_snr = np.array([]) -r_bottom = np.array([]) -val_bottom = np.array([]) -ind_bottom = np.array([]) -freq_bottom_detection = 0 +depth_cross_section = [] +depth_bottom = [] +val_bottom = [] +ind_bottom = [] +freq_bottom_detection = [] # --- Processed data in Signal Processing Tab --- # BS_cross_section_SNR_filter = np.array([[[]]]) # BS data filtered with SNR values (remove point if SNR < value) - bottom is not detected