New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix hot HCAL channels in legacy 2016 #22713
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
3a76893
official recipe: first try
deguio 27576d6
attempt to handle refs properly
deguio e8765f9
fix logic and update re-miniAOD
deguio a01f0ce
change strategy
deguio d139529
further refine logic
deguio 8cee86c
implemented some of the requested changes
deguio 06f63a8
customize reminiaod WFs
deguio 50c08dc
fix 2017 REMINIAOD WF
deguio 0aa582b
apply code-checks suggestions
deguio 5c426cc
implement comments
deguio efcc410
more fixes
deguio faee669
apply code checks
deguio 0c0346f
Address code review
gpetruc 8ea4eba
implement comments from slava
deguio 2f0d628
implementing comments
deguio 8ee9fc9
update the data GTs with buggy HCAL response tag
arunhep 2457911
Merged refs/pull/22713/head from repository cms-sw with cms-merge-topic
deguio 8e68392
adapt to 94x
deguio 19915d6
Merge branch 'CMSSW_9_4_MAOD_X' into fixLegacy2016
fabiocos File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
354 changes: 354 additions & 0 deletions
354
CommonTools/ParticleFlow/plugins/PFCandidateRecalibrator.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,354 @@ | ||
/// 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/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<> { | ||
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_; | ||
|
||
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"))), | ||
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) | ||
{ | ||
if (hcalDbWatcher_.check(iSetup) || hcalRCWatcher_.check(iSetup)) | ||
{ | ||
//Get Calib Constants from current GT | ||
edm::ESHandle<HcalDbService> gtCond; | ||
iSetup.get<HcalDbRecord>().get(gtCond); | ||
|
||
//Get Calib Constants from bugged tag | ||
edm::ESHandle<HcalTopology> htopo; | ||
iSetup.get<HcalRecNumberingRecord>().get(htopo); | ||
const HcalTopology* theHBHETopology = htopo.product(); | ||
|
||
edm::ESHandle<HcalRespCorrs> buggedCond; | ||
iSetup.get<HcalRespCorrsRcd>().get("bugged", buggedCond); | ||
HcalRespCorrs buggedRespCorrs(*buggedCond.product()); | ||
buggedRespCorrs.setTopo(theHBHETopology); | ||
|
||
//access calogeometry | ||
edm::ESHandle<CaloGeometry> calogeom; | ||
iSetup.get<CaloGeometryRecord>().get(calogeom); | ||
const CaloGeometry* cgeo = calogeom.product(); | ||
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 | ||
edm::ESHandle<CaloGeometry> calogeom; | ||
iSetup.get<CaloGeometryRecord>().get(calogeom); | ||
const CaloGeometry* cgeo = calogeom.product(); | ||
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fabozzi @prebello
please confirm that this modifier approach is OK for the workflow submission
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this is reused later in the 2017 setup
steps['REMINIAOD_data2017'] = merge([{'--era' : 'Run2_2017,run2_miniAOD_94XFall17'},steps['REMINIAOD_data2016']])
That part should be modified to undo the change for --customise_unsch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was still working on 9_4_1 and I missed that. will fix