CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/L1Trigger/GlobalMuonTrigger/src/L1MuGMTLUT.h

Go to the documentation of this file.
00001 //-------------------------------------------------
00002 //
00034 //
00035 //   $Date: 2012/02/10 14:19:28 $
00036 //   $Revision: 1.5 $
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     unsigned m_GeneralLUTVersion;
00212 };
00213 
00214 //--------------------------------------------------------------------------------
00215 
00216 unsigned L1MuGMTLUT::vec2u (const std::vector <unsigned>& vec, const std::vector<port>& widths) const{
00217   if (vec.size() != widths.size()) {
00218     edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: number of LUT inputs/outputs does not match definition";
00219     return (0);
00220   }
00221   
00222   unsigned value = 0;
00223   unsigned start_ofs=0;
00224 
00225   for (int i=vec.size()-1; i>=0; i--) {
00226     if ( vec[i] >= (unsigned) (1 << widths[i].second) ) {
00227       edm::LogWarning("LUTMismatch") << "Error in L1MuGMTLUT::vec2u: LUT input/output number " << i 
00228            << " exceeds range (0 to " << ( (1 << widths[i].second) -1 ) << ")." 
00229           ;
00230     }
00231     else
00232       value |= vec[i] << start_ofs;
00233     start_ofs += widths[i].second;
00234   }
00235   
00236   return (value);
00237 }
00238 
00239 //--------------------------------------------------------------------------------
00240 
00241 std::vector <unsigned> L1MuGMTLUT::u2vec (unsigned value, const std::vector<port>& widths) const {
00242   std::vector<unsigned> output( widths.size(), 0);
00243  
00244   unsigned start_ofs=0;
00245 
00246   for (int i=widths.size()-1; i>=0; i--) {
00247     int mask = ( (1 << widths[i].second) - 1 ) << start_ofs;
00248     output[i] = ( value & mask ) >> start_ofs;
00249     start_ofs += widths[i].second;
00250   }
00251 
00252   return output;
00253 }
00254 
00255 //--------------------------------------------------------------------------------
00256 
00257 //
00258 // the main lookup function
00259 // looks up either from the function or the table
00260 // checks the input and result ranges
00261 //
00262 unsigned L1MuGMTLUT::LookupPacked (int idx, unsigned address) const {
00263   if (! m_initialized) {
00264     edm::LogWarning("LUTMismatch")  << "Error in L1MuGMTLUT::LookupPacked: LUT not initialized. ";
00265     return 0;
00266   }
00267   if ( idx >= m_NLUTS ) {
00268     edm::LogWarning("LUTMismatch")  << "Error in L1MuGMTLUT::LookupPacked: LUT index exceeds range (0 to " << ( m_NLUTS -1 ) << ")." 
00269         ;
00270     return 0;
00271   }
00272   if ( address >= (unsigned) (1 << m_TotalInWidth) ) {
00273     edm::LogWarning("LUTMismatch")  << "Error in L1MuGMTLUT::LookupPacked: LUT input exceeds range (0 to " << ( (1 << m_TotalInWidth) -1 ) << ")." 
00274         ;
00275     return 0;
00276   }
00277 
00278   unsigned value = 0;
00279   if (m_UseLookupFunction) {
00280     value = LookupFunctionPacked (idx, address);
00281   } else {
00282     value = m_Contents[idx][address];
00283   }
00284 
00285   // check range of output
00286   if ( value >= (unsigned) (1 << m_TotalOutWidth) ) {
00287     edm::LogWarning("LUTMismatch")  << "Error in L1MuGMTLUT::LookupPacked(): LUT output value " << value
00288          << " exceeds range (0 to " << ( (1 << m_TotalOutWidth) -1 ) << ")." 
00289         ;
00290     edm::LogWarning("LUTMismatch")  << "  LUT name: " << m_name;
00291     if (m_UseLookupFunction) 
00292       edm::LogWarning("LUTMismatch")  << "  Lookup Function has to be corrected!!!";
00293     else
00294       edm::LogWarning("LUTMismatch")  << "  LUT File has to be corrected!!!";
00295     return (1 << m_TotalOutWidth) - 1;
00296   }
00297   return value;
00298 }
00299  
00300 #endif
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312