Computation of FCB and sediments attenuation are computed. FCB profile is plotted for each frequencies. Linear regression is added and can be plotted on FCB profile.

dev-brahim
brahim 2023-09-20 10:12:06 +02:00
parent 420896ca42
commit e8438ec46b
5 changed files with 406 additions and 166 deletions

View File

@ -338,8 +338,8 @@ class AcousticDataTab(QWidget):
self.spinbox_tmin = QDoubleSpinBox() self.spinbox_tmin = QDoubleSpinBox()
self.spinbox_tmin.setRange(0, 9999) self.spinbox_tmin.setRange(0, 9999)
self.gridLayout_groupbox_xaxis_time.addWidget(self.spinbox_tmin, 0, 2, 1, 1) 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_BS_raw_data)
self.spinbox_tmin.valueChanged.connect(self.update_xaxis_transect_with_SNR_data) # self.spinbox_tmin.valueChanged.connect(self.update_xaxis_transect_with_SNR_data)
self.label_tmin_unit = QLabel() self.label_tmin_unit = QLabel()
self.label_tmin_unit.setText("sec") self.label_tmin_unit.setText("sec")
@ -692,27 +692,46 @@ class AcousticDataTab(QWidget):
# --- fill date, hour and measurements information + fill frequency combobox for bottom detection --- # --- fill date, hour and measurements information + fill frequency combobox for bottom detection ---
if self.combobox_ABS_system_choice.currentIndex() != 0: if self.combobox_ABS_system_choice.currentIndex() != 0:
if self.sender().objectName() == "pushbutton_acoustic_file": if self.sender().objectName() == "pushbutton_acoustic_file":
stg.path_BS_raw_data = dir_name try:
stg.filename_BS_raw_data = name stg.path_BS_raw_data = dir_name
self.load_BS_acoustic_raw_data() stg.filename_BS_raw_data = name
self.lineEdit_acoustic_file.setText(stg.filename_BS_raw_data) self.load_BS_acoustic_raw_data()
self.lineEdit_acoustic_file.setToolTip(stg.path_BS_raw_data) except ValueError as e:
self.label_date_groupbox_acoustic_file.setText( msgBox = QMessageBox()
_translate("CONSTANT_STRING", cs.DATE) + ": " + str(stg.date)) msgBox.setWindowTitle("Download Error")
self.label_hour_groupbox_acoustic_file.setText( msgBox.setIcon(QMessageBox.Warning)
_translate("CONSTANT_STRING", cs.HOUR) + ": " + str(stg.hour)) msgBox.setText("Please select a file")
self.fill_measurements_information_groupbox() msgBox.setStandardButtons(QMessageBox.Ok)
self.combobox_freq_choice.addItems([f for f in stg.freq_text]) msgBox.exec()
else:
self.lineEdit_acoustic_file.setText(stg.filename_BS_raw_data)
self.lineEdit_acoustic_file.setToolTip(stg.path_BS_raw_data)
self.label_date_groupbox_acoustic_file.setText(
_translate("CONSTANT_STRING", cs.DATE) + ": " + str(stg.date))
self.label_hour_groupbox_acoustic_file.setText(
_translate("CONSTANT_STRING", cs.HOUR) + ": " + str(stg.hour))
self.fill_measurements_information_groupbox()
self.combobox_freq_choice.addItems([f for f in stg.freq_text])
if self.sender().objectName() == "pushbutton_noise_file": if self.sender().objectName() == "pushbutton_noise_file":
stg.path_BS_noise_data = dir_name try:
stg.filename_BS_noise_data = name stg.path_BS_noise_data = dir_name
self.load_noise_data_and_compute_SNR() stg.filename_BS_noise_data = name
self.lineEdit_noise_file.setText(stg.filename_BS_noise_data) except ValueError as e:
self.lineEdit_noise_file.setToolTip(stg.path_BS_noise_data) msgBox = QMessageBox()
self.label_date_groupbox_noise_file.setText( msgBox.setWindowTitle("Download Error")
_translate("CONSTANT_STRING", cs.DATE) + ": " + str(stg.date_noise)) msgBox.setIcon(QMessageBox.Warning)
self.label_hour_groupbox_noise_file.setText( msgBox.setText("Please select a file")
_translate("CONSTANT_STRING", cs.HOUR) + ": " + str(stg.hour_noise)) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
else:
self.load_noise_data_and_compute_SNR()
self.lineEdit_noise_file.setText(stg.filename_BS_noise_data)
self.lineEdit_noise_file.setToolTip(stg.path_BS_noise_data)
self.label_date_groupbox_noise_file.setText(
_translate("CONSTANT_STRING", cs.DATE) + ": " + str(stg.date_noise))
self.label_hour_groupbox_noise_file.setText(
_translate("CONSTANT_STRING", cs.HOUR) + ": " + str(stg.hour_noise))
def load_BS_acoustic_raw_data(self): def load_BS_acoustic_raw_data(self):
acoustic_data = AcousticDataLoader(stg.path_BS_raw_data + "/" + stg.filename_BS_raw_data) acoustic_data = AcousticDataLoader(stg.path_BS_raw_data + "/" + stg.filename_BS_raw_data)
@ -1239,7 +1258,7 @@ class AcousticDataTab(QWidget):
self.axis_SNR[f].text(1, .70, stg.freq_text[f], self.axis_SNR[f].text(1, .70, stg.freq_text[f],
fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_BS[f].transAxes) transform=self.axis_SNR[f].transAxes)
self.fig_SNR.canvas.draw_idle() self.fig_SNR.canvas.draw_idle()

View File

@ -253,25 +253,20 @@ class AcousticInversionTab(QWidget):
if len(frequencies_position) != 0: if len(frequencies_position) != 0:
# print(frequencies_position) # print(frequencies_position)
# print(freq_combination[frequencies_position[0]][0], freq_combination[frequencies_position[0]][1]) # print(freq_combination[frequencies_position[0]][0], freq_combination[frequencies_position[0]][1])
stg.frequencies_pair = ( stg.frequencies_to_compute_VBI = (
np.array([[int(np.where(stg.freq == freq_combination[frequencies_position[0]][0])[0][0]), np.array([[int(np.where(stg.freq == freq_combination[frequencies_position[0]][0])[0][0]),
freq_combination[frequencies_position[0]][0]], freq_combination[frequencies_position[0]][0]],
[int(np.where(stg.freq == freq_combination[frequencies_position[0]][1])[0][0]), [int(np.where(stg.freq == freq_combination[frequencies_position[0]][1])[0][0]),
freq_combination[frequencies_position[0]][1]]])) freq_combination[frequencies_position[0]][1]]]))
# print(type(stg.frequencies_pair))
# print(stg.frequencies_pair)
# print(stg.frequencies_pair[1, 0])
# print(type(stg.frequencies_pair[0]), stg.frequencies_pair[0],
# np.where(stg.freq == stg.frequencies_pair[0])[0][0])
# print(type(stg.frequencies_pair[1]), stg.frequencies_pair[1],
# np.where(stg.freq == stg.frequencies_pair[1])[0][0])
# --- add items in combobox of frequency for SSC computation --- # --- add items in combobox of frequency for SSC computation ---
for k in range(stg.frequencies_pair.shape[0]): for k in range(stg.frequencies_to_compute_VBI.shape[0]):
self.combobox_frequency_SSC.addItem(str(1e-6*stg.frequencies_pair[k, 1]) + " MHz") self.combobox_frequency_SSC.addItem(str(1e-6*stg.frequencies_to_compute_VBI[k, 1]) + " MHz")
for i in range(stg.frequencies_pair.shape[0]): for i in range(stg.frequencies_to_compute_VBI.shape[0]):
self.combobox_frequency_SSC.setItemChecked(i, False) self.combobox_frequency_SSC.setItemChecked(i, False)
print("frequencies to compute VBI", stg.frequencies_to_compute_VBI)
def frequency_choice_to_compute_SSC(self, index): def frequency_choice_to_compute_SSC(self, index):
# print(self.combobox_frequency_SSC.currentText()) # print(self.combobox_frequency_SSC.currentText())
# print(self.combobox_frequency_SSC.currentIndex()) # print(self.combobox_frequency_SSC.currentIndex())
@ -286,23 +281,24 @@ class AcousticInversionTab(QWidget):
stg.frequency_to_compute_SSC \ stg.frequency_to_compute_SSC \
= np.array([int(np.where(np.array(stg.freq_text) == self.combobox_frequency_SSC.currentText())[0][0]), = np.array([int(np.where(np.array(stg.freq_text) == self.combobox_frequency_SSC.currentText())[0][0]),
stg.freq[int(np.where(np.array(stg.freq_text) == self.combobox_frequency_SSC.currentText())[0][0])]]) stg.freq[int(np.where(np.array(stg.freq_text) == self.combobox_frequency_SSC.currentText())[0][0])]])
# print("stg.frequency_to_compute_SSC ", stg.frequency_to_compute_SSC)
print("stg.frequency_to_compute_SSC ", stg.frequency_to_compute_SSC)
def temperature_value(self): def temperature_value(self):
stg.temperature = self.spinbox_temperature.value() stg.temperature = self.spinbox_temperature.value()
# print(stg.temperature) # print(stg.temperature)
def compute_acoustic_inversion_method_high_concentration(self): def compute_acoustic_inversion_method_high_concentration(self):
stg.water_attenuation = self.inv_hc.water_attenuation(stg.frequencies_pair[0, 1], stg.frequencies_pair[1, 1], stg.temperature) stg.water_attenuation = self.inv_hc.water_attenuation(stg.frequencies_to_compute_VBI[0, 1], stg.frequencies_to_compute_VBI[1, 1], stg.temperature)
# print("water attenuation ", stg.water_attenuation) # print("water attenuation ", stg.water_attenuation)
stg.water_velocity = self.inv_hc.water_velocity(stg.temperature) stg.water_velocity = self.inv_hc.water_velocity(stg.temperature)
# print("water velocity ", stg.water_velocity) # print("water velocity ", stg.water_velocity)
stg.kt_corrected = self.inv_hc.kt_corrected(stg.r, stg.water_velocity, stg.kt_corrected = self.inv_hc.kt_corrected(stg.r, stg.water_velocity,
stg.gain_rx[[int(stg.frequencies_pair[0, 0]), int(stg.frequencies_pair[1, 0])]], stg.gain_rx[[int(stg.frequencies_to_compute_VBI[0, 0]), int(stg.frequencies_to_compute_VBI[1, 0])]],
stg.gain_tx[[int(stg.frequencies_pair[0, 0]), int(stg.frequencies_pair[1, 0])]], stg.gain_tx[[int(stg.frequencies_to_compute_VBI[0, 0]), int(stg.frequencies_to_compute_VBI[1, 0])]],
stg.kt[[int(stg.frequencies_pair[0, 0]), int(stg.frequencies_pair[1, 0])]]) stg.kt[[int(stg.frequencies_to_compute_VBI[0, 0]), int(stg.frequencies_to_compute_VBI[1, 0])]])
# print("kt ", stg.kt_corrected) # print("kt ", stg.kt_corrected)
# print("kt shape ", stg.kt_corrected.shape) # print("kt shape ", stg.kt_corrected.shape)
@ -318,26 +314,44 @@ class AcousticInversionTab(QWidget):
print("kt 3D shape ", stg.kt_corrected_3D.shape) print("kt 3D shape ", stg.kt_corrected_3D.shape)
# print("kt 2D", np.repeat(stg.kt_corrected[:, :, np.newaxis], stg.t.shape[0], axis=2)) # print("kt 2D", np.repeat(stg.kt_corrected[:, :, np.newaxis], stg.t.shape[0], axis=2))
stg.J_cross_section = self.inv_hc.j_cross_section(stg.BS_data[:, [int(stg.frequencies_pair[0, 0]), int(stg.frequencies_pair[0, 0])], :], if stg.BS_data_section.size == 0:
stg.r_2D, stg.J_cross_section = (
stg.kt_corrected_3D) self.inv_hc.j_cross_section(
stg.BS_data[:, [int(stg.frequencies_to_compute_VBI[0, 0]),
int(stg.frequencies_to_compute_VBI[1, 0])], :],
stg.r_2D, stg.kt_corrected_3D))
elif (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0):
stg.J_cross_section = (
self.inv_hc.j_cross_section(
stg.BS_data_section[:, [int(stg.frequencies_to_compute_VBI[0, 0]),
int(stg.frequencies_to_compute_VBI[1, 0])], :],
stg.r_2D, stg.kt_corrected_3D))
elif (stg.BS_data_section_averaged.size != 0) and (stg.BS_data_section_SNR_filter.size == 0):
stg.J_cross_section = (
self.inv_hc.j_cross_section(
stg.BS_data_section_averaged[:, [int(stg.frequencies_to_compute_VBI[0, 0]),
int(stg.frequencies_to_compute_VBI[1, 0])], :],
stg.r_2D, stg.kt_corrected_3D))
else:
stg.J_cross_section = (
self.inv_hc.j_cross_section(
stg.BS_data_section_SNR_filter[:, [int(stg.frequencies_to_compute_VBI[0, 0]),
int(stg.frequencies_to_compute_VBI[1, 0])], :],
stg.r_2D, stg.kt_corrected_3D))
print("J ", stg.J_cross_section) print("J ", stg.J_cross_section)
print("J sahpe ", stg.J_cross_section.shape) print("J sahpe ", stg.J_cross_section.shape)
stg.X_exponent = self.inv_hc.X_exponent(self.combobox_frequencies_VBI.currentIndex()) stg.X_exponent = self.inv_hc.X_exponent(self.combobox_frequencies_VBI.currentIndex())
print("X ", stg.X_exponent) print("X ", stg.X_exponent)
stg.zeta = self.inv_hc.zeta(int(stg.frequencies_pair[0, 0]), int(stg.frequencies_pair[1, 0])) stg.zeta = self.inv_hc.zeta(int(stg.frequencies_to_compute_VBI[0, 0]), int(stg.frequencies_to_compute_VBI[1, 0]))
print("zeta ", stg.zeta) print("zeta ", stg.zeta)
# print("stg.frequencies_pair ", stg.frequencies_pair)
# print("stg.frequencies_pair[0, 0]", int(stg.frequencies_pair[0, 0]))
# print("int(stg.frequencies_pair[1, 0]", int(stg.frequencies_pair[1, 0]))
stg.ks = self.inv_hc.ks(int(stg.frequency_to_compute_SSC[0])) stg.ks = self.inv_hc.ks(int(stg.frequency_to_compute_SSC[0]))
print("ks ", stg.ks) print("ks ", stg.ks)
stg.VBI_cross_section = self.inv_hc.VBI_cross_section(stg.frequencies_pair[0, 1], stg.frequencies_pair[1, 1], stg.VBI_cross_section = self.inv_hc.VBI_cross_section(stg.frequencies_to_compute_VBI[0, 1], stg.frequencies_to_compute_VBI[1, 1],
stg.zeta[0], # zeta is already limited to the frequencies pairs so that we just need to select indices 0 and 1 stg.zeta[0], # zeta is already limited to the frequencies pairs so that we just need to select indices 0 and 1
stg.zeta[1], stg.zeta[1],
stg.J_cross_section[0, :, :], stg.J_cross_section[0, :, :],
@ -378,20 +392,24 @@ class AcousticInversionTab(QWidget):
def plot_SSC_fine(self): def plot_SSC_fine(self):
val_min = 1e-2 #np.nanmin(self.model.SSC_fine[:, :]) # val_min = 1e-2
val_max = 15 #np.nanmax(self.model.SSC_fine[:, :]) # val_max = 15
# print('val_min=', val_min) # val_min = np.nanmin(stg.SSC_fine)
# print('val_max=', val_max) # val_max = np.nanmax(stg.SSC_fine)
print('val_min fine = ', np.nanmin(stg.SSC_fine))
print('val_max fine =', np.nanmax(stg.SSC_fine))
# if val_min == 0: # if val_min == 0:
# val_min = 0.5 # val_min = 0.5
# print('val_min update =', val_min) # print('val_min update =', val_min)
pcm_SSC_fine = self.axis_SSC_2D_field[0].pcolormesh(stg.t, -stg.r, stg.J_cross_section[0, :, :], pcm_SSC_fine = self.axis_SSC_2D_field[0].pcolormesh(stg.t, -stg.r, stg.SSC_fine,
cmap='rainbow', cmap='rainbow',
# norm=LogNorm(vmin=val_min, vmax=val_max), norm=LogNorm(vmin=val_min, vmax=val_max),
shading='gouraud') shading='gouraud')
self.axis_SSC_2D_field[0].plot(stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid") if stg.r_bottom.size != 0:
self.axis_SSC_2D_field[0].plot(stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid")
self.figure_SSC_2D_field.supxlabel("Time (sec)", fontsize=10) self.figure_SSC_2D_field.supxlabel("Time (sec)", fontsize=10)
self.figure_SSC_2D_field.supylabel("Depth (m)", fontsize=10) self.figure_SSC_2D_field.supylabel("Depth (m)", fontsize=10)
@ -402,21 +420,25 @@ class AcousticInversionTab(QWidget):
def plot_SSC_sand(self): def plot_SSC_sand(self):
val_min = np.nanmin(stg.VBI_cross_section) #1e-2 #np.nanmin(self.model.SSC_fine[:, :]) # val_min = 1e-2
val_max = np.nanmax(stg.VBI_cross_section) #15 #np.nanmax(self.model.SSC_fine[:, :]) # val_max = 2
# print('val_min=', val_min) # val_min = np.nanmin(stg.SSC_sand)
# print('val_max=', val_max) # val_max = np.nanmax(stg.SSC_sand)
print('val_min sand = ', np.nanmin(stg.SSC_sand))
print('val_max sand = ', np.nanmax(stg.SSC_sand))
# if val_min == 0: # if val_min == 0:
# val_min = 0.5 # val_min = 0.5
# print('val_min update =', val_min) # print('val_min update =', val_min)
pcm_SSC_sand = self.axis_SSC_2D_field[1].pcolormesh(stg.t, -stg.r, stg.J_cross_section[1, :, :], pcm_SSC_sand = self.axis_SSC_2D_field[1].pcolormesh(stg.t, -stg.r, stg.SSC_sand,
cmap='rainbow', cmap='rainbow',
# vmin=val_min, vmax=val_max, # vmin=val_min, vmax=val_max,
# norm=LogNorm(vmin=val_min, vmax=val_max), norm=LogNorm(vmin=val_min, vmax=val_max),
shading='gouraud') shading='gouraud')
self.axis_SSC_2D_field[1].plot(stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid") if stg.r_bottom.size:
self.axis_SSC_2D_field[1].plot(stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid")
self.figure_SSC_2D_field.supxlabel("Time (sec)", fontsize=10) self.figure_SSC_2D_field.supxlabel("Time (sec)", fontsize=10)
self.figure_SSC_2D_field.supylabel("Depth (m)", fontsize=10) self.figure_SSC_2D_field.supylabel("Depth (m)", fontsize=10)
@ -438,6 +460,11 @@ class AcousticInversionTab(QWidget):
if self.canvas_SSC_sample_vs_inversion == None: if self.canvas_SSC_sample_vs_inversion == None:
print("Ctot fine : ", stg.Ctot_fine)
print("SCC fine : ", stg.SSC_fine[sample_depth_position, sample_time_position])
print("Ctot fine : ", stg.Ctot_sand)
print("SCC fine : ", stg.SSC_sand[sample_depth_position, sample_time_position])
self.figure_SSC_sample_vs_inversion, self.axis_SSC_sample_vs_inversion = plt.subplots(nrows=1, ncols=1, layout="constrained") self.figure_SSC_sample_vs_inversion, self.axis_SSC_sample_vs_inversion = plt.subplots(nrows=1, ncols=1, layout="constrained")
self.canvas_SSC_sample_vs_inversion = FigureCanvas(self.figure_SSC_sample_vs_inversion) self.canvas_SSC_sample_vs_inversion = FigureCanvas(self.figure_SSC_sample_vs_inversion)
self.verticalLayout_groupbox_SSC_sample_vs_inversion.addWidget(self.canvas_SSC_sample_vs_inversion) self.verticalLayout_groupbox_SSC_sample_vs_inversion.addWidget(self.canvas_SSC_sample_vs_inversion)
@ -446,7 +473,7 @@ class AcousticInversionTab(QWidget):
self.axis_SSC_sample_vs_inversion.plot(stg.Ctot_sand, stg.SSC_sand[sample_depth_position, sample_time_position], ls=" ", marker='x', color='black', label='Sand SSC') self.axis_SSC_sample_vs_inversion.plot(stg.Ctot_sand, stg.SSC_sand[sample_depth_position, sample_time_position], ls=" ", marker='x', color='black', label='Sand SSC')
self.axis_SSC_sample_vs_inversion.set_xscale('log') self.axis_SSC_sample_vs_inversion.set_xscale('log')
self.axis_SSC_sample_vs_inversion.set_yscale('log') self.axis_SSC_sample_vs_inversion.set_yscale('log')
self.axis_SSC_sample_vs_inversion.plot([0.5e-2, 20], [0.5e-2, 20], color='black', lw=1) # self.axis_SSC_sample_vs_inversion.plot([0, 100], [0, 100], color='black', lw=1)
self.axis_SSC_sample_vs_inversion.set_xlabel('Measured SSC (g/l)', weight='bold') self.axis_SSC_sample_vs_inversion.set_xlabel('Measured SSC (g/l)', weight='bold')
self.axis_SSC_sample_vs_inversion.set_ylabel('Inverse SSC (g/l)', weight='bold') self.axis_SSC_sample_vs_inversion.set_ylabel('Inverse SSC (g/l)', weight='bold')
self.axis_SSC_sample_vs_inversion.legend() self.axis_SSC_sample_vs_inversion.legend()

View File

@ -189,7 +189,6 @@ class NoteTab(QWidget):
self.textEdit.setAlignment(Qt.AlignJustify) self.textEdit.setAlignment(Qt.AlignJustify)
def print_settings(self): def print_settings(self):
print(int(stg.frequencies_pair[0, 0]))
self.textEdit.setText("Acoustic data: \n\n" self.textEdit.setText("Acoustic data: \n\n"
f" ABS raw data file: {stg.path_BS_raw_data}/{stg.filename_BS_raw_data} \n" f" ABS raw data file: {stg.path_BS_raw_data}/{stg.filename_BS_raw_data} \n"
@ -204,7 +203,8 @@ class NoteTab(QWidget):
"------------------------------------------------------------------------- \n\n\n" "------------------------------------------------------------------------- \n\n\n"
"Acoustic Inversion parameters: \n" "Acoustic Inversion parameters: \n"
f" frequencies to compute VBI: {stg.freq_text[int(stg.frequencies_pair[0, 0])]}, {stg.freq_text[int(stg.frequencies_pair[1, 0])]} \n" f" frequencies to compute VBI: {stg.freq_text[int(stg.frequencies_to_compute_VBI[0, 0])]}, "
f"{stg.freq_text[int(stg.frequencies_to_compute_VBI[1, 0])]} \n"
f" frequency to compute SSC: {stg.freq_text[int(stg.frequency_to_compute_SSC[0])]}") f" frequency to compute SSC: {stg.freq_text[int(stg.frequency_to_compute_SSC[0])]}")

View File

@ -1,7 +1,8 @@
import sys import sys
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QGroupBox, QLabel, QCheckBox, \ from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QGroupBox, QLabel, QCheckBox,
QSpinBox, QDoubleSpinBox, QComboBox, QLineEdit, QSlider, QGridLayout, QMessageBox QSpinBox, QDoubleSpinBox, QComboBox, QLineEdit, QSlider, QGridLayout, QMessageBox,
QScrollArea)
from PyQt5.QtGui import QFont, QIcon, QPixmap from PyQt5.QtGui import QFont, QIcon, QPixmap
from PyQt5.QtCore import Qt, QCoreApplication from PyQt5.QtCore import Qt, QCoreApplication
@ -13,6 +14,7 @@ import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas 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 import stats
import Translation.constant_string as cs import Translation.constant_string as cs
@ -20,6 +22,8 @@ from Model.acoustic_data_loader import AcousticDataLoader
import settings as stg import settings as stg
from Model.acoustic_inversion_method_high_concentration import AcousticInversionMethodHighConcentration
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
@ -30,6 +34,8 @@ class SignalProcessingTab(QWidget):
def __init__(self, widget_tab): def __init__(self, widget_tab):
super().__init__() super().__init__()
self.inv_hc = AcousticInversionMethodHighConcentration()
path_icon = "./icons/" path_icon = "./icons/"
icon_triangle_left = QIcon(path_icon + "triangle_left.png") icon_triangle_left = QIcon(path_icon + "triangle_left.png")
icon_triangle_right = QIcon(path_icon + "triangle_right.png") icon_triangle_right = QIcon(path_icon + "triangle_right.png")
@ -183,24 +189,44 @@ class SignalProcessingTab(QWidget):
# --- Groupbox Window size --- # --- Groupbox Window size ---
self.horizontalLayout_groupbox_window_size = QHBoxLayout(self.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_over = QLabel() self.label_signal_averaging_horizontal = QLabel()
self.label_signal_averaging_over.setText("Signal averaging over +/- ") self.label_signal_averaging_horizontal.setText("Horizontal +/- ")
self.horizontalLayout_groupbox_window_size.addWidget(self.label_signal_averaging_over) # self.horizontalLayout_groupbox_window_size.addWidget(self.label_signal_averaging_over)
self.spinbox_average = QSpinBox() self.gridLayout_groupbox_window_size.addWidget(self.label_signal_averaging_horizontal, 0, 0, 1, 1)
self.spinbox_average.setRange(0, 9999) self.spinbox_average_horizontal = QSpinBox()
self.spinbox_average.setValue(0) self.spinbox_average_horizontal.setRange(0, 9999)
self.horizontalLayout_groupbox_window_size.addWidget(self.spinbox_average) self.spinbox_average_horizontal.setValue(0)
self.label_cells = QLabel() # self.horizontalLayout_groupbox_window_size.addWidget(self.spinbox_average)
self.horizontalLayout_groupbox_window_size.addWidget(self.label_cells) 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.spinbox_average.valueChanged.connect(self.compute_averaged_profile)
self.pushbutton_average = QPushButton() self.pushbutton_average = QPushButton()
self.pushbutton_average.setText("Apply averaging") self.pushbutton_average.setText("Apply averaging")
# self.pushbutton_snr_filter.setDisabled(True) # self.pushbutton_snr_filter.setDisabled(True)
self.horizontalLayout_groupbox_window_size.addWidget(self.pushbutton_average) # 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.compute_averaged_profile)
# self.pushbutton_average.clicked.connect(self.update_plot_profile_position_on_transect) # self.pushbutton_average.clicked.connect(self.update_plot_profile_position_on_transect)
@ -286,6 +312,7 @@ class SignalProcessingTab(QWidget):
self.gridLayout_groupbox_fit_regression.addWidget(self.combobox_frequency_compute_alphaS, 1, 0, 1, 1) 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 = QLabel()
self.label_alphaS_computation_from.setText("From -")
self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS_computation_from, 1, 1, 1, 1) 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 = QDoubleSpinBox()
@ -293,19 +320,30 @@ class SignalProcessingTab(QWidget):
self.gridLayout_groupbox_fit_regression.addWidget(self.spinbox_alphaS_computation_from, 1, 2, 1, 1) 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 = QLabel()
self.label_alphaS_computation_to.setText("To -")
self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS_computation_to, 1, 3, 1, 1) self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS_computation_to, 1, 3, 1, 1)
self.spinbox_alphaS_computation_to = QDoubleSpinBox() self.spinbox_alphaS_computation_to = QDoubleSpinBox()
self.gridLayout_groupbox_fit_regression.addWidget(self.spinbox_alphaS_computation_to, 1, 4, 1, 1) self.gridLayout_groupbox_fit_regression.addWidget(self.spinbox_alphaS_computation_to, 1, 4, 1, 1)
self.pushbutton_fit_regression_line = QPushButton() self.pushbutton_plot_FCB = QPushButton()
self.pushbutton_fit_regression_line.setText("Fit && Compute \u03B1s") self.pushbutton_plot_FCB.setText("Plot FCB")
self.gridLayout_groupbox_fit_regression.addWidget(self.pushbutton_fit_regression_line, 2, 0, 1, 1) 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 = QLabel()
self.label_alphaS.setText("\u03B1s = " + "0.0" + "dB/m") self.label_alphaS.setText("\u03B1s = " + "0.0" + "dB/m")
self.label_alphaS.setFont(QFont("Ubuntu", 14, QFont.Normal)) self.label_alphaS.setFont(QFont("Ubuntu", 14, QFont.Normal))
self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS, 2, 3, 1, 2) self.gridLayout_groupbox_fit_regression.addWidget(self.label_alphaS, 2, 3, 1, 1)
# self.verticalLayout_groupbox_fit_regression # self.verticalLayout_groupbox_fit_regression
@ -334,6 +372,7 @@ class SignalProcessingTab(QWidget):
self.verticalLayout_groupbox_plot_profile = QVBoxLayout(self.groupbox_plot_profile) self.verticalLayout_groupbox_plot_profile = QVBoxLayout(self.groupbox_plot_profile)
self.canvas_profile = None self.canvas_profile = None
self.scroll_profile = None
# # self.data_test_slider = np.array([[0, 1, 2, 3, 4, 5], # # self.data_test_slider = np.array([[0, 1, 2, 3, 4, 5],
# # [0, 1, 4, 9, 16, 25], # # [0, 1, 4, 9, 16, 25],
@ -377,6 +416,7 @@ class SignalProcessingTab(QWidget):
self.verticalLayout_groupbox_plot_averaged_profile = QVBoxLayout(self.groupbox_plot_averaged_profile) self.verticalLayout_groupbox_plot_averaged_profile = QVBoxLayout(self.groupbox_plot_averaged_profile)
self.canvas_averaged_profile = None self.canvas_averaged_profile = None
self.scroll_averaged_profile = None
# self.verticalLayout_averagedprofile = QVBoxLayout(self.groupbox_plot_averaged_profile) # self.verticalLayout_averagedprofile = QVBoxLayout(self.groupbox_plot_averaged_profile)
# self.figure_averagedprofile, self.axis_averagedprofile = plt.subplots(nrows=1, ncols=4, layout='constrained') # self.figure_averagedprofile, self.axis_averagedprofile = plt.subplots(nrows=1, ncols=4, layout='constrained')
@ -432,6 +472,7 @@ class SignalProcessingTab(QWidget):
self.verticalLayout_groupbox_plot_FCB_profile = QVBoxLayout(self.groupbox_FCB_profile) self.verticalLayout_groupbox_plot_FCB_profile = QVBoxLayout(self.groupbox_FCB_profile)
self.canvas_FCB_profile = None self.canvas_FCB_profile = None
self.scroll_FCB_profile = None
# self.verticalLayout_FCBoptions = QVBoxLayout(self.groupbox_FCB_profile) # self.verticalLayout_FCBoptions = QVBoxLayout(self.groupbox_FCB_profile)
# self.figure_FCBoptions, self.axis_FCBoptions = plt.subplots(nrows=1, ncols=4, layout="constrained") # self.figure_FCBoptions, self.axis_FCBoptions = plt.subplots(nrows=1, ncols=4, layout="constrained")
@ -525,6 +566,7 @@ class SignalProcessingTab(QWidget):
self.slider.valueChanged.connect(self.update_plot_profile_position_on_transect) 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_profile)
self.slider.valueChanged.connect(self.update_plot_averaged_profile) self.slider.valueChanged.connect(self.update_plot_averaged_profile)
self.slider.valueChanged.connect(self.update_plot_FCB)
self.retranslate_signal_processing_tab() self.retranslate_signal_processing_tab()
@ -545,7 +587,7 @@ class SignalProcessingTab(QWidget):
self.groupbox_window_size.setTitle(_translate("CONSTANT_STRING", cs.WINDOW_SIZE)) self.groupbox_window_size.setTitle(_translate("CONSTANT_STRING", cs.WINDOW_SIZE))
# self.label_averageH.setText(_translate("CONSTANT_STRING", cs.HORIZONTAL) + ": +/-") # self.label_averageH.setText(_translate("CONSTANT_STRING", cs.HORIZONTAL) + ": +/-")
self.label_cells.setText(_translate("CONSTANT_STRING", cs.CELLS) + " = +/- ? sec") # self.label_cells.setText(_translate("CONSTANT_STRING", cs.CELLS) + " = +/- ? sec")
self.groupbox_rayleigh_criterion.setTitle(_translate("CONSTANT_STRING", cs.RAYLEIGH_CRITERION)) self.groupbox_rayleigh_criterion.setTitle(_translate("CONSTANT_STRING", cs.RAYLEIGH_CRITERION))
# self.checkbox_despiked_acoustic_signal.setText(_translate("CONSTANT_STRING", cs.DESPIKING)) # self.checkbox_despiked_acoustic_signal.setText(_translate("CONSTANT_STRING", cs.DESPIKING))
@ -558,8 +600,8 @@ class SignalProcessingTab(QWidget):
self.groupbox_fit_regression_line.setTitle(_translate("CONSTANT_STRING", cs.FIT_REGRESSION_LINE)) self.groupbox_fit_regression_line.setTitle(_translate("CONSTANT_STRING", cs.FIT_REGRESSION_LINE))
self.label_alphaS_expression.setText( self.label_alphaS_expression.setText(
_translate("CONSTANT_STRING", cs.FOR_HOMOGENEOUS_SUSPENSION) + ": dFCB/dr = -2\u03B1<sub>s<\sub>") _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_from.setText(_translate("CONSTANT_STRING", cs.FROM))
self.label_alphaS_computation_to.setText(_translate("CONSTANT_STRING", cs.TO)) # self.label_alphaS_computation_to.setText(_translate("CONSTANT_STRING", cs.TO))
self.groupbox_plot_profile.setTitle(_translate("CONSTANT_STRING", cs.PROFILE)) self.groupbox_plot_profile.setTitle(_translate("CONSTANT_STRING", cs.PROFILE))
self.groupbox_plot_averaged_profile.setTitle(_translate("CONSTANT_STRING", cs.AVERAGED_PROFILE)) self.groupbox_plot_averaged_profile.setTitle(_translate("CONSTANT_STRING", cs.AVERAGED_PROFILE))
@ -630,7 +672,7 @@ class SignalProcessingTab(QWidget):
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
else: else:
filter_convolve = np.ones(self.spinbox_average.value()) 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])) 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 f in range(stg.freq.shape[0]):
@ -638,8 +680,13 @@ class SignalProcessingTab(QWidget):
stg.BS_data_section_averaged[i, f, :] \ stg.BS_data_section_averaged[i, f, :] \
= convolve1d(stg.BS_data_section[i, f, :], weights=filter_convolve) / filter_convolve.shape[0] = convolve1d(stg.BS_data_section[i, f, :], weights=filter_convolve) / filter_convolve.shape[0]
self.label_cells.clear() self.label_cells_horizontal.clear()
self.label_cells.setText("cells = +/- " + str((self.spinbox_average.value() // 2)*(1/stg.nb_profiles_per_sec)) + " sec") 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.plot_averaged_profile()
self.update_plot_profile_position_on_transect() self.update_plot_profile_position_on_transect()
@ -665,9 +712,9 @@ class SignalProcessingTab(QWidget):
stg.Noise_data[:, :, :stg.t.shape[0]]**2) stg.Noise_data[:, :, :stg.t.shape[0]]**2)
for f in range(stg.freq.shape[0]): for f in range(stg.freq.shape[0]):
stg.BS_data_section_SNR_filter[np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[0], stg.BS_data_section_SNR_filter[np.where(stg.SNR_data_average[:, f, :] < self.spinbox_SNR_criterion.value())[0],
f, f,
np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[1]] \ np.where(stg.SNR_data_average[:, f, :] < self.spinbox_SNR_criterion.value())[1]] \
= np.nan = np.nan
elif stg.BS_data_section_averaged.size != 0: elif stg.BS_data_section_averaged.size != 0:
@ -678,24 +725,34 @@ class SignalProcessingTab(QWidget):
for f in range(stg.freq.shape[0]): for f in range(stg.freq.shape[0]):
stg.BS_data_section_SNR_filter[ stg.BS_data_section_SNR_filter[
np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[0], np.where(stg.SNR_data_average[:, f, :] < self.spinbox_SNR_criterion.value())[0],
f, f,
np.where(stg.SNR_data_average[:, 0, :] < self.spinbox_SNR_criterion.value())[1]] \ np.where(stg.SNR_data_average[:, f, :] < self.spinbox_SNR_criterion.value())[1]] \
= np.nan = np.nan
self.update_plot_profile_position_on_transect() self.update_plot_profile_position_on_transect()
self.update_plot_averaged_profile() self.update_plot_averaged_profile()
def compute_water_attenuation(self): def compute_water_attenuation(self):
if self.combobox_water_attenuation_model.currentIndex() == 0: if (stg.freq.size == 0) or (self.spinbox_temperature_water_attenuation.value() == 0):
self.Francois_and_Garrison_1982() 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: else:
pass
print(f"{stg.water_attenuation:.2f}") if self.combobox_water_attenuation_model.currentIndex() == 0:
self.label_water_attenuation.clear() self.Francois_and_Garrison_1982()
self.label_water_attenuation.setText("\u03B1w = " + f"{stg.water_attenuation:.4f}" + " dB/m")
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): def Francois_and_Garrison_1982(self):
if self.spinbox_temperature_water_attenuation.value() > 20: if self.spinbox_temperature_water_attenuation.value() > 20:
@ -711,6 +768,91 @@ class SignalProcessingTab(QWidget):
(np.log(10) / 20) * (np.log(10) / 20) *
(stg.freq[self.combobox_freq_for_water_attenuation.currentIndex()] * 1e-3) ** 2) (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 --------------------------------------- # ---------------------------------------- PLOT PROFILE POSITION ON TRANSECT ---------------------------------------
def plot_profile_position_on_transect(self): def plot_profile_position_on_transect(self):
@ -848,28 +990,66 @@ class SignalProcessingTab(QWidget):
# --- Raw profile --- # --- Raw profile ---
self.figure_profile, self.axis_profile \ self.figure_profile, self.axis_profile \
= plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained') = plt.subplots(nrows=1, ncols=stg.freq.shape[0], sharex=True, sharey=True, layout='constrained')
self.canvas_profile = FigureCanvas(self.figure_profile) self.canvas_profile = FigureCanvas(self.figure_profile)
self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_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]): for f in range(stg.freq.shape[0]):
self.axis_profile[f].cla() self.axis_profile[f].cla()
self.axis_profile[f].plot(stg.BS_data_section[:, f, self.slider.value() - 1], -stg.r, self.axis_profile[f].plot(stg.BS_data_section[:, f, self.slider.value() - 1], -stg.r,
linestyle='solid', color='k', linewidth=1) 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 --- # --- Raw averaged profile ---
self.figure_averaged_profile, self.axis_averaged_profile \ self.figure_averaged_profile, self.axis_averaged_profile \
= plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained') = 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.canvas_averaged_profile = FigureCanvas(self.figure_averaged_profile)
self.verticalLayout_groupbox_plot_averaged_profile.addWidget(self.canvas_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 --- # --- Raw FCB profile ---
self.figure_FCB_profile, self.axis_FCB_profile \ self.figure_FCB_profile, self.axis_FCB_profile \
= plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained') = 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.canvas_FCB_profile = FigureCanvas(self.figure_FCB_profile)
self.verticalLayout_groupbox_plot_FCB_profile.addWidget(self.canvas_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): def update_plot_profile(self):
if self.canvas_profile is None: if self.canvas_profile is None:
@ -885,7 +1065,14 @@ class SignalProcessingTab(QWidget):
self.axis_profile[f].cla() self.axis_profile[f].cla()
self.axis_profile[f].plot(stg.BS_data_section[:, f, self.slider.value() - 1], -stg.r, self.axis_profile[f].plot(stg.BS_data_section[:, f, self.slider.value() - 1], -stg.r,
linestyle='solid', color='k', linewidth=1) 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() self.figure_profile.canvas.draw_idle()
# --------------------------------- PLOT AVERAGED PROFILE FILTERED OR NOT WITH SNR --------------------------------- # --------------------------------- PLOT AVERAGED PROFILE FILTERED OR NOT WITH SNR ---------------------------------
@ -897,7 +1084,14 @@ class SignalProcessingTab(QWidget):
self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[:, f, self.slider.value()-1], -stg.r, self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[:, f, self.slider.value()-1], -stg.r,
linestyle='solid', color='k', linewidth=1) 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].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() self.figure_averaged_profile.canvas.draw_idle()
def update_plot_averaged_profile(self): def update_plot_averaged_profile(self):
@ -909,6 +1103,9 @@ class SignalProcessingTab(QWidget):
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
elif (stg.BS_data_section_averaged.size == 0) and (stg.BS_data_section_SNR_filter.size == 0):
pass
else: else:
if stg.BS_data_section_SNR_filter.size == 0: if stg.BS_data_section_SNR_filter.size == 0:
@ -917,7 +1114,14 @@ class SignalProcessingTab(QWidget):
self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[:, f, self.slider.value() - 1], -stg.r, self.axis_averaged_profile[f].plot(stg.BS_data_section_averaged[:, f, self.slider.value() - 1], -stg.r,
linestyle='solid', color='k', linewidth=1) 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].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() self.figure_averaged_profile.canvas.draw_idle()
elif stg.BS_data_section_SNR_filter.size != 0: elif stg.BS_data_section_SNR_filter.size != 0:
@ -927,73 +1131,60 @@ class SignalProcessingTab(QWidget):
self.axis_averaged_profile[f].plot(stg.BS_data_section_SNR_filter[:, f, self.slider.value() - 1], -stg.r, 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) 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].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() self.figure_averaged_profile.canvas.draw_idle()
# def plot_transect_bottom_with_profile_position(self, profile_position): # ---------------------------------------------------- PLOT FCB ----------------------------------------------------
# frequency = self.model.Freq[0]
# val_min = 0 # np.nanmin(self.model.BS_averaged_cross_section_corr.V[:, 0, :]) def plot_FCB(self):
# val_max = np.nanmax(self.model.BS_averaged_cross_section_corr.V[:, 0, :])
# # print('val_min=', val_min) for f in range(stg.freq.shape[0]):
# # print('val_max=', val_max)
# if val_min == 0: self.axis_FCB_profile[f].cla()
# val_min = 1e-5
# # print('val_min update=', val_min) self.axis_FCB_profile[f].plot(stg.r, stg.FCB[:, f, self.slider.value()], linestyle="solid", linewidth=1, color="k")
# # if val_min == 0:
# # val_min = 1e-5 # self.axis_FCB_profile[f].set_ylim(np.max(stg.r), np.min(stg.r))
# # self.axis_plot_profile_position_on_transect.imshow(np.asarray(np.array(self.model.V[:, 0, :2300], dtype=float)), aspect='auto', self.axis_FCB_profile[f].text(.95, .05, stg.freq_text[f],
# # extent=[0, 2300, self.model.depth[-1][0], self.model.depth[0][0]], fontsize=10, fontweight='bold', fontname="Ubuntu",
# # cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) fontstyle="normal", c="black", alpha=0.2,
# self.axis_plot_profile_position_on_transect.cla() horizontalalignment='right', verticalalignment='bottom',
# # self.figure_plot_profile_position_on_transect.clf() transform=self.axis_FCB_profile[f].transAxes)
# self.axis_plot_profile_position_on_transect.pcolormesh(self.model.dist_BS_section,
# np.flipud(self.model.BS_raw_cross_section.r), if len(stg.lin_reg) != 0:
# self.model.BS_averaged_cross_section_corr.V[:, 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")
# cmap='viridis',
# norm=LogNorm(vmin=val_min, vmax=val_max), self.figure_FCB_profile.supylabel("FCB")
# shading='gouraud') self.figure_FCB_profile.supxlabel("Depth (m)")
# self.axis_plot_profile_position_on_transect.plot(self.model.dist_BS_section, self.figure_FCB_profile.canvas.draw_idle()
# np.max(self.model.r_bottom_cross_section) -
# self.model.r_bottom_cross_section + def update_plot_FCB(self):
# np.min(self.model.r_bottom_cross_section),
# color='k', linewidth=2) for f in range(stg.freq.shape[0]):
# self.axis_plot_profile_position_on_transect.plot(
# self.model.dist_BS_section[profile_position] * np.ones(self.model.r_bottom_cross_section.shape[0]), self.axis_FCB_profile[f].cla()
# self.model.r_bottom_cross_section, color='red', linestyle="solid", linewidth=2)
# self.axis_plot_profile_position_on_transect.set_xticks([]) self.axis_FCB_profile[f].plot(stg.r, stg.FCB[:, f, self.slider.value()], linestyle="solid", linewidth=1, color="k")
# self.axis_plot_profile_position_on_transect.set_yticks([])
# self.figure_plot_profile_position_on_transect.canvas.draw_idle() # 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],
# def changePlot(self): fontsize=10, fontweight='bold', fontname="Ubuntu",
# value = self.slider_plotprofile.value() fontstyle="normal", c="black", alpha=0.2,
# horizontalalignment='right', verticalalignment='bottom',
# self.string_profile_number = value transform=self.axis_FCB_profile[f].transAxes)
# self.label_profile_number.setText("Profile " + str(value) +
# " / " + str(self.string_profile_number_max)) self.figure_FCB_profile.supylabel("FCB")
# self.figure_FCB_profile.supxlabel("Depth (m)")
# self.plot_transect_bottom_with_profile_position(value) self.figure_FCB_profile.canvas.draw_idle()
#
# self.lineEdit_slider_acoustic_profile.setText(str(value))
#
# for i in range(4):
# self.axis_profile[i].cla()
# self.axis_profile[i].plot(self.model.BS_raw_cross_section.V[:, i, value-1], self.model.r, c='k')
#
# self.axis_averagedprofile[i].cla()
# self.axis_averagedprofile[i].plot(self.model.BS_averaged_cross_section.V[:, i, value-1], self.model.r, c='b')
#
# self.axis_FCBoptions[i].cla()
# self.axis_FCBoptions[i].plot(self.model.FCB[:, i, value-1], self.model.r, c='r')
# # self.axis_profile.plot(self.data_test_slider[0, :], self.data_test_slider[value-1, :])
#
# self.figure_profile.canvas.draw_idle()
# # self.figure_profile.canvas.flush_events()
# self.figure_averagedprofile.canvas.draw_idle()
# # self.figure_averagedprofile.canvas.flush_events()
# self.figure_FCBoptions.canvas.draw_idle()
# # self.figure_FCBoptions.canvas.flush_events()

View File

@ -63,6 +63,9 @@ SNR_data_average = np.array([]) # SNR data computed with BS signal a
water_attenuation = 0 water_attenuation = 0
sediment_attenuation = 0 sediment_attenuation = 0
FCB = np.array([])
lin_reg = tuple()
# --- Sample Data --- # --- Sample Data ---
samples = [] samples = []
@ -111,7 +114,7 @@ kt_corrected_2D = np.array([])
kt_corrected_3D = np.array([]) kt_corrected_3D = np.array([])
J_cross_section = np.array([]) J_cross_section = np.array([])
frequencies_pair = np.array([]) frequencies_to_compute_VBI = np.array([])
VBI_cross_section = np.array([]) VBI_cross_section = np.array([])
frequency_to_compute_SSC = 0 frequency_to_compute_SSC = 0