CMS 3D CMS Logo

SagittaBiasNtuplizer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Alignment/OfflineValidation
4 // Class: SagittaBiasNtuplizer
5 //
6 /*
7  *\class SagittaBiasNtuplizer SagittaBiasNtuplizer.cc Alignment/OfflineValidation/plugins/SagittaBiasNtuplizer.cc
8 
9  Description: This module is meant to create a simple ntuple to be able to validate the tracker alignment for the presence of Sagitta Bias.
10 
11  Implementation: the implementation is straightforward.
12 
13 */
14 //
15 // Original Author: Marco Musich, C. Alexe
16 // Created: Fri, 05 Jan 2023 11:41:00 GMT
17 //
18 //
19 
38 
39 #include "TH1F.h"
40 #include "TH2I.h"
41 #include "TTree.h"
42 #include "TLorentzVector.h"
43 
44 class SagittaBiasNtuplizer : public edm::one::EDAnalyzer<edm::one::SharedResources> {
45 public:
46  explicit SagittaBiasNtuplizer(const edm::ParameterSet&);
47  ~SagittaBiasNtuplizer() override = default;
48 
49  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
50 
51 private:
52  void analyze(const edm::Event& event, const edm::EventSetup& setup) override;
53  double openingAngle(const reco::Track* track1, const reco::Track* track2);
54  std::pair<unsigned int, reco::Vertex> findClosestVertex(const reco::Track* track1,
56  const bool useReco_;
57  const bool doGen_;
58 
59  const double muonEtaCut_;
60  const double muonPtCut_;
61  const double muondxySigCut_;
62  const double minMassWindowCut_;
63  const double maxMassWindowCut_;
64  const double d0CompatibilityCut_;
65  const double z0CompatibilityCut_;
66 
67  std::vector<double> pTthresholds_;
68 
69  // either on or the other!
70  //used to select what muon tracks to read from configuration file
72  //used to select what tracks to read from configuration file
74 
75  //used to select what tracks to read from configuration file
77 
78  // for associated genParticles
80  //edm::EDGetTokenT<std::vector<reco::GenParticle>> genParticlesToken_;
81 
84 
85  static double constexpr muMass = 0.1056583745;
86 
87  TTree* tree_;
88  float mass_;
89  float posTrackDz_;
90  float negTrackDz_;
91  float posTrackD0_;
92  float negTrackD0_;
93  float posTrackEta_;
94  float negTrackEta_;
95  float posTrackPhi_;
96  float negTrackPhi_;
97  float posTrackPt_;
98  float negTrackPt_;
99 
100  // for the gen-level info
111 
112  // control histograms
114  TH1F* h_cutFlow;
115  TH1F* h_DeltaD0;
116  TH1F* h_DeltaDz;
118 };
119 
120 //_________________________________________________________________________________
122  : useReco_(iConfig.getParameter<bool>("useReco")),
123  doGen_(iConfig.getParameter<bool>("doGen")),
124  muonEtaCut_(iConfig.getParameter<double>("muonEtaCut")),
125  muonPtCut_(iConfig.getParameter<double>("muonPtCut")),
126  muondxySigCut_(iConfig.getParameter<double>("muondxySigCut")),
127  minMassWindowCut_(iConfig.getParameter<double>("minMassWindowCut")),
128  maxMassWindowCut_(iConfig.getParameter<double>("maxMassWindowCut")),
129  d0CompatibilityCut_(iConfig.getParameter<double>("d0CompatibilityCut")),
130  z0CompatibilityCut_(iConfig.getParameter<double>("z0CompatibilityCut")),
131  pTthresholds_(iConfig.getParameter<std::vector<double>>("pTThresholds")),
132  vtxToken_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))),
133  bsToken_(consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamSpot"))),
134  mass_{0},
135  posTrackDz_{0},
136  negTrackDz_{0},
137  posTrackD0_{0},
138  negTrackD0_{0},
139  posTrackEta_{0},
140  negTrackEta_{0},
141  posTrackPhi_{0},
142  negTrackPhi_{0},
143  posTrackPt_{0},
144  negTrackPt_{0},
145  genPosMuonEta_{-99.},
146  genNegMuonEta_{-99.},
147  genPosMuonPhi_{-99.},
148  genNegMuonPhi_{-99.},
149  genPosMuonPt_{-99.},
150  genNegMuonPt_{-99.} {
151  if (useReco_) {
152  tracksToken_ = mayConsume<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("tracks"));
153  muonsToken_ = mayConsume<reco::MuonCollection>(iConfig.getParameter<edm::InputTag>("muons"));
154  } else {
155  alcaRecoToken_ = mayConsume<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("muonTracks"));
156  }
157 
158  if (doGen_) {
159  genParticlesToken_ = consumes<edm::View<reco::Candidate>>(iConfig.getParameter<edm::InputTag>("genParticles"));
160  }
161 
162  usesResource(TFileService::kSharedResource);
163 
164  // sort the vector of thresholds
165  std::sort(pTthresholds_.begin(), pTthresholds_.end(), [](const double& lhs, const double& rhs) { return lhs > rhs; });
166 
167  edm::LogInfo("SagittaBiasNtuplizer") << __FUNCTION__;
168  for (const auto& thr : pTthresholds_) {
169  edm::LogInfo("SagittaBiasNtuplizer") << " Threshold: " << thr << " ";
170  }
171 
173  h_cutFlow = fs->make<TH1F>("cutFlow", "cutFlow;cut;remaining events", 9, -0.5, 8.5);
174  std::string labels[9] = {"all events",
175  "common vertex",
176  "d0 cut",
177  "p_{T} cut",
178  "#eta cut",
179  "mass window",
180  "#delta d_{0}",
181  "#delta d_{z}",
182  "opening angle"};
183  unsigned int count{0};
184  for (const auto& label : labels) {
185  count++;
186  h_cutFlow->GetXaxis()->SetBinLabel(count, label.c_str());
187  }
188 
189  h_VertexMatrix = fs->make<TH2I>("VertexMatrix",
190  ";index of closest vertex to #mu_{0};index of closest vertex to #mu_{1}",
191  100,
192  0,
193  100,
194  100,
195  0,
196  100);
197  h_DeltaD0 = fs->make<TH1F>("DeltaD0", "#Deltad_{0};#Deltad_{0} [cm];events", 100, -0.5, 0.5);
198  h_DeltaDz = fs->make<TH1F>("DeltaDz", "#Deltad_{z};#Deltad_{z} [cm];events", 100, -1, 1);
199  h_CosOpeningAngle = fs->make<TH1F>("OpeningAngle", "cos(#gamma(#mu^{+},#mu^{-}));events", 100, -1., 1.);
200 
201  tree_ = fs->make<TTree>("tree", "My TTree");
202  tree_->Branch("mass", &mass_, "mass/F");
203  tree_->Branch("posTrackDz", &posTrackDz_, "posTrackDz/F");
204  tree_->Branch("negTrackDz", &negTrackDz_, "negTrackDz/F");
205  tree_->Branch("posTrackD0", &posTrackD0_, "posTrackD0/F");
206  tree_->Branch("negTrackD0", &negTrackD0_, "negTrackD0/F");
207  tree_->Branch("posTrackEta", &posTrackEta_, "posTrackEta/F");
208  tree_->Branch("negTrackEta", &negTrackEta_, "negTrackEta/F");
209  tree_->Branch("posTrackPhi", &posTrackPhi_, "posTrackPhi/F");
210  tree_->Branch("negTrackPhi", &negTrackPhi_, "negTrackPhi/F");
211  tree_->Branch("posTrackPt", &posTrackPt_, "posTrackPt/F");
212  tree_->Branch("negTrackPt", &negTrackPt_, "negTrackPt/F");
213 
214  if (doGen_) {
215  tree_->Branch("genPosMuonDz", &genPosMuonDz_, "genPosMuonDz/F");
216  tree_->Branch("genNegMuonDz", &genNegMuonDz_, "genNegMuonDz/F");
217  tree_->Branch("genPosMuonD0", &genPosMuonD0_, "genPosMuonD0/F");
218  tree_->Branch("genNegMuonD0", &genNegMuonD0_, "genNegMuonD0/F");
219  tree_->Branch("genPosMuonEta", &genPosMuonEta_, "genPosMuonEta/F");
220  tree_->Branch("genNegMuonEta", &genNegMuonEta_, "genNegMuonEta/F");
221  tree_->Branch("genPosMuonPhi", &genPosMuonPhi_, "genPosMuonPhi/F");
222  tree_->Branch("genNegMuonPhi", &genNegMuonPhi_, "genNegMuonPhi/F");
223  tree_->Branch("genPosMuonPt", &genPosMuonPt_, "genPosMuonPt/F");
224  tree_->Branch("genNegMuonPt", &genNegMuonPt_, "genNegMuonPt/F");
225  }
226 }
227 
228 //_________________________________________________________________________________
231  desc.ifValue(
232  edm::ParameterDescription<bool>("useReco", true, true),
233  true >> edm::ParameterDescription<edm::InputTag>("muons", edm::InputTag("muons"), true) or
234  false >> edm::ParameterDescription<edm::InputTag>("muonTracks", edm::InputTag("ALCARECOTkAlZMuMu"), true))
235  ->setComment("If useReco is true need to specify the muon tracks, otherwise take the ALCARECO Inner tracks");
236  desc.add<bool>("doGen", false);
237  desc.add<edm::InputTag>("genParticles", edm::InputTag("genParticles"));
238  desc.add<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
239  desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
240  desc.add<edm::InputTag>("beamSpot", edm::InputTag("offlineBeamSpot"));
241  desc.add<double>("muonEtaCut", 2.5)->setComment("muon system acceptance");
242  desc.add<double>("muonPtCut", 12.)->setComment("in GeV");
243  desc.add<double>("muondxySigCut", 4.)->setComment("significance of the d0 compatibility with closest vertex");
244  desc.add<double>("minMassWindowCut", 70.)->setComment("in GeV");
245  desc.add<double>("maxMassWindowCut", 110.)->setComment("in GeV");
246  desc.add<double>("d0CompatibilityCut", 0.01)->setComment("d0 compatibility between the two muons");
247  desc.add<double>("z0CompatibilityCut", 0.06)->setComment("z0 compatibility between the two muons");
248  desc.add<std::vector<double>>("pTThresholds", {30., 10.});
249  descriptions.addWithDefaultLabel(desc);
250 }
251 
252 //_________________________________________________________________________________
254  h_cutFlow->Fill(0);
255 
256  // the di-muon tracks
257  std::vector<const reco::Track*> myTracks;
258 
259  // if we have to start from scratch from RECO data-tier
260  if (useReco_) {
261  // select the good muons
262  std::vector<const reco::Muon*> myGoodMuonVector;
263  for (const auto& muon : event.get(muonsToken_)) {
264  const reco::TrackRef t = muon.innerTrack();
265  if (!t.isNull()) {
266  if (t->quality(reco::TrackBase::highPurity)) {
267  if (t->chi2() / t->ndof() <= 2.5 && t->numberOfValidHits() >= 5 &&
268  t->hitPattern().numberOfValidPixelHits() >= 2 && t->quality(reco::TrackBase::highPurity))
269  myGoodMuonVector.emplace_back(&muon);
270  }
271  }
272  }
273 
274  LogDebug("SagittaBiasNtuplizer") << "myGoodMuonVector size: " << myGoodMuonVector.size() << std::endl;
275  std::sort(myGoodMuonVector.begin(), myGoodMuonVector.end(), [](const reco::Muon*& lhs, const reco::Muon*& rhs) {
276  return lhs->pt() > rhs->pt();
277  });
278 
279  // just check the ordering
280  for (const auto& muon : myGoodMuonVector) {
281  LogDebug("SagittaBiasNtuplizer") << "pT: " << muon->pt() << " ";
282  }
283  LogDebug("SagittaBiasNtuplizer") << std::endl;
284 
285  // reject if there's no Z
286  if (myGoodMuonVector.size() < 2)
287  return;
288 
289  if ((myGoodMuonVector[0]->pt()) < pTthresholds_[0] || (myGoodMuonVector[1]->pt() < pTthresholds_[1]))
290  return;
291 
292  if (myGoodMuonVector[0]->charge() * myGoodMuonVector[1]->charge() > 0)
293  return;
294 
295  //const auto& m1 = myGoodMuonVector[1]->p4();
296  //const auto& m0 = myGoodMuonVector[0]->p4();
297  //const auto& mother = m0 + m1;
298 
299  // just copy the top two muons
300  std::vector<const reco::Muon*> theZMuonVector;
301  theZMuonVector.reserve(2);
302  theZMuonVector.emplace_back(myGoodMuonVector[1]);
303  theZMuonVector.emplace_back(myGoodMuonVector[0]);
304 
305  // do the matching of Z muons with inner tracks
306  unsigned int i = 0;
307  for (const auto& muon : theZMuonVector) {
308  i++;
309  float minD = 1e6;
310  const reco::Track* theMatch = nullptr;
311  for (const auto& track : event.get(tracksToken_)) {
312  float D = ::deltaR2(muon->eta(), muon->phi(), track.eta(), track.phi());
313  if (D < minD) {
314  minD = D;
315  theMatch = &track;
316  }
317  }
318  LogDebug("SagittaBiasNtuplizer") << "pushing new track: " << i << std::endl;
319  myTracks.emplace_back(theMatch);
320  }
321  } else {
322  // we start directly with the pre-selected ALCARECO tracks
323  for (const auto& muon : event.get(alcaRecoToken_)) {
324  myTracks.emplace_back(&muon);
325  }
326  }
327 
328  const reco::VertexCollection& vertices = event.get(vtxToken_);
329  const reco::BeamSpot& beamSpot = event.get(bsToken_);
330  math::XYZPoint bs(beamSpot.x0(), beamSpot.y0(), beamSpot.z0());
331 
332  //edm::LogPrint("SagittaBiasNtuplizer") << " track size:" << myTracks.size() << " vertex size:" << vertices.size() << std::endl;
333 
334  if ((myTracks.size() != 2)) {
335  LogTrace("SagittaBiasNtuplizer") << "Found " << myTracks.size() << " muons in the event. Skipping";
336  return;
337  }
338 
339  bool passSameVertex{true};
340  bool passD0sigCut{true};
341  bool passPtCut{true};
342  bool passEtaCut{true};
343  bool passMassWindow{true};
344  bool passDeltaD0{true};
345  bool passDeltaDz{true};
346  bool passOpeningAngle{true};
347  double d0[2] = {0., 0.};
348  double dz[2] = {0., 0.};
349  unsigned int vtxIndex[2] = {999, 999};
350 
351  unsigned int i = 0;
352  for (const auto& track : myTracks) {
353  if (track->pt() < muonPtCut_) {
354  passPtCut = false;
355  continue;
356  }
357 
358  if (std::abs(track->eta()) > muonEtaCut_) {
359  passEtaCut = false;
360  continue;
361  }
362 
363  const auto& closestVertex = this->findClosestVertex(track, vertices);
364  vtxIndex[i] = closestVertex.first;
365  d0[i] = track->dxy(closestVertex.second.position());
366  dz[i] = track->dz(closestVertex.second.position());
367 
368  if (d0[i] / track->dxyError() > muondxySigCut_) {
369  passD0sigCut = false;
370  continue;
371  }
372 
373  if (track->charge() > 0) {
374  posTrackDz_ = dz[i];
375  posTrackD0_ = d0[i];
376  posTrackEta_ = track->eta();
377  posTrackPhi_ = track->phi();
378  posTrackPt_ = track->pt();
379  } else {
380  negTrackDz_ = dz[i];
381  negTrackD0_ = d0[i];
382  negTrackEta_ = track->eta();
383  negTrackPhi_ = track->phi();
384  negTrackPt_ = track->pt();
385  }
386  i++;
387  }
388 
389  h_VertexMatrix->Fill(vtxIndex[0], vtxIndex[1]);
390  // check if the two muons have the same vertex
391  passSameVertex = (vtxIndex[0] == vtxIndex[1]);
392  if (!passSameVertex)
393  return;
394  h_cutFlow->Fill(1);
395 
396  // checks if both muons pass the IP signficance cut (w.r.t BeamSpot)
397  if (!passD0sigCut)
398  return;
399  h_cutFlow->Fill(2);
400 
401  // checks if both muons pass the pT cut
402  if (!passPtCut)
403  return;
404  h_cutFlow->Fill(3);
405 
406  // check if both muons pass the eta cut
407  if (!passEtaCut)
408  return;
409  h_cutFlow->Fill(4);
410 
411  // compute the invariant mass of the system
412  TLorentzVector posTrack, negTrack, mother;
413  posTrack.SetPtEtaPhiM(posTrackPt_, posTrackEta_, posTrackPhi_, muMass); // assume muon mass for tracks
414  negTrack.SetPtEtaPhiM(negTrackPt_, negTrackEta_, negTrackPhi_, muMass);
415  mother = posTrack + negTrack;
416  mass_ = mother.M();
417 
418  // checks if invariant mass of the system lies in the fiducial window
419  passMassWindow = (mass_ > minMassWindowCut_ && mass_ < maxMassWindowCut_);
420  if (!passMassWindow)
421  return;
422  h_cutFlow->Fill(5);
423 
424  // checks if the di-muon system passes the d0 compatibility cut
425  passDeltaD0 = (std::abs(d0[0] - d0[1]) < d0CompatibilityCut_);
426  h_DeltaD0->Fill(d0[0] - d0[1]);
427  h_DeltaDz->Fill(dz[0] - dz[1]);
428  if (!passDeltaD0)
429  return;
430  h_cutFlow->Fill(6);
431 
432  // checks if the di-muon system passes the z0 compatibility cut
433  passDeltaDz = (std::abs(dz[0] - dz[1]) < z0CompatibilityCut_);
434  if (!passDeltaDz)
435  return;
436  h_cutFlow->Fill(7);
437 
438  // checks if the di-muon system passes the opening angle cut
439  double openingAngle = this->openingAngle(myTracks[0], myTracks[1]);
441  passOpeningAngle = true; //(openingAngle > M_PI/4.);
442 
443  if (!passOpeningAngle)
444  return;
445  h_cutFlow->Fill(8);
446 
447  if (doGen_) {
448  const edm::View<reco::Candidate>* genPartCollection = &event.get(genParticlesToken_);
449 
450  // loop on the reconstructed tracks
451  for (const auto& track : myTracks) {
452  float drmin = 0.01;
453  // loop on the gen particles
454  for (auto g = genPartCollection->begin(); g != genPartCollection->end(); ++g) {
455  if (g->status() != 1)
456  continue;
457 
458  if (std::abs(g->pdgId()) != 13)
459  continue;
460 
461  if (g->charge() != track->charge())
462  continue;
463 
464  float dR = reco::deltaR2(*g, *track);
465 
466  auto const& vtx = g->vertex();
467  auto const& myBeamSpot = beamSpot.position(vtx.z());
468  const auto& theptinv2 = 1 / g->pt() * g->pt();
469 
470  if (dR < drmin) {
471  drmin = dR;
472 
473  if (g->charge() > 0) {
474  genPosMuonPt_ = g->pt();
475  genPosMuonEta_ = g->eta();
476  genPosMuonPhi_ = g->phi();
477  //d0
478  genPosMuonD0_ = -(-(vtx.x() - myBeamSpot.x()) * g->py() + (vtx.y() - myBeamSpot.y()) * g->px()) / g->pt();
479  //dz
480  genPosMuonDz_ =
481  (vtx.z() - myBeamSpot.z()) -
482  ((vtx.x() - myBeamSpot.x()) * g->px() + (vtx.y() - myBeamSpot.y()) * g->py()) * g->pz() * theptinv2;
483  } else {
484  genNegMuonPt_ = g->pt();
485  genNegMuonEta_ = g->eta();
486  genNegMuonPhi_ = g->phi();
487  //d0
488  genNegMuonD0_ = (-(vtx.x() - myBeamSpot.x()) * g->py() + (vtx.y() - myBeamSpot.y()) * g->px()) / g->pt();
489  //dz
490  genNegMuonDz_ =
491  (vtx.z() - myBeamSpot.z()) -
492  ((vtx.x() - myBeamSpot.x()) * g->px() + (vtx.y() - myBeamSpot.y()) * g->py()) * g->pz() * theptinv2;
493  }
494  } else {
495  continue;
496  }
497  }
498  }
499  }
500 
501  // if all cuts are passed fill the TTree
502  tree_->Fill();
503 }
504 
505 //_________________________________________________________________________________
507  math::XYZVector vec1(trk1->px(), trk1->py(), trk1->pz());
508  math::XYZVector vec2(trk2->px(), trk2->py(), trk2->pz());
509  return vec1.Dot(vec2) / (vec1.R() * vec2.R());
510 }
511 
512 /*
513 double SagittaBiasNtuplizer::openingAngle(const reco::Track& track1, const reco::Track& track2) {
514  double dPhi = std::abs(track1.phi() - track2.phi());
515  double dEta = std::abs(track1.eta() - track2.eta());
516  double deltaR2 = reco::deltaR2(track1, track2);
517  double openingAngle = 2 * std::atan2(std::sqrt(std::sin(dEta / 2) * std::sin(dEta / 2) + std::sinh(dPhi / 2) * std::sinh(dPhi / 2)), std::sqrt(1 - deltaR2));
518  return openingAngle;
519 }
520 */
521 
522 //_________________________________________________________________________________
523 std::pair<unsigned int, reco::Vertex> SagittaBiasNtuplizer::findClosestVertex(const reco::Track* track,
525  // Initialize variables for minimum distance and closest vertex
526  double minDistance = std::numeric_limits<double>::max();
527  reco::Vertex closestVertex;
528 
529  unsigned int index{0}, theIndex{999};
530  // Loop over the primary vertices and calculate the distance to the track
531  for (const auto& vertex : vertices) {
532  const math::XYZPoint& vertexPosition = vertex.position();
533 
534  // Calculate the distance to the track
535  const auto& trackMomentum = track->momentum();
536  const auto& vertexToPoint = vertexPosition - track->referencePoint();
537  double distance = vertexToPoint.Cross(trackMomentum).R() / trackMomentum.R();
538 
539  // Check if this is the closest vertex so far
540  if (distance < minDistance) {
541  minDistance = distance;
542  closestVertex = vertex;
543  theIndex = index;
544  }
545  index++;
546  }
547  return std::make_pair(theIndex, closestVertex);
548 }
549 
static const std::string kSharedResource
Definition: TFileService.h:76
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< reco::TrackCollection > tracksToken_
SagittaBiasNtuplizer(const edm::ParameterSet &)
double pt() const final
transverse momentum
edm::EDGetTokenT< reco::MuonCollection > muonsToken_
edm::EDGetTokenT< reco::TrackCollection > alcaRecoToken_
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:640
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:643
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
std::vector< Vertex > VertexCollection
Definition: Vertex.h:31
edm::EDGetTokenT< edm::View< reco::Candidate > > genParticlesToken_
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 g
Definition: Activities.doc:4
const edm::EDGetTokenT< reco::VertexCollection > vtxToken_
#define LogTrace(id)
static double constexpr muMass
Muon mass [GeV].
const edm::EDGetTokenT< reco::BeamSpot > bsToken_
char const * label
std::vector< double > vec1
Definition: HCALResponse.h:15
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
double openingAngle(const reco::Track *track1, const reco::Track *track2)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
~SagittaBiasNtuplizer() override=default
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Log< level::Info, false > LogInfo
static constexpr float d0
std::pair< unsigned int, reco::Vertex > findClosestVertex(const reco::Track *track1, const reco::VertexCollection &vertices)
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
void analyze(const edm::Event &event, const edm::EventSetup &setup) override
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:646
fixed size matrix
HLT enums.
const_iterator begin() const
std::vector< double > pTthresholds_
std::vector< vec1 > vec2
Definition: HCALResponse.h:16
const_iterator end() const
Definition: event.py:1
#define LogDebug(id)