CNSをスクリプトで便利に!  

単純なスクリプト  

CNS用のスクリプトを作成してみます。
CNSをスクリプトで使用する際は気を付けなければならない点を少し。

作成したスクリプト  

この時の状態を考慮して作成する必要があります。それで作成してみたスクリプトを載せてみます。

fileruncns
 1: #!/bin/bash
 2: TASK=$1
 3: 
 4: if *1
 5: then
 6:     echo "usage: runcns <taskname>"
 7:     exit 1
 8: fi
 9:
10: if [ ! -e $TASK.inp ]; then echo "$TASK.inp does not exist"; exit 1; fi
11:
12: # Run CNS
13: cns < ${TASK}.inp | tee ${TASK}.log
14: 
15: # Check CNS termination code
16: RES=$?
17: if *2   # User interruption (Ctrl-C)
18: then
19:     echo "Task [$TASK] terminated by user interruption ($RES)"
20:     exit $RES
21: elif *3   # Other errors
22:    then echo "Task [$TASK] aborted on error ($RES)"
23:    exit $RES
24: fi
25:
26: #Check CNS error
27: grep -E "^ ABORT " ${TASK}.log > /dev/null
28: if *4
29: then
30:     echo "Task [$TASK] stopped on CNS error"
31:    exit 2
32: fi

使いかた  

% runcns refine

refineの部分はタスク名で、インプットファイルの.inpを除いた部分が入ります。つまりgenerate.inpならgenerateです。

スクリプト解説  

(15-24行目)CNSではCtrl-Cにより停止したときに終了ステータス130を返すようなので、その場合は、ユーザーにより停止された、とメッセージを出力して停止します。その他のエラーの場合は終了ステータスを表示して停止します。
(26-32行目)インプットファイルのエラーで停止した場合でもCNSは正常終了ステータス(0)を返すため、ログファイル中にABORTから始まる行が出力されていないかを確認します。その行があれば、インプットファイルに不備があるのでその旨を出力し、終了ステータスとして2を返すようにしています。これにより、CNSに引き続いて処理を行う際にエラーによる停止を行うことができます。

インプットファイルの作成  

CNSで新しくタスクを実行するときに案外面倒なのがインプットファイルです。例えば、minimize.inpを使っていてその値を新たにbindividual.inpで使いたいような時に通常ならbindividual.inpをコピーしてその中の格子定数を書き換えて・・・という作業が必要になりますが、このスクリプトでは基となるインプットファイルから空間群、格子定数を取得し、新しいインプットファイルに埋め込みます。
今回はPerlを使って作ってみたalpha版です。まだあまり使い込んでないのでバグがあるかもしれません。後はCVファイルとかそのあたりのパラメータもコピーしてもいいかなと思ってますがとりあえず。

使い方  

% createinp minimize.inp bindividual

この場合、minimize.inpから空間群、格子定数を取得して$CNS_SOLVE/inputs以下からbindividual.inpを検索し、値を埋め込んで現在のディレクトリにbindividual.inpを作成します。

添付ファイル: filecreateinp 3358件 [詳細] fileruncns 3352件 [詳細]
*1  $# < 1 
*2  $RES == 130 
*3  $RES != 0 
*4  $? == 0