CMS 3D CMS Logo

ConvertedPhotonProducer.cc
Go to the documentation of this file.
1 
41 
42 #include <vector>
43 
45 public:
47 
48  void beginRun(edm::Run const&, const edm::EventSetup& es) final;
49  void produce(edm::Event& evt, const edm::EventSetup& es) override;
50 
51 private:
52  void buildCollections(
53  edm::EventSetup const& es,
56  ElectronHcalHelper const& hcalHelper,
57  const edm::Handle<reco::TrackCollection>& trkHandle,
58  std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr, CompareTwoTracksVectors>& allPairs,
59  reco::ConversionCollection& outputConvPhotonCollection);
62  reco::ConversionCollection& outputCollection);
63 
65  reco::CaloClusterPtr const& sc);
66 
67  float calculateMinApproachDistance(const reco::TrackRef& track1, const reco::TrackRef& track2);
68  void getCircleCenter(const reco::TrackRef& tk, double r, double& x0, double& y0);
69 
72 
75 
77 
78  // Register the product
81 
87 
90 
94 
98 
100  double maxHOverE_;
101  double minSCEt_;
104  double deltaCotCut_;
108 
109  std::unique_ptr<ElectronHcalHelper> hcalHelper_;
110 
113 
115 
117 };
118 
121 
123  : conversionOITrackProducer_{consumes(config.getParameter<std::string>("conversionOITrackProducer"))},
124  conversionIOTrackProducer_{consumes(config.getParameter<std::string>("conversionIOTrackProducer"))},
125  outInTrackSCAssociationCollection_{consumes({config.getParameter<std::string>("conversionOITrackProducer"),
126  config.getParameter<std::string>("outInTrackSCAssociation")})},
127  inOutTrackSCAssociationCollection_{consumes({config.getParameter<std::string>("conversionIOTrackProducer"),
128  config.getParameter<std::string>("inOutTrackSCAssociation")})},
129 
130  generalTrackProducer_{consumes(config.getParameter<edm::InputTag>("generalTracksSrc"))},
131  convertedPhotonCollectionPutToken_{
132  produces<reco::ConversionCollection>(config.getParameter<std::string>("convertedPhotonCollection"))},
133  cleanedConvertedPhotonCollectionPutToken_{
134  produces<reco::ConversionCollection>(config.getParameter<std::string>("cleanedConvertedPhotonCollection"))},
135 
136  bcBarrelCollection_{consumes(config.getParameter<edm::InputTag>("bcBarrelCollection"))},
137  bcEndcapCollection_{consumes(config.getParameter<edm::InputTag>("bcEndcapCollection"))},
138  scHybridBarrelProducer_{consumes(config.getParameter<edm::InputTag>("scHybridBarrelProducer"))},
139  scIslandEndcapProducer_{consumes(config.getParameter<edm::InputTag>("scIslandEndcapProducer"))},
140  hbheRecHits_{consumes(config.getParameter<edm::InputTag>("hbheRecHits"))},
141  caloGeomToken_{esConsumes()},
142  mFToken_{esConsumes<MagneticField, IdealMagneticFieldRecord, edm::Transition::BeginRun>()},
143  transientTrackToken_{esConsumes<TransientTrackBuilder, TransientTrackRecord, edm::Transition::BeginRun>(
144  edm::ESInputTag("", "TransientTrackBuilder"))},
145  vertexFinder_{config},
146  algoName_{config.getParameter<std::string>("AlgorithmName")},
147 
148  hOverEConeSize_{config.getParameter<double>("hOverEConeSize")},
149  maxHOverE_{config.getParameter<double>("maxHOverE")},
150  minSCEt_{config.getParameter<double>("minSCEt")},
151  recoverOneTrackCase_{config.getParameter<bool>("recoverOneTrackCase")},
152  dRForConversionRecovery_{config.getParameter<double>("dRForConversionRecovery")},
153  deltaCotCut_{config.getParameter<double>("deltaCotCut")},
154  minApproachDisCut_{config.getParameter<double>("minApproachDisCut")},
155 
156  maxNumOfCandidates_{config.getParameter<int>("maxNumOfCandidates")},
157  risolveAmbiguity_{config.getParameter<bool>("risolveConversionAmbiguity")},
158  likelihoodWeights_{config.getParameter<std::string>("MVA_weights_location")} {
159  // instantiate the Track Pair Finder algorithm
160  likelihoodCalc_.setWeightsFile(edm::FileInPath{likelihoodWeights_.c_str()}.fullPath().c_str());
161 
163  cfgCone.hOverEConeSize = hOverEConeSize_;
164  if (cfgCone.hOverEConeSize > 0) {
165  cfgCone.onlyBehindCluster = false;
166  cfgCone.checkHcalStatus = false;
167 
168  cfgCone.hbheRecHits = hbheRecHits_;
169 
170  cfgCone.eThresHB = config.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
171  cfgCone.maxSeverityHB = config.getParameter<int>("maxHcalRecHitSeverity");
172  cfgCone.eThresHE = config.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
173  cfgCone.maxSeverityHE = cfgCone.maxSeverityHB;
174  }
175 
176  hcalHelper_ = std::make_unique<ElectronHcalHelper>(cfgCone, consumesCollector());
177 }
178 
179 void ConvertedPhotonProducer::beginRun(edm::Run const& r, edm::EventSetup const& theEventSetup) {
180  magneticField_ = &theEventSetup.getData(mFToken_);
181 
182  // Transform Track into TransientTrack (needed by the Vertex fitter)
184 }
185 
186 void ConvertedPhotonProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) {
187  //
188  // create empty output collections
189  //
190  // Converted photon candidates
191  reco::ConversionCollection outputConvPhotonCollection;
192  // Converted photon candidates
193  reco::ConversionCollection cleanedConversionCollection;
194 
195  // Get the Super Cluster collection in the Barrel
196  bool validBarrelSCHandle = true;
197  auto scBarrelHandle = theEvent.getHandle(scHybridBarrelProducer_);
198  if (!scBarrelHandle.isValid()) {
199  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the scHybridBarrelProducer";
200  validBarrelSCHandle = false;
201  }
202 
203  // Get the Super Cluster collection in the Endcap
204  bool validEndcapSCHandle = true;
206  theEvent.getByToken(scIslandEndcapProducer_, scEndcapHandle);
207  if (!scEndcapHandle.isValid()) {
208  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the scIslandEndcapProducer";
209  validEndcapSCHandle = false;
210  }
211 
213  bool validTrackInputs = true;
214  auto outInTrkHandle = theEvent.getHandle(conversionOITrackProducer_);
215  if (!outInTrkHandle.isValid()) {
216  //std::cout << "Error! Can't get the conversionOITrack " << "\n";
217  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the conversionOITrack "
218  << "\n";
219  validTrackInputs = false;
220  }
221  // LogDebug("ConvertedPhotonProducer")<< "ConvertedPhotonProducer outInTrack collection size " << (*outInTrkHandle).size() << "\n";
222 
224  auto outInTrkSCAssocHandle = theEvent.getHandle(outInTrackSCAssociationCollection_);
225  if (!outInTrkSCAssocHandle.isValid()) {
226  // std::cout << "Error! Can't get the product " << outInTrackSCAssociationCollection_.c_str() <<"\n";
227  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the outInTrackSCAssociationCollection)";
228  validTrackInputs = false;
229  }
230 
232  auto inOutTrkHandle = theEvent.getHandle(conversionIOTrackProducer_);
233  if (!inOutTrkHandle.isValid()) {
234  // std::cout << "Error! Can't get the conversionIOTrack " << "\n";
235  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the conversionIOTrack "
236  << "\n";
237  validTrackInputs = false;
238  }
239  // LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer inOutTrack collection size " << (*inOutTrkHandle).size() << "\n";
240 
242 
243  edm::Handle<reco::TrackCollection> generalTrkHandle;
244  if (recoverOneTrackCase_) {
245  theEvent.getByToken(generalTrackProducer_, generalTrkHandle);
246  if (!generalTrkHandle.isValid()) {
247  //std::cout << "Error! Can't get the genralTracks " << "\n";
248  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the genralTracks "
249  << "\n";
250  }
251  }
252 
254  auto inOutTrkSCAssocHandle = theEvent.getHandle(inOutTrackSCAssociationCollection_);
255  if (!inOutTrkSCAssocHandle.isValid()) {
256  //std::cout << "Error! Can't get the product " << inOutTrackSCAssociationCollection_.c_str() <<"\n";
257  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the inOutTrackSCAssociationCollection_.c_str()";
258  validTrackInputs = false;
259  }
260 
261  // Get the basic cluster collection in the Barrel
263  theEvent.getByToken(bcBarrelCollection_, bcBarrelHandle);
264  if (!bcBarrelHandle.isValid()) {
265  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the bcBarrelCollection";
266  }
267 
268  // Get the basic cluster collection in the Endcap
270  theEvent.getByToken(bcEndcapCollection_, bcEndcapHandle);
271  if (!bcEndcapHandle.isValid()) {
272  edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the bcEndcapCollection";
273  }
274 
275  if (validTrackInputs) {
276  //do the conversion:
277  std::vector<reco::TransientTrack> t_outInTrk = transientTrackBuilder_->build(outInTrkHandle);
278  std::vector<reco::TransientTrack> t_inOutTrk = transientTrackBuilder_->build(inOutTrkHandle);
279 
281  std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr, CompareTwoTracksVectors> allPairs;
282  allPairs = trackPairFinder_.run(
283  t_outInTrk, outInTrkHandle, outInTrkSCAssocHandle, t_inOutTrk, inOutTrkHandle, inOutTrkSCAssocHandle);
284  //LogDebug("ConvertedPhotonProducer") << "ConvertedPhotonProducer allPairs.size " << allPairs.size() << "\n";
285 
286  hcalHelper_->beginEvent(theEvent, theEventSetup);
287 
288  buildCollections(theEventSetup,
289  scBarrelHandle,
290  bcBarrelHandle,
291  *hcalHelper_,
292  generalTrkHandle,
293  allPairs,
294  outputConvPhotonCollection);
295  buildCollections(theEventSetup,
296  scEndcapHandle,
297  bcEndcapHandle,
298  *hcalHelper_,
299  generalTrkHandle,
300  allPairs,
301  outputConvPhotonCollection);
302  }
303 
304  // put the product in the event
305  auto const conversionHandle =
306  theEvent.emplace(convertedPhotonCollectionPutToken_, std::move(outputConvPhotonCollection));
307 
308  // Loop over barrel and endcap SC collections and fill the photon collection
309  if (validBarrelSCHandle)
310  cleanCollections(scBarrelHandle, conversionHandle, cleanedConversionCollection);
311  if (validEndcapSCHandle)
312  cleanCollections(scEndcapHandle, conversionHandle, cleanedConversionCollection);
313 
314  theEvent.emplace(cleanedConvertedPhotonCollectionPutToken_, std::move(cleanedConversionCollection));
315 }
316 
318  edm::EventSetup const& es,
319  const edm::Handle<edm::View<reco::CaloCluster>>& scHandle,
320  const edm::Handle<edm::View<reco::CaloCluster>>& bcHandle,
321  ElectronHcalHelper const& hcalHelper,
322  const edm::Handle<reco::TrackCollection>& generalTrkHandle,
323  std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr, CompareTwoTracksVectors>& allPairs,
324  reco::ConversionCollection& outputConvPhotonCollection)
325 
326 {
327  // instantiate the algorithm for finding the position of the track extrapolation at the Ecal front face
328  ConversionTrackEcalImpactPoint theEcalImpactPositionFinder(magneticField_);
329 
331 
332  std::vector<reco::TransientTrack> t_generalTrk;
334  t_generalTrk = transientTrackBuilder_->build(generalTrkHandle);
335 
336  // Loop over SC in the barrel and reconstruct converted photons
338  for (auto const& aClus : scHandle->ptrs()) {
339  // preselection based in Et and H/E cut
340  if (aClus->energy() / cosh(aClus->eta()) <= minSCEt_)
341  continue;
342  const reco::CaloCluster* pClus = &(*aClus);
343  auto const* sc = dynamic_cast<const reco::SuperCluster*>(pClus);
344  double HoE = hcalHelper.hcalESum(*sc, 0) / sc->energy();
345  if (HoE >= maxHOverE_)
346  continue;
348 
349  std::vector<edm::Ref<reco::TrackCollection>> trackPairRef;
350  std::vector<math::XYZPointF> trackInnPos;
351  std::vector<math::XYZVectorF> trackPin;
352  std::vector<math::XYZVectorF> trackPout;
353  float minAppDist = -99;
354 
355  //LogDebug("ConvertedPhotonProducer") << "ConvertedPhotonProducer SC energy " << aClus->energy() << " eta " << aClus->eta() << " phi " << aClus->phi() << "\n";
356 
358  const reco::Particle::Point vtx(0, 0, 0);
359 
360  math::XYZVector direction = aClus->position() - vtx;
361  math::XYZVector momentum = direction.unit() * aClus->energy();
362  const reco::Particle::LorentzVector p4(momentum.x(), momentum.y(), momentum.z(), aClus->energy());
363 
364  if (!allPairs.empty()) {
365  for (auto iPair = allPairs.begin(); iPair != allPairs.end(); ++iPair) {
366  scPtrVec.clear();
367 
368  reco::Vertex theConversionVertex;
369  reco::CaloClusterPtr caloPtr = iPair->second;
370  if (!(aClus == caloPtr))
371  continue;
372 
373  scPtrVec.push_back(aClus);
374 
375  std::vector<math::XYZPointF> trkPositionAtEcal = theEcalImpactPositionFinder.find(iPair->first, bcHandle);
376  std::vector<reco::CaloClusterPtr> matchingBC = theEcalImpactPositionFinder.matchingBC();
377 
378  minAppDist = -99;
379  const std::string metname = "ConvertedPhotons|ConvertedPhotonProducer";
380  if ((iPair->first).size() > 1) {
381  try {
382  vertexFinder_.run(iPair->first, theConversionVertex);
383 
384  } catch (cms::Exception& e) {
385  //std::cout << " cms::Exception caught in ConvertedPhotonProducer::produce" << "\n" ;
386  edm::LogWarning(metname) << "cms::Exception caught in ConvertedPhotonProducer::produce\n"
387  << e.explainSelf();
388  }
389 
390  // Old TwoTrackMinimumDistance md;
391  // Old md.calculate ( (iPair->first)[0].initialFreeState(), (iPair->first)[1].initialFreeState() );
392  // Old minAppDist = md.distance();
393 
394  /*
395  for ( unsigned int i=0; i< matchingBC.size(); ++i) {
396  if ( matchingBC[i].isNull() ) std::cout << " This ref to BC is null: skipping " << "\n";
397  else
398  std::cout << " BC energy " << matchingBC[i]->energy() << "\n";
399  }
400  */
401 
403  trackPairRef.clear();
404  trackInnPos.clear();
405  trackPin.clear();
406  trackPout.clear();
407 
408  for (std::vector<reco::TransientTrack>::const_iterator iTk = (iPair->first).begin();
409  iTk != (iPair->first).end();
410  ++iTk) {
411  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer Transient Tracks in the pair charge " << iTk->charge() << " Num of RecHits " << iTk->recHitsSize() << " inner momentum " << iTk->track().innerMomentum() << "\n";
412 
413  auto const* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTk->basicTransientTrack());
414  reco::TrackRef myTkRef = ttt->persistentTrackRef();
415 
416  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer Ref to Rec Tracks in the pair charge " << myTkRef->charge() << " Num of RecHits " << myTkRef->recHitsSize() << " inner momentum " << myTkRef->innerMomentum() << "\n";
417  if (myTkRef->extra().isNonnull()) {
418  trackInnPos.push_back(toFConverterP(myTkRef->innerPosition()));
419  trackPin.push_back(toFConverterV(myTkRef->innerMomentum()));
420  trackPout.push_back(toFConverterV(myTkRef->outerMomentum()));
421  }
422  trackPairRef.push_back(myTkRef);
423  }
424 
425  // std::cout << " ConvertedPhotonProducer trackPin size " << trackPin.size() << std::endl;
426  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer SC energy " << aClus->energy() << "\n";
427  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer photon p4 " << p4 << "\n";
428  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer vtx " << vtx.x() << " " << vtx.y() << " " << vtx.z() << "\n";
429  if (theConversionVertex.isValid()) {
430  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer theConversionVertex " << theConversionVertex.position().x() << " " << theConversionVertex.position().y() << " " << theConversionVertex.position().z() << "\n";
431  }
432  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer trackPairRef " << trackPairRef.size() << "\n";
433 
434  minAppDist = calculateMinApproachDistance(trackPairRef[0], trackPairRef[1]);
435 
436  double like = -999.;
437  reco::Conversion newCandidate(scPtrVec,
438  trackPairRef,
439  trkPositionAtEcal,
440  theConversionVertex,
441  matchingBC,
442  minAppDist,
443  trackInnPos,
444  trackPin,
445  trackPout,
446  like,
447  algo);
448  like = likelihoodCalc_.calculateLikelihood(newCandidate);
449  // std::cout << "like = " << like << std::endl;
450  newCandidate.setMVAout(like);
451  outputConvPhotonCollection.push_back(newCandidate);
452 
453  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer Put the ConvertedPhotonCollection a candidate in the Barrel " << "\n";
454 
455  } else {
456  // std::cout << " ConvertedPhotonProducer case with only one track found " << "\n";
457 
458  //std::cout << " ConvertedPhotonProducer recovering one track " << "\n";
459  trackPairRef.clear();
460  trackInnPos.clear();
461  trackPin.clear();
462  trackPout.clear();
463  std::vector<reco::TransientTrack>::const_iterator iTk = (iPair->first).begin();
464  //std::cout << " ConvertedPhotonProducer Transient Tracks in the pair charge " << iTk->charge() << " Num of RecHits " << iTk->recHitsSize() << " inner momentum " << iTk->track().innerMomentum() << " pt " << sqrt(iTk->track().innerMomentum().perp2()) << "\n";
465  auto const* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTk->basicTransientTrack());
466  reco::TrackRef myTk = ttt->persistentTrackRef();
467  if (myTk->extra().isNonnull()) {
468  trackInnPos.push_back(toFConverterP(myTk->innerPosition()));
469  trackPin.push_back(toFConverterV(myTk->innerMomentum()));
470  trackPout.push_back(toFConverterV(myTk->outerMomentum()));
471  }
472  trackPairRef.push_back(myTk);
473  //std::cout << " Provenance " << myTk->algoName() << std::endl;
474 
475  if (recoverOneTrackCase_) {
476  float theta1 = myTk->innerMomentum().Theta();
477  float dCot = 999.;
478  float dCotTheta = -999.;
479  reco::TrackRef goodRef;
480  for (auto const& tran : t_generalTrk) {
481  auto const* ttt = dynamic_cast<const reco::TrackTransientTrack*>(tran.basicTransientTrack());
482  reco::TrackRef trRef = ttt->persistentTrackRef();
483  if (trRef->charge() * myTk->charge() > 0)
484  continue;
485  float dEta = trRef->eta() - myTk->eta();
486  float dPhi = trRef->phi() - myTk->phi();
488  continue;
489  float theta2 = trRef->innerMomentum().Theta();
490  dCotTheta = 1. / tan(theta1) - 1. / tan(theta2);
491  // std::cout << " ConvertedPhotonProducer recovering general transient track charge " << trRef->charge() << " momentum " << trRef->innerMomentum() << " dcotTheta " << fabs(dCotTheta) << std::endl;
492  if (fabs(dCotTheta) < dCot) {
493  dCot = fabs(dCotTheta);
494  goodRef = trRef;
495  }
496  }
497 
498  if (goodRef.isNonnull()) {
499  minAppDist = calculateMinApproachDistance(myTk, goodRef);
500 
501  // std::cout << " ConvertedPhotonProducer chosen dCotTheta " << fabs(dCotTheta) << std::endl;
502  if (fabs(dCotTheta) < deltaCotCut_ && minAppDist > minApproachDisCut_) {
503  trackInnPos.push_back(toFConverterP(goodRef->innerPosition()));
504  trackPin.push_back(toFConverterV(goodRef->innerMomentum()));
505  trackPout.push_back(toFConverterV(goodRef->outerMomentum()));
506  trackPairRef.push_back(goodRef);
507  // std::cout << " ConvertedPhotonProducer adding opposite charge track from generalTrackCollection charge " << goodRef ->charge() << " pt " << sqrt(goodRef->innerMomentum().perp2()) << " trackPairRef size " << trackPairRef.size() << std::endl;
508  //std::cout << " Track Provenenance " << goodRef->algoName() << std::endl;
509 
510  try {
511  vertexFinder_.run(iPair->first, theConversionVertex);
512 
513  } catch (cms::Exception& e) {
514  //std::cout << " cms::Exception caught in ConvertedPhotonProducer::produce" << "\n" ;
515  edm::LogWarning(metname) << "cms::Exception caught in ConvertedPhotonProducer::produce\n"
516  << e.explainSelf();
517  }
518  }
519  }
520 
521  } // bool On/Off one track case recovery using generalTracks
522  const double like = -999.;
523  outputConvPhotonCollection.emplace_back(scPtrVec,
524  trackPairRef,
525  trkPositionAtEcal,
526  theConversionVertex,
527  matchingBC,
528  minAppDist,
529  trackInnPos,
530  trackPin,
531  trackPout,
532  like,
533  algo);
534  auto& newCandidate = outputConvPhotonCollection.back();
535  newCandidate.setMVAout(likelihoodCalc_.calculateLikelihood(newCandidate));
536 
537  } // case with only on track: looking in general tracks
538  }
539  }
540  }
541 }
542 
545  reco::ConversionCollection& outputConversionCollection) {
546  reco::Conversion* newCandidate = nullptr;
547  for (auto const& aClus : scHandle->ptrs()) {
548  // SC energy preselection
549  if (aClus->energy() / cosh(aClus->eta()) <= minSCEt_)
550  continue;
551 
552  if (conversionHandle.isValid()) {
553  if (risolveAmbiguity_) {
554  std::vector<reco::ConversionRef> bestRef = solveAmbiguity(conversionHandle, aClus);
555 
556  for (std::vector<reco::ConversionRef>::iterator iRef = bestRef.begin(); iRef != bestRef.end(); iRef++) {
557  if (iRef->isNonnull()) {
558  newCandidate = (*iRef)->clone();
559  outputConversionCollection.push_back(*newCandidate);
560  delete newCandidate;
561  }
562  }
563 
564  } else {
565  for (unsigned int icp = 0; icp < conversionHandle->size(); icp++) {
567  if (!(aClus.id() == cpRef->caloCluster()[0].id() && aClus.key() == cpRef->caloCluster()[0].key()))
568  continue;
569  if (!cpRef->isConverted())
570  continue;
571  if (cpRef->nTracks() < 2)
572  continue;
573  newCandidate = (&(*cpRef))->clone();
574  outputConversionCollection.push_back(*newCandidate);
575  delete newCandidate;
576  }
577 
578  } // solve or not the ambiguity of many conversion candidates
579  }
580  }
581 }
582 
583 std::vector<reco::ConversionRef> ConvertedPhotonProducer::solveAmbiguity(
585  std::multimap<double, reco::ConversionRef, std::greater<double>> convMap;
586 
587  for (unsigned int icp = 0; icp < conversionHandle->size(); icp++) {
589 
590  //std::cout << " cpRef " << cpRef->nTracks() << " " << cpRef ->caloCluster()[0]->energy() << std::endl;
591  if (!(scRef.id() == cpRef->caloCluster()[0].id() && scRef.key() == cpRef->caloCluster()[0].key()))
592  continue;
593  if (!cpRef->isConverted())
594  continue;
595  double like = cpRef->MVAout();
596  if (cpRef->nTracks() < 2)
597  continue;
598  // std::cout << " Like " << like << std::endl;
599  convMap.emplace(like, cpRef);
600  }
601 
602  // std::cout << " convMap size " << convMap.size() << std::endl;
603 
604  std::vector<reco::ConversionRef> bestRefs;
605  for (auto iMap = convMap.begin(); iMap != convMap.end(); iMap++) {
606  // std::cout << " Like list in the map " << iMap->first << " " << (iMap->second)->EoverP() << std::endl;
607  bestRefs.push_back(iMap->second);
608  if (int(bestRefs.size()) == maxNumOfCandidates_)
609  break;
610  }
611 
612  return bestRefs;
613 }
614 
616  const reco::TrackRef& track2) {
617  double x1, x2, y1, y2;
618  double xx_1 = track1->innerPosition().x(), yy_1 = track1->innerPosition().y(), zz_1 = track1->innerPosition().z();
619  double xx_2 = track2->innerPosition().x(), yy_2 = track2->innerPosition().y(), zz_2 = track2->innerPosition().z();
620  double radius1 =
621  track1->innerMomentum().Rho() / (.3 * (magneticField_->inTesla(GlobalPoint(xx_1, yy_1, zz_1)).z())) * 100;
622  double radius2 =
623  track2->innerMomentum().Rho() / (.3 * (magneticField_->inTesla(GlobalPoint(xx_2, yy_2, zz_2)).z())) * 100;
624  getCircleCenter(track1, radius1, x1, y1);
625  getCircleCenter(track2, radius2, x2, y2);
626 
627  return std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) - radius1 - radius2;
628 }
629 
630 void ConvertedPhotonProducer::getCircleCenter(const reco::TrackRef& tk, double r, double& x0, double& y0) {
631  double x1, y1, phi;
632  x1 = tk->innerPosition().x(); //inner position and inner momentum need track Extra!
633  y1 = tk->innerPosition().y();
634  phi = tk->innerMomentum().phi();
635  const int charge = tk->charge();
636  x0 = x1 + r * sin(phi) * charge;
637  y0 = y1 - r * cos(phi) * charge;
638 }
edm::EDPutTokenT< reco::ConversionCollection > cleanedConvertedPhotonCollectionPutToken_
edm::EDGetTokenT< reco::TrackCaloClusterPtrAssociation > outInTrackSCAssociationCollection_
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
edm::EDGetTokenT< edm::View< reco::CaloCluster > > bcEndcapCollection_
TransientVertex run(const std::vector< reco::TransientTrack > &pair)
ProductID id() const
Accessor for product ID.
Definition: Ref.h:244
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:160
std::string fullPath() const
Definition: FileInPath.cc:161
edm::EDPutTokenT< reco::ConversionCollection > convertedPhotonCollectionPutToken_
T z() const
Definition: PV3DBase.h:61
const std::string metname
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
void push_back(Ptr< T > const &iPtr)
Definition: PtrVector.h:149
edm::EDGetTokenT< reco::TrackCollection > conversionIOTrackProducer_
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
edm::EDGetTokenT< edm::View< reco::CaloCluster > > scIslandEndcapProducer_
static ConversionAlgorithm algoByName(const std::string &name)
Definition: Conversion.cc:139
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeomToken_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:536
Definition: config.py:1
std::unique_ptr< ElectronHcalHelper > hcalHelper_
edm::Ptr< CaloCluster > CaloClusterPtr
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
edm::EDGetTokenT< HBHERecHitCollection > hbheRecHits_
Log< level::Error, false > LogError
MagneticField const * magneticField_
edm::EDGetTokenT< HBHERecHitCollection > hbheRecHits
key_type key() const
Accessor for product key.
Definition: Ref.h:250
std::vector< Conversion > ConversionCollection
collectin of Conversion objects
Definition: ConversionFwd.h:9
std::vector< reco::CaloClusterPtr > matchingBC() const
reco::TransientTrack build(const reco::Track *p) const
void beginRun(edm::Run const &, const edm::EventSetup &es) final
edm::EDGetTokenT< reco::TrackCollection > generalTrackProducer_
double hcalESum(const reco::SuperCluster &, int depth) const
math::XYZVectorF toFConverterV(const math::XYZVector &val)
void buildCollections(edm::EventSetup const &es, const edm::Handle< edm::View< reco::CaloCluster >> &scHandle, const edm::Handle< edm::View< reco::CaloCluster >> &bcHandle, ElectronHcalHelper const &hcalHelper, const edm::Handle< reco::TrackCollection > &trkHandle, std::map< std::vector< reco::TransientTrack >, reco::CaloClusterPtr, CompareTwoTracksVectors > &allPairs, reco::ConversionCollection &outputConvPhotonCollection)
T sqrt(T t)
Definition: SSEVec.h:19
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Conversion * clone() const
returns a clone of the candidate
Definition: Conversion.cc:148
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
math::XYZPoint Point
point in the space
Definition: Particle.h:25
std::vector< reco::ConversionRef > solveAmbiguity(const edm::OrphanHandle< reco::ConversionCollection > &conversionHandle, reco::CaloClusterPtr const &sc)
edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > transientTrackToken_
float calculateMinApproachDistance(const reco::TrackRef &track1, const reco::TrackRef &track2)
edm::EDGetTokenT< reco::TrackCollection > conversionOITrackProducer_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EDGetTokenT< reco::TrackCaloClusterPtrAssociation > inOutTrackSCAssociationCollection_
std::vector< math::XYZPointF > find(const std::vector< reco::TransientTrack > &tracks, const edm::Handle< edm::View< reco::CaloCluster > > &bcHandle)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< float > > XYZVectorF
spatial vector with cartesian internal representation
Definition: Vector3D.h:16
ConversionLikelihoodCalculator likelihoodCalc_
double calculateLikelihood(reco::ConversionRef conversion)
ProductIndex id() const
Definition: ProductID.h:35
edm::EDGetTokenT< edm::View< reco::CaloCluster > > bcBarrelCollection_
edm::EDGetTokenT< edm::View< reco::CaloCluster > > scHybridBarrelProducer_
OrphanHandle< PROD > emplace(EDPutTokenT< PROD > token, Args &&... args)
puts a new product
Definition: Event.h:434
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
void produce(edm::Event &evt, const edm::EventSetup &es) override
ConversionVertexFinder vertexFinder_
void cleanCollections(const edm::Handle< edm::View< reco::CaloCluster >> &scHandle, const edm::OrphanHandle< reco::ConversionCollection > &conversionHandle, reco::ConversionCollection &outputCollection)
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
void setMVAout(const float &mva)
set the value of the TMVA output
Definition: Conversion.h:161
bool isValid() const
Definition: HandleBase.h:70
ConvertedPhotonProducer(const edm::ParameterSet &ps)
ConversionTrackPairFinder trackPairFinder_
TransientTrackBuilder const * transientTrackBuilder_
void clear()
Clear the PtrVector.
Definition: PtrVectorBase.h:81
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:560
key_type key() const
Definition: Ptr.h:165
EgammaHcalIsolation::arrayHB eThresHB
math::XYZPointF toFConverterP(const math::XYZPoint &val)
EgammaHcalIsolation::arrayHE eThresHE
Log< level::Warning, false > LogWarning
std::array< double, 4 > arrayHB
std::map< std::vector< reco::TransientTrack >, reco::CaloClusterPtr, CompareTwoTracksVectors > run(const std::vector< reco::TransientTrack > &outIn, const edm::Handle< reco::TrackCollection > &outInTrkHandle, const edm::Handle< reco::TrackCaloClusterPtrAssociation > &outInTrackSCAssH, const std::vector< reco::TransientTrack > &inOut, const edm::Handle< reco::TrackCollection > &inOutTrkHandle, const edm::Handle< reco::TrackCaloClusterPtrAssociation > &inOutTrackSCAssH)
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:21
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > mFToken_
def move(src, dest)
Definition: eostools.py:511
bool isValid() const
Tells whether the vertex is valid.
Definition: Vertex.h:72
Definition: Run.h:45
std::array< double, 7 > arrayHE
void getCircleCenter(const reco::TrackRef &tk, double r, double &x0, double &y0)