Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:09

0001 #include "EventFilter/EcalRawToDigi/interface/DCCSCBlock.h"
0002 #include "EventFilter/EcalRawToDigi/interface/DCCEventBlock.h"
0003 #include "EventFilter/EcalRawToDigi/interface/DCCDataUnpacker.h"
0004 #include <cstdio>
0005 #include "EventFilter/EcalRawToDigi/interface/EcalElectronicsMapper.h"
0006 
0007 DCCSCBlock::DCCSCBlock(
0008     DCCDataUnpacker *u, EcalElectronicsMapper *m, DCCEventBlock *e, bool unpack, bool forceToKeepFRdata)
0009     : DCCFEBlock(u, m, e, unpack, forceToKeepFRdata) {}
0010 
0011 void DCCSCBlock::updateCollectors() {
0012   DCCFEBlock::updateCollectors();
0013 
0014   // needs to be update for eb/ee
0015   digis_ = unpacker_->eeDigisCollection();
0016 
0017   invalidGains_ = unpacker_->invalidEEGainsCollection();
0018   invalidGainsSwitch_ = unpacker_->invalidEEGainsSwitchCollection();
0019   invalidChIds_ = unpacker_->invalidEEChIdsCollection();
0020 }
0021 
0022 int DCCSCBlock::unpackXtalData(unsigned int expStripID, unsigned int expXtalID) {
0023   bool errorOnXtal(false);
0024 
0025   const uint16_t *xData_ = reinterpret_cast<const uint16_t *>(data_);
0026 
0027   // Get xtal data ids
0028   unsigned int stripId = (*xData_) & TOWER_STRIPID_MASK;
0029   unsigned int xtalId = ((*xData_) >> TOWER_XTALID_B) & TOWER_XTALID_MASK;
0030 
0031   // std::cout<<"\n DEBUG : unpacked xtal data for strip id "<<stripId<<" and xtal id "<<xtalId<<std::endl;
0032   // std::cout<<"\n DEBUG : expected strip id "<<expStripID<<" expected xtal id "<<expXtalID<<std::endl;
0033 
0034   if (!zs_ && (expStripID != stripId || expXtalID != xtalId)) {
0035     if (!DCCDataUnpacker::silentMode_) {
0036       edm::LogWarning("IncorrectBlock") << "For event LV1: " << event_->l1A() << ", fed " << mapper_->getActiveDCC()
0037                                         << " and tower " << towerId_ << "\n The expected strip is " << expStripID
0038                                         << " and " << stripId << " was found"
0039                                         << "\n The expected xtal  is " << expXtalID << " and " << xtalId
0040                                         << " was found";
0041     }
0042 
0043     // using expected cry_di to raise warning about xtal_id problem
0044     pDetId_ = (EEDetId *)mapper_->getDetIdPointer(towerId_, expStripID, expXtalID);
0045     if (pDetId_) {
0046       (*invalidChIds_)->push_back(*pDetId_);
0047     }
0048 
0049     // return here, so to skip all following checks
0050     data_ += numbDWInXtalBlock_;
0051     return BLOCK_UNPACKED;
0052   }
0053 
0054   // check id in case of 0suppressed data
0055 
0056   else if (zs_) {
0057     // Check for valid Ids 1) values out of range
0058 
0059     if (stripId == 0 || stripId > 5 || xtalId == 0 || xtalId > 5) {
0060       if (!DCCDataUnpacker::silentMode_) {
0061         edm::LogWarning("IncorrectBlock")
0062             << "For event LV1: " << event_->l1A() << ", fed " << mapper_->getActiveDCC() << " and tower " << towerId_
0063             << "\n Invalid strip : " << stripId << " or xtal : " << xtalId << " ids ( last strip was: " << lastStripId_
0064             << " last ch was: " << lastXtalId_ << ")";
0065       }
0066 
0067       int st = lastStripId_;
0068       int ch = lastXtalId_;
0069       ch++;
0070       if (ch > NUMB_XTAL) {
0071         ch = 1;
0072         st++;
0073       }
0074       if (st > NUMB_STRIP) {
0075         ch = 1;
0076         st = 1;
0077       }
0078 
0079       // adding channel following the last valid
0080       //pDetId_ = (EEDetId*) mapper_->getDetIdPointer(towerId_,st,ch);
0081       //(*invalidChIds_)->push_back(*pDetId_);
0082       fillEcalElectronicsError(invalidZSXtalIds_);
0083 
0084       lastStripId_ = st;
0085       lastXtalId_ = ch;
0086 
0087       // return here, so to skip all following checks
0088       return SKIP_BLOCK_UNPACKING;
0089     } else {
0090       // Check for zs valid Ids 2) if channel-in-strip has increased wrt previous xtal
0091       //                        3) if strip has increased wrt previous xtal
0092       if ((stripId == lastStripId_ && xtalId <= lastXtalId_) || (stripId < lastStripId_)) {
0093         if (!DCCDataUnpacker::silentMode_) {
0094           edm::LogWarning("IncorrectBlock")
0095               << "Xtal id was expected to increase but it didn't - last xtal id was " << lastXtalId_
0096               << " while current xtal is " << xtalId << " (LV1 " << event_->l1A() << " fed " << mapper_->getActiveDCC()
0097               << " tower " << towerId_ << ")";
0098         }
0099 
0100         int st = lastStripId_;
0101         int ch = lastXtalId_;
0102         ch++;
0103         if (ch > NUMB_XTAL) {
0104           ch = 1;
0105           st++;
0106         }
0107         if (st > NUMB_STRIP) {
0108           ch = 1;
0109           st = 1;
0110         }
0111 
0112         // adding channel following the last valid
0113         //pDetId_ = (EEDetId*) mapper_->getDetIdPointer(towerId_,stripId,xtalId);
0114         //(*invalidChIds_)->push_back(*pDetId_);
0115         fillEcalElectronicsError(invalidZSXtalIds_);
0116 
0117         lastStripId_ = st;
0118         lastXtalId_ = ch;
0119 
0120         // return here, so to skip all following checks
0121         return SKIP_BLOCK_UNPACKING;
0122       }
0123 
0124       lastStripId_ = stripId;
0125       lastXtalId_ = xtalId;
0126     }  // end else
0127   }  // end if(zs_)
0128 
0129   bool addedFrame = false;
0130 
0131   // if there is an error on xtal id ignore next error checks
0132   // otherwise, assume channel_id is valid and proceed with making and checking the data frame
0133   if (errorOnXtal)
0134     return SKIP_BLOCK_UNPACKING;
0135 
0136   pDetId_ = (EEDetId *)mapper_->getDetIdPointer(towerId_, stripId, xtalId);
0137 
0138   if (pDetId_) {  // checking that requested EEDetId exists
0139 
0140     (*digis_)->push_back(*pDetId_);
0141     EEDataFrame df((*digis_)->back());
0142     addedFrame = true;
0143     bool wrongGain(false);
0144 
0145     //set samples in the frame
0146     for (unsigned int i = 0; i < nTSamples_; i++) {
0147       xData_++;
0148       unsigned int data = (*xData_) & TOWER_DIGI_MASK;
0149       unsigned int gain = data >> 12;
0150       xtalGains_[i] = gain;
0151       if (gain == 0) {
0152         wrongGain = true;
0153       }  // although gain==0 found, produce the dataFrame in order to have it, for saturation case
0154       df.setSample(i, data);
0155     }
0156 
0157     bool isSaturation(true);
0158     if (wrongGain) {
0159       // check whether the gain==0 has features of saturation or not
0160       // gain==0 occurs either in case of data corruption or of ADC saturation
0161       //                                  \->reject digi            \-> keep digi
0162 
0163       // determine where gainId==0 starts
0164       short firstGainZeroSampID(-1);
0165       short firstGainZeroSampADC(-1);
0166       for (unsigned int s = 0; s < nTSamples_; s++) {
0167         if (df.sample(s).gainId() == 0 && firstGainZeroSampID == -1) {
0168           firstGainZeroSampID = s;
0169           firstGainZeroSampADC = df.sample(s).adc();
0170           break;
0171         }
0172       }
0173 
0174       // check whether gain==0 and adc() stays constant for (at least) 5 consecutive samples
0175       unsigned int plateauEnd = std::min(nTSamples_, (unsigned int)(firstGainZeroSampID + 5));
0176       for (unsigned int s = firstGainZeroSampID; s < plateauEnd; s++) {
0177         if (df.sample(s).gainId() == 0 && df.sample(s).adc() == firstGainZeroSampADC) {
0178           ;
0179         } else {
0180           isSaturation = false;
0181           break;
0182         }  //it's not saturation
0183       }
0184       // get rid of channels which are stuck in gain0
0185       if (firstGainZeroSampID < 3) {
0186         isSaturation = false;
0187       }
0188 
0189       if (!DCCDataUnpacker::silentMode_) {
0190         if (unpacker_->getChannelValue(mapper_->getActiveDCC(), towerId_, stripId, xtalId) != 10) {
0191           edm::LogWarning("IncorrectGain")
0192               << "Gain zero" << (isSaturation ? " with features of saturation" : "") << " was found in SC Block"
0193               << " (L1A " << event_->l1A() << " bx " << event_->bx() << " fed " << mapper_->getActiveDCC() << " tower "
0194               << towerId_ << " strip " << stripId << " xtal " << xtalId << ")";
0195         }
0196       }
0197 
0198       if (!isSaturation) {
0199         (*invalidGains_)->push_back(*pDetId_);
0200         (*digis_)->pop_back();
0201 
0202         //return here, so to skip all the rest
0203         //make special collection for gain0 data frames (saturation)
0204         //Point to begin of next xtal Block
0205         data_ += numbDWInXtalBlock_;
0206 
0207         return BLOCK_UNPACKED;
0208 
0209       }  //end isSaturation
0210       else {
0211         data_ += numbDWInXtalBlock_;
0212         return BLOCK_UNPACKED;
0213       }
0214     }  //end WrongGain
0215 
0216     short firstGainWrong = -1;
0217     short numGainWrong = 0;
0218 
0219     for (unsigned int i = 1; i < nTSamples_; i++) {
0220       if (xtalGains_[i - 1] > xtalGains_[i]) {
0221         numGainWrong++;
0222 
0223         if (firstGainWrong == -1) {
0224           firstGainWrong = i;
0225         }
0226       }
0227     }
0228 
0229     if (numGainWrong > 0) {
0230       if (!DCCDataUnpacker::silentMode_) {
0231         edm::LogWarning("IncorrectGain") << "A wrong gain transition switch was found for SC Block in strip " << stripId
0232                                          << " and xtal " << xtalId << " (L1A " << event_->l1A() << " bx "
0233                                          << event_->bx() << " fed " << mapper_->getActiveDCC() << " tower " << towerId_
0234                                          << ")";
0235       }
0236 
0237       (*invalidGainsSwitch_)->push_back(*pDetId_);
0238 
0239       errorOnXtal = true;
0240     }
0241 
0242     //Add frame to collection only if all data format and gain rules are respected
0243     if (errorOnXtal && addedFrame) {
0244       (*digis_)->pop_back();
0245     }
0246 
0247   }  // End 'if EE id exist'
0248 
0249   else {
0250     // in case EEDetId do not exist
0251     // In EE we may have crystals with no valid EEDetId
0252     if (!mapper_->isGhost(mapper_->getActiveDCC(), towerId_, stripId)) {  // check the VFE is not a 'ghost'
0253 
0254       // this is real EE VFE - print warning
0255       if (!DCCDataUnpacker::silentMode_) {
0256         edm::LogWarning("IncorrectBlock") << "An EEDetId was requested that does not exist "
0257                                           << "(LV1 " << event_->l1A() << " fed " << mapper_->getActiveDCC() << " tower "
0258                                           << towerId_ << " strip " << stripId << " xtal " << xtalId << ")";
0259       }
0260     }
0261   }
0262 
0263   //Point to begin of next xtal Block
0264   data_ += numbDWInXtalBlock_;
0265 
0266   return BLOCK_UNPACKED;
0267 }
0268 
0269 void DCCSCBlock::fillEcalElectronicsError(std::unique_ptr<EcalElectronicsIdCollection> *errorColection) {
0270   const int activeDCC = mapper_->getActiveSM();
0271 
0272   if ((NUMB_SM_EE_MIN_MIN <= activeDCC && activeDCC <= NUMB_SM_EE_MIN_MAX) ||
0273       (NUMB_SM_EE_PLU_MIN <= activeDCC && activeDCC <= NUMB_SM_EE_PLU_MAX)) {
0274     EcalElectronicsId *eleTp = mapper_->getSCElectronicsPointer(activeDCC, expTowerID_);
0275     (*errorColection)->push_back(*eleTp);
0276   } else {
0277     if (!DCCDataUnpacker::silentMode_) {
0278       edm::LogWarning("IncorrectBlock") << "For event " << event_->l1A() << " there's fed: " << activeDCC
0279                                         << " activeDcc: " << mapper_->getActiveSM()
0280                                         << " but that activeDcc is not valid in EE.";
0281     }
0282   }
0283 }