CMS 3D CMS Logo

GoldenPatternResult.cc
Go to the documentation of this file.
3 
5 
6 #include <iostream>
7 #include <ostream>
8 #include <iomanip>
9 #include <cmath>
10 
13 
17  : finalise([this]() { finalise0(); }), omtfConfig(omtfConfig) {
18  if (omtfConfig)
20 }
21 
24 
25 void GoldenPatternResult::set(int refLayer_, int phi, int eta, int refHitPhi) {
26  if (isValid() && this->refLayer != refLayer_) {
27  std::cout << __FUNCTION__ << " " << __LINE__ << " this->refLayer " << this->refLayer << " refLayer_ " << refLayer_
28  << std::endl;
29  }
30  assert(!isValid() || this->refLayer == refLayer_);
31 
32  this->refLayer = refLayer_;
33  this->phi = phi;
34  this->eta = eta;
35  this->refHitPhi = refHitPhi;
36 }
37 
38 void GoldenPatternResult::setStubResult(float pdfVal, bool valid, int pdfBin, int layer, MuonStubPtr stub) {
39  if (valid) {
40  //pdfSum and firedLayerBits is calculated in finaliseX()
41  firedLayerBits |= (1 << layer);
42  }
43  stubResults[layer] = StubResult(pdfVal, valid, pdfBin, layer, stub);
44 
45  //stub result is added even thought it is not valid since this might be needed for debugging or optimization
46 }
47 
49  if (stubResult.getValid()) {
50  //pdfSum and firedLayerBits is calculated in finaliseX()
51  firedLayerBits |= (1 << layer);
52  }
53  stubResults[layer] = stubResult;
54 
55  //stub result is added even thought it is not valid since this might be needed for debugging or optimization
56 }
57 
61  this->omtfConfig = omtfConfig;
62 
64 
65  if (finalizeFunction == 1)
66  finalise = [this]() { finalise1(); };
67  else if (finalizeFunction == 2)
68  finalise = [this]() { finalise2(); };
69  else if (finalizeFunction == 3)
70  finalise = [this]() { finalise3(); };
71  else if (finalizeFunction == 5)
72  finalise = [this]() { finalise5(); };
73  else if (finalizeFunction == 6)
74  finalise = [this]() { finalise6(); };
75  else if (finalizeFunction == 7)
76  finalise = [this]() { finalise7(); };
77  else if (finalizeFunction == 8)
78  finalise = [this]() { finalise8(); };
79  else if (finalizeFunction == 9)
80  finalise = [this]() { finalise9(); };
81  else if (finalizeFunction == 10)
82  finalise = [this]() { finalise10(); };
83  else if (finalizeFunction == 11)
84  finalise = [this]() { finalise11(); };
85  else
86  finalise = [this]() { finalise0(); };
87 
89  reset();
90 }
91 
93  for (auto& stubResult : stubResults) {
94  stubResult.reset();
95  }
96  valid = false;
97  refLayer = -1;
98  phi = 0;
99  eta = 0;
100  pdfSum = 0;
101  pdfSumUnconstr = 0;
102  firedLayerCnt = 0;
103  firedLayerBits = 0;
104  refHitPhi = 0;
105  gpProbability1 = 0;
106  gpProbability2 = 0;
107 }
108 
111 //default version
113  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
114  unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer);
115  //here we require that in case of the DT layers, both phi and phiB is fired
116  if (firedLayerBits & (1 << connectedLayer)) {
117  if (firedLayerBits & (1 << iLogicLayer)) {
118  //now in the GoldenPattern::process1Layer1RefLayer the pdf bin 0 is returned when the layer is not fired, so this is 'if' is to assured that this pdf val is not added here
119  pdfSum += stubResults[iLogicLayer].getPdfVal();
120 
121  if (omtfConfig->fwVersion() <= 4) {
122  if (!omtfConfig->getBendingLayers().count(iLogicLayer))
123  //in DT case, the phi and phiB layers are threaded as one, so the firedLayerCnt is increased only for the phi layer
124  firedLayerCnt++;
125  } else
126  firedLayerCnt++;
127  }
128  } else {
129  firedLayerBits &= ~(1 << iLogicLayer);
130  }
131  }
132 
133  valid = true;
134  //by default result becomes valid here, but can be overwritten later
135 }
136 
139 //for the algo version with thresholds
141  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
142  //in this version we do not require that both phi and phiB is fired (non-zero), we thread them just independent
143  //watch out that then the number of fired layers is bigger, and the cut on the minimal number of fired layers does not work in the same way as when the dt chamber is counted as one layer
144  //TODO check if it affects performance
145  pdfSum += stubResults[iLogicLayer].getPdfVal();
146  firedLayerCnt += ((firedLayerBits & (1 << iLogicLayer)) != 0);
147  }
148 
149  valid = true;
150  //by default result becomes valid here, but can be overwritten later
151 }
152 
155 //multiplication of PDF values instead of sum
157  pdfSum = 1.;
158  firedLayerCnt = 0;
159  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
160  unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer);
161  //here we require that in case of the DT layers, both phi and phiB is fired
162  if (firedLayerBits & (1 << connectedLayer)) {
163  //now in the GoldenPattern::process1Layer1RefLayer the pdf bin 0 is returned when the layer is not fired, so this is 'if' is to assured that this pdf val is not added here
164  if (firedLayerBits & (1 << iLogicLayer)) {
165  pdfSum *= stubResults[iLogicLayer].getPdfVal();
166  //in DT case, the phi and phiB layers are threaded as one, so the firedLayerCnt is increased only for the phi layer
167  if (!omtfConfig->getBendingLayers().count(iLogicLayer))
168  firedLayerCnt++;
169  }
170  } else {
171  firedLayerBits &= ~(1 << iLogicLayer);
172  }
173  }
174 
175  if (firedLayerCnt < 3)
176  pdfSum = 0;
177 
178  valid = true;
179  //by default result becomes valid here, but can be overwritten later
180 }
181 
184 //for patterns generation
186  firedLayerCnt = 0;
187  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
188  //in this version we do not require that both phi and phiB is fired (non-zero), we thread them just independent
189  //watch out that then the number of fired layers is bigger, and the cut on the minimal number of fired layers dies not work in the same way as when the dt chamber is counted as one layer
190  //TODO check if it affects performance
191  pdfSum += stubResults[iLogicLayer].getPdfVal();
192 
193  if (stubResults[iLogicLayer].getMuonStub())
194  firedLayerCnt++;
195  }
196 
197  valid = true;
198  //by default result becomes valid here, but can be overwritten later
199 }
200 
202  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
203  unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer);
204 
205  if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired
206  if ((firedLayerBits & (1 << iLogicLayer)) && (firedLayerBits & (1 << connectedLayer))) {
207  pdfSum += stubResults[iLogicLayer].getPdfVal();
208  firedLayerCnt++;
209  } else {
210  firedLayerBits &= ~(1 << iLogicLayer);
211  stubResults[iLogicLayer].setValid(false);
212  //in principle the stun should be also removed from the stubResults[iLogicLayer], on the other hand ini this way can be used e.g. for debug
213  }
214  } else if (firedLayerBits & (1 << iLogicLayer)) {
215  pdfSum += stubResults[iLogicLayer].getPdfVal();
216  firedLayerCnt++;
217  }
218  }
219 
220  valid = true;
221  //by default result becomes valid here, but can be overwritten later
222 }
223 
225  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
226  unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer);
227 
228  if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired
229  if ((firedLayerBits & (1 << iLogicLayer)) && (firedLayerBits & (1 << connectedLayer)) &&
230  (stubResults[iLogicLayer].getMuonStub()->qualityHw >= 4)) {
231  pdfSum += stubResults[iLogicLayer].getPdfVal();
232  firedLayerCnt++;
233  } else {
234  firedLayerBits &= ~(1 << iLogicLayer);
235  stubResults[iLogicLayer].setValid(false);
236  //in principle the stun should be also removed from the stubResults[iLogicLayer], on the other hand ini this way can be used e.g. for debug
237  }
238  } else if (firedLayerBits & (1 << iLogicLayer)) {
239  pdfSum += stubResults[iLogicLayer].getPdfVal();
240  firedLayerCnt++;
241  }
242  }
243 
244  valid = true;
245  //by default result becomes valid here, but can be overwritten later
246 }
247 
249  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
250  pdfSum += stubResults[iLogicLayer].getPdfVal();
251  if (firedLayerBits & (1 << iLogicLayer)) {
252  firedLayerCnt++;
253  }
254  }
255 
256  valid = true;
257  //by default result becomes valid here, but can be overwritten later
258 }
259 
261  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
262  pdfSum += stubResults[iLogicLayer].getPdfVal(); //pdfSum is counted always
263 
264  unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer);
265  if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired
266  if ((firedLayerBits & (1 << iLogicLayer)) && (firedLayerBits & (1 << connectedLayer))) {
267  firedLayerCnt++;
268  } else {
269  firedLayerBits &= ~(1 << iLogicLayer);
270  stubResults[iLogicLayer].setValid(false);
271  //in principle the stub should be also removed from the stubResults[iLogicLayer], on the other hand in this way can be used e.g. for debug
272  }
273  } else if (firedLayerBits & (1 << iLogicLayer)) {
274  firedLayerCnt++;
275  }
276  }
277 
278  valid = true;
279  //by default result becomes valid here, but can be overwritten later
280 }
281 
283  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
284  unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer);
285 
286  if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired
287  if (firedLayerBits & (1 << iLogicLayer)) {
288  if (firedLayerBits & (1 << connectedLayer)) {
289  firedLayerCnt++;
290  pdfSum += stubResults[iLogicLayer].getPdfVal();
291  } else {
292  firedLayerBits &= ~(1 << iLogicLayer);
293  stubResults[iLogicLayer].setValid(false);
294  //there was hit, but it did not fit to the pdf - this is not possible here, since the bending layer is fired here
295  //therefore there is no sense to apply the penalty when the stubResults[iLogicLayer].getPdfVal() == 0
296  //so in this case simply pdfSum += 0;
297  }
298  } else {
299  if (stubResults[iLogicLayer].getPdfVal() == 0)
300  //there is a hit, but does not fit to the pdf (therefore in firedLayerBits is 0, but getPdfVal() is not 0), so apply the penalty (-32)
301  //N.B it is possible only with the patterns having "no hit value" and with noHitValueInPdf = True
302  pdfSum -= 32; // penaly
303  else
304  pdfSum += stubResults[iLogicLayer].getPdfVal(); //bending layer not fired at all
305  }
306  } else {
307  if (iLogicLayer < 10 && stubResults[iLogicLayer].getPdfVal() == 0)
308  pdfSum -= 32; // penaly
309  else
310  pdfSum += stubResults[iLogicLayer].getPdfVal();
311  if (firedLayerBits & (1 << iLogicLayer)) { //pdfSum is counted always
312  firedLayerCnt++;
313  }
314  }
315  }
316 
317  valid = true;
318  //by default result becomes valid here, but can be overwritten later
319 }
320 
322  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
323  unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer);
324 
325  if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired
326  if (firedLayerBits & (1 << iLogicLayer)) {
327  if (firedLayerBits & (1 << connectedLayer)) {
328  firedLayerCnt++;
329  pdfSum += stubResults[iLogicLayer].getPdfVal();
330  } else {
331  firedLayerBits &= ~(1 << iLogicLayer);
332  stubResults[iLogicLayer].setValid(false);
333  //there is no sense to apply the penalty in this case,
334  //because as the layer is fired, the stubResults[iLogicLayer].getPdfVal() cannot be 0
335  //so in this case simply pdfSum += 0;
336  }
337  } else {
338  //the penalty is not applied here when the phiB does not fit to the pdf
339  //because when extrapolation from the ref layer using the phiB is applied
340  //it "normal" for the displaced muons to not fit to the pdf
341  pdfSum += stubResults[iLogicLayer].getPdfVal();
342  }
343  } else {
344  if (iLogicLayer < 10 && stubResults[iLogicLayer].getPdfVal() == 0)
345  pdfSum -= 32; // penaly
346  else
347  pdfSum += stubResults[iLogicLayer].getPdfVal();
348  if (firedLayerBits & (1 << iLogicLayer)) { //pdfSum is counted always
349  firedLayerCnt++;
350  }
351  }
352  }
353 
354  if ((omtfConfig->usePhiBExtrapolationMB1() && refLayer == 0) ||
356  auto refLayerLogicNumber = omtfConfig->getRefToLogicNumber()[refLayer];
357  //Unconstrained pt is obtained by not including the pdfValue from the phiB of the refHit
358  //TODO get logic layer from connectedLayer
359  pdfSumUnconstr = pdfSum - stubResults[refLayerLogicNumber + 1].getPdfVal();
360  //here there is an issue with the firedLayerBits and quality assignment:
361  //in case if the displaced muon the phiB layer of the ref hit might not be fired (pdfVal might be 0)
362  //which in principle has no sense, because by the displaced algorithm construction it is fired
363  //an effect of that is that some fraction of displaced muons get the quality 8 assigned
364  //the efficiency difference between quality 8 and 12 seems to be at a level of 1-2%
365  //but in the uGT menu e.g. the L1_DoubleMu0_Upt6_IP_Min1_Upt4 uses quality >= 0, so should be OK
366 
367  //hard cut - the phiB of the refHit must fit to the pdf
368  //but this cut has sometimes side effect: there can be a muon which has has pdfSum = 0 for every pattern,
369  //then in the OMTFSorter<GoldenPatternType>::sortRefHitResults the first pattern that has FiredLayerCnt >= 3 is chosen
370  //and not the one with highest pdfSum as it should be
371  //TODO what should be done is to set the pt of such a muons to 0, but after the sorter.
372  //Or maybe not - if the pt is 0, then the muon is not valid. So the displaced muon will be lost.
373  //So the way it is done now actually is good. Such a muon will have some low constrained pt probably.
374  //what can be done is to assign to it the hwPt = 1 , but not 0
375  //TODO modify this condition to use the firedLayerBits and not getPdfVal
376  //as it would be much easier for the firmware
377  if (stubResults[refLayerLogicNumber + 1].getPdfVal() == 0)
378  pdfSum = 0;
379  } else
380  pdfSumUnconstr = 0;
381 
382  valid = true;
383  //by default result becomes valid here, but can be overwritten later
384 }
385 
386 // the same as finalise10 but without:
387 //if (stubResults[refLayerLogicNumber + 1].getPdfVal() == 0)
388 // pdfSum = 0;
390  for (unsigned int iLogicLayer = 0; iLogicLayer < stubResults.size(); ++iLogicLayer) {
391  unsigned int connectedLayer = omtfConfig->getLogicToLogic().at(iLogicLayer);
392 
393  if (omtfConfig->isBendingLayer(iLogicLayer)) { //the DT phiB layer is counted only when the phi layer is fired
394  if (firedLayerBits & (1 << iLogicLayer)) {
395  if (firedLayerBits & (1 << connectedLayer)) {
396  firedLayerCnt++;
397  pdfSum += stubResults[iLogicLayer].getPdfVal();
398  } else {
399  firedLayerBits &= ~(1 << iLogicLayer);
400  stubResults[iLogicLayer].setValid(false);
401  //there is no sense to apply the penalty in this case,
402  //because as the layer is fired, the stubResults[iLogicLayer].getPdfVal() cannot be 0
403  //so in this case simply pdfSum += 0;
404  }
405  } else {
406  //the penalty is not applied here when the phiB does not fit to the pdf
407  //because when extrapolation from the ref layer using the phiB is applied
408  //it "normal" for the displaced muons to not fit to the pdf
409  pdfSum += stubResults[iLogicLayer].getPdfVal(); //bending layer not fired at all
410  }
411  } else {
412  if (iLogicLayer < 10 && stubResults[iLogicLayer].getPdfVal() == 0)
413  pdfSum -= 32; // penaly
414  else
415  pdfSum += stubResults[iLogicLayer].getPdfVal();
416  if (firedLayerBits & (1 << iLogicLayer)) { //pdfSum is counted always
417  firedLayerCnt++;
418  }
419  }
420  }
421 
422  if ((omtfConfig->usePhiBExtrapolationMB1() && refLayer == 0) ||
424  auto refLayerLogicNumber = omtfConfig->getRefToLogicNumber()[refLayer];
425  //Unconstrained pt is obtained by not including the pdfValue from the phiB of the refHit
426  //TODO get logic layer from connectedLayer
427  pdfSumUnconstr = pdfSum - stubResults[refLayerLogicNumber + 1].getPdfVal();
428 
429  } else
430  pdfSumUnconstr = 0;
431 
432  valid = true;
433  //by default result becomes valid here, but can be overwritten later
434 }
435 
438 std::ostream& operator<<(std::ostream& out, const GoldenPatternResult& gpResult) {
439  unsigned int refLayerLogicNum = gpResult.omtfConfig->getRefToLogicNumber()[gpResult.getRefLayer()];
440 
441  unsigned int sumOverFiredLayers = 0;
442  for (unsigned int iLogicLayer = 0; iLogicLayer < gpResult.stubResults.size(); ++iLogicLayer) {
443  out << " layer: " << std::setw(2) << iLogicLayer << " hit: ";
444  if (gpResult.stubResults[iLogicLayer].getMuonStub()) {
445  out << std::setw(4)
446  << (gpResult.omtfConfig->isBendingLayer(iLogicLayer)
447  ? gpResult.stubResults[iLogicLayer].getMuonStub()->phiBHw
448  : gpResult.stubResults[iLogicLayer].getMuonStub()->phiHw);
449 
450  out << " pdfBin: " << std::setw(4) << gpResult.stubResults[iLogicLayer].getPdfBin() << " pdfVal: " << std::setw(3)
451  << gpResult.stubResults[iLogicLayer].getPdfVal() << " fired " << gpResult.isLayerFired(iLogicLayer)
452  << (iLogicLayer == refLayerLogicNum ? " <<< refLayer" : "");
453 
454  if (gpResult.isLayerFired(iLogicLayer))
455  sumOverFiredLayers += gpResult.stubResults[iLogicLayer].getPdfVal();
456  } else if (gpResult.stubResults[iLogicLayer].getPdfVal()) {
457  out << " pdfVal: " << std::setw(3) << gpResult.stubResults[iLogicLayer].getPdfVal();
458  }
459  out << std::endl;
460  }
461 
462  out << " refLayer: ";
463  out << gpResult.getRefLayer() << "\t";
464 
465  out << " Sum over layers: ";
466  out << gpResult.getPdfSum() << "\t";
467 
468  out << " sumOverFiredLayers: ";
469  out << sumOverFiredLayers << "\t";
470 
471  out << " Sum over layers unconstr: ";
472  out << gpResult.getPdfSumUnconstr() << "\t";
473 
474  out << " Number of hits: ";
475  out << gpResult.getFiredLayerCnt() << "\t";
476 
477  out << " GpProbability1: ";
478  out << gpResult.getGpProbability1() << "\t";
479 
480  out << " GpProbability2: ";
481  out << gpResult.getGpProbability2() << "\t";
482 
483  out << std::endl;
484 
485  return out;
486 }
std::ostream & operator<<(std::ostream &out, const GoldenPatternResult &gpResult)
unsigned int firedLayerBits
bits representing fired logicLayers (including bending layers),
bool usePhiBExtrapolationMB2() const
PdfValueType getPdfSumUnconstr() const
double getGpProbability1() const
void set(int refLayer, int phi, int eta, int refHitPhi)
bool usePhiBExtrapolationMB1() const
const OMTFConfiguration * omtfConfig
std::function< void()> finalise
assert(be >=bs)
int getGoldenPatternResultFinalizeFunction() const
unsigned int fwVersion() const
double getGpProbability2() const
bool getValid() const
Definition: StubResult.h:27
void init(const OMTFConfiguration *omtfConfig)
void setStubResult(float pdfVal, bool valid, int pdfBin, int layer, MuonStubPtr stub)
unsigned int nLayers() const
std::shared_ptr< MuonStub > MuonStubPtr
Definition: MuonStub.h:67
const std::vector< int > & getRefToLogicNumber() const
const std::map< int, int > & getLogicToLogic() const
bool isLayerFired(unsigned int iLayer) const
unsigned int getFiredLayerCnt() const
int eta
eta at the 2nd muon station
const std::set< int > & getBendingLayers() const
PdfValueType getPdfSum() const
double pdfSum
Sum of pdfValues.
unsigned int firedLayerCnt
Number of fired layers.
bool isBendingLayer(unsigned int iLayer) const override
int phi
phi at the 2nd muon station (propagated refHitPhi)
int refHitPhi
phi of the reference hits