feat(step9): 新增浓度反演模块及 GUI 面板
This commit is contained in:
@ -325,9 +325,11 @@ class WorkerThread(QThread):
|
||||
'step3': 'step3_remove_glint',
|
||||
'step4': 'step4_process_csv',
|
||||
'step5': 'step5_extract_training_spectra',
|
||||
'step8': 'step8_water_quality_indices',
|
||||
'step6': 'step6_water_quality_indices',
|
||||
'step7': 'step7_ml_modeling',
|
||||
'step8_non_empirical_modeling': 'step8_non_empirical_modeling',
|
||||
'step8_qaa': 'step8_qaa_inversion',
|
||||
'step9_concentration': 'step9_concentration_inversion',
|
||||
'step9': 'step9_custom_regression',
|
||||
'step10': 'step10_sampling',
|
||||
'step11_ml': 'step11_ml_prediction',
|
||||
@ -342,6 +344,19 @@ class WorkerThread(QThread):
|
||||
method_name = step_method_map[step_name]
|
||||
step_config = dict(config.get(step_name, {}))
|
||||
|
||||
# step8_qaa_inversion 内部使用 config.get('step8_qaa', {}) 读取内层,
|
||||
# 必须透传完整 config dict(含外层 step_name key)
|
||||
if step_name == 'step8_qaa':
|
||||
method = getattr(self.pipeline, method_name)
|
||||
result = method(**config)
|
||||
return result
|
||||
|
||||
# step9_concentration_inversion 同理,必须透传完整 config dict
|
||||
if step_name == 'step9_concentration':
|
||||
method = getattr(self.pipeline, method_name)
|
||||
result = method(**config)
|
||||
return result
|
||||
|
||||
# 透传面板顶层传入的外部预训练模型(GUI step11_prediction_panel 通过 config['_external_model'] 传入)
|
||||
# 非空才覆盖(遵循 feedback_never_overwrite_with_empty 原则)
|
||||
for key in ('_external_model', '_external_model_path',
|
||||
@ -449,12 +464,12 @@ class WorkerThread(QThread):
|
||||
" → 请确认「流程步骤-阶段五」中已填写有效的边界 shp 路径。"
|
||||
)
|
||||
|
||||
# ── 步骤8(水质指数):训练光谱 CSV ──
|
||||
step8_cfg = config.get('step8', {})
|
||||
training_csv = step8_cfg.get('training_csv_path')
|
||||
# ── 步骤6(水质光谱指数):训练光谱 CSV ──
|
||||
step6_cfg = config.get('step6', {})
|
||||
training_csv = step6_cfg.get('training_csv_path')
|
||||
if training_csv and not os.path.isfile(training_csv):
|
||||
errors.append(
|
||||
f"步骤 8(水质指数):训练光谱文件不存在:\n {training_csv}\n"
|
||||
f"步骤 6(水质光谱指数):训练光谱文件不存在:\n {training_csv}\n"
|
||||
" → 请确认步骤 5 已成功运行并生成了训练光谱。"
|
||||
)
|
||||
|
||||
|
||||
239
src/gui/panels/step9_concentration_panel.py
Normal file
239
src/gui/panels/step9_concentration_panel.py
Normal file
@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Step9 面板 - 浓度反演(基于 QAA 物理反演的二次反演)
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
QWidget, QVBoxLayout, QGroupBox, QFormLayout, QHBoxLayout,
|
||||
QLabel, QCheckBox, QPushButton, QMessageBox, QComboBox,
|
||||
QFileDialog,
|
||||
)
|
||||
from PyQt5.QtGui import QFont
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from src.gui.components.custom_widgets import FileSelectWidget
|
||||
from src.gui.styles import ModernStylesheet
|
||||
|
||||
|
||||
class Step9ConcentrationPanel(QWidget):
|
||||
"""步骤9:浓度反演(物理模型二次反演)"""
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
layout = QVBoxLayout()
|
||||
|
||||
title = QLabel("步骤9:浓度反演(物理模型二次反演)")
|
||||
title.setFont(QFont("Arial", 12, QFont.Bold))
|
||||
layout.addWidget(title)
|
||||
|
||||
# 输入 QAA 结果文件
|
||||
self.input_file = FileSelectWidget(
|
||||
"QAA 结果文件:",
|
||||
"CSV Files (*.csv);;All Files (*.*)"
|
||||
)
|
||||
self.input_file.line_edit.setPlaceholderText(
|
||||
"选择 Step 8 输出的 a_lambda_results.csv"
|
||||
)
|
||||
layout.addWidget(self.input_file)
|
||||
|
||||
# 输出路径
|
||||
self.output_file = FileSelectWidget(
|
||||
"输出文件:",
|
||||
"CSV Files (*.csv);;All Files (*.*)",
|
||||
mode="save"
|
||||
)
|
||||
self.output_file.line_edit.setPlaceholderText(
|
||||
"自动生成到 9_Concentration,或手动指定..."
|
||||
)
|
||||
layout.addWidget(self.output_file)
|
||||
|
||||
# 选择反演指标
|
||||
indicators_group = QGroupBox("选择反演指标")
|
||||
indicators_layout = QFormLayout()
|
||||
|
||||
self.chla_check = QCheckBox("叶绿素 A (Chl-a)")
|
||||
self.chla_check.setChecked(True)
|
||||
self.cdom_check = QCheckBox("CDOM 吸收系数 a_dg(440)")
|
||||
self.cdom_check.setChecked(True)
|
||||
self.turbidity_check = QCheckBox("浊度 (Turbidity)")
|
||||
self.turbidity_check.setChecked(True)
|
||||
self.tn_check = QCheckBox("总氮 (TN)")
|
||||
self.tn_check.setChecked(True)
|
||||
self.tp_check = QCheckBox("总磷 (TP)")
|
||||
self.tp_check.setChecked(True)
|
||||
|
||||
chk_layout = QVBoxLayout()
|
||||
chk_layout.setSpacing(6)
|
||||
for cb in [self.chla_check, self.cdom_check,
|
||||
self.turbidity_check, self.tn_check, self.tp_check]:
|
||||
chk_layout.addWidget(cb)
|
||||
|
||||
indicators_layout.addRow("水质参数:", chk_layout)
|
||||
indicators_group.setLayout(indicators_layout)
|
||||
layout.addWidget(indicators_group)
|
||||
|
||||
# 水体类型(用于比吸收系数自适应)
|
||||
lake_group = QGroupBox("水体类型")
|
||||
lake_layout = QFormLayout()
|
||||
self.lake_case_combo = QComboBox()
|
||||
self.lake_case_combo.addItems([
|
||||
"通用 (medium)",
|
||||
"oligotrophic_clear(寡营养清澈)",
|
||||
"bloom_dominant(藻华主导)",
|
||||
"turbid_mixed(高浊混合)",
|
||||
])
|
||||
self.lake_case_combo.setCurrentIndex(0)
|
||||
lake_layout.addRow("水体类型:", self.lake_case_combo)
|
||||
lake_group.setLayout(lake_layout)
|
||||
layout.addWidget(lake_group)
|
||||
|
||||
# 启用步骤
|
||||
self.enable_checkbox = QCheckBox("启用此步骤")
|
||||
self.enable_checkbox.setChecked(False)
|
||||
layout.addWidget(self.enable_checkbox)
|
||||
|
||||
# 独立运行按钮
|
||||
self.run_btn = QPushButton("执行浓度反演")
|
||||
self.run_btn.setStyleSheet(ModernStylesheet.get_button_stylesheet('success'))
|
||||
self.run_btn.clicked.connect(self.run_step)
|
||||
layout.addWidget(self.run_btn)
|
||||
|
||||
layout.addStretch()
|
||||
self.setLayout(layout)
|
||||
|
||||
def _get_default_work_dir(self) -> str:
|
||||
if hasattr(self, 'work_dir') and self.work_dir:
|
||||
return str(self.work_dir)
|
||||
mw = self.window()
|
||||
if mw and hasattr(mw, 'work_dir') and mw.work_dir:
|
||||
return str(mw.work_dir)
|
||||
return ""
|
||||
|
||||
def browse_output_path(self):
|
||||
current = self.output_file.get_path().strip()
|
||||
if current:
|
||||
initial_dir = os.path.dirname(current)
|
||||
initial_file = os.path.basename(current)
|
||||
else:
|
||||
initial_dir = ""
|
||||
initial_file = ""
|
||||
|
||||
if not initial_dir or not os.path.isdir(initial_dir):
|
||||
work_dir = self._get_default_work_dir()
|
||||
initial_dir = os.path.join(work_dir, "9_Concentration") if work_dir else ""
|
||||
if initial_dir and not os.path.isdir(initial_dir):
|
||||
os.makedirs(initial_dir, exist_ok=True)
|
||||
|
||||
file_path, _ = QFileDialog.getSaveFileName(
|
||||
self, "保存输出文件",
|
||||
os.path.join(initial_dir, initial_file) if initial_file else initial_dir,
|
||||
"CSV Files (*.csv);;All Files (*.*)"
|
||||
)
|
||||
if file_path:
|
||||
self.output_file.set_path(file_path)
|
||||
|
||||
def get_config(self) -> dict:
|
||||
enabled_indicators = []
|
||||
if self.chla_check.isChecked():
|
||||
enabled_indicators.append('chla')
|
||||
if self.cdom_check.isChecked():
|
||||
enabled_indicators.append('cdom')
|
||||
if self.turbidity_check.isChecked():
|
||||
enabled_indicators.append('turbidity')
|
||||
if self.tn_check.isChecked():
|
||||
enabled_indicators.append('tn')
|
||||
if self.tp_check.isChecked():
|
||||
enabled_indicators.append('tp')
|
||||
|
||||
lake_case_map = {
|
||||
0: "medium",
|
||||
1: "oligotrophic_clear",
|
||||
2: "bloom_dominant",
|
||||
3: "turbid_mixed",
|
||||
}
|
||||
lake_case = lake_case_map.get(self.lake_case_combo.currentIndex(), "medium")
|
||||
|
||||
return {
|
||||
'input_csv': self.input_file.get_path(),
|
||||
'output_csv': self.output_file.get_path(),
|
||||
'enabled_indicators': enabled_indicators,
|
||||
'lake_case': lake_case,
|
||||
}
|
||||
|
||||
def set_config(self, config: dict):
|
||||
if 'input_csv' in config:
|
||||
self.input_file.set_path(config['input_csv'])
|
||||
if 'output_csv' in config:
|
||||
self.output_file.set_path(config['output_csv'])
|
||||
|
||||
def update_from_config(self, work_dir=None, pipeline=None):
|
||||
if work_dir:
|
||||
self.work_dir = work_dir
|
||||
elif hasattr(self, 'work_dir') and self.work_dir:
|
||||
pass
|
||||
else:
|
||||
self.work_dir = None
|
||||
|
||||
if self.work_dir:
|
||||
step8_dir = os.path.join(self.work_dir, "8_QAA_Inversion")
|
||||
if os.path.isdir(step8_dir):
|
||||
candidates = []
|
||||
for f in sorted(os.listdir(step8_dir)):
|
||||
if f.lower().endswith('.csv'):
|
||||
candidates.append(os.path.join(step8_dir, f))
|
||||
if candidates:
|
||||
self.input_file.set_path(candidates[0])
|
||||
|
||||
conc_dir = os.path.join(self.work_dir, "9_Concentration")
|
||||
os.makedirs(conc_dir, exist_ok=True)
|
||||
output_path = os.path.join(conc_dir, "final_concentrations.csv").replace('\\', '/')
|
||||
self.output_file.set_path(output_path)
|
||||
|
||||
def run_step(self):
|
||||
input_path = self.input_file.get_path()
|
||||
if not input_path:
|
||||
QMessageBox.warning(self, "输入错误", "请选择 QAA 结果文件!")
|
||||
return
|
||||
|
||||
main_window = self.window()
|
||||
if hasattr(main_window, 'run_single_step'):
|
||||
config = {'step9_concentration': self.get_config()}
|
||||
main_window.run_single_step('step9_concentration', config)
|
||||
else:
|
||||
self._run_concentration_direct()
|
||||
|
||||
def _run_concentration_direct(self):
|
||||
from src.core.algorithms.concentration_inversion import ConcentrationPipeline
|
||||
|
||||
input_path = self.input_file.get_path()
|
||||
output_path = self.output_file.get_path()
|
||||
|
||||
if not output_path:
|
||||
work_dir = self._get_default_work_dir()
|
||||
conc_dir = os.path.join(work_dir, "9_Concentration") if work_dir else ""
|
||||
if conc_dir and not os.path.isdir(conc_dir):
|
||||
os.makedirs(conc_dir, exist_ok=True)
|
||||
output_path = os.path.join(conc_dir, "final_concentrations.csv").replace('\\', '/')
|
||||
|
||||
lake_case_map = {
|
||||
0: "medium",
|
||||
1: "oligotrophic_clear",
|
||||
2: "bloom_dominant",
|
||||
3: "turbid_mixed",
|
||||
}
|
||||
lake_case = lake_case_map.get(self.lake_case_combo.currentIndex(), "medium")
|
||||
|
||||
try:
|
||||
pipeline = ConcentrationPipeline(lake_case=lake_case)
|
||||
result_csv = pipeline.run_pipeline(input_path, output_path)
|
||||
QMessageBox.information(
|
||||
self, "执行成功",
|
||||
f"浓度反演完成!\n结果已保存到:\n{result_csv}"
|
||||
)
|
||||
except Exception as e:
|
||||
QMessageBox.critical(self, "执行错误", f"浓度反演失败:\n{str(e)}")
|
||||
@ -119,14 +119,12 @@ from src.gui.panels.step2_panel import Step2Panel
|
||||
from src.gui.panels.step3_panel import Step3Panel
|
||||
from src.gui.panels.step4_panel import Step4Panel
|
||||
from src.gui.panels.step5_panel import Step5Panel
|
||||
from src.gui.panels.step8_panel import Step8Panel # was step5_5_panel
|
||||
from src.gui.panels.step6_panel import Step6Panel # was step8_panel
|
||||
from src.gui.panels.step7_panel import Step7Panel # was step6_panel
|
||||
from src.gui.panels.step8_non_empirical_panel import Step8NonEmpiricalPanel # was step6_5_panel
|
||||
from src.gui.panels.step9_panel import Step9Panel # was step6_75_panel
|
||||
from src.gui.panels.step8_qaa_panel import Step8QAAPanel # QAA 物理反演(非经验模型)
|
||||
from src.gui.panels.step9_concentration_panel import Step9ConcentrationPanel # 浓度反演
|
||||
from src.gui.panels.step10_panel import Step10Panel # was step7_panel
|
||||
from src.gui.panels.step11_ml_panel import Step11MlPanel # ML prediction (step11_ml)
|
||||
from src.gui.panels.step11_panel import Step11Panel # was step8_5_panel
|
||||
from src.gui.panels.step12_panel import Step12Panel # was step8_75_panel
|
||||
from src.gui.panels.step14_panel import Step14Panel # was step9_panel
|
||||
from src.gui.dialogs import BandConfirmDialog, AISettingsDialog
|
||||
from src.gui.panels.visualization_panel import VisualizationPanel
|
||||
@ -1390,7 +1388,7 @@ class WaterQualityGUI(QMainWindow):
|
||||
'step5': {
|
||||
'training_spectra': '5_training_spectra/training_spectra.csv'
|
||||
},
|
||||
'step8': {
|
||||
'step6': {
|
||||
'water_indices': '6_water_quality_indices/water_quality_indices.csv'
|
||||
},
|
||||
'step7': {
|
||||
@ -1438,8 +1436,8 @@ class WaterQualityGUI(QMainWindow):
|
||||
'boundary_mask_path': ('step1', 'water_mask', 'boundary_mask_file'), # 步骤5可选水体掩膜
|
||||
'glint_mask_path': ('step2', 'glint_mask', 'glint_mask_file') # 步骤5可选耀斑掩膜
|
||||
},
|
||||
'step8': {
|
||||
'training_csv_path': ('step5', 'training_spectra', 'output_file') # 步骤8需要步骤5输出的训练光谱
|
||||
'step6': {
|
||||
'training_csv_path': ('step5', 'training_spectra', 'output_file') # 步骤6需要步骤5输出的训练光谱
|
||||
},
|
||||
'step7': {
|
||||
'csv_path': ('step5', 'training_spectra', 'csv_file') # 步骤7需要训练光谱数据
|
||||
@ -1850,7 +1848,7 @@ class WaterQualityGUI(QMainWindow):
|
||||
"阶段二:样本数据准备 ": [
|
||||
("step4", "4. 数据标准化处理"),
|
||||
("step5", "5. 光谱特征提取"),
|
||||
("step8", "6. 水质参数指数计算"),
|
||||
("step6", "6. 水质参数指数计算"),
|
||||
],
|
||||
"阶段三:模型构建与训练": [
|
||||
("step7", "7. 机器学习模型训练"),
|
||||
@ -1964,19 +1962,17 @@ class WaterQualityGUI(QMainWindow):
|
||||
self.step5_panel = Step5Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step5_panel), QIcon(self.get_icon_path("5.png")), "特征构建")
|
||||
|
||||
self.step8_panel = Step8Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step8_panel), QIcon(self.get_icon_path("5.png")), "水质指数")
|
||||
self.step6_panel = Step6Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step6_panel), QIcon(self.get_icon_path("6.png")), "水质光谱指数计算")
|
||||
|
||||
self.step7_panel = Step7Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step7_panel), QIcon(self.get_icon_path("6.png")), "监督建模")
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step7_panel), QIcon(self.get_icon_path("7.png")), "监督建模")
|
||||
|
||||
self.step8_non_empirical_panel = Step8NonEmpiricalPanel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step8_non_empirical_panel), QIcon(self.get_icon_path("6.png")), "回归建模")
|
||||
self.step_stack.tabBar().setTabVisible(7, False) # 隐藏回归建模 Tab
|
||||
self.step8_qaa_panel = Step8QAAPanel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step8_qaa_panel), QIcon(self.get_icon_path("6.png")), "物理推导(非经验模型)")
|
||||
|
||||
self.step9_panel = Step9Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step9_panel), QIcon(self.get_icon_path("6.png")), "自定义回归建模")
|
||||
self.step_stack.tabBar().setTabVisible(8, False) # 隐藏自定义回归建模 Tab
|
||||
self.step9_concentration_panel = Step9ConcentrationPanel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step9_concentration_panel), QIcon(self.get_icon_path("6.png")), "浓度反演")
|
||||
|
||||
self.step10_panel = Step10Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step10_panel), QIcon(self.get_icon_path("7.png")), "采样点布设")
|
||||
@ -1984,14 +1980,6 @@ class WaterQualityGUI(QMainWindow):
|
||||
self.step11_ml_panel = Step11MlPanel() # ML prediction panel (step11_ml)
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step11_ml_panel), QIcon(self.get_icon_path("8.png")), "监督预测")
|
||||
|
||||
self.step11_panel = Step11Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step11_panel), QIcon(self.get_icon_path("8.png")), "回归预测")
|
||||
self.step_stack.tabBar().setTabVisible(11, False) # 隐藏回归预测 Tab
|
||||
|
||||
self.step12_panel = Step12Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step12_panel), QIcon(self.get_icon_path("8.png")), "自定义回归预测")
|
||||
self.step_stack.tabBar().setTabVisible(12, False) # 隐藏自定义回归预测 Tab
|
||||
|
||||
self.step14_panel = Step14Panel()
|
||||
self.step_stack.addTab(self.create_scroll_area(self.step14_panel), QIcon(self.get_icon_path("10.png")), "专题图生成")
|
||||
|
||||
@ -2143,7 +2131,7 @@ class WaterQualityGUI(QMainWindow):
|
||||
'step3': 2,
|
||||
'step4': 3,
|
||||
'step5': 4,
|
||||
'step8': 5,
|
||||
'step6': 5,
|
||||
'step7': 6,
|
||||
'step8_non_empirical_modeling': 7,
|
||||
'step9': 8,
|
||||
@ -2174,7 +2162,7 @@ class WaterQualityGUI(QMainWindow):
|
||||
2: 'step3',
|
||||
3: 'step4',
|
||||
4: 'step5',
|
||||
5: 'step8',
|
||||
5: 'step6',
|
||||
6: 'step7',
|
||||
7: 'step8_non_empirical_modeling',
|
||||
8: 'step9',
|
||||
@ -2219,44 +2207,36 @@ class WaterQualityGUI(QMainWindow):
|
||||
elif index == 4:
|
||||
self.step5_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step8(水质指数)切换时自动填充输出路径
|
||||
# Step6(水质光谱指数)切换时自动填充输出路径
|
||||
elif index == 5:
|
||||
self.step8_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
self.step6_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step7(监督建模)切换时自动填充训练数据和输出路径
|
||||
elif index == 6:
|
||||
self.step7_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step8非经验建模切换时自动填充训练数据和模型目录
|
||||
# Step8 QAA 物理反演切换时自动填充光谱数据和输出路径
|
||||
elif index == 7:
|
||||
self.step8_non_empirical_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
self.step8_qaa_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step9(自定义回归建模)切换时自动填充训练数据和模型目录
|
||||
# Step9 浓度反演切换时自动填充 QAA 结果和输出路径
|
||||
elif index == 8:
|
||||
self.step9_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
self.step9_concentration_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step10(采样点布设)切换时自动填充掩膜和输出路径
|
||||
elif index == 9:
|
||||
self.step10_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step8(机器学习预测)切换时自动填充采样光谱和模型目录
|
||||
# Step11(机器学习预测)切换时自动填充采样光谱和模型目录
|
||||
elif index == 10:
|
||||
self.step11_ml_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step11(回归预测)切换时自动填充采样光谱和回归模型目录
|
||||
elif index == 11:
|
||||
self.step11_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step12(自定义回归预测)切换时自动填充采样光谱和自定义回归模型目录
|
||||
elif index == 12:
|
||||
self.step12_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# Step14(专题图生成)切换时自动填充预测结果目录
|
||||
elif index == 13:
|
||||
elif index == 11:
|
||||
self.step14_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
# 可视化分析面板切换时自动推断图像目录并加载目录树
|
||||
elif index == 14:
|
||||
elif index == 12:
|
||||
self.viz_panel.update_from_config(work_dir=self.work_dir, pipeline=self.pipeline)
|
||||
|
||||
def apply_stylesheet(self):
|
||||
@ -2300,20 +2280,14 @@ class WaterQualityGUI(QMainWindow):
|
||||
self.step4_panel.set_config(config['step4'])
|
||||
if 'step5' in config:
|
||||
self.step5_panel.set_config(config['step5'])
|
||||
if 'step8' in config:
|
||||
self.step8_panel.set_config(config['step8'])
|
||||
if 'step6' in config:
|
||||
self.step6_panel.set_config(config['step6'])
|
||||
if 'step7' in config:
|
||||
self.step7_panel.set_config(config['step7'])
|
||||
if 'step8_non_empirical_modeling' in config:
|
||||
self.step8_non_empirical_panel.set_config(config['step8_non_empirical_modeling'])
|
||||
if 'step9' in config:
|
||||
self.step9_panel.set_config(config['step9'])
|
||||
if 'step10' in config:
|
||||
self.step10_panel.set_config(config['step10'])
|
||||
if 'step11_ml' in config:
|
||||
self.step11_ml_panel.set_config(config['step11_ml'])
|
||||
if 'step11' in config:
|
||||
self.step11_panel.set_config(config['step11'])
|
||||
if 'step14' in config:
|
||||
self.step14_panel.set_config(config['step14'])
|
||||
if 'visualization' in config:
|
||||
@ -2358,13 +2332,10 @@ class WaterQualityGUI(QMainWindow):
|
||||
'step3': self.step3_panel.get_config(),
|
||||
'step4': self.step4_panel.get_config(),
|
||||
'step5': self.step5_panel.get_config(),
|
||||
'step8': self.step8_panel.get_config(),
|
||||
'step6': self.step6_panel.get_config(),
|
||||
'step7': self.step7_panel.get_config(),
|
||||
'step8_non_empirical_modeling': self.step8_non_empirical_panel.get_config(),
|
||||
'step9': self.step9_panel.get_config(),
|
||||
'step10': self.step10_panel.get_config(),
|
||||
'step11_ml': self.step11_ml_panel.get_config(),
|
||||
'step11': self.step11_panel.get_config(),
|
||||
'step14': self.step14_panel.get_config(),
|
||||
'visualization': self.viz_panel.get_config(),
|
||||
'report_generation': self.report_panel.get_config(),
|
||||
@ -2416,14 +2387,10 @@ class WaterQualityGUI(QMainWindow):
|
||||
'step3': self.step3_panel,
|
||||
'step4': self.step4_panel,
|
||||
'step5': self.step5_panel,
|
||||
'step8': self.step8_panel,
|
||||
'step6': self.step6_panel,
|
||||
'step7': self.step7_panel,
|
||||
'step8_non_empirical_modeling': self.step8_non_empirical_panel,
|
||||
'step9': self.step9_panel,
|
||||
'step10': self.step10_panel,
|
||||
'step11_ml': self.step11_ml_panel,
|
||||
'step11': self.step11_panel,
|
||||
'step12': self.step12_panel,
|
||||
'step14': self.step14_panel,
|
||||
}
|
||||
return panel_map.get(step_id)
|
||||
@ -2518,7 +2485,7 @@ class WaterQualityGUI(QMainWindow):
|
||||
'3_deglint': 'step3',
|
||||
'4_processed_data': 'step4',
|
||||
'5_training_spectra': 'step5',
|
||||
'6_water_quality_indices': 'step8',
|
||||
'6_water_quality_indices': 'step6',
|
||||
'7_Supervised_Model_Training': 'step7',
|
||||
'8_Regression_Modeling': 'step8_non_empirical_modeling',
|
||||
'9_Custom_Regression_Modeling': 'step9',
|
||||
@ -2572,7 +2539,7 @@ class WaterQualityGUI(QMainWindow):
|
||||
discovered_outputs[step_id]['processed_data'] = str(file_path)
|
||||
elif 'training_spectra' in file_name and step_id == 'step5':
|
||||
discovered_outputs[step_id]['training_spectra'] = str(file_path)
|
||||
elif 'water_quality_indices' in file_name and step_id == 'step8':
|
||||
elif 'water_quality_indices' in file_name and step_id == 'step6':
|
||||
discovered_outputs[step_id]['water_indices'] = str(file_path)
|
||||
elif 'sampling_spectra' in file_name and step_id == 'step10':
|
||||
discovered_outputs[step_id]['sampling_points'] = str(file_path)
|
||||
@ -2599,7 +2566,7 @@ class WaterQualityGUI(QMainWindow):
|
||||
# 首先扫描工作目录发现已有的输出文件
|
||||
self.scan_work_directory_for_files(work_path)
|
||||
|
||||
step_order = ['step2', 'step3', 'step4', 'step5', 'step8', 'step7', 'step8_non_empirical_modeling', 'step9',
|
||||
step_order = ['step2', 'step3', 'step4', 'step5', 'step6', 'step7', 'step8_non_empirical_modeling', 'step9',
|
||||
'step10', 'step11_ml', 'step11', 'step12', 'step14']
|
||||
|
||||
filled_count = 0
|
||||
@ -2622,14 +2589,10 @@ class WaterQualityGUI(QMainWindow):
|
||||
('step2', self.step2_panel),
|
||||
('step3', self.step3_panel),
|
||||
('step5', self.step5_panel),
|
||||
('step8', self.step8_panel),
|
||||
('step6', self.step6_panel),
|
||||
('step7', self.step7_panel),
|
||||
('step8_non_empirical_modeling', self.step8_non_empirical_panel),
|
||||
('step9', self.step9_panel),
|
||||
('step10', self.step10_panel),
|
||||
('step11_ml', self.step11_ml_panel),
|
||||
('step11', self.step11_panel),
|
||||
('step12', self.step12_panel),
|
||||
('step14', self.step14_panel)
|
||||
]
|
||||
|
||||
@ -2926,7 +2889,7 @@ class WaterQualityGUI(QMainWindow):
|
||||
"step4", # CSV 实测数据清洗
|
||||
"step5", # 实测点光谱提取(→ training_csv_path)
|
||||
"step7", # ML 监督建模
|
||||
"step8", # 水质指数计算(辅助训练)
|
||||
"step6", # 水质指数计算(辅助训练)
|
||||
"step8_non_empirical_modeling", # 非经验回归建模
|
||||
"step9", # 自定义回归建模
|
||||
]
|
||||
@ -3022,11 +2985,11 @@ class WaterQualityGUI(QMainWindow):
|
||||
|
||||
# 准备实际运行配置(排除未启用的步骤)
|
||||
worker_config = copy.deepcopy(config)
|
||||
step8_cfg = worker_config.get('step8')
|
||||
if step8_cfg:
|
||||
enabled = step8_cfg.pop('enabled', True)
|
||||
step6_cfg = worker_config.get('step6')
|
||||
if step6_cfg:
|
||||
enabled = step6_cfg.pop('enabled', True)
|
||||
if not enabled:
|
||||
worker_config.pop('step8', None)
|
||||
worker_config.pop('step6', None)
|
||||
|
||||
# 工作线程内创建 Pipeline,避免主线程阻塞及 Qt5Agg 子线程绘图卡死
|
||||
self.worker = WorkerThread(work_dir, worker_config, mode='full', skip_list=skip_list)
|
||||
@ -3256,12 +3219,12 @@ class WaterQualityGUI(QMainWindow):
|
||||
def update_ui_for_training_mode(self):
|
||||
"""根据训练数据模式更新UI状态"""
|
||||
# 需要禁用的步骤ID(对应无训练数据模式下需要禁用的步骤)
|
||||
disabled_step_ids = ['step4', 'step5', 'step8', 'step7', 'step8_non_empirical_modeling', 'step9']
|
||||
disabled_step_ids = ['step4', 'step5', 'step6', 'step7', 'step8_non_empirical_modeling', 'step9']
|
||||
|
||||
# 更新标签页的启用/禁用状态
|
||||
step_id_to_tab = {
|
||||
'step1': 0, 'step2': 1, 'step3': 2, 'step4': 3,
|
||||
'step5': 4, 'step8': 5, 'step7': 6, 'step8_non_empirical_modeling': 7,
|
||||
'step5': 4, 'step6': 5, 'step7': 6, 'step8_non_empirical_modeling': 7,
|
||||
'step9': 8, 'step10': 9, 'step11_ml': 10, 'step11': 11,
|
||||
'step12': 12, 'step14': 13, 'step9_viz': 14
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user