CMS 3D CMS Logo

MatchProcessor.cc
Go to the documentation of this file.
5 
10 
11 #include <filesystem>
12 
13 using namespace std;
14 using namespace trklet;
15 
16 MatchProcessor::MatchProcessor(string name, Settings const& settings, Globals* global)
17  : ProcessBase(name, settings, global),
18  phimatchcuttable_(settings),
19  zmatchcuttable_(settings),
20  rphicutPStable_(settings),
21  rphicut2Stable_(settings),
22  rcutPStable_(settings),
23  rcut2Stable_(settings),
24  fullmatches_(12),
25  rinvbendlut_(settings),
26  luttable_(settings),
27  inputProjBuffer_(3) {
28  phiregion_ = name[8] - 'A';
29 
31 
33 
36 
37  if (barrel_) {
40  } else {
43  }
44 
46 
47  nrbits_ = 5;
48  nphiderbits_ = 6;
49 
50  if (!barrel_) {
53  }
54 
55  nrinv_ = NRINVBITS;
56 
57  unsigned int region = getName()[8] - 'A';
59 
60  if (barrel_) {
61  phimatchcuttable_.initmatchcut(layerdisk_, TrackletLUT::MatchType::barrelphi, region);
62  zmatchcuttable_.initmatchcut(layerdisk_, TrackletLUT::MatchType::barrelz, region);
63  } else {
64  rphicutPStable_.initmatchcut(layerdisk_, TrackletLUT::MatchType::diskPSphi, region);
65  rphicut2Stable_.initmatchcut(layerdisk_, TrackletLUT::MatchType::disk2Sphi, region);
66  rcutPStable_.initmatchcut(layerdisk_, TrackletLUT::MatchType::diskPSr, region);
67  rcut2Stable_.initmatchcut(layerdisk_, TrackletLUT::MatchType::disk2Sr, region);
68  }
69 
70  for (unsigned int i = 0; i < N_DSS_MOD * 2; i++) {
72  (1 << (settings_.nbitsalpha() - 1)) / (settings_.rDSSinner(i) * settings_.rDSSinner(i)) /
73  settings_.kphi();
75  (1 << (settings_.nbitsalpha() - 1)) / (settings_.rDSSouter(i) * settings_.rDSSouter(i)) /
76  settings_.kphi();
77  }
78 
82 
83  nMatchEngines_ = 4;
84  for (unsigned int iME = 0; iME < nMatchEngines_; iME++) {
86  tmpME.setimeu(iME);
87  matchengines_.push_back(tmpME);
88  }
89 }
90 
92  if (settings_.writetrace()) {
93  edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output "
94  << output;
95  }
96  if (output.find("matchout") != std::string::npos) {
97  auto* tmp = dynamic_cast<FullMatchMemory*>(memory);
98  assert(tmp != nullptr);
99  unsigned int iSeed = getISeed(tmp->getName());
100  assert(iSeed < fullmatches_.size());
101  assert(fullmatches_[iSeed] == nullptr);
102  fullmatches_[iSeed] = tmp;
103  return;
104  }
105  throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find output: " << output;
106 }
107 
109  if (settings_.writetrace()) {
110  edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input "
111  << input;
112  }
113  if (input == "allstubin") {
114  auto* tmp = dynamic_cast<AllStubsMemory*>(memory);
115  assert(tmp != nullptr);
116  allstubs_ = tmp;
117  return;
118  }
119  if (input == "vmstubin") {
120  auto* tmp = dynamic_cast<VMStubsMEMemory*>(memory);
121  assert(tmp != nullptr);
122  vmstubs_.push_back(tmp); //to allow more than one stub in? vmstubs_=tmp;
123  return;
124  }
125  if (input == "projin") {
126  auto* tmp = dynamic_cast<TrackletProjectionsMemory*>(memory);
127  assert(tmp != nullptr);
128  inputprojs_.push_back(tmp);
129  return;
130  }
131  throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find input: " << input;
132 }
133 
134 void MatchProcessor::execute(unsigned int iSector, double phimin) {
135  assert(vmstubs_.size() == 1);
136 
137  /*
138  The code is organized in three 'steps' corresponding to the PR, ME, and MC functions. The output from
139  the PR step is buffered in a 'circular' buffer, and similarly the ME output is put in a circular buffer.
140  The implementation is done in steps, emulating what can be done in firmware. On each step we do:
141 
142  1) A projection is read and if there is space it is insert into the inputProjBuffer_
143 
144  2) Process next match in the ME - if there is an idle ME the next projection is inserted
145 
146  3) Readout match from ME and send to match calculator
147 
148  However, for the pipelining to work in HLS these blocks are executed in reverse order
149 
150  */
151 
152  bool print = getName() == "MP_L3PHIC" && iSector == 3;
153  print = false;
154 
155  phimin_ = phimin;
156 
157  Tracklet* oldTracklet = nullptr;
158 
159  unsigned int countme = 0;
160  unsigned int countall = 0;
161  unsigned int countsel = 0;
162  unsigned int countinputproj = 0;
163 
164  unsigned int iprojmem = 0;
165  while (iprojmem < inputprojs_.size() && inputprojs_[iprojmem]->nTracklets() == 0) {
166  iprojmem++;
167  }
168 
169  unsigned int iproj = 0;
170 
171  inputProjBuffer_.reset();
172 
173  for (const auto& inputproj : inputprojs_) {
174  countinputproj += inputproj->nTracklets();
175  }
176 
177  for (auto& matchengine : matchengines_) {
178  matchengine.reset();
179  }
180 
181  ProjectionTemp tmpProj_, tmpProj__;
182  bool good_ = false;
183  bool good__ = false;
184 
185  for (unsigned int istep = 0; istep < settings_.maxStep("MP"); istep++) {
186  // This print statement is useful for detailed comparison with the HLS code
187  // It prints out detailed status information for each clock step
188  /*
189  if (print) {
190  cout << "istep = "<<istep<<" projBuff: "<<inputProjBuffer_.rptr()<<" "<<inputProjBuffer_.wptr()<<" "<<projBuffNearFull;
191  unsigned int iMEU = 0;
192  for (auto& matchengine : matchengines_) {
193  cout <<" MEU"<<iMEU<<": "<<matchengine.rptr()<<" "<<matchengine.wptr()
194  <<" "<<matchengine.idle()<<" "<<matchengine.empty()
195  <<" "<<matchengine.TCID();
196  iMEU++;
197  }
198  cout << std::endl;
199  }
200  */
201 
202  //First do some caching of state at the start of the clock
203 
204  bool projdone = false;
205 
206  bool projBuffNearFull = inputProjBuffer_.nearfull();
207 
208  for (unsigned int iME = 0; iME < nMatchEngines_; iME++) {
209  matchengines_[iME].setAlmostFull();
210  }
211 
212  //Step 3
213  //Check if we have candidate match to process
214 
215  unsigned int iMEbest = 0;
216  int bestTCID = matchengines_[0].TCID();
217  bool meactive = matchengines_[0].active();
218  for (unsigned int iME = 1; iME < nMatchEngines_; iME++) {
219  meactive = meactive || matchengines_[iME].active();
220  int tcid = matchengines_[iME].TCID();
221  if (tcid < bestTCID) {
222  bestTCID = tcid;
223  iMEbest = iME;
224  }
225  }
226 
227  // check if the matche engine processing the smallest tcid has match
228 
229  if (!matchengines_[iMEbest].empty()) {
230  std::pair<Tracklet*, const Stub*> candmatch = matchengines_[iMEbest].read();
231 
232  const Stub* fpgastub = candmatch.second;
233  Tracklet* tracklet = candmatch.first;
234 
235  //Consistency check
236  if (oldTracklet != nullptr) {
237  //allow equal here since we can have more than one cadidate match per tracklet projection
238  //cout << "old new : "<<oldTracklet->TCID()<<" "<<tracklet->TCID()<<" "<<iMEbest<<endl;
239  assert(oldTracklet->TCID() <= tracklet->TCID());
240  }
241  oldTracklet = tracklet;
242 
243  bool match = matchCalculator(tracklet, fpgastub, print, istep);
244 
245  if (settings_.debugTracklet() && match) {
246  edm::LogVerbatim("Tracklet") << getName() << " have match";
247  }
248 
249  countall++;
250  if (match)
251  countsel++;
252  }
253 
254  //Step 2
255  //Check if we have ME that can process projection
256 
257  bool addedProjection = false;
258  for (unsigned int iME = 0; iME < nMatchEngines_; iME++) {
259  if (!matchengines_[iME].idle())
260  countme++;
261  //if match engine empty and we have queued projections add to match engine
262  if ((!addedProjection) && matchengines_[iME].idle() && (!inputProjBuffer_.empty())) {
263  ProjectionTemp tmpProj = inputProjBuffer_.read();
264  VMStubsMEMemory* stubmem = vmstubs_[0];
265 
266  if (settings_.debugTracklet()) {
267  edm::LogVerbatim("Tracklet") << getName() << " adding projection to match engine";
268  }
269 
270  int nbins = (1 << N_RZBITS);
271  if (layerdisk_ >= N_LAYER) {
272  nbins *= 2; //twice as many bins in disks (since there are two disks)
273  }
274 
275  matchengines_[iME].init(stubmem,
276  nbins,
277  tmpProj.slot(),
278  tmpProj.iphi(),
279  tmpProj.shift(),
280  tmpProj.projrinv(),
281  tmpProj.projfinerz(),
282  tmpProj.projfinephi(),
283  tmpProj.use(0, 0),
284  tmpProj.use(0, 1),
285  tmpProj.use(1, 0),
286  tmpProj.use(1, 1),
287  tmpProj.isPSseed(),
288  tmpProj.proj());
289  meactive = true;
290  addedProjection = true;
291  } else {
292  matchengines_[iME].step();
293  }
294  matchengines_[iME].processPipeline();
295  }
296 
297  //Step 1
298  //First step here checks if we have more input projections to put into
299  //the input puffer for projections
300 
301  if (good__) {
302  inputProjBuffer_.store(tmpProj__);
303  }
304 
305  good__ = good_;
306  tmpProj__ = tmpProj_;
307 
308  good_ = false;
309 
310  if (iprojmem < inputprojs_.size()) {
311  TrackletProjectionsMemory* projMem = inputprojs_[iprojmem];
312  if (!projBuffNearFull) {
313  if (settings_.debugTracklet()) {
314  edm::LogVerbatim("Tracklet") << getName() << " have projection in memory : " << projMem->getName();
315  }
316 
317  Tracklet* proj = projMem->getTracklet(iproj);
318 
319  FPGAWord fpgaphi = proj->proj(layerdisk_).fpgaphiproj();
320 
321  unsigned int iphi = (fpgaphi.value() >> (fpgaphi.nbits() - nvmbits_)) & (nvmbins_ - 1);
322 
323  int nextrabits = 2;
324  int overlapbits = nvmbits_ + nextrabits;
325 
326  unsigned int extrabits = fpgaphi.bits(fpgaphi.nbits() - overlapbits - nextrabits, nextrabits);
327 
328  unsigned int ivmPlus = iphi;
329 
330  int shift = 0;
331 
332  if (extrabits == ((1U << nextrabits) - 1) && iphi != ((1U << settings_.nbitsvmme(layerdisk_)) - 1)) {
333  shift = 1;
334  ivmPlus++;
335  }
336  unsigned int ivmMinus = iphi;
337  if (extrabits == 0 && iphi != 0) {
338  shift = -1;
339  ivmMinus--;
340  }
341 
342  int projrinv = -1;
343  if (barrel_) {
344  FPGAWord phider = proj->proj(layerdisk_).fpgaphiprojder();
345  projrinv = (1 << (nrinv_ - 1)) - 1 - (phider.value() >> (phider.nbits() - nrinv_));
346  } else {
347  //The next lines looks up the predicted bend based on:
348  // 1 - r projections
349  // 2 - phi derivative
350  // 3 - the sign - i.e. if track is forward or backward
351 
352  int rindex =
353  (proj->proj(layerdisk_).fpgarzproj().value() >> (proj->proj(layerdisk_).fpgarzproj().nbits() - nrbits_)) &
354  ((1 << nrbits_) - 1);
355 
356  int phiprojder = proj->proj(layerdisk_).fpgaphiprojder().value();
357 
358  int phiderindex = (phiprojder >> (proj->proj(layerdisk_).fpgaphiprojder().nbits() - nphiderbits_)) &
359  ((1 << nphiderbits_) - 1);
360 
361  int signindex = proj->proj(layerdisk_).fpgarzprojder().value() < 0;
362 
363  int bendindex = (signindex << (nphiderbits_ + nrbits_)) + (rindex << (nphiderbits_)) + phiderindex;
364 
365  projrinv = rinvbendlut_.lookup(bendindex);
366 
367  proj->proj(layerdisk_).setBendIndex(projrinv);
368  }
369  assert(projrinv >= 0);
370 
371  unsigned int slot = proj->proj(layerdisk_).fpgarzbin1projvm().value();
372  bool second = proj->proj(layerdisk_).fpgarzbin2projvm().value();
373 
374  unsigned int projfinephi =
375  (fpgaphi.value() >> (fpgaphi.nbits() - (nvmbits_ + NFINEPHIBITS))) & ((1 << NFINEPHIBITS) - 1);
376  int projfinerz = proj->proj(layerdisk_).fpgafinerzvm().value();
377 
378  bool isPSseed = proj->PSseed();
379 
380  int nbins = (1 << N_RZBITS);
381  if (layerdisk_ >= N_LAYER) {
382  nbins *= 2; //twice as many bins in disks (since there are two disks)
383  }
384 
385  VMStubsMEMemory* stubmem = vmstubs_[0];
386  bool usefirstMinus = stubmem->nStubsBin(ivmMinus * nbins + slot) != 0;
387  bool usesecondMinus = (second && (stubmem->nStubsBin(ivmMinus * nbins + slot + 1) != 0));
388  bool usefirstPlus = ivmPlus != ivmMinus && stubmem->nStubsBin(ivmPlus * nbins + slot) != 0;
389  bool usesecondPlus = ivmPlus != ivmMinus && (second && (stubmem->nStubsBin(ivmPlus * nbins + slot + 1) != 0));
390 
391  good_ = usefirstPlus || usesecondPlus || usefirstMinus || usesecondMinus;
392 
393  if (good_) {
394  ProjectionTemp tmpProj(proj,
395  slot,
396  projrinv,
397  projfinerz,
398  projfinephi,
399  ivmMinus,
400  shift,
401  usefirstMinus,
402  usefirstPlus,
403  usesecondMinus,
404  usesecondPlus,
405  isPSseed);
406  tmpProj_ = tmpProj;
407  }
408 
409  iproj++;
410  if (iproj == projMem->nTracklets()) {
411  iproj = 0;
412  do {
413  iprojmem++;
414  } while (iprojmem < inputprojs_.size() && inputprojs_[iprojmem]->nTracklets() == 0);
415  }
416 
417  } else {
418  projdone = true && !good_ && !good__;
419  }
420  }
421 
422  //
423  // Check if done
424  //
425  //
426  //
427 
428  if ((projdone && !meactive && inputProjBuffer_.rptr() == inputProjBuffer_.wptr()) ||
429  (istep == settings_.maxStep("MP") - 1)) {
430  if (settings_.writeMonitorData("MP")) {
431  globals_->ofstream("matchprocessor.txt") << getName() << " " << istep << " " << countall << " " << countsel
432  << " " << countme << " " << countinputproj << endl;
433  }
434  break;
435  }
436  }
437 
438  if (settings_.writeMonitorData("MC")) {
439  globals_->ofstream("matchcalculator.txt") << getName() << " " << countall << " " << countsel << endl;
440  }
441 }
442 
443 bool MatchProcessor::matchCalculator(Tracklet* tracklet, const Stub* fpgastub, bool, unsigned int) {
444  const L1TStub* stub = fpgastub->l1tstub();
445 
446  if (layerdisk_ < N_LAYER) {
447  const Projection& proj = tracklet->proj(layerdisk_);
448  int ir = fpgastub->r().value();
449  int iphi = proj.fpgaphiproj().value();
450  int icorr = (ir * proj.fpgaphiprojder().value()) >> icorrshift_;
451  iphi += icorr;
452 
453  int iz = proj.fpgarzproj().value();
454  int izcor = (ir * proj.fpgarzprojder().value() + (1 << (icorzshift_ - 1))) >> icorzshift_;
455  iz += izcor;
456 
457  int ideltaz = fpgastub->z().value() - iz;
458  int ideltaphi = (fpgastub->phi().value() - iphi) << phishift_;
459 
460  //Floating point calculations
461 
462  double phi = stub->phi();
463  double r = stub->r();
464  double z = stub->z();
465 
466  if (settings_.useapprox()) {
467  double dphi = reco::reduceRange(phi - fpgastub->phiapprox(phimin_, 0.0));
468  assert(std::abs(dphi) < 0.001);
469  phi = fpgastub->phiapprox(phimin_, 0.0);
470  z = fpgastub->zapprox();
471  r = fpgastub->rapprox();
472  }
473 
474  if (phi < 0)
475  phi += 2 * M_PI;
476  phi -= phimin_;
477 
478  double dr = r - settings_.rmean(layerdisk_);
479  assert(std::abs(dr) < settings_.drmax());
480 
481  double dphi = reco::reduceRange(phi - (proj.phiproj() + dr * proj.phiprojder()));
482 
483  double dz = z - (proj.rzproj() + dr * proj.rzprojder());
484 
485  double dphiapprox = reco::reduceRange(phi - (proj.phiprojapprox() + dr * proj.phiprojderapprox()));
486 
487  double dzapprox = z - (proj.rzprojapprox() + dr * proj.rzprojderapprox());
488 
489  int seedindex = tracklet->getISeed();
490 
491  assert(phimatchcuttable_.lookup(seedindex) > 0);
492  assert(zmatchcuttable_.lookup(seedindex) > 0);
493 
494  if (settings_.bookHistos()) {
495  bool truthmatch = tracklet->stubtruthmatch(stub);
496 
498  hists->FillLayerResidual(layerdisk_ + 1,
499  seedindex,
500  dphiapprox * settings_.rmean(layerdisk_),
501  ideltaphi * settings_.kphi1() * settings_.rmean(layerdisk_),
502  (ideltaz << dzshift_) * settings_.kz(),
503  dz,
504  truthmatch);
505  }
506 
507  if (settings_.writeMonitorData("Residuals")) {
508  double pt = 0.01 * settings_.c() * settings_.bfield() / std::abs(tracklet->rinv());
509 
510  globals_->ofstream("layerresiduals.txt")
511  << layerdisk_ + 1 << " " << seedindex << " " << pt << " "
512  << ideltaphi * settings_.kphi1() * settings_.rmean(layerdisk_) << " "
513  << dphiapprox * settings_.rmean(layerdisk_) << " "
514  << phimatchcuttable_.lookup(seedindex) * settings_.kphi1() * settings_.rmean(layerdisk_) << " "
515  << (ideltaz << dzshift_) * settings_.kz() << " " << dz << " "
516  << zmatchcuttable_.lookup(seedindex) * settings_.kz() << endl;
517  }
518 
519  bool imatch = (std::abs(ideltaphi) <= phimatchcuttable_.lookup(seedindex)) &&
520  (ideltaz << dzshift_ < zmatchcuttable_.lookup(seedindex)) &&
521  (ideltaz << dzshift_ >= -zmatchcuttable_.lookup(seedindex));
522 
523  if (settings_.debugTracklet()) {
524  edm::LogVerbatim("Tracklet") << getName() << " imatch = " << imatch << " ideltaphi cut " << ideltaphi << " "
525  << phimatchcuttable_.lookup(seedindex) << " ideltaz<<dzshift cut "
526  << (ideltaz << dzshift_) << " " << zmatchcuttable_.lookup(seedindex);
527  }
528 
529  //This would catch significant consistency problems in the configuration - helps to debug if there are problems.
530  if (std::abs(dphi) > 0.5 * settings_.dphisectorHG() || std::abs(dphiapprox) > 0.5 * settings_.dphisectorHG()) {
531  throw cms::Exception("LogicError") << "WARNING dphi and/or dphiapprox too large : " << dphi << " " << dphiapprox
532  << endl;
533  }
534 
535  bool keep = true;
536  if (!settings_.doKF() || !settings_.doMultipleMatches()) {
537  // Case of allowing only one stub per track per layer (or no KF which implies the same).
538  if (imatch && tracklet->match(layerdisk_)) {
539  // Veto match if is not the best one for this tracklet (in given layer)
540  auto res = tracklet->resid(layerdisk_);
541  keep = abs(ideltaphi) < abs(res.fpgaphiresid().value());
542  imatch = keep;
543  }
544  }
545 
546  if (imatch) {
547  tracklet->addMatch(layerdisk_,
548  ideltaphi,
549  ideltaz,
550  dphi,
551  dz,
552  dphiapprox,
553  dzapprox,
554  (phiregion_ << N_BITSMEMADDRESS) + fpgastub->stubindex().value(),
555  fpgastub);
556 
557  if (settings_.debugTracklet()) {
558  edm::LogVerbatim("Tracklet") << "Accepted full match in layer " << getName() << " " << tracklet;
559  }
560 
561  int iSeed = tracklet->getISeed();
562  assert(fullmatches_[iSeed] != nullptr);
563  fullmatches_[iSeed]->addMatch(tracklet, fpgastub);
564 
565  return true;
566  } else {
567  return false;
568  }
569  } else { //disk matches
570 
571  //check that stubs and projections in same half of detector
572  assert(stub->z() * tracklet->t() > 0.0);
573 
574  int sign = (tracklet->t() > 0.0) ? 1 : -1;
575  int disk = sign * (layerdisk_ - N_LAYER + 1);
576  assert(disk != 0);
577 
578  //Perform integer calculations here
579 
580  int iz = fpgastub->z().value();
581 
582  const Projection& proj = tracklet->proj(layerdisk_);
583 
584  int iphi = proj.fpgaphiproj().value();
585  int iphicorr = (iz * proj.fpgaphiprojder().value()) >> icorrshift_;
586 
587  iphi += iphicorr;
588 
589  int ir = proj.fpgarzproj().value();
590  int ircorr = (iz * proj.fpgarzprojder().value()) >> icorzshift_;
591  ir += ircorr;
592 
593  int ideltaphi = fpgastub->phi().value() - iphi;
594 
595  int irstub = fpgastub->r().value();
596  int ialphafact = 0;
597  if (!stub->isPSmodule()) {
598  assert(irstub < (int)N_DSS_MOD * 2);
599  if (layerdisk_ - N_LAYER <= 1) {
600  ialphafact = ialphafactinner_[irstub];
601  irstub = settings_.rDSSinner(irstub) / settings_.kr();
602  } else {
603  ialphafact = ialphafactouter_[irstub];
604  irstub = settings_.rDSSouter(irstub) / settings_.kr();
605  }
606  }
607 
608  int ideltar = (irstub * settings_.kr()) / settings_.krprojshiftdisk() - ir;
609 
610  if (!stub->isPSmodule()) {
611  int ialpha = fpgastub->alpha().value();
612  int iphialphacor = ((ideltar * ialpha * ialphafact) >> settings_.alphashift());
613  ideltaphi += iphialphacor;
614  }
615 
616  //Perform floating point calculations here
617 
618  double phi = stub->phi();
619  double z = stub->z();
620  double r = stub->r();
621 
622  if (settings_.useapprox()) {
623  double dphi = reco::reduceRange(phi - fpgastub->phiapprox(phimin_, 0.0));
624  assert(std::abs(dphi) < 0.001);
625  phi = fpgastub->phiapprox(phimin_, 0.0);
626  z = fpgastub->zapprox();
627  r = fpgastub->rapprox();
628  }
629 
630  if (phi < 0)
631  phi += 2 * M_PI;
632  phi -= phimin_;
633 
634  double dz = z - sign * settings_.zmean(layerdisk_ - N_LAYER);
635 
636  if (std::abs(dz) > settings_.dzmax()) {
637  edm::LogProblem("Tracklet") << __FILE__ << ":" << __LINE__ << " " << name_ << " " << tracklet->getISeed();
638  edm::LogProblem("Tracklet") << "stub " << stub->z() << " disk " << disk << " " << dz;
640  }
641 
642  double phiproj = proj.phiproj() + dz * proj.phiprojder();
643  double rproj = proj.rzproj() + dz * proj.rzprojder();
644  double deltar = r - rproj;
645 
646  double dr = stub->r() - rproj;
647  double drapprox = stub->r() - (proj.rzprojapprox() + dz * proj.rzprojderapprox());
648 
649  double dphi = reco::reduceRange(phi - phiproj);
650 
651  double dphiapprox = reco::reduceRange(phi - (proj.phiprojapprox() + dz * proj.phiprojderapprox()));
652 
653  double drphi = dphi * stub->r();
654  double drphiapprox = dphiapprox * stub->r();
655 
656  if (!stub->isPSmodule()) {
657  double alphanorm = stub->alphanorm();
658  dphi += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r2();
659  ;
660  dphiapprox += drapprox * alphanorm * settings_.half2SmoduleWidth() / stub->r2();
661 
662  drphi += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r();
663  drphiapprox += dr * alphanorm * settings_.half2SmoduleWidth() / stub->r();
664  }
665 
666  int seedindex = tracklet->getISeed();
667 
668  int idrphicut = rphicutPStable_.lookup(seedindex);
669  int idrcut = rcutPStable_.lookup(seedindex);
670  if (!stub->isPSmodule()) {
671  idrphicut = rphicut2Stable_.lookup(seedindex);
672  idrcut = rcut2Stable_.lookup(seedindex);
673  }
674 
675  double drphicut = idrphicut * settings_.kphi() * settings_.kr();
676  double drcut = idrcut * settings_.krprojshiftdisk();
677 
678  if (settings_.writeMonitorData("Residuals")) {
679  double pt = 0.01 * settings_.c() * settings_.bfield() / std::abs(tracklet->rinv());
680 
681  globals_->ofstream("diskresiduals.txt")
682  << layerdisk_ - N_LAYER + 1 << " " << stub->isPSmodule() << " " << tracklet->layer() << " "
683  << abs(tracklet->disk()) << " " << pt << " " << ideltaphi * settings_.kphi() * stub->r() << " " << drphiapprox
684  << " " << drphicut << " " << ideltar * settings_.krprojshiftdisk() << " " << deltar << " " << drcut << " "
685  << endl;
686  }
687 
688  bool match = (std::abs(drphi) < drphicut) && (std::abs(deltar) < drcut);
689  bool imatch = (std::abs(ideltaphi * irstub) < idrphicut) && (std::abs(ideltar) < idrcut);
690 
691  if (settings_.debugTracklet()) {
692  edm::LogVerbatim("Tracklet") << "imatch match disk: " << imatch << " " << match << " " << std::abs(ideltaphi)
693  << " " << drphicut / (settings_.kphi() * stub->r()) << " " << std::abs(ideltar)
694  << " " << drcut / settings_.krprojshiftdisk() << " r = " << stub->r();
695  }
696 
697  bool keep = true;
698  if (!settings_.doKF() || !settings_.doMultipleMatches()) {
699  // Case of allowing only one stub per track per layer (or no KF which implies the same).
700  if (imatch && tracklet->match(layerdisk_)) {
701  // Veto match if is not the best one for this tracklet (in given layer)
702  auto res = tracklet->resid(layerdisk_);
703  keep = abs(ideltaphi) < abs(res.fpgaphiresid().value());
704  imatch = keep;
705  }
706  }
707 
708  if (imatch) {
709  if (settings_.debugTracklet()) {
710  edm::LogVerbatim("Tracklet") << "MatchCalculator found match in disk " << getName();
711  }
712 
713  if (std::abs(dphi) >= third * settings_.dphisectorHG()) {
714  edm::LogPrint("Tracklet") << "dphi " << dphi << " ISeed " << tracklet->getISeed();
715  }
717  assert(std::abs(dphiapprox) < third * settings_.dphisectorHG());
718 
719  tracklet->addMatch(layerdisk_,
720  ideltaphi,
721  ideltar,
722  drphi / stub->r(),
723  dr,
724  drphiapprox / stub->r(),
725  drapprox,
726  (phiregion_ << N_BITSMEMADDRESS) + fpgastub->stubindex().value(),
727  fpgastub);
728 
729  if (settings_.debugTracklet()) {
730  edm::LogVerbatim("Tracklet") << "Accepted full match in disk " << getName() << " " << tracklet;
731  }
732 
733  int iSeed = tracklet->getISeed();
734  assert(fullmatches_[iSeed] != nullptr);
735  fullmatches_[iSeed]->addMatch(tracklet, fpgastub);
736 
737  return true;
738  } else {
739  return false;
740  }
741  }
742 }
Log< level::Info, true > LogVerbatim
void initBendMatch(unsigned int layerdisk)
Definition: TrackletLUT.cc:446
constexpr unsigned int N_RZBITS
Definition: Settings.h:35
double kz() const
Definition: Settings.h:314
double phi() const
Definition: L1TStub.h:65
double t() const
Definition: Tracklet.h:123
double zapprox() const
Definition: Stub.cc:158
unsigned int maxStep(std::string module) const
Definition: Settings.h:116
const FPGAWord & r() const
Definition: Stub.h:60
bool bookHistos() const
Definition: Settings.h:207
std::string name_
Definition: ProcessBase.h:38
const Residual & resid(unsigned int layerdisk)
Definition: Tracklet.h:110
unsigned int projrinv() const
int disk() const
Definition: Tracklet.cc:782
double kphi1() const
Definition: Settings.h:311
double kphiderdisk() const
Definition: Settings.h:407
void initmatchcut(unsigned int layerdisk, MatchType type, unsigned int region)
Definition: TrackletLUT.cc:14
double rDSSinner(unsigned int iBin) const
Definition: Settings.h:171
constexpr T reduceRange(T x)
Definition: deltaPhi.h:18
void addInput(MemoryBase *memory, std::string input) override
double phiapprox(double phimin, double) const
Definition: Stub.cc:177
std::vector< MatchEngineUnit > matchengines_
double kphider() const
Definition: Settings.h:406
constexpr unsigned int NRINVBITS
Definition: Settings.h:32
const FPGAWord & z() const
Definition: Stub.h:61
void initProjectionBend(double k_phider, unsigned int idisk, unsigned int nrbits, unsigned int nphiderbits)
Definition: TrackletLUT.cc:394
double dphisectorHG() const
Definition: Settings.h:292
unsigned int projfinephi() const
Projection & proj(int layerdisk)
Definition: Tracklet.h:87
Settings const & settings_
Definition: ProcessBase.h:40
TrackletLUT phimatchcuttable_
double z() const
Definition: L1TStub.h:59
Globals * globals_
Definition: ProcessBase.h:41
double krder() const
Definition: Settings.h:409
int lookup(unsigned int index) const
Definition: TrackletLUT.cc:904
bool writetrace() const
Definition: Settings.h:183
std::vector< TrackletProjectionsMemory * > inputprojs_
double dzmax() const
Definition: Settings.h:129
constexpr unsigned int N_DSS_MOD
Definition: Settings.h:27
assert(be >=bs)
int TCID() const
Definition: Tracklet.h:214
Definition: Electron.h:6
constexpr double third
Definition: Settings.h:42
static std::string const input
Definition: EdmProvDump.cc:50
unsigned int isPSmodule() const
Definition: L1TStub.h:96
void addMatch(unsigned int layerdisk, int ideltaphi, int ideltarz, double dphi, double drz, double dphiapprox, double drzapprox, int stubid, const trklet::Stub *stubptr)
Definition: Tracklet.cc:295
U second(std::pair< T, U > const &p)
double kzder() const
Definition: Settings.h:408
unsigned int nbitsallstubs(unsigned int layerdisk) const
Definition: Settings.h:106
double half2SmoduleWidth() const
Definition: Settings.h:131
unsigned int nzbitsstub(unsigned int layerdisk) const
Definition: Settings.h:82
unsigned int nphibitsstub(unsigned int layerdisk) const
Definition: Settings.h:83
double rmean(unsigned int iLayer) const
Definition: Settings.h:164
double rinv() const
Definition: Tracklet.h:120
int ilog2(double factor)
Definition: Util.h:104
double rDSSouter(unsigned int iBin) const
Definition: Settings.h:174
bool use(unsigned int nextrzbin, unsigned int nextiphibin) const
std::vector< FullMatchMemory * > fullmatches_
double bfield() const
Definition: Settings.h:263
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
IMATH_TrackletCalculator * ITC_L1L2()
Definition: Globals.h:48
int value() const
Definition: FPGAWord.h:24
bool doMultipleMatches() const
Definition: Settings.h:242
int alphashift() const
Definition: Settings.h:216
L1TStub * l1tstub()
Definition: Stub.h:77
std::string const & getName() const
Definition: MemoryBase.h:19
unsigned int nbitsvmme(unsigned int layerdisk) const
Definition: Settings.h:103
CircularBuffer< ProjectionTemp > inputProjBuffer_
bool writeMonitorData(std::string module) const
Definition: Settings.h:109
Log< level::Warning, true > LogPrint
double rapprox() const
Definition: Stub.cc:144
double zmean(unsigned int iDisk) const
Definition: Settings.h:167
void initLayerDisk(unsigned int pos, int &layer, int &disk)
Definition: ProcessBase.cc:33
const FPGAWord & stubindex() const
Definition: Stub.h:66
#define M_PI
double K() const
Definition: imath.h:247
TrackletLUT rphicutPStable_
unsigned int nallstubs(unsigned int layerdisk) const
Definition: Settings.h:107
bool debugTracklet() const
Definition: Settings.h:182
bool matchCalculator(Tracklet *tracklet, const Stub *fpgastub, bool print, unsigned int istep)
unsigned int iphi() const
TrackletLUT rphicut2Stable_
double kr() const
Definition: Settings.h:316
unsigned int slot() const
double drmax() const
Definition: Settings.h:128
double alphanorm() const
Definition: L1TStub.cc:90
int ialphafactinner_[N_DSS_MOD *2]
bool stubtruthmatch(const L1TStub *stub)
Definition: Tracklet.cc:138
int nbits() const
Definition: FPGAWord.h:25
void addOutput(MemoryBase *memory, std::string output) override
Definition: deltar.py:1
constexpr unsigned int NFINEPHIBITS
Definition: Settings.h:34
int getISeed() const
Definition: Tracklet.cc:801
double c() const
Definition: Settings.h:212
unsigned int getISeed(const std::string &name)
Definition: ProcessBase.cc:119
unsigned int nvmme(unsigned int layerdisk) const
Definition: Settings.h:104
const FPGAWord & alpha() const
Definition: Stub.h:64
double r() const
Definition: L1TStub.h:60
bool match(unsigned int layerdisk)
Definition: Tracklet.h:105
void execute(unsigned int iSector, double phimin)
Tracklet * proj() const
unsigned int nMatchEngines_
std::ofstream & ofstream(std::string fname)
Definition: Globals.cc:44
static unsigned int const shift
int nbitsalpha() const
Definition: Settings.h:217
HistBase *& histograms()
Definition: Globals.h:38
Definition: output.py:1
double krbarrel() const
Definition: Settings.h:317
double krprojshiftdisk() const
Definition: Settings.h:413
const FPGAWord & phi() const
Definition: Stub.h:62
std::vector< VMStubsMEMemory * > vmstubs_
unsigned int nStubsBin(unsigned int bin) const
int layer() const
Definition: Tracklet.cc:773
double kphi() const
Definition: Settings.h:310
unsigned int bits(unsigned int lsb, unsigned int nbit) const
Definition: FPGAWord.cc:74
tmp
align.sh
Definition: createJobs.py:716
bool doKF() const
Definition: Settings.h:241
double r2() const
Definition: L1TStub.h:62
std::string const & getName() const
Definition: ProcessBase.h:22
AllStubsMemory * allstubs_
TrackletLUT zmatchcuttable_
int ialphafactouter_[N_DSS_MOD *2]
bool useapprox() const
Definition: Settings.h:235
constexpr unsigned int N_BITSMEMADDRESS
Definition: Settings.h:39
Log< level::Error, true > LogProblem
constexpr int N_LAYER
Definition: Settings.h:21