Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:12:44

0001 #include "L1Trigger/L1TMuonEndCap/interface/PtAssignmentEngine2016.h"
0002 #include "L1Trigger/L1TMuonEndCap/interface/PtAssignmentEngineAux2016.h"
0003 
0004 #include <iostream>
0005 #include <sstream>
0006 
0007 const PtAssignmentEngineAux2016& PtAssignmentEngine2016::aux() const {
0008   static const PtAssignmentEngineAux2016 instance;
0009   return instance;
0010 }
0011 
0012 float PtAssignmentEngine2016::scale_pt(const float pt, const int mode) const {
0013   // Scaling to achieve 90% efficency at any given L1 pT threshold
0014   // For 2016, was a flat scaling factor of 1.4
0015   float pt_scale = 1.4;
0016   return pt_scale;
0017 }
0018 
0019 float PtAssignmentEngine2016::unscale_pt(const float pt, const int mode) const {
0020   float pt_unscale = 1. / 1.4;
0021   return pt_unscale;
0022 }
0023 
0024 PtAssignmentEngine::address_t PtAssignmentEngine2016::calculate_address(const EMTFTrack& track) const {
0025   address_t address = 0;
0026 
0027   const EMTFPtLUT& ptlut_data = track.PtLUT();
0028 
0029   int mode_inv = track.Mode_inv();
0030   int theta = track.Theta_fp();
0031   theta >>= 2;  // truncate from 7-bit to 5-bit
0032 
0033   int dPhi12 = ptlut_data.delta_ph[0];
0034   int dPhi13 = ptlut_data.delta_ph[1];
0035   int dPhi14 = ptlut_data.delta_ph[2];
0036   int dPhi23 = ptlut_data.delta_ph[3];
0037   int dPhi24 = ptlut_data.delta_ph[4];
0038   int dPhi34 = ptlut_data.delta_ph[5];
0039   int dTheta12 = ptlut_data.delta_th[0];
0040   int dTheta13 = ptlut_data.delta_th[1];
0041   int dTheta14 = ptlut_data.delta_th[2];
0042   int dTheta23 = ptlut_data.delta_th[3];
0043   int dTheta24 = ptlut_data.delta_th[4];
0044   int dTheta34 = ptlut_data.delta_th[5];
0045   int FR1 = ptlut_data.fr[0];
0046   int FR2 = ptlut_data.fr[1];
0047   int FR3 = ptlut_data.fr[2];
0048   int FR4 = ptlut_data.fr[3];
0049 
0050   int sign12 = ptlut_data.sign_ph[0];
0051   int sign13 = ptlut_data.sign_ph[1];
0052   int sign14 = ptlut_data.sign_ph[2];
0053   int sign23 = ptlut_data.sign_ph[3];
0054   int sign24 = ptlut_data.sign_ph[4];
0055   int sign34 = ptlut_data.sign_ph[5];
0056   int dTheta12Sign = ptlut_data.sign_th[0];
0057   int dTheta13Sign = ptlut_data.sign_th[1];
0058   int dTheta14Sign = ptlut_data.sign_th[2];
0059   int dTheta23Sign = ptlut_data.sign_th[3];
0060   int dTheta24Sign = ptlut_data.sign_th[4];
0061   int dTheta34Sign = ptlut_data.sign_th[5];
0062 
0063   int CLCT1 = std::abs(aux().getCLCT(ptlut_data.cpattern[0]));
0064   int CLCT2 = std::abs(aux().getCLCT(ptlut_data.cpattern[1]));
0065   int CLCT3 = std::abs(aux().getCLCT(ptlut_data.cpattern[2]));
0066   int CLCT4 = std::abs(aux().getCLCT(ptlut_data.cpattern[3]));
0067   int CLCT1Sign = (aux().getCLCT(ptlut_data.cpattern[0]) > 0);
0068   int CLCT2Sign = (aux().getCLCT(ptlut_data.cpattern[1]) > 0);
0069   int CLCT3Sign = (aux().getCLCT(ptlut_data.cpattern[2]) > 0);
0070   int CLCT4Sign = (aux().getCLCT(ptlut_data.cpattern[3]) > 0);
0071 
0072   int CSCID1 = (ptlut_data.bt_vi[0] == 0 && ptlut_data.bt_vi[1] != 0) ? ptlut_data.bt_ci[1] + 16 : ptlut_data.bt_ci[0];
0073   int CSCID2 = ptlut_data.bt_ci[2];
0074   int CSCID3 = ptlut_data.bt_ci[3];
0075   int CSCID4 = ptlut_data.bt_ci[4];
0076 
0077   auto get_signed_int = [](int var, int sign) { return (sign == 1) ? (var * 1) : (var * -1); };
0078 
0079   dTheta12 = aux().getdTheta(get_signed_int(dTheta12, dTheta12Sign));
0080   dTheta13 = aux().getdTheta(get_signed_int(dTheta13, dTheta13Sign));
0081   dTheta14 = aux().getdTheta(get_signed_int(dTheta14, dTheta14Sign));
0082   dTheta23 = aux().getdTheta(get_signed_int(dTheta23, dTheta23Sign));
0083   dTheta24 = aux().getdTheta(get_signed_int(dTheta24, dTheta24Sign));
0084   dTheta34 = aux().getdTheta(get_signed_int(dTheta34, dTheta34Sign));
0085 
0086   bool use_FRLUT = true;
0087   if (use_FRLUT) {
0088     if (CSCID1 >= 16)
0089       FR1 = aux().getFRLUT(track.Sector(), 1, CSCID1 - 16);
0090     else
0091       FR1 = aux().getFRLUT(track.Sector(), 0, CSCID1);
0092     FR2 = aux().getFRLUT(track.Sector(), 2, CSCID2);
0093     FR3 = aux().getFRLUT(track.Sector(), 3, CSCID3);
0094     FR4 = aux().getFRLUT(track.Sector(), 4, CSCID4);
0095   }
0096 
0097   switch (mode_inv) {
0098     case 3:  // 1-2
0099       if (!bug9BitDPhi_)
0100         dPhi12 = std::min(511, dPhi12);
0101 
0102       address |= (dPhi12 & ((1 << 9) - 1)) << (0);
0103       address |= (sign12 & ((1 << 1) - 1)) << (0 + 9);
0104       address |= (dTheta12 & ((1 << 3) - 1)) << (0 + 9 + 1);
0105       address |= (CLCT1 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3);
0106       address |= (CLCT1Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2);
0107       address |= (CLCT2 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3 + 2 + 1);
0108       address |= (CLCT2Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2);
0109       address |= (FR1 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1);
0110       address |= (FR2 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1);
0111       address |= (theta & ((1 << 5) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1);
0112       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1 + 5);
0113       break;
0114 
0115     case 5:  // 1-3
0116       if (!bug9BitDPhi_)
0117         dPhi13 = std::min(511, dPhi13);
0118 
0119       address |= (dPhi13 & ((1 << 9) - 1)) << (0);
0120       address |= (sign13 & ((1 << 1) - 1)) << (0 + 9);
0121       address |= (dTheta13 & ((1 << 3) - 1)) << (0 + 9 + 1);
0122       address |= (CLCT1 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3);
0123       address |= (CLCT1Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2);
0124       address |= (CLCT3 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3 + 2 + 1);
0125       address |= (CLCT3Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2);
0126       address |= (FR1 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1);
0127       address |= (FR3 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1);
0128       address |= (theta & ((1 << 5) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1);
0129       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1 + 5);
0130       break;
0131 
0132     case 9:  // 1-4
0133       if (!bug9BitDPhi_)
0134         dPhi14 = std::min(511, dPhi14);
0135 
0136       address |= (dPhi14 & ((1 << 9) - 1)) << (0);
0137       address |= (sign14 & ((1 << 1) - 1)) << (0 + 9);
0138       address |= (dTheta14 & ((1 << 3) - 1)) << (0 + 9 + 1);
0139       address |= (CLCT1 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3);
0140       address |= (CLCT1Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2);
0141       address |= (CLCT4 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3 + 2 + 1);
0142       address |= (CLCT4Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2);
0143       address |= (FR1 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1);
0144       address |= (FR4 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1);
0145       address |= (theta & ((1 << 5) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1);
0146       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1 + 5);
0147       break;
0148 
0149     case 6:  // 2-3
0150       if (!bug9BitDPhi_)
0151         dPhi23 = std::min(511, dPhi23);
0152 
0153       address |= (dPhi23 & ((1 << 9) - 1)) << (0);
0154       address |= (sign23 & ((1 << 1) - 1)) << (0 + 9);
0155       address |= (dTheta23 & ((1 << 3) - 1)) << (0 + 9 + 1);
0156       address |= (CLCT2 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3);
0157       address |= (CLCT2Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2);
0158       address |= (CLCT3 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3 + 2 + 1);
0159       address |= (CLCT3Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2);
0160       address |= (FR2 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1);
0161       address |= (FR3 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1);
0162       address |= (theta & ((1 << 5) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1);
0163       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1 + 5);
0164       break;
0165 
0166     case 10:  // 2-4
0167       if (!bug9BitDPhi_)
0168         dPhi24 = std::min(511, dPhi24);
0169 
0170       address |= (dPhi24 & ((1 << 9) - 1)) << (0);
0171       address |= (sign24 & ((1 << 1) - 1)) << (0 + 9);
0172       address |= (dTheta24 & ((1 << 3) - 1)) << (0 + 9 + 1);
0173       address |= (CLCT2 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3);
0174       address |= (CLCT2Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2);
0175       address |= (CLCT4 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3 + 2 + 1);
0176       address |= (CLCT4Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2);
0177       address |= (FR2 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1);
0178       address |= (FR4 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1);
0179       address |= (theta & ((1 << 5) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1);
0180       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1 + 5);
0181       break;
0182 
0183     case 12:  // 3-4
0184       if (!bug9BitDPhi_)
0185         dPhi34 = std::min(511, dPhi34);
0186 
0187       address |= (dPhi34 & ((1 << 9) - 1)) << (0);
0188       address |= (sign34 & ((1 << 1) - 1)) << (0 + 9);
0189       address |= (dTheta34 & ((1 << 3) - 1)) << (0 + 9 + 1);
0190       address |= (CLCT3 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3);
0191       address |= (CLCT3Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2);
0192       address |= (CLCT4 & ((1 << 2) - 1)) << (0 + 9 + 1 + 3 + 2 + 1);
0193       address |= (CLCT4Sign & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2);
0194       address |= (FR3 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1);
0195       address |= (FR4 & ((1 << 1) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1);
0196       address |= (theta & ((1 << 5) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1);
0197       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1 + 5);
0198       break;
0199 
0200     case 7:  // 1-2-3
0201       dPhi12 = aux().getNLBdPhiBin(dPhi12, 7, 512);
0202       dPhi23 = aux().getNLBdPhiBin(dPhi23, 5, 256);
0203 
0204       address |= (dPhi12 & ((1 << 7) - 1)) << (0);
0205       address |= (dPhi23 & ((1 << 5) - 1)) << (0 + 7);
0206       address |= (sign12 & ((1 << 1) - 1)) << (0 + 7 + 5);
0207       address |= (sign23 & ((1 << 1) - 1)) << (0 + 7 + 5 + 1);
0208       address |= (dTheta13 & ((1 << 3) - 1)) << (0 + 7 + 5 + 1 + 1);
0209       address |= (CLCT1 & ((1 << 2) - 1)) << (0 + 7 + 5 + 1 + 1 + 3);
0210       address |= (CLCT1Sign & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2);
0211       address |= (FR1 & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1);
0212       address |= (theta & ((1 << 5) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1);
0213       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1 + 5);
0214       break;
0215 
0216     case 11:  // 1-2-4
0217       dPhi12 = aux().getNLBdPhiBin(dPhi12, 7, 512);
0218       dPhi24 = aux().getNLBdPhiBin(dPhi24, 5, 256);
0219 
0220       address |= (dPhi12 & ((1 << 7) - 1)) << (0);
0221       address |= (dPhi24 & ((1 << 5) - 1)) << (0 + 7);
0222       address |= (sign12 & ((1 << 1) - 1)) << (0 + 7 + 5);
0223       address |= (sign24 & ((1 << 1) - 1)) << (0 + 7 + 5 + 1);
0224       address |= (dTheta14 & ((1 << 3) - 1)) << (0 + 7 + 5 + 1 + 1);
0225       address |= (CLCT1 & ((1 << 2) - 1)) << (0 + 7 + 5 + 1 + 1 + 3);
0226       address |= (CLCT1Sign & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2);
0227       address |= (FR1 & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1);
0228       address |= (theta & ((1 << 5) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1);
0229       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1 + 5);
0230       break;
0231 
0232     case 13:  // 1-3-4
0233       dPhi13 = aux().getNLBdPhiBin(dPhi13, 7, 512);
0234       dPhi34 = aux().getNLBdPhiBin(dPhi34, 5, 256);
0235 
0236       address |= (dPhi13 & ((1 << 7) - 1)) << (0);
0237       address |= (dPhi34 & ((1 << 5) - 1)) << (0 + 7);
0238       address |= (sign13 & ((1 << 1) - 1)) << (0 + 7 + 5);
0239       address |= (sign34 & ((1 << 1) - 1)) << (0 + 7 + 5 + 1);
0240       address |= (dTheta14 & ((1 << 3) - 1)) << (0 + 7 + 5 + 1 + 1);
0241       address |= (CLCT1 & ((1 << 2) - 1)) << (0 + 7 + 5 + 1 + 1 + 3);
0242       address |= (CLCT1Sign & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2);
0243       address |= (FR1 & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1);
0244       address |= (theta & ((1 << 5) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1);
0245       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1 + 5);
0246       break;
0247 
0248     case 14:  // 2-3-4
0249       dPhi23 = aux().getNLBdPhiBin(dPhi23, 7, 512);
0250       dPhi34 = aux().getNLBdPhiBin(dPhi34, 6, 256);
0251 
0252       address |= (dPhi23 & ((1 << 7) - 1)) << (0);
0253       address |= (dPhi34 & ((1 << 6) - 1)) << (0 + 7);
0254       address |= (sign23 & ((1 << 1) - 1)) << (0 + 7 + 6);
0255       address |= (sign34 & ((1 << 1) - 1)) << (0 + 7 + 6 + 1);
0256       address |= (dTheta24 & ((1 << 3) - 1)) << (0 + 7 + 6 + 1 + 1);
0257       address |= (CLCT2 & ((1 << 2) - 1)) << (0 + 7 + 6 + 1 + 1 + 3);
0258       address |= (CLCT2Sign & ((1 << 1) - 1)) << (0 + 7 + 6 + 1 + 1 + 3 + 2);
0259       address |= (theta & ((1 << 5) - 1)) << (0 + 7 + 6 + 1 + 1 + 3 + 2 + 1);
0260       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 7 + 6 + 1 + 1 + 3 + 2 + 1 + 5);
0261       break;
0262 
0263     case 15:  // 1-2-3-4
0264       // Set sign23 and sign34 relative to sign12
0265       if (!sign12) {
0266         sign12 = !sign12;
0267         sign23 = !sign23;
0268         sign34 = !sign34;
0269       }
0270 
0271       dPhi12 = aux().getNLBdPhiBin(dPhi12, 7, 512);
0272       dPhi23 = aux().getNLBdPhiBin(dPhi23, 5, 256);
0273       dPhi34 = aux().getNLBdPhiBin(dPhi34, 6, 256);
0274 
0275       address |= (dPhi12 & ((1 << 7) - 1)) << (0);
0276       address |= (dPhi23 & ((1 << 5) - 1)) << (0 + 7);
0277       address |= (dPhi34 & ((1 << 6) - 1)) << (0 + 7 + 5);
0278       address |= (sign23 & ((1 << 1) - 1)) << (0 + 7 + 5 + 6);
0279       address |= (sign34 & ((1 << 1) - 1)) << (0 + 7 + 5 + 6 + 1);
0280       address |= (FR1 & ((1 << 1) - 1)) << (0 + 7 + 5 + 6 + 1 + 1);
0281       address |= (theta & ((1 << 5) - 1)) << (0 + 7 + 5 + 6 + 1 + 1 + 1);
0282       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 7 + 5 + 6 + 1 + 1 + 1 + 5);
0283       break;
0284 
0285     default:
0286       break;
0287   }
0288 
0289   return address;
0290 }
0291 
0292 float PtAssignmentEngine2016::calculate_pt_xml(const address_t& address) const {
0293   float pt = 0.;
0294 
0295   if (address == 0)  // invalid address
0296     return -1;       // return pt;
0297 
0298   int mode_inv = (address >> (30 - 4)) & ((1 << 4) - 1);
0299 
0300   auto contain = [](const std::vector<int>& vec, int elem) {
0301     return (std::find(vec.begin(), vec.end(), elem) != vec.end());
0302   };
0303 
0304   bool is_good_mode = contain(allowedModes_, mode_inv);
0305 
0306   if (!is_good_mode)  // invalid mode
0307     return -1;        // return pt;
0308 
0309   int dPhi12 = -999;
0310   int dPhi13 = -999;
0311   int dPhi14 = -999;
0312   int dPhi23 = -999;
0313   int dPhi24 = -999;
0314   int dPhi34 = -999;
0315   int dTheta12 = -999;
0316   int dTheta13 = -999;
0317   int dTheta14 = -999;
0318   int dTheta23 = -999;
0319   int dTheta24 = -999;
0320   int dTheta34 = -999;
0321   int CLCT1 = -999;
0322   int CLCT2 = -999;
0323   int CLCT3 = -999;
0324   int CLCT4 = -999;
0325   int CSCID1 = -999;
0326   int CSCID2 = -999;
0327   int CSCID3 = -999;
0328   int CSCID4 = -999;
0329   int FR1 = -999;
0330   int FR2 = -999;
0331   int FR3 = -999;
0332   int FR4 = -999;
0333 
0334   int sign12 = 1;
0335   int sign13 = 1;
0336   int sign14 = 1;
0337   int sign23 = 1;
0338   int sign24 = 1;
0339   int sign34 = 1;
0340 
0341   int CLCT1Sign = 1;
0342   int CLCT2Sign = 1;
0343   int CLCT3Sign = 1;
0344   int CLCT4Sign = 1;
0345 
0346   int theta = 0;
0347 
0348   switch (mode_inv) {
0349     case 3:  // 1-2
0350       dPhi12 = (address >> (0)) & ((1 << 9) - 1);
0351       sign12 = (address >> (0 + 9)) & ((1 << 1) - 1);
0352       dTheta12 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0353       CLCT1 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0354       CLCT1Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0355       CLCT2 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0356       CLCT2Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0357       FR1 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0358       FR2 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0359       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0360       break;
0361 
0362     case 5:  // 1-3
0363       dPhi13 = (address >> (0)) & ((1 << 9) - 1);
0364       sign13 = (address >> (0 + 9)) & ((1 << 1) - 1);
0365       dTheta13 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0366       CLCT1 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0367       CLCT1Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0368       CLCT3 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0369       CLCT3Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0370       FR1 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0371       FR3 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0372       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0373       break;
0374 
0375     case 9:  // 1-4
0376       dPhi14 = (address >> (0)) & ((1 << 9) - 1);
0377       sign14 = (address >> (0 + 9)) & ((1 << 1) - 1);
0378       dTheta14 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0379       CLCT1 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0380       CLCT1Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0381       CLCT4 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0382       CLCT4Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0383       FR1 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0384       FR4 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0385       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0386       break;
0387 
0388     case 6:  // 2-3
0389       dPhi23 = (address >> (0)) & ((1 << 9) - 1);
0390       sign23 = (address >> (0 + 9)) & ((1 << 1) - 1);
0391       dTheta23 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0392       CLCT2 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0393       CLCT2Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0394       CLCT3 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0395       CLCT3Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0396       FR2 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0397       FR3 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0398       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0399       break;
0400 
0401     case 10:  // 2-4
0402       dPhi24 = (address >> (0)) & ((1 << 9) - 1);
0403       sign24 = (address >> (0 + 9)) & ((1 << 1) - 1);
0404       dTheta24 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0405       CLCT2 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0406       CLCT2Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0407       CLCT4 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0408       CLCT4Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0409       FR2 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0410       FR4 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0411       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0412       break;
0413 
0414     case 12:  // 3-4
0415       dPhi34 = (address >> (0)) & ((1 << 9) - 1);
0416       sign34 = (address >> (0 + 9)) & ((1 << 1) - 1);
0417       dTheta34 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0418       CLCT3 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0419       CLCT3Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0420       CLCT4 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0421       CLCT4Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0422       FR3 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0423       FR4 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0424       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0425       break;
0426 
0427     case 7:  // 1-2-3
0428       dPhi12 = (address >> (0)) & ((1 << 7) - 1);
0429       dPhi23 = (address >> (0 + 7)) & ((1 << 5) - 1);
0430       sign12 = (address >> (0 + 7 + 5)) & ((1 << 1) - 1);
0431       sign23 = (address >> (0 + 7 + 5 + 1)) & ((1 << 1) - 1);
0432       dTheta13 = (address >> (0 + 7 + 5 + 1 + 1)) & ((1 << 3) - 1);
0433       CLCT1 = (address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);
0434       CLCT1Sign = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2)) & ((1 << 1) - 1);
0435       FR1 = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1)) & ((1 << 1) - 1);
0436       theta = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1)) & ((1 << 5) - 1);
0437 
0438       dPhi12 = aux().getdPhiFromBin(dPhi12, 7, 512);
0439       dPhi23 = aux().getdPhiFromBin(dPhi23, 5, 256);
0440       break;
0441 
0442     case 11:  // 1-2-4
0443       dPhi12 = (address >> (0)) & ((1 << 7) - 1);
0444       dPhi24 = (address >> (0 + 7)) & ((1 << 5) - 1);
0445       sign12 = (address >> (0 + 7 + 5)) & ((1 << 1) - 1);
0446       sign24 = (address >> (0 + 7 + 5 + 1)) & ((1 << 1) - 1);
0447       dTheta14 = (address >> (0 + 7 + 5 + 1 + 1)) & ((1 << 3) - 1);
0448       CLCT1 = (address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);
0449       CLCT1Sign = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2)) & ((1 << 1) - 1);
0450       FR1 = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1)) & ((1 << 1) - 1);
0451       theta = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1)) & ((1 << 5) - 1);
0452 
0453       dPhi12 = aux().getdPhiFromBin(dPhi12, 7, 512);
0454       dPhi24 = aux().getdPhiFromBin(dPhi24, 5, 256);
0455       break;
0456 
0457     case 13:  // 1-3-4
0458       dPhi13 = (address >> (0)) & ((1 << 7) - 1);
0459       dPhi34 = (address >> (0 + 7)) & ((1 << 5) - 1);
0460       sign13 = (address >> (0 + 7 + 5)) & ((1 << 1) - 1);
0461       sign34 = (address >> (0 + 7 + 5 + 1)) & ((1 << 1) - 1);
0462       dTheta14 = (address >> (0 + 7 + 5 + 1 + 1)) & ((1 << 3) - 1);
0463       CLCT1 = (address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);
0464       CLCT1Sign = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2)) & ((1 << 1) - 1);
0465       FR1 = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1)) & ((1 << 1) - 1);
0466       theta = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1)) & ((1 << 5) - 1);
0467 
0468       dPhi13 = aux().getdPhiFromBin(dPhi13, 7, 512);
0469       dPhi34 = aux().getdPhiFromBin(dPhi34, 5, 256);
0470       break;
0471 
0472     case 14:  // 2-3-4
0473       dPhi23 = (address >> (0)) & ((1 << 7) - 1);
0474       dPhi34 = (address >> (0 + 7)) & ((1 << 6) - 1);
0475       sign23 = (address >> (0 + 7 + 6)) & ((1 << 1) - 1);
0476       sign34 = (address >> (0 + 7 + 6 + 1)) & ((1 << 1) - 1);
0477       dTheta24 = (address >> (0 + 7 + 6 + 1 + 1)) & ((1 << 3) - 1);
0478       CLCT2 = (address >> (0 + 7 + 6 + 1 + 1 + 3)) & ((1 << 2) - 1);
0479       CLCT2Sign = (address >> (0 + 7 + 6 + 1 + 1 + 3 + 2)) & ((1 << 1) - 1);
0480       theta = (address >> (0 + 7 + 6 + 1 + 1 + 3 + 2 + 1)) & ((1 << 5) - 1);
0481 
0482       dPhi23 = aux().getdPhiFromBin(dPhi23, 7, 512);
0483       dPhi34 = aux().getdPhiFromBin(dPhi34, 6, 256);
0484       break;
0485 
0486     case 15:  // 1-2-3-4
0487       dPhi12 = (address >> (0)) & ((1 << 7) - 1);
0488       dPhi23 = (address >> (0 + 7)) & ((1 << 5) - 1);
0489       dPhi34 = (address >> (0 + 7 + 5)) & ((1 << 6) - 1);
0490       sign23 = (address >> (0 + 7 + 5 + 6)) & ((1 << 1) - 1);
0491       sign34 = (address >> (0 + 7 + 5 + 6 + 1)) & ((1 << 1) - 1);
0492       FR1 = (address >> (0 + 7 + 5 + 6 + 1 + 1)) & ((1 << 1) - 1);
0493       theta = (address >> (0 + 7 + 5 + 6 + 1 + 1 + 1)) & ((1 << 5) - 1);
0494 
0495       dPhi12 = aux().getdPhiFromBin(dPhi12, 7, 512);
0496       dPhi23 = aux().getdPhiFromBin(dPhi23, 5, 256);
0497       dPhi34 = aux().getdPhiFromBin(dPhi34, 6, 256);
0498       break;
0499 
0500     default:
0501       break;
0502   }
0503 
0504   auto get_signed_int = [](int var, int sign) { return (sign == 1) ? (var * 1) : (var * -1); };
0505 
0506   dPhi12 = get_signed_int(dPhi12, sign12);
0507   dPhi13 = get_signed_int(dPhi13, sign13);
0508   dPhi14 = get_signed_int(dPhi14, sign14);
0509   dPhi23 = get_signed_int(dPhi23, sign23);
0510   dPhi24 = get_signed_int(dPhi24, sign24);
0511   dPhi34 = get_signed_int(dPhi34, sign34);
0512 
0513   CLCT1 = get_signed_int(CLCT1, CLCT1Sign);
0514   CLCT2 = get_signed_int(CLCT2, CLCT2Sign);
0515   CLCT3 = get_signed_int(CLCT3, CLCT3Sign);
0516   CLCT4 = get_signed_int(CLCT4, CLCT4Sign);
0517 
0518   theta <<= 2;
0519   float eta = aux().getEtaFromThetaInt(theta, 5);
0520 
0521   bool use_lossy_eta = true;
0522   if (use_lossy_eta) {
0523     int etaInt = aux().getEtaInt(eta, 5);
0524     etaInt &= ((1 << 5) - 1);
0525     eta = aux().getEtaFromEtaInt(etaInt, 5);
0526   }
0527 
0528   // First fix to recover high pT muons with 3 hits in a line and one displaced hit
0529   // Done by re-writing a few addresses in the original LUT, according to the following logic
0530   // Implemented in FW 26.07.16, as of run 2774278 / fill 5119
0531   if (fixMode15HighPt_) {
0532     if (mode_inv == 15) {  // 1-2-3-4
0533       bool st2_off = false;
0534       bool st3_off = false;
0535       bool st4_off = false;
0536 
0537       dPhi13 = dPhi12 + dPhi23;
0538       dPhi14 = dPhi13 + dPhi34;
0539       dPhi24 = dPhi23 + dPhi34;
0540 
0541       int sum_st1 = abs(dPhi12 + dPhi13 + dPhi14);
0542       int sum_st2 = abs(-dPhi12 + dPhi23 + dPhi24);
0543       int sum_st3 = abs(-dPhi13 - dPhi23 + dPhi34);
0544       int sum_st4 = abs(-dPhi14 - dPhi24 - dPhi34);
0545 
0546       // Detect outliers
0547       if (sum_st2 > sum_st1 && sum_st2 > sum_st3 && sum_st2 > sum_st4)
0548         st2_off = true;
0549       if (sum_st3 > sum_st1 && sum_st3 > sum_st2 && sum_st3 > sum_st4)
0550         st3_off = true;
0551       if (sum_st4 > sum_st1 && sum_st4 > sum_st2 && sum_st4 > sum_st3)
0552         st4_off = true;
0553 
0554       // Recover outliers
0555       if (st2_off) {
0556         if ((abs(dPhi12) > 9 || abs(dPhi23) > 9 || abs(dPhi24) > 9) &&
0557             (abs(dPhi13) < 10 && abs(dPhi14) < 10 && abs(dPhi34) < 10)) {
0558           dPhi12 = dPhi13 / 2;
0559           dPhi23 = dPhi13 / 2;
0560         }
0561       }
0562       if (st3_off) {
0563         if ((abs(dPhi13) > 9 || abs(dPhi23) > 9 || abs(dPhi34) > 9) &&
0564             (abs(dPhi12) < 10 && abs(dPhi14) < 10 && abs(dPhi24) < 10)) {
0565           dPhi23 = dPhi24 / 2;
0566           dPhi34 = dPhi24 / 2;
0567         }
0568       }
0569       if (st4_off) {
0570         if ((abs(dPhi14) > 9 || abs(dPhi24) > 9 || abs(dPhi34) > 9) &&
0571             (abs(dPhi12) < 10 && abs(dPhi13) < 10 && abs(dPhi23) < 10)) {
0572           if (abs(dPhi13) < abs(dPhi23))
0573             dPhi34 = dPhi13;
0574           else
0575             dPhi34 = dPhi23;
0576         }
0577       }
0578 
0579       // Set sign23 and sign34 relative to sign12
0580       //sign12 = (dPhi12 >= 0);
0581       //sign23 = (dPhi23 >= 0);
0582       //sign34 = (dPhi34 >= 0);
0583       //if (!sign12) {
0584       //  sign12 = !sign12;
0585       //  sign23 = !sign23;
0586       //  sign34 = !sign34;
0587       //}
0588 
0589       sign12 = 1;
0590       if (dPhi12 > 0) {
0591         sign23 = (dPhi23 > 0) ? 1 : 0;
0592         sign34 = (dPhi34 > 0) ? 1 : 0;
0593       } else {
0594         sign23 = (dPhi23 < 0) ? 1 : 0;
0595         sign34 = (dPhi34 < 0) ? 1 : 0;
0596       }
0597 
0598       dPhi12 = get_signed_int(abs(dPhi12), sign12);
0599       dPhi23 = get_signed_int(abs(dPhi23), sign23);
0600       dPhi34 = get_signed_int(abs(dPhi34), sign34);
0601 
0602     }  // end if mode_inv == 15
0603   }
0604 
0605   // Inherit some bugs
0606   if (bugMode7CLCT_) {
0607     if (mode_inv == 14) {  // 2-3-4
0608       int bugged_CLCT2;
0609       address_t bugged_address;
0610 
0611       //CLCT2     = (address >> (0+7+6+1+1+3))          & ((1<<2)-1);
0612       //address |= (CLCT2       & ((1<<2)-1)) << (0+7+6+1+1+3);
0613 
0614       bugged_CLCT2 = (address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);     // bad
0615       bugged_address = address & ~(((1 << 2) - 1) << (0 + 7 + 6 + 1 + 1 + 3));  // clear bits
0616       bugged_address |= (bugged_CLCT2 & ((1 << 2) - 1)) << (0 + 7 + 6 + 1 + 1 + 3);
0617       bugged_CLCT2 = (bugged_address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);  // bad
0618 
0619       CLCT2 = bugged_CLCT2;
0620       CLCT2 = get_signed_int(CLCT2, CLCT2Sign);
0621 
0622     }  // end if mode_inv == 14
0623   }
0624 
0625   // Get pT from XML (forest)
0626   const int(*mode_variables)[6] = aux().getModeVariables();
0627 
0628   std::vector<int> variables = {dPhi12,   dPhi13,   dPhi14,   dPhi23,   dPhi24, dPhi34, dTheta12, dTheta13,
0629                                 dTheta14, dTheta23, dTheta24, dTheta34, CLCT1,  CLCT2,  CLCT3,    CLCT4,
0630                                 CSCID1,   CSCID2,   CSCID3,   CSCID4,   FR1,    FR2,    FR3,      FR4};
0631 
0632   std::vector<double> tree_data;
0633   tree_data.push_back(1.0);
0634   tree_data.push_back(eta);
0635 
0636   for (int i = 0; i < 6; i++) {  // loop over 6 variables (or less)
0637     int mv = mode_variables[mode_inv - 3][i];
0638     if (mv != -999) {
0639       int v = variables.at(mv);
0640       if (!(mode_inv == 13 && i == 3)) {  // somehow this uses CSCID1
0641         emtf_assert(v != -999);
0642       }
0643       tree_data.push_back(v);
0644     } else {
0645       tree_data.push_back(0);  // pad with zeroes, somehow BDT tries to access out of bounds
0646     }
0647   }
0648 
0649   if (verbose_ > 2) {
0650     std::cout << "mode_inv: " << mode_inv << " variables: ";
0651     for (const auto& v : tree_data)
0652       std::cout << v << " ";
0653     std::cout << std::endl;
0654   }
0655 
0656   auto tree_event = std::make_unique<emtf::Event>();
0657   tree_event->predictedValue = 0;  // must explicitly initialize
0658   tree_event->data = tree_data;
0659 
0660   // forests_.at(mode_inv).predictEvent(tree_event.get(), 64);
0661   emtf::Forest& forest = const_cast<emtf::Forest&>(forests_.at(mode_inv));
0662   forest.predictEvent(tree_event.get(), 64);
0663 
0664   float tmp_pt = tree_event->predictedValue;  // is actually 1/pT
0665 
0666   if (verbose_ > 1) {
0667     std::cout << "mode_inv: " << mode_inv << " 1/pT: " << tmp_pt << std::endl;
0668     std::cout << "dPhi12: " << dPhi12 << " dPhi13: " << dPhi13 << " dPhi14: " << dPhi14 << " dPhi23: " << dPhi23
0669               << " dPhi24: " << dPhi24 << " dPhi34: " << dPhi34 << std::endl;
0670     std::cout << "dTheta12: " << dTheta12 << " dTheta13: " << dTheta13 << " dTheta14: " << dTheta14
0671               << " dTheta23: " << dTheta23 << " dTheta24: " << dTheta24 << " dTheta34: " << dTheta34 << std::endl;
0672     std::cout << "CLCT1: " << CLCT1 << " CLCT2: " << CLCT2 << " CLCT3: " << CLCT3 << " CLCT4: " << CLCT4 << std::endl;
0673     std::cout << "CSCID1: " << CSCID1 << " CSCID2: " << CSCID2 << " CSCID3: " << CSCID3 << " CSCID4: " << CSCID4
0674               << std::endl;
0675     std::cout << "FR1: " << FR1 << " FR2: " << FR2 << " FR3: " << FR3 << " FR4: " << FR4 << std::endl;
0676   }
0677 
0678   if (bugNegPt_) {
0679     pt = (tmp_pt == 0) ? tmp_pt : 1.0 / tmp_pt;
0680     if (pt < 0.0)
0681       pt = 1.0;
0682     if (pt > 200.0)
0683       pt = 200.0;
0684 
0685   } else {
0686     if (tmp_pt < 0.0)
0687       tmp_pt = 1.0 / 7000;
0688     pt = (tmp_pt == 0) ? tmp_pt : 1.0 / tmp_pt;
0689   }
0690 
0691   emtf_assert(pt > 0);
0692   return pt;
0693 }
0694 
0695 // Not implemented for 2016
0696 float PtAssignmentEngine2016::calculate_pt_xml(const EMTFTrack& track) const {
0697   float pt = 0.;
0698 
0699   return pt;
0700 }