CMS 3D CMS Logo

TotemTimingDQMSource.cc
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * This is a part of CTPPS offline software.
4  * Authors:
5  * Nicola Minafra
6  * Laurent Forthomme
7  *
8  ****************************************************************************/
9 
17 
20 
27 
31 
36 
37 #include <string>
38 
39 //----------------------------------------------------------------------------------------------------
40 
41 namespace totemds {
42  struct Cache {
43  std::unordered_map<unsigned int, std::unique_ptr<TH2F>> hitDistribution2dMap;
44 
45  std::unordered_map<unsigned int, unsigned long> hitsCounterMap;
46  };
47 } // namespace totemds
48 
49 class TotemTimingDQMSource : public DQMOneEDAnalyzer<edm::LuminosityBlockCache<totemds::Cache>> {
50 public:
52  ~TotemTimingDQMSource() override;
53 
54 protected:
55  void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override;
56  void bookHistograms(DQMStore::IBooker &, const edm::Run &, const edm::EventSetup &) override;
57  void analyze(const edm::Event &, const edm::EventSetup &) override;
58  std::shared_ptr<totemds::Cache> globalBeginLuminosityBlock(const edm::LuminosityBlock &,
59  const edm::EventSetup &) const override;
60  void globalEndLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) override;
61 
62 private:
63  // Constants
64  static const double SEC_PER_LUMI_SECTION; // Number of seconds per
65  // lumisection: used to compute hit
66  // rates in Hz
67  static const double LHC_CLOCK_PERIOD_NS;
68  static const double DQM_FRACTION_OF_EVENTS; // approximate fraction of events
69  // sent to DQM stream
70  static const double HIT_RATE_FACTOR; // factor to have real rate in Hz
71  static const double DISPLAY_RESOLUTION_FOR_HITS_MM; // Bin width of histograms
72  // showing hits and tracks
73  // (in mm)
75  static const double TOMOGRAPHY_RESOLUTION_MM;
76  static const double SAMPIC_SAMPLING_PERIOD_NS; // ns per HPTDC bin
77  static const double SAMPIC_MAX_NUMBER_OF_SAMPLES;
78  static const double SAMPIC_ADC_V;
79  static const int CTPPS_NUM_OF_ARMS;
80  static const int TOTEM_TIMING_STATION_ID;
81  static const int TOTEM_STATION_210;
82  static const int TOTEM_STATION_220;
83  static const int TOTEM_TIMING_TOP_RP_ID;
84  static const int TOTEM_TIMING_BOT_RP_ID;
85  static const int TOTEM_STRIP_MIN_RP_ID;
86  static const int TOTEM_STRIP_MAX_RP_ID;
87  static const int CTPPS_NEAR_RP_ID;
88  static const int CTPPS_FAR_RP_ID;
89  static const int TOTEM_TIMING_NUM_OF_PLANES;
90  static const int TOTEM_TIMING_NUM_OF_CHANNELS;
91  static const int TOTEM_TIMING_FED_ID_45;
92  static const int TOTEM_TIMING_FED_ID_56;
93  static const float COS_8_DEG;
94  static const float SIN_8_DEG;
95 
100 
103 
106  unsigned int samplesForNoise_;
107  bool perLSsaving_; //to avoid nanoDQMIO crashing, driven by DQMServices/Core/python/DQMStore_cfi.py
108  unsigned int verbosity_;
110 
112 
114  struct GlobalPlots {
116 
118  GlobalPlots(DQMStore::IBooker &ibooker);
119  };
120 
122 
124  struct PotPlots {
125  // Digis
131 
135 
136  // RecHits
140 
147 
149 
152 
153  // MonitorElement *trackDistribution = nullptr;
154 
157 
158  std::set<unsigned int> planesWithDigisSet;
159  std::set<unsigned int> planesWithTimeSet;
160 
161  PotPlots(){};
162  PotPlots(DQMStore::IBooker &ibooker, unsigned int id);
163  };
164 
165  std::unordered_map<unsigned int, PotPlots> potPlots_;
166 
168  struct PlanePlots {
170 
174 
176  PlanePlots(DQMStore::IBooker &ibooker, unsigned int id);
177  };
178 
179  std::unordered_map<unsigned int, PlanePlots> planePlots_;
180 
182  struct ChannelPlots {
183  // Digis
188 
189  // RecHits
194 
197 
200 
202  ChannelPlots(DQMStore::IBooker &ibooker, unsigned int id);
203  };
204 
205  std::unordered_map<unsigned int, ChannelPlots> channelPlots_;
206 };
207 
208 //----------------------------------------------------------------------------------------------------
209 
210 // Values for all constants
211 const double TotemTimingDQMSource::SEC_PER_LUMI_SECTION = 23.31;
212 const double TotemTimingDQMSource::LHC_CLOCK_PERIOD_NS = 24.95;
214 const double TotemTimingDQMSource::HIT_RATE_FACTOR = DQM_FRACTION_OF_EVENTS / SEC_PER_LUMI_SECTION;
216 const double TotemTimingDQMSource::INV_DISPLAY_RESOLUTION_FOR_HITS_MM = 1. / DISPLAY_RESOLUTION_FOR_HITS_MM;
218 const double TotemTimingDQMSource::SAMPIC_SAMPLING_PERIOD_NS = 1. / 7.8e9;
220 const double TotemTimingDQMSource::SAMPIC_ADC_V = 1. / 256;
235 const float TotemTimingDQMSource::COS_8_DEG = 0.990268;
236 const float TotemTimingDQMSource::SIN_8_DEG = -0.139173;
237 
238 //----------------------------------------------------------------------------------------------------
239 
241  ibooker.setCurrentFolder("CTPPS/TimingFastSilicon");
242 
243  digiSentPercentage = ibooker.book2D(
244  "sent digis percentage", "sent digis percentage (sampic);board + 0.5 sampic;channel", 14, -0.5, 6.5, 16, 0, 16);
245 }
246 
247 //----------------------------------------------------------------------------------------------------
248 
252  ibooker.setCurrentFolder(path);
253 
255 
256  activityPerBX = ibooker.book1D("activity per BX CMS", title + " Activity per BX;Event.BX", 3600, -1.5, 3598. + 0.5);
257 
258  digiDistribution =
259  ibooker.book2D("digi distribution", title + " digi distribution;plane;channel", 10, -0.5, 4.5, 12, 0, 12);
260 
261  dataSamplesRaw = ibooker.book1D("raw Samples", title + " Raw Samples; ADC", 256, 0, 256);
262 
263  baseline = ibooker.book2D("baseline", title + " baseline (V);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
264  noiseRMS = ibooker.book2D("noise RMS", title + " noise RMS (V);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
265 
266  digiSent =
267  ibooker.book2D("digis sent", title + " digi sent (sampic);board + 0.5 sampic;channel", 14, -0.5, 6.5, 16, 0, 16);
268  digiAll =
269  ibooker.book2D("all digis", title + " all digis(sampic);board + 0.5 sampic;channel", 14, -0.5, 6.5, 16, 0, 16);
270  digiSentPercentage = ibooker.book2D("sent digis percentage",
271  title + " sent digis percentage (sampic);board + 0.5 sampic;channel",
272  14,
273  -0.5,
274  6.5,
275  16,
276  0,
277  16);
278 
279  hitDistribution2d = ibooker.book2D("hits in planes",
280  title + " hits in planes;plane number;x (mm)",
281  18,
282  -0.5,
283  4,
285  0,
286  15);
287  hitDistribution2dWithTime = ibooker.book2D("hits in planes with time",
288  title + " hits in planes with time;plane number;x (mm)",
289  18,
290  -0.5,
291  4,
293  0,
294  15);
295  hitDistribution2d_lumisection = ibooker.book2D("hits in planes lumisection",
296  title + " hits in planes in the last lumisection;plane number;x (mm)",
297  18,
298  -0.5,
299  4,
301  0,
302  15);
303 
304  recHitTime = ibooker.book1D("recHit time", title + " time in the recHits; t (ns)", 500, -25, 25);
305  amplitude = ibooker.book1D("amplitude", title + " amplitude above baseline; amplitude (V)", 50, 0, 1);
306  tirggerCellTime = ibooker.book1D("trigger cell time", title + " Trigger Cell Time; t (ns)", 390, -25, 25);
307  baselineRMS = ibooker.book2D("noise RMS", title + " noise RMS (V);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
308  meanAmplitude =
309  ibooker.book2D("mean amplitude", title + " Mean Amplitude (V);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
310  cellOfMax = ibooker.book2D("cell of max", title + " cell of max (0-23);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
311 
312  hitRate = ibooker.book2D("hit rate", title + " hit rate (Hz);plane;channel", 10, -0.5, 4.5, 12, 0, 12);
313 
314  planesWithDigis = ibooker.book1D(
315  "active planes digis", title + " active planes with digis sent (per event);number of active planes", 6, -0.5, 5.5);
316  planesWithTime = ibooker.book1D(
317  "active planes with time", title + " active planes with time (per event);number of active planes", 6, -0.5, 5.5);
318 
319  // trackDistribution = ibooker.book1D( "tracks", title+" tracks;x (mm)",
320  // 19.*INV_DISPLAY_RESOLUTION_FOR_HITS_MM, -1, 18 ); //TODO needs tracks
321 
322  stripTomography210 =
323  ibooker.book2D("tomography 210",
324  title + " tomography (only with time) with strips 210 (all planes);x + 50*plane(mm);y (mm)",
326  -20,
327  170,
329  0,
330  25);
331  stripTomography220 =
332  ibooker.book2D("tomography 220",
333  title + " tomography (only with time) with strips 220 (all planes);x + 50*plane(mm);y (mm)",
335  -20,
336  170,
338  0,
339  25);
340 }
341 
342 //----------------------------------------------------------------------------------------------------
343 
347  ibooker.setCurrentFolder(path);
348 
350 
351  digiDistribution = ibooker.book1D("digi distribution", title + " digi distribution;channel", 12, 0, 12);
352 
353  hitProfile = ibooker.book1D("hit distribution with time",
354  title + " hit distribution (with time);y (+ 15 for x>3) (mm)",
356  0,
357  30);
358 
359  hitMultiplicity = ibooker.book1D("channels per plane", title + " channels per plane; ch per plane", 13, -0.5, 12.5);
360 
361  hitMultiplicityWithTime = ibooker.book1D(
362  "channels per plane with time", title + " channels per plane with time; ch per plane", 13, -0.5, 12.5);
363 }
364 
365 //----------------------------------------------------------------------------------------------------
366 
370  ibooker.setCurrentFolder(path);
371 
373 
374  activityPerBX = ibooker.book1D("activity per BX", title + " Activity per BX;Event.BX", 1000, -1.5, 998. + 0.5);
375  dataSamplesRaw = ibooker.book1D("raw samples", title + " Raw Samples; ADC", 256, 0, 256);
376  cellOfMax = ibooker.book1D("cell of max", title + " cell of max; cell", 24, 0, 24);
377 
378  tirggerCellTime = ibooker.book1D("sampic trigger time", title + " Sampic Trigger Time; t (ns)", 100, -25, 25);
379  recHitTime = ibooker.book1D("recHit Time", title + " recHit Time; t (ns)", 500, -25, 25);
380  amplitude = ibooker.book1D("amplitude", title + " amplitude above baseline; amplitude (V)", 50, 0, 1);
381  noiseSamples = ibooker.book1D("noise samples", title + " noise samples; V", 50, 0, 1);
382 
383  hitTime = ibooker.book1D("hit time", title + "hit time;t - t_previous (us)", 100, 0, 10000);
384  hitRate = ibooker.book1D("hit rate", title + "hit rate;rate (Hz)", 100, 0, 10000);
385 
386  stripTomography210 = ibooker.book2D("tomography 210",
387  title + " tomography with strips 210;x (mm);y (mm)",
389  -20,
390  20,
392  0,
393  25);
394  stripTomography220 = ibooker.book2D("tomography 220",
395  title + " tomography with strips 220;x (mm);y (mm)",
397  -20,
398  20,
400  0,
401  25);
402 }
403 
404 //----------------------------------------------------------------------------------------------------
405 
408  consumes<edm::DetSetVector<TotemRPLocalTrack>>(ps.getUntrackedParameter<edm::InputTag>("tagLocalTrack"))),
409  tokenDigi_(consumes<edm::DetSetVector<TotemTimingDigi>>(ps.getUntrackedParameter<edm::InputTag>("tagDigi"))),
410  tokenRecHit_(
411  consumes<edm::DetSetVector<TotemTimingRecHit>>(ps.getUntrackedParameter<edm::InputTag>("tagRecHits"))),
412  // tokenTrack_(consumes<edm::DetSetVector<TotemTimingLocalTrack>>(
413  // ps.getParameter<edm::InputTag>("tagLocalTracks"))),
414  tokenFEDInfo_(consumes<std::vector<TotemFEDInfo>>(ps.getUntrackedParameter<edm::InputTag>("tagFEDInfo"))),
417  minimumStripAngleForTomography_(ps.getParameter<double>("minimumStripAngleForTomography")),
418  maximumStripAngleForTomography_(ps.getParameter<double>("maximumStripAngleForTomography")),
419  samplesForNoise_(ps.getUntrackedParameter<unsigned int>("samplesForNoise", 5)),
420  perLSsaving_(ps.getUntrackedParameter<bool>("perLSsaving", false)),
421  verbosity_(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
423 
424 //----------------------------------------------------------------------------------------------------
425 
427 
428 //----------------------------------------------------------------------------------------------------
429 
431  // Get detector shifts from the geometry (if present)
432  auto const &geom = iSetup.getData(geometryTokenBeginRun_);
433 
436  verticalShiftTop_ = 0;
437  verticalShiftBot_ = 0;
438  {
439  const DetGeomDesc *det_top = geom.sensorNoThrow(detid_top);
440  if (det_top) {
441  verticalShiftTop_ = det_top->translation().y() + det_top->getDiamondDimensions().yHalfWidth;
442  }
443  const DetGeomDesc *det_bot = geom.sensorNoThrow(detid_bot);
444  if (det_bot)
445  verticalShiftBot_ = det_bot->translation().y() + det_bot->getDiamondDimensions().yHalfWidth;
446  }
447 }
448 
449 //----------------------------------------------------------------------------------------------------
450 
452  ibooker.cd();
453  ibooker.setCurrentFolder("CTPPS");
454 
455  globalPlot_ = GlobalPlots(ibooker);
456 
457  for (unsigned short arm = 0; arm < CTPPS_NUM_OF_ARMS; ++arm) {
458  for (unsigned short rp = TOTEM_TIMING_TOP_RP_ID; rp <= TOTEM_TIMING_BOT_RP_ID; ++rp) {
460  potPlots_[rpId] = PotPlots(ibooker, rpId);
461  for (unsigned short pl = 0; pl < TOTEM_TIMING_NUM_OF_PLANES; ++pl) {
462  const TotemTimingDetId plId(arm, TOTEM_TIMING_STATION_ID, rp, pl);
463  planePlots_[plId] = PlanePlots(ibooker, plId);
464  for (unsigned short ch = 0; ch < TOTEM_TIMING_NUM_OF_CHANNELS; ++ch) {
465  const TotemTimingDetId chId(arm, TOTEM_TIMING_STATION_ID, rp, pl, ch);
466  channelPlots_[chId] = ChannelPlots(ibooker, chId);
467  }
468  }
469  }
470  }
471 }
472 
473 //----------------------------------------------------------------------------------------------------
474 
476  const edm::EventSetup &) const {
477  auto d = std::make_shared<totemds::Cache>();
478  d->hitDistribution2dMap.reserve(potPlots_.size());
479  if (!perLSsaving_) {
480  for (auto &plot : potPlots_)
481  d->hitDistribution2dMap[plot.first] =
482  std::unique_ptr<TH2F>(static_cast<TH2F *>(plot.second.hitDistribution2d_lumisection->getTH2F()->Clone()));
483  }
484  return d;
485 }
486 
487 //----------------------------------------------------------------------------------------------------
488 
490  // get event setup data
491  auto const &geometry = eventSetup.getData(geometryToken_);
492 
493  // get event data
495  event.getByToken(tokenLocalTrack_, stripTracks);
496 
498  event.getByToken(tokenDigi_, timingDigis);
499 
501  event.getByToken(tokenFEDInfo_, fedInfo);
502 
504  event.getByToken(tokenRecHit_, timingRecHits);
505 
506  // check validity
507  bool valid = true;
508  valid &= timingDigis.isValid();
509  valid &= fedInfo.isValid();
510 
511  if (!valid) {
512  if (verbosity_) {
513  edm::LogProblem("TotemTimingDQMSource") << "ERROR in TotemTimingDQMSource::analyze > some of the required inputs "
514  "are not valid. Skipping this event.\n"
515  << " timingDigis.isValid = " << timingDigis.isValid() << "\n"
516  << " fedInfo.isValid = " << fedInfo.isValid();
517  }
518 
519  return;
520  }
521 
522  // Using TotemTimingDigi
523  std::set<uint8_t> boardSet;
524  std::unordered_map<unsigned int, unsigned int> channelsPerPlane;
525  std::unordered_map<unsigned int, unsigned int> channelsPerPlaneWithTime;
526 
527  auto lumiCache = luminosityBlockCache(event.getLuminosityBlock().index());
528  for (const auto &digis : *timingDigis) {
529  const TotemTimingDetId detId(digis.detId());
530  TotemTimingDetId detId_pot(digis.detId());
531  detId_pot.setPlane(0);
532  detId_pot.setChannel(0);
533  TotemTimingDetId detId_plane(digis.detId());
534  detId_plane.setChannel(0);
535 
536  for (const auto &digi : digis) {
537  // Pot Plots
538  if (potPlots_.find(detId_pot) != potPlots_.end()) {
539  potPlots_[detId_pot].activityPerBX->Fill(event.bunchCrossing());
540 
541  potPlots_[detId_pot].digiDistribution->Fill(detId.plane(), detId.channel());
542 
543  for (auto it = digi.samplesBegin(); it != digi.samplesEnd(); ++it)
544  potPlots_[detId_pot].dataSamplesRaw->Fill(*it);
545 
546  float boardId = digi.eventInfo().hardwareBoardId() + 0.5 * digi.eventInfo().hardwareSampicId();
547  potPlots_[detId_pot].digiSent->Fill(boardId, digi.hardwareChannelId());
548  if (boardSet.find(digi.eventInfo().hardwareId()) == boardSet.end()) {
549  // This guarantees that every board is counted only once
550  boardSet.insert(digi.eventInfo().hardwareId());
551  std::bitset<16> chMap(digi.eventInfo().channelMap());
552  for (int i = 0; i < 16; ++i) {
553  if (chMap.test(i)) {
554  potPlots_[detId_pot].digiAll->Fill(boardId, i);
555  }
556  }
557  }
558 
559  potPlots_[detId_pot].planesWithDigisSet.insert(detId.plane());
560  }
561 
562  // Plane Plots
563  if (planePlots_.find(detId_plane) != planePlots_.end()) {
564  planePlots_[detId_plane].digiDistribution->Fill(detId.channel());
565 
566  if (channelsPerPlane.find(detId_plane) != channelsPerPlane.end())
567  channelsPerPlane[detId_plane]++;
568  else
569  channelsPerPlane[detId_plane] = 0;
570  }
571 
572  // Channel Plots
573  if (channelPlots_.find(detId) != channelPlots_.end()) {
574  channelPlots_[detId].activityPerBX->Fill(event.bunchCrossing());
575 
576  for (auto it = digi.samplesBegin(); it != digi.samplesEnd(); ++it)
577  channelPlots_[detId].dataSamplesRaw->Fill(*it);
578  for (unsigned short i = 0; i < samplesForNoise_; ++i)
579  channelPlots_[detId].noiseSamples->Fill(SAMPIC_ADC_V * digi.sampleAt(i));
580 
581  unsigned int cellOfMax = std::max_element(digi.samplesBegin(), digi.samplesEnd()) - digi.samplesBegin();
582  channelPlots_[detId].cellOfMax->Fill((int)cellOfMax);
583 
584  if (timeOfPreviousEvent_ != 0)
585  channelPlots_[detId].hitTime->Fill(1e-3 * LHC_CLOCK_PERIOD_NS *
586  (event.time().value() - timeOfPreviousEvent_));
587  ++(lumiCache->hitsCounterMap[detId]);
588  }
589  }
590  }
591  // End digis
592 
593  for (const auto &rechits : *timingRecHits) {
594  const TotemTimingDetId detId(rechits.detId());
595  TotemTimingDetId detId_pot(rechits.detId());
596  detId_pot.setPlane(0);
597  detId_pot.setChannel(0);
598  TotemTimingDetId detId_plane(rechits.detId());
599  detId_plane.setChannel(0);
600 
601  for (const auto &rechit : rechits) {
602  if (potPlots_.find(detId_pot) != potPlots_.end()) {
603  potPlots_[detId_pot].amplitude->Fill(rechit.amplitude());
604 
605  TH2F *hitHistoTmp = potPlots_[detId_pot].hitDistribution2d->getTH2F();
606  TAxis *hitHistoTmpYAxis = hitHistoTmp->GetYaxis();
607  float yCorrected = rechit.y();
609  float x_shift = detId.plane();
610  x_shift += (rechit.x() > 2) ? 0.25 : 0;
611  int startBin = hitHistoTmpYAxis->FindBin(yCorrected - 0.5 * rechit.yWidth());
612  int numOfBins = rechit.yWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
613  for (int i = 0; i < numOfBins; ++i) {
614  potPlots_[detId_pot].hitDistribution2d->Fill(detId.plane() + 0.25 * (rechit.x() > 2),
615  hitHistoTmpYAxis->GetBinCenter(startBin + i));
616  if (!perLSsaving_)
617  potPlots_[detId_pot].hitDistribution2d_lumisection->Fill(x_shift,
618  hitHistoTmpYAxis->GetBinCenter(startBin + i));
619  }
620 
621  //All plots with Time
622  if (rechit.time() != TotemTimingRecHit::NO_T_AVAILABLE) {
623  for (int i = 0; i < numOfBins; ++i)
624  potPlots_[detId_pot].hitDistribution2dWithTime->Fill(detId.plane() + 0.25 * (rechit.x() > 2),
625  hitHistoTmpYAxis->GetBinCenter(startBin + i));
626 
627  potPlots_[detId_pot].recHitTime->Fill(rechit.time());
628  potPlots_[detId_pot].planesWithTimeSet.insert(detId.plane());
629 
630  // Plane Plots
631  if (planePlots_.find(detId_plane) != planePlots_.end()) {
632  // Visualization tricks
633  float x_shift = (rechit.x() > 2) ? 15 : 0;
634  TH1F *hitProfileHistoTmp = planePlots_[detId_plane].hitProfile->getTH1F();
635  int numOfBins = rechit.yWidth() * INV_DISPLAY_RESOLUTION_FOR_HITS_MM;
636  if (detId.rp() == TOTEM_TIMING_TOP_RP_ID) {
637  float yCorrected = rechit.y() + verticalShiftTop_ - 0.5 * rechit.yWidth() + x_shift;
638  int startBin = hitProfileHistoTmp->FindBin(yCorrected);
639  for (int i = 0; i < numOfBins; ++i)
640  hitProfileHistoTmp->Fill(hitProfileHistoTmp->GetBinCenter(startBin + i));
641  } else {
642  float yCorrected = rechit.y() + verticalShiftBot_ + 0.5 * rechit.yWidth() + (15 - x_shift);
643  int startBin = hitProfileHistoTmp->FindBin(yCorrected);
644  int totBins = hitProfileHistoTmp->GetNbinsX();
645  for (int i = 0; i < numOfBins; ++i)
646  hitProfileHistoTmp->Fill(hitProfileHistoTmp->GetBinCenter(totBins - startBin + i));
647  }
648 
649  if (channelsPerPlaneWithTime.find(detId_plane) != channelsPerPlaneWithTime.end())
650  channelsPerPlaneWithTime[detId_plane]++;
651  else
652  channelsPerPlaneWithTime[detId_plane] = 0;
653  }
654 
655  if (channelPlots_.find(detId) != channelPlots_.end()) {
656  potPlots_[detId_pot].tirggerCellTime->Fill(rechit.sampicThresholdTime());
657  channelPlots_[detId].tirggerCellTime->Fill(rechit.sampicThresholdTime());
658  channelPlots_[detId].recHitTime->Fill(rechit.time());
659  channelPlots_[detId].amplitude->Fill(rechit.amplitude());
660  }
661  }
662  }
663  }
664  }
665  // End RecHits
666 
667  // Tomography of timing using strips
668  for (const auto &rechits : *timingRecHits) {
669  const TotemTimingDetId detId(rechits.detId());
670  TotemTimingDetId detId_pot(rechits.detId());
671  detId_pot.setPlane(0);
672  detId_pot.setChannel(0);
673  TotemTimingDetId detId_plane(rechits.detId());
674  detId_plane.setChannel(0);
675 
676  float y_shift = (detId.rp() == TOTEM_TIMING_TOP_RP_ID) ? 20 : 5;
677 
678  for (const auto &rechit : rechits) {
679  if (rechit.time() != TotemTimingRecHit::NO_T_AVAILABLE && potPlots_.find(detId_pot) != potPlots_.end() &&
680  planePlots_.find(detId_plane) != planePlots_.end() && channelPlots_.find(detId) != channelPlots_.end()) {
681  if (stripTracks.isValid()) {
682  for (const auto &ds : *stripTracks) {
683  const CTPPSDetId stripId(ds.detId());
684  // mean position of U and V planes
685  TotemRPDetId plId_V(stripId);
686  plId_V.setPlane(0);
687  TotemRPDetId plId_U(stripId);
688  plId_U.setPlane(1);
689 
690  double rp_x = 0;
691  double rp_y = 0;
692  try {
693  rp_x = (geometry.sensor(plId_V)->translation().x() + geometry.sensor(plId_U)->translation().x()) / 2;
694  rp_y = (geometry.sensor(plId_V)->translation().y() + geometry.sensor(plId_U)->translation().y()) / 2;
695  } catch (const cms::Exception &) {
696  continue;
697  }
698 
699  for (const auto &striplt : ds) {
700  if (striplt.isValid() && stripId.arm() == detId.arm()) {
701  if (striplt.tx() > maximumStripAngleForTomography_ || striplt.ty() > maximumStripAngleForTomography_)
702  continue;
703  if (striplt.tx() < minimumStripAngleForTomography_ || striplt.ty() < minimumStripAngleForTomography_)
704  continue;
705  if (stripId.rp() - detId.rp() == (TOTEM_STRIP_MAX_RP_ID - TOTEM_TIMING_BOT_RP_ID)) {
706  double x = striplt.x0() - rp_x;
707  double y = striplt.y0() - rp_y;
708  if (stripId.station() == TOTEM_STATION_210) {
709  potPlots_[detId_pot].stripTomography210->Fill(x + detId.plane() * 50, y + y_shift);
710  channelPlots_[detId].stripTomography210->Fill(x, y + y_shift);
711  } else if (stripId.station() == TOTEM_STATION_220) {
712  potPlots_[detId_pot].stripTomography220->Fill(x + detId.plane() * 50, y + y_shift);
713  channelPlots_[detId].stripTomography220->Fill(x, y + y_shift);
714  }
715  }
716  }
717  }
718  }
719  }
720  }
721  }
722  }
723 
724  for (auto &plt : potPlots_) {
725  plt.second.planesWithDigis->Fill(plt.second.planesWithDigisSet.size());
726  plt.second.planesWithDigisSet.clear();
727  plt.second.planesWithTime->Fill(plt.second.planesWithTimeSet.size());
728  plt.second.planesWithTimeSet.clear();
729  }
730 
731  for (const auto &plt : channelsPerPlane) {
732  planePlots_[plt.first].hitMultiplicity->Fill(plt.second);
733  }
734  for (const auto &plt : channelsPerPlaneWithTime) {
735  planePlots_[plt.first].hitMultiplicityWithTime->Fill(plt.second);
736  }
737 
738  timeOfPreviousEvent_ = event.time().value();
739 }
740 
741 //----------------------------------------------------------------------------------------------------
742 
744  auto lumiCache = luminosityBlockCache(iLumi.index());
745  if (!perLSsaving_) {
746  for (auto &plot : potPlots_) {
747  *(plot.second.hitDistribution2d_lumisection->getTH2F()) = *(lumiCache->hitDistribution2dMap[plot.first]);
748  }
749 
751  TH2F *hitHistoGlobalTmp = globalPlot_.digiSentPercentage->getTH2F();
752  for (auto &plot : potPlots_) {
753  TH2F *hitHistoTmp = plot.second.digiSentPercentage->getTH2F();
754  TH2F *histoSent = plot.second.digiSent->getTH2F();
755  TH2F *histoAll = plot.second.digiAll->getTH2F();
756 
757  hitHistoTmp->Divide(histoSent, histoAll);
758  hitHistoTmp->Scale(100);
759  hitHistoGlobalTmp->Add(hitHistoTmp, 1);
760 
761  plot.second.baseline->Reset();
762  plot.second.noiseRMS->Reset();
763  plot.second.meanAmplitude->Reset();
764  plot.second.cellOfMax->Reset();
765  plot.second.hitRate->Reset();
766  TotemTimingDetId rpId(plot.first);
767  for (auto &chPlot : channelPlots_) {
768  TotemTimingDetId chId(chPlot.first);
769  if (chId.arm() == rpId.arm() && chId.rp() == rpId.rp()) {
770  plot.second.baseline->Fill(chId.plane(), chId.channel(), chPlot.second.noiseSamples->getTH1F()->GetMean());
771  plot.second.noiseRMS->Fill(chId.plane(), chId.channel(), chPlot.second.noiseSamples->getTH1F()->GetRMS());
772  plot.second.meanAmplitude->Fill(chId.plane(), chId.channel(), chPlot.second.amplitude->getTH1F()->GetMean());
773  plot.second.cellOfMax->Fill(chId.plane(), chId.channel(), chPlot.second.cellOfMax->getTH1F()->GetMean());
774  auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[chPlot.first];
775  plot.second.hitRate->Fill(chId.plane(), chId.channel(), (double)hitsCounterPerLumisection * HIT_RATE_FACTOR);
776  }
777  }
778  }
779 
780  for (auto &plot : channelPlots_) {
781  auto hitsCounterPerLumisection = lumiCache->hitsCounterMap[plot.first];
782  if (hitsCounterPerLumisection != 0) {
783  plot.second.hitRate->Fill((double)hitsCounterPerLumisection * HIT_RATE_FACTOR);
784  }
785  }
786  }
787 }
788 
static const double INV_DISPLAY_RESOLUTION_FOR_HITS_MM
static const double LHC_CLOCK_PERIOD_NS
Detector ID class for TOTEM Si strip detectors.
Definition: TotemRPDetId.h:30
OptoRx headers and footers.
Definition: TotemFEDInfo.h:17
static const int TOTEM_STRIP_MAX_RP_ID
static const int CTPPS_NEAR_RP_ID
static const int TOTEM_STATION_210
const Translation & translation() const
Definition: DetGeomDesc.h:80
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
void setChannel(uint32_t channel)
void analyze(const edm::Event &, const edm::EventSetup &) override
edm::EDGetTokenT< edm::DetSetVector< TotemTimingDigi > > tokenDigi_
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
std::unordered_map< unsigned int, PlanePlots > planePlots_
static const int CTPPS_NUM_OF_ARMS
void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override
uint32_t arm() const
Definition: CTPPSDetId.h:57
plots related to one Diamond detector package
std::unordered_map< unsigned int, std::unique_ptr< TH2F > > hitDistribution2dMap
edm::EDGetTokenT< edm::DetSetVector< TotemTimingRecHit > > tokenRecHit_
std::unordered_map< unsigned int, ChannelPlots > channelPlots_
std::set< unsigned int > planesWithTimeSet
void globalEndLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) override
edm::EDGetTokenT< edm::DetSetVector< TotemRPLocalTrack > > tokenLocalTrack_
static const double TOMOGRAPHY_RESOLUTION_MM
static const double SAMPIC_SAMPLING_PERIOD_NS
plots related to one Diamond channel
static const double SAMPIC_MAX_NUMBER_OF_SAMPLES
void bookHistograms(DQMStore::IBooker &, const edm::Run &, const edm::EventSetup &) override
static const double HIT_RATE_FACTOR
static const int TOTEM_STATION_220
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > geometryTokenBeginRun_
static const int CTPPS_FAR_RP_ID
A track fit through a single RP.
plots related to the whole system
static const double DQM_FRACTION_OF_EVENTS
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
virtual void Reset()
Remove all data from the ME, keept the empty histogram with all its settings.
void channelName(std::string &name, NameFlag flag=nFull) const
void planeName(std::string &name, NameFlag flag=nFull) const
static const double SEC_PER_LUMI_SECTION
static const int TOTEM_STRIP_MIN_RP_ID
void setPlane(uint32_t channel)
void rpName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:134
uint32_t channel() const
static const int TOTEM_TIMING_STATION_ID
Transition
Definition: Transition.h:12
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static const int TOTEM_TIMING_TOP_RP_ID
std::unordered_map< unsigned int, PotPlots > potPlots_
const DiamondDimensions & getDiamondDimensions() const
Definition: DetGeomDesc.h:90
unsigned long long TimeValue_t
Definition: Timestamp.h:21
std::set< unsigned int > planesWithDigisSet
d
Definition: ztail.py:151
TotemTimingDQMSource(const edm::ParameterSet &)
std::shared_ptr< totemds::Cache > globalBeginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) const override
uint32_t rp() const
Definition: CTPPSDetId.h:71
static const float COS_8_DEG
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:221
void setPlane(uint32_t det)
Definition: TotemRPDetId.h:48
static const double SAMPIC_ADC_V
static const float SIN_8_DEG
static const int TOTEM_TIMING_NUM_OF_PLANES
bool isValid() const
Definition: HandleBase.h:70
Base class for CTPPS detector IDs.
Definition: CTPPSDetId.h:32
LuminosityBlockIndex index() const
uint32_t plane() const
HLT enums.
edm::TimeValue_t timeOfPreviousEvent_
edm::EDGetTokenT< std::vector< TotemFEDInfo > > tokenFEDInfo_
static const int TOTEM_TIMING_FED_ID_45
std::unordered_map< unsigned int, unsigned long > hitsCounterMap
static const double DISPLAY_RESOLUTION_FOR_HITS_MM
static const int TOTEM_TIMING_BOT_RP_ID
static const int TOTEM_TIMING_FED_ID_56
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
edm::ESGetToken< CTPPSGeometry, VeryForwardRealGeometryRecord > geometryToken_
static const int TOTEM_TIMING_NUM_OF_CHANNELS
plots related to one Diamond plane
Definition: event.py:1
Definition: Run.h:45
Log< level::Error, true > LogProblem
Detector ID class for CTPPS Totem Timing detectors. Bits [19:31] : Assigend in CTPPSDetId Calss Bits ...