//*-- Author :    Damir Buskulic   21/03/03

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// VFrameChannelPlayer                                                  //
//                                                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "VFrameChannelPlayer.h"
#include "vegaversion.h"
#include "TDatime.h"
#include "VSelector.h"
#include "TSystem.h"
#include "TROOT.h"
#include "VManagerFrameL.h"
#include "TPad.h"
#include "TPluginManager.h"

ClassImp(VFrameChannelPlayer)

//______________________________________________________________________________
VFrameChannelPlayer::VFrameChannelPlayer()
{
//*-*-*-*-*-*-*-*-*-*Default FrameChannel player constructor*-*-*-*-*-*-*-*
//*-*                =======================================
   mFrameChannel         = 0;
}

//______________________________________________________________________________
 Int_t VFrameChannelPlayer::MakeClass(const char *classname, const char* cond, Option_t *option)
{
//*-*-*-*-*Generate skeleton analysis class for this FrameChannel*-*-*-*-*-*
//*-*      ======================================================
//
//   The following files are produced: classname.h and classname.C
//   if classname is NULL, classname will be "MyFrameAnalysis".
//
//   When the option "selector" is specified, the function generates the
//   selector class described in VFrameChannel::MakeSelector.
//
//   The generated code in classname.h includes the following:
//      - Identification of the original frame channel and input conditions
//      - Definition of analysis class (data and functions)
//      - the following class functions:
//         -constructor (connecting by default the frame channel)
//         -Init(VFrameChannel *fc) to initialize a new VFrameChannel
//
//   The generated code in classname.C includes only the main
//   analysis function Loop.
//
//   To use this function:
//      - connect your frame channel (eg: fc = new VFrameChannel("infoDB.root");)
//      - fc->MakeClass("MyClass");
//    Where MyClass.h, MyClass.C the name of the files created by this function.
//   In a vega session, you can do:
//      Root > .L MyClass.C
//      Root > MyClass t
//      Root > t.Loop();       // Loop on the frames in the frame channel
//

   TString defaultname = "MyFrameAnalysis";
   TString opt = option;
   opt.ToLower();
   TString conds = cond;

   // Connect output files
   char *fchead = new char[256];

   if (!classname) classname = defaultname.Data();
   sprintf(fchead,"%s.h",classname);
   FILE *fp = fopen(fchead,"w");
   if (!fp) {
      printf("Cannot open output file:%sn",fchead);
      delete [] fchead;
      return 3;
   }
   char *fccimp = new char[256];
   sprintf(fccimp,"%s.C",classname);
   FILE *fpc = fopen(fccimp,"w");
   if (!fpc) {
      printf("Cannot open output file:%sn",fccimp);
      delete [] fchead;
      delete [] fccimp;
      return 3;
   }
   const char *fcInfoDBName = mFrameChannel->GetInfoDBName();

//======================Generate classname.h=====================
   // Print header
   TDatime td;
   fprintf(fp,"//////////////////////////////////////////////////////////n");
   fprintf(fp,"//   This class has been automatically generated n");
   TString version = VEGAVERSION;
   fprintf(fp,"//     (%s by VEGA version %s)n",td.AsString(),version.Data());
   fprintf(fp,"//   from Frame Channeln");
   fprintf(fp,"//   based on file(s): %sn",fcInfoDBName);
   fprintf(fp,"//////////////////////////////////////////////////////////n");
   fprintf(fp,"n");
   fprintf(fp,"n");
   fprintf(fp,"#ifndef %s_hn",classname);
   fprintf(fp,"#define %s_hn",classname);
   fprintf(fp,"n");
   fprintf(fp,"#if !defined(__CINT__) || defined(__MAKECINT__)n");
   fprintf(fp,"#include "VVirtualFrameChannel.h"n");
//   fprintf(fp,"extern "C" {n");
   fprintf(fp,"#include "FrameL.h"n");
//   fprintf(fp,"}n");
   if (opt.Contains("selector")) fprintf(fp,"#include "VSelector.h"n");
   fprintf(fp,"#endifn");

// second loop on all leaves to generate type declarations
   fprintf(fp,"n");
   if (opt.Contains("selector")) {
      fprintf(fp,"class %s : public VSelector {n",classname);
   } else {
      fprintf(fp,"class %s {n",classname);
   }
   fprintf(fp,"   public :n");
   fprintf(fp,"   VVirtualFrameChannel          *mFrameChannel;   //!pointer to the used Frame Channeln");

// possible condition
   if (!conds.IsNull() && !opt.Contains("selector"))
      fprintf(fp,"   VConditionSet          *mCondSetn");

// generate class member functions prototypes
   if (opt.Contains("selector")) {
      fprintf(fp,"n");
      fprintf(fp,"   %s(VVirtualFrameChannel *fc=0) { }n",classname) ;
      fprintf(fp,"   ~%s() { }n",classname);
      fprintf(fp,"   void    Begin(VVirtualFrameChannel *fc);n");
      fprintf(fp,"   void    Init(VVirtualFrameChannel *fc);n");
      fprintf(fp,"   Bool_t  ProcessCut(FrameH* frame);n");
      fprintf(fp,"   Bool_t  ProcessFrame(FrameH* frame);n");
      fprintf(fp,"   Bool_t  ProcessVect(int nbvect, FrVect** invects, FrVect* outvect);n");
      fprintf(fp,"   void    Terminate();n");
      fprintf(fp,"   ClassDef(%s,0);n",classname);
      fprintf(fp,"};n");
      fprintf(fp,"n");
      fprintf(fp,"#endifn");
      fprintf(fp,"n");
   } else {
      fprintf(fp,"n");
      fprintf(fp,"   %s(VVirtualFrameChannel *fc=0);n",classname);
      fprintf(fp,"   ~%s();n",classname);
      fprintf(fp,"   Int_t  Cut(FrameH* frame);n");
      fprintf(fp,"   void   Init(VVirtualFrameChannel *fc);n");
      fprintf(fp,"   void   Loop();n");
      fprintf(fp,"};n");
      fprintf(fp,"n");
      fprintf(fp,"#endifn");
      fprintf(fp,"n");
   }
// generate code for class constructor
   fprintf(fp,"#ifdef %s_cxxn",classname);
   if (!opt.Contains("selector")) {
      fprintf(fp,"%s::%s(VVirtualFrameChannel *fc)n",classname,classname);
      fprintf(fp,"{n");
      fprintf(fp,"// if parameter fc is not specified (or zero), connect the infodbn");
      fprintf(fp,"// used to generate this class.n");
      fprintf(fp,"   if (fc == 0) {n");
      fprintf(fp,"      fc = new VVirtualFrameChannel("%s");n",mFrameChannel->GetInfoDBName());
      fprintf(fp,"   }n");
      fprintf(fp,"   Init(fc);n");
      fprintf(fp,"}n");
      fprintf(fp,"n");
   }

// generate code for class destructor()
   if (!opt.Contains("selector")) {
      fprintf(fp,"%s::~%s()n",classname,classname);
      fprintf(fp,"{n");
      if (!conds.IsNull() && !opt.Contains("selector"))
         fprintf(fp,"   delete mCondSetn");
      fprintf(fp,"}n");
      fprintf(fp,"n");
   }

// generate code for class member function Init()
   fprintf(fp,"void %s::Init(VVirtualFrameChannel *fc)n",classname);
   fprintf(fp,"{n");
   fprintf(fp,"   mFrameChannel = fc;n");
   if (!conds.IsNull() && !opt.Contains("selector"))
      fprintf(fp,"   mCondSet = new VConditionSet(mFrameChannel,"%s");n",cond);
   fprintf(fp,"}n");
   fprintf(fp,"n");

// generate code for class member function Cut()
   if (!opt.Contains("selector")) {
      fprintf(fp,"Int_t %s::Cut(FrameH* frame)n",classname);
      fprintf(fp,"{n");
      fprintf(fp,"// This function may be called from Loop.n");
      fprintf(fp,"// returns  1 if frame is accepted.n");
      fprintf(fp,"// returns -1 otherwise.n");
      fprintf(fp,"   return 1;n");
      fprintf(fp,"}n");
   }

   fprintf(fp,"#endif // #ifdef %s_cxxn",classname);
   fprintf(fp,"n");

//======================Generate classname.C=====================
   if (!opt.Contains("selector")) {
      // generate code for class member function Loop()
      fprintf(fpc,"#define %s_cxxn",classname);
      fprintf(fpc,"#include "%s"n",fchead);
      fprintf(fpc,"n");
      fprintf(fpc,"void %s::Loop()n",classname);
      fprintf(fpc,"{n");
      fprintf(fpc,"//   In a VEGA session, you can do:n");
      fprintf(fpc,"//      vega > .L %s.Cn",classname);
      fprintf(fpc,"//      vega > %s tn",classname);
      fprintf(fpc,"//      vega > t.Loop();       // Loop on all entriesn");
      fprintf(fpc,"//n");
      fprintf(fpc,"n//     This is the loop skeletonn");
      fprintf(fpc,"n");
      fprintf(fpc,"   FrameH* frame;n");
      if (!conds.IsNull() && !opt.Contains("selector"))
         fprintf(fpc,"   while (frame = mFrameChannel->GetNextFrame(mCondSet)) {n");
      else
         fprintf(fpc,"   while (frame = mFrameChannel->GetNextFrame()) {n");
      fprintf(fpc,"    // User part of the loop, do whatever is needed heren");
      fprintf(fpc,"n");
      fprintf(fpc,"   }n");
      fprintf(fpc,"n");
      fprintf(fpc,"}n");
   }
   if (opt.Contains("selector")) {
      // generate usage comments and list of includes
      fprintf(fpc,"#define %s_cxxn",classname);
      fprintf(fpc,"// The class definition in %s.h has been generated automaticallyn",classname);
      fprintf(fpc,"// by the VEGA utility VFrameChannel::MakeSelector().n");
      fprintf(fpc,"//n");
      fprintf(fpc,"// This class is derived from the VEGA class VSelector.n");
      fprintf(fpc,"// The following members functions are called by the VFrameChannel::Process() functions:n");
      fprintf(fpc,"//    Begin():       called everytime a loop on the frame channel starts,n");
      fprintf(fpc,"//                   a convenient place to create your histograms.n");
      fprintf(fpc,"//    ProcessCut():  called at the beginning of each frame processing to return a flag,n");
      fprintf(fpc,"//                   true if the entry must be analyzed.n");
      fprintf(fpc,"//    ProcessFrame(): called in the frame loop for all frames acceptedn");
      fprintf(fpc,"//                   by ProcessCut.n");
      fprintf(fpc,"//    ProcessVect(): called in the loop for specific vectors requestedn");
      fprintf(fpc,"//    Terminate():   called at the end of a loop on the frame channel,n");
      fprintf(fpc,"//                   a convenient place to draw/fit your histograms.n");
      fprintf(fpc,"//n");
      fprintf(fpc,"//   To use this file, try the following session on your Frame Channel fcn");
      fprintf(fpc,"//n");
      fprintf(fpc,"// vega > fc->Process("%s.C")n",classname);
      fprintf(fpc,"// vega > fc->Process("%s.C","some options")n",classname);
      fprintf(fpc,"// vega > fc->Process("%s.C+")n",classname);
      fprintf(fpc,"//n");
      fprintf(fpc,"#include "%s"n",fchead);
      fprintf(fpc,"n");
      fprintf(fpc,"#if !defined(__CINT__) || defined(__MAKECINT__)n");
      fprintf(fpc,"// Here come the user includes liken");
      fprintf(fpc,"// #include "VManagerFrameL.h"n");
      fprintf(fpc,"#endifn");
      fprintf(fpc,"n");
      // generate code for class member function Begin
      fprintf(fpc,"n");
      fprintf(fpc,"void %s::Begin(VVirtualFrameChannel *fc)n",classname);
      fprintf(fpc,"{n");
      fprintf(fpc,"   // Function called before starting the analysis loop.n");
      fprintf(fpc,"   // Initialize the frame channel.n");
      fprintf(fpc,"n");
      fprintf(fpc,"   Init(fc);n");
      fprintf(fpc,"n");
      fprintf(fpc,"   TString option = GetOption();n");
      fprintf(fpc,"n");
      fprintf(fpc,"}n");
      // generate code for class member function ProcessCut
      fprintf(fpc,"n");
      fprintf(fpc,"Bool_t %s::ProcessCut(FrameH* frame)n",classname);
      fprintf(fpc,"{n");
      fprintf(fpc,"   // Selection function.n");
      fprintf(fpc,"   // The frame "frame" is passed to it.n");
      fprintf(fpc,"   // Return kFALSE as soon as a bad frame is detected.n");
      fprintf(fpc,"n");
      fprintf(fpc,"   return kTRUE;n");
      fprintf(fpc,"}n");
      // generate code for class member function ProcessFrame
      fprintf(fpc,"n");
      fprintf(fpc,"Bool_t %s::ProcessFrame(FrameH* frame)n",classname);
      fprintf(fpc,"{n");
      fprintf(fpc,"   // Processing function.n");
      fprintf(fpc,"   // The frame "frame" is passed to it.n");
      fprintf(fpc,"   // Return kFALSE to stop processing.n");
      fprintf(fpc,"n");
      fprintf(fpc,"   return kTRUE;n");
      fprintf(fpc,"}n");
      // generate code for class member function ProcessFill
      fprintf(fpc,"n");
      fprintf(fpc,"Bool_t %s::ProcessVect(int nbvect, FrVect** invects, FrVect* outvect)n",classname);
      fprintf(fpc,"{n");
      fprintf(fpc,"   // Function called for selected vectors only.n");
      fprintf(fpc,"   // invects is an array of vectors, nbvect is the number.n");
      fprintf(fpc,"   // of vectors in the array and outvect is the resulting.n");
      fprintf(fpc,"   // output vector.n");
      fprintf(fpc,"   // Return kFALSE to stop processing.n");
      fprintf(fpc,"n");
      fprintf(fpc,"   return kTRUE;n");
      fprintf(fpc,"n");
      fprintf(fpc,"}n");
      // generate code for class member function Terminate
      fprintf(fpc,"n");
      fprintf(fpc,"void %s::Terminate()n",classname);
      fprintf(fpc,"{n");
      fprintf(fpc,"   // Function called at the end of the analysis loop.n");
      fprintf(fpc,"n");
      fprintf(fpc,"n");
      fprintf(fpc,"}n");
   }
   Info("MakeClass","Files: %s and %s generated from frame channel",fchead,fccimp);
   delete [] fchead;
   delete [] fccimp;
   fclose(fp);
   fclose(fpc);

   return 0;
}

//______________________________________________________________________________
 Int_t VFrameChannelPlayer::Process(const char *filename, double starttime, double length, const char* cond,Option_t *option)
{
//   The code in filename is loaded (interpreted or compiled , see below)
//   filename must contain a valid class implementation derived from VSelector.
//   where VSelector has the following member functions:
//
//    void VSelector::Begin():       called everytime a loop on the frame channel starts,
//                   a convenient place to create your histograms.
//    Bool_t VSelector::ProcessCut():  called at the beginning of each frame processing to return a flag,
//                   true if the entry must be analyzed.
//    void VSelector::ProcessFrame(): called in the frame loop for all frames accepted
//                   by ProcessCut.
//    void VSelector::ProcessVect(): called in the loop for specific vectors requested
//    void VSelector::Terminate():   called at the end of a loop on the frame channel,
//                   a convenient place to draw/fit your histograms.
//
//   if filename is of the form file.C, the file will be interpreted.
//   if filename is of the form file.C++, the file file.C will be compiled
//      and dynamically loaded. The corresponding binary file and shared library
//      will be deleted at the end of the function.
//   if filename is of the form file.C+, the file file.C will be compiled
//      and dynamically loaded. At next call, if file.C is older than file.o
//      and file.so, the file.C is not compiled, only file.so is loaded.

   static VSelector *selector = 0;
   delete selector; //delete previous selector if any
   // This might reloads the script and delete your option
   // string! so let copy it first:
   TString opt(option);
   selector = VSelector::GetSelector(filename);
   if (!selector) return -1;

   Int_t outproc = Process(selector,starttime,length,cond,opt);
   return outproc;
}

//______________________________________________________________________________
 Int_t VFrameChannelPlayer::Process(VSelector *selector, double starttime, double length, const char* cond,Option_t *option)
{
// Process the data provided by the frame channel associated to this player
// using the provided selector
//
// The VSelector class has the following member functions
//
//    void VSelector::Begin():       called everytime a loop on the frame channel starts,
//                   a convenient place to create your histograms.
//    Bool_t VSelector::ProcessCut():  called at the beginning of each frame processing to return a flag,
//                   true if the entry must be analyzed.
//    void VSelector::ProcessFrame(): called in the frame loop for all frames accepted
//                   by ProcessCut.
//    void VSelector::ProcessVect(): called in the loop for specific vectors requested
//    void VSelector::Terminate():   called at the end of a loop on the frame channel,
//                   a convenient place to draw/fit your histograms.
//
// If a condition is set via the cond string (string not empty), the processed
// frames or vectors will be only the ones fulfilling the condition. In this case,
// the step (via Set/GetProcessStep) information is not used
// For more information about conditions, see VConditionSet

   char** vectNames;
   FrVect** inVects;
   
   selector->SetOption(option);

   selector->Begin(mFrameChannel);  //<===call user initialisation function
   
   if (selector->GetStatus()!=-1) {

      //Create a timer to get control in the frame loop(s)
      TProcessEventTimer *timer = 0;
      Int_t interval = mFrameChannel->GetTimerInterval();
      if (!gROOT->IsBatch() && interval)
        timer = new TProcessEventTimer(interval);

      // **** loop on frames or vectors ****
      Double_t step = GetProcessStep();
      Double_t truestep;
      FrameH* curFrame=0;
      Double_t curTime = starttime;
      if (curTime<mFrameChannel->GetStart() && starttime+length>mFrameChannel->GetEnd())
         curTime = mFrameChannel->GetStart();
      
      // expand vectors names
      TString vectListS = GetProcessList();
      Int_t nbVect = vectListS.CountChar(' ')+1;
      Ssiz_t blankPos;
      Int_t blankExist, iVect;

      if (vectListS.Length()!=0) {
         vectNames = new char*[nbVect];
         for (iVect = 0; iVect<nbVect; iVect++) {
            blankPos = vectListS.First(" ");
            if (blankPos<0) {
               if (vectListS.Length()<=0) break;
               blankExist = 0;
               blankPos = vectListS.Length();
            } else blankExist = 1;
            vectNames[iVect] = new char[blankPos+1];
            memcpy(vectNames[iVect],vectListS.Data(),blankPos);
            (vectNames[iVect])[blankPos] = 0;
            vectListS.Remove(0,blankPos+blankExist);
         }
         // Also book space for vectors list
         inVects = new FrVect*[nbVect];
      } else {
         nbVect = 0;
         vectNames = 0;
         inVects = 0;
      }
      
      // load first frame
      curFrame = mFrameChannel->GetNextFrame(curTime, cond);
      if (curFrame == 0) {
         Warning("Process","First frame loaded is NULL");
         if (timer) delete timer;
         for (iVect = 0; iVect<nbVect; iVect++) delete [] vectNames[iVect];
         if (vectNames) delete [] vectNames;
         if (inVects) delete [] inVects;
         return -1;
      }
      if (strlen(cond) == 0) {
         if (step ==0) truestep = curFrame->dt;
         else truestep = step;
      } else {
         truestep = curFrame->dt;
      }
      
      while (curTime<starttime+length && curTime<mFrameChannel->GetEnd()) {
         if (timer && timer->ProcessEvents()) break;
         if (gROOT->IsInterrupted()) break;
         
      // Case of full frames
         if (nbVect<=0) {
            if (curFrame && selector->ProcessCut(curFrame))
               selector->ProcessFrame(curFrame); //<==call user analysis function
            Double_t endFrame = curFrame->GTimeS +
                  1e-9*curFrame->GTimeN + 1e-5 + curFrame->dt;
            curTime += truestep;
            if (endFrame>curTime) curTime = endFrame;
            if (curFrame) {FrameFree(curFrame); curFrame = 0;}
            curFrame = mFrameChannel->GetNextFrame(curTime, cond);
         } else {
         
      // Case of a list of vectors
            double vectLength = truestep;
            if (strlen(cond) == 0) {
               for (iVect = 0; iVect<nbVect;iVect++)
                  inVects[iVect] = mFrameChannel->GetVect(vectNames[iVect],
                                   curTime, truestep);
               curTime+=truestep;
            } else {
               vectLength = 0;
               for (iVect = 0; iVect<nbVect;iVect++) {
                  inVects[iVect] = mFrameChannel->GetNextVect(vectNames[iVect],
                                   curTime, cond);
                  if (inVects[iVect]!=0) vectLength = inVects[iVect]->dx[0];
               }
               if (vectLength>0) curTime += vectLength;
               else curTime = starttime+length;
            }
            if (vectLength>0) selector->ProcessVect(nbVect,inVects,0); //<==call user analysis function
            for (iVect = 0; iVect<nbVect;iVect++) if (inVects[iVect]!=0) FrVectFree(inVects[iVect]); 
         }
      }
      if (curFrame) FrameFree(curFrame);
      
      if (timer) delete timer;

      for (iVect = 0; iVect<nbVect; iVect++) delete [] vectNames[iVect];
      if (vectNames) delete [] vectNames;
      if (inVects) delete [] inVects;
      selector->Terminate();  //<==call user termination function
   }
   
   return selector->GetStatus();
}

//______________________________________________________________________________
 void VFrameChannelPlayer::StartViewer(int mode)
{
// Start a viewer of the frame channel corresponding to this player

   if (gROOT->IsBatch()) {
      Warning("StartViewer", "Viewer cannot run in batch mode");
      return;
   }
   
   TPluginHandler *h;
   if ((h = gROOT->GetPluginManager()->FindHandler("VVirtualFrameChannelViewer"))) {
      if (h->LoadPlugin() == -1) return;
      if (mode==0) h->ExecPlugin(1,mFrameChannel);
      else h->ExecPlugin(1,0);
   }   
}


- ROOT page - VEGA page - Class index - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to , or contact with any questions or problems regarding ROOT or VEGA.