Sample data: Refactoring some functions.

dev-brahim
Pierre-Antoine 2025-03-11 09:34:04 +01:00
parent f872b625c2
commit 2697acddfe
1 changed files with 172 additions and 89 deletions

View File

@ -20,12 +20,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel, QSpacerItem, QSizePolicy, import logging
QTableWidget, QPushButton, QLineEdit,
QTableWidgetItem, QComboBox, QFileDialog, QGridLayout, QMessageBox)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QCoreApplication, pyqtSignal
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@ -36,7 +32,13 @@ from matplotlib.colors import LogNorm, BASE_COLORS
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolBar
from os import path from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel,
QSpacerItem, QSizePolicy, QTableWidget, QPushButton, QLineEdit,
QTableWidgetItem, QComboBox, QFileDialog, QGridLayout, QMessageBox
)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QCoreApplication, pyqtSignal
from Model.granulo_loader import GranuloLoader from Model.granulo_loader import GranuloLoader
@ -48,6 +50,7 @@ import settings as stg
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
logger = logging.getLogger()
class SampleDataTab(QWidget): class SampleDataTab(QWidget):
@ -57,8 +60,7 @@ class SampleDataTab(QWidget):
def __init__(self, widget_tab): def __init__(self, widget_tab):
super().__init__() super().__init__()
path_icon = "./icons/" icon_folder = QIcon(os.path.join("icons", "folder.png"))
icon_folder = QIcon(path_icon + "folder.png")
### --- General layout of widgets --- ### --- General layout of widgets ---
@ -269,20 +271,36 @@ class SampleDataTab(QWidget):
self.groupbox_plot_PSD.setTitle(_translate("CONSTANT_STRING", cs.DISTRIBUTION_PLOT)) self.groupbox_plot_PSD.setTitle(_translate("CONSTANT_STRING", cs.DISTRIBUTION_PLOT))
# ------------------------------------------------------------------------------------------------------------------
# --- Function to select directory and file name of fine sediments sample data ---
def open_dialog_box_fine_sediment(self):
def last_opened_file_path(self, priority="sand"):
lst = []
if priority == "sand":
lst += [stg.path_sand]
lst += [stg.path_fine]
else:
lst += [stg.path_fine]
lst += [stg.path_sand]
lst += stg.path_BS_raw_data
for path in lst:
if path != "":
return path
return ""
def open_dialog_box_fine_sediment(self):
filename_fine_sediment = QFileDialog.getOpenFileName( filename_fine_sediment = QFileDialog.getOpenFileName(
self, "Fine sediment file", self, "Fine sediment file",
[stg.path_fine if stg.path_fine else stg.path_sand if stg.path_sand self.last_opened_file_path(priority="fine"),
else stg.path_BS_raw_data[-1] if self.combobox_acoustic_data.count() > 0 else ""][0],
"Fine sediment file (*.xlsx, *xls, *.ods)", "Fine sediment file (*.xlsx, *xls, *.ods)",
options=QFileDialog.DontUseNativeDialog) options=QFileDialog.DontUseNativeDialog
)
try: try:
stg.path_fine = path.dirname(filename_fine_sediment[0]) stg.path_fine = os.path.dirname(filename_fine_sediment[0])
stg.filename_fine = path.basename(filename_fine_sediment[0]) stg.filename_fine = os.path.basename(filename_fine_sediment[0])
self.load_fine_sediment_data() self.load_fine_sediment_data()
except IsADirectoryError: except IsADirectoryError:
msgBox = QMessageBox() msgBox = QMessageBox()
@ -291,25 +309,24 @@ class SampleDataTab(QWidget):
msgBox.setText("Please select a file") msgBox.setText("Please select a file")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
except Exception as e:
logger.error(e)
else: else:
self.lineEdit_fine_sediment.clear() self.lineEdit_fine_sediment.clear()
self.lineEdit_fine_sediment.setText(stg.filename_fine) self.lineEdit_fine_sediment.setText(stg.filename_fine)
self.lineEdit_fine_sediment.setToolTip(stg.path_fine) self.lineEdit_fine_sediment.setToolTip(stg.path_fine)
self.fill_table_fine() self.fill_table_fine()
# --- Function to select directory and file name of sand sediments sample data ---
def open_dialog_box_sand_sediment(self): def open_dialog_box_sand_sediment(self):
filename_sand_sediment = QFileDialog.getOpenFileName( filename_sand_sediment = QFileDialog.getOpenFileName(
self, "Sand sediment file", self, "Sand sediment file",
[stg.path_sand if stg.path_sand else stg.path_fine if stg.path_fine self.last_opened_file_path(priority="sand"),
else stg.path_BS_raw_data[-1] if self.combobox_acoustic_data.count() > 0 else ""][0],
"Sand sediment file (*.xlsx, *xls, *.ods)", "Sand sediment file (*.xlsx, *xls, *.ods)",
options=QFileDialog.DontUseNativeDialog) options=QFileDialog.DontUseNativeDialog)
try: try:
stg.path_sand = path.dirname(filename_sand_sediment[0]) stg.path_sand = os.path.dirname(filename_sand_sediment[0])
stg.filename_sand = path.basename(filename_sand_sediment[0]) stg.filename_sand = os.path.basename(filename_sand_sediment[0])
self.load_sand_sediment_data() self.load_sand_sediment_data()
except IsADirectoryError: except IsADirectoryError:
msgBox = QMessageBox() msgBox = QMessageBox()
@ -318,13 +335,17 @@ class SampleDataTab(QWidget):
msgBox.setText("Please select a file") msgBox.setText("Please select a file")
msgBox.setStandardButtons(QMessageBox.Ok) msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.exec() msgBox.exec()
except Exception as e:
logger.error(e)
else: else:
self.lineEdit_sand_sediment.setText(stg.filename_sand) self.lineEdit_sand_sediment.setText(stg.filename_sand)
self.lineEdit_sand_sediment.setToolTip(stg.path_sand) self.lineEdit_sand_sediment.setToolTip(stg.path_sand)
self.fill_table_sand() self.fill_table_sand()
def load_fine_sediment_data(self): def load_fine_sediment_data(self):
fine_granulo_data = GranuloLoader(stg.path_fine + "/" + stg.filename_fine) fine_granulo_data = GranuloLoader(
os.path.join(stg.path_fine, stg.filename_fine)
)
stg.columns_fine = fine_granulo_data._data.columns stg.columns_fine = fine_granulo_data._data.columns
stg.time_fine = fine_granulo_data._time stg.time_fine = fine_granulo_data._time
stg.distance_from_bank_fine = fine_granulo_data._y stg.distance_from_bank_fine = fine_granulo_data._y
@ -336,7 +357,9 @@ class SampleDataTab(QWidget):
stg.frac_vol_fine_cumul = fine_granulo_data._frac_vol_cumul stg.frac_vol_fine_cumul = fine_granulo_data._frac_vol_cumul
def load_sand_sediment_data(self): def load_sand_sediment_data(self):
sand_granulo_data = GranuloLoader(stg.path_sand + "/" + stg.filename_sand) sand_granulo_data = GranuloLoader(
os.path.join(stg.path_sand, stg.filename_sand)
)
stg.columns_sand = sand_granulo_data._data.columns stg.columns_sand = sand_granulo_data._data.columns
stg.time_sand = sand_granulo_data._time stg.time_sand = sand_granulo_data._time
stg.distance_from_bank_sand = sand_granulo_data._y stg.distance_from_bank_sand = sand_granulo_data._y
@ -360,35 +383,54 @@ class SampleDataTab(QWidget):
# --- Function to fill table of values --- # --- Function to fill table of values ---
def fill_table_fine(self): def fill_table_fine(self):
if self.lineEdit_fine_sediment.text(): if self.lineEdit_fine_sediment.text():
self.row_fine = self.tableWidget_fine.setRowCount(
self.row_fine = self.tableWidget_fine.setRowCount(len(stg.depth_fine)) len(stg.depth_fine)
self.column_fine = self.tableWidget_fine.setColumnCount(6 + stg.radius_grain_fine.shape[0]) )
self.column_fine = self.tableWidget_fine.setColumnCount(
6 + stg.radius_grain_fine.shape[0]
)
# --- Set horizontal header --- # --- Set horizontal header ---
horizontal_header = list(
horizontal_header = list(itertools.chain(["Color", "Sample"], itertools.chain(
["Color", "Sample"],
list(map(str, stg.columns_fine[[0, 2]])), list(map(str, stg.columns_fine[[0, 2]])),
list(map(str, stg.columns_fine[3:])))) list(map(str, stg.columns_fine[3:]))
)
)
for horizontal_header_text in horizontal_header: for horizontal_header_text in horizontal_header:
self.horizontal_header_item_fine = QTableWidgetItem() self.horizontal_header_item_fine = QTableWidgetItem()
self.tableWidget_fine.setHorizontalHeaderItem(horizontal_header.index(horizontal_header_text), self.tableWidget_fine.setHorizontalHeaderItem(
self.horizontal_header_item_fine) horizontal_header.index(horizontal_header_text),
self.horizontal_header_item_fine
)
self.horizontal_header_item_fine.setText(horizontal_header_text) self.horizontal_header_item_fine.setText(horizontal_header_text)
# --- Set vertical header (color) --- # --- Set vertical header (color) ---
self.tableWidget_fine.verticalHeader().setVisible(False) self.tableWidget_fine.verticalHeader().setVisible(False)
color_list = BASE_COLORS color_list = BASE_COLORS
self.comboBox_sample_table_fine = []
for i in range(self.tableWidget_fine.rowCount()): for i in range(self.tableWidget_fine.rowCount()):
exec("self.comboBox_sample_table_fine" + str(i) + "= QComboBox()") self.comboBox_sample_table_fine.append(
exec("self.comboBox_sample_table_fine" + str(i) + ".addItems(color_list)") QComboBox()
eval(f"self.tableWidget_fine.setCellWidget(i, 0, self.comboBox_sample_table_fine{i})") )
eval(f"self.comboBox_sample_table_fine{i}.currentTextChanged."
f"connect(self.plot_total_concentration)") self.comboBox_sample_table_fine[i].addItems(color_list)
eval(f"self.comboBox_sample_table_fine{i}.currentTextChanged." self.tableWidget_fine.setCellWidget(
f"connect(self.plot_PSD_fine_and_sand_sediments)") i, 0, self.comboBox_sample_table_fine[i]
eval(f"self.comboBox_sample_table_fine{i}.currentTextChanged." )
f"connect(self.update_plot_sample_position_on_transect)")
self.comboBox_sample_table_fine[i]\
.currentTextChanged\
.connect(self.plot_total_concentration)
self.comboBox_sample_table_fine[i]\
.currentTextChanged\
.connect(self.plot_PSD_fine_and_sand_sediments)
self.comboBox_sample_table_fine[i]\
.currentTextChanged\
.connect(self.update_plot_sample_position_on_transect)
# --- Fill Sample column with checkbox --- # --- Fill Sample column with checkbox ---
for i in range(self.tableWidget_fine.rowCount()): for i in range(self.tableWidget_fine.rowCount()):
@ -401,12 +443,21 @@ class SampleDataTab(QWidget):
# --- Fill table with data --- # --- Fill table with data ---
for i in range(stg.frac_vol_fine.shape[0]): for i in range(stg.frac_vol_fine.shape[0]):
for j in range(stg.frac_vol_fine.shape[1]): for j in range(stg.frac_vol_fine.shape[1]):
self.tableWidget_fine.setItem(i, 2, QTableWidgetItem(str(stg.time_fine[i]))) self.tableWidget_fine.setItem(
self.tableWidget_fine.setItem(i, 3, QTableWidgetItem(str(stg.depth_fine[i]))) i, 2, QTableWidgetItem(str(stg.time_fine[i]))
)
self.tableWidget_fine.setItem(i, 4, QTableWidgetItem(str(stg.Ctot_fine[i]))) self.tableWidget_fine.setItem(
self.tableWidget_fine.setItem(i, 5, QTableWidgetItem(str(stg.D50_fine[i]))) i, 3, QTableWidgetItem(str(stg.depth_fine[i]))
self.tableWidget_fine.setItem(i, j + 6, QTableWidgetItem(str(stg.frac_vol_fine[i, j]))) )
self.tableWidget_fine.setItem(
i, 4, QTableWidgetItem(str(stg.Ctot_fine[i]))
)
self.tableWidget_fine.setItem(
i, 5, QTableWidgetItem(str(stg.D50_fine[i]))
)
self.tableWidget_fine.setItem(
i, j + 6, QTableWidgetItem(str(stg.frac_vol_fine[i, j]))
)
# --- Connect checkbox to all checkboxes of tableWidget --- # --- Connect checkbox to all checkboxes of tableWidget ---
# self.allChkBox.stateChanged.connect(self.check_allChkBox) # self.allChkBox.stateChanged.connect(self.check_allChkBox)
@ -422,7 +473,6 @@ class SampleDataTab(QWidget):
self.plot_sample_position_on_transect() self.plot_sample_position_on_transect()
self.plot_total_concentration() self.plot_total_concentration()
self.plot_PSD_fine_and_sand_sediments() self.plot_PSD_fine_and_sand_sediments()
else: else:
msgBox = QMessageBox() msgBox = QMessageBox()
msgBox.setWindowTitle("Fill table Error") msgBox.setWindowTitle("Fill table Error")
@ -433,35 +483,47 @@ class SampleDataTab(QWidget):
def fill_table_sand(self): def fill_table_sand(self):
if self.lineEdit_sand_sediment.text(): if self.lineEdit_sand_sediment.text():
self.row_sand = self.tableWidget_sand.setRowCount(len(stg.depth_sand)) self.row_sand = self.tableWidget_sand.setRowCount(len(stg.depth_sand))
self.column_sand = self.tableWidget_sand.setColumnCount(6 + stg.radius_grain_sand.shape[0]) self.column_sand = self.tableWidget_sand.setColumnCount(6 + stg.radius_grain_sand.shape[0])
# --- Set horizontal header --- # --- Set horizontal header ---
horizontal_header = list(
horizontal_header = list(itertools.chain(["Color", "Sample"], itertools.chain(
["Color", "Sample"],
list(map(str, stg.columns_sand[[0, 2]])), list(map(str, stg.columns_sand[[0, 2]])),
list(map(str, stg.columns_sand[3:])))) list(map(str, stg.columns_sand[3:]))
)
)
for horizontal_header_text in horizontal_header: for horizontal_header_text in horizontal_header:
self.horizontal_header_item_sand = QTableWidgetItem() self.horizontal_header_item_sand = QTableWidgetItem()
self.tableWidget_sand.setHorizontalHeaderItem(horizontal_header.index(horizontal_header_text), self.tableWidget_sand.setHorizontalHeaderItem(
self.horizontal_header_item_sand) horizontal_header.index(horizontal_header_text),
self.horizontal_header_item_sand
)
self.horizontal_header_item_sand.setText(horizontal_header_text) self.horizontal_header_item_sand.setText(horizontal_header_text)
# --- Set vertical header (color) --- # --- Set vertical header (color) ---
self.tableWidget_sand.verticalHeader().setVisible(False) self.tableWidget_sand.verticalHeader().setVisible(False)
color_list = BASE_COLORS color_list = BASE_COLORS
self.comboBox_sample_table_sand = []
for i in range(self.tableWidget_sand.rowCount()): for i in range(self.tableWidget_sand.rowCount()):
exec("self.comboBox_sample_table_sand" + str(i) + "= QComboBox()") self.comboBox_sample_table_sand.append(QComboBox())
exec("self.comboBox_sample_table_sand" + str(i) + ".addItems(color_list)")
eval(f"self.tableWidget_sand.setCellWidget(i, 0, self.comboBox_sample_table_sand{i})") self.comboBox_sample_table_sand[i].addItems(color_list)
eval(f"self.comboBox_sample_table_sand{i}.currentTextChanged." self.tableWidget_sand.setCellWidget(
f"connect(self.plot_total_concentration)") i, 0, self.comboBox_sample_table_sand[i]
eval(f"self.comboBox_sample_table_sand{i}.currentTextChanged." )
f"connect(self.plot_PSD_fine_and_sand_sediments)")
eval(f"self.comboBox_sample_table_sand{i}.currentTextChanged." self.comboBox_sample_table_sand[i]\
f"connect(self.update_plot_sample_position_on_transect)") .currentTextChanged\
.connect(self.plot_total_concentration)
self.comboBox_sample_table_sand[i]\
.currentTextChanged\
.connect(self.plot_PSD_fine_and_sand_sediments)
self.comboBox_sample_table_sand[i]\
.currentTextChanged\
.connect(self.update_plot_sample_position_on_transect)
# --- Fill Sample column with checkbox --- # --- Fill Sample column with checkbox ---
for i in range(self.tableWidget_sand.rowCount()): for i in range(self.tableWidget_sand.rowCount()):
@ -474,20 +536,37 @@ class SampleDataTab(QWidget):
# --- Fill table with data --- # --- Fill table with data ---
for i in range(stg.frac_vol_sand.shape[0]): for i in range(stg.frac_vol_sand.shape[0]):
for j in range(stg.frac_vol_sand.shape[1]): for j in range(stg.frac_vol_sand.shape[1]):
self.tableWidget_sand.setItem(i, 2, QTableWidgetItem(str(stg.time_sand[i]))) self.tableWidget_sand.setItem(
self.tableWidget_sand.setItem(i, 3, QTableWidgetItem(str(stg.depth_sand[i]))) i, 2, QTableWidgetItem(str(stg.time_sand[i]))
)
self.tableWidget_sand.setItem(i, 4, QTableWidgetItem(str(stg.Ctot_sand[i]))) self.tableWidget_sand.setItem(
self.tableWidget_sand.setItem(i, 5, QTableWidgetItem(str(stg.D50_sand[i]))) i, 3, QTableWidgetItem(str(stg.depth_sand[i]))
self.tableWidget_sand.setItem(i, j + 6, QTableWidgetItem(str(stg.frac_vol_sand[i, j]))) )
self.tableWidget_sand.setItem(
i, 4, QTableWidgetItem(str(stg.Ctot_sand[i]))
)
self.tableWidget_sand.setItem(
i, 5, QTableWidgetItem(str(stg.D50_sand[i]))
)
self.tableWidget_sand.setItem(
i, j + 6, QTableWidgetItem(str(stg.frac_vol_sand[i, j]))
)
# --- Connect checkbox items of tableWidget to update plots --- # --- Connect checkbox items of tableWidget to update plots ---
self.tableWidget_sand.itemChanged.connect(self.update_plot_sample_position_on_transect) self.tableWidget_sand\
self.tableWidget_sand.itemChanged.connect(self.plot_total_concentration) .itemChanged\
self.tableWidget_sand.itemChanged.connect(self.plot_PSD_fine_and_sand_sediments) .connect(self.update_plot_sample_position_on_transect)
self.tableWidget_sand\
.itemChanged\
.connect(self.plot_total_concentration)
self.tableWidget_sand\
.itemChanged\
.connect(self.plot_PSD_fine_and_sand_sediments)
self.combobox_x_axis.currentIndexChanged.connect(self.plot_total_concentration) self.combobox_x_axis.currentIndexChanged\
self.combobox_y_axis.currentIndexChanged.connect(self.plot_total_concentration) .connect(self.plot_total_concentration)
self.combobox_y_axis.currentIndexChanged\
.connect(self.plot_total_concentration)
self.plot_sample_position_on_transect() self.plot_sample_position_on_transect()
self.plot_total_concentration() self.plot_total_concentration()
@ -502,7 +581,7 @@ class SampleDataTab(QWidget):
if self.tableWidget_fine.item(i, 1).checkState() == 2: if self.tableWidget_fine.item(i, 1).checkState() == 2:
if self.tableWidget_fine.item(i, 1).checkState() == Qt.Checked: if self.tableWidget_fine.item(i, 1).checkState() == Qt.Checked:
position.append(i) position.append(i)
eval(f"color_list.append(self.comboBox_sample_table_fine{i}.currentText())") color_list.append(self.comboBox_sample_table_fine[i].currentText())
sample_checkbox[0, i] = 2 sample_checkbox[0, i] = 2
return position, color_list return position, color_list
@ -570,7 +649,9 @@ class SampleDataTab(QWidget):
if self.tableWidget_sand.item(i, 1).checkState() == 2: if self.tableWidget_sand.item(i, 1).checkState() == 2:
if self.tableWidget_sand.item(i, 1).checkState() == Qt.Checked: if self.tableWidget_sand.item(i, 1).checkState() == Qt.Checked:
position.append(i) position.append(i)
eval(f"color_list.append(self.comboBox_sample_table_sand{i}.currentText())") color_list.append(
self.comboBox_sample_table_sand[i].currentText()
)
sample_checkbox[0, i] = 2 sample_checkbox[0, i] = 2
return position, color_list return position, color_list
@ -646,7 +727,6 @@ class SampleDataTab(QWidget):
self.combobox_acoustic_data.showPopup() self.combobox_acoustic_data.showPopup()
def fill_comboboxes_and_plot_transect(self): def fill_comboboxes_and_plot_transect(self):
self.combobox_acoustic_data.clear() self.combobox_acoustic_data.clear()
for n, m in enumerate(stg.noise_method): for n, m in enumerate(stg.noise_method):
if stg.noise_method[n] == 0: if stg.noise_method[n] == 0:
@ -659,19 +739,23 @@ class SampleDataTab(QWidget):
self.combobox_frequencies.currentIndexChanged.connect(self.update_plot_sample_position_on_transect) self.combobox_frequencies.currentIndexChanged.connect(self.update_plot_sample_position_on_transect)
def plot_sample_position_on_transect(self): def plot_sample_position_on_transect(self):
self.verticalLayout_groupbox_plot_transect\
.removeWidget(self.canvas_plot_sample_position_on_transect)
self.verticalLayout_groupbox_plot_transect.removeWidget(self.canvas_plot_sample_position_on_transect) fig, axis = plt.subplots(nrows=1, ncols=1, layout="constrained")
self.figure_plot_sample_position_on_transect, self.axis_plot_sample_position_on_transect = \ self.figure_plot_sample_position_on_transect = fig
plt.subplots(nrows=1, ncols=1, layout="constrained") self.axis_plot_sample_position_on_transect = axis
self.canvas_plot_sample_position_on_transect = FigureCanvas(self.figure_plot_sample_position_on_transect)
self.verticalLayout_groupbox_plot_transect.addWidget(self.canvas_plot_sample_position_on_transect) self.canvas_plot_sample_position_on_transect = FigureCanvas(
self.figure_plot_sample_position_on_transect
)
self.verticalLayout_groupbox_plot_transect\
.addWidget(self.canvas_plot_sample_position_on_transect)
if self.combobox_acoustic_data.count() == 0: if self.combobox_acoustic_data.count() == 0:
if self.tableWidget_fine.columnCount() > 10: if self.tableWidget_fine.columnCount() > 10:
position_list_fine, color_list_fine = self.extract_position_list_and_color_list_from_table_checkboxes_fine() position_list_fine, color_list_fine = self.extract_position_list_and_color_list_from_table_checkboxes_fine()
self.axis_plot_sample_position_on_transect.scatter( self.axis_plot_sample_position_on_transect.scatter(
@ -1696,4 +1780,3 @@ class SampleDataTab(QWidget):
self.axis_plot_PSD[1].set_ylabel('Cumulative size volume fraction') self.axis_plot_PSD[1].set_ylabel('Cumulative size volume fraction')
self.figure_plot_PSD.canvas.draw_idle() self.figure_plot_PSD.canvas.draw_idle()