爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 10178|回复: 29

MeteoInfoLab脚本示例:计算湿位涡

[复制链接]

新浪微博达人勋

发表于 2016-8-16 23:08:57 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 MeteoInfo 于 2017-2-19 09:45 编辑

利用温度、相对湿度、风场U/V分量数据计算湿位涡。示例脚本简要说明:

1、读取数组。脚本中使用的是ARL格式的4维格点数据,数据是全球1*1度的,为了节省内存,读取4维数组时限定了经纬度范围。数组读取后可以通过数组的dimlen()方法来获取某个维的长度,用dimvalue()方法获取某个维的值的1维数组。该数据集中相对湿度(RELH)变量的高度层只有21层,而温度(TEMP)和U/V(UWND/VWND)变量的高度层有23层,在做数组运算时要求公式中所有数组的各维长度都一致,因此在读取温度和U/V数组时高度维只读到第21层和相对湿度数组一致。

2、计算涡度。利用hcurl()函数和U/V数组计算涡度。

3、构造高度层4维数组。利用dimvalue()方法获取了高度层的1维数组lev,但之后的计算中其它数组都是4维,为了匹配利用zeros()函数构造一个高度层的4维数组prs(所有值均为0)。此时的prs数组是MIArray类型,并没有各维的值的信息,因此创建一个DimArray对象加入维的详细信息。然后对高度层循环给prs数组赋值。

4、计算假相当位温。论坛里有很多帖子讨论假相当位温的计算,这里就不详细说了,公式参考GrADS脚本改写。需要注意的是计算出来的假相当位温eqt/thse是4维的。

5、计算湿位涡。湿位涡的计算也参考了GrADS脚本,由于涉及到上下层的差值,只能一层层计算。先构造一个湿位涡的4维数组mpv,再对时间维和高度维进行循环,在循环中计算2维(Y/X)湿位涡,再赋值给mpv。循环结束后4维mpv数组计算完成。

6、绘图检查计算结果。从4维mpv数组中固定时间和高度维取出2维数组(乘以10的6次方)绘制平面等值线填色图,可以看出计算结果的数量级是对的,具体结果正确与否未进行严格验证。

脚本程序:
  1. # Calculate moisture potential vorticity
  2. # Set working directory
  3. trajDir = 'D:/Temp/HYSPLIT'
  4. meteoDir = r'U:\data\ARL\2015'

  5. # Open meteorological data file
  6. print 'Open meteorological data file...'
  7. meteofn = os.path.join(meteoDir, 'gdas1.mar15.w5')
  8. print 'Meteorological file: ' + meteofn
  9. meteof = addfile(meteofn)

  10. # Read data
  11. print 'Read data...'
  12. latlim = [10,60]
  13. lonlim = [60,140]
  14. rh = meteof['RELH'][:,:,latlim,lonlim]
  15. nx = rh.dimlen(3)
  16. ny = rh.dimlen(2)
  17. nz = rh.dimlen(1)
  18. nt = rh.dimlen(0)
  19. lat = rh.dimvalue(2)
  20. lev = rh.dimvalue(1)
  21. t0 = meteof['TEMP'][:,:nz-1,latlim,lonlim]
  22. uwnd = meteof['UWND'][:,:nz-1,latlim,lonlim]
  23. vwnd = meteof['VWND'][:,:nz-1,latlim,lonlim]
  24. vort = hcurl(uwnd, vwnd)
  25. prs = zeros([nt,nz,ny,nx])
  26. prs = dim_array(prs, rh.dims)
  27. for j in range(nz):
  28.     prs[:,j,:,:] = lev[j]

  29. # Calculate pseudo-equivalent potential temperature
  30. print 'Clalulate pseudo-equivalent potential temperature...'
  31. es = 6.1078*exp(17.2693882*(t0-273.16)/(t0-35.86))
  32. qq = rh*(0.62197*es/(prs-0.378*es))/100.
  33. e = prs*qq/(0.62197+qq)+1e-10
  34. tlcl = 55.0+2840.0/(3.5*log(t0)-log(e)-4.805)
  35. theta = t0*pow((1000/prs),(0.2854*(1.0-0.28*qq)))
  36. eqt = theta*exp(((3376./tlcl)-2.54)*qq*(1.0+0.81*qq))
  37. thse = eqt-273.15

  38. # Calculate moisture potential vorticity
  39. print 'Calculate moisture potential vorticity...'
  40. mpv = zeros([nt,nz,ny,nx], dtype='double')
  41. mpv = dim_array(mpv, rh.dims)
  42. mpv.setdimvalue(1, lev[1:nz-1])
  43. for t in range(nt):
  44.     tt = meteof.gettime(t)
  45.     print tt.strftime('%Y-%m-%d %H:00')
  46.     for z in range(1, nz-1):
  47.         #print '\tLevel: %i' % z
  48.         f = zeros([ny,nx])
  49.         f1 = 2*7.292*sin(lat*3.14159/180.0)*0.00001
  50.         for i in range(nx):
  51.             f[:,i] = f1
  52.         g = 9.8
  53.         dp = 100*(lev[z-1]-lev[z+1])
  54.         deqt = eqt[t,z-1,:,:]-eqt[t,z+1,:,:]
  55.         du = uwnd[t,z-1,:,:]-uwnd[t,z+1,:,:]
  56.         dv = vwnd[t,z-1,:,:]-vwnd[t,z+1,:,:]
  57.         dx1 = 2.0*6370949.0*cos(lat*3.14159/180.0)*3.14159/180.0
  58.         dx = zeros([ny,nx])
  59.         for i in range(nx):
  60.             dx[:,i] = dx1
  61.         dy = 2.0*6370949.0*3.14159/180.0
  62.         dtx = cdiff(eqt[t,z,:,:], 1)
  63.         dty = cdiff(eqt[t,z,:,:], 0)
  64.         pv1 = -g*(vort[t,z,:,:]+f)*deqt/dp  
  65.         pv2 = g*((dv/dp)*(dtx/dx)-(du/dp)*(dty/dy))
  66.         pv = pv1+pv2
  67.         mpv[t,z-1,:,:] = pv

  68. #Plot
  69. axesm()
  70. lworld = shaperead('D:/Temp/Map/country1.shp')
  71. geoshow(lworld, edgecolor='k')
  72. t = 0
  73. tt = meteof.gettime(t)
  74. z = 5
  75. clevs = arange(-3,3.1,0.5)
  76. layer = contourfm(mpv[t,z,:,:]*1e6, clevs)
  77. colorbar(layer)
  78. title('Moisture potential vorticity (%i hPa)\n' % lev[z] + \
  79.     tt.strftime('%Y-%m-%d %H:00'))

  80. print 'Finish...'


绘图结果:
moisture_potential_vorticity.png

评分

参与人数 1金钱 +20 贡献 +2 收起 理由
良辰 + 20 + 2

查看全部评分

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

新浪微博达人勋

发表于 2017-1-15 22:49:34 | 显示全部楼层
王老师,如果后向轨迹的时效比较长,比如后向10天的,一个数据资料集就不能满足计算需求,该如何添加那?学生这样meteof = addfile(meteofn1,meteofn2,meteofn3,meteofn4),结果rh = meteof['RELH'][:,:,latlim,lonlim]报错,错误信息为TypeError: 'NoneType' object is unsubscriptable。王老师如有时间,希望指点。
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2016-8-17 00:03:35 | 显示全部楼层
  感謝老師的分享
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-8-18 18:18:45 | 显示全部楼层
王老师,源代码(只修改了资料路径)没进行其他修改的时候运行,出现如下错误代码!已经下载更新了meteoinfolab软件,1.3.5版本!
Open meteorological data file...
Meteorological file: D:\Temp\arl\gdas1.mar15.w5
Read data...
Traceback (most recent call last):
  File "<iostream>", line 28, in <module>
  File "D:\Temp\MeteoInfo\pylib\mipylib\dimarray.py", line 170, in __setitem__
    r = ArrayMath.setSection(self.array.array, ranges, value)
        at ucar.ma2.ArrayDouble.getDouble(ArrayDouble.java:208)
        at ucar.ma2.ArrayDouble.getObject(ArrayDouble.java:232)
        at org.meteoinfo.data.ArrayMath.setSection(ArrayMath.java:1505)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)

java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsException: 21
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-8-18 18:20:23 | 显示全部楼层
错误行是:
     prs[:,i,:,:] = lev
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2016-8-18 18:21:51 | 显示全部楼层
良辰 发表于 2016-8-18 18:18
王老师,源代码(只修改了资料路径)没进行其他修改的时候运行,出现如下错误代码!已经下载更新了meteoinf ...

错误信息提示第28行出错,28行是什么语句?
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2016-8-18 18:27:30 | 显示全部楼层
MeteoInfo 发表于 2016-8-18 18:21
错误信息提示第28行出错,28行是什么语句?

看看lev数组的长度是多少(len(lev))?应该和nz一样。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-8-18 19:01:07 来自手机 | 显示全部楼层
prs[:,i,:,:] = lev
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-8-18 19:21:44 | 显示全部楼层
本帖最后由 良辰 于 2016-8-18 19:23 编辑
MeteoInfo 发表于 2016-8-18 18:27
看看lev数组的长度是多少(len(lev))?应该和nz一样。


查看了是一样的,都是21


QQ截图20160818192611.png
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2016-8-18 21:51:48 | 显示全部楼层
良辰 发表于 2016-8-18 19:21
查看了是一样的,都是21

for j in range(nz):
    prs[:,j,:,:] = lev[j]

之前用的 i 做循环,论坛会自动把中括号 i 当成斜体格式处理,用 j 会避免此问题(论坛的bug)。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-8-18 21:53:38 | 显示全部楼层
MeteoInfo 发表于 2016-8-18 21:51
for j in range(nz):
    prs[:,j,:,:] = lev[j]

谢谢王老师,这么不容易发现的bug都能找出来,万分感谢!我进一步测试,辛苦了老师!
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

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

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

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