MSMデータを用いて、GrADSで描画したいと思います。
MSMデータとは、なんぞやという方は、こちらを参照してください。
MSMデータの取得
本記事では、京都大学の気象庁データを利用させていただきます。
オリジナルのMSMデータは、国際気象通報式FM92 GRIB 二進形式格子点資料気象通報式(第2版)というデータ形式になっています。
本記事では、そのオリジナルデータ(GRIB2形式)から描画させたいと思います。
Z__C_RJTD_yyyyMMddhhmmss_MSM_GPV_Rjp_Lsurf_FHhh-hh_grib2.binは、地表面データです。
Z__C_RJTD_yyyyMMddhhmmss_MSM_GPV_Rjp_L-pall_FHhh-hh_grib2.binは、気圧面データです。
本記事では、地表面データに着目します。
気圧面データは、こちら
yyyyは西暦、MMは月、ddは日、hhは時間、㎜は分、ssは秒です。
wgetコマンドで取得しましょう。
$ wget http://database.rish.kyoto-u.ac.jp/arch/jmadata/data/gpv/original/2021/07/17/Z__C_RJTD_20210717000000_MSM_GPV_Rjp_Lsurf_FH00-15_grib2.bin
上では、2021年7月17日の00UTC初期値の地表面データであるMSMデータを取得しています。予測時間は、15時間後までです。
51時間先までほしいので、合計で4つのファイルを取得します。また、初期値が03,06,09,15,18,21時の場合、39時間先までですので、合計のファイルは、3つです。
$ wget http://database.rish.kyoto-u.ac.jp/arch/jmadata/data/gpv/original/2021/07/17/Z__C_RJTD_20210717000000_MSM_GPV_Rjp_Lsurf_FH16-33_grib2.bin
$ wget http://database.rish.kyoto-u.ac.jp/arch/jmadata/data/gpv/original/2021/07/17/Z__C_RJTD_20210717000000_MSM_GPV_Rjp_Lsurf_FH34-39_grib2.bin
$ wget http://database.rish.kyoto-u.ac.jp/arch/jmadata/data/gpv/original/2021/07/17/Z__C_RJTD_20210717000000_MSM_GPV_Rjp_Lsurf_FH40-51_grib2.bin
wgrib2コマンドでバイナリファイルに変換します。
$ wgrib2 Z__C_RJTD_20210717000000_MSM_GPV_Rjp_Lsurf_FH00-15_grib2.bin -no_header -bin out0015.bin
$ wgrib2 Z__C_RJTD_20210717000000_MSM_GPV_Rjp_Lsurf_FH16-33_grib2.bin -no_header -bin out1633.bin
$ wgrib2 Z__C_RJTD_20210717000000_MSM_GPV_Rjp_Lsurf_FH34-39_grib2.bin -no_header -bin out3439.bin
$ wgrib2 Z__C_RJTD_20210717000000_MSM_GPV_Rjp_Lsurf_FH40-51_grib2.bin -no_header -bin out4051.bin
バイナリファイルの編集
この時のバイナリファイルout????.binは、海面更生気圧、地上気圧、東西風、南北風、気温、相対湿度、1時間降水量、上層雲量、中層雲量、下層雲量、全雲量、日射量、1時先の海面更生気圧、…..51時間先の日射量という並び方をしています。
51時間先まで4つのファイルに分かれているので、1つのファイルに統合しようと思います。
Fortranでやります。Pythonもいつかやろうと思います。
バイナリファイルの大きさを確認します。
$ ls -l
-rw-r--r-- 1 hoge users 69241393 Jul 27 20:00 out0015.bin
-rw-r--r-- 1 hoge users 78716561 Jul 27 20:00 out1633.bin
-rw-r--r-- 1 hoge users 26238929 Jul 27 20:00 out3439.bin
-rw-r--r-- 1 hoge users 52477745 Jul 27 20:00 out4051.bin
out0015.binは、184607800byte、out1633.binは、209869920byte、out3439.binは、69956640byte、out4051.binは、139913280byteとなっています。
本当にファイルサイズと想定しているファイル形式と一致しているのか計算します。
気象業務センターで確認すると、MSMデータは、北緯22.4~47.6度と東経120~150度で、地表面データでは、x方向(経度)格子点間隔0.0625の格子点数481、y方向(緯度)格子間隔0.05度の格子点数505です。
物理量として、 海面更生気圧、地上気圧、東西風、南北風、気温、相対湿度、1時間降水量、上層雲量、中層雲量、下層雲量、全雲量、日射量 があります。
0015.binは、時間間隔1時間で16時間先までのファイルですので、t方向に15です。
1データが4byte、物理量は12個あります。しかし、初期場には、1時間降水量及び日射量がないため、結果10個の物理量がt方向に16あり、2個の物理量がt方向に15あります。
4×10×481×505×16=155459200
4×2×481×505×15=29148600
155459200+29148600=184607800
out1633.binでは、t方向に18です。
4×12×481×505×18=209869920
out3439.binでは、t方向に6です。
4×12×481×505×6=69956640
out4051.binでは、t方向に12です。
4×12×481×505×12=139913280
と想定したファイルサイズになったので、 プログラムを書いていきます。
implicit none
real,allocatable::out0015(:),out1633(:),out3439(:),out4051(:)
real,allocatable::psea0015(:,:,:),sp0015(:,:,:),uu0015(:,:,:),vv0015(:,:,:),temp0015(:,:,:),rh0015(:,:,:),r1h0015(:,:,:)
real,allocatable::ncld_upper0015(:,:,:),ncld_mid0015(:,:,:),ncld_low0015(:,:,:),clda0015(:,:,:),dswrf0015(:,:,:)
real,allocatable::psea1633(:,:,:),sp1633(:,:,:),uu1633(:,:,:),vv1633(:,:,:),temp1633(:,:,:),rh1633(:,:,:),r1h1633(:,:,:)
real,allocatable::ncld_upper1633(:,:,:),ncld_mid1633(:,:,:),ncld_low1633(:,:,:),clda1633(:,:,:),dswrf1633(:,:,:)
real,allocatable::psea3439(:,:,:),sp3439(:,:,:),uu3439(:,:,:),vv3439(:,:,:),temp3439(:,:,:),rh3439(:,:,:),r1h3439(:,:,:)
real,allocatable::ncld_upper3439(:,:,:),ncld_mid3439(:,:,:),ncld_low3439(:,:,:),clda3439(:,:,:),dswrf3439(:,:,:)
real,allocatable::psea4051(:,:,:),sp4051(:,:,:),uu4051(:,:,:),vv4051(:,:,:),temp4051(:,:,:),rh4051(:,:,:),r1h4051(:,:,:)
real,allocatable::ncld_upper4051(:,:,:),ncld_mid4051(:,:,:),ncld_low4051(:,:,:),clda4051(:,:,:),dswrf4051(:,:,:)
real,allocatable::psea(:,:,:),sp(:,:,:),uu(:,:,:),vv(:,:,:),temp(:,:,:),rh(:,:,:),r1h(:,:,:)
real,allocatable::ncld_upper(:,:,:),ncld_mid(:,:,:),ncld_low(:,:,:),clda(:,:,:),dswrf(:,:,:)
real,allocatable::data(:,:,:)
integer::xx,yy,zz,tt,num,tdata,rnum
integer,parameter::xxdim=481,yydim=505
integer,parameter::out0015ttdim=16,out1633ttdim=18,out3439ttdim=6,out4051ttdim=12,ttdim=52
integer::out0015recl,out1633recl,out3439recl,out4051recl
out0015recl = 4 * 10 * xxdim * yydim * out0015ttdim + 4 * 2 * xxdim * yydim * (out0015ttdim -1)
out1633recl = 4 * 12 * xxdim * yydim * out1633ttdim
out3439recl = 4 * 12 * xxdim * yydim * out3439ttdim
out4051recl = 4 * 12 * xxdim * yydim * out4051ttdim
allocate(psea0015(xxdim,yydim,out0015ttdim),sp0015(xxdim,yydim,out0015ttdim),uu0015(xxdim,yydim,out0015ttdim),&
vv0015(xxdim,yydim,out0015ttdim),temp0015(xxdim,yydim,out0015ttdim),rh0015(xxdim,yydim,out0015ttdim),&
r1h0015(xxdim,yydim,out0015ttdim),ncld_upper0015(xxdim,yydim,out0015ttdim),&
ncld_mid0015(xxdim,yydim,out0015ttdim),ncld_low0015(xxdim,yydim,out0015ttdim),&
clda0015(xxdim,yydim,out0015ttdim),dswrf0015(xxdim,yydim,out0015ttdim))
allocate(psea1633(xxdim,yydim,out1633ttdim),sp1633(xxdim,yydim,out1633ttdim),uu1633(xxdim,yydim,out1633ttdim),&
vv1633(xxdim,yydim,out1633ttdim),temp1633(xxdim,yydim,out1633ttdim),rh1633(xxdim,yydim,out1633ttdim),&
r1h1633(xxdim,yydim,out1633ttdim),ncld_upper1633(xxdim,yydim,out1633ttdim),&
ncld_mid1633(xxdim,yydim,out1633ttdim),ncld_low1633(xxdim,yydim,out1633ttdim),&
clda1633(xxdim,yydim,out1633ttdim),dswrf1633(xxdim,yydim,out1633ttdim))
allocate(psea3439(xxdim,yydim,out3439ttdim),sp3439(xxdim,yydim,out3439ttdim),uu3439(xxdim,yydim,out3439ttdim),&
vv3439(xxdim,yydim,out3439ttdim),temp3439(xxdim,yydim,out3439ttdim),rh3439(xxdim,yydim,out3439ttdim),&
r1h3439(xxdim,yydim,out3439ttdim),ncld_upper3439(xxdim,yydim,out3439ttdim),&
ncld_mid3439(xxdim,yydim,out3439ttdim),ncld_low3439(xxdim,yydim,out3439ttdim),&
clda3439(xxdim,yydim,out3439ttdim),dswrf3439(xxdim,yydim,out3439ttdim))
allocate(psea4051(xxdim,yydim,out4051ttdim),sp4051(xxdim,yydim,out4051ttdim),uu4051(xxdim,yydim,out4051ttdim),&
vv4051(xxdim,yydim,out4051ttdim),temp4051(xxdim,yydim,out4051ttdim),rh4051(xxdim,yydim,out4051ttdim),&
r1h4051(xxdim,yydim,out4051ttdim),ncld_upper4051(xxdim,yydim,out4051ttdim),&
ncld_mid4051(xxdim,yydim,out4051ttdim),ncld_low4051(xxdim,yydim,out4051ttdim),&
clda4051(xxdim,yydim,out4051ttdim),dswrf4051(xxdim,yydim,out4051ttdim))
allocate(psea(xxdim,yydim,ttdim),sp(xxdim,yydim,ttdim),uu(xxdim,yydim,ttdim),vv(xxdim,yydim,ttdim),&
temp(xxdim,yydim,ttdim),rh(xxdim,yydim,ttdim),r1h(xxdim,yydim,ttdim),ncld_upper(xxdim,yydim,ttdim),&
ncld_mid(xxdim,yydim,ttdim),ncld_low(xxdim,yydim,ttdim),clda(xxdim,yydim,ttdim),dswrf(xxdim,yydim,ttdim))
allocate(data(xxdim,yydim,ttdim))
allocate(out0015(out0015recl/4),out1633(out1633recl/4),out3439(out3439recl/4),out4051(out4051recl/4))
open(10,file="out0015.bin",access="direct",recl=out0015recl)
open(11,file="out1633.bin",access="direct",recl=out1633recl)
open(12,file="out3439.bin",access="direct",recl=out3439recl)
open(13,file="out4051.bin",access="direct",recl=out4051recl)
read(10,rec=1)out0015(:)
read(11,rec=1)out1633(:)
read(12,rec=1)out3439(:)
read(13,rec=1)out4051(:)
close(10)
close(11)
close(12)
close(13)
!read
num=1
do tt=1,out0015ttdim
if(tt==1)then
call sub0015(psea0015)
call sub0015(sp0015)
call sub0015(uu0015)
call sub0015(vv0015)
call sub0015(temp0015)
call sub0015(rh0015)
do yy=1,yydim
do xx=1,xxdim
r1h0015(xx,yy,tt)=0.0
enddo
enddo
call sub0015(ncld_upper0015)
call sub0015(ncld_mid0015)
call sub0015(ncld_low0015)
call sub0015(clda0015)
do yy=1,yydim
do xx=1,xxdim
dswrf0015(xx,yy,tt)=0.0
enddo
enddo
else
call sub0015(psea0015)
call sub0015(sp0015)
call sub0015(uu0015)
call sub0015(vv0015)
call sub0015(temp0015)
call sub0015(rh0015)
call sub0015(r1h0015)
call sub0015(ncld_upper0015)
call sub0015(ncld_mid0015)
call sub0015(ncld_low0015)
call sub0015(clda0015)
call sub0015(dswrf0015)
endif
enddo
num=1
do tt=1,out1633ttdim
call sub1633(psea1633)
call sub1633(sp1633)
call sub1633(uu1633)
call sub1633(vv1633)
call sub1633(temp1633)
call sub1633(rh1633)
call sub1633(r1h1633)
call sub1633(ncld_upper1633)
call sub1633(ncld_mid1633)
call sub1633(ncld_low1633)
call sub1633(clda1633)
call sub1633(dswrf1633)
enddo
num=1
do tt=1,out3439ttdim
call sub3439(psea3439)
call sub3439(sp3439)
call sub3439(uu3439)
call sub3439(vv3439)
call sub3439(temp3439)
call sub3439(rh3439)
call sub3439(r1h3439)
call sub3439(ncld_upper3439)
call sub3439(ncld_mid3439)
call sub3439(ncld_low3439)
call sub3439(clda3439)
call sub3439(dswrf3439)
enddo
num=1
do tt=1,out4051ttdim
call sub4051(psea4051)
call sub4051(sp4051)
call sub4051(uu4051)
call sub4051(vv4051)
call sub4051(temp4051)
call sub4051(rh4051)
call sub4051(r1h4051)
call sub4051(ncld_upper4051)
call sub4051(ncld_mid4051)
call sub4051(ncld_low4051)
call sub4051(clda4051)
call sub4051(dswrf4051)
enddo
!write
do tdata=1,ttdim
do yy=1,yydim
do xx=1,xxdim
if (tdata <= out0015ttdim)then
psea(xx,yy,tdata)=psea0015(xx,yy,tdata)
sp(xx,yy,tdata)=sp0015(xx,yy,tdata)
uu(xx,yy,tdata)=uu0015(xx,yy,tdata)
vv(xx,yy,tdata)=vv0015(xx,yy,tdata)
temp(xx,yy,tdata)=temp0015(xx,yy,tdata)
rh(xx,yy,tdata)=rh0015(xx,yy,tdata)
r1h(xx,yy,tdata)=r1h0015(xx,yy,tdata)
ncld_upper(xx,yy,tdata)=ncld_upper0015(xx,yy,tdata)
ncld_mid(xx,yy,tdata)=ncld_mid0015(xx,yy,tdata)
ncld_low(xx,yy,tdata)=ncld_low0015(xx,yy,tdata)
clda(xx,yy,tdata)=clda0015(xx,yy,tdata)
dswrf(xx,yy,tdata)=dswrf0015(xx,yy,tdata)
elseif(tdata <= out0015ttdim+out1633ttdim)then
tt=tdata - out0015ttdim
psea(xx,yy,tdata)=psea1633(xx,yy,tt)
sp(xx,yy,tdata)=sp1633(xx,yy,tt)
uu(xx,yy,tdata)=uu1633(xx,yy,tt)
vv(xx,yy,tdata)=vv1633(xx,yy,tt)
temp(xx,yy,tdata)=temp1633(xx,yy,tt)
rh(xx,yy,tdata)=rh1633(xx,yy,tt)
r1h(xx,yy,tdata)=r1h1633(xx,yy,tt)
ncld_upper(xx,yy,tdata)=ncld_upper1633(xx,yy,tt)
ncld_mid(xx,yy,tdata)=ncld_mid1633(xx,yy,tt)
ncld_low(xx,yy,tdata)=ncld_low1633(xx,yy,tt)
clda(xx,yy,tdata)=clda1633(xx,yy,tt)
dswrf(xx,yy,tdata)=dswrf1633(xx,yy,tt)
elseif(tdata <= out0015ttdim+out1633ttdim+out3439ttdim)then
tt=tdata - out0015ttdim - out1633ttdim
psea(xx,yy,tdata)=psea3439(xx,yy,tt)
sp(xx,yy,tdata)=sp3439(xx,yy,tt)
uu(xx,yy,tdata)=uu3439(xx,yy,tt)
vv(xx,yy,tdata)=vv3439(xx,yy,tt)
temp(xx,yy,tdata)=temp3439(xx,yy,tt)
rh(xx,yy,tdata)=rh3439(xx,yy,tt)
r1h(xx,yy,tdata)=r1h3439(xx,yy,tt)
ncld_upper(xx,yy,tdata)=ncld_upper3439(xx,yy,tt)
ncld_mid(xx,yy,tdata)=ncld_mid3439(xx,yy,tt)
ncld_low(xx,yy,tdata)=ncld_low3439(xx,yy,tt)
clda(xx,yy,tdata)=clda3439(xx,yy,tt)
dswrf(xx,yy,tdata)=dswrf3439(xx,yy,tt)
else
tt=tdata - out0015ttdim - out1633ttdim - out3439ttdim
psea(xx,yy,tdata)=psea4051(xx,yy,tt)
sp(xx,yy,tdata)=sp4051(xx,yy,tt)
uu(xx,yy,tdata)=uu4051(xx,yy,tt)
vv(xx,yy,tdata)=vv4051(xx,yy,tt)
temp(xx,yy,tdata)=temp4051(xx,yy,tt)
rh(xx,yy,tdata)=rh4051(xx,yy,tt)
r1h(xx,yy,tdata)=r1h4051(xx,yy,tt)
ncld_upper(xx,yy,tdata)=ncld_upper4051(xx,yy,tt)
ncld_mid(xx,yy,tdata)=ncld_mid4051(xx,yy,tt)
ncld_low(xx,yy,tdata)=ncld_low4051(xx,yy,tt)
clda(xx,yy,tdata)=clda4051(xx,yy,tt)
dswrf(xx,yy,tdata)=dswrf4051(xx,yy,tt)
endif
enddo
enddo
enddo
!write(*,*)ww(:,:,:,:)
open(20,file="msm.bin",status="unknown",access="direct",form="unformatted",recl=4*xxdim*yydim)
rnum=1
do tt=1,ttdim
write(20,rec=rnum)psea(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)sp(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)uu(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)vv(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)temp(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)rh(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)r1h(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)ncld_upper(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)ncld_mid(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)ncld_low(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)clda(:,:,tt)
rnum=rnum+1
write(20,rec=rnum)dswrf(:,:,tt)
rnum=rnum+1
enddo
close(20)
stop
contains
subroutine sub0015(var)
implicit none
real::var(xxdim,yydim,out0015ttdim),fread(out0015recl/4)
do yy=1,yydim
do xx=1,xxdim
var(xx,yy,tt)=out0015(num)
num=num+1
enddo
enddo
end subroutine
subroutine sub1633(var)
implicit none
real::var(xxdim,yydim,out1633ttdim),fread(out1633recl/4)
do yy=1,yydim
do xx=1,xxdim
var(xx,yy,tt)=out1633(num)
num=num+1
enddo
enddo
end subroutine
subroutine sub3439(var)
implicit none
real::var(xxdim,yydim,out3439ttdim),fread(out3439recl/4)
do yy=1,yydim
do xx=1,xxdim
var(xx,yy,tt)=out3439(num)
num=num+1
enddo
enddo
end subroutine
subroutine sub4051(var)
implicit none
real::var(xxdim,yydim,out4051ttdim),fread(out4051recl/4)
do yy=1,yydim
do xx=1,xxdim
var(xx,yy,tt)=out4051(num)
num=num+1
enddo
enddo
end subroutine
end
コントロールファイルの作成
GrADSで描画するために、コントロールファイルを作る必要があります。
気象業務センターで確認すると、MSMデータは、北緯22.4~47.6度と東経120~150度で、地表面データでは、x方向(経度)格子点間隔0.0625の格子点数481、y方向(緯度)格子間隔0.05度の格子点数505です。
この情報の下、コントロールファイルを作成します。
地表面データのコントロールファイル
DSET msm.bin
UNDEF 999999999E+20
XDEF 481 LINEAR 120 0.0625
YDEF 505 LINEAR 22.4 0.05
ZDEF 1 LEVELS 1
TDEF 51 LINEAR 00z01jan0000 1hr
VARS 12
psea 1 99 sp
sp 1 99 u
u 1 99 u
v 1 99 v
temp 1 99 temp
rh 1 99 rh
r1h 1 99 prec
ncld_upper 1 99 ncld_upper
ncld_mid 1 99 ncld_mid
ncld_low 1 99 ncld_low
clda 1 99 clda
dswrf 1 99 dswrf
ENDVARS
GrADSで描画
本記事では、GrADSで描画します。
openでコントロールファイルを開きます。
open msm_s.ctl
例として、以下のように実行することで地上気温の図が描画されます。
ga ->d temp
GrADSの詳細はこちらで