File indexing completed on 2025-06-20 01:53:35
0001 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/hgcalinput_ref.h"
0002 #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/nn_activation.h"
0003
0004 #ifdef CMSSW_GIT_HASH
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0007
0008 l1ct::HgcalClusterDecoderEmulator::HgcalClusterDecoderEmulator(const edm::ParameterSet &pset)
0009 : slim_(pset.getParameter<bool>("slim")),
0010 multiclass_id_(pset.getParameterSet("multiclass_id")),
0011 corrector_(pset.getParameter<std::string>("corrector"),
0012 pset.getParameter<double>("correctorEmfMax"),
0013 false,
0014 pset.getParameter<bool>("emulateCorrections"),
0015 l1tpf::corrector::EmulationMode::Correction),
0016 emInterpScenario_(setEmInterpScenario(pset.getParameter<std::string>("emInterpScenario"))) {}
0017
0018 edm::ParameterSetDescription l1ct::HgcalClusterDecoderEmulator::getParameterSetDescription() {
0019 edm::ParameterSetDescription description;
0020 description.add<bool>("slim", false);
0021 description.add<std::string>("corrector", "");
0022 description.add<double>("correctorEmfMax", -1);
0023 description.add<bool>("emulateCorrections", false);
0024 description.add<edm::ParameterSetDescription>("multiclass_id", MultiClassID::getParameterSetDescription());
0025 description.add<std::string>("emInterpScenario", "No");
0026 return description;
0027 }
0028
0029 l1ct::HgcalClusterDecoderEmulator::MultiClassID::MultiClassID(const edm::ParameterSet &pset)
0030 : l1ct::HgcalClusterDecoderEmulator::MultiClassID::MultiClassID(
0031 pset.getParameter<std::string>("model"),
0032 pset.getParameter<std::vector<double>>("wp_pt"),
0033 pset.getParameter<std::vector<double>>("wp_PU"),
0034 pset.getParameter<std::vector<double>>("wp_Pi"),
0035 pset.getParameter<std::vector<double>>("wp_PFEm"),
0036 pset.getParameter<std::vector<double>>("wp_EgEm"),
0037 pset.getParameter<std::vector<double>>("wp_EgEm_tight")) {}
0038
0039 edm::ParameterSetDescription l1ct::HgcalClusterDecoderEmulator::MultiClassID::getParameterSetDescription() {
0040 edm::ParameterSetDescription description;
0041 description.add<std::string>("model");
0042 description.add<std::vector<double>>("wp_pt");
0043 description.add<std::vector<double>>("wp_PU");
0044 description.add<std::vector<double>>("wp_Pi");
0045 description.add<std::vector<double>>("wp_EgEm");
0046 description.add<std::vector<double>>("wp_EgEm_tight");
0047 description.add<std::vector<double>>("wp_PFEm");
0048 return description;
0049 }
0050
0051 #endif
0052
0053 l1ct::HgcalClusterDecoderEmulator::HgcalClusterDecoderEmulator(const std::string &model,
0054 const std::vector<double> &wp_pt,
0055 const std::vector<double> &wp_PU,
0056 const std::vector<double> &wp_Pi,
0057 const std::vector<double> &wp_PFEm,
0058 const std::vector<double> &wp_EgEm,
0059 const std::vector<double> &wp_EgEm_tight,
0060 bool slim,
0061 const std::string &corrector,
0062 float correctorEmfMax,
0063 bool emulateCorrections,
0064 const std::string &emInterpScenario)
0065 : slim_{slim},
0066 multiclass_id_(model, wp_pt, wp_PU, wp_Pi, wp_PFEm, wp_EgEm, wp_EgEm_tight),
0067 corrector_(corrector, correctorEmfMax, false, emulateCorrections, l1tpf::corrector::EmulationMode::Correction),
0068 emInterpScenario_(setEmInterpScenario(emInterpScenario)) {}
0069
0070 l1ct::HgcalClusterDecoderEmulator::UseEmInterp l1ct::HgcalClusterDecoderEmulator::setEmInterpScenario(
0071 const std::string &emInterpScenario) {
0072 if (emInterpScenario == "no")
0073 return UseEmInterp::No;
0074 if (emInterpScenario == "emOnly")
0075 return UseEmInterp::EmOnly;
0076 if (emInterpScenario == "allKeepHad")
0077 return UseEmInterp::AllKeepHad;
0078 if (emInterpScenario == "allKeepTot")
0079 return UseEmInterp::AllKeepTot;
0080 throw std::runtime_error("Unknown emInterpScenario: " + emInterpScenario);
0081 }
0082
0083 l1ct::HadCaloObjEmu l1ct::HgcalClusterDecoderEmulator::decode(const l1ct::PFRegionEmu §or,
0084 const ap_uint<256> &in,
0085 bool &valid) const {
0086
0087 ap_uint<14> w_pt = in(13, 0);
0088 ap_uint<14> w_empt = in(27, 14);
0089 ap_uint<4> w_gctqual = in(31, 28);
0090 ap_uint<8> w_emf_tot = in(39, 32);
0091 ap_uint<8> w_emf = in(47, 40);
0092
0093
0094 ap_uint<10> w_abseta = in(64 + 9, 64 + 0);
0095 ap_int<9> w_phi = in(64 + 18, 64 + 10);
0096 ap_uint<12> w_meanz = in(64 + 30, 64 + 19);
0097
0098
0099 ap_uint<6> w_showerlength = in(128 + 18, 128 + 13);
0100 ap_uint<7> w_sigmazz = in(128 + 38, 128 + 32);
0101 ap_uint<7> w_sigmaphiphi = in(128 + 45, 128 + 39);
0102 ap_uint<6> w_coreshowerlength = in(128 + 51, 128 + 46);
0103 ap_uint<5> w_sigmaetaeta = in(128 + 56, 128 + 52);
0104
0105
0106 ap_uint<13> w_sigmarrtot = in(213, 201);
0107
0108
0109 ap_int<9> w_eta = l1ct::glbeta_t(w_abseta.to_int() * (sector.floatEtaCenter() > 0 ? +1 : -1)) - sector.hwEtaCenter;
0110
0111 l1ct::HadCaloObjEmu out;
0112 out.clear();
0113 if (w_pt == 0)
0114 return out;
0115
0116
0117 out.hwPt = w_pt * l1ct::pt_t(l1ct::Scales::INTPT_LSB);
0118 out.hwEta = w_eta;
0119 out.hwPhi = w_phi;
0120 out.hwEmPt = w_empt * l1ct::pt_t(l1ct::Scales::INTPT_LSB);
0121
0122 if (!slim_) {
0123
0124 out.hwSrrTot = w_sigmarrtot * l1ct::srrtot_t(l1ct::Scales::SRRTOT_LSB);
0125
0126 out.hwMeanZ = l1ct::meanz_t(std::min(w_meanz.to_int() + 1, (1 << 12) - 1) >> 1);
0127
0128
0129
0130 ap_ufixed<10, 5, AP_RND_CONV, AP_SAT> w_hoe = 256.0 / (w_emf_tot.to_int() + 0.5) - 1;
0131 out.hwHoe = w_hoe;
0132 }
0133 std::vector<MultiClassID::bdt_feature_t> inputs = {w_showerlength,
0134 w_coreshowerlength,
0135 w_emf,
0136 w_abseta - 256,
0137 w_meanz,
0138 w_sigmaetaeta,
0139 w_sigmaphiphi,
0140 w_sigmazz};
0141
0142
0143 if (emInterpScenario_ == UseEmInterp::No) {
0144 out.hwEmPt = w_emf_tot * out.hwPt / 256;
0145
0146 } else if (emInterpScenario_ == UseEmInterp::EmOnly) {
0147 if (out.hwEmID) {
0148 out.hwPt = out.hwEmPt;
0149 out.hwHoe = 0;
0150 }
0151 } else if (emInterpScenario_ ==
0152 UseEmInterp::AllKeepHad) {
0153 l1ct::pt_t had_pt = out.hwPt - w_emf_tot * out.hwPt / 256;
0154 out.hwPt = had_pt + out.hwEmPt;
0155
0156 } else if (emInterpScenario_ ==
0157 UseEmInterp::AllKeepTot) {
0158
0159 }
0160
0161 bool notPU = multiclass_id_.evaluate(out, inputs);
0162
0163
0164 if (corrector_.valid()) {
0165 float newpt = corrector_.correctedPt(out.floatPt(), out.floatEmPt(), sector.floatGlbEta(out.hwEta));
0166 out.hwPt = l1ct::Scales::makePtFromFloat(newpt);
0167
0168 }
0169
0170
0171 valid = notPU && out.hwPt > 0;
0172
0173 return out;
0174 }
0175
0176 l1ct::HgcalClusterDecoderEmulator::MultiClassID::MultiClassID(const std::string &model,
0177 const std::vector<double> &wp_pt,
0178 const std::vector<double> &wp_PU,
0179 const std::vector<double> &wp_Pi,
0180 const std::vector<double> &wp_PFEm,
0181 const std::vector<double> &wp_EgEm,
0182 const std::vector<double> &wp_EgEm_tight) {
0183 for (auto pt : wp_pt)
0184 wp_pt_.emplace_back(pt);
0185 for (auto pu : wp_PU)
0186 wp_PU_.emplace_back(pu);
0187 for (auto pi : wp_Pi)
0188 wp_Pi_.emplace_back(pi);
0189 for (auto egem : wp_EgEm)
0190 wp_EgEm_.emplace_back(egem);
0191 for (auto pfem : wp_PFEm)
0192 wp_PFEm_.emplace_back(pfem);
0193 for (auto egem : wp_EgEm_tight)
0194 wp_EgEm_tight_.emplace_back(egem);
0195
0196 #ifdef CMSSW_GIT_HASH
0197 auto resolvedFileName = edm::FileInPath(model).fullPath();
0198 #else
0199 auto resolvedFileName = model;
0200 #endif
0201 multiclass_bdt_ = std::make_unique<conifer::BDT<bdt_feature_t, bdt_score_t, false>>(resolvedFileName);
0202 }
0203
0204 bool l1ct::HgcalClusterDecoderEmulator::MultiClassID::evaluate(l1ct::HadCaloObjEmu &cl,
0205 const std::vector<bdt_feature_t> &inputs) const {
0206 auto bdt_score = multiclass_bdt_->decision_function(inputs);
0207 bdt_score_t raw_scores[3] = {bdt_score[0], bdt_score[1], bdt_score[2]};
0208 l1ct::id_prob_t sm_scores[3];
0209 nnet::softmax_stable<bdt_score_t, l1ct::id_prob_t, softmax_config>(raw_scores, sm_scores);
0210
0211
0212
0213 unsigned int pt_bin = 0;
0214 for (size_t i = wp_pt_.size(); i > 0; --i) {
0215 if (cl.hwPt >= wp_pt_[i - 1]) {
0216 pt_bin = i;
0217 break;
0218 }
0219 }
0220 bool passPu = (sm_scores[0] >= wp_PU_[pt_bin]);
0221
0222 bool passPFEm = (sm_scores[2] >= wp_PFEm_[pt_bin]);
0223 bool passEgEm = (sm_scores[2] >= wp_EgEm_[pt_bin]);
0224 bool passEgEm_tight = (sm_scores[2] >= wp_EgEm_tight_[pt_bin]);
0225
0226
0227
0228
0229 cl.hwEmID = passPFEm | (passEgEm_tight << 1) | (passEgEm << 2);
0230
0231 cl.hwPiProb = sm_scores[1];
0232 cl.hwEmProb = sm_scores[2];
0233 return !passPu;
0234 }
0235
0236 void l1ct::HgcalClusterDecoderEmulator::MultiClassID::softmax(const float rawScores[3], float scores[3]) const {
0237
0238
0239 float denom = exp(rawScores[0]) + exp(rawScores[1]) + exp(rawScores[2]);
0240 scores[0] = exp(rawScores[0]) / denom;
0241 scores[1] = exp(rawScores[1]) / denom;
0242 scores[2] = exp(rawScores[2]) / denom;
0243 }