File indexing completed on 2023-10-25 09:55:53
0001 #ifndef L1Trigger_Phase2L1ParticleFlow_L1SeedConePFJetEmulator_h
0002 #define L1Trigger_Phase2L1ParticleFlow_L1SeedConePFJetEmulator_h
0003
0004 #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h"
0005 #include "DataFormats/L1TParticleFlow/interface/jets.h"
0006
0007 #include <iostream>
0008 #include <vector>
0009 #include <numeric>
0010 #include <algorithm>
0011
0012 #include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h"
0013
0014 class L1SCJetEmu {
0015 public:
0016
0017
0018
0019 typedef l1ct::pt_t pt_t;
0020 typedef l1ct::glbeta_t etaphi_t;
0021 typedef ap_int<13> detaphi_t;
0022 typedef ap_fixed<18, 23> detaphi2_t;
0023 typedef ap_fixed<22, 22> pt_etaphi_t;
0024 typedef l1ct::PuppiObjEmu Particle;
0025
0026 class Jet : public l1ct::Jet {
0027 public:
0028 std::vector<l1ct::PuppiObjEmu> constituents;
0029 };
0030
0031 L1SCJetEmu(bool debug, float coneSize, unsigned nJets);
0032
0033 std::vector<Jet> emulateEvent(std::vector<Particle>& parts) const;
0034
0035 private:
0036
0037 bool debug_;
0038 float coneSize_;
0039 unsigned nJets_;
0040 detaphi2_t rCone2_;
0041
0042
0043 typedef ap_ufixed<18, -2> inv_pt_t;
0044 static constexpr int N_table_inv_pt = 1024;
0045 inv_pt_t inv_pt_table_[N_table_inv_pt];
0046
0047 static constexpr int ceillog2(int x) { return (x <= 2) ? 1 : 1 + ceillog2((x + 1) / 2); }
0048
0049 static constexpr int floorlog2(int x) { return (x < 2) ? 0 : 1 + floorlog2(x / 2); }
0050
0051 template <int B>
0052 static constexpr int pow(int x) {
0053 return x == 0 ? 1 : B * pow<B>(x - 1);
0054 }
0055
0056 static constexpr int pow2(int x) { return pow<2>(x); }
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 template <class T, class Op>
0067 static T reduce(std::vector<T> x, Op op) {
0068 int N = x.size();
0069 int leftN = pow2(floorlog2(N - 1)) > 0 ? pow2(floorlog2(N - 1)) : 0;
0070
0071 if (N == 1) {
0072 return x.at(0);
0073 } else if (N == 2) {
0074 return op(x.at(0), x.at(1));
0075 } else {
0076 std::vector<T> left(x.begin(), x.begin() + leftN);
0077 std::vector<T> right(x.begin() + leftN, x.end());
0078 return op(reduce<T, Op>(left, op), reduce<T, Op>(right, op));
0079 }
0080 }
0081
0082 class OpPuppiObjMax {
0083 public:
0084 Particle const& operator()(Particle const& a, Particle const& b) const { return a.hwPt >= b.hwPt ? a : b; }
0085 };
0086
0087 static constexpr OpPuppiObjMax op_max{};
0088
0089 template <class data_T, int N>
0090 static inline float real_val_from_idx(unsigned i) {
0091
0092 static constexpr int NB = ceillog2(N);
0093 data_T x(0);
0094
0095 x[x.width - 1] = 1;
0096
0097 x(x.width - 2, x.width - NB - 1) = i;
0098 return (float)x;
0099 }
0100
0101 template <class data_T, int N>
0102 static inline unsigned idx_from_real_val(data_T x) {
0103
0104 static constexpr int NB = ceillog2(N);
0105
0106
0107 ap_uint<NB> y = x(x.width - 2, x.width - NB - 1);
0108 return (unsigned)y(NB - 1, 0);
0109 }
0110
0111 template <class data_T, class table_T, int N>
0112 static void init_invert_table(table_T table_out[N]) {
0113
0114 for (unsigned i = 0; i < N; i++) {
0115 float x = real_val_from_idx<data_T, N>(i);
0116 table_T inv_x = 1 / x;
0117 table_out[i] = inv_x;
0118 }
0119 }
0120
0121 template <class in_t, class table_t, int N>
0122 static table_t invert_with_shift(const in_t in, const table_t inv_table[N], bool debug = false) {
0123
0124 int msb = 0;
0125 for (int b = 0; b < in.width; b++) {
0126 if (in[b])
0127 msb = b;
0128 }
0129
0130 in_t in_shifted = in << (in.width - msb - 1);
0131
0132 int idx = idx_from_real_val<in_t, N>(in_shifted);
0133 table_t inv_in = inv_table[idx];
0134
0135 table_t out = inv_in << (in.width - msb - 1);
0136 if (debug) {
0137 dbgCout() << " x " << in << ", msb = " << msb << ", shift = " << (in.width - msb) << ", idx = " << idx
0138 << std::endl;
0139 dbgCout() << " pre 1 / " << in_shifted << " = " << inv_in << "(" << 1 / (float)in_shifted << ")" << std::endl;
0140 dbgCout() << " post 1 / " << in << " = " << out << "(" << 1 / (float)in << ")" << std::endl;
0141 }
0142 return out;
0143 }
0144
0145 static detaphi_t deltaPhi(Particle a, Particle b);
0146 bool inCone(Particle seed, Particle part) const;
0147 Jet makeJet_HW(const std::vector<Particle>& parts) const;
0148
0149 };
0150
0151 #endif