1195 lines
62 KiB
Python
1195 lines
62 KiB
Python
import sys
|
|
|
|
from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QGroupBox, QLabel, QCheckBox,
|
|
QSpinBox, QDoubleSpinBox, QComboBox, QLineEdit, QSlider, QGridLayout, QMessageBox,
|
|
QScrollArea)
|
|
from PyQt5.QtGui import QFont, QIcon, QPixmap
|
|
from PyQt5.QtCore import Qt, QCoreApplication
|
|
|
|
import numpy as np
|
|
from copy import deepcopy
|
|
from scipy.ndimage import convolve1d
|
|
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
|
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
|
|
from matplotlib.colors import LogNorm
|
|
from scipy import stats
|
|
|
|
import Translation.constant_string as cs
|
|
|
|
from Model.acoustic_data_loader import AcousticDataLoader
|
|
|
|
import settings as stg
|
|
|
|
from Model.acoustic_inversion_method_high_concentration import AcousticInversionMethodHighConcentration
|
|
|
|
_translate = QCoreApplication.translate
|
|
|
|
|
|
class SignalProcessingTab(QWidget):
|
|
|
|
''' This class generates the Signal Processing Tab '''
|
|
|
|
def __init__(self, widget_tab):
|
|
super().__init__()
|
|
|
|
self.inv_hc = AcousticInversionMethodHighConcentration()
|
|
|
|
path_icon = "./icons/"
|
|
icon_triangle_left = QIcon(path_icon + "triangle_left.png")
|
|
icon_triangle_right = QIcon(path_icon + "triangle_right.png")
|
|
|
|
### --- General layout of widgets ---
|
|
|
|
# ___________ ____________________________
|
|
# | profile | | Profile |
|
|
# | position | | |
|
|
# | | | |
|
|
# | | | Averaged profile |
|
|
# | post | | |
|
|
# | proc | | |
|
|
# | options | | FCB option |
|
|
# |___________| |____________________________|
|
|
|
|
self.horizontalLayout_Main = QHBoxLayout(widget_tab)
|
|
|
|
self.verticalLayout_Left = QVBoxLayout()
|
|
self.horizontalLayout_Main.addLayout(self.verticalLayout_Left, 2)
|
|
|
|
self.verticalLayout_Right = QVBoxLayout()
|
|
self.horizontalLayout_Main.addLayout(self.verticalLayout_Right, 8)
|
|
|
|
# --------------------------------------------------------------------------------------------------------------
|
|
### --- Layout of groupbox in the Left vertical layout box
|
|
|
|
# Push button Load data
|
|
# ---------------------
|
|
# Profile position
|
|
# ---------------------
|
|
# Post processing
|
|
# ---------------------
|
|
# FCB options
|
|
|
|
self.horizontalLayout_pushbutton_load_data_plot_bottom_line = QHBoxLayout()
|
|
self.verticalLayout_Left.addLayout(self.horizontalLayout_pushbutton_load_data_plot_bottom_line)
|
|
|
|
self.groupbox_display_profile_position = QGroupBox()
|
|
self.verticalLayout_Left.addWidget(self.groupbox_display_profile_position)
|
|
|
|
self.groupbox_post_processing = QGroupBox()
|
|
self.verticalLayout_Left.addWidget(self.groupbox_post_processing)
|
|
|
|
self.groupbox_FCBoption = QGroupBox()
|
|
self.verticalLayout_Left.addWidget(self.groupbox_FCBoption)
|
|
|
|
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
# +++ --- Push button Load data + Push button plot bottom --- +++
|
|
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
self.pushbutton_load_data = QPushButton()
|
|
self.horizontalLayout_pushbutton_load_data_plot_bottom_line.addWidget(self.pushbutton_load_data)
|
|
self.pushbutton_load_data.clicked.connect(self.compute_BS_data_section)
|
|
# self.pushbutton_load_data.clicked.connect(self.plot_profile_position_on_transect)
|
|
# self.pushbutton_load_data.clicked.connect(self.plot_profile)
|
|
|
|
self.combobox_frequency = QComboBox()
|
|
self.horizontalLayout_pushbutton_load_data_plot_bottom_line.addWidget(self.combobox_frequency)
|
|
# self.combobox_frequency.currentTextChanged.connect(self.update_plot_profile_position_on_transect)
|
|
|
|
# +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
# +++ --- GroupBox Display Profile Position --- +++
|
|
# +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
self.verticalLayout_groupbox_display_profile_position = QVBoxLayout(self.groupbox_display_profile_position)
|
|
|
|
self.label_profile_number = QLabel()
|
|
self.label_profile_number.setFont(QFont("Ubuntu", 16, QFont.Bold))
|
|
self.label_profile_number.setAlignment(Qt.AlignCenter)
|
|
# self.label_profile_number.setText("Profile 1 / " + str(stg.nb_profiles))
|
|
self.verticalLayout_groupbox_display_profile_position.addWidget(self.label_profile_number)
|
|
|
|
self.canvas_plot_profile_position_on_transect = None
|
|
|
|
# self.figure_plot_profile_position_on_transect, self.axis_plot_profile_position_on_transect = \
|
|
# plt.subplots(nrows=1, ncols=1, layout="constrained")
|
|
# self.canvas_plot_profile_position_on_transect = FigureCanvas(self.figure_plot_profile_position_on_transect)
|
|
# self.plot_transect_bottom_with_profile_position(0)
|
|
#
|
|
# # self.axis_plot_profile_position_on_transect.plot(
|
|
# # 0 * np.ones(self.model.r_bottom_cross_section.shape[0]),
|
|
# # self.model.r_bottom_cross_section, color='red', linestyle="solid", linewidth=2)
|
|
#
|
|
# self.verticalLayout_groupbox_display_profile_position.addWidget(self.canvas_plot_profile_position_on_transect)
|
|
#
|
|
# self.horizontalLayout_slider_plot_profile_position = QHBoxLayout()
|
|
# self.verticalLayout_groupbox_display_profile_position.addLayout(
|
|
# self.horizontalLayout_slider_plot_profile_position)
|
|
#
|
|
# # self.icon_triangle_left = QPixmap(path_icon + "triangle_left.png")
|
|
# # self.pushButton_slider_plot_profile_position_left = QPushButton()
|
|
# # self.pushButton_slider_plot_profile_position_left.setIcon(QIcon(self.icon_triangle_left))
|
|
# # self.icon_triangle_right = QPixmap(path_icon + "triangle_right.png")
|
|
# # self.pushButton_slider_plot_profile_position_right = QPushButton()
|
|
# # self.pushButton_slider_plot_profile_position_right.setIcon(QIcon(self.icon_triangle_right))
|
|
# #
|
|
# # self.horizontalLayout_slider_plot_profile_position.addWidget(self.pushButton_slider_plot_profile_position_left)
|
|
# # self.horizontalLayout_slider_plot_profile_position.addWidget(self.pushButton_slider_plot_profile_position_right)
|
|
# #
|
|
# # self.lineEdit_slider_plot_profile_position = QLineEdit()
|
|
# # self.horizontalLayout_slider_plot_profile_position.addWidget(self.lineEdit_slider_plot_profile_position)
|
|
# #
|
|
# # self.slider_plot_profile_position = QSlider()
|
|
# # self.slider_plot_profile_position.setOrientation(Qt.Horizontal)
|
|
# # self.slider_plot_profile_position.setTickPosition(QSlider.TicksBelow)
|
|
# # self.slider_plot_profile_position.setCursor(Qt.OpenHandCursor)
|
|
# # self.slider_plot_profile_position.setMinimum(0)
|
|
# # self.slider_plot_profile_position.setMaximum(1)
|
|
# # self.slider_plot_profile_position.setTickInterval(1)
|
|
# # self.slider_plot_profile_position.setValue(0)
|
|
# # self.horizontalLayout_slider_plot_profile_position.addWidget(self.slider_plot_profile_position)
|
|
#
|
|
# # self.horizontalLayoutTop_signalProcessing.addWidget(self.groupbox_display_profile_position, 3)
|
|
|
|
# ++++++++++++++++++++++++++++++++++++++++
|
|
# +++ --- GroupBox Post Processing --- +++
|
|
# ++++++++++++++++++++++++++++++++++++++++
|
|
|
|
self.verticalLayout_groupbox_post_processing = QVBoxLayout(self.groupbox_post_processing)
|
|
|
|
self.groupbox_rayleigh_criterion = QGroupBox()
|
|
self.verticalLayout_groupbox_post_processing.addWidget(self.groupbox_rayleigh_criterion)
|
|
|
|
self.groupbox_window_size = QGroupBox()
|
|
self.verticalLayout_groupbox_post_processing.addWidget(self.groupbox_window_size)
|
|
|
|
self.groupbox_acoustic_profile = QGroupBox()
|
|
self.verticalLayout_groupbox_post_processing.addWidget(self.groupbox_acoustic_profile)
|
|
|
|
# --- Groupbox Rayleigh criterion ---
|
|
|
|
self.gridLayout_rayleigh_criterion = QGridLayout(self.groupbox_rayleigh_criterion)
|
|
|
|
self.label_Rayleigh_criterion = QLabel()
|
|
self.label_Rayleigh_criterion.setText("<V²>/<V>² <=")
|
|
self.gridLayout_rayleigh_criterion.addWidget(self.label_Rayleigh_criterion, 0, 0, 1, 1)
|
|
|
|
self.spinbox_rayleigh_criterion = QSpinBox()
|
|
self.spinbox_rayleigh_criterion.setRange(0, 9999)
|
|
self.spinbox_rayleigh_criterion.setValue(10)
|
|
self.gridLayout_rayleigh_criterion.addWidget(self.spinbox_rayleigh_criterion, 0, 1, 1, 1)
|
|
|
|
self.label_4pi = QLabel()
|
|
self.label_4pi.setText("% x 4/pi")
|
|
self.gridLayout_rayleigh_criterion.addWidget(self.label_4pi, 0, 2, 1, 1)
|
|
|
|
self.pushbutton_despiking_signal = QPushButton()
|
|
self.pushbutton_despiking_signal.setText("Despiking the signal")
|
|
self.gridLayout_rayleigh_criterion.addWidget(self.pushbutton_despiking_signal, 0, 3, 1, 1)
|
|
|
|
# --- Groupbox Window size ---
|
|
|
|
# self.horizontalLayout_groupbox_window_size = QHBoxLayout(self.groupbox_window_size)
|
|
self.gridLayout_groupbox_window_size = QGridLayout(self.groupbox_window_size)
|
|
|
|
self.label_signal_averaging_horizontal = QLabel()
|
|
self.label_signal_averaging_horizontal.setText("Horizontal +/- ")
|
|
# self.horizontalLayout_groupbox_window_size.addWidget(self.label_signal_averaging_over)
|
|
self.gridLayout_groupbox_window_size.addWidget(self.label_signal_averaging_horizontal, 0, 0, 1, 1)
|
|
self.spinbox_average_horizontal = QSpinBox()
|
|
self.spinbox_average_horizontal.setRange(0, 9999)
|
|
self.spinbox_average_horizontal.setValue(0)
|
|
# self.horizontalLayout_groupbox_window_size.addWidget(self.spinbox_average)
|
|
self.gridLayout_groupbox_window_size.addWidget(self.spinbox_average_horizontal, 0, 1, 1, 1)
|
|
self.label_cells_horizontal = QLabel()
|
|
self.label_cells_horizontal.setText("cells = +/- ? sec")
|
|
# self.horizontalLayout_groupbox_window_size.addWidget(self.label_cells)
|
|
self.gridLayout_groupbox_window_size.addWidget(self.label_cells_horizontal, 0, 2, 1, 1)
|
|
|
|
# self.label_signal_averaging_vertical = QLabel()
|
|
# self.label_signal_averaging_vertical.setText("Vertical +/- ")
|
|
# # self.horizontalLayout_groupbox_window_size.addWidget(self.label_signal_averaging_over)
|
|
# self.gridLayout_groupbox_window_size.addWidget(self.label_signal_averaging_vertical, 1, 0, 1, 1)
|
|
# self.spinbox_average_vertical = QSpinBox()
|
|
# self.spinbox_average_vertical.setRange(0, 9999)
|
|
# self.spinbox_average_vertical.setValue(0)
|
|
# # self.horizontalLayout_groupbox_window_size.addWidget(self.spinbox_average)
|
|
# self.gridLayout_groupbox_window_size.addWidget(self.spinbox_average_vertical, 1, 1, 1, 1)
|
|
# self.label_cells_vertical = QLabel()
|
|
# self.label_cells_vertical.setText("cells = +/- ? sec")
|
|
# # self.horizontalLayout_groupbox_window_size.addWidget(self.label_cells)
|
|
# self.gridLayout_groupbox_window_size.addWidget(self.label_cells_vertical, 1, 2, 1, 1)
|
|
|
|
# self.spinbox_average.valueChanged.connect(self.compute_averaged_profile)
|
|
|
|
self.pushbutton_average = QPushButton()
|
|
self.pushbutton_average.setText("Apply averaging")
|
|
# self.pushbutton_snr_filter.setDisabled(True)
|
|
# self.horizontalLayout_groupbox_window_size.addWidget(self.pushbutton_average)
|
|
self.gridLayout_groupbox_window_size.addWidget(self.pushbutton_average, 0, 3, 2, 1)
|
|
|
|
self.pushbutton_average.clicked.connect(self.compute_averaged_profile)
|
|
# self.pushbutton_average.clicked.connect(self.update_plot_profile_position_on_transect)
|
|
# self.pushbutton_average.clicked.connect(self.plot_averaged_profile)
|
|
|
|
# --- Groupbox acoustic profile ---
|
|
|
|
self.gridLayout_groupbox_acoustic_profile = QGridLayout(self.groupbox_acoustic_profile)
|
|
|
|
# self.checkbox_SNR_criterion = QCheckBox()
|
|
self.label_SNR_criterion = QLabel()
|
|
self.gridLayout_groupbox_acoustic_profile.addWidget(self.label_SNR_criterion, 0, 0, 1, 1)
|
|
self.spinbox_SNR_criterion = QSpinBox()
|
|
self.spinbox_SNR_criterion.setRange(0, 9999)
|
|
self.spinbox_SNR_criterion.setValue(0)
|
|
# self.spinbox_SNR_criterion.setDisabled(True)
|
|
self.gridLayout_groupbox_acoustic_profile.addWidget(self.spinbox_SNR_criterion, 0, 1, 1, 1)
|
|
|
|
# self.spinbox_SNR_criterion.valueChanged.connect(self.remove_point_with_snr_filter)
|
|
|
|
self.pushbutton_snr_filter = QPushButton()
|
|
self.pushbutton_snr_filter.setText("Apply SNR")
|
|
self.gridLayout_groupbox_acoustic_profile.addWidget(self.pushbutton_snr_filter, 0, 2, 1, 1)
|
|
|
|
self.pushbutton_snr_filter.clicked.connect(self.remove_point_with_snr_filter)
|
|
# self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile)
|
|
# self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile_position_on_transect)
|
|
|
|
# ++++++++++++++++++++++++++++++++++++
|
|
# +++ --- GroupBox FCB options --- +++
|
|
# ++++++++++++++++++++++++++++++++++++
|
|
|
|
self.verticalLayout_groupbox_FCBoption = QVBoxLayout(self.groupbox_FCBoption)
|
|
|
|
self.groupbox_water_attenuation = QGroupBox()
|
|
self.verticalLayout_groupbox_FCBoption.addWidget(self.groupbox_water_attenuation)
|
|
|
|
self.groupbox_fit_regression_line = QGroupBox()
|
|
self.verticalLayout_groupbox_FCBoption.addWidget(self.groupbox_fit_regression_line)
|
|
|
|
# --- Groupbox water attenuation ---
|
|
|
|
self.gridLayout_groupbox_water_attenuation = QGridLayout(self.groupbox_water_attenuation)
|
|
|
|
self.combobox_water_attenuation_model = QComboBox()
|
|
self.combobox_water_attenuation_model.addItem("François & Garrison 1982")
|
|
self.combobox_water_attenuation_model.addItem("Other model")
|
|
self.gridLayout_groupbox_water_attenuation.addWidget(self.combobox_water_attenuation_model, 0, 0, 1, 1)
|
|
|
|
self.label_temperature_water_attenation = QLabel()
|
|
self.gridLayout_groupbox_water_attenuation.addWidget(self.label_temperature_water_attenation, 0, 1, 1, 1)
|
|
|
|
self.spinbox_temperature_water_attenuation = QSpinBox()
|
|
self.gridLayout_groupbox_water_attenuation.addWidget(self.spinbox_temperature_water_attenuation, 0, 2, 1, 1)
|
|
|
|
self.label_degre_celsius = QLabel()
|
|
self.label_degre_celsius.setText("°C")
|
|
self.gridLayout_groupbox_water_attenuation.addWidget(self.label_degre_celsius, 0, 3, 1, 1)
|
|
|
|
self.combobox_freq_for_water_attenuation = QComboBox()
|
|
# self.combobox_water_attenuation.currentIndexChanged.connect(self.alpha_value_changed)
|
|
self.gridLayout_groupbox_water_attenuation.addWidget(self.combobox_freq_for_water_attenuation, 1, 0, 1, 1)
|
|
|
|
self.pushbutton_water_attenuation = QPushButton()
|
|
self.pushbutton_water_attenuation.setText("Compute \u03B1w")
|
|
self.gridLayout_groupbox_water_attenuation.addWidget(self.pushbutton_water_attenuation, 1, 1, 1, 1)
|
|
self.pushbutton_water_attenuation.clicked.connect(self.compute_water_attenuation)
|
|
|
|
self.label_water_attenuation = QLabel()
|
|
self.label_water_attenuation.setText("\u03B1w = 0.00 dB/m")
|
|
self.label_water_attenuation.setFont(QFont("Ubuntu", 14, QFont.Normal))
|
|
self.gridLayout_groupbox_water_attenuation.addWidget(self.label_water_attenuation, 1, 2, 1, 1)
|
|
|
|
# --- Groupbox fit regression line ---
|
|
|
|
self.gridLayout_groupbox_fit_regression = QGridLayout(self.groupbox_fit_regression_line)
|
|
|
|
self.label_alphaS_expression = QLabel()
|
|
# self.label_alphaS_expression.setText("For homogeneous suspension: dFCB/dr = -2\u03B1<sub>s<\sub>")
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS_expression, 0, 0, 1, 5)
|
|
|
|
self.combobox_frequency_compute_alphaS = QComboBox()
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.combobox_frequency_compute_alphaS, 1, 0, 1, 1)
|
|
|
|
self.label_alphaS_computation_from = QLabel()
|
|
self.label_alphaS_computation_from.setText("From -")
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS_computation_from, 1, 1, 1, 1)
|
|
|
|
self.spinbox_alphaS_computation_from = QDoubleSpinBox()
|
|
self.spinbox_alphaS_computation_from.setRange(0, 9999)
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.spinbox_alphaS_computation_from, 1, 2, 1, 1)
|
|
|
|
self.label_alphaS_computation_to = QLabel()
|
|
self.label_alphaS_computation_to.setText("To -")
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS_computation_to, 1, 3, 1, 1)
|
|
|
|
self.spinbox_alphaS_computation_to = QDoubleSpinBox()
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.spinbox_alphaS_computation_to, 1, 4, 1, 1)
|
|
|
|
self.pushbutton_plot_FCB = QPushButton()
|
|
self.pushbutton_plot_FCB.setText("Plot FCB")
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.pushbutton_plot_FCB, 2, 0, 1, 1)
|
|
|
|
self.pushbutton_plot_FCB.clicked.connect(self.compute_FCB)
|
|
self.pushbutton_plot_FCB.clicked.connect(self.plot_FCB)
|
|
|
|
self.pushbutton_fit_linear_regression = QPushButton()
|
|
self.pushbutton_fit_linear_regression.setText("Fit && Compute \u03B1s")
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.pushbutton_fit_linear_regression, 2, 1, 1, 1)
|
|
|
|
self.pushbutton_fit_linear_regression.clicked.connect(self.fit_FCB_profile_with_linear_regression_and_compute_alphaS)
|
|
self.pushbutton_fit_linear_regression.clicked.connect(self.plot_FCB)
|
|
|
|
self.label_alphaS = QLabel()
|
|
self.label_alphaS.setText("\u03B1s = " + "0.0" + "dB/m")
|
|
self.label_alphaS.setFont(QFont("Ubuntu", 14, QFont.Normal))
|
|
self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS, 2, 3, 1, 1)
|
|
|
|
# self.verticalLayout_groupbox_fit_regression
|
|
|
|
# --------------------------------------------------------------------------------------------------------------
|
|
### --- Layout of groupbox in the Right vertical layout box
|
|
|
|
# Plot Profiles
|
|
# -------------------------
|
|
# Plot averaged profile
|
|
# -------------------------
|
|
# Plot FCB profiles
|
|
|
|
self.groupbox_plot_profile = QGroupBox()
|
|
self.verticalLayout_Right.addWidget(self.groupbox_plot_profile)
|
|
|
|
self.groupbox_plot_averaged_profile = QGroupBox()
|
|
self.verticalLayout_Right.addWidget(self.groupbox_plot_averaged_profile)
|
|
|
|
self.groupbox_FCB_profile = QGroupBox()
|
|
self.verticalLayout_Right.addWidget(self.groupbox_FCB_profile)
|
|
|
|
# +++++++++++++++++++++++++++++++++++++
|
|
# +++ --- GroupBox Plot profile --- +++
|
|
# +++++++++++++++++++++++++++++++++++++
|
|
|
|
self.verticalLayout_groupbox_plot_profile = QVBoxLayout(self.groupbox_plot_profile)
|
|
|
|
self.canvas_profile = None
|
|
self.scroll_profile = None
|
|
|
|
# # self.data_test_slider = np.array([[0, 1, 2, 3, 4, 5],
|
|
# # [0, 1, 4, 9, 16, 25],
|
|
# # [0, 1, 8, 27, 64, 125]])
|
|
#
|
|
#
|
|
#
|
|
# self.verticalLayout_plotprofiles = QVBoxLayout(self.groupbox_plot_profile)
|
|
# self.figure_profile, self.axis_profile = plt.subplots(nrows=1, ncols=4, layout='constrained')
|
|
# self.canvas_profile = FigureCanvas(self.figure_profile)
|
|
# # self.toolbar_profile =import NavigationToolBar(self.canvas_profile, self)
|
|
# # self.addToolBar(Qt.RightToolBarArea, self.toolbar_profile)
|
|
# # self.linear(self.figure_profile, self.axis_profile)
|
|
# for i in range(4):
|
|
# self.axis_profile[i].plot(self.model.BS_raw_cross_section.V[:, i, 0], self.model.r, c='k')
|
|
# # self.axis_profile.plot(self.data_test_slider[0, :], self.data_test_slider[0, :])
|
|
#
|
|
# self.toolbar_post_processing_tab = NavigationToolBar(self.canvas_profile, self)
|
|
# # self.addToolBar(Qt.RightToolBarArea, self.toolbar_post_processing_tab)
|
|
#
|
|
# # self.label_icon = QLabel()
|
|
# # self.label_icon.setPixmap(QPixmap("../icons/smiley1.jpg"))
|
|
#
|
|
# # self.verticalLayout_plotprofiles.addWidget(self.toolbar_profile)
|
|
# self.verticalLayout_plotprofiles.addWidget(self.canvas_profile)
|
|
# # self.verticalLayout_plotprofiles.addLayout(self.horizontalLayout_slider_plotprofil)
|
|
#
|
|
# # # self.verticalLayout_plotprofiles.addWidget(self.label_icon)
|
|
# # self.verticalLayout_plotprofiles.addWidget(self.slider_plotprofile)
|
|
#
|
|
# # self.slider_plotprofile.valueChanged.connect(self.changePlot)
|
|
#
|
|
# # self.horizontalLayoutTop_signalProcessing.addLayout(self.verticalLayout_plotprofiles, 7)
|
|
# # self.horizontalLayoutTop_signalProcessing.addWidget(self.groupbox_plot_profile, 7)
|
|
# # self.verticalLayout_right_SignalProcessingTab.addWidget(self.toolbar_profile)
|
|
|
|
# ++++++++++++++++++++++++++++++++++++++++++++++
|
|
# +++ --- GroupBox Plot averaged profile --- +++
|
|
# ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
self.verticalLayout_groupbox_plot_averaged_profile = QVBoxLayout(self.groupbox_plot_averaged_profile)
|
|
|
|
self.canvas_averaged_profile = None
|
|
self.scroll_averaged_profile = None
|
|
|
|
# self.verticalLayout_averagedprofile = QVBoxLayout(self.groupbox_plot_averaged_profile)
|
|
# self.figure_averagedprofile, self.axis_averagedprofile = plt.subplots(nrows=1, ncols=4, layout='constrained')
|
|
# self.canvas_averagedprofile = FigureCanvas(self.figure_averagedprofile)
|
|
# # self.toolbar_averagedprofile = NavigationToolBar(self.canvas_averagedprofile, self)
|
|
# # self.addToolBar(Qt.RightToolBarArea, self.toolbar_averagedprofile)
|
|
# # self.toolbar_profile = NavigationToolBar(self.canvas_averagedprofile, self)
|
|
# # self.polynome(self.figure_averagedprofile, self.axis_averagedprofile)
|
|
# for i in range(4):
|
|
# self.axis_averagedprofile[i].plot(self.model.BS_averaged_cross_section.V[:, i, 0], self.model.r, c='b')
|
|
#
|
|
# self.toolbar_post_processing_tab = NavigationToolBar(self.canvas_averagedprofile, self)
|
|
#
|
|
# # self.horizontalLayout_slider_averagedprofile = QHBoxLayout()
|
|
# #
|
|
# # self.pushButton_slider_averagedprofile_right = QPushButton()
|
|
# # self.pushButton_slider_averagedprofile_right.setIcon(icon_triangle_right)
|
|
# #
|
|
# # self.pushButton_slider_averagedprofile_left = QPushButton()
|
|
# # self.pushButton_slider_averagedprofile_left.setIcon(icon_triangle_left)
|
|
# #
|
|
# # self.horizontalLayout_slider_averagedprofile.addWidget(self.pushButton_slider_averagedprofile_left)
|
|
# # self.horizontalLayout_slider_averagedprofile.addWidget(self.pushButton_slider_averagedprofile_right)
|
|
# #
|
|
# # self.lineEdit_slider_averaged_profile = QLineEdit()
|
|
# # self.lineEdit_slider_averaged_profile.setFixedWidth(50)
|
|
# # self.lineEdit_slider_averaged_profile.setText("1")
|
|
# # self.horizontalLayout_slider_averagedprofile.addWidget(self.lineEdit_slider_averaged_profile)
|
|
# #
|
|
# # self.slider_averagedprofile = QSlider()
|
|
# # self.slider_averagedprofile.setOrientation(Qt.Horizontal)
|
|
# # self.slider_averagedprofile.setTickPosition(QSlider.TicksBelow)
|
|
# # self.slider_averagedprofile.setCursor(Qt.OpenHandCursor)
|
|
# # self.slider_averagedprofile.setMinimum(0)
|
|
# # self.slider_averagedprofile.setMaximum(1)
|
|
# # self.slider_averagedprofile.setTickInterval(1)
|
|
# # self.slider_averagedprofile.setValue(0)
|
|
# # # self.slider_plotprofile.valueChanged.connect(self.changePlot)
|
|
# #
|
|
# # self.horizontalLayout_slider_averagedprofile.addWidget(self.slider_averagedprofile)
|
|
#
|
|
# # self.verticalLayout_averagedprofile.addWidget(self.toolbar_averagedprofile)
|
|
# self.verticalLayout_averagedprofile.addWidget(self.canvas_averagedprofile)
|
|
# # self.verticalLayout_averagedprofile.addLayout(self.horizontalLayout_slider_averagedprofile)
|
|
#
|
|
# # self.horizontalLayoutMid_signalProcessing.addLayout(self.verticalLayout_averagedprofile, 7)
|
|
# # self.horizontalLayoutMid_signalProcessing.addWidget(self.groupbox_plot_averaged_profile, 7)
|
|
|
|
# ++++++++++++++++++++++++++++++++++++++++++++++
|
|
# +++ --- GroupBox Plot FCB profile --- +++
|
|
# ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
self.verticalLayout_groupbox_plot_FCB_profile = QVBoxLayout(self.groupbox_FCB_profile)
|
|
|
|
self.canvas_FCB_profile = None
|
|
self.scroll_FCB_profile = None
|
|
|
|
# self.verticalLayout_FCBoptions = QVBoxLayout(self.groupbox_FCB_profile)
|
|
# self.figure_FCBoptions, self.axis_FCBoptions = plt.subplots(nrows=1, ncols=4, layout="constrained")
|
|
# self.canvas_FCBoptions = FigureCanvas(self.figure_FCBoptions)
|
|
# self.toolbar_FCBoptions = NavigationToolBar(self.canvas_FCBoptions, self)
|
|
# # self.addToolBar(Qt.LeftToolBarArea, self.toolbar_FCBoptions)
|
|
# # self.toolbar_profile = NavigationToolBar(self.canvas_FCBoptions, self)
|
|
# # self.cubique(self.figure_FCBoptions, self.axis_FCBoptions)
|
|
# for i in range(4):
|
|
# self.axis_FCBoptions[i].plot(self.model.FCB[:, i, 0], self.model.r, c='r')
|
|
#
|
|
# self.toolbar_post_processing_tab = NavigationToolBar(self.canvas_FCBoptions, self)
|
|
#
|
|
# # self.horizontalLayout_slider_FCBoptions = QHBoxLayout()
|
|
# #
|
|
# # self.pushButton_slider_FCBoptions_right = QPushButton()
|
|
# # self.pushButton_slider_FCBoptions_right.setIcon(icon_triangle_right)
|
|
# #
|
|
# # self.pushButton_slider_FCBoptions_left = QPushButton()
|
|
# # self.pushButton_slider_FCBoptions_left.setIcon(icon_triangle_left)
|
|
# #
|
|
# # self.horizontalLayout_slider_FCBoptions.addWidget(self.pushButton_slider_FCBoptions_left)
|
|
# # self.horizontalLayout_slider_FCBoptions.addWidget(self.pushButton_slider_FCBoptions_right)
|
|
# #
|
|
# # self.lineEdit_slider_FCBplot = QLineEdit()
|
|
# # self.lineEdit_slider_FCBplot.setFixedWidth(50)
|
|
# # self.lineEdit_slider_FCBplot.setText("1")
|
|
# # self.horizontalLayout_slider_FCBoptions.addWidget(self.lineEdit_slider_FCBplot)
|
|
# #
|
|
# # self.slider_FCBoptions = QSlider()
|
|
# # self.slider_FCBoptions.setOrientation(Qt.Horizontal)
|
|
# # self.slider_FCBoptions.setTickPosition(QSlider.TicksBelow)
|
|
# # self.slider_FCBoptions.setCursor(Qt.OpenHandCursor)
|
|
# # self.slider_FCBoptions.setMinimum(0)
|
|
# # self.slider_FCBoptions.setMaximum(1)
|
|
# # self.slider_FCBoptions.setTickInterval(1)
|
|
# # self.slider_FCBoptions.setValue(0)
|
|
# # # self.slider_plotprofile.valueChanged.connect(self.changePlot)
|
|
# #
|
|
# # self.horizontalLayout_slider_FCBoptions.addWidget(self.slider_FCBoptions)
|
|
#
|
|
# # self.verticalLayout_FCBoptions.addWidget(self.toolbar_FCBoptions)
|
|
# self.verticalLayout_FCBoptions.addWidget(self.canvas_FCBoptions)
|
|
# # self.verticalLayout_FCBoptions.addLayout(self.horizontalLayout_slider_FCBoptions)
|
|
#
|
|
# # self.horizontalLayoutBottom_signalProcessing.addLayout(self.verticalLayout_FCBoptions, 7)
|
|
# # self.horizontalLayoutBottom_signalProcessing.addWidget(self.groupbox_FCB_profile, 7)
|
|
#
|
|
|
|
|
|
# --- Slider ----
|
|
|
|
self.horizontalLayout_slider = QHBoxLayout()
|
|
self.verticalLayout_Right.addLayout(self.horizontalLayout_slider)
|
|
|
|
self.pushbutton_slider_left = QPushButton()
|
|
self.pushbutton_slider_left.setIcon(icon_triangle_left)
|
|
self.horizontalLayout_slider.addWidget(self.pushbutton_slider_left)
|
|
|
|
self.pushbutton_slider_right = QPushButton()
|
|
self.pushbutton_slider_right.setIcon(icon_triangle_right)
|
|
self.horizontalLayout_slider.addWidget(self.pushbutton_slider_right)
|
|
|
|
self.pushbutton_slider_right.clicked.connect(self.slide_profile_number_to_right)
|
|
|
|
self.pushbutton_slider_left.clicked.connect(self.slide_profile_number_to_left)
|
|
|
|
# self.horizontalLayout_slider_plotprofil.addWidget(self.pushButton_slider_plotprofile_left)
|
|
# self.horizontalLayout_slider_plotprofil.addWidget(self.pushButton_slider_plotprofile_right)
|
|
#
|
|
self.lineEdit_slider = QLineEdit()
|
|
self.lineEdit_slider.setText("1")
|
|
# # self.lineEdit_slider_acoustic_profile.setFixedWidth(self.pushButton_slider_plotprofile_left.size().width())
|
|
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_plotprofile.setTickPosition(QSlider.TicksBelow)
|
|
self.slider.setCursor(Qt.OpenHandCursor)
|
|
self.slider.setMinimum(1)
|
|
# self.slider.setMaximum(stg.nb_profiles)#self.model.BS_averaged_cross_section_corr.V.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_plot_averaged_profile)
|
|
self.slider.valueChanged.connect(self.update_plot_FCB)
|
|
|
|
self.retranslate_signal_processing_tab()
|
|
|
|
# # -------------------- Functions for Signal processing Tab --------------------
|
|
|
|
def retranslate_signal_processing_tab(self):
|
|
self.pushbutton_load_data.setText(_translate("CONSTANT_STRING", cs.LOAD_DATA_FROM_ACOUSTIC_DATA_TAB))
|
|
|
|
self.groupbox_display_profile_position.setTitle(_translate("CONSTANT_STRING", cs.DISPLAY_PROFILE_POSITION))
|
|
# self.label_profile_number.setText(_translate("CONSTANT_STRING", cs.PROFILE_NUMBER) + " " +
|
|
# str(self.string_profile_number) + " / " + str(self.string_profile_number_max))
|
|
|
|
self.groupbox_post_processing.setTitle(_translate("CONSTANT_STRING", cs.POST_PROCESSING))
|
|
|
|
self.groupbox_acoustic_profile.setTitle(_translate("CONSTANT_STRING", cs.ACOUSTIC_PROFILE))
|
|
# self.checkbox_substract_noise.setText(_translate("CONSTANT_STRING", cs.SUBTRACT_THE_NOISE))
|
|
self.label_SNR_criterion.setText(_translate("CONSTANT_STRING", cs.SNR_CRITERION))
|
|
|
|
self.groupbox_window_size.setTitle(_translate("CONSTANT_STRING", cs.WINDOW_SIZE))
|
|
# self.label_averageH.setText(_translate("CONSTANT_STRING", cs.HORIZONTAL) + ": +/-")
|
|
# self.label_cells.setText(_translate("CONSTANT_STRING", cs.CELLS) + " = +/- ? sec")
|
|
|
|
self.groupbox_rayleigh_criterion.setTitle(_translate("CONSTANT_STRING", cs.RAYLEIGH_CRITERION))
|
|
# self.checkbox_despiked_acoustic_signal.setText(_translate("CONSTANT_STRING", cs.DESPIKING))
|
|
|
|
self.groupbox_FCBoption.setTitle(_translate("CONSTANT_STRING", cs.FCB_OPTIONS))
|
|
|
|
self.groupbox_water_attenuation.setTitle(_translate("CONSTANT_STRING", cs.COMPUTING_WATER_ATTENUATION))
|
|
self.label_temperature_water_attenation.setText(_translate("CONSTANT_STRING", cs.TEMPERATURE) + ":")
|
|
|
|
self.groupbox_fit_regression_line.setTitle(_translate("CONSTANT_STRING", cs.FIT_REGRESSION_LINE))
|
|
self.label_alphaS_expression.setText(
|
|
_translate("CONSTANT_STRING", cs.FOR_HOMOGENEOUS_SUSPENSION) + ": dFCB/dr = -2\u03B1<sub>s<\sub>")
|
|
# self.label_alphaS_computation_from.setText(_translate("CONSTANT_STRING", cs.FROM))
|
|
# self.label_alphaS_computation_to.setText(_translate("CONSTANT_STRING", cs.TO))
|
|
|
|
self.groupbox_plot_profile.setTitle(_translate("CONSTANT_STRING", cs.PROFILE))
|
|
self.groupbox_plot_averaged_profile.setTitle(_translate("CONSTANT_STRING", cs.AVERAGED_PROFILE))
|
|
self.groupbox_FCB_profile.setTitle(_translate("CONSTANT_STRING", cs.FCB_PROFILE))
|
|
|
|
# ------------------------------------- Connect Push Button Load Data + Slider -------------------------------------
|
|
|
|
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 compute_BS_data_section(self):
|
|
if stg.BS_data.size == 0:
|
|
msgBox = QMessageBox()
|
|
msgBox.setWindowTitle("Load data Error")
|
|
msgBox.setIcon(QMessageBox.Warning)
|
|
msgBox.setText("Please check acoustic data Tab")
|
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
msgBox.exec()
|
|
else:
|
|
if stg.r_bottom.size == 0:
|
|
stg.BS_data_section = deepcopy(stg.BS_data)
|
|
elif stg.r_bottom.size != 0:
|
|
stg.BS_data_section = deepcopy(stg.BS_data)
|
|
for f in range(stg.freq.shape[0]):
|
|
for k in range(stg.r_bottom.shape[0]):
|
|
# print(k, np.where(stg.r >= stg.r_bottom[k])[0])
|
|
stg.BS_data_section[np.where(stg.r >= stg.r_bottom[k])[0], f, k] = np.nan
|
|
|
|
# --- Choose frequency (Combo box) to plot transect with profile position ---
|
|
self.combobox_frequency.addItems(stg.freq_text)
|
|
self.combobox_frequency.currentTextChanged.connect(self.update_plot_profile_position_on_transect)
|
|
|
|
# --- Choose frequency (Combo box) to compute water attenuation ---
|
|
self.combobox_freq_for_water_attenuation.addItems(stg.freq_text)
|
|
|
|
# --- Choose frequency (Combo box) to compute sediment attenuation ---
|
|
self.combobox_frequency_compute_alphaS.addItems(stg.freq_text)
|
|
|
|
# --- Fix maximum value of slider + Edit Label Profile number ---
|
|
self.slider.setMaximum(stg.t.shape[0])
|
|
self.label_profile_number.clear()
|
|
self.label_profile_number.setText("Profile " + str(self.slider.value()) + " / " + str(self.slider.maximum()))
|
|
|
|
self.plot_profile_position_on_transect()
|
|
self.plot_profile()
|
|
|
|
# ----------------------------------------- Connect Groupbox average data -----------------------------------------
|
|
|
|
def compute_averaged_profile(self):
|
|
|
|
if stg.BS_data_section.size == 0:
|
|
msgBox = QMessageBox()
|
|
msgBox.setWindowTitle("Average Backscatter signal Error")
|
|
msgBox.setIcon(QMessageBox.Warning)
|
|
msgBox.setText("Load data from acoustic data tab before averaging backscatter signal")
|
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
msgBox.exec()
|
|
else:
|
|
filter_convolve = np.ones(self.spinbox_average_horizontal.value())
|
|
|
|
stg.BS_data_section_averaged = np.zeros((stg.r.shape[0], stg.freq.shape[0], stg.t.shape[0]))
|
|
for f in range(stg.freq.shape[0]):
|
|
for i in range(stg.r.shape[0]):
|
|
stg.BS_data_section_averaged[i, f, :] \
|
|
= convolve1d(stg.BS_data_section[i, f, :], weights=filter_convolve) / filter_convolve.shape[0]
|
|
|
|
self.label_cells_horizontal.clear()
|
|
self.label_cells_horizontal.setText(
|
|
"cells = +/- " + str((self.spinbox_average_horizontal.value() // 2)*(1/stg.nb_profiles_per_sec)) + " sec")
|
|
|
|
# self.label_cells_vertical.clear()
|
|
# self.label_cells_vertical.setText(
|
|
# "cells = +/- " + str((self.spinbox_average_vertical.value() // 2) * (1 / stg.nb_profiles_per_sec)) + " sec")
|
|
|
|
self.plot_averaged_profile()
|
|
self.update_plot_profile_position_on_transect()
|
|
|
|
# ---------------------------------------- Connect Groupbox filter with SNR ----------------------------------------
|
|
|
|
def remove_point_with_snr_filter(self):
|
|
|
|
if stg.SNR_data.size == 0:
|
|
msgBox = QMessageBox()
|
|
msgBox.setWindowTitle("SNR filter Error")
|
|
msgBox.setIcon(QMessageBox.Warning)
|
|
msgBox.setText("Load Noise data from acoustic data tab before using SNR filter")
|
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
msgBox.exec()
|
|
|
|
else:
|
|
|
|
if stg.BS_data_section_averaged.size == 0:
|
|
stg.BS_data_section_SNR_filter = deepcopy(stg.BS_data_section)
|
|
stg.SNR_data_average = np.divide(
|
|
(stg.BS_data_section_SNR_filter - stg.Noise_data[:, :, :stg.t.shape[0]])**2,
|
|
stg.Noise_data[:, :, :stg.t.shape[0]]**2)
|
|
|
|
for f in range(stg.freq.shape[0]):
|
|
stg.BS_data_section_SNR_filter[np.where(stg.SNR_data_average[:, f, :] < self.spinbox_SNR_criterion.value())[0],
|
|
f,
|
|
np.where(stg.SNR_data_average[:, f, :] < self.spinbox_SNR_criterion.value())[1]] \
|
|
= np.nan
|
|
|
|
elif stg.BS_data_section_averaged.size != 0:
|
|
stg.BS_data_section_SNR_filter = deepcopy(stg.BS_data_section_averaged)
|
|
stg.SNR_data_average = np.divide(
|
|
(stg.BS_data_section_SNR_filter - stg.Noise_data[:, :, :stg.t.shape[0]]) ** 2,
|
|
stg.Noise_data[:, :, :stg.t.shape[0]] ** 2)
|
|
|
|
for f in range(stg.freq.shape[0]):
|
|
stg.BS_data_section_SNR_filter[
|
|
np.where(stg.SNR_data_average[:, f, :] < self.spinbox_SNR_criterion.value())[0],
|
|
f,
|
|
np.where(stg.SNR_data_average[:, f, :] < self.spinbox_SNR_criterion.value())[1]] \
|
|
= np.nan
|
|
|
|
self.update_plot_profile_position_on_transect()
|
|
self.update_plot_averaged_profile()
|
|
|
|
def compute_water_attenuation(self):
|
|
if (stg.freq.size == 0) or (self.spinbox_temperature_water_attenuation.value() == 0):
|
|
msgBox = QMessageBox()
|
|
msgBox.setWindowTitle("Water attenuation Error")
|
|
msgBox.setIcon(QMessageBox.Warning)
|
|
msgBox.setText("Load Backscatter data from acoustic data tab and enter a value of temperature")
|
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
msgBox.exec()
|
|
|
|
else:
|
|
|
|
if self.combobox_water_attenuation_model.currentIndex() == 0:
|
|
self.Francois_and_Garrison_1982()
|
|
|
|
else:
|
|
pass
|
|
|
|
print(f"{stg.water_attenuation:.2f}")
|
|
self.label_water_attenuation.clear()
|
|
self.label_water_attenuation.setText("\u03B1w = " + f"{stg.water_attenuation:.4f}" + " dB/m")
|
|
|
|
def Francois_and_Garrison_1982(self):
|
|
if self.spinbox_temperature_water_attenuation.value() > 20:
|
|
stg.water_attenuation = ((3.964 * 1e-4 - 1.146 * 1e-5 * self.spinbox_temperature_water_attenuation.value() +
|
|
1.45 * 1e-7 * self.spinbox_temperature_water_attenuation.value() ** 2 -
|
|
6.5 * 1e-10 * self.spinbox_temperature_water_attenuation.value() ** 3) * 1e-3 *
|
|
(np.log(10) / 20) *
|
|
(stg.freq[self.combobox_freq_for_water_attenuation.currentIndex()] * 1e-3) ** 2)
|
|
else:
|
|
stg.water_attenuation = ((4.937 * 1e-4 - 2.59 * 1e-5 * self.spinbox_temperature_water_attenuation.value() +
|
|
9.11 * 1e-7 * self.spinbox_temperature_water_attenuation.value() ** 2 -
|
|
1.5 * 1e-8 * self.spinbox_temperature_water_attenuation.value() ** 3) * 1e-3 *
|
|
(np.log(10) / 20) *
|
|
(stg.freq[self.combobox_freq_for_water_attenuation.currentIndex()] * 1e-3) ** 2)
|
|
|
|
# ------------ Computing real cell size ------------ #
|
|
def range_cells_function(self):
|
|
""" Computing the real cell size, that depends on the temperature """
|
|
# defaut Aquascat cell size
|
|
aquascat_cell_size = stg.r[1] - stg.r[0]
|
|
# Pulse duration
|
|
tau = aquascat_cell_size * 2 / 1500 # figure 2.9 1500 vitesse du son entrée pour le paramètrage des mesures aquascat
|
|
# Sound speed
|
|
cel = self.inv_hc.water_velocity(self.spinbox_temperature_water_attenuation.value())
|
|
# Real cell size
|
|
real_cell_size = cel * tau / 2 # voir fig 2.9
|
|
|
|
# Converting to real cell profile
|
|
real_r = stg.r / aquascat_cell_size * real_cell_size # (/ aquascat_cell_size) pour ramener BS.r entre 0 et 1
|
|
# (* real_cell_size) pour remettre les échelles spatiales sur la taille réelle des cellules
|
|
|
|
# R with right shape (numpy array)
|
|
R_real = np.repeat(real_r, len(stg.freq), axis=1)
|
|
|
|
return R_real
|
|
|
|
def compute_FCB(self):
|
|
R_real = np.repeat(self.range_cells_function()[:, :, np.newaxis], stg.t.shape[0], axis=2)
|
|
if (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0):
|
|
stg.FCB = (np.log(stg.BS_data_section) + np.log(R_real) +
|
|
2 * stg.water_attenuation * R_real)
|
|
elif stg.BS_data_section_SNR_filter.size == 0:
|
|
stg.FCB = (np.log(stg.BS_data_section_averaged) + np.log(R_real) +
|
|
2 * stg.water_attenuation * R_real)
|
|
else:
|
|
stg.FCB = (np.log(stg.BS_data_section_SNR_filter) + np.log(R_real) +
|
|
2 * stg.water_attenuation * R_real)
|
|
|
|
def fit_FCB_profile_with_linear_regression_and_compute_alphaS(self):
|
|
|
|
y0 = stg.FCB[:, self.combobox_frequency_compute_alphaS.currentIndex(), self.slider.value()]
|
|
y = y0[np.where(np.isnan(y0) == False)]
|
|
print("y : ", y)
|
|
|
|
x0 = stg.r.reshape(-1)
|
|
x = x0[np.where(np.isnan(y0) == False)]
|
|
|
|
value1 = np.where(np.round(np.abs(x - self.spinbox_alphaS_computation_from.value()), 2)
|
|
== np.min(np.round(np.abs(x - self.spinbox_alphaS_computation_from.value()), 2)))
|
|
value2 = np.where(np.round(np.abs(x - self.spinbox_alphaS_computation_to.value()), 2)
|
|
== np.min(np.round(np.abs(x - self.spinbox_alphaS_computation_to.value()), 2)))
|
|
|
|
print(np.round(np.abs(x - self.spinbox_alphaS_computation_from.value()), 2))
|
|
print("value1 ", value1[0][0])
|
|
print(np.round(np.abs(x - self.spinbox_alphaS_computation_to.value()), 2))
|
|
print("value2 ", value2[0][0])
|
|
|
|
print("y limited ", y[value1[0][0]:value2[0][0]])
|
|
|
|
# y = stg.FCB[value1:value2, self.combobox_frequency_compute_alphaS.currentIndex(), self.slider.value()]
|
|
# print("y : ", y)
|
|
|
|
lin_reg_compute = stats.linregress(x[value1[0][0]:value2[0][0]], y[value1[0][0]:value2[0][0]])
|
|
stg.lin_reg = (lin_reg_compute.slope, lin_reg_compute.intercept)
|
|
print(f"y = {stg.lin_reg[0]}x + {stg.lin_reg[1]}")
|
|
|
|
self.label_alphaS.clear()
|
|
self.label_alphaS.setText(f"\u03B1s = {-0.5*stg.lin_reg[0]:.4f} dB/m")
|
|
|
|
# for i, value_freq in enumerate(stg.freq):
|
|
# for k, value_t in enumerate(stg.t):
|
|
# # print(f"indice i: {i}, indice k: {k}")
|
|
# # print(f"values of FCB: {stg.FCB[:, i, k]}")
|
|
# y = stg.FCB[:, i, k]
|
|
# # print("y : ", y)
|
|
# # print(f"values of FCB where FCB is not Nan {y[np.where(np.isnan(y) == False)]}")
|
|
# # print(f"values of r where FCB is not Nan {x[np.where(np.isnan(y) == False)]}")
|
|
# lin_reg_compute = stats.linregress(x[np.where(np.isnan(y) == False)], y[np.where(np.isnan(y) == False)])
|
|
# lin_reg_tuple = (lin_reg_compute.slope, lin_reg_compute.intercept)
|
|
# stg.lin_reg.append(lin_reg_tuple)
|
|
|
|
# print(f"y = {lin_reg.slope}x + {lin_reg.intercept}")
|
|
|
|
# plt.figure()
|
|
# plt.plot(stg.r, stg.FCB[:, 0, 825], 'k-', stg.r, lin_reg.slope*stg.r + lin_reg.intercept, "b--")
|
|
# plt.show()
|
|
|
|
# print("lin_reg length ", len(stg.lin_reg))
|
|
# print("lin_reg ", stg.lin_reg)
|
|
|
|
# ---------------------------------------- PLOT PROFILE POSITION ON TRANSECT ---------------------------------------
|
|
|
|
def plot_profile_position_on_transect(self):
|
|
|
|
# --- Create Matplotlib canvas (with figure and axis) to plot transect ---
|
|
self.canvas_plot_profile_position_on_transect = FigureCanvas()
|
|
self.figure_plot_profile_position_on_transect, self.axis_plot_profile_position_on_transect = \
|
|
plt.subplots(nrows=1, ncols=1, layout="constrained")
|
|
self.canvas_plot_profile_position_on_transect = FigureCanvas(self.figure_plot_profile_position_on_transect)
|
|
self.verticalLayout_groupbox_display_profile_position.addWidget(self.canvas_plot_profile_position_on_transect)
|
|
|
|
# --- Plot transect with profile position ---
|
|
val_min = np.nanmin(stg.BS_data_section[:, stg.freq_bottom_detection, :])
|
|
val_max = np.nanmax(stg.BS_data_section[:, stg.freq_bottom_detection, :])
|
|
if val_min == 0:
|
|
val_min = 1e-5
|
|
|
|
self.axis_plot_profile_position_on_transect.pcolormesh(
|
|
stg.t, -stg.r, stg.BS_data_section[:, stg.freq_bottom_detection, :],
|
|
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
|
|
|
|
if stg.r_bottom.size != 0:
|
|
self.axis_plot_profile_position_on_transect.plot(
|
|
stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid")
|
|
|
|
self.axis_plot_profile_position_on_transect.plot(
|
|
stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r,
|
|
color='red', linestyle="solid", linewidth=2)
|
|
|
|
self.axis_plot_profile_position_on_transect.set_xticks([])
|
|
self.axis_plot_profile_position_on_transect.set_yticks([])
|
|
|
|
self.figure_plot_profile_position_on_transect.canvas.draw_idle()
|
|
|
|
def update_plot_profile_position_on_transect(self):
|
|
|
|
# --- Update label "Profile N / max(N)" ---
|
|
self.label_profile_number.clear()
|
|
self.label_profile_number.setText("Profile " + str(self.slider.value()) + " / " + str(self.slider.maximum()))
|
|
|
|
# --- Update transect plot ---
|
|
|
|
if self.canvas_plot_profile_position_on_transect is None:
|
|
msgBox = QMessageBox()
|
|
msgBox.setWindowTitle("Plot Error")
|
|
msgBox.setIcon(QMessageBox.Warning)
|
|
msgBox.setText("Load and post-process data before plotting transect with profile position")
|
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
msgBox.exec()
|
|
|
|
else:
|
|
|
|
if (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0):
|
|
|
|
self.axis_plot_profile_position_on_transect.cla()
|
|
|
|
val_min = np.nanmin(stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :])
|
|
val_max = np.nanmax(stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :])
|
|
if val_min == 0:
|
|
val_min = 1e-5
|
|
|
|
self.axis_plot_profile_position_on_transect.pcolormesh(
|
|
stg.t, -stg.r, stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :],
|
|
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
|
|
|
|
if stg.r_bottom.size != 0:
|
|
self.axis_plot_profile_position_on_transect.plot(stg.t, -stg.r_bottom,
|
|
color='black', linewidth=1, linestyle="solid")
|
|
|
|
self.axis_plot_profile_position_on_transect.plot(
|
|
stg.t[self.slider.value()-1] * np.ones(stg.r.shape[0]), -stg.r,
|
|
color='red', linestyle="solid", linewidth=2)
|
|
|
|
self.axis_plot_profile_position_on_transect.set_xticks([])
|
|
self.axis_plot_profile_position_on_transect.set_yticks([])
|
|
|
|
self.figure_plot_profile_position_on_transect.canvas.draw_idle()
|
|
|
|
elif (stg.BS_data_section_averaged.size != 0) and (stg.BS_data_section_SNR_filter.size == 0):
|
|
|
|
self.axis_plot_profile_position_on_transect.cla()
|
|
|
|
val_min = np.nanmin(stg.BS_data_section_averaged[:, self.combobox_frequency.currentIndex(), :])
|
|
val_max = np.nanmax(stg.BS_data_section_averaged[:, self.combobox_frequency.currentIndex(), :])
|
|
if val_min == 0:
|
|
val_min = 1e-5
|
|
|
|
self.axis_plot_profile_position_on_transect.pcolormesh(
|
|
stg.t, -stg.r, stg.BS_data_section_averaged[:, self.combobox_frequency.currentIndex(), :],
|
|
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
|
|
|
|
if stg.r_bottom.size != 0:
|
|
self.axis_plot_profile_position_on_transect.plot(stg.t, -stg.r_bottom,
|
|
color='black', linewidth=1, linestyle="solid")
|
|
|
|
self.axis_plot_profile_position_on_transect.plot(
|
|
stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r,
|
|
color='red', linestyle="solid", linewidth=2)
|
|
|
|
self.axis_plot_profile_position_on_transect.set_xticks([])
|
|
self.axis_plot_profile_position_on_transect.set_yticks([])
|
|
|
|
self.figure_plot_profile_position_on_transect.canvas.draw_idle()
|
|
|
|
elif stg.BS_data_section_SNR_filter.size != 0:
|
|
|
|
self.axis_plot_profile_position_on_transect.cla()
|
|
|
|
val_min = np.nanmin(stg.BS_data_section_SNR_filter[:, self.combobox_frequency.currentIndex(), :])
|
|
val_max = np.nanmax(stg.BS_data_section_SNR_filter[:, self.combobox_frequency.currentIndex(), :])
|
|
if val_min == 0:
|
|
val_min = 1e-5
|
|
|
|
self.axis_plot_profile_position_on_transect.pcolormesh(
|
|
stg.t, -stg.r, stg.BS_data_section_SNR_filter[:, self.combobox_frequency.currentIndex(), :],
|
|
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
|
|
|
|
if stg.r_bottom.size != 0:
|
|
self.axis_plot_profile_position_on_transect.plot(stg.t, -stg.r_bottom,
|
|
color='black', linewidth=1, linestyle="solid")
|
|
|
|
self.axis_plot_profile_position_on_transect.plot(
|
|
stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r,
|
|
color='red', linestyle="solid", linewidth=2)
|
|
|
|
self.axis_plot_profile_position_on_transect.set_xticks([])
|
|
self.axis_plot_profile_position_on_transect.set_yticks([])
|
|
|
|
self.figure_plot_profile_position_on_transect.canvas.draw_idle()
|
|
|
|
# -------------------------------------------------- PLOT PROFILE -------------------------------------------------
|
|
|
|
def plot_profile(self):
|
|
|
|
# --- Raw profile ---
|
|
|
|
self.figure_profile, self.axis_profile \
|
|
= plt.subplots(nrows=1, ncols=stg.freq.shape[0], sharex=True, sharey=True, layout='constrained')
|
|
self.canvas_profile = FigureCanvas(self.figure_profile)
|
|
self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_profile)
|
|
# self.scroll_profile = QScrollArea()
|
|
# self.scroll_profile.setWidget(self.canvas_profile)
|
|
# self.scroll_profile.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
|
|
# self.scroll_profile.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
|
|
# self.scroll_profile.setAlignment(Qt.AlignCenter)
|
|
# self.verticalLayout_groupbox_plot_profile.addWidget(self.scroll_profile)
|
|
|
|
for f in range(stg.freq.shape[0]):
|
|
self.axis_profile[f].cla()
|
|
self.axis_profile[f].plot(stg.BS_data_section[:, f, self.slider.value() - 1], -stg.r,
|
|
linestyle='solid', color='k', linewidth=1)
|
|
self.axis_profile[f].text(.95, .05, stg.freq_text[f],
|
|
fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
fontstyle="normal", c="black", alpha=0.2,
|
|
horizontalalignment='right', verticalalignment='bottom',
|
|
transform=self.axis_profile[f].transAxes)
|
|
|
|
self.figure_profile.supxlabel("Acoustic Backscatter Signal (V)")
|
|
self.figure_profile.supylabel("Depth (m)")
|
|
|
|
# --- Raw averaged profile ---
|
|
|
|
self.figure_averaged_profile, self.axis_averaged_profile \
|
|
= plt.subplots(nrows=1, ncols=stg.freq.shape[0], sharex=True, sharey=True, layout='constrained')
|
|
self.canvas_averaged_profile = FigureCanvas(self.figure_averaged_profile)
|
|
self.verticalLayout_groupbox_plot_averaged_profile.addWidget(self.canvas_averaged_profile)
|
|
# self.scroll_averaged_profile = QScrollArea()
|
|
# self.scroll_averaged_profile.setWidget(self.canvas_averaged_profile)
|
|
# self.scroll_averaged_profile.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
|
|
# self.scroll_averaged_profile.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
|
# self.scroll_averaged_profile.setAlignment(Qt.AlignCenter)
|
|
# self.verticalLayout_groupbox_plot_averaged_profile.addWidget(self.scroll_averaged_profile)
|
|
|
|
# self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f],
|
|
# fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
# fontstyle="normal", c="black", alpha=0.2,
|
|
# horizontalalignment='right', verticalalignment='bottom',
|
|
# transform=self.axis_averaged_profile[f].transAxes)
|
|
|
|
# --- Raw FCB profile ---
|
|
|
|
self.figure_FCB_profile, self.axis_FCB_profile \
|
|
= plt.subplots(nrows=1, ncols=stg.freq.shape[0], sharex=True, sharey=True, layout='constrained')
|
|
self.canvas_FCB_profile = FigureCanvas(self.figure_FCB_profile)
|
|
self.verticalLayout_groupbox_plot_FCB_profile.addWidget(self.canvas_FCB_profile)
|
|
# self.scroll_FCB_profile = QScrollArea()
|
|
# self.scroll_FCB_profile.setWidget(self.canvas_FCB_profile)
|
|
# self.scroll_FCB_profile.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
|
|
# self.scroll_FCB_profile.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
|
# self.scroll_FCB_profile.setAlignment(Qt.AlignCenter)
|
|
# self.verticalLayout_groupbox_plot_FCB_profile.addWidget(self.scroll_FCB_profile)
|
|
|
|
# self.axis_FCB_profile[f].text(.95, .05, stg.freq_text[f],
|
|
# fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
# fontstyle="normal", c="black", alpha=0.2,
|
|
# horizontalalignment='right', verticalalignment='bottom',
|
|
# transform=self.axis_FCB_profile[f].transAxes)
|
|
|
|
def update_plot_profile(self):
|
|
if self.canvas_profile is None:
|
|
msgBox = QMessageBox()
|
|
msgBox.setWindowTitle("Plot Error")
|
|
msgBox.setIcon(QMessageBox.Warning)
|
|
msgBox.setText("Load and post-process data before plotting profiles")
|
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
msgBox.exec()
|
|
|
|
else:
|
|
for f in range(stg.freq.shape[0]):
|
|
self.axis_profile[f].cla()
|
|
self.axis_profile[f].plot(stg.BS_data_section[:, f, self.slider.value() - 1], -stg.r,
|
|
linestyle='solid', color='k', linewidth=1)
|
|
self.axis_profile[f].text(.95, .05, stg.freq_text[f],
|
|
fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
fontstyle="normal", c="black", alpha=0.2,
|
|
horizontalalignment='right', verticalalignment='bottom',
|
|
transform=self.axis_profile[f].transAxes)
|
|
|
|
self.figure_profile.supxlabel("Acoustic Backscatter Signal (V)")
|
|
self.figure_profile.supylabel("Depth (m)")
|
|
self.figure_profile.canvas.draw_idle()
|
|
|
|
# --------------------------------- PLOT AVERAGED PROFILE FILTERED OR NOT WITH SNR ---------------------------------
|
|
|
|
def plot_averaged_profile(self):
|
|
|
|
for f in range(stg.freq.shape[0]):
|
|
self.axis_averaged_profile[f].cla()
|
|
self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[:, f, self.slider.value()-1], -stg.r,
|
|
linestyle='solid', color='k', linewidth=1)
|
|
self.axis_averaged_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
|
|
self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f],
|
|
fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
fontstyle="normal", c="black", alpha=0.2,
|
|
horizontalalignment='right', verticalalignment='bottom',
|
|
transform=self.axis_averaged_profile[f].transAxes)
|
|
|
|
self.figure_averaged_profile.supxlabel("Acoustic Backscatter Signal (V)")
|
|
self.figure_averaged_profile.supylabel("Depth (m)")
|
|
self.figure_averaged_profile.canvas.draw_idle()
|
|
|
|
def update_plot_averaged_profile(self):
|
|
if self.canvas_averaged_profile is None:
|
|
msgBox = QMessageBox()
|
|
msgBox.setWindowTitle("Plot Error")
|
|
msgBox.setIcon(QMessageBox.Warning)
|
|
msgBox.setText("Load and post-process data before plotting averaged profiles")
|
|
msgBox.setStandardButtons(QMessageBox.Ok)
|
|
msgBox.exec()
|
|
|
|
elif (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0):
|
|
pass
|
|
|
|
else:
|
|
if stg.BS_data_section_SNR_filter.size == 0:
|
|
|
|
for f in range(stg.freq.shape[0]):
|
|
self.axis_averaged_profile[f].cla()
|
|
self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[:, f, self.slider.value() - 1], -stg.r,
|
|
linestyle='solid', color='k', linewidth=1)
|
|
self.axis_averaged_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
|
|
self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f],
|
|
fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
fontstyle="normal", c="black", alpha=0.2,
|
|
horizontalalignment='right', verticalalignment='bottom',
|
|
transform=self.axis_averaged_profile[f].transAxes)
|
|
|
|
self.figure_averaged_profile.supxlabel("Acoustic Backscatter Signal (V)")
|
|
self.figure_averaged_profile.supylabel("Depth (m)")
|
|
self.figure_averaged_profile.canvas.draw_idle()
|
|
|
|
elif stg.BS_data_section_SNR_filter.size != 0:
|
|
|
|
for f in range(stg.freq.shape[0]):
|
|
self.axis_averaged_profile[f].cla()
|
|
self.axis_averaged_profile[f].plot(stg.BS_data_section_SNR_filter[:, f, self.slider.value() - 1], -stg.r,
|
|
linestyle='solid', color='k', linewidth=1)
|
|
self.axis_averaged_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
|
|
self.axis_averaged_profile[f].text(.95, .05, stg.freq_text[f],
|
|
fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
fontstyle="normal", c="black", alpha=0.2,
|
|
horizontalalignment='right', verticalalignment='bottom',
|
|
transform=self.axis_averaged_profile[f].transAxes)
|
|
|
|
self.figure_averaged_profile.supxlabel("Acoustic Backscatter Signal (V)")
|
|
self.figure_averaged_profile.supylabel("Depth (m)")
|
|
self.figure_averaged_profile.canvas.draw_idle()
|
|
|
|
# ---------------------------------------------------- PLOT FCB ----------------------------------------------------
|
|
|
|
def plot_FCB(self):
|
|
|
|
for f in range(stg.freq.shape[0]):
|
|
|
|
self.axis_FCB_profile[f].cla()
|
|
|
|
self.axis_FCB_profile[f].plot(stg.r, stg.FCB[:, f, self.slider.value()], linestyle="solid", linewidth=1, color="k")
|
|
|
|
# self.axis_FCB_profile[f].set_ylim(np.max(stg.r), np.min(stg.r))
|
|
self.axis_FCB_profile[f].text(.95, .05, stg.freq_text[f],
|
|
fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
fontstyle="normal", c="black", alpha=0.2,
|
|
horizontalalignment='right', verticalalignment='bottom',
|
|
transform=self.axis_FCB_profile[f].transAxes)
|
|
|
|
if len(stg.lin_reg) != 0:
|
|
self.axis_FCB_profile[self.combobox_frequency_compute_alphaS.currentIndex()]. \
|
|
plot(stg.r, stg.lin_reg[0]*stg.r + stg.lin_reg[1], linestyle="dashed", linewidth=1, color="b")
|
|
|
|
self.figure_FCB_profile.supylabel("FCB")
|
|
self.figure_FCB_profile.supxlabel("Depth (m)")
|
|
self.figure_FCB_profile.canvas.draw_idle()
|
|
|
|
def update_plot_FCB(self):
|
|
|
|
for f in range(stg.freq.shape[0]):
|
|
|
|
self.axis_FCB_profile[f].cla()
|
|
|
|
self.axis_FCB_profile[f].plot(stg.r, stg.FCB[:, f, self.slider.value()], linestyle="solid", linewidth=1, color="k")
|
|
|
|
# self.axis_FCB_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
|
|
|
|
self.axis_FCB_profile[f].text(.95, .05, stg.freq_text[f],
|
|
fontsize=10, fontweight='bold', fontname="Ubuntu",
|
|
fontstyle="normal", c="black", alpha=0.2,
|
|
horizontalalignment='right', verticalalignment='bottom',
|
|
transform=self.axis_FCB_profile[f].transAxes)
|
|
|
|
self.figure_FCB_profile.supylabel("FCB")
|
|
self.figure_FCB_profile.supxlabel("Depth (m)")
|
|
self.figure_FCB_profile.canvas.draw_idle()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|