Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-05 04:09:43

0001 #include "FWCore/Framework/interface/ESWatcher.h"
0002 #include "DQMOffline/CalibTracker/plugins/SiStripDQMPopConSourceHandler.h"
0003 #include "CondFormats/SiStripObjects/interface/SiStripBadStrip.h"
0004 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
0005 class FedChannelConnection;
0006 class SiStripFedCabling;
0007 
0008 /**
0009   @class SiStripPopConFEDErrorsHandlerFromDQM
0010   @author A.-M. Magnan, M. De Mattia
0011   @author P. David update to PopConSourceHandler and DQMEDHarvester
0012   @EDAnalyzer to read modules flagged by the DQM due to FED errors as bad and write in the database with the proper error flag.
0013 */
0014 class SiStripPopConFEDErrorsHandlerFromDQM : public SiStripDQMPopConSourceHandler<SiStripBadStrip> {
0015 public:
0016   typedef dqm::legacy::MonitorElement MonitorElement;
0017   typedef dqm::legacy::DQMStore DQMStore;
0018 
0019   explicit SiStripPopConFEDErrorsHandlerFromDQM(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& iC);
0020   ~SiStripPopConFEDErrorsHandlerFromDQM() override;
0021   // interface methods: implemented in template
0022   void initES(const edm::EventSetup& iSetup) override;
0023   void dqmEndJob(DQMStore::IBooker& booker, DQMStore::IGetter& getter) override;
0024   SiStripBadStrip* getObj() const override;
0025 
0026 private:
0027   void readHistogram(MonitorElement* aMe, unsigned int& aCounter, const float aNorm, const unsigned int aFedId);
0028 
0029   void addBadAPV(const FedChannelConnection& aConnection,
0030                  const unsigned short aAPVNumber,
0031                  const unsigned short aFlag,
0032                  unsigned int& aCounter);
0033 
0034   void addBadStrips(const FedChannelConnection& aConnection,
0035                     const unsigned int aDetId,
0036                     const unsigned short aApvNum,
0037                     const unsigned short aFlag,
0038                     unsigned int& aCounter);
0039 
0040   /// Writes the errors to the db
0041   void addErrors();
0042 
0043 private:
0044   double threshold_;
0045   unsigned int debug_;
0046   edm::ESGetToken<SiStripFedCabling, SiStripFedCablingRcd> fedCablingToken_;
0047   edm::ESWatcher<SiStripFedCablingRcd> fedCablingWatcher_;
0048   const SiStripFedCabling* cabling_;
0049   SiStripBadStrip obj_;
0050   std::map<uint32_t, std::vector<unsigned int> > detIdErrors_;
0051 };
0052 
0053 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0054 #include "CondFormats/SiStripObjects/interface/FedChannelConnection.h"
0055 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0056 #include "DQMServices/Core/interface/DQMStore.h"
0057 
0058 SiStripPopConFEDErrorsHandlerFromDQM::SiStripPopConFEDErrorsHandlerFromDQM(const edm::ParameterSet& iConfig,
0059                                                                            edm::ConsumesCollector&& iC)
0060     : SiStripDQMPopConSourceHandler<SiStripBadStrip>(iConfig),
0061       threshold_(iConfig.getUntrackedParameter<double>("Threshold", 0)),
0062       debug_(iConfig.getUntrackedParameter<unsigned int>("Debug", 0)),
0063       fedCablingToken_(iC.esConsumes<SiStripFedCabling, SiStripFedCablingRcd, edm::Transition::BeginRun>()) {
0064   edm::LogInfo("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::SiStripFEDErrorsDQM()]";
0065 }
0066 
0067 SiStripPopConFEDErrorsHandlerFromDQM::~SiStripPopConFEDErrorsHandlerFromDQM() {
0068   edm::LogInfo("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::~SiStripFEDErrorsDQM]";
0069 }
0070 
0071 void SiStripPopConFEDErrorsHandlerFromDQM::initES(const edm::EventSetup& iSetup) {
0072   if (fedCablingWatcher_.check(iSetup)) {
0073     cabling_ = &iSetup.getData(fedCablingToken_);
0074   }
0075 }
0076 
0077 void SiStripPopConFEDErrorsHandlerFromDQM::dqmEndJob(DQMStore::IBooker&, DQMStore::IGetter& getter) {
0078   obj_ = SiStripBadStrip();
0079 
0080   std::ostringstream lPath;
0081   lPath << "Run " << getRunNumber() << "/SiStrip/Run summary/ReadoutView/";
0082   const std::string lBaseDir = lPath.str();
0083 
0084   getter.setCurrentFolder(lBaseDir);
0085   LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] Now in " << lBaseDir << std::endl;
0086 
0087   std::vector<std::pair<std::string, unsigned int> > lFedsFolder;
0088   //for FED errors, use summary folder and fedId=0
0089   //do not put a slash or "goToDir" won't work...
0090   lFedsFolder.push_back(std::pair<std::string, unsigned int>("FedMonitoringSummary", 0));
0091 
0092   //for FE/channel/APV errors, they are written in a folder per FED,
0093   //if there was at least one error.
0094   //So just loop on folders and see which ones exist.
0095   for (unsigned int ifed(FEDNumbering::MINSiStripFEDID); ifed <= FEDNumbering::MAXSiStripFEDID;
0096        ifed++) {  //loop on FEDs
0097 
0098     std::ostringstream lFedDir;
0099     lFedDir << "FrontEndDriver" << ifed;
0100     if (!getter.dirExists(lFedDir.str()))
0101       continue;
0102     else {
0103       if (debug_)
0104         LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] - Errors detected for FED " << ifed
0105                                         << std::endl;
0106       lFedsFolder.push_back(std::pair<std::string, unsigned int>(lFedDir.str(), ifed));
0107     }
0108   }
0109   getter.cd();
0110 
0111   unsigned int nAPVsTotal = 0;
0112   //retrieve total number of APVs valid and connected from cabling:
0113   if (!cabling_) {
0114     edm::LogError("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] cabling not filled, return false "
0115                                          << std::endl;
0116     return;
0117   }
0118   auto lFedVec = cabling_->fedIds();
0119   for (unsigned int iFed(0); iFed < lFedVec.size(); iFed++) {
0120     if (*(lFedVec.begin() + iFed) < sistrip::FED_ID_MIN || *(lFedVec.begin() + iFed) > sistrip::FED_ID_MAX) {
0121       edm::LogError("SiStripFEDErrorsDQM")
0122           << "[SiStripFEDErrorsDQM::readBadAPVs] Invalid fedid : " << *(lFedVec.begin() + iFed) << std::endl;
0123       continue;
0124     }
0125     auto lConnVec = cabling_->fedConnections(*(lFedVec.begin() + iFed));
0126     for (unsigned int iConn(0); iConn < lConnVec.size(); iConn++) {
0127       const FedChannelConnection& lConnection = *(lConnVec.begin() + iConn);
0128       if (!lConnection.isConnected())
0129         continue;
0130       unsigned int lDetid = lConnection.detId();
0131       if (!lDetid || lDetid == sistrip::invalid32_)
0132         continue;
0133       //2 APVs per channel....
0134       nAPVsTotal += 2;
0135     }
0136   }
0137 
0138   edm::LogInfo("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] Total number of APVs found : "
0139                                       << nAPVsTotal << std::endl;
0140 
0141   unsigned int nAPVsWithErrorTotal = 0;
0142   unsigned int nFolders = 0;
0143   float lNorm = 0;
0144   for (const auto& iFolder : lFedsFolder) {
0145     const std::string lDirName = lBaseDir + "/" + iFolder.first;
0146     const unsigned int lFedId = iFolder.second;
0147 
0148     if (!getter.dirExists(lDirName))
0149       continue;
0150 
0151     std::vector<MonitorElement*> lMeVec = getter.getContents(lDirName);
0152 
0153     if (nFolders == 0) {
0154       for (auto iMe : lMeVec) {  //loop on ME found in directory
0155         std::string lMeName = iMe->getName();
0156         if (lMeName.find("nFEDErrors") != lMeName.npos) {
0157           lNorm = iMe->getEntries();
0158         }
0159       }
0160       //if norm histo has not been found, no point in continuing....
0161       if (lNorm < 1) {
0162         edm::LogError("SiStripFEDErrorsDQM")
0163             << "[SiStripFEDErrorsDQM::readBadAPVs] nFEDErrors not found, norm is " << lNorm << std::endl;
0164         return;
0165       }
0166     }
0167 
0168     unsigned int nAPVsWithError = 0;
0169     for (auto iMe : lMeVec) {  //loop on ME found in directory
0170       if (iMe->getEntries() == 0)
0171         continue;
0172       const std::string lMeName = iMe->getName();
0173 
0174       bool lookForErrors = false;
0175       if (nFolders == 0) {
0176         //for the first element of lFedsFolder: this is FED errors
0177         lookForErrors = lMeName.find("DataMissing") != lMeName.npos || lMeName.find("AnyFEDErrors") != lMeName.npos ||
0178                         (lMeName.find("CorruptBuffer") != lMeName.npos && lMeName.find("nFED") == lMeName.npos);
0179       } else {
0180         //for the others, it is channel or FE errors.
0181         lookForErrors = lMeName.find("APVAddressError") != lMeName.npos || lMeName.find("APVError") != lMeName.npos ||
0182                         lMeName.find("BadMajorityAddresses") != lMeName.npos ||
0183                         lMeName.find("FEMissing") != lMeName.npos || lMeName.find("OOSBits") != lMeName.npos ||
0184                         lMeName.find("UnlockedBits") != lMeName.npos;
0185       }
0186 
0187       if (lookForErrors)
0188         readHistogram(iMe, nAPVsWithError, lNorm, lFedId);
0189 
0190     }  //loop on ME found in directory
0191 
0192     nAPVsWithErrorTotal += nAPVsWithError;
0193     ++nFolders;
0194   }  //loop on lFedsFolders
0195 
0196   edm::LogInfo("SiStripFEDErrorsDQM")
0197       << "[SiStripFEDErrorsDQM::readBadAPVs] Total APVs with error found above threshold = " << nAPVsWithErrorTotal
0198       << std::endl;
0199 
0200   getter.cd();
0201 
0202   addErrors();
0203 }
0204 
0205 SiStripBadStrip* SiStripPopConFEDErrorsHandlerFromDQM::getObj() const { return new SiStripBadStrip(obj_); }
0206 
0207 void SiStripPopConFEDErrorsHandlerFromDQM::readHistogram(MonitorElement* aMe,
0208                                                          unsigned int& aCounter,
0209                                                          const float aNorm,
0210                                                          const unsigned int aFedId) {
0211   unsigned short lFlag = 0;
0212   std::string lMeName = aMe->getName();
0213   if (lMeName.find("DataMissing") != lMeName.npos) {
0214     lFlag = 0;
0215   } else if (lMeName.find("AnyFEDErrors") != lMeName.npos) {
0216     lFlag = 1;
0217   } else if (lMeName.find("CorruptBuffer") != lMeName.npos && lMeName.find("nFED") == lMeName.npos) {
0218     lFlag = 2;
0219   } else if (lMeName.find("FEMissing") != lMeName.npos) {
0220     lFlag = 3;
0221   } else if (lMeName.find("BadMajorityAddresses") != lMeName.npos) {
0222     lFlag = 4;
0223   } else if (lMeName.find("UnlockedBits") != lMeName.npos) {
0224     lFlag = 5;
0225   } else if (lMeName.find("OOSBits") != lMeName.npos) {
0226     lFlag = 6;
0227   } else if (lMeName.find("APVAddressError") != lMeName.npos) {
0228     lFlag = 7;
0229   } else if (lMeName.find("APVError") != lMeName.npos) {
0230     lFlag = 8;
0231   } else {
0232     edm::LogError("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readHistogramError] Shouldn't be here ..."
0233                                          << std::endl;
0234     return;
0235   }
0236 
0237   if (debug_) {
0238     LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readHistogramError] Reading histo : " << lMeName
0239                                     << ", flag = " << lFlag << std::endl;
0240   }
0241 
0242   unsigned int lNBins = aMe->getNbinsX();
0243   int lBinShift = 0;
0244   bool lIsFedHist = false;
0245   bool lIsAPVHist = false;
0246   bool lIsFeHist = false;
0247   bool lIsChHist = false;
0248 
0249   if (lNBins > 200) {
0250     lBinShift = FEDNumbering::MINSiStripFEDID - 1;  //shift for FED ID from bin number
0251     lIsFedHist = true;
0252   } else {
0253     lBinShift = -1;  //shift for channel/APV/FE id from bin number
0254     if (lNBins > 100)
0255       lIsAPVHist = true;
0256     else if (lNBins < 10)
0257       lIsFeHist = true;
0258     else
0259       lIsChHist = true;
0260   }
0261 
0262   if (debug_) {
0263     LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readHistogramError] lIsFedHist: " << lIsFedHist
0264                                     << std::endl
0265                                     << "[SiStripFEDErrorsDQM::readHistogramError] lIsAPVHist: " << lIsAPVHist
0266                                     << std::endl
0267                                     << "[SiStripFEDErrorsDQM::readHistogramError] lIsFeHist : " << lIsFeHist
0268                                     << std::endl
0269                                     << "[SiStripFEDErrorsDQM::readHistogramError] lIsChHist : " << lIsChHist
0270                                     << std::endl;
0271   }
0272 
0273   for (unsigned int ibin(1); ibin < lNBins + 1; ibin++) {
0274     if (aMe->getBinContent(ibin) > 0) {
0275       float lStat = aMe->getBinContent(ibin) * 1. / aNorm;
0276       if (lStat <= threshold_) {
0277         if (debug_)
0278           LogTrace("SiStripFEDErrorsDQM")
0279               << "[SiStripFEDErrorsDQM::readHistogramError] ---- Below threshold : " << lStat << std::endl;
0280         continue;
0281       }
0282       if (lIsFedHist) {
0283         unsigned int lFedId = ibin + lBinShift;
0284         //loop on all enabled channels of this FED....
0285         for (unsigned int iChId = 0; iChId < sistrip::FEDCH_PER_FED; iChId++) {  //loop on channels
0286           const FedChannelConnection& lConnection = cabling_->fedConnection(lFedId, iChId);
0287           if (!lConnection.isConnected())
0288             continue;
0289           addBadAPV(lConnection, 0, lFlag, aCounter);
0290         }
0291       } else {
0292         if (lIsFeHist) {
0293           unsigned int iFeId = ibin + lBinShift;
0294           //loop on all enabled channels of this FE....
0295           for (unsigned int iFeCh = 0; iFeCh < sistrip::FEDCH_PER_FEUNIT; iFeCh++) {  //loop on channels
0296             unsigned int iChId = sistrip::FEDCH_PER_FEUNIT * iFeId + iFeCh;
0297             const FedChannelConnection& lConnection = cabling_->fedConnection(aFedId, iChId);
0298             if (!lConnection.isConnected())
0299               continue;
0300             addBadAPV(lConnection, 0, lFlag, aCounter);
0301           }
0302         } else {
0303           unsigned int iChId = ibin + lBinShift;
0304           if (lIsAPVHist) {
0305             unsigned int iAPVid = iChId % 2 + 1;
0306             iChId = static_cast<unsigned int>(iChId / 2.);
0307             const FedChannelConnection& lConnection = cabling_->fedConnection(aFedId, iChId);
0308             addBadAPV(lConnection, iAPVid, lFlag, aCounter);
0309 
0310           }  //ifAPVhists
0311           else {
0312             const FedChannelConnection& lConnection = cabling_->fedConnection(aFedId, iChId);
0313             addBadAPV(lConnection, 0, lFlag, aCounter);
0314           }
0315         }  //if not FE hist
0316       }    //if not FED hist
0317     }      //if entries in histo
0318   }        //loop on bins
0319 }  //method readHistogram
0320 
0321 void SiStripPopConFEDErrorsHandlerFromDQM::addBadAPV(const FedChannelConnection& aConnection,
0322                                                      const unsigned short aAPVNumber,
0323                                                      const unsigned short aFlag,
0324                                                      unsigned int& aCounter) {
0325   if (!aConnection.isConnected()) {
0326     edm::LogWarning("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::addBadAPV] Warning, incompatible cabling ! "
0327                                               "Channel is not connected, but entry found in histo ... "
0328                                            << std::endl;
0329     return;
0330   }
0331   unsigned int lDetid = aConnection.detId();
0332   if (!lDetid || lDetid == sistrip::invalid32_) {
0333     edm::LogWarning("SiStripFEDErrorsDQM")
0334         << "[SiStripFEDErrorsDQM::addBadAPV] Warning, DetId is invalid: " << lDetid << std::endl;
0335     return;
0336   }
0337   //unsigned short nChInModule = aConnection.nApvPairs();
0338   unsigned short lApvNum = 0;
0339   if (aAPVNumber < 2) {
0340     lApvNum = 2 * aConnection.apvPairNumber();
0341     addBadStrips(aConnection, lDetid, lApvNum, aFlag, aCounter);
0342   }
0343   if (aAPVNumber == 0 || aAPVNumber == 2) {
0344     lApvNum = 2 * aConnection.apvPairNumber() + 1;
0345     addBadStrips(aConnection, lDetid, lApvNum, aFlag, aCounter);
0346   }
0347 }
0348 
0349 void SiStripPopConFEDErrorsHandlerFromDQM::addBadStrips(const FedChannelConnection& aConnection,
0350                                                         const unsigned int aDetId,
0351                                                         const unsigned short aApvNum,
0352                                                         const unsigned short aFlag,
0353                                                         unsigned int& aCounter) {
0354   // std::vector<unsigned int> lStripVector;
0355   const unsigned short lFirstBadStrip = aApvNum * 128;
0356   const unsigned short lConsecutiveBadStrips = 128;
0357 
0358   unsigned int lBadStripRange = obj_.encode(lFirstBadStrip, lConsecutiveBadStrips, aFlag);
0359 
0360   LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::addBadStrips] ---- Adding : detid " << aDetId << " (FED "
0361                                   << aConnection.fedId() << ", Ch " << aConnection.fedCh() << ")"
0362                                   << ", APV " << aApvNum << ", flag " << aFlag << std::endl;
0363 
0364   detIdErrors_[aDetId].push_back(lBadStripRange);
0365 
0366   // lStripVector.push_back(lBadStripRange);
0367   // SiStripBadStrip::Range lRange(lStripVector.begin(),lStripVector.end());
0368   // if ( !obj.put(aDetId,lRange) ) {
0369   //   edm::LogError("SiStripFEDErrorsDQM")<<"[SiStripFEDErrorsDQM::addBadStrips] detid already exists." << std::endl;
0370   // }
0371 
0372   aCounter++;
0373 }
0374 
0375 namespace {
0376   // set corresponding bit to 1 in flag
0377   inline void setFlagBit(unsigned short& aFlag, const unsigned short aBit) { aFlag = aFlag | (0x1 << aBit); }
0378 }  // namespace
0379 
0380 void SiStripPopConFEDErrorsHandlerFromDQM::addErrors() {
0381   for (const auto& it : detIdErrors_) {
0382     const std::vector<uint32_t>& lList = it.second;
0383 
0384     //map of first strip number and flag
0385     //purpose is to encode all existing flags into a unique one...
0386     std::map<unsigned short, unsigned short> lAPVMap;
0387     for (auto cCont : lList) {
0388       SiStripBadStrip::data lData = obj_.decode(cCont);
0389       unsigned short lFlag = 0;
0390       setFlagBit(lFlag, lData.flag);
0391 
0392       //std::cout << " -- Detid " << it.first << ", strip " << lData.firstStrip << ", flag " << lData.flag << std::endl;
0393 
0394       auto lInsert = lAPVMap.emplace(lData.firstStrip, lFlag);
0395       if (!lInsert.second) {
0396         //std::cout << " ---- Adding bit : " << lData.flag << " to " << lInsert.first->second << ": ";
0397         setFlagBit(lInsert.first->second, lData.flag);
0398         //std::cout << lInsert.first->second << std::endl;
0399       }
0400     }
0401 
0402     //encode the new flag
0403     std::vector<unsigned int> lStripVector;
0404     const unsigned short lConsecutiveBadStrips = 128;
0405     lStripVector.reserve(lAPVMap.size());
0406     for (const auto& lIter : lAPVMap) {
0407       lStripVector.push_back(obj_.encode(lIter.first, lConsecutiveBadStrips, lIter.second));
0408     }
0409 
0410     SiStripBadStrip::Range lRange(lStripVector.begin(), lStripVector.end());
0411     if (!obj_.put(it.first, lRange)) {
0412       edm::LogError("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::addBadStrips] detid already exists." << std::endl;
0413     }
0414   }
0415 }
0416 
0417 #include "FWCore/Framework/interface/MakerMacros.h"
0418 #include "DQMOffline/CalibTracker/plugins/SiStripPopConDQMEDHarvester.h"
0419 using SiStripPopConFEDErrorsDQM = SiStripPopConDQMEDHarvester<SiStripPopConFEDErrorsHandlerFromDQM>;
0420 DEFINE_FWK_MODULE(SiStripPopConFEDErrorsDQM);