CMS 3D CMS Logo

SiPixelPhase1Summary.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: SiPixelPhase1Summary
4 // Class: SiPixelPhase1Summary
5 //
13 //
14 // Original Author: Duncan Leggat
15 // Created: 5th December 2016
16 //
17 //
19 // Framework
23 // DQM Framework
26 // Geometry
32 // DataFormats
39 //
40 #include <string>
41 #include <cstdlib>
42 #include <iostream>
43 #include <fstream>
44 #include <sstream>
45 
46 using namespace std;
47 using namespace edm;
48 
50  : DQMEDHarvester(iConfig), conf_(iConfig), firstLumi(true) {
51  LogInfo("PixelDQM") << "SiPixelPhase1Summary::SiPixelPhase1Summary: Got DQM BackEnd interface" << endl;
52  topFolderName_ = conf_.getParameter<std::string>("TopFolderName");
53  runOnEndLumi_ = conf_.getParameter<bool>("RunOnEndLumi");
54  runOnEndJob_ = conf_.getParameter<bool>("RunOnEndJob");
55 
56  std::vector<edm::ParameterSet> mapPSets = conf_.getParameter<std::vector<edm::ParameterSet> >("SummaryMaps");
57 
58  //Go through the configuration file and add in
59  for (auto const& mapPSet : mapPSets) {
60  summaryPlotName_[mapPSet.getParameter<std::string>("MapName")] = mapPSet.getParameter<std::string>("MapHist");
61  }
62  deadRocThresholds_ = conf_.getParameter<std::vector<double> >("DeadROCErrorThreshold");
63  deadRocWarnThresholds_ = conf_.getParameter<std::vector<double> >("DeadROCWarningThreshold");
64 }
65 
67  // do anything here that needs to be done at desctruction time
68  // (e.g. close files, deallocate resources etc.)
69  LogInfo("PixelDQM") << "SiPixelPhase1Summary::~SiPixelPhase1Summary: Destructor" << endl;
70 }
71 
73 
75  DQMStore::IGetter& iGetter,
76  const edm::LuminosityBlock& lumiSeg,
77  edm::EventSetup const& c) {
78  if (firstLumi) {
79  bookSummaries(iBooker);
80  bookTrendPlots(iBooker);
81  firstLumi = false;
82  }
83 
84  if (runOnEndLumi_) {
85  int lumiSec = lumiSeg.id().luminosityBlock();
86  fillTrendPlots(iBooker, iGetter, lumiSec);
87  fillSummaries(iBooker, iGetter);
88  }
89 
90  // iBooker.cd();
91 }
92 
93 //------------------------------------------------------------------
94 // Method called for every event
95 //------------------------------------------------------------------
97  if (firstLumi) { //Book the plots in the (maybe possible?) case that they aren't booked in the dqmEndLuminosityBlock method
98  bookSummaries(iBooker);
99  bookTrendPlots(iBooker);
100  firstLumi = false;
101  }
102  if (runOnEndJob_) {
103  if (!runOnEndLumi_)
105  iBooker,
106  iGetter); //If we're filling these plots at the end lumi step, it doesn't really make sense to also do them at the end job
107  fillSummaries(iBooker, iGetter);
108  }
109 }
110 
111 //------------------------------------------------------------------
112 // Used to book the summary plots
113 //------------------------------------------------------------------
115  iBooker.cd();
116 
117  std::vector<std::string> xAxisLabels_ = {"BMO",
118  "BMI",
119  "BPO ",
120  "BPI",
121  "HCMO_1",
122  "HCMO_2",
123  "HCMI_1",
124  "HCMI_2",
125  "HCPO_1",
126  "HCPO_2",
127  "HCPI_1",
128  "HCPI_2"}; // why not having a global variable !?!?!?!
129  std::vector<std::string> yAxisLabels_ = {
130  "1",
131  "2",
132  "3",
133  "4"}; // why not having a global variable ?!?!?!!? - I originally did, but was told not to by David Lange!
134 
135  iBooker.setCurrentFolder("PixelPhase1/Summary");
136  //Book the summary plots for the variables as described in the config file
137  for (const auto& mapInfo : summaryPlotName_) {
138  auto name = mapInfo.first;
139  summaryMap_[name] = iBooker.book2D("pixel" + name + "Summary", "Pixel " + name + " Summary", 12, 0, 12, 4, 0, 4);
140  }
141  //Make the new 6 bin ROC summary
142  deadROCSummary = iBooker.book2D("deadROCSummary", "Percentage of dead ROCs per layer/ring", 2, 0, 2, 4, 0, 4);
143  std::vector<std::string> xAxisLabelsReduced_ = {"Barrel", "Forward"};
144  deadROCSummary->setAxisTitle("Subdetector", 1);
145  for (unsigned int i = 0; i < xAxisLabelsReduced_.size(); i++) {
146  deadROCSummary->setBinLabel(i + 1, xAxisLabelsReduced_[i]);
147  }
148 
149  //Book the summary plot
150  iBooker.setCurrentFolder("PixelPhase1/EventInfo");
151 
152  if (runOnEndLumi_) {
153  //New less granular summary plot - this is currently only done online
154  summaryMap_["Grand"] = iBooker.book2D("reportSummaryMap", "Pixel Summary Map", 2, 0, 2, 4, 0, 4);
155  summaryMap_["Grand"]->setAxisTitle("Subdetector", 1);
156  for (unsigned int i = 0; i < xAxisLabelsReduced_.size(); i++) {
157  summaryMap_["Grand"]->setBinLabel(i + 1, xAxisLabelsReduced_[i]);
158  for (unsigned int j = 0; j < 4; j++) {
159  summaryMap_["Grand"]->Fill(i, j, -1);
160  }
161  }
162  } else {
163  //Book the original summary plot, for now juts doing this one offline.
164  summaryMap_["Grand"] = iBooker.book2D("reportSummaryMap", "Pixel Summary Map", 12, 0, 12, 4, 0, 4);
165  }
166 
167  reportSummary = iBooker.bookFloat("reportSummary");
168 
169  //Now set up axis and bin labels
170  for (const auto& summaryMapEntry : summaryMap_) {
171  if (summaryMapEntry.first == "Grand")
172  continue;
173  auto summaryMap = summaryMapEntry.second;
174  for (unsigned int i = 0; i < xAxisLabels_.size(); i++) {
175  summaryMap->setBinLabel(i + 1, xAxisLabels_[i], 1);
176  }
177  for (unsigned int i = 0; i < yAxisLabels_.size(); i++) {
178  summaryMap->setBinLabel(i + 1, yAxisLabels_[i], 2);
179  }
180  summaryMap->setAxisTitle("Subdetector", 1);
181  summaryMap->setAxisTitle("Layer/disk", 2);
182  for (int i = 0; i < summaryMap->getTH1()->GetXaxis()->GetNbins(); i++) { // !??!?!? xAxisLabels_.size() ?!?!
183  for (int j = 0; j < summaryMap->getTH1()->GetYaxis()->GetNbins(); j++) { // !??!?!? yAxisLabels_.size() ?!?!?!
184  summaryMap->Fill(i, j, -1.);
185  }
186  }
187  }
188  reportSummary->Fill(-1.);
189 
190  //Reset the iBooker
191  iBooker.setCurrentFolder("PixelPhase1/");
192 }
193 
194 //------------------------------------------------------------------
195 // Used to book the trend plots
196 //------------------------------------------------------------------
198  //We need different plots depending on if we're online (runOnEndLumi) or offline (!runOnEndLumi)
199  iBooker.setCurrentFolder("PixelPhase1/");
200  std::vector<string> binAxisLabels = {"Layer 1", "Layer 2", "Layer 3", "Layer 4", "Ring 1", "Ring 2"};
201  if (runOnEndLumi_) {
202  std::vector<trendPlots> histoOrder = {layer1, layer2, layer3, layer4, ring1, ring2};
203  std::vector<string> varName = {"Layer_1", "Layer_2", "Layer_3", "Layer_4", "Ring_1", "Ring_2"};
204  std::vector<int> yMax = {1536, 3584, 5632, 8192, 4224, 6528};
205  for (unsigned int i = 0; i < histoOrder.size(); i++) {
206  string varNameStr = "deadRocTrend" + varName[i];
207  string varTitle = binAxisLabels[i] + " dead ROC trend";
208  deadROCTrends_[histoOrder[i]] = iBooker.bookProfile(varNameStr, varTitle, 500, 0., 5000, 0., yMax[i], "");
209  varNameStr = "ineffRocTrend" + varName[i];
210  varTitle = binAxisLabels[i] + " inefficient ROC trend";
211  ineffROCTrends_[histoOrder[i]] = iBooker.bookProfile(varNameStr, varTitle, 500, 0., 5000, 0., yMax[i], "");
212  deadROCTrends_[histoOrder[i]]->setAxisTitle("Lumisection", 1);
213  ineffROCTrends_[histoOrder[i]]->setAxisTitle("Lumisection", 1);
214  }
215  } else {
216  deadROCTrends_[offline] = iBooker.bookProfile("deadRocTotal", "N dead ROCs", 6, 0., 6, 0., 8192, "");
217  ineffROCTrends_[offline] = iBooker.bookProfile("ineffRocTotal", "N inefficient ROCs", 6, 0., 6, 0., 8192, "");
218  deadROCTrends_[offline]->setAxisTitle("Subdetector", 1);
219  ineffROCTrends_[offline]->setAxisTitle("Subdetector", 1);
220  for (unsigned int i = 1; i <= binAxisLabels.size(); i++) {
221  deadROCTrends_[offline]->setBinLabel(i, binAxisLabels[i - 1]);
222  ineffROCTrends_[offline]->setBinLabel(i, binAxisLabels[i - 1]);
223  }
224  }
225 }
226 
227 //------------------------------------------------------------------
228 // Fill the summary histograms
229 //------------------------------------------------------------------
231  //Firstly, we will fill the regular summary maps.
232  for (const auto& mapInfo : summaryPlotName_) {
233  auto name = mapInfo.first;
234  std::ostringstream histNameStream;
235  std::string histName;
236 
237  for (int i = 0; i < 12; i++) { // !??!?!? xAxisLabels_.size() ?!?!
238  for (int j = 0; j < 4; j++) { // !??!?!? yAxisLabels_.size() ?!?!?!
239  if (i > 3 && j == 3)
240  continue;
241  bool minus = i < 2 || (i > 3 && i < 8); // bleah !
242  int iOver2 = floor(i / 2.);
243  bool outer = (i > 3) ? iOver2 % 2 == 0 : i % 2 == 0;
244  //Complicated expression that creates the name of the histogram we are interested in.
245  histNameStream.str("");
246  histNameStream << topFolderName_.c_str() << "PX" << ((i > 3) ? "Forward" : "Barrel") << "/"
247  << ((i > 3) ? "HalfCylinder" : "Shell") << "_" << (minus ? "m" : "p") << ((outer) ? "O" : "I")
248  << "/" << ((i > 3) ? ((i % 2 == 0) ? "PXRing_1/" : "PXRing_2/") : "")
249  << summaryPlotName_[name].c_str() << "_PX" << ((i > 3) ? "Disk" : "Layer") << "_"
250  << ((i > 3) ? ((minus) ? "-" : "+") : "") << (j + 1);
251  histName = histNameStream.str();
252  MonitorElement* me = iGetter.get(histName);
253 
254  if (!me) {
255  edm::LogWarning("SiPixelPhase1Summary") << "ME " << histName << " is not available !!";
256  continue; // Ignore non-existing MEs, as this can cause the whole thing to crash
257  }
258 
259  if (summaryMap_[name] == nullptr) {
260  edm::LogWarning("SiPixelPhase1Summary") << "Summary map " << name << " is not available !!";
261  continue; // Based on reported errors it seems possible that we're trying to access a non-existant summary map, so if the map doesn't exist but we're trying to access it here we'll skip it instead.
262  }
263  if (!(me->getQReports()).empty())
264  summaryMap_[name]->setBinContent(i + 1, j + 1, (me->getQReports())[0]->getQTresult());
265  else
266  summaryMap_[name]->setBinContent(i + 1, j + 1, -1);
267  }
268  }
269  }
270 
271  //Fill the dead ROC summary
272  std::vector<trendPlots> trendOrder = {layer1, layer2, layer3, layer4, ring1, ring2};
273  std::vector<int> nRocsPerTrend = {1536, 3584, 5632, 8192, 4224, 6528};
274  for (unsigned int i = 0; i < trendOrder.size(); i++) {
275  int xBin = i < 4 ? 1 : 2;
276  int yBin = i % 4 + 1;
277  float nROCs = 0.;
278  if (runOnEndLumi_) { //Online case
279  TH1* tempProfile = deadROCTrends_[trendOrder[i]]->getTH1();
280  nROCs = tempProfile->GetBinContent(tempProfile->FindLastBinAbove());
281  } else { //Offline case
282  TH1* tempProfile = deadROCTrends_[offline]->getTH1();
283  nROCs = tempProfile->GetBinContent(i + 1);
284  }
285  deadROCSummary->setBinContent(xBin, yBin, nROCs / nRocsPerTrend[i]);
286  deadROCSummary->setBinContent(2, 3, -1);
287  deadROCSummary->setBinContent(2, 4, -1);
288  }
289 
290  //Sum of non-negative bins for the reportSummary
291  float sumOfNonNegBins = 0.;
292  //Now we will use the other summary maps to create the overall map.
293  //For now we only want to do this offline
294  if (!runOnEndLumi_) {
295  for (int i = 0; i < 12; i++) { // !??!?!? xAxisLabels_.size() ?!?!
296  if (summaryMap_["Grand"] == nullptr) {
297  edm::LogWarning("SiPixelPhase1Summary") << "Grand summary does not exist!";
298  break;
299  }
300  for (int j = 0; j < 4; j++) { // !??!?!? yAxisLabels_.size() ?!?!?!
301  summaryMap_["Grand"]->setBinContent(
302  i + 1,
303  j + 1,
304  1); // This resets the map to be good. We only then set it to 0 if there has been a problem in one of the other summaries.
305  for (auto const& mapInfo : summaryPlotName_) { //Check summary maps
306  auto name = mapInfo.first;
307  if (summaryMap_[name] == nullptr) {
308  edm::LogWarning("SiPixelPhase1Summary") << "Summary " << name << " does not exist!";
309  continue;
310  }
311  if (summaryMap_["Grand"]->getBinContent(i + 1, j + 1) > summaryMap_[name]->getBinContent(i + 1, j + 1))
312  summaryMap_["Grand"]->setBinContent(i + 1, j + 1, summaryMap_[name]->getBinContent(i + 1, j + 1));
313  }
314  if (summaryMap_["Grand"]->getBinContent(i + 1, j + 1) > -0.1)
315  sumOfNonNegBins += summaryMap_["Grand"]->getBinContent(i + 1, j + 1);
316  }
317  }
318  reportSummary->Fill(sumOfNonNegBins / 40.); // The average of the 40 useful bins in the summary map.
319  }
320 
321  //Fill the new overall map
322  // if (!runOnEndLumi_) return;
323  else { //Do this for online only
324  for (int i = 0; i < 2; i++) {
325  if (summaryMap_["Grand"] == nullptr) {
326  edm::LogWarning("SiPixelPhase1Summary") << "Grand summary does not exist!";
327  break;
328  }
329  for (int j = 0; j < 4; j++) { // !??!?!? yAxisLabels_.size() ?!?!?!
330  //Ignore the bins without detectors in them
331  if (i == 1 && j > 1) {
332  summaryMap_["Grand"]->setBinContent(i + 1, j + 1, -1);
333  } else {
334  if (deadROCSummary->getBinContent(i + 1, j + 1) < deadRocWarnThresholds_[i * 4 + j])
335  summaryMap_["Grand"]->setBinContent(i + 1, j + 1, 1);
336 
337  else if (deadROCSummary->getBinContent(i + 1, j + 1) > deadRocWarnThresholds_[i * 4 + j] &&
338  deadROCSummary->getBinContent(i + 1, j + 1) < deadRocThresholds_[i * 4 + j])
339  summaryMap_["Grand"]->setBinContent(i + 1, j + 1, 0.8);
340 
341  else
342  summaryMap_["Grand"]->setBinContent(i + 1, j + 1, 0);
343 
344  sumOfNonNegBins += summaryMap_["Grand"]->getBinContent(i + 1, j + 1);
345  }
346  }
347  }
348  }
349 }
350 //------------------------------------------------------------------
351 // Fill the trend plots
352 //------------------------------------------------------------------
354  // If we're running in online mode and the lumi section is not modulo 10, return. Offline running always uses lumiSec=0, so it will pass this test.
355  if (lumiSec % 10 != 0)
356  return;
357 
358  if (runOnEndLumi_) {
359  MonitorElement* nClustersAll = iGetter.get("PixelPhase1/Phase1_MechanicalView/num_clusters_per_Lumisection_PXAll");
360  if (nClustersAll == nullptr) {
361  edm::LogWarning("SiPixelPhase1Summary") << "All pixel cluster trend plot not available!!";
362  return;
363  }
364  if (nClustersAll->getTH1()->GetBinContent(lumiSec) < 100)
365  return;
366  }
367 
368  std::string histName;
369 
370  //Find the total number of filled bins and hi efficiency bins
371  std::vector<trendPlots> trendOrder = {layer1, layer2, layer3, layer4, ring1, ring2};
372  std::vector<int> nFilledROCs(trendOrder.size(), 0);
373  std::vector<int> hiEffROCs(trendOrder.size(), 0);
374  std::vector<int> nRocsPerTrend = {1536, 3584, 5632, 8192, 4224, 6528};
375  std::vector<string> trendNames = {};
376 
377  for (auto it : {1, 2, 3, 4}) {
378  histName = "PXBarrel/digi_occupancy_per_SignedModuleCoord_per_SignedLadderCoord_PXLayer_" + std::to_string(it);
379  trendNames.push_back(histName);
380  }
381  for (auto it : {1, 2}) {
382  histName = "PXForward/digi_occupancy_per_SignedDiskCoord_per_SignedBladePanelCoord_PXRing_" + std::to_string(it);
383  trendNames.push_back(histName);
384  }
385  //Loop over layers. This will also do the rings, but we'll skip the ring calculation for
386  for (unsigned int trendIt = 0; trendIt < trendOrder.size(); trendIt++) {
387  iGetter.cd();
388  histName = "PixelPhase1/Phase1_MechanicalView/" + trendNames[trendIt];
389  MonitorElement* tempLayerME = iGetter.get(histName);
390  if (tempLayerME == nullptr)
391  continue;
392  float lowEffValue = 0.25 * (tempLayerME->getTH1()->Integral() / nRocsPerTrend[trendIt]);
393  for (int i = 1; i <= tempLayerME->getTH1()->GetXaxis()->GetNbins(); i++) {
394  for (int j = 1; j <= tempLayerME->getTH1()->GetYaxis()->GetNbins(); j++) {
395  if (tempLayerME->getBinContent(i, j) > 0.)
396  nFilledROCs[trendIt]++;
397  if (tempLayerME->getBinContent(i, j) > lowEffValue)
398  hiEffROCs[trendIt]++;
399  }
400  }
401  if (runOnEndLumi_) {
402  tempLayerME->Reset(); //If we're doing online monitoring, reset the digi maps.
403  }
404  } // Close layers/ring loop
405 
406  if (!runOnEndLumi_) { //offline
407  for (unsigned int i = 0; i < trendOrder.size(); i++) {
408  deadROCTrends_[offline]->Fill(i, nRocsPerTrend[i] - nFilledROCs[i]);
409  ineffROCTrends_[offline]->Fill(i, nFilledROCs[i] - hiEffROCs[i]);
410  }
411  } else { //online
412  for (unsigned int i = 0; i < trendOrder.size(); i++) {
413  deadROCTrends_[trendOrder[i]]->Fill(lumiSec - 1, nRocsPerTrend[i] - nFilledROCs[i]);
414  ineffROCTrends_[trendOrder[i]]->Fill(lumiSec - 1, nFilledROCs[i] - hiEffROCs[i]);
415  }
416  }
417 
418  if (!runOnEndLumi_)
419  return; // The following only occurs in the online
420  //Reset some MEs every 10LS here
421  for (auto it : {1, 2, 3, 4}) { //PXBarrel
422  histName = "PixelPhase1/Phase1_MechanicalView/PXBarrel/clusterposition_zphi_PXLayer_" + std::to_string(it);
423  MonitorElement* toReset = iGetter.get(histName);
424  if (toReset != nullptr) {
425  toReset->Reset();
426  }
427  }
428  for (auto it : {"-3", "-2", "-1", "+1", "+2", "+3"}) { //PXForward
429  histName = "PixelPhase1/Phase1_MechanicalView/PXForward/clusterposition_xy_PXDisk_" + std::string(it);
430  MonitorElement* toReset = iGetter.get(histName);
431  if (toReset != nullptr) {
432  toReset->Reset();
433  }
434  }
435 }
436 
437 //define this as a plug-in
LuminosityBlockNumber_t luminosityBlock() const
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
MonitorElement * bookFloat(TString const &name, FUNC onbooking=NOOP())
Definition: DQMStore.h:80
SiPixelPhase1Summary(const edm::ParameterSet &conf)
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
MonitorElement * deadROCSummary
std::map< trendPlots, MonitorElement * > ineffROCTrends_
void fillSummaries(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter)
void fillTrendPlots(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, int lumiSeg=0)
static std::string to_string(const XMLCh *ch)
void Fill(long long x)
virtual void Reset()
Remove all data from the ME, keept the empty histogram with all its settings.
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
void beginRun(edm::Run const &run, edm::EventSetup const &eSetup) override
edm::ParameterSet conf_
std::map< std::string, std::string > summaryPlotName_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void bookTrendPlots(DQMStore::IBooker &iBooker)
virtual void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
MonitorElement * reportSummary
Log< level::Info, false > LogInfo
std::vector< double > deadRocWarnThresholds_
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
LuminosityBlockID id() const
std::map< trendPlots, MonitorElement * > deadROCTrends_
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:212
void dqmEndJob(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter) override
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:712
std::map< std::string, MonitorElement * > summaryMap_
virtual TH1 * getTH1() const
HLT enums.
Log< level::Warning, false > LogWarning
void bookSummaries(DQMStore::IBooker &iBooker)
void dqmEndLuminosityBlock(DQMStore::IBooker &iBooker, DQMStore::IGetter &iGetter, edm::LuminosityBlock const &lumiSeg, edm::EventSetup const &c) override
std::vector< double > deadRocThresholds_
Definition: Run.h:45
virtual double getBinContent(int binx) const
get content of bin (1-D)
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)