CMS 3D CMS Logo

DTOccupancyTest.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author G. Cerminara - University and INFN Torino
5  *
6  * threadsafe version (//-) oct/nov 2014 - WATWanAbdullah -ncpp-um-my
7  *
8  */
9 
10 
12 
22 
23 #include "TMath.h"
24 
25 using namespace edm;
26 using namespace std;
27 
28 
29 
30 
32  LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest]: Constructor";
33 
34  // Get the DQM service
35 
36  lsCounter = 0;
37 
38  writeRootFile = ps.getUntrackedParameter<bool>("writeRootFile", false);
39  if(writeRootFile) {
40  rootFile = new TFile("DTOccupancyTest.root","RECREATE");
41  ntuple = new TNtuple("OccupancyNtuple", "OccupancyNtuple", "ls:wh:st:se:lay1MeanCell:lay1RMS:lay2MeanCell:lay2RMS:lay3MeanCell:lay3RMS:lay4MeanCell:lay4RMS:lay5MeanCell:lay5RMS:lay6MeanCell:lay6RMS:lay7MeanCell:lay7RMS:lay8MeanCell:lay8RMS:lay9MeanCell:lay9RMS:lay10MeanCell:lay10RMS:lay11MeanCell:lay11RMS:lay12MeanCell:lay12RMS");
42  }
43 
44  // switch on the mode for running on test pulses (different top folder)
45  tpMode = ps.getUntrackedParameter<bool>("testPulseMode", false);
46 
47  runOnAllHitsOccupancies = ps.getUntrackedParameter<bool>("runOnAllHitsOccupancies", true);
48  runOnNoiseOccupancies = ps.getUntrackedParameter<bool>("runOnNoiseOccupancies", false);
49  runOnInTimeOccupancies = ps.getUntrackedParameter<bool>("runOnInTimeOccupancies", false);
50  nMinEvts = ps.getUntrackedParameter<int>("nEventsCert", 5000);
51  nMinEvtsPC = ps.getUntrackedParameter<int>("nEventsMinPC", 2200);
52  nZeroEvtsPC = ps.getUntrackedParameter<int>("nEventsZeroPC", 30);
53 
54  bookingdone = false;
55 
56  // Event counter
57  nevents = 0;
58 
59 }
60 
62  LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << " destructor called" << endl;
63 }
64 
65 
66 void DTOccupancyTest::beginRun(const edm::Run& run, const EventSetup& context){
67 
68  LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest]: BeginRun";
69 
70  // Get the geometry
71  context.get<MuonGeometryRecord>().get(muonGeom);
72 
73 }
74 
76  edm::LuminosityBlock const & lumiSeg, edm::EventSetup const & context) {
77  if (!bookingdone) {
78 
79  // Book the summary histos
80  // - one summary per wheel
81  for(int wh = -2; wh <= 2; ++wh) { // loop over wheels
82  bookHistos(ibooker,wh, string("Occupancies"), "OccupancySummary");
83  }
84 
85  ibooker.setCurrentFolder(topFolder());
86  string title = "Occupancy Summary";
87  if(tpMode) {
88  title = "Test Pulse Occupancy Summary";
89  }
90  // - global summary with alarms
91  summaryHisto = ibooker.book2D("OccupancySummary",title.c_str(),12,1,13,5,-2,3);
92  summaryHisto->setAxisTitle("sector",1);
93  summaryHisto->setAxisTitle("wheel",2);
94 
95  // - global summary with percentages
96  glbSummaryHisto = ibooker.book2D("OccupancyGlbSummary",title.c_str(),12,1,13,5,-2,3);
97  glbSummaryHisto->setAxisTitle("sector",1);
98  glbSummaryHisto->setAxisTitle("wheel",2);
99 
100 
101  // assign the name of the input histogram
102  if(runOnAllHitsOccupancies) {
103  nameMonitoredHisto = "OccupancyAllHits_perCh";
104  } else if(runOnNoiseOccupancies) {
105  nameMonitoredHisto = "OccupancyNoise_perCh";
106  } else if(runOnInTimeOccupancies) {
107  nameMonitoredHisto = "OccupancyInTimeHits_perCh";
108  } else { // default is AllHits histo
109  nameMonitoredHisto = "OccupancyAllHits_perCh";
110  }
111 
112  }
113  bookingdone = true;
114 
115 
116  LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest")
117  <<"[DTOccupancyTest]: End of LS transition, performing the DQM client operation";
118  lsCounter++;
119 
120 
121 
122  // Reset the global summary
123  summaryHisto->Reset();
124  glbSummaryHisto->Reset();
125 
126  nChannelTotal = 0;
127  nChannelDead = 0;
128 
129  // Get all the DT chambers
130  vector<const DTChamber*> chambers = muonGeom->chambers();
131 
132  for(vector<const DTChamber*>::const_iterator chamber = chambers.begin();
133  chamber != chambers.end(); ++chamber) { // Loop over all chambers
134  DTChamberId chId = (*chamber)->id();
135 
136  MonitorElement * chamberOccupancyHisto = igetter.get(getMEName(nameMonitoredHisto, chId));
137 
138  // Run the tests on the plot for the various granularities
139  if(chamberOccupancyHisto != nullptr) {
140  // Get the 2D histo
141  TH2F* histo = chamberOccupancyHisto->getTH2F();
142  float chamberPercentage = 1.;
143  int result = runOccupancyTest(histo, chId, chamberPercentage);
144  int sector = chId.sector();
145 
146  if(sector == 13) {
147  sector = 4;
148  float resultSect4 = wheelHistos[chId.wheel()]->getBinContent(sector, chId.station());
149  if(resultSect4 > result) {
150  result = (int)resultSect4;
151  }
152  } else if(sector == 14) {
153  sector = 10;
154  float resultSect10 = wheelHistos[chId.wheel()]->getBinContent(sector, chId.station());
155  if(resultSect10 > result) {
156  result = (int)resultSect10;
157  }
158  }
159 
160  // the 2 MB4 of Sect 4 and 10 count as half a chamber
161  if((sector == 4 || sector == 10) && chId.station() == 4)
162  chamberPercentage = chamberPercentage/2.;
163 
164  wheelHistos[chId.wheel()]->setBinContent(sector, chId.station(),result);
165  if(result > summaryHisto->getBinContent(sector, chId.wheel()+3)) {
166  summaryHisto->setBinContent(sector, chId.wheel()+3, result);
167  }
168  glbSummaryHisto->Fill(sector, chId.wheel(), chamberPercentage*1./4.);
169  } else {
170  LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest] ME: "
171  << getMEName(nameMonitoredHisto, chId) << " not found!" << endl;
172  }
173 
174  }
175 
176  string nEvtsName = "DT/EventInfo/Counters/nProcessedEventsDigi";
177 
178  MonitorElement * meProcEvts = igetter.get(nEvtsName);
179 
180  if (meProcEvts) {
181  int nProcEvts = meProcEvts->getFloatValue();
182  glbSummaryHisto->setEntries(nProcEvts < nMinEvts ? 10. : nProcEvts);
183  summaryHisto->setEntries(nProcEvts < nMinEvts ? 10. : nProcEvts);
184  } else {
185  glbSummaryHisto->setEntries(nMinEvts +1);
186  summaryHisto->setEntries(nMinEvts + 1);
187  LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest] ME: "
188  << nEvtsName << " not found!" << endl;
189  }
190 
191  // Fill the global summary
192  // Check for entire sectors off and report them on the global summary
193  //FIXME: TODO
194 
195  if(writeRootFile) ntuple->AutoSave("SaveSelf");
196 
197 }
198 
200 
201  LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") << "[DTOccupancyTest] endjob called!";
202  if(writeRootFile) {
203  rootFile->cd();
204  ntuple->Write();
205  rootFile->Close();
206  }
207 }
208 
209 
210 
211 // --------------------------------------------------
212 
213 void DTOccupancyTest::bookHistos(DQMStore::IBooker & ibooker, const int wheelId,
214  string folder, string histoTag) {
215  // Set the current folder
216  stringstream wheel; wheel << wheelId;
217 
218  ibooker.setCurrentFolder(topFolder());
219 
220  // build the histo name
221  string histoName = histoTag + "_W" + wheel.str();
222 
223 
224  LogVerbatim ("DTDQM|DTMonitorClient|DTOccupancyTest") <<"[DTOccupancyTest]: booking wheel histo:"
225  << histoName
226  << " (tag "
227  << histoTag
228  << ") in: "
229  << topFolder() + "Wheel"+ wheel.str() + "/" + folder << endl;
230 
231  string histoTitle = "Occupancy summary WHEEL: "+wheel.str();
232  if(tpMode) {
233  histoTitle = "TP Occupancy summary WHEEL: "+wheel.str();
234  }
235 
236  wheelHistos[wheelId] = ibooker.book2D(histoName,histoTitle,12,1,13,4,1,5);
237  wheelHistos[wheelId]->setBinLabel(1,"MB1",2);
238  wheelHistos[wheelId]->setBinLabel(2,"MB2",2);
239  wheelHistos[wheelId]->setBinLabel(3,"MB3",2);
240  wheelHistos[wheelId]->setBinLabel(4,"MB4",2);
241  wheelHistos[wheelId]->setAxisTitle("sector",1);
242 }
243 
244 
245 
246 string DTOccupancyTest::getMEName(string histoTag, const DTChamberId& chId) {
247 
248  stringstream wheel; wheel << chId.wheel();
249  stringstream station; station << chId.station();
250  stringstream sector; sector << chId.sector();
251 
252 
253  string folderRoot = topFolder() + "Wheel" + wheel.str() +
254  "/Sector" + sector.str() +
255  "/Station" + station.str() + "/";
256 
257  string folder = "Occupancies/";
258 
259  // build the histo name
260  string histoName = histoTag
261  + "_W" + wheel.str()
262  + "_St" + station.str()
263  + "_Sec" + sector.str();
264 
265  string histoname = folderRoot + histoName;
266 
267  return histoname;
268 }
269 
270 
271 int DTOccupancyTest::getIntegral(TH2F *histo, int firstBinX, int lastBinX, int firstBinY, int lastBinY, bool doall) {
272 
273  int sum = 0;
274  for (Int_t i = firstBinX; i < lastBinX+1; i++) {
275  for (Int_t j = firstBinY; j < lastBinY+1; j++) {
276 
277  if (histo->GetBinContent(i,j) >0){
278  if (!doall) return 1;
279  sum += histo->GetBinContent(i,j);
280  }
281  }
282  }
283 
284  return sum;
285 }
286 
287 
288 // Run a test on the occupancy of the chamber
289 // Return values:
290 // 0 -> all ok
291 // 1 -> # consecutive dead channels > N
292 // 2 -> dead layer
293 // 3 -> dead SL
294 // 4 -> dead chamber
295 
296 
298  float& chamberPercentage) {
299  int nBinsX = histo->GetNbinsX();
300 
301  LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << "--- Occupancy test for chamber: " << chId << endl;
302 
303  int compDeadCell = 0;
304  int totCell = 0;
305  int totOccup = 0;
306 
307  for(int slay = 1; slay <= 3; ++slay) { // loop over SLs
308  int binYlow = ((slay-1)*4)+1;
309 
310  if(chId.station() == 4 && slay == 2) continue;
311  for(int lay = 1; lay <= 4; ++lay) { // loop over layers
312  DTLayerId layID(chId,slay,lay);
313  int firstWire = muonGeom->layer(layID)->specificTopology().firstChannel();
314  int nWires = muonGeom->layer(layID)->specificTopology().channels();
315  int binY = binYlow+(lay-1);
316  int totalDeadCells = 0;
317  int nDeadCellsInARow = 1;
318  int nDeadCellsInARowMax = 0;
319  int nCellsZeroCount = 0;
320  bool previousIsDead = false;
321 
322  int interDeadCells = 0;
323 
324  totCell += nWires;
325 
326  for(int cell = firstWire; cell != (nWires+firstWire); ++cell) { // loop over cells
327  double cellOccup = histo->GetBinContent(cell,binY);
328  LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " cell occup: " << cellOccup;
329  totOccup += cellOccup;
330 
331  if(cellOccup == 0) {
332  nCellsZeroCount++;
333  totalDeadCells++;
334  if(previousIsDead) {
335  nDeadCellsInARow++;
336  }
337  else {
338  // if(interDeadCells > 3) {
339  if(nDeadCellsInARow > nDeadCellsInARowMax) nDeadCellsInARowMax = nDeadCellsInARow;
340  nDeadCellsInARow = 1;
341  // }
342  }
343  previousIsDead = true;
344  interDeadCells = 0;
345  LogTrace("DTDQM|DTMonitorClient|DTOccupancyTest") << " below reference" << endl;
346  } else {
347  previousIsDead = false;
348  interDeadCells++;
349  }
350  // // 3 cells not dead between a group of dead cells don't break the count
351  if(nDeadCellsInARow > nDeadCellsInARowMax) nDeadCellsInARowMax = nDeadCellsInARow;
352  }
353  compDeadCell += totalDeadCells;
354  if(nDeadCellsInARowMax >= 7.) {
355  histo->SetBinContent(nBinsX+1,binY,-1.);
356  }
357  }
358  }
359 
360 
361  nChannelTotal += totCell;
362  nChannelDead += compDeadCell;
363  chamberPercentage = 1.-(float(compDeadCell)/totCell);
364 
365  int min_occup = nZeroEvtsPC*20;
366  if (chId.station() == 3) min_occup = nZeroEvtsPC*3;
367  if (chId.station() == 2) min_occup = nZeroEvtsPC*8;
368  if ((chId.station() == 4) && (chId.sector() == 9)) min_occup = nZeroEvtsPC*3;
369  if ((chId.station() == 4) && (chId.sector() == 10)) min_occup = nZeroEvtsPC*3;
370  if ((chId.station() == 4) && (chId.sector() == 11)) min_occup = nZeroEvtsPC*3;
371  if ((chId.station() == 4) && (chId.sector() == 14)) min_occup = nZeroEvtsPC*3;
372 
373 
374  if (totOccup < min_occup) return 4;
375  if (totOccup < nMinEvtsPC) chamberPercentage = 1.;
376 
377  if (chamberPercentage < 0.2) return 4;
378  if (chamberPercentage < 0.5) return 3;
379  if (chamberPercentage < 0.75) return 2;
380  if (chamberPercentage < 0.9) return 1;
381 
382  return 0;
383 }
384 
385 
387  if(tpMode) return string("DT/10-TestPulses/");
388  return string("DT/01-Digi/");
389 }
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override
Endjob.
T getUntrackedParameter(std::string const &, T const &) const
int runOccupancyTest(TH2F *histo, const DTChamberId &chId, float &chamberPercentage)
MonitorElement * get(const std::string &path)
Definition: DQMStore.cc:305
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)
int getIntegral(TH2F *histo, int, int, int, int, bool)
void dqmEndLuminosityBlock(DQMStore::IBooker &, DQMStore::IGetter &, edm::LuminosityBlock const &, edm::EventSetup const &) override
DQM Client Diagnostic.
Definition: ntuple.py:1
void bookHistos()
Definition: Histogram.h:33
DTOccupancyTest(const edm::ParameterSet &ps)
Constructor.
void bookHistos(DQMStore::IBooker &, const int wheelId, std::string folder, std::string histoTag)
book the summary histograms
std::string getMEName(std::string histoTag, const DTChamberId &chId)
Get the ME name.
double getFloatValue(void) const
void beginRun(edm::Run const &run, edm::EventSetup const &context) override
BeginRun.
#define LogTrace(id)
~DTOccupancyTest() override
Destructor.
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
MonitorElement * book2D(Args &&...args)
Definition: DQMStore.h:133
const T & get() const
Definition: EventSetup.h:55
HLT enums.
int sector() const
Definition: DTChamberId.h:61
std::string topFolder() const
int station() const
Return the station number.
Definition: DTChamberId.h:51
TH2F * getTH2F(void) const
static char chambers[264][20]
Definition: ReadPGInfo.cc:243
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45
void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)
Definition: Run.h:43