File indexing completed on 2024-04-06 12:26:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "RecoMET/METAlgorithms/interface/METSignificance.h"
0019 #include <unordered_set>
0020
0021 namespace {
0022 struct ptr_hash {
0023 std::size_t operator()(const reco::CandidatePtr& k) const {
0024 if (k.refCore().isTransient())
0025 return (unsigned long)k.refCore().productPtr() ^ k.key();
0026 else
0027 return k.refCore().id().processIndex() ^ k.refCore().id().productIndex() ^ k.key();
0028 }
0029 };
0030 }
0031
0032 metsig::METSignificance::METSignificance(const edm::ParameterSet& iConfig) {
0033 edm::ParameterSet cfgParams = iConfig.getParameter<edm::ParameterSet>("parameters");
0034
0035 double dRmatch = cfgParams.getParameter<double>("dRMatch");
0036 dR2match_ = dRmatch * dRmatch;
0037
0038 jetThreshold_ = cfgParams.getParameter<double>("jetThreshold");
0039 jetEtas_ = cfgParams.getParameter<std::vector<double> >("jeta");
0040 jetParams_ = cfgParams.getParameter<std::vector<double> >("jpar");
0041 pjetParams_ = cfgParams.getParameter<std::vector<double> >("pjpar");
0042 }
0043
0044 metsig::METSignificance::~METSignificance() {}
0045
0046 reco::METCovMatrix metsig::METSignificance::getCovariance(const edm::View<reco::Jet>& jets,
0047 const std::vector<edm::Handle<reco::CandidateView> >& leptons,
0048 const edm::Handle<edm::View<reco::Candidate> >& pfCandidatesH,
0049 double rho,
0050 JME::JetResolution& resPtObj,
0051 JME::JetResolution& resPhiObj,
0052 JME::JetResolutionScaleFactor& resSFObj,
0053 bool isRealData,
0054 double& sumPtUnclustered,
0055 edm::ValueMap<float> const* weights) {
0056
0057 const edm::View<reco::Candidate>& pfCandidates = *pfCandidatesH;
0058
0059
0060 double cov_xx = 0;
0061 double cov_xy = 0;
0062 double cov_yy = 0;
0063
0064
0065 std::unordered_set<reco::CandidatePtr, ptr_hash> footprint;
0066
0067
0068 for (const auto& lep_i : leptons) {
0069 for (const auto& lep : lep_i->ptrs()) {
0070 if (lep->pt() > 10) {
0071 for (unsigned int n = 0; n < lep->numberOfSourceCandidatePtrs(); n++)
0072 footprint.insert(lep->sourceCandidatePtr(n));
0073 }
0074 }
0075 }
0076
0077 std::vector<bool> cleanedJets(jets.size(), false);
0078 std::transform(jets.begin(), jets.end(), cleanedJets.begin(), [this, &leptons](auto const& jet) -> bool {
0079 return cleanJet(jet, leptons);
0080 });
0081
0082 auto iCleaned = cleanedJets.begin();
0083 for (const auto& jet : jets) {
0084
0085 if (!(*iCleaned++))
0086 continue;
0087 for (unsigned int n = 0; n < jet.numberOfSourceCandidatePtrs(); n++) {
0088 footprint.insert(jet.sourceCandidatePtr(n));
0089 }
0090 }
0091
0092
0093 for (size_t i = 0; i < pfCandidates.size(); ++i) {
0094
0095 bool cleancand = true;
0096 if (footprint.find(pfCandidates.ptrAt(i)) == footprint.end()) {
0097 float weight = (weights != nullptr) ? (*weights)[pfCandidates.ptrAt(i)] : 1.0;
0098
0099 for (const auto& it : footprint) {
0100 if (it.isNonnull() && it.isAvailable() && (reco::deltaR2(*it, pfCandidates[i]) < 0.00000025)) {
0101 cleancand = false;
0102 break;
0103 }
0104 }
0105
0106 if (cleancand) {
0107 sumPtUnclustered += pfCandidates[i].pt() * weight;
0108 }
0109 }
0110 }
0111
0112
0113 iCleaned = cleanedJets.begin();
0114 for (const auto& jet : jets) {
0115
0116 if (!(*iCleaned++))
0117 continue;
0118
0119 double jpt = jet.pt();
0120
0121
0122 if (jpt > jetThreshold_) {
0123
0124
0125 double jeta = jet.eta();
0126 double feta = std::abs(jeta);
0127 double c = jet.px() / jpt;
0128 double s = jet.py() / jpt;
0129
0130 JME::JetParameters parameters;
0131 parameters.setJetPt(jpt).setJetEta(jeta).setRho(rho);
0132
0133
0134 double sigmapt = resPtObj.getResolution(parameters);
0135 double sigmaphi = resPhiObj.getResolution(parameters);
0136
0137
0138
0139 double scale = 0;
0140 if (feta < jetEtas_[0])
0141 scale = jetParams_[0];
0142 else if (feta < jetEtas_[1])
0143 scale = jetParams_[1];
0144 else if (feta < jetEtas_[2])
0145 scale = jetParams_[2];
0146 else if (feta < jetEtas_[3])
0147 scale = jetParams_[3];
0148 else
0149 scale = jetParams_[4];
0150
0151
0152 double dpt = scale * jpt * sigmapt;
0153 double dph = jpt * sigmaphi;
0154
0155 cov_xx += dpt * dpt * c * c + dph * dph * s * s;
0156 cov_xy += (dpt * dpt - dph * dph) * c * s;
0157 cov_yy += dph * dph * c * c + dpt * dpt * s * s;
0158
0159 } else {
0160
0161 sumPtUnclustered += jpt;
0162 }
0163 }
0164
0165
0166 if (sumPtUnclustered < 0)
0167 sumPtUnclustered = 0;
0168
0169
0170 double pseudoJetCov = pjetParams_[0] * pjetParams_[0] + pjetParams_[1] * pjetParams_[1] * sumPtUnclustered;
0171 cov_xx += pseudoJetCov;
0172 cov_yy += pseudoJetCov;
0173
0174 reco::METCovMatrix cov;
0175 cov(0, 0) = cov_xx;
0176 cov(1, 0) = cov_xy;
0177 cov(0, 1) = cov_xy;
0178 cov(1, 1) = cov_yy;
0179
0180 return cov;
0181 }
0182
0183 double metsig::METSignificance::getSignificance(const reco::METCovMatrix& cov, const reco::MET& met) {
0184
0185 double det = cov(0, 0) * cov(1, 1) - cov(0, 1) * cov(1, 0);
0186
0187
0188 double ncov_xx = cov(1, 1) / det;
0189 double ncov_xy = -cov(0, 1) / det;
0190 double ncov_yy = cov(0, 0) / det;
0191
0192
0193 double sig = met.px() * met.px() * ncov_xx + 2 * met.px() * met.py() * ncov_xy + met.py() * met.py() * ncov_yy;
0194
0195 return sig;
0196 }
0197
0198 bool metsig::METSignificance::cleanJet(const reco::Jet& jet,
0199 const std::vector<edm::Handle<reco::CandidateView> >& leptons) {
0200 for (const auto& lep_i : leptons) {
0201 for (const auto& lep : *lep_i) {
0202 if (reco::deltaR2(lep, jet) < dR2match_) {
0203 return false;
0204 }
0205 }
0206 }
0207 return true;
0208 }