Tree
- ROOT の TTree クラスの使い方をメモする。
TLeaf::GetMaximum()
Leaf の最大値を取得するとき、TLeaf::GetMaximum() が使える。ただし、値が設定されるのは、以下の narr のような配列の要素数を指定する Leaf の場合 (tree->GetBranch("narr")->GetLeaf("narr")->GetMaximum())。その他の場合は、tree->GetMaximum("narr") が使える。ただし、返し値は整数型ではなく浮動小数点型となるようだ?
****************************************************************************** *Br 0 :narr : narr/I * *Entries : 3353 : Total Size= 13959 bytes File Size = 1011 * *Baskets : 1 : Basket Size= 32000 bytes Compression= 13.34 * *............................................................................* *Br 1 :arr : arr[narr]/I * *Entries : 3353 : Total Size= 1115822 bytes File Size = 39386 * *Baskets : 36 : Basket Size= 32000 bytes Compression= 28.30 * *............................................................................*
二次元配列を Tree に詰める
二次元次元配列のブランチ参考: https://root.cern.ch/phpBB3/viewtopic.php?t=19463
一次元次元固定長配列のブランチ参考: $ROOTSYS/tutorials/tree/tree2.C
文字列の配列を Tree に詰める
char 型の配列(文字列)の一次元配列 (実際の宣言は二次元配列, 例えば char arr[10][100] (100字の文字列が10個)) を用意してもダメらしい? std::vector <std::string> などを使う。
Tree に 文字列を詰める
3種類の文字列 (std::string, TString, and char*) を tree に詰めることが出来るらしい (参考: Developments in ROOT I/O and trees)。さらに、文字列に対して TTree::Draw や TTree::Scan ができるらしい。
root[] tree->Scan("val:flag:flag:c:cstr", "", "col=::#x:c:"); ************************************************************************ * Row * val * flag * flag * c * cstr * ************************************************************************ * 0 * 0 * 1 * 0x1 * a * i00 * * 1 * 1.1 * 2 * 0x2 * b * i01 *
とりあえず、以下のマクロ (tree_str_test_1.C) を動かす。
#include <string> #include "TTree.h" void tree_str_test_1 () { TTree *t = new TTree("t","tree t"); char str_1[4], str_2[4]; t->Branch("str_1",str_1,"str_1/C"); t->Branch("str_2",str_2,"str_2/C"); strcpy (str_1,"aa1"); strcpy (str_2,"aa2"); t->Fill(); strcpy (str_1,"bb1"); strcpy (str_2,"bb2"); t->Fill(); strcpy (str_1,"aa1"); strcpy (str_2,"bb2"); t->Fill(); t->Scan(); t->Draw("str_1:str_2","","colz"); }
- 実行結果は以下の通り。
$ root tree_str_test_1.C+ ... some messages ... root [0] Processing tree_str_test_1.C+... ************************************ * Row * str_1 * str_2 * ************************************ * 0 * aa1 * aa2 * * 1 * bb1 * bb2 * * 2 * aa1 * bb2 * ************************************ root [1]
std::string を使ったバージョンは tree_str_test_2.C。ちなみに、このマクロの t->Draw("str_1:str_2","","colz"); をコメントアウトし、マクロ実行後に t->Scan() とすると、
$ root tree_str_test_2.C+ ... some messages ... root [1] t->Scan() ************************************ * Row * str_1 * str_2 * ************************************ terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
というようなメッセージが出る。str_1, str_2 はスコープを抜けて破棄されているので、エラーになるのかも?std::string を new して使えばマクロ終了後でも問題なくstd::string にアクセスできる。マクロ終了後に、マクロで扱ったインスタンスにアクセスしたい場合、全部 new しておけばよいのかも。ただし、delete をすれば、もちろん後からアクセスできなくなる。ROOT のマクロでは new して delete しないという使い方がありうるのかも?マクロ内で t->Draw("str_1:str_2","","colz"); と書いておくと、マクロ終了後でも t->Scan() が出来たが、ROOT 終了時に
root [1] t->Scan() ************************************ * Row * str_1 * str_2 * ************************************ * 0 * aa1 * aa2 * * 1 * bb1 * bb2 * * 2 * aa1 * bb2 * ************************************ (Long64_t)3 root [2] .q *** Break *** segmentation violation =========================================================== There was a crash. This is the entire stack trace of all threads: =========================================================== #0 0x00000033dbaac68e in waitpid () from /lib64/libc.so.6 #1 0x00000033dba3e609 in do_system () from /lib64/libc.so.6 ...
となる。さらにファイルに保存するバージョンは tree_str_test_3.C。実行方法、root ファイルの読み込み、Scan とヒストグラムの表示をするには、以下のようにする。
$ root tree_str_test_3.C+ ... some messages ... root [0] Processing tree_str_test_3.C+... Info in <TUnixSystem::ACLiC>: creating shared library /path/./tree_str_test_3_C.so root [1] .q $ $ root tree_str_test_3.root ... some messages ... root [0] Attaching file tree_str_test_3.root as _file0... root [1] .ls TFile** tree_str_test_3.root TFile* tree_str_test_3.root KEY: TTree t;1 tree t root [2] t->Scan() ************************************ * Row * str_1 * str_2 * ************************************ * 0 * aa1 * aa2 * * 1 * bb1 * bb2 * * 2 * aa1 * bb2 * ************************************ (Long64_t)3 root [3] t->Draw("str_1:str_2","","colz") Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1 (Long64_t)3 root [4] .q $
二次元配列同士の計算
TTree::Draw の Drawing expressions using arrays and array elements を参考に、2つの二次元配列 fMatrix[3][3] と fResults[5][2] の
- fMatrix[2][1]-fResults[4][1]
- fMatrix[2][]-fResults[4][1]
- fMatrix[2][]-fResults[4][]
- fMatrix[][2]-fResults[][1]
- fMatrix[][2]-fResults[][]
- fMatrix[][2]-fResults[3][]
- fMatrix[][]-fResults[][]
- fMatrix[2][]-fResults[][]
- fMatrix[1][]-fResults[][]
- fMatrix[][]-fResults[][1]
を計算する。最後の 3 つは CERN のページに載ってないもの。corr_2d.C で計算させると以下の様になる。fMatrix[2][]-fResults[][] というように 1 つの配列の第一引数 (?) を指定し、他の引数で何も指定しない場合、よくわからない結果となる。ROOT のバージョンは v5.32/04。
t->Scan("fMatrix[2][1]:fResults[4][1]:fMatrix[2][1]-fResults[4][1]","","colsize=28"); ********************************************************************************************************* * Row * fMatrix[2][1] * fResults[4][1] * fMatrix[2][1]-fResults[4][1] * ********************************************************************************************************* * 0 * 121 * 241 * -120 * ********************************************************************************************************* t->Draw("fMatrix[2][1]-fResults[4][1]"); t->Draw("fMatrix[2][1]:fResults[4][1]>>h0");
t->Scan("fMatrix[2][]:fResults[4][1]:fMatrix[2][]-fResults[4][1]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[2][] * fResults[4][1] * fMatrix[2][]-fResults[4][1] * ******************************************************************************************************************** * 0 * 0 * 120 * 241 * -121 * * 0 * 1 * 121 * 241 * -120 * * 0 * 2 * 122 * 241 * -119 * ******************************************************************************************************************** t->Draw("fMatrix[2][]-fResults[4][1]"); t->Draw("fMatrix[2][]:fResults[4][1]>>h1","","colz");
t->Scan("fMatrix[2][]:fResults[4][]:fMatrix[2][]-fResults[4][]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[2][] * fResults[4][] * fMatrix[2][]-fResults[4][] * ******************************************************************************************************************** * 0 * 0 * 120 * 240 * -120 * * 0 * 1 * 121 * 241 * -120 * * 0 * 2 * 122 * * 1642390519 * ******************************************************************************************************************** t->Draw("fMatrix[2][]-fResults[4][]"); t->Draw("fMatrix[2][]:fResults[4][]>>h2","","colz");
t->Scan() で fMatrix[2][]-fResults[4][] の 3 列目の要素がなぜ計算されているのかよくわからないが、 t->Draw("fMatrix[2][]-fResults[4][]"); とすれば 3 行目は無視される。
t->Scan("fMatrix[][2]:fResults[][1]:fMatrix[][2]-fResults[][1]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[][2] * fResults[][1] * fMatrix[][2]-fResults[][1] * ******************************************************************************************************************** * 0 * 0 * 102 * 201 * -99 * * 0 * 1 * 112 * 211 * -99 * * 0 * 2 * 122 * 221 * -99 * * 0 * 3 * * 231 * * * 0 * 4 * * 241 * * ******************************************************************************************************************** t->Draw("fMatrix[][2]-fResults[][1]"); t->Draw("fMatrix[][2]-fResults[][1]>>h3","","colz");
t->Scan("fMatrix[][2]:fResults[][]:fMatrix[][2]-fResults[][]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[][2] * fResults[][] * fMatrix[][2]-fResults[][] * ******************************************************************************************************************** * 0 * 0 * 102 * 200 * -98 * * 0 * 1 * 112 * 201 * -99 * * 0 * 2 * 122 * 210 * -98 * * 0 * 3 * * 211 * -99 * * 0 * 4 * * 220 * -98 * * 0 * 5 * * 221 * -99 * * 0 * 6 * * 230 * * * 0 * 7 * * 231 * * * 0 * 8 * * 240 * * * 0 * 9 * * 241 * * ******************************************************************************************************************** t->Draw("fMatrix[][2]-fResults[][]"); t->Draw("fMatrix[][2]:fResults[][]>>h4"),"","colz";
t->Scan("fMatrix[][2]:fResults[3][]:fMatrix[][2]-fResults[3][]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[][2] * fResults[3][] * fMatrix[][2]-fResults[3][] * ******************************************************************************************************************** * 0 * 0 * 102 * 230 * -128 * * 0 * 1 * 112 * 231 * -119 * * 0 * 2 * 122 * 240 * -118 * ******************************************************************************************************************** t->Draw("fMatrix[][2]-fResults[3][]"); t->Draw("fMatrix[][2]:fResults[3][]>>h5","","colz");
t->Scan() でなぜ fResults[4][0] の要素が表示されているのがよくわからないが、 t->Draw("fMatrix[][2]-fResults[3][]"); とすれば 3 行目は無視される。
t->Scan("fMatrix[][]:fResults[][]:fMatrix[][]-fResults[][]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[][] * fResults[][] * fMatrix[][]-fResults[][] * ******************************************************************************************************************** * 0 * 0 * 100 * 200 * -100 * * 0 * 1 * 101 * 201 * -100 * * 0 * 2 * 102 * 210 * -100 * * 0 * 3 * 110 * 211 * -100 * * 0 * 4 * 111 * 220 * -100 * * 0 * 5 * 112 * 221 * -100 * * 0 * 6 * 120 * 230 * * * 0 * 7 * 121 * 231 * * * 0 * 8 * 122 * 240 * * * 0 * 9 * * 241 * * ******************************************************************************************************************** t->Draw("fMatrix[][]-fResults[][]"); t->Draw("fMatrix[][]:fResults[][]>>h6","","colz");
- 3 行目に注目すると、fMatrix[][] の列は 102, fResults[][] の列は 210, fMatrix[][]-fResults[][] の列は -100 となっている。よって、行ごとに 102 - 210 と計算しているわけではないことが分かる。
t->Scan("fMatrix[2][]:fResults[][]:fMatrix[2][]-fResults[][]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[2][] * fResults[][] * fMatrix[2][]-fResults[][] * ******************************************************************************************************************** * 0 * 0 * 120 * 200 * -80 * * 0 * 1 * 121 * 201 * -80 * * 0 * 2 * 122 * 210 * -88 * * 0 * 3 * * 211 * * * 0 * 4 * * 220 * * * 0 * 5 * * 221 * * * 0 * 6 * * 230 * * * 0 * 7 * * 231 * * * 0 * 8 * * 240 * * * 0 * 9 * * 241 * * ******************************************************************************************************************** t->Draw("fMatrix[2][]-fResults[][]"); t->Draw("fMatrix[2][]:fResults[][]>>h7","","colz");
- よくわからない結果。CERN のウェブではこの場合の解説がない。定義されてないのかも?
t->Scan("fMatrix[1][]:fResults[][]:fMatrix[1][]-fResults[][]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[1][] * fResults[][] * fMatrix[1][]-fResults[][] * ******************************************************************************************************************** * 0 * 0 * 110 * 200 * -90 * * 0 * 1 * 111 * 201 * -90 * * 0 * 2 * 112 * 210 * -98 * * 0 * 3 * 120 * 211 * -91 * * 0 * 4 * 121 * 220 * -99 * * 0 * 5 * 122 * 221 * -99 * * 0 * 6 * * 230 * * * 0 * 7 * * 231 * * * 0 * 8 * * 240 * * * 0 * 9 * * 241 * * ******************************************************************************************************************** t->Draw("fMatrix[1][]-fResults[][]"); t->Draw("fMatrix[1][]:fResults[][]>>h8","","colz");
- よくわからない結果。CERN のウェブではこの場合の解説がない。定義されてないのかも?
t->Scan("fMatrix[][]:fResults[][1]:fMatrix[][]-fResults[][1]","","colsize=28"); ******************************************************************************************************************** * Row * Instance * fMatrix[][] * fResults[][1] * fMatrix[][]-fResults[][1] * ******************************************************************************************************************** * 0 * 0 * 100 * 201 * -101 * * 0 * 1 * 101 * 211 * -100 * * 0 * 2 * 102 * 221 * -99 * * 0 * 3 * 110 * 231 * -101 * * 0 * 4 * 111 * 241 * -100 * * 0 * 5 * 112 * * -99 * * 0 * 6 * 120 * * -101 * * 0 * 7 * 121 * * -100 * * 0 * 8 * 122 * * -99 * ******************************************************************************************************************** t->Draw("fMatrix[][]-fResults[][1]"); t->Draw("fMatrix[][]:fResults[][1]>>h9","","colz");
- 期待通りの結果な気がする。