00001 #ifndef ALGO_TPC_XMIT
00002 #define ALGO_TPC_XMIT
00003
00004 #include "algo_tpc_xmit.hh"
00005
00006
00007 algo_tpc_xmit::algo_tpc_xmit()
00008 : algo_fem_decoder_base()
00009 {
00010
00011
00012 reset();
00013
00014 }
00015
00016
00017 void algo_tpc_xmit::reset() {
00018
00019
00020 _event_data = 0;
00021
00022 _ch_data.clear_data();
00023
00024 algo_fem_decoder_base::reset();
00025
00026 }
00027
00028
00029 bool algo_tpc_xmit::process_ch_word(const PMT::word_t word,
00030 PMT::word_t &last_word)
00031 {
00032
00033
00034 bool status=true;
00035
00036 if(_verbosity[MSG::DEBUG]){
00037 sprintf(_buf,"Processing ch-word: %x",word);
00038 Message::send(MSG::DEBUG,__FUNCTION__,_buf);
00039 }
00040
00041 PMT::PMT_WORD word_class=get_word_class(word);
00042 PMT::PMT_WORD last_word_class=get_word_class(last_word);
00043
00044 switch(word_class){
00045
00046 case PMT::CHANNEL_HEADER:
00047
00048
00049
00050
00051 if(last_word_class == PMT::FEM_HEADER ||
00052 last_word_class == PMT::CHANNEL_LAST_WORD ) {
00053
00054
00055
00056 _ch_data.clear_data();
00057
00058 _ch_data.set_channel_number( (word & 0xfff) );
00059
00060 if(_verbosity[MSG::DEBUG])
00061
00062 Message::send(MSG::DEBUG,__FUNCTION__,
00063 Form("New channel header: %d",_ch_data.channel_number()));
00064
00065 }else{
00066
00067 Message::send(MSG::ERROR,__FUNCTION__,
00068 Form("Unexpected channel header (%x)! Last word = %x",word,last_word));
00069
00070 status = false;
00071
00072 }
00073
00074 break;
00075
00076 case PMT::CHANNEL_LAST_WORD:
00077
00078
00079
00080
00081 if(last_word_class == PMT::CHANNEL_WORD) {
00082
00083
00084 PMT::ch_number_t ch( (word & 0xfff) );
00085
00086 if(ch == _ch_data.channel_number()) {
00087
00088 if(_verbosity[MSG::DEBUG])
00089
00090 Message::send(MSG::DEBUG,__FUNCTION__,
00091 Form("Finished reading %zu samples for Ch %d",
00092 _ch_data.size(),_ch_data.channel_number()));
00093
00094
00095 _event_data->push_back(_ch_data);
00096
00097 _ch_data.clear_data();
00098
00099 }else{
00100
00101 Message::send(MSG::ERROR,__FUNCTION__,
00102 Form("Ch. number disagreement! Header: %u ... Last: %u!",
00103 _ch_data.channel_number(),ch) );
00104
00105 status = false;
00106
00107 }
00108
00109 }
00110 else{
00111
00112 Message::send(MSG::ERROR,__FUNCTION__,
00113 Form("Unexpected channel ending (%x)! Last word = %x",word,last_word));
00114
00115 status = false;
00116
00117 }
00118
00119 break;
00120
00121 case PMT::CHANNEL_WORD:
00122
00123
00124
00125
00126 if(last_word_class == PMT::CHANNEL_HEADER ||
00127 last_word_class == PMT::CHANNEL_WORD){
00128
00129 status = decode_ch_word(word,last_word);
00130
00131 }else{
00132
00133 Message::send(MSG::ERROR,__FUNCTION__,
00134 Form("Unexpected channel word (%x)! Last word = %x",word,last_word));
00135
00136 status = false;
00137
00138 }
00139
00140 break;
00141
00142 case PMT::EVENT_LAST_WORD:
00143 case PMT::FEM_LAST_WORD:
00144 case PMT::UNDEFINED_WORD:
00145 case PMT::EVENT_HEADER:
00146 case PMT::FEM_HEADER:
00147 case PMT::FEM_FIRST_WORD:
00148
00149 Message::send(MSG::ERROR,__FUNCTION__,
00150 Form("Unexpected word found while channel word processing: %x",word));
00151
00152 status = false;
00153
00154 break;
00155 }
00156
00157
00158 if(status) {
00159
00160 _nwords++;
00161 _checksum += word;
00162
00163 }else{
00164
00165 Message::send(MSG::ERROR,__FUNCTION__,
00166 Form("Failed processing channel word %x (previous=%x)",word,last_word));
00167
00168 clear_event();
00169 }
00170
00171 if(word_class != PMT::UNDEFINED_WORD)
00172
00173 last_word = word;
00174
00175 return status;
00176 }
00177
00178
00179 bool algo_tpc_xmit::check_event_quality(){
00180
00181
00182 bool status = true;
00183
00184
00185
00186 _nwords-=1;
00187 if(_nwords!=_header_info.nwords){
00188
00189 Message::send(MSG::ERROR,__FUNCTION__,
00190 Form("Disagreement on nwords: counted=%u, expected=%u",_nwords,_header_info.nwords));
00191
00192 status = false;
00193
00194 }
00195
00196
00197 if((_checksum & 0xffffff) !=_header_info.checksum){
00198
00199 Message::send(MSG::ERROR,__FUNCTION__,
00200 Form("Disagreement on checksum: summed=%x, expected=%x",_checksum,_header_info.checksum));
00201
00202 status = false;
00203
00204 }
00205
00206 return status;
00207
00208 }
00209
00210
00211
00212
00213 bool algo_tpc_xmit::process_event_header(const PMT::word_t word,
00214 PMT::word_t &last_word)
00215 {
00216
00217
00218 bool status = true;
00219
00220 if(!_event_data)
00221
00222 _event_data = (tpc_wf_collection*)(_storage->get_data(DATA_STRUCT::TPC_WF_COLLECTION));
00223
00224 if(get_word_class(last_word)==PMT::EVENT_LAST_WORD) {
00225
00226
00227
00228 status = store_event();
00229 }else if(last_word != PMT::INVALID_WORD){
00230
00231 Message::send(MSG::ERROR,__FUNCTION__,
00232 Form("Unexpected word (%x, previous=%x) while processing event header!",word,last_word));
00233
00234 status = false;
00235
00236 }
00237
00238 last_word = word;
00239
00240 return status;
00241
00242 }
00243
00244
00245 bool algo_tpc_xmit::process_fem_last_word(const PMT::word_t word,
00246 PMT::word_t &last_word)
00247 {
00248
00249
00250
00251 Message::send(MSG::ERROR,__FUNCTION__,
00252 Form("FEM-LAST-WORD (%x, previous=%x) ... NOT expected for TPC!",word,last_word));
00253
00254 last_word = word;
00255
00256 return false;
00257 }
00258
00259
00260 bool algo_tpc_xmit::process_event_last_word(const PMT::word_t word,
00261 PMT::word_t &last_word)
00262 {
00263
00264
00265 if(_verbosity[MSG::INFO]){
00266
00267 Message::send(MSG::INFO,__FUNCTION__,
00268 Form("End of event word: %x...",word));
00269
00270 }
00271
00272 last_word = word;
00273
00274 return true;
00275 }
00276
00277
00278
00279 void algo_tpc_xmit::clear_event(){
00280
00281
00282 algo_fem_decoder_base::clear_event();
00283
00284 _event_data->clear_data();
00285
00286 _ch_data.clear();
00287
00288 }
00289
00290
00291 bool algo_tpc_xmit::store_event(){
00292
00293
00294 bool status = check_event_quality();
00295
00296
00297 if(status) {
00298
00299 if(_verbosity[MSG::INFO]){
00300
00301 Message::send(MSG::INFO,__FUNCTION__,
00302 Form("Storing event %u with %zu channel entries...",
00303 _event_data->event_id(), _event_data->size()));
00304
00305 }
00306
00307 _event_data->set_module_address ( _header_info.module_address );
00308 _event_data->set_module_id ( _header_info.module_id );
00309 _event_data->set_event_id ( _header_info.event_id );
00310 _event_data->set_event_frame_id ( _header_info.event_frame_id );
00311 _event_data->set_trigger_frame_id ( _header_info.trigger_frame_id );
00312 _event_data->set_trigger_timeslice ( _header_info.trigger_timeslice );
00313 _event_data->set_nwords ( _header_info.nwords );
00314 _event_data->set_checksum ( _header_info.checksum );
00315
00316 status = _storage->next_event();
00317
00318 }else{
00319
00320 Message::send(MSG::ERROR,__FUNCTION__,
00321 Form("Skipping to store event %d...",_header_info.event_id));
00322
00323 status = false;
00324
00325 }
00326
00327 clear_event();
00328
00329 return status;
00330 }
00331
00332
00333 bool algo_tpc_xmit::decode_ch_word(const PMT::word_t word,
00334 PMT::word_t &last_word)
00335 {
00336
00337
00338 bool status = true;
00339
00340 if( !(is_compressed(word)) ) _ch_data.push_back( (word & 0xfff) );
00341
00342 else if(!(_ch_data.size())){
00343
00344
00345
00346
00347 Message::send(MSG::ERROR,__FUNCTION__,
00348 Form("Huffman coded word %x found while the previous was non-ADC word (%x)!",
00349 word,last_word));
00350
00351 status = false;
00352
00353 }
00354 else{
00355
00356
00357 PMT::word_t data = (word & 0x7fff);
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 size_t zero_count = 0;
00414 bool non_zero_found = false;
00415 for(size_t index=0; index<15 && status; ++index){
00416
00417 if( !((data >> index) & 0x1) )
00418
00419 zero_count += ( non_zero_found ? 1 : 0 );
00420
00421 else{
00422
00423 if(!non_zero_found) non_zero_found=true;
00424
00425 else status = add_huffman_adc(_ch_data,zero_count);
00426
00427 if(status) zero_count=0;
00428 }
00429 }
00430
00431 if(zero_count && status){
00432
00433 status = add_huffman_adc(_ch_data,zero_count);
00434
00435 }
00436
00437 if(!status)
00438
00439 Message::send(MSG::ERROR,__FUNCTION__,
00440 Form("Encountered unexpected number of zeros (=%zu) in the compressed word %x!",
00441 zero_count,word));
00442
00443 }
00444
00445 return status;
00446
00447 }
00448
00449 #endif