CMS 3D CMS Logo

PuppiContainer.cc
Go to the documentation of this file.
3 #include "Math/ProbFunc.h"
4 #include "TMath.h"
5 #include <iostream>
6 #include <cmath>
9 
10 using namespace std;
11 
13  fPuppiDiagnostics = iConfig.getParameter<bool>("puppiDiagnostics");
14  fApplyCHS = iConfig.getParameter<bool>("applyCHS");
15  fInvert = iConfig.getParameter<bool>("invertPuppi");
16  fUseExp = iConfig.getParameter<bool>("useExp");
17  fPuppiWeightCut = iConfig.getParameter<double>("MinPuppiWeight");
18  fPtMaxPhotons = iConfig.getParameter<double>("PtMaxPhotons");
19  fEtaMaxPhotons = iConfig.getParameter<double>("EtaMaxPhotons");
20  fPtMaxNeutrals = iConfig.getParameter<double>("PtMaxNeutrals");
21  fPtMaxNeutralsStartSlope = iConfig.getParameter<double>("PtMaxNeutralsStartSlope");
22  std::vector<edm::ParameterSet> lAlgos = iConfig.getParameter<std::vector<edm::ParameterSet> >("algos");
23  fNAlgos = lAlgos.size();
24  for (unsigned int i0 = 0; i0 < lAlgos.size(); i0++) {
25  PuppiAlgo pPuppiConfig(lAlgos[i0]);
26  fPuppiAlgo.push_back(pPuppiConfig);
27  }
28 }
29 
30 void PuppiContainer::initialize(const std::vector<RecoObj> &iRecoObjects) {
31  //Clear everything
32  fPFParticles.resize(0);
33  fPFParticlesForVar.resize(0);
34  fPFParticlesForVarChargedPV.resize(0);
35  fWeights.resize(0);
36  fVals.resize(0);
37  fRawAlphas.resize(0);
38  fAlphaMed.resize(0);
39  fAlphaRMS.resize(0);
40  fPUProxy = 1.;
41  //Link to the RecoObjects
42  fRecoParticles = &iRecoObjects;
43  fPFParticles.reserve(iRecoObjects.size());
44  fPFParticlesForVar.reserve(iRecoObjects.size());
45  fPFParticlesForVarChargedPV.reserve(iRecoObjects.size());
46  for (auto const &rParticle : *fRecoParticles) {
47  PuppiCandidate pCand;
48  pCand.id = rParticle.id;
49  if (edm::isFinite(rParticle.rapidity)) {
50  pCand.pt = rParticle.pt;
51  pCand.eta = rParticle.eta;
52  pCand.rapidity = rParticle.rapidity;
53  pCand.phi = rParticle.phi;
54  pCand.m = rParticle.m;
55  } else {
56  pCand.pt = 0.;
57  pCand.eta = 99.;
58  pCand.rapidity = 99.;
59  pCand.phi = 0.;
60  pCand.m = 0.;
61  }
62 
63  fPFParticles.push_back(pCand);
64 
65  // skip candidates to be ignored in the computation
66  // of PUPPI's alphas (e.g. electrons and muons if puppiNoLep=True)
67  if (std::abs(rParticle.id) == 3)
68  continue;
69 
70  fPFParticlesForVar.push_back(pCand);
71  // charged candidates assigned to LV
72  if (std::abs(rParticle.id) == 1)
73  fPFParticlesForVarChargedPV.push_back(pCand);
74  }
75 }
76 
78 
80  std::vector<PuppiCandidate> const &iParts,
81  int iOpt,
82  const double iRCone) {
83  return var_within_R(iOpt, iParts, iPart, iRCone);
84 }
85 
87  const vector<PuppiCandidate> &particles,
88  const PuppiCandidate &centre,
89  const double R) {
90  if (iId == -1)
91  return 1.;
92 
93  double const r2 = R * R;
94  double var = 0.;
95 
96  for (auto const &cand : particles) {
97  if (std::abs(cand.rapidity - centre.rapidity) < R) {
98  auto const dr2y = reco::deltaR2(cand.rapidity, cand.phi, centre.rapidity, centre.phi);
99  if (dr2y < r2) {
100  auto const dr2 = reco::deltaR2(cand.eta, cand.phi, centre.eta, centre.phi);
101  if (dr2 < 0.0001)
102  continue;
103  auto const pt = cand.pt;
104  if (iId == 5)
105  var += (pt * pt / dr2);
106  else if (iId == 4)
107  var += pt;
108  else if (iId == 3)
109  var += (1. / dr2);
110  else if (iId == 2)
111  var += (1. / dr2);
112  else if (iId == 1)
113  var += pt;
114  else if (iId == 0)
115  var += (pt / dr2);
116  }
117  }
118  }
119 
120  if ((var != 0.) and ((iId == 0) or (iId == 3) or (iId == 5)))
121  var = log(var);
122  else if (iId == 1)
123  var += centre.pt;
124 
125  return var;
126 }
127 
128 //In fact takes the median not the average
130  std::vector<PuppiCandidate> const &iConstits,
131  std::vector<PuppiCandidate> const &iParticles,
132  std::vector<PuppiCandidate> const &iChargedParticles) {
133  for (unsigned int i0 = 0; i0 < iConstits.size(); i0++) {
134  //Calculate the Puppi Algo to use
135  int pPupId = getPuppiId(iConstits[i0].pt, iConstits[i0].eta);
136  if (pPupId == -1 || fPuppiAlgo[pPupId].numAlgos() <= iOpt) {
137  fVals.push_back(-1);
138  continue;
139  }
140  //Get the Puppi Sub Algo (given iteration)
141  int pAlgo = fPuppiAlgo[pPupId].algoId(iOpt);
142  bool pCharged = fPuppiAlgo[pPupId].isCharged(iOpt);
143  double pCone = fPuppiAlgo[pPupId].coneSize(iOpt);
144  // compute the Puppi metric:
145  // - calculate goodVar only for candidates that (1) will not be assigned a predefined weight (e.g 0, 1),
146  // or (2) are required for computations inside puppi-algos (see call to PuppiAlgo::add below)
147  double pVal = -1;
148  bool const getsDefaultWgtIfApplyCHS = iConstits[i0].id == 1 or iConstits[i0].id == 2;
149  if (not((fApplyCHS and getsDefaultWgtIfApplyCHS) or iConstits[i0].id == 3) or
150  (std::abs(iConstits[i0].eta) < fPuppiAlgo[pPupId].etaMaxExtrap() and getsDefaultWgtIfApplyCHS)) {
151  pVal = goodVar(iConstits[i0], pCharged ? iChargedParticles : iParticles, pAlgo, pCone);
152  }
153  fVals.push_back(pVal);
154 
155  if (!edm::isFinite(pVal)) {
156  LogDebug("NotFound") << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt << " -- " << iConstits[i0].eta
157  << endl;
158  continue;
159  }
160 
161  // code added by Nhan: now instead for every algorithm give it all the particles
162  for (int i1 = 0; i1 < fNAlgos; i1++) {
163  // skip cands outside of algo's etaMaxExtrap, as they would anyway be ignored inside PuppiAlgo::add (see end of the block)
164  if (not(std::abs(iConstits[i0].eta) < fPuppiAlgo[i1].etaMaxExtrap() and getsDefaultWgtIfApplyCHS))
165  continue;
166 
167  auto curVal = pVal;
168  // recompute goodVar if algo has changed
169  if (i1 != pPupId) {
170  pAlgo = fPuppiAlgo[i1].algoId(iOpt);
171  pCharged = fPuppiAlgo[i1].isCharged(iOpt);
172  pCone = fPuppiAlgo[i1].coneSize(iOpt);
173  curVal = goodVar(iConstits[i0], pCharged ? iChargedParticles : iParticles, pAlgo, pCone);
174  }
175 
176  fPuppiAlgo[i1].add(iConstits[i0], curVal, iOpt);
177  }
178  }
179 
180  for (int i0 = 0; i0 < fNAlgos; i0++)
181  fPuppiAlgo[i0].computeMedRMS(iOpt);
182 }
183 
184 //In fact takes the median not the average
186  std::vector<PuppiCandidate> const &iConstits,
187  std::vector<PuppiCandidate> const &iParticles,
188  std::vector<PuppiCandidate> const &iChargedParticles) {
189  for (int j0 = 0; j0 < fNAlgos; j0++) {
190  for (unsigned int i0 = 0; i0 < iConstits.size(); i0++) {
191  //Get the Puppi Sub Algo (given iteration)
192  int pAlgo = fPuppiAlgo[j0].algoId(iOpt);
193  bool pCharged = fPuppiAlgo[j0].isCharged(iOpt);
194  double pCone = fPuppiAlgo[j0].coneSize(iOpt);
195  //Compute the Puppi Metric
196  double const pVal = goodVar(iConstits[i0], pCharged ? iChargedParticles : iParticles, pAlgo, pCone);
197  fRawAlphas.push_back(pVal);
198  if (!edm::isFinite(pVal)) {
199  LogDebug("NotFound") << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt << " -- "
200  << iConstits[i0].eta << endl;
201  continue;
202  }
203  }
204  }
205 }
206 
207 int PuppiContainer::getPuppiId(float iPt, float iEta) {
208  int lId = -1;
209  for (int i0 = 0; i0 < fNAlgos; i0++) {
210  int nEtaBinsPerAlgo = fPuppiAlgo[i0].etaBins();
211  for (int i1 = 0; i1 < nEtaBinsPerAlgo; i1++) {
212  if ((std::abs(iEta) >= fPuppiAlgo[i0].etaMin(i1)) && (std::abs(iEta) < fPuppiAlgo[i0].etaMax(i1))) {
213  fPuppiAlgo[i0].fixAlgoEtaBin(i1);
214  if (iPt > fPuppiAlgo[i0].ptMin()) {
215  lId = i0;
216  break;
217  }
218  }
219  }
220  }
221  //if(lId == -1) std::cerr << "Error : Full fiducial range is not defined " << std::endl;
222  return lId;
223 }
224 double PuppiContainer::getChi2FromdZ(double iDZ) {
225  //We need to obtain prob of PU + (1-Prob of LV)
226  // Prob(LV) = Gaus(dZ,sigma) where sigma = 1.5mm (its really more like 1mm)
227  //double lProbLV = ROOT::Math::normal_cdf_c(std::abs(iDZ),0.2)*2.; //*2 is to do it double sided
228  //Take iDZ to be corrected by sigma already
229  double lProbLV = ROOT::Math::normal_cdf_c(std::abs(iDZ), 1.) * 2.; //*2 is to do it double sided
230  double lProbPU = 1 - lProbLV;
231  if (lProbPU <= 0)
232  lProbPU = 1e-16; //Quick Trick to through out infs
233  if (lProbPU >= 0)
234  lProbPU = 1 - 1e-16; //Ditto
235  double lChi2PU = TMath::ChisquareQuantile(lProbPU, 1);
236  lChi2PU *= lChi2PU;
237  return lChi2PU;
238 }
239 std::vector<double> const &PuppiContainer::puppiWeights() {
240  int lNParticles = fRecoParticles->size();
241 
242  fWeights.clear();
243  fWeights.reserve(lNParticles);
244  fVals.clear();
245  fVals.reserve(lNParticles);
246  for (int i0 = 0; i0 < fNAlgos; i0++)
247  fPuppiAlgo[i0].reset();
248 
249  int lNMaxAlgo = 1;
250  for (int i0 = 0; i0 < fNAlgos; i0++)
251  lNMaxAlgo = std::max(fPuppiAlgo[i0].numAlgos(), lNMaxAlgo);
252  //Run through all compute mean and RMS
253  for (int i0 = 0; i0 < lNMaxAlgo; i0++) {
254  getRMSAvg(i0, fPFParticles, fPFParticlesForVar, fPFParticlesForVarChargedPV);
255  }
256  if (fPuppiDiagnostics)
257  getRawAlphas(0, fPFParticles, fPFParticlesForVar, fPFParticlesForVarChargedPV);
258 
259  std::vector<double> pVals;
260  pVals.reserve(lNParticles);
261  for (int i0 = 0; i0 < lNParticles; i0++) {
262  //Refresh
263  pVals.clear();
264  double pWeight = 1;
265  //Get the Puppi Id and if ill defined move on
266  const auto &rParticle = (*fRecoParticles)[i0];
267  int pPupId = getPuppiId(rParticle.pt, rParticle.eta);
268  if (pPupId == -1) {
269  fWeights.push_back(0);
270  fAlphaMed.push_back(-10);
271  fAlphaRMS.push_back(-10);
272  continue;
273  }
274 
275  // fill the p-values
276  double pChi2 = 0;
277  if (fUseExp) {
278  //Compute an Experimental Puppi Weight with delta Z info (very simple example)
279  pChi2 = getChi2FromdZ(rParticle.dZ);
280  //Now make sure Neutrals are not set
281  if ((std::abs(rParticle.pdgId) == 22) || (std::abs(rParticle.pdgId) == 130))
282  pChi2 = 0;
283  }
284  //Fill and compute the PuppiWeight
285  int lNAlgos = fPuppiAlgo[pPupId].numAlgos();
286  for (int i1 = 0; i1 < lNAlgos; i1++)
287  pVals.push_back(fVals[lNParticles * i1 + i0]);
288 
289  pWeight = fPuppiAlgo[pPupId].compute(pVals, pChi2);
290  //Apply the CHS weights
291  if (rParticle.id == 1 && fApplyCHS)
292  pWeight = 1;
293  if (rParticle.id == 2 && fApplyCHS)
294  pWeight = 0;
295  //Apply weight of 1 for leptons if puppiNoLep
296  if (rParticle.id == 3)
297  pWeight = 1;
298  //Basic Weight Checks
299  if (!edm::isFinite(pWeight)) {
300  pWeight = 0.0;
301  LogDebug("PuppiWeightError") << "====> Weight is nan : " << pWeight << " : pt " << rParticle.pt
302  << " -- eta : " << rParticle.eta << " -- Value" << fVals[i0]
303  << " -- id : " << rParticle.id << " -- NAlgos: " << lNAlgos << std::endl;
304  }
305  //Basic Cuts
306  if (pWeight * fPFParticles[i0].pt < fPuppiAlgo[pPupId].neutralPt(fPUProxy) && rParticle.id == 0)
307  pWeight = 0; //threshold cut on the neutral Pt
308  // Protect high pT photons (important for gamma to hadronic recoil balance)
309  if (fPtMaxPhotons > 0 && rParticle.pdgId == 22 && std::abs(fPFParticles[i0].eta) < fEtaMaxPhotons &&
310  fPFParticles[i0].pt > fPtMaxPhotons)
311  pWeight = 1.;
312  // Protect high pT neutrals
313  else if ((fPtMaxNeutrals > 0) && (rParticle.id == 0))
314  pWeight = std::clamp(
315  (fPFParticles[i0].pt - fPtMaxNeutralsStartSlope) / (fPtMaxNeutrals - fPtMaxNeutralsStartSlope), pWeight, 1.);
316  if (pWeight < fPuppiWeightCut)
317  pWeight = 0; //==> Elminate the low Weight stuff
318  if (fInvert)
319  pWeight = 1. - pWeight;
320  //std::cout << "rParticle.pt = " << rParticle.pt << ", rParticle.charge = " << rParticle.charge << ", rParticle.id = " << rParticle.id << ", weight = " << pWeight << std::endl;
321 
322  fWeights.push_back(pWeight);
323  fAlphaMed.push_back(fPuppiAlgo[pPupId].median());
324  fAlphaRMS.push_back(fPuppiAlgo[pPupId].rms());
325  //Now get rid of the thrown out weights for the particle collection
326 
327  // leave these lines in, in case want to move eventually to having no 1-to-1 correspondence between puppi and pf cands
328  // if( std::abs(pWeight) < std::numeric_limits<double>::denorm_min() ) continue; // this line seems not to work like it's supposed to...
329  // if(std::abs(pWeight) <= 0. ) continue;
330  }
331  return fWeights;
332 }
PuppiCandidate::pt
double pt
Definition: PuppiCandidate.h:5
ALCARECOTkAlBeamHalo_cff.etaMin
etaMin
GeV.
Definition: ALCARECOTkAlBeamHalo_cff.py:32
PuppiContainer::getChi2FromdZ
double getChi2FromdZ(double iDZ)
Definition: PuppiContainer.cc:224
MessageLogger.h
PuppiContainer::PuppiContainer
PuppiContainer(const edm::ParameterSet &iConfig)
Definition: PuppiContainer.cc:12
PuppiCandidate::eta
double eta
Definition: PuppiCandidate.h:6
DiDispStaMuonMonitor_cfi.pt
pt
Definition: DiDispStaMuonMonitor_cfi.py:39
pfDeepBoostedJetPreprocessParams_cfi.median
median
Definition: pfDeepBoostedJetPreprocessParams_cfi.py:12
testProducerWithPsetDescEmpty_cfi.i1
i1
Definition: testProducerWithPsetDescEmpty_cfi.py:45
ptMin
constexpr float ptMin
Definition: PhotonIDValueMapProducer.cc:155
PuppiContainer::~PuppiContainer
~PuppiContainer()
Definition: PuppiContainer.cc:77
PuppiContainer::puppiWeights
const std::vector< double > & puppiWeights()
Definition: PuppiContainer.cc:239
SiStripPI::rms
Definition: SiStripPayloadInspectorHelper.h:169
ecalTrigSettings_cff.particles
particles
Definition: ecalTrigSettings_cff.py:11
PuppiCandidate
Definition: PuppiCandidate.h:4
trigObjTnPSource_cfi.var
var
Definition: trigObjTnPSource_cfi.py:21
PVValHelper::eta
Definition: PVValidationHelpers.h:70
PuppiContainer::getPuppiId
int getPuppiId(float iPt, float iEta)
Definition: PuppiContainer.cc:207
PuppiContainer::goodVar
double goodVar(PuppiCandidate const &iPart, std::vector< PuppiCandidate > const &iParts, int iOpt, const double iRCone)
Definition: PuppiContainer.cc:79
PuppiAlgo
Definition: PuppiAlgo.h:10
PuppiCandidate::id
int id
Definition: PuppiCandidate.h:10
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:233
edm::ParameterSet
Definition: ParameterSet.h:47
PuppiContainer::getRawAlphas
void getRawAlphas(int iOpt, std::vector< PuppiCandidate > const &iConstits, std::vector< PuppiCandidate > const &iParticles, std::vector< PuppiCandidate > const &iChargeParticles)
Definition: PuppiContainer.cc:185
deltaR.h
PuppiContainer::var_within_R
double var_within_R(int iId, const std::vector< PuppiCandidate > &particles, const PuppiCandidate &centre, const double R)
Definition: PuppiContainer.cc:86
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
reco::deltaR2
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
diffTwoXMLs.r2
r2
Definition: diffTwoXMLs.py:73
cand
Definition: decayParser.h:32
PuppiCandidate::rapidity
double rapidity
Definition: PuppiCandidate.h:9
std
Definition: JetResolutionObject.h:76
isFinite.h
PuppiContainer.h
ALCARECOTkAlBeamHalo_cff.etaMax
etaMax
Definition: ALCARECOTkAlBeamHalo_cff.py:33
or
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
PuppiCandidate::phi
double phi
Definition: PuppiCandidate.h:7
dqm-mbProfile.log
log
Definition: dqm-mbProfile.py:17
PuppiContainer::getRMSAvg
void getRMSAvg(int iOpt, std::vector< PuppiCandidate > const &iConstits, std::vector< PuppiCandidate > const &iParticles, std::vector< PuppiCandidate > const &iChargeParticles)
Definition: PuppiContainer.cc:129
reset
void reset(double vett[256])
Definition: TPedValues.cc:11
L1TowerCalibrationProducer_cfi.iEta
iEta
Definition: L1TowerCalibrationProducer_cfi.py:60
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::isFinite
constexpr bool isFinite(T x)
PuppiCandidate::m
double m
Definition: PuppiCandidate.h:8
PuppiContainer::initialize
void initialize(const std::vector< RecoObj > &iRecoObjects)
Definition: PuppiContainer.cc:30
dttmaxenums::R
Definition: DTTMax.h:29
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37