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  // Bin edges for TQ MVA
108  static constexpr std::array<double, 1 << TrackBitWidths::kMVAQualitySize> tqMVABins = {
109  {0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.750, 0.875}};
110 
111  // Sector constants
112  static constexpr unsigned int nSectors = 9;
113  static constexpr double sectorWidth = (2. * M_PI) / nSectors;
114 
115  // Track flags
116  typedef ap_uint<TrackBitWidths::kValidSize> valid_t; // valid bit
117 
118  // Track parameters types
119  typedef ap_uint<TrackBitWidths::kRinvSize> rinv_t; // Track Rinv
120  typedef ap_uint<TrackBitWidths::kPhiSize> phi_t; // Track phi
121  typedef ap_uint<TrackBitWidths::kTanlSize> tanl_t; // Track tan(l)
122  typedef ap_uint<TrackBitWidths::kZ0Size> z0_t; // Track z
123  typedef ap_uint<TrackBitWidths::kD0Size> d0_t; // D0
124 
125  // Track quality types
126  typedef ap_uint<TrackBitWidths::kChi2RPhiSize> chi2rphi_t; // Chi2 r-phi
127  typedef ap_uint<TrackBitWidths::kChi2RZSize> chi2rz_t; // Chi2 r-z
128  typedef ap_uint<TrackBitWidths::kBendChi2Size> bendChi2_t; // Bend-Chi2
129  typedef ap_uint<TrackBitWidths::kHitPatternSize> hit_t; // Hit mask bits
130  typedef ap_uint<TrackBitWidths::kMVAQualitySize> qualityMVA_t; // Track quality MVA
131  typedef ap_uint<TrackBitWidths::kMVAOtherSize> otherMVA_t; // Specialized MVA selection
132 
133  // Track word types
134  typedef std::bitset<kTrackWordSize> tkword_bs_t; // Entire track word;
135  typedef ap_uint<kTrackWordSize> tkword_t; // Entire track word;
136 
137 public:
138  // ----------Constructors --------------------------
140  TTTrack_TrackWord(unsigned int valid,
141  const GlobalVector& momentum,
142  const GlobalPoint& POCA,
143  double rInv,
144  double chi2RPhi, // would be xy chisq if chi2Z is non-zero
145  double chi2RZ,
146  double bendChi2,
147  unsigned int hitPattern,
148  double mvaQuality,
149  double mvaOther,
150  unsigned int sector);
151  TTTrack_TrackWord(unsigned int valid,
152  unsigned int rInv,
153  unsigned int phi0, // local phi
154  unsigned int tanl,
155  unsigned int z0,
156  unsigned int d0,
157  unsigned int chi2RPhi, // would be total chisq if chi2Z is zero
158  unsigned int chi2RZ,
159  unsigned int bendChi2,
160  unsigned int hitPattern,
161  unsigned int mvaQuality,
162  unsigned int mvaOther);
163 
164  // ----------copy constructor ----------------------
166 
167  // ----------operators -----------------------------
169  trackWord_ = word.trackWord_;
170  return *this;
171  }
172 
173  // ----------member functions (getters) ------------
174  // These functions return arbitarary precision unsigned int words (lists of bits) for each quantity
175  // Signed quantities have the sign enconded in the left-most bit.
177  rinv_t getRinvWord() const { return getTrackWord()(TrackBitLocations::kRinvMSB, TrackBitLocations::kRinvLSB); }
178  phi_t getPhiWord() const { return getTrackWord()(TrackBitLocations::kPhiMSB, TrackBitLocations::kPhiLSB); }
179  tanl_t getTanlWord() const { return getTrackWord()(TrackBitLocations::kTanlMSB, TrackBitLocations::kTanlLSB); }
180  z0_t getZ0Word() const { return getTrackWord()(TrackBitLocations::kZ0MSB, TrackBitLocations::kZ0LSB); }
181  d0_t getD0Word() const { return getTrackWord()(TrackBitLocations::kD0MSB, TrackBitLocations::kD0LSB); }
183  return getTrackWord()(TrackBitLocations::kChi2RPhiMSB, TrackBitLocations::kChi2RPhiLSB);
184  }
186  return getTrackWord()(TrackBitLocations::kChi2RZMSB, TrackBitLocations::kChi2RZLSB);
187  }
189  return getTrackWord()(TrackBitLocations::kBendChi2MSB, TrackBitLocations::kBendChi2LSB);
190  }
192  return getTrackWord()(TrackBitLocations::kHitPatternMSB, TrackBitLocations::kHitPatternLSB);
193  }
195  return getTrackWord()(TrackBitLocations::kMVAQualityMSB, TrackBitLocations::kMVAQualityLSB);
196  }
198  return getTrackWord()(TrackBitLocations::kMVAOtherMSB, TrackBitLocations::kMVAOtherLSB);
199  }
200  tkword_t getTrackWord() const { return tkword_t(trackWord_.to_string().c_str(), 2); }
201 
202  // These functions return the packed bits in unsigned integer format for each quantity
203  // Signed quantities have the sign enconded in the left-most bit of the pattern using
204  // a two's complement representation
205  unsigned int getValidBits() const { return getValidWord().to_uint(); }
206  unsigned int getRinvBits() const { return getRinvWord().to_uint(); }
207  unsigned int getPhiBits() const { return getPhiWord().to_uint(); }
208  unsigned int getTanlBits() const { return getTanlWord().to_uint(); }
209  unsigned int getZ0Bits() const { return getZ0Word().to_uint(); }
210  unsigned int getD0Bits() const { return getD0Word().to_uint(); }
211  unsigned int getChi2RPhiBits() const { return getChi2RPhiWord().to_uint(); }
212  unsigned int getChi2RZBits() const { return getChi2RZWord().to_uint(); }
213  unsigned int getBendChi2Bits() const { return getBendChi2Word().to_uint(); }
214  unsigned int getHitPatternBits() const { return getHitPatternWord().to_uint(); }
215  unsigned int getMVAQualityBits() const { return getMVAQualityWord().to_uint(); }
216  unsigned int getMVAOtherBits() const { return getMVAOtherWord().to_uint(); }
217 
218  // These functions return the unpacked and converted values
219  // These functions return real numbers converted from the digitized quantities by unpacking the 96-bit track word
220  bool getValid() const { return getValidWord().to_bool(); }
221  double getRinv() const { return undigitizeSignedValue(getRinvBits(), TrackBitWidths::kRinvSize, stepRinv); }
222  double getPhi() const { return undigitizeSignedValue(getPhiBits(), TrackBitWidths::kPhiSize, stepPhi0); }
223  double getTanl() const { return undigitizeSignedValue(getTanlBits(), TrackBitWidths::kTanlSize, stepTanL); }
224  double getZ0() const { return undigitizeSignedValue(getZ0Bits(), TrackBitWidths::kZ0Size, stepZ0); }
225  double getD0() const { return undigitizeSignedValue(getD0Bits(), TrackBitWidths::kD0Size, stepD0); }
226  double getChi2RPhi() const { return chi2RPhiBins[getChi2RPhiBits()]; }
227  double getChi2RZ() const { return chi2RZBins[getChi2RZBits()]; }
228  double getBendChi2() const { return bendChi2Bins[getBendChi2Bits()]; }
229  unsigned int getHitPattern() const { return getHitPatternBits(); }
230  unsigned int getNStubs() const { return countSetBits(getHitPatternBits()); }
231  double getMVAQuality() const { return tqMVABins[getMVAQualityBits()]; }
232  double getMVAOther() const { return getMVAOtherBits(); }
233 
234  // ----------member functions (setters) ------------
235  void setTrackWord(unsigned int valid,
236  const GlobalVector& momentum,
237  const GlobalPoint& POCA,
238  double rInv,
239  double chi2RPhi, // would be total chisq if chi2Z is zero
240  double chi2RZ,
241  double bendChi2,
242  unsigned int hitPattern,
243  double mvaQuality,
244  double mvaOther,
245  unsigned int sector);
246 
247  void setTrackWord(unsigned int valid,
248  unsigned int rInv,
249  unsigned int phi0, // local phi
250  unsigned int tanl,
251  unsigned int z0,
252  unsigned int d0,
253  unsigned int chi2RPhi, // would be total chisq if chi2Z is zero
254  unsigned int chi2RZ,
255  unsigned int bendChi2,
256  unsigned int hitPattern,
257  unsigned int mvaQuality,
258  unsigned int mvaOther);
259 
260  void setTrackWord(ap_uint<TrackBitWidths::kValidSize> valid,
261  ap_uint<TrackBitWidths::kRinvSize> rInv,
262  ap_uint<TrackBitWidths::kPhiSize> phi0, // local phi
263  ap_uint<TrackBitWidths::kTanlSize> tanl,
264  ap_uint<TrackBitWidths::kZ0Size> z0,
265  ap_uint<TrackBitWidths::kD0Size> d0,
266  ap_uint<TrackBitWidths::kChi2RPhiSize> chi2RPhi, // would be total chisq if chi2Z is zero
267  ap_uint<TrackBitWidths::kChi2RZSize> chi2RZ,
268  ap_uint<TrackBitWidths::kBendChi2Size> bendChi2,
269  ap_uint<TrackBitWidths::kHitPatternSize> hitPattern,
270  ap_uint<TrackBitWidths::kMVAQualitySize> mvaQuality,
271  ap_uint<TrackBitWidths::kMVAOtherSize> mvaOther);
272 
273  // ----------member functions (testers) ------------
274  bool singleDigitizationSchemeTest(const double floatingPointValue, const unsigned int nBits, const double lsb) const;
275  void testDigitizationScheme() const;
276 
277 protected:
278  // ----------protected member functions ------------
279  float localPhi(float globalPhi, unsigned int sector) const {
280  return reco::deltaPhi(globalPhi, (sector * sectorWidth));
281  }
282 
283 public:
284  // ----------public member functions --------------
285  unsigned int countSetBits(unsigned int n) const {
286  // Adapted from: https://www.geeksforgeeks.org/count-set-bits-in-an-integer/
287  unsigned int count = 0;
288  while (n) {
289  n &= (n - 1);
290  count++;
291  }
292  return count;
293  }
294 
295  unsigned int digitizeSignedValue(double value, unsigned int nBits, double lsb) const {
296  // Digitize the incoming value
297  int digitizedValue = std::floor(value / lsb);
298 
299  // Calculate the maxmum possible positive value given an output of nBits in size
300  int digitizedMaximum = (1 << (nBits - 1)) - 1; // The remove 1 bit from nBits to account for the sign
301  int digitizedMinimum = -1. * (digitizedMaximum + 1);
302 
303  // Saturate the digitized value
304  digitizedValue = std::clamp(digitizedValue, digitizedMinimum, digitizedMaximum);
305 
306  // Do the two's compliment encoding
307  unsigned int twosValue = digitizedValue;
308  if (digitizedValue < 0) {
309  twosValue += (1 << nBits);
310  }
311 
312  return twosValue;
313  }
314 
315  template <typename T>
316  constexpr unsigned int getBin(double value, const T& bins) const {
317  auto up = std::upper_bound(bins.begin(), bins.end(), value);
318  return (up - bins.begin() - 1);
319  }
320 
321  double undigitizeSignedValue(unsigned int twosValue, unsigned int nBits, double lsb, double offset = 0.5) const {
322  // Check that none of the bits above the nBits-1 bit, in a range of [0, nBits-1], are set.
323  // This makes sure that it isn't possible for the value represented by `twosValue` to be
324  // any bigger than ((1 << nBits) - 1).
325  assert((twosValue >> nBits) == 0);
326 
327  // Convert from twos compliment to C++ signed integer (normal digitized value)
328  int digitizedValue = twosValue;
329  if (twosValue & (1 << (nBits - 1))) { // check if the twosValue is negative
330  digitizedValue -= (1 << nBits);
331  }
332 
333  // Convert to floating point value
334  return (double(digitizedValue) + offset) * lsb;
335  }
336 
337  // ----------member data ---------------------------
339 };
340 
341 #endif
double getPhi() const
Definition: BitonicSort.h:7
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
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
ap_uint< kTrackWordSize > tkword_t
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
uint64_t word
unsigned int getMVAOtherBits() const
ap_uint< TrackBitWidths::kZ0Size > z0_t
void setTrackWord(unsigned int valid, const GlobalVector &momentum, const GlobalPoint &POCA, double rInv, double chi2RPhi, double chi2RZ, double bendChi2, unsigned int hitPattern, double mvaQuality, double mvaOther, unsigned int sector)
double getZ0() const
std::bitset< kTrackWordSize > tkword_bs_t
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
static constexpr std::array< double, 1<< TrackBitWidths::kMVAQualitySize > tqMVABins
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
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 int kTrackWordSize
double getMVAQuality() 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
double getMVAOther() 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