CMS 3D CMS Logo

CTPPSDiamondDQMSource.cc
Go to the documentation of this file.
1 /****************************************************************************
2 *
3 * This is a part of CTPPSDQM software.
4 * Authors:
5 * Jan Kašpar (jan.kaspar@gmail.com)
6 * Nicola Minafra
7 * Laurent Forthomme
8 * Christopher Misan
9 *
10 ****************************************************************************/
11 
20 
23 
28 
31 
34 
39 
40 #include <string>
41 
42 //----------------------------------------------------------------------------------------------------
43 
44 // Utility for efficiency computations
46  const CTPPSDiamondDetId& detid,
47  const CTPPSDiamondLocalTrack& localTrack,
48  const float tolerance = 1) {
49  const DetGeomDesc* det = geom->sensor(detid);
50  const float x_pos = det->translation().x(),
51  x_width = 2.0 * det->getDiamondDimensions().xHalfWidth; // parameters stand for half the size
52  return ((x_pos + 0.5 * x_width > localTrack.x0() - localTrack.x0Sigma() - tolerance &&
53  x_pos + 0.5 * x_width < localTrack.x0() + localTrack.x0Sigma() + tolerance) ||
54  (x_pos - 0.5 * x_width > localTrack.x0() - localTrack.x0Sigma() - tolerance &&
55  x_pos - 0.5 * x_width < localTrack.x0() + localTrack.x0Sigma() + tolerance) ||
56  (x_pos - 0.5 * x_width < localTrack.x0() - localTrack.x0Sigma() - tolerance &&
57  x_pos + 0.5 * x_width > localTrack.x0() + localTrack.x0Sigma() + tolerance));
58 }
59 
60 namespace dds {
61  struct Cache {
62  std::unordered_map<unsigned int, std::unique_ptr<TH2F>> hitDistribution2dMap;
63 
64  std::unordered_map<unsigned int, unsigned long> hitsCounterMap;
65  };
66 } // namespace dds
67 
68 class CTPPSDiamondDQMSource : public DQMOneEDAnalyzer<edm::LuminosityBlockCache<dds::Cache>> {
69 public:
71 
72 protected:
73  void dqmBeginRun(const edm::Run&, const edm::EventSetup&) override;
74  void dqmEndRun(edm::Run const&, edm::EventSetup const&) override;
75  void bookHistograms(DQMStore::IBooker&, const edm::Run&, const edm::EventSetup&) override;
76  void analyze(const edm::Event&, const edm::EventSetup&) override;
77  std::shared_ptr<dds::Cache> globalBeginLuminosityBlock(const edm::LuminosityBlock&,
78  const edm::EventSetup&) const override;
80 
81 private:
82  // Constants
84  static constexpr double SEC_PER_LUMI_SECTION = 23.31;
86  static constexpr unsigned short CHANNEL_OF_VFAT_CLOCK = 30;
91  static constexpr double HPTDC_BIN_WIDTH_NS = 25. / 1024;
92  static constexpr unsigned short CTPPS_PIXEL_STATION_ID = 2;
93  static constexpr unsigned short CTPPS_PIXEL_FAR_RP_ID = 3;
94  static constexpr unsigned short CTPPS_DIAMOND_CYL_STATION_ID = 1;
95  static constexpr unsigned short CTPPS_DIAMOND_CYL_RP_ID = 6;
96  static constexpr unsigned short CTPPS_DIAMOND_NUM_OF_CHANNELS = 12;
97  static constexpr unsigned short CTPPS_FED_ID_45 = 583;
98  static constexpr unsigned short CTPPS_FED_ID_56 = 582;
99  static constexpr unsigned short HPTDC_0_CHANNEL = 6;
100  static constexpr unsigned short HPTDC_1_CHANNEL = 7;
102  static constexpr unsigned int FIRST_RUN_W_PIXELS = 300000;
103 
104  bool perLSsaving_; //to avoid nanoDQMIO crashing, driven by DQMServices/Core/python/DQMStore_cfi.py
105 
107  struct GlobalPlots {
108  GlobalPlots() = default;
109  GlobalPlots(DQMStore::IBooker& ibooker);
110  };
112  struct SectorPlots {
113  // Tracks
118  SectorPlots(DQMStore::IBooker& ibooker, unsigned int id, bool plotOnline);
119  };
121  struct PotPlots {
122  std::unordered_map<unsigned int, MonitorElement*> activity_per_bx;
123 
129 
132 
133  std::unordered_map<unsigned int, MonitorElement*> pixelTomographyAll;
134 
137  MonitorElement* timeOverThresholdCumulativePot = nullptr; //, *leadingTrailingCorrelationPot = nullptr;
139 
141 
144 
146 
147  // MonitorElement* clock_Digi1_le = nullptr;
148  // MonitorElement* clock_Digi1_te = nullptr;
149  // MonitorElement* clock_Digi3_le = nullptr;
150  // MonitorElement* clock_Digi3_te = nullptr;
151 
153 
154  std::map<int, int> effTriplecountingChMap;
155  std::map<int, int> effDoublecountingChMap;
158 
159  // MonitorElement* TOTVsLS = nullptr;
160  // MonitorElement* trackTimeVsLS = nullptr;
162  // MonitorElement* trackTimeVsXAngle = nullptr;
163 
164  // MonitorElement* TOTVsLSProfile = nullptr;
165  // MonitorElement* trackTimeVsLSProfile = nullptr;
167  // MonitorElement* trackTimeVsXAngleProfile = nullptr;
168 
169  PotPlots() = default;
170  PotPlots(DQMStore::IBooker& ibooker,
171  unsigned int id,
172  unsigned int windowsNum,
173  bool plotOnline,
174  bool plotOffline,
175  bool perLSsaving);
176  };
178  struct PlanePlots {
182 
188 
190 
191  PlanePlots() = default;
192  PlanePlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
193  };
195  struct ChannelPlots {
196  std::unordered_map<unsigned int, MonitorElement*> activity_per_bx;
197 
202  //MonitorElement* LeadingTrailingCorrelationPerChannel = nullptr;
207 
209 
210  ChannelPlots() = default;
211  ChannelPlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
212  };
213 
214  void checkEventNumber(const CTPPSDiamondDetId&, const TotemFEDInfo&, const TotemVFATStatus&, PotPlots&, int&) const;
215 
222 
225 
227  const bool extract_digi_info_;
228  struct DiamondShifts {
230  };
231  std::unordered_map<CTPPSDetId, DiamondShifts> diamShifts_;
232  std::vector<std::pair<edm::EventRange, int>> runParameters_;
234  unsigned int verbosity_;
235  const bool plotOnline_;
236  const bool plotOffline_;
237  unsigned int windowsNum_;
239 
241  std::unordered_map<unsigned int, PotPlots> potPlots_;
242  std::unordered_map<unsigned int, SectorPlots> sectorPlots_;
243  std::unordered_map<unsigned int, PlanePlots> planePlots_;
244  std::unordered_map<unsigned int, ChannelPlots> channelPlots_;
245 
247 };
248 
249 //----------------------------------------------------------------------------------------------------
250 
252 
253 //----------------------------------------------------------------------------------------------------
254 
258  ibooker.setCurrentFolder(path);
259 
261 
262  trackCorrelation = ibooker.book2D("tracks correlation near-far",
263  title + " tracks correlation near-far;track x 220nr_hr (mm);track x 220cyl (mm)",
265  -1,
266  18,
268  -1,
269  18);
270  trackCorrelationLowMultiplicity = ibooker.book2D(
271  "tracks correlation with low multiplicity near-far",
272  title + " tracks correlation with low multiplicity near-far;track x 220nr_hr (mm);track x 220cyl(mm)",
274  -1,
275  18,
277  -1,
278  18);
279 }
280 
281 //----------------------------------------------------------------------------------------------------
283  unsigned int id,
284  unsigned int windowsNum,
285  bool plotOnline,
286  bool plotOffline,
287  bool perLSsaving)
288  : HitCounter(0),
289  MHCounter(0),
290  LeadingOnlyCounter(0),
291  TrailingOnlyCounter(0),
292  CompleteCounter(0),
293  pixelTracksMap("Pixel track maps for efficiency", "Pixel track maps for efficiency", 25, 0, 25, 16, -8, 8) {
296  ibooker.setCurrentFolder(path);
297 
299 
300  if (plotOnline) {
302  ibooker.book2D("hits in planes lumisection",
303  title + " hits in planes in the last lumisection;plane number;x (mm)",
304  10,
305  -0.5,
306  4.5,
308  -0.5,
309  18.5);
310 
312  ibooker.book2D("hits with OOT in planes (le only)",
313  title + " hits with OOT in planes (le only);plane number, OOT index;x (mm)",
314  1 + windowsNum * 4,
315  -1. / windowsNum,
316  4,
318  -0.5,
319  18.5);
320 
322  ibooker.book1D("active planes inclusive",
323  title + " active planes, MH and le only included (per event);number of active planes",
324  6,
325  -0.5,
326  5.5);
327 
328  ECCheck = ibooker.book1D("optorxEC(8bit) - vfatEC", title + " EC Error;optorxEC-vfatEC", 50, -25, 25);
329 
331  ibooker.book2D("Efficiency in channels",
332  title + " Efficiency (%) in channels (diamonds only);plane number;ch number",
333  10,
334  -0.5,
335  4.5,
336  14,
337  -1,
338  13);
339  }
340 
341  if (plotOffline && !perLSsaving) {
342  ibooker.setCurrentFolder(path + "/timing_profiles");
343  // TOTVsLS=ibooker.book2D("ToT vs LS",title +" ToT vs LS;LS;ToT(ns)",4000,0,4000, 200,5,25);
344  // trackTimeVsLS=ibooker.book2D("track time vs LS",title+" track time vs LS;LS;track_time(ns)",4000,0,4000, 500, -25, 25);
345  trackTimeVsBX =
346  ibooker.book2D("track time vs BX", title + " track time vs BX;BX;track_time(ns)", 4000, 0, 4000, 500, -25, 25);
347  // trackTimeVsXAngle = ibooker.book2D(
348  // "track time vs xangle", title + " track time vs xangle;xangle;track_time(ns)", 60, 120, 180, 500, -25, 25);
349 
350  // TOTVsLSProfile=ibooker.bookProfile("ToT vs LS profile",title+" ToT vs LS profile;LS;track_time(ns)", 500, -25, 25,4000,0,4000);
351  // trackTimeVsLSProfile=ibooker.bookProfile("track time vs LS profile",title+" track time vs LS profile;LS;track_time(ns)", 500, -25, 25,4000,0,4000);
353  "track time vs BX profile", title + " track time vs BX profile;BX;track_time(ns)", 500, -25, 25, 4000, 0, 4000);
354  // trackTimeVsXAngleProfile = ibooker.bookProfile("track time vs xangle profile",
355  // title + " track time vs xangle profile;xangle;track_time(ns)",
356  // 500,
357  // -25,
358  // 25,
359  // 60,
360  // 120,
361  // 180);
362  ibooker.setCurrentFolder(path);
363  }
364 
365  for (unsigned int i = 0; i < windowsNum; i++) {
366  std::string window = std::to_string(i * 25) + "-" + std::to_string((i + 1) * 25);
367  activity_per_bx[i] = ibooker.book1D(
368  "activity per BX " + window, title + " Activity per BX " + window + " ns;Event.BX", 3600, -1.5, 3598. + 0.5);
370  ibooker.book2D("tomography pixel " + window,
371  title + " tomography with pixel " + window + " ns (all planes);x + 25*plane(mm);y (mm)",
372  100,
373  0,
374  100,
375  10,
376  -5,
377  5);
378  }
379 
380  hitDistribution2d = ibooker.book2D("hits in planes",
381  title + " hits in planes;plane number;x (mm)",
382  10,
383  -0.5,
384  4.5,
386  -0.5,
387  18.5);
388 
389  hitDistribution2dOOT = ibooker.book2D("hits with OOT in planes",
390  title + " hits with OOT in planes;plane number, OOT index;x (mm)",
391  1 + windowsNum * 4,
392  -1. / windowsNum,
393  4,
395  -0.5,
396  18.5);
397 
398  { // bin labelling (for clarity)
399  int idx = 2; // start counting at 1, first bin is empty
400  for (int pl = 0; pl < 4; ++pl)
401  for (unsigned int oot = 0; oot < windowsNum; ++oot) {
402  const std::string bin_label =
403  (oot == 0 ? "Plane " + std::to_string(pl) + ", " : "") + "OOT" + std::to_string(oot);
404  hitDistribution2dOOT->setBinLabel(idx, bin_label);
405  if (plotOnline)
407  ++idx;
408  }
409  }
410 
411  recHitTime = ibooker.book1D("recHit time", title + " recHit time; t (ns)", 500, -25, 25);
412 
413  activePlanes =
414  ibooker.book1D("active planes", title + " active planes (per event);number of active planes", 6, -0.5, 5.5);
415 
417  ibooker.book1D("tracks", title + " tracks;x (mm)", 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5);
418  trackDistributionOOT = ibooker.book2D("tracks with OOT",
419  title + " tracks with OOT;plane number;x (mm)",
420  9,
421  -0.5,
422  4,
424  -0.5,
425  18.5);
426 
427  leadingEdgeCumulative_both = ibooker.book1D("leading edge (le and te)",
428  title + " leading edge (le and te) (recHits); leading edge (ns)",
429  25 * windowsNum,
430  0,
431  25 * windowsNum);
432  leadingEdgeCumulative_all = ibooker.book1D("leading edge (all)",
433  title + " leading edge (with or without te) (DIGIs); leading edge (ns)",
434  25 * windowsNum,
435  0,
436  25 * windowsNum);
437  leadingEdgeCumulative_le = ibooker.book1D("leading edge (le only)",
438  title + " leading edge (le only) (DIGIs); leading edge (ns)",
439  25 * windowsNum,
440  0,
441  25 * windowsNum);
442  trailingEdgeCumulative_te = ibooker.book1D("trailing edge (te only)",
443  title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
444  25 * windowsNum,
445  0,
446  25 * windowsNum);
448  ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 250, -25, 100);
449  // leadingTrailingCorrelationPot =
450  // ibooker.book2D("leading trailing correlation",
451  // title + " leading trailing correlation;leading edge (ns);trailing edge (ns)",
452  // 75,
453  // 0,
454  // 75,
455  // 75,
456  // 0,
457  // 75);
458 
460  ibooker.book1D("event category", title + " leading edges without trailing;;%", 3, 0.5, 3.5);
464 
465  HPTDCErrorFlags_2D = ibooker.book2D("HPTDC Errors", title + " HPTDC Errors", 16, -0.5, 16.5, 9, -0.5, 8.5);
466  for (unsigned short error_index = 1; error_index < 16; ++error_index)
467  HPTDCErrorFlags_2D->setBinLabel(error_index, HPTDCErrorFlags::hptdcErrorName(error_index - 1));
468  HPTDCErrorFlags_2D->setBinLabel(16, "Wrong EC");
469 
470  int tmpIndex = 0;
471  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 18", /* axis */ 2);
472  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 17", /* axis */ 2);
473  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 16", /* axis */ 2);
474  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 15", /* axis */ 2);
475  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 18", /* axis */ 2);
476  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 17", /* axis */ 2);
477  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 16", /* axis */ 2);
478  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 15", /* axis */ 2);
479 
480  MHComprensive =
481  ibooker.book2D("MH in channels", title + " MH (%) in channels;plane number;ch number", 10, -0.5, 4.5, 14, -1, 13);
482 
483  // ibooker.setCurrentFolder( path+"/clock/" );
484  // clock_Digi1_le = ibooker.book1D( "clock1 leading edge", title+" clock1;leading edge (ns)", 250, 0, 25 );
485  // clock_Digi1_te = ibooker.book1D( "clock1 trailing edge", title+" clock1;trailing edge (ns)", 75, 0, 75 );
486  // clock_Digi3_le = ibooker.book1D( "clock3 leading edge", title+" clock3;leading edge (ns)", 250, 0, 25 );
487  // clock_Digi3_te = ibooker.book1D( "clock3 trailing edge", title+" clock3;trailing edge (ns)", 75, 0, 75 );
488 }
489 
490 //----------------------------------------------------------------------------------------------------
491 
493  : pixelTracksMapWithDiamonds("Pixel track maps for efficiency with coincidence",
494  "Pixel track maps for efficiency with coincidence",
495  25,
496  0,
497  25,
498  16,
499  -8,
500  8) {
503  ibooker.setCurrentFolder(path);
504 
506 
507  digiProfileCumulativePerPlane = ibooker.book1D("digi profile",
508  title + " digi profile; ch number",
510  -0.5,
512  hitProfile = ibooker.book1D(
513  "hit profile", title + " hit profile;x (mm)", 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5);
514  hit_multiplicity = ibooker.book1D("channels per plane", title + " channels per plane; ch per plane", 13, -0.5, 12.5);
515 
516  leadingEdgeCumulativePerPlane_both = ibooker.book1D("leading edge (le and te)",
517  title + " leading edge (le and te) (recHits); leading edge (ns)",
518  25 * windowsNum,
519  0,
520  25 * windowsNum);
521  leadingEdgeCumulativePerPlane_le = ibooker.book1D("leading edge (le only)",
522  title + " leading edge (le only) (DIGIs); leading edge (ns)",
523  25 * windowsNum,
524  0,
525  25 * windowsNum);
526  trailingEdgeCumulativePerPlane_te = ibooker.book1D("trailing edge (te only)",
527  title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
528  25 * windowsNum,
529  0,
530  25 * windowsNum);
532  ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 75, -25, 50);
533 
534  pixelTomography_far = ibooker.book2D("tomography pixel",
535  title + " tomography with pixel;x + 25 OOT (mm);y (mm)",
536  25 * windowsNum,
537  0,
538  25 * windowsNum,
539  16,
540  -8,
541  8);
543  ibooker.book2D("Efficiency wrt pixels", title + " Efficiency wrt pixels;x (mm);y (mm)", 25, 0, 25, 16, -8, 8);
544 }
545 
546 //----------------------------------------------------------------------------------------------------
547 
549  : HitCounter(0), MHCounter(0), LeadingOnlyCounter(0), TrailingOnlyCounter(0), CompleteCounter(0) {
552  ibooker.setCurrentFolder(path);
553 
555 
556  leadingWithoutTrailing = ibooker.book1D("event category", title + " Event Category;;%", 3, 0.5, 3.5);
557  leadingWithoutTrailing->setBinLabel(1, "Leading only");
558  leadingWithoutTrailing->setBinLabel(2, "Trailing only");
560 
561  for (unsigned int i = 0; i < windowsNum; i++) {
562  std::string window = std::to_string(i * 25) + "-" + std::to_string((i + 1) * 25);
563  activity_per_bx[i] = ibooker.book1D(
564  "activity per BX " + window, title + " Activity per BX " + window + " ns;Event.BX", 3600, -1.5, 3598. + 0.5);
565  }
566 
567  HPTDCErrorFlags = ibooker.book1D("hptdc_Errors", title + " HPTDC Errors", 16, -0.5, 16.5);
568  for (unsigned short error_index = 1; error_index < 16; ++error_index)
569  HPTDCErrorFlags->setBinLabel(error_index, HPTDCErrorFlags::hptdcErrorName(error_index - 1));
570  HPTDCErrorFlags->setBinLabel(16, "MH (%)");
571 
572  leadingEdgeCumulative_both = ibooker.book1D("leading edge (le and te)",
573  title + " leading edge (le and te) (recHits); leading edge (ns)",
574  25 * windowsNum,
575  0,
576  25 * windowsNum);
577  leadingEdgeCumulative_le = ibooker.book1D("leading edge (le only)",
578  title + " leading edge (le only) (DIGIs); leading edge (ns)",
579  25 * windowsNum,
580  0,
581  25 * windowsNum);
582  trailingEdgeCumulative_te = ibooker.book1D("trailing edge (te only)",
583  title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
584  25 * windowsNum,
585  0,
586  25 * windowsNum);
588  ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 75, -25, 50);
589  // LeadingTrailingCorrelationPerChannel =
590  // ibooker.book2D("leading trailing correlation",
591  // title + " leading trailing correlation;leading edge (ns);trailing edge (ns)",
592  // 75,
593  // 0,
594  // 75,
595  // 75,
596  // 0,
597  // 75);
598 
599  pixelTomography_far = ibooker.book2D("tomography pixel",
600  "tomography with pixel;x + 25 OOT (mm);y (mm)",
601  25 * windowsNum,
602  0,
603  25 * windowsNum,
604  16,
605  -8,
606  8);
607 
608  hit_rate = ibooker.book1D("hit rate", title + "hit rate;rate (Hz)", 40, 0, 20);
609 
610  recHitTime = ibooker.book1D("recHit Time", title + " recHit Time; t (ns)", 500, -25, 25);
611 }
612 
613 //----------------------------------------------------------------------------------------------------
614 
616  : perLSsaving_(ps.getUntrackedParameter<bool>("perLSsaving", false)),
618  ps.getUntrackedParameter<edm::InputTag>("tagPixelLocalTracks"))),
620  ps.getUntrackedParameter<edm::InputTag>("tagDiamondRecHits"))),
622  ps.getUntrackedParameter<edm::InputTag>("tagDiamondLocalTracks"))),
625  excludeMultipleHits_(ps.getParameter<bool>("excludeMultipleHits")),
626  extract_digi_info_(ps.getParameter<bool>("extractDigiInfo")),
627  centralOOT_(-999),
628  verbosity_(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
629  plotOnline_(ps.getUntrackedParameter<bool>("plotOnline", true)),
630  plotOffline_(ps.getUntrackedParameter<bool>("plotOffline", false)),
631  windowsNum_(ps.getUntrackedParameter<unsigned int>("windowsNum", 3)),
632  trackCorrelationThreshold_(ps.getUntrackedParameter<unsigned int>("trackCorrelationThreshold", 3)),
633  EC_difference_56_(-500),
634  EC_difference_45_(-500) {
635  if (extract_digi_info_) {
636  tokenStatus_ = consumes<edm::DetSetVector<TotemVFATStatus>>(ps.getUntrackedParameter<edm::InputTag>("tagStatus"));
637  tokenFEDInfo_ = consumes<std::vector<TotemFEDInfo>>(ps.getUntrackedParameter<edm::InputTag>("tagFEDInfo"));
638  tokenDigi_ = consumes<edm::DetSetVector<CTPPSDiamondDigi>>(ps.getUntrackedParameter<edm::InputTag>("tagDigi"));
639  }
640  for (const auto& pset : ps.getParameter<std::vector<edm::ParameterSet>>("offsetsOOT")) {
641  runParameters_.emplace_back(
642  std::make_pair(pset.getParameter<edm::EventRange>("validityRange"), pset.getParameter<int>("centralOOT")));
643  }
644 }
645 
646 //----------------------------------------------------------------------------------------------------
647 
649  centralOOT_ = -999;
650  for (const auto& oot : runParameters_) {
651  if (edm::contains(oot.first, edm::EventID(iRun.run(), 0, 1))) {
652  centralOOT_ = oot.second;
653  break;
654  }
655  }
656 
657  // Get detector shifts from the geometry
659  for (auto it = geom.beginRP(); it != geom.endRP(); ++it)
660  if (CTPPSDiamondDetId::check(it->first)) {
661  const CTPPSDiamondDetId diam_id(it->first);
662  const auto diam = geom.sensor(it->first);
663  diamShifts_[diam_id].global = diam->translation().x() - diam->getDiamondDimensions().xHalfWidth;
664  if (iRun.run() > FIRST_RUN_W_PIXELS) { // pixel installed
666  auto pix = geom.sensor(pixid);
667  // Rough alignement of pixel detector for diamond tomography
668  diamShifts_[diam_id].withPixels =
669  pix->translation().x() - pix->getDiamondDimensions().xHalfWidth - diamShifts_[diam_id].global - 1.;
670  }
671  }
672 }
673 
674 //----------------------------------------------------------------------------------------------------
675 
677  ibooker.cd();
678  ibooker.setCurrentFolder("CTPPS");
679 
680  globalPlot_ = GlobalPlots(ibooker);
681 
682  // book plots from the geometry
684  for (auto it = geom.beginSensor(); it != geom.endSensor(); ++it) {
685  if (!CTPPSDiamondDetId::check(it->first))
686  continue;
687  // per-channel plots
688  const CTPPSDiamondDetId chId(it->first);
689  if (plotOnline_ && channelPlots_.count(chId) == 0)
690  channelPlots_[chId] = ChannelPlots(ibooker, chId, windowsNum_);
691 
692  // per-plane plots
693  const CTPPSDiamondDetId plId(chId.planeId());
694  if (planePlots_.count(plId) == 0)
695  planePlots_[plId] = PlanePlots(ibooker, plId, windowsNum_);
696  // per-pot plots
697  const CTPPSDiamondDetId rpId(chId.rpId());
698  if (potPlots_.count(rpId) == 0)
700 
701  // per-sector plots
702  const CTPPSDiamondDetId secId(chId.armId());
703  if (plotOffline_ && sectorPlots_.count(secId) == 0)
704  sectorPlots_[secId] = SectorPlots(ibooker, secId, plotOnline_);
705  }
706 }
707 
708 //----------------------------------------------------------------------------------------------------
709 
711  const edm::EventSetup&) const {
712  auto d = std::make_shared<dds::Cache>();
713  d->hitDistribution2dMap.reserve(potPlots_.size());
714  if (!perLSsaving_ && plotOnline_) {
715  for (auto& plot : potPlots_) {
716  d->hitDistribution2dMap[plot.first] = std::make_unique<TH2F>(
717  "hits in planes lumisection",
718  (std::string(plot.second.hitDistribution2d_lumisection->getTH2F()->GetTitle()) + ";plane number;x (mm)")
719  .c_str(),
720  10,
721  -0.5,
722  4.5,
724  -0.5,
725  18.5);
726  }
727  }
728  return d;
729 }
730 
731 //----------------------------------------------------------------------------------------------------
732 
734  // get event data
735 
739  if (extract_digi_info_) {
740  event.getByToken(tokenStatus_, diamondVFATStatus);
741  event.getByToken(tokenDigi_, diamondDigis);
742  event.getByToken(tokenFEDInfo_, fedInfo);
743  }
744 
746  event.getByToken(tokenPixelTrack_, pixelTracks);
747 
749  event.getByToken(tokenDiamondHit_, diamondRecHits);
750 
752  event.getByToken(tokenDiamondTrack_, diamondLocalTracks);
753 
754  const CTPPSGeometry* ctppsGeometry = &iSetup.getData(ctppsGeometryEventToken_);
755 
756  // check validity
757  bool valid = true;
758  if (extract_digi_info_) { // drop DIGI-level validity checks if not monitored
759  valid &= diamondVFATStatus.isValid();
760  valid &= diamondDigis.isValid();
761  valid &= fedInfo.isValid();
762  }
763  valid &= pixelTracks.isValid();
764  valid &= diamondRecHits.isValid();
765  valid &= diamondLocalTracks.isValid();
766 
767  if (!valid) {
768  if (verbosity_)
769  edm::LogProblem("CTPPSDiamondDQMSource")
770  << "ERROR in CTPPSDiamondDQMSource::analyze > some of the required inputs are not valid. Skipping this "
771  "event.\n"
772  << " DIGI-level: (checked? " << std::boolalpha << extract_digi_info_ << ")\n"
773  << " diamondVFATStatus.isValid = " << diamondVFATStatus.isValid() << "\n"
774  << " diamondDigis.isValid = " << diamondDigis.isValid() << "\n"
775  << " fedInfo.isValid = " << fedInfo.isValid() << "\n"
776  << " RECO-level:\n"
777  << " pixelTracks.isValid = " << pixelTracks.isValid() << "\n"
778  << " diamondRecHits.isValid = " << diamondRecHits.isValid() << "\n"
779  << " diamondLocalTracks.isValid = " << diamondLocalTracks.isValid();
780  return;
781  }
782 
783  //------------------------------
784  // Sector Plots
785  //------------------------------
786  // Using CTPPSDiamondLocalTrack
787  if (plotOffline_)
788 
789  // diamond timing detectors are located in:
790  // - 220cyl: "cylindrical pot" station (id=1), in horizontal Roman Pot with id=6 ("far")
791  // - 220nr_hr: "220m" station (id=2), in horizontal Roman Pot with id=2 ("near horizontal")
792 
793  for (const auto& tracks_220nr_hr : *diamondLocalTracks) {
794  // to preprare correlation plot, we need to select tracks from nr_hr pot in 220m station
795  const CTPPSDiamondDetId detId_220nr_hr(tracks_220nr_hr.detId());
796 
797  // selecting only tracks from 220nr station, realised as skipping tracks from 220cyl station
798  if ((detId_220nr_hr.rp() == CTPPS_DIAMOND_CYL_RP_ID) &&
799  (detId_220nr_hr.station() == CTPPS_DIAMOND_CYL_STATION_ID))
800  continue;
801 
802  if (potPlots_.count(detId_220nr_hr.rpId()) == 0)
803  continue;
804  TH1F* trackHistoInTimeTmp = potPlots_[detId_220nr_hr.rpId()].trackDistribution->getTH1F();
805 
806  for (const auto& track_220nr_hr : tracks_220nr_hr) {
807  if (!track_220nr_hr.isValid())
808  continue;
809 
810  // get the bins from per-pot plots
811  int startBin_220nr_hr = trackHistoInTimeTmp->FindBin(
812  track_220nr_hr.x0() - diamShifts_[detId_220nr_hr.rpId()].global - track_220nr_hr.x0Sigma());
813  int numOfBins_220nr_hr = 2 * track_220nr_hr.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
814 
815  for (const auto& tracks_220cyl : *diamondLocalTracks) {
816  CTPPSDiamondDetId detId_220cyl(tracks_220cyl.detId());
817 
818  // select tracks in the same arm, but belonging to the cylindrical pot
819  // that means skipping tracks from the opposite arm (skip if 220nr_hr.arm != 220cyl.arm)
820  // and skipping tracks from the 220nr_hr pot (skip if 220nr_hr == 220cyl.station)
821  if (detId_220nr_hr.arm() != detId_220cyl.arm() || detId_220nr_hr.station() == detId_220cyl.station())
822  continue;
823 
824  if (sectorPlots_.count(detId_220cyl.armId()) == 0)
825  continue;
826 
827  TH2F* trackHistoTmp = sectorPlots_[detId_220cyl.armId()].trackCorrelation->getTH2F();
828  TAxis* trackHistoTmpXAxis = trackHistoTmp->GetXaxis();
829  TAxis* trackHistoTmpYAxis = trackHistoTmp->GetYaxis();
830 
831  for (const auto& track_220cyl : tracks_220cyl) {
832  if (!track_220cyl.isValid())
833  continue;
834  int startBin_220cyl = trackHistoTmpYAxis->FindBin(
835  track_220cyl.x0() - diamShifts_[detId_220cyl.rpId()].global - track_220cyl.x0Sigma());
836  int numOfBins_220cyl = 2 * track_220cyl.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
837 
838  // fill the correlation plot
839  for (int i = 0; i < numOfBins_220nr_hr; ++i)
840  for (int y = 0; y < numOfBins_220cyl; ++y) {
841  float track_220nr_hr_x = trackHistoTmpXAxis->GetBinCenter(startBin_220nr_hr + i);
842  float track_220cyl_x = trackHistoTmpYAxis->GetBinCenter(startBin_220cyl + y);
843  trackHistoTmp->Fill(track_220nr_hr_x, track_220cyl_x);
844  // fill low multiplicity histogram
845  if (tracks_220nr_hr.size() < 3 && tracks_220cyl.size() < trackCorrelationThreshold_)
846  sectorPlots_[detId_220cyl.armId()].trackCorrelationLowMultiplicity->Fill(track_220nr_hr_x,
847  track_220cyl_x);
848  }
849  }
850  }
851  }
852  }
853 
854  //------------------------------
855  // RP Plots
856  //------------------------------
857 
858  //------------------------------
859  // Correlation Plots
860  //------------------------------
861 
862  if (extract_digi_info_) {
863  // Using CTPPSDiamondDigi
864  for (const auto& digis : *diamondDigis) {
865  const CTPPSDiamondDetId detId(digis.detId()), detId_pot(detId.rpId());
866  for (const auto& digi : digis) {
867  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
868  continue;
869  if (potPlots_.count(detId_pot) == 0)
870  continue;
871  //Leading without trailing investigation
872  if (digi.leadingEdge() != 0 || digi.trailingEdge() != 0) {
873  ++potPlots_[detId_pot].HitCounter;
874  if (digi.leadingEdge() != 0) {
875  potPlots_[detId_pot].leadingEdgeCumulative_all->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
876  }
877  if (digi.leadingEdge() != 0 && digi.trailingEdge() == 0) {
878  ++potPlots_[detId_pot].LeadingOnlyCounter;
879  potPlots_[detId_pot].leadingEdgeCumulative_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
880  }
881  if (digi.leadingEdge() == 0 && digi.trailingEdge() != 0) {
882  ++potPlots_[detId_pot].TrailingOnlyCounter;
883  potPlots_[detId_pot].trailingEdgeCumulative_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
884  }
885  if (digi.leadingEdge() != 0 && digi.trailingEdge() != 0) {
886  ++potPlots_[detId_pot].CompleteCounter;
887  // potPlots_[detId_pot].leadingTrailingCorrelationPot->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge(),
888  // HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
889  }
890  }
891 
892  // HPTDC Errors
893  const HPTDCErrorFlags hptdcErrors = digi.hptdcErrorFlags();
894  if (detId.channel() == HPTDC_0_CHANNEL ||
895  detId.channel() == HPTDC_1_CHANNEL) { // ch6 for HPTDC 0 and ch7 for HPTDC 1
896  int verticalIndex = 2 * detId.plane() + (detId.channel() - HPTDC_0_CHANNEL);
897  for (unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex)
898  if (hptdcErrors.errorId(hptdcErrorIndex - 1))
899  potPlots_[detId_pot].HPTDCErrorFlags_2D->Fill(hptdcErrorIndex, verticalIndex);
900  }
901  if (digi.multipleHit())
902  ++potPlots_[detId_pot].MHCounter;
903  }
904  }
905  }
906 
907  // EC Errors
908  if (extract_digi_info_) {
909  for (const auto& vfat_status : *diamondVFATStatus) {
910  const CTPPSDiamondDetId detId(vfat_status.detId());
911  for (const auto& status : vfat_status) {
912  if (!status.isOK())
913  continue;
914  if (potPlots_.count(detId.rpId()) == 0)
915  continue;
916  if (channelPlots_.count(detId) == 0)
917  continue;
918 
919  // Check Event Number
920  for (const auto& optorx : *fedInfo) {
921  if (detId.arm() == 1 && optorx.fedId() == CTPPS_FED_ID_56)
923  else if (detId.arm() == 0 && optorx.fedId() == CTPPS_FED_ID_45)
925  }
926  }
927  }
928  }
929 
930  // Using CTPPSDiamondRecHit
931  std::unordered_map<unsigned int, std::set<unsigned int>> planes;
932  std::unordered_map<unsigned int, std::set<unsigned int>> planes_inclusive;
933 
934  auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
935  for (const auto& rechits : *diamondRecHits) {
936  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
937  const auto& x_shift = diamShifts_.at(detId_pot);
938 
939  for (const auto& rechit : rechits) {
940  planes_inclusive[detId_pot].insert(detId.plane());
941  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
942  continue;
943  if (rechit.toT() != 0 && centralOOT_ != -999 && rechit.ootIndex() == centralOOT_)
944  planes[detId_pot].insert(detId.plane());
945 
946  if (potPlots_.count(detId_pot) == 0)
947  continue;
948 
949  potPlots_[detId_pot].recHitTime->Fill(rechit.time());
950 
951  float UFSDShift = 0.0;
952  if (rechit.yWidth() < 3)
953  UFSDShift = 0.5; // Display trick for UFSD that have 2 pixels with same X
954 
955  if (rechit.toT() != 0 && centralOOT_ != -999 && rechit.ootIndex() == centralOOT_) {
956  TH2F* hitHistoTmp = potPlots_[detId_pot].hitDistribution2d->getTH2F();
957  TAxis* hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
958  int startBin = hitHistoTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
959  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
960  for (int i = 0; i < numOfBins; ++i)
961  hitHistoTmp->Fill(detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin + i));
962 
963  if (!perLSsaving_ && plotOnline_) {
964  hitHistoTmp = lumiCache->hitDistribution2dMap[detId_pot].get();
965  hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
966  startBin = hitHistoTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
967  numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
968  for (int i = 0; i < numOfBins; ++i)
969  hitHistoTmp->Fill(detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin + i));
970  }
971  }
972 
973  if (rechit.toT() > 0) {
974  // Both
975  potPlots_[detId_pot].leadingEdgeCumulative_both->Fill(rechit.time() + 25 * rechit.ootIndex());
976  potPlots_[detId_pot].timeOverThresholdCumulativePot->Fill(rechit.toT());
977 
978  TH2F* hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT->getTH2F();
979  TAxis* hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
980  int startBin = hitHistoOOTTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
981  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
982  for (int i = 0; i < numOfBins; ++i)
983  hitHistoOOTTmp->Fill(detId.plane() + 1. / windowsNum_ * rechit.ootIndex(),
984  hitHistoOOTTmpYAxis->GetBinCenter(startBin + i));
985 
986  } else if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && plotOnline_) {
987  // Only leading
988  TH2F* hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT_le->getTH2F();
989  TAxis* hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
990  int startBin = hitHistoOOTTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
991  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
992  for (int i = 0; i < numOfBins; ++i)
993  hitHistoOOTTmp->Fill(detId.plane() + 1. / windowsNum_ * rechit.ootIndex(),
994  hitHistoOOTTmpYAxis->GetBinCenter(startBin + i));
995  }
996  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING &&
997  potPlots_[detId_pot].activity_per_bx.count(rechit.ootIndex()) > 0)
998  potPlots_[detId_pot].activity_per_bx.at(rechit.ootIndex())->Fill(event.bunchCrossing());
999 
1000  // if(plotOffline_)
1001  // potPlots_[detId_pot].TOTVsLS->Fill(event.luminosityBlock(),rechit.toT());
1002  }
1003  }
1004 
1005  for (const auto& plt : potPlots_) {
1006  plt.second.activePlanes->Fill(planes[plt.first].size());
1007  if (plotOnline_)
1008  plt.second.activePlanesInclusive->Fill(planes_inclusive[plt.first].size());
1009  }
1010 
1011  // Using CTPPSDiamondLocalTrack
1012  for (const auto& tracks : *diamondLocalTracks) {
1013  const CTPPSDiamondDetId detId(tracks.detId()), detId_pot(detId.rpId());
1014  const auto& x_shift = diamShifts_.at(detId_pot);
1015 
1016  for (const auto& track : tracks) {
1017  if (!track.isValid())
1018  continue;
1020  continue;
1021  if (excludeMultipleHits_ && track.multipleHits() > 0)
1022  continue;
1023  if (potPlots_.count(detId_pot) == 0)
1024  continue;
1025 
1026  TH2F* trackHistoOOTTmp = potPlots_[detId_pot].trackDistributionOOT->getTH2F();
1027  TAxis* trackHistoOOTTmpYAxis = trackHistoOOTTmp->GetYaxis();
1028  int startBin = trackHistoOOTTmpYAxis->FindBin(track.x0() - x_shift.global - track.x0Sigma());
1029  int numOfBins = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
1030  for (int i = 0; i < numOfBins; ++i)
1031  trackHistoOOTTmp->Fill(track.ootIndex(), trackHistoOOTTmpYAxis->GetBinCenter(startBin + i));
1032 
1033  if (centralOOT_ != -999 && track.ootIndex() == centralOOT_) {
1034  TH1F* trackHistoInTimeTmp = potPlots_[detId_pot].trackDistribution->getTH1F();
1035  int startBin = trackHistoInTimeTmp->FindBin(track.x0() - x_shift.global - track.x0Sigma());
1036  int numOfBins = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
1037  for (int i = 0; i < numOfBins; ++i)
1038  trackHistoInTimeTmp->Fill(trackHistoInTimeTmp->GetBinCenter(startBin + i));
1039  }
1040  if (plotOffline_ && !perLSsaving_) {
1041  // potPlots_[detId_pot].trackTimeVsLS->Fill(event.luminosityBlock(),track.time());
1042  potPlots_[detId_pot].trackTimeVsBX->Fill(event.bunchCrossing(), track.time());
1043  }
1044  }
1045  }
1046 
1047  // Channel efficiency using CTPPSDiamondLocalTrack
1048  for (const auto& tracks : *diamondLocalTracks) {
1049  const CTPPSDiamondDetId detId(tracks.detId()), detId_pot(detId.rpId());
1050  for (const auto& track : tracks) {
1051  // Find hits and planes in the track
1052  int numOfHits = 0;
1053  std::set<int> planesInTrackSet;
1054  for (const auto& vec : *diamondRecHits) {
1055  const CTPPSDiamondDetId detid(vec.detId());
1056  if (detid.arm() != detId_pot.arm())
1057  continue;
1058 
1059  for (const auto& hit : vec) {
1060  // first check if the hit contributes to the track
1061  if (track.containsHit(hit)) {
1062  ++numOfHits;
1063  planesInTrackSet.insert(detid.plane());
1064  }
1065  }
1066  }
1067 
1068  if (numOfHits > 0 && numOfHits <= 10 && planesInTrackSet.size() > 2) {
1069  for (const auto& plt_vs_ch : channelPlots_) { // loop over all channels registered in geometry
1070  const CTPPSDiamondDetId detId(plt_vs_ch.first);
1071  if (detId.rpId() != detId_pot)
1072  continue;
1073  const unsigned short map_index = detId.plane() * 100 + detId.channel();
1074  if (potPlots_[detId_pot].effDoublecountingChMap.count(map_index) == 0) {
1075  potPlots_[detId_pot].effTriplecountingChMap[map_index] = 0;
1076  potPlots_[detId_pot].effDoublecountingChMap[map_index] = 0;
1077  }
1078  if (channelAlignedWithTrack(ctppsGeometry, detId, track, 0.2)) {
1079  // Channel should fire
1080  ++potPlots_[detId_pot].effDoublecountingChMap[map_index];
1081  for (const auto& rechits : *diamondRecHits) {
1082  const CTPPSDiamondDetId detId_hit(rechits.detId());
1083  if (detId_hit == detId)
1084  for (const auto& rechit : rechits)
1085  if (track.containsHit(rechit, 1)) // Channel fired
1086  ++potPlots_[detId_pot].effTriplecountingChMap[map_index];
1087  }
1088  }
1089  }
1090  }
1091  }
1092  }
1093 
1094  // Tomography of diamonds using pixel
1095  for (const auto& rechits : *diamondRecHits) {
1096  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
1097  const auto pix_shift = diamShifts_.at(detId_pot).withPixels;
1098  for (const auto& rechit : rechits) {
1099  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1100  continue;
1101  if (rechit.toT() == 0)
1102  continue;
1103  if (!pixelTracks.isValid())
1104  continue;
1105  if (potPlots_.count(detId_pot) == 0)
1106  continue;
1107 
1108  for (const auto& ds : *pixelTracks) {
1109  if (ds.size() > 1)
1110  continue;
1111  const CTPPSPixelDetId pixId(ds.detId());
1112  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_PIXEL_FAR_RP_ID)
1113  continue;
1114  for (const auto& lt : ds) {
1115  if (lt.isValid() && pixId.arm() == detId_pot.arm()) {
1116  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.ootIndex() >= 0 &&
1117  potPlots_[detId_pot].pixelTomographyAll.count(rechit.ootIndex()) > 0 && lt.x0() - pix_shift < 24)
1118  potPlots_[detId_pot]
1119  .pixelTomographyAll.at(rechit.ootIndex())
1120  ->Fill(lt.x0() - pix_shift + 25 * detId.plane(), lt.y0());
1121  }
1122  }
1123  }
1124  }
1125  }
1126 
1127  //------------------------------
1128  // Clock Plots
1129  //------------------------------
1130  // Commented out to save space in the DQM files, but code should be kept
1131  // for ( const auto& digis : *diamondDigis ) {
1132  // const CTPPSDiamondDetId detId(digis.detId()), detId_pot(detId.rpId());
1133  // if ( detId.channel() == CHANNEL_OF_VFAT_CLOCK ) {
1134  // for ( const auto& digi : digis ) {
1135  // if ( digi.leadingEdge() != 0 ) {
1136  // if ( detId.plane() == 1 ) {
1137  // potPlots_[detId_pot].clock_Digi1_le->Fill( HPTDC_BIN_WIDTH_NS * digi.leadingEdge() );
1138  // potPlots_[detId_pot].clock_Digi1_te->Fill( HPTDC_BIN_WIDTH_NS * digi.trailingEdge() );
1139  // }
1140  // if ( detId.plane() == 3 ) {
1141  // potPlots_[detId_pot].clock_Digi3_le->Fill( HPTDC_BIN_WIDTH_NS * digi.leadingEdge() );
1142  // potPlots_[detId_pot].clock_Digi3_te->Fill( HPTDC_BIN_WIDTH_NS * digi.trailingEdge() );
1143  // }
1144  // }
1145  // }
1146  // }
1147  // }
1148 
1149  //------------------------------
1150  // Plane Plots
1151  //------------------------------
1152 
1153  // Using CTPPSDiamondDigi
1154  std::unordered_map<unsigned int, unsigned int> channelsPerPlane;
1155  if (extract_digi_info_) {
1156  for (const auto& digis : *diamondDigis) {
1157  const CTPPSDiamondDetId detId(digis.detId()), detId_plane(detId.planeId());
1158  for (const auto& digi : digis) {
1159  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
1160  continue;
1161  if (planePlots_.count(detId_plane) == 0)
1162  continue;
1163 
1164  if (digi.leadingEdge() != 0) {
1165  planePlots_[detId_plane].digiProfileCumulativePerPlane->Fill(detId.channel());
1166  channelsPerPlane[detId_plane]++;
1167  }
1168 
1169  // Check dropped trailing edges
1170  if ((digi.trailingEdge() == 0) && (digi.leadingEdge() != 0)) {
1171  planePlots_[detId_plane].leadingEdgeCumulativePerPlane_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
1172  } else if ((digi.leadingEdge() == 0 && (digi.trailingEdge() != 0))) { // check dropped leading edges
1173  planePlots_[detId_plane].trailingEdgeCumulativePerPlane_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1174  }
1175  }
1176  }
1177  }
1178 
1179  for (const auto& plt : channelsPerPlane)
1180  planePlots_[plt.first].hit_multiplicity->Fill(plt.second);
1181 
1182  // Using CTPPSDiamondRecHit
1183  for (const auto& rechits : *diamondRecHits) {
1184  const CTPPSDiamondDetId detId(rechits.detId()), detId_plane(detId.planeId()), detId_pot(detId.rpId());
1185  for (const auto& rechit : rechits) {
1186  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1187  continue;
1188  if (rechit.toT() == 0)
1189  continue;
1190 
1191  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING) {
1192  planePlots_[detId_plane].leadingEdgeCumulativePerPlane_both->Fill(rechit.time() + 25 * rechit.ootIndex());
1193  planePlots_[detId_plane].TimeOverThresholdCumulativePerPlane->Fill(rechit.toT());
1194  }
1195  if (planePlots_.count(detId_plane) != 0) {
1196  if (centralOOT_ != -999 && rechit.ootIndex() == centralOOT_) {
1197  TH1F* hitHistoTmp = planePlots_[detId_plane].hitProfile->getTH1F();
1198  int startBin = hitHistoTmp->FindBin(rechit.x() - diamShifts_.at(detId_pot).global - 0.5 * rechit.xWidth());
1199  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
1200  for (int i = 0; i < numOfBins; ++i)
1201  hitHistoTmp->Fill(hitHistoTmp->GetBinCenter(startBin + i));
1202  }
1203  }
1204  }
1205  }
1206 
1207  //Tomography of diamonds using pixel and Efficiency WRT Pixels
1208  for (const auto& ds : *pixelTracks) {
1209  const CTPPSPixelDetId pixId(ds.detId());
1210  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_PIXEL_FAR_RP_ID)
1211  continue;
1212  if (ds.size() > 1)
1213  continue;
1214  for (const auto& lt : ds) {
1215  if (lt.isValid()) {
1216  for (const auto& sh_vs_id : diamShifts_) {
1217  const CTPPSDiamondDetId& detId_pot = sh_vs_id.first;
1218  const auto& shift = sh_vs_id.second;
1219  if (detId_pot.arm() == pixId.arm())
1220  // For efficieny
1221  potPlots_[detId_pot].pixelTracksMap.Fill(lt.x0() - shift.withPixels, lt.y0());
1222  }
1223 
1224  std::set<CTPPSDiamondDetId> planesWitHits_set;
1225  for (const auto& rechits : *diamondRecHits) {
1226  const CTPPSDiamondDetId detId(rechits.detId()), detId_plane(detId.planeId()), detId_pot(detId.rpId());
1227  const auto pix_shift = diamShifts_.at(detId_pot).withPixels;
1228  for (const auto& rechit : rechits) {
1229  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1230  continue;
1231  if (rechit.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.toT() == 0)
1232  continue;
1233  if (planePlots_.count(detId_plane) == 0)
1234  continue;
1235  if (pixId.arm() == detId_plane.arm() && lt.x0() - pix_shift < 24) {
1236  planePlots_[detId_plane].pixelTomography_far->Fill(lt.x0() - pix_shift + 25 * rechit.ootIndex(), lt.y0());
1237  if (centralOOT_ != -999 && rechit.ootIndex() == centralOOT_)
1238  planesWitHits_set.insert(detId_plane);
1239  }
1240  }
1241  }
1242 
1243  for (auto& planeId : planesWitHits_set)
1244  planePlots_[planeId].pixelTracksMapWithDiamonds.Fill(lt.x0() - diamShifts_.at(planeId.rpId()).withPixels,
1245  lt.y0());
1246  }
1247  }
1248  }
1249 
1250  //------------------------------
1251  // Channel Plots
1252  //------------------------------
1253 
1254  // digi profile cumulative
1255  if (extract_digi_info_) {
1256  for (const auto& digis : *diamondDigis) {
1257  const CTPPSDiamondDetId detId(digis.detId());
1258  for (const auto& digi : digis) {
1259  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
1260  continue;
1261  if (channelPlots_.count(detId) != 0) {
1262  // HPTDC Errors
1263  const HPTDCErrorFlags hptdcErrors = digi.hptdcErrorFlags();
1264  for (unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex)
1265  if (hptdcErrors.errorId(hptdcErrorIndex - 1))
1266  channelPlots_[detId].HPTDCErrorFlags->Fill(hptdcErrorIndex);
1267  if (digi.multipleHit())
1268  ++channelPlots_[detId].MHCounter;
1269 
1270  // Check dropped trailing edges
1271  if (digi.leadingEdge() != 0 || digi.trailingEdge() != 0) {
1272  ++channelPlots_[detId].HitCounter;
1273  if (digi.trailingEdge() == 0) {
1274  ++channelPlots_[detId].LeadingOnlyCounter;
1275  channelPlots_[detId].leadingEdgeCumulative_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
1276  } else if (digi.leadingEdge() == 0) {
1277  ++channelPlots_[detId].TrailingOnlyCounter;
1278  channelPlots_[detId].trailingEdgeCumulative_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1279  } else {
1280  ++channelPlots_[detId].CompleteCounter;
1281  // channelPlots_[detId].LeadingTrailingCorrelationPerChannel->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge(),
1282  // HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1283  }
1284  }
1285  }
1286  }
1287  }
1288  }
1289 
1290  // Using CTPPSDiamondRecHit
1291 
1292  for (const auto& rechits : *diamondRecHits) {
1293  CTPPSDiamondDetId detId(rechits.detId());
1294  for (const auto& rechit : rechits) {
1295  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1296  continue;
1297  if (channelPlots_.count(detId) != 0) {
1298  channelPlots_[detId].recHitTime->Fill(rechit.time());
1299  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.toT() != 0) {
1300  channelPlots_[detId].leadingEdgeCumulative_both->Fill(rechit.time() + 25 * rechit.ootIndex());
1301  channelPlots_[detId].TimeOverThresholdCumulativePerChannel->Fill(rechit.toT());
1302  }
1303  ++lumiCache->hitsCounterMap[detId];
1304 
1305  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING &&
1306  channelPlots_[detId].activity_per_bx.count(rechit.ootIndex()) > 0)
1307  channelPlots_[detId].activity_per_bx.at(rechit.ootIndex())->Fill(event.bunchCrossing());
1308  }
1309  }
1310  }
1311 
1312  // Tomography of diamonds using pixel
1313  for (const auto& rechits : *diamondRecHits) {
1314  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
1315  const auto shift_pix = diamShifts_.at(detId_pot).withPixels;
1316  for (const auto& rechit : rechits) {
1317  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1318  continue;
1319  if (rechit.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.toT() == 0)
1320  continue;
1321  if (!pixelTracks.isValid())
1322  continue;
1323  if (channelPlots_.count(detId) == 0)
1324  continue;
1325 
1326  for (const auto& ds : *pixelTracks) {
1327  const CTPPSPixelDetId pixId(ds.detId());
1328  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_PIXEL_FAR_RP_ID)
1329  continue;
1330  if (ds.size() > 1)
1331  continue;
1332  for (const auto& lt : ds) {
1333  if (lt.isValid() && pixId.arm() == detId.arm() && lt.x0() - shift_pix < 24)
1334  channelPlots_[detId].pixelTomography_far->Fill(lt.x0() - shift_pix + 25 * rechit.ootIndex(), lt.y0());
1335  }
1336  }
1337  }
1338  }
1339 }
1340 
1341 //----------------------------------------------------------------------------------------------------
1342 
1344  auto lumiCache = luminosityBlockCache(iLumi.index());
1345  if (!perLSsaving_) {
1346  if (plotOnline_)
1347  for (auto& plot : potPlots_)
1348  *(plot.second.hitDistribution2d_lumisection->getTH2F()) = *(lumiCache->hitDistribution2dMap[plot.first]);
1349 
1350  for (auto& plot : channelPlots_) {
1351  auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[plot.first];
1352  if (hitsCounterPerLumisection != 0) {
1353  plot.second.hit_rate->Fill((double)hitsCounterPerLumisection / SEC_PER_LUMI_SECTION);
1354  }
1355 
1356  double HundredOverHitCounter = .0;
1357  if (plot.second.HitCounter != 0)
1358  HundredOverHitCounter = 100. / plot.second.HitCounter;
1359  plot.second.HPTDCErrorFlags->setBinContent(16, HundredOverHitCounter * plot.second.MHCounter);
1360  plot.second.leadingWithoutTrailing->setBinContent(1, HundredOverHitCounter * plot.second.LeadingOnlyCounter);
1361  plot.second.leadingWithoutTrailing->setBinContent(2, HundredOverHitCounter * plot.second.TrailingOnlyCounter);
1362  plot.second.leadingWithoutTrailing->setBinContent(3, HundredOverHitCounter * plot.second.CompleteCounter);
1363  }
1364 
1365  for (auto& plot : potPlots_) {
1366  double HundredOverHitCounterPot = 0.;
1367  if (plot.second.HitCounter != 0)
1368  HundredOverHitCounterPot = 100. / plot.second.HitCounter;
1369  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1370  1, HundredOverHitCounterPot * plot.second.LeadingOnlyCounter);
1371  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1372  2, HundredOverHitCounterPot * plot.second.TrailingOnlyCounter);
1373  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1374  3, HundredOverHitCounterPot * plot.second.CompleteCounter);
1375 
1376  plot.second.MHComprensive->Reset();
1377  const CTPPSDiamondDetId rpId(plot.first);
1378  for (auto& chPlot : channelPlots_) {
1379  const CTPPSDiamondDetId chId(chPlot.first);
1380  if (chId.arm() == rpId.arm() && chId.rp() == rpId.rp()) {
1381  plot.second.MHComprensive->Fill(
1382  chId.plane(), chId.channel(), chPlot.second.HPTDCErrorFlags->getBinContent(16));
1383  }
1384  }
1385  }
1386  // Efficiencies of single channels
1387  if (plotOnline_)
1388  for (auto& plot : potPlots_) {
1389  plot.second.EfficiencyOfChannelsInPot->Reset();
1390  for (auto& element : plot.second.effTriplecountingChMap) {
1391  if (plot.second.effDoublecountingChMap[element.first] > 0) {
1392  int plane = element.first / 100;
1393  int channel = element.first % 100;
1394  double counted = element.second;
1395  double total = plot.second.effDoublecountingChMap[element.first];
1396  double efficiency = counted / total;
1397  // double error = std::sqrt( efficiency * ( 1 - efficiency ) / total );
1398 
1399  plot.second.EfficiencyOfChannelsInPot->Fill(plane, channel, 100 * efficiency);
1400  }
1401  }
1402  }
1403 
1404  // Efficeincy wrt pixels //TODO
1405  for (auto& plot : planePlots_) {
1406  TH2F* hitHistoTmp = plot.second.EfficiencyWRTPixelsInPlane->getTH2F();
1407 
1408  const CTPPSDiamondDetId detId(plot.first), detId_pot(detId.rpId());
1409  hitHistoTmp->Divide(&(plot.second.pixelTracksMapWithDiamonds), &(potPlots_[detId_pot].pixelTracksMap));
1410  }
1411  } //perLSsaving
1412 }
1413 
1414 //----------------------------------------------------------------------------------------------------
1415 
1417  const TotemFEDInfo& optorx,
1418  const TotemVFATStatus& status,
1420  int& EC_difference) const {
1421  const CTPPSDiamondDetId detId_pot(detId.rpId());
1422  if (plotOnline_)
1423  plots.ECCheck->Fill((int)((optorx.lv1() & 0xFF) - ((unsigned int)status.ec() & 0xFF)) & 0xFF);
1424  if ((static_cast<int>((optorx.lv1() & 0xFF) - status.ec()) != EC_difference) &&
1425  (static_cast<uint8_t>((optorx.lv1() & 0xFF) - status.ec()) < 128))
1426  EC_difference = static_cast<int>(optorx.lv1() & 0xFF) - (static_cast<unsigned int>(status.ec()) & 0xFF);
1427  if (EC_difference != 1 && EC_difference != -500 && std::abs(EC_difference) < 127) {
1428  if (detId.channel() == HPTDC_0_CHANNEL || detId.channel() == HPTDC_1_CHANNEL)
1429  plots.HPTDCErrorFlags_2D->Fill(16, 2 * detId.plane() + (detId.channel() - HPTDC_0_CHANNEL));
1430  if (verbosity_)
1431  edm::LogProblem("CTPPSDiamondDQMSource")
1432  << "FED " << optorx.fedId() << ": ECError at EV: 0x" << std::hex << optorx.lv1() << "\t\tVFAT EC: 0x"
1433  << static_cast<unsigned int>(status.ec()) << "\twith ID: " << std::dec << detId
1434  << "\tdiff: " << EC_difference;
1435  }
1436 }
1437 
1438 //----------------------------------------------------------------------------------------------------
1439 
1441  if (plotOffline_ && !perLSsaving_)
1442  for (const auto& rpPlots : potPlots_) {
1443  auto plots = rpPlots.second;
1444  // *(plots.TOTVsLSProfile->getTProfile())=*plots.TOTVsLS->getTH2F()->ProfileX();
1445  // *(plots.trackTimeVsLSProfile->getTProfile())=*plots.trackTimeVsLS->getTH2F()->ProfileX();
1446  *(plots.trackTimeVsBXProfile->getTProfile()) = *plots.trackTimeVsBX->getTH2F()->ProfileX();
1447  // *(plots.trackTimeVsXAngleProfile->getTProfile()) = *plots.trackTimeVsXAngle->getTH2F()->ProfileX();
1448  }
1449 }
1450 
1451 //----------------------------------------------------------------------------------------------------
void analyze(const edm::Event &, const edm::EventSetup &) override
static constexpr unsigned short CTPPS_FED_ID_45
OptoRx headers and footers.
Definition: TotemFEDInfo.h:17
plots related to one Diamond plane
plots related to one Diamond detector package
edm::EDGetTokenT< edm::DetSetVector< CTPPSDiamondRecHit > > tokenDiamondHit_
static constexpr double SEC_PER_LUMI_SECTION
Number of seconds per lumisection: used to compute hit rates in Hz.
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
const Translation & translation() const
Definition: DetGeomDesc.h:80
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > ctppsGeometryRunToken_
edm::EDGetTokenT< std::vector< TotemFEDInfo > > tokenFEDInfo_
std::unordered_map< CTPPSDetId, DiamondShifts > diamShifts_
bool contains(EventRange const &lh, EventID const &rh)
Definition: EventRange.cc:37
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
static constexpr unsigned short CTPPS_DIAMOND_CYL_RP_ID
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
static constexpr unsigned short CTPPS_DIAMOND_NUM_OF_CHANNELS
static constexpr double DISPLAY_RESOLUTION_FOR_HITS_MM
Bin width of histograms showing hits and tracks (in mm)
uint32_t arm() const
Definition: CTPPSDetId.h:57
Reconstructed hit in diamond detectors.
const double tolerance
void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override
CTPPSDiamondDQMSource(const edm::ParameterSet &)
plots related to the whole system
uint32_t plane() const
static constexpr unsigned short CTPPS_PIXEL_STATION_ID
std::shared_ptr< dds::Cache > globalBeginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) const override
void planeName(std::string &name, NameFlag flag=nFull) const
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > ctppsGeometryEventToken_
edm::EDGetTokenT< edm::DetSetVector< CTPPSDiamondLocalTrack > > tokenDiamondTrack_
Event setup record containing the real (actual) geometry information.
static std::string to_string(const XMLCh *ch)
MonitorElement * leadingWithoutTrailingCumulativePot
edm::EDGetTokenT< edm::DetSetVector< CTPPSPixelLocalTrack > > tokenPixelTrack_
void globalEndLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) override
static constexpr unsigned short HPTDC_0_CHANNEL
void dqmEndRun(edm::Run const &, edm::EventSetup const &) override
std::unordered_map< unsigned int, MonitorElement * > pixelTomographyAll
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
T getUntrackedParameter(std::string const &, T const &) const
static std::string hptdcErrorName(const unsigned short id)
std::vector< std::pair< edm::EventRange, int > > runParameters_
RunNumber_t run() const
Definition: RunBase.h:40
edm::EDGetTokenT< edm::DetSetVector< CTPPSDiamondDigi > > tokenDigi_
void rpName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:134
void bookHistograms(DQMStore::IBooker &, const edm::Run &, const edm::EventSetup &) override
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:408
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
CTPPSDetId rpId() const
Definition: CTPPSDetId.h:84
std::unordered_map< unsigned int, ChannelPlots > channelPlots_
uint32_t channel() const
edm::EDGetTokenT< edm::DetSetVector< TotemVFATStatus > > tokenStatus_
static constexpr unsigned short CHANNEL_OF_VFAT_CLOCK
Channel ID of the VFAT that contains clock data.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static constexpr unsigned int FIRST_RUN_W_PIXELS
Number of OOT indices monitored.
std::unordered_map< unsigned int, std::unique_ptr< TH2F > > hitDistribution2dMap
Transition
Definition: Transition.h:12
plots related to one Diamond channel
bool errorId(unsigned short id) const
void armName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:98
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
def window(xmin, xmax, ymin, ymax, x=0, y=0, width=100, height=100, xlogbase=None, ylogbase=None, minusInfinity=-1000, flipx=False, flipy=True)
Definition: svgfig.py:643
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:50
const DiamondDimensions & getDiamondDimensions() const
Definition: DetGeomDesc.h:90
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)
void channelName(std::string &name, NameFlag flag=nFull) const
d
Definition: ztail.py:151
static bool check(unsigned int raw)
returns true if the raw ID is a PPS-timing one
The manager class for TOTEM RP geometry.
Definition: CTPPSGeometry.h:30
uint32_t rp() const
Definition: CTPPSDetId.h:71
CTPPSDetId armId() const
Definition: CTPPSDetId.h:80
int fedId() const
Definition: TotemFEDInfo.h:22
static constexpr unsigned short CTPPS_DIAMOND_CYL_STATION_ID
std::unordered_map< unsigned int, SectorPlots > sectorPlots_
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::unordered_map< unsigned int, MonitorElement * > activity_per_bx
bool channelAlignedWithTrack(const CTPPSGeometry *geom, const CTPPSDiamondDetId &detid, const CTPPSDiamondLocalTrack &localTrack, const float tolerance=1)
bool isValid() const
Definition: HandleBase.h:70
std::unordered_map< unsigned int, PotPlots > potPlots_
static constexpr int TIMESLICE_WITHOUT_LEADING
LuminosityBlockIndex index() const
void checkEventNumber(const CTPPSDiamondDetId &, const TotemFEDInfo &, const TotemVFATStatus &, PotPlots &, int &) const
static constexpr unsigned short CTPPS_FED_ID_56
HLT enums.
static constexpr double HPTDC_BIN_WIDTH_NS
ns per HPTDC bin
static constexpr double INV_DISPLAY_RESOLUTION_FOR_HITS_MM
uint32_t lv1() const
Definition: TotemFEDInfo.h:26
CTPPSDiamondDetId planeId() const
static unsigned int const shift
Detector ID class for CTPPS Timing Diamond detectors. Bits [19:31] : Assigend in CTPPSDetId Calss Bit...
std::unordered_map< unsigned int, PlanePlots > planePlots_
std::unordered_map< unsigned int, MonitorElement * > activity_per_bx
static constexpr unsigned short CTPPS_PIXEL_FAR_RP_ID
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
static constexpr unsigned short HPTDC_1_CHANNEL
std::unordered_map< unsigned int, unsigned long > hitsCounterMap
Definition: event.py:1
Definition: Run.h:45
Log< level::Error, true > LogProblem