Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-08 03:21:48

0001 #include "FWCore/Framework/interface/Frameworkfwd.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/Framework/interface/EventSetup.h"
0004 #include "FWCore/Framework/interface/Run.h"
0005 #include "FWCore/Framework/interface/MakerMacros.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 
0009 //DQM services
0010 #include "DQMServices/Core/interface/DQMStore.h"
0011 #include "FWCore/ServiceRegistry/interface/Service.h"
0012 #include "DQMServices/Core/interface/MonitorElement.h"
0013 #include "DQMServices/Core/interface/DQMEDHarvester.h"
0014 
0015 #include <TH2F.h>
0016 #include <TFile.h>
0017 #include <TDirectoryFile.h>
0018 #include <TKey.h>
0019 
0020 using namespace edm;
0021 
0022 class GEMDQMHarvester : public DQMEDHarvester {
0023 public:
0024   GEMDQMHarvester(const edm::ParameterSet &);
0025   ~GEMDQMHarvester() override{};
0026   static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
0027 
0028   typedef std::tuple<int, int> IdChamber;
0029   typedef std::tuple<int, int, int> IdVFAT;
0030   typedef struct PreStatusInfo {
0031     int nLumiStart;
0032     int nLumiEnd;
0033     int nStatus;
0034   } StatusInfo;
0035 
0036   class NumStatus {
0037   public:
0038     NumStatus(Float_t fNumTotal = 0,
0039               Float_t fNumOcc = 0,
0040               Float_t fNumErrVFAT = 0,
0041               Float_t fNumWarnVFAT = 0,
0042               Float_t fNumErrOH = 0,
0043               Float_t fNumWarnOH = 0,
0044               Float_t fNumErrAMC = 0,
0045               Float_t fNumWarnAMC = 0,
0046               Float_t fNumErrAMC13 = 0)
0047         : fNumTotal_(fNumTotal),
0048           fNumOcc_(fNumOcc),
0049           fNumErrVFAT_(fNumErrVFAT),
0050           fNumWarnVFAT_(fNumWarnVFAT),
0051           fNumErrOH_(fNumErrOH),
0052           fNumWarnOH_(fNumWarnOH),
0053           fNumErrAMC_(fNumErrAMC),
0054           fNumWarnAMC_(fNumWarnAMC),
0055           fNumErrAMC13_(fNumErrAMC13) {}
0056     float fNumTotal_;
0057     float fNumOcc_;
0058     float fNumErrVFAT_;
0059     float fNumWarnVFAT_;
0060     float fNumErrOH_;
0061     float fNumWarnOH_;
0062     float fNumErrAMC_;
0063     float fNumWarnAMC_;
0064     float fNumErrAMC13_;
0065   };
0066 
0067 protected:
0068   void dqmEndLuminosityBlock(DQMStore::IBooker &,
0069                              DQMStore::IGetter &,
0070                              edm::LuminosityBlock const &iLumi,
0071                              edm::EventSetup const &) override;
0072   void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override{};  // Cannot use; it is called after dqmSaver
0073 
0074   void drawSummaryHistogram(edm::Service<DQMStore> &store, Int_t nLumiCurr);
0075   void createTableWatchingSummary();
0076   void copyLabels(MonitorElement *h2Src, MonitorElement *h2Dst);
0077   void getGeometryInfo(edm::Service<DQMStore> &store, MonitorElement *h2Src);
0078   void createSummaryHist(edm::Service<DQMStore> &store, MonitorElement *h2Src, MonitorElement *&h2Sum);
0079   void createSummaryVFAT(edm::Service<DQMStore> &store,
0080                          MonitorElement *h2Src,
0081                          std::string strSuffix,
0082                          MonitorElement *&h2Sum);
0083   Float_t refineSummaryHistogram(std::string strName,
0084                                  MonitorElement *h2Sum,
0085                                  std::vector<MonitorElement *> &listOccPlots,
0086                                  MonitorElement *h2SrcStatusA,
0087                                  MonitorElement *h2SrcStatusE,
0088                                  MonitorElement *h2SrcStatusW,
0089                                  MonitorElement *h2SrcStatusEVFAT,
0090                                  MonitorElement *h2SrcStatusWVFAT,
0091                                  MonitorElement *h2SrcStatusEOH,
0092                                  MonitorElement *h2SrcStatusWOH,
0093                                  MonitorElement *h2SrcStatusEAMC,
0094                                  MonitorElement *h2SrcStatusWAMC,
0095                                  MonitorElement *h2SrcStatusEAMC13,
0096                                  Int_t nLumiCurr);
0097   Int_t refineSummaryVFAT(std::string strName,
0098                           MonitorElement *h2Sum,
0099                           MonitorElement *h2SrcOcc,
0100                           MonitorElement *h2SrcStatusE,
0101                           MonitorElement *h2SrcStatusW,
0102                           Int_t nLumiCurr,
0103                           Int_t nIdxLayer);
0104   Int_t assessOneBin(
0105       std::string strName, Int_t nIdxX, Int_t nIdxY, Float_t fAll, Float_t fNumOcc, Float_t fNumErr, Float_t fNumWarn);
0106 
0107   Int_t UpdateStatusChamber(Int_t nIdxLayer, Int_t nIdxCh, Int_t nLumiCurr, NumStatus numStatus);
0108   Int_t UpdateStatusChamber(Int_t nIdxLayer, Int_t nIdxCh, Int_t nIdxVFAT, Int_t nLumiCurr, NumStatus numStatus);
0109   Int_t UpdateStatusChamber(std::vector<StatusInfo> &listStatus,
0110                             NumStatus &numStatus,
0111                             Int_t nLumiCurr,
0112                             NumStatus numStatusNew);
0113   void createLumiFuncHist(edm::Service<DQMStore> &store, std::string strSuffix, Int_t nIdxLayer, Int_t nLumiCurr);
0114   void createInactiveChannelFracHist(edm::Service<DQMStore> &store, std::string strSuffix, Int_t nNumChamber);
0115 
0116   Float_t fCutErr_, fCutLowErr_, fCutWarn_;
0117 
0118   const std::string strDirSummary_ = "GEM/EventInfo";
0119   const std::string strDirRecHit_ = "GEM/RecHits";
0120   const std::string strDirStatus_ = "GEM/DAQStatus";
0121 
0122   const Int_t nCodeFine_ = 1;
0123   const Int_t nCodeError_ = 2;
0124   const Int_t nCodeWarning_ = 3;
0125   const Int_t nCodeLowError_ = 4;
0126 
0127   const Int_t nBitWarnVFAT_ = 7;
0128   const Int_t nBitErrVFAT_ = 6;
0129   const Int_t nBitWarnOH_ = 5;
0130   const Int_t nBitErrOH_ = 4;
0131   const Int_t nBitWarnAMC_ = 3;
0132   const Int_t nBitErrAMC_ = 2;
0133   const Int_t nBitErrAMC13_ = 1;
0134   const Int_t nBitOcc_ = 0;
0135 
0136   const Int_t nNumVFATs_ = 24;
0137 
0138   const Int_t nMaxLumi_ = 6000;  // From DQMServices/Components/plugins/DQMProvInfo.h
0139   //const Int_t nResolutionLumi_ = 5;
0140   Int_t nResolutionLumi_;
0141 
0142   typedef std::vector<std::vector<Float_t>> TableStatusOcc;
0143   typedef std::vector<std::vector<Int_t>> TableStatusNum;
0144 
0145   std::map<IdChamber, std::vector<StatusInfo>> mapStatusChambersSummary_;
0146   std::map<IdVFAT, std::vector<StatusInfo>> mapStatusVFATsSummary_;
0147   std::map<IdChamber, NumStatus> mapNumStatusChambersSummary_;
0148   std::map<IdVFAT, NumStatus> mapNumStatusVFATsSummary_;
0149 
0150   std::vector<std::string> listLayer_;
0151   std::map<std::string, int> mapIdxLayer_;  // All indices in the following objects start at 1
0152   std::map<int, int> mapNumChPerChamber_;
0153   std::map<int, MonitorElement *> mapHistLumiFunc_;
0154   Bool_t bIsStatusChambersInit_;
0155 };
0156 
0157 GEMDQMHarvester::GEMDQMHarvester(const edm::ParameterSet &cfg) {
0158   fCutErr_ = cfg.getParameter<double>("cutErr");
0159   fCutLowErr_ = cfg.getParameter<double>("cutLowErr");
0160   fCutWarn_ = cfg.getParameter<double>("cutWarn");
0161   nResolutionLumi_ = cfg.getParameter<int>("resolutionLumi");
0162   bIsStatusChambersInit_ = false;
0163 }
0164 
0165 void GEMDQMHarvester::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0166   edm::ParameterSetDescription desc;
0167   desc.add<double>("cutErr", 0.05);
0168   desc.add<double>("cutLowErr", 0.00);
0169   desc.add<double>("cutWarn", 0.05);
0170   desc.add<int>("resolutionLumi", 1);
0171   descriptions.add("GEMDQMHarvester", desc);
0172 }
0173 
0174 void GEMDQMHarvester::dqmEndLuminosityBlock(DQMStore::IBooker &,
0175                                             DQMStore::IGetter &,
0176                                             edm::LuminosityBlock const &iLumi,
0177                                             edm::EventSetup const &) {
0178   edm::Service<DQMStore> store;
0179   Int_t nLumiCurr = iLumi.id().luminosityBlock();
0180   drawSummaryHistogram(store, nLumiCurr);
0181 }
0182 
0183 void GEMDQMHarvester::drawSummaryHistogram(edm::Service<DQMStore> &store, Int_t nLumiCurr) {
0184   Float_t fReportSummary = -1.0;
0185 
0186   std::string strSrcStatusA = "GEM/DAQStatus/chamberAllStatus";
0187   std::string strSrcStatusE = "GEM/DAQStatus/chamberErrors";
0188   std::string strSrcStatusW = "GEM/DAQStatus/chamberWarnings";
0189   std::string strSrcStatusEVFAT = "GEM/DAQStatus/chamberVFATErrors";
0190   std::string strSrcStatusWVFAT = "GEM/DAQStatus/chamberVFATWarnings";
0191   std::string strSrcStatusEOH = "GEM/DAQStatus/chamberOHErrors";
0192   std::string strSrcStatusWOH = "GEM/DAQStatus/chamberOHWarnings";
0193   std::string strSrcStatusEAMC = "GEM/DAQStatus/chamberAMCErrors";
0194   std::string strSrcStatusWAMC = "GEM/DAQStatus/chamberAMCWarnings";
0195   std::string strSrcStatusEAMC13 = "GEM/DAQStatus/chamberAMC13Errors";
0196 
0197   std::string strSrcVFATOcc = "GEM/Digis/occ";
0198   std::string strSrcVFATStatusW = "GEM/DAQStatus/vfat_statusWarnSum";
0199   std::string strSrcVFATStatusE = "GEM/DAQStatus/vfat_statusErrSum";
0200 
0201   store->setCurrentFolder(strDirSummary_);
0202 
0203   MonitorElement *h2SrcStatusA = store->get(strSrcStatusA);
0204   MonitorElement *h2SrcStatusE = store->get(strSrcStatusE);
0205   MonitorElement *h2SrcStatusW = store->get(strSrcStatusW);
0206   MonitorElement *h2SrcStatusEVFAT = store->get(strSrcStatusEVFAT);
0207   MonitorElement *h2SrcStatusWVFAT = store->get(strSrcStatusWVFAT);
0208   MonitorElement *h2SrcStatusEOH = store->get(strSrcStatusEOH);
0209   MonitorElement *h2SrcStatusWOH = store->get(strSrcStatusWOH);
0210   MonitorElement *h2SrcStatusEAMC = store->get(strSrcStatusEAMC);
0211   MonitorElement *h2SrcStatusWAMC = store->get(strSrcStatusWAMC);
0212   MonitorElement *h2SrcStatusEAMC13 = store->get(strSrcStatusEAMC13);
0213 
0214   std::string strTitleSummary = "summary";
0215 
0216   getGeometryInfo(store, h2SrcStatusE);
0217 
0218   if (h2SrcStatusA != nullptr && h2SrcStatusE != nullptr && h2SrcStatusW != nullptr) {
0219     MonitorElement *h2Sum = nullptr;
0220     createSummaryHist(store, h2SrcStatusE, h2Sum);
0221     createTableWatchingSummary();
0222 
0223     std::vector<MonitorElement *> listOccPlots(listLayer_.size() + 1);  // The index starts at 1
0224     for (const auto &strSuffix : listLayer_) {
0225       if (mapIdxLayer_.find(strSuffix) == mapIdxLayer_.end())
0226         continue;
0227       auto nIdxLayer = mapIdxLayer_[strSuffix];
0228       MonitorElement *h2SrcVFATOcc = store->get(strSrcVFATOcc + strSuffix);
0229       if (h2SrcVFATOcc == nullptr)
0230         continue;
0231       listOccPlots[nIdxLayer] = h2SrcVFATOcc;
0232     }
0233 
0234     fReportSummary = refineSummaryHistogram(strTitleSummary,
0235                                             h2Sum,
0236                                             listOccPlots,
0237                                             h2SrcStatusA,
0238                                             h2SrcStatusE,
0239                                             h2SrcStatusW,
0240                                             h2SrcStatusEVFAT,
0241                                             h2SrcStatusWVFAT,
0242                                             h2SrcStatusEOH,
0243                                             h2SrcStatusWOH,
0244                                             h2SrcStatusEAMC,
0245                                             h2SrcStatusWAMC,
0246                                             h2SrcStatusEAMC13,
0247                                             nLumiCurr);
0248 
0249     for (const auto &strSuffix : listLayer_) {
0250       if (mapIdxLayer_.find(strSuffix) == mapIdxLayer_.end())
0251         continue;
0252       auto nIdxLayer = mapIdxLayer_[strSuffix];
0253       MonitorElement *h2SrcVFATOcc = store->get(strSrcVFATOcc + strSuffix);
0254       MonitorElement *h2SrcVFATStatusW = store->get(strSrcVFATStatusW + strSuffix);
0255       MonitorElement *h2SrcVFATStatusE = store->get(strSrcVFATStatusE + strSuffix);
0256       if (h2SrcVFATOcc == nullptr || h2SrcVFATStatusW == nullptr || h2SrcVFATStatusE == nullptr)
0257         continue;
0258 
0259       MonitorElement *h2SumVFAT = nullptr;
0260       createSummaryVFAT(store, h2SrcVFATStatusE, strSuffix, h2SumVFAT);
0261       refineSummaryVFAT(strSuffix, h2SumVFAT, h2SrcVFATOcc, h2SrcVFATStatusE, h2SrcVFATStatusW, nLumiCurr, nIdxLayer);
0262       TString strNewTitle = h2SrcVFATStatusE->getTitle();
0263       h2SumVFAT->setTitle((const char *)strNewTitle.ReplaceAll("errors", "errors/warnings"));
0264       h2SumVFAT->setXTitle(h2SrcVFATStatusE->getAxisTitle(1));
0265       h2SumVFAT->setYTitle(h2SrcVFATStatusE->getAxisTitle(2));
0266 
0267       createLumiFuncHist(store, strSuffix, nIdxLayer, nLumiCurr);
0268     }
0269   }
0270 
0271   for (const auto &strSuffix : listLayer_) {
0272     if (mapIdxLayer_.find(strSuffix) == mapIdxLayer_.end())
0273       continue;
0274     //auto nNumChamber = mapNumChPerChamber_[mapIdxLayer_[strSuffix]];
0275     Int_t nNumChamber = 36;
0276     createInactiveChannelFracHist(store, strSuffix, nNumChamber);
0277   }
0278 
0279   store->bookFloat("reportSummary")->Fill(fReportSummary);
0280 }
0281 
0282 void GEMDQMHarvester::createTableWatchingSummary() {
0283   if (bIsStatusChambersInit_)
0284     return;
0285 
0286   for (const auto &[nIdxLayer, nNumCh] : mapNumChPerChamber_) {
0287     for (Int_t i = 1; i <= nNumCh; i++) {
0288       mapStatusChambersSummary_[{nIdxLayer, i}] = std::vector<StatusInfo>();
0289       mapNumStatusChambersSummary_[{nIdxLayer, i}] = NumStatus();
0290       for (Int_t j = 1; j <= nNumVFATs_; j++) {
0291         mapStatusVFATsSummary_[{nIdxLayer, i, j}] = std::vector<StatusInfo>();
0292         mapNumStatusVFATsSummary_[{nIdxLayer, i, j}] = NumStatus();
0293       }
0294     }
0295   }
0296 
0297   bIsStatusChambersInit_ = true;
0298 }
0299 
0300 void GEMDQMHarvester::copyLabels(MonitorElement *h2Src, MonitorElement *h2Dst) {
0301   Int_t nBinX = h2Src->getNbinsX(), nBinY = h2Src->getNbinsY();
0302 
0303   for (Int_t i = 1; i <= nBinX; i++) {
0304     h2Dst->setBinLabel(i, h2Src->getTH2F()->GetXaxis()->GetBinLabel(i), 1);
0305   }
0306   for (Int_t i = 1; i <= nBinY; i++) {
0307     h2Dst->setBinLabel(i, h2Src->getTH2F()->GetYaxis()->GetBinLabel(i), 2);
0308   }
0309   h2Dst->setTitle(h2Src->getTitle());
0310   h2Dst->setXTitle(h2Src->getAxisTitle(1));
0311   h2Dst->setYTitle(h2Src->getAxisTitle(2));
0312 }
0313 
0314 void GEMDQMHarvester::getGeometryInfo(edm::Service<DQMStore> &store, MonitorElement *h2Src) {
0315   listLayer_.clear();
0316   mapIdxLayer_.clear();
0317   mapNumChPerChamber_.clear();
0318 
0319   if (h2Src != nullptr) {  // For online and offline
0320     Int_t nBinY = h2Src->getNbinsY();
0321     listLayer_.push_back("");
0322 
0323     for (Int_t i = 1; i <= nBinY; i++) {
0324       std::string strLabelFull = h2Src->getTH2F()->GetYaxis()->GetBinLabel(i);
0325       auto nPos = strLabelFull.find(';');
0326       auto strLayer = strLabelFull.substr(nPos + 1);
0327       Int_t nBinXActual = (Int_t)(h2Src->getBinContent(0, i) + 0.5);
0328       if (nBinXActual > 108) {  // When the number seems wrong
0329         if (strLayer.find("GE11") != std::string::npos) {
0330           nBinXActual = 36;
0331         } else if (strLayer.find("GE21") != std::string::npos) {
0332           nBinXActual = 18;
0333         } else if (strLayer.find("GE01") != std::string::npos) {
0334           nBinXActual = 36;
0335         }
0336       }
0337       listLayer_.push_back(strLayer);
0338       mapIdxLayer_[strLayer] = i;
0339       mapNumChPerChamber_[i] = nBinXActual;
0340     }
0341   } else {  // For others (validation and...?)
0342     listLayer_.push_back("");
0343     if (store->get("GEM/Digis/occupancy_GE11-M-L1/occ_GE11-M-01L1-S") != nullptr) {
0344       listLayer_.push_back("_GE11-P-L2");
0345       listLayer_.push_back("_GE11-P-L1");
0346       listLayer_.push_back("_GE11-M-L1");
0347       listLayer_.push_back("_GE11-M-L2");
0348       mapIdxLayer_["_GE11-P-L2"] = 1;
0349       mapIdxLayer_["_GE11-P-L1"] = 2;
0350       mapIdxLayer_["_GE11-M-L1"] = 3;
0351       mapIdxLayer_["_GE11-M-L2"] = 4;
0352       mapNumChPerChamber_[1] = 36;
0353       mapNumChPerChamber_[2] = 36;
0354       mapNumChPerChamber_[3] = 36;
0355       mapNumChPerChamber_[4] = 36;
0356     }
0357     // FIXME: How about GE21 and ME0?
0358   }
0359 }
0360 
0361 void GEMDQMHarvester::createSummaryHist(edm::Service<DQMStore> &store, MonitorElement *h2Src, MonitorElement *&h2Sum) {
0362   //store->setCurrentFolder(strDirSummary_);
0363 
0364   Int_t nBinX = h2Src->getNbinsX(), nBinY = h2Src->getNbinsY();
0365   h2Sum = store->book2D("reportSummaryMap", "", nBinX, 0.5, nBinX + 0.5, nBinY, 0.5, nBinY + 0.5);
0366   h2Sum->setTitle("Summary plot");
0367   h2Sum->setXTitle("Chamber");
0368   h2Sum->setYTitle("Layer");
0369 
0370   for (Int_t i = 1; i <= nBinX; i++)
0371     h2Sum->setBinLabel(i, h2Src->getTH2F()->GetXaxis()->GetBinLabel(i), 1);
0372   for (Int_t i = 1; i <= nBinY; i++)
0373     h2Sum->setBinLabel(i, listLayer_[i].substr(1), 2);
0374 }
0375 
0376 void GEMDQMHarvester::createSummaryVFAT(edm::Service<DQMStore> &store,
0377                                         MonitorElement *h2Src,
0378                                         std::string strSuffix,
0379                                         MonitorElement *&h2Sum) {
0380   //store->setCurrentFolder(strDirStatus_);
0381   //store->setCurrentFolder(strDirSummary_);
0382 
0383   Int_t nBinX = h2Src->getNbinsX(), nBinY = h2Src->getNbinsY();
0384   h2Sum = store->book2D("vfat_statusSummary" + strSuffix, "", nBinX, 0.5, nBinX + 0.5, nBinY, -0.5, nBinY - 0.5);
0385   copyLabels(h2Src, h2Sum);
0386 }
0387 
0388 Int_t GEMDQMHarvester::assessOneBin(
0389     std::string strName, Int_t nIdxX, Int_t nIdxY, Float_t fAll, Float_t fNumOcc, Float_t fNumErr, Float_t fNumWarn) {
0390   if (fNumErr > fCutErr_ * fAll)  // The error status criterion
0391     return nCodeError_;
0392   else if (fNumErr > fCutLowErr_ * fAll)  // The low-error status criterion
0393     return nCodeLowError_;
0394   else if (fNumWarn > fCutWarn_ * fAll)  // The warning status criterion
0395     return nCodeWarning_;
0396   else if (fNumOcc > 0)
0397     return nCodeFine_;
0398 
0399   return 0;
0400 }
0401 
0402 // FIXME: Need more study about how to summarize
0403 Float_t GEMDQMHarvester::refineSummaryHistogram(std::string strName,
0404                                                 MonitorElement *h2Sum,
0405                                                 std::vector<MonitorElement *> &listOccPlots,
0406                                                 MonitorElement *h2SrcStatusA,
0407                                                 MonitorElement *h2SrcStatusE,
0408                                                 MonitorElement *h2SrcStatusW,
0409                                                 MonitorElement *h2SrcStatusEVFAT,
0410                                                 MonitorElement *h2SrcStatusWVFAT,
0411                                                 MonitorElement *h2SrcStatusEOH,
0412                                                 MonitorElement *h2SrcStatusWOH,
0413                                                 MonitorElement *h2SrcStatusEAMC,
0414                                                 MonitorElement *h2SrcStatusWAMC,
0415                                                 MonitorElement *h2SrcStatusEAMC13,
0416                                                 Int_t nLumiCurr) {
0417   Int_t nBinY = h2Sum->getNbinsY();
0418   Int_t nAllBin = 0, nFineBin = 0;
0419   for (Int_t j = 1; j <= nBinY; j++) {
0420     Int_t nBinX = (Int_t)(h2SrcStatusE->getBinContent(0, j) + 0.5);
0421     auto h2SrcOcc = listOccPlots[j];
0422     Int_t nBinYOcc = 0;
0423     if (h2SrcOcc != nullptr) {
0424       nBinYOcc = h2SrcOcc->getNbinsY();
0425     }
0426 
0427     h2Sum->setBinContent(0, j, nBinX);
0428     for (Int_t i = 1; i <= nBinX; i++) {
0429       Float_t fOcc = 0;
0430       for (Int_t r = 1; r <= nBinYOcc; r++) {
0431         fOcc += h2SrcOcc->getBinContent(i, r);
0432       }
0433 
0434       Float_t fStatusAll = h2SrcStatusA->getBinContent(i, j);
0435       Float_t fStatusErr = h2SrcStatusE->getBinContent(i, j);
0436       Float_t fStatusWarn = h2SrcStatusW->getBinContent(i, j);
0437       Float_t fStatusErrVFAT = h2SrcStatusEVFAT != nullptr ? h2SrcStatusEVFAT->getBinContent(i, j) : 0;
0438       Float_t fStatusWarnVFAT = h2SrcStatusWVFAT != nullptr ? h2SrcStatusWVFAT->getBinContent(i, j) : 0;
0439       Float_t fStatusErrOH = h2SrcStatusEOH != nullptr ? h2SrcStatusEOH->getBinContent(i, j) : 0;
0440       Float_t fStatusWarnOH = h2SrcStatusWOH != nullptr ? h2SrcStatusWOH->getBinContent(i, j) : 0;
0441       Float_t fStatusErrAMC = h2SrcStatusEAMC != nullptr ? h2SrcStatusEAMC->getBinContent(i, j) : 0;
0442       Float_t fStatusWarnAMC = h2SrcStatusWAMC != nullptr ? h2SrcStatusWAMC->getBinContent(i, j) : 0;
0443       Float_t fStatusErrAMC13 = h2SrcStatusEAMC13 != nullptr ? h2SrcStatusEAMC13->getBinContent(i, j) : 0;
0444       NumStatus numStatus(fStatusAll,
0445                           fOcc,
0446                           fStatusErrVFAT,
0447                           fStatusWarnVFAT,
0448                           fStatusErrOH,
0449                           fStatusWarnOH,
0450                           fStatusErrAMC,
0451                           fStatusWarnAMC,
0452                           fStatusErrAMC13);
0453       UpdateStatusChamber(j, i, nLumiCurr, numStatus);
0454 
0455       Int_t nRes = assessOneBin(strName, i, j, fStatusAll, fOcc, fStatusErr, fStatusWarn);
0456       if (nRes == 1)
0457         nFineBin++;
0458 
0459       h2Sum->setBinContent(i, j, (Float_t)nRes);
0460       nAllBin++;
0461     }
0462   }
0463 
0464   return ((Float_t)nFineBin) / nAllBin;
0465 }
0466 
0467 Int_t GEMDQMHarvester::refineSummaryVFAT(std::string strName,
0468                                          MonitorElement *h2Sum,
0469                                          MonitorElement *h2SrcOcc,
0470                                          MonitorElement *h2SrcStatusE,
0471                                          MonitorElement *h2SrcStatusW,
0472                                          Int_t nLumiCurr,
0473                                          Int_t nIdxLayer) {
0474   Int_t nBinY = h2Sum->getNbinsY();
0475   for (Int_t j = 1; j <= nBinY; j++) {
0476     Int_t nBinX = h2Sum->getNbinsX();
0477     for (Int_t i = 1; i <= nBinX; i++) {
0478       Float_t fOcc = h2SrcOcc->getBinContent(i, j);
0479       Float_t fStatusErr = h2SrcStatusE->getBinContent(i, j);
0480       Float_t fStatusWarn = h2SrcStatusW->getBinContent(i, j);
0481       Float_t fStatusAll = fOcc + fStatusErr + fStatusWarn;
0482       NumStatus numStatus(fStatusAll, fOcc, fStatusErr, fStatusWarn, 0, 0, 0, 0, 0);
0483       UpdateStatusChamber(nIdxLayer, i, j, nLumiCurr, numStatus);
0484 
0485       Int_t nRes = assessOneBin(strName, i, j, fStatusAll, fOcc, fStatusErr, fStatusWarn);
0486       h2Sum->setBinContent(i, j, (Float_t)nRes);
0487     }
0488   }
0489 
0490   return 0;
0491 }
0492 
0493 Int_t GEMDQMHarvester::UpdateStatusChamber(Int_t nIdxLayer, Int_t nIdxCh, Int_t nLumiCurr, NumStatus numStatus) {
0494   if (!bIsStatusChambersInit_)
0495     return 0;
0496   if (0 >= nIdxCh || nIdxCh > mapNumChPerChamber_[nIdxLayer])
0497     return 0;
0498   auto &listStatus = mapStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0499   auto &numStatusPrev = mapNumStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0500   return UpdateStatusChamber(listStatus, numStatusPrev, nLumiCurr, numStatus);
0501 }
0502 
0503 Int_t GEMDQMHarvester::UpdateStatusChamber(
0504     Int_t nIdxLayer, Int_t nIdxCh, Int_t nIdxVFAT, Int_t nLumiCurr, NumStatus numStatus) {
0505   if (!bIsStatusChambersInit_)
0506     return 0;
0507   if (0 >= nIdxCh || nIdxCh > mapNumChPerChamber_[nIdxLayer])
0508     return 0;
0509   if (0 >= nIdxVFAT || nIdxVFAT > nNumVFATs_)
0510     return 0;
0511   auto &listStatus = mapStatusVFATsSummary_[{nIdxLayer, nIdxCh, nIdxVFAT}];
0512   auto &numStatusPrev = mapNumStatusVFATsSummary_[{nIdxLayer, nIdxCh, nIdxVFAT}];
0513   return UpdateStatusChamber(listStatus, numStatusPrev, nLumiCurr, numStatus);
0514 }
0515 
0516 Int_t GEMDQMHarvester::UpdateStatusChamber(std::vector<StatusInfo> &listStatus,
0517                                            NumStatus &numStatus,
0518                                            Int_t nLumiCurr,
0519                                            NumStatus numStatusNew) {
0520   // First of all, the current lumi section will be assessed, of which the result will be stored in nStatus
0521   Int_t nStatus = 0;
0522 
0523   Float_t fNumAddErrVFAT = numStatusNew.fNumErrVFAT_ - numStatus.fNumErrVFAT_;
0524   Float_t fNumAddWarnVFAT = numStatusNew.fNumWarnVFAT_ - numStatus.fNumWarnVFAT_;
0525   Float_t fNumAddErrOH = numStatusNew.fNumErrOH_ - numStatus.fNumErrOH_;
0526   Float_t fNumAddWarnOH = numStatusNew.fNumWarnOH_ - numStatus.fNumWarnOH_;
0527   Float_t fNumAddErrAMC = numStatusNew.fNumErrAMC_ - numStatus.fNumErrAMC_;
0528   Float_t fNumAddWarnAMC = numStatusNew.fNumWarnAMC_ - numStatus.fNumWarnAMC_;
0529   Float_t fNumAddErrAMC13 = numStatusNew.fNumErrAMC13_ - numStatus.fNumErrAMC13_;
0530 
0531   numStatus.fNumTotal_ = numStatusNew.fNumTotal_;
0532   numStatus.fNumOcc_ = numStatusNew.fNumOcc_;
0533   numStatus.fNumErrVFAT_ = numStatusNew.fNumErrVFAT_;
0534   numStatus.fNumWarnVFAT_ = numStatusNew.fNumWarnVFAT_;
0535   numStatus.fNumErrOH_ = numStatusNew.fNumErrOH_;
0536   numStatus.fNumWarnOH_ = numStatusNew.fNumWarnOH_;
0537   numStatus.fNumErrAMC_ = numStatusNew.fNumErrAMC_;
0538   numStatus.fNumWarnAMC_ = numStatusNew.fNumWarnAMC_;
0539   numStatus.fNumErrAMC13_ = numStatusNew.fNumErrAMC13_;
0540 
0541   nStatus = (numStatusNew.fNumOcc_ > 0 ? 1 << nBitOcc_ : 0) | (fNumAddErrAMC13 > 0 ? 1 << nBitErrAMC13_ : 0) |
0542             (fNumAddErrAMC > 0 ? 1 << nBitErrAMC_ : 0) | (fNumAddWarnAMC > 0 ? 1 << nBitWarnAMC_ : 0) |
0543             (fNumAddErrOH > 0 ? 1 << nBitErrOH_ : 0) | (fNumAddWarnOH > 0 ? 1 << nBitWarnOH_ : 0) |
0544             (fNumAddErrVFAT > 0 ? 1 << nBitErrVFAT_ : 0) | (fNumAddWarnVFAT > 0 ? 1 << nBitWarnVFAT_ : 0);
0545 
0546   // Only used in the next if statement; See statusLast
0547   StatusInfo statusNew;
0548   statusNew.nLumiStart = nLumiCurr;
0549   statusNew.nLumiEnd = nLumiCurr;
0550   statusNew.nStatus = nStatus;
0551 
0552   if (listStatus.empty()) {
0553     listStatus.push_back(statusNew);
0554   } else {
0555     auto &statusLastPre = listStatus.back();
0556     if (statusLastPre.nStatus == nStatus) {
0557       statusLastPre.nLumiEnd = nLumiCurr;
0558     } else {
0559       listStatus.push_back(statusNew);
0560     }
0561   }
0562 
0563   return 0;
0564 }
0565 
0566 void GEMDQMHarvester::createLumiFuncHist(edm::Service<DQMStore> &store,
0567                                          std::string strSuffix,
0568                                          Int_t nIdxLayer,
0569                                          Int_t nLumiCurr) {
0570   auto &nNumCh = mapNumChPerChamber_[nIdxLayer];
0571 
0572   MonitorElement *h2Summary;
0573 
0574   //Int_t nLumiCurrLowRes = ( ( nLumiCurr - 1 ) / nResolutionLumi_ ) * nResolutionLumi_;
0575   Int_t nNumBinLumi = ((nLumiCurr - 1) / nResolutionLumi_) + 1;
0576   Int_t nMaxBin = 0;
0577 
0578   // Creating or Summoning the corresponding histogram
0579   if (mapHistLumiFunc_.find(nIdxLayer) == mapHistLumiFunc_.end()) {
0580     store->setCurrentFolder(strDirSummary_);
0581     h2Summary = store->book2S("chamberStatus_inLumi" + strSuffix,
0582                               "Chamber status on lumi-block " + strSuffix.substr(1),
0583                               nMaxLumi_ / nResolutionLumi_,
0584                               1.0,
0585                               (Float_t)(nMaxLumi_ + 1),
0586                               //nNumBinLumi, 1.0, (Float_t)( nLumiCurr + 1 ),
0587                               nNumCh,
0588                               0.5,
0589                               nNumCh + 0.5);
0590     mapHistLumiFunc_[nIdxLayer] = h2Summary;
0591 
0592     h2Summary->setXTitle("Luminosity block");
0593     h2Summary->setYTitle("Chamber");
0594     for (Int_t i = 1; i <= nNumCh; i++) {
0595       h2Summary->setBinLabel(i, Form("%i", i), 2);
0596     }
0597   } else {
0598     h2Summary = mapHistLumiFunc_[nIdxLayer];
0599   }
0600 
0601   for (Int_t nIdxCh = 1; nIdxCh <= nNumCh; nIdxCh++) {
0602     auto &listStatus = mapStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0603 
0604     Int_t nIdxStatus = 0;
0605     for (Int_t nIdxLumi = 0; nIdxLumi < nNumBinLumi; nIdxLumi++) {
0606       // Lumis covered by these values (nLumiStart <=, <= nLumiEnd) are counted for the current bin
0607       Int_t nLumiStart = 1 + nIdxLumi * nResolutionLumi_;
0608       Int_t nLumiEnd = (1 + nIdxLumi) * nResolutionLumi_;
0609       if (nLumiEnd > nLumiCurr)
0610         nLumiEnd = nLumiCurr;
0611 
0612       Int_t nStatusSum = 0;
0613       while (true) {  // No worries, nIdxStatus must increase and reach at listStatus.size()
0614         // True: It was too past so that
0615         //       the lumi range of listStatus[ nIdxStatus ] is out of the coverage of the current bin
0616         if (listStatus[nIdxStatus].nLumiEnd < nLumiStart) {
0617           nIdxStatus++;
0618           if (nIdxStatus >= (int)listStatus.size()) {
0619             break;  // For safety
0620           }
0621           continue;
0622         }
0623 
0624         nStatusSum = listStatus[nIdxStatus].nStatus;
0625 
0626         // True: This is the last item of listStatus which is covered by the current bin
0627         if (nIdxStatus + 1 >= (int)listStatus.size() || listStatus[nIdxStatus].nLumiEnd >= nLumiEnd) {
0628           break;
0629         }
0630 
0631         nIdxStatus++;
0632         if (nIdxStatus >= (int)listStatus.size()) {
0633           break;  // For safety
0634         }
0635       }
0636 
0637       h2Summary->setBinContent(nIdxLumi + 1, nIdxCh, nStatusSum);
0638       if (nMaxBin < nIdxLumi + 1)
0639         nMaxBin = nIdxLumi + 1;
0640     }
0641   }
0642 
0643   for (Int_t nX = 1; nX <= nMaxBin; nX++) {
0644     h2Summary->setBinContent(nX, 0, 1);
0645   }
0646 }
0647 
0648 std::string getNameChamberOccGE11(std::string strSuffix, Int_t nIdxCh) {
0649   char cRegion;
0650   char cChType = (nIdxCh % 2 == 0 ? 'L' : 'S');
0651   Int_t nLayer;
0652 
0653   if (strSuffix.find("-M-") != std::string::npos)
0654     cRegion = 'M';
0655   else if (strSuffix.find("-P-") != std::string::npos)
0656     cRegion = 'P';
0657   else
0658     return "";
0659 
0660   if (strSuffix.find("-L1") != std::string::npos)
0661     nLayer = 1;
0662   else if (strSuffix.find("-L2") != std::string::npos)
0663     nLayer = 2;
0664   else
0665     return "";
0666 
0667   return Form(
0668       "GEM/Digis/occupancy_GE11-%c-L%i/occ_GE11-%c-%02iL%i-%c", cRegion, nLayer, cRegion, nIdxCh, nLayer, cChType);
0669 }
0670 
0671 // FIXME: The naming convention of GE21 could be changed to be different from GE11
0672 std::string getNameChamberOccGE21(std::string strSuffix, Int_t nIdxCh) {
0673   char cRegion;
0674   char cChType = (nIdxCh % 2 == 0 ? 'L' : 'S');
0675   Int_t nLayer;
0676 
0677   if (strSuffix.find("-M-") != std::string::npos)
0678     cRegion = 'M';
0679   else if (strSuffix.find("-P-") != std::string::npos)
0680     cRegion = 'P';
0681   else
0682     return "";
0683 
0684   if (strSuffix.find("-L1") != std::string::npos)
0685     nLayer = 1;
0686   else if (strSuffix.find("-L2") != std::string::npos)
0687     nLayer = 2;
0688   else
0689     return "";
0690 
0691   return Form(
0692       "GEM/Digis/occupancy_GE21-%c-L%i/occ_GE21-%c-%02iL%i-%c", cRegion, nLayer, cRegion, nIdxCh, nLayer, cChType);
0693 }
0694 
0695 std::string getNameChamberOccNull(std::string strSuffix, Int_t nIdxChamber) {
0696   return "";  // For an initialization
0697 }
0698 
0699 void GEMDQMHarvester::createInactiveChannelFracHist(edm::Service<DQMStore> &store,
0700                                                     std::string strSuffix,
0701                                                     Int_t nNumChamber) {
0702   std::string strTitle = "The fraction of inactive channels in " + strSuffix.substr(1);
0703   MonitorElement *h2InactiveChannel =
0704       store->book1D("inactive_frac_chamber" + strSuffix, strTitle, nNumChamber, 0.5, nNumChamber + 0.5);
0705   h2InactiveChannel->setXTitle("Chamber");
0706   h2InactiveChannel->setYTitle("Fraction of inactive channels");
0707   for (Int_t i = 1; i <= nNumChamber; i++) {
0708     h2InactiveChannel->setBinLabel(i, Form("%i", i), 1);
0709   }
0710 
0711   std::string (*funcNameCh)(std::string, Int_t) = getNameChamberOccNull;
0712 
0713   if (strSuffix.find("_GE11") != std::string::npos) {
0714     funcNameCh = getNameChamberOccGE11;
0715   } else if (strSuffix.find("_GE21") != std::string::npos) {
0716     funcNameCh = getNameChamberOccGE21;
0717   }
0718 
0719   for (Int_t nIdxCh = 1; nIdxCh <= nNumChamber; nIdxCh++) {
0720     std::string strNameCh = funcNameCh(strSuffix, nIdxCh);
0721     MonitorElement *h2SrcChamberOcc = store->get(strNameCh);
0722     if (h2SrcChamberOcc == nullptr) {
0723       // FIXME: It's about sending a message
0724       continue;
0725     }
0726 
0727     Int_t nNumBinX = h2SrcChamberOcc->getNbinsX();
0728     Int_t nNumBinY = h2SrcChamberOcc->getNbinsY();
0729     Int_t nNumAllChannel = nNumBinX * nNumBinY;
0730     auto *histData = h2SrcChamberOcc->getTH2F();
0731     auto *pdData = histData->GetArray();
0732     Int_t nNumChannelInactive = 0;
0733     for (Int_t j = 1; j <= nNumBinY; j++)
0734       for (Int_t i = 1; i <= nNumBinX; i++) {
0735         if (pdData[j * (nNumBinX + 2) + i] <= 0) {
0736           nNumChannelInactive++;
0737         }
0738       }
0739     h2InactiveChannel->setBinContent(nIdxCh, ((Double_t)nNumChannelInactive) / nNumAllChannel);
0740   }
0741 }
0742 
0743 DEFINE_FWK_MODULE(GEMDQMHarvester);