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());
17 using namespace l1tpf_impl;
25 if (muMatchMode ==
"boxBestByPtRatio")
27 else if (muMatchMode ==
"drBestByPtRatio")
29 else if (muMatchMode ==
"drBestByPtDiff")
32 throw cms::Exception(
"Configuration",
"bad value for trackMuMatch configurable");
35 if (tkCaloLinkMetric ==
"bestByDR")
37 else if (tkCaloLinkMetric ==
"bestByDRPt")
39 else if (tkCaloLinkMetric ==
"bestByDR2Pt2")
42 throw cms::Exception(
"Configuration",
"bad value for tkCaloLinkMetric configurable");
76 "PFAlgo3\nPFAlgo3 region eta [ %+5.2f , %+5.2f ], phi [ %+5.2f , %+5.2f ], fiducial eta [ %+5.2f , %+5.2f ], "
77 "phi [ %+5.2f , %+5.2f ]\n",
86 dbgPrintf(
"PFAlgo3 \t N(track) %3lu N(em) %3lu N(calo) %3lu N(mu) %3lu\n",
91 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
92 const auto &tk = r.
track[itk];
94 "PFAlgo3 \t track %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f "
95 "fid %1d calo ptErr %7.2f stubs %2d chi2 %7.1f\n",
108 for (
int iem = 0, nem = r.
emcalo.size(); iem < nem; ++iem) {
109 const auto &em = r.
emcalo[iem];
111 "PFAlgo3 \t EM %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f "
112 "fid %1d calo ptErr %7.2f\n",
123 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
124 auto &calo = r.
calo[ic];
126 "PFAlgo3 \t calo %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f "
127 "fid %1d calo ptErr %7.2f em pt %7.2f \n",
139 for (
int im = 0, nm = r.
muon.size(); im < nm; ++im) {
142 "PFAlgo3 \t muon %3d: pt %7.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f "
154 std::vector<int> tk2mu(r.
track.size(), -1), mu2tk(r.
muon.size(), -1);
158 std::vector<int> tk2em(r.
track.size(), -1);
162 std::vector<int> em2calo(r.
emcalo.size(), -1);
167 std::vector<int> em2ntk(r.
emcalo.size(), 0);
168 std::vector<float> em2sumtkpt(r.
emcalo.size(), 0);
169 std::vector<float> em2sumtkpterr(r.
emcalo.size(), 0);
170 sum_tk2em(r, tk2em, em2ntk, em2sumtkpt, em2sumtkpterr);
178 emtk_algo(r, tk2em, em2ntk, em2sumtkpterr);
183 std::vector<int> tk2calo(r.
track.size(), -1);
188 std::vector<int> calo2ntk(r.
calo.size(), 0);
189 std::vector<float> calo2sumtkpt(r.
calo.size(), 0);
190 std::vector<float> calo2sumtkpterr(r.
calo.size(), 0);
191 sum_tk2calo(r, tk2calo, calo2ntk, calo2sumtkpt, calo2sumtkpterr);
200 calo_relink(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr);
204 std::vector<float> calo2alpha(r.
calo.size(), 1);
205 linkedcalo_algo(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr, calo2alpha);
219 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
222 for (
int imu = 0, nmu = r.
muon.size(); imu < nmu; ++imu) {
223 const auto &
mu = r.
muon[imu];
226 "PFAlgo3 \t muon %3d (pt %7.2f, eta %+5.2f, phi %+5.2f) \n", imu,
mu.floatPt(),
mu.floatEta(),
mu.floatPhi());
227 float minDistance = 9e9;
236 minDistance = 0.5 *
mu.floatPt();
240 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
241 const auto &tk = r.
track[itk];
243 int dphi =
std::abs((
mu.hwPhi - tk.hwPhi) % CaloCluster::PHI_WRAP);
244 float dr = floatDR(
mu, tk);
245 float dpt =
std::abs(
mu.floatPt() - tk.floatPt());
246 float dptr = (
mu.hwPt > tk.hwPt ?
mu.floatPt() / tk.floatPt() : tk.floatPt() /
mu.floatPt());
251 ok = (deta < intDrMuonMatchBox) && (dphi < intDrMuonMatchBox);
265 "PFAlgo3 \t\t possible match with track %3d (pt %7.2f, caloeta %+5.2f, calophi %+5.2f, dr %.2f, eta "
266 "%+5.2f, phi %+5.2f, dr %.2f): angular %1d, distance %.3f (vs %.3f)\n",
274 deltaR(
mu.floatEta(),
mu.floatPhi(), tk.floatVtxEta(), tk.floatVtxPhi()),
282 if (distance < minDistance) {
287 if (
debug_ && imatch > -1)
288 dbgPrintf(
"PFAlgo3 \t muon %3d (pt %7.2f) linked to track %3d (pt %7.2f)\n",
292 r.
track[imatch].floatPt());
293 if (
debug_ && imatch == -1)
294 dbgPrintf(
"PFAlgo3 \t muon %3d (pt %7.2f) not linked to any track\n", imu,
mu.floatPt());
298 r.
track[imatch].muonLink =
true;
305 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
306 const auto &tk = r.
track[itk];
309 for (
int iem = 0, nem = r.
emcalo.size(); iem < nem; ++iem) {
310 const auto &em = r.
emcalo[iem];
311 float dr = floatDR(tk, em);
317 if (
debug_ && tk2em[itk] != -1)
318 dbgPrintf(
"PFAlgo3 \t track %3d (pt %7.2f) matches to EM %3d (pt %7.2f) with dr %.3f\n",
322 tk2em[itk] == -1 ? 0.0 : r.
emcalo[tk2em[itk]].floatPt(),
329 for (
int iem = 0, nem = r.
emcalo.size(); iem < nem; ++iem) {
330 const auto &em = r.
emcalo[iem];
332 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
333 const auto &calo = r.
calo[ic];
336 float dr = floatDR(calo, em);
342 if (
debug_ && em2calo[iem] != -1)
343 dbgPrintf(
"PFAlgo3 \t EM %3d (pt %7.2f) matches to calo %3d (pt %7.2f, empt %7.2f) with dr %.3f\n",
347 em2calo[iem] == -1 ? 0.0 : r.
calo[em2calo[iem]].floatPt(),
348 em2calo[iem] == -1 ? 0.0 : r.
calo[em2calo[iem]].floatEmPt(),
354 const std::vector<int> &tk2em,
355 std::vector<int> &em2ntk,
356 std::vector<float> &em2sumtkpt,
357 std::vector<float> &em2sumtkpterr)
const {
359 for (
int iem = 0, nem = r.
emcalo.size(); iem < nem; ++iem) {
360 const auto &em = r.
emcalo[iem];
363 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
364 if (tk2em[itk] == iem) {
365 const auto &tk = r.
track[itk];
369 em2sumtkpt[iem] += tk.floatPt();
370 em2sumtkpterr[iem] += tk.floatPtErr();
377 const std::vector<int> &em2ntk,
378 const std::vector<float> &em2sumtkpt,
379 const std::vector<float> &em2sumtkpterr)
const {
381 for (
int iem = 0, nem = r.
emcalo.size(); iem < nem; ++iem) {
389 dbgPrintf(
"PFAlgo3 \t EM %3d (pt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif %7.2f +- %7.2f\n",
395 em.floatPt() - em2sumtkpt[iem],
396 std::max<float>(em2sumtkpterr[iem], em.floatPtErr()));
397 if (em2ntk[iem] == 0) {
402 dbgPrintf(
"PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to photon\n", iem, em.floatPt());
405 float ptdiff = em.floatPt() - em2sumtkpt[iem];
408 if (pterr > 2 * em.floatPt()) {
409 pterr = 2 * em.floatPt();
411 dbgPrintf(
"PFAlgo3 \t EM %3d (pt %7.2f) ---> clamp pterr ---> new ptdiff %7.2f +- %7.2f\n",
424 p.setFloatPt(ptdiff);
426 dbgPrintf(
"PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to electron(s) + photon (pt %7.2f)\n",
433 dbgPrintf(
"PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to electron(s)\n", iem, em.floatPt());
445 const std::vector<int> &tk2em,
446 const std::vector<int> &em2ntk,
447 const std::vector<float> &em2sumtkpterr)
const {
449 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
450 auto &tk = r.
track[itk];
451 if (tk2em[itk] == -1 || tk.muonLink)
453 const auto &em = r.
emcalo[tk2em[itk]];
456 p.cluster.src = em.src;
459 if (em.floatPtErr() < em2sumtkpterr[tk2em[itk]]) {
460 p.setFloatPt(em.floatPt());
464 dbgPrintf(
"PFAlgo3 \t track %3d (pt %7.2f) matched to EM %3d (pt %7.2f) promoted to electron with pt %7.2f\n",
480 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
481 auto &calo = r.
calo[ic];
482 float pt0 = calo.floatPt(), ept0 = calo.floatEmPt(),
pt = pt0, ept = ept0;
484 for (
int iem = 0, nem = r.
emcalo.size(); iem < nem; ++iem) {
485 if (em2calo[iem] == ic) {
486 const auto &em = r.
emcalo[iem];
490 "PFAlgo3 \t EM %3d (pt %7.2f) is subtracted from calo %3d (pt %7.2f) scaled by %.3f (deltaPt = "
504 "PFAlgo3 \t EM %3d (pt %7.2f) not subtracted from calo %3d (pt %7.2f), and calo marked to be kept "
505 "after EM subtraction\n",
516 "PFAlgo3 \t calo %3d (pt %7.2f +- %7.2f) has a subtracted pt of %7.2f, empt %7.2f -> %7.2f, isem %d\n",
525 calo.setFloatEmPt(ept);
528 (calo.isEM && ept <= 0.125 * ept0))) {
530 dbgPrintf(
"PFAlgo3 \t calo %3d (pt %7.2f) ----> discarded\n", ic, calo.floatPt());
532 calo.setFloatPt(pt0);
540 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
541 const auto &tk = r.
track[itk];
542 if (tk.muonLink || tk.used)
544 float drbest =
drMatch_, dptscale = 0;
551 dptscale =
drMatch_ / tk.floatCaloPtErr();
555 dptscale =
drMatch_ / tk.floatCaloPtErr();
558 float minCaloPt = tk.floatPt() -
ptMatchLow_ * tk.floatCaloPtErr();
560 dbgPrintf(
"PFAlgo3 \t track %3d (pt %7.2f) to be matched to calo, min pT %7.2f\n", itk, tk.floatPt(), minCaloPt);
561 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
562 auto &calo = r.
calo[ic];
563 if (calo.used || calo.floatPt() <= minCaloPt)
565 float dr = floatDR(tk, calo), dq;
574 dq = dr + std::max<float>(tk.floatPt() - calo.floatPt(), 0.) * dptscale;
582 dq = hypot(dr, std::max<float>(tk.floatPt() - calo.floatPt(), 0.) * dptscale);
591 if (
debug_ && tk2calo[itk] != -1)
592 dbgPrintf(
"PFAlgo3 \t track %3d (pt %7.2f) matches to calo %3d (pt %7.2f) with dist %.3f\n",
596 tk2calo[itk] == -1 ? 0.0 : r.
calo[tk2calo[itk]].floatPt(),
599 if (
debug_ && tk2calo[itk] == -1) {
602 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
603 auto &calo = r.
calo[ic];
606 float dr = floatDR(tk, calo);
614 "PFAlgo3 \t track %3d (pt %7.2f) would match to calo %3d (pt %7.2f) with dr %.3f if the pt min and dr "
615 "requirement had been relaxed\n",
619 r.
calo[ibest].floatPt(),
626 const std::vector<int> &tk2calo,
627 std::vector<int> &calo2ntk,
628 std::vector<float> &calo2sumtkpt,
629 std::vector<float> &calo2sumtkpterr)
const {
631 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
632 const auto &calo = r.
calo[ic];
635 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
636 if (tk2calo[itk] == ic) {
637 const auto &tk = r.
track[itk];
638 if (tk.muonLink || tk.used)
641 calo2sumtkpt[ic] += tk.floatPt();
646 calo2sumtkpterr[ic] =
std::sqrt(calo2sumtkpterr[ic]);
652 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
653 auto &tk = r.
track[itk];
654 if (tk2calo[itk] != -1 || tk.muonLink || tk.used)
658 if (tk.floatPt() < maxPt) {
660 dbgPrintf(
"PFAlgo3 \t track %3d (pt %7.2f) not matched to calo, kept as charged hadron\n", itk, tk.floatPt());
666 dbgPrintf(
"PFAlgo3 \t track %3d (pt %7.2f) not matched to calo, dropped\n", itk, tk.floatPt());
673 const std::vector<int> &calo2ntk,
674 const std::vector<float> &calo2sumtkpt,
675 const std::vector<float> &calo2sumtkpterr)
const {
680 std::vector<float> addtopt(r.
calo.size(), 0);
681 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
682 auto &calo = r.
calo[ic];
683 if (calo2ntk[ic] != 0 || calo.used || r.
globalAbsEta(calo.floatEta()) > 2.5)
687 for (
int ic2 = 0; ic2 < nc; ++ic2) {
688 const auto &calo2 = r.
calo[ic2];
689 if (calo2ntk[ic2] == 0 || calo2.used || r.
globalAbsEta(calo2.floatEta()) > 2.5)
691 float dr = floatDR(calo, calo2);
696 calo2sumtkpt[ic2] - calo2.floatPt() + (
useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr());
704 const auto &calo2 = r.
calo[i2best];
707 "PFAlgo3 \t calo %3d (pt %7.2f) with no tracks matched within dr %.3f with calo %3d with pt %7.2f (sum tk "
708 "pt %7.2f), track excess %7.2f +- %7.2f\n",
714 calo2sumtkpt[i2best],
715 calo2sumtkpt[i2best] - calo2.floatPt(),
718 addtopt[i2best] += calo.floatPt();
722 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
724 auto &calo = r.
calo[ic];
726 dbgPrintf(
"PFAlgo3 \t calo %3d (pt %7.2f, sum tk pt %7.2f) is increased to pt %7.2f after merging\n",
730 calo.floatPt() + addtopt[ic]);
731 calo.setFloatPt(calo.floatPt() + addtopt[ic]);
737 const std::vector<int> &calo2ntk,
738 const std::vector<float> &calo2sumtkpt,
739 const std::vector<float> &calo2sumtkpterr,
740 std::vector<float> &calo2alpha)
const {
743 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
744 auto &calo = r.
calo[ic];
745 if (calo2ntk[ic] == 0 || calo.used)
747 float ptdiff = calo.floatPt() - calo2sumtkpt[ic];
751 "PFAlgo3 \t calo %3d (pt %7.2f +- %7.2f, empt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif "
764 if (calo.floatEmPt() > 1) {
765 float emptdiff =
std::min(ptdiff, calo.floatEmPt());
768 "PFAlgo3 \t calo %3d (pt %7.2f, empt %7.2f) ---> make photon with pt %7.2f, reduce ptdiff to %7.2f "
777 p.setFloatPt(emptdiff);
783 dbgPrintf(
"PFAlgo3 \t calo %3d (pt %7.2f, empt %7.2f) ---> make also neutral hadron with pt %7.2f\n",
789 p.setFloatPt(ptdiff);
794 dbgPrintf(
"PFAlgo3 \t calo %3d (pt %7.2f) ---> promoted to neutral with pt %7.2f\n",
799 p.setFloatPt(ptdiff);
807 "PFAlgo3 \t calo %3d (pt %7.2f) ---> to be deleted, will use tracks instead\n", ic, calo.floatPt());
811 calo2alpha[ic] =
rescaleTracks_ ? calo.floatPt() / calo2sumtkpt[ic] : 1.0;
814 dbgPrintf(
"PFAlgo3 \t calo %3d (pt %7.2f) ---> tracks overshoot and will be scaled down by %.4f\n",
819 dbgPrintf(
"PFAlgo3 \t calo %3d (pt %7.2f) ---> tracks overshoot by %.4f\n",
822 calo2sumtkpt[ic] / calo.floatPt());
829 const std::vector<int> &tk2calo,
830 const std::vector<int> &calo2ntk,
831 const std::vector<float> &calo2alpha)
const {
833 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
834 auto &tk = r.
track[itk];
835 if (tk2calo[itk] == -1 || tk.muonLink || tk.used)
839 const auto &calo = r.
calo[tk2calo[itk]];
840 p.cluster.src = calo.src;
841 if (calo.hwFlags == 1) {
845 float ptavg = tk.floatPt();
846 if (tk.floatPtErr() > 0) {
847 float wcalo = 1.0 /
std::pow(tk.floatCaloPtErr(), 2);
848 float wtk = 1.0 /
std::pow(tk.floatPtErr(), 2);
849 ptavg = (calo.floatPt() * wcalo + tk.floatPt() * wtk) / (wcalo + wtk);
855 "PFAlgo3 \t track %3d (pt %7.2f +- %7.2f) combined with calo %3d (pt %7.2f +- %7.2f (from tk) yielding "
856 "candidate of pt %7.2f\n",
867 dbgPrintf(
"PFAlgo3 \t track %3d (pt %7.2f) linked to calo %3d promoted to charged hadron\n",
872 }
else if (calo.hwFlags == 2) {
874 p.setFloatPt(tk.floatPt() * calo2alpha[tk2calo[itk]]);
878 "PFAlgo3 \t track %3d (pt %7.2f, stubs %2d chi2 %7.1f) linked to calo %3d promoted to charged hadron with "
879 "pt %7.2f after maybe rescaling\n",
892 for (
int ic = 0, nc = r.
calo.size(); ic < nc; ++ic) {
893 if (!r.
calo[ic].used) {
896 dbgPrintf(
"PFAlgo3 \t calo %3d (pt %7.2f) not linked, promoted to neutral\n", ic, r.
calo[ic].floatPt());
903 for (
int itk = 0, ntk = r.
track.size(); itk < ntk; ++itk) {
904 if (r.
track[itk].muonLink) {
906 p.muonsrc = r.
muon[tk2mu[itk]].src;
908 dbgPrintf(
"PFAlgo3 \t track %3d (pt %7.2f) promoted to muon.\n", itk, r.
track[itk].floatPt());
constexpr int32_t ceil(float num)
T getUntrackedParameter(std::string const &, T const &) const
float caloReLinkThreshold_
bool trackEmMayUseCaloMomenta_
PFAlgo3(const edm::ParameterSet &)
void link_tk2calo(Region &r, std::vector< int > &tk2calo) const
track to calo matching
void runPF(Region &r) const override
void link_tk2em(Region &r, std::vector< int > &tk2em) const
match all tracks to the closest EM cluster
void link_em2calo(Region &r, std::vector< int > &em2calo) const
match all em to the closest had (can happen in parallel to the above)
float globalAbsEta(float localEta) const
void sub_em2calo(Region &r, const std::vector< int > &em2calo) const
subtract EM component from Calo clusters for all photons and electrons (within tracker coverage) ...
void dbgPrintf(const char *formatString, Args &&...args)
void unlinkedtk_algo(Region &r, const std::vector< int > &tk2calo) const
promote unlinked low pt tracks to hadrons
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
bool emCaloUseAlsoCaloSigma_
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
PFParticle & addCaloToPF(Region &r, const CaloCluster &calo) const
float emHadSubtractionPtSlope_
void emtk_algo(Region &r, const std::vector< int > &tk2em, const std::vector< int > &em2ntk, const std::vector< float > &em2sumtkpterr) const
promote all flagged tracks to electrons
Abs< T >::type abs(const T &t)
float tightTrackMaxInvisiblePt_
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):
void initRegion(Region &r) const
bool trackEmUseAlsoTrackSigma_
enum l1tpf_impl::PFAlgo3::MuMatchMode muMatchMode_
T getParameter(std::string const &) const
void sum_tk2em(Region &r, const std::vector< int > &tk2em, std::vector< int > &em2ntk, std::vector< float > &em2sumtkpt, std::vector< float > &em2sumtkpterr) const
for each EM cluster, count and add up the pt of all the corresponding tracks (skipping muons) ...
unsigned int tightTrackMinStubs_
void unlinkedcalo_algo(Region &r) const
process unmatched calo clusters
TkCaloLinkMetric tkCaloLinkMetric_
bool caloTrkWeightedAverage_
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...
void emcalo_algo(Region &r, const std::vector< int > &em2ntk, const std::vector< float > &em2sumtkpt, const std::vector< float > &em2sumtkpterr) const
process ecal clusters after linking
bool fiducialLocal(float localEta, float localPhi) const
Power< A, B >::type pow(const A &a, const B &b)
void save_muons(Region &r, const std::vector< int > &tk2mu) const
save muons in output list
PFParticle & addTrackToPF(Region &r, const PropagatedTrack &tk) const
void link_tk2mu(Region &r, std::vector< int > &tk2mu, std::vector< int > &mu2tk) const
do muon track linking (also sets track.muonLink)