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
337  int myCands = 0;
339  for (auto const& aClus : scHandle->ptrs()) {
340  // preselection based in Et and H/E cut
341  if (aClus->energy() / cosh(aClus->eta()) <= minSCEt_)
342  continue;
343  const reco::CaloCluster* pClus = &(*aClus);
344  auto const* sc = dynamic_cast<const reco::SuperCluster*>(pClus);
345  double HoE = hcalHelper.hcalESum(*sc, 0) / sc->energy();
346  if (HoE >= maxHOverE_)
347  continue;
349 
350  std::vector<edm::Ref<reco::TrackCollection>> trackPairRef;
351  std::vector<math::XYZPointF> trackInnPos;
352  std::vector<math::XYZVectorF> trackPin;
353  std::vector<math::XYZVectorF> trackPout;
354  float minAppDist = -99;
355 
356  //LogDebug("ConvertedPhotonProducer") << "ConvertedPhotonProducer SC energy " << aClus->energy() << " eta " << aClus->eta() << " phi " << aClus->phi() << "\n";
357 
359  const reco::Particle::Point vtx(0, 0, 0);
360 
361  math::XYZVector direction = aClus->position() - vtx;
362  math::XYZVector momentum = direction.unit() * aClus->energy();
363  const reco::Particle::LorentzVector p4(momentum.x(), momentum.y(), momentum.z(), aClus->energy());
364 
365  int nFound = 0;
366  if (!allPairs.empty()) {
367  nFound = 0;
368 
369  for (auto iPair = allPairs.begin(); iPair != allPairs.end(); ++iPair) {
370  scPtrVec.clear();
371 
372  reco::Vertex theConversionVertex;
373  reco::CaloClusterPtr caloPtr = iPair->second;
374  if (!(aClus == caloPtr))
375  continue;
376 
377  scPtrVec.push_back(aClus);
378  nFound++;
379 
380  std::vector<math::XYZPointF> trkPositionAtEcal = theEcalImpactPositionFinder.find(iPair->first, bcHandle);
381  std::vector<reco::CaloClusterPtr> matchingBC = theEcalImpactPositionFinder.matchingBC();
382 
383  minAppDist = -99;
384  const std::string metname = "ConvertedPhotons|ConvertedPhotonProducer";
385  if ((iPair->first).size() > 1) {
386  try {
387  vertexFinder_.run(iPair->first, theConversionVertex);
388 
389  } catch (cms::Exception& e) {
390  //std::cout << " cms::Exception caught in ConvertedPhotonProducer::produce" << "\n" ;
391  edm::LogWarning(metname) << "cms::Exception caught in ConvertedPhotonProducer::produce\n"
392  << e.explainSelf();
393  }
394 
395  // Old TwoTrackMinimumDistance md;
396  // Old md.calculate ( (iPair->first)[0].initialFreeState(), (iPair->first)[1].initialFreeState() );
397  // Old minAppDist = md.distance();
398 
399  /*
400  for ( unsigned int i=0; i< matchingBC.size(); ++i) {
401  if ( matchingBC[i].isNull() ) std::cout << " This ref to BC is null: skipping " << "\n";
402  else
403  std::cout << " BC energy " << matchingBC[i]->energy() << "\n";
404  }
405  */
406 
408  trackPairRef.clear();
409  trackInnPos.clear();
410  trackPin.clear();
411  trackPout.clear();
412 
413  for (std::vector<reco::TransientTrack>::const_iterator iTk = (iPair->first).begin();
414  iTk != (iPair->first).end();
415  ++iTk) {
416  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer Transient Tracks in the pair charge " << iTk->charge() << " Num of RecHits " << iTk->recHitsSize() << " inner momentum " << iTk->track().innerMomentum() << "\n";
417 
418  auto const* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTk->basicTransientTrack());
419  reco::TrackRef myTkRef = ttt->persistentTrackRef();
420 
421  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer Ref to Rec Tracks in the pair charge " << myTkRef->charge() << " Num of RecHits " << myTkRef->recHitsSize() << " inner momentum " << myTkRef->innerMomentum() << "\n";
422  if (myTkRef->extra().isNonnull()) {
423  trackInnPos.push_back(toFConverterP(myTkRef->innerPosition()));
424  trackPin.push_back(toFConverterV(myTkRef->innerMomentum()));
425  trackPout.push_back(toFConverterV(myTkRef->outerMomentum()));
426  }
427  trackPairRef.push_back(myTkRef);
428  }
429 
430  // std::cout << " ConvertedPhotonProducer trackPin size " << trackPin.size() << std::endl;
431  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer SC energy " << aClus->energy() << "\n";
432  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer photon p4 " << p4 << "\n";
433  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer vtx " << vtx.x() << " " << vtx.y() << " " << vtx.z() << "\n";
434  if (theConversionVertex.isValid()) {
435  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer theConversionVertex " << theConversionVertex.position().x() << " " << theConversionVertex.position().y() << " " << theConversionVertex.position().z() << "\n";
436  }
437  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer trackPairRef " << trackPairRef.size() << "\n";
438 
439  minAppDist = calculateMinApproachDistance(trackPairRef[0], trackPairRef[1]);
440 
441  double like = -999.;
442  reco::Conversion newCandidate(scPtrVec,
443  trackPairRef,
444  trkPositionAtEcal,
445  theConversionVertex,
446  matchingBC,
447  minAppDist,
448  trackInnPos,
449  trackPin,
450  trackPout,
451  like,
452  algo);
453  like = likelihoodCalc_.calculateLikelihood(newCandidate);
454  // std::cout << "like = " << like << std::endl;
455  newCandidate.setMVAout(like);
456  outputConvPhotonCollection.push_back(newCandidate);
457 
458  myCands++;
459  //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer Put the ConvertedPhotonCollection a candidate in the Barrel " << "\n";
460 
461  } else {
462  // std::cout << " ConvertedPhotonProducer case with only one track found " << "\n";
463 
464  //std::cout << " ConvertedPhotonProducer recovering one track " << "\n";
465  trackPairRef.clear();
466  trackInnPos.clear();
467  trackPin.clear();
468  trackPout.clear();
469  std::vector<reco::TransientTrack>::const_iterator iTk = (iPair->first).begin();
470  //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";
471  auto const* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTk->basicTransientTrack());
472  reco::TrackRef myTk = ttt->persistentTrackRef();
473  if (myTk->extra().isNonnull()) {
474  trackInnPos.push_back(toFConverterP(myTk->innerPosition()));
475  trackPin.push_back(toFConverterV(myTk->innerMomentum()));
476  trackPout.push_back(toFConverterV(myTk->outerMomentum()));
477  }
478  trackPairRef.push_back(myTk);
479  //std::cout << " Provenance " << myTk->algoName() << std::endl;
480 
481  if (recoverOneTrackCase_) {
482  float theta1 = myTk->innerMomentum().Theta();
483  float dCot = 999.;
484  float dCotTheta = -999.;
485  reco::TrackRef goodRef;
486  for (auto const& tran : t_generalTrk) {
487  auto const* ttt = dynamic_cast<const reco::TrackTransientTrack*>(tran.basicTransientTrack());
488  reco::TrackRef trRef = ttt->persistentTrackRef();
489  if (trRef->charge() * myTk->charge() > 0)
490  continue;
491  float dEta = trRef->eta() - myTk->eta();
492  float dPhi = trRef->phi() - myTk->phi();
494  continue;
495  float theta2 = trRef->innerMomentum().Theta();
496  dCotTheta = 1. / tan(theta1) - 1. / tan(theta2);
497  // std::cout << " ConvertedPhotonProducer recovering general transient track charge " << trRef->charge() << " momentum " << trRef->innerMomentum() << " dcotTheta " << fabs(dCotTheta) << std::endl;
498  if (fabs(dCotTheta) < dCot) {
499  dCot = fabs(dCotTheta);
500  goodRef = trRef;
501  }
502  }
503 
504  if (goodRef.isNonnull()) {
505  minAppDist = calculateMinApproachDistance(myTk, goodRef);
506 
507  // std::cout << " ConvertedPhotonProducer chosen dCotTheta " << fabs(dCotTheta) << std::endl;
508  if (fabs(dCotTheta) < deltaCotCut_ && minAppDist > minApproachDisCut_) {
509  trackInnPos.push_back(toFConverterP(goodRef->innerPosition()));
510  trackPin.push_back(toFConverterV(goodRef->innerMomentum()));
511  trackPout.push_back(toFConverterV(goodRef->outerMomentum()));
512  trackPairRef.push_back(goodRef);
513  // std::cout << " ConvertedPhotonProducer adding opposite charge track from generalTrackCollection charge " << goodRef ->charge() << " pt " << sqrt(goodRef->innerMomentum().perp2()) << " trackPairRef size " << trackPairRef.size() << std::endl;
514  //std::cout << " Track Provenenance " << goodRef->algoName() << std::endl;
515 
516  try {
517  vertexFinder_.run(iPair->first, theConversionVertex);
518 
519  } catch (cms::Exception& e) {
520  //std::cout << " cms::Exception caught in ConvertedPhotonProducer::produce" << "\n" ;
521  edm::LogWarning(metname) << "cms::Exception caught in ConvertedPhotonProducer::produce\n"
522  << e.explainSelf();
523  }
524  }
525  }
526 
527  } // bool On/Off one track case recovery using generalTracks
528  const double like = -999.;
529  outputConvPhotonCollection.emplace_back(scPtrVec,
530  trackPairRef,
531  trkPositionAtEcal,
532  theConversionVertex,
533  matchingBC,
534  minAppDist,
535  trackInnPos,
536  trackPin,
537  trackPout,
538  like,
539  algo);
540  auto& newCandidate = outputConvPhotonCollection.back();
541  newCandidate.setMVAout(likelihoodCalc_.calculateLikelihood(newCandidate));
542 
543  } // case with only on track: looking in general tracks
544  }
545  }
546  }
547 }
548 
551  reco::ConversionCollection& outputConversionCollection) {
552  reco::Conversion* newCandidate = nullptr;
553  for (auto const& aClus : scHandle->ptrs()) {
554  // SC energy preselection
555  if (aClus->energy() / cosh(aClus->eta()) <= minSCEt_)
556  continue;
557 
558  if (conversionHandle.isValid()) {
559  if (risolveAmbiguity_) {
560  std::vector<reco::ConversionRef> bestRef = solveAmbiguity(conversionHandle, aClus);
561 
562  for (std::vector<reco::ConversionRef>::iterator iRef = bestRef.begin(); iRef != bestRef.end(); iRef++) {
563  if (iRef->isNonnull()) {
564  newCandidate = (*iRef)->clone();
565  outputConversionCollection.push_back(*newCandidate);
566  delete newCandidate;
567  }
568  }
569 
570  } else {
571  for (unsigned int icp = 0; icp < conversionHandle->size(); icp++) {
573  if (!(aClus.id() == cpRef->caloCluster()[0].id() && aClus.key() == cpRef->caloCluster()[0].key()))
574  continue;
575  if (!cpRef->isConverted())
576  continue;
577  if (cpRef->nTracks() < 2)
578  continue;
579  newCandidate = (&(*cpRef))->clone();
580  outputConversionCollection.push_back(*newCandidate);
581  delete newCandidate;
582  }
583 
584  } // solve or not the ambiguity of many conversion candidates
585  }
586  }
587 }
588 
589 std::vector<reco::ConversionRef> ConvertedPhotonProducer::solveAmbiguity(
591  std::multimap<double, reco::ConversionRef, std::greater<double>> convMap;
592 
593  for (unsigned int icp = 0; icp < conversionHandle->size(); icp++) {
595 
596  //std::cout << " cpRef " << cpRef->nTracks() << " " << cpRef ->caloCluster()[0]->energy() << std::endl;
597  if (!(scRef.id() == cpRef->caloCluster()[0].id() && scRef.key() == cpRef->caloCluster()[0].key()))
598  continue;
599  if (!cpRef->isConverted())
600  continue;
601  double like = cpRef->MVAout();
602  if (cpRef->nTracks() < 2)
603  continue;
604  // std::cout << " Like " << like << std::endl;
605  convMap.emplace(like, cpRef);
606  }
607 
608  // std::cout << " convMap size " << convMap.size() << std::endl;
609 
610  std::vector<reco::ConversionRef> bestRefs;
611  for (auto iMap = convMap.begin(); iMap != convMap.end(); iMap++) {
612  // std::cout << " Like list in the map " << iMap->first << " " << (iMap->second)->EoverP() << std::endl;
613  bestRefs.push_back(iMap->second);
614  if (int(bestRefs.size()) == maxNumOfCandidates_)
615  break;
616  }
617 
618  return bestRefs;
619 }
620 
622  const reco::TrackRef& track2) {
623  double x1, x2, y1, y2;
624  double xx_1 = track1->innerPosition().x(), yy_1 = track1->innerPosition().y(), zz_1 = track1->innerPosition().z();
625  double xx_2 = track2->innerPosition().x(), yy_2 = track2->innerPosition().y(), zz_2 = track2->innerPosition().z();
626  double radius1 =
627  track1->innerMomentum().Rho() / (.3 * (magneticField_->inTesla(GlobalPoint(xx_1, yy_1, zz_1)).z())) * 100;
628  double radius2 =
629  track2->innerMomentum().Rho() / (.3 * (magneticField_->inTesla(GlobalPoint(xx_2, yy_2, zz_2)).z())) * 100;
630  getCircleCenter(track1, radius1, x1, y1);
631  getCircleCenter(track2, radius2, x2, y2);
632 
633  return std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) - radius1 - radius2;
634 }
635 
636 void ConvertedPhotonProducer::getCircleCenter(const reco::TrackRef& tk, double r, double& x0, double& y0) {
637  double x1, y1, phi;
638  x1 = tk->innerPosition().x(); //inner position and inner momentum need track Extra!
639  y1 = tk->innerPosition().y();
640  phi = tk->innerMomentum().phi();
641  const int charge = tk->charge();
642  x0 = x1 + r * sin(phi) * charge;
643  y0 = y1 - r * cos(phi) * charge;
644 }
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
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:158
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.
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
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:539
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_
edm::EDGetTokenT< reco::TrackCaloClusterPtrAssociation > inOutTrackSCAssociationCollection_
std::vector< math::XYZPointF > find(const std::vector< reco::TransientTrack > &tracks, const edm::Handle< edm::View< reco::CaloCluster > > &bcHandle)
bool getData(T &iHolder) const
Definition: EventSetup.h:122
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:433
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:563
key_type key() const
Definition: Ptr.h:163
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)