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  // condition result condResult set to true if at least one permutation
145  // passes all requirements
146  // all possible permutations are checked
147  bool condResult = false;
148 
149  // store the indices of the muon objects
150  // from the combination evaluated in the condition
151  SingleCombInCond objectsInComb;
152  objectsInComb.reserve(nObjInCond);
153 
154  // clear the m_combinationsInCond vector
155  combinationsInCond().clear();
156 
157  do {
158  if (--jumpIndex)
159  continue;
160 
161  jumpIndex = jump;
162 
163  // clear the indices in the combination
164  objectsInComb.clear();
165 
166  bool tmpResult = true;
167 
168  bool passCondition = false;
169  // check if there is a permutation that matches object-parameter requirements
170  for (int i = 0; i < nObjInCond; i++) {
171  passCondition = checkObjectParameter(i, *(candVec->at(useBx, index[i])), index[i]); //BLW Change for BXVector
172  tmpResult &= passCondition;
173  if (passCondition)
174  LogDebug("L1TGlobal") << "===> MuCondition::evaluateCondition, CONGRATS!! This muon passed the condition."
175  << std::endl;
176  else
177  LogDebug("L1TGlobal") << "===> MuCondition::evaluateCondition, FAIL!! This muon failed the condition."
178  << std::endl;
179  objectsInComb.push_back(index[i]);
180  }
181 
182  // if permutation does not match particle conditions
183  // skip charge correlation and spatial correlations
184  if (!tmpResult) {
185  continue;
186  }
187 
188  // get the correlation parameters (chargeCorrelation included here also)
189  MuonTemplate::CorrelationParameter corrPar = *(m_gtMuonTemplate->correlationParameter());
190 
191  // charge_correlation consists of 3 relevant bits (D2, D1, D0)
192  unsigned int chargeCorr = corrPar.chargeCorrelation;
193 
194  // charge ignore bit (D0) not set?
195  if ((chargeCorr & 1) == 0) {
196  LogDebug("L1TGlobal") << "===> MuCondition:: Checking Charge Correlation" << std::endl;
197 
198  for (int i = 0; i < nObjInCond; i++) {
199  // check valid charge - skip if invalid charge
200  int chargeValid = (candVec->at(useBx, index[i]))->hwChargeValid(); //BLW Change for BXVector
201  tmpResult &= chargeValid;
202 
203  if (chargeValid == 0) { //BLW type change for New Muon Class
204  continue;
205  }
206  }
207 
208  if (!tmpResult) {
209  LogDebug("L1TGlobal") << "===> MuCondition:: Charge Correlation Failed...No Valid Charges" << std::endl;
210  continue;
211  }
212 
213  if (nObjInCond > 1) { // more objects condition
214 
215  // find out if signs are equal
216  bool equalSigns = true;
217  for (int i = 0; i < nObjInCond - 1; i++) {
218  if ((candVec->at(useBx, index[i]))->hwCharge() !=
219  (candVec->at(useBx, index[i + 1]))->hwCharge()) { //BLW Change for BXVector
220  equalSigns = false;
221  break;
222  }
223  }
224 
225  LogDebug("L1TGlobal") << "===> MuCondition:: Checking Charge Correlation equalSigns = " << equalSigns
226  << std::endl;
227 
228  // two or three particle condition
229  if (nObjInCond == 2 || nObjInCond == 3) {
230  if (!(((chargeCorr & 2) != 0 && equalSigns) || ((chargeCorr & 4) != 0 && !equalSigns))) {
231  LogDebug("L1TGlobal") << "===> MuCondition:: 2/3 Muon Fail Charge Correlation Condition =" << chargeCorr
232  << std::endl;
233  continue;
234  }
235  } else if (nObjInCond == 4) {
236  //counter to count positive charges to determine if there are pairs
237  unsigned int posCount = 0;
238 
239  for (int i = 0; i < nObjInCond; i++) {
240  if ((candVec->at(useBx, index[i]))->hwCharge() > 0) { //BLW Change for BXVector
241  posCount++;
242  }
243  }
244 
245  // Original OS 4 muon condition (disagreement with firmware):
246  // if (!(((chargeCorr & 2) != 0 && equalSigns) || ((chargeCorr & 4) != 0 && posCount == 2))) {
247  // Fix by R. Cavanaugh:
248  // Note that negative charge => hwCharge = 0
249  // positive charge => hwCharge = 1
250  // Hence: (0,0,0,0) => (posCount = 0) => 4 SS muons
251  // (1,0,0,0) => (posCount = 1) => 1 OS muon pair, 1 SS muon pair
252  // (1,1,0,0) => (posCount = 2) => 2 OS muon pairs
253  // (1,0,1,0) => (posCount = 2) => 2 OS muon pairs
254  // (0,0,1,1) => (posCount = 2) => 2 OS muon pairs
255  // (1,1,1,0) => (posCount = 3) => 1 SS muon pair, 1 OS muon pair
256  // (1,1,1,1) => (posCount = 4) => 4 SS muons
257  // A requirement (posCount == 2) implies there must be exactly 2 OS pairs of muons
258  // A requirement of at least 1 pair of OS muons implies condition should be (posCount > 0 && posCount < 4)
259  if (!(((chargeCorr & 2) != 0 && equalSigns) || ((chargeCorr & 4) != 0 && (posCount > 0 && posCount < 4)))) {
260  LogDebug("L1TGlobal") << "===> MuCondition:: 4 Muon Fail Charge Correlation Condition = " << chargeCorr
261  << " posCnt " << posCount << std::endl;
262  continue;
263  }
264  }
265  } // end require nObjInCond > 1
266  } // end signchecks
267 
268  if (m_gtMuonTemplate->wsc()) {
269  // wsc requirements have always nObjInCond = 2
270  // one can use directly index[0] and index[1] to compute
271  // eta and phi differences
272  const int ObjInWscComb = 2;
273  if (nObjInCond != ObjInWscComb) {
274  edm::LogError("L1TGlobal") << "\n Error: "
275  << "number of particles in condition with spatial correlation = " << nObjInCond
276  << "\n it must be = " << ObjInWscComb << std::endl;
277  // TODO Perhaps I should throw here an exception,
278  // since something is really wrong if nObjInCond != ObjInWscComb (=2)
279  continue;
280  }
281 
282  // check delta eta
283  if (!checkRangeDeltaEta((candVec->at(useBx, 0))->hwEtaAtVtx(),
284  (candVec->at(useBx, 1))->hwEtaAtVtx(),
285  corrPar.deltaEtaRangeLower,
286  corrPar.deltaEtaRangeUpper,
287  8)) {
288  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRangeDeltaEta" << std::endl;
289  continue;
290  }
291 
292  // check delta phi
293  if (!checkRangeDeltaPhi((candVec->at(useBx, 0))->hwPhiAtVtx(),
294  (candVec->at(useBx, 1))->hwPhiAtVtx(),
295  corrPar.deltaPhiRangeLower,
296  corrPar.deltaPhiRangeUpper)) {
297  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRangeDeltaPhi" << std::endl;
298  continue;
299  }
300 
301  } // end wsc check
302 
303  // if we get here all checks were successfull for this combination
304  // set the general result for evaluateCondition to "true"
305 
306  condResult = true;
307  (combinationsInCond()).push_back(objectsInComb);
308 
309  } while (std::next_permutation(index.begin(), index.end()));
310 
311  return condResult;
312 }
313 
314 // load muon candidates
315 const l1t::Muon* l1t::MuCondition::getCandidate(const int bx, const int indexCand) const {
316  return (m_gtGTL->getCandL1Mu())->at(bx, indexCand); //BLW Change for BXVector
317 }
318 
328 const bool l1t::MuCondition::checkObjectParameter(const int iCondition,
329  const l1t::Muon& cand,
330  const unsigned int index) const {
331  // number of objects in condition
332  int nObjInCond = m_gtMuonTemplate->nrObjects();
333 
334  if (iCondition >= nObjInCond || iCondition < 0) {
335  return false;
336  }
337 
338  // // empty candidates can not be compared
339  // if (cand.empty()) {
340  // return false;
341  // }
342 
343  const MuonTemplate::ObjectParameter objPar = (*(m_gtMuonTemplate->objectParameter()))[iCondition];
344 
345  // using the logic table from GTL-9U-module.pdf
346  // "Truth table for Isolation bit"
347 
348  // check thresholds:
349 
350  // value < low pt threshold
351  // fail trigger
352 
353  // low pt threshold <= value < high pt threshold & non-isolated muon:
354  // requestIso true: fail trigger
355  // requestIso false, enableIso true: fail trigger
356  // requestIso false, enableIso false: OK, trigger
357 
358  // low pt threshold <= value < high pt threshold & isolated muon:
359  // requestIso true: OK, trigger
360  // requestIso false, enableIso true: OK, trigger
361  // requestIso false, enableIso false: OK, trigger
362 
363  // value >= high pt threshold & non-isolated muon:
364  // requestIso true: fail trigger
365  // requestIso false: OK, trigger
366 
367  // value >= high pt threshold & isolated muon:
368  // OK, trigger
369 
370  LogDebug("L1TGlobal") << "\n MuonTemplate::ObjectParameter : " << std::hex << "\n\t ptHighThreshold = 0x "
371  << objPar.ptHighThreshold << "\n\t ptLowThreshold = 0x " << objPar.ptLowThreshold
372  << "\n\t indexHigh = 0x " << objPar.indexHigh << "\n\t indexLow = 0x "
373  << objPar.indexLow << "\n\t requestIso = 0x " << objPar.requestIso
374  << "\n\t enableIso = 0x " << objPar.enableIso << "\n\t etaRange = 0x "
375  << objPar.etaRange << "\n\t phiLow = 0x " << objPar.phiLow
376  << "\n\t phiHigh = 0x " << objPar.phiHigh << "\n\t phiWindow1Lower = 0x "
377  << objPar.phiWindow1Lower << "\n\t phiWindow1Upper = 0x " << objPar.phiWindow1Upper
378  << "\n\t phiWindow2Lower = 0x " << objPar.phiWindow2Lower << "\n\t phiWindow2Lower = 0x "
379  << objPar.phiWindow2Lower << "\n\t charge = 0x " << objPar.charge
380  << "\n\t qualityLUT = 0x " << objPar.qualityLUT << "\n\t isolationLUT = 0x "
381  << objPar.isolationLUT << "\n\t enableMip = 0x " << objPar.enableMip << std::endl;
382 
383  LogDebug("L1TGlobal") << "\n l1t::Muon : "
384  << "\n\t hwPt = 0x " << cand.hwPt() << "\n\t hwEtaAtVtx = 0x " << cand.hwEtaAtVtx()
385  << "\n\t hwPhiAtVtx = 0x " << cand.hwPhiAtVtx() << "\n\t hwCharge = 0x " << cand.hwCharge()
386  << "\n\t hwQual = 0x " << cand.hwQual() << "\n\t hwIso = 0x " << cand.hwIso()
387  << std::dec << std::endl;
388 
389  if (objPar.unconstrainedPtHigh > 0) // Rick Cavanaugh: Check if unconstrained pT cut-window is valid
390  {
391  if (!checkUnconstrainedPt(objPar.unconstrainedPtLow,
392  objPar.unconstrainedPtHigh,
393  cand.hwPtUnconstrained(),
394  m_gtMuonTemplate->condGEq())) {
395  LogDebug("L1TGlobal") << "\t\t Muon Failed unconstrainedPt checkThreshold; iCondition = " << iCondition
396  << std::endl;
397  return false;
398  }
399  }
400  if (objPar.impactParameterLUT !=
401  0) // Rick Cavanaugh: Check if impact parameter LUT is valid. 0xF is default; 0x0 is invalid
402  {
403  // check impact parameter ( bit check ) with impact parameter LUT
404  // sanity check on candidate impact parameter
405  if (cand.hwDXY() > 3) {
406  LogDebug("L1TGlobal") << "\t\t l1t::Candidate has out of range hwDXY = " << cand.hwDXY() << std::endl;
407  return false;
408  }
409  bool passImpactParameterLUT = ((objPar.impactParameterLUT >> cand.hwDXY()) & 1);
410  if (!passImpactParameterLUT) {
411  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed impact parameter requirement" << std::endl;
412  return false;
413  }
414  }
415 
416  if (!checkThreshold(objPar.ptLowThreshold, objPar.ptHighThreshold, cand.hwPt(), m_gtMuonTemplate->condGEq())) {
417  LogDebug("L1TGlobal") << "\t\t Muon Failed checkThreshold " << std::endl;
418  return false;
419  }
420 
421  // check index
422  if (!checkIndex(objPar.indexLow, objPar.indexHigh, index)) {
423  LogDebug("L1TGlobal") << "\t\t Muon Failed checkIndex " << std::endl;
424  return false;
425  }
426 
427  // check eta
428  if (!checkRangeEta(cand.hwEtaAtVtx(), objPar.etaWindows, 8)) {
429  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRangeEta" << std::endl;
430  return false;
431  }
432 
433  // check phi
434  if (!checkRangePhi(cand.hwPhiAtVtx(),
435  objPar.phiWindow1Lower,
436  objPar.phiWindow1Upper,
437  objPar.phiWindow2Lower,
438  objPar.phiWindow2Upper)) {
439  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRange(phi)" << std::endl;
440  return false;
441  }
442 
443  // check charge
444  if (objPar.charge >= 0) {
445  if (cand.hwCharge() != objPar.charge) {
446  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed charge requirement" << std::endl;
447  return false;
448  }
449  }
450 
451  // check quality ( bit check ) with quality LUT
452  // sanity check on candidate quality
453  if (cand.hwQual() > 16) {
454  LogDebug("L1TGlobal") << "\t\t l1t::Candidate has out of range hwQual = " << cand.hwQual() << std::endl;
455  return false;
456  }
457  bool passQualLUT = ((objPar.qualityLUT >> cand.hwQual()) & 1);
458  if (!passQualLUT) {
459  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed quality requirement" << std::endl;
460  return false;
461  }
462 
463  // check isolation ( bit check ) with isolation LUT
464  // sanity check on candidate isolation
465  if (cand.hwIso() > 4) {
466  LogDebug("L1TGlobal") << "\t\t l1t::Candidate has out of range hwIso = " << cand.hwIso() << std::endl;
467  return false;
468  }
469  bool passIsoLUT = ((objPar.isolationLUT >> cand.hwIso()) & 1);
470  if (!passIsoLUT) {
471  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed isolation requirement" << std::endl;
472  return false;
473  }
474 
475  // check muon TF index
476  if (!checkRangeTfMuonIndex(cand.tfMuonIndex(), objPar.tfMuonIndexWindows)) {
477  LogDebug("L1TGlobal") << "\t\t l1t::Candidate failed checkRangeTfMuonIndex" << std::endl;
478  return false;
479  }
480 
481  // A number of values is required to trigger (at least one).
482  // "Don't care" means that all values are allowed.
483  // Qual = 000 means then NO MUON (GTL module)
484 
485  // if (cand.hwQual() == 0) {
486  // LogDebug("L1TGlobal") << "\t\t Muon Failed hwQual() == 0" << std::endl;
487  // return false;
488  // }
489 
490  // if (objPar.qualityRange == 0) {
491  // LogDebug("L1TGlobal") << "\t\t Muon Failed qualityRange == 0" << std::endl;
492  // return false;
493  // }
494  // else {
495  // if (!checkBit(objPar.qualityRange, cand.hwQual())) {
496  // LogDebug("L1TGlobal") << "\t\t Muon Failed checkBit(qualityRange) " << std::endl;
497  // return false;
498  // }
499  // }
500 
501  // check mip
502  if (objPar.enableMip) {
503  // if (!cand.hwMip()) {
504  // LogDebug("L1TGlobal") << "\t\t Muon Failed enableMip" << std::endl;
505  // return false;
506  // }
507  }
508 
509  // particle matches if we get here
510  //LogTrace("L1TGlobal")
511  // << " checkObjectParameter: muon object OK, passes all requirements\n" << std::endl;
512 
513  return true;
514 }
515 
516 void l1t::MuCondition::print(std::ostream& myCout) const {
517  m_gtMuonTemplate->print(myCout);
518 
519  myCout << " Number of bits for eta of muon objects = " << m_ifMuEtaNumberBits << std::endl;
520  myCout << " Maximum number of bins for the delta phi scales = " << m_corrParDeltaPhiNrBins << "\n " << std::endl;
521 
523 }
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:516
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:328
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:315
unsigned size(int bx) const
unsigned long long etaRange
Definition: MuonTemplate.h:79
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
std::vector< Window > etaWindows
Definition: MuonTemplate.h:85
std::vector< Window > tfMuonIndexWindows
Definition: MuonTemplate.h:92
MuCondition & operator=(const MuCondition &)
Definition: MuCondition.cc:81
#define LogDebug(id)