CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/CommonTools/ParticleFlow/plugins/PFPileUp.cc

Go to the documentation of this file.
00001 #include "CommonTools/ParticleFlow/plugins/PFPileUp.h"
00002 
00003 #include "DataFormats/ParticleFlowCandidate/interface/PileUpPFCandidate.h"
00004 #include "DataFormats/ParticleFlowCandidate/interface/PileUpPFCandidateFwd.h"
00005 #include "DataFormats/VertexReco/interface/Vertex.h"
00006 
00007 #include "FWCore/Framework/interface/ESHandle.h"
00008 
00009 // #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "FWCore/Utilities/interface/Exception.h"
00011 #include "FWCore/Framework/interface/EventSetup.h"
00012 
00013 #include "DataFormats/Math/interface/deltaR.h"
00014 
00015 using namespace std;
00016 using namespace edm;
00017 using namespace reco;
00018 
00019 PFPileUp::PFPileUp(const edm::ParameterSet& iConfig) {
00020   
00021 
00022 
00023   inputTagPFCandidates_ 
00024     = iConfig.getParameter<InputTag>("PFCandidates");
00025 
00026   inputTagVertices_ 
00027     = iConfig.getParameter<InputTag>("Vertices");
00028 
00029   enable_ = iConfig.getParameter<bool>("Enable");
00030 
00031   verbose_ = 
00032     iConfig.getUntrackedParameter<bool>("verbose",false);
00033 
00034 
00035   if ( iConfig.exists("checkClosestZVertex") ) {
00036     checkClosestZVertex_ = iConfig.getParameter<bool>("checkClosestZVertex");
00037   } else {
00038     checkClosestZVertex_ = false;
00039   }
00040 
00041 
00042   produces<reco::PFCandidateCollection>();
00043   
00044 }
00045 
00046 
00047 
00048 PFPileUp::~PFPileUp() { }
00049 
00050 
00051 
00052 void PFPileUp::beginJob() { }
00053 
00054 
00055 void PFPileUp::produce(Event& iEvent, 
00056                           const EventSetup& iSetup) {
00057   
00058 //   LogDebug("PFPileUp")<<"START event: "<<iEvent.id().event()
00059 //                       <<" in run "<<iEvent.id().run()<<endl;
00060   
00061    
00062   // get PFCandidates
00063 
00064   auto_ptr< reco::PFCandidateCollection > 
00065     pOutput( new reco::PFCandidateCollection ); 
00066   
00067   if(enable_) {
00068 
00069     Handle<PFCandidateCollection> pfCandidates;
00070     iEvent.getByLabel( inputTagPFCandidates_, pfCandidates);
00071 
00072   
00073     // get vertices 
00074 
00075     Handle<VertexCollection> vertices;
00076     iEvent.getByLabel( inputTagVertices_, vertices);
00077   
00078     for( unsigned i=0; i<pfCandidates->size(); i++ ) {
00079     
00080       const reco::PFCandidate& cand = (*pfCandidates)[i];
00081       PFCandidatePtr candptr(pfCandidates, i);
00082 
00083       //     PFCandidateRef pfcandref(pfCandidates,i); 
00084 
00085       VertexRef vertexref;
00086 
00087       switch( candptr->particleId() ) {
00088       case PFCandidate::h:
00089         vertexref = chargedHadronVertex( vertices, *candptr );
00090         break;
00091       default:
00092         continue;
00093       } 
00094     
00095       // no associated vertex, or primary vertex
00096       // not pile-up
00097       if( vertexref.isNull() || 
00098           vertexref.key()==0 ) continue;
00099 
00100       pOutput->push_back( cand );
00101       pOutput->back().setSourceCandidatePtr( candptr );
00102     }
00103   }
00104   iEvent.put( pOutput );
00105   
00106 }
00107 
00108 
00109 
00110 VertexRef 
00111 PFPileUp::chargedHadronVertex( const Handle<VertexCollection>& vertices, const PFCandidate& pfcand ) const {
00112 
00113   
00114   reco::TrackBaseRef trackBaseRef( pfcand.trackRef() );
00115   
00116   size_t  iVertex = 0;
00117   unsigned index=0;
00118   unsigned nFoundVertex = 0;
00119   typedef reco::VertexCollection::const_iterator IV;
00120   float bestweight=0;
00121   for(IV iv=vertices->begin(); iv!=vertices->end(); ++iv, ++index) {
00122 
00123     const reco::Vertex& vtx = *iv;
00124     
00125     typedef reco::Vertex::trackRef_iterator IT;
00126     
00127     // loop on tracks in vertices
00128     for(IT iTrack=vtx.tracks_begin(); 
00129         iTrack!=vtx.tracks_end(); ++iTrack) {
00130          
00131       const reco::TrackBaseRef& baseRef = *iTrack;
00132 
00133       // one of the tracks in the vertex is the same as 
00134       // the track considered in the function
00135       if(baseRef == trackBaseRef ) {
00136         float w = vtx.trackWeight(baseRef);
00137         //select the vertex for which the track has the highest weight
00138         if (w > bestweight){
00139           bestweight=w;
00140           iVertex=index;
00141           nFoundVertex++;
00142         }               
00143       }
00144     }
00145   }
00146 
00147   if (nFoundVertex>0){
00148     if (nFoundVertex!=1)
00149       edm::LogWarning("TrackOnTwoVertex")<<"a track is shared by at least two verteces. Used to be an assert";
00150     return VertexRef( vertices, iVertex);
00151   }
00152   // no vertex found with this track. 
00153 
00154   // optional: as a secondary solution, associate the closest vertex in z
00155   if ( checkClosestZVertex_ ) {
00156 
00157     double dzmin = 10000;
00158     double ztrack = pfcand.vertex().z();
00159     bool foundVertex = false;
00160     index = 0;
00161     for(IV iv=vertices->begin(); iv!=vertices->end(); ++iv, ++index) {
00162 
00163       double dz = fabs(ztrack - iv->z());
00164       if(dz<dzmin) {
00165         dzmin = dz; 
00166         iVertex = index;
00167         foundVertex = true;
00168       }
00169     }
00170 
00171     if( foundVertex ) 
00172       return VertexRef( vertices, iVertex);  
00173 
00174   }
00175 
00176 
00177   return VertexRef();
00178 }
00179 
00180