File indexing completed on 2024-04-06 12:21:32
0001 #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h"
0002 #include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h"
0003
0004 #include <cmath>
0005 #include <cstdio>
0006 #include <algorithm>
0007 #include <vector>
0008 #include <memory>
0009
0010 #ifdef CMSSW_GIT_HASH
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0013
0014 l1ct::PFAlgo3Emulator::PFAlgo3Emulator(const edm::ParameterSet& iConfig)
0015 : PFAlgoEmulatorBase(iConfig.getParameter<uint32_t>("nTrack"),
0016 iConfig.getParameter<uint32_t>("nCalo"),
0017 iConfig.getParameter<uint32_t>("nMu"),
0018 iConfig.getParameter<uint32_t>("nSelCalo"),
0019 l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter<double>("trackMuDR")),
0020 l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter<double>("trackCaloDR")),
0021 l1ct::Scales::makePtFromFloat(iConfig.getParameter<double>("maxInvisiblePt")),
0022 l1ct::Scales::makePtFromFloat(iConfig.getParameter<double>("tightTrackMaxInvisiblePt"))),
0023 nEMCALO_(iConfig.getParameter<uint32_t>("nEmCalo")),
0024 nPHOTON_(iConfig.getParameter<uint32_t>("nPhoton")),
0025 nALLNEUTRAL_(iConfig.getParameter<uint32_t>("nAllNeutral")),
0026 dR2MAX_TK_EM_(l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter<double>("trackEmDR"))),
0027 dR2MAX_EM_CALO_(l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter<double>("emCaloDR"))) {
0028 debug_ = iConfig.getUntrackedParameter<bool>("debug", false);
0029 loadPtErrBins(iConfig);
0030 }
0031
0032 edm::ParameterSetDescription l1ct::PFAlgo3Emulator::getParameterSetDescription() {
0033 edm::ParameterSetDescription description;
0034 description.add<unsigned int>("nTrack", 25);
0035 description.add<unsigned int>("nCalo", 18);
0036 description.add<unsigned int>("nMu", 2);
0037 description.add<unsigned int>("nSelCalo", 18);
0038 description.add<unsigned int>("nEmCalo", 12);
0039 description.add<unsigned int>("nPhoton", 12);
0040 description.add<unsigned int>("nAllNeutral", 25);
0041 description.add<double>("trackMuDR", 0.2);
0042 description.add<double>("trackEmDR", 0.04);
0043 description.add<double>("emCaloDR", 0.1);
0044 description.add<double>("trackCaloDR", 0.15);
0045 description.add<double>("maxInvisiblePt", 10.0);
0046 description.add<double>("tightTrackMaxInvisiblePt", 20);
0047 addCaloResolutionParameterSetDescription(description);
0048 description.addUntracked<bool>("debug", false);
0049 return description;
0050 }
0051
0052 #endif
0053
0054 void l1ct::PFAlgo3Emulator::toFirmware(const PFInputRegion& in,
0055 PFRegion& region,
0056 HadCaloObj calo[],
0057 EmCaloObj emcalo[],
0058 TkObj track[],
0059 MuObj mu[]) const {
0060 region = in.region;
0061 l1ct::toFirmware(in.track, nTRACK_, track);
0062 l1ct::toFirmware(in.emcalo, nEMCALO_, emcalo);
0063 l1ct::toFirmware(in.hadcalo, nCALO_, calo);
0064 l1ct::toFirmware(in.muon, nMU_, mu);
0065 }
0066
0067 void l1ct::PFAlgo3Emulator::toFirmware(const OutputRegion& out,
0068 PFChargedObj outch[],
0069 PFNeutralObj outpho[],
0070 PFNeutralObj outne[],
0071 PFChargedObj outmu[]) const {
0072 l1ct::toFirmware(out.pfcharged, nTRACK_, outch);
0073 l1ct::toFirmware(out.pfphoton, nPHOTON_, outpho);
0074 l1ct::toFirmware(out.pfneutral, nSELCALO_, outne);
0075 l1ct::toFirmware(out.pfmuon, nMU_, outmu);
0076 }
0077
0078 int l1ct::PFAlgo3Emulator::tk_best_match_ref(unsigned int dR2MAX,
0079 const std::vector<l1ct::EmCaloObjEmu>& calo,
0080 const l1ct::TkObjEmu& track) const {
0081 int drmin = dR2MAX, ibest = -1;
0082 for (unsigned int ic = 0, nCAL = std::min<unsigned>(nEMCALO_, calo.size()); ic < nCAL; ++ic) {
0083 if (calo[ic].hwPt <= 0)
0084 continue;
0085 int dr = dr2_int(track.hwEta, track.hwPhi, calo[ic].hwEta, calo[ic].hwPhi);
0086 if (dr < drmin) {
0087 drmin = dr;
0088 ibest = ic;
0089 }
0090 }
0091 return ibest;
0092 }
0093 int l1ct::PFAlgo3Emulator::em_best_match_ref(unsigned int dR2MAX,
0094 const std::vector<l1ct::HadCaloObjEmu>& calo,
0095 const l1ct::EmCaloObjEmu& em) const {
0096 pt_t emPtMin = em.hwPt >> 1;
0097 int drmin = dR2MAX, ibest = -1;
0098 for (unsigned int ic = 0, nCAL = calo.size(); ic < nCAL; ++ic) {
0099 if (calo[ic].hwEmPt <= emPtMin)
0100 continue;
0101 int dr = dr2_int(em.hwEta, em.hwPhi, calo[ic].hwEta, calo[ic].hwPhi);
0102 if (dr < drmin) {
0103 drmin = dr;
0104 ibest = ic;
0105 }
0106 }
0107 return ibest;
0108 }
0109
0110 void l1ct::PFAlgo3Emulator::pfalgo3_em_ref(const PFInputRegion& in,
0111 const std::vector<int>& iMu ,
0112 std::vector<int>& iEle ,
0113 OutputRegion& out,
0114 std::vector<HadCaloObjEmu>& hadcalo_out ) const {
0115
0116 unsigned int nTRACK = std::min<unsigned>(nTRACK_, in.track.size());
0117 unsigned int nEMCALO = std::min<unsigned>(nEMCALO_, in.emcalo.size());
0118 unsigned int nPHOTON = std::min<unsigned>(nPHOTON_, in.emcalo.size());
0119 unsigned int nCALO = std::min<unsigned>(nCALO_, in.hadcalo.size());
0120
0121
0122 std::vector<pt_t> calo_sumtk(nEMCALO);
0123 for (unsigned int ic = 0; ic < nEMCALO; ++ic) {
0124 calo_sumtk[ic] = 0;
0125 }
0126 std::vector<int> tk2em(nTRACK);
0127 std::vector<bool> isEM(nEMCALO);
0128
0129 for (unsigned int it = 0; it < nTRACK; ++it) {
0130 if (in.track[it].hwPt > 0 && in.track[it].isPFLoose() && iMu[it] == -1) {
0131 tk2em[it] = tk_best_match_ref(dR2MAX_TK_EM_, in.emcalo, in.track[it]);
0132 if (tk2em[it] != -1) {
0133 if (debug_)
0134 dbgPrintf(
0135 "FW \t track %3d pt %8.2f matched to em calo %3d pt %8.2f (int deltaR2 %d)\n",
0136 it,
0137 in.track[it].floatPt(),
0138 tk2em[it],
0139 in.emcalo[tk2em[it]].floatPt(),
0140 dr2_int(in.track[it].hwEta, in.track[it].hwPhi, in.emcalo[tk2em[it]].hwEta, in.emcalo[tk2em[it]].hwPhi));
0141 calo_sumtk[tk2em[it]] += in.track[it].hwPt;
0142 }
0143 } else {
0144 tk2em[it] = -1;
0145 }
0146 }
0147
0148 if (debug_) {
0149 for (unsigned int ic = 0; ic < nEMCALO; ++ic) {
0150 if (in.emcalo[ic].hwPt > 0)
0151 dbgPrintf("FW \t emcalo %3d pt %8.2f has sumtk %8.2f\n",
0152 ic,
0153 in.emcalo[ic].floatPt(),
0154 Scales::floatPt(calo_sumtk[ic]));
0155 }
0156 }
0157
0158 assert(nEMCALO == nPHOTON);
0159 out.pfphoton.resize(nPHOTON);
0160 for (unsigned int ic = 0; ic < nEMCALO; ++ic) {
0161 pt_t photonPt;
0162 if (calo_sumtk[ic] > 0) {
0163 dpt_t ptdiff = dpt_t(in.emcalo[ic].hwPt) - dpt_t(calo_sumtk[ic]);
0164 pt2_t sigma2 = in.emcalo[ic].hwPtErr * in.emcalo[ic].hwPtErr;
0165 pt2_t sigma2Lo = 4 * sigma2;
0166 const pt2_t& sigma2Hi = sigma2;
0167 pt2_t ptdiff2 = ptdiff * ptdiff;
0168 if ((ptdiff >= 0 && ptdiff2 <= sigma2Hi) || (ptdiff < 0 && ptdiff2 < sigma2Lo)) {
0169
0170 photonPt = 0;
0171 isEM[ic] = true;
0172 if (debug_)
0173 dbgPrintf("FW \t emcalo %3d pt %8.2f ptdiff %8.2f [match window: -%.2f / +%.2f] flagged as electron\n",
0174 ic,
0175 in.emcalo[ic].floatPt(),
0176 Scales::floatPt(ptdiff),
0177 std::sqrt(Scales::floatPt(sigma2Lo)),
0178 std::sqrt(float(sigma2Hi)));
0179 } else if (ptdiff > 0) {
0180
0181 photonPt = ptdiff;
0182 isEM[ic] = true;
0183 if (debug_)
0184 dbgPrintf(
0185 "FW \t emcalo %3d pt %8.2f ptdiff %8.2f [match window: -%.2f / +%.2f] flagged as electron + photon of "
0186 "pt %8.2f\n",
0187 ic,
0188 in.emcalo[ic].floatPt(),
0189 Scales::floatPt(ptdiff),
0190 std::sqrt(Scales::floatPt(sigma2Lo)),
0191 std::sqrt(float(sigma2Hi)),
0192 Scales::floatPt(photonPt));
0193 } else {
0194
0195 photonPt = 0;
0196 isEM[ic] = false;
0197 if (debug_)
0198 dbgPrintf("FW \t emcalo %3d pt %8.2f ptdiff %8.2f [match window: -%.2f / +%.2f] flagged as pion\n",
0199 ic,
0200 in.emcalo[ic].floatPt(),
0201 Scales::floatPt(ptdiff),
0202 std::sqrt(Scales::floatPt(sigma2Lo)),
0203 std::sqrt(Scales::floatPt(sigma2Hi)));
0204 }
0205 } else {
0206
0207 isEM[ic] = true;
0208 photonPt = in.emcalo[ic].hwPt;
0209 if (debug_ && in.emcalo[ic].hwPt > 0)
0210 dbgPrintf("FW \t emcalo %3d pt %8.2f flagged as photon\n", ic, in.emcalo[ic].floatPt());
0211 }
0212 if (photonPt) {
0213 fillPFCand(in.emcalo[ic], out.pfphoton[ic]);
0214 out.pfphoton[ic].hwPt = photonPt;
0215 out.pfphoton[ic].hwEmPt = photonPt;
0216 } else {
0217 out.pfphoton[ic].clear();
0218 }
0219 }
0220
0221 iEle.resize(nTRACK);
0222 for (unsigned int it = 0; it < nTRACK; ++it) {
0223 iEle[it] = ((tk2em[it] != -1) && isEM[tk2em[it]]) ? tk2em[it] : -1;
0224 if (debug_ && (iEle[it] != -1))
0225 dbgPrintf(
0226 "FW \t track %3d pt %8.2f flagged as electron (emcluster %d).\n", it, in.track[it].floatPt(), iEle[it]);
0227 }
0228
0229 std::vector<int> em2calo(nEMCALO);
0230 for (unsigned int ic = 0; ic < nEMCALO; ++ic) {
0231 em2calo[ic] = em_best_match_ref(dR2MAX_EM_CALO_, in.hadcalo, in.emcalo[ic]);
0232 if (debug_ && (in.emcalo[ic].hwPt > 0)) {
0233 dbgPrintf("FW \t emcalo %3d pt %8.2f isEM %d matched to hadcalo %3d pt %8.2f emPt %8.2f isEM %d\n",
0234 ic,
0235 in.emcalo[ic].floatPt(),
0236 int(isEM[ic]),
0237 em2calo[ic],
0238 (em2calo[ic] >= 0 ? in.hadcalo[em2calo[ic]].floatPt() : -1),
0239 (em2calo[ic] >= 0 ? in.hadcalo[em2calo[ic]].floatEmPt() : -1),
0240 (em2calo[ic] >= 0 ? int(in.hadcalo[em2calo[ic]].hwIsEM()) : 0));
0241 }
0242 }
0243
0244 hadcalo_out.resize(nCALO);
0245 for (unsigned int ih = 0; ih < nCALO; ++ih) {
0246 hadcalo_out[ih] = in.hadcalo[ih];
0247 dpt_t sub = 0;
0248 bool keep = false;
0249 for (unsigned int ic = 0; ic < nEMCALO; ++ic) {
0250 if (em2calo[ic] == int(ih)) {
0251 if (isEM[ic])
0252 sub += in.emcalo[ic].hwPt;
0253 else
0254 keep = true;
0255 }
0256 }
0257 dpt_t emdiff = dpt_t(in.hadcalo[ih].hwEmPt) - sub;
0258 dpt_t alldiff = dpt_t(in.hadcalo[ih].hwPt) - sub;
0259 if (debug_ && (in.hadcalo[ih].hwPt > 0)) {
0260 dbgPrintf("FW \t calo %3d pt %8.2f has a subtracted pt of %8.2f, empt %8.2f -> %8.2f isem %d mustkeep %d \n",
0261 ih,
0262 in.hadcalo[ih].floatPt(),
0263 Scales::floatPt(alldiff),
0264 in.hadcalo[ih].floatEmPt(),
0265 Scales::floatPt(emdiff),
0266 int(in.hadcalo[ih].hwIsEM()),
0267 keep);
0268 }
0269 if (alldiff <= (in.hadcalo[ih].hwPt >> 4)) {
0270 hadcalo_out[ih].hwPt = 0;
0271 hadcalo_out[ih].hwEmPt = 0;
0272 if (debug_ && (in.hadcalo[ih].hwPt > 0))
0273 dbgPrintf("FW \t calo %3d pt %8.2f --> discarded (zero pt)\n", ih, in.hadcalo[ih].floatPt());
0274 } else if ((in.hadcalo[ih].hwIsEM() && emdiff <= (in.hadcalo[ih].hwEmPt >> 3)) && !keep) {
0275 hadcalo_out[ih].hwPt = 0;
0276 hadcalo_out[ih].hwEmPt = 0;
0277 if (debug_ && (in.hadcalo[ih].hwPt > 0))
0278 dbgPrintf("FW \t calo %3d pt %8.2f --> discarded (zero em)\n", ih, in.hadcalo[ih].floatPt());
0279 } else {
0280 hadcalo_out[ih].hwPt = alldiff;
0281 hadcalo_out[ih].hwEmPt = (emdiff > 0 ? pt_t(emdiff) : pt_t(0));
0282 }
0283 }
0284 }
0285
0286 void l1ct::PFAlgo3Emulator::run(const PFInputRegion& in, OutputRegion& out) const {
0287
0288 unsigned int nTRACK = std::min<unsigned>(nTRACK_, in.track.size());
0289 unsigned int nEMCALO = std::min<unsigned>(nEMCALO_, in.emcalo.size());
0290 unsigned int nPHOTON = std::min<unsigned>(nPHOTON_, in.emcalo.size());
0291 unsigned int nCALO = std::min<unsigned>(nCALO_, in.hadcalo.size());
0292 unsigned int nSELCALO = std::min<unsigned>(nSELCALO_, in.hadcalo.size());
0293 unsigned int nMU = std::min<unsigned>(nMU_, in.muon.size());
0294
0295 if (debug_) {
0296 dbgPrintf("FW\nFW \t region eta %+5.2f [ %+5.2f , %+5.2f ], phi %+5.2f [ %+5.2f , %+5.2f ] packed %s\n",
0297 in.region.floatEtaCenter(),
0298 in.region.floatEtaMinExtra(),
0299 in.region.floatEtaMaxExtra(),
0300 in.region.floatPhiCenter(),
0301 in.region.floatPhiCenter() - in.region.floatPhiHalfWidthExtra(),
0302 in.region.floatPhiCenter() + in.region.floatPhiHalfWidthExtra(),
0303 in.region.pack().to_string(16).c_str());
0304
0305 dbgPrintf("FW \t N(track) %3lu N(em) %3lu N(calo) %3lu N(mu) %3lu\n",
0306 in.track.size(),
0307 in.emcalo.size(),
0308 in.hadcalo.size(),
0309 in.muon.size());
0310
0311 for (unsigned int i = 0; i < nTRACK; ++i) {
0312 if (in.track[i].hwPt == 0)
0313 continue;
0314 dbgPrintf(
0315 "FW \t track %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] vtx eta %+5.2f "
0316 "vtx phi %+5.2f charge %+2d qual %2d fid %d glb eta %+5.2f phi %+5.2f packed %s\n",
0317 i,
0318 in.track[i].floatPt(),
0319 in.track[i].intPt(),
0320 in.track[i].floatEta(),
0321 in.track[i].intEta(),
0322 in.track[i].floatPhi(),
0323 in.track[i].intPhi(),
0324 in.track[i].floatVtxEta(),
0325 in.track[i].floatVtxPhi(),
0326 in.track[i].intCharge(),
0327 int(in.track[i].hwQuality),
0328 int(in.region.isFiducial(in.track[i].hwEta, in.track[i].hwPhi)),
0329 in.region.floatGlbEta(in.track[i].hwVtxEta()),
0330 in.region.floatGlbPhi(in.track[i].hwVtxPhi()),
0331 in.track[i].pack().to_string(16).c_str());
0332 }
0333 for (unsigned int i = 0; i < nEMCALO; ++i) {
0334 if (in.emcalo[i].hwPt == 0)
0335 continue;
0336 dbgPrintf(
0337 "FW \t EM %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] calo ptErr %8.2f [ "
0338 "%6d ] emID %2d fid %d glb eta %+5.2f phi %+5.2f packed %s \n",
0339 i,
0340 in.emcalo[i].floatPt(),
0341 in.emcalo[i].intPt(),
0342 in.emcalo[i].floatEta(),
0343 in.emcalo[i].intEta(),
0344 in.emcalo[i].floatPhi(),
0345 in.emcalo[i].intPhi(),
0346 in.emcalo[i].floatPtErr(),
0347 in.emcalo[i].intPtErr(),
0348 in.emcalo[i].hwEmID.to_int(),
0349 int(in.region.isFiducial(in.emcalo[i].hwEta, in.emcalo[i].hwPhi)),
0350 in.region.floatGlbEtaOf(in.emcalo[i]),
0351 in.region.floatGlbPhiOf(in.emcalo[i]),
0352 in.emcalo[i].pack().to_string(16).c_str());
0353 }
0354 for (unsigned int i = 0; i < nCALO; ++i) {
0355 if (in.hadcalo[i].hwPt == 0)
0356 continue;
0357 dbgPrintf(
0358 "FW \t calo %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] calo emPt %8.2f [ "
0359 "%6d ] emID %2d fid %d glb eta %+5.2f phi %+5.2f packed %s \n",
0360 i,
0361 in.hadcalo[i].floatPt(),
0362 in.hadcalo[i].intPt(),
0363 in.hadcalo[i].floatEta(),
0364 in.hadcalo[i].intEta(),
0365 in.hadcalo[i].floatPhi(),
0366 in.hadcalo[i].intPhi(),
0367 in.hadcalo[i].floatEmPt(),
0368 in.hadcalo[i].intEmPt(),
0369 in.hadcalo[i].hwEmID.to_int(),
0370 int(in.region.isFiducial(in.hadcalo[i].hwEta, in.hadcalo[i].hwPhi)),
0371 in.region.floatGlbEtaOf(in.hadcalo[i]),
0372 in.region.floatGlbPhiOf(in.hadcalo[i]),
0373 in.hadcalo[i].pack().to_string(16).c_str());
0374 }
0375 for (unsigned int i = 0; i < nMU; ++i) {
0376 if (in.muon[i].hwPt == 0)
0377 continue;
0378 dbgPrintf(
0379 "FW \t muon %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] "
0380 "vtx eta %+5.2f vtx phi %+5.2f charge %+2d qual %2d glb eta %+5.2f phi %+5.2f packed %s \n",
0381 i,
0382 in.muon[i].floatPt(),
0383 in.muon[i].intPt(),
0384 in.muon[i].floatEta(),
0385 in.muon[i].intEta(),
0386 in.muon[i].floatPhi(),
0387 in.muon[i].intPhi(),
0388 in.muon[i].floatVtxEta(),
0389 in.muon[i].floatVtxPhi(),
0390 in.muon[i].intCharge(),
0391 int(in.muon[i].hwQuality),
0392 in.region.floatGlbEta(in.muon[i].hwVtxEta()),
0393 in.region.floatGlbPhi(in.muon[i].hwVtxPhi()),
0394 in.muon[i].pack().to_string(16).c_str());
0395 }
0396 dbgPrintf("%s", "FW\n");
0397 }
0398
0399
0400
0401 std::vector<int> iMu;
0402 pfalgo_mu_ref(in, out, iMu);
0403
0404
0405
0406 std::vector<int> iEle;
0407 std::vector<HadCaloObjEmu> hadcalo_subem(nCALO);
0408 pfalgo3_em_ref(in, iMu, iEle, out, hadcalo_subem);
0409
0410
0411
0412
0413
0414 std::vector<pt_t> calo_sumtk(nCALO), calo_subpt(nCALO);
0415 std::vector<pt2_t> calo_sumtkErr2(nCALO);
0416 for (unsigned int ic = 0; ic < nCALO; ++ic) {
0417 calo_sumtk[ic] = 0;
0418 calo_sumtkErr2[ic] = 0;
0419 }
0420
0421
0422 std::vector<bool> track_good(nTRACK, false);
0423 for (unsigned int it = 0; it < nTRACK; ++it) {
0424 if (!in.track[it].isPFLoose())
0425 continue;
0426 pt_t ptInv = in.track[it].isPFTight() ? tk_MAXINVPT_TIGHT_ : tk_MAXINVPT_LOOSE_;
0427 track_good[it] = (in.track[it].hwPt < ptInv) || (iEle[it] != -1) || (iMu[it] != -1);
0428 }
0429
0430
0431 out.pfcharged.resize(nTRACK);
0432 out.pfneutral.resize(nSELCALO);
0433 for (unsigned int ipf = 0; ipf < nTRACK; ++ipf)
0434 out.pfcharged[ipf].clear();
0435 for (unsigned int ipf = 0; ipf < nSELCALO; ++ipf)
0436 out.pfneutral[ipf].clear();
0437
0438
0439 std::vector<int> tk2calo(nTRACK, -1);
0440 for (unsigned int it = 0; it < nTRACK; ++it) {
0441 if (in.track[it].hwPt > 0 && in.track[it].isPFLoose() && (iEle[it] == -1) && (iMu[it] == -1)) {
0442 pt_t tkCaloPtErr = ptErr_ref(in.region, in.track[it]);
0443 int ibest = best_match_with_pt_ref(dR2MAX_TK_CALO_, hadcalo_subem, in.track[it], tkCaloPtErr);
0444 if (ibest != -1) {
0445 if (debug_)
0446 dbgPrintf(
0447 "FW \t track %3d pt %8.2f matched to calo %3d pt %8.2f (int deltaR2 %d)\n",
0448 it,
0449 in.track[it].floatPt(),
0450 ibest,
0451 hadcalo_subem[ibest].floatPt(),
0452 dr2_int(in.track[it].hwEta, in.track[it].hwPhi, hadcalo_subem[ibest].hwEta, hadcalo_subem[ibest].hwPhi));
0453 track_good[it] = true;
0454 calo_sumtk[ibest] += in.track[it].hwPt;
0455 calo_sumtkErr2[ibest] += tkCaloPtErr * tkCaloPtErr;
0456 }
0457 tk2calo[it] = ibest;
0458 }
0459 }
0460
0461 for (unsigned int ic = 0; ic < nCALO; ++ic) {
0462 if (calo_sumtk[ic] > 0) {
0463 dpt_t ptdiff = dpt_t(hadcalo_subem[ic].hwPt) - dpt_t(calo_sumtk[ic]);
0464 pt2_t sigmamult = calo_sumtkErr2
0465 [ic];
0466 if (debug_ && (hadcalo_subem[ic].hwPt > 0)) {
0467 dbgPrintf(
0468 "FW \t calo %3d pt %8.2f [ %7d ] eta %+5.2f [ %+5d ] has a sum track pt %8.2f, difference %7.2f +- %.2f "
0469 "\n",
0470 ic,
0471 hadcalo_subem[ic].floatPt(),
0472 hadcalo_subem[ic].intPt(),
0473 hadcalo_subem[ic].floatEta(),
0474 hadcalo_subem[ic].intEta(),
0475 Scales::floatPt(calo_sumtk[ic]),
0476 Scales::floatPt(ptdiff),
0477 std::sqrt(Scales::floatPt(calo_sumtkErr2[ic])));
0478 }
0479 if (ptdiff > 0 && ptdiff * ptdiff > sigmamult) {
0480 calo_subpt[ic] = pt_t(ptdiff);
0481 } else {
0482 calo_subpt[ic] = 0;
0483 }
0484 } else {
0485 calo_subpt[ic] = hadcalo_subem[ic].hwPt;
0486 }
0487 if (debug_ && (hadcalo_subem[ic].hwPt > 0))
0488 dbgPrintf(
0489 "FW \t calo %3d pt %8.2f ---> %8.2f \n", ic, hadcalo_subem[ic].floatPt(), Scales::floatPt(calo_subpt[ic]));
0490 }
0491
0492
0493 for (unsigned int it = 0; it < nTRACK; ++it) {
0494 if (track_good[it]) {
0495 fillPFCand(in.track[it], out.pfcharged[it], iMu[it] != -1, iEle[it] != -1);
0496
0497 if (iEle[it] != -1)
0498 out.pfcharged[it].srcCluster = in.emcalo[iEle[it]].src;
0499 if (iMu[it] != -1)
0500 out.pfcharged[it].srcMu = in.muon[iMu[it]].src;
0501 }
0502 }
0503
0504
0505 std::vector<PFNeutralObjEmu> outne_all(nCALO);
0506 for (unsigned int ipf = 0; ipf < nCALO; ++ipf)
0507 outne_all[ipf].clear();
0508 for (unsigned int ic = 0; ic < nCALO; ++ic) {
0509 if (calo_subpt[ic] > 0) {
0510 fillPFCand(hadcalo_subem[ic], outne_all[ic]);
0511 outne_all[ic].hwPt = calo_subpt[ic];
0512 outne_all[ic].hwEmPt = hadcalo_subem[ic].hwIsEM() ? calo_subpt[ic] : pt_t(0);
0513 }
0514 }
0515
0516 if (nCALO_ == nSELCALO_) {
0517 std::swap(outne_all, out.pfneutral);
0518 } else {
0519 ptsort_ref(nCALO, nSELCALO, outne_all, out.pfneutral);
0520 }
0521
0522 if (debug_) {
0523 dbgPrintf("%s", "FW\n");
0524 for (unsigned int i = 0; i < nTRACK; ++i) {
0525 if (out.pfcharged[i].hwPt == 0)
0526 continue;
0527 dbgPrintf(
0528 "FW \t outch %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] pid %d packed %s\n",
0529 i,
0530 out.pfcharged[i].floatPt(),
0531 out.pfcharged[i].intPt(),
0532 out.pfcharged[i].floatEta(),
0533 out.pfcharged[i].intEta(),
0534 out.pfcharged[i].floatPhi(),
0535 out.pfcharged[i].intPhi(),
0536 out.pfcharged[i].intId(),
0537 out.pfcharged[i].pack().to_string(16).c_str());
0538 }
0539 for (unsigned int i = 0; i < nPHOTON; ++i) {
0540 if (out.pfphoton[i].hwPt == 0)
0541 continue;
0542 dbgPrintf(
0543 "FW \t outph %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] pid %d packed %s\n",
0544 i,
0545 out.pfphoton[i].floatPt(),
0546 out.pfphoton[i].intPt(),
0547 out.pfphoton[i].floatEta(),
0548 out.pfphoton[i].intEta(),
0549 out.pfphoton[i].floatPhi(),
0550 out.pfphoton[i].intPhi(),
0551 out.pfphoton[i].intId(),
0552 out.pfphoton[i].pack().to_string(16).c_str());
0553 }
0554 for (unsigned int i = 0; i < nSELCALO; ++i) {
0555 if (out.pfneutral[i].hwPt == 0)
0556 continue;
0557 dbgPrintf(
0558 "FW \t outne %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] pid %d packed %s\n",
0559 i,
0560 out.pfneutral[i].floatPt(),
0561 out.pfneutral[i].intPt(),
0562 out.pfneutral[i].floatEta(),
0563 out.pfneutral[i].intEta(),
0564 out.pfneutral[i].floatPhi(),
0565 out.pfneutral[i].intPhi(),
0566 out.pfneutral[i].intId(),
0567 out.pfneutral[i].pack().to_string(16).c_str());
0568 }
0569 dbgPrintf("%s", "FW\n");
0570 }
0571 }
0572
0573 void l1ct::PFAlgo3Emulator::mergeNeutrals(OutputRegion& out) const {
0574 out.pfphoton.reserve(out.pfphoton.size() + out.pfneutral.size());
0575 out.pfphoton.insert(out.pfphoton.end(), out.pfneutral.begin(), out.pfneutral.end());
0576 out.pfphoton.swap(out.pfneutral);
0577 out.pfphoton.clear();
0578 }