CMS 3D CMS Logo

ConversionProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: ConversionProducer
4 // Class: ConversionProducer
5 //
13 //
14 // Original Authors: Hongliang Liu, UC of Riverside US, Nancy Marinelli Univ of Notre Dame
15 // Created: Thu Mar 13 17:40:48 CDT 2008
16 //
17 //
18 
61 
62 #include <map>
63 #include <memory>
64 
66 public:
67  explicit ConversionProducer(const edm::ParameterSet&);
68 
69 private:
70  void produce(edm::Event&, const edm::EventSetup&) override;
71 
73  std::multimap<double, reco::CaloClusterPtr>& basicClusterPtrs,
74  std::multimap<double, reco::CaloClusterPtr>& superClusterPtrs);
75 
76  // ----------member data ---------------------------
78 
80  typedef std::vector<Point> PointCollection;
81 
83 
89 
93 
95 
97 
98  bool usePvtx_; //if use primary vertices
101 
103 
104  double deltaEta_;
105 
106  double halfWayEta_, halfWayPhi_; //halfway open angle to search in basic clusters
107  unsigned int maxNumOfTrackInPU_;
108  double maxTrackZ_;
109  double maxTrackRho_;
110  double minSCEt_;
113  double energyBC_; //1.5GeV for track BC selection
114  double energyTotalBC_; //5GeV for track pair BC selection
115  double d0Cut_; //0 for d0*charge cut
116  double dzCut_; //innerposition of z diff cut
117  double dEtaTkBC_, dPhiTkBC_; //0.06 0.6 for track and BC matching
118 
119  double maxChi2Left_, maxChi2Right_; //5. 5. for track chi2 quality
120  double minHitsLeft_, minHitsRight_; //5 2 for track hits quality
121 
123  minApproachHigh_; //0.02 0.2 for track pair open angle and > -0.1 cm
124 
125  double r_cut; //cross_r cut
126  double vtxChi2_; //vertex chi2 probablity cut
127 
128  bool allowSingleLeg_; //if single track conversion ?
129  bool rightBC_; //if right leg requires matching BC?
130 
132  const edm::EventSetup& iSetup,
133  const std::multimap<float, edm::Ptr<reco::ConversionTrack> >& allTracks,
134  const std::multimap<double, reco::CaloClusterPtr>& superClusterPtrs,
135  const std::multimap<double, reco::CaloClusterPtr>& basicClusterPtrs,
136  const reco::Vertex& the_pvtx,
137  reco::ConversionCollection& outputConvPhotonCollection);
138 
139  //track quality cut, returns pass or no
140  inline bool trackQualityFilter(const edm::RefToBase<reco::Track>& ref, bool isLeft);
141  inline bool trackD0Cut(const edm::RefToBase<reco::Track>& ref);
142  inline bool trackD0Cut(const edm::RefToBase<reco::Track>& ref, const reco::Vertex& the_pvtx);
143 
144  //track impact point at ECAL wall, returns validity to access position ew
145  bool getTrackImpactPosition(const reco::Track* tk_ref,
146  TrackerGeometry const& trackerGeom,
147  MagneticField const& magField,
148  math::XYZPointF& ew);
149 
150  //distance at min approaching point, returns distance
151  // double getMinApproach(const edm::RefToBase<reco::Track>& ll, const edm::RefToBase<reco::Track>& rr,
152  // const MagneticField* magField);
153 
154  bool preselectTrackPair(const reco::TransientTrack& ttk_l, const reco::TransientTrack& ttk_r, double& appDist);
155 
156  //cut-based selection, TODO remove global cut variables
159 
160  //kinematic vertex fitting, return true for valid vertex
161  inline bool checkVertex(const reco::TransientTrack& ttk_l,
162  const reco::TransientTrack& ttk_r,
163  MagneticField const& magField,
164  reco::Vertex& the_vertex) {
165  return vertexFinder_.run({ttk_l, ttk_r}, the_vertex);
166  }
167 
168  bool checkPhi(const edm::RefToBase<reco::Track>& tk_l,
169  const edm::RefToBase<reco::Track>& tk_r,
170  TrackerGeometry const& trackerGeom,
171  MagneticField const& magField,
172  const reco::Vertex& the_vertex);
173 
174  //check the closest BC, returns true for found a BC
175  bool getMatchedBC(const std::multimap<double, reco::CaloClusterPtr>& bcMap,
176  const math::XYZPointF& trackImpactPosition,
177  reco::CaloClusterPtr& closestBC);
178 
179  // finds the super cluster matching with at least one track in the pair
180  bool matchingSC(const std::multimap<double, reco::CaloClusterPtr>& scMap,
183 
184  double etaTransformation(float EtaParticle, float Zvertex);
185 
187 
189 };
190 
193 
194 inline const GeomDet* recHitDet(const TrackingRecHit& hit, const TrackingGeometry* geom) {
195  return geom->idToDet(hit.geographicalId());
196 }
197 
199  return recHitDet(hit, geom)->surface();
200 }
201 
203  return s.toLocal(GlobalVector(v.x(), v.y(), v.z()));
204 }
205 
206 ConversionProducer::ConversionProducer(const edm::ParameterSet& iConfig) : vertexFinder_{iConfig} {
207  algoName_ = iConfig.getParameter<std::string>("AlgorithmName");
208 
209  src_ = consumes<edm::View<reco::ConversionTrack> >(iConfig.getParameter<edm::InputTag>("src"));
210 
211  maxNumOfTrackInPU_ = iConfig.getParameter<int>("maxNumOfTrackInPU");
212  maxTrackRho_ = iConfig.getParameter<double>("maxTrackRho");
213  maxTrackZ_ = iConfig.getParameter<double>("maxTrackZ");
214 
215  allowTrackBC_ = iConfig.getParameter<bool>("AllowTrackBC");
216  allowD0_ = iConfig.getParameter<bool>("AllowD0");
217  allowDeltaPhi_ = iConfig.getParameter<bool>("AllowDeltaPhi");
218  allowDeltaCot_ = iConfig.getParameter<bool>("AllowDeltaCot");
219  allowMinApproach_ = iConfig.getParameter<bool>("AllowMinApproach");
220  allowOppCharge_ = iConfig.getParameter<bool>("AllowOppCharge");
221 
222  allowVertex_ = iConfig.getParameter<bool>("AllowVertex");
223 
224  bypassPreselGsf_ = iConfig.getParameter<bool>("bypassPreselGsf");
225  bypassPreselEcal_ = iConfig.getParameter<bool>("bypassPreselEcal");
226  bypassPreselEcalEcal_ = iConfig.getParameter<bool>("bypassPreselEcalEcal");
227 
228  deltaEta_ = iConfig.getParameter<double>("deltaEta");
229 
230  halfWayEta_ = iConfig.getParameter<double>("HalfwayEta"); //open angle to search track matches with BC
231 
232  d0Cut_ = iConfig.getParameter<double>("d0");
233 
234  usePvtx_ = iConfig.getParameter<bool>("UsePvtx"); //if use primary vertices
235 
236  vertexProducer_ = consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("primaryVertexProducer"));
237 
238  transientTrackBuilder_ = esConsumes(edm::ESInputTag("", "TransientTrackBuilder"));
239  trackerGeometry_ = esConsumes();
240  magneticField_ = esConsumes();
241 
242  //Track-cluster matching eta and phi cuts
243  dEtaTkBC_ = iConfig.getParameter<double>("dEtaTrackBC"); //TODO research on cut endcap/barrel
244  dPhiTkBC_ = iConfig.getParameter<double>("dPhiTrackBC");
245 
246  bcBarrelCollection_ =
247  consumes<edm::View<reco::CaloCluster> >(iConfig.getParameter<edm::InputTag>("bcBarrelCollection"));
248  bcEndcapCollection_ =
249  consumes<edm::View<reco::CaloCluster> >(iConfig.getParameter<edm::InputTag>("bcEndcapCollection"));
250 
251  scBarrelProducer_ = consumes<edm::View<reco::CaloCluster> >(iConfig.getParameter<edm::InputTag>("scBarrelProducer"));
252  scEndcapProducer_ = consumes<edm::View<reco::CaloCluster> >(iConfig.getParameter<edm::InputTag>("scEndcapProducer"));
253 
254  energyBC_ = iConfig.getParameter<double>("EnergyBC"); //BC energy threshold
255  energyTotalBC_ = iConfig.getParameter<double>("EnergyTotalBC"); //BC energy threshold
256  minSCEt_ = iConfig.getParameter<double>("minSCEt"); //super cluster energy threshold
257  dEtacutForSCmatching_ = iConfig.getParameter<double>(
258  "dEtacutForSCmatching"); // dEta between conversion momentum direction and SC position
259  dPhicutForSCmatching_ = iConfig.getParameter<double>(
260  "dPhicutForSCmatching"); // dPhi between conversion momentum direction and SC position
261 
262  //Track cuts on left right track: at least one leg reaches ECAL
263  //Left track: must exist, must reach Ecal and match BC, so loose cut on Chi2 and tight on hits
264  //Right track: not necessary to exist (if allowSingleLeg_), not necessary to reach ECAL or match BC, so tight cut on Chi2 and loose on hits
265  maxChi2Left_ = iConfig.getParameter<double>("MaxChi2Left");
266  maxChi2Right_ = iConfig.getParameter<double>("MaxChi2Right");
267  minHitsLeft_ = iConfig.getParameter<int>("MinHitsLeft");
268  minHitsRight_ = iConfig.getParameter<int>("MinHitsRight");
269 
270  //Track Open angle cut on delta cot(theta) and delta phi
271  deltaCotTheta_ = iConfig.getParameter<double>("DeltaCotTheta");
272  deltaPhi_ = iConfig.getParameter<double>("DeltaPhi");
273  minApproachLow_ = iConfig.getParameter<double>("MinApproachLow");
274  minApproachHigh_ = iConfig.getParameter<double>("MinApproachHigh");
275 
276  // if allow single track collection, by default False
277  allowSingleLeg_ = iConfig.getParameter<bool>("AllowSingleLeg");
278  rightBC_ = iConfig.getParameter<bool>("AllowRightBC");
279 
280  //track inner position dz cut, need RECO
281  dzCut_ = iConfig.getParameter<double>("dz");
282  //track analytical cross cut
283  r_cut = iConfig.getParameter<double>("rCut");
284  vtxChi2_ = iConfig.getParameter<double>("vtxChi2");
285 
286  thettbuilder_ = nullptr;
287 
288  //output
289  ConvertedPhotonCollection_ = iConfig.getParameter<std::string>("convertedPhotonCollection");
290 
291  produces<reco::ConversionCollection>(ConvertedPhotonCollection_);
292 }
293 
294 // ------------ method called to produce the data ------------
296  using namespace edm;
297 
298  reco::ConversionCollection outputConvPhotonCollection;
299  auto outputConvPhotonCollection_p = std::make_unique<reco::ConversionCollection>();
300 
301  //std::cout << " ConversionProducer::produce " << std::endl;
302  //Read multiple track input collections
303 
304  edm::Handle<edm::View<reco::ConversionTrack> > trackCollectionHandle;
305  iEvent.getByToken(src_, trackCollectionHandle);
306 
307  //build map of ConversionTracks ordered in eta
308  std::multimap<float, edm::Ptr<reco::ConversionTrack> > convTrackMap;
309  for (auto const& t : trackCollectionHandle->ptrs())
310  convTrackMap.emplace(t->track()->eta(), t);
311 
314  if (usePvtx_) {
315  iEvent.getByToken(vertexProducer_, vertexHandle);
316  if (!vertexHandle.isValid()) {
317  edm::LogError("ConversionProducer") << "Error! Can't get the product primary Vertex Collection "
318  << "\n";
319  usePvtx_ = false;
320  }
321  if (usePvtx_)
322  vertexCollection = *(vertexHandle.product());
323  }
324 
326 
327  reco::Vertex the_pvtx;
328  //because the priamry vertex is sorted by quality, the first one is the best
329  if (!vertexCollection.empty())
330  the_pvtx = *(vertexCollection.begin());
331 
332  if (trackCollectionHandle->size() > maxNumOfTrackInPU_) {
333  iEvent.put(std::move(outputConvPhotonCollection_p), ConvertedPhotonCollection_);
334  return;
335  }
336 
337  // build Super and Basic cluster geometry map to search in eta bounds for clusters
338  std::multimap<double, reco::CaloClusterPtr> basicClusterPtrs;
339  std::multimap<double, reco::CaloClusterPtr> superClusterPtrs;
340 
341  buildSuperAndBasicClusterGeoMap(iEvent, basicClusterPtrs, superClusterPtrs);
342 
344  iSetup,
345  convTrackMap,
346  superClusterPtrs,
347  basicClusterPtrs,
348  the_pvtx,
349  outputConvPhotonCollection); //allow empty basicClusterPtrs
350 
351  outputConvPhotonCollection_p->assign(outputConvPhotonCollection.begin(), outputConvPhotonCollection.end());
352  iEvent.put(std::move(outputConvPhotonCollection_p), ConvertedPhotonCollection_);
353 }
354 
356  std::multimap<double, reco::CaloClusterPtr>& basicClusterPtrs,
357  std::multimap<double, reco::CaloClusterPtr>& superClusterPtrs) {
358  // Get the Super Cluster collection in the Barrel
360  iEvent.getByToken(scBarrelProducer_, scBarrelHandle);
361  if (!scBarrelHandle.isValid()) {
362  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the barrel superclusters!";
363  }
364 
365  // Get the Super Cluster collection in the Endcap
367  iEvent.getByToken(scEndcapProducer_, scEndcapHandle);
368  if (!scEndcapHandle.isValid()) {
369  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the endcap superclusters!";
370  }
371 
373  edm::Handle<edm::View<reco::CaloCluster> > bcEndcapHandle; //TODO check cluster type if BasicCluster or PFCluster
374 
375  iEvent.getByToken(bcBarrelCollection_, bcBarrelHandle);
376  if (!bcBarrelHandle.isValid()) {
377  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the barrel basic clusters!";
378  }
379 
380  iEvent.getByToken(bcEndcapCollection_, bcEndcapHandle);
381  if (!bcEndcapHandle.isValid()) {
382  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the endcap basic clusters!";
383  }
384 
385  if (bcBarrelHandle.isValid()) {
386  for (auto const& handle : {bcBarrelHandle, bcEndcapHandle}) {
387  for (auto const& bc : handle->ptrs()) {
388  if (bc->energy() > energyBC_)
389  basicClusterPtrs.emplace(bc->position().eta(), bc);
390  }
391  }
392  }
393 
394  if (scBarrelHandle.isValid()) {
395  for (auto const& handle : {scBarrelHandle, scEndcapHandle}) {
396  for (auto const& sc : handle->ptrs()) {
397  if (sc->energy() > minSCEt_)
398  superClusterPtrs.emplace(sc->position().eta(), sc);
399  }
400  }
401  }
402 }
403 
405  const edm::EventSetup& iSetup,
406  const std::multimap<float, edm::Ptr<reco::ConversionTrack> >& allTracks,
407  const std::multimap<double, reco::CaloClusterPtr>& superClusterPtrs,
408  const std::multimap<double, reco::CaloClusterPtr>& basicClusterPtrs,
409  const reco::Vertex& the_pvtx,
410  reco::ConversionCollection& outputConvPhotonCollection) {
411  TrackerGeometry const& trackerGeom = iSetup.getData(trackerGeometry_);
412  MagneticField const& magField = iSetup.getData(magneticField_);
413 
414  // std::vector<math::XYZPointF> trackImpactPosition;
415  // trackImpactPosition.reserve(allTracks.size());//track impact position at ECAL
416  // std::vector<bool> trackValidECAL;//Does this track reach ECAL basic cluster (reach ECAL && match with BC)
417  // trackValidECAL.assign(allTracks.size(), false);
418  //
419  // std::vector<reco::CaloClusterPtr> trackMatchedBC;
420  // reco::CaloClusterPtr empty_bc;
421  // trackMatchedBC.assign(allTracks.size(), empty_bc);//TODO find a better way to avoid copy constructor
422  //
423  // std::vector<int> bcHandleId;//the associated BC handle id, -1 invalid, 0 barrel 1 endcap
424  // bcHandleId.assign(allTracks.size(), -1);
425 
426  // not used std::multimap<double, int> trackInnerEta;//Track innermost state Eta map to TrackRef index, to be used in track pair sorting
427 
428  std::map<edm::Ptr<reco::ConversionTrack>, math::XYZPointF> trackImpactPosition;
429  std::map<edm::Ptr<reco::ConversionTrack>, reco::CaloClusterPtr> trackMatchedBC;
430 
431  ConversionHitChecker hitChecker;
432 
433  //2 propagate all tracks into ECAL, record its eta and phi
434 
435  for (auto const& tk_ref : allTracks) {
436  const reco::Track* tk = tk_ref.second->trackRef().get();
437 
438  //check impact position then match with BC
439  math::XYZPointF ew;
440  if (getTrackImpactPosition(tk, trackerGeom, magField, ew)) {
441  trackImpactPosition[tk_ref.second] = ew;
442 
443  reco::CaloClusterPtr closest_bc; //the closest matching BC to track
444 
445  if (getMatchedBC(basicClusterPtrs, ew, closest_bc)) {
446  trackMatchedBC[tk_ref.second] = closest_bc;
447  }
448  }
449  }
450 
451  //3. pair up tracks:
452  //TODO it is k-Closest pair of point problem
453  //std::cout << " allTracks.size() " << allTracks.size() << std::endl;
454  for (auto ll = allTracks.begin(); ll != allTracks.end(); ++ll) {
455  bool track1HighPurity = true;
456  //std::cout << " Loop on allTracks " << std::endl;
457  const edm::RefToBase<reco::Track>& left = ll->second->trackRef();
458 
459  //TODO: This is a workaround, should be fixed with a proper function in the TTBuilder
460  //(Note that the TrackRef and GsfTrackRef versions of the constructor are needed
461  // to properly get refit tracks in the output vertex)
462  reco::TransientTrack ttk_l;
463  if (dynamic_cast<const reco::GsfTrack*>(left.get())) {
464  ttk_l = thettbuilder_->build(left.castTo<reco::GsfTrackRef>());
465  } else {
466  ttk_l = thettbuilder_->build(left.castTo<reco::TrackRef>());
467  }
468 
470  // if ((allowTrackBC_ && !trackValidECAL[ll-allTracks.begin()]) )//this Left leg should have valid BC
471  // continue;
472 
473  if (the_pvtx.isValid()) {
474  if (!(trackD0Cut(left, the_pvtx)))
475  track1HighPurity = false;
476  } else {
477  if (!(trackD0Cut(left)))
478  track1HighPurity = false;
479  }
480 
481  std::vector<int> right_candidates; //store all right legs passed the cut (theta/approach and ref pair)
482  std::vector<double> right_candidate_theta, right_candidate_approach;
483  std::vector<std::pair<bool, reco::Vertex> > vertex_candidates;
484 
485  //inner loop only over tracks between eta and eta + deltaEta of the first track
486  float etasearch = ll->first + deltaEta_;
487  std::multimap<float, edm::Ptr<reco::ConversionTrack> >::const_iterator rr = ll;
488  ++rr;
489  for (; rr != allTracks.lower_bound(etasearch); ++rr) {
490  bool track2HighPurity = true;
491  bool highPurityPair = true;
492 
493  const edm::RefToBase<reco::Track>& right = rr->second->trackRef();
494 
495  //TODO: This is a workaround, should be fixed with a proper function in the TTBuilder
496  reco::TransientTrack ttk_r;
497  if (dynamic_cast<const reco::GsfTrack*>(right.get())) {
498  ttk_r = thettbuilder_->build(right.castTo<reco::GsfTrackRef>());
499  } else {
500  ttk_r = thettbuilder_->build(right.castTo<reco::TrackRef>());
501  }
502  //std::cout << " This track is " << right->algoName() << std::endl;
503 
504  //all vertexing preselection should go here
505 
506  //check for opposite charge
507  if (allowOppCharge_ && (left->charge() * right->charge() > 0))
508  continue; //same sign, reject pair
509 
511  //if ( (allowTrackBC_ && !trackValidECAL[rr-allTracks.begin()] && rightBC_) )// if right track matches ECAL
512  // continue;
513 
514  double approachDist = -999.;
515  //apply preselection to track pair, overriding preselection for gsf+X or ecalseeded+X pairs if so configured
516  bool preselected = preselectTrackPair(ttk_l, ttk_r, approachDist);
517  preselected = preselected || (bypassPreselGsf_ &&
518  (left->algo() == reco::TrackBase::gsf || right->algo() == reco::TrackBase::gsf));
519  preselected = preselected || (bypassPreselEcal_ && (left->algo() == reco::TrackBase::outInEcalSeededConv ||
523  preselected = preselected || (bypassPreselEcalEcal_ &&
528 
529  if (!preselected) {
530  continue;
531  }
532 
533  //do the actual vertex fit
534  reco::Vertex theConversionVertex; //by default it is invalid
535  bool goodVertex = checkVertex(ttk_l, ttk_r, magField, theConversionVertex);
536 
537  //bail as early as possible in case the fit didn't return a good vertex
538  if (!goodVertex) {
539  continue;
540  }
541 
542  //track pair pass the quality cut
543  if (!((trackQualityFilter(left, true) && trackQualityFilter(right, false)) ||
544  (trackQualityFilter(left, false) && trackQualityFilter(right, true)))) {
545  highPurityPair = false;
546  }
547 
548  if (the_pvtx.isValid()) {
549  if (!(trackD0Cut(right, the_pvtx)))
550  track2HighPurity = false;
551  } else {
552  if (!(trackD0Cut(right)))
553  track2HighPurity = false;
554  }
555 
556  //if all cuts passed, go ahead to make conversion candidates
557  std::vector<edm::RefToBase<reco::Track> > trackPairRef;
558  trackPairRef.push_back(left); //left track
559  trackPairRef.push_back(right); //right track
560 
561  std::vector<math::XYZVectorF> trackPin;
562  std::vector<math::XYZVectorF> trackPout;
563  std::vector<math::XYZPointF> trackInnPos;
564  std::vector<uint8_t> nHitsBeforeVtx;
565  std::vector<Measurement1DFloat> dlClosestHitToVtx;
566 
567  if (left->extra().isNonnull() && right->extra().isNonnull()) { //only available on TrackExtra
568  trackInnPos.push_back(toFConverterP(left->innerPosition()));
569  trackInnPos.push_back(toFConverterP(right->innerPosition()));
570  trackPin.push_back(toFConverterV(left->innerMomentum()));
571  trackPin.push_back(toFConverterV(right->innerMomentum()));
572  trackPout.push_back(toFConverterV(left->outerMomentum()));
573  trackPout.push_back(toFConverterV(right->outerMomentum()));
574  auto leftWrongHits = hitChecker.nHitsBeforeVtx(*left->extra(), theConversionVertex);
575  auto rightWrongHits = hitChecker.nHitsBeforeVtx(*right->extra(), theConversionVertex);
576  nHitsBeforeVtx.push_back(leftWrongHits.first);
577  nHitsBeforeVtx.push_back(rightWrongHits.first);
578  dlClosestHitToVtx.push_back(leftWrongHits.second);
579  dlClosestHitToVtx.push_back(rightWrongHits.second);
580  }
581 
582  uint8_t nSharedHits = hitChecker.nSharedHits(*left.get(), *right.get());
583 
584  //if using kinematic fit, check with chi2 post cut
585  if (theConversionVertex.isValid()) {
586  const float chi2Prob = ChiSquaredProbability(theConversionVertex.chi2(), theConversionVertex.ndof());
587  if (chi2Prob < vtxChi2_)
588  highPurityPair = false;
589  }
590 
591  //std::cout << " highPurityPair after vertex cut " << highPurityPair << std::endl;
592  std::vector<math::XYZPointF> trkPositionAtEcal;
593  std::vector<reco::CaloClusterPtr> matchingBC;
594 
595  if (allowTrackBC_) { //TODO find out the BC ptrs if not doing matching, otherwise, leave it empty
596  //const int lbc_handle = bcHandleId[ll-allTracks.begin()],
597  // rbc_handle = bcHandleId[rr-allTracks.begin()];
598 
599  std::map<edm::Ptr<reco::ConversionTrack>, math::XYZPointF>::const_iterator trackImpactPositionLeft =
600  trackImpactPosition.find(ll->second);
601  std::map<edm::Ptr<reco::ConversionTrack>, math::XYZPointF>::const_iterator trackImpactPositionRight =
602  trackImpactPosition.find(rr->second);
603  std::map<edm::Ptr<reco::ConversionTrack>, reco::CaloClusterPtr>::const_iterator trackMatchedBCLeft =
604  trackMatchedBC.find(ll->second);
605  std::map<edm::Ptr<reco::ConversionTrack>, reco::CaloClusterPtr>::const_iterator trackMatchedBCRight =
606  trackMatchedBC.find(rr->second);
607 
608  if (trackImpactPositionLeft != trackImpactPosition.end()) {
609  trkPositionAtEcal.push_back(trackImpactPositionLeft->second); //left track
610  } else {
611  trkPositionAtEcal.push_back(math::XYZPointF()); //left track
612  }
613  if (trackImpactPositionRight != trackImpactPosition.end()) { //second track ECAL position may be invalid
614  trkPositionAtEcal.push_back(trackImpactPositionRight->second);
615  }
616 
617  double total_e_bc = 0.;
618  if (trackMatchedBCLeft != trackMatchedBC.end()) {
619  matchingBC.push_back(trackMatchedBCLeft->second); //left track
620  total_e_bc += trackMatchedBCLeft->second->energy();
621  } else {
622  matchingBC.push_back(reco::CaloClusterPtr()); //left track
623  }
624  if (trackMatchedBCRight != trackMatchedBC.end()) { //second track ECAL position may be invalid
625  matchingBC.push_back(trackMatchedBCRight->second);
626  total_e_bc += trackMatchedBCRight->second->energy();
627  }
628 
629  if (total_e_bc < energyTotalBC_) {
630  highPurityPair = false;
631  }
632  }
633  //signature cuts, then check if vertex, then post-selection cuts
634  highPurityPair = highPurityPair && track1HighPurity && track2HighPurity && goodVertex &&
635  checkPhi(left, right, trackerGeom, magField, theConversionVertex);
636 
638  /*
639  for ( std::vector<edm::RefToBase<reco::Track> >::iterator iTk=trackPairRef.begin(); iTk!=trackPairRef.end(); iTk++) {
640  math::XYZPointF impPos;
641  if ( getTrackImpactPosition(*iTk, trackerGeom, magField, impPos) ) {
642 
643  }
644 
645  }
646  */
647 
648  const float minAppDist = approachDist;
650  float dummy = 0;
652  reco::Conversion newCandidate(scPtrVec,
653  trackPairRef,
654  trkPositionAtEcal,
655  theConversionVertex,
656  matchingBC,
657  minAppDist,
658  trackInnPos,
659  trackPin,
660  trackPout,
661  nHitsBeforeVtx,
662  dlClosestHitToVtx,
663  nSharedHits,
664  dummy,
665  algo);
666  // Fill in scPtrVec with the macthing SC
667  if (matchingSC(superClusterPtrs, newCandidate, scPtrVec))
668  newCandidate.setMatchingSuperCluster(scPtrVec);
669 
670  newCandidate.setQuality(reco::Conversion::highPurity, highPurityPair);
671  bool generalTracksOnly = ll->second->isTrackerOnly() && rr->second->isTrackerOnly() &&
672  !dynamic_cast<const reco::GsfTrack*>(ll->second->trackRef().get()) &&
673  !dynamic_cast<const reco::GsfTrack*>(rr->second->trackRef().get());
674  bool gsfTracksOpenOnly = ll->second->isGsfTrackOpen() && rr->second->isGsfTrackOpen();
675  bool arbitratedEcalSeeded = ll->second->isArbitratedEcalSeeded() && rr->second->isArbitratedEcalSeeded();
676  bool arbitratedMerged = ll->second->isArbitratedMerged() && rr->second->isArbitratedMerged();
677  bool arbitratedMergedEcalGeneral =
678  ll->second->isArbitratedMergedEcalGeneral() && rr->second->isArbitratedMergedEcalGeneral();
679 
681  newCandidate.setQuality(reco::Conversion::gsfTracksOpenOnly, gsfTracksOpenOnly);
684  newCandidate.setQuality(reco::Conversion::arbitratedMergedEcalGeneral, arbitratedMergedEcalGeneral);
685 
686  outputConvPhotonCollection.push_back(newCandidate);
687  }
688  }
689 }
690 
691 //
692 // member functions
693 //
694 
696  bool pass = true;
697  if (isLeft) {
698  pass = (ref->normalizedChi2() < maxChi2Left_ && ref->found() >= minHitsLeft_);
699  } else {
700  pass = (ref->normalizedChi2() < maxChi2Right_ && ref->found() >= minHitsRight_);
701  }
702 
703  return pass;
704 }
705 
707  //NOTE if not allow d0 cut, always true
708  return ((!allowD0_) || !(ref->d0() * ref->charge() / ref->d0Error() < d0Cut_));
709 }
710 
712  //
713  return ((!allowD0_) || !(-ref->dxy(the_pvtx.position()) * ref->charge() / ref->dxyError() < d0Cut_));
714 }
715 
717  TrackerGeometry const& trackerGeom,
718  MagneticField const& magField,
719  math::XYZPointF& ew) {
720  PropagatorWithMaterial propag(alongMomentum, 0.000511, &magField);
721 
723  129.f, GlobalPoint(0., 0., 0.), TkRotation<float>(), new SimpleCylinderBounds(129, 129, -320.5, 320.5)));
724  constexpr float epsilon = 0.001;
725  Surface::RotationType rot; // unit rotation matrix
726  constexpr float barrelRadius = 129.f;
727  constexpr float barrelHalfLength = 270.9f;
728  constexpr float endcapRadius = 171.1f;
729  constexpr float endcapZ = 320.5f;
731  barrelRadius,
732  Surface::PositionType(0, 0, 0),
733  rot,
735  ReferenceCountingPointer<BoundDisk> theNegativeEtaEndcap_(new BoundDisk(
737  ReferenceCountingPointer<BoundDisk> thePositiveEtaEndcap_(new BoundDisk(
739 
740  //const TrajectoryStateOnSurface myTSOS = trajectoryStateTransform::innerStateOnSurface(*(*ref), *trackerGeom, magField);
741  const auto myTSOS = trajectoryStateTransform::outerStateOnSurface(*tk_ref, trackerGeom, &magField);
742  TrajectoryStateOnSurface stateAtECAL;
743  stateAtECAL = propag.propagate(myTSOS, *theBarrel_);
744  if (!stateAtECAL.isValid() || (stateAtECAL.isValid() && fabs(stateAtECAL.globalPosition().eta()) > 1.479f)) {
745  //endcap propagator
746  if (myTSOS.globalPosition().z() > 0.) {
747  stateAtECAL = propag.propagate(myTSOS, *thePositiveEtaEndcap_);
748  } else {
749  stateAtECAL = propag.propagate(myTSOS, *theNegativeEtaEndcap_);
750  }
751  }
752  if (stateAtECAL.isValid()) {
753  ew = stateAtECAL.globalPosition();
754  return true;
755  } else
756  return false;
757 }
758 
759 bool ConversionProducer::matchingSC(const std::multimap<double, reco::CaloClusterPtr>& scMap,
760  reco::Conversion& aConv,
761  // reco::CaloClusterPtr& mSC){
763  // double dRMin=999.;
764  double detaMin = 999.;
765  double dphiMin = 999.;
767  for (std::multimap<double, reco::CaloClusterPtr>::const_iterator scItr = scMap.begin(); scItr != scMap.end();
768  scItr++) {
769  const reco::CaloClusterPtr& sc = scItr->second;
770  const double delta_phi = reco::deltaPhi(aConv.refittedPairMomentum().phi(), sc->phi());
771  double sceta = sc->eta();
772  double conveta = etaTransformation(aConv.refittedPairMomentum().eta(), aConv.zOfPrimaryVertexFromTracks());
773  const double delta_eta = fabs(conveta - sceta);
774  if (fabs(delta_eta) < fabs(detaMin) && fabs(delta_phi) < fabs(dphiMin)) {
775  detaMin = fabs(delta_eta);
776  dphiMin = fabs(delta_phi);
777  match = sc;
778  }
779  }
780 
781  if (fabs(detaMin) < dEtacutForSCmatching_ && fabs(dphiMin) < dPhicutForSCmatching_) {
782  mSC.push_back(match);
783  return true;
784  } else
785  return false;
786 }
787 
788 bool ConversionProducer::getMatchedBC(const std::multimap<double, reco::CaloClusterPtr>& bcMap,
789  const math::XYZPointF& trackImpactPosition,
790  reco::CaloClusterPtr& closestBC) {
791  const double track_eta = trackImpactPosition.eta();
792  const double track_phi = trackImpactPosition.phi();
793 
794  double min_eta = 999., min_phi = 999.;
795  reco::CaloClusterPtr closest_bc;
796  for (std::multimap<double, reco::CaloClusterPtr>::const_iterator bc = bcMap.lower_bound(track_eta - halfWayEta_);
797  bc != bcMap.upper_bound(track_eta + halfWayEta_);
798  ++bc) { //use eta map to select possible BC collection then loop in
799  const reco::CaloClusterPtr& ebc = bc->second;
800  const double delta_eta = track_eta - (ebc->position().eta());
801  const double delta_phi = reco::deltaPhi(track_phi, (ebc->position().phi()));
802  if (fabs(delta_eta) < dEtaTkBC_ && fabs(delta_phi) < dPhiTkBC_) {
803  if (fabs(min_eta) > fabs(delta_eta) && fabs(min_phi) > fabs(delta_phi)) { //take the closest to track BC
804  min_eta = delta_eta;
805  min_phi = delta_phi;
806  closest_bc = bc->second;
807  //TODO check if min_eta>delta_eta but min_phi<delta_phi
808  }
809  }
810  }
811 
812  if (min_eta < 999.) {
813  closestBC = closest_bc;
814  return true;
815  } else
816  return false;
817 }
818 
819 //check track open angle of phi at vertex
821  const edm::RefToBase<reco::Track>& tk_r,
822  TrackerGeometry const& trackerGeom,
823  MagneticField const& magField,
824  const reco::Vertex& vtx) {
825  if (!allowDeltaPhi_)
826  return true;
827  //if track has innermost momentum, check with innermost phi
828  //if track also has valid vertex, propagate to vertex then calculate phi there
829  //if track has no innermost momentum, just return true, because track->phi() makes no sense
830  if (tk_l->extra().isNonnull() && tk_r->extra().isNonnull()) {
831  double iphi1 = tk_l->innerMomentum().phi(), iphi2 = tk_r->innerMomentum().phi();
832  if (vtx.isValid()) {
833  PropagatorWithMaterial propag(anyDirection, 0.000511, &magField);
834 
835  double recoPhoR = vtx.position().Rho();
838  recoPhoR,
839  Surface::PositionType(0, 0, 0),
840  rot,
842  recoPhoR - 0.001, recoPhoR + 0.001, -fabs(vtx.position().z()), fabs(vtx.position().z()))));
844  Surface::PositionType(0, 0, vtx.position().z()), rot, new SimpleDiskBounds(0, recoPhoR, -0.001, 0.001)));
845 
846  const auto myTSOS1 = trajectoryStateTransform::innerStateOnSurface(*tk_l, trackerGeom, &magField);
847  const auto myTSOS2 = trajectoryStateTransform::innerStateOnSurface(*tk_r, trackerGeom, &magField);
848  TrajectoryStateOnSurface stateAtVtx1, stateAtVtx2;
849  stateAtVtx1 = propag.propagate(myTSOS1, *theBarrel_);
850  if (!stateAtVtx1.isValid()) {
851  stateAtVtx1 = propag.propagate(myTSOS1, *theDisk_);
852  }
853  if (stateAtVtx1.isValid()) {
854  iphi1 = stateAtVtx1.globalDirection().phi();
855  }
856  stateAtVtx2 = propag.propagate(myTSOS2, *theBarrel_);
857  if (!stateAtVtx2.isValid()) {
858  stateAtVtx2 = propag.propagate(myTSOS2, *theDisk_);
859  }
860  if (stateAtVtx2.isValid()) {
861  iphi2 = stateAtVtx2.globalDirection().phi();
862  }
863  }
864  const double dPhi = reco::deltaPhi(iphi1, iphi2);
865  return (fabs(dPhi) < deltaPhi_);
866  } else {
867  return true;
868  }
869 }
870 
872  const reco::TransientTrack& ttk_r,
873  double& appDist) {
874  double dCotTheta = 1. / tan(ttk_l.track().innerMomentum().theta()) - 1. / tan(ttk_r.track().innerMomentum().theta());
875  if (allowDeltaCot_ && (std::abs(dCotTheta) > deltaCotTheta_)) {
876  return false;
877  }
878 
879  //non-conversion hypothesis, reject prompt track pairs
881  closest.calculate(ttk_l.innermostMeasurementState(), ttk_r.innermostMeasurementState());
882  if (!closest.status()) {
883  return false;
884  }
885 
886  if (closest.crossingPoint().perp() < r_cut) {
887  return false;
888  }
889 
890  //compute tangent point btw tracks (conversion hypothesis)
891  TangentApproachInRPhi tangent;
893  if (!tangent.status()) {
894  return false;
895  }
896 
897  GlobalPoint tangentPoint = tangent.crossingPoint();
898  double rho = tangentPoint.perp();
899 
900  //reject candidates well outside of tracker bounds
901  if (rho > maxTrackRho_) {
902  return false;
903  }
904 
905  if (std::abs(tangentPoint.z()) > maxTrackZ_) {
906  return false;
907  }
908 
909  std::pair<GlobalTrajectoryParameters, GlobalTrajectoryParameters> trajs = tangent.trajectoryParameters();
910 
911  //very large separation in z, no hope
912  if (std::abs(trajs.first.position().z() - trajs.second.position().z()) > dzCut_) {
913  return false;
914  }
915 
916  float minApproach = tangent.perpdist();
917  appDist = minApproach;
918 
919  if (allowMinApproach_ && (minApproach < minApproachLow_ || minApproach > minApproachHigh_)) {
920  return false;
921  }
922 
923  return true;
924 }
925 
928  const reco::CaloClusterPtr& bc_l = ll.second; //can be null, so check isNonnull()
929  const reco::CaloClusterPtr& bc_r = rr.second;
930 
931  //The cuts should be ordered by considering if takes time and if cuts off many fakes
932  if (allowTrackBC_) {
933  //check energy of BC
934  double total_e_bc = 0;
935  if (bc_l.isNonnull())
936  total_e_bc += bc_l->energy();
937  if (rightBC_)
938  if (bc_r.isNonnull())
939  total_e_bc += bc_r->energy();
940 
941  if (total_e_bc < energyTotalBC_)
942  return false;
943  }
944 
945  return true;
946 }
947 
948 double ConversionProducer::etaTransformation(float EtaParticle, float Zvertex) {
949  //---Definitions
950  const float PI = 3.1415927;
951 
952  //---Definitions for ECAL
953  const float R_ECAL = 136.5;
954  const float Z_Endcap = 328.0;
955  const float etaBarrelEndcap = 1.479;
956 
957  //---ETA correction
958 
959  float Theta = 0.0;
960  float ZEcal = R_ECAL * sinh(EtaParticle) + Zvertex;
961 
962  if (ZEcal != 0.0)
963  Theta = atan(R_ECAL / ZEcal);
964  if (Theta < 0.0)
965  Theta = Theta + PI;
966  double ETA = -log(tan(0.5 * Theta));
967 
968  if (fabs(ETA) > etaBarrelEndcap) {
969  float Zend = Z_Endcap;
970  if (EtaParticle < 0.0)
971  Zend = -Zend;
972  float Zlen = Zend - Zvertex;
973  float RR = Zlen / sinh(EtaParticle);
974  Theta = atan(RR / Zend);
975  if (Theta < 0.0)
976  Theta = Theta + PI;
977  ETA = -log(tan(0.5 * Theta));
978  }
979  //---Return the result
980  return ETA;
981  //---end
982 }
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
bool checkVertex(const reco::TransientTrack &ttk_l, const reco::TransientTrack &ttk_r, MagneticField const &magField, reco::Vertex &the_vertex)
unsigned int maxNumOfTrackInPU_
const Track & track() const
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
edm::EDGetTokenT< reco::VertexCollection > vertexProducer_
double zOfPrimaryVertexFromTracks(const math::XYZPoint &myBeamSpot=math::XYZPoint()) const
Definition: Conversion.h:136
edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > transientTrackBuilder_
T perp() const
Definition: PV3DBase.h:69
TransientVertex run(const std::vector< reco::TransientTrack > &pair)
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
REF castTo() const
Definition: RefToBase.h:259
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:65
TrajectoryStateOnSurface outerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)
T z() const
Definition: PV3DBase.h:61
bool status() const override
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:149
const Point & position() const
position
Definition: Vertex.h:127
const TransientTrackBuilder * thettbuilder_
void setQuality(ConversionQuality q, bool b)
Definition: Conversion.h:239
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
int closest(std::vector< int > const &vec, int value)
math::XYZVectorF refittedPairMomentum() const
Conversion tracks momentum from the tracks refitted with vertex constraint.
Definition: Conversion.cc:206
T eta() const
Definition: PV3DBase.h:73
uint8_t nSharedHits(const reco::Track &trk1, const reco::Track &trk2) const
T const * product() const
Definition: Handle.h:70
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
void buildCollection(edm::Event &iEvent, const edm::EventSetup &iSetup, const std::multimap< float, edm::Ptr< reco::ConversionTrack > > &allTracks, const std::multimap< double, reco::CaloClusterPtr > &superClusterPtrs, const std::multimap< double, reco::CaloClusterPtr > &basicClusterPtrs, const reco::Vertex &the_pvtx, reco::ConversionCollection &outputConvPhotonCollection)
bool getTrackImpactPosition(const reco::Track *tk_ref, TrackerGeometry const &trackerGeom, MagneticField const &magField, math::XYZPointF &ew)
Cylinder BoundCylinder
Definition: BoundCylinder.h:17
static ConversionAlgorithm algoByName(const std::string &name)
Definition: Conversion.cc:139
void buildSuperAndBasicClusterGeoMap(const edm::Event &, std::multimap< double, reco::CaloClusterPtr > &basicClusterPtrs, std::multimap< double, reco::CaloClusterPtr > &superClusterPtrs)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
math::XYZPointF Point
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
constexpr float barrelHalfLength
Log< level::Error, false > LogError
static constexpr float R_ECAL
double ndof() const
Definition: Vertex.h:123
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magneticField_
std::vector< Conversion > ConversionCollection
collectin of Conversion objects
Definition: ConversionFwd.h:9
std::pair< uint8_t, Measurement1DFloat > nHitsBeforeVtx(const reco::TrackExtra &track, const reco::Vertex &vtx, float sigmaTolerance=3.0) const
bool matchingSC(const std::multimap< double, reco::CaloClusterPtr > &scMap, reco::Conversion &conv, reco::CaloClusterPtrVector &mSC)
unsigned short found() const
Number of valid hits on track.
Definition: Track.h:142
reco::TransientTrack build(const reco::Track *p) const
#define ETA
int charge() const
track electric charge
Definition: TrackBase.h:596
int iEvent
Definition: GenABIO.cc:224
GlobalPoint globalPosition() const
double dxyError() const
error on dxy
Definition: TrackBase.h:769
math::XYZVectorF toFConverterV(const math::XYZVector &val)
constexpr float endcapRadius
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:146
ConversionVertexFinder vertexFinder_
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::pair< GlobalTrajectoryParameters, GlobalTrajectoryParameters > trajectoryParameters() const
double f[11][100]
float ChiSquaredProbability(double chiSquared, double nrDOF)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EDGetTokenT< edm::View< reco::CaloCluster > > scEndcapProducer_
edm::EDGetTokenT< edm::View< reco::CaloCluster > > bcBarrelCollection_
TrajectoryStateOnSurface innermostMeasurementState() const
static constexpr float etaBarrelEndcap
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< float > > XYZVectorF
spatial vector with cartesian internal representation
Definition: Vector3D.h:16
bool calculate(const TrajectoryStateOnSurface &sta, const TrajectoryStateOnSurface &stb) override
bool checkPhi(const edm::RefToBase< reco::Track > &tk_l, const edm::RefToBase< reco::Track > &tk_r, TrackerGeometry const &trackerGeom, MagneticField const &magField, const reco::Vertex &the_vertex)
edm::EDGetTokenT< edm::View< reco::CaloCluster > > bcEndcapCollection_
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > trackerGeometry_
#define PI
Definition: QcdUeDQM.h:37
constexpr float endcapZ
bool getMatchedBC(const std::multimap< double, reco::CaloClusterPtr > &bcMap, const math::XYZPointF &trackImpactPosition, reco::CaloClusterPtr &closestBC)
LocalVector toLocal(const reco::Track::Vector &v, const Surface &s)
bool checkTrackPair(const std::pair< edm::RefToBase< reco::Track >, reco::CaloClusterPtr > &ll, const std::pair< edm::RefToBase< reco::Track >, reco::CaloClusterPtr > &rr)
bool trackQualityFilter(const edm::RefToBase< reco::Track > &ref, bool isLeft)
TrackAlgorithm algo() const
Definition: TrackBase.h:547
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
double d0() const
dxy parameter in perigee convention (d0 = -dxy)
Definition: TrackBase.h:611
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
bool trackD0Cut(const edm::RefToBase< reco::Track > &ref)
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
GlobalVector globalDirection() const
double normalizedChi2() const
chi-squared divided by n.d.o.f. (or chi-squared * 1e6 if n.d.o.f. is zero)
Definition: TrackBase.h:593
std::string ConvertedPhotonCollection_
Disk BoundDisk
Definition: BoundDisk.h:54
EPOS::IO_EPOS conv
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:50
bool isValid() const
Definition: HandleBase.h:70
edm::EDGetTokenT< edm::View< reco::ConversionTrack > > src_
double chi2() const
chi-squares
Definition: Vertex.h:116
edm::EDGetTokenT< edm::View< reco::CaloCluster > > scBarrelProducer_
std::vector< Point > PointCollection
HLT enums.
void produce(edm::Event &, const edm::EventSetup &) override
double etaTransformation(float EtaParticle, float Zvertex)
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
math::XYZPointF toFConverterP(const math::XYZPoint &val)
const math::XYZVector & innerMomentum() const
momentum vector at the innermost hit position
Definition: Track.h:59
double d0Error() const
error on d0
Definition: TrackBase.h:772
bool preselectTrackPair(const reco::TransientTrack &ttk_l, const reco::TransientTrack &ttk_r, double &appDist)
const math::XYZPoint & innerPosition() const
position of the innermost hit
Definition: Track.h:56
const GeomDet * recHitDet(const TrackingRecHit &hit, const TrackingGeometry *geom)
math::XYZVector Vector
spatial vector
Definition: TrackBase.h:77
value_type const * get() const
Definition: RefToBase.h:211
void setMatchingSuperCluster(const reco::CaloClusterPtrVector &sc)
Definition: Conversion.h:165
def move(src, dest)
Definition: eostools.py:511
const BoundPlane & recHitSurface(const TrackingRecHit &hit, const TrackingGeometry *geom)
bool isValid() const
Tells whether the vertex is valid.
Definition: Vertex.h:72
static constexpr float Z_Endcap
constexpr float barrelRadius
GlobalPoint crossingPoint() const override
Global3DVector GlobalVector
Definition: GlobalVector.h:10
ConversionProducer(const edm::ParameterSet &)
TrajectoryStateOnSurface innerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:608
const TrackExtraRef & extra() const
reference to "extra" object
Definition: Track.h:139