Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-11 04:32:30

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   const Int_t nCodeMasked_ = 5;
0127 
0128   const Int_t nBitWarnVFAT_ = 7;
0129   const Int_t nBitErrVFAT_ = 6;
0130   const Int_t nBitWarnOH_ = 5;
0131   const Int_t nBitErrOH_ = 4;
0132   const Int_t nBitWarnAMC_ = 3;
0133   const Int_t nBitErrAMC_ = 2;
0134   const Int_t nBitErrAMC13_ = 1;
0135   const Int_t nBitOcc_ = 0;
0136 
0137   const Int_t nNumVFATs_ = 24;
0138 
0139   const Int_t nMaxLumi_ = 6000;  // From DQMServices/Components/plugins/DQMProvInfo.h
0140   //const Int_t nResolutionLumi_ = 5;
0141   Int_t nResolutionLumi_;
0142 
0143   typedef std::vector<std::vector<Float_t>> TableStatusOcc;
0144   typedef std::vector<std::vector<Int_t>> TableStatusNum;
0145 
0146   std::map<IdChamber, std::vector<StatusInfo>> mapStatusChambersSummary_;
0147   std::map<IdVFAT, std::vector<StatusInfo>> mapStatusVFATsSummary_;
0148   std::map<IdChamber, NumStatus> mapNumStatusChambersSummary_;
0149   std::map<IdVFAT, NumStatus> mapNumStatusVFATsSummary_;
0150 
0151   std::vector<std::string> listLayer_;
0152   std::map<std::string, int> mapIdxLayer_;  // All indices in the following objects start at 1
0153   std::map<int, int> mapNumChPerChamber_;
0154   std::map<int, std::map<int, int>> mapIdxToChamberInOcc_;
0155   std::map<int, MonitorElement *> mapHistLumiFunc_;
0156   Bool_t bIsStatusChambersInit_;
0157 };
0158 
0159 GEMDQMHarvester::GEMDQMHarvester(const edm::ParameterSet &cfg) {
0160   fCutErr_ = cfg.getParameter<double>("cutErr");
0161   fCutLowErr_ = cfg.getParameter<double>("cutLowErr");
0162   fCutWarn_ = cfg.getParameter<double>("cutWarn");
0163   nResolutionLumi_ = cfg.getParameter<int>("resolutionLumi");
0164   bIsStatusChambersInit_ = false;
0165 }
0166 
0167 void GEMDQMHarvester::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0168   edm::ParameterSetDescription desc;
0169   desc.add<double>("cutErr", 0.05);
0170   desc.add<double>("cutLowErr", 0.00);
0171   desc.add<double>("cutWarn", 0.05);
0172   desc.add<int>("resolutionLumi", 1);
0173   descriptions.add("GEMDQMHarvester", desc);
0174 }
0175 
0176 void GEMDQMHarvester::dqmEndLuminosityBlock(DQMStore::IBooker &,
0177                                             DQMStore::IGetter &,
0178                                             edm::LuminosityBlock const &iLumi,
0179                                             edm::EventSetup const &) {
0180   edm::Service<DQMStore> store;
0181   Int_t nLumiCurr = iLumi.id().luminosityBlock();
0182   drawSummaryHistogram(store, nLumiCurr);
0183 }
0184 
0185 void GEMDQMHarvester::drawSummaryHistogram(edm::Service<DQMStore> &store, Int_t nLumiCurr) {
0186   Float_t fReportSummary = -1.0;
0187 
0188   std::string strSrcStatusA = "GEM/DAQStatus/chamberAllStatus";
0189   std::string strSrcStatusE = "GEM/DAQStatus/chamberErrors";
0190   std::string strSrcStatusW = "GEM/DAQStatus/chamberWarnings";
0191   std::string strSrcStatusEVFAT = "GEM/DAQStatus/chamberVFATErrors";
0192   std::string strSrcStatusWVFAT = "GEM/DAQStatus/chamberVFATWarnings";
0193   std::string strSrcStatusEOH = "GEM/DAQStatus/chamberOHErrors";
0194   std::string strSrcStatusWOH = "GEM/DAQStatus/chamberOHWarnings";
0195   std::string strSrcStatusEAMC = "GEM/DAQStatus/chamberAMCErrors";
0196   std::string strSrcStatusWAMC = "GEM/DAQStatus/chamberAMCWarnings";
0197   std::string strSrcStatusEAMC13 = "GEM/DAQStatus/chamberAMC13Errors";
0198 
0199   std::string strSrcVFATOcc = "GEM/Digis/occ";
0200   std::string strSrcVFATStatusW = "GEM/DAQStatus/vfat_statusWarnSum";
0201   std::string strSrcVFATStatusE = "GEM/DAQStatus/vfat_statusErrSum";
0202 
0203   store->setCurrentFolder(strDirSummary_);
0204 
0205   MonitorElement *h2SrcStatusA = store->get(strSrcStatusA);
0206   MonitorElement *h2SrcStatusE = store->get(strSrcStatusE);
0207   MonitorElement *h2SrcStatusW = store->get(strSrcStatusW);
0208   MonitorElement *h2SrcStatusEVFAT = store->get(strSrcStatusEVFAT);
0209   MonitorElement *h2SrcStatusWVFAT = store->get(strSrcStatusWVFAT);
0210   MonitorElement *h2SrcStatusEOH = store->get(strSrcStatusEOH);
0211   MonitorElement *h2SrcStatusWOH = store->get(strSrcStatusWOH);
0212   MonitorElement *h2SrcStatusEAMC = store->get(strSrcStatusEAMC);
0213   MonitorElement *h2SrcStatusWAMC = store->get(strSrcStatusWAMC);
0214   MonitorElement *h2SrcStatusEAMC13 = store->get(strSrcStatusEAMC13);
0215 
0216   std::string strTitleSummary = "summary";
0217 
0218   getGeometryInfo(store, h2SrcStatusE);
0219 
0220   if (h2SrcStatusA != nullptr && h2SrcStatusE != nullptr && h2SrcStatusW != nullptr) {
0221     MonitorElement *h2Sum = nullptr;
0222     createSummaryHist(store, h2SrcStatusE, h2Sum);
0223     createTableWatchingSummary();
0224 
0225     std::vector<MonitorElement *> listOccPlots(listLayer_.size() + 1);  // The index starts at 1
0226     for (const auto &strSuffix : listLayer_) {
0227       if (mapIdxLayer_.find(strSuffix) == mapIdxLayer_.end())
0228         continue;
0229       auto nIdxLayer = mapIdxLayer_[strSuffix];
0230       MonitorElement *h2SrcVFATOcc = store->get(strSrcVFATOcc + strSuffix);
0231       if (h2SrcVFATOcc == nullptr)
0232         continue;
0233       listOccPlots[nIdxLayer] = h2SrcVFATOcc;
0234       mapIdxToChamberInOcc_[nIdxLayer] = {};
0235       // Obtaining the bin indices of chambers from their labels
0236       for (Int_t i = 1; i <= h2SrcVFATOcc->getNbinsX(); i++) {
0237         std::string strLabel = h2SrcVFATOcc->getTH2F()->GetXaxis()->GetBinLabel(i);
0238         std::string strSrc = strLabel;
0239         std::vector<int> listNumExtract;
0240 
0241         while (!strSrc.empty()) {
0242           auto nPosDigit = strSrc.find_first_of("0123456789");
0243           if (nPosDigit == std::string::npos)
0244             break;
0245           std::stringstream ss;
0246           ss << strSrc.substr(nPosDigit);
0247           Int_t nExtract;
0248           ss >> nExtract;
0249           if (!ss.eof()) {
0250             ss >> strSrc;
0251           } else {
0252             strSrc = "";
0253           }
0254           listNumExtract.push_back(nExtract);
0255         }
0256 
0257         if (listNumExtract.empty()) {  // Errneous case; but the job should not be dead
0258           edm::LogError("GEMDQMHarvester") << "Error: Wrong label of GEM VFAT occupancy plot: " << strLabel;
0259         } else {
0260           mapIdxToChamberInOcc_[nIdxLayer][listNumExtract[0]] = i;
0261         }
0262       }
0263     }
0264 
0265     fReportSummary = refineSummaryHistogram(strTitleSummary,
0266                                             h2Sum,
0267                                             listOccPlots,
0268                                             h2SrcStatusA,
0269                                             h2SrcStatusE,
0270                                             h2SrcStatusW,
0271                                             h2SrcStatusEVFAT,
0272                                             h2SrcStatusWVFAT,
0273                                             h2SrcStatusEOH,
0274                                             h2SrcStatusWOH,
0275                                             h2SrcStatusEAMC,
0276                                             h2SrcStatusWAMC,
0277                                             h2SrcStatusEAMC13,
0278                                             nLumiCurr);
0279 
0280     for (const auto &strSuffix : listLayer_) {
0281       if (mapIdxLayer_.find(strSuffix) == mapIdxLayer_.end())
0282         continue;
0283       auto nIdxLayer = mapIdxLayer_[strSuffix];
0284       MonitorElement *h2SrcVFATOcc = store->get(strSrcVFATOcc + strSuffix);
0285       MonitorElement *h2SrcVFATStatusW = store->get(strSrcVFATStatusW + strSuffix);
0286       MonitorElement *h2SrcVFATStatusE = store->get(strSrcVFATStatusE + strSuffix);
0287       if (h2SrcVFATOcc == nullptr || h2SrcVFATStatusW == nullptr || h2SrcVFATStatusE == nullptr)
0288         continue;
0289 
0290       MonitorElement *h2SumVFAT = nullptr;
0291       createSummaryVFAT(store, h2SrcVFATStatusE, strSuffix, h2SumVFAT);
0292       refineSummaryVFAT(strSuffix, h2SumVFAT, h2SrcVFATOcc, h2SrcVFATStatusE, h2SrcVFATStatusW, nLumiCurr, nIdxLayer);
0293       TString strNewTitle = h2SrcVFATStatusE->getTitle();
0294       h2SumVFAT->setTitle((const char *)strNewTitle.ReplaceAll("errors", "errors/warnings"));
0295       h2SumVFAT->setXTitle(h2SrcVFATStatusE->getAxisTitle(1));
0296       h2SumVFAT->setYTitle(h2SrcVFATStatusE->getAxisTitle(2));
0297 
0298       createLumiFuncHist(store, strSuffix, nIdxLayer, nLumiCurr);
0299     }
0300   }
0301 
0302   for (const auto &strSuffix : listLayer_) {
0303     if (mapIdxLayer_.find(strSuffix) == mapIdxLayer_.end())
0304       continue;
0305     Int_t nIdxLayer = mapIdxLayer_[strSuffix];
0306     createInactiveChannelFracHist(store, strSuffix, mapNumChPerChamber_[nIdxLayer]);
0307   }
0308 
0309   store->bookFloat("reportSummary")->Fill(fReportSummary);
0310 }
0311 
0312 void GEMDQMHarvester::createTableWatchingSummary() {
0313   if (bIsStatusChambersInit_)
0314     return;
0315 
0316   for (const auto &[nIdxLayer, nNumCh] : mapNumChPerChamber_) {
0317     for (Int_t i = 1; i <= nNumCh; i++) {
0318       mapStatusChambersSummary_[{nIdxLayer, i}] = std::vector<StatusInfo>();
0319       mapNumStatusChambersSummary_[{nIdxLayer, i}] = NumStatus();
0320       for (Int_t j = 1; j <= nNumVFATs_; j++) {
0321         mapStatusVFATsSummary_[{nIdxLayer, i, j}] = std::vector<StatusInfo>();
0322         mapNumStatusVFATsSummary_[{nIdxLayer, i, j}] = NumStatus();
0323       }
0324     }
0325   }
0326 
0327   bIsStatusChambersInit_ = true;
0328 }
0329 
0330 void GEMDQMHarvester::copyLabels(MonitorElement *h2Src, MonitorElement *h2Dst) {
0331   Int_t nBinX = h2Src->getNbinsX(), nBinY = h2Src->getNbinsY();
0332 
0333   for (Int_t i = 1; i <= nBinX; i++) {
0334     h2Dst->setBinLabel(i, h2Src->getTH2F()->GetXaxis()->GetBinLabel(i), 1);
0335   }
0336   for (Int_t i = 1; i <= nBinY; i++) {
0337     h2Dst->setBinLabel(i, h2Src->getTH2F()->GetYaxis()->GetBinLabel(i), 2);
0338   }
0339   h2Dst->setTitle(h2Src->getTitle());
0340   h2Dst->setXTitle(h2Src->getAxisTitle(1));
0341   h2Dst->setYTitle(h2Src->getAxisTitle(2));
0342 }
0343 
0344 void GEMDQMHarvester::getGeometryInfo(edm::Service<DQMStore> &store, MonitorElement *h2Src) {
0345   listLayer_.clear();
0346   mapIdxLayer_.clear();
0347   mapNumChPerChamber_.clear();
0348 
0349   if (h2Src != nullptr) {  // For online and offline
0350     Int_t nBinY = h2Src->getNbinsY();
0351     listLayer_.push_back("");
0352     Int_t nNumMerge = std::max((Int_t)(h2Src->getBinContent(0, 0) + 0.5), 1);
0353 
0354     for (Int_t i = 1; i <= nBinY; i++) {
0355       std::string strLabelFull = h2Src->getTH2F()->GetYaxis()->GetBinLabel(i);
0356       auto nPos = strLabelFull.find(';');
0357       auto strLayer = strLabelFull.substr(nPos + 1);
0358       Int_t nBinXActual = ((Int_t)(h2Src->getBinContent(0, i) + 0.5)) / nNumMerge;
0359       if (nBinXActual > 108) {  // When the number seems wrong
0360         if (strLayer.find("GE11") != std::string::npos) {
0361           nBinXActual = 36;
0362         } else if (strLayer.find("GE21") != std::string::npos) {
0363           nBinXActual = 18;
0364         } else if (strLayer.find("GE01") != std::string::npos) {
0365           nBinXActual = 36;
0366         }
0367       }
0368       listLayer_.push_back(strLayer);
0369       mapIdxLayer_[strLayer] = i;
0370       mapNumChPerChamber_[i] = nBinXActual;
0371     }
0372   } else {  // For others (validation and...?)
0373     listLayer_.push_back("");
0374     if (store->get("GEM/Digis/occupancy_GE11-M-L1/occ_GE11-M-01L1-S") != nullptr) {
0375       listLayer_.push_back("_GE11-P-L2");
0376       listLayer_.push_back("_GE11-P-L1");
0377       listLayer_.push_back("_GE11-M-L1");
0378       listLayer_.push_back("_GE11-M-L2");
0379       mapIdxLayer_["_GE11-P-L2"] = 1;
0380       mapIdxLayer_["_GE11-P-L1"] = 2;
0381       mapIdxLayer_["_GE11-M-L1"] = 3;
0382       mapIdxLayer_["_GE11-M-L2"] = 4;
0383       mapNumChPerChamber_[1] = 36;
0384       mapNumChPerChamber_[2] = 36;
0385       mapNumChPerChamber_[3] = 36;
0386       mapNumChPerChamber_[4] = 36;
0387     }
0388     // FIXME: How about GE21 and ME0?
0389   }
0390 }
0391 
0392 void GEMDQMHarvester::createSummaryHist(edm::Service<DQMStore> &store, MonitorElement *h2Src, MonitorElement *&h2Sum) {
0393   //store->setCurrentFolder(strDirSummary_);
0394 
0395   Int_t nBinX = h2Src->getNbinsX(), nBinY = h2Src->getNbinsY();
0396   h2Sum = store->book2D("reportSummaryMap", "", nBinX, 0.5, nBinX + 0.5, nBinY, 0.5, nBinY + 0.5);
0397   h2Sum->setTitle("Summary plot");
0398   h2Sum->setXTitle("Chamber");
0399   h2Sum->setYTitle("Layer");
0400 
0401   for (Int_t i = 1; i <= nBinX; i++)
0402     h2Sum->setBinLabel(i, h2Src->getTH2F()->GetXaxis()->GetBinLabel(i), 1);
0403   for (Int_t i = 1; i <= nBinY; i++)
0404     h2Sum->setBinLabel(i, listLayer_[i].substr(1), 2);
0405 }
0406 
0407 void GEMDQMHarvester::createSummaryVFAT(edm::Service<DQMStore> &store,
0408                                         MonitorElement *h2Src,
0409                                         std::string strSuffix,
0410                                         MonitorElement *&h2Sum) {
0411   //store->setCurrentFolder(strDirStatus_);
0412   //store->setCurrentFolder(strDirSummary_);
0413 
0414   Int_t nBinX = h2Src->getNbinsX(), nBinY = h2Src->getNbinsY();
0415   h2Sum = store->book2D("vfat_statusSummary" + strSuffix, "", nBinX, 0.5, nBinX + 0.5, nBinY, -0.5, nBinY - 0.5);
0416   copyLabels(h2Src, h2Sum);
0417 }
0418 
0419 Int_t GEMDQMHarvester::assessOneBin(
0420     std::string strName, Int_t nIdxX, Int_t nIdxY, Float_t fAll, Float_t fNumOcc, Float_t fNumErr, Float_t fNumWarn) {
0421   if (fNumErr < 0)
0422     return nCodeMasked_;
0423   if (fNumErr > fCutErr_ * fAll)  // The error status criterion
0424     return nCodeError_;
0425   else if (fNumErr > fCutLowErr_ * fAll)  // The low-error status criterion
0426     return nCodeLowError_;
0427   else if (fNumWarn > fCutWarn_ * fAll)  // The warning status criterion
0428     return nCodeWarning_;
0429   else if (fNumOcc > 0)
0430     return nCodeFine_;
0431 
0432   return 0;
0433 }
0434 
0435 // FIXME: Need more study about how to summarize
0436 Float_t GEMDQMHarvester::refineSummaryHistogram(std::string strName,
0437                                                 MonitorElement *h2Sum,
0438                                                 std::vector<MonitorElement *> &listOccPlots,
0439                                                 MonitorElement *h2SrcStatusA,
0440                                                 MonitorElement *h2SrcStatusE,
0441                                                 MonitorElement *h2SrcStatusW,
0442                                                 MonitorElement *h2SrcStatusEVFAT,
0443                                                 MonitorElement *h2SrcStatusWVFAT,
0444                                                 MonitorElement *h2SrcStatusEOH,
0445                                                 MonitorElement *h2SrcStatusWOH,
0446                                                 MonitorElement *h2SrcStatusEAMC,
0447                                                 MonitorElement *h2SrcStatusWAMC,
0448                                                 MonitorElement *h2SrcStatusEAMC13,
0449                                                 Int_t nLumiCurr) {
0450   Int_t nBinY = h2Sum->getNbinsY();
0451   Int_t nAllBin = 0, nFineBin = 0;
0452   for (Int_t j = 1; j <= nBinY; j++) {
0453     Int_t nBinX = mapNumChPerChamber_[j];
0454     auto h2SrcOcc = listOccPlots[j];
0455     auto &mapIdxOccChamber = mapIdxToChamberInOcc_[j];
0456     Int_t nBinYOcc = 0;
0457     if (h2SrcOcc != nullptr) {
0458       nBinYOcc = h2SrcOcc->getNbinsY();
0459     }
0460 
0461     h2Sum->setBinContent(0, j, nBinX);
0462     for (Int_t i = 1; i <= nBinX; i++) {
0463       Float_t fOcc = 0;
0464       Int_t nIdxChOcc = mapIdxOccChamber[i];
0465       for (Int_t r = 1; r <= nBinYOcc; r++) {
0466         fOcc += h2SrcOcc->getBinContent(nIdxChOcc, r);
0467       }
0468 
0469       Float_t fStatusAll = h2SrcStatusA->getBinContent(i, j);
0470       Float_t fStatusErr = h2SrcStatusE->getBinContent(i, j);
0471       Float_t fStatusWarn = h2SrcStatusW->getBinContent(i, j);
0472       Float_t fStatusErrVFAT = h2SrcStatusEVFAT != nullptr ? h2SrcStatusEVFAT->getBinContent(i, j) : 0;
0473       Float_t fStatusWarnVFAT = h2SrcStatusWVFAT != nullptr ? h2SrcStatusWVFAT->getBinContent(i, j) : 0;
0474       Float_t fStatusErrOH = h2SrcStatusEOH != nullptr ? h2SrcStatusEOH->getBinContent(i, j) : 0;
0475       Float_t fStatusWarnOH = h2SrcStatusWOH != nullptr ? h2SrcStatusWOH->getBinContent(i, j) : 0;
0476       Float_t fStatusErrAMC = h2SrcStatusEAMC != nullptr ? h2SrcStatusEAMC->getBinContent(i, j) : 0;
0477       Float_t fStatusWarnAMC = h2SrcStatusWAMC != nullptr ? h2SrcStatusWAMC->getBinContent(i, j) : 0;
0478       Float_t fStatusErrAMC13 = h2SrcStatusEAMC13 != nullptr ? h2SrcStatusEAMC13->getBinContent(i, j) : 0;
0479       NumStatus numStatus(fStatusAll,
0480                           fOcc,
0481                           fStatusErrVFAT,
0482                           fStatusWarnVFAT,
0483                           fStatusErrOH,
0484                           fStatusWarnOH,
0485                           fStatusErrAMC,
0486                           fStatusWarnAMC,
0487                           fStatusErrAMC13);
0488       UpdateStatusChamber(j, i, nLumiCurr, numStatus);
0489 
0490       Int_t nRes = assessOneBin(strName, i, j, fStatusAll, fOcc, fStatusErr, fStatusWarn);
0491       if (nRes == 1)
0492         nFineBin++;
0493 
0494       h2Sum->setBinContent(i, j, (Float_t)nRes);
0495       nAllBin++;
0496     }
0497   }
0498 
0499   return ((Float_t)nFineBin) / nAllBin;
0500 }
0501 
0502 Int_t GEMDQMHarvester::refineSummaryVFAT(std::string strName,
0503                                          MonitorElement *h2Sum,
0504                                          MonitorElement *h2SrcOcc,
0505                                          MonitorElement *h2SrcStatusE,
0506                                          MonitorElement *h2SrcStatusW,
0507                                          Int_t nLumiCurr,
0508                                          Int_t nIdxLayer) {
0509   Int_t nBinY = h2Sum->getNbinsY();
0510   for (Int_t j = 1; j <= nBinY; j++) {
0511     Int_t nBinX = h2Sum->getNbinsX();
0512     for (Int_t i = 1; i <= nBinX; i++) {
0513       Float_t fOcc = h2SrcOcc->getBinContent(i, j);
0514       Float_t fStatusErr = h2SrcStatusE->getBinContent(i, j);
0515       Float_t fStatusWarn = h2SrcStatusW->getBinContent(i, j);
0516       Float_t fStatusAll = fOcc + fStatusErr + fStatusWarn;
0517       NumStatus numStatus(fStatusAll, fOcc, fStatusErr, fStatusWarn, 0, 0, 0, 0, 0);
0518       UpdateStatusChamber(nIdxLayer, i, j, nLumiCurr, numStatus);
0519 
0520       Int_t nRes = assessOneBin(strName, i, j, fStatusAll, fOcc, fStatusErr, fStatusWarn);
0521       h2Sum->setBinContent(i, j, (Float_t)nRes);
0522     }
0523   }
0524 
0525   return 0;
0526 }
0527 
0528 Int_t GEMDQMHarvester::UpdateStatusChamber(Int_t nIdxLayer, Int_t nIdxCh, Int_t nLumiCurr, NumStatus numStatus) {
0529   if (!bIsStatusChambersInit_)
0530     return 0;
0531   if (0 >= nIdxCh || nIdxCh > mapNumChPerChamber_[nIdxLayer])
0532     return 0;
0533   auto &listStatus = mapStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0534   auto &numStatusPrev = mapNumStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0535   return UpdateStatusChamber(listStatus, numStatusPrev, nLumiCurr, numStatus);
0536 }
0537 
0538 Int_t GEMDQMHarvester::UpdateStatusChamber(
0539     Int_t nIdxLayer, Int_t nIdxCh, Int_t nIdxVFAT, Int_t nLumiCurr, NumStatus numStatus) {
0540   if (!bIsStatusChambersInit_)
0541     return 0;
0542   if (0 >= nIdxCh || nIdxCh > mapNumChPerChamber_[nIdxLayer])
0543     return 0;
0544   if (0 >= nIdxVFAT || nIdxVFAT > nNumVFATs_)
0545     return 0;
0546   auto &listStatus = mapStatusVFATsSummary_[{nIdxLayer, nIdxCh, nIdxVFAT}];
0547   auto &numStatusPrev = mapNumStatusVFATsSummary_[{nIdxLayer, nIdxCh, nIdxVFAT}];
0548   return UpdateStatusChamber(listStatus, numStatusPrev, nLumiCurr, numStatus);
0549 }
0550 
0551 Int_t GEMDQMHarvester::UpdateStatusChamber(std::vector<StatusInfo> &listStatus,
0552                                            NumStatus &numStatus,
0553                                            Int_t nLumiCurr,
0554                                            NumStatus numStatusNew) {
0555   // First of all, the current lumi section will be assessed, of which the result will be stored in nStatus
0556   Int_t nStatus = 0;
0557 
0558   Float_t fNumAddErrVFAT = numStatusNew.fNumErrVFAT_ - numStatus.fNumErrVFAT_;
0559   Float_t fNumAddWarnVFAT = numStatusNew.fNumWarnVFAT_ - numStatus.fNumWarnVFAT_;
0560   Float_t fNumAddErrOH = numStatusNew.fNumErrOH_ - numStatus.fNumErrOH_;
0561   Float_t fNumAddWarnOH = numStatusNew.fNumWarnOH_ - numStatus.fNumWarnOH_;
0562   Float_t fNumAddErrAMC = numStatusNew.fNumErrAMC_ - numStatus.fNumErrAMC_;
0563   Float_t fNumAddWarnAMC = numStatusNew.fNumWarnAMC_ - numStatus.fNumWarnAMC_;
0564   Float_t fNumAddErrAMC13 = numStatusNew.fNumErrAMC13_ - numStatus.fNumErrAMC13_;
0565 
0566   numStatus.fNumTotal_ = numStatusNew.fNumTotal_;
0567   numStatus.fNumOcc_ = numStatusNew.fNumOcc_;
0568   numStatus.fNumErrVFAT_ = numStatusNew.fNumErrVFAT_;
0569   numStatus.fNumWarnVFAT_ = numStatusNew.fNumWarnVFAT_;
0570   numStatus.fNumErrOH_ = numStatusNew.fNumErrOH_;
0571   numStatus.fNumWarnOH_ = numStatusNew.fNumWarnOH_;
0572   numStatus.fNumErrAMC_ = numStatusNew.fNumErrAMC_;
0573   numStatus.fNumWarnAMC_ = numStatusNew.fNumWarnAMC_;
0574   numStatus.fNumErrAMC13_ = numStatusNew.fNumErrAMC13_;
0575 
0576   nStatus = (numStatusNew.fNumOcc_ > 0 ? 1 << nBitOcc_ : 0) | (fNumAddErrAMC13 > 0 ? 1 << nBitErrAMC13_ : 0) |
0577             (fNumAddErrAMC > 0 ? 1 << nBitErrAMC_ : 0) | (fNumAddWarnAMC > 0 ? 1 << nBitWarnAMC_ : 0) |
0578             (fNumAddErrOH > 0 ? 1 << nBitErrOH_ : 0) | (fNumAddWarnOH > 0 ? 1 << nBitWarnOH_ : 0) |
0579             (fNumAddErrVFAT > 0 ? 1 << nBitErrVFAT_ : 0) | (fNumAddWarnVFAT > 0 ? 1 << nBitWarnVFAT_ : 0);
0580 
0581   // Only used in the next if statement; See statusLast
0582   StatusInfo statusNew;
0583   statusNew.nLumiStart = nLumiCurr;
0584   statusNew.nLumiEnd = nLumiCurr;
0585   statusNew.nStatus = nStatus;
0586 
0587   if (listStatus.empty()) {
0588     listStatus.push_back(statusNew);
0589   } else {
0590     auto &statusLastPre = listStatus.back();
0591     if (statusLastPre.nStatus == nStatus) {
0592       statusLastPre.nLumiEnd = nLumiCurr;
0593     } else {
0594       listStatus.push_back(statusNew);
0595     }
0596   }
0597 
0598   return 0;
0599 }
0600 
0601 void GEMDQMHarvester::createLumiFuncHist(edm::Service<DQMStore> &store,
0602                                          std::string strSuffix,
0603                                          Int_t nIdxLayer,
0604                                          Int_t nLumiCurr) {
0605   auto &nNumCh = mapNumChPerChamber_[nIdxLayer];
0606 
0607   MonitorElement *h2Summary;
0608 
0609   //Int_t nLumiCurrLowRes = ( ( nLumiCurr - 1 ) / nResolutionLumi_ ) * nResolutionLumi_;
0610   Int_t nNumBinLumi = ((nLumiCurr - 1) / nResolutionLumi_) + 1;
0611   Int_t nMaxBin = 0;
0612 
0613   // Creating or Summoning the corresponding histogram
0614   if (mapHistLumiFunc_.find(nIdxLayer) == mapHistLumiFunc_.end()) {
0615     store->setCurrentFolder(strDirSummary_);
0616     h2Summary = store->book2S("chamberStatus_inLumi" + strSuffix,
0617                               "Chamber status on lumi-block " + strSuffix.substr(1),
0618                               nMaxLumi_ / nResolutionLumi_,
0619                               1.0,
0620                               (Float_t)(nMaxLumi_ + 1),
0621                               //nNumBinLumi, 1.0, (Float_t)( nLumiCurr + 1 ),
0622                               nNumCh,
0623                               0.5,
0624                               nNumCh + 0.5);
0625     mapHistLumiFunc_[nIdxLayer] = h2Summary;
0626 
0627     h2Summary->setXTitle("Luminosity block");
0628     h2Summary->setYTitle("Chamber");
0629     for (Int_t i = 1; i <= nNumCh; i++) {
0630       h2Summary->setBinLabel(i, Form("%i", i), 2);
0631     }
0632   } else {
0633     h2Summary = mapHistLumiFunc_[nIdxLayer];
0634   }
0635 
0636   for (Int_t nIdxCh = 1; nIdxCh <= nNumCh; nIdxCh++) {
0637     auto &listStatus = mapStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0638 
0639     Int_t nIdxStatus = 0;
0640     for (Int_t nIdxLumi = 0; nIdxLumi < nNumBinLumi; nIdxLumi++) {
0641       // Lumis covered by these values (nLumiStart <=, <= nLumiEnd) are counted for the current bin
0642       Int_t nLumiStart = 1 + nIdxLumi * nResolutionLumi_;
0643       Int_t nLumiEnd = (1 + nIdxLumi) * nResolutionLumi_;
0644       if (nLumiEnd > nLumiCurr)
0645         nLumiEnd = nLumiCurr;
0646 
0647       Int_t nStatusSum = 0;
0648       while (true) {  // No worries, nIdxStatus must increase and reach at listStatus.size()
0649         // True: It was too past so that
0650         //       the lumi range of listStatus[ nIdxStatus ] is out of the coverage of the current bin
0651         if (listStatus[nIdxStatus].nLumiEnd < nLumiStart) {
0652           nIdxStatus++;
0653           if (nIdxStatus >= (int)listStatus.size()) {
0654             break;  // For safety
0655           }
0656           continue;
0657         }
0658 
0659         nStatusSum = listStatus[nIdxStatus].nStatus;
0660 
0661         // True: This is the last item of listStatus which is covered by the current bin
0662         if (nIdxStatus + 1 >= (int)listStatus.size() || listStatus[nIdxStatus].nLumiEnd >= nLumiEnd) {
0663           break;
0664         }
0665 
0666         nIdxStatus++;
0667         if (nIdxStatus >= (int)listStatus.size()) {
0668           break;  // For safety
0669         }
0670       }
0671 
0672       h2Summary->setBinContent(nIdxLumi + 1, nIdxCh, nStatusSum);
0673       if (nMaxBin < nIdxLumi + 1)
0674         nMaxBin = nIdxLumi + 1;
0675     }
0676   }
0677 
0678   for (Int_t nX = 1; nX <= nMaxBin; nX++) {
0679     h2Summary->setBinContent(nX, 0, 1);
0680   }
0681 }
0682 
0683 std::string getNameChamberOccGE11(std::string strSuffix, Int_t nIdxCh) {
0684   char cRegion;
0685   char cChType = (nIdxCh % 2 == 0 ? 'L' : 'S');
0686   Int_t nLayer;
0687 
0688   if (strSuffix.find("-M-") != std::string::npos)
0689     cRegion = 'M';
0690   else if (strSuffix.find("-P-") != std::string::npos)
0691     cRegion = 'P';
0692   else
0693     return "";
0694 
0695   if (strSuffix.find("-L1") != std::string::npos)
0696     nLayer = 1;
0697   else if (strSuffix.find("-L2") != std::string::npos)
0698     nLayer = 2;
0699   else
0700     return "";
0701 
0702   return Form(
0703       "GEM/Digis/occupancy_GE11-%c-L%i/occ_GE11-%c-%02iL%i-%c", cRegion, nLayer, cRegion, nIdxCh, nLayer, cChType);
0704 }
0705 
0706 // FIXME: The naming convention of GE21 could be changed to be different from GE11
0707 std::string getNameChamberOccGE21(std::string strSuffix, Int_t nIdxCh) {
0708   char cRegion;
0709   char cChType = (nIdxCh % 2 == 0 ? 'L' : 'S');
0710   Int_t nLayer;
0711   Int_t nModule;
0712 
0713   if (strSuffix.find("-M-") != std::string::npos)
0714     cRegion = 'M';
0715   else if (strSuffix.find("-P-") != std::string::npos)
0716     cRegion = 'P';
0717   else
0718     return "";
0719 
0720   if (strSuffix.find("-L1") != std::string::npos)
0721     nLayer = 1;
0722   else if (strSuffix.find("-L2") != std::string::npos)
0723     nLayer = 2;
0724   else
0725     return "";
0726 
0727   if (strSuffix.find("-M1") != std::string::npos)
0728     nModule = 1;
0729   else if (strSuffix.find("-M2") != std::string::npos)
0730     nModule = 2;
0731   else if (strSuffix.find("-M3") != std::string::npos)
0732     nModule = 3;
0733   else if (strSuffix.find("-M4") != std::string::npos)
0734     nModule = 4;
0735   else if (strSuffix.find("-M5") != std::string::npos)
0736     nModule = 5;
0737   else if (strSuffix.find("-M6") != std::string::npos)
0738     nModule = 6;
0739   else if (strSuffix.find("-M7") != std::string::npos)
0740     nModule = 7;
0741   else if (strSuffix.find("-M8") != std::string::npos)
0742     nModule = 8;
0743   else
0744     return "";
0745 
0746   return Form("GEM/Digis/occupancy_GE21-%c-L%i-M%i/occ_GE21-%c-%02iL%i-M%i-%c",
0747               cRegion,
0748               nLayer,
0749               nModule,
0750               cRegion,
0751               nIdxCh,
0752               nLayer,
0753               nModule,
0754               cChType);
0755 }
0756 
0757 std::string getNameChamberOccNull(std::string strSuffix, Int_t nIdxChamber) {
0758   return "";  // For an initialization
0759 }
0760 
0761 void GEMDQMHarvester::createInactiveChannelFracHist(edm::Service<DQMStore> &store,
0762                                                     std::string strSuffix,
0763                                                     Int_t nNumChamber) {
0764   std::string strTitle = "The fraction of inactive channels in " + strSuffix.substr(1);
0765   MonitorElement *h2InactiveChannel =
0766       store->book1D("inactive_frac_chamber" + strSuffix, strTitle, nNumChamber, 0.5, nNumChamber + 0.5);
0767   h2InactiveChannel->setXTitle("Chamber");
0768   h2InactiveChannel->setYTitle("Fraction of inactive channels");
0769   for (Int_t i = 1; i <= nNumChamber; i++) {
0770     h2InactiveChannel->setBinLabel(i, Form("%i", i), 1);
0771   }
0772 
0773   std::string (*funcNameCh)(std::string, Int_t) = getNameChamberOccNull;
0774 
0775   if (strSuffix.find("_GE11") != std::string::npos) {
0776     funcNameCh = getNameChamberOccGE11;
0777   } else if (strSuffix.find("_GE21") != std::string::npos) {
0778     funcNameCh = getNameChamberOccGE21;
0779   }
0780 
0781   for (Int_t nIdxCh = 1; nIdxCh <= nNumChamber; nIdxCh++) {
0782     std::string strNameCh = funcNameCh(strSuffix, nIdxCh);
0783     MonitorElement *h2SrcChamberOcc = store->get(strNameCh);
0784     if (h2SrcChamberOcc == nullptr) {
0785       // FIXME: It's about sending a message
0786       continue;
0787     }
0788 
0789     Int_t nNumBinX = h2SrcChamberOcc->getNbinsX();
0790     Int_t nNumBinY = h2SrcChamberOcc->getNbinsY();
0791     Int_t nNumAllChannel = nNumBinX * nNumBinY;
0792     auto *histData = h2SrcChamberOcc->getTH2F();
0793     auto *pdData = histData->GetArray();
0794     Int_t nNumChannelInactive = 0;
0795     for (Int_t j = 1; j <= nNumBinY; j++)
0796       for (Int_t i = 1; i <= nNumBinX; i++) {
0797         if (pdData[j * (nNumBinX + 2) + i] <= 0) {
0798           nNumChannelInactive++;
0799         }
0800       }
0801     h2InactiveChannel->setBinContent(nIdxCh, ((Double_t)nNumChannelInactive) / nNumAllChannel);
0802   }
0803 }
0804 
0805 DEFINE_FWK_MODULE(GEMDQMHarvester);