FCB computatuion and display are added on sediment calibration tab. By default, the position of the FCB vertical profile is set on the profile position of calibration samples. The user can choose the depth limits to fit the FCB profile with linear regression. The FCB profile is diplay on acoustic recording 2D field.

dev-brahim
brahim 2024-08-26 11:19:25 +02:00
parent 66f62765a1
commit 44d9c057aa
3 changed files with 603 additions and 13 deletions

View File

@ -2226,6 +2226,10 @@ class AcousticDataTab(QWidget):
stg.BS_stream_bed_pre_process_average.append(np.array([])) stg.BS_stream_bed_pre_process_average.append(np.array([]))
stg.BS_stream_bed_pre_process_SNR_average.append(np.array([])) stg.BS_stream_bed_pre_process_SNR_average.append(np.array([]))
stg.FCB.append([])
stg.depth_real.append([])
stg.lin_reg.append(tuple())
stg.frequencies_for_calibration.append([]) stg.frequencies_for_calibration.append([])
stg.frequency_for_inversion.append([]) stg.frequency_for_inversion.append([])

View File

@ -6,7 +6,7 @@ from PyQt5.QtWidgets import (QWidget, QMainWindow, QApplication, QVBoxLayout, QH
QSizePolicy, QSlider, QLineEdit, QDial) QSizePolicy, QSlider, QLineEdit, QDial)
from PyQt5.QtCore import QCoreApplication, Qt from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import QStandardItemModel, QIcon, QPixmap from PyQt5.QtGui import QStandardItemModel, QIcon, QPixmap, QFont
import settings as stg import settings as stg
@ -16,9 +16,12 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
from matplotlib.colors import LogNorm from matplotlib.colors import LogNorm
from scipy.stats import linregress
from View.checkable_combobox import CheckableComboBox from View.checkable_combobox import CheckableComboBox
from Model.acoustic_inversion_method_high_concentration import AcousticInversionMethodHighConcentration from Model.acoustic_inversion_method_high_concentration import AcousticInversionMethodHighConcentration
from settings import depth_cross_section
class SedimentCalibrationTab(QWidget): class SedimentCalibrationTab(QWidget):
@ -29,7 +32,12 @@ class SedimentCalibrationTab(QWidget):
super().__init__() super().__init__()
self.path_icon = "./icons/" self.path_icon = "./icons/"
self.icon_update = self.path_icon + "update.png" self.icon_folder = QIcon(self.path_icon + "folder.png")
self.icon_triangle_left = QIcon(self.path_icon + "triangle_left.png")
self.icon_triangle_left_to_begin = QIcon(self.path_icon + "triangle_left_to_begin.png")
self.icon_triangle_right = QIcon(self.path_icon + "triangle_right.png")
self.icon_triangle_right_to_end = QIcon(self.path_icon + "triangle_right_to_end.png")
self.icon_update = QIcon(self.path_icon + "update.png")
self.inv_hc = AcousticInversionMethodHighConcentration() self.inv_hc = AcousticInversionMethodHighConcentration()
@ -65,7 +73,7 @@ class SedimentCalibrationTab(QWidget):
self.verticalLayout_groupbox_acoustic_data.addLayout(self.gridLayout_data_choice) self.verticalLayout_groupbox_acoustic_data.addLayout(self.gridLayout_data_choice)
self.pushbutton_update_acoustic_file = QPushButton() self.pushbutton_update_acoustic_file = QPushButton()
self.pushbutton_update_acoustic_file.setIcon(QIcon(self.icon_update)) self.pushbutton_update_acoustic_file.setIcon(self.icon_update)
# self.horizontalLayout_acoustic_data_choice.addWidget(self.pushbutton_update_acoustic_file) # self.horizontalLayout_acoustic_data_choice.addWidget(self.pushbutton_update_acoustic_file)
self.gridLayout_data_choice.addWidget(self.pushbutton_update_acoustic_file, 0, 0, 2, 1) self.gridLayout_data_choice.addWidget(self.pushbutton_update_acoustic_file, 0, 0, 2, 1)
@ -128,25 +136,102 @@ class SedimentCalibrationTab(QWidget):
self.verticalLayout_groupbox_Mfine_profile.addWidget(self.canvas_Mfine) self.verticalLayout_groupbox_Mfine_profile.addWidget(self.canvas_Mfine)
# -------------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------------
self.groupbox_sediment_calibration = QGroupBox()
self.horizontalLayoutBottom.addWidget(self.groupbox_sediment_calibration, 5)
self.groupbox_FCB = QGroupBox() self.groupbox_FCB = QGroupBox()
self.horizontalLayoutBottom.addWidget(self.groupbox_FCB, 6) self.horizontalLayoutBottom.addWidget(self.groupbox_FCB, 5)
self.groupbox_sediment_calibration = QGroupBox()
self.horizontalLayoutBottom.addWidget(self.groupbox_sediment_calibration, 4)
# ++++++++++++++++++++ # ++++++++++++++++++++
# +++ Groupbox FCB +++ # +++ Groupbox FCB +++
self.groupbox_FCB.setTitle("Step 3 : Fluid Corrected Backscatter") self.groupbox_FCB.setTitle("Step 3 (optional) : Fluid Corrected Backscatter")
self.horizontalLayout_groupbox_FCB = QHBoxLayout(self.groupbox_FCB)
self.verticalLayout_groupbox_FCB = QVBoxLayout(self.groupbox_FCB) # --- Groupbox FCB option ---
self.groupbox_FCB_option = QGroupBox()
self.gridLayout_groupbox_FCB_option = QGridLayout(self.groupbox_FCB_option)
self.horizontalLayout_groupbox_FCB.addWidget(self.groupbox_FCB_option, 3)
self.label_temperature = QLabel()
self.label_temperature.setText("Temperature : ")
self.label_frequency_FCB = QLabel()
self.label_frequency_FCB.setText("Frequency ")
self.gridLayout_groupbox_FCB_option.addWidget(self.label_frequency_FCB, 0, 0, 1, 2)
self.combobox_frequency_FCB = QComboBox()
self.gridLayout_groupbox_FCB_option.addWidget(self.combobox_frequency_FCB, 0, 2, 1, 2)
self.label_from = QLabel()
self.label_from.setText("From ")
self.gridLayout_groupbox_FCB_option.addWidget(self.label_from, 1, 0, 1, 1)
self.spinbox_FCB_from = QDoubleSpinBox()
self.gridLayout_groupbox_FCB_option.addWidget(self.spinbox_FCB_from, 1, 1, 1, 1)
self.label_to = QLabel()
self.label_to.setText(" to ")
self.gridLayout_groupbox_FCB_option.addWidget(self.label_to, 1, 2, 1, 1)
self.spinbox_FCB_to = QDoubleSpinBox()
self.gridLayout_groupbox_FCB_option.addWidget(self.spinbox_FCB_to, 1, 3, 1, 1)
self.pushbutton_FCB_fit = QPushButton()
self.gridLayout_groupbox_FCB_option.addWidget(self.pushbutton_FCB_fit, 2, 1, 1, 2)
self.label_alphaS_FCB = QLabel()
self.label_alphaS_FCB.setText("\u03B1s = " + "0.0" + "dB/m")
self.label_alphaS_FCB.setFont(QFont("Ubuntu", 14, QFont.Normal))
self.gridLayout_groupbox_FCB_option.addWidget(self.label_alphaS_FCB, 3, 1, 1, 2)
# --- Groupbox FCB plot ---
self.verticalLayout_groupbox_FCB_plot_and_slider_FCB = QVBoxLayout()
self.horizontalLayout_groupbox_FCB.addLayout(self.verticalLayout_groupbox_FCB_plot_and_slider_FCB, 7)
self.groupbox_FCB_plot = QGroupBox()
self.verticalLayout_groupbox_FCB_plot = QVBoxLayout(self.groupbox_FCB_plot)
self.verticalLayout_groupbox_FCB_plot_and_slider_FCB.addWidget(self.groupbox_FCB_plot)
self.canvas_FCB = FigureCanvas() self.canvas_FCB = FigureCanvas()
self.toolbar_FCB = NavigationToolBar(self.canvas_FCB, self) self.toolbar_FCB = NavigationToolBar(self.canvas_FCB, self)
self.verticalLayout_groupbox_FCB.addWidget(self.toolbar_FCB) self.verticalLayout_groupbox_FCB_plot.addWidget(self.toolbar_FCB)
self.verticalLayout_groupbox_FCB.addWidget(self.canvas_FCB) self.verticalLayout_groupbox_FCB_plot.addWidget(self.canvas_FCB)
self.horizontalLayout_slider_FCB = QHBoxLayout()
self.verticalLayout_groupbox_FCB_plot_and_slider_FCB.addLayout(self.horizontalLayout_slider_FCB)
self.pushbutton_left_to_begin_FCB = QPushButton()
self.pushbutton_left_to_begin_FCB.setIcon(self.icon_triangle_left_to_begin)
self.horizontalLayout_slider_FCB.addWidget(self.pushbutton_left_to_begin_FCB)
self.pushbutton_left_FCB = QPushButton()
self.pushbutton_left_FCB.setIcon(self.icon_triangle_left)
self.horizontalLayout_slider_FCB.addWidget(self.pushbutton_left_FCB)
self.lineEdit_slider_FCB = QLineEdit()
self.lineEdit_slider_FCB.setText("1")
self.lineEdit_slider_FCB.setFixedWidth(50)
self.horizontalLayout_slider_FCB.addWidget(self.lineEdit_slider_FCB)
self.pushbutton_right_FCB = QPushButton()
self.pushbutton_right_FCB.setIcon(self.icon_triangle_right)
self.horizontalLayout_slider_FCB.addWidget(self.pushbutton_right_FCB)
self.pushbutton_right_to_end_FCB = QPushButton()
self.pushbutton_right_to_end_FCB.setIcon(self.icon_triangle_right_to_end)
self.horizontalLayout_slider_FCB.addWidget(self.pushbutton_right_to_end_FCB)
self.slider_FCB = QSlider()
self.horizontalLayout_slider_FCB.addWidget(self.slider_FCB)
self.slider_FCB.setOrientation(Qt.Horizontal)
self.slider_FCB.setCursor(Qt.OpenHandCursor)
self.slider_FCB.setMinimum(1)
self.slider_FCB.setMaximum(10)
self.slider_FCB.setTickInterval(1)
self.slider_FCB.setValue(1)
# +++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++
# +++ Groupbox sediment calibration +++ # +++ Groupbox sediment calibration +++
@ -241,6 +326,15 @@ class SedimentCalibrationTab(QWidget):
self.pushbutton_compute_calibration.clicked.connect(self.function_pushbutton_compute_calibration) self.pushbutton_compute_calibration.clicked.connect(self.function_pushbutton_compute_calibration)
self.pushbutton_left_to_begin_FCB.clicked.connect(self.slider_profile_number_to_begin_FCB)
self.pushbutton_left_FCB.clicked.connect(self.slider_profile_number_to_left_FCB)
self.pushbutton_right_FCB.clicked.connect(self.slider_profile_number_to_right_FCB)
self.pushbutton_right_to_end_FCB.clicked.connect(self.slider_profile_number_to_end_FCB)
self.lineEdit_slider_FCB.returnPressed.connect(self.profile_number_on_lineEdit_FCB)
self.slider_FCB.valueChanged.connect(self.update_lineEdit_by_moving_slider_FCB)
self.pushbutton_FCB_fit.clicked.connect(self.fit_FCB_profile_with_linear_regression_and_compute_alphaS)
# ============================================================================================================== # ==============================================================================================================
# ----------------------------------- Functions for Signal processing Tab -------------------------------------- # ----------------------------------- Functions for Signal processing Tab --------------------------------------
# ============================================================================================================== # ==============================================================================================================
@ -252,6 +346,7 @@ class SedimentCalibrationTab(QWidget):
self.sample_choice_for_calibration() self.sample_choice_for_calibration()
self.plot_acoustic_recording() self.plot_acoustic_recording()
self.plot_profile_of_concentration_fine() self.plot_profile_of_concentration_fine()
self.compute_FCB()
def update_acoustic_data(self): def update_acoustic_data(self):
@ -354,6 +449,7 @@ class SedimentCalibrationTab(QWidget):
:], :],
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
# --- Plot samples ---
print("stg.fine_sample_profile ", stg.fine_sample_profile) print("stg.fine_sample_profile ", stg.fine_sample_profile)
print("stg.sand_sample_target ", stg.sand_sample_target) print("stg.sand_sample_target ", stg.sand_sample_target)
@ -387,6 +483,57 @@ class SedimentCalibrationTab(QWidget):
self.axis_BS.text(stg.time_sand[j[1]] - 12, stg.depth_sand[j[1]] - .2, j[0], self.axis_BS.text(stg.time_sand[j[1]] - 12, stg.depth_sand[j[1]] - .2, j[0],
fontstyle="normal", fontweight="light", fontsize=8) fontstyle="normal", fontweight="light", fontsize=8)
# --- Plot vertical red line for position of FCB profile ---
if stg.sand_sample_target_indice:
if depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.red_line_plot_return, = (
self.axis_BS.plot(
stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[0][1]] *
np.ones(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
-stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), :],
color='red', linestyle="solid", linewidth=2))
else:
self.red_line_plot_return, = (
self.axis_BS.plot(
stg.time[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[0][1]] *
np.ones(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
-stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), :],
color='red', linestyle="solid", linewidth=2))
else:
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.red_line_plot_return, = (
self.axis_BS.plot(
stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[0][1]] *
np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
-stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), :],
color='red', linestyle="solid", linewidth=2))
else:
self.red_line_plot_return, = (
self.axis_BS.plot(
stg.time[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[0][1]] *
np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
-stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), :],
color='red', linestyle="solid", linewidth=2))
# self.axis_BS.set_xticks([]) # self.axis_BS.set_xticks([])
# self.axis_BS.set_yticks([]) # self.axis_BS.set_yticks([])
self.axis_BS.set_xlabel("Time (sec)") self.axis_BS.set_xlabel("Time (sec)")
@ -915,5 +1062,443 @@ class SedimentCalibrationTab(QWidget):
self.spinbox_zeta_freq2.clear() self.spinbox_zeta_freq2.clear()
self.spinbox_zeta_freq2.setValue(zeta_freq2) self.spinbox_zeta_freq2.setValue(zeta_freq2)
# --- Compute FCB ---
# ------------ Computing real cell size ------------ #
def range_cells_function(self):
""" Computing the real cell size, that depends on the temperature """
if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
aquascat_cell_size = []
tau = []
real_cell_size = []
stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()] = (
np.zeros(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape))
for f in range(stg.freq[self.combobox_acoustic_data_choice.currentIndex()].shape[0]):
print("f = ", f)
# defaut Aquascat cell size
aquascat_cell_size.append(
stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, 1] -
stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, 0])
# Pulse duration
tau.append(aquascat_cell_size[f] * 2 / 1500) # figure 2.9 1500 vitesse du son entrée pour le paramètrage des mesures aquascat
print(stg.water_velocity[self.combobox_acoustic_data_choice.currentIndex()])
print(tau)
# Real cell size
real_cell_size.append(stg.water_velocity[self.combobox_acoustic_data_choice.currentIndex()] * tau[f] / 2) # voir fig 2.9
# Converting to real cell profile
stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()][f, :] = \
(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, :] /
aquascat_cell_size[f] * real_cell_size[f]) # (/ aquascat_cell_size) pour ramener BS.r entre 0 et 1
print("stg.depth_real ", stg.depth_real)
# (* real_cell_size) pour remettre les échelles spatiales sur la taille réelle des cellules
else:
aquascat_cell_size = []
tau = []
real_cell_size = []
stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()] = (
np.zeros(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape))
for f in range(stg.freq[self.combobox_acoustic_data_choice.currentIndex()].shape[0]):
# defaut Aquascat cell size
aquascat_cell_size.append(
stg.depth[self.combobox_acoustic_data_choice.currentIndex()][f, 1] -
stg.depth[self.combobox_acoustic_data_choice.currentIndex()][f, 0])
# Pulse duration
tau.append(aquascat_cell_size[f] * 2 / 1500) # figure 2.9 1500 vitesse du son entrée pour le paramètrage des mesures aquascat
# Real cell size
real_cell_size.append(stg.water_velocity[self.combobox_acoustic_data_choice.currentIndex()] * tau[f] / 2) # voir fig 2.9
# Converting to real cell profile
stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()][f, :] = \
(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, :] /
aquascat_cell_size[f] * real_cell_size[f]) # (/ 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
print("R_real 2D ", stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()].shape)
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()] = (
np.repeat(stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()][:, :, np.newaxis],
stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], axis=2))
print("R_real 3D ", stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()].shape)
def compute_FCB(self):
# if stg.BS_stream_bed.size == 0:
# msgBox = QMessageBox()
# msgBox.setWindowTitle("FCB Error")
# msgBox.setIcon(QMessageBox.Warning)
# msgBox.setText("Load Backscatter data from acoustic data tab and compute water attenuation")
# msgBox.setStandardButtons(QMessageBox.Ok)
# msgBox.exec()
# else:
# R_real = np.repeat(self.range_cells_function()[:, :, np.newaxis], stg.t.shape[1], axis=2)
# if (stg.BS_stream_bed_pre_process_average.size == 0) and (stg.BS_stream_bed_pre_process_SNR.size == 0):
# stg.FCB = (np.log(stg.BS_stream_bed) + np.log(R_real) +
# 2 * stg.water_attenuation * R_real)
# elif stg.BS_stream_bed_pre_process_SNR.size == 0:
# stg.FCB = (np.log(stg.BS_stream_bed_pre_process_average) + np.log(R_real) +
# 2 * stg.water_attenuation * R_real)
# else:
# stg.FCB = (np.log(stg.BS_stream_bed_pre_process_SNR) + np.log(R_real) +
# 2 * stg.water_attenuation * R_real)
self.combobox_frequency_FCB.clear()
self.combobox_frequency_FCB.addItems(stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()])
self.range_cells_function()
if stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
print("zzzzzzzzzzzzzzzzzzzzz")
print(np.log(stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()]).shape)
print(np.log(stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()]).shape)
print(stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()])
print(stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()].shape)
print("zzzzzzzzzzzzzzzzzzzzz")
stg.FCB[self.combobox_acoustic_data_choice.currentIndex()] = \
(np.log(stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()]) +
np.log(stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()]) +
2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_frequency_FCB.currentIndex()] *
stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()])
elif stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
stg.FCB[self.combobox_acoustic_data_choice.currentIndex()] = \
(np.log(stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()]) +
np.log(stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()]) +
2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()] *
stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()])
else:
stg.FCB[self.combobox_acoustic_data_choice.currentIndex()] = \
(np.log(stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()]) +
np.log(stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()]) +
2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()] *
stg.depth_real[self.combobox_acoustic_data_choice.currentIndex()])
print("FCB ", stg.FCB[self.combobox_acoustic_data_choice.currentIndex()].shape)
self.plot_FCB()
def plot_FCB(self):
if stg.FCB[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.slider_FCB.setMaximum(stg.time_cross_section[
self.combobox_acoustic_data_choice.currentIndex()].shape[1])
else:
self.slider_FCB.setMaximum(stg.time[self.combobox_acoustic_data_choice.currentIndex()].shape[1])
self.slider_FCB.setValue(stg.sand_sample_target_indice[0][1])
self.verticalLayout_groupbox_FCB_plot.removeWidget(self.canvas_FCB)
self.verticalLayout_groupbox_FCB_plot.removeWidget(self.toolbar_FCB)
self.fig_FCB, self.axis_FCB = plt.subplots(nrows=1, ncols=1, layout="constrained")
self.canvas_FCB = FigureCanvas(self.fig_FCB)
self.toolbar_FCB = NavigationToolBar(self.canvas_FCB, self)
self.verticalLayout_groupbox_FCB_plot.addWidget(self.toolbar_FCB)
self.verticalLayout_groupbox_FCB_plot.addWidget(self.canvas_FCB)
if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.axis_FCB.plot(
stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex()],
stg.FCB[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1],
linestyle="solid", linewidth=1, color="k")
else:
self.axis_FCB.plot(
stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex()],
stg.FCB[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1],
linestyle="solid", linewidth=1, color="k")
self.axis_FCB.text(.95, .05,
stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex()],
fontsize=10, fontweight='bold', fontname="Ubuntu",
fontstyle="normal", c="black", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_FCB.transAxes)
# if len(stg.lin_reg) != 0:
# self.axis_FCB_profile[self.combobox_frequency_compute_alphaS.currentIndex()]. \
# plot(stg.r[f, :], stg.lin_reg[0]*stg.r[f, :] + stg.lin_reg[1], linestyle="dashed", linewidth=1, color="b")
self.fig_FCB.supxlabel("Depth (m)")
self.fig_FCB.supylabel("FCB")
self.fig_FCB.canvas.draw_idle()
self.slider_FCB.valueChanged.connect(self.update_plot_FCB)
self.combobox_frequency_FCB.currentIndexChanged.connect(self.update_plot_FCB)
def update_plot_FCB(self):
if stg.FCB[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.axis_FCB.cla()
if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.axis_FCB.plot(
stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex()],
stg.FCB[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1],
linestyle="solid", linewidth=1, color="k")
else:
self.axis_FCB.plot(
stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex()],
stg.FCB[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1],
linestyle="solid", linewidth=1, color="k")
self.axis_FCB.text(.95, .05,
stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex()],
fontsize=10, fontweight='bold', fontname="Ubuntu",
fontstyle="normal", c="black", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_FCB.transAxes)
self.fig_FCB.canvas.draw_idle()
# --- Update red line on acoustic record plot ---
if stg.sand_sample_target_indice:
if depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.red_line_plot_return.set_data(
stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), self.slider_FCB.value() -1] *
np.ones(
stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[
1]),
-stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), :])
else:
self.red_line_plot_return.set_data(
stg.time[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), self.slider_FCB.value() -1] *
np.ones(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[
1]),
-stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), :])
else:
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.red_line_plot_return.set_data(
stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), self.slider_FCB.value() -1] *
np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
-stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), :])
else:
self.red_line_plot_return.set_data(
stg.time[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), self.slider_FCB.value() -1] *
np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
-stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_freq2.currentIndex(), :])
self.fig_BS.canvas.draw_idle()
def fit_FCB_profile_with_linear_regression_and_compute_alphaS(self):
self.update_plot_FCB()
if stg.FCB[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
# --- Identify FCB profile where value are not NaN ---
y0 = stg.FCB[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1]
y = y0[np.where(np.isnan(y0) == False)]
if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
# --- Select depth corresponding to the FCB profile where value are not NaN ---
x0 = stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), :]
x = x0[np.where(np.isnan(y0) == False)]
# --- Find the indices of the values between which the linear regression is fitted ---
value1 = np.where(np.round(np.abs(x - self.spinbox_FCB_from.value()), 2) ==
np.min(np.round(np.abs(x - self.spinbox_FCB_from.value()), 2)))[0][0]
value2 = np.where(np.round(np.abs(x - self.spinbox_FCB_to.value()), 2) ==
np.min(np.round(np.abs(x - self.spinbox_FCB_to.value()), 2)))[0][0]
print("value1 ", value1)
print("value2 ", value2)
lin_reg_compute = linregress(x[value1:value2], y[value1:value2])
print("lin_reg_compute ", lin_reg_compute)
stg.lin_reg[self.combobox_acoustic_data_choice.currentIndex()] = (lin_reg_compute.slope, lin_reg_compute.intercept)
print("stg.lin_reg ", stg.lin_reg)
# --- Plot result of linear regression ---
self.axis_FCB.plot(
stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), value1:value2],
stg.lin_reg[self.combobox_acoustic_data_choice.currentIndex()][0] *
stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), value1:value2] +
stg.lin_reg[self.combobox_acoustic_data_choice.currentIndex()][1],
linestyle="dashed", linewidth=1, color="b")
else:
# --- Select depth corresponding to the FCB profile where value are not NaN ---
x0 = stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), :]
x = x0[np.where(np.isnan(y0) == False)]
# --- Find the indices of the values between which the linear regression is fitted ---
value1 = np.where(np.round(np.abs(x - self.spinbox_FCB_from.value()), 2) ==
np.min(np.round(np.abs(x - self.spinbox_FCB_from.value()), 2)))[0][0]
value2 = np.where(np.round(np.abs(x - self.spinbox_FCB_to.value()), 2) ==
np.min(np.round(np.abs(x - self.spinbox_FCB_to.value()), 2)))[0][0]
print("value1 ", value1)
print("value2 ", value2)
lin_reg_compute = linregress(x[value1:value2], y[value1:value2])
print("lin_reg_compute ", lin_reg_compute)
stg.lin_reg[self.combobox_acoustic_data_choice.currentIndex()] = (
lin_reg_compute.slope, lin_reg_compute.intercept)
# --- Plot result of linear regression ---
self.axis_FCB.plot(
stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), value1:value2],
stg.lin_reg[self.combobox_acoustic_data_choice.currentIndex()][0] *
stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_FCB.currentIndex(), value1:value2] +
stg.lin_reg[self.combobox_acoustic_data_choice.currentIndex()][1],
linestyle="dashed", linewidth=1, color="b")
self.fig_FCB.canvas.draw_idle()
# --- Display the value of alphaS compute with FCB ---
self.label_alphaS_FCB.clear()
self.label_alphaS_FCB.setText(f"\u03B1s = {-0.5*stg.lin_reg[self.combobox_acoustic_data_choice.currentIndex()][0]:.4f} dB/m")
# if stg.FCB.size == 0:
# msgBox = QMessageBox()
# msgBox.setWindowTitle("Linear regression error")
# msgBox.setIcon(QMessageBox.Warning)
# msgBox.setText("Please compute FCB before")
# msgBox.setStandardButtons(QMessageBox.Ok)
# msgBox.exec()
# else:
# try:
# y0 = stg.FCB[self.combobox_frequency_compute_alphaS.currentIndex(), :, self.slider.value()]
# y = y0[np.where(np.isnan(y0) == False)]
#
# x0 = stg.r[0, :].reshape(-1)
# x = x0[np.where(np.isnan(y0) == False)]
#
# value1 = np.where(np.round(np.abs(x - self.spinbox_alphaS_computation_from.value()), 2)
# == 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]])
#
# lin_reg_compute = stats.linregress(x[value1[0][0]:value2[0][0]], y[value1[0][0]:value2[0][0]])
# except ValueError:
# msgBox = QMessageBox()
# msgBox.setWindowTitle("Linear regression error")
# msgBox.setIcon(QMessageBox.Warning)
# msgBox.setText("Please check boundaries to fit a linear line")
# msgBox.setStandardButtons(QMessageBox.Ok)
# msgBox.exec()
# else:
# 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)
def slider_profile_number_to_begin_FCB(self):
self.slider_FCB.setValue(int(self.slider_FCB.minimum()))
self.lineEdit_slider_FCB.setText(str(self.slider_FCB.value()))
def slider_profile_number_to_right_FCB(self):
self.slider_FCB.setValue(int(self.slider_FCB.value()) + 1)
self.lineEdit_slider_FCB.setText(str(self.slider_FCB.value()))
def slider_profile_number_to_left_FCB(self):
self.slider_FCB.setValue(int(self.slider_FCB.value()) - 1)
self.lineEdit_slider_FCB.setText(str(self.slider_FCB.value()))
def slider_profile_number_to_end_FCB(self):
self.slider_FCB.setValue(int(self.slider_FCB.maximum()))
self.lineEdit_slider_FCB.setText(str(self.slider_FCB.value()))
def profile_number_on_lineEdit_FCB(self):
self.slider_FCB.setValue(int(self.lineEdit_slider_FCB.text()))
def update_lineEdit_by_moving_slider_FCB(self):
self.lineEdit_slider_FCB.setText(str(self.slider_FCB.value()))

View File

@ -103,8 +103,9 @@ SNR_data_average = np.array([]) # SNR data computed with BS signal a
sediment_attenuation = [] sediment_attenuation = []
FCB = np.array([]) FCB = []
lin_reg = tuple() depth_real = []
lin_reg = []
# --- Sample Data --- # --- Sample Data ---