feat(gui): 全流程面板合并 + 一键式运行 GUI 入口集成

This commit is contained in:
DXC
2026-06-09 11:30:42 +08:00
parent aefc9d5aac
commit 28394f2eda
20 changed files with 2843 additions and 2432 deletions

View File

@ -8,7 +8,17 @@ Pipeline 调度核心:基于 Context 的内存级依赖注入。
- 不绑定具体 Pipeline 实现duck-typedWorkerThread / Web API / 单测可共用
"""
from .context import PipelineContext
from .runner import StepSpec, PIPELINE_STEPS, PipelineRunner
from .context import (
PipelineContext,
STEP_MAP_OLD_TO_NEW, STEP_MAP_NEW_TO_OLD,
resolve_step_id, ALL_STEP_IDS,
)
from .runner import (
StepSpec, PIPELINE_STEPS, PipelineRunner, PipelineHalt,
)
__all__ = ["PipelineContext", "StepSpec", "PIPELINE_STEPS", "PipelineRunner"]
__all__ = [
"PipelineContext", "StepSpec", "PIPELINE_STEPS", "PipelineRunner", "PipelineHalt",
"STEP_MAP_OLD_TO_NEW", "STEP_MAP_NEW_TO_OLD",
"resolve_step_id", "ALL_STEP_IDS",
]

View File

@ -12,7 +12,34 @@ PipelineContext内存级数据载体跨 14 个 step 传递路径与元信
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, Set
# ============================================================
# 步骤命名映射(定义在叶子节点,打破循环依赖)
# ============================================================
STEP_MAP_OLD_TO_NEW: Dict[str, str] = {
"step5_5": "step8",
"step6_5": "step8_non_empirical_modeling",
"step6_75": "step9",
"step8_5": "step11",
"step8_75": "step12",
"step7": "step10",
"step8": "step11_ml",
"step9": "step14",
}
STEP_MAP_NEW_TO_OLD: Dict[str, str] = {v: k for k, v in STEP_MAP_OLD_TO_NEW.items()}
ALL_STEP_IDS: Set[str] = set(STEP_MAP_OLD_TO_NEW.keys()) | set(STEP_MAP_OLD_TO_NEW.values())
def resolve_step_id(step_id: str) -> str:
"""将任意 step_id 转换为标准新格式。"""
if step_id in STEP_MAP_OLD_TO_NEW:
return STEP_MAP_OLD_TO_NEW[step_id]
return step_id
@dataclass
@ -63,10 +90,29 @@ class PipelineContext:
pipeline_end_time: Optional[float] = None
last_error: Optional[str] = None
# ── 错误汇总(全流程结束后可用) ──
error_summary: List[tuple[str, str]] = field(default_factory=list)
# ── 出错时立即停止全流程(默认 False继续后续步骤 ──
breakpoint_on_error: bool = False
# ── ★ 智能补全锁定步骤列表(由 _auto_fill_missing_steps 自动开启的步骤) ──
# GUI 层读取此字段,在运行期间禁用对应面板的启用复选框
locked_steps: List[str] = field(default_factory=list)
# ============================================================
# 读写辅助
# ============================================================
def step_id(self, step_id: str) -> str:
"""将任意 step_id可能是旧名转换为标准新格式。
用法示例:
ctx.status[ctx.step_id('step6_5')] # 'step8_non_empirical_modeling'
ctx.user_config[ctx.step_id('step8_5')] # 'step11'
"""
if step_id in STEP_MAP_OLD_TO_NEW:
return STEP_MAP_OLD_TO_NEW[step_id]
return step_id
def set(self, key: str, value: Any) -> None:
"""原地写入任意属性。

View File

@ -660,7 +660,7 @@ class WaterQualityInversionPipeline:
self._notify("completed", f"训练光谱数据已保存: {result}")
return result
def step5_5_calculate_water_quality_indices(self,
def step8_water_quality_indices(self,
training_csv_path: Optional[str] = None,
formula_csv_file: Optional[str] = None,
formula_names: Optional[List[str]] = None,
@ -704,7 +704,7 @@ class WaterQualityInversionPipeline:
self._notify("completed", f"水质指数已保存: {result}")
return result
def step6_train_models(self, feature_start_column: str = "374.285004",
def step7_ml_modeling(self, feature_start_column: str = "374.285004",
preprocessing_methods: List[str] = None,
model_names: List[str] = None,
split_methods: List[str] = None,
@ -747,7 +747,7 @@ class WaterQualityInversionPipeline:
self._notify("completed", f"模型训练完成,结果保存在: {result}")
return result
def step7_generate_sampling_points(self, deglint_img_path: Optional[str] = None,
def step10_sampling(self, deglint_img_path: Optional[str] = None,
interval: int = 50,
sample_radius: int = 5,
chunk_size: int = 1000,
@ -756,7 +756,7 @@ class WaterQualityInversionPipeline:
use_adaptive_sampling: bool = True,
skip_dependency_check: bool = False, **kwargs) -> str:
"""
步骤7: 生成根据水域掩膜内且耀斑掩膜外的采样点,统计采样点的平均光谱
步骤10: 生成根据水域掩膜内且耀斑掩膜外的采样点,统计采样点的平均光谱
Args:
deglint_img_path: 去除耀斑后的影像文件路径如果为None使用步骤3的结果
@ -779,7 +779,7 @@ class WaterQualityInversionPipeline:
if water_mask_path is None and self.water_mask_path is not None:
water_mask_path = self.water_mask_path
self._notify("started", "步骤7: 生成预测采样点")
self._notify("started", "步骤10: 生成预测采样点")
result = PredictionStep.generate_sampling_points(
deglint_img_path=img_path,
interval=interval,
@ -790,21 +790,21 @@ class WaterQualityInversionPipeline:
output_dir=str(self.sampling_dir),
use_adaptive_sampling=use_adaptive_sampling,
)
self._record_step_time("步骤7: 生成预测采样点", 0, 0)
self._record_step_time("步骤10: 生成预测采样点", 0, 0)
self._notify("completed", f"采样点光谱数据已保存: {result}")
return result
def step8_predict_water_quality(self, sampling_csv_path: str,
def step11_ml_prediction(self, sampling_csv_path: str,
models_dir: Optional[str] = None,
metric: str = 'test_r2',
prediction_column: str = 'prediction',
skip_dependency_check: bool = False, **kwargs) -> Dict[str, str]:
"""
步骤8: 将训练好的最佳机器学习模型应用到采样点的平均光谱上,预测水质参数
步骤11: 将训练好的最佳机器学习模型应用到采样点的平均光谱上,预测水质参数
Args:
sampling_csv_path: 采样点光谱数据CSV路径
models_dir: 模型保存目录如果为None使用步骤6的结果)
models_dir: 模型保存目录如果为None使用步骤7的结果)
metric: 选择最佳模型的指标
prediction_column: 预测结果列名
@ -818,7 +818,7 @@ class WaterQualityInversionPipeline:
print(f"[Pipeline] 收到字典: {'Yes' if _external_models_dict else 'No'}"
f", 收到单模型: {'Yes' if _external_model else 'No'}")
self._notify("started", "步骤8: 预测水质参数")
self._notify("started", "步骤11: 预测水质参数")
result = PredictionStep.predict_water_quality(
sampling_csv_path=sampling_csv_path,
models_dir=models_dir if models_dir else str(self.models_dir),
@ -831,11 +831,11 @@ class WaterQualityInversionPipeline:
_external_models_dict=_external_models_dict,
_external_model_dir=_external_model_dir,
)
self._record_step_time("步骤8: 预测水质参数", 0, 0)
self._record_step_time("步骤11: 预测水质参数", 0, 0)
self._notify("completed", f"预测完成,结果保存在: {self.prediction_dir}")
return result
def step9_generate_distribution_map(self, prediction_csv_path: str,
def step14_distribution_map(self, prediction_csv_path: str,
boundary_shp_path: str,
output_image_path: Optional[str] = None,
resolution: float = 30,
@ -1524,99 +1524,99 @@ class WaterQualityInversionPipeline:
else:
self._notify("步骤5: 光谱提取", "skipped", "未配置")
# 步骤5.5: 计算水质指数
if 'step5_5' in config:
self._notify("步骤5.5: 水质指数计算", "start")
self.step5_5_calculate_water_quality_indices(**config['step5_5'])
self._notify("步骤5.5: 水质指数计算", "completed", f"(输出: {self.indices_path})")
# 步骤8: 计算水质指数
if 'step8' in config:
self._notify("步骤8: 水质指数计算", "start")
self.step8_water_quality_indices(**config['step8'])
self._notify("步骤8: 水质指数计算", "completed", f"(输出: {self.indices_path})")
else:
self._notify("步骤5.5: 水质指数计算", "skipped", "未配置")
self._notify("步骤8: 水质指数计算", "skipped", "未配置")
# 步骤6: 训练模型
if 'step6' in config:
self._notify("步骤6: 模型训练", "start")
self.step6_train_models(**config['step6'])
self._notify("步骤6: 模型训练", "completed", f"(输出: {self.models_dir})")
else:
self._notify("步骤6: 模型训练", "skipped", "未配置")
# 步骤6.5: 非经验统计回归模型训练
if 'step6_5' in config:
self._notify("步骤6.5: 非经验模型训练", "start")
self.step6_5_non_empirical_modeling(**config['step6_5'])
self._notify("步骤6.5: 非经验模型训练", "completed", f"(输出: {self.models_dir})")
else:
self._notify("步骤6.5: 非经验模型训练", "skipped", "未配置")
# 步骤6.75: 自定义回归分析
if 'step6_75' in config:
self._notify("步骤6.75: 自定义回归", "start")
self.step6_75_custom_regression(**config['step6_75'])
self._notify("步骤6.75: 自定义回归", "completed", f"(输出: {self.custom_regression_path})")
else:
self._notify("步骤6.75: 自定义回归", "skipped", "未配置")
# 步骤7: 生成预测采样点
# 步骤7: 训练模型
if 'step7' in config:
self._notify("步骤7: 采样点生成", "start")
sampling_csv_path = self.step7_generate_sampling_points(**config['step7'])
self._notify("步骤7: 采样点生成", "completed", f"(输出: {sampling_csv_path})")
self._notify("步骤7: 模型训练", "start")
self.step7_ml_modeling(**config['step7'])
self._notify("步骤7: 模型训练", "completed", f"(输出: {self.models_dir})")
else:
self._notify("步骤7: 模型训练", "skipped", "未配置")
# 步骤8_non_empirical_modeling: 非经验统计回归模型训练
if 'step8_non_empirical_modeling' in config:
self._notify("步骤8: 非经验模型训练", "start")
self.step8_non_empirical_modeling(**config['step8_non_empirical_modeling'])
self._notify("步骤8: 非经验模型训练", "completed", f"(输出: {self.models_dir})")
else:
self._notify("步骤8: 非经验模型训练", "skipped", "未配置")
# 步骤9: 自定义回归分析
if 'step9' in config:
self._notify("步骤9: 自定义回归", "start")
self.step9_custom_regression(**config['step9'])
self._notify("步骤9: 自定义回归", "completed", f"(输出: {self.custom_regression_path})")
else:
self._notify("步骤9: 自定义回归", "skipped", "未配置")
# 步骤10: 生成预测采样点
if 'step10' in config:
self._notify("步骤10: 采样点生成", "start")
sampling_csv_path = self.step10_sampling(**config['step10'])
self._notify("步骤10: 采样点生成", "completed", f"(输出: {sampling_csv_path})")
else:
sampling_csv_path = None
self._notify("步骤7: 采样点生成", "skipped", "未配置")
self._notify("步骤10: 采样点生成", "skipped", "未配置")
# 步骤8: 预测水质参数
if 'step8' in config and sampling_csv_path:
self._notify("步骤8: 参数预测", "start")
step8_config = config['step8'].copy()
step8_config['sampling_csv_path'] = sampling_csv_path
prediction_files = self.step8_predict_water_quality(**step8_config)
self._notify("步骤8: 参数预测", "completed", f"(生成{len(prediction_files)}个预测文件)")
# 步骤11_ml: 预测水质参数
if 'step11_ml' in config and sampling_csv_path:
self._notify("步骤11: 参数预测", "start")
step11_ml_config = config['step11_ml'].copy()
step11_ml_config['sampling_csv_path'] = sampling_csv_path
prediction_files = self.step11_ml_prediction(**step11_ml_config)
self._notify("步骤11: 参数预测", "completed", f"(生成{len(prediction_files)}个预测文件)")
else:
prediction_files = {}
self._notify("步骤8: 参数预测", "skipped", "未配置或缺少采样点")
self._notify("步骤11: 参数预测", "skipped", "未配置或缺少采样点")
# 步骤8.5: 使用非经验模型进行参数预测
# 步骤11: 使用非经验模型进行参数预测
non_empirical_prediction_files = {}
if 'step8_5' in config and sampling_csv_path:
self._notify("步骤8.5: 非经验模型预测", "start")
step8_5_config = config['step8_5'].copy()
step8_5_config['sampling_csv_path'] = sampling_csv_path
non_empirical_prediction_files = self.step8_5_predict_with_non_empirical_models(**step8_5_config)
self._notify("步骤8.5: 非经验模型预测", "completed", f"(生成{len(non_empirical_prediction_files)}个预测文件)")
if 'step11' in config and sampling_csv_path:
self._notify("步骤11: 非经验模型预测", "start")
step11_config = config['step11'].copy()
step11_config['sampling_csv_path'] = sampling_csv_path
non_empirical_prediction_files = self.step11_non_empirical_prediction(**step11_config)
self._notify("步骤11: 非经验模型预测", "completed", f"(生成{len(non_empirical_prediction_files)}个预测文件)")
else:
self._notify("步骤8.5: 非经验模型预测", "skipped", "未配置或缺少采样点")
self._notify("步骤11: 非经验模型预测", "skipped", "未配置或缺少采样点")
# 步骤8.75: 使用自定义回归模型进行参数预测
# 步骤12: 使用自定义回归模型进行参数预测
custom_regression_prediction_files = {}
if 'step8_75' in config and sampling_csv_path:
self._notify("步骤8.75: 自定义回归预测", "start")
step8_75_config = config['step8_75'].copy()
step8_75_config['sampling_csv_path'] = sampling_csv_path
custom_regression_prediction_files = self.step8_75_predict_with_custom_regression(**step8_75_config)
self._notify("步骤8.75: 自定义回归预测", "completed", f"(生成{len(custom_regression_prediction_files)}个预测文件)")
if 'step12' in config and sampling_csv_path:
self._notify("步骤12: 自定义回归预测", "start")
step12_config = config['step12'].copy()
step12_config['sampling_csv_path'] = sampling_csv_path
custom_regression_prediction_files = self.step12_custom_regression_prediction(**step12_config)
self._notify("步骤12: 自定义回归预测", "completed", f"(生成{len(custom_regression_prediction_files)}个预测文件)")
else:
self._notify("步骤8.75: 自定义回归预测", "skipped", "未配置或缺少采样点")
self._notify("步骤12: 自定义回归预测", "skipped", "未配置或缺少采样点")
# 合并机器学习预测、非经验模型预测和自定义回归预测结果
all_prediction_files = {**prediction_files, **non_empirical_prediction_files, **custom_regression_prediction_files}
# 步骤9: 生成分布图
# 步骤14: 生成分布图
distribution_maps = {}
if 'step9' in config and all_prediction_files:
self._notify("步骤9: 分布图生成", "start")
if 'step14' in config and all_prediction_files:
self._notify("步骤14: 分布图生成", "start")
for target_name, pred_file in all_prediction_files.items():
step9_config = config['step9'].copy()
step14_config = config['step14'].copy()
for _k in ('step9_batch_mode', 'prediction_csv_dir', 'recursive_csv_scan'):
step9_config.pop(_k, None)
step9_config['prediction_csv_path'] = pred_file
if 'output_image_path' not in step9_config:
step9_config['output_image_path'] = None
dist_map_path = self.step9_generate_distribution_map(**step9_config)
step14_config.pop(_k, None)
step14_config['prediction_csv_path'] = pred_file
if 'output_image_path' not in step14_config:
step14_config['output_image_path'] = None
dist_map_path = self.step14_distribution_map(**step14_config)
distribution_maps[target_name] = dist_map_path
self._notify("步骤9: 分布图生成", "completed", f"(生成{len(distribution_maps)}个分布图)")
self._notify("步骤14: 分布图生成", "completed", f"(生成{len(distribution_maps)}个分布图)")
else:
self._notify("步骤9: 分布图生成", "skipped", "未配置或缺少预测结果")
self._notify("步骤14: 分布图生成", "skipped", "未配置或缺少预测结果")
# 生成可视化图表
output_files = {}
@ -1716,10 +1716,10 @@ class WaterQualityInversionPipeline:
pipeline_info['step3'] = {'status': 'completed', 'output_file': str(self.deglint_img_path) if self.deglint_img_path else 'N/A'}
pipeline_info['step4'] = {'status': 'completed', 'output_file': str(self.processed_csv_path) if self.processed_csv_path else 'N/A'}
pipeline_info['step5'] = {'status': 'completed', 'output_file': str(self.training_csv_path) if self.training_csv_path else 'N/A'}
pipeline_info['step5_5'] = {'status': 'completed', 'output_file': str(self.indices_path) if self.indices_path else 'N/A'}
pipeline_info['step6'] = {'status': 'completed', 'output_file': str(self.models_dir)}
pipeline_info['step6_75'] = {'status': 'completed', 'output_file': str(self.custom_regression_path) if self.custom_regression_path else 'N/A'}
pipeline_info['training_params'] = config.get('step6', {})
pipeline_info['step8'] = {'status': 'completed', 'output_file': str(self.indices_path) if self.indices_path else 'N/A'}
pipeline_info['step7'] = {'status': 'completed', 'output_file': str(self.models_dir)}
pipeline_info['step9'] = {'status': 'completed', 'output_file': str(self.custom_regression_path) if self.custom_regression_path else 'N/A'}
pipeline_info['training_params'] = config.get('step7', {})
summary_path = self.report_generator.generate_batch_inference_summary(pipeline_info)
print(f"批量处理摘要已生成: {summary_path}")
@ -1769,7 +1769,7 @@ class WaterQualityInversionPipeline:
traceback.print_exc()
raise
def step6_5_non_empirical_modeling(self, csv_path: Optional[str] = None,
def step8_non_empirical_modeling(self, csv_path: Optional[str] = None,
preprocessing_methods: List[str] = None,
algorithms: List[str] = None,
value_cols: Union[int, Dict[str, int]] = 0,
@ -1819,7 +1819,7 @@ class WaterQualityInversionPipeline:
self._notify("completed", f"非经验模型训练完成")
return result
def step6_75_custom_regression(self,
def step9_custom_regression(self,
csv_path: Optional[str] = None,
x_columns: Optional[Union[str, List[str]]] = None,
y_columns: Optional[Union[str, List[str]]] = None,
@ -1999,7 +1999,7 @@ class WaterQualityInversionPipeline:
return summary_path
def step8_5_predict_with_non_empirical_models(self, sampling_csv_path: str,
def step11_non_empirical_prediction(self, sampling_csv_path: str,
non_empirical_models_dir: Optional[str] = None,
output_path: Optional[str] = None,
metric: str = 'Average Accuracy(%)',
@ -2007,13 +2007,13 @@ class WaterQualityInversionPipeline:
enabled: bool = True,
skip_dependency_check: bool = False, **kwargs) -> Dict[str, str]:
"""
步骤8.5: 使用非经验统计回归模型进行参数预测
步骤11: 使用非经验统计回归模型进行参数预测
根据非经验模型训练结果汇总CSV筛选给定方法的准确率最高的模型使用该模型进行预测
Args:
sampling_csv_path: 采样点光谱数据CSV路径
non_empirical_models_dir: 非经验模型保存目录如果为None使用步骤6.5的结果)
non_empirical_models_dir: 非经验模型保存目录如果为None使用步骤8的结果)
output_path: 输出目录路径如果为None使用默认目录
metric: 选择最佳模型的指标(默认使用平均准确率)
prediction_column: 预测结果列名
@ -2021,7 +2021,7 @@ class WaterQualityInversionPipeline:
Returns:
预测结果文件路径字典(键为算法名)
"""
self._notify("started", "步骤8.5: 使用非经验模型进行参数预测")
self._notify("started", "步骤11: 使用非经验模型进行参数预测")
result = PredictionStep.predict_with_non_empirical_models(
sampling_csv_path=sampling_csv_path,
non_empirical_models_dir=non_empirical_models_dir,
@ -2031,11 +2031,11 @@ class WaterQualityInversionPipeline:
enabled=enabled,
work_dir=str(self.work_dir),
)
self._record_step_time("步骤8.5: 非经验模型预测", 0, 0)
self._record_step_time("步骤11: 非经验模型预测", 0, 0)
self._notify("completed", f"非经验模型预测完成,结果保存在: {self.prediction_dir}")
return result
def step8_75_predict_with_custom_regression(self, sampling_csv_path: str,
def step12_custom_regression_prediction(self, sampling_csv_path: str,
custom_regression_dir: Optional[str] = None,
formula_csv_path: Optional[str] = None,
coordinate_columns: Optional[List[str]] = None,
@ -2044,13 +2044,13 @@ class WaterQualityInversionPipeline:
enabled: bool = True,
skip_dependency_check: bool = False, **kwargs) -> Dict[str, str]:
"""
步骤8.75: 使用自定义回归模型进行参数预测
步骤12: 使用自定义回归模型进行参数预测
使用新的CustomRegressionPredictor模块基于9_Custom_Regression_Modeling文件夹中的CSV
根据r_squared选择最佳模型批量预测水质参数
Args:
sampling_csv_path: 采样点光谱数据CSV路径来自步骤7
sampling_csv_path: 采样点光谱数据CSV路径来自步骤10
custom_regression_dir: 自定义回归模型目录9_Custom_Regression_Modeling
formula_csv_path: 公式CSV文件路径用于查找index_formula
coordinate_columns: 坐标列名列表,默认为['longitude', 'latitude']或自动识别
@ -2058,11 +2058,11 @@ class WaterQualityInversionPipeline:
filename_prefix: 输出文件名前缀
enabled: 是否启用
skip_dependency_check: 是否跳过依赖检查
Returns:
预测结果文件路径字典(键为参数名)
"""
self._notify("started", "步骤8.75: 使用自定义回归模型进行参数预测")
self._notify("started", "步骤12: 使用自定义回归模型进行参数预测")
result = PredictionStep.predict_with_custom_regression(
sampling_csv_path=sampling_csv_path,
custom_regression_dir=custom_regression_dir,
@ -2073,7 +2073,7 @@ class WaterQualityInversionPipeline:
enabled=enabled,
work_dir=str(self.work_dir),
)
self._record_step_time("步骤8.75: 自定义回归模型预测", 0, 0)
self._record_step_time("步骤12: 自定义回归模型预测", 0, 0)
self._notify("completed", f"自定义回归预测完成")
return result
@ -2161,20 +2161,20 @@ def main():
# 单步运行时建议显式指定完整流程中可省略将使用步骤2输出的耀斑掩膜
# 'glint_mask_path': r"path/to/severe_glint_area.dat",
},
'step5_5': {
'step8': {
'formula_csv_file': 'path/to/water_quality_formulas.csv', # 公式CSV文件路径
'formula_names': ['Al10SABI', 'TurbBe16RedOverViolet'], # 要计算的公式名称列表
'output_filename': 'water_quality_indices.csv',
'enabled': True # 是否启用水质指数计算
},
'step6': {
'step7': {
'feature_start_column': '374.285004',
'preprocessing_methods': ['None', 'MMS', 'SS', 'SNV', 'MA', 'SG', 'MSC', 'D1', 'D2', 'DT', 'CT'],
'model_names': ['SVR', 'RF', 'Ridge', 'Lasso'],
'split_methods': ['spxy', 'ks', 'random'],
'cv_folds': 3
},
'step6_5': {
'step8_non_empirical_modeling': {
'preprocessing_methods': ['None', 'MMS', 'SS', 'SNV', 'MA', 'SG', 'MSC', 'D1', 'D2', 'DT', 'CT'],
'algorithms': ['chl_a', 'nh3', 'mno4', 'tn', 'tp', 'tss'],
'value_cols': 0, # 可以是单个整数或字典,如 {'chl_a': 0, 'nh3': 1, 'mno4': 2, 'tn': 3, 'tp': 4, 'tss': 5}
@ -2182,14 +2182,14 @@ def main():
'window': 5,
'enabled': True # 是否启用非经验模型训练
},
'step6_75': {
'step9': {
'x_columns': ['NDWI', 'NDVI'], # 自变量列名列表
'y_columns': ['chl_a', 'tn', 'tp'], # 因变量列名列表
'methods': 'all', # 回归方法
'output_dir': 'custom_regression_results', # 输出目录
'enabled': True # 是否启用自定义回归分析
},
'step7': {
'step10': {
'interval': 50,
'sample_radius': 5,
'chunk_size': 1000,
@ -2197,16 +2197,16 @@ def main():
# 可选耀斑掩膜文件dat若不提供将使用步骤2结果需要外部指定时取消注释
# 'glint_mask_path': r"D:\path\to\severe_glint_area.dat",
},
'step8': {
'step11_ml': {
'metric': 'test_r2',
'prediction_column': 'prediction'
},
'step8_5': {
'step11': {
'metric': 'Average Accuracy(%)', # 选择最佳模型的指标
'prediction_column': 'prediction',
'enabled': True # 是否启用非经验模型预测
},
'step8_75': {
'step12': {
'custom_regression_dir': None, # 自定义回归模型目录None表示使用9_Custom_Regression_Modeling
'formula_csv_path': None, # 公式CSV文件路径用于查找index_formula如water_quality_formulas.csv
'coordinate_columns': None, # 坐标列名None表示自动识别
@ -2214,7 +2214,7 @@ def main():
'filename_prefix': 'custom_regression_prediction', # 输出文件名前缀
'enabled': True # 是否启用自定义回归预测
},
'step9': {
'step14': {
'boundary_shp_path': r"D:\BaiduNetdiskDownload\yaobao\roi\roi.shp" ,
'resolution': 30,
'input_crs': 'EPSG:32651',
@ -2345,41 +2345,41 @@ def example_independent_steps():
except Exception as e:
print(f"步骤6失败: {e}")
# 示例6: 独立运行步骤7 - 采样点生成
print("\n示例6: 独立运行步骤7 - 采样点生成")
# 示例6: 独立运行步骤10 - 采样点生成
print("\n示例6: 独立运行步骤10 - 采样点生成")
try:
sampling_csv = pipeline.step7_generate_sampling_points(
sampling_csv = pipeline.step10_sampling(
deglint_img_path="path/to/deglint_image.bsq",
water_mask_path="path/to/water_mask.dat",
skip_dependency_check=True
)
print(f"采样点数据: {sampling_csv}")
except Exception as e:
print(f"步骤7失败: {e}")
print(f"步骤10失败: {e}")
# 示例7: 独立运行步骤8 - 水质预测
print("\n示例7: 独立运行步骤8 - 水质预测")
# 示例7: 独立运行步骤11 - 水质预测
print("\n示例7: 独立运行步骤11 - 水质预测")
try:
predictions = pipeline.step8_predict_water_quality(
predictions = pipeline.step11_ml_prediction(
sampling_csv_path="path/to/sampling_spectra.csv",
models_dir="path/to/models_directory",
skip_dependency_check=True
)
print(f"预测结果: {predictions}")
except Exception as e:
print(f"步骤8失败: {e}")
print(f"步骤11失败: {e}")
# 示例8: 独立运行步骤9 - 分布图生成
print("\n示例8: 独立运行步骤9 - 分布图生成")
# 示例8: 独立运行步骤14 - 分布图生成
print("\n示例8: 独立运行步骤14 - 分布图生成")
try:
distribution_map = pipeline.step9_generate_distribution_map(
distribution_map = pipeline.step14_distribution_map(
prediction_csv_path="path/to/prediction_results.csv",
boundary_shp_path="path/to/boundary.shp",
skip_dependency_check=True
)
print(f"分布图: {distribution_map}")
except Exception as e:
print(f"步骤9失败: {e}")
print(f"步骤14失败: {e}")
print("\n" + "="*80)
print("独立步骤运行示例完成")