diff --git a/.gitignore b/.gitignore index 4ecc3356a1d4a5160682ddba2dbe3ca90b71436d..7ed00b371824a8816c3ef9d10c186352e00fef2c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ .project *.pyc .asetup* +.cproject diff --git a/Trigger/TrigFTK/FTK_DataProviderSvc/FTK_DataProviderSvc/FTK_DataProviderSvc.h b/Trigger/TrigFTK/FTK_DataProviderSvc/FTK_DataProviderSvc/FTK_DataProviderSvc.h index bb4bdffa1f9e0e6fe3ed806ddbe35ec721d5dc9d..9a161d563921673ec4f58f92e18efa2ad62367e6 100644 --- a/Trigger/TrigFTK/FTK_DataProviderSvc/FTK_DataProviderSvc/FTK_DataProviderSvc.h +++ b/Trigger/TrigFTK/FTK_DataProviderSvc/FTK_DataProviderSvc/FTK_DataProviderSvc.h @@ -32,6 +32,7 @@ #include "xAODTracking/VertexContainer.h" #include "xAODTracking/TrackParticleContainer.h" #include "FTK_DataProviderInterfaces/IFTK_UncertaintyTool.h" +#include "FTK_RecToolInterfaces/IFTK_DuplicateTrackRemovalTool.h" /// Forward Declarations /// class AtlasDetectorID; @@ -173,14 +174,16 @@ class FTK_DataProviderSvc : public virtual IFTK_DataProviderSvc, virtual public ToolHandle< InDet::IVertexFinder > m_VertexFinderTool; ToolHandle< IFTK_VertexFinderTool > m_RawVertexFinderTool; ToolHandle< Trk::IRIO_OnTrackCreator > m_ROTcreator; + ToolHandle< IFTK_DuplicateTrackRemovalTool > m_DuplicateTrackRemovalTool; double m_trainingBeamspotX; double m_trainingBeamspotY; double m_trainingBeamspotZ; double m_trainingBeamspotTiltX; double m_trainingBeamspotTiltY; - - + + bool m_remove_duplicates; + const FTK_RawTrackContainer* m_ftk_tracks; // Track Cache diff --git a/Trigger/TrigFTK/FTK_DataProviderSvc/src/FTK_DataProviderSvc.cxx b/Trigger/TrigFTK/FTK_DataProviderSvc/src/FTK_DataProviderSvc.cxx index 46d3a13a98a4ea447b59af9fcad5b5d72d45309b..d4541bd9c11396cb5c020ba28c93bce393d3ef91 100644 --- a/Trigger/TrigFTK/FTK_DataProviderSvc/src/FTK_DataProviderSvc.cxx +++ b/Trigger/TrigFTK/FTK_DataProviderSvc/src/FTK_DataProviderSvc.cxx @@ -53,6 +53,7 @@ #include "PixelConditionsServices/IPixelOfflineCalibSvc.h" #include "TrkToolInterfaces/ITrackSummaryTool.h" #include "TrkTrackSummary/TrackSummary.h" +#include "FTK_RecToolInterfaces/IFTK_DuplicateTrackRemovalTool.h" #include "FTK_RecToolInterfaces/IFTK_VertexFinderTool.h" #include "FTK_DataProviderInterfaces/IFTK_UncertaintyTool.h" @@ -102,11 +103,13 @@ FTK_DataProviderSvc::FTK_DataProviderSvc(const std::string& name, ISvcLocator* s m_VertexFinderTool("InDet::InDetIterativePriVxFinderTool"), m_RawVertexFinderTool("FTK_VertexFinderTool"), m_ROTcreator("Trk::IRIO_OnTrackCreator/FTK_ROTcreatorTool"), + m_DuplicateTrackRemovalTool("FTK_DuplicateTrackRemovalTool"), m_trainingBeamspotX(0.), m_trainingBeamspotY(0.), m_trainingBeamspotZ(0.), m_trainingBeamspotTiltX(0.), m_trainingBeamspotTiltY(0.), + m_remove_duplicates(false), m_ftk_tracks(nullptr), m_conv_tracks(nullptr), m_refit_tracks(nullptr), @@ -181,6 +184,7 @@ FTK_DataProviderSvc::FTK_DataProviderSvc(const std::string& name, ISvcLocator* s declareProperty("TrackFitter", m_trackFitter); declareProperty("UncertaintyTool",m_uncertaintyTool); declareProperty("TrackSummaryTool", m_trackSumTool); + declareProperty("DuplicateTrackRemovalTool",m_DuplicateTrackRemovalTool); declareProperty("TrackParticleCreatorTool", m_particleCreatorTool); declareProperty("VertexFinderTool",m_VertexFinderTool); declareProperty("ROTcreatorTool",m_ROTcreator); @@ -208,7 +212,7 @@ FTK_DataProviderSvc::FTK_DataProviderSvc(const std::string& name, ISvcLocator* s declareProperty("CorrectSCTClusters",m_correctSCTClusters); declareProperty("setBroadPixelClusterOnTrackErrors",m_broadPixelErrors); declareProperty("setBroadSCT_ClusterOnTrackErrors",m_broadSCT_Errors); - + declareProperty("RemoveDuplicates",m_remove_duplicates); } @@ -271,6 +275,8 @@ StatusCode FTK_DataProviderSvc::initialize() { ATH_CHECK(m_particleCreatorTool.retrieve()); ATH_MSG_INFO( " getting vertexFinderTool tool with name " << m_VertexFinderTool.name()); ATH_CHECK(m_VertexFinderTool.retrieve()); + ATH_MSG_INFO( " getting DuplicateTrackRemovalTool tool with name " << m_DuplicateTrackRemovalTool.name()); + ATH_CHECK(m_DuplicateTrackRemovalTool.retrieve()); ATH_MSG_INFO( " getting FTK_RawTrackVertexFinderTool tool with name " << m_RawVertexFinderTool.name()); ATH_CHECK(m_RawVertexFinderTool.retrieve()); ATH_MSG_INFO( " getting ROTcreator tool with name " << m_ROTcreator.name()); @@ -1142,23 +1148,33 @@ void FTK_DataProviderSvc::getFTK_RawTracksFromSG(){ } // new event - get the tracks from StoreGate - if (!m_storeGate->contains<FTK_RawTrackContainer>(m_RDO_key)) { - ATH_MSG_DEBUG( "getFTK_RawTracksFromSG: FTK tracks "<< m_RDO_key <<" not found in StoreGate !"); - return; - } else { - ATH_MSG_VERBOSE( "getFTK_RawTracksFromSG: Doing storegate retreive"); - StatusCode sc = m_storeGate->retrieve(m_ftk_tracks, m_RDO_key); - if (sc.isFailure()) { - ATH_MSG_VERBOSE( "getFTK_RawTracksFromSG: Failed to get FTK Tracks Container"); - return; - } - ATH_MSG_DEBUG( "getFTK_RawTracksFromSG: Got " << m_ftk_tracks->size() << " raw FTK tracks (RDO) from StoreGate "); - m_gotRawTracks = true; - + ATH_MSG_DEBUG( "getFTK_RawTracksFromSG: FTK tracks "<< m_RDO_key <<" not found in StoreGate !"); + return; + } else { + if (m_remove_duplicates){//get all tracks, and then call duplicate removal tool + const FTK_RawTrackContainer* temporaryTracks=nullptr; + StatusCode sc = m_storeGate->retrieve(temporaryTracks, m_RDO_key); + ATH_MSG_DEBUG( "getFTK_RawTracksFromSG: Got " << temporaryTracks->size() << " raw FTK tracks (RDO) from StoreGate "); + m_ftk_tracks = m_DuplicateTrackRemovalTool->removeDuplicates(temporaryTracks); + if (sc.isFailure()) { + ATH_MSG_WARNING( "getFTK_RawTracksFromSG: Failed to get FTK Tracks Container when using removeDumplicates "); + return; + } + } + else{//the original way + ATH_MSG_VERBOSE( "getFTK_RawTracksFromSG: Doing storegate retrieve"); + StatusCode sc = m_storeGate->retrieve(m_ftk_tracks, m_RDO_key); + if (sc.isFailure()) { + ATH_MSG_WARNING( "getFTK_RawTracksFromSG: Failed to get FTK Tracks Container"); + return; + } + } + ATH_MSG_DEBUG( "getFTK_RawTracksFromSG: Got " << m_ftk_tracks->size() << " raw FTK tracks"); + m_gotRawTracks = true; } + // Creating collection for pixel clusters - m_PixelClusterContainer = new InDet::PixelClusterContainer(m_pixelId->wafer_hash_max()); m_PixelClusterContainer->addRef(); StatusCode sc = m_storeGate->record(m_PixelClusterContainer,m_PixelClusterContainerName); @@ -1339,7 +1355,7 @@ Trk::Track* FTK_DataProviderSvc::ConvertTrack(const unsigned int iTrack){ // Find if the track includes IBL - needed for the error calculaton for( unsigned int cluster_number = 0; cluster_number < track.getPixelClusters().size(); ++cluster_number){ if ( !track.isMissingPixelLayer(cluster_number)) { - Identifier wafer_id = m_pixelId->wafer_id(track.getPixelClusters()[cluster_number].getModuleID()); + Identifier wafer_id = m_pixelId->wafer_id(Identifier(track.getPixelClusters()[cluster_number].getModuleID())); if (m_pixelId->barrel_ec(wafer_id)==0 && m_pixelId->layer_disk(wafer_id)==0) { hasIBL=true; break; diff --git a/Trigger/TrigFTK/FTK_RecToolInterfaces/FTK_RecToolInterfaces/IFTK_DuplicateTrackRemovalTool.h b/Trigger/TrigFTK/FTK_RecToolInterfaces/FTK_RecToolInterfaces/IFTK_DuplicateTrackRemovalTool.h new file mode 100644 index 0000000000000000000000000000000000000000..dc4fbffa813afd924436d23d9d18e2cd873c901f --- /dev/null +++ b/Trigger/TrigFTK/FTK_RecToolInterfaces/FTK_RecToolInterfaces/IFTK_DuplicateTrackRemovalTool.h @@ -0,0 +1,25 @@ + +//abstract interface + +#ifndef __IFTK_DUPLICATETRACKREMOVAL_TOOL_H__ +#define __IFTK_DUPLICATETRACKREMOVAL_TOOL_H__ + +#include "GaudiKernel/IAlgTool.h" +#include "TrigFTK_RawData/FTK_RawTrackContainer.h" + +static const InterfaceID IID_IFTK_DuplicateTrackRemovalTool("IFTK_DuplicateTrackRemovalTool",1,0); + +class IFTK_DuplicateTrackRemovalTool : virtual public IAlgTool { + + public: + /** other standard AlgTool methods */ + static const InterfaceID& interfaceID () //!< the Tool's interface + { return IID_IFTK_DuplicateTrackRemovalTool; } + + virtual FTK_RawTrackContainer* removeDuplicates(const FTK_RawTrackContainer* trks) = 0; + + private: + +}; + +#endif diff --git a/Trigger/TrigFTK/FTK_RecTools/FTK_RecTools/FTK_DuplicateTrackRemovalTool.h b/Trigger/TrigFTK/FTK_RecTools/FTK_RecTools/FTK_DuplicateTrackRemovalTool.h new file mode 100644 index 0000000000000000000000000000000000000000..45f4f573350175b857503eb7059a3f00b6b5b02f --- /dev/null +++ b/Trigger/TrigFTK/FTK_RecTools/FTK_RecTools/FTK_DuplicateTrackRemovalTool.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//////////////////////////////////////////////////////////////////////////////// +// FTK_DuplicateTrackRemovalTool tool +// ------------------------------- +// Remove duplicate (overlapping) tracks +// June 2017: Tool created +// Author: Andy Haas, NYU +// e-mail: ahaas@cern.ch +//////////////////////////////////////////////////////////////////////////////// + +#ifndef __TRIG_FTK_DUPLICATETRACKREMOVAL_TOOL_H__ +#define __TRIG_FTK_DUPLICATETRACKREMOVAL_TOOL_H__ + +#include "GaudiKernel/ToolHandle.h" +#include "AthenaBaseComps/AthAlgTool.h" +#include "FTK_RecToolInterfaces/IFTK_DuplicateTrackRemovalTool.h" +#include "TrigFTK_RawData/FTK_RawTrackContainer.h" +#include <map> + +//#define FTKDuplicateTrackRemovalTiming +#define FTKDuplicateTrackRemovalUseMap +//#define FTKDuplicateTrackRemovalTestMultiple + +class FTK_DuplicateTrackRemovalTool : public AthAlgTool, virtual public IFTK_DuplicateTrackRemovalTool +{ + public: + FTK_DuplicateTrackRemovalTool( const std::string&, const std::string&, const IInterface* ); + virtual ~FTK_DuplicateTrackRemovalTool(){}; + virtual StatusCode initialize(); + virtual StatusCode finalize (); + FTK_RawTrackContainer* removeDuplicates(const FTK_RawTrackContainer* trks); + private: + FTK_RawTrackContainer* m_trks_nodups; + bool match(const FTK_RawTrack* track, const FTK_RawTrack* oldtrack) const; + const FTK_RawTrack* besttrack(const FTK_RawTrack* track, const FTK_RawTrack* oldtrack) const; + int m_HW_ndiff; + double m_dphi_roughmatch; +#ifdef FTKDuplicateTrackRemovalUseMap + std::map<double, std::vector<unsigned int> > phimap;//keep track of the phi of tracks in the output container - at each phi there could be a vector of track indices... + void addtophimap(double trackphi, unsigned int pos); + void removefromphimap(double trackphi, unsigned int pos); +#endif +}; + +#endif diff --git a/Trigger/TrigFTK/FTK_RecTools/src/FTK_DuplicateTrackRemovalTool.cxx b/Trigger/TrigFTK/FTK_RecTools/src/FTK_DuplicateTrackRemovalTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d4d8556e2aaad1ffa86ca04dc675b38ffc7d90d3 --- /dev/null +++ b/Trigger/TrigFTK/FTK_RecTools/src/FTK_DuplicateTrackRemovalTool.cxx @@ -0,0 +1,303 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FTK_RecTools/FTK_DuplicateTrackRemovalTool.h" +#include <vector> +#include "TVector2.h" +#include "CLHEP/Units/PhysicalConstants.h" + +FTK_DuplicateTrackRemovalTool::FTK_DuplicateTrackRemovalTool(const std::string& t, + const std::string& n, + const IInterface* p ): + AthAlgTool(t,n,p), + m_trks_nodups(NULL), + m_HW_ndiff(6), + m_dphi_roughmatch(0.3) +{ + declareInterface< IFTK_DuplicateTrackRemovalTool >( this ); + declareProperty("HW_ndiff",m_HW_ndiff); + declareProperty("dphi_roughmatch",m_dphi_roughmatch); +} + +StatusCode FTK_DuplicateTrackRemovalTool::initialize() { + + StatusCode sc = AlgTool::initialize(); + MsgStream athenaLog(msgSvc(), name()); + + m_trks_nodups = new FTK_RawTrackContainer(SG::VIEW_ELEMENTS);//we don't own the tracks, we're just going to hold them + + athenaLog << MSG::INFO << "FTK_DuplicateTrackRemovalTool initialized "<< endmsg; + return sc; +} + +StatusCode FTK_DuplicateTrackRemovalTool::finalize() { + StatusCode sc = AlgTool::finalize(); + m_trks_nodups->clear(); + delete m_trks_nodups; + return sc; +} + +//tell whether the two tracks match, based on number of matching hits and unmatching hits +bool FTK_DuplicateTrackRemovalTool::match(const FTK_RawTrack* track, const FTK_RawTrack* oldtrack) const { + + const std::vector<FTK_RawPixelCluster>& pixclus = track->getPixelClusters(); + const std::vector<FTK_RawSCT_Cluster>& sctclus = track->getSCTClusters(); + + //Note to self: Clusters are made from sim in FTK_RDO_CreatorAlgo... + + int nclus = pixclus.size() + sctclus.size(); + int nmatchingclus=0; + int nclusleft=12;// there's at most 12 hits, 4 pixel and 8 sct + const std::vector<FTK_RawPixelCluster>& oldpixclus = oldtrack->getPixelClusters(); + for (auto clus : pixclus){ + //is this pixel clus matched by any on the old track? + unsigned int id = clus.getModuleID(); + for (auto oldclus : oldpixclus){ + if (oldclus.getModuleID()==id){ // if the ID matches, it's on the same module // stored in WordA + if (clus.getWordB()==oldclus.getWordB()) { // is it the same eta and phi position and width? // stored in WordB + nmatchingclus++; + + //it matches if the number of unmatched clusters is <= 6 (or HW_diff) + if ( (nclus-nmatchingclus) <= m_HW_ndiff){ //corresponding criteria in simulation + return true; //return as soon as we know the answer! + } + break; //we already found a matching cluster to this cluster, so no need to look for more matches to this cluster + } + } + }//loop over old tracks' clusters + nclusleft--; + if ((nclus-nmatchingclus-nclusleft)>m_HW_ndiff) return false; // no way we can get there with just nclusleft remaining + } + + const std::vector<FTK_RawSCT_Cluster>& oldsctclus = oldtrack->getSCTClusters(); + for (auto clus : sctclus){ + //is this sct clus matched by any on the old track? + unsigned int id = clus.getWord(); + for (auto oldclus : oldsctclus){ + if (oldclus.getWord()==id){ // if the word matches, it's the same dude + nmatchingclus++; + + //it matches if the number of unmatched clusters is <= 6 (or HW_diff) + if ( (nclus-nmatchingclus) <= m_HW_ndiff){ //corresponding criteria in simulation + return true; //return as soon as we know the answer! + } + break; //we already found a matching cluster to this cluster, so no need to look for more matches to this cluster + } + }//loop over old tracks' clusters + nclusleft--; + if ((nclus-nmatchingclus-nclusleft)>m_HW_ndiff) return false; // no way we can get there with just nclusleft remaining + } + + //ATH_MSG_DEBUG("Found "<<nmatchingpixclus<<" matching pix clus out of "<<pixclus.size()); + //ATH_MSG_DEBUG("Found "<<nmatchingsctclus<<" matching sct clus out of "<<sctclus.size()); + + //ATH_MSG_VERBOSE("ACH888: "<<matching<<" "<<track->getSectorID()<<" "<<track->getPhi()<<" "<<track->getCotTh()<<" "<<track->getZ0()<<" "<<oldtrack->getSectorID()<<" "<<oldtrack->getPhi()<<" "<<oldtrack->getCotTh()<<" "<<oldtrack->getZ0()); + return false; +} + +//return the better of two tracks, based on number of missing layers, and if those tie, chi2 +const FTK_RawTrack* FTK_DuplicateTrackRemovalTool::besttrack(const FTK_RawTrack* track, const FTK_RawTrack* oldtrack) const { + //return track;//ACH-temporary test to see if this is slow + + unsigned int trackhits = track->getPixelClusters().size()+track->getSCTClusters().size(); + unsigned int oldtrackhits = oldtrack->getPixelClusters().size()+oldtrack->getSCTClusters().size(); + if (trackhits > oldtrackhits) return track; + if (oldtrackhits > trackhits) return oldtrack; + + //in case of a tie, use chi2 + if (track->getChi2() < oldtrack->getChi2()) return track; // smaller chi2 wins + else return oldtrack; +} + +#ifdef FTKDuplicateTrackRemovalUseMap +void FTK_DuplicateTrackRemovalTool::addtophimap(double trackphi, unsigned int pos){ + phimap[trackphi].push_back(pos);//add it to the map + + //check that track phi is within 0-2pi + if (trackphi<-CLHEP::pi) ATH_MSG_ERROR("FTK track with phi < -pi! "<<trackphi); + else if (trackphi>CLHEP::pi) ATH_MSG_ERROR("FTK track with phi > pi! "<<trackphi); + + //add extra copy in case of wraparound past 0 or 2pi + if (trackphi>(CLHEP::pi-m_dphi_roughmatch)) phimap[trackphi-CLHEP::twopi].push_back(pos); + else if (trackphi<(-CLHEP::pi+m_dphi_roughmatch)) phimap[trackphi+CLHEP::twopi].push_back(pos); +} +void FTK_DuplicateTrackRemovalTool::removefromphimap(double oldtrackphi, unsigned int e){ + + //remove the old track from the map + auto& vec = phimap[oldtrackphi]; + auto ind = std::find(vec.begin(),vec.end(),e); + if (ind==vec.end()) ATH_MSG_WARNING("Wasn't in the map?! "<<oldtrackphi<<" "<<e); + else vec.erase(ind); + + //take of removing wraparound entries + if (oldtrackphi>(CLHEP::pi-m_dphi_roughmatch)) { + vec = phimap[oldtrackphi-CLHEP::twopi]; + auto ind = std::find(vec.begin(),vec.end(),e); + if (ind==vec.end()) ATH_MSG_WARNING("Wasn't in the map?! "<<oldtrackphi<<" "<<e); + else vec.erase(ind); + } + else if (oldtrackphi<(-CLHEP::pi+m_dphi_roughmatch)) { + vec = phimap[oldtrackphi+CLHEP::twopi]; + auto ind = std::find(vec.begin(),vec.end(),e); + if (ind==vec.end()) ATH_MSG_WARNING("Wasn't in the map?! "<<oldtrackphi<<" "<<e); + else vec.erase(ind); + } +} +#endif + +FTK_RawTrackContainer* FTK_DuplicateTrackRemovalTool::removeDuplicates(const FTK_RawTrackContainer* trks){ + +#ifdef FTKDuplicateTrackRemovalTiming + clock_t tStart = clock(); + for (int tim=0;tim<1000;++tim){ +#endif + +#ifdef FTKDuplicateTrackRemovalUseMap + phimap.clear(); + std::set<unsigned int> trackstokill; +#endif + + ATH_MSG_DEBUG("I'm in removeDuplicates!"); + m_trks_nodups->clear(); + m_trks_nodups->reserve(trks->size()); + for (unsigned int i = 0; i!=trks->size(); i++) { + const FTK_RawTrack *track = trks->at(i); + + //now we should see whether this track overlaps with one (or more?) tracks already in the nodups container + std::vector<unsigned int> matching_oldtracks; + +#ifdef FTKDuplicateTrackRemovalUseMap + //search just the range of phi in the map of old tracks near the phi of this new track + //the map goes from -pi-dphi_roughmatch to pi+dphi_roughmatch, to handle wraparound + double trackphi = track->getPhi(); + auto lower = phimap.lower_bound(trackphi-m_dphi_roughmatch); + auto upper = phimap.upper_bound(trackphi+m_dphi_roughmatch); + for (auto it=lower; it!=upper; it++){ + for (unsigned int e : it->second) {//these are the indices of the old tracks at each phi value in the phi range + //ATH_MSG_DEBUG("Looking for match of track "<<i<<" with oldtrack "<<e); + const FTK_RawTrack *oldtrack = m_trks_nodups->at(e); + if (this->match(track,oldtrack)) { + matching_oldtracks.push_back(e); + } + } + } +#else + //loop over all old tracks and see if they match + for (unsigned int e = 0; e!=m_trks_nodups->size(); e++) { + const FTK_RawTrack *oldtrack = m_trks_nodups->at(e); + + //first check for a rough match in phi + double dphi = TVector2::Phi_mpi_pi(track->getPhi()-oldtrack->getPhi());//make sure it's in -pi..pi + dphi = fabs(dphi);//then take abs since we don't care about sign + if (dphi>m_dphi_roughmatch) continue;//no match if dphi is larger than dphi_roughmatch, 0.3 by default + + if (this->match(track,oldtrack)) { + matching_oldtracks.push_back(e); + } + } +#endif + + //ATH_MSG_DEBUG("Found "<<matching_oldtracks.size()<<" old tracks matching track "<<i); + if (matching_oldtracks.size()==0){//if there's no match, just add the new track +#ifdef FTKDuplicateTrackRemovalTestMultiple + for (int j=0; j<3; ++j){ // ACH - temporary test - add multiple times, to test multiple matches! +#endif +#ifdef FTKDuplicateTrackRemovalUseMap + addtophimap(trackphi,m_trks_nodups->size());//so e.g. the first track will be index 0, since the size is 0 just before we push_back the first track +#endif + m_trks_nodups->push_back((FTK_RawTrack*)track); +#ifdef FTKDuplicateTrackRemovalTestMultiple + } // ACH - temporary test - add multiple times, to test multiple matches! +#endif + } + + //if it does match, either replace the matching track(s) with this new track, or ignore this new track, depending on which track we like best + else if (matching_oldtracks.size()==1){ + unsigned int e = matching_oldtracks[0]; + const FTK_RawTrack *oldtrack = m_trks_nodups->at(e); + const FTK_RawTrack *besttrack = this->besttrack(track,oldtrack); + if (besttrack==track){ +#ifdef FTKDuplicateTrackRemovalUseMap + removefromphimap(oldtrack->getPhi(),e);//remove the old track from the map + addtophimap(trackphi,e);//add the new track to the map +#endif + m_trks_nodups->at(e)=(FTK_RawTrack*)track; + } + else{ + //nothing to do - the better track was already in the output container + } + } + + else { // more than 1 matching existing track (yet the existing matching tracks did not match each other) + ATH_MSG_WARNING("Found multiple tracks ("<<matching_oldtracks.size()<<") matching track "<<i); + + // is the new track better than all the matching old tracks? + bool newisbest = true;//start with an optimistic attitude! + for (unsigned int e : matching_oldtracks){ + const FTK_RawTrack *oldtrack = m_trks_nodups->at(e); + const FTK_RawTrack *besttrack = this->besttrack(track,oldtrack); + if (besttrack!=track){ + newisbest=false; // guess we're not the best, give up! + break; + } + } + + // if the new track is better than all the matching old tracks, remove the old tracks and add this one, otherwise do nothing (the new track is dropped) + if (newisbest){ + //yikes, we're better than all the matching old tracks + bool replacedfirsttrack = false;//I want to check that the algorithm really replaces the first old track with the new one, and just once + for (unsigned int e : matching_oldtracks){ + +#ifdef FTKDuplicateTrackRemovalUseMap + removefromphimap(m_trks_nodups->at(e)->getPhi(),e); +#endif + if (e==matching_oldtracks[0]) {//this should be a little faster than removing all the old matching tracks and then adding the new one + +#ifdef FTKDuplicateTrackRemovalUseMap + addtophimap(trackphi,e); +#endif + m_trks_nodups->at(e)=(FTK_RawTrack*)track; // replace the first matching track with this new track + if (replacedfirsttrack) ATH_MSG_WARNING("We already did replace the first matching track!"); + replacedfirsttrack=true;//just check that we really did it! + } + else { + //remove the old matching tracks beyond the first one +#ifdef FTKDuplicateTrackRemovalUseMap + trackstokill.insert(e);//we'll remove these from the tracks returned at the end of the day, so we don't screw up the map in the meantime +#else + m_trks_nodups->erase(m_trks_nodups->begin()+e); // yes this is really the way you remove an element from a vector, you have to pass in the iterator +#endif + } + } + if (!replacedfirsttrack) ATH_MSG_WARNING("Why did I not replace the first track?!"); + + } // new track is best one + + } // deciding what to do based on the number of matches + + } // loop over incoming tracks + +#ifdef FTKDuplicateTrackRemovalUseMap + //remove those tracks that we flagged for killing + if (trackstokill.size()){ + ATH_MSG_WARNING("Killing an extra "<<trackstokill.size()<<" tracks from multiple matches"); + FTK_RawTrackContainer* trks_nodups_temp = new FTK_RawTrackContainer(SG::VIEW_ELEMENTS);//we don't own the tracks, we're just going to hold them + for (unsigned int e = 0; e!=m_trks_nodups->size(); e++) { + if (std::find(trackstokill.begin(),trackstokill.end(),e)==trackstokill.end()) trks_nodups_temp->push_back((FTK_RawTrack*)m_trks_nodups->at(e)); + } + m_trks_nodups->clear(); + delete m_trks_nodups; + m_trks_nodups = trks_nodups_temp; + } +#endif + +#ifdef FTKDuplicateTrackRemovalTiming + } // loop over doing the removal + clock_t tEnd = clock(); + double elapsed_secs = double(tEnd - tStart) / CLOCKS_PER_SEC; + ATH_MSG_INFO("Time taken: "<<elapsed_secs<<" ms");//it's "ms", not "s", since we did 1000 times +#endif + + return m_trks_nodups; +} diff --git a/Trigger/TrigFTK/FTK_RecTools/src/components/FTK_RecTools_entries.cxx b/Trigger/TrigFTK/FTK_RecTools/src/components/FTK_RecTools_entries.cxx index f376046dab2dd39d49f034fe50f97b6bb725c999..ee4c8bcdf7c0fc3635a6597d65705c74b5435457 100644 --- a/Trigger/TrigFTK/FTK_RecTools/src/components/FTK_RecTools_entries.cxx +++ b/Trigger/TrigFTK/FTK_RecTools/src/components/FTK_RecTools_entries.cxx @@ -3,13 +3,16 @@ #include "FTK_RecTools/FTK_VertexFinderTool.h" #include "FTK_RecTools/FTK_PixelClusterOnTrackTool.h" #include "FTK_RecTools/FTK_SCTClusterOnTrackTool.h" +#include "FTK_RecTools/FTK_DuplicateTrackRemovalTool.h" DECLARE_TOOL_FACTORY(FTK_VertexFinderTool) DECLARE_TOOL_FACTORY(FTK_PixelClusterOnTrackTool) DECLARE_TOOL_FACTORY(FTK_SCTClusterOnTrackTool) +DECLARE_TOOL_FACTORY(FTK_DuplicateTrackRemovalTool) DECLARE_FACTORY_ENTRIES(FTK_RecTools) { DECLARE_TOOL(FTK_VertexFinderTool) DECLARE_TOOL(FTK_PixelClusterOnTrackTool) DECLARE_TOOL(FTK_SCTClusterOnTrackTool) + DECLARE_TOOL(FTK_DuplicateTrackRemovalTool) }