Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-08 05:11:49

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         sign23 = !sign23;
0267         sign34 = !sign34;
0268       }
0269 
0270       dPhi12 = aux().getNLBdPhiBin(dPhi12, 7, 512);
0271       dPhi23 = aux().getNLBdPhiBin(dPhi23, 5, 256);
0272       dPhi34 = aux().getNLBdPhiBin(dPhi34, 6, 256);
0273 
0274       address |= (dPhi12 & ((1 << 7) - 1)) << (0);
0275       address |= (dPhi23 & ((1 << 5) - 1)) << (0 + 7);
0276       address |= (dPhi34 & ((1 << 6) - 1)) << (0 + 7 + 5);
0277       address |= (sign23 & ((1 << 1) - 1)) << (0 + 7 + 5 + 6);
0278       address |= (sign34 & ((1 << 1) - 1)) << (0 + 7 + 5 + 6 + 1);
0279       address |= (FR1 & ((1 << 1) - 1)) << (0 + 7 + 5 + 6 + 1 + 1);
0280       address |= (theta & ((1 << 5) - 1)) << (0 + 7 + 5 + 6 + 1 + 1 + 1);
0281       address |= (mode_inv & ((1 << 4) - 1)) << (0 + 7 + 5 + 6 + 1 + 1 + 1 + 5);
0282       break;
0283 
0284     default:
0285       break;
0286   }
0287 
0288   return address;
0289 }
0290 
0291 float PtAssignmentEngine2016::calculate_pt_xml(const address_t& address) const {
0292   float pt = 0.;
0293 
0294   if (address == 0)  // invalid address
0295     return -1;       // return pt;
0296 
0297   int mode_inv = (address >> (30 - 4)) & ((1 << 4) - 1);
0298 
0299   auto contain = [](const std::vector<int>& vec, int elem) {
0300     return (std::find(vec.begin(), vec.end(), elem) != vec.end());
0301   };
0302 
0303   bool is_good_mode = contain(allowedModes_, mode_inv);
0304 
0305   if (!is_good_mode)  // invalid mode
0306     return -1;        // return pt;
0307 
0308   int dPhi12 = -999;
0309   int dPhi13 = -999;
0310   int dPhi14 = -999;
0311   int dPhi23 = -999;
0312   int dPhi24 = -999;
0313   int dPhi34 = -999;
0314   int dTheta12 = -999;
0315   int dTheta13 = -999;
0316   int dTheta14 = -999;
0317   int dTheta23 = -999;
0318   int dTheta24 = -999;
0319   int dTheta34 = -999;
0320   int CLCT1 = -999;
0321   int CLCT2 = -999;
0322   int CLCT3 = -999;
0323   int CLCT4 = -999;
0324   int CSCID1 = -999;
0325   int CSCID2 = -999;
0326   int CSCID3 = -999;
0327   int CSCID4 = -999;
0328   int FR1 = -999;
0329   int FR2 = -999;
0330   int FR3 = -999;
0331   int FR4 = -999;
0332 
0333   int sign12 = 1;
0334   int sign13 = 1;
0335   int sign14 = 1;
0336   int sign23 = 1;
0337   int sign24 = 1;
0338   int sign34 = 1;
0339 
0340   int CLCT1Sign = 1;
0341   int CLCT2Sign = 1;
0342   int CLCT3Sign = 1;
0343   int CLCT4Sign = 1;
0344 
0345   int theta = 0;
0346 
0347   switch (mode_inv) {
0348     case 3:  // 1-2
0349       dPhi12 = (address >> (0)) & ((1 << 9) - 1);
0350       sign12 = (address >> (0 + 9)) & ((1 << 1) - 1);
0351       dTheta12 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0352       CLCT1 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0353       CLCT1Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0354       CLCT2 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0355       CLCT2Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0356       FR1 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0357       FR2 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0358       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0359       break;
0360 
0361     case 5:  // 1-3
0362       dPhi13 = (address >> (0)) & ((1 << 9) - 1);
0363       sign13 = (address >> (0 + 9)) & ((1 << 1) - 1);
0364       dTheta13 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0365       CLCT1 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0366       CLCT1Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0367       CLCT3 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0368       CLCT3Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0369       FR1 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0370       FR3 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0371       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0372       break;
0373 
0374     case 9:  // 1-4
0375       dPhi14 = (address >> (0)) & ((1 << 9) - 1);
0376       sign14 = (address >> (0 + 9)) & ((1 << 1) - 1);
0377       dTheta14 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0378       CLCT1 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0379       CLCT1Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0380       CLCT4 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0381       CLCT4Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0382       FR1 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0383       FR4 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0384       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0385       break;
0386 
0387     case 6:  // 2-3
0388       dPhi23 = (address >> (0)) & ((1 << 9) - 1);
0389       sign23 = (address >> (0 + 9)) & ((1 << 1) - 1);
0390       dTheta23 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0391       CLCT2 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0392       CLCT2Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0393       CLCT3 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0394       CLCT3Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0395       FR2 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0396       FR3 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0397       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0398       break;
0399 
0400     case 10:  // 2-4
0401       dPhi24 = (address >> (0)) & ((1 << 9) - 1);
0402       sign24 = (address >> (0 + 9)) & ((1 << 1) - 1);
0403       dTheta24 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0404       CLCT2 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0405       CLCT2Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0406       CLCT4 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0407       CLCT4Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0408       FR2 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0409       FR4 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0410       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0411       break;
0412 
0413     case 12:  // 3-4
0414       dPhi34 = (address >> (0)) & ((1 << 9) - 1);
0415       sign34 = (address >> (0 + 9)) & ((1 << 1) - 1);
0416       dTheta34 = (address >> (0 + 9 + 1)) & ((1 << 3) - 1);
0417       CLCT3 = (address >> (0 + 9 + 1 + 3)) & ((1 << 2) - 1);
0418       CLCT3Sign = (address >> (0 + 9 + 1 + 3 + 2)) & ((1 << 1) - 1);
0419       CLCT4 = (address >> (0 + 9 + 1 + 3 + 2 + 1)) & ((1 << 2) - 1);
0420       CLCT4Sign = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2)) & ((1 << 1) - 1);
0421       FR3 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1)) & ((1 << 1) - 1);
0422       FR4 = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1)) & ((1 << 1) - 1);
0423       theta = (address >> (0 + 9 + 1 + 3 + 2 + 1 + 2 + 1 + 1 + 1)) & ((1 << 5) - 1);
0424       break;
0425 
0426     case 7:  // 1-2-3
0427       dPhi12 = (address >> (0)) & ((1 << 7) - 1);
0428       dPhi23 = (address >> (0 + 7)) & ((1 << 5) - 1);
0429       sign12 = (address >> (0 + 7 + 5)) & ((1 << 1) - 1);
0430       sign23 = (address >> (0 + 7 + 5 + 1)) & ((1 << 1) - 1);
0431       dTheta13 = (address >> (0 + 7 + 5 + 1 + 1)) & ((1 << 3) - 1);
0432       CLCT1 = (address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);
0433       CLCT1Sign = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2)) & ((1 << 1) - 1);
0434       FR1 = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1)) & ((1 << 1) - 1);
0435       theta = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1)) & ((1 << 5) - 1);
0436 
0437       dPhi12 = aux().getdPhiFromBin(dPhi12, 7, 512);
0438       dPhi23 = aux().getdPhiFromBin(dPhi23, 5, 256);
0439       break;
0440 
0441     case 11:  // 1-2-4
0442       dPhi12 = (address >> (0)) & ((1 << 7) - 1);
0443       dPhi24 = (address >> (0 + 7)) & ((1 << 5) - 1);
0444       sign12 = (address >> (0 + 7 + 5)) & ((1 << 1) - 1);
0445       sign24 = (address >> (0 + 7 + 5 + 1)) & ((1 << 1) - 1);
0446       dTheta14 = (address >> (0 + 7 + 5 + 1 + 1)) & ((1 << 3) - 1);
0447       CLCT1 = (address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);
0448       CLCT1Sign = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2)) & ((1 << 1) - 1);
0449       FR1 = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1)) & ((1 << 1) - 1);
0450       theta = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1)) & ((1 << 5) - 1);
0451 
0452       dPhi12 = aux().getdPhiFromBin(dPhi12, 7, 512);
0453       dPhi24 = aux().getdPhiFromBin(dPhi24, 5, 256);
0454       break;
0455 
0456     case 13:  // 1-3-4
0457       dPhi13 = (address >> (0)) & ((1 << 7) - 1);
0458       dPhi34 = (address >> (0 + 7)) & ((1 << 5) - 1);
0459       sign13 = (address >> (0 + 7 + 5)) & ((1 << 1) - 1);
0460       sign34 = (address >> (0 + 7 + 5 + 1)) & ((1 << 1) - 1);
0461       dTheta14 = (address >> (0 + 7 + 5 + 1 + 1)) & ((1 << 3) - 1);
0462       CLCT1 = (address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);
0463       CLCT1Sign = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2)) & ((1 << 1) - 1);
0464       FR1 = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1)) & ((1 << 1) - 1);
0465       theta = (address >> (0 + 7 + 5 + 1 + 1 + 3 + 2 + 1 + 1)) & ((1 << 5) - 1);
0466 
0467       dPhi13 = aux().getdPhiFromBin(dPhi13, 7, 512);
0468       dPhi34 = aux().getdPhiFromBin(dPhi34, 5, 256);
0469       break;
0470 
0471     case 14:  // 2-3-4
0472       dPhi23 = (address >> (0)) & ((1 << 7) - 1);
0473       dPhi34 = (address >> (0 + 7)) & ((1 << 6) - 1);
0474       sign23 = (address >> (0 + 7 + 6)) & ((1 << 1) - 1);
0475       sign34 = (address >> (0 + 7 + 6 + 1)) & ((1 << 1) - 1);
0476       dTheta24 = (address >> (0 + 7 + 6 + 1 + 1)) & ((1 << 3) - 1);
0477       CLCT2 = (address >> (0 + 7 + 6 + 1 + 1 + 3)) & ((1 << 2) - 1);
0478       CLCT2Sign = (address >> (0 + 7 + 6 + 1 + 1 + 3 + 2)) & ((1 << 1) - 1);
0479       theta = (address >> (0 + 7 + 6 + 1 + 1 + 3 + 2 + 1)) & ((1 << 5) - 1);
0480 
0481       dPhi23 = aux().getdPhiFromBin(dPhi23, 7, 512);
0482       dPhi34 = aux().getdPhiFromBin(dPhi34, 6, 256);
0483       break;
0484 
0485     case 15:  // 1-2-3-4
0486       dPhi12 = (address >> (0)) & ((1 << 7) - 1);
0487       dPhi23 = (address >> (0 + 7)) & ((1 << 5) - 1);
0488       dPhi34 = (address >> (0 + 7 + 5)) & ((1 << 6) - 1);
0489       sign23 = (address >> (0 + 7 + 5 + 6)) & ((1 << 1) - 1);
0490       sign34 = (address >> (0 + 7 + 5 + 6 + 1)) & ((1 << 1) - 1);
0491       FR1 = (address >> (0 + 7 + 5 + 6 + 1 + 1)) & ((1 << 1) - 1);
0492       theta = (address >> (0 + 7 + 5 + 6 + 1 + 1 + 1)) & ((1 << 5) - 1);
0493 
0494       dPhi12 = aux().getdPhiFromBin(dPhi12, 7, 512);
0495       dPhi23 = aux().getdPhiFromBin(dPhi23, 5, 256);
0496       dPhi34 = aux().getdPhiFromBin(dPhi34, 6, 256);
0497       break;
0498 
0499     default:
0500       break;
0501   }
0502 
0503   auto get_signed_int = [](int var, int sign) { return (sign == 1) ? (var * 1) : (var * -1); };
0504 
0505   dPhi12 = get_signed_int(dPhi12, sign12);
0506   dPhi13 = get_signed_int(dPhi13, sign13);
0507   dPhi14 = get_signed_int(dPhi14, sign14);
0508   dPhi23 = get_signed_int(dPhi23, sign23);
0509   dPhi24 = get_signed_int(dPhi24, sign24);
0510   dPhi34 = get_signed_int(dPhi34, sign34);
0511 
0512   CLCT1 = get_signed_int(CLCT1, CLCT1Sign);
0513   CLCT2 = get_signed_int(CLCT2, CLCT2Sign);
0514   CLCT3 = get_signed_int(CLCT3, CLCT3Sign);
0515   CLCT4 = get_signed_int(CLCT4, CLCT4Sign);
0516 
0517   theta <<= 2;
0518   float eta = aux().getEtaFromThetaInt(theta, 5);
0519 
0520   bool use_lossy_eta = true;
0521   if (use_lossy_eta) {
0522     int etaInt = aux().getEtaInt(eta, 5);
0523     etaInt &= ((1 << 5) - 1);
0524     eta = aux().getEtaFromEtaInt(etaInt, 5);
0525   }
0526 
0527   // First fix to recover high pT muons with 3 hits in a line and one displaced hit
0528   // Done by re-writing a few addresses in the original LUT, according to the following logic
0529   // Implemented in FW 26.07.16, as of run 2774278 / fill 5119
0530   if (fixMode15HighPt_) {
0531     if (mode_inv == 15) {  // 1-2-3-4
0532       bool st2_off = false;
0533       bool st3_off = false;
0534       bool st4_off = false;
0535 
0536       dPhi13 = dPhi12 + dPhi23;
0537       dPhi14 = dPhi13 + dPhi34;
0538       dPhi24 = dPhi23 + dPhi34;
0539 
0540       int sum_st1 = abs(dPhi12 + dPhi13 + dPhi14);
0541       int sum_st2 = abs(-dPhi12 + dPhi23 + dPhi24);
0542       int sum_st3 = abs(-dPhi13 - dPhi23 + dPhi34);
0543       int sum_st4 = abs(-dPhi14 - dPhi24 - dPhi34);
0544 
0545       // Detect outliers
0546       if (sum_st2 > sum_st1 && sum_st2 > sum_st3 && sum_st2 > sum_st4)
0547         st2_off = true;
0548       if (sum_st3 > sum_st1 && sum_st3 > sum_st2 && sum_st3 > sum_st4)
0549         st3_off = true;
0550       if (sum_st4 > sum_st1 && sum_st4 > sum_st2 && sum_st4 > sum_st3)
0551         st4_off = true;
0552 
0553       // Recover outliers
0554       if (st2_off) {
0555         if ((abs(dPhi12) > 9 || abs(dPhi23) > 9 || abs(dPhi24) > 9) &&
0556             (abs(dPhi13) < 10 && abs(dPhi14) < 10 && abs(dPhi34) < 10)) {
0557           dPhi12 = dPhi13 / 2;
0558           dPhi23 = dPhi13 / 2;
0559         }
0560       }
0561       if (st3_off) {
0562         if ((abs(dPhi13) > 9 || abs(dPhi23) > 9 || abs(dPhi34) > 9) &&
0563             (abs(dPhi12) < 10 && abs(dPhi14) < 10 && abs(dPhi24) < 10)) {
0564           dPhi23 = dPhi24 / 2;
0565           dPhi34 = dPhi24 / 2;
0566         }
0567       }
0568       if (st4_off) {
0569         if ((abs(dPhi14) > 9 || abs(dPhi24) > 9 || abs(dPhi34) > 9) &&
0570             (abs(dPhi12) < 10 && abs(dPhi13) < 10 && abs(dPhi23) < 10)) {
0571           if (abs(dPhi13) < abs(dPhi23))
0572             dPhi34 = dPhi13;
0573           else
0574             dPhi34 = dPhi23;
0575         }
0576       }
0577 
0578       // Set sign23 and sign34 relative to sign12
0579       //sign12 = (dPhi12 >= 0);
0580       //sign23 = (dPhi23 >= 0);
0581       //sign34 = (dPhi34 >= 0);
0582       //if (!sign12) {
0583       //  sign12 = !sign12;
0584       //  sign23 = !sign23;
0585       //  sign34 = !sign34;
0586       //}
0587 
0588       sign12 = 1;
0589       if (dPhi12 > 0) {
0590         sign23 = (dPhi23 > 0) ? 1 : 0;
0591         sign34 = (dPhi34 > 0) ? 1 : 0;
0592       } else {
0593         sign23 = (dPhi23 < 0) ? 1 : 0;
0594         sign34 = (dPhi34 < 0) ? 1 : 0;
0595       }
0596 
0597       dPhi12 = get_signed_int(abs(dPhi12), sign12);
0598       dPhi23 = get_signed_int(abs(dPhi23), sign23);
0599       dPhi34 = get_signed_int(abs(dPhi34), sign34);
0600 
0601     }  // end if mode_inv == 15
0602   }
0603 
0604   // Inherit some bugs
0605   if (bugMode7CLCT_) {
0606     if (mode_inv == 14) {  // 2-3-4
0607       int bugged_CLCT2;
0608       address_t bugged_address;
0609 
0610       //CLCT2     = (address >> (0+7+6+1+1+3))          & ((1<<2)-1);
0611       //address |= (CLCT2       & ((1<<2)-1)) << (0+7+6+1+1+3);
0612 
0613       bugged_CLCT2 = (address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);     // bad
0614       bugged_address = address & ~(((1 << 2) - 1) << (0 + 7 + 6 + 1 + 1 + 3));  // clear bits
0615       bugged_address |= (bugged_CLCT2 & ((1 << 2) - 1)) << (0 + 7 + 6 + 1 + 1 + 3);
0616       bugged_CLCT2 = (bugged_address >> (0 + 7 + 5 + 1 + 1 + 3)) & ((1 << 2) - 1);  // bad
0617 
0618       CLCT2 = bugged_CLCT2;
0619       CLCT2 = get_signed_int(CLCT2, CLCT2Sign);
0620 
0621     }  // end if mode_inv == 14
0622   }
0623 
0624   // Get pT from XML (forest)
0625   const int(*mode_variables)[6] = aux().getModeVariables();
0626 
0627   std::vector<int> variables = {dPhi12,   dPhi13,   dPhi14,   dPhi23,   dPhi24, dPhi34, dTheta12, dTheta13,
0628                                 dTheta14, dTheta23, dTheta24, dTheta34, CLCT1,  CLCT2,  CLCT3,    CLCT4,
0629                                 CSCID1,   CSCID2,   CSCID3,   CSCID4,   FR1,    FR2,    FR3,      FR4};
0630 
0631   std::vector<double> tree_data;
0632   tree_data.push_back(1.0);
0633   tree_data.push_back(eta);
0634 
0635   for (int i = 0; i < 6; i++) {  // loop over 6 variables (or less)
0636     int mv = mode_variables[mode_inv - 3][i];
0637     if (mv != -999) {
0638       int v = variables.at(mv);
0639       if (!(mode_inv == 13 && i == 3)) {  // somehow this uses CSCID1
0640         emtf_assert(v != -999);
0641       }
0642       tree_data.push_back(v);
0643     } else {
0644       tree_data.push_back(0);  // pad with zeroes, somehow BDT tries to access out of bounds
0645     }
0646   }
0647 
0648   if (verbose_ > 2) {
0649     std::cout << "mode_inv: " << mode_inv << " variables: ";
0650     for (const auto& v : tree_data)
0651       std::cout << v << " ";
0652     std::cout << std::endl;
0653   }
0654 
0655   auto tree_event = std::make_unique<emtf::Event>();
0656   tree_event->predictedValue = 0;  // must explicitly initialize
0657   tree_event->data = tree_data;
0658 
0659   // forests_.at(mode_inv).predictEvent(tree_event.get(), 64);
0660   emtf::Forest& forest = const_cast<emtf::Forest&>(forests_.at(mode_inv));
0661   forest.predictEvent(tree_event.get(), 64);
0662 
0663   float tmp_pt = tree_event->predictedValue;  // is actually 1/pT
0664 
0665   if (verbose_ > 1) {
0666     std::cout << "mode_inv: " << mode_inv << " 1/pT: " << tmp_pt << std::endl;
0667     std::cout << "dPhi12: " << dPhi12 << " dPhi13: " << dPhi13 << " dPhi14: " << dPhi14 << " dPhi23: " << dPhi23
0668               << " dPhi24: " << dPhi24 << " dPhi34: " << dPhi34 << std::endl;
0669     std::cout << "dTheta12: " << dTheta12 << " dTheta13: " << dTheta13 << " dTheta14: " << dTheta14
0670               << " dTheta23: " << dTheta23 << " dTheta24: " << dTheta24 << " dTheta34: " << dTheta34 << std::endl;
0671     std::cout << "CLCT1: " << CLCT1 << " CLCT2: " << CLCT2 << " CLCT3: " << CLCT3 << " CLCT4: " << CLCT4 << std::endl;
0672     std::cout << "CSCID1: " << CSCID1 << " CSCID2: " << CSCID2 << " CSCID3: " << CSCID3 << " CSCID4: " << CSCID4
0673               << std::endl;
0674     std::cout << "FR1: " << FR1 << " FR2: " << FR2 << " FR3: " << FR3 << " FR4: " << FR4 << std::endl;
0675   }
0676 
0677   if (bugNegPt_) {
0678     pt = (tmp_pt == 0) ? tmp_pt : 1.0 / tmp_pt;
0679     if (pt < 0.0)
0680       pt = 1.0;
0681     if (pt > 200.0)
0682       pt = 200.0;
0683 
0684   } else {
0685     if (tmp_pt < 0.0)
0686       tmp_pt = 1.0 / 7000;
0687     pt = (tmp_pt == 0) ? tmp_pt : 1.0 / tmp_pt;
0688   }
0689 
0690   emtf_assert(pt > 0);
0691   return pt;
0692 }
0693 
0694 // Not implemented for 2016
0695 float PtAssignmentEngine2016::calculate_pt_xml(const EMTFTrack& track) const {
0696   float pt = 0.;
0697 
0698   return pt;
0699 }