白黒画像は多数の1バイトデータからなります.1バイトのデータ(8個の0と1)をそのまま書き込んだファイルをバイナリファイルと呼びます.今まで扱ってきた,人間が読めるファイルは「テキストファイル」といって区別されます.
今回あつかうデータはバイナリファイルのため,バイナリファイルの読み書きを行う必要があります.次のプログラムは,0.1から1.0までの10個の単精度実数を生成し,それをバイナリ形式でファイル10.datに書き込むプログラムです.
implicit none integer i real x open(1,file='10.dat',access='direct',form='unformatted',recl=4) do i=1,10 x=0.1*i write(1,rec=i) x enddo end
ここで,form='unformatted'でバイナリ形式を指定し,recl=4で一つのデータ(レコード)の大きさ(今の場合単精度=4バイト=32ビット)を指定します.access='direct'は,直接参照ファイルであることを指定します.今までは'sequential'となっていて,前から順番にファイルにアクセスすることが暗に指定されていました.またwrite文では,rec=iでレコード番号を指定します.このプログラムを実行し,生成された10.datのサイズが40バイトになっていることを確認しましょう.
先ほど生成したデータを読み込んで画面に表示するプログラムは以下になります.
implicit none integer i real x open(1,file='10.dat',access='direct',form='unformatted',recl=4) do i=1,10 read(1,rec=i) x write(6,*) x enddo end
実行して結果を確認しましょう.
今回扱う画像は白黒256階調なので,各ピクセルは1バイトのデータで表現されます.FORTRANでは符号なし1バイトデータを扱う適当な形式が用意されていないので,character文で宣言される文字型変数に数値を格納します.
第七回に解説しましたが,文字には文字コードと呼ばれる数字が対応しています.そこで,0から255までの整数を文字に一度変換し,その文字をファイルに書き込むと,0から255までの整数(文字コード)がファイルに書き出されます.
0から255までの整数をバイナリデータとしてファイル256.datに書き込み,そのデータを読み出して0から255までの整数を画面に表示するプログラムは以下になります.
implicit none character n integer i open(1,file='256.dat',form='unformatted',recl=1) do i=0,255 n=char(i) write(1,rec=i+1) n enddo do i=1,256 read(1,rec=i) n write(6,*) i,ichar(n) enddo end
このデータは,1980年-2000年における全地球の表面気温のデータです.360x180=64800個の4バイトデータ(単精度実数)が並んだファイルが21個あります.それぞれのデータは地球上のある経度(0-359),緯度(0-179)における温度です.注意してほしいのは,二次元的にデータが並んでいるわけではなく,一次元的にデータは並んでいることです.ダウンロードしてunzip data.zipで解凍してください.するとdataディレクトリが生成され,その中にファイルが展開されます.それらのファイルをすべて現在のディレクトリにmv ./data/*.raw ./ コマンドで移動させてください.次に,2,3章で学んだテクニックを用いて
先ほどのデータを256階調の白黒画像にしましょう.練習問題1のプログラムに引き続き,以下の作業を行ってください.
今回は,1980年から2000年までの21年分のデータを解析し,その温度上昇のトレンドが地域ごとにどう分布しているかを調べます.
そのためには,ファイルを21個開かないといけません.正直にプログラムに記述してもいいのですが効率が悪いので,今までに学んだ文字処理のテクニックを用いてファイルを操作します.次のプログラムを実行すると,21個のファイルを順番にオープンしてそのファイル名が画面に表示されます.
implicit none integer i,num,nyear character name*12,year*4,bc nyear=21 do i=1,nyear num=1979+i write(year,'(I4)') num name='temp'//year//'.raw' write(6,*) name open(10+i,file=name,access='direct',form='unformatted',recl=4) enddo end
write(year,'(I4)') num で,4桁の整数numが文字となって文字型変数yearに格納されます.
さてここまでくると,全地球の温度変化を解析できるようになりました.以下の手順を踏んで,地球上のどこで温暖化がより進行しているのか解析しましょう.
最後まで実行できたら,以下の点を観察してください.