CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoEgamma/EgammaPhotonProducers/src/SoftConversionProducer.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <vector>
00003 #include <memory>
00004 
00005 // Framework
00006 #include "DataFormats/Common/interface/Handle.h"
00007 #include "FWCore/Framework/interface/ESHandle.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 //
00011 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00012 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00013 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00014 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
00015 //
00016 #include "DataFormats/TrackReco/interface/Track.h"
00017 #include "DataFormats/TrackReco/interface/TrackBase.h"
00018 #include "DataFormats/TrackReco/interface/TrackExtra.h"
00019 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00020 #include "TrackingTools/TransientTrack/interface/TrackTransientTrack.h"
00021 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00022 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00023 #include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h"
00024 
00025 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
00026 #include "DataFormats/EgammaCandidates/interface/ConversionFwd.h"
00027 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionTrackEcalImpactPoint.h"
00028 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionTrackPairFinder.h"
00029 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionVertexFinder.h"
00030 
00031 #include "DataFormats/EgammaTrackReco/interface/TrackCaloClusterAssociation.h"
00032 #include "RecoEgamma/EgammaPhotonProducers/interface/SoftConversionProducer.h"
00033 
00034 #include "Math/GenVector/VectorUtil.h"
00035 
00036 
00037 SoftConversionProducer::SoftConversionProducer(const edm::ParameterSet& config) : conf_(config) {
00038 
00039   LogDebug("SoftConversionProducer") << " SoftConversionProducer CTOR " << "\n";
00040   
00041   conversionOITrackProducer_              = conf_.getParameter<std::string>("conversionOITrackProducer");
00042   conversionIOTrackProducer_              = conf_.getParameter<std::string>("conversionIOTrackProducer");
00043   outInTrackClusterAssociationCollection_ = conf_.getParameter<std::string>("outInTrackClusterAssociationCollection");
00044   inOutTrackClusterAssociationCollection_ = conf_.getParameter<std::string>("inOutTrackClusterAssociationCollection");
00045   clusterType_                            = conf_.getParameter<std::string>("clusterType");
00046   clusterBarrelCollection_                = conf_.getParameter<edm::InputTag>("clusterBarrelCollection");
00047   clusterEndcapCollection_                = conf_.getParameter<edm::InputTag>("clusterEndcapCollection");
00048   softConversionCollection_               = conf_.getParameter<std::string>("softConversionCollection");
00049   trackMaxChi2_                           = conf_.getParameter<double>("trackMaxChi2");
00050   trackMinHits_                           = conf_.getParameter<double>("trackMinHits");
00051   clustersMaxDeltaEta_                    = conf_.getParameter<double>("clustersMaxDeltaEta");
00052   clustersMaxDeltaPhi_                    = conf_.getParameter<double>("clustersMaxDeltaPhi");
00053   
00054   theTrackPairFinder_ = 0;
00055   theVertexFinder_ = 0;
00056   theEcalImpactPositionFinder_ = 0;
00057   
00058   // Register the product
00059   produces< reco::ConversionCollection >(softConversionCollection_);
00060 
00061 }
00062 
00063 
00064 SoftConversionProducer::~SoftConversionProducer() {}
00065 
00066 
00067 void  SoftConversionProducer::beginRun (edm::Run& r, edm::EventSetup const & theEventSetup) {
00068   
00069   //get magnetic field
00070   theEventSetup.get<IdealMagneticFieldRecord>().get(theMF_);  
00071   
00072   // instantiate the Track Pair Finder algorithm
00073   theTrackPairFinder_ = new ConversionTrackPairFinder ();
00074 
00075   // instantiate the Vertex Finder algorithm
00076   theVertexFinder_ = new ConversionVertexFinder (conf_);
00077   
00078   // instantiate the algorithm for finding the position of the track extrapolation at the Ecal front face
00079   theEcalImpactPositionFinder_ = new   ConversionTrackEcalImpactPoint ( &(*theMF_) );
00080 
00081 }
00082 
00083 
00084 void  SoftConversionProducer::endRun (edm::Run& r, edm::EventSetup const & theEventSetup) {
00085 
00086   if(theTrackPairFinder_) delete theTrackPairFinder_;
00087   if(theVertexFinder_) delete theVertexFinder_;
00088   if(theEcalImpactPositionFinder_) delete theEcalImpactPositionFinder_; 
00089 
00090 }
00091 
00092 
00093 
00094 void SoftConversionProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) {
00095   
00096   edm::Handle<reco::TrackCollection> outInTrkHandle;
00097   theEvent.getByLabel(conversionOITrackProducer_,  outInTrkHandle);
00098    
00099   edm::Handle<reco::TrackCaloClusterPtrAssociation> outInTrkClusterAssocHandle;
00100   theEvent.getByLabel( conversionOITrackProducer_, outInTrackClusterAssociationCollection_, outInTrkClusterAssocHandle);
00101 
00102   edm::Handle<reco::TrackCollection> inOutTrkHandle;
00103   theEvent.getByLabel(conversionIOTrackProducer_, inOutTrkHandle);
00104   
00105   edm::Handle<reco::TrackCaloClusterPtrAssociation> inOutTrkClusterAssocHandle;
00106   theEvent.getByLabel( conversionIOTrackProducer_, inOutTrackClusterAssociationCollection_, inOutTrkClusterAssocHandle);
00107 
00108   edm::Handle<edm::View<reco::CaloCluster> > clusterBarrelHandle;
00109   theEvent.getByLabel(clusterBarrelCollection_, clusterBarrelHandle);
00110 
00111   edm::Handle<edm::View<reco::CaloCluster> > clusterEndcapHandle;
00112   if(clusterType_ == "BasicCluster"){
00113     //theEvent.getByLabel(clusterEndcapProducer_, clusterEndcapCollection_, clusterEndcapHandle);
00114     theEvent.getByLabel(clusterEndcapCollection_, clusterEndcapHandle);
00115   }
00116 
00117   // create temporary map to loop over tracks conveniently
00118   TrackClusterMap trackClusterMap;
00119 
00120   int nTracksOI = (int) outInTrkHandle->size();
00121   //  std::cout << "  nTracksOI " <<  nTracksOI << std::endl;
00122   for(int itrk=0; itrk<nTracksOI; itrk++){
00123     reco::TrackRef tRef(outInTrkHandle,itrk);
00124     if(!trackQualityCut(tRef)) continue;
00125     reco::CaloClusterPtr cRef = (*outInTrkClusterAssocHandle)[tRef];
00126     trackClusterMap.push_back(make_pair(tRef,cRef));
00127   }
00128 
00129   int nTracksIO = (int) inOutTrkHandle->size();
00130   // std::cout << "  nTracksIO " <<  nTracksIO << std::endl;
00131   for(int itrk=0; itrk<nTracksIO; itrk++){
00132     reco::TrackRef tRef(inOutTrkHandle,itrk);
00133     if(!trackQualityCut(tRef)) continue;
00134     reco::CaloClusterPtr cRef = (*inOutTrkClusterAssocHandle)[tRef];
00135     trackClusterMap.push_back(make_pair(tRef,cRef));
00136   }
00137 
00138   // Transform Track into TransientTrack (needed by the Vertex fitter)
00139   edm::ESHandle<TransientTrackBuilder> theTransientTrackBuilder;
00140   theEventSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",theTransientTrackBuilder);
00141 
00142   // the output collection to be produced from this producer
00143   std::auto_ptr< reco::ConversionCollection > outputColl(new reco::ConversionCollection);
00144 
00145   // prepare iterator
00146   TrackClusterMap::iterator iter1    = trackClusterMap.begin();
00147   TrackClusterMap::iterator iter2    = trackClusterMap.begin();
00148   TrackClusterMap::iterator iter_end = trackClusterMap.end();
00149 
00150 
00151 
00152   // double-loop to make pairs
00153   for( ; iter1 != iter_end; iter1++) {
00154     //    std::cout << " back to start of loop 1 " << std::endl;
00155     const reco::TrackRef trk1 = iter1->first;
00156 
00157     for(iter2 = iter1+1; iter2 != iter_end; iter2++) {
00158       //      std::cout << " back to start of loop 2 " << std::endl;
00159       const reco::TrackRef trk2 = iter2->first;
00160       if(trk1 == trk2) continue;
00161 
00162 
00163       const reco::CaloClusterPtr cls1 = iter1->second;
00164       reco::TransientTrack tsk1 = theTransientTrackBuilder->build(*trk1);
00165 
00166       const reco::CaloClusterPtr cls2 = iter2->second;
00167       reco::TransientTrack tsk2 = theTransientTrackBuilder->build(*trk2);
00168 
00169       //      std::cout << " after transient " << std::endl;
00170       // std::cout << " eta1 " << cls1->position().Eta() << " eta2 " << cls2->position().Eta() << std::endl;
00171 
00172       if ( ( tsk1.innermostMeasurementState().globalParameters().position() - tsk2.innermostMeasurementState().globalParameters().position() ).mag() < 1e-7 &&
00173            ( tsk1.innermostMeasurementState().globalParameters().momentum() - tsk2.innermostMeasurementState().globalParameters().momentum() ).mag() < 1e-7 ) continue;
00174 
00175 
00176       double dEta = std::abs(cls1->position().Eta() - cls2->position().Eta());
00177       if(dEta > clustersMaxDeltaEta_) continue;
00178       double dPhi = std::abs(ROOT::Math::VectorUtil::DeltaPhi(cls1->position(),cls2->position()));
00179       if(dPhi > clustersMaxDeltaPhi_) continue;
00180 
00181       std::vector<reco::TransientTrack> toBeFitted;
00182       toBeFitted.push_back(tsk1);
00183       toBeFitted.push_back(tsk2);
00184 
00185       // 
00186       TwoTrackMinimumDistance md;
00187       md.calculate  (  tsk1.initialFreeState(),  tsk2.initialFreeState() );
00188       float minAppDist = md.distance(); 
00189  
00190 
00191 
00192       //      std::cout << " Before vertex " << std::endl;
00193       reco::Vertex theConversionVertex = (reco::Vertex) theVertexFinder_->run(toBeFitted);
00194       //std::cout << " After vertex " << std::endl;
00195 
00196       if(theConversionVertex.isValid()){
00197         //      std::cout << " valid vertex " << std::endl;
00198         reco::CaloClusterPtrVector scRefs;
00199         scRefs.push_back(cls1);
00200         scRefs.push_back(cls2);
00201         //std::cout << " after push back scref " << std::endl; 
00202         std::vector<reco::CaloClusterPtr> clusterRefs;
00203         clusterRefs.push_back(cls1);
00204         clusterRefs.push_back(cls2);
00205         //std::cout << " after push back slusterref " << std::endl; 
00206         std::vector<reco::TrackRef> trkRefs;
00207         trkRefs.push_back(trk1);
00208         trkRefs.push_back(trk2);
00209 
00210         std::vector<math::XYZVector> trackPin;
00211         std::vector<math::XYZVector> trackPout;
00212         trackPin.push_back( trk1->innerMomentum());
00213         trackPin.push_back( trk2->innerMomentum());
00214         trackPout.push_back( trk1->outerMomentum());
00215         trackPout.push_back( trk2->outerMomentum());
00216 
00217         //      std::cout << " Before impact finder " << std::endl;
00218         std::vector<math::XYZPoint> trkPositionAtEcal = theEcalImpactPositionFinder_->find(toBeFitted,clusterBarrelHandle);
00219         //      std::cout << " After impact finder " << std::endl;
00220         if((clusterType_ == "BasicCluster") && (std::abs(cls2->position().Eta()) > 1.5)){
00221           trkPositionAtEcal.clear();
00222           trkPositionAtEcal = theEcalImpactPositionFinder_->find(toBeFitted,clusterEndcapHandle);
00223         }
00224 
00225         double dummy = -9999.;
00226         std::vector<math::XYZPoint> dummyVec;
00227         reco::Conversion  newCandidate(scRefs,  trkRefs,  trkPositionAtEcal, theConversionVertex, clusterRefs,  minAppDist,dummyVec,  trackPin, trackPout, dummy );
00228 
00229         // Check this candidate is already in the collection.
00230         // This is checking that two tracks in a conversion candidate are identicial.
00231 
00232         if(NotAlreadyIn(newCandidate,outputColl)) outputColl->push_back(newCandidate);
00233 
00234         //      printf("=====> run(%d), event(%d) <=====\n",theEvent.id().run(),theEvent.id().event());
00235         //      printf("Found a softConverion with vtxR(%f), vtxEta(%f), pt(%f), pt1(%f), pt2(%f)\n",
00236         //      newCandidate.conversionVertex().position().rho(),newCandidate.conversionVertex().position().eta(),
00237         //      newCandidate.pairMomentum().perp(),trk1->momentum().rho(),trk2->momentum().rho());
00238 
00239         clusterRefs.clear();
00240         trkRefs.clear();
00241         trkPositionAtEcal.clear();
00242       }// if(theConversionVertex.isValid()
00243 
00244       toBeFitted.clear();
00245 
00246     }// end of iter2
00247   }// end of iter1
00248 
00249   //  std::cout << " Putting stuff in the event " << std::endl;
00250   // put the collection into the event
00251   theEvent.put( outputColl, softConversionCollection_);
00252   
00253 }
00254 
00255 
00256 bool SoftConversionProducer::trackQualityCut(const reco::TrackRef& trk){
00257   return (trk->numberOfValidHits() >= trackMinHits_ && trk->normalizedChi2() < trackMaxChi2_);
00258 }
00259 
00260 
00261 bool SoftConversionProducer::NotAlreadyIn(const reco::Conversion& thisConv,
00262                                           const std::auto_ptr<reco::ConversionCollection>& outputColl) const {
00263 
00264   if(outputColl->size() == 0) return true;
00265 
00266   reco::ConversionCollection::const_iterator it = outputColl->begin();
00267   reco::ConversionCollection::const_iterator it_end = outputColl->end();
00268   for( ; it != it_end; it++){
00269     const reco::Conversion& conv = *it;
00270     if((thisConv.tracks()[0] == conv.tracks()[0] && thisConv.tracks()[1] == conv.tracks()[1]) ||
00271        (thisConv.tracks()[0] == conv.tracks()[1] && thisConv.tracks()[1] == conv.tracks()[0]))
00272       return false;
00273   }// for
00274   
00275   return true;
00276 }