TRootanaEventLoop.cxx

Go to the documentation of this file.
00001 // Nothing here..
00002 
00003 // Rootana includes
00004 #include "TRootanaEventLoop.hxx"
00005 #include "XmlOdb.h"
00006 #ifdef OLD_SERVER
00007 #include "midasServer.h"
00008 #endif
00009 #ifdef HAVE_LIBNETDIRECTORY
00010 #include "libNetDirectory/netDirectoryServer.h"
00011 #endif
00012 #include "TPeriodicClass.hxx"
00013 #include "MainWindow.hxx"
00014 
00015 // ROOT includes.
00016 #include <TSystem.h>
00017 #include <TROOT.h>
00018 #include <TH1D.h>
00019 
00020 #include <stdio.h>
00021 #include <sys/time.h>
00022 #include <iostream>
00023 #include <assert.h>
00024 #include <signal.h>
00025 
00026 #ifdef HAVE_THTTP_SERVER
00027 #include "THttpServer.h"
00028 #endif
00029 
00030 #include "sys/time.h"
00031 /// Little function for printing the number of processed events and processing rate.
00032 struct timeval raLastTime;  
00033 int raTotalEventsProcessed = 0;
00034 int raTotalEventsSkippedForAge = 0;
00035 
00036 // Use only recent data (less than 1 second old) when processing online
00037 bool gUseOnlyRecent;
00038 
00039 void PrintCurrentStats(){
00040 
00041   if((raTotalEventsProcessed%500)==0){
00042     if(raTotalEventsProcessed==0){
00043       gettimeofday(&raLastTime, NULL);
00044     }else{
00045 
00046       struct timeval nowTime;  
00047       gettimeofday(&nowTime, NULL);
00048       
00049       double dtime = nowTime.tv_sec - raLastTime.tv_sec + (nowTime.tv_usec - raLastTime.tv_usec)/1000000.0;
00050       double rate = 0;
00051       if (time !=0)
00052         rate = 500.0/(dtime);
00053       printf("Processed %d events.  Analysis rate = %f events/seconds. \n",raTotalEventsProcessed,rate);
00054       gettimeofday(&raLastTime, NULL);
00055 
00056       if(gUseOnlyRecent){
00057         printf("Skipped %i events that were too old (>1sec old) out of %i events\n",
00058                raTotalEventsSkippedForAge, raTotalEventsSkippedForAge+raTotalEventsProcessed);
00059       }
00060     }
00061   }
00062   
00063   raTotalEventsProcessed++;
00064 
00065 }
00066  
00067 
00068 
00069 
00070 TRootanaEventLoop* TRootanaEventLoop::fTRootanaEventLoop = NULL;
00071 
00072 TRootanaEventLoop& TRootanaEventLoop::Get(void) {
00073   
00074   if(!fTRootanaEventLoop){
00075     std::cerr << "Singleton Not Instantiated! " 
00076               << " Need to call something like SomeClass::CreateSingleton<SomeClass>(); Exiting!"
00077               <<std::endl; exit(0);
00078   }
00079   return *fTRootanaEventLoop;
00080 }
00081   
00082 
00083 
00084 TRootanaEventLoop::TRootanaEventLoop (){
00085 
00086   fOutputFile = 0;
00087   fOutputFilename = std::string("output");
00088   fDisableRootOutput = false;
00089   fODB = 0;
00090   fOnlineHistDir = 0;
00091   fMaxEvents = 0;
00092   fCurrentRunNumber = 0;
00093   fIsOffline = true;
00094 
00095   fCreateMainWindow = true;
00096   fUseBatchMode = false;
00097   fSuppressTimestampWarnings = false;    
00098 
00099   gUseOnlyRecent = false;
00100 
00101   fBufferName = std::string("SYSTEM");
00102   fOnlineName = std::string("rootana");
00103 
00104   fDataContainer = new TDataContainer();
00105 
00106   /// Create the TApplication
00107   char **argv2 = NULL;
00108   fApp = new TApplication("rootana", 0, argv2);
00109 }
00110 
00111 TRootanaEventLoop::~TRootanaEventLoop (){
00112 
00113   if(fODB) delete fODB;
00114   CloseRootFile();
00115 
00116 }
00117 
00118 
00119 void TRootanaEventLoop::Initialize(void){};
00120   
00121 void TRootanaEventLoop::BeginRun(int transition,int run,int time){};
00122 
00123 void TRootanaEventLoop::EndRun(int transition,int run,int time){};
00124   
00125 void TRootanaEventLoop::Finalize(){};
00126 
00127 void TRootanaEventLoop::Usage(void){};
00128 void TRootanaEventLoop::UsageRAD(void){};
00129   
00130 
00131 bool TRootanaEventLoop::CheckOption(std::string option){return false;}
00132 bool TRootanaEventLoop::CheckOptionRAD(std::string option){return false;}
00133 
00134 
00135 bool TRootanaEventLoop::CheckEventID(int eventId){
00136 
00137   // If we didn't specify list of accepted IDs, then accept all.
00138   if(fProcessEventIDs.size()==0) return true;
00139 
00140   // Otherwise check event ID against list
00141   for(unsigned int i = 0; i < fProcessEventIDs.size(); i++){
00142     if(fProcessEventIDs[i] == (eventId & 0xFFFF))
00143       return true;
00144   }
00145   
00146   return false;
00147 }
00148 
00149 void TRootanaEventLoop::PrintHelp(){
00150 
00151   printf("\nUsage:\n");
00152   printf("\n./analyzer.exe [-h] [-Hhostname] [-Eexptname] [-eMaxEvents] [-P9091] [-p9090] [-m] [-g] [file1 file2 ...]\n");
00153   printf("\n");
00154   printf("\t-h: print this help message\n");
00155   printf("\t-T: test mode - start and serve a test histogram\n");
00156   printf("\t-Hhostname: connect to MIDAS experiment on given host\n");
00157   printf("\t-Eexptname: connect to this MIDAS experiment\n");
00158   printf("\t-bbuffer: connect to this MIDAS buffer\n");
00159   printf("\t-P: Start the TNetDirectory server on specified tcp port (for use with roody -Plocalhost:9091)\n");
00160   printf("\t-p: Start the old midas histogram server on specified tcp port (for use with roody -Hlocalhost:9090)\n");
00161 #ifdef HAVE_THTTP_SERVER
00162   printf("\t-r: Start THttpServer on specified tcp port\n");
00163 #endif
00164   printf("\t-eXXX: Number of events XXX to read from input data files\n");
00165   //printf("\t-m: Enable memory leak debugging\n");
00166   printf("\t-g: Enable graphics display when processing data files\n");
00167   UsageRAD();  // Print description of TRootanaDisplay options.
00168   Usage();  // Print description of user options.
00169   printf("\n");
00170   printf("Example1: analyze online data: ./analyzer.exe -P9091\n");
00171   printf("Example2: analyze existing data: ./analyzer.exe /data/alpha/current/run00500.mid\n");
00172 
00173   exit(1);
00174 }
00175 
00176 
00177 int TRootanaEventLoop::ExecuteLoop(int argc, char *argv[]){
00178   
00179   setbuf(stdout,NULL);
00180   setbuf(stderr,NULL);
00181   
00182   signal(SIGILL,  SIG_DFL);
00183   signal(SIGBUS,  SIG_DFL);
00184   signal(SIGSEGV, SIG_DFL);
00185 
00186   std::vector<std::string> args;
00187   for (int i=0; i<argc; i++)
00188     {
00189       if (strcmp(argv[i],"-h")==0)
00190         PrintHelp(); // does not return
00191       args.push_back(argv[i]);
00192     }
00193   
00194   
00195   if(fUseBatchMode){ // Disable creating extra window if batch mode requested.
00196     fCreateMainWindow = false;
00197   }
00198     
00199   if(gROOT->IsBatch() && !fUseBatchMode) {
00200     printf("Cannot run in batch mode\n");
00201     return 1;
00202   }
00203 
00204   bool forceEnableGraphics = false;
00205   bool testMode = false;
00206   int  tcpPort = 0;
00207   int  rhttpdPort = 0; // ROOT THttpServer port
00208   const char* hostname = NULL;
00209   const char* exptname = NULL;
00210   
00211   for (unsigned int i=1; i<args.size(); i++) // loop over the commandline options
00212     {
00213       const char* arg = args[i].c_str();
00214       //printf("argv[%d] is %s\n",i,arg);
00215       
00216       if (strncmp(arg,"-e",2)==0)  // Event cutoff flag (only applicable in offline mode)
00217         fMaxEvents = atoi(arg+2);
00218       else if (strncmp(arg,"-m",2)==0) // Enable memory debugging
00219         ;//      gEnableShowMem = true;
00220       else if (strncmp(arg,"-P",2)==0) // Set the histogram server port
00221         tcpPort = atoi(arg+2);
00222 #ifdef HAVE_THTTP_SERVER
00223       else if (strncmp(arg,"-r",2)==0) // Set the THttpdServer port
00224         rhttpdPort = atoi(arg+2);
00225 #endif
00226       else if (strcmp(arg,"-T")==0)
00227         testMode = true;
00228       else if (strcmp(arg,"-g")==0)
00229         forceEnableGraphics = true;
00230       else if (strncmp(arg,"-H",2)==0)
00231         hostname = strdup(arg+2);
00232       else if (strncmp(arg,"-E",2)==0)
00233         exptname = strdup(arg+2);
00234       else if (strncmp(arg,"-b",2)==0){
00235         fBufferName = std::string(arg+2);        
00236       }else if (strcmp(arg,"-h")==0)
00237         PrintHelp(); // does not return
00238       else if(arg[0] == '-')// Check if a TRootanaDisplay or user-defined options
00239         if(!CheckOptionRAD(args[i]))
00240           if(!CheckOption(args[i]))
00241             PrintHelp(); // does not return
00242     }
00243     
00244   // Do quick check if we are processing online or offline.
00245   // Want to know before we initialize.
00246   fIsOffline = false;  
00247   for (unsigned int i=1; i<args.size(); i++){
00248     const char* arg = args[i].c_str();
00249     if (arg[0] != '-')  
00250       {  
00251         fIsOffline = true;
00252       }
00253   }
00254 
00255 
00256   MainWindow *mainWindow=0;
00257   if(fCreateMainWindow){
00258     std::cout << "Create main window! " << std::endl;
00259     mainWindow = new MainWindow(gClient->GetRoot(), 200, 300);
00260   }
00261 
00262    gROOT->cd();
00263    fOnlineHistDir = new TDirectory("rootana", "rootana online plots");
00264 
00265 #ifdef HAVE_LIBNETDIRECTORY
00266    if (tcpPort)
00267      StartNetDirectoryServer(tcpPort, fOnlineHistDir);
00268 #else
00269    if (tcpPort)
00270      fprintf(stderr,"ERROR: No support for the TNetDirectory server!\n");
00271 #endif
00272 
00273 #ifdef HAVE_THTTP_SERVER
00274 
00275    THttpServer *root_http_serv; // = new THttpServer("http:8080");
00276    if(rhttpdPort){
00277      char address[100];
00278      sprintf(address,"http:%i",rhttpdPort);
00279      root_http_serv = new THttpServer(address);
00280    }
00281 #endif
00282   
00283    // Initialize the event loop with user initialization.
00284    Initialize();
00285 
00286    for (unsigned int i=1; i<args.size(); i++){
00287      const char* arg = args[i].c_str();
00288      if (arg[0] != '-')  
00289        {  
00290            ProcessMidasFile(fApp,arg);
00291        }
00292    }
00293 
00294    if (testMode){
00295      std::cout << "Entering test mode." << std::endl;
00296      fOnlineHistDir->cd();
00297      TH1D* hh = new TH1D("test", "test", 100, 0, 100);
00298      hh->Fill(1);
00299      hh->Fill(10);
00300      hh->Fill(50);
00301      
00302      fApp->Run(kTRUE);
00303      if(fCreateMainWindow) delete mainWindow;
00304      return 0;
00305    }
00306 
00307    // if we processed some data files,
00308    // do not go into online mode.
00309    if (fIsOffline){
00310      if(fCreateMainWindow) delete mainWindow;
00311      return 0;
00312    }
00313  
00314 #ifdef HAVE_MIDAS
00315    ProcessMidasOnline(fApp, hostname, exptname);;
00316 #endif
00317    
00318    if(fCreateMainWindow) delete mainWindow;
00319    
00320    Finalize();
00321    
00322    return 0;
00323   
00324 }
00325 
00326 
00327 
00328 int TRootanaEventLoop::ProcessMidasFile(TApplication*app,const char*fname)
00329 {
00330   TMidasFile f;
00331   bool tryOpen = f.Open(fname);
00332 
00333   if (!tryOpen){
00334     printf("Cannot open input file \"%s\"\n",fname);
00335     return -1;
00336   }
00337 
00338   // This parameter is irrelevant for offline processing.
00339   gUseOnlyRecent = false;
00340 
00341   int i=0;
00342   while (1)
00343     {
00344       TMidasEvent event;
00345       if (!f.Read(&event))
00346         break;
00347       
00348       /// Treat the begin run and end run events differently.
00349       int eventId = event.GetEventId();
00350 
00351       
00352 
00353       if ((eventId & 0xFFFF) == 0x8000){// begin run event
00354         
00355         event.Print();
00356         
00357         // Load ODB contents from the ODB XML file
00358         if (fODB) delete fODB;
00359         fODB = new XmlOdb(event.GetData(),event.GetDataSize());
00360         
00361         fCurrentRunNumber = event.GetSerialNumber();
00362         OpenRootFile(fCurrentRunNumber,fname);
00363         BeginRun(0,event.GetSerialNumber(),0);
00364         raTotalEventsProcessed = 0;
00365         raTotalEventsSkippedForAge = 0;
00366         
00367       } else if ((eventId & 0xFFFF) == 0x8001){// end run event
00368           
00369                                 event.Print();
00370         //EndRun(0,fCurrentRunNumber,0);
00371         
00372 
00373       } else if ((eventId & 0xFFFF) == 0x8002){
00374 
00375         event.Print(); 
00376         printf("Log message: %s\n", event.GetData()); 
00377 
00378       }else if(CheckEventID(eventId)){ // all other events; check that this event ID should be processed.
00379 
00380         // Set the bank list for midas event.
00381         event.SetBankList();
00382         
00383         // Set the midas event pointer in the physics event.
00384         fDataContainer->SetMidasEventPointer(event);
00385         
00386         //ProcessEvent if prefilter is satisfied...
00387                                 if(PreFilter(*fDataContainer))
00388                                          ProcessMidasEvent(*fDataContainer);
00389         
00390         // Cleanup the information for this event.
00391         fDataContainer->CleanupEvent();
00392         
00393       }
00394  
00395       PrintCurrentStats();
00396 
00397       // Check if we have processed desired number of events.
00398       i++;
00399       if ((fMaxEvents!=0)&&(i>=fMaxEvents)){
00400         printf("Reached event %d, exiting loop.\n",i);
00401         break;
00402       }
00403     }
00404   
00405   f.Close(); 
00406 
00407   EndRun(0,fCurrentRunNumber,0);
00408   CloseRootFile();  
00409 
00410   // start the ROOT GUI event loop
00411   //  app->Run(kTRUE);
00412 
00413   return 0;
00414 }
00415 
00416 void TRootanaEventLoop::UseOnlyRecent(bool setting){ 
00417 
00418   gUseOnlyRecent = setting;
00419 };
00420 
00421 
00422 void TRootanaEventLoop::OpenRootFile(int run, std::string midasFilename){
00423 
00424   if(fDisableRootOutput) return;
00425 
00426   if(fOutputFile) {
00427     fOutputFile->Write();
00428     fOutputFile->Close();
00429     fOutputFile=0;
00430   }  
00431 
00432   char filename[1024];
00433         // This is the default filename, using fOutputFilename
00434         sprintf(filename, "%s%08d.root",fOutputFilename.c_str(), run);
00435 
00436         // See if user has implemented a function where they specify 
00437         // the root file name using the midas file name...
00438         // Only works offline, because we need midas file name
00439         if(midasFilename.compare("") != 0){
00440                 std::string fullname = SetFullOutputFileName(run,midasFilename);
00441                 if(fullname.compare("") != 0){
00442                         sprintf(filename, "%s",fullname.c_str());
00443                 }
00444         }
00445         
00446   fOutputFile = new TFile(filename,"RECREATE");
00447   std::cout << "Opened output file with name : " << filename << std::endl;
00448 
00449 
00450 #ifdef HAVE_LIBNETDIRECTORY
00451   NetDirectoryExport(fOutputFile, "outputFile");
00452 #endif
00453 }
00454 
00455 
00456 void TRootanaEventLoop::CloseRootFile(){
00457 
00458   if(fOutputFile) {
00459                 std::cout << "Closing ROOT file " << std::endl;
00460     fOutputFile->Write();
00461     fOutputFile->Close();
00462     fOutputFile=0;
00463   } 
00464 
00465 }
00466 
00467 
00468 
00469 /// _________________________________________________________________________
00470 /// _________________________________________________________________________
00471 /// _________________________________________________________________________
00472 /// The following code is only applicable for online MIDAS programs
00473 
00474 #ifdef HAVE_MIDAS
00475 
00476 // This global variable allows us to keep track of whether we are already in the process
00477 // of analyzing a particular event. 
00478 static bool onlineEventLock = false;
00479 
00480 
00481 // number of events consecutively skipped.
00482 int numberConsSkipped=0;
00483 double nextWarn = 1.0;
00484 
00485 // number of events with late (>10sec old) timestamp.
00486 int numberOldTimestamps=0;
00487 double nextWarnTimestamps = 1.0;
00488 bool disableOnlyRecentMode = false;
00489 struct timeval lastTimeProcessed;  
00490 
00491 
00492 /// We need to use a regular function, so that it can be passed 
00493 /// to the TMidasOnline event handler.  This function calles the 
00494 /// event loop singleton, allowing the user to add their own function code. 
00495 void onlineEventHandler(const void*pheader,const void*pdata,int size)
00496 {
00497 
00498   // If we are already processing a previous event, then just dump this one.
00499   // !!!!!!!!!!! This is adding a potential dangerous race condition!!!!!
00500   // !!!!!!!!!!! Need to think hard if this is safe!!!!!!!!!!!!!!!!!!!!!!
00501   if(onlineEventLock) return;
00502   onlineEventLock = true;
00503 
00504   // Do a check; if the we are using output files, but the output file is null
00505   // then dump the event.  This will usually occur if we try to process additional
00506   // events after the end of the run.  Trying to fill a histogram will result in
00507   // seg-faults, since the histograms will have been deleted when the last ROOT file
00508   // was closed.
00509   if(TRootanaEventLoop::Get().IsRootOutputEnabled() 
00510      && !TRootanaEventLoop::Get().IsRootFileValid()){
00511 
00512     numberConsSkipped++;
00513     if(numberConsSkipped >= nextWarn){
00514       printf("onlineEventHandler Warning:  Output ROOT file is not validly open, so can't fill histograms. Have skipped %i events now.\n",
00515              numberConsSkipped);
00516       nextWarn *= 3.16227;
00517     }
00518     
00519     onlineEventLock = false;
00520     return;
00521   }
00522   numberConsSkipped = 0;
00523   nextWarn = 1.0;
00524 
00525   // If user asked for only recent events, throw out any events
00526   // that are more than 1 second old.
00527   if(gUseOnlyRecent && !disableOnlyRecentMode){
00528     TMidas_EVENT_HEADER *header = (TMidas_EVENT_HEADER*)pheader;
00529 
00530     struct timeval now;  
00531     gettimeofday(&now, NULL);
00532     if(header->fTimeStamp < now.tv_sec - 1){      
00533       
00534       // We need to add a check here: if you are connecting to MIDAS data remotely 
00535       // and the network link is being saturated, you will never get the most recent
00536       // data and so will never have any data.
00537       // This seems worse than getting old data, so disable these GET_RECENT checks if you haven't gotten
00538       // any new data for 5 seconds.
00539       if(lastTimeProcessed.tv_sec < now.tv_sec - 5 && raTotalEventsProcessed > 0){
00540         printf("You are running in 'Only Recent Data' mode, but you haven't gotten any new data in more than 5 seconds.\n");
00541         printf("Disabling 'Only Recent Data' mode for this run.\n");
00542         disableOnlyRecentMode = true;
00543       }
00544 
00545       raTotalEventsSkippedForAge++;
00546       onlineEventLock = false;
00547       return;
00548       
00549     }
00550   }
00551 
00552   // Make a MIDAS event.
00553   TMidasEvent event;
00554   memcpy(event.GetEventHeader(), pheader, sizeof(TMidas_EVENT_HEADER));
00555   event.SetData(size, (char*)pdata);
00556   event.SetBankList();
00557   
00558 
00559 
00560   // Make sure that this is an event that we actually want to process.
00561   if(!TRootanaEventLoop::Get().CheckEventID(event.GetEventId())){
00562     onlineEventLock = false;
00563     return;
00564   }
00565 
00566   /// Set the midas event pointer in the physics event.
00567   TRootanaEventLoop::Get().GetDataContainer()->SetMidasEventPointer(event);
00568 
00569   // Now pass this to the user event function, if pre-filter is satisfied
00570   if(TRootanaEventLoop::Get().PreFilter(*TRootanaEventLoop::Get().GetDataContainer())){         
00571     TRootanaEventLoop::Get().ProcessMidasEvent(*TRootanaEventLoop::Get().GetDataContainer());
00572   }
00573 
00574   gettimeofday(&lastTimeProcessed,NULL);
00575   PrintCurrentStats();
00576 
00577   // Cleanup the information for this event.
00578   TRootanaEventLoop::Get().GetDataContainer()->CleanupEvent();
00579 
00580 
00581   // Do another check.  If the event timestamp is more than 10 sec older than the current timestamp,
00582   // then the analyzer is probably falling behind the data taking.  Warn user.
00583   if(!TRootanaEventLoop::Get().GetSuppressTimestampWarnings()){
00584     struct timeval now;  
00585     gettimeofday(&now, NULL);
00586     if(event.GetTimeStamp() < now.tv_sec - 10){      
00587       numberOldTimestamps++;
00588       if(numberOldTimestamps >= nextWarnTimestamps){
00589         printf("onlineEventHandler Warning: the time for this bank (%i) is more than 10 sec older \nthan current time (%i). Has happenned %i times now.",       
00590                event.GetTimeStamp(),(int) now.tv_sec,numberOldTimestamps);
00591         printf("Either the analyzer is falling behind the data taking \n(try modifying the fraction of events plotted) or times on different computers are not synchronized.\n");  
00592         
00593         int buffer_level = TMidasOnline::instance()->getBufferLevel();
00594         int buffer_size = TMidasOnline::instance()->getBufferSize();
00595         printf("Buffer level = %i bytes out of %i bytes maximum \n\n",buffer_level,buffer_size);        
00596         nextWarnTimestamps *= 3.16227;
00597       }      
00598     }
00599   }
00600 
00601   onlineEventLock = false;
00602 }
00603 
00604 
00605 void onlineBeginRunHandler(int transition,int run,int time)
00606 {
00607   TRootanaEventLoop::Get().OpenRootFile(run);
00608   TRootanaEventLoop::Get().SetCurrentRunNumber(run);
00609   TRootanaEventLoop::Get().BeginRun(transition,run,time);
00610   raTotalEventsProcessed = 0;
00611   raTotalEventsSkippedForAge = 0;
00612   numberOldTimestamps = 0;
00613   nextWarnTimestamps = 1.0;
00614   gettimeofday(&raLastTime, NULL);
00615   disableOnlyRecentMode = false;
00616 }
00617 
00618 void onlineEndRunHandler(int transition,int run,int time)
00619 {
00620   TRootanaEventLoop::Get().SetCurrentRunNumber(run);
00621   TRootanaEventLoop::Get().EndRun(transition,run,time);
00622   TRootanaEventLoop::Get().CloseRootFile();
00623 }
00624 
00625 
00626 void MidasPollHandlerLocal()
00627 {
00628 
00629   if (!(TMidasOnline::instance()->poll(0)))
00630     gSystem->ExitLoop();
00631 }
00632 
00633 int TRootanaEventLoop::ProcessMidasOnline(TApplication*app, const char* hostname, const char* exptname)
00634 {
00635    TMidasOnline *midas = TMidasOnline::instance();
00636 
00637    int err = midas->connect(hostname, exptname, fOnlineName.c_str());
00638    if (err != 0)
00639      {
00640        fprintf(stderr,"Cannot connect to MIDAS, error %d\n", err);
00641        return -1;
00642      }
00643 
00644    fODB = midas;
00645 
00646    /* fill present run parameters */
00647 
00648    fCurrentRunNumber = fODB->odbReadInt("/runinfo/Run number");
00649 
00650    //   if ((fODB->odbReadInt("/runinfo/State") == 3))
00651    //startRun(0,gRunNumber,0);
00652    OpenRootFile(fCurrentRunNumber);
00653    BeginRun(0,fCurrentRunNumber,0);
00654 
00655    // Register begin and end run handlers.
00656    midas->setTransitionHandlers(onlineBeginRunHandler,onlineEndRunHandler,NULL,NULL);
00657    midas->registerTransitions();
00658 
00659    /* reqister event requests */
00660    midas->setEventHandler(onlineEventHandler);
00661 
00662    // 2015-02-12: this doesn't seem to work, at least not when looking 
00663    // at remote mserver.
00664    // use different options if user requested only recent data.
00665    //if(fUseOnlyRecent){
00666    //midas->eventRequest(fBufferName.c_str(),-1,-1,(1<<2));  
00667    //}else{
00668    midas->eventRequest(fBufferName.c_str(),-1,-1,(1<<1)); 
00669    //}
00670    
00671    if(gUseOnlyRecent){
00672      std::cout << "Using 'Only Recent Data' mode; all events more than 1 second old will be discarded." << std::endl;
00673    }
00674    
00675    // printf("Startup: run %d, is running: %d, is pedestals run: %d\n",gRunNumber,gIsRunning,gIsPedestalsRun);
00676    
00677    TPeriodicClass tm(100,MidasPollHandlerLocal);
00678 
00679    /*---- start main loop ----*/
00680 
00681    //loop_online();
00682    app->Run(kTRUE); // kTRUE means return to here after finished with online processing... this ensures that we can disconnect.
00683    
00684    // Call user-defined EndRun and close the ROOT file.
00685    EndRun(0,fCurrentRunNumber,0);
00686    CloseRootFile();  
00687 
00688    /* disconnect from experiment */
00689    midas->disconnect();
00690 
00691    return 0;
00692 }
00693 
00694 #endif

Generated on 12 Feb 2016 for ROOT Analyzer by  doxygen 1.6.1