Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:00:01

0001 #include "TFile.h"
0002 #include "TKey.h"
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
0005 
0006 #include "CalibTracker/SiStripCommon/interface/SiStripDetInfoFileReader.h"
0007 #include "CalibTracker/SiStripQuality/interface/SiStripQualityWithFromFedErrorsHelper.h"
0008 
0009 using dqm::harvesting::DQMStore;
0010 using dqm::harvesting::MonitorElement;
0011 
0012 namespace {
0013 
0014   void fillFedBadChannelMap(const TH2F* th2,
0015                             float entries,
0016                             float cutoff,
0017                             const SiStripFedCabling& fedCabling,
0018                             std::map<uint32_t, std::set<int>>& detectorMap) {
0019     for (uint16_t i = 1; i < th2->GetNbinsY() + 1; ++i) {
0020       for (uint16_t j = 1; j < th2->GetNbinsX() + 1; ++j) {
0021         if (th2->GetBinContent(j, i) > cutoff * entries) {
0022           const uint16_t fId = th2->GetYaxis()->GetBinLowEdge(i);
0023           edm::LogInfo("SiStripBadModuleFedErrService")
0024               << " [SiStripBadModuleFedErrService::getFedBadChannelList] :: FedId & Channel " << fId << "  "
0025               << th2->GetXaxis()->GetBinLowEdge(j);
0026           const uint16_t fChan = uint16_t(th2->GetXaxis()->GetBinLowEdge(j)) / 2;
0027           if (!((fId == 9999) && (fChan == 9999))) {
0028             const auto channel = fedCabling.fedConnection(fId, fChan);
0029             detectorMap[channel.detId()].insert(channel.apvPairNumber());
0030           }
0031         }
0032       }
0033     }
0034   }
0035 
0036   float getProcessedEvents(DQMStore::IGetter& dqmStore) {
0037     dqmStore.cd();
0038     const std::string dname{"SiStrip/ReadoutView"};
0039     const std::string hpath{dname + "/nTotalBadActiveChannels"};
0040     if (dqmStore.dirExists(dname)) {
0041       MonitorElement* me = dqmStore.get(hpath);
0042       if (me)
0043         return me->getEntries();
0044     }
0045     return 0;
0046   }
0047 
0048   std::map<uint32_t, std::set<int>> getBadChannelDetectorMap(DQMStore::IGetter& dqmStore,
0049                                                              const SiStripFedCabling& fedCabling,
0050                                                              float cutoff) {
0051     std::map<uint32_t, std::set<int>> detectorMap;
0052     dqmStore.cd();
0053     const std::string dname{"SiStrip/ReadoutView"};
0054     const std::string hpath{dname + "/FedIdVsApvId"};
0055     if (dqmStore.dirExists(dname)) {
0056       MonitorElement* me = dqmStore.get(hpath);
0057       if (me && (me->kind() == MonitorElement::Kind::TH2F)) {
0058         TH2F* th2 = me->getTH2F();
0059         float entries = getProcessedEvents(dqmStore);
0060         if (!entries) {
0061           edm::LogWarning("SiStripBadModuleFedErrService") << "Normalising to the largest bin";
0062           entries = th2->GetBinContent(th2->GetMaximumBin());
0063         }
0064         fillFedBadChannelMap(th2, entries, cutoff, fedCabling, detectorMap);
0065       } else {
0066         edm::LogError("SiStripBadModuleFedErrService") << "Could not find SiStrip/ReadoutView/FedIdVsApvId";
0067       }
0068     } else {
0069       edm::LogError("SiStripBadModuleFedErrService") << "Could not find SiStrip/ReadoutView";
0070     }
0071     return detectorMap;
0072   }
0073 
0074   TDirectoryFile* checkAndGetSubdir(TDirectoryFile* tdir, const std::vector<std::string>& path) {
0075     for (const auto& subName : path) {
0076       tdir = tdir->Get<TDirectoryFile>(subName.c_str());
0077       if (!tdir) {
0078         break;
0079       }
0080     }
0081     return tdir;
0082   }
0083 
0084   std::map<uint32_t, std::set<int>> getBadChannelDetectorMap(TFile* legacyDQMTDirFile,
0085                                                              unsigned int runNumber,
0086                                                              const SiStripFedCabling& fedCabling,
0087                                                              float cutoff) {
0088     std::map<uint32_t, std::set<int>> detectorMap;
0089     const auto stripROVDir = checkAndGetSubdir(
0090         legacyDQMTDirFile, {"DQMData", "Run " + std::to_string(runNumber), "SiStrip", "Run summary", "ReadoutView"});
0091     if (!stripROVDir) {
0092       edm::LogError("SiStripBadModuleFedErrService")
0093           << "Could not find SiStrip/ReadoutView directory in " << legacyDQMTDirFile->GetName() << " with run number "
0094           << runNumber;
0095     } else {
0096       const auto th2 = stripROVDir->Get<TH2F>("FedIdVsApvId");
0097       if (!th2) {
0098         edm::LogError("SiStripBadModuleFedErrService")
0099             << "Could not find SiStrip/ReadoutView/FedIdVsApvId in " << legacyDQMTDirFile->GetName();
0100       } else {
0101         float entries = 0.;
0102         const auto nActChan = stripROVDir->Get<TH1F>("nTotalBadActiveChannels");
0103         if (nActChan) {
0104           entries = nActChan->GetEntries();
0105         }
0106         if (!entries) {
0107           edm::LogWarning("SiStripBadModuleFedErrService") << "Normalising to the largest bin";
0108           entries = th2->GetBinContent(th2->GetMaximumBin());
0109         }
0110         fillFedBadChannelMap(th2, entries, cutoff, fedCabling, detectorMap);
0111       }
0112     }
0113     return detectorMap;
0114   }
0115 
0116   void fillQuality(SiStripQuality* quality, const std::map<uint32_t, std::set<int>>& detectorMap) {
0117     for (const auto& detElm : detectorMap) {  // pair(detId, pairs)
0118       SiStripQuality::InputVector theSiStripVector;
0119       unsigned short firstBadStrip{0};
0120       unsigned short fNconsecutiveBadStrips{0};
0121       int last_pair = -1;
0122       for (const auto pair : detElm.second) {
0123         if (last_pair == -1) {
0124           firstBadStrip = pair * 128 * 2;
0125           fNconsecutiveBadStrips = 128 * 2;
0126         } else if (pair - last_pair > 1) {
0127           theSiStripVector.push_back(quality->encode(firstBadStrip, fNconsecutiveBadStrips));
0128           firstBadStrip = pair * 128 * 2;
0129           fNconsecutiveBadStrips = 128 * 2;
0130         } else {
0131           fNconsecutiveBadStrips += 128 * 2;
0132         }
0133         last_pair = pair;
0134       }
0135       unsigned int theBadStripRange = quality->encode(firstBadStrip, fNconsecutiveBadStrips);
0136       theSiStripVector.push_back(theBadStripRange);
0137 
0138       edm::LogInfo("SiStripBadModuleFedErrService")
0139           << " SiStripBadModuleFedErrService::readBadComponentsFromFed "
0140           << " detid " << detElm.first << " firstBadStrip " << firstBadStrip << " NconsecutiveBadStrips "
0141           << fNconsecutiveBadStrips << " packed integer " << std::hex << theBadStripRange << std::dec;
0142 
0143       if (!quality->put(detElm.first, SiStripBadStrip::Range{theSiStripVector.begin(), theSiStripVector.end()})) {
0144         edm::LogError("SiStripBadModuleFedErrService")
0145             << "[SiStripBadModuleFedErrService::readBadComponentsFromFed] detid already exists";
0146       }
0147     }
0148   }
0149 
0150 }  // namespace
0151 
0152 std::unique_ptr<SiStripQuality> sistrip::badStripFromFedErr(DQMStore::IGetter& dqmStore,
0153                                                             const SiStripFedCabling& fedCabling,
0154                                                             float cutoff) {
0155   const auto detInfo =
0156       SiStripDetInfoFileReader::read(edm::FileInPath{SiStripDetInfoFileReader::kDefaultFile}.fullPath());
0157   auto quality = std::make_unique<SiStripQuality>(detInfo);
0158   auto detectorMap = getBadChannelDetectorMap(dqmStore, fedCabling, cutoff);
0159   if (!detectorMap.empty()) {
0160     fillQuality(quality.get(), detectorMap);
0161     quality->cleanUp();
0162   } else {
0163     edm::LogWarning("SiStripBadModuleFedErrService") << "Empty bad channel map from FED errors";
0164   }
0165   return quality;
0166 }
0167 
0168 std::unique_ptr<SiStripQuality> sistrip::badStripFromFedErrLegacyDQMFile(const std::string& fileName,
0169                                                                          unsigned int runNumber,
0170                                                                          const SiStripFedCabling& fedCabling,
0171                                                                          float cutoff) {
0172   const auto detInfo =
0173       SiStripDetInfoFileReader::read(edm::FileInPath{SiStripDetInfoFileReader::kDefaultFile}.fullPath());
0174   auto quality = std::make_unique<SiStripQuality>(detInfo);
0175   auto tdirFile = TFile::Open(fileName.c_str());
0176   auto detectorMap = getBadChannelDetectorMap(tdirFile, runNumber, fedCabling, cutoff);
0177   if (!detectorMap.empty()) {
0178     fillQuality(quality.get(), detectorMap);
0179     quality->cleanUp();
0180   } else {
0181     edm::LogWarning("SiStripBadModuleFedErrService") << "Empty bad channel map from FED errors";
0182   }
0183   return quality;
0184 }
0185 
0186 bool SiStripQualityWithFromFedErrorsHelper::endRun(const edm::EventSetup& iSetup) {
0187   if (stripQualityWatcher_.check(iSetup)) {
0188     if (keepCopy_) {
0189       mergedQuality_ = std::make_unique<SiStripQuality>(iSetup.getData(stripQualityToken_));
0190       if (addBadCompFromFedErr_) {
0191         fedCabling_ = std::make_unique<SiStripFedCabling>(iSetup.getData(fedCablingToken_));
0192       }
0193       merged_ = false;
0194     }
0195     return true;
0196   } else {
0197     return false;
0198   }
0199 }
0200 
0201 const SiStripQuality& SiStripQualityWithFromFedErrorsHelper::getMergedQuality(
0202     dqm::harvesting::DQMStore::IGetter& getter) {
0203   if (!merged_) {
0204     if (addBadCompFromFedErr_) {
0205       std::unique_ptr<SiStripQuality> fedErrQuality{};
0206       if (fedErrLegacyFile_.empty()) {
0207         edm::LogInfo("SiStripQuality") << "Adding bad components from FED errors in DQM store";
0208         fedErrQuality = sistrip::badStripFromFedErr(getter, *fedCabling_, fedErrCutoff_);
0209       } else {
0210         edm::LogInfo("SiStripQuality") << "Adding bad components from FED errors in legacy DQM file "
0211                                        << fedErrLegacyFile_;
0212         fedErrQuality = sistrip::badStripFromFedErrLegacyDQMFile(
0213             fedErrLegacyFile_, fedErrFileRunNumber_, *fedCabling_, fedErrCutoff_);
0214       }
0215       mergedQuality_->add(fedErrQuality.get());
0216       mergedQuality_->cleanUp();
0217       mergedQuality_->fillBadComponents();
0218     }
0219     merged_ = true;
0220   }
0221 
0222   return *mergedQuality_;
0223 }