astropy.ioでfitsファイルの情報を取得する

更新履歴: 2019 May 31, twitterにて間違い指摘と有益情報をもたらしてくださった有志の方に感謝。

# 概要

[以前の記事「PythonでHEALPixを描画する」](https://qiita.com/github-nakasho/items/6d2e06a3caca1f00f58a)で、.fitsファイルからI_StokesやQ_Stokesを描画してみました。今回はそのファイルの描画ではなく、詳細な情報を見てみましょう。

# astropy.io
以下のように必要なモジュール、今回の場合はfitsをimportします。

```python
from astropy.io import fits as ft
```

## fits
[Planck衛星のデータ](https://pla.esac.esa.int/#maps)をダウンロードして、それを読み込んでみましょう。

```python
# read Planck data
planck_map = ft.open('./LFI_SkyMap_030_1024_R2.01_full.fits')
```

## 情報を見る

### header

この`planck_map`変数の情報を見てみましょう。以下のようにして情報を見ることができます。

```python
print(repr(planck_map[0].header))
```

出力を見てみましょう。

```
SIMPLE  =                    T / file does conform to FITS standard             
BITPIX  =                   16 / number of bits per data pixel                  
NAXIS   =                    0 / number of data axes                            
EXTEND  =                    T / FITS dataset may contain extensions            
COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy
COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H                                       
```

`repr`関数は対話モードのように表示するためだけに使用しているため、あってもなくても構いません。
次に以下のようにしてみます。

```python
print(repr(planck_map[1].header))
```

すると出力は以下のようになります。

```
XTENSION= 'BINTABLE'           / binary table extension                         
BITPIX  =                    8 / 8-bit bytes                                    
NAXIS   =                    2 / 2-dimensional binary table                     
NAXIS1  =                   40 / width of table in bytes                        
NAXIS2  =             12582912 / number of rows in table                        
PCOUNT  =                    0 / size of special data area                      
GCOUNT  =                    1 / one data group (required keyword)              
TFIELDS =                   10 / number of fields in each row                   
TTYPE1  = 'I_Stokes'           / label for field   1                            
TFORM1  = 'E       '           / data format of field: 4-byte REAL              
TUNIT1  = 'K_CMB   '           / physical unit of field                         
TTYPE2  = 'Q_Stokes'           / label for field   2                            
TFORM2  = 'E       '           / data format of field: 4-byte REAL              
TUNIT2  = 'K_CMB   '           / physical unit of field                         
TTYPE3  = 'U_Stokes'           / label for field   3                            
TFORM3  = 'E       '           / data format of field: 4-byte REAL              
TUNIT3  = 'K_CMB   '           / physical unit of field                         
TTYPE4  = 'Hits    '           / label for field   4                            
TFORM4  = 'J       '           / data format of field: 4-byte INTEGER           
TUNIT4  = 'none    '           / physical unit of field                         
TTYPE5  = 'II_cov  '           / label for field   5                            
TFORM5  = 'E       '           / data format of field: 4-byte REAL              
TUNIT5  = '(K_CMB)^2'          / physical unit of field                         
TTYPE6  = 'IQ_cov  '           / label for field   6                            
TFORM6  = 'E       '           / data format of field: 4-byte REAL              
TUNIT6  = '(K_CMB)^2'          / physical unit of field                         
TTYPE7  = 'IU_cov  '           / label for field   7                            
TFORM7  = 'E       '           / data format of field: 4-byte REAL              
TUNIT7  = '(K_CMB)^2'          / physical unit of field                         
TTYPE8  = 'QQ_cov  '           / label for field   8                            
TFORM8  = 'E       '           / data format of field: 4-byte REAL              
TUNIT8  = '(K_CMB)^2'          / physical unit of field                         
TTYPE9  = 'QU_cov  '           / label for field   9                            
TFORM9  = 'E       '           / data format of field: 4-byte REAL              
TUNIT9  = '(K_CMB)^2'          / physical unit of field                         
TTYPE10 = 'UU_cov  '           / label for field  10                            
TFORM10 = 'E       '           / data format of field: 4-byte REAL              
TUNIT10 = '(K_CMB)^2'          / physical unit of field                         
EXTNAME = 'FREQ-MAP'                                                            
DATE    = '2015-01-20T12:35:13' / file creation date (YYYY-MM-DDThh:mm:ss UT)   
COMMENT                                                                         
COMMENT *** Planck params ***                                                   
COMMENT                                                                         
PIXTYPE = 'HEALPIX '           / HEALPIX pixelisation                           
ORDERING= 'NESTED  '           / Pixel ordering scheme, either RING or NESTED   
NSIDE   =                 1024 / Resolution parameter for HEALPIX               
FIRSTPIX=                    0 / First pixel # (0 based)                        
LASTPIX =             12582911 / Last pixel # (0 based)                         
INDXSCHM= 'IMPLICIT'           / Indexing: IMPLICIT or EXPLICIT                 
EXTVER  =                    2                                                  
PROCVER = 'DX11D   '                                                            
BAD_DATA=          -1.6375E+30                                                  
FREQ    =                   30                                                  
COORDSYS= 'GALACTIC'                                                            
POLCCONV= 'COSMO   '           / Coord. convention for polarization (COSMO/IAU) 
FILENAME= 'LFI_SkyMap_030_1024_R2.01_full.fits'                                 
COMMENT ---------------------------------------------------------------------   
COMMENT LFI RIMO 12.1                                                           
COMMENT Madam version 3.7.4                                                     
COMMENT Added monopole offset 8.34887355761e-05 to column I_Stokes              
COMMENT LFI-DMC object:                                                         
COMMENT TOODI%ACCTOODI%%madam_IQUmap_LFI_calib_30GHz_DX11D_full_025_sec:0%      
COMMENT TOODI%ACCTOODI%%madam_hit_LFI_calib_30GHz_DX11D_full_025_sec:0%         
COMMENT TOODI%ACCTOODI%%madam_cov_LFI_calib_30GHz_DX11D_full_025_sec:0%         
COMMENT ---------------------------------------------------------------------   
CHECKSUM= 'Ec3CFc1BEc1BEc1B'   / HDU checksum updated 2015-01-20T12:35:18       
DATASUM = '706919705'          / data unit checksum updated 2015-01-20T12:35:18 
```

すると`TTYPE1`のように書かれた項目に`I_Stokes`や`Q_Stokes`があることがわかります。

### header['TTYPE3']

試しに以下を実行してみましょう。

```python
print(planck_map[1].header['TTYPE3'])
```

すると実行結果は以下のようになります。

```
U_Stokes
```

`TTYPE3`にはストークスパラメータのUのデータが入っていることがわかりました。

### header['NSIDE']

次はこの.fitsファイルの`n_side`を見てみます。

```python
print(planck_map[1].header['NSIDE'])
```

すると

```
1024
```

のように、この.fitsファイルが何pixelなのかを求めるために必要な情報を得ることができます。

### header['ORDERING']

次にこの.fitsファイルのオーダーを見てみましょう。ここでのオーダーとはpixelのナンバリングのルールを意味します。

<img width="640" alt="スクリーンショット 2019-05-30 17.21.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335400/110b7ed8-de35-952b-dc56-9020b5f8c4e9.png">
RING
<img width="643" alt="スクリーンショット 2019-05-30 17.21.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335400/13bd6fb5-a67c-1628-200b-2aae6c0d7434.png">
NESTED

それではオーダーを調べてみましょう。

```python
print(planck_map[1].header['ORDERING'])
```

すると

```
NESTED
```

であることがわかります。

# 結言

このメソッドを用いることで、いちいち.fitsをダウンロードしてきたウェブサイトで情報を調べなくても「この.fitsファイルが何のデータなのか、どのようなデータ構造なのか」をローカル環境で確認することができます。