Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-26 23:26:58

0001 #include "L1Trigger/L1TMuonEndCap/interface/PtAssignment.h"
0002 
0003 #include "L1Trigger/L1TMuonEndCap/interface/PtAssignmentEngine.h"
0004 #include "L1Trigger/L1TMuonEndCap/interface/PtAssignmentEngineDxy.h"
0005 
0006 void PtAssignment::configure(PtAssignmentEngine* pt_assign_engine,
0007                              PtAssignmentEngineDxy* pt_assign_engine_dxy,
0008                              int verbose,
0009                              int endcap,
0010                              int sector,
0011                              int bx,
0012                              bool readPtLUTFile,
0013                              bool fixMode15HighPt,
0014                              bool bug9BitDPhi,
0015                              bool bugMode7CLCT,
0016                              bool bugNegPt,
0017                              bool bugGMTPhi,
0018                              bool promoteMode7,
0019                              int modeQualVer,
0020                              std::vector<int> promoteMode7Sectors,
0021                              std::string pbFileName) {
0022   emtf_assert(pt_assign_engine != nullptr);
0023   emtf_assert(pt_assign_engine_dxy != nullptr);
0024 
0025   pt_assign_engine_ = pt_assign_engine;
0026 
0027   pt_assign_engine_dxy_ = pt_assign_engine_dxy;
0028 
0029   verbose_ = verbose;
0030   endcap_ = endcap;
0031   sector_ = sector;
0032   bx_ = bx;
0033 
0034   pt_assign_engine_->configure(verbose_, readPtLUTFile, fixMode15HighPt, bug9BitDPhi, bugMode7CLCT, bugNegPt);
0035 
0036   pt_assign_engine_dxy_->configure(verbose_, pbFileName);
0037 
0038   bugGMTPhi_ = bugGMTPhi;
0039   promoteMode7_ = promoteMode7;
0040   modeQualVer_ = modeQualVer;
0041   promoteMode7Sectors_ = promoteMode7Sectors;
0042 
0043   int es = endcap_ == 1 ? sector_ : -1 * sector_;  // Endcap sign and sector number
0044 
0045   if (promoteMode7_ &&
0046       (promoteMode7Sectors_.at(0) == -1 ||
0047        std::find(promoteMode7Sectors_.begin(), promoteMode7Sectors_.end(), es) != promoteMode7Sectors_.end())) {
0048     promoteMode7_ = true;  // Assign station 2-3-4 tracks with |eta| > 1.6 SingleMu quality in a given sector
0049   } else {
0050     promoteMode7_ = false;  // Do not promote mode 7 tracks of other sectors
0051   }
0052 }
0053 
0054 void PtAssignment::process(EMTFTrackCollection& best_tracks) {
0055   using address_t = PtAssignmentEngine::address_t;
0056 
0057   EMTFTrackCollection::iterator best_tracks_it = best_tracks.begin();
0058   EMTFTrackCollection::iterator best_tracks_end = best_tracks.end();
0059 
0060   for (; best_tracks_it != best_tracks_end; ++best_tracks_it) {
0061     EMTFTrack& track = *best_tracks_it;  // pass by reference
0062 
0063     // Assign GMT eta and phi
0064     int gmt_phi = aux().getGMTPhi(track.Phi_fp());
0065 
0066     if (!bugGMTPhi_) {
0067       gmt_phi = aux().getGMTPhiV2(track.Phi_fp());
0068     }
0069 
0070     int gmt_eta = aux().getGMTEta(track.Theta_fp(), track.Endcap());  // Convert to integer eta using FW LUT
0071 
0072     // Notes from Alex (2016-09-28):
0073     //
0074     //     When using two's complement, you get two eta bins with zero coordinate.
0075     // This peculiarity is created because positive and negative endcaps are
0076     // processed by separate processors, so each of them gets its own zero bin.
0077     // With simple inversion, the eta scale becomes uniform, one bin for one
0078     // eta value.
0079     bool use_ones_complem_gmt_eta = true;
0080     if (use_ones_complem_gmt_eta) {
0081       gmt_eta = (gmt_eta < 0) ? ~(-gmt_eta) : gmt_eta;
0082     }
0083 
0084     // Assign prompt & displaced pT
0085     address_t address = 0;
0086     float xmlpt = 0.;
0087     float pt = 0.;
0088     int gmt_pt = 0;
0089 
0090     float pt_dxy = 0.;
0091     float dxy = 0.;
0092     int gmt_pt_dxy = 0;
0093     int gmt_dxy = 0;
0094 
0095     if (track.Mode() != 1) {
0096       address = pt_assign_engine_->calculate_address(track);
0097       xmlpt = pt_assign_engine_->calculate_pt(address);
0098 
0099       // Check address packing / unpacking using PtAssignmentEngine2017::calculate_pt_xml(const EMTFTrack& track)
0100       if (pt_assign_engine_->get_pt_lut_version() > 5 &&
0101           not(fabs(xmlpt - pt_assign_engine_->calculate_pt(track)) < 0.001)) {
0102         edm::LogError("L1T") << "EMTF pT assignment mismatch: xmlpt = " << xmlpt
0103                              << ", pt_assign_engine_->calculate_pt(track)) = "
0104                              << pt_assign_engine_->calculate_pt(track);
0105       }
0106 
0107       pt = (xmlpt < 0.) ? 1. : xmlpt;  // Matt used fabs(-1) when mode is invalid
0108       pt *= pt_assign_engine_->scale_pt(
0109           pt, track.Mode());  // Multiply by some factor to achieve 90% efficiency at threshold
0110 
0111       gmt_pt = aux().getGMTPt(pt);  // Encode integer pT in GMT format
0112     }  // End if (track.Mode() != 1)
0113     else {
0114       gmt_pt = 10 - (abs(gmt_eta) / 32);
0115     }
0116 
0117     pt = (gmt_pt <= 0) ? 0 : (gmt_pt - 1) * 0.5;  // Decode integer pT (result is in 0.5 GeV step)
0118 
0119     // Calculate displaced pT and d0 using NN
0120     emtf::Feature feature;
0121     emtf::Prediction prediction;
0122 
0123     feature.fill(0);
0124     prediction.fill(0);
0125 
0126     pt_assign_engine_dxy_->calculate_pt_dxy(track, feature, prediction);
0127 
0128     pt_dxy = std::abs(prediction.at(0));
0129     dxy = prediction.at(1);
0130 
0131     gmt_pt_dxy = aux().getGMTPtDxy(pt_dxy);
0132     gmt_dxy = aux().getGMTDxy(dxy);
0133 
0134     pt_dxy = aux().getPtFromGMTPtDxy(gmt_pt_dxy);
0135 
0136     int gmt_quality = 0;
0137     if (track.Mode() != 1) {
0138       gmt_quality = aux().getGMTQuality(track.Mode(), track.Theta_fp(), promoteMode7_, modeQualVer_);
0139     } else {  // Special quality for single-hit tracks from ME1/1
0140       gmt_quality = track.Hits().front().Pattern() / 4;
0141     }
0142 
0143     std::pair<int, int> gmt_charge = std::make_pair(0, 0);
0144     if (track.Mode() != 1) {
0145       std::vector<int> phidiffs;
0146       for (int i = 0; i < emtf::NUM_STATION_PAIRS; ++i) {
0147         int phidiff = (track.PtLUT().sign_ph[i] == 1) ? track.PtLUT().delta_ph[i] : -track.PtLUT().delta_ph[i];
0148         phidiffs.push_back(phidiff);
0149       }
0150       gmt_charge = aux().getGMTCharge(track.Mode(), phidiffs);
0151     } else {  // Special charge assignment for single-hit tracks from ME1/1
0152       int CLCT = track.Hits().front().Pattern();
0153       if (CLCT != 10) {
0154         if (endcap_ == 1)
0155           gmt_charge = std::make_pair((CLCT % 2) == 0 ? 0 : 1, 1);
0156         else
0157           gmt_charge = std::make_pair((CLCT % 2) == 0 ? 1 : 0, 1);
0158       }
0159     }
0160 
0161     // _________________________________________________________________________
0162     // Output
0163 
0164     EMTFPtLUT tmp_LUT = track.PtLUT();
0165     tmp_LUT.address = address;
0166 
0167     track.set_PtLUT(tmp_LUT);
0168     track.set_pt_XML(xmlpt);
0169     track.set_pt(pt);
0170     track.set_pt_dxy(pt_dxy);
0171     track.set_dxy(dxy);
0172     track.set_charge((gmt_charge.second == 1) ? ((gmt_charge.first == 1) ? -1 : +1) : 0);
0173 
0174     track.set_gmt_pt(gmt_pt);
0175     track.set_gmt_pt_dxy(gmt_pt_dxy);
0176     track.set_gmt_dxy(gmt_dxy);
0177     track.set_gmt_phi(gmt_phi);
0178     track.set_gmt_eta(gmt_eta);
0179     track.set_gmt_quality(gmt_quality);
0180     track.set_gmt_charge(gmt_charge.first);
0181     track.set_gmt_charge_valid(gmt_charge.second);
0182   }
0183 
0184   // Remove worst track if it addresses the same bank as one of two best tracks
0185   bool disable_worst_track_in_same_bank = true;
0186   if (disable_worst_track_in_same_bank) {
0187     // FW macro for detecting same bank address
0188     // bank and chip must match, and valid flags must be set
0189     // a and b are indexes 0,1,2
0190     // `define sb(a,b) (ptlut_addr[a][29:26] == ptlut_addr[b][29:26] && ptlut_addr[a][5:2] == ptlut_addr[b][5:2] && ptlut_addr_val[a] && ptlut_addr_val[b])
0191     auto is_in_same_bank = [](const EMTFTrack& lhs, const EMTFTrack& rhs) {
0192       unsigned lhs_addr = lhs.PtLUT().address;
0193       unsigned rhs_addr = rhs.PtLUT().address;
0194       unsigned lhs_addr_1 = (lhs_addr >> 26) & 0xF;
0195       unsigned rhs_addr_1 = (rhs_addr >> 26) & 0xF;
0196       unsigned lhs_addr_2 = (lhs_addr >> 2) & 0xF;
0197       unsigned rhs_addr_2 = (rhs_addr >> 2) & 0xF;
0198       return (lhs_addr_1 == rhs_addr_1) && (lhs_addr_2 == rhs_addr_2);
0199     };
0200 
0201     emtf_assert(best_tracks.size() <= 3);
0202     if (best_tracks.size() == 3) {
0203       bool same_bank = is_in_same_bank(best_tracks.at(0), best_tracks.at(2)) ||
0204                        is_in_same_bank(best_tracks.at(1), best_tracks.at(2));
0205       if (same_bank) {
0206         // Set worst track pT to zero
0207         best_tracks.at(2).set_pt(0);
0208         best_tracks.at(2).set_gmt_pt(0);
0209       }
0210     }
0211   }
0212 
0213   if (verbose_ > 0) {  // debug
0214     for (const auto& track : best_tracks) {
0215       std::cout << "track: " << track.Winner() << " pt address: " << track.PtLUT().address
0216                 << " GMT pt: " << track.GMT_pt() << " pt: " << track.Pt() << " mode: " << track.Mode()
0217                 << " GMT charge: " << track.GMT_charge() << " quality: " << track.GMT_quality()
0218                 << " eta: " << track.GMT_eta() << " phi: " << track.GMT_phi() << std::endl;
0219     }
0220   }
0221 }
0222 
0223 const PtAssignmentEngineAux& PtAssignment::aux() const { return pt_assign_engine_->aux(); }