CMS 3D CMS Logo

L1TMuonBarrelKalmanAlgo.cc
Go to the documentation of this file.
1 #include <cmath>
3 
4 
6  verbose_(settings.getParameter<bool>("verbose")),
7  lutService_(new L1TMuonBarrelKalmanLUTs(settings.getParameter<std::string>("lutFile"))),
8  initK_(settings.getParameter<std::vector<double> >("initialK")),
9  initK2_(settings.getParameter<std::vector<double> >("initialK2")),
10  eLoss_(settings.getParameter<std::vector<double> >("eLoss")),
11  aPhi_(settings.getParameter<std::vector<double> >("aPhi")),
12  aPhiB_(settings.getParameter<std::vector<double> >("aPhiB")),
13  aPhiBNLO_(settings.getParameter<std::vector<double> >("aPhiBNLO")),
14  bPhi_(settings.getParameter<std::vector<double> >("bPhi")),
15  bPhiB_(settings.getParameter<std::vector<double> >("bPhiB")),
16  phiAt2_(settings.getParameter<std::vector<double> >("phiAt2")),
17  globalChi2Cut_(settings.getParameter<unsigned int>("globalChi2Cut")),
18  chiSquare_(settings.getParameter<std::vector<double> >("chiSquare")),
19  chiSquareCutPattern_(settings.getParameter<std::vector<int> >("chiSquareCutPattern")),
20  chiSquareCutCurv_(settings.getParameter<std::vector<int> >("chiSquareCutCurvMax")),
21  chiSquareCut_(settings.getParameter<std::vector<int> >("chiSquareCut")),
22  combos4_(settings.getParameter<std::vector<int> >("combos4")),
23  combos3_(settings.getParameter<std::vector<int> >("combos3")),
24  combos2_(settings.getParameter<std::vector<int> >("combos2")),
25  combos1_(settings.getParameter<std::vector<int> >("combos1")),
26  useOfflineAlgo_(settings.getParameter<bool>("useOfflineAlgo")),
27  mScatteringPhi_(settings.getParameter<std::vector<double> >("mScatteringPhi")),
28  mScatteringPhiB_(settings.getParameter<std::vector<double> >("mScatteringPhiB")),
29  pointResolutionPhi_(settings.getParameter<double>("pointResolutionPhi")),
30  pointResolutionPhiB_(settings.getParameter<double>("pointResolutionPhiB")),
31  pointResolutionVertex_(settings.getParameter<double>("pointResolutionVertex"))
32 
33 {
34 
35 
36 
37 }
38 
39 
40 
42  for (uint i=0;i<tracks.size();++i) {
43  printf("Code=%d, track=%d\n",tracks[i].hitPattern(),mask);
44  if (tracks[i].hitPattern()==mask)
45  return std::make_pair(true,i);
46  }
47  return std::make_pair(false,0);
48 }
49 
50 
53  int K = fabs(track.curvatureAtVertex());
54  //calibration
55  int sign,signValid;
56 
57  if (track.curvatureAtVertex()==0) {
58  sign=0;
59  signValid=0;
60  }
61  else if (track.curvatureAtVertex()>0) {
62  sign=0;
63  signValid=1;
64  }
65  else {
66  sign=1;
67  signValid=1;
68  }
69 
70  if (K<22)
71  K=22;
72 
73  if (K>4095)
74  K=4095;
75 
76  int pt = ptLUT(K);
77 
78 
79  int K2 = fabs(track.curvatureAtMuon());
80  if (K2<22)
81  K2=22;
82 
83  if (K2>4095)
84  K2=4095;
85  int pt2 = ptLUT(K2)/2;
86  int eta = track.hasFineEta() ? track.fineEta() : track.coarseEta();
87 
88  int phi=track.phiAtMuon()+1024;
89  int signPhi=1;
90  if (phi>=0) {
91  phi = phi>>1;
92  signPhi=1;
93  }
94  else {
95  phi = (-phi)>>1;
96  signPhi=-1;
97  }
98  phi =signPhi*int((phi*2*M_PI/(6.0*2048.0))/(0.625*M_PI/180.0));
99 
100  int processor=track.sector();
101  int HF = track.hasFineEta();
102 
103  int quality=12|(rank(track)>>6);
104 
105  int dxy=abs(track.dxy())>>9;
106 
107  int trackAddr;
108  std::map<int,int> addr = trackAddress(track,trackAddr);
109 
110  l1t::RegionalMuonCand muon(pt,phi,eta,sign,signValid,quality,processor,l1t::bmtf,addr);
111  muon.setHwHF(HF);
112  muon.setHwPt2(pt2);
113  muon.setHwDXY(dxy);
114 
115 
116  //nw the words!
117  uint32_t word1=pt;
118  word1=word1 | quality<<9;
119  word1=word1 | (twosCompToBits(eta))<<13;
120  word1=word1 | HF<<22;
121  word1=word1 | (twosCompToBits(phi))<<23;
122 
123  uint32_t word2=sign;
124  word2=word2 | signValid<<1;
125  word2=word2 | dxy<<2;
126  word2=word2 | trackAddr<<4;
127  word2=word2 | (twosCompToBits(track.wheel()))<<20;
128  word2=word2 | pt2<<23;
129  muon.setDataword(word2,word1);
130  return muon;
131 }
132 
133 void L1TMuonBarrelKalmanAlgo::addBMTFMuon(int bx,const L1MuKBMTrack& track, std::unique_ptr<l1t::RegionalMuonCandBxCollection>& out) {
134  out->push_back(bx,convertToBMTF(track));
135 }
136 
137 
138 
141 
142  bool found=false;
143  uint best=0;
144  int distance=100000;
145  uint N=0;
146  for (const auto& stub :stubs) {
147  N=N+1;
148  if (stub->stNum()!=step)
149  continue;
150 
151  int d = fabs(wrapAround(((correctedPhi(seed,seed->scNum())-correctedPhi(stub,seed->scNum()))>>3),1024));
152  if (d<distance) {
153  distance = d;
154  best=N-1;
155  found=true;
156  }
157  }
158  return std::make_pair(found,best);
159 }
160 
161 
162 
164  //Promote phiB to 12 bits
165  return 8*stub->phiB();
166 
167 }
168 
170  if (stub->scNum()==sector) {
171  return stub->phi();
172  }
173  else if ((stub->scNum()==sector-1) || (stub->scNum()==11 && sector==0)) {
174  return stub->phi()-2144;
175  }
176  else if ((stub->scNum()==sector+1) || (stub->scNum()==0 && sector==11)) {
177  return stub->phi()+2144;
178  }
179  return stub->phi();
180 }
181 
182 
184  unsigned int mask = 0;
185  for (const auto& stub : track.stubs()) {
186  mask = mask+round(pow(2,stub->stNum()-1));
187  }
188  return mask;
189 }
190 
191 
192 
193 int L1TMuonBarrelKalmanAlgo::customBitmask(unsigned int bit1,unsigned int bit2,unsigned int bit3,unsigned int bit4) {
194  return bit1*1+bit2*2+bit3*4+bit4*8;
195 }
196 
197 bool L1TMuonBarrelKalmanAlgo::getBit(int bitmask,int pos) {
198  return (bitmask & ( 1 << pos )) >> pos;
199 }
200 
201 
202 
204  int K = track.curvature();
205  int phi = track.positionAngle();
206  int phiB = track.bendingAngle();
207  unsigned int step = track.step();
208 
209  //energy loss term only for MU->VERTEX
210  //int offset=int(charge*eLoss_[step-1]*K*K);
211  // if (fabs(offset)>4096)
212  // offset=4096*offset/fabs(offset);
213 
214  int charge=1;
215  if (K!=0)
216  charge = K/fabs(K);
217 
218 
219 
220 
221  int KBound=K;
222  if (KBound>4095)
223  KBound=4095;
224  if (KBound<-4095)
225  KBound=-4095;
226 
227  int deltaK=0;
228  int KNew=0;
229  if (step==1) {
230  int addr = KBound/2;
231  if (addr<0)
232  addr=(-KBound)/2;
233  deltaK =2*addr-int(2*addr/(1+eLoss_[step-1]*addr));
234 
235  if (verbose_)
236  printf("propagate to vertex K=%d deltaK=%d addr=%d\n",K,deltaK,addr);
237  }
238 
239  if (K>=0)
240  KNew=K-deltaK;
241  else
242  KNew=K+deltaK;
243 
244 
245  //phi propagation
246  int phi11 = fp_product(aPhi_[step-1],K,10);
247  int phi12 = fp_product(-bPhi_[step-1],phiB,10);
248  if (verbose_) {
249  printf("phi prop = %d* %f = %d, %d* %f =%d\n",K,aPhi_[step-1],phi11,phiB,-bPhi_[step-1],phi12);
250  }
251  int phiNew =wrapAround(phi+phi11+phi12,8192);
252  //phiB propagation
253  int phiB11 = fp_product(aPhiB_[step-1],K,10);
254  int phiB12 = fp_product(bPhiB_[step-1],phiB,11);
255  int phiBNew = wrapAround(phiB11+phiB12,2048);
256  if (verbose_) {
257  printf("phiB prop = %d* %f = %d, %d* %f =%d\n",K,aPhiB_[step-1],phiB11,phiB,bPhiB_[step-1],phiB12);
258  }
259 
260 
261  //Only for the propagation to vertex we use the LUT for better precision and the full function
262  if (step==1) {
263  int addr = KBound/2;
264  phiBNew = wrapAround(int(aPhiB_[step-1]*addr/(1+charge*aPhiBNLO_[step-1]*addr))+int(bPhiB_[step-1]*phiB),2048);
265  }
267  //Rest of the stuff is for the offline version only
268  //where we want to check what is happening in the covariaznce matrix
269 
270  //Create the transformation matrix
271  double a[9];
272  a[0] = 1.;
273  a[1] = 0.0;
274  a[2] = 0.0;
275  a[3] = aPhi_[step-1];
276  // a[3] = 0.0;
277  a[4] = 1.0;
278  a[5] = -bPhi_[step-1];
279  //a[6]=0.0;
280  a[6] = aPhiB_[step-1];
281  a[7] = 0.0;
282  a[8] = bPhiB_[step-1];
283 
284 
285  ROOT::Math::SMatrix<double,3> P(a,9);
286 
287  const std::vector<double>& covLine = track.covariance();
288  L1MuKBMTrack::CovarianceMatrix cov(covLine.begin(),covLine.end());
289  cov = ROOT::Math::Similarity(P,cov);
290 
291 
292  //Add the multiple scattering
293  double phiRMS = mScatteringPhi_[step-1]*K*K;
294  double phiBRMS = mScatteringPhiB_[step-1]*K*K;
295 
296  std::vector<double> b(6);
297  b[0] = 0;
298  b[1] = 0;
299  b[2] =phiRMS;
300  b[3] =0;
301  b[4] = 0;
302  b[5] = phiBRMS;
303 
304  reco::Candidate::CovarianceMatrix MS(b.begin(),b.end());
305 
306  cov = cov+MS;
307 
308  if (verbose_) {
309  printf("Covariance term for phiB = %f\n",cov(2,2));
310  printf("Multiple scattering term for phiB = %f\n",MS(2,2));
311  }
312 
313 
314 
315  track.setCovariance(cov);
316  track.setCoordinates(step-1,KNew,phiNew,phiBNew);
317 
318 }
319 
320 
322  updateEta(track,stub);
323  if (useOfflineAlgo_) {
324  if (mask==3 || mask ==5 || mask==9 ||mask==6|| mask==10 ||mask==12)
325  return updateOffline(track,stub);
326  else
327  return updateOffline1D(track,stub);
328 
329  }
330  else
331  return updateLUT(track,stub,mask);
332 
333 }
334 
336  int trackK = track.curvature();
337  int trackPhi = track.positionAngle();
338  int trackPhiB = track.bendingAngle();
339 
340  int phi = correctedPhi(stub,track.sector());
341  int phiB = correctedPhiB(stub);
342 
343 
344 
345 
346  Vector2 residual;
347  residual[0] = phi-trackPhi;
348  residual[1] = phiB-trackPhiB;
349 
350 
351 
352 
353  // if (stub->quality()<4)
354  // phiB=trackPhiB;
355 
356  Matrix23 H;
357  H(0,0)=0.0;
358  H(0,1)=1.0;
359  H(0,2)=0.0;
360  H(1,0)=0.0;
361  H(1,1)=0.0;
362  H(1,2)=1.0;
363 
364 
366  R(0,0) = pointResolutionPhi_;
367  R(0,1) = 0.0;
368  R(1,0) = 0.0;
369  R(1,1) = pointResolutionPhiB_;
370 
371  const std::vector<double>& covLine = track.covariance();
372  L1MuKBMTrack::CovarianceMatrix cov(covLine.begin(),covLine.end());
373 
374 
375  CovarianceMatrix2 S = ROOT::Math::Similarity(H,cov)+R;
376  if (!S.Invert())
377  return false;
378  Matrix32 Gain = cov*ROOT::Math::Transpose(H)*S;
379 
380  track.setKalmanGain(track.step(),fabs(trackK),Gain(0,0),Gain(0,1),Gain(1,0),Gain(1,1),Gain(2,0),Gain(2,1));
381 
382  int KNew = (trackK+int(Gain(0,0)*residual(0)+Gain(0,1)*residual(1)));
383  if (fabs(KNew)>8192)
384  return false;
385 
386  int phiNew = wrapAround(trackPhi+residual(0),8192);
387  int phiBNew = wrapAround(trackPhiB+int(Gain(2,0)*residual(0)+Gain(2,1)*residual(1)),2048);
388 
389  track.setResidual(stub->stNum()-1,fabs(phi-phiNew)+fabs(phiB-phiBNew)/8);
390 
391 
392  if (verbose_) {
393  printf(" K = %d + %f * %f + %f * %f\n",trackK,Gain(0,0),residual(0),Gain(0,1),residual(1));
394  printf(" phiB = %d + %f * %f + %f * %f\n",trackPhiB,Gain(2,0),residual(0),Gain(2,1),residual(1));
395  }
396 
397 
398  track.setCoordinates(track.step(),KNew,phiNew,phiBNew);
399  Matrix33 covNew = cov - Gain*(H*cov);
401 
402  c(0,0)=covNew(0,0);
403  c(0,1)=covNew(0,1);
404  c(0,2)=covNew(0,2);
405  c(1,0)=covNew(1,0);
406  c(1,1)=covNew(1,1);
407  c(1,2)=covNew(1,2);
408  c(2,0)=covNew(2,0);
409  c(2,1)=covNew(2,1);
410  c(2,2)=covNew(2,2);
411  if (verbose_) {
412  printf("Post Fit Covariance Matrix %f %f %f \n",cov(0,0),cov(1,1),cov(2,2));
413 
414  }
415 
416  track.setCovariance(c);
417  track.addStub(stub);
418  track.setHitPattern(hitPattern(track));
419 
420  return true;
421 }
422 
423 
425  int trackK = track.curvature();
426  int trackPhi = track.positionAngle();
427  int trackPhiB = track.bendingAngle();
428 
429 
430  int phi = correctedPhi(stub,track.sector());
431 
432 
433  double residual= phi-trackPhi;
434 
435  Matrix13 H;
436  H(0,0)=0.0;
437  H(0,1)=1.0;
438  H(0,2)=0.0;
439 
440 
441  const std::vector<double>& covLine = track.covariance();
442  L1MuKBMTrack::CovarianceMatrix cov(covLine.begin(),covLine.end());
443 
444  double S = ROOT::Math::Similarity(H,cov)(0,0)+pointResolutionPhi_;
445 
446  if (S==0.0)
447  return false;
448  Matrix31 Gain = cov*ROOT::Math::Transpose(H)/S;
449 
450  track.setKalmanGain(track.step(),fabs(trackK),Gain(0,0),0.0,Gain(1,0),0.0,Gain(2,0),0.0);
451 
452  int KNew = wrapAround(trackK+int(Gain(0,0)*residual),8192);
453  int phiNew = wrapAround(trackPhi+residual,8192);
454  int phiBNew = wrapAround(trackPhiB+int(Gain(2,0)*residual),2048);
455  track.setCoordinates(track.step(),KNew,phiNew,phiBNew);
456  Matrix33 covNew = cov - Gain*(H*cov);
458 
459  c(0,0)=covNew(0,0);
460  c(0,1)=covNew(0,1);
461  c(0,2)=covNew(0,2);
462  c(1,0)=covNew(1,0);
463  c(1,1)=covNew(1,1);
464  c(1,2)=covNew(1,2);
465  c(2,0)=covNew(2,0);
466  c(2,1)=covNew(2,1);
467  c(2,2)=covNew(2,2);
468  track.setCovariance(c);
469  track.addStub(stub);
470  track.setHitPattern(hitPattern(track));
471 
472  return true;
473 }
474 
475 
476 
478  int trackK = track.curvature();
479  int trackPhi = track.positionAngle();
480  int trackPhiB = track.bendingAngle();
481 
482 
483  int phi = correctedPhi(stub,track.sector());
484  int phiB = correctedPhiB(stub);
485  // if (stub->quality()<6)
486  // phiB=trackPhiB;
487 
488  Vector2 residual;
489  int residualPhi = wrapAround(phi-trackPhi,8192);
490  int residualPhiB = wrapAround(phiB-trackPhiB,2048);
491 
492 
493  if (verbose_)
494  printf("residuals %d %d\n",int(residualPhi),int(residualPhiB));
495 
496 
497  uint absK = fabs(trackK);
498  if (absK>4095)
499  absK = 4095;
500 
501  std::vector<float> GAIN;
502  //For the three stub stuff use only gains 0 and 4
503  if (!(mask==3 || mask ==5 || mask==9 ||mask==6|| mask==10 ||mask==12)) {
504  GAIN = lutService_->trackGain(track.step(),track.hitPattern(),absK/4);
505  GAIN[1]=0.0;
506  GAIN[3]=0.0;
507 
508  }
509  else {
510  GAIN = lutService_->trackGain2(track.step(),track.hitPattern(),absK/8);
511 
512 
513  }
514  if (verbose_)
515  printf("Gains:%d %f %f %f %f\n",absK/4,GAIN[0],GAIN[1],GAIN[2],GAIN[3]);
516  track.setKalmanGain(track.step(),fabs(trackK),GAIN[0],GAIN[1],1,0,GAIN[2],GAIN[3]);
517 
518  int k_0 = fp_product(GAIN[0],residualPhi,3);
519  int k_1 = fp_product(GAIN[1],residualPhiB,5);
520  int KNew = wrapAround(trackK+k_0+k_1,8192);
521 
522  if (verbose_)
523  printf("Kupdate: %d %d\n",k_0,k_1);
524 
525  int phiNew = phi;
526 
527  //different products for different firmware logic
528  int pbdouble_0 = fp_product(fabs(GAIN[2]),residualPhi,9);
529  int pb_0 = fp_product(GAIN[2],residualPhi,9);
530  int pb_1 = fp_product(GAIN[3],residualPhiB,9);
531 
532  if (verbose_)
533  printf("phiupdate: %d %d\n",pb_0,pb_1);
534 
535  int phiBNew;
536  if (!(mask==3 || mask ==5 || mask==9 ||mask==6|| mask==10 ||mask==12))
537  phiBNew = wrapAround(trackPhiB+pb_0,2048);
538  else
539  phiBNew = wrapAround(trackPhiB+pb_1-pbdouble_0,2048);
540 
541  track.setCoordinates(track.step(),KNew,phiNew,phiBNew);
542  track.addStub(stub);
543  track.setHitPattern(hitPattern(track));
544  return true;
545 }
546 
547 
548 
549 
551 
552 
553 
554 
555 }
556 
557 
558 
559 
560 
561 
563  if (useOfflineAlgo_)
565  else
566  vertexConstraintLUT(track);
567 
568 }
569 
570 
572  double residual = -track.dxy();
573  Matrix13 H;
574  H(0,0)=0;
575  H(0,1)=0;
576  H(0,2)=1;
577 
578  const std::vector<double>& covLine = track.covariance();
579  L1MuKBMTrack::CovarianceMatrix cov(covLine.begin(),covLine.end());
580 
581  double S = (ROOT::Math::Similarity(H,cov))(0,0)+pointResolutionVertex_;
582  S=1.0/S;
583  Matrix31 Gain = cov*(ROOT::Math::Transpose(H))*S;
584  track.setKalmanGain(track.step(),fabs(track.curvature()),Gain(0,0),Gain(1,0),Gain(2,0));
585 
586  if (verbose_) {
587  printf("sigma3=%f sigma6=%f\n",cov(0,3),cov(3,3));
588  printf(" K = %d + %f * %f\n",track.curvature(),Gain(0,0),residual);
589  }
590 
591  int KNew = wrapAround(int(track.curvature()+Gain(0,0)*residual),8192);
592  int phiNew = wrapAround(int(track.positionAngle()+Gain(1,0)*residual),8192);
593  int dxyNew = wrapAround(int(track.dxy()+Gain(2,0)*residual),8192);
594  if (verbose_)
595  printf("Post fit impact parameter=%d\n",dxyNew);
596  track.setCoordinatesAtVertex(KNew,phiNew,-residual);
597  Matrix33 covNew = cov - Gain*(H*cov);
599  c(0,0)=covNew(0,0);
600  c(0,1)=covNew(0,1);
601  c(0,2)=covNew(0,2);
602  c(1,0)=covNew(1,0);
603  c(1,1)=covNew(1,1);
604  c(1,2)=covNew(1,2);
605  c(2,0)=covNew(2,0);
606  c(2,1)=covNew(2,1);
607  c(2,2)=covNew(2,2);
608  track.setCovariance(c);
609  // track.covariance = track.covariance - Gain*H*track.covariance;
610 }
611 
612 
613 
615  double residual = -track.dxy();
616  uint absK = fabs(track.curvature());
617  if (absK>2047)
618  absK = 2047;
619 
620 std::pair<float,float> GAIN = lutService_->vertexGain(track.hitPattern(),absK/2);
621  track.setKalmanGain(track.step(),fabs(track.curvature()),GAIN.first,GAIN.second,-1);
622 
623  int k_0 = fp_product(GAIN.first,int(residual),7);
624  int KNew = wrapAround(track.curvature()+k_0,8192);
625 
626  if (verbose_) {
627  printf("VERTEX GAIN(%d)= %f * %d = %d\n",absK/2,GAIN.first,int(residual),k_0);
628 
629  }
630 
631 
632  int p_0 = fp_product(GAIN.second,int(residual),7);
633  int phiNew = wrapAround(track.positionAngle()+p_0,8192);
634  track.setCoordinatesAtVertex(KNew,phiNew,-residual);
635 }
636 
637 
638 
640  int K,phiINT,etaINT;
641 
642  if (track.hasFineEta())
643  etaINT=track.fineEta();
644  else
645  etaINT=track.coarseEta();
646 
647 
648  double lsb = 1.25/float(1 << 13);
649  double lsbEta = 0.010875;
650 
651 
652  if (vertex) {
653  K = track.curvatureAtVertex();
654  if (K==0)
655  track.setCharge(1);
656  else
657  track.setCharge(K/fabs(K));
658 
659  phiINT = track.phiAtVertex();
660  double phi= track.sector()*M_PI/6.0+phiINT*M_PI/(6*2048.)-2*M_PI;
661  double eta = etaINT*lsbEta;
662  if (phi<-M_PI)
663  phi=phi+2*M_PI;
664  if (K==0)
665  K=1;
666 
667 
668  float FK=fabs(K);
669  if (FK<51)
670  FK=51;
671  double pt = 1.0/(lsb*(FK));
672 
673  track.setPtEtaPhi(pt,eta,phi);
674  }
675  else {
676  K=track.curvatureAtMuon();
677  if (K==0)
678  K=1;
679  if (fabs(K)<46)
680  K=46*K/fabs(K);
681  double pt = 1.0/(lsb*fabs(K));
682  track.setPtUnconstrained(pt);
683  }
684 }
685 
686 
687 
689  L1MuKBMTrackCollection pretracks;
690  std::vector<int> combinatorics;
691  switch(seed->stNum()) {
692  case 1:
693  combinatorics=combos1_;
694  break;
695  case 2:
696  combinatorics=combos2_;
697  break;
698 
699  case 3:
700  combinatorics=combos3_;
701  break;
702 
703  case 4:
704  combinatorics=combos4_;
705  break;
706 
707  default:
708  printf("Something really bad happend\n");
709  }
710 
711  L1MuKBMTrack nullTrack(seed,correctedPhi(seed,seed->scNum()),correctedPhiB(seed));
712 
713  for( const auto& mask : combinatorics) {
714  L1MuKBMTrack track(seed,correctedPhi(seed,seed->scNum()),correctedPhiB(seed));
715  int phiB = correctedPhiB(seed);
716  int charge;
717  if (phiB==0)
718  charge = 0;
719  else
720  charge=phiB/fabs(phiB);
721 
722  int address=phiB;
723  if (track.step()>=3 && (fabs(seed->phiB())>63))
724  address=charge*63*8;
725  if (track.step()==2 && (fabs(seed->phiB())>127))
726  address=charge*127*8;
727  int initialK = int(initK_[seed->stNum()-1]*address/(1+initK2_[seed->stNum()-1]*charge*address));
728  if (initialK>8191)
729  initialK=8191;
730  if (initialK<-8191)
731  initialK=-8191;
732  track.setCoordinates(seed->stNum(),initialK,correctedPhi(seed,seed->scNum()),phiB);
733  if (seed->quality()<4) {
734  track.setCoordinates(seed->stNum(),0,correctedPhi(seed,seed->scNum()),0);
735  }
736 
737 
738 
739  track.setHitPattern(hitPattern(track));
740  //set covariance
741  L1MuKBMTrack::CovarianceMatrix covariance;
742 
743 
744  float DK=512*512.;
745  covariance(0,0)=DK;
746  covariance(0,1)=0;
747  covariance(0,2)=0;
748  covariance(1,0)=0;
749  covariance(1,1)=float(pointResolutionPhi_);
750  covariance(1,2)=0;
751  covariance(2,0)=0;
752  covariance(2,1)=0;
753  covariance(2,2)=float(pointResolutionPhiB_);
754  track.setCovariance(covariance);
755  //
756  if (verbose_) {
757  printf("New Kalman fit staring at step=%d, phi=%d,phiB=%d with curvature=%d\n",track.step(),track.positionAngle(),track.bendingAngle(),track.curvature());
758  printf("BITMASK:");
759  for (unsigned int i=0;i<4;++i)
760  printf("%d",getBit(mask,i));
761  printf("\n");
762  printf("------------------------------------------------------\n");
763  printf("------------------------------------------------------\n");
764  printf("------------------------------------------------------\n");
765  printf("stubs:\n");
766  for (const auto& stub: stubs)
767  printf("station=%d phi=%d phiB=%d qual=%d tag=%d sector=%d wheel=%d fineEta= %d %d\n",stub->stNum(),correctedPhi(stub,seed->scNum()),correctedPhiB(stub),stub->quality(),stub->tag(),stub->scNum(),stub->whNum(),stub->eta1(),stub->eta2());
768  printf("------------------------------------------------------\n");
769  printf("------------------------------------------------------\n");
770 
771  }
772 
773  int phiAtStation2=0;
774 
775  while(track.step()>0) {
776  // muon station 1
777  if (track.step()==1) {
778  track.setCoordinatesAtMuon(track.curvature(),track.positionAngle(),track.bendingAngle());
779  phiAtStation2=phiAt2(track);
783  //calculate coarse eta
785 
786 
787  if (verbose_)
788  printf ("Unconstrained PT in Muon System: pt=%f\n",track.ptUnconstrained());
789  }
790 
791  propagate(track);
792  if (verbose_)
793  printf("propagated Coordinates step:%d,phi=%d,phiB=%d,K=%d\n",track.step(),track.positionAngle(),track.bendingAngle(),track.curvature());
794 
795  if (track.step()>0)
796  if (getBit(mask,track.step()-1)) {
797  std::pair<bool,uint> bestStub = match(seed,stubs,track.step());
798  if ((!bestStub.first) || (!update(track,stubs[bestStub.second],mask)))
799  break;
800  if (verbose_) {
801  printf("updated Coordinates step:%d,phi=%d,phiB=%d,K=%d\n",track.step(),track.positionAngle(),track.bendingAngle(),track.curvature());
802  }
803  }
804 
805 
806  if (track.step()==0) {
807  track.setCoordinatesAtVertex(track.curvature(),track.positionAngle(),track.bendingAngle());
808  if (verbose_)
809  printf(" Coordinates before vertex constraint step:%d,phi=%d,dxy=%d,K=%d\n",track.step(),track.phiAtVertex(),track.dxy(),track.curvatureAtVertex());
810  if (verbose_)
811  printf("Chi Square = %d\n",track.approxChi2());
812 
813  if (fabs(track.approxChi2())>globalChi2Cut_)
814  break;
816  if (verbose_) {
817  printf(" Coordinates after vertex constraint step:%d,phi=%d,dxy=%d,K=%d maximum local chi2=%d\n",track.step(),track.phiAtVertex(),track.dxy(),track.curvatureAtVertex(),track.approxChi2());
818  printf("------------------------------------------------------\n");
819  printf("------------------------------------------------------\n");
820  }
822  //rset the coordinates at muon to include phi at station 2
823  track.setCoordinatesAtMuon(track.curvatureAtMuon(),phiAtStation2,track.phiBAtMuon());
824  track.setRank(rank(track));
825  if (verbose_)
826  printf ("Floating point coordinates at vertex: pt=%f, eta=%f phi=%f\n",track.pt(),track.eta(),track.phi());
827  pretracks.push_back(track);
828  }
829  }
830  }
831  //Now for all the pretracks we need only one
832  L1MuKBMTrackCollection cleaned = clean(pretracks,seed->stNum());
833 
834  if (!cleaned.empty()) {
835  bool veto = punchThroughVeto(cleaned[0]);
836  if (verbose_)
837  printf("Punch through veto=%d\n",veto);
838  if (!veto)
839  return std::make_pair(true,cleaned[0]);
840  }
841  return std::make_pair(false,nullTrack);
842 }
843 
844 
845 
846 
847 
848 
850  //here we have a simplification of the algorithm for the sake of the emulator - rsult is identical
851  // we apply cuts on the firmware as |u -u'|^2 < a+b *K^2
852  int K = track.curvatureAtMuon();
853 
854  int chi=0;
855  // printf("Starting Chi calculation\n");
856  int coords = (track.phiAtMuon()+track.phiBAtMuon())>>3;
857  for (const auto& stub: track.stubs()) {
858  int AK = fp_product(-chiSquare_[stub->stNum()-1],K>>3,8);
859  int stubCoords = (correctedPhi(stub,track.sector())>>3)+stub->phiB();
860  uint delta = fabs(stubCoords-coords+AK);
861  // printf("station=%d AK=%d delta=%d\n",stub->stNum(),AK,delta);
862 
863  chi=chi+fabs(delta);
864  }
865  // chi=chi/2;
866  if (chi>127)
867  chi=127;
868  track.setApproxChi2(chi);
869 }
870 
871 
873  // int offset=0;
874  if (hitPattern(track)==customBitmask(0,0,1,1))
875  return 60;
876  // return offset+(track.stubs().size()*2+track.quality())*80-track.approxChi2();
877  return 160+(track.stubs().size())*20-track.approxChi2();
878 
879 }
880 
881 
882 
884  if (value>maximum-1)
885  return value-2*maximum;
886  if (value<-maximum)
887  return value+2*maximum;
888  return value;
889 
890 }
891 
892 
894  for (uint i=0;i<chiSquareCutPattern_.size();++i) {
895  if (track.hitPattern()==chiSquareCutPattern_[i] && fabs(track.curvatureAtVertex())<chiSquareCutCurv_[i] && track.approxChi2()>chiSquareCut_[i] && track.curvature()*track.dxy()<0)
896  return true;
897  }
898 
899  return false;
900 }
901 
904 
905  if (verbose_)
906  printf(" -----Preselected Kalman Tracks-----\n");
907 
908 
909  for(const auto& track1 : pretracks) {
910  if (verbose_)
911  printf("Pre Track charge=%d pt=%f eta=%f phi=%f curvature=%d curvature STA =%d stubs=%d bitmask=%d rank=%d chi=%d pts=%f %f\n",track1.charge(),track1.pt(),track1.eta(),track1.phi(),track1.curvatureAtVertex(),track1.curvatureAtMuon(),int(track1.stubs().size()),track1.hitPattern(),rank(track1),track1.approxChi2(),track1.pt(),track1.ptUnconstrained());
912 
913  bool keep=true;
914  for(const auto& track2 : pretracks) {
915  if (track1==track2)
916  continue;
917  if (!track1.overlapTrack(track2))
918  continue;
919  if (track1.rank()<track2.rank())
920  keep=false;
921  }
922  if (keep)
923  out.push_back(track1);
924  }
925 
926  if (verbose_) {
927  printf(" -----Algo Result Kalman Tracks-----\n");
928  for (const auto& track1 :out)
929  printf("Final Kalman Track charge=%d pt=%f eta=%f phi=%f curvature=%d curvature STA =%d stubs=%d chi2=%d pts=%f %f\n",track1.charge(),track1.pt(),track1.eta(),track1.phi(),track1.curvatureAtVertex(),track1.curvatureAtMuon(),int(track1.stubs().size()),track1.approxChi2(),track1.pt(),track1.ptUnconstrained());
930  }
931 
932 
933 
935  if (!out.empty())
936  std::sort(out.begin(),out.end(),sorter);
937 
938 
939  L1MuKBMTrackCollection exported;
940  for (uint i=0;i<out.size();++i)
941  if (i<=keep)
942  exported.push_back(out[i]);
943  return exported;
944 }
945 
946 
947 int L1TMuonBarrelKalmanAlgo::encode(bool ownwheel,int sector,bool tag) {
948  if (ownwheel) {
949  if (sector==0) {
950  if (tag)
951  return 9;
952  else
953  return 8;
954  }
955  else if (sector==1) {
956  if (tag)
957  return 11;
958  else
959  return 10;
960 
961  }
962  else {
963  if (tag)
964  return 13;
965  else
966  return 12;
967  }
968 
969  }
970  else {
971  if (sector==0) {
972  if (tag)
973  return 1;
974  else
975  return 0;
976  }
977  else if (sector==1) {
978  if (tag)
979  return 3;
980  else
981  return 2;
982 
983  }
984  else {
985  if (tag)
986  return 5;
987  else
988  return 4;
989  }
990  }
991  return 15;
992 }
993 
994 
995 
996 
997 std::map<int,int> L1TMuonBarrelKalmanAlgo::trackAddress(const L1MuKBMTrack& track,int& word) {
998  std::map<int,int> out;
999  if (track.wheel()>=0)
1001  else
1003 
1004  out[l1t::RegionalMuonCand::kWheelNum] = fabs(track.wheel());
1014 
1015 
1016  for (const auto stub: track.stubs()) {
1017  bool ownwheel = stub->whNum() == track.wheel();
1018  int sector=0;
1019  if ((stub->scNum()==track.sector()+1) || (stub->scNum()==0 && track.sector()==11))
1020  sector=+1;
1021  if ((stub->scNum()==track.sector()-1) || (stub->scNum()==11 && track.sector()==0))
1022  sector=-1;
1023  int addr = encode(ownwheel,sector,stub->tag());
1024 
1025  if (stub->stNum()==4) {
1026  addr=addr & 3;
1028  }
1029  if (stub->stNum()==3) {
1030  out[l1t::RegionalMuonCand::kStat2]=addr;
1031  }
1032  if (stub->stNum()==2) {
1034  }
1035  if (stub->stNum()==1) {
1037  }
1038  }
1039 
1040  word=0;
1041  word = word | out[l1t::RegionalMuonCand::kStat1]<<12;
1042  word = word | out[l1t::RegionalMuonCand::kStat2]<<8;
1043  word = word | out[l1t::RegionalMuonCand::kStat3]<<4;
1044  word = word | out[l1t::RegionalMuonCand::kStat4];
1045 
1046 
1047 
1048  return out;
1049 }
1050 
1051 
1052 
1054  if (q>=0)
1055  return q;
1056  else
1057  return (~q)+1;
1058 
1059 
1060 }
1061 
1062 
1063 
1065  return long(a*(1<<bits)*b)>>bits;
1066 }
1067 
1068 
1069 
1071  float lsb=1.25/float(1<<13);
1072  float ptF = (2*(1.0/(lsb*float(K))));
1073  float KF = 1.0/ptF;
1074  int pt=0;
1075  KF = 0.797*KF+0.454*KF*KF-5.679e-4;
1076  if (KF!=0)
1077  pt=int(1.0/KF);
1078  else
1079  pt=511;
1080 
1081  if (pt>511)
1082  pt=511;
1083  return pt;
1084 }
1085 
1086 
1087 
1088 
1089 
1090 
1091 
1094 
1095  std::map<uint,int> infoRank;
1096  std::map<uint,L1MuKBMTrack> infoTrack;
1097  for (uint i=3;i<=15;++i) {
1098  if (i==4 ||i==8)
1099  continue;
1100  infoRank[i]=-1;
1101  }
1102 
1103  for (const auto& track :tracks) {
1104  infoRank[track.hitPattern()] = rank(track);
1105  infoTrack[track.hitPattern()]=track;
1106  }
1107 
1108 
1109  int selected=15;
1110  if (seed==4) //station 4 seeded
1111  {
1112  int sel6 = infoRank[12]>= infoRank[10] ? 12 : 10;
1113  int sel5 = infoRank[14]>= infoRank[9] ? 14 : 9;
1114  int sel4 = infoRank[11]>= infoRank[13] ? 11 : 13;
1115  int sel3 = infoRank[sel6]>= infoRank[sel5] ? sel6 : sel5;
1116  int sel2 = infoRank[sel4]>= infoRank[sel3] ? sel4 : sel3;
1117  selected = infoRank[15]>= infoRank[sel2] ? 15 : sel2;
1118  }
1119  if (seed==3) //station 3 seeded
1120  {
1121  int sel2 = infoRank[5]>= infoRank[6] ? 5 : 6;
1122  selected = infoRank[7]>= infoRank[sel2] ? 7 : sel2;
1123  }
1124  if (seed==2) //station 3 seeded
1125  selected = 3;
1126 
1127  auto search = infoTrack.find(selected);
1128  if (search != infoTrack.end())
1129  out.push_back(search->second);
1130 
1131  return out;
1132 
1133 
1134 }
1135 
1137 
1138  if (stub->qeta1()!=0 && stub->qeta2()!=0) {
1139  return 0;
1140  }
1141  if (stub->qeta1()==0) {
1142  return 0;
1143  }
1144  // return (stub->qeta1()*4+stub->stNum());
1145  return (stub->qeta1());
1146 
1147 }
1148 
1150  uint pattern = track.hitPattern();
1151  int wheel = track.stubs()[0]->whNum();
1152  uint awheel=fabs(wheel);
1153  int sign=1;
1154  if (wheel<0)
1155  sign=-1;
1156  uint nstubs = track.stubs().size();
1157  uint mask=0;
1158  for (unsigned int i=0;i<track.stubs().size();++i) {
1159  if (fabs(track.stubs()[i]->whNum())!=awheel)
1160  mask=mask|(1<<i);
1161  }
1162  mask=(awheel<<nstubs)|mask;
1163  track.setCoarseEta(sign*lutService_->coarseEta(pattern,mask));
1164 
1165 
1166  int sumweights=0;
1167  int sums=0;
1168 
1169  for (const auto& stub : track.stubs()) {
1170  uint rank = etaStubRank(stub);
1171  if (rank==0)
1172  continue;
1173  // printf("Stub station=%d rank=%d values=%d %d\n",stub->stNum(),rank,stub->eta1(),stub->eta2());
1174  sumweights+=rank;
1175  sums+=rank*stub->eta1();
1176  }
1177 
1178  //0.5 0.332031 0.25 0.199219 0.164063
1179  float factor;
1180  if (sumweights==1)
1181  factor=1.0;
1182  else if (sumweights==2)
1183  factor = 0.5;
1184  else if (sumweights==3)
1185  factor=0.332031;
1186  else if (sumweights==4)
1187  factor=0.25;
1188  else if (sumweights==5)
1189  factor=0.199219;
1190  else if (sumweights==6)
1191  factor=0.164063;
1192  else
1193  factor=0.0;
1194 
1195 
1196 
1197 
1198  int eta=0;
1199  if (sums>0)
1200  eta=fp_product(factor,sums,10);
1201  else
1202  eta=-fp_product(factor,fabs(sums),10);
1203 
1204 
1205  //int eta=int(factor*sums);
1206  // printf("Eta debug %f *%d=%d\n",factor,sums,eta);
1207 
1208  if (sumweights>0)
1209  track.setFineEta(eta);
1210 }
1211 
1212 
1214 
1215  //If there is stub at station 2 use this else propagate from 1
1216  for (const auto& stub:track.stubs())
1217  if (stub->stNum()==2)
1218  return correctedPhi(stub,track.sector());
1219 
1220 
1221  int K = track.curvature();
1222  int phi = track.positionAngle();
1223  int phiB = track.bendingAngle();
1224 
1225  //phi propagation
1226  int phi11 = fp_product(phiAt2_[0],K,10);
1227  int phi12 = fp_product(phiAt2_[1],phiB,10);
1228 
1229  int phiNew =phi+phi11+phi12;
1230  if (phiNew>2047)
1231  phiNew=2047;
1232  if (phiNew<-2048)
1233  phiNew=-2048;
1234 
1235 
1236  if (verbose_) {
1237  printf("phi at station 2 = %d* %f = %d, %d* %f =%d , final=%d\n",K,phiAt2_[0],phi11,phiB,phiAt2_[1],phi12,phiNew);
1238  }
1239 
1240  return phiNew;
1241 
1242 }
std::vector< double > bPhiB_
int correctedPhiB(const L1MuKBMTCombinedStubRef &)
dbl * delta
Definition: mlp_gen.cc:36
int fineEta() const
l1t::RegionalMuonCand convertToBMTF(const L1MuKBMTrack &track)
void setHwPt2(int bits)
Set compressed second displaced pT as transmitted by hardware LSB = 1.0 (8 bits)
std::vector< double > aPhi_
ROOT::Math::SMatrix< double, 3, 3 > Matrix33
void setCoordinatesAtVertex(int, int, int)
std::vector< double > aPhiB_
std::vector< double > aPhiBNLO_
ROOT::Math::SMatrix< double, 2, 2, ROOT::Math::MatRepSym< double, 2 > > CovarianceMatrix2
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:314
int step() const
Definition: L1MuKBMTrack.cc:90
std::vector< double > mScatteringPhiB_
int bendingAngle() const
Definition: L1MuKBMTrack.cc:74
std::vector< float > trackGain2(uint, uint, uint)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision bits
int coarseEta() const
Definition: L1MuKBMTrack.cc:78
int phiAt2(const L1MuKBMTrack &track)
bool punchThroughVeto(const L1MuKBMTrack &track)
bool update(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &, int)
void estimateChiSquare(L1MuKBMTrack &)
int phiAtVertex() const
Definition: L1MuKBMTrack.cc:58
int rank(const L1MuKBMTrack &)
void setPtUnconstrained(float)
std::vector< double > phiAt2_
void setHitPattern(int)
bool updateOffline1D(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &)
std::vector< edm::Ref< L1MuKBMTCombinedStubCollection > > L1MuKBMTCombinedStubRefVector
void setPtEtaPhi(double, double, double)
void vertexConstraintLUT(L1MuKBMTrack &)
void setCharge(Charge q) final
set electric charge
Definition: LeafCandidate.h:93
int phiBAtMuon() const
Definition: L1MuKBMTrack.cc:50
std::pair< bool, uint > getByCode(const L1MuKBMTrackCollection &tracks, int mask)
int fp_product(float, int, uint)
std::vector< double > chiSquare_
const int keep
bool updateLUT(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &, int)
int curvatureAtMuon() const
Definition: L1MuKBMTrack.cc:44
bool hasFineEta() const
std::vector< double > initK2_
std::pair< float, float > vertexGain(uint, uint)
void setCoordinates(int, int, int, int)
ROOT::Math::SVector< double, 2 > Vector2
int approxChi2() const
Definition: L1MuKBMTrack.cc:82
void setCovariance(const CovarianceMatrix &)
std::vector< double > mScatteringPhi_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
L1TMuonBarrelKalmanLUTs * lutService_
void setCoarseEta(int)
void setDataword(uint32_t msbs, uint32_t lsbs)
void setHwHF(bool bit)
Set HF (halo / fine eta) bit (EMTF: halo -> 1; BMTF: fine eta -> 1)
void vertexConstraint(L1MuKBMTrack &)
int customBitmask(unsigned int, unsigned int, unsigned int, unsigned int)
Definition: value.py:1
std::vector< double > eLoss_
void vertexConstraintOffline(L1MuKBMTrack &)
void setFineEta(int)
const L1MuKBMTCombinedStubRefVector & stubs() const
int curvature() const
Definition: L1MuKBMTrack.cc:66
int phiAtMuon() const
Definition: L1MuKBMTrack.cc:47
std::vector< double > bPhi_
std::vector< double > initK_
void updateEta(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &)
#define M_PI
int wheel() const
Definition: L1MuKBMTrack.cc:96
ROOT::Math::SMatrix< double, 2, 3 > Matrix23
void setFloatingPointValues(L1MuKBMTrack &, bool)
void setHwDXY(int bits)
Set compressed impact parameter with respect to beamspot (4 bits)
ROOT::Math::SMatrix< double, 1, 3 > Matrix13
L1MuKBMTrackCollection clean(const L1MuKBMTrackCollection &, uint)
#define N
Definition: blowfish.cc:9
int encode(bool ownwheel, int sector, bool tag)
std::vector< int > chiSquareCutPattern_
const std::vector< double > & covariance() const
int dxy() const
Definition: L1MuKBMTrack.cc:62
std::pair< bool, L1MuKBMTrack > chain(const L1MuKBMTCombinedStubRef &, const L1MuKBMTCombinedStubRefVector &)
void calculateEta(L1MuKBMTrack &track)
def uint(string)
int curvatureAtVertex() const
Definition: L1MuKBMTrack.cc:54
double b
Definition: hdecay.h:120
std::pair< OmniClusterRef, TrackingParticleRef > P
double S(const TLorentzVector &, const TLorentzVector &)
Definition: Particle.cc:99
void addBMTFMuon(int, const L1MuKBMTrack &, std::unique_ptr< l1t::RegionalMuonCandBxCollection > &)
L1MuKBMTrackCollection cleanAndSort(const L1MuKBMTrackCollection &, uint)
int hitPattern(const L1MuKBMTrack &)
void setKalmanGain(unsigned int step, unsigned int K, float a1, float a2, float a3, float a4=0, float a5=0, float a6=0)
std::vector< L1MuKBMTrack > L1MuKBMTrackCollection
Definition: L1MuKBMTrack.h:15
double a
Definition: hdecay.h:121
int correctedPhi(const L1MuKBMTCombinedStubRef &, int)
int sector() const
Definition: L1MuKBMTrack.cc:93
std::vector< int > chiSquareCutCurv_
void addStub(const L1MuKBMTCombinedStubRef &)
step
int hitPattern() const
Definition: L1MuKBMTrack.cc:86
void setResidual(uint, int)
std::vector< float > trackGain(uint, uint, uint)
math::Error< dimension >::type CovarianceMatrix
covariance error matrix (3x3)
Definition: Candidate.h:47
ROOT::Math::SMatrix< double, 3, 1 > Matrix31
int positionAngle() const
Definition: L1MuKBMTrack.cc:70
bool updateOffline(L1MuKBMTrack &, const L1MuKBMTCombinedStubRef &)
ROOT::Math::SMatrix< double, 3, 2 > Matrix32
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
uint etaStubRank(const L1MuKBMTCombinedStubRef &)
void setApproxChi2(int)
std::map< int, int > trackAddress(const L1MuKBMTrack &, int &)