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 pdfS
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  //bending layer fired, but not fits to the pdf, N.B works only with the patterns having "no hit value" and with noHitValueInPdf = True
407  if (stubResults[iLogicLayer].getPdfVal() == 0) {
408  //high penalty, we set the pdf value in the stubResults[iLogicLayer], so that this penalty is removed from pdfSumUnconstr
409  pdfSum -= 63;
410  stubResults[iLogicLayer].setPdfVal(-63);
411  } else
412  pdfSum += stubResults[iLogicLayer].getPdfVal(); //bending layer not fired at all
413  }
414  } else {
415  if (iLogicLayer < 10 && stubResults[iLogicLayer].getPdfVal() == 0)
416  pdfSum -= 32; // penaly
417  else
418  pdfSum += stubResults[iLogicLayer].getPdfVal();
419  if (firedLayerBits & (1 << iLogicLayer)) { //pdfSum is counted always
420  firedLayerCnt++;
421  }
422  }
423  }
424 
425  if ((omtfConfig->usePhiBExtrapolationMB1() && refLayer == 0) ||
427  auto refLayerLogicNumber = omtfConfig->getRefToLogicNumber()[refLayer];
428  //Unconstrained pt is obtained by not including the pdfValue from the phiB of the refHit
429  //TODO get logic layer from connectedLayer
430  pdfSumUnconstr = pdfSum - stubResults[refLayerLogicNumber + 1].getPdfVal();
431 
432  } else
433  pdfSumUnconstr = 0;
434 
435  valid = true;
436  //by default result becomes valid here, but can be overwritten later
437 }
438 
441 std::ostream& operator<<(std::ostream& out, const GoldenPatternResult& gpResult) {
442  if (gpResult.omtfConfig == nullptr) {
443  out << "empty GoldenPatternResult" << std::endl;
444  return out;
445  }
446  unsigned int refLayerLogicNum = gpResult.omtfConfig->getRefToLogicNumber()[gpResult.getRefLayer()];
447 
448  unsigned int sumOverFiredLayers = 0;
449  for (unsigned int iLogicLayer = 0; iLogicLayer < gpResult.stubResults.size(); ++iLogicLayer) {
450  out << " layer: " << std::setw(2) << iLogicLayer << " hit: ";
451  if (gpResult.stubResults[iLogicLayer].getMuonStub()) {
452  out << std::setw(4)
453  << (gpResult.omtfConfig->isBendingLayer(iLogicLayer)
454  ? gpResult.stubResults[iLogicLayer].getMuonStub()->phiBHw
455  : gpResult.stubResults[iLogicLayer].getMuonStub()->phiHw);
456 
457  out << " pdfBin: " << std::setw(4) << gpResult.stubResults[iLogicLayer].getPdfBin() << " pdfVal: " << std::setw(3)
458  << gpResult.stubResults[iLogicLayer].getPdfVal() << " fired " << gpResult.isLayerFired(iLogicLayer)
459  << (iLogicLayer == refLayerLogicNum ? " <<< refLayer" : "");
460 
461  if (gpResult.isLayerFired(iLogicLayer))
462  sumOverFiredLayers += gpResult.stubResults[iLogicLayer].getPdfVal();
463  } else if (gpResult.stubResults[iLogicLayer].getPdfVal()) {
464  out << " pdfVal: " << std::setw(3) << gpResult.stubResults[iLogicLayer].getPdfVal();
465  }
466  out << std::endl;
467  }
468 
469  out << " refLayer: ";
470  out << gpResult.getRefLayer() << "\t";
471 
472  out << " Sum over layers: ";
473  out << gpResult.getPdfSum() << "\t";
474 
475  out << " sumOverFiredLayers: ";
476  out << sumOverFiredLayers << "\t";
477 
478  out << " Sum over layers unconstr: ";
479  out << gpResult.getPdfSumUnconstr() << "\t";
480 
481  out << " Number of hits: ";
482  out << gpResult.getFiredLayerCnt() << "\t";
483 
484  out << " GpProbability1: ";
485  out << gpResult.getGpProbability1() << "\t";
486 
487  out << " GpProbability2: ";
488  out << gpResult.getGpProbability2() << "\t";
489 
490  out << std::endl;
491 
492  return out;
493 }
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:29
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