feat: step13 auto-detect ML vs formula mode like step11, remove manual selector

This commit is contained in:
duxin
2026-07-09 15:21:45 +08:00
parent 3f4cb94929
commit 66a181cbe2
2 changed files with 21 additions and 28 deletions

View File

@ -14,7 +14,7 @@ from src.gui.panels._step_path_resolver import resolve_subdir
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSettings from PyQt5.QtCore import Qt, QThread, pyqtSignal, QSettings
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QFormLayout, QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QFormLayout,
QLabel, QCheckBox, QPushButton, QLineEdit, QComboBox, QSpinBox, QLabel, QCheckBox, QPushButton, QLineEdit, QSpinBox,
QMessageBox, QFileDialog, QProgressBar, QMessageBox, QFileDialog, QProgressBar,
) )
@ -34,13 +34,12 @@ class ReportWorkerThread(QThread):
error = pyqtSignal(str) error = pyqtSignal(str)
def __init__(self, work_dir: str, output_dir: Optional[str], report_title: str, def __init__(self, work_dir: str, output_dir: Optional[str], report_title: str,
enable_ai: bool, report_mode: str = 'ml', ai_maps_limit: int = 999): enable_ai: bool, ai_maps_limit: int = 999):
super().__init__() super().__init__()
self.work_dir = work_dir self.work_dir = work_dir
self.output_dir = output_dir self.output_dir = output_dir
self.report_title = report_title self.report_title = report_title
self.enable_ai = enable_ai self.enable_ai = enable_ai
self.report_mode = report_mode
self.ai_maps_limit = ai_maps_limit self.ai_maps_limit = ai_maps_limit
def run(self): def run(self):
@ -79,7 +78,7 @@ class ReportWorkerThread(QThread):
out_path = gen.generate_report( out_path = gen.generate_report(
work_dir=self.work_dir, work_dir=self.work_dir,
report_title=self.report_title or "水质参数反演分析报告", report_title=self.report_title or "水质参数反演分析报告",
report_mode=self.report_mode, report_mode='auto',
ai_maps_limit=self.ai_maps_limit, ai_maps_limit=self.ai_maps_limit,
on_progress=lambda pct, text: self.progress.emit(int(pct), str(text)), on_progress=lambda pct, text: self.progress.emit(int(pct), str(text)),
) )
@ -262,22 +261,7 @@ class Step13ReportPanel(QWidget):
""") """)
execute_layout.addWidget(self.progress_bar) execute_layout.addWidget(self.progress_bar)
# 报告模式选择 # AI 专题图分析数量(仅水色指数公式模式生效,ML 模式忽略)
mode_row = QHBoxLayout()
mode_row.setContentsMargins(0, 4, 0, 0)
mode_row.setSpacing(10)
mode_label = QLabel("报告模式:")
mode_label.setMinimumWidth(120)
mode_label.setMaximumWidth(120)
mode_row.addWidget(mode_label)
self.report_mode_cb = QComboBox()
self.report_mode_cb.addItem("机器学习水质参数反演", "ml")
self.report_mode_cb.addItem("水色指数与物理经验公式反演", "formula")
self.report_mode_cb.setStyleSheet(common_lineedit_css)
mode_row.addWidget(self.report_mode_cb, 1)
execute_layout.addLayout(mode_row)
# AI 专题图分析数量(仅公式模式生效)
ai_maps_row = QHBoxLayout() ai_maps_row = QHBoxLayout()
ai_maps_row.setContentsMargins(0, 0, 0, 0) ai_maps_row.setContentsMargins(0, 0, 0, 0)
ai_maps_row.setSpacing(10) ai_maps_row.setSpacing(10)
@ -288,7 +272,7 @@ class Step13ReportPanel(QWidget):
self.ai_maps_spin = QSpinBox() self.ai_maps_spin = QSpinBox()
self.ai_maps_spin.setRange(0, 999) self.ai_maps_spin.setRange(0, 999)
self.ai_maps_spin.setValue(999) self.ai_maps_spin.setValue(999)
self.ai_maps_spin.setToolTip("公式报告中启用AI分析的分布图数量上限(0=全部跳过,999=全部分析)") self.ai_maps_spin.setToolTip("公式报告中启用AI分析的分布图数量上限(0=跳过,999=全部分析)")
self.ai_maps_spin.setStyleSheet(common_lineedit_css) self.ai_maps_spin.setStyleSheet(common_lineedit_css)
ai_maps_row.addWidget(self.ai_maps_spin, 1) ai_maps_row.addWidget(self.ai_maps_spin, 1)
execute_layout.addLayout(ai_maps_row) execute_layout.addLayout(ai_maps_row)
@ -430,9 +414,8 @@ class Step13ReportPanel(QWidget):
self.progress_bar.setValue(0) self.progress_bar.setValue(0)
self.progress_label.setText("正在准备生成…") self.progress_label.setText("正在准备生成…")
report_mode = self.report_mode_cb.currentData()
ai_maps_limit = self.ai_maps_spin.value() ai_maps_limit = self.ai_maps_spin.value()
self._report_thread = ReportWorkerThread(wd, out, title, enable_ai, report_mode, ai_maps_limit) self._report_thread = ReportWorkerThread(wd, out, title, enable_ai, ai_maps_limit)
self._report_thread.progress.connect(self._on_progress, Qt.QueuedConnection) self._report_thread.progress.connect(self._on_progress, Qt.QueuedConnection)
self._report_thread.finished.connect(self._on_finished, Qt.QueuedConnection) self._report_thread.finished.connect(self._on_finished, Qt.QueuedConnection)
self._report_thread.error.connect(self._on_error, Qt.QueuedConnection) self._report_thread.error.connect(self._on_error, Qt.QueuedConnection)

View File

@ -778,15 +778,14 @@ class WaterQualityReportGenerator:
parameters: List[str] = None, parameters: List[str] = None,
report_title: str = "水质参数反演分析报告", report_title: str = "水质参数反演分析报告",
output_path: Optional[str] = None, output_path: Optional[str] = None,
report_mode: str = 'ml', report_mode: str = 'auto',
ai_maps_limit: int = 999, ai_maps_limit: int = 999,
on_progress=None) -> str: on_progress=None) -> str:
""" """
生成 Word 报告(双轨制入口) 生成 Word 报告(双轨制入口,默认自动检测模式)
Args: Args:
report_mode: 'ml' → 机器学习报告, 'formula' → 水色指数/物理公式报告 report_mode: 'auto'→自动检测(参考Step11), 'ml'/'formula'→强制模式
on_progress: 可选回调 on_progress(percent: int, text: str)
""" """
# 设置工作目录 # 设置工作目录
if work_dir is not None: if work_dir is not None:
@ -805,8 +804,19 @@ class WaterQualityReportGenerator:
"spCond", "Turbidity", "TDS", "Cl-", "NO3-N", "spCond", "Turbidity", "TDS", "Cl-", "NO3-N",
"NH3-N", "BGA", "TT"] "NH3-N", "BGA", "TT"]
# ── 自动检测管线模式(参考 Step11 逻辑)──
if report_mode == 'auto':
ml_dir = self.work_dir / "9_ML_Prediction"
formula_dir = self.work_dir / "10_WaterIndex_CSV"
if ml_dir.is_dir() and list(ml_dir.glob("*.csv")):
report_mode = 'ml'
elif formula_dir.is_dir() and list(formula_dir.glob("*.csv")):
report_mode = 'formula'
else:
report_mode = 'ml' # 兜底
self._pipeline_mode = 'water_index' if report_mode == 'formula' else 'ml' self._pipeline_mode = 'water_index' if report_mode == 'formula' else 'ml'
print(f"[报告] 报告模式: {report_mode}") print(f"[报告] 自动检测 → 模式: {report_mode}")
if report_mode == 'formula': if report_mode == 'formula':
return self._generate_formula_report(parameters, report_title, output_path, return self._generate_formula_report(parameters, report_title, output_path,