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