diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/CMakeLists.txt b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/CMakeLists.txt index a66ebb0ea091e93474096a4642cef8e4d6093f73..62e1638f0b8548e7597dec9aae96af90ba0b99a6 100644 --- a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/CMakeLists.txt +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/CMakeLists.txt @@ -13,13 +13,29 @@ atlas_depends_on_subdirs( PUBLIC Tracking/TrkTools/TrkToolInterfaces PRIVATE Tracking/TrkEvent/TrkPrepRawData ) + +find_package( Boost COMPONENTS unit_test_framework ) +find_package( Eigen ) +find_package( GeoModelCore ) + # Component(s) in the package: atlas_add_component( TrkTrackCollectionMerger src/*.cxx + test/PutTrackCollectionsInSG.cxx src/components/*.cxx LINK_LIBRARIES AthenaBaseComps GaudiKernel TrkTrack TrkToolInterfaces TrkPrepRawData ) + +atlas_add_test( TrackCollectionMerger_test + SOURCES test/TrackCollectionMerger_test.cxx test/PutTrackCollectionsInSG.cxx src/TrackCollectionMerger.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: atlas_install_headers( TrkTrackCollectionMerger ) +atlas_install_joboptions( share/*.txt ) diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/TrackCollectionMerger.h b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/TrackCollectionMerger.h index fb867c0497a796cb4d28708720dab83998df3540..b4e3b5863c608ced00021e6ec16cf270e658279e 100644 --- a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/TrackCollectionMerger.h +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/TrkTrackCollectionMerger/TrackCollectionMerger.h @@ -72,7 +72,7 @@ namespace Trk { /** @brief A routine that merges the track collections. */ StatusCode mergeTrack(const TrackCollection* trackCol, - Trk::PRDtoTrackMap &prd_to_track_map, + Trk::PRDtoTrackMap *pPrdToTrackMap, TrackCollection* outputCol); MsgStream& dumptools(MsgStream& out) const; diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/share/TrackCollectionMerger_test.txt b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/share/TrackCollectionMerger_test.txt new file mode 100644 index 0000000000000000000000000000000000000000..47777c3610685c4acedace1ad4507dc96a6ca9be --- /dev/null +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/share/TrackCollectionMerger_test.txt @@ -0,0 +1,8 @@ +EventDataSvc.ForceLeaves = true; +EventDataSvc.RootCLID = 1; +ApplicationMgr.Dlls += { "AthenaServices" }; +ApplicationMgr.ExtSvc = {"StoreGateSvc"}; +ApplicationMgr.EvtMax = 1; +ApplicationMgr.EvtSel = "TestEvtSelector"; +ApplicationMgr.HistogramPersistency = "NONE"; +MessageSvc.OutputLevel = 6; \ No newline at end of file diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/TrackCollectionMerger.cxx b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/TrackCollectionMerger.cxx index 871413d07561b51c8a5541c41c6b3cdf37d461b7..9e01f0dba3ad01d603333f235b20f303cf46cecb 100644 --- a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/TrackCollectionMerger.cxx +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/TrackCollectionMerger.cxx @@ -47,14 +47,13 @@ StatusCode Trk::TrackCollectionMerger::initialize() if( m_updateSharedHitsOnly && m_updateAdditionalInfo){ msg(MSG::WARNING) << "Both UpdateAdditionalInfo and UpdateSharedHitsOnly set true - UpdateAdditionalInfo includes a shared hits update. " << endmsg; - msg(MSG::WARNING) << " If you *only* want to update shared hits, set UpdateAdditionalInfo=False and UpdateSharedHitsOnly=True" << endmsg; + msg(MSG::WARNING) << "If you *only* want to update shared hits, set UpdateAdditionalInfo=False and UpdateSharedHitsOnly=True" << endmsg; } ATH_CHECK( m_tracklocation.initialize() ); ATH_CHECK( m_outtracklocation.initialize() ); - - ATH_CHECK( m_trkSummaryTool.retrieve() ); - ATH_CHECK( m_assoTool.retrieve() ); + if (not m_trkSummaryTool.name().empty()) ATH_CHECK( m_trkSummaryTool.retrieve() ); + if (not m_assoTool.name().empty()) ATH_CHECK( m_assoTool.retrieve() ); ATH_CHECK( m_assoMapName.initialize( !m_assoMapName.key().empty() )); return StatusCode::SUCCESS; } @@ -63,10 +62,8 @@ StatusCode Trk::TrackCollectionMerger::initialize() /////////////////////////////////////////////////////////////////// // Execute /////////////////////////////////////////////////////////////////// -StatusCode Trk::TrackCollectionMerger::execute() -{ - std::unique_ptr<Trk::PRDtoTrackMap> prd_to_track_map(m_assoTool->createPRDtoTrackMap()); - +StatusCode +Trk::TrackCollectionMerger::execute(){ std::unique_ptr<TrackCollection> outputCol = m_createViewCollection ? std::make_unique<TrackCollection>(SG::VIEW_ELEMENTS) : std::make_unique<TrackCollection>(); ATH_MSG_DEBUG("Number of Track collections " << m_tracklocation.size()); @@ -76,52 +73,47 @@ StatusCode Trk::TrackCollectionMerger::execute() trackCollections.reserve(m_tracklocation.size()); size_t ttNumber = 0; for (auto& tcname : m_tracklocation){ - ///Retrieve forward tracks from StoreGate + ///Retrieve tracks from StoreGate SG::ReadHandle<TrackCollection> trackCol (tcname); trackCollections.push_back(trackCol.cptr()); ttNumber += trackCol->size(); } - + std::unique_ptr<Trk::PRDtoTrackMap> pPrdToTrackMap(m_assoTool ? m_assoTool->createPRDtoTrackMap(): nullptr); // reserve the right number of entries for the output collection outputCol->reserve(ttNumber); // merging loop for(auto& tciter : trackCollections){ // merge them in - if(mergeTrack(tciter, *prd_to_track_map, outputCol.get()).isFailure()){ + if(mergeTrack(tciter, pPrdToTrackMap.get(), outputCol.get()).isFailure()){ ATH_MSG_ERROR( "Failed to merge tracks! "); } } - ATH_MSG_DEBUG("Size of combined tracks " << outputCol->size()); - - ATH_MSG_DEBUG("Update summaries"); - // now loop over all tracks and update summaries with new shared hit counts - // @TODO magic! tracks are now non-const !?? - for (Trk::Track* trk : *outputCol) { - if (m_updateAdditionalInfo) m_trkSummaryTool->updateAdditionalInfo(*trk, prd_to_track_map.get()); - else if (m_updateSharedHitsOnly) m_trkSummaryTool->updateSharedHitCount(*trk, prd_to_track_map.get()); - else { - m_trkSummaryTool->computeAndReplaceTrackSummary(*trk, prd_to_track_map.get(), false /* DO NOT suppress hole search*/); + if (m_trkSummaryTool){ + ATH_MSG_DEBUG("Update summaries"); + // now loop over all tracks and update summaries with new shared hit counts + // @TODO magic! tracks are now non-const !?? + for (Trk::Track* trk : *outputCol) { + if (m_updateAdditionalInfo) m_trkSummaryTool->updateAdditionalInfo(*trk, pPrdToTrackMap.get()); + else if (m_updateSharedHitsOnly) m_trkSummaryTool->updateSharedHitCount(*trk, pPrdToTrackMap.get()); + else { + m_trkSummaryTool->computeAndReplaceTrackSummary(*trk, pPrdToTrackMap.get(), false /* DO NOT suppress hole search*/); + } } + } else { + ATH_MSG_WARNING("No track summary update performed because the TrackSummaryTool was not specified"); } - SG::WriteHandle<TrackCollection> h_write(m_outtracklocation); ATH_CHECK(h_write.record(std::move(outputCol))); - + // if (!m_assoMapName.key().empty()) { SG::WriteHandle<Trk::PRDtoTrackMap> write_handle(m_assoMapName); - if (write_handle.record( m_assoTool->reduceToStorableMap(std::move(prd_to_track_map))).isFailure()) { + if (write_handle.record( m_assoTool->reduceToStorableMap(std::move(pPrdToTrackMap))).isFailure()) { ATH_MSG_FATAL("Failed to add PRD to track association map."); } } - - //Print common event information - if(msgLvl(MSG::DEBUG)){ - ATH_MSG_DEBUG((*this)); - } - - + ATH_MSG_DEBUG(*this); ATH_MSG_DEBUG("Done !"); return StatusCode::SUCCESS; } @@ -199,13 +191,13 @@ std::ostream& Trk::operator << /////////////////////////////////////////////////////////////////// StatusCode Trk::TrackCollectionMerger::mergeTrack(const TrackCollection* trackCol, - Trk::PRDtoTrackMap &prd_to_track_map, + Trk::PRDtoTrackMap *pPrdToTrackMap, TrackCollection* outputCol) { - // loop over forward track, accept them and add them imto association tool + // loop over tracks, accept them and add them into association tool if(trackCol && trackCol->size()) { ATH_MSG_DEBUG("Size of track collection " << trackCol->size()); - + if (not pPrdToTrackMap) ATH_MSG_WARNING("No valid PRD to Track Map; was the association tool name missing?"); // loop over tracks for(const auto& rf: *trackCol){ // add track into output @@ -214,8 +206,8 @@ StatusCode Trk::TrackCollectionMerger::mergeTrack(const TrackCollection* trackCo Trk::Track* newTrack = m_createViewCollection ? const_cast<Trk::Track*>(rf) : new Trk::Track(*rf); outputCol->push_back(newTrack); // add tracks into PRD tool - if (m_assoTool->addPRDs(prd_to_track_map, *newTrack).isFailure()) - msg(MSG::WARNING) << "Failed to add PRDs to map" << endmsg; + if (m_assoTool and m_assoTool->addPRDs(*pPrdToTrackMap, *newTrack).isFailure()) + ATH_MSG_WARNING( "Failed to add PRDs to map" ); } } diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/components/TrkTrackCollectionMerger_entries.cxx b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/components/TrkTrackCollectionMerger_entries.cxx index d517ced21212673e6b19677885522ef7c54f3b79..5550518cd9483cf15e2e491e760a0536892e2d83 100644 --- a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/components/TrkTrackCollectionMerger_entries.cxx +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/src/components/TrkTrackCollectionMerger_entries.cxx @@ -1,4 +1,9 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + #include "TrkTrackCollectionMerger/TrackCollectionMerger.h" +#include "test/PutTrackCollectionsInSG.h" DECLARE_COMPONENT( Trk::TrackCollectionMerger ) - +DECLARE_COMPONENT( PutTrackCollectionsInSG ) diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/PutTrackCollectionsInSG.cxx b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/PutTrackCollectionsInSG.cxx new file mode 100644 index 0000000000000000000000000000000000000000..69d3f30ac5af124ed36ba46de1b593a09f085e3c --- /dev/null +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/PutTrackCollectionsInSG.cxx @@ -0,0 +1,61 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/** + * @file PutTrackCollectionsInSG.cxx + * + * @brief Implementation file for the PutTrackCollectionsInSG class + * + * @author Shaun Roe + **/ + +#include "PutTrackCollectionsInSG.h" +#include "TrkTrack/TrackCollection.h" +#include <memory> + + +PutTrackCollectionsInSG::PutTrackCollectionsInSG(const std::string& name, ISvcLocator* pSvcLocator) : + AthAlgorithm(name, pSvcLocator) +{ + //nop +} + +//Initialize +StatusCode +PutTrackCollectionsInSG::initialize() { + ATH_MSG_INFO("Calling initialize"); + return StatusCode::SUCCESS; +} + +//Execute +StatusCode +PutTrackCollectionsInSG::execute() { + auto collection1 = std::make_unique<TrackCollection>(SG::VIEW_ELEMENTS); + //note that the default c'tor should normally *not* be used and results in an invalid Track + //however, it suffices for unit testing purposes + Trk::Track *t1 = new Trk::Track(); + collection1->push_back(t1); + auto collection2 = std::make_unique<TrackCollection>(SG::VIEW_ELEMENTS); + Trk::Track *t2 = new Trk::Track(); + collection2->push_back(t2); + // + std::string collectionKey1("StoreGateSvc+TrackCollectionKey1"); + SG::WriteHandle<TrackCollection> sgTrackCollectionWriter1(collectionKey1); + ATH_MSG_INFO("Record track collection1 in SG"); + ATH_CHECK(sgTrackCollectionWriter1.record(std::move(collection1))); + // + std::string collectionKey2("StoreGateSvc+TrackCollectionKey2"); + SG::WriteHandle<TrackCollection> sgTrackCollectionWriter2(collectionKey2); + ATH_MSG_INFO("Record track collection2 in SG"); + ATH_CHECK(sgTrackCollectionWriter2.record(std::move(collection2))); + // + return StatusCode::SUCCESS; +} + +//Finalize +StatusCode +PutTrackCollectionsInSG::finalize() { + ATH_MSG_INFO("Calling finalize"); + return StatusCode::SUCCESS; +} \ No newline at end of file diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/PutTrackCollectionsInSG.h b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/PutTrackCollectionsInSG.h new file mode 100644 index 0000000000000000000000000000000000000000..47fe6a2a441a642e8a3252b3f5f6ecc8b2b0b8fb --- /dev/null +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/PutTrackCollectionsInSG.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/** +* @file PutTrackCollectionsInSG.h +* +* @brief Header file for the PutTrackCollectionsInSG class +* for testing the TrkTrackCollectionMerger +* +* @author Shaun Roe +**/ + +#ifndef PutTrackCollectionsInSG_H +#define PutTrackCollectionsInSG_H + +//Athena +#include "AthenaBaseComps/AthAlgorithm.h" + +//Gaudi + +//STL +#include <string> + +///Example algorithm to show calling the SCT_ModuleVetoSvc to exclude bad components +class PutTrackCollectionsInSG : public AthAlgorithm { + public: + PutTrackCollectionsInSG(const std::string &name,ISvcLocator *pSvcLocator) ; + virtual ~PutTrackCollectionsInSG() = default; + virtual StatusCode initialize() override; + virtual StatusCode execute() override; + virtual StatusCode finalize() override; + virtual bool isClonable() const override { return false; }; + + private: +}; //end of class + +#endif // PutTrackCollectionsInSG_H \ No newline at end of file diff --git a/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/TrackCollectionMerger_test.cxx b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/TrackCollectionMerger_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..374df157577d5f75945a442b06b1ba8d7b63b83f --- /dev/null +++ b/Tracking/TrkAlgorithms/TrkTrackCollectionMerger/test/TrackCollectionMerger_test.cxx @@ -0,0 +1,154 @@ +/* + 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/TrackCollectionMerger.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(TrackCollectionMergerTest) + 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::TrackCollectionMerger("TrackCollectionMerger",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() + +