Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:48

0001 //-------------------------------------------------
0002 //
0003 /**  \class L1MuGMTLUT
0004  *
0005  *   Description: A general-purpose Look-Up-Table Class
0006  *  
0007  *   Base class for all LUTs in the Global Muon Trigger Simulation
0008  *
0009  *
0010  *   INPUTS              OUTPUTS
0011  *
0012  *
0013  *             --------
0014  *             |      |
0015  *             |      |-- Y(1)
0016  *    eta(6) --|      |   1
0017  *      8..13  |      |
0018  *    phi(8) --|      |
0019  *      0..7   |      |-- X(1)
0020  *             |      |   0
0021  *             --------
0022  *
0023  *  std::vector<unsigned> inp; 
0024  *  inp [0] = phi
0025  *  inp [1] = eta
0026  *
0027  *  std::vector<unsigned> out = MyLUT.Lookup (lutidx, inp);
0028  *  X = out[0];
0029  *  Y = out[1];
0030  *
0031  *
0032  * 
0033 */
0034 //
0035 //
0036 //   Author :
0037 //   H. Sakulin            HEPHY Vienna
0038 //
0039 //   Migrated to CMSSW:
0040 //   I. Mikulec
0041 //
0042 //--------------------------------------------------
0043 #ifndef L1TriggerGlobalMuonTrigger_L1MuGMTLUT_h
0044 #define L1TriggerGlobalMuonTrigger_L1MuGMTLUT_h
0045 
0046 //---------------
0047 // C++ Headers --
0048 //---------------
0049 
0050 #include <vector>
0051 #include <iostream>
0052 //#include <sstream>
0053 #include <string>
0054 #include <cstdlib>
0055 #include <cstdio>
0056 
0057 //----------------------
0058 // Base Class Headers --
0059 //----------------------
0060 class L1MuGMTLUTConverter;
0061 
0062 //------------------------------------
0063 // Collaborating Class Declarations --
0064 //------------------------------------
0065 #include <L1Trigger/GlobalMuonTrigger/src/L1MuGMTLUTHelpers.h>
0066 
0067 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0068 
0069 //              ---------------------
0070 //              -- Class Interface --
0071 //              ---------------------
0072 
0073 class L1MuGMTLUT {
0074 public:
0075   typedef std::pair<std::string, unsigned> port;
0076 
0077   /// Init and Destruct
0078 
0079   /// default constructor w/o init
0080   L1MuGMTLUT() : m_initialized(false), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {}
0081 
0082   /// constructor with init
0083   L1MuGMTLUT(const char* name,
0084              const std::vector<std::string>& instances,
0085              const std::vector<port>& in_widths,
0086              const std::vector<port>& out_widths,
0087              unsigned vme_addr_width = 0,
0088              bool distrRAM = false)
0089       : m_initialized(false), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {
0090     Init(name, instances, in_widths, out_widths, vme_addr_width, distrRAM);
0091   };
0092 
0093   L1MuGMTLUT(const char* name,
0094              const std::string& instances,
0095              const std::string& inputs,
0096              const std::string& outputs,
0097              unsigned vme_addr_width = 0,
0098              bool distrRAM = false)
0099       : m_initialized(false), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {
0100     Init(name,
0101          L1MuGMTLUTHelpers::Tokenizer(" ", instances),
0102          PortDecoder(inputs),
0103          PortDecoder(outputs),
0104          vme_addr_width,
0105          distrRAM);
0106   };
0107 
0108   /// destructor
0109   virtual ~L1MuGMTLUT();
0110 
0111   /// main lookup function (unsigned -> unsigned)
0112   /// all lookup functions go through this one
0113   inline unsigned LookupPacked(int idx, unsigned) const;
0114 
0115   /// additional lookup function (std::vector -> unisgned)
0116   inline unsigned LookupPacked(int idx, const std::vector<unsigned>& address) const {
0117     return LookupPacked(idx, vec2u(address, m_Inputs));
0118   };
0119 
0120   /// additional lookup function (std::vector -> vector)
0121   inline std::vector<unsigned> Lookup(int idx, const std::vector<unsigned>& address) const {
0122     return Lookup(idx, vec2u(address, m_Inputs));
0123   };
0124 
0125   /// additional lookup function (unsigned -> std::vector)
0126   inline std::vector<unsigned> Lookup(int idx, unsigned address) const {
0127     return u2vec(LookupPacked(idx, address), m_Outputs);
0128   };
0129 
0130   /// I/O functions
0131 
0132   /// load from LUT file
0133   void Load(const char* path);
0134 
0135   /// save to LUT file
0136   void Save(const char* path);
0137 
0138   /// lookup defined as analytic function
0139   /// to be impemented in derived class
0140   virtual unsigned LookupFunctionPacked(int idx, unsigned address) const { return 0; };
0141 
0142   /// Add Generate SubClass method
0143   void MakeSubClass(const char* fname = "",
0144                     const char* template_file_h = "../interface/L1MuGMTLUT_SubClass.h_template",
0145                     const char* template_file_cc = "../interface/L1MuGMTLUT_SubClass.cc_template");
0146 
0147   std::string Name() { return m_name; };
0148 
0149   friend class L1MuGMTLUTConverter;
0150 
0151   /// get the number of Instances
0152   int numberOfInstances() { return m_NLUTS; };
0153 
0154 protected:
0155   /// Initialize the LUT
0156   void Init(const char* name,
0157             const std::vector<std::string>& instances,
0158             const std::vector<port>& in_widths,
0159             const std::vector<port>& out_widths,
0160             unsigned vme_addr_width = 0,
0161             bool distrRAM = false);
0162 
0163   /// generate address or value from composite address or value
0164   inline unsigned vec2u(const std::vector<unsigned>& vec, const std::vector<port>& widths) const;
0165 
0166   /// generate composite address or value from compact unsigned
0167   inline std::vector<unsigned> u2vec(unsigned value, const std::vector<port>& widths) const;
0168 
0169   /// set with single address and value
0170   void Set(int idx, unsigned address, unsigned value);
0171 
0172   class PortDecoder : public std::vector<port> {
0173     typedef std::vector<port> base;
0174 
0175   public:
0176     PortDecoder(const std::vector<port>& pt) : base(pt) {}
0177 
0178     PortDecoder(const std::string& input) {
0179       // decode std::string of style "phi(2) eta(4)"
0180       L1MuGMTLUTHelpers::Tokenizer tok(" ", input);
0181       for (unsigned int i = 0; i < tok.size(); i++) {
0182         size_type obrace = tok[i].find('('), cbrace = tok[i].find(')');
0183         if (obrace != std::string::npos && cbrace != std::string::npos)
0184           push_back(
0185               port(tok[i].substr(0, obrace), (unsigned)atoi(tok[i].substr(obrace + 1, cbrace - obrace - 1).c_str())));
0186         else
0187           edm::LogWarning("LUTMismatch") << "L1MuGMTLUT::PortDecoder: error decoding port " << tok[i];
0188       }
0189     };
0190     std::string str() {
0191       std::string temp;
0192       for (unsigned int i = 0; i < size(); i++) {
0193         // ostd::stringstream os; os << (*this)[i].second << ends;
0194         //    temp += (*this)[i].first + "(" + std::string( os.str() ) + ")";
0195 
0196         char buf[100];
0197         sprintf(buf, "(%d)", (*this)[i].second);
0198         temp += (*this)[i].first + std::string(buf);
0199 
0200         if (i != size() - 1)
0201           temp += " ";
0202       }
0203       return temp;
0204     };
0205 
0206   private:
0207   };
0208 
0209   bool m_initialized;
0210   int m_NLUTS;
0211   bool m_UseLookupFunction;
0212   std::vector<std::string> m_InstNames;
0213   std::vector<std::vector<unsigned> > m_Contents;
0214   std::vector<port> m_Inputs;  // first port in vector is most significant bits
0215   std::vector<port> m_Outputs;
0216   unsigned m_TotalInWidth;
0217   unsigned m_TotalOutWidth;
0218   unsigned m_vme_addr_width;
0219   bool m_distrRAM;
0220   std::string m_name;
0221   bool m_saveFlag;
0222   unsigned m_GeneralLUTVersion;
0223 };
0224 
0225 //--------------------------------------------------------------------------------
0226 
0227 unsigned L1MuGMTLUT::vec2u(const std::vector<unsigned>& vec, const std::vector<port>& widths) const {
0228   if (vec.size() != widths.size()) {
0229     edm::LogWarning("LUTMismatch")
0230         << "Error in L1MuGMTLUT::vec2u: number of LUT inputs/outputs does not match definition";
0231     return (0);
0232   }
0233 
0234   unsigned value = 0;
0235   unsigned start_ofs = 0;
0236 
0237   for (int i = vec.size() - 1; i >= 0; i--) {
0238     if (vec[i] >= (unsigned)(1 << widths[i].second)) {
0239       edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: LUT input/output number " << i
0240                                      << " exceeds range (0 to " << ((1 << widths[i].second) - 1) << ").";
0241     } else
0242       value |= vec[i] << start_ofs;
0243     start_ofs += widths[i].second;
0244   }
0245 
0246   return (value);
0247 }
0248 
0249 //--------------------------------------------------------------------------------
0250 
0251 std::vector<unsigned> L1MuGMTLUT::u2vec(unsigned value, const std::vector<port>& widths) const {
0252   std::vector<unsigned> output(widths.size(), 0);
0253 
0254   unsigned start_ofs = 0;
0255 
0256   for (int i = widths.size() - 1; i >= 0; i--) {
0257     int mask = ((1 << widths[i].second) - 1) << start_ofs;
0258     output[i] = (value & mask) >> start_ofs;
0259     start_ofs += widths[i].second;
0260   }
0261 
0262   return output;
0263 }
0264 
0265 //--------------------------------------------------------------------------------
0266 
0267 //
0268 // the main lookup function
0269 // looks up either from the function or the table
0270 // checks the input and result ranges
0271 //
0272 unsigned L1MuGMTLUT::LookupPacked(int idx, unsigned address) const {
0273   if (!m_initialized) {
0274     edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT not initialized. ";
0275     return 0;
0276   }
0277   if (idx >= m_NLUTS) {
0278     edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT index exceeds range (0 to "
0279                                    << (m_NLUTS - 1) << ").";
0280     return 0;
0281   }
0282   if (address >= (unsigned)(1 << m_TotalInWidth)) {
0283     edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked: LUT input exceeds range (0 to "
0284                                    << ((1 << m_TotalInWidth) - 1) << ").";
0285     return 0;
0286   }
0287 
0288   unsigned value = 0;
0289   if (m_UseLookupFunction) {
0290     value = LookupFunctionPacked(idx, address);
0291   } else {
0292     value = m_Contents[idx][address];
0293   }
0294 
0295   // check range of output
0296   if (value >= (unsigned)(1 << m_TotalOutWidth)) {
0297     edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::LookupPacked(): LUT output value " << value
0298                                    << " exceeds range (0 to " << ((1 << m_TotalOutWidth) - 1) << ").";
0299     edm::LogWarning("LUTMismatch") << "  LUT name: " << m_name;
0300     if (m_UseLookupFunction)
0301       edm::LogWarning("LUTMismatch") << "  Lookup Function has to be corrected!!!";
0302     else
0303       edm::LogWarning("LUTMismatch") << "  LUT File has to be corrected!!!";
0304     return (1 << m_TotalOutWidth) - 1;
0305   }
0306   return value;
0307 }
0308 
0309 #endif