具体的に〇〇をやりたいなと思った時にみるメモです. 本編に入らないトリック集です.
- 実行関連
- g++でコンパイル
- ACLiCでコンパイルして実行
- お絵描き
- RGBで色を指定したい
- 範囲を塗りつぶしたい
- ヒストグラム
- ピークサーチがしたい
- TTree
- 人からもらったTTreeをとりあえず見る
- TTreeを処理するマクロを自動生成する
- TTreeのブランチの設定を簡単にやる
- 要らないブランチを読み込まない
- Treeのブランチがstd::vectorの際に, std::vectorの関数を呼ぶ
- 同質のTTreeをまとめて解析する
- TGraph
- std::vectorで入っているデータをプロットしたい
実行関連
g++でコンパイル
ROOTをライブラリとして使って, g++でコンパイルしバイナリを作成する方法です.
root-config
というコマンドがよしなに必要なものを準備してくれます.
こういう code.cxx
があるとします.
// code.cxx
#include <iostream>
#include <TH1.h>
int main(int argc, char** argv){
auto hist = new TH1D("hist", "hist", 100, -5, 5);
hist->FillRandom("gaus");
std::cout << hist->GetEntries() << std::endl;
return 0;
}
この一行で行けます.
g++ code.cxx -o code `root-config --cflags --libs`
ACLiCでコンパイルして実行
いつものrootマクロを実行するノリでなんちゃってコンパイルをする方法です.
Shared libraryを作成します.
最後に +
をつけるだけです.
root macro.C+
この場合, 最初に呼ばれる関数はmain ではなくマクロ名と一致している必要があります. また, マクロとして実行しているときになぜか #include <iostream>
せずに呼べているものなどもきちんとincludeする必要があります.
参考
お絵描き
RGBで色を指定したい
ROOTのカラーを潰さずにやる方法です.
hist->SetLineColor((new TColor(4000, 0.5, 0.2, 0.3))->GetNumber());
// number R G B
ROOTは色を整数値に対して紐づけているので, ある整数値に色を定義して, その整数値を渡してやる必要があります. ちなみに kBlue
とかも整数値が定義された変数です.
1179までの色は定義ずみなため, 適当に大きくて重複しない値をnumberのところには入れる必要があります.
歴史を感じる実装ですね.
範囲を塗りつぶしたい
ヒストグラムをふたつ作って, 下側領域の塗りつぶしを白にして重ねます.
ヒストグラム
ピークサーチがしたい
TTree
人からもらったTTreeをとりあえず見る
root -l tree.root
でファイルを開き, .ls
コマンドで中身を見ます. TTreeの名前 (ここではtree) がわかったら
tree->Print() // 概要とブランチ確認
tree->Show(0) // 0番目のイベントの中身確認
tree->Scan() // 流してスキャン
このあたりを実行するところから始めます.
TTreeを処理するマクロを自動生成する
tree->MakeClass()
で, TTreeの名前を持ったヘッダーとソースが生成されます.
tree.C
, tree.h
が生成されますが, 特に tree.C
を編集する必要があります.
void tree::Loop()
関数の中で, ヒストグラムを作り, ループの中でFillして, 最後にヒストグラムをDrawするなりSaveするなりしてください. 実行の仕方は Loop()
関数の冒頭にコメントで記載されています.
TTreeのブランチの設定を簡単にやる
自動生成ではなく, 自分のマクロに人のtreeの読み込みを組み込みたいことがあります.
auto file = TFile::Open("somefile.root")
auto tree = dynamic_cast<TTree*>(file->Get("tree"))
などで読み込めますが, その後にやるブランチ設定が面倒です.
tree->MakeClass()
を使うと, tree.h
ができます. その中で, // Declaration of leaf types
のコメントから始まる変数の定義, // List of branches
で始まるbranchの定義, そして, void tree::Init
関数内にある fChain->SetBranchAddress()
を全てコピペしてくれば, ブランチ設定は完了です. ただし, fChain
の部分は tree
とかに変える必要があります. また, 変数の定義がポインタであるものには, コピペした後 =0
としてやらないとエラーが出ます.
要らないブランチを読み込まない
tree->GetEntry(0); // required before SetBranchStatus
tree->SetBranchStatus("*",0); // 全部無効
tree->SetBranchStatus("value1",1); // 必要なものだけ有効にする
Treeのブランチがstd::vectorの際に, std::vectorの関数を呼ぶ
tree->Draw("vector_value@.size()")
同質のTTreeをまとめて解析する
同じ構造のTTreeが別のファイルに入っている場合,
hadd
コマンドで合成したファイルを作成するか, TChain
を使います.
hadd combined_file.root fragment_*.root
TChainを使う場合は,
TChain *chain=new TChain("tree", "tree title");
chain->Add("fragment_1.root");
chain->Add("fragment_2.root");
で, chainを1つのtreeのように扱えます. また, chain->Add()
ではワイルドカードとして *
も使えます.
TGraph
std::vectorで入っているデータをプロットしたい
多少面倒ですが,
auto tg = new TGraph(x_vec.size(), x_vec.data(), y_vec.data())
で愚直に書きます.