/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
CommonTools/ParticleFlow/plugins/PFCandidateRecalibrator.cc
323 строки
13 KB
Christopher Jones
Add edm::stream::Watch* to CommonTools modules
24 мар 2026, 19:22
24 мар 2026, 19:22
b34646c
Код
Авторство
О чём код?
/// Take: // - a PF candidate collection (which uses bugged HCAL respcorrs) // - respCorrs values from fixed GT and bugged GT // Produce: // - a new PFCandidate collection containing the recalibrated PFCandidates in HF and where the neutral had pointing to problematic cells are removed // - a second PFCandidate collection with just those discarded hadrons // - a ValueMap<reco::PFCandidateRef> that maps the old to the new, and vice-versa #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/ESWatcher.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Event.h" #include "CalibFormats/HcalObjects/interface/HcalDbService.h" #include "CalibFormats/HcalObjects/interface/HcalDbRecord.h" #include "CalibFormats/HcalObjects/interface/HcalCalibrations.h" #include "Geometry/CaloTopology/interface/HcalTopology.h" #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h" #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" #include "Geometry/CaloGeometry/interface/CaloGeometry.h" #include "Geometry/Records/interface/CaloGeometryRecord.h" #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h" #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" #include "DataFormats/Common/interface/View.h" #include "DataFormats/Common/interface/Association.h" #include <iostream> struct HEChannel { float eta; float phi; float ratio; HEChannel(float eta, float phi, float ratio) : eta(eta), phi(phi), ratio(ratio) {} }; struct HFChannel { int ieta; int iphi; int depth; float ratio; HFChannel(int ieta, int iphi, int depth, float ratio) : ieta(ieta), iphi(iphi), depth(depth), ratio(ratio) {} }; class PFCandidateRecalibrator : public edm::stream::EDProducer<edm::stream::WatchRuns> { public: PFCandidateRecalibrator(const edm::ParameterSet&); ~PFCandidateRecalibrator() override {} static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); private: void beginRun(const edm::Run& iRun, edm::EventSetup const& iSetup) override; void endRun(const edm::Run& iRun, edm::EventSetup const& iSetup) override; void produce(edm::Event&, const edm::EventSetup&) override; edm::ESWatcher<HcalRecNumberingRecord> hcalDbWatcher_; edm::ESWatcher<HcalRespCorrsRcd> hcalRCWatcher_; edm::EDGetTokenT<reco::PFCandidateCollection> pfcandidates_; const edm::ESGetToken<HcalDbService, HcalDbRecord> gtCondToken_; const edm::ESGetToken<HcalTopology, HcalRecNumberingRecord> htopoToken_; const edm::ESGetToken<HcalRespCorrs, HcalRespCorrsRcd> buggedCondToken_; const edm::ESGetToken<CaloGeometry, CaloGeometryRecord> calogeomTokenRun_; const edm::ESGetToken<CaloGeometry, CaloGeometryRecord> calogeomTokenEvent_; std::vector<HEChannel> badChHE_; std::vector<HFChannel> badChHF_; float shortFibreThr_; float longFibreThr_; }; PFCandidateRecalibrator::PFCandidateRecalibrator(const edm::ParameterSet& iConfig) : pfcandidates_(consumes<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfcandidates"))), gtCondToken_(esConsumes<edm::Transition::BeginRun>()), htopoToken_(esConsumes<edm::Transition::BeginRun>()), buggedCondToken_(esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", "bugged"))), calogeomTokenRun_(esConsumes<edm::Transition::BeginRun>()), calogeomTokenEvent_(esConsumes()), shortFibreThr_(iConfig.getParameter<double>("shortFibreThr")), longFibreThr_(iConfig.getParameter<double>("longFibreThr")) { produces<reco::PFCandidateCollection>(); produces<reco::PFCandidateCollection>("discarded"); produces<edm::ValueMap<reco::PFCandidateRef>>(); } void PFCandidateRecalibrator::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { auto newDb = hcalDbWatcher_.check(iSetup); auto newRC = hcalRCWatcher_.check(iSetup); if (newDb || newRC) { //Get Calib Constants from current GT HcalDbService const& gtCond = iSetup.getData(gtCondToken_); //Get Calib Constants from bugged tag const HcalTopology& theHBHETopology = iSetup.getData(htopoToken_); HcalRespCorrs buggedRespCorrs = iSetup.getData(buggedCondToken_); buggedRespCorrs.setTopo(&theHBHETopology); //access calogeometry const CaloGeometry& cgeo = iSetup.getData(calogeomTokenRun_); const HcalGeometry* hgeom = static_cast<const HcalGeometry*>(cgeo.getSubdetectorGeometry(DetId::Hcal, HcalForward)); //reset the bad channel containers badChHE_.clear(); badChHF_.clear(); //fill bad cells HE (use eta, phi) const std::vector<DetId>& cellsHE = hgeom->getValidDetIds(DetId::Detector::Hcal, HcalEndcap); for (auto id : cellsHE) { float currentRespCorr = gtCond.getHcalRespCorr(id)->getValue(); float buggedRespCorr = buggedRespCorrs.getValues(id)->getValue(); if (buggedRespCorr == 0.) continue; float ratio = currentRespCorr / buggedRespCorr; if (std::abs(ratio - 1.f) > 0.001) { GlobalPoint pos = hgeom->getPosition(id); badChHE_.push_back(HEChannel(pos.eta(), pos.phi(), ratio)); } } //fill bad cells HF (use ieta, iphi) auto const& cellsHF = hgeom->getValidDetIds(DetId::Detector::Hcal, HcalForward); for (auto id : cellsHF) { float currentRespCorr = gtCond.getHcalRespCorr(id)->getValue(); float buggedRespCorr = buggedRespCorrs.getValues(id)->getValue(); if (buggedRespCorr == 0.) continue; float ratio = currentRespCorr / buggedRespCorr; if (std::abs(ratio - 1.f) > 0.001) { HcalDetId dummyId(id); badChHF_.push_back(HFChannel(dummyId.ieta(), dummyId.iphi(), dummyId.depth(), ratio)); } } } } void PFCandidateRecalibrator::endRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {} void PFCandidateRecalibrator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { //access calogeometry const CaloGeometry& cgeo = iSetup.getData(calogeomTokenEvent_); const HcalGeometry* hgeom = static_cast<const HcalGeometry*>(cgeo.getSubdetectorGeometry(DetId::Hcal, HcalForward)); //access PFCandidates edm::Handle<reco::PFCandidateCollection> pfcandidates; iEvent.getByToken(pfcandidates_, pfcandidates); int nPfCand = pfcandidates->size(); std::unique_ptr<reco::PFCandidateCollection> copy(new reco::PFCandidateCollection()); std::unique_ptr<reco::PFCandidateCollection> discarded(new reco::PFCandidateCollection()); copy->reserve(nPfCand); std::vector<int> oldToNew(nPfCand), newToOld, badToOld; newToOld.reserve(nPfCand); LogDebug("PFCandidateRecalibrator") << "NEW EV:"; //loop over PFCandidates int i = -1; for (const reco::PFCandidate& pf : *pfcandidates) { ++i; float absEta = std::abs(pf.eta()); //deal with HE if (pf.particleId() == reco::PFCandidate::ParticleType::h0 && !badChHE_.empty() && //don't touch if no miscalibration is found absEta > 1.4 && absEta < 3.) { bool toKill = false; for (auto const& badIt : badChHE_) if (reco::deltaR2(pf.eta(), pf.phi(), badIt.eta, badIt.phi) < 0.07) toKill = true; if (toKill) { discarded->push_back(pf); oldToNew[i] = (-discarded->size()); badToOld.push_back(i); continue; } else { copy->push_back(pf); oldToNew[i] = (copy->size()); newToOld.push_back(i); } } //deal with HF else if ((pf.particleId() == reco::PFCandidate::ParticleType::h_HF || pf.particleId() == reco::PFCandidate::ParticleType::egamma_HF) && !badChHF_.empty() && //don't touch if no miscalibration is found absEta >= 3.) { const math::XYZPointF& ecalPoint = pf.positionAtECALEntrance(); GlobalPoint ecalGPoint(ecalPoint.X(), ecalPoint.Y(), ecalPoint.Z()); HcalDetId closestDetId(hgeom->getClosestCell(ecalGPoint)); if (closestDetId.subdet() == HcalForward) { HcalDetId hDetId(closestDetId.subdet(), closestDetId.ieta(), closestDetId.iphi(), 1); //depth1 //raw*calEnergy() is the same as *calEnergy() - no corrections are done for HF float longE = pf.rawEcalEnergy() + pf.rawHcalEnergy() / 2.; //depth1 float shortE = pf.rawHcalEnergy() / 2.; //depth2 float ecalEnergy = pf.rawEcalEnergy(); float hcalEnergy = pf.rawHcalEnergy(); float totEnergy = ecalEnergy + hcalEnergy; float totEnergyOrig = totEnergy; bool toKill = false; for (auto const& badIt : badChHF_) { if (hDetId.ieta() == badIt.ieta && hDetId.iphi() == badIt.iphi) { LogDebug("PFCandidateRecalibrator") << "==> orig en (tot,H,E): " << pf.energy() << " " << pf.rawHcalEnergy() << " " << pf.rawEcalEnergy(); if (badIt.depth == 1) //depth1 { longE *= badIt.ratio; ecalEnergy = ((longE - shortE) > 0.) ? (longE - shortE) : 0.; totEnergy = ecalEnergy + hcalEnergy; } else //depth2 { shortE *= badIt.ratio; hcalEnergy = 2 * shortE; ecalEnergy = ((longE - shortE) > 0.) ? (longE - shortE) : 0.; totEnergy = ecalEnergy + hcalEnergy; } //kill candidate if goes below thr if ((pf.particleId() == reco::PFCandidate::ParticleType::h_HF && shortE < shortFibreThr_) || (pf.particleId() == reco::PFCandidate::ParticleType::egamma_HF && longE < longFibreThr_)) toKill = true; LogDebug("PFCandidateRecalibrator") << "====> ieta,iphi,depth: " << badIt.ieta << " " << badIt.iphi << " " << badIt.depth << " corr: " << badIt.ratio; LogDebug("PFCandidateRecalibrator") << "====> recal en (tot,H,E): " << totEnergy << " " << hcalEnergy << " " << ecalEnergy; } } if (toKill) { discarded->push_back(pf); oldToNew[i] = (-discarded->size()); badToOld.push_back(i); LogDebug("PFCandidateRecalibrator") << "==> KILLED "; } else { copy->push_back(pf); oldToNew[i] = (copy->size()); newToOld.push_back(i); copy->back().setHcalEnergy(hcalEnergy, hcalEnergy); copy->back().setEcalEnergy(ecalEnergy, ecalEnergy); float scalingFactor = totEnergy / totEnergyOrig; math::XYZTLorentzVector recalibP4 = pf.p4() * scalingFactor; copy->back().setP4(recalibP4); LogDebug("PFCandidateRecalibrator") << "====> stored en (tot,H,E): " << copy->back().energy() << " " << copy->back().hcalEnergy() << " " << copy->back().ecalEnergy(); } } else { copy->push_back(pf); oldToNew[i] = (copy->size()); newToOld.push_back(i); } } else { copy->push_back(pf); oldToNew[i] = (copy->size()); newToOld.push_back(i); } } // Now we put things in the event edm::OrphanHandle<reco::PFCandidateCollection> newpf = iEvent.put(std::move(copy)); edm::OrphanHandle<reco::PFCandidateCollection> badpf = iEvent.put(std::move(discarded), "discarded"); std::unique_ptr<edm::ValueMap<reco::PFCandidateRef>> pf2pf(new edm::ValueMap<reco::PFCandidateRef>()); edm::ValueMap<reco::PFCandidateRef>::Filler filler(*pf2pf); std::vector<reco::PFCandidateRef> refs; refs.reserve(nPfCand); // old to new for (auto iOldToNew : oldToNew) { if (iOldToNew > 0) { refs.push_back(reco::PFCandidateRef(newpf, iOldToNew - 1)); } else { refs.push_back(reco::PFCandidateRef(badpf, -iOldToNew - 1)); } } filler.insert(pfcandidates, refs.begin(), refs.end()); // new good to old refs.clear(); for (int i : newToOld) { refs.push_back(reco::PFCandidateRef(pfcandidates, i)); } filler.insert(newpf, refs.begin(), refs.end()); // new bad to old refs.clear(); for (int i : badToOld) { refs.push_back(reco::PFCandidateRef(pfcandidates, i)); } filler.insert(badpf, refs.begin(), refs.end()); // done filler.fill(); iEvent.put(std::move(pf2pf)); } void PFCandidateRecalibrator::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add<edm::InputTag>("pfcandidates", edm::InputTag("particleFlow")); desc.add<double>("shortFibreThr", 1.4); desc.add<double>("longFibreThr", 1.4); descriptions.add("pfCandidateRecalibrator", desc); } #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(PFCandidateRecalibrator);