Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:13:58

0001 #include "L1Trigger/TrackFindingTracklet/interface/TrackletProcessorDisplaced.h"
0002 #include "L1Trigger/TrackFindingTracklet/interface/Settings.h"
0003 #include "L1Trigger/TrackFindingTracklet/interface/Globals.h"
0004 #include "L1Trigger/TrackFindingTracklet/interface/AllStubsMemory.h"
0005 #include "L1Trigger/TrackFindingTracklet/interface/AllInnerStubsMemory.h"
0006 #include "L1Trigger/TrackFindingTracklet/interface/StubPairsMemory.h"
0007 #include "L1Trigger/TrackFindingTracklet/interface/Tracklet.h"
0008 #include "L1Trigger/TrackFindingTracklet/interface/Util.h"
0009 #include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h"
0010 
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "FWCore/Utilities/interface/Exception.h"
0013 #include "DataFormats/Math/interface/deltaPhi.h"
0014 
0015 #include <utility>
0016 #include <tuple>
0017 
0018 using namespace std;
0019 using namespace trklet;
0020 
0021 TrackletProcessorDisplaced::TrackletProcessorDisplaced(string name, Settings const& settings, Globals* globals)
0022     : TrackletCalculatorDisplaced(name, settings, globals),
0023       innerTable_(settings),
0024       innerOverlapTable_(settings),
0025       innerThirdTable_(settings) {
0026   innerallstubs_.clear();
0027   middleallstubs_.clear();
0028   outerallstubs_.clear();
0029   stubpairs_.clear();
0030   innervmstubs_.clear();
0031   outervmstubs_.clear();
0032 
0033   const unsigned layerdiskPosInName = 4;
0034   const unsigned regionPosInName1 = 9;
0035 
0036   // iAllStub_ = -1;
0037   layerdisk_ = initLayerDisk(layerdiskPosInName);
0038 
0039   unsigned int region = name.substr(1)[regionPosInName1] - 'A';
0040   // assert(region < settings_.nallstubs(layerdisk_));
0041 
0042   if (layerdisk_ == LayerDisk::L1 || layerdisk_ == LayerDisk::L2 || layerdisk_ == LayerDisk::L3 ||
0043       layerdisk_ == LayerDisk::L5 || layerdisk_ == LayerDisk::D1 || layerdisk_ == LayerDisk::D3) {
0044     innerTable_.initVMRTable(layerdisk_, TrackletLUT::VMRTableType::inner, region);  //projection to next layer/disk
0045   }
0046 
0047   if (layerdisk_ == LayerDisk::L1 || layerdisk_ == LayerDisk::L2) {
0048     innerOverlapTable_.initVMRTable(
0049         layerdisk_, TrackletLUT::VMRTableType::inneroverlap, region);  //projection to disk from layer
0050   }
0051 
0052   if (layerdisk_ == LayerDisk::L2 || layerdisk_ == LayerDisk::L3 || layerdisk_ == LayerDisk::L5 ||
0053       layerdisk_ == LayerDisk::D1) {
0054     innerThirdTable_.initVMRTable(
0055         layerdisk_, TrackletLUT::VMRTableType::innerthird, region);  //projection to third layer/disk
0056   }
0057 
0058   nbitszfinebintable_ = settings_.vmrlutzbits(layerdisk_);
0059   nbitsrfinebintable_ = settings_.vmrlutrbits(layerdisk_);
0060 
0061   for (unsigned int ilayer = 0; ilayer < N_LAYER; ilayer++) {
0062     vector<TrackletProjectionsMemory*> tmp(settings_.nallstubs(ilayer), nullptr);
0063     trackletprojlayers_.push_back(tmp);
0064   }
0065 
0066   for (unsigned int idisk = 0; idisk < N_DISK; idisk++) {
0067     vector<TrackletProjectionsMemory*> tmp(settings_.nallstubs(idisk + N_LAYER), nullptr);
0068     trackletprojdisks_.push_back(tmp);
0069   }
0070 
0071   // initLayerDisksandISeed(layerdisk1_, layerdisk2_, iSeed_);
0072 
0073   layer_ = 0;
0074   disk_ = 0;
0075   layer1_ = 0;
0076   layer2_ = 0;
0077   layer3_ = 0;
0078   disk1_ = 0;
0079   disk2_ = 0;
0080   disk3_ = 0;
0081 
0082   constexpr unsigned layerPosInName1 = 4;
0083   constexpr unsigned diskPosInName1 = 4;
0084   constexpr unsigned layer1PosInName1 = 4;
0085   constexpr unsigned disk1PosInName1 = 4;
0086   constexpr unsigned layer2PosInName1 = 6;
0087   constexpr unsigned disk2PosInName1 = 6;
0088 
0089   string name1 = name.substr(1);  //this is to correct for "TPD" having one more letter then "TP"
0090   if (name1[3] == 'L')
0091     layer_ = name1[layerPosInName1] - '0';
0092   if (name1[3] == 'D')
0093     disk_ = name1[diskPosInName1] - '0';
0094 
0095   if (name1[3] == 'L')
0096     layer1_ = name1[layer1PosInName1] - '0';
0097   if (name1[3] == 'D')
0098     disk1_ = name1[disk1PosInName1] - '0';
0099   if (name1[5] == 'L')
0100     layer2_ = name1[layer2PosInName1] - '0';
0101   if (name1[5] == 'D')
0102     disk2_ = name1[disk2PosInName1] - '0';
0103 
0104   // set TC index
0105   iSeed_ = 0;
0106 
0107   int iTC = name1[regionPosInName1] - 'A';
0108 
0109   if (name1.substr(3, 6) == "L3L4L2") {
0110     iSeed_ = 8;
0111     layer3_ = 2;
0112   } else if (name1.substr(3, 6) == "L5L6L4") {
0113     iSeed_ = 9;
0114     layer3_ = 4;
0115   } else if (name1.substr(3, 6) == "L2L3D1") {
0116     iSeed_ = 10;
0117     disk3_ = 1;
0118   } else if (name1.substr(3, 6) == "D1D2L2") {
0119     iSeed_ = 11;
0120     layer3_ = 2;
0121   }
0122   assert(iSeed_ != 0);
0123 
0124   constexpr int TCIndexMin = 128;
0125   constexpr int TCIndexMax = 191;
0126 
0127   TCIndex_ = (iSeed_ << 4) + iTC;
0128   assert(TCIndex_ >= TCIndexMin && TCIndex_ < TCIndexMax);
0129 
0130   assert((layer_ != 0) || (disk_ != 0));
0131 }
0132 
0133 void TrackletProcessorDisplaced::addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory) {
0134   outputProj = dynamic_cast<TrackletProjectionsMemory*>(memory);
0135   assert(outputProj != nullptr);
0136 }
0137 
0138 void TrackletProcessorDisplaced::addOutput(MemoryBase* memory, string output) {
0139   if (settings_.writetrace()) {
0140     edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output "
0141                                  << output;
0142   }
0143 
0144   if (output == "trackpar") {
0145     auto* tmp = dynamic_cast<TrackletParametersMemory*>(memory);
0146     assert(tmp != nullptr);
0147     trackletpars_ = tmp;
0148     return;
0149   }
0150 
0151   if (output.substr(0, 7) == "projout") {
0152     //output is on the form 'projoutL2PHIC' or 'projoutD3PHIB'
0153     auto* tmp = dynamic_cast<TrackletProjectionsMemory*>(memory);
0154     assert(tmp != nullptr);
0155 
0156     constexpr unsigned layerdiskPosInprojout = 8;
0157     constexpr unsigned phiPosInprojout = 12;
0158 
0159     unsigned int layerdisk = output[layerdiskPosInprojout] - '1';  //layer or disk counting from 0
0160     unsigned int phiregion = output[phiPosInprojout] - 'A';        //phiregion counting from 0
0161 
0162     if (output[7] == 'L') {
0163       assert(layerdisk < N_LAYER);
0164       assert(phiregion < trackletprojlayers_[layerdisk].size());
0165       //check that phiregion not already initialized
0166       assert(trackletprojlayers_[layerdisk][phiregion] == nullptr);
0167       trackletprojlayers_[layerdisk][phiregion] = tmp;
0168       return;
0169     }
0170 
0171     if (output[7] == 'D') {
0172       assert(layerdisk < N_DISK);
0173       assert(phiregion < trackletprojdisks_[layerdisk].size());
0174       //check that phiregion not already initialized
0175       assert(trackletprojdisks_[layerdisk][phiregion] == nullptr);
0176       trackletprojdisks_[layerdisk][phiregion] = tmp;
0177       return;
0178     }
0179   }
0180 
0181   throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output;
0182 }
0183 
0184 void TrackletProcessorDisplaced::addInput(MemoryBase* memory, string input) {
0185   if (settings_.writetrace()) {
0186     edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input "
0187                                  << input;
0188   }
0189 
0190   if (input == "thirdallstubin") {
0191     auto* tmp = dynamic_cast<AllStubsMemory*>(memory);
0192     assert(tmp != nullptr);
0193     innerallstubs_.push_back(tmp);
0194     return;
0195   }
0196   if (input == "firstallstubin") {
0197     auto* tmp = dynamic_cast<AllStubsMemory*>(memory);
0198     assert(tmp != nullptr);
0199     middleallstubs_.push_back(tmp);
0200     return;
0201   }
0202   if (input == "secondallstubin") {
0203     auto* tmp = dynamic_cast<AllStubsMemory*>(memory);
0204     assert(tmp != nullptr);
0205     outerallstubs_.push_back(tmp);
0206     return;
0207   }
0208   if (input.substr(0, 8) == "stubpair") {
0209     auto* tmp = dynamic_cast<StubPairsMemory*>(memory);
0210     assert(tmp != nullptr);
0211     stubpairs_.push_back(tmp);
0212     return;
0213   }
0214 
0215   if (input == "thirdvmstubin") {
0216     auto* tmp = dynamic_cast<VMStubsTEMemory*>(memory);
0217     assert(tmp != nullptr);
0218     innervmstubs_.push_back(tmp);
0219     return;
0220   }
0221   if (input == "secondvmstubin") {
0222     auto* tmp = dynamic_cast<VMStubsTEMemory*>(memory);
0223     assert(tmp != nullptr);
0224     // outervmstubs_ = tmp;
0225     outervmstubs_.push_back(tmp);
0226     return;
0227   }
0228 
0229   throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input;
0230 }
0231 
0232 void TrackletProcessorDisplaced::execute(unsigned int iSector, double phimin, double phimax) {
0233   unsigned int countall = 0;
0234   unsigned int countall_ = 0;
0235   unsigned int countsel = 0;
0236   unsigned int countpass = 0;
0237   unsigned int countpass_ = 0;
0238   // unsigned int nThirdStubs = 0;
0239   // unsigned int nOuterStubs = 0;
0240   count_ = 0;
0241 
0242   phimin_ = phimin;
0243   phimax_ = phimax;
0244   iSector_ = iSector;
0245 
0246   assert(!innerallstubs_.empty());
0247   assert(!middleallstubs_.empty());
0248   assert(!outerallstubs_.empty());
0249   assert(!innervmstubs_.empty());
0250   assert(!outervmstubs_.empty());
0251   assert(stubpairs_.empty());
0252 
0253   for (auto& iInnerMem : middleallstubs_) {
0254     assert(iInnerMem->nStubs() == iInnerMem->nStubs());
0255     for (unsigned int j = 0; j < iInnerMem->nStubs(); j++) {
0256       const Stub* firstallstub = iInnerMem->getStub(j);
0257 
0258       if (settings_.debugTracklet()) {
0259         edm::LogVerbatim("Tracklet") << "In " << getName() << " have first stub\n";
0260       }
0261 
0262       int inner = 0;
0263       bool negdisk = (firstallstub->disk().value() < 0);
0264       int indexz = (((1 << (firstallstub->z().nbits() - 1)) + firstallstub->z().value()) >>
0265                     (firstallstub->z().nbits() - nbitszfinebintable_));
0266       int indexr = -1;
0267       if (layerdisk_ > (N_LAYER - 1)) {
0268         if (negdisk) {
0269           indexz = (1 << nbitszfinebintable_) - indexz;
0270         }
0271         indexr = firstallstub->r().value();
0272         if (firstallstub->isPSmodule()) {
0273           indexr = firstallstub->r().value() >> (firstallstub->r().nbits() - nbitsrfinebintable_);
0274         }
0275       } else {
0276         //Take the top nbitsfinebintable_ bits of the z coordinate. The & is to handle the negative z values.
0277         indexr = (((1 << (firstallstub->r().nbits() - 1)) + firstallstub->r().value()) >>
0278                   (firstallstub->r().nbits() - nbitsrfinebintable_));
0279       }
0280 
0281       assert(indexz >= 0);
0282       assert(indexr >= 0);
0283       assert(indexz < (1 << nbitszfinebintable_));
0284       assert(indexr < (1 << nbitsrfinebintable_));
0285 
0286       // int melut = meTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0287       // assert(melut >= 0);
0288 
0289       unsigned int lutwidth = settings_.lutwidthtab(inner, iSeed_);
0290       if (settings_.extended()) {
0291         lutwidth = settings_.lutwidthtabextended(inner, iSeed_);
0292       }
0293 
0294       int lutval = -999;
0295 
0296       if (iSeed_ < Seed::L1D1 || iSeed_ > Seed::L2D1) {
0297         lutval = innerTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0298       } else {
0299         lutval = innerOverlapTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0300       }
0301 
0302       if (lutval == -1)
0303         continue;
0304       if (settings_.extended() &&
0305           (iSeed_ == Seed::L2L3L4 || iSeed_ == Seed::L4L5L6 || iSeed_ == Seed::D1D2L2 || iSeed_ == Seed::L2L3D1)) {
0306         int lutval2 = innerThirdTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0307         if (lutval2 != -1)
0308           lutval += (lutval2 << 10);
0309       }
0310 
0311       assert(lutval >= 0);
0312       // assert(lutwidth > 0);
0313 
0314       FPGAWord binlookup(lutval, lutwidth, true, __LINE__, __FILE__);
0315 
0316       if ((layer1_ == 3 && layer2_ == 4) || (layer1_ == 5 && layer2_ == 6)) {
0317         if (settings_.debugTracklet()) {
0318           edm::LogVerbatim("Tracklet") << getName() << " Layer-layer pair\n";
0319         }
0320 
0321         constexpr int andlookupbits = 1023;
0322         constexpr int shiftzdiffmax = 7;
0323         constexpr int andnewbin = 127;
0324         constexpr int divbin = 8;
0325         constexpr int andzbinfirst = 7;
0326         constexpr int shiftstart = 1;
0327         constexpr int andlast = 1;
0328         constexpr int maxlast = 8;
0329 
0330         int lookupbits = binlookup.value() & andlookupbits;
0331         int zdiffmax = (lookupbits >> shiftzdiffmax);
0332         int newbin = (lookupbits & andnewbin);
0333         int bin = newbin / divbin;
0334 
0335         int zbinfirst = newbin & andzbinfirst;
0336 
0337         int start = (bin >> shiftstart);
0338         int last = start + (bin & andlast);
0339 
0340         assert(last < maxlast);
0341 
0342         if (settings_.debugTracklet()) {
0343           edm::LogVerbatim("Tracklet") << "Will look in zbins " << start << " to " << last << endl;
0344         }
0345 
0346         for (int ibin = start; ibin <= last; ibin++) {
0347           for (unsigned int m = 0; m < outervmstubs_.size(); m++) {
0348             for (unsigned int j = 0; j < outervmstubs_.at(m)->nVMStubsBinned(ibin); j++) {
0349               if (settings_.debugTracklet()) {
0350                 edm::LogVerbatim("Tracklet")
0351                     << "In " << getName() << " have second stub(1) " << ibin << " " << j << endl;
0352               }
0353 
0354               const VMStubTE& secondvmstub = outervmstubs_.at(m)->getVMStubTEBinned(ibin, j);
0355 
0356               int zbin = (secondvmstub.vmbits().value() & 7);
0357               if (start != ibin)
0358                 zbin += 8;
0359               if (zbin < zbinfirst || zbin - zbinfirst > zdiffmax) {
0360                 if (settings_.debugTracklet()) {
0361                   edm::LogVerbatim("Tracklet") << "Stubpair rejected because of wrong zbin";
0362                 }
0363                 continue;
0364               }
0365 
0366               countpass++;
0367 
0368               if ((layer2_ == 4 && layer3_ == 2) || (layer2_ == 6 && layer3_ == 4)) {
0369                 constexpr int vmbitshift = 10;
0370                 constexpr int andlookupbits_ = 1023;
0371                 constexpr int andnewbin_ = 127;
0372                 constexpr int divbin_ = 8;
0373                 constexpr int shiftstart_ = 1;
0374                 constexpr int andlast_ = 1;
0375 
0376                 int lookupbits_ = (int)((binlookup.value() >> vmbitshift) & andlookupbits_);
0377                 int newbin_ = (lookupbits_ & andnewbin_);
0378                 int bin_ = newbin_ / divbin_;
0379 
0380                 int start_ = (bin_ >> shiftstart_);
0381                 int last_ = start_ + (bin_ & andlast_);
0382 
0383                 if (settings_.debugTracklet()) {
0384                   edm::LogVerbatim("Tracklet")
0385                       << "Will look in zbins for third stub" << start_ << " to " << last_ << endl;
0386                 }
0387 
0388                 for (int ibin_ = start_; ibin_ <= last_; ibin_++) {
0389                   for (unsigned int k = 0; k < innervmstubs_.size(); k++) {
0390                     for (unsigned int l = 0; l < innervmstubs_.at(k)->nVMStubsBinned(ibin_); l++) {
0391                       if (settings_.debugTracklet()) {
0392                         edm::LogVerbatim("Tracklet") << "In " << getName() << " have third stub\n";
0393                       }
0394 
0395                       countall_++;
0396 
0397                       const VMStubTE& thirdvmstub = innervmstubs_.at(k)->getVMStubTEBinned(ibin_, l);
0398 
0399                       countpass_++;
0400 
0401                       const Stub* innerFPGAStub = firstallstub;
0402                       const Stub* middleFPGAStub = secondvmstub.stub();
0403                       const Stub* outerFPGAStub = thirdvmstub.stub();
0404 
0405                       const L1TStub* innerStub = innerFPGAStub->l1tstub();
0406                       const L1TStub* middleStub = middleFPGAStub->l1tstub();
0407                       const L1TStub* outerStub = outerFPGAStub->l1tstub();
0408 
0409                       if (settings_.debugTracklet()) {
0410                         edm::LogVerbatim("Tracklet")
0411                             << "LLL seeding\n"
0412                             << innerFPGAStub->strbare() << middleFPGAStub->strbare() << outerFPGAStub->strbare()
0413                             << innerStub->stubword() << middleStub->stubword() << outerStub->stubword()
0414                             << innerFPGAStub->layerdisk() << middleFPGAStub->layerdisk() << outerFPGAStub->layerdisk();
0415                       }
0416 
0417                       if (settings_.debugTracklet()) {
0418                         edm::LogVerbatim("Tracklet")
0419                             << "TrackletCalculatorDisplaced execute " << getName() << "[" << iSector_ << "]";
0420                       }
0421 
0422                       if (innerFPGAStub->layerdisk() < N_LAYER && middleFPGAStub->layerdisk() < N_LAYER &&
0423                           outerFPGAStub->layerdisk() < N_LAYER) {
0424                         bool accept =
0425                             LLLSeeding(outerFPGAStub, outerStub, innerFPGAStub, innerStub, middleFPGAStub, middleStub);
0426 
0427                         if (accept)
0428                           countsel++;
0429                       } else if (innerFPGAStub->layerdisk() >= N_LAYER && middleFPGAStub->layerdisk() >= N_LAYER &&
0430                                  outerFPGAStub->layerdisk() >= N_LAYER) {
0431                         throw cms::Exception("LogicError") << __FILE__ << " " << __LINE__ << " Invalid seeding!";
0432                       }
0433 
0434                       if (settings_.debugTracklet()) {
0435                         edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced execute done";
0436                       }
0437                     }
0438                   }
0439                 }
0440               }
0441             }
0442           }
0443         }
0444 
0445       } else if (layer1_ == 2 && layer2_ == 3) {
0446         if (settings_.debugTracklet()) {
0447           edm::LogVerbatim("Tracklet") << getName() << " Layer-layer pair";
0448         }
0449 
0450         constexpr int andlookupbits = 1023;
0451         constexpr int shiftzdiffmax = 7;
0452         constexpr int andnewbin = 127;
0453         constexpr int divbin = 8;
0454         constexpr int andzbinfirst = 7;
0455         constexpr int shiftstart = 1;
0456         constexpr int andlast = 1;
0457         constexpr int maxlast = 8;
0458 
0459         int lookupbits = binlookup.value() & andlookupbits;
0460         int zdiffmax = (lookupbits >> shiftzdiffmax);
0461         int newbin = (lookupbits & andnewbin);
0462         int bin = newbin / divbin;
0463 
0464         int zbinfirst = newbin & andzbinfirst;
0465 
0466         int start = (bin >> shiftstart);
0467         int last = start + (bin & andlast);
0468 
0469         assert(last < maxlast);
0470 
0471         if (settings_.debugTracklet()) {
0472           edm::LogVerbatim("Tracklet") << "Will look in zbins " << start << " to " << last;
0473         }
0474 
0475         for (int ibin = start; ibin <= last; ibin++) {
0476           for (unsigned int m = 0; m < outervmstubs_.size(); m++) {
0477             for (unsigned int j = 0; j < outervmstubs_.at(m)->nVMStubsBinned(ibin); j++) {
0478               if (settings_.debugTracklet()) {
0479                 edm::LogVerbatim("Tracklet") << "In " << getName() << " have second stub(1) " << ibin << " " << j;
0480               }
0481 
0482               countall++;
0483               const VMStubTE& secondvmstub = outervmstubs_.at(m)->getVMStubTEBinned(ibin, j);
0484 
0485               int zbin = (secondvmstub.vmbits().value() & 7);
0486               if (start != ibin)
0487                 zbin += 8;
0488               if (zbin < zbinfirst || zbin - zbinfirst > zdiffmax) {
0489                 if (settings_.debugTracklet()) {
0490                   edm::LogVerbatim("Tracklet") << "Stubpair rejected because of wrong zbin";
0491                 }
0492                 continue;
0493               }
0494 
0495               if (layer2_ == 3 && disk3_ == 1) {
0496                 constexpr int vmbitshift = 10;
0497                 constexpr int andlookupbits_ = 1023;
0498                 constexpr int andnewbin_ = 127;
0499                 constexpr int divbin_ = 8;
0500                 constexpr int shiftstart_ = 1;
0501                 constexpr int andlast_ = 1;
0502 
0503                 int lookupbits_ = (int)((binlookup.value() >> vmbitshift) & andlookupbits_);
0504                 int newbin_ = (lookupbits_ & andnewbin_);
0505                 int bin_ = newbin_ / divbin_;
0506 
0507                 int start_ = (bin_ >> shiftstart_);
0508                 int last_ = start_ + (bin_ & andlast_);
0509 
0510                 for (int ibin_ = start_; ibin_ <= last_; ibin_++) {
0511                   for (unsigned int k = 0; k < innervmstubs_.size(); k++) {
0512                     for (unsigned int l = 0; l < innervmstubs_.at(k)->nVMStubsBinned(ibin_); l++) {
0513                       if (settings_.debugTracklet()) {
0514                         edm::LogVerbatim("Tracklet") << "In " << getName() << " have third stub";
0515                       }
0516 
0517                       countall_++;
0518 
0519                       const VMStubTE& thirdvmstub = innervmstubs_.at(k)->getVMStubTEBinned(ibin_, l);
0520 
0521                       countpass_++;
0522 
0523                       const Stub* innerFPGAStub = firstallstub;
0524                       const Stub* middleFPGAStub = secondvmstub.stub();
0525                       const Stub* outerFPGAStub = thirdvmstub.stub();
0526 
0527                       const L1TStub* innerStub = innerFPGAStub->l1tstub();
0528                       const L1TStub* middleStub = middleFPGAStub->l1tstub();
0529                       const L1TStub* outerStub = outerFPGAStub->l1tstub();
0530 
0531                       if (settings_.debugTracklet()) {
0532                         edm::LogVerbatim("Tracklet")
0533                             << "LLD seeding\n"
0534                             << innerFPGAStub->strbare() << middleFPGAStub->strbare() << outerFPGAStub->strbare()
0535                             << innerStub->stubword() << middleStub->stubword() << outerStub->stubword()
0536                             << innerFPGAStub->layerdisk() << middleFPGAStub->layerdisk() << outerFPGAStub->layerdisk();
0537                       }
0538 
0539                       if (settings_.debugTracklet()) {
0540                         edm::LogVerbatim("Tracklet")
0541                             << "TrackletCalculatorDisplaced execute " << getName() << "[" << iSector_ << "]";
0542                       }
0543 
0544                       bool accept =
0545                           LLDSeeding(outerFPGAStub, outerStub, innerFPGAStub, innerStub, middleFPGAStub, middleStub);
0546 
0547                       if (accept)
0548                         countsel++;
0549 
0550                       if (settings_.debugTracklet()) {
0551                         edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced execute done";
0552                       }
0553                     }
0554                   }
0555                 }
0556               }
0557             }
0558           }
0559         }
0560 
0561       } else if (disk1_ == 1 && disk2_ == 2) {
0562         if (settings_.debugTracklet())
0563           edm::LogVerbatim("Tracklet") << getName() << " Disk-disk pair";
0564 
0565         constexpr int andlookupbits = 511;
0566         constexpr int shiftrdiffmax = 6;
0567         constexpr int andnewbin = 63;
0568         constexpr int divbin = 8;
0569         constexpr int andrbinfirst = 7;
0570         constexpr int shiftstart = 1;
0571         constexpr int andlast = 1;
0572         constexpr int maxlast = 8;
0573 
0574         int lookupbits = binlookup.value() & andlookupbits;
0575         bool negdisk = firstallstub->disk().value() < 0;
0576         int rdiffmax = (lookupbits >> shiftrdiffmax);
0577         int newbin = (lookupbits & andnewbin);
0578         int bin = newbin / divbin;
0579 
0580         int rbinfirst = newbin & andrbinfirst;
0581 
0582         int start = (bin >> shiftstart);
0583         if (negdisk)
0584           start += 4;
0585         int last = start + (bin & andlast);
0586         assert(last < maxlast);
0587 
0588         for (int ibin = start; ibin <= last; ibin++) {
0589           for (unsigned int m = 0; m < outervmstubs_.size(); m++) {
0590             if (settings_.debugTracklet()) {
0591               edm::LogVerbatim("Tracklet")
0592                   << getName() << " looking for matching stub in " << outervmstubs_.at(m)->getName()
0593                   << " in bin = " << ibin << " with " << outervmstubs_.at(m)->nVMStubsBinned(ibin) << " stubs";
0594             }
0595 
0596             for (unsigned int j = 0; j < outervmstubs_.at(m)->nVMStubsBinned(ibin); j++) {
0597               countall++;
0598 
0599               const VMStubTE& secondvmstub = outervmstubs_.at(m)->getVMStubTEBinned(ibin, j);
0600               int rbin = (secondvmstub.vmbits().value() & 7);
0601               if (start != ibin)
0602                 rbin += 8;
0603               if (rbin < rbinfirst)
0604                 continue;
0605               if (rbin - rbinfirst > rdiffmax)
0606                 continue;
0607 
0608               if (disk2_ == 2 && layer3_ == 2) {
0609                 constexpr int vmbitshift = 10;
0610                 constexpr int andlookupbits_ = 1023;
0611                 constexpr int andnewbin_ = 127;
0612                 constexpr int divbin_ = 8;
0613                 constexpr int shiftstart_ = 1;
0614                 constexpr int andlast_ = 1;
0615 
0616                 int lookupbits_ = (int)((binlookup.value() >> vmbitshift) & andlookupbits_);
0617                 int newbin_ = (lookupbits_ & andnewbin_);
0618                 int bin_ = newbin_ / divbin_;
0619 
0620                 int start_ = (bin_ >> shiftstart_);
0621                 int last_ = start_ + (bin_ & andlast_);
0622 
0623                 if (firstallstub->disk().value() < 0) {  //TODO - negative disk should come from memory
0624                   start_ = settings_.NLONGVMBINS() - last_ - 1;
0625                   last_ = settings_.NLONGVMBINS() - start_ - 1;
0626                 }
0627 
0628                 for (int ibin_ = start_; ibin_ <= last_; ibin_++) {
0629                   for (unsigned int k = 0; k < innervmstubs_.size(); k++) {
0630                     for (unsigned int l = 0; l < innervmstubs_.at(k)->nVMStubsBinned(ibin_); l++) {
0631                       if (settings_.debugTracklet()) {
0632                         edm::LogVerbatim("Tracklet") << "In " << getName() << " have third stub";
0633                       }
0634 
0635                       countall_++;
0636 
0637                       const VMStubTE& thirdvmstub = innervmstubs_.at(k)->getVMStubTEBinned(ibin_, l);
0638 
0639                       countpass_++;
0640 
0641                       const Stub* innerFPGAStub = firstallstub;
0642                       const Stub* middleFPGAStub = secondvmstub.stub();
0643                       const Stub* outerFPGAStub = thirdvmstub.stub();
0644 
0645                       const L1TStub* innerStub = innerFPGAStub->l1tstub();
0646                       const L1TStub* middleStub = middleFPGAStub->l1tstub();
0647                       const L1TStub* outerStub = outerFPGAStub->l1tstub();
0648 
0649                       if (settings_.debugTracklet()) {
0650                         edm::LogVerbatim("Tracklet")
0651                             << "DDL seeding\n"
0652                             << innerFPGAStub->strbare() << middleFPGAStub->strbare() << outerFPGAStub->strbare()
0653                             << innerStub->stubword() << middleStub->stubword() << outerStub->stubword()
0654                             << innerFPGAStub->layerdisk() << middleFPGAStub->layerdisk() << outerFPGAStub->layerdisk();
0655                       }
0656 
0657                       if (settings_.debugTracklet()) {
0658                         edm::LogVerbatim("Tracklet")
0659                             << "TrackletCalculatorDisplaced execute " << getName() << "[" << iSector_ << "]";
0660                       }
0661 
0662                       bool accept =
0663                           DDLSeeding(outerFPGAStub, outerStub, innerFPGAStub, innerStub, middleFPGAStub, middleStub);
0664 
0665                       if (accept)
0666                         countsel++;
0667 
0668                       if (settings_.debugTracklet()) {
0669                         edm::LogVerbatim("Tracklet") << "TrackletCalculatorDisplaced execute done";
0670                       }
0671                     }
0672                   }
0673                 }
0674               }
0675             }
0676           }
0677         }
0678       }
0679     }
0680   }
0681 }