last-modified: 2019-04-28 (日) 18:36:58 (1834d)[変更箇所]
→ aprootに改名・移動しました。 こちら。
以下は各部分についての記述。
rootを使い始めてみました。が、慣れていないせいもあって使いづらい。個人的にはPAW/ANAPAWの様な
command HID option
のような入力でカタカタ解析したい。IさんがANAROOTなるものを開発していますが、おそらく自分の希望している様にはなっていない。以下はANAROOTをまるでANAPAWを操作するようにするための道標。(志半ばにならないように頑張ります)
ルートのコマンドはいちいち()をつけたりとか、””をつけたりとかで、キーボード派な人には使いづらい感じがしてしまう。anapawのように使うならコマンドプロンプトを走らせてそこからマクロを走らせれ同じ様な使い勝手になる?
コマンドプロンプトは以下の様にするとできる。
#include <iostream> #include <readline/readline.h> #include <readline/history.h> using namespace std; int compro() { char *line; while(1){ line = readline( "ANA> "); if ( (string)line == "exit" ) break; // execute command cout << line << endl; free(line); } return 0; }
mallocでメモリ領域を確保しているので必ずfreeで解放する必要があるとのこと。freeしないとどれだけまずいのかはよくわかりませんがとりあえず。 こんなに簡単に作れるのですね。。。コンパイルするときには
g++ -o compro compro.cc -L/usr/include/readline -lreadline
と打って上げないといけない。ROOTでやるにはどうするの?
root [1] .L /usr/lib/libreadlibe.so root [2] .L test/compro.cc+ root [3] compro()
で行けました。まだ↑とか効いていない。history?
それぞれ良い点と悪い点があるかと思います。
(ANA)PAW | (ANA)ROOT |
コマンドは全部打たなくてもOK | コマンドは全部入力する必要あり。TABが効く |
aliasが使える | aliasない?()が必ずつく |
ヒストグラムのIDは番号。hn/hbは便利 | ヒストグラムは名前でID。わかりやすい? |
anaファイルは数字の羅列それだけではあっているかどうかは分かりづらい。ただしファイルのフォーマットはかなり整う。 | ヒストグラムの定義はどうするの? |
古い。いつまでつかえる? | 新しい |
rootファイルのTreeは単位が分からない?結局単位を示すヘッダのようなものがいるのか? |
以下でヒストリーが使用可能になりました。
#include <iostream> #include <readline/readline.h> #include <readline/history.h> #define MAX_HISTORY 3 using namespace std; int compro() { char *line; int history_no=0; HIST_ENTRY *history = NULL; while(1){ line = readline( "ANA> "); if ( (string)line == "exit" ) break; // execute command cout << line << endl; add_history(line); if (++history_no > MAX_HISTORY){ history = remove_history(0); free(history); } free(line); } return 0; }
MAX_HISTORYで履歴数を定義している。 これで使い勝手の良いコマンドプロンプトが作れますな!lineを解析して、たとえば
ht 101
とかだとプロットするマクロを走らせる。登録されていないコマンドの場合にはROOTのコマンドだと思って走らせる。これでANAPAW寄りなコマンドプロンプトができるはず。ただ、ROOTのコマンドを打つ時に便利なTABは使えなくなる。
anapawmode()と打つだけでコマンドプロンプトが切り替わってほしい。-->起動時にライブラリを読ませる?anapawmode.Cというマクロにべた書き?
コマンドラインの部分は以下のように分けるかな?
単純に作るとglobaになるが、クラスを作って後者はprivateでもよい。まあglobalでもよいけどC++っぽくするなら余計な関数を見えないようにするんかな。クラスを作ってコンパイルして、root
root [1] .L Anapawmode()
としてもAnapawmodeのメンバは見えない。 どうやらClassDef?、ClassImp?が必要らしい。 ここを参照。
以上のような感じでAnapawMode?クラスを作成した。readlineのインプットを解析した後に構文解析をし、以下のように実行することにしてみた。
gROOT->ProcessLine(commandline);
たとえばcommandlineには"histo->Draw()"のような文字列が入る。 でもだめ。AnapawMode?をexitで抜けた後にプロットされる。うーむ。。。
gROOT->ProcessLine?(commandline);
gSystem->ProcessEvents();
とするとプロットしてくれる!...んだけど2個目はプロットされずにexitで抜けた後にプロットされる。うーむ。。。
とりあえずは以下で解決できる。
gROOT->ProcessLine(commandline); gSystem->ProcessEvents(); gROOT->ProcessLine("c1->Update();");
Drawするとc1というCanvasが作られる。そいつをUpdateするととりあえず描画される。超付け焼刃... c1->でなくてgPad->のほうがまだましかな?でもCanvasをマウスでクリックしても変化ない。まだ何か足りていない...
上の問題は結局readlineで入力待ちしているとROOTのEventLoop?が回っていない?ためかと思われる。両方を両立するにはもっと根っこからいじる必要があるかも?
RintはROOTのInteractive Interface。この中でコマンドプロンプトとか書いてある。これを継承してちょっと付け足せば目的は達成できる?ただしおそらく
#include "TRint_Anapaw.h" int main(int argc, char **argv) { TRint_Anapaw *theApp = new TRint_Anapaw("ROOT (ANAPAW)", &argc, argv); // Init Intrinsics, build all windows, and enter event loop theApp->Run(); return(0); }
こんな感じで書いて別のプログラムを作成することになると思う。
以下はANAPAWで使っていたコマンドの一覧(すべてではないかも?)。こいつらをANAPAWMODEで使えるようにしたい!
コマンド名 | 備考 |
fetch FILE | 簡単にできる |
hstore FILE | ファイル名を指定してヒストグラム/Treeを保存する方法がわからない... |
hcut [HID HCUTNAME OPT] | treeだったらすぐにできる? |
cdraw | hcutとコンビで必須 |
cpro [HID OPT] | treeならすぐ。ヒストグラムからでもまあできる。pawのマクロはある。 |
clear [OPT] | どうするのかな? |
hnt,hbt [OPT] | |
blow [XMIN XMAX YMIN YMAX], xblow, xyblow | あんまり使っていなかった...、個人的にはpawのhi/pl HID(x1:x2)のようなほうが好き |
prx, pry | すぐできる |
bnx, bny | すぐできる |
slx, sly NSLI | すぐできる? |
mami [MIN] [MAX] | あまり使っていなかった。すぐできる? |
xstatus | |
hstatus | |
xfitg | xfitg [XMIN XMAX]とかでフィットの範囲をキーボード入力にも対応させたい |
figa | |
xval,xyval | T君が開発済み? |
avy [HID OPT] | すぐできる? |
chbin BF | どこかに転がっている |
status | 解析しているanaファイルやrawデータファイルを表示してくれる |
lnx,lgx,... | 必須 |
pson/psoff | |
listgate | ゲートに入った数を表示。あまり使っていなかった。 |
とりあえずこんなもん?結構ありますね。 以下はanapawにはないけど、自分でマクロとか書いていて便利だったもの。追加したいね。
コマンド名 | 備考 |
plots HID1 HID2 [OPT] | HID1-HID2をプロット。 |
datplot FILE OPT [HID] | テキストをプロットさせる。 |
td HID FILE OPT | ヒストグラムのcontentsをテキストファイルに書き込む。別に名前はtdでなくてよいけど。 |
TAB補完かPAWのような部分的なコマンド文字列入力か、2通りがあるかな?前者は入力時にTABキーを押すという手間が余計にかかる。なのでキーボード入力最速のためには後者のほうが良い。
以下のプログラムでは、部分的に文字列を入力するとあらかじめあるコマンドのリストから検索して補完することができる。
#include <iostream> #include <string> using namespace std; string Complement_Command(string line){ const int MAX_LIST=40; string list[MAX_LIST] = {"hnt","hbt","lnx","lgx","lny","lgy","lnz","lgz","cpro","hcut", "avy","cdraw","listgate","prx","pry","bnx","bny","slx","sly", "xstatus","hstatus","xfitg","figa","mami","blow","xblow","xyblow", "fetch","hstore","clear","xval","xyval","chbin","status","pson", "psoff"}; int i_matched[MAX_LIST]; string word; int n_matched=0; int i=0; while (i<MAX_LIST && !(list[i].empty()) ) { //search matched commands word = list[i].substr(0,line.size()); if ( word == line ){ i_matched[n_matched]=i; n_matched++; } i++; }// while if (n_matched<1){ cout<<"*** AnapawMode: No such a command"<<endl; return ""; }else if(n_matched==1){ return list[i_matched[0]]; }else { cout<<"*** AnapawMode: Ambigous command "<<line <<". Possible "<<n_matched<<" commands are:"<<endl; for (i=0;i<n_matched;i++){ cout<<list[i_matched[i]]<<endl; } return ""; }// if nmatched } int main(int argc,char* argv[]){ string str[100]; int i; for (i=0;i<argc;i++) str[i] = argv[i]; if (argc>1) str[1] = Complement_Command(str[1]); return 0; }