diff --git a/Model/acoustic_data_loader.py b/Model/acoustic_data_loader.py
index d9f6b9c..be45708 100644
--- a/Model/acoustic_data_loader.py
+++ b/Model/acoustic_data_loader.py
@@ -80,6 +80,10 @@ class AcousticDataLoader():
order="F")
return r
+ def compute_r_2D(self):
+ r2D = np.repeat(self._r, self._time.size, axis=1)
+ return r2D
+
def reshape_t(self):
t = np.reshape(np.repeat(self._time, self._r.shape[0]), (self._time.shape[0]*self._r.shape[0], 1))
return t
diff --git a/Model/acoustic_inversion_method_high_concentration.py b/Model/acoustic_inversion_method_high_concentration.py
new file mode 100644
index 0000000..dc5868b
--- /dev/null
+++ b/Model/acoustic_inversion_method_high_concentration.py
@@ -0,0 +1,150 @@
+import numpy as np
+import settings as stg
+
+
+class AcousticInversionMethodHighConcentration():
+
+ """ Thi class compute acoustic inversion method adapted for high suspended sediments concentration
+ For instance, the case of dam flush downstream Rhone-Isere confluence (07/01/2018) evaluated at ~ 10g/L """
+
+ def __init__(self):
+
+ pass
+
+ # ==========================================
+ # Functions
+ # ==========================================
+
+ # ---------- Computing sound speed ------------- #
+ def water_velocity(self, T):
+ """Computing sond speed from Bilaniuk and Wong 1993"""
+ C = 1.40238744 * 1e3 + 5.03836171 * T - 5.81172916 * 1e-2 * T ** 2 + 3.34638117 * 1e-4 * T ** 3 - \
+ 1.48259672 * 1e-6 * T ** 4 + 3.16585020 * 1e-9 * T ** 5
+ return C
+
+ # -------- Computing water attenuation coefficient ----------- #
+ def water_attenuation(self, freq1, freq2, T):
+ """Computing attenuation from François and Garrison 1982"""
+ if T > 20:
+ alpha = (3.964 * 1e-4 - 1.146 * 1e-5 * T + 1.45 * 1e-7 * T ** 2 - 6.5 * 1e-10 * T ** 3) * 1e-3 * \
+ (np.log(10) / 20) * (np.array([freq1, freq2]) * 1e-3) ** 2
+ else:
+ alpha = (4.937 * 1e-4 - 2.59 * 1e-5 * T + 9.11 * 1e-7 * T ** 2 - 1.5 * 1e-8 * T ** 3) * 1e-3 * \
+ (np.log(10) / 20) * (np.array([freq1, freq2]) * 1e-3) ** 2
+ return alpha
+
+ # ---------- Conmpute FBC ----------
+ # def compute_FCB(self):
+ # # print(self.BS_averaged_cross_section_corr.V.shape)
+ # # print(self.r_2D.shape)
+ # FCB = np.zeros((256, 4, 1912))
+ # for f in range(4):
+ # # print(self.alpha_w_function(self.Freq[f], self.temperature))
+ # FCB[:, f, :] = np.log(self.BS_averaged_cross_section_corr.V[:, f, :]) + np.log(self.r_3D[:, f, :]) + \
+ # np.log(2 * self.alpha_w_function(self.Freq[f], self.temperature) * self.r_3D[:, f, :])
+ # return FCB
+
+ # ------------- Computing ks ------------- #
+
+ def ks(self, ind):
+ ks0 = np.array([0.0446681, 0.11490388, 0.35937832, 2.5025668])
+ ks = ks0[ind]
+ return ks
+
+ # ------------- Computing sv ------------- #
+
+ def sv(self):
+ pass
+
+ # ------------- Computing X ------------- #
+ def X_exponent(self, ind):
+ X0 = [3.688664080521131, 3.451418735488537, 0, 3.276577078823426, 0, 0]
+ X = X0[ind]
+ return X
+
+ # -------------- Computing Kt -------------- #
+ def kt_corrected(self, r, water_velocity, RxGain, TxGain, kt_ref):
+ """Computing the instrument constant Kt that depends on gain and temperature"""
+ # Cell size
+ delta_r = r[1] - r[0]
+ # Pulse length
+ tau = 2 * delta_r / 1500
+ # Sound speed
+ cel = water_velocity
+ # Reference pulse length
+ tau_ref = 13.33333e-6
+ # Reference sound speed
+ c_ref = 1475
+ # Gain
+ gain = 10 ** ((RxGain + TxGain) / 20)
+ # Computing Kt
+ kt0 = kt_ref * gain * np.sqrt(tau * cel / (tau_ref * c_ref)) # 1D numpy array
+ kt = np.reshape(kt0, (1, 2)) # convert to 2d numpy array to compute J_cross_section
+ return kt
+
+ # ------------- Computing J_cross_section ------------- #
+ def j_cross_section(self, BS, r2D, kt):
+ J_cross_section = np.zeros((2, BS.shape[0], BS.shape[2])) # 2 because it's a pair of frequencies
+ for k in range(2):
+ J_cross_section[k, :, :] = (3 / (16 * np.pi)) * ((BS[:, k, :]**2 * r2D**2) / kt[k, :, :]**2)
+ # J_cross_section[J_cross_section == 0] = np.nan
+ print("compute j_cross_section finished")
+ return J_cross_section
+
+ # ------------- Computing alpha_s ------------- #
+
+ def alpha_s(self):
+ pass
+
+ # ------------- Computing interpolation of fine SSC data obtained from water sampling -------------
+ # ------------- collected at various depth in the vertical sample -------------
+ def M_profile_SCC_fine_interpolated(self):
+ pass
+
+ # ------------- Computing zeta ------------- #
+ def zeta(self, ind1, ind2):
+ # zeta = alpha_s / ((1/r) * (M_profile_SSC_fine))
+ zeta0 = np.array([0.04341525, 0.04832906, 0.0847188, np.nan])
+ zeta = zeta0[[ind1, ind2]]
+ return zeta
+
+ # ------------- Computing VBI ------------- #
+ def VBI_cross_section(self, freq1, freq2,
+ zeta_freq1, zeta_freq2,
+ j_cross_section_freq1, j_cross_section_freq2,
+ r2D,
+ water_attenuation_freq1, water_attenuation_freq2,
+ X):
+
+ # print('self.zeta_exp[ind_j].shape', self.zeta_exp[ind_j])
+ # print('np.log(self.j_cross_section[:, ind_i, :]).shape', np.log(self.j_cross_section[:, ind_i, :]).shape)
+ # print('self.r_3D[:, ind_i, :]', self.r_3D[:, ind_i, :].shape)
+ # print('self.water_attenuation[ind_i]', self.water_attenuation[ind_i])
+ # print('self.x_exp[0.3-1 MHz]', self.x_exp['0.3-1 MHz'].values[0])
+ # print("start computing VBI")
+
+ logVBI = ((zeta_freq2 *
+ np.log(j_cross_section_freq1 * np.exp(4 * r2D * water_attenuation_freq1) /
+ (freq1 ** X)) -
+ zeta_freq1 *
+ np.log(j_cross_section_freq2 * np.exp(4 * r2D * water_attenuation_freq2) /
+ (freq2 ** X))) /
+ (zeta_freq2 - zeta_freq1))
+
+ print("compute VBI finished")
+
+ return np.exp(logVBI)
+
+ # ------------- Computing SSC fine ------------- #
+ def SSC_fine(self, zeta, r2D, VBI, freq, X, j_cross_section):
+ SSC_fine = (1/zeta) * ( 1/(4 * r2D) * np.log((VBI * freq**X) / j_cross_section) )
+ print("compute SSC fine finished")
+ return SSC_fine
+
+ # ------------- Computing SSC sand ------------- #
+ def SSC_sand(self, VBI, freq, X, ks):
+ SSC_sand = (16 * np.pi * VBI * freq ** X) / (3 * ks**2)
+ print("compute SSC sand finished")
+ return SSC_sand
+
+
diff --git a/View/acoustic_data_tab.py b/View/acoustic_data_tab.py
index bc9db1d..e450345 100644
--- a/View/acoustic_data_tab.py
+++ b/View/acoustic_data_tab.py
@@ -327,9 +327,9 @@ class AcousticDataTab(QWidget):
self.verticalLayout_display_option.addWidget(self.groupbox_xaxis_time)
self.gridLayout_groupbox_xaxis_time = QGridLayout(self.groupbox_xaxis_time)
- self.label_from = QLabel()
- self.label_from.setText("From")
- self.gridLayout_groupbox_xaxis_time.addWidget(self.label_from, 0, 0, 1, 1)
+ self.label_from_time = QLabel()
+ self.label_from_time.setText("From")
+ self.gridLayout_groupbox_xaxis_time.addWidget(self.label_from_time, 0, 0, 1, 1)
self.label_tmin = QLabel()
self.label_tmin.setText("tmin = ")
@@ -345,9 +345,9 @@ class AcousticDataTab(QWidget):
self.label_tmin_unit.setText("sec")
self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmin_unit, 0, 3, 1, 1)
- self.label_to = QLabel()
- self.label_to.setText("to")
- self.gridLayout_groupbox_xaxis_time.addWidget(self.label_to, 0, 4, 1, 1)
+ self.label_to_time = QLabel()
+ self.label_to_time.setText("to")
+ self.gridLayout_groupbox_xaxis_time.addWidget(self.label_to_time, 0, 4, 1, 1)
self.label_tmax = QLabel()
self.label_tmax.setText("tmax = ")
@@ -356,13 +356,19 @@ class AcousticDataTab(QWidget):
self.spinbox_tmax = QDoubleSpinBox()
self.spinbox_tmax.setRange(0, 9999)
self.gridLayout_groupbox_xaxis_time.addWidget(self.spinbox_tmax, 0, 6, 1, 1)
- self.spinbox_tmax.valueChanged.connect(self.update_xaxis_transect_with_BS_raw_data)
- self.spinbox_tmax.valueChanged.connect(self.update_xaxis_transect_with_SNR_data)
+ # self.spinbox_tmax.valueChanged.connect(self.update_xaxis_transect_with_BS_raw_data)
+ # self.spinbox_tmax.valueChanged.connect(self.update_xaxis_transect_with_SNR_data)
self.label_tmax_unit = QLabel()
self.label_tmax_unit.setText("sec")
self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmax_unit, 0, 7, 1, 1)
+ self.pushbutton_apply_transect_boundaries_in_time = QPushButton()
+ self.pushbutton_apply_transect_boundaries_in_time.setText("Apply")
+ self.gridLayout_groupbox_xaxis_time.addWidget(self.pushbutton_apply_transect_boundaries_in_time, 0, 7, 1, 1)
+ self.pushbutton_apply_transect_boundaries_in_time.clicked.connect(self.update_xaxis_transect_with_BS_raw_data)
+ self.pushbutton_apply_transect_boundaries_in_time.clicked.connect(self.update_xaxis_transect_with_SNR_data)
+
# --- Group Box Plot x-axis in space ---
self.groupbox_xaxis_space = QGroupBox()
@@ -372,31 +378,44 @@ class AcousticDataTab(QWidget):
self.verticalLayout_display_option.addWidget(self.groupbox_xaxis_space)
self.gridLayout_groupbox_xaxis_space = QGridLayout(self.groupbox_xaxis_space)
- self.label_from = QLabel()
- self.label_from.setText("From")
- self.gridLayout_groupbox_xaxis_space.addWidget(self.label_from, 0, 0, 1, 1)
+ self.label_from_space = QLabel()
+ self.label_from_space.setText("From ")
+ self.gridLayout_groupbox_xaxis_space.addWidget(self.label_from_space, 0, 0, 1, 1)
+
self.label_xmin = QLabel()
self.label_xmin.setText("xmin = ")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmin, 0, 1, 1, 1)
+
self.spinbox_xmin = QSpinBox()
self.spinbox_xmin.setRange(0, 9999)
self.gridLayout_groupbox_xaxis_space.addWidget(self.spinbox_xmin, 0, 2, 1, 1)
+
self.label_xmin_m = QLabel()
self.label_xmin_m.setText("m")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmin_m, 0, 3, 1, 1)
- self.label_to = QLabel()
- self.label_to.setText("to")
- self.gridLayout_groupbox_xaxis_space.addWidget(self.label_to, 0, 4, 1, 1)
+
+ self.label_to_space = QLabel()
+ self.label_to_space.setText("to")
+ self.gridLayout_groupbox_xaxis_space.addWidget(self.label_to_space, 0, 4, 1, 1)
+
self.label_xmax = QLabel()
self.label_xmax.setText("xmax = ")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmax, 0, 5, 1, 1)
+
self.spinbox_xmax = QSpinBox()
self.spinbox_xmax.setRange(0, 9999)
self.gridLayout_groupbox_xaxis_space.addWidget(self.spinbox_xmax, 0, 6, 1, 1)
+
self.label_xmax_m = QLabel()
self.label_xmax_m.setText("m")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmax_m, 0, 7, 1, 1)
+ self.pushbutton_apply_transect_boundaries_in_space = QPushButton()
+ self.pushbutton_apply_transect_boundaries_in_space.setText("Apply")
+ self.gridLayout_groupbox_xaxis_space.addWidget(self.pushbutton_apply_transect_boundaries_in_space, 0, 8, 1, 1)
+ self.pushbutton_apply_transect_boundaries_in_space.clicked.connect(self.update_xaxis_transect_with_BS_raw_data)
+ self.pushbutton_apply_transect_boundaries_in_space.clicked.connect(self.update_xaxis_transect_with_SNR_data)
+
# --- Group Box bathymetry computation algorithm to detect and plot bottom of transect---
self.groupbox_compute_bathymetry = QGroupBox()
@@ -410,30 +429,44 @@ class AcousticDataTab(QWidget):
self.combobox_freq_choice = QComboBox()
# self.combobox_freq_choice.addItems(['', '0.3 MHz', '0.5 Mhz', '1 MHz', '5 MHz'])
self.gridlayout_compute_bathymetry.addWidget(self.combobox_freq_choice, 0, 0, 2, 1)
- self.gridlayout_compute_bathymetry.addWidget(self.label_from, 0, 1, 1, 1)
+
+ self.label_from_bathy = QLabel()
+ self.label_from_bathy.setText("From ")
+ self.gridlayout_compute_bathymetry.addWidget(self.label_from_bathy, 0, 1, 1, 1)
+
self.spinbox_depth_min = QSpinBox()
self.spinbox_depth_min.setRange(0, 9999)
self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_min, 0, 2, 1, 1)
+
self.label_depth_min_unit = QLabel()
self.label_depth_min_unit.setText("m")
self.gridlayout_compute_bathymetry.addWidget(self.label_depth_min_unit, 0, 3, 1, 1)
- self.gridlayout_compute_bathymetry.addWidget(self.label_to, 0, 4, 1, 1)
+
+ self.label_to_bathy = QLabel()
+ self.label_to_bathy.setText("to ")
+ self.gridlayout_compute_bathymetry.addWidget(self.label_to_bathy, 0, 4, 1, 1)
+
self.spinbox_depth_max = QSpinBox()
self.spinbox_depth_max.setRange(0, 99999)
self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_max, 0, 5, 1, 1)
+
self.label_depth_max_unit = QLabel()
self.label_depth_max_unit.setText("m")
self.gridlayout_compute_bathymetry.addWidget(self.label_depth_max_unit, 0, 6, 1, 1)
+
self.label_next_cell = QLabel()
self.label_next_cell.setText("Next cell : +/-")
self.gridlayout_compute_bathymetry.addWidget(self.label_next_cell, 1, 1, 1, 1)
+
self.doublespinbox_next_cell = QDoubleSpinBox()
self.doublespinbox_next_cell.setRange(0, 99999)
self.doublespinbox_next_cell.setDecimals(2)
self.gridlayout_compute_bathymetry.addWidget(self.doublespinbox_next_cell, 1, 2, 1, 1)
+
self.label_next_cell_unit = QLabel()
self.label_next_cell_unit.setText("m")
self.gridlayout_compute_bathymetry.addWidget(self.label_next_cell_unit, 1, 3, 1, 1)
+
self.pushbutton_compute_bathymetry_algorithm = QPushButton()
self.pushbutton_compute_bathymetry_algorithm.setText("Compute \n&& \nPlot")
self.gridlayout_compute_bathymetry.addWidget(self.pushbutton_compute_bathymetry_algorithm, 0, 7, 2, 1)
@@ -684,6 +717,7 @@ class AcousticDataTab(QWidget):
stg.BS_raw_data = acoustic_data._BS_raw_data
stg.BS_raw_data_reshape = acoustic_data.reshape_BS_raw_cross_section()
stg.r = acoustic_data._r
+ stg.r_2D = acoustic_data.compute_r_2D()
stg.r_reshape = acoustic_data.reshape_r()
stg.time = acoustic_data._time
stg.time_reshape = acoustic_data.reshape_t()
@@ -861,6 +895,8 @@ class AcousticDataTab(QWidget):
np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]]
stg.t = stg.time[np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]:
np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]]
+ stg.r_2D = stg.r_2D[:, np.where(np.round(stg.time, 2) == self.spinbox_tmin.value())[0][0]:
+ np.where(np.round(stg.time, 2) == self.spinbox_tmax.value())[0][0]]
for f in range(stg.freq.shape[0]):
self.axis_BS[f].cla()
diff --git a/View/acoustic_inversion_tab.py b/View/acoustic_inversion_tab.py
index e663060..92f8bf1 100644
--- a/View/acoustic_inversion_tab.py
+++ b/View/acoustic_inversion_tab.py
@@ -1,18 +1,28 @@
import sys
-from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication, QVBoxLayout, QHBoxLayout, QGroupBox
-from PyQt5.QtCore import QCoreApplication
+from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication, QVBoxLayout, QHBoxLayout, QGroupBox, QComboBox, \
+ QGridLayout, QLabel, QPushButton, QSpinBox
+from PyQt5.QtCore import QCoreApplication, Qt
+from PyQt5.QtGui import QStandardItemModel
import numpy as np
+
+from itertools import combinations
+
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm, BoundaryNorm, CSS4_COLORS
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
-
import Translation.constant_string as cs
+from checkable_combobox import CheckableComboBox
+
+import settings as stg
+
+from Model.acoustic_inversion_method_high_concentration import AcousticInversionMethodHighConcentration
+
_translate = QCoreApplication.translate
@@ -23,22 +33,141 @@ class AcousticInversionTab(QWidget):
def __init__(self, widget_tab):
super().__init__()
-#
-# self.verticalLayout_acoustic_inversion_tab = QVBoxLayout(widget_tab)
-#
-# self.horizontalLayout_Top_acousticInversionTab = QHBoxLayout()
-#
-# self.groupbox_AcousticInversionOption = QGroupBox()
-# # self.groupbox_AcousticInversionOption.setTitle("Acoustic inversion option")
-#
-# self.horizontalLayout_Top_acousticInversionTab.addWidget(self.groupbox_AcousticInversionOption)
-#
-# self.verticalLayout_acoustic_inversion_tab.addLayout(self.horizontalLayout_Top_acousticInversionTab, 4)
-#
-# self.horizontalLayout_Bottom_acousticInversionTab = QHBoxLayout()
-#
-# self.groupbox_sediment_concentration_2Dplot = QGroupBox()
-# # self.groupbox_sediment_concentration_2Dplot.setTitle("Fine and sand sediment concentration")
+ self.inv_hc = AcousticInversionMethodHighConcentration()
+
+ ### --- General layout of widgets ---
+
+ self.verticalLayoutMain = QVBoxLayout(widget_tab)
+
+ self.horizontalLayoutTop = QHBoxLayout()
+ self.verticalLayoutMain.addLayout(self.horizontalLayoutTop, 4) # 1O units is 100% , 1 units is 10%
+
+ self.horizontalLayoutBottom = QHBoxLayout()
+ self.verticalLayoutMain.addLayout(self.horizontalLayoutBottom, 6)
+
+ ### --- Layout of groupbox in the Top horizontal layout box
+
+ # Acoustic inversion Options | Acoustic inversion method Settings parameter
+
+ self.groupbox_acoustic_inversion_options = QGroupBox()
+ self.horizontalLayoutTop.addWidget(self.groupbox_acoustic_inversion_options, 3)
+
+ self.groupbox_acoustic_inversion_settings_parameter = QGroupBox()
+ self.horizontalLayoutTop.addWidget(self.groupbox_acoustic_inversion_settings_parameter, 7)
+
+ ### --- Layout of groupbox in the Bottom horizontal layout box
+
+ # Plot SSC 2D field | Plot SSC graph sample vs inversion
+
+ self.groupbox_SSC_2D_field = QGroupBox()
+ self.horizontalLayoutBottom.addWidget(self.groupbox_SSC_2D_field, 6)
+
+ self.groupbox_SSC_sample_vs_inversion = QGroupBox()
+ self.horizontalLayoutBottom.addWidget(self.groupbox_SSC_sample_vs_inversion, 4)
+
+ # =====================================================
+ # TOP HORIZONTAL BOX LAYOUT
+ # =====================================================
+
+ # +++++++++++++++++++++++++++++++++++++++++++++++
+ # | Group box Acoustic inversion options |
+ # +++++++++++++++++++++++++++++++++++++++++++++++
+
+ self.gridLayout_groupbox_acoustic_inversion_options = QGridLayout(self.groupbox_acoustic_inversion_options)
+
+ self.groupbox_acoustic_inversion_options.setTitle("Acoustic inversion option")
+
+ self.label_acoustic_inversion_method_choice = QLabel()
+ self.gridLayout_groupbox_acoustic_inversion_options.addWidget(
+ self.label_acoustic_inversion_method_choice, 0, 0, 1, 1)
+ self.label_acoustic_inversion_method_choice.setText("Acoustic inversion method : ")
+
+ self.combobox_acoustic_inversion_method_choice = QComboBox()
+ self.gridLayout_groupbox_acoustic_inversion_options.addWidget(
+ self.combobox_acoustic_inversion_method_choice, 0, 1, 1, 1)
+ self.combobox_acoustic_inversion_method_choice.addItems([" ", "Acoustic inversion method 1"])
+ self.combobox_acoustic_inversion_method_choice.currentIndexChanged.connect(
+ self.acoustic_inversion_method_choice)
+
+ self.label_sample_choice = QLabel()
+ self.gridLayout_groupbox_acoustic_inversion_options.addWidget(self.label_sample_choice, 1, 0, 1, 1)
+ self.label_sample_choice.setText("Calibration samples : ")
+
+ self.combobox_calibration_samples = CheckableComboBox()
+ self.gridLayout_groupbox_acoustic_inversion_options.addWidget(self.combobox_calibration_samples, 1, 1, 1, 1)
+ self.combobox_calibration_samples.currentIndexChanged.connect(self.sample_choice)
+
+
+ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ # | Group box Acoustic inversion method settings parameter |
+ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter \
+ = QGridLayout(self.groupbox_acoustic_inversion_settings_parameter)
+
+ self.groupbox_acoustic_inversion_settings_parameter.setTitle("Acoustic inversion method settings parameter")
+
+ self.label_temperature = QLabel()
+ self.label_temperature.setText("Temperature : ")
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.label_temperature, 0, 0, 1, 1)
+ self.spinbox_temperature = QSpinBox()
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.spinbox_temperature, 0, 1, 1, 1)
+ self.spinbox_temperature.valueChanged.connect(self.temperature_value)
+
+ self.label_frequencies_pairs_to_compute_VBI = QLabel()
+ self.label_frequencies_pairs_to_compute_VBI.setText("frequencies for VBI : ")
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(
+ self.label_frequencies_pairs_to_compute_VBI, 1, 0, 1, 1)
+
+ self.combobox_frequencies_VBI = CheckableComboBox()
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(
+ self.combobox_frequencies_VBI, 1, 1, 1, 1)
+ self.combobox_frequencies_VBI.currentIndexChanged.connect(self.frequencies_pair_choice_to_compute_VBI)
+
+ self.label_frequency_to_compute_SSC = QLabel()
+ self.label_frequency_to_compute_SSC.setText("frequencies for SSC : ")
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(
+ self.label_frequency_to_compute_SSC, 2, 0, 1, 1)
+
+ self.combobox_frequency_SSC = CheckableComboBox()
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(
+ self.combobox_frequency_SSC, 2, 1, 1, 1)
+ self.combobox_frequency_SSC.currentIndexChanged.connect(self.frequency_choice_to_compute_SSC)
+
+ self.pushbutton_run = QPushButton()
+ self.pushbutton_run.setText("RUN")
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.pushbutton_run, 3, 0, 1, 1)
+ self.pushbutton_run.clicked.connect(self.compute_acoustic_inversion_method_high_concentration)
+
+ self.pushbutton_plot = QPushButton()
+ self.pushbutton_plot.setText("PLOT")
+ self.gridLayout_groupbox_acoustic_inversion_settings_parameter.addWidget(self.pushbutton_plot, 3, 1, 1, 1)
+ self.pushbutton_plot.clicked.connect(self.plot_SSC_2D_fields)
+ self.pushbutton_plot.clicked.connect(self.plot_SSC_inverse_VS_measured)
+
+ # =====================================================
+ # BOTTOM HORIZONTAL BOX LAYOUT
+ # =====================================================
+
+ # +++++++++++++++++++++++++++++++++++++++++++++++
+ # | Group box SSC 2D field |
+ # +++++++++++++++++++++++++++++++++++++++++++++++
+
+ self.verticalLayout_groupbox_SSC_2D_field = QVBoxLayout(self.groupbox_SSC_2D_field)
+
+ self.groupbox_SSC_2D_field.setTitle("Suspended Sediment Concentration 2D plot")
+
+ self.canvas_SSC_2D_field = None
+
+ # +++++++++++++++++++++++++++++++++++++++++++++++
+ # | Group box plot samples vs inversion |
+ # +++++++++++++++++++++++++++++++++++++++++++++++
+
+ self.verticalLayout_groupbox_SSC_sample_vs_inversion = QVBoxLayout(self.groupbox_SSC_sample_vs_inversion)
+
+ self.groupbox_SSC_sample_vs_inversion.setTitle("Suspended Sediment Concentration : sample vs inversion")
+
+ self.canvas_SSC_sample_vs_inversion = None
#
# self.verticalLayout_groupbox_sediment_concentration_2Dplot = QVBoxLayout(self.groupbox_sediment_concentration_2Dplot)
#
@@ -53,7 +182,7 @@ class AcousticInversionTab(QWidget):
# # self.horizontalLayout_Bottom_acousticInversionTab.addWidget(self.canvas_sediments2DPlot)
# self.horizontalLayout_Bottom_acousticInversionTab.addWidget(self.groupbox_sediment_concentration_2Dplot, 7)
#
-# self.groupbox_sediment_concentration_sample_vs_measurement = QGroupBox()
+#
# # self.groupbox_sediment_concentration_sample_vs_measurement.setTitle(
# # "Suspended sediment concentration plot : acoustic inversion theory VS measurements")
#
@@ -75,68 +204,252 @@ class AcousticInversionTab(QWidget):
# self.verticalLayout_acoustic_inversion_tab.addLayout(self.horizontalLayout_Bottom_acousticInversionTab, 6)
#
# self.retranslate_acoustic_inversion_tab()
-#
-# # ---------------------------------------------------------------------------------------------
-# # -------------------- Functions --------------------
-# # ---------------------------------------------------------------------------------------------
-#
+
+ # ----------------------------------------------------------------------------------------------------------------
+ # -------------------- Functions --------------------
+
# def retranslate_acoustic_inversion_tab(self):
#
# self.groupbox_AcousticInversionOption.setTitle(_translate("CONSTANT_STRING", cs.ACOUSTIC_INVERSION_OPTIONS))
# self.groupbox_sediment_concentration_2Dplot.setTitle(_translate("CONSTANT_STRING", cs.FINE_AND_SAND_SEDIMENTS_CONCENTRATION_2D_FIELD))
# self.groupbox_sediment_concentration_sample_vs_measurement.setTitle(_translate("CONSTANT_STRING", cs.SUSPENDED_SEDIMENT_CONCENTRATION_PLOT))
-#
-# def plot_SSC_fine(self):
-# frequency = 0
-# val_min = 1e-2 #np.nanmin(self.model.SSC_fine[:, :]) #
-# val_max = 15 #np.nanmax(self.model.SSC_fine[:, :]) #
-# # print('val_min=', val_min)
-# # print('val_max=', val_max)
-# # if val_min == 0:
-# # val_min = 0.5
-# # print('val_min update =', val_min)
-# pcm_SSC_fine = self.axis_SSC_2Dplot[0].pcolormesh(self.model.dist_BS_section, np.flipud(self.model.BS_averaged_cross_section.r),
-# self.model.SSC_fine[:, :],
-# cmap='rainbow', norm=LogNorm(vmin=val_min, vmax=val_max), shading='gouraud')
-# self.axis_SSC_2Dplot[0].plot(self.model.dist_BS_section,
-# np.max(self.model.r_bottom_cross_section) - self.model.r_bottom_cross_section
-# + np.min(self.model.r_bottom_cross_section),
-# color='k', linewidth=2)
-# self.figure_SSC_2Dplot.supxlabel("Distance from left bank (m)", fontsize=10)
-# self.figure_SSC_2Dplot.supylabel("Depth (m)", fontsize=10)
-# self.figure_SSC_2Dplot.tight_layout()
-#
-# cbar_SSC_fine = self.figure_SSC_2Dplot.colorbar(pcm_SSC_fine, ax=self.axis_SSC_2Dplot[0], shrink=1, location='right')
-# cbar_SSC_fine.set_label(label='Fine SSC (g/L', rotation=270, labelpad=15)
-#
-# def plot_SSC_sand(self):
-# frequency = 0
-# val_min = 1e-2 #np.nanmin(self.model.SSC_fine[:, :]) #
-# val_max = 2 #np.nanmax(self.model.SSC_fine[:, :]) #
-# # print('val_min=', val_min)
-# # print('val_max=', val_max)
-# # if val_min == 0:
-# # val_min = 0.5
-# # print('val_min update =', val_min)
-# pcm_SSC_sand = self.axis_SSC_2Dplot[1].pcolormesh(self.model.dist_BS_section, np.flipud(self.model.BS_averaged_cross_section.r),
-# self.model.SSC_sand[:, :],
-# cmap='rainbow', norm=LogNorm(vmin=val_min, vmax=val_max), shading='gouraud')
-# self.axis_SSC_2Dplot[1].plot(self.model.dist_BS_section,
-# np.max(self.model.r_bottom_cross_section) - self.model.r_bottom_cross_section
-# + np.min(self.model.r_bottom_cross_section),
-# color='k', linewidth=2)
-# self.figure_SSC_2Dplot.supxlabel("Distance from left bank (m)", fontsize=10)
-# self.figure_SSC_2Dplot.supylabel("Depth (m)", fontsize=10)
-# self.figure_SSC_2Dplot.tight_layout()
-#
-# cbar_SSC_sand = self.figure_SSC_2Dplot.colorbar(pcm_SSC_sand, ax=self.axis_SSC_2Dplot[1], shrink=1, location='right')
-# cbar_SSC_sand.set_label(label='Sand SSC (g/L', rotation=270, labelpad=15)
-#
-# # if __name__ == "__main__":
-# # app = QApplication(sys.argv)
-# # print("class acoustic inversion tab :", AcousticInversionTab())
-# # sys.exit(app.exec_())
-#
-#
+
+ def acoustic_inversion_method_choice(self):
+ if self.combobox_acoustic_inversion_method_choice.currentIndex() == 1:
+
+ # --- add items in combobox of samples to calibrate acoustic inversion method ---
+ samples_vertical_line = np.split(stg.samples, np.where(np.diff(stg.sample_time) != 0)[0]+1)
+
+ for s in samples_vertical_line:
+ self.combobox_calibration_samples.addItem(" - ".join([i for i in s]))
+
+ for i in range(len(samples_vertical_line)):
+ self.combobox_calibration_samples.setItemChecked(i, False)
+
+ # --- add items in combobox of frequencies for VBI computation ---
+ for k in combinations(stg.freq_text, 2):
+ self.combobox_frequencies_VBI.addItem(k[0] + " - " + k[1])
+ # print(k)
+ for i in range(len(list(combinations(stg.freq_text, 2)))):
+ self.combobox_frequencies_VBI.setItemChecked(i, False)
+
+ def sample_choice(self):
+ sample_position = []
+ for i in range(self.combobox_calibration_samples.count()):
+ if self.combobox_calibration_samples.itemChecked(i):
+ sample_position.append(i)
+ elif (i in sample_position) and (not self.combobox_calibration_samples.itemChecked(i)):
+ sample_position.remove(i)
+
+ def frequencies_pair_choice_to_compute_VBI(self):
+ freq_combination = list(combinations(stg.freq, 2))
+ frequencies_position = []
+ for i in range(self.combobox_frequencies_VBI.count()):
+ if self.combobox_frequencies_VBI.itemChecked(i):
+ frequencies_position.append(i)
+ elif (i in frequencies_position) and (not self.combobox_frequencies_VBI.itemChecked(i)):
+ frequencies_position.remove(i)
+
+ if len(frequencies_position) != 0:
+ # print(frequencies_position)
+ # print(freq_combination[frequencies_position[0]][0], freq_combination[frequencies_position[0]][1])
+ stg.frequencies_pair = (
+ np.array([[int(np.where(stg.freq == freq_combination[frequencies_position[0]][0])[0][0]),
+ freq_combination[frequencies_position[0]][0]],
+ [int(np.where(stg.freq == freq_combination[frequencies_position[0]][1])[0][0]),
+ 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 ---
+ for k in range(stg.frequencies_pair.shape[0]):
+ self.combobox_frequency_SSC.addItem(str(1e-6*stg.frequencies_pair[k, 1]) + " MHz")
+ for i in range(stg.frequencies_pair.shape[0]):
+ self.combobox_frequency_SSC.setItemChecked(i, False)
+
+ def frequency_choice_to_compute_SSC(self, index):
+ # print(self.combobox_frequency_SSC.currentText())
+ # print(self.combobox_frequency_SSC.currentIndex())
+ # print(self.combobox_frequency_SSC.itemChecked(index))
+
+
+ if self.combobox_frequency_SSC.itemChecked(index):
+ # # itemChecked(index)): # currentIndex() == 0) or (self.combobox_frequency_SSC.currentIndex() == 1):
+ # print(self.combobox_frequency_SSC.currentText())
+ # print(stg.freq_text)
+ # print(np.where(np.array(stg.freq_text) == self.combobox_frequency_SSC.currentText()))
+ stg.frequency_to_compute_SSC \
+ = 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])]])
+ # print("stg.frequency_to_compute_SSC ", stg.frequency_to_compute_SSC)
+
+ def temperature_value(self):
+ stg.temperature = self.spinbox_temperature.value()
+ # print(stg.temperature)
+
+ 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)
+ # print("water attenuation ", stg.water_attenuation)
+
+ stg.water_velocity = self.inv_hc.water_velocity(stg.temperature)
+ # print("water velocity ", 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_tx[[int(stg.frequencies_pair[0, 0]), int(stg.frequencies_pair[1, 0])]],
+ stg.kt[[int(stg.frequencies_pair[0, 0]), int(stg.frequencies_pair[1, 0])]])
+ # print("kt ", stg.kt_corrected)
+ # print("kt shape ", stg.kt_corrected.shape)
+
+ stg.kt_corrected_2D = np.repeat(stg.kt_corrected, stg.r.shape[0], axis=0)
+ # print("kt 2D ", stg.kt_corrected_2D)
+ # print("kt 2D shape ", stg.kt_corrected_2D.shape)
+ stg.kt_corrected_3D = np.zeros((stg.kt_corrected_2D.shape[1], stg.kt_corrected_2D.shape[0], stg.t.shape[0]))
+ # print("stg.t.shape ", stg.t.shape)
+ # print("kt corrected 3D zeros shape ", stg.kt_corrected_3D.shape)
+ for k in range(stg.kt_corrected_2D.shape[1]):
+ stg.kt_corrected_3D[k, :, :] = np.repeat(stg.kt_corrected_2D, stg.t.shape[0], axis=1)[:, k*stg.t.shape[0]:(k+1)*stg.t.shape[0]]
+ print("kt 3D ", stg.kt_corrected_3D)
+ 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))
+
+ 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])], :],
+ stg.r_2D,
+ stg.kt_corrected_3D)
+ print("J ", stg.J_cross_section)
+ print("J sahpe ", stg.J_cross_section.shape)
+
+ stg.X_exponent = self.inv_hc.X_exponent(self.combobox_frequencies_VBI.currentIndex())
+ print("X ", stg.X_exponent)
+
+ stg.zeta = self.inv_hc.zeta(int(stg.frequencies_pair[0, 0]), int(stg.frequencies_pair[1, 0]))
+ 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]))
+ 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.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.J_cross_section[0, :, :],
+ stg.J_cross_section[1, :, :],
+ stg.r_2D,
+ stg.water_attenuation[0],
+ stg.water_attenuation[1],
+ stg.X_exponent)
+ # print("VBI shape ", stg.VBI_cross_section.shape)
+ # print(int(self.combobox_frequency_SSC.currentIndex()))
+ # print(stg.zeta[int(self.combobox_frequency_SSC.currentIndex())])
+
+ stg.SSC_fine = self.inv_hc.SSC_fine(stg.zeta[int(self.combobox_frequency_SSC.currentIndex())],
+ stg.r_2D,
+ stg.VBI_cross_section,
+ stg.frequency_to_compute_SSC[1],
+ stg.X_exponent,
+ stg.J_cross_section[self.combobox_frequency_SSC.currentIndex(), :, :])
+ # print("SSC fine shape ", stg.SSC_fine.shape)
+
+ stg.SSC_sand = self.inv_hc.SSC_sand(stg.VBI_cross_section,
+ stg.frequency_to_compute_SSC[1],
+ stg.X_exponent,
+ stg.ks)
+
+ # print("SSC sand shape ", stg.SSC_sand.shape)
+
+ def plot_SSC_2D_fields(self):
+
+ if self.canvas_SSC_2D_field == None:
+
+ self.figure_SSC_2D_field, self.axis_SSC_2D_field = plt.subplots(nrows=2, ncols=1, layout="constrained")
+ self.canvas_SSC_2D_field = FigureCanvas(self.figure_SSC_2D_field)
+ self.verticalLayout_groupbox_SSC_2D_field.addWidget(self.canvas_SSC_2D_field)
+
+ self.plot_SSC_fine()
+ self.plot_SSC_sand()
+
+ def plot_SSC_fine(self):
+
+ val_min = 1e-2 #np.nanmin(self.model.SSC_fine[:, :]) #
+ val_max = 15 #np.nanmax(self.model.SSC_fine[:, :]) #
+ # print('val_min=', val_min)
+ # print('val_max=', val_max)
+ # if val_min == 0:
+ # val_min = 0.5
+ # 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, :, :],
+ cmap='rainbow',
+ # norm=LogNorm(vmin=val_min, vmax=val_max),
+ shading='gouraud')
+
+ 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.supylabel("Depth (m)", fontsize=10)
+
+ cbar_SSC_fine = self.figure_SSC_2D_field.colorbar(pcm_SSC_fine, ax=self.axis_SSC_2D_field[0], shrink=1, location='right')
+ cbar_SSC_fine.set_label(label='Fine SSC (g/L', rotation=270, labelpad=15)
+
+ self.figure_SSC_2D_field.canvas.draw_idle()
+
+ def plot_SSC_sand(self):
+
+ val_min = np.nanmin(stg.VBI_cross_section) #1e-2 #np.nanmin(self.model.SSC_fine[:, :]) #
+ val_max = np.nanmax(stg.VBI_cross_section) #15 #np.nanmax(self.model.SSC_fine[:, :]) #
+ # print('val_min=', val_min)
+ # print('val_max=', val_max)
+ # if val_min == 0:
+ # val_min = 0.5
+ # 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, :, :],
+ cmap='rainbow',
+ # vmin=val_min, vmax=val_max,
+ # norm=LogNorm(vmin=val_min, vmax=val_max),
+ shading='gouraud')
+
+ 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.supylabel("Depth (m)", fontsize=10)
+
+ cbar_SSC_sand = self.figure_SSC_2D_field.colorbar(pcm_SSC_sand, ax=self.axis_SSC_2D_field[1], shrink=1, location='right')
+ cbar_SSC_sand.set_label(label='Sand SSC (g/L', rotation=270, labelpad=15)
+ self.figure_SSC_2D_field.canvas.draw_idle()
+
+ def plot_SSC_inverse_VS_measured(self):
+
+ sample_depth_position = []
+ for i in range(stg.sample_depth.shape[0]):
+ sample_depth_position.append(
+ np.where(np.abs(stg.r + stg.sample_depth[i]) == np.min(np.abs(stg.r + stg.sample_depth[i])))[0][0])
+
+ sample_time_position = []
+ for j in range(stg.sample_time.shape[0]):
+ sample_time_position.append(
+ np.where(np.abs(stg.t - stg.sample_time[j]) == np.min(np.abs(stg.t - stg.sample_time[j])))[0][0])
+
+ if self.canvas_SSC_sample_vs_inversion == None:
+
+ 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.verticalLayout_groupbox_SSC_sample_vs_inversion.addWidget(self.canvas_SSC_sample_vs_inversion)
+
+ self.axis_SSC_sample_vs_inversion.plot(stg.Ctot_fine, stg.SSC_fine[sample_depth_position, sample_time_position], ls=" ", marker='v', color='black', label='Fine 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_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.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.legend()
+
diff --git a/View/checkable_combobox.py b/View/checkable_combobox.py
new file mode 100644
index 0000000..d0f31b1
--- /dev/null
+++ b/View/checkable_combobox.py
@@ -0,0 +1,33 @@
+from PyQt5.QtWidgets import QComboBox
+from PyQt5.QtCore import Qt
+
+
+class CheckableComboBox(QComboBox):
+ def __init__(self):
+ super().__init__()
+ self._changed = False
+ self.view().pressed.connect(self.handleItemPressed)
+
+ def setItemChecked(self, index, checked=False):
+ item = self.model().item(index, self.modelColumn()) # QStandardItem object
+ if checked:
+ item.setCheckState(Qt.Checked)
+ else:
+ item.setCheckState(Qt.Unchecked)
+
+ def handleItemPressed(self, index):
+ item = self.model().itemFromIndex(index)
+ if item.checkState() == Qt.Checked:
+ item.setCheckState(Qt.Unchecked)
+ else:
+ item.setCheckState(Qt.Checked)
+ self._changed = True
+
+ def hidePopup(self):
+ if not self._changed:
+ super().hidePopup()
+ self._changed = False
+
+ def itemChecked(self, index):
+ item = self.model().item(index, self.modelColumn())
+ return item.checkState() == Qt.Checked
\ No newline at end of file
diff --git a/View/sample_data_tab.py b/View/sample_data_tab.py
index ed9e406..15e3c39 100644
--- a/View/sample_data_tab.py
+++ b/View/sample_data_tab.py
@@ -415,8 +415,9 @@ class SampleDataTab(QWidget):
# horizontal_header = list(map(str, ["Color", "Sample"] + stg.fine_sediment_columns +
# stg.sand_sediment_columns[2:]))
horizontal_header = list(itertools.chain(["Color", "Sample"],
- list(map(str, stg.fine_sediment_columns.values)),
- list(map(str, stg.sand_sediment_columns[2:]))))
+ list(map(str, stg.fine_sediment_columns[:2])),
+ list(map(str, stg.fine_sediment_columns[3:])),
+ list(map(str, stg.sand_sediment_columns[3:]))))
for horizontal_header_text in horizontal_header:
# print(horizontal_header_text)
@@ -447,7 +448,8 @@ class SampleDataTab(QWidget):
self.item_checkbox = QTableWidgetItem()
self.item_checkbox.setCheckState(Qt.Unchecked)
self.tableWidget_sample.setItem(i, 1, self.item_checkbox)
- self.item_checkbox.setText("S " + str(i + 1))
+ self.item_checkbox.setText("S" + str(i + 1))
+ stg.samples.append("S" + str(i + 1))
# print(f"S{i+1} ", self.tableWidget_sample.item(i, 1).checkState())
# --- Fill table with data ---
diff --git a/View/signal_processing_tab.py b/View/signal_processing_tab.py
index 50aa9d3..5b2a144 100644
--- a/View/signal_processing_tab.py
+++ b/View/signal_processing_tab.py
@@ -1,7 +1,7 @@
import sys
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QGroupBox, QLabel, QCheckBox, \
- QSpinBox, QDoubleSpinBox, QComboBox, QLineEdit, QSlider, QGridLayout
+ QSpinBox, QDoubleSpinBox, QComboBox, QLineEdit, QSlider, QGridLayout, QMessageBox
from PyQt5.QtGui import QFont, QIcon, QPixmap
from PyQt5.QtCore import Qt, QCoreApplication
@@ -83,7 +83,7 @@ class SignalProcessingTab(QWidget):
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.plot_profile_position_on_transect)
- self.pushbutton_load_data.clicked.connect(self.plot_profiles)
+ 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)
@@ -162,26 +162,27 @@ class SignalProcessingTab(QWidget):
self.gridLayout_groupbox_acoustic_profile = QGridLayout(self.groupbox_acoustic_profile)
- self.checkbox_SNR_criterion = QCheckBox()
- self.gridLayout_groupbox_acoustic_profile.addWidget(self.checkbox_SNR_criterion, 0, 0, 1, 1)
+ # 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.spinbox_SNR_criterion.setDisabled(True)
self.gridLayout_groupbox_acoustic_profile.addWidget(self.spinbox_SNR_criterion, 0, 1, 1, 1)
- self.checkbox_SNR_criterion.clicked.connect(self.enable_disable_spinbox_snr_value)
+ # self.checkbox_SNR_criterion.clicked.connect(self.enable_disable_spinbox_snr_value)
+ 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.pushbutton_snr_filter.setDisabled(True)
+ # self.pushbutton_snr_filter.setDisabled(True)
self.gridLayout_groupbox_acoustic_profile.addWidget(self.pushbutton_snr_filter, 0, 2, 1, 1)
- self.spinbox_SNR_criterion.valueChanged.connect(self.remove_point_with_snr_filter)
# self.spinbox_SNR_criterion.valueChanged.connect(self.update_plot_profiles)
# self.spinbox_SNR_criterion.valueChanged.connect(self.update_plot_profile_position_on_transect)
- self.pushbutton_snr_filter.clicked.connect(self.update_plot_profiles)
+ self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile)
# self.pushbutton_snr_filter.clicked.connect(self.remove_point_with_snr_filter)
# self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile_position_on_transect)
@@ -190,7 +191,7 @@ class SignalProcessingTab(QWidget):
self.horizontalLayout_groupbox_window_size = QHBoxLayout(self.groupbox_window_size)
self.label_signal_averaging_over = QLabel()
- self.label_signal_averaging_over.setText("Signal averaging over ")
+ self.label_signal_averaging_over.setText("Signal averaging over +/- ")
self.horizontalLayout_groupbox_window_size.addWidget(self.label_signal_averaging_over)
self.spinbox_average = QSpinBox()
self.spinbox_average.setRange(0, 9999)
@@ -199,6 +200,15 @@ class SignalProcessingTab(QWidget):
self.label_cells = QLabel()
self.horizontalLayout_groupbox_window_size.addWidget(self.label_cells)
+ 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.pushbutton_average.clicked.connect(self.plot_averaged_profile)
+
# --- Groupbox Rayleigh criterion ---
# # self.groupbox_rayleigh_criterion.setTitle("Rayleigh criterion")
@@ -566,7 +576,8 @@ class SignalProcessingTab(QWidget):
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_profiles)
+ self.slider.valueChanged.connect(self.update_plot_profile)
+ self.slider.valueChanged.connect(self.update_plot_averaged_profile)
self.retranslate_signal_processing_tab()
@@ -583,7 +594,7 @@ class SignalProcessingTab(QWidget):
self.groupbox_acoustic_profile.setTitle(_translate("CONSTANT_STRING", cs.ACOUSTIC_PROFILE))
# self.checkbox_substract_noise.setText(_translate("CONSTANT_STRING", cs.SUBTRACT_THE_NOISE))
- self.checkbox_SNR_criterion.setText(_translate("CONSTANT_STRING", cs.SNR_CRITERION))
+ 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) + ": +/-")
@@ -621,13 +632,13 @@ class SignalProcessingTab(QWidget):
def update_lineEdit_by_moving_slider(self):
self.lineEdit_slider.setText(str(self.slider.value()))
- def enable_disable_spinbox_snr_value(self):
- if self.checkbox_SNR_criterion.isChecked():
- self.spinbox_SNR_criterion.setEnabled(True)
- self.pushbutton_snr_filter.setEnabled(True)
- else:
- self.spinbox_SNR_criterion.setDisabled(True)
- self.pushbutton_snr_filter.setDisabled(True)
+ # def enable_disable_spinbox_snr_value(self):
+ # if self.checkbox_SNR_criterion.isChecked():
+ # self.spinbox_SNR_criterion.setEnabled(True)
+ # self.pushbutton_snr_filter.setEnabled(True)
+ # else:
+ # self.spinbox_SNR_criterion.setDisabled(True)
+ # self.pushbutton_snr_filter.setDisabled(True)
def remove_point_with_snr_filter(self):
@@ -654,56 +665,56 @@ class SignalProcessingTab(QWidget):
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)
- if stg.r_bottom.size == 0:
+ # if stg.r_bottom.size == 0:
- val_min = np.min(stg.BS_data[:, stg.freq_bottom_detection, :])
- val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :])
- if val_min == 0:
- val_min = 1e-5
+ val_min = np.min(stg.BS_data[:, stg.freq_bottom_detection, :])
+ val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :])
+ if val_min == 0:
+ val_min = 1e-5
- pcm = self.axis_plot_profile_position_on_transect.pcolormesh(
- stg.t, -stg.r, stg.BS_data[:, 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")
+ pcm = self.axis_plot_profile_position_on_transect.pcolormesh(
+ stg.t, -stg.r, stg.BS_data[:, 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[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r,
- color='red', linestyle="solid", linewidth=2)
+ stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid")
- self.figure_plot_profile_position_on_transect.canvas.draw_idle()
+ 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)
- else:
+ self.figure_plot_profile_position_on_transect.canvas.draw_idle()
- stg.BS_data_section = deepcopy(stg.BS_data)
+ # else:
- 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
- # print("----------------------------------------------------------")
+ # stg.BS_data_section = deepcopy(stg.BS_data)
- val_min = np.min(stg.BS_data_section[:, stg.freq_bottom_detection, :])
- val_max = np.max(stg.BS_data_section[:, stg.freq_bottom_detection, :])
- if val_min == 0:
- val_min = 1e-5
+ # 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
+ # # print("----------------------------------------------------------")
- pcm = 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.figure_plot_profile_position_on_transect.canvas.draw_idle()
+ # val_min = np.min(stg.BS_data_section[:, stg.freq_bottom_detection, :])
+ # val_max = np.max(stg.BS_data_section[:, stg.freq_bottom_detection, :])
+ # if val_min == 0:
+ # val_min = 1e-5
+ #
+ # pcm = 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.figure_plot_profile_position_on_transect.canvas.draw_idle()
def update_plot_profile_position_on_transect(self):
@@ -714,55 +725,55 @@ class SignalProcessingTab(QWidget):
# --- Update transect plot ---
if self.canvas_plot_profile_position_on_transect != None:
+ # if stg.r_bottom.size != 0:
+
+ self.axis_plot_profile_position_on_transect.cla()
+
+ val_min = np.min(stg.BS_data[:, self.combobox_frequency.currentIndex(), :])
+ val_max = np.max(stg.BS_data[:, 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[:, 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.cla()
-
- val_min = np.min(stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :])
- val_max = np.max(stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :])
- if val_min == 0:
- val_min = 1e-5
-
- pcm = 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)
+ stg.t, -stg.r_bottom,
+ color='black', linewidth=1, linestyle="solid")
- self.figure_plot_profile_position_on_transect.canvas.draw_idle()
+ 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)
- else:
+ self.figure_plot_profile_position_on_transect.canvas.draw_idle()
- self.axis_plot_profile_position_on_transect.cla()
+ # else:
+ #
+ # self.axis_plot_profile_position_on_transect.cla()
+ #
+ # val_min = np.min(stg.BS_data[:, self.combobox_frequency.currentIndex(), :])
+ # val_max = np.max(stg.BS_data[:, self.combobox_frequency.currentIndex(), :])
+ # if val_min == 0:
+ # val_min = 1e-5
+ #
+ # pcm = self.axis_plot_profile_position_on_transect.pcolormesh(
+ # stg.t, -stg.r, stg.BS_data[:, 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.figure_plot_profile_position_on_transect.canvas.draw_idle()
- val_min = np.min(stg.BS_data[:, self.combobox_frequency.currentIndex(), :])
- val_max = np.max(stg.BS_data[:, self.combobox_frequency.currentIndex(), :])
- if val_min == 0:
- val_min = 1e-5
-
- pcm = self.axis_plot_profile_position_on_transect.pcolormesh(
- stg.t, -stg.r, stg.BS_data[:, 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.figure_plot_profile_position_on_transect.canvas.draw_idle()
-
- def plot_profiles(self):
+ def plot_profile(self):
# --- Raw profile ---
@@ -786,51 +797,46 @@ class SignalProcessingTab(QWidget):
self.figure_profile.canvas.draw_idle()
- # --- Raw averaged profile ---
+ # # --- Raw averaged profile ---
+ #
+ # self.figure_averaged_profile, self.axis_averaged_profile \
+ # = plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained')
+ # self.canvas_averaged_profile = FigureCanvas(self.figure_averaged_profile)
+ # self.verticalLayout_groupbox_plot_averaged_profile.addWidget(self.canvas_averaged_profile)
+ #
+ # for f in range(stg.freq.shape[0]):
+ # self.axis_averaged_profile[f].cla()
+ # self.axis_averaged_profile[f].plot(stg.BS_data[:, 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.figure_averaged_profile, self.axis_averaged_profile \
- = plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained')
- self.canvas_averaged_profile = FigureCanvas(self.figure_averaged_profile)
- self.verticalLayout_groupbox_plot_averaged_profile.addWidget(self.canvas_averaged_profile)
+ # # --- Raw FCB profile ---
+ #
+ # self.figure_FCB_profile, self.axis_FCB_profile \
+ # = plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained')
+ # self.canvas_FCB_profile = FigureCanvas(self.figure_FCB_profile)
+ # self.verticalLayout_groupbox_plot_FCB_profile.addWidget(self.canvas_FCB_profile)
- for f in range(stg.freq.shape[0]):
- self.axis_averaged_profile[f].cla()
- self.axis_averaged_profile[f].plot(stg.BS_data[:, 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))
+ def update_plot_profile(self):
- # --- Raw FCB profile ---
+ # if self.checkbox_SNR_criterion.isChecked():
- self.figure_FCB_profile, self.axis_FCB_profile \
- = plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained')
- self.canvas_FCB_profile = FigureCanvas(self.figure_FCB_profile)
- self.verticalLayout_groupbox_plot_FCB_profile.addWidget(self.canvas_FCB_profile)
+ # self.remove_point_with_snr_filter()
- def update_plot_profiles(self):
-
- if self.checkbox_SNR_criterion.isChecked():
-
- # self.remove_point_with_snr_filter()
+ if stg.BS_data_filter_snr.size == 0:
for f in range(stg.freq.shape[0]):
self.axis_profile[f].cla()
- self.axis_profile[f].plot(stg.BS_data_filter_snr[:, f, self.slider.value()-1], -stg.r,
- linestyle='solid', color='k', linewidth=1)
-
- # if stg.r_bottom.size != 0:
- # self.axis_profile[f].plot(
- # np.array([0, np.nanmax(stg.BS_data[:, stg.freq_bottom_detection, self.slider.value() - 1])]),
- # -stg.r_bottom[self.slider.value() - 1] * np.ones(2),
- # linestyle='dashed', color='red', linewidth=1)
-
+ self.axis_profile[f].plot(stg.BS_data[:, f, self.slider.value()-1], -stg.r,
+ linestyle='solid', color='k', linewidth=1)
self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
else:
for f in range(stg.freq.shape[0]):
self.axis_profile[f].cla()
- self.axis_profile[f].plot(stg.BS_data[:, f, self.slider.value()-1], -stg.r,
- linestyle='solid', color='k', linewidth=1)
+ self.axis_profile[f].plot(stg.BS_data_filter_snr[:, f, self.slider.value()-1], -stg.r,
+ linestyle='solid', color='k', linewidth=1)
# if stg.r_bottom.size != 0:
# self.axis_profile[f].plot(
@@ -840,10 +846,123 @@ class SignalProcessingTab(QWidget):
self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
+ # else:
+ #
+ # for f in range(stg.freq.shape[0]):
+ # self.axis_profile[f].cla()
+ # self.axis_profile[f].plot(stg.BS_data[:, f, self.slider.value()-1], -stg.r,
+ # linestyle='solid', color='k', linewidth=1)
+
+ # if stg.r_bottom.size != 0:
+ # self.axis_profile[f].plot(
+ # np.array([0, np.nanmax(stg.BS_data[:, stg.freq_bottom_detection, self.slider.value() - 1])]),
+ # -stg.r_bottom[self.slider.value() - 1] * np.ones(2),
+ # linestyle='dashed', color='red', linewidth=1)
+
+ # self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
+
self.figure_profile.canvas.draw_idle()
def compute_averaged_profile(self):
- pass
+ filter_convolve = np.ones(self.spinbox_average.value())
+
+ if stg.BS_data_filter_snr.size == 0:
+ stg.BS_data_averaged = np.zeros((stg.r.shape[0], stg.freq.shape[0], stg.t.shape[0]-self.spinbox_average.value()+1))
+ for f in range(stg.freq.shape[0]):
+ for i in range(stg.r.shape[0]):
+ stg.BS_data_averaged[i, f, :] = np.convolve(stg.BS_data[i, f, :], filter_convolve, mode='valid')
+ # stg.BS_data_averaged = np.concatenate((stg.BS_data[:, :, :np.int(self.spinbox_average.value()/2)],
+ # stg.BS_data_averaged,
+ # stg.BS_data[:, :, -np.int(self.spinbox_average.value()/2):]),
+ # axis=2)
+ # print(stg.BS_data_averaged.shape)
+ else:
+ stg.BS_data_averaged = np.zeros((stg.r.shape[0], stg.freq.shape[0], stg.t.shape[0]-self.spinbox_average.value()+1))
+ for f in range(stg.freq.shape[0]):
+ for i in range(stg.r.shape[0]):
+ stg.BS_data_averaged[i, f, :] = np.convolve(stg.BS_data_filter_snr[i, f, :], filter_convolve,
+ mode='valid')
+
+ self.label_cells.clear()
+ self.label_cells.setText("cells = +/- " + str((self.spinbox_average.value() // 2)*(1/stg.nb_profiles_per_sec)) + " sec")
+
+ def plot_averaged_profile(self):
+ # fig, ax = plt.subplots(nrows=1, ncols=1)
+ # ax.pcolormesh(stg.t[8:2232], -stg.r, stg.BS_data_averaged[:, 0, :],
+ # cmap='viridis',
+ # norm=LogNorm(vmin=1e-5, vmax=np.max(stg.BS_data_averaged[:, 0, :])))
+ # plt.show()
+
+ if self.canvas_averaged_profile != None:
+ for f in range(stg.freq.shape[0]):
+ self.axis_averaged_profile[f].cla()
+
+ self.figure_averaged_profile, self.axis_averaged_profile \
+ = plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained')
+ self.canvas_averaged_profile = FigureCanvas(self.figure_averaged_profile)
+ self.verticalLayout_groupbox_plot_averaged_profile.addWidget(self.canvas_averaged_profile)
+
+ if stg.BS_data_filter_snr.size == 0:
+
+ BS_concatenate = stg.BS_data_averaged = np.concatenate((stg.BS_data[:, :, :np.int(self.spinbox_average.value()/2)],
+ stg.BS_data_averaged,
+ stg.BS_data[:, :, -np.int(self.spinbox_average.value()/2):]),
+ axis=2)
+ for f in range(stg.freq.shape[0]):
+ self.axis_averaged_profile[f].cla()
+ self.axis_averaged_profile[f].plot(BS_concatenate[:, 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))
+ else:
+ BS_concatenate = stg.BS_data_averaged = np.concatenate((stg.BS_data_filter_snr[:, :, :np.int(self.spinbox_average.value() / 2)],
+ stg.BS_data_averaged,
+ stg.BS_data_filter_snr[:, :, -np.int(self.spinbox_average.value() / 2):]),
+ axis=2)
+ for f in range(stg.freq.shape[0]):
+ self.axis_averaged_profile[f].cla()
+ self.axis_averaged_profile[f].plot(BS_concatenate[:, 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.figure_averaged_profile.canvas.draw_idle()
+
+ def update_plot_averaged_profile(self):
+ if self.canvas_averaged_profile == None:
+
+ msgBox = QMessageBox()
+ msgBox.setWindowTitle("Plot averaged profile Error")
+ msgBox.setIcon(QMessageBox.Warning)
+ msgBox.setText("Compute acoustic backscatter averaged data")
+ msgBox.setStandardButtons(QMessageBox.Ok)
+ msgBox.exec()
+
+ else:
+
+ if stg.BS_data_filter_snr.size == 0:
+
+ BS_concatenate = stg.BS_data_averaged = np.concatenate(
+ (stg.BS_data[:, :, :np.int(self.spinbox_average.value() / 2)],
+ stg.BS_data_averaged,
+ stg.BS_data[:, :, -np.int(self.spinbox_average.value() / 2):]),
+ axis=2)
+ for f in range(stg.freq.shape[0]):
+ self.axis_averaged_profile[f].cla()
+ self.axis_averaged_profile[f].plot(BS_concatenate[:, 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))
+ else:
+ BS_concatenate = stg.BS_data_averaged = np.concatenate(
+ (stg.BS_data_filter_snr[:, :, :np.int(self.spinbox_average.value() / 2)],
+ stg.BS_data_averaged,
+ stg.BS_data_filter_snr[:, :, -np.int(self.spinbox_average.value() / 2):]),
+ axis=2)
+ for f in range(stg.freq.shape[0]):
+ self.axis_averaged_profile[f].cla()
+ self.axis_averaged_profile[f].plot(BS_concatenate[:, 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.figure_averaged_profile.canvas.draw_idle()
# def plot_transect_bottom_with_profile_position(self, profile_position):
# frequency = self.model.Freq[0]