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