Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:42:11

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 
0353     for (Int_t i = 1; i <= nBinY; i++) {
0354       std::string strLabelFull = h2Src->getTH2F()->GetYaxis()->GetBinLabel(i);
0355       auto nPos = strLabelFull.find(';');
0356       auto strLayer = strLabelFull.substr(nPos + 1);
0357       Int_t nBinXActual = (Int_t)(h2Src->getBinContent(0, i) + 0.5);
0358       if (nBinXActual > 108) {  // When the number seems wrong
0359         if (strLayer.find("GE11") != std::string::npos) {
0360           nBinXActual = 36;
0361         } else if (strLayer.find("GE21") != std::string::npos) {
0362           nBinXActual = 18;
0363         } else if (strLayer.find("GE01") != std::string::npos) {
0364           nBinXActual = 36;
0365         }
0366       }
0367       listLayer_.push_back(strLayer);
0368       mapIdxLayer_[strLayer] = i;
0369       mapNumChPerChamber_[i] = nBinXActual;
0370     }
0371   } else {  // For others (validation and...?)
0372     listLayer_.push_back("");
0373     if (store->get("GEM/Digis/occupancy_GE11-M-L1/occ_GE11-M-01L1-S") != nullptr) {
0374       listLayer_.push_back("_GE11-P-L2");
0375       listLayer_.push_back("_GE11-P-L1");
0376       listLayer_.push_back("_GE11-M-L1");
0377       listLayer_.push_back("_GE11-M-L2");
0378       mapIdxLayer_["_GE11-P-L2"] = 1;
0379       mapIdxLayer_["_GE11-P-L1"] = 2;
0380       mapIdxLayer_["_GE11-M-L1"] = 3;
0381       mapIdxLayer_["_GE11-M-L2"] = 4;
0382       mapNumChPerChamber_[1] = 36;
0383       mapNumChPerChamber_[2] = 36;
0384       mapNumChPerChamber_[3] = 36;
0385       mapNumChPerChamber_[4] = 36;
0386     }
0387     // FIXME: How about GE21 and ME0?
0388   }
0389 }
0390 
0391 void GEMDQMHarvester::createSummaryHist(edm::Service<DQMStore> &store, MonitorElement *h2Src, MonitorElement *&h2Sum) {
0392   //store->setCurrentFolder(strDirSummary_);
0393 
0394   Int_t nBinX = h2Src->getNbinsX(), nBinY = h2Src->getNbinsY();
0395   h2Sum = store->book2D("reportSummaryMap", "", nBinX, 0.5, nBinX + 0.5, nBinY, 0.5, nBinY + 0.5);
0396   h2Sum->setTitle("Summary plot");
0397   h2Sum->setXTitle("Chamber");
0398   h2Sum->setYTitle("Layer");
0399 
0400   for (Int_t i = 1; i <= nBinX; i++)
0401     h2Sum->setBinLabel(i, h2Src->getTH2F()->GetXaxis()->GetBinLabel(i), 1);
0402   for (Int_t i = 1; i <= nBinY; i++)
0403     h2Sum->setBinLabel(i, listLayer_[i].substr(1), 2);
0404 }
0405 
0406 void GEMDQMHarvester::createSummaryVFAT(edm::Service<DQMStore> &store,
0407                                         MonitorElement *h2Src,
0408                                         std::string strSuffix,
0409                                         MonitorElement *&h2Sum) {
0410   //store->setCurrentFolder(strDirStatus_);
0411   //store->setCurrentFolder(strDirSummary_);
0412 
0413   Int_t nBinX = h2Src->getNbinsX(), nBinY = h2Src->getNbinsY();
0414   h2Sum = store->book2D("vfat_statusSummary" + strSuffix, "", nBinX, 0.5, nBinX + 0.5, nBinY, -0.5, nBinY - 0.5);
0415   copyLabels(h2Src, h2Sum);
0416 }
0417 
0418 Int_t GEMDQMHarvester::assessOneBin(
0419     std::string strName, Int_t nIdxX, Int_t nIdxY, Float_t fAll, Float_t fNumOcc, Float_t fNumErr, Float_t fNumWarn) {
0420   if (fNumErr < 0)
0421     return nCodeMasked_;
0422   if (fNumErr > fCutErr_ * fAll)  // The error status criterion
0423     return nCodeError_;
0424   else if (fNumErr > fCutLowErr_ * fAll)  // The low-error status criterion
0425     return nCodeLowError_;
0426   else if (fNumWarn > fCutWarn_ * fAll)  // The warning status criterion
0427     return nCodeWarning_;
0428   else if (fNumOcc > 0)
0429     return nCodeFine_;
0430 
0431   return 0;
0432 }
0433 
0434 // FIXME: Need more study about how to summarize
0435 Float_t GEMDQMHarvester::refineSummaryHistogram(std::string strName,
0436                                                 MonitorElement *h2Sum,
0437                                                 std::vector<MonitorElement *> &listOccPlots,
0438                                                 MonitorElement *h2SrcStatusA,
0439                                                 MonitorElement *h2SrcStatusE,
0440                                                 MonitorElement *h2SrcStatusW,
0441                                                 MonitorElement *h2SrcStatusEVFAT,
0442                                                 MonitorElement *h2SrcStatusWVFAT,
0443                                                 MonitorElement *h2SrcStatusEOH,
0444                                                 MonitorElement *h2SrcStatusWOH,
0445                                                 MonitorElement *h2SrcStatusEAMC,
0446                                                 MonitorElement *h2SrcStatusWAMC,
0447                                                 MonitorElement *h2SrcStatusEAMC13,
0448                                                 Int_t nLumiCurr) {
0449   Int_t nBinY = h2Sum->getNbinsY();
0450   Int_t nAllBin = 0, nFineBin = 0;
0451   for (Int_t j = 1; j <= nBinY; j++) {
0452     Int_t nBinX = mapNumChPerChamber_[j];
0453     auto h2SrcOcc = listOccPlots[j];
0454     auto &mapIdxOccChamber = mapIdxToChamberInOcc_[j];
0455     Int_t nBinYOcc = 0;
0456     if (h2SrcOcc != nullptr) {
0457       nBinYOcc = h2SrcOcc->getNbinsY();
0458     }
0459 
0460     h2Sum->setBinContent(0, j, nBinX);
0461     for (Int_t i = 1; i <= nBinX; i++) {
0462       Float_t fOcc = 0;
0463       Int_t nIdxChOcc = mapIdxOccChamber[i];
0464       for (Int_t r = 1; r <= nBinYOcc; r++) {
0465         fOcc += h2SrcOcc->getBinContent(nIdxChOcc, r);
0466       }
0467 
0468       Float_t fStatusAll = h2SrcStatusA->getBinContent(i, j);
0469       Float_t fStatusErr = h2SrcStatusE->getBinContent(i, j);
0470       Float_t fStatusWarn = h2SrcStatusW->getBinContent(i, j);
0471       Float_t fStatusErrVFAT = h2SrcStatusEVFAT != nullptr ? h2SrcStatusEVFAT->getBinContent(i, j) : 0;
0472       Float_t fStatusWarnVFAT = h2SrcStatusWVFAT != nullptr ? h2SrcStatusWVFAT->getBinContent(i, j) : 0;
0473       Float_t fStatusErrOH = h2SrcStatusEOH != nullptr ? h2SrcStatusEOH->getBinContent(i, j) : 0;
0474       Float_t fStatusWarnOH = h2SrcStatusWOH != nullptr ? h2SrcStatusWOH->getBinContent(i, j) : 0;
0475       Float_t fStatusErrAMC = h2SrcStatusEAMC != nullptr ? h2SrcStatusEAMC->getBinContent(i, j) : 0;
0476       Float_t fStatusWarnAMC = h2SrcStatusWAMC != nullptr ? h2SrcStatusWAMC->getBinContent(i, j) : 0;
0477       Float_t fStatusErrAMC13 = h2SrcStatusEAMC13 != nullptr ? h2SrcStatusEAMC13->getBinContent(i, j) : 0;
0478       NumStatus numStatus(fStatusAll,
0479                           fOcc,
0480                           fStatusErrVFAT,
0481                           fStatusWarnVFAT,
0482                           fStatusErrOH,
0483                           fStatusWarnOH,
0484                           fStatusErrAMC,
0485                           fStatusWarnAMC,
0486                           fStatusErrAMC13);
0487       UpdateStatusChamber(j, i, nLumiCurr, numStatus);
0488 
0489       Int_t nRes = assessOneBin(strName, i, j, fStatusAll, fOcc, fStatusErr, fStatusWarn);
0490       if (nRes == 1)
0491         nFineBin++;
0492 
0493       h2Sum->setBinContent(i, j, (Float_t)nRes);
0494       nAllBin++;
0495     }
0496   }
0497 
0498   return ((Float_t)nFineBin) / nAllBin;
0499 }
0500 
0501 Int_t GEMDQMHarvester::refineSummaryVFAT(std::string strName,
0502                                          MonitorElement *h2Sum,
0503                                          MonitorElement *h2SrcOcc,
0504                                          MonitorElement *h2SrcStatusE,
0505                                          MonitorElement *h2SrcStatusW,
0506                                          Int_t nLumiCurr,
0507                                          Int_t nIdxLayer) {
0508   Int_t nBinY = h2Sum->getNbinsY();
0509   for (Int_t j = 1; j <= nBinY; j++) {
0510     Int_t nBinX = h2Sum->getNbinsX();
0511     for (Int_t i = 1; i <= nBinX; i++) {
0512       Float_t fOcc = h2SrcOcc->getBinContent(i, j);
0513       Float_t fStatusErr = h2SrcStatusE->getBinContent(i, j);
0514       Float_t fStatusWarn = h2SrcStatusW->getBinContent(i, j);
0515       Float_t fStatusAll = fOcc + fStatusErr + fStatusWarn;
0516       NumStatus numStatus(fStatusAll, fOcc, fStatusErr, fStatusWarn, 0, 0, 0, 0, 0);
0517       UpdateStatusChamber(nIdxLayer, i, j, nLumiCurr, numStatus);
0518 
0519       Int_t nRes = assessOneBin(strName, i, j, fStatusAll, fOcc, fStatusErr, fStatusWarn);
0520       h2Sum->setBinContent(i, j, (Float_t)nRes);
0521     }
0522   }
0523 
0524   return 0;
0525 }
0526 
0527 Int_t GEMDQMHarvester::UpdateStatusChamber(Int_t nIdxLayer, Int_t nIdxCh, Int_t nLumiCurr, NumStatus numStatus) {
0528   if (!bIsStatusChambersInit_)
0529     return 0;
0530   if (0 >= nIdxCh || nIdxCh > mapNumChPerChamber_[nIdxLayer])
0531     return 0;
0532   auto &listStatus = mapStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0533   auto &numStatusPrev = mapNumStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0534   return UpdateStatusChamber(listStatus, numStatusPrev, nLumiCurr, numStatus);
0535 }
0536 
0537 Int_t GEMDQMHarvester::UpdateStatusChamber(
0538     Int_t nIdxLayer, Int_t nIdxCh, Int_t nIdxVFAT, Int_t nLumiCurr, NumStatus numStatus) {
0539   if (!bIsStatusChambersInit_)
0540     return 0;
0541   if (0 >= nIdxCh || nIdxCh > mapNumChPerChamber_[nIdxLayer])
0542     return 0;
0543   if (0 >= nIdxVFAT || nIdxVFAT > nNumVFATs_)
0544     return 0;
0545   auto &listStatus = mapStatusVFATsSummary_[{nIdxLayer, nIdxCh, nIdxVFAT}];
0546   auto &numStatusPrev = mapNumStatusVFATsSummary_[{nIdxLayer, nIdxCh, nIdxVFAT}];
0547   return UpdateStatusChamber(listStatus, numStatusPrev, nLumiCurr, numStatus);
0548 }
0549 
0550 Int_t GEMDQMHarvester::UpdateStatusChamber(std::vector<StatusInfo> &listStatus,
0551                                            NumStatus &numStatus,
0552                                            Int_t nLumiCurr,
0553                                            NumStatus numStatusNew) {
0554   // First of all, the current lumi section will be assessed, of which the result will be stored in nStatus
0555   Int_t nStatus = 0;
0556 
0557   Float_t fNumAddErrVFAT = numStatusNew.fNumErrVFAT_ - numStatus.fNumErrVFAT_;
0558   Float_t fNumAddWarnVFAT = numStatusNew.fNumWarnVFAT_ - numStatus.fNumWarnVFAT_;
0559   Float_t fNumAddErrOH = numStatusNew.fNumErrOH_ - numStatus.fNumErrOH_;
0560   Float_t fNumAddWarnOH = numStatusNew.fNumWarnOH_ - numStatus.fNumWarnOH_;
0561   Float_t fNumAddErrAMC = numStatusNew.fNumErrAMC_ - numStatus.fNumErrAMC_;
0562   Float_t fNumAddWarnAMC = numStatusNew.fNumWarnAMC_ - numStatus.fNumWarnAMC_;
0563   Float_t fNumAddErrAMC13 = numStatusNew.fNumErrAMC13_ - numStatus.fNumErrAMC13_;
0564 
0565   numStatus.fNumTotal_ = numStatusNew.fNumTotal_;
0566   numStatus.fNumOcc_ = numStatusNew.fNumOcc_;
0567   numStatus.fNumErrVFAT_ = numStatusNew.fNumErrVFAT_;
0568   numStatus.fNumWarnVFAT_ = numStatusNew.fNumWarnVFAT_;
0569   numStatus.fNumErrOH_ = numStatusNew.fNumErrOH_;
0570   numStatus.fNumWarnOH_ = numStatusNew.fNumWarnOH_;
0571   numStatus.fNumErrAMC_ = numStatusNew.fNumErrAMC_;
0572   numStatus.fNumWarnAMC_ = numStatusNew.fNumWarnAMC_;
0573   numStatus.fNumErrAMC13_ = numStatusNew.fNumErrAMC13_;
0574 
0575   nStatus = (numStatusNew.fNumOcc_ > 0 ? 1 << nBitOcc_ : 0) | (fNumAddErrAMC13 > 0 ? 1 << nBitErrAMC13_ : 0) |
0576             (fNumAddErrAMC > 0 ? 1 << nBitErrAMC_ : 0) | (fNumAddWarnAMC > 0 ? 1 << nBitWarnAMC_ : 0) |
0577             (fNumAddErrOH > 0 ? 1 << nBitErrOH_ : 0) | (fNumAddWarnOH > 0 ? 1 << nBitWarnOH_ : 0) |
0578             (fNumAddErrVFAT > 0 ? 1 << nBitErrVFAT_ : 0) | (fNumAddWarnVFAT > 0 ? 1 << nBitWarnVFAT_ : 0);
0579 
0580   // Only used in the next if statement; See statusLast
0581   StatusInfo statusNew;
0582   statusNew.nLumiStart = nLumiCurr;
0583   statusNew.nLumiEnd = nLumiCurr;
0584   statusNew.nStatus = nStatus;
0585 
0586   if (listStatus.empty()) {
0587     listStatus.push_back(statusNew);
0588   } else {
0589     auto &statusLastPre = listStatus.back();
0590     if (statusLastPre.nStatus == nStatus) {
0591       statusLastPre.nLumiEnd = nLumiCurr;
0592     } else {
0593       listStatus.push_back(statusNew);
0594     }
0595   }
0596 
0597   return 0;
0598 }
0599 
0600 void GEMDQMHarvester::createLumiFuncHist(edm::Service<DQMStore> &store,
0601                                          std::string strSuffix,
0602                                          Int_t nIdxLayer,
0603                                          Int_t nLumiCurr) {
0604   auto &nNumCh = mapNumChPerChamber_[nIdxLayer];
0605 
0606   MonitorElement *h2Summary;
0607 
0608   //Int_t nLumiCurrLowRes = ( ( nLumiCurr - 1 ) / nResolutionLumi_ ) * nResolutionLumi_;
0609   Int_t nNumBinLumi = ((nLumiCurr - 1) / nResolutionLumi_) + 1;
0610   Int_t nMaxBin = 0;
0611 
0612   // Creating or Summoning the corresponding histogram
0613   if (mapHistLumiFunc_.find(nIdxLayer) == mapHistLumiFunc_.end()) {
0614     store->setCurrentFolder(strDirSummary_);
0615     h2Summary = store->book2S("chamberStatus_inLumi" + strSuffix,
0616                               "Chamber status on lumi-block " + strSuffix.substr(1),
0617                               nMaxLumi_ / nResolutionLumi_,
0618                               1.0,
0619                               (Float_t)(nMaxLumi_ + 1),
0620                               //nNumBinLumi, 1.0, (Float_t)( nLumiCurr + 1 ),
0621                               nNumCh,
0622                               0.5,
0623                               nNumCh + 0.5);
0624     mapHistLumiFunc_[nIdxLayer] = h2Summary;
0625 
0626     h2Summary->setXTitle("Luminosity block");
0627     h2Summary->setYTitle("Chamber");
0628     for (Int_t i = 1; i <= nNumCh; i++) {
0629       h2Summary->setBinLabel(i, Form("%i", i), 2);
0630     }
0631   } else {
0632     h2Summary = mapHistLumiFunc_[nIdxLayer];
0633   }
0634 
0635   for (Int_t nIdxCh = 1; nIdxCh <= nNumCh; nIdxCh++) {
0636     auto &listStatus = mapStatusChambersSummary_[{nIdxLayer, nIdxCh}];
0637 
0638     Int_t nIdxStatus = 0;
0639     for (Int_t nIdxLumi = 0; nIdxLumi < nNumBinLumi; nIdxLumi++) {
0640       // Lumis covered by these values (nLumiStart <=, <= nLumiEnd) are counted for the current bin
0641       Int_t nLumiStart = 1 + nIdxLumi * nResolutionLumi_;
0642       Int_t nLumiEnd = (1 + nIdxLumi) * nResolutionLumi_;
0643       if (nLumiEnd > nLumiCurr)
0644         nLumiEnd = nLumiCurr;
0645 
0646       Int_t nStatusSum = 0;
0647       while (true) {  // No worries, nIdxStatus must increase and reach at listStatus.size()
0648         // True: It was too past so that
0649         //       the lumi range of listStatus[ nIdxStatus ] is out of the coverage of the current bin
0650         if (listStatus[nIdxStatus].nLumiEnd < nLumiStart) {
0651           nIdxStatus++;
0652           if (nIdxStatus >= (int)listStatus.size()) {
0653             break;  // For safety
0654           }
0655           continue;
0656         }
0657 
0658         nStatusSum = listStatus[nIdxStatus].nStatus;
0659 
0660         // True: This is the last item of listStatus which is covered by the current bin
0661         if (nIdxStatus + 1 >= (int)listStatus.size() || listStatus[nIdxStatus].nLumiEnd >= nLumiEnd) {
0662           break;
0663         }
0664 
0665         nIdxStatus++;
0666         if (nIdxStatus >= (int)listStatus.size()) {
0667           break;  // For safety
0668         }
0669       }
0670 
0671       h2Summary->setBinContent(nIdxLumi + 1, nIdxCh, nStatusSum);
0672       if (nMaxBin < nIdxLumi + 1)
0673         nMaxBin = nIdxLumi + 1;
0674     }
0675   }
0676 
0677   for (Int_t nX = 1; nX <= nMaxBin; nX++) {
0678     h2Summary->setBinContent(nX, 0, 1);
0679   }
0680 }
0681 
0682 std::string getNameChamberOccGE11(std::string strSuffix, Int_t nIdxCh) {
0683   char cRegion;
0684   char cChType = (nIdxCh % 2 == 0 ? 'L' : 'S');
0685   Int_t nLayer;
0686 
0687   if (strSuffix.find("-M-") != std::string::npos)
0688     cRegion = 'M';
0689   else if (strSuffix.find("-P-") != std::string::npos)
0690     cRegion = 'P';
0691   else
0692     return "";
0693 
0694   if (strSuffix.find("-L1") != std::string::npos)
0695     nLayer = 1;
0696   else if (strSuffix.find("-L2") != std::string::npos)
0697     nLayer = 2;
0698   else
0699     return "";
0700 
0701   return Form(
0702       "GEM/Digis/occupancy_GE11-%c-L%i/occ_GE11-%c-%02iL%i-%c", cRegion, nLayer, cRegion, nIdxCh, nLayer, cChType);
0703 }
0704 
0705 // FIXME: The naming convention of GE21 could be changed to be different from GE11
0706 std::string getNameChamberOccGE21(std::string strSuffix, Int_t nIdxCh) {
0707   char cRegion;
0708   char cChType = (nIdxCh % 2 == 0 ? 'L' : 'S');
0709   Int_t nLayer;
0710   Int_t nModule;
0711 
0712   if (strSuffix.find("-M-") != std::string::npos)
0713     cRegion = 'M';
0714   else if (strSuffix.find("-P-") != std::string::npos)
0715     cRegion = 'P';
0716   else
0717     return "";
0718 
0719   if (strSuffix.find("-L1") != std::string::npos)
0720     nLayer = 1;
0721   else if (strSuffix.find("-L2") != std::string::npos)
0722     nLayer = 2;
0723   else
0724     return "";
0725 
0726   if (strSuffix.find("-M1") != std::string::npos)
0727     nModule = 1;
0728   else if (strSuffix.find("-M2") != std::string::npos)
0729     nModule = 2;
0730   else if (strSuffix.find("-M3") != std::string::npos)
0731     nModule = 3;
0732   else if (strSuffix.find("-M4") != std::string::npos)
0733     nModule = 4;
0734   else if (strSuffix.find("-M5") != std::string::npos)
0735     nModule = 5;
0736   else if (strSuffix.find("-M6") != std::string::npos)
0737     nModule = 6;
0738   else if (strSuffix.find("-M7") != std::string::npos)
0739     nModule = 7;
0740   else if (strSuffix.find("-M8") != std::string::npos)
0741     nModule = 8;
0742   else
0743     return "";
0744 
0745   return Form("GEM/Digis/occupancy_GE21-%c-L%i-M%i/occ_GE21-%c-%02iL%i-M%i-%c",
0746               cRegion,
0747               nLayer,
0748               nModule,
0749               cRegion,
0750               nIdxCh,
0751               nLayer,
0752               nModule,
0753               cChType);
0754 }
0755 
0756 std::string getNameChamberOccNull(std::string strSuffix, Int_t nIdxChamber) {
0757   return "";  // For an initialization
0758 }
0759 
0760 void GEMDQMHarvester::createInactiveChannelFracHist(edm::Service<DQMStore> &store,
0761                                                     std::string strSuffix,
0762                                                     Int_t nNumChamber) {
0763   std::string strTitle = "The fraction of inactive channels in " + strSuffix.substr(1);
0764   MonitorElement *h2InactiveChannel =
0765       store->book1D("inactive_frac_chamber" + strSuffix, strTitle, nNumChamber, 0.5, nNumChamber + 0.5);
0766   h2InactiveChannel->setXTitle("Chamber");
0767   h2InactiveChannel->setYTitle("Fraction of inactive channels");
0768   for (Int_t i = 1; i <= nNumChamber; i++) {
0769     h2InactiveChannel->setBinLabel(i, Form("%i", i), 1);
0770   }
0771 
0772   std::string (*funcNameCh)(std::string, Int_t) = getNameChamberOccNull;
0773 
0774   if (strSuffix.find("_GE11") != std::string::npos) {
0775     funcNameCh = getNameChamberOccGE11;
0776   } else if (strSuffix.find("_GE21") != std::string::npos) {
0777     funcNameCh = getNameChamberOccGE21;
0778   }
0779 
0780   for (Int_t nIdxCh = 1; nIdxCh <= nNumChamber; nIdxCh++) {
0781     std::string strNameCh = funcNameCh(strSuffix, nIdxCh);
0782     MonitorElement *h2SrcChamberOcc = store->get(strNameCh);
0783     if (h2SrcChamberOcc == nullptr) {
0784       // FIXME: It's about sending a message
0785       continue;
0786     }
0787 
0788     Int_t nNumBinX = h2SrcChamberOcc->getNbinsX();
0789     Int_t nNumBinY = h2SrcChamberOcc->getNbinsY();
0790     Int_t nNumAllChannel = nNumBinX * nNumBinY;
0791     auto *histData = h2SrcChamberOcc->getTH2F();
0792     auto *pdData = histData->GetArray();
0793     Int_t nNumChannelInactive = 0;
0794     for (Int_t j = 1; j <= nNumBinY; j++)
0795       for (Int_t i = 1; i <= nNumBinX; i++) {
0796         if (pdData[j * (nNumBinX + 2) + i] <= 0) {
0797           nNumChannelInactive++;
0798         }
0799       }
0800     h2InactiveChannel->setBinContent(nIdxCh, ((Double_t)nNumChannelInactive) / nNumAllChannel);
0801   }
0802 }
0803 
0804 DEFINE_FWK_MODULE(GEMDQMHarvester);