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 "CondFormats/RunInfo/interface/LHCInfo.h"
41 // #include "CondFormats/DataRecord/interface/LHCInfoRcd.h"
42 
43 #include <string>
44 
45 //----------------------------------------------------------------------------------------------------
46 
47 // Utility for efficiency computations
49  const CTPPSDiamondDetId& detid,
50  const CTPPSDiamondLocalTrack& localTrack,
51  const float tolerance = 1) {
52  const DetGeomDesc* det = geom->sensor(detid);
53  const float x_pos = det->translation().x(),
54  x_width = 2.0 * det->getDiamondDimensions().xHalfWidth; // parameters stand for half the size
55  return ((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  x_pos - 0.5 * x_width < localTrack.x0() + localTrack.x0Sigma() + tolerance) ||
59  (x_pos - 0.5 * x_width < localTrack.x0() - localTrack.x0Sigma() - tolerance &&
60  x_pos + 0.5 * x_width > localTrack.x0() + localTrack.x0Sigma() + tolerance));
61 }
62 
63 namespace dds {
64  struct Cache {
65  std::unordered_map<unsigned int, std::unique_ptr<TH2F>> hitDistribution2dMap;
66 
67  std::unordered_map<unsigned int, unsigned long> hitsCounterMap;
68  };
69 } // namespace dds
70 
71 class CTPPSDiamondDQMSource : public DQMOneEDAnalyzer<edm::LuminosityBlockCache<dds::Cache>> {
72 public:
74 
75 protected:
76  void dqmBeginRun(const edm::Run&, const edm::EventSetup&) override;
77  void dqmEndRun(edm::Run const&, edm::EventSetup const&) override;
78  void bookHistograms(DQMStore::IBooker&, const edm::Run&, const edm::EventSetup&) override;
79  void analyze(const edm::Event&, const edm::EventSetup&) override;
80  std::shared_ptr<dds::Cache> globalBeginLuminosityBlock(const edm::LuminosityBlock&,
81  const edm::EventSetup&) const override;
83 
84 private:
85  // Constants
87  static constexpr double SEC_PER_LUMI_SECTION = 23.31;
89  static constexpr unsigned short CHANNEL_OF_VFAT_CLOCK = 30;
94  static constexpr double HPTDC_BIN_WIDTH_NS = 25. / 1024;
95  static constexpr unsigned short CTPPS_PIXEL_STATION_ID = 2;
96  static constexpr unsigned short CTPPS_FAR_RP_ID = 3;
97  static constexpr unsigned short CTPPS_DIAMOND_NUM_OF_CHANNELS = 12;
98  static constexpr unsigned short CTPPS_FED_ID_45 = 583;
99  static constexpr unsigned short CTPPS_FED_ID_56 = 582;
100  static constexpr unsigned short HPTDC_0_CHANNEL = 6;
101  static constexpr unsigned short HPTDC_1_CHANNEL = 7;
103  static constexpr unsigned int FIRST_RUN_W_PIXELS = 300000;
104 
105  bool perLSsaving_; //to avoid nanoDQMIO crashing, driven by DQMServices/Core/python/DQMStore_cfi.py
106 
108  struct GlobalPlots {
109  GlobalPlots() = default;
110  GlobalPlots(DQMStore::IBooker& ibooker);
111  };
113  struct SectorPlots {
114  // Tracks
119  SectorPlots(DQMStore::IBooker& ibooker, unsigned int id, bool plotOnline);
120  };
122  struct PotPlots {
123  std::unordered_map<unsigned int, MonitorElement*> activity_per_bx;
124 
130 
133 
134  std::unordered_map<unsigned int, MonitorElement*> pixelTomographyAll;
135 
138  MonitorElement* timeOverThresholdCumulativePot = nullptr; //, *leadingTrailingCorrelationPot = nullptr;
140 
142 
145 
147 
148  // MonitorElement* clock_Digi1_le = nullptr;
149  // MonitorElement* clock_Digi1_te = nullptr;
150  // MonitorElement* clock_Digi3_le = nullptr;
151  // MonitorElement* clock_Digi3_te = nullptr;
152 
154 
155  std::map<int, int> effTriplecountingChMap;
156  std::map<int, int> effDoublecountingChMap;
159 
160  // MonitorElement* TOTVsLS = nullptr;
161  // MonitorElement* trackTimeVsLS = nullptr;
163  // MonitorElement* trackTimeVsXAngle = nullptr;
164 
165  // MonitorElement* TOTVsLSProfile = nullptr;
166  // MonitorElement* trackTimeVsLSProfile = nullptr;
168  // MonitorElement* trackTimeVsXAngleProfile = nullptr;
169 
170  PotPlots() = default;
171  PotPlots(DQMStore::IBooker& ibooker,
172  unsigned int id,
173  unsigned int windowsNum,
174  bool plotOnline,
175  bool plotOffline,
176  bool perLSsaving);
177  };
179  struct PlanePlots {
183 
186 
188 
189  PlanePlots() = default;
190  PlanePlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
191  };
193  struct ChannelPlots {
194  std::unordered_map<unsigned int, MonitorElement*> activity_per_bx;
195 
200  //MonitorElement* LeadingTrailingCorrelationPerChannel = nullptr;
205 
207 
208  ChannelPlots() = default;
209  ChannelPlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
210  };
211 
212  void checkEventNumber(const CTPPSDiamondDetId&, const TotemFEDInfo&, const TotemVFATStatus&, PotPlots&, int&) const;
213 
220 
223  // edm::ESGetToken<LHCInfo, LHCInfoRcd> ctppsLhcInfoToken_;
224 
226  const bool extract_digi_info_;
227  struct DiamondShifts {
229  };
230  std::unordered_map<CTPPSDetId, DiamondShifts> diamShifts_;
231  std::vector<std::pair<edm::EventRange, int>> runParameters_;
233  unsigned int verbosity_;
234  const bool plotOnline_;
235  const bool plotOffline_;
236  unsigned int windowsNum_;
238 
240  std::unordered_map<unsigned int, PotPlots> potPlots_;
241  std::unordered_map<unsigned int, SectorPlots> sectorPlots_;
242  std::unordered_map<unsigned int, PlanePlots> planePlots_;
243  std::unordered_map<unsigned int, ChannelPlots> channelPlots_;
244 
246 };
247 
248 //----------------------------------------------------------------------------------------------------
249 
251 
252 //----------------------------------------------------------------------------------------------------
253 
257  ibooker.setCurrentFolder(path);
258 
260 
261  trackCorrelation = ibooker.book2D("tracks correlation near-far",
262  title + " tracks correlation near-far;x (mm);x (mm)",
264  -1,
265  18,
267  -1,
268  18);
269  trackCorrelationLowMultiplicity =
270  ibooker.book2D("tracks correlation with low multiplicity near-far",
271  title + " tracks correlation with low multiplicity near-far;x (mm);x (mm)",
273  -1,
274  18,
276  -1,
277  18);
278 }
279 
280 //----------------------------------------------------------------------------------------------------
282  unsigned int id,
283  unsigned int windowsNum,
284  bool plotOnline,
285  bool plotOffline,
286  bool perLSsaving)
287  : HitCounter(0),
288  MHCounter(0),
289  LeadingOnlyCounter(0),
290  TrailingOnlyCounter(0),
291  CompleteCounter(0),
292  pixelTracksMap("Pixel track maps for efficiency", "Pixel track maps for efficiency", 25, 0, 25, 12, -2, 10) {
295  ibooker.setCurrentFolder(path);
296 
298 
299  if (plotOnline) {
301  ibooker.book2D("hits in planes lumisection",
302  title + " hits in planes in the last lumisection;plane number;x (mm)",
303  10,
304  -0.5,
305  4.5,
307  -0.5,
308  18.5);
309 
311  ibooker.book2D("hits with OOT in planes (le only)",
312  title + " hits with OOT in planes (le only);plane number, OOT index;x (mm)",
313  1 + windowsNum * 4,
314  -1. / windowsNum,
315  4,
317  -0.5,
318  18.5);
319 
321  ibooker.book1D("active planes inclusive",
322  title + " active planes, MH and le only included (per event);number of active planes",
323  6,
324  -0.5,
325  5.5);
326 
327  ECCheck = ibooker.book1D("optorxEC(8bit) - vfatEC", title + " EC Error;optorxEC-vfatEC", 50, -25, 25);
328 
330  ibooker.book2D("Efficiency in channels",
331  title + " Efficiency (%) in channels (diamonds only);plane number;ch number",
332  10,
333  -0.5,
334  4.5,
335  14,
336  -1,
337  13);
338  }
339 
340  if (plotOffline && !perLSsaving) {
341  ibooker.setCurrentFolder(path + "/timing_profiles");
342  // TOTVsLS=ibooker.book2D("ToT vs LS",title +" ToT vs LS;LS;ToT(ns)",4000,0,4000, 200,5,25);
343  // trackTimeVsLS=ibooker.book2D("track time vs LS",title+" track time vs LS;LS;track_time(ns)",4000,0,4000, 500, -25, 25);
344  trackTimeVsBX =
345  ibooker.book2D("track time vs BX", title + " track time vs BX;BX;track_time(ns)", 4000, 0, 4000, 500, -25, 25);
346  // trackTimeVsXAngle = ibooker.book2D(
347  // "track time vs xangle", title + " track time vs xangle;xangle;track_time(ns)", 60, 120, 180, 500, -25, 25);
348 
349  // TOTVsLSProfile=ibooker.bookProfile("ToT vs LS profile",title+" ToT vs LS profile;LS;track_time(ns)", 500, -25, 25,4000,0,4000);
350  // trackTimeVsLSProfile=ibooker.bookProfile("track time vs LS profile",title+" track time vs LS profile;LS;track_time(ns)", 500, -25, 25,4000,0,4000);
352  "track time vs BX profile", title + " track time vs BX profile;BX;track_time(ns)", 500, -25, 25, 4000, 0, 4000);
353  // trackTimeVsXAngleProfile = ibooker.bookProfile("track time vs xangle profile",
354  // title + " track time vs xangle profile;xangle;track_time(ns)",
355  // 500,
356  // -25,
357  // 25,
358  // 60,
359  // 120,
360  // 180);
361  ibooker.setCurrentFolder(path);
362  }
363 
364  for (unsigned int i = 0; i < windowsNum; i++) {
365  std::string window = std::to_string(i * 25) + "-" + std::to_string((i + 1) * 25);
366  activity_per_bx[i] = ibooker.book1D(
367  "activity per BX " + window, title + " Activity per BX " + window + " ns;Event.BX", 3600, -1.5, 3598. + 0.5);
369  ibooker.book2D("tomography pixel " + window,
370  title + " tomography with pixel " + window + " ns (all planes);x + 25*plane(mm);y (mm)",
371  100,
372  0,
373  100,
374  10,
375  -5,
376  5);
377  }
378 
379  hitDistribution2d = ibooker.book2D("hits in planes",
380  title + " hits in planes;plane number;x (mm)",
381  10,
382  -0.5,
383  4.5,
385  -0.5,
386  18.5);
387 
388  hitDistribution2dOOT = ibooker.book2D("hits with OOT in planes",
389  title + " hits with OOT in planes;plane number, OOT index;x (mm)",
390  1 + windowsNum * 4,
391  -1. / windowsNum,
392  4,
394  -0.5,
395  18.5);
396 
397  { // bin labelling (for clarity)
398  int idx = 2; // start counting at 1, first bin is empty
399  for (int pl = 0; pl < 4; ++pl)
400  for (unsigned int oot = 0; oot < windowsNum; ++oot) {
401  const std::string bin_label =
402  (oot == 0 ? "Plane " + std::to_string(pl) + ", " : "") + "OOT" + std::to_string(oot);
403  hitDistribution2dOOT->setBinLabel(idx, bin_label);
404  if (plotOnline)
406  ++idx;
407  }
408  }
409 
410  recHitTime = ibooker.book1D("recHit time", title + " recHit time; t (ns)", 500, -25, 25);
411 
412  activePlanes =
413  ibooker.book1D("active planes", title + " active planes (per event);number of active planes", 6, -0.5, 5.5);
414 
416  ibooker.book1D("tracks", title + " tracks;x (mm)", 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5);
417  trackDistributionOOT = ibooker.book2D("tracks with OOT",
418  title + " tracks with OOT;plane number;x (mm)",
419  9,
420  -0.5,
421  4,
423  -0.5,
424  18.5);
425 
426  leadingEdgeCumulative_both = ibooker.book1D("leading edge (le and te)",
427  title + " leading edge (le and te) (recHits); leading edge (ns)",
428  25 * windowsNum,
429  0,
430  25 * windowsNum);
431  leadingEdgeCumulative_all = ibooker.book1D("leading edge (all)",
432  title + " leading edge (with or without te) (DIGIs); leading edge (ns)",
433  25 * windowsNum,
434  0,
435  25 * windowsNum);
436  leadingEdgeCumulative_le = ibooker.book1D("leading edge (le only)",
437  title + " leading edge (le only) (DIGIs); leading edge (ns)",
438  25 * windowsNum,
439  0,
440  25 * windowsNum);
441  trailingEdgeCumulative_te = ibooker.book1D("trailing edge (te only)",
442  title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
443  25 * windowsNum,
444  0,
445  25 * windowsNum);
447  ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 250, -25, 100);
448  // leadingTrailingCorrelationPot =
449  // ibooker.book2D("leading trailing correlation",
450  // title + " leading trailing correlation;leading edge (ns);trailing edge (ns)",
451  // 75,
452  // 0,
453  // 75,
454  // 75,
455  // 0,
456  // 75);
457 
459  ibooker.book1D("event category", title + " leading edges without trailing;;%", 3, 0.5, 3.5);
463 
464  HPTDCErrorFlags_2D = ibooker.book2D("HPTDC Errors", title + " HPTDC Errors", 16, -0.5, 16.5, 9, -0.5, 8.5);
465  for (unsigned short error_index = 1; error_index < 16; ++error_index)
466  HPTDCErrorFlags_2D->setBinLabel(error_index, HPTDCErrorFlags::hptdcErrorName(error_index - 1));
467  HPTDCErrorFlags_2D->setBinLabel(16, "Wrong EC");
468 
469  int tmpIndex = 0;
470  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 18", /* axis */ 2);
471  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 17", /* axis */ 2);
472  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 16", /* axis */ 2);
473  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 0 TDC 15", /* axis */ 2);
474  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 18", /* axis */ 2);
475  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 17", /* axis */ 2);
476  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 16", /* axis */ 2);
477  HPTDCErrorFlags_2D->setBinLabel(++tmpIndex, "DB 1 TDC 15", /* axis */ 2);
478 
479  MHComprensive =
480  ibooker.book2D("MH in channels", title + " MH (%) in channels;plane number;ch number", 10, -0.5, 4.5, 14, -1, 13);
481 
482  // ibooker.setCurrentFolder( path+"/clock/" );
483  // clock_Digi1_le = ibooker.book1D( "clock1 leading edge", title+" clock1;leading edge (ns)", 250, 0, 25 );
484  // clock_Digi1_te = ibooker.book1D( "clock1 trailing edge", title+" clock1;trailing edge (ns)", 75, 0, 75 );
485  // clock_Digi3_le = ibooker.book1D( "clock3 leading edge", title+" clock3;leading edge (ns)", 250, 0, 25 );
486  // clock_Digi3_te = ibooker.book1D( "clock3 trailing edge", title+" clock3;trailing edge (ns)", 75, 0, 75 );
487 }
488 
489 //----------------------------------------------------------------------------------------------------
490 
492  : pixelTracksMapWithDiamonds("Pixel track maps for efficiency with coincidence",
493  "Pixel track maps for efficiency with coincidence",
494  25,
495  0,
496  25,
497  12,
498  -2,
499  10) {
502  ibooker.setCurrentFolder(path);
503 
505 
506  digiProfileCumulativePerPlane = ibooker.book1D("digi profile",
507  title + " digi profile; ch number",
509  -0.5,
511  hitProfile = ibooker.book1D(
512  "hit profile", title + " hit profile;x (mm)", 19. * INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -0.5, 18.5);
513  hit_multiplicity = ibooker.book1D("channels per plane", title + " channels per plane; ch per plane", 13, -0.5, 12.5);
514 
515  pixelTomography_far = ibooker.book2D("tomography pixel",
516  title + " tomography with pixel;x + 25 OOT (mm);y (mm)",
517  25 * windowsNum,
518  0,
519  25 * windowsNum,
520  8,
521  0,
522  8);
524  ibooker.book2D("Efficiency wrt pixels", title + " Efficiency wrt pixels;x (mm);y (mm)", 25, 0, 25, 12, -2, 10);
525 }
526 
527 //----------------------------------------------------------------------------------------------------
528 
530  : HitCounter(0), MHCounter(0), LeadingOnlyCounter(0), TrailingOnlyCounter(0), CompleteCounter(0) {
533  ibooker.setCurrentFolder(path);
534 
536 
537  leadingWithoutTrailing = ibooker.book1D("event category", title + " Event Category;;%", 3, 0.5, 3.5);
538  leadingWithoutTrailing->setBinLabel(1, "Leading only");
539  leadingWithoutTrailing->setBinLabel(2, "Trailing only");
541 
542  for (unsigned int i = 0; i < windowsNum; i++) {
543  std::string window = std::to_string(i * 25) + "-" + std::to_string((i + 1) * 25);
544  activity_per_bx[i] = ibooker.book1D(
545  "activity per BX " + window, title + " Activity per BX " + window + " ns;Event.BX", 3600, -1.5, 3598. + 0.5);
546  }
547 
548  HPTDCErrorFlags = ibooker.book1D("hptdc_Errors", title + " HPTDC Errors", 16, -0.5, 16.5);
549  for (unsigned short error_index = 1; error_index < 16; ++error_index)
550  HPTDCErrorFlags->setBinLabel(error_index, HPTDCErrorFlags::hptdcErrorName(error_index - 1));
551  HPTDCErrorFlags->setBinLabel(16, "MH (%)");
552 
553  leadingEdgeCumulative_both = ibooker.book1D("leading edge (le and te)",
554  title + " leading edge (recHits); leading edge (ns)",
555  25 * windowsNum,
556  0,
557  25 * windowsNum);
559  "leading edge (le only)", title + " leading edge (DIGIs); leading edge (ns)", 25 * windowsNum, 0, 25 * windowsNum);
560  trailingEdgeCumulative_te = ibooker.book1D("trailing edge (te only)",
561  title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
562  25 * windowsNum,
563  0,
564  25 * windowsNum);
566  ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 75, -25, 50);
567  // LeadingTrailingCorrelationPerChannel =
568  // ibooker.book2D("leading trailing correlation",
569  // title + " leading trailing correlation;leading edge (ns);trailing edge (ns)",
570  // 75,
571  // 0,
572  // 75,
573  // 75,
574  // 0,
575  // 75);
576 
577  pixelTomography_far = ibooker.book2D(
578  "tomography pixel", "tomography with pixel;x + 25 OOT (mm);y (mm)", 25 * windowsNum, 0, 25 * windowsNum, 8, 0, 8);
579 
580  hit_rate = ibooker.book1D("hit rate", title + "hit rate;rate (Hz)", 40, 0, 20);
581 
582  recHitTime = ibooker.book1D("recHit Time", title + " recHit Time; t (ns)", 500, -25, 25);
583 }
584 
585 //----------------------------------------------------------------------------------------------------
586 
588  : perLSsaving_(ps.getUntrackedParameter<bool>("perLSsaving", false)),
590  ps.getUntrackedParameter<edm::InputTag>("tagPixelLocalTracks"))),
592  ps.getUntrackedParameter<edm::InputTag>("tagDiamondRecHits"))),
594  ps.getUntrackedParameter<edm::InputTag>("tagDiamondLocalTracks"))),
597  // ctppsLhcInfoToken_(esConsumes<LHCInfo, LHCInfoRcd>()),
598  excludeMultipleHits_(ps.getParameter<bool>("excludeMultipleHits")),
599  extract_digi_info_(ps.getParameter<bool>("extractDigiInfo")),
600  centralOOT_(-999),
601  verbosity_(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
602  plotOnline_(ps.getUntrackedParameter<bool>("plotOnline", true)),
603  plotOffline_(ps.getUntrackedParameter<bool>("plotOffline", false)),
604  windowsNum_(ps.getUntrackedParameter<unsigned int>("windowsNum", 3)),
605  trackCorrelationThreshold_(ps.getUntrackedParameter<unsigned int>("trackCorrelationThreshold", 3)),
606  EC_difference_56_(-500),
607  EC_difference_45_(-500) {
608  if (extract_digi_info_) {
609  tokenStatus_ = consumes<edm::DetSetVector<TotemVFATStatus>>(ps.getUntrackedParameter<edm::InputTag>("tagStatus"));
610  tokenFEDInfo_ = consumes<std::vector<TotemFEDInfo>>(ps.getUntrackedParameter<edm::InputTag>("tagFEDInfo"));
611  tokenDigi_ = consumes<edm::DetSetVector<CTPPSDiamondDigi>>(ps.getUntrackedParameter<edm::InputTag>("tagDigi"));
612  }
613  for (const auto& pset : ps.getParameter<std::vector<edm::ParameterSet>>("offsetsOOT")) {
614  runParameters_.emplace_back(
615  std::make_pair(pset.getParameter<edm::EventRange>("validityRange"), pset.getParameter<int>("centralOOT")));
616  }
617 }
618 
619 //----------------------------------------------------------------------------------------------------
620 
622  centralOOT_ = -999;
623  for (const auto& oot : runParameters_) {
624  if (edm::contains(oot.first, edm::EventID(iRun.run(), 0, 1))) {
625  centralOOT_ = oot.second;
626  break;
627  }
628  }
629 
630  // Get detector shifts from the geometry
632  for (auto it = geom.beginRP(); it != geom.endRP(); ++it)
633  if (CTPPSDiamondDetId::check(it->first)) {
634  const CTPPSDiamondDetId diam_id(it->first);
635  const auto diam = geom.sensor(it->first);
636  diamShifts_[diam_id].global = diam->translation().x() - diam->getDiamondDimensions().xHalfWidth;
637  if (iRun.run() > FIRST_RUN_W_PIXELS) { // pixel installed
639  auto pix = geom.sensor(pixid);
640  // Rough alignement of pixel detector for diamond tomography
641  diamShifts_[diam_id].withPixels =
642  pix->translation().x() - pix->getDiamondDimensions().xHalfWidth - diamShifts_[diam_id].global - 1.;
643  }
644  }
645 }
646 
647 //----------------------------------------------------------------------------------------------------
648 
650  ibooker.cd();
651  ibooker.setCurrentFolder("CTPPS");
652 
653  globalPlot_ = GlobalPlots(ibooker);
654 
655  // book plots from the geometry
657  for (auto it = geom.beginSensor(); it != geom.endSensor(); ++it) {
658  if (!CTPPSDiamondDetId::check(it->first))
659  continue;
660  // per-channel plots
661  const CTPPSDiamondDetId chId(it->first);
662  if (plotOnline_ && channelPlots_.count(chId) == 0)
663  channelPlots_[chId] = ChannelPlots(ibooker, chId, windowsNum_);
664 
665  // per-plane plots
666  const CTPPSDiamondDetId plId(chId.planeId());
667  if (planePlots_.count(plId) == 0)
668  planePlots_[plId] = PlanePlots(ibooker, plId, windowsNum_);
669  // per-pot plots
670  const CTPPSDiamondDetId rpId(chId.rpId());
671  if (potPlots_.count(rpId) == 0)
673 
674  // per-sector plots
675  const CTPPSDiamondDetId secId(chId.armId());
676  if (plotOffline_ && sectorPlots_.count(secId) == 0)
677  sectorPlots_[secId] = SectorPlots(ibooker, secId, plotOnline_);
678  }
679 }
680 
681 //----------------------------------------------------------------------------------------------------
682 
684  const edm::EventSetup&) const {
685  auto d = std::make_shared<dds::Cache>();
686  d->hitDistribution2dMap.reserve(potPlots_.size());
687  if (!perLSsaving_ && plotOnline_) {
688  for (auto& plot : potPlots_) {
689  d->hitDistribution2dMap[plot.first] = std::make_unique<TH2F>(
690  "hits in planes lumisection",
691  (std::string(plot.second.hitDistribution2d_lumisection->getTH2F()->GetTitle()) + ";plane number;x (mm)")
692  .c_str(),
693  10,
694  -0.5,
695  4.5,
697  -0.5,
698  18.5);
699  }
700  }
701  return d;
702 }
703 
704 //----------------------------------------------------------------------------------------------------
705 
707  // get event data
708 
712  if (extract_digi_info_) {
713  event.getByToken(tokenStatus_, diamondVFATStatus);
714  event.getByToken(tokenDigi_, diamondDigis);
715  event.getByToken(tokenFEDInfo_, fedInfo);
716  }
717 
719  event.getByToken(tokenPixelTrack_, pixelTracks);
720 
722  event.getByToken(tokenDiamondHit_, diamondRecHits);
723 
725  event.getByToken(tokenDiamondTrack_, diamondLocalTracks);
726 
727  const CTPPSGeometry* ctppsGeometry = &iSetup.getData(ctppsGeometryEventToken_);
728  // const LHCInfo* hLhcInfo = &iSetup.getData(ctppsLhcInfoToken_);
729 
730  // check validity
731  bool valid = true;
732  if (extract_digi_info_) { // drop DIGI-level validity checks if not monitored
733  valid &= diamondVFATStatus.isValid();
734  valid &= diamondDigis.isValid();
735  valid &= fedInfo.isValid();
736  }
737  valid &= pixelTracks.isValid();
738  valid &= diamondRecHits.isValid();
739  valid &= diamondLocalTracks.isValid();
740 
741  if (!valid) {
742  if (verbosity_)
743  edm::LogProblem("CTPPSDiamondDQMSource")
744  << "ERROR in CTPPSDiamondDQMSource::analyze > some of the required inputs are not valid. Skipping this "
745  "event.\n"
746  << " DIGI-level: (checked? " << std::boolalpha << extract_digi_info_ << ")\n"
747  << " diamondVFATStatus.isValid = " << diamondVFATStatus.isValid() << "\n"
748  << " diamondDigis.isValid = " << diamondDigis.isValid() << "\n"
749  << " fedInfo.isValid = " << fedInfo.isValid() << "\n"
750  << " RECO-level:\n"
751  << " pixelTracks.isValid = " << pixelTracks.isValid() << "\n"
752  << " diamondRecHits.isValid = " << diamondRecHits.isValid() << "\n"
753  << " diamondLocalTracks.isValid = " << diamondLocalTracks.isValid();
754  return;
755  }
756 
757  //------------------------------
758  // Sector Plots
759  //------------------------------
760  // Using CTPPSDiamondLocalTrack
761  if (plotOffline_)
762  for (const auto& tracks : *diamondLocalTracks) {
763  const CTPPSDiamondDetId detId_near(tracks.detId());
764 
765  for (const auto& track : tracks) {
766  if (!track.isValid())
767  continue;
768  if (potPlots_.count(detId_near.rpId()) == 0)
769  continue;
770  TH1F* trackHistoInTimeTmp = potPlots_[detId_near.rpId()].trackDistribution->getTH1F();
771  int startBin_near =
772  trackHistoInTimeTmp->FindBin(track.x0() - diamShifts_[detId_near.rpId()].global - track.x0Sigma());
773  int numOfBins_near = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
774 
775  for (const auto& tracks_far : *diamondLocalTracks) {
776  CTPPSDiamondDetId detId_far(tracks_far.detId());
777  if (detId_near.arm() != detId_far.arm() || detId_near.station() == detId_far.station())
778  continue;
779  for (const auto& track_far : tracks_far) {
780  if (!track.isValid())
781  continue;
782  if (sectorPlots_.count(detId_far.armId()) == 0)
783  continue;
784  TH2F* trackHistoTmp = sectorPlots_[detId_far.armId()].trackCorrelation->getTH2F();
785  TAxis* trackHistoTmpXAxis = trackHistoTmp->GetXaxis();
786  TAxis* trackHistoTmpYAxis = trackHistoTmp->GetYaxis();
787  int startBin_far = trackHistoTmpYAxis->FindBin(track_far.x0() - diamShifts_[detId_far.rpId()].global -
788  track_far.x0Sigma());
789  int numOfBins_far = 2 * track_far.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
790  for (int i = 0; i < numOfBins_near; ++i)
791  for (int y = 0; y < numOfBins_far; ++y) {
792  trackHistoTmp->Fill(trackHistoTmpXAxis->GetBinCenter(startBin_near + i),
793  trackHistoTmpYAxis->GetBinCenter(startBin_far + y));
794  if (tracks.size() < 3 && tracks_far.size() < trackCorrelationThreshold_)
795  sectorPlots_[detId_far.armId()].trackCorrelationLowMultiplicity->Fill(
796  trackHistoTmpXAxis->GetBinCenter(startBin_near + i),
797  trackHistoTmpYAxis->GetBinCenter(startBin_far + y));
798  }
799  }
800  }
801  }
802  }
803 
804  //------------------------------
805  // RP Plots
806  //------------------------------
807 
808  //------------------------------
809  // Correlation Plots
810  //------------------------------
811 
812  if (extract_digi_info_) {
813  // Using CTPPSDiamondDigi
814  for (const auto& digis : *diamondDigis) {
815  const CTPPSDiamondDetId detId(digis.detId()), detId_pot(detId.rpId());
816  for (const auto& digi : digis) {
817  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
818  continue;
819  if (potPlots_.count(detId_pot) == 0)
820  continue;
821  //Leading without trailing investigation
822  if (digi.leadingEdge() != 0 || digi.trailingEdge() != 0) {
823  ++potPlots_[detId_pot].HitCounter;
824  if (digi.leadingEdge() != 0) {
825  potPlots_[detId_pot].leadingEdgeCumulative_all->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
826  }
827  if (digi.leadingEdge() != 0 && digi.trailingEdge() == 0) {
828  ++potPlots_[detId_pot].LeadingOnlyCounter;
829  potPlots_[detId_pot].leadingEdgeCumulative_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
830  }
831  if (digi.leadingEdge() == 0 && digi.trailingEdge() != 0) {
832  ++potPlots_[detId_pot].TrailingOnlyCounter;
833  potPlots_[detId_pot].trailingEdgeCumulative_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
834  }
835  if (digi.leadingEdge() != 0 && digi.trailingEdge() != 0) {
836  ++potPlots_[detId_pot].CompleteCounter;
837  // potPlots_[detId_pot].leadingTrailingCorrelationPot->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge(),
838  // HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
839  }
840  }
841 
842  // HPTDC Errors
843  const HPTDCErrorFlags hptdcErrors = digi.hptdcErrorFlags();
844  if (detId.channel() == HPTDC_0_CHANNEL ||
845  detId.channel() == HPTDC_1_CHANNEL) { // ch6 for HPTDC 0 and ch7 for HPTDC 1
846  int verticalIndex = 2 * detId.plane() + (detId.channel() - HPTDC_0_CHANNEL);
847  for (unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex)
848  if (hptdcErrors.errorId(hptdcErrorIndex - 1))
849  potPlots_[detId_pot].HPTDCErrorFlags_2D->Fill(hptdcErrorIndex, verticalIndex);
850  }
851  if (digi.multipleHit())
852  ++potPlots_[detId_pot].MHCounter;
853  }
854  }
855  }
856 
857  // EC Errors
858  if (extract_digi_info_) {
859  for (const auto& vfat_status : *diamondVFATStatus) {
860  const CTPPSDiamondDetId detId(vfat_status.detId());
861  for (const auto& status : vfat_status) {
862  if (!status.isOK())
863  continue;
864  if (potPlots_.count(detId.rpId()) == 0)
865  continue;
866  if (channelPlots_.count(detId) == 0)
867  continue;
868 
869  // Check Event Number
870  for (const auto& optorx : *fedInfo) {
871  if (detId.arm() == 1 && optorx.fedId() == CTPPS_FED_ID_56)
873  else if (detId.arm() == 0 && optorx.fedId() == CTPPS_FED_ID_45)
875  }
876  }
877  }
878  }
879 
880  // Using CTPPSDiamondRecHit
881  std::unordered_map<unsigned int, std::set<unsigned int>> planes;
882  std::unordered_map<unsigned int, std::set<unsigned int>> planes_inclusive;
883 
884  auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
885  for (const auto& rechits : *diamondRecHits) {
886  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
887  const auto& x_shift = diamShifts_.at(detId_pot);
888 
889  for (const auto& rechit : rechits) {
890  planes_inclusive[detId_pot].insert(detId.plane());
891  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
892  continue;
893  if (rechit.toT() != 0 && centralOOT_ != -999 && rechit.ootIndex() == centralOOT_)
894  planes[detId_pot].insert(detId.plane());
895 
896  if (potPlots_.count(detId_pot) == 0)
897  continue;
898 
899  potPlots_[detId_pot].recHitTime->Fill(rechit.time());
900 
901  float UFSDShift = 0.0;
902  if (rechit.yWidth() < 3)
903  UFSDShift = 0.5; // Display trick for UFSD that have 2 pixels with same X
904 
905  if (rechit.toT() != 0 && centralOOT_ != -999 && rechit.ootIndex() == centralOOT_) {
906  TH2F* hitHistoTmp = potPlots_[detId_pot].hitDistribution2d->getTH2F();
907  TAxis* hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
908  int startBin = hitHistoTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
909  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
910  for (int i = 0; i < numOfBins; ++i)
911  hitHistoTmp->Fill(detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin + i));
912 
913  if (!perLSsaving_ && plotOnline_) {
914  hitHistoTmp = lumiCache->hitDistribution2dMap[detId_pot].get();
915  hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
916  startBin = hitHistoTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
917  numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
918  for (int i = 0; i < numOfBins; ++i)
919  hitHistoTmp->Fill(detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin + i));
920  }
921  }
922 
923  if (rechit.toT() > 0) {
924  // Both
925  potPlots_[detId_pot].leadingEdgeCumulative_both->Fill(rechit.time() + 25 * rechit.ootIndex());
926  potPlots_[detId_pot].timeOverThresholdCumulativePot->Fill(rechit.toT());
927 
928  TH2F* hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT->getTH2F();
929  TAxis* hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
930  int startBin = hitHistoOOTTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
931  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
932  for (int i = 0; i < numOfBins; ++i)
933  hitHistoOOTTmp->Fill(detId.plane() + 1. / windowsNum_ * rechit.ootIndex(),
934  hitHistoOOTTmpYAxis->GetBinCenter(startBin + i));
935 
936  } else if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && plotOnline_) {
937  // Only leading
938  TH2F* hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT_le->getTH2F();
939  TAxis* hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
940  int startBin = hitHistoOOTTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
941  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
942  for (int i = 0; i < numOfBins; ++i)
943  hitHistoOOTTmp->Fill(detId.plane() + 1. / windowsNum_ * rechit.ootIndex(),
944  hitHistoOOTTmpYAxis->GetBinCenter(startBin + i));
945  }
946  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING &&
947  potPlots_[detId_pot].activity_per_bx.count(rechit.ootIndex()) > 0)
948  potPlots_[detId_pot].activity_per_bx.at(rechit.ootIndex())->Fill(event.bunchCrossing());
949 
950  // if(plotOffline_)
951  // potPlots_[detId_pot].TOTVsLS->Fill(event.luminosityBlock(),rechit.toT());
952  }
953  }
954 
955  for (const auto& plt : potPlots_) {
956  plt.second.activePlanes->Fill(planes[plt.first].size());
957  if (plotOnline_)
958  plt.second.activePlanesInclusive->Fill(planes_inclusive[plt.first].size());
959  }
960 
961  // Using CTPPSDiamondLocalTrack
962  for (const auto& tracks : *diamondLocalTracks) {
963  const CTPPSDiamondDetId detId(tracks.detId()), detId_pot(detId.rpId());
964  const auto& x_shift = diamShifts_.at(detId_pot);
965 
966  for (const auto& track : tracks) {
967  if (!track.isValid())
968  continue;
970  continue;
971  if (excludeMultipleHits_ && track.multipleHits() > 0)
972  continue;
973  if (potPlots_.count(detId_pot) == 0)
974  continue;
975 
976  TH2F* trackHistoOOTTmp = potPlots_[detId_pot].trackDistributionOOT->getTH2F();
977  TAxis* trackHistoOOTTmpYAxis = trackHistoOOTTmp->GetYaxis();
978  int startBin = trackHistoOOTTmpYAxis->FindBin(track.x0() - x_shift.global - track.x0Sigma());
979  int numOfBins = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
980  for (int i = 0; i < numOfBins; ++i)
981  trackHistoOOTTmp->Fill(track.ootIndex(), trackHistoOOTTmpYAxis->GetBinCenter(startBin + i));
982 
983  if (centralOOT_ != -999 && track.ootIndex() == centralOOT_) {
984  TH1F* trackHistoInTimeTmp = potPlots_[detId_pot].trackDistribution->getTH1F();
985  int startBin = trackHistoInTimeTmp->FindBin(track.x0() - x_shift.global - track.x0Sigma());
986  int numOfBins = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
987  for (int i = 0; i < numOfBins; ++i)
988  trackHistoInTimeTmp->Fill(trackHistoInTimeTmp->GetBinCenter(startBin + i));
989  }
990  if (plotOffline_ && !perLSsaving_) {
991  // potPlots_[detId_pot].trackTimeVsLS->Fill(event.luminosityBlock(),track.time());
992  potPlots_[detId_pot].trackTimeVsBX->Fill(event.bunchCrossing(), track.time());
993  //potPlots_[detId_pot].trackTimeVsXAngle->Fill(hLhcInfo->crossingAngle(), track.time());
994  }
995  }
996  }
997 
998  // Channel efficiency using CTPPSDiamondLocalTrack
999  for (const auto& tracks : *diamondLocalTracks) {
1000  const CTPPSDiamondDetId detId(tracks.detId()), detId_pot(detId.rpId());
1001  for (const auto& track : tracks) {
1002  // Find hits and planes in the track
1003  int numOfHits = 0;
1004  std::set<int> planesInTrackSet;
1005  for (const auto& vec : *diamondRecHits) {
1006  const CTPPSDiamondDetId detid(vec.detId());
1007  if (detid.arm() != detId_pot.arm())
1008  continue;
1009 
1010  for (const auto& hit : vec) {
1011  // first check if the hit contributes to the track
1012  if (track.containsHit(hit)) {
1013  ++numOfHits;
1014  planesInTrackSet.insert(detid.plane());
1015  }
1016  }
1017  }
1018 
1019  if (numOfHits > 0 && numOfHits <= 10 && planesInTrackSet.size() > 2) {
1020  for (const auto& plt_vs_ch : channelPlots_) { // loop over all channels registered in geometry
1021  const CTPPSDiamondDetId detId(plt_vs_ch.first);
1022  if (detId.rpId() != detId_pot)
1023  continue;
1024  const unsigned short map_index = detId.plane() * 100 + detId.channel();
1025  if (potPlots_[detId_pot].effDoublecountingChMap.count(map_index) == 0) {
1026  potPlots_[detId_pot].effTriplecountingChMap[map_index] = 0;
1027  potPlots_[detId_pot].effDoublecountingChMap[map_index] = 0;
1028  }
1029  if (channelAlignedWithTrack(ctppsGeometry, detId, track, 0.2)) {
1030  // Channel should fire
1031  ++potPlots_[detId_pot].effDoublecountingChMap[map_index];
1032  for (const auto& rechits : *diamondRecHits) {
1033  const CTPPSDiamondDetId detId_hit(rechits.detId());
1034  if (detId_hit == detId)
1035  for (const auto& rechit : rechits)
1036  if (track.containsHit(rechit, 1)) // Channel fired
1037  ++potPlots_[detId_pot].effTriplecountingChMap[map_index];
1038  }
1039  }
1040  }
1041  }
1042  }
1043  }
1044 
1045  // Tomography of diamonds using pixel
1046  for (const auto& rechits : *diamondRecHits) {
1047  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
1048  const auto pix_shift = diamShifts_.at(detId_pot).withPixels;
1049  for (const auto& rechit : rechits) {
1050  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1051  continue;
1052  if (rechit.toT() == 0)
1053  continue;
1054  if (!pixelTracks.isValid())
1055  continue;
1056  if (potPlots_.count(detId_pot) == 0)
1057  continue;
1058 
1059  for (const auto& ds : *pixelTracks) {
1060  if (ds.size() > 1)
1061  continue;
1062  const CTPPSPixelDetId pixId(ds.detId());
1063  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID)
1064  continue;
1065  for (const auto& lt : ds) {
1066  if (lt.isValid() && pixId.arm() == detId_pot.arm()) {
1067  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.ootIndex() >= 0 &&
1068  potPlots_[detId_pot].pixelTomographyAll.count(rechit.ootIndex()) > 0 && lt.x0() - pix_shift < 24)
1069  potPlots_[detId_pot]
1070  .pixelTomographyAll.at(rechit.ootIndex())
1071  ->Fill(lt.x0() - pix_shift + 25 * detId.plane(), lt.y0());
1072  }
1073  }
1074  }
1075  }
1076  }
1077 
1078  //------------------------------
1079  // Clock Plots
1080  //------------------------------
1081  // Commented out to save space in the DQM files, but code should be kept
1082  // for ( const auto& digis : *diamondDigis ) {
1083  // const CTPPSDiamondDetId detId(digis.detId()), detId_pot(detId.rpId());
1084  // if ( detId.channel() == CHANNEL_OF_VFAT_CLOCK ) {
1085  // for ( const auto& digi : digis ) {
1086  // if ( digi.leadingEdge() != 0 ) {
1087  // if ( detId.plane() == 1 ) {
1088  // potPlots_[detId_pot].clock_Digi1_le->Fill( HPTDC_BIN_WIDTH_NS * digi.leadingEdge() );
1089  // potPlots_[detId_pot].clock_Digi1_te->Fill( HPTDC_BIN_WIDTH_NS * digi.trailingEdge() );
1090  // }
1091  // if ( detId.plane() == 3 ) {
1092  // potPlots_[detId_pot].clock_Digi3_le->Fill( HPTDC_BIN_WIDTH_NS * digi.leadingEdge() );
1093  // potPlots_[detId_pot].clock_Digi3_te->Fill( HPTDC_BIN_WIDTH_NS * digi.trailingEdge() );
1094  // }
1095  // }
1096  // }
1097  // }
1098  // }
1099 
1100  //------------------------------
1101  // Plane Plots
1102  //------------------------------
1103 
1104  // Using CTPPSDiamondDigi
1105  std::unordered_map<unsigned int, unsigned int> channelsPerPlane;
1106  if (extract_digi_info_) {
1107  for (const auto& digis : *diamondDigis) {
1108  const CTPPSDiamondDetId detId(digis.detId()), detId_plane(detId.planeId());
1109  for (const auto& digi : digis) {
1110  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
1111  continue;
1112  if (planePlots_.count(detId_plane) == 0)
1113  continue;
1114 
1115  if (digi.leadingEdge() != 0) {
1116  planePlots_[detId_plane].digiProfileCumulativePerPlane->Fill(detId.channel());
1117  channelsPerPlane[detId_plane]++;
1118  }
1119  }
1120  }
1121  }
1122 
1123  for (const auto& plt : channelsPerPlane)
1124  planePlots_[plt.first].hit_multiplicity->Fill(plt.second);
1125 
1126  // Using CTPPSDiamondRecHit
1127  for (const auto& rechits : *diamondRecHits) {
1128  const CTPPSDiamondDetId detId(rechits.detId()), detId_plane(detId.planeId()), detId_pot(detId.rpId());
1129  for (const auto& rechit : rechits) {
1130  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1131  continue;
1132  if (rechit.toT() == 0)
1133  continue;
1134  if (planePlots_.count(detId_plane) != 0) {
1135  if (centralOOT_ != -999 && rechit.ootIndex() == centralOOT_) {
1136  TH1F* hitHistoTmp = planePlots_[detId_plane].hitProfile->getTH1F();
1137  int startBin = hitHistoTmp->FindBin(rechit.x() - diamShifts_.at(detId_pot).global - 0.5 * rechit.xWidth());
1138  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
1139  for (int i = 0; i < numOfBins; ++i)
1140  hitHistoTmp->Fill(hitHistoTmp->GetBinCenter(startBin + i));
1141  }
1142  }
1143  }
1144  }
1145 
1146  //Tomography of diamonds using pixel and Efficiency WRT Pixels
1147  for (const auto& ds : *pixelTracks) {
1148  const CTPPSPixelDetId pixId(ds.detId());
1149  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID)
1150  continue;
1151  if (ds.size() > 1)
1152  continue;
1153  for (const auto& lt : ds) {
1154  if (lt.isValid()) {
1155  for (const auto& sh_vs_id : diamShifts_) {
1156  const CTPPSDiamondDetId& detId_pot = sh_vs_id.first;
1157  const auto& shift = sh_vs_id.second;
1158  if (detId_pot.arm() == pixId.arm())
1159  // For efficieny
1160  potPlots_[detId_pot].pixelTracksMap.Fill(lt.x0() - shift.withPixels, lt.y0());
1161  }
1162 
1163  std::set<CTPPSDiamondDetId> planesWitHits_set;
1164  for (const auto& rechits : *diamondRecHits) {
1165  const CTPPSDiamondDetId detId(rechits.detId()), detId_plane(detId.planeId()), detId_pot(detId.rpId());
1166  const auto pix_shift = diamShifts_.at(detId_pot).withPixels;
1167  for (const auto& rechit : rechits) {
1168  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1169  continue;
1170  if (rechit.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.toT() == 0)
1171  continue;
1172  if (planePlots_.count(detId_plane) == 0)
1173  continue;
1174  if (pixId.arm() == detId_plane.arm() && lt.x0() - pix_shift < 24) {
1175  planePlots_[detId_plane].pixelTomography_far->Fill(lt.x0() - pix_shift + 25 * rechit.ootIndex(), lt.y0());
1176  if (centralOOT_ != -999 && rechit.ootIndex() == centralOOT_)
1177  planesWitHits_set.insert(detId_plane);
1178  }
1179  }
1180  }
1181 
1182  for (auto& planeId : planesWitHits_set)
1183  planePlots_[planeId].pixelTracksMapWithDiamonds.Fill(lt.x0() - diamShifts_.at(planeId.rpId()).withPixels,
1184  lt.y0());
1185  }
1186  }
1187  }
1188 
1189  //------------------------------
1190  // Channel Plots
1191  //------------------------------
1192 
1193  // digi profile cumulative
1194  if (extract_digi_info_) {
1195  for (const auto& digis : *diamondDigis) {
1196  const CTPPSDiamondDetId detId(digis.detId());
1197  for (const auto& digi : digis) {
1198  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
1199  continue;
1200  if (channelPlots_.count(detId) != 0) {
1201  // HPTDC Errors
1202  const HPTDCErrorFlags hptdcErrors = digi.hptdcErrorFlags();
1203  for (unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex)
1204  if (hptdcErrors.errorId(hptdcErrorIndex - 1))
1205  channelPlots_[detId].HPTDCErrorFlags->Fill(hptdcErrorIndex);
1206  if (digi.multipleHit())
1207  ++channelPlots_[detId].MHCounter;
1208 
1209  // Check dropped trailing edges
1210  if (digi.leadingEdge() != 0 || digi.trailingEdge() != 0) {
1211  ++channelPlots_[detId].HitCounter;
1212  if (digi.trailingEdge() == 0) {
1213  ++channelPlots_[detId].LeadingOnlyCounter;
1214  channelPlots_[detId].leadingEdgeCumulative_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
1215  } else if (digi.leadingEdge() == 0) {
1216  ++channelPlots_[detId].TrailingOnlyCounter;
1217  channelPlots_[detId].trailingEdgeCumulative_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1218  } else {
1219  ++channelPlots_[detId].CompleteCounter;
1220  // channelPlots_[detId].LeadingTrailingCorrelationPerChannel->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge(),
1221  // HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1222  }
1223  }
1224  }
1225  }
1226  }
1227  }
1228 
1229  // Using CTPPSDiamondRecHit
1230 
1231  for (const auto& rechits : *diamondRecHits) {
1232  CTPPSDiamondDetId detId(rechits.detId());
1233  for (const auto& rechit : rechits) {
1234  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1235  continue;
1236  if (channelPlots_.count(detId) != 0) {
1237  channelPlots_[detId].recHitTime->Fill(rechit.time());
1238  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.toT() != 0) {
1239  channelPlots_[detId].leadingEdgeCumulative_both->Fill(rechit.time() + 25 * rechit.ootIndex());
1240  channelPlots_[detId].TimeOverThresholdCumulativePerChannel->Fill(rechit.toT());
1241  }
1242  ++lumiCache->hitsCounterMap[detId];
1243 
1244  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING &&
1245  channelPlots_[detId].activity_per_bx.count(rechit.ootIndex()) > 0)
1246  channelPlots_[detId].activity_per_bx.at(rechit.ootIndex())->Fill(event.bunchCrossing());
1247  }
1248  }
1249  }
1250 
1251  // Tomography of diamonds using pixel
1252  for (const auto& rechits : *diamondRecHits) {
1253  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
1254  const auto shift_pix = diamShifts_.at(detId_pot).withPixels;
1255  for (const auto& rechit : rechits) {
1256  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1257  continue;
1258  if (rechit.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.toT() == 0)
1259  continue;
1260  if (!pixelTracks.isValid())
1261  continue;
1262  if (channelPlots_.count(detId) == 0)
1263  continue;
1264 
1265  for (const auto& ds : *pixelTracks) {
1266  const CTPPSPixelDetId pixId(ds.detId());
1267  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID)
1268  continue;
1269  if (ds.size() > 1)
1270  continue;
1271  for (const auto& lt : ds) {
1272  if (lt.isValid() && pixId.arm() == detId.arm() && lt.x0() - shift_pix < 24)
1273  channelPlots_[detId].pixelTomography_far->Fill(lt.x0() - shift_pix + 25 * rechit.ootIndex(), lt.y0());
1274  }
1275  }
1276  }
1277  }
1278 }
1279 
1280 //----------------------------------------------------------------------------------------------------
1281 
1283  auto lumiCache = luminosityBlockCache(iLumi.index());
1284  if (!perLSsaving_) {
1285  if (plotOnline_)
1286  for (auto& plot : potPlots_)
1287  *(plot.second.hitDistribution2d_lumisection->getTH2F()) = *(lumiCache->hitDistribution2dMap[plot.first]);
1288 
1289  for (auto& plot : channelPlots_) {
1290  auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[plot.first];
1291  if (hitsCounterPerLumisection != 0) {
1292  plot.second.hit_rate->Fill((double)hitsCounterPerLumisection / SEC_PER_LUMI_SECTION);
1293  }
1294 
1295  double HundredOverHitCounter = .0;
1296  if (plot.second.HitCounter != 0)
1297  HundredOverHitCounter = 100. / plot.second.HitCounter;
1298  plot.second.HPTDCErrorFlags->setBinContent(16, HundredOverHitCounter * plot.second.MHCounter);
1299  plot.second.leadingWithoutTrailing->setBinContent(1, HundredOverHitCounter * plot.second.LeadingOnlyCounter);
1300  plot.second.leadingWithoutTrailing->setBinContent(2, HundredOverHitCounter * plot.second.TrailingOnlyCounter);
1301  plot.second.leadingWithoutTrailing->setBinContent(3, HundredOverHitCounter * plot.second.CompleteCounter);
1302  }
1303 
1304  for (auto& plot : potPlots_) {
1305  double HundredOverHitCounterPot = 0.;
1306  if (plot.second.HitCounter != 0)
1307  HundredOverHitCounterPot = 100. / plot.second.HitCounter;
1308  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1309  1, HundredOverHitCounterPot * plot.second.LeadingOnlyCounter);
1310  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1311  2, HundredOverHitCounterPot * plot.second.TrailingOnlyCounter);
1312  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1313  3, HundredOverHitCounterPot * plot.second.CompleteCounter);
1314 
1315  plot.second.MHComprensive->Reset();
1316  const CTPPSDiamondDetId rpId(plot.first);
1317  for (auto& chPlot : channelPlots_) {
1318  const CTPPSDiamondDetId chId(chPlot.first);
1319  if (chId.arm() == rpId.arm() && chId.rp() == rpId.rp()) {
1320  plot.second.MHComprensive->Fill(
1321  chId.plane(), chId.channel(), chPlot.second.HPTDCErrorFlags->getBinContent(16));
1322  }
1323  }
1324  }
1325  // Efficiencies of single channels
1326  if (plotOnline_)
1327  for (auto& plot : potPlots_) {
1328  plot.second.EfficiencyOfChannelsInPot->Reset();
1329  for (auto& element : plot.second.effTriplecountingChMap) {
1330  if (plot.second.effDoublecountingChMap[element.first] > 0) {
1331  int plane = element.first / 100;
1332  int channel = element.first % 100;
1333  double counted = element.second;
1334  double total = plot.second.effDoublecountingChMap[element.first];
1335  double efficiency = counted / total;
1336  // double error = std::sqrt( efficiency * ( 1 - efficiency ) / total );
1337 
1338  plot.second.EfficiencyOfChannelsInPot->Fill(plane, channel, 100 * efficiency);
1339  }
1340  }
1341  }
1342 
1343  // Efficeincy wrt pixels //TODO
1344  for (auto& plot : planePlots_) {
1345  TH2F* hitHistoTmp = plot.second.EfficiencyWRTPixelsInPlane->getTH2F();
1346 
1347  const CTPPSDiamondDetId detId(plot.first), detId_pot(detId.rpId());
1348  hitHistoTmp->Divide(&(plot.second.pixelTracksMapWithDiamonds), &(potPlots_[detId_pot].pixelTracksMap));
1349  }
1350  } //perLSsaving
1351 }
1352 
1353 //----------------------------------------------------------------------------------------------------
1354 
1356  const TotemFEDInfo& optorx,
1357  const TotemVFATStatus& status,
1359  int& EC_difference) const {
1360  const CTPPSDiamondDetId detId_pot(detId.rpId());
1361  if (plotOnline_)
1362  plots.ECCheck->Fill((int)((optorx.lv1() & 0xFF) - ((unsigned int)status.ec() & 0xFF)) & 0xFF);
1363  if ((static_cast<int>((optorx.lv1() & 0xFF) - status.ec()) != EC_difference) &&
1364  (static_cast<uint8_t>((optorx.lv1() & 0xFF) - status.ec()) < 128))
1365  EC_difference = static_cast<int>(optorx.lv1() & 0xFF) - (static_cast<unsigned int>(status.ec()) & 0xFF);
1366  if (EC_difference != 1 && EC_difference != -500 && std::abs(EC_difference) < 127) {
1367  if (detId.channel() == HPTDC_0_CHANNEL || detId.channel() == HPTDC_1_CHANNEL)
1368  plots.HPTDCErrorFlags_2D->Fill(16, 2 * detId.plane() + (detId.channel() - HPTDC_0_CHANNEL));
1369  if (verbosity_)
1370  edm::LogProblem("CTPPSDiamondDQMSource")
1371  << "FED " << optorx.fedId() << ": ECError at EV: 0x" << std::hex << optorx.lv1() << "\t\tVFAT EC: 0x"
1372  << static_cast<unsigned int>(status.ec()) << "\twith ID: " << std::dec << detId
1373  << "\tdiff: " << EC_difference;
1374  }
1375 }
1376 
1377 //----------------------------------------------------------------------------------------------------
1378 
1380  if (plotOffline_ && !perLSsaving_)
1381  for (const auto& rpPlots : potPlots_) {
1382  auto plots = rpPlots.second;
1383  // *(plots.TOTVsLSProfile->getTProfile())=*plots.TOTVsLS->getTH2F()->ProfileX();
1384  // *(plots.trackTimeVsLSProfile->getTProfile())=*plots.trackTimeVsLS->getTH2F()->ProfileX();
1385  *(plots.trackTimeVsBXProfile->getTProfile()) = *plots.trackTimeVsBX->getTH2F()->ProfileX();
1386  // *(plots.trackTimeVsXAngleProfile->getTProfile()) = *plots.trackTimeVsXAngle->getTH2F()->ProfileX();
1387  }
1388 }
1389 
1390 //----------------------------------------------------------------------------------------------------
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
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)
static constexpr unsigned short CTPPS_FAR_RP_ID
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:399
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
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:212
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
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