Skip to content
Snippets Groups Projects
Commit 24f177d2 authored by Vakhtang Tsulaia's avatar Vakhtang Tsulaia
Browse files

Merge branch 'egammaTruthAssociationAlg_reentrant_ATLASRECTS-5840' into 'master'

ATLASRECTS-5840 :  Make egammaTruthAssociationAlg re-entrant

See merge request !39491
parents 107c1f5e bb3e2245
No related branches found
No related tags found
6 merge requests!58791DataQualityConfigurations: Modify L1Calo config for web display,!46784MuonCondInterface: Enable thread-safety checking.,!46776Updated LArMonitoring config file for WD to match new files produced using MT,!45405updated ART test cron job,!42417Draft: DIRE and VINCIA Base Fragments for Pythia 8.3,!39491ATLASRECTS-5840 : Make egammaTruthAssociationAlg re-entrant
/*
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
#include "egammaTruthAssociationAlg.h"
......@@ -19,7 +19,7 @@ using PhotonLink_t = ElementLink<xAOD::PhotonContainer>;
egammaTruthAssociationAlg::egammaTruthAssociationAlg(const std::string& name,
ISvcLocator* pSvcLocator)
: AthAlgorithm(name, pSvcLocator)
: AthReentrantAlgorithm(name, pSvcLocator)
{}
egammaTruthAssociationAlg::~egammaTruthAssociationAlg() {}
......@@ -32,7 +32,8 @@ egammaTruthAssociationAlg::initialize()
// initialize the data handles
ATH_CHECK(m_truthEventContainerKey.initialize(m_doEgammaTruthContainer));
ATH_CHECK(m_egammaTruthParticleContainerKey.initialize(m_doEgammaTruthContainer));
ATH_CHECK(
m_egammaTruthParticleContainerKey.initialize(m_doEgammaTruthContainer));
ATH_CHECK(m_truthParticleContainerKey.initialize());
// Now the standard decoration handles
......@@ -73,77 +74,105 @@ egammaTruthAssociationAlg::finalize()
}
StatusCode
egammaTruthAssociationAlg::execute_r(const EventContext& ctx) const
egammaTruthAssociationAlg::execute(const EventContext& ctx) const
{
SG::WriteHandle<xAOD::TruthParticleContainer> egammaTruthContainer;
if (m_doEgammaTruthContainer) {
egammaTruthContainer =
SG::WriteHandle<xAOD::TruthParticleContainer>(m_egammaTruthParticleContainerKey, ctx);
ATH_CHECK(egammaTruthContainer.record(std::make_unique<xAOD::TruthParticleContainer>(),
std::make_unique<xAOD::TruthParticleAuxContainer>()));
egammaTruthContainer = SG::WriteHandle<xAOD::TruthParticleContainer>(
m_egammaTruthParticleContainerKey, ctx);
ATH_CHECK(egammaTruthContainer.record(
std::make_unique<xAOD::TruthParticleContainer>(),
std::make_unique<xAOD::TruthParticleAuxContainer>()));
// Add a copy of electrons and photons to the truth egamma container
SG::ReadHandle<xAOD::TruthEventContainer> truthEvtContainer(m_truthEventContainerKey, ctx);
SG::ReadHandle<xAOD::TruthEventContainer> truthEvtContainer(
m_truthEventContainerKey, ctx);
// only for serial running. Can remove check later
if (!truthEvtContainer.isValid() || truthEvtContainer->empty()) {
ATH_MSG_WARNING("Could not retrieve " << m_truthEventContainerKey.key()
<< " or container empty, returning");
ATH_MSG_WARNING("Could not retrieve "
<< m_truthEventContainerKey.key()
<< " or container empty, returning");
return StatusCode::SUCCESS;
}
for (const auto& truthParticleLink : truthEvtContainer->front()->truthParticleLinks()) {
for (const auto& truthParticleLink :
truthEvtContainer->front()->truthParticleLinks()) {
if (!truthParticleLink.isValid())
continue;
const xAOD::TruthParticle* truthParticle = *truthParticleLink;
if (!isPromptEgammaParticle(truthParticle))
continue;
getNewTruthParticle(*egammaTruthContainer, truthParticle, truthParticleLink.getDataPtr());
getNewTruthParticle(
*egammaTruthContainer, truthParticle, truthParticleLink.getDataPtr());
}
}
// Decorate containers with truth info, including links to truth particles
// Decorate the truth particles with links to the reco ones
// note that in multithreading this must be valid; can't just fail with success.
SG::ReadHandle<xAOD::TruthParticleContainer> truthParticles(m_truthParticleContainerKey, ctx);
// note that in multithreading this must be valid; can't just fail with
// success.
SG::ReadHandle<xAOD::TruthParticleContainer> truthParticles(
m_truthParticleContainerKey, ctx);
// accessors
static const SG::AuxElement::Accessor<ClusterLink_t> accClusLink("recoClusterLink");
static const SG::AuxElement::Accessor<ElectronLink_t> accElLink("recoElectronLink");
static const SG::AuxElement::Accessor<PhotonLink_t> accPhLink("recoPhotonLink");
static const SG::AuxElement::Accessor<ClusterLink_t> accClusLink(
"recoClusterLink");
static const SG::AuxElement::Accessor<ElectronLink_t> accElLink(
"recoElectronLink");
static const SG::AuxElement::Accessor<PhotonLink_t> accPhLink(
"recoPhotonLink");
if (m_matchElectrons) {
ATH_MSG_DEBUG("About to match electrons");
ATH_CHECK(match(*truthParticles, m_electronDecKeys, accElLink, egammaTruthContainer.ptr()));
ATH_CHECK(match(ctx,
*truthParticles,
m_electronDecKeys,
accElLink,
egammaTruthContainer.ptr()));
}
if (m_matchPhotons) {
ATH_MSG_DEBUG("About to match photons");
ATH_CHECK(match(*truthParticles, m_photonDecKeys, accPhLink, egammaTruthContainer.ptr()));
ATH_CHECK(match(ctx,
*truthParticles,
m_photonDecKeys,
accPhLink,
egammaTruthContainer.ptr()));
}
if (m_matchClusters) {
ATH_MSG_DEBUG("About to match clusters");
ATH_CHECK(match(*truthParticles, m_clusterDecKeys, accClusLink, egammaTruthContainer.ptr()));
ATH_CHECK(match(ctx,
*truthParticles,
m_clusterDecKeys,
accClusLink,
egammaTruthContainer.ptr()));
}
if (m_matchForwardElectrons) {
ATH_MSG_DEBUG("About to match fwd electrons");
ATH_CHECK(match(*truthParticles, m_fwdElectronDecKeys, accElLink, egammaTruthContainer.ptr()));
ATH_CHECK(match(ctx,
*truthParticles,
m_fwdElectronDecKeys,
accElLink,
egammaTruthContainer.ptr()));
}
return StatusCode::SUCCESS;
}
bool
egammaTruthAssociationAlg::isPromptEgammaParticle(const xAOD::TruthParticle* truth) const
egammaTruthAssociationAlg::isPromptEgammaParticle(
const xAOD::TruthParticle* truth) const
{
if ((truth->pdgId() != 22 && abs(truth->pdgId()) != 11) || truth->status() == 2 ||
truth->status() == 3 || truth->barcode() > m_barcodeOffset || truth->pt() < m_minPt){
if ((truth->pdgId() != 22 && abs(truth->pdgId()) != 11) ||
truth->status() == 2 || truth->status() == 3 ||
truth->barcode() > m_barcodeOffset || truth->pt() < m_minPt) {
return false;
}
......@@ -185,10 +214,14 @@ egammaTruthAssociationAlg::getNewTruthParticle(
truthParticle->setProdVtxLink(truth->prodVtxLink());
truthParticle->setDecayVtxLink(truth->decayVtxLink());
static const SG::AuxElement::Accessor<ClusterLink_t> accClusLink("recoClusterLink");
static const SG::AuxElement::Accessor<ElectronLink_t> accElLink("recoElectronLink");
static const SG::AuxElement::Accessor<PhotonLink_t> accPhLink("recoPhotonLink");
static const SG::AuxElement::Accessor<TruthLink_t> accTruthLink("truthParticleLink");
static const SG::AuxElement::Accessor<ClusterLink_t> accClusLink(
"recoClusterLink");
static const SG::AuxElement::Accessor<ElectronLink_t> accElLink(
"recoElectronLink");
static const SG::AuxElement::Accessor<PhotonLink_t> accPhLink(
"recoPhotonLink");
static const SG::AuxElement::Accessor<TruthLink_t> accTruthLink(
"truthParticleLink");
static const SG::AuxElement::Accessor<int> accType("truthType");
static const SG::AuxElement::Accessor<int> accOrigin("truthOrigin");
......@@ -213,7 +246,7 @@ egammaTruthAssociationAlg::getEgammaTruthParticle(
const xAOD::TruthParticle* truth,
xAOD::TruthParticleContainer& egammaTruthContainer) const
{
if (!truth){
if (!truth) {
return nullptr;
}
// Find the original truth particle for electrons from conversions
......@@ -226,7 +259,7 @@ egammaTruthAssociationAlg::getEgammaTruthParticle(
}
// In case truth became null in the above loop
if (!truth){
if (!truth) {
return nullptr;
}
for (auto egammaTruth : egammaTruthContainer) {
......@@ -240,8 +273,9 @@ egammaTruthAssociationAlg::getEgammaTruthParticle(
//// The templated functions
template<class T>
StatusCode
egammaTruthAssociationAlg::initializeDecorKeys(SG::WriteDecorHandleKeyArray<T>& keys,
const std::string& name)
egammaTruthAssociationAlg::initializeDecorKeys(
SG::WriteDecorHandleKeyArray<T>& keys,
const std::string& name)
{
if (!keys.empty()) {
ATH_MSG_FATAL("The WriteDecorHandle should not be configured directly.");
......@@ -258,16 +292,17 @@ egammaTruthAssociationAlg::initializeDecorKeys(SG::WriteDecorHandleKeyArray<T>&
// constructor
template<class T>
egammaTruthAssociationAlg::writeDecorHandles<T>::writeDecorHandles(
const SG::WriteDecorHandleKeyArray<T>& hkeys)
: el(hkeys.at(0))
, type(hkeys.at(1))
, origin(hkeys.at(2))
const SG::WriteDecorHandleKeyArray<T>& hkeys,const EventContext& ctx)
: el(hkeys.at(0),ctx)
, type(hkeys.at(1),ctx)
, origin(hkeys.at(2),ctx)
{}
template<class T>
egammaTruthAssociationAlg::MCTruthInfo_t
egammaTruthAssociationAlg::particleTruthClassifier(const T* particle,
Cache* extrapolationCache) const
egammaTruthAssociationAlg::particleTruthClassifier(
const T* particle,
Cache* extrapolationCache) const
{
MCTruthInfo_t info;
IMCTruthClassifier::Info mcinfo;
......@@ -283,17 +318,20 @@ egammaTruthAssociationAlg::particleTruthClassifier(const T* particle,
* second pass based on the cluster to find true photons **/
template<>
egammaTruthAssociationAlg::MCTruthInfo_t
egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>(const xAOD::Electron* electron,
Cache* extrapolationCache) const
egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>(
const xAOD::Electron* electron,
Cache* extrapolationCache) const
{
MCTruthInfo_t info;
IMCTruthClassifier::Info mcinfo;
mcinfo.extrapolationCache = extrapolationCache;
auto ret = m_mcTruthClassifier->particleTruthClassifier(electron, &mcinfo);
if (ret.first == MCTruthPartClassifier::Unknown &&
!xAOD::EgammaHelpers::isFwdElectron(electron) && electron->caloCluster()) {
!xAOD::EgammaHelpers::isFwdElectron(electron) &&
electron->caloCluster()) {
ATH_MSG_DEBUG("Trying cluster-based truth classification for electron");
ret = m_mcTruthClassifier->particleTruthClassifier(electron->caloCluster(), &mcinfo);
ret = m_mcTruthClassifier->particleTruthClassifier(electron->caloCluster(),
&mcinfo);
}
info.genPart = mcinfo.genPart;
info.first = ret.first;
......@@ -303,13 +341,15 @@ egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>(const xAOD::E
template<class T, class L>
StatusCode
egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer& truthParticles,
const SG::WriteDecorHandleKeyArray<T>& hkeys,
const SG::AuxElement::Accessor<L>& linkAccess,
xAOD::TruthParticleContainer* egammaTruthContainer) const
egammaTruthAssociationAlg::match(
const EventContext& ctx,
const xAOD::TruthParticleContainer& truthParticles,
const SG::WriteDecorHandleKeyArray<T>& hkeys,
const SG::AuxElement::Accessor<L>& linkAccess,
xAOD::TruthParticleContainer* egammaTruthContainer) const
{
writeDecorHandles<T> decoHandles(hkeys);
writeDecorHandles<T> decoHandles(hkeys,ctx);
// Extrapolation Cache
Cache extrapolationCache{};
......@@ -320,14 +360,17 @@ egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer& truthPartic
const xAOD::TruthParticle* truthParticle = info.genPart;
if (truthParticle) {
ElementLink<xAOD::TruthParticleContainer> link(truthParticle, truthParticles);
ATH_MSG_DEBUG("Decorating object with link to truth, index = " << link.index());
ElementLink<xAOD::TruthParticleContainer> link(
truthParticle, truthParticles, ctx);
ATH_MSG_DEBUG(
"Decorating object with link to truth, index = " << link.index());
decoHandles.el(*particle) = link;
} else {
decoHandles.el(*particle) = ElementLink<xAOD::TruthParticleContainer>();
}
decoHandles.el(*particle).toPersistent();
ATH_MSG_DEBUG("truthType = " << info.first << " truthOrigin = " << info.second);
ATH_MSG_DEBUG("truthType = " << info.first
<< " truthOrigin = " << info.second);
decoHandles.type(*particle) = static_cast<int>(info.first);
decoHandles.origin(*particle) = static_cast<int>(info.second);
......@@ -337,11 +380,14 @@ egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer& truthPartic
ATH_MSG_ERROR("The egammaTruthContainer needs to be valid");
return StatusCode::FAILURE;
}
const xAOD::TruthParticle* truth = xAOD::TruthHelpers::getTruthParticle(*particle);
const xAOD::TruthParticle* truth =
xAOD::TruthHelpers::getTruthParticle(*particle);
if (truth) {
xAOD::TruthParticle* truthEgamma = getEgammaTruthParticle(truth, *egammaTruthContainer);
xAOD::TruthParticle* truthEgamma =
getEgammaTruthParticle(truth, *egammaTruthContainer);
if (truthEgamma) {
// we found a truthEgamma object we should annotate if this is the best link
// we found a truthEgamma object we should annotate if this is the
// best link
bool annotateLink = true; // by default we annotate
const auto link = linkAccess(*truthEgamma); // what already exists
if (link.isValid()) {
......@@ -351,13 +397,14 @@ egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer& truthPartic
std::abs(particle->e() / truthEgamma->e() - 1)) {
ATH_MSG_DEBUG(truthEgamma
<< ": "
<< " already set to a better matched particle: " << particle);
<< " already set to a better matched particle: "
<< particle);
annotateLink = false;
}
}
if (annotateLink) {
L link(particle, *decoHandles.readHandle());
L link(particle, *decoHandles.readHandle(), ctx);
linkAccess(*truthEgamma) = link;
linkAccess(*truthEgamma).toPersistent();
}
......
......@@ -5,7 +5,7 @@
#ifndef EGAMMAALGS_EGAMMATRUTHASSOCIATIONALG_H
#define EGAMMAALGS_EGAMMATRUTHASSOCIATIONALG_H
#include "AthenaBaseComps/AthAlgorithm.h"
#include "AthenaBaseComps/AthReentrantAlgorithm.h"
#include "GaudiKernel/EventContext.h"
#include "GaudiKernel/ToolHandle.h"
#include "MCTruthClassifier/IMCTruthClassifier.h"
......@@ -38,7 +38,7 @@
@author B. Lenzi J. Mitrevski C. Anastopoulos
*/
class egammaTruthAssociationAlg : public AthAlgorithm
class egammaTruthAssociationAlg : public AthReentrantAlgorithm
{
public:
......@@ -56,13 +56,7 @@ public:
virtual StatusCode finalize() override final;
/** @brief execute on container */
virtual StatusCode execute() override final
{
return execute_r(Algorithm::getContext());
}
// This will become the normal execute when
// inheriting from AthReentrantAlgorithm
StatusCode execute_r(const EventContext& ctx) const;
virtual StatusCode execute(const EventContext& ctx) const override final;
private:
struct MCTruthInfo_t
......@@ -82,8 +76,8 @@ private:
template<class T>
struct writeDecorHandles
{
writeDecorHandles(
const SG::WriteDecorHandleKeyArray<T>& keys); // constructor
writeDecorHandles(const SG::WriteDecorHandleKeyArray<T>& keys,
const EventContext& ctx); // constructor
SG::WriteDecorHandle<T, ElementLink<xAOD::TruthParticleContainer>> el;
SG::WriteDecorHandle<T, int> type;
......@@ -97,7 +91,8 @@ private:
* info and decorate the truth particles with links to the reco ones
* (reco<typeName>Link) **/
template<class T, class L>
StatusCode match(const xAOD::TruthParticleContainer& truthParticles,
StatusCode match(const EventContext& ctx,
const xAOD::TruthParticleContainer& truthParticles,
const SG::WriteDecorHandleKeyArray<T>& hkeys,
const SG::AuxElement::Accessor<L>& linkAccess,
xAOD::TruthParticleContainer* egammaTruthContainer) const;
......@@ -110,9 +105,10 @@ private:
/** @brief Create a copy a truth particle, add it to the new container and
* decorate it with a link to the original particle **/
void getNewTruthParticle(xAOD::TruthParticleContainer& egammaTruthContainer,
const xAOD::TruthParticle* truth,
const xAOD::TruthParticleContainer* oldContainer) const;
void getNewTruthParticle(
xAOD::TruthParticleContainer& egammaTruthContainer,
const xAOD::TruthParticle* truth,
const xAOD::TruthParticleContainer* oldContainer) const;
/** @brief Return true if the truth particle is a prompt electron or photon
* **/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment