CMS 3D CMS Logo

TTTrack_TrackWord.h
Go to the documentation of this file.
1 #ifndef L1_TRACK_TRIGGER_TRACK_WORD_H
2 #define L1_TRACK_TRIGGER_TRACK_WORD_H
3 
5 //
6 // class to store the 96-bit track word produced by the L1 Track Trigger. Intended to be inherited by L1 TTTrack.
7 // packing scheme given below.
8 //
9 // author: Mike Hildreth
10 // modified by: Alexx Perloff
11 // created: April 9, 2019
12 // modified: March 9, 2021
13 //
15 
19 
20 #include <ap_int.h>
21 
22 #include <algorithm>
23 #include <array>
24 #include <bitset>
25 #include <cmath>
26 #include <limits>
27 #include <string>
28 #include <vector>
29 
30 namespace tttrack_trackword {
32  const unsigned int, const double, const double, const unsigned int, const double, const unsigned int);
33 }
34 
36 public:
37  // ----------constants, enums and typedefs ---------
39  // The sizes of the track word components
40  kMVAOtherSize = 6, // Space for two specialized MVA selections
41  kMVAQualitySize = 3, // Width of track quality MVA
42  kHitPatternSize = 7, // Width of the hit pattern for stubs
43  kBendChi2Size = 3, // Width of the bend-chi2/dof
44  kD0Size = 13, // Width of D0
45  kChi2RZSize = 4, // Width of chi2/dof for r-z
46  kZ0Size = 12, // Width of z-position (40cm / 0.1)
47  kTanlSize = 16, // Width of tan(lambda)
48  kChi2RPhiSize = 4, // Width of chi2/dof for r-phi
49  kPhiSize = 12, // Width of phi
50  kRinvSize = 15, // Width of Rinv
51  kValidSize = 1, // Valid bit
52 
55  kMVAOtherSize, // Width of the track word in bits
56  };
57 
59  // The location of the least significant bit (LSB) and most significant bit (MSB) in the track word for different fields
61  kMVAOtherMSB = kMVAOtherLSB + TrackBitWidths::kMVAOtherSize - 1,
63  kMVAQualityMSB = kMVAQualityLSB + TrackBitWidths::kMVAQualitySize - 1,
65  kHitPatternMSB = kHitPatternLSB + TrackBitWidths::kHitPatternSize - 1,
67  kBendChi2MSB = kBendChi2LSB + TrackBitWidths::kBendChi2Size - 1,
69  kD0MSB = kD0LSB + TrackBitWidths::kD0Size - 1,
71  kChi2RZMSB = kChi2RZLSB + TrackBitWidths::kChi2RZSize - 1,
73  kZ0MSB = kZ0LSB + TrackBitWidths::kZ0Size - 1,
75  kTanlMSB = kTanlLSB + TrackBitWidths::kTanlSize - 1,
77  kChi2RPhiMSB = kChi2RPhiLSB + TrackBitWidths::kChi2RPhiSize - 1,
79  kPhiMSB = kPhiLSB + TrackBitWidths::kPhiSize - 1,
81  kRinvMSB = kRinvLSB + TrackBitWidths::kRinvSize - 1,
84  };
85 
86  // Binning constants
87  static constexpr double minRinv = -0.006;
88  static constexpr double minPhi0 = -0.7853981696; // relative to the center of the sector
89  static constexpr double minTanl = -8.;
90  static constexpr double minZ0 = -20.46912512;
91  static constexpr double minD0 = -16.;
92 
93  static constexpr double stepRinv = (2. * std::abs(minRinv)) / (1 << TrackBitWidths::kRinvSize);
94  static constexpr double stepPhi0 = (2. * std::abs(minPhi0)) / (1 << TrackBitWidths::kPhiSize);
95  static constexpr double stepTanL = (1. / (1 << 12));
96  static constexpr double stepZ0 = (2. * std::abs(minZ0)) / (1 << TrackBitWidths::kZ0Size);
97  static constexpr double stepD0 = (1. / (1 << 8));
98 
99  // Bin edges for chi2/dof
100  static constexpr std::array<double, 1 << TrackBitWidths::kChi2RPhiSize> chi2RPhiBins = {
101  {0.0, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0, 10.0, 15.0, 20.0, 35.0, 60.0, 200.0}};
102  static constexpr std::array<double, 1 << TrackBitWidths::kChi2RZSize> chi2RZBins = {
103  {0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0, 20.0, 50.0}};
104  static constexpr std::array<double, 1 << TrackBitWidths::kBendChi2Size> bendChi2Bins = {
105  {0.0, 0.75, 1.0, 1.5, 2.25, 3.5, 5.0, 20.0}};
106 
107  // Sector constants
108  static constexpr unsigned int nSectors = 9;
109  static constexpr double sectorWidth = (2. * M_PI) / nSectors;
110 
111  // Track flags
112  typedef ap_uint<TrackBitWidths::kValidSize> valid_t; // valid bit
113 
114  // Track parameters types
115  typedef ap_uint<TrackBitWidths::kRinvSize> rinv_t; // Track Rinv
116  typedef ap_uint<TrackBitWidths::kPhiSize> phi_t; // Track phi
117  typedef ap_uint<TrackBitWidths::kTanlSize> tanl_t; // Track tan(l)
118  typedef ap_uint<TrackBitWidths::kZ0Size> z0_t; // Track z
119  typedef ap_uint<TrackBitWidths::kD0Size> d0_t; // D0
120 
121  // Track quality types
122  typedef ap_uint<TrackBitWidths::kChi2RPhiSize> chi2rphi_t; // Chi2 r-phi
123  typedef ap_uint<TrackBitWidths::kChi2RZSize> chi2rz_t; // Chi2 r-z
124  typedef ap_uint<TrackBitWidths::kBendChi2Size> bendChi2_t; // Bend-Chi2
125  typedef ap_uint<TrackBitWidths::kHitPatternSize> hit_t; // Hit mask bits
126  typedef ap_uint<TrackBitWidths::kMVAQualitySize> qualityMVA_t; // Track quality MVA
127  typedef ap_uint<TrackBitWidths::kMVAOtherSize> otherMVA_t; // Specialized MVA selection
128 
129  // Track word types
130  typedef std::bitset<TrackBitWidths::kTrackWordSize> tkword_bs_t; // Entire track word;
131  typedef ap_uint<TrackBitWidths::kTrackWordSize> tkword_t; // Entire track word;
132 
133 public:
134  // ----------Constructors --------------------------
136  TTTrack_TrackWord(unsigned int valid,
137  const GlobalVector& momentum,
138  const GlobalPoint& POCA,
139  double rInv,
140  double chi2RPhi, // would be xy chisq if chi2Z is non-zero
141  double chi2RZ,
142  double bendChi2,
143  unsigned int hitPattern,
144  unsigned int mvaQuality,
145  unsigned int mvaOther,
146  unsigned int sector);
147  TTTrack_TrackWord(unsigned int valid,
148  unsigned int rInv,
149  unsigned int phi0, // local phi
150  unsigned int tanl,
151  unsigned int z0,
152  unsigned int d0,
153  unsigned int chi2RPhi, // would be total chisq if chi2Z is zero
154  unsigned int chi2RZ,
155  unsigned int bendChi2,
156  unsigned int hitPattern,
157  unsigned int mvaQuality,
158  unsigned int mvaOther);
159 
160  // ----------copy constructor ----------------------
162 
163  // ----------operators -----------------------------
165  trackWord_ = word.trackWord_;
166  return *this;
167  }
168 
169  // ----------member functions (getters) ------------
170  // These functions return arbitarary precision unsigned int words (lists of bits) for each quantity
171  // Signed quantities have the sign enconded in the left-most bit.
173  rinv_t getRinvWord() const { return getTrackWord()(TrackBitLocations::kRinvMSB, TrackBitLocations::kRinvLSB); }
174  phi_t getPhiWord() const { return getTrackWord()(TrackBitLocations::kPhiMSB, TrackBitLocations::kPhiLSB); }
175  tanl_t getTanlWord() const { return getTrackWord()(TrackBitLocations::kTanlMSB, TrackBitLocations::kTanlLSB); }
176  z0_t getZ0Word() const { return getTrackWord()(TrackBitLocations::kZ0MSB, TrackBitLocations::kZ0LSB); }
177  d0_t getD0Word() const { return getTrackWord()(TrackBitLocations::kD0MSB, TrackBitLocations::kD0LSB); }
179  return getTrackWord()(TrackBitLocations::kChi2RPhiMSB, TrackBitLocations::kChi2RPhiLSB);
180  }
182  return getTrackWord()(TrackBitLocations::kChi2RZMSB, TrackBitLocations::kChi2RZLSB);
183  }
185  return getTrackWord()(TrackBitLocations::kBendChi2MSB, TrackBitLocations::kBendChi2LSB);
186  }
188  return getTrackWord()(TrackBitLocations::kHitPatternMSB, TrackBitLocations::kHitPatternLSB);
189  }
191  return getTrackWord()(TrackBitLocations::kMVAQualityMSB, TrackBitLocations::kMVAQualityLSB);
192  }
194  return getTrackWord()(TrackBitLocations::kMVAOtherMSB, TrackBitLocations::kMVAOtherLSB);
195  }
196  tkword_t getTrackWord() const { return tkword_t(trackWord_.to_string().c_str(), 2); }
197 
198  // These functions return the packed bits in unsigned integer format for each quantity
199  // Signed quantities have the sign enconded in the left-most bit of the pattern using
200  // a two's complement representation
201  unsigned int getValidBits() const { return getValidWord().to_uint(); }
202  unsigned int getRinvBits() const { return getRinvWord().to_uint(); }
203  unsigned int getPhiBits() const { return getPhiWord().to_uint(); }
204  unsigned int getTanlBits() const { return getTanlWord().to_uint(); }
205  unsigned int getZ0Bits() const { return getZ0Word().to_uint(); }
206  unsigned int getD0Bits() const { return getD0Word().to_uint(); }
207  unsigned int getChi2RPhiBits() const { return getChi2RPhiWord().to_uint(); }
208  unsigned int getChi2RZBits() const { return getChi2RZWord().to_uint(); }
209  unsigned int getBendChi2Bits() const { return getBendChi2Word().to_uint(); }
210  unsigned int getHitPatternBits() const { return getHitPatternWord().to_uint(); }
211  unsigned int getMVAQualityBits() const { return getMVAQualityWord().to_uint(); }
212  unsigned int getMVAOtherBits() const { return getMVAOtherWord().to_uint(); }
213 
214  // These functions return the unpacked and converted values
215  // These functions return real numbers converted from the digitized quantities by unpacking the 96-bit track word
216  bool getValid() const { return getValidWord().to_bool(); }
217  double getRinv() const { return undigitizeSignedValue(getRinvBits(), TrackBitWidths::kRinvSize, stepRinv); }
218  double getPhi() const { return undigitizeSignedValue(getPhiBits(), TrackBitWidths::kPhiSize, stepPhi0); }
219  double getTanl() const { return undigitizeSignedValue(getTanlBits(), TrackBitWidths::kTanlSize, stepTanL); }
220  double getZ0() const { return undigitizeSignedValue(getZ0Bits(), TrackBitWidths::kZ0Size, stepZ0); }
221  double getD0() const { return undigitizeSignedValue(getD0Bits(), TrackBitWidths::kD0Size, stepD0); }
222  double getChi2RPhi() const { return chi2RPhiBins[getChi2RPhiBits()]; }
223  double getChi2RZ() const { return chi2RZBins[getChi2RZBits()]; }
224  double getBendChi2() const { return bendChi2Bins[getBendChi2Bits()]; }
225  unsigned int getHitPattern() const { return getHitPatternBits(); }
226  unsigned int getNStubs() const { return countSetBits(getHitPatternBits()); }
227  unsigned int getMVAQuality() const { return getMVAQualityBits(); }
228  unsigned int getMVAOther() const { return getMVAOtherBits(); }
229 
230  // ----------member functions (setters) ------------
231  void setTrackWord(unsigned int valid,
232  const GlobalVector& momentum,
233  const GlobalPoint& POCA,
234  double rInv,
235  double chi2RPhi, // would be total chisq if chi2Z is zero
236  double chi2RZ,
237  double bendChi2,
238  unsigned int hitPattern,
239  unsigned int mvaQuality,
240  unsigned int mvaOther,
241  unsigned int sector);
242 
243  void setTrackWord(unsigned int valid,
244  unsigned int rInv,
245  unsigned int phi0, // local phi
246  unsigned int tanl,
247  unsigned int z0,
248  unsigned int d0,
249  unsigned int chi2RPhi, // would be total chisq if chi2Z is zero
250  unsigned int chi2RZ,
251  unsigned int bendChi2,
252  unsigned int hitPattern,
253  unsigned int mvaQuality,
254  unsigned int mvaOther);
255 
256  void setTrackWord(ap_uint<TrackBitWidths::kValidSize> valid,
257  ap_uint<TrackBitWidths::kRinvSize> rInv,
258  ap_uint<TrackBitWidths::kPhiSize> phi0, // local phi
259  ap_uint<TrackBitWidths::kTanlSize> tanl,
260  ap_uint<TrackBitWidths::kZ0Size> z0,
261  ap_uint<TrackBitWidths::kD0Size> d0,
262  ap_uint<TrackBitWidths::kChi2RPhiSize> chi2RPhi, // would be total chisq if chi2Z is zero
263  ap_uint<TrackBitWidths::kChi2RZSize> chi2RZ,
264  ap_uint<TrackBitWidths::kBendChi2Size> bendChi2,
265  ap_uint<TrackBitWidths::kHitPatternSize> hitPattern,
266  ap_uint<TrackBitWidths::kMVAQualitySize> mvaQuality,
267  ap_uint<TrackBitWidths::kMVAOtherSize> mvaOther);
268 
269  // ----------member functions (testers) ------------
270  bool singleDigitizationSchemeTest(const double floatingPointValue, const unsigned int nBits, const double lsb) const;
271  void testDigitizationScheme() const;
272 
273 protected:
274  // ----------protected member functions ------------
275  float localPhi(float globalPhi, unsigned int sector) const {
276  return reco::deltaPhi(globalPhi, (sector * sectorWidth));
277  }
278 
279 public:
280  // ----------public member functions --------------
281  unsigned int countSetBits(unsigned int n) const {
282  // Adapted from: https://www.geeksforgeeks.org/count-set-bits-in-an-integer/
283  unsigned int count = 0;
284  while (n) {
285  n &= (n - 1);
286  count++;
287  }
288  return count;
289  }
290 
291  unsigned int digitizeSignedValue(double value, unsigned int nBits, double lsb) const {
292  // Digitize the incoming value
293  int digitizedValue = std::floor(value / lsb);
294 
295  // Calculate the maxmum possible positive value given an output of nBits in size
296  int digitizedMaximum = (1 << (nBits - 1)) - 1; // The remove 1 bit from nBits to account for the sign
297  int digitizedMinimum = -1. * (digitizedMaximum + 1);
298 
299  // Saturate the digitized value
300  digitizedValue = std::clamp(digitizedValue, digitizedMinimum, digitizedMaximum);
301 
302  // Do the two's compliment encoding
303  unsigned int twosValue = digitizedValue;
304  if (digitizedValue < 0) {
305  twosValue += (1 << nBits);
306  }
307 
308  return twosValue;
309  }
310 
311  template <typename T>
312  constexpr unsigned int getBin(double value, const T& bins) const {
313  auto up = std::upper_bound(bins.begin(), bins.end(), value);
314  return (up - bins.begin() - 1);
315  }
316 
317  double undigitizeSignedValue(unsigned int twosValue, unsigned int nBits, double lsb, double offset = 0.5) const {
318  // Check that none of the bits above the nBits-1 bit, in a range of [0, nBits-1], are set.
319  // This makes sure that it isn't possible for the value represented by `twosValue` to be
320  // any bigger than ((1 << nBits) - 1).
321  assert((twosValue >> nBits) == 0);
322 
323  // Convert from twos compliment to C++ signed integer (normal digitized value)
324  int digitizedValue = twosValue;
325  if (twosValue & (1 << (nBits - 1))) { // check if the twosValue is negative
326  digitizedValue -= (1 << nBits);
327  }
328 
329  // Convert to floating point value
330  return (double(digitizedValue) + offset) * lsb;
331  }
332 
333  // ----------member data ---------------------------
335 };
336 
337 #endif
double getPhi() const
Definition: BitonicSort.h:7
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
unsigned int getMVAQuality() const
ap_uint< TrackBitWidths::kTrackWordSize > tkword_t
static constexpr std::array< double, 1<< TrackBitWidths::kChi2RPhiSize > chi2RPhiBins
double getTanl() const
ap_uint< TrackBitWidths::kMVAQualitySize > qualityMVA_t
chi2rphi_t getChi2RPhiWord() const
unsigned int countSetBits(unsigned int n) const
otherMVA_t getMVAOtherWord() const
unsigned int getChi2RZBits() const
static constexpr double sectorWidth
static constexpr double minZ0
unsigned int getMVAQualityBits() const
unsigned int getChi2RPhiBits() const
static constexpr double minD0
valid_t getValidWord() const
static constexpr double stepD0
d0_t getD0Word() const
void infoTestDigitizationScheme(const unsigned int, const double, const double, const unsigned int, const double, const unsigned int)
static constexpr std::array< double, 1<< TrackBitWidths::kBendChi2Size > bendChi2Bins
unsigned int getHitPatternBits() const
static constexpr double minTanl
static constexpr double minRinv
assert(be >=bs)
void testDigitizationScheme() const
double getChi2RPhi() const
unsigned int getValidBits() const
unsigned int getMVAOther() const
uint64_t word
unsigned int getMVAOtherBits() const
ap_uint< TrackBitWidths::kZ0Size > z0_t
double getZ0() const
void setTrackWord(unsigned int valid, const GlobalVector &momentum, const GlobalPoint &POCA, double rInv, double chi2RPhi, double chi2RZ, double bendChi2, unsigned int hitPattern, unsigned int mvaQuality, unsigned int mvaOther, unsigned int sector)
double undigitizeSignedValue(unsigned int twosValue, unsigned int nBits, double lsb, double offset=0.5) const
static constexpr double stepRinv
const unsigned int kValidSize
ap_uint< TrackBitWidths::kMVAOtherSize > otherMVA_t
TTTrack_TrackWord(const TTTrack_TrackWord &word)
ap_uint< TrackBitWidths::kValidSize > valid_t
ap_uint< TrackBitWidths::kRinvSize > rinv_t
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static constexpr double stepTanL
unsigned int getZ0Bits() const
std::bitset< TrackBitWidths::kTrackWordSize > tkword_bs_t
Definition: value.py:1
rinv_t getRinvWord() const
tkword_t getTrackWord() const
ap_uint< TrackBitWidths::kHitPatternSize > hit_t
ap_uint< TrackBitWidths::kChi2RZSize > chi2rz_t
#define M_PI
double getRinv() const
constexpr unsigned int getBin(double value, const T &bins) const
static constexpr double minPhi0
bendChi2_t getBendChi2Word() const
qualityMVA_t getMVAQualityWord() const
phi_t getPhiWord() const
static constexpr float d0
unsigned int getTanlBits() const
static constexpr double stepPhi0
double getD0() const
unsigned int getHitPattern() const
unsigned int digitizeSignedValue(double value, unsigned int nBits, double lsb) const
static constexpr unsigned int nSectors
ap_uint< TrackBitWidths::kTanlSize > tanl_t
static constexpr std::array< double, 1<< TrackBitWidths::kChi2RZSize > chi2RZBins
unsigned int getBendChi2Bits() const
z0_t getZ0Word() const
unsigned int getNStubs() const
chi2rz_t getChi2RZWord() const
unsigned int getPhiBits() const
hit_t getHitPatternWord() const
ap_uint< TrackBitWidths::kD0Size > d0_t
TTTrack_TrackWord & operator=(const TTTrack_TrackWord &word)
long double T
static constexpr double stepZ0
bool singleDigitizationSchemeTest(const double floatingPointValue, const unsigned int nBits, const double lsb) const
ap_uint< TrackBitWidths::kChi2RPhiSize > chi2rphi_t
tanl_t getTanlWord() const
double getBendChi2() const
unsigned int getRinvBits() const
ap_uint< TrackBitWidths::kBendChi2Size > bendChi2_t
double getChi2RZ() const
float localPhi(float globalPhi, unsigned int sector) const
ap_uint< TrackBitWidths::kPhiSize > phi_t
unsigned int getD0Bits() const