CMS 3D CMS Logo

L1GtCaloCondition.cc
Go to the documentation of this file.
1 
15 // this class header
17 
18 // system include files
19 #include <iomanip>
20 #include <iostream>
21 
22 #include <algorithm>
23 #include <string>
24 #include <vector>
25 
26 // user include files
27 // base classes
30 
32 
36 
39 
42 
45 
46 // constructors
47 // default
49 
52 }
53 
54 // from base template condition (from event setup usually)
56  const L1GlobalTriggerPSB *ptrPSB,
57  const int nrL1NoIsoEG, const int nrL1IsoEG,
58  const int nrL1CenJet, const int nrL1ForJet,
59  const int nrL1TauJet,
60  const int ifCaloEtaNumberBits)
62  m_gtCaloTemplate(static_cast<const L1GtCaloTemplate *>(caloTemplate)),
63  m_gtPSB(ptrPSB), m_ifCaloEtaNumberBits(ifCaloEtaNumberBits) {
64 
66 
67  // maximum number of objects received for the evaluation of the condition
68  // retrieved before from event setup
69  // for a CondCalo, all objects ar of same type, hence it is enough to get the
70  // type for the first object
71 
72  switch ((m_gtCaloTemplate->objectType())[0]) {
73  case NoIsoEG:
74  m_condMaxNumberObjects = nrL1NoIsoEG;
75  break;
76  case IsoEG:
77  m_condMaxNumberObjects = nrL1IsoEG;
78  break;
79  case CenJet:
80  m_condMaxNumberObjects = nrL1CenJet;
81  break;
82  case ForJet:
83  m_condMaxNumberObjects = nrL1ForJet;
84  break;
85  case TauJet:
86  m_condMaxNumberObjects = nrL1TauJet;
87  break;
88  default:
90  break;
91  }
92 }
93 
94 // copy constructor
96 
98  m_gtPSB = cp.gtPSB();
99 
102 
106 
108 }
109 
112 
113  copy(cp);
114 }
115 
116 // destructor
118 
119  // empty
120 }
121 
122 // equal operator
124  copy(cp);
125  return *this;
126 }
127 
128 // methods
130 
131  m_gtCaloTemplate = caloTempl;
132 }
133 
136 
137  m_gtPSB = ptrPSB;
138 }
139 
140 // set the number of bits for eta of calorimeter objects
142  const int &ifCaloEtaNumberBitsValue) {
143 
144  m_ifCaloEtaNumberBits = ifCaloEtaNumberBitsValue;
145 }
146 
147 // set the maximum number of bins for the delta phi scales
149  const int &corrParDeltaPhiNrBins) {
150 
151  m_corrParDeltaPhiNrBins = corrParDeltaPhiNrBins;
152 }
153 
154 // try all object permutations and check spatial correlations, if required
156 
157  // number of trigger objects in the condition
158  int nObjInCond = m_gtCaloTemplate->nrObjects();
159  // LogTrace("L1GlobalTrigger") << " nObjInCond: " << nObjInCond
160  // << std::endl;
161 
162  // the candidates
163 
164  // objectType() gives the type for nrObjects() only,
165  // but in a CondCalo all objects have the same type
166  // take type from the type of the first object
167 
168  const std::vector<const L1GctCand *> *candVec;
169 
170  switch ((m_gtCaloTemplate->objectType())[0]) {
171  case NoIsoEG:
172  candVec = m_gtPSB->getCandL1NoIsoEG();
173  break;
174  case IsoEG:
175  candVec = m_gtPSB->getCandL1IsoEG();
176  break;
177  case CenJet:
178  candVec = m_gtPSB->getCandL1CenJet();
179  break;
180  case ForJet:
181  candVec = m_gtPSB->getCandL1ForJet();
182  break;
183  case TauJet:
184  candVec = m_gtPSB->getCandL1TauJet();
185  break;
186  default:
187  return false;
188  break;
189  }
190 
191  int numberObjects = candVec->size();
192  // LogTrace("L1GlobalTrigger") << " numberObjects: " << numberObjects
193  // << std::endl;
194  if (numberObjects < nObjInCond) {
195  return false;
196  }
197 
198  std::vector<int> index(numberObjects);
199 
200  for (int i = 0; i < numberObjects; ++i) {
201  index[i] = i;
202  }
203 
204  int jumpIndex = 1;
205  int jump = factorial(numberObjects - nObjInCond);
206 
207  int totalLoops = 0;
208  int passLoops = 0;
209 
210  // condition result condResult set to true if at least one permutation
211  // passes all requirements
212  // all possible permutations are checked
213  bool condResult = false;
214 
215  // store the indices of the calorimeter objects
216  // from the combination evaluated in the condition
217  SingleCombInCond objectsInComb;
218  objectsInComb.reserve(nObjInCond);
219 
220  // clear the m_combinationsInCond vector
221  combinationsInCond().clear();
222 
223  do {
224 
225  if (--jumpIndex)
226  continue;
227 
228  jumpIndex = jump;
229  totalLoops++;
230 
231  // clear the indices in the combination
232  objectsInComb.clear();
233 
234  bool tmpResult = true;
235 
236  // check if there is a permutation that matches object-parameter
237  // requirements
238  for (int i = 0; i < nObjInCond; i++) {
239 
240  tmpResult &= checkObjectParameter(i, *(*candVec)[index[i]]);
241  objectsInComb.push_back(index[i]);
242  }
243 
244  // if permutation does not match particle conditions
245  // skip spatial correlations
246  if (!tmpResult) {
247 
248  continue;
249  }
250 
251  if (m_gtCaloTemplate->wsc()) {
252 
253  // wsc requirements have always nObjInCond = 2
254  // one can use directly index[0] and index[1] to compute
255  // eta and phi differences
256  const int ObjInWscComb = 2;
257  if (nObjInCond != ObjInWscComb) {
258 
259  if (m_verbosity) {
260  edm::LogError("L1GlobalTrigger")
261  << "\n Error: "
262  << "number of particles in condition with spatial correlation = "
263  << nObjInCond << "\n it must be = " << ObjInWscComb << std::endl;
264  }
265 
266  continue;
267  }
268 
271 
272  unsigned int candDeltaEta;
273  unsigned int candDeltaPhi;
274 
275  // check candDeltaEta
276 
277  // get eta index and the sign bit of the eta index (MSB is the sign)
278  // signedEta[i] is the signed eta index of candVec[index[i]]
279  int signedEta[ObjInWscComb];
280  int signBit[ObjInWscComb] = {0, 0};
281 
282  int scaleEta = 1 << (m_ifCaloEtaNumberBits - 1);
283 
284  for (int i = 0; i < ObjInWscComb; ++i) {
285  signBit[i] = ((*candVec)[index[i]]->etaIndex() & scaleEta) >>
286  (m_ifCaloEtaNumberBits - 1);
287  signedEta[i] = ((*candVec)[index[i]]->etaIndex()) % scaleEta;
288 
289  if (signBit[i] == 1) {
290  signedEta[i] = (-1) * signedEta[i];
291  }
292  }
293 
294  // compute candDeltaEta - add 1 if signs are different (due to +0/-0
295  // indices)
296  candDeltaEta = static_cast<int>(std::abs(signedEta[1] - signedEta[0])) +
297  static_cast<int>(signBit[1] ^ signBit[0]);
298 
299  if (!checkBit(corrPar.deltaEtaRange, candDeltaEta)) {
300  continue;
301  }
302 
303  // check candDeltaPhi
304 
305  // calculate absolute value of candDeltaPhi
306  if ((*candVec)[index[0]]->phiIndex() > (*candVec)[index[1]]->phiIndex()) {
307  candDeltaPhi =
308  (*candVec)[index[0]]->phiIndex() - (*candVec)[index[1]]->phiIndex();
309  } else {
310  candDeltaPhi =
311  (*candVec)[index[1]]->phiIndex() - (*candVec)[index[0]]->phiIndex();
312  }
313 
314  // check if candDeltaPhi > 180 (via delta_phi_maxbits)
315  // delta_phi contains bits for 0..180 (0 and 180 included)
316  // protect also against infinite loop...
317 
318  int nMaxLoop = 10;
319  int iLoop = 0;
320 
321  while (candDeltaPhi >= m_corrParDeltaPhiNrBins) {
322 
323  unsigned int candDeltaPhiInitial = candDeltaPhi;
324 
325  // candDeltaPhi > 180 ==> take 360 - candDeltaPhi
326  candDeltaPhi = (m_corrParDeltaPhiNrBins - 1) * 2 - candDeltaPhi;
327  if (m_verbosity) {
328  LogTrace("L1GlobalTrigger")
329  << " Initial candDeltaPhi = " << candDeltaPhiInitial
330  << " > m_corrParDeltaPhiNrBins = " << m_corrParDeltaPhiNrBins
331  << " ==> candDeltaPhi rescaled to: " << candDeltaPhi
332  << " [ loop index " << iLoop << "; breaks after " << nMaxLoop
333  << " loops ]\n"
334  << std::endl;
335  }
336 
337  iLoop++;
338  if (iLoop > nMaxLoop) {
339  return false;
340  }
341  }
342 
343  if (!checkBit(corrPar.deltaPhiRange, candDeltaPhi)) {
344  continue;
345  }
346 
347  } // end wsc check
348 
349  // if we get here all checks were successful for this combination
350  // set the general result for evaluateCondition to "true"
351 
352  condResult = true;
353  passLoops++;
354  combinationsInCond().push_back(objectsInComb);
355 
356  // } while ( std::next_permutation(index, index + nObj) );
357  } while (std::next_permutation(index.begin(), index.end()));
358 
359  // LogTrace("L1GlobalTrigger")
360  // << "\n L1GtCaloCondition: total number of permutations found: " <<
361  // totalLoops
362  // << "\n L1GtCaloCondition: number of permutations passing requirements:
363  // " << passLoops
364  // << "\n" << std::endl;
365 
366  return condResult;
367 }
368 
369 // load calo candidates
370 const L1GctCand *L1GtCaloCondition::getCandidate(const int indexCand) const {
371 
372  // objectType() gives the type for nrObjects() only,
373  // but in a CondCalo all objects have the same type
374  // take type from the type of the first object
375  switch ((m_gtCaloTemplate->objectType())[0]) {
376  case NoIsoEG:
377  return (*(m_gtPSB->getCandL1NoIsoEG()))[indexCand];
378  break;
379  case IsoEG:
380  return (*(m_gtPSB->getCandL1IsoEG()))[indexCand];
381  break;
382  case CenJet:
383  return (*(m_gtPSB->getCandL1CenJet()))[indexCand];
384  break;
385  case ForJet:
386  return (*(m_gtPSB->getCandL1ForJet()))[indexCand];
387  break;
388  case TauJet:
389  return (*(m_gtPSB->getCandL1TauJet()))[indexCand];
390  break;
391  default:
392  return nullptr;
393  break;
394  }
395 
396  return nullptr;
397 }
398 
408 const bool
410  const L1GctCand &cand) const {
411 
412  // number of objects in condition
413  int nObjInCond = m_gtCaloTemplate->nrObjects();
414 
415  if (iCondition >= nObjInCond || iCondition < 0) {
416  return false;
417  }
418 
419  // empty candidates can not be compared
420  if (cand.empty()) {
421  return false;
422  }
423 
424  const L1GtCaloTemplate::ObjectParameter objPar =
425  (*(m_gtCaloTemplate->objectParameter()))[iCondition];
426 
427  // check energy threshold
428  if (!checkThreshold(objPar.etThreshold, cand.rank(),
430  return false;
431  }
432 
433  // check eta
434  if (!checkBit(objPar.etaRange, cand.etaIndex())) {
435  return false;
436  }
437 
438  // check phi
439 
440  if (!checkBit(objPar.phiRange, cand.phiIndex())) {
441  return false;
442  }
443 
444  // particle matches if we get here
445  // LogTrace("L1GlobalTrigger")
446  // << " checkObjectParameter: calorimeter object OK, passes all
447  // requirements\n"
448  // << std::endl;
449 
450  return true;
451 }
452 
453 void L1GtCaloCondition::print(std::ostream &myCout) const {
454 
455  m_gtCaloTemplate->print(myCout);
456 
457  myCout << " Number of bits for eta of calorimeter objects = "
458  << m_ifCaloEtaNumberBits << std::endl;
459  myCout << " Maximum number of bins for the delta phi scales = "
460  << m_corrParDeltaPhiNrBins << "\n " << std::endl;
461 
463 }
const std::vector< const L1GctCand * > * getCandL1IsoEG() const
pointer to IsoEG data list
int m_ifCaloEtaNumberBits
number of bits for eta of calorimeter objects
const int nrObjects() const
get number of trigger objects
const bool checkBit(const Type1 &mask, const unsigned int bitNumber) const
check if a bit with a given number is set in a mask
~L1GtCaloCondition() override
const std::vector< const L1GctCand * > * getCandL1ForJet() const
pointer to ForJet data list
bool m_condLastResult
the last result of evaluateCondition()
virtual bool empty() const =0
empty candidate - true if object not initialized
const int gtIfCaloEtaNumberBits() const
get / set the number of bits for eta of calorimeter objects
CombinationsInCond m_combinationsInCond
store all the object combinations evaluated to true in the condition
CombinationsInCond & combinationsInCond() const
get all the object combinations (to fill it...)
void print(std::ostream &myCout) const override
print the condition
std::vector< int > SingleCombInCond
typedefs
const L1GlobalTriggerPSB * m_gtPSB
pointer to PSB, to be able to get the trigger objects
const std::vector< L1GtObject > & objectType() const
get / set the trigger object type(s) in the condition
Definition: L1GtCondition.h:90
const L1GctCand * getCandidate(const int indexCand) const
load calo candidates
void setGtCaloTemplate(const L1GtCaloTemplate *)
virtual unsigned phiIndex() const =0
get phi index (0-17)
const bool checkObjectParameter(const int iCondition, const L1GctCand &cand) const
function to check a single object if it matches a condition
const L1GlobalTriggerPSB * gtPSB() const
get / set the pointer to PSB
const L1GtCaloTemplate * m_gtCaloTemplate
pointer to a L1GtCaloTemplate
L1GtCaloCondition & operator=(const L1GtCaloCondition &)
const bool wsc() const
const bool checkThreshold(const Type1 &threshold, const Type2 &value, const bool condGEqValue) const
const L1GtCaloTemplate * gtCaloTemplate() const
get / set the pointer to a L1GtCondition
void setGtIfCaloEtaNumberBits(const int &)
virtual unsigned etaIndex() const =0
get eta index (bit 3 is sign, 1 for -ve Z, 0 for +ve Z)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void copy(const L1GtCaloCondition &cp)
copy function for copy constructor and operator=
typedef for a single object template
unsigned int m_corrParDeltaPhiNrBins
typedef for correlation parameters
const bool evaluateCondition() const override
the core function to check if the condition matches
#define LogTrace(id)
void setGtPSB(const L1GlobalTriggerPSB *)
set the pointer to PSB
virtual unsigned rank() const =0
get the rank code (6 bits)
void print(std::ostream &myCout) const override
print condition
const CorrelationParameter * correlationParameter() const
const std::vector< const L1GctCand * > * getCandL1TauJet() const
pointer to TauJet data list
ABC for GCT EM and jet candidates.
Definition: L1GctCand.h:12
int factorial(int n)
factorial function
virtual void print(std::ostream &myCout) const
print condition
const bool condGEq() const
get / set condition GEq flag
const std::vector< ObjectParameter > * objectParameter() const
const std::vector< const L1GctCand * > * getCandL1CenJet() const
pointer to CenJet data list
const std::vector< const L1GctCand * > * getCandL1NoIsoEG() const
pointer to NoIsoEG data list
CombinationsInCond const & getCombinationsInCond() const
get all the object combinations evaluated to true in the condition
bool condLastResult() const
get the latest result for the condition
void setGtCorrParDeltaPhiNrBins(const int &)