CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/L1Trigger/GlobalMuonTrigger/src/L1MuGMTLUT.h

Go to the documentation of this file.
00001 //-------------------------------------------------
00002 //
00034 //
00035 //   $Date: 2007/03/23 18:51:35 $
00036 //   $Revision: 1.4 $
00037 //
00038 //   Author :
00039 //   H. Sakulin            HEPHY Vienna
00040 //
00041 //   Migrated to CMSSW:
00042 //   I. Mikulec
00043 //
00044 //--------------------------------------------------
00045 #ifndef L1TriggerGlobalMuonTrigger_L1MuGMTLUT_h
00046 #define L1TriggerGlobalMuonTrigger_L1MuGMTLUT_h
00047 
00048 //---------------
00049 // C++ Headers --
00050 //---------------
00051 
00052 #include <vector>
00053 #include <iostream>
00054 //#include <sstream>
00055 #include <string>
00056 #include <stdlib.h>
00057 #include "stdio.h"
00058 
00059 //----------------------
00060 // Base Class Headers --
00061 //----------------------
00062 class L1MuGMTLUTConverter;
00063 
00064 //------------------------------------
00065 // Collaborating Class Declarations --
00066 //------------------------------------
00067 #include <L1Trigger/GlobalMuonTrigger/src/L1MuGMTLUTHelpers.h>
00068 
00069 
00070 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00071 
00072 
00073 //              ---------------------
00074 //              -- Class Interface --
00075 //              ---------------------
00076 
00077 class L1MuGMTLUT {
00078 
00079   public:  
00080     typedef std::pair<std::string, unsigned> port;
00081 
00083 
00085     L1MuGMTLUT() : m_initialized(0), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {};
00086 
00088     L1MuGMTLUT(const char* name, 
00089                const std::vector<std::string>&  instances, 
00090                const std::vector<port>& in_widths, 
00091                const std::vector<port>& out_widths, 
00092                unsigned vme_addr_width=0, bool distrRAM=false) : m_initialized(0), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {
00093       Init (name, instances, in_widths, out_widths, vme_addr_width, distrRAM); 
00094       };
00095 
00096     L1MuGMTLUT(const char* name, 
00097                const std::string& instances, 
00098                const std::string& inputs, 
00099                const std::string& outputs, 
00100                unsigned vme_addr_width=0, bool distrRAM=false) : m_initialized(0), m_NLUTS(0), m_UseLookupFunction(true), m_saveFlag(false) {
00101       Init (name, L1MuGMTLUTHelpers::Tokenizer(" ",instances), PortDecoder(inputs), PortDecoder(outputs), 
00102             vme_addr_width, distrRAM); 
00103       };
00104 
00106     virtual ~L1MuGMTLUT();
00107 
00110     inline unsigned LookupPacked (int idx, unsigned ) const;
00111 
00113     inline unsigned LookupPacked (int idx, const std::vector<unsigned>& address) const { 
00114       return LookupPacked (idx, vec2u ( address, m_Inputs ) ); };
00115 
00117     inline std::vector<unsigned> Lookup (int idx, const std::vector<unsigned>& address) const { 
00118       return Lookup (idx, vec2u ( address, m_Inputs ) ); };
00119 
00121     inline std::vector<unsigned> Lookup (int idx, unsigned address) const {
00122       return u2vec ( LookupPacked(idx, address), m_Outputs );
00123     };
00124 
00125     
00127     
00129     void Load (const char* path);
00130     
00132     void Save (const char* path);    
00133 
00136     virtual unsigned LookupFunctionPacked (int idx, unsigned address) const { return 0; };
00137 
00139     void MakeSubClass (const char* fname = "", const char* template_file_h = "../interface/L1MuGMTLUT_SubClass.h_template",
00140                        const char* template_file_cc = "../interface/L1MuGMTLUT_SubClass.cc_template");
00141 
00142     std::string Name() {return m_name;};
00143 
00144     friend class L1MuGMTLUTConverter;
00145 
00147     int numberOfInstances() { return m_NLUTS; };
00148 
00149   protected:
00150 
00152     void Init(const char* name, const std::vector<std::string>& instances, 
00153               const std::vector<port>& in_widths, const std::vector<port>& out_widths, 
00154               unsigned vme_addr_width=0, bool distrRAM=false);
00155 
00157     inline unsigned vec2u (const std::vector <unsigned>& vec, const std::vector<port>& widths) const;
00158 
00160     inline std::vector<unsigned> u2vec (unsigned value, const std::vector<port>& widths) const;
00161 
00163     void Set (int idx, unsigned address, unsigned value);  
00164 
00165     class PortDecoder : public std::vector<port> { 
00166       typedef std::vector<port> base;
00167       public:
00168       PortDecoder(const std::vector<port> &pt) : base(pt) {};
00169 
00170       PortDecoder(const std::string& input){
00171         // decode std::string of style "phi(2) eta(4)"
00172         L1MuGMTLUTHelpers::Tokenizer tok(" ", input);
00173         for (unsigned int i=0;i<tok.size(); i++) {
00174           size_type obrace=tok[i].find("("), cbrace=tok[i].find(")");
00175           if (obrace != std::string::npos && cbrace != std::string::npos) 
00176             push_back( port ( tok[i].substr(0,obrace), (unsigned) atoi (tok[i].substr(obrace+1,cbrace-obrace-1).c_str() ) ) );
00177           else 
00178             edm::LogWarning("LUTMismatch") << "L1MuGMTLUT::PortDecoder: error decoding port " << tok[i]; 
00179         }
00180       };
00181       std::string str() {
00182         std::string temp;
00183         for  (unsigned int i=0; i<size();i++) {
00184           // ostd::stringstream os; os << (*this)[i].second << ends;
00185           //      temp += (*this)[i].first + "(" + std::string( os.str() ) + ")";
00186           
00187           char buf[100]; sprintf(buf,"(%d)",(*this)[i].second);
00188           temp += (*this)[i].first + std::string(buf);
00189 
00190           if (i!=size()-1) temp += " ";
00191         }
00192         return temp;
00193       };
00194       
00195     private:
00196     };
00197 
00198     bool m_initialized;
00199     int m_NLUTS; 
00200     bool m_UseLookupFunction;
00201     std::vector <std::string> m_InstNames;
00202     std::vector <std::vector <unsigned> > m_Contents;
00203     std::vector <port> m_Inputs;                  // first port in vector is most significant bits
00204     std::vector <port> m_Outputs;
00205     unsigned m_TotalInWidth;
00206     unsigned m_TotalOutWidth;
00207     unsigned m_vme_addr_width;
00208     bool m_distrRAM;
00209     std::string m_name;
00210     bool m_saveFlag;
00211 };
00212 
00213 //--------------------------------------------------------------------------------
00214 
00215 unsigned L1MuGMTLUT::vec2u (const std::vector <unsigned>& vec, const std::vector<port>& widths) const{
00216   if (vec.size() != widths.size()) {
00217     edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: number of LUT inputs/outputs does not match definition";
00218     return (0);
00219   }
00220   
00221   unsigned value = 0;
00222   unsigned start_ofs=0;
00223 
00224   for (int i=vec.size()-1; i>=0; i--) {
00225     if ( vec[i] >= (unsigned) (1 << widths[i].second) ) {
00226       edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: LUT input/output number " << i 
00227            << " exceeds range (0 to " << ( (1 << widths[i].second) -1 ) << ")." 
00228           ;
00229     }
00230     else
00231       value |= vec[i] << start_ofs;
00232     start_ofs += widths[i].second;
00233   }
00234   
00235   return (value);
00236 }
00237 
00238 //--------------------------------------------------------------------------------
00239 
00240 std::vector <unsigned> L1MuGMTLUT::u2vec (unsigned value, const std::vector<port>& widths) const {
00241   std::vector<unsigned> output( widths.size(), 0);
00242  
00243   unsigned start_ofs=0;
00244 
00245   for (int i=widths.size()-1; i>=0; i--) {
00246     int mask = ( (1 << widths[i].second) - 1 ) << start_ofs;
00247     output[i] = ( value & mask ) >> start_ofs;
00248     start_ofs += widths[i].second;
00249   }
00250 
00251   return output;
00252 }
00253 
00254 //--------------------------------------------------------------------------------
00255 
00256 //
00257 // the main lookup function
00258 // looks up either from the function or the table
00259 // checks the input and result ranges
00260 //
00261 unsigned L1MuGMTLUT::LookupPacked (int idx, unsigned address) const {
00262   if (! m_initialized) {
00263     edm::LogWarning("LUTMismatch")  << "Error in L1MuGMTLUT::LookupPacked: LUT not initialized. ";
00264     return 0;
00265   }
00266   if ( idx >= m_NLUTS ) {
00267     edm::LogWarning("LUTMismatch")  << "Error in L1MuGMTLUT::LookupPacked: LUT index exceeds range (0 to " << ( m_NLUTS -1 ) << ")." 
00268         ;
00269     return 0;
00270   }
00271   if ( address >= (unsigned) (1 << m_TotalInWidth) ) {
00272     edm::LogWarning("LUTMismatch")  << "Error in L1MuGMTLUT::LookupPacked: LUT input exceeds range (0 to " << ( (1 << m_TotalInWidth) -1 ) << ")." 
00273         ;
00274     return 0;
00275   }
00276 
00277   unsigned value = 0;
00278   if (m_UseLookupFunction) {
00279     value = LookupFunctionPacked (idx, address);
00280   } else {
00281     value = m_Contents[idx][address];
00282   }
00283 
00284   // check range of output
00285   if ( value >= (unsigned) (1 << m_TotalOutWidth) ) {
00286     edm::LogWarning("LUTMismatch")  << "Error in L1MuGMTLUT::LookupPacked(): LUT output value " << value
00287          << " exceeds range (0 to " << ( (1 << m_TotalOutWidth) -1 ) << ")." 
00288         ;
00289     edm::LogWarning("LUTMismatch")  << "  LUT name: " << m_name;
00290     if (m_UseLookupFunction) 
00291       edm::LogWarning("LUTMismatch")  << "  Lookup Function has to be corrected!!!";
00292     else
00293       edm::LogWarning("LUTMismatch")  << "  LUT File has to be corrected!!!";
00294     return (1 << m_TotalOutWidth) - 1;
00295   }
00296   return value;
00297 }
00298  
00299 #endif
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311