diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/CMakeLists.txt b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/CMakeLists.txt index 62e1638f0b8548e7597dec9aae96af90ba0b99a6..d290b9d06a51eb13822d659fd3f55ceff2a7a000 100644 --- a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/CMakeLists.txt +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/CMakeLists.txt @@ -33,6 +33,12 @@ atlas_add_test( TrackCollectionMerger_test POST_EXEC_SCRIPT "nopost.sh" ) +atlas_add_test( SimpleTrackCollectionMerger_test + SOURCES test/SimpleTrackCollectionMerger_test.cxx test/PutTrackCollectionsInSG.cxx src/SimpleTrackCollectionMerger.cxx + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} + LINK_LIBRARIES TestTools ${Boost_LIBRARIES} AthenaKernel GaudiKernel SGTools StoreGateLib CxxUtils AthenaBaseComps TrkTrack TrkToolInterfaces + POST_EXEC_SCRIPT "nopost.sh" +) # Install files from the package: diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/SimpleTrackCollectionMerger.h b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/SimpleTrackCollectionMerger.h new file mode 100644 index 0000000000000000000000000000000000000000..fa531048ead8d3d6cf858a582749998f83772225 --- /dev/null +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/SimpleTrackCollectionMerger.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// SimpleTrackCollectionMerger.h +/////////////////////////////////////////////////////////////////// +#ifndef SimpleTrackCollectionMerger_H +#define SimpleTrackCollectionMerger_H + +#include <string> +#include <map> +#include "AthenaBaseComps/AthAlgorithm.h" +#include "GaudiKernel/ToolHandle.h" + +#include "TrkTrack/TrackCollection.h" + +#include "TrkToolInterfaces/IExtendedTrackSummaryTool.h" +#include "TrkToolInterfaces/IPRDtoTrackMapTool.h" +#include "TrkEventUtils/PRDtoTrackMap.h" + +#include "StoreGate/WriteHandleKey.h" +#include "StoreGate/ReadHandleKeyArray.h" + +namespace Trk { + /** @brief algorithm for track collection merging and removal of potential duplicate tracks. */ + class SimpleTrackCollectionMerger : public AthAlgorithm{ + + public: + /////////////////////////////////////////////////////////////////// + /** @brief Standard Algorithm methods: */ + /////////////////////////////////////////////////////////////////// + SimpleTrackCollectionMerger(const std::string &name, ISvcLocator *pSvcLocator); + virtual ~SimpleTrackCollectionMerger() {} + StatusCode initialize(); + StatusCode execute(); + StatusCode finalize(); + + protected: + /////////////////////////////////////////////////////////////////// + /** @brief Protected data: */ + /////////////////////////////////////////////////////////////////// + SG::ReadHandleKeyArray<TrackCollection> m_inputTracksStoregateKeys; /** Vector of track collections to be merged. */ + SG::WriteHandleKey<TrackCollection> m_combinedTracksStoregateKey ; /** Combined track collection. */ + SG::WriteHandleKey<Trk::PRDtoTrackMap> m_associationMapKey{this,"AssociationMapSG_Key",""}; ///< the key given to the newly created association map + ToolHandle<Trk::IPRDtoTrackMapTool> m_assoTool{this, "AssociationTool", "InDet::InDetPRDtoTrackMapToolGangedPixels" }; + + /////////////////////////////////////////////////////////////////// + /** @brief Protected methods: */ + /////////////////////////////////////////////////////////////////// + /** @brief A routine that merges the track collections. */ + StatusCode mergeTrack(const TrackCollection* trackCol, Trk::PRDtoTrackMap &prd_to_track_map, TrackCollection* outputCol); + MsgStream& dumptools(MsgStream& out) const; + MsgStream& dumpevent(MsgStream& out) const; + }; + MsgStream& operator << (MsgStream& , const SimpleTrackCollectionMerger&); + std::ostream& operator << (std::ostream&, const SimpleTrackCollectionMerger&); +} +#endif // SimpleTrackCollectionMerger_H diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/SimpleTrackCollectionMerger.cxx b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/SimpleTrackCollectionMerger.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4b309fcce7773162a58b2d1f16304356509b2888 --- /dev/null +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/SimpleTrackCollectionMerger.cxx @@ -0,0 +1,99 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/////////////////////////////////////////////////////////////////// +// Implementation file for class Trk::SimpleTrackCollectionMerger +/////////////////////////////////////////////////////////////////// + + +#include "GaudiKernel/MsgStream.h" +#include "TrkPrepRawData/PrepRawData.h" +#include "TrkTrackCollectionMerger/SimpleTrackCollectionMerger.h" + +/////////////////////////////////////////////////////////////////// +// Constructor +/////////////////////////////////////////////////////////////////// +Trk::SimpleTrackCollectionMerger::SimpleTrackCollectionMerger +(const std::string& name, ISvcLocator* pSvcLocator ) : + AthAlgorithm(name, pSvcLocator ){ + m_combinedTracksStoregateKey = "CombinedInDetTracks" ; + declareProperty("TracksLocation", m_inputTracksStoregateKeys ); + declareProperty("OutputTracksLocation", m_combinedTracksStoregateKey ); +} + +/////////////////////////////////////////////////////////////////// +// Initialisation +/////////////////////////////////////////////////////////////////// +StatusCode +Trk::SimpleTrackCollectionMerger::initialize(){ + ATH_MSG_DEBUG("Initializing SimpleTrackCollectionMerger"); + ATH_CHECK( m_inputTracksStoregateKeys.initialize() ); + ATH_CHECK( m_combinedTracksStoregateKey.initialize() ); + ATH_CHECK( m_assoTool.retrieve() ); + ATH_CHECK( m_associationMapKey.initialize( !m_associationMapKey.key().empty() )); + return StatusCode::SUCCESS; +} + +/////////////////////////////////////////////////////////////////// +// Execute +/////////////////////////////////////////////////////////////////// +StatusCode +Trk::SimpleTrackCollectionMerger::execute(){ + std::unique_ptr<Trk::PRDtoTrackMap> prdToTrackMap(m_assoTool->createPRDtoTrackMap()); + std::unique_ptr<TrackCollection> outputCollection = std::make_unique<TrackCollection>(SG::VIEW_ELEMENTS); + ATH_MSG_DEBUG("Number of Track collections " << m_inputTracksStoregateKeys.size()); + + // pre-loop to reserve enough space in the output collection + std::vector<const TrackCollection*> trackCollections; + trackCollections.reserve(m_inputTracksStoregateKeys.size()); + size_t totalNumberOfTracks = 0; + for (auto& sgKey : m_inputTracksStoregateKeys){ + ///Retrieve track collections from StoreGate + SG::ReadHandle<TrackCollection> thisTrackCollection (sgKey); + trackCollections.push_back(thisTrackCollection.cptr()); + totalNumberOfTracks += thisTrackCollection->size(); + } + // reserve the right number of entries for the output collection + outputCollection->reserve(totalNumberOfTracks); + // merging loop + for(auto& pThisTrackCollection : trackCollections){ + if(mergeTrack(pThisTrackCollection, *prdToTrackMap, outputCollection.get()).isFailure()){ + ATH_MSG_ERROR( "Failed to merge tracks! "); + } + } + ATH_MSG_DEBUG("Size of combined tracks " << totalNumberOfTracks); + SG::WriteHandle<TrackCollection> sgTrackCollectionWriter(m_combinedTracksStoregateKey); + ATH_CHECK(sgTrackCollectionWriter.record(std::move(outputCollection))); + return StatusCode::SUCCESS; +} + +/////////////////////////////////////////////////////////////////// +// Finalize +/////////////////////////////////////////////////////////////////// +StatusCode +Trk::SimpleTrackCollectionMerger::finalize(){ + return StatusCode::SUCCESS; +} + +/////////////////////////////////////////////////////////////////// +// Merge track collections and remove duplicates +/////////////////////////////////////////////////////////////////// +StatusCode +Trk::SimpleTrackCollectionMerger::mergeTrack(const TrackCollection* pTrackCollection, Trk::PRDtoTrackMap &prdToTrackMap,TrackCollection* outputCollection){ + // loop over tracks, accept them and add them into association tool + if(pTrackCollection and not pTrackCollection->empty()) { + ATH_MSG_DEBUG("Size of track collection " << pTrackCollection->size()); + // loop over tracks + for(const auto& pThisTrack: *pTrackCollection){ + // add track into output + Trk::Track* newTrack = const_cast<Trk::Track*>(pThisTrack); + outputCollection->push_back(newTrack); + // add tracks into PRD tool + if (m_assoTool->addPRDs(prdToTrackMap, *newTrack).isFailure()) + msg(MSG::WARNING) << "Failed to add PRDs to map" << endmsg; + } + } + return StatusCode::SUCCESS; +} + diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/components/TrkTrackCollectionMerger_entries.cxx b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/components/TrkTrackCollectionMerger_entries.cxx index 5550518cd9483cf15e2e491e760a0536892e2d83..d4cf9099fe79dfafb1978736ada3e115c347d802 100644 --- a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/components/TrkTrackCollectionMerger_entries.cxx +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/components/TrkTrackCollectionMerger_entries.cxx @@ -3,7 +3,9 @@ */ #include "TrkTrackCollectionMerger/TrackCollectionMerger.h" +#include "TrkTrackCollectionMerger/SimpleTrackCollectionMerger.h" #include "test/PutTrackCollectionsInSG.h" DECLARE_COMPONENT( Trk::TrackCollectionMerger ) +DECLARE_COMPONENT( Trk::SimpleTrackCollectionMerger ) DECLARE_COMPONENT( PutTrackCollectionsInSG ) diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/SimpleTrackCollectionMerger_test.cxx b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/SimpleTrackCollectionMerger_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c2b84549b15f6adaf5908c58f31e621d22f56f53 --- /dev/null +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/SimpleTrackCollectionMerger_test.cxx @@ -0,0 +1,153 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ +/* + */ +/** + * @file TrackCollectionMerger/test/TrackCollectionMerger_test.cxx + * @author Shaun Roe + * @date Feb, 2019 + * @brief Some tests for TrackCollectionMerger algorithm in the Boost framework + */ + + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MAIN +#define BOOST_TEST_MODULE TEST_TRKTRACKCOLLECTIONMERGER +// +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Woverloaded-virtual" +#include <boost/test/unit_test.hpp> + +#pragma GCC diagnostic pop + +// + +#include "GaudiKernel/ISvcLocator.h" +#include "StoreGate/StoreGateSvc.h" +#include "CxxUtils/checker_macros.h" +#include "TInterpreter.h" +// +#include "GaudiKernel/IAppMgrUI.h" +#include "GaudiKernel/SmartIF.h" +#include "GaudiKernel/SystemOfUnits.h" +#include "GaudiKernel/PhysicalConstants.h" +#include "GaudiKernel/EventContext.h" +#include "CxxUtils/ubsan_suppress.h" +#include "PutTrackCollectionsInSG.h" + +#include "StoreGate/ReadHandleKey.h" +#include "TrkTrack/TrackCollection.h" +#include "../TrkTrackCollectionMerger/SimpleTrackCollectionMerger.h" +#include <vector> + +ATLAS_NO_CHECK_FILE_THREAD_SAFETY; // This test uses global svcLoc. + + +// Gaudi fixture +class GaudiFixture { + public: + ISvcLocator * + svcLoc(){ + return m_svcLoc; + } + + StoreGateSvc* + storeGateSvc(){ + return m_sg; + } + + GaudiFixture(const std::string & joPath = "TrkTrackCollectionMerger/TrackCollectionMerger_test.txt") { + setUpGaudi(joPath); + } + + ~GaudiFixture() { + tearDownGaudi(); + } + + private: + void + setUpGaudi(const std::string & joPath) { + CxxUtils::ubsan_suppress ([]() { TInterpreter::Instance(); } ); + m_appMgr = Gaudi::createApplicationMgr(); + m_svcLoc = m_appMgr; + m_svcMgr = m_appMgr; + m_propMgr = m_appMgr; + m_propMgr->setProperty( "EvtSel", "NONE" ).ignore() ; + m_propMgr->setProperty( "JobOptionsType", "FILE" ).ignore(); + //"TrkTrackCollectionMerger/TrackCollectionMerger_test.txt" + m_propMgr->setProperty( "JobOptionsPath", joPath ).ignore(); + m_toolSvc = m_svcLoc->service("ToolSvc"); + m_appMgr->configure().ignore(); + m_appMgr->initialize().ignore(); + m_sg = nullptr; + m_svcLoc->service ("StoreGateSvc", m_sg).ignore(); + } + + void + tearDownGaudi() { + m_svcMgr->finalize().ignore(); + m_appMgr->finalize().ignore(); + m_appMgr->terminate().ignore(); + m_svcLoc->release(); + m_svcMgr->release(); + Gaudi::setInstance( static_cast<IAppMgrUI*>(nullptr) ); + } + + StoreGateSvc* + evtStore(){ + return m_sg; + } + + //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; + StoreGateSvc* m_sg{ nullptr }; + }; + + +BOOST_AUTO_TEST_SUITE(SimpleTrackCollectionMergerTest) + GaudiFixture g("TrkTrackCollectionMerger/TrackCollectionMerger_test.txt"); + auto pSvcLoc=g.svcLoc(); + + BOOST_AUTO_TEST_CASE( sanityCheck ){ + const bool svcLocatorIsOk=(pSvcLoc != nullptr); + BOOST_TEST(svcLocatorIsOk); + } + + BOOST_AUTO_TEST_CASE(Execute){ + auto pAlg = new PutTrackCollectionsInSG("PutCollectionsInSG",pSvcLoc); + pAlg->addRef(); + BOOST_TEST(pAlg->execute().isSuccess()); + std::string collectionKey1("StoreGateSvc+TrackCollectionKey1"); + SG::ReadHandle<TrackCollection> thisTrackCollection1 (collectionKey1); + BOOST_TEST(thisTrackCollection1->size() == 1); + std::string collectionKey2("StoreGateSvc+TrackCollectionKey2"); + SG::ReadHandle<TrackCollection> thisTrackCollection2 (collectionKey2); + BOOST_TEST(thisTrackCollection2->size() == 1); + auto pMergeAlg = new Trk::SimpleTrackCollectionMerger("SimpleTrackCollectionMerger",pSvcLoc); + pMergeAlg->addRef(); + BOOST_TEST(pMergeAlg->setProperty("TracksLocation","['TrackCollectionKey1','TrackCollectionKey2']").isSuccess()); + //initialize() is necessary here + BOOST_TEST(pMergeAlg->initialize().isSuccess()); + BOOST_TEST(pMergeAlg->execute().isSuccess()); + std::vector<std::string> keysPresent{}; + g.storeGateSvc()->keys<TrackCollection>(keysPresent); + for (auto & n: keysPresent){ + BOOST_TEST_MESSAGE(n); + } + std::string mergedCollectionKey("CombinedInDetTracks"); + SG::ReadHandle<TrackCollection> mergedCollection (mergedCollectionKey); + BOOST_TEST(mergedCollection->size() == 2); + // + const std::vector<std::string> expectedKeys{"CombinedInDetTracks","TrackCollectionKey1", "TrackCollectionKey2"}; + g.storeGateSvc()->keys<TrackCollection>(keysPresent); + BOOST_TEST(keysPresent == expectedKeys, boost::test_tools::per_element()); + } + +BOOST_AUTO_TEST_SUITE_END() + +