格子点データの解析 1 月平均全球客観解析データの解析 客観解析データや衛星観測データのような格子点データは バイナリ形式のデータファイルに記録されていることが多いです バイナリ形式のデータファイルは テキスト形式の場合とは異なり 直接中身を見ることができません プログラムを書いてデータを読み出して

Similar documents
FORTRAN( と C) によるプログラミング 5 ファイル入出力 ここではファイルからデータを読みこんだり ファイルにデータを書き出したりするプログラムを作成してみます はじめに テキスト形式で書かれたデータファイルに書かれているデータを読みこんで配列に代入し 標準出力に書き出すプログラムを作り

格子点データの解析 4 気象庁合成レーダーの解析 気象庁合成レーダーは全国 20 か所に設置された気象レーダーによって観測されたエコー強度 ( レーダーで観測される換算降水強度 ) とエコー頂高度 ( レーダーで観測される降水エコーの高さ ) のデータです エコー強度は格子間隔が 1 km エコー頂

GrADS の使い方 GrADS(Grid Analysis and Display System) は おもに 客観解析データのような格子点データを地図上に作図するために使われるアプリケーションです 全球スケールの気象を扱う分野で広く使われています GrADS は Unix 系の OS 上でよく利

< 中略 > 24 0 NNE 次に 指定した日時の時間降水量と気温を 観測地点の一覧表に載っているすべての地点について出力するプログラムを作成してみます 観測地点の一覧表は index.txt というファイルで与えられています このファイルを読みこむためのサブルーチンが AMD

< 中略 > 24 0 NNE 次に 指定した日時の時間降水量と気温を 観測地点の一覧表に載っているすべての地点について出力するプログラムを作成してみます 観測地点の一覧表は index.txt というファイルで与えられています このファイルを読みこむためのサブルーチンが AMD

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

情報処理演習 B8クラス

Microsoft Word - Cプログラミング演習(10)

Microsoft PowerPoint - 第3回目.ppt [互換モード]

演算増幅器

PowerPoint Presentation

2006年10月5日(木)実施

Microsoft PowerPoint - kougi6.ppt

Prog1_12th

Microsoft PowerPoint - 14th.ppt [互換モード]

Microsoft Word - Cプログラミング演習(9)

02: 変数と標準入出力

※ ポイント ※

PowerPoint Presentation

02: 変数と標準入出力

Microsoft PowerPoint - kougi7.ppt

情報処理概論(第二日目)

Microsoft Word - DF-Salford解説09.doc

Microsoft PowerPoint - CproNt11.ppt [互換モード]

Taro-ファイル処理(公開版).jtd

Microsoft PowerPoint - prog04.ppt

プログラミング基礎

Microsoft PowerPoint - kougi8.ppt

gengo1-12

cp-7. 配列

gengo1-12

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

計算機プログラミング

gengo1-12

memo

memo

PowerPoint プレゼンテーション

memo

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - prog06.ppt

今後の予定 6/29 パターン形成第 11 回 7/6 データ解析第 12 回 7/13 群れ行動 ( 久保先生 ) 第 13 回 7/17 ( 金 ) 休講 7/20 まとめ第 14 回 7/27 休講?

Microsoft PowerPoint pptx

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

Microsoft PowerPoint - 計算機言語 第7回.ppt

PowerPoint プレゼンテーション

Microsoft Word - JRA55_TL319_manual.docx

C言語講座 ~ファイル入出力編~

ポインタ変数

Microsoft PowerPoint - kougi2.ppt

今までの復習 プログラムで最低限必要なもの 入力 ( キーボードから ファイルから ) 出力 ( 画面へ ファイルへ ) 条件分岐 : 条件の成立 不成立により 異なる動作をする 繰り返し : 一定の回数の繰返し 条件成立の間の繰返し 関数の定義 関数の呼び出し C ではそれ以外に ポインタ データ

PowerPoint プレゼンテーション

Microsoft PowerPoint - 11.pptx

全体ロードマップ インターネット電話 音の符号化 ( 信号処理 ) 今日 音の録音 再生 ネットワーク ( ソケット ) プログラミング ファイル入出力 インターネットの基礎 C プログラミング基礎

Microsoft Word - 3new.doc

02: 変数と標準入出力

演習2

ゲームエンジンの構成要素

02: 変数と標準入出力

スライド タイトルなし

PowerPoint Presentation

Cプログラミング1(再) 第2回

slide4.pptx

プログラミング演習3 - Cプログラミング -

プログラミング演習3 - Cプログラミング -

ポインタ変数

プログラミング実習I

始めに, 最下位共通先祖を求めるための関数 LcaDFS( int v ) の処理を記述する. この関数は値を返さない再帰的な void 関数で, 点 v を根とする木 T の部分木を深さ優先探索する. 整数の引数 v は, 木 T の点を示す点番号で, 配列 NodeSpace[ ] へのカーソル

Microsoft PowerPoint - 講義10改.pptx

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

Microsoft PowerPoint - 5Chap15.ppt

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

PowerPoint Presentation

PowerPoint プレゼンテーション

memo

ディジタル信号処理

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

情報工学実験 C コンパイラ第 2 回説明資料 (2017 年度 ) 担当 : 笹倉 佐藤

V

02: 変数と標準入出力

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

02: 変数と標準入出力

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

情報画像工学実験I-1

Prog1_10th

Microsoft PowerPoint - kougi4.ppt

C言語入門

プログラミング及び演習 第1回 講義概容・実行制御

ファイル入出力

第1回 プログラミング演習3 センサーアプリケーション

1 C STL(1) C C C libc C C C++ STL(Standard Template Library ) libc libc C++ C STL libc STL iostream Algorithm libc STL string vector l

ディジタル信号処理

Microsoft PowerPoint - 説明2_演算と型(C_guide2)【2015新教材対応確認済み】.pptx

Microsoft Word - no103.docx

作図コマンド : pscoast -R125/148/30/46 -JM15c -B5g5 -Di -W5 -S235 -X6c -Y4c > test.ps 作図例 : 2 分布図の作成 2.1 点を描く 地点の分布を作図するときは たとえば以下のように行います > pscoast -R125/1

風力発電インデックスの算出方法について 1. 風力発電インデックスについて風力発電インデックスは 気象庁 GPV(RSM) 1 局地気象モデル 2 (ANEMOS:LAWEPS-1 次領域モデル ) マスコンモデル 3 により 1km メッシュの地上高 70m における 24 時間の毎時風速を予測し

訋箊æ©�ã…Šã…�ㇰㅩã…�ㅳㇰ - 第13åłž ã…Łã‡¡ã‡¤ã…«å⁄¦ç’ƒ

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

演習1

Fortran 勉強会 第 5 回 辻野智紀

Transcription:

格子点データの解析 1 月平均全球客観解析データの解析 客観解析データや衛星観測データのような格子点データは バイナリ形式のデータファイルに記録されていることが多いです バイナリ形式のデータファイルは テキスト形式の場合とは異なり 直接中身を見ることができません プログラムを書いてデータを読み出して解析するのが普通です ここでは 全球客観解析データを用いてバイナリ形式のファイルに記録された格子点データの解析について学びたいと思います はじめに 月平均海面気圧のデータファイルを開いて 特定の月のデータを読み出してみます データファ イルには 1979 年 1 月からの月別データが書きこまれていますが ここでは 2011 年 1 月のデータを読み出す プログラムを作成します FORTRAN では OPEN 文でバイナリ形式のファイルを開きます テキスト形式の場合とは引数の指定が異なります バイナリ形式の場合には FORM='UNFORMATTED' と指定し さらに ACCESS='DIRECT' とします また RECL= で レコード長をバイト数 ( 整数値 ) で指定します 実数型の配列の場合 各要素は 4 バイトで 要素の数は LMAX*MMAX(LMAX は経度方向の格子数 MMAX は緯度方向の格子数 ) なので レコード長は 4*LMAX*MMAX バイトになります C では fopen 関数を使ってファイルを開きます モードが "rb" であることに注意します FORTRAN では READ 文でデータを読みこみます 書式の指定はありませんが REC= でレコード番号を指定します 2011 年 1 月のデータは 385 番目のデータですので レコード番号は 385 です C では fseek 関数を使ってデータファイル上の所定の位置に移動 つまり 384 個のレコードの分だけ前に移動した後で fread 関数でデータを読みこみます 書き出しの場合は FORTRAN の場合は WRITE 文 C の場合は fwrite 関数を使います プログラム : FORTRAN C PARAMETER 文で定数 LMAXとMMAXを宣言する C 定数 LMAXは経度方向の格子数を MMAXは緯度方向の格子数を表す PARAMETER (LMAX=144,MMAX=73) C 配列 A を宣言する REAL A(LMAX,MMAX) C データを読みこむ C ファイルを開く C 機番は10 以降の番号を指定する C STATUSは読みこみの場合は 'OLD' を指定する 9

C バイナリファイルの場合は FORMには 'UNFORMATTED' を指定する C さらに ACCESSには 'DIRECT' を指定し C RECLにはレコード長をバイト数 ( 整数値 ) で指定する C 各要素は4バイトなので レコード長は4 要素数である OPEN(10,FILE='SLP.dat',STATUS='OLD', + FORM='UNFORMATTED', + ACCESS='DIRECT',RECL=4*LMAX*MMAX) C READ 文でデータを読みこむ C 機番 10を指定する REC=... でレコード番号を指定する C ここでは 385 番目のレコードを読みこむ C 読みこんだデータを配列 Aに格納する READ(10,REC=385) A C ファイルを閉じる CLOSE(10) C データを書き出す C ファイルを開く C 機番は10 以降の番号を指定する C STATUSは書き出しの場合は 'UNKNOWN' を指定する C バイナリファイルの場合は FORMには 'UNFORMATTED' を指定する C さらに ACCESSには 'DIRECT' を指定し C RECLにはレコード長を整数値で指定する OPEN(10,FILE='output.dat',STATUS='UNKNOWN', + FORM='UNFORMATTED', + ACCESS='DIRECT',RECL=4*LMAX*MMAX) C 配列 A の各要素の値を機番 10 で指定されたファイルに書き出す C REC=1 と指定し 1 番目のレコードとして出力する WRITE(10,REC=1) A C ファイルを閉じる CLOSE(10) STOP END ( 参考 )C 10

#include <stdio.h> int main(void) /* 定数 mmax と lmax を宣言する 定数 mmax は緯度方向の格子数を lmax は経度方向の格子数を表す */ int mmax=73, lmax=144; /* 配列 a を宣言する */ float a[mmax][lmax]; /* ファイルポインタ fp を宣言する */ FILE *fp; /* データを読みこむ */ /* ファイルを開く モードは "rb"( バイナリファイルの読みこみ ) を指定する */ fp = fopen( "SLP.dat", "rb" ); /* ファイルポインタ fp で指定されたファイルの所定の位置に移動する 第 3 引数に SEEK_SET を指定し ファイルの先頭を位置の基準とする ここでは 385 番目のレコードを読みこむので まず ファイルの先頭から (385-1)*mmax*lmax*sizeof(float) バイトだけ前方に移動する */ fseek( fp, (385-1)*mmax*lmax*sizeof(float), SEEK_SET ); /* 配列 a の各要素の値をファイルポインタ fp で指定されたファイルから読みこむ 項目のサイズは浮動小数点のサイズ sizeof(float) を指定する 項目の数は mmax*lmax を指定する */ fread( a, sizeof(float), mmax*lmax, fp ); /* ファイルを閉じる */ fclose( fp ); /* データを書き出す */ /* ファイルを開く モードは "wb"( バイナリファイルへの書き出し ) を指定する */ 11

fp = fopen( "output.dat", "wb" ); /* 配列 a の各要素の値をファイルポインタ fp で指定されたファイルに書き出す 項目のサイズは浮動小数点のサイズ sizeof(float) を指定する 項目の数は mmax*lmax を指定する */ fwrite( a, sizeof(float), mmax*lmax, fp ); /* ファイルを閉じる */ fclose( fp ); return 0; 計算結果は output.dat というファイルに出力されましたが このファイルの形式をコントロールファイルに記述しておきます 以下のようなテキスト形式のファイルを作成し output.ctl というファイル名で保存しておきます ここでは 変数名を "A" としています GrADS では output.ctl を開いて "a" という名前の変数として作図できます ( 各種設定をした後 "d a" とすればよい ) コントロールファイル : DSET output.dat UNDEF -9.99E33 OPTIONS yrev XDEF 144 LINEAR 0.0 2.5 YDEF 73 LINEAR -90.0 2.5 ZDEF 1 LEVELS 1000 TDEF 1 LINEAR jan1979 1mo VARS 1 A 0 99 Output ENDVARS 上のコントロールファイルでは DSET はデータファイル名 UNDEF は欠損値 "OPTIONS yrev" はデータの並び順が南から北ではなく北から南であることを示しています XDEF(YDEF) は 東西 ( 南北 ) 方向の格子点の数 始点の経度 ( 緯度 ) 経度( 緯度 ) 間隔 ZDEF は各等圧面の気圧の値 (hpa) TDEF は時刻 ( この場合は 1979 年 1 月から 1 か月間隔 ) を表します VARS は変数の種類の数を示し そのあとで 各変数を列挙します この場合は 変数は 1 種類で 変数名は "A" です ひとつめの数字 "0" は 2 次元であることを示します 3 次元の場合は鉛直方向の格子数を入れます ふたつめの数字 "99" は ( 特殊な書式ではなく ) 通常の書式であることを意味します そのあと 同じ行に続けて変数名を書きます 12

作図例 : 次に 2010 年 12 月から 2011 年 2 月までの 3 か月間の海面気圧の平均値を計算してみます ここでは 3 つ の月別値の単純な平均を 3 か月間の平均とみなします 384 番目から 386 番目までのレコードを順に読みこん で 足していき 最後にレコードの個数 3 で割ります プログラム : FORTRAN C PARAMETER 文で定数 LMAXとMMAXを宣言する C 定数 LMAXは経度方向の格子数を MMAXは緯度方向の格子数を表す PARAMETER (LMAX=144,MMAX=73) C 配列 A B を宣言する REAL A(LMAX,MMAX),B(LMAX,MMAX) C 配列 Aの各要素にゼロを代入する DO 11 M=1,MMAX DO 12 L=1,LMAX A(L,M) = 0. 12 CONTINUE 11 CONTINUE C データを読みこむ 13

C ファイルを開く C 機番は10 以降の番号を指定する C STATUSは読みこみの場合は 'OLD' を指定する C バイナリファイルの場合は FORMには 'UNFORMATTED' を指定する C さらに ACCESSには 'DIRECT' を指定し C RECLにはレコード長をバイト数 ( 整数値 ) で指定する C 各要素は4バイトなので レコード長は4 要素数である OPEN(10,FILE='SLP.dat',STATUS='OLD', + FORM='UNFORMATTED', + ACCESS='DIRECT',RECL=4*LMAX*MMAX) C ここからデータを読みこむためのDOループが始まる C 読みこみたいレコードの個数だけ反復する C ここでは 384 番目から386 番目までのレコードを読みこむ DO 21 I=384,386 C READ 文でデータを読みこむ C 機番 10を指定する REC=... でレコード番号を指定する C 読みこんだデータを配列 Bに格納する READ(10,REC=I) B C 配列 Bの各要素を配列 Aの各要素に加える DO 31 M=1,MMAX DO 32 L=1,LMAX A(L,M) = A(L,M) + B(L,M) 32 CONTINUE 31 CONTINUE C ここで DO ループ 21 が終了する 21 CONTINUE C ファイルを閉じる CLOSE(10) C 平均値を計算する C 配列 Aの各要素をレコードの個数で割る DO 41 M=1,MMAX DO 42 L=1,LMAX 14

42 CONTINUE 41 CONTINUE A(L,M) = A(L,M) / REAL(3) C データを書き出す C ファイルを開く C 機番は10 以降の番号を指定する C STATUSは書き出しの場合は 'UNKNOWN' を指定する C バイナリファイルの場合は FORMには 'UNFORMATTED' を指定する C さらに ACCESSには 'DIRECT' を指定し C RECLにはレコード長を整数値で指定する OPEN(10,FILE='output.dat',STATUS='UNKNOWN', + FORM='UNFORMATTED', + ACCESS='DIRECT',RECL=4*LMAX*MMAX) C 配列 A の各要素の値を機番 10 で指定されたファイルに書き出す C REC=1 と指定し 1 番目のレコードとして出力する WRITE(10,REC=1) A C ファイルを閉じる CLOSE(10) STOP END ( 参考 )C #include <stdio.h> int main(void) /* 定数 mmax と lmax を宣言する 定数 mmax は緯度方向の格子数を lmax は経度方向の格子数を表す */ int mmax=73, lmax=144, i, m, l; /* 配列 a b を宣言する */ float a[mmax][lmax], b[mmax][lmax]; /* ファイルポインタ fp を宣言する */ 15

FILE *fp; /* 配列 a の各要素にゼロを代入する */ for (m=0; m<=mmax-1; m++) for (l=0; l<=lmax-1; l++) a[m][l] = 0.; /* データを読みこむ */ /* ファイルを開く モードは "rb"( バイナリファイルの読みこみ ) を指定する */ fp = fopen( "SLP.dat", "rb" ); /* ここからデータを読みこむための for ループが始まる 読みこみたいレコードの個数だけ反復する ここでは 384 番目から 386 番目までのレコードを読みこむ */ for (i=384-1; i<=386-1; i++) /* ファイルポインタ fp で指定されたファイルの所定の位置に移動する 第 3 引数に SEEK_SET を指定し ファイルの先頭を位置の基準とする ファイルの先頭から i*mmax*lmax*sizeof(float) バイトだけ前方に移動する */ fseek( fp, i*mmax*lmax*sizeof(float), SEEK_SET ); /* 配列 b の各要素の値をファイルポインタ fp で指定されたファイルから読みこむ 項目のサイズは浮動小数点のサイズ sizeof(float) を指定する 項目の数は mmax*lmax を指定する */ fread( b, sizeof(float), mmax*lmax, fp ); /* 配列 b の各要素を配列 a の各要素に加える */ for (m=0; m<=mmax-1; m++) for (l=0; l<=lmax-1; l++) a[m][l] = a[m][l] + b[m][l]; 16

/* ここで for ループが終了する */ /* ファイルを閉じる */ fclose( fp ); /* 平均値を計算する */ /* 配列 A の各要素をレコードの個数で割る */ for (m=0; m<=mmax-1; m++) for (l=0; l<=lmax-1; l++) a[m][l] = a[m][l] / 3.; /* データを書き出す */ /* ファイルを開く モードは "wb"( バイナリファイルへの書き出し ) を指定する */ fp = fopen( "output.dat", "wb" ); /* 配列 a の各要素の値をファイルポインタ fp で指定されたファイルに書き出す 項目のサイズは浮動小数点のサイズ sizeof(float) を指定する 項目の数は mmax*lmax を指定する */ fwrite( a, sizeof(float), mmax*lmax, fp ); /* ファイルを閉じる */ fclose( fp ); return 0; 17

作図例 : さらに 1 月の月平均海面気圧の平年値 (1981 年から 2010 年までの 30 年間の平均値 ) を計算してみます 1981 年 1 月のレコード (25 番目 ) から 2010 年 1 月のレコード (373 番目 ) を 12 個おきに順に読みこんで 足していき 最後にレコードの個数 30 で割ります プログラム : FORTRAN C PARAMETER 文で定数 LMAXとMMAXを宣言する C 定数 LMAXは経度方向の格子数を MMAXは緯度方向の格子数を表す PARAMETER (LMAX=144,MMAX=73) C 配列 A B を宣言する REAL A(LMAX,MMAX),B(LMAX,MMAX) C 配列 Aの各要素にゼロを代入する DO 11 M=1,MMAX DO 12 L=1,LMAX A(L,M) = 0. 12 CONTINUE 11 CONTINUE C データを読みこむ 18

C ファイルを開く C 機番は10 以降の番号を指定する C STATUSは読みこみの場合は 'OLD' を指定する C バイナリファイルの場合は FORMには 'UNFORMATTED' を指定する C さらに ACCESSには 'DIRECT' を指定し C RECLにはレコード長をバイト数 ( 整数値 ) で指定する C 各要素は4バイトなので レコード長は4 要素数である OPEN(10,FILE='SLP.dat',STATUS='OLD', + FORM='UNFORMATTED', + ACCESS='DIRECT',RECL=4*LMAX*MMAX) C ここからデータを読みこむためのDOループが始まる C 読みこみたいレコードの個数だけ反復する C ここでは 1981 年から2010 年までの1 月のレコードを読みこむ DO 21 IY=1981,2010 C レコード番号を計算する C ここでは 25 番目から 373 番目までのレコードを読みこむ I = 1 + 12 * (IY-1979) C READ 文でデータを読みこむ C 機番 10を指定する REC=... でレコード番号を指定する C 読みこんだデータを配列 Bに格納する READ(10,REC=I) B C 配列 Bの各要素を配列 Aの各要素に加える DO 31 M=1,MMAX DO 32 L=1,LMAX A(L,M) = A(L,M) + B(L,M) 32 CONTINUE 31 CONTINUE C ここで DO ループ 21 が終了する 21 CONTINUE C ファイルを閉じる CLOSE(10) C 平均値を計算する 19

C 配列 Aの各要素をレコードの個数で割る DO 41 M=1,MMAX DO 42 L=1,LMAX A(L,M) = A(L,M) / REAL(30) 42 CONTINUE 41 CONTINUE C データを書き出す C ファイルを開く C 機番は10 以降の番号を指定する C STATUSは書き出しの場合は 'UNKNOWN' を指定する C バイナリファイルの場合は FORMには 'UNFORMATTED' を指定する C さらに ACCESSには 'DIRECT' を指定し C RECLにはレコード長を整数値で指定する OPEN(10,FILE='output.dat',STATUS='UNKNOWN', + FORM='UNFORMATTED', + ACCESS='DIRECT',RECL=4*LMAX*MMAX) C 配列 A の各要素の値を機番 10 で指定されたファイルに書き出す C REC=1 と指定し 1 番目のレコードとして出力する WRITE(10,REC=1) A C ファイルを閉じる CLOSE(10) STOP END ( 参考 )C #include <stdio.h> int main(void) /* 定数 mmax と lmax を宣言する 定数 mmax は緯度方向の格子数を lmax は経度方向の格子数を表す */ int mmax=73, lmax=144, i, iy, m, l; 20

/* 配列 a b を宣言する */ float a[mmax][lmax], b[mmax][lmax]; /* ファイルポインタ fp を宣言する */ FILE *fp; /* 配列 a の各要素にゼロを代入する */ for (m=0; m<=mmax-1; m++) for (l=0; l<=lmax-1; l++) a[m][l] = 0.; /* データを読みこむ */ /* ファイルを開く モードは "rb"( バイナリファイルの読みこみ ) を指定する */ fp = fopen( "SLP.dat", "rb" ); /* ここからデータを読みこむための for ループが始まる 読みこみたいレコードの個数だけ反復する ここでは 1981 年から 2010 年までの 1 月のレコードを読みこむ */ for (iy=1981; iy<=2010; iy++) /* レコード番号を計算する ここでは 25 番目 (i=12) から 373 番目 (i=372) までのレコードを読みこむ */ i = 12 * (iy-1979); /* ファイルポインタ fp で指定されたファイルの所定の位置に移動する 第 3 引数に SEEK_SET を指定し ファイルの先頭を位置の基準とする ファイルの先頭から i*mmax*lmax*sizeof(float) バイトだけ前方に移動する */ fseek( fp, i*mmax*lmax*sizeof(float), SEEK_SET ); /* 配列 b の各要素の値をファイルポインタ fp で指定されたファイルから読みこむ 項目のサイズは浮動小数点のサイズ sizeof(float) を指定する 項目の数は mmax*lmax を指定する */ fread( b, sizeof(float), mmax*lmax, fp ); 21

/* 配列 b の各要素を配列 a の各要素に加える */ for (m=0; m<=mmax-1; m++) for (l=0; l<=lmax-1; l++) a[m][l] = a[m][l] + b[m][l]; /* ここで for ループが終了する */ /* ファイルを閉じる */ fclose( fp ); /* 平均値を計算する */ /* 配列 A の各要素をレコードの個数で割る */ for (m=0; m<=mmax-1; m++) for (l=0; l<=lmax-1; l++) a[m][l] = a[m][l] / 30.; /* データを書き出す */ /* ファイルを開く モードは "wb"( バイナリファイルへの書き出し ) を指定する */ fp = fopen( "output.dat", "wb" ); /* 配列 a の各要素の値をファイルポインタ fp で指定されたファイルに書き出す 項目のサイズは浮動小数点のサイズ sizeof(float) を指定する 項目の数は mmax*lmax を指定する */ fwrite( a, sizeof(float), mmax*lmax, fp ); /* ファイルを閉じる */ fclose( fp ); 22

return 0; 作図例 : ここで 東西平均からのずれを計算してみます まず 2011 年 1 月のデータを読みこんで それぞれの緯 度において 東西平均 ( 全経度のデータの平均 ) を計算します その後で 各経度での値から東西平均の値を 差し引きます プログラム : FORTRAN C PARAMETER 文で定数 LMAXとMMAXを宣言する C 定数 LMAXは経度方向の格子数を MMAXは緯度方向の格子数を表す PARAMETER (LMAX=144,MMAX=73) C 配列 A B を宣言する REAL A(LMAX,MMAX),B(MMAX) C データを読みこむ C ファイルを開く C 機番は 10 以降の番号を指定する 23

C STATUSは読みこみの場合は 'OLD' を指定する C バイナリファイルの場合は FORMには 'UNFORMATTED' を指定する C さらに ACCESSには 'DIRECT' を指定し C RECLにはレコード長をバイト数 ( 整数値 ) で指定する C 各要素は4バイトなので レコード長は4 要素数である OPEN(10,FILE='SLP.dat',STATUS='OLD', + FORM='UNFORMATTED', + ACCESS='DIRECT',RECL=4*LMAX*MMAX) C READ 文でデータを読みこむ C 機番 10を指定する REC=... でレコード番号を指定する C ここでは 385 番目のレコードを読みこむ C 読みこんだデータを配列 Aに格納する READ(10,REC=385) A C ファイルを閉じる CLOSE(10) C 東西平均値を計算する C 配列 Bの各要素にゼロを代入する DO 11 M=1,MMAX B(M) = 0. 11 CONTINUE C ここから東西平均を計算するための DO ループが始まる DO 21 M=1,MMAX C 配列 Aの各経度での値を配列 Bに加える DO 31 L=1,LMAX B(M) = B(M) + A(L,M) 31 CONTINUE C 配列 B の各要素の値を経度方向の格子数で割る B(M) = B(M) / REAL(LMAX) C ここで DO ループ 21 が終了する 21 CONTINUE C 東西平均値からの偏差を計算する 24

C 配列 Aの各要素の値から 配列 Bの対応する要素の値を差し引く DO 41 M=1,MMAX DO 42 L=1,LMAX A(L,M) = A(L,M) - B(M) 42 CONTINUE 41 CONTINUE C データを書き出す C ファイルを開く C 機番は10 以降の番号を指定する C STATUSは書き出しの場合は 'UNKNOWN' を指定する C バイナリファイルの場合は FORMには 'UNFORMATTED' を指定する C さらに ACCESSには 'DIRECT' を指定し C RECLにはレコード長を整数値で指定する OPEN(10,FILE='output.dat',STATUS='UNKNOWN', + FORM='UNFORMATTED', + ACCESS='DIRECT',RECL=4*LMAX*MMAX) C 配列 A の各要素の値を機番 10 で指定されたファイルに書き出す C REC=1 と指定し 1 番目のレコードとして出力する WRITE(10,REC=1) A C ファイルを閉じる CLOSE(10) STOP END ( 参考 )C #include <stdio.h> int main(void) /* 定数 mmax と lmax を宣言する 定数 mmax は緯度方向の格子数を lmax は経度方向の格子数を表す */ int mmax=73, lmax=144, m, l; 25

/* 配列 a b を宣言する */ float a[mmax][lmax], b[mmax]; /* ファイルポインタ fp を宣言する */ FILE *fp; /* データを読みこむ */ /* ファイルを開く モードは "rb"( バイナリファイルの読みこみ ) を指定する */ fp = fopen( "SLP.dat", "rb" ); /* ファイルポインタ fp で指定されたファイルの所定の位置に移動する 第 3 引数に SEEK_SET を指定し ファイルの先頭を位置の基準とする ここでは 385 番目のレコードを読みこむので まず ファイルの先頭から (385-1)*mmax*lmax*sizeof(float) バイトだけ前方に移動する */ fseek( fp, (385-1)*mmax*lmax*sizeof(float), SEEK_SET ); /* 配列 a の各要素の値をファイルポインタ fp で指定されたファイルから読みこむ 項目のサイズは浮動小数点のサイズ sizeof(float) を指定する 項目の数は mmax*lmax を指定する */ fread( a, sizeof(float), mmax*lmax, fp ); /* ファイルを閉じる */ fclose( fp ); /* 東西平均値を計算する */ /* 配列 b の各要素にゼロを代入する */ for (m=0; m<=mmax-1; m++) b[m] = 0.; /* ここから東西平均を計算するための for ループが始まる */ for (m=0; m<=mmax-1; m++) /* 配列 a の各経度での値を配列 b に加える */ 26

for (l=0; l<=lmax-1; l++) b[m] = b[m] + a[m][l]; /* 配列 b の各要素の値を経度方向の格子数で割る */ b[m] = b[m] / lmax; /* ここで for ループが終了する */ /* 東西平均値からの偏差を計算する */ /* 配列 a の各要素の値から 配列 b の対応する要素の値を差し引く */ for (m=0; m<=mmax-1; m++) for (l=0; l<=lmax-1; l++) a[m][l] = a[m][l] - b[m]; /* データを書き出す */ /* ファイルを開く モードは "wb"( バイナリファイルへの書き出し ) を指定する */ fp = fopen( "output.dat", "wb" ); /* 配列 a の各要素の値をファイルポインタ fp で指定されたファイルに書き出す 項目のサイズは浮動小数点のサイズ sizeof(float) を指定する 項目の数は mmax*lmax を指定する */ fwrite( a, sizeof(float), mmax*lmax, fp ); /* ファイルを閉じる */ fclose( fp ); return 0; 27

作図例 : 客観解析データは 数値モデルに観測値を取りこみながら時間発展させて得られた格子点データです 現業 の天気予報や学術研究では観測値とみなして利用することも多いですが 厳密には観測値ではない点に注意が 必要です 課題 :2011 年 1 月の月平均海面気圧 500hPa 面高度 850hPa 面気温の偏差を計算せよ ここでは 平年値 (1981 年から 2010 年までの 30 年間の平均値 ) からのずれを偏差と定義する 海面気圧の偏差の計算に用いたプログラム (anomaly.f[.c]) と 海面気圧 (SLP.ps) 500hPa 面高度 (Z500.ps) 850hPa 面気温 (T850.ps) の偏差を作図した図を提出せよ なお 作図する領域は北緯 20 度以北の全経度域とし ポーラーステレオで作図せよ この演習では NCEP/NCAR( 米国環境予測センター / 米国大気研究センター ) による客観解析データを用い ています 28