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  // condition result condResult set to true if at least one permutation
192  // passes all requirements
193  // all possible permutations are checked
194  bool condResult = false;
195 
196  // store the indices of the calorimeter objects
197  // from the combination evaluated in the condition
198  SingleCombInCond objectsInComb;
199  objectsInComb.reserve(nObjInCond);
200 
201  // clear the m_combinationsInCond vector
202  combinationsInCond().clear();
203 
204  do {
205  if (--jumpIndex)
206  continue;
207 
208  jumpIndex = jump;
209 
210  // clear the indices in the combination
211  objectsInComb.clear();
212 
213  bool tmpResult = true;
214 
215  // check if there is a permutation that matches object-parameter
216  // requirements
217  for (int i = 0; i < nObjInCond; i++) {
218  tmpResult &= checkObjectParameter(i, *(*candVec)[index[i]]);
219  objectsInComb.push_back(index[i]);
220  }
221 
222  // if permutation does not match particle conditions
223  // skip spatial correlations
224  if (!tmpResult) {
225  continue;
226  }
227 
228  if (m_gtCaloTemplate->wsc()) {
229  // wsc requirements have always nObjInCond = 2
230  // one can use directly index[0] and index[1] to compute
231  // eta and phi differences
232  const int ObjInWscComb = 2;
233  if (nObjInCond != ObjInWscComb) {
234  if (m_verbosity) {
235  edm::LogError("L1GlobalTrigger")
236  << "\n Error: "
237  << "number of particles in condition with spatial correlation = " << nObjInCond
238  << "\n it must be = " << ObjInWscComb << std::endl;
239  }
240 
241  continue;
242  }
243 
245 
246  unsigned int candDeltaEta;
247  unsigned int candDeltaPhi;
248 
249  // check candDeltaEta
250 
251  // get eta index and the sign bit of the eta index (MSB is the sign)
252  // signedEta[i] is the signed eta index of candVec[index[i]]
253  int signedEta[ObjInWscComb];
254  int signBit[ObjInWscComb] = {0, 0};
255 
256  int scaleEta = 1 << (m_ifCaloEtaNumberBits - 1);
257 
258  for (int i = 0; i < ObjInWscComb; ++i) {
259  signBit[i] = ((*candVec)[index[i]]->etaIndex() & scaleEta) >> (m_ifCaloEtaNumberBits - 1);
260  signedEta[i] = ((*candVec)[index[i]]->etaIndex()) % scaleEta;
261 
262  if (signBit[i] == 1) {
263  signedEta[i] = (-1) * signedEta[i];
264  }
265  }
266 
267  // compute candDeltaEta - add 1 if signs are different (due to +0/-0
268  // indices)
269  candDeltaEta =
270  static_cast<int>(std::abs(signedEta[1] - signedEta[0])) + static_cast<int>(signBit[1] ^ signBit[0]);
271 
272  if (!checkBit(corrPar.deltaEtaRange, candDeltaEta)) {
273  continue;
274  }
275 
276  // check candDeltaPhi
277 
278  // calculate absolute value of candDeltaPhi
279  if ((*candVec)[index[0]]->phiIndex() > (*candVec)[index[1]]->phiIndex()) {
280  candDeltaPhi = (*candVec)[index[0]]->phiIndex() - (*candVec)[index[1]]->phiIndex();
281  } else {
282  candDeltaPhi = (*candVec)[index[1]]->phiIndex() - (*candVec)[index[0]]->phiIndex();
283  }
284 
285  // check if candDeltaPhi > 180 (via delta_phi_maxbits)
286  // delta_phi contains bits for 0..180 (0 and 180 included)
287  // protect also against infinite loop...
288 
289  int nMaxLoop = 10;
290  int iLoop = 0;
291 
292  while (candDeltaPhi >= m_corrParDeltaPhiNrBins) {
293  unsigned int candDeltaPhiInitial = candDeltaPhi;
294 
295  // candDeltaPhi > 180 ==> take 360 - candDeltaPhi
296  candDeltaPhi = (m_corrParDeltaPhiNrBins - 1) * 2 - candDeltaPhi;
297  if (m_verbosity) {
298  LogTrace("L1GlobalTrigger") << " Initial candDeltaPhi = " << candDeltaPhiInitial
299  << " > m_corrParDeltaPhiNrBins = " << m_corrParDeltaPhiNrBins
300  << " ==> candDeltaPhi rescaled to: " << candDeltaPhi << " [ loop index " << iLoop
301  << "; breaks after " << nMaxLoop << " loops ]\n"
302  << std::endl;
303  }
304 
305  iLoop++;
306  if (iLoop > nMaxLoop) {
307  return false;
308  }
309  }
310 
311  if (!checkBit(corrPar.deltaPhiRange, candDeltaPhi)) {
312  continue;
313  }
314 
315  } // end wsc check
316 
317  // if we get here all checks were successful for this combination
318  // set the general result for evaluateCondition to "true"
319 
320  condResult = true;
321  combinationsInCond().push_back(objectsInComb);
322 
323  // } while ( std::next_permutation(index, index + nObj) );
324  } while (std::next_permutation(index.begin(), index.end()));
325 
326  return condResult;
327 }
328 
329 // load calo candidates
330 const L1GctCand *L1GtCaloCondition::getCandidate(const int indexCand) const {
331  // objectType() gives the type for nrObjects() only,
332  // but in a CondCalo all objects have the same type
333  // take type from the type of the first object
334  switch ((m_gtCaloTemplate->objectType())[0]) {
335  case NoIsoEG:
336  return (*(m_gtPSB->getCandL1NoIsoEG()))[indexCand];
337  break;
338  case IsoEG:
339  return (*(m_gtPSB->getCandL1IsoEG()))[indexCand];
340  break;
341  case CenJet:
342  return (*(m_gtPSB->getCandL1CenJet()))[indexCand];
343  break;
344  case ForJet:
345  return (*(m_gtPSB->getCandL1ForJet()))[indexCand];
346  break;
347  case TauJet:
348  return (*(m_gtPSB->getCandL1TauJet()))[indexCand];
349  break;
350  default:
351  return nullptr;
352  break;
353  }
354 
355  return nullptr;
356 }
357 
367 const bool L1GtCaloCondition::checkObjectParameter(const int iCondition, const L1GctCand &cand) const {
368  // number of objects in condition
369  int nObjInCond = m_gtCaloTemplate->nrObjects();
370 
371  if (iCondition >= nObjInCond || iCondition < 0) {
372  return false;
373  }
374 
375  // empty candidates can not be compared
376  if (cand.empty()) {
377  return false;
378  }
379 
380  const L1GtCaloTemplate::ObjectParameter objPar = (*(m_gtCaloTemplate->objectParameter()))[iCondition];
381 
382  // check energy threshold
383  if (!checkThreshold(objPar.etThreshold, cand.rank(), m_gtCaloTemplate->condGEq())) {
384  return false;
385  }
386 
387  // check eta
388  if (!checkBit(objPar.etaRange, cand.etaIndex())) {
389  return false;
390  }
391 
392  // check phi
393 
394  if (!checkBit(objPar.phiRange, cand.phiIndex())) {
395  return false;
396  }
397 
398  // particle matches if we get here
399  // LogTrace("L1GlobalTrigger")
400  // << " checkObjectParameter: calorimeter object OK, passes all
401  // requirements\n"
402  // << std::endl;
403 
404  return true;
405 }
406 
407 void L1GtCaloCondition::print(std::ostream &myCout) const {
408  m_gtCaloTemplate->print(myCout);
409 
410  myCout << " Number of bits for eta of calorimeter objects = " << m_ifCaloEtaNumberBits << std::endl;
411  myCout << " Maximum number of bins for the delta phi scales = " << m_corrParDeltaPhiNrBins << "\n " << std::endl;
412 
414 }
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 &)