Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:08:50

0001 // -*- C++ -*-
0002 //
0003 // Package:    DQM/SiStripMonitorHardware
0004 // Class:      SiStripFEDMonitorPlugin
0005 //
0006 /**\class SiStripFEDMonitorPlugin SiStripFEDMonitor.cc DQM/SiStripMonitorHardware/plugins/SiStripFEDMonitor.cc
0007 
0008  Description: DQM source application to produce data integrety histograms for SiStrip data
0009 */
0010 //
0011 // Original Author:  Nicholas Cripps
0012 //         Created:  2008/09/16
0013 //
0014 //Modified        :  Anne-Marie Magnan
0015 //   ---- 2009/04/21 : histogram management put in separate class
0016 //                     struct helper to simplify arguments of functions
0017 //   ---- 2009/04/22 : add TkHistoMap with % of bad channels per module
0018 //   ---- 2009/04/27 : create FEDErrors class
0019 
0020 #include <sstream>
0021 #include <memory>
0022 #include <list>
0023 #include <algorithm>
0024 #include <cassert>
0025 
0026 #include "FWCore/Utilities/interface/EDGetToken.h"
0027 #include "FWCore/Framework/interface/Frameworkfwd.h"
0028 #include "FWCore/Framework/interface/Event.h"
0029 #include "FWCore/Framework/interface/EventSetup.h"
0030 #include "FWCore/Framework/interface/ESWatcher.h"
0031 #include "FWCore/Framework/interface/LuminosityBlock.h"
0032 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0033 #include "FWCore/Utilities/interface/InputTag.h"
0034 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0035 #include "FWCore/ServiceRegistry/interface/Service.h"
0036 #include "FWCore/Utilities/interface/Exception.h"
0037 
0038 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0039 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0040 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0041 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
0042 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0043 #include "Geometry/Records/interface/TrackerTopologyRcd.h"
0044 
0045 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
0046 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0047 
0048 #include "DQMServices/Core/interface/DQMStore.h"
0049 
0050 #include "DQM/SiStripMonitorHardware/interface/FEDHistograms.hh"
0051 #include "DQM/SiStripMonitorHardware/interface/FEDErrors.hh"
0052 
0053 #include "DPGAnalysis/SiStripTools/interface/EventWithHistory.h"
0054 
0055 #include <DQMServices/Core/interface/DQMOneEDAnalyzer.h>
0056 
0057 //
0058 // Class declaration
0059 //
0060 
0061 //class SiStripFEDMonitorPlugin : public DQMOneLumiEDAnalyzer<> {
0062 
0063 namespace sifedmon {
0064   struct LumiErrors {
0065     std::vector<unsigned int> nTotal;
0066     std::vector<unsigned int> nErrors;
0067   };
0068 }  // namespace sifedmon
0069 class SiStripFEDMonitorPlugin : public DQMOneEDAnalyzer<edm::LuminosityBlockCache<sifedmon::LumiErrors> > {
0070 public:
0071   explicit SiStripFEDMonitorPlugin(const edm::ParameterSet&);
0072   ~SiStripFEDMonitorPlugin() override;
0073 
0074 private:
0075   void analyze(const edm::Event&, const edm::EventSetup&) override;
0076 
0077   std::shared_ptr<sifedmon::LumiErrors> globalBeginLuminosityBlock(const edm::LuminosityBlock& lumi,
0078                                                                    const edm::EventSetup& iSetup) const override;
0079 
0080   void globalEndLuminosityBlock(const edm::LuminosityBlock& lumi, const edm::EventSetup& iSetup) override;
0081 
0082   void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
0083 
0084   //update the cabling if necessary
0085   void updateCabling(const SiStripFedCablingRcd& cablingRcd);
0086 
0087   static bool pairComparison(const std::pair<unsigned int, unsigned int>& pair1,
0088                              const std::pair<unsigned int, unsigned int>& pair2);
0089 
0090   void getMajority(const std::vector<std::pair<unsigned int, unsigned int> >& aFeMajVec,
0091                    unsigned int& aMajorityCounter,
0092                    std::vector<unsigned int>& afedIds);
0093 
0094   //tag of FEDRawData collection
0095   edm::InputTag rawDataTag_;
0096   edm::EDGetTokenT<FEDRawDataCollection> rawDataToken_;
0097   edm::EDGetTokenT<EventWithHistory> heToken_;
0098 
0099   //histogram helper class
0100   FEDHistograms fedHists_;
0101   //folder name for histograms in DQMStore
0102   std::string topFolderName_;
0103   std::string folderName_;
0104   //book detailed histograms even if they will be empty (for merging)
0105   bool fillAllDetailedHistograms_;
0106   //do histos vs time with time=event number. Default time = orbit number (s)
0107   bool fillWithEvtNum_;
0108   //print debug messages when problems are found: 1=error debug, 2=light debug, 3=full debug
0109   unsigned int printDebug_;
0110   //FED cabling
0111   const SiStripFedCabling* cabling_;
0112 
0113   edm::ESWatcher<SiStripFedCablingRcd> fedCablingWatcher_;
0114   edm::ESGetToken<SiStripFedCabling, SiStripFedCablingRcd> fedCablingToken_;
0115   edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> tTopoToken_;
0116   edm::ESGetToken<TkDetMap, TrackerTopologyRcd> tkDetMapToken_;
0117 
0118   //add parameter to save computing time if TkHistoMap/Median/FeMajCheck are not enabled
0119   bool doTkHistoMap_;
0120   bool doMedHists_;
0121   bool doFEMajorityCheck_;
0122 
0123   unsigned int nEvt_;
0124 
0125   //FED errors
0126   //need class member for lumi histograms
0127   FEDErrors fedErrors_;
0128   unsigned int maxFedBufferSize_;
0129   bool fullDebugMode_;
0130 
0131   bool enableFEDerrLumi_;
0132   MonitorElement* lumiErrfac_;
0133 };
0134 
0135 //
0136 // Constructors and destructor
0137 //
0138 
0139 SiStripFEDMonitorPlugin::SiStripFEDMonitorPlugin(const edm::ParameterSet& iConfig)
0140     : rawDataTag_(iConfig.getUntrackedParameter<edm::InputTag>("RawDataTag", edm::InputTag("source", ""))),
0141       topFolderName_(iConfig.getUntrackedParameter<std::string>("TopFolderName", "SiStrip")),
0142       fillAllDetailedHistograms_(iConfig.getUntrackedParameter<bool>("FillAllDetailedHistograms", false)),
0143       fillWithEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithEventNumber", false)),
0144       printDebug_(iConfig.getUntrackedParameter<unsigned int>("PrintDebugMessages", 1)),
0145       fedCablingWatcher_(this, &SiStripFEDMonitorPlugin::updateCabling),
0146       fedCablingToken_(esConsumes<>()),
0147       tTopoToken_(esConsumes<>()),
0148       tkDetMapToken_(esConsumes<edm::Transition::BeginRun>()),
0149       maxFedBufferSize_(0),
0150       fullDebugMode_(iConfig.getUntrackedParameter<bool>("FullDebugMode", false)) {
0151   std::string subFolderName = iConfig.getUntrackedParameter<std::string>("HistogramFolderName", "ReadoutView");
0152   folderName_ = topFolderName_ + "/" + subFolderName;
0153 
0154   rawDataToken_ = consumes<FEDRawDataCollection>(rawDataTag_);
0155   heToken_ = consumes<EventWithHistory>(edm::InputTag("consecutiveHEs"));
0156 
0157   if (iConfig.exists("ErrorFractionByLumiBlockHistogramConfig")) {
0158     const edm::ParameterSet& ps =
0159         iConfig.getUntrackedParameter<edm::ParameterSet>("ErrorFractionByLumiBlockHistogramConfig");
0160     enableFEDerrLumi_ = (ps.exists("Enabled") ? ps.getUntrackedParameter<bool>("Enabled") : true);
0161   }
0162   //print config to debug log
0163   std::ostringstream debugStream;
0164   if (printDebug_ > 1) {
0165     debugStream << "[SiStripFEDMonitorPlugin]Configuration for SiStripFEDMonitorPlugin: " << std::endl
0166                 << "[SiStripFEDMonitorPlugin]\tRawDataTag: " << rawDataTag_ << std::endl
0167                 << "[SiStripFEDMonitorPlugin]\tHistogramFolderName: " << folderName_ << std::endl
0168                 << "[SiStripFEDMonitorPlugin]\tFillAllDetailedHistograms? "
0169                 << (fillAllDetailedHistograms_ ? "yes" : "no") << std::endl
0170                 << "[SiStripFEDMonitorPlugin]\tFillWithEventNumber?" << (fillWithEvtNum_ ? "yes" : "no") << std::endl
0171                 << "[SiStripFEDMonitorPlugin]\tPrintDebugMessages? " << (printDebug_ ? "yes" : "no") << std::endl;
0172   }
0173 
0174   //don;t generate debug mesages if debug is disabled
0175   std::ostringstream* pDebugStream = (printDebug_ > 1 ? &debugStream : nullptr);
0176 
0177   fedHists_.initialise(iConfig, pDebugStream);
0178 
0179   doTkHistoMap_ = fedHists_.tkHistoMapEnabled();
0180 
0181   doMedHists_ = fedHists_.cmHistosEnabled();
0182 
0183   doFEMajorityCheck_ = fedHists_.feMajHistosEnabled();
0184 
0185   if (printDebug_) {
0186     LogTrace("SiStripMonitorHardware") << debugStream.str();
0187   }
0188 
0189   nEvt_ = 0;
0190 }
0191 
0192 SiStripFEDMonitorPlugin::~SiStripFEDMonitorPlugin() {}
0193 
0194 //
0195 // Member functions
0196 //
0197 
0198 // ------------ method called to for each event  ------------
0199 void SiStripFEDMonitorPlugin::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0200   const auto tTopo = &iSetup.getData(tTopoToken_);
0201   fedCablingWatcher_.check(iSetup);
0202 
0203   //get raw data
0204   edm::Handle<FEDRawDataCollection> rawDataCollectionHandle;
0205   iEvent.getByToken(rawDataToken_, rawDataCollectionHandle);
0206   const FEDRawDataCollection& rawDataCollection = *rawDataCollectionHandle;
0207 
0208   fedErrors_.initialiseEvent();
0209 
0210   //add the deltaBX value if the product exist
0211 
0212   edm::Handle<EventWithHistory> he;
0213   iEvent.getByToken(heToken_, he);
0214 
0215   //get the fedErrors object for each LS
0216   auto lumiErrors = luminosityBlockCache(iEvent.getLuminosityBlock().index());
0217   auto& nToterr = lumiErrors->nTotal;
0218   auto& nErr = lumiErrors->nErrors;
0219 
0220   if (he.isValid() && !he.failedToGet()) {
0221     fedErrors_.fillEventProperties(he->deltaBX());
0222   }
0223 
0224   //initialise map of fedId/bad channel number
0225   std::map<unsigned int, std::pair<unsigned short, unsigned short> > badChannelFraction;
0226 
0227   unsigned int lNFEDMonitoring = 0;
0228   unsigned int lNFEDUnpacker = 0;
0229   unsigned int lNChannelMonitoring = 0;
0230   unsigned int lNChannelUnpacker = 0;
0231 
0232   unsigned int lNTotBadFeds = 0;
0233   unsigned int lNTotBadChannels = 0;
0234   unsigned int lNTotBadActiveChannels = 0;
0235 
0236   std::vector<std::vector<std::pair<unsigned int, unsigned int> > > lFeMajFrac;
0237   const unsigned int nParts = 4;
0238   if (doFEMajorityCheck_) {
0239     lFeMajFrac.resize(nParts);
0240     //max nFE per partition
0241     lFeMajFrac[0].reserve(912);
0242     lFeMajFrac[1].reserve(1080);
0243     lFeMajFrac[2].reserve(768);
0244     lFeMajFrac[3].reserve(760);
0245   }
0246 
0247   maxFedBufferSize_ = 0;
0248 
0249   //loop over siStrip FED IDs
0250   for (unsigned int fedId = FEDNumbering::MINSiStripFEDID; fedId <= FEDNumbering::MAXSiStripFEDID;
0251        fedId++) {  //loop over FED IDs
0252     unsigned int lNBadChannels_perFEDID = 0;
0253     const FEDRawData& fedData = rawDataCollection.FEDData(fedId);
0254 
0255     //create an object to fill all errors
0256     fedErrors_.initialiseFED(fedId, cabling_, tTopo);
0257 
0258     double aLumiSection = iEvent.orbitNumber() / 262144.0;
0259 
0260     //Do detailed check
0261     //first check if data exists
0262     bool lDataExist = fedErrors_.checkDataPresent(fedData);
0263     if (!lDataExist) {
0264       fedHists_.fillFEDHistograms(fedErrors_, 0, fullDebugMode_, aLumiSection, lNBadChannels_perFEDID);
0265       continue;
0266     }
0267 
0268     //check for problems and fill detailed histograms
0269     fedErrors_.fillFEDErrors(fedData,
0270                              fullDebugMode_,
0271                              printDebug_,
0272                              lNChannelMonitoring,
0273                              lNChannelUnpacker,
0274                              doMedHists_,
0275                              fedHists_.cmHistPointer(false),
0276                              fedHists_.cmHistPointer(true),
0277                              doFEMajorityCheck_,
0278                              lFeMajFrac);
0279 
0280     //check filled in previous method.
0281     bool lFailUnpackerFEDcheck = fedErrors_.failUnpackerFEDCheck();
0282 
0283     fedErrors_.incrementFEDCounters();
0284     unsigned int lSize = fedData.size();
0285     if (lSize > maxFedBufferSize_) {
0286       maxFedBufferSize_ = lSize;
0287     }
0288     //std::cout << " -- " << fedId << " " << lSize << std::endl;
0289 
0290     //fedHists_.fillFEDHistograms(fedErrors_,lSize,fullDebugMode_);
0291 
0292     bool lFailMonitoringFEDcheck = fedErrors_.failMonitoringFEDCheck();
0293     if (lFailMonitoringFEDcheck)
0294       lNTotBadFeds++;
0295 
0296     //sanity check: if something changed in the unpacking code
0297     //but wasn't propagated here
0298     //print only the summary, and more info if printDebug>1
0299     if (lFailMonitoringFEDcheck != lFailUnpackerFEDcheck) {
0300       if (printDebug_ > 1) {
0301         std::ostringstream debugStream;
0302         debugStream << " --- WARNING: FED " << fedId << std::endl << " ------ Monitoring FED check ";
0303         if (lFailMonitoringFEDcheck)
0304           debugStream << "failed." << std::endl;
0305         else
0306           debugStream << "passed." << std::endl;
0307         debugStream << " ------ Unpacker FED check ";
0308         if (lFailUnpackerFEDcheck)
0309           debugStream << "failed." << std::endl;
0310         else
0311           debugStream << "passed." << std::endl;
0312         edm::LogError("SiStripMonitorHardware") << debugStream.str();
0313       }
0314 
0315       if (lFailMonitoringFEDcheck)
0316         lNFEDMonitoring++;
0317       else if (lFailUnpackerFEDcheck)
0318         lNFEDUnpacker++;
0319     }
0320 
0321     //Fill TkHistoMap:
0322     //add an entry for all channels (good = 0),
0323     //so that tkHistoMap knows which channels should be there.
0324     if (doTkHistoMap_ && !fedHists_.tkHistoMapPointer()) {
0325       edm::LogWarning("SiStripMonitorHardware")
0326           << " -- Fedid " << fedId << ", TkHistoMap enabled but pointer is null." << std::endl;
0327     }
0328 
0329     fedErrors_.fillBadChannelList(doTkHistoMap_,
0330                                   fedHists_.tkHistoMapPointer(),
0331                                   fedHists_.getFedvsAPVpointer(),
0332                                   lNTotBadChannels,
0333                                   lNTotBadActiveChannels,
0334                                   lNBadChannels_perFEDID,
0335                                   nToterr,
0336                                   nErr);
0337     fedHists_.fillFEDHistograms(fedErrors_, lSize, fullDebugMode_, aLumiSection, lNBadChannels_perFEDID);
0338   }  //loop over FED IDs
0339 
0340   if (doFEMajorityCheck_) {
0341     for (unsigned int iP(0); iP < nParts; ++iP) {
0342       //std::cout << " -- Partition " << iP << std::endl;
0343       //std::cout << " --- Number of elements in vec = " << lFeMajFrac[iP].size() << std::endl;
0344       if (lFeMajFrac[iP].empty())
0345         continue;
0346       std::sort(lFeMajFrac[iP].begin(), lFeMajFrac[iP].end(), SiStripFEDMonitorPlugin::pairComparison);
0347 
0348       unsigned int lMajorityCounter = 0;
0349       std::vector<unsigned int> lfedIds;
0350 
0351       getMajority(lFeMajFrac[iP], lMajorityCounter, lfedIds);
0352       //std::cout << " -- Found " << lfedIds.size() << " unique elements not matching the majority." << std::endl;
0353       fedHists_.fillMajorityHistograms(iP, static_cast<float>(lMajorityCounter) / lFeMajFrac[iP].size(), lfedIds);
0354     }
0355   }
0356 
0357   if ((lNTotBadFeds > 0 || lNTotBadChannels > 0) && printDebug_ > 1) {
0358     std::ostringstream debugStream;
0359     debugStream << "[SiStripFEDMonitorPlugin] --- Total number of bad feds = " << lNTotBadFeds << std::endl
0360                 << "[SiStripFEDMonitorPlugin] --- Total number of bad channels = " << lNTotBadChannels << std::endl
0361                 << "[SiStripFEDMonitorPlugin] --- Total number of bad active channels = " << lNTotBadActiveChannels
0362                 << std::endl;
0363     edm::LogInfo("SiStripMonitorHardware") << debugStream.str();
0364   }
0365 
0366   if ((lNFEDMonitoring > 0 || lNFEDUnpacker > 0 || lNChannelMonitoring > 0 || lNChannelUnpacker > 0) && printDebug_) {
0367     std::ostringstream debugStream;
0368     debugStream
0369         << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------"
0370         << std::endl
0371         << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------"
0372         << std::endl
0373         << "[SiStripFEDMonitorPlugin]-- Summary of differences between unpacker and monitoring at FED level : "
0374         << std::endl
0375         << "[SiStripFEDMonitorPlugin] ---- Number of times monitoring fails but not unpacking = " << lNFEDMonitoring
0376         << std::endl
0377         << "[SiStripFEDMonitorPlugin] ---- Number of times unpacking fails but not monitoring = " << lNFEDUnpacker
0378         << std::endl
0379         << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------"
0380         << std::endl
0381         << "[SiStripFEDMonitorPlugin]-- Summary of differences between unpacker and monitoring at Channel level : "
0382         << std::endl
0383         << "[SiStripFEDMonitorPlugin] ---- Number of times monitoring fails but not unpacking = " << lNChannelMonitoring
0384         << std::endl
0385         << "[SiStripFEDMonitorPlugin] ---- Number of times unpacking fails but not monitoring = " << lNChannelUnpacker
0386         << std::endl
0387         << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------"
0388         << std::endl
0389         << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------"
0390         << std::endl;
0391     edm::LogError("SiStripMonitorHardware") << debugStream.str();
0392   }
0393 
0394   fedErrors_.getFEDErrorsCounters().nTotalBadChannels = lNTotBadChannels;
0395   fedErrors_.getFEDErrorsCounters().nTotalBadActiveChannels = lNTotBadActiveChannels;
0396 
0397   //time in seconds since beginning of the run or event number
0398   if (fillWithEvtNum_) {
0399     // explicitely casting the event number unsigned long long to double here
0400     double eventNumber = static_cast<double>(iEvent.id().event());
0401     fedHists_.fillCountersHistograms(
0402         fedErrors_.getFEDErrorsCounters(), fedErrors_.getChannelErrorsCounters(), maxFedBufferSize_, eventNumber);
0403   } else {
0404     double aTime = iEvent.orbitNumber() / 11223.;
0405     fedHists_.fillCountersHistograms(
0406         fedErrors_.getFEDErrorsCounters(), fedErrors_.getChannelErrorsCounters(), maxFedBufferSize_, aTime);
0407   }
0408 
0409   nEvt_++;
0410 
0411 }  //analyze method
0412 
0413 bool SiStripFEDMonitorPlugin::pairComparison(const std::pair<unsigned int, unsigned int>& pair1,
0414                                              const std::pair<unsigned int, unsigned int>& pair2) {
0415   return (pair1.second < pair2.second);
0416 }
0417 
0418 void SiStripFEDMonitorPlugin::getMajority(const std::vector<std::pair<unsigned int, unsigned int> >& aFeMajVec,
0419                                           unsigned int& aMajorityCounter,
0420                                           std::vector<unsigned int>& afedIds) {
0421   unsigned int lMajAddress = 0;
0422   std::vector<std::pair<unsigned int, unsigned int> >::const_iterator lIter = aFeMajVec.begin();
0423   unsigned int lMajAddr = (*lIter).second;
0424   unsigned int lCounter = 0;
0425 
0426   //std::cout << " --- First element: addr = " << lMajAddr << " counter = " << lCounter << std::endl;
0427   unsigned int iele = 0;
0428   //bool foundMaj = false;
0429   for (; lIter != aFeMajVec.end(); ++lIter, ++iele) {
0430     //std::cout << " ---- Ele " << iele << " " << (*lIter).first << " " << (*lIter).second << " ref " << lMajAddr << std::endl;
0431     if ((*lIter).second == lMajAddr) {
0432       ++lCounter;
0433       //std::cout << " ----- =ref: Counter = " << lCounter << std::endl;
0434     } else {
0435       //std::cout << " ----- !=ref: Counter = " << lCounter << " Majority = " << aMajorityCounter << std::endl;
0436       if (lCounter > aMajorityCounter) {
0437         //std::cout << " ------ >Majority: " << std::endl;
0438         aMajorityCounter = lCounter;
0439         // AV bug here??
0440         lMajAddress = lMajAddr;
0441         //  lMajAddress = (*lIter).second;
0442         //foundMaj=true;
0443       }
0444       lCounter = 0;
0445       lMajAddr = (*lIter).second;
0446       --lIter;
0447       --iele;
0448     }
0449   }
0450   // AV Bug here? The check has to be done regardless foundMaj == false or true
0451   //  if (!foundMaj) {
0452   if (lCounter > aMajorityCounter) {
0453     //std::cout << " ------ >Majority: " << std::endl;
0454     aMajorityCounter = lCounter;
0455     lMajAddress = lMajAddr;
0456   }
0457   //  }
0458   //std::cout << " -- found majority value for " << aMajorityCounter << " elements out of " << aFeMajVec.size() << "." << std::endl;
0459   //get list of feds with address different from majority in partition:
0460   lIter = aFeMajVec.begin();
0461   afedIds.reserve(135);
0462   for (; lIter != aFeMajVec.end(); ++lIter) {
0463     if ((*lIter).second != lMajAddress) {
0464       afedIds.push_back((*lIter).first);
0465     } else {
0466       lIter += aMajorityCounter - 1;
0467       if (lIter >= aFeMajVec.end()) {
0468         std::cout << "Here it is a bug: " << aMajorityCounter << " " << aFeMajVec.size() << " "
0469                   << lIter - aFeMajVec.end() << std::endl;
0470       }
0471     }
0472   }
0473   //std::cout << " -- Found " << lfedIds.size() << " elements not matching the majority." << std::endl;
0474   if (!afedIds.empty()) {
0475     std::sort(afedIds.begin(), afedIds.end());
0476     std::vector<unsigned int>::iterator lIt = std::unique(afedIds.begin(), afedIds.end());
0477     afedIds.erase(lIt, afedIds.end());
0478   }
0479 }
0480 
0481 void SiStripFEDMonitorPlugin::bookHistograms(DQMStore::IBooker& ibooker,
0482                                              const edm::Run& run,
0483                                              const edm::EventSetup& eSetup) {
0484   ibooker.setCurrentFolder(folderName_);
0485 
0486   const auto tkDetMap = &eSetup.getData(tkDetMapToken_);
0487   fedHists_.bookTopLevelHistograms(ibooker, tkDetMap);
0488 
0489   if (fillAllDetailedHistograms_)
0490     fedHists_.bookAllFEDHistograms(ibooker, fullDebugMode_);
0491 
0492   if (enableFEDerrLumi_) {
0493     ibooker.cd();
0494     ibooker.setCurrentFolder("SiStrip/ReadoutView/PerLumiSection");
0495     {
0496       auto scope = DQMStore::IBooker::UseRunScope(ibooker);
0497       lumiErrfac_ =
0498           ibooker.book1D("lumiErrorFraction", "Fraction of error per lumi section vs subdetector", 6, 0.5, 6.5);
0499       lumiErrfac_->setAxisTitle("SubDetId", 1);
0500       lumiErrfac_->setBinLabel(1, "TECB");
0501       lumiErrfac_->setBinLabel(2, "TECF");
0502       lumiErrfac_->setBinLabel(3, "TIB");
0503       lumiErrfac_->setBinLabel(4, "TIDB");
0504       lumiErrfac_->setBinLabel(5, "TIDF");
0505       lumiErrfac_->setBinLabel(6, "TOB");
0506     }
0507   } else {
0508     lumiErrfac_ = nullptr;
0509   }
0510 }
0511 
0512 std::shared_ptr<sifedmon::LumiErrors> SiStripFEDMonitorPlugin::globalBeginLuminosityBlock(
0513     const edm::LuminosityBlock& lumi, const edm::EventSetup& iSetup) const {
0514   auto lumiErrors = std::make_shared<sifedmon::LumiErrors>();
0515   lumiErrors->nTotal.resize(6, 0);
0516   lumiErrors->nErrors.resize(6, 0);
0517   return lumiErrors;
0518 }
0519 
0520 void SiStripFEDMonitorPlugin::globalEndLuminosityBlock(const edm::LuminosityBlock& lumi,
0521                                                        const edm::EventSetup& iSetup) {
0522   auto lumiErrors = luminosityBlockCache(lumi.index());
0523   if (enableFEDerrLumi_ && lumiErrfac_) {
0524     for (unsigned int iD(0); iD < lumiErrors->nTotal.size(); iD++) {
0525       if (lumiErrors->nTotal[iD] > 0)
0526         lumiErrfac_->Fill(iD + 1, static_cast<float>(lumiErrors->nErrors[iD]) / lumiErrors->nTotal[iD]);
0527     }
0528   }
0529 }
0530 
0531 void SiStripFEDMonitorPlugin::updateCabling(const SiStripFedCablingRcd& cablingRcd) {
0532   cabling_ = &cablingRcd.get(fedCablingToken_);
0533 }
0534 
0535 //
0536 // Define as a plug-in
0537 //
0538 
0539 #include "FWCore/Framework/interface/MakerMacros.h"
0540 DEFINE_FWK_MODULE(SiStripFEDMonitorPlugin);