00001 #ifndef ALGO_FEM_DECODER_BASE
00002 #define ALGO_FEM_DECODER_BASE
00003
00004 #include "algo_fem_decoder_base.hh"
00005
00006
00007 algo_fem_decoder_base::algo_fem_decoder_base()
00008 : algo_base()
00009
00010 {
00011 _name = "algo_fem_decoder_base";
00012 reset();
00013 }
00014
00015
00016
00017 void algo_fem_decoder_base::reset() {
00018
00019
00020 algo_base::reset();
00021
00022 _last_word = PMT::INVALID_WORD;
00023
00024 _event_header_count = 0;
00025
00026 _search_for_next_event = false;
00027
00028 for(size_t i=0; i< FEM_HEADER_COUNT; i++)
00029
00030 _event_header_words[i] = 0;
00031
00032 }
00033
00034
00035
00036 bool algo_fem_decoder_base::process_word(PMT::word_t word)
00037
00038 {
00039
00040
00041
00042
00043
00044
00045
00046 if(_bt_mode){
00047
00048
00049 if(!_bt_nwords_filled)
00050 _bt_nwords_filled = (_bt_nwords == _bt_words.size());
00051
00052
00053 if(_bt_nwords_filled)
00054 _bt_words.pop_front();
00055
00056
00057 _bt_words.push_back(word);
00058
00059 }
00060
00061 bool status=true;
00062 PMT::word_t word_class=get_word_class(word);
00063 PMT::word_t last_word_class=get_word_class(_last_word);
00064
00065
00066
00067 if( _search_for_next_event &&
00068 word_class == PMT::FEM_HEADER &&
00069 last_word_class != PMT::FEM_HEADER )
00070
00071 _search_for_next_event = false;
00072
00073
00074 if( _search_for_next_event ) {
00075
00076 if(_verbosity[MSG::INFO])
00077
00078 Message::send(MSG::INFO,__FUNCTION__,
00079 Form("Skipping a word (%x, previous=%x) to the next event..",word,_last_word));
00080
00081 _last_word = PMT::INVALID_WORD;
00082
00083 return true;
00084 }
00085
00086 switch(word_class){
00087
00088 case PMT::EVENT_HEADER:
00089
00090
00091 status = process_event_header(word,_last_word);
00092 break;
00093
00094 case PMT::FEM_HEADER:
00095
00096
00097
00098
00099
00100
00101 status = process_fem_header(word,_last_word);
00102 break;
00103
00104 case PMT::FEM_FIRST_WORD:
00105 case PMT::CHANNEL_HEADER:
00106 case PMT::CHANNEL_WORD:
00107 case PMT::CHANNEL_LAST_WORD:
00108 case PMT::FEM_LAST_WORD:
00109 {
00110
00111
00112
00113
00114 PMT::word_t first_word = (word & 0xffff);
00115 PMT::word_t second_word = (word >> 16);
00116
00117 if(status) status = process_ch_word(first_word,_last_word);
00118
00119
00120 if(status){
00121
00122 switch(get_word_class(second_word)){
00123 case PMT::FEM_FIRST_WORD:
00124 case PMT::CHANNEL_HEADER:
00125 case PMT::CHANNEL_WORD:
00126 case PMT::CHANNEL_LAST_WORD:
00127 status = process_ch_word(second_word,_last_word);
00128 break;
00129 case PMT::FEM_LAST_WORD:
00130 status = process_fem_last_word(second_word,_last_word);
00131 break;
00132 default:
00133 status = false;
00134 Message::send(MSG::ERROR,__FUNCTION__,
00135 Form("Unexpected word (%x) while processing channel data (previous=%x)",second_word,first_word));
00136 }
00137
00138 }
00139 break;
00140 }
00141 case PMT::EVENT_LAST_WORD:
00142
00143 status = process_event_last_word(word,_last_word);
00144 break;
00145
00146 case PMT::UNDEFINED_WORD:
00147
00148
00149 if(word != 0x0 || (last_word_class != PMT::EVENT_LAST_WORD && last_word_class != PMT::FEM_LAST_WORD) ) {
00150
00151 Message::send(MSG::ERROR,__FUNCTION__,
00152 Form("Undefined word: %x (previous = %x)",word,_last_word));
00153
00154 status = false;
00155 }else if(_verbosity[MSG::INFO]){
00156
00157
00158 Message::send(MSG::INFO,__FUNCTION__,
00159 Form("Padding of undefined word (tolerated): %x (previous=%x)",word,_last_word));
00160 }
00161 break;
00162 }
00163
00164 if(!status){
00165
00166 backtrace();
00167
00168 if(_debug_mode) {
00169
00170 if(_header_info.event_id>0)
00171
00172 Message::send(MSG::WARNING,__FUNCTION__,Form("Failed decoding event %d ...",_header_info.event_id));
00173
00174 Message::send(MSG::WARNING,__FUNCTION__,"DEBUG MODE => Continue to the next event...\n");
00175
00176 _search_for_next_event = true;
00177 clear_event();
00178 }
00179 }
00180
00181 return status;
00182 }
00183
00184
00185 bool algo_fem_decoder_base::process_fem_header(const PMT::word_t word, PMT::word_t &last_word) {
00186
00187
00188 bool status=true;
00189
00190
00191
00192 PMT::PMT_WORD word_class=get_word_class(word);
00193 if(_verbosity[MSG::DEBUG]){
00194 sprintf(_buf,"Processing Header: %x",word);
00195 Message::send(MSG::DEBUG,__FUNCTION__,_buf);
00196 }
00197
00198
00199 if( word_class != PMT::FEM_HEADER) {
00200
00201 Message::send(MSG::ERROR,__FUNCTION__,
00202 Form("Encountered unexpected word while an event header search: %x (word type=%d)",
00203 word,word_class) );
00204 status = false;
00205
00206 }else if(get_word_class(word>>16)!=PMT::FEM_HEADER) {
00207
00208
00209
00210
00211 Message::send(MSG::ERROR,__FUNCTION__,Form("Found an odd event header word: %x",word));
00212
00213 status = false;
00214
00215 }
00216
00217 if(status) {
00218
00219
00220
00221
00222 switch(get_word_class(last_word)){
00223 case PMT::EVENT_HEADER:
00224 case PMT::FEM_HEADER:
00225 case PMT::FEM_LAST_WORD:
00226
00227 break;
00228 case PMT::FEM_FIRST_WORD:
00229 case PMT::CHANNEL_HEADER:
00230 case PMT::CHANNEL_WORD:
00231 case PMT::UNDEFINED_WORD:
00232 case PMT::EVENT_LAST_WORD:
00233
00234 Message::send(MSG::ERROR,__FUNCTION__,
00235 Form("Unexpected word while FEM_HEADER processing: %x (previous word=%x)",word,last_word));
00236 status = false;
00237 break;
00238 case PMT::CHANNEL_LAST_WORD:
00239
00240 status = store_event();
00241 if(_debug_mode) {
00242
00243
00244
00245 Message::send(MSG::WARNING,__FUNCTION__,"DEBUG MODE => Continue to the next event...\n");
00246
00247 clear_event();
00248
00249 status = true;
00250 }
00251 break;
00252 }
00253
00254 if(status){
00255
00256
00257 if (_event_header_count<FEM_HEADER_COUNT) {
00258
00259
00260 _event_header_words[_event_header_count]=word;
00261 _event_header_count++;
00262
00263
00264 if(_event_header_count==FEM_HEADER_COUNT) {
00265
00266
00267 status = decode_fem_header(_event_header_words);
00268
00269 }
00270 }else{
00271
00272
00273 Message::send(MSG::ERROR,__FUNCTION__,
00274 Form("Logic error: event header word counter not working! (%zu/%zu)",
00275 _event_header_count,FEM_HEADER_COUNT));
00276 status=false;
00277 }
00278 }
00279 }
00280
00281 if(!status){
00282
00283 Message::send(MSG::ERROR,__FUNCTION__,
00284 Form("Failed processing the word %x (last word %x) as an event header!",word,last_word));
00285
00286 }
00287
00288 last_word = word;
00289 return status;
00290
00291 }
00292
00293
00294
00295 bool algo_fem_decoder_base::decode_fem_header(const PMT::word_t *event_header){
00296
00297
00298 bool status=true;
00299
00300
00301
00302
00303
00304 if(!( event_header[0] & 0xffff))
00305 Message::send(MSG::ERROR,"Unexpected first word in event headers!");
00306
00307 if(!status) return status;
00308
00309
00310 _header_info.clear_event();
00311
00312
00313 _header_info.module_address = ( (event_header[0]>>16 & 0xfff) & 0x1f);
00314
00315
00316 _header_info.module_id = ( (event_header[0]>>16 & 0xfff)>>5 & 0x7f);
00317
00318
00319
00320
00321
00322 _header_info.nwords = ( (((event_header[1]>>16) & 0xfff) + ((event_header[1] & 0xfff)<<12)));
00323
00324
00325
00326 _header_info.event_id = ( (((event_header[2]>>16) & 0xfff) + ((event_header[2] & 0xfff)<<12)));
00327
00328
00329
00330 _header_info.event_frame_id = ( (((event_header[3]>>16) & 0xfff) + ((event_header[3] & 0xfff)<<12)));
00331
00332
00333 _header_info.checksum = ( (((event_header[4]>>16) & 0xfff) + ((event_header[4] & 0xfff)<<12)));
00334
00335
00336 #ifdef INCLUDE_EXTRA_HEADER
00337 _header_info.trigger_frame_id = ( ((event_header[5] & 0xfff)>>4 & 0xf) +
00338 (((_header_info.event_frame_id)>>4)<<4));
00339
00340
00341 _header_info.trigger_frame_id = round_diff(_header_info.event_frame_id, _header_info.trigger_frame_id, 0x7);
00342
00343 _header_info.trigger_timeslice = ((((event_header[5]>>16) & 0xf)<<8) + (event_header[5] & 0xff));
00344
00345 #endif
00346
00347
00348 if(_verbosity[MSG::INFO])
00349 {
00350 Message::send(MSG::INFO,Form("Module %d (ID=%d)", _header_info.module_address, _header_info.module_id));
00351 Message::send(MSG::INFO,Form("Event ID %d",_header_info.event_id));
00352 Message::send(MSG::INFO,Form("Frame ID %d",_header_info.event_frame_id));
00353 Message::send(MSG::INFO,Form("Number of Words = %d",_header_info.nwords));
00354 Message::send(MSG::INFO,Form("Checksum = %x", _header_info.checksum));
00355 Message::send(MSG::INFO,Form("Trigger Frame %d",_header_info.trigger_frame_id));
00356 Message::send(MSG::INFO,Form("Trigger Sample %d",_header_info.trigger_timeslice));
00357 }
00358
00359 _checksum=0;
00360
00361 _nwords=0;
00362
00363 return status;
00364 }
00365
00366
00367
00368 PMT::word_t algo_fem_decoder_base::round_diff(PMT::word_t ref_id,
00369 PMT::word_t subject_id,
00370 PMT::word_t diff) const
00371
00372 {
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 if( (subject_id > ref_id) && ((subject_id-ref_id) >= diff) )
00387 return subject_id - (diff+1);
00388 else if( (ref_id > subject_id) && ((ref_id-subject_id) >= diff) )
00389 return subject_id + (diff+1);
00390 else
00391 return subject_id;
00392
00393 }
00394
00395
00396 bool algo_fem_decoder_base::add_huffman_adc(std::vector<UShort_t> &wf, size_t zero_count)
00397 {
00398
00399
00400 bool status = true;
00401
00402 switch(zero_count){
00403
00404 case 0:
00405 wf.push_back( (*(wf.rbegin())) ); break;
00406
00407 case 1:
00408 wf.push_back( (*(wf.rbegin())) -1 ); break;
00409
00410 case 2:
00411 wf.push_back( (*(wf.rbegin())) +1 ); break;
00412
00413 case 3:
00414 wf.push_back( (*(wf.rbegin())) -2 ); break;
00415
00416 case 4:
00417 wf.push_back( (*(wf.rbegin())) +2 ); break;
00418
00419 case 5:
00420 wf.push_back( (*(wf.rbegin())) -3 ); break;
00421
00422 case 6:
00423 wf.push_back( (*(wf.rbegin())) +3 ); break;
00424
00425 default:
00426
00427 std::cout<<zero_count<<std::endl;
00428
00429 status = false;
00430 }
00431
00432 return status;
00433
00434 }
00435
00436
00437 #endif