13#include "AthLinks/ElementLink.h"
26BuildTruthTaus::BuildTruthTaus(
const std::string& name )
27 : AsgMetadataTool(
name)
32StatusCode BuildTruthTaus::initialize()
34 if (!m_truthMatchingMode) {
35 ATH_MSG_INFO(
"Initializing BuildTruthTaus, will generate " << m_truthTauOutputContainer.key() <<
" from " << m_truthParticleContainer.key() <<
" container" );
38 ATH_MSG_INFO(
"Initializing BuildTruthTaus in truth matching mode, using input container " << m_truthTauInputContainer.key() );
42 ATH_CHECK( m_truthTauInputContainer.initialize(m_truthMatchingMode) );
49 if (m_truthMatchingMode) {
50 if (m_truthElectronContainer.empty()) {
51 ATH_MSG_WARNING(
"Truth electron container is not available, won't perform matching to truth electrons");
53 if (m_truthMuonContainer.empty()) {
54 ATH_MSG_WARNING(
"Truth muon container is not available, won't perform matching to truth muons");
56 if (m_truthJetContainer.empty()) {
57 ATH_MSG_WARNING(
"Truth jet container is not available, won't perform matching to truth jets");
62 ATH_CHECK( m_truthTauOutputContainer.initialize(!m_truthMatchingMode) );
65 ATH_CHECK( m_originReadDecorKey.initialize(!m_truthMatchingMode) );
66 ATH_CHECK( m_typeReadDecorKey.initialize(!m_truthMatchingMode) );
67 ATH_CHECK( m_outcomeReadDecorKey.initialize(!m_truthMatchingMode) );
68 ATH_CHECK( m_classificationReadDecorKey.initialize(!m_truthMatchingMode) );
70 ATH_CHECK( m_linkDecoratorKey.initialize(!m_truthMatchingMode) );
71 ATH_CHECK( m_originDecoratorKey.initialize(!m_truthMatchingMode) );
72 ATH_CHECK( m_typeDecoratorKey.initialize(!m_truthMatchingMode) );
73 ATH_CHECK( m_outcomeDecoratorKey.initialize(!m_truthMatchingMode) );
74 ATH_CHECK( m_classificationDecoratorKey.initialize(!m_truthMatchingMode) );
77 m_bTruthTauAvailable = !m_truthTauInputContainer.empty();
79 return StatusCode::SUCCESS;
83StatusCode BuildTruthTaus::retrieveTruthTaus()
85 const EventContext& ctx = Gaudi::Hive::currentContext();
86 return retrieveTruthTausImpl (m_truthTausEvent, ctx);
90StatusCode BuildTruthTaus::retrieveTruthTaus(ITruthTausEvent& truthTausEvent,
const EventContext& ctx)
const
92 return retrieveTruthTausImpl (
dynamic_cast<TruthTausEvent&
> (truthTausEvent), ctx);
96StatusCode BuildTruthTaus::retrieveTruthTausImpl(TruthTausEvent& truthTausEvent,
const EventContext& ctx)
const
99 if (m_truthMatchingMode) {
100 if (!m_truthElectronContainer.empty()) {
102 if (!truthElectronsHandle.isValid()) {
103 ATH_MSG_ERROR (
"Could not retrieve " << truthElectronsHandle.key());
104 return StatusCode::FAILURE;
106 truthTausEvent.m_xTruthElectronContainerConst = truthElectronsHandle.cptr();
109 if (!m_truthMuonContainer.empty()) {
111 if (!truthMuonsHandle.isValid()) {
112 ATH_MSG_ERROR (
"Could not retrieve " << truthMuonsHandle.key());
113 return StatusCode::FAILURE;
115 truthTausEvent.m_xTruthMuonContainerConst = truthMuonsHandle.cptr();
118 if (!m_truthJetContainer.empty()) {
120 if (!truthJetsHandle.isValid()) {
121 ATH_MSG_ERROR (
"Could not retrieve " << truthJetsHandle.key());
122 return StatusCode::FAILURE;
124 truthTausEvent.m_xTruthJetContainerConst = truthJetsHandle.cptr();
128 if (!truthTausHandle.isValid()) {
129 ATH_MSG_ERROR (
"Could not retrieve " << truthTausHandle.key());
130 return StatusCode::FAILURE;
132 truthTausEvent.m_xTruthTauContainerConst = truthTausHandle.cptr();
137 if (!truthParticlesHandle.isValid()) {
138 ATH_MSG_ERROR (
"Could not retrieve " << truthParticlesHandle.key());
139 return StatusCode::FAILURE;
141 truthTausEvent.m_xTruthParticleContainer = truthParticlesHandle.cptr();
143 auto truthTausOutput = std::make_unique<xAOD::TruthParticleContainer>();
144 auto truthTausOutputAux = std::make_unique<xAOD::TruthParticleAuxContainer>();
145 truthTausOutput->setStore(truthTausOutputAux.get());
146 truthTausEvent.m_xTruthTauContainer = truthTausOutput.get();
148 auto writeHandle =
SG::makeHandle(m_truthTauOutputContainer, ctx);
149 ATH_CHECK(writeHandle.record(std::move(truthTausOutput), std::move(truthTausOutputAux)));
151 ATH_CHECK( buildTruthTausFromTruthParticles(truthTausEvent, ctx) );
154 return StatusCode::SUCCESS;
161BuildTruthTaus::buildTruthTausFromTruthParticles(TruthTausEvent& truthTausEvent,
const EventContext& ctx)
const
174 for (
auto xTruthParticle : *truthTausEvent.m_xTruthParticleContainer)
176 if ( xTruthParticle->isTau() )
178 auto xTruthTau = std::make_unique<xAOD::TruthParticle>();
179 xTruthTau->makePrivateStore( *xTruthParticle );
181 if ( examineTruthTau(*xTruthTau).isFailure() )
187 truthTausEvent.m_xTruthTauContainer->push_back(std::move(xTruthTau));
191 typeDecorator(*truthTau) = typeReadDecor.isAvailable() ? typeReadDecor(*xTruthParticle) : -1234;
192 originDecorator(*truthTau) = originReadDecor.isAvailable() ? originReadDecor(*xTruthParticle) : -1234;
193 outcomeDecorator(*truthTau) = outcomeReadDecor.isAvailable() ? outcomeReadDecor(*xTruthParticle) : -1234;
194 classificationDecorator(*truthTau) = classificationReadDecor.isAvailable() ? classificationReadDecor(*xTruthParticle) : -1234;
197 ElementLink < xAOD::TruthParticleContainer > lTruthParticleLink(xTruthParticle, *truthTausEvent.m_xTruthParticleContainer, ctx);
198 linkDecorator(*truthTau) = lTruthParticleLink;
201 return StatusCode::SUCCESS;
209 return StatusCode::FAILURE;
213 TauTruthInfo truthInfo;
216 if (xDecayVertex ==
nullptr)
217 return StatusCode::FAILURE;
218 for (
size_t iOutgoingParticle = 0; iOutgoingParticle < xDecayVertex->
nOutgoingParticles(); ++iOutgoingParticle )
221 if (xTruthDaughter ==
nullptr)
223 ATH_MSG_ERROR(
"examineTruthTau: Truth daughter of tau decay was not found in "<< m_truthParticleContainer.key() <<
" container. Please ensure that this container has the full tau decay information or produce the TruthTaus container in AtlasDerivation.");
224 return StatusCode::FAILURE;
228 if ( xTruthDaughter->
isTau() )
231 return StatusCode::FAILURE;
235 examineTruthTauDecay(xTruthParticle, truthInfo).ignore();
237 if (truthInfo.m_bIsHadronicTau)
241 if ( truthInfo.m_iNChargedDaughters%2 == 0 )
243 ATH_MSG_WARNING(
"found tau with even multiplicity: " << truthInfo.m_iNChargedDaughters);
244 printDecay(xTruthParticle);
257 decPtVis(xTruthParticle) = truthInfo.m_vTruthVisTLV.Pt();
258 decEtaVis(xTruthParticle) = truthInfo.m_vTruthVisTLV.Eta();
259 decPhiVis(xTruthParticle) = truthInfo.m_vTruthVisTLV.Phi();
260 decMVis(xTruthParticle) = truthInfo.m_vTruthVisTLV.M();
262 decNumCharged(xTruthParticle) = truthInfo.m_iNChargedDaughters;
263 decNumChargedPion(xTruthParticle) = truthInfo.m_iNChargedPions;
264 decNumNeutral(xTruthParticle) = truthInfo.m_iNNeutralPions+truthInfo.m_iNNeutralOthers;
265 decNumNeutralPion(xTruthParticle) = truthInfo.m_iNNeutralPions;
268 decIsHadronicTau(xTruthParticle) = (
char)truthInfo.m_bIsHadronicTau;
270 if ( m_bWriteInvisibleFourMomentum )
272 TLorentzVector vTruthInvisTLV = xTruthParticle.
p4() - truthInfo.m_vTruthVisTLV;
277 decPtInvis(xTruthParticle) = vTruthInvisTLV.Pt();
278 decEtaInvis(xTruthParticle) = vTruthInvisTLV.Eta();
279 decPhiInvis(xTruthParticle) = vTruthInvisTLV.Phi();
280 decMInvis(xTruthParticle) = vTruthInvisTLV.M();
283 if ( m_bWriteVisibleChargedFourMomentum )
289 decPtVisCharged(xTruthParticle) = truthInfo.m_vTruthVisTLVCharged.Pt();
290 decEtaVisCharged(xTruthParticle) = truthInfo.m_vTruthVisTLVCharged.Eta();
291 decPhiVisCharged(xTruthParticle) = truthInfo.m_vTruthVisTLVCharged.Phi();
292 decMVisCharged(xTruthParticle) = truthInfo.m_vTruthVisTLVCharged.M();
295 if ( m_bWriteVisibleChargedFourMomentumComponent )
301 for(
size_t iProducts=0; iProducts < truthInfo.m_TLVCharged.size(); ++iProducts){
302 TLorentzVector iTLV_c = truthInfo.m_TLVCharged.at(iProducts);
303 vec_ptcharged.push_back(iTLV_c.Pt());
304 vec_etacharged.push_back(iTLV_c.Eta());
305 vec_phicharged.push_back(iTLV_c.Phi());
306 vec_mcharged.push_back(iTLV_c.M());
308 decCharged_pt(xTruthParticle) = std::move(vec_ptcharged);
309 decCharged_eta(xTruthParticle) = std::move(vec_etacharged);
310 decCharged_phi(xTruthParticle) = std::move(vec_phicharged);
311 decCharged_m(xTruthParticle) = std::move(vec_mcharged);
314 if ( m_bWriteVisibleNeutralFourMomentum )
320 decPtVisNeutral(xTruthParticle) = truthInfo.m_vTruthVisTLVNeutral.Pt();
321 decEtaVisNeutral(xTruthParticle) = truthInfo.m_vTruthVisTLVNeutral.Eta();
322 decPhiVisNeutral(xTruthParticle) = truthInfo.m_vTruthVisTLVNeutral.Phi();
323 decMVisNeutral(xTruthParticle) = truthInfo.m_vTruthVisTLVNeutral.M();
326 if ( m_bWriteVisibleNeutralFourMomentumComponent )
332 for(
size_t iProducts=0; iProducts < truthInfo.m_TLVNeutral.size(); ++iProducts){
333 TLorentzVector iTLV_n = truthInfo.m_TLVNeutral.at(iProducts);
334 vec_ptneutral.push_back(iTLV_n.Pt());
335 vec_etaneutral.push_back(iTLV_n.Eta());
336 vec_phineutral.push_back(iTLV_n.Phi());
337 vec_mneutral.push_back(iTLV_n.M());
339 decNeutral_pt(xTruthParticle) = std::move(vec_ptneutral);
340 decNeutral_eta(xTruthParticle) = std::move(vec_etaneutral);
341 decNeutral_phi(xTruthParticle) = std::move(vec_phineutral);
342 decNeutral_m(xTruthParticle) = std::move(vec_mneutral);
345 if ( m_bWriteDecayModeVector )
348 decDecayModeVector(xTruthParticle) = truthInfo.m_vDecayMode;
351 if ( m_bWriteVertices )
358 decDecayVertexX(xTruthParticle) = truthInfo.m_vDecayVertex.X();
359 decDecayVertexY(xTruthParticle) = truthInfo.m_vDecayVertex.Y();
360 decDecayVertexZ(xTruthParticle) = truthInfo.m_vDecayVertex.Z();
367 decProdVertexX(xTruthParticle) = truthInfo.m_vProdVertex.X();
368 decProdVertexY(xTruthParticle) = truthInfo.m_vProdVertex.Y();
369 decProdVertexZ(xTruthParticle) = truthInfo.m_vProdVertex.Z();
372 return StatusCode::SUCCESS;
377 TauTruthInfo& truthInfo)
const
382 return StatusCode::SUCCESS;
384 truthInfo.m_vDecayVertex.SetXYZ(xDecayVertex->
x(),xDecayVertex->
y(),xDecayVertex->
z());
388 truthInfo.m_vProdVertex.SetXYZ(xProdVertex->
x(),xProdVertex->
y(),xProdVertex->
z());
390 truthInfo.m_vProdVertex.SetXYZ(-1234,-1234,-1234);
393 for (
size_t iOutgoingParticle = 0; iOutgoingParticle < xDecayVertex->
nOutgoingParticles(); ++iOutgoingParticle )
396 if (xTruthDaughter ==
nullptr)
398 ATH_MSG_ERROR(
"examineTruthTauDecay: Truth daughter of tau decay was not found in "<< m_truthParticleContainer.key() <<
" container. Please ensure that this container has the full tau decay information or produce the TruthTaus container in AtlasDerivation.");
399 return StatusCode::FAILURE;
402 int iAbsPdgId = xTruthDaughter->
absPdgId();
403 int iPdgId = xTruthDaughter->
pdgId();
408 if ( iAbsPdgId != 111 && iAbsPdgId != 311 && iAbsPdgId != 310 && iAbsPdgId != 130 )
410 examineTruthTauDecay(*xTruthDaughter, truthInfo).ignore();
420 truthInfo.m_vDecayMode.push_back(iPdgId);
425 truthInfo.m_bIsHadronicTau =
true;
435 truthInfo.m_vTruthVisTLV += xTruthDaughter->
p4();
436 if ( m_bWriteVisibleChargedFourMomentum )
438 truthInfo.m_vTruthVisTLVCharged += xTruthDaughter->
p4();
439 if ( m_bWriteVisibleChargedFourMomentumComponent)
441 truthInfo.m_TLVCharged.push_back(xTruthDaughter->
p4());
442 if ( m_bWriteVisibleNeutralFourMomentum )
444 truthInfo.m_vTruthVisTLVNeutral += xTruthDaughter->
p4();
445 if ( m_bWriteVisibleNeutralFourMomentumComponent)
447 truthInfo.m_TLVNeutral.push_back(xTruthDaughter->
p4());
453 truthInfo.m_iNChargedDaughters++;
455 if (iAbsPdgId==211) truthInfo.m_iNChargedPions++;
456 else truthInfo.m_iNChargedOthers++;
462 if (iAbsPdgId==111) truthInfo.m_iNNeutralPions++;
463 else truthInfo.m_iNNeutralOthers++;
466 return StatusCode::SUCCESS;
474 if (xDecayVertex ==
nullptr)
477 for (
size_t iOutgoingParticle = 0; iOutgoingParticle < xDecayVertex->
nOutgoingParticles(); ++iOutgoingParticle )
480 if (xTruthDaughter ==
nullptr)
482 ATH_MSG_WARNING(
"Truth daughter of tau decay was not found in "<< m_truthParticleContainer.key() <<
" container. Please ensure that this container has the full tau decay information or produce the TruthTaus container in AtlasDerivation.");
486 <<
" e "<<xTruthDaughter->
e()
487 <<
" eta "<<xTruthDaughter->
p4().Eta()
488 <<
" phi "<<xTruthDaughter->
p4().Phi()
489 <<
" pdgid "<<xTruthDaughter->
pdgId()
490 <<
" status "<<xTruthDaughter->
status()
492 printDecay(*xTruthDaughter,
depth+1);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
Helper class to provide type-safe access to aux data.
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
bool isNeutrino() const
Whether the particle is a neutrino (or antineutrino).
int status() const
Status code.
bool isHadron() const
Whether the particle is a hadron.
int pdgId() const
PDG ID code.
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
bool isCharged() const
Whether the particle is electrically charged.
int absPdgId() const
Absolute PDG ID code (often useful).
bool hasProdVtx() const
Check for a production vertex on this particle.
bool hasDecayVtx() const
Check for a decay vertex on this particle.
virtual double e() const override final
The total energy of the particle.
bool isNeutral() const
Whether the particle is electrically neutral.
const TruthVertex_v1 * prodVtx() const
The production vertex of this particle.
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
bool isTau() const
Whether the particle is a tau (or antitau).
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
float z() const
Vertex longitudinal distance along the beam line form the origin.
float y() const
Vertex y displacement.
size_t nOutgoingParticles() const
Get the number of outgoing particles.
float x() const
Vertex x displacement.
std::string depth
tag string for intendation
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isDecayed(const T &p)
Identify if the particle decayed.
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
TruthVertex_v1 TruthVertex
Typedef to implementation.
TruthParticle_v1 TruthParticle
Typedef to implementation.