HydroPilot

SWAT+

SWAT+

这一页展示的是 SWAT+ 在 HydroPilot 里的典型模型路径,也就是怎样把 SWAT+ 工程、calibration.cal 写参与输出提取组织成一条可重复评估的运行链。

它重点强调什么

  • 面向模板的模型支持
  • SWAT+ 专属的参数写入链路
  • 用于率定和评估的模型输出提取

什么情况下适合用 SWAT+ 这条线

如果你的项目符合下面这些条件,就更适合采用这条线:

  • 目标工程是 SWAT+,而不是 SWAT 2012
  • 参数更新需要走 SWAT+ 的 calibration.cal 路线
  • 运行时元数据需要从 file.ciotime.simprint.prthru-data.hru 等文件中发现
  • 你希望 HydroPilot 能理解 SWAT+ 对象类型和过滤边界

典型配置形态

这条路径通常从 version: swatplus 开始:

yaml
version: swatplus
basic:
  projectPath: ./TxtInOut
  workPath: ./work
  command: swatplus.exe

HydroPilot 会把这份模板配置展开成通用配置,但参数写入的核心仍然是自动生成的 calibration.cal 记录,而不是在运行时直接修改多个源文件。

它和 SWAT 2012 为什么不同

SWAT+ 的工程结构和参数写入策略都不同,所以 HydroPilot 需要模型感知的处理方式,而不是简单复用 SWAT 2012 的路径。

放到实际项目里看,SWAT+ 这条线的难点并不是“有没有配置文件”,而是:

  • 参数写入不再只是改几个传统 SWAT 文本文件
  • 输出文件组织和对象体系都不一样
  • 参数过滤和 calibration targeting 的语义更复杂

所以这一页更适合拿来建立整体认知,而不是照着复制一份配置就结束。

HydroPilot 目前已经提供了什么

当前 SWAT+ 这一块已经覆盖了几层关键能力:

  • 独立的模板展开
  • 基于真实 SWAT+ 文件的工程发现
  • 针对部分参数组的参数数据库支持
  • 基于 calibration.cal 的参数写入
  • 常见输出频率下的一级流量序列提取

如果从“能不能支撑真实项目起步”这个角度看,当前最有价值的能力是:

  • 你已经可以围绕 version: swatplus 搭起一条完整运行链
  • 你可以把参数写入统一收敛到 calibration.cal
  • 你可以从常见 SWAT+ 输出文件里抽取一批关键流量序列

最小配置形态

yaml
version: swatplus
basic:
  projectPath: ./TxtInOut
  workPath: ./work
  command: swatplus.exe

parameters:
  design:
    - name: surq_lag
      bounds: [0.05, 24.0]
    - name: esco
      bounds: [0.0, 1.0]
  physical:
    - name: surq_lag
      mode: v
    - name: esco
      mode: v

这代表了 SWAT+ 支持路径最常见的起始形态,真实配置仍然需要补上 series 和评估定义。

一个完整的 SWAT+ 项目配置,通常还会继续补上:

  • series:从 basin_wb_*hydout_*channel_sd_* 中读取模拟结果
  • obs:观测文件及其行列位置
  • functions / derived / objectives:把模拟结果接成真正的评价指标

从用户角度看,最直接的好处是:你可以更多地按参数名和支持的过滤条件思考,而不是手工去改多个 SWAT+ 文件。

更适合怎样的推进方式

对 SWAT+ 项目来说,更稳妥的做法通常不是“一步到位配完整率定”,而是分三步走:

  1. 先确认模板能正确发现工程结构
  2. 再确认 calibration.cal 写入和 series 提取是通的
  3. 最后再把目标函数、重复评估和优化流程接上去

这比直接把所有东西一次性写满要稳得多。

当前边界

这条线已经可用,但限制确实比成熟的 SWAT 2012 支持更多。

已知边界包括:

  • 不同参数组的过滤能力不完全一致
  • 某些选择器目前仍然是精确匹配
  • 更丰富的 calibration condition 语法还没完全覆盖
  • 还需要更多真实工程验证

在中文语境下可以把它理解为:

  • 这条线已经够你开始做事
  • 但它还不适合被描述成“SWAT+ 所有情况都已经完全覆盖”
  • 真正复杂的 SWAT+ calibration targeting 仍然要谨慎推进

这一页对应的能力目前支持什么

  • 面向 SWAT+ 的工程发现
  • 通过 calibration.cal 写参数
  • 按参数组进行的部分过滤处理
  • 常见流量序列提取模式

一个更像真实项目的使用场景

比较典型的 SWAT+ 使用方式往往是这样的:

  1. 先从流量相关序列入手,而不是一开始就上复杂水质指标
  2. 先选少量关键参数,例如 surq_lagesco
  3. hydropilot-validatehydropilot-test 确认工程结构、输出提取和参数写入都正常
  4. 再决定要不要通过 UQPyLAdapter 挂到优化流程上

如果这四步跑通了,说明你的 SWAT+ 工程已经具备向更复杂场景扩展的基础。

完整工作流示例:先做流量率定,再接 UQPyL

如果你希望这一页不只是说明“SWAT+ 支持到什么程度”,而是能直接映射到真实项目,一个比较合理的完整工作流可以这样组织:

  1. 先用 version: swatplus 定义工程路径和基本运行命令
  2. 选少量关键参数,通过 calibration.cal 管理参数写入
  3. channel_sd_*hydout_*basin_wb_* 中提取流量序列
  4. 对接观测值,先构造单目标评价函数
  5. 先用 hydropilot-validatehydropilot-test 打通运行链
  6. 最后再把同一份配置交给 UQPyLAdapter

在真实项目里,这种顺序比一开始就堆多参数、多对象和多目标要稳得多。

一份可继续扩展的基础配置

yaml
version: swatplus

basic:
  projectPath: ./TxtInOut
  workPath: ./work
  command: swatplus.exe

parameters:
  design:
    - name: surq_lag
      bounds: [0.05, 24.0]
    - name: esco
      bounds: [0.0, 1.0]
    - name: epco
      bounds: [0.0, 1.0]
  physical:
    - name: surq_lag
      mode: v
    - name: esco
      mode: v
    - name: epco
      mode: v

series:
  - id: flow
    sim:
      file: channel_sd_day.csv
      id: 33
      variable: flo_out
      period: [2012, 2016]
    obs:
      file: obs_flow_day.csv
      rowRanges:
        - [1, 1826]
      colNum: 1

functions:
  - name: NSE
    kind: builtin

derived:
  - id: nse_flow
    call:
      func: NSE
      args: [flow.sim, flow.obs]

objectives:
  - id: obj_nse
    ref: nse_flow
    sense: max

这份配置的重点不在于字段名必须和你的工程完全一致,而在于它说明了 SWAT+ 这条线最关键的三件事:

  • 参数写入仍然通过模板层和 calibration.cal 管理
  • 模拟序列提取要围绕 SWAT+ 的输出文件体系来定义
  • 一旦 seriesobjectives 成形,这个工程就可以被当成可重复评估的问题

更推荐的落地顺序

对 SWAT+ 来说,真正稳妥的推进顺序通常是:

  1. 先只保留 2 到 3 个参数,确认 calibration.cal 写入无误
  2. 只抽一条最关键的流量序列,确认输出文件与观测值对齐
  3. 先做单目标 NSERMSE
  4. 运行 hydropilot-validate
  5. 运行 hydropilot-test
  6. 确认单次运行稳定之后,再交给 UQPyL 做批量搜索

这里最容易被忽略的一点是:SWAT+ 真正的复杂度往往不在优化器,而在参数 targeting 和输出提取是否已经定义清楚。

和 UQPyL 怎么接

只要前面的配置已经能稳定完成校验、写参和单次评估,就可以直接通过 UQPyLAdapter 包装成 UQPyL 问题:

python
from hydropilot.integrations import UQPyLAdapter

with UQPyLAdapter("my_swatplus.yaml") as problem:
    print(problem.nInput)
    print(problem.lb)
    print(problem.ub)

接下来就可以按 UQPyL 的标准问题接口继续往下做,例如:

  • GA 做单目标率定
  • NSGAII 做多目标率定
  • 先做 Morris 或 Sobol 敏感性分析,再缩小参数范围

也就是说,SWAT+ 这条线完全可以不止停留在“模板支持”,而是能继续向完整的率定与分析工作流推进。

这一页更适合承接哪些扩展

如果你后面还要继续把内容做深,最自然的扩展方向通常有三类:

从单站流量扩展到多序列目标

例如同时考虑多个断面流量,或者把总径流和基流指标一起接进 derived / objectives

从单目标率定扩展到敏感性分析

如果你还不确定哪些参数最值得率定,可以先把这份 SWAT+ 配置接到 UQPyL 的敏感性分析模块,先筛掉低敏感参数,再进入优化。

从基础流量扩展到更复杂输出

例如在流量跑通之后,再补土壤水、蒸散发或水质相关输出,但这一步最好建立在前面的输出提取已经完全稳定的基础上。

建议的第一步

更稳妥的理解方式是,把它看作“一条已经可用、但仍在持续完善的路径”:

  1. 先从 SWAT+ 模板结构起步
  2. 尽早校验配置
  3. 先确认真实工程能完整跑通一次
  4. 再考虑是否接入 UQPyL 做重复搜索

所以更准确的定位是:这条线已经具备实用价值,尤其适合那些正好落在当前已支持参数组和输出范围内的项目。

和 UQPyL 的连接点

只要一份 SWAT+ 配置已经能在 HydroPilot 里完成校验和运行,就可以进一步通过 UQPyLAdapter 接到 UQPyL。这样 SWAT+ 文件处理仍然留在 HydroPilot,优化逻辑则交给 UQPyL。

建议继续阅读