00001 #include "PhysicsTools/PFCandProducer/interface/PFPileUp.h"
00002 #include "PhysicsTools/PFCandProducer/interface/FetchCollection.h"
00003
00004 #include "DataFormats/ParticleFlowCandidate/interface/PileUpPFCandidate.h"
00005 #include "DataFormats/ParticleFlowCandidate/interface/PileUpPFCandidateFwd.h"
00006 #include "DataFormats/VertexReco/interface/Vertex.h"
00007
00008 #include "FWCore/Framework/interface/ESHandle.h"
00009
00010
00011 #include "FWCore/Utilities/interface/Exception.h"
00012 #include "FWCore/Framework/interface/EventSetup.h"
00013
00014 #include "DataFormats/Math/interface/deltaR.h"
00015
00016 using namespace std;
00017 using namespace edm;
00018 using namespace reco;
00019
00020 PFPileUp::PFPileUp(const edm::ParameterSet& iConfig) {
00021
00022
00023
00024 inputTagPFCandidates_
00025 = iConfig.getParameter<InputTag>("PFCandidates");
00026
00027 inputTagVertices_
00028 = iConfig.getParameter<InputTag>("Vertices");
00029
00030 verbose_ =
00031 iConfig.getUntrackedParameter<bool>("verbose",false);
00032
00033
00034
00035 produces<reco::PileUpPFCandidateCollection>();
00036
00037 }
00038
00039
00040
00041 PFPileUp::~PFPileUp() { }
00042
00043
00044
00045 void PFPileUp::beginJob(const edm::EventSetup & es) { }
00046
00047
00048 void PFPileUp::produce(Event& iEvent,
00049 const EventSetup& iSetup) {
00050
00051
00052
00053
00054
00055
00056
00057
00058 Handle<PFCandidateCollection> pfCandidates;
00059 pfpat::fetchCollection(pfCandidates,
00060 inputTagPFCandidates_,
00061 iEvent );
00062
00063
00064
00065
00066 Handle<VertexCollection> vertices;
00067 pfpat::fetchCollection(vertices,
00068 inputTagVertices_,
00069 iEvent );
00070
00071 auto_ptr< reco::PileUpPFCandidateCollection >
00072 pOutput( new reco::PileUpPFCandidateCollection );
00073
00074 for( unsigned i=0; i<pfCandidates->size(); i++ ) {
00075
00076
00077 PFCandidatePtr candptr(pfCandidates, i);
00078
00079
00080
00081 VertexRef vertexref;
00082
00083 switch( candptr->particleId() ) {
00084 case PFCandidate::h:
00085 vertexref = chargedHadronVertex( vertices, *candptr );
00086 break;
00087 default:
00088 continue;
00089 }
00090
00091
00092
00093 if( vertexref.isNull() ||
00094 vertexref.key()==0 ) continue;
00095
00096 pOutput->push_back( PileUpPFCandidate( candptr, vertexref ) );
00097
00098 }
00099
00100 iEvent.put( pOutput );
00101
00102 }
00103
00104
00105
00106 VertexRef
00107 PFPileUp::chargedHadronVertex( const Handle<VertexCollection>& vertices, const PFCandidate& pfcand ) const {
00108
00109
00110 reco::TrackBaseRef trackBaseRef( pfcand.trackRef() );
00111
00112 unsigned nFoundVertex = 0;
00113 size_t iVertex = 0;
00114 unsigned index=0;
00115 typedef reco::VertexCollection::const_iterator IV;
00116 for(IV iv=vertices->begin(); iv!=vertices->end(); ++iv, ++index) {
00117
00118
00119
00120
00121 const reco::Vertex& vtx = *iv;
00122
00123 typedef reco::Vertex::trackRef_iterator IT;
00124
00125
00126 for(IT iTrack=vtx.tracks_begin();
00127 iTrack!=vtx.tracks_end(); ++iTrack) {
00128
00129 const reco::TrackBaseRef& baseRef = *iTrack;
00130
00131
00132
00133 if(baseRef == trackBaseRef ) {
00134 iVertex = index;
00135 nFoundVertex++;
00136 }
00137 }
00138 }
00139
00140 if( nFoundVertex == 1) {
00141 return VertexRef( vertices, iVertex);
00142 }
00143 else if(nFoundVertex>1) assert(false);
00144
00145 assert( !iVertex );
00146
00147
00148
00149
00150 double dzmin = 10000;
00151 double ztrack = pfcand.vertex().z();
00152 bool foundVertex = false;
00153 index = 0;
00154 for(IV iv=vertices->begin(); iv!=vertices->end(); ++iv, ++index) {
00155
00156 double dz = fabs(ztrack - iv->z());
00157 if(dz<dzmin) {
00158 dzmin = dz;
00159 iVertex = index;
00160 foundVertex = true;
00161 }
00162 }
00163
00164 if( foundVertex )
00165 return VertexRef( vertices, iVertex);
00166 else
00167 return VertexRef();
00168 }
00169
00170