尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

WRF前处理实战:为JRA55数据定制Vtable避坑指南

WRF前处理实战:为JRA55数据定制Vtable避坑指南 1. 先说清楚Vtable到底是什么为什么JRA55会踩坑气象建模这行做了快十年我见过太多人在WRF前处理这一关卡住。模型装好了、namelist写完了结果ungrib一跑就报错日志里一堆Unknown parameter或者变量名对不上最后排查半天发现是Vtable的问题。尤其是JRA55数据明明是个公开再分析资料偏偏每次用都能折腾出点新花样所以这次专门聊聊怎么给JRA55这类非标准数据定制Vtable。WRF前处理流程是固定的geogrid生成静态地形ungrib把气象场从GRIB格式提取成中间格式metgrid把气象场插值到模拟域网格上。ungrib本身不关心数据是ECMWF还是NCEP还是JRA55它靠的是Vtable这张对照表来搞明白GRIB文件里每一个变量是什么、单位是什么、需不需要处理。换句话说Vtable就是ungrib的字典你得告诉它第几个变量是对应的什么物理量。JRA55是日本气象厅做的长期再分析产品时间跨度从1958年到现在分辨率虽然不比ERA5精致但胜在时间长、资料稳定做气候尺度的模拟或者长时段个例研究非常好用。问题是它的变量组织方式、GRIB编码规则、字段划分和WRF官方自带的Vtable里那些常见数据源比如FNL、GFS、ERA5有差异。官方Vtable里没有完全对应的映射规则你就得自己写。这文章适合谁看手上拿着JRA55数据想跑通WRF但卡在ungrib阶段的人以及那些拿到任何非标准气象数据比如某个机构自定义的GRIB产品、模式输出的后处理场就不知道怎么下手的人。看完你会明白Vtable的工作机制掌握诊断数据的方法最后能自己写出一个可用的Vtable并知道怎么验证它跑得对不对。1.1 WRF前处理链路里Vtable扮演的角色先把链路理清楚。WRF的输入数据细分为三大步ungrib、geogrid、metgrid。geogrid负责地形和土地利用这一步和气象数据没关系。ungrib负责把GRIB格式的原始气象场就是那些气压层上的温度、湿度、风场以及地表温度、土壤湿度、海表温度等转换成中间格式。metgrid再把这些中间格式的场水平插值到你要模拟的区域网格上垂直方向保持不变。ungrib读GRIB文件时并不去理解里面每个变量的物理意义。GRIB文件本质上是打包好的二进制段record每个record有对应的参数编码但ungrib拿到这些编码之后不知道该把它当什么用。Vtable的作用就是把GRIB record里每个参数的编码映射到WRF需要的标准变量名上并告诉ungrib这个变量的单位是什么、垂直坐标是哪种类型、需不需要特殊的换算。举个直白例子GRIB里有一条记录参数表编号告诉你它是温度在气压层上。Vtable里对应一行写着TMPpressureK表示把这条记录当成开尔文温度放在气压层上。ungrib看到之后才敢把这个变量写进中间文件。如果没有这一行它会直接跳过或者报错。所以Vtable不仅是变量名翻译器它还控制了三件事变量映射GRIB编码对应哪个WRF变量、垂直坐标处理是气压层、高度层还是地面、单位转换与物理处理要不要从位势高度转为几何高度等。这三件事恰恰是定制Vtable时最容易出错的地方。1.2 标准JRA55能跑为什么还要定制Vtable回到JRA55本身。JRA55官网发布的原始数据分几大类气压层资料、地面资料、通量资料、土壤资料还有3小时和6小时间隔的版本。如果从JMA官网下载原始GRIB格式按官方说明选好字段其实存在可以勉强用的Vtable映射网上也能找到别人分享的版本。但实际项目里你拿到的JRA55往往不够标准。这几种情况我都遇到过大家自己对号入座数据被加工过比如有人把JRA55的GRIB格式转成了NetCDF再用工具转回GRIB参数编码表已经被改写了原始编码信息可能丢失或错位。混合了多个来源同一个模拟时段的气象场气压层用的是JRA55地表场用的是另一个产品两套GRIB编码混在一起。选择了非常规变量JRA55提供了一些附加变量比如云水、雨混合比、不同高度的温度官方Vtable没有映射你需要自己定义。改过分辨率或投影JRA55原始是约55km的网格有人做了降尺度到0.5度甚至更细数据本身还是GRIB格式但文件头信息可能有变化。GRIB版本差异JRA55早期产品大量使用GRIB1编码新版部分字段是GRIB2两者的参数编码规则完全不同。Vtable的写法也要跟着改。我遇到最典型的场景是组里做长时段降尺度模拟下载了JRA55的3小时气压层资料结果发现表面气压字段在某个时间段之前用的是GRIB1编码之后换成了GRIB2编码。直接用网上找的Vtable跑前半段正常后半段报错排查了很久才发现是数据源内部编码不统一。这种问题只能靠定制Vtable并且针对不同时段准备两份映射。2. 动手之前先诊断你的JRA55数据到底非标在哪我第一次定制Vtable时走了弯路拿着GRIB文件用各种工具一顿翻还是没头绪。后来总结出一套固定诊断流程先花20分钟把数据摸清楚再动手写Vtable成功率极高。这一步千万别跳过你连数据里有什么都不知道写出来的Vtable只能是靠猜。2.1 用wgrib2把家底盘清楚诊断GRIB文件最顺手的工具就是wgrib2NCEP出品几乎所有气象数据处理环境里都能装上。它的作用是把GRIB2文件里的每个record列出来显示参数编号、层次、时间、网格信息。如果是GRIB1文件用wgrib不带2的版本来看。基本操作思路是这样的先列文件全貌再按变量归类最后检查关键字段。# 如果是GRIB2格式 wgrib2 jra55_pressure_2024010100.grib2 # 如果是GRIB1格式 wgrib -V jra55_pressure_2024010100.grib # 只看特定变量比如温度 wgrib2 jra55_pressure_2024010100.grib2 | grep TMP # 看某个变量在哪些气压层上有数据 wgrib2 jra55_pressure_2024010100.grib2 | grep TMP | grep : | head -20输出会包含每个record的关键信息。以GRIB2为例典型的一行长这样1:0:d2024010100:TMP:pressure:1000 mb:anl:这表示第1条记录起始字节位置0数据时间2024年1月1日00时变量TMP在1000hPa气压层分析场。wgrib2还会显示变量的GRIB2参数编号这是定制Vtable时最关键的信息大概长这样1:0:d2024010100:TMP:pressure:1000 mb:anl:PARAM0:2:0末尾的0:2:0就是GRIB2的discipline、category、number三个编号。后文会详细讲它是怎么对应Vtable的。除了变量清单还要确认网格信息。同一份数据的水平网格必须一致否则metgrid插值时网格不匹配一样跑不过。用wgrib2 -grid看网格描述确认是经纬度网格还是高斯网格纬度是均匀的还是高斯纬度。wgrib2 jra55_pressure_2024010100.grib2 -grid这一步如果你看到网格描述是lat-lon grid说明是规整经纬度网格WRF处理起来最省心。如果看到的是gaussian gridungrib也能读但插值时会多一步稍麻烦。其实JRA55官方发布的基本都是规整经纬度网格但某些转手过的版本会把网格定义改掉所以这一步别省。2.2 关键字段缺一不可对照清单检查诊断的目的不是把每个变量都看一遍而是弄清楚WRF跑起来必需的变量到底有没有有的话编码是多少。干这事最靠谱的是把WRF官方的Vtable.ERA-interim.pl或者Vtable.GFS打开对照着查。WRF需要的基本变量就那些三维气压层变量位势高度HGT、温度TMP、相对湿度RH、U风UGRD、V风VGRD有的方案还需要水汽混合比、云水混合比等。二维地面变量地表气压PRES、2米温度、2米相对湿度、10米U/V风、地表温度SKINTEMP、土壤温度SOILTMP是多层、土壤湿度SOILM是多层、积雪深度SNOW、海表温度SST、海平面气压PRMSL、反照率等。部分物理方案需要的额外变量植被覆盖度、叶面积指数、糙率长度等。拿着wgrib2的输出对照这个清单把找到的变量列一个草表格式大概可以是WRF变量名JRA55数据中对应的GRIB参数层次单位备注HGTGRIB2 3:0:0气压层gpm需要确认是位势米还是几何米TMPGRIB2 0:0:0气压层K正常开尔文RH需搜索气压层%JRA55可能给相对湿度也可能给露点UGRDGRIB2 0:2:2气压层m/s确认是U还是V别搞反这一步的关键在于不要假设变量名和数据存在性。JRA55不同版本之间、不同变量子集之间差异很大。我遇到过JRA55的资料里相对湿度不是直接给出而是给出露点温度你得在Vtable里用露点温度变量或者在ungrib之后用一个额外的脚本做换算。这些都是在诊断阶段就该发现的等跑起来才发现就晚了。另一个在诊断阶段要确认的事是垂直坐标的类型。GRIB文件里的气压层资料可能是等压面pressure也可能有等位温面、模式层等。WRF的标准中间格式对等压面处理最成熟如果JRA55数据里有等模式层数据Vtable里需要标注坐标类型为model_level这往往会导致ungrib处理复杂不少。所以一般来说做WRF模拟优先选等压面资料。诊断完毕基本心里有数了有哪些变量、各自什么编码、什么层次、什么单位、缺什么。接下来就是动手写Vtable的时刻。3. 手把手定制Vtable从模板到验证的完整过程定制Vtable核心原则是宁可少映射不可错映射。少映射顶多是某个变量在中间文件里没有后处理时缺个东西错映射是温度当成位势高度跑出来的结果整个废掉而且废得很隐蔽不在ungrib阶段报错在模式积分阶段才爆炸到那时排查代价极高。下面我按实操顺序把每一个环节拆开讲。3.1 准备工作选对基础模板不要从零写Vtable。WRF的WPS安装目录里有几十个Vtable模板选一个和JRA55最接近的开始改能省大量时间。放Vtable的位置一般在WPS/ungrib/Variable_Tables/目录下。常见的模板包括Vtable.GFS、Vtable.ERA-interim.pl、Vtable.NCEP_RUC等。地面资料选一个高空资料选一个。两个模板并行的原因是ungrib运行时分两步第一步处理高空气压层资料第二步处理地面资料或者你可以用两个链接分别指向不同Vtable。选模板的优先级我是这样排的如果JRA55数据来自官方优先试Vtable.ERA-interim.pl因为JRA55和ERA-interim的变量组织逻辑非常相似都是再分析产品变量命名习惯接近。如果走了Vtable.JRA55——有些新版WPS确实带了Vtable.JRA55——先用它这是官方适配过的能跑就不要自己改。如果都没有退而求其次用Vtable.GFS然后手动改差异部分。实际操作中我会同时打开模板和wgrib2输出一列一列核对缺的映射自己补多出的映射影响不大ungrib不会因为Vtable里多定义了变量而报错它只会按数据里实际存在的record去匹配。3.2 Vtable文件的格式逐列拆解Vtable文件本身是个纯文本格式非常固定。打开任何一个模板你会看到类似这样的结构GribID | ShortName | LevelType | FromLevel1 | FromLevel2 | ToLevel | Units | Description这是注释行真正内容是数据行。以Vtable.GFS的一行为例0 HGT pressure 100000 0 3000 gpm Height这一行信息的含义得逐列分解。第一列变量在GRIB数据里的参数编码。GRIB1和GRIB2的编码规则完全不同GRIB1用单一数字标识变量比如温度是11U风是33V风是34。GRIB2用三个数字标识分别是discipline、category、number。温度是0 0 0U风是0 2 2V风是0 2 3位势高度是3 0 0。WRF的Vtable里第一列就是这三个数字用空格分隔。如果你用的是GRIB1数据可能得写一个数字但大多数新版WPS统一用GRIB2编码格式即使是GRIB1数据ungrib内部也会先转成类似GRIB2的编码规则来匹配。第二列是WRF中间格式里的变量名缩写比如HGT、TMP、RH、UGRD、VGRD、PRES、SKINTEMP、SOILM、SOILTMP、SNOW、SST等。ungrib会把这个名字写成中间文件的变量名后面metgrid和real就是靠这个名字识别变量的。所以这一列必须用WRF认识的缩写不能自己发明。常用缩写可以从/WPS/metgrid/METGRID.TBL里查。第三列是LevelType描述变量的垂直层次类型。常见取值有pressure等压面。surface地表面即单层二维变量。height离地高度层比如2米温度。model_level模式层。isobaric部分版本用这个表示等压面效果和pressure一样。第四、五列FromLevel1和FromLevel2表示数据里这个变量对应的层次区间。对等压面来说FromLevel1是气压上限FromLevel2是气压下限单位是Pa。比如要从1000hPa到100hPa就写100000 10000。如果某个变量只在特定层有比如只有地表层这两个值填啥其实影响不大但为了规范通常写0 0。第六列ToLevel表示ungrib输出时把这个变量放在哪个标准层。对等压面这个值一般是0表示不做垂直场转换原样输出。如果你想把数据插值到WRF的eta层那是由metgrid和real控制的不是Vtable控制的。所以这一列绝大多数情况是0。第七列Units单位。ungrib会用这个单位判断需不需要做换算。例如数据明明是K但你写了Cungrib不会替你换算它只是把这个值原样写进中间文件单位的正确性全靠你人工保证。WRF内部期望的标准单位是温度K、气压Pa、风m/s、高度gpm、湿度%或kg/kg。看清楚你数据的原始单位填对。第八列Description用途是给人看的描述不影响运行但强烈建议写上方便以后自己回头查。3.3 一个实际例子从JRA55非标准数据写Vtable假设我手上拿到一份JRA55气压层资料经过wgrib2诊断里面的变量是这样的注意这个字段组合是非标准的典型位势高度GRIB2编码3 0 0在气压层上单位gpm。温度GRIB2编码0 0 0在气压层上单位K。相对湿度GRIB2编码0 1 1在气压层上单位%。U风GRIB2编码0 2 2在气压层上单位m/s。V风GRIB2编码0 2 3在气压层上单位m/s。气压层数据里还混入了一个特殊的地表气压变量编码0 0 0但LevelType是surface——这里就有坑了温度和地表气压编码相同完全靠LevelType区分。这份数据已经够非标准了因为正常的JRA55气压层资料里地表气压应该单独放在地面文件中现在混在一起你必须在Vtable里同时处理。对应的Vtable片段长这样0 HGT pressure 100000 10000 0 gpm Geopotential height 0 TMP pressure 100000 10000 0 K Temperature 0 RH pressure 100000 10000 0 % Relative humidity 0 UGRD pressure 100000 10000 0 m/s U wind 0 VGRD pressure 100000 10000 0 m/s V wind 0 PRES surface 0 0 0 Pa Surface pressure 7 HGT surface 0 0 0 gpm Surface geopotential height注意最后一行7是GRIB1里地形高度对应的编码不这里用了GRIB2编码0 7 0所以我写的是0 7 0但只写了7是为了示范简洁不行这里必须严谨。 实际写的时候第一列如果是GRIB2编码必须写全三个数字比如3 0 0 HGT pressure 100000 10000 0 gpm Geopotential height 0 0 0 TMP pressure 100000 10000 0 K Temperature 0 1 1 RH pressure 100000 10000 0 % Relative humidity 0 2 2 UGRD pressure 100000 10000 0 m/s U wind 0 2 3 VGRD pressure 100000 10000 0 m/s V wind 0 0 0 PRES surface 0 0 0 Pa Surface pressure 0 7 0 HGT surface 0 0 0 gpm Surface geopotential height这里有个非常容易踩的坑0 0 0温度是GRIB2里的编码但如果数据本身是GRIB1里面温度变量用编码11标识那么WPS的ungrib在读取时会自动把GRIB1编码转换成GRIB2兼容编码吗实际上ungrib的机制是它内部维护了GRIB1和GRIB2两套匹配逻辑Vtable里写的编码它会先去查数据的GRIB版本是什么然后分别去匹配。为了保险我在实际项目中见过两种做法如果数据是GRIB1Vtable第一列也会写GRIB1编码单一数字如果数据是GRIB2写三个数字。正常大多数情况下JRA55官方数据以GRIB1为主但2015年《JRA-55》发布时有GRIB2版本。我的建议是先用file命令或者wgrib判断数据是GRIB1还是GRIB2再决定Vtable第一列写法。如果你不确定ungrib到底怎么匹配可以直接在Vtable里同时写两个条目不行Vtable没有这种机制它只匹配第一列。所以诊断阶段就要确认数据版本。实际上WPS较新的版本4.x里无论数据是GRIB1还是GRIB2Vtable第一列都推荐按GRIB2编码来写ungrib内部会把GRIB1参数编号映射到GRIB2编号。比如GRIB1的温度11映射到GRIB2的0 0 0。这个机制我不百分百确定所有版本都成立但官方模板按GRIB2写是主流趋势。所以你直接按GRIB2写大概率没问题。无论如何write the Vtable然后看ungrib日志验证。验证是检验Vtable唯一标准。3.4 把Vtable注册进ungrib并验证Vtable写好后要放到WPS运行目录并让ungrib知道用哪个。WPS的ungrib默认读取Vtable这个文件所以实际操作是建立一个软链接cd /path/to/WPS ln -sf ungrib/Variable_Tables/Vtable.JRA55_custom Vtable然后运行ungrib。ungrib有两种方式最常用的是link_grib.csh链接所有输入GRIB文件再跑ungrib。但新版WPS推荐用ungrib.exe配合namelist.wps里的prefix参数。# 链接所有需要处理的GRIB文件 ./link_grib.csh /path/to/jra55_data/*.grib # 先转高空数据 # 在namelist.wps里设置 prefix 3D ./ungrib.exe # 再转地面数据 # 在namelist.wps里设置 prefix SFC # 注意这需要切换不同的Vtable文件 ./ungrib.exe如果只想快速验证只需先处理一个时间步的一个文件。运行完ungrib后会在目录下生成3D:2024-01-01_00这样的中间文件。中间文件是二进制的可以用ncdump或自己写个Python脚本读取但更简单的是用util/rd_intermediate.py脚本WPS自带的位于WPS/util/下python util/rd_intermediate.py 3D:2024-01-01_00输出里会列出每个变量的名字、层次、单位。重点检查三件事变量名是不是WRF认识的HGT、TMP、RH、UGRD、VGRD等。层次是不是完整的等压面序列有没有某个变量缺层。单位是不是WRF期望的标准单位。如果中间文件里的变量、层次、单位都对Vtable基本算合格。但还有最后一道坎儿把中间文件和地理静态数据交给metgrid和real跑通一个real.exe如果wrfinput_d01里的变量都齐了、初值没有明显的坏值这才算真正验证通过。4. 高频踩坑记录那些日志报错和诡异现象定制Vtable最大的问题就是ungrib不报错但结果错还有各种让人摸不着头脑的报错信息。这里把实战中最常见的问题以及排查思路整理成速查手册希望对大家有帮助。4.1 ungrib Unknown parameter类报错ungrib日志里出现类似unrecognized parameter或者unknown code table entry本质是Vtable里没有匹配到你数据里某个变量的GRIB编码。原因基本有这几类数据里确实有这个变量但你的Vtable没写这个编码。解决办法是回诊断阶段wgrib2输出里找到这条record的编码手动补一行。编码字段写错。常见是GRIB1、GRIB2搞混。确认数据版本第一列按正确格式写。数据里有坑编码的变量比如某些地表通量变量真实物理意义不明确不映射也没关系。这类变量忽略即可ungrib只是给出警告。处理策略是先分清楚必需变量和非必需变量。必需变量一个都不能少非必需变量缺失可以暂时不管等程序跑起来再说。日志里出现的warning不致命fatal才致命。如果你看到ERROR、FATAL那基本就是Vtable有硬伤。4.2 温压湿风变量名字对但不合理我最怕遇到这种ungrib跑完了中间文件有了metgrid也过了real也过了结果模拟出来是离谱的天气场。后来查来查去发现某个变量映射错了。比如JRA55数据里有露点温度DPT和位势HGT你Vtable里没写露点温度的映射于是ungrib把露点当成了相对湿度不会编码不同ungrib不会这么傻。真正容易错的是JRA55数据里温度的单位是C摄氏度但你Vtable里写了KWRF拿着C数值当K用初值温度场直接爆表。这类问题从中间文件里是完全看不出来的变量名对、层次对、数值范围不对。诊断手段是看中间文件里数值范围温度K应该在200-320之间湿度%在0-100之间气压Pa在10000-110000之间。如果超出这个区间多半就是单位没弄对。解决的办法没有捷径只能回到数据诊断阶段用wgrib2的-V参数查看每个变量的原始单位再比对你Vtable里写的单位。这一步千万别懒。4.3 网格和维度相关的问题这一条不完全是Vtable的锅但常和Vtable一起出现。ungrib出来的中间文件要交给metgridmetgrid要求你的气象场和目标模拟域有对应的维度映射。典型报错是inconsistent grid或者某个变量维度对不上。原因是JRA55数据被裁剪过比如全球场被切成了某个区域或者降尺度到新网格之后网格定义和原文件不一致。Vtable在这里无能为力你要做的是用wgrib2 -grid和geogrid的输出对比确认网格定义一致如果不一致得在namelist.wps里调整max_dom和e_we/e_sn来匹配数据网格或者用工具重新投影数据。另一个和Vtable相关的维度问题是垂直层不完整。ungrib输出的等压面层数取决于输入数据里有多少层。Vtable决定的是映射和单位不决定层数。所以如果JRA55数据只有1000、850、500hPa三层你Vtable里写1000到100hPa也没用中间文件里只有这几层。WRF要求初值场在模式层通常是30-50层上有完整覆盖所以推荐下载JRA55完整的等压面层次从1000hPa到1hPa一般有37层。如果数据下载时只选了部分层次ungrib也能跑但real阶段垂直插值会出问题。这种属于数据源准备问题不是Vtable能解决的。5. 几条实战技巧最后分享几个这几年攒下来的小经验算不上高深但确实能在关键时候救命。第一多做一步中间文件校验。每次定制完Vtable跑完ungrib不要着急往下走。花10分钟看一眼rd_intermediate.py输出确认每个变量的层数、单位、数值范围。这个习惯帮我避免过至少5次跑完三天发现初值场全是坏的的灾难。第二用最小数据验证。跑整段模拟之前先只下载或切片一个时间步的数据比如某个时次的6小时间隔数据用这份最小数据把ungrib、metgrid、real整条链路都测通。一个小文件的验证时间只要几分钟但能帮你排除掉90%的配置问题。真实跑整段模拟时时间成本极高等跑了两天发现Vtable不对再重头来心态直接崩。第三Vtable版本管理。JRA55数据的GRIB编码偶尔会随官方升级变化。拿到一份新数据即使之前Vtable跑通过也别直接就用。用wgrib2重新诊断一遍对比你手上的Vtable确认编码没变。特别是长时间跨度项目数据可能跨越了JRA55的更新版本中途编码变了你的Vtable也要相应调整。我的做法是每个Vtable文件开头都写清楚适用的时间范围和数据版本比如Vtable.JRA55_1958-2014_GRIB1和Vtable.JRA55_2015-latest_GRIB2。第四模板优先不要重复造轮子。WPS自带的模板里Vtable.ERA-interim.pl对再分析产品普适性很强JRA55、ERA5、NCEP再分析多数变量编码一眼就能对上以它为基础加加减减比从零开始写稳得多。第五如果要转的变量带有单位换算需求比如从位势高度换算成几何高度或者从比湿换算成相对湿度我的建议是宁可让ungrib原样输出再用Python脚本做后处理也别在Vtable里搞复杂转换。Vtable本来不设计做单位换算只适合做映射如果载入了换算逻辑出了问题极难排查。保持Vtable透明简单数据的事让数据处理工具去处理。JRA55做WRF模拟这件事难点从来不在WRF本身而在于气象数据的多样性和不规范性。把一个Vtable搞定你对WRF数据流的理解就上了一个台阶以后拿到再冷门的数据源都不慌了。希望这篇实战记录能帮你少踩几个坑。
返回列表