CMS 3D CMS Logo

TotemRPDQMSource.cc
Go to the documentation of this file.
1 /****************************************************************************
2 *
3 * This is a part of TotemDQM and TOTEM offline software.
4 * Authors:
5 * Jan Kašpar (jan.kaspar@gmail.com)
6 * Rafał Leszko (rafal.leszko@gmail.com)
7 *
8 ****************************************************************************/
9 
16 
20 
29 //#include "RecoTotemRP/RPRecoDataFormats/interface/RPMulFittedTrackCollection.h"
30 
34 
35 #include <string>
36 
37 //----------------------------------------------------------------------------------------------------
38 
40 {
41  public:
43  ~TotemRPDQMSource() override;
44 
45  protected:
46  void dqmBeginRun(edm::Run const &, edm::EventSetup const &) override;
47  void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
48  void analyze(edm::Event const& e, edm::EventSetup const& eSetup) override;
49  void beginLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& eSetup) override;
50  void endLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& eSetup) override;
51  void endRun(edm::Run const& run, edm::EventSetup const& eSetup) override;
52 
53  private:
54  unsigned int verbosity;
55 
62  //edm::EDGetTokenT< RPMulFittedTrackCollection > tokenMultiTrackColl;
63 
65  struct GlobalPlots
66  {
69 
70  void Init(DQMStore::IBooker &ibooker);
71  };
72 
74 
77  {
78  int id;
79 
80  MonitorElement *h_lrc_x_d=nullptr, *h_lrc_x_n=nullptr, *h_lrc_x_f=nullptr;
81  MonitorElement *h_lrc_y_d=nullptr, *h_lrc_y_n=nullptr, *h_lrc_y_f=nullptr;
82 
84 
85  DiagonalPlots(DQMStore::IBooker &ibooker, int _id);
86  };
87 
88  std::map<unsigned int, DiagonalPlots> diagonalPlots;
89 
91  struct ArmPlots
92  {
93  int id;
94 
95  MonitorElement *h_numRPWithTrack_top=nullptr, *h_numRPWithTrack_hor=nullptr, *h_numRPWithTrack_bot=nullptr;
96  MonitorElement *h_trackCorr=nullptr, *h_trackCorr_overlap=nullptr;
97 
99 
100  ArmPlots(DQMStore::IBooker &ibooker, int _id);
101  };
102 
103  std::map<unsigned int, ArmPlots> armPlots;
104 
107  {
109  StationPlots(DQMStore::IBooker &ibooker, int _id);
110  };
111 
112  std::map<unsigned int, StationPlots> stationPlots;
113 
115  struct PotPlots
116  {
117  MonitorElement *vfat_problem=nullptr, *vfat_missing=nullptr, *vfat_ec_bc_error=nullptr, *vfat_corruption=nullptr;
118 
119  MonitorElement *activity=nullptr, *activity_u=nullptr, *activity_v=nullptr;
120  MonitorElement *activity_per_bx=nullptr, *activity_per_bx_short=nullptr;
121  MonitorElement *hit_plane_hist=nullptr;
122  MonitorElement *patterns_u=nullptr, *patterns_v=nullptr;
123  MonitorElement *h_planes_fit_u=nullptr, *h_planes_fit_v=nullptr;
124  MonitorElement *event_category=nullptr;
125  MonitorElement *trackHitsCumulativeHist=nullptr;
126  MonitorElement *track_u_profile=nullptr, *track_v_profile=nullptr;
127 
128  PotPlots() {}
129  PotPlots(DQMStore::IBooker &ibooker, unsigned int id);
130  };
131 
132  std::map<unsigned int, PotPlots> potPlots;
133 
135  struct PlanePlots
136  {
137  MonitorElement *digi_profile_cumulative = nullptr;
138  MonitorElement *cluster_profile_cumulative = nullptr;
139  MonitorElement *hit_multiplicity = nullptr;
140  MonitorElement *cluster_size = nullptr;
141  MonitorElement *efficiency_num = nullptr, *efficiency_den = nullptr;
142 
144  PlanePlots(DQMStore::IBooker &ibooker, unsigned int id);
145  };
146 
147  std::map<unsigned int, PlanePlots> planePlots;
148 };
149 
150 //----------------------------------------------------------------------------------------------------
151 //----------------------------------------------------------------------------------------------------
152 
153 using namespace std;
154 using namespace edm;
155 
156 //----------------------------------------------------------------------------------------------------
157 
159 {
160  ibooker.setCurrentFolder("CTPPS");
161 
162  events_per_bx = ibooker.book1D("events per BX", "rp;Event.BX", 4002, -1.5, 4000. + 0.5);
163  events_per_bx_short = ibooker.book1D("events per BX (short)", "rp;Event.BX", 102, -1.5, 100. + 0.5);
164 
165  ibooker.setCurrentFolder("CTPPS/TrackingStrip");
166 
167  h_trackCorr_hor = ibooker.book2D("track correlation RP-210-hor", "rp, 210, hor", 4, -0.5, 3.5, 4, -0.5, 3.5);
168  TH2F *hist = h_trackCorr_hor->getTH2F();
169  TAxis *xa = hist->GetXaxis(), *ya = hist->GetYaxis();
170  xa->SetBinLabel(1, "45, 210, near"); ya->SetBinLabel(1, "45, 210, near");
171  xa->SetBinLabel(2, "45, 210, far"); ya->SetBinLabel(2, "45, 210, far");
172  xa->SetBinLabel(3, "56, 210, near"); ya->SetBinLabel(3, "56, 210, near");
173  xa->SetBinLabel(4, "56, 210, far"); ya->SetBinLabel(4, "56, 210, far");
174 }
175 
176 //----------------------------------------------------------------------------------------------------
177 
179 {
180  bool top45 = id & 2;
181  bool top56 = id & 1;
182  bool diag = (top45 != top56);
183 
184  char name[50];
185  sprintf(name, "%s 45%s - 56%s",
186  (diag) ? "diagonal" : "antidiagonal",
187  (top45) ? "top" : "bot",
188  (top56) ? "top" : "bot"
189  );
190 
191  ibooker.setCurrentFolder(string("CTPPS/TrackingStrip/") + name);
192 
193  // TODO: define ranges! If defined automatically, can lead to problems when histograms are merged from several instances of the module.
194  h_lrc_x_d = ibooker.book2D("dx left vs right", string(name) + " : dx left vs. right, histogram;#Delta x_{45};#Delta x_{56}", 50, 0., 0., 50, 0., 0.);
195  h_lrc_x_n = ibooker.book2D("xn left vs right", string(name) + " : xn left vs. right, histogram;x^{N}_{45};x^{N}_{56}", 50, 0., 0., 50, 0., 0.);
196  h_lrc_x_f = ibooker.book2D("xf left vs right", string(name) + " : xf left vs. right, histogram;x^{F}_{45};x^{F}_{56}", 50, 0., 0., 50, 0., 0.);
197 
198  h_lrc_y_d = ibooker.book2D("dy left vs right", string(name) + " : dy left vs. right, histogram;#Delta y_{45};#Delta y_{56}", 50, 0., 0., 50, 0., 0.);
199  h_lrc_y_n = ibooker.book2D("yn left vs right", string(name) + " : yn left vs. right, histogram;y^{N}_{45};y^{N}_{56}", 50, 0., 0., 50, 0., 0.);
200  h_lrc_y_f = ibooker.book2D("yf left vs right", string(name) + " : yf left vs. right, histogram;y^{F}_{45};y^{F}_{56}", 50, 0., 0., 50, 0., 0.);
201 }
202 
203 //----------------------------------------------------------------------------------------------------
204 
206 {
207  string path;
209  ibooker.setCurrentFolder(path);
210 
211  string title;
213 
214  h_numRPWithTrack_top = ibooker.book1D("number of top RPs with tracks", title+";number of top RPs with tracks", 5, -0.5, 4.5);
215  h_numRPWithTrack_hor = ibooker.book1D("number of hor RPs with tracks", title+";number of hor RPs with tracks", 5, -0.5, 4.5);
216  h_numRPWithTrack_bot = ibooker.book1D("number of bot RPs with tracks", title+";number of bot RPs with tracks", 5, -0.5, 4.5);
217 
218  h_trackCorr = ibooker.book2D("track RP correlation", title, 13, -0.5, 12.5, 13, -0.5, 12.5);
219  TH2F *h_trackCorr_h = h_trackCorr->getTH2F();
220  TAxis *xa = h_trackCorr_h->GetXaxis(), *ya = h_trackCorr_h->GetYaxis();
221  xa->SetBinLabel(1, "210, near, top"); ya->SetBinLabel(1, "210, near, top");
222  xa->SetBinLabel(2, "bot"); ya->SetBinLabel(2, "bot");
223  xa->SetBinLabel(3, "hor"); ya->SetBinLabel(3, "hor");
224  xa->SetBinLabel(4, "far, hor"); ya->SetBinLabel(4, "far, hor");
225  xa->SetBinLabel(5, "top"); ya->SetBinLabel(5, "top");
226  xa->SetBinLabel(6, "bot"); ya->SetBinLabel(6, "bot");
227  xa->SetBinLabel(8, "220, near, top"); ya->SetBinLabel(8, "220, near, top");
228  xa->SetBinLabel(9, "bot"); ya->SetBinLabel(9, "bot");
229  xa->SetBinLabel(10, "hor"); ya->SetBinLabel(10, "hor");
230  xa->SetBinLabel(11, "far, hor"); ya->SetBinLabel(11, "far, hor");
231  xa->SetBinLabel(12, "top"); ya->SetBinLabel(12, "top");
232  xa->SetBinLabel(13, "bot"); ya->SetBinLabel(13, "bot");
233 
234  h_trackCorr_overlap = ibooker.book2D("track RP correlation hor-vert overlaps", title, 13, -0.5, 12.5, 13, -0.5, 12.5);
235  h_trackCorr_h = h_trackCorr_overlap->getTH2F();
236  xa = h_trackCorr_h->GetXaxis(); ya = h_trackCorr_h->GetYaxis();
237  xa->SetBinLabel(1, "210, near, top"); ya->SetBinLabel(1, "210, near, top");
238  xa->SetBinLabel(2, "bot"); ya->SetBinLabel(2, "bot");
239  xa->SetBinLabel(3, "hor"); ya->SetBinLabel(3, "hor");
240  xa->SetBinLabel(4, "far, hor"); ya->SetBinLabel(4, "far, hor");
241  xa->SetBinLabel(5, "top"); ya->SetBinLabel(5, "top");
242  xa->SetBinLabel(6, "bot"); ya->SetBinLabel(6, "bot");
243  xa->SetBinLabel(8, "220, near, top"); ya->SetBinLabel(8, "220, near, top");
244  xa->SetBinLabel(9, "bot"); ya->SetBinLabel(9, "bot");
245  xa->SetBinLabel(10, "hor"); ya->SetBinLabel(10, "hor");
246  xa->SetBinLabel(11, "far, hor"); ya->SetBinLabel(11, "far, hor");
247  xa->SetBinLabel(12, "top"); ya->SetBinLabel(12, "top");
248  xa->SetBinLabel(13, "bot"); ya->SetBinLabel(13, "bot");
249 }
250 
251 //----------------------------------------------------------------------------------------------------
252 
254 {
255  string path;
257  ibooker.setCurrentFolder(path);
258 }
259 
260 //----------------------------------------------------------------------------------------------------
261 //----------------------------------------------------------------------------------------------------
262 
264 {
265  string path;
267  ibooker.setCurrentFolder(path);
268 
269  string title;
271 
272  vfat_problem = ibooker.book2D("vfats with any problem", title+";plane;vfat index", 10, -0.5, 9.5, 4, -0.5, 3.5);
273  vfat_missing = ibooker.book2D("vfats missing", title+";plane;vfat index", 10, -0.5, 9.5, 4, -0.5, 3.5);
274  vfat_ec_bc_error = ibooker.book2D("vfats with EC or BC error", title+";plane;vfat index", 10, -0.5, 9.5, 4, -0.5, 3.5);
275  vfat_corruption = ibooker.book2D("vfats with data corruption", title+";plane;vfat index", 10, -0.5, 9.5, 4, -0.5, 3.5);
276 
277  activity = ibooker.book1D("active planes", title+";number of active planes", 11, -0.5, 10.5);
278  activity_u = ibooker.book1D("active planes U", title+";number of active U planes", 11, -0.5, 10.5);
279  activity_v = ibooker.book1D("active planes V", title+";number of active V planes", 11, -0.5, 10.5);
280 
281  activity_per_bx = ibooker.book1D("activity per BX", title+";Event.BX", 4002, -1.5, 4000. + 0.5);
282  activity_per_bx_short = ibooker.book1D("activity per BX (short)", title+";Event.BX", 102, -1.5, 100. + 0.5);
283 
284  hit_plane_hist = ibooker.book2D("activity in planes (2D)", title+";plane number;strip number", 10, -0.5, 9.5, 32, -0.5, 511.5);
285 
286  patterns_u = ibooker.book1D("recognized patterns U", title+";number of recognized U patterns", 11, -0.5, 10.5);
287  patterns_v = ibooker.book1D("recognized patterns V", title+";number of recognized V patterns", 11, -0.5, 10.5);
288 
289  h_planes_fit_u = ibooker.book1D("planes contributing to fit U", title+";number of planes contributing to U fit", 6, -0.5, 5.5);
290  h_planes_fit_v = ibooker.book1D("planes contributing to fit V", title+";number of planes contributing to V fit", 6, -0.5, 5.5);
291 
292  event_category = ibooker.book1D("event category", title+";event category", 5, -0.5, 4.5);
293  TH1F *event_category_h = event_category->getTH1F();
294  event_category_h->GetXaxis()->SetBinLabel(1, "empty");
295  event_category_h->GetXaxis()->SetBinLabel(2, "insufficient");
296  event_category_h->GetXaxis()->SetBinLabel(3, "single-track");
297  event_category_h->GetXaxis()->SetBinLabel(4, "multi-track");
298  event_category_h->GetXaxis()->SetBinLabel(5, "shower");
299 
300  trackHitsCumulativeHist = ibooker.book2D("track XY profile", title+";x (mm);y (mm)", 100, -18., +18., 100, -18., +18.);
301 
302  track_u_profile = ibooker.book1D("track profile U", title+"; U (mm)", 512, -256*66E-3, +256*66E-3);
303  track_v_profile = ibooker.book1D("track profile V", title+"; V (mm)", 512, -256*66E-3, +256*66E-3);
304 }
305 
306 //----------------------------------------------------------------------------------------------------
307 //----------------------------------------------------------------------------------------------------
308 
310 {
311  string path;
313  ibooker.setCurrentFolder(path);
314 
315  string title;
317 
318  digi_profile_cumulative = ibooker.book1D("digi profile", title+";strip number", 512, -0.5, 511.5);
319  cluster_profile_cumulative = ibooker.book1D("cluster profile", title+";cluster center", 1024, -0.25, 511.75);
320  hit_multiplicity = ibooker.book1D("hit multiplicity", title+";hits/detector/event", 6, -0.5, 5.5);
321  cluster_size = ibooker.book1D("cluster size", title+";hits per cluster", 5, 0.5, 5.5);
322 
323  efficiency_num = ibooker.book1D("efficiency num", title+";track position (mm)", 30, -15., 0.);
324  efficiency_den = ibooker.book1D("efficiency den", title+";track position (mm)", 30, -15., 0.);
325 }
326 
327 //----------------------------------------------------------------------------------------------------
328 //----------------------------------------------------------------------------------------------------
329 
331  verbosity(ps.getUntrackedParameter<unsigned int>("verbosity", 0))
332 {
333  tokenStatus = consumes<DetSetVector<TotemVFATStatus>>(ps.getParameter<edm::InputTag>("tagStatus"));
334 
335  tokenDigi = consumes< DetSetVector<TotemRPDigi> >(ps.getParameter<edm::InputTag>("tagDigi"));
336  tokenCluster = consumes< edm::DetSetVector<TotemRPCluster> >(ps.getParameter<edm::InputTag>("tagCluster"));
337  tokenRecHit = consumes< edm::DetSetVector<TotemRPRecHit> >(ps.getParameter<edm::InputTag>("tagRecHit"));
338  tokenUVPattern = consumes< DetSetVector<TotemRPUVPattern> >(ps.getParameter<edm::InputTag>("tagUVPattern"));
339  tokenLocalTrack = consumes< DetSetVector<TotemRPLocalTrack> >(ps.getParameter<edm::InputTag>("tagLocalTrack"));
340  //tokenMultiTrackColl = consumes< RPMulFittedTrackCollection >(ps.getParameter<edm::InputTag>("tagMultiTrackColl"));
341 }
342 
343 //----------------------------------------------------------------------------------------------------
344 
346 {
347 }
348 
349 //----------------------------------------------------------------------------------------------------
350 
352 {
353 }
354 
355 //----------------------------------------------------------------------------------------------------
356 
358 {
359  ibooker.cd();
360  ibooker.setCurrentFolder("CTPPS");
361 
362  // global plots
363  globalPlots.Init(ibooker);
364 
365  // temporarily disabled
366  /*
367  // initialize diagonals
368  diagonalPlots[1] = DiagonalPlots(ibooker, 1); // 45 bot - 56 top
369  diagonalPlots[2] = DiagonalPlots(ibooker, 2); // 45 top - 45 bot
370 
371  // initialize anti-diagonals
372  diagonalPlots[0] = DiagonalPlots(ibooker, 0); // 45 bot - 56 bot
373  diagonalPlots[3] = DiagonalPlots(ibooker, 3); // 45 top - 56 top
374  */
375 
376  // loop over arms
377  for (unsigned int arm = 0; arm < 2; arm++)
378  {
379  TotemRPDetId armId(arm, 0);
380  armPlots[armId] = ArmPlots(ibooker, armId);
381 
382  // loop over stations
383  for (unsigned int st = 0; st < 3; st += 2)
384  {
385  TotemRPDetId stId(arm, st);
386  stationPlots[stId] = StationPlots(ibooker, stId);
387 
388  // loop over RPs
389  for (unsigned int rp = 0; rp < 6; ++rp)
390  {
391  if (st == 2)
392  {
393  // unit 220-nr is not equipped
394  if (rp <= 2)
395  continue;
396 
397  // RP 220-fr-hr contains pixels
398  if (rp == 3)
399  continue;
400  }
401 
402  TotemRPDetId rpId(arm, st, rp);
403  potPlots[rpId] = PotPlots(ibooker, rpId);
404 
405  // loop over planes
406  for (unsigned int pl = 0; pl < 10; ++pl)
407  {
408  TotemRPDetId plId(arm, st, rp, pl);
409  planePlots[plId] = PlanePlots(ibooker, plId);
410  }
411  }
412  }
413  }
414 }
415 
416 //----------------------------------------------------------------------------------------------------
417 
419  edm::EventSetup const& context)
420 {
421 }
422 
423 //----------------------------------------------------------------------------------------------------
424 
426 {
427  // get event setup data
429  eventSetup.get<VeryForwardRealGeometryRecord>().get(geometry);
430 
431  // get event data
433  event.getByToken(tokenStatus, status);
434 
436  event.getByToken(tokenDigi, digi);
437 
439  event.getByToken(tokenCluster, digCluster);
440 
442  event.getByToken(tokenRecHit, hits);
443 
445  event.getByToken(tokenUVPattern, patterns);
446 
448  event.getByToken(tokenLocalTrack, tracks);
449 
450  //Handle< RPMulFittedTrackCollection > multiTracks;
451  //event.getByToken(tokenMultiTrackColl, multiTracks);
452 
453  // check validity
454  bool valid = true;
455  valid &= status.isValid();
456  valid &= digi.isValid();
457  valid &= digCluster.isValid();
458  valid &= hits.isValid();
459  valid &= patterns.isValid();
460  valid &= tracks.isValid();
461  //valid &= multiTracks.isValid();
462 
463  if (!valid)
464  {
465  if (verbosity)
466  {
467  LogProblem("TotemRPDQMSource") <<
468  "ERROR in TotemDQMModuleRP::analyze > some of the required inputs are not valid. Skipping this event.\n"
469  << " status.isValid = " << status.isValid() << "\n"
470  << " digi.isValid = " << digi.isValid() << "\n"
471  << " digCluster.isValid = " << digCluster.isValid() << "\n"
472  << " hits.isValid = " << hits.isValid() << "\n"
473  << " patterns.isValid = " << patterns.isValid() << "\n"
474  << " tracks.isValid = " << tracks.isValid();
475  //<< " multiTracks.isValid = %i\n", multiTracks.isValid()
476  }
477 
478  return;
479  }
480 
481  //------------------------------
482  // Global Plots
483 
486 
487  for (auto &ds1 : *tracks)
488  {
489  for (auto &tr1 : ds1)
490  {
491  if (! tr1.isValid())
492  continue;
493 
494  CTPPSDetId rpId1(ds1.detId());
495  unsigned int arm1 = rpId1.arm();
496  unsigned int stNum1 = rpId1.station();
497  unsigned int rpNum1 = rpId1.rp();
498  if (stNum1 != 0 || (rpNum1 != 2 && rpNum1 != 3))
499  continue;
500  unsigned int idx1 = arm1*2 + rpNum1-2;
501 
502  for (auto &ds2 : *tracks)
503  {
504  for (auto &tr2 : ds2)
505  {
506  if (! tr2.isValid())
507  continue;
508 
509  CTPPSDetId rpId2(ds2.detId());
510  unsigned int arm2 = rpId2.arm();
511  unsigned int stNum2 = rpId2.station();
512  unsigned int rpNum2 = rpId2.rp();
513  if (stNum2 != 0 || (rpNum2 != 2 && rpNum2 != 3))
514  continue;
515  unsigned int idx2 = arm2*2 + rpNum2-2;
516 
517  globalPlots.h_trackCorr_hor->Fill(idx1, idx2);
518  }
519  }
520  }
521  }
522 
523  //------------------------------
524  // Status Plots
525 
526  for (auto &ds : *status)
527  {
528  TotemRPDetId detId(ds.detId());
529  unsigned int plNum = detId.plane();
530  CTPPSDetId rpId = detId.getRPId();
531 
532  auto &plots = potPlots[rpId];
533 
534  for (auto &s : ds)
535  {
536  if (s.isMissing())
537  {
538  plots.vfat_problem->Fill(plNum, s.getChipPosition());
539  plots.vfat_missing->Fill(plNum, s.getChipPosition());
540  }
541 
542  if (s.isECProgressError() || s.isBCProgressError())
543  {
544  plots.vfat_problem->Fill(plNum, s.getChipPosition());
545  plots.vfat_ec_bc_error->Fill(plNum, s.getChipPosition());
546  }
547 
548  if (s.isIDMismatch() || s.isFootprintError() || s.isCRCError())
549  {
550  plots.vfat_problem->Fill(plNum, s.getChipPosition());
551  plots.vfat_corruption->Fill(plNum, s.getChipPosition());
552  }
553  }
554  }
555 
556  //------------------------------
557  // Plane Plots
558 
559  // digi profile cumulative
560  for (DetSetVector<TotemRPDigi>::const_iterator it = digi->begin(); it != digi->end(); ++it)
561  {
562  TotemRPDetId detId(it->detId());
563  for (DetSet<TotemRPDigi>::const_iterator dit = it->begin(); dit != it->end(); ++dit)
564  planePlots[detId].digi_profile_cumulative->Fill(dit->getStripNumber());
565  }
566 
567  // cluster profile cumulative
568  for (DetSetVector<TotemRPCluster>::const_iterator it = digCluster->begin(); it != digCluster->end(); it++)
569  {
570  TotemRPDetId detId(it->detId());
571  for (DetSet<TotemRPCluster>::const_iterator dit = it->begin(); dit != it->end(); ++dit)
572  planePlots[detId].cluster_profile_cumulative->Fill(dit->getCenterStripPosition());
573  }
574 
575  // hit multiplicity
576  for (DetSetVector<TotemRPCluster>::const_iterator it = digCluster->begin(); it != digCluster->end(); it++)
577  {
578  TotemRPDetId detId(it->detId());
579  planePlots[detId].hit_multiplicity->Fill(it->size());
580  }
581 
582  // cluster size
583  for (DetSetVector<TotemRPCluster>::const_iterator it = digCluster->begin(); it != digCluster->end(); it++)
584  {
585  TotemRPDetId detId(it->detId());
586  for (DetSet<TotemRPCluster>::const_iterator dit = it->begin(); dit != it->end(); ++dit)
587  planePlots[detId].cluster_size->Fill(dit->getNumberOfStrips());
588  }
589 
590  // plane efficiency plots
591  for (auto &ds : *tracks)
592  {
593  CTPPSDetId rpId(ds.detId());
594 
595  for (auto &ft : ds)
596  {
597  if (!ft.isValid())
598  continue;
599 
600  double rp_z = geometry->getRPTranslation(rpId).z();
601 
602  for (unsigned int plNum = 0; plNum < 10; ++plNum)
603  {
604  TotemRPDetId plId = rpId;
605  plId.setPlane(plNum);
606 
607  double ft_z = ft.getZ0();
608  double ft_x = ft.getX0() + ft.getTx() * (ft_z - rp_z);
609  double ft_y = ft.getY0() + ft.getTy() * (ft_z - rp_z);
610 
611  double ft_v = geometry->globalToLocal(plId, CLHEP::Hep3Vector(ft_x, ft_y, ft_z)).y();
612 
613  bool hasMatchingHit = false;
614  const auto &hit_ds_it = hits->find(plId);
615  if (hit_ds_it != hits->end())
616  {
617  for (const auto &h : *hit_ds_it)
618  {
619  bool match = (fabs(ft_v - h.getPosition()) < 2.*0.066);
620  if (match)
621  {
622  hasMatchingHit = true;
623  break;
624  }
625  }
626  }
627 
628  auto &pp = planePlots[plId];
629 
630  pp.efficiency_den->Fill(ft_v);
631  if (hasMatchingHit)
632  pp.efficiency_num->Fill(ft_v);
633  }
634  }
635  }
636 
637 
638  //------------------------------
639  // Roman Pots Plots
640 
641  // determine active planes (from RecHits and VFATStatus)
642  map<unsigned int, set<unsigned int> > planes;
643  map<unsigned int, set<unsigned int> > planes_u;
644  map<unsigned int, set<unsigned int> > planes_v;
645  for (const auto &ds : *hits)
646  {
647  if (ds.empty())
648  continue;
649 
650  TotemRPDetId detId(ds.detId());
651  unsigned int planeNum = detId.plane();
652  CTPPSDetId rpId = detId.getRPId();
653 
654  planes[rpId].insert(planeNum);
655  if (detId.isStripsCoordinateUDirection())
656  planes_u[rpId].insert(planeNum);
657  else
658  planes_v[rpId].insert(planeNum);
659  }
660 
661  for (const auto &ds : *status)
662  {
663  bool activity = false;
664  for (const auto &s : ds)
665  {
666  if (s.isNumberOfClustersSpecified() && s.getNumberOfClusters() > 0)
667  {
668  activity = true;
669  break;
670  }
671  }
672 
673  if (!activity)
674  continue;
675 
676  TotemRPDetId detId(ds.detId());
677  unsigned int planeNum = detId.plane();
678  CTPPSDetId rpId = detId.getRPId();
679 
680  planes[rpId].insert(planeNum);
681  if (detId.isStripsCoordinateUDirection())
682  planes_u[rpId].insert(planeNum);
683  else
684  planes_v[rpId].insert(planeNum);
685  }
686 
687  // plane activity histogram
688  for (std::map<unsigned int, PotPlots>::iterator it = potPlots.begin(); it != potPlots.end(); it++)
689  {
690  it->second.activity->Fill(planes[it->first].size());
691  it->second.activity_u->Fill(planes_u[it->first].size());
692  it->second.activity_v->Fill(planes_v[it->first].size());
693 
694  if (planes[it->first].size() >= 6)
695  {
696  it->second.activity_per_bx->Fill(event.bunchCrossing());
697  it->second.activity_per_bx_short->Fill(event.bunchCrossing());
698  }
699  }
700 
701  for (DetSetVector<TotemRPCluster>::const_iterator it = digCluster->begin(); it != digCluster->end(); it++)
702  {
703  TotemRPDetId detId(it->detId());
704  unsigned int planeNum = detId.plane();
705  CTPPSDetId rpId = detId.getRPId();
706 
707  PotPlots &pp = potPlots[rpId];
708  for (DetSet<TotemRPCluster>::const_iterator dit = it->begin(); dit != it->end(); ++dit)
709  pp.hit_plane_hist->Fill(planeNum, dit->getCenterStripPosition());
710  }
711 
712  // recognized pattern histograms
713  for (auto &ds : *patterns)
714  {
715  CTPPSDetId rpId(ds.detId());
716 
717  PotPlots &pp = potPlots[rpId];
718 
719  // count U and V patterns
720  unsigned int u = 0, v = 0;
721  for (auto &p : ds)
722  {
723  if (! p.getFittable())
724  continue;
725 
726  if (p.getProjection() == TotemRPUVPattern::projU)
727  u++;
728 
729  if (p.getProjection() == TotemRPUVPattern::projV)
730  v++;
731  }
732 
733  pp.patterns_u->Fill(u);
734  pp.patterns_v->Fill(v);
735  }
736 
737  // event-category histogram
738  for (auto &it : potPlots)
739  {
740  TotemRPDetId rpId(it.first);
741  auto &pp = it.second;
742 
743  // process hit data for this plot
744  unsigned int pl_u = planes_u[rpId].size();
745  unsigned int pl_v = planes_v[rpId].size();
746 
747  // process pattern data for this pot
748  const auto &rp_pat_it = patterns->find(rpId);
749 
750  unsigned int pat_u = 0, pat_v = 0;
751  if (rp_pat_it != patterns->end())
752  {
753  for (auto &p : *rp_pat_it)
754  {
755  if (! p.getFittable())
756  continue;
757 
758  if (p.getProjection() == TotemRPUVPattern::projU)
759  pat_u++;
760 
761  if (p.getProjection() == TotemRPUVPattern::projV)
762  pat_v++;
763  }
764  }
765 
766  // determine category
767  signed int category = -1;
768 
769  if (pl_u == 0 && pl_v == 0) category = 0; // empty
770 
771  if (category == -1 && pat_u + pat_v <= 1)
772  {
773  if (pl_u + pl_v < 6)
774  category = 1; // insuff
775  else
776  category = 4; // shower
777  }
778 
779  if (pat_u == 1 && pat_v == 1) category = 2; // 1-track
780 
781  if (category == -1) category = 3; // multi-track
782 
783  pp.event_category->Fill(category);
784  }
785 
786  // RP track-fit plots
787  for (auto &ds : *tracks)
788  {
789  CTPPSDetId rpId(ds.detId());
790 
791  PotPlots &pp = potPlots[rpId];
792 
793  for (auto &ft : ds)
794  {
795  if (!ft.isValid())
796  continue;
797 
798  // number of planes contributing to (valid) fits
799  unsigned int n_pl_in_fit_u = 0, n_pl_in_fit_v = 0;
800  for (auto &hds : ft.getHits())
801  {
802  TotemRPDetId plId(hds.detId());
803  bool uProj = plId.isStripsCoordinateUDirection();
804 
805  for (auto &h : hds)
806  {
807  h.getPosition(); // just to keep compiler silent
808  if (uProj)
809  n_pl_in_fit_u++;
810  else
811  n_pl_in_fit_v++;
812  }
813  }
814 
815  pp.h_planes_fit_u->Fill(n_pl_in_fit_u);
816  pp.h_planes_fit_v->Fill(n_pl_in_fit_v);
817 
818  // mean position of U and V planes
819  TotemRPDetId plId_V(rpId); plId_V.setPlane(0);
820  TotemRPDetId plId_U(rpId); plId_U.setPlane(1);
821 
822  double rp_x = ( geometry->getSensor(plId_V)->translation().x() +
823  geometry->getSensor(plId_U)->translation().x() ) / 2.;
824  double rp_y = ( geometry->getSensor(plId_V)->translation().y() +
825  geometry->getSensor(plId_U)->translation().y() ) / 2.;
826 
827  // mean read-out direction of U and V planes
828  CLHEP::Hep3Vector rod_U = geometry->localToGlobalDirection(plId_U, CLHEP::Hep3Vector(0., 1., 0.));
829  CLHEP::Hep3Vector rod_V = geometry->localToGlobalDirection(plId_V, CLHEP::Hep3Vector(0., 1., 0.));
830 
831  double x = ft.getX0() - rp_x;
832  double y = ft.getY0() - rp_y;
833 
834  pp.trackHitsCumulativeHist->Fill(x, y);
835 
836  double U = x * rod_U.x() + y * rod_U.y();
837  double V = x * rod_V.x() + y * rod_V.y();
838 
839  pp.track_u_profile->Fill(U);
840  pp.track_v_profile->Fill(V);
841  }
842  }
843 
844  //------------------------------
845  // Station Plots
846 
847 
848  //------------------------------
849  // Arm Plots
850  {
851  map<unsigned int, unsigned int> mTop, mHor, mBot;
852 
853  for (auto p : armPlots)
854  {
855  mTop[p.first] = 0;
856  mHor[p.first] = 0;
857  mBot[p.first] = 0;
858  }
859 
860  for (auto &ds : *tracks)
861  {
862  CTPPSDetId rpId(ds.detId());
863  unsigned int rpNum = rpId.rp();
864  CTPPSDetId armId = rpId.getArmId();
865 
866  for (auto &tr : ds)
867  {
868  if (! tr.isValid())
869  continue;
870 
871  if (rpNum == 0 || rpNum == 4)
872  mTop[armId]++;
873  if (rpNum == 2 || rpNum == 3)
874  mHor[armId]++;
875  if (rpNum == 1 || rpNum == 5)
876  mBot[armId]++;
877  }
878  }
879 
880  for (auto &p : armPlots)
881  {
882  p.second.h_numRPWithTrack_top->Fill(mTop[p.first]);
883  p.second.h_numRPWithTrack_hor->Fill(mHor[p.first]);
884  p.second.h_numRPWithTrack_bot->Fill(mBot[p.first]);
885  }
886 
887  // track RP correlation
888  for (auto &ds1 : *tracks)
889  {
890  for (auto &tr1 : ds1)
891  {
892  if (! tr1.isValid())
893  continue;
894 
895  CTPPSDetId rpId1(ds1.detId());
896  unsigned int arm1 = rpId1.arm();
897  unsigned int stNum1 = rpId1.station();
898  unsigned int rpNum1 = rpId1.rp();
899  unsigned int idx1 = stNum1/2 * 7 + rpNum1;
900  bool hor1 = (rpNum1 == 2 || rpNum1 == 3);
901 
902  CTPPSDetId armId = rpId1.getArmId();
903  ArmPlots &ap = armPlots[armId];
904 
905  for (auto &ds2 : *tracks)
906  {
907  for (auto &tr2 : ds2)
908  {
909  if (! tr2.isValid())
910  continue;
911 
912  CTPPSDetId rpId2(ds2.detId());
913  unsigned int arm2 = rpId2.arm();
914  unsigned int stNum2 = rpId2.station();
915  unsigned int rpNum2 = rpId2.rp();
916  unsigned int idx2 = stNum2/2 * 7 + rpNum2;
917  bool hor2 = (rpNum2 == 2 || rpNum2 == 3);
918 
919  if (arm1 != arm2)
920  continue;
921 
922  ap.h_trackCorr->Fill(idx1, idx2);
923 
924  if (hor1 != hor2)
925  ap.h_trackCorr_overlap->Fill(idx1, idx2);
926  }
927  }
928  }
929  }
930  }
931 
932  //------------------------------
933  // RP-system plots
934  // TODO: this code needs
935  // * generalization for more than two RPs per arm
936  // * updating for tracks as DetSetVector
937  /*
938  for (auto &dp : diagonalPlots)
939  {
940  unsigned int id = dp.first;
941  bool top45 = id & 2;
942  bool top56 = id & 1;
943 
944  unsigned int id_45_n = (top45) ? 20 : 21;
945  unsigned int id_45_f = (top45) ? 24 : 25;
946  unsigned int id_56_n = (top56) ? 120 : 121;
947  unsigned int id_56_f = (top56) ? 124 : 125;
948 
949  bool h_45_n = (tracks->find(id_45_n) != tracks->end() && tracks->find(id_45_n)->second.IsValid());
950  bool h_45_f = (tracks->find(id_45_f) != tracks->end() && tracks->find(id_45_f)->second.IsValid());
951  bool h_56_n = (tracks->find(id_56_n) != tracks->end() && tracks->find(id_56_n)->second.IsValid());
952  bool h_56_f = (tracks->find(id_56_f) != tracks->end() && tracks->find(id_56_f)->second.IsValid());
953 
954  if (! (h_45_n && h_45_f && h_56_n && h_56_f) )
955  continue;
956 
957  double x_45_n = tracks->find(id_45_n)->second.X0(), y_45_n = tracks->find(id_45_n)->second.Y0();
958  double x_45_f = tracks->find(id_45_f)->second.X0(), y_45_f = tracks->find(id_45_f)->second.Y0();
959  double x_56_n = tracks->find(id_56_n)->second.X0(), y_56_n = tracks->find(id_56_n)->second.Y0();
960  double x_56_f = tracks->find(id_56_f)->second.X0(), y_56_f = tracks->find(id_56_f)->second.Y0();
961 
962  double dx_45 = x_45_f - x_45_n;
963  double dy_45 = y_45_f - y_45_n;
964  double dx_56 = x_56_f - x_56_n;
965  double dy_56 = y_56_f - y_56_n;
966 
967  DiagonalPlots &pl = dp.second;
968 
969  pl.h_lrc_x_d->Fill(dx_45, dx_56);
970  pl.h_lrc_y_d->Fill(dy_45, dy_56);
971 
972  pl.h_lrc_x_n->Fill(x_45_n, x_56_n);
973  pl.h_lrc_y_n->Fill(y_45_n, y_56_n);
974 
975  pl.h_lrc_x_f->Fill(x_45_f, x_56_f);
976  pl.h_lrc_y_f->Fill(y_45_f, y_56_f);
977  }
978  */
979 }
980 
981 //----------------------------------------------------------------------------------------------------
982 
984 {
985 }
986 
987 //----------------------------------------------------------------------------------------------------
988 
990 {
991 }
992 
993 //----------------------------------------------------------------------------------------------------
994 
Detector ID class for TOTEM Si strip detectors.
Definition: TotemRPDetId.h:30
T getParameter(std::string const &) const
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
void dqmBeginRun(edm::Run const &, edm::EventSetup const &) override
GlobalPlots globalPlots
void Init(DQMStore::IBooker &ibooker)
MonitorElement * h_trackCorr_overlap
void cd(void)
Definition: DQMStore.cc:269
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::map< unsigned int, ArmPlots > armPlots
int bunchCrossing() const
Definition: EventBase.h:66
plots related to one arm
uint32_t plane() const
Definition: TotemRPDetId.h:49
void endRun(edm::Run const &run, edm::EventSetup const &eSetup) override
bool isStripsCoordinateUDirection() const
Definition: TotemRPDetId.h:80
edm::EDGetTokenT< edm::DetSetVector< TotemRPDigi > > tokenDigi
Event setup record containing the real (actual) geometry information.
MonitorElement * h_numRPWithTrack_top
const PhiMemoryImage patterns[9]
void Fill(long long x)
plots related to one RP plane
std::map< unsigned int, PlanePlots > planePlots
MonitorElement * h_numRPWithTrack_hor
edm::EDGetTokenT< edm::DetSetVector< TotemRPRecHit > > tokenRecHit
const DetGeomDesc * getSensor(unsigned int id) const
returns geometry of a detector performs necessary checks, returns NULL if fails
unsigned int verbosity
plots related to one (anti)diagonal
void beginLuminosityBlock(edm::LuminosityBlock const &lumi, edm::EventSetup const &eSetup) override
~TotemRPDQMSource() override
edm::EDGetTokenT< edm::DetSetVector< TotemRPUVPattern > > tokenUVPattern
plots related to one RP
MonitorElement * h_numRPWithTrack_bot
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
DDTranslation translation() const
Definition: DetGeomDesc.h:84
void rpName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:139
CTPPSDetId getRPId() const
Definition: CTPPSDetId.h:97
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:49
uint32_t arm() const
Definition: CTPPSDetId.h:52
bool isValid() const
Definition: HandleBase.h:74
MonitorElement * events_per_bx_short
void armName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:115
plots related to one station
iterator begin()
Definition: DetSet.h:59
CLHEP::Hep3Vector getRPTranslation(unsigned int id) const
edm::EDGetTokenT< edm::DetSetVector< TotemRPCluster > > tokenCluster
std::map< unsigned int, StationPlots > stationPlots
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
CTPPSDetId getArmId() const
Definition: CTPPSDetId.h:87
MonitorElement * book2D(Args &&...args)
Definition: DQMStore.h:133
CLHEP::Hep3Vector localToGlobalDirection(unsigned int id, const CLHEP::Hep3Vector &) const
const T & get() const
Definition: EventSetup.h:55
void setPlane(uint32_t det)
Definition: TotemRPDetId.h:54
void endLuminosityBlock(edm::LuminosityBlock const &lumi, edm::EventSetup const &eSetup) override
TH1F * getTH1F(void) const
Base class for CTPPS detector IDs.
Definition: CTPPSDetId.h:32
TotemRPDQMSource(const edm::ParameterSet &ps)
ESHandle< TrackerGeometry > geometry
HLT enums.
void stationName(std::string &name, NameFlag flag=nFull) const
Definition: CTPPSDetId.h:127
std::map< unsigned int, PotPlots > potPlots
void planeName(std::string &name, NameFlag flag=nFull) const
Definition: TotemRPDetId.h:105
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
plots related to the whole system
void analyze(edm::Event const &e, edm::EventSetup const &eSetup) override
std::map< unsigned int, DiagonalPlots > diagonalPlots
TH2F * getTH2F(void) const
CLHEP::Hep3Vector globalToLocal(const DetGeomDesc *, const CLHEP::Hep3Vector &) const
edm::EDGetTokenT< edm::DetSetVector< TotemRPLocalTrack > > tokenLocalTrack
edm::EDGetTokenT< edm::DetSetVector< TotemVFATStatus > > tokenStatus
Definition: event.py:1
Definition: Run.h:42
uint32_t rp() const
Definition: CTPPSDetId.h:74