L1MuPacking

L1MuPseudoSignedPacking

L1MuSignedPacking

L1MuSignedPackingGeneric

L1MuUnsignedPacking

L1MuUnsignedPackingGeneric

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
//-------------------------------------------------
//
/* L1MuPacking
 *
 * define abstract packing and three implementations
 *
*/
//
//   $Date: 2008/04/16 23:25:10 $
//   $Revision: 1.4 $
//
//   Original Author :
//   H. Sakulin            HEPHY Vienna
//
//   Migrated to CMSSW:
//   I. Mikulec
//
//--------------------------------------------------

#ifndef CondFormatsL1TObjects_L1MuPacking_h
#define CondFormatsL1TObjects_L1MuPacking_h

#include "CondFormats/Serialization/interface/Serializable.h"

#include "FWCore/MessageLogger/interface/MessageLogger.h"

#include <cstdlib>
#include <limits>

/**
 * \class L1MuPacking
 *
 *  Abstract Packing of an int in a bit-field
*/

class L1MuPacking {
public:
  virtual ~L1MuPacking() {}

  /// get the sign from the packed notation (0=positive, 1=negative)
  virtual int signFromPacked(unsigned packed) const = 0;
  /// get the value from the packed notation
  virtual int idxFromPacked(unsigned packed) const = 0;
  /// get the packed notation of a value
  virtual unsigned packedFromIdx(int idx) const = 0;

  COND_SERIALIZABLE;
};

/**
 * \class L1MuUnsignedPacking
 *
 * Packing of an unsigned int in a bit field
*/

template <unsigned int Bits>
class L1MuUnsignedPacking : public L1MuPacking {
public:
  /// get the sign from the packed notation. always psitive (0)
  int signFromPacked(unsigned packed) const override { return 0; };
  /// get the value from the packed notation (always positive)
  int idxFromPacked(unsigned packed) const override { return (int)packed; };
  /// get the packed notation of a value, check the range
  unsigned packedFromIdx(int idx) const override {
    if (idx >= (1 << Bits))
      edm::LogWarning("ScaleRangeViolation")
          << "L1MuUnignedPacking::packedFromIdx: warning value " << idx << "exceeds " << Bits << "-bit range !!!";
    return (unsigned)idx;
  };
};

class L1MuUnsignedPackingGeneric : public L1MuPacking {
public:
  /// get the sign from the packed notation. always psitive (0)
  static int signFromPacked(unsigned packed, unsigned int nbits) { return 0; };
  /// get the value from the packed notation (always positive)
  static int idxFromPacked(unsigned packed, unsigned int nbits) { return (int)packed; };
  /// get the packed notation of a value, check the range
  static unsigned packedFromIdx(int idx, unsigned int nbits) {
    if (idx >= (1 << nbits))
      edm::LogWarning("ScaleRangeViolation")
          << "L1MuUnignedPacking::packedFromIdx: warning value " << idx << "exceeds " << nbits << "-bit range !!!";
    return (unsigned)idx;
  };

private:
  int signFromPacked(unsigned packed) const = 0;
  int idxFromPacked(unsigned packed) const = 0;
  unsigned packedFromIdx(int idx) const = 0;
};

/**
 * \class L1MuSignedPacking
 *
 * Packing of a signed int in a bit field (2's complement)
*/

template <unsigned int Bits>
class L1MuSignedPacking : public L1MuPacking {
public:
  /// get the sign from the packed notation (0=positive, 1=negative)
  int signFromPacked(unsigned packed) const override { return packed & (1 << (Bits - 1)) ? 1 : 0; };

  /// get the value from the packed notation (+/-)
  int idxFromPacked(unsigned packed) const override {
    return packed & (1 << (Bits - 1)) ? (packed - (1 << Bits)) : packed;
  };
  /// get the packed notation of a value, check range
  unsigned packedFromIdx(int idx) const override {
    unsigned maxabs = 1U << (Bits - 1);
    if (idx < -(int)maxabs && idx >= (int)maxabs)
      edm::LogWarning("ScaleRangeViolation")
          << "L1MuSignedPacking::packedFromIdx: warning value " << idx << "exceeds " << Bits << "-bit range !!!";
    return ~(std::numeric_limits<unsigned>::max() << Bits) & (idx < 0 ? (1U << Bits) + idx : idx);
  };
};

class L1MuSignedPackingGeneric : public L1MuPacking {
public:
  /// get the sign from the packed notation (0=positive, 1=negative)
  static int signFromPacked(unsigned packed, unsigned int nbits) { return packed & (1 << (nbits - 1)) ? 1 : 0; };

  /// get the value from the packed notation (+/-)
  static int idxFromPacked(unsigned packed, unsigned int nbits) {
    return packed & (1 << (nbits - 1)) ? (packed - (1 << nbits)) : packed;
  };
  /// get the packed notation of a value, check range
  static unsigned packedFromIdx(int idx, unsigned int nbits) {
    unsigned maxabs = 1U << (nbits - 1);
    if (idx < -(int)maxabs && idx >= (int)maxabs)
      edm::LogWarning("ScaleRangeViolation")
          << "L1MuSignedPacking::packedFromIdx: warning value " << idx << "exceeds " << nbits << "-bit range !!!";
    return ~(std::numeric_limits<unsigned>::max() << nbits) & (idx < 0 ? (1U << nbits) + idx : idx);
  };

private:
  int signFromPacked(unsigned packed) const = 0;
  int idxFromPacked(unsigned packed) const = 0;
  unsigned packedFromIdx(int idx) const = 0;
};

/**
 * \class L1MuPseudoSignedPacking
 *
 * Packing of a signed int in a bit field (pseudo-sign)
 *
 * There is a -0 and a +0 in the pseudo-signed scale
*/

class L1MuPseudoSignedPacking : public L1MuPacking {
public:
  L1MuPseudoSignedPacking() {}
  ~L1MuPseudoSignedPacking() override {}
  L1MuPseudoSignedPacking(unsigned int nbits) : m_nbits(nbits) {}

  /// get the (pseudo-)sign from the packed notation (0=positive, 1=negative)
  int signFromPacked(unsigned packed) const override { return (packed & (1 << (m_nbits - 1))) ? 1 : 0; };

  /// get the value from the packed notation (+/-)
  int idxFromPacked(unsigned packed) const override {
    unsigned mask = (1 << (m_nbits - 1)) - 1;  // for lower bits
    int absidx = (int)(packed & mask);
    unsigned psmask = (1 << (m_nbits - 1));
    return absidx * (((packed & psmask) == psmask) ? -1 : 1);  // pseudo sign==1 is negative
  };
  /// get the packed notation of a value, check range
  unsigned packedFromIdx(int idx) const override {
    unsigned packed = std::abs(idx);
    unsigned maxabs = (1 << (m_nbits - 1)) - 1;
    if (packed > maxabs)
      edm::LogWarning("ScaleRangeViolation") << "L1MuPseudoSignedPacking::packedFromIdx: warning value " << idx
                                             << "exceeds " << m_nbits << "-bit range !!!";
    if (idx < 0)
      packed |= 1 << (m_nbits - 1);
    return packed;
  }

  /// get the packed notation of a value, check range; sets the sign separately, 1 is neg. sign(!)
  virtual unsigned packedFromIdx(int idx, int sig) const {
    unsigned packed = std::abs(idx);
    unsigned maxabs = (1 << (m_nbits - 1)) - 1;
    if (packed > maxabs)
      edm::LogWarning("ScaleRangeViolation") << "L1MuPseudoSignedPacking::packedFromIdx: warning value " << idx
                                             << "exceeds " << m_nbits << "-bit range !!!";
    if (sig == 1)
      packed |= 1 << (m_nbits - 1);  // sig==1 is negative
    return packed;
  }

private:
  unsigned int m_nbits;

  COND_SERIALIZABLE;
};

#endif