Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-10 01:53:51

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