ATLAS Offline Software
Loading...
Searching...
No Matches
JGTowerNoiseAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "JGTowerNoiseAlg.h"
8#include "TFile.h"
9#include "TH1F.h"
10#include <memory>
11#include "GaudiKernel/SystemOfUnits.h"
12#include <algorithm>
13
14namespace
15{
16 const static SG::AuxElement::Decorator<float> decNoise("noise");
17}
18
19namespace LVL1
20{
21 JGTowerNoiseAlg::JGTowerNoiseAlg(const std::string &name, ISvcLocator *pSvcLocator)
22 : AthReentrantAlgorithm(name, pSvcLocator)
23 {
24 declareProperty("InputTowers", m_inputKey);
25 declareProperty("NoiseFile", m_noiseFile = "Run3L1CaloSimulation/Noise/jTowergTowerNoise.20210209.r11881.root");
26 declareProperty("DoJFEX", m_doJFex = false, "If true, use jFEX noise values, otherwise use gFEX");
27 declareProperty("DefaultNoise", m_defaultNoise = 1 * Gaudi::Units::GeV, "Default noise value to use if no file provided");
28 }
29
31
33 {
34 ATH_CHECK(m_inputKey.initialize());
35
36 if (m_noiseFile.empty())
37 {
38 ATH_MSG_WARNING("No noise file found. Will set all noises to " << m_defaultNoise);
39 return StatusCode::SUCCESS;
40 }
41 std::unique_ptr<TFile> noiseFile(TFile::Open(PathResolver::find_calib_file(m_noiseFile).c_str()));
42 if (m_doJFex)
43 {
44 m_etaBins = {0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.1, 2.2, 2.3, 2.4, 2.5, 2.7, 2.9, 3.1};
45 TProfile *noiseProfileEM = dynamic_cast<TProfile *>(noiseFile->Get("jTowerNoise/pr_eta_EM"));
46 TProfile *noiseProfileHAD = dynamic_cast<TProfile *>(noiseFile->Get("jTowerNoise/pr_eta_HAD"));
47 TProfile *noiseProfileFCAL = dynamic_cast<TProfile *>(noiseFile->Get("jTowerNoise/pr_eta_FCAL"));
48 if (!noiseProfileEM || !noiseProfileHAD || !noiseProfileFCAL)
49 {
50 ATH_MSG_ERROR("Failed to load noise values from input file!");
51 return StatusCode::FAILURE;
52 }
53 if (m_etaBins.size() != static_cast<std::size_t>(noiseProfileEM->GetNbinsX()) + 1)
54 {
55 ATH_MSG_ERROR("Number of EM profile eta bins '" << noiseProfileEM->GetNbinsX() << "' does not match expected value '" << m_etaBins.size() - 1 << "'!");
56 return StatusCode::FAILURE;
57 }
58 if (m_etaBins.size() != static_cast<std::size_t>(noiseProfileHAD->GetNbinsX()) + 1)
59 {
60 ATH_MSG_ERROR("Number of HAD profile eta bins '" << noiseProfileHAD->GetNbinsX() << "' does not match expected value '" << m_etaBins.size() - 1 << "'!");
61 return StatusCode::FAILURE;
62 }
63
64 // Load the noise values. Start off assigning the default value to all bins (including overflows)
65 m_noiseValuesEM.assign(m_defaultNoise, m_etaBins.size() + 1);
66 m_noiseValuesHAD.assign(m_defaultNoise, m_etaBins.size() + 1);
67 for (std::size_t idx = 1; idx < m_etaBins.size(); ++idx)
68 {
69 m_noiseValuesEM.at(idx) = noiseProfileEM->GetBinError(idx);
70 m_noiseValuesHAD.at(idx) = noiseProfileHAD->GetBinError(idx);
71 }
72
73 for (std::size_t idx = 1; idx < static_cast<std::size_t>(noiseProfileFCAL->GetNbinsX() + 1); ++idx)
74 {
75 std::string label = noiseProfileFCAL->GetXaxis()->GetBinLabel(idx);
76 // There are empty bins which have an empty label
77 if (label.empty())
78 continue;
79 if (label.substr(0, 4) != "ieta")
80 {
81 ATH_MSG_ERROR("Bin label '" << label << "'is not in the expected format");
82 return StatusCode::FAILURE;
83 }
84 std::size_t towerIdx = static_cast<std::size_t>(std::atoi(label.substr(4).c_str()));
85 m_noiseValuesFCAL[towerIdx] = noiseProfileFCAL->GetBinError(idx);
86 }
87 }
88 else
89 {
90 m_etaBins = {0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.5, 2.7, 2.9, 3.1, 3.5, 4.0, 4.45, 4.9};
91 TProfile *noiseProfile = dynamic_cast<TProfile *>(noiseFile->Get("gTowerNoise/pr_eta"));
92 if (!noiseProfile)
93 {
94 ATH_MSG_ERROR("Failed to load noise values from input file!");
95 return StatusCode::FAILURE;
96 }
97 if (m_etaBins.size() != static_cast<std::size_t>(noiseProfile->GetNbinsX()) + 1)
98 {
99 ATH_MSG_ERROR("Number of profile eta bins '" << noiseProfile->GetNbinsX() << "' does not match expected value '" << m_etaBins.size() - 1 << "'!");
100 return StatusCode::FAILURE;
101 }
102 // Load the noise values. Start off assigning the default value to all bins (including overflows)
103 m_noiseValues.assign(m_defaultNoise, m_etaBins.size() + 1);
104 for (std::size_t idx = 1; idx < m_etaBins.size(); ++idx)
105 m_noiseValues.at(idx) = noiseProfile->GetBinError(idx);
106 }
107 return StatusCode::SUCCESS;
108 }
109
110 StatusCode JGTowerNoiseAlg::execute(const EventContext& ctx) const
111 {
112 auto inputTowers = SG::makeHandle(m_inputKey, ctx);
113 if (!inputTowers.isValid())
114 {
115 ATH_MSG_ERROR("Could not retrieve input towers " << m_inputKey.key());
116 return StatusCode::FAILURE;
117 }
118 for (const xAOD::JGTower *iTower : *inputTowers)
119 {
120 float absEta = std::abs(iTower->eta());
121 if (m_doJFex)
122 {
123 if (absEta > m_etaBins.back())
124 {
125 float noise = m_noiseValuesFCAL.at(iTower->index());
126 decNoise(*iTower) = noise > 0 ? noise : m_defaultNoise;
127 }
128 else
129 {
130 // Use the eta-binned histograms
131 // std::upper_bound returns an iterator to the first element larger than the provided value
132 // This means that it maps onto ROOT binning exactly: if the value is smaller than the lowest bin edge
133 // (underflow) it returns 0, right on up to if it's larger than the largest bin edge where it returns the size of the edge vector
134 // which is the overflow bin
135 std::size_t iEta = std::distance(m_etaBins.begin(), std::upper_bound(m_etaBins.begin(), m_etaBins.end(), absEta));
136 if (iEta == 0 || iEta == m_etaBins.size())
137 ATH_MSG_WARNING("Eta value " << absEta << " falls in the under/overflow?");
138 if (iTower->sampling() == 0)
139 decNoise(*iTower) = m_noiseValuesEM.at(iEta);
140 else
141 decNoise(*iTower) = m_noiseValuesHAD.at(iEta);
142 }
143 }
144 else
145 {
146 // std::upper_bound returns an iterator to the first element larger than the provided value
147 // This means that it maps onto ROOT binning exactly: if the value is smaller than the lowest bin edge
148 // (underflow) it returns 0, right on up to if it's larger than the largest bin edge where it returns the size of the edge vector
149 // which is the overflow bin
150 std::size_t iEta = std::distance(m_etaBins.begin(), std::upper_bound(m_etaBins.begin(), m_etaBins.end(), absEta));
151 if (iEta == 0 || iEta == m_etaBins.size())
152 ATH_MSG_WARNING("Eta value " << absEta << " falls in the under/overflow?");
153 decNoise(*iTower) = m_noiseValues.at(iEta);
154 }
155 }
156 return StatusCode::SUCCESS;
157 }
158} // namespace LVL1
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
Handle class for reading from StoreGate.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
An algorithm that can be simultaneously executed in multiple threads.
std::vector< float > m_noiseValues
SG::ReadHandleKey< xAOD::JGTowerContainer > m_inputKey
virtual ~JGTowerNoiseAlg() override
std::vector< float > m_noiseValuesEM
virtual StatusCode initialize() override
virtual StatusCode execute(const EventContext &ctx) const override
std::vector< float > m_noiseValuesHAD
std::map< std::size_t, float > m_noiseValuesFCAL
JGTowerNoiseAlg(const std::string &name, ISvcLocator *pSvcLocator)
std::vector< float > m_etaBins
static std::string find_calib_file(const std::string &logical_file_name)
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
std::string label(const std::string &format, int i)
Definition label.h:19
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
JGTower_v1 JGTower
Define the latest version of the JGTower class.
Definition JGTower.h:15