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: TMidasOnline.cxx 146 2014-01-30 17:35:37Z lindner $
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 */
00274   status = bm_set_cache_size(r->fBufferHandle, 100000, 0);
00275   assert(status == BM_SUCCESS);
00276 
00277   if (poll)
00278     status = bm_request_event(r->fBufferHandle, r->fEventId, r->fTriggerMask, r->fSamplingType, &r->fRequestId, NULL);
00279   else
00280     status = bm_request_event(r->fBufferHandle, r->fEventId, r->fTriggerMask, r->fSamplingType, &r->fRequestId, eventCallback);
00281   assert(status == BM_SUCCESS);
00282   
00283   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);
00284   
00285   r->fNext = fEventRequests;
00286   fEventRequests = r;
00287   
00288   return r->fRequestId;
00289 };
00290 
00291 int TMidasOnline::getBufferLevel(){
00292 
00293   if(!fEventRequests || !fEventRequests->fBufferHandle) return -1;
00294 
00295   int n_bytes;
00296   bm_get_buffer_level(fEventRequests->fBufferHandle, &n_bytes);
00297 
00298   return n_bytes;
00299 
00300 }
00301 
00302 int TMidasOnline::getBufferSize(){
00303 
00304   if(!fEventRequests || !fEventRequests->fBufferHandle) return -1;
00305 
00306   BUFFER_HEADER buffer_header;
00307   bm_get_buffer_info(fEventRequests->fBufferHandle,&buffer_header);      
00308 
00309   return buffer_header.size;
00310 
00311 }
00312 void TMidasOnline::deleteEventRequest(int requestId)
00313 {
00314   for (EventRequest* r = fEventRequests; r != NULL; r = r->fNext)
00315     if (r->fRequestId == requestId)
00316       {
00317         int status = bm_delete_request(r->fRequestId);
00318         assert(status == BM_SUCCESS);
00319         
00320         r->fBufferHandle = -1;
00321         r->fRequestId    = -1;
00322       }
00323 }
00324 
00325 
00326 
00327 
00328 int TMidasOnline::odbReadInt(const char*name,int index,int defaultValue)
00329 {
00330   int value = defaultValue;
00331   if (odbReadAny(name,index,TID_INT,&value) == 0)
00332     return value;
00333   else
00334     return defaultValue;
00335 };
00336 
00337 uint32_t TMidasOnline::odbReadUint32(const char*name,int index,uint32_t defaultValue)
00338 {
00339   uint32_t value = defaultValue;
00340   if (odbReadAny(name,index,TID_DWORD,&value) == 0)
00341     return value;
00342   else
00343     return defaultValue;
00344 };
00345 
00346 bool     TMidasOnline::odbReadBool(const char*name,int index,bool defaultValue)
00347 {
00348   uint32_t value = defaultValue;
00349   if (odbReadAny(name,index,TID_BOOL,&value) == 0)
00350     return value;
00351   else
00352     return defaultValue;
00353 };
00354 
00355 float TMidasOnline::odbReadFloat(const char*name,int index,float defaultValue)
00356 {
00357   float value = defaultValue;
00358   if (odbReadAny(name,index,TID_FLOAT,&value) == 0)
00359     return value;
00360   else
00361     return defaultValue;
00362 };
00363 
00364 double TMidasOnline::odbReadDouble(const char*name,int index,double defaultValue)
00365 {
00366   double value = defaultValue;
00367   if (odbReadAny(name,index,TID_DOUBLE,&value) == 0)
00368     return value;
00369   else
00370     return defaultValue;
00371 };
00372 
00373 const char* TMidasOnline::odbReadString(const char *name, int index, const char *defaultValue)
00374 {
00375   const int bufsize = 1024;
00376   static char buf[bufsize];
00377   if (odbReadAny(name, index, TID_STRING, buf, bufsize) == 0)
00378     return buf;
00379   else
00380     return defaultValue;
00381 };
00382 
00383 int TMidasOnline::odbReadArraySize(const char*name)
00384 {
00385   int status;
00386   HNDLE hdir = 0;
00387   HNDLE hkey;
00388   KEY key;
00389 
00390   status = db_find_key (fDB, hdir, (char*)name, &hkey);
00391   if (status != SUCCESS)
00392     return 0;
00393 
00394   status = db_get_key(fDB, hkey, &key);
00395   if (status != SUCCESS)
00396     return 0;
00397 
00398   return key.num_values;
00399 }
00400 
00401 int TMidasOnline::odbReadAny(const char*name,int index,int tid,void* buf, int bufsize)
00402 {
00403   int status;
00404   int size = bufsize; 
00405   HNDLE hdir = 0;
00406   HNDLE hkey;
00407 
00408   if (size == 0)
00409     size = rpc_tid_size(tid);
00410 
00411   status = db_find_key (fDB, hdir, (char*)name, &hkey);
00412   if (status == SUCCESS)
00413     {
00414       status = db_get_data_index(fDB, hkey, buf, &size, index, tid);
00415       if (status != SUCCESS)
00416         {
00417           cm_msg(MERROR, "TMidasOnline", "Cannot read \'%s\'[%d] of type %d from odb, db_get_data_index() status %d", name, index, tid, status);
00418           return -1;
00419         }
00420 
00421       return 0;
00422     }
00423   else if (status == DB_NO_KEY)
00424     {
00425       cm_msg(MINFO, "TMidasOnline", "Creating \'%s\'[%d] of type %d", name, index, tid);
00426 
00427       status = db_create_key(fDB, hdir, (char*)name, tid);
00428       if (status != SUCCESS)
00429         {
00430           cm_msg (MERROR, "TMidasOnline", "Cannot create \'%s\' of type %d, db_create_key() status %d", name, tid, status);
00431           return -1;
00432         }
00433 
00434       status = db_find_key (fDB, hdir, (char*)name, &hkey);
00435       if (status != SUCCESS)
00436         {
00437           cm_msg(MERROR, "TMidasOnline", "Cannot create \'%s\', db_find_key() status %d", name, status);
00438           return -1;
00439         }
00440 
00441       status = db_set_data_index(fDB, hkey, buf, size, index, tid);
00442       if (status != SUCCESS)
00443         {
00444           cm_msg(MERROR, "TMidasOnline", "Cannot write \'%s\'[%d] of type %d to odb, db_set_data_index() status %d", name, index, tid, status);
00445           return -1;
00446         }
00447 
00448       return 0;
00449     }
00450   else
00451     {
00452       cm_msg(MERROR, "TMidasOnline", "Cannot read \'%s\'[%d] from odb, db_find_key() status %d", name, index, status);
00453       return -1;
00454     }
00455 };
00456 
00457 TMidasOnline* TMidasOnline::gfMidas = NULL;
00458 
00459 //end

Generated on 5 May 2014 for ROOT Analyzer by  doxygen 1.6.1