CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/EventFilter/EcalRawToDigi/src/DCCSCBlock.cc

Go to the documentation of this file.
00001 #include "EventFilter/EcalRawToDigi/interface/DCCSCBlock.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 DCCSCBlock::DCCSCBlock( DCCDataUnpacker * u,EcalElectronicsMapper * m , DCCEventBlock * e, bool unpack, bool forceToKeepFRdata)
00010 : DCCFEBlock(u,m,e,unpack,forceToKeepFRdata){}
00011 
00012 
00013 void DCCSCBlock::updateCollectors(){
00014 
00015   DCCFEBlock::updateCollectors();
00016   
00017   // needs to be update for eb/ee
00018   digis_               = unpacker_->eeDigisCollection();
00019 
00020   invalidGains_        = unpacker_->invalidEEGainsCollection();
00021   invalidGainsSwitch_  = unpacker_->invalidEEGainsSwitchCollection();
00022   invalidChIds_        = unpacker_->invalidEEChIdsCollection();
00023 
00024 }
00025 
00026 
00027 
00028 
00029 int DCCSCBlock::unpackXtalData(unsigned int expStripID, unsigned int expXtalID){
00030   
00031   bool errorOnXtal(false);
00032  
00033   const uint16_t * xData_= reinterpret_cast<const uint16_t *>(data_);
00034 
00035  
00036   // Get xtal data ids
00037   unsigned int stripId = (*xData_) & TOWER_STRIPID_MASK;
00038   unsigned int xtalId  =((*xData_)>>TOWER_XTALID_B ) & TOWER_XTALID_MASK;
00039   
00040   // std::cout<<"\n DEBUG : unpacked xtal data for strip id "<<stripId<<" and xtal id "<<xtalId<<std::endl;
00041   // std::cout<<"\n DEBUG : expected strip id "<<expStripID<<" expected xtal id "<<expXtalID<<std::endl;
00042   
00043 
00044   if( !zs_ && (expStripID != stripId || expXtalID != xtalId)){ 
00045 
00046     if( ! DCCDataUnpacker::silentMode_ ){         
00047       edm::LogWarning("IncorrectBlock")
00048         <<"For event LV1: "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower "<<towerId_
00049         <<"\n The expected strip is "<<expStripID<<" and "<<stripId<<" was found"
00050         <<"\n The expected xtal  is "<<expXtalID <<" and "<<xtalId<<" was found";        
00051      }
00052     
00053     
00054     // using expected cry_di to raise warning about xtal_id problem
00055     pDetId_ = (EEDetId*) mapper_->getDetIdPointer(towerId_,expStripID,expXtalID);
00056     if(pDetId_) {  (*invalidChIds_)->push_back(*pDetId_); }
00057     
00058     stripId = expStripID;
00059     xtalId  = expXtalID;
00060     errorOnXtal = true;
00061     
00062     // return here, so to skip all following checks
00063     data_ += numbDWInXtalBlock_;
00064     return BLOCK_UNPACKED;
00065   }
00066 
00067 
00068   // check id in case of 0suppressed data
00069 
00070   else if(zs_) {
00071 
00072     // Check for valid Ids 1) values out of range
00073 
00074     if (stripId == 0 || stripId > 5 || xtalId == 0 || xtalId > 5) {
00075       
00076       if (! DCCDataUnpacker::silentMode_ ) {
00077         edm::LogWarning("IncorrectBlock")
00078           <<"For event LV1: "<<event_->l1A()<<", fed "<<mapper_->getActiveDCC()<<" and tower "<<towerId_
00079           <<"\n Invalid strip : "<<stripId<<" or xtal : "<<xtalId
00080           <<" ids ( last strip was: " << lastStripId_ << " last ch was: " << lastXtalId_ << ")";
00081        }
00082       
00083       int st = lastStripId_;
00084       int ch = lastXtalId_;
00085       ch++;
00086       if (ch > NUMB_XTAL)         {ch=1; st++;}
00087       if (st > NUMB_STRIP)        {ch=1; st=1;}
00088 
00089       // adding channel following the last valid
00090       //pDetId_ = (EEDetId*) mapper_->getDetIdPointer(towerId_,st,ch);
00091       //(*invalidChIds_)->push_back(*pDetId_);
00092       fillEcalElectronicsError(invalidZSXtalIds_); 
00093       errorOnXtal = true;
00094 
00095       lastStripId_ = st;
00096       lastXtalId_  = ch;
00097 
00098       // return here, so to skip all following checks
00099       return SKIP_BLOCK_UNPACKING;
00100     }
00101     else {
00102       // Check for zs valid Ids 2) if channel-in-strip has increased wrt previous xtal
00103       //                        3) if strip has increased wrt previous xtal
00104       if ((stripId == lastStripId_ && xtalId <= lastXtalId_ ) ||
00105           (stripId < lastStripId_))
00106         {
00107           if (! DCCDataUnpacker::silentMode_) {
00108             edm::LogWarning("IncorrectBlock")
00109               << "Xtal id was expected to increase but it didn't - last xtal id was " << lastXtalId_ << " while current xtal is " << xtalId
00110               << " (LV1 " << event_->l1A() << " fed " << mapper_->getActiveDCC() << " tower " << towerId_ << ")";
00111           }
00112           
00113           int st = lastStripId_;
00114           int ch = lastXtalId_;
00115           ch++;
00116           if (ch > NUMB_XTAL)        {ch=1; st++;}
00117           if (st > NUMB_STRIP)        {ch=1; st=1;}
00118           
00119           // adding channel following the last valid
00120           //pDetId_ = (EEDetId*) mapper_->getDetIdPointer(towerId_,stripId,xtalId);
00121           //(*invalidChIds_)->push_back(*pDetId_);
00122           fillEcalElectronicsError(invalidZSXtalIds_); 
00123            
00124            errorOnXtal = true;
00125            lastStripId_ = st;
00126            lastXtalId_  = ch;
00127            
00128            // return here, so to skip all following checks
00129            return SKIP_BLOCK_UNPACKING;
00130 
00131         }
00132         
00133       lastStripId_  = stripId;
00134       lastXtalId_   = xtalId;
00135     }// end else
00136   }// end if(zs_)
00137  
00138   bool addedFrame=false;
00139   
00140   // if there is an error on xtal id ignore next error checks  
00141   // otherwise, assume channel_id is valid and proceed with making and checking the data frame
00142   if(errorOnXtal) return SKIP_BLOCK_UNPACKING;
00143   
00144   pDetId_ = (EEDetId*) mapper_->getDetIdPointer(towerId_, stripId, xtalId);
00145   
00146   if(pDetId_){// checking that requested EEDetId exists
00147     
00148     (*digis_)->push_back(*pDetId_);
00149     EEDataFrame df( (*digis_)->back() );
00150     addedFrame=true;
00151     bool wrongGain(false);
00152     
00153     //set samples in the frame
00154     for(unsigned int i =0; i< nTSamples_ ;i++){ 
00155       xData_++;
00156       unsigned int data =  (*xData_) & TOWER_DIGI_MASK;
00157       unsigned int gain =  data>>12;
00158       xtalGains_[i]=gain;
00159       if(gain == 0){          wrongGain = true; }      // although gain==0 found, produce the dataFrame in order to have it, for saturation case
00160       df.setSample(i,data);
00161     }
00162     
00163     bool isSaturation(true);
00164     if(wrongGain){
00165       
00166       // check whether the gain==0 has features of saturation or not 
00167       // gain==0 occurs either in case of data corruption or of ADC saturation 
00168       //                                  \->reject digi            \-> keep digi 
00169       
00170       // determine where gainId==0 starts
00171       short firstGainZeroSampID(-1);    short firstGainZeroSampADC(-1);
00172       for (unsigned int s=0; s<nTSamples_; s++ ) {
00173         if(df.sample(s).gainId()==0 && firstGainZeroSampID==-1)
00174           {
00175           firstGainZeroSampID  = s;
00176           firstGainZeroSampADC = df.sample(s).adc();
00177           break;
00178           }
00179       }
00180       
00181     // check whether gain==0 and adc() stays constant for (at least) 5 consecutive samples
00182     unsigned int plateauEnd = std::min(nTSamples_,(unsigned int)(firstGainZeroSampID+5));
00183     for (unsigned int s=firstGainZeroSampID; s<plateauEnd; s++) 
00184       {
00185         if( df.sample(s).gainId()==0 && df.sample(s).adc()==firstGainZeroSampADC ) {;}
00186         else
00187           { isSaturation=false;   break;}  //it's not saturation
00188       }
00189     // get rid of channels which are stuck in gain0
00190     if(firstGainZeroSampID<3) {isSaturation=false; }
00191 
00192     if (! DCCDataUnpacker::silentMode_) {
00193       if (unpacker_->getChannelValue(mapper_->getActiveDCC(), towerId_, stripId, xtalId) != 10) {
00194         edm::LogWarning("IncorrectBlock")
00195           << "Gain zero" << (isSaturation ? " with features of saturation" : "" ) << " was found in SC Block"
00196           << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC()
00197           << " tower " << towerId_ << " strip " << stripId << " xtal " << xtalId << ")";
00198       }
00199     }
00200     
00201     if (! isSaturation)
00202       {     
00203         (*invalidGains_)->push_back(*pDetId_); 
00204         (*digis_)->pop_back();
00205         errorOnXtal = true;
00206         
00207         //return here, so to skip all the rest
00208         //make special collection for gain0 data frames (saturation)
00209         //Point to begin of next xtal Block
00210         data_ += numbDWInXtalBlock_;
00211         
00212         return BLOCK_UNPACKED;
00213         
00214       }//end isSaturation 
00215     else {
00216             data_ += numbDWInXtalBlock_;
00217             return BLOCK_UNPACKED;
00218     }
00219     }//end WrongGain
00220     
00221     short firstGainWrong=-1;
00222     short numGainWrong=0;
00223     
00224     for (unsigned int i=1; i<nTSamples_; i++ ) {
00225       if (xtalGains_[i-1]>xtalGains_[i]) {
00226         numGainWrong++;
00227         
00228         if (firstGainWrong == -1) { firstGainWrong=i;}
00229       }
00230     }
00231     
00232     if (numGainWrong > 0) {
00233       if (! DCCDataUnpacker::silentMode_) {
00234         edm::LogWarning("IncorrectBlock")
00235           << "A wrong gain transition switch was found for SC Block in strip " << stripId << " and xtal " << xtalId
00236           << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << " tower " << towerId_ << ")";
00237       }
00238       
00239       (*invalidGainsSwitch_)->push_back(*pDetId_);
00240       
00241       errorOnXtal = true;
00242     }
00243     
00244     //Add frame to collection only if all data format and gain rules are respected
00245     if (errorOnXtal && addedFrame) {
00246       (*digis_)->pop_back();
00247     }
00248     
00249   }// End 'if EE id exist'
00250   
00251   else {
00252     // in case EEDetId do not exist
00253     // In EE we may have crystals with no valid EEDetId
00254     if (! mapper_->isGhost(mapper_->getActiveDCC(), towerId_, stripId)) { // check the VFE is not a 'ghost'
00255       
00256       // this is real EE VFE - print warning
00257       if (! DCCDataUnpacker::silentMode_) {
00258         edm::LogWarning("IncorrectBlock")
00259           << "An EEDetId was requested that does not exist "
00260           << "(LV1 " << event_->l1A()
00261           << " fed " << mapper_->getActiveDCC()
00262           << " tower " << towerId_
00263           << " strip " << stripId
00264           << " xtal " << xtalId << ")";
00265       }
00266     }
00267   }
00268   
00269   //Point to begin of next xtal Block
00270   data_ += numbDWInXtalBlock_;
00271   
00272   return BLOCK_UNPACKED;
00273 }
00274 
00275 
00276 void DCCSCBlock::fillEcalElectronicsError( std::auto_ptr<EcalElectronicsIdCollection> * errorColection){
00277 
00278   const int activeDCC = mapper_->getActiveSM();
00279 
00280   if ( (NUMB_SM_EE_MIN_MIN <=activeDCC && activeDCC<=NUMB_SM_EE_MIN_MAX) ||
00281          (NUMB_SM_EE_PLU_MIN <=activeDCC && activeDCC<=NUMB_SM_EE_PLU_MAX) ){
00282      EcalElectronicsId  *  eleTp = mapper_->getSCElectronicsPointer(activeDCC,expTowerID_);
00283      (*errorColection)->push_back(*eleTp);
00284   }else{
00285      if( ! DCCDataUnpacker::silentMode_ ){
00286        edm::LogWarning("IncorrectBlock")
00287          <<"For event "<<event_->l1A()<<" there's fed: "<< activeDCC
00288          <<" activeDcc: "<<mapper_->getActiveSM()
00289          <<" but that activeDcc is not valid in EE.";
00290      }
00291   }
00292 
00293 }