VertexBitLocations

VertexBitWidths

VertexWord

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 197 198 199 200 201
#ifndef DataFormats_L1TVertex_VertexWord_h
#define DataFormats_L1TVertex_VertexWord_h

////////
//
// class to store the 96-bit track word produced by the L1 Track Trigger.  Intended to be inherited by L1 TTTrack.
// packing scheme given below.
//
// author:      Alexx Perloff
// created:     March 17, 2021
// modified by:    Nick Manganelli
// modified:    November 18, 2022
//
///////

#include "DataFormats/L1Trigger/interface/Vertex.h"

#include <ap_int.h>
#include <ap_fixed.h>

#include <bitset>
#include <vector>

namespace l1t {

  class VertexWord {
  public:
    // ----------constants, enums and typedefs ---------
    enum VertexBitWidths {
      // The sizes of the vertex word components and total word size
      kValidSize = 1,         // Width of the valid bit
      kZ0Size = 15,           // Width of z-position
      kZ0MagSize = 6,         // Width of z-position magnitude (signed)
      kNTrackInPVSize = 8,    // Width of the multiplicity in the PV (unsigned)
      kSumPtSize = 12,        // Width of pT
      kSumPtMagSize = 10,     // Width of pT magnitude (unsigned)
      kQualitySize = 3,       // Width of the quality field
      kNTrackOutPVSize = 10,  // Width of the multiplicity outside the PV (unsigned)
      kUnassignedSize = 15,   // Width of the unassigned bits

      kVertexWordSize = kValidSize + kZ0Size + kNTrackInPVSize + kSumPtSize + kQualitySize + kNTrackOutPVSize +
                        kUnassignedSize,  // Width of the vertex word in bits
    };

    enum VertexBitLocations {
      // The location of the least significant bit (LSB) and most significant bit (MSB) in the vertex word for different fields
      kValidLSB = 0,
      kValidMSB = kValidLSB + VertexBitWidths::kValidSize - 1,
      kZ0LSB = kValidMSB + 1,
      kZ0MSB = kZ0LSB + VertexBitWidths::kZ0Size - 1,
      kNTrackInPVLSB = kZ0MSB + 1,
      kNTrackInPVMSB = kNTrackInPVLSB + VertexBitWidths::kNTrackInPVSize - 1,
      kSumPtLSB = kNTrackInPVMSB + 1,
      kSumPtMSB = kSumPtLSB + VertexBitWidths::kSumPtSize - 1,
      kQualityLSB = kSumPtMSB + 1,
      kQualityMSB = kQualityLSB + VertexBitWidths::kQualitySize - 1,
      kNTrackOutPVLSB = kQualityMSB + 1,
      kNTrackOutPVMSB = kNTrackOutPVLSB + VertexBitWidths::kNTrackOutPVSize - 1,
      kUnassignedLSB = kNTrackOutPVMSB + 1,
      kUnassignedMSB = kUnassignedLSB + VertexBitWidths::kUnassignedSize - 1
    };

    // vertex parameters types
    typedef ap_uint<VertexBitWidths::kValidSize> vtxvalid_t;  // Vertex validity
    typedef ap_fixed<VertexBitWidths::kZ0Size, VertexBitWidths::kZ0MagSize, AP_RND_CONV, AP_SAT> vtxz0_t;  // Vertex z0
    typedef ap_ufixed<VertexBitWidths::kNTrackInPVSize, VertexBitWidths::kNTrackInPVSize, AP_RND_CONV, AP_SAT>
        vtxmultiplicity_t;  // NTracks in vertex
    typedef ap_ufixed<VertexBitWidths::kSumPtSize, VertexBitWidths::kSumPtMagSize, AP_RND_CONV, AP_SAT>
        vtxsumpt_t;                                               // Vertex Sum pT
    typedef ap_uint<VertexBitWidths::kQualitySize> vtxquality_t;  // Vertex quality
    typedef ap_ufixed<VertexBitWidths::kNTrackOutPVSize, VertexBitWidths::kNTrackOutPVSize, AP_RND_CONV, AP_SAT>
        vtxinversemult_t;                                               // NTracks outside vertex
    typedef ap_uint<VertexBitWidths::kUnassignedSize> vtxunassigned_t;  // Unassigned bits

    // vertex word types
    typedef std::bitset<VertexBitWidths::kVertexWordSize> vtxword_bs_t;  // Entire track word;
    typedef ap_uint<VertexBitWidths::kVertexWordSize> vtxword_t;         // Entire vertex word;

    // reference types
    typedef edm::Ref<l1t::VertexCollection> VertexRef;  // Reference to a persistent l1t::Vertex

  public:
    // ----------Constructors --------------------------
    VertexWord() {}
    VertexWord(unsigned int valid,
               double z0,
               unsigned int multiplicity,
               double pt,
               unsigned int quality,
               unsigned int inverseMultiplicity,
               unsigned int unassigned);
    VertexWord(unsigned int valid,
               unsigned int z0,
               unsigned int multiplicity,
               unsigned int pt,
               unsigned int quality,
               unsigned int inverseMultiplicity,
               unsigned int unassigned);
    VertexWord(vtxvalid_t valid,
               vtxz0_t z0,
               vtxmultiplicity_t multiplicity,
               vtxsumpt_t pt,
               vtxquality_t quality,
               vtxinversemult_t inverseMultiplicity,
               vtxunassigned_t unassigned);

    ~VertexWord() {}

    // ----------copy constructor ----------------------
    VertexWord(const VertexWord& word) { vertexWord_ = word.vertexWord_; }

    // ----------operators -----------------------------
    VertexWord& operator=(const VertexWord& word) {
      vertexWord_ = word.vertexWord_;
      return *this;
    }

    // ----------member functions (getters) ------------
    // These functions return arbitarary precision words (lists of bits) for each quantity
    vtxvalid_t validWord() const { return vertexWord()(VertexBitLocations::kValidMSB, VertexBitLocations::kValidLSB); }
    vtxz0_t z0Word() const {
      vtxz0_t ret;
      ret.V = vertexWord()(VertexBitLocations::kZ0MSB, VertexBitLocations::kZ0LSB);
      return ret;
    }
    vtxmultiplicity_t multiplicityWord() const {
      return vertexWord()(VertexBitLocations::kNTrackInPVMSB, VertexBitLocations::kNTrackInPVLSB);
    }
    vtxsumpt_t ptWord() const {
      vtxsumpt_t ret;
      ret.V = vertexWord()(VertexBitLocations::kSumPtMSB, VertexBitLocations::kSumPtLSB);
      return ret;
    }
    vtxquality_t qualityWord() const {
      return vertexWord()(VertexBitLocations::kQualityMSB, VertexBitLocations::kQualityLSB);
    }
    vtxinversemult_t inverseMultiplicityWord() const {
      return vertexWord()(VertexBitLocations::kNTrackOutPVMSB, VertexBitLocations::kNTrackOutPVLSB);
    }
    vtxunassigned_t unassignedWord() const {
      return vertexWord()(VertexBitLocations::kUnassignedMSB, VertexBitLocations::kUnassignedLSB);
    }
    vtxword_t vertexWord() const { return vtxword_t(vertexWord_.to_string().c_str(), 2); }

    // These functions return the packed bits in integer format for each quantity
    // Signed quantities have the sign enconded in the left-most bit.
    unsigned int validBits() const { return validWord().to_uint(); }
    unsigned int z0Bits() const { return z0Word().range().to_uint(); }
    unsigned int multiplicityBits() const { return multiplicityWord().to_uint(); }
    unsigned int ptBits() const { return ptWord().range().to_uint(); }
    unsigned int qualityBits() const { return qualityWord().to_uint(); }
    unsigned int inverseMultiplicityBits() const { return inverseMultiplicityWord().to_uint(); }
    unsigned int unassignedBits() const { return unassignedWord().to_uint(); }

    // These functions return the unpacked and converted values
    // These functions return real numbers converted from the digitized quantities by unpacking the 64-bit vertex word
    bool valid() const { return validWord().to_bool(); }
    double z0() const { return z0Word().to_double(); }
    unsigned int multiplicity() const { return multiplicityWord().to_uint(); }
    double pt() const { return ptWord().to_double(); }
    unsigned int quality() const { return qualityWord().to_uint(); }
    unsigned int inverseMultiplicity() const { return inverseMultiplicityWord().to_uint(); }
    unsigned int unassigned() const { return unassignedWord().to_uint(); }

    // return reference to floating point vertex
    VertexRef vertexRef() const { return vertexRef_; }

    // ----------member functions (setters) ------------
    void setVertexWord(vtxvalid_t valid,
                       vtxz0_t z0,
                       vtxmultiplicity_t multiplicity,
                       vtxsumpt_t pt,
                       vtxquality_t quality,
                       vtxinversemult_t inverseMultiplicity,
                       vtxunassigned_t unassigned);

    // set reference to floating point vertex
    void setVertexRef(const VertexRef& ref) { vertexRef_ = ref; }

  private:
    // ----------private member functions --------------
    double unpackSignedValue(unsigned int bits, unsigned int nBits, double lsb) const {
      int isign = 1;
      unsigned int digitized_maximum = (1 << nBits) - 1;
      if (bits & (1 << (nBits - 1))) {  // check the sign
        isign = -1;
        bits = (1 << (nBits + 1)) - bits;  // if negative, flip everything for two's complement encoding
      }
      return (double(bits & digitized_maximum) + 0.5) * lsb * isign;
    }

    // ----------member data ---------------------------
    vtxword_bs_t vertexWord_;
    VertexRef vertexRef_;
  };

  typedef std::vector<VertexWord> VertexWordCollection;
  typedef edm::Ref<VertexWordCollection> VertexWordRef;
}  // namespace l1t

#endif