Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:20:57

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