TEventlistでGateをかけてDumpしたtreeをその場で作る
treeには様々なBranchを詰めると思いますが、「この条件がかかったデータだけ解析してほしいなぁ」ということが多々あります。
例えば、(TTree*)treeには(x,y,a)のBranchがあって、「aが50未満のときのx,yの相関を見たい」というシチュエーションがあります。 もちろん
root [] tree->Draw("y:x","a < 50");
などその都度"a < 50"の条件をかけて描画してもよいのですが、これだとROOTちゃんはいちいち
「このEntryはa < 50を満たしているのかな?ふむふむ……あぁ、これは条件満たしていないねぇ、つぎつぎっと」
などと1Event毎にチェックしにいくのでデータ量(Entry数)や条件が多くなれば処理が遅くなります*1>。同じ条件で色々な絵を見たいのに一々待たされていてはたまったもんではありません。
*1: 基本、コンピュータはプログラムの命令をパイプラインで処理していますが、このような分岐により折角途中まで処理されたものがFALSE返されて棄却されるとそれまでの処理を捨てることになります。これをパイプラインハザードというらしい。
それを劇的に改善してくれる方法があるんです。TEventListというものを使います。
実装
まず、EventListをこのように作ります。
root [] tree->Draw(">>good","a < 50");
これで(TEventList*)goodが作られます。Objectの確認は
root [] .ls
...
OBJ: TTree tree tree : 0 at: 0x295b440
OBJ: TEventList good a < 50 : 0 at: 0x2967870
のようにして出来ます。 これのObjectを取得してtreeに適用します。
root [] TEventList* goodList = gDirectory->Get("good");
root [] tree->SetEventList(goodList);
試しにaのヒストグラムをDrawしてみるとたしかにa < 50の領域にしかプロットされないはずです。一応、
root [] goodList
(class TEventList*)0x2967870
root [] tree->GetEventList()
(const class TEventList*)0x2967870
と、gDirectoryにあるObject,Getしたポインタ,適用したtreeのTTree::GetEventList()で返ってくるアドレスが全て一致しているかでも確認は出来ます。
EventListはこの条件に合ったEntryの番号(tree->Scan()したときに一番左側に出てくるやつ)を記録し、そのEntry番号しかtreeに存在しないかのように振る舞うので、条件の検査の過程をすっ飛ばしてくれます。つまり、treeをDumpしてくれているということになります。
これを外すには
root [] tree->SetEventList(NULL);
とすればOKです。
さて、EventListのおかげでこれを書いているうちに解析が回り終わったのでこのへんで。