爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 13873|回复: 26

GRIB格式转为ARL格式

[复制链接]

新浪微博达人勋

发表于 2013-1-2 13:35:23 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
MeteoInfo支持多种气象数据格式,比如netCDF, GRIB 1&2, ARL等,但是缺乏写ARL数据的能力,因此最近做了一些这方面的工作,有了一些初步结果,还需要进一步完善。ARL格式用HYSPLIT模式的人应该比较清楚。需要MeteoInfo最新文件(见置顶帖子)。

转换需要写脚本来完成。测试了一个FNL的GRIB2数据,转换后的ARL和原GRIB2数据是吻合的,当然还需要更多的测试。

Image00957.png
Image00958.png

示例脚本代码如下:
  1. #--------------------------------------------------------        
  2. # Author: Yaqiang Wang                                          
  3. # Date: 2012-12-31                                               
  4. # Purpose: Convert GRIB data to ARL data  
  5. # Note: Sample                                                   
  6. #-----------------------------------------------------------
  7. import clr
  8. from System import *
  9. from System.Collections.Generic import *
  10. clr.AddReference("MeteoInfoC.dll")
  11. from MeteoInfoC import *
  12. from MeteoInfoC.Data import *
  13. from MeteoInfoC.Data.MeteoData import *

  14. #---- Set directories
  15. dataDir = "D:\\Temp\\"

  16. #---- Set output data file
  17. outFile = dataDir + 'arl\\test1.arl'

  18. #---- Read a GRIB data file
  19. mydata = MeteoDataInfo()
  20. infile = dataDir + 'grib\\fnl_20110416_00_00'
  21. mydata.OpenGRIBData(infile)

  22. #---- Set output ARL data info
  23. arlDI = ARLDataInfo()

  24. #---- Set variable and level list
  25. gvars = ['Pressure@surface','Temperature@height_above_ground',\
  26.     'U-component_of_wind@height_above_ground','V-component_of_wind@height_above_ground',\
  27.     'Total_precipitation@surface','Geopotential_height@pressure','Temperature@pressure',\
  28.     'U-component_of_wind@pressure','V-component_of_wind@pressure','Vertical_velocity@pressure',\
  29.     'Relative_humidity@pressure']
  30. avars = ['PRSS','T02M','U10M','V10M','TPP6','HGTS','TEMP','UWND','VWND','WWND','RELH']
  31. levels = [0,10,20,30,50,70,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,\
  32.     850,900,925,950,975,1000]
  33. for l in levels:
  34.     arlDI.levels.Add(l)
  35.     if l == 0:
  36.         arlDI.LevelVarList.Add(List[str](['PRSS','T02M','U10M','V10M','TPP6']))
  37.     elif l < 100:
  38.         arlDI.LevelVarList.Add(List[str](['HGTS','TEMP','UWND','VWND']))
  39.     else:
  40.         arlDI.LevelVarList.Add(List[str](['HGTS','TEMP','UWND','VWND','WWND','RELH']))

  41. #---- Write ARL data file
  42. arlDI.CreateDataFile(outFile)
  43. arlDI.X = mydata.GetX()
  44. arlDI.Y = mydata.GetY()
  45. variables = mydata.GetVariables()
  46. tNum = mydata.GetTimeNumber()
  47. for t in range(0, tNum):
  48.     mydata.TimeIndex = t
  49.     atime = mydata.GetTime(t)
  50.     print atime.ToString("yyyy-MM-dd HH")
  51.     aDH = arlDI.GetDataHead(mydata.ProjInfo, 'FNL1', 2)
  52.     arlDI.WriteIndexRecord(atime, aDH)
  53.     lidx = 0
  54.     for l in arlDI.levels:
  55.         print l
  56.         for v in arlDI.LevelVarList[lidx]:
  57.             vName = gvars[avars.index(v)]
  58.             print vName
  59.             if lidx == 0:
  60.                 mydata.LevelIndex = lidx
  61.             else:
  62.                 variable = mydata.GetVariable(vName)
  63.                 nlidx = variable.Levels.IndexOf(l)
  64.                 mydata.LevelIndex = nlidx
  65.             gData = mydata.GetGridData(vName)
  66.             aDL = DataLabel(atime)
  67.             aDL.Level = lidx
  68.             aDL.Variable = v
  69.             aDL.Grid = 99
  70.             aDL.Forecast = 0
  71.             arlDI.WriteGridData(aDL, gData)
  72.         lidx += 1

  73. arlDI.CloseDataFile()

  74. print 'Finished!'




密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-2 14:03:20 | 显示全部楼层
王老师过节还不休息啊...
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-2 14:53:07 | 显示全部楼层
好好向王老师学习
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-2 19:38:01 | 显示全部楼层
赞, 很实用的
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-2 20:23:33 | 显示全部楼层
谢谢楼主啦
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-5 13:40:40 | 显示全部楼层
具体在格式转化时可以先在MeteoInfo中打开GRIB数据,并查看其变量信息,选择某变量可以查看其分层信息,这些信息可以用于script程序中。ARL数据的变量信息可以在ARL官方网站上查找。
Image00311.png
Image00312.png

具体转换时还需要考虑GRIB和ARL数据中相应变量可能单位不同,比如此例中GRIB气压数据的单位是Pa,而ARL中是hPa,在写格点数据前需要先进行单位变换的计算,修改后的代码和图形如下:
  1. #--------------------------------------------------------        
  2. # Author: Yaqiang Wang                                          
  3. # Date: 2012-12-31                                               
  4. # Purpose: Convert GRIB data to ARL data  
  5. # Note: Sample                                                   
  6. #-----------------------------------------------------------
  7. import clr
  8. from System import *
  9. from System.Collections.Generic import *
  10. clr.AddReference("MeteoInfoC.dll")
  11. from MeteoInfoC import *
  12. from MeteoInfoC.Data import *
  13. from MeteoInfoC.Data.MeteoData import *

  14. #---- Set directories
  15. dataDir = "D:\\Temp\\"

  16. #---- Set output data file
  17. outFile = dataDir + 'arl\\test1.arl'

  18. #---- Read a GRIB data file
  19. mydata = MeteoDataInfo()
  20. infile = dataDir + 'grib\\fnl_20110416_00_00'
  21. mydata.OpenGRIBData(infile)

  22. #---- Set output ARL data info
  23. arlDI = ARLDataInfo()

  24. #---- Set variable and level list
  25. gvars = ['Pressure@surface','Temperature@height_above_ground',\
  26.     'U-component_of_wind@height_above_ground','V-component_of_wind@height_above_ground',\
  27.     'Total_precipitation@surface','Geopotential_height@pressure','Temperature@pressure',\
  28.     'U-component_of_wind@pressure','V-component_of_wind@pressure','Vertical_velocity@pressure',\
  29.     'Relative_humidity@pressure']
  30. avars = ['PRSS','T02M','U10M','V10M','TPP6','HGTS','TEMP','UWND','VWND','WWND','RELH']
  31. levels = [0,10,20,30,50,70,100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,\
  32.     850,900,925,950,975,1000]
  33. for l in levels:
  34.     arlDI.levels.Add(l)
  35.     if l == 0:
  36.         arlDI.LevelVarList.Add(List[str](['PRSS','T02M','U10M','V10M','TPP6']))
  37.     elif l < 100:
  38.         arlDI.LevelVarList.Add(List[str](['HGTS','TEMP','UWND','VWND']))
  39.     else:
  40.         arlDI.LevelVarList.Add(List[str](['HGTS','TEMP','UWND','VWND','WWND','RELH']))

  41. #---- Write ARL data file
  42. arlDI.CreateDataFile(outFile)
  43. arlDI.X = mydata.GetX()
  44. arlDI.Y = mydata.GetY()
  45. variables = mydata.GetVariables()
  46. tNum = mydata.GetTimeNumber()
  47. for t in range(0, tNum):
  48.     mydata.TimeIndex = t
  49.     atime = mydata.GetTime(t)
  50.     print atime.ToString("yyyy-MM-dd HH")
  51.     aDH = arlDI.GetDataHead(mydata.ProjInfo, 'FNL1', 2)
  52.     arlDI.WriteIndexRecord(atime, aDH)
  53.     lidx = 0
  54.     for l in arlDI.levels:
  55.         print l
  56.         for v in arlDI.LevelVarList[lidx]:
  57.             vName = gvars[avars.index(v)]
  58.             print vName
  59.             if lidx == 0:
  60.                 mydata.LevelIndex = lidx
  61.             else:
  62.                 variable = mydata.GetVariable(vName)
  63.                 nlidx = variable.Levels.IndexOf(l)
  64.                 mydata.LevelIndex = nlidx
  65.             gData = mydata.GetGridData(vName)
  66.             if v == 'PRSS' or v == 'WWND':
  67.                 gData = gData / 100
  68.             elif v == 'TPP6':
  69.                 gData = gData / 1000
  70.             aDL = DataLabel(atime)
  71.             aDL.Level = lidx
  72.             aDL.Variable = v
  73.             aDL.Grid = 99
  74.             aDL.Forecast = 0
  75.             arlDI.WriteGridData(aDL, gData)
  76.         lidx += 1

  77. arlDI.CloseDataFile()

  78. print 'Finished!'


Image00313.png

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-8 18:37:05 | 显示全部楼层
王老师,提取ARL数据写成新的ARL数据应该也差不多吧?直接改这个script行不行?

比如说我想提取GDAP0P5数据的单数层,然后再写成一个新的ARL文件,是不是在levels=[]里把需要的层次列出来写到新的文件里就可以了?

还有就是GDAS0P5文件垂直方向是气压-sigma混合坐标,在读取的时候是不是还是跟读气压坐标的数据是一样的?
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-8 20:04:25 | 显示全部楼层

应该是可以的,你需要试试。注意Level循环时的处理。

如果原数据是混合坐标,那么提取的数据也是一样的。改变垂直坐标需要垂直插值,目前MeteoInfo里还没有现成的函数,在脚本里做应该也是可以的,不过估计比较繁琐。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2013-1-14 20:31:03 | 显示全部楼层
MeteoInfo 发表于 2013-1-8 20:04
应该是可以的,你需要试试。注意Level循环时的处理。

如果原数据是混合坐标,那么提取的数据也是一样的 ...

王老师,我改好了script,运行也没问题,可是生成的ARL文件meteoinfo不能打开,提示‘input string was not a correct format’,不知道是什么原因?

另外,改写ARL数据还有个问题,ARL数据的地面层标题不是数字,是用Surface来标记的,这种情况怎么在level循环里把地面层的数据写进新的ARL文件里?

附件里是我的script,麻烦您帮忙看一下。

arlextract.py (3.71 KB, 下载次数: 6)
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2013-1-15 09:42:28 | 显示全部楼层
dolces 发表于 2013-1-14 20:31
王老师,我改好了script,运行也没问题,可是生成的ARL文件meteoinfo不能打开,提示‘input string was n ...

我下载一个0.5度的数据试试吧。
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表