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