Page for understanding ANAROOT. Sorry for Japanese only.
はじめに
ここではANAROOTの初歩的な扱いに慣れた人がANAROOTの構造を理解するためのtutorial。 試験的に作成している段階なので変だと思う所は直接コメントを書いたりメールしてください。
演習1
ANAROOTは解析するためのライブラリ群で、これをコード上で呼ぶことで解析する。 ここではbookだとかstartだとかのANAROOTのコマンドは一切使わない。
step 1.0
まず少しだけ前準備をしておく。 ただし、理研や東工大の解析マシンで
anarootlogon
などのshell commandがある場合は特に準備する必要はないはず。
ディレクトリ構造
ここでは解析を行うベースディレクトリを"mayoi"としたとき、
mayoi mayoi/db mayoi/macros mayoi/matrix mayoi/ridf mayoi/rootlogon.C mayoi/src
というディレクトリ構造を想定する。 公式に配布されているANAROOTの書庫はmayoi/src以下に展開し、compileを通す。 ライブラリがmayoi/src/lib以下にinstallされたことを確かめる。 compile・install周りの詳しいことは公式サイトを見てください。
rootlogon.C
ANAROOTは単なるライブラリ群(libanaroot.so等)なので、 ROOTではこれを明示的に指定・呼び出ししてあげないと使いようがない。 そのために、例えばROOT起動時に実行される rootlogon.C にライブラリの場所の指定・呼び出しを書いといてあげる。
以下は愚直に書く場合の例。
void rootlogon() { gSystem->AddIncludePath("-Isrc/include"); gSystem->Load("libXMLParser.so"); gSystem->Load("src/lib/libanaroot.so"); }
これをmayoi/rootlogon.Cとして保存しておく。 場合によってはカレントディレクトリにあるrootlogon.Cを読むように指定してない場合もあり、 その場合は.rootrcを編集する必要があるかもしれません。
step 1.1
まずは最小のプログラムを理解しよう。 こちら(ArtAnalyzeDALI1.C)をダウンロードください。 このstep 1.1が本質で、あとは拡張するだけなので。
念のため実行方法を説明しておく。 cint上(rootを実行したときのコマンド入力画面)で実行する場合には以下の四つの方法がある。
// cint上でコンパイルしない方法 .x ArtAnalyzeDALI1.C // cint上でコンパイルする方法 .x ArtAnalyzeDALI1.C+ // ロードして実行 .L ArtAnalyzeDALI1.C ArtAnalyzeDALI1() // コンパイル&ロードして実行 .L ArtAnalyzeDALI1.C+ ArtAnalyzeDALI1()
cintは完全にcの文法を理解できる分けではない(関数ポインタ、演算子のオーバーロード、テンプレート引数にオブジェクト等)のと自分の書いたコードのDEBUGという観点からコンパイルして実行することを勧める。 つまり、.x ArtAnalyzeDALI1.C"+"と最後に+をつけて実行する方法が推奨される。
では、説明を加えると、
#ifndef __CINT__ ... #endif
これは.x ArtAnalyzeDALI1.Cで呼んだときと、.x ArtAnalyzeDALI1.C+で呼んだときで ヘッダーファイルの読み込みがされない/されるを切り替えるため。
"TArtHoge.hh"
TArtはANAROOT独自のオブジェクトということを表しており命名規則の一つ。 TArtHoge.hhにはTArtHogeクラスが定義されている (たまに継承したクラスも一緒にかかれていることがあるので注意)。
TArtEventStore.hh: ridfファイルを読み込んでデコードしてrawdata型に詰めてくれる一番偉い人 TArtDALIParameters.hh: DALIのparameterを読み込んでDALIのparameter型に詰め込む TArtCalibDALI.hh: DALIへの窓口&本体。DALIという検出器その物を表したクラスではないということに注意。 TArtDALINaI.hh: DALIの素要素であるNaI一つのデータ形式 TArtDALIPara.hh: DALIのNaI用のparameterのデータ形式
ここで人によっては、DALI全体を表すクラスが独立にないことを気持ち悪いと思うかもしれないが、 諸事情により、素要素を定義するクラスの集合(vector<TArtDALINaI>の様なイメージ)を一つの検出器として扱っている。 具体的にはTClonesArrayというROOT標準のクラスに詰め込んでいる。 また一方ではbeam lineのplasticをTClonesArrayにまとめて突っ込んでたりする。 おそらくこの時点では何を言っているかわからないと思うが、 とりあえず構造がオブジェクト指向のセオリーに完全には乗っていないことだけは覚えていてほしい。 あと、Calibなんたらとついているものはあくまで”窓口兼本体”であることをよく頭に入れておくこと。
注意点をいくつか述べておく。
EventStore周りは深追いしても何も良い事はないので関数の中身を見て雰囲気を理解するぐらいにしておくべき。逆に、TArtCalibDALIだとかDALINaIとかはその先のコードまで理解できていることが望ましい。
- クラスをまたがる多くの処理をコンストラクタや関数内部で勝手にやっているので、その辺はとりあえず慣れてください。例えばTArtCalibDALIより先にTArtDALIParametersをコンストラクトしなければならない(コンストラクトする順番に依存するクラスは設計としては良くないとか突っ込まない)とか。
step 1.2
step 1.1にhistogramの定義を追加する。 こちら(ArtAnalyzeDALI2.C)をダウンロードください。 多くのユーザーがちゃんとc++を勉強していない感があるので"new"についてだけ注釈をいれる。
普通に変数を宣言してオブジェクトを生成する場合はスコープを抜けるときに必ず そのオブジェクトは破棄される。 一方newでオブジェクトを生成した場合はスコープを抜けてもそのオブジェクトは破棄されずメモリ上に残る。 例えばヒストグラムはmacroで処理した後も参照したいのでメモリ上に残しておく必要がある。 このためあえてnewして且つあえてdeleteしていないのである。 これとは別にnewしてポインタで取り扱う方が汎用的で便利という目的もあるが、 明確に意味が違うので混同しないこと。 TArtAnalyzeDALI2でnewしたTH1DのオブジェクトをTH1という親の型のポインタで受けているのは両方の目的がある。
このマクロを回したら、.lsかls() すればhistogramが出来ているのが見えるはずである。 あとはhid->Draw()やhn()とすればちゃん表示されるはず。
step 1.3
...あとは何とかなるでしょう。また時間を見てCalibやTAlのいじり方とかを追加します。