CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
L1GtMuonCondition.cc
Go to the documentation of this file.
1 
17 // this class header
19 
20 // system include files
21 #include <iostream>
22 #include <iomanip>
23 
24 #include <string>
25 #include <vector>
26 #include <algorithm>
27 
28 // user include files
29 // base classes
32 
34 
36 
39 
42 
43 // constructors
44 // default
47 
48  // empty
49 
50 }
51 
52 // from base template condition (from event setup usually)
54  const L1GlobalTriggerGTL* ptrGTL, const int nrL1Mu,
55  const int ifMuEtaNumberBits) :
57  m_gtMuonTemplate(static_cast<const L1GtMuonTemplate*>(muonTemplate)),
58  m_gtGTL(ptrGTL),
59  m_ifMuEtaNumberBits(ifMuEtaNumberBits)
60 {
61 
62  m_condMaxNumberObjects = nrL1Mu;
63 }
64 
65 // copy constructor
67 
69  m_gtGTL = cp.gtGTL();
70 
72 
76 
78 
79 }
80 
83  copy(cp);
84 }
85 
86 // destructor
88 
89  // empty
90 
91 }
92 
93 // equal operator
95 {
96  copy(cp);
97  return *this;
98 }
99 
100 // methods
102 
103  m_gtMuonTemplate = muonTempl;
104 
105 }
106 
107 // set the number of bits for eta of muon objects
108 void L1GtMuonCondition::setGtIfMuEtaNumberBits(const int& ifMuEtaNumberBitsValue) {
109 
110  m_ifMuEtaNumberBits = ifMuEtaNumberBitsValue;
111 
112 }
113 
116 
117  m_gtGTL = ptrGTL;
118 
119 }
120 
121 // try all object permutations and check spatial correlations, if required
123 
124  // number of trigger objects in the condition
125  int nObjInCond = m_gtMuonTemplate->nrObjects();
126 
127  // the candidates
128  const std::vector<const L1MuGMTCand*>* candVec = m_gtGTL->getCandL1Mu();
129 
130  int numberObjects = candVec->size();
131  //LogTrace("L1GtCaloCondition") << " numberObjects: " << numberObjects
132  // << std::endl;
133  if (numberObjects < nObjInCond) {
134  return false;
135  }
136 
137  std::vector<int> index(numberObjects);
138 
139  for (int i = 0; i < numberObjects; ++i) {
140  index[i] = i;
141  }
142 
143  int jumpIndex = 1;
144  int jump = factorial(numberObjects - nObjInCond);
145 
146  int totalLoops = 0;
147  int passLoops = 0;
148 
149  // condition result condResult set to true if at least one permutation
150  // passes all requirements
151  // all possible permutations are checked
152  bool condResult = false;
153 
154  // store the indices of the muon objects
155  // from the combination evaluated in the condition
156  SingleCombInCond objectsInComb;
157  objectsInComb.reserve(nObjInCond);
158 
159  // clear the m_combinationsInCond vector
160  (*m_combinationsInCond).clear();
161 
162  do {
163 
164  if (--jumpIndex)
165  continue;
166 
167  jumpIndex = jump;
168  totalLoops++;
169 
170  // clear the indices in the combination
171  objectsInComb.clear();
172 
173  bool tmpResult = true;
174 
175  // check if there is a permutation that matches object-parameter requirements
176  for (int i = 0; i < nObjInCond; i++) {
177 
178  tmpResult &= checkObjectParameter(i, *(*candVec)[index[i]]);
179  objectsInComb.push_back(index[i]);
180 
181  }
182 
183  // if permutation does not match particle conditions
184  // skip charge correlation and spatial correlations
185  if ( !tmpResult) {
186 
187  continue;
188 
189  }
190 
191  // get the correlation parameters (chargeCorrelation included here also)
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 
201  for (int i = 0; i < nObjInCond; i++) {
202  // check valid charge - skip if invalid charge
203  bool chargeValid = (*candVec)[index[i]]->charge_valid();
204  tmpResult &= chargeValid;
205 
206  if ( !chargeValid) {
207  continue;
208  }
209  }
210 
211  if ( !tmpResult) {
212  continue;
213  }
214 
215  if (nObjInCond == 1) { // one object condition
216 
217  // D2..enable pos, D1..enable neg
218  if ( ! ( ( (chargeCorr & 4) != 0 && (*candVec)[index[0]]->charge()> 0 )
219  || ( (chargeCorr & 2) != 0 && (*candVec)[index[0]]->charge() < 0 ) )) {
220 
221  continue;
222  }
223 
224  }
225  else { // more objects condition
226 
227  // find out if signs are equal
228  bool equalSigns = true;
229  for (int i = 0; i < nObjInCond-1; i++) {
230  if ((*candVec)[index[i]]->charge() != (*candVec)[index[i+1]]->charge()) {
231  equalSigns = false;
232  break;
233  }
234  }
235 
236  // two or three particle condition
237  if (nObjInCond == 2 || nObjInCond == 3) {
238  // D2..enable equal, D1..enable not equal
239  if ( ! ( ( (chargeCorr & 4) != 0 && equalSigns ) || ( (chargeCorr & 2) != 0
240  && !equalSigns ) )) {
241 
242  continue;
243  }
244  }
245 
246  // four particle condition
247  if (nObjInCond == 4) {
248  //counter to count positive charges to determine if there are pairs
249  unsigned int posCount = 0;
250 
251  for (int i = 0; i < nObjInCond; i++) {
252  if ((*candVec)[index[i]]->charge()> 0) {
253  posCount++;
254  }
255  }
256 
257  // D2..enable equal, D1..enable pairs
258  if ( ! ( ( (chargeCorr & 4) != 0 && equalSigns ) || ( (chargeCorr & 2) != 0
259  && posCount == 2 ) )) {
260 
261  continue;
262  }
263  }
264  }
265  } // end signchecks
266 
267 
268  if (m_gtMuonTemplate->wsc()) {
269 
270  // wsc requirements have always nObjInCond = 2
271  // one can use directly index[0] and index[1] to compute
272  // eta and phi differences
273  const int ObjInWscComb = 2;
274  if (nObjInCond != ObjInWscComb) {
275 
276  edm::LogError("L1GtMuonCondition") << "\n Error: "
277  << "number of particles in condition with spatial correlation = " << nObjInCond
278  << "\n it must be = " << ObjInWscComb << std::endl;
279  // TODO Perhaps I should throw here an exception,
280  // since something is really wrong if nObjInCond != ObjInWscComb (=2)
281  continue;
282  }
283 
284  unsigned int candDeltaEta;
285  unsigned int candDeltaPhi;
286 
287  // check candDeltaEta
288 
289  // get eta index and the sign bit of the eta index (MSB is the sign)
290  // signedEta[i] is the signed eta index of (*candVec)[index[i]]
291  int signedEta[ObjInWscComb];
292  int signBit[ObjInWscComb] = { 0, 0 };
293 
294  int scaleEta = 1 << (m_ifMuEtaNumberBits - 1);
295 
296  for (int i = 0; i < ObjInWscComb; ++i) {
297  signBit[i] = ((*candVec)[index[i]]->etaIndex() & scaleEta)>>(m_ifMuEtaNumberBits - 1);
298  signedEta[i] = ((*candVec)[index[i]]->etaIndex() )%scaleEta;
299 
300  if (signBit[i] == 1) {
301  signedEta[i] = (-1)*signedEta[i];
302  }
303 
304  }
305 
306  // compute candDeltaEta - add 1 if signs are different (due to +0/-0 indices)
307  candDeltaEta = static_cast<int> (std::abs(signedEta[1] - signedEta[0]))
308  + static_cast<int> (signBit[1]^signBit[0]);
309 
310  if ( !checkBit(corrPar.deltaEtaRange, candDeltaEta) ) {
311  continue;
312  }
313 
314  // check candDeltaPhi
315 
316  // calculate absolute value of candDeltaPhi
317  if ((*candVec)[index[0]]->phiIndex()> (*candVec)[index[1]]->phiIndex()) {
318  candDeltaPhi = (*candVec)[index[0]]->phiIndex() - (*candVec)[index[1]]->phiIndex();
319  }
320  else {
321  candDeltaPhi = (*candVec)[index[1]]->phiIndex() - (*candVec)[index[0]]->phiIndex();
322  }
323 
324  // check if candDeltaPhi > 180 (via delta_phi_maxbits)
325  // delta_phi contains bits for 0..180 (0 and 180 included)
326  while (candDeltaPhi> corrPar.deltaPhiMaxbits) {
327 
328  // candDeltaPhi > 180 ==> take 360 - candDeltaPhi
329  candDeltaPhi = (corrPar.deltaPhiMaxbits - 1)*2 - candDeltaPhi;
330  LogTrace("L1GtMuonCondition") << " candDeltaPhi rescaled to: " << candDeltaPhi
331  << std::endl;
332  }
333 
334  // delta_phi bitmask is saved in two boost::uint64_t words
335  if (candDeltaPhi < 64) {
336  if (!checkBit(corrPar.deltaPhiRange0Word, candDeltaPhi) ) {
337  continue;
338  }
339  }
340  else {
341  if (!checkBit(corrPar.deltaPhiRange1Word, (candDeltaPhi - 64))) {
342  continue;
343  }
344  }
345 
346  } // end wsc check
347 
348  // if we get here all checks were successfull for this combination
349  // set the general result for evaluateCondition to "true"
350 
351  condResult = true;
352  passLoops++;
353  (*m_combinationsInCond).push_back(objectsInComb);
354 
355  } while (std::next_permutation(index.begin(), index.end()) );
356 
357  //LogTrace("L1GtMuonCondition")
358  // << "\n L1GtMuonCondition: total number of permutations found: " << totalLoops
359  // << "\n L1GtMuonCondition: number of permutations passing requirements: " << passLoops
360  // << "\n" << std::endl;
361 
362  return condResult;
363 
364 }
365 
366 // load muon candidates
367 const L1MuGMTCand* L1GtMuonCondition::getCandidate(const int indexCand) const {
368 
369  return (*(m_gtGTL->getCandL1Mu()))[indexCand];
370 }
371 
381 const bool L1GtMuonCondition::checkObjectParameter(const int iCondition, const L1MuGMTCand& cand) const {
382 
383  // number of objects in condition
384  int nObjInCond = m_gtMuonTemplate->nrObjects();
385 
386  if (iCondition >= nObjInCond || iCondition < 0) {
387  return false;
388  }
389 
390  // empty candidates can not be compared
391  if (cand.empty()) {
392  return false;
393  }
394 
395  const L1GtMuonTemplate::ObjectParameter objPar =
396  ( *(m_gtMuonTemplate->objectParameter()) )[iCondition];
397 
398  // using the logic table from GTL-9U-module.pdf
399  // "Truth table for Isolation bit"
400 
401  // check thresholds:
402 
403  // value < low pt threshold
404  // fail trigger
405 
406  // low pt threshold <= value < high pt threshold & non-isolated muon:
407  // requestIso true: fail trigger
408  // requestIso false, enableIso true: fail trigger
409  // requestIso false, enableIso false: OK, trigger
410 
411  // low pt threshold <= value < high pt threshold & isolated muon:
412  // requestIso true: OK, trigger
413  // requestIso false, enableIso true: OK, trigger
414  // requestIso false, enableIso false: OK, trigger
415 
416  // value >= high pt threshold & non-isolated muon:
417  // requestIso true: fail trigger
418  // requestIso false: OK, trigger
419 
420  // value >= high pt threshold & isolated muon:
421  // OK, trigger
422 
423 
424  if ( !checkThreshold(objPar.ptHighThreshold, cand.ptIndex(), m_gtMuonTemplate->condGEq()) ) {
425 
426  if ( !checkThreshold(objPar.ptLowThreshold, cand.ptIndex(), m_gtMuonTemplate->condGEq()) ) {
427 
428  return false;
429  }
430  else {
431 
432  // check isolation
433  if ( !cand.isol() ) {
434  if (objPar.requestIso || objPar.enableIso) {
435 
436  return false;
437  }
438  }
439 
440  }
441 
442  }
443  else {
444 
445  if ( !cand.isol() ) {
446  if (objPar.requestIso) {
447 
448  return false;
449  }
450  }
451 
452  }
453 
454  // check eta
455 
456  if (!checkBit(objPar.etaRange, cand.etaIndex())) {
457  return false;
458  }
459 
460  // check phi - in the requested range (no LUT used - LUT too big for hw chip)
461  // for phiLow <= phiHigh takes [phiLow, phiHigh]
462  // for phiLow >= phiHigh takes [phiLow, phiHigh] over zero angle!
463 
464  if (objPar.phiHigh >= objPar.phiLow) {
465 
466  if (! ( (objPar.phiLow <= cand.phiIndex()) && (cand.phiIndex() <= objPar.phiHigh ) )) {
467 
468  return false;
469  }
470 
471  }
472  else { // go over zero angle!!
473  if (! ( (objPar.phiLow <= cand.phiIndex()) || (cand.phiIndex() <= objPar.phiHigh ) )) {
474 
475  return false;
476  }
477  }
478 
479  // check quality ( bit check )
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.quality() == 0) {
486  return false;
487  }
488 
489  if (objPar.qualityRange == 0) {
490  return false;
491  }
492  else {
493  if (!checkBit(objPar.qualityRange, cand.quality())) {
494  return false;
495  }
496  }
497 
498  // check mip
499  if (objPar.enableMip) {
500  if (!cand.mip()) {
501 
502  return false;
503  }
504  }
505 
506  // particle matches if we get here
507  //LogTrace("L1GtMuonCondition")
508  // << " checkObjectParameter: muon object OK, passes all requirements\n" << std::endl;
509 
510  return true;
511 }
512 
513 void L1GtMuonCondition::print(std::ostream& myCout) const {
514 
515  m_gtMuonTemplate->print(myCout);
517 
518 }
519 
L1GtMuonCondition & operator=(const L1GtMuonCondition &)
int i
Definition: DBlmapReader.cc:9
CombinationsInCond * m_combinationsInCond
store all the object combinations evaluated to true in the condition
const int nrObjects() const
get number of trigger objects
const CorrelationParameter * correlationParameter() const
const bool checkBit(const Type1 &mask, const unsigned int bitNumber) const
check if a bit with a given number is set in a mask
virtual ~L1GtMuonCondition()
CombinationsInCond * getCombinationsInCond() const
get all the object combinations evaluated to true in the condition
bool m_condLastResult
the last result of evaluateCondition()
unsigned int phiIndex() const
get phi-code
Definition: L1MuGMTCand.h:75
void setGtIfMuEtaNumberBits(const int &)
#define abs(x)
Definition: mlp_lapack.h:159
unsigned int etaIndex() const
get eta-code
Definition: L1MuGMTCand.h:110
void copy(const L1GtMuonCondition &cp)
copy function for copy constructor and operator=
std::vector< int > SingleCombInCond
typedefs
int m_ifMuEtaNumberBits
number of bits for eta of muon objects
const L1GtMuonTemplate * m_gtMuonTemplate
pointer to a L1GtMuonTemplate
double charge(const std::vector< uint8_t > &Ampls)
bool isol() const
get isolation
Definition: L1MuGMTCand.h:116
const int gtIfMuEtaNumberBits() const
get / set the number of bits for eta of muon objects
bool empty() const
is it an empty muon candidate?
Definition: L1MuGMTCand.h:66
const bool wsc() const
const bool checkThreshold(const Type1 &threshold, const Type2 &value, const bool condGEqValue) const
const L1MuGMTCand * getCandidate(const int indexCand) const
load muon candidates
const L1GlobalTriggerGTL * gtGTL() const
get / set the pointer to GTL
const std::vector< ObjectParameter > * objectParameter() const
bool mip() const
get mip
Definition: L1MuGMTCand.h:119
const bool checkObjectParameter(const int iCondition, const L1MuGMTCand &cand) const
function to check a single object if it matches a condition
#define LogTrace(id)
void setGtGTL(const L1GlobalTriggerGTL *)
set the pointer to GTL
unsigned int quality() const
get quality
Definition: L1MuGMTCand.h:95
void setGtMuonTemplate(const L1GtMuonTemplate *)
const bool evaluateCondition() const
the core function to check if the condition matches
const L1GlobalTriggerGTL * m_gtGTL
pointer to GTL, to be able to get the trigger objects
virtual void print(std::ostream &myCout) const
print the condition
string const
Definition: compareJSON.py:14
const L1GtMuonTemplate * gtMuonTemplate() const
get / set the pointer to a L1GtCondition
void print(std::ostream &myCout) const
print condition
int factorial(int n)
factorial function
virtual void print(std::ostream &myCout) const
print condition
const bool condGEq() const
get / set condition GEq flag
Definition: L1GtCondition.h:99
const std::vector< const L1MuGMTCand * > * getCandL1Mu() const
return global muon trigger candidate
unsigned int ptIndex() const
get pt-code
Definition: L1MuGMTCand.h:78
bool condLastResult() const
get the latest result for the condition