File indexing completed on 2021-07-07 22:33:40
0001 #include "L1Trigger/TrackFindingTracklet/interface/TrackletProcessor.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/Util.h"
0007 #include "L1Trigger/TrackFindingTracklet/interface/IMATH_TrackletCalculator.h"
0008
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "FWCore/Utilities/interface/Exception.h"
0011 #include "DataFormats/Math/interface/deltaPhi.h"
0012
0013 #include <utility>
0014 #include <tuple>
0015
0016 using namespace std;
0017 using namespace trklet;
0018
0019 TrackletProcessor::TrackletProcessor(string name, Settings const& settings, Globals* globals)
0020 : TrackletCalculatorBase(name, settings, globals),
0021 tebuffer_(CircularBuffer<TEData>(3), 0, 0, 0, 0),
0022 pttableinner_(settings),
0023 pttableouter_(settings),
0024 useregiontable_(settings),
0025 innerTable_(settings),
0026 innerOverlapTable_(settings) {
0027 iAllStub_ = -1;
0028
0029 for (unsigned int ilayer = 0; ilayer < N_LAYER; ilayer++) {
0030 vector<TrackletProjectionsMemory*> tmp(settings_.nallstubs(ilayer), nullptr);
0031 trackletprojlayers_.push_back(tmp);
0032 }
0033
0034 for (unsigned int idisk = 0; idisk < N_DISK; idisk++) {
0035 vector<TrackletProjectionsMemory*> tmp(settings_.nallstubs(idisk + N_LAYER), nullptr);
0036 trackletprojdisks_.push_back(tmp);
0037 }
0038
0039 outervmstubs_ = nullptr;
0040
0041 initLayerDisksandISeed(layerdisk1_, layerdisk2_, iSeed_);
0042
0043 double rmin = -1.0;
0044 double rmax = -1.0;
0045
0046 if (iSeed_ == Seed::L1L2 || iSeed_ == Seed::L2L3 || iSeed_ == Seed::L3L4 || iSeed_ == Seed::L5L6) {
0047 rmin = settings_.rmean(layerdisk1_);
0048 rmax = settings_.rmean(layerdisk2_);
0049 } else {
0050 if (iSeed_ == Seed::L1D1) {
0051 rmax = settings_.rmaxdiskl1overlapvm();
0052 rmin = settings_.rmean(layerdisk1_);
0053 } else if (iSeed_ == Seed::L2D1) {
0054 rmax = settings_.rmaxdiskvm();
0055 rmin = settings_.rmean(layerdisk1_);
0056 } else {
0057 rmax = settings_.rmaxdiskvm();
0058 rmin = rmax * settings_.zmean(layerdisk2_ - N_LAYER - 1) / settings_.zmean(layerdisk2_ - N_LAYER);
0059 }
0060 }
0061
0062 double dphimax = asin(0.5 * settings_.maxrinv() * rmax) - asin(0.5 * settings_.maxrinv() * rmin);
0063
0064
0065 int nfinephibins =
0066 settings_.nallstubs(layerdisk2_) * settings_.nvmte(1, iSeed_) * (1 << settings_.nfinephi(1, iSeed_));
0067 double dfinephi = settings_.dphisectorHG() / nfinephibins;
0068
0069 nbitsfinephi_ = settings_.nbitsallstubs(layerdisk2_) + settings_.nbitsvmte(1, iSeed_) + settings_.nfinephi(1, iSeed_);
0070
0071 int nbins = 2.0 * (dphimax / dfinephi + 1.0);
0072
0073 nbitsfinephidiff_ = log(nbins) / log(2.0) + 1;
0074
0075 nbitszfinebintable_ = settings_.vmrlutzbits(layerdisk1_);
0076 nbitsrfinebintable_ = settings_.vmrlutrbits(layerdisk1_);
0077
0078 nbitsrzbin_ = N_RZBITS;
0079 if (iSeed_ == Seed::D1D2 || iSeed_ == Seed::D3D4)
0080 nbitsrzbin_ = 2;
0081
0082 innerphibits_ = settings_.nfinephi(0, iSeed_);
0083 outerphibits_ = settings_.nfinephi(1, iSeed_);
0084
0085 if (layerdisk1_ == LayerDisk::L1 || layerdisk1_ == LayerDisk::L2 || layerdisk1_ == LayerDisk::L3 ||
0086 layerdisk1_ == LayerDisk::L5 || layerdisk1_ == LayerDisk::D1 || layerdisk1_ == LayerDisk::D3) {
0087 innerTable_.initVMRTable(layerdisk1_, TrackletLUT::VMRTableType::inner);
0088 }
0089
0090 if (layerdisk1_ == LayerDisk::L1 || layerdisk1_ == LayerDisk::L2) {
0091 innerOverlapTable_.initVMRTable(layerdisk1_,
0092 TrackletLUT::VMRTableType::inneroverlap);
0093 }
0094
0095
0096 iTC_ = name_[7] - 'A';
0097 assert(iTC_ >= 0 && iTC_ < 14);
0098
0099 TCIndex_ = (iSeed_ << 4) + iTC_;
0100 assert(TCIndex_ >= 0 && TCIndex_ <= (int)settings_.ntrackletmax());
0101
0102 maxStep_ = settings_.maxStep("TP");
0103 }
0104
0105 void TrackletProcessor::addOutputProjection(TrackletProjectionsMemory*& outputProj, MemoryBase* memory) {
0106 outputProj = dynamic_cast<TrackletProjectionsMemory*>(memory);
0107 assert(outputProj != nullptr);
0108 }
0109
0110 void TrackletProcessor::addOutput(MemoryBase* memory, string output) {
0111 if (settings_.writetrace()) {
0112 edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output "
0113 << output;
0114 }
0115 if (output == "trackpar") {
0116 auto* tmp = dynamic_cast<TrackletParametersMemory*>(memory);
0117 assert(tmp != nullptr);
0118 trackletpars_ = tmp;
0119 return;
0120 }
0121
0122 if (output.substr(0, 7) == "projout") {
0123
0124 auto* tmp = dynamic_cast<TrackletProjectionsMemory*>(memory);
0125 assert(tmp != nullptr);
0126
0127 unsigned int layerdisk = output[8] - '1';
0128 unsigned int phiregion = output[12] - 'A';
0129
0130 if (output[7] == 'L') {
0131 assert(layerdisk < N_LAYER);
0132 assert(phiregion < trackletprojlayers_[layerdisk].size());
0133
0134 assert(trackletprojlayers_[layerdisk][phiregion] == nullptr);
0135 trackletprojlayers_[layerdisk][phiregion] = tmp;
0136 return;
0137 }
0138
0139 if (output[7] == 'D') {
0140 assert(layerdisk < N_DISK);
0141 assert(phiregion < trackletprojdisks_[layerdisk].size());
0142
0143 assert(trackletprojdisks_[layerdisk][phiregion] == nullptr);
0144 trackletprojdisks_[layerdisk][phiregion] = tmp;
0145 return;
0146 }
0147 }
0148
0149 throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find output : " << output;
0150 }
0151
0152 void TrackletProcessor::addInput(MemoryBase* memory, string input) {
0153 if (settings_.writetrace()) {
0154 edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input "
0155 << input;
0156 }
0157
0158 if (input == "outervmstubin") {
0159 auto* tmp = dynamic_cast<VMStubsTEMemory*>(memory);
0160 assert(tmp != nullptr);
0161 outervmstubs_ = tmp;
0162 iAllStub_ = tmp->getName()[11] - 'A';
0163 if (iSeed_ == Seed::L2L3)
0164 iAllStub_ = tmp->getName()[11] - 'I';
0165 if (iSeed_ == Seed::L1D1 || iSeed_ == Seed::L2D1) {
0166 if (tmp->getName()[11] == 'X')
0167 iAllStub_ = 0;
0168 if (tmp->getName()[11] == 'Y')
0169 iAllStub_ = 1;
0170 if (tmp->getName()[11] == 'Z')
0171 iAllStub_ = 2;
0172 if (tmp->getName()[11] == 'W')
0173 iAllStub_ = 3;
0174 }
0175
0176 unsigned int iTP = getName()[7] - 'A';
0177
0178 pttableinner_.initTPlut(true, iSeed_, layerdisk1_, layerdisk2_, nbitsfinephidiff_, iTP);
0179 pttableouter_.initTPlut(false, iSeed_, layerdisk1_, layerdisk2_, nbitsfinephidiff_, iTP);
0180
0181
0182
0183 useregiontable_.initTPregionlut(
0184 iSeed_, layerdisk1_, layerdisk2_, iAllStub_, nbitsfinephidiff_, nbitsfinephi_, pttableinner_, iTP);
0185
0186 TrackletEngineUnit teunit(&settings_,
0187 nbitsfinephi_,
0188 layerdisk1_,
0189 layerdisk2_,
0190 iSeed_,
0191 nbitsfinephidiff_,
0192 iAllStub_,
0193 &pttableinner_,
0194 &pttableouter_,
0195 outervmstubs_);
0196
0197 teunits_.resize(settings_.teunits(iSeed_), teunit);
0198
0199 return;
0200 }
0201
0202 if (input == "innerallstubin") {
0203 auto* tmp = dynamic_cast<AllInnerStubsMemory*>(memory);
0204 assert(tmp != nullptr);
0205 if (innerallstubs_.size() == 2) {
0206 innerallstubs_.insert(innerallstubs_.begin(), tmp);
0207 } else {
0208 innerallstubs_.push_back(tmp);
0209 }
0210
0211
0212 tebuffer_ = tuple<CircularBuffer<TEData>, unsigned int, unsigned int, unsigned int, unsigned int>(
0213 CircularBuffer<TEData>(3), 0, 0, 0, innerallstubs_.size());
0214
0215 return;
0216 }
0217 if (input == "outerallstubin") {
0218 auto* tmp = dynamic_cast<AllStubsMemory*>(memory);
0219 assert(tmp != nullptr);
0220 outerallstubs_.push_back(tmp);
0221 return;
0222 }
0223 throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " Could not find input : " << input;
0224 }
0225
0226 void TrackletProcessor::execute(unsigned int iSector, double phimin, double phimax) {
0227 bool print = (iSector == 3) && (getName() == "TP_L1L2D");
0228 print = false;
0229
0230 phimin_ = phimin;
0231 phimax_ = phimax;
0232 iSector_ = iSector;
0233
0234 if (!settings_.useSeed(iSeed_))
0235 return;
0236
0237
0238 int donecount = 0;
0239
0240
0241 assert(iAllStub_ >= 0);
0242 assert(iAllStub_ < (int)settings_.nallstubs(layerdisk2_));
0243 assert(outervmstubs_ != nullptr);
0244
0245
0246 unsigned int countall = 0;
0247 unsigned int countsel = 0;
0248
0249 unsigned int countteall = 0;
0250 unsigned int stubpairs = 0;
0251
0252 unsigned int ntedata = 0;
0253
0254 unsigned int ninnerstubs = 0;
0255
0256
0257
0258
0259 std::get<0>(tebuffer_).reset();
0260 std::get<1>(tebuffer_) = 0;
0261 std::get<2>(tebuffer_) = std::get<3>(tebuffer_);
0262
0263
0264 for (auto& teunit : teunits_) {
0265 teunit.reset();
0266 }
0267
0268 TEData tedata;
0269 TEData tedata__;
0270 TEData tedata___;
0271 bool goodtedata = false;
0272 bool goodtedata__ = false;
0273 bool goodtedata___ = false;
0274
0275 bool tebuffernearfull;
0276
0277 for (unsigned int istep = 0; istep < maxStep_; istep++) {
0278
0279
0280 if (print) {
0281 CircularBuffer<TEData>& tedatabuffer = std::get<0>(tebuffer_);
0282 unsigned int& istub = std::get<1>(tebuffer_);
0283 unsigned int& imem = std::get<2>(tebuffer_);
0284 cout << "istep=" << istep << " TEBuffer: " << istub << " " << imem << " " << tedatabuffer.rptr() << " "
0285 << tedatabuffer.wptr();
0286 int k = -1;
0287 for (auto& teunit : teunits_) {
0288 k++;
0289 cout << " [" << k << " " << teunit.rptr() << " " << teunit.wptr() << " " << teunit.idle() << "]";
0290 }
0291 cout << endl;
0292 }
0293
0294 CircularBuffer<TEData>& tedatabuffer = std::get<0>(tebuffer_);
0295 tebuffernearfull = tedatabuffer.nearfull();
0296
0297
0298
0299
0300
0301
0302 TrackletEngineUnit* teunitptr = nullptr;
0303
0304 for (auto& teunit : teunits_) {
0305 teunit.setNearFull();
0306 if (!teunit.empty()) {
0307 teunitptr = &teunit;
0308 }
0309 }
0310
0311 if (teunitptr != nullptr) {
0312 auto stubpair = teunitptr->read();
0313 stubpairs++;
0314
0315 if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) {
0316 edm::LogVerbatim("Tracklet") << "Will break on too many tracklets in " << getName();
0317 break;
0318 }
0319 countall++;
0320 const Stub* innerFPGAStub = stubpair.first;
0321 const L1TStub* innerStub = innerFPGAStub->l1tstub();
0322
0323 const Stub* outerFPGAStub = stubpair.second;
0324 const L1TStub* outerStub = outerFPGAStub->l1tstub();
0325
0326 if (settings_.debugTracklet()) {
0327 edm::LogVerbatim("Tracklet") << "TrackletProcessor execute " << getName() << "[" << iSector_ << "]";
0328 }
0329
0330 bool accept = false;
0331
0332 if (iSeed_ == Seed::L1L2 || iSeed_ == Seed::L2L3 || iSeed_ == Seed::L3L4 || iSeed_ == Seed::L5L6) {
0333 accept = barrelSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub);
0334 } else if (iSeed_ == Seed::D1D2 || iSeed_ == Seed::D3D4) {
0335 accept = diskSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub);
0336 } else {
0337 accept = overlapSeeding(outerFPGAStub, outerStub, innerFPGAStub, innerStub);
0338 }
0339
0340 if (accept)
0341 countsel++;
0342
0343 if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) {
0344 edm::LogVerbatim("Tracklet") << "Will break on number of tracklets in " << getName();
0345 assert(0);
0346 break;
0347 }
0348
0349 if (settings_.debugTracklet()) {
0350 edm::LogVerbatim("Tracklet") << "TrackletProcessor execute done";
0351 }
0352 }
0353
0354
0355
0356
0357
0358
0359 bool notemptytebuffer = !tedatabuffer.empty();
0360
0361 int ite = -1;
0362 for (auto& teunit : teunits_) {
0363 ite++;
0364 if (teunit.idle()) {
0365 if (notemptytebuffer) {
0366 teunit.init(std::get<0>(tebuffer_).read());
0367 notemptytebuffer = false;
0368 }
0369 }
0370 teunit.step(print, istep, ite);
0371 }
0372
0373
0374
0375
0376
0377
0378 if (goodtedata___)
0379 tedatabuffer.store(tedata___);
0380
0381 goodtedata = false;
0382
0383 unsigned int& istub = std::get<1>(tebuffer_);
0384 unsigned int& imem = std::get<2>(tebuffer_);
0385 unsigned int imemend = std::get<4>(tebuffer_);
0386
0387 if ((!tebuffernearfull) && imem < imemend && istub < innerallstubs_[imem]->nStubs()) {
0388 ninnerstubs++;
0389
0390 const Stub* stub = innerallstubs_[imem]->getStub(istub);
0391
0392 if (settings_.debugTracklet()) {
0393 edm::LogVerbatim("Tracklet") << getName() << " Have stub in " << innerallstubs_[imem]->getName();
0394 }
0395
0396 bool negdisk = (stub->disk().value() < 0);
0397
0398 FPGAWord phicorr = stub->phicorr();
0399 int innerfinephi = phicorr.bits(phicorr.nbits() - nbitsfinephi_, nbitsfinephi_);
0400 FPGAWord innerbend = stub->bend();
0401
0402
0403 int indexz = (stub->z().value() >> (stub->z().nbits() - nbitszfinebintable_)) & ((1 << nbitszfinebintable_) - 1);
0404 int indexr = -1;
0405 if (layerdisk1_ > (N_LAYER - 1)) {
0406 if (negdisk) {
0407 indexz = ((1 << nbitszfinebintable_) - 1) - indexz;
0408 }
0409 indexr = stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_);
0410 } else {
0411 indexr = (stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_)) & ((1 << nbitsrfinebintable_) - 1);
0412 }
0413
0414 int lutval = -1;
0415 if (iSeed_ < 6) {
0416 lutval = innerTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0417 } else {
0418 lutval = innerOverlapTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0419 }
0420
0421 if (lutval != -1) {
0422 unsigned int lutwidth = settings_.lutwidthtab(0, iSeed_);
0423 FPGAWord lookupbits(lutval, lutwidth, true, __LINE__, __FILE__);
0424
0425 int rzfinebinfirst = lookupbits.bits(0, NFINERZBITS);
0426 int next = lookupbits.bits(NFINERZBITS, 1);
0427 int start = lookupbits.bits(NFINERZBITS + 1, nbitsrzbin_);
0428 int rzdiffmax = lookupbits.bits(NFINERZBITS + 1 + nbitsrzbin_, NFINERZBITS);
0429
0430 if ((iSeed_ == Seed::D1D2 || iSeed_ == Seed::D3D4) && negdisk) {
0431 start += (1 << nbitsrzbin_);
0432 }
0433 int last = start + next;
0434
0435 int nbins = (1 << N_RZBITS);
0436
0437 unsigned int useregindex = (innerfinephi << innerbend.nbits()) + innerbend.value();
0438 if (iSeed_ == Seed::D1D2 || iSeed_ == Seed::D3D4 || iSeed_ == Seed::L1D1 || iSeed_ == Seed::L2D1) {
0439
0440 unsigned int nrbits = 3;
0441 int ir = ((start & ((1 << (nrbits - 1)) - 1)) << 1) + (rzfinebinfirst >> (NFINERZBITS - 1));
0442 useregindex = (useregindex << nrbits) + ir;
0443 }
0444
0445 unsigned int usereg = useregiontable_.lookup(useregindex);
0446
0447 tedata.regions_.clear();
0448 tedata.stub_ = stub;
0449 tedata.rzbinfirst_ = rzfinebinfirst;
0450 tedata.start_ = start;
0451 tedata.innerfinephi_ = innerfinephi;
0452 tedata.rzdiffmax_ = rzdiffmax;
0453 tedata.innerbend_ = innerbend;
0454
0455 std::string mask = "";
0456
0457 for (int ibin = start; ibin <= last; ibin++) {
0458 for (unsigned int ireg = 0; ireg < settings_.nvmte(1, iSeed_); ireg++) {
0459 if (!(usereg & (1 << ireg))) {
0460 mask = "0" + mask;
0461 continue;
0462 }
0463
0464 if (settings_.debugTracklet()) {
0465 edm::LogVerbatim("Tracklet") << getName() << " looking for matching stub in bin " << ibin << " with "
0466 << outervmstubs_->nVMStubsBinned(ireg * nbins + ibin) << " stubs";
0467 }
0468 assert(ireg * nbins + ibin < outervmstubs_->nBin());
0469 int nstubs = outervmstubs_->nVMStubsBinned(ireg * nbins + ibin);
0470
0471 if (nstubs > 0) {
0472 mask = "1" + mask;
0473 tedata.regions_.emplace_back(tuple<int, int, int>(ibin - start, ireg, nstubs));
0474 countteall += nstubs;
0475 } else {
0476 mask = "0" + mask;
0477 }
0478 }
0479 }
0480
0481 if (!tedata.regions_.empty()) {
0482 ntedata++;
0483 goodtedata = true;
0484 }
0485 }
0486 istub++;
0487 if (istub >= innerallstubs_[imem]->nStubs()) {
0488 istub = 0;
0489 imem++;
0490 }
0491 } else if ((!tebuffernearfull) && imem < imemend && istub == 0) {
0492 imem++;
0493 }
0494
0495 goodtedata___ = goodtedata__;
0496 goodtedata__ = goodtedata;
0497
0498 tedata___ = tedata__;
0499 tedata__ = tedata;
0500
0501
0502
0503
0504
0505 bool done = true;
0506
0507 if (imem < imemend || (!tedatabuffer.empty())) {
0508 done = false;
0509 }
0510
0511 for (auto& teunit : teunits_) {
0512 if (!(teunit.idle() && teunit.empty()))
0513 done = false;
0514 }
0515
0516 if (done) {
0517 donecount++;
0518 }
0519
0520
0521 if (donecount > 4) {
0522 break;
0523 }
0524 }
0525
0526
0527
0528
0529
0530 if (settings_.writeMonitorData("TP")) {
0531 globals_->ofstream("trackletprocessor.txt") << getName() << " " << ninnerstubs
0532 << " " << outervmstubs_->nVMStubs()
0533 << " " << countteall
0534 << " " << stubpairs
0535 << " " << countsel
0536 << endl;
0537 }
0538 }