Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-01-23 00:19:42

0001 #ifndef L1Trigger_Phase2L1ParticleFlow_TAUNNIDHW_H_
0002 #define L1Trigger_Phase2L1ParticleFlow_TAUNNIDHW_H_
0003 
0004 #include <cstdio>
0005 #include <complex>
0006 
0007 #include "L1Trigger/Phase2L1ParticleFlow/interface/taus/tau_parameters.h"
0008 #include "L1Trigger/Phase2L1ParticleFlow/interface/taus/defines.h"
0009 
0010 #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h"
0011 #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h"
0012 
0013 typedef ap_ufixed<16, 14> pt_t;
0014 typedef ap_fixed<10, 4> etaphi_t;
0015 
0016 // Tau NN returns two values
0017 struct Tau_NN_Result {
0018   result_t nn_pt_correction;
0019   result_t nn_id;
0020 };
0021 
0022 namespace L1TauEmu {
0023   // Data types and constants used in the FPGA and FPGA-optimized functions
0024   //etaphi_base maps physical eta phi units onto bits
0025   //This way, the least significant bit of etaphi_t is exactly 0.01
0026   //Even though 0.01 is not a power of 2
0027   static constexpr float etaphi_base = 100. / 64;
0028   typedef ap_ufixed<16, 14> pt_t;        // 1 unit = 0.25 GeV;
0029   typedef ap_fixed<10, 4> etaphi_t;      // 1 unit = 0.01;
0030   typedef ap_fixed<12, 6> detaphi_t;     // type for the difference between etas or phis
0031   typedef ap_fixed<18, 9> detaphi2_t;    // type for detaphi_t squared
0032   typedef ap_fixed<22, 16> pt_etaphi_t;  // type for product of pt with deta or phi
0033   typedef ap_int<8> dxy_t;
0034   typedef ap_int<10> z0_t;
0035   typedef ap_uint<5> count_t;  // type for multiplicity
0036   typedef ap_uint<5> id_t;     // type for multiplicity
0037 
0038   // constants for the axis update
0039   typedef ap_ufixed<18, -2> inv_pt_t;
0040   static constexpr int N_table_inv_pt = 1024;
0041   static const detaphi_t TWOPI = 3.14159 * 2. * etaphi_base;
0042   static const detaphi_t PI = 3.14159 * etaphi_base;
0043   static const detaphi_t HALFPI = 3.14159 / 2 * etaphi_base;
0044   static const detaphi_t RCONE = 0.4 * 100 / 128;
0045   static const detaphi_t R2CONE = RCONE * RCONE;
0046   //
0047   static const etaphi_t FIDUCIAL_ETA_PHI = 5.11 * etaphi_base;
0048 
0049   constexpr int ceillog2(int x) { return (x <= 2) ? 1 : 1 + ceillog2((x + 1) / 2); }
0050   constexpr int floorlog2(int x) { return (x < 2) ? 0 : 1 + floorlog2(x / 2); }
0051   constexpr int pow2(int x) { return x == 0 ? 1 : 2 * pow2(x - 1); }
0052 
0053   template <class data_T, int N>
0054   inline float real_val_from_idx(unsigned i) {
0055     // Treat the index as the top N bits
0056     static constexpr int NB = ceillog2(N);  // number of address bits for table
0057     data_T x(0);
0058     // The MSB of 1 is implicit in the table
0059     x[x.width - 1] = 1;
0060     // So we can use the next NB bits for real data
0061     x(x.width - 2, x.width - NB - 1) = i;
0062     return (float)x;
0063   }
0064 
0065   template <class data_T, int N>
0066   inline unsigned idx_from_real_val(data_T x) {
0067     // Slice the top N bits to get an index into the table
0068     static constexpr int NB = ceillog2(N);  // number of address bits for table
0069     // Slice the top-1 NB bits of the value
0070     // the MSB of '1' is implicit, so only slice below that
0071     ap_uint<NB> y = x(x.width - 2, x.width - NB - 1);
0072     return (unsigned)y(NB - 1, 0);
0073   }
0074 
0075   template <class data_T, class table_T, int N>
0076   void init_invert_table(table_T table_out[N]) {
0077     // The template data_T is the data type used to address the table
0078     for (unsigned i = 0; i < N; i++) {
0079       float x = real_val_from_idx<data_T, N>(i);
0080       table_T inv_x = 1 / x;
0081       table_out[i] = inv_x;
0082     }
0083   }
0084 
0085   template <class in_t, class table_t, int N>
0086   table_t invert_with_shift(in_t in, bool debug = false) {
0087     table_t inv_table[N];
0088     init_invert_table<in_t, table_t, N>(inv_table);
0089 
0090     // find the first '1' in the denominator
0091     int msb = 0;
0092     for (int b = 0; b < in.width; b++) {
0093       if (in[b])
0094         msb = b;
0095     }
0096     // shift up the denominator such that the left-most bit (msb) is '1'
0097     in_t in_shifted = in << (in.width - msb - 1);
0098     // lookup the inverse of the shifted input
0099     int idx = idx_from_real_val<in_t, N>(in_shifted);
0100     table_t inv_in = inv_table[idx];
0101     // shift the output back
0102     table_t out = inv_in << (in.width - msb - 1);
0103 
0104     return out;
0105   }
0106 
0107   inline detaphi_t deltaPhi(l1t::PFCandidate a, l1t::PFCandidate b) {
0108     // scale the particle eta, phi to hardware units
0109     etaphi_t aphi = etaphi_t(a.phi() * etaphi_base);
0110     etaphi_t bphi = etaphi_t(b.phi() * etaphi_base);
0111     detaphi_t dphi = detaphi_t(aphi) - detaphi_t(bphi);
0112     // phi wrap
0113     detaphi_t dphi0 =
0114         dphi > detaphi_t(l1ct::Scales::INTPHI_PI) ? detaphi_t(l1ct::Scales::INTPHI_TWOPI - dphi) : detaphi_t(dphi);
0115     detaphi_t dphi1 =
0116         dphi < detaphi_t(-l1ct::Scales::INTPHI_PI) ? detaphi_t(l1ct::Scales::INTPHI_TWOPI + dphi) : detaphi_t(dphi);
0117     //dphi > PI ? detaphi_t(TWOPI - dphi) : detaphi_t(dphi);
0118     //dphi < -PI ? detaphi_t(TWOPI + dphi) : detaphi_t(dphi);
0119     detaphi_t dphiw = dphi > detaphi_t(0) ? dphi0 : dphi1;
0120     return dphiw;
0121   }
0122 
0123   inline bool inCone(l1t::PFCandidate seed, l1t::PFCandidate part, detaphi_t cone2) {
0124     // scale the particle eta, phi to hardware units
0125     etaphi_t seta = etaphi_t(seed.eta() * etaphi_base);
0126     etaphi_t peta = etaphi_t(part.eta() * etaphi_base);
0127     detaphi_t deta = detaphi_t(seta) - detaphi_t(peta);
0128     detaphi_t dphi = deltaPhi(seed, part);
0129     bool ret = (deta * deta + dphi * dphi) < cone2;
0130     return ret;
0131   }
0132 
0133 };  // namespace L1TauEmu
0134 
0135 class TauNNIdHW {
0136 public:
0137   TauNNIdHW();
0138   ~TauNNIdHW();
0139 
0140   void initialize(const std::string &iName, int iNParticles);
0141   void SetNNVectorVar();
0142   input_t *NNVectorVar() { return NNvectorVar_.data(); }
0143   Tau_NN_Result EvaluateNN();
0144   Tau_NN_Result compute(const l1t::PFCandidate &iSeed, std::vector<l1t::PFCandidate> &iParts);
0145   //void print();
0146 
0147   std::string fInput_;
0148   unsigned fNParticles_;
0149   unique_ptr<pt_t[]> fPt_;
0150   unique_ptr<etaphi_t[]> fEta_;
0151   unique_ptr<etaphi_t[]> fPhi_;
0152   unique_ptr<id_t[]> fId_;
0153   //FILE *file_;
0154 
0155 private:
0156   std::vector<input_t> NNvectorVar_;
0157 };
0158 
0159 #endif