CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
METSignificance.cc
Go to the documentation of this file.
1 
2 // -*- C++ -*-
3 //
4 // Package: METAlgorithms
5 // Class: METSignificance
6 //
12 //
13 // Original Author: Nathan Mirman (Cornell University)
14 // Created: Thu May 30 16:39:52 CDT 2013
15 //
16 //
17 
19 #include <unordered_set>
20 
21 namespace {
22  struct ptr_hash {
23  std::size_t operator()(const reco::CandidatePtr& k) const {
24  if (k.refCore().isTransient())
25  return (unsigned long)k.refCore().productPtr() ^ k.key();
26  else
27  return k.refCore().id().processIndex() ^ k.refCore().id().productIndex() ^ k.key();
28  }
29  };
30 } // namespace
31 
33  edm::ParameterSet cfgParams = iConfig.getParameter<edm::ParameterSet>("parameters");
34 
35  double dRmatch = cfgParams.getParameter<double>("dRMatch");
36  dR2match_ = dRmatch * dRmatch;
37 
38  jetThreshold_ = cfgParams.getParameter<double>("jetThreshold");
39  jetEtas_ = cfgParams.getParameter<std::vector<double> >("jeta");
40  jetParams_ = cfgParams.getParameter<std::vector<double> >("jpar");
41  pjetParams_ = cfgParams.getParameter<std::vector<double> >("pjpar");
42 }
43 
45 
48  const edm::Handle<edm::View<reco::Candidate> >& pfCandidatesH,
49  double rho,
50  JME::JetResolution& resPtObj,
51  JME::JetResolution& resPhiObj,
53  bool isRealData,
54  double& sumPtUnclustered,
56  //pfcandidates
57  const edm::View<reco::Candidate>& pfCandidates = *pfCandidatesH;
58 
59  // metsig covariance
60  double cov_xx = 0;
61  double cov_xy = 0;
62  double cov_yy = 0;
63 
64  // for lepton and jet subtraction
65  std::unordered_set<reco::CandidatePtr, ptr_hash> footprint;
66 
67  // subtract leptons out of sumPtUnclustered
68  for (const auto& lep_i : leptons) {
69  for (const auto& lep : lep_i->ptrs()) {
70  if (lep->pt() > 10) {
71  for (unsigned int n = 0; n < lep->numberOfSourceCandidatePtrs(); n++)
72  footprint.insert(lep->sourceCandidatePtr(n));
73  }
74  }
75  }
76 
77  std::vector<bool> cleanedJets(jets.size(), false);
78  std::transform(jets.begin(), jets.end(), cleanedJets.begin(), [this, &leptons](auto const& jet) -> bool {
79  return cleanJet(jet, leptons);
80  });
81  // subtract jets out of sumPtUnclustered
82  auto iCleaned = cleanedJets.begin();
83  for (const auto& jet : jets) {
84  // disambiguate jets and leptons
85  if (!(*iCleaned++))
86  continue;
87  for (unsigned int n = 0; n < jet.numberOfSourceCandidatePtrs(); n++) {
88  footprint.insert(jet.sourceCandidatePtr(n));
89  }
90  }
91 
92  // calculate sumPtUnclustered
93  for (size_t i = 0; i < pfCandidates.size(); ++i) {
94  // check if candidate exists in a lepton or jet
95  bool cleancand = true;
96  if (footprint.find(pfCandidates.ptrAt(i)) == footprint.end()) {
97  float weight = (weights != nullptr) ? (*weights)[pfCandidates.ptrAt(i)] : 1.0;
98  //dP4 recovery
99  for (const auto& it : footprint) {
100  if (it.isNonnull() && it.isAvailable() && (reco::deltaR2(*it, pfCandidates[i]) < 0.00000025)) {
101  cleancand = false;
102  break;
103  }
104  }
105  // if not, add to sumPtUnclustered
106  if (cleancand) {
107  sumPtUnclustered += pfCandidates[i].pt() * weight;
108  }
109  }
110  }
111 
112  // add jets to metsig covariance matrix and subtract them from sumPtUnclustered
113  iCleaned = cleanedJets.begin();
114  for (const auto& jet : jets) {
115  // disambiguate jets and leptons
116  if (!(*iCleaned++))
117  continue;
118 
119  double jpt = jet.pt();
120 
121  // split into high-pt and low-pt sector
122  if (jpt > jetThreshold_) {
123  // high-pt jets enter into the covariance matrix via JER
124 
125  double jeta = jet.eta();
126  double feta = std::abs(jeta);
127  double c = jet.px() / jpt;
128  double s = jet.py() / jpt;
129 
131  parameters.setJetPt(jpt).setJetEta(jeta).setRho(rho);
132 
133  // jet energy resolutions
134  double sigmapt = resPtObj.getResolution(parameters);
135  double sigmaphi = resPhiObj.getResolution(parameters);
136  // SF not needed since is already embedded in the sigma in the dataGlobalTag
137  // double sigmaSF = isRealData ? resSFObj.getScaleFactor(parameters) : 1.0;
138 
139  double scale = 0;
140  if (feta < jetEtas_[0])
141  scale = jetParams_[0];
142  else if (feta < jetEtas_[1])
143  scale = jetParams_[1];
144  else if (feta < jetEtas_[2])
145  scale = jetParams_[2];
146  else if (feta < jetEtas_[3])
147  scale = jetParams_[3];
148  else
149  scale = jetParams_[4];
150 
151  // double dpt = sigmaSF*scale*jpt*sigmapt;
152  double dpt = scale * jpt * sigmapt;
153  double dph = jpt * sigmaphi;
154 
155  cov_xx += dpt * dpt * c * c + dph * dph * s * s;
156  cov_xy += (dpt * dpt - dph * dph) * c * s;
157  cov_yy += dph * dph * c * c + dpt * dpt * s * s;
158 
159  } else {
160  // add the (corrected) jet to the sumPtUnclustered
161  sumPtUnclustered += jpt;
162  }
163  }
164 
165  //protection against unphysical events
166  if (sumPtUnclustered < 0)
167  sumPtUnclustered = 0;
168 
169  // add pseudo-jet to metsig covariance matrix
170  double pseudoJetCov = pjetParams_[0] * pjetParams_[0] + pjetParams_[1] * pjetParams_[1] * sumPtUnclustered;
171  cov_xx += pseudoJetCov;
172  cov_yy += pseudoJetCov;
173 
174  reco::METCovMatrix cov;
175  cov(0, 0) = cov_xx;
176  cov(1, 0) = cov_xy;
177  cov(0, 1) = cov_xy;
178  cov(1, 1) = cov_yy;
179 
180  return cov;
181 }
182 
184  // covariance matrix determinant
185  double det = cov(0, 0) * cov(1, 1) - cov(0, 1) * cov(1, 0);
186 
187  // invert matrix
188  double ncov_xx = cov(1, 1) / det;
189  double ncov_xy = -cov(0, 1) / det;
190  double ncov_yy = cov(0, 0) / det;
191 
192  // product of met and inverse of covariance
193  double sig = met.px() * met.px() * ncov_xx + 2 * met.px() * met.py() * ncov_xy + met.py() * met.py() * ncov_yy;
194 
195  return sig;
196 }
197 
200  for (const auto& lep_i : leptons) {
201  for (const auto& lep : *lep_i) {
202  if (reco::deltaR2(lep, jet) < dR2match_) {
203  return false;
204  }
205  }
206  }
207  return true;
208 }
bool cleanJet(const reco::Jet &jet, const std::vector< edm::Handle< reco::CandidateView > > &leptons)
reco::METCovMatrix getCovariance(const edm::View< reco::Jet > &jets, const std::vector< edm::Handle< reco::CandidateView > > &leptons, const edm::Handle< edm::View< reco::Candidate > > &pfCandidates, double rho, JME::JetResolution &resPtObj, JME::JetResolution &resPhiObj, JME::JetResolutionScaleFactor &resSFObj, bool isRealData, double &sumPtUnclustered, edm::ValueMap< float > const *weights=nullptr)
float getResolution(const JetParameters &parameters) const
const edm::EventSetup & c
JetParameters & setJetEta(float eta)
static double getSignificance(const reco::METCovMatrix &cov, const reco::MET &met)
JetParameters & setRho(float rho)
key_type key() const
Definition: Ptr.h:163
Ptr< value_type > ptrAt(size_type i) const
Base class for all types of Jets.
Definition: Jet.h:20
ROOT::Math::SMatrix< double, 2 > METCovMatrix
Definition: MET.h:39
ProcessIndex productIndex() const
Definition: ProductID.h:34
size_type size() const
std::vector< double > jetEtas_
double px() const final
x coordinate of momentum vector
const_iterator begin() const
Definition: MET.h:41
vector< PseudoJet > jets
void const * productPtr() const
Definition: RefCore.h:51
RefCore const & refCore() const
Definition: Ptr.h:167
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< double > pjetParams_
double py() const final
y coordinate of momentum vector
std::vector< double > jetParams_
METSignificance(const edm::ParameterSet &iConfig)
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
ProductID id() const
Definition: RefCore.h:48
bool isTransient() const
Definition: RefCore.h:105
const_iterator end() const
JetParameters & setJetPt(float pt)
int weight
Definition: histoStyle.py:51
ProcessIndex processIndex() const
Definition: ProductID.h:33
unsigned transform(const HcalDetId &id, unsigned transformCode)