CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/CommonTools/ParticleFlow/src/PFPileUpAlgo.cc

Go to the documentation of this file.
00001 #include "CommonTools/ParticleFlow/interface/PFPileUpAlgo.h"
00002 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00003 #include "DataFormats/VertexReco/interface/Vertex.h"
00004 
00005 void PFPileUpAlgo::process(const PFCollection & pfCandidates, 
00006                            const reco::VertexCollection & vertices)  {
00007 
00008   pfCandidatesFromVtx_.clear();
00009   pfCandidatesFromPU_.clear();
00010 
00011   for( unsigned i=0; i<pfCandidates.size(); i++ ) {
00012     
00013     const reco::PFCandidate& cand = * ( pfCandidates[i] );
00014     
00015     int ivertex;
00016 
00017     switch( cand.particleId() ) {
00018     case reco::PFCandidate::h:
00019       ivertex = chargedHadronVertex( vertices, cand );
00020       break;
00021     default:
00022       continue;
00023     } 
00024     
00025     // no associated vertex, or primary vertex
00026     // not pile-up
00027     if( ivertex == -1  || 
00028         ivertex == 0 ) {
00029       if(verbose_)
00030         std::cout<<"VTX "<<i<<" "<< *(pfCandidates[i])<<std::endl;
00031       pfCandidatesFromVtx_.push_back( pfCandidates[i] );
00032     } else {
00033       if(verbose_)
00034         std::cout<<"PU  "<<i<<" "<< *(pfCandidates[i])<<std::endl;
00035       // associated to a vertex
00036       pfCandidatesFromPU_.push_back( pfCandidates[i] );
00037     }
00038   }
00039 }
00040 
00041 
00042 int 
00043 PFPileUpAlgo::chargedHadronVertex( const reco::VertexCollection& vertices, const reco::PFCandidate& pfcand ) const {
00044 
00045   
00046   reco::TrackBaseRef trackBaseRef( pfcand.trackRef() );
00047   
00048   size_t  iVertex = 0;
00049   unsigned index=0;
00050   unsigned nFoundVertex = 0;
00051   typedef reco::VertexCollection::const_iterator IV;
00052   typedef reco::Vertex::trackRef_iterator IT;
00053   float bestweight=0;
00054   for(IV iv=vertices.begin(); iv!=vertices.end(); ++iv, ++index) {
00055 
00056     const reco::Vertex& vtx = *iv;
00057     
00058     // loop on tracks in vertices
00059     for(IT iTrack=vtx.tracks_begin(); 
00060         iTrack!=vtx.tracks_end(); ++iTrack) {
00061          
00062       const reco::TrackBaseRef& baseRef = *iTrack;
00063 
00064       // one of the tracks in the vertex is the same as 
00065       // the track considered in the function
00066       if(baseRef == trackBaseRef ) {
00067         float w = vtx.trackWeight(baseRef);
00068         //select the vertex for which the track has the highest weight
00069         if (w > bestweight){
00070           bestweight=w;
00071           iVertex=index;
00072           nFoundVertex++;
00073         }               
00074       }
00075     }
00076   }
00077 
00078   if (nFoundVertex>0){
00079     if (nFoundVertex!=1)
00080       edm::LogWarning("TrackOnTwoVertex")<<"a track is shared by at least two verteces. Used to be an assert";
00081     return iVertex;
00082   }
00083   // no vertex found with this track. 
00084 
00085   // optional: as a secondary solution, associate the closest vertex in z
00086   if ( checkClosestZVertex_ ) {
00087 
00088     double dzmin = 10000;
00089     double ztrack = pfcand.vertex().z();
00090     bool foundVertex = false;
00091     index = 0;
00092     for(IV iv=vertices.begin(); iv!=vertices.end(); ++iv, ++index) {
00093 
00094       double dz = fabs(ztrack - iv->z());
00095       if(dz<dzmin) {
00096         dzmin = dz; 
00097         iVertex = index;
00098         foundVertex = true;
00099       }
00100     }
00101 
00102     if( foundVertex ) 
00103       return iVertex;  
00104 
00105   }
00106 
00107 
00108   return -1 ;
00109 }
00110