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 )