[ROOT] Problem to copy selected entries of tree friends

From: cstrato (cstrato@aon.at)
Date: Sun Apr 25 2004 - 23:28:29 MEST


Dear Rooters

Sorry to bother you again with a version of my macro, but since
days I am trying to find an error in my program.

This is my intention:
Having a tree fTree with friend trees, I want to copy all trees
to a new file, but only with a subset of tree entries. Variable
fTree should now contain the new tree with friends.

The enclosed macro "macroFriends1.C" should create a new tree
containing as entries the mean value of the corresponding entries
of the friend trees.

Running the macro ".x macroFriends1.C(0)" uses all tree entries
to calculate the mean. It works both with CINT and ACLiC.

However, macro ".x macroFriends1.C(1)", using only every second
tree entry, crashes at different points when using CINT or ACLiC.

There must be a severe mistake in my macro, but I am unable to
detect it. It would be great if someone could tell me what the
error may be?

Thank you in advance for your help.

P.S.: To give you an idea how severe the crash of my program is,
here is part of the output that I get after calling atree->GetTitle():
nentries(atree)= 173
atree_title= <Test@T_(W9
Then the xterm produces only random characters.

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 macroFriends1.C 
//
///////////////////////////

#include "TBranch.h"
#include "TFile.h"
#include "TFriendElement.h"
#include "TLeaf.h"
#include "TList.h"
#include "TRandom.h"
#include "TROOT.h"
#include "TString.h"
#include "TSystem.h"
#include "TTree.h"

#include <Riostream.h>


class MyClass: public TNamed {

   protected:
      TFile   *fFile;
      TTree   *fTree;

   protected:
      Double_t Mean(Int_t n, const Double_t *arr);
      void     Mean(TTree *intree, const char *leafname, TTree *outtree);
      
   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(TTree *tree, const char *filename);
      void MeanTree(const char *treename, const char *filename, Int_t copy = 0);
      void GetTree();

#if !defined (__CINT__) || defined (__MAKECINT__)
      ClassDef(MyClass,1) //MyClass
#endif
};

class MyData {
//class MyData: public TObject {

   protected:
      Int_t    fID;
      Double_t fX;

   public:
      MyData() {}
      virtual ~MyData() {}

      void SetID(Int_t id)   {fID = id;}
      void SetX(Double_t x)  {fX  = x;}

      Int_t    GetID() const {return fID;}
      Double_t GetX()  const {return fX;}

#if !defined (__CINT__) || defined (__MAKECINT__)
      ClassDef(MyData,1) //MyData
#endif
};


#if !defined (__CINT__) || defined (__MAKECINT__)
ClassImp(MyClass);
ClassImp(MyData);
#endif

//______________________________________________________________________________
MyClass::MyClass(const char *name, const char *title)
        :TNamed(name, title)
{
   cout << "------MyClass::MyClass------" << endl;

   fFile = 0;
   fTree = 0;
}//Constructor

//______________________________________________________________________________
MyClass::~MyClass()
{
   cout << "------MyClass::~MyClass------" << endl;

   SafeDelete(fTree);
   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;

   TTree *tree = 0;
   TString str = "";

   gRandom->SetSeed();
   for (Int_t i=0; i<4; i++) {
      str = treename; str += i;
      tree = new TTree(str, "trees");

      Int_t split = 99;
      MyData *data = 0;
      data = new MyData();
      tree->Branch("DataBranch", "MyData", &data, 64000, split);

      for (Int_t j=0; j<nentries; j++) {
         data->SetID(j);
         data->SetX(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 (!fTree) fTree = (TTree*)fFile->Get(treename);
   else        fTree->AddFriend(treename, filename);

}//AddTree

//______________________________________________________________________________
void MyClass::CopyTrees1(TTree *tree, const char *filename)
{
   // creates new trees and copies selected entries
   cout << "------MyClass::CopyTrees1------" << endl;

   TList *friends  = tree->GetListOfFriends();
   Int_t  nentries = (Int_t)(tree->GetEntries());
   Int_t  nfriends = friends->GetSize();
   Int_t  ntrees   = nfriends + 1;

   TFriendElement *fe = 0;
   TTree   *treej[20];
   MyData  *dataj[20];
   for (Int_t j=0; j<ntrees; j++) {
      dataj[j] = 0;
   }//for_j

// Create tree/branch/leaf arrays
//   fFile->cd();
   fe = (TFriendElement*)friends->At(0);
   treej[0] = fe->GetParentTree();
cout << "treej[0] = " << treej[0]->GetName() << endl;
   treej[0]->SetBranchAddress("DataBranch",&dataj[0]);
   for (Int_t j=0; j<nfriends; j++) {
      fe = (TFriendElement*)friends->At(j);
      treej[j+1] = fe->GetTree();
cout << "treej[" << j+1 << "] = " << treej[j+1]->GetName() << endl;
      treej[j+1]->SetBranchAddress("DataBranch",&dataj[j+1]);
   }//for_j

   TFile *file = new TFile(filename,"RECREATE");
cout << "file = " << file->GetName() << endl;


   TTree *newtree = 0;
   TTree *tmptree = 0;

   for (Int_t j=0; j<ntrees; j++) {
      TString name  = treej[j]->GetName();
      TString alias = name + "=" + TString(treej[j]->GetName());
cout << "alias = " << alias << endl;
      tmptree = new TTree(treej[j]->GetName(), treej[j]->GetTitle());

      Int_t split = 99;
      MyData *data = 0;
      data = new MyData();
      tmptree->Branch("DataBranch", "MyData", &data, 64000, split);

      for (Int_t i=0; i<nentries; i++) {
         // Test: filter mask!!!!
         if (i%2) continue;

         treej[j]->GetEntry(i);
         data->SetID(dataj[j]->GetID());
         data->SetX(dataj[j]->GetX());
//if (i<4) cout << "i= " << i <<  " j= " << j << "  data= " << data->GetX() << endl;
         tmptree->Fill();
      }//for_i

      tmptree->Write();

      if (j == 0) {
         newtree = tmptree;
      } else {
         newtree->AddFriend(tmptree, alias.Data());
      }//if

      delete data;
   }//for_j

   fTree = newtree;
}//CopyTrees1

//______________________________________________________________________________
void MyClass::MeanTree(const char *treename, const char *filename, Int_t copy)
{
   cout << "------MyClass::MeanTree------" << endl;

   TBranch *brch = 0;
   TLeaf   *leaf = 0;

cout << "nentries(fTree)= " << (Int_t)(fTree->GetEntries()) << endl;
   if (copy > 0) {
      this->CopyTrees1(fTree, filename);
cout << "nentries(fTree)= " << (Int_t)(fTree->GetEntries()) << endl;
   }//if

   char title[512];
   strcpy(title, fTree->GetTitle());
   TTree *atree = new TTree(treename, title);
//   TTree *atree = new TTree(treename, fTree->GetTitle());

   this->Mean(fTree, "fX", atree);
cout << "nentries(atree)= " << (Int_t)(atree->GetEntries()) << endl;

// Get file filename
   TFile *file = 0;
   const char *fname;
   if ((fname = gSystem->ExpandPathName(filename))) {
      file = gROOT->GetFile(fname);

      if (file)  file->ReOpen("UPDATE");
      if (!file) file = TFile::Open(filename, "UPDATE");

      delete [] (char*)fname;
   }//if
   if (!file || file->IsZombie()) return;

// Write expression tree to file 
   file->cd();
   atree->Write();

  if (atree) {atree->Delete(""); atree = 0;}
}//MeanTree

//______________________________________________________________________________
void MyClass::Mean(TTree *intree, const char *leafname, TTree *outtree)
{
   cout << "------MyClass::Mean------" << endl;

// Get list of tree friends
   TFriendElement *fe = 0;
   TList *friends = intree->GetListOfFriends();
   Int_t nfriends = friends->GetSize();
   Int_t nentries = (Int_t)(intree->GetEntries());
   Int_t ntrees   = nfriends + 1;

// Get parent tree
   fe = (TFriendElement*)friends->At(0);
   TTree   *tree0 = fe->GetParentTree();
   TLeaf   *leaf0 = tree0->FindLeaf(leafname);
   TBranch *brch0 = leaf0->GetBranch();
   TTree   *treej = 0;
   TBranch *brchj = 0;
   TLeaf   *leafj = 0;

   Double_t *arr = new Double_t[ntrees];
   Double_t *mn  = new Double_t[nentries];

// Read intree entries
   for (Int_t i=0; i<nentries; i++) {
      brch0->GetEntry(i);
      arr[0] = leaf0->GetValue();

      for (Int_t j=0; j<nfriends; j++) {
         fe = (TFriendElement*)friends->At(j);
         treej = fe->GetTree();
         leafj = treej->FindLeaf(leafname);
         brchj = leafj->GetBranch();
         brchj->GetEntry(i);
         arr[j+1] = leafj->GetValue();
      }//for_j

      mn[i] = Mean(ntrees, arr);
   }//for_i

// Create branches for outtree
   Double_t mean = 0;
   outtree->Branch("BrMean",  &mean,  "mean/D");

// Fill outtree
   for (Int_t i=0; i<nentries; i++) {
      mean = mn[i];
      outtree->Fill();
   }//for_i

   if (mn)  {delete [] mn;  mn  = 0;}
   if (arr) {delete [] arr; arr = 0;}
}//Mean

//______________________________________________________________________________
void MyClass::GetTree()
{
   cout << "------MyClass::GetTree------" << endl;

   if (!fTree) {cout << "fTree does not exist" << endl; return;}

   TList *friends  = fTree->GetListOfFriends();
   Int_t  nentries = (Int_t)(fTree->GetEntries());
   Int_t  nfriends = friends->GetSize();

   cout << "nentries(tree) = " << nentries << endl;
   cout << "nfriends(tree) = " << nfriends << endl;
}//GetTree

//______________________________________________________________________________
Double_t MyClass::Mean(Int_t n, const Double_t *arr)
{
   // Calculate arithmetic mean

   if (n == 1) return arr[0];

   Double_t mean = 0.0;
   for (Int_t i=0; i<n; i++) mean += arr[i];

   return mean/n;
}//Mean

//______________________________________________________________________________
//______________________________________________________________________________
void macroFriends1(Int_t copy = 0)
{
   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->MeanTree("TreeMean","TreeZ.root", copy);
   myclass->GetTree();

   delete myclass;
}//macroFriends1



This archive was generated by hypermail 2b29 : Sun Jan 02 2005 - 05:50:07 MET