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