diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetConversionTrackSelectorTool.h b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetConversionTrackSelectorTool.h new file mode 100644 index 0000000000000000000000000000000000000000..61365aa4b8f11932df56d3cd2eb3556c2f15efaf --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetConversionTrackSelectorTool.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef InDetTrackSelectorTool_InDetConversionTrackSelectorTool_H +#define InDetTrackSelectorTool_InDetConversionTrackSelectorTool_H + +//#include "GaudiKernel/MsgStream.h" +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/ServiceHandle.h" +#include "TrkToolInterfaces/ITrackSelectorTool.h" +#include "xAODTracking/TrackParticle.h" + +/** + * A tool to be used for track preselection in conversion + * vertex finding. + * + * Thomas Koffas <Thomas.Koffas@cern.ch> + * June 2008 + */ + +class IBeamCondSvc; + +namespace Trk +{ + class ITrackSummaryTool; + class Vertex; + class IExtrapolator; + class Track; + class TrackParticleBase; +} + +namespace InDet +{ + + class InDetConversionTrackSelectorTool : virtual public Trk::ITrackSelectorTool, public AthAlgTool + { + + public: + + StatusCode initialize(); + + StatusCode finalize(); + + InDetConversionTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p); + + ~InDetConversionTrackSelectorTool(); + + /** Select a Trk::Track */ + bool decision(const Trk::Track& track,const Trk::Vertex* vertex) const; + + /** Select a Trk::TrackParticleBase */ + bool decision(const Trk::TrackParticleBase& track,const Trk::Vertex* vertex) const; + + bool decision(const xAOD::TrackParticle&,const xAOD::Vertex*) const ; + + + + private: + + int getCount( const xAOD::TrackParticle& tp, xAOD::SummaryType type ) const { + uint8_t val; + if( !tp.summaryValue(val,type) ) return 0; + return val > 0 ? val : 0; + } + + + ToolHandle <Trk::ITrackSummaryTool> m_trkSumTool; //!< Track summary tool + ToolHandle<Trk::IExtrapolator> m_extrapolator; //!< Extrapolator tool + ServiceHandle<IBeamCondSvc> m_iBeamCondSvc; //!< pointer to the beam condition service + + /** Properties for track selection:all cuts are ANDed */ + double m_maxSiD0; //!< Maximal d0 at (0,0,0) for tracks with Si hits + double m_maxTrtD0; //!< Maximal d0 at (0,0,0) for standalone TRT tracks + double m_maxSiZ0; //!< Maximal z0 at (0,0,0) + double m_maxTrtZ0; //!< Maximal z0 at (0,0,0) for standalone TRT tracks + double m_minPt; //!< Minimum Pt of tracks + double m_trRatio1; //!< TR ratio for tracks with 15-20 TRT hits + double m_trRatio2; //!< TR ratio for tracks with 20-25 TRT hits + double m_trRatio3; //!< TR ratio for tracks with >25 TRT hits + double m_trRatioTRT;//!< TR ratio for TRT only tracks + double m_trRatioV0;//!< TR ratio for pion selection during V0 reconstruction + double m_sD0_Si; //!< Cut on D0 significance of Si tracks + double m_sD0_Trt; //!< Cut on D0 significance of TRT tracks + double m_sZ0_Trt; //!< Cut on Z0 significance of TRT tracks + bool m_isConv; //!< Conversion flag + bool m_PIDonlyForXe; //!< Only check TRT PID if all hits are Xe hits + + }; //end of class definitions +} //end of namespace definitions + +#endif diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetCosmicTrackSelectorTool.h b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetCosmicTrackSelectorTool.h new file mode 100644 index 0000000000000000000000000000000000000000..33b7281ebe3bd81b621d8ce3273351991cea2643 --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetCosmicTrackSelectorTool.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef InDetTrackSelectorTool_InDetCosmicTrackSelectorTool_H +#define InDetTrackSelectorTool_InDetCosmicTrackSelectorTool_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/ServiceHandle.h" +#include "TrkToolInterfaces/ITrackSelectorTool.h" +#include "TrkEventPrimitives/ParticleHypothesis.h" +#include "TrkParameters/TrackParameters.h" + +namespace Trk +{ + class IMagneticFieldTool; + class ITrackSummaryTool; + class Vertex; + class TrackParticleBase; + class Track; +} + +namespace MagField { + class IMagFieldSvc; +} + +namespace InDet +{ + + class InDetCosmicTrackSelectorTool : virtual public Trk::ITrackSelectorTool, public AthAlgTool + { + + public: + + StatusCode initialize(); + + StatusCode finalize(); + + InDetCosmicTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p); + + ~InDetCosmicTrackSelectorTool(); + + bool decision(const Trk::Track& track,const Trk::Vertex* vertex) const; + + bool decision(const Trk::TrackParticleBase& track,const Trk::Vertex* vertex) const; + + bool decision(const xAOD::TrackParticle&,const xAOD::Vertex*) const { + ATH_MSG_WARNING("xAOD::TrackParticle selection not implemented yet"); + return false; + } + + private: + + int getNSiHits(const Trk::Track* track, bool top) const; + bool decision(const Trk::TrackParameters* track, const Trk::Vertex* vertex, const Trk::ParticleHypothesis) const; + double m_maxZ0; //!< Maximum z0 of tracks + double m_maxD0; //!< Maximum d0 of tracks + double m_minPt; //!< Minimum pT of tracks + int m_numberOfPixelHits; //!< Minimum number of Pixel hits + int m_numberOfSCTHits; //!< Minimum number of SCT hits + int m_numberOfTRTHits; //!< Minimum number of TRT hits + int m_numberOfSiHits; //!< Minimum number of Silicon hits + int m_numberOfSiHitsTop; //!< Minimum number of Silicon hits + int m_numberOfSiHitsBottom; //!< Minimum number of Silicon hits + + ToolHandle<Trk::ITrackSummaryTool> m_trackSumTool; + bool m_trackSumToolAvailable; + + ServiceHandle<MagField::IMagFieldSvc> m_magFieldSvc; + + + + }; //end of class definitions +} //end of namespace definitions + +#endif //TrkMultipleVertexSeedFinders_PVFindingTrackSelectoTool_H diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetDetailedTrackSelectorTool.h b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetDetailedTrackSelectorTool.h new file mode 100644 index 0000000000000000000000000000000000000000..6817f9d945791d7f39db49aafbcc23b139ff0a4c --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetDetailedTrackSelectorTool.h @@ -0,0 +1,173 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef InDetDetailedTrackSelectorTool_InDetDetailedTrackSelectorTool_H +#define InDetDetailedTrackSelectorTool_InDetDetailedTrackSelectorTool_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/ServiceHandle.h" +#include "TrkToolInterfaces/ITrackSelectorTool.h" +#include "TrkParameters/TrackParameters.h" +#include "xAODTracking/TrackParticle.h" +#include "xAODTracking/VertexFwd.h" + +/** + * @file InDetDetailedTrackSelectorTool.h + * @class InDetDetailedTrackSelectorTool + * + * @brief TrackSelector for general use + * + * The option for anyDirection: + * Required for cosmic tracks: mixture of tracks with different reo logic. + * Default is the extrapolation oppositeToMomentum, which is required for collision tracks. + * + * @author Giacinto Piacquadio <giacinto.piacquadio@physik.uni-freiburg.de> + * @author Kirill Prokofiev <Kirill.Prokofiev@cern.ch> + * @author Daniel Kollar <daniel.kollar@cern.ch> + */ + +class IBeamCondSvc; + + +namespace MagField { + class IMagFieldSvc; +} + +namespace Trk +{ + class IMagneticFieldTool; + class ITrackSummaryTool; + class IExtrapolator; + class Vertex; + class RecVertex; + class FitQuality; + class TrackSummary; + class Track; + class TrackParticleBase; +} + +namespace InDet +{ + class ITrtDriftCircleCutTool; + class IInDetTestBLayerTool; + + + class InDetDetailedTrackSelectorTool : virtual public Trk::ITrackSelectorTool, public AthAlgTool + { + + public: + + enum Grade { Undefined, Good, Shared, nbGrades }; + + StatusCode initialize(); + + StatusCode finalize(); + + InDetDetailedTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p); + + ~InDetDetailedTrackSelectorTool(); + + bool decision(const Trk::Track& track,const Trk::Vertex* vertex) const; + + bool decision(const Trk::TrackParticleBase& track,const Trk::Vertex* vertex) const; + + bool decision(const xAOD::TrackParticle& track,const xAOD::Vertex* vertex) const; + + private: + int getCount( const xAOD::TrackParticle& tp, xAOD::SummaryType type ) const { + uint8_t val; + if( !tp.summaryValue(val,type) ) return 0; + return val > 0 ? val : 0; + } + bool decision(const Trk::Perigee* track,const AmgSymMatrix(3)* covariancePosition) const; + bool decision(const Trk::FitQuality* TrkQuality) const; + bool decision(double chi2, int ndf ) const; + bool decision(const Trk::TrackSummary* summary,bool useSharedHitInfo,bool useTrtHitInfo, + const Trk::Perigee* track) const; + + bool preselectionBeforeExtrapolation(const Trk::Perigee & myPerigee) const; + + double m_pTMin; //<! min. pT: |pT|>pTMin + double m_pMin; //<! min. p = pT/cos(theta): |p| > pMin + double m_IPd0Max; //<! max. d0: |d0|<d0Max + double m_IPz0Max; //<! max. z0: |z0*sin(theta)|<z0Max + double m_z0Max; //<! max. z0: |z0|<z0Max + double m_sigIPd0Max; //<! max sig IP d0: + double m_sigIPz0Max; //<! max sig IP z0 (error only due to z0)*sin(theta) + double m_d0significanceMax; //<! max IP significance d0 (-1 switches it off) + double m_z0significanceMax; //<! max IP significance z0 (-1 switches it off) + double m_etaMax; //<! max. pseudo-rapidity + + bool m_useTrackSummaryInfo; //<! if false the following cuts are ignored + + int m_nHitBLayer; //<! at least n hits in Blayer + int m_nHitPix; //<! at least n hits in pixels + int m_nHitBLayerPlusPix; //<! at least n hits in blayer+pixel + int m_nHitSct; //<! at least n hits in SCT + int m_nHitSi; //<! at least n hits in pixels+SCT + + int m_nHitPixPhysical; //!< at least n physical hits in pixel + int m_nHitSiPhysical; //!< at least n physical hits in pixel+SCT + + mutable int m_nHitTrt; //<! at least n hits in TRT + mutable int m_nHitTrtPlusOutliers; //<! at least n hits in TRT (including outliers) + + //<! for selecting electrons (soft E-ID) + int m_nHitTrtHighE; //<! at least n high threshold hits in TRT + int m_nHitTrtPlusOutliersHighE; //<! at least n high threshold hits in TRT (including outliers) + //<! for rejecting electrons (tau-ID) + double m_nHitTrtHighEFraction; //<! maximum x fraction of transition hits in TRT + double m_nHitTrtHighEFractionWithOutliers; //<! maximum x fraction of transition hits in TRT (including outliers) + + double m_TrtMaxEtaAcceptance;//<! limit of eta regions where trt hits are expected + bool m_useSharedHitInfo; //<! if false the following cuts are ignored + int m_nSharedBLayer;//<! max. number of shared hits in B layer + int m_nSharedPix; //<! max. number of shared hits in pixels + int m_nSharedSct; //<! max. number of shared hits in SCT + int m_nSharedSi; //<! max. number of shared hits in pixels+SCT + + int m_nHoles; //<! max. number of holes in pixel+SCT + int m_nDoubleHoles; //<! max number of double-holes in SCT + int m_nHolesPix; //<! max. number of holes in pixels + int m_nHolesSct; //<! max. number of holes in SCT + + bool m_useTrackQualityInfo; //<! if false the following cuts are ignored + double m_fitChi2; //<! max. fit chi2 + double m_fitProb; //<! min. fit chi2 probability + double m_fitChi2OnNdfMax; //<! max. fitchi2/ndf + + double m_scaleMinHitTrt; //<! scale the eta dependent minimum number of TRT hits; scaling is only applied if m_addToMinHitTrt==0 + int m_addToMinHitTrt; //<! add to/subtract from eta dependent minimum nimber of TRT hits + double m_scaleMinHitTrtWithOutliers; //<! scale the eta dependent minimum number of TRT hits + outliers; scaling is only applied if m_addToMinHitTrtWithOutliers==0 + int m_addToMinHitTrtWithOutliers; //<! add to/subtract from eta dependent minimum nimber of TRT hits + outliers + + bool m_usePreselectionCuts; + double m_d0MaxPreselection; + + bool m_useEtaDepententMinHitTrt; + bool m_useEtaDepententMinHitTrtWithOutliers; + + ToolHandle<Trk::ITrackSummaryTool> m_trackSumTool; //!< Track summary tool + ToolHandle<Trk::IExtrapolator> m_extrapolator; //!< Extrapolator tool + ServiceHandle<IBeamCondSvc> m_iBeamCondSvc; //!< pointer to the beam condition service + ServiceHandle<MagField::IMagFieldSvc> m_magFieldSvc; + ToolHandle<ITrtDriftCircleCutTool> m_trtDCTool; //!< Tool to get eta dependent cut on number of TRT hits + + ToolHandle< InDet::IInDetTestBLayerTool > m_inDetTestBLayerTool; //Tool to test if the track crosses a dead module on the b-layer + + bool m_trackSumToolAvailable; + +// chnages for the pt-dependent sct cut + bool m_usePtDependentCuts; + + std::vector<float> m_ptBenchmarks; + + std::vector<int> m_nSCTValues; + + }; //end of class definitions + +} //end of namespace definitions + +#endif //TrkMultipleVertexSeedFinders_PVFindingTrackSelectoTool_H diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetIsoTrackSelectorTool.h b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetIsoTrackSelectorTool.h new file mode 100644 index 0000000000000000000000000000000000000000..b282fadd429777f8c51562d40018cbc639a25122 --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetIsoTrackSelectorTool.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef InDetIsoTrackSelectorTool_InDetIsoTrackSelectorTool_H +#define InDetIsoTrackSelectorTool_InDetIsoTrackSelectorTool_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "TrkToolInterfaces/IIsoTrackSelectorTool.h" +#include "TrkParameters/TrackParameters.h" + +/** + * @file InDetIsoTrackSelectorTool.h + * @class InDetIsoTrackSelectorTool + * + * @brief A tool to be used for track preselection in isolation, + * the given AtaLine is the transported lepton to the BeamLine + * tracks can be checkec w.r.t to it + * + * @author Andreas Salzburger +*/ + +namespace Trk { + class IExtrapolator; + class ITrackSelectorTool; + class Track; + class TrackParticleBase; +} + +namespace InDet +{ + class InDetIsoTrackSelectorTool : virtual public Trk::IIsoTrackSelectorTool, public AthAlgTool + { + + public: + /** Athena AlgTool methods */ + StatusCode initialize(); + StatusCode finalize(); + + /** Constructor / Destructor */ + InDetIsoTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p); + ~InDetIsoTrackSelectorTool(); + + /** ESD type interface */ + bool decision(const Trk::AtaStraightLine&, const Trk::Track& track) const; + + /** AOD type interface */ + bool decision(const Trk::AtaStraightLine&, const Trk::TrackParticleBase& trackParticle) const; + + /** Work-horse interface - will ignore TrackSelector */ + bool decision(const Trk::AtaStraightLine&, const Trk::TrackParameters& trackPars) const; + + private: + /** Robust cut window setting */ + bool m_robustCuts; + bool m_applySinThetaCorrection; + double m_d0max; + double m_z0stMax; + /** Sophisticated cut window setting : d0/z0 significance - only when robustCuts off*/ + double m_d0Significance; + double m_z0Significance; + + ToolHandle<Trk::IExtrapolator> m_extrapolator; //<! Extrapolator tool + /** Extra checks on hits & holes */ + ToolHandle<Trk::ITrackSelectorTool> m_trackSelector; //!< track selector tool + + + }; //end of class definitions +} //end of namespace definitions + +#endif //TrkMultipleVertexSeedFinders_PVFindingTrackSelectoTool_H diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetTrackSelectorTool.h b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetTrackSelectorTool.h new file mode 100644 index 0000000000000000000000000000000000000000..3545328ac009030afeacc78122d6efe31c14d930 --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetTrackSelectorTool.h @@ -0,0 +1,83 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef InDetTrackSelectorTool_InDetTrackSelectorTool_H +#define InDetTrackSelectorTool_InDetTrackSelectorTool_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "TrkToolInterfaces/ITrackSelectorTool.h" +#include "TrkEventPrimitives/ParticleHypothesis.h" +#include "TrkParameters/TrackParameters.h" + +/** + * @file InDetTrackSelectorTool.h + * @class InDetTrackSelectorTool + * + * @brief A tool to be used for track preselection in primary + * vertex finding. One possible implementation of the + * track selector tool. Here all possible cuts used in the + * primary vertex finding will be implemented. The particular + * cuts will be turned on and off by user through the python + * jobOptions. + * + * @author Kirill Prokofiev <Kirill.Prokofiev@cern.ch> + * @date Mai 2007 + * + * @author Daniel Kollar <daniel.kollar@cern.ch> + */ + +namespace Trk +{ + class ITrackSummaryTool; + class Vertex; + class IExtrapolator; + class Track; + class TrackParticleBase; +} + +namespace InDet +{ + class InDetTrackSelectorTool : virtual public Trk::ITrackSelectorTool, public AthAlgTool + { + + public: + + StatusCode initialize(); + + StatusCode finalize(); + + InDetTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p); + + ~InDetTrackSelectorTool(); + + bool decision(const Trk::Track& track,const Trk::Vertex* vertex) const; + + bool decision(const Trk::TrackParticleBase& track,const Trk::Vertex* vertex) const; + + bool decision(const xAOD::TrackParticle&,const xAOD::Vertex*) const { + ATH_MSG_WARNING("xAOD::TrackParticle selection not implemented yet"); + return false; + } + + private: + + bool decision(const Trk::TrackParameters* track, const Trk::Vertex* vertex, const Trk::ParticleHypothesis) const; + + double m_minPt; //!< Minimum Pt of tracks + double m_IPz0Max; //!< max. z0: |z0*sin(theta)| < z0Max + double m_maxZ0; //!< Maximum z0 of tracks + double m_maxD0; //!< Maximum d0 of tracks + double m_maxD0overSigmaD0; //!< Maximum d0/sigmad0 of tracks + int m_numberOfPixelHits; //!< Check for silicon hits ? + int m_numberOfBLayerHits; + ToolHandle<Trk::ITrackSummaryTool> m_trackSumTool; //<! Track summary tool + bool m_trackSumToolAvailable; + + ToolHandle<Trk::IExtrapolator> m_extrapolator; //<! Extrapolator tool + + }; //end of class definitions +} //end of namespace definitions + +#endif //TrkMultipleVertexSeedFinders_PVFindingTrackSelectoTool_H diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetTrtDriftCircleCutTool.h b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetTrtDriftCircleCutTool.h new file mode 100644 index 0000000000000000000000000000000000000000..291aabe9785a1b9d68d8dba1b295cc8d97f831db --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/InDetTrackSelectorTool/InDetTrtDriftCircleCutTool.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef InDetTrackSelectorTool_InDetTrtDriftCircleCutTool_H +#define InDetTrackSelectorTool_InDetTrtDriftCircleCutTool_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/ServiceHandle.h" +#include "InDetRecToolInterfaces/ITrtDriftCircleCutTool.h" + +/** + * A tool to be used for trt segment pre-selection + * + * Thomas Koffas <Thomas.Koffas@cern.ch> + * April 2009 + */ + +class ITRT_ActiveFractionSvc; + +namespace InDet{ + + class InDetTrtDriftCircleCutTool : virtual public ITrtDriftCircleCutTool, public AthAlgTool + { + + public: + + StatusCode initialize(); + + StatusCode finalize(); + + InDetTrtDriftCircleCutTool(const std::string& t, const std::string& n, const IInterface* p); + + ~InDetTrtDriftCircleCutTool(); + + /** @brief Minimum number of drift circles using the track scoring tool */ + int minNumberDCs(const Trk::TrackParameters*) const; + + private: + + ServiceHandle<ITRT_ActiveFractionSvc> m_trtCondSvc; //!< TRT active fraction service + + /** Properties for track selection:all cuts are ANDed */ + int m_minOffset; //!< Minimum number of TRT drit circles required + bool m_param; //!< Use the new or the old parameterization + bool m_useTRT; //!< Use the TRT active fraction services to correct for dead straws + + }; //end of class definitions +} //end of namespace + +#endif diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/cmt/requirements b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..a0dc9a55b8956cce476681bac9b7db05b4688e32 --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/cmt/requirements @@ -0,0 +1,37 @@ +package InDetTrackSelectorTool + +author Kirill Prokofiev <Kirill.Prokofiev@cern.ch> + +private + +use DataModel DataModel-* Control +use AtlasCLHEP AtlasCLHEP-* External +use AtlasROOT AtlasROOT-* External +use TrkSurfaces TrkSurfaces-* Tracking/TrkDetDescr +use TrkTrack TrkTrack-* Tracking/TrkEvent +use TrkTrackSummary TrkTrackSummary-* Tracking/TrkEvent +use TrkParticleBase TrkParticleBase-* Tracking/TrkEvent +use TrkExInterfaces TrkExInterfaces-* Tracking/TrkExtrapolation +use VxVertex VxVertex-* Tracking/TrkEvent +use InDetBeamSpotService InDetBeamSpotService-* InnerDetector/InDetConditions +use TrkRIO_OnTrack TrkRIO_OnTrack-* Tracking/TrkEvent +use InDetRIO_OnTrack InDetRIO_OnTrack-* InnerDetector/InDetRecEvent +use TRT_ConditionsServices TRT_ConditionsServices-* InnerDetector/InDetConditions +use MagFieldInterfaces MagFieldInterfaces-* MagneticField +use GeoPrimitives GeoPrimitives-* DetectorDescription +use EventPrimitives EventPrimitives-* Event + +public + +use AtlasPolicy AtlasPolicy-* +use GaudiInterface GaudiInterface-* External +use AthenaBaseComps AthenaBaseComps-* Control +use TrkEventPrimitives TrkEventPrimitives-* Tracking/TrkEvent +use TrkToolInterfaces TrkToolInterfaces-* Tracking/TrkTools +use InDetRecToolInterfaces InDetRecToolInterfaces-* InnerDetector/InDetRecTools +use TrkParameters TrkParameters-* Tracking/TrkEvent +use xAODTracking xAODTracking-* Event/xAOD + +library InDetTrackSelectorTool *.cxx -s=components *.cxx +apply_pattern component_library +macro DOXYGEN_IMAGE_PATH "../doc/images" diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/images/TrackSelectorVariables.png b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/images/TrackSelectorVariables.png new file mode 100644 index 0000000000000000000000000000000000000000..05a12100b8707a765928692464cd49edead19c35 Binary files /dev/null and b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/images/TrackSelectorVariables.png differ diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/images/TrackSelectorVariables.xls b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/images/TrackSelectorVariables.xls new file mode 100644 index 0000000000000000000000000000000000000000..d90eb65211a5745f0db2eb43e58503d2917807d6 Binary files /dev/null and b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/images/TrackSelectorVariables.xls differ diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/mainpage.h b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/mainpage.h new file mode 100644 index 0000000000000000000000000000000000000000..52880b23cfbefaef368a0c93a7376ba5d8c9e10c --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/doc/mainpage.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** +@mainpage The InDetTrackSelectorTool package + +@author Andreas.Wildauer@cern.ch +@author Daniel.Kollar@cern.ch + +@section introductionInDetTrackSelectorTool Introduction +This package contains the concrete implementation of the inner detector track selector tools. The interface can be found +in Tracking/TrkTools/TrkToolInterfaces. + +@section selectorsInDetTrackSelectorTool Selectors +The implementations in this package are + +- InDetTrackSelector: has mostly cuts on perigee parameters +- InDetDetailedTrackSelector: in addition can cut on hits and other variables +- InDetConversionTrackSelector: a track selector dedicated for conversion finding + +The cuts implemented in each version are shown below. + +@image html TrackSelectorVariables.png + +*/ + diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetConversionTrackSelectorTool.cxx b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetConversionTrackSelectorTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ed5989a42aeb1407749edfad05d631f2dd6c8eac --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetConversionTrackSelectorTool.cxx @@ -0,0 +1,403 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetTrackSelectorTool/InDetConversionTrackSelectorTool.h" +// forward declare +#include "TrkToolInterfaces/ITrackSummaryTool.h" +#include "TrkExInterfaces/IExtrapolator.h" +#include "VxVertex/Vertex.h" +#include "TrkTrack/Track.h" +#include "InDetBeamSpotService/IBeamCondSvc.h" +#include "TrkParticleBase/TrackParticleBase.h" +// normal includes +#include "TrkTrackSummary/TrackSummary.h" +#include "TrkSurfaces/PerigeeSurface.h" +#include "VxVertex/RecVertex.h" +#include "TrkParameters/TrackParameters.h" +#include "xAODTracking/Vertex.h" + + +namespace InDet +{ + + InDetConversionTrackSelectorTool::InDetConversionTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p) + :AthAlgTool(t,n,p), + m_trkSumTool("Trk::TrackSummaryTool"), + m_extrapolator("Trk::Extrapolator"), + m_iBeamCondSvc ("BeamCondSvc",n), + m_maxSiD0 (35.), + m_maxTrtD0 (100.), + m_maxSiZ0 (200.), + m_maxTrtZ0 (1200), + m_minPt (500.), + m_trRatio1 (0.5), + m_trRatio2 (0.1), + m_trRatio3 (0.05), + m_trRatioTRT(0.1), + m_trRatioV0 (1.), + m_sD0_Si (2.), + m_sD0_Trt (0.5), + m_sZ0_Trt (3.), + m_isConv(true) + { + declareInterface<ITrackSelectorTool>(this); + declareProperty("TrackSummaryTool", m_trkSumTool); + declareProperty("Extrapolator", m_extrapolator); + declareProperty("maxSiD0", m_maxSiD0); + declareProperty("maxTrtD0", m_maxTrtD0); + declareProperty("maxSiZ0", m_maxSiZ0); + declareProperty("maxTrtZ0", m_maxTrtZ0); + declareProperty("minPt", m_minPt); + declareProperty("RatioCut1", m_trRatio1); + declareProperty("RatioCut2", m_trRatio2); + declareProperty("RatioCut3", m_trRatio3); + declareProperty("RatioTRT", m_trRatioTRT); + declareProperty("RatioV0", m_trRatioV0); + declareProperty("significanceD0_Si", m_sD0_Si); + declareProperty("significanceD0_Trt", m_sD0_Trt); + declareProperty("significanceZ0_Trt", m_sZ0_Trt); + declareProperty("IsConversion", m_isConv); + declareProperty("BeamPositionSvc", m_iBeamCondSvc); + declareProperty("BeamPositionSvc", m_iBeamCondSvc); + declareProperty("PIDonlyForXe", m_PIDonlyForXe = false, + "Only check TRT PID if all hits are Xe hits"); + } + + InDetConversionTrackSelectorTool::~InDetConversionTrackSelectorTool() + {} + + StatusCode InDetConversionTrackSelectorTool::initialize() + { + StatusCode sc = AthAlgTool::initialize(); + if(sc.isFailure()){ + msg(MSG::ERROR)<<" Unable to initialize the AlgTool"<<endreq; + return StatusCode::FAILURE; + } + + /* Get the track summary tool from ToolSvc */ + if ( m_trkSumTool.retrieve().isFailure() ) { + msg(MSG::ERROR) << "Failed to retrieve tool " << m_trkSumTool << endreq; + return StatusCode::FAILURE; + } else { + msg(MSG::INFO) << "Retrieved tool " << m_trkSumTool << endreq; + } + + /* Get the extrapolator tool from ToolSvc */ + if ( m_extrapolator.retrieve().isFailure() ) { + msg(MSG::ERROR) << "Failed to retrieve tool " << m_extrapolator << endreq; + return StatusCode::FAILURE; + } else { + msg(MSG::INFO) << "Retrieved tool " << m_extrapolator << endreq; + } + + /* Get BeamCondSvc */ + sc = m_iBeamCondSvc.retrieve(); + if (sc.isFailure()) { + msg(MSG::INFO) << "Could not find BeamCondSvc. Will use (0,0,0) if no vertex is given and extrapolation is needed." << endreq; + } + + return StatusCode::SUCCESS; + } + + StatusCode InDetConversionTrackSelectorTool::finalize() + { + msg(MSG::INFO) << "Finalize successful" << endreq; + return StatusCode::SUCCESS; + } + + bool InDetConversionTrackSelectorTool::decision(const Trk::Track& track,const Trk::Vertex* vx) const + { + bool pass = false; + + const Trk::Perigee* perigee=dynamic_cast<const Trk::Perigee*>(track.perigeeParameters()); + const Trk::Vertex* myVertex=vx; + //in case no Vertex is provided by the user, beam position will be used if available + if (myVertex==0) { + if (!m_iBeamCondSvc.empty()) { + myVertex=new Trk::RecVertex(m_iBeamCondSvc->beamVtx()); + } else { + msg(MSG::WARNING) << " Cannot get beamSpot center from iBeamCondSvc. Using (0,0,0)... " << endreq; + myVertex=new Trk::Vertex(Amg::Vector3D(0,0,0)); + } + } + + Trk::PerigeeSurface perigeeSurface(myVertex->position()); + const Trk::TrackParameters *firstmeaspar=0; + for (unsigned int i=0;i<track.trackParameters()->size();i++){ + if ( (*track.trackParameters())[i]->covariance() && !dynamic_cast<const Trk::Perigee*>((*track.trackParameters())[i])) { + firstmeaspar=(*track.trackParameters())[i]; + break; + } + } + if (!firstmeaspar) { + //assumes perigeeParameters exist... + //no track selection if firstmeas + perigee does not exist ! + firstmeaspar=track.perigeeParameters(); + if (!firstmeaspar){ + msg(MSG::WARNING) << " First measurment on track is missing. Using perigee Parameters, but they are missing: 0 pointer! Track selection failed " << endreq; + //clean up vertex + if (myVertex!=vx) { + delete myVertex; + myVertex=0; + } + return false; + } + } + + const Trk::TrackParameters * extrapolatedParameters= m_extrapolator->extrapolate(*firstmeaspar,perigeeSurface,Trk::anyDirection,true,track.info().particleHypothesis() ); +// const Trk::TrackParameters * extrapolatedParameters= firstmeaspar ? m_extrapolator->extrapolate(*firstmeaspar,perigeeSurface,Trk::anyDirection,true,track.info().particleHypothesis() ) : 0; + perigee = extrapolatedParameters ? dynamic_cast<const Trk::Perigee*>(extrapolatedParameters) : 0; + if (perigee==0 || !perigee->covariance() ) { + msg(MSG::WARNING) << "Track Selector failed to extrapolate track to the vertex: " << myVertex->position() << endreq; + if (extrapolatedParameters!=0) { + msg(MSG::WARNING) << "The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" << endreq; + delete extrapolatedParameters; + if (myVertex!=vx) delete myVertex; + return false; + } + return false; + } + + double qOverP = perigee->parameters()[Trk::qOverP]; + double pt = fabs(1/qOverP)*sin(perigee->parameters()[Trk::theta]); + double d0 = perigee->parameters()[Trk::d0]; + double z0 = perigee->parameters()[Trk::z0]; + const Trk::TrackSummary* tSum = m_trkSumTool->createSummaryNoHoleSearch(track); + if(tSum){ + double ratioTrk = 1.0; + int nclus = tSum->get(Trk::numberOfPixelHits) + tSum->get(Trk::numberOfSCTHits); + int nTrtHits = tSum->get(Trk::numberOfTRTHits); + int nTrtOutliers = tSum->get(Trk::numberOfTRTOutliers); + int ntrt = nTrtHits + nTrtOutliers; + int nTrtXenonHits = tSum->get(Trk::numberOfTRTXenonHits); + + if(m_isConv) { + + if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ) // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits + ratioTrk = tSum->getPID(Trk::eProbabilityComb); + + if ( pt >= m_minPt ) { + if ( (nclus==0 && fabs(d0)<=m_maxTrtD0) || (nclus>0 && fabs(d0)<=m_maxSiD0) ) { + if ( (nclus==0 && fabs(z0)<=m_maxTrtZ0) || (nclus>0 && fabs(z0)<=m_maxSiZ0) ) { + if (nclus>0) { + if((ntrt<=15 && ratioTrk>=m_trRatio1) || + (ntrt>15 && ntrt<=25 && ratioTrk>=m_trRatio2) || + (ntrt>25 && ratioTrk>=m_trRatio3)) pass = true; + } else if (ratioTrk>=m_trRatioTRT) pass = true; + } + } + } + } else { + //The cuts below are necessary for the V0 track selection + const AmgSymMatrix(5)& err = *perigee->covariance(); + double sd0sq = err(0,0); + double sd0 = (sd0sq>0.)?sqrt(sd0sq):0.; + double sz0sq = err(1,1); + double sz0 = (sz0sq>0.)?sqrt(sz0sq):0.; + if(nclus == 0){ + if(fabs(d0)>=m_sD0_Trt*sd0 && fabs(d0)<=m_maxTrtD0 && fabs(z0)<=m_sZ0_Trt*sz0 && pt>=m_minPt) pass = true; + }else{ + if(fabs(d0)>=m_sD0_Si*sd0 && fabs(z0)<=m_maxSiZ0 && pt>=m_minPt) pass = true; + } + + ratioTrk = 1.0; + if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ) // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits + ratioTrk = tSum->getPID(Trk::eProbabilityComb); + + if(ratioTrk>m_trRatioV0) pass = false; + } + + delete tSum; + } else pass = false; + + if (myVertex!=vx) delete myVertex; + if (perigee!=track.perigeeParameters()) delete perigee; + + return pass; + } + + bool InDetConversionTrackSelectorTool::decision(const Trk::TrackParticleBase& track,const Trk::Vertex* vx) const + { + bool pass = false; + + const Trk::TrackParameters* definintParameters=&(track.definingParameters()); + const Trk::Perigee* perigee=dynamic_cast<const Trk::Perigee*>(definintParameters); + const Trk::Vertex* myVertex=vx; + //in case no Vertex is provided by the user, beam position will be used if available + if (myVertex==0) { + if (!m_iBeamCondSvc.empty()) { + myVertex=new Trk::RecVertex(m_iBeamCondSvc->beamVtx()); + } else { + msg(MSG::WARNING) << " Cannot get beamSpot center from iBeamCondSvc. Using (0,0,0)... " << endreq; + myVertex=new Trk::Vertex(Amg::Vector3D(0,0,0)); + } + } + + Trk::PerigeeSurface perigeeSurface(myVertex->position()); + const Trk::TrackParameters *firstmeaspar=0; + for (unsigned int i=0;i<track.trackParameters().size();i++){ + if ( (track.trackParameters())[i]->covariance() && !dynamic_cast<const Trk::Perigee*>((track.trackParameters())[i])) { + firstmeaspar=(track.trackParameters())[i]; + break; + } + } + + if (!firstmeaspar) { + //using perigee instead of firstmeasurement, since first measurement was not found... + firstmeaspar=&(track.definingParameters()); + if (!firstmeaspar){ + msg(MSG::DEBUG) << " Track Paraemters at first measurement not found. Perigee not found. Cannot do TrackSelection..." << endreq; + if (myVertex!=vx) { + delete myVertex; + myVertex=0; + } + return false; + } + } + + const Trk::TrackParameters * extrapolatedParameters= m_extrapolator->extrapolate(*firstmeaspar,perigeeSurface,Trk::anyDirection,true,Trk::pion ); + //const Trk::TrackParameters * extrapolatedParameters= firstmeaspar ? m_extrapolator->extrapolate(*firstmeaspar,perigeeSurface,Trk::anyDirection,true,Trk::pion ) : 0; + perigee = extrapolatedParameters ? dynamic_cast<const Trk::Perigee*>(extrapolatedParameters) : 0; + if (perigee==0 || !perigee->covariance()) { + msg(MSG::WARNING) << "Track Selector failed to extrapolate track to the vertex: " << myVertex->position() << endreq; + if (extrapolatedParameters!=0) { + msg(MSG::WARNING) << "The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" << endreq; + delete extrapolatedParameters; + if (myVertex!=vx) delete myVertex; + return false; + } + return false; + } + + double qOverP = perigee->parameters()[Trk::qOverP]; + double pt = fabs(1/qOverP)*sin(perigee->parameters()[Trk::theta]); + double d0 = perigee->parameters()[Trk::d0]; + double z0 = perigee->parameters()[Trk::z0]; + const Trk::TrackSummary* tSum = track.trackSummary(); + if(tSum){ + double ratioTrk = 1.0; + int nclus = tSum->get(Trk::numberOfPixelHits) + tSum->get(Trk::numberOfSCTHits); + int nTrtHits = tSum->get(Trk::numberOfTRTHits); + int nTrtOutliers = tSum->get(Trk::numberOfTRTOutliers); + int ntrt = nTrtHits + nTrtOutliers; + int nTrtXenonHits = tSum->get(Trk::numberOfTRTXenonHits); + + if(m_isConv){ + + if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ) // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits + ratioTrk = tSum->getPID(Trk::eProbabilityComb); + + if ( pt >= m_minPt ) { + if ( (nclus==0 && fabs(d0)<=m_maxTrtD0) || (nclus>0 && fabs(d0)<=m_maxSiD0) ) { + if ( (nclus==0 && fabs(z0)<=m_maxTrtZ0) || (nclus>0 && fabs(z0)<=m_maxSiZ0) ) { + if (nclus > 0) { + if((ntrt<=15 && ratioTrk>=m_trRatio1) || + (ntrt>15 && ntrt<=25 && ratioTrk>=m_trRatio2) || + (ntrt>25 && ratioTrk>=m_trRatio3)) pass = true; + } else if (ratioTrk>=m_trRatioTRT) pass = true; + } + } + } + } else { + //The cuts below are necessary for the V0 track selection + const AmgSymMatrix(5)& err = *perigee->covariance(); + double sd0sq = err(0,0); + double sd0 = (sd0sq>0.)?sqrt(sd0sq):0.; + double sz0sq = err(1,1); + double sz0 = (sz0sq>0.)?sqrt(sz0sq):0.; + if(nclus == 0){ + if(fabs(d0)>=m_sD0_Trt*sd0 && fabs(d0)<= m_maxTrtD0 && fabs(z0)<=m_sZ0_Trt*sz0 && pt>=m_minPt) pass = true; + }else{ + if(fabs(d0)>=m_sD0_Si*sd0 && fabs(z0)<=m_maxSiZ0 && pt>=m_minPt) pass = true; + } + + ratioTrk = 1.0; + if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ) // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits + ratioTrk = tSum->getPID(Trk::eProbabilityComb); + if(ratioTrk>m_trRatioV0) pass = false; + } + } else pass = false; + + if (myVertex!=vx) delete myVertex; + if (perigee!=&(track.definingParameters())) delete perigee; + + return pass; + } + + + // --------------------------------------------------------------------- + bool InDetConversionTrackSelectorTool::decision(const xAOD::TrackParticle& tp,const xAOD::Vertex* vertex) const + { + + + + + bool pass = false; + + const Trk::Perigee& perigee=tp.perigeeParameters(); + + //in case no Vertex is provided by the user, beam position will be used if available + + Trk::PerigeeSurface perigeeSurface( vertex ? vertex->position() : (!m_iBeamCondSvc.empty() ? m_iBeamCondSvc->beamVtx().position() : Amg::Vector3D(0,0,0) ) ); + + const Trk::TrackParameters* extrapolatedParameters= m_extrapolator->extrapolate(perigee,perigeeSurface,Trk::anyDirection,false,Trk::pion ); + if (extrapolatedParameters==0) { + ATH_MSG_WARNING( "Extrapolation to the vertex failed: " << perigeeSurface << std::endl << perigee ); + return false; + } + + double qOverP = perigee.parameters()[Trk::qOverP]; + double pt = fabs(1/qOverP)*sin(perigee.parameters()[Trk::theta]); + double d0 = extrapolatedParameters->parameters()[Trk::d0]; + double z0 = extrapolatedParameters->parameters()[Trk::z0]; + + double ratioTrk = 1.0; + int nclus = getCount(tp,xAOD::numberOfPixelHits) + getCount(tp,xAOD::numberOfSCTHits); + int nTrtHits = getCount(tp,xAOD::numberOfTRTHits); + int nTrtOutliers = getCount(tp,xAOD::numberOfTRTOutliers); + int ntrt = nTrtHits + nTrtOutliers; + int nTrtXenonHits = getCount(tp,xAOD::numberOfTRTXenonHits); + + if(m_isConv){ + float temp(0); + if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ){ // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits + ratioTrk = tp.summaryValue(temp,xAOD::eProbabilityComb) ? temp: 0 ; + } + + if ( pt >= m_minPt ) { + if ( (nclus==0 && fabs(d0)<=m_maxTrtD0) || (nclus>0 && fabs(d0)<=m_maxSiD0) ) { + if ( (nclus==0 && fabs(z0)<=m_maxTrtZ0) || (nclus>0 && fabs(z0)<=m_maxSiZ0) ) { + if (nclus > 0) { + if((ntrt<=15 && ratioTrk>=m_trRatio1) || + (ntrt>15 && ntrt<=25 && ratioTrk>=m_trRatio2) || + (ntrt>25 && ratioTrk>=m_trRatio3)) pass = true; + } else if (ratioTrk>=m_trRatioTRT) pass = true; + } + } + } + } else { + //The cuts below are necessary for the V0 track selection + const AmgSymMatrix(5)& err = *perigee.covariance(); + double sd0sq = err(0,0); + double sd0 = (sd0sq>0.)?sqrt(sd0sq):0.; + double sz0sq = err(1,1); + double sz0 = (sz0sq>0.)?sqrt(sz0sq):0.; + if(nclus == 0){ + if(fabs(d0)>=m_sD0_Trt*sd0 && fabs(d0)<= m_maxTrtD0 && fabs(z0)<=m_sZ0_Trt*sz0 && pt>=m_minPt) pass = true; + }else{ + if(fabs(d0)>=m_sD0_Si*sd0 && fabs(z0)<=m_maxSiZ0 && pt>=m_minPt) pass = true; + } + + ratioTrk = 1.0; + float temp(0); + if(ntrt > 0 && (!m_PIDonlyForXe || nTrtXenonHits==ntrt) ) // only check TRT PID if m_PIDonlyForXe is false or all TRT hits are Xenon hits + ratioTrk = tp.summaryValue(temp,xAOD::eProbabilityComb) ? temp: 0 ; + if(ratioTrk>m_trRatioV0) pass = false; + } + + + delete extrapolatedParameters; + return pass; + } +}//end of namespace definitions diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetCosmicTrackSelectorTool.cxx b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetCosmicTrackSelectorTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b9cd19fe9875faad8c4f094a7a0088ebd09efdee --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetCosmicTrackSelectorTool.cxx @@ -0,0 +1,286 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetTrackSelectorTool/InDetCosmicTrackSelectorTool.h" + +// forward declares +#include "TrkToolInterfaces/ITrackSummaryTool.h" +#include "MagFieldInterfaces/IMagFieldSvc.h" +#include "VxVertex/Vertex.h" +#include "TrkTrack/Track.h" +#include "TrkParticleBase/TrackParticleBase.h" + +// normal includes +#include "TrkTrackSummary/TrackSummary.h" +#include "TrkRIO_OnTrack/RIO_OnTrack.h" +#include "InDetRIO_OnTrack/SiClusterOnTrack.h" +#include "InDetRIO_OnTrack/SCT_ClusterOnTrack.h" +#include "DataModel/DataVector.h" + + +namespace InDet +{ + //---------------------------------------------------------------------------- + InDetCosmicTrackSelectorTool::InDetCosmicTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p) + : AthAlgTool(t,n,p) + , m_magFieldSvc("AtlasFieldSvc",n) + { + declareInterface<ITrackSelectorTool>(this); + declareProperty("maxZ0", m_maxZ0 = 150.); + declareProperty("maxD0", m_maxD0 = 2.5); + declareProperty("minPt", m_minPt = 0.); + declareProperty("numberOfPixelHits", m_numberOfPixelHits = 0); + declareProperty("numberOfSCTHits", m_numberOfSCTHits = 0); + declareProperty("numberOfTRTHits", m_numberOfTRTHits = 15); + declareProperty("numberOfSiliconHits", m_numberOfSiHits = 8); + declareProperty("numberOfSiliconHitsTop", m_numberOfSiHitsTop = -1); + declareProperty("numberOfSiliconHitsBottom", m_numberOfSiHitsBottom = -1); + declareProperty("TrackSummaryTool", m_trackSumTool); + declareProperty("MagFieldSvc", m_magFieldSvc); + } + + //---------------------------------------------------------------------------- + InDetCosmicTrackSelectorTool::~InDetCosmicTrackSelectorTool() + {} + + //---------------------------------------------------------------------------- + StatusCode InDetCosmicTrackSelectorTool::initialize() + { + if(AthAlgTool::initialize().isFailure()) { + msg(MSG::ERROR)<<" Unable to initialize the AlgTool"<<endreq; + return StatusCode::FAILURE; + } + + m_trackSumToolAvailable = false; + if (!m_trackSumTool.empty()) { + if(m_trackSumTool.retrieve().isFailure()) + { + msg(MSG::ERROR)<<" Unable to retrieve "<<m_trackSumTool<<endreq; + return StatusCode::FAILURE; + } + ATH_MSG_INFO("Track summary tool retrieved"); + m_trackSumToolAvailable = true; + } + + if (m_magFieldSvc.retrieve().isFailure()) { + msg(MSG::FATAL) << "Failed to retrieve tool " << m_magFieldSvc << endreq; + return StatusCode::FAILURE; + } + ATH_MSG_INFO("Retrieved tool "<<m_magFieldSvc); + + return StatusCode::SUCCESS; + } + + //---------------------------------------------------------------------------- + StatusCode InDetCosmicTrackSelectorTool::finalize() + { + ATH_MSG_INFO("Finalize successful"); + return StatusCode::SUCCESS; + } + + //---------------------------------------------------------------------------- + bool InDetCosmicTrackSelectorTool::decision(const Trk::Track & track, const Trk::Vertex * vertex) const + { + + // decision based on the track parameters + if(!decision(track.perigeeParameters(), vertex, track.info().particleHypothesis())) + return false; + + // number of hits, silicon hits, b-layer + // first ask track for summary + const Trk::TrackSummary * summary = track.trackSummary(); + if (summary == 0 && m_trackSumToolAvailable) { + // ugly but one needs to cast the const away because the method needs to update the track (the tool is a friend of track) + Trk::Track& nonConstTrack = const_cast<Trk::Track&>(track); + m_trackSumTool->updateTrack(nonConstTrack); + // now get it from the track (the track has OWNERSHIP) + summary = nonConstTrack.trackSummary(); + } + + if (0==summary) { + ATH_MSG_DEBUG( "Track preselection: cannot create a track summary. This track will not pass." ); + return false; + } + + int nPixHits = summary->get(Trk::numberOfPixelHits); + int nSCTHits = summary->get(Trk::numberOfSCTHits); + int nTRTHits = summary->get(Trk::numberOfTRTHits); + int nSiHits = summary->get(Trk::numberOfPixelHits) * 2 + summary->get(Trk::numberOfSCTHits); + int nSiHitsTop = getNSiHits(&track,true); + int nSiHitsBottom = getNSiHits(&track,false); + + if(nPixHits<m_numberOfPixelHits) { + ATH_MSG_DEBUG("Track rejected because of numberOfPixelHits "<<nPixHits<<"<"<<m_numberOfPixelHits); + return false; + } + + if(nSCTHits<m_numberOfSCTHits) { + ATH_MSG_DEBUG("Track rejected because of numberOfSCTHits "<<nSCTHits<<"<"<<m_numberOfSCTHits); + return false; + } + + if(nTRTHits<m_numberOfTRTHits) { + ATH_MSG_DEBUG("Track rejected because of numberOfTRTHits "<<nTRTHits<<"<"<<m_numberOfTRTHits); + return false; + } + + if(nSiHits<m_numberOfSiHits) { + ATH_MSG_DEBUG("Track rejected because of numberOfSiHits "<<nSiHits<<"<"<<m_numberOfSiHits); + return false; + } + + if(nSiHitsTop<m_numberOfSiHitsTop) { + ATH_MSG_DEBUG("Track rejected because of nSiHitsTop "<<nSiHitsTop<<"<"<<m_numberOfSiHitsTop); + return false; + } + + if(nSiHitsBottom<m_numberOfSiHitsBottom) { + ATH_MSG_DEBUG("Track rejected because of numberOfSiHitsBottom "<<nSiHitsBottom<<"<"<<m_numberOfSiHitsBottom); + return false; + } + + // all ok + return true; + } + + //---------------------------------------------------------------------------- + bool InDetCosmicTrackSelectorTool::decision(const Trk::TrackParticleBase & track,const Trk::Vertex * vertex) const + { + if(!decision(&(track.definingParameters()), vertex, Trk::pion)) + return false; + + const Trk::TrackSummary * summary = track.trackSummary(); + if (0==summary ) { + ATH_MSG_DEBUG( "TrackParticleBase does not have a Track Summary. Rejected." ); + return false; + } + const Trk::Track * otrack= track.originalTrack(); + + if(otrack==0){ + ATH_MSG_DEBUG( "TrackParticleBase does not contain the original cosmic track. Rejected." ); + return false; + } + + int nPixHits = summary->get(Trk::numberOfPixelHits); + int nSCTHits = summary->get(Trk::numberOfSCTHits); + int nTRTHits = summary->get(Trk::numberOfTRTHits); + int nSiHits = summary->get(Trk::numberOfPixelHits)*2+summary->get(Trk::numberOfSCTHits); + int nSiHitsTop = getNSiHits(otrack,true); + int nSiHitsBottom = getNSiHits(otrack,false); + + if(nPixHits<m_numberOfPixelHits) { + ATH_MSG_DEBUG("Track rejected because of numberOfPixelHits "<<nPixHits<<"<"<<m_numberOfPixelHits); + return false; + } + + if(nSCTHits<m_numberOfSCTHits) { + ATH_MSG_DEBUG("Track rejected because of numberOfSCTHits "<<nSCTHits<<"<"<<m_numberOfSCTHits); + return false; + } + + if(nTRTHits<m_numberOfTRTHits) { + ATH_MSG_DEBUG("Track rejected because of numberOfTRTHits "<<nTRTHits<<"<"<<m_numberOfTRTHits); + return false; + } + + if(nSiHits<m_numberOfSiHits) { + ATH_MSG_DEBUG("Track rejected because of numberOfSiHits "<<nSiHits<<"<"<<m_numberOfSiHits); + return false; + } + + if(nSiHitsTop<m_numberOfSiHitsTop) { + ATH_MSG_DEBUG("Track rejected because of nSiHitsTop "<<nSiHitsTop<<"<"<<m_numberOfSiHitsTop); + return false; + } + + if(nSiHitsBottom<m_numberOfSiHitsBottom) { + ATH_MSG_DEBUG("Track rejected because of numberOfSiHitsBottom "<<nSiHitsBottom<<"<"<<m_numberOfSiHitsBottom); + return false; + } + + // all ok + return true; + } + + //---------------------------------------------------------------------------- + bool InDetCosmicTrackSelectorTool::decision(const Trk::TrackParameters* track, const Trk::Vertex *, const Trk::ParticleHypothesis) const + { + // checking pointer first + if(0==track) { + ATH_MSG_DEBUG( "Track preselection: Zero pointer to parameterbase* received (most likely a track without perigee). This track will not pass." ); + return false; + } + + // getting the perigee parameters of the track + const Trk::Perigee * perigee(0); + perigee = dynamic_cast<const Trk::Perigee *>(track); + + if(!perigee || !perigee->covariance()) { + ATH_MSG_DEBUG( "Track preselection: cannot make a measured perigee. This track will not pass." ); + return false; + } + + Amg::VectorX trackParameters = perigee->parameters(); + + // d0 and z0 cuts + double d0 = trackParameters[Trk::d0]; + if(fabs(d0) > fabs(m_maxD0)) { + ATH_MSG_DEBUG("Track rejected because of d0 "<<fabs(d0)<<">"<<m_maxD0); + return false; + } + + double z0 = trackParameters[Trk::z0]; + if(fabs(z0) > fabs(m_maxZ0)) { + ATH_MSG_DEBUG("Track rejected because of z0 "<<fabs(z0)<<">"<<m_maxZ0); + return false; + } + + // only check pt if mag. field is on + if (m_magFieldSvc->solenoidOn()) { + if (trackParameters[Trk::qOverP] == 0.) { + ATH_MSG_DEBUG("Track rejected because of qOverP == 0."); + return false; + } + + double pt = fabs(1./trackParameters[Trk::qOverP])*sin(trackParameters[Trk::theta]); + if (pt < m_minPt) { + ATH_MSG_DEBUG("Track rejected because of pt " << pt << " < " << m_minPt); + return false; + } + } + return true; + } + + //---------------------------------------------------------------------------- + int InDetCosmicTrackSelectorTool::getNSiHits(const Trk::Track * track, bool top) const + { + int nsilicon = 0; + + //loop over all measurements on Track + DataVector<const Trk::MeasurementBase>::const_iterator it = track->measurementsOnTrack()->begin(); + DataVector<const Trk::MeasurementBase>::const_iterator itEnd = track->measurementsOnTrack()->end(); + for ( ; it!=itEnd; ++it) { + const Trk::RIO_OnTrack *rot = dynamic_cast<const Trk::RIO_OnTrack *>(*it); + if (!rot) + continue; + const InDet::SiClusterOnTrack *siclus = dynamic_cast<const InDet::SiClusterOnTrack *>(rot); + if(!siclus) + continue; + + if(top && siclus->globalPosition().y()<0) + continue; + if(!top && siclus->globalPosition().y()>0) + continue; + + const SCT_ClusterOnTrack *sctclus = dynamic_cast<const SCT_ClusterOnTrack *>(siclus); + if(!sctclus) + //Pixel hit + nsilicon += 2; + else + nsilicon += 1; + } + return nsilicon; + } + +} //end of namespace definitions diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetDetailedTrackSelectorTool.cxx b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetDetailedTrackSelectorTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..423cd5b24604e9d92d73dafd7e44d262026baeb9 --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetDetailedTrackSelectorTool.cxx @@ -0,0 +1,1202 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetTrackSelectorTool/InDetDetailedTrackSelectorTool.h" +// forward declares +#include "TrkToolInterfaces/ITrackSummaryTool.h" +#include "TrkExInterfaces/IExtrapolator.h" +#include "VxVertex/Vertex.h" +#include "VxVertex/RecVertex.h" +#include "TrkEventPrimitives/FitQuality.h" +#include "TrkTrack/Track.h" +#include "TrkTrackSummary/TrackSummary.h" +#include "TrkParticleBase/TrackParticleBase.h" +#include "InDetBeamSpotService/IBeamCondSvc.h" +#include "MagFieldInterfaces/IMagFieldSvc.h" +#include "InDetRecToolInterfaces/ITrtDriftCircleCutTool.h" +#include "InDetRecToolInterfaces/IInDetTestBLayerTool.h" + +#include "xAODTracking/TrackParticle.h" +#include "xAODTracking/Vertex.h" + + +// normal includes +#include "CLHEP/GenericFunctions/CumulativeChiSquare.hh" +#include "TrkSurfaces/PerigeeSurface.h" +#include "GeoPrimitives/GeoPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" +#include <TMath.h> + +using CLHEP::GeV; +using CLHEP::mm; + +namespace InDet +{ + + // --------------------------------------------------------------------- + InDetDetailedTrackSelectorTool::InDetDetailedTrackSelectorTool(const std::string& t, const std::string& n, const IInterface* p) + : AthAlgTool(t,n,p) + , m_trackSumTool("Trk::TrackSummaryTool") + , m_extrapolator("Trk::Extrapolator") + , m_iBeamCondSvc ("BeamCondSvc",n) + , m_magFieldSvc("AtlasFieldSvc",n) + , m_trtDCTool("InDet::InDetTrtDriftCircleCutTool") + // , m_inDetTestBLayerTool("InDet::InDetTestBLayerTool") + , m_inDetTestBLayerTool("") + , m_trackSumToolAvailable(true) + , m_usePtDependentCuts(false) + // , m_ptBenchmarks(1, 0) // create with dummy length 1 filled with 0 + // , m_nSCTValues(1, 0) // same + + { + declareInterface<ITrackSelectorTool>(this); + declareProperty("pTMin" , m_pTMin = 1.*GeV); + declareProperty("pMin" , m_pMin = 0.); + declareProperty("IPd0Max" , m_IPd0Max = 2.*mm); + declareProperty("IPz0Max" , m_IPz0Max = 1.5*mm); + declareProperty("z0Max" , m_z0Max = 9999.*mm); + declareProperty("sigIPd0Max" , m_sigIPd0Max = 999.*mm); + declareProperty("sigIPz0Max" , m_sigIPz0Max = 999.*mm); + declareProperty("d0significanceMax", m_d0significanceMax = -1.); + declareProperty("z0significanceMax", m_z0significanceMax = -1.); + declareProperty("etaMax" , m_etaMax = 9999.); + + declareProperty("useTrackSummaryInfo", m_useTrackSummaryInfo = true); + + declareProperty("nHitBLayer" , m_nHitBLayer = 1); + declareProperty("nHitPix" , m_nHitPix = 2); + declareProperty("nHitBLayerPlusPix", m_nHitBLayerPlusPix = 0); + declareProperty("nHitSct" , m_nHitSct = 0); + declareProperty("nHitSi" , m_nHitSi = 7); + + declareProperty("nHitPixPhysical", m_nHitPixPhysical = 0); + declareProperty("nHitSiPhysical", m_nHitSiPhysical = 3); + + declareProperty("nHitTrt" , m_nHitTrt = 0); + declareProperty("nHitTrtPlusOutliers" , m_nHitTrtPlusOutliers = 0); + declareProperty("nHitTrtHighE" , m_nHitTrtHighE = 0); + declareProperty("nHitTrtPlusOutliersHighE" , m_nHitTrtPlusOutliersHighE = 0); + declareProperty("nHitTrtHighEFractionMax" , m_nHitTrtHighEFraction = 999); + declareProperty("nHitTrtHighEFractionWithOutliersMax", m_nHitTrtHighEFractionWithOutliers = 999); + + declareProperty("useSharedHitInfo", m_useSharedHitInfo = false); + declareProperty("nSharedBLayer" , m_nSharedBLayer = 0); + declareProperty("nSharedPix" , m_nSharedPix = 0); + declareProperty("nSharedSct" , m_nSharedSct = 1); + declareProperty("nSharedSi" , m_nSharedSi = 999); + + declareProperty("nHoles" , m_nHoles = 999); + declareProperty("nDoubleHoles", m_nDoubleHoles = 999); + declareProperty("nHolesPixel" , m_nHolesPix = 999); + declareProperty("nHolesSct" , m_nHolesSct = 999); + + declareProperty("useTrackQualityInfo", m_useTrackQualityInfo = true); + declareProperty("fitChi2" , m_fitChi2 = 99999.); + declareProperty("fitProb" , m_fitProb = -1.); + declareProperty("fitChi2OnNdfMax" , m_fitChi2OnNdfMax = 999.); + declareProperty("TrtMaxEtaAcceptance", m_TrtMaxEtaAcceptance = 999.); + + declareProperty("usePreselectionCuts", m_usePreselectionCuts = false); + declareProperty("d0MaxPreselection" , m_d0MaxPreselection = 10.); + + declareProperty("useEtaDepententMinHitTrt", m_useEtaDepententMinHitTrt = false); + declareProperty("scaleMinHitTrt" , m_scaleMinHitTrt = 1.); + declareProperty("addToMinHitTrt" , m_addToMinHitTrt = 0); + + declareProperty("useEtaDepententMinHitTrtWithOutliers", m_useEtaDepententMinHitTrtWithOutliers = false); + declareProperty("scaleMinHitTrtWithOutliers" , m_scaleMinHitTrtWithOutliers = 1.); + declareProperty("addToMinHitTrtWithOutliers" , m_addToMinHitTrtWithOutliers = 0); + + declareProperty("TrackSummaryTool" , m_trackSumTool); + declareProperty("Extrapolator" , m_extrapolator); + declareProperty("BeamPositionSvc" , m_iBeamCondSvc); + declareProperty("MagFieldSvc", m_magFieldSvc); + declareProperty("TrtDCCutTool" , m_trtDCTool); + declareProperty("InDetTestBLayerTool", m_inDetTestBLayerTool); + + //pt-dependent cuts; default vector values (can be done much smarter, but I want + // to have an explicit code..) + + // std::vector<float> loc_bench; + // loc_bench.push_back(100.); + // loc_bench.push_back(200.); + // loc_bench.push_back(300.); + + // std::vector<int> loc_nsct; + // loc_nsct.push_back(2); + // loc_nsct.push_back(4); + // loc_nsct.push_back(6); + + declareProperty("UsePtDependentCuts", m_usePtDependentCuts = false); + declareProperty("PtBenchmarks" , m_ptBenchmarks); + declareProperty("SCTCutValues" , m_nSCTValues); + } + + // --------------------------------------------------------------------- + InDetDetailedTrackSelectorTool::~InDetDetailedTrackSelectorTool() + {} + + // --------------------------------------------------------------------- + StatusCode InDetDetailedTrackSelectorTool::initialize() + { + StatusCode sc = AthAlgTool::initialize(); + if(sc.isFailure()) + { + msg(MSG::ERROR)<<" Unable to initialize the AlgTool"<<endreq; + return StatusCode::FAILURE; + } + + m_trackSumToolAvailable=false; + if (!m_trackSumTool.empty()) + { + if(m_trackSumTool.retrieve().isFailure()) + { + msg(MSG::INFO)<<" Unable to retrieve. OK if running on AOD. "<<m_trackSumTool<<endreq; + } + else + { + msg(MSG::INFO)<<"Track summary tool retrieved"<<endreq; + m_trackSumToolAvailable=true; + } + } + + if ( m_extrapolator.retrieve().isFailure() ) + { + msg(MSG::ERROR) << "Failed to retrieve tool " << m_extrapolator << endreq; + return StatusCode::FAILURE; + } + ATH_MSG_INFO("Retrieved tool " << m_extrapolator); + + sc = m_iBeamCondSvc.retrieve(); + if (sc.isFailure()) + ATH_MSG_INFO("Could not find BeamCondSvc. Will use (0,0,0) if no vertex is given and extrapolation is needed."); + + if (m_useEtaDepententMinHitTrt || m_useEtaDepententMinHitTrtWithOutliers) + { + if(m_trtDCTool.empty()) { + msg(MSG::ERROR)<<" Eta delendent cut on number of TRT hits requested but TrtDCCutTool not specified. "<<endreq; + return StatusCode::FAILURE; + } + else if(m_trtDCTool.retrieve().isFailure()) { + msg(MSG::ERROR)<<" Unable to retrieve tool "<<m_trtDCTool<<endreq; + return StatusCode::FAILURE; + } + ATH_MSG_INFO("Retrieved tool "<<m_trtDCTool); + + if(m_useEtaDepententMinHitTrt) + ATH_MSG_INFO("Using eta dependent cut on number of TRT hits."); + if(m_useEtaDepententMinHitTrtWithOutliers) + ATH_MSG_INFO("Using eta dependent cut on number of TRT hits + outliers."); + } + + if (m_magFieldSvc.retrieve().isFailure()) + { + msg(MSG::FATAL) << "Failed to retrieve " << m_magFieldSvc << endreq; + return StatusCode::FAILURE; + } + ATH_MSG_INFO("Retrieved tool "<<m_magFieldSvc); + + if(m_inDetTestBLayerTool.empty()) + { + msg(MSG::INFO)<<" The BLayerTool not specified, turning off cut. "<<endreq; + } + else if ( m_inDetTestBLayerTool.retrieve().isFailure() ) + { + msg(MSG::ERROR)<< "Failed to retrieve tool " << m_inDetTestBLayerTool<<endreq; + return StatusCode::FAILURE; + } + ATH_MSG_INFO("Using cuts on the number of Silicon hits"); + + if(m_usePtDependentCuts) + { + //checking whether sizes of cuts and pt interval expressed in vectors match + if( m_ptBenchmarks.size() != m_nSCTValues.size()) + { + msg(MSG::ERROR)<< "Number of cuts DOES NOT match the number of intervals to apply. Please check jobOptions. "<<endreq; + return StatusCode::FAILURE; + } else if (m_ptBenchmarks.size() == 0) + { + msg(MSG::ERROR)<< "Zero vectors for number of cuts and pt intervals. Please check jobOptions. "<<endreq; + return StatusCode::FAILURE; + }//end of vector size protection block + }//end of memory protection + + return StatusCode::SUCCESS; + } + + // --------------------------------------------------------------------- + StatusCode InDetDetailedTrackSelectorTool::finalize() + { + msg(MSG::INFO) << "Finalize successful" << endreq; + return StatusCode::SUCCESS; + } + + // --------------------------------------------------------------------- + bool InDetDetailedTrackSelectorTool::decision(const Trk::Track& track,const Trk::Vertex* vertex) const + { + const Trk::Perigee* perigeeBeforeExtrapolation= + dynamic_cast<const Trk::Perigee*>(track.perigeeParameters()); + + if (perigeeBeforeExtrapolation && m_usePreselectionCuts) + { + bool preselectionDecision=preselectionBeforeExtrapolation(*perigeeBeforeExtrapolation); + if (!preselectionDecision) { + ATH_MSG_DEBUG("Track rejected because of preselection decision!"); + return false; + } + } + else if (m_usePreselectionCuts) + { + ATH_MSG_INFO( " Preselection was requested but cannot be made since no Perigee in Track is available. This is not an error." ); + } + + const Trk::Vertex* myVertex=vertex; + + //in case no Vertex is provided by the user, beam position will be used if available + + if (myVertex==0) { + //ATH_MSG_DEBUG( "No vertex given, using beam spot or 0,0,0" ); + if (!m_iBeamCondSvc.empty()) { + myVertex=new Trk::RecVertex(m_iBeamCondSvc->beamVtx()); + } else { + ATH_MSG_WARNING( " Cannot get beamSpot center from iBeamCondSvc. Using (0,0,0)... " ); + myVertex=new Trk::Vertex(Amg::Vector3D(0,0,0)); + } + } + + Trk::PerigeeSurface perigeeSurface(myVertex->position()); + const Trk::TrackParameters *firstmeaspar=0; + for (unsigned int i=0;i<track.trackParameters()->size();i++){ + if ( (*track.trackParameters())[i]->covariance() && !dynamic_cast<const Trk::Perigee*>((*track.trackParameters())[i])) { + firstmeaspar=(*track.trackParameters())[i]; + break; + } + } + + if (!firstmeaspar) { + //assumes perigeeParameters exist... + //no track selection if firstmeas + perigee does not exist ! + firstmeaspar=track.perigeeParameters(); + if (!firstmeaspar) + { + ATH_MSG_WARNING( " First measurment on track is missing. Using perigee Parameters, but they are missing: 0 pointer! Track selection failed " ); + //clean up vertex + if (myVertex!=vertex) { + delete myVertex; + myVertex=0; + } + return false; + } + } + + const Trk::TrackParameters* extrapolatedParameters= firstmeaspar ? + m_extrapolator->extrapolate(*firstmeaspar,perigeeSurface,Trk::anyDirection,true,track.info().particleHypothesis() ) : 0; + const Trk::Perigee* extrapolatedPerigee = extrapolatedParameters ? dynamic_cast<const Trk::Perigee*>(extrapolatedParameters) : 0; + + if (!extrapolatedPerigee || !extrapolatedPerigee->covariance() ) { + ATH_MSG_WARNING( "Track Selector failed to extrapolate track to the vertex: " << myVertex->position() ); + if (extrapolatedParameters!=0) { + ATH_MSG_WARNING( "The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" ); + delete extrapolatedParameters; + } + } + + //decision based on the track parameters + const Trk::RecVertex* recVertex = dynamic_cast<const Trk::RecVertex*>(myVertex); + bool dec = decision(extrapolatedPerigee, recVertex ? &recVertex->covariancePosition() : 0 ); + + if (myVertex!=vertex) { + delete myVertex; + myVertex=0; + } + + bool isInTrtAcceptance=true; + + if (!extrapolatedPerigee || fabs(extrapolatedPerigee->momentum().eta())>m_TrtMaxEtaAcceptance) { + isInTrtAcceptance=false; + } + + if (extrapolatedPerigee!=track.perigeeParameters()) { + delete extrapolatedPerigee; + extrapolatedPerigee=0; + } + + if(!dec) { + ATH_MSG_DEBUG("Track rejected because of perigee parameters!"); + return false; + } + + if (m_useTrackQualityInfo) { + + const Trk::FitQuality* TrkQuality=track.fitQuality(); + + if (TrkQuality==0) { + ATH_MSG_WARNING( "Requested cut on track quality was not possible. Track has no FitQuality object attached. Selection failed." ); + return false; + } + + if (!decision(TrkQuality)) { + return false; + } + } + + if (m_useTrackSummaryInfo) { + //number of hits, silicon hits, b-layer + + const Trk::TrackSummary* summary = 0; + + // first ask track for summary + summary = track.trackSummary(); + + if (m_trackSumToolAvailable && summary == 0) { + // ugly but one needs to cast the const away because the method needs to update the track (the tool is a friend of track) + Trk::Track& nonConstTrack = const_cast<Trk::Track&>(track); + m_trackSumTool->updateTrack(nonConstTrack); + summary = nonConstTrack.trackSummary(); + } + + if (!m_trackSumToolAvailable) { + ATH_MSG_WARNING( " No Track Summary Tool available. This should be the case only when running on AOD" ); + } + + if (0==summary ) { + ATH_MSG_WARNING( "Track preselection: cannot create a track summary (but useTrackSummary is true). Selection failed." ); + return false; + } + + // get the minimum nimber of TRT hits based on eta of the track + if(m_useEtaDepententMinHitTrt) { + m_nHitTrt = m_trtDCTool->minNumberDCs( (*track.trackParameters())[0] ); + if(m_addToMinHitTrt!=0) + m_nHitTrt += m_addToMinHitTrt; + else + m_nHitTrt = (int)((double)m_nHitTrt*m_scaleMinHitTrt); + } + + // get the minimum nimber of TRT hits + outliers based on eta of the track + if(m_useEtaDepententMinHitTrtWithOutliers) { + m_nHitTrtPlusOutliers = m_trtDCTool->minNumberDCs( (*track.trackParameters())[0] ); + if(m_addToMinHitTrtWithOutliers!=0) + m_nHitTrtPlusOutliers += m_addToMinHitTrtWithOutliers; + else + m_nHitTrtPlusOutliers = (int)((double)m_nHitTrtPlusOutliers*m_scaleMinHitTrtWithOutliers); + } + + if (!decision(summary,m_useSharedHitInfo,isInTrtAcceptance, perigeeBeforeExtrapolation)) { + summary=0; + return false; + } + summary=0; + } + + //all ok + return true; + } + + // --------------------------------------------------------------------- + bool InDetDetailedTrackSelectorTool::decision(const Trk::TrackParticleBase& track,const Trk::Vertex* vertex) const + { + + const Trk::TrackParameters* definintParameters=&(track.definingParameters()); + + const Trk::Perigee* perigeeBeforeExtrapolation= + dynamic_cast<const Trk::Perigee*>(definintParameters); + + if (perigeeBeforeExtrapolation && m_usePreselectionCuts) { + bool preselectionDecision=preselectionBeforeExtrapolation(*perigeeBeforeExtrapolation); + if (!preselectionDecision) { + ATH_MSG_DEBUG("Track rejected because of preselection decision!"); + return false; + } + } + else if (m_usePreselectionCuts) { + ATH_MSG_WARNING( " Preselection was requested but cannot be made since the Perigee is not the defining Parameter of the TrackParticle. This is not an error." ); + } + + + bool isInTrtAcceptance=true; + if (!perigeeBeforeExtrapolation || fabs(perigeeBeforeExtrapolation->momentum().eta())>m_TrtMaxEtaAcceptance) { + isInTrtAcceptance=false; + } + + + if (m_useTrackQualityInfo) { + + const Trk::FitQuality* TrkQuality=track.fitQuality(); + + if (TrkQuality==0) { + ATH_MSG_WARNING( "Requested cut on track quality was not possible. TrackParticleBase has no FitQuality object attached. Selection failed." ); + return false; + } + + if (!decision(TrkQuality)) { + return false; + } + + } + + if (m_useTrackSummaryInfo) { + //number of hits, silicon hits, b-layer + const Trk::TrackSummary* summary = track.trackSummary(); + + if (0==summary ) { + ATH_MSG_WARNING( "Track preselection: cannot create a track summary (but useTrackSummary is true). Selection failed." ); + return false; + } + + if(m_useEtaDepententMinHitTrt) { + m_nHitTrt = m_trtDCTool->minNumberDCs( (track.trackParameters())[0] ); + if(m_addToMinHitTrt!=0) + m_nHitTrt += m_addToMinHitTrt; + else + m_nHitTrt = (int)((double)m_nHitTrt*m_scaleMinHitTrt); + } + + if(m_useEtaDepententMinHitTrtWithOutliers) { + m_nHitTrtPlusOutliers = m_trtDCTool->minNumberDCs( (track.trackParameters())[0] ); + if(m_addToMinHitTrtWithOutliers!=0) + m_nHitTrtPlusOutliers += m_addToMinHitTrtWithOutliers; + else + m_nHitTrtPlusOutliers = (int)((double)m_nHitTrtPlusOutliers*m_scaleMinHitTrtWithOutliers); + } + + if (!decision(summary, m_useSharedHitInfo, isInTrtAcceptance, perigeeBeforeExtrapolation)) { + return false; + } + } + + const Trk::Perigee* extrapolatedPerigee=dynamic_cast<const Trk::Perigee*>(definintParameters); + + const Trk::Vertex* myVertex=vertex; + + if (vertex==0) { + //ATH_MSG_DEBUG( "No vertex given, using beam spot or 0,0,0" ); + if (!m_iBeamCondSvc.empty()) { + myVertex=new Trk::RecVertex(m_iBeamCondSvc->beamVtx()); + } else { + ATH_MSG_WARNING( " Cannot get beamSpot center from iBeamCondSvc. Using (0,0,0)... " ); + myVertex=new Trk::Vertex(Amg::Vector3D(0,0,0)); + } + } + + Trk::PerigeeSurface perigeeSurface(myVertex->position()); + + const Trk::TrackParameters *firstmeaspar=0; + + for (unsigned int i=0;i<track.trackParameters().size();i++) { + if ((track.trackParameters())[i]->covariance() && + !dynamic_cast<const Trk::Perigee*>((track.trackParameters())[i])) { + firstmeaspar=(track.trackParameters())[i]; + break; + } + } + + if (!firstmeaspar) { + if (!extrapolatedPerigee || !extrapolatedPerigee->covariance() ) { + ATH_MSG_DEBUG( " Track Paraemters at first measurement not found. Perigee not found. Cannot do TrackSelection..." ); + if (myVertex!=vertex) { + delete myVertex; + myVertex=0; + } + return false; + } + //using perigee instead of firstmeasurement, since first measurement was not found... + firstmeaspar=&(track.definingParameters()); + } + + ATH_MSG_VERBOSE ("Input to extrapolation: " << *firstmeaspar); + ATH_MSG_VERBOSE ("Extrapolating to position: " << myVertex->position()[0] << " , " << + myVertex->position()[1] << " , " << myVertex->position()[2]); + + const Trk::TrackParameters* extrapolatedParameters= firstmeaspar ? + m_extrapolator->extrapolate(*firstmeaspar,perigeeSurface,Trk::anyDirection,true,Trk::pion ) : 0; + + extrapolatedPerigee = extrapolatedParameters ? dynamic_cast<const Trk::Perigee*>(extrapolatedParameters) : 0; + + + if (extrapolatedPerigee==0 || !extrapolatedPerigee->covariance()) { + ATH_MSG_WARNING( "Track Selector failed to extrapolate track to the vertex: " << myVertex->position() ); + if (extrapolatedParameters!=0) { + ATH_MSG_WARNING( "The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" ); + delete extrapolatedParameters; + } + } + + ATH_MSG_VERBOSE ("Result: " << *extrapolatedParameters); + + const Trk::RecVertex* recVertex = dynamic_cast<const Trk::RecVertex*>(myVertex); + bool dec = decision(extrapolatedPerigee, recVertex ? &recVertex->covariancePosition() : 0 ); + + if (myVertex!=vertex) { + delete myVertex; + myVertex=0; + } + if (extrapolatedPerigee!=&(track.definingParameters())) { + delete extrapolatedPerigee; + extrapolatedPerigee=0; + } + + if(!dec) { + ATH_MSG_DEBUG("Track rejected because of perigee parameters!"); + return false; + } + + return true; + } + + + // --------------------------------------------------------------------- + bool InDetDetailedTrackSelectorTool::decision(const xAOD::TrackParticle& tp,const xAOD::Vertex* vertex) const + { + + const Trk::Perigee& perigee=tp.perigeeParameters(); + if (m_usePreselectionCuts && !preselectionBeforeExtrapolation(perigee)) { + ATH_MSG_DEBUG("Track rejected because of preselection decision!"); + return false; + } + + if (m_useTrackQualityInfo && !decision(tp.chiSquared(),tp.numberDoF())) { + ATH_MSG_DEBUG("Track rejected because of bad fit quality!"); + return false; + } + + if (m_useTrackSummaryInfo) { + //number of hits, silicon hits, b-layer + + if(m_useEtaDepententMinHitTrt) { + m_nHitTrt = m_trtDCTool->minNumberDCs( &perigee ); + if(m_addToMinHitTrt!=0) + m_nHitTrt += m_addToMinHitTrt; + else + m_nHitTrt = (int)((double)m_nHitTrt*m_scaleMinHitTrt); + } + + if(m_useEtaDepententMinHitTrtWithOutliers) { + m_nHitTrtPlusOutliers = m_trtDCTool->minNumberDCs( &perigee ); + if(m_addToMinHitTrtWithOutliers!=0) + m_nHitTrtPlusOutliers += m_addToMinHitTrtWithOutliers; + else + m_nHitTrtPlusOutliers = (int)((double)m_nHitTrtPlusOutliers*m_scaleMinHitTrtWithOutliers); + } + + + int nb = getCount(tp,xAOD::numberOfBLayerHits ); + int np = getCount(tp,xAOD::numberOfPixelHits ); + int npd = getCount(tp,xAOD::numberOfPixelDeadSensors ); + int ns = getCount(tp,xAOD::numberOfSCTHits ); + int nhp = getCount(tp,xAOD::numberOfPixelHoles ); + int nhs = getCount(tp,xAOD::numberOfSCTHoles ); + int ndhs = getCount(tp,xAOD::numberOfSCTDoubleHoles); + + //**----------------------------------------------------------------------- + if(m_usePtDependentCuts) { + + double pt = tp.pt(); + + unsigned int it = 0; + for(; it< m_ptBenchmarks.size()-1; ++it ) { + if(pt>m_ptBenchmarks[it] && pt <=m_ptBenchmarks[it+1] && ns < m_nSCTValues[it]) { + ATH_MSG_DEBUG("Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ; + return false; + } + }//end of pt intervals loop + + //now cutting all the rest by the last value in the vector + if(pt>m_ptBenchmarks[it+1] && ns < m_nSCTValues[it+1]) { + ATH_MSG_DEBUG("Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ; + return false; + } + } + + //*-------------------------------------------------------------------------------- + + //normal cuts in all their variety + + if(nb == 0 && nb < m_nHitBLayer) { + ATH_MSG_DEBUG("Track rejected because of nHitBLayer "<<nb<<" < "<<m_nHitBLayer); + if(m_inDetTestBLayerTool.empty()) { + ATH_MSG_DEBUG("and no blayer tool configured, so will not try to recover track"); + return false; + } else if (m_inDetTestBLayerTool->expectHitInBLayer(&perigee)) { + ATH_MSG_DEBUG("and track rejected because of Number of b-layer hits ACCOUNTING for those expected") ; + return false; + }else ATH_MSG_DEBUG("recovered track as no b-layer expected") ; + }//end of checking the b-layer + + if(np+npd < m_nHitPix) { + ATH_MSG_DEBUG("Track rejected because of nHitPix "<<np+npd<<" < "<<m_nHitPix); + return false; + } + + if(np < m_nHitPixPhysical) { + ATH_MSG_DEBUG("Track rejected because of nHitPixPhysical "<<np<<" < "<<m_nHitPixPhysical); + return false; + } + + int nsd = getCount(tp,xAOD::numberOfSCTDeadSensors); + if(ns+nsd < m_nHitSct) { + ATH_MSG_DEBUG("Track rejected because of nHitSct "<<ns+nsd<<" < "<<m_nHitSct); + return false; + } + + if(np+ns+npd+nsd < m_nHitSi) { + ATH_MSG_DEBUG("Track rejected because of nHitSi "<<np+npd+ns+nsd<<" < "<<m_nHitSi); + return false; + } + + if(np+ns < m_nHitSiPhysical) { + ATH_MSG_DEBUG("Track rejected because of nHitSiPhysical "<<np+ns<<" < "<<m_nHitSiPhysical); + return false; + } + + if (nb+np+npd< m_nHitBLayerPlusPix){ + ATH_MSG_DEBUG("Track rejected because of nHitBLayerPlusPix "<<nb+np+npd<<" < "<<m_nHitBLayerPlusPix); + return false; + } + + // Cuts on number of Holes + if (nhp+nhs > m_nHoles){ + ATH_MSG_DEBUG("Track rejected because of nHolesPixPlusSCT "<<nhp+nhs<<" > "<<m_nHoles); + return false; + } + + if(ndhs > m_nDoubleHoles){ + ATH_MSG_DEBUG("Track rejected because of nDoubleHolesSCT "<<ndhs<<" > "<<m_nDoubleHoles); + return false; + } + + if(nhp > m_nHolesPix){ + ATH_MSG_DEBUG("Track rejected because of nHolesPix "<<nhp<<" > "<<m_nHolesPix); + return false; + } + + if (nhs > m_nHolesSct){ + ATH_MSG_DEBUG("Track rejected because of nHolesSct "<<nhs<<" > "<<m_nHolesSct); + return false; + } + + if (fabs(tp.eta())>m_TrtMaxEtaAcceptance) { + int nh = getCount(tp,xAOD::numberOfTRTHits); + if(nh < m_nHitTrt) { + ATH_MSG_DEBUG("Track rejected because of nHitTrt "<<nh<<" < "<<m_nHitTrt); + return false; + } + + int nhh = getCount(tp, xAOD::numberOfTRTHits ) + getCount(tp, xAOD::numberOfTRTOutliers ); + if (nhh<m_nHitTrtPlusOutliers) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtPlusOutliers "<<nhh<<" < "<<m_nHitTrtPlusOutliers); + return false; + } + + int nhthits= getCount(tp,xAOD::numberOfTRTHighThresholdHits); + if (nhthits<m_nHitTrtHighE) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtHighE "<<nhthits<<" < "<<m_nHitTrtHighE); + return false; + } + + int nhthitsWithOutliers= getCount(tp,xAOD::numberOfTRTHighThresholdHits) + getCount(tp,xAOD::numberOfTRTHighThresholdOutliers); + if (nhthitsWithOutliers<m_nHitTrtPlusOutliersHighE) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtPlusOutliersHighE "<<nhthitsWithOutliers<<" < "<<m_nHitTrtPlusOutliersHighE); + return false; + } + + if ( getCount(tp, xAOD::numberOfTRTHits )>0) { + double nhe = getCount(tp,xAOD::numberOfTRTHighThresholdHits); + nhe /= getCount(tp, xAOD::numberOfTRTHits); + if(nhe > m_nHitTrtHighEFraction ) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtHighEFraction "<<nhe<<" < "<<m_nHitTrtHighEFraction); + return false; + } + } + + if ( getCount(tp, xAOD::numberOfTRTHits ) + getCount(tp, xAOD::numberOfTRTOutliers ) > 0 ) { + double nheh = (double)(getCount(tp,xAOD::numberOfTRTHighThresholdHits) + getCount(tp,xAOD::numberOfTRTHighThresholdOutliers))/ + (double)(getCount(tp, xAOD::numberOfTRTHits) + getCount(tp, xAOD::numberOfTRTOutliers ) ); + if(nheh<0.) nheh=0.; + if (nheh>1.) nheh=1.; + if(nheh > m_nHitTrtHighEFractionWithOutliers ) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtHighEFractionWithOutliers "<<nheh<<" < "<<m_nHitTrtHighEFractionWithOutliers); + return false; + } + } + } + + if (m_useSharedHitInfo) { + + int nbs = getCount(tp,xAOD::numberOfBLayerSharedHits); + if (nbs>1) nbs=1; + if(nbs>m_nSharedBLayer) { + ATH_MSG_DEBUG("Track rejected because of nSharedBLayer "<<nbs<<" < "<<m_nSharedBLayer); + return false; + } + + int nps = getCount(tp,xAOD::numberOfPixelSharedHits); + if(nps>m_nSharedPix) { + ATH_MSG_DEBUG("Track rejected because of nSharedPix "<<nps<<" < "<<m_nSharedPix); + return false; + } + + int nss = getCount(tp,xAOD::numberOfSCTSharedHits); + if(nss > m_nSharedSct) { + ATH_MSG_DEBUG("Track rejected because of nSharedSct "<<nss<<" < "<<m_nSharedSct); + return false; + } + + int nst = nps + nss; + if(nst>m_nSharedSi) { + ATH_MSG_DEBUG("Track rejected because of nSharedSi "<<nst<<" < "<<m_nSharedSi); + return false; + } + } + } + Trk::PerigeeSurface perigeeSurface( vertex ? vertex->position() : (!m_iBeamCondSvc.empty() ? m_iBeamCondSvc->beamVtx().position() : Amg::Vector3D(0,0,0) ) ); + + const Trk::TrackParameters* extrapolatedParameters= m_extrapolator->extrapolate(perigee,perigeeSurface,Trk::anyDirection,true,Trk::pion ); + const Trk::Perigee* extrapolatedPerigee = extrapolatedParameters ? dynamic_cast<const Trk::Perigee*>(extrapolatedParameters) : 0; + if (extrapolatedPerigee==0) { + ATH_MSG_WARNING( "Extrapolation to the vertex failed: " << perigeeSurface << std::endl << perigee ); + if (extrapolatedParameters!=0) { + ATH_MSG_WARNING( "The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" ); + delete extrapolatedParameters; + } + return false; + } + bool dec = false; + if( vertex ){ + // for now copy the position error + AmgSymMatrix(3) vertexError = vertex->covariancePosition(); + dec = decision(extrapolatedPerigee,&vertexError); + }else{ + dec = decision(extrapolatedPerigee,0); + } + + delete extrapolatedPerigee; + + if(!dec) { + ATH_MSG_DEBUG("Track rejected because of perigee parameters!"); + return false; + } + + return true; + } + + + // --------------------------------------------------------------------- + bool InDetDetailedTrackSelectorTool::decision(const Trk::Perigee* track,const AmgSymMatrix(3)* covariancePosition) const { + + // checking pointer first + if(0==track || !track->covariance()) { + ATH_MSG_WARNING( "Decision on measured perigee: Zero pointer to measured perigee passed. Selection failed." ); + return false; + } + + const AmgVector(5)& perigeeParms = track->parameters(); + + if (m_magFieldSvc->solenoidOn()) { + if (perigeeParms[Trk::qOverP] == 0.) { + ATH_MSG_DEBUG("Track rejected because of qOverP == 0."); + return false; + } + double p = fabs(1./perigeeParms[Trk::qOverP]); + if (p<m_pMin) { + ATH_MSG_DEBUG("Track rejected because of p " << p << " < " << m_pMin); + return false; + } + double pt = p*sin(perigeeParms[Trk::theta]); + if (pt<m_pTMin) { + ATH_MSG_DEBUG("Track rejected because of pt " << pt << " < " << m_pTMin); + return false; + } + } + + if (fabs(perigeeParms[Trk::d0]) > m_IPd0Max) { + ATH_MSG_DEBUG("Track rejected because of fabs(d0) " << fabs(perigeeParms[Trk::d0]) << " > " << m_IPd0Max); + return false; + } + + if (fabs(perigeeParms[Trk::z0]*sin(perigeeParms[Trk::theta])) > m_IPz0Max) { + ATH_MSG_DEBUG("Track rejected because of fabs(z0*sin(theta)) " << fabs(perigeeParms[Trk::z0]*sin(perigeeParms[Trk::theta])) << " > " << m_IPz0Max); + return false; + } + + if (fabs(perigeeParms[Trk::z0]) > m_z0Max) { + ATH_MSG_DEBUG("Track rejected because of fabs(z0) " << fabs(perigeeParms[Trk::z0]) << " > " << m_z0Max); + return false; + } + + if (sqrt( (*track->covariance())(Trk::z0,Trk::z0) )*sin(perigeeParms[Trk::theta])>m_sigIPz0Max) { + ATH_MSG_DEBUG("Track rejected because of err(z0)*sin(theta) " << sqrt( (*track->covariance())(Trk::z0,Trk::z0) )*sin(perigeeParms[Trk::theta]) << " > " << m_sigIPz0Max); + return false; + } + + if (sqrt( (*track->covariance())(Trk::d0,Trk::d0) )>m_sigIPd0Max) { + ATH_MSG_DEBUG("Track rejected because of err(d0) " << sqrt( (*track->covariance())(Trk::d0,Trk::d0) ) << " > " << m_sigIPd0Max); + return false; + } + + if (m_d0significanceMax>0 || m_z0significanceMax>0) { + + double sinTheta = sin(perigeeParms[Trk::theta]); + double cosTheta = cos(perigeeParms[Trk::theta]); + double d0wrtPriVtx = perigeeParms[Trk::d0]; + double deltaZ = perigeeParms[Trk::z0]; + double z0wrtPriVtx = deltaZ*sinTheta; + double testtrackSigD0 = sqrt( (*track->covariance())(Trk::d0,Trk::d0) ); + double testtrackSigZ0 = sqrt( (*track->covariance())(Trk::z0,Trk::z0) ); + double testtrackSigTh = sqrt( (*track->covariance())(Trk::theta,Trk::theta) ); + // error on IP: + double trackPhi = perigeeParms[Trk::phi]; + double dIPdx = sin(trackPhi); + double dIPdy = -cos(trackPhi); + double DD0 = testtrackSigD0*testtrackSigD0; + double newD0Err=0; + if (covariancePosition) { + double DXX = dIPdx*dIPdx* (*covariancePosition)(0,0); + double DYY = dIPdy*dIPdy* (*covariancePosition)(1,1); + double DXY = 2.*dIPdx*dIPdy* (*covariancePosition)(0,1); + newD0Err = DD0 + DXX + DYY + DXY; + } else { + newD0Err = DD0; + } + + double d0ErrwrtPriVtx = (newD0Err>0 ? sqrt(newD0Err) : -10e-9); + + if (d0ErrwrtPriVtx<0) { + ATH_MSG_WARNING( " error on d0 is negative: numeric error... (not expected. please report!)" ); + } + + if (m_d0significanceMax>0) { + if (fabs(d0wrtPriVtx/d0ErrwrtPriVtx)>m_d0significanceMax) { + ATH_MSG_DEBUG("Track rejected because of fabs(d0wrtPriVtx/d0ErrwrtPriVtx) " << fabs(d0wrtPriVtx/d0ErrwrtPriVtx) << " > " << m_d0significanceMax); + return false; + } + } + + if (m_z0significanceMax>0) { + + // error on zIP: + double dZIPdTheta = deltaZ*cosTheta; + double dZIPdz0 = sinTheta; + double dZIPdzV = -sinTheta; + double DTheta2 = dZIPdTheta*dZIPdTheta*testtrackSigTh*testtrackSigTh; + double DZ02 = dZIPdz0*dZIPdz0*testtrackSigZ0*testtrackSigZ0; + double DThetaZ0 = 2.*dZIPdTheta*dZIPdz0*(*track->covariance())(Trk::theta,Trk::z0); + double newZ0Err(0); + if (covariancePosition) { + double DZV2 = dZIPdzV*dZIPdzV* (*covariancePosition)(2,2); + newZ0Err = DTheta2 + DZ02 + DZV2 + DThetaZ0; + } else { + newZ0Err = DTheta2 + DZ02 + DThetaZ0; + } + + double z0ErrwrtPriVtx = (newZ0Err>0 ? sqrt(newZ0Err) : -10e-9); + + if (z0ErrwrtPriVtx<0) { + ATH_MSG_WARNING( " error on z0 is negative: numeric error... (not expected. please report!)" ); + } + + if (fabs(z0wrtPriVtx/z0ErrwrtPriVtx)>m_z0significanceMax) { + ATH_MSG_DEBUG("Track rejected because of fabs(z0wrtPriVtx/z0ErrwrtPriVtx) " << fabs(z0wrtPriVtx/z0ErrwrtPriVtx) << " > " << m_z0significanceMax); + return false; + } + } + + } + + if (fabs(track->momentum().eta())>m_etaMax) { + ATH_MSG_DEBUG("Track rejected because of fabs(eta) " << fabs(track->momentum().eta()) << " > " << m_etaMax); + return false; + } + + return true; + } + + // --------------------------------------------------------------------- + bool InDetDetailedTrackSelectorTool::decision(const Trk::FitQuality* trkQuality) const + { + if(0 == trkQuality) { + ATH_MSG_WARNING( "Null FitQuality pointer passed. No track Quality cut possible. Selection failed." ); + return false; + } + return decision(trkQuality->chiSquared(),trkQuality->numberDoF()); + } + + bool InDetDetailedTrackSelectorTool::decision(double chi2, int ndf ) const{ + + double proba = 1.; + + if(ndf>0 && chi2>=0.) { + Genfun::CumulativeChiSquare myCumulativeChiSquare(ndf); + proba = 1.-myCumulativeChiSquare(chi2); + } + + if(chi2>m_fitChi2) { + ATH_MSG_DEBUG("Track rejected because of chi2 "<<chi2<<" > "<<m_fitChi2); + return false; + } + + if(proba<m_fitProb) { + ATH_MSG_DEBUG("Track rejected because of fit probability "<<proba<<" > "<<m_fitProb); + return false; + } + if(ndf>0 && chi2/double(ndf)>m_fitChi2OnNdfMax) { + ATH_MSG_DEBUG("Track rejected because of chi2/ndof "<<chi2/double(ndf)<<" > "<<m_fitChi2OnNdfMax); + return false; + } + + return true; + } + + + // --------------------------------------------------------------------- + bool InDetDetailedTrackSelectorTool::decision(const Trk::TrackSummary* summary,bool useSharedHitInfo,bool useTrtHitInfo, + const Trk::Perigee * track) const + { + if (summary==0) { + ATH_MSG_WARNING( "Null TrackSummary pointer passed. Selection failed." ); + return false; + } + + int nb = summary->get(Trk::numberOfBLayerHits); + + if(nb<0) nb=0; + + int np = summary->get(Trk::numberOfPixelHits); + if(np<0) np=0; + + int npd = summary->get(Trk::numberOfPixelDeadSensors); + if(npd<0) npd=0; + + int ns = summary->get(Trk::numberOfSCTHits); + if(ns<0) ns=0; + + int nhp = summary->get(Trk::numberOfPixelHoles); + if (nhp < 0) nhp = 0; + + int nhs = summary->get(Trk::numberOfSCTHoles); + if (nhs < 0) nhs = 0; + + int ndhs = summary->get(Trk::numberOfSCTDoubleHoles); + if (ndhs < 0) ndhs = 0; + + //**----------------------------------------------------------------------- + + if(m_usePtDependentCuts) { + + const AmgVector(5)& perigeeParms = track->parameters(); + double p = fabs(1./perigeeParms[Trk::qOverP]); + double pt = p*sin(perigeeParms[Trk::theta]); + + unsigned int it = 0; + for(; it< m_ptBenchmarks.size()-1; ++it ) { + if(pt>m_ptBenchmarks[it] && pt <=m_ptBenchmarks[it+1] && ns < m_nSCTValues[it]) { + ATH_MSG_DEBUG("Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ; + return false; + } + }//end of pt intervals loop + + //now cutting all the rest by the last value in the vector + if(pt>m_ptBenchmarks[it+1] && ns < m_nSCTValues[it+1]) { + ATH_MSG_DEBUG("Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ; + return false; + } + + } + + //*-------------------------------------------------------------------------------- + + //normal cuts in all their variety + + if(nb == 0 && nb < m_nHitBLayer) { + ATH_MSG_DEBUG("Track rejected because of nHitBLayer "<<nb<<" < "<<m_nHitBLayer); + if(m_inDetTestBLayerTool.empty()) { + ATH_MSG_DEBUG("and no blayer tool configured, so will not try to recover track"); + return false; + } else if (m_inDetTestBLayerTool->expectHitInBLayer(track)) { + ATH_MSG_DEBUG("and track rejected because of Number of b-layer hits ACCOUNTING for those expected") ; + return false; + }else ATH_MSG_DEBUG("recovered track as no b-layer expected") ; + }//end of checking the b-layer + + if(np+npd < m_nHitPix) { + ATH_MSG_DEBUG("Track rejected because of nHitPix "<<np+npd<<" < "<<m_nHitPix); + return false; + } + + if(np < m_nHitPixPhysical) { + ATH_MSG_DEBUG("Track rejected because of nHitPixPhysical "<<np<<" < "<<m_nHitPixPhysical); + return false; + } + + int nsd = summary->get(Trk::numberOfSCTDeadSensors); + if(nsd<0) + nsd=0; + + if(ns+nsd < m_nHitSct) + { + ATH_MSG_DEBUG("Track rejected because of nHitSct "<<ns+nsd<<" < "<<m_nHitSct); + return false; + } + + if((np+ns+npd+nsd) < m_nHitSi) + { + ATH_MSG_DEBUG("Track rejected because of nHitSi "<<np+npd+ns+nsd<<" < "<<m_nHitSi); + return false; + } + + if((np+ns) < m_nHitSiPhysical) + { + ATH_MSG_DEBUG("Track rejected because of nHitSiPhysical "<<np+ns<<" < "<<m_nHitSiPhysical); + return false; + } + + if ((nb+np+npd)< m_nHitBLayerPlusPix) + { + ATH_MSG_DEBUG("Track rejected because of nHitBLayerPlusPix "<<nb+np+npd<<" < "<<m_nHitBLayerPlusPix); + return false; + } + + // Cuts on number of Holes + + if ((nhp+nhs) > m_nHoles) + { + ATH_MSG_DEBUG("Track rejected because of nHolesPixPlusSCT "<<nhp+nhs<<" > "<<m_nHoles); + return false; + } + + if (ndhs > m_nDoubleHoles) + { + ATH_MSG_DEBUG("Track rejected because of nDoubleHolesSCT "<<ndhs<<" > "<<m_nDoubleHoles); + return false; + } + + if (nhp > m_nHolesPix) + { + ATH_MSG_DEBUG("Track rejected because of nHolesPix "<<nhp<<" > "<<m_nHolesPix); + return false; + } + + if (nhs > m_nHolesSct) + { + ATH_MSG_DEBUG("Track rejected because of nHolesSct "<<nhs<<" > "<<m_nHolesSct); + return false; + } + + if (useTrtHitInfo) { + + int nh = summary->get(Trk::numberOfTRTHits); + if(nh<0) nh=0; + if(nh < m_nHitTrt) { + ATH_MSG_DEBUG("Track rejected because of nHitTrt "<<nh<<" < "<<m_nHitTrt); + return false; + } + + int nhh = summary->get( Trk::numberOfTRTHits ) + summary->get( Trk::numberOfTRTOutliers ); + if (nhh<0) nhh=0; + if (nhh<m_nHitTrtPlusOutliers) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtPlusOutliers "<<nhh<<" < "<<m_nHitTrtPlusOutliers); + return false; + } + + int nhthits=summary->get(Trk::numberOfTRTHighThresholdHits); + if (nhthits<0) nhthits=0; + if (nhthits<m_nHitTrtHighE) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtHighE "<<nhthits<<" < "<<m_nHitTrtHighE); + return false; + } + + int nhthitsWithOutliers=summary->get(Trk::numberOfTRTHighThresholdHits) + summary->get(Trk::numberOfTRTHighThresholdOutliers); + if (nhthitsWithOutliers<0) nhthitsWithOutliers=0; + if (nhthitsWithOutliers<m_nHitTrtPlusOutliersHighE) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtPlusOutliersHighE "<<nhthitsWithOutliers<<" < "<<m_nHitTrtPlusOutliersHighE); + return false; + } + + if (summary->get( Trk :: numberOfTRTHits )>0) { + double nhe = (double)summary->get(Trk::numberOfTRTHighThresholdHits) / (double)summary->get( Trk::numberOfTRTHits ); + if(nhe<0.) nhe=0.; + if(nhe > m_nHitTrtHighEFraction ) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtHighEFraction "<<nhe<<" < "<<m_nHitTrtHighEFraction); + return false; + } + } + + if ( summary->get( Trk :: numberOfTRTHits ) + summary->get( Trk :: numberOfTRTOutliers ) > 0 ) { + double nheh = (double)(summary->get(Trk::numberOfTRTHighThresholdHits) + summary->get(Trk::numberOfTRTHighThresholdOutliers))/ + (double)(summary->get( Trk::numberOfTRTHits) + summary->get( Trk :: numberOfTRTOutliers ) ); + if(nheh<0.) nheh=0.; + if (nheh>1.) nheh=1.; + if(nheh > m_nHitTrtHighEFractionWithOutliers ) { + ATH_MSG_DEBUG("Track rejected because of nHitTrtHighEFractionWithOutliers "<<nheh<<" < "<<m_nHitTrtHighEFractionWithOutliers); + return false; + } + } + } + + if (useSharedHitInfo) { + + int nbs = summary->get(Trk::numberOfBLayerSharedHits); + if(nbs < 0) nbs = 0; + if (nbs>1) nbs=1; + if(nbs>m_nSharedBLayer) { + ATH_MSG_DEBUG("Track rejected because of nSharedBLayer "<<nbs<<" < "<<m_nSharedBLayer); + return false; + } + + int nps = summary->get(Trk::numberOfPixelSharedHits); + if(nps < 0) nps = 0; + if(nps>m_nSharedPix) { + ATH_MSG_DEBUG("Track rejected because of nSharedPix "<<nps<<" < "<<m_nSharedPix); + return false; + } + + int nss = summary->get(Trk::numberOfSCTSharedHits); + if(nss < 0) nss = 0; + if(nss > m_nSharedSct) { + ATH_MSG_DEBUG("Track rejected because of nSharedSct "<<nss<<" < "<<m_nSharedSct); + return false; + } + + int nst = nps + nss; + if(nst>m_nSharedSi) { + ATH_MSG_DEBUG("Track rejected because of nSharedSi "<<nst<<" < "<<m_nSharedSi); + return false; + } + } + + return true; + + } + + // --------------------------------------------------------------------- + bool InDetDetailedTrackSelectorTool::preselectionBeforeExtrapolation(const Trk::Perigee & myPerigee) const + { + const AmgVector(5)& perigeeParms = myPerigee.parameters(); + + if (m_magFieldSvc->solenoidOn()) { + if (perigeeParms[Trk::qOverP] == 0.) { + ATH_MSG_DEBUG("Track rejected because of perigee qOverP == 0."); + return false; + } + double p = fabs(1./perigeeParms[Trk::qOverP]); + if (p<m_pMin) { + ATH_MSG_DEBUG("Track rejected because of p " << p << " < " << m_pMin); + return false; + } + double pt = p*sin(perigeeParms[Trk::theta]); + if (pt<m_pTMin) { + ATH_MSG_DEBUG("Track rejected because of pt " << pt << " < " << m_pTMin); + return false; + } + } + + if (fabs(perigeeParms[Trk::d0]) > m_d0MaxPreselection) { + ATH_MSG_DEBUG("Track rejected because of fabs(d0) "<<fabs(perigeeParms[Trk::d0])<<" < "<<m_d0MaxPreselection); + return false; + } + + return true; + } + +} //end of namespace definitions diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetIsoTrackSelectorTool.cxx b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetIsoTrackSelectorTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..006dbe6a78da397f7a67fffcd5fa618f9511158c --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetIsoTrackSelectorTool.cxx @@ -0,0 +1,183 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetTrackSelectorTool/InDetIsoTrackSelectorTool.h" +#include "TrkToolInterfaces/ITrackSelectorTool.h" +// forward declares +#include "TrkExInterfaces/IExtrapolator.h" +#include "TrkTrack/Track.h" +#include "TrkParticleBase/TrackParticleBase.h" +#include "TrkSurfaces/StraightLineSurface.h" + +using CLHEP::mm; + +//_______________________________________________________________________________ +InDet::InDetIsoTrackSelectorTool::InDetIsoTrackSelectorTool(const std::string & t, const std::string & n, const IInterface * p) + : AthAlgTool(t,n,p), + m_robustCuts(true), + m_applySinThetaCorrection(true), + m_d0max(1.5*mm), + m_z0stMax(1.5*mm), + m_d0Significance(3), + m_z0Significance(3), + m_extrapolator("Trk::Extrapolator/InDetExtrapolator"), + m_trackSelector("") +{ + declareInterface<Trk::IIsoTrackSelectorTool>(this); + // properties via python binding + declareProperty("RobustCuts", m_robustCuts); + declareProperty("SinThetaCorrection", m_applySinThetaCorrection); + declareProperty("maxD0", m_d0max); + declareProperty("maxZ0", m_z0stMax); + declareProperty("maxD0overSigmaD0", m_d0Significance); + declareProperty("maxZ0overSigmaZ0", m_z0Significance); + // tools + declareProperty("Extrapolator", m_extrapolator); + declareProperty("TrackSelector", m_trackSelector); +} + +//_______________________________________________________________________________ +InDet::InDetIsoTrackSelectorTool::~InDetIsoTrackSelectorTool() +{} + +//_______________________________________________________________________________ +StatusCode InDet::InDetIsoTrackSelectorTool::initialize() +{ + + // get the extrapolator + if ( m_extrapolator.retrieve().isFailure() ){ + ATH_MSG_ERROR("Could not retrieve Extrapolator '" << m_extrapolator << "' (essential). Abort."); + return StatusCode::FAILURE; + } else + ATH_MSG_DEBUG("Successfully retrieved " << m_extrapolator); + + // get the track selector if needed + if ( !m_trackSelector.empty() && m_trackSelector.retrieve().isFailure() ){ + ATH_MSG_ERROR("Could not retrieve TrackSelector '" << m_trackSelector <<"' although configured. Abort."); + return StatusCode::FAILURE; + } + // done + return StatusCode::SUCCESS; +} + +//_______________________________________________________________________________ +StatusCode InDet::InDetIsoTrackSelectorTool::finalize() +{ + ATH_MSG_INFO("Finalize successful"); + return StatusCode::SUCCESS; +} + +//_______________________________________________________________________________ +bool InDet::InDetIsoTrackSelectorTool::decision(const Trk::AtaStraightLine& atl, const Trk::Track& track) const +{ + const Trk::Perigee* tPerigee = track.perigeeParameters(); + if (!tPerigee){ + ATH_MSG_DEBUG("No perigee on track, discard this one."); + return false; + } + // call the workhorse interface + bool passed = decision(atl,*tPerigee); + // only check if needed + passed = (!passed || m_trackSelector.empty()) ? passed : ( passed && m_trackSelector->decision(track) ); + // return what you have + ATH_MSG_VERBOSE("Track " << ( passed ? "passed" : "did not pass") << " isolation track selector."); + return passed; +} + + +//_______________________________________________________________________________ +bool InDet::InDetIsoTrackSelectorTool::decision(const Trk::AtaStraightLine& atl, const Trk::TrackParticleBase& trackParticle) const +{ + + // get the paramters base + const Trk::TrackParameters* definintParameters = &(trackParticle.definingParameters()); + const Trk::TrackParameters* trackParameters= + dynamic_cast<const Trk::Perigee*>(definintParameters); + if (!trackParameters){ + ATH_MSG_DEBUG("No parameters to start from on track, discard this one."); + return false; + } + // call the workhorse interface + bool passed = decision(atl,*trackParameters); + // only check if needed + passed = (!passed || m_trackSelector.empty()) ? passed : ( passed && m_trackSelector->decision(trackParticle) ); + // return what you have + ATH_MSG_VERBOSE("TrackParticle " << ( passed ? "passed" : "did not pass") << " isolation track selector."); + return passed; +} + +//_______________________________________________________________________________ +bool InDet::InDetIsoTrackSelectorTool::decision(const Trk::AtaStraightLine& atl, const Trk::TrackParameters& trackPars) const +{ + // get the surface + bool passed = false; + const Trk::StraightLineSurface& alSurface = atl.associatedSurface(); + // no surface: bail out + // get the track to the BeamLine Parameters ( given by AtaStrainghtLine) + const Trk::TrackParameters* trackAtBL = m_extrapolator->extrapolate(trackPars, + alSurface, + Trk::anyDirection, + false); + // no parameterisation : bail out + if (!trackAtBL) return false; + // d0,z0 wrt BL for reference and track + double d0track_wrtBL = trackAtBL->parameters()[Trk::d0]; + double sinTheta = m_applySinThetaCorrection ? 1. : sin(trackAtBL->parameters()[Trk::theta]); + double z0track_wrtBL = trackAtBL->parameters()[Trk::z0]*sinTheta; + double sinThetaRef = m_applySinThetaCorrection ? 1. : sin(atl.parameters()[Trk::theta]); + double z0ref_wrtBL = atl.parameters()[Trk::z0] * sinThetaRef; + if (m_robustCuts){ + // check d0 cut with respect to BL + passed = (d0track_wrtBL*d0track_wrtBL < m_d0max*m_d0max); + ATH_MSG_VERBOSE("TrackParameters " << ( passed ? "passed" : "did not pass" ) << " d0 cut wrt BL : " + << d0track_wrtBL << " (cut is : | " << m_d0max << " | )."); + // check z0 cut with respect to reference + passed = ( (z0track_wrtBL-z0ref_wrtBL)*(z0track_wrtBL-z0ref_wrtBL) < m_z0stMax*m_z0stMax ); + ATH_MSG_VERBOSE("TrackParameters " << ( passed ? "passed" : "did not pass" ) << " z0 " << ( m_applySinThetaCorrection ? "*sin(theta)" : "") + << " cut wrt reference :" + << (z0track_wrtBL-z0ref_wrtBL) << " (cut is : | " << m_z0stMax << " | )."); + } else { + // cast to measured parameters + if (!trackAtBL->covariance()){ + ATH_MSG_VERBOSE("Can not apply signficance cut on Parameters w/o Error. Ignore Track."); + return false; + } + // get the error on the track + double covTrackD0 = (*trackAtBL->covariance())(Trk::d0,Trk::d0); + double covTrackZ0 = (*trackAtBL->covariance())(Trk::z0,Trk::z0); + // check d0 signficiance cut with respect to BL + passed = (d0track_wrtBL*d0track_wrtBL)/(covTrackD0) < m_d0Significance*m_d0Significance; + ATH_MSG_VERBOSE("TrackParameters " << ( passed ? "passed" : "did not pass" ) << " d0 signficance cut wrt BL : " + << (d0track_wrtBL*d0track_wrtBL)/(covTrackD0) << " (cut is : | " << m_d0Significance << " | )."); + double deltaZ = z0ref_wrtBL - z0track_wrtBL; + if (m_applySinThetaCorrection){ + double covTrackTheta = (*trackAtBL->covariance())(Trk::theta,Trk::theta); + double covTrackZ0Theta = (*trackAtBL->covariance())(Trk::z0,Trk::theta); + // check z0 signficance cut with respect to reference -- apply theta projection into longitudinal track frame + double cosTheta = cos(trackAtBL->parameters()[Trk::theta]); + // derivatives + apply jacobian transormation + double dZIPdTheta = deltaZ*cosTheta; + double dZIPdz0 = sinTheta; + double DTheta2 = dZIPdTheta*dZIPdTheta*covTrackTheta; + double DZ02 = dZIPdz0*dZIPdz0*covTrackZ0; + double DThetaZ0 = 2.*dZIPdTheta*dZIPdz0*covTrackZ0Theta; + // check for it + double newZ0Err = DTheta2 + DZ02 + DThetaZ0; + passed = (deltaZ*deltaZ)/(newZ0Err) < m_z0Significance*m_z0Significance; + ATH_MSG_VERBOSE("TrackParameters " << ( passed ? "passed" : "did not pass" ) << " z0*sin(theta) signficance cut wrt BL : " + << (deltaZ*deltaZ)/(newZ0Err) << " (cut is : | " << m_z0Significance << " | )."); + + } else { + // check z0 signficiance cut with respect to BL + passed = (deltaZ*deltaZ)/(covTrackZ0) < m_z0Significance*m_z0Significance; + ATH_MSG_VERBOSE("TrackParameters " << ( passed ? "passed" : "did not pass" ) << " z0 signficance cut wrt BL : " + << (deltaZ*deltaZ)/(covTrackZ0) << " (cut is : | " << m_z0Significance << " | )."); + + } + } + // memory cleanup + delete trackAtBL; + return passed; +} + diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetTrackSelectorTool.cxx b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetTrackSelectorTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e4811046328989364916b77a3e4d25742f0b27b9 --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetTrackSelectorTool.cxx @@ -0,0 +1,195 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetTrackSelectorTool/InDetTrackSelectorTool.h" +// forward declares +#include "TrkToolInterfaces/ITrackSummaryTool.h" +#include "TrkExInterfaces/IExtrapolator.h" +#include "VxVertex/Vertex.h" +#include "TrkParticleBase/TrackParticleBase.h" +#include "TrkTrack/Track.h" +// normal includes +#include "TrkTrackSummary/TrackSummary.h" +#include "CLHEP/Matrix/Vector.h" + +using CLHEP::mm; + +namespace InDet +{ + +//_______________________________________________________________________________ +InDetTrackSelectorTool::InDetTrackSelectorTool(const std::string & t, const std::string & n, const IInterface * p) + : AthAlgTool(t,n,p) + , m_minPt(500.) + , m_IPz0Max(10.*mm) + , m_maxZ0(99999.) + , m_maxD0(2.*mm) + , m_maxD0overSigmaD0(3.) + , m_numberOfPixelHits(2) + , m_numberOfBLayerHits(1) + , m_extrapolator("Trk::Extrapolator") +{ + declareInterface<ITrackSelectorTool>(this); + declareProperty("minPt", m_minPt); + declareProperty("IPz0Max", m_IPz0Max); // cut on |z|*sin(theta) + declareProperty("maxZ0", m_maxZ0); + declareProperty("maxD0", m_maxD0); + declareProperty("maxD0overSigmaD0", m_maxD0overSigmaD0); + declareProperty("numberOfPixelHits", m_numberOfPixelHits); + declareProperty("numberOfBLayerHits", m_numberOfBLayerHits); + declareProperty("TrackSummaryTool", m_trackSumTool); + declareProperty("Extrapolator", m_extrapolator); +} + +//_______________________________________________________________________________ +InDetTrackSelectorTool::~InDetTrackSelectorTool() +{} + +//_______________________________________________________________________________ +StatusCode InDetTrackSelectorTool::initialize() +{ + StatusCode sc = AthAlgTool::initialize(); + if(sc.isFailure()) { + msg(MSG::ERROR)<<" Unable to initialize the AlgTool"<<endreq; + return StatusCode::FAILURE; + } + + m_trackSumToolAvailable = false; + if (!m_trackSumTool.empty()) + { + if(m_trackSumTool.retrieve().isFailure()) { + msg(MSG::ERROR)<<" Unable to retrieve "<<m_trackSumTool<<endreq; + return StatusCode::FAILURE; + } + else { + ATH_MSG_INFO("Track summary tool retrieved"); + m_trackSumToolAvailable = true; + } + } + + if ( m_extrapolator.retrieve().isFailure() ) { + msg(MSG::ERROR) << "Failed to retrieve tool " << m_extrapolator << endreq; + return StatusCode::FAILURE; + } + ATH_MSG_INFO("Retrieved tool " << m_extrapolator); + + return StatusCode::SUCCESS; +} + +//_______________________________________________________________________________ +StatusCode InDetTrackSelectorTool::finalize() +{ + ATH_MSG_INFO("Finalize successful"); + return StatusCode::SUCCESS; +} + +//_______________________________________________________________________________ +bool InDetTrackSelectorTool::decision(const Trk::Track & track, const Trk::Vertex * vertex) const +{ + // decision based on the track parameters + if(!decision(track.perigeeParameters(), vertex, track.info().particleHypothesis())) + return false; + + // number of hits, silicon hits, b-layer + // first ask track for summary + const Trk::TrackSummary * summary = track.trackSummary(); + if (summary == 0 && m_trackSumToolAvailable) { + // ugly but one needs to cast the const away because the method needs to update the track (the tool is a friend of track) + Trk::Track & nonConstTrack = const_cast<Trk::Track &>(track); + m_trackSumTool->updateTrack(nonConstTrack); + // now get it from the track (the track has OWNERSHIP) + summary = nonConstTrack.trackSummary(); + } + + if (0==summary) { + ATH_MSG_DEBUG( "Track preselection: cannot create a track summary. This track will not pass." ); + return false; + } + + int nPixelHits = summary->get(Trk::numberOfPixelHits); + int nPixelDead = summary->get(Trk::numberOfPixelDeadSensors); + if (nPixelDead<0) + nPixelDead=0; + + int nBLayerHits = summary->get(Trk::numberOfBLayerHits); + + if(nPixelHits+nPixelDead<m_numberOfPixelHits || nBLayerHits<m_numberOfBLayerHits ) + return false; + + // all ok + return true; +} + +//_______________________________________________________________________________ +bool InDetTrackSelectorTool::decision(const Trk::TrackParticleBase & track, const Trk::Vertex * vertex) const +{ + if(!decision(&(track.definingParameters()), vertex, Trk::pion)) + return false; + + const Trk::TrackSummary * summary = track.trackSummary(); + if (summary == 0) { + ATH_MSG_INFO( "TrackParticleBase does not have a Track Summary. Rejected." ); + return false; + } + int nPixelHits = summary->get(Trk::numberOfPixelHits); + int nPixelDead = summary->get(Trk::numberOfPixelDeadSensors); + if (nPixelDead<0) + nPixelDead=0; + + int nBLayerHits = summary->get(Trk::numberOfBLayerHits); + + if(nPixelHits+nPixelDead<m_numberOfPixelHits || nBLayerHits<m_numberOfBLayerHits ) + return false; + return true; +} + +//_______________________________________________________________________________ +bool InDetTrackSelectorTool::decision(const Trk::TrackParameters * track, const Trk::Vertex * vertex, const Trk::ParticleHypothesis hyp) const +{ + // checking pointer first + if(0==track || !track->covariance()) { + ATH_MSG_WARNING( "Track preselection: Zero pointer to parameterbase* received (most likely a track without perigee). This track will not pass." ); + return false; + } + + // getting the perigee parameters of the track + const Trk::Perigee * perigee(0); + if(vertex == 0) + perigee = dynamic_cast<const Trk::Perigee *>(track); + else { + Trk::PerigeeSurface perigeeSurface(vertex->position()); + perigee = dynamic_cast<const Trk::Perigee *>(m_extrapolator->extrapolate(*track,perigeeSurface,Trk::anyDirection,true,hyp)); + } + + if(0 == perigee || !perigee->covariance() ) { + ATH_MSG_INFO( "Track preselection: cannot make a measured perigee. This track will not pass." ); + return false; + } + + AmgVector(5) trackParameters = perigee->parameters(); + + // d0 and z0 cuts + double d0 = trackParameters[Trk::d0]; + if(fabs(d0) > m_maxD0) { if(vertex != 0) { delete perigee; } return false; } + + double z0 = trackParameters[Trk::z0]; + if (fabs(z0)*sin(trackParameters[Trk::theta]) > m_IPz0Max) + { if(vertex != 0) { delete perigee; } return false; } + if (fabs(z0) > m_maxZ0) + { if(vertex != 0) { delete perigee; } return false; } + + // transverse momentum + double pt = perigee->momentum().perp(); + if(pt<m_minPt) { if(vertex != 0) { delete perigee; } return false; } + + // d0 significance + double d0Significance=fabs(trackParameters[Trk::d0]/sqrt( (*perigee->covariance())(Trk::d0,Trk::d0) )); + if (d0Significance>m_maxD0overSigmaD0) + { if(vertex != 0) { delete perigee; } return false; } + + if(vertex != 0) { delete perigee; } + return true; +} //end of selection method + +} //end of namespace definitions diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetTrtDriftCircleCutTool.cxx b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetTrtDriftCircleCutTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..87cb4913023e10b7bf1539fb4ad44094c8fd56be --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetTrtDriftCircleCutTool.cxx @@ -0,0 +1,90 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "InDetTrackSelectorTool/InDetTrtDriftCircleCutTool.h" +#include "TRT_ConditionsServices/ITRT_ActiveFractionSvc.h" + +StatusCode InDet::InDetTrtDriftCircleCutTool::initialize() +{ + StatusCode sc = AthAlgTool::initialize(); + + /* Get the trt active fraction tool */ + if(m_useTRT){ + if ( m_trtCondSvc.retrieve().isFailure() ) { + msg(MSG::ERROR) << "Failed to retrieve tool " << m_trtCondSvc << endreq; + return StatusCode::FAILURE; + } else { + msg(MSG::INFO) << "Retrieved tool " << m_trtCondSvc << endreq; + } + } + + if(sc.isFailure()){ + msg(MSG::ERROR)<<" Unable to initialize the AlgTool"<<endreq; + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + +StatusCode InDet::InDetTrtDriftCircleCutTool::finalize() +{ + msg(MSG::INFO) << "Finalize successful" << endreq; + return StatusCode::SUCCESS; +} + +InDet::InDetTrtDriftCircleCutTool::InDetTrtDriftCircleCutTool(const std::string& t, const std::string& n, const IInterface* p) + :AthAlgTool(t,n,p), + m_trtCondSvc("TRT_ActiveFractionSvc",n), + m_minOffset(0), + m_param(false), + m_useTRT(true) +{ + declareInterface<ITrtDriftCircleCutTool>(this); + declareProperty("TrtConditionsSvc", m_trtCondSvc); + declareProperty("MinOffsetDCs", m_minOffset ); + declareProperty("UseNewParameterization", m_param ); + declareProperty("UseActiveFractionSvc", m_useTRT ); +} + +InDet::InDetTrtDriftCircleCutTool::~InDetTrtDriftCircleCutTool() +{} + +int InDet::InDetTrtDriftCircleCutTool::minNumberDCs(const Trk::TrackParameters* trkp) const { + if(!m_param){ + const double TrtEtaBin[6] = {0., 0.65, 0.85, 1.25, 1.80, 2.10}; + const double TrtA [5] = { 29., 31., 20., 36., 34. }; + const double TrtB [5] = { 2./0.65, -11./0.20, 16./0.40, -2./0.55, -24./0.3}; + + double eta= fabs(trkp->momentum().eta()); + + for(int i=0; i!=5; ++i) { + if(eta <= TrtEtaBin[i+1]) { + return int(TrtA[i]+TrtB[i]*(eta-TrtEtaBin[i])-m_minOffset); + } + } + return int(m_minOffset); + } else { + const double TrtEtaBin[7] = {0., 0.1, 0.6255, 1.07, 1.304, 1.752, 2.0 }; + const double TrtA [6] = { 33.28, 30.40, 182.38, -226.18, -351.56, -250.2 }; + const double TrtB [6] = { -79.4, 18.79, -371.9, 495.12, 777.5, 377.9 }; + const double TrtC [6] = { 589.7, -42.73, 213.3, -314.96 , -512.3, -128.7 }; + const double TrtD [6] = { 0., 32.53, 0. , 69.42 , 111.0, 3.4 }; + const double TrtO [6] = { 9., 11., 10., 7., 9., 12. }; + + double eta = fabs(trkp->momentum().eta()); + + for(int i=0; i!=6; ++i) { + if(eta <= TrtEtaBin[i+1]) { + double diff = eta; + double nDiffTRT = TrtA[i]+TrtB[i]*diff+TrtC[i]*diff*diff+TrtD[i]*diff*diff*diff-TrtO[i]; + double activeF = 1.; + if(m_useTRT) activeF = m_trtCondSvc->getActiveFraction(trkp); + nDiffTRT = nDiffTRT*activeF; + if (nDiffTRT>=1) return int(nDiffTRT); + else return int(m_minOffset); + } + } + return int(m_minOffset); + } +} diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/components/InDetTrackSelectorTool_entries.cxx b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/components/InDetTrackSelectorTool_entries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f48544f66c1e303a8fa67e5a61c579e9f3ffe385 --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/components/InDetTrackSelectorTool_entries.cxx @@ -0,0 +1,26 @@ +#include "GaudiKernel/DeclareFactoryEntries.h" +#include "InDetTrackSelectorTool/InDetTrackSelectorTool.h" +#include "InDetTrackSelectorTool/InDetIsoTrackSelectorTool.h" +#include "InDetTrackSelectorTool/InDetCosmicTrackSelectorTool.h" +#include "InDetTrackSelectorTool/InDetDetailedTrackSelectorTool.h" +#include "InDetTrackSelectorTool/InDetConversionTrackSelectorTool.h" +#include "InDetTrackSelectorTool/InDetTrtDriftCircleCutTool.h" + +using namespace InDet; + +DECLARE_TOOL_FACTORY( InDetTrackSelectorTool ) +DECLARE_TOOL_FACTORY( InDetIsoTrackSelectorTool ) +DECLARE_TOOL_FACTORY( InDetCosmicTrackSelectorTool ) +DECLARE_TOOL_FACTORY( InDetDetailedTrackSelectorTool ) +DECLARE_TOOL_FACTORY( InDetConversionTrackSelectorTool ) +DECLARE_TOOL_FACTORY( InDetTrtDriftCircleCutTool ) + +DECLARE_FACTORY_ENTRIES( InDetTrackSelectorTool ) +{ + DECLARE_TOOL( InDetTrackSelectorTool ); + DECLARE_TOOL( InDetIsoTrackSelectorTool ); + DECLARE_TOOL( InDetCosmicTrackSelectorTool ); + DECLARE_TOOL( InDetDetailedTrackSelectorTool ); + DECLARE_TOOL( InDetConversionTrackSelectorTool ); + DECLARE_TOOL( InDetTrtDriftCircleCutTool ); +} diff --git a/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/components/InDetTrackSelectorTool_load.cxx b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/components/InDetTrackSelectorTool_load.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4877876e80610c106b60ec1d33422248c96f79c0 --- /dev/null +++ b/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/components/InDetTrackSelectorTool_load.cxx @@ -0,0 +1,3 @@ +#include "GaudiKernel/LoadFactoryEntries.h" + +LOAD_FACTORY_ENTRIES( InDetTrackSelectorTool )