忍者ブログ

火山系フリーターの落書き帳

火山学者が書かない秘密の話。

MELTS自動化の旅その2。xautomationを使ったコード実装例

1.はじめに

ubuntuにxautomationを導入した前回に引き続き、MELTSを自動で計算させるための話。

いろいろ紹介したい個所もありますが、今回も引き続きxautomationに絡む点を紹介します。

2.xautomationでMELTSを使う

今回、筆者はC言語でxautomationを利用しつつ、MELTSを自動で走らせています。 最初はシェルスクリプトでちまちまとxautomationのコードを書こうかと思いましたが、 シェルスクリプトは算術演算が苦手なので、いろいろ派生させようとしたときに不利だからです。

C言語でxautomationを呼び出すためには、system関数を利用します。 この関数の詳細は、Man page of SYSTEMを見てください。

例えば、以下のようなコードです。

system("xte 'key n'");

"xte 'key n'"部分がシェルです。 このコード例ではnキーを入力できます。

MELTSの基本的な入力と計算は、*.meltsファイル(実体はただのテキストファイル)と、GUIでのショートカットキーの操作だけで使えるようになっているため、 わざわざ座標を指定してクリックというコードは不要でした。

1.そもそもMELTSの使い方について

一般的な火山学研究者らがどんな使い方をしているかは知りませんが、 筆者はイニシャルの組成を入力後、温度・圧力条件を動かしたときに結晶化する鉱物や組成を見る、という使い方をしています。

すなわち、手順は

  1. *.meltsファイルの読み込み
  2. Compute Redox Stateによる鉄の2価・3価分配
  3. Normalize
  4. Find Liquidusでリキダス温度の検出
  5. Execute/Haltで実行

です。 これでmelts.outファイル及びxxx.tblファイルなど(これらも実体はただのテキストファイル)が出てきますので、それをチェックするのです。

2.上記操作をショートカットキーで操作するならば

これらの操作には、全てショートカットキーが割り振られています。

  1. Ctrl + O
  2. Ctrl + R
  3. Ctrl + N
  4. Ctrl + L
  5. Ctrl + E

温度を下げる割合や減圧のスピードを入力するIntensive Variablesにはショートカットキーが割り振られていません。 が、これらのパラメータは*.meltsファイルでも設定できるため、そちらのほうが処理が楽です。

3.C言語でのコード例

というわけで上記の操作を行うソースコード例が以下です。 エラーチェックはしていないため、ご了承ください。

  1. /* 起動待ち */
  2. usleep(sleeptime->wait);
  3. /* コマンドライン */
  4. system("xte 'key n'");
  5. system("xte 'key Return'");
  6. usleep(sleeptime->command);
  7. /* ファイルオープン */
  8. system("xte 'keydown Control_L'");
  9. usleep(sleeptime->keydown);
  10. system("xte 'key o'");
  11. usleep(sleeptime->keydown);
  12. system("xte 'keyup Control_L'");
  13. usleep(sleeptime->wait);
  14. /* ファイル名(tmp)入力 */
  15. system("xte 'key t'");
  16. usleep(sleeptime->keydown);
  17. system("xte 'key m'");
  18. usleep(sleeptime->keydown);
  19. system("xte 'key p'");
  20. usleep(sleeptime->keydown);
  21. system("xte 'key Return'");
  22. usleep(sleeptime->keydown);
  23. usleep(sleeptime->calc);
  24. /* Compute Redox */
  25. system("xte 'keydown Control_L'");
  26. system("xte 'key r'");
  27. usleep(sleeptime->calc);
  28. /* Normalize */
  29. system("xte 'key n'");
  30. usleep(sleeptime->calc);
  31. /* Find liquidas */
  32. system("xte 'key l'");
  33. usleep(sleeptime->calc);
  34. /* Execute */
  35. system("xte 'key e'");
  36. usleep(sleeptime->keydown);
  37. sleep(sleeptime->end);
  38. /* Exit */
  39. system("xte 'key c'");
  40. usleep(sleeptime->keydown);
  41. system("xte 'keyup Control_L'");
  42. usleep(sleeptime->keydown);
  43. system("xte 'key Up'");
  44. usleep(sleeptime->calc);
  45. system("xte 'key Return'");
  46. sleep(1);

このコードでは、端末からMELTSを立ち上げ、同一ディレクトリにあるtmpというファイルを読み込み、前述の計算操作を行い、MELTS終了までの面倒を見ています。 この部分を1つの関数にすることで、あとは計算したいファイル数に応じてこの処理を何度も呼び出すことができます。

ところどころusleepを挟んでいるのは、xautomationによる操作が早すぎてMELTSの動作が追いつかない場合もあるためです。 構造体にして他所から呼んでいるには、スリープ間隔をPC環境に合わせて自由に調整できるよう、外部ファイル化しているためです。

4.おしまい

今回は自動化部分に焦点を当てましたが、筆者環境ではCSVファイルから大量の*.meltsファイルを生成し、それに応じて自動で計算をまわす処理も実装しています。

今作ってるのは、出てきた結果を如何に簡単に解析できるようにできるか、という点。 数百個もファイル計算させても、見る方が追いつきません・・・って。

PR