Implementation of acoustic inversion method for suspended sediments high concentrations

dev-brahim
brahim 2023-09-05 12:09:21 +02:00
parent 1b8945025c
commit 5bd6f9d08f
7 changed files with 888 additions and 231 deletions

View File

@ -80,6 +80,10 @@ class AcousticDataLoader():
order="F") order="F")
return r return r
def compute_r_2D(self):
r2D = np.repeat(self._r, self._time.size, axis=1)
return r2D
def reshape_t(self): def reshape_t(self):
t = np.reshape(np.repeat(self._time, self._r.shape[0]), (self._time.shape[0]*self._r.shape[0], 1)) t = np.reshape(np.repeat(self._time, self._r.shape[0]), (self._time.shape[0]*self._r.shape[0], 1))
return t return t

View File

@ -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

View File

@ -327,9 +327,9 @@ class AcousticDataTab(QWidget):
self.verticalLayout_display_option.addWidget(self.groupbox_xaxis_time) self.verticalLayout_display_option.addWidget(self.groupbox_xaxis_time)
self.gridLayout_groupbox_xaxis_time = QGridLayout(self.groupbox_xaxis_time) self.gridLayout_groupbox_xaxis_time = QGridLayout(self.groupbox_xaxis_time)
self.label_from = QLabel() self.label_from_time = QLabel()
self.label_from.setText("From") self.label_from_time.setText("From")
self.gridLayout_groupbox_xaxis_time.addWidget(self.label_from, 0, 0, 1, 1) self.gridLayout_groupbox_xaxis_time.addWidget(self.label_from_time, 0, 0, 1, 1)
self.label_tmin = QLabel() self.label_tmin = QLabel()
self.label_tmin.setText("t<span style= vertical-align:sub>min</span> = ") self.label_tmin.setText("t<span style= vertical-align:sub>min</span> = ")
@ -345,9 +345,9 @@ class AcousticDataTab(QWidget):
self.label_tmin_unit.setText("sec") self.label_tmin_unit.setText("sec")
self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmin_unit, 0, 3, 1, 1) self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmin_unit, 0, 3, 1, 1)
self.label_to = QLabel() self.label_to_time = QLabel()
self.label_to.setText("to") self.label_to_time.setText("to")
self.gridLayout_groupbox_xaxis_time.addWidget(self.label_to, 0, 4, 1, 1) self.gridLayout_groupbox_xaxis_time.addWidget(self.label_to_time, 0, 4, 1, 1)
self.label_tmax = QLabel() self.label_tmax = QLabel()
self.label_tmax.setText("t<span style= vertical-align:sub>max</span> = ") self.label_tmax.setText("t<span style= vertical-align:sub>max</span> = ")
@ -356,13 +356,19 @@ class AcousticDataTab(QWidget):
self.spinbox_tmax = QDoubleSpinBox() self.spinbox_tmax = QDoubleSpinBox()
self.spinbox_tmax.setRange(0, 9999) self.spinbox_tmax.setRange(0, 9999)
self.gridLayout_groupbox_xaxis_time.addWidget(self.spinbox_tmax, 0, 6, 1, 1) 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_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_SNR_data)
self.label_tmax_unit = QLabel() self.label_tmax_unit = QLabel()
self.label_tmax_unit.setText("sec") self.label_tmax_unit.setText("sec")
self.gridLayout_groupbox_xaxis_time.addWidget(self.label_tmax_unit, 0, 7, 1, 1) 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 --- # --- Group Box Plot x-axis in space ---
self.groupbox_xaxis_space = QGroupBox() self.groupbox_xaxis_space = QGroupBox()
@ -372,31 +378,44 @@ class AcousticDataTab(QWidget):
self.verticalLayout_display_option.addWidget(self.groupbox_xaxis_space) self.verticalLayout_display_option.addWidget(self.groupbox_xaxis_space)
self.gridLayout_groupbox_xaxis_space = QGridLayout(self.groupbox_xaxis_space) self.gridLayout_groupbox_xaxis_space = QGridLayout(self.groupbox_xaxis_space)
self.label_from = QLabel() self.label_from_space = QLabel()
self.label_from.setText("From") self.label_from_space.setText("From ")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_from, 0, 0, 1, 1) self.gridLayout_groupbox_xaxis_space.addWidget(self.label_from_space, 0, 0, 1, 1)
self.label_xmin = QLabel() self.label_xmin = QLabel()
self.label_xmin.setText("x<span style= vertical-align:sub>min</span> = ") self.label_xmin.setText("x<span style= vertical-align:sub>min</span> = ")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmin, 0, 1, 1, 1) self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmin, 0, 1, 1, 1)
self.spinbox_xmin = QSpinBox() self.spinbox_xmin = QSpinBox()
self.spinbox_xmin.setRange(0, 9999) self.spinbox_xmin.setRange(0, 9999)
self.gridLayout_groupbox_xaxis_space.addWidget(self.spinbox_xmin, 0, 2, 1, 1) self.gridLayout_groupbox_xaxis_space.addWidget(self.spinbox_xmin, 0, 2, 1, 1)
self.label_xmin_m = QLabel() self.label_xmin_m = QLabel()
self.label_xmin_m.setText("m") self.label_xmin_m.setText("m")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmin_m, 0, 3, 1, 1) self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmin_m, 0, 3, 1, 1)
self.label_to = QLabel()
self.label_to.setText("to") self.label_to_space = QLabel()
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_to, 0, 4, 1, 1) 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 = QLabel()
self.label_xmax.setText("x<span style= vertical-align:sub>max</span> = ") self.label_xmax.setText("x<span style= vertical-align:sub>max</span> = ")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmax, 0, 5, 1, 1) self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmax, 0, 5, 1, 1)
self.spinbox_xmax = QSpinBox() self.spinbox_xmax = QSpinBox()
self.spinbox_xmax.setRange(0, 9999) self.spinbox_xmax.setRange(0, 9999)
self.gridLayout_groupbox_xaxis_space.addWidget(self.spinbox_xmax, 0, 6, 1, 1) self.gridLayout_groupbox_xaxis_space.addWidget(self.spinbox_xmax, 0, 6, 1, 1)
self.label_xmax_m = QLabel() self.label_xmax_m = QLabel()
self.label_xmax_m.setText("m") self.label_xmax_m.setText("m")
self.gridLayout_groupbox_xaxis_space.addWidget(self.label_xmax_m, 0, 7, 1, 1) 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--- # --- Group Box bathymetry computation algorithm to detect and plot bottom of transect---
self.groupbox_compute_bathymetry = QGroupBox() self.groupbox_compute_bathymetry = QGroupBox()
@ -410,30 +429,44 @@ class AcousticDataTab(QWidget):
self.combobox_freq_choice = QComboBox() self.combobox_freq_choice = QComboBox()
# self.combobox_freq_choice.addItems(['', '0.3 MHz', '0.5 Mhz', '1 MHz', '5 MHz']) # 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.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 = QSpinBox()
self.spinbox_depth_min.setRange(0, 9999) self.spinbox_depth_min.setRange(0, 9999)
self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_min, 0, 2, 1, 1) self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_min, 0, 2, 1, 1)
self.label_depth_min_unit = QLabel() self.label_depth_min_unit = QLabel()
self.label_depth_min_unit.setText("m") 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_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 = QSpinBox()
self.spinbox_depth_max.setRange(0, 99999) self.spinbox_depth_max.setRange(0, 99999)
self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_max, 0, 5, 1, 1) self.gridlayout_compute_bathymetry.addWidget(self.spinbox_depth_max, 0, 5, 1, 1)
self.label_depth_max_unit = QLabel() self.label_depth_max_unit = QLabel()
self.label_depth_max_unit.setText("m") self.label_depth_max_unit.setText("m")
self.gridlayout_compute_bathymetry.addWidget(self.label_depth_max_unit, 0, 6, 1, 1) self.gridlayout_compute_bathymetry.addWidget(self.label_depth_max_unit, 0, 6, 1, 1)
self.label_next_cell = QLabel() self.label_next_cell = QLabel()
self.label_next_cell.setText("Next cell : +/-") self.label_next_cell.setText("Next cell : +/-")
self.gridlayout_compute_bathymetry.addWidget(self.label_next_cell, 1, 1, 1, 1) self.gridlayout_compute_bathymetry.addWidget(self.label_next_cell, 1, 1, 1, 1)
self.doublespinbox_next_cell = QDoubleSpinBox() self.doublespinbox_next_cell = QDoubleSpinBox()
self.doublespinbox_next_cell.setRange(0, 99999) self.doublespinbox_next_cell.setRange(0, 99999)
self.doublespinbox_next_cell.setDecimals(2) self.doublespinbox_next_cell.setDecimals(2)
self.gridlayout_compute_bathymetry.addWidget(self.doublespinbox_next_cell, 1, 2, 1, 1) self.gridlayout_compute_bathymetry.addWidget(self.doublespinbox_next_cell, 1, 2, 1, 1)
self.label_next_cell_unit = QLabel() self.label_next_cell_unit = QLabel()
self.label_next_cell_unit.setText("m") self.label_next_cell_unit.setText("m")
self.gridlayout_compute_bathymetry.addWidget(self.label_next_cell_unit, 1, 3, 1, 1) 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 = QPushButton()
self.pushbutton_compute_bathymetry_algorithm.setText("Compute \n&& \nPlot") self.pushbutton_compute_bathymetry_algorithm.setText("Compute \n&& \nPlot")
self.gridlayout_compute_bathymetry.addWidget(self.pushbutton_compute_bathymetry_algorithm, 0, 7, 2, 1) 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 = acoustic_data._BS_raw_data
stg.BS_raw_data_reshape = acoustic_data.reshape_BS_raw_cross_section() stg.BS_raw_data_reshape = acoustic_data.reshape_BS_raw_cross_section()
stg.r = acoustic_data._r stg.r = acoustic_data._r
stg.r_2D = acoustic_data.compute_r_2D()
stg.r_reshape = acoustic_data.reshape_r() stg.r_reshape = acoustic_data.reshape_r()
stg.time = acoustic_data._time stg.time = acoustic_data._time
stg.time_reshape = acoustic_data.reshape_t() 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]] 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]: 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]] 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]): for f in range(stg.freq.shape[0]):
self.axis_BS[f].cla() self.axis_BS[f].cla()

View File

@ -1,18 +1,28 @@
import sys import sys
from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication, QVBoxLayout, QHBoxLayout, QGroupBox from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication, QVBoxLayout, QHBoxLayout, QGroupBox, QComboBox, \
from PyQt5.QtCore import QCoreApplication QGridLayout, QLabel, QPushButton, QSpinBox
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import QStandardItemModel
import numpy as np import numpy as np
from itertools import combinations
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm, BoundaryNorm, CSS4_COLORS from matplotlib.colors import LogNorm, BoundaryNorm, CSS4_COLORS
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
import Translation.constant_string as cs 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 _translate = QCoreApplication.translate
@ -23,22 +33,141 @@ class AcousticInversionTab(QWidget):
def __init__(self, widget_tab): def __init__(self, widget_tab):
super().__init__() super().__init__()
# self.inv_hc = AcousticInversionMethodHighConcentration()
# self.verticalLayout_acoustic_inversion_tab = QVBoxLayout(widget_tab)
# ### --- General layout of widgets ---
# self.horizontalLayout_Top_acousticInversionTab = QHBoxLayout()
# self.verticalLayoutMain = QVBoxLayout(widget_tab)
# self.groupbox_AcousticInversionOption = QGroupBox()
# # self.groupbox_AcousticInversionOption.setTitle("Acoustic inversion option") self.horizontalLayoutTop = QHBoxLayout()
# self.verticalLayoutMain.addLayout(self.horizontalLayoutTop, 4) # 1O units is 100% , 1 units is 10%
# self.horizontalLayout_Top_acousticInversionTab.addWidget(self.groupbox_AcousticInversionOption)
# self.horizontalLayoutBottom = QHBoxLayout()
# self.verticalLayout_acoustic_inversion_tab.addLayout(self.horizontalLayout_Top_acousticInversionTab, 4) self.verticalLayoutMain.addLayout(self.horizontalLayoutBottom, 6)
#
# self.horizontalLayout_Bottom_acousticInversionTab = QHBoxLayout() ### --- Layout of groupbox in the Top horizontal layout box
#
# self.groupbox_sediment_concentration_2Dplot = QGroupBox() # Acoustic inversion Options | Acoustic inversion method Settings parameter
# # self.groupbox_sediment_concentration_2Dplot.setTitle("Fine and sand sediment concentration")
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) # 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.canvas_sediments2DPlot)
# self.horizontalLayout_Bottom_acousticInversionTab.addWidget(self.groupbox_sediment_concentration_2Dplot, 7) # 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( # # self.groupbox_sediment_concentration_sample_vs_measurement.setTitle(
# # "Suspended sediment concentration plot : acoustic inversion theory VS measurements") # # "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.verticalLayout_acoustic_inversion_tab.addLayout(self.horizontalLayout_Bottom_acousticInversionTab, 6)
# #
# self.retranslate_acoustic_inversion_tab() # self.retranslate_acoustic_inversion_tab()
#
# # --------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------
# # -------------------- Functions -------------------- # -------------------- Functions --------------------
# # ---------------------------------------------------------------------------------------------
#
# def retranslate_acoustic_inversion_tab(self): # def retranslate_acoustic_inversion_tab(self):
# #
# self.groupbox_AcousticInversionOption.setTitle(_translate("CONSTANT_STRING", cs.ACOUSTIC_INVERSION_OPTIONS)) # 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_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)) # self.groupbox_sediment_concentration_sample_vs_measurement.setTitle(_translate("CONSTANT_STRING", cs.SUSPENDED_SEDIMENT_CONCENTRATION_PLOT))
#
# def plot_SSC_fine(self): def acoustic_inversion_method_choice(self):
# frequency = 0 if self.combobox_acoustic_inversion_method_choice.currentIndex() == 1:
# val_min = 1e-2 #np.nanmin(self.model.SSC_fine[:, :]) #
# val_max = 15 #np.nanmax(self.model.SSC_fine[:, :]) # # --- add items in combobox of samples to calibrate acoustic inversion method ---
# # print('val_min=', val_min) samples_vertical_line = np.split(stg.samples, np.where(np.diff(stg.sample_time) != 0)[0]+1)
# # print('val_max=', val_max)
# # if val_min == 0: for s in samples_vertical_line:
# # val_min = 0.5 self.combobox_calibration_samples.addItem(" - ".join([i for i in s]))
# # 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), for i in range(len(samples_vertical_line)):
# self.model.SSC_fine[:, :], self.combobox_calibration_samples.setItemChecked(i, False)
# cmap='rainbow', norm=LogNorm(vmin=val_min, vmax=val_max), shading='gouraud')
# self.axis_SSC_2Dplot[0].plot(self.model.dist_BS_section, # --- add items in combobox of frequencies for VBI computation ---
# np.max(self.model.r_bottom_cross_section) - self.model.r_bottom_cross_section for k in combinations(stg.freq_text, 2):
# + np.min(self.model.r_bottom_cross_section), self.combobox_frequencies_VBI.addItem(k[0] + " - " + k[1])
# color='k', linewidth=2) # print(k)
# self.figure_SSC_2Dplot.supxlabel("Distance from left bank (m)", fontsize=10) for i in range(len(list(combinations(stg.freq_text, 2)))):
# self.figure_SSC_2Dplot.supylabel("Depth (m)", fontsize=10) self.combobox_frequencies_VBI.setItemChecked(i, False)
# self.figure_SSC_2Dplot.tight_layout()
# def sample_choice(self):
# cbar_SSC_fine = self.figure_SSC_2Dplot.colorbar(pcm_SSC_fine, ax=self.axis_SSC_2Dplot[0], shrink=1, location='right') sample_position = []
# cbar_SSC_fine.set_label(label='Fine SSC (g/L', rotation=270, labelpad=15) for i in range(self.combobox_calibration_samples.count()):
# if self.combobox_calibration_samples.itemChecked(i):
# def plot_SSC_sand(self): sample_position.append(i)
# frequency = 0 elif (i in sample_position) and (not self.combobox_calibration_samples.itemChecked(i)):
# val_min = 1e-2 #np.nanmin(self.model.SSC_fine[:, :]) # sample_position.remove(i)
# val_max = 2 #np.nanmax(self.model.SSC_fine[:, :]) #
# # print('val_min=', val_min) def frequencies_pair_choice_to_compute_VBI(self):
# # print('val_max=', val_max) freq_combination = list(combinations(stg.freq, 2))
# # if val_min == 0: frequencies_position = []
# # val_min = 0.5 for i in range(self.combobox_frequencies_VBI.count()):
# # print('val_min update =', val_min) if self.combobox_frequencies_VBI.itemChecked(i):
# pcm_SSC_sand = self.axis_SSC_2Dplot[1].pcolormesh(self.model.dist_BS_section, np.flipud(self.model.BS_averaged_cross_section.r), frequencies_position.append(i)
# self.model.SSC_sand[:, :], elif (i in frequencies_position) and (not self.combobox_frequencies_VBI.itemChecked(i)):
# cmap='rainbow', norm=LogNorm(vmin=val_min, vmax=val_max), shading='gouraud') frequencies_position.remove(i)
# 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 if len(frequencies_position) != 0:
# + np.min(self.model.r_bottom_cross_section), # print(frequencies_position)
# color='k', linewidth=2) # print(freq_combination[frequencies_position[0]][0], freq_combination[frequencies_position[0]][1])
# self.figure_SSC_2Dplot.supxlabel("Distance from left bank (m)", fontsize=10) stg.frequencies_pair = (
# self.figure_SSC_2Dplot.supylabel("Depth (m)", fontsize=10) np.array([[int(np.where(stg.freq == freq_combination[frequencies_position[0]][0])[0][0]),
# self.figure_SSC_2Dplot.tight_layout() freq_combination[frequencies_position[0]][0]],
# [int(np.where(stg.freq == freq_combination[frequencies_position[0]][1])[0][0]),
# cbar_SSC_sand = self.figure_SSC_2Dplot.colorbar(pcm_SSC_sand, ax=self.axis_SSC_2Dplot[1], shrink=1, location='right') freq_combination[frequencies_position[0]][1]]]))
# cbar_SSC_sand.set_label(label='Sand SSC (g/L', rotation=270, labelpad=15) # print(type(stg.frequencies_pair))
# # print(stg.frequencies_pair)
# # if __name__ == "__main__": # print(stg.frequencies_pair[1, 0])
# # app = QApplication(sys.argv) # print(type(stg.frequencies_pair[0]), stg.frequencies_pair[0],
# # print("class acoustic inversion tab :", AcousticInversionTab()) # np.where(stg.freq == stg.frequencies_pair[0])[0][0])
# # sys.exit(app.exec_()) # 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()

View File

@ -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

View File

@ -415,8 +415,9 @@ class SampleDataTab(QWidget):
# horizontal_header = list(map(str, ["Color", "Sample"] + stg.fine_sediment_columns + # horizontal_header = list(map(str, ["Color", "Sample"] + stg.fine_sediment_columns +
# stg.sand_sediment_columns[2:])) # stg.sand_sediment_columns[2:]))
horizontal_header = list(itertools.chain(["Color", "Sample"], horizontal_header = list(itertools.chain(["Color", "Sample"],
list(map(str, stg.fine_sediment_columns.values)), list(map(str, stg.fine_sediment_columns[:2])),
list(map(str, stg.sand_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: for horizontal_header_text in horizontal_header:
# print(horizontal_header_text) # print(horizontal_header_text)
@ -447,7 +448,8 @@ class SampleDataTab(QWidget):
self.item_checkbox = QTableWidgetItem() self.item_checkbox = QTableWidgetItem()
self.item_checkbox.setCheckState(Qt.Unchecked) self.item_checkbox.setCheckState(Qt.Unchecked)
self.tableWidget_sample.setItem(i, 1, self.item_checkbox) 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()) # print(f"S{i+1} ", self.tableWidget_sample.item(i, 1).checkState())
# --- Fill table with data --- # --- Fill table with data ---

View File

@ -1,7 +1,7 @@
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 QSpinBox, QDoubleSpinBox, QComboBox, QLineEdit, QSlider, QGridLayout, QMessageBox
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
@ -83,7 +83,7 @@ class SignalProcessingTab(QWidget):
self.pushbutton_load_data = QPushButton() self.pushbutton_load_data = QPushButton()
self.horizontalLayout_pushbutton_load_data_plot_bottom_line.addWidget(self.pushbutton_load_data) 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_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.combobox_frequency = QComboBox()
self.horizontalLayout_pushbutton_load_data_plot_bottom_line.addWidget(self.combobox_frequency) 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.gridLayout_groupbox_acoustic_profile = QGridLayout(self.groupbox_acoustic_profile)
self.checkbox_SNR_criterion = QCheckBox() # self.checkbox_SNR_criterion = QCheckBox()
self.gridLayout_groupbox_acoustic_profile.addWidget(self.checkbox_SNR_criterion, 0, 0, 1, 1) 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 = QSpinBox()
self.spinbox_SNR_criterion.setRange(0, 9999) self.spinbox_SNR_criterion.setRange(0, 9999)
self.spinbox_SNR_criterion.setValue(0) 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.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 = QPushButton()
self.pushbutton_snr_filter.setText("Apply SNR") 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.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_profiles)
# self.spinbox_SNR_criterion.valueChanged.connect(self.update_plot_profile_position_on_transect) # 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.remove_point_with_snr_filter)
# self.pushbutton_snr_filter.clicked.connect(self.update_plot_profile_position_on_transect) # 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.horizontalLayout_groupbox_window_size = QHBoxLayout(self.groupbox_window_size)
self.label_signal_averaging_over = QLabel() 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.horizontalLayout_groupbox_window_size.addWidget(self.label_signal_averaging_over)
self.spinbox_average = QSpinBox() self.spinbox_average = QSpinBox()
self.spinbox_average.setRange(0, 9999) self.spinbox_average.setRange(0, 9999)
@ -199,6 +200,15 @@ class SignalProcessingTab(QWidget):
self.label_cells = QLabel() self.label_cells = QLabel()
self.horizontalLayout_groupbox_window_size.addWidget(self.label_cells) 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 --- # --- Groupbox Rayleigh criterion ---
# # self.groupbox_rayleigh_criterion.setTitle("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_lineEdit_by_moving_slider)
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_profiles) self.slider.valueChanged.connect(self.update_plot_profile)
self.slider.valueChanged.connect(self.update_plot_averaged_profile)
self.retranslate_signal_processing_tab() self.retranslate_signal_processing_tab()
@ -583,7 +594,7 @@ class SignalProcessingTab(QWidget):
self.groupbox_acoustic_profile.setTitle(_translate("CONSTANT_STRING", cs.ACOUSTIC_PROFILE)) 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_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.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) + ": +/-")
@ -621,13 +632,13 @@ class SignalProcessingTab(QWidget):
def update_lineEdit_by_moving_slider(self): def update_lineEdit_by_moving_slider(self):
self.lineEdit_slider.setText(str(self.slider.value())) self.lineEdit_slider.setText(str(self.slider.value()))
def enable_disable_spinbox_snr_value(self): # def enable_disable_spinbox_snr_value(self):
if self.checkbox_SNR_criterion.isChecked(): # if self.checkbox_SNR_criterion.isChecked():
self.spinbox_SNR_criterion.setEnabled(True) # self.spinbox_SNR_criterion.setEnabled(True)
self.pushbutton_snr_filter.setEnabled(True) # self.pushbutton_snr_filter.setEnabled(True)
else: # else:
self.spinbox_SNR_criterion.setDisabled(True) # self.spinbox_SNR_criterion.setDisabled(True)
self.pushbutton_snr_filter.setDisabled(True) # self.pushbutton_snr_filter.setDisabled(True)
def remove_point_with_snr_filter(self): def remove_point_with_snr_filter(self):
@ -654,7 +665,7 @@ class SignalProcessingTab(QWidget):
self.canvas_plot_profile_position_on_transect = FigureCanvas(self.figure_plot_profile_position_on_transect) 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) 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_min = np.min(stg.BS_data[:, stg.freq_bottom_detection, :])
val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :]) val_max = np.max(stg.BS_data[:, stg.freq_bottom_detection, :])
@ -675,35 +686,35 @@ class SignalProcessingTab(QWidget):
self.figure_plot_profile_position_on_transect.canvas.draw_idle() self.figure_plot_profile_position_on_transect.canvas.draw_idle()
else: # else:
stg.BS_data_section = deepcopy(stg.BS_data) # stg.BS_data_section = deepcopy(stg.BS_data)
for f in range(stg.freq.shape[0]): # for f in range(stg.freq.shape[0]):
for k in range(stg.r_bottom.shape[0]): # for k in range(stg.r_bottom.shape[0]):
# print(k, np.where(stg.r >= stg.r_bottom[k])[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] \ # stg.BS_data_section[np.where(stg.r >= stg.r_bottom[k])[0], f, k] \
= np.nan # = np.nan
# print("----------------------------------------------------------") # # print("----------------------------------------------------------")
val_min = np.min(stg.BS_data_section[:, stg.freq_bottom_detection, :]) # val_min = np.min(stg.BS_data_section[:, stg.freq_bottom_detection, :])
val_max = np.max(stg.BS_data_section[:, stg.freq_bottom_detection, :]) # val_max = np.max(stg.BS_data_section[:, stg.freq_bottom_detection, :])
if val_min == 0: # if val_min == 0:
val_min = 1e-5 # val_min = 1e-5
#
pcm = self.axis_plot_profile_position_on_transect.pcolormesh( # pcm = self.axis_plot_profile_position_on_transect.pcolormesh(
stg.t, -stg.r, stg.BS_data_section[:, stg.freq_bottom_detection, :], # stg.t, -stg.r, stg.BS_data_section[:, stg.freq_bottom_detection, :],
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) # cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
#
if stg.r_bottom.size != 0: # if stg.r_bottom.size != 0:
self.axis_plot_profile_position_on_transect.plot( # self.axis_plot_profile_position_on_transect.plot(
stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid") # stg.t, -stg.r_bottom, color='black', linewidth=1, linestyle="solid")
#
self.axis_plot_profile_position_on_transect.plot( # self.axis_plot_profile_position_on_transect.plot(
stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r, # stg.t[self.slider.value() - 1] * np.ones(stg.r.shape[0]), -stg.r,
color='red', linestyle="solid", linewidth=2) # color='red', linestyle="solid", linewidth=2)
#
self.figure_plot_profile_position_on_transect.canvas.draw_idle() # self.figure_plot_profile_position_on_transect.canvas.draw_idle()
def update_plot_profile_position_on_transect(self): def update_plot_profile_position_on_transect(self):
@ -714,17 +725,17 @@ class SignalProcessingTab(QWidget):
# --- Update transect plot --- # --- Update transect plot ---
if self.canvas_plot_profile_position_on_transect != None: if self.canvas_plot_profile_position_on_transect != None:
if stg.r_bottom.size != 0: # if stg.r_bottom.size != 0:
self.axis_plot_profile_position_on_transect.cla() self.axis_plot_profile_position_on_transect.cla()
val_min = np.min(stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :]) val_min = np.min(stg.BS_data[:, self.combobox_frequency.currentIndex(), :])
val_max = np.max(stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :]) val_max = np.max(stg.BS_data[:, self.combobox_frequency.currentIndex(), :])
if val_min == 0: if val_min == 0:
val_min = 1e-5 val_min = 1e-5
pcm = self.axis_plot_profile_position_on_transect.pcolormesh( self.axis_plot_profile_position_on_transect.pcolormesh(
stg.t, -stg.r, stg.BS_data_section[:, self.combobox_frequency.currentIndex(), :], stg.t, -stg.r, stg.BS_data[:, self.combobox_frequency.currentIndex(), :],
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
if stg.r_bottom.size != 0: if stg.r_bottom.size != 0:
@ -738,31 +749,31 @@ class SignalProcessingTab(QWidget):
self.figure_plot_profile_position_on_transect.canvas.draw_idle() self.figure_plot_profile_position_on_transect.canvas.draw_idle()
else: # 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()
self.axis_plot_profile_position_on_transect.cla() def plot_profile(self):
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):
# --- Raw profile --- # --- Raw profile ---
@ -786,32 +797,42 @@ class SignalProcessingTab(QWidget):
self.figure_profile.canvas.draw_idle() 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 \ # # --- Raw FCB profile ---
= plt.subplots(nrows=1, ncols=stg.freq.shape[0], layout='constrained') #
self.canvas_averaged_profile = FigureCanvas(self.figure_averaged_profile) # self.figure_FCB_profile, self.axis_FCB_profile \
self.verticalLayout_groupbox_plot_averaged_profile.addWidget(self.canvas_averaged_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]): def update_plot_profile(self):
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))
# --- 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)
def update_plot_profiles(self):
if self.checkbox_SNR_criterion.isChecked():
# self.remove_point_with_snr_filter() # 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[:, 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]): 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_filter_snr[:, f, self.slider.value()-1], -stg.r, self.axis_profile[f].plot(stg.BS_data_filter_snr[:, f, self.slider.value()-1], -stg.r,
@ -825,12 +846,12 @@ class SignalProcessingTab(QWidget):
self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
else: # else:
#
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[:, f, self.slider.value()-1], -stg.r, # self.axis_profile[f].plot(stg.BS_data[:, f, self.slider.value()-1], -stg.r,
linestyle='solid', color='k', linewidth=1) # linestyle='solid', color='k', linewidth=1)
# if stg.r_bottom.size != 0: # if stg.r_bottom.size != 0:
# self.axis_profile[f].plot( # self.axis_profile[f].plot(
@ -838,12 +859,110 @@ class SignalProcessingTab(QWidget):
# -stg.r_bottom[self.slider.value() - 1] * np.ones(2), # -stg.r_bottom[self.slider.value() - 1] * np.ones(2),
# linestyle='dashed', color='red', linewidth=1) # linestyle='dashed', color='red', linewidth=1)
self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r)) # self.axis_profile[f].set_ylim(-np.max(stg.r), np.min(stg.r))
self.figure_profile.canvas.draw_idle() self.figure_profile.canvas.draw_idle()
def compute_averaged_profile(self): 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): # def plot_transect_bottom_with_profile_position(self, profile_position):
# frequency = self.model.Freq[0] # frequency = self.model.Freq[0]