CMS 3D CMS Logo

SiStripQualityWithFromFedErrorsHelper.cc
Go to the documentation of this file.
1 #include "TFile.h"
2 #include "TKey.h"
5 
8 
11 
12 namespace {
13 
14  void fillFedBadChannelMap(const TH2F* th2,
15  float entries,
16  float cutoff,
17  const SiStripFedCabling& fedCabling,
18  std::map<uint32_t, std::set<int>>& detectorMap) {
19  for (uint16_t i = 1; i < th2->GetNbinsY() + 1; ++i) {
20  for (uint16_t j = 1; j < th2->GetNbinsX() + 1; ++j) {
21  if (th2->GetBinContent(j, i) > cutoff * entries) {
22  const uint16_t fId = th2->GetYaxis()->GetBinLowEdge(i);
23  edm::LogInfo("SiStripBadModuleFedErrService")
24  << " [SiStripBadModuleFedErrService::getFedBadChannelList] :: FedId & Channel " << fId << " "
25  << th2->GetXaxis()->GetBinLowEdge(j);
26  const uint16_t fChan = uint16_t(th2->GetXaxis()->GetBinLowEdge(j)) / 2;
27  if (!((fId == 9999) && (fChan == 9999))) {
28  const auto channel = fedCabling.fedConnection(fId, fChan);
29  detectorMap[channel.detId()].insert(channel.apvPairNumber());
30  }
31  }
32  }
33  }
34  }
35 
36  float getProcessedEvents(DQMStore::IGetter& dqmStore) {
37  dqmStore.cd();
38  const std::string dname{"SiStrip/ReadoutView"};
39  const std::string hpath{dname + "/nTotalBadActiveChannels"};
40  if (dqmStore.dirExists(dname)) {
41  MonitorElement* me = dqmStore.get(hpath);
42  if (me)
43  return me->getEntries();
44  }
45  return 0;
46  }
47 
48  std::map<uint32_t, std::set<int>> getBadChannelDetectorMap(DQMStore::IGetter& dqmStore,
49  const SiStripFedCabling& fedCabling,
50  float cutoff) {
51  std::map<uint32_t, std::set<int>> detectorMap;
52  dqmStore.cd();
53  const std::string dname{"SiStrip/ReadoutView"};
54  const std::string hpath{dname + "/FedIdVsApvId"};
55  if (dqmStore.dirExists(dname)) {
56  MonitorElement* me = dqmStore.get(hpath);
57  if (me && (me->kind() == MonitorElement::Kind::TH2F)) {
58  TH2F* th2 = me->getTH2F();
59  float entries = getProcessedEvents(dqmStore);
60  if (!entries) {
61  edm::LogWarning("SiStripBadModuleFedErrService") << "Normalising to the largest bin";
62  entries = th2->GetBinContent(th2->GetMaximumBin());
63  }
64  fillFedBadChannelMap(th2, entries, cutoff, fedCabling, detectorMap);
65  } else {
66  edm::LogError("SiStripBadModuleFedErrService") << "Could not find SiStrip/ReadoutView/FedIdVsApvId";
67  }
68  } else {
69  edm::LogError("SiStripBadModuleFedErrService") << "Could not find SiStrip/ReadoutView";
70  }
71  return detectorMap;
72  }
73 
74  TDirectoryFile* checkAndGetSubdir(TDirectoryFile* tdir, const std::vector<std::string>& path) {
75  for (const auto& subName : path) {
76  tdir = tdir->Get<TDirectoryFile>(subName.c_str());
77  if (!tdir) {
78  break;
79  }
80  }
81  return tdir;
82  }
83 
84  std::map<uint32_t, std::set<int>> getBadChannelDetectorMap(TFile* legacyDQMTDirFile,
85  unsigned int runNumber,
86  const SiStripFedCabling& fedCabling,
87  float cutoff) {
88  std::map<uint32_t, std::set<int>> detectorMap;
89  const auto stripROVDir = checkAndGetSubdir(
90  legacyDQMTDirFile, {"DQMData", "Run " + std::to_string(runNumber), "SiStrip", "Run summary", "ReadoutView"});
91  if (!stripROVDir) {
92  edm::LogError("SiStripBadModuleFedErrService")
93  << "Could not find SiStrip/ReadoutView directory in " << legacyDQMTDirFile->GetName() << " with run number "
94  << runNumber;
95  } else {
96  const auto th2 = stripROVDir->Get<TH2F>("FedIdVsApvId");
97  if (!th2) {
98  edm::LogError("SiStripBadModuleFedErrService")
99  << "Could not find SiStrip/ReadoutView/FedIdVsApvId in " << legacyDQMTDirFile->GetName();
100  } else {
101  float entries = 0.;
102  const auto nActChan = stripROVDir->Get<TH1F>("nTotalBadActiveChannels");
103  if (nActChan) {
104  entries = nActChan->GetEntries();
105  }
106  if (!entries) {
107  edm::LogWarning("SiStripBadModuleFedErrService") << "Normalising to the largest bin";
108  entries = th2->GetBinContent(th2->GetMaximumBin());
109  }
110  fillFedBadChannelMap(th2, entries, cutoff, fedCabling, detectorMap);
111  }
112  }
113  return detectorMap;
114  }
115 
116  void fillQuality(SiStripQuality* quality, const std::map<uint32_t, std::set<int>>& detectorMap) {
117  for (const auto& detElm : detectorMap) { // pair(detId, pairs)
118  SiStripQuality::InputVector theSiStripVector;
119  unsigned short firstBadStrip{0};
120  unsigned short fNconsecutiveBadStrips{0};
121  int last_pair = -1;
122  for (const auto pair : detElm.second) {
123  if (last_pair == -1) {
124  firstBadStrip = pair * 128 * 2;
125  fNconsecutiveBadStrips = 128 * 2;
126  } else if (pair - last_pair > 1) {
127  theSiStripVector.push_back(quality->encode(firstBadStrip, fNconsecutiveBadStrips));
128  firstBadStrip = pair * 128 * 2;
129  fNconsecutiveBadStrips = 128 * 2;
130  } else {
131  fNconsecutiveBadStrips += 128 * 2;
132  }
133  last_pair = pair;
134  }
135  unsigned int theBadStripRange = quality->encode(firstBadStrip, fNconsecutiveBadStrips);
136  theSiStripVector.push_back(theBadStripRange);
137 
138  edm::LogInfo("SiStripBadModuleFedErrService")
139  << " SiStripBadModuleFedErrService::readBadComponentsFromFed "
140  << " detid " << detElm.first << " firstBadStrip " << firstBadStrip << " NconsecutiveBadStrips "
141  << fNconsecutiveBadStrips << " packed integer " << std::hex << theBadStripRange << std::dec;
142 
143  if (!quality->put(detElm.first, SiStripBadStrip::Range{theSiStripVector.begin(), theSiStripVector.end()})) {
144  edm::LogError("SiStripBadModuleFedErrService")
145  << "[SiStripBadModuleFedErrService::readBadComponentsFromFed] detid already exists";
146  }
147  }
148  }
149 
150 } // namespace
151 
152 std::unique_ptr<SiStripQuality> sistrip::badStripFromFedErr(DQMStore::IGetter& dqmStore,
153  const SiStripFedCabling& fedCabling,
154  float cutoff) {
155  const auto detInfo =
157  auto quality = std::make_unique<SiStripQuality>(detInfo);
158  auto detectorMap = getBadChannelDetectorMap(dqmStore, fedCabling, cutoff);
159  if (!detectorMap.empty()) {
160  fillQuality(quality.get(), detectorMap);
161  quality->cleanUp();
162  } else {
163  edm::LogWarning("SiStripBadModuleFedErrService") << "Empty bad channel map from FED errors";
164  }
165  return quality;
166 }
167 
168 std::unique_ptr<SiStripQuality> sistrip::badStripFromFedErrLegacyDQMFile(const std::string& fileName,
169  unsigned int runNumber,
170  const SiStripFedCabling& fedCabling,
171  float cutoff) {
172  const auto detInfo =
174  auto quality = std::make_unique<SiStripQuality>(detInfo);
175  auto tdirFile = TFile::Open(fileName.c_str());
176  auto detectorMap = getBadChannelDetectorMap(tdirFile, runNumber, fedCabling, cutoff);
177  if (!detectorMap.empty()) {
178  fillQuality(quality.get(), detectorMap);
179  quality->cleanUp();
180  } else {
181  edm::LogWarning("SiStripBadModuleFedErrService") << "Empty bad channel map from FED errors";
182  }
183  return quality;
184 }
185 
187  if (stripQualityWatcher_.check(iSetup)) {
188  if (keepCopy_) {
189  mergedQuality_ = std::make_unique<SiStripQuality>(iSetup.getData(stripQualityToken_));
190  if (addBadCompFromFedErr_) {
191  fedCabling_ = std::make_unique<SiStripFedCabling>(iSetup.getData(fedCablingToken_));
192  }
193  merged_ = false;
194  }
195  return true;
196  } else {
197  return false;
198  }
199 }
200 
203  if (!merged_) {
204  if (addBadCompFromFedErr_) {
205  std::unique_ptr<SiStripQuality> fedErrQuality{};
206  if (fedErrLegacyFile_.empty()) {
207  edm::LogInfo("SiStripQuality") << "Adding bad components from FED errors in DQM store";
208  fedErrQuality = sistrip::badStripFromFedErr(getter, *fedCabling_, fedErrCutoff_);
209  } else {
210  edm::LogInfo("SiStripQuality") << "Adding bad components from FED errors in legacy DQM file "
214  }
215  mergedQuality_->add(fedErrQuality.get());
216  mergedQuality_->cleanUp();
217  mergedQuality_->fillBadComponents();
218  }
219  merged_ = true;
220  }
221 
222  return *mergedQuality_;
223 }
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
edm::ESWatcher< SiStripQualityRcd > stripQualityWatcher_
dqm::legacy::DQMStore DQMStore
Definition: DQMStore.h:825
std::unique_ptr< SiStripQuality > badStripFromFedErr(dqm::harvesting::DQMStore::IGetter &dqmStore, const SiStripFedCabling &fedCabling, float cutoff)
FedChannelConnection fedConnection(uint16_t fed_id, uint16_t fed_ch) const
edm::ESGetToken< SiStripFedCabling, SiStripFedCablingRcd > fedCablingToken_
Log< level::Error, false > LogError
static std::string to_string(const XMLCh *ch)
edm::ESGetToken< SiStripQuality, SiStripQualityRcd > stripQualityToken_
string quality
SiStripDetInfo read(std::string filePath)
dqm::legacy::MonitorElement MonitorElement
Log< level::Info, false > LogInfo
const SiStripQuality & getMergedQuality(dqm::harvesting::DQMStore::IGetter &getter)
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
std::pair< ContainerIterator, ContainerIterator > Range
static constexpr char const *const kDefaultFile
Log< level::Warning, false > LogWarning
std::unique_ptr< SiStripQuality > badStripFromFedErrLegacyDQMFile(const std::string &fileName, unsigned int runNumber, const SiStripFedCabling &fedCabling, float cutoff)
Container InputVector