File indexing completed on 2024-09-07 04:37:31
0001
0002
0003
0004
0005 #include <memory>
0006 #include <string>
0007 #include <vector>
0008
0009
0010 #include "DataFormats/Common/interface/Handle.h"
0011 #include "DataFormats/Common/interface/View.h"
0012 #include "DataFormats/JetReco/interface/Jet.h"
0013 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0014 #include "DataFormats/PatCandidates/interface/Jet.h"
0015 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0016 #include "FWCore/Framework/interface/Event.h"
0017 #include "FWCore/Framework/interface/global/EDProducer.h"
0018 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0019 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0021 #include "FWCore/Utilities/interface/StreamID.h"
0022
0023
0024 class HiFJRhoProducer : public edm::global::EDProducer<> {
0025 public:
0026 explicit HiFJRhoProducer(const edm::ParameterSet&);
0027 ~HiFJRhoProducer() override = default;
0028
0029 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0030
0031 private:
0032 void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override;
0033
0034 double calcMedian(std::vector<double>& v) const;
0035 double calcMd(reco::Jet const& jet) const;
0036 bool isPackedCandidate(reco::Candidate const* candidate) const;
0037
0038
0039 const edm::EDGetTokenT<edm::View<reco::Jet>> jetsToken_;
0040 const unsigned int nExcl_;
0041 const unsigned int nExcl2_;
0042 const double etaMaxExcl_;
0043 const double ptMinExcl_;
0044 const double etaMaxExcl2_;
0045 const double ptMinExcl2_;
0046 const std::vector<double> etaRanges_;
0047 mutable std::once_flag checkJetCand_;
0048 mutable bool usingPackedCand_ = false;
0049 };
0050
0051 using namespace reco;
0052
0053
0054 HiFJRhoProducer::HiFJRhoProducer(const edm::ParameterSet& iConfig)
0055 : jetsToken_(consumes<edm::View<reco::Jet>>(iConfig.getParameter<edm::InputTag>("jetSource"))),
0056 nExcl_(iConfig.getParameter<int>("nExcl")),
0057 nExcl2_(iConfig.getParameter<int>("nExcl2")),
0058 etaMaxExcl_(iConfig.getParameter<double>("etaMaxExcl")),
0059 ptMinExcl_(iConfig.getParameter<double>("ptMinExcl")),
0060 etaMaxExcl2_(iConfig.getParameter<double>("etaMaxExcl2")),
0061 ptMinExcl2_(iConfig.getParameter<double>("ptMinExcl2")),
0062 etaRanges_(iConfig.getParameter<std::vector<double>>("etaRanges")) {
0063
0064 produces<std::vector<double>>("mapEtaEdges");
0065 produces<std::vector<double>>("mapToRho");
0066 produces<std::vector<double>>("mapToRhoM");
0067 produces<std::vector<double>>("ptJets");
0068 produces<std::vector<double>>("areaJets");
0069 produces<std::vector<double>>("etaJets");
0070 }
0071
0072
0073 void HiFJRhoProducer::produce(edm::StreamID, edm::Event& iEvent, edm::EventSetup const& iSetup) const {
0074
0075 edm::Handle<edm::View<reco::Jet>> jets;
0076 iEvent.getByToken(jetsToken_, jets);
0077
0078 int neta = static_cast<int>(etaRanges_.size());
0079 auto mapEtaRangesOut = std::make_unique<std::vector<double>>(neta, -999.);
0080
0081 for (int ieta = 0; ieta < neta; ieta++) {
0082 mapEtaRangesOut->at(ieta) = etaRanges_[ieta];
0083 }
0084 auto mapToRhoOut = std::make_unique<std::vector<double>>(neta - 1, 1e-6);
0085 auto mapToRhoMOut = std::make_unique<std::vector<double>>(neta - 1, 1e-6);
0086
0087 int njets = static_cast<int>(jets->size());
0088
0089 auto ptJetsOut = std::make_unique<std::vector<double>>();
0090 ptJetsOut->reserve(njets);
0091 auto areaJetsOut = std::make_unique<std::vector<double>>();
0092 areaJetsOut->reserve(njets);
0093 auto etaJetsOut = std::make_unique<std::vector<double>>();
0094 etaJetsOut->reserve(njets);
0095
0096 std::vector<double> rhoVec;
0097 rhoVec.reserve(njets);
0098 std::vector<double> rhomVec;
0099 rhomVec.reserve(njets);
0100
0101 int nacc = 0;
0102 unsigned int njetsEx = 0;
0103 unsigned int njetsEx2 = 0;
0104 for (auto const& jet : *jets) {
0105 if (njetsEx < nExcl_ and fabs(jet.eta()) < etaMaxExcl_ and jet.pt() > ptMinExcl_) {
0106 ++njetsEx;
0107 continue;
0108 }
0109 if (njetsEx2 < nExcl2_ and fabs(jet.eta()) < etaMaxExcl2_ and fabs(jet.eta()) > etaMaxExcl_ and
0110 jet.pt() > ptMinExcl2_) {
0111 ++njetsEx2;
0112 continue;
0113 }
0114 float pt = jet.pt();
0115 float area = jet.jetArea();
0116 float eta = jet.eta();
0117
0118 if (eta < mapEtaRangesOut->at(0) || eta > mapEtaRangesOut->at(neta - 1))
0119 continue;
0120 if (area > 0.) {
0121 rhoVec.push_back(pt / area);
0122 rhomVec.push_back(calcMd(jet) / area);
0123 ptJetsOut->push_back(pt);
0124 areaJetsOut->push_back(area);
0125 etaJetsOut->push_back(eta);
0126 ++nacc;
0127 }
0128 }
0129
0130
0131 const double radius = 0.2;
0132 for (int ieta = 0; ieta < (neta - 1); ++ieta) {
0133 std::vector<double> rhoVecCur;
0134 rhoVecCur.reserve(nacc);
0135 std::vector<double> rhomVecCur;
0136 rhomVecCur.reserve(nacc);
0137
0138 double etaMin = mapEtaRangesOut->at(ieta) + radius;
0139 double etaMax = mapEtaRangesOut->at(ieta + 1) - radius;
0140
0141 for (int i = 0; i < nacc; ++i) {
0142 if ((*etaJetsOut)[i] >= etaMin and (*etaJetsOut)[i] < etaMax) {
0143 rhoVecCur.push_back(rhoVec[i]);
0144 rhomVecCur.push_back(rhomVec[i]);
0145 }
0146 }
0147
0148 if (not rhoVecCur.empty()) {
0149 mapToRhoOut->at(ieta) = calcMedian(rhoVecCur);
0150 mapToRhoMOut->at(ieta) = calcMedian(rhomVecCur);
0151 }
0152 }
0153
0154 iEvent.put(std::move(mapEtaRangesOut), "mapEtaEdges");
0155 iEvent.put(std::move(mapToRhoOut), "mapToRho");
0156 iEvent.put(std::move(mapToRhoMOut), "mapToRhoM");
0157 iEvent.put(std::move(ptJetsOut), "ptJets");
0158 iEvent.put(std::move(areaJetsOut), "areaJets");
0159 iEvent.put(std::move(etaJetsOut), "etaJets");
0160 }
0161
0162 double HiFJRhoProducer::calcMd(reco::Jet const& jet) const {
0163
0164
0165
0166 double sum = 0.;
0167 for (auto const* daughter : jet.getJetConstituentsQuick()) {
0168 if (isPackedCandidate(daughter)) {
0169 auto part = static_cast<pat::PackedCandidate const*>(daughter);
0170 sum += sqrt(part->mass() * part->mass() + part->pt() * part->pt()) - part->pt();
0171 } else {
0172 auto part = static_cast<reco::PFCandidate const*>(daughter);
0173 sum += sqrt(part->mass() * part->mass() + part->pt() * part->pt()) - part->pt();
0174 }
0175 }
0176
0177 return sum;
0178 }
0179
0180 bool HiFJRhoProducer::isPackedCandidate(const reco::Candidate* candidate) const {
0181
0182 std::call_once(checkJetCand_, [&]() {
0183 if (typeid(pat::PackedCandidate) == typeid(*candidate))
0184 usingPackedCand_ = true;
0185 else if (typeid(reco::PFCandidate) == typeid(*candidate))
0186 usingPackedCand_ = false;
0187 else
0188 throw cms::Exception("WrongJetCollection", "Jet constituents are not particle flow candidates");
0189 });
0190 return usingPackedCand_;
0191 }
0192
0193 void HiFJRhoProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0194 edm::ParameterSetDescription desc;
0195 desc.add<edm::InputTag>("jetSource", edm::InputTag("kt4PFJets"));
0196 desc.add<int>("nExcl", 2);
0197 desc.add<double>("etaMaxExcl", 2.);
0198 desc.add<double>("ptMinExcl", 20.);
0199 desc.add<int>("nExcl2", 2);
0200 desc.add<double>("etaMaxExcl2", 2.);
0201 desc.add<double>("ptMinExcl2", 20.);
0202 desc.add<std::vector<double>>("etaRanges", {});
0203 descriptions.add("hiFJRhoProducer", desc);
0204 }
0205
0206
0207 double HiFJRhoProducer::calcMedian(std::vector<double>& v) const {
0208
0209
0210 if (v.empty()) {
0211 return 0.0;
0212 }
0213 auto n = v.size() / 2;
0214 std::nth_element(v.begin(), v.begin() + n, v.end());
0215 auto med = v[n];
0216 if (!(v.size() & 1)) {
0217 auto max_it = std::max_element(v.begin(), v.begin() + n);
0218 med = (*max_it + med) / 2.0;
0219 }
0220 return med;
0221 }
0222
0223
0224 #include "FWCore/Framework/interface/MakerMacros.h"
0225 DEFINE_FWK_MODULE(HiFJRhoProducer);