CMS 3D CMS Logo

MuCondition.cc
Go to the documentation of this file.
1 
16 // this class header
18 
19 // system include files
20 #include <iostream>
21 #include <iomanip>
22 
23 #include <string>
24 #include <vector>
25 #include <algorithm>
26 
27 // user include files
28 // base classes
31 
33 
35 
38 
39 // constructors
40 // default
42  // empty
43 }
44 
45 // from base template condition (from event setup usually)
47  const GlobalBoard* ptrGTL,
48  const int nrL1Mu,
49  const int ifMuEtaNumberBits)
51  m_gtMuonTemplate(static_cast<const MuonTemplate*>(muonTemplate)),
52  m_gtGTL(ptrGTL),
53  m_ifMuEtaNumberBits(ifMuEtaNumberBits) {
55  m_condMaxNumberObjects = nrL1Mu;
56 }
57 
58 // copy constructor
60  m_gtMuonTemplate = cp.gtMuonTemplate();
61  m_gtGTL = cp.gtGTL();
62 
63  m_ifMuEtaNumberBits = cp.gtIfMuEtaNumberBits();
64  m_corrParDeltaPhiNrBins = cp.m_corrParDeltaPhiNrBins;
65 
66  m_condMaxNumberObjects = cp.condMaxNumberObjects();
67  m_condLastResult = cp.condLastResult();
68  m_combinationsInCond = cp.getCombinationsInCond();
69 
70  m_verbosity = cp.m_verbosity;
71 }
72 
74 
75 // destructor
77  // empty
78 }
79 
80 // equal operator
82  copy(cp);
83  return *this;
84 }
85 
86 // methods
87 void l1t::MuCondition::setGtMuonTemplate(const MuonTemplate* muonTempl) { m_gtMuonTemplate = muonTempl; }
88 
90 void l1t::MuCondition::setGtGTL(const GlobalBoard* ptrGTL) { m_gtGTL = ptrGTL; }
91 
92 // set the number of bits for eta of muon objects
93 void l1t::MuCondition::setGtIfMuEtaNumberBits(const int& ifMuEtaNumberBitsValue) {
94  m_ifMuEtaNumberBits = ifMuEtaNumberBitsValue;
95 }
96 
97 // set the maximum number of bins for the delta phi scales
98 void l1t::MuCondition::setGtCorrParDeltaPhiNrBins(const int& corrParDeltaPhiNrBins) {
99  m_corrParDeltaPhiNrBins = corrParDeltaPhiNrBins;
100 }
101 
102 // try all object permutations and check spatial correlations, if required
103 const bool l1t::MuCondition::evaluateCondition(const int bxEval) const {
104  // BLW Need to pass this as an argument
105  //const int bxEval=0; //BLW Change for BXVector
106 
107  // number of trigger objects in the condition
108  int nObjInCond = m_gtMuonTemplate->nrObjects();
109 
110  // the candidates
111  const BXVector<const l1t::Muon*>* candVec = m_gtGTL->getCandL1Mu(); //BLW Change for BXVector
112 
113  // Look at objects in bx = bx + relativeBx
114  int useBx = bxEval + m_gtMuonTemplate->condRelativeBx();
115 
116  // Fail condition if attempting to get Bx outside of range
117  if ((useBx < candVec->getFirstBX()) || (useBx > candVec->getLastBX())) {
118  return false;
119  }
120 
121  int numberObjects = candVec->size(useBx); //BLW Change for BXVector
122  //LogTrace("L1TGlobal") << " numberObjects: " << numberObjects
123  // << std::endl;
124  if (numberObjects < nObjInCond) {
125  return false;
126  }
127 
128  std::vector<int> index(numberObjects);
129 
130  for (int i = 0; i < numberObjects; ++i) {
131  index[i] = i;
132  }
133 
134  int numberForFactorial = numberObjects - nObjInCond;
135 
136  // TEMPORARY FIX UNTIL IMPLEMENT NEW MUON CONDITIONS
137  int myfactorial = 1;
138  for (int i = numberForFactorial; i > 0; i--)
139  myfactorial *= i;
140 
141  int jumpIndex = 1;
142  int jump = myfactorial; //factorial(numberObjects - nObjInCond);
143 
144  int totalLoops = 0;
145  int passLoops = 0;
146 
147  // condition result condResult set to true if at least one permutation
148  // passes all requirements
149  // all possible permutations are checked
150  bool condResult = false;
151 
152  // store the indices of the muon objects
153  // from the combination evaluated in the condition
154  SingleCombInCond objectsInComb;
155  objectsInComb.reserve(nObjInCond);
156 
157  // clear the m_combinationsInCond vector
158  combinationsInCond().clear();
159 
160  do {
161  if (--jumpIndex)
162  continue;
163 
164  jumpIndex = jump;
165  totalLoops++;
166 
167  // clear the indices in the combination
168  objectsInComb.clear();
169 
170  bool tmpResult = true;
171 
172  bool passCondition = false;
173  // check if there is a permutation that matches object-parameter requirements
174  for (int i = 0; i < nObjInCond; i++) {
175  passCondition = checkObjectParameter(i, *(candVec->at(useBx, index[i])), index[i]); //BLW Change for BXVector
176  tmpResult &= passCondition;
177  if (passCondition)
178  LogDebug("L1TGlobal") << "===> MuCondition::evaluateCondition, CONGRATS!! This muon passed the condition."
179  << std::endl;
180  else
181  LogDebug("L1TGlobal") << "===> MuCondition::evaluateCondition, FAIL!! This muon failed the condition."
182  << std::endl;
183  objectsInComb.push_back(index[i]);
184  }
185 
186  // if permutation does not match particle conditions
187  // skip charge correlation and spatial correlations
188  if (!tmpResult) {
189  continue;
190  }
191 
192  // get the correlation parameters (chargeCorrelation included here also)
193  MuonTemplate::CorrelationParameter corrPar = *(m_gtMuonTemplate->correlationParameter());
194 
195  // charge_correlation consists of 3 relevant bits (D2, D1, D0)
196  unsigned int chargeCorr = corrPar.chargeCorrelation;
197 
198  // charge ignore bit (D0) not set?
199  if ((chargeCorr & 1) == 0) {
200  LogDebug("L1TGlobal") << "===> MuCondition:: Checking Charge Correlation" << std::endl;
201 
202  for (int i = 0; i < nObjInCond; i++) {
203  // check valid charge - skip if invalid charge
204  int chargeValid = (candVec->at(useBx, index[i]))->hwChargeValid(); //BLW Change for BXVector
205  tmpResult &= chargeValid;
206 
207  if (chargeValid == 0) { //BLW type change for New Muon Class
208  continue;
209  }
210  }
211 
212  if (!tmpResult) {
213  LogDebug("L1TGlobal") << "===> MuCondition:: Charge Correlation Failed...No Valid Charges" << std::endl;
214  continue;
215  }
216 
217  if (nObjInCond > 1) { // more objects condition
218 
219  // find out if signs are equal
220  bool equalSigns = true;
221  for (int i = 0; i < nObjInCond - 1; i++) {
222  if ((candVec->at(useBx, index[i]))->hwCharge() !=
223  (candVec->at(useBx, index[i + 1]))->hwCharge()) { //BLW Change for BXVector
224  equalSigns = false;
225  break;
226  }
227  }
228 
229  LogDebug("L1TGlobal") << "===> MuCondition:: Checking Charge Correlation equalSigns = " << equalSigns
230  << std::endl;
231 
232  // two or three particle condition
233  if (nObjInCond == 2 || nObjInCond == 3) {
234  if (!(((chargeCorr & 2) != 0 && equalSigns) || ((chargeCorr & 4) != 0 && !equalSigns))) {
235  LogDebug("L1TGlobal") << "===> MuCondition:: 2/3 Muon Fail Charge Correlation Condition =" << chargeCorr
236  << std::endl;
237  continue;
238  }
239  } else if (nObjInCond == 4) {
240  //counter to count positive charges to determine if there are pairs
241  unsigned int posCount = 0;
242 
243  for (int i = 0; i < nObjInCond; i++) {
244  if ((candVec->at(useBx, index[i]))->hwCharge() > 0) { //BLW Change for BXVector
245  posCount++;
246  }
247  }
248 
249  // Original OS 4 muon condition (disagreement with firmware):
250  // if (!(((chargeCorr & 2) != 0 && equalSigns) || ((chargeCorr & 4) != 0 && posCount == 2))) {
251  // Fix by R. Cavanaugh:
252  // Note that negative charge => hwCharge = 0
253  // positive charge => hwCharge = 1
254  // Hence: (0,0,0,0) => (posCount = 0) => 4 SS muons
255  // (1,0,0,0) => (posCount = 1) => 1 OS muon pair, 1 SS muon pair
256  // (1,1,0,0) => (posCount = 2) => 2 OS muon pairs
257  // (1,0,1,0) => (posCount = 2) => 2 OS muon pairs
258  // (0,0,1,1) => (posCount = 2) => 2 OS muon pairs
259  // (1,1,1,0) => (posCount = 3) => 1 SS muon pair, 1 OS muon pair
260  // (1,1,1,1) => (posCount = 4) => 4 SS muons
261  // A requirement (posCount == 2) implies there must be exactly 2 OS pairs of muons
262  // A requirement of at least 1 pair of OS muons implies condition should be (posCount > 0 && posCount < 4)
263  if (!(((chargeCorr & 2) != 0 && equalSigns) || ((chargeCorr & 4) != 0 && (posCount > 0 && posCount < 4)))) {
264  LogDebug("L1TGlobal") << "===> MuCondition:: 4 Muon Fail Charge Correlation Condition = " << chargeCorr
265  << " posCnt " << posCount << std::endl;
266  continue;
267  }
268  }
269  } // end require nObjInCond > 1
270  } // end signchecks
271 
272  if (m_gtMuonTemplate->wsc()) {
273  // wsc requirements have always nObjInCond = 2
274  // one can use directly index[0] and index[1] to compute
275  // eta and phi differences
276  const int ObjInWscComb = 2;
277  if (nObjInCond != ObjInWscComb) {
278  edm::LogError("L1TGlobal") << "\n Error: "
279  << "number of particles in condition with spatial correlation = " << nObjInCond
280  << "\n it must be = " << ObjInWscComb << std::endl;
281  // TODO Perhaps I should throw here an exception,
282  // since something is really wrong if nObjInCond != ObjInWscComb (=2)
283  continue;
284  }
285 
286  // check delta eta
287  if (!checkRangeDeltaEta((candVec->at(useBx, 0))->hwEtaAtVtx(),
288  (candVec->at(useBx, 1))->hwEtaAtVtx(),
289  corrPar.deltaEtaRangeLower,
290  corrPar.deltaEtaRangeUpper,
291  8)) {
292  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRangeDeltaEta" << std::endl;
293  continue;
294  }
295 
296  // check delta phi
297  if (!checkRangeDeltaPhi((candVec->at(useBx, 0))->hwPhiAtVtx(),
298  (candVec->at(useBx, 1))->hwPhiAtVtx(),
299  corrPar.deltaPhiRangeLower,
300  corrPar.deltaPhiRangeUpper)) {
301  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRangeDeltaPhi" << std::endl;
302  continue;
303  }
304 
305  } // end wsc check
306 
307  // if we get here all checks were successfull for this combination
308  // set the general result for evaluateCondition to "true"
309 
310  condResult = true;
311  passLoops++;
312  (combinationsInCond()).push_back(objectsInComb);
313 
314  } while (std::next_permutation(index.begin(), index.end()));
315 
316  //LogTrace("L1TGlobal")
317  // << "\n MuCondition: total number of permutations found: " << totalLoops
318  // << "\n MuCondition: number of permutations passing requirements: " << passLoops
319  // << "\n" << std::endl;
320 
321  return condResult;
322 }
323 
324 // load muon candidates
325 const l1t::Muon* l1t::MuCondition::getCandidate(const int bx, const int indexCand) const {
326  return (m_gtGTL->getCandL1Mu())->at(bx, indexCand); //BLW Change for BXVector
327 }
328 
338 const bool l1t::MuCondition::checkObjectParameter(const int iCondition,
339  const l1t::Muon& cand,
340  const unsigned int index) const {
341  // number of objects in condition
342  int nObjInCond = m_gtMuonTemplate->nrObjects();
343 
344  if (iCondition >= nObjInCond || iCondition < 0) {
345  return false;
346  }
347 
348  // // empty candidates can not be compared
349  // if (cand.empty()) {
350  // return false;
351  // }
352 
353  const MuonTemplate::ObjectParameter objPar = (*(m_gtMuonTemplate->objectParameter()))[iCondition];
354 
355  // using the logic table from GTL-9U-module.pdf
356  // "Truth table for Isolation bit"
357 
358  // check thresholds:
359 
360  // value < low pt threshold
361  // fail trigger
362 
363  // low pt threshold <= value < high pt threshold & non-isolated muon:
364  // requestIso true: fail trigger
365  // requestIso false, enableIso true: fail trigger
366  // requestIso false, enableIso false: OK, trigger
367 
368  // low pt threshold <= value < high pt threshold & isolated muon:
369  // requestIso true: OK, trigger
370  // requestIso false, enableIso true: OK, trigger
371  // requestIso false, enableIso false: OK, trigger
372 
373  // value >= high pt threshold & non-isolated muon:
374  // requestIso true: fail trigger
375  // requestIso false: OK, trigger
376 
377  // value >= high pt threshold & isolated muon:
378  // OK, trigger
379 
380  LogDebug("L1TGlobal") << "\n MuonTemplate::ObjectParameter : " << std::hex << "\n\t ptHighThreshold = 0x "
381  << objPar.ptHighThreshold << "\n\t ptLowThreshold = 0x " << objPar.ptLowThreshold
382  << "\n\t indexHigh = 0x " << objPar.indexHigh << "\n\t indexLow = 0x "
383  << objPar.indexLow << "\n\t requestIso = 0x " << objPar.requestIso
384  << "\n\t enableIso = 0x " << objPar.enableIso << "\n\t etaRange = 0x "
385  << objPar.etaRange << "\n\t phiLow = 0x " << objPar.phiLow
386  << "\n\t phiHigh = 0x " << objPar.phiHigh << "\n\t phiWindow1Lower = 0x "
387  << objPar.phiWindow1Lower << "\n\t phiWindow1Upper = 0x " << objPar.phiWindow1Upper
388  << "\n\t phiWindow2Lower = 0x " << objPar.phiWindow2Lower << "\n\t phiWindow2Lower = 0x "
389  << objPar.phiWindow2Lower << "\n\t charge = 0x " << objPar.charge
390  << "\n\t qualityLUT = 0x " << objPar.qualityLUT << "\n\t isolationLUT = 0x "
391  << objPar.isolationLUT << "\n\t enableMip = 0x " << objPar.enableMip << std::endl;
392 
393  LogDebug("L1TGlobal") << "\n l1t::Muon : "
394  << "\n\t hwPt = 0x " << cand.hwPt() << "\n\t hwEtaAtVtx = 0x " << cand.hwEtaAtVtx()
395  << "\n\t hwPhiAtVtx = 0x " << cand.hwPhiAtVtx() << "\n\t hwCharge = 0x " << cand.hwCharge()
396  << "\n\t hwQual = 0x " << cand.hwQual() << "\n\t hwIso = 0x " << cand.hwIso()
397  << std::dec << std::endl;
398 
399  if (objPar.unconstrainedPtHigh > 0) // Rick Cavanaugh: Check if unconstrained pT cut-window is valid
400  {
401  if (!checkUnconstrainedPt(objPar.unconstrainedPtLow,
402  objPar.unconstrainedPtHigh,
403  cand.hwPtUnconstrained(),
404  m_gtMuonTemplate->condGEq())) {
405  LogDebug("L1TGlobal") << "\t\t Muon Failed unconstrainedPt checkThreshold; iCondition = " << iCondition
406  << std::endl;
407  return false;
408  }
409  }
410  if (objPar.impactParameterLUT !=
411  0) // Rick Cavanaugh: Check if impact parameter LUT is valid. 0xF is default; 0x0 is invalid
412  {
413  // check impact parameter ( bit check ) with impact parameter LUT
414  // sanity check on candidate impact parameter
415  if (cand.hwDXY() > 3) {
416  LogDebug("L1TGlobal") << "\t\t l1t::Candidate has out of range hwDXY = " << cand.hwDXY() << std::endl;
417  return false;
418  }
419  bool passImpactParameterLUT = ((objPar.impactParameterLUT >> cand.hwDXY()) & 1);
420  if (!passImpactParameterLUT) {
421  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed impact parameter requirement" << std::endl;
422  return false;
423  }
424  }
425 
426  if (!checkThreshold(objPar.ptLowThreshold, objPar.ptHighThreshold, cand.hwPt(), m_gtMuonTemplate->condGEq())) {
427  LogDebug("L1TGlobal") << "\t\t Muon Failed checkThreshold " << std::endl;
428  return false;
429  }
430 
431  // check index
432  if (!checkIndex(objPar.indexLow, objPar.indexHigh, index)) {
433  LogDebug("L1TGlobal") << "\t\t Muon Failed checkIndex " << std::endl;
434  return false;
435  }
436 
437  // check eta
438  if (!checkRangeEta(cand.hwEtaAtVtx(),
439  objPar.etaWindow1Lower,
440  objPar.etaWindow1Upper,
441  objPar.etaWindow2Lower,
442  objPar.etaWindow2Upper,
443  8)) {
444  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRange(eta)" << std::endl;
445  return false;
446  }
447 
448  // check phi
449  if (!checkRangePhi(cand.hwPhiAtVtx(),
450  objPar.phiWindow1Lower,
451  objPar.phiWindow1Upper,
452  objPar.phiWindow2Lower,
453  objPar.phiWindow2Upper)) {
454  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRange(phi)" << std::endl;
455  return false;
456  }
457 
458  // check charge
459  if (objPar.charge >= 0) {
460  if (cand.hwCharge() != objPar.charge) {
461  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed charge requirement" << std::endl;
462  return false;
463  }
464  }
465 
466  // check quality ( bit check ) with quality LUT
467  // sanity check on candidate quality
468  if (cand.hwQual() > 16) {
469  LogDebug("L1TGlobal") << "\t\t l1t::Candidate has out of range hwQual = " << cand.hwQual() << std::endl;
470  return false;
471  }
472  bool passQualLUT = ((objPar.qualityLUT >> cand.hwQual()) & 1);
473  if (!passQualLUT) {
474  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed quality requirement" << std::endl;
475  return false;
476  }
477 
478  // check isolation ( bit check ) with isolation LUT
479  // sanity check on candidate isolation
480  if (cand.hwIso() > 4) {
481  LogDebug("L1TGlobal") << "\t\t l1t::Candidate has out of range hwIso = " << cand.hwIso() << std::endl;
482  return false;
483  }
484  bool passIsoLUT = ((objPar.isolationLUT >> cand.hwIso()) & 1);
485  if (!passIsoLUT) {
486  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed isolation requirement" << std::endl;
487  return false;
488  }
489 
490  // A number of values is required to trigger (at least one).
491  // "Don't care" means that all values are allowed.
492  // Qual = 000 means then NO MUON (GTL module)
493 
494  // if (cand.hwQual() == 0) {
495  // LogDebug("L1TGlobal") << "\t\t Muon Failed hwQual() == 0" << std::endl;
496  // return false;
497  // }
498 
499  // if (objPar.qualityRange == 0) {
500  // LogDebug("L1TGlobal") << "\t\t Muon Failed qualityRange == 0" << std::endl;
501  // return false;
502  // }
503  // else {
504  // if (!checkBit(objPar.qualityRange, cand.hwQual())) {
505  // LogDebug("L1TGlobal") << "\t\t Muon Failed checkBit(qualityRange) " << std::endl;
506  // return false;
507  // }
508  // }
509 
510  // check mip
511  if (objPar.enableMip) {
512  // if (!cand.hwMip()) {
513  // LogDebug("L1TGlobal") << "\t\t Muon Failed enableMip" << std::endl;
514  // return false;
515  // }
516  }
517 
518  // particle matches if we get here
519  //LogTrace("L1TGlobal")
520  // << " checkObjectParameter: muon object OK, passes all requirements\n" << std::endl;
521 
522  return true;
523 }
524 
525 void l1t::MuCondition::print(std::ostream& myCout) const {
526  m_gtMuonTemplate->print(myCout);
527 
528  myCout << " Number of bits for eta of muon objects = " << m_ifMuEtaNumberBits << std::endl;
529  myCout << " Maximum number of bins for the delta phi scales = " << m_corrParDeltaPhiNrBins << "\n " << std::endl;
530 
532 }
int getLastBX() const
void setGtGTL(const GlobalBoard *)
set the pointer to GTL
Definition: MuCondition.cc:90
~MuCondition() override
Definition: MuCondition.cc:76
void print(std::ostream &myCout) const override
print condition
Definition: MuCondition.cc:525
const bool checkObjectParameter(const int iCondition, const l1t::Muon &cand, const unsigned int index) const
function to check a single object if it matches a condition
Definition: MuCondition.cc:338
std::vector< int > SingleCombInCond
typedefs
Log< level::Error, false > LogError
const l1t::Muon * getCandidate(const int bx, const int indexCand) const
load muon candidates
Definition: MuCondition.cc:325
unsigned size(int bx) const
unsigned long long etaRange
Definition: MuonTemplate.h:70
unsigned int m_corrParDeltaPhiNrBins
Definition: MuCondition.h:104
void setGtIfMuEtaNumberBits(const int &)
Definition: MuCondition.cc:93
const T & at(int bx, unsigned i) const
Definition: Muon.h:21
virtual void print(std::ostream &myCout) const
print condition
void setGtCorrParDeltaPhiNrBins(const int &)
Definition: MuCondition.cc:98
void copy(const MuCondition &cp)
copy function for copy constructor and operator=
Definition: MuCondition.cc:59
void setGtMuonTemplate(const MuonTemplate *)
Definition: MuCondition.cc:87
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
const bool evaluateCondition(const int bxEval) const override
the core function to check if the condition matches
Definition: MuCondition.cc:103
MuCondition & operator=(const MuCondition &)
Definition: MuCondition.cc:81
#define LogDebug(id)