00001 #ifndef ALGO_TPC_HUFFMAN_CC
00002 #define ALGO_TPC_HUFFMAN_CC
00003
00004 #include "algo_tpc_huffman.hh"
00005
00006 algo_tpc_huffman::algo_tpc_huffman() : algo_tpc_xmit()
00007 {
00008 _name = "algo_tpc_huffman";
00009 reset();
00010 }
00011
00012 void algo_tpc_huffman::reset() {
00013
00014 algo_tpc_xmit::reset();
00015
00016 }
00017
00018 void algo_tpc_huffman::clear_event() {
00019
00020 _search_header = false;
00021
00022 algo_tpc_xmit::clear_event();
00023
00024 }
00025
00026 bool algo_tpc_huffman::process_word(const PMT::word_t word) {
00027
00028
00029 if(_bt_mode){
00030
00031
00032 if(!_bt_nwords_filled)
00033 _bt_nwords_filled = (_bt_nwords == _bt_words.size());
00034
00035
00036 if(_bt_nwords_filled)
00037 _bt_words.pop_front();
00038
00039
00040 _bt_words.push_back(word);
00041
00042 }
00043
00044 if(word==0x0)
00045
00046 return true;
00047
00048 bool status = true;
00049 PMT::word_t word_class = get_word_class(word);
00050 PMT::word_t last_word_class = get_word_class(_last_word);
00051
00052 if( _search_for_next_event ) {
00053
00054 if( !(word_class == PMT::EVENT_HEADER &&
00055 last_word_class == PMT::EVENT_LAST_WORD ) ) {
00056
00057 _last_word = word;
00058 return status;
00059 }
00060
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 switch(word_class){
00074
00075 case PMT::EVENT_HEADER:
00076
00077 if( (last_word_class == PMT::EVENT_LAST_WORD && !(_header_info.nwords)) || !(_event_data)) {
00078
00079 _search_for_next_event = false;
00080
00081 status = process_event_header(word,_last_word);
00082 }
00083 else{
00084
00085 PMT::word_t first_word = (word & 0xffff);
00086 PMT::word_t second_word = (word >> 16);
00087
00088 status = process_ch_word(first_word,_last_word);
00089
00090 if(status) status = process_ch_word(second_word,_last_word);
00091
00092 }
00093
00094 break;
00095
00096 case PMT::FEM_HEADER:
00097
00098 if(_nwords && _nwords == _header_info.nwords){
00099
00100 _nwords++;
00101 status = store_event();
00102
00103 }
00104
00105 if(status){
00106
00107 if(!(_header_info.nwords))
00108
00109 status = process_fem_header(word,_last_word);
00110
00111 else{
00112
00113 PMT::word_t first_word = (word & 0xffff);
00114 PMT::word_t second_word = (word >> 16);
00115
00116 status = process_ch_word(first_word,_last_word);
00117
00118 if(status) status = process_ch_word(second_word,_last_word);
00119
00120 }
00121 }
00122
00123 break;
00124
00125 case PMT::EVENT_LAST_WORD:
00126
00127
00128
00129 status = process_event_last_word(word,_last_word);
00130 break;
00131
00132
00133 default:
00134
00135 PMT::word_t first_word = (word & 0xffff);
00136 PMT::word_t second_word = (word >> 16);
00137
00138 status = process_ch_word(first_word,_last_word);
00139
00140 if(status) status = process_ch_word(second_word,_last_word);
00141
00142 }
00143
00144 if(!status){
00145
00146 if(_bt_mode)
00147 backtrace();
00148
00149 clear_event();
00150
00151 if(_debug_mode){
00152
00153 Message::send(MSG::WARNING,__FUNCTION__,"DEBUG MODE => Continue to next event...");
00154
00155 _search_for_next_event = true;
00156
00157 }
00158
00159 }
00160
00161 return status;
00162 }
00163
00164 bool algo_tpc_huffman::process_event_header(const PMT::word_t word,
00165 PMT::word_t &last_word)
00166 {
00167 bool status = true;
00168
00169 if(!_event_data)
00170
00171 _event_data = (tpc_wf_collection*)(_storage->get_data(DATA_STRUCT::TPC_WF_COLLECTION));
00172
00173 else if(get_word_class(last_word)!=PMT::EVENT_LAST_WORD){
00174
00175 Message::send(MSG::ERROR,__FUNCTION__,
00176 Form("Unexpected event header (%x) with the previous word %x!",word,last_word));
00177
00178 status = false;
00179
00180 }
00181
00182 last_word = word;
00183
00184 return status;
00185 }
00186
00187 bool algo_tpc_huffman::process_fem_header(const PMT::word_t word,
00188 PMT::word_t &last_word)
00189 {
00190 bool status = true;
00191
00192
00193
00194
00195 PMT::word_t last_word_class = get_word_class(last_word);
00196
00197 if(last_word_class != PMT::EVENT_HEADER &&
00198 last_word_class != PMT::FEM_HEADER &&
00199 last_word_class != PMT::CHANNEL_LAST_WORD) {
00200
00201 Message::send(MSG::ERROR,__FUNCTION__,
00202 Form("Unexpected FEM header (%x) with the previous word %x!",word,last_word));
00203
00204 status = false;
00205 }else if(get_word_class(word>>16)!=PMT::FEM_HEADER) {
00206
00207
00208
00209
00210 Message::send(MSG::ERROR,__FUNCTION__,Form("Found an odd event header word: %x",word));
00211
00212 status = false;
00213 }else{
00214
00215 _event_header_words[_event_header_count] = word;
00216
00217 _event_header_count++;
00218
00219 if(_event_header_count == FEM_HEADER_COUNT)
00220
00221 status = decode_fem_header(_event_header_words);
00222
00223 }
00224
00225 last_word = word;
00226
00227 return status;
00228 }
00229
00230 bool algo_tpc_huffman::process_event_last_word(const PMT::word_t word,
00231 PMT::word_t &last_word)
00232 {
00233 bool status = true;
00234
00235
00236
00237
00238
00239
00240 PMT::word_t last_word_class = get_word_class(last_word);
00241
00242 if(last_word_class != PMT::CHANNEL_LAST_WORD) {
00243
00244 Message::send(MSG::ERROR,__FUNCTION__,
00245 Form("Unexpected event last word (%x) with the previous word %x!",word,last_word));
00246
00247 status = false;
00248
00249 }else if(_header_info.event_id!=PMT::INVALID_WORD){
00250
00251 Message::send(MSG::ERROR,__FUNCTION__,
00252 Form("End of event (%x) ... but buffer holds data for event %d!",word,_header_info.event_id));
00253
00254 status = false;
00255
00256 }
00257
00258 last_word = word;
00259
00260 return status;
00261 }
00262
00263 bool algo_tpc_huffman::process_fem_last_word(const PMT::word_t word,
00264 PMT::word_t &last_word)
00265 {
00266
00267
00268
00269 Message::send(MSG::ERROR,__FUNCTION__,
00270 "This function should not be called...");
00271
00272 last_word = word;
00273 return false;
00274 }
00275
00276 bool algo_tpc_huffman::process_ch_word(const PMT::word_t word,
00277 PMT::word_t &last_word)
00278 {
00279
00280
00281
00282
00283
00284
00285
00286 bool status = true;
00287 PMT::word_t word_class = get_word_class(word);
00288 PMT::word_t last_word_class = get_word_class(last_word);
00289
00290
00291 if(word == 0x0){
00292
00293 if(get_word_class(last_word)!=PMT::CHANNEL_LAST_WORD){
00294
00295 Message::send(MSG::ERROR,__FUNCTION__,
00296 Form("Unexpected Zero-padding found after %x",last_word));
00297 status = false;
00298 }else if(_verbosity[MSG::INFO])
00299
00300 Message::send(MSG::INFO,__FUNCTION__,
00301 Form("Zero-padding found after %x",last_word));
00302
00303 return status;
00304 }
00305
00306 switch(word_class){
00307
00308 case PMT::CHANNEL_HEADER:
00309
00310
00311
00312
00313 if(last_word_class == PMT::FEM_HEADER ||
00314 last_word_class == PMT::CHANNEL_LAST_WORD ) {
00315
00316
00317
00318 _ch_data.clear_data();
00319
00320 _ch_data.set_channel_number( (word & 0xfff) );
00321
00322 if(_verbosity[MSG::DEBUG])
00323
00324 Message::send(MSG::DEBUG,__FUNCTION__,
00325 Form("New channel header: %d",_ch_data.channel_number()));
00326
00327 }else{
00328
00329 Message::send(MSG::ERROR,__FUNCTION__,
00330 Form("Unexpected channel header (%x)! Last word = %x",word,last_word));
00331
00332 status = false;
00333
00334 }
00335
00336 break;
00337
00338 case PMT::CHANNEL_LAST_WORD:{
00339
00340
00341 PMT::ch_number_t ch( (word & 0xfff) );
00342 if(ch == _ch_data.channel_number()) {
00343
00344 if(_verbosity[MSG::DEBUG])
00345
00346 Message::send(MSG::DEBUG,__FUNCTION__,
00347 Form("Finished reading %zu samples for Ch %d",
00348 _ch_data.size(),_ch_data.channel_number()));
00349
00350
00351 _event_data->push_back(_ch_data);
00352
00353 _ch_data.clear_data();
00354
00355 }else{
00356
00357 Message::send(MSG::ERROR,__FUNCTION__,
00358 Form("Ch. number disagreement! Header: %u ... Last: %u!",
00359 _ch_data.channel_number(),ch) );
00360
00361 status = false;
00362 }
00363
00364
00365 if(status && _nwords == _header_info.nwords){
00366 _nwords++;
00367 _checksum += word;
00368 status = store_event();
00369 }
00370
00371 break;
00372 }
00373 case PMT::FEM_LAST_WORD:
00374
00375 if(last_word_class == PMT::CHANNEL_LAST_WORD)
00376
00377 status = process_fem_last_word(word,last_word);
00378
00379 else status = decode_ch_word(word,last_word);
00380
00381 break;
00382
00383 default:
00384
00385 status = decode_ch_word(word,last_word);
00386 }
00387
00388 if(status && _header_info.nwords){
00389
00390 _nwords++;
00391 _checksum += word;
00392
00393 }
00394
00395 last_word = word;
00396
00397 return status;
00398 }
00399
00400 #endif