CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/EventFilter/EcalRawToDigi/src/DCCMemBlock.cc

Go to the documentation of this file.
00001 #include "EventFilter/EcalRawToDigi/interface/DCCMemBlock.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 DCCMemBlock::DCCMemBlock( DCCDataUnpacker * u,EcalElectronicsMapper * m, DCCEventBlock * e) 
00010 :DCCDataBlockPrototype(u,m,e)
00011 {
00012 
00013   unfilteredTowerBlockLength_  = mapper_->getUnfilteredTowerBlockLength();
00014   expXtalTSamples_             = mapper_->numbXtalTSamples();
00015 
00016   numbDWInXtalBlock_           = (expXtalTSamples_-2)/4+1;
00017   xtalBlockSize_               = numbDWInXtalBlock_*8;
00018   kSamplesPerPn_               = expXtalTSamples_*5;  
00019   
00020   unsigned int numbOfXtalBlocks        = (unfilteredTowerBlockLength_-1)/numbDWInXtalBlock_; 
00021   unsigned int numbOfPnBlocks          = numbOfXtalBlocks/5; //change 5 by a variable
00022   unsigned int vectorSize              = numbOfPnBlocks*10*expXtalTSamples_;
00023 
00024   //Build pnDiodevector
00025   for(unsigned int i =0; i< vectorSize; i++){ pn_.push_back(-1);}
00026 
00027 }
00028 
00029 void DCCMemBlock::updateCollectors(){
00030 
00031   invalidMemChIds_             = unpacker_->invalidMemChIdsCollection();
00032   invalidMemBlockSizes_        = unpacker_->invalidMemBlockSizesCollection();
00033   invalidMemTtIds_             = unpacker_->invalidMemTtIdsCollection();
00034   invalidMemGains_             = unpacker_->invalidMemGainsCollection();
00035   pnDiodeDigis_                = unpacker_->pnDiodeDigisCollection();
00036 
00037 }
00038 
00039 
00040 
00041 int DCCMemBlock::unpack(uint64_t ** data, unsigned int * dwToEnd, unsigned int expectedTowerID){
00042   
00043   error_   = false;  
00044   datap_   = data;
00045   data_    = *data;
00046   dwToEnd_ = dwToEnd;
00047 
00048  
00049   if( (*dwToEnd_)<1){
00050     if( ! DCCDataUnpacker::silentMode_ ){
00051       edm::LogWarning("IncorrectEvent")
00052         <<"\nUnable to unpack MEM block for event "<<event_->l1A()<<" in fed "<<mapper_->getActiveDCC()
00053         <<"\nThe end of event was reached !";
00054     }
00055     return STOP_EVENT_UNPACKING;
00056   }
00057   
00058   lastStripId_     = 0;
00059   lastXtalId_      = 0;
00060   expTowerID_      = expectedTowerID;
00061   
00062   
00063   //Point to begin of block
00064   data_++;
00065   
00066   towerId_           = ( *data_ ) & TOWER_ID_MASK;
00067   nTSamples_         = ( *data_>>TOWER_NSAMP_B  ) & TOWER_NSAMP_MASK; 
00068   bx_                = ( *data_>>TOWER_BX_B     ) & TOWER_BX_MASK;
00069   l1_                = ( *data_>>TOWER_L1_B     ) & TOWER_L1_MASK;
00070   blockLength_       = ( *data_>>TOWER_LENGTH_B ) & TOWER_LENGTH_MASK;
00071  
00072   event_->setFESyncNumbers(l1_,bx_,short(expectedTowerID-1));
00073 
00074  
00075   //debugging
00076   //display(cout);
00077 
00078   // Block Length Check (1)
00079   if ( unfilteredTowerBlockLength_ != blockLength_ ){    
00080    
00081     // chosing channel 1 as representative of a dummy...
00082     EcalElectronicsId id( mapper_->getActiveSM() , expTowerID_,1, 1);
00083     (*invalidMemBlockSizes_)->push_back(id);
00084     if( ! DCCDataUnpacker::silentMode_ ){ 
00085       edm::LogWarning("IncorrectEvent")
00086         <<"\nFor event "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower block "<<towerId_
00087         <<"\nExpected mem block size is "<<(unfilteredTowerBlockLength_*8)<<" bytes while "<<(blockLength_*8)<<" was found";
00088     }
00089     return STOP_EVENT_UNPACKING;
00090     
00091   }
00092   
00093   // Block Length Check (2)
00094   if((*dwToEnd_)<blockLength_){
00095     if( ! DCCDataUnpacker::silentMode_ ){
00096       edm::LogWarning("IncorrectEvent")
00097         <<"\nUnable to unpack MEM block for event "<<event_->l1A()<<" in fed "<<mapper_->getActiveDCC()
00098         <<"\n Only "<<((*dwToEnd_)*8)<<" bytes are available while "<<(blockLength_*8)<<" are needed!";
00099       // chosing channel 1 as representative of a dummy...
00100     } 
00101     EcalElectronicsId id( mapper_->getActiveSM() , expTowerID_,1, 1);
00102     (*invalidMemBlockSizes_)->push_back(id);
00103     return STOP_EVENT_UNPACKING;
00104   }
00105   
00106   // Synchronization Check 
00107   if(sync_){
00108     const unsigned int dccBx = ( event_->bx()) & TOWER_BX_MASK;
00109     const unsigned int dccL1 = ( event_->l1A() ) & TOWER_L1_MASK;
00110     const unsigned int fov   = ( event_->fov() ) & H_FOV_MASK;
00111     
00112     if (! isSynced(dccBx, bx_, dccL1, l1_, FE_MEM, fov)) {
00113       if( ! DCCDataUnpacker::silentMode_ ){
00114         edm::LogWarning("IncorrectEvent")
00115           << "Synchronization error for Mem block"
00116           << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << ")\n"
00117           << "  dccBx = " << dccBx << " bx_ = " << bx_ << " dccL1 = " << dccL1 << " l1_ = " << l1_ << "\n"
00118           << "  => Stop event unpacking";
00119       }
00120       //Note : add to error collection ?
00121       // need of a new collection
00122       return STOP_EVENT_UNPACKING;
00123     }
00124   }  
00125   
00126   // Number Of Samples Check
00127   if( nTSamples_ != expXtalTSamples_ ){
00128     if( ! DCCDataUnpacker::silentMode_ ){
00129       edm::LogWarning("IncorrectEvent")
00130         <<"\nUnable to unpack MEM block for event "<<event_->l1A()<<" in fed "<<mapper_->getActiveDCC()
00131         <<"\nNumber of time samples "<<nTSamples_<<" is not the same as expected ("<<expXtalTSamples_<<")";
00132      }
00133     //Note : add to error collection ?           
00134     return STOP_EVENT_UNPACKING;
00135   }
00136   
00137   
00138   //Channel Id Check
00139   if( expTowerID_ != towerId_){
00140     
00141     // chosing channel 1 as representative as a dummy...
00142     EcalElectronicsId id( mapper_->getActiveSM() , expTowerID_, 1,1);
00143     (*invalidMemTtIds_)->push_back(id);
00144     if( ! DCCDataUnpacker::silentMode_ ){
00145       edm::LogWarning("IncorrectBlock")
00146         <<"For event "<<event_->l1A()<<" and fed "<<mapper_->getActiveDCC() << " and sm: "  << mapper_->getActiveSM()
00147         <<"\nExpected mem tower block is "<<expTowerID_<<" while "<<towerId_<<" was found ";
00148      }
00149     
00150     towerId_=expTowerID_;
00151     
00152     // todo : go to the next mem
00153     error_= true;
00154         
00155         updateEventPointers();
00156         return SKIP_BLOCK_UNPACKING;
00157   }
00158    
00159  
00160   //point to xtal data
00161   data_++;
00162                                
00163   
00164   unpackMemTowerData();
00165   
00166   if(!error_){ fillPnDiodeDigisCollection();}
00167 
00168   updateEventPointers();
00169   
00170   return BLOCK_UNPACKED;
00171      
00172 }
00173 
00174 
00175 
00176 void DCCMemBlock::unpackMemTowerData(){
00177   
00178     
00179   //todo: move EcalPnDiodeDetId to electronics mapper
00180 
00181 
00182   lastTowerBeforeMem_ = 0;
00183   // differentiating the barrel and the endcap case
00184   if (9 < mapper_->getActiveSM() || mapper_->getActiveSM() < 46){
00185     lastTowerBeforeMem_ = 69; }
00186   else {
00187     lastTowerBeforeMem_ = 69; } 
00188   
00189 
00190   for(unsigned int expStripId = 1; expStripId<= 5; expStripId++){
00191 
00192     for(unsigned int expXtalId = 1; expXtalId <= 5; expXtalId++){
00193          
00194       uint16_t * xData_= reinterpret_cast<uint16_t *>(data_);
00195  
00196       // Get xtal data ids
00197       unsigned int stripId = (*xData_) & TOWER_STRIPID_MASK;
00198       unsigned int xtalId  =((*xData_)>>TOWER_XTALID_B ) & TOWER_XTALID_MASK;
00199    
00200       bool errorOnDecoding(false);
00201           
00202       if(expStripId != stripId || expXtalId != xtalId){
00203 
00204         // chosing channel and strip as EcalElectronicsId
00205         EcalElectronicsId id( mapper_->getActiveSM() , towerId_, expStripId, expXtalId);
00206        (*invalidMemChIds_)->push_back(id);
00207       
00208         if( ! DCCDataUnpacker::silentMode_ ){
00209           edm::LogWarning("IncorrectBlock")
00210             <<"For event "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower mem block "<<towerId_
00211             <<"\nThe expected strip is "<<expStripId<<" and "<<stripId<<" was found"
00212             <<"\nThe expected xtal  is "<<expXtalId <<" and "<<xtalId<<" was found";
00213         }
00214 
00215         stripId = expStripId;
00216         xtalId  = expXtalId;
00217                  
00218 
00219 
00220          errorOnDecoding = true; 
00221         
00222        //Note : move to the next ...   
00223                  
00224      }
00225          
00226      unsigned int ipn, index;
00227                 
00228      if((stripId-1)%2==0){ ipn = (towerId_-lastTowerBeforeMem_)*5 + xtalId - 1; }
00229      else                { ipn = (towerId_-lastTowerBeforeMem_)*5 + 5 - xtalId; }
00230          
00231                 
00232       //Cooking samples
00233       for(unsigned int i =0; i< nTSamples_ ;i++){ 
00234       
00235         xData_++;
00236                   
00237         index = ipn*50 + (stripId-1)*nTSamples_+i;
00238                  
00239             //edm::LogDebug("EcalRawToDigiMemChId")<<"\n Strip id "<<std::dec<<stripId<<" Xtal id "<<xtalId
00240             //  <<" tsamp = "<<i<<" 16b = 0x "<<std::hex<<(*xData_)<<dec;
00241            
00242         unsigned int temp = (*xData_)&TOWER_DIGI_MASK;
00243                 
00244              short sample(0);
00245                 
00246                 
00247         if( (stripId-1)%2 ) {
00248              
00249           // If strip number is even, 14 bits are reversed in order
00250                for(int ib=0;ib<14;ib++){ 
00251                  sample <<= 1;
00252                  sample |= (temp&1);
00253                  temp  >>= 1;
00254                }
00255                         
00256         } else { sample=temp;}
00257         
00258              sample   ^=  0x800;
00259         unsigned int gain =  sample>>12;
00260                         
00261         if( gain >= 2 ){
00262 
00263           EcalElectronicsId id(mapper_->getActiveSM() , towerId_, stripId,xtalId);
00264           (*invalidMemGains_)->push_back(id);
00265           
00266            if( ! DCCDataUnpacker::silentMode_ ){
00267               edm::LogWarning("IncorrectBlock")
00268                <<"For event "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" , mem tower block "<<towerId_
00269                <<"\nIn strip "<<stripId<<" xtal "<<xtalId<<" the gain is "<<gain<<" in sample "<<(i+1);
00270            }
00271 
00272           errorOnDecoding=true;
00273         }
00274                 
00275         if( !errorOnDecoding && !error_){pn_[index]=sample;} //Note : move to the next versus flag...
00276                  
00277       }// loop over samples ended
00278         
00279       data_ += numbDWInXtalBlock_;
00280     }//loop over xtals
00281   }// loop over strips
00282          
00283 
00284 }
00285 
00286 void DCCMemBlock::fillPnDiodeDigisCollection(){
00287  
00288   //todo change pnId max
00289   for (int pnId=1; pnId<=5; pnId++){
00290     bool errorOnPn(false);
00291     unsigned int realPnId = pnId;
00292     
00293     if(towerId_==70){ realPnId += 5;}
00294          
00295     // Note : we are assuming always 5 VFE channels enabled 
00296     // This means we all have 5 pns per tower 
00297 
00298     // solution before sending creation of PnDigi's in mapper as done with crystals
00299     //     mapper_->getActiveSM()  : this is the 'dccid'
00300     //     number ranging internally in ECAL from 1 to 54, according convention specified here:
00301     //     https://indico.cern.ch/getFile.py/access?contribId=0&resId=0&materialId=slides&confId=11621
00302 
00303     //     mapper_->getActiveDCC() : this is the FED_id (601 - 654 for ECAL at CMS)
00304 
00305     const int activeSM = mapper_->getActiveSM();
00306     int subdet(0);
00307     if (NUMB_SM_EB_MIN_MIN <= activeSM && activeSM <= NUMB_SM_EB_PLU_MAX) {
00308       subdet = EcalBarrel;
00309     }
00310     else if( (NUMB_SM_EE_MIN_MIN <= activeSM && activeSM <= NUMB_SM_EE_MIN_MAX) ||
00311             (NUMB_SM_EE_PLU_MIN <= activeSM && activeSM <= NUMB_SM_EE_PLU_MAX) ) {
00312       subdet = EcalEndcap;
00313     }
00314     else {
00315       if( ! DCCDataUnpacker::silentMode_ ){
00316         edm::LogWarning("IncorrectMapping")
00317           <<"\n mapper points to non existing dccid: " << activeSM;
00318       }
00319     }
00320 
00321 
00322     EcalPnDiodeDetId PnId(subdet, activeSM, realPnId );
00323     
00324     EcalPnDiodeDigi thePnDigi(PnId );
00325     thePnDigi.setSize(kSamplesPerPn_);
00326     
00327     
00328     for (unsigned int ts =0; ts <kSamplesPerPn_; ts++){
00329       
00330       short pnDiodeData = pn_[(towerId_-lastTowerBeforeMem_)*250 + (pnId-1)*kSamplesPerPn_ + ts];
00331       if( pnDiodeData == -1){
00332         errorOnPn=true;
00333              break;
00334       }
00335          
00336       EcalFEMSample thePnSample(pnDiodeData );
00337       thePnDigi.setSample(ts, thePnSample );  
00338     }
00339     
00340     if(!errorOnPn){ (*pnDiodeDigis_)->push_back(thePnDigi);}
00341   
00342   }
00343   
00344 } 
00345 
00346 
00347 
00348 void DCCMemBlock::display(std::ostream& o){
00349 
00350   o<<"\n Unpacked Info for DCC MEM Block"
00351   <<"\n DW1 ============================="
00352   <<"\n Mem Tower Block Id "<<towerId_
00353   <<"\n Numb Samp "<<nTSamples_
00354   <<"\n Bx "<<bx_
00355   <<"\n L1 "<<l1_
00356   <<"\n blockLength "<<blockLength_;  
00357 } 
00358 
00359 
00360 
00361