Dear Rooters
In the attached macro "macroFriends.C" I want to copy selected
entries from a tree and its friends to a new file. For this
purpose I have written two functions:
- CopyTrees1() creates new trees which are stored in the new file.
- CopyTrees2() uses CloneTree() for this purpose.
While CopyTrees1() works fine, CopyTrees2() does not copy the
entries of the first tree but the entries of the last tree, as
seen in the following output:
root [0] .x macroFriends.C
------MyClass::MyClass------
------MyClass::CreateTrees------
------MyClass::CreateTrees------
------MyClass::AddTree------
------MyClass::AddTree------
------MyClass::AddTree------
------MyClass::AddTree------
------MyClass::AddTree------
------MyClass::AddTree------
------MyClass::AddTree------
------MyClass::AddTree------
------MyClass::CopyTrees1------
nfriends(treeX) = 7
file = TreeZ1.root
j= 0 x[0]= 0.107915 //<========correct!
j= 1 x[0]= 0.0206264
j= 2 x[0]= 0.142258
j= 3 x[0]= 0.0588223
j= 4 x[0]= 0.107915
j= 5 x[0]= 0.0206264
j= 6 x[0]= 0.142258
j= 7 x[0]= 0.0588223
------MyClass::GetTreeZ------
nentries(treeZ) = 50
nfriends(treeZ) = 7
------MyClass::CopyTrees2------
nfriends(treeX) = 7
file = TreeZ2.root
j= 0 x[0]= 0.0588223 //<========entry of j=7!
j= 1 x[0]= 0.0206264
j= 2 x[0]= 0.142258
j= 3 x[0]= 0.0588223
j= 4 x[0]= 0.107915
j= 5 x[0]= 0.0206264
j= 6 x[0]= 0.142258
j= 7 x[0]= 0.0588223
------MyClass::GetTreeZ------
nentries(treeZ) = 50
nfriends(treeZ) = 7
------MyClass::~MyClass------
root [1]
I have the following questions:
1, CopyTrees2: Do you know why the parent tree copies the wrong
entries to the cloned tree?
2, CopyTrees1: Why can I not use the following code in line 171:
fTreeZ->AddFriend(str.Data(), filename);
Thank you in advance for your help.
Best regards
Christian
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
C.h.r.i.s.t.i.a.n. .S.t.r.a.t.o.w.a
V.i.e.n.n.a. .A.u.s.t.r.i.a
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
///////////////////////////
//
// in new root session:
// > .x macroFriends.C
//
///////////////////////////
#include "TBranch.h"
#include "TFile.h"
#include "TFriendElement.h"
#include "TLeaf.h"
#include "TList.h"
#include "TRandom.h"
#include "TTree.h"
#include "TString.h"
#include <Riostream.h>
class MyClass: public TNamed {
protected:
TFile *fFile;
TTree *fTreeX;
TTree *fTreeY;
TTree *fTreeZ;
public:
MyClass() {}
MyClass(const char *name, const char *title = "test");
virtual ~MyClass();
void CreateTrees(const char *treename, const char *filename);
void AddTree(const char *treename, const char *filename);
void CopyTrees1(const char *treename, const char *filename);
void CopyTrees2(const char *treename, const char *filename);
void GetTreeZ();
#if !defined (__CINT__) || defined (__MAKECINT__)
ClassDef(MyClass,1) //MyClass
#endif
};
#if !defined (__CINT__) || defined (__MAKECINT__)
ClassImp(MyClass);
#endif
//______________________________________________________________________________
MyClass::MyClass(const char *name, const char *title)
:TNamed(name, title)
{
cout << "------MyClass::MyClass------" << endl;
fFile = 0;
fTreeX = 0;
fTreeY = 0;
fTreeZ = 0;
}//Constructor
//______________________________________________________________________________
MyClass::~MyClass()
{
cout << "------MyClass::~MyClass------" << endl;
SafeDelete(fTreeZ);
SafeDelete(fTreeY);
SafeDelete(fTreeX);
SafeDelete(fFile);
}//Destructor
//______________________________________________________________________________
void MyClass::CreateTrees(const char *treename, const char *filename)
{
cout << "------MyClass::CreateTrees------" << endl;
TFile *file = new TFile(filename,"RECREATE");
// Number of tree entries
Int_t nentries = 100;
Double_t x;
TTree *tree = 0;
TString str = "";
gRandom->SetSeed();
for (Int_t i=0; i<4; i++) {
str = treename; str += i;
tree = new TTree(str, "trees");
tree->Branch("BrX", &x, "x/D");
for (Int_t j=0; j<nentries; j++) {
x = gRandom->Rndm(1);
tree->Fill();
}//for_j
tree->Write();
}//for_i
delete file;
}//CreateTrees
//______________________________________________________________________________
void MyClass::AddTree(const char *treename, const char *filename)
{
cout << "------MyClass::AddTree------" << endl;
if (!fFile) fFile = new TFile(filename,"READ");
if (!fTreeX) fTreeX = (TTree*)fFile->Get(treename);
else fTreeX->AddFriend(treename, filename);
}//AddTree
//______________________________________________________________________________
void MyClass::CopyTrees1(const char *treename, const char *filename)
{
// creates new trees and copies selected entries
cout << "------MyClass::CopyTrees1------" << endl;
TList *friends = fTreeX->GetListOfFriends();
Int_t nentries = (Int_t)(fTreeX->GetEntries());
Int_t nfriends = friends->GetSize();
Int_t ntrees = nfriends + 1;
cout << "nfriends(treeX) = " << nfriends << endl;
TFriendElement *fe = 0;
TTree *treej[20];
TBranch *brchj[20];
TLeaf *leafj[20];
// Create tree/branch/leaf arrays
fe = (TFriendElement*)friends->At(0);
treej[0] = fe->GetParentTree();
brchj[0] = treej[0]->GetBranch("BrX");
leafj[0] = brchj[0]->GetLeaf("x");
for (Int_t j=0; j<nfriends; j++) {
fe = (TFriendElement*)friends->At(j);
treej[j+1] = fe->GetTree();
brchj[j+1] = treej[j+1]->GetBranch("BrX");
leafj[j+1] = brchj[j+1]->GetLeaf("x");
}//for_j
TFile *file = new TFile(filename,"RECREATE");
cout << "file = " << file->GetName() << endl;
Double_t x;
TTree *tree = 0;
TString str = "";
for (Int_t j=0; j<ntrees; j++) {
str = treename; str += j;
tree = new TTree(str, "trees");
tree->Branch("BrX", &x, "x/D");
for (Int_t i=0; i<nentries; i++) {
// Test: select every second entry
if (i%2) continue;
brchj[j]->GetEntry(i);
x = leafj[j]->GetValue();
if (i<2) cout << "j= " << j << " x[" << i << "]= " << x << endl;
tree->Fill();
}//for_j
tree->Write();
if (j == 0) {
fTreeZ = tree;
} else {
//ERROR! fTreeZ->AddFriend(str.Data(), filename);
fTreeZ->AddFriend(tree, str.Data());
delete tree;
}//if
}//for_i
// delete file;
}//CopyTrees1
//______________________________________________________________________________
void MyClass::CopyTrees2(const char *treename, const char *filename)
{
cout << "------MyClass::CopyTrees2------" << endl;
TList *friends = fTreeX->GetListOfFriends();
Int_t nentries = (Int_t)(fTreeX->GetEntries());
Int_t nfriends = friends->GetSize();
Int_t ntrees = nfriends + 1;
cout << "nfriends(treeX) = " << nfriends << endl;
TFriendElement *fe = 0;
TTree *treej[20];
Double_t x;
// Create tree/branch/leaf arrays
fe = (TFriendElement*)friends->At(0);
treej[0] = fe->GetParentTree();
treej[0]->SetBranchAddress("BrX",&x);
for (Int_t j=0; j<nfriends; j++) {
fe = (TFriendElement*)friends->At(j);
treej[j+1] = fe->GetTree();
treej[j+1]->SetBranchAddress("BrX",&x);
}//for_j
TFile *file = new TFile(filename,"RECREATE");
cout << "file = " << file->GetName() << endl;
TTree *tree = 0;
for (Int_t j=0; j<ntrees; j++) {
tree = treej[j]->CloneTree(0);
for (Int_t i=0; i<nentries; i++) {
// Test: select every second entry
if (i%2) continue;
treej[j]->GetEntry(i);
if (i<2) cout << "j= " << j << " x[" << i << "]= " << x << endl;
tree->Fill();
}//for_j
tree->Write();
if (j == 0) {
fTreeZ = tree;
} else {
//not allowed! fTreeZ->AddFriend(tree, str.Data());
delete tree;
}//if
}//for_i
// delete file;
}//CopyTrees2
//______________________________________________________________________________
void MyClass::GetTreeZ()
{
cout << "------MyClass::GetTreeZ------" << endl;
if (!fTreeZ) {cout << "fTreeZ does not exist" << endl; return;}
TList *friends = fTreeZ->GetListOfFriends();
Int_t nentries = (Int_t)(fTreeZ->GetEntries());
Int_t nfriends = friends->GetSize();
cout << "nentries(treeZ) = " << nentries << endl;
cout << "nfriends(treeZ) = " << nfriends << endl;
}//GetTreeZ
//______________________________________________________________________________
//______________________________________________________________________________
void macroFriends()
{
MyClass *myclass = new MyClass("MyClass");
myclass->CreateTrees("TreeX","TreeX.root");
myclass->CreateTrees("TreeY","TreeY.root");
myclass->AddTree("TreeX0","TreeX.root");
myclass->AddTree("TreeX1","TreeX.root");
myclass->AddTree("TreeX2","TreeX.root");
myclass->AddTree("TreeX3","TreeX.root");
myclass->AddTree("TreeY0","TreeY.root");
myclass->AddTree("TreeY1","TreeY.root");
myclass->AddTree("TreeY2","TreeY.root");
myclass->AddTree("TreeY3","TreeY.root");
myclass->CopyTrees1("TreeZ","TreeZ1.root");
myclass->GetTreeZ();
myclass->CopyTrees2("TreeZ","TreeZ2.root");
myclass->GetTreeZ();
delete myclass;
}//macroFriends
This archive was generated by hypermail 2b29 : Sun Jan 02 2005 - 05:50:07 MET