CMS 3D CMS Logo

L1TMuonBarrelKalmanAlgo.cc
Go to the documentation of this file.
1 #include <cmath>
3 #include "ap_int.h"
4 #include "ap_fixed.h"
5 
7  : verbose_(settings.getParameter<bool>("verbose")),
8  lutService_(new L1TMuonBarrelKalmanLUTs(settings.getParameter<std::string>("lutFile"))),
9  initK_(settings.getParameter<std::vector<double> >("initialK")),
10  initK2_(settings.getParameter<std::vector<double> >("initialK2")),
11  eLoss_(settings.getParameter<std::vector<double> >("eLoss")),
12  aPhi_(settings.getParameter<std::vector<double> >("aPhi")),
13  aPhiB_(settings.getParameter<std::vector<double> >("aPhiB")),
14  aPhiBNLO_(settings.getParameter<std::vector<double> >("aPhiBNLO")),
15  bPhi_(settings.getParameter<std::vector<double> >("bPhi")),
16  bPhiB_(settings.getParameter<std::vector<double> >("bPhiB")),
17  phiAt2_(settings.getParameter<double>("phiAt2")),
18 
19  chiSquare_(settings.getParameter<std::vector<double> >("chiSquare")),
20  chiSquareCutPattern_(settings.getParameter<std::vector<int> >("chiSquareCutPattern")),
21  chiSquareCutCurv_(settings.getParameter<std::vector<int> >("chiSquareCutCurvMax")),
22  chiSquareCut_(settings.getParameter<std::vector<int> >("chiSquareCut")),
23  trackComp_(settings.getParameter<std::vector<double> >("trackComp")),
24  trackCompErr1_(settings.getParameter<std::vector<double> >("trackCompErr1")),
25  trackCompErr2_(settings.getParameter<std::vector<double> >("trackCompErr2")),
26  trackCompPattern_(settings.getParameter<std::vector<int> >("trackCompCutPattern")),
27  trackCompCutCurv_(settings.getParameter<std::vector<int> >("trackCompCutCurvMax")),
28  trackCompCut_(settings.getParameter<std::vector<int> >("trackCompCut")),
29  chiSquareCutTight_(settings.getParameter<std::vector<int> >("chiSquareCutTight")),
30  combos4_(settings.getParameter<std::vector<int> >("combos4")),
31  combos3_(settings.getParameter<std::vector<int> >("combos3")),
32  combos2_(settings.getParameter<std::vector<int> >("combos2")),
33  combos1_(settings.getParameter<std::vector<int> >("combos1")),
34 
35  useOfflineAlgo_(settings.getParameter<bool>("useOfflineAlgo")),
36  mScatteringPhi_(settings.getParameter<std::vector<double> >("mScatteringPhi")),
37  mScatteringPhiB_(settings.getParameter<std::vector<double> >("mScatteringPhiB")),
38  pointResolutionPhi_(settings.getParameter<double>("pointResolutionPhi")),
39  pointResolutionPhiB_(settings.getParameter<double>("pointResolutionPhiB")),
40  pointResolutionPhiBH_(settings.getParameter<std::vector<double> >("pointResolutionPhiBH")),
41  pointResolutionPhiBL_(settings.getParameter<std::vector<double> >("pointResolutionPhiBL")),
42  pointResolutionVertex_(settings.getParameter<double>("pointResolutionVertex")),
43  useNewQualityCalculation_(settings.getParameter<bool>("useNewQualityCalculation"))
44 
45 {}
46 
48  for (uint i = 0; i < tracks.size(); ++i) {
49  printf("Code=%d, track=%d\n", tracks[i].hitPattern(), mask);
50  if (tracks[i].hitPattern() == mask)
51  return std::make_pair(true, i);
52  }
53  return std::make_pair(false, 0);
54 }
55 
57  // int K = fabs(track.curvatureAtVertex());
58 
59  //calibration
60  int sign, signValid;
61 
62  if (track.curvatureAtVertex() == 0) {
63  sign = 0;
64  signValid = 0;
65  } else if (track.curvatureAtVertex() > 0) {
66  sign = 0;
67  signValid = 1;
68  } else {
69  sign = 1;
70  signValid = 1;
71  }
72 
73  // if (K<22)
74  // K=22;
75 
76  // if (K>4095)
77  // K=4095;
78 
79  int pt = ptLUT(track.curvatureAtVertex());
80 
81  // int K2 = fabs(track.curvatureAtMuon());
82  // if (K2<22)
83  // K2=22;
84 
85  // if (K2>4095)
86  // K2=4095;
87  int pt2 = ptLUT(track.curvatureAtMuon()) / 2;
88  int eta = track.hasFineEta() ? track.fineEta() : track.coarseEta();
89 
90  // int phi2 = track.phiAtMuon()>>2;
91  // float phi_f = float(phi2);
92  //double kPhi = 57.2958/0.625/1024.;
93  //int phi = 24+int(floor(kPhi*phi_f));
94  // if (phi > 69) phi = 69;
95  // if (phi < -8) phi = -8;
96  int phi2 = track.phiAtMuon() >> 2;
97  int tmp = fp_product(0.0895386, phi2, 14);
98  int phi = 24 + tmp;
99 
100  int processor = track.sector();
101  int HF = track.hasFineEta();
102 
103  int quality = 0;
105  int r = rank(track);
106  if (r < 192)
107  quality = 12;
108  else if (r < 204)
109  quality = 13;
110  else if (r < 220)
111  quality = 14;
112  else
113  quality = 15;
114  } else {
115  quality = 12 | (rank(track) >> 6);
116  }
117 
118  int dxy = abs(track.dxy()) >> 8;
119  if (dxy > 3)
120  dxy = 3;
121 
122  int trackAddr;
123  std::map<int, int> addr = trackAddress(track, trackAddr);
124 
125  l1t::RegionalMuonCand muon(pt, phi, eta, sign, signValid, quality, processor, l1t::bmtf, addr);
126  muon.setHwHF(HF);
127  muon.setHwPtUnconstrained(pt2);
128  muon.setHwDXY(dxy);
129 
130  //nw the words!
131  uint32_t word1 = pt;
132  word1 = word1 | quality << 9;
133  word1 = word1 | (twosCompToBits(eta)) << 13;
134  word1 = word1 | HF << 22;
135  word1 = word1 | (twosCompToBits(phi)) << 23;
136 
137  uint32_t word2 = sign;
138  word2 = word2 | signValid << 1;
139  word2 = word2 | dxy << 2;
140  word2 = word2 | trackAddr << 4;
141  word2 = word2 | (twosCompToBits(track.wheel())) << 20;
142  word2 = word2 | pt2 << 23;
143  muon.setDataword(word2, word1);
144  return muon;
145 }
146 
148  const L1MuKBMTrack& track,
149  std::unique_ptr<l1t::RegionalMuonCandBxCollection>& out) {
150  out->push_back(bx, convertToBMTF(track));
151 }
152 
153 // std::pair<bool,uint> L1TMuonBarrelKalmanAlgo::match(const L1MuKBMTCombinedStubRef& seed, const L1MuKBMTCombinedStubRefVector& stubs,int step) {
154 // L1MuKBMTCombinedStubRefVector selected;
155 
156 // bool found=false;
157 // uint best=0;
158 // int distance=100000;
159 // uint N=0;
160 // for (const auto& stub :stubs) {
161 // N=N+1;
162 // if (stub->stNum()!=step)
163 // continue;
164 
165 // int d = fabs(wrapAround(((correctedPhi(seed,seed->scNum())-correctedPhi(stub,seed->scNum()))>>3),1024));
166 // if (d<distance) {
167 // distance = d;
168 // best=N-1;
169 // found=true;
170 // }
171 // }
172 // return std::make_pair(found,best);
173 // }
174 
176  if (info[i] < info[j])
177  return i;
178  else
179  return j;
180 }
181 
184  int step) {
186 
187  std::map<uint, uint> diffInfo;
188  for (uint i = 0; i < 12; ++i) {
189  diffInfo[i] = 60000;
190  }
191 
192  std::map<uint, uint> stubInfo;
193 
194  int sector = seed->scNum();
195  int previousSector = sector - 1;
196  int nextSector = sector + 1;
197  if (sector == 0) {
198  previousSector = 11;
199  }
200  if (sector == 11) {
201  nextSector = 0;
202  }
203 
204  int wheel = seed->whNum();
205  int innerWheel = 0;
206  if (wheel == -2)
207  innerWheel = -1;
208  if (wheel == -1)
209  innerWheel = 0;
210  if (wheel == 0)
211  innerWheel = 1982;
212  if (wheel == 1)
213  innerWheel = 0;
214  if (wheel == 2)
215  innerWheel = 1;
216 
217  //First align the data
218  uint N = 0;
219  for (const auto& stub : stubs) {
220  N = N + 1;
221 
222  if (stub->stNum() != step)
223  continue;
224 
225  uint distance =
226  fabs(wrapAround(((correctedPhi(seed, seed->scNum()) - correctedPhi(stub, seed->scNum())) >> 3), 1024));
227 
228  if (stub->scNum() == previousSector) {
229  if (stub->whNum() == wheel) {
230  if (!stub->tag()) {
231  diffInfo[0] = distance;
232  stubInfo[0] = N - 1;
233  } else {
234  diffInfo[1] = distance;
235  stubInfo[1] = N - 1;
236  }
237  } else if (stub->whNum() == innerWheel) {
238  if (!stub->tag()) {
239  diffInfo[2] = distance;
240  stubInfo[2] = N - 1;
241  } else {
242  diffInfo[3] = distance;
243  stubInfo[3] = N - 1;
244  }
245  }
246  } else if (stub->scNum() == sector) {
247  if (stub->whNum() == wheel) {
248  if (!stub->tag()) {
249  diffInfo[4] = distance;
250  stubInfo[4] = N - 1;
251  } else {
252  diffInfo[5] = distance;
253  stubInfo[5] = N - 1;
254  }
255  } else if (stub->whNum() == innerWheel) {
256  if (!stub->tag()) {
257  diffInfo[6] = distance;
258  stubInfo[6] = N - 1;
259  } else {
260  diffInfo[7] = distance;
261  stubInfo[7] = N - 1;
262  }
263  }
264  } else if (stub->scNum() == nextSector) {
265  if (stub->whNum() == wheel) {
266  if (!stub->tag()) {
267  diffInfo[8] = distance;
268  stubInfo[8] = N - 1;
269  } else {
270  diffInfo[9] = distance;
271  stubInfo[9] = N - 1;
272  }
273  } else if (stub->whNum() == innerWheel) {
274  if (!stub->tag()) {
275  diffInfo[10] = distance;
276  stubInfo[10] = N - 1;
277  } else {
278  diffInfo[11] = distance;
279  stubInfo[11] = N - 1;
280  }
281  }
282  }
283  }
284 
285  uint s1_1 = matchAbs(diffInfo, 0, 1);
286  uint s1_2 = matchAbs(diffInfo, 2, 3);
287  uint s1_3 = matchAbs(diffInfo, 4, 5);
288  uint s1_4 = matchAbs(diffInfo, 6, 7);
289  uint s1_5 = matchAbs(diffInfo, 8, 9);
290  uint s1_6 = matchAbs(diffInfo, 10, 11);
291 
292  uint s2_1 = matchAbs(diffInfo, s1_1, s1_2);
293  uint s2_2 = matchAbs(diffInfo, s1_3, s1_4);
294  uint s2_3 = matchAbs(diffInfo, s1_5, s1_6);
295 
296  uint s3_1 = matchAbs(diffInfo, s2_1, s2_2);
297 
298  uint s4 = matchAbs(diffInfo, s3_1, s2_3);
299 
300  if (diffInfo[s4] != 60000)
301  return std::make_pair(true, stubInfo[s4]);
302  else
303  return std::make_pair(false, 0);
304 }
305 
307  //Promote phiB to 12 bits
308  return 8 * stub->phiB();
309 }
310 
312  if (stub->scNum() == sector) {
313  return stub->phi();
314  } else if ((stub->scNum() == sector - 1) || (stub->scNum() == 11 && sector == 0)) {
315  return stub->phi() - 2144;
316  } else if ((stub->scNum() == sector + 1) || (stub->scNum() == 0 && sector == 11)) {
317  return stub->phi() + 2144;
318  }
319  return stub->phi();
320 }
321 
323  unsigned int mask = 0;
324  for (const auto& stub : track.stubs()) {
325  mask = mask + round(pow(2, stub->stNum() - 1));
326  }
327  return mask;
328 }
329 
330 int L1TMuonBarrelKalmanAlgo::customBitmask(unsigned int bit1, unsigned int bit2, unsigned int bit3, unsigned int bit4) {
331  return bit1 * 1 + bit2 * 2 + bit3 * 4 + bit4 * 8;
332 }
333 
334 bool L1TMuonBarrelKalmanAlgo::getBit(int bitmask, int pos) { return (bitmask & (1 << pos)) >> pos; }
335 
337  int K = track.curvature();
338  int phi = track.positionAngle();
339  int phiB = track.bendingAngle();
340  unsigned int step = track.step();
341 
342  //energy loss term only for MU->VERTEX
343  //int offset=int(charge*eLoss_[step-1]*K*K);
344  // if (fabs(offset)>4096)
345  // offset=4096*offset/fabs(offset);
346  int charge = 1;
347  if (K != 0)
348  charge = K / fabs(K);
349 
350  int KBound = K;
351 
352  if (KBound > 4095)
353  KBound = 4095;
354  if (KBound < -4095)
355  KBound = -4095;
356 
357  int deltaK = 0;
358  int KNew = 0;
359  if (step == 1) {
360  int addr = KBound / 2;
361  if (addr < 0)
362  addr = (-KBound) / 2;
363  deltaK = 2 * addr - int(2 * addr / (1 + eLoss_[step - 1] * addr));
364 
365  if (verbose_)
366  printf("propagate to vertex K=%d deltaK=%d addr=%d\n", K, deltaK, addr);
367  }
368 
369  if (K >= 0)
370  KNew = K - deltaK;
371  else
372  KNew = K + deltaK;
373 
374  //phi propagation
375  ap_fixed<BITSCURV, BITSCURV> phi11 = ap_fixed<BITSPARAM + 1, 2>(aPhi_[step - 1]) * ap_fixed<BITSCURV, BITSCURV>(K);
376  ap_fixed<BITSPHIB, BITSPHIB> phi12 =
377  ap_fixed<BITSPARAM + 1, 2>(-bPhi_[step - 1]) * ap_fixed<BITSPHIB, BITSPHIB>(phiB);
378 
379  if (verbose_) {
380  printf("phi prop = %d * %f = %d, %d * %f = %d\n",
381  K,
382  ap_fixed<BITSPARAM + 1, 2>(aPhi_[step - 1]).to_float(),
383  phi11.to_int(),
384  phiB,
385  ap_fixed<BITSPARAM + 1, 2>(-bPhi_[step - 1]).to_float(),
386  phi12.to_int());
387  }
388  int phiNew = ap_fixed<BITSPHI, BITSPHI>(phi + phi11 + phi12);
389 
390  //phiB propagation
391  ap_fixed<BITSCURV, BITSCURV> phiB11 = ap_fixed<BITSPARAM, 1>(aPhiB_[step - 1]) * ap_fixed<BITSCURV, BITSCURV>(K);
392  ap_fixed<BITSPHIB + 1, BITSPHIB + 1> phiB12 =
393  ap_ufixed<BITSPARAM + 1, 1>(bPhiB_[step - 1]) * ap_fixed<BITSPHIB, BITSPHIB>(phiB);
394  int phiBNew = ap_fixed<13, 13>(phiB11 + phiB12);
395  if (verbose_) {
396  printf("phiB prop = %d * %f = %d, %d * %f = %d\n",
397  K,
398  ap_fixed<BITSPARAM + 1, 2>(aPhiB_[step - 1]).to_float(),
399  phiB11.to_int(),
400  phiB,
401  ap_ufixed<BITSPARAM + 1, 1>(bPhiB_[step - 1]).to_float(),
402  phiB12.to_int());
403  }
404 
405  //Only for the propagation to vertex we use the LUT for better precision and the full function
406  if (step == 1) {
407  int addr = KBound / 2;
408  // Extra steps to mimic firmware for vertex prop
409  ap_ufixed<11, 11> dxyOffset = (int)fabs(aPhiB_[step - 1] * addr / (1 + charge * aPhiBNLO_[step - 1] * addr));
410  ap_fixed<12, 12> DXY;
411  if (addr > 0)
412  DXY = -dxyOffset;
413  else
414  DXY = dxyOffset;
415  phiBNew = ap_fixed<BITSPHIB, BITSPHIB>(DXY - ap_fixed<BITSPHIB, BITSPHIB>(phiB));
416  if (verbose_) {
417  printf("Vertex phiB prop = %d - %d = %d\n", DXY.to_int(), ap_fixed<BITSPHIB, BITSPHIB>(phiB).to_int(), phiBNew);
418  }
419  }
421  //Rest of the stuff is for the offline version only
422  //where we want to check what is happening in the covariaznce matrix
423 
424  //Create the transformation matrix
425  double a[9];
426  a[0] = 1.;
427  a[1] = 0.0;
428  a[2] = 0.0;
429  a[3] = aPhi_[step - 1];
430  // a[3] = 0.0;
431  a[4] = 1.0;
432  a[5] = -bPhi_[step - 1];
433  //a[6]=0.0;
434  a[6] = aPhiB_[step - 1];
435  if (step == 1)
436  a[6] = aPhiB_[step - 1] / 2.0;
437 
438  a[7] = 0.0;
439  a[8] = bPhiB_[step - 1];
440 
441  ROOT::Math::SMatrix<double, 3> P(a, 9);
442 
443  const std::vector<double>& covLine = track.covariance();
444  L1MuKBMTrack::CovarianceMatrix cov(covLine.begin(), covLine.end());
445  cov = ROOT::Math::Similarity(P, cov);
446 
447  //Add the multiple scattering
448  double phiRMS = mScatteringPhi_[step - 1] * K * K;
449  double phiBRMS = mScatteringPhiB_[step - 1] * K * K;
450 
451  std::vector<double> b(6);
452  b[0] = 0;
453  b[1] = 0;
454  b[2] = phiRMS;
455  b[3] = 0;
456  b[4] = 0;
457  b[5] = phiBRMS;
458 
459  reco::Candidate::CovarianceMatrix MS(b.begin(), b.end());
460 
461  cov = cov + MS;
462 
463  if (verbose_) {
464  printf("Covariance term for phiB = %f\n", cov(2, 2));
465  printf("Multiple scattering term for phiB = %f\n", MS(2, 2));
466  }
467 
468  track.setCovariance(cov);
469  track.setCoordinates(step - 1, KNew, phiNew, phiBNew);
470 }
471 
473  updateEta(track, stub);
474  if (useOfflineAlgo_) {
475  if (mask == 3 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12)
476  return updateOffline(track, stub);
477  else
478  return updateOffline1D(track, stub);
479 
480  } else
481  return updateLUT(track, stub, mask, seedQual);
482 }
483 
485  int trackK = track.curvature();
486  int trackPhi = track.positionAngle();
487  int trackPhiB = track.bendingAngle();
488 
489  int phi = correctedPhi(stub, track.sector());
490  int phiB = correctedPhiB(stub);
491 
492  Vector2 residual;
493  residual[0] = phi - trackPhi;
494  residual[1] = phiB - trackPhiB;
495 
496  Matrix23 H;
497  H(0, 0) = 0.0;
498  H(0, 1) = 1.0;
499  H(0, 2) = 0.0;
500  H(1, 0) = 0.0;
501  H(1, 1) = 0.0;
502  H(1, 2) = 1.0;
503 
505  R(0, 0) = pointResolutionPhi_;
506  R(0, 1) = 0.0;
507  R(1, 0) = 0.0;
508  if (stub->quality() < 4)
509  R(1, 1) = pointResolutionPhiBL_[track.step() - 1];
510  else
511  R(1, 1) = pointResolutionPhiBH_[track.step() - 1];
512 
513  const std::vector<double>& covLine = track.covariance();
514  L1MuKBMTrack::CovarianceMatrix cov(covLine.begin(), covLine.end());
515 
516  CovarianceMatrix2 S = ROOT::Math::Similarity(H, cov) + R;
517  if (!S.Invert())
518  return false;
519  Matrix32 Gain = cov * ROOT::Math::Transpose(H) * S;
520 
521  track.setKalmanGain(
522  track.step(), fabs(trackK), Gain(0, 0), Gain(0, 1), Gain(1, 0), Gain(1, 1), Gain(2, 0), Gain(2, 1));
523 
524  int KNew = (trackK + int(Gain(0, 0) * residual(0) + Gain(0, 1) * residual(1)));
525  if (fabs(KNew) > 8192)
526  return false;
527 
528  int phiNew = wrapAround(trackPhi + residual(0), 8192);
529  int phiBNew = wrapAround(trackPhiB + int(Gain(2, 0) * residual(0) + Gain(2, 1) * residual(1)), 4096);
530 
531  track.setResidual(stub->stNum() - 1, fabs(phi - phiNew) + fabs(phiB - phiBNew) / 8);
532 
533  if (verbose_) {
534  printf("residual %d - %d = %d %d - %d = %d\n", phi, trackPhi, int(residual[0]), phiB, trackPhiB, int(residual[1]));
535  printf("Gains offline: %f %f %f %f\n", Gain(0, 0), Gain(0, 1), Gain(2, 0), Gain(2, 1));
536  printf(" K = %d + %f * %f + %f * %f\n", trackK, Gain(0, 0), residual(0), Gain(0, 1), residual(1));
537  printf(" phiB = %d + %f * %f + %f * %f\n", trackPhiB, Gain(2, 0), residual(0), Gain(2, 1), residual(1));
538  }
539 
540  track.setCoordinates(track.step(), KNew, phiNew, phiBNew);
541  Matrix33 covNew = cov - Gain * (H * cov);
543 
544  c(0, 0) = covNew(0, 0);
545  c(0, 1) = covNew(0, 1);
546  c(0, 2) = covNew(0, 2);
547  c(1, 0) = covNew(1, 0);
548  c(1, 1) = covNew(1, 1);
549  c(1, 2) = covNew(1, 2);
550  c(2, 0) = covNew(2, 0);
551  c(2, 1) = covNew(2, 1);
552  c(2, 2) = covNew(2, 2);
553  if (verbose_) {
554  printf("Post Fit Covariance Matrix %f %f %f\n", cov(0, 0), cov(1, 1), cov(2, 2));
555  }
556 
557  track.setCovariance(c);
558  track.addStub(stub);
559  track.setHitPattern(hitPattern(track));
560 
561  return true;
562 }
563 
565  int trackK = track.curvature();
566  int trackPhi = track.positionAngle();
567  int trackPhiB = track.bendingAngle();
568 
569  int phi = correctedPhi(stub, track.sector());
570 
571  double residual = phi - trackPhi;
572 
573  if (verbose_)
574  printf("residuals %d - %d = %d\n", phi, trackPhi, int(residual));
575 
576  Matrix13 H;
577  H(0, 0) = 0.0;
578  H(0, 1) = 1.0;
579  H(0, 2) = 0.0;
580 
581  const std::vector<double>& covLine = track.covariance();
582  L1MuKBMTrack::CovarianceMatrix cov(covLine.begin(), covLine.end());
583 
584  double S = ROOT::Math::Similarity(H, cov)(0, 0) + pointResolutionPhi_;
585 
586  if (S == 0.0)
587  return false;
588  Matrix31 Gain = cov * ROOT::Math::Transpose(H) / S;
589 
590  track.setKalmanGain(track.step(), fabs(trackK), Gain(0, 0), 0.0, Gain(1, 0), 0.0, Gain(2, 0), 0.0);
591  if (verbose_)
592  printf("Gains: %f %f\n", Gain(0, 0), Gain(2, 0));
593 
594  int KNew = wrapAround(trackK + int(Gain(0, 0) * residual), 8192);
595  int phiNew = wrapAround(trackPhi + residual, 8192);
596  int phiBNew = wrapAround(trackPhiB + int(Gain(2, 0) * residual), 4096);
597  track.setCoordinates(track.step(), KNew, phiNew, phiBNew);
598  Matrix33 covNew = cov - Gain * (H * cov);
600 
601  if (verbose_) {
602  printf("phiUpdate: %d %d\n", int(Gain(0, 0) * residual), int(Gain(2, 0) * residual));
603  }
604 
605  c(0, 0) = covNew(0, 0);
606  c(0, 1) = covNew(0, 1);
607  c(0, 2) = covNew(0, 2);
608  c(1, 0) = covNew(1, 0);
609  c(1, 1) = covNew(1, 1);
610  c(1, 2) = covNew(1, 2);
611  c(2, 0) = covNew(2, 0);
612  c(2, 1) = covNew(2, 1);
613  c(2, 2) = covNew(2, 2);
614  track.setCovariance(c);
615  track.addStub(stub);
616  track.setHitPattern(hitPattern(track));
617 
618  return true;
619 }
620 
622  const L1MuKBMTCombinedStubRef& stub,
623  int mask,
624  int seedQual) {
625  int trackK = track.curvature();
626  int trackPhi = track.positionAngle();
627  int trackPhiB = track.bendingAngle();
628 
629  int phi = correctedPhi(stub, track.sector());
630  int phiB = correctedPhiB(stub);
631 
632  Vector2 residual;
633  ap_fixed<BITSPHI + 1, BITSPHI + 1> residualPhi = phi - trackPhi;
634  ap_fixed<BITSPHIB + 1, BITSPHIB + 1> residualPhiB = phiB - trackPhiB;
635 
636  if (verbose_)
637  printf("residual %d - %d = %d %d - %d = %d\n",
638  phi,
639  trackPhi,
640  residualPhi.to_int(),
641  phiB,
642  trackPhiB,
643  residualPhiB.to_int());
644 
645  uint absK = fabs(trackK);
646  if (absK > 4095)
647  absK = 4095;
648 
649  std::vector<float> GAIN;
650  //For the three stub stuff use only gains 0 and 4
651  if (!(mask == 3 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12)) {
652  GAIN = lutService_->trackGain(track.step(), track.hitPattern(), absK / 4);
653  GAIN[1] = 0.0;
654  GAIN[3] = 0.0;
655 
656  } else {
657  GAIN = lutService_->trackGain2(track.step(), track.hitPattern(), absK / 8, seedQual, stub->quality());
658  }
659  if (verbose_) {
660  printf("Gains (fp): %f %f %f %f\n", GAIN[0], GAIN[1], GAIN[2], GAIN[3]);
661  if (!(mask == 3 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12))
662  printf("Addr=%d gain0=%f gain4=-%f\n",
663  absK / 4,
664  ap_ufixed<GAIN_0, GAIN_0INT>(GAIN[0]).to_float(),
665  ap_ufixed<GAIN_4, GAIN_4INT>(GAIN[2]).to_float());
666  else
667  printf("Addr=%d %f -%f %f %f\n",
668  absK / 4,
669  ap_fixed<GAIN2_0, GAIN2_0INT>(GAIN[0]).to_float(),
670  ap_ufixed<GAIN2_1, GAIN2_1INT>(GAIN[1]).to_float(),
671  ap_ufixed<GAIN2_4, GAIN2_4INT>(GAIN[2]).to_float(),
672  ap_ufixed<GAIN2_5, GAIN2_5INT>(GAIN[3]).to_float());
673  }
674 
675  track.setKalmanGain(track.step(), fabs(trackK), GAIN[0], GAIN[1], 1, 0, GAIN[2], GAIN[3]);
676 
677  int KNew;
678  if (!(mask == 3 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12)) {
679  KNew = ap_fixed<BITSPHI + 9, BITSPHI + 9>(ap_fixed<BITSCURV, BITSCURV>(trackK) +
680  ap_ufixed<GAIN_0, GAIN_0INT>(GAIN[0]) * residualPhi);
681  } else {
682  ap_fixed<BITSPHI + 7, BITSPHI + 7> k11 = ap_fixed<GAIN2_0, GAIN2_0INT>(GAIN[0]) * residualPhi;
683  ap_fixed<BITSPHIB + 4, BITSPHIB + 4> k12 = ap_ufixed<GAIN2_1, GAIN2_1INT>(GAIN[1]) * residualPhiB;
684  KNew = ap_fixed<BITSPHI + 9, BITSPHI + 9>(ap_fixed<BITSCURV, BITSCURV>(trackK) + k11 - k12);
685  }
686  if (fabs(KNew) >= 8191)
687  return false;
688  KNew = wrapAround(KNew, 8192);
689  int phiNew = phi;
690 
691  //different products for different firmware logic
692  ap_fixed<BITSPHI + 5, BITSPHI + 5> pbdouble_0 = ap_ufixed<GAIN2_4, GAIN2_4INT>(GAIN[2]) * residualPhi;
693  ap_fixed<BITSPHIB + 24, BITSPHIB + 4> pb_1 = ap_ufixed<GAIN2_5, GAIN2_5INT>(GAIN[3]) * residualPhiB;
694  ap_fixed<BITSPHI + 9, BITSPHI + 5> pb_0 = ap_ufixed<GAIN_4, GAIN_4INT>(GAIN[2]) * residualPhi;
695 
696  if (verbose_) {
697  printf("phiupdate %f %f %f\n", pb_0.to_float(), pb_1.to_float(), pbdouble_0.to_float());
698  }
699 
700  int phiBNew;
701  if (!(mask == 3 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12)) {
702  phiBNew = ap_fixed<BITSPHI + 8, BITSPHI + 8>(ap_fixed<BITSPHIB, BITSPHIB>(trackPhiB) -
703  ap_ufixed<GAIN_4, GAIN_4INT>(GAIN[2]) * residualPhi);
704 
705  if (fabs(phiBNew) >= 4095)
706  return false;
707  } else {
708  phiBNew = ap_fixed<BITSPHI + 7, BITSPHI + 7>(ap_fixed<BITSPHIB, BITSPHIB>(trackPhiB) + pb_1 - pbdouble_0);
709  if (fabs(phiBNew) >= 4095)
710  return false;
711  }
712  track.setCoordinates(track.step(), KNew, phiNew, phiBNew);
713  track.addStub(stub);
714  track.setHitPattern(hitPattern(track));
715  return true;
716 }
717 
719 
721  if (useOfflineAlgo_)
723  else
725 }
726 
728  double residual = -track.dxy();
729  Matrix13 H;
730  H(0, 0) = 0;
731  H(0, 1) = 0;
732  H(0, 2) = 1;
733 
734  const std::vector<double>& covLine = track.covariance();
735  L1MuKBMTrack::CovarianceMatrix cov(covLine.begin(), covLine.end());
736 
737  double S = (ROOT::Math::Similarity(H, cov))(0, 0) + pointResolutionVertex_;
738  S = 1.0 / S;
739  Matrix31 Gain = cov * (ROOT::Math::Transpose(H)) * S;
740  track.setKalmanGain(track.step(), fabs(track.curvature()), Gain(0, 0), Gain(1, 0), Gain(2, 0));
741 
742  if (verbose_) {
743  printf("sigma3=%f sigma6=%f\n", cov(0, 3), cov(3, 3));
744  printf(" K = %d + %f * %f\n", track.curvature(), Gain(0, 0), residual);
745  }
746 
747  int KNew = wrapAround(int(track.curvature() + Gain(0, 0) * residual), 8192);
748  int phiNew = wrapAround(int(track.positionAngle() + Gain(1, 0) * residual), 8192);
749  int dxyNew = wrapAround(int(track.dxy() + Gain(2, 0) * residual), 8192);
750  if (verbose_)
751  printf("Post fit impact parameter=%d\n", dxyNew);
752  track.setCoordinatesAtVertex(KNew, phiNew, -residual);
753  Matrix33 covNew = cov - Gain * (H * cov);
755  c(0, 0) = covNew(0, 0);
756  c(0, 1) = covNew(0, 1);
757  c(0, 2) = covNew(0, 2);
758  c(1, 0) = covNew(1, 0);
759  c(1, 1) = covNew(1, 1);
760  c(1, 2) = covNew(1, 2);
761  c(2, 0) = covNew(2, 0);
762  c(2, 1) = covNew(2, 1);
763  c(2, 2) = covNew(2, 2);
764  track.setCovariance(c);
765  // track.covariance = track.covariance - Gain*H*track.covariance;
766 }
767 
769  double residual = -track.dxy();
770  uint absK = fabs(track.curvature());
771  if (absK > 2047)
772  absK = 2047;
773 
774  std::pair<float, float> GAIN = lutService_->vertexGain(track.hitPattern(), absK / 2);
775  track.setKalmanGain(track.step(), fabs(track.curvature()), GAIN.first, GAIN.second, -1);
776 
777  ap_fixed<BITSCURV, BITSCURV> k_0 =
778  -(ap_ufixed<GAIN_V0, GAIN_V0INT>(fabs(GAIN.first))) * ap_fixed<BITSPHIB, BITSPHIB>(residual);
779  int KNew = ap_fixed<BITSCURV, BITSCURV>(k_0 + ap_fixed<BITSCURV, BITSCURV>(track.curvature()));
780 
781  if (verbose_) {
782  printf("VERTEX GAIN(%d)= -%f * %d = %d\n",
783  absK / 2,
784  ap_ufixed<GAIN_V0, GAIN_V0INT>(fabs(GAIN.first)).to_float(),
785  ap_fixed<BITSPHIB, BITSPHIB>(residual).to_int(),
786  k_0.to_int());
787  }
788 
789  int p_0 = fp_product(GAIN.second, int(residual), 7);
790  int phiNew = wrapAround(track.positionAngle() + p_0, 8192);
791  track.setCoordinatesAtVertex(KNew, phiNew, -residual);
792 }
793 
795  int K, etaINT;
796 
797  if (track.hasFineEta())
798  etaINT = track.fineEta();
799  else
800  etaINT = track.coarseEta();
801 
802  double lsb = 1.25 / float(1 << 13);
803  double lsbEta = 0.010875;
804 
805  if (vertex) {
806  int charge = 1;
807  if (track.curvatureAtVertex() < 0)
808  charge = -1;
809  double pt = double(ptLUT(track.curvatureAtVertex())) / 2.0;
810 
811  double phi = track.sector() * M_PI / 6.0 + track.phiAtVertex() * M_PI / (6 * 2048.) - 2 * M_PI;
812 
813  double eta = etaINT * lsbEta;
814  track.setPtEtaPhi(pt, eta, phi);
815  track.setCharge(charge);
816  } else {
817  K = track.curvatureAtMuon();
818  if (K == 0)
819  K = 1;
820 
821  if (fabs(K) < 46)
822  K = 46 * K / fabs(K);
823  double pt = 1.0 / (lsb * fabs(K));
824  if (pt < 1.6)
825  pt = 1.6;
826  track.setPtUnconstrained(pt);
827  }
828 }
829 
830 std::pair<bool, L1MuKBMTrack> L1TMuonBarrelKalmanAlgo::chain(const L1MuKBMTCombinedStubRef& seed,
832  L1MuKBMTrackCollection pretracks;
833  std::vector<int> combinatorics;
834  int seedQual;
835  switch (seed->stNum()) {
836  case 1:
837  combinatorics = combos1_;
838  break;
839  case 2:
840  combinatorics = combos2_;
841  break;
842 
843  case 3:
844  combinatorics = combos3_;
845  break;
846 
847  case 4:
848  combinatorics = combos4_;
849  break;
850 
851  default:
852  printf("Something really bad happend\n");
853  }
854 
855  L1MuKBMTrack nullTrack(seed, correctedPhi(seed, seed->scNum()), correctedPhiB(seed));
856  seedQual = seed->quality();
857  for (const auto& mask : combinatorics) {
859  int phiB = correctedPhiB(seed);
860  int charge;
861  if (phiB == 0)
862  charge = 0;
863  else
864  charge = phiB / fabs(phiB);
865 
866  int address = phiB;
867  if (track.step() == 4 && (fabs(seed->phiB()) > 15))
868  address = charge * 15 * 8;
869 
870  if (track.step() == 3 && (fabs(seed->phiB()) > 30))
871  address = charge * 30 * 8;
872  if (track.step() == 2 && (fabs(seed->phiB()) > 127))
873  address = charge * 127 * 8;
874  int initialK = int(initK_[seed->stNum() - 1] * address / (1 + initK2_[seed->stNum() - 1] * charge * address));
875  if (initialK > 8191)
876  initialK = 8191;
877  if (initialK < -8191)
878  initialK = -8191;
879 
880  track.setCoordinates(seed->stNum(), initialK, correctedPhi(seed, seed->scNum()), phiB);
881  if (seed->quality() < 4) {
882  track.setCoordinates(seed->stNum(), 0, correctedPhi(seed, seed->scNum()), 0);
883  }
884 
885  track.setHitPattern(hitPattern(track));
886  //set covariance
888 
889  float DK = 512 * 512.;
890  covariance(0, 0) = DK;
891  covariance(0, 1) = 0;
892  covariance(0, 2) = 0;
893  covariance(1, 0) = 0;
894  covariance(1, 1) = float(pointResolutionPhi_);
895  covariance(1, 2) = 0;
896  covariance(2, 0) = 0;
897  covariance(2, 1) = 0;
898  if (!(mask == 3 || mask == 5 || mask == 9 || mask == 6 || mask == 10 || mask == 12))
899  covariance(2, 2) = float(pointResolutionPhiB_);
900  else {
901  if (seed->quality() < 4)
902  covariance(2, 2) = float(pointResolutionPhiBL_[seed->stNum() - 1]);
903  else
904  covariance(2, 2) = float(pointResolutionPhiBH_[seed->stNum() - 1]);
905  }
906  track.setCovariance(covariance);
907 
908  //
909  if (verbose_) {
910  printf("New Kalman fit staring at step=%d, phi=%d,phiB=%d with curvature=%d\n",
911  track.step(),
912  track.positionAngle(),
913  track.bendingAngle(),
914  track.curvature());
915  printf("BITMASK:");
916  for (unsigned int i = 0; i < 4; ++i)
917  printf("%d", getBit(mask, i));
918  printf("\n");
919  printf("------------------------------------------------------\n");
920  printf("------------------------------------------------------\n");
921  printf("------------------------------------------------------\n");
922  printf("stubs:\n");
923  for (const auto& stub : stubs)
924  printf("station=%d phi=%d phiB=%d qual=%d tag=%d sector=%d wheel=%d fineEta= %d %d\n",
925  stub->stNum(),
926  correctedPhi(stub, seed->scNum()),
927  correctedPhiB(stub),
928  stub->quality(),
929  stub->tag(),
930  stub->scNum(),
931  stub->whNum(),
932  stub->eta1(),
933  stub->eta2());
934  printf("------------------------------------------------------\n");
935  printf("------------------------------------------------------\n");
936  }
937 
938  int phiAtStation2 = 0;
939 
940  while (track.step() > 0) {
941  // muon station 1
942  if (track.step() == 1) {
943  track.setCoordinatesAtMuon(track.curvature(), track.positionAngle(), track.bendingAngle());
944  phiAtStation2 = phiAt2(track);
946  if (!passed)
947  break;
950  //calculate coarse eta
952 
953  if (verbose_)
954  printf("Unconstrained PT in Muon System: pt=%f\n", track.ptUnconstrained());
955  }
956 
957  propagate(track);
958  if (verbose_)
959  printf("propagated Coordinates step:%d,phi=%d,phiB=%d,K=%d\n",
960  track.step(),
961  track.positionAngle(),
962  track.bendingAngle(),
963  track.curvature());
964 
965  if (track.step() > 0)
966  if (getBit(mask, track.step() - 1)) {
967  std::pair<bool, uint> bestStub = match(seed, stubs, track.step());
968  if ((!bestStub.first) || (!update(track, stubs[bestStub.second], mask, seedQual)))
969  break;
970  if (verbose_) {
971  printf("updated Coordinates step:%d,phi=%d,phiB=%d,K=%d\n",
972  track.step(),
973  track.positionAngle(),
974  track.bendingAngle(),
975  track.curvature());
976  }
977  }
978 
979  if (track.step() == 0) {
980  track.setCoordinatesAtVertex(track.curvature(), track.positionAngle(), track.bendingAngle());
981  if (verbose_)
982  printf(" Coordinates before vertex constraint step:%d,phi=%d,dxy=%d,K=%d\n",
983  track.step(),
984  track.phiAtVertex(),
985  track.dxy(),
986  track.curvatureAtVertex());
987  if (verbose_)
988  printf("Chi Square = %d\n", track.approxChi2());
989 
992  if (verbose_) {
993  printf(" Coordinates after vertex constraint step:%d,phi=%d,dxy=%d,K=%d maximum local chi2=%d\n",
994  track.step(),
995  track.phiAtVertex(),
996  track.dxy(),
997  track.curvatureAtVertex(),
998  track.approxChi2());
999  printf("------------------------------------------------------\n");
1000  printf("------------------------------------------------------\n");
1001  }
1003  //set the coordinates at muon to include phi at station 2
1004  track.setCoordinatesAtMuon(track.curvatureAtMuon(), phiAtStation2, track.phiBAtMuon());
1005  track.setRank(rank(track));
1006  if (verbose_)
1007  printf("Floating point coordinates at vertex: pt=%f, eta=%f phi=%f\n", track.pt(), track.eta(), track.phi());
1008  pretracks.push_back(track);
1009  }
1010  }
1011  }
1012 
1013  //Now for all the pretracks we need only one
1014  L1MuKBMTrackCollection cleaned = clean(pretracks, seed->stNum());
1015 
1016  if (!cleaned.empty()) {
1017  return std::make_pair(true, cleaned[0]);
1018  }
1019  return std::make_pair(false, nullTrack);
1020 }
1021 
1023  //here we have a simplification of the algorithm for the sake of the emulator - rsult is identical
1024  // we apply cuts on the firmware as |u -u'|^2 < a+b *K^2
1025  int K = track.curvatureAtMuon();
1026 
1027  uint chi = 0;
1028 
1029  // const double PHI[4]={0.0,0.249,0.543,0.786};
1030  // const double DROR[4]={0.0,0.182,0.430,0.677};
1031 
1032  int coords = wrapAround((track.phiAtMuon() + track.phiBAtMuon()) >> 4, 512);
1033  for (const auto& stub : track.stubs()) {
1034  int AK = wrapAround(fp_product(-chiSquare_[stub->stNum() - 1], K >> 4, 8), 256);
1035  int stubCoords = wrapAround((correctedPhi(stub, track.sector()) >> 4) + (stub->phiB() >> 1), 512);
1036  int diff1 = wrapAround(stubCoords - coords, 1024);
1037  uint delta = wrapAround(abs(diff1 + AK), 2048);
1038  chi = chi + delta;
1039  if (verbose_)
1040  printf("Chi Square stub for track with pattern=%d coords=%d -> AK=%d stubCoords=%d diff=%d delta=%d\n",
1041  track.hitPattern(),
1042  coords,
1043  AK,
1044  stubCoords,
1045  diff1,
1046  delta);
1047  }
1048 
1049  if (chi > 127)
1050  chi = 127;
1051  // for (const auto& stub: track.stubs()) {
1052  // int deltaPhi = (correctedPhi(stub,track.sector())-track.phiAtMuon())>>3;
1053  // int AK = fp_product(PHI[stub->stNum()-1],K>>3,8);
1054  // int BPB = fp_product(DROR[stub->stNum()-1],track.phiBAtMuon()>>3,8);
1055  // chi=chi+abs(deltaPhi-AK-BPB);
1056  // }
1057  // // }
1058 
1059  track.setApproxChi2(chi);
1060  for (uint i = 0; i < chiSquareCutPattern_.size(); ++i) {
1061  if (track.hitPattern() == chiSquareCutPattern_[i] && fabs(K) < chiSquareCutCurv_[i] &&
1062  track.approxChi2() > chiSquareCut_[i])
1063  return false;
1064  }
1065  return true;
1066 }
1067 
1069  int K = track.curvatureAtVertex() >> 4;
1070 
1071  if (track.stubs().size() != 2) {
1072  track.setTrackCompatibility(0);
1073  return;
1074  }
1075 
1076  uint stubSel = 1;
1077  if (track.stubs()[0]->quality() > track.stubs()[1]->quality())
1078  stubSel = 0;
1079  const L1MuKBMTCombinedStubRef& stub = track.stubs()[stubSel];
1080 
1081  if (verbose_) {
1082  printf("stubsel %d phi=%d phiB=%d\n", stubSel, stub->phi(), stub->phiB());
1083  }
1084 
1085  ap_ufixed<BITSCURV - 5, BITSCURV - 5> absK;
1086  if (K < 0)
1087  absK = -K;
1088  else
1089  absK = K;
1090 
1091  ap_fixed<12, 12> diff = ap_int<10>(stub->phiB()) -
1092  ap_ufixed<5, 1>(trackComp_[stub->stNum() - 1]) * ap_fixed<BITSCURV - 4, BITSCURV - 4>(K);
1093  ap_ufixed<11, 11> delta;
1094  if (diff.is_neg())
1095  delta = -diff;
1096  else
1097  delta = diff;
1098 
1099  ap_ufixed<BITSCURV - 5, BITSCURV - 5> err =
1100  ap_uint<3>(trackCompErr1_[stub->stNum() - 1]) + ap_ufixed<5, 0>(trackCompErr2_[stub->stNum() - 1]) * absK;
1101  track.setTrackCompatibility(((int)delta) / ((int)err));
1102  for (uint i = 0; i < trackCompPattern_.size(); ++i) {
1103  int deltaMax = ap_ufixed<BITSCURV, BITSCURV>(err * trackCompCut_[i]);
1104  if (verbose_) {
1105  if (track.hitPattern() == trackCompPattern_[i]) {
1106  printf("delta = %d = abs(%d - %f*%d\n", delta.to_int(), stub->phiB(), trackComp_[stub->stNum() - 1], K);
1107  printf("err = %d = %f + %f*%d\n",
1108  err.to_int(),
1109  trackCompErr1_[stub->stNum() - 1],
1110  trackCompErr2_[stub->stNum() - 1],
1111  absK.to_int());
1112  printf("deltaMax = %d = %d*%d\n", deltaMax, err.to_int(), trackCompCut_[i]);
1113  }
1114  }
1115  if ((track.hitPattern() == trackCompPattern_[i]) && ((int)absK < trackCompCutCurv_[i]) &&
1116  ((track.approxChi2() > chiSquareCutTight_[i]) || (delta > deltaMax))) {
1117  track.setCoordinatesAtVertex(8191, track.phiAtVertex(), track.dxy());
1118  break;
1119  }
1120  }
1121 }
1122 
1124  // int offset=0;
1125  uint chi = track.approxChi2() > 127 ? 127 : track.approxChi2();
1126  if (hitPattern(track) == customBitmask(0, 0, 1, 1)) {
1127  return 60;
1128  }
1129  // return offset+(track.stubs().size()*2+track.quality())*80-track.approxChi2();
1130  return 160 + (track.stubs().size()) * 20 - chi;
1131 }
1132 
1134  if (value > maximum - 1)
1135  return wrapAround(value - 2 * maximum, maximum);
1136  if (value < -maximum)
1137  return wrapAround(value + 2 * maximum, maximum);
1138  return value;
1139 }
1140 
1141 int L1TMuonBarrelKalmanAlgo::encode(bool ownwheel, int sector, bool tag) {
1142  if (ownwheel) {
1143  if (sector == 0) {
1144  if (tag)
1145  return 9;
1146  else
1147  return 8;
1148  } else if (sector == 1) {
1149  if (tag)
1150  return 11;
1151  else
1152  return 10;
1153 
1154  } else {
1155  if (tag)
1156  return 13;
1157  else
1158  return 12;
1159  }
1160 
1161  } else {
1162  if (sector == 0) {
1163  if (tag)
1164  return 1;
1165  else
1166  return 0;
1167  } else if (sector == 1) {
1168  if (tag)
1169  return 3;
1170  else
1171  return 2;
1172 
1173  } else {
1174  if (tag)
1175  return 5;
1176  else
1177  return 4;
1178  }
1179  }
1180  return 15;
1181 }
1182 
1184  std::map<int, int> out;
1185 
1187  if (track.wheel() == -2)
1189  else if (track.wheel() == -1)
1191  else if (track.wheel() == 0)
1193  else if (track.wheel() == 1)
1195  else if (track.wheel() == 2)
1197  else
1207  //out[l1t::RegionalMuonCand::kNumBmtfSubAddr]=0; // This is commented out for better data/MC agreement
1208 
1209  for (const auto& stub : track.stubs()) {
1210  bool ownwheel = stub->whNum() == track.wheel();
1211  int sector = 0;
1212  if ((stub->scNum() == track.sector() + 1) || (stub->scNum() == 0 && track.sector() == 11))
1213  sector = +1;
1214  if ((stub->scNum() == track.sector() - 1) || (stub->scNum() == 11 && track.sector() == 0))
1215  sector = -1;
1216  int addr = encode(ownwheel, sector, stub->tag());
1217 
1218  if (stub->stNum() == 4) {
1219  if (stub->tag())
1220  addr = 1;
1221  else
1222  addr = 2;
1224  }
1225  if (stub->stNum() == 3) {
1227  }
1228  if (stub->stNum() == 2) {
1230  }
1231  if (stub->stNum() == 1) {
1233  }
1234  }
1235 
1236  word = 0;
1241 
1242  return out;
1243 }
1244 
1246  if (q >= 0)
1247  return q;
1248  else
1249  return (~q) + 1;
1250 }
1251 
1253  // return long(a*(1<<bits)*b)>>bits;
1254  return (long((a * (1 << bits)) * b)) >> bits;
1255 }
1256 
1258  int charge = (K >= 0) ? +1 : -1;
1259  float lsb = 1.25 / float(1 << 13);
1260  float FK = fabs(K);
1261 
1262  if (FK > 2047)
1263  FK = 2047.;
1264  if (FK < 26)
1265  FK = 26.;
1266 
1267  FK = FK * lsb;
1268 
1269  //step 1 -material and B-field
1270  FK = .8569 * FK / (1.0 + 0.1144 * FK);
1271  //step 2 - misalignment
1272  FK = FK - charge * 1.23e-03;
1273  //Get to BMTF scale
1274  FK = FK / 1.17;
1275 
1276  int pt = 0;
1277  if (FK != 0)
1278  pt = int(2.0 / FK);
1279 
1280  if (pt > 511)
1281  pt = 511;
1282 
1283  if (pt < 8)
1284  pt = 8;
1285 
1286  return pt;
1287 }
1288 
1291 
1292  std::map<uint, int> infoRank;
1293  std::map<uint, L1MuKBMTrack> infoTrack;
1294  for (uint i = 3; i <= 15; ++i) {
1295  if (i == 4 || i == 8)
1296  continue;
1297  infoRank[i] = -1;
1298  }
1299 
1300  for (const auto& track : tracks) {
1301  infoRank[track.hitPattern()] = rank(track);
1302  infoTrack[track.hitPattern()] = track;
1303  }
1304 
1305  int selected = 15;
1306  if (seed == 4) //station 4 seeded
1307  {
1308  int sel6 = infoRank[10] >= infoRank[12] ? 10 : 12;
1309  int sel5 = infoRank[14] >= infoRank[9] ? 14 : 9;
1310  int sel4 = infoRank[11] >= infoRank[13] ? 11 : 13;
1311  int sel3 = infoRank[sel6] >= infoRank[sel5] ? sel6 : sel5;
1312  int sel2 = infoRank[sel4] >= infoRank[sel3] ? sel4 : sel3;
1313  selected = infoRank[15] >= infoRank[sel2] ? 15 : sel2;
1314  }
1315  if (seed == 3) //station 3 seeded
1316  {
1317  int sel2 = infoRank[5] >= infoRank[6] ? 5 : 6;
1318  selected = infoRank[7] >= infoRank[sel2] ? 7 : sel2;
1319  }
1320  if (seed == 2) //station 2 seeded
1321  selected = 3;
1322 
1323  auto search = infoTrack.find(selected);
1324  if (search != infoTrack.end())
1325  out.push_back(search->second);
1326 
1327  return out;
1328 }
1329 
1331  if (stub->qeta1() != 0 && stub->qeta2() != 0) {
1332  return 0;
1333  }
1334  if (stub->qeta1() == 0) {
1335  return 0;
1336  }
1337  // return (stub->qeta1()*4+stub->stNum());
1338  return (stub->qeta1());
1339 }
1340 
1342  uint pattern = track.hitPattern();
1343  int wheel = track.stubs()[0]->whNum();
1344  uint awheel = fabs(wheel);
1345  int sign = 1;
1346  if (wheel < 0)
1347  sign = -1;
1348  uint nstubs = track.stubs().size();
1349  uint mask = 0;
1350  for (unsigned int i = 0; i < track.stubs().size(); ++i) {
1351  if (fabs(track.stubs()[i]->whNum()) != awheel)
1352  mask = mask | (1 << i);
1353  }
1354  mask = (awheel << nstubs) | mask;
1355  track.setCoarseEta(sign * lutService_->coarseEta(pattern, mask));
1356  int sumweights = 0;
1357  int sums = 0;
1358 
1359  for (const auto& stub : track.stubs()) {
1360  uint rank = etaStubRank(stub);
1361  if (rank == 0)
1362  continue;
1363  // printf("Stub station=%d rank=%d values=%d %d\n",stub->stNum(),rank,stub->eta1(),stub->eta2());
1364  sumweights += rank;
1365  sums += rank * stub->eta1();
1366  }
1367  //0.5 0.332031 0.25 0.199219 0.164063
1368  float factor;
1369  if (sumweights == 1)
1370  factor = 1.0;
1371  else if (sumweights == 2)
1372  factor = 0.5;
1373  else if (sumweights == 3)
1374  factor = 0.332031;
1375  else if (sumweights == 4)
1376  factor = 0.25;
1377  else if (sumweights == 5)
1378  factor = 0.199219;
1379  else if (sumweights == 6)
1380  factor = 0.164063;
1381  else
1382  factor = 0.0;
1383 
1384  int eta = 0;
1385  if (sums > 0)
1386  eta = fp_product(factor, sums, 10);
1387  else
1388  eta = -fp_product(factor, fabs(sums), 10);
1389 
1390  //int eta=int(factor*sums);
1391  // printf("Eta debug %f *%d=%d\n",factor,sums,eta);
1392 
1393  if (sumweights > 0)
1394  track.setFineEta(eta);
1395 }
1396 
1398  //If there is stub at station 2 use this else propagate from 1
1399  for (const auto& stub : track.stubs())
1400  if (stub->stNum() == 2)
1401  return correctedPhi(stub, track.sector());
1402 
1403  ap_fixed<BITSPHI, BITSPHI> phi = track.phiAtMuon();
1404  ap_fixed<BITSPHIB, BITSPHIB> phiB = track.phiBAtMuon();
1405  ap_fixed<BITSPARAM, 1> phiAt2 = phiAt2_;
1406  int phiNew = ap_fixed<BITSPHI + 1, BITSPHI + 1, AP_TRN_ZERO, AP_SAT>(phi + phiAt2 * phiB);
1407 
1408  if (verbose_)
1409  printf("Phi at second station=%d\n", phiNew);
1410  return phiNew;
1411 }
std::vector< double > bPhiB_
int correctedPhiB(const L1MuKBMTCombinedStubRef &)
l1t::RegionalMuonCand convertToBMTF(const L1MuKBMTrack &track)
std::vector< double > aPhi_
static const TGPicture * info(bool iBackgroundIsBlack)
std::vector< double > aPhiB_
std::vector< double > aPhiBNLO_
L1TMuonBarrelKalmanAlgo(const edm::ParameterSet &settings)
std::pair< bool, uint > match(const L1MuKBMTCombinedStubRef &, const L1MuKBMTCombinedStubRefVector &, int)
std::vector< T >::const_iterator search(const cond::Time_t &val, const std::vector< T > &container)
Definition: IOVProxy.cc:21
std::vector< double > mScatteringPhiB_
int phiAt2(const L1MuKBMTrack &track)
bool update(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &, int, int)
int rank(const L1MuKBMTrack &)
std::vector< int > trackCompPattern_
std::vector< edm::Ref< L1MuKBMTCombinedStubCollection > > L1MuKBMTCombinedStubRefVector
bool updateOffline1D(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &)
void estimateCompatibility(L1MuKBMTrack &)
bool updateLUT(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &, int, int)
void vertexConstraintLUT(L1MuKBMTrack &)
std::pair< bool, uint > getByCode(const L1MuKBMTrackCollection &tracks, int mask)
int fp_product(float, int, uint)
string quality
std::vector< double > chiSquare_
uint64_t word
std::vector< double > pointResolutionPhiBH_
std::vector< double > initK2_
ROOT::Math::SMatrix< double, 1, 3 > Matrix13
std::pair< float, float > vertexGain(uint, uint)
std::vector< double > trackComp_
std::vector< double > mScatteringPhi_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
L1TMuonBarrelKalmanLUTs * lutService_
void vertexConstraint(L1MuKBMTrack &)
int customBitmask(unsigned int, unsigned int, unsigned int, unsigned int)
Definition: value.py:1
std::vector< double > eLoss_
ROOT::Math::SMatrix< double, 3, 1 > Matrix31
bool estimateChiSquare(L1MuKBMTrack &)
void vertexConstraintOffline(L1MuKBMTrack &)
ROOT::Math::SMatrix< double, 2, 2, ROOT::Math::MatRepSym< double, 2 > > CovarianceMatrix2
uint matchAbs(std::map< uint, uint > &, uint, uint)
std::vector< int > chiSquareCutTight_
std::vector< double > bPhi_
std::vector< double > initK_
void updateEta(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &)
#define M_PI
void setFloatingPointValues(L1MuKBMTrack &, bool)
L1MuKBMTrackCollection clean(const L1MuKBMTrackCollection &, uint)
#define N
Definition: blowfish.cc:9
int encode(bool ownwheel, int sector, bool tag)
std::vector< int > chiSquareCutPattern_
std::pair< bool, L1MuKBMTrack > chain(const L1MuKBMTCombinedStubRef &, const L1MuKBMTCombinedStubRefVector &)
void calculateEta(L1MuKBMTrack &track)
double b
Definition: hdecay.h:120
std::pair< OmniClusterRef, TrackingParticleRef > P
std::vector< int > chiSquareCut_
void addBMTFMuon(int, const L1MuKBMTrack &, std::unique_ptr< l1t::RegionalMuonCandBxCollection > &)
int hitPattern(const L1MuKBMTrack &)
ROOT::Math::SVector< double, 2 > Vector2
std::vector< L1MuKBMTrack > L1MuKBMTrackCollection
Definition: L1MuKBMTrack.h:15
double a
Definition: hdecay.h:121
ROOT::Math::SMatrix< double, 2, 3 > Matrix23
int correctedPhi(const L1MuKBMTCombinedStubRef &, int)
std::vector< double > trackCompErr1_
std::vector< float > trackGain2(uint, uint, uint, uint, uint)
ROOT::Math::SMatrix< double, 3, 2 > Matrix32
std::vector< int > chiSquareCutCurv_
ROOT::Math::SMatrix< double, 3, 3 > Matrix33
step
Definition: StallMonitor.cc:83
std::vector< double > trackCompErr2_
std::vector< float > trackGain(uint, uint, uint)
math::Error< dimension >::type CovarianceMatrix
covariance error matrix (3x3)
Definition: Candidate.h:46
tmp
align.sh
Definition: createJobs.py:716
bool updateOffline(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
uint etaStubRank(const L1MuKBMTCombinedStubRef &)
std::vector< int > trackCompCutCurv_
std::map< int, int > trackAddress(const L1MuKBMTrack &, int &)
std::vector< double > pointResolutionPhiBL_