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