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