Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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