CMS 3D CMS Logo

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

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