MakeClass ( 4 )

From: Jacek M. Holeczek (holeczek@us.edu.pl)
Date: Mon Apr 19 1999 - 17:11:56 MEST


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