NWPC笔记:为GRAPES_MESO v5.0后处理增加冷启动数据支持
两周前我将文章《NWPC笔记:GRAPES_MESO v5.0 后处理系统运行报告》作为 GRAPES_MESO v5.0 后处理系统升级工作完结的纪念。
可惜我还是太乐观了:
系统更新工作永远没有尽头。
作为数值预报业务系统的建设人员,尤其是变更频繁的后处理系统的建设人员,我一直尽可能保持系统的灵活性,提高系统变更的效率。
本文介绍最近几天更新的 GRAPES_MESO v5.0 后处理系统,支持包括冷启的多种数据组合。
需求
GRAPES_MESO v5.0 系统包含两个冷启动时次(00和12)和八个暖启动时次(00,03,06,09,12,15,18,21),每个时次都有 36 小时预报。
在业务化评审时,后处理产品均来自八个暖启动时次。 但因为某些原因,单位计划用冷启动时次的数据制作 00 和 12 两个时次的产品。
虽然针对特定的时次在脚本中直接修改比较容易,但为了应对后续可能的需求,还是应该从灵活性上入手,让后处理系统可以适应多样的需求。
比如,后续可能会再次使用暖启动数据制作 00 和 12 两个时次的产品; 或者全部 10 个时次的产品都需要生成。
为了实现冷暖启动的灵活组合,需要在现有系统基础上增加新的机制,仅通过需要修改配置信息就可以实现数据的切换。
现状
目前系统使用如下的字段对象配置时次信息:
{
"00": {
"time": "07:00",
"forecast_type": "36h",
},
"03": {
"time": "09:00",
"forecast_type": "36h",
},
}
字典中的每个顶层 key 代表一个时次,会在系统中添加以该 key 名称命名的时次 family。
该 family 会添加 HH
变量,值为 key 名称,代表时次,会被用于构造产品目录、名称等一系列任务。
任务脚本中会使用 HH
构造形如 YYYYMMDDHH
的变量,用于创建运行目录。
在现有的方案中,如果同时制作冷启动和暖启动两个时次,key 名会有重复,无法实现。 所以需要添加额外的信息。
方案
首先需要添加时次类型信息(cycle_type
),表示暖启动(warm
)或冷启动(cold
)。
为了避免 family 名称重复,添加 family 名称字段(cycle_label
)。
这样 key 名称与实际的 famliy 名称不再相关。
添加额外的时次变量(HH
),并设置到 family 节点。这样,不同的 family 可以有相同的时次变量值。
添加控制是否绘图的标识(enable_graph
),如果设置为 True
,则添加绘图任务。
运行目录不再与 HH
相关,而是改为使用 family 名称字段。修改后的运行目录如下:
${ECF_DATE}${CYCLE_LABEL}
使用到外部数据的脚本(例如用于检测数据的 initial.ecf 脚本),会根据 CYCLE_LABEL
时次类型,设置相应的数据查找类型(data_type
),不同时次类型的数据在 nwpc-data-client 工具中使用不同的配置文件。
这样,仅需要在系统配置对象中修改相应的设置,就可以任意组合数据。
实现
配置对象
配置对象示例:
start_hour_config = {
"00": {
"HH": "00",
"cycle_label": "00",
"time": "07:00",
"forecast_type": "36h",
"cycle_type": "warm",
"enable_graph": True,
},
"00_cold": {
"HH": "00",
"cycle_label": "00_cold",
"time": "07:20",
"forecast_type": "36h",
"cycle_type": "cold",
"enable_graph": False,
},
# ...skip...
}
流程
构建单个时次的流程时,添加 HH
和 CYCLE_LABEL
变量。
并根据 self.config["enable_graph"]
决定是否添加绘图任务。
with Family(self.name) as fm_one_cycle:
fm_one_cycle.add_variable('HH', self.config["HH"])
fm_one_cycle.add_variable('CYCLE_LABEL', self.config["cycle_label"])
fm_one_cycle.add_variable(self.attrs)
fm_one_cycle.add_variable(common.lljob_s())
with self.initial() as tk_initial:
fm_one_cycle.add_task(tk_initial)
with self.togrib2() as fm_togrib2:
fm_one_cycle.add_family(fm_togrib2)
if self.config["enable_graph"]:
with self.tograph() as fm_tograph:
fm_one_cycle.add_family(fm_tograph)
运行目录
使用 CYCLE_LABEL
构建运行目录
CYCLE_TYPE=%CYCLE_TYPE%
CYCLE_LABEL=%CYCLE_LABEL%
COMPONENT_NAME=%COMPONENT_NAME%
RUN_BASE_DIR=${DATA_BASE}/${ECF_DATE}${CYCLE_LABEL}/${COMPONENT_NAME}
数据类型
冷启动和暖启动使用不同的配置文件
if [[ "${CYCLE_TYPE}" == "cold" ]]; then
data_type="grapes_meso_3km.2020/bin/postvar.cold"
elif [[ "${CYCLE_TYPE}" == "warm" ]]; then
data_type="grapes_meso_3km.2020/bin/postvar"
fi
对于数据检查程序,其他参数完全一致
seq 0 ${FORECAST_LENGTH} |
awk '{b=$1"h"; print b}' |
${data_chekcer_bin} local \
--data-config-dir=${data_client_config_dir} \
--location-level=${data_client_location_level} \
--data-type=${data_type} \
--max-check-count=${max_check_count} \
--check-interval="${sleep_seconds_for_check}s" \
--delay-time "${sleep_seconds_for_next_time}s" \
--execute-command "$(which ecflow_client) --event grapes_postvar_{.Forecast}" \
${START_TIME}
归档目录
冷启动和暖启动使用不同的归档根目录
if [[ "${CYCLE_TYPE}" == "cold" ]]; then
ARCHIVE_BASE=/g11/nwp_ex/GRAPES_MESO_3KM_cold
elif [[ "${CYCLE_TYPE}" == "warm" ]]; then
ARCHIVE_BASE=/g11/nwp_ex/GRAPES_MESO_3KM
fi
效果
下图为全部 10 个时次生成数据产品,但仅有暖启时次生成图片产品。
局限
尚未处理产品分发问题,需要为时次配置对象中添加额外字段,比如为时次添加 attrs
属性,设置上传标识,覆盖默认标识。
当前方案需要同时修改系统定义的 Python 文件、include 文件和 ecf 任务脚本文件。 这基本覆盖业务系统灵活性的三种实现方式。 后续可以考虑将类似的条件判断均放到系统定义中来实现,毕竟 Python 提供更加完备的编程语言机制。