ATLAS Offline Software
Loading...
Searching...
No Matches
jFEXPileupAndNoise.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4//***************************************************************************
5// jFEXPileupAndNoise - Algorithm for Pileup and Noise in jFEX
6// -------------------
7// begin : 24 05 2021
8// email : Sergi.Rodriguez@cern.ch
9//***************************************************************************
10#include <vector>
11#include <stdio.h>
12#include <math.h>
13#include "L1CaloFEXSim/jTower.h"
15#include "jFEXPileupAndNoise.h"
17
18namespace LVL1{
19
20//Default Constructor
21LVL1::jFEXPileupAndNoise::jFEXPileupAndNoise(const std::string& type, const std::string& name, const IInterface* parent): AthAlgTool(type, name, parent) {
22 declareInterface<IjFEXPileupAndNoise>(this);
23}
24
28
30
31 ATH_CHECK(m_jTowerContainerKey.initialize());
32 ATH_CHECK( m_BDToolKey.initialize() );
33
34
35 return StatusCode::SUCCESS;
36}
37
38//calls container for TT
40
42 if(! m_jTowerContainer.isValid()) {
43 ATH_MSG_ERROR("Could not retrieve jTowerContainer " << m_jTowerContainerKey.key());
44 return StatusCode::FAILURE;
45 }
46
47 return StatusCode::SUCCESS;
48}
49
51
52 m_is_FWD=0;
57
59
60 return StatusCode::SUCCESS;
61}
62
64
65 m_rho_EM = 0;
66 m_rho_HAD1 = 0;
67 m_rho_HAD2 = 0;
68 m_rho_HAD3 = 0;
69 m_rho_FCAL = 0;
70
76
77}
78
79
80//Setup for the central region, duplicate fuction
88
89
90//Setup for the forward region, duplicate fuction
98
99
101
103
105 if(! myDBTool.isValid()) {
106 ATH_MSG_ERROR("Could not retrieve DB tool " << m_BDToolKey);
107 }
108
109 for(int iphi=0;iphi<FEXAlgoSpaceDefs::jFEX_algoSpace_height;iphi++){
110 for(int ieta=0;ieta<m_etaMAX;ieta++){
111
112 int TTID = 0;
113
114 if(m_is_FWD){
115 TTID = m_FPGA_forward[iphi][ieta];
116 }
117 else{
118 TTID = m_FPGA_central[iphi][ieta];
119 }
120
121 if(TTID == 0){
122 continue; //skipping TTID iqual to 0
123 }
124
125 const LVL1::jTower *tmpTower = m_jTowerContainer->findTower(TTID);
126
127 int tmp_eta = getTTowerEta(tmpTower);
128 // energies used below are in MeV, but to reproduce firmware behavior we need to truncate at the same position,
129 // i.e., temporarily go back to the granularity used in firmware!
130 int em_granularity = 25;
131 int had_granularity = tmp_eta < 15 ? 500 : 25; //For Tile inputs granularity is 500MeV, for LAr 25MeV
132 //storing the energies
133 int tmp_energy_EM = getET_EM(tmpTower)/em_granularity;
134 int tmp_energy_HAD = getET_HAD(tmpTower)/had_granularity;
135 int tmp_EM_AreaINV = getTTAreaINV_EM(tmpTower);
136 int tmp_HD_AreaINV = getTTAreaINV_HAD(tmpTower);
137 m_FPGA_ET_EM[TTID] = getET_EM(tmpTower);
138 m_FPGA_ET_HAD[TTID] = getET_HAD(tmpTower);
139
140 tmp_energy_EM = (tmp_energy_EM * tmp_EM_AreaINV)/(1<<FEXAlgoSpaceDefs::pu_AreaINV);
141 tmp_energy_HAD= (tmp_energy_HAD* tmp_HD_AreaINV)/(1<<FEXAlgoSpaceDefs::pu_AreaINV);
142
143 //calculating rho's
144
145 // EM layer ( not EM FCAL!! )
146
147 if(tmp_eta < 32 ){
148 if(tmp_energy_EM > myDBTool->get_PUThrLowEm() and tmp_energy_EM < myDBTool->get_PUThrHighEm()) {
149 m_rho_EM += tmp_energy_EM;
151 }
152 }
153
154 // Tile layer
155 if(tmp_eta < 15){
156 if(tmp_energy_HAD > myDBTool->get_PUThrLowHadTrex() and tmp_energy_HAD < myDBTool->get_PUThrHighHadTrex()){
157 m_rho_HAD1 += tmp_energy_HAD;
159 }
160 }
161 // HEC Overlap layer!
162 else if(tmp_eta < 16 ){
163 if(tmp_energy_HAD > myDBTool->get_PUThrLowHadHecOverlap() and tmp_energy_HAD < myDBTool->get_PUThrHighHadHecOverlap()){
164 m_rho_HAD2 += tmp_energy_HAD;
166 }
167 }
168 // Rest of HEC without overlap
169 else if(tmp_eta < 32 ){
170 if(tmp_energy_HAD > myDBTool->get_PUThrLowHadLar() and tmp_energy_HAD < myDBTool->get_PUThrHighHadLar()){
171 m_rho_HAD3 += tmp_energy_HAD;
173 }
174 }
175 // FCAL is treated here!
176 else if(tmp_eta >= 32){
177
178 // Contributes the HAD layer (FCAL2 and FCAL3)
180 if(tmp_energy_HAD > myDBTool->get_PUThrLowFcal() and tmp_energy_HAD < myDBTool->get_PUThrHighFcal()){
181 m_rho_FCAL += tmp_energy_HAD;
183 }
184 }
185 // FCAL1 is EM layer so the energy is suposed to be in the EM layer
186 else{
187 if(tmp_energy_EM > myDBTool->get_PUThrLowFcal() and tmp_energy_EM < myDBTool->get_PUThrHighFcal()){
188 m_rho_FCAL += tmp_energy_EM;
190 }
191 }
192 }
193 }
194 }//end of iphi loop
195
196 //calculating rho values for each region
202
203 //return values in MeV -> m_rho_HAD1 corresponds to TileCal, so 500MeV/count, rest is 25MeV/count
204 //note: do not convert the internal values yet, this needs to happen after the PU correction is applied
205 // to fully reproduce FW behavior!
206 std::vector<int> rho_values {m_rho_EM*25,m_rho_HAD1*500,m_rho_HAD2*25,m_rho_HAD3*25,m_rho_FCAL*25};
207
209
210 return rho_values;
211}
212
214
215 //This is to save one bit in the firmware (19 bit will set be set to 1 instead of the 20th bit and rest are 0)
216 if(ntowers == 1) return ((1<<FEXAlgoSpaceDefs::pu_rhoLUT) - 1);
217 return static_cast<int>((1.0/ntowers)*(1<<FEXAlgoSpaceDefs::pu_rhoLUT) );
218}
219
221
222 for(int iphi=0; iphi<FEXAlgoSpaceDefs::jFEX_algoSpace_height; iphi++) {
223 for(int ieta=0; ieta<m_etaMAX; ieta++) {
224
225 int TTID = 0;
226
227 if(m_is_FWD) {
228 TTID = m_FPGA_forward[iphi][ieta];
229 }
230 else {
231 TTID = m_FPGA_central[iphi][ieta];
232 }
233
234 if(TTID == 0) continue; //skipping TTID iqual to 0
235
236 const LVL1::jTower *tmpTower = m_jTowerContainer->findTower(TTID);
237 int tmp_eta = getTTowerEta(tmpTower);
238 int tmp_EM_Area = getTTArea_EM(tmpTower);
239 int tmp_HD_Area = getTTArea_HAD(tmpTower);
240
241 if(tmp_eta < 32) {
242 m_FPGA_ET_EM[TTID] =m_FPGA_ET_EM[TTID] - ((m_rho_EM * tmp_EM_Area)/(1<<FEXAlgoSpaceDefs::pu_Area)) * 25; //factor 25: jFEX internal counts -> MeV (LAr)
243 }
244
245 if(tmp_eta < 15) {
246 m_FPGA_ET_HAD[TTID]=m_FPGA_ET_HAD[TTID] - ((m_rho_HAD1 * tmp_HD_Area)/(1<<FEXAlgoSpaceDefs::pu_Area)) * 500; //factor 500: jFEX internal counts -> MeV (Tile)
247 }
248 else if(tmp_eta < 16 ) {
249 m_FPGA_ET_HAD[TTID]=m_FPGA_ET_HAD[TTID] - ((m_rho_HAD2 * tmp_HD_Area)/(1<<FEXAlgoSpaceDefs::pu_Area)) * 25; //factor 25: jFEX internal counts -> MeV (LAr)
250 }
251 else if(tmp_eta < 32 ) {
252 m_FPGA_ET_HAD[TTID]=m_FPGA_ET_HAD[TTID] - ((m_rho_HAD3 * tmp_HD_Area)/(1<<FEXAlgoSpaceDefs::pu_Area)) * 25; //factor 25: jFEX internal counts -> MeV (LAr)
253 }
254 else if(tmp_eta >= 32) {
255 // Contributes the HAD layer (FCAL2 and FCAL3)
257 m_FPGA_ET_HAD[TTID] = m_FPGA_ET_HAD[TTID] - ((m_rho_FCAL * (tmp_HD_Area))/(1<<FEXAlgoSpaceDefs::pu_Area)) * 25; //factor 25: jFEX internal counts -> MeV (LAr)
258 }
259 // FCAL1 is EM layer so the energy is suposed to be in the EM layer
260 else{
261 m_FPGA_ET_EM[TTID] = m_FPGA_ET_EM[TTID] - ((m_rho_FCAL * (tmp_EM_Area))/(1<<FEXAlgoSpaceDefs::pu_Area)) * 25; //factor 25: jFEX internal counts -> MeV (LAr)
262 }
263 }
264 }
265 }
266}
267
268
269//Flags that allow to apply the pileup/noise to the objets
272 if(! myDBTool.isValid()) {
273 ATH_MSG_ERROR("Could not retrieve DB tool " << m_BDToolKey);
274 return StatusCode::FAILURE;
275 }
276
277 m_apply_pileup2jets = myDBTool->get_doPileUpJet();
278 m_apply_pileup2met = myDBTool->get_doPileUpMet();
279
280 return StatusCode::SUCCESS;
281}
282
286
290
291
292
293std::unordered_map<int,std::vector<int> > LVL1::jFEXPileupAndNoise::Get_EM_Et_values(){
294
295 // map for energies sent to the FPGA
296 m_map_Etvalues_EM.clear();
297
298
299 for(int iphi=0; iphi<FEXAlgoSpaceDefs::jFEX_algoSpace_height; iphi++) {
300 for(int ieta=0; ieta<m_etaMAX; ieta++) {
301
302 int TTID = 0;
303
304 if(m_is_FWD) {
305 TTID = m_FPGA_forward[iphi][ieta];
306 }
307 else {
308 TTID = m_FPGA_central[iphi][ieta];
309 }
310
311 if(TTID == 0) continue; //skipping TTID iqual to 0
312 const LVL1::jTower *tmpTower = m_jTowerContainer->findTower(TTID);
313
314 // tmp variable to fill the map
315 std::vector<int> v_energies;
316 v_energies.clear();
317 v_energies.resize(2,0);
318
319 //saving the SG energy
320 int tmp_TotalEt_jet=getET_EM(tmpTower);
321 int tmp_TotalEt_met=getET_EM(tmpTower);
322
323 // if true changing the raw energy to the pileup subtracted energy for jets
325 tmp_TotalEt_jet = m_FPGA_ET_EM[TTID];
326 }
327
328 // if true changing the raw energy to the pileup subtracted energy for met
330 tmp_TotalEt_met = m_FPGA_ET_EM[TTID];
331 }
332
333 v_energies[0]=tmp_TotalEt_jet;
334 v_energies[1]=tmp_TotalEt_met;
335
336 m_map_Etvalues_EM.insert(std::make_pair(TTID, v_energies));
337 }
338 }
339
341
342 return m_map_Etvalues_EM;
343}
344
345std::unordered_map<int,std::vector<int> > LVL1::jFEXPileupAndNoise::Get_HAD_Et_values(){
346
347 // map for energies sent to the FPGA
348 m_map_Etvalues_HAD.clear();
349
350
351 for(int iphi=0; iphi<FEXAlgoSpaceDefs::jFEX_algoSpace_height; iphi++) {
352 for(int ieta=0; ieta<m_etaMAX; ieta++) {
353
354 int TTID = 0;
355
356 if(m_is_FWD) {
357 TTID = m_FPGA_forward[iphi][ieta];
358 }
359 else {
360 TTID = m_FPGA_central[iphi][ieta];
361 }
362
363 if(TTID == 0) continue; //skipping TTID iqual to 0
364 const LVL1::jTower *tmpTower = m_jTowerContainer->findTower(TTID);
365
366 // tmp variable to fill the map
367 std::vector<int> v_energies;
368 v_energies.clear();
369 v_energies.resize(2,0);
370
371 //saving the SG energy
372 int tmp_TotalEt_jet=getET_HAD(tmpTower);
373 int tmp_TotalEt_met=getET_HAD(tmpTower);
374
375 // if true changing the raw energy to the pileup subtracted energy for jets
377 tmp_TotalEt_jet = m_FPGA_ET_HAD[TTID];
378 }
379
380 // if true changing the raw energy to the pileup subtracted energy for met
382 tmp_TotalEt_met = m_FPGA_ET_HAD[TTID];
383 }
384
385 v_energies[0]=tmp_TotalEt_jet;
386 v_energies[1]=tmp_TotalEt_met;
387
388 m_map_Etvalues_HAD.insert(std::make_pair(TTID, v_energies));
389 }
390 }
391
393
394 return m_map_Etvalues_HAD;
395}
396
397void LVL1::jFEXPileupAndNoise::ApplyNoiseCuts(std::unordered_map<int,std::vector<int> > & map_Etvalues,int layer ){
398
399 const LVL1::jTower *tmpTower;
400
401 for(auto [key,vec] : map_Etvalues){
402
403 tmpTower = m_jTowerContainer->findTower(key);
404 int Jet_NoiseCut = tmpTower->getNoiseForJet(layer);
405 int Met_NoiseCut = tmpTower->getNoiseForMet(layer);
406
407 if(m_apply_noise2jets && map_Etvalues[key][0]<=Jet_NoiseCut){ // Et for jets
408 map_Etvalues[key][0]=0.;
409 }
410 if(m_apply_noise2met && map_Etvalues[key][1]<=Met_NoiseCut){ // Et for Met
411 map_Etvalues[key][1]=0.;
412 }
413
414 }
415
416}
417
418std::unordered_map<int,std::vector<int> > LVL1::jFEXPileupAndNoise::GetEt_values(){
419
420 // map for energies sent to the FPGA
421 std::unordered_map<int,std::vector<int> > map_Etvalues;
422 map_Etvalues.clear();
423
424
425 /*
426 * The vector Et_energy has size 2
427 * Et_energy[0] is used un the Jet algos
428 * Et_energy[1] is used un the Met/SumEt algos
429 */
430 std::vector<int> Et_energy;
431
432 for(auto [key,vec] : m_map_Etvalues_EM){
433
434 Et_energy.clear();
435 Et_energy.resize(2,0);
436
437 Et_energy[0]=m_map_Etvalues_EM[key][0]+m_map_Etvalues_HAD[key][0];
438 Et_energy[1]=m_map_Etvalues_EM[key][1]+m_map_Etvalues_HAD[key][1];
439 map_Etvalues[key] = Et_energy;
440 }
441 return map_Etvalues;
442}
443
444
445//Gets Eta of the TT
447 return tmpTower->iEta() < 0 ? std::abs(tmpTower->iEta()+1) : tmpTower->iEta() ;
448}
449//Gets ET of the TT
451 return tmpTower->getTotalET();
452}
453//Gets EM ET of the TT
455 return tmpTower->getET_EM();
456}
457//Gets HAD ET of the TT
459 return tmpTower->getET_HAD();
460}
461
462//Get Area of a EM TT
464 return tmpTower->getTTowerArea(0);
465}
466
467//Get Area of a HAD TT
469 return tmpTower->getTTowerArea(1);
470}
471
472//Get Area of a EM TT
474 return tmpTower->getTTowerAreaInv(0);
475}
476
477//Get Area of a HAD TT
479 return tmpTower->getTTowerAreaInv(1);
480}
481
482
483}// end of namespace LVL1
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
std::vector< size_t > vec
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
static constexpr int jFEX_wide_algoSpace_width
static constexpr unsigned int pu_AreaINV
static constexpr unsigned int pu_Area
static constexpr unsigned int pu_rhoLUT
static constexpr int jFEX_FCAL2_start
static constexpr int jFEX_thin_algoSpace_width
static constexpr int jFEX_algoSpace_height
std::unordered_map< int, int > m_FPGA_ET_EM
int m_FPGA_central[FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width]
virtual std::unordered_map< int, std::vector< int > > Get_HAD_Et_values() override
std::unordered_map< int, int > m_FPGA_ET_HAD
virtual StatusCode safetyTest() override
SG::ReadCondHandleKey< jFEXDBCondData > m_BDToolKey
jFEXPileupAndNoise(const std::string &type, const std::string &name, const IInterface *parent)
Constructors.
int getET_HAD(const LVL1::jTower *tmpTower)
int getTTowerEta(const LVL1::jTower *tmpTower)
std::unordered_map< int, std::vector< int > > m_map_Etvalues_EM
int getTTArea_HAD(const LVL1::jTower *tmpTower)
virtual void ApplyNoise2Met(bool b) override
virtual void setup(int FPGA[FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_thin_algoSpace_width]) override
int getTTAreaINV_EM(const LVL1::jTower *tmpTower)
int getET_EM(const LVL1::jTower *tmpTower)
SG::ReadHandle< jTowerContainer > m_jTowerContainer
virtual StatusCode initialize() override
standard Athena-Algorithm method
virtual StatusCode reset() override
int getTTAreaINV_HAD(const LVL1::jTower *tmpTower)
int m_FPGA_forward[FEXAlgoSpaceDefs::jFEX_algoSpace_height][FEXAlgoSpaceDefs::jFEX_wide_algoSpace_width]
virtual std::unordered_map< int, std::vector< int > > GetEt_values() override
virtual ~jFEXPileupAndNoise()
Destructor.
void ApplyNoiseCuts(std::unordered_map< int, std::vector< int > > &map_Etvalues, int layer)
virtual StatusCode ApplyPileup() override
SG::ReadHandleKey< LVL1::jTowerContainer > m_jTowerContainerKey
int getTTowerET(const LVL1::jTower *tmpTower)
virtual std::vector< int > CalculatePileup() override
virtual std::unordered_map< int, std::vector< int > > Get_EM_Et_values() override
virtual void ApplyNoise2Jets(bool b) override
int getTTArea_EM(const LVL1::jTower *tmpTower)
std::unordered_map< int, std::vector< int > > m_map_Etvalues_HAD
The jTower class is an interface object for jFEX trigger algorithms The purposes are twofold:
Definition jTower.h:36
int getTotalET() const
Get ET sum of all cells in the jTower in MeV.
Definition jTower.cxx:198
int getET_EM() const
Get EM ET value in MeV.
Definition jTower.h:131
int iEta() const
Get coordinates of tower.
Definition jTower.cxx:166
int getNoiseForJet(int layer) const
Definition jTower.cxx:347
int getTTowerArea(int layer) const
Definition jTower.cxx:321
int getTTowerAreaInv(int layer) const
Definition jTower.cxx:329
int getNoiseForMet(int layer) const
Definition jTower.cxx:338
int getET_HAD() const
Get HAD ET value in MeV.
Definition jTower.h:134
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...