FITSIO入門(Fortran版)

東京大学理学部天文学教育研究センター  濱部 勝

FITSIOサブルーチンライブラリ

FITSIOはNASAのHEASARCでDr. W. D. Pence等によって開発保守されている FITSファイルを扱うためのサブルーチンライブラリである。Fortran版とC版が あるがここではFortran版のみを扱う。

FITSIOは今だ改良が続けられているライブラリであり、必ずしも上位互換 にはなっていないようである。使用時にはバージョンに注意していただきたい。 ここでの記述は、4.1.4版を元にしている。

ここではごく簡単に使用例などを示すだけにとどめるので、詳しくはFITSIOと共に 配付されているマニュアルおよびクックブックを参照していただきたい。

データ型とサブルーチンのファミリー

多くのサブルーチンは、様々なデータ形式をサポートする個々のサブルーチンの ファミリーとして提供されている。同じファミリーに属するサブルーチンは、 サブルーチン名の末尾の1文字のみが異なっており、その文字が
        x - bit
        b - character*1 (unsigned byte)
        i - short integer (I*2)
        j - integer (I*4)
        e - real exponential floating point (R*4)
        f - real fixed-format floating point (R*4)
        d - double precision real floating-point (R*8)
        g - double precision fixed-format floating point (R*8)
        c - complex reals (pairs of R*4 values)
        m - double precision complex (pairs of R*8 values)
        l - logical (L*4)
        s - character string
というように扱うデータの型を示している。

Reading an existing FITS file

以下は、既に存在するFITSファイルを読み込む場合のサブルーチン呼出しの 流れの簡単な例である。(もっと詳しくは英文マニュアルあるいはクックブックを 参照のこと)
 1. FTOPENを用いてファイルを開く.
 2. 必要なキーワードをFTGHPRあるいはFTGKYxを用いて読む.
 3. もし主配列データが存在すればFTGPVxあるいはFTGPFxで読む.
 4. 上記のステップ2と3を繰り返して全ての必要な情報を読む.
 5. FTMAHDあるいはFTMRHDを用いて次の拡張部へ移動する.
 6. 拡張ヘッダキーワードを読む(e.g. FTGHTB, FTGHBN あるいはFTGKYxを用いる)
 7. 拡張部からデータを読む(e.g. FTGCVxあるいはFTGCFxを用いる)
 8. 上記のステップ6と7を繰り返して全ての情報を読む.
 9. 更に拡張部があれば上記のステップ5から8までを繰り返す.
10. FTCLOSを用いてファイルを閉じる.
上記で FTGKYx などの x には先に述べた扱うデータの型を示す1文字が 入る。

新しいFITSファイルの作成

以下に示すものは、新しいFITSファイルを書く場合のサブルーチンの 呼出し流れの簡単な例である。
 1. FTINITを用いて新しいファイルを作成する.
 2. FTPHPRを用いて主配列に必須なキーワードを書く.
 3. 他に必要なキーワードがあればFTPKYxを用いて書く.
 4. 主配列データがあればFTPPRxを用いて書く.
 5. 拡張部が必要であればFTCRHDを用いて作成する.
 6. 拡張部の必須ヘッダキーワードをFTPHTBあるいはFTPHBNを用いて書く.
 7. 他に必要なキーワードがあればFTPKYxを用いて書く.
 8. FTPCLxを用いて拡張部へデータを、一度に1カラムずつ書く.
 9. さらに拡張部を必要とするなら上記のステップ5〜8を繰り返す.
10. FITSファイルをFTCLOSを用いて閉じる.
ここで、必須キーワード'END'を明示的に書こうとしてはいけないことに 注意する。ENDキーワードはヘッダが閉じられる時に自動的に付加される。

エラー処理

FITSIOには、サブルーチン呼出し後にサブルーチンが返すエラーコードを 解釈して文字列として表すためのサブルーチン FTGERR が含まれている。 これをうまく使うとプログラムのデバッグが非常に楽になる。

プログラム例

以下に、FITSファイルを読み書きするプログラムの非常に簡単な例を示す。 このプログラムは 512 × 512までのFITS画像を読み、それに 2×2のビンニング を施した後、別のFITSファイルとして出力するものである。 プログラムのコンパイルは、以下の例のプログラムソースをtest.fとする時、
                % f77 -o test.e test.f -lfitsio
といったふうにすれば良いはずである。

プログラム例


      program fitsbin

      character sfile*80, title*40, title0*40, comment*80
      character dfile*80, errmsg*80
      integer   im, nim, naxes(2), pcount, gcount, block 
      integer   rwmode, bitpix, irc
      dimension G(512,512), WORK(256)
      logical   simple, anyf

      sfile='In.fits'
      dfile='Out.fits'

c---- open an input FITS file in read-only mode
      call FTGIOU(im,irc)                          ! get the unused I/O unit number 
      if ( irc.ne.0 ) go to 999
      rwmode=0                                     ! read-only mode
      call FTOPEN(im,sfile,rwmode,block,irc)       ! open FITS file with read-only mode
      if ( irc.ne.0 ) go to 999

C---- read the required primary array keywords
      maxdim=2
      call FTGHPR(im,maxdim,simple,bitpix,naxis,naxes,
     +     pcount,gcount,extendf,irc)              ! get primary header
      if ( irc.ne.0 ) go to 999
      iext=naxes(1)
      jext=naxes(2)

      call FTGKEY(im,'OBJECT',TITLE0,comment,irc)  ! get the literal keyword value
      if ( irc.ne.0 ) go to 999
      lquote=index(title0(2:),char(39))
      title=title0(2:lquote)
      write(*,'(''     Object :'',a)') title
      write(*,'(''     Image size ='',i4,'' x'',i4)') iext, jext
      group=0                                      ! non-grouped data
      nelements=iext*jext
      nullval=0                                    ! value to represent undefined pixels
      fpixel=1                                     ! the first pixel position
      call FTGPVE(im,group,1,nelements,nullval,G,anyf,irc)
      if ( irc.ne.0 ) go to 999                    ! get elements from the data array

      isub=iext/2
      jsub=jext/2
      naxis=2
      naxes(1)=isub
      naxes(2)=jsub

      call FTGIOU(nim,irc)                         ! get the unused I/O unit number
      if ( irc.ne.0 ) go to 999
      iblksize=1
      call FTINIT(nim,dfile,iblksize,irc)          ! open & initialize a new empty FITS file
      if ( irc.ne.0 ) go to 999
      morekeys=10
      call FTCOPY(im,nim,morekeys,irc)             ! copy the entire CHDU 
      if ( irc.ne.0 ) go to 999
      call FTCPDT(im,nim,irc)                      ! copy just the data from the CHDU
      if ( irc.ne.0 ) go to 999
      call FTUKYJ(nim,'NAXIS1',naxes(1),' ',irc)   ! update the keyword value
      if ( irc.ne.0 ) go to 999
      call FTUKYJ(nim,'NAXIS2',naxes(2),' ',irc)
      if ( irc.ne.0 ) go to 999
      call FTCLOS(im,irc)                          ! close the source FITS file
      if ( irc.ne.0 ) go to 999

      call fbin2(nim,g,work,iext,jext,isub,jsub)   ! some process
      if ( irc.ne.0 ) go to 999

      call FTCLOS(nim,irc)                         ! close the source FITS file
      if ( irc.ne.0 ) go to 999

      stop
 999  call FTGERR (irc, errmsg)                    ! return the descriptive text string  
                                                   ! corresponding to a FITSIO error code
      write(*,'('' Error: '',i5,'' '',a80)') irc,errmsg

      end
c-------------------------------------------------------------------
      subroutine fbin2(nim,g,work,iext,jext,isub,jsub)

      dimension g(iext,jext), work(isub)

      DO J=1,JSUB
         do i=1, isub
            work(i)=0.0
            do jj=(j-1)*2+1, (j-1)*2+2
               do ii=(i-1)*2+1, (i-1)*2+2
                  work(i)=work(i)+g(ii,jj)
               end do
            end do
            if ( mode.eq.0 ) work(i)=work(i)/float(2*2)
         end do
         call FTPPRE(nim,0,(j-1)*isub+1,isub,work,irc) ! put elements into the data array
      END DO

      return
      end