CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
21 
24 
29 
32 
35 
40 
41 // #include "CondFormats/RunInfo/interface/LHCInfo.h"
42 // #include "CondFormats/DataRecord/interface/LHCInfoRcd.h"
43 
44 #include <string>
45 
46 //----------------------------------------------------------------------------------------------------
47 
48 // Utility for efficiency computations
50  const CTPPSDiamondDetId& detid,
51  const CTPPSDiamondLocalTrack& localTrack,
52  const float tolerance = 1) {
53  const DetGeomDesc* det = geom->sensor(detid);
54  const float x_pos = det->translation().x(),
55  x_width = 2.0 * det->getDiamondDimensions().xHalfWidth; // parameters stand for half the size
56  return ((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  x_pos + 0.5 * x_width > localTrack.x0() + localTrack.x0Sigma() + tolerance));
62 }
63 
64 namespace dds {
65  struct Cache {
66  std::unordered_map<unsigned int, std::unique_ptr<TH2F>> hitDistribution2dMap;
67 
68  std::unordered_map<unsigned int, unsigned long> hitsCounterMap;
69  };
70 } // namespace dds
71 
72 class CTPPSDiamondDQMSource : public DQMOneEDAnalyzer<edm::LuminosityBlockCache<dds::Cache>> {
73 public:
75 
76 protected:
77  void dqmBeginRun(const edm::Run&, const edm::EventSetup&) override;
78  void dqmEndRun(edm::Run const&, edm::EventSetup const&) override;
79  void bookHistograms(DQMStore::IBooker&, const edm::Run&, const edm::EventSetup&) override;
80  void analyze(const edm::Event&, const edm::EventSetup&) override;
81  std::shared_ptr<dds::Cache> globalBeginLuminosityBlock(const edm::LuminosityBlock&,
82  const edm::EventSetup&) const override;
84 
85 private:
86  // Constants
88  static constexpr double SEC_PER_LUMI_SECTION = 23.31;
90  static constexpr unsigned short CHANNEL_OF_VFAT_CLOCK = 30;
92  static constexpr double DISPLAY_RESOLUTION_FOR_HITS_MM = 0.1;
95  static constexpr double HPTDC_BIN_WIDTH_NS = 25. / 1024;
96  static constexpr unsigned short CTPPS_PIXEL_STATION_ID = 2;
97  static constexpr unsigned short CTPPS_FAR_RP_ID = 3;
98  static constexpr unsigned short CTPPS_DIAMOND_NUM_OF_CHANNELS = 12;
99  static constexpr unsigned short CTPPS_FED_ID_45 = 583;
100  static constexpr unsigned short CTPPS_FED_ID_56 = 582;
101  static constexpr unsigned short HPTDC_0_CHANNEL = 6;
102  static constexpr unsigned short HPTDC_1_CHANNEL = 7;
104  static constexpr unsigned int FIRST_RUN_W_PIXELS = 300000;
105 
106  bool perLSsaving_; //to avoid nanoDQMIO crashing, driven by DQMServices/Core/python/DQMStore_cfi.py
107 
109  struct GlobalPlots {
110  GlobalPlots() = default;
111  GlobalPlots(DQMStore::IBooker& ibooker);
112  };
114  struct SectorPlots {
115  // Tracks
120  SectorPlots(DQMStore::IBooker& ibooker, unsigned int id, bool plotOnline);
121  };
123  struct PotPlots {
124  std::unordered_map<unsigned int, MonitorElement*> activity_per_bx;
125 
131 
134 
135  std::unordered_map<unsigned int, MonitorElement*> pixelTomographyAll;
136 
139  MonitorElement* timeOverThresholdCumulativePot = nullptr; //, *leadingTrailingCorrelationPot = nullptr;
141 
143 
146 
148 
149  // MonitorElement* clock_Digi1_le = nullptr;
150  // MonitorElement* clock_Digi1_te = nullptr;
151  // MonitorElement* clock_Digi3_le = nullptr;
152  // MonitorElement* clock_Digi3_te = nullptr;
153 
155 
156  std::map<int, int> effTriplecountingChMap;
157  std::map<int, int> effDoublecountingChMap;
160 
161  // MonitorElement* TOTVsLS = nullptr;
162  // MonitorElement* trackTimeVsLS = nullptr;
164  // MonitorElement* trackTimeVsXAngle = nullptr;
165 
166  // MonitorElement* TOTVsLSProfile = nullptr;
167  // MonitorElement* trackTimeVsLSProfile = nullptr;
169  // MonitorElement* trackTimeVsXAngleProfile = nullptr;
170 
171  PotPlots() = default;
172  PotPlots(DQMStore::IBooker& ibooker,
173  unsigned int id,
174  unsigned int windowsNum,
175  bool plotOnline,
176  bool plotOffline,
177  bool perLSsaving);
178  };
180  struct PlanePlots {
184 
187 
189 
190  PlanePlots() = default;
191  PlanePlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
192  };
194  struct ChannelPlots {
195  std::unordered_map<unsigned int, MonitorElement*> activity_per_bx;
196 
201  //MonitorElement* LeadingTrailingCorrelationPerChannel = nullptr;
206 
208 
209  ChannelPlots() = default;
210  ChannelPlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum);
211  };
212 
213  void checkEventNumber(const CTPPSDiamondDetId&, const TotemFEDInfo&, const TotemVFATStatus&, PotPlots&, int&) const;
214 
221 
224  // edm::ESGetToken<LHCInfo, LHCInfoRcd> ctppsLhcInfoToken_;
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 
255 CTPPSDiamondDQMSource::SectorPlots::SectorPlots(DQMStore::IBooker& ibooker, unsigned int id, bool plotOnline) {
258  ibooker.setCurrentFolder(path);
259 
261 
262  trackCorrelation = ibooker.book2D("tracks correlation near-far",
263  title + " tracks correlation near-far;x (mm);x (mm)",
265  -1,
266  18,
268  -1,
269  18);
270  trackCorrelationLowMultiplicity =
271  ibooker.book2D("tracks correlation with low multiplicity near-far",
272  title + " tracks correlation with low multiplicity near-far;x (mm);x (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, 12, -2, 10) {
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)
406  hitDistribution2dOOT_le->setBinLabel(idx, bin_label);
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 
492 CTPPSDiamondDQMSource::PlanePlots::PlanePlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum)
493  : pixelTracksMapWithDiamonds("Pixel track maps for efficiency with coincidence",
494  "Pixel track maps for efficiency with coincidence",
495  25,
496  0,
497  25,
498  12,
499  -2,
500  10) {
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  pixelTomography_far = ibooker.book2D("tomography pixel",
517  title + " tomography with pixel;x + 25 OOT (mm);y (mm)",
518  25 * windowsNum,
519  0,
520  25 * windowsNum,
521  8,
522  0,
523  8);
525  ibooker.book2D("Efficiency wrt pixels", title + " Efficiency wrt pixels;x (mm);y (mm)", 25, 0, 25, 12, -2, 10);
526 }
527 
528 //----------------------------------------------------------------------------------------------------
529 
530 CTPPSDiamondDQMSource::ChannelPlots::ChannelPlots(DQMStore::IBooker& ibooker, unsigned int id, unsigned int windowsNum)
531  : HitCounter(0), MHCounter(0), LeadingOnlyCounter(0), TrailingOnlyCounter(0), CompleteCounter(0) {
534  ibooker.setCurrentFolder(path);
535 
537 
538  leadingWithoutTrailing = ibooker.book1D("event category", title + " Event Category;;%", 3, 0.5, 3.5);
539  leadingWithoutTrailing->setBinLabel(1, "Leading only");
540  leadingWithoutTrailing->setBinLabel(2, "Trailing only");
542 
543  for (unsigned int i = 0; i < windowsNum; i++) {
544  std::string window = std::to_string(i * 25) + "-" + std::to_string((i + 1) * 25);
545  activity_per_bx[i] = ibooker.book1D(
546  "activity per BX " + window, title + " Activity per BX " + window + " ns;Event.BX", 3600, -1.5, 3598. + 0.5);
547  }
548 
549  HPTDCErrorFlags = ibooker.book1D("hptdc_Errors", title + " HPTDC Errors", 16, -0.5, 16.5);
550  for (unsigned short error_index = 1; error_index < 16; ++error_index)
551  HPTDCErrorFlags->setBinLabel(error_index, HPTDCErrorFlags::hptdcErrorName(error_index - 1));
552  HPTDCErrorFlags->setBinLabel(16, "MH (%)");
553 
554  leadingEdgeCumulative_both = ibooker.book1D("leading edge (le and te)",
555  title + " leading edge (recHits); leading edge (ns)",
556  25 * windowsNum,
557  0,
558  25 * windowsNum);
560  "leading edge (le only)", title + " leading edge (DIGIs); leading edge (ns)", 25 * windowsNum, 0, 25 * windowsNum);
561  trailingEdgeCumulative_te = ibooker.book1D("trailing edge (te only)",
562  title + " trailing edge (te only) (DIGIs); trailing edge (ns)",
563  25 * windowsNum,
564  0,
565  25 * windowsNum);
567  ibooker.book1D("time over threshold", title + " time over threshold;time over threshold (ns)", 75, -25, 50);
568  // LeadingTrailingCorrelationPerChannel =
569  // ibooker.book2D("leading trailing correlation",
570  // title + " leading trailing correlation;leading edge (ns);trailing edge (ns)",
571  // 75,
572  // 0,
573  // 75,
574  // 75,
575  // 0,
576  // 75);
577 
578  pixelTomography_far = ibooker.book2D(
579  "tomography pixel", "tomography with pixel;x + 25 OOT (mm);y (mm)", 25 * windowsNum, 0, 25 * windowsNum, 8, 0, 8);
580 
581  hit_rate = ibooker.book1D("hit rate", title + "hit rate;rate (Hz)", 40, 0, 20);
582 
583  recHitTime = ibooker.book1D("recHit Time", title + " recHit Time; t (ns)", 500, -25, 25);
584 }
585 
586 //----------------------------------------------------------------------------------------------------
587 
589  : perLSsaving_(ps.getUntrackedParameter<bool>("perLSsaving", false)),
591  consumes<edm::DetSetVector<CTPPSPixelLocalTrack>>(ps.getParameter<edm::InputTag>("tagPixelLocalTracks"))),
593  consumes<edm::DetSetVector<CTPPSDiamondRecHit>>(ps.getParameter<edm::InputTag>("tagDiamondRecHits"))),
595  consumes<edm::DetSetVector<CTPPSDiamondLocalTrack>>(ps.getParameter<edm::InputTag>("tagDiamondLocalTracks"))),
598  // ctppsLhcInfoToken_(esConsumes<LHCInfo, LHCInfoRcd>()),
599  excludeMultipleHits_(ps.getParameter<bool>("excludeMultipleHits")),
600  extract_digi_info_(ps.getParameter<bool>("extractDigiInfo")),
601  centralOOT_(-999),
602  verbosity_(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
603  plotOnline_(ps.getUntrackedParameter<bool>("plotOnline", true)),
604  plotOffline_(ps.getUntrackedParameter<bool>("plotOffline", false)),
605  windowsNum_(ps.getUntrackedParameter<unsigned int>("windowsNum", 3)),
606  trackCorrelationThreshold_(ps.getUntrackedParameter<unsigned int>("trackCorrelationThreshold", 3)),
607  EC_difference_56_(-500),
608  EC_difference_45_(-500) {
609  if (extract_digi_info_) {
610  tokenStatus_ = consumes<edm::DetSetVector<TotemVFATStatus>>(ps.getParameter<edm::InputTag>("tagStatus"));
611  tokenFEDInfo_ = consumes<std::vector<TotemFEDInfo>>(ps.getParameter<edm::InputTag>("tagFEDInfo"));
612  tokenDigi_ = consumes<edm::DetSetVector<CTPPSDiamondDigi>>(ps.getParameter<edm::InputTag>("tagDigi"));
613  }
614  for (const auto& pset : ps.getParameter<std::vector<edm::ParameterSet>>("offsetsOOT")) {
615  runParameters_.emplace_back(
616  std::make_pair(pset.getParameter<edm::EventRange>("validityRange"), pset.getParameter<int>("centralOOT")));
617  }
618 }
619 
620 //----------------------------------------------------------------------------------------------------
621 
623  centralOOT_ = -999;
624  for (const auto& oot : runParameters_) {
625  if (edm::contains(oot.first, edm::EventID(iRun.run(), 0, 1))) {
626  centralOOT_ = oot.second;
627  break;
628  }
629  }
630 
631  // Get detector shifts from the geometry
633  for (auto it = geom.beginRP(); it != geom.endRP(); ++it)
634  if (CTPPSDiamondDetId::check(it->first)) {
635  const CTPPSDiamondDetId diam_id(it->first);
636  const auto diam = geom.sensor(it->first);
637  diamShifts_[diam_id].global = diam->translation().x() - diam->getDiamondDimensions().xHalfWidth;
638  if (iRun.run() > FIRST_RUN_W_PIXELS) { // pixel installed
640  auto pix = geom.sensor(pixid);
641  // Rough alignement of pixel detector for diamond tomography
642  diamShifts_[diam_id].withPixels =
643  pix->translation().x() - pix->getDiamondDimensions().xHalfWidth - diamShifts_[diam_id].global - 1.;
644  }
645  }
646 }
647 
648 //----------------------------------------------------------------------------------------------------
649 
651  ibooker.cd();
652  ibooker.setCurrentFolder("CTPPS");
653 
654  globalPlot_ = GlobalPlots(ibooker);
655 
656  // book plots from the geometry
658  for (auto it = geom.beginSensor(); it != geom.endSensor(); ++it) {
659  if (!CTPPSDiamondDetId::check(it->first))
660  continue;
661  // per-channel plots
662  const CTPPSDiamondDetId chId(it->first);
663  if (plotOnline_ && channelPlots_.count(chId) == 0)
664  channelPlots_[chId] = ChannelPlots(ibooker, chId, windowsNum_);
665 
666  // per-plane plots
667  const CTPPSDiamondDetId plId(chId.planeId());
668  if (planePlots_.count(plId) == 0)
669  planePlots_[plId] = PlanePlots(ibooker, plId, windowsNum_);
670  // per-pot plots
671  const CTPPSDiamondDetId rpId(chId.rpId());
672  if (potPlots_.count(rpId) == 0)
674 
675  // per-sector plots
676  const CTPPSDiamondDetId secId(chId.armId());
677  if (plotOffline_ && sectorPlots_.count(secId) == 0)
678  sectorPlots_[secId] = SectorPlots(ibooker, secId, plotOnline_);
679  }
680 }
681 
682 //----------------------------------------------------------------------------------------------------
683 
685  const edm::EventSetup&) const {
686  auto d = std::make_shared<dds::Cache>();
687  d->hitDistribution2dMap.reserve(potPlots_.size());
688  if (!perLSsaving_ && plotOnline_) {
689  for (auto& plot : potPlots_)
690  d->hitDistribution2dMap[plot.first] =
691  std::unique_ptr<TH2F>(static_cast<TH2F*>(plot.second.hitDistribution2d_lumisection->getTH2F()->Clone()));
692  }
693  return d;
694 }
695 
696 //----------------------------------------------------------------------------------------------------
697 
699  // get event data
700 
704  if (extract_digi_info_) {
705  event.getByToken(tokenStatus_, diamondVFATStatus);
706  event.getByToken(tokenDigi_, diamondDigis);
707  event.getByToken(tokenFEDInfo_, fedInfo);
708  }
709 
711  event.getByToken(tokenPixelTrack_, pixelTracks);
712 
714  event.getByToken(tokenDiamondHit_, diamondRecHits);
715 
717  event.getByToken(tokenDiamondTrack_, diamondLocalTracks);
718 
719  const CTPPSGeometry* ctppsGeometry = &iSetup.getData(ctppsGeometryEventToken_);
720  // const LHCInfo* hLhcInfo = &iSetup.getData(ctppsLhcInfoToken_);
721 
722  // check validity
723  bool valid = true;
724  if (extract_digi_info_) { // drop DIGI-level validity checks if not monitored
725  valid &= diamondVFATStatus.isValid();
726  valid &= diamondDigis.isValid();
727  valid &= fedInfo.isValid();
728  }
729  valid &= pixelTracks.isValid();
730  valid &= diamondRecHits.isValid();
731  valid &= diamondLocalTracks.isValid();
732 
733  if (!valid) {
734  if (verbosity_)
735  edm::LogProblem("CTPPSDiamondDQMSource")
736  << "ERROR in CTPPSDiamondDQMSource::analyze > some of the required inputs are not valid. Skipping this "
737  "event.\n"
738  << " DIGI-level: (checked? " << std::boolalpha << extract_digi_info_ << ")\n"
739  << " diamondVFATStatus.isValid = " << diamondVFATStatus.isValid() << "\n"
740  << " diamondDigis.isValid = " << diamondDigis.isValid() << "\n"
741  << " fedInfo.isValid = " << fedInfo.isValid() << "\n"
742  << " RECO-level:\n"
743  << " pixelTracks.isValid = " << pixelTracks.isValid() << "\n"
744  << " diamondRecHits.isValid = " << diamondRecHits.isValid() << "\n"
745  << " diamondLocalTracks.isValid = " << diamondLocalTracks.isValid();
746  return;
747  }
748 
749  //------------------------------
750  // Sector Plots
751  //------------------------------
752  // Using CTPPSDiamondLocalTrack
753  if (plotOffline_)
754  for (const auto& tracks : *diamondLocalTracks) {
755  const CTPPSDiamondDetId detId_near(tracks.detId());
756 
757  for (const auto& track : tracks) {
758  if (!track.isValid())
759  continue;
760  if (potPlots_.count(detId_near.rpId()) == 0)
761  continue;
762  TH1F* trackHistoInTimeTmp = potPlots_[detId_near.rpId()].trackDistribution->getTH1F();
763  int startBin_near =
764  trackHistoInTimeTmp->FindBin(track.x0() - diamShifts_[detId_near.rpId()].global - track.x0Sigma());
765  int numOfBins_near = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
766 
767  for (const auto& tracks_far : *diamondLocalTracks) {
768  CTPPSDiamondDetId detId_far(tracks_far.detId());
769  if (detId_near.arm() != detId_far.arm() || detId_near.station() == detId_far.station())
770  continue;
771  for (const auto& track_far : tracks_far) {
772  if (!track.isValid())
773  continue;
774  if (sectorPlots_.count(detId_far.armId()) == 0)
775  continue;
776  TH2F* trackHistoTmp = sectorPlots_[detId_far.armId()].trackCorrelation->getTH2F();
777  TAxis* trackHistoTmpXAxis = trackHistoTmp->GetXaxis();
778  TAxis* trackHistoTmpYAxis = trackHistoTmp->GetYaxis();
779  int startBin_far = trackHistoTmpYAxis->FindBin(track_far.x0() - diamShifts_[detId_far.rpId()].global -
780  track_far.x0Sigma());
781  int numOfBins_far = 2 * track_far.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
782  for (int i = 0; i < numOfBins_near; ++i)
783  for (int y = 0; y < numOfBins_far; ++y) {
784  trackHistoTmp->Fill(trackHistoTmpXAxis->GetBinCenter(startBin_near + i),
785  trackHistoTmpYAxis->GetBinCenter(startBin_far + y));
786  if (tracks.size() < 3 && tracks_far.size() < trackCorrelationThreshold_)
787  sectorPlots_[detId_far.armId()].trackCorrelationLowMultiplicity->Fill(
788  trackHistoTmpXAxis->GetBinCenter(startBin_near + i),
789  trackHistoTmpYAxis->GetBinCenter(startBin_far + y));
790  }
791  }
792  }
793  }
794  }
795 
796  //------------------------------
797  // RP Plots
798  //------------------------------
799 
800  //------------------------------
801  // Correlation Plots
802  //------------------------------
803 
804  if (extract_digi_info_) {
805  // Using CTPPSDiamondDigi
806  for (const auto& digis : *diamondDigis) {
807  const CTPPSDiamondDetId detId(digis.detId()), detId_pot(detId.rpId());
808  for (const auto& digi : digis) {
809  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
810  continue;
811  if (potPlots_.count(detId_pot) == 0)
812  continue;
813  //Leading without trailing investigation
814  if (digi.leadingEdge() != 0 || digi.trailingEdge() != 0) {
815  ++potPlots_[detId_pot].HitCounter;
816  if (digi.leadingEdge() != 0) {
817  potPlots_[detId_pot].leadingEdgeCumulative_all->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
818  }
819  if (digi.leadingEdge() != 0 && digi.trailingEdge() == 0) {
820  ++potPlots_[detId_pot].LeadingOnlyCounter;
821  potPlots_[detId_pot].leadingEdgeCumulative_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
822  }
823  if (digi.leadingEdge() == 0 && digi.trailingEdge() != 0) {
824  ++potPlots_[detId_pot].TrailingOnlyCounter;
825  potPlots_[detId_pot].trailingEdgeCumulative_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
826  }
827  if (digi.leadingEdge() != 0 && digi.trailingEdge() != 0) {
828  ++potPlots_[detId_pot].CompleteCounter;
829  // potPlots_[detId_pot].leadingTrailingCorrelationPot->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge(),
830  // HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
831  }
832  }
833 
834  // HPTDC Errors
835  const HPTDCErrorFlags hptdcErrors = digi.hptdcErrorFlags();
836  if (detId.channel() == HPTDC_0_CHANNEL ||
837  detId.channel() == HPTDC_1_CHANNEL) { // ch6 for HPTDC 0 and ch7 for HPTDC 1
838  int verticalIndex = 2 * detId.plane() + (detId.channel() - HPTDC_0_CHANNEL);
839  for (unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex)
840  if (hptdcErrors.errorId(hptdcErrorIndex - 1))
841  potPlots_[detId_pot].HPTDCErrorFlags_2D->Fill(hptdcErrorIndex, verticalIndex);
842  }
843  if (digi.multipleHit())
844  ++potPlots_[detId_pot].MHCounter;
845  }
846  }
847  }
848 
849  // EC Errors
850  if (extract_digi_info_) {
851  for (const auto& vfat_status : *diamondVFATStatus) {
852  const CTPPSDiamondDetId detId(vfat_status.detId());
853  for (const auto& status : vfat_status) {
854  if (!status.isOK())
855  continue;
856  if (potPlots_.count(detId.rpId()) == 0)
857  continue;
858  if (channelPlots_.count(detId) == 0)
859  continue;
860 
861  // Check Event Number
862  for (const auto& optorx : *fedInfo) {
863  if (detId.arm() == 1 && optorx.fedId() == CTPPS_FED_ID_56)
864  checkEventNumber(detId, optorx, status, potPlots_[detId.rpId()], EC_difference_56_);
865  else if (detId.arm() == 0 && optorx.fedId() == CTPPS_FED_ID_45)
866  checkEventNumber(detId, optorx, status, potPlots_[detId.rpId()], EC_difference_45_);
867  }
868  }
869  }
870  }
871 
872  // Using CTPPSDiamondRecHit
873  std::unordered_map<unsigned int, std::set<unsigned int>> planes;
874  std::unordered_map<unsigned int, std::set<unsigned int>> planes_inclusive;
875 
876  auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
877  for (const auto& rechits : *diamondRecHits) {
878  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
879  const auto& x_shift = diamShifts_.at(detId_pot);
880 
881  for (const auto& rechit : rechits) {
882  planes_inclusive[detId_pot].insert(detId.plane());
883  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
884  continue;
885  if (rechit.toT() != 0 && centralOOT_ != -999 && rechit.ootIndex() == centralOOT_)
886  planes[detId_pot].insert(detId.plane());
887 
888  if (potPlots_.count(detId_pot) == 0)
889  continue;
890 
891  potPlots_[detId_pot].recHitTime->Fill(rechit.time());
892 
893  float UFSDShift = 0.0;
894  if (rechit.yWidth() < 3)
895  UFSDShift = 0.5; // Display trick for UFSD that have 2 pixels with same X
896 
897  if (rechit.toT() != 0 && centralOOT_ != -999 && rechit.ootIndex() == centralOOT_) {
898  TH2F* hitHistoTmp = potPlots_[detId_pot].hitDistribution2d->getTH2F();
899  TAxis* hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
900  int startBin = hitHistoTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
901  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
902  for (int i = 0; i < numOfBins; ++i)
903  hitHistoTmp->Fill(detId.plane() + UFSDShift, hitHistoTmpYAxis->GetBinCenter(startBin + i));
904 
905  if (!perLSsaving_ && plotOnline_) {
906  hitHistoTmp = lumiCache->hitDistribution2dMap[detId_pot].get();
907  hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
908  startBin = hitHistoTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
909  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  }
914 
915  if (rechit.toT() != 0) {
916  // Both
917  potPlots_[detId_pot].leadingEdgeCumulative_both->Fill(rechit.time() + 25 * rechit.ootIndex());
918  potPlots_[detId_pot].timeOverThresholdCumulativePot->Fill(rechit.toT());
919 
920  TH2F* hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT->getTH2F();
921  TAxis* hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
922  int startBin = hitHistoOOTTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
923  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
924  for (int i = 0; i < numOfBins; ++i)
925  hitHistoOOTTmp->Fill(detId.plane() + 0.25 * rechit.ootIndex(),
926  hitHistoOOTTmpYAxis->GetBinCenter(startBin + i));
927  } else if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && plotOnline_) {
928  // Only leading
929  TH2F* hitHistoOOTTmp = potPlots_[detId_pot].hitDistribution2dOOT_le->getTH2F();
930  TAxis* hitHistoOOTTmpYAxis = hitHistoOOTTmp->GetYaxis();
931  int startBin = hitHistoOOTTmpYAxis->FindBin(rechit.x() - x_shift.global - 0.5 * rechit.xWidth());
932  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
933  for (int i = 0; i < numOfBins; ++i) {
934  hitHistoOOTTmp->Fill(detId.plane() + 0.25 * rechit.ootIndex(),
935  hitHistoOOTTmpYAxis->GetBinCenter(startBin + i));
936  }
937  }
938  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING &&
939  potPlots_[detId_pot].activity_per_bx.count(rechit.ootIndex()) > 0)
940  potPlots_[detId_pot].activity_per_bx.at(rechit.ootIndex())->Fill(event.bunchCrossing());
941 
942  // if(plotOffline_)
943  // potPlots_[detId_pot].TOTVsLS->Fill(event.luminosityBlock(),rechit.toT());
944  }
945  }
946 
947  for (const auto& plt : potPlots_) {
948  plt.second.activePlanes->Fill(planes[plt.first].size());
949  if (plotOnline_)
950  plt.second.activePlanesInclusive->Fill(planes_inclusive[plt.first].size());
951  }
952 
953  // Using CTPPSDiamondLocalTrack
954  for (const auto& tracks : *diamondLocalTracks) {
955  const CTPPSDiamondDetId detId(tracks.detId()), detId_pot(detId.rpId());
956  const auto& x_shift = diamShifts_.at(detId_pot);
957 
958  for (const auto& track : tracks) {
959  if (!track.isValid())
960  continue;
962  continue;
963  if (excludeMultipleHits_ && track.multipleHits() > 0)
964  continue;
965  if (potPlots_.count(detId_pot) == 0)
966  continue;
967 
968  TH2F* trackHistoOOTTmp = potPlots_[detId_pot].trackDistributionOOT->getTH2F();
969  TAxis* trackHistoOOTTmpYAxis = trackHistoOOTTmp->GetYaxis();
970  int startBin = trackHistoOOTTmpYAxis->FindBin(track.x0() - x_shift.global - track.x0Sigma());
971  int numOfBins = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
972  for (int i = 0; i < numOfBins; ++i)
973  trackHistoOOTTmp->Fill(track.ootIndex(), trackHistoOOTTmpYAxis->GetBinCenter(startBin + i));
974 
975  if (centralOOT_ != -999 && track.ootIndex() == centralOOT_) {
976  TH1F* trackHistoInTimeTmp = potPlots_[detId_pot].trackDistribution->getTH1F();
977  int startBin = trackHistoInTimeTmp->FindBin(track.x0() - x_shift.global - track.x0Sigma());
978  int numOfBins = 2 * track.x0Sigma() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
979  for (int i = 0; i < numOfBins; ++i)
980  trackHistoInTimeTmp->Fill(trackHistoInTimeTmp->GetBinCenter(startBin + i));
981  }
982  if (plotOffline_ && !perLSsaving_) {
983  // potPlots_[detId_pot].trackTimeVsLS->Fill(event.luminosityBlock(),track.time());
984  potPlots_[detId_pot].trackTimeVsBX->Fill(event.bunchCrossing(), track.time());
985  //potPlots_[detId_pot].trackTimeVsXAngle->Fill(hLhcInfo->crossingAngle(), track.time());
986  }
987  }
988  }
989 
990  // Channel efficiency using CTPPSDiamondLocalTrack
991  for (const auto& tracks : *diamondLocalTracks) {
992  const CTPPSDiamondDetId detId(tracks.detId()), detId_pot(detId.rpId());
993  for (const auto& track : tracks) {
994  // Find hits and planes in the track
995  int numOfHits = 0;
996  std::set<int> planesInTrackSet;
997  for (const auto& vec : *diamondRecHits) {
998  const CTPPSDiamondDetId detid(vec.detId());
999  if (detid.arm() != detId_pot.arm())
1000  continue;
1001 
1002  for (const auto& hit : vec) {
1003  // first check if the hit contributes to the track
1004  if (track.containsHit(hit)) {
1005  ++numOfHits;
1006  planesInTrackSet.insert(detid.plane());
1007  }
1008  }
1009  }
1010 
1011  if (numOfHits > 0 && numOfHits <= 10 && planesInTrackSet.size() > 2) {
1012  for (const auto& plt_vs_ch : channelPlots_) { // loop over all channels registered in geometry
1013  const CTPPSDiamondDetId detId(plt_vs_ch.first);
1014  if (detId.rpId() != detId_pot)
1015  continue;
1016  const unsigned short map_index = detId.plane() * 100 + detId.channel();
1017  if (potPlots_[detId_pot].effDoublecountingChMap.count(map_index) == 0) {
1018  potPlots_[detId_pot].effTriplecountingChMap[map_index] = 0;
1019  potPlots_[detId_pot].effDoublecountingChMap[map_index] = 0;
1020  }
1021  if (channelAlignedWithTrack(ctppsGeometry, detId, track, 0.2)) {
1022  // Channel should fire
1023  ++potPlots_[detId_pot].effDoublecountingChMap[map_index];
1024  for (const auto& rechits : *diamondRecHits) {
1025  const CTPPSDiamondDetId detId_hit(rechits.detId());
1026  if (detId_hit == detId)
1027  for (const auto& rechit : rechits)
1028  if (track.containsHit(rechit, 1)) // Channel fired
1029  ++potPlots_[detId_pot].effTriplecountingChMap[map_index];
1030  }
1031  }
1032  }
1033  }
1034  }
1035  }
1036 
1037  // Tomography of diamonds using pixel
1038  for (const auto& rechits : *diamondRecHits) {
1039  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
1040  const auto pix_shift = diamShifts_.at(detId_pot).withPixels;
1041  for (const auto& rechit : rechits) {
1042  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1043  continue;
1044  if (rechit.toT() == 0)
1045  continue;
1046  if (!pixelTracks.isValid())
1047  continue;
1048  if (potPlots_.count(detId_pot) == 0)
1049  continue;
1050 
1051  for (const auto& ds : *pixelTracks) {
1052  if (ds.size() > 1)
1053  continue;
1054  const CTPPSPixelDetId pixId(ds.detId());
1055  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID)
1056  continue;
1057  for (const auto& lt : ds) {
1058  if (lt.isValid() && pixId.arm() == detId_pot.arm()) {
1059  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.ootIndex() >= 0 &&
1060  potPlots_[detId_pot].pixelTomographyAll.count(rechit.ootIndex()) > 0 && lt.x0() - pix_shift < 24)
1061  potPlots_[detId_pot]
1062  .pixelTomographyAll.at(rechit.ootIndex())
1063  ->Fill(lt.x0() - pix_shift + 25 * detId.plane(), lt.y0());
1064  }
1065  }
1066  }
1067  }
1068  }
1069 
1070  //------------------------------
1071  // Clock Plots
1072  //------------------------------
1073  // Commented out to save space in the DQM files, but code should be kept
1074  // for ( const auto& digis : *diamondDigis ) {
1075  // const CTPPSDiamondDetId detId(digis.detId()), detId_pot(detId.rpId());
1076  // if ( detId.channel() == CHANNEL_OF_VFAT_CLOCK ) {
1077  // for ( const auto& digi : digis ) {
1078  // if ( digi.leadingEdge() != 0 ) {
1079  // if ( detId.plane() == 1 ) {
1080  // potPlots_[detId_pot].clock_Digi1_le->Fill( HPTDC_BIN_WIDTH_NS * digi.leadingEdge() );
1081  // potPlots_[detId_pot].clock_Digi1_te->Fill( HPTDC_BIN_WIDTH_NS * digi.trailingEdge() );
1082  // }
1083  // if ( detId.plane() == 3 ) {
1084  // potPlots_[detId_pot].clock_Digi3_le->Fill( HPTDC_BIN_WIDTH_NS * digi.leadingEdge() );
1085  // potPlots_[detId_pot].clock_Digi3_te->Fill( HPTDC_BIN_WIDTH_NS * digi.trailingEdge() );
1086  // }
1087  // }
1088  // }
1089  // }
1090  // }
1091 
1092  //------------------------------
1093  // Plane Plots
1094  //------------------------------
1095 
1096  // Using CTPPSDiamondDigi
1097  std::unordered_map<unsigned int, unsigned int> channelsPerPlane;
1098  if (extract_digi_info_) {
1099  for (const auto& digis : *diamondDigis) {
1100  const CTPPSDiamondDetId detId(digis.detId()), detId_plane(detId.planeId());
1101  for (const auto& digi : digis) {
1102  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
1103  continue;
1104  if (planePlots_.count(detId_plane) == 0)
1105  continue;
1106 
1107  if (digi.leadingEdge() != 0) {
1108  planePlots_[detId_plane].digiProfileCumulativePerPlane->Fill(detId.channel());
1109  channelsPerPlane[detId_plane]++;
1110  }
1111  }
1112  }
1113  }
1114 
1115  for (const auto& plt : channelsPerPlane)
1116  planePlots_[plt.first].hit_multiplicity->Fill(plt.second);
1117 
1118  // Using CTPPSDiamondRecHit
1119  for (const auto& rechits : *diamondRecHits) {
1120  const CTPPSDiamondDetId detId(rechits.detId()), detId_plane(detId.planeId()), detId_pot(detId.rpId());
1121  for (const auto& rechit : rechits) {
1122  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1123  continue;
1124  if (rechit.toT() == 0)
1125  continue;
1126  if (planePlots_.count(detId_plane) != 0) {
1127  if (centralOOT_ != -999 && rechit.ootIndex() == centralOOT_) {
1128  TH1F* hitHistoTmp = planePlots_[detId_plane].hitProfile->getTH1F();
1129  int startBin = hitHistoTmp->FindBin(rechit.x() - diamShifts_.at(detId_pot).global - 0.5 * rechit.xWidth());
1130  int numOfBins = rechit.xWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
1131  for (int i = 0; i < numOfBins; ++i)
1132  hitHistoTmp->Fill(hitHistoTmp->GetBinCenter(startBin + i));
1133  }
1134  }
1135  }
1136  }
1137 
1138  //Tomography of diamonds using pixel and Efficiency WRT Pixels
1139  for (const auto& ds : *pixelTracks) {
1140  const CTPPSPixelDetId pixId(ds.detId());
1141  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID)
1142  continue;
1143  if (ds.size() > 1)
1144  continue;
1145  for (const auto& lt : ds) {
1146  if (lt.isValid()) {
1147  for (const auto& sh_vs_id : diamShifts_) {
1148  const CTPPSDiamondDetId& detId_pot = sh_vs_id.first;
1149  const auto& shift = sh_vs_id.second;
1150  if (detId_pot.arm() == pixId.arm())
1151  // For efficieny
1152  potPlots_[detId_pot].pixelTracksMap.Fill(lt.x0() - shift.withPixels, lt.y0());
1153  }
1154 
1155  std::set<CTPPSDiamondDetId> planesWitHits_set;
1156  for (const auto& rechits : *diamondRecHits) {
1157  const CTPPSDiamondDetId detId(rechits.detId()), detId_plane(detId.planeId()), detId_pot(detId.rpId());
1158  const auto pix_shift = diamShifts_.at(detId_pot).withPixels;
1159  for (const auto& rechit : rechits) {
1160  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1161  continue;
1162  if (rechit.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.toT() == 0)
1163  continue;
1164  if (planePlots_.count(detId_plane) == 0)
1165  continue;
1166  if (pixId.arm() == detId_plane.arm() && lt.x0() - pix_shift < 24) {
1167  planePlots_[detId_plane].pixelTomography_far->Fill(lt.x0() - pix_shift + 25 * rechit.ootIndex(), lt.y0());
1168  if (centralOOT_ != -999 && rechit.ootIndex() == centralOOT_)
1169  planesWitHits_set.insert(detId_plane);
1170  }
1171  }
1172  }
1173 
1174  for (auto& planeId : planesWitHits_set)
1175  planePlots_[planeId].pixelTracksMapWithDiamonds.Fill(lt.x0() - diamShifts_.at(planeId.rpId()).withPixels,
1176  lt.y0());
1177  }
1178  }
1179  }
1180 
1181  //------------------------------
1182  // Channel Plots
1183  //------------------------------
1184 
1185  // digi profile cumulative
1186  if (extract_digi_info_) {
1187  for (const auto& digis : *diamondDigis) {
1188  const CTPPSDiamondDetId detId(digis.detId());
1189  for (const auto& digi : digis) {
1190  if (detId.channel() == CHANNEL_OF_VFAT_CLOCK)
1191  continue;
1192  if (channelPlots_.count(detId) != 0) {
1193  // HPTDC Errors
1194  const HPTDCErrorFlags hptdcErrors = digi.hptdcErrorFlags();
1195  for (unsigned short hptdcErrorIndex = 1; hptdcErrorIndex < 16; ++hptdcErrorIndex)
1196  if (hptdcErrors.errorId(hptdcErrorIndex - 1))
1197  channelPlots_[detId].HPTDCErrorFlags->Fill(hptdcErrorIndex);
1198  if (digi.multipleHit())
1199  ++channelPlots_[detId].MHCounter;
1200 
1201  // Check dropped trailing edges
1202  if (digi.leadingEdge() != 0 || digi.trailingEdge() != 0) {
1203  ++channelPlots_[detId].HitCounter;
1204  if (digi.trailingEdge() == 0) {
1205  ++channelPlots_[detId].LeadingOnlyCounter;
1206  channelPlots_[detId].leadingEdgeCumulative_le->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge());
1207  } else if (digi.leadingEdge() == 0) {
1208  ++channelPlots_[detId].TrailingOnlyCounter;
1209  channelPlots_[detId].trailingEdgeCumulative_te->Fill(HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1210  } else {
1211  ++channelPlots_[detId].CompleteCounter;
1212  // channelPlots_[detId].LeadingTrailingCorrelationPerChannel->Fill(HPTDC_BIN_WIDTH_NS * digi.leadingEdge(),
1213  // HPTDC_BIN_WIDTH_NS * digi.trailingEdge());
1214  }
1215  }
1216  }
1217  }
1218  }
1219  }
1220 
1221  // Using CTPPSDiamondRecHit
1222 
1223  for (const auto& rechits : *diamondRecHits) {
1224  CTPPSDiamondDetId detId(rechits.detId());
1225  for (const auto& rechit : rechits) {
1226  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1227  continue;
1228  if (channelPlots_.count(detId) != 0) {
1229  channelPlots_[detId].recHitTime->Fill(rechit.time());
1230  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING && rechit.toT() != 0) {
1231  channelPlots_[detId].leadingEdgeCumulative_both->Fill(rechit.time() + 25 * rechit.ootIndex());
1232  channelPlots_[detId].TimeOverThresholdCumulativePerChannel->Fill(rechit.toT());
1233  }
1234  ++lumiCache->hitsCounterMap[detId];
1235 
1236  if (rechit.ootIndex() != CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING &&
1237  channelPlots_[detId].activity_per_bx.count(rechit.ootIndex()) > 0)
1238  channelPlots_[detId].activity_per_bx.at(rechit.ootIndex())->Fill(event.bunchCrossing());
1239  }
1240  }
1241  }
1242 
1243  // Tomography of diamonds using pixel
1244  for (const auto& rechits : *diamondRecHits) {
1245  const CTPPSDiamondDetId detId(rechits.detId()), detId_pot(detId.rpId());
1246  const auto shift_pix = diamShifts_.at(detId_pot).withPixels;
1247  for (const auto& rechit : rechits) {
1248  if (excludeMultipleHits_ && rechit.multipleHits() > 0)
1249  continue;
1250  if (rechit.ootIndex() == CTPPSDiamondRecHit::TIMESLICE_WITHOUT_LEADING || rechit.toT() == 0)
1251  continue;
1252  if (!pixelTracks.isValid())
1253  continue;
1254  if (channelPlots_.count(detId) == 0)
1255  continue;
1256 
1257  for (const auto& ds : *pixelTracks) {
1258  const CTPPSPixelDetId pixId(ds.detId());
1259  if (pixId.station() != CTPPS_PIXEL_STATION_ID || pixId.rp() != CTPPS_FAR_RP_ID)
1260  continue;
1261  if (ds.size() > 1)
1262  continue;
1263  for (const auto& lt : ds) {
1264  if (lt.isValid() && pixId.arm() == detId.arm() && lt.x0() - shift_pix < 24)
1265  channelPlots_[detId].pixelTomography_far->Fill(lt.x0() - shift_pix + 25 * rechit.ootIndex(), lt.y0());
1266  }
1267  }
1268  }
1269  }
1270 }
1271 
1272 //----------------------------------------------------------------------------------------------------
1273 
1275  auto lumiCache = luminosityBlockCache(iLumi.index());
1276  if (!perLSsaving_) {
1277  if (plotOnline_)
1278  for (auto& plot : potPlots_) {
1279  *(plot.second.hitDistribution2d_lumisection->getTH2F()) = *(lumiCache->hitDistribution2dMap[plot.first]);
1280  }
1281 
1282  for (auto& plot : channelPlots_) {
1283  auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[plot.first];
1284  if (hitsCounterPerLumisection != 0) {
1285  plot.second.hit_rate->Fill((double)hitsCounterPerLumisection / SEC_PER_LUMI_SECTION);
1286  }
1287 
1288  double HundredOverHitCounter = .0;
1289  if (plot.second.HitCounter != 0)
1290  HundredOverHitCounter = 100. / plot.second.HitCounter;
1291  plot.second.HPTDCErrorFlags->setBinContent(16, HundredOverHitCounter * plot.second.MHCounter);
1292  plot.second.leadingWithoutTrailing->setBinContent(1, HundredOverHitCounter * plot.second.LeadingOnlyCounter);
1293  plot.second.leadingWithoutTrailing->setBinContent(2, HundredOverHitCounter * plot.second.TrailingOnlyCounter);
1294  plot.second.leadingWithoutTrailing->setBinContent(3, HundredOverHitCounter * plot.second.CompleteCounter);
1295  }
1296 
1297  for (auto& plot : potPlots_) {
1298  double HundredOverHitCounterPot = 0.;
1299  if (plot.second.HitCounter != 0)
1300  HundredOverHitCounterPot = 100. / plot.second.HitCounter;
1301  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1302  1, HundredOverHitCounterPot * plot.second.LeadingOnlyCounter);
1303  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1304  2, HundredOverHitCounterPot * plot.second.TrailingOnlyCounter);
1305  plot.second.leadingWithoutTrailingCumulativePot->setBinContent(
1306  3, HundredOverHitCounterPot * plot.second.CompleteCounter);
1307 
1308  plot.second.MHComprensive->Reset();
1309  const CTPPSDiamondDetId rpId(plot.first);
1310  for (auto& chPlot : channelPlots_) {
1311  const CTPPSDiamondDetId chId(chPlot.first);
1312  if (chId.arm() == rpId.arm() && chId.rp() == rpId.rp()) {
1313  plot.second.MHComprensive->Fill(
1314  chId.plane(), chId.channel(), chPlot.second.HPTDCErrorFlags->getBinContent(16));
1315  }
1316  }
1317  }
1318  // Efficiencies of single channels
1319  if (plotOnline_)
1320  for (auto& plot : potPlots_) {
1321  plot.second.EfficiencyOfChannelsInPot->Reset();
1322  for (auto& element : plot.second.effTriplecountingChMap) {
1323  if (plot.second.effDoublecountingChMap[element.first] > 0) {
1324  int plane = element.first / 100;
1325  int channel = element.first % 100;
1326  double counted = element.second;
1327  double total = plot.second.effDoublecountingChMap[element.first];
1328  double efficiency = counted / total;
1329  // double error = std::sqrt( efficiency * ( 1 - efficiency ) / total );
1330 
1331  plot.second.EfficiencyOfChannelsInPot->Fill(plane, channel, 100 * efficiency);
1332  }
1333  }
1334  }
1335 
1336  // Efficeincy wrt pixels //TODO
1337  for (auto& plot : planePlots_) {
1338  TH2F* hitHistoTmp = plot.second.EfficiencyWRTPixelsInPlane->getTH2F();
1339 
1340  const CTPPSDiamondDetId detId(plot.first), detId_pot(detId.rpId());
1341  hitHistoTmp->Divide(&(plot.second.pixelTracksMapWithDiamonds), &(potPlots_[detId_pot].pixelTracksMap));
1342  }
1343  } //perLSsaving
1344 }
1345 
1346 //----------------------------------------------------------------------------------------------------
1347 
1349  const TotemFEDInfo& optorx,
1350  const TotemVFATStatus& status,
1352  int& EC_difference) const {
1353  const CTPPSDiamondDetId detId_pot(detId.rpId());
1354  if (plotOnline_)
1355  plots.ECCheck->Fill((int)((optorx.lv1() & 0xFF) - ((unsigned int)status.ec() & 0xFF)) & 0xFF);
1356  if ((static_cast<int>((optorx.lv1() & 0xFF) - status.ec()) != EC_difference) &&
1357  (static_cast<uint8_t>((optorx.lv1() & 0xFF) - status.ec()) < 128))
1358  EC_difference = static_cast<int>(optorx.lv1() & 0xFF) - (static_cast<unsigned int>(status.ec()) & 0xFF);
1359  if (EC_difference != 1 && EC_difference != -500 && std::abs(EC_difference) < 127) {
1360  if (detId.channel() == HPTDC_0_CHANNEL || detId.channel() == HPTDC_1_CHANNEL)
1361  plots.HPTDCErrorFlags_2D->Fill(16, 2 * detId.plane() + (detId.channel() - HPTDC_0_CHANNEL));
1362  if (verbosity_)
1363  edm::LogProblem("CTPPSDiamondDQMSource")
1364  << "FED " << optorx.fedId() << ": ECError at EV: 0x" << std::hex << optorx.lv1() << "\t\tVFAT EC: 0x"
1365  << static_cast<unsigned int>(status.ec()) << "\twith ID: " << std::dec << detId
1366  << "\tdiff: " << EC_difference;
1367  }
1368 }
1369 
1370 //----------------------------------------------------------------------------------------------------
1371 
1373  if (plotOffline_ && !perLSsaving_)
1374  for (const auto& rpPlots : potPlots_) {
1375  auto plots = rpPlots.second;
1376  // *(plots.TOTVsLSProfile->getTProfile())=*plots.TOTVsLS->getTH2F()->ProfileX();
1377  // *(plots.trackTimeVsLSProfile->getTProfile())=*plots.trackTimeVsLS->getTH2F()->ProfileX();
1378  *(plots.trackTimeVsBXProfile->getTProfile()) = *plots.trackTimeVsBX->getTH2F()->ProfileX();
1379  // *(plots.trackTimeVsXAngleProfile->getTProfile()) = *plots.trackTimeVsXAngle->getTH2F()->ProfileX();
1380  }
1381 }
1382 
1383 //----------------------------------------------------------------------------------------------------
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.
def window
Definition: svgfig.py:643
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
RunNumber_t run() const
Definition: RunBase.h:40
LuminosityBlockIndex index() const
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
static constexpr unsigned short CTPPS_DIAMOND_NUM_OF_CHANNELS
const Translation & translation() const
Definition: DetGeomDesc.h:80
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
Reconstructed hit in diamond detectors.
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const double tolerance
void channelName(std::string &name, NameFlag flag=nFull) const
const DiamondDimensions & getDiamondDimensions() const
Definition: DetGeomDesc.h:90
void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override
CTPPSDiamondDetId planeId() const
CTPPSDiamondDQMSource(const edm::ParameterSet &)
plots related to the whole system
list status
Definition: mps_update.py:107
int bunchCrossing() const
Definition: EventBase.h:64
static constexpr unsigned short CTPPS_PIXEL_STATION_ID
std::shared_ptr< dds::Cache > globalBeginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) const override
auto const & tracks
cannot be loose
mapType::const_iterator beginSensor() const
begin iterator over sensors
Definition: CTPPSGeometry.h:67
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > ctppsGeometryEventToken_
edm::EDGetTokenT< edm::DetSetVector< CTPPSDiamondLocalTrack > > tokenDiamondTrack_
Event setup record containing the real (actual) geometry information.
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
CTPPSDetId rpId() const
Definition: CTPPSDetId.h:78
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
void Fill(long long x)
static std::string hptdcErrorName(const unsigned short id)
bool getData(T &iHolder) const
Definition: EventSetup.h:128
tuple d
Definition: ztail.py:151
std::vector< std::pair< edm::EventRange, int > > runParameters_
uint32_t lv1() const
Definition: TotemFEDInfo.h:26
edm::EDGetTokenT< edm::DetSetVector< CTPPSDiamondDigi > > tokenDigi_
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:322
def plot
Definition: bigModule.py:18
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
std::unordered_map< unsigned int, ChannelPlots > channelPlots_
RPDeviceMapType::const_iterator beginRP() const
begin iterator over RPs
Definition: CTPPSGeometry.h:72
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
void rpName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:128
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
uint32_t plane() const
LuminosityBlock const & getLuminosityBlock() const
Definition: Event.h:100
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:50
uint32_t arm() const
Definition: CTPPSDetId.h:51
bool isValid() const
Definition: HandleBase.h:70
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 armName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:92
CTPPSDetId armId() const
Definition: CTPPSDetId.h:74
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
int fedId() const
Definition: TotemFEDInfo.h:22
const DetGeomDesc * sensor(unsigned int id) const
returns geometry of a detector performs necessary checks, returns NULL if fails
uint32_t channel() const
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:177
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
mapType::const_iterator endSensor() const
end iterator over sensors
Definition: CTPPSGeometry.h:69
void planeName(std::string &name, NameFlag flag=nFull) const
std::unordered_map< unsigned int, MonitorElement * > activity_per_bx
RPDeviceMapType::const_iterator endRP() const
end iterator over RPs
Definition: CTPPSGeometry.h:74
bool channelAlignedWithTrack(const CTPPSGeometry *geom, const CTPPSDiamondDetId &detid, const CTPPSDiamondLocalTrack &localTrack, const float tolerance=1)
std::unordered_map< unsigned int, PotPlots > potPlots_
static constexpr int TIMESLICE_WITHOUT_LEADING
static constexpr unsigned short CTPPS_FED_ID_56
static constexpr double HPTDC_BIN_WIDTH_NS
ns per HPTDC bin
bool errorId(unsigned short id) const
< trclass="colgroup">< tdclass="colgroup"colspan=5 > DT local reconstruction</td ></tr >< tr >< td >< ahref="classDTRecHit1DPair.html"> DTRecHit1DPair</a ></td >< td >< ahref="DataFormats_DTRecHit.html"> edm::RangeMap & lt
static constexpr double INV_DISPLAY_RESOLUTION_FOR_HITS_MM
void checkEventNumber(const CTPPSDiamondDetId &, const TotemFEDInfo &, const TotemVFATStatus &, PotPlots &, int &) 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
uint8_t ec() const
event Counter
std::unordered_map< unsigned int, unsigned long > hitsCounterMap
Definition: Run.h:45
Log< level::Error, true > LogProblem
uint32_t rp() const
Definition: CTPPSDetId.h:65