ATLAS Offline Software
Loading...
Searching...
No Matches
CPMTobAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4/***************************************************************************
5 CPMTobAlgorithm.cxx - description
6 -------------------
7 begin : Thu 6 Mar 2014
8 Derived from CPAlgorithm (Run 1 version)
9 email : Alan.Watson@cern.ch
10 ***************************************************************************/
11
17#include "TrigConfData/L1Menu.h"
18
19#include <math.h>
20
21namespace LVL1 {
22using namespace TrigConf;
23
24const unsigned int CPMTobAlgorithm::m_maxClus = 0xFF;
25const double CPMTobAlgorithm::m_maxEta = 2.5;
26
27const unsigned int CPMTobAlgorithm::m_emLUT_ClusterFirstBit = 1;
28const unsigned int CPMTobAlgorithm::m_emLUT_ClusterNBits = 6;
29const unsigned int CPMTobAlgorithm::m_emLUT_EMIsolFirstBit = 0;
30const unsigned int CPMTobAlgorithm::m_emLUT_EMIsolNBits = 4;
31const unsigned int CPMTobAlgorithm::m_emLUT_HadVetoFirstBit = 0;
32const unsigned int CPMTobAlgorithm::m_emLUT_HadVetoNBits = 3;
33
35const unsigned int CPMTobAlgorithm::m_tauLUT_ClusterNBits = 7;
36const unsigned int CPMTobAlgorithm::m_tauLUT_EMIsolFirstBit = 0;
37const unsigned int CPMTobAlgorithm::m_tauLUT_EMIsolNBits = 6;
38
39const unsigned int CPMTobAlgorithm::m_noIsol = 999;
40
42 const TrigConf::L1Menu * l1menu, int slice ):
43 m_l1menu(l1menu),
44 m_Core(0),
45 m_EMClus(0),
46 m_TauClus(0),
47 m_EMIsolWord(0),
49 m_EMCore(0),
50 m_EMIsol(0),
51 m_HadCore(0),
52 m_HadIsol(0),
53 m_EtMax(false),
54 m_EMThresh(false),
55 m_TauThresh(false)
56 //m_debug(false)
57{
70
71 TriggerTowerKey get(phi-M_PI/128.,eta-0.025);
72 Coordinate refCoord = get.coord();
73 m_refEta = refCoord.eta();
74 m_refPhi = refCoord.phi();
75
76 // Set coordinate of centre of RoI, starting from reference tower coordinate
78
92
93 std::vector<unsigned int> emEt(4);
94 std::vector<unsigned int> cores(9);
95 for (int etaOffset = -1; etaOffset <= 2; etaOffset++) {
96 double tempEta = m_refEta + etaOffset*0.1;
97 for (int phiOffset = -1; phiOffset <= 2; phiOffset++) {
98 double tempPhi = m_refPhi + phiOffset*M_PI/32;
99 int key = get.ttKey(tempPhi, tempEta);
100 xAOD::CPMTowerMap_t::const_iterator tt = ttContainer->find(key);
101 if (tt != ttContainer->end() && fabs(tempEta) < m_maxEta) {
102 // Get the TT ET values once here, rather than repeat function calls
103 int emTT = 0;
104 int hadTT = 0;
105 if (slice < 0) { // Default to using peak slice
106 emTT = (tt->second)->emEnergy();
107 hadTT = (tt->second)->hadEnergy();
108 }
109 else { // Use user-specified slice
110 emTT = (tt->second)->emSliceEnergy(slice);
111 hadTT = (tt->second)->hadSliceEnergy(slice);
112 }
113 // EM Trigger Clusters and Core clusters
114 if (etaOffset >= 0 && etaOffset <= 1 && phiOffset >= 0 && phiOffset <= 1) {
115 emEt[phiOffset+2*etaOffset] = emTT;
116 m_EMCore += emTT;
117 m_HadCore += hadTT;
118 }
119 // Isolation sums
120 else {
121 m_EMIsol += emTT;
122 m_HadIsol += hadTT;
123 }
124 // Each tower is part of up to 4 RoI core clusters
125 if (etaOffset >= 0) {
126 if (phiOffset >= 0) cores[phiOffset+3*etaOffset] += emTT + hadTT;
127 if (phiOffset < 2) cores[phiOffset+3*etaOffset+1] += emTT + hadTT;
128 }
129 if (etaOffset < 2) {
130 if (phiOffset >= 0) cores[phiOffset+3*etaOffset+3] += emTT + hadTT;
131 if (phiOffset < 2) cores[phiOffset+3*etaOffset+4] += emTT + hadTT;
132 }
133
134 }
135 } // phi offset loop
136 } // eta offset loop
137
138 // Core of this window is cores[4]
139 m_Core = cores[4];
140
141 // Form most energetic 2-tower EM cluster
142 m_EMClus = ( (emEt[0] > emEt[3]) ? emEt[0] : emEt[3] )
143 + ( (emEt[1] > emEt[2]) ? emEt[1] : emEt[2] );
144
145 // Tau cluster
147
148 // Check whether RoI condition is met.
149 testEtMax(cores);
150
151 // test cluster and isolation conditions
152 emAlgorithm();
153 tauAlgorithm();
154
155}
156
159
163
164 // TriggerTowerKey::coord() returns centre of TriggerTower
165 TriggerTowerKey keyLL(phi,eta);
166 Coordinate lowerLeft = keyLL.coord();
167
168 // Get centre of tower at eta+1, phi+1, i.e. opposite corner of RoI core
169 double dEta = keyLL.dEta(lowerLeft);
170 double dPhi = keyLL.dPhi(lowerLeft);
171
172 TriggerTowerKey keyUR(phi+dPhi, eta + dEta);
173 Coordinate upperRight = keyUR.coord();
174
175 // CoordinateRange object will compute centre, correcting for wrap-around
176 CoordinateRange roi(lowerLeft.phi(),upperRight.phi(),lowerLeft.eta(),upperRight.eta());
177 m_eta = roi.eta();
178 m_phi = roi.phi();
179
180 // Range check (shouldn't be needed, but floating point precision errors possible)
181 if (m_eta > 2.5) m_eta = 2.5;
182 else if (m_eta < -2.5) m_eta = -2.5;
183}
184
186void LVL1::CPMTobAlgorithm::testEtMax(const std::vector<unsigned int>& cores) {
187
195
196 // RoI condition test
197 m_EtMax = true;
198 for (int i = 0; i < 4; i++) if (m_Core < cores[i]) m_EtMax = false;
199 for (int i = 5; i < 9; i++) if (m_Core <= cores[i]) m_EtMax = false;
200
201}
202
203
206
207 // Initialise to correct defaults, to be sure
208 m_EMThresh = false;
209 m_EMIsolWord = 0;
210
211 // Don't waste time if it isn't an RoI candidate
212 if (!m_EtMax) return;
213
214 // Does this pass min TOB pT cut?
215 // Need to worry about digit scale not being GeV
216 float emEnergyScale{1};
217 unsigned int tobPtMinEM{0};
218 emEnergyScale = m_l1menu->thrExtraInfo().EM().emScale();
219 tobPtMinEM = m_l1menu->thrExtraInfo().EM().ptMinToTopo();
220
221 unsigned int thresh = tobPtMinEM * emEnergyScale;
222
223 if (m_EMClus <= thresh) return;
224
225 // Passed, so there is a TOB here
226 m_EMThresh = true;
227
228 // Now calculate isolation word
229 // Define cluster and isolation values with appropriate scales and range for isolation LUT
230 unsigned int clusMask = ( (1<<m_emLUT_ClusterNBits)-1 )<<m_emLUT_ClusterFirstBit;
231 unsigned int emIsolMask = ( (1<<m_emLUT_EMIsolNBits) -1 )<<m_emLUT_EMIsolFirstBit;
232 unsigned int hadIsolMask = ( (1<<m_emLUT_HadVetoNBits)-1 )<<m_emLUT_HadVetoFirstBit;
233
234 // If cluster overflows, set all threshold bits
235 if (m_EMClus >= clusMask) {
236 m_EMIsolWord = 0x1F;
237 return;
238 }
239
240 // For consistency with LUT filling and menu parameters, convert ET sums to 100 MeV units
241 int clus = (( (m_EMClus < clusMask) ? (m_EMClus & clusMask) : clusMask ) * 10)/emEnergyScale;
242 int emIsol = (( (m_EMIsol < emIsolMask) ? (m_EMIsol & emIsolMask) : emIsolMask ) * 10)/emEnergyScale;
243 int hadVeto = (( (m_HadCore < hadIsolMask) ? (m_HadCore & hadIsolMask) : hadIsolMask ) * 10)/emEnergyScale;
244
249 std::vector<int> emisolcuts(5,m_noIsol);
250 std::vector<int> hadisolcuts(5,m_noIsol);
251 for(size_t bit = 1; bit<=5; ++bit) {
252 const TrigConf::IsolationLegacy & iso = m_l1menu->thrExtraInfo().EM().isolation("EMIsoForEMthr", bit);
253 if(! iso.isDefined() ) {
254 continue;
255 }
256 int offset = iso.offset();
257 int slope = iso.slope();
258 int mincut = iso.mincut();
259 int upperlimit = iso.upperlimit()*10;
260 if (clus < upperlimit && bit >= 1 && bit <= 5) {
261 // As "slope" = 10* slope, rescale clus too to get fraction right.
262 int cut = offset + (slope != 0 ? 10*clus/slope : 0);
263 if (cut < mincut) cut = mincut;
264 emisolcuts[bit-1] = cut;
265 }
266 }
267 for(size_t bit = 1; bit<=5; ++bit) {
268 const TrigConf::IsolationLegacy & iso = m_l1menu->thrExtraInfo().EM().isolation("HAIsoForEMthr", bit);
269 if(! iso.isDefined() ) {
270 continue;
271 }
272 int offset = iso.offset();
273 int slope = iso.slope();
274 int mincut = iso.mincut();
275 int upperlimit = iso.upperlimit()*10;
276 if (clus < upperlimit && bit >= 1 && bit <= 5) {
277 // As "slope" = 10* slope, rescale clus too to get fraction right.
278 int cut = offset + (slope != 0 ? 10*clus/slope : 0);
279 if (cut < mincut) cut = mincut;
280 hadisolcuts[bit-1] = cut;
281 }
282 }
283
284 // Set isolation bits
285 for (unsigned int isol = 0; isol < 5; ++isol) {
286 if (emIsol <= emisolcuts[isol] && hadVeto <= hadisolcuts[isol]) m_EMIsolWord += (1 << isol);
287 }
288
289}
290
291
294
295 // Initialise to correct defaults, to be sure
296 m_TauThresh = false;
297 m_TauIsolWord = 0;
298
299 // Don't waste time if it isn't an RoI candidate
300 if (!m_EtMax) return;
301
302 // Does this pass min TOB pT cut?
303 // Need to worry about digit scale not being GeV
304 float emEnergyScale{1};
305 unsigned int tobPtMinTau{0};
306 emEnergyScale = m_l1menu->thrExtraInfo().EM().emScale();
307 tobPtMinTau = m_l1menu->thrExtraInfo().TAU().ptMinToTopo();
308 unsigned int thresh = tobPtMinTau * emEnergyScale;
309
310 if (m_TauClus <= thresh) return;
311
312 // Passed, so there is a TOB here
313 m_TauThresh = true;
314
315 // Now calculate isolation word
316 // Define cluster and isolation values with appropriate scales and range for isolation LUT
317 unsigned int clusMask = ( (1<<m_tauLUT_ClusterNBits)-1 )<<m_tauLUT_ClusterFirstBit;
318 unsigned int emIsolMask = ( (1<<m_tauLUT_EMIsolNBits) -1 )<<m_tauLUT_EMIsolFirstBit;
319
320 // If cluster overflows, set all threshold bits
321 if (m_TauClus >= clusMask) {
322 m_TauIsolWord = 0x1F;
323 return;
324 }
325
326 // Convert to 100 MeV units to match parameters
327 int clus = (( (m_TauClus < clusMask) ? (m_TauClus & clusMask) : clusMask ) * 10)/emEnergyScale;
328 int emIsol = (( (m_EMIsol < emIsolMask) ? (m_EMIsol & emIsolMask) : emIsolMask ) * 10)/emEnergyScale;
329
330 // Get isolation values from menu (placeholder code - example logic)
331 std::vector<int> emisolcuts(5,m_noIsol);
332 for(size_t bit = 1; bit<=5; ++bit) {
333 const TrigConf::IsolationLegacy & iso = m_l1menu->thrExtraInfo().TAU().isolation("EMIsoForTAUthr", bit);
334 if(! iso.isDefined() ) {
335 continue;
336 }
337 int offset = iso.offset();
338 int slope = iso.slope();
339 int mincut = iso.mincut();
340 int upperlimit = iso.upperlimit()*10;
341 if (clus < upperlimit && bit >= 1 && bit <= 5) {
342 // As "slope" = 10* slope, rescale clus too to get fraction right.
343 int cut = offset + (slope != 0 ? 10*clus/slope : 0);
344 if (cut < mincut) cut = mincut;
345 emisolcuts[bit-1] = cut;
346 }
347 }
348
349 // Set isolation bits
350 for (unsigned int isol = 0; isol < 5; ++isol)
351 if (emIsol <= emisolcuts[isol]) m_TauIsolWord += (1 << isol);
352
353}
354
357
358 bool passed = ( m_EMThresh && m_EtMax );
359
360 return passed;
361}
362
365
366 bool passed = ( m_TauThresh && m_EtMax );
367
368 return passed;
369}
370
371// Public accessor methods follow
372
375 return m_Core;
376}
377
382
387
392
397
402
407
412
417
420 return m_EtMax;
421}
422
425 int ET = (m_EMClus >> m_emLUT_ClusterFirstBit);
426 if (ET > (1<< m_emLUT_ClusterNBits) - 1) ET = (1<<m_emLUT_ClusterNBits) - 1;
427 return (ET << m_emLUT_ClusterFirstBit);
428}
429
433 if (ET > (1<<m_tauLUT_ClusterNBits) - 1) ET = (1<<m_tauLUT_ClusterNBits) - 1;
434 return (ET << m_tauLUT_ClusterFirstBit);
435}
436
439 int ET = (m_EMIsol >> m_emLUT_EMIsolFirstBit);
440 if (ET > (1<<m_emLUT_EMIsolNBits) - 1) ET = (1<<m_emLUT_EMIsolNBits) - 1;
441 return (ET << m_emLUT_EMIsolFirstBit);
442}
443
447 if (ET > (1<<m_emLUT_HadVetoNBits) - 1) ET = (1<<m_emLUT_HadVetoNBits) - 1;
448 return (ET << m_emLUT_HadVetoFirstBit);
449}
450
453 int ET = (m_EMIsol >> m_tauLUT_EMIsolFirstBit);
454 if (ET > (1<<m_tauLUT_EMIsolNBits) - 1) ET = (1<<m_tauLUT_EMIsolNBits) - 1;
455 return (ET << m_tauLUT_EMIsolFirstBit);
456}
457
460 return m_eta;
461}
462
465 return ( (m_phi <= M_PI) ? m_phi : m_phi - 2.*M_PI);
466}
467
470 if (isEMRoI()) {
472 return pointer;
473 }
474
475 return 0;
476
477}
478
481
482 xAOD::CPMTobRoI* pointer = 0;
483
485
486 return pointer;
487
488}
489
495
496 xAOD::CPMTobRoI* pointer = 0;
497
498 int et = 0;
499 int isol = 0;
500
502 et = EMClusET();
503 isol = EMIsolWord();
504 }
505 else if (type == TrigT1CaloDefs::tauTobType) {
506 et = TauClusET();
507 isol = TauIsolWord();
508 }
509 else return pointer;
510
511 // Need to calculate hardware coordinate
512 // Object coordinate is RoI centre, but this works better if use reference tower coord
513 float eta = m_eta - 0.05;
514 float phi = m_phi - M_PI/64;
515 if (phi < 0) phi += 2*M_PI;
517 CoordToHardware convertor;
518
519 int crate = convertor.cpCrate(coord);
520 int module = convertor.cpModule(coord);
521 int chip = convertor.cpModuleFPGA(coord);
522 int location = convertor.cpModuleLocalRoI(coord);
523
524 /*
525 float phi = ( (m_phi >= 0) ? m_phi : 2.*M_PI + m_phi );
526 int crate = 2*phi/M_PI;
527 int module = (m_eta + 2.8)/0.4 + 1;
528 int iPhi = (phi - crate*M_PI/2)*32/M_PI;
529 int chip = iPhi/2;
530 int iEta = (m_eta + 2.8 - module*0.4)/0.1;
531 int iSide = iEta/2;
532 int location = (iSide << 2) + ((iPhi&1) << 1) + (iEta&1);
533 */
534
535 pointer = new xAOD::CPMTobRoI;
536 pointer->makePrivateStore();
537 pointer->initialize(crate, module, chip, location, type, et, isol);
538
539 return pointer;
540
541}
542
543
544} // end of namespace bracket
545
546
#define M_PI
double coord
Type of coordination system.
bool passed(DecisionID id, const DecisionIDContainer &)
checks if required decision ID is in the set of IDs in the container
static const double m_maxEta
int CoreET()
Additional information for reconstruction & performance studies.
void tauAlgorithm()
Check trigger condition and set hits if appropriate.
void setRoICoord(double eta, double phi)
threshold values
int EMLUTClus()
Sums with the range & precision of isolation LUT inputs.
int HadIsolET()
Returns Had isolation ET.
static const unsigned int m_emLUT_ClusterNBits
double m_eta
Algorithm results.
int EMIsolWord()
Returns EM isolation word (5 bits)
static const unsigned int m_maxClus
Algorithm parameters.
static const unsigned int m_emLUT_HadVetoFirstBit
static const unsigned int m_emLUT_HadVetoNBits
int TauIsolWord()
Returns Tau isolation word (5 bits)
int EMClusET()
Returns EM cluster ET, limited to 8 bits.
bool isTauRoI()
Report whether this passed as a Tau TOB.
int TauLUTClus()
Returns Tau cluster ET with range and precision of LUT input.
void testEtMax(const std::vector< unsigned int > &cores)
Form all 2x2 clusters within window and test centre is a local ET maximum.
static const unsigned int m_emLUT_ClusterFirstBit
xAOD::CPMTobRoI * EMCPMTobRoI()
Create CPMTobRoIs and return pointers to them.
int EMLUTEMIsol()
Returns EM isolation ET with range and precision of EM LUT input.
CPMTobAlgorithm(double eta, double phi, const xAOD::CPMTowerMap_t *ttContainer, const TrigConf::L1Menu *l1menu, int slice=-1)
double eta()
Accessors for TOB data.
static const unsigned int m_tauLUT_EMIsolNBits
static const unsigned int m_emLUT_EMIsolFirstBit
const TrigConf::L1Menu * m_l1menu
static const unsigned int m_tauLUT_ClusterFirstBit
int TauClusET()
Returns Tau cluster ET, limited to 8 bits.
xAOD::CPMTobRoI * createTobRoI(int type)
Create a pointer to a CPMTobRoI and return it.
xAOD::CPMTobRoI * TauCPMTobRoI()
Returns CPMTobRoI for TAU hypothesis, provided TAU Tob conditions passed.
int HadCoreET()
Returns Had core ET (inner isolation sum)
static const unsigned int m_tauLUT_EMIsolFirstBit
int TauLUTEMIsol()
Returns EM isolation ET with range and precision of Tau LUT input.
static const unsigned int m_tauLUT_ClusterNBits
static const unsigned int m_emLUT_EMIsolNBits
int EMCoreET()
Returns EM core ET.
static const unsigned int m_noIsol
void emAlgorithm()
Check trigger condition and set hits if appropriate.
bool isEtMax()
Does this window pass the local ET maximum condition.
double phi()
Returns phi coordinate of RoI, using standard ATLAS convention.
int EMLUTHadVeto()
Returns Had veto ET with range and precision of EM LUT input.
int EMIsolET()
Returns EM isolation ET.
bool isEMRoI()
Report whether this passed as an EM TOB.
returns the trigger hardware components associated with a given Coordinate
unsigned int cpModuleFPGA(const Coordinate &coord)
returns ID [0-7] of the CP FPGA.
unsigned int cpModule(const Coordinate &coord)
return ID of CP module.
unsigned int cpModuleLocalRoI(const Coordinate &coord)
returns local RoI coordinate within FPGA
unsigned int cpCrate(const Coordinate &coord)
returns crate ID covering that coord.
CoordinateRange class declaration.
double phi() const
return phi
double eta() const
return eta
Coordinate coord() const
return central coords of current key value.
The TriggerTowerKey object provides the key for each trigger tower depending on its eta-phi coords.
double dPhi(const Coordinate &coord) const
returns phi height of trigger tower at coordinate coord
double dEta(const Coordinate &coord) const
returns eta width of trigger tower at coordinate coord
void makePrivateStore()
Create a new (empty) private store for this object.
L1 menu configuration.
Definition L1Menu.h:28
virtual void initialize(int crate, int cpm, int chip, int location, int type, int energy, int isol)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
CPMTobRoI_v1 CPMTobRoI
Define the latest version of the CPMTobRoI class.
std::map< int, const CPMTower * > CPMTowerMap_t
Extra patterns decribing particle interation process.