File indexing completed on 2024-06-22 02:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 #include "DataFormats/EgammaCandidates/interface/Photon.h"
0012 #include "FWCore/Framework/interface/stream/EDProducer.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "FWCore/Framework/interface/Event.h"
0015 #include "FWCore/Framework/interface/MakerMacros.h"
0016 #include "DataFormats/Common/interface/ValueMap.h"
0017 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0018 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0019 #include "DataFormats/MuonReco/interface/MuonToMuonMap.h"
0020
0021 namespace edm {
0022 class EventSetup;
0023 }
0024
0025 class PFLinker : public edm::stream::EDProducer<> {
0026 public:
0027 explicit PFLinker(const edm::ParameterSet&);
0028
0029 ~PFLinker() override;
0030
0031 void produce(edm::Event&, const edm::EventSetup&) override;
0032 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0033
0034 private:
0035 template <typename TYPE>
0036 edm::ValueMap<reco::PFCandidatePtr> fillValueMap(
0037 edm::Event& event,
0038 std::string label,
0039 edm::Handle<TYPE>& inputObjCollection,
0040 const std::map<edm::Ref<TYPE>, reco::PFCandidatePtr>& mapToTheCandidate,
0041 const edm::OrphanHandle<reco::PFCandidateCollection>& newPFCandColl) const;
0042
0043 private:
0044
0045 std::vector<edm::EDGetTokenT<reco::PFCandidateCollection>> inputTagPFCandidates_;
0046
0047
0048 edm::EDGetTokenT<reco::GsfElectronCollection> inputTagGsfElectrons_;
0049
0050
0051 edm::EDGetTokenT<reco::PhotonCollection> inputTagPhotons_;
0052
0053
0054 edm::InputTag muonTag_;
0055 edm::EDGetTokenT<reco::MuonCollection> inputTagMuons_;
0056 edm::EDGetTokenT<reco::MuonToMuonMap> inputTagMuonMap_;
0057
0058 std::string nameOutputPF_;
0059
0060
0061 std::string nameOutputElectronsPF_;
0062
0063
0064 std::string nameOutputPhotonsPF_;
0065
0066
0067 std::string nameOutputMergedPF_;
0068
0069
0070 bool producePFCandidates_;
0071
0072
0073 bool fillMuonRefs_;
0074
0075
0076 bool forceElectronsInHGCAL_;
0077 };
0078
0079 DEFINE_FWK_MODULE(PFLinker);
0080
0081 void PFLinker::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0082 edm::ParameterSetDescription desc;
0083 desc.add<std::vector<edm::InputTag>>("PFCandidate", {edm::InputTag("particleFlow")});
0084 desc.add<edm::InputTag>("GsfElectrons", {"gedGsfElectrons"});
0085 desc.add<edm::InputTag>("Photons", {"gedPhotons"});
0086 desc.add<edm::InputTag>("Muons", {"muons", "muons1stStep2muonsMap"});
0087 desc.add<bool>("ProducePFCandidates", true);
0088 desc.add<bool>("FillMuonRefs", true);
0089 desc.add<std::string>("OutputPF", "");
0090 desc.add<std::string>("ValueMapElectrons", "electrons");
0091 desc.add<std::string>("ValueMapPhotons", "photons");
0092 desc.add<std::string>("ValueMapMerged", "all");
0093 desc.add<bool>("forceElectronsInHGCAL", false);
0094 descriptions.addWithDefaultLabel(desc);
0095 }
0096
0097 PFLinker::PFLinker(const edm::ParameterSet& iConfig) {
0098
0099
0100 std::vector<edm::InputTag> tags = iConfig.getParameter<std::vector<edm::InputTag>>("PFCandidate");
0101 for (unsigned int i = 0; i < tags.size(); ++i)
0102 inputTagPFCandidates_.push_back(consumes<reco::PFCandidateCollection>(tags[i]));
0103
0104 inputTagGsfElectrons_ = consumes<reco::GsfElectronCollection>(iConfig.getParameter<edm::InputTag>("GsfElectrons"));
0105
0106 inputTagPhotons_ = consumes<reco::PhotonCollection>(iConfig.getParameter<edm::InputTag>("Photons"));
0107
0108 muonTag_ = iConfig.getParameter<edm::InputTag>("Muons");
0109 inputTagMuons_ = consumes<reco::MuonCollection>(edm::InputTag(muonTag_.label()));
0110 inputTagMuonMap_ = consumes<reco::MuonToMuonMap>(muonTag_);
0111
0112 nameOutputPF_ = iConfig.getParameter<std::string>("OutputPF");
0113
0114 nameOutputElectronsPF_ = iConfig.getParameter<std::string>("ValueMapElectrons");
0115
0116 nameOutputPhotonsPF_ = iConfig.getParameter<std::string>("ValueMapPhotons");
0117
0118 producePFCandidates_ = iConfig.getParameter<bool>("ProducePFCandidates");
0119
0120 nameOutputMergedPF_ = iConfig.getParameter<std::string>("ValueMapMerged");
0121
0122 fillMuonRefs_ = iConfig.getParameter<bool>("FillMuonRefs");
0123
0124 forceElectronsInHGCAL_ = iConfig.getParameter<bool>("forceElectronsInHGCAL");
0125
0126
0127 if (producePFCandidates_ && inputTagPFCandidates_.size() > 1) {
0128 edm::LogError("PFLinker")
0129 << " cannot read several collections of PFCandidates and produce a new collection at the same time. "
0130 << std::endl;
0131 assert(false);
0132 }
0133 if (producePFCandidates_) {
0134 produces<reco::PFCandidateCollection>(nameOutputPF_);
0135 }
0136 produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputElectronsPF_);
0137 produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputPhotonsPF_);
0138 produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputMergedPF_);
0139 if (fillMuonRefs_)
0140 produces<edm::ValueMap<reco::PFCandidatePtr>>(muonTag_.label());
0141 }
0142
0143 PFLinker::~PFLinker() { ; }
0144
0145 void PFLinker::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0146 auto pfCandidates_p = std::make_unique<reco::PFCandidateCollection>();
0147
0148 auto gsfElectrons = iEvent.getHandle(inputTagGsfElectrons_);
0149
0150 std::map<reco::GsfElectronRef, reco::PFCandidatePtr> electronCandidateMap;
0151
0152 auto photons = iEvent.getHandle(inputTagPhotons_);
0153 std::map<reco::PhotonRef, reco::PFCandidatePtr> photonCandidateMap;
0154
0155 edm::Handle<reco::MuonToMuonMap> muonMap;
0156 if (fillMuonRefs_)
0157 muonMap = iEvent.getHandle(inputTagMuonMap_);
0158 std::map<reco::MuonRef, reco::PFCandidatePtr> muonCandidateMap;
0159
0160 unsigned nColPF = inputTagPFCandidates_.size();
0161
0162 for (unsigned icol = 0; icol < nColPF; ++icol) {
0163 auto pfCandidates = iEvent.getHandle(inputTagPFCandidates_[icol]);
0164 unsigned ncand = pfCandidates->size();
0165
0166 for (unsigned i = 0; i < ncand; ++i) {
0167 edm::Ptr<reco::PFCandidate> candPtr(pfCandidates, i);
0168 reco::PFCandidate cand(candPtr);
0169
0170 bool isphoton = cand.particleId() == reco::PFCandidate::gamma && cand.mva_nothing_gamma() > 0.;
0171 bool iselectron = cand.particleId() == reco::PFCandidate::e;
0172
0173 bool hasNonNullMuonRef = cand.muonRef().isNonnull() && fillMuonRefs_;
0174
0175
0176 if (!(isphoton || iselectron || hasNonNullMuonRef)) {
0177 pfCandidates_p->push_back(cand);
0178 continue;
0179 }
0180
0181 if (hasNonNullMuonRef) {
0182 reco::MuonRef muRef = (*muonMap)[cand.muonRef()];
0183 cand.setMuonRef(muRef);
0184 muonCandidateMap[muRef] = candPtr;
0185 }
0186
0187
0188 if (iselectron) {
0189 const reco::GsfTrackRef& gsfTrackRef(cand.gsfTrackRef());
0190 auto itcheck = find_if(gsfElectrons->begin(), gsfElectrons->end(), [&gsfTrackRef](const auto& ele) {
0191 return (ele.gsfTrack() == gsfTrackRef);
0192 });
0193 if (itcheck == gsfElectrons->end()) {
0194 if (!forceElectronsInHGCAL_) {
0195 std::ostringstream err;
0196 err << " Problem in PFLinker: no GsfElectron " << std::endl;
0197 edm::LogError("PFLinker") << err.str();
0198 } else {
0199 LogDebug("PFLinker") << "Forcing an electron pfCandidate at: " << cand.eta() << " in HGCAL" << std::endl;
0200 pfCandidates_p->push_back(cand);
0201 }
0202 continue;
0203 }
0204 reco::GsfElectronRef electronRef(gsfElectrons, itcheck - gsfElectrons->begin());
0205 cand.setGsfElectronRef(electronRef);
0206 cand.setSuperClusterRef(electronRef->superCluster());
0207
0208 cand.setEcalEnergy(electronRef->superCluster()->rawEnergy(), electronRef->ecalEnergy());
0209 cand.setDeltaP(electronRef->p4Error(reco::GsfElectron::P4_COMBINATION));
0210 cand.setP4(electronRef->p4(reco::GsfElectron::P4_COMBINATION));
0211 electronCandidateMap[electronRef] = candPtr;
0212 }
0213
0214
0215 if (isphoton) {
0216 const reco::SuperClusterRef& scRef(cand.superClusterRef());
0217 auto itcheck = find_if(
0218 photons->begin(), photons->end(), [&scRef](const auto& photon) { return photon.superCluster() == scRef; });
0219 if (itcheck == photons->end()) {
0220 std::ostringstream err;
0221 err << " Problem in PFLinker: no Photon " << std::endl;
0222 edm::LogError("PFLinker") << err.str();
0223 continue;
0224 }
0225 reco::PhotonRef photonRef(photons, itcheck - photons->begin());
0226 cand.setPhotonRef(photonRef);
0227 cand.setSuperClusterRef(photonRef->superCluster());
0228
0229 cand.setEcalEnergy(photonRef->superCluster()->rawEnergy(),
0230 photonRef->getCorrectedEnergy(reco::Photon::regression2));
0231 cand.setDeltaP(photonRef->getCorrectedEnergyError(reco::Photon::regression2));
0232 cand.setP4(photonRef->p4(reco::Photon::regression2));
0233 photonCandidateMap[photonRef] = candPtr;
0234 }
0235
0236 pfCandidates_p->push_back(cand);
0237 }
0238
0239 }
0240 const edm::OrphanHandle<reco::PFCandidateCollection> pfCandidateRefProd =
0241 (producePFCandidates_) ? iEvent.put(std::move(pfCandidates_p), nameOutputPF_)
0242 : edm::OrphanHandle<reco::PFCandidateCollection>();
0243
0244
0245
0246 edm::ValueMap<reco::PFCandidatePtr> pfMapGsfElectrons = fillValueMap<reco::GsfElectronCollection>(
0247 iEvent, nameOutputElectronsPF_, gsfElectrons, electronCandidateMap, pfCandidateRefProd);
0248
0249 edm::ValueMap<reco::PFCandidatePtr> pfMapPhotons = fillValueMap<reco::PhotonCollection>(
0250 iEvent, nameOutputPhotonsPF_, photons, photonCandidateMap, pfCandidateRefProd);
0251
0252 edm::ValueMap<reco::PFCandidatePtr> pfMapMuons;
0253
0254 if (fillMuonRefs_) {
0255 auto muons = iEvent.getHandle(inputTagMuons_);
0256
0257 pfMapMuons =
0258 fillValueMap<reco::MuonCollection>(iEvent, muonTag_.label(), muons, muonCandidateMap, pfCandidateRefProd);
0259 }
0260
0261 auto pfMapMerged = std::make_unique<edm::ValueMap<reco::PFCandidatePtr>>();
0262 edm::ValueMap<reco::PFCandidatePtr>::Filler pfMapMergedFiller(*pfMapMerged);
0263
0264 *pfMapMerged += pfMapGsfElectrons;
0265 *pfMapMerged += pfMapPhotons;
0266 if (fillMuonRefs_)
0267 *pfMapMerged += pfMapMuons;
0268
0269 iEvent.put(std::move(pfMapMerged), nameOutputMergedPF_);
0270 }
0271
0272 template <typename TYPE>
0273 edm::ValueMap<reco::PFCandidatePtr> PFLinker::fillValueMap(
0274 edm::Event& event,
0275 std::string label,
0276 edm::Handle<TYPE>& inputObjCollection,
0277 const std::map<edm::Ref<TYPE>, reco::PFCandidatePtr>& mapToTheCandidate,
0278 const edm::OrphanHandle<reco::PFCandidateCollection>& newPFCandColl) const {
0279 auto pfMap_p = std::make_unique<edm::ValueMap<reco::PFCandidatePtr>>();
0280 edm::ValueMap<reco::PFCandidatePtr>::Filler filler(*pfMap_p);
0281
0282 typedef typename std::map<edm::Ref<TYPE>, reco::PFCandidatePtr>::const_iterator MapTYPE_it;
0283
0284 unsigned nObj = inputObjCollection->size();
0285 std::vector<reco::PFCandidatePtr> values(nObj);
0286
0287 for (unsigned iobj = 0; iobj < nObj; ++iobj) {
0288 edm::Ref<TYPE> objRef(inputObjCollection, iobj);
0289 MapTYPE_it itcheck = mapToTheCandidate.find(objRef);
0290
0291 reco::PFCandidatePtr candPtr;
0292
0293 if (itcheck != mapToTheCandidate.end())
0294 candPtr = producePFCandidates_ ? reco::PFCandidatePtr(newPFCandColl, itcheck->second.key()) : itcheck->second;
0295
0296 values[iobj] = candPtr;
0297 }
0298
0299 filler.insert(inputObjCollection, values.begin(), values.end());
0300 filler.fill();
0301 edm::ValueMap<reco::PFCandidatePtr> returnValue = *pfMap_p;
0302 event.put(std::move(pfMap_p), label);
0303 return returnValue;
0304 }