CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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