eFEXFPGA.cxx 19.7 KB
Newer Older
1
/*
2
  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
*/

//***************************************************************************
//                           eFEXFPGA  -  description
//                              -------------------
//     begin                : 15 10 2019
//     email                : jacob.julian.kempster@cern.ch
//  ***************************************************************************/
#include "L1CaloFEXSim/eFEXFPGA.h"
#include "L1CaloFEXSim/eTowerContainer.h"
#include "L1CaloFEXSim/eFEXegAlgo.h"
#include "L1CaloFEXSim/eFEXegTOB.h"
#include "L1CaloFEXSim/eFEXOutputCollection.h"
#include "L1CaloFEXSim/eFEXtauAlgo.h"
#include "L1CaloFEXSim/eFEXtauTOB.h"
#include "CaloEvent/CaloCellContainer.h"
#include "CaloIdentifier/CaloIdManager.h"
#include "CaloIdentifier/CaloCell_SuperCell_ID.h"
#include "AthenaBaseComps/AthAlgorithm.h"
#include "StoreGate/StoreGateSvc.h"
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/ISvcLocator.h"
#include "GaudiKernel/ITHistSvc.h"
#include <vector>
#include "TH1F.h"
#include "StoreGate/WriteHandle.h"
#include "StoreGate/ReadHandle.h"
#include "SGTools/TestStore.h"
31
#include "TrigConfData/L1Menu.h"
32
#include <unordered_map>
33

34
35
36
#include <iostream>
#include <fstream>

37
38
39
40
41
42
43
44
45
namespace LVL1 {

  // default constructor for persistency

eFEXFPGA::eFEXFPGA(const std::string& type,const std::string& name,const IInterface* parent):
  AthAlgTool(type,name,parent)
{
  declareInterface<IeFEXFPGA>(this);
}
46
 
47
48
49
50
51
52
    
  /** Destructor */
  eFEXFPGA::~eFEXFPGA()
  {
  }

53
//---------------- Initialisation -------------------------------------------------
54
55
56
57
  
StatusCode eFEXFPGA::initialize()
{

58
  ATH_CHECK(m_eTowerContainerKey.initialize());
59
60
61
62
  ATH_CHECK( m_eFEXegAlgoTool.retrieve() );
  ATH_CHECK( m_eFEXtauAlgoTool.retrieve() );
  
  
63
  ATH_CHECK(m_l1MenuKey.initialize());
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  return StatusCode::SUCCESS;
}
  

StatusCode eFEXFPGA::init(int id, int efexid)
{
  m_id = id;
  m_efexid = efexid;

  return StatusCode::SUCCESS;

}

void eFEXFPGA::reset(){

  m_id = -1;
  m_efexid = -1;

}

85
StatusCode eFEXFPGA::execute(eFEXOutputCollection* inputOutputCollection){
86
  m_emTobObjects.clear();
87
  m_tauTobObjects.clear();
88

89
90
91
  SG::ReadHandle<eTowerContainer> eTowerContainer(m_eTowerContainerKey/*,ctx*/);
  if(!eTowerContainer.isValid()){
    ATH_MSG_FATAL("Could not retrieve container " << m_eTowerContainerKey.key() );
92
93
    return StatusCode::FAILURE;
  }
94
95
96
97
98
99

  // Retrieve the L1 menu configuration
  SG::ReadHandle<TrigConf::L1Menu> l1Menu (m_l1MenuKey/*, ctx*/);
  ATH_CHECK(l1Menu.isValid());

  auto & thr_eEM = l1Menu->thrExtraInfo().eEM();
Nicholas Luongo's avatar
Nicholas Luongo committed
100
  auto & thr_eTAU = l1Menu->thrExtraInfo().eTAU();
101

Nicholas Luongo's avatar
Nicholas Luongo committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  // Define eta range to consider extra towers in edge cases
  int min_eta;
  int overflow_eta;
  if ((m_efexid%3 == 0) && (m_id == 0)) {
    min_eta = 0;
  } else {
    min_eta = 1;
  }
  if ((m_efexid%3 == 2) && (m_id == 3)) {
    overflow_eta = 6;
  } else {
    overflow_eta = 5;
  }
  
Nicholas Luongo's avatar
Nicholas Luongo committed
116
  for(int ieta = min_eta; ieta < overflow_eta; ieta++) {
117
    for(int iphi = 1; iphi < 9; iphi++) {
Will Buttinger's avatar
Will Buttinger committed
118

119
      int tobtable[3][3]={
120
121
122
123
124
125
126
127
128
129
130
        {ieta > 0 ? m_eTowersIDs[iphi-1][ieta-1] : 0,
         m_eTowersIDs[iphi-1][ieta],
         ieta < 5 ? m_eTowersIDs[iphi-1][ieta+1] : 0},

        {ieta > 0 ? m_eTowersIDs[iphi][ieta-1] : 0,
         m_eTowersIDs[iphi][ieta],
         ieta < 5 ? m_eTowersIDs[iphi][ieta+1] : 0},

        {ieta > 0 ? m_eTowersIDs[iphi+1][ieta-1] : 0,
         m_eTowersIDs[iphi+1][ieta],
         ieta < 5 ? m_eTowersIDs[iphi+1][ieta+1] : 0},
131
132
      };

133

134
      ATH_CHECK( m_eFEXegAlgoTool->safetyTest() );
Nicholas Luongo's avatar
Nicholas Luongo committed
135
      m_eFEXegAlgoTool->setup(tobtable, m_efexid, m_id, ieta);
136

137
138
      // ignore any tobs without a seed, move on to the next window
      if (m_eFEXegAlgoTool->hasSeed() == false) continue;
139
140
      unsigned int seed = m_eFEXegAlgoTool->getSeed();
      unsigned int und = (m_eFEXegAlgoTool->getUnD() ? 1 : 0);
141
142
143
144
145

      // the minimum energy to send to topo (not eta dependent yet, but keep inside loop as it will be eventually?)
      unsigned int ptMinToTopoCounts = 0;
      ptMinToTopoCounts = thr_eEM.ptMinToTopoCounts(); 

146
      //returns a unsigned integer et value corresponding to the... eFEX EM cluster in 25 MeV internal calculation scale
147
148
      unsigned int eEMTobEt = 0;
      eEMTobEt = m_eFEXegAlgoTool->getET();
149
            
150
      // thresholds from Trigger menu
Will Buttinger's avatar
Will Buttinger committed
151
152
153
154
155
      // the menu eta runs from -25 to 24
      int menuEta = m_id*4 + (m_efexid%3)*16 + ieta - 25;
      auto iso_loose  = thr_eEM.isolation(TrigConf::Selection::WP::LOOSE, menuEta);
      auto iso_medium = thr_eEM.isolation(TrigConf::Selection::WP::MEDIUM, menuEta);
      auto iso_tight  = thr_eEM.isolation(TrigConf::Selection::WP::TIGHT, menuEta);  
156
157

      std::vector<unsigned int> threshReta;
158
159
160
      threshReta.push_back(iso_loose.reta_fw());
      threshReta.push_back(iso_medium.reta_fw());
      threshReta.push_back(iso_tight.reta_fw());
161
162

      std::vector<unsigned int> threshRhad;
163
164
165
      threshRhad.push_back(iso_loose.rhad_fw());
      threshRhad.push_back(iso_medium.rhad_fw());
      threshRhad.push_back(iso_tight.rhad_fw());
166
167

      std::vector<unsigned int> threshWstot;
168
169
170
      threshWstot.push_back(iso_loose.wstot_fw());
      threshWstot.push_back(iso_medium.wstot_fw());
      threshWstot.push_back(iso_tight.wstot_fw());
171

172
173
174
      ATH_MSG_DEBUG("ieta=" << ieta << "  loose => reta_fw=" << threshReta[0] << ", rhad_fw=" << threshRhad[0] << ", wstot_fw=" << threshWstot[0]);
      ATH_MSG_DEBUG("ieta=" << ieta << "  medium => reta_fw=" << threshReta[1] << ", rhad_fw=" << threshRhad[1] << ", wstot_fw=" << threshWstot[1]);
      ATH_MSG_DEBUG("ieta=" << ieta << "  tight => reta_fw=" << threshReta[2] << ", rhad_fw=" << threshRhad[2] << ", wstot_fw=" << threshWstot[2]);
175

176
177
178
      // Get Reta and Rhad outputs
      std::vector<unsigned int> RetaCoreEnv; 
      m_eFEXegAlgoTool->getReta(RetaCoreEnv);
179
180
181
182
      std::vector<unsigned int> RhadEMHad; 
      m_eFEXegAlgoTool->getRhad(RhadEMHad);
      std::vector<unsigned int> WstotDenNum;
      m_eFEXegAlgoTool->getWstot(WstotDenNum);
183
184
185
186
187

      // Set Reta, Rhad and Wstot WP
      unsigned int RetaWP = 0;
      unsigned int RhadWP = 0;
      unsigned int WstotWP = 0;
188
189
190
191
192
      
      // bitshifts for the different iso vars
      unsigned int RetaBitS = 3;
      unsigned int RhadBitS = 3;
      unsigned int WstotBitS = 5;
193

Will Buttinger's avatar
Will Buttinger committed
194
195
      unsigned int maxEtCountsEm = thr_eEM.maxEtCounts(m_eFexStep);
      if (eEMTobEt >= maxEtCountsEm){
Alan Watson's avatar
Alan Watson committed
196
197
198
	       RetaWP = 3;
	       RhadWP = 3;
	       WstotWP = 3;
199
200
      }
      else{
Alan Watson's avatar
Alan Watson committed
201
202
203
	       SetIsoWP(RetaCoreEnv,threshReta,RetaWP,RetaBitS);
	       SetIsoWP(RhadEMHad,threshRhad,RhadWP,RhadBitS);
	       SetIsoWP(WstotDenNum,threshWstot,WstotWP,WstotBitS);
204
      }
205
      int eta_ind = ieta; // No need to offset eta index with new 0-5 convention
206
      int phi_ind = iphi - 1;
207

208
209
210
      //form the egamma tob word and xTOB words
      uint32_t tobword = m_eFEXFormTOBsTool->formEmTOBWord(m_id,eta_ind,phi_ind,RhadWP,WstotWP,RetaWP,seed,und,eEMTobEt,ptMinToTopoCounts);
      std::vector<uint32_t> xtobwords = m_eFEXFormTOBsTool->formEmxTOBWords(m_efexid,m_id,eta_ind,phi_ind,RhadWP,WstotWP,RetaWP,seed,und,eEMTobEt,ptMinToTopoCounts);
211

212
213
214
      std::unique_ptr<eFEXegTOB> tmp_tob = m_eFEXegAlgoTool->geteFEXegTOB();
      
      tmp_tob->setFPGAID(m_id);
215
      tmp_tob->seteFEXID(m_efexid);
216
217
      tmp_tob->setEta(ieta);
      tmp_tob->setPhi(iphi);
218
      tmp_tob->setTobword(tobword);
219
220
      tmp_tob->setxTobword0(xtobwords[0]);
      tmp_tob->setxTobword1(xtobwords[1]);
221
222

      // for plotting
223
      if (inputOutputCollection->getdooutput() && (tobword != 0) && (eEMTobEt != 0)) {
224
225
226
227
        inputOutputCollection->addeFexNumber(m_efexid);
        inputOutputCollection->addEMtob(tobword);
        inputOutputCollection->addValue_eg("WstotNum", tmp_tob->getWstotNum());
        inputOutputCollection->addValue_eg("WstotDen", tmp_tob->getWstotDen());
228
229
230
231
        inputOutputCollection->addValue_eg("RetaNum", tmp_tob->getRetaCore());
        inputOutputCollection->addValue_eg("RetaDen", tmp_tob->getRetaEnv());
        inputOutputCollection->addValue_eg("RhadNum", tmp_tob->getRhadEM());
        inputOutputCollection->addValue_eg("RhadDen", tmp_tob->getRhadHad());
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
        inputOutputCollection->addValue_eg("haveSeed", m_eFEXegAlgoTool->hasSeed());
        inputOutputCollection->addValue_eg("ET", m_eFEXegAlgoTool->getET());
        float eta = 9999;
        m_eFEXegAlgoTool->getRealEta(eta);
        inputOutputCollection->addValue_eg("eta", eta);
        float phi = 9999;
        m_eFEXegAlgoTool->getRealPhi(phi);
        inputOutputCollection->addValue_eg("phi", phi);
        unsigned int em_et = 9999; 
        m_eFEXegAlgoTool->getCoreEMTowerET(em_et);
        inputOutputCollection->addValue_eg("em", em_et);
        unsigned int had_et = 9999;
        m_eFEXegAlgoTool->getCoreHADTowerET(had_et);
        inputOutputCollection->addValue_eg("had", had_et);
        inputOutputCollection->fill_eg();
      }
248

249
250
251
252
      // Now we've finished with that object we can move it into the class results store
      if ( (tobword != 0) && (eEMTobEt != 0) ) m_emTobObjects.push_back(std::move(tmp_tob));


253
254
255
    }
  }

256
  // --------------- TAU -------------
Nicholas Luongo's avatar
Nicholas Luongo committed
257
  for(int ieta = min_eta; ieta < overflow_eta; ieta++)
258
259
260
261
  {
    for(int iphi = 1; iphi < 9; iphi++)
    {
      int tobtable[3][3]={
262
263
264
265
266
267
268
269
270
271
272
        {ieta > 0 ? m_eTowersIDs[iphi-1][ieta-1] : 0,
         m_eTowersIDs[iphi-1][ieta],
         ieta < 5 ? m_eTowersIDs[iphi-1][ieta+1] : 0},

        {ieta > 0 ? m_eTowersIDs[iphi][ieta-1] : 0,
         m_eTowersIDs[iphi][ieta],
         ieta < 5 ? m_eTowersIDs[iphi][ieta+1] : 0},

        {ieta > 0 ? m_eTowersIDs[iphi+1][ieta-1] : 0,
         m_eTowersIDs[iphi+1][ieta],
         ieta < 5 ? m_eTowersIDs[iphi+1][ieta+1] : 0},
273
274
275
      };
      
      ATH_CHECK( m_eFEXtauAlgoTool->safetyTest() );
Nicholas Luongo's avatar
Nicholas Luongo committed
276
      m_eFEXtauAlgoTool->setup(tobtable, m_efexid, m_id, ieta);
277

Nicholas Luongo's avatar
Nicholas Luongo committed
278
279
      if (!m_eFEXtauAlgoTool->isCentralTowerSeed()){ continue; }

Nicholas Luongo's avatar
Nicholas Luongo committed
280
281
282
283
      // the minimum energy to send to topo (not eta dependent yet, but keep inside loop as it will be eventually?)
      unsigned int ptTauMinToTopoCounts = 0;
      ptTauMinToTopoCounts = thr_eTAU.ptMinToTopoCounts();

284
      // Get Et of eFEX tau object in internal units (25 MeV)
Nicholas Luongo's avatar
Nicholas Luongo committed
285
286
287
      unsigned int eTauTobEt = 0;
      eTauTobEt = m_eFEXtauAlgoTool->getEt();

Nicholas Luongo's avatar
Nicholas Luongo committed
288
      // thresholds from Trigger menu
Will Buttinger's avatar
Will Buttinger committed
289
290
291
292
293
      // the menu eta runs from -25 to 24
      int menuEta = m_id*4 + (m_efexid%3)*16 + ieta - 25;
      auto iso_loose  = thr_eTAU.isolation(TrigConf::Selection::WP::LOOSE, menuEta);
      auto iso_medium = thr_eTAU.isolation(TrigConf::Selection::WP::MEDIUM, menuEta);
      auto iso_tight  = thr_eTAU.isolation(TrigConf::Selection::WP::TIGHT, menuEta);  
Nicholas Luongo's avatar
Nicholas Luongo committed
294
295
296
297
298
299

      std::vector<unsigned int> threshRCore;
      threshRCore.push_back(iso_loose.rCore_fw());
      threshRCore.push_back(iso_medium.rCore_fw());
      threshRCore.push_back(iso_tight.rCore_fw());

300
301
302
303
304
      std::vector<unsigned int> threshRHad;
      threshRHad.push_back(iso_loose.rHad_fw());
      threshRHad.push_back(iso_medium.rHad_fw());
      threshRHad.push_back(iso_tight.rHad_fw());

Nicholas Luongo's avatar
Nicholas Luongo committed
305
306
307
308
      // Get isolation values
      std::vector<unsigned int> rCoreVec; 
      m_eFEXtauAlgoTool->getRCore(rCoreVec);

309
310
311
      std::vector<unsigned int> rHadVec;
      m_eFEXtauAlgoTool->getRHad(rHadVec);

Nicholas Luongo's avatar
Nicholas Luongo committed
312
313
      // Set isolation WP
      unsigned int rCoreWP = 0;
314
      unsigned int rHadWP = 0;
Nicholas Luongo's avatar
Nicholas Luongo committed
315
316
317

      // Isolation bitshift value
      unsigned int RcoreBitS = 3;
318
      unsigned int RhadBitS = 3;
Nicholas Luongo's avatar
Nicholas Luongo committed
319

Will Buttinger's avatar
Will Buttinger committed
320
321
322
323
      unsigned int maxEtCountsTau = thr_eTAU.maxEtCounts(m_eFexStep);
      if (eTauTobEt >= maxEtCountsTau) {
	rCoreWP = 3;
	rHadWP = 3;
324
      } else {
Will Buttinger's avatar
Will Buttinger committed
325
326
	SetIsoWP(rCoreVec,threshRCore,rCoreWP,RcoreBitS);
	SetIsoWP(rHadVec,threshRHad,rHadWP,RhadBitS);
Nicholas Luongo's avatar
Nicholas Luongo committed
327
328
329
330
331
332
333
      }

      unsigned int seed = 0;
      seed = m_eFEXtauAlgoTool->getSeed();
      // Seed as returned is supercell value within 3x3 area, here want it within central cell
      seed = seed - 4;      

334
      unsigned int und = (m_eFEXtauAlgoTool->getUnD() ? 1 : 0);
Nicholas Luongo's avatar
Nicholas Luongo committed
335

Nicholas Luongo's avatar
Nicholas Luongo committed
336
337
      int eta_ind = ieta; // No need to offset eta index with new 0-5 convention
      int phi_ind = iphi - 1;
338

339
      // Form the tau TOB word and xTOB words
340
      uint32_t tobword = m_eFEXFormTOBsTool->formTauTOBWord(m_id, eta_ind, phi_ind, eTauTobEt, rHadWP, rCoreWP, seed, und, ptTauMinToTopoCounts);
341
342
      std::vector<uint32_t> xtobwords = m_eFEXFormTOBsTool->formTauxTOBWords(m_efexid, m_id, eta_ind, phi_ind, eTauTobEt, rHadWP, rCoreWP, seed, und, ptTauMinToTopoCounts);

Alan Watson's avatar
Alan Watson committed
343
      std::unique_ptr<eFEXtauTOB> tmp_tau_tob = m_eFEXtauAlgoTool->getTauTOB();
344
345
346
347
348
      tmp_tau_tob->setFPGAID(m_id);
      tmp_tau_tob->seteFEXID(m_efexid);
      tmp_tau_tob->setEta(ieta);
      tmp_tau_tob->setPhi(iphi);
      tmp_tau_tob->setTobword(tobword);
349
350
      tmp_tau_tob->setxTobword0(xtobwords[0]);
      tmp_tau_tob->setxTobword1(xtobwords[1]);
Nicholas Luongo's avatar
Nicholas Luongo committed
351

352
      // for plotting
353
      if ((inputOutputCollection->getdooutput()) && ( tobword != 0 )) {
354
355
356
357
        inputOutputCollection->addValue_tau("isCentralTowerSeed", m_eFEXtauAlgoTool->isCentralTowerSeed());
        inputOutputCollection->addValue_tau("Et", m_eFEXtauAlgoTool->getEt());
        inputOutputCollection->addValue_tau("Eta", ieta);
        inputOutputCollection->addValue_tau("Phi", iphi);
358
        const LVL1::eTower * centerTower = eTowerContainer->findTower(m_eTowersIDs[iphi][ieta]);
359
360
        const LVL1::eTower * oneOffEtaTower = ieta < 5 ? eTowerContainer->findTower(m_eTowersIDs[iphi][ieta+1]) : nullptr;
        const LVL1::eTower * oneBelowEtaTower = ieta > 0 ? eTowerContainer->findTower(m_eTowersIDs[iphi][ieta-1]) : nullptr;
Nicholas Luongo's avatar
Nicholas Luongo committed
361
        inputOutputCollection->addValue_tau("CenterTowerEt", centerTower->getTotalET());
362
363
        inputOutputCollection->addValue_tau("OneOffEtaTowerEt", oneOffEtaTower ? oneOffEtaTower->getTotalET() : 0);
        inputOutputCollection->addValue_tau("OneBelowEtaTowerEt", oneBelowEtaTower ? oneBelowEtaTower->getTotalET() : 0);
364
365
        inputOutputCollection->addValue_tau("FloatEta", centerTower->eta() * centerTower->getPosNeg());
        inputOutputCollection->addValue_tau("FloatPhi", centerTower->phi());
366
367
368
369
370
371
372
373
        inputOutputCollection->addValue_tau("RCoreCore", rCoreVec[0]);
        inputOutputCollection->addValue_tau("RCoreEnv", rCoreVec[1]);
        inputOutputCollection->addValue_tau("RealRCore", m_eFEXtauAlgoTool->getRealRCore());
        inputOutputCollection->addValue_tau("RCoreWP", rCoreWP);
        inputOutputCollection->addValue_tau("RHadCore", rHadVec[0]);
        inputOutputCollection->addValue_tau("RHadEnv", rHadVec[1]);
        inputOutputCollection->addValue_tau("RealRHad", m_eFEXtauAlgoTool->getRealRHad());
        inputOutputCollection->addValue_tau("RHadWP", rHadWP);
Nicholas Luongo's avatar
Nicholas Luongo committed
374
375
        inputOutputCollection->addValue_tau("Seed", seed);
        inputOutputCollection->addValue_tau("UnD", und);
Nicholas Luongo's avatar
Nicholas Luongo committed
376
377
378
        inputOutputCollection->addValue_tau("eFEXID", m_efexid);
        inputOutputCollection->addValue_tau("FPGAID", m_id);

379
380
381
        
        inputOutputCollection->fill_tau();
      }
382
383
384
      // Now we've finished with that object we can move it into the class results store
      if ( tobword != 0 ) m_tauTobObjects.push_back(std::move(tmp_tau_tob));

385
386
387
388
389
390
391
    }
  }

  return StatusCode::SUCCESS;

}

392
393


394
std::vector<std::unique_ptr<eFEXegTOB>> eFEXFPGA::getEmTOBs()
395
{
396
397
398
  // TOB sorting moved to eFEXSysSim to simplify xTOB production
  // But leave this here in case more subtle requirement is uncovered in future
  /*
399
  auto tobsSort = m_emTobObjects;
400
401
402
403

  ATH_MSG_DEBUG("number of tobs: " <<tobsSort.size() << " in FPGA: " << m_id << " before truncation");

  // sort tobs by their et (last 12 bits of the 32 bit tob word)
404
  std::sort (tobsSort.begin(), tobsSort.end(), TOBetSort<eFEXegTOB>);
405
406

  // return the top 6 highest ET TOBs from the FPGA
407
  if (tobsSort.size() > 6) tobsSort.resize(6);
408
  return tobsSort;
409
410
411
412
413
414
415
416
417
418
419
420
421
422
  */

  /* Returning a vector of unique_pointers means this class will lose ownership.
     This shouldn't be an issue since all this class does is create and return the 
     objects, but you should bear it in mind if you make changes */

  // This copy seems to be needed - it won't let me pass m_emTobOjects directly (to do with being a class member?)
  std::vector<std::unique_ptr<eFEXegTOB>> tobsSort;
  tobsSort.clear();
  for(auto &j : m_emTobObjects){
      tobsSort.push_back(std::move(j));
  }

  return tobsSort;
423
424
425

}

426
std::vector<std::unique_ptr<eFEXtauTOB>> eFEXFPGA::getTauTOBs()
Nicholas Luongo's avatar
Nicholas Luongo committed
427
{
428
429
430
  // TOB sorting moved to eFEXSysSim to simplify xTOB production
  // But leave this here in case more subtle requirement is uncovered in future
  /*
431
  auto tobsSort = m_tauTobObjects;
Nicholas Luongo's avatar
Nicholas Luongo committed
432
433
434
435

  ATH_MSG_DEBUG("number of tobs: " <<tobsSort.size() << " in FPGA: " << m_id << " before truncation");

  // sort tobs by their et (last 12 bits of the 32 bit tob word)
436
  std::sort (tobsSort.begin(), tobsSort.end(), TOBetSort<eFEXtauTOB>);
Nicholas Luongo's avatar
Nicholas Luongo committed
437
438
439
440

  // return the top 6 highest ET TOBs from the FPGA
  if (tobsSort.size() > 6) tobsSort.resize(6);
  return tobsSort;
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  */

  /* Returning a vector of unique_pointers means this class will lose ownership.
     This shouldn't be an issue since all this class does is create and return the 
     objects, but you should bear it in mind if you make changes */

  // This copy seems to be needed - it won't let me pass m_tauTobOjects directly (to do with being a class member?)
  std::vector<std::unique_ptr<eFEXtauTOB>> tobsSort;
  tobsSort.clear();
  for(auto &j : m_tauTobObjects){
      tobsSort.push_back(std::move(j));
  }

  return tobsSort;
Nicholas Luongo's avatar
Nicholas Luongo committed
455
456

}
457

458
459
460
461
462
463
464
465
void eFEXFPGA::SetTowersAndCells_SG(int tmp_eTowersIDs_subset[][6]){
    
  int rows = 10;
  int cols = sizeof tmp_eTowersIDs_subset[0] / sizeof tmp_eTowersIDs_subset[0][0];
  
  std::copy(&tmp_eTowersIDs_subset[0][0], &tmp_eTowersIDs_subset[0][0]+(10*6),&m_eTowersIDs[0][0]);
  
  if(false){ //this prints out the eTower IDs that each FPGA is responsible for
Jacob Julian Kempster's avatar
Jacob Julian Kempster committed
466
    ATH_MSG_DEBUG("\n---- eFEXFPGA --------- eFEX (" << m_efexid << " ----- FPGA (" << m_id << ") IS RESPONSIBLE FOR eTOWERS :");
467
468
469
470
471
472
473
    for (int thisRow=rows-1; thisRow>=0; thisRow--){
      for (int thisCol=0; thisCol<cols; thisCol++){
	if(thisCol != cols-1){ ATH_MSG_DEBUG("|  " << m_eTowersIDs[thisRow][thisCol] << "  "); }
	else { ATH_MSG_DEBUG("|  " << m_eTowersIDs[thisRow][thisCol] << "  |"); }
      }
    }
  }
474
475
476
477
478


  //-----------------------------------------------------------
  // 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)
  if(false){ // CSV CODE TO BE RE-INTRODUCED VERY SOON
479
480
481
    SG::ReadHandle<eTowerContainer> eTowerContainer(m_eTowerContainerKey);
    if(!eTowerContainer.isValid()){
      ATH_MSG_FATAL("Could not retrieve container " << m_eTowerContainerKey.key() );
482
483
484
485
486
487
488
489
    }
    
    std::ofstream tower_fpga_efex_map;
    tower_fpga_efex_map.open ("./tower_fpga_efex_map.csv", std::ios_base::app);
    
    for (int thisRow=rows-1; thisRow>=0; thisRow--){
      for (int thisCol=0; thisCol<cols; thisCol++){
	
490
	const LVL1::eTower * tmpTower = eTowerContainer->findTower(m_eTowersIDs[thisRow][thisCol]);
491
492
493
494
495
496
497
498
	
	tower_fpga_efex_map << m_efexid << "," << m_id << "," << m_eTowersIDs[thisRow][thisCol] << "," << tmpTower->eta() << "," << tmpTower->phi() << "\n";
	
      }
    }
  }
  //------------------------------------------------------------

499
500
  
}
501

502

503
504
505
506
void eFEXFPGA::SetIsoWP(std::vector<unsigned int> & CoreEnv, std::vector<unsigned int> & thresholds, unsigned int & workingPoint, unsigned int & bitshift) {
  // Working point evaluted by Core * 2^bitshift > Threshold * Environment conditions
  std::unordered_map<unsigned int, unsigned int> bsmap { {3, 8}, {5, 32}};

Will Buttinger's avatar
Will Buttinger committed
507
508
  int large = CoreEnv[0]*bsmap[bitshift]; // core
  int small = CoreEnv[1]; // env
509

Will Buttinger's avatar
Will Buttinger committed
510
511
512
513
514
515
  unsigned int shifted = large;// <<bitShift;
  if ( shifted > 0xffff )
    shifted = 0xffff;
  if ( shifted >= small*thresholds[2] ) {
    workingPoint=3;
    return;
516
  }
Will Buttinger's avatar
Will Buttinger committed
517
518
519
520
521
522
523
524
525
526
  if ( shifted >= small*thresholds[1] ) {
    workingPoint=2;
    return;
  }
  if ( shifted >= small*thresholds[0] ) {
    workingPoint=1;
    return;
  }
  workingPoint=0;
  return;
527
528
}

529
530
} // end of namespace bracket