CMS 3D CMS Logo

PFAlgo2HGC.cc
Go to the documentation of this file.
3 
5 
7 
9 
10 namespace {
11  template <typename T1, typename T2>
12  float floatDR(const T1 &t1, const T2 &t2) {
13  return deltaR(t1.floatEta(), t1.floatPhi(), t2.floatEta(), t2.floatPhi());
14  }
15 } // namespace
16 
17 using namespace l1tpf_impl;
18 
20  debug_ = iConfig.getUntrackedParameter<int>("debugPFAlgo2HGC", iConfig.getUntrackedParameter<int>("debug", 0));
21  edm::ParameterSet linkcfg = iConfig.getParameter<edm::ParameterSet>("linking");
22  drMatchMu_ = linkcfg.getParameter<double>("trackMuDR");
23 
24  std::string muMatchMode = linkcfg.getParameter<std::string>("trackMuMatch");
25  if (muMatchMode == "boxBestByPtRatio")
27  else if (muMatchMode == "drBestByPtRatio")
29  else if (muMatchMode == "drBestByPtDiff")
31  else
32  throw cms::Exception("Configuration", "bad value for trackMuMatch configurable");
33 
34  std::string tkCaloLinkMetric = linkcfg.getParameter<std::string>("trackCaloLinkMetric");
35  if (tkCaloLinkMetric == "bestByDR")
37  else if (tkCaloLinkMetric == "bestByDRPt")
39  else if (tkCaloLinkMetric == "bestByDR2Pt2")
41  else
42  throw cms::Exception("Configuration", "bad value for tkCaloLinkMetric configurable");
43 
44  drMatch_ = linkcfg.getParameter<double>("trackCaloDR");
45  ptMatchLow_ = linkcfg.getParameter<double>("trackCaloNSigmaLow");
46  ptMatchHigh_ = linkcfg.getParameter<double>("trackCaloNSigmaHigh");
47  useTrackCaloSigma_ = linkcfg.getParameter<bool>("useTrackCaloSigma");
48  maxInvisiblePt_ = linkcfg.getParameter<double>("maxInvisiblePt");
49 
50  caloReLinkStep_ = linkcfg.getParameter<bool>("caloReLink");
51  caloReLinkDr_ = linkcfg.getParameter<double>("caloReLinkDR");
52  caloReLinkThreshold_ = linkcfg.getParameter<double>("caloReLinkThreshold");
53  rescaleTracks_ = linkcfg.getParameter<bool>("rescaleTracks");
54  caloTrkWeightedAverage_ = linkcfg.getParameter<bool>("useCaloTrkWeightedAverage");
55  sumTkCaloErr2_ = linkcfg.getParameter<bool>("sumTkCaloErr2");
56  ecalPriority_ = linkcfg.getParameter<bool>("ecalPriority");
57  tightTrackMinStubs_ = linkcfg.getParameter<unsigned>("tightTrackMinStubs");
58  tightTrackMaxChi2_ = linkcfg.getParameter<double>("tightTrackMaxChi2");
59  tightTrackMaxInvisiblePt_ = linkcfg.getParameter<double>("tightTrackMaxInvisiblePt");
60 }
61 
62 void PFAlgo2HGC::runPF(Region &r) const {
63  initRegion(r);
64 
66 
67  if (debug_) {
68  dbgPrintf(
69  "PFAlgo2HGC\nPFAlgo2HGC region eta [ %+5.2f , %+5.2f ], phi [ %+5.2f , %+5.2f ], fiducial eta [ %+5.2f , "
70  "%+5.2f ], phi [ %+5.2f , %+5.2f ]\n",
71  r.etaMin - r.etaExtra,
72  r.etaMax + r.etaExtra,
73  r.phiCenter - r.phiHalfWidth - r.phiExtra,
74  r.phiCenter + r.phiHalfWidth + r.phiExtra,
75  r.etaMin,
76  r.etaMax,
77  r.phiCenter - r.phiHalfWidth,
78  r.phiCenter + r.phiHalfWidth);
79  dbgPrintf(
80  "PFAlgo2HGC \t N(track) %3lu N(calo) %3lu N(mu) %3lu\n", r.track.size(), r.calo.size(), r.muon.size());
81  for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) {
82  const auto &tk = r.track[itk];
83  dbgPrintf(
84  "PFAlgo2HGC \t track %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi "
85  "%+5.2f fid %1d calo ptErr %7.2f stubs %2d chi2 %7.1f\n",
86  itk,
87  tk.floatPt(),
88  tk.floatPtErr(),
89  tk.floatVtxEta(),
90  tk.floatVtxPhi(),
91  tk.floatEta(),
92  tk.floatPhi(),
93  int(r.fiducialLocal(tk.floatEta(), tk.floatPhi())),
94  tk.floatCaloPtErr(),
95  int(tk.hwStubs),
96  tk.hwChi2 * 0.1f);
97  }
98  for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) {
99  auto &calo = r.calo[ic];
100  dbgPrintf(
101  "PFAlgo2HGC \t calo %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi "
102  "%+5.2f fid %1d calo ptErr %7.2f em pt %7.2f isEM %1d \n",
103  ic,
104  calo.floatPt(),
105  calo.floatPtErr(),
106  calo.floatEta(),
107  calo.floatPhi(),
108  calo.floatEta(),
109  calo.floatPhi(),
110  int(r.fiducialLocal(calo.floatEta(), calo.floatPhi())),
111  calo.floatPtErr(),
112  calo.floatEmPt(),
113  calo.isEM);
114  }
115  for (int im = 0, nm = r.muon.size(); im < nm; ++im) {
116  auto &mu = r.muon[im];
117  dbgPrintf(
118  "PFAlgo2HGC \t muon %3d: pt %7.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi "
119  "%+5.2f fid %1d\n",
120  im,
121  mu.floatPt(),
122  mu.floatEta(),
123  mu.floatPhi(),
124  mu.floatEta(),
125  mu.floatPhi(),
126  int(r.fiducialLocal(mu.floatEta(), mu.floatPhi())));
127  }
128  }
129 
130  std::vector<int> tk2mu(r.track.size(), -1), mu2tk(r.muon.size(), -1);
131  link_tk2mu(r, tk2mu, mu2tk);
132 
133  // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later)
134  std::vector<int> tk2calo(r.track.size(), -1);
135  link_tk2calo(r, tk2calo);
136 
138  // for each calo, compute the sum of the track pt
139  std::vector<int> calo2ntk(r.calo.size(), 0);
140  std::vector<float> calo2sumtkpt(r.calo.size(), 0);
141  std::vector<float> calo2sumtkpterr(r.calo.size(), 0);
142  sum_tk2calo(r, tk2calo, calo2ntk, calo2sumtkpt, calo2sumtkpterr);
143 
144  // in the meantime, promote unlinked low pt tracks to hadrons
145  unlinkedtk_algo(r, tk2calo);
146 
149  // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events
150  if (caloReLinkStep_)
151  calo_relink(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr);
152 
154  // process matched calo clusters, compare energy to sum track pt
155  std::vector<float> calo2alpha(r.calo.size(), 1);
156  linkedcalo_algo(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr, calo2alpha);
157 
160  linkedtk_algo(r, tk2calo, calo2ntk, calo2alpha);
161  // process unmatched calo clusters
163  // finally do muons
164  save_muons(r, tk2mu);
165 }
166 
167 void PFAlgo2HGC::link_tk2mu(Region &r, std::vector<int> &tk2mu, std::vector<int> &mu2tk) const {
168  // do a rectangular match for the moment; make a box of the same are as a 0.2 cone
169  int intDrMuonMatchBox = std::ceil(drMatchMu_ * CaloCluster::ETAPHI_SCALE * std::sqrt(M_PI / 4));
170  for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) {
171  tk2mu[itk] = false;
172  }
173  for (int imu = 0, nmu = r.muon.size(); imu < nmu; ++imu) {
174  const auto &mu = r.muon[imu];
175  if (debug_)
176  dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f, eta %+5.2f, phi %+5.2f) \n",
177  imu,
178  mu.floatPt(),
179  mu.floatEta(),
180  mu.floatPhi());
181  float minDistance = 9e9;
182  switch (muMatchMode_) {
184  minDistance = 4.;
185  break;
187  minDistance = 4.;
188  break;
190  minDistance = 0.5 * mu.floatPt();
191  break;
192  }
193  int imatch = -1;
194  for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) {
195  const auto &tk = r.track[itk];
196  int deta = std::abs(mu.hwEta - tk.hwEta);
197  int dphi = std::abs((mu.hwPhi - tk.hwPhi) % CaloCluster::PHI_WRAP);
198  float dr = floatDR(mu, tk);
199  float dpt = std::abs(mu.floatPt() - tk.floatPt());
200  float dptr = (mu.hwPt > tk.hwPt ? mu.floatPt() / tk.floatPt() : tk.floatPt() / mu.floatPt());
201  bool ok = false;
202  float distance = 9e9;
203  switch (muMatchMode_) {
205  ok = (deta < intDrMuonMatchBox) && (dphi < intDrMuonMatchBox);
206  distance = dptr;
207  break;
209  ok = (dr < drMatchMu_);
210  distance = dptr;
211  break;
213  ok = (dr < drMatchMu_);
214  distance = dpt;
215  break;
216  }
217  if (debug_ && dr < 0.4) {
218  dbgPrintf(
219  "PFAlgo2HGC \t\t possible match with track %3d (pt %7.2f, caloeta %+5.2f, calophi %+5.2f, dr %.2f, eta "
220  "%+5.2f, phi %+5.2f, dr %.2f): angular %1d, distance %.3f (vs %.3f)\n",
221  itk,
222  tk.floatPt(),
223  tk.floatEta(),
224  tk.floatPhi(),
225  dr,
226  tk.floatVtxEta(),
227  tk.floatVtxPhi(),
228  deltaR(mu.floatEta(), mu.floatPhi(), tk.floatVtxEta(), tk.floatVtxPhi()),
229  (ok ? 1 : 0),
230  distance,
231  minDistance);
232  }
233  if (!ok)
234  continue;
235  // FIXME for the moment, we do the floating point matching in pt
236  if (distance < minDistance) {
237  minDistance = distance;
238  imatch = itk;
239  }
240  }
241  if (debug_ && imatch > -1)
242  dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f) linked to track %3d (pt %7.2f)\n",
243  imu,
244  mu.floatPt(),
245  imatch,
246  r.track[imatch].floatPt());
247  if (debug_ && imatch == -1)
248  dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f) not linked to any track\n", imu, mu.floatPt());
249  mu2tk[imu] = imatch;
250  if (imatch > -1) {
251  tk2mu[imatch] = imu;
252  r.track[imatch].muonLink = true;
253  }
254  }
255 }
256 
257 void PFAlgo2HGC::link_tk2calo(Region &r, std::vector<int> &tk2calo) const {
258  // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later)
259  for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) {
260  const auto &tk = r.track[itk];
261  if (tk.muonLink || tk.used)
262  continue; // not necessary but just a waste of CPU otherwise
263  float drbest = drMatch_, dptscale = 0;
264  switch (tkCaloLinkMetric_) {
266  drbest = drMatch_;
267  break;
269  drbest = 1.0;
270  dptscale = drMatch_ / tk.floatCaloPtErr();
271  break;
273  drbest = 1.0;
274  dptscale = drMatch_ / tk.floatCaloPtErr();
275  break;
276  }
277  float minCaloPt = tk.floatPt() - ptMatchLow_ * tk.floatCaloPtErr();
278  if (debug_)
279  dbgPrintf(
280  "PFAlgo2HGC \t track %3d (pt %7.2f) to be matched to calo, min pT %7.2f\n", itk, tk.floatPt(), minCaloPt);
281  for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) {
282  auto &calo = r.calo[ic];
283  if (calo.used || calo.floatPt() <= minCaloPt)
284  continue;
285  float dr = floatDR(tk, calo), dq;
286  switch (tkCaloLinkMetric_) {
288  if (dr < drbest) {
289  tk2calo[itk] = ic;
290  drbest = dr;
291  }
292  break;
294  dq = dr + std::max<float>(tk.floatPt() - calo.floatPt(), 0.) * dptscale;
295  if (debug_ > 2 && dr < 0.3)
296  dbgPrintf("PFAlgo2HGC \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n",
297  itk,
298  tk.floatPt(),
299  ic,
300  calo.floatPt(),
301  dr,
302  dq);
303  if (dr < drMatch_ && dq < drbest) {
304  tk2calo[itk] = ic;
305  drbest = dq;
306  }
307  break;
309  dq = hypot(dr, std::max<float>(tk.floatPt() - calo.floatPt(), 0.) * dptscale);
310  if (debug_ > 2 && dr < 0.3)
311  dbgPrintf("PFAlgo2HGC \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n",
312  itk,
313  tk.floatPt(),
314  ic,
315  calo.floatPt(),
316  dr,
317  dq);
318  if (dr < drMatch_ && dq < drbest) {
319  tk2calo[itk] = ic;
320  drbest = dq;
321  }
322  break;
323  }
324  }
325  if (debug_ && tk2calo[itk] != -1)
326  dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) matches to calo %3d (pt %7.2f) with dist %.3f (dr %.3f)\n",
327  itk,
328  tk.floatPt(),
329  tk2calo[itk],
330  r.calo[tk2calo[itk]].floatPt(),
331  drbest,
332  floatDR(tk, r.calo[tk2calo[itk]]));
333  // now we re-do this for debugging sake, it may be done for real later
334  if (debug_ && tk2calo[itk] == -1) {
335  int ibest = -1;
336  drbest = 0.3;
337  for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) {
338  auto &calo = r.calo[ic];
339  if (calo.used)
340  continue;
341  float dr = floatDR(tk, calo);
342  if (dr < drbest) {
343  ibest = ic;
344  drbest = dr;
345  }
346  }
347  if (ibest != -1)
348  dbgPrintf(
349  "PFAlgo2HGC \t track %3d (pt %7.2f) would match to calo %3d (pt %7.2f) with dr %.3f if the pt min and dr "
350  "requirement had been relaxed\n",
351  itk,
352  tk.floatPt(),
353  ibest,
354  r.calo[ibest].floatPt(),
355  drbest);
356  }
357  }
358 }
359 
361  const std::vector<int> &tk2calo,
362  std::vector<int> &calo2ntk,
363  std::vector<float> &calo2sumtkpt,
364  std::vector<float> &calo2sumtkpterr) const {
365  // for each calo, compute the sum of the track pt
366  for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) {
367  const auto &calo = r.calo[ic];
368  if (r.globalAbsEta(calo.floatEta()) > 2.5)
369  continue;
370  for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) {
371  if (tk2calo[itk] == ic) {
372  const auto &tk = r.track[itk];
373  if (tk.muonLink || tk.used)
374  continue;
375  calo2ntk[ic]++;
376  calo2sumtkpt[ic] += tk.floatPt();
377  calo2sumtkpterr[ic] += std::pow(tk.floatCaloPtErr(), sumTkCaloErr2_ ? 2 : 1);
378  }
379  }
380  if (sumTkCaloErr2_ && calo2sumtkpterr[ic] > 0)
381  calo2sumtkpterr[ic] = std::sqrt(calo2sumtkpterr[ic]);
382  }
383 }
384 
385 void PFAlgo2HGC::unlinkedtk_algo(Region &r, const std::vector<int> &tk2calo) const {
386  // in the meantime, promote unlinked low pt tracks to hadrons
387  for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) {
388  auto &tk = r.track[itk];
389  if (tk2calo[itk] != -1 || tk.muonLink || tk.used)
390  continue;
391  float maxPt = (tk.hwStubs >= tightTrackMinStubs_ && tk.hwChi2 < 10. * tightTrackMaxChi2_)
393  : maxInvisiblePt_;
394  if (tk.floatPt() < maxPt) {
395  if (debug_)
396  dbgPrintf(
397  "PFAlgo2HGC \t track %3d (pt %7.2f) not matched to calo, kept as charged hadron\n", itk, tk.floatPt());
398  auto &p = addTrackToPF(r, tk);
399  p.hwStatus = GoodTK_NoCalo;
400  tk.used = true;
401  } else {
402  if (debug_)
403  dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) not matched to calo, dropped\n", itk, tk.floatPt());
404  }
405  }
406 }
407 
409  const std::vector<int> &calo2ntk,
410  const std::vector<float> &calo2sumtkpt,
411  const std::vector<float> &calo2sumtkpterr) const {
413  // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt
414  // add this pt to the calo pt of the other cluster
415  // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events
416  std::vector<float> addtopt(r.calo.size(), 0);
417  for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) {
418  auto &calo = r.calo[ic];
419  if (calo2ntk[ic] != 0 || calo.used || r.globalAbsEta(calo.floatEta()) > 2.5)
420  continue;
421  int i2best = -1;
422  float drbest = caloReLinkDr_;
423  for (int ic2 = 0; ic2 < nc; ++ic2) {
424  const auto &calo2 = r.calo[ic2];
425  if (calo2ntk[ic2] == 0 || calo2.used || r.globalAbsEta(calo2.floatEta()) > 2.5)
426  continue;
427  float dr = floatDR(calo, calo2);
429  //if (debug_ && dr < 0.5) dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) with no tracks is at dr %.3f from calo %3d with pt %7.2f (sum tk pt %7.2f), track excess %7.2f +- %7.2f\n", ic, calo.floatPt(), dr, ic2, calo2.floatPt(), calo2sumtkpt[ic2], calo2sumtkpt[ic2] - calo2.floatPt(), useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr());
430  if (dr < drbest) {
431  float ptdiff =
432  calo2sumtkpt[ic2] - calo2.floatPt() + (useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr());
433  if (ptdiff >= caloReLinkThreshold_ * calo.floatPt()) {
434  i2best = ic2;
435  drbest = dr;
436  }
437  }
438  }
439  if (i2best != -1) {
440  const auto &calo2 = r.calo[i2best];
441  if (debug_)
442  dbgPrintf(
443  "PFAlgo2HGC \t calo %3d (pt %7.2f) with no tracks matched within dr %.3f with calo %3d with pt %7.2f (sum "
444  "tk pt %7.2f), track excess %7.2f +- %7.2f\n",
445  ic,
446  calo.floatPt(),
447  drbest,
448  i2best,
449  calo2.floatPt(),
450  calo2sumtkpt[i2best],
451  calo2sumtkpt[i2best] - calo2.floatPt(),
452  useTrackCaloSigma_ ? calo2sumtkpterr[i2best] : calo2.floatPtErr());
453  calo.used = true;
454  addtopt[i2best] += calo.floatPt();
455  }
456  }
457  // we do this at the end, so that the above loop is parallelizable
458  for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) {
459  if (addtopt[ic]) {
460  auto &calo = r.calo[ic];
461  if (debug_)
462  dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f, sum tk pt %7.2f) is increased to pt %7.2f after merging\n",
463  ic,
464  calo.floatPt(),
465  calo2sumtkpt[ic],
466  calo.floatPt() + addtopt[ic]);
467  calo.setFloatPt(calo.floatPt() + addtopt[ic]);
468  }
469  }
470 }
471 
473  const std::vector<int> &calo2ntk,
474  const std::vector<float> &calo2sumtkpt,
475  const std::vector<float> &calo2sumtkpterr,
476  std::vector<float> &calo2alpha) const {
478  // process matched calo clusters, compare energy to sum track pt
479  for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) {
480  auto &calo = r.calo[ic];
481  if (calo2ntk[ic] == 0 || calo.used)
482  continue;
483  float ptdiff = calo.floatPt() - calo2sumtkpt[ic];
484  float pterr = useTrackCaloSigma_ ? calo2sumtkpterr[ic] : calo.floatPtErr();
485  if (debug_)
486  dbgPrintf(
487  "PFAlgo2HGC \t calo %3d (pt %7.2f +- %7.2f, empt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif "
488  "%7.2f +- %7.2f\n",
489  ic,
490  calo.floatPt(),
491  calo.floatPtErr(),
492  calo.floatEmPt(),
493  calo2ntk[ic],
494  calo2sumtkpt[ic],
495  calo2sumtkpterr[ic],
496  ptdiff,
497  pterr);
498  if (ptdiff > +ptMatchHigh_ * pterr) {
499  if (ecalPriority_) {
500  if (calo.floatEmPt() > 1) {
501  float emptdiff = std::min(ptdiff, calo.floatEmPt());
502  if (debug_)
503  dbgPrintf(
504  "PFAlgo2HGC \t calo %3d (pt %7.2f, empt %7.2f) ---> make photon with pt %7.2f, reduce ptdiff to "
505  "%7.2f +- %7.2f\n",
506  ic,
507  calo.floatPt(),
508  calo.floatEmPt(),
509  emptdiff,
510  ptdiff - emptdiff,
511  pterr);
512  auto &p = addCaloToPF(r, calo);
513  p.setFloatPt(emptdiff);
515  ptdiff -= emptdiff;
516  }
517  if (ptdiff > 2) {
518  if (debug_)
519  dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f, empt %7.2f) ---> make also neutral hadron with pt %7.2f\n",
520  ic,
521  calo.floatPt(),
522  calo.floatEmPt(),
523  ptdiff);
524  auto &p = addCaloToPF(r, calo);
525  p.setFloatPt(ptdiff);
527  }
528  } else {
529  if (debug_)
530  dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> promoted to neutral with pt %7.2f\n",
531  ic,
532  calo.floatPt(),
533  ptdiff);
534  auto &p = addCaloToPF(r, calo);
535  p.setFloatPt(ptdiff);
536  calo.hwFlags = 0;
537  }
538  } else if (ptdiff > -ptMatchLow_ * pterr) {
539  // nothing to do (weighted average happens when we process the tracks)
540  calo.hwFlags = 1;
541  if (debug_)
542  dbgPrintf(
543  "PFAlgo2HGC \t calo %3d (pt %7.2f) ---> to be deleted, will use tracks instead\n", ic, calo.floatPt());
544  } else {
545  // tracks overshoot, rescale to tracks to calo
546  calo2alpha[ic] = rescaleTracks_ ? calo.floatPt() / calo2sumtkpt[ic] : 1.0;
547  calo.hwFlags = 2;
548  if (debug_ && rescaleTracks_)
549  dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> tracks overshoot and will be scaled down by %.4f\n",
550  ic,
551  calo.floatPt(),
552  calo2alpha[ic]);
553  if (debug_ && !rescaleTracks_)
554  dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> tracks overshoot by %.4f\n",
555  ic,
556  calo.floatPt(),
557  calo2sumtkpt[ic] / calo.floatPt());
558  }
559  calo.used = true;
560  }
561 }
562 
564  const std::vector<int> &tk2calo,
565  const std::vector<int> &calo2ntk,
566  const std::vector<float> &calo2alpha) const {
567  // process matched tracks, if necessary rescale or average
568  for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) {
569  auto &tk = r.track[itk];
570  if (tk2calo[itk] == -1 || tk.muonLink || tk.used)
571  continue;
572  auto &p = addTrackToPF(r, tk);
573  tk.used = true;
574  const auto &calo = r.calo[tk2calo[itk]];
575  if (calo.isEM)
577  p.cluster.src = calo.src;
578  if (calo.hwFlags == 1) {
579  // can do weighted average if there's just one track
580  if (calo2ntk[tk2calo[itk]] == 1 && caloTrkWeightedAverage_) {
581  p.hwStatus = GoodTK_Calo_TkPt;
582  float ptavg = tk.floatPt();
583  if (tk.floatPtErr() > 0) {
584  float wcalo = 1.0 / std::pow(tk.floatCaloPtErr(), 2);
585  float wtk = 1.0 / std::pow(tk.floatPtErr(), 2);
586  ptavg = (calo.floatPt() * wcalo + tk.floatPt() * wtk) / (wcalo + wtk);
587  p.hwStatus = GoodTK_Calo_TkCaloPt;
588  }
589  p.setFloatPt(ptavg);
590  if (debug_)
591  dbgPrintf(
592  "PFAlgo2HGC \t track %3d (pt %7.2f +- %7.2f) combined with calo %3d (pt %7.2f +- %7.2f (from tk) "
593  "yielding candidate of pt %7.2f\n",
594  itk,
595  tk.floatPt(),
596  tk.floatPtErr(),
597  tk2calo[itk],
598  calo.floatPt(),
599  tk.floatCaloPtErr(),
600  ptavg);
601  } else {
602  p.hwStatus = GoodTK_Calo_TkPt;
603  if (debug_)
604  dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) linked to calo %3d promoted to %s\n",
605  itk,
606  tk.floatPt(),
607  tk2calo[itk],
608  (p.hwId == l1t::PFCandidate::Electron ? "electron" : "charged hadron"));
609  }
610  } else if (calo.hwFlags == 2) {
611  // must rescale
612  p.setFloatPt(tk.floatPt() * calo2alpha[tk2calo[itk]]);
613  p.hwStatus = GoodTk_Calo_CaloPt;
614  if (debug_)
615  dbgPrintf(
616  "PFAlgo2HGC \t track %3d (pt %7.2f, stubs %2d chi2 %7.1f) linked to calo %3d promoted to %s with pt %7.2f "
617  "after maybe rescaling\n",
618  itk,
619  tk.floatPt(),
620  int(tk.hwStubs),
621  tk.hwChi2 * 0.1f,
622  tk2calo[itk],
623  (p.hwId == l1t::PFCandidate::Electron ? "electron" : "charged hadron"),
624  p.floatPt());
625  }
626  }
627 }
628 
630  // process unmatched calo clusters
631  for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) {
632  if (!r.calo[ic].used) {
633  addCaloToPF(r, r.calo[ic]);
634  if (debug_)
635  dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) not linked, promoted to neutral\n", ic, r.calo[ic].floatPt());
636  }
637  }
638 }
639 
640 void PFAlgo2HGC::save_muons(Region &r, const std::vector<int> &tk2mu) const {
641  // finally do muons
642  for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) {
643  if (r.track[itk].muonLink) {
644  auto &p = addTrackToPF(r, r.track[itk]);
645  p.muonsrc = r.muon[tk2mu[itk]].src;
646  if (debug_)
647  dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) promoted to muon.\n", itk, r.track[itk].floatPt());
648  }
649  }
650 }
void unlinkedtk_algo(Region &r, const std::vector< int > &tk2calo) const
promote unlinked low pt tracks to hadrons
Definition: PFAlgo2HGC.cc:385
constexpr int32_t ceil(float num)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
TkCaloLinkMetric tkCaloLinkMetric_
Definition: PFAlgo2HGC.h:18
unsigned int tightTrackMinStubs_
Definition: PFAlgo2HGC.h:22
float tightTrackMaxInvisiblePt_
Definition: PFAlgo2HGC.h:23
void initRegion(Region &r) const
Definition: PFAlgoBase.cc:11
PFParticle & addTrackToPF(Region &r, const PropagatedTrack &tk) const
Definition: PFAlgoBase.h:20
void save_muons(Region &r, const std::vector< int > &tk2mu) const
save muons in output list
Definition: PFAlgo2HGC.cc:640
void unlinkedcalo_algo(Region &r) const
process unmatched calo clusters
Definition: PFAlgo2HGC.cc:629
void linkedcalo_algo(Region &r, const std::vector< int > &calo2ntk, const std::vector< float > &calo2sumtkpt, const std::vector< float > &calo2sumtkpterr, std::vector< float > &calo2alpha) const
process matched calo clusters, compare energy to sum track pt, compute track rescaling factor if need...
Definition: PFAlgo2HGC.cc:472
void dbgPrintf(const char *formatString, Args &&...args)
Definition: dbgPrintf.h:5
T getUntrackedParameter(std::string const &, T const &) const
void sum_tk2calo(Region &r, const std::vector< int > &tk2calo, std::vector< int > &calo2ntk, std::vector< float > &calo2sumtkpt, std::vector< float > &calo2sumtkpterr) const
for each calo, compute the sum of the track pt
Definition: PFAlgo2HGC.cc:360
T sqrt(T t)
Definition: SSEVec.h:19
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void linkedtk_algo(Region &r, const std::vector< int > &tk2calo, const std::vector< int > &calo2ntk, const std::vector< float > &calo2alpha) const
process matched tracks, if necessary rescale or average
Definition: PFAlgo2HGC.cc:563
#define M_PI
void link_tk2mu(Region &r, std::vector< int > &tk2mu, std::vector< int > &mu2tk) const
do muon track linking (also sets track.muonLink)
Definition: PFAlgo2HGC.cc:167
void link_tk2calo(Region &r, std::vector< int > &tk2calo) const
track to calo matching
Definition: PFAlgo2HGC.cc:257
void calo_relink(Region &r, const std::vector< int > &calo2ntk, const std::vector< float > &calo2sumtkpt, const std::vector< float > &calo2sumtkpterr) const
try to recover split hadron showers (v1.0):
Definition: PFAlgo2HGC.cc:408
enum l1tpf_impl::PFAlgo2HGC::MuMatchMode muMatchMode_
PFAlgo2HGC(const edm::ParameterSet &)
Definition: PFAlgo2HGC.cc:19
void runPF(Region &r) const override
Definition: PFAlgo2HGC.cc:62
PFParticle & addCaloToPF(Region &r, const CaloCluster &calo) const
Definition: PFAlgoBase.h:21
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
Definition: Common.h:9