Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:51:17

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 
0087 /**
0088  * \class L1MuSignedPacking
0089  *
0090  * Packing of a signed int in a bit field (2's complement)
0091 */
0092 
0093 template <unsigned int Bits>
0094 class L1MuSignedPacking : public L1MuPacking {
0095 public:
0096   /// get the sign from the packed notation (0=positive, 1=negative)
0097   int signFromPacked(unsigned packed) const override { return packed & (1 << (Bits - 1)) ? 1 : 0; };
0098 
0099   /// get the value from the packed notation (+/-)
0100   int idxFromPacked(unsigned packed) const override {
0101     return packed & (1 << (Bits - 1)) ? (packed - (1 << Bits)) : packed;
0102   };
0103   /// get the packed notation of a value, check range
0104   unsigned packedFromIdx(int idx) const override {
0105     unsigned maxabs = 1U << (Bits - 1);
0106     if (idx < -(int)maxabs && idx >= (int)maxabs)
0107       edm::LogWarning("ScaleRangeViolation")
0108           << "L1MuSignedPacking::packedFromIdx: warning value " << idx << "exceeds " << Bits << "-bit range !!!";
0109     return ~(std::numeric_limits<unsigned>::max() << Bits) & (idx < 0 ? (1U << Bits) + idx : idx);
0110   };
0111 };
0112 
0113 class L1MuSignedPackingGeneric : public L1MuPacking {
0114 public:
0115   /// get the sign from the packed notation (0=positive, 1=negative)
0116   static int signFromPacked(unsigned packed, unsigned int nbits) { return packed & (1 << (nbits - 1)) ? 1 : 0; };
0117 
0118   /// get the value from the packed notation (+/-)
0119   static int idxFromPacked(unsigned packed, unsigned int nbits) {
0120     return packed & (1 << (nbits - 1)) ? (packed - (1 << nbits)) : packed;
0121   };
0122   /// get the packed notation of a value, check range
0123   static unsigned packedFromIdx(int idx, unsigned int nbits) {
0124     unsigned maxabs = 1U << (nbits - 1);
0125     if (idx < -(int)maxabs && idx >= (int)maxabs)
0126       edm::LogWarning("ScaleRangeViolation")
0127           << "L1MuSignedPacking::packedFromIdx: warning value " << idx << "exceeds " << nbits << "-bit range !!!";
0128     return ~(std::numeric_limits<unsigned>::max() << nbits) & (idx < 0 ? (1U << nbits) + idx : idx);
0129   };
0130 };
0131 
0132 /**
0133  * \class L1MuPseudoSignedPacking
0134  *
0135  * Packing of a signed int in a bit field (pseudo-sign)
0136  *
0137  * There is a -0 and a +0 in the pseudo-signed scale
0138 */
0139 
0140 class L1MuPseudoSignedPacking : public L1MuPacking {
0141 public:
0142   L1MuPseudoSignedPacking() {}
0143   ~L1MuPseudoSignedPacking() override{};
0144   L1MuPseudoSignedPacking(unsigned int nbits) : m_nbits(nbits){};
0145 
0146   /// get the (pseudo-)sign from the packed notation (0=positive, 1=negative)
0147   int signFromPacked(unsigned packed) const override { return (packed & (1 << (m_nbits - 1))) ? 1 : 0; };
0148 
0149   /// get the value from the packed notation (+/-)
0150   int idxFromPacked(unsigned packed) const override {
0151     unsigned mask = (1 << (m_nbits - 1)) - 1;  // for lower bits
0152     int absidx = (int)(packed & mask);
0153     unsigned psmask = (1 << (m_nbits - 1));
0154     return absidx * (((packed & psmask) == psmask) ? -1 : 1);  // pseudo sign==1 is negative
0155   };
0156   /// get the packed notation of a value, check range
0157   unsigned packedFromIdx(int idx) const override {
0158     unsigned packed = std::abs(idx);
0159     unsigned maxabs = (1 << (m_nbits - 1)) - 1;
0160     if (packed > maxabs)
0161       edm::LogWarning("ScaleRangeViolation") << "L1MuPseudoSignedPacking::packedFromIdx: warning value " << idx
0162                                              << "exceeds " << m_nbits << "-bit range !!!";
0163     if (idx < 0)
0164       packed |= 1 << (m_nbits - 1);
0165     return packed;
0166   }
0167 
0168   /// get the packed notation of a value, check range; sets the sign separately, 1 is neg. sign(!)
0169   virtual unsigned packedFromIdx(int idx, int sig) const {
0170     unsigned packed = std::abs(idx);
0171     unsigned maxabs = (1 << (m_nbits - 1)) - 1;
0172     if (packed > maxabs)
0173       edm::LogWarning("ScaleRangeViolation") << "L1MuPseudoSignedPacking::packedFromIdx: warning value " << idx
0174                                              << "exceeds " << m_nbits << "-bit range !!!";
0175     if (sig == 1)
0176       packed |= 1 << (m_nbits - 1);  // sig==1 is negative
0177     return packed;
0178   }
0179 
0180 private:
0181   unsigned int m_nbits;
0182 
0183   COND_SERIALIZABLE;
0184 };
0185 
0186 #endif