Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-11-12 00:00:46

0001 
0002 /*
0003  *  See header file for a description of this class.
0004  *
0005  *  author
0006  */
0007 
0008 // CMSSW FW
0009 #include "FWCore/Framework/interface/Event.h"
0010 #include "FWCore/Framework/interface/Run.h"
0011 #include "FWCore/Framework/interface/LuminosityBlock.h"
0012 #include "FWCore/Framework/interface/FileBlock.h"
0013 #include "FWCore/Framework/interface/EventSetup.h"
0014 #include "DataFormats/Common/interface/Handle.h"
0015 #include "FWCore/Framework/interface/MakerMacros.h"
0016 #include "FWCore/Framework/interface/ConsumesCollector.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 #include "FWCore/ServiceRegistry/interface/Service.h"
0020 #include "FWCore/Utilities/interface/Transition.h"
0021 // Pixel geometry and cabling map
0022 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0023 #include "CondFormats/DataRecord/interface/SiPixelFedCablingMapRcd.h"
0024 // Condition Format
0025 #include "CondFormats/DataRecord/interface/SiPixelQualityRcd.h"
0026 // LHCinfo
0027 //#include "CondFormats/RunInfo/interface/LHCInfo.h"
0028 //#include "CondFormats/DataRecord/interface/LHCInfoRcd.h"
0029 
0030 // CondOutput
0031 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
0032 // Dataformat of SiPixel status in ALCAPROMPT data
0033 #include "CalibTracker/SiPixelQuality/interface/SiPixelDetectorStatus.h"
0034 //#include "CondCore/Utilities/bin/cmscond_export_iov.cpp"
0035 //#include "CondCore/Utilities/interface/Utilities.h"
0036 // harvest helper class
0037 #include "CalibTracker/SiPixelQuality/interface/SiPixelStatusManager.h"
0038 // header file
0039 #include "CalibTracker/SiPixelQuality/plugins/SiPixelStatusHarvester.h"
0040 
0041 // output format
0042 #include "TH1.h"
0043 #include "TTree.h"
0044 #include "TString.h"
0045 
0046 #include <iostream>
0047 #include <cstring>
0048 
0049 using namespace edm;
0050 //class MonitorElement;
0051 
0052 //--------------------------------------------------------------------------------------------------
0053 SiPixelStatusHarvester::SiPixelStatusHarvester(const edm::ParameterSet& iConfig)
0054     : HistogramManagerHolder(iConfig, consumesCollector()),
0055       thresholdL1_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0056                        .getUntrackedParameter<double>("thresholdL1")),
0057       thresholdL2_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0058                        .getUntrackedParameter<double>("thresholdL2")),
0059       thresholdL3_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0060                        .getUntrackedParameter<double>("thresholdL3")),
0061       thresholdL4_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0062                        .getUntrackedParameter<double>("thresholdL4")),
0063       thresholdRNG1_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0064                          .getUntrackedParameter<double>("thresholdRNG1")),
0065       thresholdRNG2_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0066                          .getUntrackedParameter<double>("thresholdRNG2")),
0067       outputBase_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0068                       .getUntrackedParameter<std::string>("outputBase")),
0069       aveDigiOcc_(
0070           iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters").getUntrackedParameter<int>("aveDigiOcc")),
0071       nLumi_(iConfig.getParameter<edm::ParameterSet>("SiPixelStatusManagerParameters")
0072                  .getUntrackedParameter<int>("resetEveryNLumi")),
0073       moduleName_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0074                       .getUntrackedParameter<std::string>("moduleName")),
0075       label_(iConfig.getParameter<ParameterSet>("SiPixelStatusManagerParameters")
0076                  .getUntrackedParameter<std::string>("label")),
0077       trackerGeometryToken_(esConsumes<TrackerGeometry, TrackerDigiGeometryRecord, edm::Transition::EndRun>()),
0078       trackerTopologyToken_(esConsumes<TrackerTopology, TrackerTopologyRcd, edm::Transition::EndRun>()),
0079       siPixelFedCablingMapToken_(esConsumes<SiPixelFedCablingMap, SiPixelFedCablingMapRcd, edm::Transition::EndRun>()),
0080       siPixelQualityToken_(esConsumes<SiPixelQuality, SiPixelQualityFromDbRcd, edm::Transition::EndRun>()) {
0081   SiPixelStatusManager* siPixelStatusManager = new SiPixelStatusManager(iConfig, consumesCollector());
0082   siPixelStatusManager_ = *siPixelStatusManager;
0083   debug_ = iConfig.getUntrackedParameter<bool>("debug");
0084   recordName_ = iConfig.getUntrackedParameter<std::string>("recordName", "SiPixelQualityFromDbRcd");
0085 
0086   sensorSize_.clear();
0087   pixelO2O_.clear();
0088 
0089   siPixelStatusManager_.reset();
0090   endLumiBlock_ = 0;
0091   countLumi_ = 0;
0092 }
0093 
0094 //--------------------------------------------------------------------------------------------------
0095 SiPixelStatusHarvester::~SiPixelStatusHarvester() {}
0096 
0097 //--------------------------------------------------------------------------------------------------
0098 void SiPixelStatusHarvester::beginJob() {}
0099 
0100 //--------------------------------------------------------------------------------------------------
0101 void SiPixelStatusHarvester::bookHistograms(DQMStore::IBooker& iBooker,
0102                                             edm::Run const&,
0103                                             edm::EventSetup const& iSetup) {
0104   for (auto& histoman : histo) {
0105     histoman.book(iBooker, iSetup);
0106   }
0107 }
0108 
0109 //--------------------------------------------------------------------------------------------------
0110 void SiPixelStatusHarvester::analyze(const edm::Event& iEvent, const edm::EventSetup&) {}
0111 
0112 //--------------------------------------------------------------------------------------------------
0113 void SiPixelStatusHarvester::dqmEndRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
0114   // tracker geometry and cabling map to convert offline row/column (module) to online row/column
0115   trackerGeometry_ = &iSetup.getData(trackerGeometryToken_);
0116   const TrackerTopology* trackerTopology = &iSetup.getData(trackerTopologyToken_);
0117   const SiPixelFedCablingMap* siPixelFedCablingMap = &iSetup.getData(siPixelFedCablingMapToken_);
0118   cablingMap_ = siPixelFedCablingMap;
0119 
0120   // Pixel Phase-1 helper class
0121   coord_.init(trackerTopology, trackerGeometry_, siPixelFedCablingMap);
0122 
0123   for (TrackerGeometry::DetContainer::const_iterator it = trackerGeometry_->dets().begin();
0124        it != trackerGeometry_->dets().end();
0125        it++) {
0126     const PixelGeomDetUnit* pgdu = dynamic_cast<const PixelGeomDetUnit*>((*it));
0127     if (pgdu == nullptr)
0128       continue;
0129     DetId detId = (*it)->geographicalId();
0130     int detid = detId.rawId();
0131 
0132     const PixelTopology* topo = static_cast<const PixelTopology*>(&pgdu->specificTopology());
0133     // number of row/columns for a given module
0134     int rowsperroc = topo->rowsperroc();
0135     int colsperroc = topo->colsperroc();
0136 
0137     int nROCrows = pgdu->specificTopology().nrows() / rowsperroc;
0138     int nROCcolumns = pgdu->specificTopology().ncolumns() / colsperroc;
0139     unsigned int nrocs = nROCrows * nROCcolumns;
0140     sensorSize_[detid] = nrocs;
0141 
0142     std::map<int, std::pair<int, int>> rocToOfflinePixel;
0143 
0144     std::vector<sipixelobjects::CablingPathToDetUnit> path = (cablingMap_->det2PathMap()).find(detId.rawId())->second;
0145     typedef std::vector<sipixelobjects::CablingPathToDetUnit>::const_iterator IT;
0146     for (IT it = path.begin(); it != path.end(); ++it) {
0147       // Pixel ROC building from path in cabling map
0148       const sipixelobjects::PixelROC* roc = cablingMap_->findItem(*it);
0149       int idInDetUnit = (int)roc->idInDetUnit();
0150 
0151       // local to global conversion
0152       sipixelobjects::LocalPixel::RocRowCol local = {rowsperroc / 2, colsperroc / 2};
0153       sipixelobjects::GlobalPixel global = roc->toGlobal(sipixelobjects::LocalPixel(local));
0154 
0155       rocToOfflinePixel[idInDetUnit] = std::pair<int, int>(global.row, global.col);
0156     }
0157 
0158     pixelO2O_[detid] = rocToOfflinePixel;
0159   }
0160 
0161   // Permananent bad components
0162   badPixelInfo_ = &iSetup.getData(siPixelQualityToken_);
0163 
0164   // read in SiPixel occupancy data in ALCARECO/ALCAPROMPT
0165   siPixelStatusManager_.createPayloads();
0166   std::map<edm::LuminosityBlockNumber_t, std::map<int, std::vector<int>>> FEDerror25Map =
0167       siPixelStatusManager_.getFEDerror25Rocs();
0168   std::map<edm::LuminosityBlockNumber_t, SiPixelDetectorStatus> siPixelStatusMap =
0169       siPixelStatusManager_.getBadComponents();
0170 
0171   // DB service
0172   edm::Service<cond::service::PoolDBOutputService> poolDbService;
0173 
0174   if (poolDbService.isAvailable()) {  // if(poolDbService.isAvailable() )
0175 
0176     // start producing tag for permanent component removed
0177     SiPixelQuality siPixelQualityPermBad;
0178     const std::vector<SiPixelQuality::disabledModuleType> badComponentList = badPixelInfo_->getBadComponentList();
0179     for (unsigned int i = 0; i < badComponentList.size(); i++) {
0180       siPixelQualityPermBad.addDisabledModule(badComponentList[i]);
0181 
0182       uint32_t detId = badComponentList[i].DetID;
0183       int detid = int(detId);
0184       unsigned int nroc = sensorSize_[detid];
0185 
0186       for (int iroc = 0; iroc < int(nroc); iroc++) {
0187         if (badPixelInfo_->IsRocBad(detId, short(iroc))) {
0188           std::map<int, std::pair<int, int>> rocToOfflinePixel = pixelO2O_[detid];
0189           int row = rocToOfflinePixel[iroc].first;
0190           int column = rocToOfflinePixel[iroc].second;
0191           histo[PERMANENTBADROC].fill(detId, nullptr, column, row);
0192         }
0193       }
0194     }
0195     if (debug_ == true) {  // only produced for debugging reason
0196       cond::Time_t thisIOV = (cond::Time_t)iRun.id().run();
0197       poolDbService->writeOneIOV<SiPixelQuality>(siPixelQualityPermBad, thisIOV, recordName_ + "_permanentBad");
0198     }
0199 
0200     // IOV for final payloads. FEDerror25 and pcl
0201     std::map<edm::LuminosityBlockNumber_t, edm::LuminosityBlockNumber_t> finalIOV;
0202     std::map<edm::LuminosityBlockNumber_t, edm::LuminosityBlockNumber_t> fedError25IOV;
0203     std::map<edm::LuminosityBlockNumber_t, edm::LuminosityBlockNumber_t> pclIOV;
0204 
0205     // container for SiPixelQuality for the whole run
0206     std::map<int, SiPixelQuality> siPixelQualityStuckTBM_Tag;
0207 
0208     // stuckTBM tag from FED error 25 with permanent component removed
0209     for (SiPixelStatusManager::FEDerror25Map_iterator it = FEDerror25Map.begin(); it != FEDerror25Map.end(); it++) {
0210       cond::Time_t thisIOV = 1;
0211       edm::LuminosityBlockID lu(iRun.id().run(), it->first);
0212       thisIOV = (cond::Time_t)(lu.value());
0213 
0214       int interval = 0;
0215       // interval is the number of lumi sections in the IOV
0216       SiPixelStatusManager::FEDerror25Map_iterator nextIt = std::next(it);
0217       if (nextIt != FEDerror25Map.end())
0218         interval = int(nextIt->first - it->first);
0219       else
0220         interval = int(endLumiBlock_ - it->first + 1);  // +1 because need to include the last lumi section
0221 
0222       SiPixelQuality siPixelQuality_stuckTBM;
0223       SiPixelQuality siPixelQuality_FEDerror25;
0224 
0225       std::map<int, std::vector<int>> tmpFEDerror25 = it->second;
0226       for (std::map<int, std::vector<int>>::iterator ilist = tmpFEDerror25.begin(); ilist != tmpFEDerror25.end();
0227            ilist++) {
0228         int detid = ilist->first;
0229         uint32_t detId = uint32_t(detid);
0230 
0231         SiPixelQuality::disabledModuleType BadModule_stuckTBM, BadModule_FEDerror25;
0232 
0233         BadModule_stuckTBM.DetID = uint32_t(detid);
0234         BadModule_FEDerror25.DetID = uint32_t(detid);
0235         BadModule_stuckTBM.errorType = 3;
0236         BadModule_FEDerror25.errorType = 3;
0237 
0238         BadModule_stuckTBM.BadRocs = 0;
0239         BadModule_FEDerror25.BadRocs = 0;
0240         std::vector<uint32_t> BadRocList_stuckTBM, BadRocList_FEDerror25;
0241         std::vector<int> list = ilist->second;
0242 
0243         for (unsigned int i = 0; i < list.size(); i++) {
0244           int iroc = list[i];
0245           std::map<int, std::pair<int, int>> rocToOfflinePixel = pixelO2O_[detid];
0246           int row = rocToOfflinePixel[iroc].first;
0247           int column = rocToOfflinePixel[iroc].second;
0248 
0249           BadRocList_FEDerror25.push_back(uint32_t(iroc));
0250           for (int iLumi = 0; iLumi < interval; iLumi++) {
0251             histo[FEDERRORROC].fill(detId, nullptr, column, row);  // 1.0/nLumiBlock_);
0252           }
0253 
0254           // only include rocs that are not permanent known bad
0255           if (!badPixelInfo_->IsRocBad(detId, short(iroc))) {  // stuckTBM = FEDerror25 - permanent bad
0256             BadRocList_stuckTBM.push_back(uint32_t(iroc));
0257             for (int iLumi = 0; iLumi < interval; iLumi++) {
0258               histo[STUCKTBMROC].fill(detId, nullptr, column, row);  //, 1.0/nLumiBlock_);
0259             }
0260           }
0261         }
0262 
0263         // change module error type if all ROCs are bad
0264         if (BadRocList_stuckTBM.size() == sensorSize_[detid])
0265           BadModule_stuckTBM.errorType = 0;
0266 
0267         short badrocs_stuckTBM = 0;
0268         for (std::vector<uint32_t>::iterator iter = BadRocList_stuckTBM.begin(); iter != BadRocList_stuckTBM.end();
0269              ++iter) {
0270           badrocs_stuckTBM += 1 << *iter;  // 1 << *iter = 2^{*iter} using bitwise shift
0271         }
0272         // fill the badmodule only if there is(are) bad ROC(s) in it
0273         if (badrocs_stuckTBM != 0) {
0274           BadModule_stuckTBM.BadRocs = badrocs_stuckTBM;
0275           siPixelQuality_stuckTBM.addDisabledModule(BadModule_stuckTBM);
0276         }
0277 
0278         // change module error type if all ROCs are bad
0279         if (BadRocList_FEDerror25.size() == sensorSize_[detid])
0280           BadModule_FEDerror25.errorType = 0;
0281 
0282         short badrocs_FEDerror25 = 0;
0283         for (std::vector<uint32_t>::iterator iter = BadRocList_FEDerror25.begin(); iter != BadRocList_FEDerror25.end();
0284              ++iter) {
0285           badrocs_FEDerror25 += 1 << *iter;  // 1 << *iter = 2^{*iter} using bitwise shift
0286         }
0287         // fill the badmodule only if there is(are) bad ROC(s) in it
0288         if (badrocs_FEDerror25 != 0) {
0289           BadModule_FEDerror25.BadRocs = badrocs_FEDerror25;
0290           siPixelQuality_FEDerror25.addDisabledModule(BadModule_FEDerror25);
0291         }
0292 
0293       }  // loop over modules
0294 
0295       siPixelQualityStuckTBM_Tag[it->first] = siPixelQuality_stuckTBM;
0296 
0297       finalIOV[it->first] = it->first;
0298       fedError25IOV[it->first] = it->first;
0299 
0300       if (debug_ == true)  // only produced for debugging reason
0301         poolDbService->writeOneIOV<SiPixelQuality>(siPixelQuality_FEDerror25, thisIOV, recordName_ + "_FEDerror25");
0302     }
0303 
0304     // IOV for PCL output tags that "combines" permanent bad/stuckTBM/other
0305     for (SiPixelStatusManager::siPixelStatusMap_iterator it = siPixelStatusMap.begin(); it != siPixelStatusMap.end();
0306          it++) {
0307       finalIOV[it->first] = it->first;
0308       pclIOV[it->first] = it->first;
0309     }
0310 
0311     // loop over final IOV
0312     std::map<edm::LuminosityBlockNumber_t, edm::LuminosityBlockNumber_t>::iterator itIOV;
0313 
0314     // container for SiPixelQuality for the whole run
0315     std::map<int, SiPixelQuality> siPixelQualityPCL_Tag;
0316     std::map<int, SiPixelQuality> siPixelQualityPrompt_Tag;
0317     std::map<int, SiPixelQuality> siPixelQualityOther_Tag;
0318 
0319     for (itIOV = finalIOV.begin(); itIOV != finalIOV.end(); itIOV++) {
0320       int interval = 0;
0321       std::map<edm::LuminosityBlockNumber_t, edm::LuminosityBlockNumber_t>::iterator nextItIOV = std::next(itIOV);
0322       if (nextItIOV != finalIOV.end())
0323         interval = int(nextItIOV->first - itIOV->first);
0324       else
0325         interval = int(endLumiBlock_ - itIOV->first + 1);
0326 
0327       edm::LuminosityBlockNumber_t lumiFEDerror25 = SiPixelStatusHarvester::stepIOV(itIOV->first, fedError25IOV);
0328       edm::LuminosityBlockNumber_t lumiPCL = SiPixelStatusHarvester::stepIOV(itIOV->first, pclIOV);
0329 
0330       // get badROC list due to FEDerror25 = stuckTBM + permanent bad components
0331       std::map<int, std::vector<int>> tmpFEDerror25 = FEDerror25Map[lumiFEDerror25];
0332       // get SiPixelDetectorStatus
0333       SiPixelDetectorStatus tmpSiPixelStatus = siPixelStatusMap[lumiPCL];
0334       double DetAverage = tmpSiPixelStatus.perRocDigiOcc();
0335 
0336       // For the IOV of which the statistics is too low, for e.g., a cosmic run
0337       // When using dynamicLumibased harvester or runbased harvester
0338       // this only happens when the full run is lack of statistics
0339       if (DetAverage < aveDigiOcc_) {
0340         edm::LogInfo("SiPixelStatusHarvester")
0341             << "Tag requested for prompt in low statistics IOV in the " << outputBase_ << " harvester" << std::endl;
0342         siPixelQualityPCL_Tag[itIOV->first] = siPixelQualityPermBad;
0343         siPixelQualityPrompt_Tag[itIOV->first] = siPixelQualityPermBad;
0344 
0345         // loop over modules to fill the PROMPT DQM plots with permanent bad components
0346         std::map<int, SiPixelModuleStatus> detectorStatus = tmpSiPixelStatus.getDetectorStatus();
0347         std::map<int, SiPixelModuleStatus>::iterator itModEnd = detectorStatus.end();
0348         for (std::map<int, SiPixelModuleStatus>::iterator itMod = detectorStatus.begin(); itMod != itModEnd; ++itMod) {
0349           int detid = itMod->first;
0350           uint32_t detId = uint32_t(detid);
0351           SiPixelModuleStatus modStatus = itMod->second;
0352 
0353           for (int iroc = 0; iroc < modStatus.nrocs(); ++iroc) {
0354             if (badPixelInfo_->IsRocBad(detId, short(iroc))) {
0355               std::map<int, std::pair<int, int>> rocToOfflinePixel = pixelO2O_[detid];
0356               int row = rocToOfflinePixel[iroc].first;
0357               int column = rocToOfflinePixel[iroc].second;
0358               for (int iLumi = 0; iLumi < interval; iLumi++) {
0359                 histo[PROMPTBADROC].fill(detId, nullptr, column, row);     //, 1.0/nLumiBlock_);
0360                 histo[PERMANENTBADROC].fill(detId, nullptr, column, row);  //, 1.0/nLumiBlock_);
0361               }
0362 
0363             }  // if permanent BAD
0364 
0365           }  // loop over ROCs
0366 
0367         }  // loop over modules
0368 
0369         // add empty bad components to "other" tag
0370         edm::LogInfo("SiPixelStatusHarvester")
0371             << "Tag requested for other in low statistics IOV in the " << outputBase_ << " harvester" << std::endl;
0372         siPixelQualityOther_Tag[itIOV->first] = SiPixelQuality();
0373 
0374         continue;
0375       }
0376 
0377       // create the DB object
0378       // payload including all : PCL = permanent bad (low DIGI ROC) + other + stuckTBM
0379       SiPixelQuality siPixelQualityPCL;
0380       SiPixelQuality siPixelQualityOther;
0381       // Prompt = permanent bad(low DIGI + low eff/damaged ROCs + other)
0382       SiPixelQuality siPixelQualityPrompt;
0383 
0384       // loop over modules
0385       std::map<int, SiPixelModuleStatus> detectorStatus = tmpSiPixelStatus.getDetectorStatus();
0386       std::map<int, SiPixelModuleStatus>::iterator itModEnd = detectorStatus.end();
0387       for (std::map<int, SiPixelModuleStatus>::iterator itMod = detectorStatus.begin(); itMod != itModEnd; ++itMod) {
0388         // create the bad module list for PCL and other
0389         SiPixelQuality::disabledModuleType BadModulePCL, BadModuleOther;
0390 
0391         int detid = itMod->first;
0392         uint32_t detId = uint32_t(detid);
0393 
0394         double DetAverage_local = SiPixelStatusHarvester::perLayerRingAverage(detid, tmpSiPixelStatus);
0395         double local_threshold = 0.0;
0396 
0397         int layer = coord_.layer(DetId(detid));
0398         int ring = coord_.ring(DetId(detid));
0399 
0400         if (layer == 1)
0401           local_threshold = thresholdL1_;
0402         if (layer == 2)
0403           local_threshold = thresholdL2_;
0404         if (layer == 3)
0405           local_threshold = thresholdL3_;
0406         if (layer == 4)
0407           local_threshold = thresholdL4_;
0408 
0409         if (ring == 1)
0410           local_threshold = thresholdRNG1_;
0411         if (ring == 2)
0412           local_threshold = thresholdRNG2_;
0413 
0414         BadModulePCL.DetID = uint32_t(detid);
0415         BadModuleOther.DetID = uint32_t(detid);
0416         BadModulePCL.errorType = 3;
0417         BadModuleOther.errorType = 3;
0418         BadModulePCL.BadRocs = 0;
0419         BadModuleOther.BadRocs = 0;
0420 
0421         std::vector<uint32_t> BadRocListPCL, BadRocListOther;
0422 
0423         // module status and FEDerror25 status for module with DetId detId
0424         SiPixelModuleStatus modStatus = itMod->second;
0425         std::vector<int> listFEDerror25 = tmpFEDerror25[detid];
0426 
0427         std::map<int, std::pair<int, int>> rocToOfflinePixel = pixelO2O_[detid];
0428         for (int iroc = 0; iroc < modStatus.nrocs(); ++iroc) {
0429           unsigned int rocOccupancy = modStatus.digiOccROC(iroc);
0430 
0431           int row = rocToOfflinePixel[iroc].first;
0432           int column = rocToOfflinePixel[iroc].second;
0433 
0434           // Bad ROC are from low DIGI Occ ROCs
0435           if (rocOccupancy < local_threshold * DetAverage_local) {  // if BAD
0436 
0437             //PCL bad roc list
0438             BadRocListPCL.push_back(uint32_t(iroc));
0439             for (int iLumi = 0; iLumi < interval; iLumi++) {
0440               histo[BADROC].fill(detId, nullptr, column, row);  //, 1.0/nLumiBlock_);
0441             }
0442 
0443             //FEDerror25 list
0444             std::vector<int>::iterator it = std::find(listFEDerror25.begin(), listFEDerror25.end(), iroc);
0445 
0446             // other source of bad components = PCL bad - FEDerror25 - permanent bad
0447             if (it == listFEDerror25.end() && !(badPixelInfo_->IsRocBad(detId, short(iroc)))) {
0448               // if neither permanent nor FEDerror25
0449               BadRocListOther.push_back(uint32_t(iroc));
0450               for (int iLumi = 0; iLumi < interval; iLumi++) {
0451                 histo[OTHERBADROC].fill(detId, nullptr, column, row);  //, 1.0/nLumiBlock_);
0452               }
0453             }
0454 
0455           }  // if BAD
0456 
0457         }  // loop over ROCs
0458 
0459         // errorType 0 means the full module is bad
0460         if (BadRocListPCL.size() == sensorSize_[detid])
0461           BadModulePCL.errorType = 0;
0462         if (BadRocListOther.size() == sensorSize_[detid])
0463           BadModuleOther.errorType = 0;
0464 
0465         // PCL
0466         short badrocsPCL = 0;
0467         for (std::vector<uint32_t>::iterator iterPCL = BadRocListPCL.begin(); iterPCL != BadRocListPCL.end();
0468              ++iterPCL) {
0469           badrocsPCL += 1 << *iterPCL;  // 1 << *iter = 2^{*iter} using bitwise shift
0470         }
0471         if (badrocsPCL != 0) {
0472           BadModulePCL.BadRocs = badrocsPCL;
0473           siPixelQualityPCL.addDisabledModule(BadModulePCL);
0474         }
0475 
0476         // Other
0477         short badrocsOther = 0;
0478         for (std::vector<uint32_t>::iterator iterOther = BadRocListOther.begin(); iterOther != BadRocListOther.end();
0479              ++iterOther) {
0480           badrocsOther += 1 << *iterOther;  // 1 << *iter = 2^{*iter} using bitwise shift
0481         }
0482         if (badrocsOther != 0) {
0483           BadModuleOther.BadRocs = badrocsOther;
0484           siPixelQualityOther.addDisabledModule(BadModuleOther);
0485         }
0486 
0487         // start constructing bad components for prompt = "other" + permanent
0488         SiPixelQuality::disabledModuleType BadModulePrompt;
0489         BadModulePrompt.DetID = uint32_t(detid);
0490         BadModulePrompt.errorType = 3;
0491         BadModulePrompt.BadRocs = 0;
0492 
0493         std::vector<uint32_t> BadRocListPrompt;
0494         for (int iroc = 0; iroc < modStatus.nrocs(); ++iroc) {
0495           // if in permannet bad tag or is in other tag
0496           if (badPixelInfo_->IsRocBad(detId, short(iroc)) || ((badrocsOther >> short(iroc)) & 0x1)) {
0497             BadRocListPrompt.push_back(uint32_t(iroc));
0498 
0499             std::map<int, std::pair<int, int>> rocToOfflinePixel = pixelO2O_[detid];
0500             int row = rocToOfflinePixel[iroc].first;
0501             int column = rocToOfflinePixel[iroc].second;
0502             for (int iLumi = 0; iLumi < interval; iLumi++) {
0503               histo[PROMPTBADROC].fill(detId, nullptr, column, row);  //, 1.0/nLumiBlock_);
0504             }
0505           }  // if bad
0506         }    // loop over all ROCs
0507 
0508         // errorType 0 means the full module is bad
0509         if (BadRocListPrompt.size() == sensorSize_[detid])
0510           BadModulePrompt.errorType = 0;
0511 
0512         short badrocsPrompt = 0;
0513         for (std::vector<uint32_t>::iterator iterPrompt = BadRocListPrompt.begin();
0514              iterPrompt != BadRocListPrompt.end();
0515              ++iterPrompt) {
0516           badrocsPrompt += 1 << *iterPrompt;  // 1 << *iter = 2^{*iter} using bitwise shift
0517         }
0518         if (badrocsPrompt != 0) {
0519           BadModulePrompt.BadRocs = badrocsPrompt;
0520           siPixelQualityPrompt.addDisabledModule(BadModulePrompt);
0521         }
0522 
0523       }  // end module loop
0524 
0525       // PCL
0526       siPixelQualityPCL_Tag[itIOV->first] = siPixelQualityPCL;
0527       // Prompt
0528       siPixelQualityPrompt_Tag[itIOV->first] = siPixelQualityPrompt;
0529       // Other
0530       siPixelQualityOther_Tag[itIOV->first] = siPixelQualityOther;
0531 
0532     }  // loop over IOV
0533 
0534     // Now construct the tags made of payloads
0535     // and only append newIOV if this payload differs wrt last
0536 
0537     //PCL
0538     if (debug_ == true)  // only produced for debugging reason
0539       SiPixelStatusHarvester::constructTag(siPixelQualityPCL_Tag, poolDbService, "PCL", iRun);
0540     // other
0541     SiPixelStatusHarvester::constructTag(siPixelQualityOther_Tag, poolDbService, "other", iRun);
0542     // prompt
0543     SiPixelStatusHarvester::constructTag(siPixelQualityPrompt_Tag, poolDbService, "prompt", iRun);
0544     // stuckTBM
0545     SiPixelStatusHarvester::constructTag(siPixelQualityStuckTBM_Tag, poolDbService, "stuckTBM", iRun);
0546 
0547     // Add a dummy IOV starting from last lumisection+1 to close the tag for the run
0548     if ((outputBase_ == "nLumibased" || outputBase_ == "dynamicLumibased") && !finalIOV.empty()) {
0549       itIOV = std::prev(finalIOV.end());  // go to last element in the pixel quality tag
0550       SiPixelQuality lastPrompt = siPixelQualityPrompt_Tag[itIOV->first];
0551       SiPixelQuality lastOther = siPixelQualityOther_Tag[itIOV->first];
0552 
0553       // add permanent bad components to last lumi+1 IF AND ONLY IF the last payload of prompt is not equal to permanent bad components
0554       edm::LuminosityBlockID lu(iRun.id().run(), endLumiBlock_ + 1);
0555       cond::Time_t thisIOV = (cond::Time_t)(lu.value());
0556       if (!SiPixelStatusHarvester::equal(lastPrompt, siPixelQualityPermBad))
0557         poolDbService->writeOneIOV<SiPixelQuality>(siPixelQualityPermBad, thisIOV, recordName_ + "_prompt");
0558 
0559       // add empty bad components to last lumi+1 IF AND ONLY IF the last payload of other is not equal to empty
0560       SiPixelQuality siPixelQualityDummy;
0561       if (!SiPixelStatusHarvester::equal(lastOther, siPixelQualityDummy))
0562         poolDbService->writeOneIOV<SiPixelQuality>(siPixelQualityDummy, thisIOV, recordName_ + "_other");
0563     }
0564   }  // end of if(poolDbService.isAvailable() )
0565 }
0566 
0567 //--------------------------------------------------------------------------------------------------
0568 void SiPixelStatusHarvester::beginLuminosityBlock(const edm::LuminosityBlock& iLumi, const edm::EventSetup&) {
0569   countLumi_++;
0570 }
0571 
0572 //--------------------------------------------------------------------------------------------------
0573 void SiPixelStatusHarvester::endLuminosityBlock(const edm::LuminosityBlock& iLumi, const edm::EventSetup&) {
0574   siPixelStatusManager_.readLumi(iLumi);
0575   // update endLumiBlock_ by current lumi block
0576   if (endLumiBlock_ < iLumi.luminosityBlock())
0577     endLumiBlock_ = iLumi.luminosityBlock();
0578 }
0579 
0580 // step function for IOV
0581 edm::LuminosityBlockNumber_t SiPixelStatusHarvester::stepIOV(
0582     edm::LuminosityBlockNumber_t pin, std::map<edm::LuminosityBlockNumber_t, edm::LuminosityBlockNumber_t> IOV) {
0583   std::map<edm::LuminosityBlockNumber_t, edm::LuminosityBlockNumber_t>::iterator itIOV;
0584   for (itIOV = IOV.begin(); itIOV != IOV.end(); itIOV++) {
0585     std::map<edm::LuminosityBlockNumber_t, edm::LuminosityBlockNumber_t>::iterator nextItIOV;
0586     nextItIOV = itIOV;
0587     nextItIOV++;
0588 
0589     if (nextItIOV != IOV.end()) {
0590       if (pin >= itIOV->first && pin < nextItIOV->first) {
0591         return itIOV->first;
0592       }
0593     } else {
0594       if (pin >= itIOV->first) {
0595         return itIOV->first;
0596       }
0597     }
0598   }
0599 
0600   // return the firstIOV in case all above fail
0601   return (IOV.begin())->first;
0602 }
0603 
0604 //--------------------------------------------------------------------------------------------------
0605 bool SiPixelStatusHarvester::equal(SiPixelQuality a, SiPixelQuality b) {
0606   std::vector<SiPixelQuality::disabledModuleType> badRocListA;
0607   std::vector<SiPixelQuality::disabledModuleType> badRocListB;
0608 
0609   for (unsigned int ia = 0; ia < (a.getBadComponentList()).size(); ia++) {
0610     badRocListA.push_back((a.getBadComponentList())[ia]);
0611   }
0612   for (unsigned int ib = 0; ib < (b.getBadComponentList()).size(); ib++) {
0613     badRocListB.push_back((b.getBadComponentList())[ib]);
0614   }
0615 
0616   if (badRocListA.size() != badRocListB.size())
0617     return false;
0618 
0619   // ordering ROCs by DetId
0620   std::sort(badRocListA.begin(), badRocListA.end(), SiPixelQuality::BadComponentStrictWeakOrdering());
0621   std::sort(badRocListB.begin(), badRocListB.end(), SiPixelQuality::BadComponentStrictWeakOrdering());
0622 
0623   for (unsigned int i = 0; i < badRocListA.size(); i++) {
0624     uint32_t detIdA = badRocListA[i].DetID;
0625     uint32_t detIdB = badRocListB[i].DetID;
0626     if (detIdA != detIdB)
0627       return false;
0628     else {
0629       unsigned short BadRocsA = badRocListA[i].BadRocs;
0630       unsigned short BadRocsB = badRocListB[i].BadRocs;
0631       if (BadRocsA != BadRocsB)
0632         return false;
0633     }
0634   }
0635 
0636   //if the module list is the same, and for each module, roc list is the same
0637   //the two SiPixelQualitys are equal
0638   return true;
0639 }
0640 
0641 //--------------------------------------------------------------------------------------------------
0642 void SiPixelStatusHarvester::constructTag(std::map<int, SiPixelQuality> siPixelQualityTag,
0643                                           edm::Service<cond::service::PoolDBOutputService>& poolDbService,
0644                                           std::string tagName,
0645                                           edm::Run const& iRun) {
0646   for (std::map<int, SiPixelQuality>::iterator qIt = siPixelQualityTag.begin(); qIt != siPixelQualityTag.end(); ++qIt) {
0647     edm::LuminosityBlockID lu(iRun.id().run(), qIt->first);
0648     cond::Time_t thisIOV = (cond::Time_t)(lu.value());
0649 
0650     SiPixelQuality thisPayload = qIt->second;
0651     if (qIt == siPixelQualityTag.begin())
0652       poolDbService->writeOneIOV<SiPixelQuality>(thisPayload, thisIOV, recordName_ + "_" + tagName);
0653     else {
0654       SiPixelQuality prevPayload = (std::prev(qIt))->second;
0655       if (!SiPixelStatusHarvester::equal(thisPayload,
0656                                          prevPayload))  // only append newIOV if this payload differs wrt last
0657         poolDbService->writeOneIOV<SiPixelQuality>(thisPayload, thisIOV, recordName_ + "_" + tagName);
0658     }
0659   }
0660 }
0661 
0662 //--------------------------------------------------------------------------------------------------------
0663 double SiPixelStatusHarvester::perLayerRingAverage(int detid, SiPixelDetectorStatus tmpSiPixelStatus) {
0664   unsigned long int ave(0);
0665   int nrocs(0);
0666 
0667   int layer = coord_.layer(DetId(detid));
0668   int ring = coord_.ring(DetId(detid));
0669 
0670   std::map<int, SiPixelModuleStatus> detectorStatus = tmpSiPixelStatus.getDetectorStatus();
0671   std::map<int, SiPixelModuleStatus>::iterator itModEnd = detectorStatus.end();
0672   for (std::map<int, SiPixelModuleStatus>::iterator itMod = detectorStatus.begin(); itMod != itModEnd; ++itMod) {
0673     if (layer != coord_.layer(DetId(itMod->first)))
0674       continue;
0675     if (ring != coord_.ring(DetId(itMod->first)))
0676       continue;
0677     unsigned long int inc = itMod->second.digiOccMOD();
0678     ave += inc;
0679     nrocs += itMod->second.nrocs();
0680   }
0681 
0682   if (nrocs > 0)
0683     return ave * 1.0 / nrocs;
0684   else
0685     return 0.0;
0686 }
0687 
0688 std::string SiPixelStatusHarvester::substructure(int detid) {
0689   std::string substructure = "";
0690   int layer = coord_.layer(DetId(detid));
0691 
0692   if (layer > 0) {
0693     std::string L = std::to_string(layer);
0694     substructure = "BpixLYR";
0695     substructure += L;
0696   } else {
0697     substructure = "FpixRNG";
0698     int ring = coord_.ring(DetId(detid));
0699     std::string R = std::to_string(ring);
0700     substructure += R;
0701   }
0702 
0703   return substructure;
0704 }
0705 
0706 DEFINE_FWK_MODULE(SiPixelStatusHarvester);