TMidasOnline.cxx

Go to the documentation of this file.
00001 /********************************************************************\
00002 
00003   Name:         TMidasOnline.cxx
00004   Created by:   Konstantin Olchanski - TRIUMF
00005 
00006   Contents:     C++ MIDAS analyzer
00007 
00008   $Id$
00009 
00010 \********************************************************************/
00011 
00012 #include "TMidasOnline.h"
00013 
00014 #include <string>
00015 #include <assert.h>
00016 #include "midas.h"
00017 #include "msystem.h"
00018 //#include "hardware.h"
00019 //#include "ybos.h"
00020 
00021 
00022 TMidasOnline::TMidasOnline() // ctor
00023 {
00024   fDB = 0;
00025   fStartHandler  = 0;
00026   fStopHandler   = 0;
00027   fPauseHandler  = 0;
00028   fResumeHandler = 0;
00029   fEventRequests = 0;
00030   fEventHandler  = 0;
00031 }
00032 
00033 TMidasOnline::~TMidasOnline() // dtor
00034 {
00035   disconnect();
00036 }
00037 
00038 TMidasOnline* TMidasOnline::instance()
00039 {
00040   if (!gfMidas)
00041     gfMidas = new TMidasOnline();
00042   
00043   return gfMidas;
00044 }
00045 
00046 int TMidasOnline::connect(const char*hostname,const char*exptname,const char*progname)
00047 {
00048   int status;
00049   
00050   char xhostname[HOST_NAME_LENGTH];
00051   char xexptname[NAME_LENGTH];
00052   
00053   /* get default from environment */
00054   status = cm_get_environment(xhostname, sizeof(xhostname), xexptname, sizeof(xexptname));
00055   assert(status == CM_SUCCESS);
00056   
00057   if (hostname)
00058     strlcpy(xhostname,hostname,sizeof(xhostname));
00059   
00060   if (exptname)
00061     strlcpy(xexptname,exptname,sizeof(xexptname));
00062   
00063   fHostname = xhostname;
00064   fExptname = xexptname;
00065 
00066   fprintf(stderr, "TMidasOnline::connect: Connecting to experiment \"%s\" on host \"%s\"\n", fExptname.c_str(), fHostname.c_str());
00067   
00068   //int watchdog = DEFAULT_WATCHDOG_TIMEOUT;
00069   int watchdog = 60*1000;
00070 
00071   status = cm_connect_experiment1((char*)fHostname.c_str(), (char*)fExptname.c_str(), (char*)progname, NULL, DEFAULT_ODB_SIZE, watchdog);
00072   
00073   if (status == CM_UNDEF_EXP)
00074     {
00075       fprintf(stderr, "TMidasOnline::connect: Error: experiment \"%s\" not defined.\n", fExptname.c_str());
00076       return -1;
00077     }
00078   else if (status != CM_SUCCESS)
00079     {
00080       fprintf(stderr, "TMidasOnline::connect: Cannot connect to MIDAS, status %d.\n", status);
00081       return -1;
00082     }
00083   
00084   status = cm_get_experiment_database(&fDB, NULL);
00085   assert(status == CM_SUCCESS);
00086   
00087   cm_set_watchdog_params(true, 60*1000);
00088 
00089   return 0;
00090 }
00091 
00092 int TMidasOnline::disconnect()
00093 {
00094   if (fDB)
00095     {
00096       fprintf(stderr, "TMidasOnline::disconnect: Disconnecting from experiment \"%s\" on host \"%s\"\n", fExptname.c_str(), fHostname.c_str());
00097       cm_disconnect_experiment();
00098       fDB = 0;
00099     }
00100   
00101   return 0;
00102 }
00103 
00104 void TMidasOnline::registerTransitions()
00105 {
00106   cm_register_transition(TR_START,  NULL, 300);
00107   cm_register_transition(TR_PAUSE,  NULL, 700);
00108   cm_register_transition(TR_RESUME, NULL, 300);
00109   cm_register_transition(TR_STOP,   NULL, 700);
00110 }
00111 
00112 void TMidasOnline::setTransitionHandlers(TransitionHandler start,TransitionHandler stop,TransitionHandler pause,TransitionHandler resume)
00113 {
00114   fStartHandler  = start;
00115   fStopHandler   = stop;
00116   fPauseHandler  = pause;
00117   fResumeHandler = resume;
00118 }
00119 
00120 bool TMidasOnline::checkTransitions()
00121 {
00122   int transition, run_number, trans_time;
00123   
00124   int status = cm_query_transition(&transition, &run_number, &trans_time);
00125   if (status != CM_SUCCESS)
00126     return false;
00127   
00128   //printf("cm_query_transition: status %d, tr %d, run %d, time %d\n",status,transition,run_number,trans_time);
00129   
00130   if (transition == TR_START)
00131     {
00132       if (fStartHandler)
00133         (*fStartHandler)(transition,run_number,trans_time);
00134       return true;
00135     }
00136   else if (transition == TR_STOP)
00137     {
00138       if (fStopHandler)
00139         (*fStopHandler)(transition,run_number,trans_time);
00140       return true;
00141       
00142     }
00143   else if (transition == TR_PAUSE)
00144     {
00145       if (fPauseHandler)
00146         (*fPauseHandler)(transition,run_number,trans_time);
00147       return true;
00148       
00149     }
00150   else if (transition == TR_RESUME)
00151     {
00152       if (fResumeHandler)
00153         (*fResumeHandler)(transition,run_number,trans_time);
00154       return true;
00155     }
00156   
00157   return false;
00158 }
00159 
00160 bool TMidasOnline::poll(int mdelay)
00161 {
00162   //printf("poll!\n");
00163   
00164   if (checkTransitions())
00165     return true;
00166   
00167   int status = cm_yield(mdelay);
00168   if (status == RPC_SHUTDOWN || status == SS_ABORT)
00169     {
00170       fprintf(stderr, "TMidasOnline::poll: cm_yield(%d) status %d, shutting down.\n",mdelay,status);
00171       disconnect();
00172       return false;
00173     }
00174   
00175   return true;
00176 }
00177 
00178 void TMidasOnline::setEventHandler(EventHandler handler)
00179 {
00180   fEventHandler  = handler;
00181 }
00182 
00183 static void eventCallback(HNDLE buffer_handle, HNDLE request_id, EVENT_HEADER* pheader, void* pevent)
00184 {
00185 #if 0
00186   printf("eventCallback: buffer %d, request %d, pheader %p (event_id: %d, trigger mask: 0x%x, serial: %d, time: %d, size: %d), pevent %p\n",
00187          buffer_handle,
00188          request_id,
00189          pheader,
00190          pheader->event_id,
00191          pheader->trigger_mask,
00192          pheader->serial_number,
00193          pheader->time_stamp,
00194          pheader->data_size,
00195          pevent);
00196 #endif
00197   
00198   if (TMidasOnline::instance()->fEventHandler)
00199     TMidasOnline::instance()->fEventHandler(pheader,pevent,pheader->data_size);
00200 }
00201 
00202 int TMidasOnline::receiveEvent(int requestId, void* pevent, int size, bool async)
00203 {
00204   EventRequest* r = fEventRequests;
00205 
00206   while (1)
00207     {
00208       if (!r)
00209         {
00210           fprintf(stderr, "TMidasOnline::receiveEvent: Cannot find request %d\n", requestId);
00211           return -1;
00212         }
00213 
00214       if (r->fRequestId == requestId)
00215         break;
00216 
00217       r = r->fNext;
00218     }
00219 
00220   int flag = 0;
00221   if (async){
00222 #ifdef BM_NO_WAIT
00223     flag = BM_NO_WAIT;
00224 #else
00225     flag = ASYNC;
00226 #endif
00227   }
00228 
00229 
00230   int status = bm_receive_event(r->fBufferHandle, pevent, &size, flag);
00231 
00232   if (status == BM_ASYNC_RETURN)
00233     {
00234       return 0;
00235     }
00236 
00237   if (status != BM_SUCCESS)
00238     {
00239       fprintf(stderr, "TMidasOnline::receiveEvent: bm_receive_event() error %d\n", status);
00240       return -1;
00241     }
00242 
00243   return size;
00244 }
00245 
00246 #ifndef EVENT_BUFFER_SIZE
00247 #define EVENT_BUFFER_SIZE 0
00248 #endif
00249 
00250 int TMidasOnline::eventRequest(const char* bufferName, int eventId, int triggerMask, int samplingType, bool poll)
00251 {
00252   int status;
00253   EventRequest* r = new EventRequest();
00254 
00255   if (bufferName == NULL)
00256     bufferName = EVENT_BUFFER_NAME;
00257   
00258   r->fNext         = NULL;
00259   r->fBufferName   = bufferName;
00260   r->fEventId      = eventId;
00261   r->fTriggerMask  = triggerMask;
00262   r->fSamplingType = samplingType;
00263   
00264   
00265   /*---- open event buffer ---------------------------------------*/
00266   status = bm_open_buffer((char*)bufferName, EVENT_BUFFER_SIZE, &r->fBufferHandle);
00267   if (status!=SUCCESS && status!=BM_CREATED)
00268     {
00269       fprintf(stderr, "TMidasOnline::eventRequest: Cannot find data buffer \"%s\", bm_open_buffer() error %d\n", bufferName, status);
00270       return -1;
00271     }
00272   
00273   /* set the default buffer cache size (but not GET_RECENT sampling type*/
00274         if(samplingType != GET_RECENT){
00275                 status = bm_set_cache_size(r->fBufferHandle, 100000, 0);
00276                 assert(status == BM_SUCCESS);
00277         }
00278 
00279   if (poll)
00280     status = bm_request_event(r->fBufferHandle, r->fEventId, r->fTriggerMask, r->fSamplingType, &r->fRequestId, NULL);
00281   else
00282     status = bm_request_event(r->fBufferHandle, r->fEventId, r->fTriggerMask, r->fSamplingType, &r->fRequestId, eventCallback);
00283   assert(status == BM_SUCCESS);
00284   
00285   fprintf(stderr, "TMidasOnline::eventRequest: Event request: buffer \"%s\" (%d), event id 0x%x, trigger mask 0x%x, sample %d, request id: %d\n",bufferName,r->fBufferHandle,r->fEventId,r->fTriggerMask,r->fSamplingType,r->fRequestId);
00286   
00287   r->fNext = fEventRequests;
00288   fEventRequests = r;
00289   
00290   return r->fRequestId;
00291 };
00292 
00293 int TMidasOnline::getBufferLevel(){
00294 
00295   if(!fEventRequests || !fEventRequests->fBufferHandle) return -1;
00296 
00297   int n_bytes;
00298   bm_get_buffer_level(fEventRequests->fBufferHandle, &n_bytes);
00299 
00300   return n_bytes;
00301 
00302 }
00303 
00304 int TMidasOnline::getBufferSize(){
00305 
00306   if(!fEventRequests || !fEventRequests->fBufferHandle) return -1;
00307 
00308   BUFFER_HEADER buffer_header;
00309   bm_get_buffer_info(fEventRequests->fBufferHandle,&buffer_header);      
00310 
00311   return buffer_header.size;
00312 
00313 }
00314 void TMidasOnline::deleteEventRequest(int requestId)
00315 {
00316   for (EventRequest* r = fEventRequests; r != NULL; r = r->fNext)
00317     if (r->fRequestId == requestId)
00318       {
00319         int status = bm_delete_request(r->fRequestId);
00320         assert(status == BM_SUCCESS);
00321         
00322         r->fBufferHandle = -1;
00323         r->fRequestId    = -1;
00324       }
00325 }
00326 
00327 
00328 
00329 
00330 int TMidasOnline::odbReadInt(const char*name,int index,int defaultValue)
00331 {
00332   int value = defaultValue;
00333   if (odbReadAny(name,index,TID_INT,&value) == 0)
00334     return value;
00335   else
00336     return defaultValue;
00337 };
00338 
00339 uint32_t TMidasOnline::odbReadUint32(const char*name,int index,uint32_t defaultValue)
00340 {
00341   uint32_t value = defaultValue;
00342   if (odbReadAny(name,index,TID_DWORD,&value) == 0)
00343     return value;
00344   else
00345     return defaultValue;
00346 };
00347 
00348 bool     TMidasOnline::odbReadBool(const char*name,int index,bool defaultValue)
00349 {
00350   uint32_t value = defaultValue;
00351   if (odbReadAny(name,index,TID_BOOL,&value) == 0)
00352     return value;
00353   else
00354     return defaultValue;
00355 };
00356 
00357 float TMidasOnline::odbReadFloat(const char*name,int index,float defaultValue)
00358 {
00359   float value = defaultValue;
00360   if (odbReadAny(name,index,TID_FLOAT,&value) == 0)
00361     return value;
00362   else
00363     return defaultValue;
00364 };
00365 
00366 double TMidasOnline::odbReadDouble(const char*name,int index,double defaultValue)
00367 {
00368   double value = defaultValue;
00369   if (odbReadAny(name,index,TID_DOUBLE,&value) == 0)
00370     return value;
00371   else
00372     return defaultValue;
00373 };
00374 
00375 const char* TMidasOnline::odbReadString(const char *name, int index, const char *defaultValue)
00376 {
00377   const int bufsize = 1024;
00378   static char buf[bufsize];
00379   if (odbReadAny(name, index, TID_STRING, buf, bufsize) == 0)
00380     return buf;
00381   else
00382     return defaultValue;
00383 };
00384 
00385 int TMidasOnline::odbReadArraySize(const char*name)
00386 {
00387   int status;
00388   HNDLE hdir = 0;
00389   HNDLE hkey;
00390   KEY key;
00391 
00392   status = db_find_key (fDB, hdir, (char*)name, &hkey);
00393   if (status != SUCCESS)
00394     return 0;
00395 
00396   status = db_get_key(fDB, hkey, &key);
00397   if (status != SUCCESS)
00398     return 0;
00399 
00400   return key.num_values;
00401 }
00402 
00403 int TMidasOnline::odbReadAny(const char*name,int index,int tid,void* buf, int bufsize)
00404 {
00405   int status;
00406   int size = bufsize; 
00407   HNDLE hdir = 0;
00408   HNDLE hkey;
00409 
00410   if (size == 0)
00411     size = rpc_tid_size(tid);
00412 
00413   status = db_find_key (fDB, hdir, (char*)name, &hkey);
00414   if (status == SUCCESS)
00415     {
00416       status = db_get_data_index(fDB, hkey, buf, &size, index, tid);
00417       if (status != SUCCESS)
00418         {
00419           cm_msg(MERROR, "TMidasOnline", "Cannot read \'%s\'[%d] of type %d from odb, db_get_data_index() status %d", name, index, tid, status);
00420           return -1;
00421         }
00422 
00423       return 0;
00424     }
00425   else if (status == DB_NO_KEY)
00426     {
00427       cm_msg(MINFO, "TMidasOnline", "Creating \'%s\'[%d] of type %d", name, index, tid);
00428 
00429       status = db_create_key(fDB, hdir, (char*)name, tid);
00430       if (status != SUCCESS)
00431         {
00432           cm_msg (MERROR, "TMidasOnline", "Cannot create \'%s\' of type %d, db_create_key() status %d", name, tid, status);
00433           return -1;
00434         }
00435 
00436       status = db_find_key (fDB, hdir, (char*)name, &hkey);
00437       if (status != SUCCESS)
00438         {
00439           cm_msg(MERROR, "TMidasOnline", "Cannot create \'%s\', db_find_key() status %d", name, status);
00440           return -1;
00441         }
00442 
00443       status = db_set_data_index(fDB, hkey, buf, size, index, tid);
00444       if (status != SUCCESS)
00445         {
00446           cm_msg(MERROR, "TMidasOnline", "Cannot write \'%s\'[%d] of type %d to odb, db_set_data_index() status %d", name, index, tid, status);
00447           return -1;
00448         }
00449 
00450       return 0;
00451     }
00452   else
00453     {
00454       cm_msg(MERROR, "TMidasOnline", "Cannot read \'%s\'[%d] from odb, db_find_key() status %d", name, index, status);
00455       return -1;
00456     }
00457 };
00458 
00459 TMidasOnline* TMidasOnline::gfMidas = NULL;
00460 
00461 //end

Generated on 12 Feb 2016 for ROOT Analyzer by  doxygen 1.6.1