CMS 3D CMS Logo

BtlLocalRecoValidation.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Validation/MtdValidation
4 // Class: BtlLocalRecoValidation
5 //
14 #include <string>
15 
20 
23 
30 
34 
39 
42 
44 
47 
48 #include "MTDHit.h"
49 
51 public:
53  ~BtlLocalRecoValidation() override;
54 
55  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
56 
57 private:
58  void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
59 
60  void analyze(const edm::Event&, const edm::EventSetup&) override;
61 
62  bool isSameCluster(const FTLCluster&, const FTLCluster&);
63 
64  // ------------ member data ------------
65 
67  const double hitMinEnergy_;
68  const bool optionalPlots_;
70  const double hitMinAmplitude_;
71 
77 
81 
82  // --- histograms declaration
83 
85 
87 
92 
94 
95  //local position monitoring
100 
106 
116 
119 
123 
126 
128 
138 
157 
159 
160  // --- UncalibratedRecHits histograms
161 
162  static constexpr int nBinsQ_ = 20;
163  static constexpr float binWidthQ_ = 30.;
164  static constexpr int nBinsQEta_ = 3;
165  static constexpr float binsQEta_[nBinsQEta_ + 1] = {0., 0.65, 1.15, 1.55};
166 
169 
170  static constexpr int nBinsEta_ = 31;
171  static constexpr float binWidthEta_ = 0.05;
172  static constexpr int nBinsEtaQ_ = 7;
173  static constexpr float binsEtaQ_[nBinsEtaQ_ + 1] = {0., 30., 60., 90., 120., 150., 360., 600.};
174 
177 };
178 
180  return clu1.id() == clu2.id() && clu1.size() == clu2.size() && clu1.x() == clu2.x() && clu1.y() == clu2.y() &&
181  clu1.time() == clu2.time();
182 }
183 
184 // ------------ constructor and destructor --------------
186  : folder_(iConfig.getParameter<std::string>("folder")),
187  hitMinEnergy_(iConfig.getParameter<double>("HitMinimumEnergy")),
188  optionalPlots_(iConfig.getParameter<bool>("optionalPlots")),
189  uncalibRecHitsPlots_(iConfig.getParameter<bool>("UncalibRecHitsPlots")),
190  hitMinAmplitude_(iConfig.getParameter<double>("HitMinimumAmplitude")),
191  mtdgeoToken_(esConsumes<MTDGeometry, MTDDigiGeometryRecord>()),
192  mtdtopoToken_(esConsumes<MTDTopology, MTDTopologyRcd>()),
193  cpeToken_(esConsumes<MTDClusterParameterEstimator, MTDCPERecord>(edm::ESInputTag("", "MTDCPEBase"))) {
194  btlRecHitsToken_ = consumes<FTLRecHitCollection>(iConfig.getParameter<edm::InputTag>("recHitsTag"));
197  consumes<FTLUncalibratedRecHitCollection>(iConfig.getParameter<edm::InputTag>("uncalibRecHitsTag"));
198  btlSimHitsToken_ = consumes<CrossingFrame<PSimHit> >(iConfig.getParameter<edm::InputTag>("simHitsTag"));
199  btlRecCluToken_ = consumes<FTLClusterCollection>(iConfig.getParameter<edm::InputTag>("recCluTag"));
200  mtdTrackingHitToken_ = consumes<MTDTrackingDetSetVector>(iConfig.getParameter<edm::InputTag>("trkHitTag"));
201 }
202 
204 
205 // ------------ method called for each event ------------
207  using namespace edm;
208  using namespace std;
209  using namespace geant_units::operators;
210 
211  auto geometryHandle = iSetup.getTransientHandle(mtdgeoToken_);
212  const MTDGeometry* geom = geometryHandle.product();
213 
214  auto topologyHandle = iSetup.getTransientHandle(mtdtopoToken_);
215  const MTDTopology* topology = topologyHandle.product();
216 
217  auto const& cpe = iSetup.getData(cpeToken_);
218 
219  auto btlRecHitsHandle = makeValid(iEvent.getHandle(btlRecHitsToken_));
220  auto btlSimHitsHandle = makeValid(iEvent.getHandle(btlSimHitsToken_));
221  auto btlRecCluHandle = makeValid(iEvent.getHandle(btlRecCluToken_));
222  auto mtdTrkHitHandle = makeValid(iEvent.getHandle(mtdTrackingHitToken_));
223  MixCollection<PSimHit> btlSimHits(btlSimHitsHandle.product());
224 
225 #ifdef EDM_ML_DEBUG
226  for (const auto& hits : *mtdTrkHitHandle) {
227  if (MTDDetId(hits.id()).mtdSubDetector() == MTDDetId::MTDType::BTL) {
228  LogDebug("BtlLocalRecoValidation") << "MTD cluster DetId " << hits.id() << " # cluster " << hits.size();
229  for (const auto& hit : hits) {
230  LogDebug("BtlLocalRecoValidation")
231  << "MTD_TRH: " << hit.localPosition().x() << "," << hit.localPosition().y() << " : "
232  << hit.localPositionError().xx() << "," << hit.localPositionError().yy() << " : " << hit.time() << " : "
233  << hit.timeError();
234  }
235  }
236  }
237 #endif
238 
239  // --- Loop over the BTL SIM hits
240  std::unordered_map<uint32_t, MTDHit> m_btlSimHits;
241  for (auto const& simHit : btlSimHits) {
242  // --- Use only hits compatible with the in-time bunch-crossing
243  if (simHit.tof() < 0 || simHit.tof() > 25.)
244  continue;
245 
246  DetId id = simHit.detUnitId();
247 
248  auto simHitIt = m_btlSimHits.emplace(id.rawId(), MTDHit()).first;
249 
250  // --- Accumulate the energy (in MeV) of SIM hits in the same detector cell
251  (simHitIt->second).energy += convertUnitsTo(0.001_MeV, simHit.energyLoss());
252 
253  // --- Get the time of the first SIM hit in the cell
254  if ((simHitIt->second).time == 0 || simHit.tof() < (simHitIt->second).time) {
255  (simHitIt->second).time = simHit.tof();
256 
257  auto hit_pos = simHit.localPosition();
258  (simHitIt->second).x = hit_pos.x();
259  (simHitIt->second).y = hit_pos.y();
260  (simHitIt->second).z = hit_pos.z();
261  }
262 
263  } // simHit loop
264 
265  // --- Loop over the BTL RECO hits
266  unsigned int n_reco_btl = 0;
267  for (const auto& recHit : *btlRecHitsHandle) {
268  BTLDetId detId = recHit.id();
270  const MTDGeomDet* thedet = geom->idToDet(geoId);
271  if (thedet == nullptr)
272  throw cms::Exception("BtlLocalRecoValidation") << "GeographicalID: " << std::hex << geoId.rawId() << " ("
273  << detId.rawId() << ") is invalid!" << std::dec << std::endl;
274  const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(thedet->topology());
275  const RectangularMTDTopology& topo = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
276 
277  Local3DPoint local_point(0., 0., 0.);
278  local_point = topo.pixelToModuleLocalPoint(local_point, detId.row(topo.nrows()), detId.column(topo.nrows()));
279  const auto& global_point = thedet->toGlobal(local_point);
280 
281  meHitEnergy_->Fill(recHit.energy());
282  meHitLogEnergy_->Fill(log10(recHit.energy()));
283  meHitTime_->Fill(recHit.time());
284  meHitTimeError_->Fill(recHit.timeError());
285  meHitLongPos_->Fill(recHit.position());
286  meHitLongPosErr_->Fill(recHit.positionError());
287 
288  meOccupancy_->Fill(global_point.z(), global_point.phi());
289 
290  if (optionalPlots_) {
291  meLocalOccupancy_->Fill(local_point.x() + recHit.position(), local_point.y());
292  meHitXlocal_->Fill(local_point.x());
293  meHitYlocal_->Fill(local_point.y());
294  meHitZlocal_->Fill(local_point.z());
295  }
296  meHitX_->Fill(global_point.x());
297  meHitY_->Fill(global_point.y());
298  meHitZ_->Fill(global_point.z());
299  meHitPhi_->Fill(global_point.phi());
300  meHitEta_->Fill(global_point.eta());
301 
302  meHitTvsE_->Fill(recHit.energy(), recHit.time());
303  meHitEvsPhi_->Fill(global_point.phi(), recHit.energy());
304  meHitEvsEta_->Fill(global_point.eta(), recHit.energy());
305  meHitEvsZ_->Fill(global_point.z(), recHit.energy());
306  meHitTvsPhi_->Fill(global_point.phi(), recHit.time());
307  meHitTvsEta_->Fill(global_point.eta(), recHit.time());
308  meHitTvsZ_->Fill(global_point.z(), recHit.time());
309 
310  // Resolution histograms
311  if (m_btlSimHits.count(detId.rawId()) == 1 && m_btlSimHits[detId.rawId()].energy > hitMinEnergy_) {
312  float longpos_res = recHit.position() - convertMmToCm(m_btlSimHits[detId.rawId()].x);
313  float time_res = recHit.time() - m_btlSimHits[detId.rawId()].time;
314  float energy_res = recHit.energy() - m_btlSimHits[detId.rawId()].energy;
315 
316  Local3DPoint local_point_sim(convertMmToCm(m_btlSimHits[detId.rawId()].x),
317  convertMmToCm(m_btlSimHits[detId.rawId()].y),
318  convertMmToCm(m_btlSimHits[detId.rawId()].z));
319  local_point_sim =
320  topo.pixelToModuleLocalPoint(local_point_sim, detId.row(topo.nrows()), detId.column(topo.nrows()));
321  const auto& global_point_sim = thedet->toGlobal(local_point_sim);
322 
323  meTimeRes_->Fill(time_res);
324  meEnergyRes_->Fill(energy_res);
325 
326  meLongPosPull_->Fill(longpos_res / recHit.positionError());
327  meLongPosPullvsEta_->Fill(std::abs(global_point_sim.eta()), longpos_res / recHit.positionError());
328  meLongPosPullvsE_->Fill(m_btlSimHits[detId.rawId()].energy, longpos_res / recHit.positionError());
329 
330  meTPullvsEta_->Fill(std::abs(global_point_sim.eta()), time_res / recHit.timeError());
331  meTPullvsE_->Fill(m_btlSimHits[detId.rawId()].energy, time_res / recHit.timeError());
332  }
333 
334  n_reco_btl++;
335 
336  } // recHit loop
337 
338  if (n_reco_btl > 0)
339  meNhits_->Fill(log10(n_reco_btl));
340 
341  // --- Loop over the BTL RECO clusters ---
342  unsigned int n_clus_btl(0);
343  for (const auto& DetSetClu : *btlRecCluHandle) {
344  for (const auto& cluster : DetSetClu) {
345  if (cluster.energy() < hitMinEnergy_)
346  continue;
347  BTLDetId cluId = cluster.id();
348  DetId detIdObject(cluId);
349  const auto& genericDet = geom->idToDetUnit(detIdObject);
350  if (genericDet == nullptr) {
351  throw cms::Exception("BtlLocalRecoValidation")
352  << "GeographicalID: " << std::hex << cluId << " is invalid!" << std::dec << std::endl;
353  }
354  n_clus_btl++;
355 
356  const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(genericDet->topology());
357  const RectangularMTDTopology& topo = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
358 
359  MTDClusterParameterEstimator::ReturnType tuple = cpe.getParameters(cluster, *genericDet);
360 
361  // --- Cluster position in the module reference frame
362  LocalPoint local_point(std::get<0>(tuple));
363  const auto& global_point = genericDet->toGlobal(local_point);
364 
365  meCluEnergy_->Fill(cluster.energy());
366  meCluTime_->Fill(cluster.time());
367  meCluTimeError_->Fill(cluster.timeError());
368  meCluPhi_->Fill(global_point.phi());
369  meCluEta_->Fill(global_point.eta());
370  meCluZvsPhi_->Fill(global_point.z(), global_point.phi());
371  meCluHits_->Fill(cluster.size());
372 
373  // --- Get the SIM hits associated to the cluster and calculate
374  // the cluster SIM energy, time and position
375 
376  double cluEneSIM = 0.;
377  double cluTimeSIM = 0.;
378  double cluLocXSIM = 0.;
379  double cluLocYSIM = 0.;
380  double cluLocZSIM = 0.;
381 
382  for (int ihit = 0; ihit < cluster.size(); ++ihit) {
383  int hit_row = cluster.minHitRow() + cluster.hitOffset()[ihit * 2];
384  int hit_col = cluster.minHitCol() + cluster.hitOffset()[ihit * 2 + 1];
385 
386  // Match the RECO hit to the corresponding SIM hit
387  for (const auto& recHit : *btlRecHitsHandle) {
388  BTLDetId hitId(recHit.id().rawId());
389 
390  if (m_btlSimHits.count(hitId.rawId()) == 0)
391  continue;
392 
393  // Check the hit position
394  if (hitId.mtdSide() != cluId.mtdSide() || hitId.mtdRR() != cluId.mtdRR() || recHit.row() != hit_row ||
395  recHit.column() != hit_col)
396  continue;
397 
398  // Check the hit energy and time
399  if (recHit.energy() != cluster.hitENERGY()[ihit] || recHit.time() != cluster.hitTIME()[ihit])
400  continue;
401 
402  // SIM hit's position in the module reference frame
403  Local3DPoint local_point_sim(convertMmToCm(m_btlSimHits[recHit.id().rawId()].x),
404  convertMmToCm(m_btlSimHits[recHit.id().rawId()].y),
405  convertMmToCm(m_btlSimHits[recHit.id().rawId()].z));
406  local_point_sim =
407  topo.pixelToModuleLocalPoint(local_point_sim, hitId.row(topo.nrows()), hitId.column(topo.nrows()));
408 
409  // Calculate the SIM cluster's position in the module reference frame
410  cluLocXSIM += local_point_sim.x() * m_btlSimHits[recHit.id().rawId()].energy;
411  cluLocYSIM += local_point_sim.y() * m_btlSimHits[recHit.id().rawId()].energy;
412  cluLocZSIM += local_point_sim.z() * m_btlSimHits[recHit.id().rawId()].energy;
413 
414  // Calculate the SIM cluster energy and time
415  cluEneSIM += m_btlSimHits[recHit.id().rawId()].energy;
416  cluTimeSIM += m_btlSimHits[recHit.id().rawId()].time * m_btlSimHits[recHit.id().rawId()].energy;
417 
418  break;
419 
420  } // recHit loop
421 
422  } // ihit loop
423 
424  // Find the MTDTrackingRecHit corresponding to the cluster
425  const MTDTrackingRecHit* comp(nullptr);
426  bool matchClu = false;
427  const auto& trkHits = (*mtdTrkHitHandle)[detIdObject];
428  for (const auto& trkHit : trkHits) {
429  if (isSameCluster(trkHit.mtdCluster(), cluster)) {
430  comp = trkHit.clone();
431  matchClu = true;
432  break;
433  }
434  }
435  if (!matchClu) {
436  edm::LogWarning("BtlLocalRecoValidation")
437  << "No valid TrackingRecHit corresponding to cluster, detId = " << detIdObject.rawId();
438  }
439 
440  // --- Fill the cluster resolution histograms
441  if (cluTimeSIM > 0. && cluEneSIM > 0.) {
442  cluTimeSIM /= cluEneSIM;
443 
444  Local3DPoint cluLocalPosSIM(cluLocXSIM / cluEneSIM, cluLocYSIM / cluEneSIM, cluLocZSIM / cluEneSIM);
445  const auto& cluGlobalPosSIM = genericDet->toGlobal(cluLocalPosSIM);
446 
447  float time_res = cluster.time() - cluTimeSIM;
448  float energy_res = cluster.energy() - cluEneSIM;
449  meCluTimeRes_->Fill(time_res);
450  meCluEnergyRes_->Fill(energy_res);
451 
452  float rho_res = global_point.perp() - cluGlobalPosSIM.perp();
453  float phi_res = global_point.phi() - cluGlobalPosSIM.phi();
454 
455  meCluRhoRes_->Fill(rho_res);
456  meCluPhiRes_->Fill(phi_res);
457 
458  float xlocal_res = local_point.x() - cluLocalPosSIM.x();
459  float ylocal_res = local_point.y() - cluLocalPosSIM.y();
460  float z_res = global_point.z() - cluGlobalPosSIM.z();
461 
462  meCluZRes_->Fill(z_res);
463 
464  if (optionalPlots_) {
465  if (matchClu && comp != nullptr) {
466  meCluLocalXRes_->Fill(xlocal_res);
467  meCluLocalYRes_->Fill(ylocal_res);
468  meCluLocalXPull_->Fill(xlocal_res / std::sqrt(comp->localPositionError().xx()));
469  meCluLocalYPull_->Fill(ylocal_res / std::sqrt(comp->localPositionError().yy()));
470  meCluZPull_->Fill(z_res / std::sqrt(comp->globalPositionError().czz()));
471  meCluXLocalErr_->Fill(std::sqrt(comp->localPositionError().xx()));
472  meCluYLocalErr_->Fill(std::sqrt(comp->localPositionError().yy()));
473  }
474 
475  meCluYXLocal_->Fill(local_point.x(), local_point.y());
476  meCluYXLocalSim_->Fill(cluLocalPosSIM.x(), cluLocalPosSIM.y());
477  }
478 
479  meCluEnergyvsEta_->Fill(std::abs(cluGlobalPosSIM.eta()), cluster.energy());
480  meCluHitsvsEta_->Fill(std::abs(cluGlobalPosSIM.eta()), cluster.size());
481 
482  meCluTResvsEta_->Fill(std::abs(cluGlobalPosSIM.eta()), time_res);
483  meCluTResvsE_->Fill(cluEneSIM, time_res);
484 
485  meCluTPullvsEta_->Fill(std::abs(cluGlobalPosSIM.eta()), time_res / cluster.timeError());
486  meCluTPullvsE_->Fill(cluEneSIM, time_res / cluster.timeError());
487 
488  } // if ( cluTimeSIM > 0. && cluEneSIM > 0. )
489  else {
490  meUnmatchedCluEnergy_->Fill(std::log10(cluster.energy()));
491  }
492 
493  } // cluster loop
494 
495  } // DetSetClu loop
496 
497  if (n_clus_btl > 0)
498  meNclusters_->Fill(log10(n_clus_btl));
499 
500  // --- This is to count the number of processed events, needed in the harvesting step
501  meNevents_->Fill(0.5);
502 
503  // --- Loop over the BTL Uncalibrated RECO hits
504  if (uncalibRecHitsPlots_) {
505  auto btlUncalibRecHitsHandle = makeValid(iEvent.getHandle(btlUncalibRecHitsToken_));
506 
507  for (const auto& uRecHit : *btlUncalibRecHitsHandle) {
508  BTLDetId detId = uRecHit.id();
509 
510  // --- Skip UncalibratedRecHits not matched to SimHits
511  if (m_btlSimHits.count(detId.rawId()) != 1)
512  continue;
513 
515  const MTDGeomDet* thedet = geom->idToDet(geoId);
516  if (thedet == nullptr)
517  throw cms::Exception("BtlLocalRecoValidation") << "GeographicalID: " << std::hex << geoId.rawId() << " ("
518  << detId.rawId() << ") is invalid!" << std::dec << std::endl;
519  const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(thedet->topology());
520  const RectangularMTDTopology& topo = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
521 
522  Local3DPoint local_point(0., 0., 0.);
523  local_point = topo.pixelToModuleLocalPoint(local_point, detId.row(topo.nrows()), detId.column(topo.nrows()));
524  const auto& global_point = thedet->toGlobal(local_point);
525 
526  // --- Combine the information from the left and right BTL cell sides
527 
528  float nHits = 0.;
529  float hit_amplitude = 0.;
530  float hit_time = 0.;
531 
532  // left side:
533  if (uRecHit.amplitude().first > 0.) {
534  hit_amplitude += uRecHit.amplitude().first;
535  hit_time += uRecHit.time().first;
536  nHits += 1.;
537  }
538  // right side:
539  if (uRecHit.amplitude().second > 0.) {
540  hit_amplitude += uRecHit.amplitude().second;
541  hit_time += uRecHit.time().second;
542  nHits += 1.;
543  }
544 
545  hit_amplitude /= nHits;
546  hit_time /= nHits;
547 
548  // --- Fill the histograms
549 
550  if (hit_amplitude < hitMinAmplitude_)
551  continue;
552 
553  float time_res = hit_time - m_btlSimHits[detId.rawId()].time;
554 
555  // amplitude histograms
556 
557  int qBin = (int)(hit_amplitude / binWidthQ_);
558  if (qBin > nBinsQ_ - 1)
559  qBin = nBinsQ_ - 1;
560 
561  meTimeResQ_[qBin]->Fill(time_res);
562 
563  int etaBin = 0;
564  for (int ibin = 1; ibin < nBinsQEta_; ++ibin)
565  if (fabs(global_point.eta()) >= binsQEta_[ibin] && fabs(global_point.eta()) < binsQEta_[ibin + 1])
566  etaBin = ibin;
567 
568  meTimeResQvsEta_[qBin][etaBin]->Fill(time_res);
569 
570  // eta histograms
571 
572  etaBin = (int)(fabs(global_point.eta()) / binWidthEta_);
573  if (etaBin > nBinsEta_ - 1)
574  etaBin = nBinsEta_ - 1;
575 
576  meTimeResEta_[etaBin]->Fill(time_res);
577 
578  qBin = 0;
579  for (int ibin = 1; ibin < nBinsEtaQ_; ++ibin)
580  if (hit_amplitude >= binsEtaQ_[ibin] && hit_amplitude < binsEtaQ_[ibin + 1])
581  qBin = ibin;
582 
583  meTimeResEtavsQ_[etaBin][qBin]->Fill(time_res);
584 
585  } // uRecHit loop
586  }
587 }
588 
589 // ------------ method for histogram booking ------------
591  edm::Run const& run,
592  edm::EventSetup const& iSetup) {
593  ibook.setCurrentFolder(folder_);
594 
595  // --- histograms booking
596 
597  meNevents_ = ibook.book1D("BtlNevents", "Number of events", 1, 0., 1.);
598 
599  meNhits_ = ibook.book1D("BtlNhits", "Number of BTL RECO hits;log_{10}(N_{RECO})", 100, 0., 5.25);
600 
601  meHitEnergy_ = ibook.book1D("BtlHitEnergy", "BTL RECO hits energy;E_{RECO} [MeV]", 100, 0., 20.);
602  meHitLogEnergy_ = ibook.book1D("BtlHitLogEnergy", "BTL RECO hits energy;log_{10}(E_{RECO} [MeV])", 25, -1., 1.5);
603  meHitTime_ = ibook.book1D("BtlHitTime", "BTL RECO hits ToA;ToA_{RECO} [ns]", 100, 0., 25.);
604  meHitTimeError_ = ibook.book1D("BtlHitTimeError", "BTL RECO hits ToA error;#sigma^{ToA}_{RECO} [ns]", 50, 0., 0.1);
605  meOccupancy_ = ibook.book2D(
606  "BtlOccupancy", "BTL RECO hits occupancy;Z_{RECO} [cm]; #phi_{RECO} [rad]", 65, -260., 260., 126, -3.2, 3.2);
607  if (optionalPlots_) {
608  meLocalOccupancy_ = ibook.book2D(
609  "BtlLocalOccupancy", "BTL RECO hits local occupancy;X_{RECO} [cm]; Y_{RECO} [cm]", 100, 10., 10., 60, -3., 3.);
610  meHitXlocal_ = ibook.book1D("BtlHitXlocal", "BTL RECO local X;X_{RECO}^{LOC} [cm]", 100, -10., 10.);
611  meHitYlocal_ = ibook.book1D("BtlHitYlocal", "BTL RECO local Y;Y_{RECO}^{LOC} [cm]", 60, -3, 3);
612  meHitZlocal_ = ibook.book1D("BtlHitZlocal", "BTL RECO local z;z_{RECO}^{LOC} [cm]", 10, -1, 1);
613  }
614  meHitX_ = ibook.book1D("BtlHitX", "BTL RECO hits X;X_{RECO} [cm]", 60, -120., 120.);
615  meHitY_ = ibook.book1D("BtlHitY", "BTL RECO hits Y;Y_{RECO} [cm]", 60, -120., 120.);
616  meHitZ_ = ibook.book1D("BtlHitZ", "BTL RECO hits Z;Z_{RECO} [cm]", 100, -260., 260.);
617  meHitPhi_ = ibook.book1D("BtlHitPhi", "BTL RECO hits #phi;#phi_{RECO} [rad]", 126, -3.2, 3.2);
618  meHitEta_ = ibook.book1D("BtlHitEta", "BTL RECO hits #eta;#eta_{RECO}", 100, -1.55, 1.55);
619  meHitTvsE_ =
620  ibook.bookProfile("BtlHitTvsE", "BTL RECO ToA vs energy;E_{RECO} [MeV];ToA_{RECO} [ns]", 50, 0., 20., 0., 100.);
621  meHitEvsPhi_ = ibook.bookProfile(
622  "BtlHitEvsPhi", "BTL RECO energy vs #phi;#phi_{RECO} [rad];E_{RECO} [MeV]", 50, -3.2, 3.2, 0., 100.);
623  meHitEvsEta_ = ibook.bookProfile(
624  "BtlHitEvsEta", "BTL RECO energy vs #eta;#eta_{RECO};E_{RECO} [MeV]", 50, -1.55, 1.55, 0., 100.);
625  meHitEvsZ_ =
626  ibook.bookProfile("BtlHitEvsZ", "BTL RECO energy vs Z;Z_{RECO} [cm];E_{RECO} [MeV]", 50, -260., 260., 0., 100.);
627  meHitTvsPhi_ = ibook.bookProfile(
628  "BtlHitTvsPhi", "BTL RECO ToA vs #phi;#phi_{RECO} [rad];ToA_{RECO} [ns]", 50, -3.2, 3.2, 0., 100.);
629  meHitTvsEta_ =
630  ibook.bookProfile("BtlHitTvsEta", "BTL RECO ToA vs #eta;#eta_{RECO};ToA_{RECO} [ns]", 50, -1.6, 1.6, 0., 100.);
631  meHitTvsZ_ =
632  ibook.bookProfile("BtlHitTvsZ", "BTL RECO ToA vs Z;Z_{RECO} [cm];ToA_{RECO} [ns]", 50, -260., 260., 0., 100.);
633  meHitLongPos_ = ibook.book1D("BtlLongPos", "BTL RECO hits longitudinal position;long. pos._{RECO}", 100, -10, 10);
635  ibook.book1D("BtlLongPosErr", "BTL RECO hits longitudinal position error; long. pos. error_{RECO}", 100, -1, 1);
636  meTimeRes_ = ibook.book1D("BtlTimeRes", "BTL time resolution;T_{RECO}-T_{SIM}", 100, -0.5, 0.5);
637  meEnergyRes_ = ibook.book1D("BtlEnergyRes", "BTL energy resolution;E_{RECO}-E_{SIM}", 100, -0.5, 0.5);
638  meLongPosPull_ = ibook.book1D("BtlLongPosPull",
639  "BTL longitudinal position pull;X^{loc}_{RECO}-X^{loc}_{SIM}/#sigma_{xloc_{RECO}}",
640  100,
641  -5.,
642  5.);
644  "BtlLongposPullvsE",
645  "BTL longitudinal position pull vs E;E_{SIM} [MeV];X^{loc}_{RECO}-X^{loc}_{SIM}/#sigma_{xloc_{RECO}}",
646  20,
647  0.,
648  20.,
649  -5.,
650  5.,
651  "S");
653  "BtlLongposPullvsEta",
654  "BTL longitudinal position pull vs #eta;|#eta_{RECO}|;X^{loc}_{RECO}-X^{loc}_{SIM}/#sigma_{xloc_{RECO}}",
655  32,
656  0,
657  1.55,
658  -5.,
659  5.,
660  "S");
661  meTPullvsE_ = ibook.bookProfile(
662  "BtlTPullvsE", "BTL time pull vs E;E_{SIM} [MeV];(T_{RECO}-T_{SIM})/#sigma_{T_{RECO}}", 20, 0., 20., -5., 5., "S");
663  meTPullvsEta_ = ibook.bookProfile("BtlTPullvsEta",
664  "BTL time pull vs #eta;|#eta_{RECO}|;(T_{RECO}-T_{SIM})/#sigma_{T_{RECO}}",
665  30,
666  0,
667  1.55,
668  -5.,
669  5.,
670  "S");
671 
672  meNclusters_ = ibook.book1D("BtlNclusters", "Number of BTL RECO clusters;log_{10}(N_{RECO})", 100, 0., 5.25);
673  meCluTime_ = ibook.book1D("BtlCluTime", "BTL cluster time ToA;ToA [ns]", 250, 0, 25);
674  meCluTimeError_ = ibook.book1D("BtlCluTimeError", "BTL cluster time error;#sigma_{t} [ns]", 100, 0, 0.1);
675  meCluEnergy_ = ibook.book1D("BtlCluEnergy", "BTL cluster energy;E_{RECO} [MeV]", 100, 0, 20);
676  meCluPhi_ = ibook.book1D("BtlCluPhi", "BTL cluster #phi;#phi_{RECO} [rad]", 144, -3.2, 3.2);
677  meCluEta_ = ibook.book1D("BtlCluEta", "BTL cluster #eta;#eta_{RECO}", 100, -1.55, 1.55);
678  meCluHits_ = ibook.book1D("BtlCluHitNumber", "BTL hits per cluster; Cluster size", 10, 0, 10);
679  meCluZvsPhi_ = ibook.book2D(
680  "BtlOccupancy", "BTL cluster Z vs #phi;Z_{RECO} [cm]; #phi_{RECO} [rad]", 144, -260., 260., 50, -3.2, 3.2);
682  "BtlCluEnergyVsEta", "BTL cluster energy vs #eta; |#eta_{RECO}|; E_{RECO} [cm]", 30, 0., 1.55, 0., 20., "S");
684  "BtlCluHitsVsEta", "BTL hits per cluster vs #eta; |#eta_{RECO}|;Cluster size", 30, 0., 1.55, 0., 10., "S");
685 
686  meCluTimeRes_ = ibook.book1D("BtlCluTimeRes", "BTL cluster time resolution;T_{RECO}-T_{SIM} [ns]", 100, -0.5, 0.5);
688  ibook.book1D("BtlCluEnergyRes", "BTL cluster energy resolution;E_{RECO}-E_{SIM} [MeV]", 100, -0.5, 0.5);
689  meCluTResvsE_ = ibook.bookProfile("BtlCluTResvsE",
690  "BTL cluster time resolution vs E;E_{SIM} [MeV];(T_{RECO}-T_{SIM}) [ns]",
691  20,
692  0.,
693  20.,
694  -0.5,
695  0.5,
696  "S");
697  meCluTResvsEta_ = ibook.bookProfile("BtlCluTResvsEta",
698  "BTL cluster time resolution vs #eta;|#eta_{RECO}|;(T_{RECO}-T_{SIM}) [ns]",
699  30,
700  0,
701  1.55,
702  -0.5,
703  0.5,
704  "S");
705  meCluTPullvsE_ = ibook.bookProfile("BtlCluTPullvsE",
706  "BTL cluster time pull vs E;E_{SIM} [MeV];(T_{RECO}-T_{SIM})/#sigma_{T_{RECO}}",
707  20,
708  0.,
709  20.,
710  -5.,
711  5.,
712  "S");
714  ibook.bookProfile("BtlCluTPullvsEta",
715  "BTL cluster time pull vs #eta;|#eta_{RECO}|;(T_{RECO}-T_{SIM})/#sigma_{T_{RECO}}",
716  30,
717  0,
718  1.55,
719  -5.,
720  5.,
721  "S");
722  meCluRhoRes_ =
723  ibook.book1D("BtlCluRhoRes", "BTL cluster #rho resolution;#rho_{RECO}-#rho_{SIM} [cm]", 100, -0.5, 0.5);
724  meCluPhiRes_ =
725  ibook.book1D("BtlCluPhiRes", "BTL cluster #phi resolution;#phi_{RECO}-#phi_{SIM} [rad]", 100, -0.03, 0.03);
726  meCluZRes_ = ibook.book1D("BtlCluZRes", "BTL cluster Z resolution;Z_{RECO}-Z_{SIM} [cm]", 100, -0.2, 0.2);
727  if (optionalPlots_) {
729  ibook.book1D("BtlCluLocalXRes", "BTL cluster local X resolution;X_{RECO}-X_{SIM} [cm]", 100, -3.1, 3.1);
731  ibook.book1D("BtlCluLocalYRes", "BTL cluster local Y resolution;Y_{RECO}-Y_{SIM} [cm]", 100, -3.1, 3.1);
733  ibook.book1D("BtlCluLocalXPull", "BTL cluster local X pull;X_{RECO}-X_{SIM}/sigmaX_[RECO]", 100, -5., 5.);
735  ibook.book1D("BtlCluLocalYPull", "BTL cluster local Y pull;Y_{RECO}-Y_{SIM}/sigmaY_[RECO]", 100, -5., 5.);
736  meCluZPull_ = ibook.book1D("BtlCluZPull", "BTL cluster Z pull;Z_{RECO}-Z_{SIM}/sigmaZ_[RECO]", 100, -5., 5.);
737  meCluYXLocal_ = ibook.book2D("BtlCluYXLocal",
738  "BTL cluster local Y vs X;X^{local}_{RECO} [cm];Y^{local}_{RECO} [cm]",
739  200,
740  -9.5,
741  9.5,
742  200,
743  -2.8,
744  2.8);
745  meCluYXLocalSim_ = ibook.book2D("BtlCluYXLocalSim",
746  "BTL cluster local Y vs X;X^{local}_{SIM} [cm];Y^{local}_{SIM} [cm]",
747  200,
748  -9.5,
749  9.5,
750  200,
751  -2.8,
752  2.8);
753  meCluXLocalErr_ = ibook.book1D("BtlCluXLocalErr", "BTL cluster X local error;sigmaX_{RECO,loc} [cm]", 30, 0., 3.);
754  meCluYLocalErr_ = ibook.book1D("BtlCluYLocalErr", "BTL cluster Y local error;sigmaY_{RECO,loc} [cm]", 30, 0., 0.9);
755  }
757  ibook.book1D("BtlUnmatchedCluEnergy", "BTL unmatched cluster log10(energy);log10(E_{RECO} [MeV])", 5, -3, 2);
758 
759  // --- UncalibratedRecHits histograms
760 
761  if (uncalibRecHitsPlots_) {
762  for (unsigned int ihistoQ = 0; ihistoQ < nBinsQ_; ++ihistoQ) {
763  std::string hname = Form("TimeResQ_%d", ihistoQ);
764  std::string htitle = Form("BTL time resolution (Q bin = %d);T_{RECO} - T_{SIM} [ns]", ihistoQ);
765  meTimeResQ_[ihistoQ] = ibook.book1D(hname, htitle, 200, -0.3, 0.7);
766 
767  for (unsigned int ihistoEta = 0; ihistoEta < nBinsQEta_; ++ihistoEta) {
768  hname = Form("TimeResQvsEta_%d_%d", ihistoQ, ihistoEta);
769  htitle = Form("BTL time resolution (Q bin = %d, |#eta| bin = %d);T_{RECO} - T_{SIM} [ns]", ihistoQ, ihistoEta);
770  meTimeResQvsEta_[ihistoQ][ihistoEta] = ibook.book1D(hname, htitle, 200, -0.3, 0.7);
771 
772  } // ihistoEta loop
773 
774  } // ihistoQ loop
775 
776  for (unsigned int ihistoEta = 0; ihistoEta < nBinsEta_; ++ihistoEta) {
777  std::string hname = Form("TimeResEta_%d", ihistoEta);
778  std::string htitle = Form("BTL time resolution (|#eta| bin = %d);T_{RECO} - T_{SIM} [ns]", ihistoEta);
779  meTimeResEta_[ihistoEta] = ibook.book1D(hname, htitle, 200, -0.3, 0.7);
780 
781  for (unsigned int ihistoQ = 0; ihistoQ < nBinsEtaQ_; ++ihistoQ) {
782  hname = Form("TimeResEtavsQ_%d_%d", ihistoEta, ihistoQ);
783  htitle = Form("BTL time resolution (|#eta| bin = %d, Q bin = %d);T_{RECO} - T_{SIM} [ns]", ihistoEta, ihistoQ);
784  meTimeResEtavsQ_[ihistoEta][ihistoQ] = ibook.book1D(hname, htitle, 200, -0.3, 0.7);
785 
786  } // ihistoQ loop
787 
788  } // ihistoEta loop
789  }
790 }
791 
792 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
795 
796  desc.add<std::string>("folder", "MTD/BTL/LocalReco");
797  desc.add<edm::InputTag>("recHitsTag", edm::InputTag("mtdRecHits", "FTLBarrel"));
798  desc.add<edm::InputTag>("uncalibRecHitsTag", edm::InputTag("mtdUncalibratedRecHits", "FTLBarrel"));
799  desc.add<edm::InputTag>("simHitsTag", edm::InputTag("mix", "g4SimHitsFastTimerHitsBarrel"));
800  desc.add<edm::InputTag>("recCluTag", edm::InputTag("mtdClusters", "FTLBarrel"));
801  desc.add<edm::InputTag>("trkHitTag", edm::InputTag("mtdTrackingRecHits"));
802  desc.add<double>("HitMinimumEnergy", 1.); // [MeV]
803  desc.add<bool>("optionalPlots", false);
804  desc.add<bool>("UncalibRecHitsPlots", false);
805  desc.add<double>("HitMinimumAmplitude", 30.); // [pC]
806 
807  descriptions.add("btlLocalRecoValid", desc);
808 }
809 
uint8_t geoId(const VFATFrame &frame)
retrieve the GEO information for this channel
int getMTDTopologyMode() const
Definition: MTDTopology.h:27
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
int row(unsigned nrows=kCrystalsPerModuleV2) const
Definition: BTLDetId.h:93
std::string folder_
float x() const
Definition: FTLCluster.h:120
int size() const
Definition: FTLCluster.h:141
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
const edm::ESGetToken< MTDTopology, MTDTopologyRcd > mtdtopoToken_
T z() const
Definition: PV3DBase.h:61
virtual const Topology & topology() const
Definition: GeomDet.cc:67
virtual const PixelTopology & specificTopology() const
const edm::ESGetToken< MTDClusterParameterEstimator, MTDCPERecord > cpeToken_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
int mtdSide() const
Definition: MTDDetId.h:59
Definition: MTDHit.h:4
static constexpr float binWidthQ_
MonitorElement * meUnmatchedCluEnergy_
static constexpr int nBinsEtaQ_
LocalPoint pixelToModuleLocalPoint(const LocalPoint &plp, int row, int col) const
edm::EDGetTokenT< MTDTrackingDetSetVector > mtdTrackingHitToken_
MonitorElement * meLongPosPullvsEta_
Detector identifier base class for the MIP Timing Layer.
Definition: MTDDetId.h:21
constexpr NumType convertUnitsTo(double desiredUnits, NumType val)
Definition: GeantUnits.h:73
bool isSameCluster(const FTLCluster &, const FTLCluster &)
void Fill(long long x)
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
float y() const
Definition: FTLCluster.h:125
int iEvent
Definition: GenABIO.cc:224
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:399
static constexpr float binWidthEta_
T sqrt(T t)
Definition: SSEVec.h:19
edm::EDGetTokenT< FTLClusterCollection > btlRecCluToken_
static constexpr float binsQEta_[nBinsQEta_+1]
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int mtdRR() const
Definition: MTDDetId.h:64
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static constexpr int nBinsQEta_
int nrows() const override
bool getData(T &iHolder) const
Definition: EventSetup.h:122
MonitorElement * meLocalOccupancy_
MonitorElement * meTimeResEta_[nBinsEta_]
int column(unsigned nrows=kCrystalsPerModuleV2) const
Definition: BTLDetId.h:98
BtlLocalRecoValidation(const edm::ParameterSet &)
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
edm::EDGetTokenT< FTLUncalibratedRecHitCollection > btlUncalibRecHitsToken_
const edm::ESGetToken< MTDGeometry, MTDDigiGeometryRecord > mtdgeoToken_
Definition: DetId.h:17
const DetId & id() const
Definition: FTLCluster.h:178
constexpr NumType convertMmToCm(NumType millimeters)
Definition: angle_units.h:44
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
edm::EDGetTokenT< FTLRecHitCollection > btlRecHitsToken_
A 2D TrackerRecHit with time and time error information.
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:212
void add(std::string const &label, ParameterSetDescription const &psetDescription)
caConstants::TupleMultiplicity const CAHitNtupletGeneratorKernelsGPU::HitToTuple const cms::cuda::AtomicPairCounter GPUCACell const *__restrict__ uint32_t const *__restrict__ gpuPixelDoublets::CellNeighborsVector const gpuPixelDoublets::CellTracksVector const GPUCACell::OuterHitOfCell const int32_t nHits
void analyze(const edm::Event &, const edm::EventSetup &) override
static constexpr int nBinsQ_
MonitorElement * meTimeResQvsEta_[nBinsQ_][nBinsQEta_]
static constexpr float binsEtaQ_[nBinsEtaQ_+1]
HLT enums.
MonitorElement * meTimeResEtavsQ_[nBinsEta_][nBinsEtaQ_]
Detector identifier class for the Barrel Timing Layer. The crystal count must start from 0...
Definition: BTLDetId.h:19
ESTransientHandle< T > getTransientHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:162
static constexpr int nBinsEta_
float time() const
Definition: FTLCluster.h:130
BTLDetId::CrysLayout crysLayoutFromTopoMode(const int &topoMode)
Log< level::Warning, false > LogWarning
auto makeValid(const U &iOtherHandleType) noexcept(false)
Definition: ValidHandle.h:52
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
edm::EDGetTokenT< CrossingFrame< PSimHit > > btlSimHitsToken_
MonitorElement * meTimeResQ_[nBinsQ_]
std::tuple< LocalPoint, LocalError, TimeValue, TimeValueError > ReturnType
BTLDetId geographicalId(CrysLayout lay) const
Definition: BTLDetId.cc:3
Definition: Run.h:45
#define LogDebug(id)