00001 #include <iostream>
00002 #include <vector>
00003 #include <memory>
00004
00005
00006 #include "FWCore/Framework/interface/Event.h"
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "DataFormats/Common/interface/Handle.h"
00009 #include "FWCore/Framework/interface/ESHandle.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include "FWCore/Utilities/interface/Exception.h"
00012
00013 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
00014 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00015 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
00016
00017
00018 #include "DataFormats/EgammaTrackReco/interface/TrackCaloClusterAssociation.h"
00019 #include "DataFormats/EgammaCandidates/interface/Photon.h"
00020 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
00021 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
00022 #include "DataFormats/EgammaCandidates/interface/ConversionFwd.h"
00023 #include "DataFormats/TrackReco/interface/Track.h"
00024 #include "DataFormats/TrackReco/interface/TrackExtra.h"
00025 #include "DataFormats/VertexReco/interface/Vertex.h"
00026 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00027
00028 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00029
00030 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00031
00032 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionTrackEcalImpactPoint.h"
00033 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionTrackPairFinder.h"
00034 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionVertexFinder.h"
00035 #include "RecoEgamma/EgammaPhotonProducers/interface/ConvertedPhotonProducer.h"
00036
00037 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00038 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00039
00040 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00041 #include "TrackingTools/TransientTrack/interface/TrackTransientTrack.h"
00042 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h"
00043 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00044 #include "RecoEgamma/EgammaIsolationAlgos/interface/EgammaTowerIsolation.h"
00045
00046 ConvertedPhotonProducer::ConvertedPhotonProducer(const edm::ParameterSet& config) :
00047 conf_(config),
00048 theTrackPairFinder_(0),
00049 theVertexFinder_(0),
00050 theLikelihoodCalc_(0)
00051 {
00052
00053
00054
00055
00056
00057
00058
00059
00060 bcBarrelCollection_ = conf_.getParameter<edm::InputTag>("bcBarrelCollection");
00061 bcEndcapCollection_ = conf_.getParameter<edm::InputTag>("bcEndcapCollection");
00062
00063 scHybridBarrelProducer_ = conf_.getParameter<edm::InputTag>("scHybridBarrelProducer");
00064 scIslandEndcapProducer_ = conf_.getParameter<edm::InputTag>("scIslandEndcapProducer");
00065
00066 conversionOITrackProducer_ = conf_.getParameter<std::string>("conversionOITrackProducer");
00067 conversionIOTrackProducer_ = conf_.getParameter<std::string>("conversionIOTrackProducer");
00068
00069 outInTrackSCAssociationCollection_ = conf_.getParameter<std::string>("outInTrackSCAssociation");
00070 inOutTrackSCAssociationCollection_ = conf_.getParameter<std::string>("inOutTrackSCAssociation");
00071
00072 algoName_ = conf_.getParameter<std::string>( "AlgorithmName" );
00073
00074 hcalTowers_ = conf_.getParameter<edm::InputTag>("hcalTowers");
00075 hOverEConeSize_ = conf_.getParameter<double>("hOverEConeSize");
00076 maxHOverE_ = conf_.getParameter<double>("maxHOverE");
00077 minSCEt_ = conf_.getParameter<double>("minSCEt");
00078 recoverOneTrackCase_ = conf_.getParameter<bool>( "recoverOneTrackCase" );
00079 dRForConversionRecovery_ = conf_.getParameter<double>("dRForConversionRecovery");
00080 deltaCotCut_ = conf_.getParameter<double>("deltaCotCut");
00081 minApproachDisCut_ = conf_.getParameter<double>("minApproachDisCut");
00082
00083 maxNumOfCandidates_ = conf_.getParameter<int>("maxNumOfCandidates");
00084 risolveAmbiguity_ = conf_.getParameter<bool>("risolveConversionAmbiguity");
00085 likelihoodWeights_= conf_.getParameter<std::string>("MVA_weights_location");
00086
00087
00088
00089 ConvertedPhotonCollection_ = conf_.getParameter<std::string>("convertedPhotonCollection");
00090 CleanedConvertedPhotonCollection_ = conf_.getParameter<std::string>("cleanedConvertedPhotonCollection");
00091
00092
00093
00094 produces< reco::ConversionCollection >(ConvertedPhotonCollection_);
00095 produces< reco::ConversionCollection >(CleanedConvertedPhotonCollection_);
00096
00097
00098 theTrackPairFinder_ = new ConversionTrackPairFinder ();
00099 edm::FileInPath path_mvaWeightFile(likelihoodWeights_.c_str() );
00100 theLikelihoodCalc_ = new ConversionLikelihoodCalculator();
00101 theLikelihoodCalc_->setWeightsFile(path_mvaWeightFile.fullPath().c_str());
00102
00103 theVertexFinder_ = new ConversionVertexFinder ( conf_);
00104
00105
00106
00107 nEvt_=0;
00108
00109 }
00110
00111 ConvertedPhotonProducer::~ConvertedPhotonProducer() {
00112 delete theTrackPairFinder_;
00113 delete theLikelihoodCalc_;
00114 delete theVertexFinder_;
00115 }
00116
00117
00118
00119 void ConvertedPhotonProducer::beginRun (edm::Run& r, edm::EventSetup const & theEventSetup) {
00120
00121
00122
00123
00124 theEventSetup.get<IdealMagneticFieldRecord>().get(theMF_);
00125
00126
00127 theEventSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",theTransientTrackBuilder_);
00128
00129
00130 }
00131
00132
00133 void ConvertedPhotonProducer::endRun (edm::Run& r, edm::EventSetup const & theEventSetup) {
00134 }
00135
00136
00137 void ConvertedPhotonProducer::endJob () {
00138
00139
00140
00141
00142
00143 }
00144
00145
00146
00147 void ConvertedPhotonProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) {
00148
00149 using namespace edm;
00150 nEvt_++;
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 reco::ConversionCollection outputConvPhotonCollection;
00161 std::auto_ptr<reco::ConversionCollection> outputConvPhotonCollection_p(new reco::ConversionCollection);
00162
00163 reco::ConversionCollection cleanedConversionCollection;
00164 std::auto_ptr<reco::ConversionCollection> cleanedConversionCollection_p(new reco::ConversionCollection);
00165
00166
00167
00168 bool validBarrelSCHandle=true;
00169 edm::Handle<edm::View<reco::CaloCluster> > scBarrelHandle;
00170 theEvent.getByLabel(scHybridBarrelProducer_,scBarrelHandle);
00171 if (!scBarrelHandle.isValid()) {
00172 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product "<<scHybridBarrelProducer_.label();
00173 validBarrelSCHandle=false;
00174 }
00175
00176
00177 bool validEndcapSCHandle=true;
00178 edm::Handle<edm::View<reco::CaloCluster> > scEndcapHandle;
00179 theEvent.getByLabel(scIslandEndcapProducer_,scEndcapHandle);
00180 if (!scEndcapHandle.isValid()) {
00181 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product "<<scIslandEndcapProducer_.label();
00182 validEndcapSCHandle=false;
00183 }
00184
00185
00187 bool validTrackInputs=true;
00188 Handle<reco::TrackCollection> outInTrkHandle;
00189 theEvent.getByLabel(conversionOITrackProducer_, outInTrkHandle);
00190 if (!outInTrkHandle.isValid()) {
00191
00192 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the conversionOITrack " << "\n";
00193 validTrackInputs=false;
00194 }
00195
00196
00197
00199 Handle<reco::TrackCaloClusterPtrAssociation> outInTrkSCAssocHandle;
00200 theEvent.getByLabel( conversionOITrackProducer_, outInTrackSCAssociationCollection_, outInTrkSCAssocHandle);
00201 if (!outInTrkSCAssocHandle.isValid()) {
00202
00203 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product " << outInTrackSCAssociationCollection_.c_str() <<"\n";
00204 validTrackInputs=false;
00205 }
00206
00208 Handle<reco::TrackCollection> inOutTrkHandle;
00209 theEvent.getByLabel(conversionIOTrackProducer_, inOutTrkHandle);
00210 if (!inOutTrkHandle.isValid()) {
00211
00212 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the conversionIOTrack " << "\n";
00213 validTrackInputs=false;
00214 }
00215
00216
00217
00219
00220 Handle<reco::TrackCollection> generalTrkHandle;
00221 if ( recoverOneTrackCase_ ) {
00222 theEvent.getByLabel("generalTracks", generalTrkHandle);
00223 if (!generalTrkHandle.isValid()) {
00224
00225 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the genralTracks " << "\n";
00226 }
00227 }
00228
00230 Handle<reco::TrackCaloClusterPtrAssociation> inOutTrkSCAssocHandle;
00231 theEvent.getByLabel( conversionIOTrackProducer_, inOutTrackSCAssociationCollection_, inOutTrkSCAssocHandle);
00232 if (!inOutTrkSCAssocHandle.isValid()) {
00233
00234 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product " << inOutTrackSCAssociationCollection_.c_str() <<"\n";
00235 validTrackInputs=false;
00236 }
00237
00238
00239
00240
00241
00242 edm::Handle<edm::View<reco::CaloCluster> > bcBarrelHandle;
00243 theEvent.getByLabel( bcBarrelCollection_, bcBarrelHandle);
00244 if (!bcBarrelHandle.isValid()) {
00245 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product "<<bcBarrelCollection_.label();
00246 }
00247
00248
00249
00250 edm::Handle<edm::View<reco::CaloCluster> > bcEndcapHandle;
00251 theEvent.getByLabel( bcEndcapCollection_, bcEndcapHandle);
00252 if (!bcEndcapHandle.isValid()) {
00253 edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product "<<bcEndcapCollection_.label();
00254 }
00255
00256
00257
00258 Handle<CaloTowerCollection> hcalTowersHandle;
00259 theEvent.getByLabel(hcalTowers_, hcalTowersHandle);
00260
00261
00262 theEventSetup.get<CaloGeometryRecord>().get(theCaloGeom_);
00263
00264
00265 if ( validTrackInputs ) {
00266
00267 std::vector<reco::TransientTrack> t_outInTrk = ( *theTransientTrackBuilder_ ).build(outInTrkHandle );
00268 std::vector<reco::TransientTrack> t_inOutTrk = ( *theTransientTrackBuilder_ ).build(inOutTrkHandle );
00269
00270
00272 std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr, CompareTwoTracksVectors> allPairs;
00273 allPairs = theTrackPairFinder_->run(t_outInTrk, outInTrkHandle, outInTrkSCAssocHandle, t_inOutTrk, inOutTrkHandle, inOutTrkSCAssocHandle );
00274
00275
00276 buildCollections(theEventSetup, scBarrelHandle, bcBarrelHandle, hcalTowersHandle, generalTrkHandle, allPairs, outputConvPhotonCollection);
00277 buildCollections(theEventSetup, scEndcapHandle, bcEndcapHandle, hcalTowersHandle, generalTrkHandle, allPairs, outputConvPhotonCollection);
00278 }
00279
00280
00281 outputConvPhotonCollection_p->assign(outputConvPhotonCollection.begin(),outputConvPhotonCollection.end());
00282
00283 const edm::OrphanHandle<reco::ConversionCollection> conversionHandle= theEvent.put( outputConvPhotonCollection_p, ConvertedPhotonCollection_);
00284
00285
00286
00287 if ( validBarrelSCHandle) cleanCollections(scBarrelHandle,
00288 conversionHandle,
00289 cleanedConversionCollection);
00290 if ( validEndcapSCHandle) cleanCollections(scEndcapHandle,
00291 conversionHandle,
00292 cleanedConversionCollection);
00293
00294
00295 cleanedConversionCollection_p->assign(cleanedConversionCollection.begin(),cleanedConversionCollection.end());
00296 theEvent.put( cleanedConversionCollection_p, CleanedConvertedPhotonCollection_);
00297
00298
00299 }
00300
00301
00302 void ConvertedPhotonProducer::buildCollections ( edm::EventSetup const & es,
00303 const edm::Handle<edm::View<reco::CaloCluster> > & scHandle,
00304 const edm::Handle<edm::View<reco::CaloCluster> > & bcHandle,
00305 const edm::Handle<CaloTowerCollection> & hcalTowersHandle,
00306 const edm::Handle<reco::TrackCollection> & generalTrkHandle,
00307 std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr, CompareTwoTracksVectors>& allPairs,
00308 reco::ConversionCollection & outputConvPhotonCollection)
00309
00310 {
00311
00312
00313 ConversionTrackEcalImpactPoint theEcalImpactPositionFinder( &(*theMF_) );
00314
00315
00316 reco::Conversion::ConversionAlgorithm algo = reco::Conversion::algoByName(algoName_);
00317
00318 std::vector<reco::TransientTrack> t_generalTrk;
00319 if ( recoverOneTrackCase_ ) t_generalTrk = ( *theTransientTrackBuilder_ ).build(generalTrkHandle );
00320
00321
00322
00323 int myCands=0;
00324 reco::CaloClusterPtrVector scPtrVec;
00325 for (unsigned i = 0; i < scHandle->size(); ++i ) {
00326 reco::CaloClusterPtr aClus= scHandle->ptrAt(i);
00327
00328
00329 if (aClus->energy()/cosh(aClus->eta()) <= minSCEt_) continue;
00330 const reco::CaloCluster* pClus=&(*aClus);
00331 const reco::SuperCluster* sc=dynamic_cast<const reco::SuperCluster*>(pClus);
00332 const CaloTowerCollection* hcalTowersColl = hcalTowersHandle.product();
00333 EgammaTowerIsolation towerIso(hOverEConeSize_,0.,0.,-1,hcalTowersColl) ;
00334 double HoE=towerIso.getTowerESum(sc)/sc->energy();
00335 if (HoE>=maxHOverE_) continue;
00337
00338
00339 std::vector<edm::Ref<reco::TrackCollection> > trackPairRef;
00340 std::vector<math::XYZPointF> trackInnPos;
00341 std::vector<math::XYZVectorF> trackPin;
00342 std::vector<math::XYZVectorF> trackPout;
00343 float minAppDist=-99;
00344
00345
00346
00347
00349 const reco::Particle::Point vtx( 0, 0, 0 );
00350
00351
00352 math::XYZVector direction =aClus->position() - vtx;
00353 math::XYZVector momentum = direction.unit() * aClus->energy();
00354 const reco::Particle::LorentzVector p4(momentum.x(), momentum.y(), momentum.z(), aClus->energy() );
00355
00356 int nFound=0;
00357 if ( allPairs.size() ) {
00358
00359 nFound=0;
00360
00361
00362 for ( std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr>::const_iterator iPair= allPairs.begin(); iPair!= allPairs.end(); ++iPair ) {
00363 scPtrVec.clear();
00364
00365 reco::Vertex theConversionVertex;
00366 reco::CaloClusterPtr caloPtr=iPair->second;
00367 if ( !( aClus == caloPtr ) ) continue;
00368
00369 scPtrVec.push_back(aClus);
00370 nFound++;
00371
00372 std::vector<math::XYZPointF> trkPositionAtEcal = theEcalImpactPositionFinder.find( iPair->first, bcHandle );
00373 std::vector<reco::CaloClusterPtr> matchingBC = theEcalImpactPositionFinder.matchingBC();
00374
00375
00376 minAppDist=-99;
00377 const std::string metname = "ConvertedPhotons|ConvertedPhotonProducer";
00378 if ( (iPair->first).size() > 1 ) {
00379 try{
00380
00381 theVertexFinder_->run(iPair->first, theConversionVertex );
00382
00383
00384 }
00385 catch ( cms::Exception& e ) {
00386
00387 edm::LogWarning(metname) << "cms::Exception caught in ConvertedPhotonProducer::produce\n"
00388 << e.explainSelf();
00389
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00412 trackPairRef.clear();
00413 trackInnPos.clear();
00414 trackPin.clear();
00415 trackPout.clear();
00416
00417
00418 for ( std::vector<reco::TransientTrack>::const_iterator iTk=(iPair->first).begin(); iTk!= (iPair->first).end(); ++iTk) {
00419
00420
00421 const reco::TrackTransientTrack* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTk->basicTransientTrack());
00422 reco::TrackRef myTkRef= ttt->persistentTrackRef();
00423
00424
00425 if ( myTkRef->extra().isNonnull() ) {
00426 trackInnPos.push_back( toFConverterP(myTkRef->innerPosition()));
00427 trackPin.push_back( toFConverterV( myTkRef->innerMomentum()));
00428 trackPout.push_back( toFConverterV(myTkRef->outerMomentum()));
00429 }
00430 trackPairRef.push_back(myTkRef);
00431
00432 }
00433
00434
00435
00436
00437
00438 if( theConversionVertex.isValid() ) {
00439
00440
00441
00442 }
00443
00444
00445
00446 minAppDist=calculateMinApproachDistance( trackPairRef[0], trackPairRef[1]);
00447
00448 double like = -999.;
00449 reco::Conversion newCandidate(scPtrVec, trackPairRef, trkPositionAtEcal, theConversionVertex, matchingBC, minAppDist, trackInnPos, trackPin, trackPout, like, algo);
00450
00451 like = theLikelihoodCalc_->calculateLikelihood( newCandidate );
00452
00453 newCandidate.setMVAout(like);
00454 outputConvPhotonCollection.push_back(newCandidate);
00455
00456
00457 myCands++;
00458
00459
00460 } else {
00461
00462
00463
00464
00465
00466 trackPairRef.clear();
00467 trackInnPos.clear();
00468 trackPin.clear();
00469 trackPout.clear();
00470 std::vector<reco::TransientTrack>::const_iterator iTk=(iPair->first).begin();
00471
00472 const reco::TrackTransientTrack* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTk->basicTransientTrack());
00473 reco::TrackRef myTk= ttt->persistentTrackRef();
00474 if ( myTk->extra().isNonnull() ) {
00475 trackInnPos.push_back( toFConverterP(myTk->innerPosition()));
00476 trackPin.push_back( toFConverterV(myTk->innerMomentum()));
00477 trackPout.push_back( toFConverterV(myTk->outerMomentum()));
00478 }
00479 trackPairRef.push_back(myTk);
00480
00481
00482 if ( recoverOneTrackCase_ ) {
00483 float theta1 = myTk->innerMomentum().Theta();
00484 float dCot=999.;
00485 float dCotTheta=-999.;
00486 reco::TrackRef goodRef;
00487 std::vector<reco::TransientTrack>::const_iterator iGoodGenTran;
00488 for ( std::vector<reco::TransientTrack>::const_iterator iTran= t_generalTrk.begin(); iTran != t_generalTrk.end(); ++iTran) {
00489 const reco::TrackTransientTrack* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTran->basicTransientTrack());
00490 reco::TrackRef trRef= ttt->persistentTrackRef();
00491 if ( trRef->charge()*myTk->charge() > 0 ) continue;
00492 float dEta = trRef->eta() - myTk->eta();
00493 float dPhi = trRef->phi() - myTk->phi();
00494 if ( sqrt (dEta*dEta + dPhi*dPhi) > dRForConversionRecovery_ ) continue;
00495 float theta2 = trRef->innerMomentum().Theta();
00496 dCotTheta = 1./tan(theta1) - 1./tan(theta2) ;
00497
00498 if ( fabs(dCotTheta) < dCot ) {
00499 dCot = fabs(dCotTheta);
00500 goodRef = trRef;
00501 iGoodGenTran=iTran;
00502 }
00503 }
00504
00505 if ( goodRef.isNonnull() ) {
00506
00507 minAppDist=calculateMinApproachDistance( myTk, goodRef);
00508
00509
00510 if ( fabs(dCotTheta) < deltaCotCut_ && minAppDist > minApproachDisCut_ ) {
00511 trackInnPos.push_back( toFConverterP(goodRef->innerPosition()));
00512 trackPin.push_back( toFConverterV(goodRef->innerMomentum()));
00513 trackPout.push_back( toFConverterV(goodRef->outerMomentum()));
00514 trackPairRef.push_back( goodRef );
00515
00516
00517 std::vector<reco::TransientTrack> mypair;
00518 mypair.push_back(*iTk);
00519 mypair.push_back(*iGoodGenTran);
00520
00521 try{
00522 theVertexFinder_->run(iPair->first, theConversionVertex );
00523
00524 }
00525 catch ( cms::Exception& e ) {
00526
00527 edm::LogWarning(metname) << "cms::Exception caught in ConvertedPhotonProducer::produce\n"
00528 << e.explainSelf();
00529
00530 }
00531 }
00532
00533 }
00534
00535 }
00536 double like = -999.;
00537 reco::Conversion newCandidate(scPtrVec, trackPairRef, trkPositionAtEcal, theConversionVertex, matchingBC, minAppDist, trackInnPos, trackPin, trackPout, like, algo);
00538 like = theLikelihoodCalc_->calculateLikelihood(newCandidate);
00539 newCandidate.setMVAout(like);
00540 outputConvPhotonCollection.push_back(newCandidate);
00541
00542
00543
00544
00545 }
00546
00547
00548
00549
00550 }
00551
00552 }
00553
00554
00555
00556
00557 }
00558
00559
00560
00561
00562
00563 }
00564
00565
00566 void ConvertedPhotonProducer::cleanCollections(const edm::Handle<edm::View<reco::CaloCluster> > & scHandle,
00567 const edm::OrphanHandle<reco::ConversionCollection> & conversionHandle,
00568 reco::ConversionCollection & outputConversionCollection) {
00569
00570
00571 reco::Conversion* newCandidate=0;
00572 for(unsigned int lSC=0; lSC < scHandle->size(); lSC++) {
00573
00574
00575 reco::CaloClusterPtr aClus= scHandle->ptrAt(lSC);
00576
00577
00578 if (aClus->energy()/cosh(aClus->eta()) <= minSCEt_) continue;
00579
00580
00581 if ( conversionHandle.isValid() ) {
00582
00583 if ( risolveAmbiguity_ ) {
00584 std::vector<reco::ConversionRef> bestRef=solveAmbiguity( conversionHandle , aClus);
00585
00586 for ( std::vector<reco::ConversionRef>::iterator iRef=bestRef.begin(); iRef!=bestRef.end(); iRef++ ) {
00587 if ( iRef->isNonnull() ) {
00588 newCandidate= (*iRef)->clone();
00589 outputConversionCollection.push_back(*newCandidate);
00590 delete newCandidate;
00591 }
00592 }
00593
00594 } else {
00595
00596
00597 for( unsigned int icp = 0; icp < conversionHandle->size(); icp++) {
00598 reco::ConversionRef cpRef(reco::ConversionRef(conversionHandle,icp));
00599 if (!( aClus.id() == cpRef->caloCluster()[0].id() && aClus.key() == cpRef->caloCluster()[0].key() )) continue;
00600 if ( !cpRef->isConverted() ) continue;
00601 if ( cpRef->nTracks() <2 ) continue;
00602 newCandidate= (&(*cpRef))->clone();
00603 outputConversionCollection.push_back(*newCandidate);
00604 delete newCandidate;
00605
00606 }
00607
00608 }
00609
00610 }
00611
00612
00613 }
00614 }
00615
00616
00617
00618
00619 std::vector<reco::ConversionRef> ConvertedPhotonProducer::solveAmbiguity(const edm::OrphanHandle<reco::ConversionCollection> & conversionHandle, reco::CaloClusterPtr& scRef) {
00620 std::multimap<double, reco::ConversionRef, std::greater<double> > convMap;
00621
00622 for ( unsigned int icp=0; icp< conversionHandle->size(); icp++) {
00623 reco::ConversionRef cpRef(reco::ConversionRef(conversionHandle,icp));
00624
00625
00626 if (!( scRef.id() == cpRef->caloCluster()[0].id() && scRef.key() == cpRef->caloCluster()[0].key() )) continue;
00627 if ( !cpRef->isConverted() ) continue;
00628 double like = cpRef->MVAout();
00629 if ( cpRef->nTracks() <2 ) continue;
00630
00631 convMap.insert ( std::make_pair(like,cpRef) );
00632
00633 }
00634
00635
00636
00637 std::multimap<double, reco::ConversionRef>::iterator iMap;
00638 std::vector<reco::ConversionRef> bestRefs;
00639 for (iMap=convMap.begin(); iMap!=convMap.end(); iMap++) {
00640
00641 bestRefs.push_back( iMap->second );
00642 if ( int(bestRefs.size()) == maxNumOfCandidates_ ) break;
00643 }
00644
00645
00646 return bestRefs;
00647
00648
00649 }
00650
00651
00652
00653
00654
00655 float ConvertedPhotonProducer::calculateMinApproachDistance ( const reco::TrackRef& track1, const reco::TrackRef& track2) {
00656 float dist=9999.;
00657
00658 double x1, x2, y1, y2;
00659 double xx_1 = track1->innerPosition().x(), yy_1 = track1->innerPosition().y(), zz_1 = track1->innerPosition().z();
00660 double xx_2 = track2->innerPosition().x(), yy_2 = track2->innerPosition().y(), zz_2 = track2->innerPosition().z();
00661 double radius1 = track1->innerMomentum().Rho()/(.3*(theMF_->inTesla(GlobalPoint(xx_1, yy_1, zz_1)).z()))*100;
00662 double radius2 = track2->innerMomentum().Rho()/(.3*(theMF_->inTesla(GlobalPoint(xx_2, yy_2, zz_2)).z()))*100;
00663 getCircleCenter(track1, radius1, x1, y1);
00664 getCircleCenter(track2, radius2, x2, y2);
00665 dist = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) - radius1 - radius2;
00666
00667 return dist;
00668
00669 }
00670
00671
00672 void ConvertedPhotonProducer::getCircleCenter(const reco::TrackRef& tk, double r, double& x0, double& y0){
00673 double x1, y1, phi;
00674 x1 = tk->innerPosition().x();
00675 y1 = tk->innerPosition().y();
00676 phi = tk->innerMomentum().phi();
00677 const int charge = tk->charge();
00678 x0 = x1 + r*sin(phi)*charge;
00679 y0 = y1 - r*cos(phi)*charge;
00680
00681 }