File indexing completed on 2024-06-22 02:24:06
0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/Utilities/interface/EDPutToken.h"
0004 #include "FWCore/Framework/interface/MakerMacros.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "FWCore/ParameterSet/interface/EmptyGroupDescription.h"
0007 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0008 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
0009 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementSuperCluster.h"
0010 #include "DataFormats/Common/interface/ValueMap.h"
0011 #include "RecoParticleFlow/PFProducer/interface/PFEGammaFilters.h"
0012 #include "RecoParticleFlow/PFProducer/interface/PFAlgo.h"
0013 #include "FWCore/Framework/interface/MakerMacros.h"
0014 #include "FWCore/Framework/interface/ESHandle.h"
0015 #include "FWCore/Framework/interface/EventSetup.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
0018 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibrationHF.h"
0019 #include "CondFormats/PhysicsToolsObjects/interface/PerformancePayloadFromTFormula.h"
0020 #include "CondFormats/DataRecord/interface/PFCalibrationRcd.h"
0021 #include "CondFormats/DataRecord/interface/GBRWrapperRcd.h"
0022
0023 #include <sstream>
0024 #include <string>
0025
0026 #include "TFile.h"
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 class PFProducer : public edm::stream::EDProducer<> {
0038 public:
0039 explicit PFProducer(const edm::ParameterSet&);
0040
0041 void produce(edm::Event&, const edm::EventSetup&) override;
0042 void beginRun(const edm::Run&, const edm::EventSetup&) override;
0043
0044 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0045
0046 private:
0047 const edm::EDPutTokenT<reco::PFCandidateCollection> pfCandidatesToken_;
0048 const edm::EDPutTokenT<reco::PFCandidateCollection> pfCleanedCandidatesToken_;
0049 edm::ESGetToken<PerformancePayload, PFCalibrationRcd> perfToken_;
0050
0051 const edm::EDGetTokenT<reco::PFBlockCollection> inputTagBlocks_;
0052 edm::EDGetTokenT<reco::MuonCollection> inputTagMuons_;
0053 edm::EDGetTokenT<reco::VertexCollection> vertices_;
0054 edm::EDGetTokenT<reco::GsfElectronCollection> inputTagEgammaElectrons_;
0055
0056 std::vector<edm::EDGetTokenT<reco::PFRecHitCollection>> inputTagCleanedHF_;
0057 std::string electronExtraOutputCol_;
0058 std::string photonExtraOutputCol_;
0059
0060 bool vetoEndcap_;
0061 edm::EDGetTokenT<reco::PFCandidateCollection> inputTagVetoes_;
0062
0063
0064 edm::EDGetTokenT<edm::ValueMap<reco::GsfElectronRef>> inputTagValueMapGedElectrons_;
0065 edm::EDGetTokenT<edm::ValueMap<reco::PhotonRef>> inputTagValueMapGedPhotons_;
0066 edm::EDGetTokenT<edm::View<reco::PFCandidate>> inputTagPFEGammaCandidates_;
0067
0068 bool use_EGammaFilters_;
0069 std::unique_ptr<PFEGammaFilters> pfegamma_ = nullptr;
0070
0071
0072 bool useHO_;
0073
0074
0075 bool verbose_;
0076
0077
0078 bool postMuonCleaning_;
0079
0080
0081 bool useEGammaElectrons_;
0082
0083
0084 bool useVerticesForNeutral_;
0085
0086
0087 bool useCalibrationsFromDB_;
0088 std::string calibrationsLabel_;
0089
0090 bool postHFCleaning_;
0091
0092
0093
0094
0095 PFEnergyCalibration pfEnergyCalibration_;
0096 PFEnergyCalibrationHF pfEnergyCalibrationHF_;
0097
0098
0099 PFAlgo pfAlgo_;
0100 };
0101
0102 DEFINE_FWK_MODULE(PFProducer);
0103
0104 using namespace std;
0105 using namespace edm;
0106
0107 PFProducer::PFProducer(const edm::ParameterSet& iConfig)
0108 : pfCandidatesToken_{produces<reco::PFCandidateCollection>()},
0109 pfCleanedCandidatesToken_{produces<reco::PFCandidateCollection>("CleanedHF")},
0110 inputTagBlocks_(consumes<reco::PFBlockCollection>(iConfig.getParameter<InputTag>("blocks"))),
0111 pfEnergyCalibrationHF_(iConfig.getParameter<bool>("calibHF_use"),
0112 iConfig.getParameter<std::vector<double>>("calibHF_eta_step"),
0113 iConfig.getParameter<std::vector<double>>("calibHF_a_EMonly"),
0114 iConfig.getParameter<std::vector<double>>("calibHF_b_HADonly"),
0115 iConfig.getParameter<std::vector<double>>("calibHF_a_EMHAD"),
0116 iConfig.getParameter<std::vector<double>>("calibHF_b_EMHAD")),
0117 pfAlgo_(iConfig.getParameter<double>("pf_nsigma_ECAL"),
0118 iConfig.getParameter<double>("pf_nsigma_HCAL"),
0119 iConfig.getParameter<double>("pf_nsigma_HFEM"),
0120 iConfig.getParameter<double>("pf_nsigma_HFHAD"),
0121 iConfig.getParameter<std::vector<double>>("resolHF_square"),
0122 pfEnergyCalibration_,
0123 pfEnergyCalibrationHF_,
0124 iConfig) {
0125
0126 inputTagMuons_ = consumes<reco::MuonCollection>(iConfig.getParameter<InputTag>("muons"));
0127 postMuonCleaning_ = iConfig.getParameter<bool>("postMuonCleaning");
0128 vetoEndcap_ = iConfig.getParameter<bool>("vetoEndcap");
0129 if (vetoEndcap_)
0130 inputTagVetoes_ = consumes<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("vetoes"));
0131
0132 use_EGammaFilters_ = iConfig.getParameter<bool>("useEGammaFilters");
0133 useEGammaElectrons_ = iConfig.getParameter<bool>("useEGammaElectrons");
0134
0135 if (useEGammaElectrons_) {
0136 inputTagEgammaElectrons_ =
0137 consumes<reco::GsfElectronCollection>(iConfig.getParameter<edm::InputTag>("egammaElectrons"));
0138 }
0139
0140
0141 produces<reco::PFCandidateCollection>("CleanedCosmicsMuons");
0142 produces<reco::PFCandidateCollection>("CleanedTrackerAndGlobalMuons");
0143 produces<reco::PFCandidateCollection>("CleanedFakeMuons");
0144 produces<reco::PFCandidateCollection>("CleanedPunchThroughMuons");
0145 produces<reco::PFCandidateCollection>("CleanedPunchThroughNeutralHadrons");
0146 produces<reco::PFCandidateCollection>("AddedMuonsAndHadrons");
0147
0148
0149 bool useProtectionsForJetMET(false);
0150
0151
0152 if (use_EGammaFilters_) {
0153 inputTagPFEGammaCandidates_ =
0154 consumes<edm::View<reco::PFCandidate>>((iConfig.getParameter<edm::InputTag>("PFEGammaCandidates")));
0155 inputTagValueMapGedElectrons_ =
0156 consumes<edm::ValueMap<reco::GsfElectronRef>>(iConfig.getParameter<edm::InputTag>("GedElectronValueMap"));
0157 inputTagValueMapGedPhotons_ =
0158 consumes<edm::ValueMap<reco::PhotonRef>>(iConfig.getParameter<edm::InputTag>("GedPhotonValueMap"));
0159 useProtectionsForJetMET = iConfig.getParameter<bool>("useProtectionsForJetMET");
0160
0161 const edm::ParameterSet pfEGammaFiltersParams =
0162 iConfig.getParameter<edm::ParameterSet>("PFEGammaFiltersParameters");
0163 pfegamma_ = std::make_unique<PFEGammaFilters>(pfEGammaFiltersParams);
0164 }
0165
0166
0167 pfAlgo_.setEGammaParameters(use_EGammaFilters_, useProtectionsForJetMET);
0168
0169
0170
0171 bool rejectTracks_Bad = iConfig.getParameter<bool>("rejectTracks_Bad");
0172
0173 bool rejectTracks_Step45 = iConfig.getParameter<bool>("rejectTracks_Step45");
0174
0175 bool usePFNuclearInteractions = iConfig.getParameter<bool>("usePFNuclearInteractions");
0176
0177 bool usePFConversions = iConfig.getParameter<bool>("usePFConversions");
0178
0179 bool usePFDecays = iConfig.getParameter<bool>("usePFDecays");
0180
0181 double dptRel_DispVtx = iConfig.getParameter<double>("dptRel_DispVtx");
0182
0183 useCalibrationsFromDB_ = iConfig.getParameter<bool>("useCalibrationsFromDB");
0184
0185 if (useCalibrationsFromDB_) {
0186 calibrationsLabel_ = iConfig.getParameter<std::string>("calibrationsLabel");
0187 perfToken_ = esConsumes<edm::Transition::BeginRun>(edm::ESInputTag("", calibrationsLabel_));
0188 }
0189
0190 pfAlgo_.setDisplacedVerticesParameters(
0191 rejectTracks_Bad, rejectTracks_Step45, usePFNuclearInteractions, usePFConversions, usePFDecays, dptRel_DispVtx);
0192
0193 if (usePFNuclearInteractions)
0194 pfAlgo_.setCandConnectorParameters(iConfig.getParameter<edm::ParameterSet>("iCfgCandConnector"));
0195
0196
0197 postHFCleaning_ = iConfig.getParameter<bool>("postHFCleaning");
0198 const edm::ParameterSet pfHFCleaningParams = iConfig.getParameter<edm::ParameterSet>("PFHFCleaningParameters");
0199
0200
0201 pfAlgo_.setPostHFCleaningParameters(postHFCleaning_, pfHFCleaningParams);
0202
0203
0204 std::vector<edm::InputTag> tags = iConfig.getParameter<std::vector<edm::InputTag>>("cleanedHF");
0205 for (unsigned int i = 0; i < tags.size(); ++i)
0206 inputTagCleanedHF_.push_back(consumes<reco::PFRecHitCollection>(tags[i]));
0207
0208 vertices_ = consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertexCollection"));
0209 useVerticesForNeutral_ = iConfig.getParameter<bool>("useVerticesForNeutral");
0210
0211
0212 useHO_ = iConfig.getParameter<bool>("useHO");
0213 pfAlgo_.setHOTag(useHO_);
0214
0215 verbose_ = iConfig.getUntrackedParameter<bool>("verbose", false);
0216 }
0217
0218 void PFProducer::beginRun(const edm::Run& run, const edm::EventSetup& es) {
0219 if (useCalibrationsFromDB_) {
0220
0221 auto perfH = es.getHandle(perfToken_);
0222
0223 PerformancePayloadFromTFormula const* pfCalibrations =
0224 static_cast<const PerformancePayloadFromTFormula*>(perfH.product());
0225
0226 pfEnergyCalibration_.setCalibrationFunctions(pfCalibrations);
0227 }
0228 }
0229
0230 void PFProducer::produce(Event& iEvent, const EventSetup& iSetup) {
0231 LogDebug("PFProducer") << "START event: " << iEvent.id().event() << " in run " << iEvent.id().run() << endl;
0232
0233
0234 pfAlgo_.setPFVertexParameters(useVerticesForNeutral_, iEvent.get(vertices_));
0235
0236
0237 auto blocks = iEvent.getHandle(inputTagBlocks_);
0238 assert(blocks.isValid());
0239
0240
0241 if (postMuonCleaning_) {
0242 pfAlgo_.setMuonHandle(iEvent.getHandle(inputTagMuons_));
0243 if (vetoEndcap_) {
0244 auto& muAlgo = *pfAlgo_.getPFMuonAlgo();
0245 muAlgo.setVetoes(iEvent.get(inputTagVetoes_));
0246 }
0247 }
0248
0249 if (use_EGammaFilters_)
0250 pfAlgo_.setEGammaCollections(iEvent.get(inputTagPFEGammaCandidates_),
0251 iEvent.get(inputTagValueMapGedElectrons_),
0252 iEvent.get(inputTagValueMapGedPhotons_));
0253
0254 LogDebug("PFProducer") << "particle flow is starting" << endl;
0255
0256 pfAlgo_.reconstructParticles(blocks, pfegamma_.get());
0257
0258 if (verbose_) {
0259 ostringstream str;
0260 str << pfAlgo_ << endl;
0261 LogInfo("PFProducer") << str.str() << endl;
0262 }
0263
0264
0265 if (postHFCleaning_) {
0266 reco::PFRecHitCollection hfCopy;
0267 for (unsigned ihf = 0; ihf < inputTagCleanedHF_.size(); ++ihf) {
0268 Handle<reco::PFRecHitCollection> hfCleaned;
0269 bool foundHF = iEvent.getByToken(inputTagCleanedHF_[ihf], hfCleaned);
0270 if (!foundHF)
0271 continue;
0272 for (unsigned jhf = 0; jhf < (*hfCleaned).size(); ++jhf) {
0273 hfCopy.push_back((*hfCleaned)[jhf]);
0274 }
0275 }
0276 pfAlgo_.checkCleaning(hfCopy);
0277 }
0278
0279
0280 auto pOutputCandidateCollection = pfAlgo_.makeConnectedCandidates();
0281
0282 LogDebug("PFProducer") << "particle flow: putting products in the event";
0283 if (verbose_) {
0284 int nC = 0;
0285 ostringstream ss;
0286 for (auto const& cand : pOutputCandidateCollection) {
0287 nC++;
0288 ss << " " << nC << ") pid=" << cand.particleId() << " pt=" << cand.pt() << endl;
0289 }
0290 LogDebug("PFProducer") << "Here the full list:" << endl << ss.str();
0291 }
0292
0293
0294 iEvent.emplace(pfCandidatesToken_, pOutputCandidateCollection);
0295 iEvent.emplace(pfCleanedCandidatesToken_, pfAlgo_.getCleanedCandidates());
0296
0297 if (postMuonCleaning_) {
0298 auto& muAlgo = *pfAlgo_.getPFMuonAlgo();
0299
0300 iEvent.put(muAlgo.transferCleanedCosmicCandidates(), "CleanedCosmicsMuons");
0301
0302 iEvent.put(muAlgo.transferCleanedTrackerAndGlobalCandidates(), "CleanedTrackerAndGlobalMuons");
0303
0304 iEvent.put(muAlgo.transferCleanedFakeCandidates(), "CleanedFakeMuons");
0305
0306 iEvent.put(muAlgo.transferPunchThroughCleanedMuonCandidates(), "CleanedPunchThroughMuons");
0307
0308 iEvent.put(muAlgo.transferPunchThroughCleanedHadronCandidates(), "CleanedPunchThroughNeutralHadrons");
0309
0310 iEvent.put(muAlgo.transferAddedMuonCandidates(), "AddedMuonsAndHadrons");
0311 }
0312 }
0313
0314 void PFProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0315 edm::ParameterSetDescription desc;
0316
0317
0318 desc.addUntracked<bool>("verbose", false);
0319 desc.addUntracked<bool>("debug", false);
0320
0321
0322 desc.add<edm::InputTag>("blocks", edm::InputTag("particleFlowBlock"));
0323
0324
0325 desc.add<edm::InputTag>("muons", edm::InputTag("muons1stStep"));
0326 desc.add<bool>("postMuonCleaning", true);
0327
0328
0329 edm::ParameterSetDescription emptyDescription;
0330 desc.ifValue(edm::ParameterDescription<bool>("vetoEndcap", false, true),
0331 true >> edm::ParameterDescription<edm::InputTag>("vetoes", {"pfTICL"}, true) or
0332 false >> edm::EmptyGroupDescription());
0333
0334
0335 desc.add<edm::InputTag>("vertexCollection", edm::InputTag("offlinePrimaryVertices"));
0336 desc.add<bool>("useVerticesForNeutral", true);
0337
0338
0339 desc.add<bool>("useHO", true);
0340
0341
0342 desc.add<edm::InputTag>("PFEGammaCandidates", edm::InputTag("particleFlowEGamma"));
0343 desc.add<edm::InputTag>("GedElectronValueMap", {"gedGsfElectronValueMapsTmp"});
0344 desc.add<edm::InputTag>("GedPhotonValueMap", edm::InputTag("gedPhotonsTmp", "valMapPFEgammaCandToPhoton"));
0345
0346 desc.add<bool>("useEGammaElectrons", true);
0347 desc.add<edm::InputTag>("egammaElectrons", edm::InputTag("mvaElectrons"));
0348
0349 desc.add<bool>("useEGammaFilters", true);
0350 desc.add<bool>("useProtectionsForJetMET", true);
0351
0352
0353 edm::ParameterSetDescription psd_PFEGammaFilters;
0354 PFEGammaFilters::fillPSetDescription(psd_PFEGammaFilters);
0355 desc.add<edm::ParameterSetDescription>("PFEGammaFiltersParameters", psd_PFEGammaFilters);
0356
0357
0358
0359 desc.add<std::vector<double>>("muon_HCAL", {3.0, 3.0});
0360 desc.add<std::vector<double>>("muon_ECAL", {0.5, 0.5});
0361 desc.add<std::vector<double>>("muon_HO", {0.9, 0.9});
0362
0363
0364 edm::ParameterSetDescription psd_PFMuonAlgo;
0365 PFMuonAlgo::fillPSetDescription(psd_PFMuonAlgo);
0366 desc.add<edm::ParameterSetDescription>("PFMuonAlgoParameters", psd_PFMuonAlgo);
0367
0368
0369
0370 desc.add<bool>("rejectTracks_Bad", true);
0371 desc.add<bool>("rejectTracks_Step45", true);
0372
0373 desc.add<bool>("usePFNuclearInteractions", true);
0374 desc.add<bool>("usePFConversions", true);
0375 desc.add<bool>("usePFDecays", false);
0376
0377 desc.add<double>("dptRel_DispVtx", 10.0);
0378
0379
0380 edm::ParameterSetDescription psd_CandConnector;
0381 PFCandConnector::fillPSetDescription(psd_CandConnector);
0382 desc.add<edm::ParameterSetDescription>("iCfgCandConnector", psd_CandConnector);
0383
0384
0385 desc.add<double>("nsigma_TRACK", 1.0)->setComment("Number of sigmas for fake track detection");
0386
0387 desc.add<double>("pt_Error", 1.0)
0388 ->setComment("Absolute pt error to detect fake tracks in the first three iterations");
0389 desc.add<std::vector<double>>("factors_45", {10.0, 100.0})
0390 ->setComment("Factors to be applied in the four and fifth steps to the pt error");
0391
0392
0393 desc.add<double>("goodTrackDeadHcal_ptErrRel", 0.2)->setComment("trackRef->ptError()/trackRef->pt() < X");
0394 desc.add<double>("goodTrackDeadHcal_chi2n", 5)->setComment("trackRef->normalizedChi2() < X");
0395 desc.add<unsigned int>("goodTrackDeadHcal_layers", 4)
0396 ->setComment("trackRef->hitPattern().trackerLayersWithMeasurement() >= X");
0397 desc.add<double>("goodTrackDeadHcal_validFr", 0.5)->setComment("trackRef->validFraction() > X");
0398 desc.add<double>("goodTrackDeadHcal_dxy", 0.5)->setComment("abs(trackRef->dxy(primaryVertex_.position())) < X [cm]");
0399
0400 desc.add<double>("goodPixelTrackDeadHcal_minEta", 2.3)->setComment("abs(trackRef->eta()) > X");
0401 desc.add<double>("goodPixelTrackDeadHcal_maxPt", 50.0)->setComment("trackRef->ptError()/trackRef->pt() < X");
0402 desc.add<double>("goodPixelTrackDeadHcal_ptErrRel", 1.0)->setComment("trackRef->ptError()/trackRef->pt() < X");
0403 desc.add<double>("goodPixelTrackDeadHcal_chi2n", 2)->setComment("trackRef->normalizedChi2() < X");
0404 desc.add<int>("goodPixelTrackDeadHcal_maxLost3Hit", 0)
0405 ->setComment(
0406 "max missing outer hits for a track with 3 valid pixel layers (can set to -1 to reject all these tracks)");
0407 desc.add<int>("goodPixelTrackDeadHcal_maxLost4Hit", 1)
0408 ->setComment("max missing outer hits for a track with >= 4 valid pixel layers");
0409 desc.add<double>("goodPixelTrackDeadHcal_dxy", 0.02)
0410 ->setComment("abs(trackRef->dxy(primaryVertex_.position())) < X [cm] ");
0411 desc.add<double>("goodPixelTrackDeadHcal_dz", 0.05)
0412 ->setComment("abs(trackRef->dz(primaryVertex_.position())) < X [cm]");
0413
0414
0415 desc.add<double>("pf_nsigma_ECAL", 0.0);
0416 desc.add<double>("pf_nsigma_HCAL", 1.0);
0417 desc.add<double>("pf_nsigma_HFEM", 1.0);
0418 desc.add<double>("pf_nsigma_HFHAD", 1.0);
0419
0420
0421 desc.add<bool>("useCalibrationsFromDB", true);
0422 desc.add<std::string>("calibrationsLabel", "");
0423
0424
0425 desc.add<bool>("postHFCleaning", false);
0426 {
0427 edm::ParameterSetDescription psd_PFHFCleaning;
0428 psd_PFHFCleaning.add<double>("minHFCleaningPt", 5.0)
0429 ->setComment("Clean only objects with pt larger than this value");
0430 psd_PFHFCleaning.add<double>("maxSignificance", 2.5)
0431 ->setComment("Clean only if the initial MET/sqrt(sumet) is larger than this value");
0432 psd_PFHFCleaning.add<double>("minSignificance", 2.5)
0433 ->setComment("Clean only if the final MET/sqrt(sumet) is smaller than this value");
0434 psd_PFHFCleaning.add<double>("minSignificanceReduction", 1.4)
0435 ->setComment("Clean only if the significance reduction is larger than this value");
0436 psd_PFHFCleaning.add<double>("maxDeltaPhiPt", 7.0)
0437 ->setComment("Clean only if the MET and the to-be-cleaned object satisfy this DeltaPhi * Pt cut");
0438
0439 psd_PFHFCleaning.add<double>("minDeltaMet", 0.4)
0440 ->setComment(
0441 "Clean only if the MET relative reduction from the to-be-cleaned object is larger than this value");
0442 desc.add<edm::ParameterSetDescription>("PFHFCleaningParameters", psd_PFHFCleaning);
0443 }
0444
0445
0446 desc.add<std::vector<edm::InputTag>>("cleanedHF",
0447 {
0448 edm::InputTag("particleFlowRecHitHF", "Cleaned"),
0449 edm::InputTag("particleFlowClusterHF", "Cleaned"),
0450 });
0451
0452
0453 desc.add<bool>("calibHF_use", false);
0454 desc.add<std::vector<double>>("calibHF_eta_step", {0.0, 2.9, 3.0, 3.2, 4.2, 4.4, 4.6, 4.8, 5.2, 5.4});
0455 desc.add<std::vector<double>>("calibHF_a_EMonly", {1., 1., 1., 1., 1., 1., 1., 1., 1., 1.});
0456 desc.add<std::vector<double>>("calibHF_a_EMHAD", {1., 1., 1., 1., 1., 1., 1., 1., 1., 1.});
0457 desc.add<std::vector<double>>("calibHF_b_HADonly", {1., 1., 1., 1., 1., 1., 1., 1., 1., 1.});
0458 desc.add<std::vector<double>>("calibHF_b_EMHAD", {1., 1., 1., 1., 1., 1., 1., 1., 1., 1.});
0459
0460
0461 desc.add<std::vector<double>>("resolHF_square", {2.799 * 2.799, 0.114 * 0.114, 0.0 * 0.0})
0462 ->setComment("HF resolution - stochastic, constant, noise term squares");
0463
0464 descriptions.add("particleFlow", desc);
0465 }