CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/RecoEgamma/EgammaPhotonProducers/src/ConvertedPhotonProducer.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <vector>
00003 #include <memory>
00004 
00005 // Framework
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   //cout<< " ConvertedPhotonProducer CTOR " << "\n";
00056   
00057   
00058   
00059   // use onfiguration file to setup input collection names
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   // use onfiguration file to setup output collection names
00089   ConvertedPhotonCollection_     = conf_.getParameter<std::string>("convertedPhotonCollection");
00090   CleanedConvertedPhotonCollection_     = conf_.getParameter<std::string>("cleanedConvertedPhotonCollection");
00091   
00092   
00093   // Register the product
00094   produces< reco::ConversionCollection >(ConvertedPhotonCollection_);
00095   produces< reco::ConversionCollection >(CleanedConvertedPhotonCollection_);
00096   
00097   // instantiate the Track Pair Finder algorithm
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   // instantiate the Vertex Finder algorithm
00103   theVertexFinder_ = new ConversionVertexFinder ( conf_);
00104 
00105 
00106   // Inizilize my global event counter
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     //get magnetic field
00123   //edm::LogInfo("ConvertedPhotonProducer") << " get magnetic field" << "\n";
00124   theEventSetup.get<IdealMagneticFieldRecord>().get(theMF_);  
00125 
00126   // Transform Track into TransientTrack (needed by the Vertex fitter)
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   //LogDebug("ConvertedPhotonProducer") << "ConvertedPhotonProducer::endJob Processed " << nEvt_ << " events " << "\n";
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   //  LogDebug("ConvertedPhotonProducer")   << "ConvertedPhotonProduce::produce event number " <<   theEvent.id() << " Global counter " << nEvt_ << "\n";
00154   //  std::cout    << "ConvertedPhotonProduce::produce event number " <<   theEvent.id() << " Global counter " << nEvt_ << "\n";
00155   
00156   //
00157   // create empty output collections
00158   //
00159   // Converted photon candidates
00160   reco::ConversionCollection outputConvPhotonCollection;
00161   std::auto_ptr<reco::ConversionCollection> outputConvPhotonCollection_p(new reco::ConversionCollection);
00162   // Converted photon candidates
00163   reco::ConversionCollection cleanedConversionCollection;
00164   std::auto_ptr<reco::ConversionCollection> cleanedConversionCollection_p(new reco::ConversionCollection);
00165 
00166   
00167   // Get the Super Cluster collection in the Barrel
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   // Get the Super Cluster collection in the Endcap
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     //std::cout << "Error! Can't get the conversionOITrack " << "\n";
00192     edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the conversionOITrack " << "\n";
00193     validTrackInputs=false;
00194   }
00195   //  LogDebug("ConvertedPhotonProducer")<< "ConvertedPhotonProducer  outInTrack collection size " << (*outInTrkHandle).size() << "\n";
00196   
00197    
00199   Handle<reco::TrackCaloClusterPtrAssociation> outInTrkSCAssocHandle;
00200   theEvent.getByLabel( conversionOITrackProducer_, outInTrackSCAssociationCollection_, outInTrkSCAssocHandle);
00201   if (!outInTrkSCAssocHandle.isValid()) {
00202     //  std::cout << "Error! Can't get the product " <<  outInTrackSCAssociationCollection_.c_str() <<"\n";
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     // std::cout << "Error! Can't get the conversionIOTrack " << "\n";
00212     edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the conversionIOTrack " << "\n";
00213     validTrackInputs=false;
00214   }
00215   //  LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer inOutTrack collection size " << (*inOutTrkHandle).size() << "\n";
00216 
00217 
00219 
00220   Handle<reco::TrackCollection> generalTrkHandle;
00221   if (  recoverOneTrackCase_ ) {
00222     theEvent.getByLabel("generalTracks", generalTrkHandle);
00223     if (!generalTrkHandle.isValid()) {
00224       //std::cout << "Error! Can't get the genralTracks " << "\n";
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     //std::cout << "Error! Can't get the product " <<  inOutTrackSCAssociationCollection_.c_str() <<"\n";
00234     edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product " <<  inOutTrackSCAssociationCollection_.c_str() <<"\n";
00235     validTrackInputs=false;
00236   }
00237 
00238 
00239   
00240 
00241   // Get the basic cluster collection in the Barrel 
00242   bool validBarrelBCHandle=true;
00243   edm::Handle<edm::View<reco::CaloCluster> > bcBarrelHandle;
00244   theEvent.getByLabel( bcBarrelCollection_, bcBarrelHandle);
00245   if (!bcBarrelHandle.isValid()) {
00246     edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product "<<bcBarrelCollection_.label();
00247      validBarrelBCHandle=false;
00248   }
00249 
00250     
00251   // Get the basic cluster collection in the Endcap 
00252   bool validEndcapBCHandle=true;
00253   edm::Handle<edm::View<reco::CaloCluster> > bcEndcapHandle;
00254   theEvent.getByLabel( bcEndcapCollection_, bcEndcapHandle);
00255   if (!bcEndcapHandle.isValid()) {
00256     edm::LogError("ConvertedPhotonProducer") << "Error! Can't get the product "<<bcEndcapCollection_.label();
00257     validEndcapBCHandle=true;
00258   }
00259  
00260 
00261 // get Hcal towers collection 
00262   Handle<CaloTowerCollection> hcalTowersHandle;
00263   theEvent.getByLabel(hcalTowers_, hcalTowersHandle);
00264 
00265   // get the geometry from the event setup:
00266   theEventSetup.get<CaloGeometryRecord>().get(theCaloGeom_);
00267 
00268 
00269   if (  validTrackInputs ) {
00270     //do the conversion:
00271     std::vector<reco::TransientTrack> t_outInTrk = ( *theTransientTrackBuilder_ ).build(outInTrkHandle );
00272     std::vector<reco::TransientTrack> t_inOutTrk = ( *theTransientTrackBuilder_ ).build(inOutTrkHandle );
00273     
00274     
00276     //  std::map<std::vector<reco::TransientTrack>, const reco::SuperCluster*> allPairs;
00277     std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr> allPairs;
00278     allPairs = theTrackPairFinder_->run(t_outInTrk, outInTrkHandle, outInTrkSCAssocHandle, t_inOutTrk, inOutTrkHandle, inOutTrkSCAssocHandle  );
00279     //LogDebug("ConvertedPhotonProducer")  << "ConvertedPhotonProducer  allPairs.size " << allPairs.size() << "\n";      
00280 
00281     buildCollections(theEventSetup, scBarrelHandle, bcBarrelHandle, hcalTowersHandle, generalTrkHandle, allPairs, outputConvPhotonCollection);
00282     buildCollections(theEventSetup, scEndcapHandle, bcEndcapHandle, hcalTowersHandle, generalTrkHandle, allPairs, outputConvPhotonCollection);
00283   }
00284   
00285   // put the product in the event
00286   outputConvPhotonCollection_p->assign(outputConvPhotonCollection.begin(),outputConvPhotonCollection.end());
00287   //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer Putting in the event    converted photon candidates " << (*outputConvPhotonCollection_p).size() << "\n";  
00288   const edm::OrphanHandle<reco::ConversionCollection> conversionHandle= theEvent.put( outputConvPhotonCollection_p, ConvertedPhotonCollection_);
00289 
00290 
00291   // Loop over barrel and endcap SC collections and fill the  photon collection
00292   if ( validBarrelSCHandle) cleanCollections(scBarrelHandle,
00293                                              conversionHandle,
00294                                              cleanedConversionCollection);
00295   if ( validEndcapSCHandle) cleanCollections(scEndcapHandle,
00296                                              conversionHandle,
00297                                              cleanedConversionCollection);
00298                                                 
00299 
00300   cleanedConversionCollection_p->assign(cleanedConversionCollection.begin(),cleanedConversionCollection.end());   
00301   theEvent.put( cleanedConversionCollection_p, CleanedConvertedPhotonCollection_);
00302 
00303   
00304 }
00305 
00306 
00307 void ConvertedPhotonProducer::buildCollections ( edm::EventSetup const & es,  
00308                                                  const edm::Handle<edm::View<reco::CaloCluster> > & scHandle,
00309                                                  const edm::Handle<edm::View<reco::CaloCluster> > & bcHandle,
00310                                                  const edm::Handle<CaloTowerCollection> & hcalTowersHandle, 
00311                                                  const edm::Handle<reco::TrackCollection>  & generalTrkHandle,
00312                                                  std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr>& allPairs,
00313                                                  reco::ConversionCollection & outputConvPhotonCollection)
00314 
00315 {
00316 
00317  // instantiate the algorithm for finding the position of the track extrapolation at the Ecal front face
00318   ConversionTrackEcalImpactPoint theEcalImpactPositionFinder( &(*theMF_) );
00319   
00320 
00321   reco::Conversion::ConversionAlgorithm algo = reco::Conversion::algoByName(algoName_);
00322  
00323   std::vector<reco::TransientTrack> t_generalTrk;
00324   if (  recoverOneTrackCase_ )  t_generalTrk = ( *theTransientTrackBuilder_ ).build(generalTrkHandle );
00325   //const CaloGeometry* geometry = theCaloGeom_.product(); 
00326 
00327   //  Loop over SC in the barrel and reconstruct converted photons
00328   int myCands=0;
00329   reco::CaloClusterPtrVector scPtrVec;
00330   for (unsigned i = 0; i < scHandle->size(); ++i ) {
00331     reco::CaloClusterPtr aClus= scHandle->ptrAt(i);
00332 
00333     // preselection based in Et and H/E cut
00334     if (aClus->energy()/cosh(aClus->eta()) <= minSCEt_) continue;
00335     const reco::CaloCluster* pClus=&(*aClus);
00336     const reco::SuperCluster*  sc=dynamic_cast<const reco::SuperCluster*>(pClus);
00337     const CaloTowerCollection* hcalTowersColl = hcalTowersHandle.product();
00338     EgammaTowerIsolation towerIso(hOverEConeSize_,0.,0.,-1,hcalTowersColl) ;
00339     double HoE=towerIso.getTowerESum(sc)/sc->energy();
00340     if (HoE>=maxHOverE_)  continue;
00342 
00343 
00344     std::vector<edm::Ref<reco::TrackCollection> > trackPairRef;
00345     std::vector<math::XYZPointF> trackInnPos;
00346     std::vector<math::XYZVectorF> trackPin;
00347     std::vector<math::XYZVectorF> trackPout;
00348     float minAppDist=-99;
00349 
00350     //LogDebug("ConvertedPhotonProducer") << "ConvertedPhotonProducer SC energy " << aClus->energy() << " eta " <<  aClus->eta() << " phi " <<  aClus->phi() << "\n";
00351 
00352     
00354     const reco::Particle::Point  vtx( 0, 0, 0 );
00355     reco::Vertex  theConversionVertex;
00356    
00357     math::XYZVector direction =aClus->position() - vtx;
00358     math::XYZVector momentum = direction.unit() * aClus->energy();
00359     const reco::Particle::LorentzVector  p4(momentum.x(), momentum.y(), momentum.z(), aClus->energy() );
00360     
00361     int nFound=0;    
00362     if ( allPairs.size() ) {
00363 
00364       nFound=0;
00365 
00366 
00367       for (  std::map<std::vector<reco::TransientTrack>, reco::CaloClusterPtr>::const_iterator iPair= allPairs.begin(); iPair!= allPairs.end(); ++iPair ) {
00368         scPtrVec.clear();
00369        
00370         reco::CaloClusterPtr caloPtr=iPair->second;
00371         if ( !( aClus == caloPtr ) ) continue;
00372             
00373         scPtrVec.push_back(aClus);     
00374         nFound++;
00375 
00376         std::vector<math::XYZPointF> trkPositionAtEcal = theEcalImpactPositionFinder.find(  iPair->first, bcHandle );
00377         std::vector<reco::CaloClusterPtr>  matchingBC = theEcalImpactPositionFinder.matchingBC();
00378         
00379 
00380         minAppDist=-99;
00381         const std::string metname = "ConvertedPhotons|ConvertedPhotonProducer";
00382         if ( (iPair->first).size()  > 1 ) {
00383           try{
00384             
00385             theVertexFinder_->run(iPair->first, theConversionVertex ); 
00386             
00387             
00388           }
00389           catch ( cms::Exception& e ) {
00390             //std::cout << " cms::Exception caught in ConvertedPhotonProducer::produce" << "\n" ;
00391             edm::LogWarning(metname) << "cms::Exception caught in ConvertedPhotonProducer::produce\n"
00392                                      << e.explainSelf();
00393             
00394           }
00395          
00396           // Old TwoTrackMinimumDistance md;
00397           // Old md.calculate  (  (iPair->first)[0].initialFreeState(),  (iPair->first)[1].initialFreeState() );
00398           // Old minAppDist = md.distance(); 
00399  
00400         
00401         
00402 
00403         
00404         
00405 
00406         /*
00407         for ( unsigned int i=0; i< matchingBC.size(); ++i) {
00408           if (  matchingBC[i].isNull() )  std::cout << " This ref to BC is null: skipping " <<  "\n";
00409           else 
00410             std::cout << " BC energy " << matchingBC[i]->energy() <<  "\n";
00411         }
00412         */
00413 
00414 
00416         trackPairRef.clear();
00417         trackInnPos.clear();
00418         trackPin.clear();
00419         trackPout.clear();
00420       
00421         
00422         for ( std::vector<reco::TransientTrack>::const_iterator iTk=(iPair->first).begin(); iTk!= (iPair->first).end(); ++iTk) {
00423           //LogDebug("ConvertedPhotonProducer")  << "  ConvertedPhotonProducer Transient Tracks in the pair  charge " << iTk->charge() << " Num of RecHits " << iTk->recHitsSize() << " inner momentum " << iTk->track().innerMomentum() << "\n";  
00424           
00425           const reco::TrackTransientTrack* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTk->basicTransientTrack());
00426           reco::TrackRef myTkRef= ttt->persistentTrackRef(); 
00427           
00428           //LogDebug("ConvertedPhotonProducer")  << " ConvertedPhotonProducer Ref to Rec Tracks in the pair  charge " << myTkRef->charge() << " Num of RecHits " << myTkRef->recHitsSize() << " inner momentum " << myTkRef->innerMomentum() << "\n";  
00429           if ( myTkRef->extra().isNonnull() ) {
00430             trackInnPos.push_back(  toFConverterP(myTkRef->innerPosition()));
00431             trackPin.push_back(  toFConverterV( myTkRef->innerMomentum()));
00432             trackPout.push_back(  toFConverterV(myTkRef->outerMomentum()));
00433           }
00434           trackPairRef.push_back(myTkRef);
00435           
00436         }
00437         
00438         //      std::cout << " ConvertedPhotonProducer trackPin size " << trackPin.size() << std::endl;
00439         //LogDebug("ConvertedPhotonProducer")  << " ConvertedPhotonProducer SC energy " <<  aClus->energy() << "\n";
00440         //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer photon p4 " << p4  << "\n";
00441         //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer vtx " << vtx.x() << " " << vtx.y() << " " << vtx.z() << "\n";
00442         if( theConversionVertex.isValid() ) {
00443           
00444           //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer theConversionVertex " << theConversionVertex.position().x() << " " << theConversionVertex.position().y() << " " << theConversionVertex.position().z() << "\n";
00445           
00446         }
00447         //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer trackPairRef  " << trackPairRef.size() <<  "\n";
00448 
00449         
00450         minAppDist=calculateMinApproachDistance( trackPairRef[0],  trackPairRef[1]);
00451 
00452         double like = -999.;
00453         reco::Conversion  newCandidate(scPtrVec,  trackPairRef,  trkPositionAtEcal, theConversionVertex, matchingBC,  minAppDist, trackInnPos, trackPin, trackPout, like, algo);
00454 //    like = theLikelihoodCalc_->calculateLikelihood(newCandidate, es );
00455         like = theLikelihoodCalc_->calculateLikelihood( newCandidate );
00456 //    std::cout << "like = " << like << std::endl;
00457     newCandidate.setMVAout(like);
00458         outputConvPhotonCollection.push_back(newCandidate);
00459         
00460         
00461         myCands++;
00462         //LogDebug("ConvertedPhotonProducer") << " ConvertedPhotonProducer Put the ConvertedPhotonCollection a candidate in the Barrel " << "\n";
00463         
00464         } else {
00465           
00466           
00467           //      std::cout << "   ConvertedPhotonProducer case with only one track found " <<  "\n";
00468  
00469             //std::cout << "   ConvertedPhotonProducer recovering one track " <<  "\n";
00470             trackPairRef.clear();
00471             trackInnPos.clear();
00472             trackPin.clear();
00473             trackPout.clear();
00474             std::vector<reco::TransientTrack>::const_iterator iTk=(iPair->first).begin();
00475             //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";         
00476             const reco::TrackTransientTrack* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTk->basicTransientTrack());
00477             reco::TrackRef myTk= ttt->persistentTrackRef(); 
00478             if ( myTk->extra().isNonnull() ) {
00479               trackInnPos.push_back(  toFConverterP(myTk->innerPosition()));
00480               trackPin.push_back(  toFConverterV(myTk->innerMomentum()));
00481               trackPout.push_back(  toFConverterV(myTk->outerMomentum()));
00482             }
00483             trackPairRef.push_back(myTk);
00484             //std::cout << " Provenance " << myTk->algoName() << std::endl;
00485         
00486             if (  recoverOneTrackCase_ ) {    
00487               float theta1 = myTk->innerMomentum().Theta();
00488               float dCot=999.;
00489               float dCotTheta=-999.;
00490               reco::TrackRef goodRef;
00491               std::vector<reco::TransientTrack>::const_iterator iGoodGenTran;
00492               for ( std::vector<reco::TransientTrack>::const_iterator iTran= t_generalTrk.begin(); iTran != t_generalTrk.end(); ++iTran) {
00493                 const reco::TrackTransientTrack* ttt = dynamic_cast<const reco::TrackTransientTrack*>(iTran->basicTransientTrack());
00494                 reco::TrackRef trRef= ttt->persistentTrackRef(); 
00495                 if ( trRef->charge()*myTk->charge() > 0 ) continue;
00496                 float dEta =  trRef->eta() - myTk->eta();
00497                 float dPhi =  trRef->phi() - myTk->phi();
00498                 if ( sqrt (dEta*dEta + dPhi*dPhi) > dRForConversionRecovery_ ) continue; 
00499                 float theta2 = trRef->innerMomentum().Theta();
00500                 dCotTheta =  1./tan(theta1) - 1./tan(theta2) ;
00501                 //      std::cout << "  ConvertedPhotonProducer recovering general transient track charge " << trRef->charge() << " momentum " << trRef->innerMomentum() << " dcotTheta " << fabs(dCotTheta) << std::endl;
00502                 if ( fabs(dCotTheta) < dCot ) {
00503                   dCot = fabs(dCotTheta);
00504                   goodRef = trRef;
00505                   iGoodGenTran=iTran;
00506                 }
00507               }
00508               
00509               if ( goodRef.isNonnull() ) {
00510                 
00511                 minAppDist=calculateMinApproachDistance( myTk, goodRef);
00512                 
00513                 // std::cout << "  ConvertedPhotonProducer chosen dCotTheta " <<  fabs(dCotTheta) << std::endl;
00514                 if ( fabs(dCotTheta) < deltaCotCut_ && minAppDist > minApproachDisCut_ ) {
00515                   trackInnPos.push_back(  toFConverterP(goodRef->innerPosition()));     
00516                   trackPin.push_back(  toFConverterV(goodRef->innerMomentum()));
00517                   trackPout.push_back(  toFConverterV(goodRef->outerMomentum()));
00518                   trackPairRef.push_back( goodRef );
00519                   //        std::cout << " ConvertedPhotonProducer adding opposite charge track from generalTrackCollection charge " <<  goodRef ->charge() << " pt " << sqrt(goodRef->innerMomentum().perp2())  << " trackPairRef size " << trackPairRef.size() << std::endl;            
00520                   //std::cout << " Track Provenenance " << goodRef->algoName() << std::endl; 
00521                   std::vector<reco::TransientTrack> mypair;
00522                   mypair.push_back(*iTk); 
00523                   mypair.push_back(*iGoodGenTran); 
00524                   
00525                   try{
00526                     theVertexFinder_->run(iPair->first, theConversionVertex ); 
00527                     
00528                   }
00529                   catch ( cms::Exception& e ) {
00530                     //std::cout << " cms::Exception caught in ConvertedPhotonProducer::produce" << "\n" ;
00531                     edm::LogWarning(metname) << "cms::Exception caught in ConvertedPhotonProducer::produce\n"
00532                                              << e.explainSelf();
00533                     
00534                   }
00535                 } 
00536                 
00537               }     
00538               
00539             } // bool On/Off one track case recovery using generalTracks  
00540             double like = -999.;
00541             reco::Conversion  newCandidate(scPtrVec,  trackPairRef,  trkPositionAtEcal, theConversionVertex, matchingBC,  minAppDist, trackInnPos, trackPin, trackPout, like, algo);
00542             like = theLikelihoodCalc_->calculateLikelihood(newCandidate);
00543             newCandidate.setMVAout(like);
00544             outputConvPhotonCollection.push_back(newCandidate);
00545               
00546               
00547               
00548             
00549         } // case with only on track: looking in general tracks
00550         
00551         
00552         
00553         
00554       } 
00555       
00556     }
00557     
00558 
00559 
00560     
00561   }
00562   
00563 
00564 
00565 
00566 
00567 }
00568 
00569 
00570 void ConvertedPhotonProducer::cleanCollections(const edm::Handle<edm::View<reco::CaloCluster> > & scHandle,
00571                                               const edm::OrphanHandle<reco::ConversionCollection> & conversionHandle,
00572                                               reco::ConversionCollection & outputConversionCollection) {
00573 
00574 
00575   reco::Conversion* newCandidate=0;
00576   for(unsigned int lSC=0; lSC < scHandle->size(); lSC++) {
00577     
00578     // get pointer to SC
00579     reco::CaloClusterPtr aClus= scHandle->ptrAt(lSC);    
00580         
00581     // SC energy preselection
00582     if (aClus->energy()/cosh(aClus->eta()) <= minSCEt_) continue;
00583 
00584 
00585     if (  conversionHandle.isValid() ) {
00586 
00587       if ( risolveAmbiguity_ ) {
00588         std::vector<reco::ConversionRef> bestRef=solveAmbiguity( conversionHandle , aClus);
00589    
00590         for ( std::vector<reco::ConversionRef>::iterator iRef=bestRef.begin(); iRef!=bestRef.end(); iRef++ ) {
00591           if ( iRef->isNonnull() )  {
00592             newCandidate= (*iRef)->clone();
00593             outputConversionCollection.push_back(*newCandidate);
00594             delete newCandidate;
00595           }
00596         }
00597         
00598       } else {
00599         
00600 
00601         for( unsigned int icp = 0;  icp < conversionHandle->size(); icp++) {
00602           reco::ConversionRef cpRef(reco::ConversionRef(conversionHandle,icp));
00603           if (!( aClus.id() == cpRef->caloCluster()[0].id() && aClus.key() == cpRef->caloCluster()[0].key() )) continue; 
00604           if ( !cpRef->isConverted() ) continue;  
00605           if ( cpRef->nTracks() <2 ) continue;
00606           newCandidate= (&(*cpRef))->clone();    
00607           outputConversionCollection.push_back(*newCandidate);
00608           delete newCandidate;
00609 
00610         }         
00611         
00612       } // solve or not the ambiguity of many conversion candidates     
00613         
00614     }     
00615 
00616    
00617   }    
00618 }
00619 
00620 
00621 
00622 
00623 std::vector<reco::ConversionRef>  ConvertedPhotonProducer::solveAmbiguity(const edm::OrphanHandle<reco::ConversionCollection> & conversionHandle, reco::CaloClusterPtr& scRef) {
00624   std::multimap<double, reco::ConversionRef, std::greater<double> >   convMap;
00625 
00626   for ( unsigned int icp=0; icp< conversionHandle->size(); icp++) {
00627     reco::ConversionRef cpRef(reco::ConversionRef(conversionHandle,icp));
00628     
00629     //std::cout << " cpRef " << cpRef->nTracks() << " " <<  cpRef ->caloCluster()[0]->energy() << std::endl;    
00630     if (!( scRef.id() == cpRef->caloCluster()[0].id() && scRef.key() == cpRef->caloCluster()[0].key() )) continue;    
00631     if ( !cpRef->isConverted() ) continue;  
00632     double like = cpRef->MVAout();
00633     if ( cpRef->nTracks() <2 ) continue;
00634     //    std::cout << " Like " << like << std::endl;
00635     convMap.insert ( std::make_pair(like,cpRef) );
00636     
00637   }                  
00638   
00639   //  std::cout << " convMap size " << convMap.size() << std::endl;
00640 
00641   std::multimap<double, reco::ConversionRef>::iterator  iMap; 
00642   std::vector<reco::ConversionRef> bestRefs;
00643   for (iMap=convMap.begin();  iMap!=convMap.end(); iMap++) {
00644     //    std::cout << " Like list in the map " <<  iMap->first << " " << (iMap->second)->EoverP() << std::endl;
00645     bestRefs.push_back(  iMap->second );
00646     if (  int(bestRefs.size()) ==  maxNumOfCandidates_ ) break;   
00647   }
00648 
00649 
00650    return bestRefs;
00651   
00652   
00653 } 
00654 
00655 
00656 
00657 
00658 
00659 float ConvertedPhotonProducer::calculateMinApproachDistance ( const reco::TrackRef& track1, const reco::TrackRef& track2) {
00660   float dist=9999.;
00661 
00662   double x1, x2, y1, y2;
00663   double xx_1 = track1->innerPosition().x(), yy_1 = track1->innerPosition().y(), zz_1 = track1->innerPosition().z();
00664   double xx_2 = track2->innerPosition().x(), yy_2 = track2->innerPosition().y(), zz_2 = track2->innerPosition().z();
00665   double radius1 = track1->innerMomentum().Rho()/(.3*(theMF_->inTesla(GlobalPoint(xx_1, yy_1, zz_1)).z()))*100;
00666   double radius2 = track2->innerMomentum().Rho()/(.3*(theMF_->inTesla(GlobalPoint(xx_2, yy_2, zz_2)).z()))*100;
00667   getCircleCenter(track1, radius1, x1, y1);
00668   getCircleCenter(track2, radius2, x2, y2);
00669   dist = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) - radius1 - radius2;
00670   
00671  return dist;
00672 
00673 } 
00674 
00675 
00676 void ConvertedPhotonProducer::getCircleCenter(const reco::TrackRef& tk, double r, double& x0, double& y0){
00677   double x1, y1, phi;
00678   x1 = tk->innerPosition().x();//inner position and inner momentum need track Extra!
00679   y1 = tk->innerPosition().y();
00680   phi = tk->innerMomentum().phi();
00681   const int charge = tk->charge();
00682   x0 = x1 + r*sin(phi)*charge;
00683   y0 = y1 - r*cos(phi)*charge;
00684 
00685 }