CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 #include "EventFilter/EcalRawToDigi/interface/DCCFEBlock.h"
00002 #include "EventFilter/EcalRawToDigi/interface/DCCEventBlock.h"
00003 #include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
00004 #include <stdio.h>
00005 #include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
00006 
00007 
00008 
00009 DCCFEBlock::DCCFEBlock( DCCDataUnpacker * u, EcalElectronicsMapper * m, DCCEventBlock * e,bool unpack, bool forceToKeepFRdata)
00010   : DCCDataBlockPrototype(u,m,e,unpack), checkFeId_(false), forceToKeepFRdata_(forceToKeepFRdata) {
00011    
00012   expXtalTSamples_           = mapper_->numbXtalTSamples();
00013   numbDWInXtalBlock_         = (expXtalTSamples_-2)/4+1;
00014   unfilteredDataBlockLength_ = mapper_->getUnfilteredTowerBlockLength();
00015   xtalGains_                 = new short[expXtalTSamples_]; 
00016   
00017 }
00018 
00019 
00020 void DCCFEBlock::updateCollectors(){
00021 
00022   invalidBlockLengths_    = unpacker_->invalidBlockLengthsCollection();
00023   invalidTTIds_           = unpacker_->invalidTTIdsCollection();
00024   invalidZSXtalIds_       = unpacker_->invalidZSXtalIdsCollection();
00025 }
00026 
00027 
00028 
00029 int DCCFEBlock::unpack(const uint64_t ** data, unsigned int * dwToEnd, bool zs, unsigned int expectedTowerID){
00030   
00031   zs_      = zs;  
00032   datap_   = data;
00033   data_    = *data;
00034   dwToEnd_ = dwToEnd;
00035   
00036   const unsigned int activeDCC = mapper_->getActiveSM();
00037 
00038   if( (*dwToEnd_)<1){
00039     if( ! DCCDataUnpacker::silentMode_ ){
00040       edm::LogWarning("IncorrectEvent")
00041         <<"\n Unable to unpack Tower block for event "<<event_->l1A()<<" in fed "<<activeDCC
00042         <<"\n The end of event was reached "
00043         <<"\n(or, previously, pointers intended to navigate outside of FedBlock (based on block sizes), and were stopped by setting dwToEnd_ to zero)"    ;
00044       //TODO : add this to a dcc event size collection error?
00045     }
00046     return STOP_EVENT_UNPACKING;
00047   }
00048   
00049   lastStripId_     = 0;
00050   lastXtalId_      = 0;
00051   expTowerID_      = expectedTowerID;
00052   
00053   
00054   //Point to begin of block
00055   data_++;
00056   
00057   towerId_           = ( *data_ )                   & TOWER_ID_MASK;
00058   nTSamples_         = ( *data_>>TOWER_NSAMP_B  )   & TOWER_NSAMP_MASK; 
00059   bx_                = ( *data_>>TOWER_BX_B     )   & TOWER_BX_MASK;
00060   l1_                = ( *data_>>TOWER_L1_B     )   & TOWER_L1_MASK;
00061   blockLength_       = ( *data_>>TOWER_LENGTH_B )   & TOWER_LENGTH_MASK;
00062   
00063   event_->setFESyncNumbers(l1_,bx_, (short)(expTowerID_-1));
00064 
00065   //debugging
00066   //display(cout);
00067 
00068 
00069   
00071   // check that expected fe_id==fe_expected is on
00072   if (checkFeId_              &&
00073       expTowerID_ != towerId_ &&
00074       expTowerID_ <= mapper_->getNumChannelsInDcc(activeDCC) ){ // fe_id must be within range foreseen in the FED 
00075     if (! DCCDataUnpacker::silentMode_) {
00076       edm::LogWarning("IncorrectBlock")
00077         << "Expected tower ID is " << expTowerID_ << " while " << towerId_ << " was found"
00078         << " (L1A " << event_->l1A() << " fed " << mapper_->getActiveDCC() << ")\n"
00079         << "  => Skipping to next FE block...";
00080     }
00081     
00082     fillEcalElectronicsError(invalidTTIds_); 
00083     
00084     updateEventPointers();
00085     return SKIP_BLOCK_UNPACKING;
00086   }
00087 
00089   // check that expected fe_id==fe_expected is off
00090   else if( (!checkFeId_) && 
00091            towerId_ > mapper_->getNumChannelsInDcc(activeDCC) ){ // fe_id must still be within range foreseen in the FED 
00092     if( ! DCCDataUnpacker::silentMode_ ){
00093       edm::LogWarning("IncorrectBlock")
00094         <<"For event "<<event_->l1A()<<" and fed "<<mapper_->getActiveDCC()<<" (there's no check fe_id==dcc_channel)"
00095         <<"\n the FE_id found: "<<towerId_<<" exceeds max number of FE foreseen in fed"
00096         <<"\n => Skipping to next FE block...";
00097     }
00098     
00099     updateEventPointers();
00100     return SKIP_BLOCK_UNPACKING;
00101   }
00102   
00103   // Check synchronization
00104   if (sync_) {
00105     const unsigned int dccBx = (event_->bx())  & TCC_BX_MASK;
00106     const unsigned int dccL1 = (event_->l1A()) & TCC_L1_MASK;
00107     const unsigned int fov   = (event_->fov()) & H_FOV_MASK;
00108     
00109     if (! isSynced(dccBx, bx_, dccL1, l1_, FE_MEM, fov)) {
00110       if (! DCCDataUnpacker::silentMode_) {
00111         // TODO: add check for status from Channel Status DB
00112         
00113         edm::LogWarning("IncorrectBlock")
00114           << "Synchronization error for Tower Block"
00115           << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << " tower " << towerId_ << ")\n"
00116           << "  dccBx = " << dccBx << " bx_ = " << bx_ << " dccL1 = " << dccL1 << " l1_ = " << l1_ << "\n"
00117           << "  => Skipping to next tower block";
00118       }
00119       
00120       //Note : add to error collection ?
00121       updateEventPointers();
00122       return SKIP_BLOCK_UNPACKING;
00123     }
00124   }
00125   
00126   // check number of samples
00127   if( nTSamples_ != expXtalTSamples_ ){
00128     if( ! DCCDataUnpacker::silentMode_ ){
00129       edm::LogWarning("IncorrectBlock")
00130         <<"Unable to unpack Tower Block "<<towerId_<<" for event L1A "<<event_->l1A()<<" in fed "<<mapper_->getActiveDCC()
00131         <<"\n Number of time samples "<<nTSamples_<<" is not the same as expected ("<<expXtalTSamples_<<")"
00132         <<"\n => Skipping to next tower block...";
00133      } 
00134     //Note : add to error collection ?                 
00135     updateEventPointers();
00136     return SKIP_BLOCK_UNPACKING;
00137   }
00138 
00139   
00140   xtalBlockSize_     = numbDWInXtalBlock_*8;
00141   blockSize_           = blockLength_*8;  
00142   
00143   if((*dwToEnd_)<blockLength_){
00144     if( ! DCCDataUnpacker::silentMode_ ){
00145       edm::LogWarning("IncorrectEvent")
00146         <<"\n Unable to unpack Tower Block "<<towerId_<<" for event L1A "<<event_->l1A()<<" in fed "<<mapper_->getActiveDCC()
00147         <<"\n Only "<<((*dwToEnd_)*8)<<" bytes are available while "<<blockSize_<<" are needed!"
00148         <<"\n => Skipping to next fed block...";
00149     }
00150     //TODO : add to error collections
00151     return STOP_EVENT_UNPACKING;
00152   }
00153 
00154 
00155   if(!zs_ && !forceToKeepFRdata_){
00156          
00157     if ( unfilteredDataBlockLength_ != blockLength_ ){
00158       if( ! DCCDataUnpacker::silentMode_ ){ 
00159         edm::LogWarning("IncorrectEvent")
00160           <<"\n For event L1A "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower "<<towerId_
00161           <<"\n Expected block size is "<<(unfilteredDataBlockLength_*8)<<" bytes while "<<(blockLength_*8)<<" was found"
00162           <<"\n => Skipping to next fed block...";
00163        }
00164 
00165       fillEcalElectronicsError(invalidBlockLengths_) ;
00166 
00167       //Safer approach...  - why pointers do not navigate in this case?
00168       return STOP_EVENT_UNPACKING;          
00169 
00170       
00171     }
00172 
00173     
00174   }
00175   else if (!zs && forceToKeepFRdata_){
00176 
00177      if ( unfilteredDataBlockLength_ != blockLength_ ){
00178       if( ! DCCDataUnpacker::silentMode_ ){ 
00179         edm::LogWarning("IncorrectBlock")
00180           <<"For event L1A "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower "<<towerId_
00181           <<"\n Expected block size is "<<(unfilteredDataBlockLength_*8)<<" bytes while "<<(blockLength_*8)<<" was found"
00182           <<"\n => Keeps unpacking as the unpacker was forced to keep FR data (by configuration) ...";
00183        }
00184 
00185       fillEcalElectronicsError(invalidBlockLengths_) ;
00186      }
00187 
00188   }
00189   else if( blockLength_ > unfilteredDataBlockLength_ || (blockLength_-1) < numbDWInXtalBlock_ ){
00190     if( ! DCCDataUnpacker::silentMode_ ){
00191       edm::LogWarning("IncorrectEvent")
00192         <<"\n For event L1A "<<event_->l1A()<<" and fed "<<mapper_->getActiveDCC()
00193         <<"\n The tower "<<towerId_<<" has a wrong number of bytes : "<<(blockLength_*8)           
00194         <<"\n => Skipping to next fed block...";
00195      }
00196 
00197      fillEcalElectronicsError(invalidBlockLengths_) ;
00198 
00199 
00200     //Safer approach... - why pointers do not navigate in this case?
00201     return STOP_EVENT_UNPACKING;
00202   }
00203   
00204 
00205 
00206   // If the HLT says to skip this tower we skip it...
00207   if( ! event_->getHLTChannel(towerId_) ){
00208     updateEventPointers();
00209     return SKIP_BLOCK_UNPACKING;
00210   }
00212 
00213 
00214 
00215 
00216 
00217   unsigned int numbOfXtalBlocks = (blockLength_-1)/numbDWInXtalBlock_; 
00218 
00219   // get XTAL Data
00220   unsigned int expStripID(0), expXtalID(0);
00221   //point to xtal data
00222   data_++;
00223   
00224   int statusUnpackXtal =0;
00225 
00226   for(unsigned int numbXtal=1; numbXtal <= numbOfXtalBlocks && statusUnpackXtal!= SKIP_BLOCK_UNPACKING; numbXtal++){
00227 
00228     
00229     if(!zs_ && ! forceToKeepFRdata_){
00230       expStripID  = ( numbXtal-1)/5 + 1;        
00231       expXtalID   =  numbXtal - (expStripID-1)*5;
00232     }
00233     
00234     statusUnpackXtal = unpackXtalData(expStripID,expXtalID);
00235     if (statusUnpackXtal== SKIP_BLOCK_UNPACKING)
00236       {
00237         if( ! DCCDataUnpacker::silentMode_ ){
00238             edm::LogWarning("IncorrectBlock")
00239             <<"For event L1A "<<event_->l1A()<<" and fed "<<mapper_->getActiveDCC()
00240             <<"\n The tower "<<towerId_<<" won't be unpacked further";
00241         }
00242       }
00243 
00244   }// end loop over xtals of given FE 
00245 
00246   updateEventPointers();
00247   return BLOCK_UNPACKED;                
00248   
00249 }
00250 
00251 
00252 
00253 
00254 void DCCFEBlock::display(std::ostream& o){
00255 
00256   o<<"\n Unpacked Info for DCC Tower Block"
00257   <<"\n DW1 ============================="
00258   <<"\n Tower Id "<<towerId_
00259   <<"\n Numb Samp "<<nTSamples_
00260   <<"\n Bx "<<bx_
00261   <<"\n L1 "<<l1_
00262   <<"\n blockLength "<<blockLength_;  
00263 } 
00264 
00265