ATLAS Offline Software
Truth.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 // This source file implements all of the functions related to Truth
6 // in the SUSYObjDef_xAOD class
7 
8 // Local include(s):
10 
11 // For using the MCTruthClassifier definitions
13 
15 
16 #ifndef XAOD_STANDALONE // For now metadata is Athena-only
18 #endif
19 
20 namespace ST {
21 
22 
24 
25  const int type = acc_truthType(*part);
26  int origin = acc_truthOrigin(*part);
27  int originbkg = 0;
28  if(acc_bkgTruthOrigin.isAvailable(*part)){ //only in SUSY2,3,5 for the moment!
29  originbkg = acc_bkgTruthOrigin(*part);
30  }
31  else{
32  ATH_MSG_DEBUG("::isPrompt() : No bkgTruthOrigin decoration available. Returning false by default.");
33  return false;
34  }
35 
36  //Electrons
37  if( part->type() == xAOD::Type::Electron ){
38  switch(type){
40  if(origin != MCTruthPartClassifier::PhotonConv) return false;
41  if(originbkg == MCTruthPartClassifier::FSRPhot || originbkg == MCTruthPartClassifier::BremPhot) return true;
42  origin = originbkg;
43  /* FALLTHRU */
44  case MCTruthPartClassifier::IsoElectron:
45  return (origin == MCTruthPartClassifier::top
48  || origin == MCTruthPartClassifier::Higgs
53  || origin == MCTruthPartClassifier::NuRMu
55  || origin == MCTruthPartClassifier::LQ
56  || origin == MCTruthPartClassifier::SUSY);
57  default:
58  return false;
59  }
60  // NB: will classify a few muon/quark brems as prompt electrons, but a small effect
61  }
62  if( part->type() == xAOD::Type::Muon ){
64  }
65  else{
66  ATH_MSG_DEBUG("::isPrompt() : Only Electrons supported at the moment!");
67  }
68 
69  //Photons ... ?
70  //Taus ... ?
71  return false;
72 }
73 
74 
75 StatusCode SUSYObjDef_xAOD::FindSusyHP(int& pdgid1, int& pdgid2) const {
76 
77  const xAOD::TruthParticleContainer* truthP = nullptr;
78  bool isTruth3 = false;
79  std::string key_T1 = "TruthParticles";
80  std::string key_T3 = "TruthBSM";
81 
82  ATH_MSG_DEBUG("Contains " << key_T1 << ": " << ((evtStore()->contains<xAOD::TruthParticleContainer>( key_T1 ))?1:0));
83  ATH_MSG_DEBUG("Contains " << key_T3 << ": " << ((evtStore()->contains<xAOD::TruthParticleContainer>( key_T3 ))?1:0));
84 
85  if(evtStore()->contains<xAOD::TruthParticleContainer>( key_T1 )){
86  ATH_CHECK( evtStore()->retrieve(truthP, key_T1) );
87  ATH_MSG_DEBUG("Retrieved " << key_T1 << " : size = " << truthP->size());
88  if (truthP->empty()) { ATH_MSG_WARNING(key_T1 << " is empty. Skipping FindSusyHP."); return StatusCode::SUCCESS; }
89  }
90  else if(evtStore()->contains<xAOD::TruthParticleContainer>( key_T3 )){
91  isTruth3=true;
92  ATH_CHECK( evtStore()->retrieve(truthP, key_T3) );
93  ATH_MSG_DEBUG("Retrieved " << key_T3 << " : size = " << truthP->size());
94  if (truthP->empty()) { ATH_MSG_WARNING(key_T3 << " is empty. Skipping FindSusyHP."); return StatusCode::SUCCESS; }
95  }
96  else {
97  ATH_MSG_WARNING("Neither " << key_T1 << " nor " << key_T3 << " are avaible. Skipping FindSusyHP.");
98  return StatusCode::SUCCESS;
99  }
100 
101  return SUSYObjDef_xAOD::FindSusyHP(truthP, pdgid1, pdgid2, isTruth3);
102 }
103 
104 
105 StatusCode SUSYObjDef_xAOD::FindSusyHP(const xAOD::TruthParticleContainer *truthP, int& pdgid1, int& pdgid2, bool isTruth3) const {
106  if (!truthP) {
107  ATH_MSG_ERROR("Null TruthParticleContainer pointer!!");
108  return StatusCode::FAILURE;
109  }
110  if (truthP->empty()) {
111  ATH_MSG_ERROR("Empty TruthParticleContainer!!");
112  return StatusCode::FAILURE;
113  }
114  if ( !SUSYObjDef_xAOD::FindSusyHardProc(truthP, pdgid1, pdgid2, isTruth3) ) {
115  ATH_MSG_ERROR("Problem finding SUSY hard process");
116  return StatusCode::FAILURE;
117  }
118  if (pdgid1 == 0 || pdgid2 == 0) {
119  ATH_MSG_DEBUG("No sparticles found!");
120  }
121  return StatusCode::SUCCESS;
122 }
123 
124 
125 bool SUSYObjDef_xAOD::FindSusyHardProc(const xAOD::TruthParticleContainer *truthP, int& pdgid1, int& pdgid2, bool isTruth3) {
126 
127  pdgid1 = 0;
128  pdgid2 = 0;
129 
130  //check for TRUTH3 structure first
131  if(isTruth3){
132  if(!truthP || truthP->size()<2){
133  return false;
134  }
135 
136  //get ID of first two BSM particles
137  pdgid1 = (*truthP)[0]->pdgId();
138  pdgid2 = (*truthP)[1]->pdgId();
139  return true;
140  }
141 
142  //go for TRUTH1-like if not...
143  const xAOD::TruthParticle* firstsp(nullptr);
144  const xAOD::TruthParticle* secondsp(nullptr);
145 
146  if (!truthP || truthP->empty()) {
147  return false;
148  }
149  for (const xAOD::TruthParticle* tp : *truthP) {
150 
151  //check ifSUSY particle
152  if ((tp->absPdgId() > 1000000 && tp->absPdgId() < 1000007) || // squarkL
153  (tp->absPdgId() > 1000010 && tp->absPdgId() < 1000017) || // sleptonL
154  (tp->absPdgId() > 2000000 && tp->absPdgId() < 2000007) || // squarkR
155  (tp->absPdgId() > 2000010 && tp->absPdgId() < 2000017) || // sleptonR
156  (tp->absPdgId() > 1000020 && tp->absPdgId() < 1000040)) { // gauginos
157 
158  if (tp->nParents() != 0) {
159  if ( tp->parent(0)->absPdgId() < 1000000) {
160  if (!firstsp) {
161  firstsp = tp;
162  } else if (!secondsp) {
163  secondsp = tp;
164  } else {
165  if (firstsp->nChildren() != 0 && HepMC::is_same_particle(tp,firstsp->child(0))) {
166  firstsp = tp;
167  }
168  else if (secondsp->nChildren() != 0 && HepMC::is_same_particle(tp,secondsp->child(0))) {
169  secondsp = tp;
170  }
171  else if (firstsp->nChildren() != 0 && HepMC::is_same_particle(firstsp->child(0),secondsp)) {
172  firstsp = secondsp;
173  secondsp = tp;
174  }
175  else if (secondsp->nChildren() != 0 && HepMC::is_same_particle(secondsp->child(0),firstsp)) {
176  secondsp = firstsp;
177  firstsp = tp;
178  }
179  }
180  }
181  }
182  }
183  }
184 
185  // quit if no sparticles found
186  if (!firstsp && !secondsp) return true; // should find none or two
187 
188  if (firstsp->nChildren() == 1) {
189  for (const xAOD::TruthParticle* tp : *truthP) {
190  if (HepMC::is_same_particle(tp,firstsp->child(0)) && tp->pdgId() != firstsp->pdgId()) {
191  firstsp = tp;
192  break;
193  }
194  }
195  }
196 
197  if (secondsp->nChildren() == 1) {
198  for (const xAOD::TruthParticle* tp : *truthP) {
199  if (HepMC::is_same_particle(tp,secondsp->child(0)) && tp->pdgId() != secondsp->pdgId()) {
200  secondsp = tp;
201  break;
202  }
203  }
204  }
205 
206  if (firstsp->absPdgId() > 1000000) pdgid1 = firstsp->pdgId();
207  if (secondsp->absPdgId() > 1000000) pdgid2 = secondsp->pdgId();
208 
209  // Return gracefully:
210  return true;
211 }
212 
213 
214 StatusCode SUSYObjDef_xAOD::FindSusyHP(const xAOD::TruthEvent *truthE, int& pdgid1, int& pdgid2) const {
215 
216  if (!truthE) {
217  ATH_MSG_ERROR("Null TruthEvent pointer!!");
218  return StatusCode::FAILURE;
219  }
220  if ( !SUSYObjDef_xAOD::FindSusyHardProc(truthE, pdgid1, pdgid2) ) {
221  ATH_MSG_ERROR("Problem finding SUSY hard process");
222  return StatusCode::FAILURE;
223  }
224  if (pdgid1 == 0 || pdgid2 == 0) {
225  ATH_MSG_DEBUG("No sparticles found!");
226  }
227  return StatusCode::SUCCESS;
228 }
229 
230 
231 bool SUSYObjDef_xAOD::FindSusyHardProc(const xAOD::TruthEvent *truthE, int& pdgid1, int& pdgid2) {
232 
233  pdgid1 = 0;
234  pdgid2 = 0;
235 
236  //go for TRUTH1-like ...
237  const xAOD::TruthParticle* firstsp(nullptr);
238  const xAOD::TruthParticle* secondsp(nullptr);
239 
240  for (unsigned int p=0; p < truthE->nTruthParticles(); ++p){
241 
242  const xAOD::TruthParticle* tp = truthE->truthParticle(p);
243 
244  //check ifSUSY particle
245  if ((tp->absPdgId() > 1000000 && tp->absPdgId() < 1000007) || // squarkL
246  (tp->absPdgId() > 1000010 && tp->absPdgId() < 1000017) || // sleptonL
247  (tp->absPdgId() > 2000000 && tp->absPdgId() < 2000007) || // squarkR
248  (tp->absPdgId() > 2000010 && tp->absPdgId() < 2000017) || // sleptonR
249  (tp->absPdgId() > 1000020 && tp->absPdgId() < 1000040)) { // gauginos
250 
251  if (tp->nParents() != 0) {
252  if ( tp->parent(0)->absPdgId() < 1000000) {
253  if (!firstsp) {
254  firstsp = tp;
255  } else if (!secondsp) {
256  secondsp = tp;
257  } else {
258  if (firstsp->nChildren() != 0 && HepMC::is_same_particle(tp,firstsp->child(0))) {
259  firstsp = tp;
260  }
261  else if (secondsp->nChildren() != 0 && HepMC::is_same_particle(tp,secondsp->child(0))) {
262  secondsp = tp;
263  }
264  else if (firstsp->nChildren() != 0 && HepMC::is_same_particle(firstsp->child(0),secondsp)) {
265  firstsp = secondsp;
266  secondsp = tp;
267  }
268  else if (secondsp->nChildren() != 0 && HepMC::is_same_particle(secondsp->child(0),firstsp)) {
269  secondsp = firstsp;
270  firstsp = tp;
271  }
272  }
273  }
274  }
275  }
276  }
277 
278  // quit if no sparticles found
279  if (!firstsp && !secondsp) return true; // should find none or two
280 
281  if (firstsp->nChildren() == 1) {
282  for (unsigned int p=0; p < truthE->nTruthParticles(); ++p){
283  const xAOD::TruthParticle* tp = truthE->truthParticle(p);
284  if (HepMC::is_same_particle(tp,firstsp->child(0)) && tp->pdgId() != firstsp->pdgId()) {
285  firstsp = tp;
286  break;
287  }
288  }
289  }
290 
291  if (secondsp->nChildren() == 1) {
292  for (unsigned int p=0; p < truthE->nTruthParticles(); ++p){
293  const xAOD::TruthParticle* tp = truthE->truthParticle(p);
294  if (HepMC::is_same_particle(tp,secondsp->child(0)) && tp->pdgId() != secondsp->pdgId()) {
295  secondsp = tp;
296  break;
297  }
298  }
299  }
300 
301  if (firstsp->absPdgId() > 1000000) pdgid1 = firstsp->pdgId();
302  if (secondsp->absPdgId() > 1000000) pdgid2 = secondsp->pdgId();
303 
304  // Return gracefully:
305  return true;
306 }
307 
308 
310  //Method to set correctly the IsBjet decoration needed by the JetUncertainties tool
311  bool isBjet = false;
312  if (acc_signal(input)) {
313 
314  int truthlabel(-1);
315  if (!input.getAttribute("HadronConeExclTruthLabelID", truthlabel)) {
316  ATH_MSG_ERROR("Failed to get jet truth label!");
317  }
318 
319  isBjet = std::abs(truthlabel) == 5;
320  }
321 
322  const static SG::AuxElement::Decorator<char> dec_bjet_jetunc("bjet_jetunc"); //added for JetUncertainties usage
323  dec_bjet_jetunc(input) = isBjet;
324 
325  return isBjet;
326 }
327 
328 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
ST::SUSYObjDef_xAOD::isPrompt
bool isPrompt(const xAOD::IParticle *part) const override final
Definition: Truth.cxx:23
NuRMu
@ NuRMu
Definition: TruthClasses.h:73
ST::SUSYObjDef_xAOD::IsTruthBJet
bool IsTruthBJet(const xAOD::Jet &input) const override final
Definition: Truth.cxx:309
xAOD::TruthParticle_v1::absPdgId
int absPdgId() const
Absolute PDG ID code (often useful)
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
NuREle
@ NuREle
Definition: TruthClasses.h:72
WBosonLRSM
@ WBosonLRSM
Definition: TruthClasses.h:71
ST
Definition: Electrons.cxx:41
xAOD::TruthEventBase_v1::truthParticle
const TruthParticle * truthParticle(size_t index) const
Get a pointer to one of the truth particles.
Definition: TruthEventBase_v1.cxx:50
ParticleTest.tp
tp
Definition: ParticleTest.py:25
PhotonConv
@ PhotonConv
Definition: TruthClasses.h:59
SUSYObjDef_xAOD.h
NuRTau
@ NuRTau
Definition: TruthClasses.h:74
ZBoson
@ ZBoson
Definition: TruthClasses.h:67
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
HepMC::is_same_particle
bool is_same_particle(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same particle.
Definition: MagicNumbers.h:354
WBoson
@ WBoson
Definition: TruthClasses.h:66
FSRPhot
@ FSRPhot
Definition: TruthClasses.h:96
HiggsMSSM
@ HiggsMSSM
Definition: TruthClasses.h:69
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
MCTruthClassifierDefs.h
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:59
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
xAOD::TruthEvent_v1
Class describing a signal truth event in the MC record.
Definition: TruthEvent_v1.h:35
LQ
@ LQ
Definition: TruthClasses.h:75
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
IsoMuon
@ IsoMuon
Definition: TruthClasses.h:15
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
xAOD::TruthParticle_v1::nChildren
size_t nChildren() const
Number of children of this particle.
Definition: TruthParticle_v1.cxx:140
MagicNumbers.h
SUSY
@ SUSY
Definition: TruthClasses.h:77
HeavyBoson
@ HeavyBoson
Definition: TruthClasses.h:70
xAOD::TruthEventBase_v1::nTruthParticles
size_t nTruthParticles() const
Get the number of truth particles.
Muon
struct TBPatternUnitContext Muon
AthAnalysisHelper.h
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
ST::SUSYObjDef_xAOD::FindSusyHP
StatusCode FindSusyHP(int &pdgid1, int &pdgid2) const
Definition: Truth.cxx:75
ST::SUSYObjDef_xAOD::FindSusyHardProc
static bool FindSusyHardProc(const xAOD::TruthParticleContainer *truthP, int &pdgid1, int &pdgid2, bool isTruth3=false)
Definition: Truth.cxx:125
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
xAOD::TruthParticle_v1::child
const TruthParticle_v1 * child(size_t i=0) const
Retrieve the i-th mother (TruthParticle) of this TruthParticle.
Definition: TruthParticle_v1.cxx:149
Higgs
@ Higgs
Definition: TruthClasses.h:68
top
@ top
Definition: TruthClasses.h:64
xAOD::TruthParticle_v1::pdgId
int pdgId() const
PDG ID code.
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
BkgElectron
@ BkgElectron
Definition: TruthClasses.h:13
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
BremPhot
@ BremPhot
Definition: TruthClasses.h:92