File indexing completed on 2024-04-06 12:22:05
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 countsel = 0;
0247
0248 unsigned int countteall = 0;
0249 unsigned int stubpairs = 0;
0250
0251 unsigned int ninnerstubs = 0;
0252
0253
0254
0255
0256 std::get<0>(tebuffer_).reset();
0257 std::get<1>(tebuffer_) = 0;
0258 std::get<2>(tebuffer_) = std::get<3>(tebuffer_);
0259
0260
0261 for (auto& teunit : teunits_) {
0262 teunit.reset();
0263 }
0264
0265 TEData tedata;
0266 TEData tedata__;
0267 TEData tedata___;
0268 bool goodtedata = false;
0269 bool goodtedata__ = false;
0270 bool goodtedata___ = false;
0271
0272 bool tebuffernearfull;
0273
0274 for (unsigned int istep = 0; istep < maxStep_; istep++) {
0275
0276
0277 if (print) {
0278 CircularBuffer<TEData>& tedatabuffer = std::get<0>(tebuffer_);
0279 unsigned int& istub = std::get<1>(tebuffer_);
0280 unsigned int& imem = std::get<2>(tebuffer_);
0281 cout << "istep=" << istep << " TEBuffer: " << istub << " " << imem << " " << tedatabuffer.rptr() << " "
0282 << tedatabuffer.wptr();
0283 int k = -1;
0284 for (auto& teunit : teunits_) {
0285 k++;
0286 cout << " [" << k << " " << teunit.rptr() << " " << teunit.wptr() << " " << teunit.idle() << "]";
0287 }
0288 cout << endl;
0289 }
0290
0291 CircularBuffer<TEData>& tedatabuffer = std::get<0>(tebuffer_);
0292 tebuffernearfull = tedatabuffer.nearfull();
0293
0294
0295
0296
0297
0298
0299 TrackletEngineUnit* teunitptr = nullptr;
0300
0301 for (auto& teunit : teunits_) {
0302 teunit.setNearFull();
0303 if (!teunit.empty()) {
0304 teunitptr = &teunit;
0305 }
0306 }
0307
0308 if (teunitptr != nullptr) {
0309 auto stubpair = teunitptr->read();
0310 stubpairs++;
0311
0312 if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) {
0313 edm::LogVerbatim("Tracklet") << "Will break on too many tracklets in " << getName();
0314 break;
0315 }
0316 const Stub* innerFPGAStub = stubpair.first;
0317 const L1TStub* innerStub = innerFPGAStub->l1tstub();
0318
0319 const Stub* outerFPGAStub = stubpair.second;
0320 const L1TStub* outerStub = outerFPGAStub->l1tstub();
0321
0322 if (settings_.debugTracklet()) {
0323 edm::LogVerbatim("Tracklet") << "TrackletProcessor execute " << getName() << "[" << iSector_ << "]";
0324 }
0325
0326 bool accept = false;
0327
0328 if (iSeed_ == Seed::L1L2 || iSeed_ == Seed::L2L3 || iSeed_ == Seed::L3L4 || iSeed_ == Seed::L5L6) {
0329 accept = barrelSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub);
0330 } else if (iSeed_ == Seed::D1D2 || iSeed_ == Seed::D3D4) {
0331 accept = diskSeeding(innerFPGAStub, innerStub, outerFPGAStub, outerStub);
0332 } else {
0333 accept = overlapSeeding(outerFPGAStub, outerStub, innerFPGAStub, innerStub);
0334 }
0335
0336 if (accept)
0337 countsel++;
0338
0339 if (trackletpars_->nTracklets() >= settings_.ntrackletmax()) {
0340 edm::LogVerbatim("Tracklet") << "Will break on number of tracklets in " << getName();
0341 assert(0);
0342 break;
0343 }
0344
0345 if (settings_.debugTracklet()) {
0346 edm::LogVerbatim("Tracklet") << "TrackletProcessor execute done";
0347 }
0348 }
0349
0350
0351
0352
0353
0354
0355 bool notemptytebuffer = !tedatabuffer.empty();
0356
0357 int ite = -1;
0358 for (auto& teunit : teunits_) {
0359 ite++;
0360 if (teunit.idle()) {
0361 if (notemptytebuffer) {
0362 teunit.init(std::get<0>(tebuffer_).read());
0363 notemptytebuffer = false;
0364 }
0365 }
0366 teunit.step(print, istep, ite);
0367 }
0368
0369
0370
0371
0372
0373
0374 if (goodtedata___)
0375 tedatabuffer.store(tedata___);
0376
0377 goodtedata = false;
0378
0379 unsigned int& istub = std::get<1>(tebuffer_);
0380 unsigned int& imem = std::get<2>(tebuffer_);
0381 unsigned int imemend = std::get<4>(tebuffer_);
0382
0383 if ((!tebuffernearfull) && imem < imemend && istub < innerallstubs_[imem]->nStubs()) {
0384 ninnerstubs++;
0385
0386 const Stub* stub = innerallstubs_[imem]->getStub(istub);
0387
0388 if (settings_.debugTracklet()) {
0389 edm::LogVerbatim("Tracklet") << getName() << " Have stub in " << innerallstubs_[imem]->getName();
0390 }
0391
0392 bool negdisk = (stub->disk().value() < 0);
0393
0394 FPGAWord phicorr = stub->phicorr();
0395 int innerfinephi = phicorr.bits(phicorr.nbits() - nbitsfinephi_, nbitsfinephi_);
0396 FPGAWord innerbend = stub->bend();
0397
0398
0399 int indexz = (stub->z().value() >> (stub->z().nbits() - nbitszfinebintable_)) & ((1 << nbitszfinebintable_) - 1);
0400 int indexr = -1;
0401 if (layerdisk1_ > (N_LAYER - 1)) {
0402 if (negdisk) {
0403 indexz = ((1 << nbitszfinebintable_) - 1) - indexz;
0404 }
0405 indexr = stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_);
0406 } else {
0407 indexr = (stub->r().value() >> (stub->r().nbits() - nbitsrfinebintable_)) & ((1 << nbitsrfinebintable_) - 1);
0408 }
0409
0410 int lutval = -1;
0411 if (iSeed_ < 6) {
0412 lutval = innerTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0413 } else {
0414 lutval = innerOverlapTable_.lookup((indexz << nbitsrfinebintable_) + indexr);
0415 }
0416
0417 if (lutval != -1) {
0418 unsigned int lutwidth = settings_.lutwidthtab(0, iSeed_);
0419 FPGAWord lookupbits(lutval, lutwidth, true, __LINE__, __FILE__);
0420
0421 int rzfinebinfirst = lookupbits.bits(0, NFINERZBITS);
0422 int next = lookupbits.bits(NFINERZBITS, 1);
0423 int start = lookupbits.bits(NFINERZBITS + 1, nbitsrzbin_);
0424 int rzdiffmax = lookupbits.bits(NFINERZBITS + 1 + nbitsrzbin_, NFINERZBITS);
0425
0426 if ((iSeed_ == Seed::D1D2 || iSeed_ == Seed::D3D4) && negdisk) {
0427 start += (1 << nbitsrzbin_);
0428 }
0429 int last = start + next;
0430
0431 int nbins = (1 << N_RZBITS);
0432
0433 unsigned int useregindex = (innerfinephi << innerbend.nbits()) + innerbend.value();
0434 if (iSeed_ == Seed::D1D2 || iSeed_ == Seed::D3D4 || iSeed_ == Seed::L1D1 || iSeed_ == Seed::L2D1) {
0435
0436 unsigned int nrbits = 3;
0437 int ir = ((start & ((1 << (nrbits - 1)) - 1)) << 1) + (rzfinebinfirst >> (NFINERZBITS - 1));
0438 useregindex = (useregindex << nrbits) + ir;
0439 }
0440
0441 unsigned int usereg = useregiontable_.lookup(useregindex);
0442
0443 tedata.regions_.clear();
0444 tedata.stub_ = stub;
0445 tedata.rzbinfirst_ = rzfinebinfirst;
0446 tedata.start_ = start;
0447 tedata.innerfinephi_ = innerfinephi;
0448 tedata.rzdiffmax_ = rzdiffmax;
0449 tedata.innerbend_ = innerbend;
0450
0451 std::string mask = "";
0452
0453 for (int ibin = start; ibin <= last; ibin++) {
0454 for (unsigned int ireg = 0; ireg < settings_.nvmte(1, iSeed_); ireg++) {
0455 if (!(usereg & (1 << ireg))) {
0456 mask = "0" + mask;
0457 continue;
0458 }
0459
0460 if (settings_.debugTracklet()) {
0461 edm::LogVerbatim("Tracklet") << getName() << " looking for matching stub in bin " << ibin << " with "
0462 << outervmstubs_->nVMStubsBinned(ireg * nbins + ibin) << " stubs";
0463 }
0464 assert(ireg * nbins + ibin < outervmstubs_->nBin());
0465 int nstubs = outervmstubs_->nVMStubsBinned(ireg * nbins + ibin);
0466
0467 if (nstubs > 0) {
0468 mask = "1" + mask;
0469 tedata.regions_.emplace_back(tuple<int, int, int>(ibin - start, ireg, nstubs));
0470 countteall += nstubs;
0471 } else {
0472 mask = "0" + mask;
0473 }
0474 }
0475 }
0476
0477 if (!tedata.regions_.empty()) {
0478 goodtedata = true;
0479 }
0480 }
0481 istub++;
0482 if (istub >= innerallstubs_[imem]->nStubs()) {
0483 istub = 0;
0484 imem++;
0485 }
0486 } else if ((!tebuffernearfull) && imem < imemend && istub == 0) {
0487 imem++;
0488 }
0489
0490 goodtedata___ = goodtedata__;
0491 goodtedata__ = goodtedata;
0492
0493 tedata___ = tedata__;
0494 tedata__ = tedata;
0495
0496
0497
0498
0499
0500 bool done = true;
0501
0502 if (imem < imemend || (!tedatabuffer.empty())) {
0503 done = false;
0504 }
0505
0506 for (auto& teunit : teunits_) {
0507 if (!(teunit.idle() && teunit.empty()))
0508 done = false;
0509 }
0510
0511 if (done) {
0512 donecount++;
0513 }
0514
0515
0516 if (donecount > 4) {
0517 break;
0518 }
0519 }
0520
0521
0522
0523
0524
0525 if (settings_.writeMonitorData("TP")) {
0526 globals_->ofstream("trackletprocessor.txt") << getName() << " " << ninnerstubs
0527 << " " << outervmstubs_->nVMStubs()
0528 << " " << countteall
0529 << " " << stubpairs
0530 << " " << countsel
0531 << endl;
0532 }
0533 }