Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-12 04:16:16

0001 //-------------------------------------------------
0002 //
0003 /* L1MuPacking
0004  *
0005  * define abstract packing and three implementations
0006  *
0007 */
0008 //
0009 //   $Date: 2008/04/16 23:25:10 $
0010 //   $Revision: 1.4 $
0011 //
0012 //   Original Author :
0013 //   H. Sakulin            HEPHY Vienna
0014 //
0015 //   Migrated to CMSSW:
0016 //   I. Mikulec
0017 //
0018 //--------------------------------------------------
0019 
0020 #ifndef CondFormatsL1TObjects_L1MuPacking_h
0021 #define CondFormatsL1TObjects_L1MuPacking_h
0022 
0023 #include "CondFormats/Serialization/interface/Serializable.h"
0024 
0025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0026 
0027 #include <cstdlib>
0028 #include <limits>
0029 
0030 /**
0031  * \class L1MuPacking
0032  *
0033  *  Abstract Packing of an int in a bit-field
0034 */
0035 
0036 class L1MuPacking {
0037 public:
0038   virtual ~L1MuPacking() {}
0039 
0040   /// get the sign from the packed notation (0=positive, 1=negative)
0041   virtual int signFromPacked(unsigned packed) const = 0;
0042   /// get the value from the packed notation
0043   virtual int idxFromPacked(unsigned packed) const = 0;
0044   /// get the packed notation of a value
0045   virtual unsigned packedFromIdx(int idx) const = 0;
0046 
0047   COND_SERIALIZABLE;
0048 };
0049 
0050 /**
0051  * \class L1MuUnsignedPacking
0052  *
0053  * Packing of an unsigned int in a bit field
0054 */
0055 
0056 template <unsigned int Bits>
0057 class L1MuUnsignedPacking : public L1MuPacking {
0058 public:
0059   /// get the sign from the packed notation. always psitive (0)
0060   int signFromPacked(unsigned packed) const override { return 0; };
0061   /// get the value from the packed notation (always positive)
0062   int idxFromPacked(unsigned packed) const override { return (int)packed; };
0063   /// get the packed notation of a value, check the range
0064   unsigned packedFromIdx(int idx) const override {
0065     if (idx >= (1 << Bits))
0066       edm::LogWarning("ScaleRangeViolation")
0067           << "L1MuUnignedPacking::packedFromIdx: warning value " << idx << "exceeds " << Bits << "-bit range !!!";
0068     return (unsigned)idx;
0069   };
0070 };
0071 
0072 class L1MuUnsignedPackingGeneric : public L1MuPacking {
0073 public:
0074   /// get the sign from the packed notation. always psitive (0)
0075   static int signFromPacked(unsigned packed, unsigned int nbits) { return 0; };
0076   /// get the value from the packed notation (always positive)
0077   static int idxFromPacked(unsigned packed, unsigned int nbits) { return (int)packed; };
0078   /// get the packed notation of a value, check the range
0079   static unsigned packedFromIdx(int idx, unsigned int nbits) {
0080     if (idx >= (1 << nbits))
0081       edm::LogWarning("ScaleRangeViolation")
0082           << "L1MuUnignedPacking::packedFromIdx: warning value " << idx << "exceeds " << nbits << "-bit range !!!";
0083     return (unsigned)idx;
0084   };
0085 
0086 private:
0087   int signFromPacked(unsigned packed) const = 0;
0088   int idxFromPacked(unsigned packed) const = 0;
0089   unsigned packedFromIdx(int idx) const = 0;
0090 };
0091 
0092 /**
0093  * \class L1MuSignedPacking
0094  *
0095  * Packing of a signed int in a bit field (2's complement)
0096 */
0097 
0098 template <unsigned int Bits>
0099 class L1MuSignedPacking : public L1MuPacking {
0100 public:
0101   /// get the sign from the packed notation (0=positive, 1=negative)
0102   int signFromPacked(unsigned packed) const override { return packed & (1 << (Bits - 1)) ? 1 : 0; };
0103 
0104   /// get the value from the packed notation (+/-)
0105   int idxFromPacked(unsigned packed) const override {
0106     return packed & (1 << (Bits - 1)) ? (packed - (1 << Bits)) : packed;
0107   };
0108   /// get the packed notation of a value, check range
0109   unsigned packedFromIdx(int idx) const override {
0110     unsigned maxabs = 1U << (Bits - 1);
0111     if (idx < -(int)maxabs && idx >= (int)maxabs)
0112       edm::LogWarning("ScaleRangeViolation")
0113           << "L1MuSignedPacking::packedFromIdx: warning value " << idx << "exceeds " << Bits << "-bit range !!!";
0114     return ~(std::numeric_limits<unsigned>::max() << Bits) & (idx < 0 ? (1U << Bits) + idx : idx);
0115   };
0116 };
0117 
0118 class L1MuSignedPackingGeneric : public L1MuPacking {
0119 public:
0120   /// get the sign from the packed notation (0=positive, 1=negative)
0121   static int signFromPacked(unsigned packed, unsigned int nbits) { return packed & (1 << (nbits - 1)) ? 1 : 0; };
0122 
0123   /// get the value from the packed notation (+/-)
0124   static int idxFromPacked(unsigned packed, unsigned int nbits) {
0125     return packed & (1 << (nbits - 1)) ? (packed - (1 << nbits)) : packed;
0126   };
0127   /// get the packed notation of a value, check range
0128   static unsigned packedFromIdx(int idx, unsigned int nbits) {
0129     unsigned maxabs = 1U << (nbits - 1);
0130     if (idx < -(int)maxabs && idx >= (int)maxabs)
0131       edm::LogWarning("ScaleRangeViolation")
0132           << "L1MuSignedPacking::packedFromIdx: warning value " << idx << "exceeds " << nbits << "-bit range !!!";
0133     return ~(std::numeric_limits<unsigned>::max() << nbits) & (idx < 0 ? (1U << nbits) + idx : idx);
0134   };
0135 
0136 private:
0137   int signFromPacked(unsigned packed) const = 0;
0138   int idxFromPacked(unsigned packed) const = 0;
0139   unsigned packedFromIdx(int idx) const = 0;
0140 };
0141 
0142 /**
0143  * \class L1MuPseudoSignedPacking
0144  *
0145  * Packing of a signed int in a bit field (pseudo-sign)
0146  *
0147  * There is a -0 and a +0 in the pseudo-signed scale
0148 */
0149 
0150 class L1MuPseudoSignedPacking : public L1MuPacking {
0151 public:
0152   L1MuPseudoSignedPacking() {}
0153   ~L1MuPseudoSignedPacking() override {}
0154   L1MuPseudoSignedPacking(unsigned int nbits) : m_nbits(nbits) {}
0155 
0156   /// get the (pseudo-)sign from the packed notation (0=positive, 1=negative)
0157   int signFromPacked(unsigned packed) const override { return (packed & (1 << (m_nbits - 1))) ? 1 : 0; };
0158 
0159   /// get the value from the packed notation (+/-)
0160   int idxFromPacked(unsigned packed) const override {
0161     unsigned mask = (1 << (m_nbits - 1)) - 1;  // for lower bits
0162     int absidx = (int)(packed & mask);
0163     unsigned psmask = (1 << (m_nbits - 1));
0164     return absidx * (((packed & psmask) == psmask) ? -1 : 1);  // pseudo sign==1 is negative
0165   };
0166   /// get the packed notation of a value, check range
0167   unsigned packedFromIdx(int idx) const override {
0168     unsigned packed = std::abs(idx);
0169     unsigned maxabs = (1 << (m_nbits - 1)) - 1;
0170     if (packed > maxabs)
0171       edm::LogWarning("ScaleRangeViolation") << "L1MuPseudoSignedPacking::packedFromIdx: warning value " << idx
0172                                              << "exceeds " << m_nbits << "-bit range !!!";
0173     if (idx < 0)
0174       packed |= 1 << (m_nbits - 1);
0175     return packed;
0176   }
0177 
0178   /// get the packed notation of a value, check range; sets the sign separately, 1 is neg. sign(!)
0179   virtual unsigned packedFromIdx(int idx, int sig) const {
0180     unsigned packed = std::abs(idx);
0181     unsigned maxabs = (1 << (m_nbits - 1)) - 1;
0182     if (packed > maxabs)
0183       edm::LogWarning("ScaleRangeViolation") << "L1MuPseudoSignedPacking::packedFromIdx: warning value " << idx
0184                                              << "exceeds " << m_nbits << "-bit range !!!";
0185     if (sig == 1)
0186       packed |= 1 << (m_nbits - 1);  // sig==1 is negative
0187     return packed;
0188   }
0189 
0190 private:
0191   unsigned int m_nbits;
0192 
0193   COND_SERIALIZABLE;
0194 };
0195 
0196 #endif