// evio2et // Reads evio events from a file and inserts into ET system // Rereads file at eof // Adds run and event number if requested // Still to do: // ejw, 8-jul-2013 // Disable building in codaobject support, even if it is available. // This functionality was included by Elliott so this could be used // while testing the DAQ in some integrated way. At this point, I want // to use it without any CODA system integration. The easiest thing to // do is disable it here so that it can be easily resurrected in the // future if needed. // 8/22/2014 DL #ifdef HAVE_CODAOBJECTS #undef HAVE_CODAOBJECTS #endif #include #include #include #include #include #include #include #include using namespace std; // for et #include // for evio #include "evioUtil.hxx" #include #include using namespace evio; #ifdef HAVE_CODAOBJECTS // for coda object package #include using namespace codaObject; #endif #ifndef _DBG_ #define _DBG_ cerr<<__FILE__<<":"<<__LINE__<<" " #define _DBG__ cerr<<__FILE__<<":"<<__LINE__< msg(msgp); cMsgMessage *msg = msgp; string subject = msg->getSubject(); if(subject=="delay") { // in msecs delay_time=atoi(msg->getText().c_str()); cout << "evio2et userMsgHandler...new delay time is: " << delay_time << endl; } else if(subject=="rate") { // in secs rate_time=atoi(msg->getText().c_str()); cout << "evio2et userMsgHandler...new rate time is: " << rate_time << endl; } else { cerr << "?evio2et...received unknown message subject,type: " << msg->getSubject() << "," << msg->getType() << endl << endl; } } //------------------------------------------------------------------------------- // end class definition //------------------------------------------------------------------------------- }; #endif //HAVE_CODAOBJECTS static void* monitoring_thread(void *arg) { time_t now; while(true) { // sleep if(rate_time>0) { sleep(rate_time); } else { sleep(1); } now=time(NULL); if((rate_time>0)&&(now-last_time)>rate_time) { int delta=now-last_time; read_rate=(double)(nev_read-last_rec)/(double)delta; proc_rate=(double)(nev_to_et-last_proc)/(double)delta; too_long_rate=(double)(nev_too_long-last_too_long)/(double)delta; last_time=now; last_rec=nev_read; last_proc=nev_to_et; last_too_long=nev_too_long; cout << " nev_read: " << nev_read << " events" << endl << " read_rate: " << (int)read_rate << " Hz" << endl << " nev_to_et: " << nev_to_et << " events" << endl << " proc_rate: " << (int)proc_rate << " Hz" << endl << " nev_too_long: " << nev_too_long << endl << " too_long_rate: " << (int)too_long_rate << endl << " nev_this_run: " << nev_this_run << endl << " processing: " << processing << endl << endl; } } return NULL; } //------------------------------------------------------------------------------- int main(int argc,char **argv) { int status, filecount=0, evfilecount, nDumped; bool eof=false; const uint32_t *pevio = NULL; int length,etBufferCount; uint32_t *pdata; int padding = 100; // decode command line decode_command_line(argc,argv); cout << endl << "evio2et using chunk = " << chunk << endl << endl; #ifdef HAVE_CODAOBJECTS // set session name if(startup_session.empty())startup_session="halldsession"; #endif // HAVE_CODAOBJECTS // launch monitoring thread //thread t(monitoring_thread); pthread_t t; pthread_create(&t, NULL, monitoring_thread, NULL); // allocate pevents array pevents = (et_event **) calloc(chunk, sizeof(et_event*)); if (pevents == NULL) { cerr << "unable to allocate events array, chunk is " << chunk << endl; exit(EXIT_FAILURE); } try { // create coda object and start processing #ifdef HAVE_CODAOBJECTS evio2et c(udl, name, "evio2et", startup_session); cout << "Process startup: " << name << " in session " << c.getSession() < chan(new evioFileChannel(evioFilename,"r")); evioFileChannel *chan =new evioFileChannel(evioFilename,"r"); #ifdef HAVE_CODAOBJECTS // start coda object processing c.startProcessing(); #endif // HAVE_CODAOBJECTS // force start processing = force_start; // event processing loop filecount=0; while(!done) { if(!processing) { sleep(1); } else { // open/read/close evio file as many times as needed evfilecount=0; while(!done && processing && ((max_file<=0)||(filecountopen(); // fill et buffers with evio events, reopen file if needed while(!done && processing && ((max_event_file<=0)||(evfilecount0)usleep(delay_time*1000); // get evio event from file eof=!chan->readNoCopy(); if(!eof) { nev_read++; evfilecount++; pevio=chan->getNoCopyBuffer(); length=(pevio[0]+1)*sizeof(uint32_t) + padding; // check if event fits into et buffer, must account for block headers if(length<(max_len)) { // get ET buffer data pointer et_event_getdata(pevents[i],(void**)&pdata); if(pdata==NULL) { cerr << "?null pdata" << endl; exit(EXIT_FAILURE); } // set control words...must set 1st word > 32 to not fool CODA et_control[0]=0x21; for(int ii=1; iiclose(); } } } #ifdef HAVE_CODAOBJECTS // stop processing c.stopProcessing(); #endif // HAVE_CODAOBJECTS } catch (evioException e) { cerr << "evioException caught:" << endl; cerr << e.toString() << endl; #ifdef HAVE_CODAOBJECTS } catch (CodaException e) { cerr << "CodaException caught:" << endl; cerr << e.toString() << endl; #endif // HAVE_CODAOBJECTS } catch (...) { cerr << "?unknown exception" << endl; } // done cout << endl << " *** evio2et shutdown after reading " << nev_read << "(" << filecount << ") events(files), inserting " << nev_to_et << " events ***" << endl << endl; if(connected)et_forcedclose(et_system_id); } //-------------------------------------------------------------------------- void connect_et() { int status; sigset_t sigblock; // open et system if(et_open(&et_system_id,et_filename.c_str(),openconfig)!=ET_OK) { cerr << "?connect_et...bad return from et_open" << endl; return; } // block signals to THIS thread and any thread created by this thread // needed to keep signals from et threads sigfillset(&sigblock); pthread_sigmask(SIG_BLOCK,&sigblock,NULL); // attach to grandcentral status=et_station_attach(et_system_id,ET_GRANDCENTRAL,&et_attach_id); if(status!=ET_OK) { et_forcedclose(et_system_id); cerr << "?unable to attach to grandcentral station" << endl; return; } // unblock signals pthread_sigmask(SIG_UNBLOCK,&sigblock,NULL); // now connected if(debug)cout << "...connection to grandcentral established" << endl; et_system_geteventsize(et_system_id,&etbuffersize); if(debug)cout << "Default ET event size = " << etbuffersize << endl; connected=true; et_ok=true; return; } //--------------------------------------------------------------------- void decode_command_line(int argc, char**argv) { const string help = "\nUsage:\n\n evio2et [-udl udl] [-n name] [-s session] [-force]\n" " [-delay delay_time] [-rate rate_time]\n" " [-max_event max_event] [-max_file max_file] [-max_ev_file max_event_file]\n" " [-max_len max_len] [-chunk chunk]\n" " [-no_fill] [-no_write] [-no_buffer] [-no_memcpy]\n" " [-evio evioFilename] [-et et_filename] [-debug]\n"; int i=1; while(i