ATLAS Offline Software
Loading...
Searching...
No Matches
eFEXFPGA.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5//***************************************************************************
6// eFEXFPGA - description
7// -------------------
8// begin : 15 10 2019
9// email : jacob.julian.kempster@cern.ch
10// ***************************************************************************/
11#include "eFEXFPGA.h"
16#include "eFEXtauAlgo.h"
18#include <vector>
20#include "TrigConfData/L1Menu.h"
21#include <unordered_map>
22
23#include <iostream>
24#include <fstream>
25
26namespace LVL1 {
27
28 // default constructor for persistency
29
30eFEXFPGA::eFEXFPGA(const std::string& type,const std::string& name,const IInterface* parent):
31 AthAlgTool(type,name,parent)
32{
33 declareInterface<eFEXFPGA>(this);
34}
35
36
41
42//---------------- Initialisation -------------------------------------------------
43
45{
46
47 ATH_CHECK(m_eTowerContainerKey.initialize());
48 ATH_CHECK( m_eFEXegAlgoTool.retrieve() );
49 ATH_CHECK( m_eFEXtauAlgoTool.retrieve() );
50 ATH_CHECK( m_eFEXtauBDTAlgoTool.retrieve() );
51
52
53 ATH_CHECK(m_l1MenuKey.initialize());
54
55 return StatusCode::SUCCESS;
56}
57
58
59StatusCode eFEXFPGA::init(int id, int efexid)
60{
61 m_id = id;
62 m_efexid = efexid;
63
64 return StatusCode::SUCCESS;
65}
66
68
69 m_id = -1;
70 m_efexid = -1;
71}
72
73StatusCode eFEXFPGA::execute(eFEXOutputCollection* inputOutputCollection){
74 m_emTobObjects.clear();
76 m_tauBDTTobObjects.clear();
77
79 if(!eTowerContainer.isValid()){
80 ATH_MSG_FATAL("Could not retrieve container " << m_eTowerContainerKey.key() );
81 return StatusCode::FAILURE;
82 }
83
84 // Retrieve the L1 menu configuration
86 ATH_CHECK(l1Menu.isValid());
87
88 auto & thr_eEM = l1Menu->thrExtraInfo().eEM();
89 auto & thr_eTAU = l1Menu->thrExtraInfo().eTAU();
90
91 auto emAlgoVersion = thr_eEM.algoVersion();
92 auto tauAlgoVersion = thr_eTAU.algoVersion();
93
94
95 // Define eta range to consider extra towers in edge cases
96 int min_eta;
97 int overflow_eta;
98 if ((m_efexid%3 == 0) && (m_id == 0)) {
99 min_eta = 0;
100 } else {
101 min_eta = 1;
102 }
103 if ((m_efexid%3 == 2) && (m_id == 3)) {
104 overflow_eta = 6;
105 } else {
106 overflow_eta = 5;
107 }
108
109 for(int ieta = min_eta; ieta < overflow_eta; ieta++) {
110 for(int iphi = 1; iphi < 9; iphi++) {
111
112 int tobtable[3][3]={
113 {ieta > 0 ? m_eTowersIDs[iphi-1][ieta-1] : 0,
114 m_eTowersIDs[iphi-1][ieta],
115 ieta < 5 ? m_eTowersIDs[iphi-1][ieta+1] : 0},
116
117 {ieta > 0 ? m_eTowersIDs[iphi][ieta-1] : 0,
118 m_eTowersIDs[iphi][ieta],
119 ieta < 5 ? m_eTowersIDs[iphi][ieta+1] : 0},
120
121 {ieta > 0 ? m_eTowersIDs[iphi+1][ieta-1] : 0,
122 m_eTowersIDs[iphi+1][ieta],
123 ieta < 5 ? m_eTowersIDs[iphi+1][ieta+1] : 0},
124 };
125
126
127 ATH_CHECK( m_eFEXegAlgoTool->safetyTest() );
128 m_eFEXegAlgoTool->setup(tobtable, m_efexid, m_id, ieta);
129
130 // ignore any tobs without a seed, move on to the next window
131 if (m_eFEXegAlgoTool->hasSeed() == false) continue;
132 unsigned int seed = m_eFEXegAlgoTool->getSeed();
133 unsigned int und = (m_eFEXegAlgoTool->getUnD() ? 1 : 0);
134
135 // the minimum energy to send to topo (not eta dependent yet, but keep inside loop as it will be eventually?)
136 unsigned int ptMinToTopoCounts = thr_eEM.ptMinToTopoCounts();
137
138 //returns a unsigned integer et value corresponding to the... eFEX EM cluster in 25 MeV internal calculation scale
139 unsigned int eEMTobEt = m_eFEXegAlgoTool->getET();
140
141 // thresholds from Trigger menu
142 // the menu eta runs from -25 to 24
143 int menuEta = m_id*4 + (m_efexid%3)*16 + ieta - 25;
144 auto iso_loose = thr_eEM.isolation(TrigConf::Selection::WP::LOOSE, menuEta);
145 auto iso_medium = thr_eEM.isolation(TrigConf::Selection::WP::MEDIUM, menuEta);
146 auto iso_tight = thr_eEM.isolation(TrigConf::Selection::WP::TIGHT, menuEta);
147
148 std::vector<unsigned int> threshReta;
149 threshReta.push_back(iso_loose.reta_fw());
150 threshReta.push_back(iso_medium.reta_fw());
151 threshReta.push_back(iso_tight.reta_fw());
152
153 std::vector<unsigned int> threshRhad;
154 threshRhad.push_back(iso_loose.rhad_fw());
155 threshRhad.push_back(iso_medium.rhad_fw());
156 threshRhad.push_back(iso_tight.rhad_fw());
157
158 std::vector<unsigned int> threshWstot;
159 threshWstot.push_back(iso_loose.wstot_fw());
160 threshWstot.push_back(iso_medium.wstot_fw());
161 threshWstot.push_back(iso_tight.wstot_fw());
162
163 ATH_MSG_DEBUG("ieta=" << ieta << " loose => reta_fw=" << threshReta[0] << ", rhad_fw=" << threshRhad[0] << ", wstot_fw=" << threshWstot[0]);
164 ATH_MSG_DEBUG("ieta=" << ieta << " medium => reta_fw=" << threshReta[1] << ", rhad_fw=" << threshRhad[1] << ", wstot_fw=" << threshWstot[1]);
165 ATH_MSG_DEBUG("ieta=" << ieta << " tight => reta_fw=" << threshReta[2] << ", rhad_fw=" << threshRhad[2] << ", wstot_fw=" << threshWstot[2]);
166
167 // Get Reta and Rhad outputs
168 std::vector<unsigned int> RetaCoreEnv;
169 m_eFEXegAlgoTool->getReta(RetaCoreEnv);
170 std::vector<unsigned int> RhadEMHad;
171 m_eFEXegAlgoTool->getRhad(RhadEMHad);
172 std::vector<unsigned int> WstotDenNum;
173 m_eFEXegAlgoTool->getWstot(WstotDenNum);
174
175 // Set Reta, Rhad and Wstot WP
176 unsigned int RetaWP = 0;
177 unsigned int RhadWP = 0;
178 unsigned int WstotWP = 0;
179
180 // bitshifts for the different iso vars
181 unsigned int RetaBitS = 3;
182 unsigned int RhadBitS = 3;
183 unsigned int WstotBitS = 5;
184
185 unsigned int maxEtCountsEm = thr_eEM.maxEtCounts(m_eFexStep);
186 if (eEMTobEt >= maxEtCountsEm){
187 RetaWP = 3;
188 RhadWP = 3;
189 WstotWP = 3;
190 }
191 else{
192 SetIsoWP(RetaCoreEnv,threshReta,RetaWP,RetaBitS);
193 SetIsoWP(RhadEMHad,threshRhad,RhadWP,RhadBitS);
194 SetIsoWP(WstotDenNum,threshWstot,WstotWP,WstotBitS);
195 }
196 int eta_ind = ieta; // No need to offset eta index with new 0-5 convention
197 int phi_ind = iphi - 1;
198
199 //form the egamma tob word and xTOB words
200 uint32_t tobword = m_eFEXFormTOBsTool->formEmTOBWord(m_id,eta_ind,phi_ind,RhadWP,WstotWP,RetaWP,seed,und,eEMTobEt,ptMinToTopoCounts, emAlgoVersion);
201 std::vector<uint32_t> xtobwords = m_eFEXFormTOBsTool->formEmxTOBWords(m_efexid,m_id,eta_ind,phi_ind,RhadWP,WstotWP,RetaWP,seed,und,eEMTobEt,ptMinToTopoCounts, emAlgoVersion);
202
203 std::unique_ptr<eFEXegTOB> tmp_tob = m_eFEXegAlgoTool->geteFEXegTOB();
204
205 tmp_tob->setFPGAID(m_id);
206 tmp_tob->seteFEXID(m_efexid);
207 tmp_tob->setEta(ieta);
208 tmp_tob->setPhi(iphi);
209 tmp_tob->setTobword(tobword);
210 tmp_tob->setxTobword0(xtobwords[0]);
211 tmp_tob->setxTobword1(xtobwords[1]);
212
213 // for plotting
214 if (inputOutputCollection->getdooutput() && (tobword != 0) && (eEMTobEt != 0)) {
215 inputOutputCollection->addeFexNumber(m_efexid);
216 inputOutputCollection->addEMtob(tobword);
217 inputOutputCollection->addValue_eg("WstotNum", tmp_tob->getWstotNum());
218 inputOutputCollection->addValue_eg("WstotDen", tmp_tob->getWstotDen());
219 inputOutputCollection->addValue_eg("RetaNum", tmp_tob->getRetaCore());
220 inputOutputCollection->addValue_eg("RetaDen", tmp_tob->getRetaEnv());
221 inputOutputCollection->addValue_eg("RhadNum", tmp_tob->getRhadEM());
222 inputOutputCollection->addValue_eg("RhadDen", tmp_tob->getRhadHad());
223 inputOutputCollection->addValue_eg("haveSeed", m_eFEXegAlgoTool->hasSeed());
224 inputOutputCollection->addValue_eg("ET", m_eFEXegAlgoTool->getET());
225 float eta = 9999;
226 m_eFEXegAlgoTool->getRealEta(eta);
227 inputOutputCollection->addValue_eg("eta", eta);
228 float phi = 9999;
229 m_eFEXegAlgoTool->getRealPhi(phi);
230 inputOutputCollection->addValue_eg("phi", phi);
231 unsigned int em_et = 9999;
232 m_eFEXegAlgoTool->getCoreEMTowerET(em_et);
233 inputOutputCollection->addValue_eg("em", em_et);
234 unsigned int had_et = 9999;
235 m_eFEXegAlgoTool->getCoreHADTowerET(had_et);
236 inputOutputCollection->addValue_eg("had", had_et);
237 inputOutputCollection->fill_eg();
238 }
239
240 // Now we've finished with that object we can move it into the class results store
241 if ( (tobword != 0) && (eEMTobEt != 0) ) m_emTobObjects.push_back(std::move(tmp_tob));
242
243 }
244 }
245
246 // --------------- TAU -------------
247 for(int ieta = min_eta; ieta < overflow_eta; ieta++)
248 {
249 for(int iphi = 1; iphi < 9; iphi++)
250 {
251 int tobtable[3][3]={
252 {ieta > 0 ? m_eTowersIDs[iphi-1][ieta-1] : 0,
253 m_eTowersIDs[iphi-1][ieta],
254 ieta < 5 ? m_eTowersIDs[iphi-1][ieta+1] : 0},
255
256 {ieta > 0 ? m_eTowersIDs[iphi][ieta-1] : 0,
257 m_eTowersIDs[iphi][ieta],
258 ieta < 5 ? m_eTowersIDs[iphi][ieta+1] : 0},
259
260 {ieta > 0 ? m_eTowersIDs[iphi+1][ieta-1] : 0,
261 m_eTowersIDs[iphi+1][ieta],
262 ieta < 5 ? m_eTowersIDs[iphi+1][ieta+1] : 0},
263 };
264
265 ATH_CHECK( m_eFEXtauAlgoTool->safetyTest() );
266 ATH_CHECK( m_eFEXtauBDTAlgoTool->safetyTest() );
267 m_eFEXtauAlgoTool->setup(tobtable, m_efexid, m_id, ieta);
268 m_eFEXtauAlgoTool->setAlgoVersion(tauAlgoVersion);
269 m_eFEXtauBDTAlgoTool->setup(tobtable, m_efexid, m_id, ieta);
270
271 if ( m_eFEXtauAlgoTool->isCentralTowerSeed() != m_eFEXtauBDTAlgoTool->isCentralTowerSeed() )
272 {
273 ATH_MSG_FATAL("BDT tau algo and heuristic tau algo should agree on seeding for all TOBs");
274 return StatusCode::FAILURE;
275 }
276
277 if (!m_eFEXtauAlgoTool->isCentralTowerSeed()){ continue; }
278
279 // the minimum energy to send to topo (not eta dependent yet, but keep inside loop as it will be eventually?)
280 unsigned int ptTauMinToTopoCounts = thr_eTAU.ptMinToTopoCounts();
281
282 unsigned int ptTauMinToTopoInEfexCounts = TrigConf::energyInCounts(thr_eTAU.ptMinToTopoMeV(), m_eFexStep);
283
284 // Get Et of eFEX tau object in internal units (25 MeV)
285 unsigned int eTauTobEt = m_eFEXtauAlgoTool->getEt();
286 unsigned int eTauBDTTobEt = m_eFEXtauBDTAlgoTool->getEt();
287
288 // thresholds from Trigger menu
289 // the menu eta runs from -25 to 24
290 int menuEta = m_id*4 + (m_efexid%3)*16 + ieta - 25;
291 auto iso_loose = thr_eTAU.isolation(TrigConf::Selection::WP::LOOSE, menuEta);
292 auto iso_medium = thr_eTAU.isolation(TrigConf::Selection::WP::MEDIUM, menuEta);
293 auto iso_tight = thr_eTAU.isolation(TrigConf::Selection::WP::TIGHT, menuEta);
294
295 std::vector<unsigned int> threshRCore;
296 threshRCore.push_back(iso_loose.rCore_fw());
297 threshRCore.push_back(iso_medium.rCore_fw());
298 threshRCore.push_back(iso_tight.rCore_fw());
299
300 std::vector<unsigned int> threshRHad;
301 threshRHad.push_back(iso_loose.rHad_fw());
302 threshRHad.push_back(iso_medium.rHad_fw());
303 threshRHad.push_back(iso_tight.rHad_fw());
304
305 // Get isolation values
306 std::vector<unsigned int> rCoreVec;
307 m_eFEXtauAlgoTool->getRCore(rCoreVec);
308
309 std::vector<unsigned int> rHadVec;
310 m_eFEXtauAlgoTool->getRHad(rHadVec);
311
312 // BDT-based tau algorithm outputs (both 0 for heuristic algorithm)
313 unsigned int bdtScore = 0;
314 unsigned int bdtCondition = 0;
315 unsigned int bdtRHadWP = 0;
316
317 // Set isolation WP
318 unsigned int rCoreWP = 0;
319 unsigned int rHadWP = 0;
320
321 // Isolation bitshift value
322 unsigned int RcoreBitS = 3;
323 unsigned int RhadBitS = 3;
324
325 unsigned int maxEtCountsTau = thr_eTAU.maxEtCounts(m_eFexStep);
326 unsigned int bdtMinEtCounts = thr_eTAU.minIsoEtCounts(m_eFexStep);
327 if (eTauTobEt >= maxEtCountsTau) {
328 rCoreWP = 3;
329 rHadWP = 3;
330 } else {
331 SetIsoWP(rCoreVec,threshRCore,rCoreWP,RcoreBitS);
332 SetIsoWP(rHadVec,threshRHad,rHadWP,RhadBitS);
333 }
334
335 // Only one tau algorithm may be active and this is controlled by the L1 menu.
336 // When the BDT algorithm is active, the rCore field contains the BDT L/M/T thresholds.
337 std::vector<unsigned int> threshBDT;
338 threshBDT.push_back(iso_loose.rCore_fw());
339 threshBDT.push_back(iso_medium.rCore_fw());
340 threshBDT.push_back(iso_tight.rCore_fw());
341 // in tau algoVersion 2, the autopass threshold for rhad frac (last parameter) is hardcoded
342 m_eFEXtauBDTAlgoTool->setThresholds(threshRHad, threshBDT, ptTauMinToTopoInEfexCounts, maxEtCountsTau, bdtMinEtCounts, (tauAlgoVersion==2) ? 0x0ff0 : maxEtCountsTau);
343 // Re-compute after setting thresholds.
344 // Threshold bits in the BDT algorithm's implementation are computed inside the algorithm class
345 m_eFEXtauBDTAlgoTool->compute();
346 eTauBDTTobEt = m_eFEXtauBDTAlgoTool->getEt();
347 bdtScore = m_eFEXtauBDTAlgoTool->getBDTScore();
348 bdtCondition = m_eFEXtauBDTAlgoTool->getBDTCondition();
349 bdtRHadWP = m_eFEXtauBDTAlgoTool->getBDTHadFracCondition();
350
351 unsigned int seed = m_eFEXtauAlgoTool->getSeed();
352 // Heuristic seed as returned is supercell value within 3x3 area, here want it within central cell
353 seed = seed - 4;
354
355 unsigned int und = (m_eFEXtauAlgoTool->getUnD() ? 1 : 0);
356
357 unsigned int bdtSeed = m_eFEXtauBDTAlgoTool->getSeed();
358
359 int eta_ind = ieta; // No need to offset eta index with new 0-5 convention
360 int phi_ind = iphi - 1;
361
362 // Form the tau TOB word and xTOB words
363 std::vector<uint32_t> xtobwords;
364 std::vector<uint32_t> xtobwordsBDT;
365
366 ATH_MSG_DEBUG("m_id: " << m_id << ", eta_ind: " << eta_ind << ", phi_ind: "
367 << phi_ind << ", eTauBDTTobEt: " << eTauBDTTobEt
368 << ", eTauTobEt: " << eTauTobEt << ", ptTauMinToTopoCounts: "
369 << ptTauMinToTopoCounts << ", maxEtCountsTau: " << maxEtCountsTau
370 << ", bdtScore: " << bdtScore << " bdtMinEtCounts: " << bdtMinEtCounts << " bdtRHadWP " << bdtRHadWP);
371
372 uint32_t tobwordBDT = m_eFEXFormTOBsTool->formTauTOBWord(m_id, eta_ind, phi_ind, eTauBDTTobEt, bdtRHadWP, bdtCondition, bdtSeed,0, ptTauMinToTopoCounts, tauAlgoVersion);
373 xtobwordsBDT = m_eFEXFormTOBsTool->formTauxTOBWords(m_efexid, m_id, eta_ind, phi_ind, eTauBDTTobEt, bdtRHadWP, bdtCondition, bdtSeed, 0, ptTauMinToTopoCounts, tauAlgoVersion, bdtScore);
374 uint32_t tobword = m_eFEXFormTOBsTool->formTauTOBWord(m_id, eta_ind, phi_ind, eTauTobEt, rHadWP, rCoreWP, seed, und, ptTauMinToTopoCounts, 0);
375 xtobwords = m_eFEXFormTOBsTool->formTauxTOBWords(m_efexid, m_id, eta_ind, phi_ind, eTauTobEt, rHadWP, rCoreWP, seed, und, ptTauMinToTopoCounts, 0, 0);
376
377 std::unique_ptr<eFEXtauTOB> tmp_tau_tob = m_eFEXtauAlgoTool->getTauTOB();
378 tmp_tau_tob->setFPGAID(m_id);
379 tmp_tau_tob->seteFEXID(m_efexid);
380 tmp_tau_tob->setEta(ieta);
381 tmp_tau_tob->setPhi(iphi);
382 tmp_tau_tob->setTobword(tobword);
383 tmp_tau_tob->setxTobword0(xtobwords[0]);
384 tmp_tau_tob->setxTobword1(xtobwords[1]);
385
386 std::unique_ptr<eFEXtauTOB> tmp_tau_tob_bdt = m_eFEXtauBDTAlgoTool->getTauTOB();
387 tmp_tau_tob_bdt->setFPGAID(m_id);
388 tmp_tau_tob_bdt->seteFEXID(m_efexid);
389 tmp_tau_tob_bdt->setEta(ieta);
390 tmp_tau_tob_bdt->setPhi(iphi);
391 tmp_tau_tob_bdt->setTobword(tobwordBDT);
392 tmp_tau_tob_bdt->setxTobword0(xtobwordsBDT[0]);
393 tmp_tau_tob_bdt->setxTobword1(xtobwordsBDT[1]);
394
395 // for plotting
396 if ((inputOutputCollection->getdooutput()) && ( tobword != 0 )) {
397 inputOutputCollection->addValue_tau("isCentralTowerSeed", m_eFEXtauAlgoTool->isCentralTowerSeed());
398 inputOutputCollection->addValue_tau("Et", m_eFEXtauAlgoTool->getEt());
399 inputOutputCollection->addValue_tau("EtBDT", m_eFEXtauBDTAlgoTool->getEt());
400 inputOutputCollection->addValue_tau("Eta", ieta);
401 inputOutputCollection->addValue_tau("Phi", iphi);
402 const LVL1::eTower * centerTower = eTowerContainer->findTower(m_eTowersIDs[iphi][ieta]);
403 const LVL1::eTower * oneOffEtaTower = ieta < 5 ? eTowerContainer->findTower(m_eTowersIDs[iphi][ieta+1]) : nullptr;
404 const LVL1::eTower * oneBelowEtaTower = ieta > 0 ? eTowerContainer->findTower(m_eTowersIDs[iphi][ieta-1]) : nullptr;
405 inputOutputCollection->addValue_tau("CenterTowerEt", centerTower->getTotalET());
406 inputOutputCollection->addValue_tau("OneOffEtaTowerEt", oneOffEtaTower ? oneOffEtaTower->getTotalET() : 0);
407 inputOutputCollection->addValue_tau("OneBelowEtaTowerEt", oneBelowEtaTower ? oneBelowEtaTower->getTotalET() : 0);
408 inputOutputCollection->addValue_tau("FloatEta", centerTower->eta() * centerTower->getPosNeg());
409 inputOutputCollection->addValue_tau("FloatPhi", centerTower->phi());
410 inputOutputCollection->addValue_tau("RCoreCore", rCoreVec[0]);
411 inputOutputCollection->addValue_tau("RCoreEnv", rCoreVec[1]);
412 inputOutputCollection->addValue_tau("RealRCore", m_eFEXtauAlgoTool->getRealRCore());
413 inputOutputCollection->addValue_tau("RCoreWP", rCoreWP);
414 inputOutputCollection->addValue_tau("RHadCore", rHadVec[0]);
415 inputOutputCollection->addValue_tau("RHadEnv", rHadVec[1]);
416 inputOutputCollection->addValue_tau("RealRHad", m_eFEXtauAlgoTool->getRealRHad());
417 inputOutputCollection->addValue_tau("RealRHadBDT", m_eFEXtauBDTAlgoTool->getRealRHad());
418 inputOutputCollection->addValue_tau("RHadWP", rHadWP);
419 inputOutputCollection->addValue_tau("Seed", seed);
420 inputOutputCollection->addValue_tau("UnD", und);
421 inputOutputCollection->addValue_tau("BDTScore", bdtScore);
422 inputOutputCollection->addValue_tau("BDTCondition", bdtCondition);
423 inputOutputCollection->addValue_tau("eFEXID", m_efexid);
424 inputOutputCollection->addValue_tau("FPGAID", m_id);
425
426
427 inputOutputCollection->fill_tau();
428 }
429 // Now we've finished with that object we can move it into the class results store
430 if ( tobword != 0 ) m_tauHeuristicTobObjects.push_back(std::move(tmp_tau_tob));
431 if ( tobwordBDT != 0 ) m_tauBDTTobObjects.push_back(std::move(tmp_tau_tob_bdt));
432
433 }
434 }
435
436 return StatusCode::SUCCESS;
437}
438
439
440
441std::vector<std::unique_ptr<eFEXegTOB>> eFEXFPGA::getEmTOBs()
442{
443 // TOB sorting moved to eFEXSysSim to simplify xTOB production
444 // But leave this here in case more subtle requirement is uncovered in future
445 /*
446 auto tobsSort = m_emTobObjects;
447
448 ATH_MSG_DEBUG("number of tobs: " <<tobsSort.size() << " in FPGA: " << m_id << " before truncation");
449
450 // sort tobs by their et (last 12 bits of the 32 bit tob word)
451 std::sort (tobsSort.begin(), tobsSort.end(), TOBetSort<eFEXegTOB>);
452
453 // return the top 6 highest ET TOBs from the FPGA
454 if (tobsSort.size() > 6) tobsSort.resize(6);
455 return tobsSort;
456 */
457
458 /* Returning a vector of unique_pointers means this class will lose ownership.
459 This shouldn't be an issue since all this class does is create and return the
460 objects, but you should bear it in mind if you make changes */
461
462 // This copy seems to be needed - it won't let me pass m_emTobOjects directly (to do with being a class member?)
463 std::vector<std::unique_ptr<eFEXegTOB>> tobsSort;
464 for(auto &j : m_emTobObjects){
465 tobsSort.push_back(std::move(j));
466 }
467
468 return tobsSort;
469}
470
471std::vector<std::unique_ptr<eFEXtauTOB>> eFEXFPGA::getTauTOBs(std::vector< std::unique_ptr<eFEXtauTOB> >& tauTobObjects)
472{
473 // TOB sorting moved to eFEXSysSim to simplify xTOB production
474 // But leave this here in case more subtle requirement is uncovered in future
475 /*
476 auto tobsSort = tauTobObjects;
477
478 ATH_MSG_DEBUG("number of tobs: " <<tobsSort.size() << " in FPGA: " << m_id << " before truncation");
479
480 // sort tobs by their et (last 12 bits of the 32 bit tob word)
481 std::sort (tobsSort.begin(), tobsSort.end(), TOBetSort<eFEXtauTOB>);
482
483 // return the top 6 highest ET TOBs from the FPGA
484 if (tobsSort.size() > 6) tobsSort.resize(6);
485 return tobsSort;
486 */
487
488 /* Returning a vector of unique_pointers means this class will lose ownership.
489 This shouldn't be an issue since all this class does is create and return the
490 objects, but you should bear it in mind if you make changes */
491
492 // This copy seems to be needed - it won't let me pass m_tauTobOjects directly (to do with being a class member?)
493 std::vector<std::unique_ptr<eFEXtauTOB>> tobsSort;
494 for(auto &j : tauTobObjects){
495 tobsSort.push_back(std::move(j));
496 }
497
498 return tobsSort;
499}
500
501std::vector<std::unique_ptr<eFEXtauTOB>> eFEXFPGA::getTauHeuristicTOBs()
502{
504}
505
506std::vector<std::unique_ptr<eFEXtauTOB>> eFEXFPGA::getTauBDTTOBs()
507{
509}
510
511void eFEXFPGA::SetTowersAndCells_SG(int tmp_eTowersIDs_subset[][6]){
512
513 int rows = 10;
514 int cols = sizeof tmp_eTowersIDs_subset[0] / sizeof tmp_eTowersIDs_subset[0][0];
515
516 std::copy(&tmp_eTowersIDs_subset[0][0], &tmp_eTowersIDs_subset[0][0]+(10*6),&m_eTowersIDs[0][0]);
517
518 if(false){ //this prints out the eTower IDs that each FPGA is responsible for
519 ATH_MSG_DEBUG("\n---- eFEXFPGA --------- eFEX (" << m_efexid << " ----- FPGA (" << m_id << ") IS RESPONSIBLE FOR eTOWERS :");
520 for (int thisRow=rows-1; thisRow>=0; thisRow--){
521 for (int thisCol=0; thisCol<cols; thisCol++){
522 if(thisCol != cols-1){ ATH_MSG_DEBUG("| " << m_eTowersIDs[thisRow][thisCol] << " "); }
523 else { ATH_MSG_DEBUG("| " << m_eTowersIDs[thisRow][thisCol] << " |"); }
524 }
525 }
526 }
527
528
529 //-----------------------------------------------------------
530 // Set up a the second CSV file if necessary (should only need to be done if the mapping changes, which should never happen unless major changes to the simulation are required)
531 if(false){ // CSV CODE TO BE RE-INTRODUCED VERY SOON
533 if(!eTowerContainer.isValid()){
534 ATH_MSG_FATAL("Could not retrieve container " << m_eTowerContainerKey.key() );
535 }
536
537 std::ofstream tower_fpga_efex_map;
538 tower_fpga_efex_map.open ("./tower_fpga_efex_map.csv", std::ios_base::app);
539
540 for (int thisRow=rows-1; thisRow>=0; thisRow--){
541 for (int thisCol=0; thisCol<cols; thisCol++){
542
543 const LVL1::eTower * tmpTower = eTowerContainer->findTower(m_eTowersIDs[thisRow][thisCol]);
544
545 tower_fpga_efex_map << m_efexid << "," << m_id << "," << m_eTowersIDs[thisRow][thisCol] << "," << tmpTower->eta() << "," << tmpTower->phi() << "\n";
546
547 }
548 }
549 }
550 //------------------------------------------------------------
551
552
553}
554
555
556void eFEXFPGA::SetIsoWP(const std::vector<unsigned int>& CoreEnv, const std::vector<unsigned int>& thresholds, unsigned int & workingPoint, unsigned int bitshift) const {
557 // Working point evaluted by Core * 2^bitshift > Threshold * Environment conditions
558 std::unordered_map<unsigned int, unsigned int> bsmap { {3, 8}, {5, 32}};
559
560 // if core (denom) has overflowed, automatically pass all thresholds
561 if (CoreEnv[0] > 0xffff) {
562 workingPoint = 3;
563 return;
564 }
565
566 unsigned int large = CoreEnv[0]*bsmap[bitshift]; // core
567 unsigned int small = CoreEnv[1]; // env
568
569 // Word length conditions
570 if (large > 0xffff ) large = 0xffff;
571 if (small > 0xffff ) small = 0xffff;
572
573 // Fail all if env sum overflows
574 if (small == 0xffff) {
575 workingPoint = 0;
576 return;
577 }
578
579 // Otherwise test thresholds in firmware order
580 // i.e. check lowest threshold failed rather than highest passed
581 if ( large < small*thresholds[0] ) {
582 workingPoint = 0;
583 return;
584 }
585 if ( large < small*thresholds[1] ) {
586 workingPoint = 1;
587 return;
588 }
589 if ( large < small*thresholds[2] ) {
590 workingPoint = 2;
591 return;
592 }
593 workingPoint = 3;
594 return;
595}
596
597} // end of namespace bracket
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const unsigned int m_eFexStep
Internal data.
Definition eFEXFPGA.h:67
virtual ~eFEXFPGA()
Destructor.
Definition eFEXFPGA.cxx:38
ToolHandle< eFEXFormTOBs > m_eFEXFormTOBsTool
Definition eFEXFPGA.h:96
virtual void SetTowersAndCells_SG(int[][6])
Definition eFEXFPGA.cxx:511
virtual StatusCode init(int id, int efexid)
Definition eFEXFPGA.cxx:59
std::vector< std::unique_ptr< eFEXegTOB > > m_emTobObjects
Definition eFEXFPGA.h:71
std::vector< std::unique_ptr< eFEXtauTOB > > m_tauHeuristicTobObjects
Definition eFEXFPGA.h:72
SG::ReadHandleKey< TrigConf::L1Menu > m_l1MenuKey
Definition eFEXFPGA.h:76
ToolHandle< eFEXtauAlgoBase > m_eFEXtauAlgoTool
Definition eFEXFPGA.h:84
virtual StatusCode execute(eFEXOutputCollection *inputOutputCollection)
Definition eFEXFPGA.cxx:73
std::vector< std::unique_ptr< eFEXtauTOB > > m_tauBDTTobObjects
Definition eFEXFPGA.h:73
virtual std::vector< std::unique_ptr< eFEXegTOB > > getEmTOBs()
Definition eFEXFPGA.cxx:441
virtual void SetIsoWP(const std::vector< unsigned int > &, const std::vector< unsigned int > &, unsigned int &, unsigned int) const
Definition eFEXFPGA.cxx:556
virtual StatusCode initialize()
standard Athena-Algorithm method
Definition eFEXFPGA.cxx:44
ToolHandle< eFEXegAlgo > m_eFEXegAlgoTool
Definition eFEXFPGA.h:92
int m_eTowersIDs[10][6]
Definition eFEXFPGA.h:74
std::vector< std::unique_ptr< eFEXtauTOB > > getTauTOBs(std::vector< std::unique_ptr< eFEXtauTOB > > &tauTobObjects)
Definition eFEXFPGA.cxx:471
SG::ReadHandleKey< LVL1::eTowerContainer > m_eTowerContainerKey
Definition eFEXFPGA.h:80
virtual std::vector< std::unique_ptr< eFEXtauTOB > > getTauBDTTOBs()
Definition eFEXFPGA.cxx:506
virtual void reset()
Definition eFEXFPGA.cxx:67
ToolHandle< eFEXtauAlgoBase > m_eFEXtauBDTAlgoTool
Definition eFEXFPGA.h:88
eFEXFPGA(const std::string &type, const std::string &name, const IInterface *parent)
Constructors.
Definition eFEXFPGA.cxx:30
virtual std::vector< std::unique_ptr< eFEXtauTOB > > getTauHeuristicTOBs()
Definition eFEXFPGA.cxx:501
bool getdooutput() const
return to true if ntuple output is needed
void fill_tau()
Save all tau values. Use only after finishing defining all tau values for one TOB.
void fill_eg()
Save all e-gamma values. Use only after finishing defining all e-gamma values for one TOB.
void addeFexNumber(int)
add the eEFX number of a TOB
void addValue_tau(const std::string &key, float value)
define a value related to the tau algorithm for a TOB
void addValue_eg(const std::string &key, float value)
add a value related to the e-gamma algorithm for a TOB
void addEMtob(uint32_t)
add a 32-bit e-gamma TOB word
const LVL1::eTower * findTower(int towerID) const
fast find method given identifier.
The eTower class is an interface object for eFEX trigger algorithms The purposes are twofold:
Definition eTower.h:38
float phi() const
Definition eTower.h:65
int getPosNeg() const
Definition eTower.h:121
int getTotalET() const
Get ET sum of all cells in the eTower in MeV.
Definition eTower.cxx:194
float eta() const
Definition eTower.h:64
virtual bool isValid() override final
Can the handle be successfully dereferenced?
create ntuples output
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
unsigned int energyInCounts(unsigned int energyMeV, unsigned int energyResolutionMeV)
helper funtion to translate energies into counts