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