algo_slow_readout_decoder.cc

Go to the documentation of this file.
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   // A simple function to call other members depending on the status.
00077   // Let other members to deal with expected/unexpected case
00078   //
00079 
00080   // If in back_trace mode, add this word in record
00081   if(_bt_mode){
00082     
00083     // Check if buffer is filled
00084     if(!_bt_nwords_filled)
00085       _bt_nwords_filled = (_bt_nwords == _bt_words.size());
00086 
00087     // If filled, remove the oldest element
00088     if(_bt_nwords_filled)
00089       _bt_words.pop_front();
00090 
00091     // Add new word
00092     _bt_words.push_back(word);
00093 
00094   }
00095 
00096   // IF data pointer is not set, set
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     // hand over 32-bit word as it is for processing event header
00110     //
00111     status=process_header(word);
00112     break;
00113   case READ_CHANNEL:
00114     //
00115     // Exceptional case handling: if word type is event header,
00116     // warn a user & process it as a header
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     // Check data quality: return is not relevant as this is debug mode.
00127     //if(_beam_event) apply_beamgate_correction();
00128     status = check_event_quality();
00129     
00130     init_event_info();
00131     // Process this as a header 
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     // As this is debug mode, we let the run continiue
00143     status=true;
00144       }
00145       else
00146     status=false;
00147       break;
00148     }
00149     //
00150     // hand over 2 of 16-bit words for channel data
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       // Something went wrong in processing channel word.
00159       // If _debug_mode is set true, we let it continue to
00160       // the next event.
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   // Handle the case this is not a header word
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     // Ommit undefined word
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     // Raise error for non-header words
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     // Header word -> store & process
00211   case PMT::EVENT_HEADER:
00212     // This is just a marker. Nothing really to be done.
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     // Event header should come as a 32-bit word which is a pair of two 16-bit header words.
00219     // The first 16-bit is already checked by this point. Check the second part.
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       // Store header words
00230       _event_header_words[_event_header_count]=word;
00231       _event_header_count++;
00232 
00233       if(_event_header_count==FEM_HEADER_COUNT) {
00234     
00235     // Process header words
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       // Raise error if a header word count > set constant (should not happen)
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   // Get event information
00263   //
00264 
00265   // (1) check if the very first 16-bit word is as expected
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   // (2) get module address ... lowest 5 of 12 bits
00272   //  _event_data->set_module_address(( event_header[0]>>16 & 0xfff ) & 0x1f);
00273   _event_data->set_module_address(( event_header[0]>>16 & 0xfff ) & 0x1f);
00274 
00275   // (3) get module ID number ... upper 7 bit of 12 bits
00276   _event_data->set_module_id((event_header[0]>>16 & 0xfff)>>5 & 0x7f);
00277 
00278   // (4) get number of 16-bit words to be read in this event.
00279   // Lower 12 bits of two 16-bit words.
00280   // The very last "last word for channel info" is not included in this.
00281   // For later checking purpose, increment by 1.
00282   _event_data->set_nwords( (( (event_header[1]>>16) & 0xfff ) + ((event_header[1] & 0xfff)<<12)) );
00283 
00284   // (5) get event ID
00285   // Lower 12 bits of two 16-bit words.
00286   _event_data->set_event_id( (( (event_header[2]>>16) & 0xfff ) + ((event_header[2] & 0xfff)<<12)));
00287 
00288   // (6) get frame ID
00289   // Lower 12 bits of two 16-bit words.
00290   _event_data->set_event_frame_id((( (event_header[3]>>16) & 0xfff ) + ((event_header[3] & 0xfff)<<12)));
00291 
00292   // (7) get checksum
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   // Correct for a roll over
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   // Report if verbosity is set.
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   // extract information
00334   PMT::PMT_WORD last_word_class=get_word_class(last_word);
00335   PMT::PMT_WORD word_class=get_word_class(word);
00336 
00337   // Print out DEBUG information
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     // Something went wrong in decode_ch_word function
00361     sprintf(_buf,"Status failure while analyzing: %x ... (previous word: %x)",word,last_word);
00362     Message::send(MSG::ERROR,__FUNCTION__,_buf);
00363   }else{
00364     // subtract # words & check-sum
00365     if(word_class==PMT::EVENT_LAST_WORD){
00366       // This is the last sample for this event.
00367       if(_verbosity[MSG::INFO]){
00368     sprintf(_buf,"Found the last event word: %x",word);
00369     Message::send(MSG::INFO,__FUNCTION__,_buf);
00370       }
00371       //if(_beam_event) apply_beamgate_correction();
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   // Used to recover pmt/trigger frame id from roll over effect.
00398   // One can test this by simply calling this function.
00399   // For instance, to test the behavior for a roll-over of 0x7 ...
00400   //
00401   // > root
00402   // root[0] gSystem->Load("libDecoder")
00403   // root[1] algo_slow_readout_decoder k
00404   // root [6] k.get_pmt_frame(583,584,0x7)
00405   // (const unsigned int)584
00406   // root [7] k.get_pmt_frame(584,583,0x7)
00407   // (const unsigned int)583
00408   //
00409   // I think this implementation works. ... Aug. 12 2013
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   // Following part is provided by David & Georgia for a specific implementation for PMT... Aug. 12 2013
00418   // But I don't think this works right. 
00419   // -Kazu Aug. 12 2013
00420   /*
00421   PMT::word_t correct_frame= ( ( event_frame_id & (~0x7) ) | ( channel_frame_id & 0x7 ) );
00422   if( (correct_frame-event_frame_id)<-1 )
00423     return correct_frame+8;
00424   else if( (correct_frame-event_frame_id)>2 )
00425     return correct_frame-8;
00426   else 
00427     return correct_frame;
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       // Case 1: pulse comes before the beamgate but in the same frame
00442       //
00443       if( (*iter).timeslice() < _beam_ref_sample && (*iter).channel_frame_id() == _beam_ref_frame )
00444 
00445     // shift the sample number by diff of the sample size
00446     (*iter).set_timeslice( _beam_ref_sample + _beam_ref_nwords - (*iter).size() );
00447 
00448       //
00449       // Case 2: pulse comes before the beamgate and in the previous frame
00450       //
00451       if( (*iter).channel_frame_id() < _beam_ref_frame ) {
00452 
00453     // shift the sample number by diff of the sample size first
00454     (*iter).set_timeslice( _beam_ref_sample + _beam_ref_nwords - (*iter).size() );
00455     
00456     // if this sample number is exceeding the frame edge, change the frame number
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       // Case 3: pulse comes after the beamgate ... data should be readout correctly.
00465       //         Nothing to be done.
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     // Found an event header: -> unexpected. This should be handled in process_word().
00514     // Return "false" if executed even in _debug_mode (as it's this program's logic error)
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     // Found an undefined word: unexpected. This should be handled in process_ch_word().
00524     // Return "false" if executed even in _debug_mode=true... it's this program's logic error.
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     // First channel word in this event ... nothing special to do
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     // Channel header ... read in channel info from this word
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       // Initialize channel info, then fill with channel number & disc. id.
00550       init_ch_info();
00551       _ch_data.set_channel_number( word & 0x3f ); // Lower-most 6 bits of 12-bit word is channel number
00552       _ch_data.set_disc_id((PMT::DISCRIMINATOR)((word & 0xfff)>>9));  // Upper-most 2 bits of 12-bit word is discriminator ID
00553     }
00554     break;
00555 
00556   case PMT::CHANNEL_WORD:
00557   case PMT::CHANNEL_LAST_WORD:
00558     //
00559     // This is channel ADC count or possibly remaining channel header info
00560     // The first two sample are treated as channel header info
00561     if(last_word_class!=PMT::CHANNEL_HEADER && 
00562        last_word_class!=PMT::CHANNEL_WORD &&
00563        last_word_class!=PMT::CHANNEL_LAST_WORD ) {
00564       // Sanity check: the last word should be either channel header or data word.
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       // Treat a case of missing very first channel header word: happens when there is no time in between two readout data.
00571       if(last_word_class==PMT::CHANNEL_LAST_WORD){
00572     // In this case, we should be missing the CHANNEL_HEADER because this pulse is from the same channel & discriminator id.
00573     // Do an operation that is done for the case of CHANNEL_HEADER, but use a stored value of channel number & disc. id.
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       // Ordinary operation for channel header / adc words
00586       //
00587       if(_channel_header_count==CHANNEL_HEADER_COUNT ) {
00588     // Finished reading in header words. This should be a mere ADC count.
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     // First of 2 channel header words. Record the values.
00593 
00594     // This gives upper 8 bits of 20-bit timeslice number
00595     _ch_data.set_timeslice( (word & 0x1f)<<12 );       
00596 
00597     // Lower 3 of 8 bits is the channel frame ID
00598     _ch_data.set_channel_frame_id( ((word & 0xff)>>5) +
00599                        (((_event_data->event_frame_id())>>3)<<3) ); 
00600 
00601     // Correct channel frame id roll-over w.r.t. event frame id
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     // Second of 2 channel header words. Record the values & inspect them.
00608     _ch_data.set_timeslice(_ch_data.timeslice() + (word & 0xfff)); // This gives lower 12 bits of 20-bit timeslice number
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       // If this is channel's last word, store & clear channel info
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   // Store this waveform's channel number and discriminator id.
00661   // This may be used in the next pulse in case the next pulse is coming with no time space in between.
00662   // In such case, the next pulse is missing the channel very first header word because it is supposed
00663   // to be combined.
00664   _last_channel_number=_ch_data.channel_number();
00665   _last_disc_id=_ch_data.disc_id();
00666 
00667 }
00668 
00669 #endif

Generated on Mon Apr 7 15:35:12 2014 for MyProject by  doxygen 1.4.7