CMS 3D CMS Logo

L1TEMTFEventInfoClient.cc
Go to the documentation of this file.
1 
13 // this class header
15 
16 // constructor
18  : m_verbose(parSet.getUntrackedParameter<bool>("verbose", false)),
19  m_monitorDir(parSet.getUntrackedParameter<std::string>("monitorDir", "")),
20  m_histDir(parSet.getUntrackedParameter<std::string>("histDir", "")),
21  m_runInEventLoop(parSet.getUntrackedParameter<bool>("runInEventLoop", false)),
22  m_runInEndLumi(parSet.getUntrackedParameter<bool>("runInEndLumi", false)),
23  m_runInEndRun(parSet.getUntrackedParameter<bool>("runInEndRun", false)),
24  m_runInEndJob(parSet.getUntrackedParameter<bool>("runInEndJob", false)),
25  m_trackObjects(parSet.getParameter<std::vector<edm::ParameterSet> >("TrackObjects")),
26  m_hitObjects(parSet.getParameter<std::vector<edm::ParameterSet> >("HitObjects")),
27  m_disableTrackObjects(parSet.getParameter<std::vector<std::string> >("DisableTrackObjects")),
28  m_disableHitObjects(parSet.getParameter<std::vector<std::string> >("DisableHitObjects")),
29  m_noisyStrip(parSet.getParameter<std::vector<edm::ParameterSet> >("NoisyStrip")),
30  m_deadStrip(parSet.getParameter<std::vector<edm::ParameterSet> >("DeadStrip")),
31  m_disableNoisyStrip(parSet.getParameter<std::vector<std::string> >("DisableNoisyStrip")),
32  m_disableDeadStrip(parSet.getParameter<std::vector<std::string> >("DisableDeadStrip")),
33  m_nrTrackObjects(0),
34  m_nrHitObjects(0),
35  m_nrNoisyStrip(0),
36  m_nrDeadStrip(0),
37  m_totalNrQtSummaryEnabled(0) {
38  initialize();
39 }
40 
41 // destructor
43  //empty
44 }
45 
47  if (m_verbose)
48  std::cout << "\nMonitor directory = " << m_monitorDir << std::endl;
49 
50  // L1 systems
51 
53 
55  // m_trackLabelExt.reserve(m_nrTrackObjects); // Not needed? - AWB 05.12.16
57 
58  // on average five quality test per system - just a best guess
59  m_trackQualityTestName.reserve(5 * m_nrTrackObjects); // Not needed? - AWB 05.12.16
60  m_trackQualityTestHist.reserve(5 * m_nrTrackObjects); // Not needed? - AWB 05.12.16
61  m_trackQtSummaryEnabled.reserve(5 * m_nrTrackObjects); // Not needed? - AWB 05.12.16
62 
63  int indexSys = 0;
64 
65  int totalNrQualityTests = 0;
66 
67  for (const auto& itTrack : m_trackObjects) {
68  m_trackLabel.push_back(itTrack.getParameter<std::string>("SystemLabel"));
69 
70  // m_trackLabelExt.push_back(itTrack.getParameter<std::string>( // Not needed? - AWB 05.12.16
71  // "HwValLabel"));
72 
73  m_trackDisable.push_back(itTrack.getParameter<unsigned int>("SystemDisable"));
74  // check the additional disable flag from m_disableTrackObjects
75  for (const auto& itSys : m_disableTrackObjects) {
76  if (itSys == m_trackLabel[indexSys]) {
77  m_trackDisable[indexSys] = 1;
78  }
79  }
80 
81  std::vector<edm::ParameterSet> qTests = itTrack.getParameter<std::vector<edm::ParameterSet> >("QualityTests");
82  size_t qtPerSystem = qTests.size();
83 
84  std::vector<std::string> qtNames;
85  qtNames.reserve(qtPerSystem);
86 
87  std::vector<std::string> qtFullPathHists;
88  qtFullPathHists.reserve(qtPerSystem);
89 
90  std::vector<unsigned int> qtSumEnabled;
91  qtSumEnabled.reserve(qtPerSystem);
92 
93  if (m_verbose)
94  std::cout << "\nLooping over track quality tests" << std::endl;
95  for (const auto& itQT : qTests) {
96  totalNrQualityTests++;
97 
98  qtNames.push_back(itQT.getParameter<std::string>("QualityTestName"));
99 
100  // qtFullPathHists.push_back( m_histDir + "/" + itQT.getParameter<std::string> ("QualityTestHist"));
101  qtFullPathHists.push_back(itQT.getParameter<std::string>("QualityTestHist"));
102  if (m_verbose)
103  std::cout << qtFullPathHists.back() << std::endl;
104 
105  unsigned int qtEnabled = itQT.getParameter<unsigned int>("QualityTestSummaryEnabled");
106 
107  qtSumEnabled.push_back(qtEnabled);
108 
109  if (qtEnabled) {
111  }
112  }
113 
114  m_trackQualityTestName.push_back(qtNames);
115  m_trackQualityTestHist.push_back(qtFullPathHists);
116  m_trackQtSummaryEnabled.push_back(qtSumEnabled);
117 
118  indexSys++;
119  }
120 
121  // L1 objects
122 
123  //
124  m_nrHitObjects = m_hitObjects.size();
125 
126  m_hitLabel.reserve(m_nrHitObjects);
127  m_hitDisable.reserve(m_nrHitObjects);
128 
129  // on average five quality test per object - just a best guess
133 
134  int indexObj = 0;
135 
136  for (const auto& itObject : m_hitObjects) {
137  m_hitLabel.push_back(itObject.getParameter<std::string>("HitLabel"));
138 
139  m_hitDisable.push_back(itObject.getParameter<unsigned int>("HitDisable"));
140  // check the additional disable flag from m_disableHitObjects
141  for (const auto& itObj : m_disableHitObjects) {
142  if (itObj == m_hitLabel[indexObj]) {
143  m_hitDisable[indexObj] = 1;
144  }
145  }
146 
147  std::vector<edm::ParameterSet> qTests = itObject.getParameter<std::vector<edm::ParameterSet> >("QualityTests");
148  size_t qtPerObject = qTests.size();
149 
150  std::vector<std::string> qtNames;
151  qtNames.reserve(qtPerObject);
152 
153  std::vector<std::string> qtFullPathHists;
154  qtFullPathHists.reserve(qtPerObject);
155 
156  std::vector<unsigned int> qtSumEnabled;
157  qtSumEnabled.reserve(qtPerObject);
158 
159  if (m_verbose)
160  std::cout << "\nLooping over hit quality tests" << std::endl;
161  for (const auto& itQT : qTests) {
162  totalNrQualityTests++;
163 
164  qtNames.push_back(itQT.getParameter<std::string>("QualityTestName"));
165 
166  // qtFullPathHists.push_back( m_histDir + "/" + itQT.getParameter<std::string> ("QualityTestHist") );
167  qtFullPathHists.push_back(itQT.getParameter<std::string>("QualityTestHist"));
168  if (m_verbose)
169  std::cout << qtFullPathHists.back() << std::endl;
170 
171  unsigned int qtEnabled = itQT.getParameter<unsigned int>("QualityTestSummaryEnabled");
172 
173  qtSumEnabled.push_back(qtEnabled);
174 
175  if (qtEnabled) {
177  }
178  }
179 
180  m_hitQualityTestName.push_back(qtNames);
181  m_hitQualityTestHist.push_back(qtFullPathHists);
182  m_hitQtSummaryEnabled.push_back(qtSumEnabled);
183 
184  indexObj++;
185  }
186 
187  // L1 Strip Noisy=========================================================================================
188 
189  m_nrNoisyStrip = m_noisyStrip.size();
190 
191  m_noisyLabel.reserve(m_nrNoisyStrip);
193 
194  // on average 20 quality tests per system
195  m_noisyQualityTestName.reserve(20 * m_nrNoisyStrip); // Not needed? - AWB 05.12.16
196  m_noisyQualityTestHist.reserve(20 * m_nrNoisyStrip); // Not needed? - AWB 05.12.16
197  m_noisyQtSummaryEnabled.reserve(20 * m_nrNoisyStrip); // Not needed? - AWB 05.12.16
198 
199  int indexNois = 0;
200 
201  for (const auto& itNoisy : m_noisyStrip) {
202  m_noisyLabel.push_back(itNoisy.getParameter<std::string>("NoisyLabel"));
203 
204  m_noisyDisable.push_back(itNoisy.getParameter<unsigned int>("NoisyDisable"));
205  // check the additional disable flag from m_disableNoisyObjects
206  for (const auto& itNois : m_disableNoisyStrip) {
207  if (itNois == m_noisyLabel[indexNois]) {
208  m_noisyDisable[indexNois] = 1;
209  }
210  }
211 
212  std::vector<edm::ParameterSet> qTests = itNoisy.getParameter<std::vector<edm::ParameterSet> >("QualityTests");
213  size_t qtPerNoisy = qTests.size();
214 
215  std::vector<std::string> qtNames;
216  qtNames.reserve(qtPerNoisy);
217 
218  std::vector<std::string> qtFullPathHists;
219  qtFullPathHists.reserve(qtPerNoisy);
220 
221  std::vector<unsigned int> qtSumEnabled;
222  qtSumEnabled.reserve(qtPerNoisy);
223 
224  if (m_verbose)
225  std::cout << "\nLooping over noisy quality tests" << std::endl;
226  for (const auto& itQT : qTests) {
227  totalNrQualityTests++;
228 
229  qtNames.push_back(itQT.getParameter<std::string>("QualityTestName"));
230 
231  qtFullPathHists.push_back(itQT.getParameter<std::string>("QualityTestHist"));
232  if (m_verbose)
233  std::cout << qtFullPathHists.back() << std::endl;
234 
235  unsigned int qtEnabled = itQT.getParameter<unsigned int>("QualityTestSummaryEnabled");
236 
237  qtSumEnabled.push_back(qtEnabled);
238 
239  if (qtEnabled) {
241  }
242  }
243 
244  m_noisyQualityTestName.push_back(qtNames);
245  m_noisyQualityTestHist.push_back(qtFullPathHists);
246  m_noisyQtSummaryEnabled.push_back(qtSumEnabled);
247 
248  indexNois++;
249  }
250 
251  // L1 Strip Dead=========================================================================================
252 
253  m_nrDeadStrip = m_deadStrip.size();
254 
255  m_deadLabel.reserve(m_nrDeadStrip);
256  m_deadDisable.reserve(m_nrDeadStrip);
257 
258  // on average 20 quality tests per system
259  m_deadQualityTestName.reserve(20 * m_nrDeadStrip); // Not needed? - AWB 05.12.16
260  m_deadQualityTestHist.reserve(20 * m_nrDeadStrip); // Not needed? - AWB 05.12.16
261  m_deadQtSummaryEnabled.reserve(20 * m_nrDeadStrip); // Not needed? - AWB 05.12.16
262 
263  int indexDed = 0;
264 
265  for (const auto& itDead : m_deadStrip) {
266  m_deadLabel.push_back(itDead.getParameter<std::string>("DeadLabel"));
267 
268  m_deadDisable.push_back(itDead.getParameter<unsigned int>("DeadDisable"));
269  // check the additional disable flag from m_disableDeadObjects
270  for (const auto& itDed : m_disableDeadStrip) {
271  if (itDed == m_deadLabel[indexDed]) {
272  m_deadDisable[indexDed] = 1;
273  }
274  }
275 
276  std::vector<edm::ParameterSet> qTests = itDead.getParameter<std::vector<edm::ParameterSet> >("QualityTests");
277  size_t qtPerDead = qTests.size();
278 
279  std::vector<std::string> qtNames;
280  qtNames.reserve(qtPerDead);
281 
282  std::vector<std::string> qtFullPathHists;
283  qtFullPathHists.reserve(qtPerDead);
284 
285  std::vector<unsigned int> qtSumEnabled;
286  qtSumEnabled.reserve(qtPerDead);
287 
288  if (m_verbose)
289  std::cout << "\nLooping over dead quality tests" << std::endl;
290  for (const auto& itQT : qTests) {
291  totalNrQualityTests++;
292 
293  qtNames.push_back(itQT.getParameter<std::string>("QualityTestName"));
294 
295  qtFullPathHists.push_back(itQT.getParameter<std::string>("QualityTestHist"));
296  if (m_verbose)
297  std::cout << qtFullPathHists.back() << std::endl;
298 
299  unsigned int qtEnabled = itQT.getParameter<unsigned int>("QualityTestSummaryEnabled");
300 
301  qtSumEnabled.push_back(qtEnabled);
302 
303  if (qtEnabled) {
305  }
306  }
307 
308  m_deadQualityTestName.push_back(qtNames);
309  m_deadQualityTestHist.push_back(qtFullPathHists);
310  m_deadQtSummaryEnabled.push_back(qtSumEnabled);
311 
312  indexDed++;
313  }
314 
316  m_meReportSummaryContent.reserve(totalNrQualityTests);
317 }
318 
320  DQMStore::IGetter& igetter,
321  const edm::LuminosityBlock& lumiSeg,
322  const edm::EventSetup& evSetup) {
323  if (m_verbose)
324  std::cout << "\nInside void L1TEMTFEventInfoClient::dqmEndLuminosityBlock" << std::endl;
325  if (m_runInEndLumi) {
326  book(ibooker, igetter);
327  readQtResults(ibooker, igetter);
328 
329  if (m_verbose) {
330  std::cout << "\n L1TEMTFEventInfoClient::endLuminosityBlock\n" << std::endl;
331  dumpContentMonitorElements(ibooker, igetter);
332  }
333  }
334 }
335 
337  if (m_verbose)
338  std::cout << "\nInside void L1TEMTFEventInfoClient::dqmEndJob" << std::endl;
339  book(ibooker, igetter);
340 
341  readQtResults(ibooker, igetter);
342 
343  if (m_verbose) {
344  std::cout << "\n L1TEMTFEventInfoClient::endRun\n" << std::endl;
345  dumpContentMonitorElements(ibooker, igetter);
346  }
347 }
348 
350  if (m_verbose)
351  std::cout << "\nSummary report " << std::endl;
352 
353  // summary content
354 
356 
357  if (m_verbose)
358  std::cout << "\nSummary content per system and object as filled in histogram\n " << m_meReportSummaryMap->getName()
359  << std::endl;
360 
361  if (!me) {
362  if (m_verbose)
363  std::cout << "\nNo histogram " << m_meReportSummaryMap->getName()
364  << "\nNo summary content per system and object as filled in histogram.\n " << std::endl;
365  return;
366  }
367 
368  TH2F* hist = me->getTH2F();
369 
370  const int nBinsX = hist->GetNbinsX();
371  const int nBinsY = hist->GetNbinsY();
372  if (m_verbose)
373  std::cout << nBinsX << " " << nBinsY;
374 
375  std::vector<std::vector<int> > meReportSummaryMap(nBinsX, std::vector<int>(nBinsY));
376 
377  // for (int iBinX = 0; iBinX < nBinsX; iBinX++) {
378  // for (int iBinY = 0; iBinY < nBinsY; iBinY++) {
379  // meReportSummaryMap[iBinX][iBinY]
380  // = static_cast<int>(me->GetBinContent(iBinX + 1, iBinY + 1));
381  // }
382  // }
383 
384  if (m_verbose)
385  std::cout << "\nL1 systems: " << m_nrTrackObjects << " systems included\n"
386  << "\n Summary content size: " << (m_summaryContent.size()) << std::endl;
387 
388  for (unsigned int iTrackObj = 0; iTrackObj < m_nrTrackObjects; ++iTrackObj) {
389  if (m_verbose)
390  std::cout << std::setw(10) << m_trackLabel[iTrackObj]
391  << std::setw(10)
392  // << m_trackLabelExt[iTrackObj] << " \t" << m_trackDisable[iTrackObj]
393  << m_trackDisable[iTrackObj] << " \t" << std::setw(25) << " m_summaryContent[" << std::setw(2)
394  << iTrackObj << "] = " << meReportSummaryMap[0][iTrackObj] << std::endl;
395  }
396 
397  if (m_verbose)
398  std::cout << "\n L1 trigger objects: " << m_nrHitObjects << " objects included\n" << std::endl;
399 
400  for (unsigned int iMon = m_nrTrackObjects; iMon < m_nrTrackObjects + m_nrHitObjects; ++iMon) {
401  if (m_verbose)
402  std::cout << std::setw(20) << m_hitLabel[iMon - m_nrTrackObjects] << " \t"
403  << m_hitDisable[iMon - m_nrTrackObjects] << " \t" << std::setw(25) << " m_summaryContent["
404  << std::setw(2) << iMon << "] = \t" << m_summaryContent[iMon] << std::endl;
405  }
406 
407  if (m_verbose)
408  std::cout << std::endl;
409 
410  // quality tests
411 
412  if (m_verbose)
413  std::cout << "\nQuality test results as filled in "
414  << "\n " << m_monitorDir << "/EventInfo/reportSummaryContents\n"
415  << "\n Total number of quality tests: " << (m_meReportSummaryContent.size()) << "\n"
416  << std::endl;
417 
418  for (const auto itME : m_meReportSummaryContent) {
419  if (m_verbose)
420  std::cout << std::setw(50) << itME->getName() << " \t" << std::setw(25) << itME->getFloatValue() << std::endl;
421  }
422 
423  if (m_verbose)
424  std::cout << std::endl;
425 }
426 
428  if (m_verbose)
429  std::cout << "\nInside void L1TEMTFEventInfoClient::book" << std::endl;
430  std::string dirEventInfo = m_monitorDir + "/EventInfo";
431  if (m_verbose)
432  std::cout << dirEventInfo << std::endl;
433 
434  ibooker.setCurrentFolder(dirEventInfo);
435  if (m_verbose)
436  std::cout << "Ran ibooker.setCurrentFolder(dirEventInfo;" << std::endl;
437 
438  // ...and book it again
439  m_meReportSummary = ibooker.bookFloat("reportSummary");
440  if (m_verbose)
441  std::cout << "Ran m_meReportSummary = ibooker.bookFloat" << std::endl;
442 
443  // initialize reportSummary to 1
444 
445  if (m_meReportSummary) {
446  if (m_verbose)
447  std::cout << "Initializing reportSummary to 1" << std::endl;
449  if (m_verbose)
450  std::cout << "Ran m_meReportSummary->Fill(1);" << std::endl;
451  }
452 
453  // define float histograms for reportSummaryContents (one histogram per quality test),
454  // initialize them to zero
455  // initialize also m_summaryContent to dqm::qstatus::DISABLED
456 
457  ibooker.setCurrentFolder(dirEventInfo + "/reportSummaryContents");
458  if (m_verbose)
459  std::cout << "Ran ibooker.setCurrentFolder(dirEventInfo" << std::endl;
460  // general counters:
461  // iAllQTest: all quality tests for all systems and objects
462  int iAllQTest = 0;
463 
464  if (m_verbose)
465  std::cout << "m_nrTrackObjects = " << m_nrTrackObjects << std::endl;
466  for (unsigned int iMon = 0; iMon < m_nrTrackObjects; ++iMon) {
467  if (m_verbose)
468  std::cout << " * iMon = " << iMon << std::endl;
469 
471  if (m_verbose)
472  std::cout << "Ran m_summaryContent.push_back(dqm::qstatus::DISABLED);" << std::endl;
473 
474  const std::vector<std::string>& trackObjQtName = m_trackQualityTestName[iMon];
475  if (m_verbose)
476  std::cout << "Ran const std::vector<std::string>& trackObjQtName = m_trackQualityTestName[iMon];" << std::endl;
477 
478  for (const auto& itQtName : trackObjQtName) {
479  if (m_verbose)
480  std::cout << " - m_monitorDir = " << m_monitorDir << ", m_trackLabel[iMon] = " << m_trackLabel[iMon]
481  << ", (itQtName) = " << (itQtName) << std::endl;
482 
483  // Avoid error in ibooker.bookFloat(hStr))
484  std::string m_mon_mod = m_monitorDir;
485  std::replace(m_mon_mod.begin(), m_mon_mod.end(), '/', '_');
486 
487  const std::string hStr = m_mon_mod + "_L1Sys_" + m_trackLabel[iMon] + "_" + (itQtName);
488  if (m_verbose)
489  std::cout << " - " << hStr << std::endl;
490 
491  m_meReportSummaryContent.push_back(ibooker.bookFloat(hStr));
492  if (m_verbose)
493  std::cout << " - Ran m_meReportSummaryContent.push_back(ibooker.bookFloat(hStr));" << std::endl;
494  m_meReportSummaryContent[iAllQTest]->Fill(0.);
495  if (m_verbose)
496  std::cout << " - Ran m_meReportSummaryContent[iAllQTest]->Fill(0.);" << std::endl;
497 
498  iAllQTest++;
499  }
500  }
501 
502  for (unsigned int iMon = 0; iMon < m_nrHitObjects; ++iMon) {
503  if (m_verbose)
504  std::cout << " * iMon = " << iMon << std::endl;
505 
507 
508  const std::vector<std::string>& objQtName = m_hitQualityTestName[iMon];
509 
510  for (const auto& itQtName : objQtName) {
511  // Avoid error in ibooker.bookFloat(hStr))
512  std::string m_mon_mod = m_monitorDir;
513  std::replace(m_mon_mod.begin(), m_mon_mod.end(), '/', '_');
514 
515  const std::string hStr = m_mon_mod + "_L1Obj_" + m_hitLabel[iMon] + "_" + (itQtName);
516  if (m_verbose)
517  std::cout << " - " << hStr << std::endl;
518 
519  m_meReportSummaryContent.push_back(ibooker.bookFloat(hStr));
520  if (m_verbose)
521  std::cout << " - Ran m_meReportSummaryContent.push_back(ibooker.bookFloat(hStr));" << std::endl;
522  m_meReportSummaryContent[iAllQTest]->Fill(0.);
523  if (m_verbose)
524  std::cout << " - Ran m_meReportSummaryContent[iAllQTest]->Fill(0.);" << std::endl;
525 
526  iAllQTest++;
527  }
528  }
529 
530  // for Noisy Strips ====================================================================
531  for (unsigned int iMon = 0; iMon < m_nrNoisyStrip; ++iMon) {
533 
534  const std::vector<std::string>& objQtName = m_noisyQualityTestName[iMon];
535 
536  for (const auto& itQtName : objQtName) {
537  // Avoid error in ibooker.bookFloat(hStr))
538  std::string m_mon_mod = m_monitorDir;
539  std::replace(m_mon_mod.begin(), m_mon_mod.end(), '/', '_');
540 
541  const std::string hStr = m_mon_mod + "_L1Obj_" + m_noisyLabel[iMon] + "_" + (itQtName);
542  if (m_verbose)
543  std::cout << " - " << hStr << std::endl;
544 
545  m_meReportSummaryContent.push_back(ibooker.bookFloat(hStr));
546  m_meReportSummaryContent[iAllQTest]->Fill(0.);
547 
548  iAllQTest++;
549  }
550  }
551  // for Dead Strips ====================================================================
552  for (unsigned int iMon = 0; iMon < m_nrDeadStrip; ++iMon) {
554 
555  const std::vector<std::string>& objQtName = m_deadQualityTestName[iMon];
556 
557  for (const auto& itQtName : objQtName) {
558  // Avoid error in ibooker.bookFloat(hStr))
559  std::string m_mon_mod = m_monitorDir;
560  std::replace(m_mon_mod.begin(), m_mon_mod.end(), '/', '_');
561 
562  const std::string hStr = m_mon_mod + "_L1Obj_" + m_deadLabel[iMon] + "_" + (itQtName);
563  if (m_verbose)
564  std::cout << " - " << hStr << std::endl;
565 
566  m_meReportSummaryContent.push_back(ibooker.bookFloat(hStr));
567  m_meReportSummaryContent[iAllQTest]->Fill(0.);
568 
569  iAllQTest++;
570  }
571  }
572 
573  if (m_verbose)
574  std::cout << "Setting current folder to " << dirEventInfo << std::endl;
575  ibooker.setCurrentFolder(dirEventInfo);
576  if (m_verbose)
577  std::cout << "Ran ibooker.setCurrentFolder(dirEventInfo);" << std::endl;
578 
579  // define a histogram with two bins on X and maximum of m_nrTrackObjects, m_nrHitObjects on Y
581  int nBinsYStrip = std::max(m_nrNoisyStrip, m_nrDeadStrip);
582 
584  ibooker.book2D("reportSummaryMap_EMTF", "reportSummaryMap_EMTF", 2, 1, 3, nBinsY, 1, nBinsY + 1);
586  "reportSummaryMap_chamberStrip", "reportSummaryMap_chamberStrip", 2, 1, 3, nBinsYStrip, 1, nBinsYStrip + 1);
587 
588  if (m_monitorDir == "L1TEMU") {
589  m_meReportSummaryMap->setTitle("L1TEMU: L1 Emulator vs Data Report Summary Map");
590 
591  } else if (m_monitorDir == "L1T") {
592  m_meReportSummaryMap->setTitle("L1T: L1 Trigger Data Report Summary Map");
593  } else if (m_monitorDir == "L1T2016") {
594  m_meReportSummaryMap->setTitle("L1T2016: L1 Trigger Data Report Summary Map");
595  } else {
596  // do nothing
597  }
598 
601 
602  m_meReportSummaryMap->setBinLabel(1, "Noisy Check", 1);
603  m_meReportSummaryMap->setBinLabel(2, "Dead Check", 1);
604 
605  m_meReportSummaryMap_chamberStrip->setBinLabel(1, "Noisy Check", 1);
606  m_meReportSummaryMap_chamberStrip->setBinLabel(2, "Dead Check", 1);
607 
608  // for (int iBin = 0; iBin < nBinsY; ++iBin) {
609  // m_meReportSummaryMap->setBinLabel(iBin + 1, " ", 2); }
610 
611  m_meReportSummaryMap->setBinLabel(1, "Hit BX", 2);
612  m_meReportSummaryMap->setBinLabel(2, "Track BX", 2);
613  //m_meReportSummaryMap->setBinLabel(3, "Track Phi", 2);
614 
615  const std::vector<std::string> suffix_name = {"-4/2", "-4/1", "-3/2", "-3/1", "-2/2", "-2/1", "-1/3",
616  "-1/2", "-1/1b", "-1/1a", "+1/1a", "+1/1b", "+1/2", "+1/3",
617  "+2/1", "+2/2", "+3/1", "+3/2", "+4/1", "+4/2"};
618  for (int iBin = 0; iBin < nBinsYStrip; ++iBin) {
619  m_meReportSummaryMap_chamberStrip->setBinLabel(iBin + 1, "ChamberStrip " + suffix_name[iBin], 2);
620  }
621 }
622 
624  // initialize summary content, summary sum and ReportSummaryContent float histograms
625  // for all L1 systems and L1 objects
626 
627  if (m_verbose)
628  std::cout << "\nInside L1TEMTFEventInfoClient::readQtResults" << std::endl; // Extra printout - AWB 03.12.16
629 
630  for (std::vector<int>::iterator it = m_summaryContent.begin(); it != m_summaryContent.end(); ++it) {
631  (*it) = dqm::qstatus::DISABLED;
632  }
633 
634  m_summarySum = 0.;
635 
636  for (const auto& itME : m_meReportSummaryContent) {
637  itME->Fill(0.);
638  }
639 
640  // general counters:
641  // iAllQTest: all quality tests for all systems and objects
642  // iAllMon: all monitored systems and objects
643  int iAllQTest = 0;
644  int iAllMon = 0;
645 
646  // quality tests for all L1 systems
647 
648  for (unsigned int iTrackObj = 0; iTrackObj < m_nrTrackObjects; ++iTrackObj) {
649  // get the reports for each quality test
650 
651  const std::vector<std::string>& trackObjQtName = m_trackQualityTestName[iTrackObj];
652  const std::vector<std::string>& trackObjQtHist = m_trackQualityTestHist[iTrackObj];
653  const std::vector<unsigned int>& trackObjQtSummaryEnabled = m_trackQtSummaryEnabled[iTrackObj];
654 
655  // pro system counter for quality tests
656  int iTrackObjQTest = 0;
657 
658  for (const auto& itQtName : trackObjQtName) {
659  // get results, status and message
660 
661  if (m_verbose)
662  std::cout << " itQtName = " << (itQtName) << std::endl; // Extra printout - AWB 03.12.16
663 
664  MonitorElement* qHist = igetter.get(trackObjQtHist[iTrackObjQTest]);
665 
666  if (qHist) {
667  const std::vector<QReport*> qtVec = qHist->getQReports();
668 
669  // if (m_verbose) {
670  if (true) { // Force printout - AWB 03.12.16
671 
672  if (m_verbose)
673  std::cout << " - Number of quality tests"
674  // if (m_verbose) std::cout << "\nNumber of quality tests"
675  << " for histogram " << trackObjQtHist[iTrackObjQTest] << ": " << qtVec.size() << "\n"
676  << std::endl;
677  }
678 
679  const QReport* sysQReport = qHist->getQReport(itQtName);
680  if (sysQReport) {
681  const float trackObjQtResult = sysQReport->getQTresult();
682  const int trackObjQtStatus = sysQReport->getStatus();
683  const std::string& trackObjQtMessage = sysQReport->getMessage();
684 
685  if (m_verbose) {
686  std::cout << "\n"
687  << (itQtName) << " quality test:"
688  << "\n result: " << trackObjQtResult << "\n status: " << trackObjQtStatus
689  << "\n message: " << trackObjQtMessage << "\n"
690  << "\nFilling m_meReportSummaryContent[" << iAllQTest << "] with value " << trackObjQtResult
691  << "\n"
692  << std::endl;
693  }
694 
695  m_meReportSummaryContent[iAllQTest]->Fill(trackObjQtResult);
696 
697  // for the summary map, keep the highest status value ("ERROR") of all tests
698  // which are considered for the summary plot
699  if (trackObjQtSummaryEnabled[iTrackObjQTest]) {
700  if (trackObjQtStatus > m_summaryContent[iAllMon]) {
701  m_summaryContent[iAllMon] = trackObjQtStatus;
702  }
703 
704  m_summarySum += trackObjQtResult;
705  }
706 
707  } else {
708  // for the summary map, if the test was not found but it is assumed to be
709  // considered for the summary plot, set it to dqm::qstatus::INVALID
710 
711  int trackObjQtStatus = dqm::qstatus::INVALID;
712 
713  if (trackObjQtSummaryEnabled[iTrackObjQTest]) {
714  if (trackObjQtStatus > m_summaryContent[iAllMon]) {
715  m_summaryContent[iAllMon] = trackObjQtStatus;
716  }
717  }
718 
719  m_meReportSummaryContent[iAllQTest]->Fill(0.);
720 
721  if (m_verbose)
722  std::cout << "\n" << (itQtName) << " quality test not found\n" << std::endl;
723  }
724 
725  } else {
726  // for the summary map, if the histogram was not found but it is assumed
727  // to have a test be considered for the summary plot, set it to dqm::qstatus::INVALID
728 
729  int trackObjQtStatus = dqm::qstatus::INVALID;
730 
731  if (trackObjQtSummaryEnabled[iTrackObjQTest]) {
732  if (trackObjQtStatus > m_summaryContent[iAllMon]) {
733  m_summaryContent[iAllMon] = trackObjQtStatus;
734  }
735  }
736 
737  m_meReportSummaryContent[iAllQTest]->Fill(0.);
738 
739  if (m_verbose)
740  std::cout << "\nHistogram " << trackObjQtHist[iTrackObjQTest] << " not found\n" << std::endl;
741  }
742 
743  // increase counters for quality tests
744  iTrackObjQTest++;
745  iAllQTest++;
746  }
747 
748  iAllMon++;
749  }
750 
751  // quality tests for all L1 objects
752 
753  for (unsigned int iHitObj = 0; iHitObj < m_nrHitObjects; ++iHitObj) {
754  // get the reports for each quality test
755 
756  const std::vector<std::string>& hitObjQtName = m_hitQualityTestName[iHitObj];
757  const std::vector<std::string>& hitObjQtHist = m_hitQualityTestHist[iHitObj];
758  const std::vector<unsigned int>& hitObjQtSummaryEnabled = m_hitQtSummaryEnabled[iHitObj];
759 
760  // pro object counter for quality tests
761  int iHitObjQTest = 0;
762 
763  for (const auto& itQtName : hitObjQtName) {
764  // get results, status and message
765 
766  MonitorElement* qHist = igetter.get(hitObjQtHist[iHitObjQTest]);
767 
768  if (qHist) {
769  const std::vector<QReport*> qtVec = qHist->getQReports();
770 
771  if (m_verbose)
772  std::cout << "\nNumber of quality tests "
773  << " for histogram " << hitObjQtHist[iHitObjQTest] << ": " << qtVec.size() << "\n"
774  << std::endl;
775 
776  const QReport* objQReport = qHist->getQReport(itQtName);
777  if (objQReport) {
778  const float hitObjQtResult = objQReport->getQTresult();
779  const int hitObjQtStatus = objQReport->getStatus();
780  const std::string& hitObjQtMessage = objQReport->getMessage();
781 
782  if (m_verbose) {
783  std::cout << "\n"
784  << (itQtName) << " quality test:"
785  << "\n result: " << hitObjQtResult << "\n status: " << hitObjQtStatus
786  << "\n message: " << hitObjQtMessage << "\n"
787  << "\nFilling m_meReportSummaryContent[" << iAllQTest << "] with value " << hitObjQtResult << "\n"
788  << std::endl;
789  }
790 
791  m_meReportSummaryContent[iAllQTest]->Fill(hitObjQtResult);
792 
793  // for the summary map, keep the highest status value ("ERROR") of all tests
794  // which are considered for the summary plot
795  if (hitObjQtSummaryEnabled[iHitObjQTest]) {
796  if (hitObjQtStatus > m_summaryContent[iAllMon]) {
797  m_summaryContent[iAllMon] = hitObjQtStatus;
798  }
799 
800  m_summarySum += hitObjQtResult;
801  }
802 
803  } else {
804  // for the summary map, if the test was not found but it is assumed to be
805  // considered for the summary plot, set it to dqm::qstatus::INVALID
806 
807  int hitObjQtStatus = dqm::qstatus::INVALID;
808 
809  if (hitObjQtSummaryEnabled[iHitObjQTest]) {
810  if (hitObjQtStatus > m_summaryContent[iAllMon]) {
811  m_summaryContent[iAllMon] = hitObjQtStatus;
812  }
813  }
814 
815  m_meReportSummaryContent[iAllQTest]->Fill(0.);
816 
817  if (m_verbose)
818  std::cout << "\n" << (itQtName) << " quality test not found\n" << std::endl;
819  }
820 
821  } else {
822  // for the summary map, if the histogram was not found but it is assumed
823  // to have a test be considered for the summary plot, set it to dqm::qstatus::INVALID
824 
825  int hitObjQtStatus = dqm::qstatus::INVALID;
826 
827  if (hitObjQtSummaryEnabled[iHitObjQTest]) {
828  if (hitObjQtStatus > m_summaryContent[iAllMon]) {
829  m_summaryContent[iAllMon] = hitObjQtStatus;
830  }
831  }
832 
833  m_meReportSummaryContent[iAllQTest]->Fill(0.);
834 
835  if (m_verbose)
836  std::cout << "\nHistogram " << hitObjQtHist[iHitObjQTest] << " not found\n" << std::endl;
837  }
838  // increase counters for quality tests
839  iHitObjQTest++;
840  iAllQTest++;
841  }
842  iAllMon++;
843  }
844 
845  // quality tests for all L1 Noisy Strip =================================================================
846 
847  for (unsigned int iNoisyStrp = 0; iNoisyStrp < m_nrNoisyStrip; ++iNoisyStrp) {
848  // get the reports for each quality test
849  const std::vector<std::string>& noisyStrpQtName = m_noisyQualityTestName[iNoisyStrp];
850  const std::vector<std::string>& noisyStrpQtHist = m_noisyQualityTestHist[iNoisyStrp];
851  const std::vector<unsigned int>& noisyStrpQtSummaryEnabled = m_noisyQtSummaryEnabled[iNoisyStrp];
852 
853  // pro object counter for quality tests
854  int iNoisyStrpQTest = 0;
855 
856  for (const auto& itQtName : noisyStrpQtName) {
857  // get results, status and message
858  MonitorElement* qHist = igetter.get(noisyStrpQtHist[iNoisyStrpQTest]);
859 
860  if (qHist) {
861  const std::vector<QReport*> qtVec = qHist->getQReports();
862 
863  if (m_verbose)
864  std::cout << "\nNumber of quality tests "
865  << " for histogram " << noisyStrpQtHist[iNoisyStrpQTest] << ": " << qtVec.size() << "\n"
866  << std::endl;
867 
868  const QReport* objQReport = qHist->getQReport(itQtName);
869  if (objQReport) {
870  const float noisyStrpQtResult = objQReport->getQTresult();
871  const int noisyStrpQtStatus = objQReport->getStatus();
872  const std::string& noisyStrpQtMessage = objQReport->getMessage();
873 
874  if (m_verbose) {
875  std::cout << "\n"
876  << (itQtName) << " quality test:"
877  << "\n result: " << noisyStrpQtResult << "\n status: " << noisyStrpQtStatus
878  << "\n message: " << noisyStrpQtMessage << "\n"
879  << "\nFilling m_meReportSummaryContent[" << iAllQTest << "] with value " << noisyStrpQtResult
880  << "\n"
881  << std::endl;
882  }
883 
884  m_meReportSummaryContent[iAllQTest]->Fill(noisyStrpQtResult);
885 
886  // for the summary map, keep the highest status value ("ERROR") of all tests
887  // which are considered for the summary plot
888  if (noisyStrpQtSummaryEnabled[iNoisyStrpQTest]) {
889  if (noisyStrpQtStatus > m_summaryContent[iAllMon]) {
890  m_summaryContent[iAllMon] = noisyStrpQtStatus;
891  }
892  m_summarySum += noisyStrpQtResult;
893  }
894 
895  } else {
896  // for the summary map, if the test was not found but it is assumed to be
897  // considered for the summary plot, set it to dqm::qstatus::INVALID
898 
899  int noisyStrpQtStatus = dqm::qstatus::INVALID;
900 
901  if (noisyStrpQtSummaryEnabled[iNoisyStrpQTest]) {
902  if (noisyStrpQtStatus > m_summaryContent[iAllMon]) {
903  m_summaryContent[iAllMon] = noisyStrpQtStatus;
904  }
905  }
906 
907  m_meReportSummaryContent[iAllQTest]->Fill(0.);
908 
909  if (m_verbose)
910  std::cout << "\n" << (itQtName) << " quality test not found\n" << std::endl;
911  }
912 
913  } else {
914  // for the summary map, if the histogram was not found but it is assumed
915  // to have a test be considered for the summary plot, set it to dqm::qstatus::INVALID
916 
917  int noisyStrpQtStatus = dqm::qstatus::INVALID;
918 
919  if (noisyStrpQtSummaryEnabled[iNoisyStrpQTest]) {
920  if (noisyStrpQtStatus > m_summaryContent[iAllMon]) {
921  m_summaryContent[iAllMon] = noisyStrpQtStatus;
922  }
923  }
924 
925  m_meReportSummaryContent[iAllQTest]->Fill(0.);
926 
927  if (m_verbose)
928  std::cout << "\nHistogram " << noisyStrpQtHist[iNoisyStrpQTest] << " not found\n" << std::endl;
929  }
930  // increase counters for quality tests
931  iNoisyStrpQTest++;
932  iAllQTest++;
933  }
934  iAllMon++;
935  }
936  // quality tests for all L1 Dead Strip =================================================================
937 
938  for (unsigned int iDeadStrp = 0; iDeadStrp < m_nrDeadStrip; ++iDeadStrp) {
939  // get the reports for each quality test
940  const std::vector<std::string>& deadStrpQtName = m_deadQualityTestName[iDeadStrp];
941  const std::vector<std::string>& deadStrpQtHist = m_deadQualityTestHist[iDeadStrp];
942  const std::vector<unsigned int>& deadStrpQtSummaryEnabled = m_deadQtSummaryEnabled[iDeadStrp];
943 
944  // pro object counter for quality tests
945  int iDeadStrpQTest = 0;
946 
947  for (const auto& itQtName : deadStrpQtName) {
948  // get results, status and message
949 
950  MonitorElement* qHist = igetter.get(deadStrpQtHist[iDeadStrpQTest]);
951 
952  if (qHist) {
953  const std::vector<QReport*> qtVec = qHist->getQReports();
954 
955  if (m_verbose)
956  std::cout << "\nNumber of quality tests "
957  << " for histogram " << deadStrpQtHist[iDeadStrpQTest] << ": " << qtVec.size() << "\n"
958  << std::endl;
959 
960  const QReport* objQReport = qHist->getQReport(itQtName);
961  if (objQReport) {
962  const float deadStrpQtResult = objQReport->getQTresult();
963  const int deadStrpQtStatus = objQReport->getStatus();
964  const std::string& deadStrpQtMessage = objQReport->getMessage();
965 
966  if (m_verbose) {
967  std::cout << "\n"
968  << (itQtName) << " quality test:"
969  << "\n result: " << deadStrpQtResult << "\n status: " << deadStrpQtStatus
970  << "\n message: " << deadStrpQtMessage << "\n"
971  << "\nFilling m_meReportSummaryContent[" << iAllQTest << "] with value " << deadStrpQtResult
972  << "\n"
973  << std::endl;
974  }
975 
976  m_meReportSummaryContent[iAllQTest]->Fill(deadStrpQtResult);
977 
978  // for the summary map, keep the highest status value ("ERROR") of all tests
979  // which are considered for the summary plot
980  if (deadStrpQtSummaryEnabled[iDeadStrpQTest]) {
981  if (deadStrpQtStatus > m_summaryContent[iAllMon]) {
982  m_summaryContent[iAllMon] = deadStrpQtStatus;
983  }
984  m_summarySum += deadStrpQtResult;
985  }
986 
987  } else {
988  // for the summary map, if the test was not found but it is assumed to be
989  // considered for the summary plot, set it to dqm::qstatus::INVALID
990 
991  int deadStrpQtStatus = dqm::qstatus::INVALID;
992 
993  if (deadStrpQtSummaryEnabled[iDeadStrpQTest]) {
994  if (deadStrpQtStatus > m_summaryContent[iAllMon]) {
995  m_summaryContent[iAllMon] = deadStrpQtStatus;
996  }
997  }
998 
999  m_meReportSummaryContent[iAllQTest]->Fill(0.);
1000 
1001  if (m_verbose)
1002  std::cout << "\n" << (itQtName) << " quality test not found\n" << std::endl;
1003  }
1004 
1005  } else {
1006  // for the summary map, if the histogram was not found but it is assumed
1007  // to have a test be considered for the summary plot, set it to dqm::qstatus::INVALID
1008 
1009  int deadStrpQtStatus = dqm::qstatus::INVALID;
1010 
1011  if (deadStrpQtSummaryEnabled[iDeadStrpQTest]) {
1012  if (deadStrpQtStatus > m_summaryContent[iAllMon]) {
1013  m_summaryContent[iAllMon] = deadStrpQtStatus;
1014  }
1015  }
1016 
1017  m_meReportSummaryContent[iAllQTest]->Fill(0.);
1018 
1019  if (m_verbose)
1020  std::cout << "\nHistogram " << deadStrpQtHist[iDeadStrpQTest] << " not found\n" << std::endl;
1021  }
1022 
1023  // increase counters for quality tests
1024  iDeadStrpQTest++;
1025  iAllQTest++;
1026  }
1027  iAllMon++;
1028  }
1029 
1030  // reportSummary value
1032  if (m_meReportSummary) {
1034  }
1035 
1036  // fill the ReportSummaryMap for L1 systems (bin 1 on X)
1037  for (unsigned int iTrackObj = 0; iTrackObj < m_nrTrackObjects; ++iTrackObj) {
1038  double summCont = static_cast<double>(m_summaryContent[iTrackObj]);
1039  m_meReportSummaryMap->setBinContent(1, iTrackObj + 1, summCont);
1040  }
1041  // fill the ReportSummaryMap for L1 objects (bin 2 on X)
1042  for (unsigned int iMon = m_nrTrackObjects; iMon < m_nrTrackObjects + m_nrHitObjects; ++iMon) {
1043  double summCont = static_cast<double>(m_summaryContent[iMon]);
1044  m_meReportSummaryMap->setBinContent(2, iMon - m_nrTrackObjects + 1, summCont);
1045  }
1046 
1047  // fill the ReportSummaryMap_chamberStrip for L1 Noisy Strip (bin 1 on X)
1048  for (unsigned int iNoisyStrp = m_nrTrackObjects + m_nrHitObjects;
1050  ++iNoisyStrp) {
1051  double summCont = static_cast<double>(m_summaryContent[iNoisyStrp]);
1053  }
1054  // fill the ReportSummaryMap_chamberStrip for L1 objects (bin 2 on X)
1055  for (unsigned int iDeadStrp = m_nrTrackObjects + m_nrHitObjects + m_nrNoisyStrip;
1057  ++iDeadStrp) {
1058  double summCont = static_cast<double>(m_summaryContent[iDeadStrp]);
1060  2, iDeadStrp - m_nrTrackObjects - m_nrHitObjects - m_nrNoisyStrip + 1, summCont);
1061  }
1062 }
void readQtResults(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter)
read quality test results
std::vector< std::vector< std::string > > m_trackQualityTestName
virtual void setTitle(const std::string &title)
set (ie. change) histogram/profile title
std::vector< std::string > m_disableDeadStrip
MonitorElement * bookFloat(TString const &name, FUNC onbooking=NOOP())
Definition: DQMStore.h:80
std::vector< edm::ParameterSet > m_deadStrip
void book(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter)
book histograms
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
std::vector< std::string > m_disableTrackObjects
bool m_verbose
input parameters
float getQTresult() const
get test result i.e. prob value
std::vector< MonitorElementData::QReport * > getQReports() const
get map of QReports
void dqmEndLuminosityBlock(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter, const edm::LuminosityBlock &, const edm::EventSetup &) override
std::vector< std::string > m_noisyLabel
size_t m_nrHitObjects
number of L1 trigger objects
std::vector< std::vector< std::string > > m_deadQualityTestHist
std::vector< std::vector< unsigned int > > m_deadQtSummaryEnabled
std::vector< int > m_deadDisable
def replace(string, replacements)
std::vector< std::string > m_deadLabel
void dqmEndJob(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter) override
end job
std::vector< std::vector< std::string > > m_hitQualityTestName
void initialize()
private methods
void Fill(long long x)
std::vector< edm::ParameterSet > m_hitObjects
MonitorElement * m_meReportSummary
a summary report
std::vector< std::vector< std::string > > m_noisyQualityTestName
static const int INVALID
std::vector< std::vector< unsigned int > > m_trackQtSummaryEnabled
const MonitorElementData::QReport * getQReport(const std::string &qtname) const
get QReport corresponding to <qtname> (null pointer if QReport does not exist)
std::vector< std::vector< std::string > > m_trackQualityTestHist
std::vector< std::vector< std::string > > m_hitQualityTestHist
std::vector< MonitorElement * > m_meReportSummaryContent
monitor elements to report content for all quality tests
static const int DISABLED
size_t m_nrDeadStrip
number of L1 trigger dead strips
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)
std::vector< std::vector< unsigned int > > m_hitQtSummaryEnabled
~L1TEMTFEventInfoClient() override
Destructor.
void dumpContentMonitorElements(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter)
dump the content of the monitoring elements defined in this module
std::vector< std::string > m_disableHitObjects
MonitorElement * m_meReportSummaryMap_chamberStrip
std::vector< std::string > m_trackLabel
const std::string & getMessage() const
get message attached to test
std::vector< int > m_trackDisable
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
std::vector< std::vector< std::string > > m_noisyQualityTestHist
MonitorElement * m_meReportSummaryMap
report summary map
std::vector< std::vector< std::string > > m_deadQualityTestName
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:221
std::vector< std::string > m_hitLabel
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:712
L1TEMTFEventInfoClient(const edm::ParameterSet &)
Constructor.
std::vector< edm::ParameterSet > m_trackObjects
const std::string & getName() const
get name of ME
HLT enums.
Float_t m_reportSummary
summary report
std::vector< std::string > m_disableNoisyStrip
std::vector< int > m_noisyDisable
std::vector< int > m_summaryContent
int getStatus() const
get test status
std::vector< std::vector< unsigned int > > m_noisyQtSummaryEnabled
size_t m_nrTrackObjects
number of L1 trigger systems
std::vector< int > m_hitDisable
size_t m_nrNoisyStrip
number of L1 trigger noisy strips
std::vector< edm::ParameterSet > m_noisyStrip
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)