diff --git a/Tracking/TrkAlgorithms/TrkAmbiguitySolver/TrkAmbiguitySolver/TrkAmbiguityScore.h b/Tracking/TrkAlgorithms/TrkAmbiguitySolver/TrkAmbiguitySolver/TrkAmbiguityScore.h index e112ca6e98f251c12c2a9d27e3b46cab471586e6..dfc97b79118651caba40aef777ab125ae0224c93 100644 --- a/Tracking/TrkAlgorithms/TrkAmbiguitySolver/TrkAmbiguitySolver/TrkAmbiguityScore.h +++ b/Tracking/TrkAlgorithms/TrkAmbiguitySolver/TrkAmbiguitySolver/TrkAmbiguityScore.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ diff --git a/Tracking/TrkAlgorithms/TrkAmbiguitySolver/TrkAmbiguitySolver/TrkAmbiguitySolver.h b/Tracking/TrkAlgorithms/TrkAmbiguitySolver/TrkAmbiguitySolver/TrkAmbiguitySolver.h index 600744a934b4775cb3d5cbe2e699c63a00d8c468..37ebe6c7f566dd8c6c48b34bafa1f70ac591dfb4 100644 --- a/Tracking/TrkAlgorithms/TrkAmbiguitySolver/TrkAmbiguitySolver/TrkAmbiguitySolver.h +++ b/Tracking/TrkAlgorithms/TrkAmbiguitySolver/TrkAmbiguitySolver/TrkAmbiguitySolver.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ diff --git a/Tracking/TrkAlgorithms/TrkAmbiguitySolver/src/TrkAmbiguityScore.cxx b/Tracking/TrkAlgorithms/TrkAmbiguitySolver/src/TrkAmbiguityScore.cxx index a6e67930c9bfdbfde4d29e3f6313a305716fe8ff..f3dce3e541842313ca533b4d4d27117acb70cc5c 100644 --- a/Tracking/TrkAlgorithms/TrkAmbiguitySolver/src/TrkAmbiguityScore.cxx +++ b/Tracking/TrkAlgorithms/TrkAmbiguitySolver/src/TrkAmbiguityScore.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "TrkAmbiguitySolver/TrkAmbiguityScore.h" @@ -22,47 +22,34 @@ Trk::TrkAmbiguityScore::~TrkAmbiguityScore(void) //----------------------------------------------------------------------- StatusCode -Trk::TrkAmbiguityScore::initialize() -{ - ATH_MSG_INFO( "TrkAmbiguityScore::initialize(). " ); - +Trk::TrkAmbiguityScore::initialize(){ + ATH_MSG_VERBOSE( "TrkAmbiguityScore::initialize(). " ); ATH_CHECK(m_scoreTool.retrieve( DisableTool{m_scoreTool.empty()} )); - ATH_CHECK(m_scoredTracksKey.initialize()); ATH_CHECK(m_originTracksKey.initialize()); - return StatusCode::SUCCESS; } //------------------------------------------------------------------------- StatusCode -Trk::TrkAmbiguityScore::execute(const EventContext& ctx) const -{ +Trk::TrkAmbiguityScore::execute(const EventContext& ctx) const{ std::vector<SG::ReadHandle<TrackCollection>> handles = m_originTracksKey.makeHandles(ctx); - size_t totalsize = 0; - for (SG::ReadHandle<TrackCollection>& trackColHandle : handles) { - if (!trackColHandle.isValid()) - msg(MSG::WARNING) << "Could not retrieve tracks from "<< trackColHandle.key() << endmsg; - totalsize += trackColHandle->size(); + ATH_MSG_DEBUG(handles.size() << " handles are requested"); + if (handles.size() > 1){ + ATH_MSG_WARNING("More than one collection has been requested. Only the first collection is taken"); } - - std::vector<const Track*> originTracks; - originTracks.reserve(totalsize); - for (SG::ReadHandle<TrackCollection>& trackColHandle : handles) { - for(const Track* trk: *trackColHandle ) { - if (std::find(originTracks.begin(), originTracks.end(),trk) == originTracks.end()) { - originTracks.push_back(trk); - } - } + auto & theTrackCollectionHandle = handles.at(0); + if (not theTrackCollectionHandle.isValid()){ + ATH_MSG_FATAL( "Could not retrieve tracks from "<< theTrackCollectionHandle.key() ); + return StatusCode::FAILURE; } - + const auto & theTrackCollection = *theTrackCollectionHandle; std::unique_ptr<TracksScores> scoredTracks(new TracksScores); if (m_scoreTool.isEnabled()){ - m_scoreTool->process(&originTracks, scoredTracks.get()); - } - else{ - scoredTracks->reserve(originTracks.size()); - for(const Track* trk: originTracks ){ + m_scoreTool->process(theTrackCollection, scoredTracks.get()); + } else { + scoredTracks->reserve(theTrackCollection.size()); + for(const Track* trk: theTrackCollection ){ scoredTracks->push_back( std::pair<const Track*, float>(trk, 0));//TODO: logpT } } diff --git a/Tracking/TrkAlgorithms/TrkAmbiguitySolver/src/TrkAmbiguitySolver.cxx b/Tracking/TrkAlgorithms/TrkAmbiguitySolver/src/TrkAmbiguitySolver.cxx index d5acba4f127a3a02102ab530be1a776428ef7701..fd3a6a9c0836bca564f59d2d382c10304ed0a745 100644 --- a/Tracking/TrkAlgorithms/TrkAmbiguitySolver/src/TrkAmbiguitySolver.cxx +++ b/Tracking/TrkAlgorithms/TrkAmbiguitySolver/src/TrkAmbiguitySolver.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #include "TrkAmbiguitySolver/TrkAmbiguitySolver.h" @@ -58,8 +58,7 @@ Trk::TrkAmbiguitySolver::execute(const EventContext& ctx) const //--------------------------------------------------------------------------- StatusCode -Trk::TrkAmbiguitySolver::finalize() -{ +Trk::TrkAmbiguitySolver::finalize(){ if (m_ambiTool.isEnabled()) { m_ambiTool->statistics(); } diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/CMakeLists.txt b/Tracking/TrkTools/TrkAmbiguityProcessor/CMakeLists.txt index ce2b1e29d05078478d1ec7d085c06127e6d9513a..5e9256a66bdfab56679670c2a0ef61362b46737e 100644 --- a/Tracking/TrkTools/TrkAmbiguityProcessor/CMakeLists.txt +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/CMakeLists.txt @@ -35,13 +35,14 @@ find_package( HepPDT ) atlas_add_library( TrkAmbiguityProcessorLib src/DenseEnvironmentsAmbiguityProcessorTool.cxx src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx - + src/AmbiguityProcessorUtility.cxx + src/AmbiguityProcessorBase.cxx PUBLIC_HEADERS TrkAmbiguityProcessor PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} LINK_LIBRARIES ${ROOT_LIBRARIES} AthenaKernel AthenaBaseComps AtlasDetDescr GaudiKernel InDetPrepRawData InDetRecToolInterfaces TrkDetElementBase TrkEventPrimitives TrkParameters TrkRIO_OnTrack TrkTrack TrkTrackSummary TrkTruthData TrkFitterInterfaces TrkToolInterfaces TrkValInterfaces TrkExInterfaces TrkCaloClusterROI) atlas_add_component( TrkAmbiguityProcessor - src/SimpleAmbiguityProcessorTool.cxx src/TrackScoringTool.cxx src/TrackSelectionProcessorTool.cxx + src/SimpleAmbiguityProcessorTool.cxx src/TrackScoringTool.cxx src/TrackSelectionProcessorTool.cxx src/AmbiguityProcessorUtility.cxx src/AmbiguityProcessorBase.cxx src/components/*.cxx INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${HEPPDT_INCLUDE_DIRS} LINK_LIBRARIES ${CLHEP_LIBRARIES} ${HEPPDT_LIBRARIES} TrkAmbiguityProcessorLib ) diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorBase.cxx b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorBase.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a29225e6e389d3364906aceb719f374af6f8eca1 --- /dev/null +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorBase.cxx @@ -0,0 +1,170 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "AmbiguityProcessorBase.h" +#include "TrackScoringTool.h" +#include "AmbiguityProcessorUtility.h" + + + +namespace Trk { + AmbiguityProcessorBase::AmbiguityProcessorBase(const std::string& t, const std::string& n, const IInterface* p ): + AthAlgTool(t,n,p), + m_etaBounds{0.8, 1.6, 2.5, 4.0}, + m_stat(m_etaBounds), + m_scoringTool("Trk::TrackScoringTool/TrackScoringTool"){ + } + // + bool + AmbiguityProcessorBase::shouldTryBremRecovery(const Trk::Track & track) const{ + return m_tryBremFit and + not (track.info().trackProperties(Trk::TrackInfo::BremFit)) and + (track.trackParameters()->front()->pT() > m_pTminBrem) and + ((not m_caloSeededBrem) or track.info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI)); + } + + bool + AmbiguityProcessorBase::shouldTryBremRecovery(const Trk::Track & track, const TrackParameters * pPar) const{ + return m_tryBremFit and + (pPar->pT() > m_pTminBrem) and + ((not m_caloSeededBrem) or track.info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI)); + } + // + Track * + AmbiguityProcessorBase::refitTrack( const Trk::Track* track,Trk::PRDtoTrackMap &prdToTrackMap, Counter &stat) const{ + std::unique_ptr<Trk::Track> newTrack; + if (!m_suppressTrackFit){ + if (m_refitPrds) { + // simple case, fit PRD directly + ATH_MSG_VERBOSE ("Refit track "<<track<<" from PRDs"); + newTrack.reset(refitPrds (track,prdToTrackMap, stat)); + }else { + // ok, we fit ROTs + ATH_MSG_VERBOSE ("Refit track "<<track<<" from ROTs"); + newTrack.reset(refitRots (track,stat)); + } + } else { + newTrack = AmbiguityProcessor::createNewFitQualityTrack(*track); + } + if (newTrack) { + ATH_MSG_DEBUG ("New track "<<newTrack.get()<<" successfully fitted from "<<track); + } else { + ATH_MSG_DEBUG ("Fit failed !"); + } + return newTrack.release(); + } + // + void + AmbiguityProcessorBase::addTrack(Trk::Track* in_track,const bool fitted, + TrackScoreMap &trackScoreTrackMap, + Trk::PRDtoTrackMap &prdToTrackMap, + std::vector<std::unique_ptr<const Trk::Track> >& trackDustbin, + Counter &stat) const { + std::unique_ptr<Trk::Track> atrack(in_track); + // compute score + TrackScore score; + bool suppressHoleSearch = fitted ? m_suppressHoleSearch : true; + if (m_trackSummaryTool.isEnabled()) { + m_trackSummaryTool->computeAndReplaceTrackSummary(*atrack,&prdToTrackMap,suppressHoleSearch); + } + score = m_scoringTool->score( *atrack, suppressHoleSearch ); + // do we accept the track ? + if (score!=0){ + ATH_MSG_DEBUG ("Track ("<< atrack.get() <<") has score "<<score); + // statistic + stat.incrementCounterByRegion(CounterIndex::kNscoreOk,atrack.get()); + // add track to map, map is sorted small to big ! + trackScoreTrackMap.emplace(-score, TrackPtr(atrack.release(), fitted)); + return; + } + // do we try to recover the track ? + if (fitted and shouldTryBremRecovery(*atrack)){ + ATH_MSG_DEBUG ("Track score is zero, try to recover it via brem fit"); + // run track fit using electron hypothesis + auto bremTrack(doBremRefit(*atrack)); + if (!bremTrack){ + ATH_MSG_DEBUG ("Brem refit failed, drop track"); + // statistic + stat.incrementCounterByRegion(CounterIndex::kNscoreZeroBremRefitFailed,atrack.get()); + stat.incrementCounterByRegion(CounterIndex::kNfailedFits,atrack.get()); + // clean up + trackDustbin.push_back(std::move(atrack)); + } else { + // statistic + stat.incrementCounterByRegion(CounterIndex::kNgoodFits,bremTrack.get()); + // rerun score + if (m_trackSummaryTool.isEnabled()) { + m_trackSummaryTool->computeAndReplaceTrackSummary(*bremTrack, &prdToTrackMap,suppressHoleSearch); + } + score = m_scoringTool->score( *bremTrack, suppressHoleSearch ); + //put original track in the bin, ready to preserve a new Brem track + trackDustbin.push_back(std::move(atrack) ); + // do we accept the track ? + if (score!=0){ + ATH_MSG_DEBUG ("Brem refit successful, recovered track ("<< bremTrack.get() <<") has score "<<score); + // statistics + stat.incrementCounterByRegion(CounterIndex::kNscoreZeroBremRefit,bremTrack.get()); + // add track to map, map is sorted small to big ! + trackScoreTrackMap.emplace(-score, TrackPtr(bremTrack.release(), fitted) ); + return; + } else { + ATH_MSG_DEBUG ("Brem refit gave still track score zero, reject it"); + // statistic + stat.incrementCounterByRegion(CounterIndex::kNscoreZeroBremRefitScoreZero,bremTrack.get()); + } + } + } else { + ATH_MSG_DEBUG ("Track score is zero, reject it"); + // statistic + stat.incrementCounterByRegion(CounterIndex::kNscoreZero,atrack.get()); + trackDustbin.push_back(std::move(atrack)); + } + } + + const TrackParameters * + AmbiguityProcessorBase::getTrackParameters(const Trk::Track* track) const{ + const TrackParameters* par = track->perigeeParameters(); + if (not par) { + ATH_MSG_DEBUG ("Track ("<<track<<") has no perigee! Try any other ?"); + par = track->trackParameters()->front(); + } + if (not par) ATH_MSG_DEBUG ("Track ("<<track<<") has no Track Parameters ! No refit !"); + return par; + } + + //================================================================================================== + + Trk::Track* + AmbiguityProcessorBase::refitRots(const Trk::Track* track,Counter &stat) const{ + ATH_MSG_VERBOSE ("Refit track "<<track); + // refit using first parameter, do outliers + std::unique_ptr<Trk::Track> newTrack{}; + if (m_tryBremFit and track->info().trackProperties(Trk::TrackInfo::BremFit)){ + stat.incrementCounterByRegion(CounterIndex::kNbremFits,track); + ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit"); + newTrack = doBremRefit(*track); + } else { + stat.incrementCounterByRegion(CounterIndex::kNfits,track); + ATH_MSG_VERBOSE ("Normal track, refit"); + newTrack = fit(*track, true, m_particleHypothesis); + if ( (not newTrack) and shouldTryBremRecovery(*track)){ + stat.incrementCounterByRegion(CounterIndex::kNrecoveryBremFits,track); + ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery"); + newTrack = doBremRefit(*track); + } + } + + if(newTrack){ + stat.incrementCounterByRegion(CounterIndex::kNgoodFits,newTrack.get()); + //keeping the track of previously accumulated TrackInfo + const Trk::TrackInfo& originalInfo = track->info(); + newTrack->info().addPatternReco(originalInfo); + } else { + stat.incrementCounterByRegion(CounterIndex::kNfailedFits,track); + } + return newTrack.release(); + } + + +} \ No newline at end of file diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorBase.h b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorBase.h new file mode 100644 index 0000000000000000000000000000000000000000..4c9fec21d7c9ec61a44ee170b1a1bef2ac46fdcc --- /dev/null +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorBase.h @@ -0,0 +1,126 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef AmbiguityProcessorBase_h +#define AmbiguityProcessorBase_h + +#include "AthenaBaseComps/AthAlgTool.h" +#include "TrkToolInterfaces/ITrackAmbiguityProcessorTool.h" +#include "TrkToolInterfaces/IExtendedTrackSummaryTool.h" +#include "AmbiCounter.icc" +#include "GaudiKernel/ToolHandle.h" + +#include "TrackPtr.h" +#include "TrkEventPrimitives/TrackScore.h" + +#include <vector> +#include <map> //multimap +#include <memory> //unique_ptr +#include <mutex> //mutex + + + +namespace Trk { + //fwd declare + class ITrackScoringTool; + class Track; + class PRDtoTrackMap; + + //base class for SimpleAmbiguityProcessorTool and DenseEnvironmentsAmbiguityProcessorTool + class AmbiguityProcessorBase : public AthAlgTool, virtual public ITrackAmbiguityProcessorTool { + public: + enum class CounterIndex { + kNcandidates, + kNcandScoreZero, + kNcandDouble, + kNscoreOk, + kNscoreZeroBremRefit, + kNscoreZeroBremRefitFailed, + kNscoreZeroBremRefitScoreZero, + kNscoreZero, + kNaccepted, + kNsubTrack, + kNnoSubTrack, + kNacceptedBrem, + kNbremFits, + kNfits, + kNrecoveryBremFits, + kNgoodFits, + kNfailedFits, + kNCounter + }; + using Counter = AmbiCounter<CounterIndex>; + using TrackScoreMap = std::multimap< TrackScore, TrackPtr > ; + + // default methods + AmbiguityProcessorBase(const std::string&,const std::string&,const IInterface*); + virtual ~AmbiguityProcessorBase () = default; + protected: + // methods + // should try a Brem refit? based on track properties + bool + shouldTryBremRecovery(const Trk::Track & track) const; + + // should try a Brem refit? based on track properties and previously obtained track parameters + bool + shouldTryBremRecovery(const Trk::Track & track, const TrackParameters * pPar) const; + + // do a brem refit; implemented in the derived classes + virtual std::unique_ptr<Trk::Track> + doBremRefit(const Trk::Track & track) const = 0; + + /** refit track */ + Track * + refitTrack( const Trk::Track* track,Trk::PRDtoTrackMap &prdToTrackMap, Counter &stat) const; + + //refit PRD + virtual Trk::Track* + refitPrds( const Trk::Track* track, Trk::PRDtoTrackMap &prdToTrackMap,Counter &stat) const = 0; + + //refit ROTs + virtual Trk::Track* + refitRots( const Trk::Track* track, Counter &stat) const; + + //generic normal fit + virtual std::unique_ptr<Trk::Track> + fit(const Track &track, bool flag, Trk::ParticleHypothesis hypo) const = 0; + + void + addTrack(Trk::Track* in_track, const bool fitted, + TrackScoreMap &trackScoreTrackMap, + Trk::PRDtoTrackMap &prdToTrackMap, + std::vector<std::unique_ptr<const Trk::Track> >& trackDustbin, + Counter &stat) const; + + const TrackParameters * + getTrackParameters(const Trk::Track* track) const; + + //variables accessible to derived classes + std::vector<float> m_etaBounds; //!< eta intervals for internal monitoring + mutable std::mutex m_statMutex; + mutable Counter m_stat ATLAS_THREAD_SAFE; + /**Scoring tool + This tool is used to 'score' the tracks, i.e. to quantify what a good track is. + @todo The actual tool that is used should be configured through job options*/ + ToolHandle<ITrackScoringTool> m_scoringTool; + ToolHandle<Trk::IExtendedTrackSummaryTool> m_trackSummaryTool{this, "TrackSummaryTool", "InDetTrackSummaryToolNoHoleSearch"}; + /** brem recovery mode with brem fit ? */ + bool m_tryBremFit{}; + bool m_caloSeededBrem{}; + float m_pTminBrem{1000.}; + bool m_suppressHoleSearch{}; + // for track refit + bool m_suppressTrackFit{}; + bool m_refitPrds{}; + /** by default tracks at input get refitted */ + bool m_forceRefit{true}; + + /** read in as an integer and convert to particle hypothesis */ + /** reference: /TrkEventPrimitives/ParticleHypothesis.h **/ + int m_matEffects{3};//pion + Trk::ParticleHypothesis m_particleHypothesis{undefined}; + }; +}//namespace +#endif + diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorUtility.cxx b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorUtility.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0ab7ba28597ff53cbd37898bd598b21f0ff5eaa9 --- /dev/null +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorUtility.cxx @@ -0,0 +1,60 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "AmbiguityProcessorUtility.h" +#include "AthContainers/DataVector.h" +#include "TrkTrack/TrackStateOnSurface.h" +#include "TrkEventPrimitives/FitQuality.h" +#include "TrkTrack/TrackInfo.h" +#include "TrkTrack/Track.h" + + +namespace AmbiguityProcessor{ + TrackFilterCategory + categoriseTrack(const Trk::Track & track, const Trk::TrackScore & score, const bool dropDuplicates, const AssociationTool & associate, AssociationMap & map, DuplicationCheckSet & set){ + if (score == 0) return TrackFilterCategory::ScoreIsZero; + if (dropDuplicates){ + if(const auto & [p, uniqueTrack] = set.insert(associate->getPrdsOnTrack( map, track)); not uniqueTrack) return TrackFilterCategory::TrackIsDuplicate; + } + return TrackFilterCategory::TrackAccepted; + } + // + float + calculateFitQuality(const Trk::Track & track){ + float result{0.0}; + if (const auto quality=track.fitQuality(); quality and quality->numberDoF()>0 ){ + result = quality->chiSquared()/quality->numberDoF(); + } + return result; + } + // + std::unique_ptr<Trk::Track> + createNewFitQualityTrack(const Trk::Track & track){ + double reXi2 = 0.; + int nDF = 0; + const DataVector<const Trk::TrackStateOnSurface>* tsos = track.trackStateOnSurfaces(); + DataVector<const Trk::TrackStateOnSurface>* vecTsos = new DataVector<const Trk::TrackStateOnSurface>(); + // loop over TSOS, copy TSOS and push into vector + DataVector<const Trk::TrackStateOnSurface>::const_iterator iTsos = tsos->begin(); + DataVector<const Trk::TrackStateOnSurface>::const_iterator iTsosEnd = tsos->end(); + for ( ; iTsos != iTsosEnd ; ++iTsos) { + const Trk::TrackStateOnSurface* newTsos = new Trk::TrackStateOnSurface(**iTsos); + vecTsos->push_back(newTsos); + if((*iTsos)->type(Trk::TrackStateOnSurface::Measurement)){ //Get the chi2 and number of hits + if ((*iTsos)->fitQualityOnSurface()) { + reXi2 += (*iTsos)->fitQualityOnSurface()->chiSquared(); + nDF += (*iTsos)->fitQualityOnSurface()->numberDoF(); + } + } + } + Trk::FitQuality* fq = new Trk::FitQuality(reXi2,nDF-5); + Trk::TrackInfo info; + info.addPatternRecoAndProperties(track.info()); + Trk::TrackInfo newInfo; + newInfo.setPatternRecognitionInfo(Trk::TrackInfo::SimpleAmbiguityProcessorTool); + info.addPatternReco(newInfo); + return std::make_unique<Trk::Track>(info, vecTsos, fq); + } + +} diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorUtility.h b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorUtility.h new file mode 100644 index 0000000000000000000000000000000000000000..94bec981350da102901b6fe724fdbecbb82add14 --- /dev/null +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/AmbiguityProcessorUtility.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef AmbiguityProcessorUtility_h +#define AmbiguityProcessorUtility_h + +#include "GaudiKernel/ToolHandle.h" +#include "TrkToolInterfaces/IPRDtoTrackMapTool.h" +#include "TrkEventUtils/PRDtoTrackMap.h" +#include "TrkEventPrimitives/TrackScore.h" +#include <vector> +#include <set> +#include <array> +#include <string> +#include <memory> //unique_ptr + +namespace Trk{ + class Track; + class PrepRawData; +} + + +namespace AmbiguityProcessor{ + enum TrackFilterCategory{ ScoreIsZero, TrackIsDuplicate, TrackAccepted, nCategories}; + using AssociationTool = ToolHandle<Trk::IPRDtoTrackMapTool>; + using AssociationMap = Trk::PRDtoTrackMap; + using DuplicationCheckSet = std::set<std::vector<const Trk::PrepRawData*>> ; + // + //categorise the track as zero-score, duplicate or 'accepted' + TrackFilterCategory + categoriseTrack(const Trk::Track & track, const Trk::TrackScore & score, const bool dropDuplicates, const AssociationTool &, AssociationMap &, DuplicationCheckSet &); + // + //give appropriate text for each category + const static std::array<std::string , nCategories> debugMessage {"Score is zero, reject.", "Track is duplicate, reject.", "Track is accepted."}; + //calculate a simple chi^2/ndof + float calculateFitQuality(const Trk::Track & track); + //create a track from a new FitQuality object looping over track-state-on-surfaces to calculate + std::unique_ptr<Trk::Track> createNewFitQualityTrack(const Trk::Track & track); +}//namespace + +#endif diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.cxx b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.cxx index 0be1d65fef6fd94b47965be988d78ac8dd64479d..e6224bce632a627f675b38501de1df7c260f4bbd 100644 --- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.cxx +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.cxx @@ -17,6 +17,7 @@ #include "InDetPrepRawData/PixelCluster.h" #include "InDetPrepRawData/SCT_Cluster.h" #include "InDetIdentifier/PixelID.h" +#include "AmbiguityProcessorUtility.h" #include <cmath> #include <iterator> @@ -48,20 +49,15 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::DenseEnvironmentsAmbiguityProcesso const std::string& n, const IInterface* p ) : - AthAlgTool(t,n,p), - m_particleHypothesis{undefined}, - m_scoringTool("Trk::TrackScoringTool/TrackScoringTool"), + AmbiguityProcessorBase(t,n,p), m_extrapolatorTool("Trk::Extrapolator/AtlasExtrapolator"), - m_selectionTool("InDet::InDetDenseEnvAmbiTrackSelectionTool/InDetAmbiTrackSelectionTool"), - m_etaBounds{0.8, 1.6, 2.5, 4.0}, - m_stat(m_etaBounds){ + m_selectionTool("InDet::InDetDenseEnvAmbiTrackSelectionTool/InDetAmbiTrackSelectionTool"){ // statitics stuff m_fitterTool.push_back("Trk::KalmanFitter/InDetTrackFitter"); declareInterface<ITrackAmbiguityProcessorTool>(this); declareProperty("RefitPrds" , m_refitPrds = true); // True to allow for updated NN information to be taken into account - declareProperty("applydRcorrection" , m_applydRcorrection = false); declareProperty("MatEffects" , m_matEffects = 3); // pion declareProperty("ScoringTool" , m_scoringTool); declareProperty("SelectionTool" , m_selectionTool); @@ -123,11 +119,15 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::initialize(){ ATH_CHECK(m_dRMap.initialize() ); } - if (m_etaBounds.size() != TrackStat::nRegions) { - ATH_MSG_FATAL("There must be exactly " << (TrackStat::nRegions) << " eta bounds but " + if (m_etaBounds.size() != Counter::nRegions) { + ATH_MSG_FATAL("There must be exactly " << (Counter::nRegions) << " eta bounds but " << m_etaBounds.size() << " are set." ); return StatusCode::FAILURE; } + ATH_MSG_INFO(m_fitterTool.size()<<" fitters was/were input"); + for(const auto & i:m_fitterTool){ + ATH_MSG_INFO(i.name()); + } return sc; } //================================================================================================== @@ -164,7 +164,7 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::process(const TracksScores *trackS ATH_MSG_ERROR("Failed to retrieve prd to track map " << m_assoMapName.key() ); } } - std::vector<std::unique_ptr<const Trk::Track> > cleanup_tracks; + std::vector<std::unique_ptr<const Trk::Track> > trackDustbin; reloadHadROIs(); // going to do simple algorithm for now: // - take track with highest score @@ -173,112 +173,35 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::process(const TracksScores *trackS ATH_MSG_DEBUG ("Solving Tracks"); TrackCollection* finalTracks = new TrackCollection; { - TrackStat stat(m_etaBounds); + Counter stat(m_etaBounds); stat.newEvent(); - solveTracks(*trackScoreTrackMap, *prdToTrackMap, *finalTracks, cleanup_tracks,stat); + solveTracks(*trackScoreTrackMap, *prdToTrackMap, *finalTracks, trackDustbin,stat); { std::lock_guard<std::mutex> lock(m_statMutex); m_stat += stat; } } - if(m_applydRcorrection){ - ATH_MSG_ERROR("applydRcorrection is going to be removed."); - } return finalTracks; } -//================================================================================================== -// taking ownership of input track -void -Trk::DenseEnvironmentsAmbiguityProcessorTool::addTrack(Trk::Track* track, const bool fitted, - std::multimap<float, TrackPtr > &scoreTrackFitflagMap, - const Trk::PRDtoTrackMap &prdToTrackMap, - std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks, - TrackStat &stat) const{ - // compute score - TrackScore score; - bool suppressHoleSearch = fitted ? m_suppressHoleSearch : true; - ATH_MSG_DEBUG ("addTrack()::Fitted "<< fitted); - if (m_trackSummaryTool.isEnabled()) { - m_trackSummaryTool->computeAndReplaceTrackSummary(*track, - &prdToTrackMap, - suppressHoleSearch); - } - // @TODO create track summary for track - score = m_scoringTool->score( *track, suppressHoleSearch ); - // do we accept the track ? - if (score!=0){ - ATH_MSG_DEBUG ("Track ("<< track <<") has score "<<score); - // add track to map, map is sorted small to big ! - scoreTrackFitflagMap.emplace(-score, TrackPtr(track, fitted) ); - return; - } - // do we try to recover the track ? - if ( fitted && m_tryBremFit && - !track->info().trackProperties(Trk::TrackInfo::BremFit) && - track->trackParameters()->front()->pT() > m_pTminBrem && - (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI))){ - // - ATH_MSG_DEBUG ("Track score is zero, try to recover it via brem fit"); - // run track fit using electron hypothesis - Trk::Track* bremTrack = fit(*track,true,Trk::electron); - if (!bremTrack){ - ATH_MSG_DEBUG ("Brem refit failed, drop track"); - stat.incrementCounterByRegion(EStatType::kNscoreZeroBremRefitFailed,track); - stat.incrementCounterByRegion(EStatType::kNfailedFits,track); - // clean up - cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(track) ); - track=nullptr; - } else { - if (m_trackSummaryTool.isEnabled()) { - m_trackSummaryTool->computeAndReplaceTrackSummary(*bremTrack,&prdToTrackMap,m_suppressHoleSearch); - } - stat.incrementCounterByRegion(EStatType::kNgoodFits,bremTrack); - // rerun score - score = m_scoringTool->score( *bremTrack, suppressHoleSearch ); - cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(track) ); - track=nullptr; - // do we accept the track ? - if (score!=0){ - ATH_MSG_DEBUG ("Brem refit successful, recovered track ("<< track <<") has score "<<score); - stat.incrementCounterByRegion(EStatType::kNscoreZeroBremRefit,bremTrack); - // add track to map, map is sorted small to big ! - scoreTrackFitflagMap.emplace( -score, TrackPtr(bremTrack, true) ); - return; - } - ATH_MSG_DEBUG ("Brem refit gave still track score zero, reject it"); - stat.incrementCounterByRegion(EStatType::kNscoreZeroBremRefitScoreZero,bremTrack); - // clean up - cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(bremTrack) ); - - } - } else { - ATH_MSG_DEBUG ("Track score is zero, reject it"); - stat.incrementCounterByRegion(EStatType::kNscoreZero,track); - // @TODO can delete this track ? - cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(track) ); - } -} -//================================================================================================== - void Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScores &trackScoreTrackMap, Trk::PRDtoTrackMap &prdToTrackMap, TrackCollection &finalTracks, - std::vector<std::unique_ptr<const Trk::Track> > &cleanup_tracks, - TrackStat &stat) const{ - std::multimap<float, TrackPtr > scoreTrackFitflagMap; + std::vector<std::unique_ptr<const Trk::Track> > &trackDustbin, + Counter &stat) const{ + TrackScoreMap scoreTrackFitflagMap; for(const std::pair< const Trk::Track *, float> &scoreTrack: trackScoreTrackMap){ scoreTrackFitflagMap.emplace(scoreTrack.second, TrackPtr(scoreTrack.first) ); - stat.incrementCounterByRegion(EStatType::kNcandidates,scoreTrack.first); + stat.incrementCounterByRegion(CounterIndex::kNcandidates,scoreTrack.first); } ATH_MSG_DEBUG ("Starting to solve tracks"); // now loop as long as map is not empty while ( !scoreTrackFitflagMap.empty() ){ // get current best candidate - std::multimap<float, TrackPtr >::iterator itnext = scoreTrackFitflagMap.begin(); + TrackScoreMap::iterator itnext = scoreTrackFitflagMap.begin(); TrackPtr atrack( std::move(itnext->second) ); float ascore = itnext->first; scoreTrackFitflagMap.erase(itnext); @@ -292,15 +215,12 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScores &tr if (keepOriginal && atrack.fitted()){ // track can be kept as is and is already fitted ATH_MSG_DEBUG ("Accepted track "<<atrack.track()<<"\t has score "<<-ascore); - stat.incrementCounterByRegion(EStatType::kNaccepted, atrack.track() ); + stat.incrementCounterByRegion(CounterIndex::kNaccepted, atrack.track() ); if (m_tryBremFit && atrack.track()->info().trackProperties(Trk::TrackInfo::BremFit)) { - stat.incrementCounterByRegion(EStatType::kNacceptedBrem,atrack.track()); + stat.incrementCounterByRegion(CounterIndex::kNacceptedBrem,atrack.track()); } //Compute the fitQuality - double fitQual = 0; - if (atrack->fitQuality() && atrack->fitQuality()->numberDoF()>0 ){ - fitQual = atrack->fitQuality()->chiSquared()/atrack->fitQuality()->numberDoF(); - } + const float fitQual = AmbiguityProcessor::calculateFitQuality(*atrack); if(fitQual > 1.3 && decideIfInHighPtBROI(atrack.track())){ std::unique_ptr<Trk::Track> refittedTrack( refitTracksFromB(atrack.track(), fitQual)); //Q: Is there the case atrack == refittedTrack ? if(refittedTrack){ @@ -311,7 +231,7 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScores &tr // add to output list finalTracks.push_back( refittedTrack.release() ); if (atrack.newTrack()) { - cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(atrack.release()) ); + trackDustbin.emplace_back(atrack.release()); } } else { // add track to PRD_AssociationTool @@ -333,30 +253,30 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScores &tr } else if ( keepOriginal){ // track can be kept as is, but is not yet fitted ATH_MSG_DEBUG ("Good track("<< atrack.track() << ") but need to fit this track first, score, add it into map again and retry ! "); - Trk::Track *refittedTrack = refitTrack(atrack.track(),prdToTrackMap, stat); - if(refittedTrack) { - addTrack( refittedTrack, true , scoreTrackFitflagMap, prdToTrackMap, cleanup_tracks, stat); + Trk::Track * pRefittedTrack = refitTrack(atrack.track(),prdToTrackMap, stat); + if(pRefittedTrack) { + addTrack( pRefittedTrack, true , scoreTrackFitflagMap, prdToTrackMap, trackDustbin, stat); } // remove original copy, but delay removal since some pointer to it or its constituents may still be in used if (atrack.newTrack()) { - cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(atrack.release()) ); + trackDustbin.emplace_back(atrack.release()); } } else if ( cleanedTrack ) {//cleanedTrack != atrack ATH_MSG_DEBUG ("Candidate excluded, add subtrack to map. Track "<<cleanedTrack.get()); - stat.incrementCounterByRegion(EStatType::kNsubTrack,cleanedTrack.get()); + stat.incrementCounterByRegion(CounterIndex::kNsubTrack,cleanedTrack.get()); // for this case clenedTrack is a new created object. - addTrack(cleanedTrack.release(), false, scoreTrackFitflagMap, prdToTrackMap, cleanup_tracks, stat); + addTrack(cleanedTrack.release(), false, scoreTrackFitflagMap, prdToTrackMap, trackDustbin, stat); // remove original copy, but delay removal since some pointer to it or its constituents may still be in used if (atrack.newTrack()) { - cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(atrack.release()) ); + trackDustbin.emplace_back(atrack.release() ); } } else { // track should be discarded ATH_MSG_DEBUG ("Track "<< atrack.track() << " is excluded, no subtrack, reject"); - stat.incrementCounterByRegion(EStatType::kNnoSubTrack,atrack.track()); + stat.incrementCounterByRegion(CounterIndex::kNnoSubTrack,atrack.track()); // remove original copy, but delay removal since some pointer to it or its constituents may still be in used if (atrack.newTrack()) { - cleanup_tracks.push_back(std::unique_ptr<const Trk::Track>(atrack.release()) ); + trackDustbin.emplace_back(atrack.release()); } } } @@ -365,62 +285,12 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::solveTracks(const TracksScores &tr -//================================================================================================== -Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitTrack( const Trk::Track* track, - Trk::PRDtoTrackMap &prdToTrackMap, - TrackStat &stat) const{ - Trk::Track* newTrack = nullptr; - if (!m_suppressTrackFit){ - if (m_refitPrds) { - // simple case, fit PRD directly - ATH_MSG_VERBOSE ("Refit track "<<track<<" from PRDs"); - newTrack = refitPrds (track,prdToTrackMap, stat); - }else { - // ok, we fit ROTs - ATH_MSG_VERBOSE ("Refit track "<<track<<" from ROTs"); - newTrack = refitRots (track,stat); - } - } else { - double reXi2 = 0.; - int nDF = 0; - const DataVector<const TrackStateOnSurface>* tsos = track->trackStateOnSurfaces(); - DataVector<const TrackStateOnSurface>* vecTsos = new DataVector<const TrackStateOnSurface>(); - // loop over TSOS, copy TSOS and push into vector - DataVector<const TrackStateOnSurface>::const_iterator iTsos = tsos->begin(); - DataVector<const TrackStateOnSurface>::const_iterator iTsosEnd = tsos->end(); - for ( ; iTsos != iTsosEnd ; ++iTsos) { - const TrackStateOnSurface* newTsos = new TrackStateOnSurface(**iTsos); - vecTsos->push_back(newTsos); - if((*iTsos)->type(Trk::TrackStateOnSurface::Measurement)){ //Get the chi2 and number of hits - if ((*iTsos)->fitQualityOnSurface()) { - reXi2 += (*iTsos)->fitQualityOnSurface()->chiSquared(); - nDF += (*iTsos)->fitQualityOnSurface()->numberDoF(); - } - } - } - Trk::FitQuality* fq = new Trk::FitQuality(reXi2,nDF-5); - Trk::TrackInfo info; - info.addPatternRecoAndProperties(track->info()); - Trk::TrackInfo newInfo; - newInfo.setPatternRecognitionInfo(Trk::TrackInfo::SimpleAmbiguityProcessorTool); - info.addPatternReco(newInfo); - newTrack = new Trk::Track(info, vecTsos, fq); - } - - if (newTrack!=nullptr) { - ATH_MSG_DEBUG ("New track "<<newTrack<<" successfully fitted from "<<track); - } else { - ATH_MSG_DEBUG ("Fit failed !"); - } - return newTrack; -} - //================================================================================================== Trk::Track* Trk::DenseEnvironmentsAmbiguityProcessorTool::refitPrds( const Trk::Track* track, Trk::PRDtoTrackMap &prdToTrackMap, - TrackStat &stat) const{ + Counter &stat) const{ // get vector of PRDs // @TODO ensured that prds on track are registered for this track ? const auto & prds = m_assoTool->getPrdsOnTrack(prdToTrackMap,*track); @@ -429,86 +299,38 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::refitPrds( const Trk::Track* track return nullptr; } ATH_MSG_VERBOSE ("Track "<<track<<"\t has "<<prds.size()<<"\t PRDs"); - const TrackParameters* par = track->perigeeParameters(); - if (par==nullptr) { - ATH_MSG_DEBUG ("Track ("<<track<<") has no perigee! Try any other ?"); - par = track->trackParameters()->front(); - if (par==nullptr) { - ATH_MSG_DEBUG ("Track ("<<track<<") has no Track Parameters ! No refit !"); - return nullptr; - } - } + const TrackParameters* par = getTrackParameters(track); + if (not par) return nullptr; + // // refit using first parameter, do outliers - Trk::Track* newTrack = nullptr; - if (m_tryBremFit && track->info().trackProperties(Trk::TrackInfo::BremFit)){ - stat.incrementCounterByRegion(EStatType::kNbremFits,track); + std::unique_ptr<Trk::Track> newTrack; + if (m_tryBremFit and track->info().trackProperties(Trk::TrackInfo::BremFit)){ + stat.incrementCounterByRegion(CounterIndex::kNbremFits,track); ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit"); - // TODO revert once GlobalChi2Fitter properly handles brem fits when - // starting from prds + //revert once GlobalChi2Fitter properly handles brem fits when starting from prds // newTrack = fit(prds, *par, true, Trk::electron); - newTrack = fit(*track, true, Trk::electron); + newTrack = doBremRefit(*track); } else { - stat.incrementCounterByRegion(EStatType::kNfits,track); + stat.incrementCounterByRegion(CounterIndex::kNfits,track); ATH_MSG_VERBOSE ("Normal track, refit"); newTrack = fit(prds, *par, true, m_particleHypothesis); - if (!newTrack && m_tryBremFit && par->pT() > m_pTminBrem && - (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI))) - { - stat.incrementCounterByRegion(EStatType::kNrecoveryBremFits,track); + if ((not newTrack) and shouldTryBremRecovery(*track, par)){ + stat.incrementCounterByRegion(CounterIndex::kNrecoveryBremFits,track); ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery"); - // TODO revert once GlobalChi2Fitter properly handles brem fits when - // starting from prds - // newTrack = fit(prds, *par, true, Trk::electron); - newTrack = fit(*track, true, Trk::electron); + //revert once GlobalChi2Fitter properly handles brem fits when starting from prds + //newTrack = fit(prds, *par, true, Trk::electron); + newTrack = doBremRefit(*track); } } if(newTrack) { - stat.incrementCounterByRegion(EStatType::kNgoodFits,newTrack); + stat.incrementCounterByRegion(CounterIndex::kNgoodFits,newTrack.get()); //keeping the track of previously accumulated TrackInfo const Trk::TrackInfo& originalInfo = track->info(); newTrack->info().addPatternReco(originalInfo); } else { - stat.incrementCounterByRegion(EStatType::kNfailedFits,track); + stat.incrementCounterByRegion(CounterIndex::kNfailedFits,track); } - return newTrack; -} - -//================================================================================================== - -Trk::Track* -Trk::DenseEnvironmentsAmbiguityProcessorTool::refitRots(const Trk::Track* track, - TrackStat &stat) const{ - ATH_MSG_VERBOSE ("Refit track "<<track); - // refit using first parameter, do outliers - Trk::Track* newTrack = nullptr; - if (m_tryBremFit && - track->info().trackProperties(Trk::TrackInfo::BremFit)){ - stat.incrementCounterByRegion(EStatType::kNbremFits,track); - ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit"); - newTrack = fit(*track, true, Trk::electron); - } else { - stat.incrementCounterByRegion(EStatType::kNfits,track); - ATH_MSG_VERBOSE ("Normal track, refit"); - newTrack = fit(*track, true, m_particleHypothesis); - if (!newTrack && m_tryBremFit && - track->trackParameters()->front()->pT() > m_pTminBrem && - (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI))) - { - stat.incrementCounterByRegion(EStatType::kNrecoveryBremFits,track); - ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery"); - newTrack = fit(*track, true, Trk::electron); - } - } - - if(newTrack){ - stat.incrementCounterByRegion(EStatType::kNgoodFits,newTrack); - //keeping the track of previously accumulated TrackInfo - const Trk::TrackInfo& originalInfo = track->info(); - newTrack->info().addPatternReco(originalInfo); - } else { - stat.incrementCounterByRegion(EStatType::kNfailedFits,track); - } - return newTrack; + return newTrack.release(); } @@ -602,9 +424,10 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::storeTrkDistanceMapdR( TrackCollec // if we already have a dR for this prd, we update it, if current value is smaller if (!ret.second) { InDet::DRMap::iterator it{dRMapHandle->find(pixel)}; - if(std::sqrt(std::pow((*it).second.first,2)+std::pow((*it).second.second,2)) > (float)mindR) { - (*it).second.first = (float)mindX; - (*it).second.second = (float)mindZ; + auto &[x, z] = it->second; + if(std::sqrt(x * x + z * z) > (float)mindR) { + x = (float) mindX; + z = (float) mindZ; } } } @@ -717,19 +540,19 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::refitTracksFromB(const Trk::Track* } std::vector<const Trk::MeasurementBase*> measurementSet{}; //store all silicon measurements into the measurementset - DataVector<const Trk::TrackStateOnSurface>::const_iterator trackStateOnSurface = track->trackStateOnSurfaces()->begin(); - for ( ; trackStateOnSurface != track->trackStateOnSurfaces()->end(); ++trackStateOnSurface ) { - if ( !(*trackStateOnSurface) ){ + DataVector<const Trk::TrackStateOnSurface>::const_iterator TrackStateOnSurface = track->trackStateOnSurfaces()->begin(); + for ( ; TrackStateOnSurface != track->trackStateOnSurfaces()->end(); ++TrackStateOnSurface ) { + if ( !(*TrackStateOnSurface) ){ ATH_MSG_WARNING( "This track contains an empty MeasurementBase object that won't be included in the fit" ); continue; } - if ( (*trackStateOnSurface)->measurementOnTrack() ){ - if ( (*trackStateOnSurface)->type( Trk::TrackStateOnSurface::Measurement) ){ - const Trk::RIO_OnTrack* rio = dynamic_cast <const Trk::RIO_OnTrack*>( (*trackStateOnSurface)->measurementOnTrack() ); + if ( (*TrackStateOnSurface)->measurementOnTrack() ){ + if ( (*TrackStateOnSurface)->type( Trk::TrackStateOnSurface::Measurement) ){ + const Trk::RIO_OnTrack* rio = dynamic_cast <const Trk::RIO_OnTrack*>( (*TrackStateOnSurface)->measurementOnTrack() ); if (rio != nullptr) { const Identifier& surfaceID = (rio->identify()) ; if(m_idHelper->is_pixel(surfaceID)|| m_idHelper->is_sct(surfaceID)) { - measurementSet.push_back( (*trackStateOnSurface)->measurementOnTrack() ); + measurementSet.push_back( (*TrackStateOnSurface)->measurementOnTrack() ); } } } @@ -740,13 +563,13 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::refitTracksFromB(const Trk::Track* while (true){ removeInnerHits(measurementSet); if(measurementSet.size()>4){ - Trk::Track* refittedTrack = fit(measurementSet,*par,true,Trk::pion); + auto pRefittedTrack{fit(measurementSet,*par,true,Trk::pion)}; double fitQualPostRefit = 10; - if (refittedTrack && refittedTrack->fitQuality() && refittedTrack->fitQuality()->numberDoF()!=0 ) - fitQualPostRefit = refittedTrack->fitQuality()->chiSquared()/refittedTrack->fitQuality()->numberDoF(); + if (pRefittedTrack && pRefittedTrack->fitQuality() && pRefittedTrack->fitQuality()->numberDoF()!=0 ) + fitQualPostRefit = pRefittedTrack->fitQuality()->chiSquared()/pRefittedTrack->fitQuality()->numberDoF(); if (fitQualityOriginal/fitQualPostRefit > 1){ if ( fitQualityOriginal/fitQualPostRefit > 1.2){ - return refittedTrack; + return pRefittedTrack.release(); } } if (previousMeasSize == measurementSet.size()){ @@ -777,48 +600,53 @@ Trk::DenseEnvironmentsAmbiguityProcessorTool::dumpStat(MsgStream &out) const{ out << __func__; out << "\n"; out << "------------------------------------------------------------------------------------" << "\n"; - out << " Number of events processed : "<< m_stat.globalCount(TrackStat::nEvents) << "\n"; - if (const auto nInvalid = m_stat.globalCount(TrackStat::nInvalidTracks); nInvalid>0) { + out << " Number of events processed : "<< m_stat.globalCount(Counter::nEvents) << "\n"; + if (const auto nInvalid = m_stat.globalCount(Counter::nInvalidTracks); nInvalid>0) { out << " Number of invalid tracks : "<< nInvalid<< "\n"; } - if (const auto nNoParams = m_stat.globalCount(TrackStat::nTracksWithoutParam); nNoParams>0) { + if (const auto nNoParams = m_stat.globalCount(Counter::nTracksWithoutParam); nNoParams>0) { out << " Tracks without parameters : "<< nNoParams << "\n"; } out << " statistics by eta range ------All---Barrel---Trans.-- Endcap-- Forwrd-- " << "\n"; out << "------------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " Number of candidates at input :", EStatType::kNcandidates,iw); + out << m_stat.dumpRegions( " Number of candidates at input :", CounterIndex::kNcandidates,iw); out << "------------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " candidates with good score :", EStatType::kNscoreOk,iw); + out << m_stat.dumpRegions( " candidates with good score :", CounterIndex::kNscoreOk,iw); if (m_tryBremFit) { - out << m_stat.dumpRegions( " + recovered after brem refit :", EStatType::kNscoreZeroBremRefit,iw); + out << m_stat.dumpRegions( " + recovered after brem refit :", CounterIndex::kNscoreZeroBremRefit,iw); } - out << m_stat.dumpRegions( " candidates rejected score 0 :", EStatType::kNscoreZero,iw); + out << m_stat.dumpRegions( " candidates rejected score 0 :", CounterIndex::kNscoreZero,iw); if (m_tryBremFit) { - out << m_stat.dumpRegions( " + m refit :", EStatType::kNscoreZeroBremRefitFailed,iw); - out << m_stat.dumpRegions( " + rejected brem refit score 0 :", EStatType::kNscoreZeroBremRefitScoreZero,iw); + out << m_stat.dumpRegions( " + m refit :", CounterIndex::kNscoreZeroBremRefitFailed,iw); + out << m_stat.dumpRegions( " + rejected brem refit score 0 :", CounterIndex::kNscoreZeroBremRefitScoreZero,iw); } out << "------------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " number of normal fits :" , EStatType::kNfits,iw); + out << m_stat.dumpRegions( " number of normal fits :" , CounterIndex::kNfits,iw); if (m_tryBremFit) { - out << m_stat.dumpRegions( " + 2nd brem fit for failed fit :", EStatType::kNrecoveryBremFits,iw); - out << m_stat.dumpRegions( " normal brem fits for electrons :", EStatType::kNbremFits,iw); + out << m_stat.dumpRegions( " + 2nd brem fit for failed fit :", CounterIndex::kNrecoveryBremFits,iw); + out << m_stat.dumpRegions( " normal brem fits for electrons :", CounterIndex::kNbremFits,iw); } out << "------------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " sum of succesful fits :", EStatType::kNgoodFits,iw); - out << m_stat.dumpRegions( " sum of failed fits :", EStatType::kNfailedFits,iw); + out << m_stat.dumpRegions( " sum of succesful fits :", CounterIndex::kNgoodFits,iw); + out << m_stat.dumpRegions( " sum of failed fits :", CounterIndex::kNfailedFits,iw); out << "------------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " Number of subtracks created :", EStatType::kNsubTrack,iw); - out << m_stat.dumpRegions( " Number of candidates excluded :", EStatType::kNnoSubTrack,iw); + out << m_stat.dumpRegions( " Number of subtracks created :", CounterIndex::kNsubTrack,iw); + out << m_stat.dumpRegions( " Number of candidates excluded :", CounterIndex::kNnoSubTrack,iw); out << "------------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " Number of tracks accepted :", EStatType::kNaccepted,iw); + out << m_stat.dumpRegions( " Number of tracks accepted :", CounterIndex::kNaccepted,iw); if (m_tryBremFit) { - out << m_stat.dumpRegions( " including number of brem fits :", EStatType::kNacceptedBrem,iw); + out << m_stat.dumpRegions( " including number of brem fits :", CounterIndex::kNacceptedBrem,iw); } out << "------------------------------------------------------------------------------------" << "\n"; out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2) - << " definition: ( 0.0 < Barrel < " << m_etaBounds[TrackStat::iBarrel] << " < Transition < " << m_etaBounds[TrackStat::iTransi] - << " < Endcap < " << m_etaBounds[TrackStat::iEndcap] << " < Forward < " << m_etaBounds[TrackStat::iForwrd] << " )" << "\n"; + << " definition: ( 0.0 < Barrel < " << m_etaBounds[Counter::iBarrel] << " < Transition < " << m_etaBounds[Counter::iTransi] + << " < Endcap < " << m_etaBounds[Counter::iEndcap] << " < Forward < " << m_etaBounds[Counter::iForwrd] << " )" << "\n"; out << "------------------------------------------------------------------------------------" << "\n"; out << std::setprecision(ss); - } +} + +std::unique_ptr<Trk::Track> +Trk::DenseEnvironmentsAmbiguityProcessorTool::doBremRefit(const Trk::Track & track) const{ + return std::unique_ptr<Trk::Track>(fit(track,true,Trk::electron)); +} diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.h b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.h index 178af39e0e4d5fca62a75a4bd2fd3643870dae13..2acd36c3019b2f897fbd238bb1045c0165ef67c3 100644 --- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.h +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityProcessorTool.h @@ -5,11 +5,7 @@ #ifndef DenseEnvironmentsAmbiguityProcessorTool_H #define DenseEnvironmentsAmbiguityProcessorTool_H -#include "AthenaBaseComps/AthAlgTool.h" -#include "GaudiKernel/ToolHandle.h" - -#include "TrkToolInterfaces/ITrackAmbiguityProcessorTool.h" -#include "TrkEventPrimitives/TrackScore.h" +#include "AmbiguityProcessorBase.h" #include "TrkFitterInterfaces/ITrackFitter.h" #include "TrkToolInterfaces/IAmbiTrackSelectionTool.h" #include "InDetPrepRawData/PixelGangedClusterAmbiguities.h" @@ -18,7 +14,6 @@ #include "TrkToolInterfaces/IPRDtoTrackMapTool.h" #include "TrkEventUtils/PRDtoTrackMap.h" -#include "TrkToolInterfaces/IExtendedTrackSummaryTool.h" //need to include the following, since its a typedef and can't be forward declared. #include "TrkTrack/TrackCollection.h" @@ -30,7 +25,7 @@ #include <map> #include <vector> -#include "TrackPtr.h" + class AtlasDetectorID; @@ -43,34 +38,11 @@ namespace InDet{ } namespace Trk { - class ITrackScoringTool; class ITruthToTrack; class IExtrapolator; // - class DenseEnvironmentsAmbiguityProcessorTool : public AthAlgTool, - virtual public ITrackAmbiguityProcessorTool{ + class DenseEnvironmentsAmbiguityProcessorTool : public AmbiguityProcessorBase{ public: - enum class EStatType { - kNtracks, - kNinvalid, - kNcandidates, - kNscoreOk, - kNscoreZeroBremRefit, - kNscoreZeroBremRefitFailed, - kNscoreZeroBremRefitScoreZero, - kNscoreZero, - kNaccepted, - kNsubTrack, - kNnoSubTrack, - kNacceptedBrem, - kNbremFits, - kNfits, - kNrecoveryBremFits, - kNgoodFits, - kNfailedFits, - kNCounter - }; - using TrackStat = AmbiCounter<EStatType>; // default methods DenseEnvironmentsAmbiguityProcessorTool(const std::string&,const std::string&,const IInterface*); virtual ~DenseEnvironmentsAmbiguityProcessorTool (); @@ -93,81 +65,64 @@ namespace Trk { virtual void statistics() override; private: - //transfer ownership - void addTrack(Track* track, const bool fitted, - std::multimap<float, TrackPtr > &scoreTrackFitflagMap, - const Trk::PRDtoTrackMap &prd_to_track_map, - std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks, - TrackStat &stat) const; - void solveTracks(const TracksScores& trackScoreTrackMap, Trk::PRDtoTrackMap &prd_to_track_map, TrackCollection &finalTracks, - std::vector<std::unique_ptr<const Trk::Track> >& cleanup_tracks, - TrackStat &stat) const; + std::vector<std::unique_ptr<const Trk::Track> >& trackDustbin, + Counter &stat) const; - /** refit track */ - Track* refitTrack( const Trk::Track* track, Trk::PRDtoTrackMap &prd_to_track_map, - TrackStat &stat) const; /** refit PRDs */ - Track* refitPrds( const Track* track, Trk::PRDtoTrackMap &prd_to_track_map, - TrackStat &stat) const; + Track* + refitPrds( const Track* track, Trk::PRDtoTrackMap &prd_to_track_map, + Counter &stat) const override final; /** refit ROTs corresponding to PRDs*/ //TODO or Q: new created track, why const - Track* refitRots( const Track* track, TrackStat &stat) const; + /**Track* + refitRots( const Track* track, Counter &stat) const override final;**/ /** stores the minimal dist(trk,trk) for covariance correction*/ - void storeTrkDistanceMapdR(TrackCollection& tracks, std::vector<Trk::Track*> &refit_tracks_out ); + void + storeTrkDistanceMapdR(TrackCollection& tracks, std::vector<Trk::Track*> &refit_tracks_out ); /** refit Tracks that are in the region of interest and removes inner hits that are wrongly assigned*/ - void removeInnerHits(std::vector<const Trk::MeasurementBase*>& measurements) const; + void + removeInnerHits(std::vector<const Trk::MeasurementBase*>& measurements) const; - Trk::Track* refitTracksFromB(const Trk::Track* track,double fitQualityOriginal) const; + Trk::Track* + refitTracksFromB(const Trk::Track* track,double fitQualityOriginal) const; /** see if we are in the region of interest for B tracks*/ - bool decideIfInHighPtBROI(const Trk::Track*) const; + bool + decideIfInHighPtBROI(const Trk::Track*) const; /** Check if the cluster is compatible with a hadronic cluster*/ - bool isHadCaloCompatible(const Trk::TrackParameters& Tp) const; + bool + isHadCaloCompatible(const Trk::TrackParameters& Tp) const; /** Load the clusters to see if they are compatibles with ROI*/ - void reloadHadROIs() const; + void + reloadHadROIs() const; + + virtual std::unique_ptr<Trk::Track> + doBremRefit(const Trk::Track & track) const override final; - Trk::Track *fit(const std::vector<const Trk::PrepRawData*> &raw, + std::unique_ptr<Trk::Track> + fit(const std::vector<const Trk::PrepRawData*> &raw, const TrackParameters ¶m, bool flag, Trk::ParticleHypothesis hypo) const; - Trk::Track *fit(const std::vector<const Trk::MeasurementBase*> &measurements, + std::unique_ptr<Trk::Track> + fit(const std::vector<const Trk::MeasurementBase*> &measurements, const TrackParameters ¶m, bool flag, Trk::ParticleHypothesis hypo) const; - template<typename... Args> - Trk::Track *fit(const Track &track, Args... args) const; - bool checkTrack(const Trk::Track *) const; - - // private data members - - /** brem recovery mode with brem fit ? */ - bool m_tryBremFit; - bool m_caloSeededBrem; - float m_pTminBrem; - - /** by default refit tracks from PRD */ - bool m_refitPrds; + std::unique_ptr<Trk::Track> + fit(const Track &track, bool flag, Trk::ParticleHypothesis hypo) const override final; - /** rescale pixel PRD covariances */ - bool m_applydRcorrection; - - /** suppress Hole Search */ - bool m_suppressHoleSearch; - - /** suppress Track Fit */ - bool m_suppressTrackFit; - - /** by default tracks at input get refitted */ - bool m_forceRefit; + bool + checkTrack(const Trk::Track *) const; /** variables to decide if we are in a ROI */ bool m_useHClusSeed; @@ -180,16 +135,6 @@ namespace Trk { mutable std::vector<double> m_hadE; mutable std::vector<double> m_hadR; mutable std::vector<double> m_hadZ; - - /** control material effects (0=non-interacting, 1=pion, 2=electron, 3=muon, 4=pion) read in as an integer - read in as an integer and convert to particle hypothesis */ - int m_matEffects; - Trk::ParticleHypothesis m_particleHypothesis; - - /**Scoring tool - This tool is used to 'score' the tracks, i.e. to quantify what a good track is. - @todo The actual tool that is used should be configured through job options*/ - ToolHandle<ITrackScoringTool> m_scoringTool; /** refitting tool - used to refit tracks once shared hits are removed. Refitting tool used is configured via jobOptions.*/ @@ -201,9 +146,6 @@ namespace Trk { ToolHandle<Trk::IPRDtoTrackMapTool> m_assoTool {this, "AssociationTool", "InDet::InDetPRDtoTrackMapToolGangedPixels" }; - ToolHandle<Trk::IExtendedTrackSummaryTool> m_trackSummaryTool - {this, "TrackSummaryTool", "InDetTrackSummaryToolNoHoleSearch"}; - /** key for the PRDtoTrackMap to filled by the ambiguity score processor.**/ SG::ReadHandleKey<Trk::PRDtoTrackMap> m_assoMapName {this,"AssociationMapName",""}; ///< the key given to the newly created association map @@ -215,70 +157,57 @@ namespace Trk { /**These allow us to retrieve the helpers*/ const PixelID* m_pixelId; const AtlasDetectorID* m_idHelper; - std::vector<float> m_etaBounds; //!< eta intervals for internal monitoring SG::WriteHandleKey<InDet::DRMap> m_dRMap; //!< the actual dR map - mutable std::mutex m_statMutex; - mutable TrackStat m_stat ATLAS_THREAD_SAFE; - bool m_rejectInvalidTracks; }; - inline Trk::Track * + inline std::unique_ptr<Trk::Track> DenseEnvironmentsAmbiguityProcessorTool::fit(const std::vector<const Trk::PrepRawData*> &raw, const TrackParameters ¶m, bool flag, Trk::ParticleHypothesis hypo) const { - Trk::Track *newTrack=nullptr; + std::unique_ptr<Trk::Track> newTrack; for ( const ToolHandle<ITrackFitter> &thisFitter : m_fitterTool) { - delete newTrack; - newTrack=nullptr; - newTrack = thisFitter->fit(raw, param, flag,hypo); - if (Trk::DenseEnvironmentsAmbiguityProcessorTool::checkTrack(newTrack)) { + newTrack.reset(thisFitter->fit(raw, param, flag,hypo)); + if (Trk::DenseEnvironmentsAmbiguityProcessorTool::checkTrack(newTrack.get())) { return newTrack; } ATH_MSG_WARNING( "The track fitter, " << thisFitter->name() << ", produced a track with an invalid covariance matrix." ); } ATH_MSG_WARNING( "None of the " << m_fitterTool.size() << " track fitter(s) produced a track with a valid covariance matrix." ); if (m_rejectInvalidTracks) { - delete newTrack; - newTrack=nullptr; + newTrack.reset(nullptr); } return newTrack; } - inline Trk::Track * + inline std::unique_ptr<Trk::Track> DenseEnvironmentsAmbiguityProcessorTool::fit(const std::vector<const Trk::MeasurementBase*> &measurements, const TrackParameters ¶m, bool flag, Trk::ParticleHypothesis hypo) const{ - Trk::Track *newTrack=nullptr; + std::unique_ptr<Trk::Track> newTrack; for ( const ToolHandle<ITrackFitter> &thisFitter : m_fitterTool) { - delete newTrack; - newTrack = nullptr; - newTrack = thisFitter->fit(measurements, param, flag, hypo); - if (Trk::DenseEnvironmentsAmbiguityProcessorTool::checkTrack(newTrack)) { + newTrack.reset(thisFitter->fit(measurements, param, flag, hypo)); + if (Trk::DenseEnvironmentsAmbiguityProcessorTool::checkTrack(newTrack.get())) { return newTrack; } ATH_MSG_WARNING( "The track fitter, " << thisFitter->name() << ", produced a track with an invalid covariance matrix." ); } ATH_MSG_WARNING( "None of the " << m_fitterTool.size() << " track fitter(s) produced a track with a valid covariance matrix." ); if (m_rejectInvalidTracks) { - delete newTrack; - newTrack = nullptr; + newTrack.reset(nullptr); } return newTrack; } - template<typename... Args> - inline Trk::Track * - DenseEnvironmentsAmbiguityProcessorTool::fit(const Track &track, Args... args) const{ - Trk::Track *newTrack=nullptr; - for ( const ToolHandle<ITrackFitter> &thisFitter : m_fitterTool) { - delete newTrack; - newTrack=nullptr; - newTrack = thisFitter->fit(track,args...); - if (Trk::DenseEnvironmentsAmbiguityProcessorTool::checkTrack(newTrack)) { + inline std::unique_ptr<Trk::Track> + DenseEnvironmentsAmbiguityProcessorTool::fit(const Track &track, bool flag, Trk::ParticleHypothesis hypo) const{ + std::unique_ptr<Trk::Track> newTrack; + for ( const ToolHandle<ITrackFitter> &thisFitter : m_fitterTool) { //note: there is only ever one fitter anyway + newTrack.reset(thisFitter->fit(track,flag, hypo)); + if (Trk::DenseEnvironmentsAmbiguityProcessorTool::checkTrack(newTrack.get())) { return newTrack; } ATH_MSG_WARNING( "The track fitter, " << thisFitter->name() << ", produced a track with an invalid covariance matrix." ); @@ -286,8 +215,7 @@ namespace Trk { } ATH_MSG_WARNING( "None of the " << m_fitterTool.size() << " track fitter(s) produced a track with a valid covariance matrix." ); if (m_rejectInvalidTracks) { - delete newTrack; - newTrack=nullptr; + newTrack.reset(nullptr); } return newTrack; } diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx index c1d0d4c6a8a5e6a41454ad54cf53c4608f69e824..90aac7985425c99954df631e8a4c7c71686bbfe1 100644 --- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.cxx @@ -19,6 +19,7 @@ #include "InDetPrepRawData/PixelCluster.h" #include "InDetPrepRawData/SCT_Cluster.h" #include "InDetIdentifier/PixelID.h" +#include "AmbiguityProcessorUtility.h" //================================================================================================== Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::DenseEnvironmentsAmbiguityScoreProcessorTool(const std::string& t, @@ -65,8 +66,8 @@ Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::initialize(){ ATH_CHECK( m_splitClusterMapKey_last.initialize(!m_splitClusterMapKey_last.key().empty()) ); ATH_CHECK( m_splitClusterMapKey.initialize(!m_splitClusterMapKey.key().empty()) ); - if (m_etaBounds.size() != TrackStat3::nRegions) { - ATH_MSG_FATAL("There must be exactly " << (TrackStat3::nRegions) << " eta bounds but " + if (m_etaBounds.size() != Counter::nRegions) { + ATH_MSG_FATAL("There must be exactly " << (Counter::nRegions) << " eta bounds but " << m_etaBounds.size() << " are set." ); return StatusCode::FAILURE; } @@ -98,7 +99,7 @@ Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::statistics() { and then returns the tracks which have been selected*/ void -Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::process(std::vector<const Track*>* tracks, +Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::process(const TrackCollection & tracks, Trk::TracksScores* trackScoreTrackMap) const{ InDet::PixelGangedClusterAmbiguities *splitClusterMap = nullptr; if(!m_splitClusterMapKey.key().empty()){ @@ -138,43 +139,27 @@ Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::process(std::vector<const Tra //================================================================================================== void -Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::addNewTracks(std::vector<const Track*>* tracks, +Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::addNewTracks(const TrackCollection & tracks, Trk::TracksScores* trackScoreTrackMap) const{ - TrackStat3 stat(m_etaBounds); + Counter stat(m_etaBounds); stat.newEvent(); std::unique_ptr<Trk::PRDtoTrackMap> prdToTrackMap( m_assoTool->createPRDtoTrackMap() ); - PrdSignatureSet prdSigSet; - ATH_MSG_DEBUG ("Number of tracks at Input: "<<tracks->size()); - for(const Track* a_track : *tracks) { - ATH_MSG_DEBUG ("Processing track candidate "<<a_track); - stat.incrementCounterByRegion(EStatType::kNcandidates,a_track); // @TODO should go to the score processor - // only fitted tracks get hole search, input is not fitted - float score = m_scoringTool->score( *a_track, true); - ATH_MSG_DEBUG ("Track Score is "<< score); - // veto tracks with score 0 - bool reject = (score==0); - if (reject){ - stat.incrementCounterByRegion(EStatType::kNcandScoreZero,a_track); - } else {// double track rejection - const std::vector<const Trk::PrepRawData*> & prds = m_assoTool->getPrdsOnTrack(*prdToTrackMap, *a_track); - // convert to set - //PrdSignature prdSig( prds.begin(),prds.end() ); - // we try to insert it into the set, if we fail (pair.second), it then exits already - if ( !(prdSigSet.insert(prds)).second ) { - ATH_MSG_DEBUG ("Double track, reject it !"); - stat.incrementCounterByRegion(EStatType::kNcandDouble,a_track); - reject = true; - } else { - ATH_MSG_DEBUG ("Insert new track in PrdSignatureSet"); - } - } - if (!reject) { - // add track to map, map is sorted small to big ! set if fitted - ATH_MSG_VERBOSE ("Track ("<< a_track <<" --> "<< *a_track << ") has score "<<score); - trackScoreTrackMap->push_back( std::make_pair(a_track, -score)); + PrdSignatureSet prdSigSet; + ATH_MSG_DEBUG ("Number of tracks at Input: "<<tracks.size()); + const std::array<ScoreCategory, 3> categoryMapping {ScoreCategory::kNcandScoreZero, ScoreCategory::kNcandDouble, ScoreCategory::kNaccept}; + constexpr bool dropDuplicateTracks{true}; + for(const Track* pThisTrack : tracks) { + ATH_MSG_VERBOSE ("Processing track candidate "<<pThisTrack); + stat.incrementCounterByRegion(ScoreCategory::kNcandidates,pThisTrack); // @TODO should go to the score processor + TrackScore score = m_scoringTool->score( *pThisTrack, true); + const auto category = AmbiguityProcessor::categoriseTrack(*pThisTrack, score, dropDuplicateTracks, m_assoTool, *prdToTrackMap, prdSigSet); + if (category<categoryMapping.size()) stat.incrementCounterByRegion(categoryMapping[category],pThisTrack); + ATH_MSG_DEBUG(AmbiguityProcessor::debugMessage[category]); + if (category == AmbiguityProcessor::TrackAccepted){ + ATH_MSG_VERBOSE ("Track ("<< pThisTrack <<") has score "<<score); + trackScoreTrackMap->push_back(std::make_pair(pThisTrack, -score)); } } - ATH_MSG_DEBUG ("Number of tracks in map:"<<trackScoreTrackMap->size()); { std::lock_guard<std::mutex> lock(m_statMutex); m_stat += stat; @@ -325,22 +310,22 @@ Trk::DenseEnvironmentsAmbiguityScoreProcessorTool::dumpStat(MsgStream &out) cons out << __func__; out << "\n"; out << "------------------------------------------------------------------------------------" << "\n"; - out << " Number of events processed : "<< m_stat.globalCount(TrackStat3::nEvents) << "\n"; - if (m_stat.globalCount(TrackStat3::nInvalidTracks)>0) { - out << " Number of invalid tracks : "<< m_stat.globalCount(TrackStat3::nInvalidTracks) << "\n"; + out << " Number of events processed : "<< m_stat.globalCount(Counter::nEvents) << "\n"; + if (m_stat.globalCount(Counter::nInvalidTracks)>0) { + out << " Number of invalid tracks : "<< m_stat.globalCount(Counter::nInvalidTracks) << "\n"; } - if (m_stat.globalCount(TrackStat3::nTracksWithoutParam)>0) { - out << " Tracks without parameters : "<< m_stat.globalCount(TrackStat3::nTracksWithoutParam) << "\n"; + if (m_stat.globalCount(Counter::nTracksWithoutParam)>0) { + out << " Tracks without parameters : "<< m_stat.globalCount(Counter::nTracksWithoutParam) << "\n"; } out << " statistics by eta range ------All---Barrel---Trans.-- Endcap-- Forwrd-- " << "\n"; out << "------------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions(" Number of candidates at input :", EStatType::kNcandidates,iw); - out << m_stat.dumpRegions(" - candidates rejected score 0 :", EStatType::kNcandScoreZero,iw); - out << m_stat.dumpRegions(" - candidates rejected as double :", EStatType::kNcandDouble,iw); + out << m_stat.dumpRegions(" Number of candidates at input :", ScoreCategory::kNcandidates,iw); + out << m_stat.dumpRegions(" - candidates rejected score 0 :", ScoreCategory::kNcandScoreZero,iw); + out << m_stat.dumpRegions(" - candidates rejected as double :", ScoreCategory::kNcandDouble,iw); out << "------------------------------------------------------------------------------------" << "\n"; out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2) - << " definition: ( 0.0 < Barrel < " << m_etaBounds[TrackStat3::iBarrel] << " < Transition < " << m_etaBounds[TrackStat3::iTransi] - << " < Endcap < " << m_etaBounds[TrackStat3::iEndcap] << " < Forward < " << m_etaBounds[TrackStat3::iForwrd] << " )" << "\n"; + << " definition: ( 0.0 < Barrel < " << m_etaBounds[Counter::iBarrel] << " < Transition < " << m_etaBounds[Counter::iTransi] + << " < Endcap < " << m_etaBounds[Counter::iEndcap] << " < Forward < " << m_etaBounds[Counter::iForwrd] << " )" << "\n"; out << "------------------------------------------------------------------------------------" << "\n"; out << std::setprecision(ss); } diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.h b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.h index 69cfa2e5ae91ef14b0974fc35fcfe09778d57acc..df34c8de899c134d58f27ab3971afd7820fe9985 100644 --- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.h +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/DenseEnvironmentsAmbiguityScoreProcessorTool.h @@ -40,14 +40,15 @@ namespace Trk { virtual public ITrackAmbiguityScoreProcessorTool { public: - enum class EStatType { + enum class ScoreCategory { kNtracks, kNcandidates, kNcandScoreZero, kNcandDouble, + kNaccept, kNCounter }; - using TrackStat3 = AmbiCounter<EStatType>; + using Counter = AmbiCounter<ScoreCategory>; // public types typedef std::multimap< TrackScore, const Track* > TrackScoreMap; typedef std::vector<const PrepRawData*> PrdSignature; @@ -56,11 +57,10 @@ namespace Trk { // default methods DenseEnvironmentsAmbiguityScoreProcessorTool(const std::string&,const std::string&,const IInterface*); virtual ~DenseEnvironmentsAmbiguityScoreProcessorTool(); - virtual StatusCode initialize() override; - virtual StatusCode finalize () override; + virtual StatusCode initialize() override final; + virtual StatusCode finalize () override final; - virtual void process(std::vector<const Track*>* tracks, - TracksScores* trackScoreTrackMap) const override; + virtual void process(const TrackCollection & tracks, TracksScores* trackScoreTrackMap) const override final; /** statistics output to be called by algorithm during finalize. */ void statistics() override; @@ -72,7 +72,7 @@ namespace Trk { @param tracks the TrackCollection is looped over, and each Trk::Track is added to the various caches. The Trk::PrepRawData from each Trk::Track are added to the IPRD_AssociationTool*/ - void addNewTracks(std::vector<const Track*>* tracks, + void addNewTracks(const TrackCollection & tracks, TracksScores* trackScoreTrackMap) const; /** Find SiS Tracks that share hits in the track score map*/ @@ -122,7 +122,7 @@ namespace Trk { std::vector<float> m_etaBounds; //!< eta intervals for internal monitoring mutable std::mutex m_statMutex; - mutable TrackStat3 m_stat ATLAS_THREAD_SAFE; + mutable Counter m_stat ATLAS_THREAD_SAFE; }; } //end ns diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.cxx b/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.cxx index 7328fd37a19030ce14d6509e6c16dc48498e56e5..70da48d5cb0c448a5e0692c52f0365cf7a7eb17b 100644 --- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.cxx +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.cxx @@ -12,21 +12,18 @@ #include "TrkTrack/TrackInfo.h" #include <map> #include <memory> +#include "AmbiguityProcessorUtility.h" + //================================================================================================== Trk::SimpleAmbiguityProcessorTool::SimpleAmbiguityProcessorTool(const std::string& t, const std::string& n, const IInterface* p ) : - AthAlgTool(t,n,p), - m_particleHypothesis{undefined}, - m_scoringTool("Trk::TrackScoringTool/TrackScoringTool"), + AmbiguityProcessorBase(t,n,p), m_fitterTool ("Trk::KalmanFitter/InDetTrackFitter"), - m_selectionTool("InDet::InDetAmbiTrackSelectionTool/InDetAmbiTrackSelectionTool"), - m_etabounds( {0.8,1.6,2.5,10.0} ), - m_stat(m_etabounds) -{ - // statitics stuff + m_selectionTool("InDet::InDetAmbiTrackSelectionTool/InDetAmbiTrackSelectionTool"){ + // statistics stuff declareInterface<ITrackAmbiguityProcessorTool>(this); declareProperty("DropDouble" , m_dropDouble = true); @@ -41,7 +38,7 @@ Trk::SimpleAmbiguityProcessorTool::SimpleAmbiguityProcessorTool(const std::strin declareProperty("tryBremFit" , m_tryBremFit = false); declareProperty("caloSeededBrem" , m_caloSeededBrem = false); declareProperty("pTminBrem" , m_pTminBrem = 1000.); - declareProperty("etaBounds" , m_etabounds,"eta intervals for internal monitoring"); + declareProperty("etaBounds" , m_etaBounds,"eta intervals for internal monitoring"); } //================================================================================================== @@ -65,7 +62,7 @@ StatusCode Trk::SimpleAmbiguityProcessorTool::initialize(){ ATH_CHECK( m_fitterTool.retrieve()); // suppress refit overwrites force refit if (m_forceRefit && m_suppressTrackFit ) { - ATH_MSG_WARNING( "Inconsistent parameter settings, forced refit is true, but fitting suppressed, resetingt force refit !" ); + ATH_MSG_WARNING( "Inconsistent parameter settings, forced refit is true, but fitting suppressed, resetting force refit !" ); m_forceRefit = false; } // Print out memo that tracks have to be fitted @@ -81,7 +78,7 @@ StatusCode Trk::SimpleAmbiguityProcessorTool::initialize(){ ATH_MSG_INFO( "Try brem fit and recovery for electron like tracks."); } // statistics - if (m_etabounds.size() != Counter::nRegions) { + if (m_etaBounds.size() != Counter::nRegions) { ATH_MSG_ERROR( "There must be exactly " << Counter::nRegions << " etaBounds: barrel end, transition region end, end-cap end, DBM start, DBM end." ); return StatusCode::FAILURE; @@ -139,19 +136,15 @@ Trk::SimpleAmbiguityProcessorTool::processVector(const TrackCollection &tracks, } //put tracks into maps etc ATH_MSG_DEBUG ("Adding input track candidates to list"); - Counter stat(m_etabounds); - addNewTracks(tracks, trackScoreTrackMap, *prdToTrackMap, stat); - { - std::lock_guard<std::mutex> lock(m_statMutex); - stat.newEvent(); - } + Counter stat(m_etaBounds); + addNewTracks(tracks, trackScoreTrackMap, *prdToTrackMap); // going to do simple algorithm for now: // - take track with highest score // - remove shared hits from all other tracks // - take next highest scoring tracks, and repeat ATH_MSG_DEBUG ("Solving Tracks"); - std::vector<std::unique_ptr<const Trk::Track> > cleanupTracks; - TrackCollection* finalTracks = solveTracks(trackScoreTrackMap, *prdToTrackMap,cleanupTracks, stat); + std::vector<std::unique_ptr<const Trk::Track> > trackDustbin; + TrackCollection* finalTracks = solveTracks(trackScoreTrackMap, *prdToTrackMap,trackDustbin, stat); { std::lock_guard<std::mutex> lock(m_statMutex); m_stat += stat; @@ -163,45 +156,22 @@ Trk::SimpleAmbiguityProcessorTool::processVector(const TrackCollection &tracks, //================================================================================================== void Trk::SimpleAmbiguityProcessorTool::addNewTracks(const TrackCollection &tracks, TrackScoreMap& trackScoreTrackMap, - Trk::PRDtoTrackMap &prdToTrackMap, - Counter &stat) const { + Trk::PRDtoTrackMap &prdToTrackMap) const { + Counter stat(m_etaBounds); + stat.newEvent(); + // ATH_MSG_DEBUG ("Number of tracks at Input: "<<tracks.size()); - /** signature map to drop double track. */ + /** signature set to drop double track. */ PrdSignatureSet prdSigSet; + //map the two lowest categories (zero score, duplicate track) onto the counter categories + const std::array<CounterIndex, 2> categoryMapping {CounterIndex::kNcandScoreZero, CounterIndex::kNcandDouble}; for(const Track *pTrack : tracks) { - ATH_MSG_DEBUG ("Processing track candidate "<<pTrack); - // statistics - stat.incrementCounterByRegion(ECounter::kNcandidates,pTrack); - bool reject = false; - // only fitted tracks get hole search, input is not fitted + stat.incrementCounterByRegion(CounterIndex::kNcandidates,pTrack); TrackScore score = m_scoringTool->score( *pTrack, true); - // veto tracks with score 0 - if (score==0) { - ATH_MSG_DEBUG ("Candidate score is zero, reject it"); - // statistic - stat.incrementCounterByRegion(ECounter::kNcandScoreZero,pTrack); - reject = true; - } else { - ATH_MSG_DEBUG ("Track Score is "<< score); - // double track rejection - if (m_dropDouble) { - const auto & prds = m_assoTool->getPrdsOnTrack(prdToTrackMap, *pTrack); - // unfortunately PrepRawDataSet is not a set ! - PrdSignature prdSig; - prdSig.insert( prds.begin(),prds.end() ); - // we try to insert it into the set, if we fail (pair.second), it then exists already - if ( !(prdSigSet.insert(prdSig)).second ) { - ATH_MSG_DEBUG ("Double track, reject it !"); - // statistic - stat.incrementCounterByRegion(ECounter::kNcandDouble,pTrack); - reject = true; - } else { - ATH_MSG_DEBUG ("Insert new track in PrdSignatureSet"); - } - } - } - if (!reject) { - // add track to map, map is sorted small to big ! set if fitted + const auto category = AmbiguityProcessor::categoriseTrack(*pTrack, score, m_dropDouble, m_assoTool, prdToTrackMap, prdSigSet); + if (category < categoryMapping.size()) stat.incrementCounterByRegion(categoryMapping[category],pTrack); + ATH_MSG_DEBUG(AmbiguityProcessor::debugMessage[category]); + if (category == AmbiguityProcessor::TrackAccepted){ ATH_MSG_VERBOSE ("Track ("<< pTrack <<") has score "<<score); TrackPtr ptr(pTrack); if (!m_forceRefit) ptr.forceFitted(); @@ -209,83 +179,20 @@ void Trk::SimpleAmbiguityProcessorTool::addNewTracks(const TrackCollection &trac } } ATH_MSG_DEBUG ("Number of tracks in map:"<<trackScoreTrackMap.size()); + { + std::lock_guard<std::mutex> lock(m_statMutex); + m_stat += stat; + } } -//================================================================================================== -void Trk::SimpleAmbiguityProcessorTool::addTrack(Trk::Track* in_track, - const bool fitted, - TrackScoreMap &trackScoreTrackMap, - Trk::PRDtoTrackMap &prdToTrackMap, - std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks, - Counter &stat) const { - std::unique_ptr<Trk::Track> atrack(in_track); - // compute score - TrackScore score; - bool suppressHoleSearch = fitted ? m_suppressHoleSearch : true; - if (m_trackSummaryTool.isEnabled()) { - m_trackSummaryTool->computeAndReplaceTrackSummary(*atrack,&prdToTrackMap,suppressHoleSearch); - } - score = m_scoringTool->score( *atrack, suppressHoleSearch ); - // do we accept the track ? - if (score!=0){ - ATH_MSG_DEBUG ("Track ("<< atrack.get() <<") has score "<<score); - // statistic - stat.incrementCounterByRegion(ECounter::kNscoreOk,atrack.get()); - // add track to map, map is sorted small to big ! - trackScoreTrackMap.insert( std::make_pair(-score, TrackPtr(atrack.release(), fitted)) ); - return; - } - // do we try to recover the track ? - if (score==0 && fitted && m_tryBremFit && - !atrack->info().trackProperties(Trk::TrackInfo::BremFit) && - atrack->trackParameters()->front()->pT() > m_pTminBrem && - (!m_caloSeededBrem || atrack->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI))){ - ATH_MSG_DEBUG ("Track score is zero, try to recover it via brem fit"); - // run track fit using electron hypothesis - std::unique_ptr<Trk::Track> bremTrack( m_fitterTool->fit(*atrack,true,Trk::electron) ); - if (!bremTrack){ - ATH_MSG_DEBUG ("Brem refit failed, drop track"); - // statistic - stat.incrementCounterByRegion(ECounter::kNscoreZeroBremRefitFailed,atrack.get()); - stat.incrementCounterByRegion(ECounter::kNfailedFits,atrack.get()); - // clean up - cleanupTracks.push_back(std::move(atrack)); - } else { - // statistic - stat.incrementCounterByRegion(ECounter::kNgoodFits,bremTrack.get()); - // rerun score - if (m_trackSummaryTool.isEnabled()) { - m_trackSummaryTool->computeAndReplaceTrackSummary(*bremTrack, &prdToTrackMap,suppressHoleSearch); - } - score = m_scoringTool->score( *bremTrack, suppressHoleSearch ); - // do we accept the track ? - if (score!=0){ - ATH_MSG_DEBUG ("Brem refit successful, recovered track ("<< atrack.get() <<") has score "<<score); - // statistics - stat.incrementCounterByRegion(ECounter::kNscoreZeroBremRefit,bremTrack.get()); - // add track to map, map is sorted small to big ! - trackScoreTrackMap.insert( std::make_pair(-score, TrackPtr(bremTrack.release(), fitted)) ); - return; - } else { - ATH_MSG_DEBUG ("Brem refit gave still track score zero, reject it"); - // statistic - stat.incrementCounterByRegion(ECounter::kNscoreZeroBremRefitScoreZero,bremTrack.get()); - } - cleanupTracks.push_back(std::move(atrack)); - } - } else { - ATH_MSG_DEBUG ("Track score is zero, reject it"); - // statistic - stat.incrementCounterByRegion(ECounter::kNscoreZero,atrack.get()); - cleanupTracks.push_back(std::move(atrack)); - } -} + //================================================================================================== -TrackCollection *Trk::SimpleAmbiguityProcessorTool::solveTracks(TrackScoreMap& trackScoreTrackMap, +TrackCollection * +Trk::SimpleAmbiguityProcessorTool::solveTracks(TrackScoreMap& trackScoreTrackMap, Trk::PRDtoTrackMap &prdToTrackMap, - std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks, + std::vector<std::unique_ptr<const Trk::Track> >& trackDustbin, Counter &stat) const{ std::unique_ptr<TrackCollection> finalTracks(std::make_unique<TrackCollection>()); ATH_MSG_DEBUG ("Starting to solve tracks"); @@ -306,8 +213,8 @@ TrackCollection *Trk::SimpleAmbiguityProcessorTool::solveTracks(TrackScoreMap& t // track can be kept as is and is already fitted ATH_MSG_DEBUG ("Accepted track "<<atrack.track()<<"\t has score "<<-(ascore)); // statistic - stat.incrementCounterByRegion(ECounter::kNaccepted,atrack.track()); - if (m_tryBremFit && atrack->info().trackProperties(Trk::TrackInfo::BremFit)) stat.incrementCounterByRegion(ECounter::kNacceptedBrem,atrack.track()); + stat.incrementCounterByRegion(CounterIndex::kNaccepted,atrack.track()); + if (m_tryBremFit && atrack->info().trackProperties(Trk::TrackInfo::BremFit)) stat.incrementCounterByRegion(CounterIndex::kNacceptedBrem,atrack.track()); // add track to PRD_AssociationTool if (m_assoTool->addPRDs(prdToTrackMap, *atrack.track()).isFailure()) ATH_MSG_ERROR("addPRDs() failed" ); // add to output list @@ -316,30 +223,33 @@ TrackCollection *Trk::SimpleAmbiguityProcessorTool::solveTracks(TrackScoreMap& t // don't forget to drop track from map // track can be kept as is, but is not yet fitted ATH_MSG_DEBUG ("Good track, but need to fit this track first, score, add it into map again and retry !"); - refitTrack(atrack.track(),trackScoreTrackMap, prdToTrackMap, cleanupTracks, stat); + auto pRefittedTrack = refitTrack(atrack.track(), prdToTrackMap, stat); + if(pRefittedTrack) { + addTrack( pRefittedTrack, true , trackScoreTrackMap, prdToTrackMap, trackDustbin, stat); + } if (atrack.newTrack()) { - cleanupTracks.push_back( std::unique_ptr<Trk::Track>(atrack.release()) ); + trackDustbin.emplace_back(atrack.release()); } // delete original copy } else if ( cleanedTrack ) { // now delete original track if (atrack.newTrack()) { - cleanupTracks.push_back( std::unique_ptr<Trk::Track>(atrack.release())); + trackDustbin.emplace_back(atrack.release()); } // don't forget to drop track from map // stripped down version should be reconsidered ATH_MSG_DEBUG ("Candidate excluded, add subtrack to map. Track "<<cleanedTrack.get()); // statistic - stat.incrementCounterByRegion(ECounter::kNsubTrack,cleanedTrack.get()); + stat.incrementCounterByRegion(CounterIndex::kNsubTrack,cleanedTrack.get()); // track needs fitting ! - addTrack( cleanedTrack.release(), false, trackScoreTrackMap, prdToTrackMap, cleanupTracks, stat); + addTrack( cleanedTrack.release(), false, trackScoreTrackMap, prdToTrackMap, trackDustbin, stat); } else { // track should be discarded ATH_MSG_DEBUG ("Track "<< atrack.track() << " is excluded, no subtrack, reject"); // statistic - stat.incrementCounterByRegion(ECounter::kNnoSubTrack,atrack.track()); + stat.incrementCounterByRegion(CounterIndex::kNnoSubTrack,atrack.track()); if (atrack.newTrack()) { - cleanupTracks.push_back( std::unique_ptr<Trk::Track>(atrack.release()) ); + trackDustbin.emplace_back(atrack.release()); } // don't forget to drop track from map } @@ -348,58 +258,6 @@ TrackCollection *Trk::SimpleAmbiguityProcessorTool::solveTracks(TrackScoreMap& t return finalTracks.release(); } -//================================================================================================== - -void -Trk::SimpleAmbiguityProcessorTool::refitTrack( const Trk::Track* track, - TrackScoreMap& trackScoreTrackMap, - Trk::PRDtoTrackMap &prdToTrackMap, - std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks, - Counter &stat) const{ - std::unique_ptr<Trk::Track> newTrack; - if (!m_suppressTrackFit) { - if (m_refitPrds) { - // simple case, fit PRD directly - ATH_MSG_VERBOSE ("Refit track "<<track<<" from PRDs"); - newTrack.reset( refitPrds (track, prdToTrackMap,stat) ); - } else { - // ok, we fit ROTs - ATH_MSG_VERBOSE ("Refit track "<<track<<" from ROTs"); - newTrack.reset( refitRots (track,stat) ); - } - }else{ - double reXi2 = 0.; - int nDF = 0; - const DataVector<const TrackStateOnSurface>* tsos = track->trackStateOnSurfaces(); - DataVector<const TrackStateOnSurface>* vecTsos = new DataVector<const TrackStateOnSurface>(); - // loop over TSOS, copy TSOS and push into vector - DataVector<const TrackStateOnSurface>::const_iterator iTsos = tsos->begin(); - DataVector<const TrackStateOnSurface>::const_iterator iTsosEnd = tsos->end(); - for ( ; iTsos != iTsosEnd ; ++iTsos) { - const TrackStateOnSurface* newTsos = new TrackStateOnSurface(**iTsos); - vecTsos->push_back(newTsos); - if((*iTsos)->type(Trk::TrackStateOnSurface::Measurement)){ //Get the chi2 and number of hits - if ((*iTsos)->fitQualityOnSurface()) { - reXi2 += (*iTsos)->fitQualityOnSurface()->chiSquared(); - nDF += (*iTsos)->fitQualityOnSurface()->numberDoF(); - } - } - } - Trk::FitQuality* fq = new Trk::FitQuality(reXi2,nDF-5); - Trk::TrackInfo info; - info.addPatternRecoAndProperties(track->info()); - Trk::TrackInfo newInfo; - newInfo.setPatternRecognitionInfo(Trk::TrackInfo::SimpleAmbiguityProcessorTool); - info.addPatternReco(newInfo); - newTrack = std::make_unique<Trk::Track>( info, vecTsos, fq ); - } - if (newTrack){ - ATH_MSG_DEBUG ("New track successfully fitted"<<newTrack.get()); - addTrack( newTrack.release(), true, trackScoreTrackMap, prdToTrackMap, cleanupTracks, stat); - } else { - ATH_MSG_DEBUG ("Fit failed !"); - } -} //================================================================================================== @@ -413,88 +271,35 @@ Trk::SimpleAmbiguityProcessorTool::refitPrds( const Trk::Track* track, ATH_MSG_WARNING( "No PRDs on track"); return nullptr; } - ATH_MSG_VERBOSE ("Track "<<track<<"\t has "<<prds.size()<<"\t PRDs"); - const TrackParameters* par = track->perigeeParameters(); - if (par==nullptr) { - ATH_MSG_DEBUG ("Track ("<<track<<") has no perigee! Try any other ?"); - par = track->trackParameters()->front(); - if (par==nullptr) { - ATH_MSG_DEBUG ("Track ("<<track<<") has no Track Parameters ! No refit !"); - return nullptr; - } - } + const TrackParameters* par = getTrackParameters(track); + if (not par) return nullptr; // refit using first parameter, do outliers Trk::Track* newTrack = nullptr; if (m_tryBremFit && track->info().trackProperties(Trk::TrackInfo::BremFit)){ - // statistics - stat.incrementCounterByRegion(ECounter::kNbremFits,track); + stat.incrementCounterByRegion(CounterIndex::kNbremFits,track); ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit"); newTrack = m_fitterTool->fit(prds, *par, true, Trk::electron); } else { - // statistics - stat.incrementCounterByRegion(ECounter::kNfits,track); + stat.incrementCounterByRegion(CounterIndex::kNfits,track); ATH_MSG_VERBOSE ("Normal track, refit"); newTrack = m_fitterTool->fit(prds, *par, true, m_particleHypothesis); - if (!newTrack && m_tryBremFit && par->pT() > m_pTminBrem && - (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI))){ - // statistics - stat.incrementCounterByRegion(ECounter::kNrecoveryBremFits,track); + if ((not newTrack) and shouldTryBremRecovery(*track, par)){ + stat.incrementCounterByRegion(CounterIndex::kNrecoveryBremFits,track); ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery"); newTrack = m_fitterTool->fit(prds, *par, true, Trk::electron); } } if(newTrack){ - // statistic - stat.incrementCounterByRegion(ECounter::kNgoodFits,newTrack); + stat.incrementCounterByRegion(CounterIndex::kNgoodFits,newTrack); //keeping the track of previously accumulated TrackInfo const Trk::TrackInfo& originalInfo = track->info(); newTrack->info().addPatternReco(originalInfo); } else { - // statistic - stat.incrementCounterByRegion(ECounter::kNfailedFits,track); + stat.incrementCounterByRegion(CounterIndex::kNfailedFits,track); } return newTrack; } -//================================================================================================== - -Trk::Track* Trk::SimpleAmbiguityProcessorTool::refitRots( const Trk::Track* track, - Counter &stat) const { - ATH_MSG_VERBOSE ("Refit track "<<track); - // refit using first parameter, do outliers - Trk::Track* newTrack = nullptr; - if (m_tryBremFit && track->info().trackProperties(Trk::TrackInfo::BremFit)) { - // statistics - stat.incrementCounterByRegion(ECounter::kNbremFits,track); - ATH_MSG_VERBOSE ("Brem track, refit with electron brem fit"); - newTrack = m_fitterTool->fit(*track, true, Trk::electron); - } else { - // statistics - stat.incrementCounterByRegion(ECounter::kNfits,track); - ATH_MSG_VERBOSE ("Normal track, refit"); - newTrack = m_fitterTool->fit(*track, true, m_particleHypothesis); - if (!newTrack && m_tryBremFit && - track->trackParameters()->front()->pT() > m_pTminBrem && - (!m_caloSeededBrem || track->info().patternRecoInfo(Trk::TrackInfo::TrackInCaloROI))){ - // statistics - stat.incrementCounterByRegion(ECounter::kNrecoveryBremFits,track); - - ATH_MSG_VERBOSE ("Normal fit failed, try brem recovery"); - newTrack = m_fitterTool->fit(*track, true, Trk::electron); - } - } - if(newTrack){ - // statistic - stat.incrementCounterByRegion(ECounter::kNgoodFits,newTrack); - //keeping the track of previously accumulated TrackInfo - const Trk::TrackInfo& originalInfo = track->info(); - newTrack->info().addPatternReco(originalInfo); - } else { - // statistic - stat.incrementCounterByRegion(ECounter::kNfailedFits,track); - } - return newTrack; -} //================================================================================================== @@ -532,44 +337,55 @@ Trk::SimpleAmbiguityProcessorTool::dumpStat(MsgStream &out) const { out << " Number of events processed : "<< m_stat.numberOfEvents() << "\n"; out << " statistics by eta range ------All---Barrel---Trans.--- Endcap---DBM---" << "\n"; out << "---------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " Number of candidates at input :", ECounter::kNcandidates); - out << m_stat.dumpRegions( " - candidates rejected score 0 :", ECounter::kNcandScoreZero); - out << m_stat.dumpRegions( " - candidates rejected as double :", ECounter::kNcandDouble); + out << m_stat.dumpRegions( " Number of candidates at input :", CounterIndex::kNcandidates); + out << m_stat.dumpRegions( " - candidates rejected score 0 :", CounterIndex::kNcandScoreZero); + out << m_stat.dumpRegions( " - candidates rejected as double :", CounterIndex::kNcandDouble); out << "---------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " candidates with good score :", ECounter::kNscoreOk); + out << m_stat.dumpRegions( " candidates with good score :", CounterIndex::kNscoreOk); if (m_tryBremFit) { - out << m_stat.dumpRegions(" + recovered after brem refit :", ECounter::kNscoreZeroBremRefit); + out << m_stat.dumpRegions(" + recovered after brem refit :", CounterIndex::kNscoreZeroBremRefit); } - out << m_stat.dumpRegions( " candidates rejected score 0 :", ECounter::kNscoreZero); + out << m_stat.dumpRegions( " candidates rejected score 0 :", CounterIndex::kNscoreZero); if (m_tryBremFit) { - out << m_stat.dumpRegions(" + rejected failed brem refit :", ECounter::kNscoreZeroBremRefitFailed); + out << m_stat.dumpRegions(" + rejected failed brem refit :", CounterIndex::kNscoreZeroBremRefitFailed); } out << "---------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " number of normal fits :", ECounter::kNfits); + out << m_stat.dumpRegions( " number of normal fits :", CounterIndex::kNfits); if (m_tryBremFit) { - out << m_stat.dumpRegions(" + 2nd brem fit for failed fit :", ECounter::kNrecoveryBremFits); - out << m_stat.dumpRegions(" normal brem fits for electrons :", ECounter::kNbremFits); + out << m_stat.dumpRegions(" + 2nd brem fit for failed fit :", CounterIndex::kNrecoveryBremFits); + out << m_stat.dumpRegions(" normal brem fits for electrons :", CounterIndex::kNbremFits); } out << "---------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " sum of succesful fits :", ECounter::kNgoodFits); - out << m_stat.dumpRegions( " sum of failed fits :", ECounter::kNfailedFits); + out << m_stat.dumpRegions( " sum of succesful fits :", CounterIndex::kNgoodFits); + out << m_stat.dumpRegions( " sum of failed fits :", CounterIndex::kNfailedFits); out << "---------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " Number of subtracks created :", ECounter::kNsubTrack); - out << m_stat.dumpRegions( " Number of candidates excluded :", ECounter::kNnoSubTrack); + out << m_stat.dumpRegions( " Number of subtracks created :", CounterIndex::kNsubTrack); + out << m_stat.dumpRegions( " Number of candidates excluded :", CounterIndex::kNnoSubTrack); out << "---------------------------------------------------------------------------------" << "\n"; - out << m_stat.dumpRegions( " Number of tracks accepted :", ECounter::kNaccepted); + out << m_stat.dumpRegions( " Number of tracks accepted :", CounterIndex::kNaccepted); if (m_tryBremFit) { - out << m_stat.dumpRegions(" including number of brem fits :", ECounter::kNacceptedBrem); + out << m_stat.dumpRegions(" including number of brem fits :", CounterIndex::kNacceptedBrem); } out << "---------------------------------------------------------------------------------" << "\n"; out << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2) - << " definition: ( 0.0 < Barrel < " << m_etabounds[Counter::iBarrel] << " < Transition < " << m_etabounds[Counter::iTransi] - << " < Endcap < " << m_etabounds[Counter::iEndcap] << " DBM )" << "\n"; + << " definition: ( 0.0 < Barrel < " << m_etaBounds[Counter::iBarrel] << " < Transition < " << m_etaBounds[Counter::iTransi] + << " < Endcap < " << m_etaBounds[Counter::iEndcap] << " DBM )" << "\n"; out << "-------------------------------------------------------------------------------" << "\n"; out.precision (ss); } +std::unique_ptr<Trk::Track> +Trk::SimpleAmbiguityProcessorTool::doBremRefit(const Trk::Track & track) const{ + return std::unique_ptr<Trk::Track>(m_fitterTool->fit(track,true,Trk::electron)); +} + +std::unique_ptr<Trk::Track> +Trk::SimpleAmbiguityProcessorTool::fit(const Track &track, bool flag, Trk::ParticleHypothesis hypo) const{ + return std::unique_ptr<Trk::Track>(m_fitterTool->fit(track,flag,hypo)); +} + + diff --git a/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.h b/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.h index 074760b7f3277676eea39eebd71478dab5ba08ee..532d2f3f1554de573b3a6df12ebf4f5379c6f495 100644 --- a/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.h +++ b/Tracking/TrkTools/TrkAmbiguityProcessor/src/SimpleAmbiguityProcessorTool.h @@ -6,8 +6,7 @@ #define SIMPLEAMBIGUITYPROCESSORTOOL_H -#include "AthenaBaseComps/AthAlgTool.h" -#include "TrkToolInterfaces/ITrackAmbiguityProcessorTool.h" +#include "AmbiguityProcessorBase.h" #include "TrkEventPrimitives/TrackScore.h" #include "TrkFitterInterfaces/ITrackFitter.h" #include "GaudiKernel/ToolHandle.h" @@ -25,9 +24,9 @@ #include <vector> #include <mutex> #include <array> -#include "AmbiCounter.icc" -#include "TrackPtr.h" + + class AtlasDetectorID; class PixelID; @@ -37,25 +36,18 @@ namespace Trk { class IPRD_AssociationTool; class ITruthToTrack; - class SimpleAmbiguityProcessorTool : public AthAlgTool, virtual public ITrackAmbiguityProcessorTool - { + class SimpleAmbiguityProcessorTool : public AmbiguityProcessorBase { public: - enum class ECounter {kNcandidates, kNcandScoreZero, kNcandDouble, - kNscoreOk,kNscoreZeroBremRefit,kNscoreZeroBremRefitFailed,kNscoreZeroBremRefitScoreZero,kNscoreZero, - kNaccepted,kNsubTrack,kNnoSubTrack,kNacceptedBrem, - kNbremFits,kNfits,kNrecoveryBremFits,kNgoodFits,kNfailedFits, kNCounter}; - using Counter = AmbiCounter<ECounter>; // public types typedef std::multimap< TrackScore, TrackPtr > TrackScoreMap; - - typedef std::set<const PrepRawData*> PrdSignature; + typedef std::vector<const PrepRawData*> PrdSignature; typedef std::set<PrdSignature> PrdSignatureSet; // default methods SimpleAmbiguityProcessorTool(const std::string&,const std::string&,const IInterface*); virtual ~SimpleAmbiguityProcessorTool (); - virtual StatusCode initialize() override; - virtual StatusCode finalize () override; + virtual StatusCode initialize() override final; + virtual StatusCode finalize () override final; /**Returns a processed TrackCollection from the passed 'tracks' @param tracks collection of tracks which will have ambiguities resolved. Will not be @@ -74,106 +66,59 @@ namespace Trk { virtual void statistics() override; private: - TrackCollection* processVector(const TrackCollection &tracks, Trk::PRDtoTrackMap *prdToTrackMap) const; + TrackCollection* + processVector(const TrackCollection &tracks, Trk::PRDtoTrackMap *prdToTrackMap) const; /**Add passed TrackCollection, and Trk::PrepRawData from tracks to caches @param tracks the TrackCollection is looped over, and each Trk::Track is added to the various caches. The Trk::PrepRawData from each Trk::Track are added to the IPRD_AssociationTool*/ - //void addNewTracks(const std::vector<const Track*> &tracks, - void addNewTracks(const TrackCollection &tracks, - TrackScoreMap& trackScoreTrackMap, - Trk::PRDtoTrackMap &prdToTrackMap, - Counter &stat) const; - - void addTrack(Track* track, const bool fitted, - TrackScoreMap &trackScoreMap, - Trk::PRDtoTrackMap &prdToTrackMap, - std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks, - Counter &stat) const; - - TrackCollection *solveTracks(TrackScoreMap &trackScoreTrackMap, - Trk::PRDtoTrackMap &prdToTrackMap, - std::vector<std::unique_ptr<const Trk::Track> > &cleanupTracks, - Counter &stat) const; + void + addNewTracks(const TrackCollection &tracks, + TrackScoreMap& trackScoreTrackMap, + Trk::PRDtoTrackMap &prdToTrackMap) const; + + TrackCollection * + solveTracks(TrackScoreMap &trackScoreTrackMap, + Trk::PRDtoTrackMap &prdToTrackMap, + std::vector<std::unique_ptr<const Trk::Track> > &trackDustbin, + Counter &stat) const; /** add subtrack to map */ - void addSubTrack( const std::vector<const TrackStateOnSurface*>& tsos) const; + void + addSubTrack( const std::vector<const TrackStateOnSurface*>& tsos) const; - /** refit track */ - void refitTrack( const Trk::Track* track, - TrackScoreMap &trackScoreMap, - Trk::PRDtoTrackMap &prdToTrackMap, - std::vector<std::unique_ptr<const Trk::Track> >& cleanupTracks, - Counter &stat) const; + /** do a refit assuming electron hypothesis **/ + virtual std::unique_ptr<Trk::Track> + doBremRefit(const Trk::Track & track) const override final; /** refit PRDs */ - Track* refitPrds( const Track* track, Trk::PRDtoTrackMap &prdToTrackMap, - Counter &stat) const; - - /** refit ROTs corresponding to PRDs */ - Track* refitRots( const Track* track, - Counter &stat) const; + Track* + refitPrds( const Track* track, Trk::PRDtoTrackMap &prdToTrackMap, Counter &stat) const override final; /** print out tracks and their scores for debugging*/ - void dumpTracks(const TrackCollection& tracks) const; + void + dumpTracks(const TrackCollection& tracks) const; /** dump the accumulated statistics */ - void dumpStat(MsgStream &out) const; + void + dumpStat(MsgStream &out) const; + + std::unique_ptr<Trk::Track> + fit(const Track &track, bool flag, Trk::ParticleHypothesis hypo) const override final; // private data members - - /** brem recovery mode with brem fit ? */ - bool m_tryBremFit; - bool m_caloSeededBrem; - float m_pTminBrem; - /** by default drop double tracks before refit*/ bool m_dropDouble; - - /** by default tracks at input get refitted */ - bool m_forceRefit; - - /** by default refit tracks from PRD */ - bool m_refitPrds; - - /** suppress Hole Search */ - bool m_suppressHoleSearch; - - /** suppress Track Fit */ - bool m_suppressTrackFit; - - /** control material effects (0=non-interacting, 1=pion, 2=electron, 3=muon, 4=pion) read in as an integer - read in as an integer and convert to particle hypothesis */ - int m_matEffects; - Trk::ParticleHypothesis m_particleHypothesis; - - /**Scoring tool - This tool is used to 'score' the tracks, i.e. to quantify what a good track is. - @todo The actual tool that is used should be configured through job options*/ - ToolHandle<ITrackScoringTool> m_scoringTool; - + /** refitting tool - used to refit tracks once shared hits are removed. Refitting tool used is configured via jobOptions.*/ ToolHandle<ITrackFitter> m_fitterTool; - - ToolHandle<Trk::IPRDtoTrackMapTool> m_assoTool - {this, "AssociationTool", "Trk::PRDtoTrackMapTool" }; - - ToolHandle<Trk::IExtendedTrackSummaryTool> m_trackSummaryTool - {this, "TrackSummaryTool", "InDetTrackSummaryToolNoHoleSearch"}; - - /** selection tool - here the decision which hits remain on a track and - which are removed are made - */ + /** association tool **/ + ToolHandle<Trk::IPRDtoTrackMapTool> m_assoTool{this, "AssociationTool", "Trk::PRDtoTrackMapTool" }; + /** selection tool - here the decision which hits remain on a track and which are removed are made */ ToolHandle<IAmbiTrackSelectionTool> m_selectionTool; - /** monitoring statistics */ - //enum RegionIndex {iBarrel , iTransi , iEndcap , iDBM = 4, nRegions=4}; - std::vector<float> m_etabounds; //!< Four eta intervals for internal monitoring - mutable std::mutex m_statMutex; - mutable Counter m_stat ATLAS_THREAD_SAFE; - }; } //end ns diff --git a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackAmbiguityScoreProcessorTool.h b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackAmbiguityScoreProcessorTool.h index 8217278628edae32df92266838df85024d74a7b8..13600e08b2a953d0619264c92b8a252c2d952ccc 100644 --- a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackAmbiguityScoreProcessorTool.h +++ b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackAmbiguityScoreProcessorTool.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration */ #ifndef ITRKAMBIGUITYSCOREPROCESSORTOOL_H @@ -14,7 +14,7 @@ static const InterfaceID IID_ITrackAmbiguityScoreProcessorTool("Trk::ITrackAmbig namespace Trk { -/** @brief Interface for resolving hit assoication ambiguities in a given track collection. +/** @brief Interface for resolving hit association ambiguities in a given track collection. The TrkAmbiguityScoreProcessor attempts to improve the 'score' of an event, where the score of an event is the summed scores of all the tracks it contains. @@ -28,11 +28,9 @@ class ITrackAmbiguityScoreProcessorTool : virtual public IAlgTool @param tracks collection of tracks which will have ambiguities resolved. Will not be modified. @return map of score and track. Ownership is passed on (i.e. client handles deletion)*/ - virtual void process(std::vector<const Track*>* tracks , TracksScores* scoredTracks) const = 0; - - /** Print statistics at the end of the processing. - */ - virtual void statistics() = 0; + virtual void process(const TrackCollection & tracks , TracksScores* scoredTracks) const = 0; + //Print statistics at the end of the processing. + virtual void statistics() = 0; };