00001 #include "RecoParticleFlow/PFProducer/plugins/PFLinker.h"
00002
00003 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00004 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
00005 #include "DataFormats/MuonReco/interface/MuonToMuonMap.h"
00006 #include "DataFormats/MuonReco/interface/Muon.h"
00007 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00008
00009 #include "RecoParticleFlow/PFProducer/interface/GsfElectronEqual.h"
00010 #include "RecoParticleFlow/PFProducer/interface/PhotonEqual.h"
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012
00013
00014 PFLinker::PFLinker(const edm::ParameterSet & iConfig) {
00015
00016 inputTagPFCandidates_
00017 = iConfig.getParameter<std::vector<edm::InputTag> >("PFCandidate");
00018 inputTagGsfElectrons_
00019 = iConfig.getParameter<edm::InputTag>("GsfElectrons");
00020 inputTagPhotons_
00021 = iConfig.getParameter<edm::InputTag>("Photons");
00022 inputTagMuons_
00023 = iConfig.getParameter<edm::InputTag>("Muons");
00024
00025 nameOutputPF_
00026 = iConfig.getParameter<std::string>("OutputPF");
00027
00028 nameOutputElectronsPF_
00029 = iConfig.getParameter<std::string>("ValueMapElectrons");
00030
00031 nameOutputPhotonsPF_
00032 = iConfig.getParameter<std::string>("ValueMapPhotons");
00033
00034 producePFCandidates_
00035 = iConfig.getParameter<bool>("ProducePFCandidates");
00036
00037 nameOutputMergedPF_
00038 = iConfig.getParameter<std::string>("ValueMapMerged");
00039
00040 fillMuonRefs_
00041 = iConfig.getParameter<bool>("FillMuonRefs");
00042
00043
00044 if(producePFCandidates_ && inputTagPFCandidates_.size()>1) {
00045 edm::LogError("PFLinker") << " cannot read several collections of PFCandidates and produce a new collection at the same time. " << std::endl;
00046 assert(0);
00047 }
00048 if(producePFCandidates_) {
00049 produces<reco::PFCandidateCollection>(nameOutputPF_);
00050 }
00051 produces<edm::ValueMap<reco::PFCandidatePtr> > (nameOutputElectronsPF_);
00052 produces<edm::ValueMap<reco::PFCandidatePtr> > (nameOutputPhotonsPF_);
00053 produces<edm::ValueMap<reco::PFCandidatePtr> > (nameOutputMergedPF_);
00054 if(fillMuonRefs_) produces<edm::ValueMap<reco::PFCandidatePtr> > (inputTagMuons_.label());
00055
00056 }
00057
00058 PFLinker::~PFLinker() {;}
00059
00060 void PFLinker::beginRun(edm::Run& run,const edm::EventSetup & es) {;}
00061
00062 void PFLinker::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
00063
00064 std::auto_ptr<reco::PFCandidateCollection>
00065 pfCandidates_p(new reco::PFCandidateCollection);
00066
00067 edm::Handle<reco::GsfElectronCollection> gsfElectrons;
00068 bool status=fetchCollection<reco::GsfElectronCollection>(gsfElectrons,
00069 inputTagGsfElectrons_,
00070 iEvent );
00071 std::map<reco::GsfElectronRef,reco::PFCandidatePtr> electronCandidateMap;
00072
00073 if(!status) {
00074 std::ostringstream err;
00075 err << " Problem in PFLinker: no electron collection called " << inputTagGsfElectrons_ << std::endl;
00076 edm::LogError("PFLinker") << err.str();
00077 }
00078
00079
00080 edm::Handle<reco::PhotonCollection> photons;
00081 status=fetchCollection<reco::PhotonCollection>(photons,
00082 inputTagPhotons_,
00083 iEvent );
00084 if(!status) {
00085 std::ostringstream err;
00086 err << " Problem in PFLinker: no photon collection called " << inputTagPhotons_ << std::endl;
00087 edm::LogError("PFLinker") << err.str();
00088 }
00089
00090
00091 std::map<reco::PhotonRef,reco::PFCandidatePtr> photonCandidateMap;
00092
00093
00094 edm::Handle<reco::MuonToMuonMap> muonMap;
00095 if(fillMuonRefs_)
00096 status=fetchCollection<reco::MuonToMuonMap>(muonMap,
00097 inputTagMuons_,
00098 iEvent);
00099 std::map<reco::MuonRef,reco::PFCandidatePtr> muonCandidateMap;
00100
00101 unsigned nColPF=inputTagPFCandidates_.size();
00102
00103 if(!status) {
00104 std::ostringstream err;
00105 err << " Problem in PFLinker: no muon collection called " << inputTagMuons_ << std::endl;
00106 edm::LogError("PFLinker") << err.str();
00107 }
00108
00109
00110 edm::Handle<reco::PFCandidateCollection> pfCandidates;
00111 for(unsigned icol=0;icol<nColPF;++icol) {
00112
00113 bool status=fetchCollection<reco::PFCandidateCollection>(pfCandidates,
00114 inputTagPFCandidates_[icol],
00115 iEvent );
00116
00117 unsigned ncand=(status)?pfCandidates->size():0;
00118
00119 for( unsigned i=0; i<ncand; ++i) {
00120 edm::Ptr<reco::PFCandidate> candPtr(pfCandidates,i);
00121 reco::PFCandidate cand(candPtr);
00122
00123 bool isphoton = cand.particleId() == reco::PFCandidate::gamma && cand.mva_nothing_gamma()>0.;
00124 bool iselectron = cand.particleId() == reco::PFCandidate::e;
00125
00126 bool hasNonNullMuonRef = cand.muonRef().isNonnull() && fillMuonRefs_;
00127
00128
00129 if ( !(isphoton || iselectron || hasNonNullMuonRef)){pfCandidates_p->push_back(cand); continue;}
00130
00131
00132 if (hasNonNullMuonRef) {
00133 reco::MuonRef muRef = (*muonMap)[cand.muonRef()];
00134 cand.setMuonRef(muRef);
00135 muonCandidateMap[muRef] = candPtr;
00136 }
00137
00138
00139
00140 if (iselectron) {
00141 const reco::GsfTrackRef & gsfTrackRef(cand.gsfTrackRef());
00142 GsfElectronEqual myEqual(gsfTrackRef);
00143 std::vector<reco::GsfElectron>::const_iterator itcheck=find_if(gsfElectrons->begin(),gsfElectrons->end(),myEqual);
00144 if(itcheck==gsfElectrons->end()) {
00145 std::ostringstream err;
00146 err << " Problem in PFLinker: no GsfElectron " << std::endl;
00147 edm::LogError("PFLinker") << err.str();
00148 continue;
00149 }
00150 reco::GsfElectronRef electronRef(gsfElectrons,itcheck-gsfElectrons->begin());
00151 cand.setGsfElectronRef(electronRef);
00152 cand.setSuperClusterRef(electronRef->superCluster());
00153 electronCandidateMap[electronRef] = candPtr;
00154 }
00155
00156
00157 if (isphoton) {
00158 const reco::SuperClusterRef & scRef(cand.superClusterRef());
00159 PhotonEqual myEqual(scRef);
00160 std::vector<reco::Photon>::const_iterator itcheck=find_if(photons->begin(),photons->end(),myEqual);
00161 if(itcheck==photons->end()) {
00162 std::ostringstream err;
00163 err << " Problem in PFLinker: no Photon " << std::endl;
00164 edm::LogError("PFLinker") << err.str();
00165 continue;
00166 }
00167 reco::PhotonRef photonRef(photons,itcheck-photons->begin());
00168 cand.setPhotonRef(photonRef);
00169 cand.setSuperClusterRef(photonRef->superCluster());
00170 photonCandidateMap[photonRef] = candPtr;
00171 }
00172
00173 pfCandidates_p->push_back(cand);
00174 }
00175
00176 }
00177 const edm::OrphanHandle<reco::PFCandidateCollection> pfCandidateRefProd = (producePFCandidates_) ? iEvent.put(pfCandidates_p,nameOutputPF_) :
00178 edm::OrphanHandle<reco::PFCandidateCollection>();
00179
00180
00181
00182
00183 edm::ValueMap<reco::PFCandidatePtr> pfMapGsfElectrons = fillValueMap<reco::GsfElectronCollection>(iEvent,
00184 nameOutputElectronsPF_,
00185 gsfElectrons,
00186 electronCandidateMap,
00187 pfCandidateRefProd);
00188
00189 edm::ValueMap<reco::PFCandidatePtr> pfMapPhotons = fillValueMap<reco::PhotonCollection>(iEvent,
00190 nameOutputPhotonsPF_,
00191 photons,
00192 photonCandidateMap,
00193 pfCandidateRefProd);
00194
00195
00196 edm::ValueMap<reco::PFCandidatePtr> pfMapMuons;
00197
00198 if(fillMuonRefs_){
00199 edm::Handle<reco::MuonCollection> muons;
00200 iEvent.getByLabel(inputTagMuons_.label(), muons);
00201
00202 pfMapMuons = fillValueMap<reco::MuonCollection>(iEvent,
00203 inputTagMuons_.label(),
00204 muons,
00205 muonCandidateMap,
00206 pfCandidateRefProd);
00207 }
00208
00209 std::auto_ptr<edm::ValueMap<reco::PFCandidatePtr> >
00210 pfMapMerged(new edm::ValueMap<reco::PFCandidatePtr>());
00211 edm::ValueMap<reco::PFCandidatePtr>::Filler pfMapMergedFiller(*pfMapMerged);
00212
00213 *pfMapMerged += pfMapGsfElectrons;
00214 *pfMapMerged += pfMapPhotons;
00215 if(fillMuonRefs_) *pfMapMerged += pfMapMuons;
00216
00217 iEvent.put(pfMapMerged,nameOutputMergedPF_);
00218 }
00219
00220 template<typename T>
00221 bool PFLinker::fetchCollection(edm::Handle<T>& c,
00222 const edm::InputTag& tag,
00223 const edm::Event& iEvent) const {
00224
00225 bool found = iEvent.getByLabel(tag, c);
00226
00227 if(!found )
00228 {
00229 std::ostringstream err;
00230 err<<" cannot get " <<tag<<std::endl;
00231 edm::LogError("PFLinker")<<err.str();
00232 }
00233 return found;
00234 }
00235
00236
00237
00238 template<typename TYPE>
00239 edm::ValueMap<reco::PFCandidatePtr> PFLinker::fillValueMap(edm::Event & event,
00240 std::string label,
00241 edm::Handle<TYPE>& inputObjCollection,
00242 const std::map<edm::Ref<TYPE>, reco::PFCandidatePtr> & mapToTheCandidate,
00243 const edm::OrphanHandle<reco::PFCandidateCollection> & newPFCandColl) const {
00244
00245 std::auto_ptr<edm::ValueMap<reco::PFCandidatePtr> > pfMap_p(new edm::ValueMap<reco::PFCandidatePtr>());
00246 edm::ValueMap<reco::PFCandidatePtr>::Filler filler(*pfMap_p);
00247
00248 typedef typename std::map<edm::Ref<TYPE>, reco::PFCandidatePtr>::const_iterator MapTYPE_it;
00249
00250 unsigned nObj=inputObjCollection->size();
00251 std::vector<reco::PFCandidatePtr> values(nObj);
00252
00253 for(unsigned iobj=0; iobj < nObj; ++iobj) {
00254
00255 edm::Ref<TYPE> objRef(inputObjCollection, iobj);
00256 MapTYPE_it itcheck = mapToTheCandidate.find(objRef);
00257
00258 reco::PFCandidatePtr candPtr;
00259
00260 if(itcheck != mapToTheCandidate.end())
00261 candPtr = producePFCandidates_ ? reco::PFCandidatePtr(newPFCandColl,itcheck->second.key()) : itcheck->second;
00262
00263 values[iobj] = candPtr;
00264 }
00265
00266 filler.insert(inputObjCollection,values.begin(),values.end());
00267 filler.fill();
00268 edm::ValueMap<reco::PFCandidatePtr> returnValue = *pfMap_p;
00269 event.put(pfMap_p,label);
00270 return returnValue;
00271 }