CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/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( uint64_t * buffer, unsigned int 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     // looping over FE channels, i.e. tower blocks
00202     for( unsigned int chNumber=1; chNumber<= numbChannels && STATUS!=STOP_EVENT_UNPACKING; chNumber++, it++ ){                        
00203       //for( unsigned int i=1; chNumber<= numbChannels; chNumber++, it++ ){                        
00204       
00205       const short chStatus(*it);
00206       
00207       // skip unpacking if channel disabled
00208       if (chStatus == CH_DISABLED) {
00209         continue;
00210       }
00211       
00212       // force MEM readout if mem_ is enabled in EEs regardless on ch suppress status flag
00213       if (chStatus == CH_SUPPRESS && !mem_ ) {
00214         continue;
00215       }
00216       
00217       // issuiung messages for problematic cases, even though handled by the DCC
00218       // and skip channel
00219       if (chStatus == CH_TIMEOUT || chStatus == CH_HEADERERR ||
00220           chStatus == CH_LINKERR || chStatus == CH_LENGTHERR ||
00221           chStatus == CH_IFIFOFULL || chStatus == CH_L1AIFIFOFULL)
00222       {
00223         if (! DCCDataUnpacker::silentMode_) {
00224           const int val = unpacker_->getCCUValue(fedId_, chNumber);
00225           const bool ttProblem = (val == 13) || (val == 14);
00226           if (! ttProblem) {
00227             edm::LogWarning("IncorrectBlock")
00228               << "Bad channel status: " << chStatus
00229               << " in the DCC channel: " << chNumber
00230               << " (LV1 " << l1_ << " fed " << fedId_ << ")\n"
00231               << "  => DCC channel is not being unpacked";
00232           }
00233         }
00234         continue;
00235       }
00236       
00237       // Unpack Tower (Xtal Block) in case of SR (data are 0 suppressed)
00238       if(feUnpacking_ && sr_ && chNumber<=68)
00239         {
00240           if( fov_ > 0){  
00241             bool applyZS(true);
00242             if( !ignoreSR && chStatus != CH_FORCEDZS1
00243               && (srpBlock_->srFlag(chNumber) & SRP_SRVAL_MASK) == SRP_FULLREADOUT){ applyZS = false; }
00244           
00245 
00246             // If there is a decision to fully suppress data this is updated in channel status by the dcc
00247             //if ( ( srpBlock_->srFlag(chNumber) & SRP_SRVAL_MASK) != SRP_NREAD ){
00248                 STATUS = towerBlock_->unpack(&data_,&dwToEnd_,applyZS,chNumber);
00249             //}
00250           }
00251           else{
00252 
00253              // introduced to keep backward compatibility with FOV = 0; 
00254              STATUS = towerBlock_->unpack(&data_,&dwToEnd_,true,chNumber);
00255 
00256           }
00257         }
00258       
00259 
00260 
00261       
00262       
00263       // Unpack Tower (Xtal Block) for no SR (possibly 0 suppression flags)
00264       else if (feUnpacking_ && chNumber<=68)
00265         {
00266           // if tzs_ data are not really suppressed, even though zs flags are calculated
00267           if(tzs_){ zs_ = false;}
00268           STATUS = towerBlock_->unpack(&data_,&dwToEnd_,zs_,chNumber);
00269         }
00270       
00271       
00272       // Unpack Mem blocks
00273       if(memUnpacking_        && chNumber>68 )
00274         {
00275           STATUS = memBlock_->unpack(&data_,&dwToEnd_,chNumber);
00276         }
00277       
00278     }
00279     // closing loop over FE/TTblock channels
00280     
00281   }// check if we need to perform unpacking of FE or mem data
00282   
00283   
00284   if(headerUnpacking_) addHeaderToCollection();
00285   
00286 }
00287 
00288 
00289 
00290 
00291 int DCCEEEventBlock::unpackTCCBlocks(){
00292 
00293   int STATUS(BLOCK_UNPACKED);
00294   std::vector<short>::iterator it;
00295   unsigned int tccChId(0);
00296   for(it=tccChStatus_.begin();it!=tccChStatus_.end();it++, tccChId++){
00297     if( (*it) != CH_TIMEOUT &&  (*it) != CH_DISABLED){
00298       STATUS = tccBlock_->unpack(&data_,&dwToEnd_,tccChId);
00299           if(STATUS == STOP_EVENT_UNPACKING) break;
00300     }
00301   }
00302   return STATUS;
00303   
00304 }
00305