CMS 3D CMS Logo

VMRouterCM.cc
Go to the documentation of this file.
10 
13 
14 using namespace std;
15 using namespace trklet;
16 
17 VMRouterCM::VMRouterCM(string name, Settings const& settings, Globals* global)
18  : ProcessBase(name, settings, global),
19  meTable_(settings),
20  diskTable_(settings),
21  meTableOld_(settings),
22  diskTableOld_(settings),
23  innerTable_(settings),
24  innerOverlapTable_(settings),
25  innerThirdTable_(settings) {
27 
28  unsigned int region = name[9] - 'A';
30 
31  overlapbits_ = 7;
33 
34  // The TrackletProcessorDisplaced currently uses the older LUTs that were
35  // used with the non-combined modules. To maintain compatibility, we
36  // initialize these older LUTs below, which are used for the triplet seeds in
37  // the "execute" method. Once the TrackletProcessorDisplaced is updated,
38  // these can be removed.
39 
40  meTable_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::me, region); //used for ME and outer TE barrel
41  meTableOld_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::me, region, false); //used for ME and outer TE barrel
42 
44  diskTable_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::disk, region); //outer disk used by D1, D2, and D4
46  layerdisk_, TrackletLUT::VMRTableType::disk, region, false); //outer disk used by D1, D2, and D4
47  }
48 
52  layerdisk_, TrackletLUT::VMRTableType::inner, region, false); //projection to next layer/disk
53  }
54 
57  layerdisk_, TrackletLUT::VMRTableType::inneroverlap, region, false); //projection to disk from layer
58  }
59 
63  layerdisk_, TrackletLUT::VMRTableType::innerthird, region, false); //projection to third layer/disk
64  }
65 
68 
69  nvmmebins_ = settings_.NLONGVMBINS() * ((layerdisk_ >= N_LAYER) ? 2 : 1); //number of long z/r bins in VM
70 }
71 
73  if (settings_.writetrace()) {
74  edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output "
75  << output;
76  }
77 
78  if (output == "allinnerstubout") {
80  assert(tmp != nullptr);
81  char memtype = memory->getName().back();
82  allinnerstubs_.emplace_back(memtype, tmp);
83  return;
84  }
85 
86  if (output.substr(0, 10) == "allstubout") {
87  AllStubsMemory* tmp = dynamic_cast<AllStubsMemory*>(memory);
88  allstubs_.push_back(tmp);
89  return;
90  }
91 
92  if (output.substr(0, 9) == "vmstubout") {
93  if (memory->getName().substr(3, 2) == "TE") {
94  VMStubsTEMemory* tmp = dynamic_cast<VMStubsTEMemory*>(memory);
95  int i = output.find_last_of('_');
96  unsigned int iseed = std::stoi(output.substr(i + 1));
97  assert(iseed < N_SEED);
98 
99  // This flag is used to replicate the behavior of the old VMRouter for
100  // the case of the triplet seeds.
101  const bool isTripletSeed = (iseed >= L2L3L4);
102 
103  // seedtype, vmbin, and inner are only used in the case of the triplet
104  // seeds.
105  char seedtype = memory->getName().substr(11, 1)[0];
106  unsigned int pos = 12;
107  int vmbin = memory->getName().substr(pos, 1)[0] - '0';
108  pos++;
109  if (pos < memory->getName().size()) {
110  if (memory->getName().substr(pos, 1)[0] != 'n') {
111  vmbin = vmbin * 10 + memory->getName().substr(pos, 1)[0] - '0';
112  pos++;
113  }
114  }
115  unsigned int inner = 1;
116  if (seedtype < 'I') {
119  inner = 0;
120  } else if (seedtype < 'M') {
121  if (layerdisk_ == LayerDisk::L2)
122  inner = 0;
123  } else if (seedtype <= 'Z') {
125  inner = 0;
126  } else if (seedtype < 'o' && seedtype >= 'a') {
127  if (layerdisk_ == LayerDisk::L2)
128  inner = 0;
129  } else if (seedtype > 'o' && seedtype <= 'z') {
130  inner = 2;
131  } else {
132  throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!";
133  }
134 
135  int seedindex = -1;
136  for (unsigned int k = 0; k < vmstubsTEPHI_.size(); k++) {
137  if (vmstubsTEPHI_[k].seednumber == iseed) {
138  seedindex = k;
139  }
140  }
141  if (seedindex == -1) {
142  seedindex = vmstubsTEPHI_.size();
143  vector<VMStubsTEMemory*> avectmp;
144  vector<vector<VMStubsTEMemory*> > vectmp(!isTripletSeed ? 1 : settings_.nvmte(inner, iseed), avectmp);
145  VMStubsTEPHICM atmp(iseed, inner, vectmp);
146  vmstubsTEPHI_.push_back(atmp);
147  }
148  if (!isTripletSeed) {
149  tmp->resize(settings_.NLONGVMBINS() * settings_.nvmte(1, iseed));
150  vmstubsTEPHI_[seedindex].vmstubmem[0].push_back(tmp);
151  } else {
152  vmstubsTEPHI_[seedindex].vmstubmem[(vmbin - 1) & (settings_.nvmte(inner, iseed) - 1)].push_back(tmp);
153  }
154 
155  } else if (memory->getName().substr(3, 2) == "ME") {
156  VMStubsMEMemory* tmp = dynamic_cast<VMStubsMEMemory*>(memory);
157  assert(tmp != nullptr);
159  vmstubsMEPHI_.push_back(tmp);
160  } else {
161  throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " memory: " << memory->getName()
162  << " => should never get here!";
163  }
164 
165  return;
166  }
167 
168  throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output;
169 }
170 
172  if (settings_.writetrace()) {
173  edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input "
174  << input;
175  }
176  if (input == "stubin") {
177  InputLinkMemory* tmp1 = dynamic_cast<InputLinkMemory*>(memory);
178  assert(tmp1 != nullptr);
179  if (tmp1 != nullptr) {
180  stubinputs_.push_back(tmp1);
181  }
182  return;
183  }
184  throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input;
185 }
186 
187 void VMRouterCM::execute(unsigned int) {
188  unsigned int allStubCounter = 0;
189 
190  //bool print = getName() == "VMR_D1PHIB" && iSector == 3;
191  //print = false;
192 
193  //Loop over the input stubs
194  for (auto& stubinput : stubinputs_) {
195  for (unsigned int i = 0; i < stubinput->nStubs(); i++) {
196  if (allStubCounter > settings_.maxStep("VMR"))
197  continue;
198  if (allStubCounter >= (1 << N_BITSMEMADDRESS))
199  continue;
200 
201  Stub* stub = stubinput->getStub(i);
202 
203  //Note - below information is not part of the stub, but rather from which input memory
204  //we are reading
205  bool negdisk = (stub->disk().value() < 0);
206 
207  //use &127 to make sure we fit into the number of bits -
208  //though we should have protected against overflows above
209  FPGAWord allStubIndex(allStubCounter & ((1 << N_BITSMEMADDRESS) - 1), N_BITSMEMADDRESS, true, __LINE__, __FILE__);
210 
211  //TODO - should not be needed - but need to migrate some other pieces of code before removing
212  stub->setAllStubIndex(allStubCounter);
213  //TODO - should not be needed - but need to migrate some other pieces of code before removing
214  stub->l1tstub()->setAllStubIndex(allStubCounter);
215 
216  allStubCounter++;
217 
218  for (auto& allstub : allstubs_) {
219  allstub->addStub(stub);
220  if (settings_.debugTracklet()) {
221  edm::LogVerbatim("Tracklet") << getName() << " adding stub to " << allstub->getName();
222  }
223  }
224 
225  FPGAWord iphi = stub->phicorr();
226  unsigned int iphipos = iphi.bits(iphi.nbits() - (settings_.nbitsallstubs(layerdisk_) + N_PHIBITS), N_PHIBITS);
227 
228  unsigned int phicutmax = 4;
229  unsigned int phicutmin = 4;
230 
231  if (layerdisk_ != 0) {
232  phicutmax = 6;
233  phicutmin = 2;
234  }
235 
236  //Fill inner allstubs memories - in HLS this is the same write to multiple memories
237  for (auto& allstub : allinnerstubs_) {
238  char memtype = allstub.first;
239  if (memtype == 'R' && iphipos < phicutmax)
240  continue;
241  if (memtype == 'L' && iphipos >= phicutmin)
242  continue;
243  if (memtype == 'A' && iphipos < 4)
244  continue;
245  if (memtype == 'B' && iphipos >= 4)
246  continue;
247  if (memtype == 'E' && iphipos >= 4)
248  continue;
249  if (memtype == 'F' && iphipos < 4)
250  continue;
251  if (memtype == 'C' && iphipos >= 4)
252  continue;
253  if (memtype == 'D' && iphipos < 4)
254  continue;
255 
256  int absz = std::abs(stub->z().value());
258  continue;
261  continue;
263  stub->r().value() > VMROUTERCUTRD1D3 / settings_.kr())
264  continue;
265  if ((layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D3) && stub->r().value() < 2 * int(N_DSS_MOD))
266  continue;
267  if (layerdisk_ == LayerDisk::L1) {
268  if (memtype == 'M' || memtype == 'R' || memtype == 'L') {
269  if (absz < VMROUTERCUTZL1 / settings_.kz(layerdisk_))
270  continue;
271  } else {
273  continue;
274  }
275  }
276 
277  if (settings_.debugTracklet()) {
278  edm::LogVerbatim("Tracklet") << getName() << " adding stub to " << allstub.second->getName();
279  }
280 
281  allstub.second->addStub(stub);
282  }
283 
284  //Fill all the ME VM memories
285  unsigned int ivm =
288 
289  //Calculate the z and r position for the vmstub
290 
291  //Take the top nbitszfinebintable_ bits of the z coordinate
292  int indexz = (stub->z().value() >> (stub->z().nbits() - nbitszfinebintable_)) & ((1 << nbitszfinebintable_) - 1);
293  int indexr = -1;
294  if (layerdisk_ > (N_LAYER - 1)) {
295  if (negdisk) {
296  indexz = ((1 << nbitszfinebintable_) - 1) - indexz;
297  }
298  indexr = stub->r().value();
299  if (stub->isPSmodule()) {
300  indexr = stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_);
301  }
302  } else {
303  //Take the top nbitsfinebintable_ bits of the z coordinate. The & is to handle the negative z values.
304  indexr = (stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_)) & ((1 << nbitsrfinebintable_) - 1);
305  }
306 
307  assert(indexz >= 0);
308  assert(indexr >= 0);
309  assert(indexz < (1 << nbitszfinebintable_));
310  assert(indexr < (1 << nbitsrfinebintable_));
311 
312  int melut = meTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
313 
314  assert(melut >= 0);
315 
316  // The following indices are calculated in the same way as in the old
317  // VMRouter and are only used for the triplet seeds.
318  int indexzOld =
319  (((1 << (stub->z().nbits() - 1)) + stub->z().value()) >> (stub->z().nbits() - nbitszfinebintable_));
320  int indexrOld = -1;
321  if (layerdisk_ > (N_LAYER - 1)) {
322  if (negdisk) {
323  indexzOld = (1 << nbitszfinebintable_) - indexzOld;
324  }
325  indexrOld = stub->r().value();
326  if (stub->isPSmodule()) {
327  indexrOld = stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_);
328  }
329  } else {
330  //Take the top nbitsfinebintable_ bits of the z coordinate. The & is to handle the negative z values.
331  indexrOld = (((1 << (stub->r().nbits() - 1)) + stub->r().value()) >> (stub->r().nbits() - nbitsrfinebintable_));
332  }
333 
334  assert(indexzOld >= 0);
335  assert(indexrOld >= 0);
336  assert(indexzOld < (1 << nbitszfinebintable_));
337  assert(indexrOld < (1 << nbitsrfinebintable_));
338 
339  int melutOld = meTableOld_.lookup((indexzOld << nbitsrfinebintable_) + indexrOld);
340 
341  assert(melutOld >= 0);
342 
343  int vmbin = melut >> NFINERZBITS;
344  if (negdisk)
345  vmbin += (1 << NFINERZBITS);
346  int rzfine = melut & ((1 << NFINERZBITS) - 1);
347 
348  // pad disk PS bend word with a '0' in MSB so that all disk bends have 4 bits (for HLS compatibility)
349  int nbendbits = stub->bend().nbits();
350  if (layerdisk_ >= N_LAYER)
351  nbendbits = settings_.nbendbitsmedisk();
352 
353  VMStubME vmstub(
354  stub,
356  FPGAWord(rzfine, NFINERZBITS, true, __LINE__, __FILE__),
357  FPGAWord(stub->bend().value(), nbendbits, true, __LINE__, __FILE__),
358  allStubIndex);
359 
360  unsigned int nmems = vmstubsMEPHI_.size();
361 
362  for (unsigned int i = 0; i < nmems; i++) { // allows multiple VMStubs to be written for duplicated MPs
363  if (vmstubsMEPHI_[i] != nullptr)
364  vmstubsMEPHI_[i]->addStub(vmstub, ivm * nvmmebins_ + vmbin);
365  }
366 
367  for (auto& ivmstubTEPHI : vmstubsTEPHI_) {
368  unsigned int iseed = ivmstubTEPHI.seednumber;
369 
370  // This flag is used to replicate the behavior of the old VMRouter for
371  // the case of the triplet seeds.
372  const bool isTripletSeed = (iseed >= L2L3L4);
373 
374  if (!isTripletSeed && layerdisk_ >= N_LAYER && (!stub->isPSmodule()))
375  continue;
376  unsigned int inner = (!isTripletSeed ? 1 : ivmstubTEPHI.stubposition);
377  unsigned int lutwidth = settings_.lutwidthtab(inner, iseed);
378  if (settings_.extended()) {
380  }
381 
382  int lutval = -999;
383 
384  if (inner > 0) {
385  if (layerdisk_ < N_LAYER) {
386  lutval = (!isTripletSeed ? melut : melutOld);
387  } else {
388  if (inner == 2 && iseed == Seed::L2L3D1) {
389  lutval = 0;
390  if (stub->r().value() < 10) {
391  lutval = 8 * (1 + (stub->r().value() >> 2));
392  } else {
393  if (stub->r().value() < settings_.rmindiskl3overlapvm() / settings_.kr()) {
394  lutval = -1;
395  }
396  }
397  } else {
398  lutval = (!isTripletSeed ? diskTable_.lookup((indexz << nbitsrfinebintable_) + indexr)
399  : diskTableOld_.lookup((indexzOld << nbitsrfinebintable_) + indexrOld));
400  if (lutval == 0)
401  continue;
402  }
403  }
404  if (lutval == -1)
405  continue;
406  } else {
407  if (iseed < Seed::L1D1 || iseed > Seed::L2D1) {
408  lutval = innerTable_.lookup((indexzOld << nbitsrfinebintable_) + indexrOld);
409  } else {
410  lutval = innerOverlapTable_.lookup((indexzOld << nbitsrfinebintable_) + indexrOld);
411  }
412  if (lutval == -1)
413  continue;
414  if (settings_.extended() &&
416  int lutval2 = innerThirdTable_.lookup((indexzOld << nbitsrfinebintable_) + indexrOld);
417  if (lutval2 != -1) {
418  const auto& lutshift = innerTable_.nbits(); // should be same for all inner tables
419  lutval += (lutval2 << lutshift);
420  }
421  }
422  }
423 
424  assert(lutval >= 0);
425 
426  FPGAWord binlookup(lutval, lutwidth, true, __LINE__, __FILE__);
427 
428  if (binlookup.value() < 0)
429  continue;
430 
431  unsigned int ivmte =
434 
435  int bin = -1;
436  if (inner != 0) {
437  bin = binlookup.value() >> settings_.NLONGVMBITS();
438  unsigned int tmp = binlookup.value() & (settings_.NLONGVMBINS() - 1); //three bits in outer layers
439  binlookup.set(tmp, settings_.NLONGVMBITS(), true, __LINE__, __FILE__);
440  }
441 
443 
444  VMStubTE tmpstub(stub, finephi, stub->bend(), binlookup, allStubIndex);
445 
446  unsigned int nmem = ivmstubTEPHI.vmstubmem[!isTripletSeed ? 0 : ivmte].size();
447  assert(nmem > 0);
448 
449  for (unsigned int l = 0; l < nmem; l++) {
450  if (settings_.debugTracklet()) {
451  edm::LogVerbatim("Tracklet") << getName() << " try adding stub to "
452  << ivmstubTEPHI.vmstubmem[!isTripletSeed ? 0 : ivmte][l]->getName()
453  << " bin=" << bin << " ivmte " << ivmte << " finephi " << finephi.value()
454  << " regions bits " << settings_.nphireg(1, iseed) << " finephibits "
455  << settings_.nfinephi(1, iseed);
456  }
457  if (!isTripletSeed)
458  ivmstubTEPHI.vmstubmem[0][l]->addVMStub(tmpstub, bin, ivmte);
459  else {
460  if (inner == 0) {
461  ivmstubTEPHI.vmstubmem[ivmte][l]->addVMStub(tmpstub);
462  } else {
463  ivmstubTEPHI.vmstubmem[ivmte][l]->addVMStub(tmpstub, bin, 0, false);
464  }
465  }
466  }
467  }
468  }
469  }
470 }
unsigned int vmrlutrbits(unsigned int layerdisk) const
Definition: Settings.h:191
Log< level::Info, true > LogVerbatim
double kz() const
Definition: Settings.h:349
Divides< B, C > D2
Definition: Factorize.h:137
TrackletLUT innerOverlapTable_
Definition: VMRouterCM.h:72
constexpr double VMROUTERCUTZL1L3L5
Definition: Settings.h:49
unsigned int maxStep(std::string module) const
Definition: Settings.h:125
const FPGAWord & r() const
Definition: Stub.h:65
double lutwidthtab(unsigned int inner, unsigned int iSeed) const
Definition: Settings.h:149
TrackletLUT diskTable_
Definition: VMRouterCM.h:65
std::string name_
Definition: ProcessBase.h:42
unsigned int NLONGVMBITS() const
Definition: Settings.h:375
unsigned int nbits() const
Definition: TrackletLUT.h:119
constexpr double VMROUTERCUTZL1
Definition: Settings.h:50
unsigned int nvmmebins_
Definition: VMRouterCM.h:62
TrackletLUT innerTable_
Definition: VMRouterCM.h:71
const FPGAWord & z() const
Definition: Stub.h:66
constexpr unsigned int N_SEED
Definition: Settings.h:28
std::vector< InputLinkMemory * > stubinputs_
Definition: VMRouterCM.h:76
unsigned int nbendbitsmedisk() const
Definition: Settings.h:101
Settings const & settings_
Definition: ProcessBase.h:44
int lookup(unsigned int index) const
bool writetrace() const
Definition: Settings.h:195
std::vector< std::pair< char, AllInnerStubsMemory * > > allinnerstubs_
Definition: VMRouterCM.h:80
const FPGAWord & bend() const
Definition: Stub.h:63
std::vector< VMStubsMEMemory * > vmstubsMEPHI_
Definition: VMRouterCM.h:83
constexpr unsigned int N_DSS_MOD
Definition: Settings.h:31
assert(be >=bs)
constexpr double VMROUTERCUTZL2
Definition: Settings.h:48
TrackletLUT diskTableOld_
Definition: VMRouterCM.h:70
static std::string const input
Definition: EdmProvDump.cc:50
unsigned int NLONGVMBINS() const
Definition: Settings.h:376
const FPGAWord & disk() const
Definition: Stub.h:74
FPGAWord iphivmFineBins(int VMbits, int finebits) const
Definition: Stub.cc:109
void execute(unsigned int iSector)
Definition: VMRouterCM.cc:187
unsigned int nbitsallstubs(unsigned int layerdisk) const
Definition: Settings.h:115
std::vector< VMStubsTEPHICM > vmstubsTEPHI_
Definition: VMRouterCM.h:86
void initVMRTable(unsigned int layerdisk, VMRTableType type, int region=-1, bool combined=true)
Definition: TrackletLUT.cc:998
double rmindiskl3overlapvm() const
Definition: Settings.h:367
unsigned int overlapbits_
Definition: VMRouterCM.h:56
void setAllStubIndex(int nstub)
Definition: Stub.cc:131
TrackletLUT innerThirdTable_
Definition: VMRouterCM.h:73
void addOutput(MemoryBase *memory, std::string output) override
Definition: VMRouterCM.cc:72
Divides< A, C > D1
Definition: Factorize.h:136
unsigned int nbitsvmte(unsigned int inner, unsigned int iSeed) const
Definition: Settings.h:104
constexpr double VMROUTERCUTRD1D3
Definition: Settings.h:51
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int value() const
Definition: FPGAWord.h:24
double lutwidthtabextended(unsigned int inner, unsigned int iSeed) const
Definition: Settings.h:150
L1TStub * l1tstub()
Definition: Stub.h:83
unsigned int nextrabits_
Definition: VMRouterCM.h:57
unsigned int nbitsvmme(unsigned int layerdisk) const
Definition: Settings.h:112
void initLayerDisk(unsigned int pos, int &layer, int &disk)
Definition: ProcessBase.cc:33
unsigned int nvmte(unsigned int inner, unsigned int iSeed) const
Definition: Settings.h:110
constexpr unsigned int NFINERZBITS
Definition: Settings.h:37
unsigned int nallstubs(unsigned int layerdisk) const
Definition: Settings.h:116
bool debugTracklet() const
Definition: Settings.h:194
double kr() const
Definition: Settings.h:351
int iseed
Definition: AMPTWrapper.h:134
int nbits() const
Definition: FPGAWord.h:25
void set(int value, int nbits, bool positive=true, int line=-1, const char *file=nullptr)
Definition: FPGAWord.cc:14
bool isPSmodule() const
Definition: Stub.h:77
int nfinephi(unsigned int inner, unsigned int iSeed) const
Definition: Settings.h:142
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
const FPGAWord & phicorr() const
Definition: Stub.h:69
bool extended() const
Definition: Settings.h:268
unsigned int nvmme(unsigned int layerdisk) const
Definition: Settings.h:113
double nphireg(unsigned int inner, unsigned int iSeed) const
Definition: Settings.h:143
TrackletLUT meTable_
Definition: VMRouterCM.h:64
Definition: output.py:1
void setAllStubIndex(unsigned int index)
Definition: L1TStub.h:83
void addInput(MemoryBase *memory, std::string input) override
Definition: VMRouterCM.cc:171
unsigned int layerdisk_
Definition: VMRouterCM.h:52
tmp
align.sh
Definition: createJobs.py:716
std::vector< AllStubsMemory * > allstubs_
Definition: VMRouterCM.h:79
std::string const & getName() const
Definition: ProcessBase.h:22
constexpr unsigned int N_PHIBITS
Definition: Settings.h:40
TrackletLUT meTableOld_
Definition: VMRouterCM.h:69
constexpr unsigned int N_BITSMEMADDRESS
Definition: Settings.h:43
unsigned int vmrlutzbits(unsigned int layerdisk) const
Definition: Settings.h:190
constexpr int N_LAYER
Definition: Settings.h:25