爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10584|回复: 8

[秀图] 用NCL直接读取MICAPS4的资料并绘图

[复制链接]
发表于 2018-5-3 10:16:28 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 柿子柿子柿子 于 2018-5-3 10:33 编辑

test.png


首先是丢一张图来展示结果。这个是某天某时某气压层的流场。刚出图的时候感觉还是不错的,但也被这密密麻麻的线恶心了一下,之后越看越觉得美感十足。后面用了稀疏(stMinDistanceF)发现不够这个有艺术感,就又去掉了。


接下来的话就是直接展示程序,懒得上传了,就直接分享出来了。也方便大家和自己以后的查询。

function readMicaps4Model(fileName:string)
begin

        f = cbinread(fileName, -1, "byte")

        discriminator  = tochar(f(0:3))            ; 合法数据关键字(mdfs)
        type              = toshort(f(4))              ; 数据类型(4/11)
        modelName   = tochar(f(6:25))           ; 模式名字
        element         = tochar(f(26:75))         ; 物理量
        description     = tochar(f(76:105))       ; 附加描述信息
        Extent           = tochar(f(178:277))      ; 扩展段(目前没有用)

        ; 层次
        cbinwrite("tmp.bin", f(106:109))
        level = cbinread("tmp.bin", -1, "float")
        system("rm tmp.bin")

        ; 年  月  日  起报时刻  时区  预报时效
        cbinwrite("tmp.bin", f(110:133))
        tmp = cbinread("tmp.bin", -1, "integer")
        system("rm tmp.bin")
        year          = tmp(0)        ; 年
        month       = tmp(1)        ; 月
        day           = tmp(2)        ; 日
        hour          = tmp(3)        ; 起报时刻
        timezone    = tmp(4)        ; 时区
        period        = tmp(5)        ; 预报时效
        delete(tmp)

        ; 经度
        cbinwrite("tmp.bin", f(134:145))
        tmp = cbinread("tmp.bin", -1, "float")
        system("rm tmp.bin")
        startLongitude        = tmp(0)  ; 起始经度
        endLongitude         = tmp(1)  ; 终止经度
        longitudeGridSpace = tmp(2)  ; 经度格距
        delete(tmp)
        ; 经度
        cbinwrite("tmp.bin", f(146:149))
        latitudeGridNumber = cbinread("tmp.bin", -1, "integer")        ; 纬向经线格点数
        system("rm tmp.bin")

        ; 纬度
        cbinwrite("tmp.bin",f(150:161))
        tmp = cbinread("tmp.bin", -1, "float")
        system("rm tmp.bin")
        startLatitude           = tmp(0)        ; 起始纬度
        endLatitude           = tmp(1)        ; 终止纬度
        latitudeGridSpace = tmp(2)        ; 纬度格距
        delete(tmp)
        ; 纬度
        cbinwrite("tmp.bin",f(162:165))
        longitudeGridNumber = cbinread("tmp.bin", -1, "integer")        ; 经向纬线格点数
        system("rm tmp.bin")

        ; 等值线
        cbinwrite("tmp.bin", f(166:177))
        tmp = cbinread("tmp.bin", -1, "float")
        system("rm tmp.bin")
        isolineStartValue = tmp(0)
        isolineEndValue  = tmp(1)
        isolineSpace       = tmp(2)
        delete(tmp)

        ; 坐标系
        Lat = fspan(startLatitude, endLatitude, longitudeGridNumber)
        Lon = fspan(startLongitude, endLongitude, latitudeGridNumber)
        Lat@long_name  = "Latitude"
        Lon@long_name = "Longitude"
        Lat@units   = "degrees-north"
        Lon@units  = "degrees-east"
        Lat!0          = "Lat"
        Lon!0         = "Lon"
        Lat&Lat      = Lat
        Lon&Lon     = Lon

        ; 数据区
        if (type .eq. 4) then
                ; 读数据
                cbinwrite("tmp.bin",f(278:))
                dat = cbinread("tmp.bin", (/longitudeGridNumber, latitudeGridNumber/), "float")
                system("rm tmp.bin")
                ; 设置信息
                dat!0     = "Lat"
                dat!1     = "Lon"
                dat&Lat  = Lat
                dat&Lon = Lon
        else if (type .eq. 11) then
                ; 读数据
                cbinwrite("tmp.bin",f(278:))
                dat = cbinread("tmp.bin", (/2, longitudeGridNumber, latitudeGridNumber/), "float")
                system("rm tmp.bin")
                ; 模和角度
                Norm = dat(0,:,:)
                Angle = dat(1,:,:)
                delete(dat)
                ; 计算uv
                u = new((/longitudeGridNumber, latitudeGridNumber/), float)
                v = new((/longitudeGridNumber, latitudeGridNumber/), float)
                do j = 0, longitudeGridNumber-1
                        do i = 0, latitudeGridNumber-1
                                rad   = Angle(j,i) * get_pi("float") / 180
                                u(j,i) = Norm(j,i) * cos(rad)
                                v(j,i) = Norm(j,i) * sin(rad)
                        end do
                end do
                delete([/Norm, Angle/])
                ; 填充数据
                dat            = new((/2, longitudeGridNumber, latitudeGridNumber/), float)
                dat(0,:,:) = u
                dat(1,:,:) = v
                ; 设置信息
                Direction            = (/"u", "v"/)
                dat!0                 = "Direction"
                dat!1                 = "Lat"
                dat!2                 = "Lon"
                dat&Direction     = Direction
                dat&Lat             = Lat
                dat&Lon            = Lon
                delete(Direction)
        end if
        end if

        ; 设置数据信息
        dat@type              = tostring(type)
        dat@modelName    = tostring(modelName)
        dat@element         = tostring(element)
        dat@description     = tostring(description)
        dat@level              = tostring(level)
        dat@year              = tostring(year)
        dat@month           = tostring(month)
        dat@day               = tostring(day)
        dat@hour              = tostring(hour)
        dat@timezone        = tostring(timezone)
        dat@period            = tostring(period)
        dat@isolineStartValue = tostring(isolineStartValue)
        dat@isolineEndValue  = tostring(isolineEndValue)
        dat@isolineSpace       = tostring(isolineSpace)
        
        ; 返回数组
        ; 标量(:,:)
        ; 矢量(0,:,:) => u
        ;       (1,:,:) => v
        return dat
end


上面这段是读取MICAPS4数据的。因为M4和M3数据差别很大,昨天无聊就把好久之前拖着的程序给弄了,也正好NCL可以立马就展示出来我提取的对不对。结果看来还是不错了。下面的这个的话就是绘图的部分了,我放在了另一个文件(mian.ncl)里面。

load "readMicaps4Model.ncl"

begin

        ;HGT = readMicaps4Model("dat/HGT.500.18050108.000")

        UV = readMicaps4Model("dat/UV.500.18050108.000")

        wks = gsn_open_wks("png", "test")
        ;res = True
        ;res@gsnDraw        = False
        ;res@gsnFrame      = False
        ;res@cnFillOn         = False
        ;res@cnLinesOn      = True
        ;res@gsnMaximize  = True
        ;res@gsnAddCyclic  = False

        ;res@mpMinLatF = min(HGT&Lat)
        ;res@mpMinLonF = min(HGT&Lon)
        ;res@mpMaxLatF = max(HGT&Lat)
        ;res@mpMaxLonF = max(HGT&Lon)

        ;plot = gsn_csm_contour_map(wks, HGT, res)

        stres = True
        stres@gsnDraw          = False
        stres@gsnFrame         = False
        stres@gsnMaximize     = True
        stres@gsnAddCyclic     = False
        ;stres@stMinDistanceF = 0.035
        stres@mpMinLatF = min(UV&Lat)
        stres@mpMinLonF = min(UV&Lon)
        stres@mpMaxLatF = max(UV&Lat)
        stres@mpMaxLonF = max(UV&Lon)
        ;stplot = gsn_csm_streamline(wks, UV(0,:,:), UV(1,:,:), stres)
        splot = gsn_csm_streamline_map_ce(wks, UV(0,:,:), UV(1,:,:), stres)

        ;overlay(plot,stplot)
        draw(splot)
        frame(wks)
end



最后说一下有个不知道什么原因出错的地方。
readMicaps4Model这个函数里面,在byte转换成short的那里,我查到的short是2个byte,然后往临时文件里面写出2byte再按照short读取的话会得到一个长度为2的short数组……有谁知道这个是本身的bug还是什么情况?至于我为什么要先写出到一个临时文件再读回来,是暂时没找到怎么从byte数组转换成integer、float这类数据的方法。



密码修改失败请联系微信:mofangbao
发表于 2018-5-3 22:22:09 | 显示全部楼层
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

发表于 2018-5-7 13:38:06 | 显示全部楼层
加点颜色渲染,就梵高再现了
密码修改失败请联系微信:mofangbao
发表于 2020-3-22 15:11:10 | 显示全部楼层
太厉害啦
密码修改失败请联系微信:mofangbao
回复

使用道具 举报

发表于 2020-4-19 21:56:32 | 显示全部楼层
逛论坛都能笑死我
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

发表于 2020-5-20 16:42:41 | 显示全部楼层
谢谢楼主,有人知道python怎么读这个数据吗?我直接从micaps4软件下载下来的
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-23 23:33:28 | 显示全部楼层
weety9394 发表于 2020-5-20 16:42
谢谢楼主,有人知道python怎么读这个数据吗?我直接从micaps4软件下载下来的

以byteArray的方式读入数据,再用struct.unpack()解码
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

发表于 2022-1-21 11:00:58 | 显示全部楼层
想请教下,怎样用Python获取micaps4的数据啊?
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-21 21:41:28 | 显示全部楼层
hPa 发表于 2022-1-21 11:00
想请教下,怎样用Python获取micaps4的数据啊?

你在论坛里搜一下,我记得有这帖子
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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