クイックツアー
とりあえず使ってみる
ディレクトリ kinoko/local/samples に,いくつかのサンプルスクリプトがあります.まず,CAMAC の ADC をソフトウェアでシミュレートする例を使って,Kinoko を一通り使ってみます.
TinyKinoko (Graphical 版)
TinyKinoko は,シングルプロセスで動作する軽量のデータ収集プログラムです.
使い方
- ディレクトリ samples に移り,TinyKinoko を立ち上げてください.
% cd kinoko/local/samples
% tinykinoko-graphical
- 表示されたウィンドウの Configuration および Run Control セクションの各フィールドに,以下の値を設定してください.
- Run Control セクションの [Start Data Taking] ボタンをクリックしてください.データ収集を開始します.データ収集は,十数秒で終了します.
- Data Dump セクションの [Dump] ボタンをクリックすると,エディタを起動し,得られたデータを表示します.また,[Summary]ボタンにより,イベント数や平均などの統計情報を表示します.
- Plot セクションの Script File Name フィールドに test01.kvs と設定し,右下にある [Generate Script] ボタンを押してください.これにより描画スクリプトが自動生成されます.その後 [Draw] ボタンをクリックするとヒストグラムが描画されます.
SmallKinoko
SmallKinoko は,リアルタイムのデータ表示などができる,マルチプロセスのデータ収集システムです.ただし,単一の PC 上で動作し,ネットワーク上の分散並列処理などはできません.
使い方
- ディレクトリ samples に移り,SmallKinoko を立ち上げてください.
% cd kinoko/local/samples
% smallkinoko
- しばらくするといくつかのウィンドウが表示されます.この中の,タイトルバーにSmallKinoko Control Panel と表示されているウィンドウ(コントロールパネル)の入力フィールドに,以下の値を設定してください.
- 次に,コントロールパネル下部にある [Construct] ボタンをクリックしてください.
- タイトルバーにlogger と書かれたウィンドウ(ロガー)には,各コンポーネントからのログメッセージが表示されます.各ログメッセージの先頭に E (エラー) または P (パニック)が無いことを確認してください.ログメッセージの表示が止まって,E や P が無ければ,
コントロールパネルの [Start] ボタンをクリックしてください.データ収集を開始します.もし,E または P がある場合は,コントロールパネルの [Quit] ボタンをクリックして,すぐに終了してください.
- あきたら,コントロールパネルの [Stop] ボタンでデータ収集を終了し,[Quit] ボタンで終了してください.
準備
実際にデータを取り始める前に,作業ディレクトリを作成してください.どこでも良いのですが,kinoko ディレクトリの下に置きたいのならば,実験固有のファイルを置くための場所 kinoko/local があるので,ここを使ってください.この例では,このディレクトリの下に,trial01 というディレクトリを作成し,その下で作業することにします.
% cd kinoko/local
% mkdir trial01
% cd trial01
なお,クイックツアーで使用しているスクリプト類は全て kinoko/local/tutorials/QuickTour に置いてあるので,ここからコピーすることもできます.
TinyKinoko を使う
TinyKinoko は,シングルプロセスで動作するデータ収集プログラムです.リアルタイムのデータ表示などはできませんが,読み出しスクリプト(.ktsスクリプト)に基づくデータ読み出しなどはできます.この部分は他の kinoko と共通なので,特に初期の動作テスト等に役に立ちます.
ここでは,東陽テクニカの CAMAC コントローラ (CC/7x00) を使った CAMAC システムに,林栄精器の電荷積分型 ADC (RPC-022) を使い,チャンネル 0 からチャンネル 3 のデータを読み出してみます.なお,ADC はステーション 3 に入っており,ゲート入力後 LAM を発生するように設定されているとします.
以下のようなファイルを書き,Trial01.kts という名前で保存してください(行番号は後の説明のためのものです.これは入力しないでください).
1: /* Trial01.kts */
2:
3: datasource Trial01
4: {
5: int station_number = 3;
6: long readout_channels = #0..#3;
7:
8: CamacCrate crate;
9: CamacController controller("Toyo-CC7x00");
10: CamacModule adc("Rinei-RPC022");
11:
12: crate.installController(controller);
13: crate.installModule(adc, station_number);
14:
15: on trigger(adc) {
16: adc.read(readout_channels);
17: adc.clear();
18: }
19: }
若干の文法拡張がしてありますが,基本的な部分は C++ と同じなので,理解しやすいと思います.詳しくは,使用方法の章で説明します.
ユーティリティ ktscheck により,スクリプトの構文エラーをチェックできます.
% ktscheck Trial01.kts
UNIX の伝統に従い,エラーがない場合には何も出力されません.エラーがあれば,行番号とともにメッセージが表示されます(以下の例では,Rinei-RPC022 を Rinei-RPC002 としてしまっている).
% ktscheck Trial01.kts
script exception: line 10: unknown camac module: Rinei-RPC002
%
エラーがないことを確認したら,このスクリプトを指定して,TinyKinoko でデータを読み出してみます.
% tinykinoko Trial01.kts trial01.kdf 100
ここで,第2引数はデータファイル名,第3引数は読み出すイベント数です.イベント数を省略したら,Ctrl-cを押すまで実行を続けます.また,--time オプションにより,時間を指定して実行することもできます.プログラムを実行する前に,ADC のゲートにちゃんと信号が入るようにしておいてください(適当な信号源がない場合は,10〜100Hz 程度のクロックをゲートに入れるだけでも良いです).
もし,すでに同名のデータファイルが存在している場合,tinykinoko はエラーを出して停止します.その場合は古いデータファイルを削除するか,強制上書きオプション -f を指定してください.
うまく動作したでしょうか.ちゃんと終了すれば,trial01.kdf というファイルができているはずです.script exception というエラーが出た場合は,スクリプトの文法エラーです.上の例とよく見比べて,修正してください.メッセージが出ずに固まってしまった場合は,以下の点を確認してください.
- ゲートにちゃんと信号が来ているか.ゲート信号幅は適切か.
- ADC は LAM を出すように設定されているか(RPC-022 はジャンパ設定が必要です).
- CAMAC コントローラは LAM を受け取ったとき割り込みを発生させるようになっているか(CC/7000 ではジャンパ設定が必要です).
- デバイスドライバはちゃんと動作しているか(ドライバのテストプログラムで確認してください).
- モジュールが故障していないか(トラブルの原因の大半はこれです).
データファイルを読む
得られたデータ (trial01.kdf) は様々な情報を含んだバイナリファイルです.これをテキストに直す一番簡単な方法は,以下のように kdfdump ユーティリティを使うことです.
% kdfdump trial01.kdf -
これにより以下のような出力が得られるはずです.
# Creator: tinykinoko
# DateTime: 2008-05-28 13:18:54 JST
# UserName: sanshiro
# Host: kinoko.awa.tohoku.ac.jp
# Directory: /home/sanshiro/work/kinoko/local/trial01
# ScriptFile: Trial01.kts
# EventTime: 1211948334
# EventTime: 1211948334
adc 0 1970
adc 1 1043
adc 2 1505
adc 3 339
# EventTime: 1211948334
adc 0 1216
adc 1 1411
adc 2 972
adc 3 183
adc 0 1521
adc 1 1510
adc 2 885
adc 3 1369
# EventTime: 1211948335
adc 0 173
adc 1 2022
adc 2 1016
adc 3 704
(以下省略)
# から始まる行はコメントです.データは,左のカラムから,セクション名,アドレス,データです.この例の場合,セクション名はスクリプト中でモジュールにつけた名前(スクリプト10行目),アドレスはADCのチャンネルです.イベントの区切りに空行が挿入されています.また,# EventTime には,時刻情報が UNIX の time(2) 形式で1秒ごとに記録されています.
ユーティリティ kdftable を使うと,もう少し解析しやすい形に整形できます.
(ただし,kdftable で整形できるのは,各イベントのデータの構造が表形式で表現できる形で固定されている場合のみです.フラッシュADCやマルチヒットTDCなどのデータは,kdftableでは整形できません.)
% kdftable trial01.kdf -
# Creator: tinykinoko
# DateTime: 2008-05-28 13:18:54 JST
# UserName: sanshiro
# Host: kinoko.awa.tohoku.ac.jp
# Directory: /home/sanshiro/work/kinoko/local/trial01
# ScriptFile: Trial01.kts
# Fields: index time adc.0 adc.1 adc.2 adc.3
# StartTime: 1211948334
0 0 1970 1043 1505 339
1 0 1216 1411 972 183
2 1 1521 1510 885 1369
3 1 173 2022 1016 704
4 2 1632 1518 1075 1951
(以下省略)
ここで,最初のカラムはイベント番号,2番めは開始時刻からの経過秒数です.ヘッダの StartTime フィールドには開始時刻が UNIX の time(2) 形式で書かれています.
コメントや空行は解析プログラムの中で簡単に読み飛ばせると思いますが,もし邪魔なら,UNIX 標準のコマンド grep で取り除くことができます.
% kdftable trial01.kdf | grep "^[0-9]"
0 0 1970 1043 1505 339
1 0 1216 1411 972 183
2 1 1521 1510 885 1369
3 1 173 2022 1016 704
4 2 1632 1518 1075 1951
(以下省略)
プログラムの中から直接 KDF ファイルを読む方法については,使用方法の章で説明します.
TinyKinoko グラフィカルフロントエンド
TinyKinoko 用のグラフィカルフロントエンド tinykinoko-graphical を使うと,上記のデータ収集を GUI 上で行うことができます.さらに,tinykinoko-graphical は Kinoko の描画システムや GNUPLOT/ROOT と連動し,得られたデータのヒストグラムなどを表示することもできます.この際,これらの描画ツールでデータファイルを読み,解析するためのスクリプトを自動生成するので,これを雛型にして描画スクリプトや解析スクリプトを作成すると便利です(ハードコーディングが多いですが...).
データを収集するには,Configuration セクションのフィールドにファイル名などをセットし,Run Control セクションの [Start] ボタンを押してください.端末ウィンドウ(xterm など)が開き,その中で tinykinoko が実行されます.このウィンドウで Ctrl-c を押すことにより,データ収集を停止させることができます.
得られたデータは,Data Dump セクションの [Dump] ボタンで表示することができます.また,[Summary] ボタンで,チャンネルごとのイベント数や平均などの統計情報を表示できます.
Plot セクションのフィールドにパラメータを設定し,[Generate Script] ボタンを押すと,描画スクリプトを自動生成します.同じセクションの [Draw] ボタンにより,描画ツールを起動して,そのスクリプトを実行します.描画ツールの選択は,Plot セクションの Visualizer フィールドで指定します.
ROOT/GNUPLOT へのインターフェース部分には,内部で kdftable ユーティリティを使用しています.したがって,これらの機能が使えるのは,得られたデータが kdftable で扱える場合のみです.Kinoko の描画システムである KinokoViewer を選択した場合は,kdf ファイルが直接読み込まれるので,この制限はありません.
SmallKinoko を使う
SmallKinoko は,単一のPC上で動作する(ネットワーク機能を持たない)マルチプロセスのデータ収集システムです.データを読み出す Collector,共有メモリを管理する Buffer,リアルタイムにデータを表示する Viewer,データを記録する Recorder,ログを記録する Logger,およびユーザコントロールを伝達する Controller の各コンポーネントから構成されます.
このうち Controller,Logger,Viewer はユーザインターフェース(KinokoShell)との通信チャネルを持ち,それぞれ kinoko-control,kinoko-board,kinoko-canvas の各ウィンドウと接続されます.
使用する前に,Viewer コンポーネントが使用するスクリプト(ビュースクリプト)を作成します.
以下のようなファイルを書き,Trial01.kvs という名前で保存してください(拡張子は .kvs です..kts などと混乱しないように注意してください).また,Tinykinoko Graphical で KinokoViewer を指定して雛型を作成することもできます.
1: /* Trial01.kvs */
2:
3: display Trial01
4: {
5: Histogram histogram_adc_01("ADC ch 01", 128, 0, 4096);
6: Histogram histogram_adc_all("ADC all channels", 128, 0, 4096);
7: Tabular tabular_adc_all("ADC values");
8: Trend trend_event_rate("Event Rate", 0, 5000, 60);
9:
10: analysis {
11: DataElement adc_01("adc", 1);
12: DataElement adc_all("adc");
13:
14: histogram_adc_01.fill(adc_01);
15: histogram_adc_all.fillOne(adc_all);
16: tabular_adc_all.fillOne(adc_all);
17: trend_event_rate.fill(adc_01);
18: }
19:
20: on every (1sec) {
21: histogram_adc_01.draw();
22: histogram_adc_all.draw();
23: tabular_adc_all.draw();
24: trend_event_rate.drawCounts();
25: }
26: }
このスクリプトも,だいたい想像したとおりに動きます.詳細については,使用方法の章で説明します.
ビュースクリプトに対するスクリプトチェックのユーティリティは kvscheck です.ktscheck と同様に,エラーがなければ何も表示されません.
% kvscheck Trial01.kvs
すでに tinykinoko などで取ったデータがあるならば,kinoko-viewer ツールを使用して描画内容をチェックすることができます.
% kinoko-viewer trial01.kdf Trial01.kvs | kinoko-canvas
スクリプトの準備ができたら,smallkinoko を起動します.
% smallkinoko
しばらくすると,いくつかのウィンドウが表示されます.ウィンドウのタイトルバーには,それぞれ,[SmallKinoko Control Panel],[logger],[viewer] とかかれているはずです.これらが,それぞれ Controller,Logger,Viewer の各コンポーネントと接続された KinokoShell のウィンドウです.
コントロールパネルウィンドウの各フィールドに,以下の値を設定してください.
Readout Script (.kts): Trial01.kts
View Script (.kvs): Trial01.kvs
Data File (.kdf): trial01.kdf
できたら,コントロールパネルの [Construct] ボタンを押してください.各コンポーネントがスクリプトの解読をし,データストリームを構築していきます.コンポーネントが出すログメッセージは,ロガーウィンドウに表示されます.以下は,ロガーに表示されるメッセージの例です.
N 05 Mar 2001 06:35:13 JST, collector: change state: ComponentReady
N 05 Mar 2001 06:35:14 JST, recorder: change state: ComponentReady
N 05 Mar 2001 06:35:14 JST, viewer: change state: ComponentReady
N 05 Mar 2001 06:35:14 JST, buffer: change state: Constructing
N 05 Mar 2001 06:35:15 JST, buffer: change state: DataTaking
D 05 Mar 2001 06:39:16 JST, collector: setReadoutScript(): trial01.kts
D 05 Mar 2001 06:39:16 JST, viewer: setViewScript(): trial01.kvs
D 05 Mar 2001 06:39:16 JST, recorder: setDataFile(): smallkinoko.kdf
D 05 Mar 2001 06:39:17 JST, collector: setSink: buffer (buffer) @127.0.0.1, shm: 100, msg: 101
D 05 Mar 2001 06:39:18 JST, recorder: setSource(): buffer (buffer) @127.0.0.1, shm: 100, msg: 101
D 05 Mar 2001 06:39:19 JST, viewer: setSource(): buffer (buffer) @127.0.0.1, shm: 100, msg: 101
N 05 Mar 2001 06:39:19 JST, collector: change state: Connecting
D 05 Mar 2001 06:39:19 JST, collector: connecting sink...
D 05 Mar 2001 06:39:20 JST, collector: connected
(以下省略)
各ログメッセージの最初の文字がログレベルを表しています.ログレベルの意味は以下のとおりです.
もし,エラー (E または P) が表示された場合,[Quit] ボタンを押してシステムを終了させてください.ほとんどの場合,スクリプトのエラーが原因です.
ここまで正常に来たら,[start] ボタンを押してデータ収集開始です.一秒ごとにヒストグラムが更新され,伸びていくのが見られます.
あきたら,[Stop] ボタンを押して,次に [Quit] を押し,終了してください.終了処理のため,[Quit] を押してからターミナルにプロンプトが戻るまで若干時間がかかります(数秒程度).終了処理が完了する前に Ctrl-c などを押さないようにしてください(リソースが開放されない可能性があります).
SmallKinoko を活用する
SmallKinoko のコントロールパネルには,コメントを記入したりデータファイルに関するオプションを設定するなどの様々なフィールドがあります.
コントロールパネルに記述された RunName や Comment の内容は,[Construct] をした際に,そのままデータファイルのヘッダに記録されます.ヘッダの内容は,kdfdump などで表示させることができます.
[Auto-stop Conditions] にある #-of-events や time を設定すると,指定した数のイベントを処理した時や指定した時間が経過した時に自動でランを停止させることができます.この機能を使用しない場合は,これらのフィールドを空欄のままにしておいてください.
データファイルを指定するフィールドのとなりにある [substitute] ボタンを押すと,データファイル名に含まれる特殊文字を置換できます.何度もデータを取る場合,いちいちデータファイル名を変えなくて済むので便利です.
- "#数字" があると,数字の部分をインクリメントします.# だけで数字がなければ,# が #1 になります.
run-#.kdf --> run-#1.kdf
run-#0100.kdf --> run-#0101.kdf
- "$d数字" があると,数字を削除して,$d を $d日付 に置き換えます.
run-$d.kdf --> run-$d051207.kdf (2005年12月7日)
run-$d051206.kdf --> run-$d051207.kdf
- "$t数字" があると,数字を削除して,$t を $t時間 に置き換えます.
run-$t.kdf --> run-$t092311.kdf (9時23分11秒)
run-$t092311.kdf --> run-$t092543.kdf
なお,いろいろな条件で取った kdf ファイルがたくさんある場合は,kdflist コマンドでそれらを一覧できます.
% kdflist run-*.kdf
run-#1.kdf sanshiro 18528 2005-12-07 23:35:55 JST physics run #1
run-#2.kdf sanshiro 9788 2005-12-07 23:36:23 JST pedestal run #1
run-#3.kdf sanshiro 18712 2005-12-07 23:36:50 JST physics run #2
run-#4.kdf sanshiro 9880 2005-12-07 23:37:19 JST pedestal run #2
[Data File Settings] にある Enable File Name Auto-Substitution を選択すると,このファイル名前置換を [Construct] のときに自動で行うようになります.
Prohibit Datafile Overwriting は,データファイルの上書きを禁止するオプションです.通常,すでに存在するデータファイル名を指定すると,警告のポップアップがでますが,このオプションが設定されていると,ポップアップで上書きを選択しても,エラーになって上書きができないようになります.
Set Datafile Readonly を選択すると,取ったデータのデータファイルの属性を書き込み不可に設定します(444: -r--r--r-- にする).Kinoko はファイルの属性を一切変更しないので,ファイルはシステムレベルで保護されることになります.
Enable Data Compression を選択すると,zlib を用いたファイル圧縮が行なわれます.ファイルはかなり小さくなりますが,ファイルのランダムアクセスなどの一部の機能が使えなくなる場合があります.
Make Data Index を選択すると,インデクスファイルが別に生成され,これを用いたランダムアクセスができるようになります.ただ,通常は指定する必要はないと思います(インデクスは後から生成させることもできます).
これらのオプションは [Construct] ボタンをクリックする前に設定されている必要があります.
Web-KiNOKO を使う
Web-KiNOKO を使うと,実行中の Kinoko をウェブブラウザからコントロールしたり,ビューアの絵やロガーのメッセージをリアルタイムに確認したりできるようになります.また,生成されたウェブページを保存しておくことにより,ランサマリとして利用できます.
Web-KiNOKO は,比較的新しめの標準的なウェブブラウザで動作します.Firefox 1.5,Safari 3.0 および Opera 9.51 で動作確認を行いました.Internet Explorer では動作しません.また,ブラウザでは,JavaScript が利用可能に設定されている必要があります.
Web-KiNOKO では,それ自体としてはアクセス制限の機能を提供していません.必要に応じて,ウェブサーバの認証機能などを設定してください.
現時点では,Web-KiNOKO のセキュリティが十分でない可能性があります.ファイアーウォールの内側だけで使用するか,慎重なアクセス制限を設定した状態で使用してください.
Web-KiNOKO を使用するには,ウェブサーバ (apache など) を動作させて,そこから参照できるディレクトリを用意する必要があります.このディレクトリでは CGI が実行できるようにしておいてください.kinoko/scripts に dump-http-request.cgi というサンプルCGIがあるので,これをそのディレクトリに置くことにより,CGIが実行できるようになっているか確認できます.ここでは,/home/kinoko/public_html/webkinoko が Web-KiNOKO 用に設定されているディレクトリだとします.
上記の設定がされていれば,SmallKinoko のスタート時に --web-dir または --web-root オプションで Web-KiNOKO 用のディレクトリを指定するだけで Web-KiNOKO を使用できるようになります.SmallKinoko は --web-dir で指定されたディレクトリに必要なファイル類をコピーし,ウェブサーバ経由で参照できるようにします.--web-dir ではなく,--web-root でディレクトリを指定すると,SmallKinoko はそのディレクトリの下に run-日付 という名前のディレクトリを新規に作成し,そこを使用します.--web-root のほうが毎回違うディレクトリを指定する煩わしさがなく,また,過去のランの履歴を保存し一覧できるようになるので便利です.
% smallkinoko --web-root=/home/kinoko/public_html/webkinoko
環境変数 KINOKO_WEB_ROOT を指定しておくと,毎回 --web-root を指定しなくても Web-KiNOKO の設定が自動で行われます.ただし,この場合は SmallKinoko を実行するたびに全てのファイルが保存され続けてしまうので,ファイルの管理に注意が必要です.
--web-dir または --web-root を設定して SmallKinoko を立ち上げたら,そのディレクトリをウェブブラウザでアクセスしてみてください.--web-root で指定した場合は run-日付-時間 というディレクトリができているので,そこをクリックします.Web-KiNOKO のページの上部には,以下のようなメニューがあります.
一番左側のプルダウンメニューでは,動作モードを設定します.static モードでは,ページのロード時にのみ更新を行い,その後の自動更新は行いません.逆に live モードでは,コントロールパネルの値,ビューアの絵,ロガーのメッセージ,モニタの数値などが適宜更新されていきます.実行中の Kinoko に対しては live モードが,過去のランに対しては static モードが適しています.実行中の場合でも,自動更新が邪魔な場合は static モードにすることにより更新を止めることができます.Safari 3.0 では,今のところロガーの自動更新が動作しないので,ロガーだけは static モードを使用してください.
モード選択の右側には,ページ選択メニューがあり,それぞれコントロールパネルやビューアなどを選べます.モードを変更した場合は,もう一度ページ選択ボタンでページを選択しなおし,モード変更を反映させてください.
ネットワークの状態によっては,コントロールパネルからの操作に時間がかかることがあります.このときボタンを複数回クリックするとエラーメッセージなどが出てうっとおしいことになるので,コントロールパネルのボタンを操作したら,次の更新が終わるまで(通常1秒程度)はボタンなどを操作しないようにしてください.また,SmallKinoko 本体がポップアップウィンドウを表示してユーザの操作待ちになった場合,Web-KiNOKO の操作もできなくなってしまうので注意してください(Web-KiNOKO ではポップアップは表示されません).
一番右側にある Run Summary は,ランの実行時間やコメント,使用したスクリプトなどをまとめて表示します.このページに関しては,実行中はあまり意味をもちません.実行後に過去のランの条件を参照するのに便利です.
オートパイロットを使う
オートパイロットを使うと,コントロールパネルに対するマウスやキーボードの操作を自動化できます.これにより,一定時間ごとのランのスタート・ストップや,条件を変えながらのランのくり返しなどが自動で行えるようになります.
以下は,[START] ボタンと [STOP] ボタンを操作して,1 時間ごとに 10 分間のデータを取る動作を 10 回繰り返す例です.以下の内容のファイルを auto-startstop.kcms という名前で作成してください.
int run_count = 0;
on every (1 hour)
{
invoke start();
after (10 min) invoke stop();
}
on transition (from "stopping" to "system_ready")
{
run_count++;
if (run_count == 10) {
invoke quit();
}
}
SmallKinoko を起動し,スクリプトやデータファイル名前を指定して,[Construct] をしてください.次に,コントロールパネルのメニューバーの [Action]-[LoadScript] でファイル選択ダイアログを開いて,auto-startstop.kcms を選択してください.これにより,オートパイロットスクリプトがロードされ,実行されます.
この例で作成されるデータファイルには,10回分のランのデータが格納されます.これを分離するには,コマンド kdfseparate を使います.
% ls *.kdf
foo.kdf
% kdfseparate foo.kdf
making foo-1.kdf...
making foo-2.kdf...
(略)
making foo-10.kdf...
% ls *.kdf
foo.kdf foo-1.kdf foo-2.kdf foo-3.kdf foo-4.kdf
(略)
次はもう少し複雑な例です.ここでは,1時間ごとに10分間の通常ランと,その後1分間のペデスタルランを行います.通常ランとペデスタルランでは異なったスクリプトを使うことにし,データファイルも別々にします.
int run_count = 0;
bool is_physics_run;
on every (1 hour)
{
run_count++;
string data_file = "foo-physics-" + run_count + ".kdf";
system("rm -f " + data_file);
<readout_script>.setValue("SimCamacAdc.kts");
<view_script>.setValue("CamacAdc.kvs");
<data_file>.setValue(data_file);
<message>.setValue("AUTOPILOT: taking physics data...");
is_physics_run = 1;
invoke construct();
}
on transition (from "constructing" to "system_ready")
{
invoke start();
if (is_physics_run) {
after (10 min) invoke stop();
}
else {
after (1 min) invoke stop();
}
}
on transition (from "stopping" to "system_ready")
{
if (! is_physics_run) {
if (run_count == 10) {
invoke quit();
}
else {
<message>.setValue("AUTOPILOT: idling...");
}
return;
}
string data_file = "foo-pedestal-" + run_count + ".kdf";
system("rm -f " + data_file);
<readout_script>.setValue("SimCamacAdc.kts");
<view_script>.setValue("CamacAdc.kvs");
<data_file>.setValue(data_file);
<message>.setValue("AUTOPILOT: taking pedestal data...");
is_physics_run = 0;
invoke construct();
}
オートパイロット実行中にポップアップなどが出て実行が中断しないように注意してください.あまり安全ではありませんが,この例では,新しくファイルを作成する前に,同名のファイルを削除しています.
この例には,[Construct] ボタンの操作も含まれているので,オートパイロットスクリプトのロードは,[Construct] を行う前(すなわち SmallKinoko を立ち上げた直後)に行います.後は,オートパイロットがシステムの終了まで自動で行います.
この例のように,起動直後からロードできるスクリプトは,smallkinoko のコマンド引数で起動時に指定することもできます.
% smallkinoko --autopilot = auto-periodic.kcms
コントロールパネルをカスタマイズする
ここでは,コントロールパネルをカスタマイズして,ADC のステーション番号と読み出すチャンネルをコントロールパネルから指定できるようにしてみます.以下は,ここで作成するコントロールパネルの外観です.ステーション番号やチャンネルの入力フィールド追加されています.
コントロールパネルの構成は,コントロールパネルスクリプト (KCML スクリプト) により記述されています.これは,今までとは異なり,XML を用いたスクリプトになっています.ここでは,SMallKinoko で使っているコントロールパネルスクリプトをベースにして,それを改造することにします(ただし,通常の SmallKinoko のコントロールパネルは多機能で複雑すぎるので,ここでは最小機能を実装している SmallKinoko Lite を使います).SmallKinoko のスクリプト(とそこで使っている画像)を以下のように自分の作業ディレクトリにコピーしてください.
% cp $KINOKO_ROOT/scripts/SmallKinoko-Lite.kcml ./Trial02.kcml
% cp $KINOKO_ROOT/scripts/SmallKinoko.xpm .
Trial02.kcml を,以下のように編集してください.太字の行が追加する部分です.
1: <?xml version="1.0"?>
2:
3: <KinokoControlPanel label="SmallKinoko Control Panel">
4: <HSpace/><Image file="SmallKinoko.xpm"/>
5: <VSpace/>
6:
7: <HSpace/><Label name="message" label="Welcome to the Kinoko World." font="times-italic" size="14"/><HSpace/>
8: <VSpace/>
9:
0: <EntryList>
11: <Entry name="readout_script" label="ReadoutScript (.kts)" option="file_select"/>
12: <Entry name="view_script" label="ViewScript (.kvs)" option="file_select"/>
13: <Entry name="data_file" label="DataFile (.kdf)" option="file_select"/>
14: </EntryList>
15: <VSpace/>
16:
17: <Frame label="ADC Configuration">
18: <Entry name="station" label="Station" width="50" selection="1 2 3 4"/>
19: <Label label="Ch: "/>
20: <RadioButton name="enable_ch0" label="0"/>
21: <RadioButton name="enable_ch1" label="1"/>
22: <RadioButton name="enable_ch2" label="2"/>
23: <RadioButton name="enable_ch3" label="3"/>
24: <RadioButton name="enable_ch4" label="4"/>
25: <RadioButton name="enable_ch5" label="5"/>
26: <RadioButton name="enable_ch6" label="6"/>
27: <RadioButton name="enable_ch7" label="7"/>
28: </Frame>
29: <NewLine/>
30:
31: <Frame name="run_control" label="Run Control">
32: <ButtonList>
33: <Button name="construct" label="Construct" enabled_on="stream_ready system_ready"/>
34: <Button name="start" label="Start" enabled_on="system_ready"/>
35: <Button name="stop" label="Stop" enabled_on="data_taking"/>
36: <Button name="clear" label="Clear" enabled_on="system_ready data_taking"/>
37: <Button name="quit" label="Quit" enabled_on="stream_ready system_ready error"/>
38: </ButtonList>
39: </Frame>
40: </KinokoControlPanel>
このスクリプトが生成するコントロールパネルの外観は,コマンド kcmlcheck により確認することができます.
% kcmlcheck Trial02.kcml
次に,読み出しスクリプトの側を,コントロールパネルに設定された値を取得し,それを使うように変更します.Trial01.kts で,ステーション番号やチャンネルをハードコーディングしている部分(5行目 と 6行目)を削除し,以下の太字の部分を追加してください.ここで,getRegistry() が,コントロールパネルが設定したパラメータを取得する関数です.
1: /* Trial02.kts */
2:
3: datasource Trial02
4: {
5: int station = getRegistry("control/station");
6: int readout_channels;
7: for (int ch = 0; ch < 16; ch++) {
8: if (getRegistry("control/enable_ch" + ch) == "1") {
9: readout_channels |= #ch;
10: }
11: }
12:
13: CamacCrate crate;
14: CamacController controller("Toyo-CC7x00");
15: CamacModule adc("Rinei-RPC022");
16:
17: crate.installController(controller);
18: crate.installModule(adc, station_number);
19:
20: on trigger(adc) {
21: adc.read(readout_channels);
22: adc.clear();
23: }
24: }
作成した KCML スクリプトを引数にして,SmallKinoko を立ち上げてください.作成したコントロールパネルを持ったシステムが起動するはずです.
% smallkinoko Trial02.kcml
[Construct] する前に,ReadoutScript を Trial02.kts に変更するのを忘れないように注意してください.
なお,この例のように,特定の読みだしスクリプトを使用することを想定する場合,KCML の <Constant>タグを使うことにより,KCML スクリプトの中にハードコーディングすることもできます.
10: <EntryList>
11: <Entry name="view_script" label="ViewScript (.kvs)" option="file_select"/>
12: <Entry name="data_file" label="DataFile (.kdf)" option="file_select"/>
13: </EntryList>
14: <Constant name="readout_script" value="Trial02.kts"/>
コントロールパネルで独立アプリケーションを作る
コントロールパネルを記述する KCML スクリプトの中で <Script> タグを使うことにより,オートパイロットで使用した KCMS スクリプトの内容を直接 KCML の中に書くことができます.KCML スクリプトは kcmlcheck ツールで独立に動作させることができるので,これを利用することにより,Kinoko システムとは独立に動作するスタンドアローンのグラフィカルアプリケーションを作成することができます.実際,tinykinoko-graphical はこの仕組みを使って実装されています.
以下は,kcmlcheck を使って作成した例です.入力フィールドの値を10進数または16進数に変換します.
このプログラムは,1つの入力フィールドと2つのボタン,および改行や空白などのレイアウトウィジェットから構成されています.ソースコードは以下のようになっています.ボタンウィジェットの on_click 属性でボタンがクリックされたときに呼び出される関数を指定し,<Script> の中でその関数を定義しています.
<?xml version="1.0"?>
<KinokoControlPanel label="Dec-Hex Converter">
<Entry name="value" label="Value" alignment="right"/>
<NewLine/>
<HSpace/>
<Button label="HEX" on_click="convertToHex"/>
<Button label="DEC" on_click="convertToDec"/>
<Script>
<!--
void convertToHex() {
int value;
try {
value = (int) eval(<value>.getValue());
<value>.setValue("0x" + hex(value));
}
catch {
openPopup("ERROR", "OK", "invalid dec value");
}
}
void convertToDec() {
int value;
try {
value = (int) eval(<value>.getValue());
<value>.setValue(value);
}
catch {
openPopup("ERROR", "OK", "invalid hex value");
}
}
-->
</Script>
</KinokoControlPanel>
入力フィールドの値を getValue() で取得した後に eval() していますが,これは入力が計算式のときにその処理を行うためです.これにより,例えば 2 * 0x100 のような入力を処理できるようになっており,簡易電卓としても使用できます(上記プログラム中の int へのキャストを float にすれば関数電卓になります).
このプログラムは kcmlcheck で実行できます.
% kcmlcheck DecHexConverter.kcml
次はもう少し複雑な例です.UNIXコマンドの uptime を呼び出してロードアベレージを取得し,Kinoko Version 2 より導入された VisualWidget と Viewlet を使ってロードアベレージの現在値と推移をグラフィカルに表示します.
ソースコードは以下のようになっています.uptime コマンドの出力形式によっては getLoadAverage() 関数の中身を修正する必要があるかもしれません.文法の詳細については使用方法の章で説明します.
<?xml version="1.0"?>
<KinokoControlPanel label="Load Average Monitor">
<Label label="Load Average Monitor" font="helvetica-bold" size="14"/><HSpace/>
<VSpace/>
<Box>
<HSpace/>
<VisualGuage name="guage" min="0" max="3" foreground="red" wideness="20"/>
<HSpace/>
<NewLine/>
<VisualDisplay name="display" height="40" width="80" fg="lightgreen" bg="black" align="center"/>
</Box>
<Plot name="plot" width="370" height="300" xmin="0" xmax="100" ymin="0" ymax="3"/>
<Script>
<![CDATA[
on startup() {
reset();
}
on every (1 sec) {
update();
}
int start_time;
list x, y;
void reset() {
start_time = time();
x = {}; y = {};
<plot>.setTimeTick(start_time, "%H:%M'%S", "sec", 30);
}
void update() {
int time = time();
double value = getLoadAverage();
if (time - start_time > 100) {
reset();
}
x <+>= time;
y <+>= value;
<guage>.setValue(value);
<display>.setValue(value);
<plot>.draw(x - start_time, y);
}
double getLoadAverage() {
string uptime = shell("uptime");
$match = (uptime =~ m/[Ll]oad [Aa]verage: ([0-9\.]+)/);
return $match[1];
}
]]>
</Script>
</KinokoControlPanel>
異常終了後のクリーンアップ
もし,Kinoko が異常終了して,その結果システムにゴミ(共有メモリなどのシステム資源や生き残りプロセス)が残り,次に起動しなくなった場合(通常,File already exists などのエラーメッセージが出ます),以下の手順によりクリーンアップをおこなってください.ただし,この手順は,オペレーティングシステムによって微妙に異なります.ここでは Linux 2.x での手順を示します.
メッセージキューの削除
SmallKinoko は,2つのメッセージキューを使用します.現在使用中のメッセージキューは,コマンド ipcs で確認できます.
% ipcs
(途中省略)
------ メッセージキュー --------
キー msqid 所有者 権限 使用バイト数メッセージ
0x01039817 0 sanshiro 600 0 0
0x6503802e 1 sanshiro 600 0 0
kinoko 以外がメッセージキューを使用していることはあまりないのですが,見分け方としては,所有者が自分で,パーミッションが 600 となっていることです.削除は,ipcrm コマンドに msqid を指定して行います.
% ipcrm msg 0
% ipcrm msg 1
この瞬間に,多くの Kinoko プロセスがエラーメッセージを出して異常終了するはずです.
共有メモリの削除
SmallKinoko は,1つの共有メモリを使用します.現在使用中の共有メモリは,コマンド ipcs で確認できます.
% ipcs
------ シェアードメモリセグメント --------
キー shmid 所有者 権限 バイト nattch 状態
0x5b037c7f 3 root 644 1048576 0 対象
0x00000000 260 root 644 98304 16 対象
0x00000000 1157 sanshiro 777 65536 2 対象
0x00000000 1158 sanshiro 777 65536 2 対象
0x00000000 1159 sanshiro 777 65536 2 対象
(途中省略)
0x00000000 71365 sanshiro 777 65536 2 対象
0x00000000 71366 sanshiro 777 65536 2 対象
0x6403802e 73159 sanshiro 600 33554432 4
(以下省略)
GNOME などのデスクトップ環境を使用していると,多くの共有メモリが使用されます.kinoko が使用している共有メモリの見分け方としては,所有者が自分で,パーミッションが 600 となっていて,サイズが 33554432 (または指定したサイズ)となっていることです.削除は,ipcrm コマンドに shmid を指定して行います.
% ipcrm shm 73159
生き残りプロセスの削除
まず,表示されている Kinoko 関係のウィンドウは全て閉じてください.つぎに,Kinoko 関連の生き残りプロセスを探します.
% ps -ef | grep inoko
sanshiro 1259 1 0 06:34 ttyp2 00:00:00 wish /home/sanshiro/work/kinoko/bin/kinoko-control-panel kinoko.awa.tohoku.ac.jp 10001
sanshiro 1273 1 0 06:34 ttyp2 00:00:00 KinokoController-kcom controller port: 10002
sanshiro 1277 1 0 06:35 ttyp2 00:00:00 KinokoCollector-kcom collector file: smallkinoko.log
sanshiro 1303 1285 0 07:23 ttyp5 00:00:00 grep inoko
ここで,grep をするときに inoko で探していることに注意してください.これは,kinoko の最初の K が大文字と小文字の両方があるためです.kill コマンドにより,これらを削除します.
% kill 1259
% kill 1273
% kill 1277
Kinoko のユーティリティに,grep による検索と kill を一度に行う簡単なスクリプト killoff があります.これを使うと,上記の処理は以下のように行うことができます.
% killoff inoko
sanshiro 1259 1 0 06:34 ttyp2 00:00:00 wish /home/sanshiro/work/kinoko/bin/kinoko-control-panel kinoko.awa.tohoku.ac.jp 10001
sanshiro 1273 1 0 06:34 ttyp2 00:00:00 KinokoController-kcom controller port: 10002
sanshiro 1277 1 0 06:35 ttyp2 00:00:00 KinokoCollector-kcom collector file: smallkinoko.log
commit? (y/n) > y
kill 1259
kill 1273
kill 1277
%
一応,キーワード kcom,korb でも grep してプロセスが生き残っていないか確かめてください.以下のプロセスが生き残っている可能性があります.
kcom-manager
kcom-registry-server
korb-broker
korb-nameserver
どうしてもうまくいかない場合
オペレーティングシステムを再起動してください.全てのゴミは自動で削除されます(再起動後,必要なドライバ類を組み込むのを忘れないように注意してください).
Edited by: Enomoto Sanshiro