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