ブランチを作成したい(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::BranchTTreeにブランチを作成するメソッドです。 ブランチは変数を格納するための構造で、イベントごとに異なる値を保存できます。

第一引数(name)にはブランチの名前を指定します。 第二引数(address)には変数のアドレスを指定します。 配列を使う場合は先頭アドレスにします。

ヒント

変数が実体の場合は&変数名のように先頭に&をつけます。 配列の場合は、変数が先頭アドレスを指すため&は不要です。

第三引数(leaflist)は変数名とその型を指定する文字列で、変数/型の形式で記述します。 たとえば、int型の変数を保存する場合はIfloat型の場合はFdouble型の場合は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は不要です。

参考リンク