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