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