Numpy + Python3 > WPSのmetgrid.exeで読まれるFortran出力ファイル(big endian)を作成する

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2 
32GB RAM 
CentOS Linux release 7.7.1908 (Core)
Python 3.6.8 (default, Aug  7 2019, 17:28:10) 
IPython 7.9.0 -- An enhanced Interactive Python. Type '?' for help.
Scipy v1.4.1
```

WRF (Weather Research and Forecasting Model)関連。
前処理のWPSについて。

### 概要

- WPSで使うSSTファイルを自前で用意する
    - 関連: [2020-01-10 WRF > NCEP SST Analysis > EOL: サポート終了](https://qiita.com/7of9/items/e657a564a0245fae496d)
    - 関連: [2020-01-15 WRF > NCEP SST Analysisデータ終了後のSSTデータの選択 > OI SSTデータの使用](https://qiita.com/7of9/items/39ae638926341b73c769)
- WPSのmetgrid.exeにて使う形式を作成する
- Fortranプログラムで書き出す例は公式サイトなどにある
- Numpyで処理をしたいため、Fortran出力と同じようになるように実装をした
    - big endian

### 参考情報

- [Reading Fortran binary file in Python](https://stackoverflow.com/questions/53639058/reading-fortran-binary-file-in-python)
    - FortranFile()でbig endian指定の例(`>`)がある
- [NumPyのデータ型dtype一覧とastypeによる変換（キャスト）](https://note.nkmk.me/python-numpy-dtype-astype/)
    - character型の記載はない？

### はまったところ

character定義の出力のdtype指定(`c`)に気づくまで時間がかかった。

### 確認方法と確認ツール

以下を比較することで、プログラムのデバッグを行った。

A. 提供終了したSSTファイルをungrib.exe実行した結果ファイル
B. 本記事のスクリプトで生成したファイル

内容はhexdumpで確認した。

```
$ hexdump -c SST_met 
0000000  \0  \0  \0 004  \0  \0  \0 005  \0  \0  \0 004  \0  \0  \0 234
0000010   2   0   1   9   -   1   1   -   0   1   _   0   0   :   0   0
0000020   :   0   0                      \0  \0  \0  \0   N   C   E   P
```

### 実装

```intermediateFile_200117.py
import numpy as np
from scipy.io import FortranFile

# on Pyhont 3.6.8
# checked with PEP8

# About: Save to intermediate file for metgrid.exe

frt = FortranFile('SST_met', 'w', '>u4')
version = 5
frt.write_record(np.array([version], dtype='>i4'))

#        123456789012345678901234
hdate = '2019-11-01_00:00:00     '
xfcst = 0.00000000
#             12345678901234567890123456789012
map_source = 'NCEP SST Analysis       GRID 173'
#        123456789
field = 'SST      '
#        1234567890123456789012345
units = 'K                        '
#       1234567890123456789012345678901234567890123456
desc = 'Sea Surface Temperature                       '
xlvl = 200100.000  # 200100 for surface, 201300 for SLP
nx, ny = 4320, 2160
iproj = 0

print(hdate)
d1 = np.array([hdate], dtype='c')
d2 = np.array([xfcst], dtype='>f4')
d3 = np.array([map_source], dtype='c')
d4 = np.array([field], dtype='c')
d5 = np.array([units], dtype='c')
d6 = np.array([desc], dtype='c')
d7 = np.array([xlvl], dtype='>f4')
d8 = np.array([nx], dtype='>i4')
d9 = np.array([ny], dtype='>i4')
d10 = np.array([iproj], dtype='>i4')
frt.write_record(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10)

startloc = 'SWCORNER'
startlat = 89.9583359
startlon = 4.16669995E-02
deltalat = -8.33333358E-02
deltalon = 8.33333358E-02
earth_radius_km = 6371.22900
d1 = np.array([startloc], dtype='c')
alist = [startlat, startlon, deltalat, deltalon, earth_radius_km]
d2 = np.array(alist, dtype='>f4')
frt.write_record(d1, d2)

is_wind_grid_rel = 0
frt.write_record(np.array([is_wind_grid_rel], dtype='>i4'))

ssts = np.full((nx, ny), 273.15, dtype='>f4')
frt.write_record(ssts)  # TODO: need transpose by using .T ?

frt.close()
```

### 実行

```
$ python3 intermediateFile_200117.py                                                            
2019-11-01_00:00:00     
```

`SST_met`ファイルが生成される。
そのファイルは以下のプログラムで内容確認できる。

- [WRF / WPS > Fortran90 > metgrid.exeで読込む中間ファイルのReadプログラム](https://qiita.com/7of9/items/f1f0c85432010cea1d3c)


### 関連

- [User's Guide for the NMM Core of the Weather Research and Forecast (WRF) Modeling System Version 3 ](https://dtcenter.org/wrf-nmm/users/docs/user_guide/V3/old/users_guide_nmm_chap3.pdf)
    - p3-25 Writing Meteological Data to the Intermediate Format
- [OISSTにSSTデータを差し替える](https://sites.google.com/site/afcwrf/home/preproc/oisst)
- [The FortranFile class](https://scipy-cookbook.readthedocs.io/items/FortranIO_FortranFile.html)
- [Scipy > FortranFile() > big endianでのFortran用データファイルの作成](https://qiita.com/7of9/items/b8eda643e656564794cc)

### 補足

FortranFile()というのはScipy以外にも実装が見つかった。
https://pypi.org/project/fortranfile/
そちらのFortranFile()には`endian`指定があったが、Scipyの方には`endian`指定はない。
同じ名前のクラスが別の団体？で用意されているので混乱のもとになった。