CMS 3D CMS Logo

DiMuonVertexValidation.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Alignment/OfflineValidation
4 // Class: DiMuonVertexValidation
5 //
11 //
12 // Original Author: Marco Musich
13 // Created: Wed, 21 Apr 2021 09:06:25 GMT
14 //
15 //
16 
17 // system include files
18 #include <memory>
19 #include <utility>
20 
21 // user include files
28 
29 // muons
33 
34 // utils
37 #include "TLorentzVector.h"
38 
39 // tracks
46 
47 // vertices
52 
53 // IP tools
55 
56 // ROOT
57 #include "TH1F.h"
58 #include "TH2F.h"
59 
60 //#define LogDebug(X) std::cout << X
61 
62 //
63 // class declaration
64 //
65 
66 class DiMuonVertexValidation : public edm::one::EDAnalyzer<edm::one::SharedResources> {
67 public:
69  ~DiMuonVertexValidation() override;
70 
71  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
72 
73 private:
74  void beginJob() override;
75  void analyze(const edm::Event&, const edm::EventSetup&) override;
77  void endJob() override;
78 
79  // ----------member data ---------------------------
81 
83  const bool useReco_;
84  const bool useClosestVertex_;
85  std::pair<float, float> massLimits_; /* for the mass plot x-range */
86  std::vector<double> pTthresholds_;
87  const float maxSVdist_;
88 
89  // plot configurations
98 
99  // control plots
100  TH1F* hSVProb_;
101  TH1F* hSVChi2_;
103 
104  TH1F* hSVDist_;
105  TH1F* hSVDistErr_;
106  TH1F* hSVDistSig_;
108 
109  TH1F* hSVDist3D_;
113 
114  TH1F* hCosPhi_;
115  TH1F* hCosPhi3D_;
116  TH1F* hCosPhiInv_;
120 
121  TH1F* hInvMass_;
123 
124  TH1F* hCutFlow_;
125 
126  // impact parameters information
127  TH1F* hdxy_;
128  TH1F* hdz_;
129  TH1F* hdxyErr_;
130  TH1F* hdzErr_;
131  TH1F* hIP2d_;
132  TH1F* hIP3d_;
133  TH1F* hIP2dsig_;
134  TH1F* hIP3dsig_;
135 
136  // 2D maps
137 
146 
147  // plots vs region
150 
152 
153  //used to select what tracks to read from configuration file
155  //used to select what vertices to read from configuration file
157 
158  // either on or the other!
159  edm::EDGetTokenT<reco::MuonCollection> muonsToken_; // used to select tracks to read from configuration file
160  edm::EDGetTokenT<reco::TrackCollection> alcaRecoToken_; //used to select muon tracks to read from configuration file
161 };
162 
163 //
164 // constants, enums and typedefs
165 //
166 
167 static constexpr float cmToum = 10e4;
168 static constexpr float mumass2 = 0.105658367 * 0.105658367; //mu mass squared (GeV^2/c^4)
169 
170 //
171 // static data member definitions
172 //
173 
174 //
175 // constructors and destructor
176 //
178  : motherName_(iConfig.getParameter<std::string>("decayMotherName")),
179  useReco_(iConfig.getParameter<bool>("useReco")),
180  useClosestVertex_(iConfig.getParameter<bool>("useClosestVertex")),
181  pTthresholds_(iConfig.getParameter<std::vector<double>>("pTThresholds")),
182  maxSVdist_(iConfig.getParameter<double>("maxSVdist")),
183  CosPhiConfiguration_(iConfig.getParameter<edm::ParameterSet>("CosPhiConfig")),
184  CosPhi3DConfiguration_(iConfig.getParameter<edm::ParameterSet>("CosPhi3DConfig")),
185  VtxProbConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxProbConfig")),
186  VtxDistConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDistConfig")),
187  VtxDist3DConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDist3DConfig")),
188  VtxDistSigConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDistSigConfig")),
189  VtxDist3DSigConfiguration_(iConfig.getParameter<edm::ParameterSet>("VtxDist3DSigConfig")),
190  DiMuMassConfiguration_(iConfig.getParameter<edm::ParameterSet>("DiMuMassConfig")),
191  ttbESToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))),
192  vertexToken_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))) {
193  if (useReco_) {
194  tracksToken_ = consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"));
195  muonsToken_ = consumes<reco::MuonCollection>(iConfig.getParameter<edm::InputTag>("muons"));
196  } else {
197  alcaRecoToken_ = consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("muonTracks"));
198  }
199 
200  usesResource(TFileService::kSharedResource);
201 
202  // sort the vector of thresholds
203  std::sort(pTthresholds_.begin(), pTthresholds_.end(), [](const double& lhs, const double& rhs) { return lhs > rhs; });
204 
205  edm::LogInfo("DiMuonVertexValidation") << __FUNCTION__;
206  for (const auto& thr : pTthresholds_) {
207  edm::LogInfo("DiMuonVertexValidation") << " Threshold: " << thr << " ";
208  }
209  edm::LogInfo("DiMuonVertexValidation") << "Max SV distance: " << maxSVdist_ << " ";
210 
211  // set the limits for the mass plots
212  if (motherName_.find('Z') != std::string::npos) {
213  massLimits_ = std::make_pair(50., 120);
214  } else if (motherName_.find("J/#psi") != std::string::npos) {
215  massLimits_ = std::make_pair(2.7, 3.4);
216  } else if (motherName_.find("#Upsilon") != std::string::npos) {
217  massLimits_ = std::make_pair(8.9, 9.9);
218  } else {
219  edm::LogError("DiMuonVertexValidation") << " unrecognized decay mother particle: " << motherName_
220  << " setting the default for the Z->mm (50.,120.)" << std::endl;
221  massLimits_ = std::make_pair(50., 120);
222  }
223 }
224 
226 
227 //
228 // member functions
229 //
230 
231 // ------------ method called for each event ------------
233  using namespace edm;
234 
236 
237  // the di-muon tracks
238  std::vector<const reco::Track*> myTracks;
239 
240  // if we have to start from scratch from RECO data-tier
241  if (useReco_) {
242  // select the good muons
243  std::vector<const reco::Muon*> myGoodMuonVector;
244  for (const auto& muon : iEvent.get(muonsToken_)) {
245  const reco::TrackRef t = muon.innerTrack();
246  if (!t.isNull()) {
247  if (t->quality(reco::TrackBase::highPurity)) {
248  if (t->chi2() / t->ndof() <= 2.5 && t->numberOfValidHits() >= 5 &&
249  t->hitPattern().numberOfValidPixelHits() >= 2 && t->quality(reco::TrackBase::highPurity))
250  myGoodMuonVector.emplace_back(&muon);
251  }
252  }
253  }
254 
255  LogDebug("DiMuonVertexValidation") << "myGoodMuonVector size: " << myGoodMuonVector.size() << std::endl;
256  std::sort(myGoodMuonVector.begin(), myGoodMuonVector.end(), [](const reco::Muon*& lhs, const reco::Muon*& rhs) {
257  return lhs->pt() > rhs->pt();
258  });
259 
260  // just check the ordering
261  for (const auto& muon : myGoodMuonVector) {
262  LogDebug("DiMuonVertexValidation") << "pT: " << muon->pt() << " ";
263  }
264  LogDebug("DiMuonVertexValidation") << std::endl;
265 
266  // reject if there's no Z
267  if (myGoodMuonVector.size() < 2)
268  return;
269 
271 
272  if ((myGoodMuonVector[0]->pt()) < pTthresholds_[0] || (myGoodMuonVector[1]->pt() < pTthresholds_[1]))
273  return;
274 
277 
278  if (myGoodMuonVector[0]->charge() * myGoodMuonVector[1]->charge() > 0)
279  return;
280 
281  const auto& m1 = myGoodMuonVector[1]->p4();
282  const auto& m0 = myGoodMuonVector[0]->p4();
283  const auto& mother = m0 + m1;
284 
285  float invMass = mother.M();
286  hInvMass_->Fill(invMass);
287 
288  // just copy the top two muons
289  std::vector<const reco::Muon*> theZMuonVector;
290  theZMuonVector.reserve(2);
291  theZMuonVector.emplace_back(myGoodMuonVector[1]);
292  theZMuonVector.emplace_back(myGoodMuonVector[0]);
293 
294  // do the matching of Z muons with inner tracks
295  unsigned int i = 0;
296  for (const auto& muon : theZMuonVector) {
297  i++;
298  float minD = 1000.;
299  const reco::Track* theMatch = nullptr;
300  for (const auto& track : iEvent.get(tracksToken_)) {
301  float D = ::deltaR(muon->eta(), muon->phi(), track.eta(), track.phi());
302  if (D < minD) {
303  minD = D;
304  theMatch = &track;
305  }
306  }
307  LogDebug("DiMuonVertexValidation") << "pushing new track: " << i << std::endl;
308  myTracks.emplace_back(theMatch);
309  }
310  } else {
311  // we start directly with the pre-selected ALCARECO tracks
312  for (const auto& muon : iEvent.get(alcaRecoToken_)) {
313  myTracks.emplace_back(&muon);
314  }
315  }
316 
317 #ifdef EDM_ML_DEBUG
318  for (const auto& track : myTracks) {
319  edm::LogVerbatim("DiMuonVertexValidation") << __PRETTY_FUNCTION__ << " pT: " << track->pt() << " GeV"
320  << " , pT error: " << track->ptError() << " GeV"
321  << " , eta: " << track->eta() << " , phi: " << track->phi() << std::endl;
322  }
323 #endif
324 
325  LogDebug("DiMuonVertexValidation") << "selected tracks: " << myTracks.size() << std::endl;
326 
327  const TransientTrackBuilder* theB = &iSetup.getData(ttbESToken_);
328  TransientVertex aTransientVertex;
329  std::vector<reco::TransientTrack> tks;
330 
331  if (myTracks.size() != 2)
332  return;
333 
334  const auto& t1 = myTracks[1]->momentum();
335  const auto& t0 = myTracks[0]->momentum();
336  const auto& ditrack = t1 + t0;
337 
338  const auto& tplus = myTracks[0]->charge() > 0 ? myTracks[0] : myTracks[1];
339  const auto& tminus = myTracks[0]->charge() < 0 ? myTracks[0] : myTracks[1];
340 
341  TLorentzVector p4_tplus(tplus->px(), tplus->py(), tplus->pz(), sqrt((tplus->p() * tplus->p()) + mumass2));
342  TLorentzVector p4_tminus(tminus->px(), tminus->py(), tminus->pz(), sqrt((tminus->p() * tminus->p()) + mumass2));
343 
344 #ifdef EDM_ML_DEBUG
345  // Define a lambda function to convert TLorentzVector to a string
346  auto tLorentzVectorToString = [](const TLorentzVector& vector) {
347  return std::to_string(vector.Px()) + " " + std::to_string(vector.Py()) + " " + std::to_string(vector.Pz()) + " " +
348  std::to_string(vector.E());
349  };
350 
351  edm::LogVerbatim("DiMuonVertexValidation") << "mu+" << tLorentzVectorToString(p4_tplus) << std::endl;
352  edm::LogVerbatim("DiMuonVertexValidation") << "mu-" << tLorentzVectorToString(p4_tminus) << std::endl;
353 #endif
354 
355  const auto& Zp4 = p4_tplus + p4_tminus;
356  float track_invMass = Zp4.M();
357  hTrackInvMass_->Fill(track_invMass);
358 
359  // creat the pair of TLorentVectors used to make the plos
360  std::pair<TLorentzVector, TLorentzVector> tktk_p4 = std::make_pair(p4_tplus, p4_tminus);
361 
362  // fill the z->mm mass plots
363  ZMassPlots.fillPlots(track_invMass, tktk_p4);
364  InvMassInEtaBins.fillTH1Plots(track_invMass, tktk_p4);
365 
366  math::XYZPoint ZpT(ditrack.x(), ditrack.y(), 0);
367  math::XYZPoint Zp(ditrack.x(), ditrack.y(), ditrack.z());
368 
369  for (const auto& track : myTracks) {
370  reco::TransientTrack trajectory = theB->build(track);
371  tks.push_back(trajectory);
372  }
373 
374  KalmanVertexFitter kalman(true);
375  aTransientVertex = kalman.vertex(tks);
376 
377  double SVProb = TMath::Prob(aTransientVertex.totalChiSquared(), (int)aTransientVertex.degreesOfFreedom());
378 
379  LogDebug("DiMuonVertexValidation") << " vertex prob: " << SVProb << std::endl;
380 
381  hSVProb_->Fill(SVProb);
382  hSVChi2_->Fill(aTransientVertex.totalChiSquared());
383  hSVNormChi2_->Fill(aTransientVertex.totalChiSquared() / (int)aTransientVertex.degreesOfFreedom());
384 
385  LogDebug("DiMuonVertexValidation") << " vertex norm chi2: "
386  << (aTransientVertex.totalChiSquared() / (int)aTransientVertex.degreesOfFreedom())
387  << std::endl;
388 
389  if (!aTransientVertex.isValid())
390  return;
391 
393 
394  // fill the VtxProb plots
395  VtxProbPlots.fillPlots(SVProb, tktk_p4);
396 
397  math::XYZPoint mainVtxPos(0, 0, 0);
398  const reco::Vertex* theClosestVertex = nullptr;
399  // get collection of reconstructed vertices from event
400  edm::Handle<reco::VertexCollection> vertexHandle = iEvent.getHandle(vertexToken_);
401  if (vertexHandle.isValid()) {
402  const reco::VertexCollection* vertices = vertexHandle.product();
403  theClosestVertex = this->findClosestVertex(aTransientVertex, vertices);
404  } else {
405  edm::LogWarning("DiMuonVertexMonitor") << "invalid vertex collection encountered Skipping event!";
406  return;
407  }
408 
409  reco::Vertex theMainVertex;
410  if (!useClosestVertex_ || theClosestVertex == nullptr) {
411  // if the closest vertex is not available, or explicitly not chosen
412  theMainVertex = vertexHandle.product()->front();
413  } else {
414  theMainVertex = *theClosestVertex;
415  }
416 
417  mainVtxPos.SetXYZ(theMainVertex.position().x(), theMainVertex.position().y(), theMainVertex.position().z());
418  const math::XYZPoint myVertex(
419  aTransientVertex.position().x(), aTransientVertex.position().y(), aTransientVertex.position().z());
420  const math::XYZPoint deltaVtx(
421  mainVtxPos.x() - myVertex.x(), mainVtxPos.y() - myVertex.y(), mainVtxPos.z() - myVertex.z());
422 
423 #ifdef EDM_ML_DEBUG
424  edm::LogVerbatim("DiMuonVertexValidation")
425  << "mm vertex position:" << aTransientVertex.position().x() << "," << aTransientVertex.position().y() << ","
426  << aTransientVertex.position().z();
427 
428  edm::LogVerbatim("DiMuonVertexValidation") << "main vertex position:" << theMainVertex.position().x() << ","
429  << theMainVertex.position().y() << "," << theMainVertex.position().z();
430 #endif
431 
432  if (theMainVertex.isValid()) {
433  // fill the impact parameter plots
434  for (const auto& track : myTracks) {
435  hdxy_->Fill(track->dxy(mainVtxPos) * cmToum);
436  hdz_->Fill(track->dz(mainVtxPos) * cmToum);
437  hdxyErr_->Fill(track->dxyError() * cmToum);
438  hdzErr_->Fill(track->dzError() * cmToum);
439 
440  const auto& ttrk = theB->build(track);
441  Global3DVector dir(track->px(), track->py(), track->pz());
442  const auto& ip2d = IPTools::signedTransverseImpactParameter(ttrk, dir, theMainVertex);
443  const auto& ip3d = IPTools::signedImpactParameter3D(ttrk, dir, theMainVertex);
444 
445  hIP2d_->Fill(ip2d.second.value() * cmToum);
446  hIP3d_->Fill(ip3d.second.value() * cmToum);
447  hIP2dsig_->Fill(ip2d.second.significance());
448  hIP3dsig_->Fill(ip3d.second.significance());
449  }
450 
451  LogDebug("DiMuonVertexValidation") << " after filling the IP histograms " << std::endl;
452 
453  // Z Vertex distance in the xy plane
454  VertexDistanceXY vertTool;
455  double distance = vertTool.distance(aTransientVertex, theMainVertex).value();
456  double dist_err = vertTool.distance(aTransientVertex, theMainVertex).error();
457  float compatibility = 0.;
458 
459  try {
460  compatibility = vertTool.compatibility(aTransientVertex, theMainVertex);
461  } catch (cms::Exception& er) {
462  LogTrace("DiMuonVertexValidation") << "caught std::exception " << er.what() << std::endl;
463  }
464 
465  hSVCompatibility_->Fill(compatibility);
466  hSVDist_->Fill(distance * cmToum);
467  hSVDistErr_->Fill(dist_err * cmToum);
468  hSVDistSig_->Fill(distance / dist_err);
469 
470  // fill the VtxDist plots
472 
473  // fill the VtxDisSig plots
474  VtxDistSigPlots.fillPlots(distance / dist_err, tktk_p4);
475 
476  // Z Vertex distance in 3D
477 
478  VertexDistance3D vertTool3D;
479  double distance3D = vertTool3D.distance(aTransientVertex, theMainVertex).value();
480  double dist3D_err = vertTool3D.distance(aTransientVertex, theMainVertex).error();
481  float compatibility3D = 0.;
482 
483  try {
484  compatibility3D = vertTool3D.compatibility(aTransientVertex, theMainVertex);
485  } catch (cms::Exception& er) {
486  LogTrace("DiMuonVertexMonitor") << "caught std::exception " << er.what() << std::endl;
487  }
488 
489  hSVCompatibility3D_->Fill(compatibility3D);
490  hSVDist3D_->Fill(distance3D * cmToum);
491  hSVDist3DErr_->Fill(dist3D_err * cmToum);
492  hSVDist3DSig_->Fill(distance3D / dist3D_err);
493 
494  // fill the VtxDist3D plots
495  VtxDist3DPlots.fillPlots(distance3D * cmToum, tktk_p4);
496 
497  // fill the VtxDisSig plots
498  VtxDist3DSigPlots.fillPlots(distance3D / dist3D_err, tktk_p4);
499 
500  LogDebug("DiMuonVertexValidation") << "distance: " << distance << "+/-" << dist_err << std::endl;
501  // cut on the PV - SV distance
502  if (distance * cmToum < maxSVdist_) {
504 
505  double cosphi = (ZpT.x() * deltaVtx.x() + ZpT.y() * deltaVtx.y()) /
506  (sqrt(ZpT.x() * ZpT.x() + ZpT.y() * ZpT.y()) *
507  sqrt(deltaVtx.x() * deltaVtx.x() + deltaVtx.y() * deltaVtx.y()));
508 
509  double cosphi3D = (Zp.x() * deltaVtx.x() + Zp.y() * deltaVtx.y() + Zp.z() * deltaVtx.z()) /
510  (sqrt(Zp.x() * Zp.x() + Zp.y() * Zp.y() + Zp.z() * Zp.z()) *
511  sqrt(deltaVtx.x() * deltaVtx.x() + deltaVtx.y() * deltaVtx.y() + deltaVtx.z() * deltaVtx.z()));
512 
513  LogDebug("DiMuonVertexValidation") << "cos(phi) = " << cosphi << std::endl;
514 
515  hCosPhi_->Fill(cosphi);
516  hCosPhi3D_->Fill(cosphi3D);
517 
518 #ifdef EDM_ML_DEBUG
519  edm::LogVerbatim("DiMuonVertexValidation")
520  << "distance " << distance * cmToum << " cosphi3D:" << cosphi3D << std::endl;
521 #endif
522 
523  // unbalance
524  hCosPhiUnbalance_->Fill(cosphi, 1.);
525  hCosPhiUnbalance_->Fill(-cosphi, -1.);
526  hCosPhi3DUnbalance_->Fill(cosphi3D, 1.);
527  hCosPhi3DUnbalance_->Fill(-cosphi3D, -1.);
528 
529  // fill the cosphi plots
530  CosPhiPlots.fillPlots(cosphi, tktk_p4);
531 
532  // fill the cosphi3D plots
533  CosPhi3DPlots.fillPlots(cosphi3D, tktk_p4);
534 
535  // fill the cosphi3D plots in eta bins
536  CosPhi3DInEtaBins.fillTH1Plots(cosphi3D, tktk_p4);
537  }
538  }
539 }
540 
541 // ------------ method called once each job just before starting event loop ------------
544 
545  // clang-format off
546  TH1F::SetDefaultSumw2(kTRUE);
547  hSVProb_ = fs->make<TH1F>("VtxProb", ";#mu^{+}#mu^{-} vertex probability;N(#mu#mu pairs)", 100, 0., 1.);
548 
549  auto extractRangeValues = [](const edm::ParameterSet& PSetConfiguration_) -> std::pair<double, double> {
550  double min = PSetConfiguration_.getParameter<double>("ymin");
551  double max = PSetConfiguration_.getParameter<double>("ymax");
552  return {min, max};
553  };
554 
555  std::string ts = fmt::sprintf(";%s vertex probability;N(#mu#mu pairs)", motherName_);
556  std::string ps = "N(#mu#mu pairs)";
557  ts = fmt::sprintf("#chi^{2} of the %s vertex; #chi^{2} of the %s vertex; %s", motherName_, motherName_, ps);
558  hSVChi2_ = fs->make<TH1F>("VtxChi2", ts.c_str(), 200, 0., 200.);
559 
560  ts = fmt::sprintf("#chi^{2}/ndf of the %s vertex; #chi^{2}/ndf of %s vertex; %s", motherName_, motherName_, ps);
561  hSVNormChi2_ = fs->make<TH1F>("VtxNormChi2", ts.c_str(), 100, 0., 20.);
562 
563  // take the range from the 2D histograms
564  const auto& svDistRng = extractRangeValues(VtxDistConfiguration_);
565  hSVDist_ = fs->make<TH1F>("VtxDist", ";PV-#mu^{+}#mu^{-} vertex xy distance [#mum];N(#mu#mu pairs)", 100, svDistRng.first, svDistRng.second);
566 
567  std::string histTit = motherName_ + " #rightarrow #mu^{+}#mu^{-}";
568  ts = fmt::sprintf("%s;PV-%sV xy distance error [#mum];%s", histTit, motherName_, ps);
569  hSVDistErr_ = fs->make<TH1F>("VtxDistErr", ts.c_str(), 100, 0., 1000.);
570 
571  // take the range from the 2D histograms
572  const auto& svDistSigRng = extractRangeValues(VtxDistSigConfiguration_);
573  hSVDistSig_ = fs->make<TH1F>("VtxDistSig", ";PV-#mu^{+}#mu^{-} vertex xy distance signficance;N(#mu#mu pairs)", 100, svDistSigRng.first, svDistSigRng.second);
574 
575  // take the range from the 2D histograms
576  const auto& svDist3DRng = extractRangeValues(VtxDist3DConfiguration_);
577  hSVDist3D_ = fs->make<TH1F>("VtxDist3D", ";PV-#mu^{+}#mu^{-} vertex 3D distance [#mum];N(#mu#mu pairs)", 100, svDist3DRng.first, svDist3DRng.second);
578 
579  ts = fmt::sprintf("%s;PV-%sV 3D distance error [#mum];%s", histTit, motherName_, ps);
580  hSVDist3DErr_ = fs->make<TH1F>("VtxDist3DErr", ts.c_str(), 100, 0., 1000.);
581 
582  // take the range from the 2D histograms
583  const auto& svDist3DSigRng = extractRangeValues(VtxDist3DSigConfiguration_);
584  hSVDist3DSig_ = fs->make<TH1F>("VtxDist3DSig", ";PV-#mu^{+}#mu^{-} vertex 3D distance signficance;N(#mu#mu pairs)", 100, svDist3DSigRng.first, svDist3DSigRng.second);
585 
586  ts = fmt::sprintf("compatibility of %s vertex; compatibility of %s vertex; %s", motherName_, motherName_, ps);
587  hSVCompatibility_ = fs->make<TH1F>("VtxCompatibility", ts.c_str(), 100, 0., 100.);
588 
589  ts = fmt::sprintf("3D compatibility of %s vertex;3D compatibility of %s vertex; %s", motherName_, motherName_, ps);
590  hSVCompatibility3D_ = fs->make<TH1F>("VtxCompatibility3D", ts.c_str(), 100, 0., 100.);
591 
592  // take the range from the 2D histograms
593  const auto& massRng = extractRangeValues(DiMuMassConfiguration_);
594  hInvMass_ = fs->make<TH1F>("InvMass", ";M(#mu#mu) [GeV];N(#mu#mu pairs)", 70., massRng.first, massRng.second);
595  hTrackInvMass_ = fs->make<TH1F>("TkTkInvMass", ";M(tk,tk) [GeV];N(tk tk pairs)", 70., massRng.first, massRng.second);
596 
597  hCosPhi_ = fs->make<TH1F>("CosPhi", ";cos(#phi_{xy});N(#mu#mu pairs)", 50, -1., 1.);
598  hCosPhi3D_ = fs->make<TH1F>("CosPhi3D", ";cos(#phi_{3D});N(#mu#mu pairs)", 50, -1., 1.);
599 
600  hCosPhiInv_ = fs->make<TH1F>("CosPhiInv", ";inverted cos(#phi_{xy});N(#mu#mu pairs)", 50, -1., 1.);
601  hCosPhiInv3D_ = fs->make<TH1F>("CosPhiInv3D", ";inverted cos(#phi_{3D});N(#mu#mu pairs)", 50, -1., 1.);
602 
603  hCosPhiUnbalance_ = fs->make<TH1F>("CosPhiUnbalance", fmt::sprintf("%s;cos(#phi_{xy}) unbalance;#Delta%s", histTit, ps).c_str(), 50, -1.,1.);
604  hCosPhi3DUnbalance_ = fs->make<TH1F>("CosPhi3DUnbalance", fmt::sprintf("%s;cos(#phi_{3D}) unbalance;#Delta%s", histTit, ps).c_str(), 50, -1., 1.);
605 
606  hdxy_ = fs->make<TH1F>("dxy", fmt::sprintf("%s;muon track d_{xy}(PV) [#mum];muon tracks", histTit).c_str(), 150, -300, 300);
607  hdz_ = fs->make<TH1F>("dz", fmt::sprintf("%s;muon track d_{z}(PV) [#mum];muon tracks", histTit).c_str(), 150, -300, 300);
608  hdxyErr_ = fs->make<TH1F>("dxyErr", fmt::sprintf("%s;muon track err_{dxy} [#mum];muon tracks", histTit).c_str(), 250, 0., 500.);
609  hdzErr_ = fs->make<TH1F>("dzErr", fmt::sprintf("%s;muon track err_{dz} [#mum];muon tracks", histTit).c_str(), 250, 0., 500.);
610  hIP2d_ = fs->make<TH1F>("IP2d", fmt::sprintf("%s;muon track IP_{2D} [#mum];muon tracks", histTit).c_str(), 150, -300, 300);
611  hIP3d_ = fs->make<TH1F>("IP3d", fmt::sprintf("%s;muon track IP_{3D} [#mum];muon tracks", histTit).c_str(), 150, -300, 300);
612  hIP2dsig_ = fs->make<TH1F>("IP2Dsig", fmt::sprintf("%s;muon track IP_{2D} significance;muon tracks", histTit).c_str(), 100, 0., 5.);
613  hIP3dsig_ = fs->make<TH1F>("IP3Dsig", fmt::sprintf("%s;muon track IP_{3D} significance;muon tracks", histTit).c_str(), 100, 0., 5.);
614  // clang-format on
615 
616  // 2D Maps
617 
618  TFileDirectory dirCosPhi = fs->mkdir("CosPhiPlots");
620 
621  TFileDirectory dirCosPhi3D = fs->mkdir("CosPhi3DPlots");
623 
624  TFileDirectory dirVtxProb = fs->mkdir("VtxProbPlots");
626 
627  TFileDirectory dirVtxDist = fs->mkdir("VtxDistPlots");
629 
630  TFileDirectory dirVtxDist3D = fs->mkdir("VtxDist3DPlots");
632 
633  TFileDirectory dirVtxDistSig = fs->mkdir("VtxDistSigPlots");
635 
636  TFileDirectory dirVtxDist3DSig = fs->mkdir("VtxDist3DSigPlots");
638 
639  TFileDirectory dirInvariantMass = fs->mkdir("InvariantMassPlots");
641 
642  // CosPhi3D in eta bins
643  TFileDirectory dirCosphi3DEta = fs->mkdir("CosPhi3DInEtaBins");
644  CosPhi3DInEtaBins.bookSet(dirCosphi3DEta, hCosPhi3D_);
645 
646  // Z-> mm mass in eta bins
647  TFileDirectory dirResMassEta = fs->mkdir("TkTkMassInEtaBins");
648  InvMassInEtaBins.bookSet(dirResMassEta, hTrackInvMass_);
649 
650  // cut flow
651 
652  hCutFlow_ = fs->make<TH1F>("hCutFlow", "cut flow;cut step;events left", 6, -0.5, 5.5);
653  std::string names[6] = {"Total", "Mult.", ">pT", "<eta", "hasVtx", "VtxDist"};
654  for (unsigned int i = 0; i < 6; i++) {
655  hCutFlow_->GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
656  }
657 
658  myCounts.zeroAll();
659 }
660 
661 // ------------ method called once each job just after ending the event loop ------------
664 
665  hCutFlow_->SetBinContent(1, myCounts.eventsTotal);
666  hCutFlow_->SetBinContent(2, myCounts.eventsAfterMult);
667  hCutFlow_->SetBinContent(3, myCounts.eventsAfterPt);
668  hCutFlow_->SetBinContent(4, myCounts.eventsAfterEta);
669  hCutFlow_->SetBinContent(5, myCounts.eventsAfterVtx);
670  hCutFlow_->SetBinContent(6, myCounts.eventsAfterDist);
671 
672  TH1F::SetDefaultSumw2(kTRUE);
673  const unsigned int nBinsX = hCosPhi_->GetNbinsX();
674  for (unsigned int i = 1; i <= nBinsX; i++) {
675  //float binContent = hCosPhi_->GetBinContent(i);
676  float invertedBinContent = hCosPhi_->GetBinContent(nBinsX + 1 - i);
677  float invertedBinError = hCosPhi_->GetBinError(nBinsX + 1 - i);
678  hCosPhiInv_->SetBinContent(i, invertedBinContent);
679  hCosPhiInv_->SetBinError(i, invertedBinError);
680 
681  //float binContent3D = hCosPhi3D_->GetBinContent(i);
682  float invertedBinContent3D = hCosPhi3D_->GetBinContent(nBinsX + 1 - i);
683  float invertedBinError3D = hCosPhi3D_->GetBinError(nBinsX + 1 - i);
684  hCosPhiInv3D_->SetBinContent(i, invertedBinContent3D);
685  hCosPhiInv3D_->SetBinError(i, invertedBinError3D);
686  }
687 }
688 
689 // compute the closest vertex to di-lepton ------------------------------------
691  const reco::VertexCollection* vertices) const {
692  reco::Vertex* defaultVtx = nullptr;
693 
694  if (!aTransVtx.isValid())
695  return defaultVtx;
696 
697  // find the closest vertex to the secondary vertex in 3D
698  VertexDistance3D vertTool3D;
699  float minD = 9999.;
700  int closestVtxIndex = 0;
701  int counter = 0;
702  for (const auto& vtx : *vertices) {
703  double dist3D = vertTool3D.distance(aTransVtx, vtx).value();
704  if (dist3D < minD) {
705  minD = dist3D;
706  closestVtxIndex = counter;
707  }
708  counter++;
709  }
710 
711  if ((*vertices).at(closestVtxIndex).isValid()) {
712  return &(vertices->at(closestVtxIndex));
713  } else {
714  return defaultVtx;
715  }
716 }
717 
718 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
721  desc.ifValue(edm::ParameterDescription<bool>("useReco", true, true),
722  true >> edm::ParameterDescription<edm::InputTag>("muons", edm::InputTag("muons"), true) or
724  "muonTracks", edm::InputTag("ALCARECOTkAlDiMuon"), true))
725  ->setComment("If useReco is true need to specify the muon tracks, otherwise take the ALCARECO Inner tracks");
726  //desc.add<bool>("useReco",true);
727  //desc.add<edm::InputTag>("muons", edm::InputTag("muons"));
728  //desc.add<edm::InputTag>("muonTracks", edm::InputTag("ALCARECOTkAlDiMuon"));
729  desc.add<std::string>("decayMotherName", "Z");
730  desc.add<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
731  desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
732  desc.add<std::vector<double>>("pTThresholds", {30., 10.});
733  desc.add<bool>("useClosestVertex", true);
734  desc.add<double>("maxSVdist", 50.);
735 
736  {
737  edm::ParameterSetDescription psDiMuMass;
738  psDiMuMass.add<std::string>("name", "DiMuMass");
739  psDiMuMass.add<std::string>("title", "M(#mu#mu)");
740  psDiMuMass.add<std::string>("yUnits", "[GeV]");
741  psDiMuMass.add<int>("NxBins", 24);
742  psDiMuMass.add<int>("NyBins", 50);
743  psDiMuMass.add<double>("ymin", 70.);
744  psDiMuMass.add<double>("ymax", 120.);
745  desc.add<edm::ParameterSetDescription>("DiMuMassConfig", psDiMuMass);
746  }
747  {
749  psCosPhi.add<std::string>("name", "CosPhi");
750  psCosPhi.add<std::string>("title", "cos(#phi_{xy})");
751  psCosPhi.add<std::string>("yUnits", "");
752  psCosPhi.add<int>("NxBins", 50);
753  psCosPhi.add<int>("NyBins", 50);
754  psCosPhi.add<double>("ymin", -1.);
755  psCosPhi.add<double>("ymax", 1.);
756  desc.add<edm::ParameterSetDescription>("CosPhiConfig", psCosPhi);
757  }
758  {
759  edm::ParameterSetDescription psCosPhi3D;
760  psCosPhi3D.add<std::string>("name", "CosPhi3D");
761  psCosPhi3D.add<std::string>("title", "cos(#phi_{3D})");
762  psCosPhi3D.add<std::string>("yUnits", "");
763  psCosPhi3D.add<int>("NxBins", 50);
764  psCosPhi3D.add<int>("NyBins", 50);
765  psCosPhi3D.add<double>("ymin", -1.);
766  psCosPhi3D.add<double>("ymax", 1.);
767  desc.add<edm::ParameterSetDescription>("CosPhi3DConfig", psCosPhi3D);
768  }
769  {
771  psVtxProb.add<std::string>("name", "VtxProb");
772  psVtxProb.add<std::string>("title", "Prob(#chi^{2}_{SV})");
773  psVtxProb.add<std::string>("yUnits", "");
774  psVtxProb.add<int>("NxBins", 50);
775  psVtxProb.add<int>("NyBins", 50);
776  psVtxProb.add<double>("ymin", 0);
777  psVtxProb.add<double>("ymax", 1.);
778  desc.add<edm::ParameterSetDescription>("VtxProbConfig", psVtxProb);
779  }
780  {
782  psVtxDist.add<std::string>("name", "VtxDist");
783  psVtxDist.add<std::string>("title", "d_{xy}(PV,SV)");
784  psVtxDist.add<std::string>("yUnits", "[#mum]");
785  psVtxDist.add<int>("NxBins", 50);
786  psVtxDist.add<int>("NyBins", 100);
787  psVtxDist.add<double>("ymin", 0);
788  psVtxDist.add<double>("ymax", 300.);
789  desc.add<edm::ParameterSetDescription>("VtxDistConfig", psVtxDist);
790  }
791  {
792  edm::ParameterSetDescription psVtxDist3D;
793  psVtxDist3D.add<std::string>("name", "VtxDist3D");
794  psVtxDist3D.add<std::string>("title", "d_{3D}(PV,SV)");
795  psVtxDist3D.add<std::string>("yUnits", "[#mum]");
796  psVtxDist3D.add<int>("NxBins", 50);
797  psVtxDist3D.add<int>("NyBins", 250);
798  psVtxDist3D.add<double>("ymin", 0);
799  psVtxDist3D.add<double>("ymax", 500.);
800  desc.add<edm::ParameterSetDescription>("VtxDist3DConfig", psVtxDist3D);
801  }
802  {
803  edm::ParameterSetDescription psVtxDistSig;
804  psVtxDistSig.add<std::string>("name", "VtxDistSig");
805  psVtxDistSig.add<std::string>("title", "d_{xy}(PV,SV)/#sigma_{dxy}(PV,SV)");
806  psVtxDistSig.add<std::string>("yUnits", "");
807  psVtxDistSig.add<int>("NxBins", 50);
808  psVtxDistSig.add<int>("NyBins", 100);
809  psVtxDistSig.add<double>("ymin", 0);
810  psVtxDistSig.add<double>("ymax", 5.);
811  desc.add<edm::ParameterSetDescription>("VtxDistSigConfig", psVtxDistSig);
812  }
813  {
814  edm::ParameterSetDescription psVtxDist3DSig;
815  psVtxDist3DSig.add<std::string>("name", "VtxDist3DSig");
816  psVtxDist3DSig.add<std::string>("title", "d_{3D}(PV,SV)/#sigma_{d3D}(PV,SV)");
817  psVtxDist3DSig.add<std::string>("yUnits", "");
818  psVtxDist3DSig.add<int>("NxBins", 50);
819  psVtxDist3DSig.add<int>("NyBins", 100);
820  psVtxDist3DSig.add<double>("ymin", 0);
821  psVtxDist3DSig.add<double>("ymax", 5.);
822  desc.add<edm::ParameterSetDescription>("VtxDist3DSigConfig", psVtxDist3DSig);
823  }
824 
825  descriptions.addWithDefaultLabel(desc);
826 }
827 
828 //define this as a plug-in
DiMuonVertexValidation(const edm::ParameterSet &)
static const std::string kSharedResource
Definition: TFileService.h:76
const edm::ParameterSet VtxProbConfiguration_
Log< level::Info, true > LogVerbatim
const edm::ParameterSet DiMuMassConfiguration_
~DiMuonVertexValidation() override
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
float totalChiSquared() const
const edm::ParameterSet CosPhi3DConfiguration_
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
double pt() const final
transverse momentum
GlobalPoint position() const
Measurement1D distance(const GlobalPoint &vtx1Position, const GlobalError &vtx1PositionError, const GlobalPoint &vtx2Position, const GlobalError &vtx2PositionError) const override
DiLeptonHelp::Counts myCounts
const edm::ParameterSet CosPhiConfiguration_
T z() const
Definition: PV3DBase.h:61
void analyze(const edm::Event &, const edm::EventSetup &) override
DiLeptonHelp::PlotsVsDiLeptonRegion InvMassInEtaBins
static constexpr float mumass2
const Point & position() const
position
Definition: Vertex.h:128
void fillTH1Plots(const float val, const std::pair< TLorentzVector, TLorentzVector > &momenta)
std::pair< bool, Measurement1D > signedTransverseImpactParameter(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:57
T const * product() const
Definition: Handle.h:70
DiLeptonHelp::PlotsVsKinematics CosPhiPlots
const edm::ParameterSet VtxDist3DConfiguration_
std::pair< bool, Measurement1D > signedImpactParameter3D(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:81
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
DiLeptonHelp::PlotsVsKinematics VtxDist3DPlots
Log< level::Error, false > LogError
const edm::ParameterSet VtxDist3DSigConfiguration_
std::vector< Vertex > VertexCollection
Definition: Vertex.h:31
float degreesOfFreedom() const
const std::string names[nVars_]
DiLeptonHelp::PlotsVsKinematics VtxDist3DSigPlots
static std::string to_string(const XMLCh *ch)
#define LogTrace(id)
CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &tracks) const override
reco::TransientTrack build(const reco::Track *p) const
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
int iEvent
Definition: GenABIO.cc:224
void bookSet(const TFileDirectory &fs, const TH1 *histo)
bool isValid() const
T sqrt(T t)
Definition: SSEVec.h:19
const edm::ParameterSet VtxDistSigConfiguration_
DiLeptonHelp::PlotsVsKinematics VtxDistSigPlots
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
static constexpr float cmToum
edm::EDGetTokenT< reco::MuonCollection > muonsToken_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > ttbESToken_
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Measurement1D distance(const GlobalPoint &vtx1Position, const GlobalError &vtx1PositionError, const GlobalPoint &vtx2Position, const GlobalError &vtx2PositionError) const override
Log< level::Info, false > LogInfo
std::pair< float, float > massLimits_
edm::EDGetTokenT< reco::TrackCollection > tracksToken_
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
DiLeptonHelp::PlotsVsKinematics VtxProbPlots
bool isValid() const
Definition: HandleBase.h:70
double value() const
Definition: Measurement1D.h:25
float compatibility(const GlobalPoint &vtx1Position, const GlobalError &vtx1PositionError, const GlobalPoint &vtx2Position, const GlobalError &vtx2PositionError) const override
const edm::ParameterSet VtxDistConfiguration_
const reco::Vertex * findClosestVertex(const TransientVertex aTransVtx, const reco::VertexCollection *vertices) const
DiLeptonHelp::PlotsVsKinematics CosPhi3DPlots
fixed size matrix
HLT enums.
static std::atomic< unsigned int > counter
double error() const
Definition: Measurement1D.h:27
std::vector< double > pTthresholds_
DiLeptonHelp::PlotsVsKinematics VtxDistPlots
void fillPlots(const float val, const std::pair< TLorentzVector, TLorentzVector > &momenta)
void bookFromPSet(const TFileDirectory &fs, const edm::ParameterSet &hpar)
Log< level::Warning, false > LogWarning
char const * what() const noexcept override
Definition: Exception.cc:107
DiLeptonHelp::PlotsVsDiLeptonRegion CosPhi3DInEtaBins
DiLeptonHelp::PlotsVsKinematics ZMassPlots
edm::EDGetTokenT< reco::TrackCollection > alcaRecoToken_
const edm::EDGetTokenT< reco::VertexCollection > vertexToken_
bool isValid() const
Tells whether the vertex is valid.
Definition: Vertex.h:73
#define LogDebug(id)
float compatibility(const GlobalPoint &vtx1Position, const GlobalError &vtx1PositionError, const GlobalPoint &vtx2Position, const GlobalError &vtx2PositionError) const override