Dear ROOTers,
I'm wondering why CopyTree(Cuts) is affected by SetBranchAddress(...). Consider a fragment like
T b_val;
TBranch *b_ref;
tree->SetBranchAddress(bname, &b_val);
//Here is a code, that doesn't reset the branch address...
int main()
{
TFile inp_file("inpfile.root", "READ"); TTree *tree = (TTree*)inp_file.Get("tree");
func(tree, "branchname", ...);
TFile out_file("outfile.root", "RECREATE"); TString Cuts = "..."; //some cuts, maybe "", then all tree should be copied
TTree *newtree = tree->CopyTree(Cuts);
newtree->SetName("newtree");
newtree->Write();
One may discover the branch "branchname" in "newtree" will be filled with 0's. Is it a bug or a feature?
More unexpected things appear if to try a similar program structure (SetBranchAddress to a local variable in a function) with TChain. In that case even ResetBranchAddresses() doesn't help. Please consider the sample program (test_CopyTree.cxx) attached. It is expected to do the following:
What I observed in reality (test_out.txt) is the following:
What is wrong with the sample code? I used ROOT 5.06 and gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-54), SLC3. The code was compiled with:
g++ -o test_CopyTree test_CopyTree.cxx `root-config --cflags --libs`
With the best regards,
Vassili.
#include <iostream> #include <vector> #include <algorithm> #include "TChain.h" #include "TFile.h"
using namespace std;
const char *fname = "testCopyTree"; const char *fbname = "fbranch"; const char *ibname = "ibranch";
void make_datafile(const char *f_name)
{
//Create a ROOT file with a tree "T" with 2 simple branches, one with //float's, another with int's. Integers incremented from 0 to 9999, floats //normally distributed around 10 with sigma=1.
Float_t fbranch;
Int_t ibranch;
TFile *f = new TFile(f_name,"recreate"); TTree *T = new TTree("T","test CopyTree"); T->Branch(fbname,&fbranch,"fbranch/F"); T->Branch(ibname,&ibranch,"ibranch/I");
TRandom r;
for (Int_t ii=0; ii<10000; ii++) {
fbranch = r.Gaus(10,1); ibranch = ii; T->Fill();
template <class T>
void FindInterval(TChain *tree, const char *b_name,
T& left, T& right, Float_t frac = 0.95)
//Scans a branch <b_name> of a tree <tree> that contain a simple //variable (no objects) and returns interval [left, right] that //contains required fraction <frac> of entries.
Int_t n_ent = tree->GetEntries();
std::vector<T> val;
val.reserve(n_ent);
T b_val;
TBranch *b_ref;
tree->SetBranchAddress(b_name, &b_val);
b_ref = tree->GetBranch(b_name);
for (int ii = 0; ii < n_ent; ii++) {
b_ref->GetEntry(ii); val.push_back(b_val);
sort(val.begin(), val.end());
frac = 1.0 - frac;
if (frac <= 0.0) {
left = val.front(); right = val.back(); return;
Int_t n_skip = (Int_t)(0.5 * frac * n_ent);
cout << "Skipping " << n_skip << " entries..." << endl; cout << "End index: " << n_ent - n_skip - 1 << endl;
left = val[n_skip];
right = val[n_ent - n_skip - 1];
cout << "\nArray \"head\" :" << endl;
for (int ii = 0; ii < 20; ii++) {
b_ref->GetEntry(ii);
cout << "val[" << ii << "] = " << val[ii] << " ; GetEntry(" << ii << ") = " << b_val << endl;
}
cout << "\nArray \"tail\" :" << endl;
int jj = n_ent - n_skip - 1;
for (int ii = 0; ii < 20; ii++) {
b_ref->GetEntry(jj);
cout << "val[" << jj << "] = " << val[jj] << " ; GetEntry(" << jj << ") = " << b_val << endl;
jj--;
}
tree->ResetBranchAddresses();
return;
}
int main()
{
Float_t fleft, fright;
Int_t ileft, iright;
TString fullfname;
for (Int_t ii = 0; ii < 2; ii++) {
fullfname = fname; fullfname += "_"; //"straight" fullfname = fname+"_"+ii+".root"; doesn't work fullfname += ii; fullfname += ".root"; cout << "...making datafile " << fullfname << endl; make_datafile(fullfname);
TChain *chain = new TChain("T");
chain->Add((fullfname = fname) + "*.root");
FindInterval(chain, fbname, fleft, fright); FindInterval(chain, ibname, ileft, iright);
cout << "\nThe interval for \"" << fbname << "\": [" << fleft << "," << fright << "]"
<< "\nThe interval for \"" << ibname << "\": [" << ileft << "," << iright << "]\n" << endl;
char sLeft[30];
char sRight[30];
sprintf(sLeft, "%g", fleft);
sprintf(sRight, "%g", fright);
TString Cuts;
Cuts = "(" + (TString)fbname + ">=" + sLeft + ")&&(" + (TString)fbname + "<=" + sRight + ")";
sprintf(sLeft, "%d", ileft);
sprintf(sRight, "%d", iright);
Cuts += "&&(" + (TString)ibname + ">=" + sLeft + ")&&(" + (TString)ibname + "<=" + sRight + ")";
cout << "Cuts string: " << Cuts.Data() << endl;
TFile out_file("test_out_file.root", "RECREATE");
cout << "New file recreated. Trying to CopyTree with cuts..."<< endl;
TTree *newtree = chain->CopyTree(Cuts);
newtree->SetName("NewTree_WingCuts");
cout << "Writing the new tree..." << endl;
newtree->Write();
out_file.Close();
}
[pcmspur5] ~/TreePlay > test_CopyTree
...making datafile testCopyTree_0.root
...making datafile testCopyTree_1.root
Skipping 500 entries...
End index: 19499
Array "head" :
val[0] = 6.56342 ; GetEntry(0) = 8.89772 val[1] = 6.60677 ; GetEntry(1) = 11.2028 val[2] = 6.73436 ; GetEntry(2) = 10.3929 val[3] = 6.74979 ; GetEntry(3) = 9.47582 val[4] = 6.80376 ; GetEntry(4) = 9.40583 val[5] = 6.81106 ; GetEntry(5) = 10.3499 val[6] = 6.82342 ; GetEntry(6) = 10.5525 val[7] = 6.83903 ; GetEntry(7) = 10.1094 val[8] = 6.85538 ; GetEntry(8) = 10.223 val[9] = 6.87955 ; GetEntry(9) = 10.2056 val[10] = 6.95277 ; GetEntry(10) = 9.66529 val[11] = 6.96276 ; GetEntry(11) = 9.64864 val[12] = 6.97322 ; GetEntry(12) = 9.72508 val[13] = 6.97927 ; GetEntry(13) = 10.9662 val[14] = 6.99377 ; GetEntry(14) = 8.93446 val[15] = 7.03579 ; GetEntry(15) = 9.54132 val[16] = 7.03654 ; GetEntry(16) = 8.49909 val[17] = 7.0802 ; GetEntry(17) = 8.79561 val[18] = 7.08616 ; GetEntry(18) = 9.28766 val[19] = 7.08897 ; GetEntry(19) = 10.2172
Array "tail" :
val[19499] = 11.5811 ; GetEntry(19499) = 10.2172 val[19498] = 11.5806 ; GetEntry(19498) = 10.2172 val[19497] = 11.5803 ; GetEntry(19497) = 10.2172 val[19496] = 11.5799 ; GetEntry(19496) = 10.2172 val[19495] = 11.5783 ; GetEntry(19495) = 10.2172 val[19494] = 11.578 ; GetEntry(19494) = 10.2172 val[19493] = 11.5778 ; GetEntry(19493) = 10.2172 val[19492] = 11.5755 ; GetEntry(19492) = 10.2172 val[19491] = 11.5747 ; GetEntry(19491) = 10.2172 val[19490] = 11.5735 ; GetEntry(19490) = 10.2172 val[19489] = 11.5733 ; GetEntry(19489) = 10.2172 val[19488] = 11.5731 ; GetEntry(19488) = 10.2172 val[19487] = 11.5724 ; GetEntry(19487) = 10.2172 val[19486] = 11.5721 ; GetEntry(19486) = 10.2172 val[19485] = 11.572 ; GetEntry(19485) = 10.2172 val[19484] = 11.5716 ; GetEntry(19484) = 10.2172 val[19483] = 11.5697 ; GetEntry(19483) = 10.2172 val[19482] = 11.5697 ; GetEntry(19482) = 10.2172 val[19481] = 11.5695 ; GetEntry(19481) = 10.2172 val[19480] = 11.5683 ; GetEntry(19480) = 10.2172Skipping 500 entries...
Array "head" :
val[0] = 0 ; GetEntry(0) = 0 val[1] = 1 ; GetEntry(1) = 1 val[2] = 2 ; GetEntry(2) = 2 val[3] = 3 ; GetEntry(3) = 3 val[4] = 4 ; GetEntry(4) = 4 val[5] = 5 ; GetEntry(5) = 5 val[6] = 6 ; GetEntry(6) = 6 val[7] = 7 ; GetEntry(7) = 7 val[8] = 8 ; GetEntry(8) = 8 val[9] = 9 ; GetEntry(9) = 9 val[10] = 10 ; GetEntry(10) = 10 val[11] = 11 ; GetEntry(11) = 11 val[12] = 12 ; GetEntry(12) = 12 val[13] = 13 ; GetEntry(13) = 13 val[14] = 14 ; GetEntry(14) = 14 val[15] = 15 ; GetEntry(15) = 15 val[16] = 16 ; GetEntry(16) = 16 val[17] = 17 ; GetEntry(17) = 17 val[18] = 18 ; GetEntry(18) = 18 val[19] = 19 ; GetEntry(19) = 19
Array "tail" :
val[19499] = 9999 ; GetEntry(19499) = 19 val[19498] = 9999 ; GetEntry(19498) = 19 val[19497] = 9999 ; GetEntry(19497) = 19 val[19496] = 9999 ; GetEntry(19496) = 19 val[19495] = 9999 ; GetEntry(19495) = 19 val[19494] = 9999 ; GetEntry(19494) = 19 val[19493] = 9999 ; GetEntry(19493) = 19 val[19492] = 9999 ; GetEntry(19492) = 19 val[19491] = 9999 ; GetEntry(19491) = 19 val[19490] = 9999 ; GetEntry(19490) = 19 val[19489] = 9999 ; GetEntry(19489) = 19 val[19488] = 9999 ; GetEntry(19488) = 19 val[19487] = 9999 ; GetEntry(19487) = 19 val[19486] = 9999 ; GetEntry(19486) = 19 val[19485] = 9999 ; GetEntry(19485) = 19 val[19484] = 9999 ; GetEntry(19484) = 19 val[19483] = 9999 ; GetEntry(19483) = 19 val[19482] = 9999 ; GetEntry(19482) = 19 val[19481] = 9999 ; GetEntry(19481) = 19 val[19480] = 9999 ; GetEntry(19480) = 19
The interval for "fbranch": [8.37443,11.5811] The interval for "ibranch": [500,9999]
Cuts string: (fbranch>=8.37443)&&(fbranch<=11.5811)&&(ibranch>=500)&&(ibranch<=9999) New file recreated. Trying to CopyTree with cuts...
This archive was generated by hypermail 2.2.0 : Mon Jan 01 2007 - 16:31:58 MET