CMS 3D CMS Logo

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