00001 #ifndef ALGO_SLOW_READOUT_DECODER_CC
00002 #define ALGO_SLOW_READOUT_DECODER_CC
00003
00004 #include "algo_slow_readout_decoder.hh"
00005
00006
00007 algo_slow_readout_decoder::algo_slow_readout_decoder() :
00008 algo_base()
00009 {
00010 _name="algo_slow_readout_decoder";
00011 _last_word=PMT::INVALID_WORD;
00012 _print_adcval=false;
00013 _continue_to_next_event=false;
00014 _process=READ_HEADER;
00015 _event_data=0;
00016 set_verbosity(MSG::NORMAL);
00017
00018 reset();
00019
00020 }
00021
00022 void algo_slow_readout_decoder::reset(){
00023
00024 init_ch_info();
00025 init_event_info();
00026 _event_data=0;
00027
00028 }
00029
00030 void algo_slow_readout_decoder::init_ch_info(){
00031
00032 _channel_header_count=0;
00033 _ch_data.clear_data();
00034
00035 }
00036
00037 void algo_slow_readout_decoder::init_event_info(){
00038
00039 _event_header_count=0;
00040 _last_channel_number=PMT::INVALID_CH;
00041 _last_disc_id=PMT::DISC_MAX;
00042 _beam_event=false;
00043 _beam_ref_sample=PMT::INVALID_WORD;
00044 _beam_ref_nwords=PMT::INVALID_WORD;
00045 _beam_ref_frame=PMT::INVALID_WORD;
00046 _process=READ_HEADER;
00047 algo_base::init_checker_info();
00048
00049 }
00050
00051 void algo_slow_readout_decoder::print_adc_values()
00052 {
00053 sprintf(_buf,"Printing ADC values for Event=%d Channel=%d",
00054 _event_data->event_id(),
00055 _ch_data.channel_number());
00056 Message::send(MSG::INFO,_buf);
00057 size_t ctr=0;
00058 std::string line("");
00059 for(pmt_waveform::iterator iter(_ch_data.begin());
00060 iter!=_ch_data.end();
00061 ++iter)
00062 {
00063 sprintf(_buf," %-6d",(*iter));
00064 line+=_buf;
00065 ctr++;
00066 if(ctr%8==0) {
00067 Message::send(MSG::INFO,line.c_str());
00068 line="";
00069 }
00070 }
00071 }
00072
00073 bool algo_slow_readout_decoder::process_word(PMT::word_t word) {
00074
00075
00076
00077
00078
00079
00080
00081 if(_bt_mode){
00082
00083
00084 if(!_bt_nwords_filled)
00085 _bt_nwords_filled = (_bt_nwords == _bt_words.size());
00086
00087
00088 if(_bt_nwords_filled)
00089 _bt_words.pop_front();
00090
00091
00092 _bt_words.push_back(word);
00093
00094 }
00095
00096
00097 if(!_event_data) {
00098 _event_data=(pmt_wf_collection*)(_storage->get_data(DATA_STRUCT::PMT_WF_COLLECTION));
00099 if(!_event_data) {
00100 Message::send(MSG::ERROR,__FUNCTION__,"Could not retrieve pmt_wf_collection poitner!");
00101 return false;
00102 }
00103 }
00104
00105 bool status=true;
00106 switch(_process){
00107 case READ_HEADER:
00108
00109
00110
00111 status=process_header(word);
00112 break;
00113 case READ_CHANNEL:
00114
00115
00116
00117
00118 PMT::word_t word_class=get_word_class(word);
00119 if(word_class==PMT::FEM_HEADER ||
00120 word_class==PMT::EVENT_HEADER) {
00121 sprintf(_buf,"Found an event header (%x) while looping over channel data (last word: %x)!",
00122 word,_last_word);
00123 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00124
00125 if(_debug_mode) {
00126
00127
00128 status = check_event_quality();
00129
00130 init_event_info();
00131
00132 if(!status){
00133 sprintf(_buf,"DEBUG mode-> continue ... but Skip saving event: %d ",_event_data->event_id());
00134 Message::send(MSG::WARNING,__FUNCTION__,_buf);
00135 }else{
00136 sprintf(_buf,"DEBUG mode-> continue ... Good checksum -> stored previous event: %d",_event_data->event_id());
00137 Message::send(MSG::WARNING,__FUNCTION__,_buf);
00138 _storage->next_event();
00139 }
00140 status=process_header(word);
00141
00142
00143 status=true;
00144 }
00145 else
00146 status=false;
00147 break;
00148 }
00149
00150
00151
00152 PMT::word_t first_word = word & 0xffff;
00153 PMT::word_t second_word = word >> 16;
00154 status = process_ch_word(first_word,_last_word);
00155 if(status && _process==READ_CHANNEL)
00156 status=process_ch_word(second_word,_last_word);
00157 else if(!status){
00158
00159
00160
00161 if(_debug_mode) {
00162 status=true;
00163 _continue_to_next_event=true;
00164 _process=READ_HEADER;
00165 }
00166 }
00167 break;
00168 }
00169 return status;
00170 }
00171
00172 bool algo_slow_readout_decoder::process_header(const PMT::word_t word) {
00173
00174 bool status=true;
00175
00176
00177
00178 PMT::PMT_WORD word_class=get_word_class(word);
00179 if(_verbosity[MSG::DEBUG]){
00180 sprintf(_buf,"Processing Header: %x",word);
00181 Message::send(MSG::DEBUG,__FUNCTION__,_buf);
00182 }
00183 switch(word_class){
00184
00185
00186 case PMT::UNDEFINED_WORD:
00187 sprintf(_buf,"Skipping undefined word while searching an event header: %x",word);
00188 Message::send(MSG::WARNING,__FUNCTION__,_buf);
00189 break;
00190
00191
00192 case PMT::FEM_FIRST_WORD:
00193 case PMT::CHANNEL_HEADER:
00194 case PMT::CHANNEL_WORD:
00195 case PMT::CHANNEL_LAST_WORD:
00196 case PMT::FEM_LAST_WORD:
00197 case PMT::EVENT_LAST_WORD:
00198 if(!_continue_to_next_event){
00199 sprintf(_buf,"Encountered unexpected word while an event header search: %x (word type=%d)",
00200 word,word_class);
00201 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00202 if(!_debug_mode)
00203 status=false;
00204 }else if(_verbosity[MSG::WARNING]){
00205 sprintf(_buf,"Skipping non-header till next event (debug mode): %x",word);
00206 Message::send(MSG::WARNING,__FUNCTION__,_buf);
00207 }
00208 break;
00209
00210
00211 case PMT::EVENT_HEADER:
00212
00213 if(_continue_to_next_event) _continue_to_next_event=false;
00214 break;
00215 case PMT::FEM_HEADER:
00216 if(_continue_to_next_event) _continue_to_next_event=false;
00217
00218
00219
00220 if(get_word_class(word>>16)!=PMT::FEM_HEADER) {
00221 sprintf(_buf,"Found an odd event header word: %x",word);
00222 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00223 status=false;
00224 break;
00225 }
00226
00227 if (_event_header_count<FEM_HEADER_COUNT) {
00228
00229
00230 _event_header_words[_event_header_count]=word;
00231 _event_header_count++;
00232
00233 if(_event_header_count==FEM_HEADER_COUNT) {
00234
00235
00236 if(decode_event_header(_event_header_words)) {
00237 _event_header_count=0;
00238 _process=READ_CHANNEL;
00239 status=true;
00240 }
00241 else
00242 status=false;
00243 }
00244 }
00245 else {
00246
00247 Message::send(MSG::ERROR,__FUNCTION__,
00248 "Logic error: event header word counter not working!");
00249 status=false;
00250 }
00251 break;
00252 }
00253 _last_word=word;
00254
00255 return status;
00256 }
00257
00258 bool algo_slow_readout_decoder::decode_event_header(const PMT::word_t *event_header){
00259
00260 bool status=true;
00261
00262
00263
00264
00265
00266 if(!( event_header[0] & 0xffff))
00267 Message::send(MSG::ERROR,"Unexpected first word in event headers!");
00268
00269 if(!status) return status;
00270
00271
00272
00273 _event_data->set_module_address(( event_header[0]>>16 & 0xfff ) & 0x1f);
00274
00275
00276 _event_data->set_module_id((event_header[0]>>16 & 0xfff)>>5 & 0x7f);
00277
00278
00279
00280
00281
00282 _event_data->set_nwords( (( (event_header[1]>>16) & 0xfff ) + ((event_header[1] & 0xfff)<<12)) );
00283
00284
00285
00286 _event_data->set_event_id( (( (event_header[2]>>16) & 0xfff ) + ((event_header[2] & 0xfff)<<12)));
00287
00288
00289
00290 _event_data->set_event_frame_id((( (event_header[3]>>16) & 0xfff ) + ((event_header[3] & 0xfff)<<12)));
00291
00292
00293 _event_data->set_checksum( (( (event_header[4]>>16) & 0xfff ) + ((event_header[4] & 0xfff)<<12)) );
00294
00295
00296 #ifdef INCLUDE_EXTRA_HEADER
00297 _event_data->set_trigger_frame_id( (((event_header[5]>>16) & 0xfff)>>4 & 0xf) +
00298 (((_event_data->event_frame_id())>>4)<<4) );
00299
00300 _event_data->set_trigger_frame_id( round_diff(_event_data->event_frame_id(),
00301 _event_data->trigger_frame_id(),
00302 0x7));
00303 _event_data->set_trigger_timeslice( (((event_header[5]>>16) & 0xf)<<8) + (event_header[5] & 0xff) );
00304 #endif
00305
00306
00307 if(_verbosity[MSG::INFO])
00308 {
00309 sprintf(_buf,"Module %d (ID=%d)", _event_data->module_address(), _event_data->module_id());
00310 Message::send(MSG::INFO,_buf);
00311 sprintf(_buf,"Event ID %d",_event_data->event_id());
00312 Message::send(MSG::INFO,_buf);
00313 sprintf(_buf,"Frame ID %d",_event_data->event_frame_id());
00314 Message::send(MSG::INFO,_buf);
00315 sprintf(_buf,"Number of Words = %d",_event_data->nwords());
00316 Message::send(MSG::INFO,_buf);
00317 sprintf(_buf,"Checksum = %x", _event_data->checksum());
00318 Message::send(MSG::INFO,_buf);
00319 sprintf(_buf,"Trigger Frame %d",_event_data->trigger_frame_id());
00320 Message::send(MSG::INFO,_buf);
00321 sprintf(_buf,"Trigger Sample %d",_event_data->trigger_timeslice());
00322 Message::send(MSG::INFO,_buf);
00323 }
00324
00325 _checksum=_event_data->checksum();
00326 _nwords=_event_data->nwords();
00327
00328 return status;
00329 }
00330
00331 bool algo_slow_readout_decoder::process_ch_word(const PMT::word_t word,
00332 PMT::word_t &last_word){
00333
00334 PMT::PMT_WORD last_word_class=get_word_class(last_word);
00335 PMT::PMT_WORD word_class=get_word_class(word);
00336
00337
00338 if(_verbosity[MSG::DEBUG]){
00339 sprintf(_buf,"Processing: %x ... Previous: %x ... Remaining: %d words, checksum=%d",
00340 word,last_word,_nwords,_checksum);
00341 Message::send(MSG::DEBUG,__FUNCTION__,_buf);
00342 }
00343
00344 if(word_class==PMT::UNDEFINED_WORD){
00345 sprintf(_buf,"Found an undefined word: %x ",word);
00346 if(last_word_class!=PMT::CHANNEL_LAST_WORD &&
00347 last_word_class!=PMT::FEM_LAST_WORD &&
00348 last_word_class!=PMT::EVENT_LAST_WORD)
00349 Message::send(MSG::WARNING,__FUNCTION__,_buf);
00350 else{
00351 if(_verbosity[MSG::INFO])
00352 Message::send(MSG::INFO,__FUNCTION__,_buf);
00353 }
00354 return true;
00355 }
00356
00357 bool status = decode_ch_word(word,last_word_class);
00358
00359 if(!status){
00360
00361 sprintf(_buf,"Status failure while analyzing: %x ... (previous word: %x)",word,last_word);
00362 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00363 }else{
00364
00365 if(word_class==PMT::EVENT_LAST_WORD){
00366
00367 if(_verbosity[MSG::INFO]){
00368 sprintf(_buf,"Found the last event word: %x",word);
00369 Message::send(MSG::INFO,__FUNCTION__,_buf);
00370 }
00371
00372 status = check_event_quality();
00373 if(status)
00374 _storage->next_event();
00375 else if(_debug_mode){
00376 sprintf(_buf,"DEBUG mode-> continue ... but Skip saving event: %d ",_event_data->event_id());
00377 Message::send(MSG::WARNING,__FUNCTION__,_buf);
00378 status=true;
00379 }
00380 init_event_info();
00381 }else if(word_class!=PMT::FEM_LAST_WORD){
00382 _nwords-=1;
00383 _checksum-=word;
00384 }
00385
00386 }
00387
00388 last_word=word;
00389 return status;
00390 }
00391
00392
00393 PMT::word_t algo_slow_readout_decoder::round_diff(PMT::word_t ref_id,
00394 PMT::word_t subject_id,
00395 PMT::word_t diff) const
00396 {
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 if( (subject_id > ref_id) && ((subject_id-ref_id) >= diff) )
00411 return subject_id - (diff+1);
00412 else if( (ref_id > subject_id) && ((ref_id-subject_id) >= diff) )
00413 return subject_id + (diff+1);
00414 else
00415 return subject_id;
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 }
00431
00432 void algo_slow_readout_decoder::apply_beamgate_correction() {
00433
00434 for(std::vector<pmt_waveform>::iterator iter(_event_data->begin());
00435 iter!=_event_data->end();
00436 ++iter){
00437
00438 if( (*iter).size()>BEAM_NWORDS ) {
00439
00440
00441
00442
00443 if( (*iter).timeslice() < _beam_ref_sample && (*iter).channel_frame_id() == _beam_ref_frame )
00444
00445
00446 (*iter).set_timeslice( _beam_ref_sample + _beam_ref_nwords - (*iter).size() );
00447
00448
00449
00450
00451 if( (*iter).channel_frame_id() < _beam_ref_frame ) {
00452
00453
00454 (*iter).set_timeslice( _beam_ref_sample + _beam_ref_nwords - (*iter).size() );
00455
00456
00457 if((*iter).timeslice() >= FRAME_WIDTH) {
00458 (*iter).set_timeslice((*iter).timeslice() - FRAME_WIDTH);
00459 (*iter).set_channel_frame_id((*iter).channel_frame_id() + 1);
00460 }
00461 }
00462
00463
00464
00465
00466 }
00467 }
00468
00469 }
00470
00471 bool algo_slow_readout_decoder::check_event_quality() {
00472
00473 if(_verbosity[MSG::INFO]){
00474 sprintf(_buf,"Exiting ch-loop in event: %d",_event_data->event_id());
00475 Message::send(MSG::INFO,__FUNCTION__,_buf);
00476 sprintf(_buf,"Number of channels read : %zd",_event_data->size());
00477 Message::send(MSG::INFO,__FUNCTION__,_buf);
00478 }
00479
00480 bool status=true;
00481
00482 if(_nwords){
00483 sprintf(_buf,"Number words expected - counted = %d",_nwords);
00484 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00485 status=false;
00486 }
00487 if(_checksum & 0xffffff){
00488 sprintf(_buf,"Checksum expected - recieved = %d",_checksum);
00489 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00490 status=false;
00491 }
00492
00493 return status;
00494 }
00495
00496
00497 bool algo_slow_readout_decoder::decode_ch_word(const PMT::word_t word,
00498 const PMT::PMT_WORD last_word_class) {
00499
00500 PMT::PMT_WORD word_class = get_word_class(word);
00501 bool status=true;
00502
00503 if(_verbosity[MSG::DEBUG]){
00504 sprintf(_buf,"Decoding word: %x ... last word class: %d",word,last_word_class);
00505 Message::send(MSG::DEBUG,__FUNCTION__,_buf);
00506 }
00507
00508 switch(word_class){
00509
00510 case PMT::EVENT_HEADER:
00511 case PMT::FEM_HEADER:
00512
00513
00514
00515 sprintf(_buf,"Found an event header (%x) while processing channel data word!",word);
00516 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00517 Message::send(MSG::ERROR,__FUNCTION__,"Terminate channel data readout loop.");
00518 status=false;
00519 break;
00520
00521 case PMT::UNDEFINED_WORD:
00522
00523
00524
00525 sprintf(_buf,"Logic error: should not find an undefined word (%x) here.",word);
00526 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00527 Message::send(MSG::ERROR,__FUNCTION__,"Terminate channel data readout loop.");
00528 status=false;
00529 break;
00530
00531 case PMT::FEM_FIRST_WORD:
00532
00533
00534 if(last_word_class!=PMT::FEM_HEADER){
00535 Message::send(MSG::ERROR,__FUNCTION__,
00536 "Found the first word while the previous one was not event header!");
00537 status=false;
00538 }
00539 break;
00540
00541 case PMT::CHANNEL_HEADER:
00542
00543
00544 if(last_word_class!=PMT::FEM_FIRST_WORD && last_word_class!=PMT::CHANNEL_LAST_WORD) {
00545 Message::send(MSG::ERROR,__FUNCTION__,
00546 "Found the channel header in wrong place: previous word is missing!");
00547 status=false;
00548 }else{
00549
00550 init_ch_info();
00551 _ch_data.set_channel_number( word & 0x3f );
00552 _ch_data.set_disc_id((PMT::DISCRIMINATOR)((word & 0xfff)>>9));
00553 }
00554 break;
00555
00556 case PMT::CHANNEL_WORD:
00557 case PMT::CHANNEL_LAST_WORD:
00558
00559
00560
00561 if(last_word_class!=PMT::CHANNEL_HEADER &&
00562 last_word_class!=PMT::CHANNEL_WORD &&
00563 last_word_class!=PMT::CHANNEL_LAST_WORD ) {
00564
00565 sprintf(_buf,"Missing a channel header word! Current word: %x ... Last word class %d",word,last_word_class);
00566 Message::send(MSG::ERROR,__FUNCTION__,_buf);
00567
00568 status=false;
00569 }else{
00570
00571 if(last_word_class==PMT::CHANNEL_LAST_WORD){
00572
00573
00574 init_ch_info();
00575 _ch_data.set_channel_number(_last_channel_number);
00576 _ch_data.set_disc_id(_last_disc_id);
00577 if(_verbosity[MSG::NORMAL])
00578 Message::send(MSG::NORMAL,__FUNCTION__,
00579 Form("Found consecutively readout data arrays @ event %d (missing channel very first header)!",
00580 _event_data->event_id())
00581 );
00582 }
00583
00584
00585
00586
00587 if(_channel_header_count==CHANNEL_HEADER_COUNT ) {
00588
00589 if(word_class!=PMT::CHANNEL_LAST_WORD)
00590 _ch_data.push_back(word & 0xfff);
00591 }else if(last_word_class==PMT::CHANNEL_HEADER ) {
00592
00593
00594
00595 _ch_data.set_timeslice( (word & 0x1f)<<12 );
00596
00597
00598 _ch_data.set_channel_frame_id( ((word & 0xff)>>5) +
00599 (((_event_data->event_frame_id())>>3)<<3) );
00600
00601
00602 _ch_data.set_channel_frame_id(round_diff(_event_data->event_frame_id(),
00603 _ch_data.channel_frame_id(),
00604 0x7));
00605 _channel_header_count++;
00606 }else if(last_word_class==PMT::CHANNEL_WORD ) {
00607
00608 _ch_data.set_timeslice(_ch_data.timeslice() + (word & 0xfff));
00609 _channel_header_count++;
00610
00611 if(_verbosity[MSG::INFO]){
00612 sprintf(_buf,"Read-in headers for Ch. %-3d!",_ch_data.channel_number());
00613 Message::send(MSG::INFO,_buf);
00614 }
00615 }
00616
00617
00618 if(word_class==PMT::CHANNEL_LAST_WORD){
00619 if(_verbosity[MSG::INFO]){
00620 sprintf(_buf,"Encountered the last word (%x) for channel %d",word,_ch_data.channel_number());
00621 Message::send(MSG::INFO,_buf);
00622 sprintf(_buf,"Event frame : %d",_event_data->event_frame_id());
00623 Message::send(MSG::INFO,_buf);
00624 sprintf(_buf,"PMT frame : %d",_ch_data.channel_frame_id());
00625 Message::send(MSG::INFO,_buf);
00626 sprintf(_buf,"Disc. ID : %d",_ch_data.disc_id());
00627 Message::send(MSG::INFO,_buf);
00628 sprintf(_buf,"Start Time : %d",_ch_data.timeslice());
00629 Message::send(MSG::INFO,_buf);
00630 sprintf(_buf,"# ADC sample : %zd",_ch_data.size());
00631 Message::send(MSG::INFO,_buf);
00632 }
00633 if( _print_adcval )
00634 print_adc_values();
00635 store_ch_data();
00636 init_ch_info();
00637 }
00638 }
00639 break;
00640 case PMT::FEM_LAST_WORD:
00641 case PMT::EVENT_LAST_WORD:
00642 break;
00643 }
00644 return status;
00645
00646 }
00647
00648 void algo_slow_readout_decoder::store_ch_data(){
00649
00650 if(_ch_data.channel_number() == BEAM_REF_CHANNEL) {
00651 _beam_event = (_beam_event || _ch_data.size() > BEAM_NWORDS);
00652 if(_beam_event){
00653 _beam_ref_nwords=(PMT::word_t)(_ch_data.size());
00654 _beam_ref_sample=_ch_data.timeslice();
00655 _beam_ref_frame=_ch_data.channel_frame_id();
00656 }
00657 }
00658 _event_data->push_back(_ch_data);
00659
00660
00661
00662
00663
00664 _last_channel_number=_ch_data.channel_number();
00665 _last_disc_id=_ch_data.disc_id();
00666
00667 }
00668
00669 #endif