ATLAS Offline Software
Loading...
Searching...
No Matches
TrigFastCalibWithRings.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6
9
10TrigFastCalibWithRings::TrigFastCalibWithRings([[maybe_unused]] const std::string& type, const std::string& myname, [[maybe_unused]] const IInterface* parent):asg::AsgTool(myname){}
11
12
14
16
17 ATH_CHECK(m_ringerKey.initialize());
18
19 //Setup the BDTs ...
21
22
23 return StatusCode::SUCCESS;
24}
25
27
28 return StatusCode::SUCCESS;
29}
30
31bool TrigFastCalibWithRings::checkRings(const EventContext& ctx ) const {
33 if (rgCont.isValid()){
34 ATH_MSG_DEBUG("No valid Ringer Container");
35 return false;
36 }
37 const xAOD::TrigRingerRings_v2 *ring=rgCont->at(0);
38 if(!ring->emCluster()){
39 ATH_MSG_DEBUG("There is no link to emCluster.");
40 return false;
41 }
42
43 return true;
44
45}
46
47
48StatusCode TrigFastCalibWithRings::setupBDTFastCalo(const std::string& fileName){
49
50
51
52 std::unique_ptr<TFile> f(TFile::Open(fileName.c_str()));
53 if (!f || f->IsZombie()) {
54 ATH_MSG_FATAL("Could not open " << fileName);
55 return StatusCode::FAILURE;
56 }
57
58 // Load hPoly
59 TH2Poly *hPoly = nullptr;
60 f->GetObject("hPoly", hPoly);
61 if (!hPoly) {
62 ATH_MSG_FATAL("Could not find hPoly");
63 return StatusCode::FAILURE;
64 }
65 //pass ownership to class variable
66 m_hPoly.reset(static_cast<TH2Poly*>(hPoly));
67 m_hPoly->SetDirectory(nullptr);
68
69 // Load variables
70 TObjArray *variablesTmp = nullptr;
71 f->GetObject("variables", variablesTmp);
72 if (!variablesTmp) {
73 ATH_MSG_FATAL("Could not find variables");
74 return StatusCode::FAILURE;
75 }
76 auto variables = std::unique_ptr<TObjArray>(variablesTmp);
77 variables->SetOwner(); // to delete the objects when d-tor is called
78
79 // Load shifts
80 TObjArray *shiftsTmp = nullptr;
81 f->GetObject("shifts", shiftsTmp);
82 if (!shiftsTmp) {
83 ATH_MSG_FATAL("Could not find shifts");
84 return StatusCode::FAILURE;
85 }
86 auto shifts = std::unique_ptr<TObjArray>(shiftsTmp);
87 shifts->SetOwner(); // to delete the objects when d-tor is called
88
89 // Load trees
90 TObjArray *treesTmp = nullptr;
91 //std::unique_ptr<TObjArray> trees;
92 TObjArray *trees = nullptr;
93 f->GetObject("trees", treesTmp);
94 if (treesTmp) {
95 trees = treesTmp;
96 trees->SetOwner(); // to delete the objects when d-tor is called
97 ATH_MSG_DEBUG("setupBDT " << "BDTs read from TObjArray");
98 } else {
99 ATH_MSG_DEBUG("setupBDT " << "Reading trees individually");
100 trees = new TObjArray();
101 trees->SetOwner(); // to delete the objects when d-tor is called
102 for (int i = 0; i < variables->GetEntries(); ++i)
103 {
104 TTree *tree = nullptr;
105 f->GetObject(Form("BDT%d", i), tree);
106 if (tree) tree->SetCacheSize(0);
107 trees->AddAtAndExpand(tree, i);
108 }
109 }
110
111 // Ensure the objects have (the same number of) entries
112 if (!trees->GetEntries() || !(trees->GetEntries() == variables->GetEntries())) {
113 ATH_MSG_FATAL("Tree has size " << trees->GetEntries()
114 << " while variables has size " << variables->GetEntries());
115 return StatusCode::FAILURE;
116 }
117
118 // Loop simultaneously over trees, variables and shifts
119 // Define the BDTs, the list of variables and the shift for each BDT
120 TObjString *str2;
121
122 TTree *tree;
123 TIter nextTree(trees);
124 TIter nextVariables(variables.get());
125 TIter nextShift(shifts.get());
126 for (int i=0; (tree = (TTree*) nextTree()) && ((TObjString*) nextVariables()); ++i)
127 {
128 m_BDTs.emplace_back(tree);
129
130 std::vector<std::function<float(const xAOD::Egamma*, const xAOD::CaloCluster*)> > funcs;
131 // Loop over variables, which are separated by comma
132 char separator_var = ';';
133 if (getString(variables->At(i)).Index(";") < 1) separator_var = ','; // old versions
134 std::unique_ptr<TObjArray> tokens(getString(variables->At(i)).Tokenize(separator_var));
135 TIter nextVar(tokens.get());
136 while ((str2 = (TObjString*) nextVar()))
137 {
138 const TString& varName = getString(str2);
139 if (!varName.Length()) {
140 ATH_MSG_FATAL("There was an empty variable name!");
141 return StatusCode::FAILURE;
142 }
143 }
144 }
145return StatusCode::SUCCESS;
146}
147
148
149const TString& TrigFastCalibWithRings::getString(TObject* obj)
150{
151 TObjString *objS = dynamic_cast<TObjString*>(obj);
152 if (!objS) {
153 throw std::runtime_error("egammaMVACalibTool::getString was passed something that was not a string object");
154 }
155 return objS->GetString();
156}
157
158
159
160float TrigFastCalibWithRings::makeCalibWRings(const EventContext& ctx) const {
162 const xAOD::TrigRingerRings_v2 *ring=rgCont->at(0);
163
164
165 //Open the EventContext and create a BDT input vector: Rings + Et + eta
166 float eta_cluster=ring->emCluster()->eta();
167 float et_cluster=ring->emCluster()->et();
168 const static std::vector<float>rings=rgCont->at(0)->rings();
169
170 //Define the Rings to be used as inputs
171 const std::vector<int>inputRingsIndex{0,1,2,3,8,9,10,11,12,13,14,15,72,73,74,75,76,77,78,79,81,82,83,84,88,89,90,91};
172
173 if (!(static_cast<int>(ring ->size()) > inputRingsIndex.back())){
174 throw std::runtime_error("The last ring index is bigger than the ring's lenght");
175 }
176
177 std::vector<float>ringsInput;
178 for(auto index:inputRingsIndex)ringsInput.push_back(rings[index]);
179
180 const TH2Poly* hPoly = m_hPoly.get();
181 const int bin = hPoly->FindFixBin(eta_cluster, et_cluster/Gaudi::Units::GeV) - 1; // poly bins are shifted by one
182
183 ATH_MSG_DEBUG("Using bin: " << bin);
184
185 if (bin < 0) {
186 ATH_MSG_DEBUG("The bin is under/overflow; just return the energy");
187 return et_cluster;
188 }
189
190 if (bin >= static_cast<int>(m_BDTs.size())) {
191 ATH_MSG_WARNING("The bin is outside the range, so just return the energy");
192 return et_cluster;
193 }
194
195 // select the bdt and functions. (shifts are done later if needed)
196 // if there is only one BDT just use that
197 const int bin_BDT = m_BDTs.size() != 1 ? bin : 0;
198 const auto& bdt = m_BDTs[bin_BDT];
199
200 // evaluate the BDT response
201 const float mvaOutput = bdt.GetResponse(ringsInput);
202
203
204
205 return et_cluster*mvaOutput;
206}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
macros for messaging and checking status codes
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
virtual bool isValid() override final
Can the handle be successfully dereferenced?
static const TString & getString(TObject *obj)
float makeCalibWRings(const EventContext &ctx) const
bool checkRings(const EventContext &ctx) const
StatusCode initialize() final
Dummy implementation of the initialisation function.
std::vector< MVAUtils::BDT > m_BDTs
Where the BDTs are stored.
std::unique_ptr< TH2Poly > m_hPoly
A TH2Poly used to extract bin numbers. Note there is an offset of 1.
TrigFastCalibWithRings(const std::string &type, const std::string &myname, const IInterface *parent)
SG::ReadHandleKey< xAOD::TrigRingerRingsContainer > m_ringerKey
Gaudi::Property< std::string > m_CalibPath
StatusCode setupBDTFastCalo(const std::string &fileName)
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
float et() const
get Et (calibrated)
float eta() const
get Eta (calibrated)
const TrigEMCluster * emCluster() const
The associated EM cluster, as a simple pointer.
Definition index.py:1
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
TChain * tree