Skip to content
Snippets Groups Projects
Commit bb3e2245 authored by Christos Anastopoulos's avatar Christos Anastopoulos
Browse files

ATLASRECTS-5840 : Make egammaTruthAssociationAlg re-entrant

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