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