CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/EventFilter/EcalRawToDigi/src/DCCEBEventBlock.cc

Go to the documentation of this file.
00001 
00002 #include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
00003 #include "EventFilter/EcalRawToDigi/interface/EcalDCCHeaderRuntypeDecoder.h"
00004 #include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
00005 #include "EventFilter/EcalRawToDigi/interface/DCCMemBlock.h"
00006 
00007 
00008 #include "EventFilter/EcalRawToDigi/interface/DCCEBEventBlock.h"
00009 #include "EventFilter/EcalRawToDigi/interface/DCCTowerBlock.h"
00010 #include "EventFilter/EcalRawToDigi/interface/DCCEBTCCBlock.h"
00011 #include "EventFilter/EcalRawToDigi/interface/DCCEBSRPBlock.h"
00012 #include <sys/time.h>
00013 
00014 #include <iomanip>
00015 #include <sstream>
00016 
00017 
00018 DCCEBEventBlock::DCCEBEventBlock( DCCDataUnpacker * u, EcalElectronicsMapper * m , bool hU, bool srpU, bool tccU, bool feU , bool memU, bool forceToKeepFRdata) : 
00019   DCCEventBlock(u,m,hU,srpU,tccU,feU,memU,forceToKeepFRdata)
00020 {
00021 
00022   //Builds a tower unpacker block
00023   towerBlock_ = new DCCTowerBlock(u,m,this,feUnpacking_, forceToKeepFRdata_); 
00024   
00025   //Builds a srp unpacker block
00026   srpBlock_   = new DCCEBSRPBlock(u,m,this,srpUnpacking_);
00027   
00028   //Builds a tcc unpacker block
00029   tccBlock_   = new DCCEBTCCBlock(u,m,this,tccUnpacking_);
00030 
00031   // This field is not used in EB
00032   mem_ = 0;    
00033   
00034  
00035 }
00036 
00037 
00038 
00039 void DCCEBEventBlock::unpack(const uint64_t * buffer, size_t numbBytes, unsigned int expFedId){
00040   
00041   reset();
00042  
00043   eventSize_ = numbBytes;        
00044   data_      = buffer;
00045   
00046   // First Header Word of fed block
00047   fedId_             = ((*data_)>>H_FEDID_B)   & H_FEDID_MASK;
00048   bx_                = ((*data_)>>H_BX_B   )   & H_BX_MASK;
00049   l1_                = ((*data_)>>H_L1_B   )   & H_L1_MASK;
00050   triggerType_       = ((*data_)>>H_TTYPE_B)   & H_TTYPE_MASK;
00051   
00052   // Check if fed id is the same as expected...
00053   if( fedId_ != expFedId  ){ 
00054 
00055   if( ! DCCDataUnpacker::silentMode_ ){  
00056     edm::LogWarning("IncorrectEvent")
00057       <<"\n For event L1A: "<<l1_
00058       <<"\n Expected FED id is: "<<expFedId<<" while current FED id is: "<<fedId_
00059       <<"\n => Skipping to next fed block...";
00060     }
00061   
00062   //TODO : add this to an error event collection
00063   
00064   return;
00065   } 
00066   
00067   // Check if this event is an empty event 
00068   if( eventSize_ == EMPTYEVENTSIZE ){ 
00069     if( ! DCCDataUnpacker::silentMode_ ){
00070       edm::LogWarning("IncorrectEvent")
00071         <<"\n Event L1A: "<<l1_<<" is empty for fed: "<<fedId_
00072         <<"\n => Skipping to next fed block...";
00073     }
00074     return;
00075     
00076   } 
00077   
00078   //Check if event size allows at least building the header
00079   else if( eventSize_ < HEADERSIZE ){    
00080     if( ! DCCDataUnpacker::silentMode_ ){
00081       edm::LogError("IncorrectEvent")
00082         <<"\n Event L1A: "<<l1_<<" in fed: "<< fedId_
00083         <<"\n Event size is "<<eventSize_<<" bytes while the minimum is "<<HEADERSIZE<<" bytes"
00084         <<"\n => Skipping to next fed block..."; 
00085      }
00086     
00087     //TODO : add this to a dcc size error collection  
00088     
00089     return;
00090     
00091   }
00092   
00093   //Second Header Word of fed block
00094   data_++;
00095   
00096   blockLength_   =   (*data_ )                 & H_EVLENGTH_MASK;
00097   dccErrors_     =   ((*data_)>>H_ERRORS_B)    & H_ERRORS_MASK;
00098   runNumber_     =   ((*data_)>>H_RNUMB_B )    & H_RNUMB_MASK;
00099   
00100   
00101   if( eventSize_ != blockLength_*8 ){
00102     if( ! DCCDataUnpacker::silentMode_ ){
00103       edm::LogError("IncorrectEvent")
00104         <<"\n Event L1A: "<<l1_<<" in fed: "<< fedId_
00105         <<"\n size is "<<eventSize_<<" bytes while "<<(blockLength_*8)<<" are set in the event header "
00106         <<"\n => Skipping to next fed block..."; 
00107       //TODO : add this to a dcc size error collection 
00108      }
00109     return;
00110     
00111   }  
00112   
00113   //Third Header Word  of fed block
00114   data_++;
00115 
00116 
00117   // bits 0.. 31 of the 3rd DCC header word
00118   runType_              = (*data_) & H_RTYPE_MASK;
00119   
00120   fov_                  = ((*data_)>>H_FOV_B) & H_FOV_MASK;
00121 
00122   // bits 32.. 47 of the 3rd DCC header word
00123   detailedTriggerType_ = ((*data_) >> H_DET_TTYPE_B) & H_DET_TTYPE_MASK;
00124 
00125   //Forth Header Word
00126   data_++;
00127   orbitCounter_        = ((*data_)>>H_ORBITCOUNTER_B)  & H_ORBITCOUNTER_MASK;
00128   sr_                  = ((*data_)>>H_SR_B)            & B_MASK;
00129   zs_                  = ((*data_)>>H_ZS_B)            & B_MASK;
00130   tzs_                 = ((*data_)>>H_TZS_B)           & B_MASK;
00131   srChStatus_          = ((*data_)>>H_SRCHSTATUS_B)    & H_CHSTATUS_MASK;
00132   
00133 
00134   bool ignoreSR(true);
00135 
00136   // getting TCC channel status bits
00137   tccChStatus_[0] = ((*data_)>>H_TCC1CHSTATUS_B)   & H_CHSTATUS_MASK; 
00138   tccChStatus_[1] = ((*data_)>>H_TCC2CHSTATUS_B)   & H_CHSTATUS_MASK;
00139   tccChStatus_[2] = ((*data_)>>H_TCC3CHSTATUS_B)   & H_CHSTATUS_MASK;
00140   tccChStatus_[3] = ((*data_)>>H_TCC4CHSTATUS_B)   & H_CHSTATUS_MASK;
00141     
00142   // FE  channel Status data
00143   int channel(0);
00144   for( int dw = 0; dw<5; dw++ ){
00145     data_++;
00146     for( int i = 0; i<14; i++, channel++){
00147       unsigned int shift = i*4; //each channel has 4 bits
00148       feChStatus_[channel] = ( (*data_)>>shift ) &  H_CHSTATUS_MASK ;
00149     }
00150   }
00151    
00152   // debugging
00153   //display(cout);
00154   
00155   // Update number of available dwords
00156   dwToEnd_ = blockLength_ - HEADERLENGTH ;
00157    
00158   int STATUS = unpackTCCBlocks();
00159 
00160   if(  STATUS != STOP_EVENT_UNPACKING && (feUnpacking_ || srpUnpacking_) ){
00161     
00162     //NMGA note : SR comes before TCC blocks 
00163     // Emmanuelle please change this in the digi to raw
00164   
00165     // Unpack SRP block
00166     if(srChStatus_ != CH_TIMEOUT &&  srChStatus_ != CH_DISABLED){
00167       STATUS = srpBlock_->unpack(&data_,&dwToEnd_);
00168       if ( STATUS == BLOCK_UNPACKED ){ ignoreSR = false; }
00169     }
00170     
00171   }
00172 
00173 
00174 
00175 
00176 
00177   // See number of FE channels that we need according to the trigger type //
00178   // TODO : WHEN IN LOCAL MODE WE SHOULD CHECK RUN TYPE                        
00179   unsigned int numbChannels(0);
00180   
00181   if(       triggerType_ == PHYSICTRIGGER      ){ numbChannels = 68; }
00182   else if ( triggerType_ == CALIBRATIONTRIGGER ){ numbChannels = 70; }
00183   else {
00184     if( ! DCCDataUnpacker::silentMode_ ){
00185       edm::LogError("IncorrectEvent")
00186         <<"\n Event L1A: "<<l1_<<" in fed: "<< fedId_
00187         <<"\n Event has an unsupported trigger type "<<triggerType_
00188         <<"\n => Skipping to next fed block..."; 
00189       //TODO : add this to a dcc trigger type error collection 
00190     }
00191     return;
00192   }
00193   
00194   // note: there is no a-priori check that number_active_channels_from_header
00195   //          equals number_channels_found_in_data.
00196   //          The checks are doing f.e. by f.e. only.
00197   
00198   if( feUnpacking_ || memUnpacking_ ){
00199     // pointer for the
00200     std::vector<short>::iterator it = feChStatus_.begin();
00201     
00202     // fields for tower recovery code
00203     unsigned int next_tower_id = 1000;
00204     const uint64_t* next_data = data_;
00205     unsigned int next_dwToEnd = dwToEnd_;
00206     
00207     // looping over FE channels, i.e. tower blocks
00208     for (unsigned int chNumber=1; chNumber<= numbChannels && STATUS!=STOP_EVENT_UNPACKING; chNumber++, it++ ){
00209       //for( unsigned int i=1; chNumber<= numbChannels; chNumber++, it++ ){                        
00210 
00211       const short chStatus(*it);
00212       
00213       // regular cases
00214       const bool regular = (chStatus == CH_DISABLED ||
00215                             chStatus == CH_SUPPRESS);
00216       
00217       // problematic cases
00218       const bool problematic = (chStatus == CH_TIMEOUT ||
00219                                 chStatus == CH_HEADERERR ||
00220                                 chStatus == CH_LINKERR ||
00221                                 chStatus == CH_LENGTHERR ||
00222                                 chStatus == CH_IFIFOFULL ||
00223                                 chStatus == CH_L1AIFIFOFULL);
00224       
00225       // issuiung messages for problematic cases, even though handled by the DCC
00226       if (problematic) {
00227         if (! DCCDataUnpacker::silentMode_ ) {
00228           const int val = unpacker_->getCCUValue(fedId_, chNumber);
00229           const bool ttProblem = (val == 13) || (val == 14);
00230           if (! ttProblem) {
00231             edm::LogWarning("IncorrectBlock")
00232               << "Bad DCC channel status: " << chStatus
00233               << " (LV1 " << l1_ << " fed " << fedId_ << " tower " << chNumber << ")\n"
00234               << "  => DCC channel is not being unpacked";
00235           }
00236         }
00237       }
00238       
00239       // skip unpack in case of bad status
00240       if (regular || problematic) {
00241         continue;
00242       }
00243       
00244       // preserve data pointer
00245       const uint64_t* const prev_data = data_;
00246       const unsigned int prev_dwToEnd = dwToEnd_;
00247       
00248       // skip corrupted/problematic data block
00249       if (chNumber >= next_tower_id) {
00250         data_ = next_data;
00251         dwToEnd_ = next_dwToEnd;
00252         next_tower_id = 1000;
00253       }
00254       
00255       
00256       // Unpack Tower (Xtal Block)
00257       if (feUnpacking_ && chNumber <= 68) {
00258         
00259         //  in case of SR (data are 0 suppressed)
00260         if (sr_) {
00261           const bool applyZS =
00262             (fov_ == 0) ||      // backward compatibility with FOV = 0;
00263             ignoreSR ||
00264             (chStatus == CH_FORCEDZS1) ||
00265             ((srpBlock_->srFlag(chNumber) & SRP_SRVAL_MASK) != SRP_FULLREADOUT);
00266           
00267           STATUS = towerBlock_->unpack(&data_, &dwToEnd_, applyZS, chNumber);
00268           
00269               // If there is an action to suppress SR channel the associated channel status should be updated 
00270               // so we can remove this piece of code
00271               // if ( ( srpBlock_->srFlag(chNumber) & SRP_SRVAL_MASK) != SRP_NREAD ){
00272               //
00273               //  STATUS = towerBlock_->unpack(&data_,&dwToEnd_,applyZS,chNumber);
00274               //}
00275         }
00276         // no SR (possibly 0 suppression flags)
00277         else {
00278           // if tzs_ data are not really suppressed, even though zs flags are calculated
00279           if(tzs_){ zs_ = false;}
00280           STATUS = towerBlock_->unpack(&data_,&dwToEnd_,zs_,chNumber);
00281         }
00282       }
00283       
00284       
00285       // Unpack Mem blocks
00286       if (memUnpacking_ && chNumber > 68) {
00287           STATUS = memBlock_->unpack(&data_,&dwToEnd_,chNumber);
00288       }
00289       
00290       
00291       // corruption recovery
00292       if (STATUS == SKIP_BLOCK_UNPACKING) {
00293         data_ = prev_data;
00294         dwToEnd_ = prev_dwToEnd;
00295         
00296         next_tower_id = next_tower_search(chNumber);
00297         
00298         next_data = data_;
00299         next_dwToEnd = dwToEnd_;
00300         
00301         data_ = prev_data;
00302         dwToEnd_ = prev_dwToEnd;
00303       }
00304       
00305     }
00306     // closing loop over FE/TTblock channels
00307     
00308   }// check if we need to perform unpacking of FE or mem data
00309   
00310   
00311   if(headerUnpacking_) addHeaderToCollection();
00312   
00313   
00314 }
00315 
00316 
00317 
00318  // Unpack TCC blocks
00319 int DCCEBEventBlock::unpackTCCBlocks(){
00320 
00321     if(tccChStatus_[0] != CH_TIMEOUT && tccChStatus_[0] != CH_DISABLED)
00322       return tccBlock_->unpack(&data_,&dwToEnd_);
00323     else return BLOCK_UNPACKED;
00324 
00325 }