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) {
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 }
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 }