Locked History Actions

Diff for "ANAROOT/Manual/analoop"

Differences between revisions 16 and 17
Deletions are marked like this. Additions are marked like this.
Line 6: Line 6:
AnaLoop is
AnaLoopとは解析の流れ、およびコントロールをするインターフェースクラス。
TArtAnaLoopが正確な名前でこれを継承したクラスを作成し、解析内容を実装する。
子クラスではConstruct(), Calculate(), Destruct(), ClassName()の実装が
要求される。
以下に各関数の説明を書くが、macros/analoopにあるsampleやsourceを見るほうがわかりやすい気もする。
AnaLoop(Exact class name is TArtAnaLoop) is a abstract class to control flow of analysis.
Developer can make a class inherit TArtAnaLoop and required to implement 4 functions,
Construct(), Calculate(), Destruct(), and ClassName().
Maybe it's easier to understand to look source code like TAlDALIExample.cc and .hh.

Abstract of AnaLoop

AnaLoop(Exact class name is TArtAnaLoop) is a abstract class to control flow of analysis. Developer can make a class inherit TArtAnaLoop and required to implement 4 functions, Construct(), Calculate(), Destruct(), and ClassName(). Maybe it's easier to understand to look source code like TAlDALIExample.cc and .hh.

Construct()

TArtCalibNEBULAとかをnewする。 TH1とかのnewはConstruct()やコンストラクタではなく、 book関数をオーバーロードしてその中で行なってください。 具体的には、TArtAnaLoopUserクラスを作った場合なら、

void book(TArtAnaLoopUser* analoop)

という関数を作るということです。 具体例がmacros/analoop/TArtAnaLoopUser.Cにあるはずです。 newしたTH1のdeleteはデストラクタで。

Calculate()

毎loop呼ばれるので、oneloopの処理を書く。 手動でif文で条件別けして途中で抜けるのは構わない。

Destruct()

newしたTArtCalibNEBULAとかをdeleteする。

ClassName()

これは実は単にstatus()で表示するためだけに存在する。

AnaLoopの2つの使い方

libraryに組み込み

source/AnaLoop以下に正しく作れはroot上で見える。 標準的なものを作ってblack boxとしてユーザーに使わせるのに向いている。

手元にmacroとして置いておいて動的にload

libraryに組み込むのと同じソースをroot上で動的にloadすることもできる。

root[i] .L macros/TArtAnaLoopUser.C+

こう書くとコンパイルしてロードしてくれる(.xはコンパイルして実行なのでだめ)。 ちょくちょく書き換える場合やrootに慣れていて直接TH1とかをanaloopクラス内で constructする場合に向いている。

AnaLoopを継承した特殊なクラスTAlEncExample

TAlEncExampleではTAlEncSubを継承したクラスを登録して、それを登録した順に解析する特殊なAnaLoop手動で登録する場合は、

root[i] TAlEncExample* alencexample = new TAlEncExample;
root[i] alencexample->Register(new TAlEncSAMURAIExample);
root[i] alencexample->Register(new TAlEncDALIExample);
root[i] alencexample->Register(new TAlEncNEBULAExample);
root[i] book(alencexample);
root[i] push("ridf/sm_com/sdaq02/run0140.ridf");
root[i] start();

という感じで登録する。 anafileを使う場合はanafileで<analys>を使うことで自動的に登録作業が行われる。

# hoge.ana
<analys> 0,15,12,

あとは普通に、

root[i] book(new TAlEncExample, "hoge.ana");
root[i] push("ridf/sm_com/sdaq02/run0140.ridf");
root[i] start();

とすればよい。 TAlEncExampleを使う場合はstopとかも使える。

自前の計算ルーチンを組み込む

TAlEncSubを継承したクラスを自作してRegisterすればよい。 これの作り方はTAlEncUser.CTAlEncUser.hhを参考にしてください。 あとはこれをロードして、

root[i] .L macros/analoop/TAlEncUser.C+
root[i] book(new TAlEncExample, "ana/hoge.ana")
root[i] push("ridf/run0140.ridf")
root[i] start()

と普通に解析をはじめる。 自分で作ったTAlEncSubを継承したクラスをRegisterする過程は内部で(トリッキーに)実装しているので手動でやる必要はない。

anapaw: valに詰める -> anaroot: Add関数

valに詰める代わりにAdd関数を使う。 このときanapawではデータが無いときに非物理量(-1000等)を詰めていたが、 anarootではAddしなければhistogramにはfillされない。 でも、非物理量を意識する必要はやっぱりあり、今NaNを使う方針が進行している。 TDCのover flowとかを詰めたいのなら詰めて構わないがその分パフォーマンスは落ちる。

EAnalyser and EWNum

EAnalyserとEWNumはAnaFileでIDで物理量を指定するための列挙体。

src/source/AnaLoop/include/EAnalyser.hh
src/source/AnaLoop/include/EWNum.hh

に書く。 わかりやすいように定義の後ろに数字を書いているが、 現在はroot上で

root[i] lv();

と打てば見れるので書かなくてもいい。 ただし、C++の文法に完全に対応した処理をしているわけではないのである程度EAnalyser.hhとEWNum.hhの書き方は限られる。