diff --git a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/CMakeLists.txt b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/CMakeLists.txt index d6c61ad880e412aac0994014cbfe7459bd343ded..aadd21bdfc4e8af3aa42590fd7b5cee00353af3b 100644 --- a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/CMakeLists.txt +++ b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/CMakeLists.txt @@ -37,6 +37,12 @@ atlas_add_test( GenParticleGenericFilter_test INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS} ${HEPMC_INCLUDE_DIRS} LINK_LIBRARIES ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} ${HEPMC_LIBRARIES} AthenaBaseComps ) +# Tests +atlas_add_test( GenParticleInteractingFilter_test + SOURCES test/GenParticleInteractingFilter_test.cxx src/GenParticleInteractingFilter.cxx + INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS} ${HEPMC_INCLUDE_DIRS} + LINK_LIBRARIES ${GTEST_LIBRARIES} ${GMOCK_LIBRARIES} ${HEPMC_LIBRARIES} AthenaBaseComps TruthUtils ) + # Install files from the package: atlas_install_headers( ISF_HepMC_Tools ) atlas_install_python_modules( python/*.py ) diff --git a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/python/ISF_HepMC_ToolsConfig.py b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/python/ISF_HepMC_ToolsConfig.py index b317e7e18c8f7a307f9a777f4ed1d41c324969ec..e504bdbc6de0746ddb2302c2c8fe1b84661dfdf3 100644 --- a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/python/ISF_HepMC_ToolsConfig.py +++ b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/python/ISF_HepMC_ToolsConfig.py @@ -84,6 +84,10 @@ def getParticlePositionFilterDynamic(name="ISF_ParticlePositionFilterDynamic", * return getParticlePositionFilterWorld(name, **kwargs) def getGenParticleInteractingFilter(name="ISF_GenParticleInteractingFilter", **kwargs): + from G4AtlasApps.SimFlags import simFlags + simdict = simFlags.specialConfiguration.get_Value() + if "InteractingPDGCodes" in simdict: + kwargs.setdefault('AdditionalInteractingParticleTypes', simdict["InteractingPDGCodes"]) return CfgMgr.ISF__GenParticleInteractingFilter(name, **kwargs) def getEtaPhiFilter(name="ISF_EtaPhiFilter", **kwargs): diff --git a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/src/GenParticleInteractingFilter.cxx b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/src/GenParticleInteractingFilter.cxx index 71c173d4750b43d9ba650bfe821bb7326899e05a..b48885d715007281faadcd718184258614ce67b3 100644 --- a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/src/GenParticleInteractingFilter.cxx +++ b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/src/GenParticleInteractingFilter.cxx @@ -21,11 +21,30 @@ ISF::GenParticleInteractingFilter::GenParticleInteractingFilter( const std::stri const IInterface* p ) : base_class(t,n,p) { + declareProperty("AdditionalInteractingParticleTypes", m_additionalInteractingParticleTypes); +} + +StatusCode ISF::GenParticleInteractingFilter::initialize() +{ + if(m_additionalInteractingParticleTypes.empty()) { + ATH_MSG_DEBUG("No additional particle types will be classified as interacting."); + } + else { + ATH_MSG_DEBUG("Will classify particles with the following additional PDG codes as interacting:"); + for(const auto& pdg_id : m_additionalInteractingParticleTypes) { + ATH_MSG_DEBUG(" " << pdg_id); + } + } + return StatusCode::SUCCESS; } /** passes through to the private version of the filter */ bool ISF::GenParticleInteractingFilter::pass(const HepMC::GenParticle& particle) const { - return !MC::isNonInteracting( &particle ); + const int& pdg_id = particle.pdg_id(); + const bool isInteracting = find(m_additionalInteractingParticleTypes.begin(), + m_additionalInteractingParticleTypes.end(), + pdg_id) != m_additionalInteractingParticleTypes.end(); + return !MC::isNonInteracting( &particle ) || isInteracting; } diff --git a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/src/GenParticleInteractingFilter.h b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/src/GenParticleInteractingFilter.h index 9f46fef89ff51feff6486bccc6b22a8146bd025f..387b4fd6cb6c1912f380b78bd3644efcf65b7cc2 100644 --- a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/src/GenParticleInteractingFilter.h +++ b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/src/GenParticleInteractingFilter.h @@ -29,7 +29,7 @@ namespace ISF { @author ZLMarshall -at- lbl.gov */ - class GenParticleInteractingFilter : public extends<AthAlgTool, IGenParticleFilter> { + class GenParticleInteractingFilter final : public extends<AthAlgTool, IGenParticleFilter> { public: //** Constructor with parameters */ @@ -38,9 +38,14 @@ namespace ISF { /** Destructor */ ~GenParticleInteractingFilter(){} + /** Framework methods */ + virtual StatusCode initialize() override; + /** passes through to the private version */ - bool pass(const HepMC::GenParticle& particle ) const; + virtual bool pass(const HepMC::GenParticle& particle ) const override; + /** Additional PDG codes to classify as interacting */ + std::vector<int> m_additionalInteractingParticleTypes; }; } diff --git a/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/test/GenParticleInteractingFilter_test.cxx b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/test/GenParticleInteractingFilter_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..975eed9a83389d5809374c01bd050851190b6177 --- /dev/null +++ b/Simulation/ISF/ISF_HepMC/ISF_HepMC_Tools/test/GenParticleInteractingFilter_test.cxx @@ -0,0 +1,189 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @author Elmar Ritsch <Elmar.Ritsch@cern.ch> + * @date October, 2016 + * @brief Tests for ISF::GenParticleInteractingFilter. + */ + +#undef NDEBUG + +// Google Test +#include "gtest/gtest.h" + +// Framework includes +#include "GaudiKernel/Bootstrap.h" +#include "GaudiKernel/IAppMgrUI.h" +#include "GaudiKernel/SmartIF.h" +#include "GaudiKernel/IToolSvc.h" +#include "GaudiKernel/ISvcLocator.h" +#include "GaudiKernel/IProperty.h" + +// tested AthAlgTool +#include "../src/GenParticleInteractingFilter.h" + +// Truth related includes +#include "HepMC/GenParticle.h" +#include "HepMC/GenVertex.h" + + +namespace ISFTesting { + +// Gaudi Test fixture that provides a clean Gaudi environment for +// each individual test case +class GaudiFixture { + +protected: + GaudiFixture() { + SetUpGaudi(); + } + + ~GaudiFixture() { + TearDownGaudi(); + } + + void SetUpGaudi() { + m_appMgr = Gaudi::createApplicationMgr(); + ASSERT_TRUE( m_appMgr!=nullptr ); + + m_svcLoc = m_appMgr; + ASSERT_TRUE( m_svcLoc.isValid() ); + + m_svcMgr = m_appMgr; + ASSERT_TRUE( m_svcMgr.isValid() ); + + m_propMgr = m_appMgr; + ASSERT_TRUE( m_propMgr.isValid() ); + ASSERT_TRUE( m_propMgr->setProperty("EvtSel", "NONE").isSuccess() ); + ASSERT_TRUE( m_propMgr->setProperty("JobOptionsType", "NONE").isSuccess() ); + + m_toolSvc = m_svcLoc->service("ToolSvc"); + ASSERT_TRUE( m_toolSvc.isValid() ); + + ASSERT_TRUE( m_appMgr->configure().isSuccess() ); + ASSERT_TRUE( m_appMgr->initialize().isSuccess() ); + } + + void TearDownGaudi() { + ASSERT_TRUE( m_appMgr->finalize().isSuccess() ); + ASSERT_TRUE( m_appMgr->terminate().isSuccess() ); + Gaudi::setInstance( static_cast<IAppMgrUI*>(nullptr) ); + } + + // protected member variables for Core Gaudi components + IAppMgrUI* m_appMgr = nullptr; + SmartIF<ISvcLocator> m_svcLoc; + SmartIF<ISvcManager> m_svcMgr; + SmartIF<IToolSvc> m_toolSvc; + SmartIF<IProperty> m_propMgr; +}; + + +// Test fixture specifically for SimKernelMT AthAlgorithm +class GenParticleInteractingFilter_test: public ::testing::Test, public GaudiFixture { + +protected: + virtual void SetUp() override { + // the tested tool + IAlgTool* tool = nullptr; + m_toolSvc->retrieveTool("ISF::GenParticleInteractingFilter/TestGenParticleInteractingFilter", tool); + m_filterTool = dynamic_cast<ISF::GenParticleInteractingFilter*>(tool); + } + + virtual void TearDown() override { + for (size_t refCount = m_filterTool->refCount(); refCount>0; refCount--) { + StatusCode sc = m_toolSvc->releaseTool(m_filterTool); + ASSERT_TRUE( sc.isSuccess() ); + } + } + + // the tested AthAlgTool + ISF::GenParticleInteractingFilter* m_filterTool; + +}; // GenParticleInteractingFilter_test fixture + + +TEST_F(GenParticleInteractingFilter_test, allPropertiesUnset_stdParticle_expectPass) { + EXPECT_TRUE( m_filterTool->initialize().isSuccess() ); + + HepMC::ThreeVector mom(1., 0., 0.); // rho=1 + mom.setTheta(150.*M_PI/180.); // eta=-1.32 + const HepMC::FourVector mom4(mom.x(), mom.y(), mom.z(), 0.); + const HepMC::GenParticle part(mom4, /*pdg id=*/11); + ASSERT_TRUE( m_filterTool->pass(part) ); +} + + +TEST_F(GenParticleInteractingFilter_test, allPropertiesUnset_stdParticle_expectNoPass) { + EXPECT_TRUE( m_filterTool->initialize().isSuccess() ); + + HepMC::ThreeVector mom(1., 0., 0.); // rho=1 + mom.setTheta(150.*M_PI/180.); // eta=-1.32 + const HepMC::FourVector mom4(mom.x(), mom.y(), mom.z(), 0.); + const HepMC::GenParticle part(mom4, /*pdg id=*/12); + ASSERT_FALSE( m_filterTool->pass(part) ); +} + + +TEST_F(GenParticleInteractingFilter_test, allPropertiesUnset_exoticParticle_expectNoPass) { + EXPECT_TRUE( m_filterTool->initialize().isSuccess() ); + + HepMC::ThreeVector mom(1., 0., 0.); // rho=1 + mom.setTheta(150.*M_PI/180.); // eta=-1.32 + const HepMC::FourVector mom4(mom.x(), mom.y(), mom.z(), 0.); + const HepMC::GenParticle part(mom4, /*pdg id=*/4110000); + + ASSERT_FALSE( m_filterTool->pass(part) ); +} + + +TEST_F(GenParticleInteractingFilter_test, stdParticle_expectPass) { + EXPECT_TRUE( m_filterTool->setProperty("AdditionalInteractingParticleTypes", "[4110000]").isSuccess() ); + EXPECT_TRUE( m_filterTool->initialize().isSuccess() ); + + HepMC::ThreeVector mom(1., 0., 0.); // rho=1 + mom.setTheta(150.*M_PI/180.); // eta=-1.32 + const HepMC::FourVector mom4(mom.x(), mom.y(), mom.z(), 0.); + const HepMC::GenParticle part(mom4, /*pdg id=*/11); + ASSERT_TRUE( m_filterTool->pass(part) ); +} + + +TEST_F(GenParticleInteractingFilter_test, stdParticle_expectNoPass) { + EXPECT_TRUE( m_filterTool->setProperty("AdditionalInteractingParticleTypes", "[4110000]").isSuccess() ); + EXPECT_TRUE( m_filterTool->initialize().isSuccess() ); + + HepMC::ThreeVector mom(1., 0., 0.); // rho=1 + mom.setTheta(150.*M_PI/180.); // eta=-1.32 + const HepMC::FourVector mom4(mom.x(), mom.y(), mom.z(), 0.); + const HepMC::GenParticle part(mom4, /*pdg id=*/12); + ASSERT_FALSE( m_filterTool->pass(part) ); +} + + +TEST_F(GenParticleInteractingFilter_test, exoticParticle_expectPass) { + EXPECT_TRUE( m_filterTool->setProperty("AdditionalInteractingParticleTypes", "[4110000]").isSuccess() ); + EXPECT_TRUE( m_filterTool->initialize().isSuccess() ); + + HepMC::ThreeVector mom(1., 0., 0.); // rho=1 + mom.setTheta(150.*M_PI/180.); // eta=-1.32 + const HepMC::FourVector mom4(mom.x(), mom.y(), mom.z(), 0.); + const HepMC::GenParticle part(mom4, /*pdg id=*/4110000); + + ASSERT_TRUE( m_filterTool->pass(part) ); +} + +} // namespace ISFTesting + + +int main(int argc, char *argv[]) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); + // if the above gets stuck forever while trying to finalize Boost stuff + // inside SGTools, try to use that: + // skips proper finalization: + //std::quick_exit( RUN_ALL_TESTS() ); +} diff --git a/Simulation/SimulationJobOptions/share/specialConfig/preInclude.Monopole.py b/Simulation/SimulationJobOptions/share/specialConfig/preInclude.Monopole.py index b145139e408e9171184d1e78f11f5ecc1c9d1a11..b9af8ac2960dd5148392247dfee48d938aa98b54 100644 --- a/Simulation/SimulationJobOptions/share/specialConfig/preInclude.Monopole.py +++ b/Simulation/SimulationJobOptions/share/specialConfig/preInclude.Monopole.py @@ -47,6 +47,8 @@ try: doG4SimConfig = False else: from G4AtlasApps.SimFlags import simFlags + if not "InteractingPDGCodes" in simFlags.specialConfiguration.get_Value(): + simFlags.specialConfiguration.get_Value()['InteractingPDGCodes'] = [4110000,-4110000] simdict = simFlags.specialConfiguration.get_Value() except: from G4AtlasApps.SimFlags import simFlags