# ============================================================================== #
    # 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 -*-

import os
import logging

from scipy.stats import linregress

import numpy as np
import pandas as pd

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

from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QComboBox,
    QGridLayout, QLabel, QPushButton, QSlider, QLineEdit,
    QFileDialog, QMessageBox, QFrame
)

from PyQt5.QtCore import Qt, QPropertyAnimation, QSize
from PyQt5.QtGui import QIcon, QPixmap, QFont

import settings as stg

from View.checkable_combobox import CheckableComboBox
from Model.acoustic_inversion_method_high_concentration import AcousticInversionMethodHighConcentration

logger = logging.getLogger()

class SedimentCalibrationTab(QWidget):

    ''' This class generates the Sediment Calibration Tab '''

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

        self._widget_tab = widget_tab
        self.inv_hc = AcousticInversionMethodHighConcentration()

        self._setup_icons()
        self._setup_widgets()

    def _path_icon(self, icon):
        return os.path.join("icons", icon)

    def _setup_icons(self):
        self.icon_folder = QIcon(self._path_icon("folder.png"))
        self.icon_triangle_left = QIcon(self._path_icon("triangle_left.png"))
        self.icon_triangle_left_to_begin = QIcon(
            self._path_icon("triangle_left_to_begin.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_update = QIcon(self._path_icon("update.png"))
        self.icon_approved = QIcon(self._path_icon("approved.png"))
        self.icon_no_approved = QIcon(self._path_icon("no_approved.png"))


    def _setup_widgets(self):
        self.verticalLayoutMain = QVBoxLayout(self._widget_tab)

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

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

        self.groupbox_acoustic_data = QGroupBox()
        self.horizontalLayoutTop.addWidget(self.groupbox_acoustic_data, 6)

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

        self._setup_widgets_acoustic_data()
        self._setup_widgets_concentration()
        self._setup_widgets_calibration()
        self._setup_widgets_fcb()

        self._setup_connections()

    def _setup_widgets_acoustic_data(self):
        self.groupbox_acoustic_data.setTitle(
            "Step 1 : acoustic and sample data choice"
        )

        self.horizontalLayout_groupbox_acoustic_data = QHBoxLayout(self.groupbox_acoustic_data)

        self.groupbox_data_choice = QGroupBox()
        self.horizontalLayout_groupbox_acoustic_data.addWidget(self.groupbox_data_choice, 3)

        self.groupbox_data_plot = QGroupBox()
        self.horizontalLayout_groupbox_acoustic_data.addWidget(self.groupbox_data_plot, 7)

        self.verticalLayout_groupbox_data_choice = QVBoxLayout(self.groupbox_data_choice)

        self._setup_widgets_acoustic_data_1()
        self._setup_widgets_acoustic_data_2()
        self._setup_widgets_acoustic_data_3()
        self._setup_widgets_acoustic_data_plot()

    def _setup_widgets_acoustic_data_1(self):
        self.groupbox_acoustic_recording = QGroupBox()
        self.groupbox_acoustic_recording.setTitle("➊")
        self.verticalLayout_groupbox_data_choice.addWidget(
            self.groupbox_acoustic_recording
        )

        self.gridLayout_groupbox_acoustic_recording = QGridLayout(
            self.groupbox_acoustic_recording
        )

        self.pushbutton_update_acoustic_file = QPushButton()
        self.pushbutton_update_acoustic_file.setIcon(self.icon_update)
        self.gridLayout_groupbox_acoustic_recording.addWidget(
            self.pushbutton_update_acoustic_file, 0, 0, 1, 2
        )

        self.label_acoustic_data_choice = QLabel()
        self.label_acoustic_data_choice.setText("Acoustic data")
        self.gridLayout_groupbox_acoustic_recording.addWidget(
            self.label_acoustic_data_choice, 1, 0, 1, 1
        )

        self.combobox_acoustic_data_choice = QComboBox()
        self.gridLayout_groupbox_acoustic_recording.addWidget(
            self.combobox_acoustic_data_choice, 1, 1, 1, 1
        )

    def _setup_widgets_acoustic_data_2(self):
        self.groupbox_frequency = QGroupBox()
        self.groupbox_frequency.setTitle("➋")
        self.verticalLayout_groupbox_data_choice.addWidget(
            self.groupbox_frequency
        )

        self.gridLayout_groupbox_frequency = QGridLayout(
            self.groupbox_frequency
        )

        self.label_freq1_choice = QLabel()
        self.label_freq1_choice.setText("Frequency 1")
        self.gridLayout_groupbox_frequency.addWidget(
            self.label_freq1_choice, 0, 0, 1, 1
        )

        self.combobox_freq1 = QComboBox()
        self.gridLayout_groupbox_frequency.addWidget(
            self.combobox_freq1, 0, 1, 1, 1
        )

        self.label_freq2_choice = QLabel()
        self.label_freq2_choice.setText("Frequency 2")
        self.gridLayout_groupbox_frequency.addWidget(
            self.label_freq2_choice, 1, 0, 1, 1
        )

        self.combobox_freq2 = QComboBox()
        self.gridLayout_groupbox_frequency.addWidget(
            self.combobox_freq2, 1, 1, 1, 1
        )

    def _setup_widgets_acoustic_data_3(self):
        self.groupbox_sample = QGroupBox()
        self.groupbox_sample.setTitle("➌")
        self.verticalLayout_groupbox_data_choice.addWidget(
            self.groupbox_sample
        )

        self.gridLayout_groupbox_sample = QGridLayout(
            self.groupbox_sample
        )

        self.label_fine_profile = QLabel()
        self.label_fine_profile.setText("Fine profile")
        self.gridLayout_groupbox_sample.addWidget(
            self.label_fine_profile, 0, 0, 1, 1
        )
        self.combobox_fine_sample_choice = CheckableComboBox()
        self.gridLayout_groupbox_sample.addWidget(
            self.combobox_fine_sample_choice, 0, 1, 1, 1
        )

        self.label_sand_target = QLabel()
        self.label_sand_target.setText("Sand target")
        self.gridLayout_groupbox_sample.addWidget(
            self.label_sand_target, 1, 0, 1, 1
        )
        self.combobox_sand_sample_choice = QComboBox()
        self.gridLayout_groupbox_sample.addWidget(
            self.combobox_sand_sample_choice, 1, 1, 1, 1
        )

        self.pushbutton_plot_sample = QPushButton()
        self.pushbutton_plot_sample.setText("Plot sample")
        self.gridLayout_groupbox_sample.addWidget(
            self.pushbutton_plot_sample, 2, 0, 1, 2
        )

    def _setup_widgets_acoustic_data_plot(self):
        self.verticalLayout_groupbox_data_plot = QVBoxLayout(
            self.groupbox_data_plot
        )

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

        # self.verticalLayout_groupbox_acoustic_data.addWidget(self.canvas_BS)
        self.verticalLayout_groupbox_data_plot.addWidget(self.toolbar_BS)
        self.verticalLayout_groupbox_data_plot.addWidget(self.canvas_BS)


    def _setup_widgets_concentration(self):
        self.groupbox_Mfine_profile.setTitle(
            "Step 2 : profile of the fine sediment concentration"
        )
        self.horizontalLayout_groupbox_Mfine_profile = QHBoxLayout(
            self.groupbox_Mfine_profile
        )

        self.groupbox_interpolate_info = QGroupBox()
        self.horizontalLayout_groupbox_Mfine_profile.addWidget(
            self.groupbox_interpolate_info, 4
        )

        self.groupbox_interpolate_plot = QGroupBox()
        self.horizontalLayout_groupbox_Mfine_profile.addWidget(
            self.groupbox_interpolate_plot, 6
        )

        self._setup_widgets_concentration_interpolate()
        self._setup_widgets_concentration_interpolate_plot()

    def _setup_widgets_concentration_interpolate(self):
        self.gridLayout_groupbox_interpolate_info = QGridLayout(
            self.groupbox_interpolate_info
        )

        self.pushbutton_interpolate_Mfine_profile = QPushButton()
        self.pushbutton_interpolate_Mfine_profile.setText("Interpolate")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.pushbutton_interpolate_Mfine_profile, 0, 0, 1, 4,
            Qt.AlignCenter
        )

        self.label_sample_fine = QLabel()
        self.label_sample_fine.setText("Sample")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.label_sample_fine, 1, 0, 1, 1, Qt.AlignCenter
        )

        self.label_depth_fine = QLabel()
        self.label_depth_fine.setText("Depth (m)")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.label_depth_fine, 1, 1, 1, 1, Qt.AlignCenter
        )

        self.label_time_fine = QLabel()
        self.label_time_fine.setText("time")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.label_time_fine, 1, 2, 1, 1, Qt.AlignCenter
        )

        self.label_concentration_fine = QLabel()
        self.label_concentration_fine.setText("Cfine (g/L)")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.label_concentration_fine, 1, 3, 1, 1, Qt.AlignCenter
        )

        self.double_horizontal_line = QFrame()
        self.double_horizontal_line.setFrameShape(QFrame.HLine)
        self.double_horizontal_line.setFrameShadow(QFrame.Sunken)
        self.double_horizontal_line.setLineWidth(1)
        self.double_horizontal_line.setMidLineWidth(3)
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.double_horizontal_line, 4, 0, 1, 4, Qt.AlignCenter
        )

        self.label_sample_sand = QLabel()
        self.label_sample_sand.setText("Sample")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.label_sample_sand, 5, 0, 1, 1, Qt.AlignCenter
        )

        self.label_depth_sand = QLabel()
        self.label_depth_sand.setText("Depth (m)")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.label_depth_sand, 5, 1, 1, 1, Qt.AlignCenter
        )

        self.label_time_sand = QLabel()
        self.label_time_sand.setText("time")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.label_time_sand, 5, 2, 1, 1, Qt.AlignCenter
        )

        self.label_concentration_sand = QLabel()
        self.label_concentration_sand.setText("Csand (g/L)")
        self.gridLayout_groupbox_interpolate_info.addWidget(
            self.label_concentration_sand, 5, 3, 1, 1, Qt.AlignCenter
        )

    def _setup_widgets_concentration_interpolate_plot(self):
        self.verticalLayout_groupbox_interpolate_plot = QVBoxLayout(
            self.groupbox_interpolate_plot
        )

        self.canvas_Mfine = FigureCanvas()
        self.toolbar_Mfine = NavigationToolBar(self.canvas_Mfine, self)

        self.verticalLayout_groupbox_interpolate_plot\
            .addWidget(self.toolbar_Mfine)
        self.verticalLayout_groupbox_interpolate_plot\
            .addWidget(self.canvas_Mfine)


    def _setup_widgets_calibration(self):
        self.groupbox_sediment_calibration = QGroupBox()
        self.horizontalLayoutBottom.addWidget(self.groupbox_sediment_calibration, 4)

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

        self.groupbox_sediment_calibration.setTitle("Step 3 : Compute Calibration")
        self.verticalLayout_groupbox_sediment_calibration = QVBoxLayout(self.groupbox_sediment_calibration)

        self.horizontalLayout_groupboxes_Import_Compute_Calibration = QHBoxLayout()
        self.verticalLayout_groupbox_sediment_calibration.addLayout(self.horizontalLayout_groupboxes_Import_Compute_Calibration)

        self._setup_widgets_calibration_import_file()
        self._setup_widgets_calibration_compute()
        self._setup_widgets_calibration_parameters()

    def _setup_widgets_calibration_import_file(self):
        self.groupbox_sediment_calibration_import = QGroupBox()
        self.groupbox_sediment_calibration_import.setTitle(
            "Import sediment calibration file"
        )
        self.groupbox_sediment_calibration_import.setCheckable(True)
        self.groupbox_sediment_calibration_import.setChecked(True)
        self.horizontalLayout_groupboxes_Import_Compute_Calibration.addWidget(
            self.groupbox_sediment_calibration_import
        )

        self.gridLayout_groupbox_sediment_calibration_import = QGridLayout(
            self.groupbox_sediment_calibration_import
        )

        self.pushbutton_import_calibration = QPushButton()
        self.pushbutton_import_calibration.setText('Import calibration')
        self.gridLayout_groupbox_sediment_calibration_import.addWidget(
            self.pushbutton_import_calibration, 0, 0, 1, 1
        )

        self.lineEdit_import_calibration = QLineEdit()
        self.gridLayout_groupbox_sediment_calibration_import.addWidget(
            self.lineEdit_import_calibration, 0, 1, 1, 2
        )

    def _setup_widgets_calibration_compute(self):
        self.groupbox_sediment_calibration_compute = QGroupBox()
        self.groupbox_sediment_calibration_compute.setTitle(
            "Compute sediment calibration"
        )
        self.groupbox_sediment_calibration_compute.setCheckable(True)
        self.groupbox_sediment_calibration_compute.setChecked(False)
        self.horizontalLayout_groupboxes_Import_Compute_Calibration\
            .addWidget(self.groupbox_sediment_calibration_compute)

        self.gridLayout_groupbox_sediment_calibration_compute = QGridLayout(
            self.groupbox_sediment_calibration_compute
        )

        self.pushbutton_compute_calibration = QPushButton()
        self.pushbutton_compute_calibration.setText(
            "Compute Calibration"
        )
        self.pushbutton_compute_calibration.setToolTip(
            "Calibration is computed at abscissa 'sand target'"
        )
        self.gridLayout_groupbox_sediment_calibration_compute\
            .addWidget(self.pushbutton_compute_calibration, 0, 0, 1, 3)


    def _setup_widgets_calibration_parameters(self):
        self.groupbox_sediment_calibration_parameter = QGroupBox()
        self.gridLayout_groupbox_sediment_calibration_parameter = \
            QGridLayout(self.groupbox_sediment_calibration_parameter)

        self.verticalLayout_groupbox_sediment_calibration\
            .addWidget(self.groupbox_sediment_calibration_parameter)

        self.label_temperature = QLabel()
        self.label_temperature.setText("T = 0.00 °C")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_temperature, 0, 0, 1, 1)

        self.label_freq1 = QLabel("Frequency 1")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_freq1, 1, 1, 1, 2, Qt.AlignCenter)

        self.label_freq2 = QLabel("Frequency 2")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_freq2, 1, 3, 1, 2, Qt.AlignCenter)

        self.label_kt = QLabel()
        self.label_kt.setText("kt")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_kt, 2, 0, 1, 1, Qt.AlignCenter)

        self.label_kt_freq1 = QLabel()
        self.label_kt_freq1.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_kt_freq1, 2, 1, 1, 1, Qt.AlignRight)

        self.label_kt_freq1_unit = QLabel()
        self.label_kt_freq1_unit.setText("V.m<sup>1.5</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_kt_freq1_unit, 2, 2, 1, 1, Qt.AlignLeft)

        self.label_kt_freq2 = QLabel()
        self.label_kt_freq2.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_kt_freq2, 2, 3, 1, 1, Qt.AlignRight)

        self.label_kt_freq2_unit = QLabel()
        self.label_kt_freq2_unit.setText("V.m<sup>1.5</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_kt_freq2_unit, 2, 4, 1, 1, Qt.AlignLeft)

        self.horizontalLine = QFrame()
        self.horizontalLine.setFrameShape(QFrame.HLine)
        self.horizontalLine.setFrameShadow(QFrame.Sunken)
        self.horizontalLine.setLineWidth(1)
        self.horizontalLine.setMidLineWidth(0)
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.horizontalLine, 3, 0, 1, 6)

        self.label_ks = QLabel()
        self.label_ks.setText("ks")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_ks, 4, 0, 1, 1, Qt.AlignCenter)

        self.lineEdit_ks_freq1 = QLineEdit()
        self.lineEdit_ks_freq1.setMaximumWidth(100)
        self.lineEdit_ks_freq1.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_ks_freq1, 4, 1, 1, 1)

        self.label_ks_freq1_unit = QLabel()
        self.label_ks_freq1_unit.setText("m.kg<sup>-0.5</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_ks_freq1_unit, 4, 2, 1, 1, Qt.AlignLeft)

        self.lineEdit_ks_freq2 = QLineEdit()
        self.lineEdit_ks_freq2.setMaximumWidth(100)
        self.lineEdit_ks_freq2.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_ks_freq2, 4, 3, 1, 1)

        self.label_ks_freq2_unit = QLabel()
        self.label_ks_freq2_unit.setText("m.kg<sup>-0.5</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_ks_freq2_unit, 4, 4, 1, 1, Qt.AlignLeft)

        self.label_sv = QLabel()
        self.label_sv.setText("sv")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_sv, 5, 0, 1, 1, Qt.AlignCenter)

        self.lineEdit_sv_freq1 = QLineEdit()
        self.lineEdit_sv_freq1.setMaximumWidth(100)
        self.lineEdit_sv_freq1.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_sv_freq1, 5, 1, 1, 1)

        self.label_sv_freq1_unit = QLabel()
        self.label_sv_freq1_unit.setText("m<sup>-1</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_sv_freq1_unit, 5, 2, 1, 1)

        self.lineEdit_sv_freq2 = QLineEdit()
        self.lineEdit_sv_freq2.setMaximumWidth(100)
        self.lineEdit_sv_freq2.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_sv_freq2, 5, 3, 1, 1)

        self.label_sv_freq2_unit = QLabel()
        self.label_sv_freq2_unit.setText("m<sup>-1</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_sv_freq2_unit, 5, 4, 1, 1)

        self.label_X = QLabel()
        self.label_X.setText("X")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_X, 6, 0, 1, 1, Qt.AlignCenter)

        self.lineEdit_X = QLineEdit()
        self.lineEdit_X.setMaximumWidth(100)
        self.lineEdit_X.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_X, 6, 2, 1, 1, Qt.AlignCenter)

        self.label_alphas = QLabel()
        self.label_alphas.setText("\u03B1s")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_alphas, 7, 0, 1, 1, Qt.AlignCenter)

        self.lineEdit_alphas_freq1 = QLineEdit()
        self.lineEdit_alphas_freq1.setMaximumWidth(100)
        self.lineEdit_alphas_freq1.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_alphas_freq1, 7, 1, 1, 1)

        self.label_alphas_freq1_unit = QLabel()
        self.label_alphas_freq1_unit.setText("m<sup>-1</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_alphas_freq1_unit, 7, 2, 1, 1, Qt.AlignLeft)

        self.lineEdit_alphas_freq2 = QLineEdit()
        self.lineEdit_alphas_freq2.setMaximumWidth(100)
        self.lineEdit_alphas_freq2.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_alphas_freq2, 7, 3, 1, 1)

        self.label_alphas_freq2_unit = QLabel()
        self.label_alphas_freq2_unit.setText("m<sup>-1</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_alphas_freq2_unit, 7, 4, 1, 1, Qt.AlignLeft)

        self.label_zeta = QLabel()
        self.label_zeta.setText("\u03B6")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_zeta, 8, 0, 1, 1, Qt.AlignCenter)

        self.lineEdit_zeta_freq1 = QLineEdit()
        self.lineEdit_zeta_freq1.setMaximumWidth(100)
        self.lineEdit_zeta_freq1.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_zeta_freq1, 8, 1, 1, 1)

        self.label_zeta_freq1_unit = QLabel()
        self.label_zeta_freq1_unit.setText("m<sup>-1</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_zeta_freq1_unit, 8, 2, 1, 1, Qt.AlignLeft)

        self.lineEdit_zeta_freq2 = QLineEdit()
        self.lineEdit_zeta_freq2.setMaximumWidth(100)
        self.lineEdit_zeta_freq2.setText("0.00")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.lineEdit_zeta_freq2, 8, 3, 1, 1)

        self.label_zeta_freq2_unit = QLabel()
        self.label_zeta_freq2_unit.setText("m<sup>-1</sup>")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.label_zeta_freq2_unit, 8, 4, 1, 1, Qt.AlignLeft)

        self.pushbutton_save_calibration = QPushButton()
        self.pushbutton_save_calibration.setText("Save calibration")
        self.gridLayout_groupbox_sediment_calibration_parameter\
            .addWidget(self.pushbutton_save_calibration,9, 5, 1, 1)


    def _setup_widgets_fcb(self):
        self.groupbox_FCB.setTitle(
            "Step 3 (for information) : Fluid Corrected Backscatter"
        )
        self.horizontalLayout_groupbox_FCB = QHBoxLayout(self.groupbox_FCB)

        self.groupbox_FCB.setCheckable(True)
        self.groupbox_FCB.setChecked(False)

        self._setup_widgets_fcb_options()
        self._setup_widgets_fcb_plot()

    def _setup_widgets_fcb_options(self):
        self.groupbox_FCB_option = QGroupBox()
        self.verticalLayout_groupbox_FCB_option = QVBoxLayout(self.groupbox_FCB_option)
        self.horizontalLayout_groupbox_FCB\
            .addWidget(self.groupbox_FCB_option, 4)

        self.groupbox_FCB_text = QGroupBox()
        self.verticalLayout_groupbox_FCB_text = QVBoxLayout(self.groupbox_FCB_text)
        self.verticalLayout_groupbox_FCB_option\
            .addWidget(self.groupbox_FCB_text)

        self.label_FCB_explanation = QLabel()
        self.label_FCB_explanation.setText(
            "When fine sediments concentration is constant \n "
            "and effect on sound attenuation on sand is negligible, \n "
            "this sediment attenuation alphas can be compared \n "
            "to the obtained by the sediment calibration computation."
        )
        self.verticalLayout_groupbox_FCB_text\
            .addWidget(self.label_FCB_explanation)

        self.gridLayout_groupbox_FCB_text_alphas = QGridLayout()
        self.verticalLayout_groupbox_FCB_text\
            .addLayout(self.gridLayout_groupbox_FCB_text_alphas)

        self.label_FCB_explanation_alphas_positive_icon = QLabel()
        self.label_FCB_explanation_alphas_positive_icon.setPixmap(
            QPixmap(self._path_icon("approved.png")).scaledToHeight(
                16, Qt.SmoothTransformation
            )
        )
        self.gridLayout_groupbox_FCB_text_alphas.addWidget(
            self.label_FCB_explanation_alphas_positive_icon,
            0, 0, 1, 1, Qt.AlignCenter
        )

        self.label_FCB_explanation_alphas_positive = QLabel()
        self.label_FCB_explanation_alphas_positive.setText(
            "&alpha;<sub>s FCB</sub> &gt; 0 : comparison with calibration"
        )
        self.label_FCB_explanation_alphas_positive.setFont(QFont('Ubuntu', 12))
        self.gridLayout_groupbox_FCB_text_alphas.addWidget(
            self.label_FCB_explanation_alphas_positive,
            0, 1, 1, 1, Qt.AlignLeft
        )

        self.label_FCB_explanation_alphas_negative_icon = QLabel()
        self.label_FCB_explanation_alphas_negative_icon.setPixmap(
            QPixmap(self._path_icon("no_approved.png")).scaledToHeight(
                16, Qt.SmoothTransformation
            )
        )
        self.gridLayout_groupbox_FCB_text_alphas.addWidget(
            self.label_FCB_explanation_alphas_negative_icon,
            1, 0, 1, 1, Qt.AlignCenter
        )

        self.label_FCB_explanation_alphas_negative = QLabel()
        self.label_FCB_explanation_alphas_negative.setText(
            "&alpha;<sub>s FCB</sub> &lt; 0 : do not compare with calibration"
        )
        self.label_FCB_explanation_alphas_negative.setFont(QFont('Ubuntu', 12))
        self.gridLayout_groupbox_FCB_text_alphas.addWidget(
            self.label_FCB_explanation_alphas_negative,
            1, 1, 1, 1, Qt.AlignLeft
        )

        self.groupbox_FCB_compute = QGroupBox()
        self.gridLayout_groupbox_FCB_compute = QGridLayout(self.groupbox_FCB_compute)
        self.verticalLayout_groupbox_FCB_option.addWidget(self.groupbox_FCB_compute)

        self.label_frequency_FCB = QLabel()
        self.label_frequency_FCB.setText("Frequency ")
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.label_frequency_FCB, 0, 0, 1, 3, Qt.AlignCenter
        )

        self.combobox_frequency_FCB = QComboBox()
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.combobox_frequency_FCB, 0, 3, 1, 3, Qt.AlignCenter
        )

        self.label_from = QLabel()
        self.label_from.setText("From ")
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.label_from, 1, 0, 1, 1, Qt.AlignCenter
        )

        self.lineEdit_FCB_from = QLineEdit()
        self.lineEdit_FCB_from.setMaximumWidth(100)
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.lineEdit_FCB_from, 1, 1, 1, 1, Qt.AlignCenter
        )

        self.label_FCB_from_unit = QLabel()
        self.label_FCB_from_unit.setText("m")
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.label_FCB_from_unit, 1, 2, 1, 1, Qt.AlignLeft
        )

        self.label_to = QLabel()
        self.label_to.setText("to ")
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.label_to, 1, 3, 1, 1, Qt.AlignCenter
        )

        self.lineEdit_FCB_to = QLineEdit()
        self.lineEdit_FCB_to.setMaximumWidth(100)
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.lineEdit_FCB_to, 1, 4, 1, 1, Qt.AlignCenter
        )

        self.label_FCB_to_unit = QLabel()
        self.label_FCB_to_unit.setText("m")
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.label_FCB_to_unit, 1, 5, 1, 1, Qt.AlignLeft
        )

        self.pushbutton_FCB_fit = QPushButton()
        self.pushbutton_FCB_fit.setText("Compute and Plot Linear regression")
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.pushbutton_FCB_fit, 2, 0, 1, 3, Qt.AlignCenter
        )

        self.label_alphaS_FCB = QLabel()
        self.label_alphaS_FCB.setText(
            "&alpha;<sub>s</sub> = " + "0.0" + "dB/m"
        )
        self.label_alphaS_FCB.setFont(QFont("Ubuntu", 14, QFont.Normal))
        self.gridLayout_groupbox_FCB_compute.addWidget(
            self.label_alphaS_FCB, 2, 4, 1, 2
        )


    def _setup_widgets_fcb_plot(self):
        self.verticalLayout_groupbox_FCB_plot_and_slider_FCB = QVBoxLayout()
        self.horizontalLayout_groupbox_FCB.addLayout(
            self.verticalLayout_groupbox_FCB_plot_and_slider_FCB, 8
        )

        self.groupbox_FCB_plot = QGroupBox()
        self.verticalLayout_groupbox_FCB_plot = QVBoxLayout(self.groupbox_FCB_plot)
        self.verticalLayout_groupbox_FCB_plot_and_slider_FCB\
            .addWidget(self.groupbox_FCB_plot)

        self.canvas_FCB = FigureCanvas()
        self.toolbar_FCB = NavigationToolBar(self.canvas_FCB, self)

        self.verticalLayout_groupbox_FCB_plot.addWidget(self.toolbar_FCB)
        self.verticalLayout_groupbox_FCB_plot.addWidget(self.canvas_FCB)

        self.horizontalLayout_slider_FCB = QHBoxLayout()
        self.verticalLayout_groupbox_FCB_plot_and_slider_FCB\
            .addLayout(self.horizontalLayout_slider_FCB)

        self.pushbutton_left_to_begin_FCB = QPushButton()
        self.pushbutton_left_to_begin_FCB.setIcon(
            self.icon_triangle_left_to_begin
        )
        self.horizontalLayout_slider_FCB.addWidget(
            self.pushbutton_left_to_begin_FCB
        )

        self.pushbutton_left_FCB = QPushButton()
        self.pushbutton_left_FCB.setIcon(self.icon_triangle_left)
        self.horizontalLayout_slider_FCB.addWidget(self.pushbutton_left_FCB)

        self.lineEdit_slider_FCB = QLineEdit()
        self.lineEdit_slider_FCB.setText("1")
        self.lineEdit_slider_FCB.setFixedWidth(50)
        self.horizontalLayout_slider_FCB.addWidget(self.lineEdit_slider_FCB)

        self.pushbutton_right_FCB = QPushButton()
        self.pushbutton_right_FCB.setIcon(self.icon_triangle_right)
        self.horizontalLayout_slider_FCB.addWidget(self.pushbutton_right_FCB)

        self.pushbutton_right_to_end_FCB = QPushButton()
        self.pushbutton_right_to_end_FCB.setIcon(
            self.icon_triangle_right_to_end
        )
        self.horizontalLayout_slider_FCB.addWidget(
            self.pushbutton_right_to_end_FCB
        )

        self.slider_FCB = QSlider()
        self.horizontalLayout_slider_FCB.addWidget(self.slider_FCB)

        self.slider_FCB.setOrientation(Qt.Horizontal)
        self.slider_FCB.setCursor(Qt.OpenHandCursor)
        self.slider_FCB.setMinimum(1)
        self.slider_FCB.setMaximum(10)
        self.slider_FCB.setTickInterval(1)
        self.slider_FCB.setValue(1)


    def _setup_connections(self):
        self.pushbutton_update_acoustic_file\
            .clicked.connect(
                self.function_pushbutton_update_acoustic_file
            )

        self.pushbutton_plot_sample\
            .clicked.connect(
                self.function_pushbutton_plot_sample
            )

        self.pushbutton_interpolate_Mfine_profile\
            .clicked.connect(self.interpolate_Mfine_profile)

        self.groupbox_sediment_calibration_import\
            .toggled.connect(self.groupbox_calibration_import_toggle)
        self.groupbox_sediment_calibration_import\
            .toggled.connect(self.groupbox_calibration_import_size_change)

        self.pushbutton_import_calibration\
            .clicked.connect(self.import_calibration_file)

        self.groupbox_sediment_calibration_compute\
            .toggled.connect(self.groupbox_calibration_compute_toggle)
        self.groupbox_sediment_calibration_compute\
            .toggled.connect(self.groupbox_calibration_compute_size_change)

        self.pushbutton_compute_calibration\
            .clicked.connect(self.function_pushbutton_compute_calibration)

        self.pushbutton_save_calibration\
            .clicked.connect(self.save_calibration)

        self.pushbutton_left_to_begin_FCB\
            .clicked.connect(self.slider_profile_number_to_begin_FCB)
        self.pushbutton_left_FCB\
            .clicked.connect(self.slider_profile_number_to_left_FCB)
        self.pushbutton_right_FCB\
            .clicked.connect(self.slider_profile_number_to_right_FCB)
        self.pushbutton_right_to_end_FCB\
            .clicked.connect(self.slider_profile_number_to_end_FCB)

        self.lineEdit_slider_FCB\
            .returnPressed.connect(self.profile_number_on_lineEdit_FCB)
        self.slider_FCB\
            .valueChanged.connect(self.update_lineEdit_by_moving_slider_FCB)

        self.pushbutton_FCB_fit\
            .clicked.connect(
                self.fit_FCB_profile_with_linear_regression_and_compute_alphaS
            )

    # ==============================================================================================================
    # ----------------------------------- Functions for Signal processing Tab --------------------------------------
    # ==============================================================================================================

    def function_pushbutton_update_acoustic_file(self):
        if len(stg.data_preprocessed) == 0:
            return

        if (len(stg.sample_fine) == 0 or len(stg.sample_sand) == 0):
            return

        self.update_acoustic_data()
        # self.compute_depth_2D()

    def update_acoustic_data(self):
        self.combobox_acoustic_data_choice.clear()
        self.combobox_acoustic_data_choice.addItems(stg.data_preprocessed)
        self.combobox_acoustic_data_choice\
            .currentIndexChanged.connect(self.plot_acoustic_recording)

        self.combobox_freq1.clear()
        self.combobox_freq1.addItems(
            stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()]
        )
        self.combobox_freq1.currentIndexChanged\
                           .connect(self.update_label_freq1_for_calibration)
        self.combobox_freq1.currentIndexChanged\
                           .connect(self.update_label_kt_value_for_calibration)

        self.combobox_freq2.clear()
        self.combobox_freq2.addItems(
            stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()]
        )
        self.combobox_freq2.currentIndexChanged\
                           .connect(self.update_label_freq2_for_calibration)
        self.combobox_freq2.currentIndexChanged\
                           .connect(self.update_label_kt_value_for_calibration)
        self.combobox_freq2.currentIndexChanged\
                           .connect(self.plot_acoustic_recording)

        self.combobox_fine_sample_choice.clear()
        self.combobox_fine_sample_choice.addItems(
            [f[0] for f in stg.sample_fine]
        )

        self.combobox_sand_sample_choice.clear()
        self.combobox_sand_sample_choice.addItems(
            [s[0] for s in stg.sample_sand]
        )

        self.plot_acoustic_recording()

        self.label_temperature.clear()
        self.label_temperature.setText("T = " + str(stg.temperature) + " °C")

        self.update_label_freq1_for_calibration()
        self.update_label_freq2_for_calibration()
        self.update_label_kt_value_for_calibration()

    def function_pushbutton_plot_sample(self):
        if (self.combobox_acoustic_data_choice.currentIndex() == -1):
            return

        self.sample_choice_for_calibration()
        self.plot_acoustic_recording()
        self.summary_samples_choices()
        self.plot_profile_of_concentration_fine()
        self.compute_FCB()

    def plot_acoustic_recording(self):
        # --- Record frequencies for calibration ---
        stg.frequencies_for_calibration.clear()
        stg.frequencies_for_calibration.append(
            (
                stg.freq[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq1.currentIndex()
                ],
                self.combobox_freq1.currentIndex()
            )
        )
        stg.frequencies_for_calibration.append(
            (
                stg.freq[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex()
                ],
                self.combobox_freq2.currentIndex()
            )
        )

        stg.frequency_for_inversion = tuple()
        stg.frequency_for_inversion = (
            stg.freq[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex()
            ],
            self.combobox_freq2.currentIndex()
        )

        # --- Plot acoustic data recording ---
        self.verticalLayout_groupbox_data_plot.removeWidget(self.toolbar_BS)
        self.verticalLayout_groupbox_data_plot.removeWidget(self.canvas_BS)
        self.fig_BS, self.axis_BS = plt.subplots(
            nrows=1, ncols=1, sharex=True, sharey=False, layout='constrained'
        )
        self.canvas_BS = FigureCanvas(self.fig_BS)
        self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)
        self.verticalLayout_groupbox_data_plot.addWidget(self.toolbar_BS)
        self.verticalLayout_groupbox_data_plot.addWidget(self.canvas_BS)

        if stg.BS_stream_bed_pre_process_average[
                self.combobox_acoustic_data_choice.currentIndex()
        ].shape != (0,):
            val_min = np.nanmin(
                stg.BS_stream_bed_pre_process_average[
                    self.combobox_acoustic_data_choice.currentIndex()
                ][
                    self.combobox_freq2.currentIndex(), :, :
                ]
            )
            val_max = np.nanmax(
                stg.BS_stream_bed_pre_process_average[
                    self.combobox_acoustic_data_choice.currentIndex()
                ][
                    self.combobox_freq2.currentIndex(), :, :
                ]
            )
            if val_min == 0:
                val_min = 1e-5

            if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_stream_bed_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_stream_bed_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
            else:
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_stream_bed_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_stream_bed_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))



        elif stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            val_min = np.nanmin(
                stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :])
            val_max = np.nanmax(
                stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :])
            if val_min == 0:
                val_min = 1e-5

            if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
            else:
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

        elif stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            val_min = np.nanmin(
                stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(),
                :, :])
            val_max = np.nanmax(
                stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(),
                :, :])
            if val_min == 0:
                val_min = 1e-5

            if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex(), :],
                    -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_freq2.currentIndex(), :],
                    stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(),
                    :, :],
                    cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex(), :],
                    -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_freq2.currentIndex(), :],
                    stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(),
                    :, :],
                    cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

            else:
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex(), :],
                    -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_freq2.currentIndex(), :],
                    stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(),
                    :, :],
                    cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex(), :],
                    -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_freq2.currentIndex(), :],
                    stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(),
                    :, :],
                    cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

        elif stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            val_min = np.nanmin(
                stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :])
            val_max = np.nanmax(
                stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :])
            if val_min == 0:
                val_min = 1e-5

            if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
            else:
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

        elif stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            val_min = np.nanmin(
                stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :])
            val_max = np.nanmax(
                stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :])
            if val_min == 0:
                val_min = 1e-5

            if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0):
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
            else:
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0):
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

        elif stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            val_min = np.nanmin(
                stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :])
            val_max = np.nanmax(
                stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :])
            if val_min == 0:
                val_min = 1e-5

            if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
            else:
                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))
                else:
                    self.axis_BS.pcolormesh(
                        stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :],
                        -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                         self.combobox_freq2.currentIndex(), :],
                        stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_freq2.currentIndex(), :, :],
                        cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))


        elif stg.BS_raw_data_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            val_min = np.nanmin(stg.BS_raw_data_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :, :])
            val_max = np.nanmax(stg.BS_raw_data_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :, :])
            if val_min == 0:
                val_min = 1e-5

            self.axis_BS.pcolormesh(
                stg.time[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :],
                -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :],
                stg.BS_raw_data_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :],
                cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))



        elif stg.BS_raw_data_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            val_min = np.nanmin(stg.BS_raw_data_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :, :])
            val_max = np.nanmax(stg.BS_raw_data_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :, :])
            if val_min == 0:
                val_min = 1e-5

            self.axis_BS.pcolormesh(
                stg.time[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :],
                -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :],
                stg.BS_raw_data_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex(), :, :],
                cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

        elif stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            val_min = np.nanmin(stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :, :])
            val_max = np.nanmax(stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :, :])
            if val_min == 0:
                val_min = 1e-5

            self.axis_BS.pcolormesh(
                stg.time[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :],
                -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex(), :],
                stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex(), :, :],
                cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max))

        # --- Plot samples ---

        if (stg.fine_sample_profile) or (stg.sand_sample_target):

            self.axis_BS.scatter([stg.time_fine[f[1]] for f in stg.fine_sample_profile],
                                 [stg.depth_fine[f[1]] for f in stg.fine_sample_profile],
                                 marker='o', s=20, facecolor="k", edgecolor="None")
            self.axis_BS.scatter([stg.time_sand[s[1]] for s in stg.sand_sample_target],
                                 [stg.depth_sand[s[1]] for s in stg.sand_sample_target],
                                 marker='o', s=50, facecolor="None", edgecolor="k")

            for i in stg.fine_sample_profile:
                self.axis_BS.text(stg.time_fine[i[1]] + 5, stg.depth_fine[i[1]] - .2, i[0],
                                  fontstyle="normal", fontweight="light", fontsize=8)

            for j in stg.sand_sample_target:
                self.axis_BS.text(stg.time_sand[j[1]] - 12, stg.depth_sand[j[1]] - .2, j[0],
                                  fontstyle="normal", fontweight="light", fontsize=8)

        elif (stg.sample_fine) or (stg.sample_sand):

            self.axis_BS.scatter(stg.time_fine, stg.depth_fine, marker='o', s=20, facecolor="k", edgecolor="None")
            self.axis_BS.scatter(stg.time_sand, stg.depth_sand, marker='o', s=50, facecolor="None", edgecolor="k")

            for i in stg.sample_fine:
                self.axis_BS.text(stg.time_fine[i[1]] + 5, stg.depth_fine[i[1]] - .2, i[0],
                                  fontstyle="normal", fontweight="light", fontsize=8)

            for j in stg.sample_sand:
                self.axis_BS.text(stg.time_sand[j[1]] - 12, stg.depth_sand[j[1]] - .2, j[0],
                                  fontstyle="normal", fontweight="light", fontsize=8)

        # --- Plot vertical red line for position of FCB profile ---
        if stg.sand_sample_target_indice:

            if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                    self.red_line_plot_return, = (
                        self.axis_BS.plot(
                            stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[0][1]] *
                            np.ones(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
                            -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :],
                            color='red', linestyle="solid", linewidth=2))

                else:

                    self.red_line_plot_return, = (
                        self.axis_BS.plot(
                            stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[0][1]] *
                            np.ones(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
                            -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                             self.combobox_freq2.currentIndex(), :],
                            color='red', linestyle="solid", linewidth=2))

            else:

                if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                    self.red_line_plot_return, = (
                        self.axis_BS.plot(
                            stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[0][1]] *
                            np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
                            -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                             self.combobox_freq2.currentIndex(), :],
                            color='red', linestyle="solid", linewidth=2))

                else:

                    self.red_line_plot_return, = (
                        self.axis_BS.plot(
                            stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[0][1]] *
                            np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
                            -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                             self.combobox_freq2.currentIndex(), :],
                            color='red', linestyle="solid", linewidth=2))

        self.axis_BS.set_xlabel("Time (sec)")
        self.axis_BS.set_ylabel("Depth (m)")
        self.fig_BS.canvas.draw_idle()

    def sample_choice_for_calibration(self):
        # --- List selected fine samples ---
        stg.fine_sample_profile = [(f, int(f[1:]) - 1) for f in self.combobox_fine_sample_choice.currentData()]

        # --- List selected sand samples ---
        # stg.sand_sample_target = [(s, int(s[1:]) - 1) for s in self.combobox_sand_sample_choice.currentData()]
        stg.sand_sample_target = [(self.combobox_sand_sample_choice.currentText(),
                                   self.combobox_sand_sample_choice.currentIndex())]

        # --- Find index in time (along acoustic recording) of sand sample target ---
        if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
            t1 = (
                np.where(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                           self.combobox_freq1.currentIndex()] - stg.time_sand[stg.sand_sample_target[0][1]]) ==
                np.nanmin(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                           self.combobox_freq1.currentIndex()] - stg.time_sand[stg.sand_sample_target[0][1]])))[0][0]
            )
            t2 = (
                np.where(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                           self.combobox_freq2.currentIndex()] - stg.time_sand[stg.sand_sample_target[0][1]]) ==
                np.nanmin(np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                           self.combobox_freq2.currentIndex()] - stg.time_sand[stg.sand_sample_target[0][1]])))[0][0]
            )
        else:
            t1 = (
                np.where(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                    self.combobox_freq1.currentIndex()] - stg.time_sand[
                                    stg.sand_sample_target[0][1]]) ==
                         np.nanmin(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                              self.combobox_freq1.currentIndex()] - stg.time_sand[
                                              stg.sand_sample_target[0][1]])))[0][0]
            )
            t2 = (
                np.where(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                    self.combobox_freq2.currentIndex()] - stg.time_sand[
                                    stg.sand_sample_target[0][1]]) ==
                         np.nanmin(np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                              self.combobox_freq2.currentIndex()] - stg.time_sand[
                                              stg.sand_sample_target[0][1]])))[0][0]
            )

        # --- Find index in depth (along acoustic recording) of sand sample target ---
        if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
            d1 = (
                np.where(np.abs(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                           self.combobox_freq1.currentIndex()] - (-stg.depth_sand[stg.sand_sample_target[0][1]]) ) ==
                np.nanmin(np.abs(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                           self.combobox_freq1.currentIndex()] - (-stg.depth_sand[stg.sand_sample_target[0][1]]) )))[0][0]
            )
            d2 = (
                np.where(np.abs(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                           self.combobox_freq2.currentIndex()] - (-stg.depth_sand[stg.sand_sample_target[0][1]]) ) ==
                np.nanmin(np.abs(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                           self.combobox_freq2.currentIndex()] - (-stg.depth_sand[stg.sand_sample_target[0][1]]) )))[0][0]
            )
        else:
            d1 = (
                np.where(np.abs(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                                    self.combobox_freq1.currentIndex()] - (-stg.depth_sand[
                                    stg.sand_sample_target[0][1]]) ) ==
                         np.nanmin(np.abs(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                                              self.combobox_freq1.currentIndex()] - (-stg.depth_sand[
                                              stg.sand_sample_target[0][1]]) )))[0][0]
            )
            d2 = (
                np.where(np.abs(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                                    self.combobox_freq2.currentIndex()] - (-stg.depth_sand[
                                    stg.sand_sample_target[0][1]]) ) ==
                         np.nanmin(np.abs(stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                                              self.combobox_freq2.currentIndex()] - (-stg.depth_sand[
                                              stg.sand_sample_target[0][1]]) )))[0][0]
            )

        stg.sand_sample_target_indice = [(d1, t1), (d2, t2)]

    def summary_samples_choices(self):

        self.pushbutton_compute_calibration.setToolTip("Calibration is computed at abscissa " + str(self.combobox_sand_sample_choice.currentText()))

        for i in reversed(range(self.gridLayout_groupbox_interpolate_info.count())):
            self.gridLayout_groupbox_interpolate_info.itemAt(i).widget().setParent(None)

        self.gridLayout_groupbox_interpolate_info.addWidget(self.pushbutton_interpolate_Mfine_profile, 0, 0, 1, 4, Qt.AlignCenter)

        fine_head = ["Sample", "Depth (m)", "time", "Cfine (g/L)"]
        fine_label = [self.label_sample_fine, self.label_depth_fine, self.label_time_fine,
                      self.label_concentration_fine]

        for j in range(len(fine_head)):
            exec("fine_label[" + str(j) + "] = QLabel()")
            eval("fine_label[" + str(j) + "].setText(fine_head[" + str(j) + "])")
            print((f"self.gridLayout_groupbox_interpolate_info.addWidget(fine_label[{j}], 1, {j}, 1, 1, Qt.AlignCenter)"))
            eval(f"self.gridLayout_groupbox_interpolate_info.addWidget(fine_label[{j}], 1, {j}, 1, 1, Qt.AlignCenter)")

        fine_data = []
        for k in range(len(stg.fine_sample_profile)):
            fine_data.append([stg.fine_sample_profile[k][0], str(stg.depth_fine[k]), str(stg.time_fine[k]), str(stg.Ctot_fine[k])])
        print(fine_data)

        for p in range(len(fine_data)):
            for q in range(len(fine_data[0])):
                print(f"self.gridLayout_groupbox_interpolate_info.addWidget(QLabel(fine_data[{p}][{q}]), {2 + p}, {q}, 1, 1, Qt.AlignCenter)")
                eval(f"self.gridLayout_groupbox_interpolate_info.addWidget(QLabel(fine_data[{p}][{q}]), {2 + p}, {q}, 1, 1, Qt.AlignCenter)")

        self.gridLayout_groupbox_interpolate_info.addWidget(self.double_horizontal_line, 2 + len(fine_data), 0, 1, 4, Qt.AlignCenter)

        sand_head = ["Sample", "Depth (m)", "time", "Csand (g/L)"]
        sand_label = [self.label_sample_sand, self.label_depth_sand, self.label_time_sand,
                      self.label_concentration_sand]

        for s in range(len(sand_head)):
            exec("sand_label[" + str(s) + "] = QLabel()")
            eval("sand_label[" + str(s) + "].setText(sand_head[" + str(s) + "])")
            print(f"self.gridLayout_groupbox_interpolate_info.addWidget(sand_label[{s}], {3 + len(fine_data)}, {s}, 1, 1, Qt.AlignCenter)")
            eval(f"self.gridLayout_groupbox_interpolate_info.addWidget(sand_label[{s}], {3 + len(fine_data)}, {s}, 1, 1, Qt.AlignCenter)")

        sand_data = [stg.sand_sample_target[0][0],
                     str(stg.depth_sand[stg.sand_sample_target[0][1]]),
                     str(stg.time_sand[stg.sand_sample_target[0][1]]),
                     str(stg.Ctot_sand[stg.sand_sample_target[0][1]])]

        for t in range(len(sand_data)):
            self.gridLayout_groupbox_interpolate_info.addWidget(QLabel(sand_data[t]), 4 + len(fine_data), t, 1, 1, Qt.AlignCenter)


    def plot_profile_of_concentration_fine(self):

        # --- Plot profile of the concentration of the fine sediments ---
        self.verticalLayout_groupbox_interpolate_plot.removeWidget(self.canvas_Mfine)
        self.verticalLayout_groupbox_interpolate_plot.removeWidget(self.toolbar_Mfine)
        self.fig_Mfine, self.ax_Mfine = plt.subplots(1, 1, layout="constrained")
        self.canvas_Mfine = FigureCanvas(self.fig_Mfine)
        self.toolbar_Mfine = NavigationToolBar(self.canvas_Mfine, self)
        self.verticalLayout_groupbox_interpolate_plot.addWidget(self.toolbar_Mfine)
        self.verticalLayout_groupbox_interpolate_plot.addWidget(self.canvas_Mfine)

        for t, c in stg.fine_sample_profile:

            self.ax_Mfine.plot(stg.Ctot_fine[c], stg.depth_fine[c],
                               marker="o", mfc="k", mec="k", ms=10, ls="None")

            self.ax_Mfine.text(stg.Ctot_fine[c] + 0.05 * stg.Ctot_fine[c], stg.depth_fine[c], t,
                               fontstyle="normal", fontweight="light", fontsize=12)

        self.ax_Mfine.set_xlabel("Concentration fine sediments (g/L)")
        self.ax_Mfine.set_ylabel("Depth (m)")

        if stg.M_profile_fine.any():
            self.ax_Mfine.plot(stg.M_profile_fine, -stg.range_lin_interp,
                               marker="*", mfc="b", mec="b", ms=8, ls="None")

    def interpolate_Mfine_profile(self):
        # Variable 'stg.sand_sample_target_indice' is set only at
        # 'plot sample' button click
        if len(stg.sand_sample_target_indice) == 0:
            self._data_validity_message_box()
            return

        data_choice = self.combobox_acoustic_data_choice\
                          .currentIndex()

        if stg.depth_cross_section[data_choice].shape != (0,):
            depth_data = stg.depth_cross_section

            if stg.time_cross_section[data_choice].shape != (0,):
                time_data = stg.time_cross_section
            else:
                time_data = stg.time

        else:
            depth_data = stg.depth

            if stg.time_cross_section[data_choice].shape != (0,):
                time_data = stg.time_cross_sectino
            else:
                time_data = stg.time

        self.interpolate_Mfine_profile_compute(
            data_choice, depth_data, time_data
        )

    def interpolate_Mfine_profile_compute(self, data_choice, depth_data, time_data):
        range_cells=depth_data[data_choice][
            self.combobox_freq2.currentIndex(), :
        ]

        sample_depth = [
            -stg.depth_fine[k[1]]
            for k in stg.fine_sample_profile
        ]

        M_profile = [
            stg.Ctot_fine[k[1]]
            for k in stg.fine_sample_profile
        ]

        r_bottom = stg.depth_bottom[data_choice][
            np.where(
                np.abs(
                    time_data[data_choice][
                        self.combobox_freq2.currentIndex(), :
                    ]
                    - stg.time_fine[stg.fine_sample_profile[-1][1]]
                ) == np.nanmin(
                    np.abs(
                        time_data[data_choice][
                            self.combobox_freq2.currentIndex(), :
                        ]
                        - stg.time_fine[stg.fine_sample_profile[-1][1]])
                )
            )[0][0]
        ]

        logger.debug(
            "call 'inv_hc.M_profile_SCC_fine_interpolated' params:"
        )
        logger.debug(f"sample_depth = {sample_depth}")
        logger.debug(f"M_profile = {M_profile}")
        logger.debug(f"range_cells = {range_cells}")
        logger.debug(f"r_bottom = {r_bottom}")

        stg.range_lin_interp, stg.M_profile_fine = (
            self.inv_hc.M_profile_SCC_fine_interpolated(
                sample_depth=sample_depth,
                M_profile=M_profile,
                range_cells=range_cells,
                r_bottom=r_bottom
            )
        )

        stg.range_lin_interp = stg.range_lin_interp
        stg.M_profile_fine = stg.M_profile_fine
        stg.M_profile_fine = stg.M_profile_fine[
            :stg.range_lin_interp.shape[0]
        ]

        self.plot_profile_of_concentration_fine()

    def _data_validity_message_box(self):
        msgBox = QMessageBox()
        msgBox.setWindowTitle("Interpolate (step 2)")
        msgBox.setIconPixmap(
            QPixmap(
                self._path_icon("no_approved.png")
            )
            .scaledToHeight(32, Qt.SmoothTransformation)
        )
        msgBox.setText(
            "Please select and valid the sample data with"
            + "click on 'sample plot' button"
        )
        msgBox.setStandardButtons(QMessageBox.Ok)
        msgBox.exec()

    # ------------------------------------------------------------------
    # --------------- Functions for sediment calibration ---------------
    # ------------------------------------------------------------------

    def groupbox_calibration_import_toggle(self):
        if self.groupbox_sediment_calibration_import.isChecked() == True:
            self.groupbox_sediment_calibration_compute.setChecked(False)
        elif self.groupbox_sediment_calibration_import.isChecked() == True:
            self.groupbox_sediment_calibration_compute.setChecked(False)

    def groupbox_calibration_import_size_change(self):
        duration = 500
        self.animaiton_groupbox_import = QPropertyAnimation(self.groupbox_sediment_calibration_import, b"size")
        self.animaiton_groupbox_import.setDuration(duration)

        self.animaiton_groupbox_import.setStartValue(QSize(self.groupbox_sediment_calibration_import.width(),
                                              self.groupbox_sediment_calibration_import.height()))

        if self.groupbox_sediment_calibration_import.isChecked():
            self.animaiton_groupbox_import.setEndValue(
                QSize(self.groupbox_sediment_calibration_import.width(),
                      self.groupbox_sediment_calibration_import.sizeHint().height()))
        else:
            self.animaiton_groupbox_import.setEndValue(QSize(self.groupbox_sediment_calibration_import.width(), 25))

        self.animaiton_groupbox_import.start()

    def groupbox_calibration_compute_toggle(self):
        if self.groupbox_sediment_calibration_compute.isChecked() == True:
            self.groupbox_sediment_calibration_import.setChecked(False)
        elif self.groupbox_sediment_calibration_compute.isChecked() == True:
            self.groupbox_sediment_calibration_import.setChecked(False)

    def groupbox_calibration_compute_size_change(self):

        duration = 500
        self.animaiton_groupbox_compute = QPropertyAnimation(self.groupbox_sediment_calibration_compute, b"size")
        self.animaiton_groupbox_compute.setDuration(duration)

        self.animaiton_groupbox_compute.setStartValue(QSize(self.groupbox_sediment_calibration_compute.width(),
                                              self.groupbox_sediment_calibration_compute.height()))

        if self.groupbox_sediment_calibration_compute.isChecked():
            self.animaiton_groupbox_compute.setEndValue(
                QSize(self.groupbox_sediment_calibration_compute.width(),
                      self.groupbox_sediment_calibration_compute.sizeHint().height()))
        else:
            self.animaiton_groupbox_compute.setEndValue(QSize(self.groupbox_sediment_calibration_compute.width(), 25))

        self.animaiton_groupbox_compute.start()

    def import_calibration_file(self):

        filename = QFileDialog.getOpenFileName(
            self, "Open calibration",
            [stg.path_calibration_file if stg.path_calibration_file else
                                                stg.path_BS_raw_data[
                                                    -1] if self.combobox_acoustic_data_choice.count() > 0 else ""][0],
            "Calibration file (*.xls, *.ods, *csv)",
        options=QFileDialog.DontUseNativeDialog)

        dir_name = os.path.dirname(filename[0])
        name = os.path.basename(filename[0])

        stg.path_calibration_file = dir_name
        stg.filename_calibration_file = name

        self.lineEdit_import_calibration.clear()
        self.lineEdit_import_calibration.setText(name)

        self.lineEdit_import_calibration.setToolTip(dir_name)

        self.read_calibration_file_and_fill_parameter()

    def update_label_freq1_for_calibration(self):
        self.label_freq1.clear()
        self.label_freq1.setText(str(self.combobox_freq1.currentText()))

    def update_label_freq2_for_calibration(self):
        self.label_freq2.clear()
        self.label_freq2.setText(self.combobox_freq2.currentText())

    def update_label_kt_value_for_calibration(self):
        self.label_kt_freq1.clear()
        print("self.combobox_freq1.currentIndex() ", self.combobox_freq1.currentIndex(), self.combobox_freq1.currentText())
        if stg.kt_corrected[self.combobox_freq1.currentIndex()] != stg.kt_read[self.combobox_freq1.currentIndex()]:
            self.label_kt_freq1.setText(str('%.4f' % stg.kt_corrected[self.combobox_freq1.currentIndex()]))
        else:
            self.label_kt_freq1.setText(str('%.4f' % stg.kt_read[self.combobox_freq1.currentIndex()]))

        self.label_kt_freq2.clear()
        if stg.kt_corrected[self.combobox_freq2.currentIndex()] != stg.kt_read[self.combobox_freq2.currentIndex()]:
            self.label_kt_freq2.setText(str('%.4f' % stg.kt_corrected[self.combobox_freq2.currentIndex()]))
        else:
            self.label_kt_freq2.setText(str('%.4f' % stg.kt_read[self.combobox_freq2.currentIndex()]))

    def read_calibration_file_and_fill_parameter(self):
        if self.combobox_acoustic_data_choice.count() == 0:

            msgBox = QMessageBox()
            msgBox.setWindowTitle("Calibration import error")
            msgBox.setIconPixmap(
                QPixmap(self._path_icon("no_approved.png")).scaledToHeight(32, Qt.SmoothTransformation))
            msgBox.setText("Update data before importing calibration")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

        else:

            # --- Read calibration file ---
            data = pd.read_csv(stg.path_calibration_file + "/" + stg.filename_calibration_file, header=0, index_col=0)

            # --- Fill spinboxes of calibration parameter ---
            self.label_temperature.clear()
            self.label_temperature.setText("T = " + str(stg.temperature) + " °C")

            self.label_freq1.clear()
            self.label_freq1.setText(data.columns[0])

            index_freq1 = np.where(np.asarray(stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()]) ==
                                   data.columns[0])[0][0]
            stg.frequencies_for_calibration.clear()
            stg.frequencies_for_calibration.append((stg.freq[self.combobox_acoustic_data_choice.currentIndex()][
                                                        index_freq1],
                                                    index_freq1))

            self.label_freq2.clear()
            self.label_freq2.setText(data.columns[1])

            index_freq2 = np.where(np.asarray(stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()]) ==
                                   data.columns[1])[0][0]
            stg.frequencies_for_calibration.append((stg.freq[self.combobox_acoustic_data_choice.currentIndex()][
                                                        index_freq2],
                                                    index_freq2))

            stg.frequency_for_inversion = tuple()
            stg.frequency_for_inversion = (stg.freq[self.combobox_acoustic_data_choice.currentIndex()][index_freq2],
                                           index_freq2)

            self.lineEdit_ks_freq1.clear()
            self.lineEdit_ks_freq1.setText(str("%.5f" % float(data.iloc[0][0])))

            self.lineEdit_ks_freq2.clear()
            self.lineEdit_ks_freq2.setText(str("%.5f" % float(data.iloc[0][1])))

            stg.ks.clear()
            stg.ks = [float(self.lineEdit_ks_freq1.text()), float(self.lineEdit_ks_freq2.text())]

            self.lineEdit_sv_freq1.clear()
            self.lineEdit_sv_freq1.setText(str("%.5f" % float(data.iloc[1][0])))

            self.lineEdit_sv_freq2.clear()
            self.lineEdit_sv_freq2.setText(str("%.5f" % float(data.iloc[1][1])))

            stg.sv.clear()
            stg.sv = [float(self.lineEdit_sv_freq1.text()), float(self.lineEdit_sv_freq2.text())]

            self.lineEdit_X.clear()
            self.lineEdit_X.setText(str("%.2f" % float(data.iloc[2][0])))

            stg.X_exponent.clear()
            stg.X_exponent.append(float(self.lineEdit_X.text()))

            self.lineEdit_alphas_freq1.clear()
            self.lineEdit_alphas_freq1.setText(str("%.5f" % float(data.iloc[3][0])))

            self.lineEdit_alphas_freq2.clear()
            self.lineEdit_alphas_freq2.setText(str("%.5f" % float(data.iloc[3][1])))

            stg.alpha_s.clear()
            stg.alpha_s = [float(self.lineEdit_alphas_freq1.text()), float(self.lineEdit_alphas_freq2.text())]

            self.lineEdit_zeta_freq1.clear()
            self.lineEdit_zeta_freq1.setText(str("%.5f" % float(data.iloc[4][0])))

            self.lineEdit_zeta_freq2.clear()
            self.lineEdit_zeta_freq2.setText(str("%.5f" % float(data.iloc[4][1])))

            stg.zeta.clear()
            stg.zeta = [float(self.lineEdit_zeta_freq1.text()), float(self.lineEdit_zeta_freq2.text())]

            self.compute_kt2D_kt3D()
            self.compute_J_cross_section()

    def compute_depth_2D(self):
        if self.combobox_acoustic_data_choice.count() > 0:

            for k in range(self.combobox_acoustic_data_choice.count()):

                if stg.depth_cross_section[k].shape != (0,):

                    if stg.time_cross_section[k].shape != (0,):

                        stg.depth_2D[k] = (
                            np.zeros((stg.freq[k].shape[0],
                                      stg.depth_cross_section[k].shape[1],
                                      stg.time_cross_section[k].shape[1])))

                        for f, _ in enumerate(stg.freq[k]):
                            stg.depth_2D[k][f, :, :] = (
                                np.repeat(np.transpose(stg.depth_cross_section[k]
                                               [self.combobox_freq1.currentIndex()])[:, np.newaxis],
                                          stg.time_cross_section[k].shape[1],
                                          axis=1))

                    elif stg.time[k].shape != (0,):

                        stg.depth_2D[k] = (
                            np.zeros((stg.freq[k].shape[0],
                                      stg.depth_cross_section[k].shape[1],
                                      stg.time[k].shape[1])))

                        for f, _ in enumerate(stg.freq[k]):
                            stg.depth_2D[k][f, :, :] = (
                                np.repeat(
                                    np.transpose(stg.depth_cross_section[k]
                                                 [self.combobox_freq1.currentIndex()])[:, np.newaxis],
                                    stg.time[k].shape[1],
                                    axis=1))

                elif stg.depth[k].shape != (0,):

                    if stg.time_cross_section[k].shape != (0,):

                        stg.depth_2D[k] = (
                            np.zeros((stg.freq[k].shape[0],
                                      stg.depth[k].shape[1],
                                      stg.time_cross_section[k].shape[1])))

                        for f, _ in enumerate(stg.freq[k]):
                            stg.depth_2D[k][f, :, :] = (
                                np.repeat(
                                    np.transpose(stg.depth[k]
                                                 [self.combobox_freq1.currentIndex()])[:, np.newaxis],
                                    stg.time_cross_section[k].shape[1],
                                    axis=1))

                    elif stg.time[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                        stg.depth_2D[k] = (
                            np.zeros((stg.freq[k].shape[0],
                                      stg.depth[k].shape[1],
                                      stg.time[k].shape[1])))

                        for f, _ in enumerate(stg.freq[k]):
                            stg.depth_2D[k][f, :, :] = (
                                np.repeat(
                                    np.transpose(stg.depth[k]
                                                 [self.combobox_freq1.currentIndex()])[:, np.newaxis],
                                    stg.time[k].shape[1],
                                    axis=1))

    def function_pushbutton_compute_calibration(self):
        if len(stg.sand_sample_target_indice) == 0:
            self._data_validity_message_box()
            return

        self.label_temperature.clear()
        self.label_temperature.setText("T = " + str(stg.temperature) + " °C")

        self.compute_depth_2D()
        self.compute_ks()
        self.compute_sv()
        self.compute_X()
        self.compute_kt2D_kt3D()
        self.compute_J_cross_section()
        self.compute_alpha_s()
        self.compute_zeta()

    def compute_ks(self):
        psd_number_of_particles = (
            self.inv_hc.compute_particle_size_distribution_in_number_of_particles(
                num_sample=stg.sand_sample_target[0][1],
                r_grain=stg.radius_grain_sand,
                frac_vol_cumul=stg.frac_vol_sand_cumul
            )
        )

        ks_freq1 = self.inv_hc.ks(
            proba_num=psd_number_of_particles,
            freq=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq1.currentIndex()
            ],
            C=stg.water_velocity
        )

        ks_freq2 = self.inv_hc.ks(
            proba_num=psd_number_of_particles,
            freq=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][
                self.combobox_freq2.currentIndex()
            ],
            C=stg.water_velocity
        )

        stg.ks = [ks_freq1, ks_freq2]

        logger.debug(
            "ks for frequency of "
            + f"{stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex()]} : "
            + f"{ks_freq1} m/kg^0.5 \n"
        )
        logger.debug(
            "ks for frequency of "
            + f"{stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()]} : " +
            f"{ks_freq2} m/kg^0.5"
        )

        self.lineEdit_ks_freq1.clear()
        self.lineEdit_ks_freq1.setText(str("%.5f" % ks_freq1))

        self.lineEdit_ks_freq2.clear()
        self.lineEdit_ks_freq2.setText(str("%.5f" % ks_freq2))

    def compute_sv(self):
        sv_freq1 = self.inv_hc.sv(ks=stg.ks[0], M_sand=stg.Ctot_sand[stg.sand_sample_target[0][1]])
        sv_freq2 = self.inv_hc.sv(ks=stg.ks[1], M_sand=stg.Ctot_sand[stg.sand_sample_target[0][1]])

        stg.sv = [sv_freq1, sv_freq2]

        print(f"sv for frequency of {stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex()]} : {sv_freq1:.8f} /m \n")
        print(f"sv for frequency of {stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()]} : {sv_freq2:.8f} /m")

        self.lineEdit_sv_freq1.clear()
        self.lineEdit_sv_freq1.setText(str("%.5f" % sv_freq1))

        self.lineEdit_sv_freq2.clear()
        self.lineEdit_sv_freq2.setText(str("%.5f" % sv_freq2))

    def compute_X(self):
        X_exponent = self.inv_hc.X_exponent(freq1=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex()],
                                            freq2=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()],
                                            sv_freq1=stg.sv[0], sv_freq2=stg.sv[1])

        stg.X_exponent.clear()
        stg.X_exponent.append(X_exponent)

        print(f"Exponent X = {X_exponent:.2f}\n")

        self.lineEdit_X.setText(str("%.2f" % X_exponent))

    def compute_kt2D_kt3D(self):
        for i in range(self.combobox_acoustic_data_choice.count()):
            if stg.depth_cross_section[i].shape != (0,):
                depth_data = stg.depth_cross_section
            elif stg.depth[i].shape != (0,):
                depth_data = stg.depth
            else:
                continue

            if stg.time_cross_section[i].shape != (0,):
                time_data = stg.time_cross_section
            elif stg.time[i].shape != (0,):
                time_data = stg.time
            else:
                continue

            if stg.kt_corrected != stg.kt_read:
                kt_data = stg.kt_corrected
            else:
                kt_data = stg.kt_read

            stg.kt2D[i] = np.repeat(
                np.array([kt_data]).transpose(),
                time_data[i].shape[1],
                axis=1
            )

            stg.kt3D[i] = np.repeat(
                stg.kt2D[i][:, np.newaxis, :],
                depth_data[i].shape[1],
                axis=1
            )

    def compute_J_cross_section(self):
        for i in range(self.combobox_acoustic_data_choice.count()):

            J_cross_section_freq1 = np.array([])
            J_cross_section_freq2 = np.array([])

            # --- Compute J ---
            if stg.BS_stream_bed_pre_process_average[i].shape != (0,):

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_stream_bed_pre_process_average[i][
                       stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1],
                        :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_stream_bed_pre_process_average[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1],
                        :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            elif stg.BS_stream_bed_pre_process_SNR[i].shape != (0,):

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_stream_bed_pre_process_SNR[i][
                       stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1],
                        :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_stream_bed_pre_process_SNR[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1],
                        :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            elif stg.BS_stream_bed[i].shape != (0,):

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_stream_bed[i][stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_stream_bed[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            elif stg.BS_cross_section_pre_process_average[i].shape != (0,):

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_cross_section_pre_process_average[i][
                       stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1],
                        :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_cross_section_pre_process_average[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1],
                        :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            elif stg.BS_cross_section_pre_process_SNR[i].shape != (0,):

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_cross_section_pre_process_SNR[i][
                       stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1],
                        :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_cross_section_pre_process_SNR[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1],
                        :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            elif stg.BS_cross_section[i].shape != (0,):

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_cross_section[i][
                       stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i, :, :][stg.frequencies_for_calibration[0][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_cross_section[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i, :, :][stg.frequencies_for_calibration[1][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            elif stg.BS_raw_data_pre_process_average[i].shape != (0,):

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_raw_data_pre_process_average[i][
                       stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_raw_data_pre_process_average[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            elif stg.BS_raw_data_pre_process_SNR[i].shape != (0,):

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_raw_data_pre_process_SNR[i][
                       stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_raw_data_pre_process_SNR[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            elif stg.BS_raw_data:

                J_cross_section_freq1 = self.inv_hc.j_cross_section(
                    BS=stg.BS_raw_data[i][
                       stg.frequencies_for_calibration[0][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :])

                J_cross_section_freq2 = self.inv_hc.j_cross_section(
                    BS=stg.BS_raw_data[i][
                       stg.frequencies_for_calibration[1][1], :, :],
                    r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1], :, :],
                    kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :])

            stg.J_cross_section[i][0] = J_cross_section_freq1
            stg.J_cross_section[i][1] = J_cross_section_freq2

    def compute_alpha_s(self):

        # --- Compute alpha_s ---
        if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            alpha_s_freq1 = self.inv_hc.alpha_s(
                sv=stg.sv[0],
                j_cross_section=stg.J_cross_section[self.combobox_acoustic_data_choice.currentIndex()][0][
                    stg.sand_sample_target_indice[0][0], stg.sand_sample_target_indice[0][1]],
                depth=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq1.currentIndex(), stg.sand_sample_target_indice[0][0]],
                alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq1.currentIndex()])

            alpha_s_freq2 = self.inv_hc.alpha_s(
                sv=stg.sv[1],
                j_cross_section=stg.J_cross_section[self.combobox_acoustic_data_choice.currentIndex()][1][
                    stg.sand_sample_target_indice[1][0], stg.sand_sample_target_indice[1][1]],
                depth=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[1][0]],
                alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex()])

        else:

            alpha_s_freq1 = self.inv_hc.alpha_s(
                sv=stg.sv[0],
                j_cross_section=stg.J_cross_section[self.combobox_acoustic_data_choice.currentIndex()][0][
                    stg.sand_sample_target_indice[0][0], stg.sand_sample_target_indice[0][1]],
                depth=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq1.currentIndex(), stg.sand_sample_target_indice[0][0]],
                alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq1.currentIndex()])

            alpha_s_freq2 = self.inv_hc.alpha_s(
                sv=stg.sv[1],
                j_cross_section=stg.J_cross_section[self.combobox_acoustic_data_choice.currentIndex()][1][
                    stg.sand_sample_target_indice[1][0], stg.sand_sample_target_indice[1][1]],
                depth=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[1][0]],
                alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                    self.combobox_freq2.currentIndex()])

        stg.alpha_s = [alpha_s_freq1, alpha_s_freq2]

        print(f"\u03B1s for frequency of freq1 : {alpha_s_freq1:.2f} /m \n")
        print(f"\u03B1s for frequency of freq2 : {alpha_s_freq2:.2f} /m")

        self.lineEdit_alphas_freq1.clear()
        self.lineEdit_alphas_freq1.setText(str("%.5f" % alpha_s_freq1))

        self.lineEdit_alphas_freq2.clear()
        self.lineEdit_alphas_freq2.setText(str("%.5f" % alpha_s_freq2))

        if (alpha_s_freq1 < 0) or (alpha_s_freq2 < 0):

            msgBox = QMessageBox()
            msgBox.setWindowTitle("Alpha computation error")
            msgBox.setIconPixmap(QPixmap(self._path_icon("no_approved.png")).scaledToHeight(32, Qt.SmoothTransformation))
            msgBox.setText("Sediment sound attenuation is negative !")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

        else:

            msgBox = QMessageBox()
            msgBox.setWindowTitle("Alpha computation validation")
            msgBox.setIconPixmap(QPixmap(self._path_icon("approved.png")).scaledToHeight(32, Qt.SmoothTransformation))
            msgBox.setText("Sediment sound attenuation is positive.")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

    def compute_zeta(self):

        # --- Compute zeta ---
        if stg.M_profile_fine.shape == (0,):

            msgBox = QMessageBox()
            msgBox.setWindowTitle("Zeta computation error")
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Please interpolate fine profile")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

        else:

            if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                zeta_freq1 = self.inv_hc.zeta(alpha_s=stg.alpha_s[0],
                                              r=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                                self.combobox_freq1.currentIndex(), :],
                                              M_profile_fine=stg.M_profile_fine)
                zeta_freq2 = self.inv_hc.zeta(alpha_s=stg.alpha_s[1],
                                              r=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                                self.combobox_freq2.currentIndex(), :],
                                              M_profile_fine=stg.M_profile_fine)

            else:
                zeta_freq1 = self.inv_hc.zeta(alpha_s=stg.alpha_s[0],
                                              r=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                                                self.combobox_freq1.currentIndex(), :],
                                              M_profile_fine=stg.M_profile_fine)
                zeta_freq2 = self.inv_hc.zeta(alpha_s=stg.alpha_s[1],
                                              r=stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                                                self.combobox_freq2.currentIndex(), :],
                                              M_profile_fine=stg.M_profile_fine)

            stg.zeta = [zeta_freq1, zeta_freq2]

            print(f"\u03B6 for frequency of freq1 : {zeta_freq1:.3f} /m \n")
            print(f"\u03B6 for frequency of freq2 : {zeta_freq2:.3f} /m")

            self.lineEdit_zeta_freq1.clear()
            self.lineEdit_zeta_freq1.setText(str("%.5f" % zeta_freq1))

            self.lineEdit_zeta_freq2.clear()
            self.lineEdit_zeta_freq2.setText(str("%.5f" % zeta_freq2))

    def save_calibration(self):

        if stg.alpha_s:

            dir_save_cal = QFileDialog.getExistingDirectory(
                caption="Save calibration",
                directory=[stg.path_calibration_file if stg.path_calibration_file else stg.path_BS_raw_data[-1] if self.combobox_acoustic_data_choice.count() > 0 else ""][0],
                options=QFileDialog.DontUseNativeDialog)

            if dir_save_cal:

                stg.path_calibration_file = os.path.dirname(dir_save_cal)

                cal_array = [[' ', stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()][stg.frequencies_for_calibration[0][1]],
                                    stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()][stg.frequencies_for_calibration[1][1]]],
                             ['ks', stg.ks[0], stg.ks[1]],
                             ['sv', stg.sv[0], stg.sv[1]],
                             ['X', stg.X_exponent[0], 0],
                             ['alphas', stg.alpha_s[0], stg.alpha_s[1]],
                             ['zeta', stg.zeta[0], stg.zeta[1]]]

                eval("np.savetxt('"+ dir_save_cal + "/Sediment_calibration_" +
                                    str(stg.filename_BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()][:-4]) + ".csv' ," +
                                "cal_array, " +
                                "delimiter=',' ," +
                                "fmt ='% s'" +
                                ")")

        else:

            msgBox = QMessageBox()
            msgBox.setWindowTitle("Save Error")
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setText("Please compute calibration before saving")
            msgBox.setStandardButtons(QMessageBox.Ok)
            msgBox.exec()

    # --- Compute FCB ---

    # ------------ Computing real cell size ------------ #
    def range_cells_function(self):
        """ Computing the real cell size, that depends on the temperature """

        if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            aquascat_cell_size = []
            tau = []
            real_cell_size = []

            stg.depth_real = np.zeros(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape)

            for f in range(stg.freq[self.combobox_acoustic_data_choice.currentIndex()].shape[0]):
                # defaut Aquascat cell size
                aquascat_cell_size.append(
                    stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, 1] -
                    stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, 0])

                # Pulse duration
                tau.append(aquascat_cell_size[f] * 2 / 1500)  # figure 2.9  1500 vitesse du son entrée pour le paramètrage des mesures aquascat

                # Real cell size
                real_cell_size.append(stg.water_velocity * tau[f] / 2)  # voir fig 2.9

                # Converting to real cell profile
                stg.depth_real[f, :] = (stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][f, :]
                                        / aquascat_cell_size[f] * real_cell_size[f])

        else:

            aquascat_cell_size = []
            tau = []
            real_cell_size = []

            stg.depth_real = (np.zeros(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape))

            for f in range(stg.freq[self.combobox_acoustic_data_choice.currentIndex()].shape[0]):

                # defaut Aquascat cell size
                aquascat_cell_size.append(
                    stg.depth[self.combobox_acoustic_data_choice.currentIndex()][f, 1] -
                    stg.depth[self.combobox_acoustic_data_choice.currentIndex()][f, 0])

                # Pulse duration
                tau.append(aquascat_cell_size[f] * 2 / 1500)  # figure 2.9  1500 vitesse du son entrée pour le paramètrage des mesures aquascat

                # Real cell size
                real_cell_size.append(stg.water_velocity * tau[f] / 2)  # voir fig 2.9

                # Converting to real cell profile

                stg.depth_real[f, :] = (stg.depth[self.combobox_acoustic_data_choice.currentIndex()][f, :] /
                                            aquascat_cell_size[f] * real_cell_size[f])

        if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.depth_real = \
                (np.repeat(stg.depth_real[:, :, np.newaxis],
                           stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[1], axis=2))

        else:

            stg.depth_real = (
                np.repeat(stg.depth_real[:, :, np.newaxis],
                          stg.time[self.combobox_acoustic_data_choice.currentIndex()].shape[1], axis=2))

    def compute_FCB(self):

        self.combobox_frequency_FCB.clear()
        self.combobox_frequency_FCB.addItems(stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()])

        self.range_cells_function()

        if stg.BS_stream_bed_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_stream_bed_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        elif stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_stream_bed_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        elif stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        elif stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_cross_section_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        elif stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_cross_section_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        elif stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_cross_section[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        elif stg.BS_raw_data_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_raw_data_pre_process_average[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        elif stg.BS_raw_data_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_raw_data_pre_process_SNR[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        elif stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

            stg.FCB = \
                (np.log(stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()]) +
                 np.log(stg.depth_real) +
                 2 * stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex()] *
                 stg.depth_real)

        self.plot_FCB()

    def plot_FCB(self):

        if stg.FCB.shape != (0,):

            if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                self.slider_FCB.setMaximum(stg.time_cross_section[
                                               self.combobox_acoustic_data_choice.currentIndex()].shape[1])

            else:

                self.slider_FCB.setMaximum(stg.time[self.combobox_acoustic_data_choice.currentIndex()].shape[1])

            self.slider_FCB.setValue(stg.sand_sample_target_indice[0][1])

            self.verticalLayout_groupbox_FCB_plot.removeWidget(self.canvas_FCB)
            self.verticalLayout_groupbox_FCB_plot.removeWidget(self.toolbar_FCB)

            self.fig_FCB, self.axis_FCB = plt.subplots(nrows=1, ncols=1, layout="constrained")

            self.canvas_FCB = FigureCanvas(self.fig_FCB)
            self.toolbar_FCB = NavigationToolBar(self.canvas_FCB, self)

            self.verticalLayout_groupbox_FCB_plot.addWidget(self.toolbar_FCB)
            self.verticalLayout_groupbox_FCB_plot.addWidget(self.canvas_FCB)

            if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                self.axis_FCB.plot(
                    stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex()],
                    stg.FCB[self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1],
                    linestyle="solid", linewidth=1, color="k")
            else:

                self.axis_FCB.plot(
                    stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex()],
                    stg.FCB[self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1],
                    linestyle="solid", linewidth=1, color="k")

            self.axis_FCB.text(.95, .05,
                               stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()][
                                   self.combobox_frequency_FCB.currentIndex()],
                               fontsize=10, fontweight='bold', fontname="Ubuntu",
                               fontstyle="normal", c="black", alpha=0.2,
                               horizontalalignment='right', verticalalignment='bottom',
                               transform=self.axis_FCB.transAxes)

            self.fig_FCB.supxlabel("Depth (m)")
            self.fig_FCB.supylabel("FCB")
            self.fig_FCB.canvas.draw_idle()

            self.slider_FCB.valueChanged.connect(self.update_plot_FCB)
            self.combobox_frequency_FCB.currentIndexChanged.connect(self.update_plot_FCB)

    def update_plot_FCB(self):

        if stg.FCB.shape != (0,):
            self.axis_FCB.cla()

            if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                self.axis_FCB.plot(
                    stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex()],
                    stg.FCB[self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1],
                    linestyle="solid", linewidth=1, color="k")

            else:

                self.axis_FCB.plot(
                    stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex()],
                    stg.FCB[self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1],
                    linestyle="solid", linewidth=1, color="k")

            self.axis_FCB.text(.95, .05,
                               stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()][
                                   self.combobox_frequency_FCB.currentIndex()],
                               fontsize=10, fontweight='bold', fontname="Ubuntu",
                               fontstyle="normal", c="black", alpha=0.2,
                               horizontalalignment='right', verticalalignment='bottom',
                               transform=self.axis_FCB.transAxes)

            self.fig_FCB.canvas.draw_idle()

            # --- Update red line on acoustic record plot ---

            if stg.sand_sample_target_indice:

                if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                    if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                        self.red_line_plot_return.set_data(
                                stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                    self.combobox_freq2.currentIndex(), self.slider_FCB.value() -1] *
                                np.ones(
                                    stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[
                                        1]),
                                -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                 self.combobox_freq2.currentIndex(), :])

                    else:

                        self.red_line_plot_return.set_data(
                            stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), self.slider_FCB.value() -1] *
                            np.ones(stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape[
                                        1]),
                            -stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :])

                else:

                    if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                        self.red_line_plot_return.set_data(
                            stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), self.slider_FCB.value() -1] *
                                np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
                            -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                                 self.combobox_freq2.currentIndex(), :])

                    else:

                        self.red_line_plot_return.set_data(
                            stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), self.slider_FCB.value() -1] *
                                np.ones(stg.depth[self.combobox_acoustic_data_choice.currentIndex()].shape[1]),
                            -stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                                self.combobox_freq2.currentIndex(), :])

                self.fig_BS.canvas.draw_idle()

    def fit_FCB_profile_with_linear_regression_and_compute_alphaS(self):

        self.update_plot_FCB()

        if stg.FCB.shape != (0,):

            # --- Identify FCB profile where value are not NaN ---
            y0 = stg.FCB[self.combobox_frequency_FCB.currentIndex(), :, self.slider_FCB.value() - 1]
            y = y0[np.where(np.isnan(y0) == False)]

            if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):

                # --- Select depth corresponding to the FCB profile where value are not NaN ---
                x0 = stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex(), :]
                x = x0[np.where(np.isnan(y0) == False)]

                # --- Find the indices of the values between which the linear regression is fitted ---
                value1 = np.where(np.round(np.abs(x - float(self.lineEdit_FCB_from.text().replace(',','.'))), 2) ==
                                  np.min(np.round(np.abs(x - float(self.lineEdit_FCB_from.text().replace(',','.'))), 2)))[0][0]
                value2 = np.where(np.round(np.abs(x - float(self.lineEdit_FCB_to.text().replace(',', '.'))), 2) ==
                                  np.min(np.round(np.abs(x - float(self.lineEdit_FCB_to.text().replace(',', '.'))), 2)))[0][0]

                lin_reg_compute = linregress(x[value1:value2], y[value1:value2])

                stg.lin_reg.clear()
                stg.lin_reg = [lin_reg_compute.slope, lin_reg_compute.intercept]

                # --- Plot result of linear regression ---
                self.axis_FCB.plot(
                    stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex(), value1:value2],
                    stg.lin_reg[0] *
                        stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex(), value1:value2] +
                        stg.lin_reg[1],
                    linestyle="dashed", linewidth=1, color="b")

            else:

                # --- Select depth corresponding to the FCB profile where value are not NaN ---
                x0 = stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                     self.combobox_frequency_FCB.currentIndex(), :]
                x = x0[np.where(np.isnan(y0) == False)]

                # --- Find the indices of the values between which the linear regression is fitted ---
                value1 = np.where(np.round(np.abs(x - float(self.lineEdit_FCB_from.text().replace(',','.'))), 2) ==
                                  np.min(np.round(np.abs(x - float(self.lineEdit_FCB_from.text().replace(',','.'))), 2)))[0][0]
                value2 = np.where(np.round(np.abs(x - float(self.lineEdit_FCB_to.text().replace(',', '.'))), 2) ==
                                  np.min(np.round(np.abs(x - float(self.lineEdit_FCB_to.text().replace(',', '.'))), 2)))[0][0]

                lin_reg_compute = linregress(x[value1:value2], y[value1:value2])

                stg.lin_reg.clear()
                stg.lin_reg = [lin_reg_compute.slope, lin_reg_compute.intercept]

                # --- Plot result of linear regression ---
                self.axis_FCB.plot(
                    stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex(), value1:value2],
                    stg.lin_reg[0] *
                        stg.depth[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex(), value1:value2] +
                        stg.lin_reg[1],
                    linestyle="dashed", linewidth=1, color="b")

            self.fig_FCB.canvas.draw_idle()

            # --- Display the value of alphaS compute with FCB ---
            self.label_alphaS_FCB.clear()
            self.label_alphaS_FCB.setText(f"&alpha;<sub>s</sub> = {-0.5*stg.lin_reg[0]:.4f} dB/m")

    def slider_profile_number_to_begin_FCB(self):
        self.slider_FCB.setValue(int(self.slider_FCB.minimum()))
        self.update_lineEdit_by_moving_slider_FCB()

    def slider_profile_number_to_right_FCB(self):
        self.slider_FCB.setValue(int(self.slider_FCB.value()) + 1)
        self.update_lineEdit_by_moving_slider_FCB()

    def slider_profile_number_to_left_FCB(self):
        self.slider_FCB.setValue(int(self.slider_FCB.value()) - 1)
        self.update_lineEdit_by_moving_slider_FCB()

    def slider_profile_number_to_end_FCB(self):
        self.slider_FCB.setValue(int(self.slider_FCB.maximum()))
        self.update_lineEdit_by_moving_slider_FCB()

    def profile_number_on_lineEdit_FCB(self):
        if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
            self.slider_FCB.setValue(
                int(np.where(
                    np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                               self.combobox_frequency_FCB.currentIndex()] -
                           float(self.lineEdit_slider_FCB.text().replace(",", "."))) ==
                    np.nanmin(
                        np.abs(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                                   self.combobox_frequency_FCB.currentIndex()] -
                               float(self.lineEdit_slider_FCB.text().replace(",", ".")))))[0][0]))
        else:
            self.slider_FCB.setValue(
                int(np.where(
                    np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                               self.combobox_frequency_FCB.currentIndex()] -
                           float(self.lineEdit_slider_FCB.text().replace(",", "."))) ==
                    np.nanmin(
                        np.abs(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                                   self.combobox_frequency_FCB.currentIndex()] -
                               float(self.lineEdit_slider_FCB.text().replace(",", ".")))))[0][0]))

    def update_lineEdit_by_moving_slider_FCB(self):
        if stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
            self.lineEdit_slider_FCB.setText(
                str(stg.time_cross_section[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex(), self.slider_FCB.value()-1]))
        else:
            self.lineEdit_slider_FCB.setText(
                str(stg.time[self.combobox_acoustic_data_choice.currentIndex()][
                        self.combobox_frequency_FCB.currentIndex(), self.slider_FCB.value()-1]))
