# ============================================================================== #
    # acoustic_data_tab.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/>. #

    #                                                      by Brahim MOUDJED #
# ============================================================================== #

# -*- coding: utf-8 -*-


from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QGroupBox,
    QPushButton, QComboBox, QLineEdit, QLabel,
    QGridLayout, QTableView, QSpacerItem, QSizePolicy,
    QFileDialog, QMessageBox, QScrollArea,
    QSlider, QMenu, QCheckBox
)
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtCore import (
    Qt, QCoreApplication, pyqtSignal, QEvent, QSize,
    QPropertyAnimation
)

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm, CSS4_COLORS, BoundaryNorm
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar

import os
from copy import deepcopy
import locale

locale.setlocale(locale.LC_ALL, '')

from scipy.signal import savgol_filter

from re import findall

from pyqt_file_list_widget.fileListWidget import FileListWidget

import Translation.constant_string as cs

from Model.TableModel import TableModel
from Model.acoustic_data_loader import AcousticDataLoader
from Model.acoustic_data_loader_UBSediFlow import AcousticDataLoaderUBSediFlow
from Model.calibration_constant_kt import CalibrationConstantKt

import settings as stg

_translate = QCoreApplication.translate


class AcousticDataTab(QWidget):
    COMPTEUR = 1
    """
    This class generates the Acoustic Data Tab
    """

    fileAdded = pyqtSignal(list)
    fileRemoved = pyqtSignal(list)
    newValueChanged = pyqtSignal(float)

    def __init__(self, tab_widget):
        super().__init__()

        self.path_icon = "./icons/"
        self.icon_folder = QIcon(self.path_icon + "folder.png")
        self.icon_apply_limits = QIcon(self.path_icon + "circle_green_arrow_right.png")
        self.icon_triangle_left_to_begin = QIcon(self.path_icon + "triangle_left_to_begin.png")
        self.icon_triangle_left = QIcon(self.path_icon + "triangle_left.png")
        self.icon_triangle_right = QIcon(self.path_icon + "triangle_right.png")
        self.icon_triangle_right_to_end = QIcon(self.path_icon + "triangle_right_to_end.png")
        self.icon_add = QIcon(self.path_icon + "add.png")
        self.icon_delete = QIcon(self.path_icon + "delete.png")
        self.icon_clear = QIcon(self.path_icon + "clear.png")
        self.icon_between = QPixmap(self.path_icon + "between.png")
        self.icon_refresh = QIcon(self.path_icon + "update.png")
        self.calib_kt = CalibrationConstantKt()

        ### --- General layout of widgets ---

        self.verticalLayoutMain = QVBoxLayout(tab_widget)

        self.horizontalLayoutTop = QHBoxLayout()
        self.verticalLayoutMain.addLayout(self.horizontalLayoutTop, 5)         # 1O units is 100% , 1 units is 10%

        self.horizontalLayoutBottom = QHBoxLayout()
        self.verticalLayoutMain.addLayout(self.horizontalLayoutBottom, 5)

        ### --- Layout of groupbox in the Top horizontal layout box

        #           Download          |   Table of values   |      GPS file
        #   Measurement information   |                     |   Display options

        self.groupbox_download = QGroupBox()
        self.horizontalLayoutTop.addWidget(self.groupbox_download, 3)

        self.groupbox_table = QGroupBox()
        self.horizontalLayoutTop.addWidget(self.groupbox_table, 3)

        self.groupbox_display_option = QGroupBox()
        self.horizontalLayoutTop.addWidget(self.groupbox_display_option, 4)

        ### --- Layout of groupbox in the Bottom horizontal layout box

        #   2D field of raw acoustic backscatter data    |   2D field of Signal to Noise ratio

        self.groupbox_transect_2Dplot_raw_BS_data = QGroupBox()
        self.horizontalLayoutBottom.addWidget(self.groupbox_transect_2Dplot_raw_BS_data, 6)

        self.groupbox_plot_the_vertical_profile_for_a_frequency = QGroupBox()
        self.horizontalLayoutBottom.addWidget(self.groupbox_plot_the_vertical_profile_for_a_frequency, 4)

        # =====================================================
        #               TOP HORIZONTAL BOX LAYOUT
        # =====================================================

        self.groupbox_download.setTitle("Acoustic recording")
        self.verticalLayout_groupbox_download = QVBoxLayout(self.groupbox_download)

        self.groupbox_acoustic_file = QGroupBox()
        self.groupbox_acoustic_file.setTitle("Download file")
        self.verticalLayout_groupbox_download.addWidget(self.groupbox_acoustic_file, 5)

        self.groupbox_info = QGroupBox()
        self.scrollbar_measurement_information = QScrollArea()
        self.verticalLayout_groupbox_download.addWidget(self.scrollbar_measurement_information, 5)

        # +++++++++++++++++++++++++++
        # | Group box Download file |
        # +++++++++++++++++++++++++++

        self.gridLayout_groupbox_acoustic_file = QGridLayout(self.groupbox_acoustic_file)

        self.combobox_ABS_system_choice = QComboBox()
        self.combobox_ABS_system_choice.addItems([" ", "AQUAscat", "UBSediFlow"])
        self.gridLayout_groupbox_acoustic_file.addWidget(self.combobox_ABS_system_choice, 0, 0, 1, 1)

        self.spacerItem_FileList = QSpacerItem(5, 10, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.gridLayout_groupbox_acoustic_file.addItem(self.spacerItem_FileList, 0, 1, 1, 1)

        self.addBtn = QPushButton()
        self.addBtn.setIcon(self.icon_add)

        self.delBtn = QPushButton()
        self.delBtn.setIcon(self.icon_delete)

        self.clearBtn = QPushButton()
        self.clearBtn.setIcon(self.icon_clear)

        self.gridLayout_groupbox_acoustic_file.addWidget(self.addBtn, 0, 2, 1, 1)
        self.gridLayout_groupbox_acoustic_file.addWidget(self.delBtn, 0, 3, 1, 1)
        self.gridLayout_groupbox_acoustic_file.addWidget(self.clearBtn, 0, 4, 1, 1)

        self.fileListWidget = FileListWidget()
        self.gridLayout_groupbox_acoustic_file.addWidget(self.fileListWidget, 1, 0, 1, 5)

        # ++++++++++++++++++++++++++++++++++++++
        # | Group Box Measurements information |
        # ++++++++++++++++++++++++++++++++++++++

        self.scrollbar_measurement_information.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollbar_measurement_information.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollbar_measurement_information.setWidgetResizable(True)

        self.gridLayout_groupbox_info = QGridLayout(self.scrollbar_measurement_information)

        self.groupbox_info.setLayout(self.gridLayout_groupbox_info)

        self.scrollbar_measurement_information.setWidget(self.groupbox_info)

        self.label_ABS_name = QLabel()
        self.combobox_ABS_name = QComboBox()
        self.combobox_ABS_name.addItems(self.calib_kt.data_ABS.keys())

        self.label_date_acoustic_file = QLabel()
        self.label_hour_acoustic_file = QLabel()

        self.label_distance_from_ABS_to_free_surface = QLabel()
        self.label_distance_from_ABS_to_free_surface.setText("Distance from ABS to free surface")

        self.lineEdit_distance_from_ABS_to_free_surface = QLineEdit()
        self.lineEdit_distance_from_ABS_to_free_surface.setText("0.00")
        self.lineEdit_distance_from_ABS_to_free_surface.setMaximumWidth(100)

        self.label_distance_from_ABS_to_free_surface_unit = QLabel()
        self.label_distance_from_ABS_to_free_surface_unit.setText("m")

        self.pushbutton_distance_from_ABS_to_free_surface = QPushButton()
        self.pushbutton_distance_from_ABS_to_free_surface.setIcon(self.icon_refresh)

        self.label_temperature = QLabel("Temperature : ")

        self.lineEdit_temperature = QLineEdit()
        self.lineEdit_temperature.setText("0.00")
        self.lineEdit_temperature.setMaximumWidth(100)

        self.label_temperature_unit = QLabel()
        self.label_temperature_unit.setText("°C")

        self.label_speed_of_sound = QLabel("Speed of sound : ")

        self.lineEdit_speed_of_sound = QLineEdit()
        self.lineEdit_speed_of_sound.setMaximumWidth(100)

        self.label_speed_of_sound_unit = QLabel()
        self.label_speed_of_sound_unit.setText("m/s")

        self.label_freq = QLabel()
        self.combobox_frequency_information = QComboBox()
        self.combobox_frequency_information.setMaximumWidth(100)

        self.label_kt = QLabel()

        self.lineEdit_kt = QLineEdit()
        self.lineEdit_kt.setMaximumWidth(100)

        self.label_kt_unit = QLabel()
        self.label_kt_unit.setText("<p>V.m<sup>1.5</sup></p>")

        self.checkbox_kt = QCheckBox()
        self.checkbox_kt.setChecked(True)
        self.checkbox_kt.setToolTip("Checkbox checked : calibration is computed with kt value from the file (see File -> Settings -> ABS constant calibration kt) \n"
                                    "Checkbox unchecked : calibration is computed from kt values read from the ABS")

        self.label_sound_attenuation = QLabel("Sound attenuation : ")

        self.lineEdit_sound_attenuation = QLineEdit()
        self.lineEdit_sound_attenuation.setMaximumWidth(100)

        self.label_sound_attenuation_unit = QLabel()
        self.label_sound_attenuation_unit.setText("<p>m<sup>-1</sup><p>")

        self.label_profiles = QLabel()
        self.label_profiles_value = QLabel()
        self.label_profiles_per_sec = QLabel()
        self.label_profiles_per_sec_value = QLabel()
        self.label_cells = QLabel()  # n_cell in UBSediFlow parameters
        self.label_cells_value = QLabel()
        self.label_cell_size = QLabel()  # r_em in UBSediFlow parameters
        self.label_cell_size_value = QLabel()
        self.label_pulse_length = QLabel()  # n_p / PRF with n_p = n_ech, nb of pulses to calculate one instantaneous profile
        self.label_pulse_length_value = QLabel()
        self.label_pings_per_sec = QLabel()  # PRF in UBSediFlow parameters
        self.label_pings_per_sec_value = QLabel()
        self.label_pings_per_profile = QLabel()  # n_profile/n_avg in UBSediFlow parameters
        self.label_pings_per_profile_value = QLabel()

        self.label_rx = QLabel()  # a0 in UBSediFlow parameters

        self.lineEdit_rx = QLineEdit()
        self.lineEdit_rx.setMaximumWidth(100)

        self.checkbox_rx = QCheckBox()

        self.label_tx = QLabel()  # a1 in UBSediFlow parameters

        self.lineEdit_tx = QLineEdit()
        self.lineEdit_tx.setMaximumWidth(100)

        self.checkbox_tx = QCheckBox()


        # +++++++++++++++++++++++++++++
        # | Group Box Table of values |
        # +++++++++++++++++++++++++++++

        self.groupbox_table.setTitle("Table of values")
        self.verticalLayout_groupbox_table = QVBoxLayout(self.groupbox_table)

        self.tableView = QTableView()
        data = pd.DataFrame(np.zeros((10, 10)))
        self.tableModel = TableModel(data)
        self.tableView.setModel(self.tableModel)
        self.verticalLayout_groupbox_table.addWidget(self.tableView)

        # ++++++++++++++++++++++++++++
        # | Group Box Display option |
        # ++++++++++++++++++++++++++++

        self.groupbox_display_option.setTitle("Display option")
        self.verticalLayout_groupbox_display_option = QVBoxLayout(self.groupbox_display_option)

        # o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o

        # --- Group box GPS file ---

        self.groupbox_gps = QGroupBox()
        self.groupbox_gps.setTitle("Convert recording time to distance from bank")
        self.horizontal_gps_input_data = QHBoxLayout(self.groupbox_gps)

        self.verticalLayout_groupbox_display_option.addWidget(self.groupbox_gps)

        self.groupbox_gps_value = QGroupBox()
        self.groupbox_gps_value.setTitle("Value")
        self.groupbox_gps_value.setCheckable(True)
        self.groupbox_gps_value.setChecked(True)
        self.horizontal_gps_input_data.addWidget(self.groupbox_gps_value)

        self.gridLayout_gps_value = QGridLayout(self.groupbox_gps_value)
        self.label_distance_value = QLabel()
        self.label_distance_value.setText("Distance : ")
        self.gridLayout_gps_value.addWidget(self.label_distance_value, 0, 0, 1, 1)
        self.lineEdit_gps_value = QLineEdit()
        self.lineEdit_gps_value.setMaximumWidth(80)
        self.gridLayout_gps_value.addWidget(self.lineEdit_gps_value, 0, 1, 1, 1)
        self.label_m_per_record = QLabel("m / record")
        self.gridLayout_gps_value.addWidget(self.label_m_per_record, 0, 2, 1, 1)

        self.groupbox_gps_file = QGroupBox()
        self.groupbox_gps_file.setCheckable(True)
        self.groupbox_gps_file.setChecked(False)
        self.groupbox_gps_file.setTitle("GPS file")

        self.horizontal_gps_input_data.addWidget(self.groupbox_gps_file)

        self.gridLayout_groupbox_gps_file = QGridLayout(self.groupbox_gps_file)

        self.pushbutton_gps_file = QPushButton()
        self.pushbutton_gps_file.setIcon(self.icon_folder)
        self.gridLayout_groupbox_gps_file.addWidget(self.pushbutton_gps_file, 0, 0, 1, 1)
        self.lineEdit_gps_file = QLineEdit()
        self.gridLayout_groupbox_gps_file.addWidget(self.lineEdit_gps_file, 0, 1, 1, 1)

        # --- Time offset line between ABS system time and GPS time ---

        self.label_acoustic_gps_time = QLabel()
        self.label_acoustic_gps_time.setText(
            "T<span style= vertical-align:sub>acoustic</span> =" + " T<span style= vertical-align:sub>gps</span>")
        self.gridLayout_groupbox_gps_file.addWidget(self.label_acoustic_gps_time, 0, 2, 1, 1)
        self.combobox_plus_minus = QComboBox()
        self.combobox_plus_minus.addItem("+")
        self.combobox_plus_minus.addItem("-")
        self.gridLayout_groupbox_gps_file.addWidget(self.combobox_plus_minus, 0, 3, 1, 1)
        self.lineEdit_time_offset_value = QLineEdit()
        self.lineEdit_time_offset_value.setMaximumWidth(80)
        self.gridLayout_groupbox_gps_file.addWidget(self.lineEdit_time_offset_value, 0, 4, 1, 1)
        self.label_seconds = QLabel()
        self.label_seconds.setText("sec")
        self.gridLayout_groupbox_gps_file.addWidget(self.label_seconds, 0, 5, 1, 1)


        # ----------------------------------------------------------------------------

        # o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o

        # --- Groupbox display option limits ---

        self.groupbox_display_option_limits = QGroupBox()
        self.groupbox_display_option_limits.setTitle("Set the boundaries")
        self.gridLayout_groupbox_display_option_limits = QGridLayout(self.groupbox_display_option_limits)

        self.verticalLayout_groupbox_display_option.addWidget(self.groupbox_display_option_limits)

        # --------------------------------

        self.label_min = QLabel()
        self.label_min.setText("min")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_min, 0, 1, 1, 1, Qt.AlignCenter)

        self.label_upstream = QLabel()
        self.label_upstream.setText("limit -->")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_upstream, 0, 2, 1, 1, Qt.AlignCenter)

        self.label_downstream = QLabel()
        self.label_downstream.setText("<-- limit")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_downstream, 0, 3, 1, 1, Qt.AlignCenter)

        self.label_max = QLabel()
        self.label_max.setText("max")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_max, 0, 4, 1, 1, Qt.AlignCenter)

        self.label_unit = QLabel()
        self.label_unit.setText("unit")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_unit, 0, 5, 1, 1, Qt.AlignCenter)

        # --------------------------------

        self.label_depth = QLabel("Depth")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_depth, 1, 0, 1, 1, Qt.AlignRight)

        self.label_depth_min = QLabel()
        self.label_depth_min.setText("0.00")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_depth_min, 1, 1, 1, 1, Qt.AlignCenter)

        self.lineEdit_depth_min_limits = QLineEdit()
        self.lineEdit_depth_min_limits.setText("0.00")
        self.lineEdit_depth_min_limits.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.lineEdit_depth_min_limits, 1, 2, 1, 1, Qt.AlignCenter)

        self.lineEdit_depth_max_limits = QLineEdit()
        self.lineEdit_depth_max_limits.setText("0.00")
        self.lineEdit_depth_max_limits.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.lineEdit_depth_max_limits, 1, 3, 1, 1, Qt.AlignCenter)

        self.label_depth_max = QLabel()
        self.label_depth_max.setText("0.00")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_depth_max, 1, 4, 1, 1, Qt.AlignCenter)

        self.label_depth_unit_meter = QLabel("meters")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_depth_unit_meter, 1, 5, 1, 1, Qt.AlignCenter)

        self.pushbutton_apply_depth_limits = QPushButton()
        self.pushbutton_apply_depth_limits.setIcon(self.icon_apply_limits)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.pushbutton_apply_depth_limits, 1, 6, 1, 1)

        # --------------------------------

        self.label_recording_time = QLabel("Recording time")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_recording_time, 2, 0, 1, 1, Qt.AlignRight)

        self.label_time_min = QLabel()
        self.label_time_min.setText("0.00")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_time_min, 2, 1, 1, 1, Qt.AlignCenter)

        self.lineEdit_time_min_limits = QLineEdit()
        self.lineEdit_time_min_limits.setText("0.00")
        self.lineEdit_time_min_limits.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.lineEdit_time_min_limits, 2, 2, 1, 1,
                                                                 Qt.AlignCenter)

        self.lineEdit_time_max_limits = QLineEdit()
        self.lineEdit_time_max_limits.setText("0.00")
        self.lineEdit_time_max_limits.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.lineEdit_time_max_limits, 2, 3, 1, 1,
                                                                 Qt.AlignCenter)

        self.label_time_max = QLabel()
        self.label_time_max.setText("0.00")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_time_max, 2, 4, 1, 1, Qt.AlignCenter)

        self.label_recording_time_unit_meter = QLabel("seconds")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_recording_time_unit_meter, 2, 5, 1, 1, Qt.AlignCenter)

        self.pushbutton_apply_recording_time_limits = QPushButton()
        self.pushbutton_apply_recording_time_limits.setIcon(self.icon_apply_limits)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.pushbutton_apply_recording_time_limits, 2, 6, 1, 1)

        # ---------------------------------

        self.label_distance_from_bank = QLabel("Distance from bank")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_distance_from_bank, 3, 0, 1, 1, Qt.AlignRight)

        self.label_distance_from_bank_min = QLabel()
        self.label_distance_from_bank_min.setText("0.00")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_distance_from_bank_min, 3, 1, 1, 1, Qt.AlignCenter)

        self.lineEdit_distance_from_bank_min_limits = QLineEdit()
        self.lineEdit_distance_from_bank_min_limits.setText("0.00")
        self.lineEdit_distance_from_bank_min_limits.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.lineEdit_distance_from_bank_min_limits, 3, 2, 1, 1,
                                                                 Qt.AlignCenter)

        self.lineEdit_distance_from_bank_max_limits = QLineEdit()
        self.lineEdit_distance_from_bank_max_limits.setText("0.00")
        self.lineEdit_distance_from_bank_max_limits.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.lineEdit_distance_from_bank_max_limits, 3, 3, 1, 1,
                                                                 Qt.AlignCenter)

        self.label_distance_from_bank_max = QLabel()
        self.label_distance_from_bank_max.setText("0.00")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_distance_from_bank_max, 3, 4, 1, 1, Qt.AlignCenter)

        self.label_distance_from_bank_unit_meter = QLabel("meters")
        self.gridLayout_groupbox_display_option_limits.addWidget(self.label_distance_from_bank_unit_meter, 3, 5, 1, 1, Qt.AlignCenter)

        self.pushbutton_apply_distance_from_bank_limits = QPushButton()
        self.pushbutton_apply_distance_from_bank_limits.setIcon(self.icon_apply_limits)
        self.gridLayout_groupbox_display_option_limits.addWidget(self.pushbutton_apply_distance_from_bank_limits, 3, 6, 1, 1)

        # ---------------------------------------

        self.groupbox_display_option_bathymetry = QGroupBox()
        self.groupbox_display_option_bathymetry.setTitle("Detect bottom of the river")
        self.gridLayout_groupbox_display_option_bathymetry = QGridLayout(self.groupbox_display_option_bathymetry)

        self.verticalLayout_groupbox_display_option.addWidget(self.groupbox_display_option_bathymetry)

        self.combobox_frequency_bathymetry = QComboBox()
        self.combobox_frequency_bathymetry.setMaximumWidth(150)
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.combobox_frequency_bathymetry, 0, 0, 1, 1, Qt.AlignCenter)

        self.label_from_bathy = QLabel()
        self.label_from_bathy.setText("From")
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.label_from_bathy, 0, 1, 1, 1, Qt.AlignCenter)

        self.lineEdit_depth_min_bathy = QLineEdit()
        self.lineEdit_depth_min_bathy.setText("0.00")
        self.lineEdit_depth_min_bathy.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.lineEdit_depth_min_bathy, 0, 2, 1, 1, Qt.AlignCenter)

        self.label_depth_min_unit = QLabel()
        self.label_depth_min_unit.setText("m")
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.label_depth_min_unit, 0, 3, 1, 1, Qt.AlignLeft)

        self.label_to_bathy = QLabel()
        self.label_to_bathy.setText("to")
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.label_to_bathy, 0, 4, 1, 1, Qt.AlignCenter)

        self.lineEdit_depth_max_bathy = QLineEdit()
        self.lineEdit_depth_max_bathy.setText("0.00")
        self.lineEdit_depth_max_bathy.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.lineEdit_depth_max_bathy, 0, 5, 1, 1, Qt.AlignCenter)

        self.label_depth_max_unit = QLabel()
        self.label_depth_max_unit.setText("m")
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.label_depth_max_unit, 0, 6, 1, 1, Qt.AlignLeft)

        self.label_next_cell = QLabel()
        self.label_next_cell.setText("+/-")
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.label_next_cell, 0, 7, 1, 1, Qt.AlignCenter)

        self.lineEdit_next_cell_bathy = QLineEdit()
        self.lineEdit_next_cell_bathy.setText("0.00")
        self.lineEdit_next_cell_bathy.setMaximumWidth(80)
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.lineEdit_next_cell_bathy, 0, 8, 1, 1, Qt.AlignCenter)

        self.label_next_cell_unit = QLabel()
        self.label_next_cell_unit.setText("m")
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.label_next_cell_unit, 0, 9, 1, 1, Qt.AlignLeft)

        self.pushbutton_apply_bathymetry = QPushButton()
        self.pushbutton_apply_bathymetry.setIcon(self.icon_apply_limits)
        self.gridLayout_groupbox_display_option_bathymetry.addWidget(self.pushbutton_apply_bathymetry, 0, 10, 1, 1)

        # =====================================================
        #               BOTTOM HORIZONTAL BOX LAYOUT
        # =====================================================

        # +++++++++++++++++++++++++++++++++++++************+++
        # | Group Box Backscatter Acoustic Raw Data 2D field |
        # ++++++++++++++++++++++++++************++++++++++++++

        self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data = QVBoxLayout(self.groupbox_transect_2Dplot_raw_BS_data)

        self.canvas_BS = FigureCanvas()
        self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)

        self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.toolbar_BS)

        self.scroll_BS = QScrollArea()
        self.scroll_BS.setWidget(self.canvas_BS)
        self.scroll_BS.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scroll_BS.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scroll_BS.setAlignment(Qt.AlignCenter)
        self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS)

        # +++++++++++++++++++++++++++++++++++++++++++
        # | Group Box Plot profile from BS 2D field |
        # +++++++++++++++++++++++++++++++++++++++++++

        self.verticalLayout_groupbox_plot_the_vertical_profile_for_a_frequency = QVBoxLayout(self.groupbox_plot_the_vertical_profile_for_a_frequency)
        self.groupbox_plot_the_vertical_profile_for_a_frequency.setTitle("Plot the vertical profile for one frequency")

        self.horizontalLayout_spacerItem_combobox_frequency_profile = QHBoxLayout()
        self.verticalLayout_groupbox_plot_the_vertical_profile_for_a_frequency.addLayout(
            self.horizontalLayout_spacerItem_combobox_frequency_profile)
        self.spacerItem_frequency_profile = QSpacerItem(50, 10, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_spacerItem_combobox_frequency_profile.addSpacerItem(self.spacerItem_frequency_profile)
        self.combobox_frequency_profile = QComboBox()
        self.horizontalLayout_spacerItem_combobox_frequency_profile.addWidget(self.combobox_frequency_profile)

        self.groupbox_plot_profile = QGroupBox()
        self.verticalLayout_groupbox_plot_profile = QVBoxLayout(self.groupbox_plot_profile)

        self.verticalLayout_groupbox_plot_the_vertical_profile_for_a_frequency.addWidget(self.groupbox_plot_profile)

        self.canvas_plot_profile = FigureCanvas()

        self.toolbar_profile = NavigationToolBar(self.canvas_plot_profile, self)

        self.verticalLayout_groupbox_plot_profile.addWidget(self.toolbar_profile)
        self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_plot_profile)

        # --- Slider for moving the profile ---
        self.horizontalLayout_slider = QHBoxLayout()
        self.verticalLayout_groupbox_plot_the_vertical_profile_for_a_frequency.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)

        self.retranslate_acoustic_data_tab()

        self.max_selected_file = 1

        # --------------------------------------------------------------------------------------------------------------
        # --- Connect signal of widget ---

        self.combobox_ABS_system_choice.currentTextChanged.connect(self.ABS_system_choice)

        self.addBtn.clicked.connect(self.open_dialog_box)
        self.delBtn.clicked.connect(self.remove_file_from_ListWidget)
        self.clearBtn.clicked.connect(self.clear_files_from_ListWidget)

        self.fileListWidget.itemSelectionChanged.connect(self.print_selected_file)
        self.fileListWidget.itemSelectionChanged.connect(self.fill_measurements_information_groupbox)
        self.fileListWidget.itemSelectionChanged.connect(self.fill_table)
        self.fileListWidget.itemSelectionChanged.connect(self.compute_tmin_tmax)
        self.fileListWidget.itemSelectionChanged.connect(self.compute_rmin_rmax)
        self.fileListWidget.itemSelectionChanged.connect(self.update_frequency_combobox)
        self.fileListWidget.itemSelectionChanged.connect(self.plot_backscattered_acoustic_signal_recording)
        self.fileListWidget.itemSelectionChanged.connect(self.plot_profile)
        self.fileListWidget.itemSelectionChanged.connect(self.update_plot_backscattered_acoustic_signal_recording)
        self.fileListWidget.itemSelectionChanged.connect(self.update_plot_profile)
        self.fileListWidget.itemSelectionChanged.connect(self.set_range_for_spinboxes_bathymetry)

        self.combobox_ABS_name.currentIndexChanged.connect(self.fill_measurements_information_groupbox)

        self.checkbox_kt.stateChanged.connect(self.activate_unactivate_spinbox_kt)

        self.lineEdit_distance_from_ABS_to_free_surface.returnPressed.connect(self.distance_from_ABS_to_free_surface)
        self.pushbutton_distance_from_ABS_to_free_surface.clicked.connect(self.refresh_distance_from_ABS_to_free_surface)

        self.lineEdit_temperature.returnPressed.connect(self.temperature_value)
        self.lineEdit_speed_of_sound.returnPressed.connect(self.water_velocity)
        self.lineEdit_sound_attenuation.returnPressed.connect(self.water_attenuation)

        self.groupbox_gps_value.toggled.connect(self.groupbox_gps_value_toggle)
        self.groupbox_gps_value.toggled.connect(self.groupbox_gps_value_size_change)

        self.groupbox_gps_file.toggled.connect(self.groupbox_gps_file_toggle)
        self.groupbox_gps_file.toggled.connect(self.groupbox_gps_file_size_change)

        self.pushbutton_apply_depth_limits.clicked.connect(self.compute_BS_cross_section)
        self.pushbutton_apply_depth_limits.clicked.connect(self.update_plot_backscattered_acoustic_signal_recording)
        self.pushbutton_apply_depth_limits.clicked.connect(self.update_plot_profile)
        self.pushbutton_apply_depth_limits.clicked.connect(self.set_range_for_spinboxes_bathymetry)

        self.pushbutton_apply_recording_time_limits.clicked.connect(self.compute_BS_cross_section)
        self.pushbutton_apply_recording_time_limits.clicked.connect(self.detect_bottom)
        self.pushbutton_apply_recording_time_limits.clicked.connect(self.update_plot_backscattered_acoustic_signal_recording)
        self.pushbutton_apply_recording_time_limits.clicked.connect(self.update_plot_profile)

        self.pushbutton_apply_bathymetry.clicked.connect(self.detect_bottom)

        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.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.lineEdit_slider.returnPressed.connect(self.profile_number_on_lineEdit)

        self.slider.valueChanged.connect(self.update_lineEdit_by_moving_slider)
        self.slider.valueChanged.connect(self.update_plot_profile)
        self.slider.valueChanged.connect(self.update_plot_backscattered_acoustic_signal_recording)

    # -------------------- Functions for Acoustic dataTab --------------------

    def retranslate_acoustic_data_tab(self):

        self.groupbox_info.setTitle(_translate("CONSTANT_STRING", cs.MEASUREMENTS_INFORMATION))

        self.label_date_acoustic_file.setText(_translate("CONSTANT_STRING", cs.DATE) + ":")
        self.label_hour_acoustic_file.setText(_translate("CONSTANT_STRING", cs.HOUR) + ":")

        self.label_profiles.setText(_translate("CONSTANT_STRING", cs.NB_PROFILES) + ":")
        self.label_profiles.setToolTip(_translate("CONSTANT_STRING", cs.NB_PROFILES_TOOLTIP))

        self.label_profiles_per_sec.setText(_translate("CONSTANT_STRING", cs.NB_PROFILES_PER_SEC) + ":")
        self.label_profiles_per_sec.setToolTip(_translate("CONSTANT_STRING", cs.NB_PROFILES_PER_SEC_TOOLTIP))

        self.label_cells.setText(_translate("CONSTANT_STRING", cs.NB_CELLS) + ":")
        self.label_cells.setToolTip(_translate("CONSTANT_STRING", cs.NB_CELLS_TOOLTIP))

        self.label_cell_size.setText(_translate("CONSTANT_STRING", cs.CELL_SIZE) + ":")
        self.label_cell_size.setToolTip(_translate("CONSTANT_STRING", cs.CELL_SIZE_TOOLTIP))

        self.label_pulse_length.setText(_translate("CONSTANT_STRING", cs.PULSE_LENGHT) + ":")
        self.label_pulse_length.setToolTip(_translate("CONSTANT_STRING", cs.PULSE_LENGHT_TOOLTIP))

        self.label_pings_per_sec.setText(_translate("CONSTANT_STRING", cs.NB_PINGS_PER_SEC))
        self.label_pings_per_sec.setToolTip(_translate("CONSTANT_STRING", cs.NB_PINGS_PER_SEC_TOOLTIP))

        self.label_pings_per_profile.setText(_translate("CONSTANT_STRING", cs.NB_PINGS_PER_PROFILE) + ":")
        self.label_pings_per_profile.setToolTip(_translate("CONSTANT_STRING", cs.NB_PINGS_PER_PROFILE_TOOLTIP))

        self.label_freq.setText(_translate("CONSTANT_STRING", cs.FREQUENCY) + ":")
        self.label_freq.setToolTip(_translate("CONSTANT_STRING", cs.FREQUENCY_TOOLTIP))

        self.label_kt.setText(_translate("CONSTANT_STRING", cs.KT) + ":")
        self.label_kt.setToolTip(_translate("CONSTANT_STRING", cs.KT_TOOLTIP))

        self.label_rx.setText(_translate("CONSTANT_STRING", cs.GAIN_RX) + ":")
        self.label_rx.setToolTip(_translate("CONSTANT_STRING", cs.GAIN_RX_TOOLTIP))

        self.label_tx.setText(_translate("CONSTANT_STRING", cs.GAIN_TX) + ":")
        self.label_tx.setToolTip(_translate("CONSTANT_STRING", cs.GAIN_TX_TOOLTIP))

        self.groupbox_transect_2Dplot_raw_BS_data.setTitle(_translate("CONSTANT_STRING", cs.RAW_ACOUSTIC_DATA_2D_FIELD))

    def print_selected_file(self):
        print(f"Selected file in list widget : {self.fileListWidget.selectedItems()}")
        print("self.fileListWidget.selectedItems()[1:] : ", self.fileListWidget.selectedItems()[1:])
        if len(self.fileListWidget.selectedItems()) > self.max_selected_file:
            self.fileListWidget.setSelectionMode(1)

    def onClicked_radiobutton_gps(self):
        radiobutton = self.sender()

        if radiobutton.isChecked():
            if self.radiobutton_value.isChecked():
                self.groupbox_gps_value.setVisible(True)
                self.groupbox_gps_file.setVisible(False)
            elif self.radiobutton_file.isChecked():
                self.groupbox_gps_value.setVisible(False)
                self.groupbox_gps_file.setVisible(True)

    def ABS_system_choice(self):
        if self.combobox_ABS_system_choice.currentText() == " ":
            self.groupbox_measurement_information_no_ABS()
        elif self.combobox_ABS_system_choice.currentText() == "AQUAscat":
            self.groupbox_measurement_information_Aquascat()
        elif self.combobox_ABS_system_choice.currentText() == "UBSediFlow":
            self.groupbox_measurement_information_UBSediFlow()

    def groupbox_measurement_information_no_ABS(self):

        self.label_ABS_name.hide()

        self.combobox_ABS_name.hide()

        self.label_date_acoustic_file.hide()
        self.label_hour_acoustic_file.hide()

        self.label_distance_from_ABS_to_free_surface.hide()
        self.lineEdit_distance_from_ABS_to_free_surface.hide()
        self.label_distance_from_ABS_to_free_surface_unit.hide()
        self.pushbutton_distance_from_ABS_to_free_surface.hide()

        self.label_temperature.hide()
        self.lineEdit_temperature.hide()
        self.label_temperature_unit.hide()

        self.label_speed_of_sound.hide()
        self.lineEdit_speed_of_sound.hide()
        self.label_speed_of_sound_unit.hide()

        self.label_sound_attenuation.hide()
        self.lineEdit_sound_attenuation.hide()
        self.label_sound_attenuation_unit.hide()

        self.label_freq.hide()
        self.combobox_frequency_information.hide()

        self.label_profiles.hide()
        self.label_profiles_per_sec.hide()
        self.label_cells.hide()
        self.label_cell_size.hide()
        self.label_pulse_length.hide()
        self.label_pings_per_sec.hide()
        self.label_pings_per_profile.hide()

        self.label_kt.hide()
        self.lineEdit_kt.hide()
        self.label_kt_unit.hide()
        self.checkbox_kt.hide()

        self.label_rx.hide()
        self.lineEdit_rx.hide()
        self.checkbox_rx.hide()

        self.label_tx.hide()
        self.lineEdit_tx.hide()
        self.checkbox_tx.hide()

    def groupbox_measurement_information_Aquascat(self):
        # --- Hide UBSediFlow information and remove widget from grid layout ---
        self.label_ABS_name.hide()

        self.combobox_ABS_name.hide()

        self.label_date_acoustic_file.hide()
        self.label_hour_acoustic_file.hide()

        self.label_distance_from_ABS_to_free_surface.hide()
        self.lineEdit_distance_from_ABS_to_free_surface.hide()
        self.label_distance_from_ABS_to_free_surface_unit.hide()
        self.pushbutton_distance_from_ABS_to_free_surface.hide()

        self.label_temperature.hide()
        self.lineEdit_temperature.hide()
        self.label_temperature_unit.hide()

        self.label_speed_of_sound.hide()
        self.lineEdit_speed_of_sound.hide()
        self.label_speed_of_sound_unit.hide()

        self.label_sound_attenuation.hide()
        self.lineEdit_sound_attenuation.hide()
        self.label_sound_attenuation_unit.hide()

        self.label_freq.hide()
        self.combobox_frequency_information.hide()

        self.label_profiles.hide()
        self.label_profiles_per_sec.hide()
        self.label_cells.hide()
        self.label_cell_size.hide()
        self.label_pulse_length.hide()
        self.label_pings_per_sec.hide()
        self.label_pings_per_profile.hide()

        self.label_kt.hide()
        self.lineEdit_kt.hide()
        self.label_kt_unit.hide()
        self.checkbox_kt.hide()

        self.label_rx.hide()
        self.lineEdit_rx.hide()
        self.checkbox_rx.hide()

        self.label_tx.hide()
        self.lineEdit_tx.hide()
        self.checkbox_tx.hide()

        for i in reversed(range(self.gridLayout_groupbox_info.count())):
            widgetToRemove = self.gridLayout_groupbox_info.itemAt(i).widget()
            # remove it from the layout list
            self.gridLayout_groupbox_info.removeWidget(widgetToRemove)
            # remove it from the gui
            widgetToRemove.setParent(None)

        # --- Show Aquascat information ---

        self.label_ABS_name.show()
        self.label_ABS_name.setText("Acoustic Backscatter System: AQUAscat")
        self.gridLayout_groupbox_info.addWidget(self.label_ABS_name, 0, 0, 1, 2, Qt.AlignCenter)

        self.combobox_ABS_name.show()
        self.gridLayout_groupbox_info.addWidget(self.combobox_ABS_name, 0, 2, 1, 2, Qt.AlignCenter)

        self.label_date_acoustic_file.show()
        self.gridLayout_groupbox_info.addWidget(self.label_date_acoustic_file, 1, 0, 1, 1, Qt.AlignLeft)
        self.label_hour_acoustic_file.show()
        self.gridLayout_groupbox_info.addWidget(self.label_hour_acoustic_file, 1, 1, 1, 1, Qt.AlignLeft)

        self.label_distance_from_ABS_to_free_surface.show()
        self.gridLayout_groupbox_info.addWidget(self.label_distance_from_ABS_to_free_surface, 2, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_distance_from_ABS_to_free_surface.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_distance_from_ABS_to_free_surface, 2, 1, 1, 1, Qt.AlignLeft)
        self.label_distance_from_ABS_to_free_surface_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_distance_from_ABS_to_free_surface_unit, 2, 2, 1, 1, Qt.AlignLeft)
        self.pushbutton_distance_from_ABS_to_free_surface.show()
        self.gridLayout_groupbox_info.addWidget(self.pushbutton_distance_from_ABS_to_free_surface, 2, 3, 1, 1, Qt.AlignLeft)

        self.label_temperature.show()
        self.gridLayout_groupbox_info.addWidget(self.label_temperature, 3, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_temperature.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_temperature, 3, 1, 1, 1, Qt.AlignLeft)
        self.label_temperature_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_temperature_unit, 3, 2, 1, 1, Qt.AlignLeft)
        self.temperature_value()

        self.label_speed_of_sound.show()
        self.gridLayout_groupbox_info.addWidget(self.label_speed_of_sound, 4, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_speed_of_sound.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_speed_of_sound, 4, 1, 1, 1, Qt.AlignLeft)
        self.label_speed_of_sound_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_speed_of_sound_unit, 4, 2, 1, 1, Qt.AlignLeft)

        self.label_freq.show()
        self.gridLayout_groupbox_info.addWidget(self.label_freq, 5, 0, 1, 1, Qt.AlignLeft)
        self.combobox_frequency_information.show()
        self.gridLayout_groupbox_info.addWidget(self.combobox_frequency_information, 5, 1, 1, 1, Qt.AlignLeft)

        self.label_kt.show()
        self.gridLayout_groupbox_info.addWidget(self.label_kt, 6, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_kt.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_kt, 6, 1, 1, 1, Qt.AlignLeft)
        self.label_kt_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_kt_unit, 6, 2, 1, 1, Qt.AlignLeft)
        self.checkbox_kt.show()
        self.gridLayout_groupbox_info.addWidget(self.checkbox_kt, 6, 3, 1, 1, Qt.AlignLeft)

        self.label_sound_attenuation.show()
        self.gridLayout_groupbox_info.addWidget(self.label_sound_attenuation, 7, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_sound_attenuation.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_sound_attenuation, 7, 1, 1, 1, Qt.AlignLeft)
        self.label_sound_attenuation_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_sound_attenuation_unit, 7, 2, 1, 1, Qt.AlignLeft)

        self.label_profiles.show()
        self.gridLayout_groupbox_info.addWidget(self.label_profiles, 8, 0, 1, 1, Qt.AlignLeft)
        self.label_profiles_per_sec.show()
        self.gridLayout_groupbox_info.addWidget(self.label_profiles_per_sec, 9, 0, 1, 1, Qt.AlignLeft)
        self.label_cells.show()
        self.gridLayout_groupbox_info.addWidget(self.label_cells, 10, 0, 1, 1, Qt.AlignLeft)
        self.label_cell_size.show()
        self.gridLayout_groupbox_info.addWidget(self.label_cell_size, 11, 0, 1, 1, Qt.AlignLeft)
        self.label_pulse_length.show()
        self.gridLayout_groupbox_info.addWidget(self.label_pulse_length, 12, 0, 1, 1, Qt.AlignLeft)
        self.label_pings_per_sec.show()
        self.gridLayout_groupbox_info.addWidget(self.label_pings_per_sec, 13, 0, 1, 1, Qt.AlignLeft)
        self.label_pings_per_profile.show()
        self.gridLayout_groupbox_info.addWidget(self.label_pings_per_profile, 14, 0, 1, 1, Qt.AlignLeft)

        self.label_rx.show()
        self.gridLayout_groupbox_info.addWidget(self.label_rx, 15, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_rx.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_rx, 15, 1, 1, 1, Qt.AlignLeft)
        self.checkbox_rx.show()
        self.gridLayout_groupbox_info.addWidget(self.checkbox_rx, 15, 3, 1, 1, Qt.AlignLeft)

        self.label_tx.show()
        self.gridLayout_groupbox_info.addWidget(self.label_tx, 16, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_tx.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_tx, 16, 1, 1, 1, Qt.AlignLeft)
        self.checkbox_tx.show()
        self.gridLayout_groupbox_info.addWidget(self.checkbox_tx, 16, 3, 1, 1, Qt.AlignLeft)

    def groupbox_measurement_information_UBSediFlow(self):
        # --- Hide Aquascat information ---
        self.label_ABS_name.hide()

        self.combobox_ABS_name.hide()

        self.label_date_acoustic_file.hide()
        self.label_hour_acoustic_file.hide()

        self.label_distance_from_ABS_to_free_surface.hide()
        self.lineEdit_distance_from_ABS_to_free_surface.hide()
        self.label_distance_from_ABS_to_free_surface_unit.hide()
        self.pushbutton_distance_from_ABS_to_free_surface.hide()

        self.label_temperature.hide()
        self.lineEdit_temperature.hide()
        self.label_temperature_unit.hide()

        self.label_speed_of_sound.hide()
        self.lineEdit_speed_of_sound.hide()
        self.label_speed_of_sound_unit.hide()

        self.label_sound_attenuation.hide()
        self.lineEdit_sound_attenuation.hide()
        self.label_sound_attenuation_unit.hide()

        self.label_freq.hide()
        self.combobox_frequency_information.hide()

        self.label_profiles.hide()
        self.label_profiles_per_sec.hide()
        self.label_cells.hide()
        self.label_cell_size.hide()
        self.label_pulse_length.hide()
        self.label_pings_per_sec.hide()
        self.label_pings_per_profile.hide()

        self.label_kt.hide()
        self.lineEdit_kt.hide()
        self.label_kt_unit.hide()
        self.checkbox_kt.hide()

        self.label_rx.hide()
        self.lineEdit_rx.hide()
        self.checkbox_rx.hide()

        self.label_tx.hide()
        self.lineEdit_tx.hide()
        self.checkbox_tx.hide()

        for i in reversed(range(self.gridLayout_groupbox_info.count())):
            widgetToRemove = self.gridLayout_groupbox_info.itemAt(i).widget()
            # remove it from the layout list
            self.gridLayout_groupbox_info.removeWidget(widgetToRemove)
            # remove it from the gui
            widgetToRemove.setParent(None)

        # --- Show UBSediFlow information ---
        self.label_ABS_name.show()
        self.label_ABS_name.setText("Acoustic Backscatter System: UBSediFlow")
        self.gridLayout_groupbox_info.addWidget(self.label_ABS_name, 0, 0, 1, 2, Qt.AlignCenter)

        self.combobox_ABS_name.show()
        self.gridLayout_groupbox_info.addWidget(self.combobox_ABS_name, 0, 2, 1, 2, Qt.AlignCenter)

        self.label_date_acoustic_file.show()
        self.gridLayout_groupbox_info.addWidget(self.label_date_acoustic_file, 1, 0, 1, 1, Qt.AlignLeft)
        self.label_hour_acoustic_file.show()
        self.gridLayout_groupbox_info.addWidget(self.label_hour_acoustic_file, 1, 1, 1, 1, Qt.AlignLeft)

        self.label_distance_from_ABS_to_free_surface.show()
        self.gridLayout_groupbox_info.addWidget(self.label_distance_from_ABS_to_free_surface, 2, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_distance_from_ABS_to_free_surface.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_distance_from_ABS_to_free_surface, 2, 1, 1, 1, Qt.AlignLeft)
        self.label_distance_from_ABS_to_free_surface_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_distance_from_ABS_to_free_surface_unit, 2, 2, 1, 1, Qt.AlignLeft)
        self.pushbutton_distance_from_ABS_to_free_surface.show()
        self.gridLayout_groupbox_info.addWidget(self.pushbutton_distance_from_ABS_to_free_surface, 2, 3, 1, 1, Qt.AlignLeft)

        self.label_temperature.show()
        self.gridLayout_groupbox_info.addWidget(self.label_temperature, 3, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_temperature.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_temperature, 3, 1, 1, 1, Qt.AlignLeft)
        self.label_temperature_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_temperature_unit, 3, 2, 1, 1, Qt.AlignLeft)

        self.label_speed_of_sound.show()
        self.gridLayout_groupbox_info.addWidget(self.label_speed_of_sound, 4, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_speed_of_sound.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_speed_of_sound, 4, 1, 1, 1, Qt.AlignLeft)
        self.label_speed_of_sound_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_speed_of_sound_unit, 4, 2, 1, 1, Qt.AlignLeft)

        self.label_freq.show()
        self.gridLayout_groupbox_info.addWidget(self.label_freq, 5, 0, 1, 1, Qt.AlignLeft)
        self.combobox_frequency_information.show()
        self.gridLayout_groupbox_info.addWidget(self.combobox_frequency_information, 5, 1, 1, 1, Qt.AlignLeft)

        self.label_kt.show()
        self.gridLayout_groupbox_info.addWidget(self.label_kt, 6, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_kt.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_kt, 6, 1, 1, 1, Qt.AlignLeft)
        self.label_kt_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_kt_unit, 6, 2, 1, 1, Qt.AlignLeft)
        self.checkbox_kt.show()
        self.gridLayout_groupbox_info.addWidget(self.checkbox_kt, 6, 3, 1, 1, Qt.AlignLeft)

        self.label_sound_attenuation.show()
        self.gridLayout_groupbox_info.addWidget(self.label_sound_attenuation, 7, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_sound_attenuation.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_sound_attenuation, 7, 1, 1, 1, Qt.AlignLeft)
        self.label_sound_attenuation_unit.show()
        self.gridLayout_groupbox_info.addWidget(self.label_sound_attenuation_unit, 7, 2, 1, 1, Qt.AlignLeft)

        self.label_profiles.show()
        self.gridLayout_groupbox_info.addWidget(self.label_profiles, 8, 0, 1, 1, Qt.AlignLeft)
        self.label_profiles_per_sec.show()
        self.gridLayout_groupbox_info.addWidget(self.label_profiles_per_sec, 9, 0, 1, 1, Qt.AlignLeft)
        self.label_cells.show()
        self.gridLayout_groupbox_info.addWidget(self.label_cells, 10, 0, 1, 1, Qt.AlignLeft)
        self.label_cell_size.show()
        self.gridLayout_groupbox_info.addWidget(self.label_cell_size, 11, 0, 1, 1, Qt.AlignLeft)
        self.label_pulse_length.show()
        self.gridLayout_groupbox_info.addWidget(self.label_pulse_length, 12, 0, 1, 1, Qt.AlignLeft)
        self.label_pings_per_sec.show()
        self.gridLayout_groupbox_info.addWidget(self.label_pings_per_sec, 13, 0, 1, 1, Qt.AlignLeft)
        self.label_pings_per_profile.show()
        self.gridLayout_groupbox_info.addWidget(self.label_pings_per_profile, 14, 0, 1, 1, Qt.AlignLeft)

        self.label_rx.show()
        self.gridLayout_groupbox_info.addWidget(self.label_rx, 15, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_rx.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_rx, 15, 1, 1, 1, Qt.AlignLeft)
        self.checkbox_rx.show()
        self.gridLayout_groupbox_info.addWidget(self.checkbox_rx, 15, 2, 1, 1, Qt.AlignLeft)

        self.label_tx.show()
        self.gridLayout_groupbox_info.addWidget(self.label_tx, 16, 0, 1, 1, Qt.AlignLeft)
        self.lineEdit_tx.show()
        self.gridLayout_groupbox_info.addWidget(self.lineEdit_tx, 16, 1, 1, 1, Qt.AlignLeft)
        self.checkbox_tx.show()
        self.gridLayout_groupbox_info.addWidget(self.checkbox_tx, 16, 2, 1, 1, Qt.AlignLeft)

    def distance_from_ABS_to_free_surface(self):
        if self.fileListWidget.count() == 0:

            msgBox = QMessageBox()
            msgBox.setWindowTitle("Distance ABS - Free surface Error")
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Upload data before setting distance ABS - Free surface")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

            self.lineEdit_distance_from_ABS_to_free_surface.setText("0.00")

        else:

            stg.distance_from_ABS_to_free_surface[self.fileListWidget.currentRow()] = (
                float(self.lineEdit_distance_from_ABS_to_free_surface.text().replace(",", ".")))
            self.lineEdit_distance_from_ABS_to_free_surface.setText(
                str("%4s" % stg.distance_from_ABS_to_free_surface[self.fileListWidget.currentRow()]))

    def refresh_distance_from_ABS_to_free_surface(self):

        acoustic_data = AcousticDataLoader(stg.path_BS_raw_data[self.fileListWidget.currentRow()] + "/" +
                                           stg.filename_BS_raw_data[self.fileListWidget.currentRow()])

        stg.depth[self.fileListWidget.currentRow()] = acoustic_data._r
        stg.depth_reshape[self.fileListWidget.currentRow()] = acoustic_data.reshape_r()

        stg.depth[self.fileListWidget.currentRow()] = (
                stg.depth[self.fileListWidget.currentRow()] +
                stg.distance_from_ABS_to_free_surface[self.fileListWidget.currentRow()])

        stg.depth_reshape[self.fileListWidget.currentRow()] = (
                stg.depth_reshape[self.fileListWidget.currentRow()] +
                stg.distance_from_ABS_to_free_surface[self.fileListWidget.currentRow()])

        stg.depth_cross_section[self.fileListWidget.currentRow()] = stg.depth[self.fileListWidget.currentRow()]

        self.fill_table()

        self.compute_rmin_rmax()
        self.compute_depth_cross_section()
        self.set_range_for_spinboxes_bathymetry()

        self.compute_BS_cross_section()

        self.update_plot_backscattered_acoustic_signal_recording()
        self.update_plot_profile()

    def temperature_value(self):

        if findall(r",", self.lineEdit_temperature.text()):
            stg.temperature = float(self.lineEdit_temperature.text().replace(',', '.'))
            self.lineEdit_temperature.setText(self.lineEdit_temperature.text().replace(',', '.'))
        else:
            stg.temperature = float(self.lineEdit_temperature.text())
            self.lineEdit_temperature.setText(self.lineEdit_temperature.text())
        self.water_velocity()
        self.water_attenuation()

    def water_velocity(self):
        """Computing sond speed from Bilaniuk and Wong 1993"""
        C = (1.40238744 * 1e3 +
             5.03836171 * float(self.lineEdit_temperature.text()) -
             5.81172916 * 1e-2 * float(self.lineEdit_temperature.text()) ** 2 +
             3.34638117 * 1e-4 * float(self.lineEdit_temperature.text()) ** 3 -
             1.48259672 * 1e-6 * float(self.lineEdit_temperature.text()) ** 4 +
             3.16585020 * 1e-9 * float(self.lineEdit_temperature.text()) ** 5)
        stg.water_velocity = C

        self.lineEdit_speed_of_sound.setText(str(round(stg.water_velocity, 2)))

    def groupbox_gps_value_toggle(self):
        if self.groupbox_gps_value.isChecked() == True:
            self.groupbox_gps_file.setChecked(False)

    def groupbox_gps_value_size_change(self):

        duration = 500
        self.animation_groupbox_gps_value = QPropertyAnimation(self.groupbox_gps_value, b"size")
        self.animation_groupbox_gps_value.setDuration(duration)

        self.animation_groupbox_gps_value.setStartValue(QSize(self.groupbox_gps_value.width(),
                                              self.groupbox_gps_value.height()))

        if self.groupbox_gps_value.isChecked():
            self.animation_groupbox_gps_value.setEndValue(
                QSize(self.groupbox_gps_value.width(),
                      self.groupbox_gps_value.sizeHint().height()))
        else:
            self.animation_groupbox_gps_value.setEndValue(QSize(self.groupbox_gps_value.width(), 25))

        self.animation_groupbox_gps_value.start()

    def groupbox_gps_file_toggle(self):
        if self.groupbox_gps_file.isChecked() == True:
            self.groupbox_gps_value.setChecked(False)

    def groupbox_gps_file_size_change(self):

        duration = 500
        self.animation_groupbox_gps_file = QPropertyAnimation(self.groupbox_gps_file, b"size")
        self.animation_groupbox_gps_file.setDuration(duration)

        self.animation_groupbox_gps_file.setStartValue(QSize(self.groupbox_gps_file.width(),
                                              self.groupbox_gps_file.height()))

        if self.groupbox_gps_file.isChecked():
            self.animation_groupbox_gps_file.setEndValue(
                QSize(self.groupbox_gps_file.width(),
                      self.groupbox_gps_file.sizeHint().height()))
        else:
            self.animation_groupbox_gps_file.setEndValue(QSize(self.groupbox_gps_file.width(), 25))

        self.animation_groupbox_gps_file.start()

    # -------- Computing water attenuation coefficient ----------- #
    def water_attenuation(self):
        """Computing attenuation from François and Garrison 1982"""
        if self.fileListWidget.count() > 0:
            stg.water_attenuation[self.fileListWidget.currentRow()].clear()
            for f in stg.freq[self.fileListWidget.currentRow()]:
                if float(self.lineEdit_temperature.text()) > 20:
                    alpha = ((3.964 * 1e-4 -
                             1.146 * 1e-5 * float(self.lineEdit_temperature.text()) +
                             1.45 * 1e-7 * float(self.lineEdit_temperature.text()) ** 2 -
                             6.5 * 1e-10 * float(self.lineEdit_temperature.text()) ** 3) *
                             1e-3 * (np.log(10) / 20) * (f * 1e-3) ** 2)
                else:
                    alpha = ((4.937 * 1e-4 -
                             2.59 * 1e-5 * float(self.lineEdit_temperature.text()) +
                             9.11 * 1e-7 * float(self.lineEdit_temperature.text()) ** 2 -
                             1.5 * 1e-8 * float(self.lineEdit_temperature.text()) ** 3) *
                             1e-3 * (np.log(10) / 20) * (f * 1e-3) ** 2)

                stg.water_attenuation[self.fileListWidget.currentRow()].append(alpha)

            self.lineEdit_sound_attenuation.setText(
                str("%.6f" % stg.water_attenuation[self.fileListWidget.currentRow()][
                              self.combobox_frequency_information.currentIndex()]))

    def open_dialog_box(self):
        abs_params = [
            (None, None),
            ("AQUAscat file", "Aquascat file (*.aqa)"),
            ("UBSediFlow file", "UBSediFlow file (*.udt)"),
        ]


        system = self.combobox_ABS_system_choice.currentIndex()

        if system == 0:
            msgBox = QMessageBox()
            msgBox.setWindowTitle("Download Error")
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Choose ABS system before download acoustic files")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()
        else:
            abs_name, abs_file_type = abs_params[system]

            filenames, _ = QFileDialog.getOpenFileNames(
                self, abs_name,
                [
                    stg.path_BS_raw_data[-1]
                    if self.fileListWidget.count() > 0
                    else ""
                ][0],
                abs_file_type,
                options=QFileDialog.DontUseNativeDialog
            )

            if len(filenames) == 0:
                return

            for n in filenames:
                stg.path_BS_raw_data.append(os.path.dirname(n))
                stg.filename_BS_raw_data.append(os.path.basename(n))
                stg.data_preprocessed.append(os.path.basename(n))

            self.open_acoustic_data()

    def open_acoustic_data(self):
        # --- Fill lineEdit with path and file names + load acoustic data ---
        # --- fill date, hour and measurements information + fill frequency combobox for bottom detection ---
        system = self.combobox_ABS_system_choice.currentIndex()
        if system != 0:
            try:
                self.load_BS_acoustic_raw_data()
            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:
                if self.fileListWidget.count() == 0:
                    for p, f in zip(stg.path_BS_raw_data,
                                    stg.filename_BS_raw_data):
                        self.fileListWidget.addFilenames([f])
                        self.fileListWidget.setToolTip(p)
                else:
                    for k in range(self.fileListWidget.count(),
                                   len(stg.filename_BS_raw_data),
                                   1):
                        self.fileListWidget.addFilenames(
                            [stg.filename_BS_raw_data[k]]
                        )
                        self.fileListWidget.setToolTip(
                            stg.path_BS_raw_data[k]
                        )

                self.fill_measurements_information_groupbox()
                self.fill_table()
                self.plot_backscattered_acoustic_signal_recording()
                self.update_frequency_combobox()
                self.water_attenuation()

                stg.acoustic_data = list(
                    range(
                        self.fileListWidget.count()
                    )
                )

    def rename_file_in_ListWidget(self, event):

        if event == QEvent.MouseButtonPress:
            print("c'est bon")
            if event.button == Qt.RightButton:
                print("Right button clicked")
            elif event.button == Qt.LeftButton:
                print("Left button clicked")

        if event.type() == QEvent.ContextMenu:
            menu = QMenu()
            menu.addAction('Rename')

    def remove_file_from_ListWidget(self):
        if self.fileListWidget.count() > 0:

            # --- Clear files included in list Widget ---
            current_row = self.fileListWidget.currentRow()
            if current_row >= 0:
                current_item = self.fileListWidget.takeItem(current_row)
                del current_item

            # --- Clear variables ---
            list_to_pop1 = ["stg.acoustic_data", "stg.date", "stg.hour", "stg.freq", "stg.freq_text", "stg.temperature",
                            "stg.nb_profiles", "stg.nb_profiles_per_sec", "stg.nb_cells", "stg.cell_size",
                            "stg.pulse_length", "stg.nb_pings_per_sec", "stg.nb_pings_averaged_per_profile",
                            "stg.kt_read", "stg.kt_corrected", "stg.gain_rx", "stg.gain_tx",
                            "stg.filename_BS_raw_data", "stg.path_BS_raw_data",
                            "stg.BS_raw_data", "stg.time", "stg.depth",
                            "stg.BS_raw_data_reshape", "stg.time_reshape", "stg.depth_reshape"]

            for p in list_to_pop1:
                if isinstance(p, list):
                    exec(p + ".pop(current_row)")

            if stg.BS_cross_section:

                list_to_pop2 = ["stg.rmin", "stg.rmax", "stg.tmin", "stg.tmax",
                                "stg.time_cross_section", "stg.BS_cross_section"]

                for k in list_to_pop2:
                    exec(k + ".pop(current_row)")

            if self.fileListWidget.count() == 0:

                # --- Clear measurements information ---
                self.label_date_acoustic_file.clear()
                self.label_date_acoustic_file.setText("Date: ")
                self.label_hour_acoustic_file.clear()
                self.label_hour_acoustic_file.setText("Hour: ")
                self.lineEdit_sound_attenuation.setText("0.00")
                self.combobox_frequency_information.clear()
                self.label_profiles_value.clear()
                self.label_profiles_per_sec_value.clear()
                self.label_cells_value.clear()
                self.label_cell_size_value.clear()
                self.label_pulse_length_value.clear()
                self.label_pings_per_sec_value.clear()
                self.label_pings_per_profile_value.clear()
                self.lineEdit_kt.setText("0.00")
                self.lineEdit_rx.setText("0.00")
                self.lineEdit_tx.setText("0.00")

                # --- Clear display options ---

                self.label_time_min.setText("0.00")
                self.lineEdit_time_min_limits.setText("0.00")
                self.lineEdit_time_max_limits.setText("0.00")
                self.label_time_max.setText("0.00")

                self.label_depth_min.setText("0.00")
                self.lineEdit_depth_min_limits.setText("0.00")
                self.lineEdit_depth_max_limits.setText("0.00")
                self.label_depth_max.setText("0.00")

                self.label_distance_from_bank_min.setText("0.00")
                self.lineEdit_distance_from_bank_min_limits.setText("0.00")
                self.lineEdit_distance_from_bank_max_limits.setText("0.00")
                self.label_distance_from_bank_max.setText("0.00")

                self.combobox_frequency_bathymetry.clear()
                self.lineEdit_depth_min_bathy.setText("0.00")
                self.lineEdit_depth_max_bathy.setText("0.00")
                self.lineEdit_next_cell_bathy.setText("0.00")

                # --- Clear table of values ---
                self.tableView.reset()
                data = pd.DataFrame(np.zeros((10, 10)))
                self.tableModel = TableModel(data)
                self.tableView.setModel(self.tableModel)

                # --- Clear figure : 2D plot of the acoustic recording ---
                self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS)
                self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.toolbar_BS)

                self.canvas_BS = FigureCanvas()
                self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)
                self.scroll_BS.setWidget(self.canvas_BS)

                self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.toolbar_BS)
                self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS)

                # --- Clear figure : profile ---
                self.combobox_frequency_profile.clear()

                self.verticalLayout_groupbox_plot_profile.removeWidget(self.canvas_plot_profile)
                self.verticalLayout_groupbox_plot_profile.removeWidget(self.toolbar_profile)

                self.canvas_plot_profile = FigureCanvas()
                self.toolbar_profile = NavigationToolBar(self.canvas_plot_profile, self)

                self.verticalLayout_groupbox_plot_profile.addWidget(self.toolbar_profile)
                self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_plot_profile)

                self.slider.setValue(0)
                self.slider.setMaximum(10)

    def clear_files_from_ListWidget(self):

        list_to_clear = ["stg.acoustic_data", "stg.date", "stg.hour", "stg.freq", "stg.freq_text", "stg.temperature",
                             "stg.nb_profiles", "stg.nb_profiles_per_sec", "stg.nb_cells", "stg.cell_size",
                             "stg.pulse_length", "stg.nb_pings_per_sec", "stg.nb_pings_averaged_per_profile",
                             "stg.kt_read", "stg.kt_corrected", "stg.gain_rx", "stg.gain_tx",
                             "stg.BS_raw_data", "stg.time", "stg.depth",
                             "stg.BS_raw_data_reshape", "stg.time_reshape", "stg.depth_reshape",
                             "stg.rmin", "stg.rmax", "stg.tmin", "stg.tmax",
                             "stg.time_cross_section", "stg.depth_cross_section", "stg.BS_cross_section"]

        for k in list_to_clear:
            if isinstance(k, list):
                exec(k + ".clear()")

        self.fileListWidget.clear()

        if self.fileListWidget.count() == 0:
            # --- Clear measurmeents information ---
            self.label_date_acoustic_file.clear()
            self.label_date_acoustic_file.setText("Date: ")
            self.label_hour_acoustic_file.clear()
            self.label_hour_acoustic_file.setText("Hour: ")
            self.lineEdit_sound_attenuation.setText("0.00")
            self.combobox_frequency_information.clear()
            self.label_profiles_value.clear()
            self.label_profiles_per_sec_value.clear()
            self.label_cells_value.clear()
            self.label_cell_size_value.clear()
            self.label_pulse_length_value.clear()
            self.label_pings_per_sec_value.clear()
            self.label_pings_per_profile_value.clear()
            self.lineEdit_kt.setText("0.00")
            self.lineEdit_rx.setText("0.00")
            self.lineEdit_tx.setText("0.00")

            # --- Clear display options ---

            self.label_time_min.setText("0.00")
            self.lineEdit_time_min_limits.setText("0.00")
            self.lineEdit_time_max_limits.setText("0.00")
            self.label_time_max.setText("0.00")

            self.label_depth_min.setText("0.00")
            self.lineEdit_depth_min_limits.setText("0.00")
            self.lineEdit_depth_max_limits.setText("0.00")
            self.label_depth_max.setText("0.00")

            self.label_distance_from_bank_min.setText("0.00")
            self.lineEdit_distance_from_bank_min_limits.setText("0.00")
            self.lineEdit_distance_from_bank_max_limits.setText("0.00")
            self.label_distance_from_bank_max.setText("0.00")

            self.combobox_frequency_bathymetry.clear()
            self.lineEdit_depth_min_bathy.setText("0.00")
            self.lineEdit_depth_max_bathy.setText("0.00")
            self.lineEdit_next_cell_bathy.setText("0.00")

            # --- Clear table of values ---
            self.tableView.reset()
            data = pd.DataFrame(np.zeros((10, 10)))
            self.tableModel = TableModel(data)
            self.tableView.setModel(self.tableModel)

            # --- Clear figure : 2D plot of the acoustic recording ---
            self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS)
            self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.toolbar_BS)

            self.canvas_BS = FigureCanvas()
            self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)
            self.scroll_BS.setWidget(self.canvas_BS)

            self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.toolbar_BS)
            self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS)

            # --- Clear figure : profile ---
            self.combobox_frequency_profile.clear()

            self.verticalLayout_groupbox_plot_profile.removeWidget(self.canvas_plot_profile)
            self.verticalLayout_groupbox_plot_profile.removeWidget(self.toolbar_profile)

            self.canvas_plot_profile = FigureCanvas()
            self.toolbar_profile = NavigationToolBar(self.canvas_plot_profile, self)

            self.verticalLayout_groupbox_plot_profile.addWidget(self.toolbar_profile)
            self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_plot_profile)

            self.slider.setValue(0)
            self.slider.setMaximum(10)

    def load_BS_acoustic_raw_data(self):

        if self.fileListWidget.count() == 0:

            for p, f in zip(stg.path_BS_raw_data, stg.filename_BS_raw_data):

                if self.combobox_ABS_system_choice.currentIndex() == 1:

                    acoustic_data = AcousticDataLoader(p + "/" + f)

                elif self.combobox_ABS_system_choice.currentIndex() == 2:

                    acoustic_data = AcousticDataLoaderUBSediFlow(p + "/" + f)

                self.initiate_setting_parameters(acoustic_data=acoustic_data)

        else:

            for k in range(self.fileListWidget.count(), len(stg.filename_BS_raw_data), 1):

                if self.combobox_ABS_system_choice.currentIndex() == 1:

                    acoustic_data = AcousticDataLoader(stg.path_BS_raw_data[k] + "/" + stg.filename_BS_raw_data[k])

                elif self.combobox_ABS_system_choice.currentIndex() == 2:

                    acoustic_data = AcousticDataLoaderUBSediFlow(stg.path_BS_raw_data[k] + "/" + stg.filename_BS_raw_data[k])

                self.initiate_setting_parameters(acoustic_data=acoustic_data)

    def initiate_setting_parameters(self, acoustic_data):
        # --- The acoustic variables are field with loaded data ---

        stg.ABS_name.append(self.combobox_ABS_system_choice.currentText())
        stg.BS_raw_data.append(acoustic_data._BS_raw_data)
        stg.BS_raw_data_reshape.append(acoustic_data.reshape_BS_raw_data())
        stg.depth.append(acoustic_data._r)
        stg.depth_2D.append(np.array([]))
        stg.depth_reshape.append(acoustic_data.reshape_r())
        stg.time.append(acoustic_data._time)
        stg.time_reshape.append(acoustic_data.reshape_t())
        stg.freq.append(acoustic_data._freq)
        stg.freq_text.append(acoustic_data._freq_text)
        stg.date.append(acoustic_data._date)
        stg.hour.append(acoustic_data._hour)
        stg.distance_from_ABS_to_free_surface.append(0.00)
        stg.nb_profiles.append(acoustic_data._nb_profiles)
        stg.nb_profiles_per_sec.append(acoustic_data._nb_profiles_per_sec)
        stg.nb_cells.append(acoustic_data._nb_cells)
        stg.cell_size.append(acoustic_data._cell_size)
        stg.pulse_length.append(acoustic_data._cell_size)
        stg.nb_pings_per_sec.append(acoustic_data._nb_pings_per_sec)
        stg.nb_pings_averaged_per_profile.append(acoustic_data._nb_pings_averaged_per_profile)
        if self.combobox_ABS_name.currentIndex() == 1:
            stg.kt_read = acoustic_data._kt
        else:
            stg.kt_read = [0*i for i in range(acoustic_data._freq.shape[0])]
        stg.gain_rx.append(acoustic_data._gain_rx)
        stg.gain_tx.append(acoustic_data._gain_tx)
        stg.water_attenuation.append([])

        # --- The other acoustic variables lists are filled with empty object. ---
        # ---           They will be used for pre- and post-processing              ---

        stg.BS_cross_section.append(np.array([]))
        stg.depth_cross_section.append(np.array([]))
        stg.time_cross_section.append(np.array([]))

        stg.tmin.append((0, 0))
        stg.tmax.append((0, 0))
        stg.rmin.append((0, 0))
        stg.rmax.append((0, 0))

        stg.BS_stream_bed.append(np.array([]))
        stg.depth_bottom.append(np.array([]))
        stg.val_bottom.append([])
        stg.ind_bottom.append([])
        stg.freq_bottom_detection.append((0, 0))

        stg.BS_mean.append(np.array([]))
        stg.BS_noise_raw_data.append(np.array([]))
        stg.BS_noise_averaged_data.append(np.array([]))
        stg.SNR_raw_data.append(np.array([]))
        stg.SNR_cross_section.append(np.array([]))
        stg.SNR_stream_bed.append(np.array([]))
        stg.time_noise.append(np.array([]))
        stg.depth_noise.append(np.array([]))
        stg.noise_method.append(0)
        stg.noise_value.append(0)
        stg.SNR_filter_value.append(0)
        stg.Nb_cells_to_average_BS_signal.append(0)
        stg.filename_BS_noise_data.append("")
        stg.path_BS_noise_data.append("")

        stg.BS_raw_data_pre_process_SNR.append(np.array([]))
        stg.BS_raw_data_pre_process_average.append(np.array([]))

        stg.BS_cross_section_pre_process_SNR.append(np.array([]))
        stg.BS_cross_section_pre_process_average.append(np.array([]))

        stg.BS_stream_bed_pre_process_SNR.append(np.array([]))
        stg.BS_stream_bed_pre_process_average.append(np.array([]))

        stg.FCB = np.array([])
        stg.depth_real = np.array([])
        stg.lin_reg = []

        stg.kt2D.append(np.array([]))
        stg.kt3D.append(np.array([]))
        stg.J_cross_section.append([np.array([]), np.array([])])
        stg.VBI_cross_section.append(np.array([]))
        stg.SSC_fine.append(np.array([]))
        stg.SSC_sand.append(np.array([]))

    def fill_measurements_information_groupbox(self):

        if self.fileListWidget.currentRow() != -1:

            self.label_date_acoustic_file.clear()
            self.label_date_acoustic_file.setText("Date: " + str(stg.date[self.fileListWidget.currentRow()]))
            self.gridLayout_groupbox_info.addWidget(self.label_date_acoustic_file, 1, 0, 1, 1, Qt.AlignLeft)

            self.label_hour_acoustic_file.clear()
            self.label_hour_acoustic_file.setText("Hour: " + str(stg.hour[self.fileListWidget.currentRow()]))
            self.gridLayout_groupbox_info.addWidget(self.label_hour_acoustic_file, 1, 1, 1, 1, Qt.AlignLeft)

            self.combobox_frequency_information.clear()
            self.combobox_frequency_information.addItems(stg.freq_text[self.fileListWidget.currentRow()])
            self.combobox_frequency_information.currentIndexChanged.connect(self.combobox_frequency_information_update)

            self.lineEdit_temperature.setText(str(stg.temperature))

            self.label_profiles_value.setText(str(stg.nb_profiles[self.fileListWidget.currentRow()]
                                                       [self.combobox_frequency_information.currentIndex()]))
            self.gridLayout_groupbox_info.addWidget(self.label_profiles_value, 8, 1, 1, 1, Qt.AlignLeft)

            self.label_profiles_per_sec_value.setText(str(stg.nb_profiles_per_sec[self.fileListWidget.currentRow()]
                                                               [self.combobox_frequency_information.currentIndex()]) + " Hz")
            self.gridLayout_groupbox_info.addWidget(self.label_profiles_per_sec_value, 9, 1, 1, 1, Qt.AlignLeft)

            self.label_cells_value.setText(str(stg.nb_cells[self.fileListWidget.currentRow()]
                                                    [self.combobox_frequency_information.currentIndex()]))
            self.gridLayout_groupbox_info.addWidget(self.label_cells_value, 10, 1, 1, 1, Qt.AlignLeft)

            self.label_cell_size_value.setText(str(100*round(stg.cell_size[self.fileListWidget.currentRow()]
                                                                  [self.combobox_frequency_information.currentIndex()], 3)) + " cm")
            self.gridLayout_groupbox_info.addWidget(self.label_cell_size_value, 11, 1, 1, 1, Qt.AlignLeft)

            self.label_pulse_length_value.setText(str(round(stg.pulse_length[self.fileListWidget.currentRow()]
                                                                 [self.combobox_frequency_information.currentIndex()], 6)) + " sec")
            self.gridLayout_groupbox_info.addWidget(self.label_pulse_length_value, 12, 1, 1, 1, Qt.AlignLeft)

            self.label_pings_per_sec_value.setText(str(stg.nb_pings_per_sec[self.fileListWidget.currentRow()]
                                                            [self.combobox_frequency_information.currentIndex()]) + " Hz")
            self.gridLayout_groupbox_info.addWidget(self.label_pings_per_sec_value, 13, 1, 1, 1, Qt.AlignLeft)

            self.label_pings_per_profile_value.setText(str(stg.nb_pings_averaged_per_profile[self.fileListWidget.currentRow()]
                                                                [self.combobox_frequency_information.currentIndex()]))
            self.gridLayout_groupbox_info.addWidget(self.label_pings_per_profile_value, 14, 1, 1, 1, Qt.AlignLeft)

            stg.kt_corrected.clear()
            for f in range(stg.freq[self.fileListWidget.currentRow()].shape[0]):
                stg.kt_corrected.append(
                        self.calib_kt.data_ABS[self.combobox_ABS_name.currentText()].iloc[
                            np.where(
                                np.abs(np.array([stg.freq[self.fileListWidget.currentRow()][f] - l for l in
                                                 self.calib_kt.data_ABS[self.combobox_ABS_name.currentText()][
                                                     self.calib_kt.data_ABS[
                                                         self.combobox_ABS_name.currentText()].columns[0]].values]))
                                ==
                                np.min(np.abs(np.array([stg.freq[self.fileListWidget.currentRow()][f] - l for l in
                                                        self.calib_kt.data_ABS[self.combobox_ABS_name.currentText()][
                                                            self.calib_kt.data_ABS[
                                                                self.combobox_ABS_name.currentText()].columns[
                                                                0]].values])
                                              ))
                            )[0][0]
                        ][1])


            self.lineEdit_kt.setText(str("%.4f" % stg.kt_corrected[self.combobox_frequency_information.currentIndex()]))
            self.lineEdit_kt.setEnabled(True)
            self.lineEdit_kt.returnPressed.connect(self.kt_value)

            self.lineEdit_rx.setText(str("%.2f" % stg.gain_rx[self.fileListWidget.currentRow()][self.combobox_frequency_information.currentIndex()]))
            self.lineEdit_rx.setEnabled(False)
            self.checkbox_rx.stateChanged.connect(self.activate_unactivate_spinbox_rx)
            self.lineEdit_rx.returnPressed.connect(self.gain_rx_value)

            self.lineEdit_tx.setText(str("%.2f" % stg.gain_tx[self.fileListWidget.currentRow()][self.combobox_frequency_information.currentIndex()]))
            self.lineEdit_tx.setEnabled(False)
            self.checkbox_tx.stateChanged.connect(self.activate_unactivate_spinbox_tx)
            self.lineEdit_tx.returnPressed.connect(self.gain_tx_value)

    def combobox_frequency_information_update(self):
        if self.fileListWidget.count() > 0:

            if stg.water_attenuation[self.fileListWidget.currentRow()]:

                self.lineEdit_sound_attenuation.setText(
                    str("%.6f" % stg.water_attenuation[self.fileListWidget.currentRow()][
                                  self.combobox_frequency_information.currentIndex()]))

            self.label_profiles_value.clear()
            self.gridLayout_groupbox_info.removeWidget(self.label_profiles_value)
            self.label_profiles_value.setText(str(stg.nb_profiles[self.fileListWidget.currentRow()]
                                                   [self.combobox_frequency_information.currentIndex()]))
            self.gridLayout_groupbox_info.addWidget(self.label_profiles_value, 8, 1, 1, 1, Qt.AlignLeft)

            self.label_profiles_per_sec_value.clear()
            self.label_profiles_per_sec_value.setText(
                str(stg.nb_profiles_per_sec[self.fileListWidget.currentRow()]
                    [self.combobox_frequency_information.currentIndex()]) + " Hz")
            self.gridLayout_groupbox_info.addWidget(self.label_profiles_per_sec_value, 9, 1, 1, 1, Qt.AlignLeft)

            self.label_cells_value.clear()
            self.label_cells_value.setText(str(stg.nb_cells[self.fileListWidget.currentRow()]
                                                [self.combobox_frequency_information.currentIndex()]))
            self.gridLayout_groupbox_info.addWidget(self.label_cells_value, 10, 1, 1, 1, Qt.AlignLeft)

            self.label_cell_size_value.clear()
            self.gridLayout_groupbox_info.removeWidget(self.label_cell_size_value)
            self.label_cell_size_value.setText(
                str(100 * round(stg.cell_size[self.fileListWidget.currentRow()]
                                [self.combobox_frequency_information.currentIndex()], 3)) + " cm")
            self.gridLayout_groupbox_info.addWidget(self.label_cell_size_value, 11, 1, 1, 1, Qt.AlignLeft)

            self.label_pulse_length_value.clear()
            self.label_pulse_length_value.setText(
                str(round(stg.pulse_length[self.fileListWidget.currentRow()]
                          [self.combobox_frequency_information.currentIndex()], 6)) + " sec")
            self.gridLayout_groupbox_info.addWidget(self.label_pulse_length_value, 12, 1, 1, 1, Qt.AlignLeft)

            self.label_pings_per_sec_value.clear()
            self.label_pings_per_sec_value.setText(str(stg.nb_pings_per_sec[self.fileListWidget.currentRow()]
                                                        [self.combobox_frequency_information.currentIndex()]) + " Hz")
            self.gridLayout_groupbox_info.addWidget(self.label_pings_per_sec_value, 13, 1, 1, 1, Qt.AlignLeft)

            self.label_pings_per_profile_value.clear()
            self.label_pings_per_profile_value.setText(
                str(stg.nb_pings_averaged_per_profile[self.fileListWidget.currentRow()]
                    [self.combobox_frequency_information.currentIndex()]))
            self.gridLayout_groupbox_info.addWidget(self.label_pings_per_profile_value, 14, 1, 1, 1, Qt.AlignLeft)

            if self.checkbox_kt.isChecked():
                if self.combobox_frequency_information.count() > 0:
                    self.lineEdit_kt.setText(str("%.4f" % stg.kt_corrected[self.combobox_frequency_information.currentIndex()]))
            else:
                self.lineEdit_kt.setText(str("%.4f" % stg.kt_read[self.combobox_frequency_information.currentIndex()]))

            self.lineEdit_rx.setText(str(stg.gain_rx[self.fileListWidget.currentRow()][
                                             self.combobox_frequency_information.currentIndex()]))

            self.lineEdit_tx.setText(str(stg.gain_tx[self.fileListWidget.currentRow()][
                                             self.combobox_frequency_information.currentIndex()]))

    def activate_unactivate_spinbox_kt(self):
        if self.checkbox_kt.isChecked():
            self.lineEdit_kt.setEnabled(True)
            if stg.kt_corrected:
                self.lineEdit_kt.setText(str("%.4f" % stg.kt_corrected[self.combobox_frequency_information.currentIndex()]))
        else:
            self.lineEdit_kt.setDisabled(True)
            if stg.kt_read:
                self.lineEdit_kt.setText(str("%.4f" % stg.kt_read[self.combobox_frequency_information.currentIndex()]))

    def activate_unactivate_spinbox_rx(self):
        if self.checkbox_rx.isChecked():
            self.lineEdit_rx.setEnabled(True)
        else:
            self.lineEdit_rx.setDisabled(True)

    def activate_unactivate_spinbox_tx(self):
        if self.checkbox_tx.isChecked():
            self.lineEdit_tx.setEnabled(True)
        else:
            self.lineEdit_tx.setDisabled(True)

    def kt_value(self):

        if self.fileListWidget.count() > 0:
            if self.checkbox_kt.isChecked():

                if findall(r",", self.lineEdit_kt.text()):
                    stg.kt_corrected[self.combobox_frequency_information.currentIndex()] = (
                        float(self.lineEdit_kt.text().replace(',', '.')))
                    self.lineEdit_kt.setText("%.4f" % float(self.lineEdit_kt.text().replace(',', '.')))
                else:
                    stg.kt_corrected[self.combobox_frequency_information.currentIndex()] = (
                        float(self.lineEdit_kt.text()))
                    self.lineEdit_kt.setText("%.4f" % float(self.lineEdit_kt.text()))

    def gain_rx_value(self):
        if self.fileListWidget.count() > 0:
            stg.gain_rx[self.fileListWidget.currentRow()][self.combobox_frequency_information.currentIndex()] = (
                float(self.lineEdit_rx.text()))


    def gain_tx_value(self):
        if self.fileListWidget.count() > 0:
            stg.gain_tx[self.fileListWidget.currentRow()][self.combobox_frequency_information.currentIndex()] = (
                float(self.lineEdit_tx.text()))

    def fill_table(self):

        if self.fileListWidget.currentRow() != -1:

            header_list = []
            header_list.clear()
            table_data = np.array([[]])
            for freq_ind, freq_value in enumerate(stg.freq_text[0]):
                header_list.append("Time - " + freq_value)
                header_list.append("Depth - " + freq_value)
                header_list.append("BS - " + freq_value)

                if freq_ind == 0:
                    table_data = np.vstack((np.vstack((stg.time_reshape[self.fileListWidget.currentRow()][:, freq_ind],
                                                       stg.depth_reshape[self.fileListWidget.currentRow()][:, freq_ind])),
                                            stg.BS_raw_data_reshape[self.fileListWidget.currentRow()][:, freq_ind]))

                else:
                    table_data = np.vstack((table_data,
                                            np.vstack((np.vstack((stg.time_reshape[self.fileListWidget.currentRow()][:, freq_ind],
                                                                  stg.depth_reshape[self.fileListWidget.currentRow()][:, freq_ind])),
                                                       stg.BS_raw_data_reshape[self.fileListWidget.currentRow()][:, freq_ind]))
                                            ))

            stg.DataFrame_acoustic = pd.DataFrame(None)
            stg.DataFrame_acoustic = pd.DataFrame(data=table_data.transpose(), columns=header_list)

        self.tableModel = TableModel(stg.DataFrame_acoustic)
        self.tableView.setModel(self.tableModel)

    def export_table(self):
        if self.tableWidget.columnCount() == 10:
            msgBox = QMessageBox()
            msgBox.setWindowTitle("Export table Error")
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Fill table before export table")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()
        else:
            print("export table")

    def transect_xaxis_choice(self):
        if self.groupbox_xaxis_time.isChecked() == True:
            self.groupbox_xaxis_space.setChecked(False)
        elif self.groupbox_xaxis_space.isChecked() == True:
            self.groupbox_xaxis_time.setChecked(False)

    def compute_tmin_tmax(self):
        ''' tmin and tmax are filled with min and max of time when data are uploaded and
            double slider of time are updated with these values '''

        if self.fileListWidget.currentRow() != -1:

            # --- tmim / tmax ---
            tmin_indice = np.where(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmin(
                    stg.time[self.fileListWidget.currentRow()][0, :])) ==
                                       np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmin(
                                           stg.time[self.fileListWidget.currentRow()][0, :]))))[0][0]
            tmin_value = np.round(np.nanmin(stg.time[self.fileListWidget.currentRow()][0, :]), 2)
            stg.tmin[self.fileListWidget.currentRow()] = (tmin_indice, tmin_value)

            tmax_indice = np.where(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmax(
                    stg.time[self.fileListWidget.currentRow()][0, :])) ==
                                       np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmax(
                                           stg.time[self.fileListWidget.currentRow()][0, :]))))[0][0]
            tmax_value = np.round(np.nanmax(stg.time[self.fileListWidget.currentRow()][0, :]), 2)
            stg.tmax[self.fileListWidget.currentRow()] = (tmax_indice + 1, tmax_value)

            self.set_range_for_time_boundaries_option()

    def set_range_for_time_boundaries_option(self):

        self.label_time_min.clear()
        self.label_time_min.setText("%.5s" % str(stg.time[self.fileListWidget.currentRow()][0, 0]))

        self.label_time_max.clear()
        self.label_time_max.setText("%.5s" % str(stg.time[self.fileListWidget.currentRow()][0, -1]))

        if stg.time_cross_section[self.fileListWidget.currentRow()].shape != (0,):

            self.lineEdit_time_min_limits.setText("%.5s" % str(stg.time_cross_section[self.fileListWidget.currentRow()][0, 0]))
            self.lineEdit_time_max_limits.setText("%.5s" % str(stg.time_cross_section[self.fileListWidget.currentRow()][0, -1]))

        else:

            self.lineEdit_time_min_limits.setText("%.5s" % str(stg.time[self.fileListWidget.currentRow()][0, 0]))
            self.lineEdit_time_max_limits.setText("%.5s" % str(stg.time[self.fileListWidget.currentRow()][0, -1]))

    def compute_time_cross_section(self):

        ''' tmin and tmax are updated with double slider of time '''

        stg.tmin[self.fileListWidget.currentRow()] = ((
            np.where(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], 2) -
                            float(self.lineEdit_time_min_limits.text().replace(",", "."))) ==
                     np.nanmin(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :],
                                               2) - float(self.lineEdit_time_min_limits.text().replace(",", ".")))))[0][0],
            float(self.lineEdit_time_min_limits.text().replace(",", "."))
        ))

        stg.tmax[self.fileListWidget.currentRow()] = ((
                    np.where(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :], 2) -
                                    float(self.lineEdit_time_max_limits.text().replace(",", "."))) ==
                             np.nanmin(np.abs(np.round(stg.time[self.fileListWidget.currentRow()][0, :],
                                                       2) - float(self.lineEdit_time_max_limits.text().replace(",", ".")))))[0][0]+1,
                    float(self.lineEdit_time_max_limits.text().replace(",", "."))
                ))

        stg.time_cross_section[self.fileListWidget.currentRow()] = (
            stg.time[self.fileListWidget.currentRow()][:, stg.tmin[self.fileListWidget.currentRow()][0]:
                                                          stg.tmax[self.fileListWidget.currentRow()][0]]
        )

    def compute_rmin_rmax(self):
        ''' rmin and rmax are filled with min and max of depth when data are uploaded and
            double slider of depth are updated with these values '''

        if self.fileListWidget.currentRow() != -1:

            # --- rmim / rmax ---
            rmin_indice = np.where(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmin(
                stg.depth[self.fileListWidget.currentRow()][0, :])) ==
                                   np.nanmin(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmin(
                                       stg.depth[self.fileListWidget.currentRow()][0, :]))))[0][0]
            rmin_value = np.round(np.nanmin(stg.depth[self.fileListWidget.currentRow()][0, :]), 2)
            stg.rmin[self.fileListWidget.currentRow()] = (rmin_indice, rmin_value)

            rmax_indice = np.where(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmax(
                stg.depth[self.fileListWidget.currentRow()][0, :])) ==
                                   np.nanmin(np.abs(stg.depth[self.fileListWidget.currentRow()][0, :] - np.nanmax(
                                       stg.depth[self.fileListWidget.currentRow()][0, :]))))[0][0]
            rmax_value = np.round(np.nanmax(stg.depth[self.fileListWidget.currentRow()][0, :]), 2)
            stg.rmax[self.fileListWidget.currentRow()] = (rmax_indice + 1, rmax_value)

            self.set_range_for_depth_boundaries_option()

    def set_range_for_depth_boundaries_option(self):

        self.label_depth_min.clear()
        self.label_depth_min.setText("-" + str("%.5s" % stg.depth[self.fileListWidget.currentRow()][0, -1]))

        self.label_depth_max.clear()
        self.label_depth_max.setText("-" + str("%.5s" % stg.depth[self.fileListWidget.currentRow()][0, 0]))

        if stg.depth_cross_section[self.fileListWidget.currentRow()].shape != (0,):
            self.lineEdit_depth_min_limits.setText("-" + str("%.5s" % stg.depth_cross_section[self.fileListWidget.currentRow()][0, -1]))
            self.lineEdit_depth_max_limits.setText("-" + str("%.5s" % stg.depth_cross_section[self.fileListWidget.currentRow()][0, 0]))

        else:

            self.lineEdit_depth_min_limits.setText("-" + str("%.5s" % stg.depth[self.fileListWidget.currentRow()][0, -1]))
            self.lineEdit_depth_max_limits.setText("-" + str("%.5s" % stg.depth[self.fileListWidget.currentRow()][0, 0]))

    def compute_depth_cross_section(self):

        ''' rmin and rmax are updated with double slider of depth '''

        stg.rmin[self.fileListWidget.currentRow()] = ((
            np.where(np.abs(np.round(stg.depth[self.fileListWidget.currentRow()][0, :], 2) -
                            float("".join(findall("[.0-9]", self.lineEdit_depth_max_limits.text())))) ==
                     np.nanmin(np.abs(np.round(stg.depth[self.fileListWidget.currentRow()][0, :],
                                               2) - (float("".join(findall("[.0-9]", self.lineEdit_depth_max_limits.text()))))
                                      )))[0][0]+1,
            float("".join(findall("[.0-9]", self.lineEdit_depth_max_limits.text())))
        ))

        stg.rmax[self.fileListWidget.currentRow()] = ((
            np.where(np.abs(np.round(stg.depth[self.fileListWidget.currentRow()][0, :], 2) -
                            float("".join(findall("[.0-9]", self.lineEdit_depth_min_limits.text())))) ==
                     np.nanmin(np.abs(np.round(stg.depth[self.fileListWidget.currentRow()][0, :],
                                               2) - (float("".join(findall("[.0-9]", self.lineEdit_depth_min_limits.text()))))
                                      )))[0][0],
            float("".join(findall("[.0-9]", self.lineEdit_depth_min_limits.text())))
        ))


        stg.depth_cross_section[self.fileListWidget.currentRow()] = (
            stg.depth[self.fileListWidget.currentRow()][:,
            stg.rmin[self.fileListWidget.currentRow()][0]:stg.rmax[self.fileListWidget.currentRow()][0]]
        )

    def compute_BS_cross_section(self):
        if self.fileListWidget.currentRow() != -1:

            self.compute_depth_cross_section()
            self.compute_time_cross_section()

            stg.BS_cross_section[self.fileListWidget.currentRow()] = (
                stg.BS_raw_data[self.fileListWidget.currentRow()]
                [:, stg.rmin[self.fileListWidget.currentRow()][0]:stg.rmax[self.fileListWidget.currentRow()][0],
                stg.tmin[self.fileListWidget.currentRow()][0]:stg.tmax[self.fileListWidget.currentRow()][0]])

    def update_frequency_combobox(self):
        if self.fileListWidget.currentRow() != -1:
            self.combobox_frequency_bathymetry.clear()
            self.combobox_frequency_bathymetry.addItems([f for f in stg.freq_text[self.fileListWidget.currentRow()]])
            self.combobox_frequency_profile.clear()
            self.combobox_frequency_profile.addItems([f for f in stg.freq_text[self.fileListWidget.currentRow()]])

    def set_range_for_doubleRangeSlider_intg_area(self):
        if self.fileListWidget.currentRow() != -1:

            if stg.depth_cross_section[self.fileListWidget.currentRow()].shape == (0,):
                self.doubleRangeSlider_intg_area.setRange(
                    min=-stg.depth[self.fileListWidget.currentRow()][0, -1],
                    max=-stg.depth[self.fileListWidget.currentRow()][0, 0])

                self.doubleRangeSlider_intg_area.setValue(
                    value=(-stg.depth[self.fileListWidget.currentRow()][0, -1],
                           -stg.depth[self.fileListWidget.currentRow()][0, 0]))

            else:

                self.doubleRangeSlider_intg_area.setRange(
                    min=-stg.depth_cross_section[self.fileListWidget.currentRow()][0, -1],
                    max=-stg.depth_cross_section[self.fileListWidget.currentRow()][0, 0])

                self.doubleRangeSlider_intg_area.setValue(
                    value=(-stg.depth_cross_section[self.fileListWidget.currentRow()][0, -1],
                           -stg.depth_cross_section[self.fileListWidget.currentRow()][0, 0]))

    def set_range_for_spinboxes_bathymetry(self):
        if self.fileListWidget.currentRow() != -1:

            if stg.depth_cross_section[self.fileListWidget.currentRow()].shape != (0,):

                # self.spinbox_depth_min_bathy.setValue(stg.depth_cross_section[self.fileListWidget.currentRow()][0, 0])
                self.lineEdit_depth_min_bathy.setText(
                    "-" + str("%.5s" % stg.depth_cross_section[self.fileListWidget.currentRow()][0, -1]))
                # self.spinbox_depth_max_bathy.setValue(stg.depth_cross_section[self.fileListWidget.currentRow()][0, -1])
                self.lineEdit_depth_max_bathy.setText(
                    "-" + str("%.5s" % stg.depth_cross_section[self.fileListWidget.currentRow()][0, 0]))

            else:

                self.lineEdit_depth_min_bathy.setText(
                    "-" + str("%.5s" % stg.depth[self.fileListWidget.currentRow()][0, -1]))
                self.lineEdit_depth_max_bathy.setText(
                    "-" + str("%.5s" % stg.depth[self.fileListWidget.currentRow()][0, 0]))

    def plot_backscattered_acoustic_signal_recording(self):

        if self.fileListWidget.count() > 0:

            self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.toolbar_BS)
            self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS)

            self.fig_BS, self.axis_BS = plt.subplots(nrows=stg.freq[self.fileListWidget.currentRow()].shape[0], ncols=1,
                                                     sharex=False, 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_transect_2Dplot_raw_BS_data.addWidget(self.toolbar_BS)
            self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS)

            for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]):

                val_min = np.nanmin(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
                val_max = np.nanmax(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
                if val_min == 0:
                    val_min = 1e-5

                if self.combobox_ABS_system_choice.currentIndex() == 1:

                    pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :],
                                                             -stg.depth[self.fileListWidget.currentRow()][f, :],
                                                             stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :],
                                                             cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

                elif self.combobox_ABS_system_choice.currentIndex() == 2:
                    pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :],
                                                         -stg.depth[self.fileListWidget.currentRow()][f, :],
                                                         np.log(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]),
                                                         cmap='Blues')

                self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f],
                                         fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5,
                                         horizontalalignment='right', verticalalignment='bottom',
                                         transform=self.axis_BS[f].transAxes)

            # --- Plot red solid line on transect to visualize position of plotted profile ---
            self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot(
                stg.time[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(),
                                                           self.slider.value() - 1] * np.ones(stg.depth[self.fileListWidget.currentRow()].shape[1]),
                    -stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :],
                    color='red', linestyle="solid", linewidth=2)

            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()

    def update_plot_backscattered_acoustic_signal_recording(self):

        # --- Condition if table is filled but transect is not plotted
        # --- => Error message if spin box values of tmin or tmax is change
        if self.canvas_BS == None:
            msgBox = QMessageBox()
            msgBox.setWindowTitle("Plot transect Error")
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Plot transect before change x-axis value")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

        else:

            if self.fileListWidget.currentRow() != -1:
                if len(self.axis_BS.tolist()) != stg.freq[self.fileListWidget.currentRow()].shape[0]:
                    self.fig_BS, self.axis_BS = plt.subplots(nrows=stg.freq[self.fileListWidget.currentRow()].shape[0],
                                                             ncols=1,
                                                             sharex=False, sharey=False, layout="constrained")

                for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]):
                    self.axis_BS[f].cla()

                    if stg.BS_cross_section[self.fileListWidget.currentRow()].shape != (0,):

                        val_min = np.nanmin(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :])
                        val_max = np.nanmax(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :])
                        if val_min == 0:
                            val_min = 1e-5

                        if self.combobox_ABS_system_choice.currentIndex() == 1:
                            pcm = self.axis_BS[f].pcolormesh(
                                stg.time_cross_section[self.fileListWidget.currentRow()][f, :],
                                -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :],
                                stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :],
                                cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                        elif self.combobox_ABS_system_choice.currentIndex() == 2:
                            pcm = self.axis_BS[f].pcolormesh(
                                stg.time_cross_section[self.fileListWidget.currentRow()][f, :],
                                -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :],
                                np.log(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :,
                                       :]),
                                cmap='Blues')

                        # --- Plot red solid line on transect to visualize position of plotted profile ---
                        slider_value = \
                            [self.slider.value() - 1 if self.slider.value() - 1 <=
                                                        stg.time_cross_section[self.fileListWidget.currentRow()].shape[
                                                            1] - 1
                             else np.max(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1] - 1)][0]

                        self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot(
                            stg.time_cross_section[self.fileListWidget.currentRow()][
                                0,  # self.combobox_frequency_profile.currentIndex(),
                                slider_value] * np.ones(
                                stg.depth_cross_section[self.fileListWidget.currentRow()].shape[1]),
                            -stg.depth_cross_section[self.fileListWidget.currentRow()][
                             self.combobox_frequency_profile.currentIndex(), :],
                            color='red', linestyle="solid", linewidth=2)

                        # --- Plot river bottom line ---
                        if stg.depth_bottom[self.fileListWidget.currentRow()].shape != (0,):

                            self.axis_BS[f].plot(stg.time_cross_section[self.fileListWidget.currentRow()][
                                                 self.combobox_frequency_bathymetry.currentIndex(), :],
                                                 -stg.depth_bottom[self.fileListWidget.currentRow()],
                                                 color='black', linewidth=1, linestyle="solid")

                    else:

                        val_min = np.nanmin(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
                        val_max = np.nanmax(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
                        if val_min == 0:
                            val_min = 1e-5

                        if self.combobox_ABS_system_choice.currentIndex() == 1:
                            pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :],
                                                             -stg.depth[self.fileListWidget.currentRow()][f,
                                                              :],
                                                             stg.BS_raw_data[self.fileListWidget.currentRow()][f, :,
                                                             :],
                                                             cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

                        elif self.combobox_ABS_system_choice.currentIndex() == 2:
                            pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :],
                                                             -stg.depth[self.fileListWidget.currentRow()][f,
                                                              :],
                                                             np.log(
                                                                 stg.BS_raw_data[self.fileListWidget.currentRow()][f,
                                                                 :, :]),
                                                             cmap='Blues')

                        # --- Plot red solid line on transect to visualize position of plotted profile ---
                        slider_value = \
                            [self.slider.value() - 1 if self.slider.value() - 1 <=
                                                        stg.time[self.fileListWidget.currentRow()].shape[
                                                            1] - 1
                             else np.max(stg.time[self.fileListWidget.currentRow()].shape[1] - 1)][0]

                        self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot(
                            stg.time[self.fileListWidget.currentRow()][0, slider_value] *
                            np.ones(stg.depth[self.fileListWidget.currentRow()].shape[1]),
                            -stg.depth[self.fileListWidget.currentRow()][
                             self.combobox_frequency_profile.currentIndex(), :],
                            color='red', linestyle="solid", linewidth=2)

                        # --- Plot river bottom line ---
                        if stg.depth_bottom[self.fileListWidget.currentRow()].shape != (0,):
                            self.axis_BS[f].plot(stg.time[self.fileListWidget.currentRow()][
                                                 self.combobox_frequency_bathymetry.currentIndex(), :],
                                                 -stg.depth_bottom[self.fileListWidget.currentRow()],
                                                 color='black', linewidth=1, linestyle="solid")

                    self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f],
                                                 fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5,
                                                 horizontalalignment='right', verticalalignment='bottom',
                                                 transform=self.axis_BS[f].transAxes)

                self.fig_BS.supxlabel('Time (sec)', fontsize=10)
                self.fig_BS.supylabel('Depth (m)', fontsize=10)
                self.fig_BS.canvas.draw_idle()

    def plot_profile(self):
        if self.fileListWidget.currentRow() != -1:

            self.combobox_frequency_profile.setCurrentIndex(0)

            self.combobox_frequency_profile.currentIndexChanged.connect(self.update_plot_profile)
            self.combobox_frequency_profile.currentIndexChanged.connect(
                self.update_plot_backscattered_acoustic_signal_recording)

            self.slider.setMaximum(stg.time[self.fileListWidget.currentRow()].shape[1])

            self.verticalLayout_groupbox_plot_profile.removeWidget(self.toolbar_profile)
            self.verticalLayout_groupbox_plot_profile.removeWidget(self.canvas_plot_profile)

            # --- Figure to plot profiles ---
            self.fig_profile, self.axis_profile = plt.subplots(nrows=1, ncols=1, layout="constrained")
            self.canvas_plot_profile = FigureCanvas(self.fig_profile)
            self.toolbar_profile = NavigationToolBar(self.canvas_plot_profile, self)

            self.verticalLayout_groupbox_plot_profile.addWidget(self.toolbar_profile)
            self.verticalLayout_groupbox_plot_profile.addWidget(self.canvas_plot_profile)

            slider_value = [
                self.slider.value() - 1 if self.slider.value() - 1 <= stg.time[self.fileListWidget.currentRow()].shape[
                    1] - 1 else np.max(stg.time[self.fileListWidget.currentRow()].shape[1] - 1)][0]

            # --- Profile plot ---

            self.axis_profile.plot(stg.BS_raw_data[self.fileListWidget.currentRow()][
                                   self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
                                   -stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :],
                                   linestyle='solid', color='k', linewidth=1)
            self.axis_profile.text(.95, .05, stg.freq_text[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()],
                                              fontsize=10, fontweight='bold', fontname="Ubuntu",
                                              fontstyle="normal", c="black", alpha=0.2,
                                              horizontalalignment='right', verticalalignment='bottom',
                                              transform=self.axis_profile.transAxes)

            # --- Plot bottom line ---

            if len(stg.depth_bottom[self.fileListWidget.currentRow()]) != 0:

                self.axis_profile.plot([0,
                                            np.nanmax(stg.BS_raw_data[self.fileListWidget.currentRow()][
                                                      self.combobox_frequency_profile.currentIndex(),
                                                      :, slider_value])],
                                           -stg.depth[self.fileListWidget.currentRow()][
                                               self.combobox_frequency_profile.currentIndex(),
                                               int(stg.ind_bottom[self.fileListWidget.currentRow()][slider_value])] * np.ones(2),
                                           linestyle='solid', color='r', linewidth=1)

                position_x = (stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(),
                    int(stg.ind_bottom[self.fileListWidget.currentRow()][slider_value])] /
                                  np.nanmax(
                                      stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(),
                                      :]))

                self.axis_profile.text(.95, 1 - position_x + 0.05, "River bed",
                                           fontsize=10, fontweight='normal', fontname="Times New Roman",
                                           fontstyle="italic", c="red", alpha=0.2,
                                           horizontalalignment='right', verticalalignment='bottom',
                                           transform=self.axis_profile.transAxes)

            self.fig_profile.supxlabel("Acoustic Backscatter Signal (V)")
            self.fig_profile.supylabel("Depth (m)")

            self.fig_profile.canvas.draw_idle()

    def update_plot_profile(self):

        if self.fileListWidget.currentRow() != -1:

            if stg.BS_cross_section[self.fileListWidget.currentRow()].shape != (0,):

                self.axis_profile.cla()

                # --- Set slider value ---
                self.slider.setMaximum(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1])
                slider_value = [self.slider.value() - 1 if self.slider.value() - 1 <= stg.time_cross_section[
                    self.fileListWidget.currentRow()].shape[1] - 1
                                else np.max(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1] - 1)][0]

                # --- Profile plot ---
                self.axis_profile.plot(stg.BS_cross_section[self.fileListWidget.currentRow()][
                                       self.combobox_frequency_profile.currentIndex(), :, slider_value],
                                       -stg.depth_cross_section[self.fileListWidget.currentRow()][
                                        self.combobox_frequency_profile.currentIndex(), :],
                                       linestyle='solid', color='k', linewidth=1)

                # --- Write frequency on graph ---
                self.axis_profile.text(.95, .90, stg.freq_text[self.fileListWidget.currentRow()][
                    self.combobox_frequency_profile.currentIndex()],
                                       fontsize=14, fontweight='bold', fontname="Ubuntu",
                                       fontstyle="normal", c="black", alpha=0.2,
                                       horizontalalignment='right', verticalalignment='bottom',
                                       transform=self.axis_profile.transAxes)

                # --- Plot bottom line ---
                if stg.depth_bottom[self.fileListWidget.currentRow()].shape != (0,):
                    self.axis_profile.plot([0,
                                            np.nanmax(stg.BS_cross_section[self.fileListWidget.currentRow()][
                                                      self.combobox_frequency_profile.currentIndex(),
                                                      :, slider_value])],
                                           -stg.depth[self.fileListWidget.currentRow()][
                                               self.combobox_frequency_profile.currentIndex(),
                                               int(stg.ind_bottom[self.fileListWidget.currentRow()][
                                                   slider_value])] * np.ones(2),
                                           linestyle='solid', color='r', linewidth=1)

                    position_x = (stg.depth[self.fileListWidget.currentRow()][
                                      self.combobox_frequency_profile.currentIndex(),
                                      int(stg.ind_bottom[self.fileListWidget.currentRow()][slider_value])] /
                                  np.nanmax(stg.depth[self.fileListWidget.currentRow()][
                                            self.combobox_frequency_profile.currentIndex(), :]))

                    self.axis_profile.text(.95, 1 - position_x + 0.05, "River bed",
                                           fontsize=10, fontweight='normal', fontname="Ubuntu",
                                           fontstyle="italic", c="red", alpha=0.2,
                                           horizontalalignment='right', verticalalignment='bottom',
                                           transform=self.axis_profile.transAxes)

            else:

                self.axis_profile.cla()

                # --- Set slider value ---
                self.slider.setMaximum(stg.time[self.fileListWidget.currentRow()].shape[1])
                slider_value = [self.slider.value() - 1 if self.slider.value() - 1 <= stg.time[
                    self.fileListWidget.currentRow()].shape[1] - 1
                                else np.max(stg.time[self.fileListWidget.currentRow()].shape[1] - 1)][0]

                # --- Profile plot ---
                self.axis_profile.plot(stg.BS_raw_data[self.fileListWidget.currentRow()][
                                       self.combobox_frequency_profile.currentIndex(), :, self.slider.value() - 1],
                                       -stg.depth[self.fileListWidget.currentRow()][
                                        self.combobox_frequency_profile.currentIndex(), :],
                                       linestyle='solid', color='k', linewidth=1)

                # --- Write frequency on graph ---
                self.axis_profile.text(.95, .05, stg.freq_text[self.fileListWidget.currentRow()][
                    self.combobox_frequency_profile.currentIndex()],
                                       fontsize=10, fontweight='bold', fontname="Ubuntu",
                                       fontstyle="normal", c="black", alpha=0.2,
                                       horizontalalignment='right', verticalalignment='bottom',
                                       transform=self.axis_profile.transAxes)

                # --- Plot bottom line ---
                if stg.depth_bottom[self.fileListWidget.currentRow()].shape != (0,):
                    self.axis_profile.plot([0,
                                            np.nanmax(stg.BS_raw_data[self.fileListWidget.currentRow()][
                                                      self.combobox_frequency_profile.currentIndex(),
                                                      :, slider_value])],
                                           -stg.depth[self.fileListWidget.currentRow()][
                                               self.combobox_frequency_profile.currentIndex(),
                                               int(stg.ind_bottom[self.fileListWidget.currentRow()][
                                                   slider_value])] * np.ones(2),
                                           linestyle='solid', color='r', linewidth=1)

                    position_x = (stg.depth[self.fileListWidget.currentRow()][
                                      self.combobox_frequency_profile.currentIndex(),
                                      int(stg.ind_bottom[self.fileListWidget.currentRow()][slider_value])] /
                                  np.nanmax(stg.depth[self.fileListWidget.currentRow()][
                                            self.combobox_frequency_profile.currentIndex(), :]))

                    self.axis_profile.text(.95, 1 - position_x + 0.05, "River bed",
                                           fontsize=10, fontweight='normal', fontname="Ubuntu",
                                           fontstyle="italic", c="red", alpha=0.2,
                                           horizontalalignment='right', verticalalignment='bottom',
                                           transform=self.axis_profile.transAxes)

            self.fig_profile.supxlabel("Acoustic Backscatter Signal (V)")
            self.fig_profile.supylabel("Depth (m)")
            self.fig_profile.canvas.draw_idle()

    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.fileListWidget.currentRow()].shape != (0,):
            self.slider.setValue(
                int(np.where(np.abs(stg.time_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()] -
                               float(self.lineEdit_slider.text().replace(",", "."))) ==
                        np.nanmin(np.abs(stg.time_cross_section[self.fileListWidget.currentRow()][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.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()] -
                               float(self.lineEdit_slider.text().replace(",", "."))) ==
                        np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()] -
                                         float(self.lineEdit_slider.text().replace(",", ".")))))[0][0]))

    def update_lineEdit_by_moving_slider(self):
        print("min ", np.nanmin(stg.time[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()]))
        print("max ", np.nanmax(stg.time[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()]))
        if stg.time_cross_section[self.fileListWidget.currentRow()].shape != (0,):
            self.lineEdit_slider.setText(
                str(stg.time_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), self.slider.value()-1]))
        else:
            self.lineEdit_slider.setText(
                str(stg.time[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), self.slider.value()-1]))


    def detect_bottom(self):
        if self.fileListWidget.count() == 0:
            msgBox = QMessageBox()
            msgBox.setWindowTitle("Detect bottom Error")
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Load data before compute bathymety algorithm")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

        elif self.canvas_BS == None:
            msgBox = QMessageBox()
            msgBox.setWindowTitle("Detect bottom Error")
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Plot transect before compute bathymety algorithm")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

        elif self.lineEdit_next_cell_bathy.text() == "0.00":

            pass

        else:

            if stg.BS_cross_section[self.fileListWidget.currentRow()].shape != (0,):

                stg.freq_bottom_detection[self.fileListWidget.currentRow()] = \
                    (self.combobox_frequency_bathymetry.currentIndex(), self.combobox_frequency_bathymetry.currentText())

                rmin = float("".join(findall("[.0-9]", self.lineEdit_depth_max_bathy.text())))
                rmax = float("".join(findall("[.0-9]", self.lineEdit_depth_min_bathy.text())))

                r_bottom = np.zeros(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1])
                val_bottom = np.zeros(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1])

                r_bottom_ind = []

                BS_smooth = deepcopy(stg.BS_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :, :])

                for k in range(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1]):
                    BS_smooth[:, k] = savgol_filter(BS_smooth[:, k], 10, 2)

            # ----------- Detecting the bottom -------------
                for d in range(stg.time_cross_section[self.fileListWidget.currentRow()].shape[1]):

                    ind_min = np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][int(self.combobox_frequency_bathymetry.currentIndex()), :] >= rmin)[0][0]
                    ind_max = np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][int(self.combobox_frequency_bathymetry.currentIndex()), :] <= rmax)[0][-1]


                    # Getting the peak
                    try:
                        val_bottom[d] = np.nanmax(BS_smooth[ind_min:ind_max, d])

                    except ValueError as e:
                        msgBox = QMessageBox()
                        msgBox.setWindowTitle("Detect bottom Error")
                        msgBox.setIcon(QMessageBox.Warning)
                        msgBox.setText(f"1/ {e} : maximum value of section bottom is not found. \n "
                                       f"Please change parameter of algorithm")
                        msgBox.setStandardButtons(QMessageBox.Ok)
                        msgBox_return = msgBox.exec()
                        if msgBox_return == msgBox.Ok:
                            break
                    else:

                        ind_bottom = np.where((BS_smooth[ind_min:ind_max, d]) == val_bottom[d])[0][0]
                        np.append(stg.ind_bottom, ind_bottom)

                        r_bottom[d] = stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), ind_bottom + ind_min]
                        r_bottom_ind.append(ind_bottom + ind_min)
                        # Updating the range where we will look for the peak (in the next cell)
                        rmin = r_bottom[d] - float("".join(findall("[.0-9]", self.lineEdit_next_cell_bathy.text())))
                        rmax = r_bottom[d] + float("".join(findall("[.0-9]", self.lineEdit_next_cell_bathy.text())))

                BS_section_bottom = np.zeros((stg.depth_cross_section[self.fileListWidget.currentRow()].shape[1],
                                              stg.time_cross_section[self.fileListWidget.currentRow()].shape[1]))

                for i in range(BS_section_bottom.shape[0]):
                    try:
                        BS_section_bottom[r_bottom_ind[i]][i] = 1
                    except IndexError as e:
                        msgBox = QMessageBox()
                        msgBox.setWindowTitle("Detect bottom Error")
                        msgBox.setIcon(QMessageBox.Warning)
                        msgBox.setText(f"2/ {e} : maximum value of section bottom is not found. \n "
                                       f"Please change parameter of algorithm")
                        msgBox.setStandardButtons(QMessageBox.Ok)
                        msgBox_return = msgBox.exec()
                        if msgBox_return == msgBox.Ok:
                            break

                if BS_section_bottom.sum() > 2:

                    stg.depth_bottom[self.fileListWidget.currentRow()] = r_bottom

                    stg.val_bottom[self.fileListWidget.currentRow()] = val_bottom

                    stg.ind_bottom[self.fileListWidget.currentRow()] = r_bottom_ind


                    BS_stream_bed_copy = deepcopy(stg.BS_cross_section[self.fileListWidget.currentRow()])
                    for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]):
                        for k, _ in enumerate(stg.depth_bottom[self.fileListWidget.currentRow()]):
                            BS_stream_bed_copy[
                                f, np.where(stg.depth_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :]
                                            >= stg.depth_bottom[self.fileListWidget.currentRow()][k])[
                                    0], k] = np.nan

                    stg.BS_stream_bed[self.fileListWidget.currentRow()] = BS_stream_bed_copy

                    # --- Plot transect BS with bathymetry ---
                    for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]):
                        self.axis_BS[f].cla()

                        val_min = np.min(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
                        val_max = np.max(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
                        if val_min == 0:
                            val_min = 1e-5

                        if self.combobox_ABS_system_choice.currentIndex() == 1:
                            pcm = self.axis_BS[f].pcolormesh(stg.time_cross_section[self.fileListWidget.currentRow()][f, :],
                                                             -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :],
                                                             stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :],
                                                             cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                        elif self.combobox_ABS_system_choice.currentIndex() == 2:
                            pcm = self.axis_BS[f].pcolormesh(stg.time_cross_section[self.fileListWidget.currentRow()][f, :],
                                                             -stg.depth_cross_section[self.fileListWidget.currentRow()][f, :],
                                                             np.log(stg.BS_cross_section[self.fileListWidget.currentRow()][f, :, :]),
                                                             cmap='Blues')

                        self.axis_BS[f].plot(stg.time_cross_section[self.fileListWidget.currentRow()][self.combobox_frequency_bathymetry.currentIndex(), :],
                                             -stg.depth_bottom[self.fileListWidget.currentRow()],
                                             color='black', linewidth=1, linestyle="solid")

                        self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f],
                                             fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5,
                                             horizontalalignment='right', verticalalignment='bottom',
                                             transform=self.axis_BS[f].transAxes)

                        # --- Update plot profile ---
                        self.update_plot_profile()

                    self.fig_BS.canvas.draw_idle()

            elif stg.BS_raw_data[self.fileListWidget.currentRow()].shape != (0,):

                stg.freq_bottom_detection[self.fileListWidget.currentRow()] = (
                    self.combobox_frequency_bathymetry.currentIndex(), self.combobox_frequency_bathymetry.currentText())

                # Selecting the range in which we look for the bottom reflection
                rmin = float("".join(findall("[.0-9]", self.lineEdit_depth_max_bathy.text())))
                rmax = float("".join(findall("[.0-9]", self.lineEdit_depth_min_bathy.text())))

                # empty result arrays
                r_bottom = np.zeros(stg.time[self.fileListWidget.currentRow()].shape[1])
                val_bottom = np.zeros(stg.time[self.fileListWidget.currentRow()].shape[1])

                r_bottom_ind = []

                BS_smooth = deepcopy(stg.BS_raw_data[self.fileListWidget.currentRow()][
                                        self.combobox_frequency_bathymetry.currentIndex(), :, :])
                for k in range(stg.time[self.fileListWidget.currentRow()].shape[1]):
                    BS_smooth[:, k] = savgol_filter(BS_smooth[:, k], 10, 2)

                # ----------- Detecting the bottom -------------
                for d in range(stg.time[self.fileListWidget.currentRow()].shape[1]):
                    # Index of the range where we look for the peak
                    ind_min = np.where(stg.depth[self.fileListWidget.currentRow()][
                                        int(self.combobox_frequency_bathymetry.currentIndex()), :] >= rmin)[0][0]
                    ind_max = np.where(stg.depth[self.fileListWidget.currentRow()][
                                        int(self.combobox_frequency_bathymetry.currentIndex()), :] <= rmax)[0][-1]

                    # Getting the peak
                    try:
                        val_bottom[d] = np.nanmax(BS_smooth[ind_min:ind_max, d])

                    except ValueError as e:
                        msgBox = QMessageBox()
                        msgBox.setWindowTitle("Detect bottom Error")
                        msgBox.setIcon(QMessageBox.Warning)
                        msgBox.setText(f"1/ {e} : maximum value of section bottom is not found. \n "
                                        f"Please change parameter of algorithm")
                        msgBox.setStandardButtons(QMessageBox.Ok)
                        msgBox_return = msgBox.exec()
                        if msgBox_return == msgBox.Ok:
                            break  # msgBox.close()
                    else:
                        # Getting the range cell of the peak
                        ind_bottom = np.where((BS_smooth[ind_min:ind_max, d]) == val_bottom[d])[0][0]
                        np.append(stg.ind_bottom, ind_bottom)

                        r_bottom[d] = stg.depth[self.fileListWidget.currentRow()][
                            self.combobox_frequency_bathymetry.currentIndex(), ind_bottom + ind_min]
                        r_bottom_ind.append(ind_bottom + ind_min)

                        # Updating the range where we will look for the peak (in the next cell)
                        rmin = r_bottom[d] - float("".join(findall("[.0-9]", self.lineEdit_next_cell_bathy.text())))
                        rmax = r_bottom[d] + float("".join(findall("[.0-9]", self.lineEdit_next_cell_bathy.text())))

                BS_section_bottom = np.zeros((stg.depth[self.fileListWidget.currentRow()].shape[1],
                                                stg.time[self.fileListWidget.currentRow()].shape[1]))

                for i in range(BS_section_bottom.shape[0]):
                    try:
                        BS_section_bottom[r_bottom_ind[i]][i] = 1
                    except IndexError as e:
                        msgBox = QMessageBox()
                        msgBox.setWindowTitle("Detect bottom Error")
                        msgBox.setIcon(QMessageBox.Warning)
                        msgBox.setText(f"2/ {e} : maximum value of section bottom is not found. \n "
                                        f"Please change parameter of algorithm")
                        msgBox.setStandardButtons(QMessageBox.Ok)
                        msgBox_return = msgBox.exec()
                        if msgBox_return == msgBox.Ok:
                            break  # msgBox.close()

                if BS_section_bottom.sum() > 2:
                    # --- Record r_bottom for other tabs ---
                    stg.depth_bottom[self.fileListWidget.currentRow()] = r_bottom

                    stg.val_bottom[self.fileListWidget.currentRow()] = val_bottom

                    stg.ind_bottom[self.fileListWidget.currentRow()] = r_bottom_ind

                    BS_stream_bed_copy = deepcopy(stg.BS_raw_data[self.fileListWidget.currentRow()])
                    for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]):
                        for k, _ in enumerate(stg.depth_bottom[self.fileListWidget.currentRow()]):
                            BS_stream_bed_copy[
                                f, np.where(stg.depth[self.fileListWidget.currentRow()][
                                            self.combobox_frequency_bathymetry.currentIndex(), :]
                                            >= stg.depth_bottom[self.fileListWidget.currentRow()][k])[
                                    0], k] = np.nan

                    stg.BS_stream_bed[self.fileListWidget.currentRow()] = BS_stream_bed_copy

                    # --- Plot transect BS with bathymetry ---
                    for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]):
                        self.axis_BS[f].cla()

                        val_min = np.min(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
                        val_max = np.max(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
                        if val_min == 0:
                            val_min = 1e-5

                        if self.combobox_ABS_system_choice.currentIndex() == 1:
                            pcm = self.axis_BS[f].pcolormesh(
                                stg.time[self.fileListWidget.currentRow()][f, :],
                                -stg.depth[self.fileListWidget.currentRow()][f, :],
                                stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :],
                                cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                        elif self.combobox_ABS_system_choice.currentIndex() == 2:
                            pcm = self.axis_BS[f].pcolormesh(
                                stg.time[self.fileListWidget.currentRow()][f, :],
                                -stg.depth[self.fileListWidget.currentRow()][f, :],
                                np.log(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]),
                                cmap='Blues')

                        self.axis_BS[f].plot(stg.time[self.fileListWidget.currentRow()][
                                                self.combobox_frequency_bathymetry.currentIndex(), :],
                                                -stg.depth_bottom[self.fileListWidget.currentRow()],
                                                color='black', linewidth=1, linestyle="solid")

                        self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f],
                                                fontsize=14, fontweight='bold', fontname="Ubuntu", c="black",
                                                alpha=0.5,
                                                horizontalalignment='right', verticalalignment='bottom',
                                                transform=self.axis_BS[f].transAxes)

                        # --- Update plot profile ---
                        self.update_plot_profile()

                    self.fig_BS.canvas.draw_idle()
