Problems Cloning a Tree

Hi,

I try to clone a Tree[*] (with zero entries just to get the structure) and want to fill it with elements of the original (or a similar) tree based upon certain conditionals (e.g. calculated from values within an entry of the tree).

([*] OK, I use a Chain, but basically it’s the same, right?)

But if I check a certain element, e.g. a Branch, exactly this value will have a single value for every entry I filled into the cloned Tree, NOT the value in the source tree.

As example, take a clean/new installation of root_v5.24, for example located in /opt/root_v5.24 . To demonstrate my question, I simply chose one of the existing trees (residing in tutorials/quadp/stock.root, part “C”), taking a random branch (e.g. “fHigh”).

So try to run a macro like:

{
  TChain* tree = new TChain("C");
  tree->Add("/opt/root_v5.24/tutorials/quadp/stock.root");

  TFile *CloneFile = new TFile("outtest.root","recreate");

  TTree *CloneTree = tree->CloneTree(0);

  double foo;
  tree->SetBranchAddress("fHigh",&foo);

  long nentries = (long)tree->GetEntriesFast();

  for(long ee = 0; ee < nentries; ee++)
    {
      tree->GetEntry(ee);
      CloneTree->Fill();
    }
  
  CloneTree->Print();
  CloneFile->Write();

  delete CloneFile;
}

You will notice, that the cloned Tree is the same as the original Tree – but for the values of the Branch “fHigh”; it’s value is constant. I tried this with several versions of root and very different Trees, the outcome is the same.

I read about the issues of using SetBranchAddress(…), but I did not manage to solve the problem. Any ideas?
As a side note – reading out the values of the particular branch (in this case “fHigh” by the means of “foo”) inside the loop works, the right values are shown.

Cheers,
Christoph

Hi Christoph,

In this example fHigh is an int and not a double so the code should be: int foo; tree->SetBranchAddress("fHigh",&foo);. Also the TTree was filled using an object so in order to be able to read the information by the setting directly the address of one of the member of the object, you need to tell the TTree to ‘decompose’ the object by calling ‘tree->SetMakeClass(1);’ … However such a tree can not be cloned. So instead of setting the address you will need to retrieve it or retrieve the value using the TLeaf interface and/or the TTreeFormula interface.
The simpliest might actually be to leverage the TFile::MakeProject utility and use an object:[code]{
TFile f(“tutorials/quadp/stock.root”);
f.MakeProject(“stock”,"*",“RECREATE++”);

TChain* tree = new TChain(“C”);
tree->Add(“tutorials/quadp/stock.root”);

TFile *CloneFile = new TFile(“outtest.root”,“recreate”);

TTree *CloneTree = tree->CloneTree(0);

TStockDaily *obj = 0;
tree->SetBranchAddress(“daily”,&obj);

for(long ee = 0; ee < tree->GetEntriesFast(); ee++)
{
tree->GetEntry(ee);
CloneTree->Fill();
}

// CloneTree->Print();
CloneFile->Write();

delete CloneFile;
}[/code]

Cheers,
Philippe.