Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
CopyTruthJetParticles.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
10 
17 #include "AsgMessaging/Check.h"
19 
20 #include <mutex> // std::call_once, std::once_flag
21 
22 #ifndef XAOD_STANDALONE
23 // Usage of metadata is for now only possible in Athena...
24 //#include "CoralBase/AttributeListException.h"
26 #endif
27 
28 // For std::find in comesFrom()
29 #include <algorithm>
30 
31 using namespace std;
32 using namespace MCTruthPartClassifier;
33 
37  ATH_CHECK(m_classif.retrieve());
38 
39  ATH_CHECK(m_truthEventKey.initialize());
40  ATH_CHECK(m_outTruthPartKey.initialize());
41 
42  return StatusCode::SUCCESS;
43 }
44 
45 
46 
48  std::vector<const xAOD::TruthParticle*>& promptLeptons,
49  std::map<const xAOD::TruthParticle*,unsigned int>& tc_results) const {
50 
51  // Check if this thing is a candidate to be in a truth jet
52  // First block is largely copied from isGenStable, which works on HepMC only
53  if (HepMC::is_simulation_particle(tp)) return false; // Particle is from G4
54  int pdgid = tp->pdgId();
55  if (MC::isZeroEnergyPhoton(tp)) return false; // Work around for an old generator bug
56 
57  // -- changed for dark jet clustering -- //
58  if ( !MC::isStable(tp) && !m_includeDark ) return false; // dark hadrons will not be status 1
59  // ----------------------------------- //
60 
61  // Easy classifiers by PDG ID
62  if(MC::isNeutrino(pdgid)) {
63  if (!m_includeNu) return false;
64  } else {
65  if (!m_includeBSMNonInt && !MC::isInteracting(pdgid)) return false;
66  }
67  if (!m_includeMu && MC::isMuon(pdgid)) return false;
68 
69  // Already built a list of prompt leptons, just use it here
70  if (!m_includePromptLeptons && std::find(promptLeptons.begin(),promptLeptons.end(),tp)!=promptLeptons.end()){
71  ATH_MSG_VERBOSE("Veto prompt lepton (" << pdgid << ") with pt " << tp->pt());
72  return false;
73  }
74 
75  // Extra catch. If we aren't supposed to include prompt leptons, we aren't supposed to include prompt neutrinos
76  unsigned int tc_res = getTCresult(tp, tc_results);
78  return false;
79  }
80 
81  // -- added for dark jet clustering -- //
82  // new classifiers to account for dark particles
83  // for dark jets: ignore SM particles; include only "stable" dark hadrons
84  if (!m_includeSM && !MC::isHiddenValley(tp)) return false;
85  if (m_includeDark) {
86  if (abs(tp->pdgId()) <= 4900101) return false; // ignore Xd, qd, gd
87  if (tp->hasDecayVtx()) {
88  size_t good_hadrons = 0;
89  for (size_t p = 0; p < tp->end_vertex()->nOutgoingParticles(); ++p) {
90  if (!MC::isHiddenValley(tp->child(p))) {
91  good_hadrons++;
92  }
93  }
94  if (good_hadrons == 0) return false; // ignore "non-stable" dark hadrons (decaying to dark sector) -- "stable" if decaying to SM
95  }
96  }
97  // for SM jets: ignore dark particles - probably unnecessary bc of status requirement above
98  if (!m_includeDark && MC::isHiddenValley(tp)) return false;
99  // ----------------------------------- //
100 
101  if (!m_includePromptPhotons && MC::isPhoton(pdgid) && tp->hasProdVtx()){
102  //ParticleOrigin orig = getPartOrigin(tp, originMap);
103  //if (orig==Higgs || orig==HiggsMSSM) return false;
104  if (MCTruthPartClassifier::isPrompt(tc_res)) return false;
105  }
106 
107  // If we want to remove photons via the dressing decoration
108  if (!m_dressingName.empty()){
109  // Accessor for the dressing decoration above
110  const static SG::AuxElement::Accessor<char> dressAcc(m_dressingName);
111  if (MC::isPhoton(pdgid) && dressAcc(*tp)) return false;
112  } // End of removal via dressing decoration
113 
114  // Pseudo-rapidity cut
115  if(std::abs(tp->eta())>m_maxAbsEta) return false;
116 
117  // Vetoes of specific origins. Not fast, but if no particles are specified should not execute
118  if (m_vetoPDG_IDs.size()>0){
119  std::vector<int> used_vertices;
120  for (int anID : m_vetoPDG_IDs){
121  used_vertices.clear();
122  if (comesFrom(tp,anID,used_vertices)) return false;
123  }
124  }
125 
126  // Made it!
127  return true;
128 }
129 
130 
132  std::map<const xAOD::TruthParticle*,unsigned int>& tc_results) const
133 {
134  if(tc_results.find(tp) == tc_results.end()) {
135  const unsigned int result = tp ? std::get<0>(MCTruthPartClassifier::defOrigOfParticle(tp)) : 0;
136  tc_results[tp] = result;
137  }
138  return tc_results[tp];
139 }
140 
142 
143  // Usage of metadata is only possible in Athena (not supported by dual-use tools yet)...
144 #ifndef XAOD_STANDALONE
145  bool found = false;
146  // retrieve the value for the current sample from metadata
147 
148  int barcodeOffset_tmp(0);
149  ATH_MSG_INFO("Look for barcode offset in metadata ... ");
150  try {
151  StatusCode sc= AthAnalysisHelper::retrieveMetadata("/Simulation/Parameters","SimBarcodeOffset",barcodeOffset_tmp) ;
152  found = sc.isSuccess();
153  } catch(std::exception &e) {
154  ATH_MSG_DEBUG(" Could not retrieve barcode offset in metadata : "<< e.what());
155  }
156  if (found) {
157  if (HepMC::SIM_BARCODE_THRESHOLD!=barcodeOffset_tmp) ATH_MSG_WARNING(" Barcode offset found in metadata. Its value is : "<< barcodeOffset_tmp << "vs the used "<< HepMC::SIM_BARCODE_THRESHOLD);
158  }
159 #else // standalone :
160  ATH_MSG_WARNING("Can't retrieve automatically the truth barcode offset outside Athena. Falling back to offset property: " << HepMC::SIM_BARCODE_THRESHOLD);
161 #endif
162  return 0;
163 }
164 
166 
167  // retrieve barcode Offset for this event from metadata.
168  // We'd need a cleaner solution where this offset is set only at
169  // each new file, but this requires some tool interface which does
170  // not exist in RootCore yet.
171  // So we use the less disruptive solution in Athena for now...
172 
173  // the function used below is
174  // std::call_once(metaDataFlag,basicMetaDataCheck(), this);
175  // std::call_once(metaDataFlag,this->basicMetaDataCheck());
176  // the syntax is explained in http://stackoverflow.com/questions/23197333/why-is-this-pointer-needed-when-calling-stdcall-once
177  // this syntax requires the call_once function to receive the object the function is called upon
178  //": these are all non-static member functions , they act on objects
179  // they need the "this" pointer which always point to the object the function is working on
180  //http://www.learncpp.com/cpp-tutorial/812-static-member-functions/
181 
182 
183  // std::call_once(metaDataFlag,&CopyTruthJetParticles::basicMetaDataCheck,this,barcodeOffset);
184  // this call happens only once and it modifies m_barcodeOffset
185  // Note that catching the return value of this is rather complicated, so it throws rather than returning errors
186  static std::once_flag metaDataFlag;
187  std::call_once(metaDataFlag,[&]() {setBarCodeFromMetaDataCheck();});
188 
189  std::vector<const xAOD::TruthParticle*> promptLeptons;
190  promptLeptons.reserve(10);
191 
192  // Retrieve the xAOD truth objects
193  auto truthEvents = SG::makeHandle(m_truthEventKey);
194  if ( !truthEvents.isValid() ) {
195  ATH_MSG_ERROR("Failed to retrieve truth event container " << m_truthEventKey.key());
196  return 1;
197  }
198 
199  // Classify particles for tagging and add to the TruthParticleContainer
200  std::unique_ptr<ConstDataVector<xAOD::TruthParticleContainer> > ptruth(new ConstDataVector<xAOD::TruthParticleContainer>(SG::VIEW_ELEMENTS));
201  std::map<const xAOD::TruthParticle*,unsigned int> tc_results;
202  tc_results.clear();
203  size_t numCopied = 0;
204  const xAOD::TruthEvent* hsevt = truthEvents->front();
205  if(!hsevt) {
206  ATH_MSG_ERROR("Null pointer received for first truth event!");
207  return 1;
208  }
209 
210  for (unsigned int ip = 0; ip < hsevt->nTruthParticles(); ++ip) {
211  const xAOD::TruthParticle* tp = hsevt->truthParticle(ip);
212  if(!tp) continue;
213  if (tp->pt() < m_ptmin)
214  continue;
215  // Cannot use the truth helper functions; they're written for HepMC
216  // Last two switches only apply if the thing is a lepton and not a tau
217  if ((MC::isElectron(tp) || MC::isMuon(tp)) && tp->hasProdVtx()) {
218  // If this is a prompt, generator stable lepton, then we can use it
220  promptLeptons.push_back(tp);
221  }
222  }
223  }
224 
225  for (size_t itp(0); itp<hsevt->nTruthParticles(); ++itp) {
226  const xAOD::TruthParticle* tp = hsevt->truthParticle(itp);
227  if(!tp) continue;
228  if (tp->pt() < m_ptmin)
229  continue;
230 
231  if (classifyJetInput(tp, promptLeptons, tc_results)) {
232  ptruth->push_back(tp);
233  numCopied += 1;
234  }
235  }
236 
237  ATH_MSG_DEBUG("Copied " << numCopied << " truth particles into " << m_outTruthPartKey.key() << " TruthParticle container");
238 
239  // record
240  auto truthParticles_out = SG::makeHandle(m_outTruthPartKey);
241  ATH_MSG_DEBUG("Recorded truth particle collection " << m_outTruthPartKey.key());
242  // notify
243  if (!truthParticles_out.put(std::move(ptruth))) {
244  ATH_MSG_ERROR("Unable to write new TruthParticleContainer to event store: "
245  << m_outTruthPartKey.key());
246  } else {
247  ATH_MSG_DEBUG("Created new TruthParticleContainer in event store: "
248  << m_outTruthPartKey.key());
249  }
250 
251  return 0;
252 }
253 
254 
255 bool CopyTruthJetParticles::comesFrom( const xAOD::TruthParticle* tp, const int pdgID, std::vector<int>& used_vertices ) const {
256  // If it's not a particle, then it doesn't come from something...
257  if (!tp) return false;
258  // If it doesn't have a production vertex or has no parents, it doesn't come from much of anything
259  if (!tp->prodVtx() || tp->nParents()==0) return false;
260  // If we have seen it before, then skip this production vertex
261  if (std::find(used_vertices.begin(),used_vertices.end(), HepMC::uniqueID(tp->prodVtx()))!=used_vertices.end()) return false;
262  // Add the production vertex to our used list
263  used_vertices.push_back( HepMC::uniqueID(tp->prodVtx()) );
264  // Loop over the parents
265  for (size_t par=0;par<tp->nParents();++par){
266  // Check for null pointers in case of skimming
267  if (!tp->parent(par)) continue;
268  // Check for a match
269  if (tp->parent(par)->absPdgId()==pdgID) return true;
270  // Recurse on this parent
271  if (comesFrom(tp->parent(par), pdgID, used_vertices)) return true;
272  }
273  // No hits -- all done with the checks!
274  return false;
275 }
276 
WriteHandle.h
Handle class for recording to StoreGate.
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TruthTest.itp
itp
Definition: TruthTest.py:46
HepMC::SIM_BARCODE_THRESHOLD
constexpr int SIM_BARCODE_THRESHOLD
Constant defining the barcode threshold for simulated particles, eg. can be used to separate generato...
Definition: MagicNumbers.h:37
Check.h
get_generator_info.result
result
Definition: get_generator_info.py:21
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
CopyTruthJetParticles::m_includeSM
Gaudi::Property< bool > m_includeSM
Definition: CopyTruthJetParticles.h:57
CopyTruthJetParticles::comesFrom
bool comesFrom(const xAOD::TruthParticle *tp, const int pdgID, std::vector< int > &used_vertices) const
Definition: CopyTruthJetParticles.cxx:255
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
isHiddenValley
bool isHiddenValley(const T &p)
PDG rule 11k Hidden Valley particles have n = 4 and n_r = 9, and trailing numbers in agreement with t...
Definition: AtlasPID.h:592
ConstDataVector.h
DataVector adapter that acts like it holds const pointers.
TruthParticleContainer.h
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
isNeutrino
bool isNeutrino(const T &p)
APID: the fourth generation neutrinos are neutrinos.
Definition: AtlasPID.h:191
ParticleTest.tp
tp
Definition: ParticleTest.py:25
CopyTruthJetParticles::m_maxAbsEta
Gaudi::Property< float > m_maxAbsEta
Maximum allowed eta for particles in jets.
Definition: CopyTruthJetParticles.h:66
MCTruthClassifier.h
MCTruthPartClassifier::defOrigOfParticle
std::tuple< unsigned int, T > defOrigOfParticle(T thePart)
Definition: TruthClassifiers.h:151
CopyTruthJetParticles::m_includeDark
Gaudi::Property< bool > m_includeDark
Definition: CopyTruthJetParticles.h:59
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
CopyTruthJetParticles::m_includeMu
Gaudi::Property< bool > m_includeMu
Definition: CopyTruthJetParticles.h:48
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
TruthParticleAuxContainer.h
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
CopyTruthParticles::m_outTruthPartKey
SG::WriteHandleKey< ConstDataVector< xAOD::TruthParticleContainer > > m_outTruthPartKey
Key for output truth particles.
Definition: CopyTruthParticles.h:46
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
HepMC::is_simulation_particle
bool is_simulation_particle(const T &p)
Method to establish if a particle (or barcode) was created during the simulation (TODO update to be s...
Definition: MagicNumbers.h:355
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::EgammaHelpers::isElectron
bool isElectron(const xAOD::Egamma *eg)
is the object an electron (not Fwd)
Definition: EgammaxAODHelpers.cxx:12
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
CopyTruthJetParticles::setBarCodeFromMetaDataCheck
int setBarCodeFromMetaDataCheck() const
Definition: CopyTruthJetParticles.cxx:141
calibdata.exception
exception
Definition: calibdata.py:496
HepMC::uniqueID
int uniqueID(const T &p)
Definition: MagicNumbers.h:116
xAOD::TruthEvent_v1
Class describing a signal truth event in the MC record.
Definition: TruthEvent_v1.h:35
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CopyTruthParticles::m_truthEventKey
SG::ReadHandleKey< xAOD::TruthEventContainer > m_truthEventKey
Key for input truth event.
Definition: CopyTruthParticles.h:43
CopyTruthJetParticles::m_includePromptLeptons
Gaudi::Property< bool > m_includePromptLeptons
Definition: CopyTruthJetParticles.h:50
TruthVertex.h
CopyTruthJetParticles.h
CopyTruthJetParticles::m_dressingName
Gaudi::Property< std::string > m_dressingName
Name of the decoration to be used for identifying FSR (dressing) photons.
Definition: CopyTruthJetParticles.h:73
CopyTruthJetParticles::execute
virtual int execute() const
redefine execute so we can call our own classify() with the barcode offset for the current event.
Definition: CopyTruthJetParticles.cxx:165
CopyTruthJetParticles::m_includePromptPhotons
Gaudi::Property< bool > m_includePromptPhotons
Definition: CopyTruthJetParticles.h:52
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
createCoolChannelIdFile.par
par
Definition: createCoolChannelIdFile.py:29
MagicNumbers.h
CopyTruthJetParticles::m_includeBSMNonInt
Gaudi::Property< bool > m_includeBSMNonInt
Definition: CopyTruthJetParticles.h:44
ReadHandle.h
Handle class for reading from StoreGate.
xAOD::TruthEventBase_v1::nTruthParticles
size_t nTruthParticles() const
Get the number of truth particles.
checkTriggerxAOD.found
found
Definition: checkTriggerxAOD.py:328
CopyTruthJetParticles::m_classif
ToolHandle< IMCTruthClassifier > m_classif
Handle on MCTruthClassifier for finding prompt leptons.
Definition: CopyTruthJetParticles.h:77
AthAnalysisHelper.h
MC::isStable
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
Definition: HepMCHelpers.h:45
CopyTruthJetParticles::classifyJetInput
bool classifyJetInput(const xAOD::TruthParticle *tp, std::vector< const xAOD::TruthParticle * > &promptLeptons, std::map< const xAOD::TruthParticle *, unsigned int > &tc_results) const
Redefine our own Classifier function(s)
Definition: CopyTruthJetParticles.cxx:47
MCTruthPartClassifier::isPrompt
int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays=true)
Definition: TruthClassifiers.h:180
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MCTruthPartClassifier
Definition: TruthClassifiers.h:12
ConstDataVector
DataVector adapter that acts like it holds const pointers.
Definition: ConstDataVector.h:76
CopyTruthParticles::m_ptmin
Gaudi::Property< float > m_ptmin
Minimum pT for particle selection (in MeV)
Definition: CopyTruthParticles.h:40
xAOD::EgammaHelpers::isPhoton
bool isPhoton(const xAOD::Egamma *eg)
is the object a photon
Definition: EgammaxAODHelpers.cxx:21
CopyTruthJetParticles::m_vetoPDG_IDs
Gaudi::Property< std::vector< int > > m_vetoPDG_IDs
Definition: CopyTruthJetParticles.h:68
CopyTruthJetParticles::initialize
virtual StatusCode initialize()
Function initialising the tool.
Definition: CopyTruthJetParticles.cxx:36
MC::isInteracting
bool isInteracting(const T &p)
Identify if the particle with given PDG ID would not interact with the detector, i....
Definition: HepMCHelpers.h:33
CopyTruthParticles
Definition: CopyTruthParticles.h:18
CopyTruthJetParticles::getTCresult
unsigned int getTCresult(const xAOD::TruthParticle *tp, std::map< const xAOD::TruthParticle *, unsigned int > &tc_results) const
Definition: CopyTruthJetParticles.cxx:131
MC::isZeroEnergyPhoton
bool isZeroEnergyPhoton(const T &p)
Identify a photon with zero energy. Probably a workaround for a generator bug.
Definition: HepMCHelpers.h:71
CopyTruthJetParticles::m_includeNu
Gaudi::Property< bool > m_includeNu
Definition: CopyTruthJetParticles.h:46
TruthEventContainer.h
checker_macros.h
Define macros for attributes used to control the static checker.
HepMCHelpers.h
AthAnalysisHelper::retrieveMetadata
static std::string retrieveMetadata(const std::string &folder, const std::string &key, const ServiceHandle< StoreGateSvc > &inputMetaStore)
method that always returns as a string you can use from, e.g, pyROOT with evt = ROOT....
Definition: AthAnalysisHelper.h:254
CopyTruthJetParticles::CopyTruthJetParticles
CopyTruthJetParticles(const std::string &name)
Constructor.
Definition: CopyTruthJetParticles.cxx:34
isMuon
bool isMuon(const T &p)
Definition: AtlasPID.h:184