Locked History Actions

Diff for "ANAROOT/Manual/analoop"

Differences between revisions 17 and 18
Deletions are marked like this. Additions are marked like this.
Line 12: Line 12:
TArtCalibNEBULAとかをnewする。
TH1とかのnewはConstruct()やコンストラクタではなく、
book関数をオーバーロードしてその中で行なってください。
具体的には、TArtAnaLoopUserクラスを作った場合なら、
{{{
void book(TArtAnaLoopUser* analoop)
}}}
という関数を作るということです。
具体例がmacros/analoop/TArtAnaLoopUser.Cにあるはずです。
newしたTH1のdeleteはデストラクタで。
This function is for construct like TArtCalibNEBULA, namely "new TArtCalibNEBULA".
Constructing like TH1 is better to do in global book function (override it),
but this is not essential and construct TH1 in Construct() is ok.
You can find example of this in TArtAnaLoopUser.C.
Line 24: Line 18:
毎loop呼ばれるので、oneloopの処理を書く。
手動でif文で条件別けして途中で抜けるのは構わない。
This function will be called every event loop, so write only one step.
Line 28: Line 21:
newしたTArtCalibNEBULAとかをdeleteする。 Just delete object which you create in Construct().
This part is important

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()

This function is for construct like TArtCalibNEBULA, namely "new TArtCalibNEBULA". Constructing like TH1 is better to do in global book function (override it), but this is not essential and construct TH1 in Construct() is ok. You can find example of this in TArtAnaLoopUser.C.

Calculate()

This function will be called every event loop, so write only one step.

Destruct()

Just delete object which you create in Construct(). This part is important

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の書き方は限られる。