Keita Mizukoshi’s page
Keita Mizukoshi’s page

Tips

具体的に〇〇をやりたいなと思った時にみるメモです. 本編に入らないトリック集です.

  • 実行関連
  • 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する必要があります.

参考

ROOT で使われる色をプレゼンで見やすく変更しよう - 宇宙線実験の覚え書き

ROOT では色の種類を番号で表します。ROOT で default で用意されており、通常よく使われるものは、1:黒 (K)、2:赤 (R)、3:緑 (G)、4:青 (B)、5:黄色 (Y)、6:マゼンタ (M)、7:シアン (C) です。 しかしこれらの色のうち、プレゼン中で使うべきではない色に緑 (G) と黄色 (Y) とシアン (C) があります。背景色が白の場合、線の色が明るすぎて、会場の状況によっては聴衆から識別が困難なためです*1 。ということで、このうち 2 色を少し見やすく変えてやりましょう。それぞれ深緑とオレンジにしちゃいます。シアンは他の良い代替案が思いつかないので、もう 7 色目を使うのは諦めましょう。 例えば以下の ROOT script で、color() と color_mod() を実行します。 ▲ color() の出力結果 ▲ color_mod() の出力結果 この 2 行で、色番号 3 と 5 の TColor への pointer を取り出し、 RGB の割合を再設定してやっています。この 2 行を ~/.rootlogon.C に追記すれば、いつでもこの設定で使用できます。

oxon.hatenablog.com

ROOT で使われる色をプレゼンで見やすく変更しよう - 宇宙線実験の覚え書き

お絵描き

RGBで色を指定したい

ROOTのカラーを潰さずにやる方法です.

hist->SetLineColor((new TColor(4000, 0.5, 0.2, 0.3))->GetNumber());
														// number R    G    B

ROOTは色を整数値に対して紐づけているので, ある整数値に色を定義して, その整数値を渡してやる必要があります. ちなみに kBlue とかも整数値が定義された変数です.

1179までの色は定義ずみなため, 適当に大きくて重複しない値をnumberのところには入れる必要があります.

歴史を感じる実装ですね.

範囲を塗りつぶしたい

ヒストグラムをふたつ作って, 下側領域の塗りつぶしを白にして重ねます.

ヒストグラム

ピークサーチがしたい

ROOTのTSpectrumクラスを使ってpeak searchをする

TSpectrum を使うと簡単にpeak searchができた。 の中のサンプルプログラムを動かしたら大体分かる。 ピークの最大数を適当に決めてTSpecrumのインスタンスをつくる。 Int_t maxpeaks = 10; TSpectrum *s = new TSpectrum(maxpeaks); ちなみにこれだとresolutionは1になる。今はピークが探せさえすればいいので気にしない。あとから TSpectum::SetResolutionで変えれる。resolution=1はピーク間の距離は3 sigmaに対応するのだとか。詳しくは TSpectrum::SetResolution を参照。 TSpectrum::Searchを使う。 h1 というTH1Fオブジェクトがあったら、 をするだけでいい。めっちゃ簡単。2つ目の引数はsigma。詳しくはマニュアルって書いてあるのであとで読む。3つ目はオプション。4つ目は省略してるけどthresholdを設定する。ピークサーチが終わると fNPeaks, fPositionXなどの変数に情報が入ってるので、 TSpectrum::GetNPeaks, TSpectrum::GetPositionX とかで取ってくる。 Float_t *xpeaks = s->GetPositionX(); あとはresolutionやthresholdをいじってoptimizeしたり、それはピークじゃないってやつをfitできるかどうかで除けばよいのかな。あとsmoothingしたりも。 コンパイルするときのオプションに、-lSpectrum が必要。これは しても出てこないので自分で Makefile に書いておく必要がある(?)。 に書いてあったけどもっと分かりやすいところに書いて欲しい。

gist.github.com

ROOTのTSpectrumクラスを使ってpeak searchをする

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

で愚直に書きます.

Home

Keita Mizukoshi