ROOTANA
TRootanaEventLoop.cxx
Go to the documentation of this file.
1 // Nothing here..
2 
3 // Rootana includes
4 #include "TRootanaEventLoop.hxx"
5 #ifdef HAVE_MIDAS
6 #include "TMidasOnline.h"
7 #endif
8 //#ifdef HAVE_ROOT_XML
9 //#include "XmlOdb.h"
10 //#endif
11 #ifdef OLD_SERVER
12 #include "midasServer.h"
13 #endif
14 #ifdef HAVE_LIBNETDIRECTORY
15 #include "netDirectoryServer.h"
16 #endif
17 #ifdef HAVE_THTTP_SERVER
18 #include "THttpServer.h"
19 #endif
20 #include "TPeriodicClass.hxx"
21 #include "MainWindow.hxx"
22 
23 // ROOT includes.
24 #include <TSystem.h>
25 #include <TROOT.h>
26 #include <TH1D.h>
27 
28 #include <stdio.h>
29 #include <sys/time.h>
30 #include <iostream>
31 #include <assert.h>
32 #include <signal.h>
33 
34 #include "midasio.h"
35 
36 #include "sys/time.h"
37 /// Little function for printing the number of processed events and processing rate.
38 struct timeval raLastTime;
41 
42 // Use only recent data (less than 1 second old) when processing online
44 
46 
47  if((raTotalEventsProcessed%5000)==0){
49  gettimeofday(&raLastTime, NULL);
50  }else{
51 
52  struct timeval nowTime;
53  gettimeofday(&nowTime, NULL);
54 
55  double dtime = nowTime.tv_sec - raLastTime.tv_sec + (nowTime.tv_usec - raLastTime.tv_usec)/1000000.0;
56  double rate = 0;
57  if (dtime !=0)
58  rate = 5.0/(dtime);
59  printf("Processed %d events. Analysis rate = %6.3fkHz. \n",raTotalEventsProcessed,rate);
60  gettimeofday(&raLastTime, NULL);
61 
62  if(gUseOnlyRecent){
63  printf("Skipped %i events that were too old (>1sec old) out of %i events\n",
65  }
66  }
67  }
68 
70 
71 }
72 
73 
74 
75 
77 
79 
80  if(!fTRootanaEventLoop){
81  std::cerr << "Singleton Not Instantiated! "
82  << " Need to call something like SomeClass::CreateSingleton<SomeClass>(); Exiting!"
83  <<std::endl; exit(0);
84  }
85  return *fTRootanaEventLoop;
86 }
87 
88 // ROOT THttpServer... leave as global variable, so others don't need to know about this.
89 #ifdef HAVE_THTTP_SERVER
90  THttpServer* gRoot_http_serv = 0;
91 #endif
92 
93 
95 
96  fOutputFile = 0;
97  fOutputFilename = std::string("output");
98  fDisableRootOutput = false;
99  fODB = 0;
100  fOnlineHistDir = 0;
101  fMaxEvents = 0;
102  fCurrentRunNumber = 0;
103  fIsOffline = true;
104 
105  fCreateMainWindow = true;
106  fUseBatchMode = false;
108 
109  gUseOnlyRecent = false;
110 
111  fBufferName = std::string("SYSTEM");
112  fOnlineName = std::string("rootana");
113 
115 
116  /// Create the TApplication
117  char **argv2 = NULL;
118  fApp = new TApplication("rootana", 0, argv2);
119 }
120 
122 
123  if(fODB) delete fODB;
124  CloseRootFile();
125 
126 }
127 
128 
130 
131 void TRootanaEventLoop::BeginRun(int transition,int run,int time){};
132 
133 void TRootanaEventLoop::EndRun(int transition,int run,int time){};
134 
136 
139 
140 
141 bool TRootanaEventLoop::CheckOption(std::string option){return false;}
142 bool TRootanaEventLoop::CheckOptionRAD(std::string option){return false;}
143 
144 
146 
147  // If we didn't specify list of accepted IDs, then accept all.
148  if(fProcessEventIDs.size()==0) return true;
149 
150  // Otherwise check event ID against list
151  for(unsigned int i = 0; i < fProcessEventIDs.size(); i++){
152  if(fProcessEventIDs[i] == (eventId & 0xFFFF))
153  return true;
154  }
155 
156  return false;
157 }
158 
160 #ifdef HAVE_THTTP_SERVER
161  if(gRoot_http_serv) gRoot_http_serv->SetReadOnly(!readwrite);
162 #endif
163 }
164 
165 #ifdef HAVE_THTTP_SERVER
166 THttpServer* TRootanaEventLoop::GetTHttpServer(){
167  return gRoot_http_serv;
168 }
169 #endif
170 
171 
172 
174 
175  printf("\nUsage:\n");
176  printf("\n./analyzer.exe [-h] [-Hhostname] [-Eexptname] [-eMaxEvents] [-P9091] [-p9090] [-m] [file1 file2 ...]\n");
177  printf("\n");
178  printf("\t-h: print this help message\n");
179  printf("\t-T: test mode - start and serve a test histogram\n");
180  printf("\t-D: Become a daemon\n");
181  printf("\t-Hhostname: connect to MIDAS experiment on given host\n");
182  printf("\t-Eexptname: connect to this MIDAS experiment\n");
183  printf("\t-bbuffer: connect to this MIDAS buffer\n");
184  printf("\t-P: Start the TNetDirectory server on specified tcp port (for use with roody -Plocalhost:9091)\n");
185  printf("\t-p: Start the old midas histogram server on specified tcp port (for use with roody -Hlocalhost:9090)\n");
186 #ifdef HAVE_THTTP_SERVER
187  printf("\t-r: Start THttpServer on specified tcp port\n");
188 #endif
189  printf("\t-eXXX: Number of events XXX to read from input data files\n");
190  //printf("\t-m: Enable memory leak debugging\n");
191  UsageRAD(); // Print description of TRootanaDisplay options.
192  Usage(); // Print description of user options.
193  printf("\n");
194  printf("Example1: analyze online data: ./analyzer.exe -P9091\n");
195  printf("Example2: analyze existing data: ./analyzer.exe /data/alpha/current/run00500.mid\n");
196 
197  exit(1);
198 }
199 
200 // Stolen from MIDAS...
201 // returns 1 = success, 0 = failure
202 // copied almost completely from MIDAS system.c
204 
205  //Unused:
206  //bool keep_stdout = false;
207 #ifdef OS_LINUX
208 
209  /* only implemented for UNIX */
210  int i, fd, pid;
211 
212  if ((pid = fork()) < 0)
213  return 0;
214  else if (pid != 0)
215  exit(0); /* parent finished */
216 
217  /* child continues here */
218 
219  /* try and use up stdin, stdout and stderr, so other
220  routines writing to stdout etc won't cause havoc. Copied from smbd */
221  for (i = 0; i < 3; i++) {
222  close(i);
223  fd = open("/dev/null", O_RDWR, 0);
224  if (fd < 0)
225  fd = open("/dev/null", O_WRONLY, 0);
226  if (fd < 0) {
227  std::cout << "Can't open /dev/null" << std::endl;
228  return 0;
229  }
230  if (fd != i) {
231  std::cout << "Did not get file descriptor" << std::endl;
232  return 0;
233  }
234  }
235 
236  setsid(); /* become session leader */
237 
238 #endif
239 
240  return 1;
241 }
242 
243 
244 int TRootanaEventLoop::ExecuteLoop(int argc, char *argv[]){
245 
246  setbuf(stdout,NULL);
247  setbuf(stderr,NULL);
248 
249  signal(SIGILL, SIG_DFL);
250  signal(SIGBUS, SIG_DFL);
251  signal(SIGSEGV, SIG_DFL);
252 
253  std::vector<std::string> args;
254  for (int i=0; i<argc; i++)
255  {
256  if (strcmp(argv[i],"-h")==0)
257  PrintHelp(); // does not return
258  args.push_back(argv[i]);
259  }
260 
261 
262  if(fUseBatchMode){ // Disable creating extra window if batch mode requested.
263  gROOT->SetBatch();
264  fCreateMainWindow = false;
265  }
266 
267  if(gROOT->IsBatch() && !fUseBatchMode) {
268  printf("Cannot run without X-window support; this program is not setup to run in batch mode\n");
269  return 1;
270  }
271 
272  bool testMode = false;
273  bool daemonMode = false;
274  int tcpPort = 0;
275 #ifdef HAVE_THTTP_SERVER
276  int rhttpdPort = 0; // ROOT THttpServer port
277 #endif
278 #ifdef HAVE_MIDAS
279  const char* hostname = NULL;
280  const char* exptname = NULL;
281 #endif
282  for (unsigned int i=1; i<args.size(); i++) // loop over the commandline options
283  {
284  const char* arg = args[i].c_str();
285  //printf("argv[%d] is %s\n",i,arg);
286 
287  if (strncmp(arg,"-e",2)==0) // Event cutoff flag (only applicable in offline mode)
288  fMaxEvents = atoi(arg+2);
289  else if (strncmp(arg,"-m",2)==0) // Enable memory debugging
290  ;// gEnableShowMem = true;
291  else if (strncmp(arg,"-P",2)==0) // Set the histogram server port
292  tcpPort = atoi(arg+2);
293 #ifdef HAVE_THTTP_SERVER
294  else if (strncmp(arg,"-r",2)==0) // Set the THttpdServer port
295  rhttpdPort = atoi(arg+2);
296 #endif
297  else if (strcmp(arg,"-T")==0)
298  testMode = true;
299  else if (strcmp(arg,"-D")==0)
300  daemonMode = true;
301  #ifdef HAVE_MIDAS
302  else if (strncmp(arg,"-H",2)==0)
303  hostname = strdup(arg+2);
304  else if (strncmp(arg,"-E",2)==0)
305  exptname = strdup(arg+2);
306  #endif
307  else if (strncmp(arg,"-b",2)==0){
308  fBufferName = std::string(arg+2);
309  }else if (strcmp(arg,"-h")==0)
310  PrintHelp(); // does not return
311  else if(arg[0] == '-')// Check if a TRootanaDisplay or user-defined options
312  if(!CheckOptionRAD(args[i]))
313  if(!CheckOption(args[i]))
314  PrintHelp(); // does not return
315  }
316 
317  // Do quick check if we are processing online or offline.
318  // Want to know before we initialize.
319  fIsOffline = false;
320  for (unsigned int i=1; i<args.size(); i++){
321  const char* arg = args[i].c_str();
322  if (arg[0] != '-')
323  {
324  fIsOffline = true;
325  }
326  }
327 
328  if (daemonMode) {
329  printf("\nBecoming a daemon...\n");
330  ss_daemon_init();
331  }
332 
333  MainWindow *mainWindow=0;
334  if(fCreateMainWindow){
335  std::cout << "Create main window! " << std::endl;
336  mainWindow = new MainWindow(gClient->GetRoot(), 200, 300);
337  }
338 
339  gROOT->cd();
340  fOnlineHistDir = new TDirectory("rootana", "rootana online plots");
341 
342 #ifdef HAVE_LIBNETDIRECTORY
343  if (tcpPort)
345 #else
346  if (tcpPort)
347  fprintf(stderr,"ERROR: No support for the TNetDirectory server!\n");
348 #endif
349 
350 #ifdef HAVE_THTTP_SERVER
351  if(rhttpdPort){
352  char address[100];
353  sprintf(address,"http:%i",rhttpdPort);
354  gRoot_http_serv = new THttpServer(address);
355  }
356 #endif
357 
358  // Initialize the event loop with user initialization.
359  Initialize();
360 
361  // Initialize the event loop with rootana display initialization.
362  InitializeRAD();
363 
364 
365  for (unsigned int i=1; i<args.size(); i++){
366  const char* arg = args[i].c_str();
367  if (arg[0] != '-')
368  {
369  ProcessMidasFile(fApp,arg);
370  }
371  }
372 
373  if (testMode){
374  std::cout << "Entering test mode." << std::endl;
375  fOnlineHistDir->cd();
376  TH1D* hh = new TH1D("test", "test", 100, 0, 100);
377  hh->Fill(1);
378  hh->Fill(10);
379  hh->Fill(50);
380 
381  fApp->Run(kTRUE);
382  if(fCreateMainWindow) delete mainWindow;
383  return 0;
384  }
385 
386  // if we processed some data files,
387  // do not go into online mode.
388  if (fIsOffline){
389  if(fCreateMainWindow) delete mainWindow;
390  return 0;
391  }
392 
393 #ifdef HAVE_MIDAS
394  ProcessMidasOnline(fApp, hostname, exptname);;
395 #endif
396 
397  if(fCreateMainWindow) delete mainWindow;
398 
399  Finalize();
400 
401  return 0;
402 
403 }
404 
405 
406 
407 int TRootanaEventLoop::ProcessMidasFile(TApplication*app,const char*fname)
408 {
409  TMReaderInterface* reader = TMNewReader(fname);
410 
411  if (reader->fError) {
412  printf("Cannot open input file \"%s\"\n",fname);
413  delete reader;
414  return -1;
415  }
416 
417  // This parameter is irrelevant for offline processing.
418  gUseOnlyRecent = false;
419 
420  int i=0;
421  while (1)
422  {
423  TMidasEvent event;
424  if (!TMReadEvent(reader, &event))
425  break;
426 
427  /// Treat the begin run and end run events differently.
428  int eventId = event.GetEventId();
429 
430 
431 
432  if ((eventId & 0xFFFF) == 0x8000){// begin run event
433 
434  event.Print();
435 
436  // Load ODB contents from the ODB XML file
437  if (fODB) delete fODB;
438  fODB = MakeFileDumpOdb(event.GetData(),event.GetDataSize());
439  fCurrentRunNumber = event.GetSerialNumber();
441  BeginRun(0,event.GetSerialNumber(),0);
442  BeginRunRAD(0,event.GetSerialNumber(),0);
445 
446  } else if ((eventId & 0xFFFF) == 0x8001){// end run event
447 
448  event.Print();
449  //EndRun(0,fCurrentRunNumber,0);
450 
451 
452  } else if ((eventId & 0xFFFF) == 0x8002){
453 
454  event.Print();
455  printf("Log message: %s\n", event.GetData());
456 
457  }else if(CheckEventID(eventId)){ // all other events; check that this event ID should be processed.
458 
459  // Set the bank list for midas event.
460  event.SetBankList();
461 
462  // Set the midas event pointer in the physics event.
464 
465  //ProcessEvent if prefilter is satisfied...
468 
469  // Cleanup the information for this event.
471 
472  }
473 
475 
476  // Check if we have processed desired number of events.
477  i++;
478  if ((fMaxEvents!=0)&&(i>=fMaxEvents)){
479  printf("Reached event %d, exiting loop.\n",i);
480  break;
481  }
482  }
483 
484  reader->Close();
485  delete reader;
486  reader = NULL;
487 
490  CloseRootFile();
491 
492  // start the ROOT GUI event loop
493  // app->Run(kTRUE);
494 
495  return 0;
496 }
497 
499 
500  gUseOnlyRecent = setting;
501 };
502 
503 
504 void TRootanaEventLoop::OpenRootFile(int run, std::string midasFilename){
505 
506  if(fDisableRootOutput) return;
507 
508  if(fOutputFile) {
509  fOutputFile->Write();
510  fOutputFile->Close();
511  fOutputFile=0;
512  }
513 
514  char filename[1024];
515  // This is the default filename, using fOutputFilename
516  sprintf(filename, "%s%08d.root",fOutputFilename.c_str(), run);
517 
518  // See if user has implemented a function where they specify
519  // the root file name using the midas file name...
520  // Only works offline, because we need midas file name
521  if(midasFilename.compare("") != 0){
522  std::string fullname = SetFullOutputFileName(run,midasFilename);
523  if(fullname.compare("") != 0){
524  sprintf(filename, "%s",fullname.c_str());
525  }
526  }
527 
528  fOutputFile = new TFile(filename,"RECREATE");
529  std::cout << "Opened output file with name : " << filename << std::endl;
530 
531 
532 #ifdef HAVE_LIBNETDIRECTORY
533  NetDirectoryExport(fOutputFile, "outputFile");
534 #endif
535 }
536 
537 
539 
540  if(fOutputFile) {
541  std::cout << "Closing ROOT file "
542  << fOutputFile->GetName() << std::endl;
543  fOutputFile->Write();
544  fOutputFile->Close();
545  fOutputFile=0;
546  }
547 
548 }
549 
550 
551 
552 /// _________________________________________________________________________
553 /// _________________________________________________________________________
554 /// _________________________________________________________________________
555 /// The following code is only applicable for online MIDAS programs
556 
557 #ifdef HAVE_MIDAS
558 
559 // This global variable allows us to keep track of whether we are already in the process
560 // of analyzing a particular event.
561 static bool onlineEventLock = false;
562 
563 
564 // number of events consecutively skipped.
566 double nextWarn = 1.0;
567 
568 // number of events with late (>10sec old) timestamp.
570 double nextWarnTimestamps = 1.0;
572 struct timeval lastTimeProcessed;
573 
574 
575 /// We need to use a regular function, so that it can be passed
576 /// to the TMidasOnline event handler. This function calles the
577 /// event loop singleton, allowing the user to add their own function code.
578 void onlineEventHandler(const void*pheader,const void*pdata,int size)
579 {
580 
581 
582  // If we are already processing a previous event, then just dump this one.
583  // !!!!!!!!!!! This is adding a potential dangerous race condition!!!!!
584  // !!!!!!!!!!! Need to think hard if this is safe!!!!!!!!!!!!!!!!!!!!!!
585  if(onlineEventLock) return;
586  onlineEventLock = true;
587 
588  // Do a check; if the we are using output files, but the output file is null
589  // then dump the event. This will usually occur if we try to process additional
590  // events after the end of the run. Trying to fill a histogram will result in
591  // seg-faults, since the histograms will have been deleted when the last ROOT file
592  // was closed.
593 
594  if(TRootanaEventLoop::Get().IsRootOutputEnabled()
595  && !TRootanaEventLoop::Get().IsRootFileValid()){
596 
599  printf("onlineEventHandler Warning: Output ROOT file is not validly open, so can't fill histograms. Have skipped %i events now.\n",
601  nextWarn *= 3.16227;
602  }
603 
604  onlineEventLock = false;
605  return;
606  }
607  numberConsSkipped = 0;
608  nextWarn = 1.0;
609 
610  // If user asked for only recent events, throw out any events
611  // that are more than 1 second old.
613  TMidas_EVENT_HEADER *header = (TMidas_EVENT_HEADER*)pheader;
614 
615  struct timeval now;
616  gettimeofday(&now, NULL);
617  if(header->fTimeStamp < now.tv_sec - 1){
618 
619  // We need to add a check here: if you are connecting to MIDAS data remotely
620  // and the network link is being saturated, you will never get the most recent
621  // data and so will never have any data.
622  // This seems worse than getting old data, so disable these GET_RECENT checks if you haven't gotten
623  // any new data for 5 seconds.
624  if(lastTimeProcessed.tv_sec < now.tv_sec - 5 && raTotalEventsProcessed > 0){
625  printf("You are running in 'Only Recent Data' mode, but you haven't gotten any new data in more than 5 seconds.\n");
626  printf("Disabling 'Only Recent Data' mode for this run.\n");
627  disableOnlyRecentMode = true;
628  }
629 
631  onlineEventLock = false;
632  return;
633 
634  }
635  }
636 
637 
638  // Make a MIDAS event.
639  TMidasEvent event;
640  memcpy(event.GetEventHeader(), pheader, sizeof(TMidas_EVENT_HEADER));
641  event.SetData(size, (char*)pdata);
642  event.SetBankList();
643 
644 
645 
646  // Make sure that this is an event that we actually want to process.
647  if(!TRootanaEventLoop::Get().CheckEventID(event.GetEventId())){
648  onlineEventLock = false;
649  return;
650  }
651 
652  /// Set the midas event pointer in the physics event.
654 
655  // Now pass this to the user event function, if pre-filter is satisfied
656  if(TRootanaEventLoop::Get().PreFilter(*TRootanaEventLoop::Get().GetDataContainer())){
658  }
659 
660  gettimeofday(&lastTimeProcessed,NULL);
662 
663  // Cleanup the information for this event.
665 
666  // Do another check. If the event timestamp is more than 10 sec older than the current timestamp,
667  // then the analyzer is probably falling behind the data taking. Warn user.
668  if(!TRootanaEventLoop::Get().GetSuppressTimestampWarnings()){
669  struct timeval now;
670  gettimeofday(&now, NULL);
671  if(event.GetTimeStamp() < now.tv_sec - 10){
674  printf("onlineEventHandler Warning: the time for this bank (%i) is more than 10 sec older \nthan current time (%i). Has happenned %i times now.",
675  event.GetTimeStamp(),(int) now.tv_sec,numberOldTimestamps);
676  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");
677 
678  int buffer_level = TMidasOnline::instance()->getBufferLevel();
679  int buffer_size = TMidasOnline::instance()->getBufferSize();
680  printf("Buffer level = %i bytes out of %i bytes maximum \n\n",buffer_level,buffer_size);
681  nextWarnTimestamps *= 3.16227;
682  }
683  }
684  }
685 
686  onlineEventLock = false;
687 }
688 
689 
690 void onlineBeginRunHandler(int transition,int run,int time)
691 {
694  TRootanaEventLoop::Get().BeginRun(transition,run,time);
695  TRootanaEventLoop::Get().BeginRunRAD(transition,run,time);
699  nextWarnTimestamps = 1.0;
700  gettimeofday(&raLastTime, NULL);
701  disableOnlyRecentMode = false;
702 }
703 
704 void onlineEndRunHandler(int transition,int run,int time)
705 {
707  TRootanaEventLoop::Get().EndRunRAD(transition,run,time);
708  TRootanaEventLoop::Get().EndRun(transition,run,time);
710 }
711 
712 
714 {
715 
716  if (!(TMidasOnline::instance()->poll(0)))
717  gSystem->ExitLoop();
718 }
719 
720 int TRootanaEventLoop::ProcessMidasOnline(TApplication*app, const char* hostname, const char* exptname)
721 {
723 
724  int err = midas->connect(hostname, exptname, fOnlineName.c_str());
725  if (err != 0)
726  {
727  fprintf(stderr,"Cannot connect to MIDAS, error %d\n", err);
728  return -1;
729  }
730 
731  fODB = MakeMidasOdb(midas->fDB);
732 
733  /* fill present run parameters */
734 
735  fCurrentRunNumber = 0;
736  fODB->RI("runinfo/Run number", &fCurrentRunNumber);
737 
741 
742  // Register begin and end run handlers.
744  midas->registerTransitions();
745 
746  /* reqister event requests */
748 
749  // 2015-02-12: this doesn't seem to work, at least not when looking
750  // at remote mserver.
751  // use different options if user requested only recent data.
752  //if(fUseOnlyRecent){
753  //midas->eventRequest(fBufferName.c_str(),-1,-1,(1<<2));
754  //}else{
755  midas->eventRequest(fBufferName.c_str(),-1,-1,(1<<1));
756  //}
757 
758 
759  if(gUseOnlyRecent){
760  std::cout << "Using 'Only Recent Data' mode; all events more than 1 second old will be discarded." << std::endl;
761  }
762 
763  //printf("Startup: run %d, is running: %d, is pedestals run: %d\n",gRunNumber,gIsRunning,gIsPedestalsRun);
764 
766 
767  /*---- start main loop ----*/
768 
769  //loop_online();
770  app->Run(kTRUE); // kTRUE means return to here after finished with online processing... this ensures that we can disconnect.
771 
772  // Call user-defined EndRun and close the ROOT file.
775  CloseRootFile();
776 
777  /* disconnect from experiment */
778  midas->disconnect();
779 
780  return 0;
781 }
782 
783 #endif
struct timeval lastTimeProcessed
int raTotalEventsProcessed
bool disableOnlyRecentMode
void onlineEndRunHandler(int transition, int run, int time)
void MidasPollHandlerLocal()
int numberOldTimestamps
double nextWarnTimestamps
static bool onlineEventLock
double nextWarn
int numberConsSkipped
void onlineBeginRunHandler(int transition, int run, int time)
int ss_daemon_init()
void onlineEventHandler(const void *pheader, const void *pdata, int size)
int raTotalEventsSkippedForAge
void PrintCurrentStats()
bool gUseOnlyRecent
struct timeval raLastTime
Little function for printing the number of processed events and processing rate.
virtual void RI(const char *varname, int *value, bool create=false, MVOdbError *error=NULL)=0
void SetMidasEventPointer(TMidasEvent &event)
virtual Bool_t cd(const char *path=0)
virtual int Close()=0
MIDAS event.
Definition: TMidasEvent.h:22
TMidas_EVENT_HEADER * GetEventHeader()
return pointer to the event header
uint32_t GetDataSize() const
return the event size
uint16_t GetEventId() const
return the event id
Definition: TMidasEvent.cxx:93
uint32_t GetTimeStamp() const
return the time stamp (unix time in seconds)
uint32_t GetSerialNumber() const
return the serial number
char * GetData()
return pointer to the data buffer
void setEventHandler(EventHandler handler)
Specify user handler for data events.
void registerTransitions()
Ask MIDAS to tell us about run transitions.
int disconnect()
Disconnect from MIDAS.
static TMidasOnline * instance()
int getBufferLevel()
Get buffer level (ie the number of bytes in buffer)
int connect(const char *hostname, const char *exptname, const char *progname)
Connect to MIDAS experiment.
HNDLE fDB
ODB handle.
Definition: TMidasOnline.h:58
void setTransitionHandlers(TransitionHandler start, TransitionHandler stop, TransitionHandler pause, TransitionHandler resume)
Specify user handlers for run transitions.
int getBufferSize()
Get buffer size.
int eventRequest(const char *bufferName, int eventId, int triggerMask, int samplingType, bool poll=false)
Request data for delivery via callback (setEventHandler) or by polling (via receiveEvent)
TFile * fOutputFile
Output ROOT file.
bool fDisableRootOutput
Variable for disabling/enabling Root output.
std::string fBufferName
Buffer to connect to.
static TRootanaEventLoop & Get(void)
bool fIsOffline
Are we processing offline or online data?
virtual void Initialize(void)
virtual bool CheckOptionRAD(std::string option)
virtual bool ProcessMidasEvent(TDataContainer &dataContainer)=0
void PrintHelp()
Help Message.
void SetCurrentRunNumber(int run)
Current Run Number.
TDataContainer * fDataContainer
void UseOnlyRecent(bool setting=true)
void OpenRootFile(int run, std::string midasFilename=std::string(""))
Open output ROOT file.
std::vector< int > fProcessEventIDs
This is the set of eventIDs to process.
virtual void BeginRun(int transition, int run, int time)
virtual std::string SetFullOutputFileName(int run, std::string midasFilename)
virtual bool CheckOption(std::string option)
int fCurrentRunNumber
Current run number.
int ExecuteLoop(int argc, char *argv[])
Method to actually process the Midas information, either as file or online.
bool CheckEventID(int eventId)
Little helper method to check if EventID matchs requested EventID list.
static TRootanaEventLoop * fTRootanaEventLoop
The static pointer to the singleton instance.
void CloseRootFile()
Cloe output ROOT file.
virtual void UsageRAD(void)
Also a special version of usage for TRootanaDisplay. See CheckOptionRAD.
bool fSuppressTimestampWarnings
Bool for suppressing the warnings about old timestamps.
MVOdb * fODB
Pointer to the ODB access instance.
virtual void EndRun(int transition, int run, int time)
virtual void BeginRunRAD(int transition, int run, int time)
virtual void InitializeRAD(void)
Special version of Init method, to be used only by TRootanaDisplay.
virtual void EndRunRAD(int transition, int run, int time)
Also special version of EOR method, to be used only by TRootanaDisplay.
int ProcessMidasOnline(TApplication *app, const char *hostname, const char *exptname)
virtual void Finalize()
virtual void Usage(void)
TDataContainer * GetDataContainer()
Method to get the data container that event loop owns.
std::string fOnlineName
Name of program, as seen by MIDAS.
void SetTHttpServerReadWrite(bool readwrite=true)
TDirectory * fOnlineHistDir
TDirectory for online histograms.
virtual bool PreFilter(TDataContainer &dataContainer)
int ProcessMidasFile(TApplication *app, const char *fname)
TMReaderInterface * TMNewReader(const char *source)
Definition: midasio.cxx:442
TMEvent * TMReadEvent(TMReaderInterface *reader)
Definition: midasio.cxx:584
MVOdb * MakeMidasOdb(int hDB, MVOdbError *error=NULL)
Definition: midasodb.cxx:836
MVOdb * MakeFileDumpOdb(const char *buf, int bufsize, MVOdbError *error=NULL)
Access ODB from a midas file dump. FOrmat could be .xml, .json or .odb.
Definition: mvodb.cxx:91
void NetDirectoryExport(TDirectory *dir, const char *exportName)
void StartNetDirectoryServer(int port, TDirectory *dir)
Event header.
Definition: TMidasStructs.h:16
uint32_t fTimeStamp
event timestamp in seconds
Definition: TMidasStructs.h:20