Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:35:07

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