Compare commits

...

14 Commits

6 changed files with 778 additions and 537 deletions

View File

@ -11,17 +11,13 @@ It is divided in six tabs:
- Calibration : calibration parameter are computed - Calibration : calibration parameter are computed
- Inversion : inversion method is calculated to provide fine and sand sediments fields - Inversion : inversion method is calculated to provide fine and sand sediments fields
## Software documentation ## Installation
### Installation
Acoused is developped for Linux and Windows on Python version 3.8 or Acoused is developped for Linux and Windows on Python version 3.8 or
greater. By default, Acoused is developped with Pypi package greater. By default, Acoused is developped with Pypi package
dependencies, but is also possible to use Guix package manager to run dependencies, but is also possible to use Guix package manager to run
Acoused. Acoused.
## Development documentation
### **TODO** Windows ### **TODO** Windows
### Linux ### Linux
@ -49,27 +45,6 @@ script `guix.sh` to run the program.
guix shell sqlitebrowser -- ./guix.sh guix shell sqlitebrowser -- ./guix.sh
``` ```
## License
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/>.
## Authors & Contacts
- Brahim MOUDJED 2022-2025 ([INRAE](https://www.inrae.fr/))
- Pierre-Antoine ROUBY 2025 ([TECC](https://parouby.fr))
If you have any questions or suggestions, please contact us to celine.berni@inrae.fr and/or jerome.lecoz@inrae.fr.
## Acknowledgment (Funding)
This study was conducted within the [Rhône Sediment Observatory](https://observatoire-sediments-rhone.fr/) (OSR), a multi-partner research program funded through the Plan Rhône by the European Regional Development Fund (ERDF), Agence de lEau RMC, CNR, EDF and three regional councils (Auvergne-Rhône-Alpes, PACA and Occitanie). It was also support by CNR.
## Support files & References ## Support files & References
- [ ] [Acoustic inversion method diagram](https://forgemia.inra.fr/theophile.terraz/acoused/-/blob/main/Acoustic_Inversion_theory.pdf?ref_type=heads) - [ ] [Acoustic inversion method diagram](https://forgemia.inra.fr/theophile.terraz/acoused/-/blob/main/Acoustic_Inversion_theory.pdf?ref_type=heads)
@ -80,3 +55,24 @@ This study was conducted within the [Rhône Sediment Observatory](https://observ
- [ ] [Vergne A., Le Coz J., Berni C., & Pierrefeu G. (2020), Water Resources Research, 56(2)](https://doi.org/10.1029/2019WR024877) - [ ] [Vergne A., Le Coz J., Berni C., & Pierrefeu G. (2020), Water Resources Research, 56(2)](https://doi.org/10.1029/2019WR024877)
- [ ] [Vergne A., Berni C., Le Coz J., & Tencé F., (2021), Water Resources Research, 57(9)](https://doi.org/10.1029/2021WR029589) - [ ] [Vergne A., Berni C., Le Coz J., & Tencé F., (2021), Water Resources Research, 57(9)](https://doi.org/10.1029/2021WR029589)
## Authors & Contacts
- Brahim MOUDJED 2022-2025 ([INRAE](https://www.inrae.fr/))
- Pierre-Antoine ROUBY 2025 ([TECC](https://parouby.fr))
If you have any questions or suggestions, please contact us to celine.berni@inrae.fr and/or jerome.lecoz@inrae.fr.
## Acknowledgment (Funding)
This study was conducted within the [Rhône Sediment Observatory](https://observatoire-sediments-rhone.fr/) (OSR), a multi-partner research program funded through the Plan Rhône by the European Regional Development Fund (ERDF), Agence de lEau RMC, CNR, EDF and three regional councils (Auvergne-Rhône-Alpes, PACA and Occitanie). It was also support by CNR.
## License
AcouSed
Copyright (C) 2024-2025 - 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/>.

View File

@ -1,6 +1,6 @@
# ============================================================================== # # ============================================================================== #
# acoustic_data_tab.py - AcouSed # # acoustic_data_tab.py - AcouSed #
# Copyright (C) 2024 INRAE # # Copyright (C) 2024-2025 INRAE #
# # # #
# This program is free software: you can redistribute it and/or modify # # 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 # # it under the terms of the GNU General Public License as published by #
@ -20,6 +20,21 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
import locale
import logging
import numpy as np
import pandas as pd
from re import findall
from copy import deepcopy
from scipy.signal import savgol_filter
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm, CSS4_COLORS, BoundaryNorm
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QWidget, QVBoxLayout, QHBoxLayout, QGroupBox,
@ -34,26 +49,9 @@ from PyQt5.QtCore import (
QPropertyAnimation QPropertyAnimation
) )
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm, CSS4_COLORS, BoundaryNorm
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
import os
from copy import deepcopy
import locale
locale.setlocale(locale.LC_ALL, '')
from scipy.signal import savgol_filter
from re import findall
from pyqt_file_list_widget.fileListWidget import FileListWidget from pyqt_file_list_widget.fileListWidget import FileListWidget
import settings as stg
import Translation.constant_string as cs import Translation.constant_string as cs
from Model.TableModel import TableModel from Model.TableModel import TableModel
@ -61,10 +59,12 @@ from Model.acoustic_data_loader import AcousticDataLoader
from Model.acoustic_data_loader_UBSediFlow import AcousticDataLoaderUBSediFlow from Model.acoustic_data_loader_UBSediFlow import AcousticDataLoaderUBSediFlow
from Model.calibration_constant_kt import CalibrationConstantKt from Model.calibration_constant_kt import CalibrationConstantKt
import settings as stg
locale.setlocale(locale.LC_ALL, '')
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
logger = logging.getLogger()
class AcousticDataTab(QWidget): class AcousticDataTab(QWidget):
COMPTEUR = 1 COMPTEUR = 1
@ -79,18 +79,8 @@ class AcousticDataTab(QWidget):
def __init__(self, tab_widget): def __init__(self, tab_widget):
super().__init__() super().__init__()
self.path_icon = "./icons/" self._setup_icons()
self.icon_folder = QIcon(self.path_icon + "folder.png")
self.icon_apply_limits = QIcon(self.path_icon + "circle_green_arrow_right.png")
self.icon_triangle_left_to_begin = QIcon(self.path_icon + "triangle_left_to_begin.png")
self.icon_triangle_left = QIcon(self.path_icon + "triangle_left.png")
self.icon_triangle_right = QIcon(self.path_icon + "triangle_right.png")
self.icon_triangle_right_to_end = QIcon(self.path_icon + "triangle_right_to_end.png")
self.icon_add = QIcon(self.path_icon + "add.png")
self.icon_delete = QIcon(self.path_icon + "delete.png")
self.icon_clear = QIcon(self.path_icon + "clear.png")
self.icon_between = QPixmap(self.path_icon + "between.png")
self.icon_refresh = QIcon(self.path_icon + "update.png")
self.calib_kt = CalibrationConstantKt() self.calib_kt = CalibrationConstantKt()
### --- General layout of widgets --- ### --- General layout of widgets ---
@ -642,7 +632,7 @@ class AcousticDataTab(QWidget):
self.fileListWidget.itemSelectionChanged.connect(self.compute_tmin_tmax) self.fileListWidget.itemSelectionChanged.connect(self.compute_tmin_tmax)
self.fileListWidget.itemSelectionChanged.connect(self.compute_rmin_rmax) self.fileListWidget.itemSelectionChanged.connect(self.compute_rmin_rmax)
self.fileListWidget.itemSelectionChanged.connect(self.update_frequency_combobox) self.fileListWidget.itemSelectionChanged.connect(self.update_frequency_combobox)
self.fileListWidget.itemSelectionChanged.connect(self.plot_backscattered_acoustic_signal_recording) # self.fileListWidget.itemSelectionChanged.connect(self.plot_backscattered_acoustic_signal_recording)
self.fileListWidget.itemSelectionChanged.connect(self.plot_profile) self.fileListWidget.itemSelectionChanged.connect(self.plot_profile)
self.fileListWidget.itemSelectionChanged.connect(self.update_plot_backscattered_acoustic_signal_recording) self.fileListWidget.itemSelectionChanged.connect(self.update_plot_backscattered_acoustic_signal_recording)
self.fileListWidget.itemSelectionChanged.connect(self.update_plot_profile) self.fileListWidget.itemSelectionChanged.connect(self.update_plot_profile)
@ -691,6 +681,25 @@ class AcousticDataTab(QWidget):
self.slider.valueChanged.connect(self.update_plot_profile) self.slider.valueChanged.connect(self.update_plot_profile)
self.slider.valueChanged.connect(self.update_plot_backscattered_acoustic_signal_recording) self.slider.valueChanged.connect(self.update_plot_backscattered_acoustic_signal_recording)
def _setup_icons(self):
def path_icon(icon):
return os.path.join(
"icons", icon
)
self.icon_folder = QIcon(path_icon("folder.png"))
self.icon_apply_limits = QIcon(path_icon("circle_green_arrow_right.png"))
self.icon_triangle_left_to_begin = QIcon(path_icon("triangle_left_to_begin.png"))
self.icon_triangle_left = QIcon(path_icon("triangle_left.png"))
self.icon_triangle_right = QIcon(path_icon("triangle_right.png"))
self.icon_triangle_right_to_end = QIcon(path_icon("triangle_right_to_end.png"))
self.icon_add = QIcon(path_icon("add.png"))
self.icon_delete = QIcon(path_icon("delete.png"))
self.icon_clear = QIcon(path_icon("clear.png"))
self.icon_between = QPixmap(path_icon("between.png"))
self.icon_refresh = QIcon(path_icon("update.png"))
# -------------------- Functions for Acoustic dataTab -------------------- # -------------------- Functions for Acoustic dataTab --------------------
def retranslate_acoustic_data_tab(self): def retranslate_acoustic_data_tab(self):
@ -1100,7 +1109,6 @@ class AcousticDataTab(QWidget):
def distance_from_ABS_to_free_surface(self): def distance_from_ABS_to_free_surface(self):
if self.fileListWidget.count() == 0: if self.fileListWidget.count() == 0:
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.setWindowTitle("Distance ABS - Free surface Error") msgBox.setWindowTitle("Distance ABS - Free surface Error")
msgBox.setIcon(QMessageBox.Warning) msgBox.setIcon(QMessageBox.Warning)
@ -1109,18 +1117,22 @@ class AcousticDataTab(QWidget):
msgBox.exec() msgBox.exec()
self.lineEdit_distance_from_ABS_to_free_surface.setText("0.00") self.lineEdit_distance_from_ABS_to_free_surface.setText("0.00")
else: else:
stg.distance_from_ABS_to_free_surface[self.fileListWidget\
stg.distance_from_ABS_to_free_surface[self.fileListWidget.currentRow()] = ( .currentRow()] = (
float(self.lineEdit_distance_from_ABS_to_free_surface.text().replace(",", "."))) float(
self.lineEdit_distance_from_ABS_to_free_surface\
.text().replace(",", ".")
)
)
self.lineEdit_distance_from_ABS_to_free_surface.setText( self.lineEdit_distance_from_ABS_to_free_surface.setText(
str("%4s" % stg.distance_from_ABS_to_free_surface[self.fileListWidget.currentRow()])) str("%4s" % stg.distance_from_ABS_to_free_surface[self.fileListWidget.currentRow()]))
def refresh_distance_from_ABS_to_free_surface(self): def refresh_distance_from_ABS_to_free_surface(self):
acoustic_data = AcousticDataLoader(
acoustic_data = AcousticDataLoader(stg.path_BS_raw_data[self.fileListWidget.currentRow()] + "/" + stg.path_BS_raw_data[self.fileListWidget.currentRow()] + "/" +
stg.filename_BS_raw_data[self.fileListWidget.currentRow()]) stg.filename_BS_raw_data[self.fileListWidget.currentRow()]
)
stg.depth[self.fileListWidget.currentRow()] = acoustic_data._r stg.depth[self.fileListWidget.currentRow()] = acoustic_data._r
stg.depth_reshape[self.fileListWidget.currentRow()] = acoustic_data.reshape_r() stg.depth_reshape[self.fileListWidget.currentRow()] = acoustic_data.reshape_r()
@ -1294,6 +1306,8 @@ class AcousticDataTab(QWidget):
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
else: else:
self.fileListWidget.blockSignals(True)
if self.fileListWidget.count() == 0: if self.fileListWidget.count() == 0:
for p, f in zip(stg.path_BS_raw_data, for p, f in zip(stg.path_BS_raw_data,
stg.filename_BS_raw_data): stg.filename_BS_raw_data):
@ -1322,6 +1336,8 @@ class AcousticDataTab(QWidget):
) )
) )
self.fileListWidget.blockSignals(False)
def rename_file_in_ListWidget(self, event): def rename_file_in_ListWidget(self, event):
if event == QEvent.MouseButtonPress: if event == QEvent.MouseButtonPress:
@ -1441,14 +1457,20 @@ class AcousticDataTab(QWidget):
def clear_files_from_ListWidget(self): def clear_files_from_ListWidget(self):
list_to_clear = ["stg.acoustic_data", "stg.date", "stg.hour", "stg.freq", "stg.freq_text", "stg.temperature", list_to_clear = [
"stg.nb_profiles", "stg.nb_profiles_per_sec", "stg.nb_cells", "stg.cell_size", "stg.acoustic_data", "stg.date", "stg.hour",
"stg.pulse_length", "stg.nb_pings_per_sec", "stg.nb_pings_averaged_per_profile", "stg.freq", "stg.freq_text", "stg.temperature",
"stg.nb_profiles", "stg.nb_profiles_per_sec",
"stg.nb_cells", "stg.cell_size",
"stg.pulse_length", "stg.nb_pings_per_sec",
"stg.nb_pings_averaged_per_profile",
"stg.kt_read", "stg.kt_corrected", "stg.gain_rx", "stg.gain_tx", "stg.kt_read", "stg.kt_corrected", "stg.gain_rx", "stg.gain_tx",
"stg.BS_raw_data", "stg.time", "stg.depth", "stg.BS_raw_data", "stg.time", "stg.depth",
"stg.BS_raw_data_reshape", "stg.time_reshape", "stg.depth_reshape", "stg.BS_raw_data_reshape", "stg.time_reshape", "stg.depth_reshape",
"stg.rmin", "stg.rmax", "stg.tmin", "stg.tmax", "stg.rmin", "stg.rmax", "stg.tmin", "stg.tmax",
"stg.time_cross_section", "stg.depth_cross_section", "stg.BS_cross_section"] "stg.time_cross_section", "stg.depth_cross_section",
"stg.BS_cross_section"
]
for k in list_to_clear: for k in list_to_clear:
if isinstance(k, list): if isinstance(k, list):
@ -1530,34 +1552,42 @@ class AcousticDataTab(QWidget):
self.slider.setMaximum(10) self.slider.setMaximum(10)
def load_BS_acoustic_raw_data(self): def load_BS_acoustic_raw_data(self):
if self.fileListWidget.count() == 0: if self.fileListWidget.count() == 0:
for p, f in zip(stg.path_BS_raw_data,
for p, f in zip(stg.path_BS_raw_data, stg.filename_BS_raw_data): stg.filename_BS_raw_data):
if self.combobox_ABS_system_choice.currentIndex() == 1: if self.combobox_ABS_system_choice.currentIndex() == 1:
acoustic_data = AcousticDataLoader(
acoustic_data = AcousticDataLoader(p + "/" + f) os.path.join(p, f)
)
elif self.combobox_ABS_system_choice.currentIndex() == 2: elif self.combobox_ABS_system_choice.currentIndex() == 2:
acoustic_data = AcousticDataLoaderUBSediFlow(
os.path.join(p, f)
)
acoustic_data = AcousticDataLoaderUBSediFlow(p + "/" + f) self.initiate_setting_parameters(
acoustic_data=acoustic_data
self.initiate_setting_parameters(acoustic_data=acoustic_data) )
else: else:
for k in range(self.fileListWidget.count(),
for k in range(self.fileListWidget.count(), len(stg.filename_BS_raw_data), 1): len(stg.filename_BS_raw_data), 1):
if self.combobox_ABS_system_choice.currentIndex() == 1: if self.combobox_ABS_system_choice.currentIndex() == 1:
acoustic_data = AcousticDataLoader(
acoustic_data = AcousticDataLoader(stg.path_BS_raw_data[k] + "/" + stg.filename_BS_raw_data[k]) os.path.join(
stg.path_BS_raw_data[k],
stg.filename_BS_raw_data[k]
)
)
elif self.combobox_ABS_system_choice.currentIndex() == 2: elif self.combobox_ABS_system_choice.currentIndex() == 2:
acoustic_data = AcousticDataLoaderUBSediFlow(
os.path.join(
stg.path_BS_raw_data[k],
stg.filename_BS_raw_data[k]
)
)
acoustic_data = AcousticDataLoaderUBSediFlow(stg.path_BS_raw_data[k] + "/" + stg.filename_BS_raw_data[k]) self.initiate_setting_parameters(
acoustic_data=acoustic_data
self.initiate_setting_parameters(acoustic_data=acoustic_data) )
def initiate_setting_parameters(self, acoustic_data): def initiate_setting_parameters(self, acoustic_data):
# --- The acoustic variables are field with loaded data --- # --- The acoustic variables are field with loaded data ---
@ -1644,156 +1674,290 @@ class AcousticDataTab(QWidget):
stg.SSC_sand.append(np.array([])) stg.SSC_sand.append(np.array([]))
def fill_measurements_information_groupbox(self): def fill_measurements_information_groupbox(self):
if self.fileListWidget.currentRow() == -1:
return
if self.fileListWidget.currentRow() != -1: self.fill_measurements_information_groupbox_datetime()
self.fill_measurements_information_groupbox_frequency()
self.fill_measurements_information_groupbox_cells()
self.fill_measurements_information_groupbox_kt()
def fill_measurements_information_groupbox_datetime(self):
self.label_date_acoustic_file.clear() self.label_date_acoustic_file.clear()
self.label_date_acoustic_file.setText("Date: " + str(stg.date[self.fileListWidget.currentRow()])) self.label_date_acoustic_file.setText(
self.gridLayout_groupbox_info.addWidget(self.label_date_acoustic_file, 1, 0, 1, 1, Qt.AlignLeft) "Date: " + str(stg.date[self.fileListWidget.currentRow()])
)
self.gridLayout_groupbox_info.addWidget(
self.label_date_acoustic_file,
1, 0, 1, 1,
Qt.AlignLeft
)
self.label_hour_acoustic_file.clear() self.label_hour_acoustic_file.clear()
self.label_hour_acoustic_file.setText("Hour: " + str(stg.hour[self.fileListWidget.currentRow()])) self.label_hour_acoustic_file.setText(
self.gridLayout_groupbox_info.addWidget(self.label_hour_acoustic_file, 1, 1, 1, 1, Qt.AlignLeft) "Hour: " + str(stg.hour[self.fileListWidget.currentRow()])
)
self.gridLayout_groupbox_info.addWidget(
self.label_hour_acoustic_file,
1, 1, 1, 1,
Qt.AlignLeft
)
def fill_measurements_information_groupbox_frequency(self):
file_id = self.fileListWidget.currentRow()
freq_id = self.combobox_frequency_information.currentIndex()
self.combobox_frequency_information.clear() self.combobox_frequency_information.clear()
self.combobox_frequency_information.addItems(stg.freq_text[self.fileListWidget.currentRow()]) self.combobox_frequency_information.addItems(
self.combobox_frequency_information.currentIndexChanged.connect(self.combobox_frequency_information_update) stg.freq_text[file_id]
)
self.combobox_frequency_information\
.currentIndexChanged\
.connect(self.combobox_frequency_information_update)
self.lineEdit_temperature.setText(str(stg.temperature)) self.lineEdit_temperature.setText(str(stg.temperature))
self.label_profiles_value.setText(str(stg.nb_profiles[self.fileListWidget.currentRow()] self.label_profiles_value.setText(
[self.combobox_frequency_information.currentIndex()])) str(stg.nb_profiles[file_id][freq_id])
self.gridLayout_groupbox_info.addWidget(self.label_profiles_value, 8, 1, 1, 1, Qt.AlignLeft) )
self.gridLayout_groupbox_info.addWidget(
self.label_profiles_value,
8, 1, 1, 1,
Qt.AlignLeft
)
self.label_profiles_per_sec_value.setText(str(stg.nb_profiles_per_sec[self.fileListWidget.currentRow()] self.label_profiles_per_sec_value.setText(
[self.combobox_frequency_information.currentIndex()]) + " Hz") str(stg.nb_profiles_per_sec[file_id][freq_id]) + " Hz"
self.gridLayout_groupbox_info.addWidget(self.label_profiles_per_sec_value, 9, 1, 1, 1, Qt.AlignLeft) )
self.gridLayout_groupbox_info.addWidget(
self.label_profiles_per_sec_value,
9, 1, 1, 1,
Qt.AlignLeft
)
self.label_cells_value.setText(str(stg.nb_cells[self.fileListWidget.currentRow()] def fill_measurements_information_groupbox_cells(self):
[self.combobox_frequency_information.currentIndex()])) file_id = self.fileListWidget.currentRow()
self.gridLayout_groupbox_info.addWidget(self.label_cells_value, 10, 1, 1, 1, Qt.AlignLeft) freq_id = self.combobox_frequency_information.currentIndex()
self.label_cell_size_value.setText(str(100*round(stg.cell_size[self.fileListWidget.currentRow()] self.label_cells_value.setText(
[self.combobox_frequency_information.currentIndex()], 3)) + " cm") str(stg.nb_cells[file_id][freq_id])
self.gridLayout_groupbox_info.addWidget(self.label_cell_size_value, 11, 1, 1, 1, Qt.AlignLeft) )
self.gridLayout_groupbox_info.addWidget(
self.label_cells_value,
10, 1, 1, 1,
Qt.AlignLeft
)
self.label_pulse_length_value.setText(str(round(stg.pulse_length[self.fileListWidget.currentRow()] self.label_cell_size_value.setText(
[self.combobox_frequency_information.currentIndex()], 6)) + " sec") str(100*round(stg.cell_size[file_id][freq_id], 3)) + " cm"
self.gridLayout_groupbox_info.addWidget(self.label_pulse_length_value, 12, 1, 1, 1, Qt.AlignLeft) )
self.label_pings_per_sec_value.setText(str(stg.nb_pings_per_sec[self.fileListWidget.currentRow()] self.gridLayout_groupbox_info.addWidget(
[self.combobox_frequency_information.currentIndex()]) + " Hz") self.label_cell_size_value,
self.gridLayout_groupbox_info.addWidget(self.label_pings_per_sec_value, 13, 1, 1, 1, Qt.AlignLeft) 11, 1, 1, 1,
Qt.AlignLeft
)
self.label_pings_per_profile_value.setText(str(stg.nb_pings_averaged_per_profile[self.fileListWidget.currentRow()] self.label_pulse_length_value.setText(
[self.combobox_frequency_information.currentIndex()])) str(round(stg.pulse_length[file_id][freq_id], 6)) + " sec"
self.gridLayout_groupbox_info.addWidget(self.label_pings_per_profile_value, 14, 1, 1, 1, Qt.AlignLeft) )
self.gridLayout_groupbox_info.addWidget(
self.label_pulse_length_value,
12, 1, 1, 1,
Qt.AlignLeft
)
self.label_pings_per_sec_value.setText(
str(stg.nb_pings_per_sec[file_id][freq_id]) + " Hz"
)
self.gridLayout_groupbox_info.addWidget(
self.label_pings_per_sec_value,
13, 1, 1, 1,
Qt.AlignLeft
)
self.label_pings_per_profile_value.setText(
str(stg.nb_pings_averaged_per_profile[file_id][freq_id])
)
self.gridLayout_groupbox_info.addWidget(
self.label_pings_per_profile_value,
14, 1, 1, 1,
Qt.AlignLeft
)
def fill_measurements_information_groupbox_kt(self):
file_id = self.fileListWidget.currentRow()
freq_id = self.combobox_frequency_information.currentIndex()
abs_id = self.combobox_ABS_name.currentText()
data_ABS = self.calib_kt.data_ABS[abs_id]["Frequency"].values
stg.kt_corrected.clear() stg.kt_corrected.clear()
for f in range(stg.freq[self.fileListWidget.currentRow()].shape[0]): for f in range(stg.freq[file_id].shape[0]):
freq_array = np.array(
[
stg.freq[file_id][f] - freq
for freq in data_ABS
]
)
stg.kt_corrected.append( stg.kt_corrected.append(
self.calib_kt.data_ABS[self.combobox_ABS_name.currentText()].iloc[ self.calib_kt.data_ABS[abs_id].iloc[
np.where( np.where(
np.abs(np.array([stg.freq[self.fileListWidget.currentRow()][f] - l for l in np.abs(
self.calib_kt.data_ABS[self.combobox_ABS_name.currentText()][ freq_array
self.calib_kt.data_ABS[ ) == np.min(
self.combobox_ABS_name.currentText()].columns[0]].values])) np.abs(
== freq_array
np.min(np.abs(np.array([stg.freq[self.fileListWidget.currentRow()][f] - l for l in )
self.calib_kt.data_ABS[self.combobox_ABS_name.currentText()][ )
self.calib_kt.data_ABS[
self.combobox_ABS_name.currentText()].columns[
0]].values])
))
)[0][0] )[0][0]
][1]) ][1]
)
self.lineEdit_kt.setText(
self.lineEdit_kt.setText(str("%.4f" % stg.kt_corrected[self.combobox_frequency_information.currentIndex()])) str("%.4f" % stg.kt_corrected[freq_id])
)
self.lineEdit_kt.setEnabled(True) self.lineEdit_kt.setEnabled(True)
self.lineEdit_kt.returnPressed.connect(self.kt_value) self.lineEdit_kt.returnPressed.connect(self.kt_value)
self.lineEdit_rx.setText(str("%.2f" % stg.gain_rx[self.fileListWidget.currentRow()][self.combobox_frequency_information.currentIndex()])) self.lineEdit_rx.setText(
str("%.2f" % stg.gain_rx[file_id][freq_id])
)
self.lineEdit_rx.setEnabled(False) self.lineEdit_rx.setEnabled(False)
self.checkbox_rx.stateChanged.connect(self.activate_unactivate_spinbox_rx) self.checkbox_rx.stateChanged.connect(
self.activate_unactivate_spinbox_rx
)
self.lineEdit_rx.returnPressed.connect(self.gain_rx_value) self.lineEdit_rx.returnPressed.connect(self.gain_rx_value)
self.lineEdit_tx.setText(str("%.2f" % stg.gain_tx[self.fileListWidget.currentRow()][self.combobox_frequency_information.currentIndex()])) self.lineEdit_tx.setText(str("%.2f" % stg.gain_tx[file_id][freq_id]))
self.lineEdit_tx.setEnabled(False) self.lineEdit_tx.setEnabled(False)
self.checkbox_tx.stateChanged.connect(self.activate_unactivate_spinbox_tx) self.checkbox_tx.stateChanged.connect(
self.activate_unactivate_spinbox_tx
)
self.lineEdit_tx.returnPressed.connect(self.gain_tx_value) self.lineEdit_tx.returnPressed.connect(self.gain_tx_value)
def combobox_frequency_information_update(self): def combobox_frequency_information_update(self):
if self.fileListWidget.count() > 0: if self.fileListWidget.count() <= 0:
return
if stg.water_attenuation[self.fileListWidget.currentRow()]: file_id = self.fileListWidget.currentRow()
freq_id = self.combobox_frequency_information.currentIndex()
if stg.water_attenuation[file_id]:
self.lineEdit_sound_attenuation.setText( self.lineEdit_sound_attenuation.setText(
str("%.6f" % stg.water_attenuation[self.fileListWidget.currentRow()][ str(
self.combobox_frequency_information.currentIndex()])) "%.6f"
% stg.water_attenuation[file_id][freq_id]
)
)
self.label_profiles_value.clear() self.label_profiles_value.clear()
self.gridLayout_groupbox_info.removeWidget(self.label_profiles_value) self.gridLayout_groupbox_info.removeWidget(
self.label_profiles_value.setText(str(stg.nb_profiles[self.fileListWidget.currentRow()] self.label_profiles_value
[self.combobox_frequency_information.currentIndex()])) )
self.gridLayout_groupbox_info.addWidget(self.label_profiles_value, 8, 1, 1, 1, Qt.AlignLeft) self.label_profiles_value.setText(
str(
stg.nb_profiles[file_id][freq_id]
)
)
self.gridLayout_groupbox_info.addWidget(
self.label_profiles_value,
8, 1, 1, 1, Qt.AlignLeft
)
self.label_profiles_per_sec_value.clear() self.label_profiles_per_sec_value.clear()
self.label_profiles_per_sec_value.setText( self.label_profiles_per_sec_value.setText(
str(stg.nb_profiles_per_sec[self.fileListWidget.currentRow()] str(
[self.combobox_frequency_information.currentIndex()]) + " Hz") stg.nb_profiles_per_sec[file_id][freq_id]
self.gridLayout_groupbox_info.addWidget(self.label_profiles_per_sec_value, 9, 1, 1, 1, Qt.AlignLeft) ) + " Hz"
)
self.gridLayout_groupbox_info.addWidget(
self.label_profiles_per_sec_value,
9, 1, 1, 1, Qt.AlignLeft
)
self.label_cells_value.clear() self.label_cells_value.clear()
self.label_cells_value.setText(str(stg.nb_cells[self.fileListWidget.currentRow()] self.label_cells_value.setText(
[self.combobox_frequency_information.currentIndex()])) str(
self.gridLayout_groupbox_info.addWidget(self.label_cells_value, 10, 1, 1, 1, Qt.AlignLeft) stg.nb_cells[file_id][freq_id]
)
)
self.gridLayout_groupbox_info.addWidget(
self.label_cells_value,
10, 1, 1, 1, Qt.AlignLeft
)
self.label_cell_size_value.clear() self.label_cell_size_value.clear()
self.gridLayout_groupbox_info.removeWidget(self.label_cell_size_value) self.gridLayout_groupbox_info.removeWidget(self.label_cell_size_value)
self.label_cell_size_value.setText( self.label_cell_size_value.setText(
str(100 * round(stg.cell_size[self.fileListWidget.currentRow()] str(
[self.combobox_frequency_information.currentIndex()], 3)) + " cm") 100 * round(stg.cell_size[file_id][freq_id], 3)
self.gridLayout_groupbox_info.addWidget(self.label_cell_size_value, 11, 1, 1, 1, Qt.AlignLeft) ) + " cm"
)
self.gridLayout_groupbox_info.addWidget(
self.label_cell_size_value,
11, 1, 1, 1, Qt.AlignLeft
)
self.label_pulse_length_value.clear() self.label_pulse_length_value.clear()
self.label_pulse_length_value.setText( self.label_pulse_length_value.setText(
str(round(stg.pulse_length[self.fileListWidget.currentRow()] str(
[self.combobox_frequency_information.currentIndex()], 6)) + " sec") round(stg.pulse_length[file_id][freq_id], 6)
self.gridLayout_groupbox_info.addWidget(self.label_pulse_length_value, 12, 1, 1, 1, Qt.AlignLeft) ) + " sec"
)
self.gridLayout_groupbox_info.addWidget(
self.label_pulse_length_value,
12, 1, 1, 1, Qt.AlignLeft
)
self.label_pings_per_sec_value.clear() self.label_pings_per_sec_value.clear()
self.label_pings_per_sec_value.setText(str(stg.nb_pings_per_sec[self.fileListWidget.currentRow()] self.label_pings_per_sec_value.setText(
[self.combobox_frequency_information.currentIndex()]) + " Hz") str(
self.gridLayout_groupbox_info.addWidget(self.label_pings_per_sec_value, 13, 1, 1, 1, Qt.AlignLeft) stg.nb_pings_per_sec[file_id][freq_id]
) + " Hz"
)
self.gridLayout_groupbox_info.addWidget(
self.label_pings_per_sec_value,
13, 1, 1, 1, Qt.AlignLeft
)
self.label_pings_per_profile_value.clear() self.label_pings_per_profile_value.clear()
self.label_pings_per_profile_value.setText( self.label_pings_per_profile_value.setText(
str(stg.nb_pings_averaged_per_profile[self.fileListWidget.currentRow()] str(stg.nb_pings_averaged_per_profile[file_id][freq_id])
[self.combobox_frequency_information.currentIndex()])) )
self.gridLayout_groupbox_info.addWidget(self.label_pings_per_profile_value, 14, 1, 1, 1, Qt.AlignLeft) self.gridLayout_groupbox_info.addWidget(
self.label_pings_per_profile_value,
14, 1, 1, 1, Qt.AlignLeft
)
if self.checkbox_kt.isChecked(): if self.checkbox_kt.isChecked():
if self.combobox_frequency_information.count() > 0: if self.combobox_frequency_information.count() > 0:
self.lineEdit_kt.setText(str("%.4f" % stg.kt_corrected[self.combobox_frequency_information.currentIndex()])) self.lineEdit_kt.setText(
str("%.4f" % stg.kt_corrected[freq_id])
)
else: else:
self.lineEdit_kt.setText(str("%.4f" % stg.kt_read[self.combobox_frequency_information.currentIndex()])) self.lineEdit_kt.setText(str("%.4f" % stg.kt_read[freq_id]))
self.lineEdit_rx.setText(str(stg.gain_rx[self.fileListWidget.currentRow()][ self.lineEdit_rx.setText(
self.combobox_frequency_information.currentIndex()])) str(stg.gain_rx[file_id][freq_id])
)
self.lineEdit_tx.setText(str(stg.gain_tx[self.fileListWidget.currentRow()][ self.lineEdit_tx.setText(str(stg.gain_tx[file_id][freq_id]))
self.combobox_frequency_information.currentIndex()]))
def activate_unactivate_spinbox_kt(self): def activate_unactivate_spinbox_kt(self):
freq_id = self.combobox_frequency_information.currentIndex()
if self.checkbox_kt.isChecked(): if self.checkbox_kt.isChecked():
self.lineEdit_kt.setEnabled(True) self.lineEdit_kt.setEnabled(True)
if stg.kt_corrected: if stg.kt_corrected:
self.lineEdit_kt.setText(str("%.4f" % stg.kt_corrected[self.combobox_frequency_information.currentIndex()])) self.lineEdit_kt.setText(str("%.4f" % stg.kt_corrected[freq_id]))
else: else:
self.lineEdit_kt.setDisabled(True) self.lineEdit_kt.setDisabled(True)
if stg.kt_read: if stg.kt_read:
self.lineEdit_kt.setText(str("%.4f" % stg.kt_read[self.combobox_frequency_information.currentIndex()])) self.lineEdit_kt.setText(str("%.4f" % stg.kt_read[freq_id]))
def activate_unactivate_spinbox_rx(self): def activate_unactivate_spinbox_rx(self):
if self.checkbox_rx.isChecked(): if self.checkbox_rx.isChecked():
@ -1808,33 +1972,48 @@ class AcousticDataTab(QWidget):
self.lineEdit_tx.setDisabled(True) self.lineEdit_tx.setDisabled(True)
def kt_value(self): def kt_value(self):
if self.fileListWidget.count() <= 0:
return
if self.fileListWidget.count() > 0: if not self.checkbox_kt.isChecked():
if self.checkbox_kt.isChecked(): return
freq_id = self.combobox_frequency_information.currentIndex()
if findall(r",", self.lineEdit_kt.text()): if findall(r",", self.lineEdit_kt.text()):
stg.kt_corrected[self.combobox_frequency_information.currentIndex()] = ( stg.kt_corrected[freq_id] = (
float(self.lineEdit_kt.text().replace(',', '.'))) float(self.lineEdit_kt.text().replace(',', '.'))
self.lineEdit_kt.setText("%.4f" % float(self.lineEdit_kt.text().replace(',', '.'))) )
self.lineEdit_kt.setText(
"%.4f" % float(
self.lineEdit_kt.text().replace(',', '.')
)
)
else: else:
stg.kt_corrected[self.combobox_frequency_information.currentIndex()] = ( stg.kt_corrected[freq_id] = (
float(self.lineEdit_kt.text())) float(self.lineEdit_kt.text())
)
self.lineEdit_kt.setText("%.4f" % float(self.lineEdit_kt.text())) self.lineEdit_kt.setText("%.4f" % float(self.lineEdit_kt.text()))
def gain_rx_value(self): def gain_rx_value(self):
if self.fileListWidget.count() > 0: freq_id = self.combobox_frequency_information.currentIndex()
stg.gain_rx[self.fileListWidget.currentRow()][self.combobox_frequency_information.currentIndex()] = (
float(self.lineEdit_rx.text()))
if self.fileListWidget.count() > 0:
stg.gain_rx[self.fileListWidget.currentRow()][freq_id] = (
float(self.lineEdit_rx.text())
)
def gain_tx_value(self): def gain_tx_value(self):
freq_id = self.combobox_frequency_information.currentIndex()
if self.fileListWidget.count() > 0: if self.fileListWidget.count() > 0:
stg.gain_tx[self.fileListWidget.currentRow()][self.combobox_frequency_information.currentIndex()] = ( stg.gain_tx[self.fileListWidget.currentRow()][freq_id] = (
float(self.lineEdit_tx.text())) float(self.lineEdit_tx.text())
)
def fill_table(self): def fill_table(self):
if self.fileListWidget.currentRow() != -1: if self.fileListWidget.currentRow() != -1:
file_id = self.fileListWidget.currentRow()
header_list = [] header_list = []
header_list.clear() header_list.clear()
@ -1845,19 +2024,37 @@ class AcousticDataTab(QWidget):
header_list.append("BS - " + freq_value) header_list.append("BS - " + freq_value)
if freq_ind == 0: if freq_ind == 0:
table_data = np.vstack((np.vstack((stg.time_reshape[self.fileListWidget.currentRow()][:, freq_ind], table_data = np.vstack(
stg.depth_reshape[self.fileListWidget.currentRow()][:, freq_ind])), (
stg.BS_raw_data_reshape[self.fileListWidget.currentRow()][:, freq_ind])) np.vstack(
(
stg.time_reshape[file_id][:, freq_ind],
stg.depth_reshape[file_id][:, freq_ind]
)
),
stg.BS_raw_data_reshape[file_id][:, freq_ind]
)
)
else: else:
table_data = np.vstack((table_data, table_data = np.vstack((
np.vstack((np.vstack((stg.time_reshape[self.fileListWidget.currentRow()][:, freq_ind], table_data,
stg.depth_reshape[self.fileListWidget.currentRow()][:, freq_ind])), np.vstack(
stg.BS_raw_data_reshape[self.fileListWidget.currentRow()][:, freq_ind])) (
np.vstack(
(
stg.time_reshape[file_id][:, freq_ind],
stg.depth_reshape[file_id][:, freq_ind]
)
),
stg.BS_raw_data_reshape[file_id][:, freq_ind]
)
)
)) ))
stg.DataFrame_acoustic = pd.DataFrame(None) stg.DataFrame_acoustic = pd.DataFrame(None)
stg.DataFrame_acoustic = pd.DataFrame(data=table_data.transpose(), columns=header_list) stg.DataFrame_acoustic = pd.DataFrame(
data=table_data.transpose(), columns=header_list
)
self.tableModel = TableModel(stg.DataFrame_acoustic) self.tableModel = TableModel(stg.DataFrame_acoustic)
self.tableView.setModel(self.tableModel) self.tableView.setModel(self.tableModel)
@ -1883,27 +2080,45 @@ class AcousticDataTab(QWidget):
''' tmin and tmax are filled with min and max of time when data are uploaded and ''' tmin and tmax are filled with min and max of time when data are uploaded and
double slider of time are updated with these values ''' double slider of time are updated with these values '''
if self.fileListWidget.currentRow() != -1: if self.fileListWidget.currentRow() == -1:
return
# --- tmim / tmax --- file_id = self.fileListWidget.currentRow()
tmin_indice = np.where(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmin(
stg.time[self.fileListWidget.currentRow()][0, :])) ==
np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmin(
stg.time[self.fileListWidget.currentRow()][0, :]))))[0][0]
tmin_value = np.round(np.nanmin(stg.time[self.fileListWidget.currentRow()][0, :]), 2)
stg.tmin[self.fileListWidget.currentRow()] = (tmin_indice, tmin_value)
tmax_indice = np.where(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmax( tmin_indice = np.where(
stg.time[self.fileListWidget.currentRow()][0, :])) == np.abs(
np.nanmin(np.abs(stg.time[self.fileListWidget.currentRow()][0, :] - np.nanmax( stg.time[file_id][0, :] - np.nanmin(stg.time[file_id][0, :])
stg.time[self.fileListWidget.currentRow()][0, :]))))[0][0] ) == np.nanmin(
tmax_value = np.round(np.nanmax(stg.time[self.fileListWidget.currentRow()][0, :]), 2) np.abs(
stg.tmax[self.fileListWidget.currentRow()] = (tmax_indice + 1, tmax_value) stg.time[file_id][0, :]
- np.nanmin(stg.time[file_id][0, :])
)
)
)[0][0]
tmin_value = np.round(
np.nanmin(stg.time[file_id][0, :]), 2
)
stg.tmin[file_id] = (tmin_indice, tmin_value)
tmax_indice = np.where(
np.abs(
stg.time[file_id][0, :] - np.nanmax(stg.time[file_id][0, :])
) == np.nanmin(
np.abs(
stg.time[file_id][0, :]
- np.nanmax(stg.time[file_id][0, :])
)
)
)[0][0]
tmax_value = np.round(np.nanmax(stg.time[file_id][0, :]), 2)
stg.tmax[file_id] = (tmax_indice + 1, tmax_value)
self.set_range_for_time_boundaries_option() self.set_range_for_time_boundaries_option()
def set_range_for_time_boundaries_option(self): def set_range_for_time_boundaries_option(self):
self.label_time_min.clear() self.label_time_min.clear()
self.label_time_min.setText("%.5s" % str(stg.time[self.fileListWidget.currentRow()][0, 0])) self.label_time_min.setText("%.5s" % str(stg.time[self.fileListWidget.currentRow()][0, 0]))
@ -2073,58 +2288,82 @@ class AcousticDataTab(QWidget):
"-" + str("%.5s" % stg.depth[self.fileListWidget.currentRow()][0, 0])) "-" + str("%.5s" % stg.depth[self.fileListWidget.currentRow()][0, 0]))
def plot_backscattered_acoustic_signal_recording(self): def plot_backscattered_acoustic_signal_recording(self):
if self.fileListWidget.count() <= 0:
return
if self.fileListWidget.count() > 0: layout = self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data
file_id = self.fileListWidget.currentRow()
freq_id = self.combobox_frequency_profile.currentIndex()
self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.toolbar_BS) layout.removeWidget(self.toolbar_BS)
self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.removeWidget(self.scroll_BS) layout.removeWidget(self.scroll_BS)
self.fig_BS, self.axis_BS = plt.subplots(nrows=stg.freq[self.fileListWidget.currentRow()].shape[0], ncols=1, self.fig_BS, self.axis_BS = plt.subplots(
sharex=False, sharey=False, layout="constrained") nrows=stg.freq[file_id].shape[0],
ncols=1, sharex=False, sharey=False,
layout="constrained"
)
self.canvas_BS = FigureCanvas(self.fig_BS) self.canvas_BS = FigureCanvas(self.fig_BS)
self.toolbar_BS = NavigationToolBar(self.canvas_BS, self) self.toolbar_BS = NavigationToolBar(self.canvas_BS, self)
self.scroll_BS.setWidget(self.canvas_BS) self.scroll_BS.setWidget(self.canvas_BS)
self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.toolbar_BS) layout.addWidget(self.toolbar_BS)
self.verticalLayout_groupbox_transect_2Dplot_raw_BS_data.addWidget(self.scroll_BS) layout.addWidget(self.scroll_BS)
for f, _ in enumerate(stg.freq[self.fileListWidget.currentRow()]): for f, _ in enumerate(stg.freq[file_id]):
val_min = np.nanmin(stg.BS_raw_data[file_id][f, :, :])
val_min = np.nanmin(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]) val_max = np.nanmax(stg.BS_raw_data[file_id][f, :, :])
val_max = np.nanmax(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :])
if val_min == 0: if val_min == 0:
val_min = 1e-5 val_min = 1e-5
if self.combobox_ABS_system_choice.currentIndex() == 1: if self.combobox_ABS_system_choice.currentIndex() == 1:
pcm = self.axis_BS[f].pcolormesh(
pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :], stg.time[file_id][f, :],
-stg.depth[self.fileListWidget.currentRow()][f, :], -stg.depth[file_id][f, :],
stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :], stg.BS_raw_data[file_id][f, :, :],
cmap='viridis', norm=LogNorm(vmin=val_min, vmax=val_max)) cmap='viridis',
norm=LogNorm(vmin=val_min, vmax=val_max)
)
elif self.combobox_ABS_system_choice.currentIndex() == 2: elif self.combobox_ABS_system_choice.currentIndex() == 2:
pcm = self.axis_BS[f].pcolormesh(stg.time[self.fileListWidget.currentRow()][f, :], pcm = self.axis_BS[f].pcolormesh(
-stg.depth[self.fileListWidget.currentRow()][f, :], stg.time[file_id][f, :],
np.log(stg.BS_raw_data[self.fileListWidget.currentRow()][f, :, :]), -stg.depth[file_id][f, :],
cmap='Blues') np.log(stg.BS_raw_data[file_id][f, :, :]),
cmap='Blues'
)
self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], self.axis_BS[f].text(
fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, 1, .70, stg.freq_text[file_id][f],
fontsize=14, fontweight='bold', fontname="DejaVu Sans",
c="black", alpha=0.5,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_BS[f].transAxes) transform=self.axis_BS[f].transAxes
)
# --- Plot red solid line on transect to visualize position of plotted profile --- # --- Plot red solid line on transect to visualize position of
self.axis_BS[self.combobox_frequency_profile.currentIndex()].plot( # --- plotted profile ---
stg.time[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), self.axis_BS[freq_id].plot(
self.slider.value() - 1] * np.ones(stg.depth[self.fileListWidget.currentRow()].shape[1]), stg.time[file_id][
-stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :], freq_id, self.slider.value() - 1
color='red', linestyle="solid", linewidth=2) ]
* np.ones(stg.depth[file_id].shape[1]),
-stg.depth[file_id][freq_id, :],
color='red', linestyle="solid", linewidth=2
)
self.fig_BS.supxlabel('Time (sec)', fontsize=10) self.fig_BS.supxlabel('Time (sec)', fontsize=10)
self.fig_BS.supylabel('Depth (m)', fontsize=10) self.fig_BS.supylabel('Depth (m)', fontsize=10)
cbar = self.fig_BS.colorbar(pcm, ax=self.axis_BS[:], shrink=1, location='right')
cbar.set_label(label='Acoustic backscatter signal (V)', rotation=270, labelpad=10) cbar = self.fig_BS.colorbar(
pcm, ax=self.axis_BS[:],
shrink=1, location='right'
)
cbar.set_label(
label='Acoustic backscatter signal (V)',
rotation=270, labelpad=10
)
self.fig_BS.canvas.draw_idle() self.fig_BS.canvas.draw_idle()
def update_plot_backscattered_acoustic_signal_recording(self): def update_plot_backscattered_acoustic_signal_recording(self):
@ -2241,7 +2480,7 @@ class AcousticDataTab(QWidget):
color='black', linewidth=1, linestyle="solid") color='black', linewidth=1, linestyle="solid")
self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f],
fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, fontsize=14, fontweight='bold', fontname="DejaVu Sans", c="black", alpha=0.5,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_BS[f].transAxes) transform=self.axis_BS[f].transAxes)
@ -2256,7 +2495,8 @@ class AcousticDataTab(QWidget):
self.combobox_frequency_profile.currentIndexChanged.connect(self.update_plot_profile) self.combobox_frequency_profile.currentIndexChanged.connect(self.update_plot_profile)
self.combobox_frequency_profile.currentIndexChanged.connect( self.combobox_frequency_profile.currentIndexChanged.connect(
self.update_plot_backscattered_acoustic_signal_recording) self.update_plot_backscattered_acoustic_signal_recording
)
self.slider.setMaximum(stg.time[self.fileListWidget.currentRow()].shape[1]) self.slider.setMaximum(stg.time[self.fileListWidget.currentRow()].shape[1])
@ -2282,7 +2522,7 @@ class AcousticDataTab(QWidget):
-stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :], -stg.depth[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex(), :],
linestyle='solid', color='k', linewidth=1) linestyle='solid', color='k', linewidth=1)
self.axis_profile.text(.95, .05, stg.freq_text[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()], self.axis_profile.text(.95, .05, stg.freq_text[self.fileListWidget.currentRow()][self.combobox_frequency_profile.currentIndex()],
fontsize=10, fontweight='bold', fontname="Ubuntu", fontsize=10, fontweight='bold', fontname="DejaVu Sans",
fontstyle="normal", c="black", alpha=0.2, fontstyle="normal", c="black", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_profile.transAxes) transform=self.axis_profile.transAxes)
@ -2341,7 +2581,7 @@ class AcousticDataTab(QWidget):
# --- Write frequency on graph --- # --- Write frequency on graph ---
self.axis_profile.text(.95, .90, stg.freq_text[self.fileListWidget.currentRow()][ self.axis_profile.text(.95, .90, stg.freq_text[self.fileListWidget.currentRow()][
self.combobox_frequency_profile.currentIndex()], self.combobox_frequency_profile.currentIndex()],
fontsize=14, fontweight='bold', fontname="Ubuntu", fontsize=14, fontweight='bold', fontname="DejaVu Sans",
fontstyle="normal", c="black", alpha=0.2, fontstyle="normal", c="black", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_profile.transAxes) transform=self.axis_profile.transAxes)
@ -2365,7 +2605,7 @@ class AcousticDataTab(QWidget):
self.combobox_frequency_profile.currentIndex(), :])) self.combobox_frequency_profile.currentIndex(), :]))
self.axis_profile.text(.95, 1 - position_x + 0.05, "River bed", self.axis_profile.text(.95, 1 - position_x + 0.05, "River bed",
fontsize=10, fontweight='normal', fontname="Ubuntu", fontsize=10, fontweight='normal', fontname="DejaVu Sans",
fontstyle="italic", c="red", alpha=0.2, fontstyle="italic", c="red", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_profile.transAxes) transform=self.axis_profile.transAxes)
@ -2390,7 +2630,7 @@ class AcousticDataTab(QWidget):
# --- Write frequency on graph --- # --- Write frequency on graph ---
self.axis_profile.text(.95, .05, stg.freq_text[self.fileListWidget.currentRow()][ self.axis_profile.text(.95, .05, stg.freq_text[self.fileListWidget.currentRow()][
self.combobox_frequency_profile.currentIndex()], self.combobox_frequency_profile.currentIndex()],
fontsize=10, fontweight='bold', fontname="Ubuntu", fontsize=10, fontweight='bold', fontname="DejaVu Sans",
fontstyle="normal", c="black", alpha=0.2, fontstyle="normal", c="black", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_profile.transAxes) transform=self.axis_profile.transAxes)
@ -2414,7 +2654,7 @@ class AcousticDataTab(QWidget):
self.combobox_frequency_profile.currentIndex(), :])) self.combobox_frequency_profile.currentIndex(), :]))
self.axis_profile.text(.95, 1 - position_x + 0.05, "River bed", self.axis_profile.text(.95, 1 - position_x + 0.05, "River bed",
fontsize=10, fontweight='normal', fontname="Ubuntu", fontsize=10, fontweight='normal', fontname="DejaVu Sans",
fontstyle="italic", c="red", alpha=0.2, fontstyle="italic", c="red", alpha=0.2,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_profile.transAxes) transform=self.axis_profile.transAxes)
@ -2598,7 +2838,7 @@ class AcousticDataTab(QWidget):
color='black', linewidth=1, linestyle="solid") color='black', linewidth=1, linestyle="solid")
self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f],
fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", alpha=0.5, fontsize=14, fontweight='bold', fontname="DejaVu Sans", c="black", alpha=0.5,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_BS[f].transAxes) transform=self.axis_BS[f].transAxes)
@ -2726,7 +2966,7 @@ class AcousticDataTab(QWidget):
color='black', linewidth=1, linestyle="solid") color='black', linewidth=1, linestyle="solid")
self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f], self.axis_BS[f].text(1, .70, stg.freq_text[self.fileListWidget.currentRow()][f],
fontsize=14, fontweight='bold', fontname="Ubuntu", c="black", fontsize=14, fontweight='bold', fontname="DejaVu Sans", c="black",
alpha=0.5, alpha=0.5,
horizontalalignment='right', verticalalignment='bottom', horizontalalignment='right', verticalalignment='bottom',
transform=self.axis_BS[f].transAxes) transform=self.axis_BS[f].transAxes)

View File

@ -147,12 +147,14 @@ class Ui_MainWindow(object):
icon6.addPixmap(QtGui.QPixmap("icons/en.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) icon6.addPixmap(QtGui.QPixmap("icons/en.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionEnglish.setIcon(icon6) self.actionEnglish.setIcon(icon6)
self.actionEnglish.setObjectName("actionEnglish") self.actionEnglish.setObjectName("actionEnglish")
self.actionEnglish.setEnabled(False)
self.actionFrench = QtWidgets.QAction(self.mainwindow) self.actionFrench = QtWidgets.QAction(self.mainwindow)
icon7 = QtGui.QIcon() icon7 = QtGui.QIcon()
icon7.addPixmap(QtGui.QPixmap("icons/fr.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) icon7.addPixmap(QtGui.QPixmap("icons/fr.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionFrench.setIcon(icon7) self.actionFrench.setIcon(icon7)
self.actionFrench.setObjectName("actionFrench") self.actionFrench.setObjectName("actionFrench")
self.actionFrench.setEnabled(False)
self.action_ABSCalibrationConstant = QtWidgets.QAction(self.mainwindow) self.action_ABSCalibrationConstant = QtWidgets.QAction(self.mainwindow)
self.action_ABSCalibrationConstant.setText("ABS constant calibration kt") self.action_ABSCalibrationConstant.setText("ABS constant calibration kt")
@ -268,7 +270,10 @@ class Ui_MainWindow(object):
) )
def save(self): def save(self):
if stg.dirname_save_as:
UpdateTableForSave() UpdateTableForSave()
else:
self.save_as()
def open(self): def open(self):
reader = ReadTableForOpen() reader = ReadTableForOpen()

View File

@ -87,11 +87,13 @@ class SedimentCalibrationTab(QWidget):
# 1O units is 100% , 1 units is 10% # 1O units is 100% , 1 units is 10%
self.horizontalLayoutTop = QHBoxLayout() self.horizontalLayoutTop = QHBoxLayout()
self.verticalLayoutMain.addLayout(self.horizontalLayoutTop, 5) self.verticalLayoutMain.addLayout(self.horizontalLayoutTop, 5) # 1O units is 100% , 1 units is 10%
self.horizontalLayoutBottom = QHBoxLayout() self.horizontalLayoutBottom = QHBoxLayout()
self.verticalLayoutMain.addLayout(self.horizontalLayoutBottom, 5) self.verticalLayoutMain.addLayout(self.horizontalLayoutBottom, 5)
# --------------------------------------------------------------------------------------------------------------
self.groupbox_acoustic_data = QGroupBox() self.groupbox_acoustic_data = QGroupBox()
self.horizontalLayoutTop.addWidget(self.groupbox_acoustic_data, 6) self.horizontalLayoutTop.addWidget(self.groupbox_acoustic_data, 6)
@ -118,6 +120,7 @@ class SedimentCalibrationTab(QWidget):
self.groupbox_data_plot = QGroupBox() self.groupbox_data_plot = QGroupBox()
self.horizontalLayout_groupbox_acoustic_data.addWidget(self.groupbox_data_plot, 7) self.horizontalLayout_groupbox_acoustic_data.addWidget(self.groupbox_data_plot, 7)
# --- Groupbox data choice ---
self.verticalLayout_groupbox_data_choice = QVBoxLayout(self.groupbox_data_choice) self.verticalLayout_groupbox_data_choice = QVBoxLayout(self.groupbox_data_choice)
self._setup_widgets_acoustic_data_1() self._setup_widgets_acoustic_data_1()
@ -347,6 +350,9 @@ class SedimentCalibrationTab(QWidget):
self.groupbox_FCB = QGroupBox() self.groupbox_FCB = QGroupBox()
self.horizontalLayoutBottom.addWidget(self.groupbox_FCB, 6) self.horizontalLayoutBottom.addWidget(self.groupbox_FCB, 6)
# +++++++++++++++++++++++++++++++++++++
# +++ Groupbox sediment calibration +++
self.groupbox_sediment_calibration.setTitle("Step 3 : Compute Calibration") self.groupbox_sediment_calibration.setTitle("Step 3 : Compute Calibration")
self.verticalLayout_groupbox_sediment_calibration = QVBoxLayout(self.groupbox_sediment_calibration) self.verticalLayout_groupbox_sediment_calibration = QVBoxLayout(self.groupbox_sediment_calibration)
@ -1600,7 +1606,7 @@ class SedimentCalibrationTab(QWidget):
for k in stg.fine_sample_profile for k in stg.fine_sample_profile
] ]
r_bottom = stg.depth_bottom[data_choice][ r_bottom = [stg.depth_bottom[data_choice][
np.where( np.where(
np.abs( np.abs(
time_data[data_choice][ time_data[data_choice][
@ -1615,7 +1621,7 @@ class SedimentCalibrationTab(QWidget):
- stg.time_fine[stg.fine_sample_profile[-1][1]]) - stg.time_fine[stg.fine_sample_profile[-1][1]])
) )
)[0][0] )[0][0]
] ] if len(stg.depth_bottom[data_choice])!=0 else np.array([])][0]
logger.debug( logger.debug(
"call 'inv_hc.M_profile_SCC_fine_interpolated' params:" "call 'inv_hc.M_profile_SCC_fine_interpolated' params:"
@ -1710,14 +1716,18 @@ class SedimentCalibrationTab(QWidget):
self.animaiton_groupbox_compute.start() self.animaiton_groupbox_compute.start()
def import_calibration_file(self): def import_calibration_file(self):
filename = QFileDialog.getOpenFileName( filename = QFileDialog.getOpenFileName(
self, "Open calibration", self, "Open calibration",
[stg.path_calibration_file if stg.path_calibration_file else [
stg.path_BS_raw_data[ stg.path_calibration_file
-1] if self.combobox_acoustic_data_choice.count() > 0 else ""][0], 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)", "Calibration file (*.xls, *.ods, *csv)",
options=QFileDialog.DontUseNativeDialog) options=QFileDialog.DontUseNativeDialog
)
dir_name = os.path.dirname(filename[0]) dir_name = os.path.dirname(filename[0])
name = os.path.basename(filename[0]) name = os.path.basename(filename[0])
@ -1730,114 +1740,189 @@ class SedimentCalibrationTab(QWidget):
self.lineEdit_import_calibration.setToolTip(dir_name) self.lineEdit_import_calibration.setToolTip(dir_name)
self.compute_depth_2D()
self.read_calibration_file_and_fill_parameter() self.read_calibration_file_and_fill_parameter()
def update_label_freq1_for_calibration(self): def update_label_freq1_for_calibration(self):
self.label_freq1.clear() self.label_freq1.clear()
self.label_freq1.setText(str(self.combobox_freq1.currentText())) self.label_freq1.setText(
str(self.combobox_freq1.currentText())
)
def update_label_freq2_for_calibration(self): def update_label_freq2_for_calibration(self):
self.label_freq2.clear() self.label_freq2.clear()
self.label_freq2.setText(self.combobox_freq2.currentText()) self.label_freq2.setText(
self.combobox_freq2.currentText()
)
def update_label_kt_value_for_calibration(self): def update_label_kt_value_for_calibration(self):
print("self.combobox_freq1.currentIndex() ",
self.combobox_freq1.currentIndex(),
self.combobox_freq1.currentText())
freq_1 = self.combobox_freq1.currentIndex()
freq_2 = self.combobox_freq2.currentIndex()
self.label_kt_freq1.clear() self.label_kt_freq1.clear()
print("self.combobox_freq1.currentIndex() ", self.combobox_freq1.currentIndex(), self.combobox_freq1.currentText()) if stg.kt_corrected[freq_1] != stg.kt_read[freq_1]:
if stg.kt_corrected[self.combobox_freq1.currentIndex()] != stg.kt_read[self.combobox_freq1.currentIndex()]: self.label_kt_freq1.setText(
self.label_kt_freq1.setText(str('%.4f' % stg.kt_corrected[self.combobox_freq1.currentIndex()])) str('%.4f' % stg.kt_corrected[freq_1])
)
else: else:
self.label_kt_freq1.setText(str('%.4f' % stg.kt_read[self.combobox_freq1.currentIndex()])) self.label_kt_freq1.setText(
str('%.4f' % stg.kt_read[freq_1])
)
self.label_kt_freq2.clear() self.label_kt_freq2.clear()
if stg.kt_corrected[self.combobox_freq2.currentIndex()] != stg.kt_read[self.combobox_freq2.currentIndex()]: if stg.kt_corrected[freq_2] != stg.kt_read[freq_2]:
self.label_kt_freq2.setText(str('%.4f' % stg.kt_corrected[self.combobox_freq2.currentIndex()])) self.label_kt_freq2.setText(
str('%.4f' % stg.kt_corrected[freq_2])
)
else: else:
self.label_kt_freq2.setText(str('%.4f' % stg.kt_read[self.combobox_freq2.currentIndex()])) self.label_kt_freq2.setText(
str('%.4f' % stg.kt_read[freq_2])
)
def read_calibration_file_and_fill_parameter(self): def read_calibration_file_and_fill_parameter(self):
if self.combobox_acoustic_data_choice.count() == 0: if self.combobox_acoustic_data_choice.count() == 0:
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.setWindowTitle("Calibration import error") msgBox.setWindowTitle("Calibration import error")
msgBox.setIconPixmap( msgBox.setIconPixmap(
QPixmap(self._path_icon("no_approved.png")).scaledToHeight(32, Qt.SmoothTransformation)) QPixmap(
self._path_icon("no_approved.png")
).scaledToHeight(32, Qt.SmoothTransformation)
)
msgBox.setText("Update data before importing calibration") msgBox.setText("Update data before importing calibration")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
else: else:
# --- Read calibration file --- # --- Read calibration file ---
data = pd.read_csv(stg.path_calibration_file + "/" + stg.filename_calibration_file, header=0, index_col=0) data = pd.read_csv(
os.path.join(
stg.path_calibration_file,
stg.filename_calibration_file
),
header=0, index_col=0
)
# --- Fill spinboxes of calibration parameter --- # --- Fill spinboxes of calibration parameter ---
self.label_temperature.clear() self.label_temperature.clear()
self.label_temperature.setText("T = " + str(stg.temperature) + " °C") self.label_temperature.setText(
"T = " + str(stg.temperature) + " °C"
)
self.label_freq1.clear() self.label_freq1.clear()
self.label_freq1.setText(data.columns[0]) self.label_freq1.setText(data.columns[0])
index_freq1 = np.where(np.asarray(stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()]) == data_id = self.combobox_acoustic_data_choice.currentIndex()
data.columns[0])[0][0]
index_freq1 = np.where(
np.asarray(
stg.freq_text[data_id]
) == data.columns[0]
)[0][0]
stg.frequencies_for_calibration.clear() stg.frequencies_for_calibration.clear()
stg.frequencies_for_calibration.append((stg.freq[self.combobox_acoustic_data_choice.currentIndex()][ stg.frequencies_for_calibration.append(
index_freq1], (
index_freq1)) stg.freq[data_id][index_freq1],
index_freq1
)
)
self.label_freq2.clear() self.label_freq2.clear()
self.label_freq2.setText(data.columns[1]) self.label_freq2.setText(data.columns[1])
index_freq2 = np.where(np.asarray(stg.freq_text[self.combobox_acoustic_data_choice.currentIndex()]) == index_freq2 = np.where(
data.columns[1])[0][0] np.asarray(
stg.frequencies_for_calibration.append((stg.freq[self.combobox_acoustic_data_choice.currentIndex()][ stg.freq_text[data_id]
index_freq2], ) == data.columns[1]
index_freq2)) )[0][0]
stg.frequencies_for_calibration.append(
(
stg.freq[data_id][index_freq2],
index_freq2
)
)
stg.frequency_for_inversion = tuple() stg.frequency_for_inversion = tuple()
stg.frequency_for_inversion = (stg.freq[self.combobox_acoustic_data_choice.currentIndex()][index_freq2], stg.frequency_for_inversion = (
index_freq2) stg.freq[data_id][index_freq2],
index_freq2
)
self.lineEdit_ks_freq1.clear() self.lineEdit_ks_freq1.clear()
self.lineEdit_ks_freq1.setText(str("%.5f" % float(data.iloc[0][0]))) self.lineEdit_ks_freq1.setText(
str("%.5f" % float(data.iloc[0][0]))
)
self.lineEdit_ks_freq2.clear() self.lineEdit_ks_freq2.clear()
self.lineEdit_ks_freq2.setText(str("%.5f" % float(data.iloc[0][1]))) self.lineEdit_ks_freq2.setText(
str("%.5f" % float(data.iloc[0][1]))
)
stg.ks.clear() stg.ks.clear()
stg.ks = [float(self.lineEdit_ks_freq1.text()), float(self.lineEdit_ks_freq2.text())] stg.ks = [
float(self.lineEdit_ks_freq1.text()),
float(self.lineEdit_ks_freq2.text())
]
self.lineEdit_sv_freq1.clear() self.lineEdit_sv_freq1.clear()
self.lineEdit_sv_freq1.setText(str("%.5f" % float(data.iloc[1][0]))) self.lineEdit_sv_freq1.setText(
str("%.5f" % float(data.iloc[1][0]))
)
self.lineEdit_sv_freq2.clear() self.lineEdit_sv_freq2.clear()
self.lineEdit_sv_freq2.setText(str("%.5f" % float(data.iloc[1][1]))) self.lineEdit_sv_freq2.setText(
str("%.5f" % float(data.iloc[1][1]))
)
stg.sv.clear() stg.sv.clear()
stg.sv = [float(self.lineEdit_sv_freq1.text()), float(self.lineEdit_sv_freq2.text())] stg.sv = [
float(self.lineEdit_sv_freq1.text()),
float(self.lineEdit_sv_freq2.text())
]
self.lineEdit_X.clear() self.lineEdit_X.clear()
self.lineEdit_X.setText(str("%.2f" % float(data.iloc[2][0]))) self.lineEdit_X.setText(
str("%.2f" % float(data.iloc[2][0]))
)
stg.X_exponent.clear() stg.X_exponent.clear()
stg.X_exponent.append(float(self.lineEdit_X.text())) stg.X_exponent.append(float(self.lineEdit_X.text()))
self.lineEdit_alphas_freq1.clear() self.lineEdit_alphas_freq1.clear()
self.lineEdit_alphas_freq1.setText(str("%.5f" % float(data.iloc[3][0]))) self.lineEdit_alphas_freq1.setText(
str("%.5f" % float(data.iloc[3][0]))
)
self.lineEdit_alphas_freq2.clear() self.lineEdit_alphas_freq2.clear()
self.lineEdit_alphas_freq2.setText(str("%.5f" % float(data.iloc[3][1]))) self.lineEdit_alphas_freq2.setText(
str("%.5f" % float(data.iloc[3][1]))
)
stg.alpha_s.clear() stg.alpha_s.clear()
stg.alpha_s = [float(self.lineEdit_alphas_freq1.text()), float(self.lineEdit_alphas_freq2.text())] stg.alpha_s = [
float(self.lineEdit_alphas_freq1.text()),
float(self.lineEdit_alphas_freq2.text())
]
self.lineEdit_zeta_freq1.clear() self.lineEdit_zeta_freq1.clear()
self.lineEdit_zeta_freq1.setText(str("%.5f" % float(data.iloc[4][0]))) self.lineEdit_zeta_freq1.setText(
str("%.5f" % float(data.iloc[4][0]))
)
self.lineEdit_zeta_freq2.clear() self.lineEdit_zeta_freq2.clear()
self.lineEdit_zeta_freq2.setText(str("%.5f" % float(data.iloc[4][1]))) self.lineEdit_zeta_freq2.setText(
str("%.5f" % float(data.iloc[4][1]))
)
stg.zeta.clear() stg.zeta.clear()
stg.zeta = [float(self.lineEdit_zeta_freq1.text()), float(self.lineEdit_zeta_freq2.text())] stg.zeta = [
float(self.lineEdit_zeta_freq1.text()),
float(self.lineEdit_zeta_freq2.text())
]
self.compute_kt2D_kt3D() self.compute_kt2D_kt3D()
self.compute_J_cross_section() self.compute_J_cross_section()
@ -1911,9 +1996,6 @@ class SedimentCalibrationTab(QWidget):
axis=1)) axis=1))
def function_pushbutton_compute_calibration(self): 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.clear()
self.label_temperature.setText("T = " + str(stg.temperature) + " °C") self.label_temperature.setText("T = " + str(stg.temperature) + " °C")
@ -1928,6 +2010,8 @@ class SedimentCalibrationTab(QWidget):
self.compute_zeta() self.compute_zeta()
def compute_ks(self): def compute_ks(self):
data_id = self.combobox_acoustic_data_choice.currentIndex()
psd_number_of_particles = ( psd_number_of_particles = (
self.inv_hc.compute_particle_size_distribution_in_number_of_particles( self.inv_hc.compute_particle_size_distribution_in_number_of_particles(
num_sample=stg.sand_sample_target[0][1], num_sample=stg.sand_sample_target[0][1],
@ -1938,17 +2022,13 @@ class SedimentCalibrationTab(QWidget):
ks_freq1 = self.inv_hc.ks( ks_freq1 = self.inv_hc.ks(
proba_num=psd_number_of_particles, proba_num=psd_number_of_particles,
freq=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][ freq=stg.freq[data_id][self.combobox_freq1.currentIndex()],
self.combobox_freq1.currentIndex()
],
C=stg.water_velocity C=stg.water_velocity
) )
ks_freq2 = self.inv_hc.ks( ks_freq2 = self.inv_hc.ks(
proba_num=psd_number_of_particles, proba_num=psd_number_of_particles,
freq=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][ freq=stg.freq[data_id][self.combobox_freq2.currentIndex()],
self.combobox_freq2.currentIndex()
],
C=stg.water_velocity C=stg.water_velocity
) )
@ -1956,12 +2036,12 @@ class SedimentCalibrationTab(QWidget):
logger.debug( logger.debug(
"ks for frequency of " "ks for frequency of "
+ f"{stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex()]} : " + f"{stg.freq[data_id][self.combobox_freq1.currentIndex()]} : "
+ f"{ks_freq1} m/kg^0.5 \n" + f"{ks_freq1} m/kg^0.5 \n"
) )
logger.debug( logger.debug(
"ks for frequency of " "ks for frequency of "
+ f"{stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()]} : " + + f"{stg.freq[data_id][self.combobox_freq2.currentIndex()]} : " +
f"{ks_freq2} m/kg^0.5" f"{ks_freq2} m/kg^0.5"
) )
@ -1972,13 +2052,21 @@ class SedimentCalibrationTab(QWidget):
self.lineEdit_ks_freq2.setText(str("%.5f" % ks_freq2)) self.lineEdit_ks_freq2.setText(str("%.5f" % ks_freq2))
def compute_sv(self): def compute_sv(self):
data_id = self.combobox_acoustic_data_choice.currentIndex()
sv_freq1 = self.inv_hc.sv(ks=stg.ks[0], M_sand=stg.Ctot_sand[stg.sand_sample_target[0][1]]) 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]]) 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] 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(
print(f"sv for frequency of {stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()]} : {sv_freq2:.8f} /m") f"sv for frequency of {stg.freq[data_id][self.combobox_freq1.currentIndex()]}"
+ f" : {sv_freq1:.8f} /m \n"
)
print(
f"sv for frequency of {stg.freq[data_id][self.combobox_freq2.currentIndex()]}"
+ f" : {sv_freq2:.8f} /m"
)
self.lineEdit_sv_freq1.clear() self.lineEdit_sv_freq1.clear()
self.lineEdit_sv_freq1.setText(str("%.5f" % sv_freq1)) self.lineEdit_sv_freq1.setText(str("%.5f" % sv_freq1))
@ -1987,9 +2075,13 @@ class SedimentCalibrationTab(QWidget):
self.lineEdit_sv_freq2.setText(str("%.5f" % sv_freq2)) self.lineEdit_sv_freq2.setText(str("%.5f" % sv_freq2))
def compute_X(self): def compute_X(self):
X_exponent = self.inv_hc.X_exponent(freq1=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq1.currentIndex()], data_id = self.combobox_acoustic_data_choice.currentIndex()
freq2=stg.freq[self.combobox_acoustic_data_choice.currentIndex()][self.combobox_freq2.currentIndex()],
sv_freq1=stg.sv[0], sv_freq2=stg.sv[1]) X_exponent = self.inv_hc.X_exponent(
freq1=stg.freq[data_id][self.combobox_freq1.currentIndex()],
freq2=stg.freq[data_id][self.combobox_freq2.currentIndex()],
sv_freq1=stg.sv[0], sv_freq2=stg.sv[1]
)
stg.X_exponent.clear() stg.X_exponent.clear()
stg.X_exponent.append(X_exponent) stg.X_exponent.append(X_exponent)
@ -2032,190 +2124,89 @@ class SedimentCalibrationTab(QWidget):
) )
def compute_J_cross_section(self): def compute_J_cross_section(self):
for i in range(self.combobox_acoustic_data_choice.count()): lst_bs_data = [
stg.BS_stream_bed_pre_process_average,
stg.BS_stream_bed_pre_process_SNR,
stg.BS_stream_bed,
stg.BS_cross_section_pre_process_average,
stg.BS_cross_section_pre_process_SNR,
stg.BS_cross_section,
stg.BS_raw_data_pre_process_average,
stg.BS_raw_data_pre_process_SNR,
stg.BS_raw_data
]
for i in range(self.combobox_acoustic_data_choice.count()):
J_cross_section_freq1 = np.array([]) J_cross_section_freq1 = np.array([])
J_cross_section_freq2 = np.array([]) J_cross_section_freq2 = np.array([])
# --- Compute J --- for data in lst_bs_data:
if stg.BS_stream_bed_pre_process_average[i].shape != (0,): if data[i].shape != (0,):
bs_data = data
break
print(f"{stg.depth_2D[i].shape}")
print(f"{stg.depth_2D[i]}")
J_cross_section_freq1 = self.inv_hc.j_cross_section( J_cross_section_freq1 = self.inv_hc.j_cross_section(
BS=stg.BS_stream_bed_pre_process_average[i][ BS = bs_data[i][
stg.frequencies_for_calibration[0][1], :, :], stg.frequencies_for_calibration[0][1], :, :
r2D=stg.depth_2D[i][stg.frequencies_for_calibration[0][1], ],
:, :], r2D = stg.depth_2D[i][
kt=stg.kt3D[i][stg.frequencies_for_calibration[0][1], :, :]) 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( J_cross_section_freq2 = self.inv_hc.j_cross_section(
BS=stg.BS_stream_bed_pre_process_average[i][ BS = bs_data[i][
stg.frequencies_for_calibration[1][1], :, :], stg.frequencies_for_calibration[1][1], :, :
r2D=stg.depth_2D[i][stg.frequencies_for_calibration[1][1], ],
:, :], r2D = stg.depth_2D[i][
kt=stg.kt3D[i][stg.frequencies_for_calibration[1][1], :, :]) stg.frequencies_for_calibration[1][1], :, :
],
elif stg.BS_stream_bed_pre_process_SNR[i].shape != (0,): kt = stg.kt3D[i][
stg.frequencies_for_calibration[1][1], :, :
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][0] = J_cross_section_freq1
stg.J_cross_section[i][1] = J_cross_section_freq2 stg.J_cross_section[i][1] = J_cross_section_freq2
def compute_alpha_s(self): def compute_alpha_s(self):
data_id = self.combobox_acoustic_data_choice.currentIndex()
freq_1 = self.combobox_freq1.currentIndex()
freq_2 = self.combobox_freq2.currentIndex()
# --- Compute alpha_s --- depth_data = stg.depth
if stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): if stg.depth_cross_section[data_id].shape != (0,):
depth_data = stg.depth_cross_section
alpha_s_freq1 = self.inv_hc.alpha_s( alpha_s_freq1 = self.inv_hc.alpha_s(
sv=stg.sv[0], sv=stg.sv[0],
j_cross_section=stg.J_cross_section[self.combobox_acoustic_data_choice.currentIndex()][0][ j_cross_section=stg.J_cross_section[data_id][0][
stg.sand_sample_target_indice[0][0], stg.sand_sample_target_indice[0][1]], stg.sand_sample_target_indice[0][0],
depth=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ stg.sand_sample_target_indice[0][1]
self.combobox_freq1.currentIndex(), stg.sand_sample_target_indice[0][0]], ],
alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][ depth=depth_data[data_id][
self.combobox_freq1.currentIndex()]) freq_1, stg.sand_sample_target_indice[0][0]
],
alpha_w=stg.water_attenuation[data_id][freq_1]
)
alpha_s_freq2 = self.inv_hc.alpha_s( alpha_s_freq2 = self.inv_hc.alpha_s(
sv=stg.sv[1], sv=stg.sv[1],
j_cross_section=stg.J_cross_section[self.combobox_acoustic_data_choice.currentIndex()][1][ j_cross_section=stg.J_cross_section[data_id][1][
stg.sand_sample_target_indice[1][0], stg.sand_sample_target_indice[1][1]], stg.sand_sample_target_indice[1][0],
depth=stg.depth_cross_section[self.combobox_acoustic_data_choice.currentIndex()][ stg.sand_sample_target_indice[1][1]
self.combobox_freq2.currentIndex(), stg.sand_sample_target_indice[1][0]], ],
alpha_w=stg.water_attenuation[self.combobox_acoustic_data_choice.currentIndex()][ depth=depth_data[data_id][
self.combobox_freq2.currentIndex()]) freq_2, stg.sand_sample_target_indice[1][0]
],
else: alpha_w=stg.water_attenuation[data_id][freq_2]
)
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] stg.alpha_s = [alpha_s_freq1, alpha_s_freq2]
@ -2229,19 +2220,25 @@ class SedimentCalibrationTab(QWidget):
self.lineEdit_alphas_freq2.setText(str("%.5f" % alpha_s_freq2)) self.lineEdit_alphas_freq2.setText(str("%.5f" % alpha_s_freq2))
if (alpha_s_freq1 < 0) or (alpha_s_freq2 < 0): if (alpha_s_freq1 < 0) or (alpha_s_freq2 < 0):
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.setWindowTitle("Alpha computation error") msgBox.setWindowTitle("Alpha computation error")
msgBox.setIconPixmap(QPixmap(self._path_icon("no_approved.png")).scaledToHeight(32, Qt.SmoothTransformation)) msgBox.setIconPixmap(
QPixmap(
self._path_icon("no_approved.png")
).scaledToHeight(32, Qt.SmoothTransformation)
)
msgBox.setText("Sediment sound attenuation is negative !") msgBox.setText("Sediment sound attenuation is negative !")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
else: else:
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.setWindowTitle("Alpha computation validation") msgBox.setWindowTitle("Alpha computation validation")
msgBox.setIconPixmap(QPixmap(self._path_icon("approved.png")).scaledToHeight(32, Qt.SmoothTransformation)) msgBox.setIconPixmap(
QPixmap(
self._path_icon("approved.png")
).scaledToHeight(32, Qt.SmoothTransformation)
)
msgBox.setText("Sediment sound attenuation is positive.") msgBox.setText("Sediment sound attenuation is positive.")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()

View File

@ -647,6 +647,9 @@ class SignalProcessingTab(QWidget):
stg.BS_mean[self.combobox_acoustic_data_choice.currentIndex()] = ( stg.BS_mean[self.combobox_acoustic_data_choice.currentIndex()] = (
np.nanmean(stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()][:, :, val1:val2], axis=2)) np.nanmean(stg.BS_raw_data[self.combobox_acoustic_data_choice.currentIndex()][:, :, val1:val2], axis=2))
if stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
self.compute_noise_from_profile_tail_value()
def plot_averaged_profile_tail(self): def plot_averaged_profile_tail(self):
# --- Plot averaged signal --- # --- Plot averaged signal ---
@ -932,7 +935,7 @@ class SignalProcessingTab(QWidget):
# --- Compute noise from value and compute SNR --- # --- Compute noise from value and compute SNR ---
if stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,): if stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape != (0,):
stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()] = np.array([])
stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()] = ( stg.BS_noise_raw_data[self.combobox_acoustic_data_choice.currentIndex()] = (
np.full(stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape, np.full(stg.BS_stream_bed[self.combobox_acoustic_data_choice.currentIndex()].shape,
float(self.lineEdit_profile_tail_value.text().replace(",", ".")))) float(self.lineEdit_profile_tail_value.text().replace(",", "."))))
@ -992,7 +995,7 @@ class SignalProcessingTab(QWidget):
self.plot_pre_processed_BS_signal() self.plot_pre_processed_BS_signal()
self.plot_pre_processed_profile() self.plot_pre_processed_profile()
self.activate_list_of_pre_processed_data() # self.activate_list_of_pre_processed_data()
def plot_noise(self): def plot_noise(self):
self.horizontalLayout_groupbox_plot_noise_data.removeWidget(self.canvas_noise) self.horizontalLayout_groupbox_plot_noise_data.removeWidget(self.canvas_noise)

View File

@ -33,7 +33,8 @@ logging.basicConfig(
) )
logger = logging.getLogger() logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # logger.setLevel(logging.DEBUG)
logger.setLevel(logging.INFO)
class MainApplication(QMainWindow): class MainApplication(QMainWindow):
@ -53,7 +54,6 @@ class MainApplication(QMainWindow):
# -------------- Acoustic data tab --------------- # -------------- Acoustic data tab ---------------
self.acoustic_data_tab = AcousticDataTab(self.ui_mainwindow.tab1) self.acoustic_data_tab = AcousticDataTab(self.ui_mainwindow.tab1)
print("0 AcousticDataTab ", id(AcousticDataTab))
self.acoustic_data_tab\ self.acoustic_data_tab\
.combobox_ABS_system_choice\ .combobox_ABS_system_choice\