CMS 3D CMS Logo

DCCMemBlock.cc

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

Generated on Tue Jun 9 17:34:37 2009 for CMSSW by  doxygen 1.5.4