Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-03 00:11:55

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