ATLAS Offline Software
Loading...
Searching...
No Matches
ClassifyAndCalculateHFTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// ClassifyAndCalculateHFTool.cxx //
8// Implementation file for class ClassifyAndCalculateHFTool //
9// Author: Adrian Berrocal Guardia <adrian.berrocal.guardia@cern.ch> //
10// //
12
16
17namespace DerivationFramework {
18
19 /*
20 ---------------------------------------------------------------------------------------------------------------------------------------
21 ------------------------------------------------------- Constructor/Destructor --------------------------------------------------------
22 ---------------------------------------------------------------------------------------------------------------------------------------
23 */
24
25 ClassifyAndCalculateHFTool::ClassifyAndCalculateHFTool(const std::string& t, const std::string& n, const IInterface* p) : AthAlgTool(t,n,p){
26 }
27
30
31 /*
32 ---------------------------------------------------------------------------------------------------------------------------------------
33 --------------------------------------------------------- Initialize/Finalize ---------------------------------------------------------
34 ---------------------------------------------------------------------------------------------------------------------------------------
35 */
36
38
39 ATH_MSG_INFO("Initialize");
40
41 // Print the string variables.
42
43 ATH_MSG_INFO("Cut on the pt of the jets: " << m_jetPtCut);
44 ATH_MSG_INFO("Cut on the eta of the jets: " << m_jetEtaCut);
45 ATH_MSG_INFO("Cut on the pt of the leading B-hadron: " << m_leadingBHadronPtCut);
46 ATH_MSG_INFO("Cut on the pt of the leading C-hadron: " << m_leadingCHadronPtCut);
47 ATH_MSG_INFO("Cut on the ratio between the pt of the leading hadron and the pt of its associated jet: " << m_leadingHadronPtRatioCut);
48
49 return StatusCode::SUCCESS;
50 }
51
53 return StatusCode::SUCCESS;
54 }
55
56 /*
57 ---------------------------------------------------------------------------------------------------------------------------------------
58 -------------------------------------------------------------- Flag Jets --------------------------------------------------------------
59 ---------------------------------------------------------------------------------------------------------------------------------------
60 */
61
63 const std::map<const xAOD::Jet*, std::vector<xAOD::TruthParticleContainer::const_iterator>>& particleMatch,
64 const std::map<const xAOD::TruthParticle*, DerivationFramework::HadronOriginClassifier::HF_id>& hadronMap,
65 const std::string& hfDecorationName) const{
66
67 SG::Decorator< int > decorator_flav(hfDecorationName + "_flav");
68 SG::Decorator< int > decorator_id(hfDecorationName + "_id");
69 SG::Decorator< int > decorator_count(hfDecorationName + "_count");
70
71 for(const xAOD::Jet* jet : *jets){
72
73 // Check if the jet passes the cuts and if it does not, then skip it.
74
75 if(jet->p4().Pt() < m_jetPtCut || std::abs(jet->p4().Eta()) > m_jetEtaCut) {
76 decorator_flav(*jet) = -999;
77 decorator_id(*jet) = -999;
78 decorator_count(*jet) = -999;
79 continue;
80 }
81
82 // Create a set of integer variables to save the necessary variables for the HF classifier:
83 // -flav: Flavour of the jet.
84 // -id: Origin of the most initial hadron of the jet.
85 // -count: Number of associated hadrons of the jet that have the same flavour as the jet.
86
87 int flav=0;
88 int id=0;
89 int count=0;
90
91 // Create a set of integer variables to save information that is required to compute the necessary variables for the HF classifier.:
92 // -bcount: It contains the number of B-hadrons.
93 // -ccount: It contains the number of C-hadrons.
94 // -bcountcut: It contains the number of B-hadron that pass the cuts.
95 // -ccountcut: It contains the number of C-hadron that pass the cuts.
96 // -bid: The greatest value of the variable "TopHadronOriginFlag" for B-hadrons (most initial B-hadron).
97 // -cid: The greatest value of the variable "TopHadronOriginFlag" for C-hadrons (most initial B-hadron).
98
99 int bcount=0;
100 int ccount=0;
101 int bcountcut=0;
102 int ccountcut=0;
103
104 int bid=0;
105 int cid=0;
106
107 // Get the hadrons associated with the jet that is being considered.
108
109 auto it = particleMatch.find (jet);
110 if (it != particleMatch.end()) {
111
113
114 // Create two integer variables:
115 // -hforigin: It will contain the origin of the hadron if it is a HF hadron. Otherwise, it will be 6.
116 // -pdgId: It will contain the value of the variable "pdgId" of the hadron.
117
118 int hforigin = 6;
119 int pdgId = (*hf)->pdgId();
120
121 // Extract the origin of the hadron.
122
123 auto h_it = hadronMap.find(*hf);
124 if(h_it!=hadronMap.end()){
125 hforigin= static_cast<int>(h_it->second);
126 }
127
128 // Check if hforigin is 6 and if it is the case, then hadron is not HF and it is skipped.
129
130 if(6==hforigin) continue;
131
132 // Compute the ratio between the pt of the hadron and the pt of its associated jet.
133
134 float ptratio = (*hf)->p4().Pt()/jet->p4().Pt();
135
136 // Determine if the hadron is a B-hadron or a C-hadron.
137
138 int hftype = 0;
139
140 if(MC::isCharmHadron(pdgId)) hftype=4; // B-hadron
141 if(MC::isBottomHadron(pdgId)) hftype=5; // C-hadron.
142
143 // Check if hftype is 4 or 5.
144
145 if(5==hftype){
146
147 // In this case, hftype is 5 so the hadron is a B-hadron.
148 // Save hforigin in bid if it is greater than the current bid.
149
150 if(bid<hforigin)bid=hforigin;
151
152 // Add one to bcount and to bcountcut if hadron passes the cuts.
153
154 ++bcount;
155
156 if((*hf)->p4().Pt()>m_leadingBHadronPtCut && ptratio>m_leadingHadronPtRatioCut){
157 ++bcountcut;
158 }
159 }
160 else if(4==hftype){
161
162 // In this case, hftype is 4 so the hadron is a C-hadron.
163 // Save hforigin in cid if it is greater than the current cid.
164
165 if(cid>hforigin)cid=hforigin;
166
167 // Add one to ccount and to ccountcut if hadron passes the cuts.
168
169 ++ccount;
170
171 if((*hf)->p4().Pt()>m_leadingCHadronPtCut && ptratio>m_leadingHadronPtRatioCut){
172 ++ccountcut;
173 }
174
175 }
176 else{
177
178 // In this case, hftype is not 4 neither 5 so print an error.
179
180 ATH_MSG_WARNING("Hadron type '" << hftype << "' is not 4 or 5");
181
182 }
183
184 }
185 }
186
187 // Check if there is at least one B-hadron or a C-hadron that passes the cuts.
188
189 if(bcountcut){
190
191 // In this case, at least one B-hadron passes the cuts.
192 // The "flavour" of the jet (flav) is set to 5.
193 // As a id of the jet, the greatest value of the variable "TopHadronOriginFlag" for B-hadrons is used (origin of the most initial hadron).
194 // The number of B-hadrons is saved in count.
195
196 flav=5;
197 id=bid;
198 count=bcount;
199 }
200 else if(ccountcut){
201
202 // In this case, no B-hadron passes the cuts, but at least one C-hadron does.
203 // The "flavour" of the jet (flav) is set to 4.
204 // As a id of the jet, the greatest value of the variable "TopHadronOriginFlag" for C-hadrons is used (origin of the most initial hadron).
205 // The number of C-hadrons is saved in count.
206
207 flav=4;
208 id=cid;
209 count=ccount;
210 }
211
212 // Dectorate the jet with the flav, id and count.
213 decorator_flav(*jet) = flav;
214 decorator_id(*jet) = id;
215 decorator_count(*jet) = count;
216 }
217
218 }
219
220 /*
221 ---------------------------------------------------------------------------------------------------------------------------------------
222 ---------------------------------------------------------- HF Classification ----------------------------------------------------------
223 ---------------------------------------------------------------------------------------------------------------------------------------
224 */
225
226 int ClassifyAndCalculateHFTool::computeHFClassification(const xAOD::JetContainer* jets, const std::string& hfDecorationName) const{
227
228 // Create a set of integer variables to save information that is required to compute the HF classifier.:
229 // -b: Number of jets that has just one B-hadron that passes the cuts.
230 // -B: Number of jets that has more than one B-hadron and at least one of them passes the cuts.
231 // -c: Number of jets that has just one C-hadron that passes the cuts (and no B-hadron)
232 // -C: Number of jets that has more than one C-hadron and at least one of them passes the cuts (and no B-hadron).
233 // -b_prompt: Number of jets that has just one prompt B-hadron that passes the cuts.
234 // -B_prompt: Number of jets that has more than one prompt B-hadron and at least one of them passes the cuts.
235 // -c_prompt: Number of jets that has just one prompt C-hadron that passes the cuts (and no B-hadron).
236 // -C_prompt: Number of jets that has more than one prompt C-hadron and at least one of them passes the cuts (and no B-hadron).
237 // -mpifsr_code: HF classifier for events with no prompt additional hadrons, just Multi-Parton Interaction (MPI) and/or Final State Radiation (FSR) hadrons.
238 // Note: prompt hadrons in this context are hadrons that do not come from the direct decay of top, W or Higgs but they are not from MPI or FSR.
239
240 int b=0, B=0, c=0, C=0;
241 int b_prompt=0, B_prompt=0, c_prompt=0, C_prompt=0;
242
243 int mpifsr_code=0;
244
245 for(const xAOD::Jet* jet : *jets){
246
247 // Check if the jet passes the cuts and if it does not, then skip it.
248
249 if(jet->p4().Pt() < m_jetPtCut) continue;
250 if(std::abs(jet->p4().Eta()) > m_jetEtaCut) continue;
251
252 // Get the flavour, the id and the number of hadrons of the considered jet.
253
254 int flav = 0;
255 int id = 0;
256 int count = 0;
257
258 SG::ConstAccessor<int> hfflavAcc(hfDecorationName + "_flav");
259 if(hfflavAcc.isAvailable(*jet)){
260 flav=hfflavAcc(*jet);
261 }else{
262 ATH_MSG_WARNING("variable '" + hfDecorationName + "_flav' not found.");
263 continue;
264 }
265
266 SG::ConstAccessor<int> hfidAcc(hfDecorationName + "_id");
267 if(hfidAcc.isAvailable(*jet)){
268 id=hfidAcc(*jet);
269 }else{
270 ATH_MSG_WARNING("variable '" + hfDecorationName + "_id' not found.");
271 continue;
272 }
273
274 SG::ConstAccessor<int> hfcountAcc(hfDecorationName + "_count");
275 if(hfcountAcc.isAvailable(*jet)){
276 count=hfcountAcc(*jet);
277 }else{
278 ATH_MSG_WARNING("variable '" + hfDecorationName + "_count' not found.");
279 continue;
280 }
281
282 // Check the flavour and the id of the jet.
283
284 if(flav==5 && id < 3){
285
286 // In this case, the flavour is 5 and id is less than 3.
287 // This means that the jet has at least one B-hadron that is not from direct decay of top, W or Higgs.
288 // Hence, the jet is an additional one.
289
290 // Check the number of B-hadrons.
291
292 if(count > 1){
293
294 // In this case, there is more than one B-hadron, so add 1 to B.
295
296 B++;
297
298 }
299 else{
300
301 // In this case, there is just one B-hadron, so add 1 to b.
302
303 b++;
304
305 }
306 }
307 if(flav==4 && (id==0 || id==-1 || id==-2)){
308
309 // In this case, the flavour is 4 and id is 0, -1 or -2.
310 // This means that the jet has no B-hadron and at least one C-hadron that is not from direct decay of top, W or Higgs.
311 // Hence, the jet is an additional one.
312
313 // Check the number of C-hadrons.
314
315 if(count > 1){
316
317 // In this case, there is more than one C-hadron, so add 1 to C.
318
319 C++;
320 }
321 else{
322
323 // In this case, there is just one C-hadron, so add 1 to c.
324
325 c++;
326 }
327 }
328
329 // Check the flavour and the id of the jet but considering only prompt particles (id=0).
330
331 if(flav==5 && id==0){
332
333 // In this case, the flavour is 5 and id is 0.
334 // This means that the jet has at least one B-hadron that is not from direct decay of top, W or Higgs neither from MPI or FSR.
335
336 // Check the number of B-hadrons.
337
338 if(count > 1){
339
340 // In this case, there is more than one B-hadron, so add 1 to B_prompt.
341
342 B_prompt++;
343
344 }
345 else{
346
347 // In this case, there is jut one B-hadron, so add 1 to b_prompt.
348
349 b_prompt++;
350
351 }
352 }
353 if(flav==4 && id==0){
354
355 // In this case, the flavour is 4 and id is 0.
356 // This means that the jet has no B-hadron and at least one C-hadron that is not from direct decay of top, W or Higgs neither from MPI or FSR.
357
358 // Check the number of C-hadrons.
359
360 if(count > 1){
361
362 // In this case, there is more than one C-hadron, so add 1 to C_prompt.
363
364 C_prompt++;
365 }
366 else{
367
368 // In this case, there is just one C-hadron, so add 1 to C_prompt.
369
370 c_prompt++;
371
372 }
373 }
374
375 // In the case when there is no prompt hadrons, then the HF classifier is computed with non-promt hadrons.
376 // This hadrons come from Multi-Parton Interactions (MPI) and the Final State Radiation (FSR).
377 // Compute mpifsr_code which will contain the HF classifier when there is no prompt hadrons.
378 // Each jet adds a different quantity to mpifsr_code depending on its flavour and its id.
379
380 if(id==1 && flav==5){ // b MPI
381 mpifsr_code -= 1000;
382 }
383 else if(id==2 && flav==5){ // b FSR
384 mpifsr_code -= 100;
385 }
386 else if(id==-1 && flav==4){ // c MPI
387 mpifsr_code -= 10;
388 }
389 else if(id==-2 && flav==4) { // c FSR
390 mpifsr_code -= 1;
391 }
392 }
393
394 // Compute the ext_code using the number of additional jets with HF hadrons.
395 // Compute the prompt_code using the number of additional jets with propmt HF hadrons.
396
397 int ext_code = 1000*b+100*B+10*c+1*C;
398 int prompt_code = 1000*b_prompt+100*B_prompt+10*c_prompt+1*C_prompt;
399
400 // Check if there are prompt hadrons and non-prompt hadrons using ext_code and prompt_code.
401
402 if(prompt_code==0 && ext_code!=0){
403
404 // In this case, there is no prompt hadrons but there are MPI and FSR hadrons.
405 // Hence, return mpifsr_code as a HF classifier, which is equal to ext_code but in negative sign.
406
407 return mpifsr_code;
408
409 }
410
411 // In this case, there are prompt hadrons, so return ext_code as HF classifier.
412
413 return ext_code;
414
415 }
416
418
419 // Check the value of the HF classifier (hfclassif) which is computed with the function computeHFClassification.
420
421 if(std::abs(hfclassif)>=100){
422
423 // If the absolute value of hfclassif is greater than 100, then there is at least one jet with a B-hadron.
424 // In this case, return 1.
425
426 return 1;
427
428
429 }
430 else if(hfclassif==0){
431
432 // If hfclassif is 0, then there is no jet with a B-hadron or a C-hadron.
433 // In this case, return 0.
434
435 return 0;
436 }
437
438 // If the absolute value of hfclassif is lower than 100 and non-zero, then there is no jet with a B-hadron but at least one with a C-hadron.
439 // In this case, return -1.
440
441 return -1;
442 }
443}
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
Helper class to provide constant type-safe access to aux data.
ATLAS-specific HepMC functions.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
void flagJets(const xAOD::JetContainer *jets, const std::map< const xAOD::Jet *, std::vector< xAOD::TruthParticleContainer::const_iterator > > &particleMatch, const std::map< const xAOD::TruthParticle *, DerivationFramework::HadronOriginClassifier::HF_id > &hadronMap, const std::string &hfDecorationName) const
int computeHFClassification(const xAOD::JetContainer *jets, const std::string &hfDecorationName) const
ClassifyAndCalculateHFTool(const std::string &t, const std::string &n, const IInterface *p)
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148
struct color C
THE reconstruction tool.
bool isCharmHadron(const T &p)
bool isBottomHadron(const T &p)
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
Definition AuxElement.h:576
Jet_v1 Jet
Definition of the current "jet version".
JetContainer_v1 JetContainer
Definition of the current "jet container version".