Hi, Please find attached the new version of my MakeClass.cxx macro. Possibly it works for arrays and other objects now. Due to CINT limitations one cannot write 'x=leaf()[]; leaf()[]=y', one must say 'tmp=leaf(); x=tmp[]; tmp[]=y'. Due to CINT limitations one cannot use code generated by this macro for two-dimensional arrays directly in CINT ( as a CINT macro ), one needs to compile the analysis code and create the shared library. Have fun, Jacek. P.S. The code for arrays is not really tested. Please test it and report any problems. Jacek. //_____________________________________________________________________________ Int_t MakeClass(TTree *t, const char *classname = 0) { //====> //*-*-*-*-*-*-*Generate skeleton analysis class for this Tree*-*-*-*-*-*-* //*-* ============================================== // // The following files are produced: classname.hxx and classname.cxx // if classname is NULL, classname will be nameoftree. // // The generated code in classname.hxx includes the following: // - Identification of the original Tree and Input file name // - Definition of analysis class (data and functions) // - the following class functions: // -constructor (connecting by default the Tree file) // -GetEvent(Int_t event) // -Init(TTree *tree) to initialize a new TTree // -Show(Int_t event) to read and Dump event // // The generated code in classname.cxx includes only the main // analysis function Loop. // // To use this function: // - connect your Tree file (eg: TFile f("myfile.root");) // - T->MakeClass("MyClass"); // where T is the name of the Tree in the myfile.root file, // and MyClass.hxx, MyClass.cxx are names of files created by this function. // In a Root session, you can do: // Root > .L MyClass.cxx // Root > MyClass t // Root > t.GetEvent(12); // Fill t data members with event number 12 // Root > t.Show(); // Show values of event 12 // Root > t.Show(16); // Read and show values of event 16 // Root > t.Loop(); // Loop on all events // //====> // Check against an invalid Tree pointer if (!t) return 1; if (!t->IsA()->InheritsFrom("TTree")) { printf("Attempt to MakeClass for a non-TTree object\n"); return 2; } // Connect output files char *thead = new char[256]; if (!classname) classname = t->GetName(); sprintf(thead,"%s.hxx",classname); FILE *fp = fopen(thead,"w"); if (!fp) { printf("Cannot open output file:%s\n",thead); delete [] thead; return 3; } char *tcimp = new char[256]; sprintf(tcimp,"%s.cxx",classname); FILE *fpc = fopen(tcimp,"w"); if (!fpc) { printf("Cannot open output file:%s\n",tcimp); delete [] thead; delete [] tcimp; return 3; } char *treefile = new char[1000]; if (t->GetDirectory() && t->GetDirectory()->GetFile()) strcpy(treefile,t->GetDirectory()->GetFile()->GetName()); else strcpy(treefile,"Memory Directory"); //======================Generate classname.hxx===================== // Print header TObjArray *leaves = t->GetListOfLeaves(); Int_t nleaves = leaves->GetEntriesFast(); TDatime td; fprintf(fp,"//////////////////////////////////////////////////////////\n"); fprintf(fp,"// This class has been automatically generated \n"); fprintf(fp,"// (%s by ROOT version%s)\n",td.AsString(),gROOT->GetVersion()); fprintf(fp,"// from TTree %s/%s\n",t->GetName(),t->GetTitle()); fprintf(fp,"// found on file: %s\n",treefile); fprintf(fp,"//////////////////////////////////////////////////////////\n"); fprintf(fp,"\n"); fprintf(fp,"\n"); fprintf(fp,"#ifndef %s_hxx\n",classname); fprintf(fp,"#define %s_hxx\n",classname); fprintf(fp,"\n"); fprintf(fp,"#ifndef __CINT__\n"); fprintf(fp,"#include \"TROOT.h\"\n"); fprintf(fp,"#include \"TBranch.h\"\n"); fprintf(fp,"#include \"TTree.h\"\n"); fprintf(fp,"#include \"TFile.h\"\n"); fprintf(fp,"#else\n"); fprintf(fp,"class TBranch;\n"); fprintf(fp,"class TTree;\n"); fprintf(fp,"class TFile;\n"); fprintf(fp,"#endif\n"); fprintf(fp,"\n"); fprintf(fp,"class %s {\n",classname); fprintf(fp," public :\n"); fprintf(fp," TTree *fTree; // pointer to the analyzed TTree\n"); fprintf(fp," Int_t fEvent; // current Event number\n"); // First loop on all branches to generate branch declarations fprintf(fp," // declaration of branches\n"); Int_t nb, i; nb = t->GetListOfBranches().GetEntriesFast(); for (i=0;i<nb;i++) { branch = (TBranch*)t->GetListOfBranches().UncheckedAt(i); fprintf(fp,"%s%-15s branch_%s;\n"," ","Int_t", branch->GetName()); fprintf(fp,"%s%-15s *branch_pointer_%s;\n"," ","TBranch", branch->GetName()); } // First loop on all leaves to generate leaf declarations fprintf(fp," // declaration of leaves\n"); Int_t len, l; TLeaf *leafcount; TLeafObject *leafobj; char *bname; const char *headOK = " "; const char *headcom = " //"; const char *head; char branchname[64]; for (l=0;l<nleaves;l++) { TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l); len = leaf->GetLen(); leafcount =leaf->GetLeafCount(); TBranch *branch = leaf->GetBranch(); if (leafcount) strcpy(branchname,branch->GetName()); else strcpy(branchname,leaf->GetTitle()); char *twodim = (char*)strstr(leaf->GetTitle(),"]["); bname = branchname; while (*bname) {if (*bname == '.') *bname='_'; bname++;} if (branch->IsA() == TBranchObject::Class()) { if (branch->GetListOfBranches()->GetEntriesFast()) continue; leafobj = (TLeafObject*)leaf; if (leafobj->GetClass()) head = headOK; else head = headcom; fprintf(fp,"%s%-15s *leaf_%s;\n",head,leafobj->GetTypeName(),leafobj->GetName()); fprintf(fp,"%s%-15s *%s() {",head,leafobj->GetTypeName(),leafobj->GetName()); fprintf(fp,"if (branch_%s) return leaf_%s;",branch->GetName(),leafobj->GetName()); fprintf(fp,"branch_pointer_%s->GetEvent(fEvent);",branch->GetName()); fprintf(fp,"branch_%s = 1;return leaf_%s;}\n",branch->GetName(),leafobj->GetName()); continue; } if (leafcount) { len = leafcount->GetMaximum(); if (twodim) { fprintf(fp," %-15s leaf_%s[%d]%s;\n",leaf->GetTypeName(),branchname,len,(char*)(twodim+1)); // fprintf(fp," %-15s (&%s())[%d]%s {",leaf->GetTypeName(),branchname,len,(char*)(twodim+1)); fprintf(fp," %-15s (*%s())%s {",leaf->GetTypeName(),branchname,(char*)(twodim+1)); fprintf(fp,"if (branch_%s) return leaf_%s;",branch->GetName(),branchname); fprintf(fp,"branch_pointer_%s->GetEvent(fEvent);",branch->GetName()); fprintf(fp,"branch_%s = 1;return leaf_%s;}\n",branch->GetName(),branchname); } else { fprintf(fp," %-15s leaf_%s[%d];\n",leaf->GetTypeName(), branchname,len); // fprintf(fp," %-15s (&%s())[%d] {",leaf->GetTypeName(),branchname,len); fprintf(fp," %-15s *s() {",leaf->GetTypeName(),branchname); fprintf(fp,"if (branch_%s) return leaf_%s;",branch->GetName(),branchname); fprintf(fp,"branch_pointer_%s->GetEvent(fEvent);",branch->GetName()); fprintf(fp,"branch_%s = 1;return leaf_%s;}\n",branch->GetName(),branchname); } } else { fprintf(fp," %-15s leaf_%s;\n",leaf->GetTypeName(),branchname); fprintf(fp," %-15s &%s() {",leaf->GetTypeName(),branchname); fprintf(fp,"if (branch_%s) return leaf_%s;",branch->GetName(),branchname); fprintf(fp,"branch_pointer_%s->GetEvent(fEvent);",branch->GetName()); fprintf(fp,"branch_%s = 1;return leaf_%s;}\n",branch->GetName(),branchname); } } // generate class member functions prototypes fprintf(fp,"\n"); fprintf(fp," %s(TTree *tree = 0);\n",classname); fprintf(fp," ~%s() {;}\n",classname); fprintf(fp," Int_t GetEvent(Int_t event);\n"); fprintf(fp," void Init(TTree *tree);\n"); fprintf(fp," void Loop();\n"); fprintf(fp," void Show(Int_t event = -1);\n"); fprintf(fp,"};\n"); fprintf(fp,"\n"); fprintf(fp,"#endif\n"); fprintf(fp,"\n"); fprintf(fp,"#ifdef %s_cxx\n",classname); fprintf(fp,"\n"); // generate code for class constructor fprintf(fp,"%s::%s(TTree *tree)\n",classname,classname); fprintf(fp,"{\n"); fprintf(fp," // If parameter tree is not specified (or zero), connect the file\n"); fprintf(fp," // used to generate this class and read the Tree.\n"); fprintf(fp," if (tree == 0) {\n"); fprintf(fp," TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(\"%s\");\n",treefile); fprintf(fp," if (!f) {\n"); fprintf(fp," f = new TFile(\"%s\");\n",treefile); fprintf(fp," }\n"); fprintf(fp," tree = (TTree*)gDirectory->Get(\"%s\");\n\n",t->GetName()); fprintf(fp," }\n"); fprintf(fp," Init(tree);\n"); fprintf(fp,"}\n"); fprintf(fp,"\n"); // generate code for class member function GetEvent() fprintf(fp,"Int_t %s::GetEvent(Int_t event)\n",classname); fprintf(fp,"{\n"); fprintf(fp," // Prepare to read specified event from the Tree.\n"); fprintf(fp," if (!fTree) return 0;\n"); fprintf(fp," // if (fEvent==event) return 1;\n"); nb = t->GetListOfBranches().GetEntriesFast(); for (i=0;i<nb;i++) { branch = (TBranch*)t->GetListOfBranches().UncheckedAt(i); fprintf(fp," branch_%s = 0;\n",branch->GetName()); } fprintf(fp," fEvent = event;\n"); fprintf(fp," return 1;\n"); fprintf(fp,"}\n"); fprintf(fp,"\n"); // generate code for class member function Init() fprintf(fp,"void %s::Init(TTree *tree)\n",classname); fprintf(fp,"{\n"); fprintf(fp," // Set branch addresses.\n"); fprintf(fp," if (tree == 0) return;\n"); fprintf(fp," fTree = tree;\n"); for (l=0;l<nleaves;l++) { TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l); len = leaf->GetLen(); leafcount =leaf->GetLeafCount(); TBranch *branch = leaf->GetBranch(); if (leafcount) strcpy(branchname,branch->GetName()); else strcpy(branchname,leaf->GetTitle()); bname = branchname; while (*bname) {if (*bname == '.') *bname='_'; bname++;} char *brak = strstr(branchname,"["); if (brak) *brak = 0; head = headOK; if (branch->IsA() == TBranchObject::Class()) { if (branch->GetListOfBranches()->GetEntriesFast()) continue; leafobj = (TLeafObject*)leaf; if (!leafobj->GetClass()) head = headcom; strcpy(branchname,branch->GetName()); } if (leafcount) len = leafcount->GetMaximum()+1; if (len > 1) fprintf(fp,"%sfTree->SetBranchAddress(\"%s\",leaf_%s);\n",head,branch->GetName(),branchname); else fprintf(fp,"%sfTree->SetBranchAddress(\"%s\",&leaf_%s);\n",head,branch->GetName(),branchname); } fprintf(fp," fTree->SetBranchStatus(\"*\",0); // disable all branches\n"); nb = t->GetListOfBranches().GetEntriesFast(); for (i=0;i<nb;i++) { branch = (TBranch*)t->GetListOfBranches().UncheckedAt(i); fprintf(fp," branch_%s = 0;\n",branch->GetName()); fprintf(fp," branch_pointer_%s = fTree->GetBranch(\"%s\");\n",branch->GetName(),branch->GetName()); } fprintf(fp," fEvent = -1;\n"); fprintf(fp,"}\n"); fprintf(fp,"\n"); // generate code for class member function Show() fprintf(fp,"void %s::Show(Int_t event)\n",classname); fprintf(fp,"{\n"); fprintf(fp," // Print contents of event.\n"); fprintf(fp," // If event is not specified, print current event.\n"); fprintf(fp," if (!fTree) return;\n"); fprintf(fp," if (event>=0) fEvent = event; else event = fEvent;\n"); fprintf(fp," if (fEvent<0) return;\n"); fprintf(fp," fTree->SetBranchStatus(\"*\",1); // enable all branches\n"); fprintf(fp," fTree->Show(fEvent);\n"); fprintf(fp," fTree->SetBranchStatus(\"*\",0); // disable all branches\n"); nb = t->GetListOfBranches().GetEntriesFast(); for (i=0;i<nb;i++) { branch = (TBranch*)t->GetListOfBranches().UncheckedAt(i); fprintf(fp," branch_%s = 1;\n",branch->GetName()); } fprintf(fp,"}\n"); fprintf(fp,"\n"); fprintf(fp,"#endif\n"); fprintf(fp,"\n"); //======================Generate classname.cxx===================== // generate code for class member function Loop() fprintf(fpc,"#ifndef %s_cxx\n",classname); fprintf(fpc,"#define %s_cxx\n",classname); fprintf(fpc,"#endif\n"); fprintf(fpc,"\n"); fprintf(fpc,"#include \"%s\"\n",thead); fprintf(fpc,"\n"); fprintf(fpc,"#ifndef __CINT__\n"); fprintf(fpc,"// Place here all ROOT related includes that you need.\n"); fprintf(fpc,"#endif\n"); fprintf(fpc,"\n"); fprintf(fpc,"void %s::Loop()\n",classname); fprintf(fpc,"{\n"); fprintf(fpc,"\n // This is the loop skeleton.\n"); fprintf(fpc," if (fTree == 0) return;\n"); fprintf(fpc,"\n Stat_t nentries = fTree->GetEntries();\n"); fprintf(fpc,"\n Int_t ne = 0, nevents = 0;\n"); fprintf(fpc," for (Int_t i=0; i<nentries; i++) {\n"); fprintf(fpc," ne = fTree->GetEvent(i); nevents += ne;\n"); fprintf(fpc," }\n"); fprintf(fpc,"}\n"); fprintf(fpc,"\n"); printf("Files: %s and %s generated from Tree: %s\n",thead,tcimp,t->GetName()); delete [] thead; delete [] tcimp; delete [] treefile; fclose(fp); fclose(fpc); return 0; } //_____________________________________________________________________________
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:31 MET