[ROOT] Problem with CloneTree()

From: cstrato (cstrato@aon.at)
Date: Sun Apr 18 2004 - 22:10:06 MEST


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