yyの日記

大気海洋に関する研究の個人的備忘録です。

サーバー上のディスクをマウントするのを自動化

普段、オフィスのある建物内からだけアクセスできるサーバーに大きなデータをおいている。小さめの計算や、図等をインタラクティブにチェックする作業の際は、サーバーのディスクを手元のPCにマウントして使っている。ただそのときに、手元のマシンを再起動させたりすると再マウントがめんどくさい。そこで、そのあたりの作業を全部起動時に行うようにした。


  • やりたいこと サーバー(SERVER)上のあるディレクトリ(s_dir: 絶対パス) をnfsマウントで、あたかも外付けHDDを繋いだ時のように扱う。 OSはmac OS High Sierra (ver. 10.13.4)

1 マウント用のディレクトリ作成

外付けHDDを繋いだ時のように使いたかったので、ローカルマシンの/Volumes以下にディレクトリを作成。

sudo mkdir /Volumes/dir

2 nfsマウント

マウントは以下のようにする。

sudo mount_nfs -P SERVER:s_dir /Volumes/dir

3 (好みで)sudo時にパスを求められないようにする

sudo時にパスワードを入力がめんどくさかったので、以下の設定をした。 セキュリティ的によくない気がするので実行には注意(私は後からこの設定はやめました)。

visudoでできる。viによる編集。

sudo visudo  

3行目を追加。名前は自分のユーザー名にすること。

root    ALL=(ALL) ALL
%admin  ALL=(ALL) ALL
hoge ALL=(ALL) NOPASSWD: ALL #この行を追加。hogeは自分のユーザー名

4 ~/.bash_profileに記述

ログイン時にディレクトリがなければ、ディレクトリ作成、マウントをするように、1,2の手順を以下のように記述(ログインシェルがbashの場合のみ)。

if [ -e /Volumes/dir ]; then
    echo "Data dir -> /Volumes/dir"
else
    echo "nfs_mount SERVER:s_dir to /Volumes/dir"
    sudo mkdir /Volumes/dir
    sudo mount_nfs -P SERVER:s_dir /Volumes/dir
fi

これでターミナルを開いたら勝手にディスクがマウントされて楽です。

ヘッダーつきバイナリデータを、好き勝手に色々とインストールできないサーバー上で処理したときの出力形式に関するメモ。

タイトルのようなことが起きて、色々試してみた結果のメモ。 結果的には、numpy.savezを使って.npz拡張子のファイルとして出力することにした。

というのも、エンディアンや配列のオーダー(列指向or行指向)を丁寧に扱うのがめんどい&混乱しそうで、結局pythonで読み込むのであれば全部numpyで完結させればええやんと思ったから。

  • 使い方
np.savez('filepath/file.npz',var1=var1,var2=var2,...)

or

np.savez_compressed('filepath/file.npz',var1=var1,var2=var2,...)

二つの違いは、np.savez:非圧縮、実行速度が速め?、np.savez:圧縮、実行速度が遅め?。 以下はテストプログラムの結果。

"""
データを読み込んだりする部分
今回は月毎のデータ1年分2.3GBのファイルから、
はじめの月のデータを読み込んでそれをアウトプット。
変数tに格納してある。
"""

tmpdate = np.array(datetime(year,mon+1,1))

tstart = time.time()
np.savez('test.npz',time=tmpdate,temp=t)
tend = time.time()

tstart2 = time.time()
np.savez_compressed('test2.npz',time=tmpdate,temp=t)
tend2 = time.time()

print('np.savez: {0}'.format(tend-tstart)+'[sec]')
print('np.savez_compressed: {0}'.format(tend2-tstart2)+'[sec]')

結果

np.savez: 11.986746072769165[sec]
np.savez_compressed: 31.117304801940918[sec]

ちなみにファイルサイズは、test.npz:886MB、test2.npz:174MB。

使い分けが必要そうだ。

温度・塩分から海水密度の計算(主にpython)

海水の密度を計算する場面というのは多々あると思います。 私はユネスコ状態方程式を計算するfortranサブルーチンをこれまで利用してきましたが、 pythonでの解析に適したものが必要になったので、その内容をまとめました。


研究で使う場合は以下引用(詳細:Thermodynamic Equation of SeaWater TEOS-10)

If you use the GSW Oceanographic Toolbox we ask that you include a reference to McDougall and Barker (2011), whose full citation is: McDougall, T.J. and P.M. Barker, 2011: Getting started with TEOS-10 and the Gibbs Seawater (GSW) Oceanographic Toolbox, 28pp., SCOR/IAPSO WG127, ISBN 978-0-646-55621-5.


手持ちのモデルアウトプットで使ってみる。t, s(温度、塩分)から密度等を計算してみます。

  • 関数
"""
gsw.rho(SA,CT,p)

INPUT:

SA  =  Absolute Salinity                                        [ g/kg ]
CT  =  Conservative Temperature                                [ deg C ]
p   =  sea pressure                                             [ dbar ]
       (i.e. absolute pressure - 10.1325 dbar)
SA & CT need to have the same dimensions.
p may have dimensions 1x1 or Mx1 or 1xN or MxN, where SA & CT are MxN.
OUTPUT:

rho  =  in-situ density                                      [ kg m^-3 ]
"""
# EXAMPLE:
>>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
>>> CT = [28.8099, 28.4392, 22.7862, 10.2262,  6.8272,  4.3236]
>>> p =  [     10,      50,     125,     250,     600,    1000]
>>> rho = gsw.rho(SA,CT,p)
>>> print(rho)
[1021.83993574 1022.26245797 1024.42719541 1027.79015276 1029.837779
 1032.00245322]
gsw.cp_t_exact(SA,t,p)

INPUT:
SA   =   Absolute Salinity                                      [ g/kg ]
t    =   in-situ temperature (ITS-90)                          [ deg C ]
p    =   sea pressure                                           [ dbar ]
        ( ie. absolute pressure - 10.1325 dbar )
SA & t need to have the same dimensions.
p may have dimensions 1x1 or Mx1 or 1xN or MxN, where SA & t are MxN.
OUTPUT:
cp_t_exact   =   heat capacity of seawater                     [ J/(kg*K) ]

  • やってみた
"""
t: 温度
s: 塩分
p: 圧力(dbar)
"""
import time
import numpy as np
import gsw

""
t,s,pを読み込む部分(省略)
"""

print(t.shape)

rho = np.zeros(t.shape)
cp  = np.zeros(t.shape)
start = time.time()
for k in range(len(p)):
  rho[k,:,:] = gsw.rho(s[k,:,:],t[k,:,:],p[k])
  cp[k,:,:]  = gsw.cp_t_exact(cp[k,:,:],t[k,:,:],p[k])
print("elapsed_time:{0}".format(time.time()-start) + "[sec]")

結果

(63, 1280, 1440) # 配列のサイズ
elapsed_time:171.92075514793396[sec] 

まあこんなものでしょうか。例えば、CMIPモデルはもっと解像度低いですし、高解像モデルの場合でも必要な領域だけ切り出したりすれば良いでしょう。

何より、地衡流流線関数や浮力振動数計算などT,Sから計算できるものは、だいたい関数が用意されているのがありがたいです。