Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-16 02:43:04

0001 #include "L1Trigger/Phase2L1GMT/interface/KMTF.h"
0002 using namespace Phase2L1GMT;
0003 
0004 KMTF::KMTF(int verbose, const edm::ParameterSet& iConfig)
0005     : verbose_(verbose), trackMaker_(std::make_unique<KMTFCore>(iConfig)) {}
0006 
0007 KMTF::~KMTF() = default;
0008 
0009 std::pair<std::vector<l1t::KMTFTrack>, std::vector<l1t::KMTFTrack> > KMTF::process(
0010     const l1t::MuonStubRefVector& stubsAll, int bx, unsigned int MAXN) {
0011   std::vector<l1t::KMTFTrack> pretracksP2;
0012   std::vector<l1t::KMTFTrack> pretracksP3;
0013   std::vector<l1t::KMTFTrack> pretracksP4;
0014   std::vector<l1t::KMTFTrack> pretracksD2;
0015   std::vector<l1t::KMTFTrack> pretracksD3;
0016   std::vector<l1t::KMTFTrack> pretracksD4;
0017   uint Nstubs4 = 0;
0018   uint Nstubs3 = 0;
0019   uint Nstubs2 = 0;
0020   uint Nstubs1 = 0;
0021 
0022   l1t::MuonStubRefVector stubs4;
0023   l1t::MuonStubRefVector stubs3;
0024   l1t::MuonStubRefVector stubs2;
0025   l1t::MuonStubRefVector stubs1;
0026 
0027   for (const auto& stub : stubsAll) {
0028     if (stub->bxNum() != bx || stub->id() > 3)
0029       continue;
0030     if (!stub->isBarrel())
0031       continue;
0032 
0033     if (stub->depthRegion() == 4) {
0034       if (Nstubs4 < MAXN) {
0035         stubs4.push_back(stub);
0036         Nstubs4++;
0037       }
0038     }
0039     if (stub->depthRegion() == 3) {
0040       if (Nstubs3 < MAXN) {
0041         stubs3.push_back(stub);
0042         Nstubs3++;
0043       }
0044     }
0045     if (stub->depthRegion() == 2) {
0046       if (Nstubs2 < MAXN) {
0047         stubs2.push_back(stub);
0048         Nstubs2++;
0049       }
0050     }
0051     if (stub->depthRegion() == 1) {
0052       if (Nstubs1 < MAXN) {
0053         stubs1.push_back(stub);
0054         Nstubs1++;
0055       }
0056     }
0057   }
0058 
0059   //Sort the seeds by tag so that the emulator is aligned like the firmware
0060   SeedSorter sorter;
0061   if (stubs4.size() > 1) {
0062     std::sort(stubs4.begin(), stubs4.end(), sorter);
0063   }
0064   if (stubs3.size() > 1) {
0065     std::sort(stubs3.begin(), stubs3.end(), sorter);
0066   }
0067   if (stubs2.size() > 1) {
0068     std::sort(stubs2.begin(), stubs2.end(), sorter);
0069   }
0070   if (stubs1.size() > 1) {
0071     std::sort(stubs1.begin(), stubs1.end(), sorter);
0072   }
0073 
0074   bool pre_patterns = (verbose_ > 1) && ((Nstubs4 + Nstubs3 + Nstubs2 + Nstubs1) > 2);
0075 
0076   //OK now process the data almost as in hardware
0077   for (unsigned int i = 0; i < 32; ++i) {
0078     //print the stubs taking into account
0079 
0080     bool patterns = pre_patterns && ((i < Nstubs4) || (i < Nstubs3) || (i << Nstubs2));
0081 
0082     if (patterns) {
0083       edm::LogInfo("KMTF") << "KMTFPattern " << std::flush;
0084       if (i < Nstubs4)
0085         edm::LogInfo("KMTF") << stubs4[0]->coord1() << " " << stubs4[0]->coord2() << " " << stubs4[0]->quality() << " "
0086                              << " 1 " << stubs4[0]->kmtf_address() << " 0 " << std::flush;
0087       else
0088         edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush;
0089 
0090       if (i < Nstubs3) {
0091         for (const auto& s : stubs3) {
0092           edm::LogInfo("KMTF") << "" << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 "
0093                                << s->kmtf_address() << " 0 " << std::flush;
0094         }
0095         //pad with zeros
0096         for (unsigned int j = stubs3.size(); j < 32; ++j) {
0097           edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush;
0098         }
0099       } else {
0100         for (unsigned int j = stubs3.size(); j < 32; ++j) {
0101           edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush;
0102         }
0103         for (const auto& s : stubs3) {
0104           edm::LogInfo("KMTF") << "" << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 "
0105                                << s->kmtf_address() << " 0 " << std::flush;
0106         }
0107       }
0108 
0109       if (i < Nstubs2) {
0110         for (const auto& s : stubs2) {
0111           edm::LogInfo("KMTF") << "" << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 "
0112                                << s->kmtf_address() << " 0 " << std::flush;
0113         }
0114         //pad with zeros
0115         for (unsigned int j = stubs2.size(); j < 32; ++j) {
0116           edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush;
0117         }
0118       } else {
0119         for (unsigned int j = stubs2.size(); j < 32; ++j) {
0120           edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush;
0121         }
0122         for (const auto& s : stubs2) {
0123           edm::LogInfo("KMTF") << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " << s->kmtf_address()
0124                                << " 0 " << std::flush;
0125         }
0126       }
0127       if (i < Nstubs1) {
0128         for (const auto& s : stubs1) {
0129           edm::LogInfo("KMTF") << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " << s->kmtf_address()
0130                                << " 0 " << std::flush;
0131         }
0132         //pad with zeros
0133         for (unsigned int j = stubs1.size(); j < 32; ++j) {
0134           edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush;
0135         }
0136       } else {
0137         for (unsigned int j = stubs1.size(); j < 32; ++j) {
0138           edm::LogInfo("KMTF") << "0 0 0 0 511 0 " << std::flush;
0139         }
0140         for (const auto& s : stubs1) {
0141           edm::LogInfo("KMTF") << s->coord1() << " " << s->coord2() << " " << s->quality() << " 1 " << s->kmtf_address()
0142                                << " 0 " << std::flush;
0143         }
0144       }
0145     }
0146 
0147     //seed is 4
0148     if (i < Nstubs4) {
0149       l1t::MuonStubRefVector stubs_proc;
0150       if (Nstubs3 > 0)
0151         stubs_proc.insert(stubs_proc.end(), stubs3.begin(), stubs3.end());
0152       if (Nstubs2 > 0)
0153         stubs_proc.insert(stubs_proc.end(), stubs2.begin(), stubs2.end());
0154       if (Nstubs1 > 0)
0155         stubs_proc.insert(stubs_proc.end(), stubs1.begin(), stubs1.end());
0156       std::pair<l1t::KMTFTrack, l1t::KMTFTrack> tracks = trackMaker_->chain(stubs4[0], stubs_proc);
0157       if (tracks.first.id() & 0x1)
0158         pretracksP4.push_back(tracks.first);
0159       if (tracks.second.id() & 0x2)
0160         pretracksD4.push_back(tracks.second);
0161       if (patterns) {
0162         if (tracks.first.id() & 0x1)
0163           edm::LogInfo("KMTF") << "1 " << (tracks.first.curvatureAtVertex() < 0 ? 1 : 0) << " "
0164                                << tracks.first.ptPrompt() << " " << tracks.first.phiAtMuon() / (1 << 5) << " "
0165                                << tracks.first.coarseEta() << " " << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606))
0166                                << " " << tracks.first.rankPrompt() << " " << std::flush;
0167 
0168         else
0169           edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0170         if (tracks.second.id() & 0x2)
0171           edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtVertex() < 0 ? 1 : 0) << " "
0172                                << tracks.second.ptDisplaced() << " " << tracks.second.phiAtMuon() / (1 << 5) << " "
0173                                << tracks.second.coarseEta() << " " << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606))
0174                                << " " << tracks.second.rankDisp() << " " << std::flush;
0175 
0176         else
0177           edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0178       }
0179     } else if (patterns) {
0180       edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0181       edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0182     }
0183 
0184     if (i < Nstubs3) {
0185       l1t::MuonStubRefVector stubs_proc;
0186       if (Nstubs2 > 0)
0187         stubs_proc.insert(stubs_proc.end(), stubs2.begin(), stubs2.end());
0188       if (Nstubs1 > 0)
0189         stubs_proc.insert(stubs_proc.end(), stubs1.begin(), stubs1.end());
0190       std::pair<l1t::KMTFTrack, l1t::KMTFTrack> tracks = trackMaker_->chain(stubs3[0], stubs_proc);
0191       if (tracks.first.id() & 0x1)
0192         pretracksP3.push_back(tracks.first);
0193       if (tracks.second.id() & 0x2)
0194         pretracksD3.push_back(tracks.second);
0195       if (patterns) {
0196         if (tracks.first.id() & 0x1)
0197           edm::LogInfo("KMTF") << "1 " << (tracks.first.curvatureAtVertex() < 0 ? 1 : 0) << " "
0198                                << tracks.first.ptPrompt() << " " << tracks.first.phiAtMuon() / (1 << 5) << " "
0199                                << tracks.first.coarseEta() << " " << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606))
0200                                << " " << tracks.first.rankPrompt() << " " << std::flush;
0201 
0202         else
0203           edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0204         if (tracks.second.id() & 0x2)
0205           edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtVertex() < 0 ? 1 : 0) << " "
0206                                << tracks.second.ptDisplaced() << " " << tracks.second.phiAtMuon() / (1 << 5) << " "
0207                                << tracks.second.coarseEta() << " " << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606))
0208                                << " " << tracks.second.rankDisp() << " " << std::flush;
0209 
0210         else
0211           edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0212       }
0213     } else if (patterns) {
0214       edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0215       edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0216     }
0217     if (i < Nstubs2) {
0218       l1t::MuonStubRefVector stubs_proc;
0219       if (Nstubs1 > 0)
0220         stubs_proc.insert(stubs_proc.end(), stubs1.begin(), stubs1.end());
0221       std::pair<l1t::KMTFTrack, l1t::KMTFTrack> tracks = trackMaker_->chain(stubs2[0], stubs_proc);
0222       if (tracks.first.id() & 0x1)
0223         pretracksP2.push_back(tracks.first);
0224       if (tracks.second.id() & 0x2)
0225         pretracksD2.push_back(tracks.second);
0226       if (patterns) {
0227         if (tracks.first.id() & 0x1)
0228           edm::LogInfo("KMTF") << "1 " << (tracks.first.curvatureAtVertex() < 0 ? 1 : 0) << " "
0229                                << tracks.first.ptPrompt() << " " << tracks.first.phiAtMuon() / (1 << 5) << " "
0230                                << tracks.first.coarseEta() << " " << int(tracks.first.dxy() * ap_ufixed<8, 1>(1.606))
0231                                << " " << tracks.first.rankPrompt() << " " << std::flush;
0232 
0233         else
0234           edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0235         if (tracks.second.id() & 0x2)
0236           edm::LogInfo("KMTF") << "1 " << (tracks.second.curvatureAtVertex() < 0 ? 1 : 0) << " "
0237                                << tracks.second.ptDisplaced() << " " << tracks.second.phiAtMuon() / (1 << 5) << " "
0238                                << tracks.second.coarseEta() << " " << int(tracks.second.dxy() * ap_ufixed<8, 1>(1.606))
0239                                << " " << tracks.second.rankDisp();
0240         else
0241           edm::LogInfo("KMTF") << "0 0 0 0 0 0 0" << std::flush;
0242       }
0243     } else if (patterns) {
0244       edm::LogInfo("KMTF") << "0 0 0 0 0 0 0 " << std::flush;
0245       edm::LogInfo("KMTF") << "0 0 0 0 0 0 0";
0246     }
0247     //Now the shift register emulation in C_++
0248     if (stubs4.size() > 1) {
0249       l1t::MuonStubRef s4 = stubs4[0];
0250       stubs4.erase(stubs4.begin(), stubs4.begin() + 1);
0251       stubs4.push_back(s4);
0252     }
0253     if (stubs3.size() > 1) {
0254       l1t::MuonStubRef s3 = stubs3[0];
0255       stubs3.erase(stubs3.begin(), stubs3.begin() + 1);
0256       stubs3.push_back(s3);
0257     }
0258     if (stubs2.size() > 1) {
0259       l1t::MuonStubRef s2 = stubs2[0];
0260       stubs2.erase(stubs2.begin(), stubs2.begin() + 1);
0261       stubs2.push_back(s2);
0262     }
0263     if (stubs1.size() > 1) {
0264       l1t::MuonStubRef s1 = stubs1[0];
0265       stubs1.erase(stubs1.begin(), stubs1.begin() + 1);
0266       stubs1.push_back(s1);
0267     }
0268   }
0269 
0270   std::vector<l1t::KMTFTrack> cleanedPrompt = cleanRegion(pretracksP2, pretracksP3, pretracksP4, true);
0271   std::vector<l1t::KMTFTrack> cleanedDisp = cleanRegion(pretracksD2, pretracksD3, pretracksD4, false);
0272   if (verbose_) {
0273     edm::LogInfo("KMTF") << "Prompt pretracks 2=" << int(pretracksP2.size()) << " 3=" << int(pretracksP3.size())
0274                          << " 4=" << int(pretracksP4.size());
0275     edm::LogInfo("KMTF") << "Cleaned Tracks Prompt=" << (int)cleanedPrompt.size()
0276                          << " Displaced=" << (int)cleanedDisp.size();
0277   }
0278 
0279   if (verbose_ && !cleanedPrompt.empty())
0280     for (const auto& t : cleanedPrompt)
0281       if (t.id() != 0)
0282         edm::LogInfo("KMTF") << "final cleaned sector track from all chains  track pt=" << t.ptPrompt()
0283                              << " pattern=" << t.hitPattern() << " rank=" << t.rankPrompt();
0284 
0285   sort(cleanedPrompt, true);
0286   sort(cleanedDisp, false);
0287 
0288   if (verbose_ && !cleanedPrompt.empty())
0289     for (const auto& t : cleanedPrompt)
0290       if (t.id() != 0)
0291         edm::LogInfo("KMTF") << "final sorted sector track from all chains  track pt=" << t.ptPrompt()
0292                              << " pattern=" << t.hitPattern() << " rank=" << t.rankPrompt();
0293 
0294   return std::make_pair(cleanedPrompt, cleanedDisp);
0295 }
0296 
0297 void KMTF::overlapCleanTrack(l1t::KMTFTrack& source, const l1t::KMTFTrack& other, bool eq, bool vertex) {
0298   int rank1 = vertex ? source.rankPrompt() : source.rankDisp();
0299   int rank2 = vertex ? other.rankPrompt() : other.rankDisp();
0300   int id1 = vertex ? source.id() & 0x1 : source.id() & 0x2;
0301   int id2 = vertex ? other.id() & 0x1 : other.id() & 0x2;
0302   bool keep = true;
0303   unsigned int pattern = 0;
0304   if (id1 == 0)
0305     keep = false;
0306   else if (id1 != 0 && id2 != 0) {
0307     if (eq && rank1 <= rank2)
0308       keep = false;
0309     if ((!eq) && rank1 < rank2)
0310       keep = false;
0311   }
0312 
0313   l1t::MuonStubRefVector stubs;
0314   for (const auto& s1 : source.stubs()) {
0315     bool ok = true;
0316     for (const auto& s2 : other.stubs()) {
0317       if ((*s1) == (*s2) && (!keep))
0318         ok = false;
0319     }
0320     if (ok) {
0321       stubs.push_back(s1);
0322       pattern = pattern | (1 << (s1->depthRegion() - 1));
0323     }
0324   }
0325   source.setStubs(stubs);
0326   source.setHitPattern(pattern);
0327 }
0328 
0329 std::vector<l1t::KMTFTrack> KMTF::cleanRegion(const std::vector<l1t::KMTFTrack>& tracks2,
0330                                               const std::vector<l1t::KMTFTrack>& tracks3,
0331                                               const std::vector<l1t::KMTFTrack>& tracks4,
0332                                               bool vertex) {
0333   std::vector<l1t::KMTFTrack> cleaned2;
0334   for (unsigned int i = 0; i < tracks2.size(); ++i) {
0335     l1t::KMTFTrack source = tracks2[i];
0336 
0337     for (unsigned int j = 0; j < tracks2.size(); ++j) {
0338       if (i == j)
0339         continue;
0340       overlapCleanTrack(source, tracks2[j], false, vertex);
0341     }
0342     for (unsigned int j = 0; j < tracks3.size(); ++j) {
0343       overlapCleanTrack(source, tracks3[j], true, vertex);
0344     }
0345     for (unsigned int j = 0; j < tracks4.size(); ++j) {
0346       overlapCleanTrack(source, tracks4[j], true, vertex);
0347     }
0348 
0349     if (source.stubs().size() > 1)
0350       cleaned2.push_back(source);
0351   }
0352 
0353   std::vector<l1t::KMTFTrack> cleaned3;
0354   for (unsigned int i = 0; i < tracks3.size(); ++i) {
0355     l1t::KMTFTrack source = tracks3[i];
0356 
0357     for (unsigned int j = 0; j < tracks3.size(); ++j) {
0358       if (i == j)
0359         continue;
0360       overlapCleanTrack(source, tracks3[j], false, vertex);
0361     }
0362     for (unsigned int j = 0; j < tracks2.size(); ++j) {
0363       overlapCleanTrack(source, tracks2[j], false, vertex);
0364     }
0365     for (unsigned int j = 0; j < tracks4.size(); ++j) {
0366       overlapCleanTrack(source, tracks4[j], true, vertex);
0367     }
0368 
0369     if (source.stubs().size() > 1)
0370       cleaned3.push_back(source);
0371   }
0372 
0373   std::vector<l1t::KMTFTrack> cleaned4;
0374   for (unsigned int i = 0; i < tracks4.size(); ++i) {
0375     l1t::KMTFTrack source = tracks4[i];
0376 
0377     for (unsigned int j = 0; j < tracks4.size(); ++j) {
0378       if (i == j)
0379         continue;
0380       overlapCleanTrack(source, tracks4[j], false, vertex);
0381     }
0382     for (unsigned int j = 0; j < tracks3.size(); ++j) {
0383       overlapCleanTrack(source, tracks3[j], false, vertex);
0384     }
0385     for (unsigned int j = 0; j < tracks2.size(); ++j) {
0386       overlapCleanTrack(source, tracks2[j], false, vertex);
0387     }
0388 
0389     if (source.stubs().size() > 1)
0390       cleaned4.push_back(source);
0391   }
0392   uint max234 = std::max(cleaned2.size(), std::max(cleaned3.size(), cleaned4.size()));
0393 
0394   std::vector<l1t::KMTFTrack> output;
0395 
0396   for (uint i = 0; i < max234; ++i) {
0397     if (i < cleaned2.size())
0398       output.push_back(cleaned2[i]);
0399     if (i < cleaned3.size())
0400       output.push_back(cleaned3[i]);
0401     if (i < cleaned4.size())
0402       output.push_back(cleaned4[i]);
0403   }
0404   return output;
0405 }
0406 
0407 void KMTF::swap(std::vector<l1t::KMTFTrack>& list, int i, int j, bool vertex) {
0408   const l1t::KMTFTrack& track1 = list[i];
0409   const l1t::KMTFTrack& track2 = list[j];
0410   int id1 = track1.id();
0411   int id2 = track2.id();
0412   int pt1 = vertex ? track1.ptPrompt() : track1.ptDisplaced();
0413   int pt2 = vertex ? track2.ptPrompt() : track2.ptDisplaced();
0414   bool swap = false;
0415   if (vertex) {
0416     id1 = id1 & 0x1;
0417     id2 = id2 & 0x1;
0418   } else {
0419     id1 = id1 & 0x2;
0420     id2 = id2 & 0x2;
0421   }
0422   if (id1 && (!id2))
0423     swap = false;
0424   else if ((!id1) && id2)
0425     swap = true;
0426   else if (id1 && id2) {
0427     if (pt1 > pt2)
0428       swap = false;
0429     else
0430       swap = true;
0431   } else {
0432     swap = false;
0433   }
0434   if (swap) {
0435     l1t::KMTFTrack tmp = list[i];
0436     list[i] = list[j];
0437     list[j] = tmp;
0438   }
0439 }
0440 
0441 void KMTF::sort(std::vector<l1t::KMTFTrack>& in, bool vertex) {
0442   l1t::KMTFTrack nullTrack;
0443   nullTrack.setPtEtaPhi(0, 0, 0);
0444   nullTrack.setIDFlag(false, false);
0445   nullTrack.setRank(0, vertex);
0446   while (in.size() < 32)
0447     in.push_back(nullTrack);
0448 
0449   for (uint iteration = 0; iteration < 16; ++iteration) {
0450     for (uint i = 0; i < 32; i = i + 2) {
0451       swap(in, i, i + 1, vertex);
0452     }
0453     for (uint i = 1; i < 31; i = i + 2) {
0454       swap(in, i, i + 1, vertex);
0455     }
0456   }
0457 
0458   std::vector<l1t::KMTFTrack> out;
0459   for (const auto& track : in) {
0460     if ((vertex && (track.id() & 0x1)) || ((!vertex) && (track.id() & 0x2)))
0461       out.push_back(track);
0462   }
0463   in = out;
0464 }