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  fChargedPV.resize(0);
34  fWeights.resize(0);
35  fVals.resize(0);
36  fRawAlphas.resize(0);
37  fAlphaMed.resize(0);
38  fAlphaRMS.resize(0);
39  //fChargedNoPV.resize(0);
40  //Link to the RecoObjects
41  fPVFrac = 0.;
42  fNPV = 1.;
43  fRecoParticles = &iRecoObjects;
44  for (auto const &rParticle : *fRecoParticles) {
45  PuppiCandidate curPseudoJet;
46  // float nom = sqrt((rParticle.m)*(rParticle.m) + (rParticle.pt)*(rParticle.pt)*(cosh(rParticle.eta))*(cosh(rParticle.eta))) + (rParticle.pt)*sinh(rParticle.eta);//hacked
47  // float denom = sqrt((rParticle.m)*(rParticle.m) + (rParticle.pt)*(rParticle.pt));//hacked
48  // float rapidity = log(nom/denom);//hacked
49  if (edm::isFinite(rParticle.rapidity)) {
50  curPseudoJet.reset_PtYPhiM(rParticle.pt, rParticle.rapidity, rParticle.phi, rParticle.m); //hacked
51  } else {
52  curPseudoJet.reset_PtYPhiM(0, 99., 0, 0); //skipping may have been a better choice
53  }
54  //curPseudoJet.reset_PtYPhiM(rParticle.pt,rParticle.eta,rParticle.phi,rParticle.m);
55  // fill puppi_register
56  curPseudoJet.set_info(rParticle.id);
57  // fill vector of pseudojets for internal references
58  fPFParticles.push_back(curPseudoJet);
59  //Take Charged particles associated to PV
60  if (std::abs(rParticle.id) == 1)
61  fChargedPV.push_back(curPseudoJet);
62  //if(rParticle.id == 3) _chargedNoPV.push_back(curPseudoJet);
63  // if(fNPV < rParticle.vtxId) fNPV = rParticle.vtxId;
64  }
65 }
67 
69  std::vector<PuppiCandidate> const &iParts,
70  int iOpt,
71  const double iRCone) {
72  return var_within_R(iOpt, iParts, iPart, iRCone);
73 }
74 
76  const vector<PuppiCandidate> &particles,
77  const PuppiCandidate &centre,
78  const double R) {
79  if (iId == -1)
80  return 1;
81 
82  //this is a circle in rapidity-phi
83  //it would make more sense to have var definition consistent
84  //fastjet::Selector sel = fastjet::SelectorCircle(R);
85  //sel.set_reference(centre);
86  //the original code used Selector infrastructure: it is too heavy here
87  //logic of SelectorCircle is preserved below
88 
89  vector<double> near_dR2s;
90  near_dR2s.reserve(std::min(50UL, particles.size()));
91  vector<double> near_pts;
92  near_pts.reserve(std::min(50UL, particles.size()));
93  const double r2 = R * R;
94  for (auto const &part : particles) {
95  if (part.puppi_register() == 3)
96  continue;
97  //squared_distance is in (y,phi) coords: rap() has faster access -> check it first
98  if (std::abs(part.rap() - centre.rap()) < R && part.squared_distance(centre) < r2) {
99  near_dR2s.push_back(reco::deltaR2(part, centre));
100  near_pts.push_back(part.pt());
101  }
102  }
103  double var = 0;
104  //double lSumPt = 0;
105  //if(iId == 1) for(auto pt : near_pts) lSumPt += pt;
106  auto nParts = near_dR2s.size();
107  for (auto i = 0UL; i < nParts; ++i) {
108  auto dr2 = near_dR2s[i];
109  auto pt = near_pts[i];
110  if (dr2 < 0.0001)
111  continue;
112  if (iId == 0)
113  var += (pt / dr2);
114  else if (iId == 1)
115  var += pt;
116  else if (iId == 2)
117  var += (1. / dr2);
118  else if (iId == 3)
119  var += (1. / dr2);
120  else if (iId == 4)
121  var += pt;
122  else if (iId == 5)
123  var += (pt * pt / dr2);
124  }
125  if (iId == 1)
126  var += centre.pt(); //Sum in a cone
127  else if (iId == 0 && var != 0)
128  var = log(var);
129  else if (iId == 3 && var != 0)
130  var = log(var);
131  else if (iId == 5 && var != 0)
132  var = log(var);
133  return var;
134 }
135 //In fact takes the median not the average
137  std::vector<PuppiCandidate> const &iConstits,
138  std::vector<PuppiCandidate> const &iParticles,
139  std::vector<PuppiCandidate> const &iChargedParticles) {
140  for (unsigned int i0 = 0; i0 < iConstits.size(); i0++) {
141  double pVal = -1;
142  //Calculate the Puppi Algo to use
143  int pPupId = getPuppiId(iConstits[i0].pt(), iConstits[i0].eta());
144  if (pPupId == -1 || fPuppiAlgo[pPupId].numAlgos() <= iOpt) {
145  fVals.push_back(-1);
146  continue;
147  }
148  //Get the Puppi Sub Algo (given iteration)
149  int pAlgo = fPuppiAlgo[pPupId].algoId(iOpt);
150  bool pCharged = fPuppiAlgo[pPupId].isCharged(iOpt);
151  double pCone = fPuppiAlgo[pPupId].coneSize(iOpt);
152  //Compute the Puppi Metric
153  if (!pCharged)
154  pVal = goodVar(iConstits[i0], iParticles, pAlgo, pCone);
155  if (pCharged)
156  pVal = goodVar(iConstits[i0], iChargedParticles, pAlgo, pCone);
157  fVals.push_back(pVal);
158  //if(std::isnan(pVal) || std::isinf(pVal)) cerr << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt() << " -- " << iConstits[i0].eta() << endl;
159  if (!edm::isFinite(pVal)) {
160  LogDebug("NotFound") << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt() << " -- "
161  << iConstits[i0].eta() << endl;
162  continue;
163  }
164 
165  // // fPuppiAlgo[pPupId].add(iConstits[i0],pVal,iOpt);
166  //code added by Nhan, now instead for every algorithm give it all the particles
167  for (int i1 = 0; i1 < fNAlgos; i1++) {
168  pAlgo = fPuppiAlgo[i1].algoId(iOpt);
169  pCharged = fPuppiAlgo[i1].isCharged(iOpt);
170  pCone = fPuppiAlgo[i1].coneSize(iOpt);
171  double curVal = -1;
172  if (i1 != pPupId) {
173  if (!pCharged)
174  curVal = goodVar(iConstits[i0], iParticles, pAlgo, pCone);
175  if (pCharged)
176  curVal = goodVar(iConstits[i0], iChargedParticles, pAlgo, pCone);
177  } else { //no need to repeat the computation
178  curVal = pVal;
179  }
180  //std::cout << "i1 = " << i1 << ", curVal = " << curVal << ", eta = " << iConstits[i0].eta() << ", pupID = " << pPupId << std::endl;
181  fPuppiAlgo[i1].add(iConstits[i0], curVal, iOpt);
182  }
183  }
184  for (int i0 = 0; i0 < fNAlgos; i0++)
185  fPuppiAlgo[i0].computeMedRMS(iOpt);
186 }
187 //In fact takes the median not the average
189  std::vector<PuppiCandidate> const &iConstits,
190  std::vector<PuppiCandidate> const &iParticles,
191  std::vector<PuppiCandidate> const &iChargedParticles) {
192  for (int j0 = 0; j0 < fNAlgos; j0++) {
193  for (unsigned int i0 = 0; i0 < iConstits.size(); i0++) {
194  double pVal = -1;
195  //Get the Puppi Sub Algo (given iteration)
196  int pAlgo = fPuppiAlgo[j0].algoId(iOpt);
197  bool pCharged = fPuppiAlgo[j0].isCharged(iOpt);
198  double pCone = fPuppiAlgo[j0].coneSize(iOpt);
199  //Compute the Puppi Metric
200  if (!pCharged)
201  pVal = goodVar(iConstits[i0], iParticles, pAlgo, pCone);
202  if (pCharged)
203  pVal = goodVar(iConstits[i0], iChargedParticles, pAlgo, pCone);
204  fRawAlphas.push_back(pVal);
205  if (!edm::isFinite(pVal)) {
206  LogDebug("NotFound") << "====> Value is Nan " << pVal << " == " << iConstits[i0].pt() << " -- "
207  << iConstits[i0].eta() << endl;
208  continue;
209  }
210  }
211  }
212 }
213 int PuppiContainer::getPuppiId(float iPt, float iEta) {
214  int lId = -1;
215  for (int i0 = 0; i0 < fNAlgos; i0++) {
216  int nEtaBinsPerAlgo = fPuppiAlgo[i0].etaBins();
217  for (int i1 = 0; i1 < nEtaBinsPerAlgo; i1++) {
218  if ((std::abs(iEta) > fPuppiAlgo[i0].etaMin(i1)) && (std::abs(iEta) < fPuppiAlgo[i0].etaMax(i1))) {
219  fPuppiAlgo[i0].fixAlgoEtaBin(i1);
220  if (iPt > fPuppiAlgo[i0].ptMin()) {
221  lId = i0;
222  break;
223  }
224  }
225  }
226  }
227  //if(lId == -1) std::cerr << "Error : Full fiducial range is not defined " << std::endl;
228  return lId;
229 }
230 double PuppiContainer::getChi2FromdZ(double iDZ) {
231  //We need to obtain prob of PU + (1-Prob of LV)
232  // Prob(LV) = Gaus(dZ,sigma) where sigma = 1.5mm (its really more like 1mm)
233  //double lProbLV = ROOT::Math::normal_cdf_c(std::abs(iDZ),0.2)*2.; //*2 is to do it double sided
234  //Take iDZ to be corrected by sigma already
235  double lProbLV = ROOT::Math::normal_cdf_c(std::abs(iDZ), 1.) * 2.; //*2 is to do it double sided
236  double lProbPU = 1 - lProbLV;
237  if (lProbPU <= 0)
238  lProbPU = 1e-16; //Quick Trick to through out infs
239  if (lProbPU >= 0)
240  lProbPU = 1 - 1e-16; //Ditto
241  double lChi2PU = TMath::ChisquareQuantile(lProbPU, 1);
242  lChi2PU *= lChi2PU;
243  return lChi2PU;
244 }
245 std::vector<double> const &PuppiContainer::puppiWeights() {
246  int lNParticles = fRecoParticles->size();
247 
248  fWeights.clear();
249  fWeights.reserve(lNParticles);
250  fVals.clear();
251  fVals.reserve(lNParticles);
252  for (int i0 = 0; i0 < fNAlgos; i0++)
253  fPuppiAlgo[i0].reset();
254 
255  int lNMaxAlgo = 1;
256  for (int i0 = 0; i0 < fNAlgos; i0++)
257  lNMaxAlgo = std::max(fPuppiAlgo[i0].numAlgos(), lNMaxAlgo);
258  //Run through all compute mean and RMS
259  for (int i0 = 0; i0 < lNMaxAlgo; i0++) {
260  getRMSAvg(i0, fPFParticles, fPFParticles, fChargedPV);
261  }
262  if (fPuppiDiagnostics)
263  getRawAlphas(0, fPFParticles, fPFParticles, fChargedPV);
264 
265  std::vector<double> pVals;
266  pVals.reserve(lNParticles);
267  for (int i0 = 0; i0 < lNParticles; i0++) {
268  //Refresh
269  pVals.clear();
270  double pWeight = 1;
271  //Get the Puppi Id and if ill defined move on
272  const auto &rParticle = (*fRecoParticles)[i0];
273  int pPupId = getPuppiId(rParticle.pt, rParticle.eta);
274  if (pPupId == -1) {
275  fWeights.push_back(0);
276  fAlphaMed.push_back(-10);
277  fAlphaRMS.push_back(-10);
278  continue;
279  }
280 
281  // fill the p-values
282  double pChi2 = 0;
283  if (fUseExp) {
284  //Compute an Experimental Puppi Weight with delta Z info (very simple example)
285  pChi2 = getChi2FromdZ(rParticle.dZ);
286  //Now make sure Neutrals are not set
287  if ((std::abs(rParticle.pdgId) == 22) || (std::abs(rParticle.pdgId) == 130))
288  pChi2 = 0;
289  }
290  //Fill and compute the PuppiWeight
291  int lNAlgos = fPuppiAlgo[pPupId].numAlgos();
292  for (int i1 = 0; i1 < lNAlgos; i1++)
293  pVals.push_back(fVals[lNParticles * i1 + i0]);
294 
295  pWeight = fPuppiAlgo[pPupId].compute(pVals, pChi2);
296  //Apply the CHS weights
297  if (rParticle.id == 1 && fApplyCHS)
298  pWeight = 1;
299  if (rParticle.id == 2 && fApplyCHS)
300  pWeight = 0;
301  //Apply weight of 1 for leptons if puppiNoLep
302  if (rParticle.id == 3)
303  pWeight = 1;
304  //Basic Weight Checks
305  if (!edm::isFinite(pWeight)) {
306  pWeight = 0.0;
307  LogDebug("PuppiWeightError") << "====> Weight is nan : " << pWeight << " : pt " << rParticle.pt
308  << " -- eta : " << rParticle.eta << " -- Value" << fVals[i0]
309  << " -- id : " << rParticle.id << " -- NAlgos: " << lNAlgos << std::endl;
310  }
311  //Basic Cuts
312  if (pWeight * fPFParticles[i0].pt() < fPuppiAlgo[pPupId].neutralPt(fNPV) && rParticle.id == 0)
313  pWeight = 0; //threshold cut on the neutral Pt
314  // Protect high pT photons (important for gamma to hadronic recoil balance)
315  if ((fPtMaxPhotons > 0) && (rParticle.pdgId == 22) && (std::abs(fPFParticles[i0].eta()) < fEtaMaxPhotons) &&
316  (fPFParticles[i0].pt() > fPtMaxPhotons))
317  pWeight = 1.;
318  // Protect high pT neutrals
319  else if ((fPtMaxNeutrals > 0) && (rParticle.id == 0))
320  pWeight =
321  std::clamp((fPFParticles[i0].pt() - fPtMaxNeutralsStartSlope) / (fPtMaxNeutrals - fPtMaxNeutralsStartSlope),
322  pWeight,
323  1.);
324  if (pWeight < fPuppiWeightCut)
325  pWeight = 0; //==> Elminate the low Weight stuff
326  if (fInvert)
327  pWeight = 1. - pWeight;
328  //std::cout << "rParticle.pt = " << rParticle.pt << ", rParticle.charge = " << rParticle.charge << ", rParticle.id = " << rParticle.id << ", weight = " << pWeight << std::endl;
329 
330  fWeights.push_back(pWeight);
331  fAlphaMed.push_back(fPuppiAlgo[pPupId].median());
332  fAlphaRMS.push_back(fPuppiAlgo[pPupId].rms());
333  //Now get rid of the thrown out weights for the particle collection
334 
335  // leave these lines in, in case want to move eventually to having no 1-to-1 correspondence between puppi and pf cands
336  // if( std::abs(pWeight) < std::numeric_limits<double>::denorm_min() ) continue; // this line seems not to work like it's supposed to...
337  // if(std::abs(pWeight) <= 0. ) continue;
338  }
339  return fWeights;
340 }
ALCARECOTkAlBeamHalo_cff.etaMin
etaMin
GeV.
Definition: ALCARECOTkAlBeamHalo_cff.py:32
mps_fire.i
i
Definition: mps_fire.py:355
PuppiContainer::getChi2FromdZ
double getChi2FromdZ(double iDZ)
Definition: PuppiContainer.cc:230
MessageLogger.h
PuppiContainer::PuppiContainer
PuppiContainer(const edm::ParameterSet &iConfig)
Definition: PuppiContainer.cc:12
DiDispStaMuonMonitor_cfi.pt
pt
Definition: DiDispStaMuonMonitor_cfi.py:39
min
T min(T a, T b)
Definition: MathUtil.h:58
testProducerWithPsetDescEmpty_cfi.i1
i1
Definition: testProducerWithPsetDescEmpty_cfi.py:45
ptMin
constexpr float ptMin
Definition: PhotonIDValueMapProducer.cc:153
PuppiContainer::~PuppiContainer
~PuppiContainer()
Definition: PuppiContainer.cc:66
PuppiContainer::puppiWeights
const std::vector< double > & puppiWeights()
Definition: PuppiContainer.cc:245
SiStripPI::rms
Definition: SiStripPayloadInspectorHelper.h:169
ecalTrigSettings_cff.particles
particles
Definition: ecalTrigSettings_cff.py:11
trigObjTnPSource_cfi.var
var
Definition: trigObjTnPSource_cfi.py:21
deltaR.h
part
part
Definition: HCALResponse.h:20
PVValHelper::eta
Definition: PVValidationHelpers.h:69
PuppiContainer::getPuppiId
int getPuppiId(float iPt, float iEta)
Definition: PuppiContainer.cc:213
PuppiContainer::goodVar
double goodVar(PuppiCandidate const &iPart, std::vector< PuppiCandidate > const &iParts, int iOpt, const double iRCone)
Definition: PuppiContainer.cc:68
PuppiAlgo
Definition: PuppiAlgo.h:10
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:670
edm::ParameterSet
Definition: ParameterSet.h:36
PuppiContainer::getRawAlphas
void getRawAlphas(int iOpt, std::vector< PuppiCandidate > const &iConstits, std::vector< PuppiCandidate > const &iParticles, std::vector< PuppiCandidate > const &iChargeParticles)
Definition: PuppiContainer.cc:188
PuppiContainer::var_within_R
double var_within_R(int iId, const std::vector< PuppiCandidate > &particles, const PuppiCandidate &centre, const double R)
Definition: PuppiContainer.cc:75
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
PuppiCandidate
Definition: PuppiCandidate.h:8
pfParticleNetPreprocessParams_cfi.median
median
Definition: pfParticleNetPreprocessParams_cfi.py:16
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
std
Definition: JetResolutionObject.h:76
isFinite.h
PuppiContainer.h
PuppiCandidate::set_info
void set_info(int puppi_register)
Definition: PuppiCandidate.h:20
ALCARECOTkAlBeamHalo_cff.etaMax
etaMax
Definition: ALCARECOTkAlBeamHalo_cff.py:33
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:136
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)
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