jFEXFPGA.cxx 38.3 KB
Newer Older
1
/*
2
  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3
4
5
6
7
8
9
10
11
12
13
*/

//***************************************************************************
//                           jFEXFPGA  -  description
//                              -------------------
//     begin                : 19 10 2020
//     email                : jacob.julian.kempster@cern.ch
//  ***************************************************************************/
#include "L1CaloFEXSim/jFEXFPGA.h"
#include "L1CaloFEXSim/jTower.h"
#include "L1CaloFEXSim/jTowerContainer.h"
14
15
#include "L1CaloFEXSim/jFEXSmallRJetAlgo.h" 
#include "L1CaloFEXSim/jFEXSmallRJetTOB.h" 
16
17
#include "L1CaloFEXSim/jFEXLargeRJetTOB.h"
#include "L1CaloFEXSim/jFEXLargeRJetAlgo.h" 
18
#include "L1CaloFEXSim/jFEXOutputCollection.h" 
19
#include "L1CaloFEXSim/FEXAlgoSpaceDefs.h"
20
21
22
23
24
25
#include "L1CaloFEXSim/jFEXtauAlgo.h" 
#include "L1CaloFEXSim/jFEXtauTOB.h"  
#include "L1CaloFEXSim/jFEXsumETAlgo.h" 
#include "L1CaloFEXSim/jFEXsumETTOB.h"  
#include "L1CaloFEXSim/jFEXmetAlgo.h" 
#include "L1CaloFEXSim/jFEXmetTOB.h"  
26
27
#include "L1CaloFEXSim/jFEXForwardJetsAlgo.h"
#include "L1CaloFEXSim/jFEXForwardJetsInfo.h"
28
#include "L1CaloFEXSim/jFEXPileupAndNoise.h"
29
30
31
32
#include "CaloEvent/CaloCellContainer.h"
#include "CaloIdentifier/CaloIdManager.h"
#include "CaloIdentifier/CaloCell_SuperCell_ID.h"
#include "AthenaBaseComps/AthAlgorithm.h"
33
#include <vector>
34
#include "TrigConfData/L1Menu.h"
35
#include "TH1F.h"
36
37
38
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/ISvcLocator.h"
#include "GaudiKernel/ITHistSvc.h"
39
#include "GaudiKernel/IClassIDSvc.h"
40
41
42
#include "StoreGate/WriteHandle.h"
#include "StoreGate/ReadHandle.h"
#include "SGTools/TestStore.h"
43
#include "StoreGate/StoreGateSvc.h"
44

45

46
47
48
49
namespace LVL1 {

  // default constructor for persistency

50
51
jFEXFPGA::jFEXFPGA(const std::string& type,const std::string& name,const IInterface* parent): AthAlgTool(type,name,parent) {
    declareInterface<IjFEXFPGA>(this);
52
}
53
54
55
56
57

/** Destructor */
jFEXFPGA::~jFEXFPGA()
{
}
58
59
60

//================ Initialisation =================================================
  
61
StatusCode jFEXFPGA::initialize() {
62

63
64
65
66
67
    ATH_CHECK(m_jFEXFPGA_jTowerContainerKey.initialize());
    ATH_CHECK(m_jFEXFPGA_jFEXOutputCollectionKey.initialize());
    ATH_CHECK(m_l1MenuKey.initialize());
    ATH_CHECK( m_jFEXtauAlgoTool.retrieve());
    return StatusCode::SUCCESS;
68
}
69

70
71
72
StatusCode jFEXFPGA::init(int id, int jfexid) {
    m_id = id;
    m_jfexid = jfexid;
73

74
    return StatusCode::SUCCESS;
75
76
77

}

78
void jFEXFPGA::reset() {
79

80
81
82
83
84
85
86
87
    m_id = -1;
    m_jfexid = -1;
    m_tau_tobwords.clear();
    m_SRJet_tobwords.clear();
    m_LRJet_tobwords.clear();
    m_sumET_tobwords.clear();
    m_Met_tobwords.clear();
    m_map_Etvalues_FPGA.clear();
88
89
90

}

91
StatusCode jFEXFPGA::execute(jFEXOutputCollection* inputOutputCollection) {
92

93
94
95
96
97
    SG::ReadHandle<jTowerContainer> jk_jFEXFPGA_jTowerContainer(m_jFEXFPGA_jTowerContainerKey/*,ctx*/);
    if(!jk_jFEXFPGA_jTowerContainer.isValid()) {
        ATH_MSG_FATAL("Could not retrieve jk_jFEXFPGA_jTowerContainer " << m_jFEXFPGA_jTowerContainerKey.key() );
        return StatusCode::FAILURE;
    }
98
    
99
    ATH_CHECK( m_jFEXPileupAndNoiseTool->reset());
100
101
    ATH_CHECK( m_jFEXPileupAndNoiseTool->safetyTest());
    
102
    if(m_jfexid == 0 || m_jfexid == 5) {
103
        m_jFEXPileupAndNoiseTool->setup(m_jTowersIDs_Wide);
104
        //return StatusCode::SUCCESS;
105
    }
106
107
    else {
        //return StatusCode::SUCCESS;
108
109
110
        m_jFEXPileupAndNoiseTool->setup(m_jTowersIDs_Thin);
    }
    //Calculating and sustracting pileup
111
    std::vector<float> pileup_rho;
112
    pileup_rho = m_jFEXPileupAndNoiseTool->CalculatePileup();
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

    //Applying pileup sustraction in jet or met independently - this sets the flags to true in m_jFEXPileupAndNoiseTool
    m_jFEXPileupAndNoiseTool->ApplyPileup2Jets(true);
    m_jFEXPileupAndNoiseTool->ApplyPileup2Met(true);
    
    //Noise should be always applied
    m_jFEXPileupAndNoiseTool->ApplyNoise2Jets(true);
    m_jFEXPileupAndNoiseTool->ApplyNoise2Met(true);
    //Getting the values
    m_map_HAD_Etvalues_FPGA = m_jFEXPileupAndNoiseTool->Get_HAD_Et_values();
    m_map_EM_Etvalues_FPGA  = m_jFEXPileupAndNoiseTool->Get_EM_Et_values();
    m_map_Etvalues_FPGA     = m_jFEXPileupAndNoiseTool->GetEt_values();
    std::vector<int> pileup_ID;
    std::vector<int> pileup_HAD_jet;
    std::vector<int> pileup_EM_jet;
    std::vector<int> pileup_Total_jet;
    std::vector<int> pileup_HAD_met;
    std::vector<int> pileup_EM_met;
    std::vector<int> pileup_Total_met;
    for (auto const& [key, val] : m_map_HAD_Etvalues_FPGA)
    {
        pileup_ID.push_back(key);
        pileup_HAD_jet.push_back(val[0]);
        pileup_EM_jet.push_back(m_map_EM_Etvalues_FPGA[key][0]);
        pileup_Total_jet.push_back(m_map_Etvalues_FPGA[key][0]);
        pileup_HAD_met.push_back(val[1]);
        pileup_EM_met.push_back(m_map_EM_Etvalues_FPGA[key][1]);
        pileup_Total_met.push_back(m_map_Etvalues_FPGA[key][1]);
    }    
    
    //saving pileup information
144
145
146
147
148
149
150
    inputOutputCollection->addValue_pileup("pileup_FPGAid", m_id);
    inputOutputCollection->addValue_pileup("pileup_jFEXid", m_jfexid);
    inputOutputCollection->addValue_pileup("pileup_rho_EM", pileup_rho[0]);
    inputOutputCollection->addValue_pileup("pileup_rho_HAD1", pileup_rho[1]);
    inputOutputCollection->addValue_pileup("pileup_rho_HAD2", pileup_rho[2]);
    inputOutputCollection->addValue_pileup("pileup_rho_HAD3", pileup_rho[3]);
    inputOutputCollection->addValue_pileup("pileup_rho_FCAL", pileup_rho[4]);
151
152
153
154
155
156
157
158
159
160
161
    inputOutputCollection->addValue_pileup("pileup_map_ID"  , pileup_ID);
    inputOutputCollection->addValue_pileup("pileup_map_Et_values_HAD_jet"  , pileup_HAD_jet);
    inputOutputCollection->addValue_pileup("pileup_map_Et_values_EM_jet"   , pileup_EM_jet);
    inputOutputCollection->addValue_pileup("pileup_map_Et_values_Total_jet", pileup_Total_jet);
    inputOutputCollection->addValue_pileup("pileup_map_Et_values_HAD_met"  , pileup_HAD_met);
    inputOutputCollection->addValue_pileup("pileup_map_Et_values_EM_met"   , pileup_EM_met);
    inputOutputCollection->addValue_pileup("pileup_map_Et_values_Total_met", pileup_Total_met);
    inputOutputCollection->fill_pileup();    
    
    
    
162
    if(m_id==0 || m_id==2) {
163
        ATH_CHECK( m_jFEXsumETAlgoTool->safetyTest());
164
        ATH_CHECK( m_jFEXsumETAlgoTool->reset());
165
        ATH_CHECK( m_jFEXmetAlgoTool->safetyTest());
166
        ATH_CHECK( m_jFEXmetAlgoTool->reset());
167
168
        m_jFEXsumETAlgoTool->setFPGAEnergy(m_map_Etvalues_FPGA);
        m_jFEXmetAlgoTool->setFPGAEnergy(m_map_Etvalues_FPGA);
169
170
171
172
173
174
175
           
           
        //Retrieve the L1 menu configuration
        SG::ReadHandle<TrigConf::L1Menu> l1Menu (m_l1MenuKey/*, ctx*/);
        const TrigConf::L1ThrExtraInfo_jTE & thr_jTE = l1Menu->thrExtraInfo().jTE();
        std::string str_jfexname = m_jfex_string[m_jfexid];
        unsigned int bin_pos = thr_jTE.etaBoundary_fw(str_jfexname);
176
177
178

        if(m_jfexid > 0 && m_jfexid < 5) {

179
180
181
            //-----------------jFEXsumETAlgo-----------------
            m_jFEXsumETAlgoTool->setup(m_jTowersIDs_Thin);
            m_jFEXsumETAlgoTool->buildBarrelSumET();
182
            m_sumET_tobwords.push_back(formSumETTOB(m_jFEXsumETAlgoTool->getETlowerEta(bin_pos),m_jFEXsumETAlgoTool->getETupperEta(bin_pos)));
183
184
185

            //-----------------jFEXmetAlgo-----------------
            m_jFEXmetAlgoTool->setup(m_jTowersIDs_Thin);
186
187
188
            m_jFEXmetAlgoTool->buildBarrelmet();
            m_Met_tobwords.push_back(formMetTOB(m_jFEXmetAlgoTool->GetMetXComponent(),m_jFEXmetAlgoTool->GetMetYComponent()));
        }
189
        else if(m_jfexid == 0 ) {
190
191
192
            int flipped_jTowersIDs      [FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width] = {{0}};
            int max_phi_it = FEXAlgoSpaceDefs::jFEX_algoSpace_height-1;
            int max_eta_it = FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width-1;
193
            for(int mphi = 0; mphi <= max_phi_it; mphi++) {
194
195
196
197
                for(int meta = 0; meta <= max_eta_it; meta++) {
                    flipped_jTowersIDs[mphi][meta]=m_jTowersIDs_Wide[mphi][max_eta_it-meta];
                }
            }
198
            //-----------------jFEXsumETAlgo-----------------
199
            m_jFEXsumETAlgoTool->setup(flipped_jTowersIDs);
200
            m_jFEXsumETAlgoTool->buildFWDSumET();
201
            m_sumET_tobwords.push_back(formSumETTOB(m_jFEXsumETAlgoTool->getETlowerEta(bin_pos),m_jFEXsumETAlgoTool->getETupperEta(bin_pos)));
202
203

            //-----------------jFEXmetAlgo-----------------
204
            m_jFEXmetAlgoTool->setup(flipped_jTowersIDs);
205
            m_jFEXmetAlgoTool->buildFWDmet();
206
            m_Met_tobwords.push_back(formMetTOB(m_jFEXmetAlgoTool->GetMetXComponent(),m_jFEXmetAlgoTool->GetMetYComponent()));
207
        }
208
        else if(m_jfexid == 5) {
209
210
211
            //-----------------jFEXsumETAlgo-----------------
            m_jFEXsumETAlgoTool->setup(m_jTowersIDs_Wide);
            m_jFEXsumETAlgoTool->buildFWDSumET();
212
            m_sumET_tobwords.push_back(formSumETTOB(m_jFEXsumETAlgoTool->getETlowerEta(bin_pos),m_jFEXsumETAlgoTool->getETupperEta(bin_pos)));
213
214

            //-----------------jFEXmetAlgo-----------------
215
216
217
218
219
            m_jFEXmetAlgoTool->setup(m_jTowersIDs_Wide);
            m_jFEXmetAlgoTool->buildFWDmet();
            m_Met_tobwords.push_back(formMetTOB(m_jFEXmetAlgoTool->GetMetXComponent(),m_jFEXmetAlgoTool->GetMetYComponent()));
        }
    }
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    //-----------jFEXSmallRJet & Large R Jet Algo-----------------
    ATH_MSG_DEBUG("==== jFEXSmallRJetAlgo ========");

    //Central region algorithms
    if(m_jfexid > 0 && m_jfexid < 5) {
            for(int mphi = 8; mphi < FEXAlgoSpaceDefs::jFEX_algoSpace_height -8; mphi++) {
            for(int meta = 8; meta < FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width -8; meta++) {

                //create search window including towerIDs required for seeding.
                int SRJet_SearchWindow[7][7] = {{0}};
                int largeRCluster_IDs[15][15]= {{0}};


                for(int i = -7; i< 8; i++ ) {
                    for(int j = -7; j< 8; j++) {

                        if(std::abs(i)<4 && std::abs(j)<4) {
                            SRJet_SearchWindow[3 + i][3 + j] = m_jTowersIDs_Thin[mphi + i][meta +j];
                        }
                        uint deltaR = std::sqrt(std::pow(i,2)+std::pow(j,2));
                        if(deltaR>=4 && deltaR<8) {
                            largeRCluster_IDs[7 +i][7 +j] = m_jTowersIDs_Thin[mphi + i][meta +j];
                        }

                    }
                }

                m_jFEXSmallRJetAlgoTool->setFPGAEnergy(m_map_Etvalues_FPGA);
                m_jFEXLargeRJetAlgoTool->setFPGAEnergy(m_map_Etvalues_FPGA);
                m_jFEXSmallRJetAlgoTool->setup(SRJet_SearchWindow);
                m_jFEXLargeRJetAlgoTool->setupCluster(largeRCluster_IDs);
                m_jFEXSmallRJetAlgoTool->buildSeeds();
                bool SRJet_LM = m_jFEXSmallRJetAlgoTool->isSeedLocalMaxima();
254
                inputOutputCollection->addValue_smallRJet("smallRJet_isCentralTowerSeed", SRJet_LM);
255
256
                int smallClusterET = m_jFEXSmallRJetAlgoTool->getSmallClusterET();
                //These are plots of the central TT for each 5x5 search window.
257
258
259
                inputOutputCollection->addValue_smallRJet("smallRJet_ET", m_jFEXSmallRJetAlgoTool->getTTowerET(m_jTowersIDs_Thin[mphi][meta]));
                inputOutputCollection->addValue_smallRJet("smallRJet_phi",m_jFEXSmallRJetAlgoTool->getRealPhi(m_jTowersIDs_Thin[mphi][meta]));
                inputOutputCollection->addValue_smallRJet("smallRJet_eta",m_jFEXSmallRJetAlgoTool->getRealEta(m_jTowersIDs_Thin[mphi][meta]));
260

261
                inputOutputCollection->addValue_smallRJet("smallRJet_clusterET", smallClusterET);
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

                if(!SRJet_LM) {
                    continue;
                }
                std::unique_ptr<jFEXSmallRJetTOB> tmp_SRJet_tob = m_jFEXSmallRJetAlgoTool->getSmallRJetTOBs();

                bool check = m_jFEXSmallRJetAlgoTool->checkDisplacedLM();
                //to check if Local Maxima is displaced.
                int meta_LM = meta;
                int mphi_LM = mphi;
                if(check  && SRJet_LM) {
                    meta_LM = meta -1;
                    mphi_LM = mphi -1;

                }
277

278
279
280
281
                bool SR_TOB_saturated = false;
                if (smallClusterET/200. > 0x7ff) SR_TOB_saturated = true;

                // for plotting variables in TOBS- internal check:
282
283
284
285
286
287
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_eta", tmp_SRJet_tob->setEta(meta_LM)-8);
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_phi", tmp_SRJet_tob->setPhi(mphi_LM)-8);
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_ET", tmp_SRJet_tob->setET(smallClusterET/200));
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_sat", tmp_SRJet_tob->setSat(SR_TOB_saturated));
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_jfexID", m_jfexid);
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_fpgaID", m_id);
288
289
290

                uint32_t SRJet_tobword = formSmallRJetTOB(mphi_LM, meta_LM);
                m_SRJet_tobwords.push_back(SRJet_tobword);
291
292
293
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_word",SRJet_tobword);
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_jfexID", m_jfexid);
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_fpgaID", m_id);
294

295
                inputOutputCollection->fill_smallRJet();
296
297
298
299
300
301
302
303

                ATH_MSG_DEBUG("==== jFEXLargeRJetAlgo ========");
                //LargeRJetAlgo is here as SmallRJetlocalMaxima is a requirement
                unsigned int largeClusterET = m_jFEXLargeRJetAlgoTool->getLargeClusterET(smallClusterET,m_jFEXLargeRJetAlgoTool->getRingET());
                std::unique_ptr<jFEXLargeRJetTOB> tmp_LRJet_tob = m_jFEXLargeRJetAlgoTool->getLargeRJetTOBs(smallClusterET,m_jFEXSmallRJetAlgoTool->getTTIDcentre());
                unsigned int LR_TOB_saturated = 0;
                if (largeClusterET/200. >  0x1fff) LR_TOB_saturated = 1;

304
305
306
                inputOutputCollection->addValue_largeRJet("largeRJet_ET", largeClusterET);
                inputOutputCollection->addValue_largeRJet("largeRJet_phi", m_jFEXSmallRJetAlgoTool->getRealPhi(m_jTowersIDs_Thin[mphi][meta]));
                inputOutputCollection->addValue_largeRJet("largeRJet_eta", m_jFEXSmallRJetAlgoTool->getRealEta(m_jTowersIDs_Thin[mphi][meta]));
307

308
309
310
311
312
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_ET",tmp_LRJet_tob->setET(largeClusterET/200));
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_eta",tmp_SRJet_tob->setEta(meta));
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_phi",tmp_SRJet_tob->setPhi(mphi));
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_sat",tmp_LRJet_tob->setSat(LR_TOB_saturated));
                inputOutputCollection->fill_largeRJet();
313
314
                uint32_t LRJet_tobword = formLargeRJetTOB(mphi, meta);
                if ( LRJet_tobword != 0 ) m_LRJet_tobwords.push_back(LRJet_tobword);
315
316
317
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_word", LRJet_tobword);
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_jfexID", m_jfexid);
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_fpgaID", m_id);
318
            }
319
        }
320
321


322
    } //end of if statement for checking if in central jfex modules
323
324
    inputOutputCollection->fill_smallRJet();
    inputOutputCollection->fill_largeRJet();
325

326
    //**********Forward Jets***********************
327

328
329
330
331
332
    //FCAL region algorithm
    if(m_jfexid ==0 || m_jfexid ==5) {
        ATH_CHECK(m_jFEXForwardJetsAlgoTool->safetyTest());
        m_jFEXForwardJetsAlgoTool->setFPGAEnergy(m_map_Etvalues_FPGA);
        m_jFEXForwardJetsAlgoTool->setup(m_jTowersIDs_Wide,m_jfexid,m_id);
333

334
        m_FCALJets =  m_jFEXForwardJetsAlgoTool->calculateJetETs();
335

336
        for(std::unordered_map<int, jFEXForwardJetsInfo>::iterator it = m_FCALJets.begin(); it!=(m_FCALJets.end()); ++it) {
337

338
339
340
            jFEXForwardJetsInfo FCALJets = it->second;
            int iphi = FCALJets.getCentreLocalTTPhi();
            int ieta = FCALJets.getCentreLocalTTEta();
341

342
343
344
345
            float centre_eta = std::round(FCALJets.getCentreTTEta()*10);
            float centre_phi = std::round(FCALJets.getCentreTTPhi()*10);
            int output_centre_eta = static_cast<int> (centre_eta);
            int output_centre_phi = static_cast<int> (centre_phi);
346

347
348
349
350
351
352
353
354
355
356
            m_SRJetET = FCALJets.getSeedET() + FCALJets.getFirstEnergyRingET();
            m_LRJetET = m_SRJetET + FCALJets.getSecondEnergyRingET();
            uint32_t SRFCAL_Jet_tobword = formSmallRJetTOB(iphi, ieta);
            if ( SRFCAL_Jet_tobword != 0 ) m_SRJet_tobwords.push_back(SRFCAL_Jet_tobword);
            uint32_t LRFCAL_Jet_tobword = formLargeRJetTOB(iphi, ieta);
            if ( LRFCAL_Jet_tobword != 0 ) m_LRJet_tobwords.push_back(LRFCAL_Jet_tobword);
            int SRFCAL_TOB_saturated = 0;
            if (m_SRJetET/200. > 0x7ff) SRFCAL_TOB_saturated = 1;
            unsigned int LRFCAL_TOB_saturated = 0;
            if (m_LRJetET/200. >  0x1fff) LRFCAL_TOB_saturated = 1;
357
358
359
360
361
362
363
            inputOutputCollection->addValue_smallRJet("smallRJet_phi", output_centre_phi);
            inputOutputCollection->addValue_smallRJet("smallRJet_eta", output_centre_eta);
            inputOutputCollection->addValue_smallRJet("smallRJet_clusterET", m_SRJetET);
            inputOutputCollection->addValue_smallRJet("smallRJet_sat", SRFCAL_TOB_saturated);
            inputOutputCollection->addValue_smallRJet("smallRJet_isCentralTowerSeed",true);
            inputOutputCollection->addValue_smallRJet("smallRJetTOB_jfexID", m_jfexid);
            inputOutputCollection->addValue_smallRJet("smallRJetTOB_fpgaID", m_id);
364
            if(m_jfexid == 0) {
365
366
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_eta", 36-ieta);
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_eta", 36-ieta);
367
            }
368

369
            if(m_jfexid == 5) {
370
371
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_eta", ieta-8);
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_eta", ieta-8);
372
            }
373

374
            if(iphi >=FEXAlgoSpaceDefs::jFEX_algoSpace_EMB_start_phi && iphi< FEXAlgoSpaceDefs::jFEX_algoSpace_EMB_end_phi) {
375
376
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_phi", iphi-8);
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_phi", iphi-8);
377
            }
378

379
            if(iphi >=FEXAlgoSpaceDefs::jFEX_algoSpace_EMIE_start_phi && iphi< FEXAlgoSpaceDefs::jFEX_algoSpace_EMIE_end_phi) {
380
381
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_phi", iphi-4);
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_phi", iphi-4);
382
            }
383

384
            if(iphi >=FEXAlgoSpaceDefs::jFEX_algoSpace_FCAL_start_phi && iphi< FEXAlgoSpaceDefs::jFEX_algoSpace_FCAL_end_phi) {
385
386
                inputOutputCollection->addValue_smallRJet("smallRJetTOB_phi", iphi-2);
                inputOutputCollection->addValue_largeRJet("largeRJetTOB_phi", iphi-2);
387
            }
388
389
            inputOutputCollection->addValue_smallRJet("smallRJetTOB_ET", m_SRJetET/200);
            inputOutputCollection->addValue_smallRJet("smallRJetTOB_sat", SRFCAL_TOB_saturated);
390

391
392
393
            inputOutputCollection->addValue_smallRJet("smallRJetTOB_word", SRFCAL_Jet_tobword);
            inputOutputCollection->addValue_smallRJet("smallRJetTOB_jfexID", m_jfexid);
            inputOutputCollection->addValue_smallRJet("smallRJetTOB_fpgaID", m_id);
394

395
            //Output Collection for Large R Jet
396
397
398
399
            inputOutputCollection->addValue_largeRJet("largeRJet_ET", m_LRJetET);
            inputOutputCollection->addValue_largeRJet("largeRJet_phi", output_centre_phi);
            inputOutputCollection->addValue_largeRJet("largeRJet_eta", output_centre_eta);
            inputOutputCollection->addValue_largeRJet("largeRJet_sat", LRFCAL_TOB_saturated);
400

401
402
            inputOutputCollection->addValue_largeRJet("largeRJetTOB_ET", m_LRJetET/200);
            inputOutputCollection->addValue_largeRJet("largeRJetTOB_sat",LRFCAL_TOB_saturated);
403

404
405
406
            inputOutputCollection->addValue_largeRJet("largeRJetTOB_word", LRFCAL_Jet_tobword);
            inputOutputCollection->addValue_largeRJet("largeRJetTOB_jfexID", m_jfexid);
            inputOutputCollection->addValue_largeRJet("largeRJetTOB_fpgaID", m_id);
407
408

        }
409

410
411
        inputOutputCollection->fill_smallRJet();
        inputOutputCollection->fill_largeRJet();
412

413

414
415
    } //end of if statement for checking if in central jfex modules
    //******************************** TAU **********************************************
416

417
    memset(m_jTowersIDs, 0, sizeof(m_jTowersIDs[0][0]) * FEXAlgoSpaceDefs::jFEX_algoSpace_height*FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width); // Reseting m_jTowersIDs array with 0
418

419
420
    int max_meta=16;
    if(m_jfexid ==0) {
421

422
423
424
425
426
427
        for(int i=0; i<FEXAlgoSpaceDefs::jFEX_algoSpace_height; i++) {
            for(int j=28; j<(FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width-6); j++) { //lower values of j (j<28) are the Fcals not entering in the jFEX tau range
                m_jTowersIDs[i][j-28+8]=m_jTowersIDs_Wide[i][j]; // second argument in m_jTowersIDs is to center the FPGA core area in te same region as the central FPGAs
            }
        }
        max_meta++; // increase max of eta because te core module has one more TT to be considered
428
    }
429
430
431
432
433
434
435
436
437
    else if(m_jfexid ==5 ) {

        // Filling m_jTowersIDs with the m_jTowersIDs_Wide ID values up to 2.5 eta
        for(int i=0; i<FEXAlgoSpaceDefs::jFEX_algoSpace_height; i++) {
            for(int j=4; j<17; j++) { //higher values of j (j>16) are the Fcals not entering in the jFEX tau range
                m_jTowersIDs[i][j]=m_jTowersIDs_Wide[i][j];
            }
        }
        max_meta++; // increase max of eta because te core module has one more TT to be considered
438
    }
439
440
441
    else {
        //For Module 1,2,3,4 (central modules) the m_jTowersIDs array is m_jTowersIDs_Thin
        std::copy(&m_jTowersIDs_Thin[0][0], &m_jTowersIDs_Thin[0][0] + FEXAlgoSpaceDefs::jFEX_algoSpace_height*FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width, &m_jTowersIDs[0][0]);
442
    }
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
    ATH_MSG_DEBUG("============================ jFEXtauAlgo ============================");
    for(int mphi = 8; mphi < 24; mphi++) {
        for(int meta = 8; meta < max_meta; meta++) {

            int TT_seed_ID[3][3]= {{0}};
            int TT_searchWindow_ID[5][5]= {{0}};
            int TT_First_ETring[36]= {0};
            int First_ETring_it = 0;

            for(int i = -3; i< 4; i++ ) {
                for(int j = -3; j< 4; j++) {
                    int DeltaR = std::sqrt(std::pow(i,2)+std::pow(j,2));
                    if(DeltaR<3) {
                        TT_searchWindow_ID[i+2][j+2] = m_jTowersIDs[mphi +i][meta +j]; // Search window for the tau algo used for the LocalMaxima studies
                    }

                    if(DeltaR<2) {
                        TT_seed_ID[i+1][j+1] = m_jTowersIDs[mphi +i][meta +j]; // Seed 0.3x0.3 in phi-eta plane
                    }
                    else if(DeltaR<4) {
                        TT_First_ETring[First_ETring_it]= m_jTowersIDs[mphi +i][meta +j]; // First energy ring, will be used as tau ISO
                        ++First_ETring_it;

                    }
                }
            }
469

470
471
472
473
474
475
476
            ATH_CHECK( m_jFEXtauAlgoTool->safetyTest());
            m_jFEXtauAlgoTool->setFPGAEnergy(m_map_Etvalues_FPGA);
            m_jFEXtauAlgoTool->setup(TT_searchWindow_ID,TT_seed_ID);
            m_jFEXtauAlgoTool->buildSeeds();
            bool is_tau_LocalMax = m_jFEXtauAlgoTool->isSeedLocalMaxima();
            m_jFEXtauAlgoTool->setFirstEtRing(TT_First_ETring);

477
478
479
480
481
482
483
484
485
486
            inputOutputCollection->addValue_tau("tau_ET", m_jFEXtauAlgoTool->getTTowerET(m_jTowersIDs[mphi][meta]));
            inputOutputCollection->addValue_tau("tau_clusterET", m_jFEXtauAlgoTool->getClusterEt());
            inputOutputCollection->addValue_tau("tau_eta",std::abs(m_jFEXtauAlgoTool->getRealEta(m_jTowersIDs[mphi][meta]))) ;
            inputOutputCollection->addValue_tau("tau_phi",m_jFEXtauAlgoTool->getRealPhi(m_jTowersIDs[mphi][meta])) ;
            inputOutputCollection->addValue_tau("tau_realeta",m_jFEXtauAlgoTool->getRealEta(m_jTowersIDs[mphi][meta])) ;
            inputOutputCollection->addValue_tau("tau_ISO",m_jFEXtauAlgoTool->getFirstEtRing()) ;
            inputOutputCollection->addValue_tau("tau_TT_ID",TT_seed_ID[1][1]) ;
            inputOutputCollection->addValue_tau("tau_isLocalMax",is_tau_LocalMax) ;
            inputOutputCollection->addValue_tau("tau_jFEXid",m_jfexid) ;
            inputOutputCollection->addValue_tau("tau_FPGAid",m_id) ;
487
488
489
490
491

            uint32_t tobword = formTauTOB(mphi, meta);
            if ( is_tau_LocalMax ) {
                m_tau_tobwords.push_back(tobword);
            }
492

493
494
            std::unique_ptr<jFEXtauTOB> tmp_tob = m_jFEXtauAlgoTool->getTauTOBs(mphi, meta);
            // for plotting variables in TOBS- internal check:
495
496
497
498
499
500
501
502
            inputOutputCollection->addValue_tau("tau_TOB_word",tobword);
            inputOutputCollection->addValue_tau("tau_TOB_ET",tmp_tob->GetET());
            inputOutputCollection->addValue_tau("tau_TOB_eta",tmp_tob->GetEta());
            inputOutputCollection->addValue_tau("tau_TOB_phi",tmp_tob->GetPhi());
            inputOutputCollection->addValue_tau("tau_TOB_ISO",tmp_tob->GetIso());
            inputOutputCollection->addValue_tau("tau_TOB_Sat",tmp_tob->GetSat());

            inputOutputCollection->fill_tau();
503
504
505
506
507

        }
    }

    return StatusCode::SUCCESS;
508
509
510
} //end of the execute function

void jFEXFPGA::SetTowersAndCells_SG(int tmp_jTowersIDs_subset[][FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width]){
511
    
512
  const int rows = FEXAlgoSpaceDefs::jFEX_algoSpace_height;
513
514
515
  const int cols = sizeof tmp_jTowersIDs_subset[0] / sizeof tmp_jTowersIDs_subset[0][0];
  
  std::copy(&tmp_jTowersIDs_subset[0][0], &tmp_jTowersIDs_subset[0][0]+(rows*cols),&m_jTowersIDs_Wide[0][0]);
516

517
  ATH_MSG_DEBUG("\n==== jFEXFPGA ========= FPGA (" << m_id << ") [on jFEX " << m_jfexid << "] IS RESPONSIBLE FOR jTOWERS :");
518

519
  for (int thisRow=rows-1; thisRow>=0; thisRow--){
520
521
522
    for (int thisCol=0; thisCol<cols; thisCol++){
      if(thisCol != cols-1){ ATH_MSG_DEBUG("|  " << m_jTowersIDs_Wide[thisRow][thisCol] << "  "); }
      else { ATH_MSG_DEBUG("|  " << m_jTowersIDs_Wide[thisRow][thisCol] << "  |"); }
523
    }
524
  }
525
526
527
  
}

528
void jFEXFPGA::SetTowersAndCells_SG(int tmp_jTowersIDs_subset[][FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width]) {
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    const int rows = FEXAlgoSpaceDefs::jFEX_algoSpace_height;
    const int cols = sizeof tmp_jTowersIDs_subset[0] / sizeof tmp_jTowersIDs_subset[0][0];

    std::copy(&tmp_jTowersIDs_subset[0][0], &tmp_jTowersIDs_subset[0][0]+(rows*cols),&m_jTowersIDs_Thin[0][0]);

    //this prints out the jTower IDs that each FPGA is responsible for
    ATH_MSG_DEBUG("\n==== jFEXFPGA ========= FPGA (" << m_id << ") [on jFEX " << m_jfexid << "] IS RESPONSIBLE FOR jTOWERS :");

    for (int thisRow=rows-1; thisRow>=0; thisRow--) {
        for (int thisCol=0; thisCol<cols; thisCol++) {
            if(thisCol != cols-1) {
                ATH_MSG_DEBUG("|  " << m_jTowersIDs_Thin[thisRow][thisCol] << "  ");
            }
            else {
                ATH_MSG_DEBUG("|  " << m_jTowersIDs_Thin[thisRow][thisCol] << "  |");
            }
        }
547
    }
548

549
550
}

551
std::vector <uint32_t> jFEXFPGA::getSmallRJetTOBs()
552
{
553
554
555
556
557
558
    auto tobsSort = m_SRJet_tobwords;

    ATH_MSG_DEBUG("number of smallRJet tobs: " << tobsSort.size() << " in FPGA: " << m_id<< " before truncation");
    // sort tobs by their et ( 11 bits of the 32 bit tob word)
    std::sort (tobsSort.begin(), tobsSort.end(), etSRJetSort);
    tobsSort.resize(7);
559

560
    return tobsSort;
561
562
563

}

564
565
std::vector <uint32_t> jFEXFPGA::getLargeRJetTOBs()
{
Varsiha Sothilingam's avatar
Varsiha Sothilingam committed
566
  auto tobsSort = m_LRJet_tobwords;
567

568
  ATH_MSG_DEBUG("number of largeRJet tobs: " << tobsSort.size() << " in FPGA: " << m_id<< " before truncation");
569
  // sort tobs by their et ( 13 bits of the 32 bit tob word)
570
  std::sort (tobsSort.begin(), tobsSort.end(), etLRJetSort);
571
  tobsSort.resize(1);
572

573
574
  return tobsSort;
  
575
576
}

577
uint32_t jFEXFPGA::formSmallRJetTOB(int &iphi, int &ieta) {
578
579
    uint32_t tobWord = 0;
    const unsigned int jFEXETResolution = 200; //LSB is 200MeV
580
581
    unsigned int eta = 0;
    unsigned int phi = 0;
582
583
584
585
586
587
588
589
590
591
    unsigned int et = 0;
    unsigned int jFEXSmallRJetTOBEt = 0;
    int Res = 0; // 11 bits reserved
    int Sat = 0; //  1 bit for saturation. Set to 1 when jet energy is saturated

    if(m_jfexid > 0 && m_jfexid < 5) {
        et = m_jFEXSmallRJetAlgoTool->getSmallClusterET();
        eta = ieta -8;
        phi = iphi -8;
    }
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
    else if(m_jfexid == 5) {
        et = m_SRJetET;
        eta = ieta -8;
        if(ieta < FEXAlgoSpaceDefs::jFEX_algoSpace_A_EMIE_eta) { // ieta lower than EMIE stats -> belong to EMB
            phi = iphi-8;
        }
        else if(ieta < FEXAlgoSpaceDefs::jFEX_algoSpace_A_FCAL_start_eta) { // ieta lower than FCAL stats -> belong to EMIE
            phi = iphi -4;
        }
        else { // rest ieta belongs to FCAL
            phi = iphi -2;
        }
    }
    else if(m_jfexid == 0) {
        et = m_SRJetET;   
        eta = 36 - ieta;
        
        if(ieta < FEXAlgoSpaceDefs::jFEX_algoSpace_C_FCAL_end_eta) { // ieta lower than FCal ends -> FCAL
            phi = iphi -2 ;
        }
        else if(ieta < FEXAlgoSpaceDefs::jFEX_algoSpace_C_EMIE_end_eta) {// ieta lower than EMIE ends -> EMIE
            phi = iphi -4 ;
614
        }
615
616
617
        else {// rest of ieta -> EMB
            phi = iphi -8 ;
        } 
618
    }
Varsiha Sothilingam's avatar
Varsiha Sothilingam committed
619

620
621
    jFEXSmallRJetTOBEt = et/jFEXETResolution;
    if(jFEXSmallRJetTOBEt > 0x7ff) {
622
623
624
625
626
627
        jFEXSmallRJetTOBEt = 0x7ff;
        Sat = 1;
    }
    //create basic tobword with 32 bits
    tobWord = tobWord + (eta<<27) + (phi << 23) + (jFEXSmallRJetTOBEt << 12) + (Res<<1) + (Sat);
    ATH_MSG_DEBUG("tobword smallRJet with et, phi, eta, res and sat : " << std::bitset<32>(tobWord) );
628
     //Retrieve the L1 menu configuration
629
    SG::ReadHandle<TrigConf::L1Menu> l1Menu (m_l1MenuKey/*, ctx*/);
630
631
632
    const TrigConf::L1ThrExtraInfo_jJ & thr_jJ = l1Menu->thrExtraInfo().jJ();
    std::string str_jfexname = m_jfex_string[m_jfexid];
    unsigned int minEtThreshold = thr_jJ.ptMinToTopoMeV(str_jfexname)/jFEXETResolution;
633

634
635
    if (jFEXSmallRJetTOBEt < minEtThreshold) return 0;
    else return tobWord;
636
}
637

638
639
uint32_t jFEXFPGA::formLargeRJetTOB(int &iphi, int &ieta) {
    
640
641
    uint32_t tobWord = 0;
    const unsigned int jFEXETResolution = 200; //LSB is 200MeV
642
643
    unsigned int eta = 0;
    unsigned int phi = 0;
644
645
646
647
648
649
650
651
652
    unsigned int et = 0;
    unsigned int jFEXLargeRJetTOBEt = 0;
    int Res = 0; // 9 bits reserved
    int Sat = 0; //  1 bit for saturation. Set to 1 when jet energy is saturated

    if(m_jfexid > 0 && m_jfexid < 5) {
        et = m_jFEXLargeRJetAlgoTool->getLargeClusterET(m_jFEXSmallRJetAlgoTool->getSmallClusterET(),m_jFEXLargeRJetAlgoTool->getRingET());
        eta = ieta -8;
        phi = iphi -8;
653
    }
654

655
656
657
658
659
660
661
662
663
664
665
666
    else if(m_jfexid == 5) {
        et = m_LRJetET;
        eta = ieta -8;

        if(ieta < FEXAlgoSpaceDefs::jFEX_algoSpace_A_EMIE_eta) { // ieta lower than EMIE stats -> belong to EMB
            phi = iphi-8;
        }
        else if(ieta < FEXAlgoSpaceDefs::jFEX_algoSpace_A_FCAL_start_eta) { // ieta lower than FCAL stats -> belong to EMIE
            phi = iphi -4;
        }
        else { // rest ieta belongs to FCAL
            phi = iphi -2;
667
        }
668
    }
669
670
671
    else if(m_jfexid == 0) {
        et = m_LRJetET;
        eta = 36 - ieta;
672

673
674
675
676
677
678
679
680
681
        if(ieta < FEXAlgoSpaceDefs::jFEX_algoSpace_C_FCAL_end_eta) { // ieta lower than FCal ends -> FCAL
            phi = iphi -2 ;
        }
        else if(ieta < FEXAlgoSpaceDefs::jFEX_algoSpace_C_EMIE_end_eta) {// ieta lower than EMIE ends -> EMIE
            phi = iphi -4 ;
        }
        else {// rest of ieta -> EMB
            phi = iphi -8 ;
        }
682
    }
683

684

685
686
687
688
689
690
691
692
    jFEXLargeRJetTOBEt = et/jFEXETResolution;
    if (jFEXLargeRJetTOBEt > 0x1fff) {
        jFEXLargeRJetTOBEt = 0x1fff;  //0x1fff is 13 bits
        Sat = 1;
    }
    //create basic tobword with 32 bits
    tobWord = tobWord + (eta<<27) + (phi << 23) + (jFEXLargeRJetTOBEt << 10) + (Res<<1) + (Sat);
    ATH_MSG_DEBUG("tobword largeRJet with et, phi, eta, sub and sat : " << std::bitset<32>(tobWord) );
693

694
695
696
697
698
    // Retrieve the L1 menu configuration
    SG::ReadHandle<TrigConf::L1Menu> l1Menu (m_l1MenuKey/*, ctx*/);
    const TrigConf::L1ThrExtraInfo_jLJ & thr_jLJ = l1Menu->thrExtraInfo().jLJ();
    std::string str_jfexname = m_jfex_string[m_jfexid];
    unsigned int minEtThreshold = thr_jLJ.ptMinToTopoMeV(str_jfexname)/jFEXETResolution;
699

700
701
    if (jFEXLargeRJetTOBEt < minEtThreshold) return 0;
    else return tobWord;
702
703
704
}


705
706
uint32_t jFEXFPGA::formTauTOB(int & iphi, int &ieta )
{
707
708
709
710
711
712
713
714
715
716
717
718
719
    uint32_t tobWord = 0;
    const unsigned int jFEXETResolution = 200; //LSB is 200MeV

    int eta = ieta-8; // needed to substract 8 to be in the FPGA core area
    int phi = iphi-8; // needed to substract 8 to be in the FPGA core area
    int sat = 0; //1 bit for saturation flag, not coded yet

    unsigned int et = m_jFEXtauAlgoTool->getClusterEt()/jFEXETResolution;
    if (et > 0x7ff) { //0x7ff is 11 bits
        ATH_MSG_DEBUG("Et saturated: " << et );
        et = 0x7ff;
        sat=1;
    }
720

721
722
    unsigned int iso = m_jFEXtauAlgoTool->getFirstEtRing()/jFEXETResolution;
    if (iso > 0x7ff) iso = 0x7ff;  //0x7ff is 11 bits
723

724
725
    //create basic tobword with 32 bits
    tobWord = tobWord + (eta << 27) + (phi << 23) + (et << 12) + (iso << 1) + sat ;
726

727
728
729
    ATH_MSG_DEBUG("tobword tau with eta, phi, et, iso and sat : " << std::bitset<32>(tobWord) );

    // Retrieve the L1 menu configuration
730
    SG::ReadHandle<TrigConf::L1Menu> l1Menu (m_l1MenuKey/*, ctx*/);
731
732
733
    const TrigConf::L1ThrExtraInfo_jTAU & thr_jTAU = l1Menu->thrExtraInfo().jTAU();
    std::string str_jfexname = m_jfex_string[m_jfexid];
    unsigned int minEtThreshold = thr_jTAU.ptMinToTopoMeV(str_jfexname)/jFEXETResolution;
734

735
736
    if (et < minEtThreshold) return 0;
    else return tobWord;
737
738
739
740

}


741
742
std::vector <uint32_t> jFEXFPGA::getTauTOBs() {
    auto tobsSort = m_tau_tobwords;
743

744
745
746
    ATH_MSG_DEBUG("number of tau tobs: " << tobsSort.size() << " in FPGA: " << m_id<< " before truncation");
    // sort tobs by their et ( 13 bits of the 32 bit tob word)
    std::sort (tobsSort.begin(), tobsSort.end(), etTauSort);
747

748
749
    tobsSort.resize(6);
    return tobsSort;
750
751
752

}

753
754
755
756
757
758
759
std::vector <uint32_t> jFEXFPGA::getTauxTOBs()
{

  return m_tau_tobwords;

}

760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
uint32_t jFEXFPGA::formSumETTOB(int ETlow, int EThigh )
{
  uint32_t tobWord = 0;
  const unsigned int jFEXETResolution = 200; //LSB is 200MeV

  int satlow = 0;
  int sathigh = 0; 

  unsigned int etlow = ETlow/jFEXETResolution;
  if (etlow > 0x7fff) { //0x7fff is 15 bits
    ATH_MSG_DEBUG("sumEtlow saturated: " << etlow );
    etlow = 0x7fff;
    satlow=1;
  }

  unsigned int ethigh = EThigh/jFEXETResolution;
  if (ethigh > 0x7fff) { //0x7fff is 15 bits
    ATH_MSG_DEBUG("sumEthigh saturated: " << ethigh );
    ethigh = 0x7fff;
    sathigh=1;
  }

  //create basic tobword with 32 bits
  tobWord = tobWord + (etlow << 17) + (satlow << 16) + (ethigh << 1) + sathigh ;
  ATH_MSG_DEBUG("tobword SumET with ETlow, Satlow, EThigh and Sathigh : " << std::bitset<32>(tobWord) );

  return tobWord;

}

790
791
std::vector <uint32_t> jFEXFPGA::getSumEtTOBs() {
    auto tobsSort = m_sumET_tobwords;
792

793
794
    ATH_MSG_DEBUG("number of SumEt tobs: " << tobsSort.size() << " in FPGA: " << m_id);
    return tobsSort;
795

796
}
797

798
799
800
uint32_t jFEXFPGA::formMetTOB(int METX, int METY ) {
    uint32_t tobWord = 0;
    const float_t jFEXETResolution = 200.0; //LSB is 200MeV
801

802
803
    int sat = 0;
    int res = 0;
804

805
    int metX = METX/jFEXETResolution;
806

807
808
809
810
811
812
    //0x7fff is 15 bits (decimal value 32767), however as MET is a signed value (can be negative) only 14 bits are allowed (16383) the MSB is the sign
    if (std::abs(metX) > 0x3fff) {
        ATH_MSG_DEBUG("sumEtlow saturated: " << metX );
        metX = 0x7fff;
        sat=1;
    }
813

814
815
816
817
818
819
820
821
822
823
824
825
    int metY = METY/jFEXETResolution;
    if (std::abs(metY) > 0x3fff) { //0x7fff is 15 bits (decimal value 32767), however as MET is a signed value (can be negative) only 14 bits are allowed (16383)
        ATH_MSG_DEBUG("sumEthigh saturated: " << metY );
        metY = 0x7fff;
        sat=1;
    }

    //create basic tobword with 32 bits
    tobWord = tobWord + ((metX & 0x7fff) << 17) + (sat << 16) + ((metY & 0x7fff) << 1) + res ;
    ATH_MSG_DEBUG("tobword MET with MET_X, Sat, MET_Y and Res : " << std::bitset<32>(tobWord) );

    return tobWord;
826
827
828

}

829
830
std::vector <uint32_t> jFEXFPGA::getMetTOBs() {
    auto tobsSort = m_Met_tobwords;
831

832
833
    ATH_MSG_DEBUG("number of Met tobs: " << tobsSort.size() << " in FPGA: " << m_id);
    return tobsSort;
834
835

}
836
837


838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
//Returns the Electromagnetic energy for Jet Algos (NOT MET/SumET)
int jFEXFPGA::getTTowerET_EM(unsigned int TTID) {
    
    if(m_map_EM_Etvalues_FPGA.find(TTID) != m_map_EM_Etvalues_FPGA.end()){
        return m_map_EM_Etvalues_FPGA[TTID][0];
    }
    
    ATH_MSG_DEBUG("In jFEXFPGA::getTTowerET_EM, TTower ID not found in map: " << TTID );
    return -99999;
    
}


//Returns the Hadronic energy for Jet Algos (NOT MET/SumET)
int jFEXFPGA::getTTowerET_HAD(unsigned int TTID) {
    
    if(m_map_HAD_Etvalues_FPGA.find(TTID) != m_map_HAD_Etvalues_FPGA.end()){
        return m_map_HAD_Etvalues_FPGA[TTID][0];
    }
    
    ATH_MSG_DEBUG("In jFEXFPGA::getTTowerET_HAD, TTower ID not found in map: " << TTID );
    return -99999;
    
}


//Returns the Total TT energy for Jet Algos (NOT MET/SumET)
int jFEXFPGA::getTTowerET(unsigned int TTID) {

    return getTTowerET_EM(TTID)+getTTowerET_HAD(TTID);

}  


//Returns the Total TT energy for MET/SumÉT Algos
int jFEXFPGA::getTTowerET_forMET(unsigned int TTID) {

    int tmp_EM = 0;
    if(m_map_EM_Etvalues_FPGA.find(TTID) != m_map_EM_Etvalues_FPGA.end()){
        tmp_EM = m_map_EM_Etvalues_FPGA[TTID][1];
    }
    else{
        ATH_MSG_DEBUG("In jFEXFPGA::getTTowerET_forMET (EM energy), TTower ID not found in map: " << TTID );
        tmp_EM = -99999;
    }


    int tmp_HAD = 0;
    if(m_map_HAD_Etvalues_FPGA.find(TTID) != m_map_HAD_Etvalues_FPGA.end()){
        tmp_HAD = m_map_HAD_Etvalues_FPGA[TTID][1];
    }
    else{
        ATH_MSG_DEBUG("In jFEXFPGA::getTTowerET_forMET (HAD energy), TTower ID not found in map: " << TTID );
        tmp_HAD = -99999;
    }
    
    
    return tmp_EM + tmp_HAD;

}  


//Returns de ET of a given TT ID for Algorithm
int jFEXFPGA::getTTowerET_SG(unsigned int TTID) {

    SG::ReadHandle<jTowerContainer> jFEXFPGA_jTowerContainer(m_jFEXFPGA_jTowerContainerKey);
    const LVL1::jTower * tmpTower = jFEXFPGA_jTowerContainer->findTower(TTID);
    return tmpTower->getTotalET();
}





912
} // end of namespace bracket