CMS 3D CMS Logo

SiStripHitEfficiencyHarvester.cc
Go to the documentation of this file.
1 // user includes
24 
25 //system includes
26 #include <boost/type_index.hpp>
27 #include <fmt/printf.h>
28 #include <numeric> // for std::accumulate
29 #include <sstream>
30 
31 // ROOT includes
32 #include "TCanvas.h"
33 #include "TEfficiency.h"
34 #include "TGraphAsymmErrors.h"
35 #include "TLegend.h"
36 #include "TStyle.h"
37 #include "TTree.h"
38 
39 // custom made printout
40 #define LOGPRINT edm::LogPrint("SiStripHitEfficiencyHarvester")
41 
43 public:
45  ~SiStripHitEfficiencyHarvester() override = default;
46  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
47 
48  void endRun(edm::Run const&, edm::EventSetup const&) override;
50 
51 private:
54  const bool isAtPCL_;
56  const bool doStoreOnTree_;
58  const unsigned int nTEClayers_;
59  const double threshold_;
60  const int nModsMin_;
61  const float effPlotMin_;
62  const double tkMapMin_;
64 
69 
70  std::unique_ptr<TrackerTopology> tTopo_;
71  std::unique_ptr<TkDetMap> tkDetMap_;
72  std::unique_ptr<SiStripQuality> stripQuality_;
73  std::vector<DetId> stripDetIds_;
74 
75  int goodlayertotal[bounds::k_END_OF_LAYS_AND_RINGS];
76  int goodlayerfound[bounds::k_END_OF_LAYS_AND_RINGS];
77  int alllayertotal[bounds::k_END_OF_LAYS_AND_RINGS];
78  int alllayerfound[bounds::k_END_OF_LAYS_AND_RINGS];
79 
80  // information for the TTree
81  TTree* tree;
82  unsigned int t_DetId, t_found, t_total;
83  unsigned char t_layer;
85  float t_threshold;
86 
87  void writeBadStripPayload(const SiStripQuality& quality) const;
88  void printTotalStatistics(const std::array<long, bounds::k_END_OF_LAYERS>& layerFound,
89  const std::array<long, bounds::k_END_OF_LAYERS>& layerTotal) const;
90  void printAndWriteBadModules(const SiStripQuality& quality, const SiStripDetInfo& detInfo) const;
91  bool checkMapsValidity(const std::vector<MonitorElement*>& maps, const std::string& type) const;
92  unsigned int countTotalHits(const std::vector<MonitorElement*>& maps); /* to check if TK was ON */
93  void makeSummary(DQMStore::IGetter& getter, DQMStore::IBooker& booker, bool doProfiles = false) const;
94  template <typename T>
95  void setEffBinLabels(const T gr, const T gr2, const unsigned int nLayers) const;
96  void makeSummaryVsVariable(DQMStore::IGetter& getter, DQMStore::IBooker& booker, ::projections theProj) const;
97 };
98 
100  : inputFolder_(conf.getParameter<std::string>("inputFolder")),
101  isAtPCL_(conf.getParameter<bool>("isAtPCL")),
102  autoIneffModTagging_(conf.getUntrackedParameter<bool>("AutoIneffModTagging", false)),
103  doStoreOnDB_(conf.getParameter<bool>("doStoreOnDB")),
104  doStoreOnTree_(conf.getUntrackedParameter<bool>("doStoreOnTree")),
105  showRings_(conf.getUntrackedParameter<bool>("ShowRings", false)),
106  showEndcapSides_(conf.getUntrackedParameter<bool>("ShowEndcapSides", true)),
107  showTOB6TEC9_(conf.getUntrackedParameter<bool>("ShowTOB6TEC9", false)),
108  showOnlyGoodModules_(conf.getUntrackedParameter<bool>("ShowOnlyGoodModules", false)),
109  nTEClayers_(showRings_ ? 7 : 9), // number of rings or wheels
110  threshold_(conf.getParameter<double>("Threshold")),
111  nModsMin_(conf.getParameter<int>("nModsMin")),
112  effPlotMin_(conf.getUntrackedParameter<double>("EffPlotMin", 0.9)),
113  tkMapMin_(conf.getUntrackedParameter<double>("TkMapMin", 0.9)),
114  title_(conf.getParameter<std::string>("Title")),
115  record_(conf.getParameter<std::string>("Record")),
116  tTopoToken_(esConsumes<edm::Transition::EndRun>()),
117  tkDetMapToken_(esConsumes<edm::Transition::EndRun>()),
118  stripQualityToken_(esConsumes<edm::Transition::EndRun>()),
119  tkGeomToken_(esConsumes<edm::Transition::EndRun>()) {
120  // zero in all counts
121  for (int l = 0; l < bounds::k_END_OF_LAYS_AND_RINGS; l++) {
122  goodlayertotal[l] = 0;
123  goodlayerfound[l] = 0;
124  alllayertotal[l] = 0;
125  alllayerfound[l] = 0;
126  }
127 }
128 
130  if (!tTopo_) {
131  tTopo_ = std::make_unique<TrackerTopology>(iSetup.getData(tTopoToken_));
132  }
133  if (!tkDetMap_) {
134  tkDetMap_ = std::make_unique<TkDetMap>(iSetup.getData(tkDetMapToken_));
135  }
136  if (!stripQuality_) {
137  stripQuality_ = std::make_unique<SiStripQuality>(iSetup.getData(stripQualityToken_));
138  }
139  if (stripDetIds_.empty()) {
140  const auto& tkGeom = iSetup.getData(tkGeomToken_);
141  for (const auto& det : tkGeom.detUnits()) {
142  if (dynamic_cast<const StripGeomDetUnit*>(det)) {
143  stripDetIds_.push_back(det->geographicalId());
144  }
145  }
146  }
147 }
148 
149 bool SiStripHitEfficiencyHarvester::checkMapsValidity(const std::vector<MonitorElement*>& maps,
150  const std::string& type) const {
151  std::vector<bool> isThere;
152  isThere.reserve(maps.size());
153  std::transform(maps.begin() + 1, maps.end(), std::back_inserter(isThere), [](auto& x) { return !(x == nullptr); });
154 
155  int count{0};
156  for (const auto& it : isThere) {
157  count++;
158  LogDebug("SiStripHitEfficiencyHarvester") << " layer: " << count << " " << it << std::endl;
159  if (it)
160  LogDebug("SiStripHitEfficiencyHarvester") << "resolving to " << maps[count]->getName() << std::endl;
161  }
162 
163  // check on the input TkHistoMap
164  bool areMapsAvailable{true};
165  int layerCount{0};
166  for (const auto& it : isThere) {
167  layerCount++;
168  if (!it) {
169  edm::LogError("SiStripHitEfficiencyHarvester")
170  << type << " TkHistoMap for layer " << layerCount << " was not found.\n -> Aborting!";
171  areMapsAvailable = false;
172  break;
173  }
174  }
175  return areMapsAvailable;
176 }
177 
178 unsigned int SiStripHitEfficiencyHarvester::countTotalHits(const std::vector<MonitorElement*>& maps) {
179  return std::accumulate(maps.begin() + 1, maps.end(), 0, [](unsigned int total, MonitorElement* item) {
180  return total + item->getEntries();
181  });
182 }
183 
185  if (!isAtPCL_) {
187  if (!fs.isAvailable()) {
188  throw cms::Exception("BadConfig") << "TFileService unavailable: "
189  << "please add it to config file";
190  }
191 
192  if (doStoreOnTree_) {
193  // store information per DetId in the output tree
194  tree = fs->make<TTree>("ModEff", "ModEff");
195  tree->Branch("DetId", &t_DetId, "DetId/i");
196  tree->Branch("Layer", &t_layer, "Layer/b");
197  tree->Branch("FoundHits", &t_found, "FoundHits/i");
198  tree->Branch("AllHits", &t_total, "AllHits/i");
199  tree->Branch("IsTaggedIneff", &t_isTaggedIneff, "IsTaggedIneff/O");
200  tree->Branch("TagThreshold", &t_threshold, "TagThreshold/F");
201  }
202  }
203 
205  LOGPRINT << "A module is bad if efficiency < " << threshold_ << " and has at least " << nModsMin_ << " nModsMin.";
206  else
207  LOGPRINT << "A module is bad if the upper limit on the efficiency is < to the avg in the layer - " << threshold_
208  << " and has at least " << nModsMin_ << " nModsMin.";
209 
210  auto h_module_total = std::make_unique<TkHistoMap>(tkDetMap_.get());
211  h_module_total->loadTkHistoMap(fmt::format("{}/TkDetMaps", inputFolder_), "perModule_total");
212  auto h_module_found = std::make_unique<TkHistoMap>(tkDetMap_.get());
213  h_module_found->loadTkHistoMap(fmt::format("{}/TkDetMaps", inputFolder_), "perModule_found");
214 
215  // collect how many layers are missing
216  const auto& totalMaps = h_module_total->getAllMaps();
217  const auto& foundMaps = h_module_found->getAllMaps();
218 
219  LogDebug("SiStripHitEfficiencyHarvester")
220  << "totalMaps.size(): " << totalMaps.size() << " foundMaps.size() " << foundMaps.size() << std::endl;
221 
222  // check on the input TkHistoMaps
223  bool isTotalMapAvailable = this->checkMapsValidity(totalMaps, std::string("Total"));
224  bool isFoundMapAvailable = this->checkMapsValidity(foundMaps, std::string("Found"));
225 
226  LogDebug("SiStripHitEfficiencyHarvester")
227  << "isTotalMapAvailable: " << isTotalMapAvailable << " isFoundMapAvailable " << isFoundMapAvailable << std::endl;
228 
229  // no input TkHistoMaps -> early return
230  if (!isTotalMapAvailable or !isFoundMapAvailable)
231  return;
232 
233  LogDebug("SiStripHitEfficiencyHarvester")
234  << "Entries in total TkHistoMap for layer 3: " << h_module_total->getMap(3)->getEntries() << ", found "
235  << h_module_found->getMap(3)->getEntries();
236 
237  // count how many hits in the denominator we have
238  const unsigned int totalHits = this->countTotalHits(totalMaps);
239 
240  // set colz
241  for (size_t i = 1; i < totalMaps.size(); i++) {
242  h_module_total->getMap(i)->setOption("colz");
243  h_module_found->getMap(i)->setOption("colz");
244  }
245 
246  // come back to the main folder
248 
249  std::vector<MonitorElement*> hEffInLayer(std::size_t(1), nullptr);
250  hEffInLayer.reserve(bounds::k_END_OF_LAYERS);
251  for (std::size_t i = 1; i != bounds::k_END_OF_LAYERS; ++i) {
252  const auto lyrName = ::layerName(i, showRings_, nTEClayers_);
253  hEffInLayer.push_back(booker.book1D(
254  Form("eff_layer%i", int(i)), Form("Module efficiency in layer %s", lyrName.c_str()), 201, 0, 1.005));
255  }
256  std::array<long, bounds::k_END_OF_LAYERS> layerTotal{};
257  std::array<long, bounds::k_END_OF_LAYERS> layerFound{};
258  layerTotal.fill(0);
259  layerFound.fill(0);
260 
262  // Effiency calculation, bad module tagging, and tracker maps //
264 
265  TrackerMap tkMap{" Detector Inefficiency "};
266  TrackerMap tkMapBad{" Inefficient Modules "};
267  TrackerMap tkMapEff{title_};
268  TrackerMap tkMapNum{" Detector numerator "};
269  TrackerMap tkMapDen{" Detector denominator "};
270  std::map<unsigned int, double> badModules;
271 
272  // load the FEDError map
273  const auto& EventStats = getter.get(fmt::format("{}/EventInfo/EventStats", inputFolder_));
274  const int totalEvents = EventStats->getBinContent(1., 1.); // first bin contains info on number of events run
275  calibData_.FEDErrorOccupancy = std::make_unique<TkHistoMap>(tkDetMap_.get());
276  calibData_.FEDErrorOccupancy->loadTkHistoMap(fmt::format("{}/FEDErrorTkDetMaps", inputFolder_),
277  "perModule_FEDErrors");
278 
279  // tag as bad from FEDErrors the modules that have an error on 75% of the events
280  calibData_.fillMapFromTkMap(totalEvents, 0.75, stripDetIds_);
281 
282  for (const auto& [badId, fraction] : calibData_.fedErrorCounts) {
283  LogDebug("SiStripHitEfficiencyHarvester")
284  << __PRETTY_FUNCTION__ << " bad module from FEDError " << badId << "," << fraction << std::endl;
285  }
286 
287  for (auto det : stripDetIds_) {
288  auto layer = ::checkLayer(det, tTopo_.get());
289  const auto num = h_module_found->getValue(det);
290  const auto denom = h_module_total->getValue(det);
291  if (denom) {
292  // use only the "good" modules
293  if (stripQuality_->getBadApvs(det) == 0 && calibData_.checkFedError(det)) {
294  const auto eff = num / denom;
295  hEffInLayer[layer]->Fill(eff);
296  if (!autoIneffModTagging_) {
297  if ((denom >= nModsMin_) && (eff < threshold_)) {
298  // We have a bad module, put it in the list!
299  badModules[det] = eff;
300  tkMapBad.fillc(det, 255, 0, 0);
301  LOGPRINT << "Layer " << layer << " (" << ::layerName(layer, showRings_, nTEClayers_) << ") module "
302  << det.rawId() << " efficiency: " << eff << " , " << num << "/" << denom;
303  } else {
304  //Fill the bad list with empty results for every module
305  tkMapBad.fillc(det, 255, 255, 255);
306  }
307  if (eff < threshold_)
308  LOGPRINT << "Layer " << layer << " (" << ::layerName(layer, showRings_, nTEClayers_) << ") module "
309  << det.rawId() << " efficiency: " << eff << " , " << num << "/" << denom;
310 
311  if (denom < nModsMin_) {
312  LOGPRINT << "Layer " << layer << " (" << ::layerName(layer, showRings_, nTEClayers_) << ") module "
313  << det.rawId() << " is under occupancy at " << denom;
314  }
315 
316  if (doStoreOnTree_ && !isAtPCL_) {
317  t_DetId = det.rawId();
318  t_layer = layer;
319  t_found = num;
320  t_total = denom;
321  t_isTaggedIneff = false;
322  t_threshold = 0;
323  tree->Fill();
324  }
325  }
326 
327  //Put any module into the TKMap
328  tkMap.fill(det, 1. - eff);
329  tkMapEff.fill(det, eff);
330  tkMapNum.fill(det, num);
331  tkMapDen.fill(det, denom);
332 
333  layerTotal[layer] += denom;
334  layerFound[layer] += num;
335 
336  // for the summary
337  // Have to do the decoding for which side to go on (ugh)
338  if (layer <= bounds::k_LayersAtTOBEnd) {
341  } else if (layer > bounds::k_LayersAtTOBEnd && layer <= bounds::k_LayersAtTIDEnd) {
342  if (tTopo_->tidSide(det) == 1) {
345  } else if (tTopo_->tidSide(det) == 2) {
346  goodlayerfound[layer + 3] += num;
347  goodlayertotal[layer + 3] += denom;
348  }
349  } else if (layer > bounds::k_LayersAtTIDEnd && layer <= bounds::k_LayersAtTECEnd) {
350  if (tTopo_->tecSide(det) == 1) {
351  goodlayerfound[layer + 3] += num;
352  goodlayertotal[layer + 3] += denom;
353  } else if (tTopo_->tecSide(det) == 2) {
356  }
357  }
358  } // if the module is good!
359 
360  //Do the one where we don't exclude bad modules!
361  if (layer <= bounds::k_LayersAtTOBEnd) {
362  alllayerfound[layer] += num;
364  } else if (layer > bounds::k_LayersAtTOBEnd && layer <= bounds::k_LayersAtTIDEnd) {
365  if (tTopo_->tidSide(det) == 1) {
366  alllayerfound[layer] += num;
368  } else if (tTopo_->tidSide(det) == 2) {
369  alllayerfound[layer + 3] += num;
370  alllayertotal[layer + 3] += denom;
371  }
372  } else if (layer > bounds::k_LayersAtTIDEnd && layer <= bounds::k_LayersAtTECEnd) {
373  if (tTopo_->tecSide(det) == 1) {
374  alllayerfound[layer + 3] += num;
375  alllayertotal[layer + 3] += denom;
376  } else if (tTopo_->tecSide(det) == 2) {
379  }
380  }
381 
382  } // if denom
383  } // loop on DetIds
384 
385  if (autoIneffModTagging_) {
386  for (unsigned int i = 1; i <= k_LayersAtTECEnd; i++) {
387  //Compute threshold to use for each layer
388  hEffInLayer[i]->getTH1()->GetXaxis()->SetRange(
389  3, hEffInLayer[i]->getNbinsX() + 1); // Remove from the avg modules below 1%
390  const double layer_min_eff = hEffInLayer[i]->getMean() - std::max(2.5 * hEffInLayer[i]->getRMS(), threshold_);
391  LOGPRINT << "Layer " << i << " threshold for bad modules: <" << layer_min_eff
392  << " (layer mean: " << hEffInLayer[i]->getMean() << " rms: " << hEffInLayer[i]->getRMS() << ")";
393 
394  hEffInLayer[i]->getTH1()->GetXaxis()->SetRange(1, hEffInLayer[i]->getNbinsX() + 1);
395 
396  for (auto det : stripDetIds_) {
397  // use only the "good" modules
398  if (stripQuality_->getBadApvs(det) == 0 && calibData_.checkFedError(det)) {
399  const auto layer = ::checkLayer(det, tTopo_.get());
400  if (layer == i) {
401  const auto num = h_module_found->getValue(det);
402  const auto denom = h_module_total->getValue(det);
403  if (denom) {
404  assert(num <= denom); // can't have this happen
405  const auto eff = num / denom;
406  const auto eff_up = TEfficiency::Bayesian(denom, num, .99, 1, 1, true);
407 
408  if ((denom >= nModsMin_) && (eff_up < layer_min_eff)) {
409  //We have a bad module, put it in the list!
410  badModules[det] = eff;
411  tkMapBad.fillc(det, 255, 0, 0);
412  if (!isAtPCL_ && doStoreOnTree_) {
413  t_isTaggedIneff = true;
414  }
415  } else {
416  //Fill the bad list with empty results for every module
417  tkMapBad.fillc(det, 255, 255, 255);
418  if (!isAtPCL_ && doStoreOnTree_) {
419  t_isTaggedIneff = false;
420  }
421  }
422  if (eff_up < layer_min_eff + 0.08) {
423  // printing message also for modules sligthly above (8%) the limit
424  LOGPRINT << "Layer " << layer << " (" << ::layerName(layer, showRings_, nTEClayers_) << ") module "
425  << det.rawId() << " efficiency: " << eff << " , " << num << "/" << denom
426  << " , upper limit: " << eff_up;
427  }
428  if (denom < nModsMin_) {
429  LOGPRINT << "Layer " << layer << " (" << ::layerName(layer, showRings_, nTEClayers_) << ") module "
430  << det.rawId() << " layer " << layer << " is under occupancy at " << denom;
431  }
432 
433  if (!isAtPCL_ && doStoreOnTree_) {
434  t_DetId = det.rawId();
435  t_layer = layer;
436  t_found = num;
437  t_total = denom;
438  t_threshold = layer_min_eff;
439  tree->Fill();
440  } // if storing tree
441  } // if denom
442  } // layer = i
443  } // if there are no bad APVs
444  } // loop on detids
445  } // loop on layers
446  } // if auto tagging
447 
448  tkMap.save(true, 0, 0, "SiStripHitEffTKMap_NEW.png");
449  tkMapBad.save(true, 0, 0, "SiStripHitEffTKMapBad_NEW.png");
450  tkMapEff.save(true, tkMapMin_, 1., "SiStripHitEffTKMapEff_NEW.png");
451  tkMapNum.save(true, 0, 0, "SiStripHitEffTKMapNum_NEW.png");
452  tkMapDen.save(true, 0, 0, "SiStripHitEffTKMapDen_NEW.png");
453 
454  const auto detInfo =
456  SiStripQuality pQuality{detInfo};
457  //This is the list of the bad strips, use to mask out entire APVs
458  //Now simply go through the bad hit list and mask out things that
459  //are bad!
460  for (const auto it : badModules) {
461  const auto det = it.first;
462  std::vector<unsigned int> badStripList;
463  //We need to figure out how many strips are in this particular module
464  //To Mask correctly!
465  const auto nStrips = detInfo.getNumberOfApvsAndStripLength(det).first * sistrip::STRIPS_PER_APV;
466  LOGPRINT << "Number of strips module " << det << " is " << nStrips;
467  badStripList.push_back(pQuality.encode(0, nStrips, 0));
468  //Now compact into a single bad module
469  LOGPRINT << "ID1 should match list of modules above " << det;
470  pQuality.compact(det, badStripList);
471  pQuality.put(det, SiStripQuality::Range(badStripList.begin(), badStripList.end()));
472  }
473  pQuality.fillBadComponents();
474  if (doStoreOnDB_) {
475  if (totalHits > 0u) {
476  writeBadStripPayload(pQuality);
477  } else {
478  edm::LogPrint("SiStripHitEfficiencyHarvester")
479  << __PRETTY_FUNCTION__ << " There are no SiStrip hits for a valid measurement, skipping!";
480  }
481  } else {
482  edm::LogInfo("SiStripHitEfficiencyHarvester") << "Will not produce payload!";
483  }
484 
485  printTotalStatistics(layerFound, layerTotal); // statistics by layer and subdetector
486  //LOGPRINT << "\n-----------------\nNew IOV starting from run " << e.id().run() << " event " << e.id().event()
487  // << " lumiBlock " << e.luminosityBlock() << " time " << e.time().value() << "\n-----------------\n";
488  printAndWriteBadModules(pQuality, detInfo); // TODO
489 
490  // make summary plots
491  makeSummary(getter, booker);
492  makeSummaryVsVariable(getter, booker, projections::k_vs_LUMI);
493  makeSummaryVsVariable(getter, booker, projections::k_vs_PU);
494  makeSummaryVsVariable(getter, booker, projections::k_vs_BX);
495 }
496 
498  const std::array<long, bounds::k_END_OF_LAYERS>& layerFound,
499  const std::array<long, bounds::k_END_OF_LAYERS>& layerTotal) const {
500  //Calculate the statistics by layer
501  int totalfound = 0;
502  int totaltotal = 0;
503  double layereff;
504  int subdetfound[5] = {0, 0, 0, 0, 0};
505  int subdettotal[5] = {0, 0, 0, 0, 0};
506 
507  for (unsigned int i = 1; i <= bounds::k_LayersAtTECEnd; i++) {
508  layereff = double(layerFound[i]) / double(layerTotal[i]);
509  LOGPRINT << "Layer " << i << " (" << ::layerName(i, showRings_, nTEClayers_) << ") has total efficiency "
510  << layereff << " " << layerFound[i] << "/" << layerTotal[i];
511  totalfound += layerFound[i];
512  totaltotal += layerTotal[i];
513  if (i <= bounds::k_LayersAtTIBEnd) {
514  subdetfound[1] += layerFound[i];
515  subdettotal[1] += layerTotal[i];
516  }
517  if (i > bounds::k_LayersAtTIBEnd && i <= bounds::k_LayersAtTOBEnd) {
518  subdetfound[2] += layerFound[i];
519  subdettotal[2] += layerTotal[i];
520  }
521  if (i > bounds::k_LayersAtTOBEnd && i <= bounds::k_LayersAtTIDEnd) {
522  subdetfound[3] += layerFound[i];
523  subdettotal[3] += layerTotal[i];
524  }
525  if (i > bounds::k_LayersAtTIDEnd) {
526  subdetfound[4] += layerFound[i];
527  subdettotal[4] += layerTotal[i];
528  }
529  }
530 
531  LOGPRINT << "The total efficiency is " << double(totalfound) / double(totaltotal);
532  LOGPRINT << " TIB: " << double(subdetfound[1]) / subdettotal[1] << " " << subdetfound[1] << "/"
533  << subdettotal[1];
534  LOGPRINT << " TOB: " << double(subdetfound[2]) / subdettotal[2] << " " << subdetfound[2] << "/"
535  << subdettotal[2];
536  LOGPRINT << " TID: " << double(subdetfound[3]) / subdettotal[3] << " " << subdetfound[3] << "/"
537  << subdettotal[3];
538  LOGPRINT << " TEC: " << double(subdetfound[4]) / subdettotal[4] << " " << subdetfound[4] << "/"
539  << subdettotal[4];
540 }
541 
543  SiStripBadStrip pBadStrip{};
544  const auto pQdvBegin = quality.getDataVectorBegin();
545  for (auto rIt = quality.getRegistryVectorBegin(); rIt != quality.getRegistryVectorEnd(); ++rIt) {
546  const auto range = SiStripBadStrip::Range(pQdvBegin + rIt->ibegin, pQdvBegin + rIt->iend);
547  if (!pBadStrip.put(rIt->detid, range))
548  edm::LogError("SiStripHitEfficiencyHarvester") << "detid already exists in SiStripBadStrip";
549  }
551  if (poolDbService.isAvailable()) {
552  poolDbService->writeOneIOV(pBadStrip, poolDbService->currentTime(), record_);
553  } else {
554  throw cms::Exception("PoolDBService required");
555  }
556 }
557 
559  DQMStore::IBooker& booker,
560  bool doProfiles) const {
561  // use goodlayer_total/found and alllayer_total/found, collapse side and/or ring if needed
562  unsigned int nLayers{34}; // default
563  if (showRings_)
564  nLayers = 30;
565  if (!showEndcapSides_) {
566  if (!showRings_)
567  nLayers = 22;
568  else
569  nLayers = 20;
570  }
571 
572  // come back to the main folder and create a final efficiency folder
573  booker.setCurrentFolder(fmt::format("{}/EfficiencySummary", inputFolder_));
574  MonitorElement* found = booker.book1D("found", "found", nLayers + 1, 0, nLayers + 1);
575  MonitorElement* all = booker.book1D("all", "all", nLayers + 1, 0, nLayers + 1);
576  MonitorElement* found2 = booker.book1D("found2", "found", nLayers + 1, 0, nLayers + 1);
577  MonitorElement* all2 = booker.book1D("all2", "all2", nLayers + 1, 0, nLayers + 1);
578 
579  // first bin only to keep real data off the y axis so set to -1
580  found->setBinContent(0, -1);
581  all->setBinContent(0, 1);
582 
583  // new ROOT version: TGraph::Divide don't handle null or negative values
584  for (unsigned int i = 1; i < nLayers + 2; ++i) {
585  found->setBinContent(i, 1e-6);
586  all->setBinContent(i, 1);
587  found2->setBinContent(i, 1e-6);
588  all2->setBinContent(i, 1);
589  }
590 
591  TCanvas* c7 = new TCanvas("c7", " test ", 10, 10, 800, 600);
592  c7->SetFillColor(0);
593  c7->SetGrid();
594 
595  unsigned int nLayers_max = nLayers + 1; // barrel+endcap
596  if (!showEndcapSides_)
597  nLayers_max = 11; // barrel
598  for (unsigned int i = 1; i < nLayers_max; ++i) {
599  LOGPRINT << "Fill only good modules layer " << i << ": S = " << goodlayerfound[i]
600  << " B = " << goodlayertotal[i];
601  if (goodlayertotal[i] > 5) {
602  found->setBinContent(i, goodlayerfound[i]);
603  all->setBinContent(i, goodlayertotal[i]);
604  }
605 
606  LOGPRINT << "Filling all modules layer " << i << ": S = " << alllayerfound[i] << " B = " << alllayertotal[i];
607  if (alllayertotal[i] > 5) {
608  found2->setBinContent(i, alllayerfound[i]);
609  all2->setBinContent(i, alllayertotal[i]);
610  }
611  }
612 
613  // endcap - merging sides
614  if (!showEndcapSides_) {
615  for (unsigned int i = 11; i < 14; ++i) { // TID disks
616  LOGPRINT << "Fill only good modules layer " << i << ": S = " << goodlayerfound[i] + goodlayerfound[i + 3]
617  << " B = " << goodlayertotal[i] + goodlayertotal[i + 3];
618  if (goodlayertotal[i] + goodlayertotal[i + 3] > 5) {
619  found->setBinContent(i, goodlayerfound[i] + goodlayerfound[i + 3]);
620  all->setBinContent(i, goodlayertotal[i] + goodlayertotal[i + 3]);
621  }
622  LOGPRINT << "Filling all modules layer " << i << ": S = " << alllayerfound[i] + alllayerfound[i + 3]
623  << " B = " << alllayertotal[i] + alllayertotal[i + 3];
624  if (alllayertotal[i] + alllayertotal[i + 3] > 5) {
625  found2->setBinContent(i, alllayerfound[i] + alllayerfound[i + 3]);
626  all2->setBinContent(i, alllayertotal[i] + alllayertotal[i + 3]);
627  }
628  }
629  for (unsigned int i = 17; i < 17 + nTEClayers_; ++i) { // TEC disks
630  LOGPRINT << "Fill only good modules layer " << i - 3
631  << ": S = " << goodlayerfound[i] + goodlayerfound[i + nTEClayers_]
632  << " B = " << goodlayertotal[i] + goodlayertotal[i + nTEClayers_];
633  if (goodlayertotal[i] + goodlayertotal[i + nTEClayers_] > 5) {
634  found->setBinContent(i - 3, goodlayerfound[i] + goodlayerfound[i + nTEClayers_]);
635  all->setBinContent(i - 3, goodlayertotal[i] + goodlayertotal[i + nTEClayers_]);
636  }
637  LOGPRINT << "Filling all modules layer " << i - 3
638  << ": S = " << alllayerfound[i] + alllayerfound[i + nTEClayers_]
639  << " B = " << alllayertotal[i] + alllayertotal[i + nTEClayers_];
640  if (alllayertotal[i] + alllayertotal[i + nTEClayers_] > 5) {
643  }
644  }
645  }
646 
647  found->getTH1F()->Sumw2();
648  all->getTH1F()->Sumw2();
649 
650  found2->getTH1F()->Sumw2();
651  all2->getTH1F()->Sumw2();
652 
653  MonitorElement* h_eff_all =
654  booker.book1D("eff_all", "Strip hit efficiency for all modules", nLayers + 1, 0, nLayers + 1);
655  MonitorElement* h_eff_good =
656  booker.book1D("eff_good", "Strip hit efficiency for good modules", nLayers + 1, 0, nLayers + 1);
657 
658  if (doProfiles) {
659  // now do the profile
660  TProfile* profile_all = ::computeEff(found2->getTH1F(), all2->getTH1F(), "all");
661  profile_all->SetMinimum(tkMapMin_);
662  profile_all->SetTitle("Strip hit efficiency for all modules");
663  booker.bookProfile(profile_all->GetName(), profile_all);
664 
665  TProfile* profile_good = ::computeEff(found->getTH1F(), all->getTH1F(), "good");
666  profile_good->SetMinimum(tkMapMin_);
667  profile_good->SetTitle("Strip hit efficiency for good modules");
668  booker.bookProfile(profile_good->GetName(), profile_good);
669 
670  // clean the house
671  delete profile_all;
672  delete profile_good;
673  }
674 
675  for (int i = 1; i < found->getNbinsX(); i++) {
676  const auto& den_all = all2->getBinContent(i);
677  const auto& num_all = found2->getBinContent(i);
678  const auto& den_good = all->getBinContent(i);
679  const auto& num_good = found->getBinContent(i);
680 
681  // fill all modules efficiency
682  if (den_all > 0.) {
683  // naive binomial errors
684  //float eff_all = num_all / den_all;
685  //float err_eff_all = (eff_all * (1 - eff_all)) / den_all;
686 
687  // use Clopper-Pearson errors
688  const auto& effPair_all = ::computeCPEfficiency(num_all, den_all);
689  h_eff_all->setBinContent(i, effPair_all.value());
690  h_eff_all->setBinError(i, effPair_all.error());
691  }
692 
693  // fill good modules efficiency
694  if (den_good > 0.) {
695  // naive binomial errors
696  //float eff_good = num_good / den_good;
697  //float err_eff_good = (eff_good * (1 - eff_good)) / den_good;
698 
699  // use Clopper-Pearson errors
700  const auto& effPair_good = ::computeCPEfficiency(num_good, den_good);
701  h_eff_good->setBinContent(i, effPair_good.value());
702  h_eff_good->setBinError(i, effPair_good.error());
703  }
704  }
705 
706  h_eff_all->getTH1F()->SetMinimum(effPlotMin_);
707  h_eff_good->getTH1F()->SetMinimum(effPlotMin_);
708 
709  // set the histogram bin labels
710  this->setEffBinLabels(h_eff_all->getTH1F(), h_eff_good->getTH1F(), nLayers);
711 
712  if (!isAtPCL_) {
713  // if TFileService is not avaible, just go on
715  if (!fs.isAvailable()) {
716  throw cms::Exception("BadConfig") << "TFileService unavailable: "
717  << "please add it to config file";
718  }
719 
720  TGraphAsymmErrors* gr = (*fs).make<TGraphAsymmErrors>(nLayers + 1);
721  gr->SetName("eff_good");
722  gr->BayesDivide(found->getTH1F(), all->getTH1F());
723 
724  TGraphAsymmErrors* gr2 = (*fs).make<TGraphAsymmErrors>(nLayers + 1);
725  gr2->SetName("eff_all");
726  gr2->BayesDivide(found2->getTH1F(), all2->getTH1F());
727 
728  for (unsigned int j = 0; j < nLayers + 1; j++) {
729  gr->SetPointError(j, 0., 0., gr->GetErrorYlow(j), gr->GetErrorYhigh(j));
730  gr2->SetPointError(j, 0., 0., gr2->GetErrorYlow(j), gr2->GetErrorYhigh(j));
731  }
732 
733  this->setEffBinLabels(gr, gr2, nLayers);
734 
735  gr->GetXaxis()->SetLimits(0, nLayers);
736  gr->SetMarkerColor(2);
737  gr->SetMarkerSize(1.2);
738  gr->SetLineColor(2);
739  gr->SetLineWidth(4);
740  gr->SetMarkerStyle(20);
741  gr->SetMinimum(effPlotMin_);
742  gr->SetMaximum(1.001);
743  gr->GetYaxis()->SetTitle("Efficiency");
744  gStyle->SetTitleFillColor(0);
745  gStyle->SetTitleBorderSize(0);
746  gr->SetTitle("SiStripHitEfficiency by Layer");
747 
748  gr2->GetXaxis()->SetLimits(0, nLayers);
749  gr2->SetMarkerColor(1);
750  gr2->SetMarkerSize(1.2);
751  gr2->SetLineColor(1);
752  gr2->SetLineWidth(4);
753  gr2->SetMarkerStyle(21);
754  gr2->SetMinimum(effPlotMin_);
755  gr2->SetMaximum(1.001);
756  gr2->GetYaxis()->SetTitle("Efficiency");
757  gr2->SetTitle("SiStripHitEfficiency by Layer");
758 
759  gr->Draw("AP");
760  gr->GetXaxis()->SetNdivisions(36);
761 
762  c7->cd();
763  TPad* overlay = new TPad("overlay", "", 0, 0, 1, 1);
764  overlay->SetFillStyle(4000);
765  overlay->SetFillColor(0);
766  overlay->SetFrameFillStyle(4000);
767  overlay->Draw("same");
768  overlay->cd();
770  gr2->Draw("AP");
771 
772  TLegend* leg = new TLegend(0.70, 0.27, 0.88, 0.40);
773  leg->AddEntry(gr, "Good Modules", "p");
775  leg->AddEntry(gr2, "All Modules", "p");
776  leg->SetTextSize(0.020);
777  leg->SetFillColor(0);
778  leg->Draw("same");
779 
780  c7->SaveAs("Summary.png");
781  c7->SaveAs("Summary.root");
782  } // if it's not run at PCL
783 }
784 
785 template <typename T>
786 void SiStripHitEfficiencyHarvester::setEffBinLabels(const T gr, const T gr2, const unsigned int nLayers) const {
787  LogDebug("SiStripHitEfficiencyHarvester")
788  << "nLayers = " << nLayers << " number of bins, gr1: " << gr->GetXaxis()->GetNbins()
789  << " number of bins, gr2: " << gr2->GetXaxis()->GetNbins() << " showRings: " << showRings_
790  << " showEndcapSides: " << showEndcapSides_ << " type of object is "
791  << boost::typeindex::type_id<T>().pretty_name();
792 
793  for (unsigned int k = 1; k < nLayers + 1; k++) {
794  std::string label{};
795  if (showEndcapSides_)
796  label = ::layerSideName(k, showRings_, nTEClayers_);
797  else
798  label = ::layerName(k, showRings_, nTEClayers_);
799  if (!showTOB6TEC9_) {
800  if (k == 10)
801  label = "";
802  if (!showRings_ && k == nLayers)
803  label = "";
804  if (!showRings_ && showEndcapSides_ && k == 25)
805  label = "";
806  }
807 
808  int bin{-1};
809  if constexpr (std::is_same_v<T, TGraphAsymmErrors*>) {
810  edm::LogInfo("SiStripHitEfficiencyHarvester")
811  << "class name: " << gr->ClassName() << " expected TGraphAsymErrors" << std::endl;
812  if (!showRings_) {
813  if (showEndcapSides_) {
814  bin = (((k + 1) * 100 + 2) / (nLayers)-4);
815  } else {
816  bin = ((k + 1) * 100 / (nLayers)-6);
817  }
818  } else {
819  if (showEndcapSides_) {
820  bin = ((k + 1) * 100 / (nLayers)-4);
821  } else {
822  bin = ((k + 1) * 100 / (nLayers)-7);
823  }
824  }
825  } else {
826  edm::LogInfo("SiStripHitEfficiencyHarvester")
827  << "class name: " << gr->ClassName() << " expected TH1F" << std::endl;
828  bin = k;
829  }
830  gr->GetXaxis()->SetBinLabel(bin, label.data());
831  gr2->GetXaxis()->SetBinLabel(bin, label.data());
832  }
833 }
834 
836  DQMStore::IBooker& booker,
837  ::projections theProj) const {
838  std::vector<MonitorElement*> effVsVariable;
839  effVsVariable.reserve(showRings_ ? 20 : 22);
840 
841  const auto& folderString = ::projFolder[theProj];
842  const auto& foundHistoString = ::projFoundHisto[theProj];
843  const auto& totalHistoString = ::projTotalHisto[theProj];
844  const auto& titleString = ::projTitle[theProj];
845  const auto& titleXString = ::projXtitle[theProj];
846 
847  LogDebug("SiStripHitEfficiencyHarvester")
848  << " inside" << __PRETTY_FUNCTION__ << " from " << ::projFolder[theProj] << " " << __LINE__ << std::endl;
849 
850  for (unsigned int iLayer = 1; iLayer != (showRings_ ? 20 : 22); ++iLayer) {
851  LogDebug("SiStripHitEfficiencyHarvester")
852  << "iLayer " << iLayer << " " << fmt::format("{}/{}/{}{}", inputFolder_, folderString, foundHistoString, iLayer)
853  << std::endl;
854 
855  const auto lyrName = ::layerName(iLayer, showRings_, nTEClayers_);
856  auto hfound = getter.get(fmt::format("{}/{}/{}{}", inputFolder_, folderString, foundHistoString, iLayer));
857  auto htotal = getter.get(fmt::format("{}/{}/{}{}", inputFolder_, folderString, totalHistoString, iLayer));
858 
859  if (hfound == nullptr or htotal == nullptr) {
860  if (hfound == nullptr)
861  edm::LogError("SiStripHitEfficiencyHarvester")
862  << fmt::format("{}/{}/{}{}", inputFolder_, folderString, foundHistoString, iLayer) << " was not found!";
863  if (htotal == nullptr)
864  edm::LogError("SiStripHitEfficiencyHarvester")
865  << fmt::format("{}/{}/{}{}", inputFolder_, folderString, totalHistoString, iLayer) << " was not found!";
866  // no input histograms -> continue in the loop
867  continue;
868  }
869 
870  // in order to display correct errors when taking the ratio
871  if (!hfound->getTH1F()->GetSumw2())
872  hfound->getTH1F()->Sumw2();
873  if (!htotal->getTH1F()->GetSumw2())
874  htotal->getTH1F()->Sumw2();
875 
876  // prevent dividing by 0
877  for (int i = 0; i != hfound->getNbinsX() + 1; ++i) {
878  if (hfound->getBinContent(i) == 0)
879  hfound->setBinContent(i, 1e-6);
880  if (htotal->getBinContent(i) == 0)
881  htotal->setBinContent(i, 1);
882  }
883  LogDebug("SiStripHitEfficiencyHarvester") << "Total hits for layer " << iLayer << " (" << folderString
884  << "): " << htotal->getEntries() << ", found " << hfound->getEntries();
885 
886  booker.setCurrentFolder(fmt::format("{}/EfficiencySummary{}", inputFolder_, folderString));
887  effVsVariable[iLayer] = booker.book1D(
888  fmt::sprintf("eff%sLayer%s", folderString, lyrName),
889  fmt::sprintf("Efficiency vs %s for layer %s;%s;SiStrip Hit efficiency", titleString, lyrName, titleXString),
890  hfound->getNbinsX(),
891  hfound->getAxisMin(),
892  hfound->getAxisMax());
893 
894  LogDebug("SiStripHitEfficiencyHarvester")
895  << " bin 0 " << hfound->getAxisMin() << " bin last: " << hfound->getAxisMax() << std::endl;
896 
897  for (int i = 0; i != hfound->getNbinsX() + 1; ++i) {
898  const auto& den = htotal->getBinContent(i);
899  const auto& num = hfound->getBinContent(i);
900 
901  // fill all modules efficiency
902  if (den > 0.) {
903  const auto& effPair = ::computeCPEfficiency(num, den);
904  effVsVariable[iLayer]->setBinContent(i, effPair.value());
905  effVsVariable[iLayer]->setBinError(i, effPair.error());
906 
907  LogDebug("SiStripHitEfficiencyHarvester")
908  << __PRETTY_FUNCTION__ << " " << lyrName << " bin:" << i << " err:" << effPair.error() << std::endl;
909  }
910  }
911 
912  // graphics adjustment
913  effVsVariable[iLayer]->getTH1F()->SetMinimum(tkMapMin_);
914 
915  // now do the profile
916  TProfile* profile = ::computeEff(hfound->getTH1F(), htotal->getTH1F(), lyrName);
917  TString title =
918  fmt::sprintf("Efficiency vs %s for layer %s;%s;SiStrip Hit efficiency", titleString, lyrName, titleXString);
919  profile->SetMinimum(tkMapMin_);
920 
921  profile->SetTitle(title.Data());
922  booker.bookProfile(profile->GetName(), profile);
923 
924  delete profile;
925  } // loop on layers
926 }
927 
928 namespace {
929  void setBadComponents(int i,
930  int comp,
932  std::stringstream ssV[4][19],
933  int nBad[4][19][4],
934  int nAPV) {
935  ssV[i][comp] << "\n\t\t " << bc.detid << " \t " << bc.BadModule << " \t " << ((bc.BadFibers) & 0x1) << " ";
936  if (nAPV == 4)
937  ssV[i][comp] << "x " << ((bc.BadFibers >> 1) & 0x1);
938 
939  if (nAPV == 6)
940  ssV[i][comp] << ((bc.BadFibers >> 1) & 0x1) << " " << ((bc.BadFibers >> 2) & 0x1);
941  ssV[i][comp] << " \t " << ((bc.BadApvs) & 0x1) << " " << ((bc.BadApvs >> 1) & 0x1) << " ";
942  if (nAPV == 4)
943  ssV[i][comp] << "x x " << ((bc.BadApvs >> 2) & 0x1) << " " << ((bc.BadApvs >> 3) & 0x1);
944  if (nAPV == 6)
945  ssV[i][comp] << ((bc.BadApvs >> 2) & 0x1) << " " << ((bc.BadApvs >> 3) & 0x1) << " " << ((bc.BadApvs >> 4) & 0x1)
946  << " " << ((bc.BadApvs >> 5) & 0x1) << " ";
947 
948  if (bc.BadApvs) {
949  nBad[i][0][2] += ((bc.BadApvs >> 5) & 0x1) + ((bc.BadApvs >> 4) & 0x1) + ((bc.BadApvs >> 3) & 0x1) +
950  ((bc.BadApvs >> 2) & 0x1) + ((bc.BadApvs >> 1) & 0x1) + ((bc.BadApvs) & 0x1);
951  nBad[i][comp][2] += ((bc.BadApvs >> 5) & 0x1) + ((bc.BadApvs >> 4) & 0x1) + ((bc.BadApvs >> 3) & 0x1) +
952  ((bc.BadApvs >> 2) & 0x1) + ((bc.BadApvs >> 1) & 0x1) + ((bc.BadApvs) & 0x1);
953  }
954  if (bc.BadFibers) {
955  nBad[i][0][1] += ((bc.BadFibers >> 2) & 0x1) + ((bc.BadFibers >> 1) & 0x1) + ((bc.BadFibers) & 0x1);
956  nBad[i][comp][1] += ((bc.BadFibers >> 2) & 0x1) + ((bc.BadFibers >> 1) & 0x1) + ((bc.BadFibers) & 0x1);
957  }
958  if (bc.BadModule) {
959  nBad[i][0][0]++;
960  nBad[i][comp][0]++;
961  }
962  }
963 } // namespace
964 
966  const SiStripDetInfo& detInfo) const {
968  //try to write out what's in the quality record
970  int nTkBadComp[4]; //k: 0=BadModule, 1=BadFiber, 2=BadApv, 3=BadStrips
971  int nBadComp[4][19][4];
972  //legend: nBadComp[i][j][k]= SubSystem i, layer/disk/wheel j, BadModule/Fiber/Apv k
973  // i: 0=TIB, 1=TID, 2=TOB, 3=TEC
974  // k: 0=BadModule, 1=BadFiber, 2=BadApv, 3=BadStrips
975  std::stringstream ssV[4][19];
976 
977  for (int i = 0; i < 4; ++i) {
978  nTkBadComp[i] = 0;
979  for (int j = 0; j < 19; ++j) {
980  ssV[i][j].str("");
981  for (int k = 0; k < 4; ++k)
982  nBadComp[i][j][k] = 0;
983  }
984  }
985 
986  for (const auto& bc : quality.getBadComponentList()) {
987  // Full Tk
988  if (bc.BadModule)
989  nTkBadComp[0]++;
990  if (bc.BadFibers)
991  nTkBadComp[1] += ((bc.BadFibers >> 2) & 0x1) + ((bc.BadFibers >> 1) & 0x1) + ((bc.BadFibers) & 0x1);
992  if (bc.BadApvs)
993  nTkBadComp[2] += ((bc.BadApvs >> 5) & 0x1) + ((bc.BadApvs >> 4) & 0x1) + ((bc.BadApvs >> 3) & 0x1) +
994  ((bc.BadApvs >> 2) & 0x1) + ((bc.BadApvs >> 1) & 0x1) + ((bc.BadApvs) & 0x1);
995  // single subsystem
996  DetId det(bc.detid);
997  if ((det.subdetId() >= SiStripSubdetector::TIB) && (det.subdetId() <= SiStripSubdetector::TEC)) {
998  const auto nAPV = detInfo.getNumberOfApvsAndStripLength(det).first;
999  switch (det.subdetId()) {
1001  setBadComponents(0, tTopo_->tibLayer(det), bc, ssV, nBadComp, nAPV);
1002  break;
1004  setBadComponents(1,
1005  (tTopo_->tidSide(det) == 2 ? tTopo_->tidWheel(det) : tTopo_->tidWheel(det) + 3),
1006  bc,
1007  ssV,
1008  nBadComp,
1009  nAPV);
1010  break;
1012  setBadComponents(2, tTopo_->tobLayer(det), bc, ssV, nBadComp, nAPV);
1013  break;
1015  setBadComponents(3,
1016  (tTopo_->tecSide(det) == 2 ? tTopo_->tecWheel(det) : tTopo_->tecWheel(det) + 9),
1017  bc,
1018  ssV,
1019  nBadComp,
1020  nAPV);
1021  break;
1022  default:
1023  break;
1024  }
1025  }
1026  }
1027  // single strip info
1028  for (auto rp = quality.getRegistryVectorBegin(); rp != quality.getRegistryVectorEnd(); ++rp) {
1029  DetId det{rp->detid};
1030  int subdet = -999;
1031  int component = -999;
1032  switch (det.subdetId()) {
1034  subdet = 0;
1035  component = tTopo_->tibLayer(det);
1036  break;
1038  subdet = 1;
1039  component = tTopo_->tidSide(det) == 2 ? tTopo_->tidWheel(det) : tTopo_->tidWheel(det) + 3;
1040  break;
1042  subdet = 2;
1043  component = tTopo_->tobLayer(det);
1044  break;
1046  subdet = 3;
1047  component = tTopo_->tecSide(det) == 2 ? tTopo_->tecWheel(det) : tTopo_->tecWheel(det) + 9;
1048  break;
1049  default:
1050  break;
1051  }
1052 
1053  const auto pQdvBegin = quality.getDataVectorBegin();
1054  const auto sqrange = SiStripQuality::Range(pQdvBegin + rp->ibegin, pQdvBegin + rp->iend);
1055  float percentage = 0;
1056  for (int it = 0; it < sqrange.second - sqrange.first; it++) {
1057  unsigned int range = quality.decode(*(sqrange.first + it)).range;
1058  nTkBadComp[3] += range;
1059  nBadComp[subdet][0][3] += range;
1060  nBadComp[subdet][component][3] += range;
1061  percentage += range;
1062  }
1063  if (percentage != 0)
1064  percentage /= (sistrip::STRIPS_PER_APV * detInfo.getNumberOfApvsAndStripLength(det).first);
1065  if (percentage > 1)
1066  edm::LogError("SiStripHitEfficiencyHarvester") << "PROBLEM detid " << det.rawId() << " value " << percentage;
1067  }
1068 
1069  // printout
1070  std::ostringstream ss;
1071  ss << "\n-----------------\nGlobal Info\n-----------------";
1072  ss << "\nBadComp \t Modules \tFibers "
1073  "\tApvs\tStrips\n----------------------------------------------------------------";
1074  ss << "\nTracker:\t\t" << nTkBadComp[0] << "\t" << nTkBadComp[1] << "\t" << nTkBadComp[2] << "\t" << nTkBadComp[3];
1075  ss << "\nTIB:\t\t\t" << nBadComp[0][0][0] << "\t" << nBadComp[0][0][1] << "\t" << nBadComp[0][0][2] << "\t"
1076  << nBadComp[0][0][3];
1077  ss << "\nTID:\t\t\t" << nBadComp[1][0][0] << "\t" << nBadComp[1][0][1] << "\t" << nBadComp[1][0][2] << "\t"
1078  << nBadComp[1][0][3];
1079  ss << "\nTOB:\t\t\t" << nBadComp[2][0][0] << "\t" << nBadComp[2][0][1] << "\t" << nBadComp[2][0][2] << "\t"
1080  << nBadComp[2][0][3];
1081  ss << "\nTEC:\t\t\t" << nBadComp[3][0][0] << "\t" << nBadComp[3][0][1] << "\t" << nBadComp[3][0][2] << "\t"
1082  << nBadComp[3][0][3];
1083  ss << "\n";
1084 
1085  for (int i = 1; i < 5; ++i)
1086  ss << "\nTIB Layer " << i << " :\t\t" << nBadComp[0][i][0] << "\t" << nBadComp[0][i][1] << "\t" << nBadComp[0][i][2]
1087  << "\t" << nBadComp[0][i][3];
1088  ss << "\n";
1089  for (int i = 1; i < 4; ++i)
1090  ss << "\nTID+ Disk " << i << " :\t\t" << nBadComp[1][i][0] << "\t" << nBadComp[1][i][1] << "\t" << nBadComp[1][i][2]
1091  << "\t" << nBadComp[1][i][3];
1092  for (int i = 4; i < 7; ++i)
1093  ss << "\nTID- Disk " << i - 3 << " :\t\t" << nBadComp[1][i][0] << "\t" << nBadComp[1][i][1] << "\t"
1094  << nBadComp[1][i][2] << "\t" << nBadComp[1][i][3];
1095  ss << "\n";
1096  for (int i = 1; i < 7; ++i)
1097  ss << "\nTOB Layer " << i << " :\t\t" << nBadComp[2][i][0] << "\t" << nBadComp[2][i][1] << "\t" << nBadComp[2][i][2]
1098  << "\t" << nBadComp[2][i][3];
1099  ss << "\n";
1100  for (int i = 1; i < 10; ++i)
1101  ss << "\nTEC+ Disk " << i << " :\t\t" << nBadComp[3][i][0] << "\t" << nBadComp[3][i][1] << "\t" << nBadComp[3][i][2]
1102  << "\t" << nBadComp[3][i][3];
1103  for (int i = 10; i < 19; ++i)
1104  ss << "\nTEC- Disk " << i - 9 << " :\t\t" << nBadComp[3][i][0] << "\t" << nBadComp[3][i][1] << "\t"
1105  << nBadComp[3][i][2] << "\t" << nBadComp[3][i][3];
1106  ss << "\n";
1107 
1108  ss << "\n----------------------------------------------------------------\n\t\t Detid \tModules Fibers "
1109  "Apvs\n----------------------------------------------------------------";
1110  for (int i = 1; i < 5; ++i)
1111  ss << "\nTIB Layer " << i << " :" << ssV[0][i].str();
1112  ss << "\n";
1113  for (int i = 1; i < 4; ++i)
1114  ss << "\nTID+ Disk " << i << " :" << ssV[1][i].str();
1115  for (int i = 4; i < 7; ++i)
1116  ss << "\nTID- Disk " << i - 3 << " :" << ssV[1][i].str();
1117  ss << "\n";
1118  for (int i = 1; i < 7; ++i)
1119  ss << "\nTOB Layer " << i << " :" << ssV[2][i].str();
1120  ss << "\n";
1121  for (int i = 1; i < 10; ++i)
1122  ss << "\nTEC+ Disk " << i << " :" << ssV[3][i].str();
1123  for (int i = 10; i < 19; ++i)
1124  ss << "\nTEC- Disk " << i - 9 << " :" << ssV[3][i].str();
1125 
1126  LOGPRINT << ss.str();
1127 
1128  // store also bad modules in log file
1129  std::ofstream badModules;
1130  badModules.open("BadModules_NEW.log");
1131  badModules << "\n----------------------------------------------------------------\n\t\t Detid \tModules Fibers "
1132  "Apvs\n----------------------------------------------------------------";
1133  for (int i = 1; i < 5; ++i)
1134  badModules << "\nTIB Layer " << i << " :" << ssV[0][i].str();
1135  badModules << "\n";
1136  for (int i = 1; i < 4; ++i)
1137  badModules << "\nTID+ Disk " << i << " :" << ssV[1][i].str();
1138  for (int i = 4; i < 7; ++i)
1139  badModules << "\nTID- Disk " << i - 3 << " :" << ssV[1][i].str();
1140  badModules << "\n";
1141  for (int i = 1; i < 7; ++i)
1142  badModules << "\nTOB Layer " << i << " :" << ssV[2][i].str();
1143  badModules << "\n";
1144  for (int i = 1; i < 10; ++i)
1145  badModules << "\nTEC+ Disk " << i << " :" << ssV[3][i].str();
1146  for (int i = 10; i < 19; ++i)
1147  badModules << "\nTEC- Disk " << i - 9 << " :" << ssV[3][i].str();
1148  badModules.close();
1149 }
1150 
1153  desc.add<std::string>("inputFolder", "AlCaReco/SiStripHitEfficiency");
1154  desc.add<bool>("isAtPCL", false);
1155  desc.add<bool>("doStoreOnDB", false);
1156  desc.add<std::string>("Record", "SiStripBadStrip");
1157  desc.add<double>("Threshold", 0.1);
1158  desc.add<std::string>("Title", "Hit Efficiency");
1159  desc.add<int>("nModsMin", 5);
1160  desc.addUntracked<bool>("doStoreOnTree", false);
1161  desc.addUntracked<bool>("AutoIneffModTagging", false);
1162  desc.addUntracked<double>("TkMapMin", 0.9);
1163  desc.addUntracked<double>("EffPlotMin", 0.9);
1164  desc.addUntracked<bool>("ShowRings", false);
1165  desc.addUntracked<bool>("ShowEndcapSides", true);
1166  desc.addUntracked<bool>("ShowTOB6TEC9", false);
1167  desc.addUntracked<bool>("ShowOnlyGoodModules", false);
1168  descriptions.addWithDefaultLabel(desc);
1169 }
1170 
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
void setEffBinLabels(const T gr, const T gr2, const unsigned int nLayers) const
void makeSummary(DQMStore::IGetter &getter, DQMStore::IBooker &booker, bool doProfiles=false) const
int goodlayerfound[bounds::k_END_OF_LAYS_AND_RINGS]
def all(container)
workaround iterator generators for ROOT classes
Definition: cmstools.py:25
int goodlayertotal[bounds::k_END_OF_LAYS_AND_RINGS]
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken_
std::unique_ptr< TrackerTopology > tTopo_
void endRun(edm::Run const &, edm::EventSetup const &) override
int alllayertotal[bounds::k_END_OF_LAYS_AND_RINGS]
void printAndWriteBadModules(const SiStripQuality &quality, const SiStripDetInfo &detInfo) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Log< level::Error, false > LogError
std::unordered_map< uint32_t, int > fedErrorCounts
assert(be >=bs)
const edm::ESGetToken< SiStripQuality, SiStripQualityRcd > stripQualityToken_
nStrips
1.2 is to make the matching window safely the two nearest strips 0.35 is the size of an ME0 chamber i...
std::unique_ptr< TkHistoMap > FEDErrorOccupancy
constexpr std::array< uint8_t, layerIndexSize< TrackerTraits > > layer
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > tkGeomToken_
char const * label
string quality
def overlay(hists, ytitle, header, addon)
Definition: compare.py:122
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:399
const bool checkFedError(const DetId det)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void printTotalStatistics(const std::array< long, bounds::k_END_OF_LAYERS > &layerFound, const std::array< long, bounds::k_END_OF_LAYERS > &layerTotal) const
unsigned int countTotalHits(const std::vector< MonitorElement *> &maps)
void writeBadStripPayload(const SiStripQuality &quality) const
Hash writeOneIOV(const T &payload, Time_t time, const std::string &recordName)
Transition
Definition: Transition.h:12
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
SiStripDetInfo read(std::string filePath)
Log< level::Warning, true > LogPrint
SiStripHitEfficiencyHarvester(const edm::ParameterSet &)
Log< level::Info, false > LogInfo
Definition: DetId.h:17
void setBadComponents(int i, int component, const SiStripQuality::BadComponent &BC, int NBadComponent[4][19][4])
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override
void fillMapFromTkMap(const int nevents, const float threshold, const std::vector< DetId > &stripDetIds)
const std::pair< unsigned short, double > getNumberOfApvsAndStripLength(uint32_t detId) const
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
Constants and enumerated types for FED/FEC systems.
virtual TH1F * getTH1F() const
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:712
~SiStripHitEfficiencyHarvester() override=default
HLT enums.
static const uint16_t STRIPS_PER_APV
std::pair< ContainerIterator, ContainerIterator > Range
std::unique_ptr< SiStripQuality > stripQuality_
int alllayerfound[bounds::k_END_OF_LAYS_AND_RINGS]
static constexpr char const *const kDefaultFile
bool isAvailable() const
Definition: Service.h:40
virtual void setBinError(int binx, double error)
set uncertainty on content of bin (1-D)
Definition: tree.py:1
void makeSummaryVsVariable(DQMStore::IGetter &getter, DQMStore::IBooker &booker, ::projections theProj) const
const edm::ESGetToken< TkDetMap, TrackerTopologyRcd > tkDetMapToken_
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
bool checkMapsValidity(const std::vector< MonitorElement *> &maps, const std::string &type) const
#define str(s)
long double T
Definition: Run.h:45
#define LogDebug(id)
virtual double getBinContent(int binx) const
get content of bin (1-D)
unsigned transform(const HcalDetId &id, unsigned transformCode)