CMS 3D CMS Logo

L1GTTInputProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: L1Trigger/L1TTrackMatch
4 // Class: L1GTTInputProducer
5 //
14 //
15 // Original Author: Alexx Perloff
16 // Created: Sat, 20 Feb 2021 17:02:00 GMT
17 //
18 //
19 
20 // user include files
34 
35 // Vivado HLS includes
36 #include <ap_fixed.h>
37 #include <ap_int.h>
38 
39 // system include files
40 #define _USE_MATH_DEFINES
41 #include <cmath>
42 #include <string>
43 #include <sstream>
44 #include <vector>
45 
46 //
47 // class declaration
48 //
49 
51 public:
52  explicit L1GTTInputProducer(const edm::ParameterSet&);
53  ~L1GTTInputProducer() override;
54 
55  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
56 
57 private:
58  // ----------constants, enums and typedefs ---------
59  static constexpr unsigned int Npars4 = 4;
60  static constexpr unsigned int Npars5 = 5;
62  kEtaMagSize = 3, // eta output magnitude size; MAG + FRAC should be <= kEtaInputSize
63  kEtaFracSize = 5, // eta output fraction size; MAG + FRAC should be <= kEtaInputSize
64  kEtaInputSize = 16, // size of tan(lambda)
65 
66  kPTMagSize = 7, // magnitude output size; MAG + FRAC should be <= kPTInputSize
67  kPTFracSize = 3, // fraction output size; MAG + FRAC should be <= kPTInputSize
68  kPTInputSize = 15, // size of 1/R
69 
70  kEtaOutputSize = kEtaMagSize + kEtaFracSize, // total bit width for eta
71  kPTOutputSize = kPTMagSize + kPTFracSize, // total bit width for pT
72  };
73 
74  static constexpr double kEtaErrThresh = 0.0485; // error corresponding to 0.25 of a degree error in lambda
75 
76  static constexpr double kPTErrThresh = 5; // error threshold in percent
77  static constexpr double kSynchrotron = (1.0 / (0.3 * 3.8)); // 1/(0.3*B) for 1/R to 1/pT conversion
78  static constexpr unsigned int kPtLutSize = (1 << ConversionBitWidths::kPTOutputSize);
79  static constexpr unsigned int kEtaLutSize = (1 << (ConversionBitWidths::kEtaOutputSize - 1));
80 
82  typedef std::vector<L1Track> TTTrackCollection;
84  typedef ap_fixed<kEtaOutputSize, kEtaMagSize, AP_RND_CONV, AP_SAT> out_eta_t;
86  typedef ap_ufixed<kPTOutputSize, kPTMagSize, AP_RND_CONV, AP_SAT> out_pt_t;
88  typedef ap_uint<1> out_charge_t;
89 
90  // ----------member functions ----------------------
91  void generate_eta_lut();
92  void generate_pt_lut();
93  bool getEtaBits(
94  const L1Track& track, out_eta_t& etaBits, double& expected, double& maxErrPerc, double& maxErrEpsilon) const;
95  bool getPtBits(const L1Track& track,
96  out_pt_t& ptBits,
97  out_charge_t& chargeBit,
98  double& expected,
99  double& maxErrPerc,
100  double& maxErrEpsilon,
101  double& minErrPerc,
102  double& minExpected) const;
103  double indexTanLambda2Eta(unsigned int indexTanLambda) const;
104  double inverseRT2InversePT(unsigned int indexRT) const;
105  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
106  template <typename T>
107  int sgn(T val) const {
108  return (T(0) < val) - (val < T(0));
109  } // From https://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c
110  double unpackSignedValue(unsigned int bits, unsigned int nBits, double lsb) const;
111 
112  // ----------member data ---------------------------
115  int debug_;
116  std::vector<out_pt_t> pt_lut_;
117  std::vector<out_eta_t> eta_lut_;
118 };
119 
120 //
121 // constructors and destructor
122 //
124  : l1TracksToken_(consumes<TTTrackCollectionView>(iConfig.getParameter<edm::InputTag>("l1TracksInputTag"))),
125  outputCollectionName_(iConfig.getParameter<std::string>("outputCollectionName")),
126  debug_(iConfig.getParameter<int>("debug")) {
127  // Generate the required luts
129  generate_pt_lut();
130 
131  // Define EDM output to be written to file (if required)
132  produces<TTTrackCollection>(outputCollectionName_);
133  produces<std::vector<double>>("L1GTTInputTrackPtExpected");
134  produces<std::vector<double>>("L1GTTInputTrackEtaExpected");
135 }
136 
138 
139 //
140 // member functions
141 //
142 
154  // initialize lut array
155  eta_lut_.reserve(kEtaLutSize);
156 
157  // iterate through all values in the lut
158  for (unsigned int i = 0; i < kEtaLutSize; i++) {
159  // -1 to ignore sign bit for input
160  unsigned int index = ((i + 0.5) * pow(2, (int)(kEtaInputSize - kEtaOutputSize)));
161  double newValue = indexTanLambda2Eta(index); // map out the index to the represented eta
162  out_eta_t out_eta = newValue; // cast it to fxp
163  eta_lut_[i] = out_eta; // add value for the lut
164  }
165 
166  if (debug_ >= 3) {
167  edm::LogInfo log("L1GTTInputProducer");
168  log << "generate_eta_lut::The eta_lut_[" << kEtaLutSize << "] values are ... \n";
169  for (unsigned int i = 0; i < kEtaLutSize; i++) {
170  log << "\t" << i << "\t" << eta_lut_[i] << "\n";
171  }
172  }
173 }
174 
176  // initialize lut array
177  pt_lut_.reserve(kPtLutSize); // generate lut
178 
179  // iterate through all values in the lut
180  for (unsigned int i = 0; i < kPtLutSize; i++) {
181  unsigned int index = (i + 0.5) * pow(2, (int)(kPTInputSize - 1 - kPTOutputSize));
182  double newValue = inverseRT2InversePT(index); //map out the index to the represented 1/pT
183  out_pt_t out_pt = 1.0 / newValue; // take the reciprocal and cast as an AP fixed-point (1/pt ==> pt)
184  pt_lut_[i] = out_pt; // setting the i-th value for the lut
185  }
186 
187  if (debug_ >= 3) {
188  edm::LogInfo log("L1GTTInputProducer");
189  log << "generate_pt_lut::The pt_lut_[" << kPtLutSize << "] values are ... \n";
190  for (unsigned int i = 0; i < kPtLutSize; i++) {
191  log << "\t" << i << "\t" << pt_lut_[i] << "\n";
192  }
193  }
194 }
195 
196 double L1GTTInputProducer::unpackSignedValue(unsigned int bits, unsigned int nBits, double lsb) const {
197  // Check that none of the bits above the nBits-1 bit, in a range of [0, nBits-1], are set.
198  // This makes sure that it isn't possible for the value represented by 'bits' to be
199  // any bigger than ((1 << nBits) - 1).
200  assert((bits >> nBits) == 0);
201 
202  // Convert from twos compliment to C++ signed integer (normal digitized value)
203  int digitizedValue = bits;
204  if (bits & (1 << (nBits - 1))) { // check if the 'bits' is negative
205  digitizedValue -= (1 << nBits);
206  }
207 
208  // Convert to floating point value
209  return (double(digitizedValue) + 0.5) * lsb;
210 }
211 
220 double L1GTTInputProducer::indexTanLambda2Eta(unsigned int indexTanLambda) const {
221  double tanl = unpackSignedValue(indexTanLambda, kEtaInputSize, TTTrack_TrackWord::stepTanL);
222  double theta = (M_PI / 2.0) - atan(tanl);
223  double eta = -1.0 * log(tan(theta / 2.0));
224  if (debug_ >= 3) {
225  edm::LogInfo("L1GTTInputProducer") << "indexTanLambda2Eta::tanl index = " << indexTanLambda << "\n"
226  << "indexTanLambda2Eta::tanl value = " << tanl << "\n"
227  << "indexTanLambda2Eta::theta = " << theta << "\n"
228  << "indexTanLambda2Eta::eta = " << eta;
229  }
230  return eta;
231 }
232 
241 double L1GTTInputProducer::inverseRT2InversePT(unsigned int indexRT) const {
242  double inverseRT = unpackSignedValue(indexRT, kPTInputSize, TTTrack_TrackWord::stepRinv);
243  return 100.0 * kSynchrotron * inverseRT; // multiply by 100 to convert from cm to m
244 }
245 
247  const L1Track& track, out_eta_t& etaBits, double& expected, double& maxErrPerc, double& maxErrEpsilon) const {
248  // Conver the input to an ap_uint
249  in_eta_t value = track.getTanlWord();
250 
251  // Get the expected outcome (floating point)
252  out_eta_t maxValuePossible = pow(2, 15); // saturate at max value possible for fxp
253  expected = indexTanLambda2Eta(value); // expected value for eta
254  if (expected > maxValuePossible) {
255  expected = maxValuePossible;
256  }
257 
258  // Converted value (emulation)
259  // Masking and shifting converts the efficient bit representation into an index
260  // Start by setting up the masks
261  in_eta_t indexTanLambda = value;
262  in_eta_t mask = ~0; // mask (all 1's)
263  bool sign = indexTanLambda.range(kEtaInputSize - 1, kEtaInputSize - 1); // sign bit of indexTanLambda
264  mask *= sign; // all 0's for positive numbers, all 1's for negative numbers
265 
266  // Take the absolute value of indexTanLambda (2's complement)
267  indexTanLambda ^= mask;
268  indexTanLambda += sign;
269 
270  // Find the value for eta, not |eta|
271  indexTanLambda =
272  indexTanLambda >>
273  (kEtaInputSize -
274  kEtaOutputSize); // Don't subtract 1 because we now want to take into account the sign bit of the output
275  indexTanLambda =
276  (indexTanLambda < (1 << (kEtaOutputSize - 1))) ? indexTanLambda : in_eta_t((1 << (kEtaOutputSize - 1)) - 1);
277  etaBits = eta_lut_[indexTanLambda];
278 
279  // Reinacting the sign
280  out_eta_t maskOut;
281  maskOut.V = ~0;
282  maskOut *= sign;
283  etaBits ^= maskOut;
284  etaBits.V += sign;
285 
286  // Compare the floating point calculation to the emulation
287  double delta = std::abs(expected - etaBits.to_double());
288  double perc_diff = (delta / std::abs(expected)) * 100.; // calc percentage error
289  if (delta > maxErrEpsilon) {
290  maxErrPerc = perc_diff;
291  maxErrEpsilon = delta;
292  }
293 
294  if (delta >= kEtaErrThresh) {
295  edm::LogError("L1GTTInputProducer") << "getEtaBits::MISMATCH!!!\n"
296  << "\tTTTrack tanL = " << track.tanL() << "\n"
297  << "\tTTTrack eta = " << track.momentum().eta() << "\n"
298  << "\tTTTrack_TrackWord = " << track.getTrackWord().to_string(2) << "\n"
299  << "\tTTTrack_TrackWord tanlWord = " << track.getTanlWord() << " ("
300  << track.getTanlWord().to_string(2) << ")\n"
301  << "\tin_eta_t value = " << value << " (" << value.to_string(2) << ")\n"
302  << "\tExpected value = " << expected << "\n"
303  << "\tCalculated eta = " << etaBits.to_double() << " (" << etaBits.to_string(2)
304  << ") @ index " << indexTanLambda << "\n"
305  << "\tDelta = " << delta << "\tpercentage error = " << perc_diff;
306  return true;
307  } else {
308  if (debug_ >= 2) {
309  edm::LogInfo("L1GTTInputProducer")
310  << "getEtaBits::SUCCESS (TTTrack, floating eta calculation, bitwise calculation, initial index, lut index) = "
311  << "(" << track.momentum().eta() << ", " << expected << ", " << etaBits << ", " << value << ", "
312  << indexTanLambda << ")";
313  }
314  }
315 
316  return false;
317 }
318 
320  out_pt_t& ptBits,
321  out_charge_t& chargeBit,
322  double& expected,
323  double& maxErrPerc,
324  double& maxErrEpsilon,
325  double& minErrPerc,
326  double& minExpected) const {
327  // Convert the input to an ap_uint
328  in_pt_t value = track.getRinvWord();
329  in_pt_t value_initial = value;
330 
331  // Get the expected outcome (floating point)
332  out_pt_t maxValuePossible = pow(2, 16); // saturate at max value possible for fxp
333  expected = 1.0 / inverseRT2InversePT(value); // expected value for inverse
334  bool saturation = true;
335  if (std::abs(expected) > maxValuePossible) {
336  expected = maxValuePossible;
337  } else {
338  saturation = false;
339  }
340 
341  // Converted value (emulation)
342  // Masking and shifting converts the efficient bit representation into an index
343  // Start by setting up the masks
344  in_pt_t mask = ~0; // mask (all 1's)
345  bool sign = value.range(kPTInputSize - 1, kPTInputSize - 1); // sign bit of value
346  mask *= sign; // all 0's for positive numbers, all 1's for negative numbers
347 
348  // Take the absolute value of value (2's complement)
349  value ^= mask;
350  value += sign;
351 
352  // Shift the value so that the index changes when the LSB of the output changes
353  value = value >> (kPTInputSize - 1 - (kPTOutputSize));
354 
355  // Get the pt from the LUT
356  ptBits = pt_lut_[value];
357 
358  // Set the charge bit
359  chargeBit = sign;
360  double charge = 1. - (2 * chargeBit.to_uint());
361 
362  // Compare the floating point calculation to the emulation
363  double delta = std::abs(expected - (charge * ptBits.to_double()));
364  double perc_diff = (delta / std::abs(expected)) * 100.;
365 
366  if (delta > maxErrEpsilon) {
367  maxErrPerc = perc_diff;
368  maxErrEpsilon = delta;
369  } else if (delta < minExpected && !saturation && minErrPerc > 100.0) {
370  minErrPerc = perc_diff;
371  minExpected = expected;
372  }
373 
374  if (std::abs(perc_diff) >= kPTErrThresh && !saturation) {
375  edm::LogError("L1GTTInputProducer") << "getPtBits::MISMATCH!!!\n"
376  << "\tTTTrack Rinv = " << track.rInv() << "\n"
377  << "\tTTTrack pt = " << track.momentum().transverse() << "\n"
378  << "\tTTTrack_TrackWord = " << track.getTrackWord().to_string(2) << "\n"
379  << "\tTTTrack_TrackWord RinvWord = " << track.getRinvWord() << " ("
380  << track.getRinvWord().to_string(2) << ")\n"
381  << "\tin_pt_t value = " << value_initial << " (" << value_initial.to_string(2)
382  << ")\n"
383  << "\tExpected value = " << expected << "\n"
384  << "\tCalculated pt = " << ptBits.to_double() << " (" << ptBits.to_string(2)
385  << ") @ index " << value << "\n"
386  << "\tcharge = " << charge << " (bit = " << chargeBit << ")\n"
387  << "\tDelta = " << delta << "\tpercentage error = " << perc_diff;
388  return true;
389  } else {
390  if (debug_ >= 2) {
391  edm::LogInfo("L1GTTInputProducer") << "getPtBits::SUCCESS (TTTrack, floating pt calculation, charge, bitwise "
392  "calculation, initial index, lut index) = "
393  << "(" << sgn(track.rInv()) * track.momentum().transverse() << ", " << expected
394  << ", " << charge << ", " << ptBits << ", " << value_initial << ", " << value
395  << ")";
396  }
397  }
398 
399  return false;
400 }
401 
402 // ------------ method called to produce the data ------------
404  auto vTTTrackOutput = std::make_unique<TTTrackCollection>();
405  auto vPtOutput = std::make_unique<std::vector<double>>();
406  auto vEtaOutput = std::make_unique<std::vector<double>>();
407 
408  edm::Handle<TTTrackCollectionView> l1TracksHandle;
409  iEvent.getByToken(l1TracksToken_, l1TracksHandle);
410 
411  out_charge_t chargeBit = 0;
412  out_pt_t ptBits = 0;
413  out_eta_t etaBits = 0;
414  in_pt_t ptBitsShifted = 0;
415  in_eta_t etaBitsShifted = 0;
416  unsigned int error_pt_c = 0; // error counter
417  unsigned int error_eta_c = 0; // error counter
418  double expectedPt = 0.0; // expected value of the pt
419  double expectedEta = 0.0; // expected value of the eta
420  double maxErrPercPt = 0.0; // stores the maximum error percentage
421  double maxErrPercEta = 0.0; // stores the maximum error percentage
422  double maxErrEpsilonPt = 0.0; // keeps track of epsilon for max error
423  double maxErrEpsilonEta = 0.0; // keeps track of epsilon for max error
424  double minErrPercPt = 10000000.0; // stores the maximum error percentage
425  double minExpectedPt = 10000000.0; // keeps track of epsilon for max error
426 
427  unsigned int nOutput = l1TracksHandle->size();
428  vTTTrackOutput->reserve(nOutput);
429  vPtOutput->reserve(nOutput);
430  vEtaOutput->reserve(nOutput);
431  for (const auto& track : *l1TracksHandle) {
432  if (!(track.nFitPars() == Npars4 || track.nFitPars() == Npars5)) {
433  throw cms::Exception("nFitPars unknown")
434  << "L1GTTInputProducer::produce method is called with numFitPars_ = " << track.nFitPars()
435  << ". The only possible values are 4/5.";
436  }
437 
438  // Fill the vector of tracks
439  vTTTrackOutput->push_back(track);
440  auto& currentTrackRef = vTTTrackOutput->back();
441  if (debug_ >= 2) {
442  edm::LogInfo("L1GTTInputProducer") << "produce::word before anything "
443  << currentTrackRef.getTrackWord().to_string(2);
444  }
445 
446  // Do an initial setting of the bits based on the floating point values
447  currentTrackRef.setTrackWordBits();
448  if (debug_ >= 2) {
449  edm::LogInfo("L1GTTInputProducer") << "produce::word after initial setting of the track word "
450  << currentTrackRef.getTrackWord().to_string(2);
451  }
452 
453  // Do the conversions
454  error_pt_c += getPtBits(
455  currentTrackRef, ptBits, chargeBit, expectedPt, maxErrPercPt, maxErrEpsilonPt, minErrPercPt, minExpectedPt);
456  error_eta_c += getEtaBits(currentTrackRef, etaBits, expectedEta, maxErrPercEta, maxErrEpsilonEta);
457 
458  // Assign the exat same bits to an ap_uint
459  ptBitsShifted = ptBits.range();
460  etaBitsShifted = etaBits.range();
461 
462  // Shift the bits so that the decimal is in the right spot for the GTT software
463  ptBitsShifted = ptBitsShifted << 2;
464  etaBitsShifted = etaBitsShifted << 8;
465 
466  // Set the MSB for the pt to the sign of the incoming word
467  ptBitsShifted.set(kPTInputSize - 1, chargeBit);
468 
469  // Set the correct bits based on the converted quanteties and the existing track word components
470  currentTrackRef.setTrackWord(currentTrackRef.getValidWord(),
471  ptBitsShifted,
472  currentTrackRef.getPhiWord(),
473  etaBitsShifted,
474  currentTrackRef.getZ0Word(),
475  currentTrackRef.getD0Word(),
476  currentTrackRef.getChi2RPhiWord(),
477  currentTrackRef.getChi2RZWord(),
478  currentTrackRef.getBendChi2Word(),
479  currentTrackRef.getHitPatternWord(),
480  currentTrackRef.getMVAQualityWord(),
481  currentTrackRef.getMVAOtherWord());
482  if (debug_ >= 2) {
483  edm::LogInfo("L1GTTInputProducer") << "produce::charge after all conversions " << chargeBit << "\n"
484  << "produce::ptBits after all conversions " << ptBits.to_string(2) << " ("
485  << ptBitsShifted.to_string(2) << " = " << ptBitsShifted.to_uint() << ")\n"
486  << "produce::etaBits after all conversions " << etaBits.to_string(2) << " ("
487  << etaBitsShifted.to_string(2) << " = " << etaBitsShifted.to_uint() << ")\n"
488  << "produce::word after all conversions "
489  << vTTTrackOutput->back().getTrackWord().to_string(2);
490  }
491 
492  // Fill the remaining outputs
493  vPtOutput->push_back(expectedPt);
494  vEtaOutput->push_back(expectedEta);
495  }
496 
497  if (debug_ >= 1) {
498  edm::LogInfo("L1GTTInputProducer") << "\nNumber of converted tracks: " << nOutput << "\n\n"
499  << "q/r ==> pt conversion:\n"
500  << "\tError Threshold: " << kPTErrThresh << "%\n"
501  << "\tMax error: " << maxErrEpsilonPt
502  << " GeV difference with percentage: " << maxErrPercPt << "% @ "
503  << 100.0 * maxErrEpsilonPt / maxErrPercPt << " GeV"
504  << "\n"
505  << "\tError @ max range: " << minExpectedPt
506  << " GeV with precentage: " << minErrPercPt << "%"
507  << "\n"
508  << "\tTotal number of errors: " << error_pt_c << "\n\n"
509  << "tan(lambda) ==> eta conversion:\n"
510  << "\tError Threshold: " << kEtaErrThresh << "\n"
511  << "\tMax error: " << maxErrEpsilonEta << " with percentage: " << maxErrPercEta
512  << "% @ " << 100.0 * maxErrEpsilonEta / maxErrPercEta << "\n"
513  << "\tTotal number of errors: " << error_eta_c;
514  }
515 
516  if (error_pt_c + error_eta_c) {
517  edm::LogError("L1GTTInputProducer") << "produce::" << error_pt_c << "/" << error_eta_c
518  << " pt/eta mismatches detected!!!";
519  }
520 
521  // Put the outputs into the event
522  iEvent.put(std::move(vTTTrackOutput), outputCollectionName_);
523  iEvent.put(std::move(vPtOutput), "L1GTTInputTrackPtExpected");
524  iEvent.put(std::move(vEtaOutput), "L1GTTInputTrackEtaExpected");
525 }
526 
527 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
529  // L1GTTInputProducer
531  desc.add<int>("debug", 0)->setComment("Verbosity levels: 0, 1, 2, 3");
532  desc.add<edm::InputTag>("l1TracksInputTag", edm::InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"));
533  desc.add<std::string>("outputCollectionName", "Level1TTTracksConverted");
534  descriptions.addWithDefaultLabel(desc);
535 }
536 
537 //define this as a plug-in
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
const edm::EDGetTokenT< TTTrackCollectionView > l1TracksToken_
static constexpr unsigned int kEtaLutSize
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const std::string outputCollectionName_
ap_ufixed< kPTOutputSize, kPTMagSize, AP_RND_CONV, AP_SAT > out_pt_t
static constexpr unsigned int kPtLutSize
TTTrack< Ref_Phase2TrackerDigi_ > L1Track
int sgn(T val) const
L1GTTInputProducer(const edm::ParameterSet &)
TTTrack_TrackWord::tanl_t in_eta_t
Log< level::Error, false > LogError
assert(be >=bs)
TTTrack_TrackWord::rinv_t in_pt_t
std::vector< L1Track > TTTrackCollection
int iEvent
Definition: GenABIO.cc:224
static constexpr double stepRinv
std::vector< out_eta_t > eta_lut_
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
static constexpr double kSynchrotron
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
ap_uint< TrackBitWidths::kRinvSize > rinv_t
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static constexpr unsigned int Npars5
static constexpr double stepTanL
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ap_fixed< kEtaOutputSize, kEtaMagSize, AP_RND_CONV, AP_SAT > out_eta_t
Definition: value.py:1
edm::View< L1Track > TTTrackCollectionView
#define M_PI
Log< level::Info, false > LogInfo
bool getEtaBits(const L1Track &track, out_eta_t &etaBits, double &expected, double &maxErrPerc, double &maxErrEpsilon) const
static constexpr double kEtaErrThresh
Class to store the L1 Track Trigger tracks.
Definition: TTTrack.h:29
HLT enums.
std::vector< out_pt_t > pt_lut_
ap_uint< TrackBitWidths::kTanlSize > tanl_t
static constexpr unsigned int Npars4
double unpackSignedValue(unsigned int bits, unsigned int nBits, double lsb) const
long double T
static constexpr double kPTErrThresh
double inverseRT2InversePT(unsigned int indexRT) const
bool getPtBits(const L1Track &track, out_pt_t &ptBits, out_charge_t &chargeBit, double &expected, double &maxErrPerc, double &maxErrEpsilon, double &minErrPerc, double &minExpected) const
Geom::Theta< T > theta() const
double indexTanLambda2Eta(unsigned int indexTanLambda) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
def move(src, dest)
Definition: eostools.py:511