acoused/View/signal_processing_tab.py

2217 lines
97 KiB
Python

# ============================================================================== #
# mainwindow.py - AcouSed #
# Copyright (C) 2024 INRAE #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
import math
# by Brahim MOUDJED #
# ============================================================================== #
# -*- coding: utf-8 -*-
import os
import logging
from cProfile import label
from PyQt5.QtWidgets import (
QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QGroupBox,
QLabel, QSpinBox, QComboBox, QLineEdit, QSlider,
QGridLayout, QMessageBox, QScrollArea, QFileDialog,
QSpacerItem, QSizePolicy
)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import (
Qt, QCoreApplication, QEvent, pyqtSignal, QPropertyAnimation,
QSize
)
import numpy as np
from copy import deepcopy
from astropy.convolution import convolve
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
from matplotlib.colors import LogNorm, BoundaryNorm
from os import path
from numba.np.arraymath import np_average
from View.show_popup_combobox import ComboBoxShowPopUpWindow
from View.plot_noise_window import PlotNoiseWindow
import Translation.constant_string as cs
from Model.acoustic_data_loader import AcousticDataLoader
import settings as stg
from tools import trace
_translate = QCoreApplication.translate
logger = logging.getLogger("acoused")
class SignalProcessingTab(QWidget):
''' This class generates the Signal Processing Tab '''
FillCombobox = pyqtSignal()
def __init__(self, widget_tab):
super().__init__()
self._setup_icons()
self._setup_attrs()
### --- General layout of widgets ---
# |-----------------| |------------| |-----------------|
# | Data to be | | Plot SNR | | Pre-processing |
# | pre-processed | |------------| | options |
# |-----------------| |-----------------|
# |------------------------------------------------------------------------|
# |-----------------------| |-----------------------| |------------------|
# | Plot pre-processed | | Plot pre-processed | | Pre-processed |
# | data 2D field | | data profile | | data list |
# |-----------------------| |-----------------------| |------------------|
# |------------------------------------------------------------------------|
self.verticalLayoutMain = QVBoxLayout(widget_tab)
self.horizontalLayout_Top = QHBoxLayout()
self.verticalLayoutMain.addLayout(self.horizontalLayout_Top, 5)
self.horizontalLayout_Bottom = QHBoxLayout()
self.verticalLayoutMain.addLayout(self.horizontalLayout_Bottom, 5)
# --------------------------------------------------------------------------------------------------------------
### --- Layout of groupbox in the top layout box
self.groupbox_study_data = QGroupBox()
self.horizontalLayout_Top.addWidget(self.groupbox_study_data, 3)
self.groupbox_plot_SNR = QGroupBox()
self.horizontalLayout_Top.addWidget(self.groupbox_plot_SNR, 5)
self.groupbox_pre_processing_option = QGroupBox()
self.horizontalLayout_Top.addWidget(self.groupbox_pre_processing_option, 2)
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# +++ --- Download data to be processed + Download noise file + compute noise data from profile tail + --- +++
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
self.groupbox_study_data.setTitle("Study data")
### --- Groupbox download data to be processed ---
self.verticalLayout_groupbox_study_data = QVBoxLayout(self.groupbox_study_data)
self.horizontalLayout_groupbox_data_to_be_processed_Pushbutton_plot_clear_noise = QHBoxLayout()
self.verticalLayout_groupbox_study_data.addLayout(self.horizontalLayout_groupbox_data_to_be_processed_Pushbutton_plot_clear_noise)
self.groupbox_data_to_be_processed = QGroupBox()
self.gridLayout_groupbox_data_to_be_processed = QGridLayout(self.groupbox_data_to_be_processed)
self.groupbox_data_to_be_processed.setTitle("Data to be processed")
self.combobox_acoustic_data_choice = QComboBox()
self.combobox_acoustic_data_choice.setMinimumWidth(200)
self.gridLayout_groupbox_data_to_be_processed.addWidget(self.combobox_acoustic_data_choice, 0, 0, 1, 1, Qt.AlignCenter)
self.pushbutton_update = QPushButton()
self.pushbutton_update.setIcon(self.icon_update)
self.gridLayout_groupbox_data_to_be_processed.addWidget(self.pushbutton_update, 0, 1, 1, 1, Qt.AlignCenter)
self.horizontalLayout_groupbox_data_to_be_processed_Pushbutton_plot_clear_noise.addWidget(
self.groupbox_data_to_be_processed)
self.pushbutton_plot_noise_data = QPushButton()
self.pushbutton_plot_noise_data.setText("Plot noise field")
self.horizontalLayout_groupbox_data_to_be_processed_Pushbutton_plot_clear_noise.addWidget(
self.pushbutton_plot_noise_data)
self.pushbutton_clear_noise_data = QPushButton()
self.pushbutton_clear_noise_data.setIcon(self.icon_clear)
self.horizontalLayout_groupbox_data_to_be_processed_Pushbutton_plot_clear_noise.addWidget(
self.pushbutton_clear_noise_data)
### --- Groupbox download noise file ---
self.groupbox_download_noise_file = QGroupBox()
self.groupbox_download_noise_file.setTitle("Noise file")
self.groupbox_download_noise_file.setCheckable(True)
self.groupbox_download_noise_file.setChecked(True)
self.gridLayout_groupbox_noise_file = QGridLayout(self.groupbox_download_noise_file)
self.verticalLayout_groupbox_study_data.addWidget(self.groupbox_download_noise_file)
self.pushbutton_noise_file = QPushButton()
self.pushbutton_noise_file.setIcon(self.icon_folder)
self.gridLayout_groupbox_noise_file.addWidget(self.pushbutton_noise_file, 0, 0, 1, 1, Qt.AlignCenter)
self.lineEdit_noise_file = QLineEdit()
self.gridLayout_groupbox_noise_file.addWidget(self.lineEdit_noise_file, 0, 1, 1, 2, Qt.AlignLeft)
### --- Groupbox compute noise from profile tail ---
self.groupbox_compute_noise_from_profile_tail = QGroupBox()
self.groupbox_compute_noise_from_profile_tail.setTitle("Profile tail")
self.groupbox_compute_noise_from_profile_tail.setCheckable(True)
self.groupbox_compute_noise_from_profile_tail.setChecked(False)
self.verticalLayout_groupbox_study_data.addWidget(self.groupbox_compute_noise_from_profile_tail)
self.horizontalLayout_groupbox_compute_noise_from_profile_tail = QHBoxLayout(self.groupbox_compute_noise_from_profile_tail)
self.groupbox_plot_profile_tail = QGroupBox()
self.horizontalLayout_groupbox_compute_noise_from_profile_tail.addWidget(self.groupbox_plot_profile_tail)
self.verticalLayout_groupbox_plot_profile_tail = QVBoxLayout(self.groupbox_plot_profile_tail)
self.canvas_profile_tail = FigureCanvas()
self.verticalLayout_groupbox_plot_profile_tail.addWidget(self.canvas_profile_tail)
self.horizontalLayout_groupbox_compute_noise_from_profile_tail.addWidget(self.groupbox_plot_profile_tail)
self.groupbox_option_profile_tail = QGroupBox()
self.horizontalLayout_groupbox_compute_noise_from_profile_tail.addWidget(self.groupbox_option_profile_tail)
self.gridLayout_groupbox_option_profile_tail = QGridLayout(self.groupbox_option_profile_tail)
self.combobox_freq_noise_from_profile_tail = QComboBox()
self.gridLayout_groupbox_option_profile_tail.addWidget(self.combobox_freq_noise_from_profile_tail, 0, 0, 1, 2, Qt.AlignCenter)
self.lineEdit_val1 = QLineEdit()
self.lineEdit_val1.setText("0.00")
self.gridLayout_groupbox_option_profile_tail.addWidget(self.lineEdit_val1, 1, 0, 1, 1, Qt.AlignCenter)
self.lineEdit_val2 = QLineEdit()
self.lineEdit_val2.setText("0.00")
self.gridLayout_groupbox_option_profile_tail.addWidget(self.lineEdit_val2, 1, 1, 1, 1, Qt.AlignCenter)
self.pushbutton_plot_profile_tail = QPushButton()
self.pushbutton_plot_profile_tail.setIcon(self.icon_apply)
self.gridLayout_groupbox_option_profile_tail.addWidget(self.pushbutton_plot_profile_tail, 1, 2, 1, 1, Qt.AlignCenter)
self.lineEdit_profile_tail_value = QLineEdit()
self.lineEdit_profile_tail_value.setText("0.0000")
self.gridLayout_groupbox_option_profile_tail.addWidget(self.lineEdit_profile_tail_value, 2, 0, 1, 1, Qt.AlignCenter)
self.label_Volts = QLabel()
self.label_Volts.setText("Volts")
self.gridLayout_groupbox_option_profile_tail.addWidget(self.label_Volts, 2, 1, 1, 1, Qt.AlignLeft)
self.pushbutton_apply_noise_from_profile_tail = QPushButton()
self.pushbutton_apply_noise_from_profile_tail.setIcon(self.icon_apply)
self.gridLayout_groupbox_option_profile_tail.addWidget(self.pushbutton_apply_noise_from_profile_tail, 2, 2, 1, 1, Qt.AlignCenter)
# ++++++++++++++++++++++++
# +++ --- Plot SNR --- +++
# ++++++++++++++++++++++++
self.groupbox_plot_SNR.setTitle("Plot SNR")
self.verticalLayout_groupbox_plot_SNR = QVBoxLayout(self.groupbox_plot_SNR)
self.canvas_SNR = FigureCanvas()
self.toolbar_SNR = NavigationToolBar(self.canvas_SNR, self)
self.verticalLayout_groupbox_plot_SNR.addWidget(self.toolbar_SNR)
self.scroll_SNR = QScrollArea()
self.scroll_SNR.setWidget(self.canvas_SNR)
self.scroll_SNR.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll_SNR.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll_SNR.setAlignment(Qt.AlignCenter)
self.verticalLayout_groupbox_plot_SNR.addWidget(self.scroll_SNR)
# +++++++++++++++++++++++++++++++++++++
# +++ --- Pre-processing option --- +++
# +++++++++++++++++++++++++++++++++++++
self.groupbox_pre_processing_option.setTitle("Pre-processing options")
self.verticalLayout_groupbox_pre_processing_option = QVBoxLayout(self.groupbox_pre_processing_option)
### --- Groupbox SNR criterion ---
self.groupbox_SNR_criterion = QGroupBox()
self.groupbox_SNR_criterion.setTitle("SNR filter")
self.gridLayout_SNR_criterion = QGridLayout(self.groupbox_SNR_criterion)
self.label_SNR_criterion = QLabel("SNR < ")
self.gridLayout_SNR_criterion.addWidget(self.label_SNR_criterion, 0, 0, 1, 1, Qt.AlignCenter)
self.lineEdit_SNR_criterion = QLineEdit()
self.lineEdit_SNR_criterion.setMaximumWidth(60)
self.gridLayout_SNR_criterion.addWidget(self.lineEdit_SNR_criterion, 0, 1, 1, 1, Qt.AlignCenter)
self.pushbutton_Apply_SNR_filter = QPushButton()
self.pushbutton_Apply_SNR_filter.setIcon(self.icon_apply)
self.gridLayout_SNR_criterion.addWidget(self.pushbutton_Apply_SNR_filter, 0, 2, 1, 1, Qt.AlignCenter)
self.verticalLayout_groupbox_pre_processing_option.addWidget(self.groupbox_SNR_criterion)
# --- Rayleigh criterion groupbox ---
self.groupbox_Rayleigh_criterion = QGroupBox()
self.groupbox_Rayleigh_criterion.setTitle("Despiking the signal")
self.groupbox_Rayleigh_criterion.setDisabled(True)
self.gridLayout_Rayleigh_criterion = QGridLayout(self.groupbox_Rayleigh_criterion)
self.label_Rayleigh_criterion = QLabel()
self.label_Rayleigh_criterion.setText("<V²>/<V>² <=")
self.gridLayout_Rayleigh_criterion.addWidget(self.label_Rayleigh_criterion, 0, 0, 1, 1)
self.spinbox_Rayleigh_criterion = QSpinBox()
self.spinbox_Rayleigh_criterion.setRange(0, 9999)
self.spinbox_Rayleigh_criterion.setValue(10)
self.gridLayout_Rayleigh_criterion.addWidget(self.spinbox_Rayleigh_criterion, 0, 1, 1, 1)
self.label_4pi = QLabel()
self.label_4pi.setText("% x 4/pi")
self.gridLayout_Rayleigh_criterion.addWidget(self.label_4pi, 0, 2, 1, 1)
self.pushbutton_despiking_signal = QPushButton()
self.pushbutton_despiking_signal.setText("Despiking the signal")
self.gridLayout_Rayleigh_criterion.addWidget(self.pushbutton_despiking_signal, 0, 3, 1, 1)
self.verticalLayout_groupbox_pre_processing_option.addWidget(self.groupbox_Rayleigh_criterion)
# --- Average signal groupbox ---
self.groupbox_window_size = QGroupBox()
self.groupbox_window_size.setTitle("Horizontal averaging")
self.gridLayout_groupbox_window_size = QGridLayout(self.groupbox_window_size)
self.label_signal_averaging_horizontal = QLabel()
self.label_signal_averaging_horizontal.setText("Horizontal +/- ")
self.gridLayout_groupbox_window_size.addWidget(self.label_signal_averaging_horizontal, 0, 0, 1, 1, Qt.AlignCenter)
self.lineEdit_horizontal_average = QLineEdit()
self.lineEdit_horizontal_average.setText("0.00")
self.lineEdit_horizontal_average.setMaximumWidth(60)
self.gridLayout_groupbox_window_size.addWidget(self.lineEdit_horizontal_average, 0, 1, 1, 1, Qt.AlignCenter)
self.label_cells_horizontal = QLabel()
self.label_cells_horizontal.setText("cells = +/- ? sec")
self.gridLayout_groupbox_window_size.addWidget(self.label_cells_horizontal, 0, 2, 1, 1, Qt.AlignCenter)
self.pushbutton_average = QPushButton()
self.pushbutton_average.setIcon(self.icon_apply)
self.gridLayout_groupbox_window_size.addWidget(self.pushbutton_average, 0, 3, 1, 1, Qt.AlignCenter)
self.verticalLayout_groupbox_pre_processing_option.addWidget(self.groupbox_window_size)
# # ++++++++++++++++++++++++++++++++++++++++++++++
# # +++ --- Plot BS data filtered with SNR --- +++
# # ++++++++++++++++++++++++++++++++++++++++++++++
# --------------------------------------------------------------------------------------------------------------
### --- Layout of groupbox in the bottom layout box
self.groupbox_plot_pre_processed_data_2D_field = QGroupBox()
self.horizontalLayout_Bottom.addWidget(self.groupbox_plot_pre_processed_data_2D_field, 5)
self.groupbox_plot_pre_processed_data_profile = QGroupBox()
self.horizontalLayout_Bottom.addWidget(self.groupbox_plot_pre_processed_data_profile, 3)
self.groupbox_list_pre_processed_data = QGroupBox()
self.horizontalLayout_Bottom.addWidget(self.groupbox_list_pre_processed_data, 2)
# ++++++++++++++++++++++++++++++++++++++++++++++++
# +++ --- Plot pre-processed data 2D field --- +++
# ++++++++++++++++++++++++++++++++++++++++++++++++
self.groupbox_plot_pre_processed_data_2D_field.setTitle("Display pre-processed data 2D fields")
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field = QVBoxLayout(
self.groupbox_plot_pre_processed_data_2D_field)
self.canvas_BS = FigureCanvas()
self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field.addWidget(self.toolbar_BS)
self.scroll_BS = QScrollArea()
self.scroll_BS.setWidget(self.canvas_BS)
self.scroll_BS.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll_BS.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll_BS.setAlignment(Qt.AlignCenter)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field.addWidget(self.scroll_BS)
# +++++++++++++++++++++++++++++++++++++++++++++++
# +++ --- Plot pre-processed data profile --- +++
# +++++++++++++++++++++++++++++++++++++++++++++++
self.groupbox_plot_pre_processed_data_profile.setTitle("Display pre-processed data profile")
self.verticalLayout_groupbox_plot_pre_processed_data_2D_profile = QVBoxLayout(
self.groupbox_plot_pre_processed_data_profile)
self.horizontalLayout_profile_frequency = QHBoxLayout()
self.verticalLayout_groupbox_plot_pre_processed_data_2D_profile.addLayout(
self.horizontalLayout_profile_frequency)
self.spacerItem_frequency_profile = QSpacerItem(50, 10, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalLayout_profile_frequency.addSpacerItem(self.spacerItem_frequency_profile)
self.combobox_frequency_profile = QComboBox()
self.horizontalLayout_profile_frequency.addWidget(self.combobox_frequency_profile)
self.groupbox_plot_profile = QGroupBox()
self.verticalLayout_groupbox_plot_profile = QVBoxLayout(self.groupbox_plot_profile)
self.canvas_profile = FigureCanvas()
self.toolbar_profile = NavigationToolBar(self.canvas_profile, self)
self.verticalLayout_groupbox_plot_profile.addWidget(self.toolbar_profile)
self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_profile)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_profile.addWidget(self.groupbox_plot_profile)
# --- Slider for moving the profile ---
self.horizontalLayout_slider = QHBoxLayout()
self.verticalLayout_groupbox_plot_pre_processed_data_2D_profile.addLayout(self.horizontalLayout_slider)
self.pushbutton_slider_left_to_begin = QPushButton()
self.pushbutton_slider_left_to_begin.setIcon(self.icon_triangle_left_to_begin)
self.horizontalLayout_slider.addWidget(self.pushbutton_slider_left_to_begin)
self.pushbutton_slider_left = QPushButton()
self.pushbutton_slider_left.setIcon(self.icon_triangle_left)
self.horizontalLayout_slider.addWidget(self.pushbutton_slider_left)
self.lineEdit_slider = QLineEdit()
self.lineEdit_slider.setText("1")
self.lineEdit_slider.setFixedWidth(50)
self.horizontalLayout_slider.addWidget(self.lineEdit_slider)
self.pushbutton_slider_right = QPushButton()
self.pushbutton_slider_right.setIcon(self.icon_triangle_right)
self.horizontalLayout_slider.addWidget(self.pushbutton_slider_right)
self.pushbutton_slider_right_to_end = QPushButton()
self.pushbutton_slider_right_to_end.setIcon(self.icon_triangle_right_to_end)
self.horizontalLayout_slider.addWidget(self.pushbutton_slider_right_to_end)
self.slider = QSlider()
self.horizontalLayout_slider.addWidget(self.slider, 9)
self.slider.setOrientation(Qt.Horizontal)
self.slider.setCursor(Qt.OpenHandCursor)
self.slider.setMinimum(1)
self.slider.setMaximum(10)
self.slider.setTickInterval(1)
self.slider.setValue(1)
# ++++++++++++++++++++++++++++++++++++++++++
# +++ --- List of pre-processed data --- +++
# ++++++++++++++++++++++++++++++++++++++++++
self.groupbox_list_pre_processed_data.setTitle("List pre-processed data: user label")
self.verticalLayout_groupbox_list_pre_processed_data = QVBoxLayout(self.groupbox_list_pre_processed_data)
# Create a scroll area
self.scrollArea_list_preprocessed_data = QScrollArea()
self.verticalLayout_groupbox_list_pre_processed_data.addWidget(self.scrollArea_list_preprocessed_data)
# Set scrollbar policies
self.scrollArea_list_preprocessed_data.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scrollArea_list_preprocessed_data.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll_BS.setAlignment(Qt.AlignLeft)
# Create a widget to be scrolled
self.widget_scrollArea_list_preprocessed_data = QWidget()
self.verticalLayout_scrollArea_list_pre_processed_data = QVBoxLayout()
self.widget_scrollArea_list_preprocessed_data.setLayout(self.verticalLayout_scrollArea_list_pre_processed_data)
# Add content to the widget (labels in this example)
self.lineEdit_list_pre_processed_data = []
for i in range(20):
self.lineEdit_list_pre_processed_data.append(QLineEdit())
self.verticalLayout_scrollArea_list_pre_processed_data.addWidget(
self.lineEdit_list_pre_processed_data[i]
)
self.lineEdit_list_pre_processed_data[i].setDisabled(True)
# Set the widget as the scroll area's widget
self.scrollArea_list_preprocessed_data.setWidget(self.widget_scrollArea_list_preprocessed_data)
self.scrollArea_list_preprocessed_data.setWidgetResizable(True)
# --------------------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------------------
# +++++++++ CONNECT SIGNAL OF WIDGET TO SLOT FUNCTION +++++++++
# --------------------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------------------
self.pushbutton_update.clicked.connect(self.update_SignalPreprocessingTab)
# self.pushbutton_update.clicked.connect(self.compute_average_profile_tail)
# self.pushbutton_update.clicked.connect(self.plot_averaged_profile_tail)
self.combobox_acoustic_data_choice.currentIndexChanged.connect(self.combobox_acoustic_data_choice_change_index)
self.groupbox_download_noise_file.toggled.connect(self.groupbox_download_noise_file_toggle)
self.groupbox_compute_noise_from_profile_tail.toggled.connect(self.groupbox_option_profile_tail_toggle)
self.pushbutton_noise_file.clicked.connect(self.open_dialog_box)
self.pushbutton_plot_noise_data.clicked.connect(self.open_plot_noise_window)
self.pushbutton_clear_noise_data.clicked.connect(self.clear_noise_data)
self.pushbutton_plot_profile_tail.clicked.connect(self.compute_average_profile_tail)
self.pushbutton_plot_profile_tail.clicked.connect(self.replot)
self.pushbutton_apply_noise_from_profile_tail.clicked.connect(self.compute_noise_from_profile_tail_value)
self.pushbutton_apply_noise_from_profile_tail.clicked.connect(self.replot)
self.combobox_freq_noise_from_profile_tail.currentIndexChanged.connect(self.compute_average_profile_tail)
self.combobox_freq_noise_from_profile_tail.currentIndexChanged.connect(self.plot_averaged_profile_tail)
self.pushbutton_Apply_SNR_filter.clicked.connect(self.remove_point_with_snr_filter)
self.pushbutton_Apply_SNR_filter.clicked.connect(self.replot)
self.lineEdit_horizontal_average.returnPressed.connect(self.update_label_cells_sec)
self.pushbutton_average.clicked.connect(self.compute_averaged_BS_data)
self.pushbutton_average.clicked.connect(self.replot)
self.pushbutton_slider_left_to_begin.clicked.connect(self.slide_profile_number_to_begin)
self.pushbutton_slider_left.clicked.connect(self.slide_profile_number_to_left)
self.lineEdit_slider.returnPressed.connect(self.profile_number_on_lineEdit)
self.pushbutton_slider_right.clicked.connect(self.slide_profile_number_to_right)
self.pushbutton_slider_right_to_end.clicked.connect(self.slide_profile_number_to_end)
self.slider.valueChanged.connect(self.update_lineEdit_by_moving_slider)
self.slider.valueChanged.connect(self.update_plot_pre_processed_profile)
def _setup_icons(self):
def path_icon(icon):
return os.path.join(
os.path.dirname(__file__), "..", "icons", icon
)
self.icon_folder = QIcon(path_icon("folder.png"))
self.icon_triangle_left = QIcon(path_icon("triangle_left.png"))
self.icon_triangle_right = QIcon(path_icon("triangle_right.png"))
self.icon_triangle_left_to_begin = QIcon(
path_icon("triangle_left_to_begin.png")
)
self.icon_triangle_right_to_end = QIcon(
path_icon("triangle_right_to_end.png")
)
self.icon_update = QIcon(path_icon("update.png"))
self.icon_clear = QIcon(path_icon("clear.png"))
self.icon_apply = QIcon(path_icon("circle_green_arrow_right.png"))
def _setup_attrs(self):
self.fig_profile_tail = None
self.fig_noise = None
self.fig_SNR = None
self.fig_BS = None
self.figure_profile = None
def full_update(self):
logger.debug(f"{__name__}: Update")
self.blockSignals(True)
self.combobox_acoustic_data_choice.blockSignals(True)
self.full_update_fill_text()
self.update_SignalPreprocessingTab()
self.combobox_acoustic_data_choice.blockSignals(False)
self.blockSignals(False)
def full_update_fill_text(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
self.lineEdit_profile_tail_value.setText(
str(stg.noise_value[data_id])
)
self.lineEdit_SNR_criterion.setText(
str(stg.SNR_filter_value[data_id])
)
self.lineEdit_horizontal_average.setText(
str(stg.Nb_cells_to_average_BS_signal[data_id])
)
def update_SignalPreprocessingTab(self):
""" The tab is updated in two cases :
- the user remove a file (in the list widget) in the first tab (Acoustic data), so that the combobox
of data to be processed is updated,
- the user change the limits of one or all the records in the first tab (Acoustic data) """
if len(stg.filename_BS_raw_data) == 0:
msgBox = QMessageBox()
msgBox.setWindowTitle("Compute noise from profile tail error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Download acoustic data in previous tab before updating data")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
else:
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
self.combobox_acoustic_data_choice.blockSignals(True)
self.combobox_freq_noise_from_profile_tail.blockSignals(True)
logger.debug("Update the Signal preprocessing tab...")
self.combobox_acoustic_data_choice.clear()
self.combobox_acoustic_data_choice.addItems(stg.filename_BS_raw_data)
if stg.noise_method[data_id] == 0:
self.groupbox_download_noise_file.setChecked(True)
self.groupbox_compute_noise_from_profile_tail.setChecked(False)
self.groupbox_download_noise_file_toggle()
elif stg.noise_method[data_id] == 1:
self.groupbox_download_noise_file.setChecked(False)
self.groupbox_compute_noise_from_profile_tail.setChecked(True)
self.groupbox_option_profile_tail_toggle()
self.combobox_freq_noise_from_profile_tail.clear()
self.combobox_freq_noise_from_profile_tail.addItems(
stg.freq_text[data_id]
)
self.recompute()
self.replot()
logger.debug("Update the Signal preprocessing tab... Done")
self.combobox_freq_noise_from_profile_tail.blockSignals(False)
self.combobox_acoustic_data_choice.blockSignals(False)
def _is_correct_shape(self, data):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
if stg.time_cross_section[data_id].shape != (0,):
x_time = stg.time_cross_section[data_id]
else:
x_time = stg.time[data_id]
if stg.depth_cross_section[data_id].shape != (0,):
y_depth = stg.depth_cross_section[data_id]
else:
y_depth = stg.depth[data_id]
time_shape, = x_time[data_id].shape
depth_shape, = y_depth[data_id].shape
logger.debug(f"_is_correct_shape: time shape: {time_shape}")
logger.debug(f"_is_correct_shape: depth shape: {depth_shape}")
logger.debug(f"_is_correct_shape: data shape: {data[data_id].shape}")
if data[data_id].shape == (0,):
return False
_, y, z = data[data_id].shape
return (y == depth_shape and z == time_shape)
def recompute(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
self.compute_average_profile_tail()
if stg.noise_method[data_id] == 0:
if stg.filename_BS_noise_data[data_id] == "":
return
if len(stg.BS_noise_raw_data) == 0:
self.load_noise_data_and_compute_SNR()
else:
for i in range(self.combobox_acoustic_data_choice.count()):
self.compute_noise(i)
elif stg.noise_method[data_id] == 1:
self.compute_noise_from_profile_tail_value()
self.remove_point_with_snr_filter()
self.compute_averaged_BS_data()
@trace
def compute_noise(self, data_id):
if self._is_correct_shape(stg.BS_stream_bed):
BS_data = stg.BS_stream_bed
SNR_data = stg.SNR_stream_bed
elif self._is_correct_shape(stg.BS_cross_section):
BS_data = stg.BS_cross_section
SNR_data = stg.SNR_cross_section
else:
BS_data = stg.BS_raw_data
SNR_data = stg.SNR_raw_data
noise = np.zeros(BS_data[data_id].shape)
for f, _ in enumerate(BS_data[data_id]):
noise[f, :, :] = np.mean(
stg.BS_noise_raw_data[data_id][f, :, :], axis=(0, 1)
)
stg.BS_noise_averaged_data[data_id] = noise
SNR_data[data_id] = (
np.divide(
(
BS_data[data_id] - stg.BS_noise_averaged_data[data_id]
) ** 2,
stg.BS_noise_averaged_data[data_id] ** 2
)
)
self.combobox_frequency_profile.clear()
self.combobox_frequency_profile.addItems(
[f for f in stg.freq_text[data_id]]
)
def replot(self):
self.plot_averaged_profile_tail()
self.plot_transect_with_SNR_data()
self.plot_pre_processed_BS_signal()
self.plot_pre_processed_profile()
def activate_list_of_pre_processed_data(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
for i in range(self.combobox_acoustic_data_choice.count()):
self.lineEdit_list_pre_processed_data[i].setDisabled(True)
self.lineEdit_list_pre_processed_data[data_id].setEnabled(True)
self.lineEdit_list_pre_processed_data[data_id]\
.returnPressed.connect(self.rename_preprocessed_data)
self.lineEdit_list_pre_processed_data[data_id]\
.setText(stg.filename_BS_raw_data[data_id])
def rename_preprocessed_data(self):
stg.data_preprocessed[data_id] = \
self.lineEdit_list_pre_processed_data[data_id].text()
# ------------------------------------------------------
def groupbox_download_noise_file_toggle(self):
if self.groupbox_download_noise_file.isChecked() == True:
self.groupbox_compute_noise_from_profile_tail.setChecked(False)
elif self.groupbox_download_noise_file.isChecked() == False:
self.groupbox_compute_noise_from_profile_tail.setChecked(True)
def groupbox_download_noise_file_size_change(self):
duration = 500
self.animation_groupbox_download_noise_file = QPropertyAnimation(
self.groupbox_download_noise_file, b"size"
)
self.animation_groupbox_download_noise_file.setDuration(duration)
self.animation_groupbox_download_noise_file.setStartValue(
QSize(
self.groupbox_download_noise_file.width(),
self.groupbox_download_noise_file.height()
)
)
if self.groupbox_download_noise_file.isChecked():
self.animation_groupbox_download_noise_file.setEndValue(
QSize(
self.groupbox_download_noise_file.width(),
self.groupbox_download_noise_file.sizeHint().height()
)
)
else:
self.animation_groupbox_download_noise_file.setEndValue(
QSize(self.groupbox_download_noise_file.width(), 25)
)
self.animation_groupbox_download_noise_file.start()
def groupbox_option_profile_tail_toggle(self):
if self.groupbox_compute_noise_from_profile_tail.isChecked() == True:
self.groupbox_download_noise_file.setChecked(False)
elif self.groupbox_compute_noise_from_profile_tail.isChecked() == False:
self.groupbox_download_noise_file.setChecked(True)
def groupbox_option_profile_tail_size_change(self):
duration = 500
self.animation_groupbox_option_profile_tail = QPropertyAnimation(
self.groupbox_option_profile_tail, b"size"
)
self.animation_groupbox_option_profile_tail.setDuration(duration)
self.animation_groupbox_option_profile_tail.setStartValue(
QSize(
self.groupbox_option_profile_tail.width(),
self.groupbox_option_profile_tail.height()
)
)
if self.groupbox_option_profile_tail.isChecked():
self.animation_groupbox_option_profile_tail.setEndValue(
QSize(
self.groupbox_option_profile_tail.width(),
self.groupbox_option_profile_tail.sizeHint().height()
)
)
else:
self.animation_groupbox_option_profile_tail.setEndValue(
QSize(self.groupbox_option_profile_tail.width(), 25)
)
self.animation_groupbox_option_profile_tail.start()
# ------------------------------------------------------
def compute_average_profile_tail(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
freq_noise_id = self.combobox_freq_noise_from_profile_tail.currentIndex()
if ((float(self.lineEdit_val1.text()) == 0)
and (float(self.lineEdit_val2.text()) == 0)):
if stg.time_cross_section[data_id].shape != (0,):
self.lineEdit_val1.setText(str(
'%.3f' % np.nanmin(
stg.time_cross_section[data_id][
freq_noise_id
]
)
))
self.lineEdit_val2.setText(str(
'%.3f' % np.nanmax(
stg.time_cross_section[data_id][
freq_noise_id
]
)
))
elif stg.time[data_id].shape != (0,):
self.lineEdit_val1.setText(str(
'%.3f' % np.nanmin(stg.time[data_id][
freq_noise_id])))
self.lineEdit_val2.setText(str(
'%.3f' % np.nanmax(stg.time[data_id][
freq_noise_id])))
# --- Find index of line edit value ---
if stg.time_cross_section[data_id].shape != (0,):
time_data = stg.time_cross_section
elif stg.time[data_id].shape != (0,):
time_data = stg.time
val1 = np.where(
np.abs(
time_data[data_id][freq_noise_id]
- float(self.lineEdit_val1.text().replace(",", "."))
) == np.nanmin(
np.abs(
time_data[data_id][freq_noise_id]
- float(self.lineEdit_val1.text().replace(",", "."))
)
)
)[0][0]
val2 = np.where(
np.abs(
time_data[data_id][freq_noise_id]
- float(self.lineEdit_val2.text().replace(",", "."))
) == np.nanmin(
np.abs(
time_data[data_id][freq_noise_id]
- float(self.lineEdit_val2.text().replace(",", "."))
)
)
)[0][0]
stg.BS_mean[data_id] = (
np.nanmean(
stg.BS_raw_data[data_id][:, :, val1:val2],
axis=2
)
)
def plot_averaged_profile_tail(self):
# --- Plot averaged signal ---
if len(stg.filename_BS_raw_data) == 0:
msgBox = QMessageBox()
msgBox.setWindowTitle("Compute noise from profile tail error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Download acoustic data in previous tab before computing noise from profile tail")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
elif self.combobox_acoustic_data_choice.count() == 0:
msgBox = QMessageBox()
msgBox.setWindowTitle("Compute noise from profile tail error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Refresh acoustic data before computing noise from profile tail")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
else:
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
freq_noise_id = self.combobox_freq_noise_from_profile_tail.currentIndex()
if stg.BS_mean[data_id].shape == (0,):
return
self.verticalLayout_groupbox_plot_profile_tail.removeWidget(self.canvas_profile_tail)
if self.fig_profile_tail is not None:
self.fig_profile_tail.clear()
self.fig_profile_tail, self.axis_profile_tail = \
plt.subplots(nrows=1, ncols=1, layout='constrained')
self.canvas_profile_tail = FigureCanvas(self.fig_profile_tail)
self.verticalLayout_groupbox_plot_profile_tail.addWidget(self.canvas_profile_tail)
self.axis_profile_tail.plot(
-stg.depth[data_id][freq_noise_id],
stg.BS_mean[data_id][freq_noise_id],
color="blue", linewidth=1
)
self.axis_profile_tail.plot(
-stg.depth[data_id][freq_noise_id],
float(self.lineEdit_profile_tail_value.text().replace(",", "."))
* np.ones(stg.depth[data_id][freq_noise_id].shape[0]),
linestyle='dashed', linewidth=2, color='red'
)
self.axis_profile_tail.set_yscale('log')
self.axis_profile_tail.tick_params(axis='both', labelsize=8)
self.axis_profile_tail.text(
.98, .03, "Depth (m)",
fontsize=8, fontweight='bold',
fontname="DejaVu Sans", c="black", alpha=0.9,
horizontalalignment='right',
verticalalignment='bottom', rotation='horizontal',
transform=self.axis_profile_tail.transAxes
)
self.axis_profile_tail.text(
.1, .45, "BS signal (v)",
fontsize=8, fontweight='bold',
fontname="DejaVu Sans", c="black", alpha=0.9,
horizontalalignment='right',
verticalalignment='bottom', rotation='vertical',
transform=self.axis_profile_tail.transAxes
)
self.axis_profile_tail.text(
.98, .85,
stg.freq_text[data_id][freq_noise_id],
fontsize=10, fontweight='bold',
fontname="DejaVu Sans", c="black", alpha=0.5,
horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_profile_tail.transAxes
)
self.fig_profile_tail.canvas.draw_idle()
# ------------------------------------------------------
def combobox_acoustic_data_choice_change_index(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
self.combobox_frequency_profile.blockSignals(True)
self.compute_average_profile_tail()
self.lineEdit_profile_tail_value.setText(
str(stg.noise_value[data_id])
)
self.lineEdit_SNR_criterion.setText(
str(stg.SNR_filter_value[data_id])
)
self.lineEdit_horizontal_average.setText(
str(stg.Nb_cells_to_average_BS_signal[data_id])
)
self.combobox_frequency_profile.clear()
self.combobox_frequency_profile.addItems(
[f for f in stg.freq_text[data_id]]
)
self.recompute()
self.replot()
if self.combobox_acoustic_data_choice.count() > 0:
for i in range(self.combobox_acoustic_data_choice.count()):
self.lineEdit_list_pre_processed_data[i].setDisabled(True)
self.lineEdit_list_pre_processed_data[data_id].setEnabled(True)
self.combobox_frequency_profile.blockSignals(False)
def clear_noise_data(self):
if len(stg.filename_BS_raw_data) == 0:
pass
else:
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
stg.BS_noise_raw_data[data_id] = np.array([])
stg.BS_noise_averaged_data[data_id] = np.array([])
stg.SNR_raw_data[data_id] = np.array([])
stg.SNR_cross_section[data_id] = np.array([])
stg.SNR_stream_bed[data_id] = np.array([])
stg.time_noise[data_id] = np.array([])
stg.SNR_filter_value[data_id] = 0
stg.BS_raw_data_pre_process_SNR[data_id] = np.array([])
stg.BS_raw_data_pre_process_average[data_id] = np.array([])
stg.BS_cross_section_pre_process_SNR[data_id] = np.array([])
stg.BS_cross_section_pre_process_average[data_id] = np.array([])
stg.BS_stream_bed_pre_process_SNR[data_id] = np.array([])
stg.BS_stream_bed_pre_process_average[data_id] = np.array([])
if stg.noise_method[data_id] == 0:
self.lineEdit_noise_file.clear()
elif stg.noise_method[data_id] == 1:
self.lineEdit_val1.clear()
self.lineEdit_val1.setText("0.00")
self.lineEdit_val2.clear()
self.lineEdit_val2.setText("0.00")
self.lineEdit_profile_tail_value.clear()
self.lineEdit_profile_tail_value.setText("0.0000")
self.verticalLayout_groupbox_plot_profile_tail.removeWidget(self.canvas_profile_tail)
self.canvas_profile_tail = FigureCanvas()
self.verticalLayout_groupbox_plot_profile_tail.addWidget(self.canvas_profile_tail)
self.lineEdit_SNR_criterion.setText("0.00")
self.lineEdit_horizontal_average.setText("0.00")
# --- Clear SNR plot ---
self.verticalLayout_groupbox_plot_SNR.removeWidget(self.toolbar_SNR)
self.verticalLayout_groupbox_plot_SNR.removeWidget(self.scroll_SNR)
self.canvas_SNR = FigureCanvas()
self.toolbar_SNR = NavigationToolBar(self.canvas_SNR, self)
self.scroll_SNR.setWidget(self.canvas_SNR)
self.verticalLayout_groupbox_plot_SNR.addWidget(self.toolbar_SNR)
self.verticalLayout_groupbox_plot_SNR.addWidget(self.scroll_SNR)
# --- Clear BS plot ---
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field.removeWidget(self.toolbar_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field.removeWidget(self.scroll_BS)
self.canvas_BS = FigureCanvas()
self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)
self.scroll_BS.setWidget(self.canvas_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field.addWidget(self.toolbar_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field.addWidget(self.scroll_BS)
self.combobox_frequency_profile.clear()
self.verticalLayout_groupbox_plot_profile.removeWidget(self.toolbar_profile)
self.verticalLayout_groupbox_plot_profile.removeWidget(self.canvas_profile)
self.canvas_profile = FigureCanvas()
self.toolbar_profile = NavigationToolBar(self.canvas_profile, self)
self.verticalLayout_groupbox_plot_profile.addWidget(self.toolbar_profile)
self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_profile)
self.slider.setValue(1)
self.slider.setMaximum(10)
self.slider.setValue(0)
self.slider.setMaximum(10)
def open_dialog_box(self):
data_id = self.combobox_acoustic_data_choice.currentIndex()
if self.combobox_acoustic_data_choice.count() > 0:
directory = ""
if self.combobox_acoustic_data_choice.count() > 0:
directory = stg.path_BS_raw_data[-1]
filename, _ = QFileDialog.getOpenFileName(
self, "AQUAscat Noise file",
directory,
"Aquascat file (*.aqa)",
options=QFileDialog.DontUseNativeDialog
)
if filename == "":
return
dir_name = path.dirname(filename)
name = path.basename(filename)
stg.path_BS_noise_data[data_id] = dir_name
stg.filename_BS_noise_data[data_id] = name
try:
self.load_noise_data_and_compute_SNR()
except ValueError as e:
msgBox = QMessageBox()
msgBox.setWindowTitle("Download Error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Please select a file")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
else:
self.lineEdit_noise_file.setText(stg.filename_BS_noise_data[data_id])
self.lineEdit_noise_file.setToolTip(stg.path_BS_noise_data[data_id])
self.plot_transect_with_SNR_data()
self.combobox_frequency_profile.clear()
self.combobox_frequency_profile.addItems(
[f for f in stg.freq_text[data_id]]
)
self.combobox_frequency_profile\
.currentIndexChanged\
.connect(self.plot_pre_processed_BS_signal)
self.combobox_frequency_profile\
.currentIndexChanged\
.connect(self.update_plot_pre_processed_profile)
if stg.time_cross_section[data_id].shape != (0,):
self.slider.setMaximum(stg.time_cross_section[data_id].shape[1])
else:
self.slider.setMaximum(stg.time[data_id].shape[1])
self.plot_pre_processed_BS_signal()
self.plot_pre_processed_profile()
stg.noise_method[data_id] = 0
self.activate_list_of_pre_processed_data()
else:
msgBox = QMessageBox()
msgBox.setWindowTitle("Download Error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Please upload acoustic data")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
def load_noise_data_and_compute_SNR(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
stg.noise_method[data_id] = 0
noise_data = AcousticDataLoader(
os.path.join(
stg.path_BS_noise_data[data_id],
stg.filename_BS_noise_data[data_id]
)
)
stg.BS_noise_raw_data[data_id] = noise_data._BS_raw_data
stg.time_noise[data_id] = noise_data._time
stg.depth_noise[data_id] = noise_data._r
if stg.BS_stream_bed[data_id].shape != (0,):
BS_data = stg.BS_stream_bed
SNR_data = stg.SNR_stream_bed
elif stg.BS_cross_section[data_id].shape != (0,):
BS_data = stg.BS_cross_section
SNR_data = stg.SNR_cross_section
else:
BS_data = stg.BS_raw_data
SNR_data = stg.SNR_raw_data
noise = np.zeros(BS_data[data_id].shape)
for f, _ in enumerate(noise_data._freq):
noise[f, :, :] = np.mean(
stg.BS_noise_raw_data[data_id][f, :, :], axis=(0, 1)
)
stg.BS_noise_averaged_data[data_id] = noise
SNR_data[data_id] = (
np.divide(
(
BS_data[data_id] - stg.BS_noise_averaged_data[data_id]
) ** 2,
stg.BS_noise_averaged_data[data_id] ** 2
)
)
def open_plot_noise_window(self):
pnw = PlotNoiseWindow()
pnw.exec()
def compute_noise_from_profile_tail_value(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
stg.noise_method[data_id] = 1
stg.noise_value[data_id] = (
float(self.lineEdit_profile_tail_value.text().replace(",", "."))
)
self.compute_noise_from_profile_tail_value_compute()
@trace
def compute_noise_from_profile_tail_value_compute(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
if stg.time_cross_section[data_id].shape != (0,):
stg.time_noise[data_id] = (
stg.time_cross_section[data_id]
)
else:
stg.time_noise[data_id] = (
stg.time[data_id]
)
if stg.depth_cross_section[data_id].shape != (0,):
stg.depth_noise[data_id] = (
stg.depth_cross_section[data_id]
)
else:
stg.depth_noise[data_id] = (
stg.depth[data_id]
)
# --- Compute noise from value and compute SNR ---
if self._is_correct_shape(stg.BS_stream_bed):
BS_data = stg.BS_stream_bed
SNR_data = stg.SNR_stream_bed
elif self._is_correct_shape(stg.BS_cross_section):
BS_data = stg.BS_cross_section
SNR_data = stg.SNR_cross_section
else:
BS_data = stg.BS_raw_data
SNR_data = stg.SNR_raw_data
stg.BS_noise_raw_data[data_id] = (
np.full(
BS_data[data_id].shape,
float(self.lineEdit_profile_tail_value.text().replace(",", "."))
)
)
stg.BS_noise_averaged_data[data_id] = (
stg.BS_noise_raw_data[data_id]
)
SNR_data[data_id] = (
np.divide(
(
BS_data[data_id] - stg.BS_noise_raw_data[data_id]
) ** 2,
stg.BS_noise_raw_data[data_id] ** 2
)
)
self.combobox_frequency_profile.clear()
self.combobox_frequency_profile.addItems(
[f for f in stg.freq_text[data_id]]
)
# --- Trigger graphic widgets ---
if stg.SNR_filter_value[data_id] == 0:
self.lineEdit_SNR_criterion.setText("0.00")
else:
self.lineEdit_SNR_criterion.setText(str(stg.SNR_filter_value[data_id]))
if stg.time_cross_section[data_id].shape != (0,):
self.slider.setMaximum(stg.time_cross_section[data_id].shape[1])
else:
self.slider.setMaximum(stg.time[data_id].shape[1])
# self.activate_list_of_pre_processed_data()
def plot_noise(self):
self.horizontalLayout_groupbox_plot_noise_data.removeWidget(self.canvas_noise)
if self.fig_noise is not None:
self.fig_noise.clear()
self.fig_noise, self.axis_noise = plt.subplots(
nrows=1, ncols=1, layout="constrained"
)
self.canvas_noise = FigureCanvas(self.fig_noise)
self.horizontalLayout_groupbox_plot_noise_data.addWidget(self.canvas_noise)
val_min = np.nanmin(stg.BS_noise_raw_data[self.combobox_freq_noise.currentIndex(), :, :])
val_max = np.nanmax(stg.BS_noise_raw_data[self.combobox_freq_noise.currentIndex(), :, :])
if val_min == val_max:
pcm = self.axis_noise.pcolormesh(stg.time_snr[0, :],
-stg.depth[self.combobox_freq_noise.currentIndex(), :],
stg.BS_noise_raw_data[self.combobox_freq_noise.currentIndex(), :, :],
cmap='viridis')
else:
if val_min == 0:
val_min = 1e-5
pcm = self.axis_noise.pcolormesh(stg.time_snr[0, :],
-stg.r[self.combobox_freq_noise.currentIndex(), :],
stg.BS_noise_raw_data[self.combobox_freq_noise.currentIndex(), :, :],
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
self.axis_noise.tick_params(axis='both', which='minor', labelsize=10)
def plot_transect_with_SNR_data(self):
# --- Condition if table is not filled ---
# if not self.lineEdit_noise_file.text():
if len(stg.BS_noise_raw_data) == 0:
msgBox = QMessageBox()
msgBox.setWindowTitle("Plot transect Error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Load data before plot transect 2D field")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
# elif self.canvas_SNR == None:
else:
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
if ((data_id != -1)
and (stg.BS_noise_raw_data[data_id].shape != (0,))):
self.verticalLayout_groupbox_plot_SNR.removeWidget(self.toolbar_SNR)
self.verticalLayout_groupbox_plot_SNR.removeWidget(self.scroll_SNR)
if self.fig_SNR is not None:
self.fig_SNR.clear()
self.fig_SNR, self.axis_SNR = plt.subplots(
nrows=stg.freq[data_id].shape[0], ncols=1,
sharex=True, sharey=False, layout='constrained'
)
self.canvas_SNR = FigureCanvas(self.fig_SNR)
self.toolbar_SNR = NavigationToolBar(self.canvas_SNR, self)
self.scroll_SNR.setWidget(self.canvas_SNR)
self.verticalLayout_groupbox_plot_SNR.addWidget(self.toolbar_SNR)
self.verticalLayout_groupbox_plot_SNR.addWidget(self.scroll_SNR)
for f, _ in enumerate(stg.freq[data_id]):
if stg.SNR_stream_bed[data_id].shape != (0,):
SNR_data = stg.SNR_stream_bed
elif stg.SNR_cross_section[data_id].shape != (0,):
SNR_data = stg.SNR_cross_section
if stg.time_cross_section[data_id].shape != (0,):
time_data = stg.time_cross_section
else:
time_data = stg.time
if stg.depth_cross_section[data_id].shape != (0,):
depth_data = stg.depth_cross_section
elif stg.depth[data_id].shape != (0,):
depth_data = stg.depth
x, y = np.meshgrid(
time_data[data_id][f, :],
depth_data[data_id][f, :]
)
val_min = np.nanmin(SNR_data[data_id][f, :, :])
val_max = np.nanmax(SNR_data[data_id][f, :, :])
levels = np.array([00.1, 1, 2, 10, 100, 1000, 1e6])
bounds = [00.1, 1, 2, 10, 100, 1000, val_max * 1.2]
if val_min != val_max:
if val_min == 0:
val_min = 1e-5
else:
levels = np.array(
[00.1, 1, 2, 10, 100, 1000, val_max * 1000 + 1]
)
bounds = [
00.1, 1, 2, 10, 100, 1000,
val_max * 1000 + 1
]
norm = BoundaryNorm(boundaries=bounds, ncolors=300)
cf = self.axis_SNR[f].contourf(
x, -y,
SNR_data[data_id][f, :, :],
levels, cmap='gist_rainbow',
norm=norm
)
self.axis_SNR[f].text(
1, .70, stg.freq_text[data_id][f],
fontsize=14, fontweight='bold', fontname="DejaVu Sans",
c="black", alpha=0.5,
horizontalalignment='right',
verticalalignment='bottom',
transform=self.axis_SNR[f].transAxes
)
self.fig_SNR.supxlabel('Time (sec)', fontsize=10)
self.fig_SNR.supylabel('Depth (m)', fontsize=10)
cbar = self.fig_SNR.colorbar(
cf, ax=self.axis_SNR[:],
shrink=1, location='right'
)
cbar.set_label(
label='Signal to Noise Ratio',
rotation=270, labelpad=10
)
cbar.set_ticklabels(
[
'0', '1', '2', '10', '100',
r'10$^3$', r'10$^6$'
]
)
self.fig_SNR.canvas.draw_idle()
else:
self.verticalLayout_groupbox_plot_SNR.removeWidget(self.toolbar_SNR)
self.verticalLayout_groupbox_plot_SNR.removeWidget(self.scroll_SNR)
self.canvas_SNR = FigureCanvas()
self.toolbar_SNR = NavigationToolBar(self.canvas_SNR, self)
self.scroll_SNR.setWidget(self.canvas_SNR)
self.verticalLayout_groupbox_plot_SNR.addWidget(self.toolbar_SNR)
self.verticalLayout_groupbox_plot_SNR.addWidget(self.scroll_SNR)
def remove_point_with_snr_filter(self):
if self.lineEdit_SNR_criterion.text() == '':
return
if len(stg.filename_BS_raw_data) == 0:
msgBox = QMessageBox()
msgBox.setWindowTitle("Compute noise from profile tail error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Download acoustic data in previous tab before applying SNR filter")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
elif len(stg.BS_noise_raw_data) == 0:
msgBox = QMessageBox()
msgBox.setWindowTitle("SNR filter Error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Define noise data (file or profile tail) before using SNR filter")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
else:
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
stg.SNR_filter_value[data_id] = (
float(self.lineEdit_SNR_criterion.text().replace(",", ".")))
if stg.BS_stream_bed[data_id].shape != (0,):
stg.BS_stream_bed_pre_process_SNR = deepcopy(stg.BS_stream_bed)
for f, _ in enumerate(stg.freq[data_id]):
stg.BS_stream_bed_pre_process_SNR[data_id][
f,
np.where(stg.SNR_stream_bed[data_id][f, :, :] <
float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0],
np.where(stg.SNR_stream_bed[data_id][f, :, :] <
float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \
= np.nan
elif stg.BS_cross_section[data_id].shape != (0,):
stg.BS_cross_section_pre_process_SNR = deepcopy(stg.BS_cross_section)
for f, _ in enumerate(stg.freq[data_id]):
stg.BS_cross_section_pre_process_SNR[data_id][
f,
np.where(stg.SNR_cross_section[data_id][f, :,
:] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0],
np.where(stg.SNR_cross_section[data_id][f, :,
:] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \
= np.nan
else:
stg.BS_raw_data_pre_process_SNR = deepcopy(stg.BS_raw_data)
for f, _ in enumerate(stg.freq[data_id]):
stg.BS_raw_data_pre_process_SNR[data_id][
f,
np.where(stg.SNR_raw_data[data_id][f, :,
:] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[0],
np.where(stg.SNR_raw_data[data_id][f, :,
:] < float(self.lineEdit_SNR_criterion.text().replace(",", ".")))[1]] \
= np.nan
self.compute_averaged_BS_data()
def plot_pre_processed_BS_signal(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
self.lineEdit_horizontal_average.setText(
str(stg.Nb_cells_to_average_BS_signal[data_id])
)
if ((data_id != -1)
and (stg.BS_noise_raw_data[data_id].shape != (0,))):
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field\
.removeWidget(self.toolbar_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field\
.removeWidget(self.scroll_BS)
if self.fig_BS is not None:
self.fig_BS.clear()
self.fig_BS, self.axis_BS = plt.subplots(
nrows=stg.freq[data_id].shape[0], ncols=1,
sharex=True, sharey=False, layout="constrained"
)
self.canvas_BS = FigureCanvas(self.fig_BS)
self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)
self.scroll_BS.setWidget(self.canvas_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field\
.addWidget(self.toolbar_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field\
.addWidget(self.scroll_BS)
if stg.time_cross_section[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
x_time = stg.time_cross_section[data_id]
y_depth = stg.depth_cross_section[data_id]
elif stg.depth[data_id].shape != (0,):
x_time = stg.time_cross_section[data_id]
y_depth = stg.depth[data_id]
else:
if stg.depth_cross_section[data_id].shape != (0,):
x_time = stg.time[data_id]
y_depth = stg.depth_cross_section[data_id]
elif stg.depth[data_id].shape != (0,):
x_time = stg.time[data_id]
y_depth = stg.depth[data_id]
for f, _ in enumerate(stg.freq[data_id]):
if stg.BS_stream_bed_pre_process_average[data_id].shape != (0,):
BS_data = stg.BS_stream_bed_pre_process_average
elif stg.BS_cross_section_pre_process_average[data_id].shape != (0,):
BS_data = stg.BS_cross_section_pre_process_average
elif stg.BS_raw_data_pre_process_average[data_id].shape != (0,):
BS_data = stg.BS_raw_data_pre_process_average
elif stg.BS_stream_bed_pre_process_SNR[data_id].shape != (0,):
BS_data = stg.BS_stream_bed_pre_process_SNR
elif stg.BS_cross_section_pre_process_SNR[data_id].shape != (0,):
BS_data = stg.BS_cross_section_pre_process_SNR
elif stg.BS_raw_data_pre_process_SNR[data_id].shape != (0,):
BS_data = stg.BS_raw_data_pre_process_SNR
elif stg.BS_stream_bed[data_id].shape != (0,):
BS_data = stg.BS_stream_bed
elif stg.BS_cross_section[data_id].shape != (0,):
BS_data = stg.BS_cross_section
elif stg.BS_raw_data[data_id].shape != (0,):
BS_data = stg.BS_raw_data
val_min = np.nanmin(
BS_data[data_id][f, :, :]
)
val_max = np.nanmax(
BS_data[data_id][f, :, :]
)
if val_min == 0 or math.isinf(val_min):
val_min = 1e-5
pcm = self.axis_BS[f].pcolormesh(
x_time[f, :], -y_depth[f, :],
BS_data[data_id][f, :, :],
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)
)
if stg.depth_bottom[data_id].shape != (0,):
self.axis_BS[f].plot(
x_time[f, :], -stg.depth_bottom[data_id],
color='black', linewidth=1, linestyle="solid"
)
self.axis_BS[f].text(
1, .70, stg.freq_text[data_id][f],
fontsize=14, fontweight='bold', fontname="DejaVu Sans",
c="black", alpha=0.5,
horizontalalignment='right',
verticalalignment='bottom',
transform=self.axis_BS[f].transAxes
)
# --- Display red line on acoustic recording for profile position ---
freq_id = self.combobox_frequency_profile.currentIndex()
self.red_line_return, = self.axis_BS[freq_id].plot(
x_time[freq_id, self.slider.value() - 1] *
np.ones(y_depth.shape[1]),
-y_depth[freq_id, :],
linestyle="solid", linewidth=2, color="red"
)
self.fig_BS.supxlabel('Time (sec)', fontsize=10)
self.fig_BS.supylabel('Depth (m)', fontsize=10)
# cbar = self.fig_BS.colorbar(pcm, ax=self.axis_BS[:],
# shrink=1, location='right')
# cbar.set_label(label='Acoustic backscatter signal (V)',
# rotation=270, labelpad=10)
self.fig_BS.canvas.draw_idle()
else:
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field\
.removeWidget(self.toolbar_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field\
.removeWidget(self.scroll_BS)
self.canvas_BS = FigureCanvas()
self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)
self.scroll_BS.setWidget(self.canvas_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field\
.addWidget(self.toolbar_BS)
self.verticalLayout_groupbox_plot_pre_processed_data_2D_field\
.addWidget(self.scroll_BS)
def update_label_cells_sec(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
self.label_cells_horizontal.clear()
self.label_cells_horizontal.setText(
"cells = +/- "
+ str(
(float(
self.lineEdit_horizontal_average.text().replace(",", ".")
) // 2)
* (1 / stg.nb_profiles_per_sec[data_id][0])
) + " sec"
)
def compute_averaged_BS_data(self):
if len(stg.filename_BS_raw_data) == 0:
msgBox = QMessageBox()
msgBox.setWindowTitle("Compute noise from profile tail error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Download acoustic data in previous tab before applying SNR filter")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
elif len(stg.BS_noise_raw_data) == 0:
msgBox = QMessageBox()
msgBox.setWindowTitle("SNR filter Error")
msgBox.setIcon(QMessageBox.Warning)
msgBox.setText("Define noise data (file or profile tail) before using SNR filter")
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec()
else:
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
n_average = 2 * int(float(self.lineEdit_horizontal_average.text().replace(",", "."))) + 1
kernel_avg = np.ones(n_average)
logger.debug(f"kernel_avg: {kernel_avg}")
stg.Nb_cells_to_average_BS_signal[data_id] = (
float(
self.lineEdit_horizontal_average\
.text().replace(",", ".")
)
)
if stg.depth_cross_section[data_id].shape != (0,):
y_depth = stg.depth_cross_section[data_id]
elif stg.depth[data_id].shape != (0,):
y_depth = stg.depth[data_id]
BS = [
stg.BS_stream_bed_pre_process_SNR,
stg.BS_cross_section_pre_process_SNR,
stg.BS_raw_data_pre_process_SNR,
stg.BS_stream_bed,
stg.BS_cross_section,
stg.BS_raw_data,
]
BS_ppa = [
stg.BS_stream_bed_pre_process_average,
stg.BS_cross_section_pre_process_average,
stg.BS_raw_data_pre_process_average,
stg.BS_stream_bed_pre_process_average,
stg.BS_cross_section_pre_process_average,
stg.BS_raw_data_pre_process_average,
]
BS_data = stg.BS_raw_data
BS_data_ppa = stg.BS_raw_data_pre_process_average
for i in range(len(BS)):
bs = BS[i]
if bs[data_id].shape == (0,):
continue
if self._is_correct_shape(bs):
BS_data = bs
BS_data_ppa = BS_ppa[i]
break
# BS_data_ppa[data_id] = deepcopy(BS_data[data_id])
#
# for f, _ in enumerate(stg.freq[data_id]):
# for i in range(y_depth.shape[1]):
# BS_data_ppa[data_id][f, i, :] = (
# convolve(
# BS_data[data_id][f, i, :],
# kernel_avg
# )
# )
temp_list = []
for f, _ in enumerate(stg.freq[data_id]):
temp0 = np.array([])
for i in range(y_depth.shape[1]):
# temp = convolve(BS_data[data_id][f, i, :], kernel_avg, "same") / n_average
temp = convolve(array=BS_data[data_id][f, i, :],
kernel=kernel_avg,
nan_treatment='interpolate')
if temp0.shape == (0,):
temp0 = np.array([temp])
else:
temp0 = np.append(temp0, np.array([temp]), axis=0)
temp_list.append(temp0)
BS_data_ppa[data_id] = np.array([temp_list[0]])
for j in range(stg.freq[data_id].shape[0]-1):
BS_data_ppa[data_id] = np.append(
BS_data_ppa[data_id],
np.array([temp_list[j+1]]),
axis=0
)
def plot_pre_processed_profile(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
if ((data_id != -1) and
(stg.BS_noise_raw_data[data_id].shape != (0,))):
self.verticalLayout_groupbox_plot_profile.removeWidget(self.toolbar_profile)
self.verticalLayout_groupbox_plot_profile.removeWidget(self.canvas_profile)
if self.figure_profile is not None:
self.figure_profile.clear()
self.figure_profile, self.axis_profile = plt.subplots(
nrows=1, ncols=1, layout="constrained"
)
self.canvas_profile = FigureCanvas(self.figure_profile)
self.toolbar_profile = NavigationToolBar(self.canvas_profile, self)
self.verticalLayout_groupbox_plot_profile.addWidget(self.toolbar_profile)
self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_profile)
# --- PLot profile ---
if stg.BS_stream_bed_pre_process_average[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_cross_section_pre_process_average[self.combobox_frequency_profile.currentIndex()].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_raw_data_pre_process_average[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_stream_bed_pre_process_SNR[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_cross_section_pre_process_SNR[self.combobox_frequency_profile.currentIndex()].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_raw_data_pre_process_SNR[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_stream_bed[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_cross_section[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_raw_data[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
self.axis_profile.text(
.95, .05, stg.freq_text[data_id][
self.combobox_frequency_profile.currentIndex()],
fontsize=10, fontweight='bold', fontname="DejaVu Sans",
fontstyle="normal", c="black", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_profile.transAxes)
self.axis_profile.set_xlabel("Acoustic Backscatter Signal (V)")
self.axis_profile.set_ylabel("Depth (m)")
self.figure_profile.canvas.draw_idle()
else:
self.combobox_frequency_profile.clear()
self.verticalLayout_groupbox_plot_profile.removeWidget(self.toolbar_profile)
self.verticalLayout_groupbox_plot_profile.removeWidget(self.canvas_profile)
self.canvas_profile = FigureCanvas()
self.toolbar_profile = NavigationToolBar(self.canvas_profile, self)
self.verticalLayout_groupbox_plot_profile.addWidget(self.toolbar_profile)
self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_profile)
self.slider.setValue(1)
self.slider.setMaximum(10)
def update_plot_pre_processed_profile(self):
data_id = max(0, self.combobox_acoustic_data_choice.currentIndex())
if ((data_id != -1) and
(stg.BS_noise_raw_data[data_id].shape != (0,))):
self.axis_profile.cla()
# --- PLot profile ---
if stg.BS_stream_bed_pre_process_average[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_cross_section_pre_process_average[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_raw_data_pre_process_average[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data_pre_process_average[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_stream_bed_pre_process_SNR[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_cross_section_pre_process_SNR[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_raw_data_pre_process_SNR[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data_pre_process_SNR[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_stream_bed[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_stream_bed[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_cross_section[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.BS_raw_data[data_id].shape != (0,):
if stg.depth_cross_section[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
elif stg.depth[data_id].shape != (0,):
self.axis_profile.plot(
stg.BS_raw_data[data_id][
self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1)
self.axis_profile.text(
.95, .05, stg.freq_text[data_id][
self.combobox_frequency_profile.currentIndex()],
fontsize=10, fontweight='bold', fontname="DejaVu Sans",
fontstyle="normal", c="black", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_profile.transAxes)
self.axis_profile.set_xlabel("Acoustic Backscatter Signal (V)")
self.axis_profile.set_ylabel("Depth (m)")
self.figure_profile.canvas.draw_idle()
# --- Update red line position on transect ---
if stg.depth_cross_section[data_id].shape != (0,):
if stg.time_cross_section[data_id].shape != (0,):
self.red_line_return.set_data(
stg.time_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), self.slider.value()-1] *
np.ones(stg.depth_cross_section[data_id].shape[1]),
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :])
elif stg.time[data_id].shape != (0,):
self.red_line_return.set_data(
stg.time[data_id][
self.combobox_frequency_profile.currentIndex(), self.slider.value() - 1] *
np.ones(stg.depth_cross_section[data_id].shape[1]),
-stg.depth_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), :])
elif stg.depth[data_id].shape != (0,):
if stg.time_cross_section[data_id].shape != (0,):
self.red_line_return.set_data(
stg.time_cross_section[data_id][
self.combobox_frequency_profile.currentIndex(), self.slider.value() - 1] *
np.ones(stg.depth[data_id].shape[1]),
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :])
elif stg.time[data_id].shape != (0,):
self.red_line_return.set_data(
stg.time[data_id][
self.combobox_frequency_profile.currentIndex(), self.slider.value() - 1] *
np.ones(stg.depth[data_id].shape[1]),
-stg.depth[data_id][
self.combobox_frequency_profile.currentIndex(), :])
self.fig_BS.canvas.draw_idle()
# ------------------------------------- Connect Push Button Load Data + Slider -------------------------------------
def slide_profile_number_to_begin(self):
self.slider.setValue(int(self.slider.minimum()))
self.update_lineEdit_by_moving_slider()
def slide_profile_number_to_right(self):
self.slider.setValue(int(self.slider.value()) + 1)
self.update_lineEdit_by_moving_slider()
def slide_profile_number_to_left(self):
self.slider.setValue(int(self.slider.value()) - 1)
self.update_lineEdit_by_moving_slider()
def slide_profile_number_to_end(self):
self.slider.setValue(int(self.slider.maximum()))
self.update_lineEdit_by_moving_slider()
def profile_number_on_lineEdit(self):
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.slider.setValue(
int(np.where(
np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_frequency_profile.currentIndex()] -
float(self.lineEdit_slider.text().replace(",", "."))) ==
np.nanmin(
np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_frequency_profile.currentIndex()] -
float(self.lineEdit_slider.text().replace(",", ".")))))[0][0]))
else:
self.slider.setValue(
int(np.where(
np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_frequency_profile.currentIndex()] -
float(self.lineEdit_slider.text().replace(",", "."))) ==
np.nanmin(
np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_frequency_profile.currentIndex()] -
float(self.lineEdit_slider.text().replace(",", ".")))))[0][0]))
def update_lineEdit_by_moving_slider(self):
if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.lineEdit_slider.setText(
str(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_profile.currentIndex(), self.slider.value()-1]))
else:
self.lineEdit_slider.setText(
str(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
self.combobox_frequency_profile.currentIndex(), self.slider.value()-1]))