この文書の現在のバージョンと選択したバージョンの差分を表示します。
| 両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
|
ja:root:ttree [2014/06/11 06:43] kota [読み込むBranchを限定する] |
ja:root:ttree [2017/08/19 09:27] (現在) kota [読み込むBranchを限定する] |
||
|---|---|---|---|
| ライン 1: | ライン 1: | ||
| - | ====== TTree を使う ====== | + | ====== TTree ====== |
| ライン 5: | ライン 5: | ||
| ==== 読み込むBranchを限定する ==== | ==== 読み込むBranchを限定する ==== | ||
| - | デフォルトではGetEntryすると、SetBranchAddressで指定されていないBranchまでも読みにいく(らしい)。 | + | === 方法1 --- SetBranchStatus === |
| - | treeに多数のBranchが入っていて、その一部だけを使う場合、これは非常に無駄になる。 | + | デフォルトではGetEntryすると、SetBranchAddressで指定されていないBranchまでも読みにいく。\\ |
| + | というかすべてのbranchのデータをメモリに乗せるが、SetBranchAddressすると | ||
| + | そのbranchに対応するメモリのポインタが指定した変数に割り当てられる。 | ||
| + | |||
| + | treeに多数のBranchが入っていて、その一部だけを使う場合、毎回全branchをメモリに乗せるのは無駄。 | ||
| Branchを読み込む・読み込まないを指定するメソッドが、SetBranchStatus である。 | Branchを読み込む・読み込まないを指定するメソッドが、SetBranchStatus である。 | ||
| ライン 15: | ライン 19: | ||
| </code> | </code> | ||
| - | このとき、先に0番目のEntryをGetEntryしてやらなければならないらしい。 | + | このとき、先にGetEntryを呼んでやらなくてはならないらしい。http://root.cern.ch/root/roottalk/roottalk03/4900.html |
| - | 理由は不明。 | + | (GetEntryの前にSetBranchAddressを呼んでやっておく必要があるっぽい) |
| - | 具体的には以下のように | + | |
| + | 理由はあまりよくわからない。 | ||
| + | 具体的には以下のようにする。 | ||
| <code c_mac> | <code c_mac> | ||
| tree->SetBranchAddress("hoge",&hoge); | tree->SetBranchAddress("hoge",&hoge); | ||
| ライン 25: | ライン 31: | ||
| ・ | ・ | ||
| tree->GetEntry(0); | tree->GetEntry(0); | ||
| - | + | tree->SetBranchStatus("*",0); | |
| - | tree->SetBranchStatus("*",0); //まず全体を読み込まない様に指定 | + | tree->SetBranchStatus("Detector.nHit",1); |
| - | tree->SetBranchStatus("Detector.nHit",1); //次いで、使用するものを順次読み込む設定に変えていく | + | tree->SetBranchStatus("Detector.hits.*",1); |
| - | tree->SetBranchStatus("Detector.hits.*",1);//クラス化されているものはワイルドカードで指定したりもできる | + | |
| ・ | ・ | ||
| ・ | ・ | ||
| ・ | ・ | ||
| 以下 event loop | 以下 event loop | ||
| + | </code> | ||
| + | |||
| + | |||
| + | === 方法2 --- TBranch::GetEntry=== | ||
| + | TBranch のGetEntryを用いることで、Branch毎に読み込むことができる。\\ | ||
| + | ただし、TChainを用いている時、気をつけなければならないことが1つ。\\ | ||
| + | TBranch::GetEntryは、引数として”当該イベントが含まれているTree内でのEntry Number”を取らなくてはならない。\\ | ||
| + | 具体的には次のようにする。 | ||
| + | <code c> | ||
| + | TChain *chain = ...; | ||
| + | Long64_t localEntry = chain->LoadTree(entry); | ||
| + | branch->GetEntry(localEntry); | ||
| + | </code> | ||
| + | |||
| + | Long64_t TChain::LoadTree(Long64_t entry)は | ||
| + | TChainで結びつけられたTreeの全エントリにつけられた通し番号(entry)を引数にとり、 | ||
| + | そのentryが含まれるTreeをCurrent Treeとし、 | ||
| + | Current Tree内でのEntry Numberを返り値とする関数。\\ | ||
| + | Errorがあると-1~-4の値を返すので、 if( localEntry < 0 ) でError判定ができる。 | ||
| + | |||
| + | ==== 元treeから条件を満たすイベントの、必要なbranchだけを抽出したtreeを作る ==== | ||
| + | |||
| + | |||
| + | TTree* TTree::CopyTree(const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0) | ||
| + | を用いる。 | ||
| + | さらに | ||
| + | void TTree::SetBranchStatus (const char *bname, Bool_t status=1, UInt_t *found=0) | ||
| + | を用いることで、必要なbranchだけを取り出してくることができる。 | ||
| + | |||
| + | こんな感じで使う: | ||
| + | <code c_mac> | ||
| + | TChain* chain = new TChain("T");//上の話はTChainでも同じ | ||
| + | chain->Add(....); | ||
| + | | ||
| + | std::string branchname[] = {"brA","br2","br3",...};//抜き出すbranchをリストアップ | ||
| + | const Int_t nBranch = sizeof(branchname)/sizeof(branchname[0]); | ||
| + | chain->SetBranchStatus("*",0);//一旦全てのbranchをdeactiveに | ||
| + | for(Int_t iBranch = 0 ; iBranch < nBranch ; ++iBranch) | ||
| + | chain->SetBranchStatus(branchname[iBranch].c_str(),1);//リストされたbranchだけをactiveにしていく | ||
| + | TFile* ofile = new TFile("file.root","RECREATE"); | ||
| + | TTree* newtree = chain->CopyTree("(SelectBit&0x4)>0");// とある変数"SelectBit"の0x4 Bitが立っていることを要求 | ||
| + | ofile->cd(); | ||
| + | newtree->Write(); | ||
| + | ofile->Close(); | ||
| </code> | </code> | ||