ブランチを作成したい(TTree::Branch)
1// Define branch variables
2int run{0}; // イベント番号
3double energy{0.0}; // エネルギー
4
5// Create branches and associate them with the variables
6TTree *tree = new TTree("events", "Event data");
7tree->Branch("run", &run, "run/I");
8tree->Branch("energy", &energy, "energy/D");
TTree::BranchはTTreeにブランチを作成するメソッドです。
ブランチは変数を格納するための構造で、イベントごとに異なる値を保存できます。
第一引数(name)にはブランチの名前を指定します。
第二引数(address)には変数のアドレスを指定します。
配列を使う場合は先頭アドレスにします。
ヒント
変数が実体の場合は&変数名のように先頭に&をつけます。
配列の場合は、変数が先頭アドレスを指すため&は不要です。
第三引数(leaflist)は変数名とその型を指定する文字列で、変数/型の形式で記述します。
たとえば、int型の変数を保存する場合はI、float型の場合はF、double型の場合はDを使用します。
固定長配列を使う場合は、leaflistに配列の長さを明示します。
ブランチを作成した後、変数に値を設定してFillメソッドを呼び出すことで、イベントデータを保存できます。
1import ROOT
2import numpy as np
3
4def macro():
5
6 with ROOT.TFile("output.root", "RECREATE") as f:
7 tree = ROOT.TTree("events", "Event data")
8
9 # ブランチ変数を定義する(arrayもしくはnumpy.array)
10 run = np.zeros(1, dtype=np.int32) # イベント番号
11 energy = np.zeros(1, dtype=np.float64) # エネルギー
12 n_hits = np.zeros(1, dtype=np.int32) # ヒット数
13 fadc = np.zeros(100, dtype=np.int32) # FADCの波形データ(最大100サンプル)
14
15 # ブランチを作成する
16 tree.Branch("run", run, "run/I")
17 tree.Branch("energy", energy, "energy/D")
18 tree.Branch("n_hits", n_hits, "n_hits/I")
19 tree.Branch("fadc", fadc, "fadc[100]/I")
20
21 # イベントループ
22 for i in range(1000):
23 run[0] = i
24 energy[0] = 1.0 + i * 0.01
25 n_hits[0] = i % 10
26 tree.Fill()
27 tree.Write()
可変長配列したい(TTree::Branch)
1TTree *tree = new TTree("events", "Event data");
2
3int n_hits{0};
4float hit_energy[100]{0}; // ヒットのエネルギー(最大100ヒット)
5
6tree->Branch("n_hits", &n_hits, "n_hits/I");
7tree->Branch("hit_energy", hit_energy, "hit_energy[n_hits]/F");
イベントごとに異なるサイズの配列を保存する場合、 可変長配列を使用します。 このとき、配列の長さの変数と配列の両方をブランチとして作成します。 配列を定義する際には、配列の最大サイズを指定する必要があります。
このサンプルでは
イベントごとの異なるヒットのエネルギーを記録するために、
イベントごとのヒット数(n_hits)と、
ヒットごとのエネルギー(hit_energy)のブランチを作成しています。
可変長配列したい(std::vector)
1void macro() {
2 TFile* file = TFile::Open("output_vector.root", "RECREATE");
3 TTree *tree = new TTree("events", "Event data");
4
5 std::vector<double> hit_energy;
6 tree->Branch("hit_energy", &hit_energy);
7
8 for (int event = 0; event < 1000; ++event) {
9 // イベントループの先頭でベクター配列をクリアする
10 hit_energy.clear();
11 for (int h = 0; h < event + 1; ++h) {
12 // ベクター配列にヒットのエネルギーを追加する
13 hit_energy.push_back(0.5 * (h + 1));
14 }
15 tree->Fill();
16 }
17 tree->Write();
18 file->Close();
19}
C++標準のstd::vectorを使用して可変長配列を保存できます。
この場合、配列の最大サイズの指定は不要です。
ROOTが自動的にサイズと型を判定してくれるためleaflistは不要です。