HITRAN データベースの API, HAPI の使い方

# 初めに
[HITRAN](https://hitran.org/)は、大気の吸収線のデータベースです。IR 測定などで得られたスペクトルのピークなどを同定する際に使うことができます。そして、HITRAN では[HAPI](https://hitran.org/hapi/)という HITRAN アプリケーションプログラミングインタフェースが公開されています。これは、HITRAN によって提供される機能とデータへのリモートアクセスを提供することを目的とした Python のルーチンのセットです。ここでは、この API の使い方を紹介します。HAPI 詳しい使い方は、[公式のリファレンス](https://hitran.org/static/hapi/hapi_manual.pdf)を参照してください。

# HAPI の基本的な使い方
まず、[公式のページ](https://hitran.org/hapi/)から、`hapi.py`をダウンロードしてください。このファイルのあるディレクトリで

```python
from hapi import *
```

とすれば、この API を使うことができます。

まず、ローカルデータベース用のフォルダを選択します。 Python プロジェクトを起動するたびに、データベースフォルダの任意の名前を指定する必要があります。

```python
db_begin('data')
```

そして、データをダウンロードするには、関数`fetch`を呼び出します。 これにより、メインサーバーからデータが取得されます。 例えば、$\mathrm{H}_2\mathrm{O}$ の、400 cm$^{-1}$ から 4000 cm$^{-1}$ までのデータを取得するためには、

```python
fetch('H2O',1,1,400,4000)
```

とします。第一引数は、ローカルでのテーブル名になります。自分の分かりやすいように、任意につけることができます。第二引数、第三引数は、それぞれ HITRAN での `moleculeID`、`isotopologueID`です。これは、[HITRAN の line-by-line のページ](https://hitran.org/lbl/)で探すことができます。Select Molecules のページの ID が、第二引数のもので、その次の Select Isotopologues のページの ID が、第三引数のものです。例えば、上の例では、$\mathrm{H}_2^{16}\mathrm{O}$ のデータをダウンロードしています。第三、第四引数は、取得したいスペクトルの初めから終わりまでを指定します。この関数は、一度実行するとローカルにデータが残るため、二度目以降の実行の際は、この関数を呼ぶことを省略することができます。

また、取得したテーブル（または、関数`select`で自分で作成したテーブル）からカラムを取得する関数に、`getColumn(...)`,`getColumns(...)`があります。これは例えば次のように使用します。

```python
nu1 =getColumn('H2O','nu')
nu2,sw2 =getColumns('H2O',['nu','sw'])
```

第一引数は、データベースのテーブルの名前、第二引数は、取得したいデータの名前です。第二引数に使用する名前は、[公式のリファレンス](https://hitran.org/static/hapi/hapi_manual.pdf)9ページにある表 Parameter identifiers used in HAPI の Identifier の欄にあります。上の例では、`nu`が遷移波数、`sw`が遷移強度です。

さらに、関数`select`を用いることで、データを処理してテーブルを作ったり、データをファイルに書き出したりすることができます。詳しくは、公式リファレンスを参照してください。

# IR ピークの同定
HITRAN から得られたデータを、`plotly`を用いて表示してみます。

```python
from hapi import *
import numpy as np
import plotly

# パラメータを指定
# --- ここから ---

# スペクトルの範囲
spectrum_begin = 400 # cm^-1
spectrum_end = 4000

# HITRAN のパラメータ
name = 'H2O' 
moleculeID = 1
isotopologueID = 1

# --- ここまで ---

db_begin('data')

fetch(name, moleculeID, isotopologueID, spectrum_begin, spectrum_end)

# 取得したテーブルから、必要な情報を取得
nu, sw = getColumns(name, ['nu', 'sw']) # 波長, 線強度

# 振動準位の上下を取得
global_upper_quanta, global_lower_quanta = getColumns(name, ['global_upper_quanta','global_lower_quanta'])

# 回転準位の上下を取得
local_upper_quanta, local_lower_quanta = getColumns(name, ['local_upper_quanta','local_lower_quanta'])

# 以下、グラフ作成

# グラフに表示するための、量子数のラベルを作成
graph_label = ['global : ' + str(a)  + str(b) +  '   lolal : ' + str(c) + str (d) for a, b, c, d in zip(global_upper_quanta, global_lower_quanta, local_upper_quanta, local_lower_quanta)]

# プロットするデータの指定
data = [
    plotly.graph_objs.Scatter(x=nu, y=sw, name="HITRAN\'s " + str(name) + " data",mode = 'markers', text=graph_label)
]

# グラフレイアウトの指定
layout = plotly.graph_objs.Layout(
    title="HITRAN\'s " + str(name) + " data from " + str(spectrum_begin) + " to "  + str(spectrum_end),
    xaxis={"title":"1/CM"},
    yaxis={"title":"Line intensity"}
)

# プロット
fig = plotly.graph_objs.Figure(data=data, layout=layout)
plotly.offline.iplot(fig)
```

上記のものを実行すると、

![Screenshot from 2019-08-05 00-01-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195827/ff383ead-0b78-7a26-8381-da051b2d2422.png)

のようなグラフができます。このグラフは拡大、縮小可能で、軸もスライドさせることができます。また、プロットの点にカーソルを合わせると、それぞれの準位の変化が表示されるようになっています。（個人的に、`plotly`はとても便利だと思います。）ここで、グラフで吹き出しの中に表示されているものは、glbal、local どちらも左側のほうが高い準位の量子数です。この量子数の見方は、[The HITRAN 2004 molecular spectroscopic database](https://hitran.org/media/refs/HITRAN-2004.pdf)の 7, 8 ページ目を参照してください。この場合、global のものは、それぞれ$v_1$, $v_2$, 及び$v_3$、localのものは$J$, $K_ a$, 及び$K_c$ だと思われます。

ピーク同定の際は、上記のグラフのように表示したものに、同定したいスペクトルを重ねて表示すれば、ピークを同定することができると思われます。（その際、ピークが上向きになるように、スペクトルの絶対値を表示すると見やすいかもしれません。）

# データのファイルへの書き出し
関数`select`を用いることで、データベースのデータを処理して、データベースのテーブルを作ったり、データをファイルに書き出したりすることができます。データをファイルに書き出す例を、以下に示します。

```python
import numpy as np
from hapi import *

# パラメータを指定
# --- ここから ---

# スペクトルの範囲
spectrum_begin = 400 # cm^-1
spectrum_end = 4000

# HITRAN のパラメータ
name = 'H2O' 
moleculeID = 1
isotopologueID = 1

# --- ここまで ---

db_begin('data')

fetch(name, moleculeID, isotopologueID, spectrum_begin, spectrum_end)

file_name = str(name) + '_from_' + str(spectrum_begin) + '_to_'\
              + str(spectrum_end) + '.txt'

select(name, ParameterNames=('nu','sw','global_upper_quanta',
       'global_lower_quanta','local_upper_quanta','local_lower_quanta'), File=file_name)
```

# 吸光係数の計算
HITRAN から得られるデータから、吸光係数を計算してみます。詳しくは、公式リファレンスを参照してください。圧力、温度、気体の組成など、様々なパラメータを指定することができます。また、吸光係数を計算する際に使用する関数を選ぶことができます。また、次の例では matplotlib でグラフを作成しています。

```python
import numpy as np
from hapi import *
import matplotlib.pyplot as plt

# パラメータを指定
# --- ここから ---

# スペクトルの範囲
spectrum_begin = 400 # cm^-1
spectrum_end = 4000

# HITRAN のパラメータ
name = 'H2O' 
moleculeID = 1
isotopologueID = 1

# 気圧、温度を指定
pressure = 1. # atm
temperature = 296. # K

# --- ここまで ---

db_begin('data')

fetch(name, moleculeID, isotopologueID, spectrum_begin, spectrum_end)

# 指定した気圧と温度の吸光係数を計算
axis_hitran, value_hitran = absorptionCoefficient_SDVoigt(((moleculeID,isotopologueID),), name,
                                          Environment = {'p':pressure,'T':temperature})

# グラフを作成

fig = plt.figure(figsize=(9, 4.5), dpi = 200)
ax = fig.add_subplot(111)
ax.set_title("Calculated " + str(name) + " absorption coefficient from " + str(spectrum_begin)\
             + " to " + str(spectrum_end))
ax.set_xlabel("1/CM")
ax.set_ylabel("absorption coefficient")
ax.grid(True)
ax.set_xlim([spectrum_begin, spectrum_end])
ax.plot(axis_hitran, value_hitran, linewidth = 0.5)

# グラフを表示
plt.show()
plt.close()
```

上記のものを実行すると、次のようなグラフが得られます。

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195827/7840a73c-a5da-162d-7824-7cc2498fca56.png)

また、装置関数をシミュレーションして表示する際は、例えば

```python
nu_,trans_,i1,i2,slit = convolveSpectrum(axis_hitran,value_hitran, SlitFunction=SLIT_GAUSSIAN, Resolution=1.)
```

のように書き加えてください。`nu_`、`trans_`に装置関数(この例では GAUSSIAN)を考慮した結果が代入されています。引数の `Resolution` には、波数の単位での装置の分解能を指定してください。

# まとめ
オンラインデータベース HITRAN の APIである HAPI を用いることで、IR ピークを同定することができたり、データをファイルに書き出したり、吸光係数を計算したりすることができます。