CMS 3D CMS Logo

PtAssignmentEngine2017.cc
Go to the documentation of this file.
4 
5 #include <cassert>
6 #include <iostream>
7 #include <sstream>
8 
10  static const PtAssignmentEngineAux2017
11  instance; // KK: arguable design solution, but const qualifier makes it thread-safe anyway
12  return instance;
13 }
14 
15 float PtAssignmentEngine2017::scale_pt(const float pt, const int mode) const {
16  if (not(ptLUTVersion_ >= 6)) {
17  edm::LogError("L1T") << "ptLUTVersion_ = " << ptLUTVersion_;
18  return 0;
19  }
20 
21  float pt_xml = -99;
22  float pt_scale = -99;
23 
24  // Scaling to achieve 90% efficency at any given L1 pT threshold
25  // For now, a linear scaling based on SingleMu-quality (modes 11, 13, 14, 15), CSC+RPC tracks
26  // Should maybe scale each mode differently in the future - AWB 31.05.17
27 
28  // TRG = (1.2 + 0.015*TRG) * XML
29  // TRG = 1.2*XML / (1 - 0.015*XML)
30  // TRG / XML = 1.2 / (1 - 0.015*XML)
31 
32  // First "physics" LUTs for 2017, deployed June 7
33  if (ptLUTVersion_ >= 6) {
34  pt_xml = fmin(20., pt); // Maximum scale set by muons with XML pT = 20 GeV (scaled pT ~35 GeV)
35  pt_scale = 1.2 / (1 - 0.015 * pt_xml);
36  }
37 
38  return pt_scale;
39 }
40 
41 float PtAssignmentEngine2017::unscale_pt(const float pt, const int mode) const {
42  if (not(ptLUTVersion_ >= 6)) {
43  edm::LogError("L1T") << "ptLUTVersion_ = " << ptLUTVersion_;
44  return 0;
45  }
46 
47  float pt_unscale = -99;
48 
49  // First "physics" LUTs for 2017, deployed June 7
50  if (ptLUTVersion_ >= 6) {
51  pt_unscale = 1 / (1.2 + 0.015 * pt);
52  pt_unscale = fmax(pt_unscale, (1 - 0.015 * 20) / 1.2);
53  }
54 
55  return pt_unscale;
56 }
57 
59  address_t address = 0;
60 
61  EMTFPtLUT data = track.PtLUT();
62 
63  int mode = track.Mode();
64  int theta = track.Theta_fp();
65  int endcap = track.Endcap();
66  int nHits = (mode / 8) + ((mode % 8) / 4) + ((mode % 4) / 2) + ((mode % 2) / 1);
67  if (not(nHits > 1 && nHits < 5)) {
68  edm::LogError("L1T") << "nHits = " << nHits;
69  return 0;
70  }
71 
72  // 'A' is first station in the track, 'B' the second, etc.
73  int mode_ID = -1;
74  int iA = -1, iB = -1, iC = -1, iD = -1;
75  int iAB, iAC, iAD, iBC, iCD;
76 
77  switch (mode) { // Indices for quantities by station or station pair
78  case 15:
79  mode_ID = 0b1;
80  iA = 0;
81  iB = 1;
82  iC = 2;
83  iD = 3;
84  break;
85  case 14:
86  mode_ID = 0b11;
87  iA = 0;
88  iB = 1;
89  iC = 2;
90  break;
91  case 13:
92  mode_ID = 0b10;
93  iA = 0;
94  iB = 1;
95  iC = 3;
96  break;
97  case 11:
98  mode_ID = 0b01;
99  iA = 0;
100  iB = 2;
101  iC = 3;
102  break;
103  case 7:
104  mode_ID = 0b1;
105  iA = 1;
106  iB = 2;
107  iC = 3;
108  break;
109  case 12:
110  mode_ID = 0b111;
111  iA = 0;
112  iB = 1;
113  break;
114  case 10:
115  mode_ID = 0b110;
116  iA = 0;
117  iB = 2;
118  break;
119  case 9:
120  mode_ID = 0b101;
121  iA = 0;
122  iB = 3;
123  break;
124  case 6:
125  mode_ID = 0b100;
126  iA = 1;
127  iB = 2;
128  break;
129  case 5:
130  mode_ID = 0b011;
131  iA = 1;
132  iB = 3;
133  break;
134  case 3:
135  mode_ID = 0b010;
136  iA = 2;
137  iB = 3;
138  break;
139  default:
140  break;
141  }
142  iAB = (iA >= 0 && iB >= 0) ? iA + iB - (iA == 0) : -1;
143  iAC = (iA >= 0 && iC >= 0) ? iA + iC - (iA == 0) : -1;
144  iAD = (iA >= 0 && iD >= 0) ? 2 : -1;
145  iBC = (iB >= 0 && iC >= 0) ? iB + iC : -1;
146  iCD = (iC >= 0 && iD >= 0) ? 5 : -1;
147 
148  // Fill variable info from pT LUT data
149  int st1_ring2, dTheta;
150  int dPhiAB, dPhiBC, dPhiCD;
151  int sPhiAB, sPhiBC, sPhiCD;
152  int frA, frB;
153  int clctA, clctB, clctC, clctD;
154  int mode15_8b; // Combines track theta, stations with RPC hits, and station 1 bend information
155  int rpc_2b; // Identifies which stations have RPC hits in 3-station tracks
156 
157  st1_ring2 = data.st1_ring2;
158  if (nHits == 4) {
159  dPhiAB = data.delta_ph[iAB];
160  dPhiBC = data.delta_ph[iBC];
161  dPhiCD = data.delta_ph[iCD];
162  sPhiAB = data.sign_ph[iAB];
163  sPhiBC = (data.sign_ph[iBC] == sPhiAB);
164  sPhiCD = (data.sign_ph[iCD] == sPhiAB);
165  dTheta = data.delta_th[iAD] * (data.sign_th[iAD] ? 1 : -1);
166  frA = data.fr[iA];
167  clctA = data.cpattern[iA];
168  clctB = data.cpattern[iB];
169  clctC = data.cpattern[iC];
170  clctD = data.cpattern[iD];
171  } else if (nHits == 3) {
172  dPhiAB = data.delta_ph[iAB];
173  dPhiBC = data.delta_ph[iBC];
174  sPhiAB = data.sign_ph[iAB];
175  sPhiBC = (data.sign_ph[iBC] == sPhiAB);
176  dTheta = data.delta_th[iAC] * (data.sign_th[iAC] ? 1 : -1);
177  frA = data.fr[iA];
178  frB = data.fr[iB];
179  clctA = data.cpattern[iA];
180  clctB = data.cpattern[iB];
181  clctC = data.cpattern[iC];
182  } else if (nHits == 2) {
183  dPhiAB = data.delta_ph[iAB];
184  sPhiAB = data.sign_ph[iAB];
185  dTheta = data.delta_th[iAB] * (data.sign_th[iAB] ? 1 : -1);
186  frA = data.fr[iA];
187  frB = data.fr[iB];
188  clctA = data.cpattern[iA];
189  clctB = data.cpattern[iB];
190  }
191 
192  // Convert variables to words for pT LUT address
193  if (nHits == 4) {
194  dPhiAB = aux().getNLBdPhiBin(dPhiAB, 7, 512);
195  dPhiBC = aux().getNLBdPhiBin(dPhiBC, 5, 256);
196  dPhiCD = aux().getNLBdPhiBin(dPhiCD, 4, 256);
197  dTheta = aux().getdTheta(dTheta, 2);
198  mode15_8b = aux().get8bMode15(theta, st1_ring2, endcap, (sPhiAB == 1 ? 1 : -1), clctA, clctB, clctC, clctD);
199  } else if (nHits == 3) {
200  dPhiAB = aux().getNLBdPhiBin(dPhiAB, 7, 512);
201  dPhiBC = aux().getNLBdPhiBin(dPhiBC, 5, 256);
202  dTheta = aux().getdTheta(dTheta, 3);
203  rpc_2b = aux().get2bRPC(clctA, clctB, clctC); // Have to use un-compressed CLCT words
204  clctA = aux().getCLCT(clctA, endcap, (sPhiAB == 1 ? 1 : -1), 2);
205  theta = aux().getTheta(theta, st1_ring2, 5);
206  } else if (nHits == 2) {
207  dPhiAB = aux().getNLBdPhiBin(dPhiAB, 7, 512);
208  dTheta = aux().getdTheta(dTheta, 3);
209  clctA = aux().getCLCT(clctA, endcap, (sPhiAB == 1 ? 1 : -1), 3);
210  clctB = aux().getCLCT(clctB, endcap, (sPhiAB == 1 ? 1 : -1), 3);
211  theta = aux().getTheta(theta, st1_ring2, 5);
212  }
213 
214  // Form the pT LUT address
215  if (nHits == 4) {
216  address |= (dPhiAB & ((1 << 7) - 1)) << (0);
217  address |= (dPhiBC & ((1 << 5) - 1)) << (0 + 7);
218  address |= (dPhiCD & ((1 << 4) - 1)) << (0 + 7 + 5);
219  address |= (sPhiBC & ((1 << 1) - 1)) << (0 + 7 + 5 + 4);
220  address |= (sPhiCD & ((1 << 1) - 1)) << (0 + 7 + 5 + 4 + 1);
221  address |= (dTheta & ((1 << 2) - 1)) << (0 + 7 + 5 + 4 + 1 + 1);
222  address |= (frA & ((1 << 1) - 1)) << (0 + 7 + 5 + 4 + 1 + 1 + 2);
223  address |= (mode15_8b & ((1 << 8) - 1)) << (0 + 7 + 5 + 4 + 1 + 1 + 2 + 1);
224  address |= (mode_ID & ((1 << 1) - 1)) << (0 + 7 + 5 + 4 + 1 + 1 + 2 + 1 + 8);
225  if (not(address < pow(2, 30) && address >= pow(2, 29))) {
226  edm::LogError("L1T") << "address = " << address;
227  return 0;
228  }
229  } else if (nHits == 3) {
230  address |= (dPhiAB & ((1 << 7) - 1)) << (0);
231  address |= (dPhiBC & ((1 << 5) - 1)) << (0 + 7);
232  address |= (sPhiBC & ((1 << 1) - 1)) << (0 + 7 + 5);
233  address |= (dTheta & ((1 << 3) - 1)) << (0 + 7 + 5 + 1);
234  address |= (frA & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 3);
235  int bit = 0;
236  if (mode != 7) {
237  address |= (frB & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 3 + 1);
238  bit = 1;
239  }
240  address |= (clctA & ((1 << 2) - 1)) << (0 + 7 + 5 + 1 + 3 + 1 + bit);
241  address |= (rpc_2b & ((1 << 2) - 1)) << (0 + 7 + 5 + 1 + 3 + 1 + bit + 2);
242  address |= (theta & ((1 << 5) - 1)) << (0 + 7 + 5 + 1 + 3 + 1 + bit + 2 + 2);
243  if (mode != 7) {
244  address |= (mode_ID & ((1 << 2) - 1)) << (0 + 7 + 5 + 1 + 3 + 1 + bit + 2 + 2 + 5);
245  if (not(address < pow(2, 29) && address >= pow(2, 27))) {
246  edm::LogError("L1T") << "address = " << address;
247  return 0;
248  }
249  } else {
250  address |= (mode_ID & ((1 << 1) - 1)) << (0 + 7 + 5 + 1 + 3 + 1 + bit + 2 + 2 + 5);
251  if (not(address < pow(2, 27) && address >= pow(2, 26))) {
252  edm::LogError("L1T") << "address = " << address;
253  return 0;
254  }
255  }
256  } else if (nHits == 2) {
257  address |= (dPhiAB & ((1 << 7) - 1)) << (0);
258  address |= (dTheta & ((1 << 3) - 1)) << (0 + 7);
259  address |= (frA & ((1 << 1) - 1)) << (0 + 7 + 3);
260  address |= (frB & ((1 << 1) - 1)) << (0 + 7 + 3 + 1);
261  address |= (clctA & ((1 << 3) - 1)) << (0 + 7 + 3 + 1 + 1);
262  address |= (clctB & ((1 << 3) - 1)) << (0 + 7 + 3 + 1 + 1 + 3);
263  address |= (theta & ((1 << 5) - 1)) << (0 + 7 + 3 + 1 + 1 + 3 + 3);
264  address |= (mode_ID & ((1 << 3) - 1)) << (0 + 7 + 3 + 1 + 1 + 3 + 3 + 5);
265  if (not(address < pow(2, 26) && address >= pow(2, 24))) {
266  edm::LogError("L1T") << "address = " << address;
267  return 0;
268  }
269  }
270 
271  return address;
272 } // End function: PtAssignmentEngine2017::calculate_address()
273 
274 // Calculate XML pT from address
276  // std::cout << "Inside calculate_pt_xml, examining address: ";
277  // for (int j = 0; j < 30; j++) {
278  // std::cout << ((address >> (29 - j)) & 0x1);
279  // if ((j % 5) == 4) std::cout << " ";
280  // }
281  // std::cout << std::endl;
282 
283  float pt_xml = 0.;
284  int nHits = -1, mode = -1;
285 
286  if (not(address < pow(2, 30))) {
287  edm::LogError("L1T") << "address = " << address;
288  return 0;
289  }
290  if (address >= pow(2, 29)) {
291  nHits = 4;
292  mode = 15;
293  } else if (address >= pow(2, 27)) {
294  nHits = 3;
295  } else if (address >= pow(2, 26)) {
296  nHits = 3;
297  mode = 7;
298  } else if (address >= pow(2, 24)) {
299  nHits = 2;
300  } else
301  return pt_xml;
302 
303  // Variables to unpack from the pT LUT address
304  int mode_ID, theta, dTheta;
305  int dPhiAB, dPhiBC = -1, dPhiCD = -1;
306  int sPhiAB, sPhiBC = -1, sPhiCD = -1;
307  int frA, frB = -1;
308  int clctA, clctB = -1;
309  int rpcA, rpcB, rpcC, rpcD;
310  int endcap = 1;
311  sPhiAB = 1; // Assume positive endcap and dPhiAB for unpacking CLCT bend
312  int mode15_8b = -1; // Combines track theta, stations with RPC hits, and station 1 bend information
313  int rpc_2b = -1; // Identifies which stations have RPC hits in 3-station tracks
314 
315  // Unpack variable words from the pT LUT address
316  if (nHits == 4) {
317  dPhiAB = (address >> (0) & ((1 << 7) - 1));
318  dPhiBC = (address >> (0 + 7) & ((1 << 5) - 1));
319  dPhiCD = (address >> (0 + 7 + 5) & ((1 << 4) - 1));
320  sPhiBC = (address >> (0 + 7 + 5 + 4) & ((1 << 1) - 1));
321  sPhiCD = (address >> (0 + 7 + 5 + 4 + 1) & ((1 << 1) - 1));
322  dTheta = (address >> (0 + 7 + 5 + 4 + 1 + 1) & ((1 << 2) - 1));
323  frA = (address >> (0 + 7 + 5 + 4 + 1 + 1 + 2) & ((1 << 1) - 1));
324  mode15_8b = (address >> (0 + 7 + 5 + 4 + 1 + 1 + 2 + 1) & ((1 << 8) - 1));
325  mode_ID = (address >> (0 + 7 + 5 + 4 + 1 + 1 + 2 + 1 + 8) & ((1 << 1) - 1));
326  if (not(address < pow(2, 30))) {
327  edm::LogError("L1T") << "address = " << address;
328  return 0;
329  }
330  } else if (nHits == 3) {
331  dPhiAB = (address >> (0) & ((1 << 7) - 1));
332  dPhiBC = (address >> (0 + 7) & ((1 << 5) - 1));
333  sPhiBC = (address >> (0 + 7 + 5) & ((1 << 1) - 1));
334  dTheta = (address >> (0 + 7 + 5 + 1) & ((1 << 3) - 1));
335  frA = (address >> (0 + 7 + 5 + 1 + 3) & ((1 << 1) - 1));
336  int bit = 0;
337  if (mode != 7) {
338  frB = (address >> (0 + 7 + 5 + 1 + 3 + 1) & ((1 << 1) - 1));
339  bit = 1;
340  }
341  clctA = (address >> (0 + 7 + 5 + 1 + 3 + 1 + bit) & ((1 << 2) - 1));
342  rpc_2b = (address >> (0 + 7 + 5 + 1 + 3 + 1 + bit + 2) & ((1 << 2) - 1));
343  theta = (address >> (0 + 7 + 5 + 1 + 3 + 1 + bit + 2 + 2) & ((1 << 5) - 1));
344  if (mode != 7) {
345  mode_ID = (address >> (0 + 7 + 5 + 1 + 3 + 1 + bit + 2 + 2 + 5) & ((1 << 2) - 1));
346  if (not(address < pow(2, 29))) {
347  edm::LogError("L1T") << "address = " << address;
348  return 0;
349  }
350  } else {
351  mode_ID = (address >> (0 + 7 + 5 + 1 + 3 + 1 + bit + 2 + 2 + 5) & ((1 << 1) - 1));
352  if (not(address < pow(2, 27))) {
353  edm::LogError("L1T") << "address = " << address;
354  return 0;
355  }
356  }
357  } else if (nHits == 2) {
358  dPhiAB = (address >> (0) & ((1 << 7) - 1));
359  dTheta = (address >> (0 + 7) & ((1 << 3) - 1));
360  frA = (address >> (0 + 7 + 3) & ((1 << 1) - 1));
361  frB = (address >> (0 + 7 + 3 + 1) & ((1 << 1) - 1));
362  clctA = (address >> (0 + 7 + 3 + 1 + 1) & ((1 << 3) - 1));
363  clctB = (address >> (0 + 7 + 3 + 1 + 1 + 3) & ((1 << 3) - 1));
364  theta = (address >> (0 + 7 + 3 + 1 + 1 + 3 + 3) & ((1 << 5) - 1));
365  mode_ID = (address >> (0 + 7 + 3 + 1 + 1 + 3 + 3 + 5) & ((1 << 3) - 1));
366  if (not(address < pow(2, 26))) {
367  edm::LogError("L1T") << "address = " << address;
368  return 0;
369  }
370  }
371 
372  // Infer track mode (and stations with hits) from mode_ID
373  if (nHits == 3 && mode != 7) {
374  switch (mode_ID) {
375  case 0b11:
376  mode = 14;
377  break;
378  case 0b10:
379  mode = 13;
380  break;
381  case 0b01:
382  mode = 11;
383  break;
384  default:
385  break;
386  }
387  } else if (nHits == 2) {
388  switch (mode_ID) {
389  case 0b111:
390  mode = 12;
391  break;
392  case 0b110:
393  mode = 10;
394  break;
395  case 0b101:
396  mode = 9;
397  break;
398  case 0b100:
399  mode = 6;
400  break;
401  case 0b011:
402  mode = 5;
403  break;
404  case 0b010:
405  mode = 3;
406  break;
407  default:
408  break;
409  }
410  }
411 
412  if (not(mode > 0)) {
413  edm::LogError("L1T") << "mode = " << mode;
414  return 0;
415  }
416 
417  // Un-compress words from address
418  // For most variables (e.g. theta, dTheta, CLCT) don't need to unpack, since compressed version was used in training
419  int St1_ring2 = -1;
420  if (nHits == 4) {
421  dPhiAB = aux().getdPhiFromBin(dPhiAB, 7, 512);
422  dPhiBC = aux().getdPhiFromBin(dPhiBC, 5, 256) * (sPhiBC == 1 ? 1 : -1);
423  dPhiCD = aux().getdPhiFromBin(dPhiCD, 4, 256) * (sPhiCD == 1 ? 1 : -1);
424  aux().unpack8bMode15(mode15_8b, theta, St1_ring2, endcap, (sPhiAB == 1 ? 1 : -1), clctA, rpcA, rpcB, rpcC, rpcD);
425 
426  // // Check bit-wise compression / de-compression
427  // if (not( dTheta == aux().getdTheta( aux().unpackdTheta( dTheta, 2), 2) );
428  // { edm::LogError("L1T") << " = " << ; return; }
429  } else if (nHits == 3) {
430  dPhiAB = aux().getdPhiFromBin(dPhiAB, 7, 512);
431  dPhiBC = aux().getdPhiFromBin(dPhiBC, 5, 256) * (sPhiBC == 1 ? 1 : -1);
432  St1_ring2 = aux().unpackSt1Ring2(theta, 5);
433  aux().unpack2bRPC(rpc_2b, rpcA, rpcB, rpcC);
434 
435  // // Check bit-wise compression / de-compression
436  // if (not( dTheta == aux().getdTheta( aux().unpackdTheta( dTheta, 3), 3) );
437  // { edm::LogError("L1T") << " = " << ; return; }
438  // if (not( clctA == aux().getCLCT( aux().unpackCLCT( clctA, endcap, (sPhiAB == 1 ? 1 : -1), 2),
439  // endcap, (sPhiAB == 1 ? 1 : -1), 2) );
440  // { edm::LogError("L1T") << " = " << ; return; }
441  // int theta_unp = theta;
442  // aux().unpackTheta( theta_unp, St1_ring2, 5 );
443  // if (not( theta == aux().getTheta(theta_unp, St1_ring2, 5) );
444  // { edm::LogError("L1T") << " = " << ; return; }
445  } else if (nHits == 2) {
446  dPhiAB = aux().getdPhiFromBin(dPhiAB, 7, 512);
447  St1_ring2 = aux().unpackSt1Ring2(theta, 5);
448 
449  // // Check bit-wise compression / de-compression
450  // if (not( dTheta == aux().getdTheta( aux().unpackdTheta( dTheta, 3), 3) );
451  // { edm::LogError("L1T") << " = " << ; return; }
452  // if (not( clctA == aux().getCLCT( aux().unpackCLCT( clctA, endcap, (sPhiAB == 1 ? 1 : -1), 3),
453  // endcap, (sPhiAB == 1 ? 1 : -1), 3) );
454  // { edm::LogError("L1T") << " = " << ; return; }
455  // if (not( clctB == aux().getCLCT( aux().unpackCLCT( clctB, endcap, (sPhiAB == 1 ? 1 : -1), 3),
456  // endcap, (sPhiAB == 1 ? 1 : -1), 3) );
457  // { edm::LogError("L1T") << " = " << ; return; }
458  // int theta_unp = theta;
459  // aux().unpackTheta( theta_unp, St1_ring2, 5 );
460  // if (not( theta == aux().getTheta(theta_unp, St1_ring2, 5) );
461  // { edm::LogError("L1T") << " = " << ; return; }
462  }
463 
464  // Fill vectors of variables for XMLs
465  // KK: sequence of variables here should exaclty match <Variables> block produced by TMVA
466  std::vector<int> predictors;
467 
468  // Variables for input to XMLs
469  int dPhiSum4, dPhiSum4A, dPhiSum3, dPhiSum3A, outStPhi;
470 
471  // Convert words into variables for XMLs
472  if (nHits == 4) {
473  predictors = {
474  theta, St1_ring2, dPhiAB, dPhiBC, dPhiCD, dPhiAB + dPhiBC, dPhiAB + dPhiBC + dPhiCD, dPhiBC + dPhiCD, frA, clctA};
475 
476  CalcDeltaPhiSums(dPhiSum4,
477  dPhiSum4A,
478  dPhiSum3,
479  dPhiSum3A,
480  outStPhi,
481  dPhiAB,
482  dPhiAB + dPhiBC,
483  dPhiAB + dPhiBC + dPhiCD,
484  dPhiBC,
485  dPhiBC + dPhiCD,
486  dPhiCD);
487 
488  int tmp[10] = {dPhiSum4, dPhiSum4A, dPhiSum3, dPhiSum3A, outStPhi, dTheta, rpcA, rpcB, rpcC, rpcD};
489  predictors.insert(predictors.end(), tmp, tmp + 10);
490  } else if (nHits == 3) {
491  if (mode == 14)
492  predictors = {theta, St1_ring2, dPhiAB, dPhiBC, dPhiAB + dPhiBC, frA, frB, clctA, dTheta, rpcA, rpcB, rpcC};
493  else if (mode == 13)
494  predictors = {theta, St1_ring2, dPhiAB, dPhiAB + dPhiBC, dPhiBC, frA, frB, clctA, dTheta, rpcA, rpcB, rpcC};
495  else if (mode == 11)
496  predictors = {theta, St1_ring2, dPhiBC, dPhiAB, dPhiAB + dPhiBC, frA, frB, clctA, dTheta, rpcA, rpcB, rpcC};
497  else if (mode == 7)
498  predictors = {theta, dPhiAB, dPhiBC, dPhiAB + dPhiBC, frA, clctA, dTheta, rpcA, rpcB, rpcC};
499  } else if (nHits == 2 && mode >= 8) {
500  predictors = {theta, St1_ring2, dPhiAB, frA, frB, clctA, clctB, dTheta, (clctA == 0), (clctB == 0)};
501  } else if (nHits == 2 && mode < 8) {
502  predictors = {theta, dPhiAB, frA, frB, clctA, clctB, dTheta, (clctA == 0), (clctB == 0)};
503  } else {
504  edm::LogError("L1T") << "nHits = " << nHits << ", mode = " << mode;
505  return 0;
506  }
507 
508  // Retreive pT from XMLs
509  std::vector<double> tree_data(predictors.cbegin(), predictors.cend());
510 
511  auto tree_event = std::make_unique<emtf::Event>();
512  tree_event->predictedValue = 0;
513  tree_event->data = tree_data;
514 
515  // forests_.at(mode).predictEvent(tree_event.get(), 400);
516  emtf::Forest& forest = const_cast<emtf::Forest&>(forests_.at(mode));
517  forest.predictEvent(tree_event.get(), 400);
518 
519  // // Adjust this for different XMLs
520  // float log2_pt = tree_event->predictedValue;
521  // pt_xml = pow(2, fmax(0.0, log2_pt)); // Protect against negative values
522 
523  float inv_pt = tree_event->predictedValue;
524  pt_xml = 1.0 / fmax(0.001, inv_pt); // Protect against negative values
525 
526  return pt_xml;
527 
528 } // End function: float PtAssignmentEngine2017::calculate_pt_xml(const address_t& address)
529 
530 // Calculate XML pT directly from track quantities, without forming an address
532  float pt_xml = 0.;
533 
534  EMTFPtLUT data = track.PtLUT();
535 
536  auto contain = [](const std::vector<int>& vec, int elem) {
537  return (std::find(vec.begin(), vec.end(), elem) != vec.end());
538  };
539 
540  int endcap = track.Endcap();
541  int mode = track.Mode();
542  int theta = track.Theta_fp();
543  int phi = track.Phi_fp();
544  if (!contain(allowedModes_, mode))
545  return pt_xml;
546 
547  // Which stations have hits
548  int st1 = (mode >= 8);
549  int st2 = ((mode % 8) >= 4);
550  int st3 = ((mode % 4) >= 2);
551  int st4 = ((mode % 2) == 1);
552 
553  // Variables for input to XMLs
554  int dPhi_12, dPhi_13, dPhi_14, dPhi_23, dPhi_24, dPhi_34, dPhiSign;
555  int dPhiSum4, dPhiSum4A, dPhiSum3, dPhiSum3A, outStPhi;
556  int dTh_12, dTh_13, dTh_14, dTh_23, dTh_24, dTh_34;
557  int FR_1, FR_2, FR_3, FR_4;
558  int bend_1, bend_2, bend_3, bend_4;
559  int RPC_1, RPC_2, RPC_3, RPC_4;
560  int St1_ring2 = data.st1_ring2;
561 
562  int ph1 = -99, ph2 = -99, ph3 = -99, ph4 = -99;
563  int th1 = -99, th2 = -99, th3 = -99, th4 = -99;
564  int pat1 = -99, pat2 = -99, pat3 = -99, pat4 = -99;
565 
566  // Compute the original phi and theta coordinates
567  if (st2) {
568  ph2 = phi; // Track phi is from station 2 (if it exists), otherwise 3 or 4
569  th2 = theta; // Likewise for track theta
570  if (st1)
571  ph1 = ph2 - data.delta_ph[0] * (data.sign_ph[0] ? 1 : -1);
572  if (st1)
573  th1 = th2 - data.delta_th[0] * (data.sign_th[0] ? 1 : -1);
574  if (st3)
575  ph3 = ph2 + data.delta_ph[3] * (data.sign_ph[3] ? 1 : -1);
576  // Important that phi be from adjacent station pairs (see note below)
577  if (st3 && st4)
578  ph4 = ph3 + data.delta_ph[5] * (data.sign_ph[5] ? 1 : -1);
579  else if (st4)
580  ph4 = ph2 + data.delta_ph[4] * (data.sign_ph[4] ? 1 : -1);
581  // Important that theta be from first-last station pair, not adjacent pairs: delta_th values are "best" for each pair, but
582  // thanks to duplicated CSC LCTs, are not necessarily consistent (or physical) between pairs or between delta_th and delta_ph.
583  // This is an artifact of the firmware implementation of deltas: see src/AngleCalculation.cc.
584  if (st1 && st3)
585  th3 = th1 + data.delta_th[1] * (data.sign_th[1] ? 1 : -1);
586  else if (st3)
587  th3 = th2 + data.delta_th[3] * (data.sign_th[3] ? 1 : -1);
588  if (st1 && st4)
589  th4 = th1 + data.delta_th[2] * (data.sign_th[2] ? 1 : -1);
590  else if (st4)
591  th4 = th2 + data.delta_th[4] * (data.sign_th[4] ? 1 : -1);
592  } else if (st3) {
593  ph3 = phi;
594  th3 = theta;
595  if (st1)
596  ph1 = ph3 - data.delta_ph[1] * (data.sign_ph[1] ? 1 : -1);
597  if (st1)
598  th1 = th3 - data.delta_th[1] * (data.sign_th[1] ? 1 : -1);
599  if (st4)
600  ph4 = ph3 + data.delta_ph[5] * (data.sign_ph[5] ? 1 : -1);
601  if (st1 && st4)
602  th4 = th1 + data.delta_th[2] * (data.sign_th[2] ? 1 : -1);
603  else if (st4)
604  th4 = th3 + data.delta_th[5] * (data.sign_th[5] ? 1 : -1);
605  } else if (st4) {
606  ph4 = phi;
607  th4 = theta;
608  if (st1)
609  ph1 = ph4 - data.delta_ph[2] * (data.sign_ph[2] ? 1 : -1);
610  if (st1)
611  th1 = th4 - data.delta_th[2] * (data.sign_th[2] ? 1 : -1);
612  }
613 
614  if (st1)
615  pat1 = data.cpattern[0];
616  if (st2)
617  pat2 = data.cpattern[1];
618  if (st3)
619  pat3 = data.cpattern[2];
620  if (st4)
621  pat4 = data.cpattern[3];
622 
623  // BEGIN: Identical (almost) to BDT training code in EMTFPtAssign2017/PtRegression_Apr_2017.C
624 
625  theta = CalcTrackTheta(th1, th2, th3, th4, St1_ring2, mode, true);
626 
627  CalcDeltaPhis(dPhi_12,
628  dPhi_13,
629  dPhi_14,
630  dPhi_23,
631  dPhi_24,
632  dPhi_34,
633  dPhiSign,
634  dPhiSum4,
635  dPhiSum4A,
636  dPhiSum3,
637  dPhiSum3A,
638  outStPhi,
639  ph1,
640  ph2,
641  ph3,
642  ph4,
643  mode,
644  true);
645 
646  CalcDeltaThetas(dTh_12, dTh_13, dTh_14, dTh_23, dTh_24, dTh_34, th1, th2, th3, th4, mode, true);
647 
648  FR_1 = (st1 ? data.fr[0] : -99);
649  FR_2 = (st2 ? data.fr[1] : -99);
650  FR_3 = (st3 ? data.fr[2] : -99);
651  FR_4 = (st4 ? data.fr[3] : -99);
652 
653  CalcBends(bend_1, bend_2, bend_3, bend_4, pat1, pat2, pat3, pat4, dPhiSign, endcap, mode, true);
654 
655  RPC_1 = (st1 ? (pat1 == 0) : -99);
656  RPC_2 = (st2 ? (pat2 == 0) : -99);
657  RPC_3 = (st3 ? (pat3 == 0) : -99);
658  RPC_4 = (st4 ? (pat4 == 0) : -99);
659 
660  CalcRPCs(RPC_1, RPC_2, RPC_3, RPC_4, mode, St1_ring2, theta, true);
661 
662  // END: Identical (almost) to BDT training code in EMTFPtAssign2017/PtRegression_Apr_2017.C
663 
664  // Fill vectors of variables for XMLs
665  // KK: sequence of variables here should exaclty match <Variables> block produced by TMVA
666  std::vector<int> predictors;
667  switch (mode) {
668  case 15: // 1-2-3-4
669  predictors = {theta, St1_ring2, dPhi_12, dPhi_23, dPhi_34, dPhi_13, dPhi_14, dPhi_24, FR_1, bend_1,
670  dPhiSum4, dPhiSum4A, dPhiSum3, dPhiSum3A, outStPhi, dTh_14, RPC_1, RPC_2, RPC_3, RPC_4};
671  break;
672  case 14: // 1-2-3
673  predictors = {theta, St1_ring2, dPhi_12, dPhi_23, dPhi_13, FR_1, FR_2, bend_1, dTh_13, RPC_1, RPC_2, RPC_3};
674  break;
675  case 13: // 1-2-4
676  predictors = {theta, St1_ring2, dPhi_12, dPhi_14, dPhi_24, FR_1, FR_2, bend_1, dTh_14, RPC_1, RPC_2, RPC_4};
677  break;
678  case 11: // 1-3-4
679  predictors = {theta, St1_ring2, dPhi_34, dPhi_13, dPhi_14, FR_1, FR_3, bend_1, dTh_14, RPC_1, RPC_3, RPC_4};
680  break;
681  case 7: // 2-3-4
682  predictors = {theta, dPhi_23, dPhi_34, dPhi_24, FR_2, bend_2, dTh_24, RPC_2, RPC_3, RPC_4};
683  break;
684  case 12: // 1-2
685  predictors = {theta, St1_ring2, dPhi_12, FR_1, FR_2, bend_1, bend_2, dTh_12, RPC_1, RPC_2};
686  break;
687  case 10: // 1-3
688  predictors = {theta, St1_ring2, dPhi_13, FR_1, FR_3, bend_1, bend_3, dTh_13, RPC_1, RPC_3};
689  break;
690  case 9: // 1-4
691  predictors = {theta, St1_ring2, dPhi_14, FR_1, FR_4, bend_1, bend_4, dTh_14, RPC_1, RPC_4};
692  break;
693  case 6: // 2-3
694  predictors = {theta, dPhi_23, FR_2, FR_3, bend_2, bend_3, dTh_23, RPC_2, RPC_3};
695  break;
696  case 5: // 2-4
697  predictors = {theta, dPhi_24, FR_2, FR_4, bend_2, bend_4, dTh_24, RPC_2, RPC_4};
698  break;
699  case 3: // 3-4
700  predictors = {theta, dPhi_34, FR_3, FR_4, bend_3, bend_4, dTh_34, RPC_3, RPC_4};
701  break;
702  }
703 
704  std::vector<double> tree_data(predictors.cbegin(), predictors.cend());
705 
706  auto tree_event = std::make_unique<emtf::Event>();
707  tree_event->predictedValue = 0;
708  tree_event->data = tree_data;
709 
710  // forests_.at(mode).predictEvent(tree_event.get(), 400);
711  emtf::Forest& forest = const_cast<emtf::Forest&>(forests_.at(mode));
712  forest.predictEvent(tree_event.get(), 400);
713 
714  // // Adjust this for different XMLs
715  // float log2_pt = tree_event->predictedValue;
716  // pt_xml = pow(2, fmax(0.0, log2_pt)); // Protect against negative values
717 
718  float inv_pt = tree_event->predictedValue;
719  pt_xml = 1.0 / fmax(0.001, inv_pt); // Protect against negative values
720 
721  return pt_xml;
722 
723 } // End function: float PtAssignmentEngine2017::calculate_pt_xml(const EMTFTrack& track)
int Theta_fp() const
Definition: EMTFTrack.h:167
int getTheta(int theta, int ring2, int bits=5) const
void predictEvent(Event *e, unsigned int trees)
Definition: Forest.cc:440
uint16_t sign_ph[6]
Definition: EMTFTrack.h:24
int Endcap() const
Definition: EMTFTrack.h:148
static PFTauRenderPlugin instance
float scale_pt(const float pt, const int mode=15) const override
const PtAssignmentEngineAux2017 & aux() const
int Phi_fp() const
Definition: EMTFTrack.h:170
Geom::Theta< T > theta() const
void CalcDeltaThetas(int &dTh12, int &dTh13, int &dTh14, int &dTh23, int &dTh24, int &dTh34, const int th1, const int th2, const int th3, const int th4, const int mode, const bool BIT_COMP=false)
void unpack8bMode15(int mode15_8b, int &theta, int &st1_ring2, int endcap, int sPhiAB, int &clctA, int &rpcA, int &rpcB, int &rpcC, int &rpcD) const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
uint16_t delta_ph[6]
Definition: EMTFTrack.h:22
int get2bRPC(int clctA, int clctB, int clctC) const
void unpack2bRPC(int rpc_2b, int &rpcA, int &rpcB, int &rpcC) const
uint16_t delta_th[6]
Definition: EMTFTrack.h:23
address_t calculate_address(const EMTFTrack &track) const override
int CalcTrackTheta(const int th1, const int th2, const int th3, const int th4, const int ring1, const int mode, const bool BIT_COMP=false)
Definition: PtLUTVarCalc.cc:11
void CalcDeltaPhiSums(int &dPhSum4, int &dPhSum4A, int &dPhSum3, int &dPhSum3A, int &outStPh, const int dPh12, const int dPh13, const int dPh14, const int dPh23, const int dPh24, const int dPh34)
uint16_t cpattern[4]
Definition: EMTFTrack.h:26
int getCLCT(int clct, int endcap, int dPhiSign, int bits=3) const
uint16_t fr[4]
Definition: EMTFTrack.h:27
float calculate_pt_xml(const address_t &address) const override
def elem(elemtype, innerHTML='', html_class='', kwargs)
Definition: HTMLExport.py:19
float unscale_pt(const float pt, const int mode=15) const override
void CalcDeltaPhis(int &dPh12, int &dPh13, int &dPh14, int &dPh23, int &dPh24, int &dPh34, int &dPhSign, int &dPhSum4, int &dPhSum4A, int &dPhSum3, int &dPhSum3A, int &outStPh, const int ph1, const int ph2, const int ph3, const int ph4, const int mode, const bool BIT_COMP=false)
Definition: PtLUTVarCalc.cc:40
void CalcBends(int &bend1, int &bend2, int &bend3, int &bend4, const int pat1, const int pat2, const int pat3, const int pat4, const int dPhSign, const int endcap, const int mode, const bool BIT_COMP=false)
uint16_t sign_th[6]
Definition: EMTFTrack.h:25
std::array< emtf::Forest, 16 > forests_
uint16_t st1_ring2
Definition: EMTFTrack.h:20
int getdPhiFromBin(int dPhiBin, int bits=7, int max=512) const
int getdTheta(int dTheta, int bits=3) const
int get8bMode15(int theta, int st1_ring2, int endcap, int sPhiAB, int clctA, int clctB, int clctC, int clctD) const
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
int Mode() const
Definition: EMTFTrack.h:151
void CalcRPCs(int &RPC1, int &RPC2, int &RPC3, int &RPC4, const int mode, const int st1_ring2, const int theta, const bool BIT_COMP=false)
std::vector< int > allowedModes_
tmp
align.sh
Definition: createJobs.py:716
int unpackSt1Ring2(int theta, int bits) const
EMTFPtLUT PtLUT() const
Definition: EMTFTrack.h:116
int getNLBdPhiBin(int dPhi, int bits=7, int max=512) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:30