13 #include <JANA/JException.h>
22 HDET::HDET(
string source_name,
int ET_STATION_NEVENTS,
bool ET_STATION_CREATE_BLOCKING):
23 source_name(source_name)
24 ,ET_STATION_NEVENTS(ET_STATION_NEVENTS)
25 ,ET_STATION_CREATE_BLOCKING(ET_STATION_CREATE_BLOCKING)
42 cerr <<
"=== ERROR: ET source specified and this was compiled without ===" << endl;
43 cerr <<
"=== ET support. You need to install ET and set your ===" << endl;
44 cerr <<
"=== ETROOT environment variable appropriately before ===" << endl;
45 cerr <<
"=== recompiling. ===" << endl;
47 throw JException(
"Compiled without ET support " + this->source_name, __FILE__, __LINE__);
85 vector<string> fields;
87 size_t startpos=0, endpos=0;
88 while((endpos = str.find(
":", startpos)) != str.npos){
89 size_t len = endpos-startpos;
90 fields.push_back(len==0 ?
"":str.substr(startpos, len));
93 if(startpos<str.length()) fields.push_back(str.substr(startpos, str.npos));
95 string session = fields.size()>1 ? fields[1]:
"";
96 string station = fields.size()>2 ? fields[2]:
"";
97 string host = fields.size()>3 ? fields[3]:
"localhost";
98 int port = fields.size()>4 ? atoi(fields[4].c_str()):ET_SERVER_PORT;
100 if(session ==
"") session =
"none";
101 if(station ==
"") station =
"DANA";
102 if(host ==
"") host =
"localhost";
103 string fname = session.at(0)==
'/' ? session:(
string(
"/tmp/et_sys_") + session);
106 cout <<
" Opening ET system:" << endl;
107 if(session!=fname) cout <<
" session: " << session << endl;
108 cout <<
" station: " << station << endl;
109 cout <<
" system file: " << fname << endl;
110 cout <<
" host: " << host << endl;
111 if(port !=0) cout <<
" port: " << port << endl;
114 et_openconfig openconfig;
115 et_open_config_init(&openconfig);
117 if(host.find(
"239.")==0){
118 cout<<__FILE__<<
":"<<__LINE__<<
" Configuring input ET for multicast" << endl;
119 et_open_config_setcast(openconfig, ET_MULTICAST);
120 et_open_config_addmulticast(openconfig, host.c_str());
121 et_open_config_sethost(openconfig, ET_HOST_ANYWHERE);
122 et_open_config_setport(openconfig, port);
123 struct timespec tspec={5,5};
124 et_open_config_settimeout(openconfig, tspec);
125 et_open_config_setwait(openconfig, ET_OPEN_WAIT);
127 cout<<__FILE__<<
":"<<__LINE__<<
" Configuring input ET for direct connection" << endl;
128 et_open_config_setcast(openconfig, ET_DIRECT);
129 et_open_config_setmode(openconfig, ET_HOST_AS_LOCAL);
130 et_open_config_sethost(openconfig, host.c_str());
131 et_open_config_setport(openconfig, ET_BROADCAST_PORT);
132 if(port != 0)et_open_config_setserverport(openconfig, port);
135 int err = et_open(&sys_id,fname.c_str(),openconfig);
137 cerr << __FILE__<<
":"<<__LINE__<<
" Problem opening ET system"<<endl;
138 cerr << et_perror(err);
143 et_statconfig et_station_config;
144 et_station_config_init(&et_station_config);
145 et_station_config_setblock(et_station_config, ET_STATION_CREATE_BLOCKING ? ET_STATION_BLOCKING:ET_STATION_NONBLOCKING);
146 et_station_config_setselect(et_station_config,ET_STATION_SELECT_ALL);
147 et_station_config_setuser(et_station_config,ET_STATION_USER_MULTI);
148 et_station_config_setrestore(et_station_config,ET_STATION_RESTORE_OUT);
149 et_station_config_setcue(et_station_config,ET_STATION_NEVENTS);
150 et_station_config_setprescale(et_station_config,1);
151 cout<<
"ET station configured\n";
154 int status=et_station_create(sys_id,&sta_id,station.c_str(),et_station_config);
155 if((status!=ET_OK)&&(status!=ET_ERROR_EXISTS)) {
157 cerr <<
"Unable to create station " << station << endl;
158 cerr << et_perror(status);
163 et_system_getnumevents(sys_id, &Nevents);
164 if(Nevents <= ET_STATION_NEVENTS){
165 cerr <<
"NOTE: The number of events specified for the station cue is equal to" << endl;
166 cerr <<
"or greater than the number of events in the entire ET system:" << endl;
168 cerr <<
" " << ET_STATION_NEVENTS <<
" >= " << Nevents << endl;
170 cerr <<
"Try re-running with: " << endl;
172 cerr <<
" -PEVIO:ET_STATION_NEVENTS=" << (Nevents+1)/2 << endl;
177 if(status==ET_ERROR_EXISTS){
178 cout <<
" Using existing ET station " << station << endl;
180 cout <<
" ET station " << station <<
" created\n";
184 status=et_station_attach(sys_id,sta_id,&att_id);
187 cerr <<
"Unable to attach to station " << station << endl;
191 cout <<
"...now connected to ET system: " << fname
192 <<
", station: " << station <<
" (station id=" << sta_id <<
", attach id=" << att_id <<
")" << endl;
199 et_system_geteventsize(sys_id, &eventsize);
200 cout<<
" ET system event size:"<<eventsize<<endl;
217 et_buff_pool.clear();
223 bool HDET::read(uint32_t* &buff, uint32_t &buff_len,
bool allow_swap)
246 if(
VERBOSE>3) cout <<
"HDET: et_buffs empty. Will read new ET event ..." << endl;
250 struct timespec timeout;
251 timeout.tv_sec = (
unsigned int)floor(TIMEOUT);
252 timeout.tv_nsec = (
unsigned int)floor(1.0E9*(TIMEOUT-(
float)timeout.tv_sec));
254 int err = et_event_get(sys_id, att_id, &pe, ET_TIMED , &timeout);
259 uint32_t *et_buff = NULL;
261 et_event_getdata(pe, (
void**)&et_buff);
262 et_event_getlength(pe, &et_len);
264 if(
VERBOSE>3) cout <<
"HDET: read ET event with total length of " << et_len <<
" bytes (" << et_len/4 <<
" words)" << endl;
279 while(et_idx < et_len/4){
282 if(
VERBOSE>3)cout <<
"HDET: Looking for EVIO block header at et_idx=" << et_idx << endl;
283 uint32_t *evio_block = &et_buff[et_idx];
289 uint32_t magic = evio_block[7];
294 cout <<
"HDET: EVIO magic word not present!" << endl;
298 uint32_t len = evio_block[0];
301 cout <<
"HDET: Swapping is " << (
swap_needed ?
"":
"not ") <<
"needed" << endl;
302 cout <<
"HDET: Num. words in EVIO buffer: "<<len<<endl;
305 bool is_last_evio_block = (evio_block[5]>>(9+8))&0x1;
306 if(
VERBOSE>3)cout <<
"HDET: Is last EVIO block?: " << is_last_evio_block << endl;
315 if(
VERBOSE>3)cout <<
"HDET: Looking for EVIO event at idx="<<idx<<
" (mylen="<<mylen<<
" words)" << endl;
319 if( (idx+mylen) > len ){
320 err_mess <<
"Bad word count while for event in ET event stack!" << endl;
321 err_mess <<
"idx="<<idx<<
" mylen="<<mylen<<
" len="<<len<<endl;
322 err_mess <<
"This indicates a problem either with the DAQ system"<<endl;
323 err_mess <<
"or this parser code! Contact davidl@jlab.org x5567 " <<endl;
331 uint32_t *mybuff = NULL;
332 uint32_t mybuff_len = 0;
334 if(
VERBOSE>3)cout <<
"HDET: Getting buffer from pool" << endl;
338 mybuff_len = b.second;
339 if(mybuff_len < (mylen+1)){
340 if(
VERBOSE>3)cout <<
"HDET: buffer too small ("<<mybuff_len<<
" < "<<(mylen+1)<<
") discarding so new one will be allocated ..." << endl;
349 mybuff_len = mylen+1;
350 if(
VERBOSE>3)cout <<
"HDET: Allocating buffer of length: " << mybuff_len <<
" words" <<endl;
351 mybuff =
new uint32_t[mybuff_len];
353 err_mess <<
"HDET: Failed to allocate buffer of length " << mybuff_len <<
" words";
361 if(
VERBOSE>3 &&
swap_needed && !allow_swap) cout <<
"HDET: Swapping is needed, but user does not allow." << endl;
363 if(
VERBOSE>3)cout <<
"HDET: swapping EVIO buffer ... " <<endl;
364 swap_bank(mybuff, &evio_block[idx], mylen+1);
366 if(
VERBOSE>3)cout <<
"HDET: copying EVIO buffer without swapping ... " <<endl;
367 memcpy(mybuff, &evio_block[idx], (mylen+1)*4);
371 et_buffs.push_back( pair<uint32_t*,uint32_t>(mybuff, mybuff_len) );
379 if(
VERBOSE>3)cout <<
"HDET: EVIO events found so far: " <<
et_buffs.size() << endl;
380 if(is_last_evio_block){
381 if(
VERBOSE>3) cout <<
"HDET: Block flagged as last in ET event. Ignoring last " << (et_len/4 - et_idx) <<
" words" <<endl;
387 if(
VERBOSE>5)cout <<
"HDET: returning ET event to system" << endl;
388 et_event_put(sys_id, att_id, pe);
390 if(
VERBOSE>3) cout <<
"HDET: Found " <<
et_buffs.size() <<
" events in the ET event stack." << endl;
394 if(
VERBOSE>3) cout <<
"HDET: number of et event buffers: " <<
et_buffs.size() << endl;
400 et_buff_pool.push_back(pair<uint32_t*, uint32_t>( buff, buff_len));
419 string swap_str =
"(unknown, swapping bypassed)";
420 uint32_t magic = inbuff[7];
423 case 0xc0da0100: swap_str =
"(without swapping)";
425 case 0x0001dac0: swap_str =
"(after swapping)";
432 for(
int i=0; i<8; i++) buff[i] =
swap32(inbuff[i]);
434 for(
int i=0; i<8; i++) buff[i] =inbuff[i];
438 cout <<
"EVIO Block Header: " << swap_str << endl;
439 cout <<
"------------------------" << endl;
440 cout <<
" Block Length: " <<
HexStr(buff[0]) <<
" (" << buff[0] <<
" words = " << (buff[0]>>(10-2)) <<
" kB)" << endl;
441 cout <<
" Block Number: " <<
HexStr(buff[1]) << endl;
442 cout <<
"Header Length: " <<
HexStr(buff[2]) <<
" (should be 0x00000008)" << endl;
443 cout <<
" Event Count: " <<
HexStr(buff[3]) << endl;
444 cout <<
" Reserved 1: " <<
HexStr(buff[4]) << endl;
445 cout <<
" Bit Info: " <<
HexStr(buff[5]>>8) << endl;
446 cout <<
" Version: " <<
HexStr(buff[5]&0xFF) << endl;
447 cout <<
" Reserved 3: " <<
HexStr(buff[6]) << endl;
448 cout <<
" Magic word: " <<
HexStr(buff[7]) << endl;
457 cout <<
"ET Statistics for " <<
source_name << endl;
458 cout <<
"------------------------" << endl;
459 cout <<
" Net_events: " <<
Net_events << endl;
469 void HDET::DumpBinary(
const uint32_t *iptr,
const uint32_t *iend, uint32_t MaxWords,
const uint32_t *imark)
478 cout <<
"HDET: Dumping binary: istart=" << hex << iptr <<
" iend=" << iend <<
" MaxWords=" << dec << MaxWords << endl;
480 if(iend==NULL && MaxWords==0) MaxWords=1;
481 if(MaxWords==0) MaxWords = (uint32_t)0xffffffff;
484 while(iptr!=iend && Nwords<MaxWords){
487 stringstream line1, line2;
492 line1 << setw(5) << Nwords;
496 for(uint32_t i=0; i<
Ncols; i++, iptr++, Nwords++){
498 if(iptr == iend)
break;
499 if(Nwords>=MaxWords)
break;
501 stringstream iptr_hex;
502 iptr_hex << hex <<
"0x" << *iptr;
504 string mark = (iptr==imark ?
"*":
" ");
506 line1 << setw(12) << iptr_hex.str() << mark;
507 line2 << setw(12) << *iptr << mark;
510 cout << line1.str() << endl;
511 cout << line2.str() << endl;
uint32_t swap_bank(uint32_t *outbuff, uint32_t *inbuff, uint32_t len)
void PrintEVIOBlockHeader(uint32_t *buff)
HDET(string source_name, int ET_STATION_NEVENTS=10, bool ET_STATION_CREATE_BLOCKING=false)
list< pair< uint32_t *, uint32_t > > et_buffs
list< pair< uint32_t *, uint32_t > > et_buff_pool
string HexStr(uint32_t v)
bool read(uint32_t *&buff, uint32_t &buff_len, bool allow_swap)
void DumpBinary(const uint32_t *iptr, const uint32_t *iend, uint32_t MaxWords=0, const uint32_t *imark=NULL)