ATLAS Offline Software
InDetTrackSelectionTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "AsgMessaging/Check.h"
9 #include "InDetAccessor.h"
10 
11 #ifndef XAOD_ANALYSIS
13 #include "TrkTrack/Track.h"
14 #include "VxVertex/Vertex.h"
17 #endif
18 
19 #include <memory>
20 #include <array>
21 
22 using namespace InDetAccessor;
23 
24 namespace {
25  template <unsigned int n_summary_types>
26  std::array<xAOD::SummaryType, n_summary_types> summaryArray( std::array<xAOD::SummaryType, n_summary_types> summary_types) {return summary_types; }
27 
28  template <class Trk_Helper, unsigned int n_summary_types>
29  class MinTRTHitsCut {
30  public:
31  MinTRTHitsCut( double maxTrtEtaAcceptance,
32  double maxEtaForTrtHitCuts,
33  int min_n_hits,
34  std::array<xAOD::SummaryType, n_summary_types> summary_types)
35  : m_maxTrtEtaAcceptance(maxTrtEtaAcceptance),
36  m_maxEtaForTrtHitCuts(maxEtaForTrtHitCuts),
37  m_minNHits(min_n_hits),
38  m_summaryTypes(summary_types)
39  {}
40 
41  uint8_t nHits(Trk_Helper helper, const asg::AsgMessaging &msgHelper) const {
42  return getSummarySum(helper,msgHelper,m_summaryTypes);
43  }
44  bool operator()(Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
45  double absEta = std::abs( helper.eta( msgHelper) );
46  return (absEta <= m_maxTrtEtaAcceptance || absEta > m_maxEtaForTrtHitCuts) || nHits(helper,msgHelper) >=m_minNHits;
47  }
48  private:
49  double m_maxTrtEtaAcceptance;
50  double m_maxEtaForTrtHitCuts;
51  int m_minNHits;
52  std::array<xAOD::SummaryType, n_summary_types> m_summaryTypes;
53  };
54 
55  // return the first bin whose value is lower or equal than the given value
56  // the bins have to be in ascending order;
57  template <typename T>
58  unsigned int findBin(const std::vector<T> &bins, T value) {
59  if (bins.empty() || bins[0]>value) return bins.size();
60  unsigned int bin_i=bins.size();
61  while ( value < bins[--bin_i]) {};
62  return bin_i;
63  }
64  // return true if the given bins are in ascending order
65  template <typename T>
66  bool checkOrder(const std::vector<T> &bins) {
67  if (bins.empty()) return true;
68  for (unsigned int bin_i=1; bin_i<bins.size(); ++bin_i) {
69  if (bins[bin_i-1]>=bins[bin_i]) return false;
70  }
71  return true;
72  }
73 }
74 
75 InDet::InDetTrackSelectionTool::InDetTrackSelectionTool(const std::string& name)
76  : asg::AsgTool(name)
77  , m_acceptInfo( "InDetTrackSelection" )
78 #ifndef XAOD_ANALYSIS
79 #endif // XAOD_ANALYSIS
80 {
81 
82  // set the cut selection: default is "no cut"
83  setCutLevelPrivate(InDet::CutLevel::NoCut);
84 
85 #ifndef XAOD_STANDALONE
86  declareInterface<IInDetTrackSelectionTool>(this);
87 #endif
88 
89 }
90 
91 // we must define the destructor in order to use forward-declaration with unique_ptr
92 InDet::InDetTrackSelectionTool::~InDetTrackSelectionTool() = default;
93 
104  // Make sure we haven't already been initialized - this would be a sign of improper usage.
105  if (m_isInitialized) {
106  ATH_MSG_ERROR( "Tool has already been initialized. This is illegitimate." );
107  ATH_MSG_ERROR( "This call to initialize() will do nothing." );
108  return StatusCode::SUCCESS;
109  }
110 
111  // Greet the user:
113 
114  // if the CutLevel string is set to something recognizable,
115  // then do a soft set on the cuts (i.e. not overwriting those already set)
116  if (!m_cutLevel.empty()) {
117  std::unordered_map<std::string, InDet::CutLevel>::const_iterator it_mapCutLevel = s_mapCutLevel.find(m_cutLevel);
118  if ( it_mapCutLevel == s_mapCutLevel.end() ) {
119  ATH_MSG_ERROR( "The string \"" << m_cutLevel << "\" is not recognized as a cut level. No cuts will be changed." );
120  ATH_MSG_ERROR( "Cut level options are:" );
121  for (const auto& opt : s_mapCutLevel) {
122  ATH_MSG_ERROR( "\t" << opt.first );
123  }
124  } else {
125  ATH_MSG_DEBUG( "Cut level set to \"" << it_mapCutLevel->first << "\"." );
126  ATH_MSG_DEBUG( "This will not overwrite other cuts that have been set.");
127  setCutLevelPrivate( it_mapCutLevel->second, false );
128  }
129  }
130 
131 #ifndef XAOD_ANALYSIS
132  if (m_initTrkTools) {
133  m_trackSumToolAvailable = false;
134  if (!m_trackSumTool.empty()) {
135  ATH_CHECK( m_trackSumTool.retrieve() );
136  ATH_MSG_DEBUG( "Track summary tool retrieved." );
137  m_trackSumToolAvailable = true;
138  }
139  ATH_CHECK( m_extrapolator.retrieve() );
140  ATH_MSG_DEBUG( "Retrieved tool " << m_extrapolator );
141  } else {
142  m_extrapolator.disable();
143  m_trackSumTool.disable();
144  }
145 #endif // XAOD_ANALYSIS
146 
147  // Need messaging helper for cut functions
148  m_msgHelper = std::make_unique<asg::AsgMessaging>(this) ;
149 
150 
151 #ifndef XAOD_ANALYSIS
152  // setup cut functions for Trk::Tracks
153  ATH_CHECK( setupCuts<0>(m_trkTrackCuts) );
154  ATH_CHECK( setupCuts<0>(m_trackParticleCuts) );
155 #else
156  ATH_CHECK( setupCuts<1>(m_trackParticleCuts) );
157 #endif
158  // setup cut functions for xAOD::TrackParticles
159  for (const auto& cutFamily : m_trackParticleCuts) {
160  const std::string& cutFamilyName = cutFamily.first;
161  // lock(m_mutex) is not needed because this is inside of non-const initialize method.
162  m_numTracksPassedCuts.push_back(0);
163  if (m_acceptInfo.addCut( cutFamilyName, "Selection of tracks according to " + cutFamilyName ) < 0) {
164  ATH_MSG_ERROR( "Failed to add cut family " << cutFamilyName << " because the TAccept object is full." );
165  return StatusCode::FAILURE;
166  }
167  ATH_MSG_VERBOSE("Adding cut family " << cutFamilyName);
168  }
169 
170  m_isInitialized = true;
171 
172  return StatusCode::SUCCESS;
173 }
174 
175 namespace {
176  template <typename T>
177  inline T sqr(T a) { return a *a;}
178 }
179 template <int VERBOSE, class Trk_Helper>
180 StatusCode InDet::InDetTrackSelectionTool::setupCuts(std::map< std::string, std::vector< std::function<bool(Trk_Helper helper, const asg::AsgMessaging &msgHelper)> > > &trackCuts) {
181  // track parameter cuts
182  if (m_minPt > 0.) {
183  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum Pt: " << m_minPt << " MeV" );
184  trackCuts["Pt"].push_back( [minPt = m_minPt](Trk_Helper helper, const asg::AsgMessaging &msgHelper) -> bool { return helper.pt(msgHelper) >= minPt; } );
185  }
186  if (maxDoubleIsSet(m_maxAbsEta)) {
187  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum |Eta|: " << m_maxAbsEta );
188  trackCuts["Eta"].push_back( [maxAbsEta = m_maxAbsEta](Trk_Helper helper, const asg::AsgMessaging &msgHelper) { return std::abs(helper.eta(msgHelper)) <= maxAbsEta; } );
189  }
190  if (m_minP > 0.) {
191  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum P: " << m_minP << " MeV" );
192  trackCuts["P"].push_back( [maxInvP = 1./m_minP](Trk_Helper helper, const asg::AsgMessaging &msgHelper) { return std::abs(helper.qOverP(msgHelper)) <= maxInvP; } );
193  }
194  if (maxDoubleIsSet(m_maxD0)) {
195  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum d0: " << m_maxD0 << " mm" );
196  trackCuts["D0"].push_back( [maxD0 = m_maxD0](Trk_Helper helper, const asg::AsgMessaging &msgHelper) { return std::abs(helper.d0(msgHelper)) <= maxD0; } );
197  }
198  if (maxDoubleIsSet(m_maxZ0)) {
199  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum z0: " << m_maxZ0 << " mm");
200  trackCuts["Z0"].push_back( [maxZ0 = m_maxZ0](Trk_Helper helper, const asg::AsgMessaging &msgHelper) { return std::abs(helper.z0(msgHelper)) <= maxZ0; } );
201  }
202  if (maxDoubleIsSet(m_maxZ0SinTheta)) {
203  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum z0*sin(theta): " << m_maxZ0SinTheta << " mm" );
204  trackCuts["Z0SinTheta"].push_back([maxZ0SinTheta = m_maxZ0SinTheta](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
205  return std::abs( helper.z0(msgHelper) * std::sin(helper.theta(msgHelper))) <= maxZ0SinTheta;
206  });
207  }
208  if (maxDoubleIsSet(m_maxSigmaD0)) {
209  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum uncertainty on d0: " << m_maxSigmaD0 << " mm" );
210  trackCuts["D0"].push_back([maxSigmaD0Squared = sqr(m_maxSigmaD0.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
211  return getDefiningParametersCov(helper,msgHelper, InDetAccessor::d0,InDetAccessor::d0) <= maxSigmaD0Squared;
212  });
213  }
214  if (maxDoubleIsSet(m_maxSigmaZ0)) {
215  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum uncertainty on z0: " << m_maxSigmaZ0 << " mm" );
216  trackCuts["Z0"].push_back([maxSigmaZ0Squared = sqr(m_maxSigmaZ0.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
217  return getDefiningParametersCov(helper,msgHelper, InDetAccessor::z0,InDetAccessor::z0) <= maxSigmaZ0Squared;
218  });
219  }
220  if (maxDoubleIsSet(m_maxSigmaZ0SinTheta)) {
221  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum uncertainty on z0*sin(theta): "
222  << m_maxSigmaZ0SinTheta << " mm" );
223  trackCuts["Z0SinTheta"].push_back([maxSigmaZ0SinThetaSquared = sqr(m_maxSigmaZ0SinTheta.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
224  double theta = helper.theta(msgHelper);
225  double sinTheta = std::sin(theta);
226  double cosTheta = std::cos(theta);
227  double z0 = helper.z0(msgHelper);
228 
229  return ( sqr(z0)*sqr(cosTheta) * getDefiningParametersCov(helper,msgHelper, InDetAccessor::theta,InDetAccessor::theta)
230  + 2*z0 *sinTheta*cosTheta * getDefiningParametersCov(helper,msgHelper, InDetAccessor::theta,InDetAccessor::z0)
231  + sqr(sinTheta) * getDefiningParametersCov(helper,msgHelper, InDetAccessor::z0, InDetAccessor::z0) ) <= maxSigmaZ0SinThetaSquared;
232  });
233  }
234  if (maxDoubleIsSet(m_maxD0overSigmaD0)) {
235  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum significance on d0: " << m_maxD0overSigmaD0 );
236  trackCuts["D0"].push_back([maxD0overSigmaD0Squared = sqr(m_maxD0overSigmaD0.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
237  return sqr(helper.d0(msgHelper)) <= maxD0overSigmaD0Squared * getDefiningParametersCov(helper,msgHelper, InDetAccessor::d0,InDetAccessor::d0);
238  });
239  }
240  if (maxDoubleIsSet(m_maxZ0overSigmaZ0)) {
241  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum significance on z0: " << m_maxZ0overSigmaZ0 );
242  trackCuts["Z0"].push_back([maxZ0overSigmaZ0Squared = sqr(m_maxZ0overSigmaZ0.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) -> bool {
243  return sqr(helper.z0(msgHelper)) <= maxZ0overSigmaZ0Squared * getDefiningParametersCov(helper,msgHelper, InDetAccessor::z0,InDetAccessor::z0);
244  });
245  }
246  if (maxDoubleIsSet(m_maxZ0SinThetaoverSigmaZ0SinTheta)) {
247  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum significance on z0*sin(theta): "
248  << m_maxZ0SinThetaoverSigmaZ0SinTheta );
249  trackCuts["Z0SinTheta"].push_back([maxZ0SinThetaoverSigmaZ0SinThetaSquared = sqr(m_maxZ0SinThetaoverSigmaZ0SinTheta.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
250 
251  double theta = helper.theta(msgHelper);
252  double sinTheta = std::sin(theta);
253  double cosTheta = std::cos(theta);
254  double z0 = helper.z0(msgHelper);
255 
256  return sqr(z0*sinTheta) <=
257  maxZ0SinThetaoverSigmaZ0SinThetaSquared * ( sqr(z0)*sqr(cosTheta) * getDefiningParametersCov(helper,msgHelper, InDetAccessor::theta,InDetAccessor::theta)
258  + 2*z0 *sinTheta*cosTheta * getDefiningParametersCov(helper,msgHelper, InDetAccessor::theta,InDetAccessor::z0)
259  + sqr(sinTheta) * getDefiningParametersCov(helper,msgHelper, InDetAccessor::z0, InDetAccessor::z0));
260  });
261  }
262 
263  // hit cuts
264  if (m_minNInnermostLayerHits > 0) {
265  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum hits from innermost pixel layer: " << m_minNInnermostLayerHits );
266  if constexpr(VERBOSE>0) ATH_MSG_INFO( " (Track will pass if no hit is expected.)" );
267  trackCuts["InnermostLayersHits"].push_back([minNInnermostLayerHits = m_minNInnermostLayerHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
268  return ( getSummary(helper, msgHelper, xAOD::numberOfInnermostPixelLayerHits) >= minNInnermostLayerHits
270  });
271  }
272  if (m_minNNextToInnermostLayerHits > 0) {
273  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum hits from next to innermost pixel layer: " << m_minNNextToInnermostLayerHits );
274  if constexpr(VERBOSE>0) ATH_MSG_INFO( " (Track will pass if no hit is expected.)" );
275  trackCuts["InnermostLayersHits"].push_back([minNNextToInnermostLayerHits = m_minNNextToInnermostLayerHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
276  return ( getSummary(helper, msgHelper, xAOD::numberOfNextToInnermostPixelLayerHits) >= minNNextToInnermostLayerHits
278  });
279  }
280  if (m_minNBothInnermostLayersHits > 0) {
281  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum hits from both innermost pixel layers: " << m_minNBothInnermostLayersHits );
282  if constexpr(VERBOSE>0) ATH_MSG_INFO( " (If a layer has no hits but one is not expected, the" );
283  if constexpr(VERBOSE>0) ATH_MSG_INFO( " number of hits in that layer will be taken to be 1.)" );
284  if (m_minNBothInnermostLayersHits > 2) {
285  ATH_MSG_WARNING( "A value of minNBothInnermostLayersHits above 2 does not make sense." );
286  ATH_MSG_WARNING( " Use 1 for \"or\" or 2 for \"and\"." );
287  }
288  trackCuts["InnermostLayersHits"].push_back([minNBothInnermostLayersHits = m_minNBothInnermostLayersHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
290  static_cast<uint8_t>( !getSummary(helper, msgHelper, xAOD::expectInnermostPixelLayerHit) ))
293  >= minNBothInnermostLayersHits);
294  });
295  }
296  if (m_useMinBiasInnermostLayersCut > 0 ) { // less than zero indicates this cut is manually turned off
297  if constexpr(VERBOSE>0) ATH_MSG_INFO( " An innermost layer hit is required if expected, otherwise" );
298  if constexpr(VERBOSE>0) ATH_MSG_INFO( " a next-to-innermost layer hit is required if it is expected." );
299  trackCuts["InnermostLayersHits"].push_back([](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
300  uint8_t expected_innermost_pixel_layer_hit = getSummary(helper, msgHelper, xAOD::expectInnermostPixelLayerHit);
301  return (expected_innermost_pixel_layer_hit > 0 && getSummary(helper, msgHelper, xAOD::numberOfInnermostPixelLayerHits)>=1)
302  || (expected_innermost_pixel_layer_hit == 0 && ( getSummary(helper, msgHelper, xAOD::expectNextToInnermostPixelLayerHit)==0
304  });
305  }
306  if (maxIntIsSet(m_maxNInnermostLayerSharedHits)) {
307  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum shared hits in innermost pixel layer: " << m_maxNInnermostLayerSharedHits );
308  trackCuts["InnermostLayersHits"].push_back([maxNInnermostLayerSharedHits = m_maxNInnermostLayerSharedHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
309  return getSummary(helper, msgHelper, xAOD::numberOfInnermostPixelLayerSharedHits) <= maxNInnermostLayerSharedHits;
310  });
311  }
312  if (m_minNPixelHits > 0) {
313  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum pixel hits: " << m_minNPixelHits );
314  trackCuts["PixelHits"].push_back( [minNPixelHits = m_minNPixelHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
315  return getSummarySum<2,Trk_Helper>(helper, msgHelper, {xAOD::numberOfPixelHits,xAOD::numberOfPixelDeadSensors}) >= minNPixelHits;
316  });
317  }
318  if (m_minNPixelHitsPhysical > 0) {
319  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum physical pixel hits (i.e. dead sensors do not count): "
320  << m_minNPixelHitsPhysical );
321  trackCuts["PixelHits"].push_back([minNPixelHitsPhysical = m_minNPixelHitsPhysical](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
322  return getSummary(helper, msgHelper, xAOD::numberOfPixelHits) >= minNPixelHitsPhysical;
323  });
324  }
325  if (maxIntIsSet(m_maxNPixelHoles)) {
326  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum pixel holes: " << m_maxNPixelHoles );
327  trackCuts["PixelHits"].push_back([maxNPixelHoles = m_maxNPixelHoles](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
328  return getSummary(helper, msgHelper, xAOD::numberOfPixelHoles) <= maxNPixelHoles;
329  });
330  }
331  if (maxIntIsSet(m_maxNPixelSharedHits)) {
332  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum pixel shared hits: " << m_maxNPixelSharedHits );
333  trackCuts["PixelHits"].push_back([maxNPixelSharedHits = m_maxNPixelSharedHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
334  return getSummary(helper, msgHelper, xAOD::numberOfPixelSharedHits) <= maxNPixelSharedHits;
335  });
336  }
337  if (m_minNSctHits > 0) {
338  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum SCT hits: " << m_minNSctHits );
339  trackCuts["SctHits"].push_back( [minNSctHits = m_minNSctHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
340  return getSummarySum<2,Trk_Helper>(helper, msgHelper, {xAOD::numberOfSCTHits, xAOD::numberOfSCTDeadSensors}) >= minNSctHits;
341  });
342  }
343  if (m_minNSctHitsPhysical > 0) {
344  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum physical SCT hits (i.e. dead sensors do not count): "
345  << m_minNSctHitsPhysical );
346  trackCuts["SctHits"].push_back([minNSctHitsPhysical = m_minNSctHitsPhysical](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
347  return getSummary(helper, msgHelper, xAOD::numberOfSCTHits) >= minNSctHitsPhysical;
348  });
349  }
350  if (maxIntIsSet(m_maxNSctHoles)) {
351  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum SCT holes: " << m_maxNSctHoles );
352  trackCuts["SctHits"].push_back([maxNSctHoles = m_maxNSctHoles](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
353  return getSummary(helper, msgHelper, xAOD::numberOfSCTHoles) <= maxNSctHoles;
354  });
355  }
356  if (maxIntIsSet(m_maxNSctSharedHits)) {
357  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum SCT shared hits: " << m_maxNSctSharedHits );
358  trackCuts["SctHits"].push_back([maxNSctSharedHits = m_maxNSctSharedHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
359  return getSummary(helper, msgHelper, xAOD::numberOfSCTSharedHits) <= maxNSctSharedHits;
360  });
361  }
362  if (maxIntIsSet(m_maxNSctDoubleHoles)) {
363  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum SCT double holes: " << m_maxNSctDoubleHoles );
364  trackCuts["SctHits"].push_back([maxNSctDoubleHoles = m_maxNSctDoubleHoles](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
365  return getSummary(helper, msgHelper, xAOD::numberOfSCTDoubleHoles) <= maxNSctDoubleHoles ;
366  });
367  }
368  if (m_minNSiHits > 0) {
369  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum silicon (pixel + SCT) hits: " << m_minNSiHits );
370  trackCuts["SiHits"].push_back([minNSiHits = m_minNSiHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
371  return getSummarySum<4,Trk_Helper>(helper, msgHelper, {xAOD::numberOfPixelHits,
374  xAOD::numberOfSCTDeadSensors} ) >= minNSiHits ;
375  });
376  }
377  if (m_minNSiHitsPhysical > 0) {
378  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum physical silicon hits (i.e. dead sensors do not count): "
379  << m_minNSiHitsPhysical );
380  trackCuts["SiHits"].push_back([minNSiHitsPhysical = m_minNSiHitsPhysical](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
381  return getSummarySum<2,Trk_Helper>(helper, msgHelper,{xAOD::numberOfPixelHits, xAOD::numberOfSCTHits} ) >= minNSiHitsPhysical ;
382  });
383  }
384  if (maxIntIsSet(m_maxNSiHoles)) {
385  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum silicon holes: " << m_maxNSiHoles );
386  trackCuts["SiHits"].push_back([maxNSiHoles = m_maxNSiHoles](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
387  return getSummarySum<2,Trk_Helper>(helper, msgHelper,{xAOD::numberOfPixelHoles, xAOD::numberOfSCTHoles} ) <= maxNSiHoles ;
388  });
389  }
390  if (maxIntIsSet(m_maxNSiSharedHits)) {
391  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum silicon shared hits: " << m_maxNSiSharedHits );
392  trackCuts["SiHits"].push_back([maxNSiSharedHits = m_maxNSiSharedHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
393  return getSummarySum<2,Trk_Helper>(helper, msgHelper,{xAOD::numberOfPixelSharedHits, xAOD::numberOfSCTSharedHits} ) <= maxNSiSharedHits ;
394  });
395  }
396  if (m_maxOneSharedModule) {
397  if constexpr(VERBOSE>0) ATH_MSG_INFO( " No more than one shared module:" );
398  if constexpr(VERBOSE>0) ATH_MSG_INFO( " i.e. max 1 shared pixel hit or" );
399  if constexpr(VERBOSE>0) ATH_MSG_INFO( " 2 shared SCT hits, and not both." );
400  trackCuts["SiHits"].push_back([](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
402  + getSummary(helper, msgHelper,xAOD::numberOfSCTSharedHits )/2 <= 1 ;
403  });
404  }
405  if (m_minNSiHitsIfSiSharedHits > 0) {
406  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum silicon hits if the track has shared hits: "
407  << m_minNSiHitsIfSiSharedHits );
408  trackCuts["SiHits"].push_back([minNSiHitsIfSiSharedHits = m_minNSiHitsIfSiSharedHits](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
409  return getSummarySum<2,Trk_Helper>(helper, msgHelper,{xAOD::numberOfPixelSharedHits, xAOD::numberOfSCTSharedHits} ) == 0
410  || getSummarySum<4,Trk_Helper>(helper, msgHelper,{xAOD::numberOfPixelHits,
413  xAOD::numberOfSCTDeadSensors}) >=minNSiHitsIfSiSharedHits;
414  });
415  }
416  if (maxDoubleIsSet(m_minEtaForStrictNSiHitsCut)
417  && m_minNSiHitsAboveEtaCutoff > 0) {
418  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Require " << m_minNSiHitsAboveEtaCutoff
419  << " silicon hits above eta = " << m_minEtaForStrictNSiHitsCut );
420  trackCuts["SiHits"].push_back([minEtaForStrictNSiHitsCut = m_minEtaForStrictNSiHitsCut,
421  minNSiHitsAboveEtaCutoff = m_minNSiHitsAboveEtaCutoff](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
422  return std::abs(helper.eta(msgHelper)) <= minEtaForStrictNSiHitsCut
423  || getSummarySum<4,Trk_Helper>(helper, msgHelper,{xAOD::numberOfPixelHits,
426  xAOD::numberOfSCTDeadSensors}) >= minNSiHitsAboveEtaCutoff;
427  });
428  }
429  if (m_useExperimentalInnermostLayersCut) {
430  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Zero pixel holes allowed, except one pix hole is allowed if there is a physical IBL hit and a BLayer hit is expected but there is no BLayer hit." );
431  trackCuts["PixHits"].push_back([](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
432  uint8_t pixel_holes = getSummary(helper, msgHelper,xAOD::numberOfPixelHoles);
433  return pixel_holes == 0 || ( pixel_holes<=1 && getSummary(helper, msgHelper,xAOD::numberOfInnermostPixelLayerHits) >= 1
436  });
437  }
438 #ifndef XAOD_ANALYSIS
439  if (m_minNSiHitsMod > 0) {
440  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum modified Si hits (2*pix + sct) (does not include dead sensors)= "
441  << m_minNSiHitsMod );
442  trackCuts["SiHits"].push_back([minNSiHitsMod = m_minNSiHitsMod](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
443  return getSummarySum<3,Trk_Helper>(helper, msgHelper,{xAOD::numberOfPixelHits,
444  xAOD::numberOfPixelHits, // pixel hits count twice in this definition
445  xAOD::numberOfSCTHits}) >= minNSiHitsMod;
446  });
447  }
448  if (m_minNSiHitsModTop > 0 || m_minNSiHitsModBottom > 0) {
449  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum modified Si hits in top half = "
450  << m_minNSiHitsModTop );
451  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum modified Si hits in bottom half = "
452  << m_minNSiHitsModBottom );
453  trackCuts["SiHits"].push_back([minNSiHitsModTop = m_minNSiHitsModTop,
454  minNSiHitsModBottom = m_minNSiHitsModBottom](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
455  auto [top,bottom] = getSiHitsTopBottom(helper, msgHelper);
456  return top >= minNSiHitsModTop && bottom >= minNSiHitsModBottom;
457  });
458  }
459 #endif
460  if (m_maxEtaForTrtHitCuts > 0. && m_maxTrtEtaAcceptance < m_maxEtaForTrtHitCuts) {
461  if constexpr(VERBOSE>0) ATH_MSG_INFO( " -- TRT hit cuts applied above eta = " << m_maxTrtEtaAcceptance
462  << " and below eta = " << m_maxEtaForTrtHitCuts << " --" );
463  if (m_minNTrtHits > 0) {
464  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum TRT hits outside eta acceptance: " << m_minNTrtHits );
465  trackCuts["TrtHits"].push_back( MinTRTHitsCut<Trk_Helper,1>( m_maxTrtEtaAcceptance, m_maxEtaForTrtHitCuts, m_minNTrtHits,
467  }
468  if (m_minNTrtHitsPlusOutliers > 0) {
469  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum TRT hits outside eta acceptance including outliers: " << m_minNTrtHitsPlusOutliers );
470  trackCuts["TrtHits"].push_back( MinTRTHitsCut<Trk_Helper,2>( m_maxTrtEtaAcceptance,m_maxEtaForTrtHitCuts, m_minNTrtHitsPlusOutliers,
472  }
473  if (m_minNTrtHighThresholdHits > 0) {
474  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum TRT hits outside eta acceptance above high energy threshold: "
475  << m_minNTrtHighThresholdHits );
476  trackCuts["TrtHits"].push_back( MinTRTHitsCut<Trk_Helper,1>( m_maxTrtEtaAcceptance,m_maxEtaForTrtHitCuts, m_minNTrtHighThresholdHits,
478  }
479  if (m_minNTrtHighThresholdHitsPlusOutliers > 0) {
480  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum TRT hits outside eta acceptance above high energy threshold including outliers: "
481  << m_minNTrtHighThresholdHitsPlusOutliers );
482  trackCuts["TrtHits"].push_back( MinTRTHitsCut<Trk_Helper,2>( m_maxTrtEtaAcceptance,m_maxEtaForTrtHitCuts, m_minNTrtHighThresholdHitsPlusOutliers,
484  }
485  if (maxDoubleIsSet(m_maxTrtHighEFraction)) { // I think this condition could be instead that it is between 0 and 1
486  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum ratio of high threshold to regular TRT hits outside eta acceptance: "
487  << m_maxTrtHighEFraction);
488  trackCuts["TrtHits"].push_back([maxTrtEtaAcceptance = m_maxTrtEtaAcceptance,
489  maxEtaForTrtHitCuts = m_maxEtaForTrtHitCuts,
490  maxTrtHighEFraction = m_maxTrtHighEFraction](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
491  double absEta = std::abs( helper.eta( msgHelper) );
492  return (absEta <= maxTrtEtaAcceptance || absEta > maxEtaForTrtHitCuts)
494  <= maxTrtHighEFraction * getSummary(helper, msgHelper,xAOD::numberOfTRTHits );
495  });
496  }
497  if (maxDoubleIsSet(m_maxTrtHighEFractionWithOutliers)) {
498  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum ratio of high threshold to regular TRT hits above eta acceptance including outliers: "
499  << m_maxTrtHighEFractionWithOutliers);
500  trackCuts["TrtHits"].push_back([maxTrtEtaAcceptance = m_maxTrtEtaAcceptance,
501  maxEtaForTrtHitCuts = m_maxEtaForTrtHitCuts,
502  maxTrtHighEFractionWithOutliers = m_maxTrtHighEFractionWithOutliers](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
503  double absEta = std::abs( helper.eta( msgHelper) );
504  return (absEta <= maxTrtEtaAcceptance || absEta > maxEtaForTrtHitCuts)
505  || ( getSummarySum<2,Trk_Helper>(helper, msgHelper,{xAOD::numberOfTRTHighThresholdHits, xAOD::numberOfTRTHighThresholdOutliers} ))
506  <= maxTrtHighEFractionWithOutliers * ( getSummarySum<2,Trk_Helper>(helper, msgHelper,{xAOD::numberOfTRTHits, xAOD::numberOfTRTOutliers} ));
507  });
508  }
509  if (m_maxTrtOutlierFraction < 1. && m_maxTrtOutlierFraction >= 0.) {
510  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum fraction of TRT hits that are outliers: " << m_maxTrtOutlierFraction );
511  trackCuts["TrtHits"].push_back([maxTrtEtaAcceptance = m_maxTrtEtaAcceptance,
512  maxEtaForTrtHitCuts = m_maxEtaForTrtHitCuts,
513  maxTrtOutlierFraction = m_maxTrtOutlierFraction](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
514  double absEta = std::abs( helper.eta( msgHelper) );
515  uint8_t trt_outliers = getSummary(helper, msgHelper,xAOD::numberOfTRTOutliers );
516  return ( absEta <= maxTrtEtaAcceptance || absEta > maxEtaForTrtHitCuts)
517  || trt_outliers <= maxTrtOutlierFraction * ( trt_outliers + getSummary(helper, msgHelper,xAOD::numberOfTRTHits) );
518  });
519  }
520  }
521 
522  // fit quality cuts
523  if (m_useEtaDependentMaxChiSq) {
524  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Using pre-defined eta-dependent maximum chi squared (no longer recommended)." );
525  trackCuts["FitQuality"].push_back([](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
526  double eta = helper.eta(msgHelper);
527  double fit_chi_square = getFitChiSquare(helper,msgHelper);
528  double fit_ndof = getFitNDoF(helper,msgHelper);
529  if (std::abs( eta) < 1.9) {
530  return fit_chi_square <= fit_ndof * ( 4.4 + 0.32*sqr(eta) );
531  }
532  else {
533  return fit_chi_square <= fit_ndof * ( 26.9 - 19.6978*std::abs(eta) + 4.4534*sqr(eta) );
534  }
535  });
536  }
537  if (maxDoubleIsSet(m_maxChiSq)) {
538  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum chi squared: " << m_maxChiSq );
539  trackCuts["FitQuality"].push_back([maxChiSq = m_maxChiSq](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
540  return getFitChiSquare(helper,msgHelper) <= maxChiSq;
541  });
542  }
543  if (maxDoubleIsSet(m_maxChiSqperNdf)) {
544  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Maximum chi squared per degree of freedom: " << m_maxChiSqperNdf );
545  trackCuts["FitQuality"].push_back([maxChiSqperNdf = m_maxChiSqperNdf](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
546  return getFitChiSquare(helper,msgHelper) <= maxChiSqperNdf * getFitNDoF(helper,msgHelper);
547  });
548  }
549  if (m_minProb > 0.) {
550  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum chi squared probability: " << m_minProb );
551  trackCuts["FitQuality"].push_back([minProb = m_minProb](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
552  return TMath::Prob( getFitChiSquare(helper,msgHelper),getFitNDoF(helper,msgHelper)) >= minProb;
553  });
554  }
555  if (maxDoubleIsSet(m_minPtForProbCut) && m_minProbAbovePtCutoff > 0.) {
556  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum chi-sq probability of " << m_minProbAbovePtCutoff
557  << " above pt of " << m_minPtForProbCut*1e-3 << " GeV." );
558  trackCuts["FitQuality"].push_back([minPtForProbCut = m_minPtForProbCut,
559  minProbAbovePtCutoff = m_minProbAbovePtCutoff](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
560  return helper.pt(msgHelper) <= minPtForProbCut
561  || TMath::Prob( getFitChiSquare(helper,msgHelper),getFitNDoF(helper,msgHelper)) >= minProbAbovePtCutoff;
562  });
563  }
564 
565  // dE/dx cuts
566  if (m_minNUsedHitsdEdx > 0) {
567  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum used hits for dEdx: " << m_minNUsedHitsdEdx );
568  trackCuts["dEdxHits"].push_back([minNUsedHitsdEdx = m_minNUsedHitsdEdx](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
569  return getNumberOfUsedHitsdEdx(helper,msgHelper) >= minNUsedHitsdEdx;
570  });
571  }
572  if (m_minNOverflowHitsdEdx > 0) {
573  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum IBL overflow hits for dEdx: " << m_minNOverflowHitsdEdx );
574  trackCuts["dEdxHits"].push_back([minNOverflowHitsdEdx = m_minNOverflowHitsdEdx](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
575  return getNumberOfIBLOverflowsdEdx(helper,msgHelper) >= minNOverflowHitsdEdx;
576  });
577  }
578  if (m_minEProbabilityHT > 0) {
579  if constexpr(VERBOSE>0) ATH_MSG_INFO( " Minimum high threshold electron probability: " << m_minEProbabilityHT );
580  if (m_eProbHTonlyForXe) {
581  if constexpr(VERBOSE>0) ATH_MSG_INFO( " (only applied on tracks where all TRT hits are Xenon)" );
582  trackCuts["eProbHT"].push_back([minEProbabilityHT = m_minEProbabilityHT](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
583  return getSummarySum<2,Trk_Helper>(helper, msgHelper, {xAOD::numberOfTRTHits, xAOD::numberOfTRTOutliers})
585  || getEProbabilityHT(helper,msgHelper) >= minEProbabilityHT;
586  });
587  } else {
588  trackCuts["eProbHT"].push_back([minEProbabilityHT = m_minEProbabilityHT](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
589  return getEProbabilityHT(helper,msgHelper) >= minEProbabilityHT;
590  });
591  }
592  }
593 
594  if (!m_vecEtaCutoffsForSiHitsCut.empty() || !m_vecMinNSiHitsAboveEta.empty()) {
595  auto cutSize = m_vecEtaCutoffsForSiHitsCut.size();
596  if (cutSize != m_vecMinNSiHitsAboveEta.size()) {
597  ATH_MSG_ERROR( "Eta cutoffs and Silicon hit cuts must be vectors of the same length." );
598  return StatusCode::FAILURE;
599  }
600  if constexpr(VERBOSE>0) {
601  for (size_t i_cut=0; i_cut<cutSize-1; ++i_cut) {
602  ATH_MSG_INFO( " for " << m_vecEtaCutoffsForSiHitsCut[i_cut]
603  << " < eta < " << m_vecEtaCutoffsForSiHitsCut[i_cut+1]
604  << " ,Silicon hits >= " << m_vecMinNSiHitsAboveEta[i_cut] );
605  }
606  }
607  if (!checkOrder(m_vecEtaCutoffsForSiHitsCut.value())) {
608  ATH_MSG_ERROR( "Eta values not in ascending order." );
609  return StatusCode::FAILURE;
610  }
611  if constexpr(VERBOSE>0) ATH_MSG_INFO( " for eta > " << m_vecEtaCutoffsForSiHitsCut[cutSize-1]
612  << " ,Silicon hits >= " << m_vecMinNSiHitsAboveEta[cutSize-1] );
613 
614  trackCuts["SiHits"].push_back([p_vecEtaCutoffsForSiHitsCut = &std::as_const(m_vecEtaCutoffsForSiHitsCut.value()),
615  p_vecMinNSiHitsAboveEta = &std::as_const(m_vecMinNSiHitsAboveEta.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
616  double abs_eta = std::abs(helper.eta(msgHelper));
617  unsigned int bin_i = findBin(*p_vecEtaCutoffsForSiHitsCut, abs_eta);
618  return bin_i >= p_vecMinNSiHitsAboveEta->size()
619  || abs_eta>5.0
620  || getSummarySum<4,Trk_Helper>(helper, msgHelper,{xAOD::numberOfPixelHits,
621  xAOD::numberOfSCTHits,
622  xAOD::numberOfPixelDeadSensors,
623  xAOD::numberOfSCTDeadSensors}) >= (*p_vecMinNSiHitsAboveEta)[bin_i];
624  });
625  }
626 
627  if (!m_vecEtaCutoffsForPtCut.empty() || !m_vecMinPtAboveEta.empty()) {
628  auto cutSize = m_vecEtaCutoffsForPtCut.size();
629  if (cutSize != m_vecMinPtAboveEta.size()) {
630  ATH_MSG_ERROR( "Eta cutoffs and pT cuts must be vectors of the same length." );
631  return StatusCode::FAILURE;
632  }
633  if constexpr(VERBOSE>0) {
634  for (size_t i_cut=0; i_cut<cutSize-1; ++i_cut) {
635  ATH_MSG_INFO( " for " << m_vecEtaCutoffsForPtCut[i_cut]
636  << " < eta < " << m_vecEtaCutoffsForPtCut[i_cut+1]
637  << " ,transverse momentum >= " << m_vecMinPtAboveEta[i_cut] );
638  }
639  }
640  if (!checkOrder(m_vecEtaCutoffsForPtCut.value())) {
641  ATH_MSG_ERROR( "Eta values not in ascending order." );
642  return StatusCode::FAILURE;
643  }
644  if constexpr(VERBOSE>0) ATH_MSG_INFO( " for eta > " << m_vecEtaCutoffsForPtCut[cutSize-1]
645  << " ,transverse momentum >= " << m_vecMinPtAboveEta[cutSize-1] );
646  trackCuts["Pt"].push_back([p_vecEtaCutoffsForPtCut = &std::as_const(m_vecEtaCutoffsForPtCut.value()),
647  p_vecMinPtAboveEta = &std::as_const(m_vecMinPtAboveEta.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
648  double abs_eta = std::abs(helper.eta(msgHelper));
649  unsigned int bin_i = findBin(*p_vecEtaCutoffsForPtCut, abs_eta);
650  return bin_i >= p_vecMinPtAboveEta->size() || abs_eta > 5.0 || helper.pt(msgHelper) >= (*p_vecMinPtAboveEta)[bin_i];
651  });
652  }
653 
654  if (!m_vecPtCutoffsForSctHitsCut.empty() || !m_vecMinNSctHitsAbovePt.empty()) {
655  auto cutSize = m_vecPtCutoffsForSctHitsCut.size();
656  if (cutSize != m_vecMinNSctHitsAbovePt.size()) {
657  ATH_MSG_ERROR( "Pt cutoffs and SCT hit cuts must be vectors of the same length." );
658  return StatusCode::FAILURE;
659  }
660  if constexpr(VERBOSE>0) {
661  for (size_t i_cut=0; i_cut<cutSize-1; ++i_cut) {
662  ATH_MSG_INFO( " for " << m_vecPtCutoffsForSctHitsCut[i_cut]
663  << " < pt < " << m_vecPtCutoffsForSctHitsCut[i_cut+1]
664  << " MeV,\tSCT hits >= " << m_vecMinNSctHitsAbovePt[i_cut] );
665  }
666  }
667  if (!checkOrder(m_vecPtCutoffsForSctHitsCut.value())) {
668  ATH_MSG_ERROR( "Pt values not in ascending order." );
669  return StatusCode::FAILURE;
670  }
671  if constexpr(VERBOSE>0) ATH_MSG_INFO( " for pt > " << m_vecPtCutoffsForSctHitsCut[cutSize-1]
672  << " MeV,\t\tSCT hits >= " << m_vecMinNSctHitsAbovePt[cutSize-1] );
673  trackCuts["SctHits"].push_back([p_vecPtCutoffsForSctHitsCut = &std::as_const(m_vecPtCutoffsForSctHitsCut.value()),
674  p_vecMinNSctHitsAbovePt = &std::as_const(m_vecMinNSctHitsAbovePt.value())](Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
675  double pt = helper.pt(msgHelper);
676  unsigned int bin_i = findBin(*p_vecPtCutoffsForSctHitsCut, pt);
677  return bin_i >= p_vecPtCutoffsForSctHitsCut->size()
678  || getSummarySum<2,Trk_Helper>(helper, msgHelper,{xAOD::numberOfSCTHits,
679  xAOD::numberOfSCTDeadSensors}) >= (*p_vecMinNSctHitsAbovePt)[bin_i];
680  });
681  }
682 
683  if (!m_vecPtCutoffsForZ0SinThetaCut.empty() ||
684  !m_vecEtaCutoffsForZ0SinThetaCut.empty() ||
685  !m_vecvecMaxZ0SinThetaAboveEtaPt.empty()) {
686  auto etaSize = m_vecEtaCutoffsForZ0SinThetaCut.size();
687  auto ptSize = m_vecPtCutoffsForZ0SinThetaCut.size();
688  if (etaSize != m_vecvecMaxZ0SinThetaAboveEtaPt.size()) {
689  ATH_MSG_ERROR( "Eta cutoffs and Z0SinTheta cuts must be vectors of the same length." );
690  return StatusCode::FAILURE;
691  }
692  for (size_t i_size=0; i_size<etaSize-1; ++i_size) {
693  if (ptSize != m_vecvecMaxZ0SinThetaAboveEtaPt[i_size].size()) {
694  ATH_MSG_ERROR( "Pt cutoffs and Z0SinTheta cuts must be vectors of the same length." );
695  return StatusCode::FAILURE;
696  }
697  }
698 
699  std::stringstream pTRangeBuffer;
700  std::copy(m_vecPtCutoffsForZ0SinThetaCut.begin(), m_vecPtCutoffsForZ0SinThetaCut.end(), std::ostream_iterator<Double_t>(pTRangeBuffer, ", "));
701  std::string pTString=pTRangeBuffer.str();
702  if constexpr(VERBOSE>0) ATH_MSG_INFO("Z0SinTheta cuts (<=) for pT above "<<pTString.substr(0, pTString.size()-2)<<"MeV, respectively:");
703  for (size_t i_cut_eta=0; i_cut_eta<etaSize; ++i_cut_eta)
704  {
705  std::stringstream etaRangeBuffer;
706  etaRangeBuffer << std::setprecision(2) << std::fixed << m_vecEtaCutoffsForZ0SinThetaCut[i_cut_eta] << " < |#eta| < ";
707  if(i_cut_eta!=etaSize-1) etaRangeBuffer << std::setprecision(2) << std::fixed << m_vecEtaCutoffsForZ0SinThetaCut[i_cut_eta+1];
708  else etaRangeBuffer << std::setprecision(2) << std::fixed <<m_maxAbsEta;
709 
710  std::stringstream cutBuffer;
711  std::copy(m_vecvecMaxZ0SinThetaAboveEtaPt[i_cut_eta].begin(), m_vecvecMaxZ0SinThetaAboveEtaPt[i_cut_eta].end(), std::ostream_iterator<Double_t>(cutBuffer, ", "));
712  std::string cutString=cutBuffer.str();
713 
714  if constexpr(VERBOSE>0) ATH_MSG_INFO(" for "<<etaRangeBuffer.str()<<": "<<cutString.substr(0, cutString.size()-2));
715  }
716 
717  if (!checkOrder(m_vecEtaCutoffsForZ0SinThetaCut.value())) {
718  ATH_MSG_ERROR( "Eta values not in ascending order." );
719  return StatusCode::FAILURE;
720  }
721  if (!checkOrder(m_vecPtCutoffsForZ0SinThetaCut.value())) {
722  ATH_MSG_ERROR( "Pt values not in ascending order." );
723  return StatusCode::FAILURE;
724  }
725 
726  trackCuts["Z0SinTheta"].push_back([p_vecEtaCutoffsForZ0SinThetaCut = &std::as_const(m_vecEtaCutoffsForZ0SinThetaCut.value()),
727  p_vecPtCutoffsForZ0SinThetaCut = &std::as_const(m_vecPtCutoffsForZ0SinThetaCut.value()),
728  p_vecvecMaxZ0SinThetaAboveEtaPt = &std::as_const(m_vecvecMaxZ0SinThetaAboveEtaPt.value())] (Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
729  double eta = helper.eta(msgHelper);
730  unsigned int bin_eta = findBin(*p_vecEtaCutoffsForZ0SinThetaCut, std::fabs(eta));
731  double pt = helper.pt(msgHelper);
732  unsigned int bin_pt = findBin(*p_vecPtCutoffsForZ0SinThetaCut, pt);
733  return bin_eta >= p_vecEtaCutoffsForZ0SinThetaCut->size()
734  || bin_pt >= p_vecPtCutoffsForZ0SinThetaCut->size()
735  || std::fabs(helper.z0(msgHelper) * std::sin(helper.theta(msgHelper))) <= (*p_vecvecMaxZ0SinThetaAboveEtaPt)[bin_eta][bin_pt];
736  });
737  }
738 
739  if (!m_vecPtCutoffsForD0Cut.empty() ||
740  !m_vecEtaCutoffsForD0Cut.empty() ||
741  !m_vecvecMaxD0AboveEtaPt.empty()) {
742  auto etaSize = m_vecEtaCutoffsForD0Cut.size();
743  auto ptSize = m_vecPtCutoffsForD0Cut.size();
744  if (etaSize != m_vecvecMaxD0AboveEtaPt.size()) {
745  ATH_MSG_ERROR( "Eta cutoffs and D0 cuts must be vectors of the same length." );
746  return StatusCode::FAILURE;
747  }
748  for (size_t i_size=0; i_size<etaSize-1; ++i_size) {
749  if (ptSize != m_vecvecMaxD0AboveEtaPt[i_size].size()) {
750  ATH_MSG_ERROR( "Pt cutoffs and D0 cuts must be vectors of the same length." );
751  return StatusCode::FAILURE;
752  }
753  }
754 
755  std::stringstream pTRangeBuffer;
756  std::copy(m_vecPtCutoffsForD0Cut.begin(), m_vecPtCutoffsForD0Cut.end(), std::ostream_iterator<Double_t>(pTRangeBuffer, ", "));
757  std::string pTString=pTRangeBuffer.str();
758  if constexpr(VERBOSE>0) ATH_MSG_INFO("D0 cuts (<=) for pT above "<<pTString.substr(0, pTString.size()-2)<<"MeV, respectively:");
759  for (size_t i_cut_eta=0; i_cut_eta<etaSize; ++i_cut_eta)
760  {
761  std::stringstream etaRangeBuffer;
762  etaRangeBuffer << std::setprecision(2) << std::fixed << m_vecEtaCutoffsForD0Cut[i_cut_eta] << " < |#eta| < ";
763  if(i_cut_eta!=etaSize-1) etaRangeBuffer << std::setprecision(2) << std::fixed << m_vecEtaCutoffsForD0Cut[i_cut_eta+1];
764  else etaRangeBuffer << std::setprecision(2) << std::fixed <<m_maxAbsEta;
765 
766  std::stringstream cutBuffer;
767  std::copy(m_vecvecMaxD0AboveEtaPt[i_cut_eta].begin(), m_vecvecMaxD0AboveEtaPt[i_cut_eta].end(), std::ostream_iterator<Double_t>(cutBuffer, ", "));
768  std::string cutString=cutBuffer.str();
769 
770  if constexpr(VERBOSE>0) ATH_MSG_INFO(" for "<<etaRangeBuffer.str()<<": "<<cutString.substr(0, cutString.size()-2));
771  }
772 
773  if (!checkOrder(m_vecEtaCutoffsForD0Cut.value())) {
774  ATH_MSG_ERROR( "Eta values not in ascending order." );
775  return StatusCode::FAILURE;
776  }
777  if (!checkOrder(m_vecPtCutoffsForD0Cut.value())) {
778  ATH_MSG_ERROR( "Pt values not in ascending order." );
779  return StatusCode::FAILURE;
780  }
781 
782  trackCuts["D0"].push_back([p_vecEtaCutoffsForD0Cut = &std::as_const(m_vecEtaCutoffsForD0Cut.value()),
783  p_vecPtCutoffsForD0Cut = &std::as_const(m_vecPtCutoffsForD0Cut.value()),
784  p_vecvecMaxD0AboveEtaPt = &std::as_const(m_vecvecMaxD0AboveEtaPt.value())] (Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
785  double eta = helper.eta(msgHelper);
786  unsigned int bin_eta = findBin(*p_vecEtaCutoffsForD0Cut, std::fabs(eta));
787  double pt = helper.pt(msgHelper);
788  unsigned int bin_pt = findBin(*p_vecPtCutoffsForD0Cut, pt);
789  return bin_eta >= p_vecEtaCutoffsForD0Cut->size()
790  || bin_pt >= p_vecPtCutoffsForD0Cut->size()
791  || std::fabs(helper.d0(msgHelper)) <= (*p_vecvecMaxD0AboveEtaPt)[bin_eta][bin_pt];
792  });
793  }
794 
795  if (!m_vecPtCutoffsForSctHolesCut.empty() ||
796  !m_vecEtaCutoffsForSctHolesCut.empty() ||
797  !m_vecvecMaxSctHolesAboveEtaPt.empty()) {
798  auto etaSize = m_vecEtaCutoffsForSctHolesCut.size();
799  auto ptSize = m_vecPtCutoffsForSctHolesCut.size();
800  if (etaSize != m_vecvecMaxSctHolesAboveEtaPt.size()) {
801  ATH_MSG_ERROR( "Eta cutoffs and SctHoles cuts must be vectors of the same length." );
802  return StatusCode::FAILURE;
803  }
804  for (size_t i_size=0; i_size<etaSize-1; ++i_size) {
805  if (ptSize != m_vecvecMaxSctHolesAboveEtaPt[i_size].size()) {
806  ATH_MSG_ERROR( "Pt cutoffs and SctHoles cuts must be vectors of the same length." );
807  return StatusCode::FAILURE;
808  }
809  }
810 
811  std::stringstream pTRangeBuffer;
812  std::copy(m_vecPtCutoffsForSctHolesCut.begin(), m_vecPtCutoffsForSctHolesCut.end(), std::ostream_iterator<Double_t>(pTRangeBuffer, ", "));
813  std::string pTString=pTRangeBuffer.str();
814  if constexpr(VERBOSE>0) ATH_MSG_INFO("SctHoles cuts (<=) for pT above "<<pTString.substr(0, pTString.size()-2)<<"MeV, respectively:");
815  for (size_t i_cut_eta=0; i_cut_eta<etaSize; ++i_cut_eta)
816  {
817  std::stringstream etaRangeBuffer;
818  etaRangeBuffer << std::setprecision(2) << std::fixed << m_vecEtaCutoffsForSctHolesCut[i_cut_eta] << " < |#eta| < ";
819  if(i_cut_eta!=etaSize-1) etaRangeBuffer << std::setprecision(2) << std::fixed << m_vecEtaCutoffsForSctHolesCut[i_cut_eta+1];
820  else etaRangeBuffer << std::setprecision(2) << std::fixed <<m_maxAbsEta;
821 
822  std::stringstream cutBuffer;
823  std::copy(m_vecvecMaxSctHolesAboveEtaPt[i_cut_eta].begin(), m_vecvecMaxSctHolesAboveEtaPt[i_cut_eta].end(), std::ostream_iterator<Double_t>(cutBuffer, ", "));
824  std::string cutString=cutBuffer.str();
825 
826  if constexpr(VERBOSE>0) ATH_MSG_INFO(" for "<<etaRangeBuffer.str()<<": "<<cutString.substr(0, cutString.size()-2));
827  }
828 
829  if (!checkOrder(m_vecEtaCutoffsForSctHolesCut.value())) {
830  ATH_MSG_ERROR( "Eta values not in ascending order." );
831  return StatusCode::FAILURE;
832  }
833  if (!checkOrder(m_vecPtCutoffsForSctHolesCut.value())) {
834  ATH_MSG_ERROR( "Pt values not in ascending order." );
835  return StatusCode::FAILURE;
836  }
837 
838  trackCuts["SctHits"].push_back([p_vecEtaCutoffsForSctHolesCut = &std::as_const(m_vecEtaCutoffsForSctHolesCut.value()),
839  p_vecPtCutoffsForSctHolesCut = &std::as_const(m_vecPtCutoffsForSctHolesCut.value()),
840  p_vecvecMaxSctHolesAboveEtaPt = &std::as_const(m_vecvecMaxSctHolesAboveEtaPt.value())] (Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
841  double eta = helper.eta(msgHelper);
842  unsigned int bin_eta = findBin(*p_vecEtaCutoffsForSctHolesCut, std::fabs(eta));
843  double pt = helper.pt(msgHelper);
844  unsigned int bin_pt = findBin(*p_vecPtCutoffsForSctHolesCut, pt);
845  return bin_eta >= p_vecEtaCutoffsForSctHolesCut->size()
846  || bin_pt >= p_vecPtCutoffsForSctHolesCut->size()
847  || getSummary(helper, msgHelper, xAOD::numberOfSCTHoles) <= (*p_vecvecMaxSctHolesAboveEtaPt)[bin_eta][bin_pt];
848  });
849  }
850 
851  if (!m_vecPtCutoffsForSctHitsPlusDeadCut.empty() ||
852  !m_vecEtaCutoffsForSctHitsPlusDeadCut.empty() ||
853  !m_vecvecMinSctHitsPlusDeadAboveEtaPt.empty()) {
854  auto etaSize = m_vecEtaCutoffsForSctHitsPlusDeadCut.size();
855  auto ptSize = m_vecPtCutoffsForSctHitsPlusDeadCut.size();
856  if (etaSize != m_vecvecMinSctHitsPlusDeadAboveEtaPt.size()) {
857  ATH_MSG_ERROR( "Eta cutoffs and SctHitsPlusDead cuts must be vectors of the same length." );
858  return StatusCode::FAILURE;
859  }
860  for (size_t i_size=0; i_size<etaSize-1; ++i_size) {
861  if (ptSize != m_vecvecMinSctHitsPlusDeadAboveEtaPt[i_size].size()) {
862  ATH_MSG_ERROR( "Pt cutoffs and SctHitsPlusDead cuts must be vectors of the same length." );
863  return StatusCode::FAILURE;
864  }
865  }
866 
867  std::stringstream pTRangeBuffer;
868  std::copy(m_vecPtCutoffsForSctHitsPlusDeadCut.begin(), m_vecPtCutoffsForSctHitsPlusDeadCut.end(), std::ostream_iterator<Double_t>(pTRangeBuffer, ", "));
869  std::string pTString=pTRangeBuffer.str();
870  if constexpr(VERBOSE>0) ATH_MSG_INFO("SctHitsPlusDead cuts (>=) for pT above "<<pTString.substr(0, pTString.size()-2)<<"MeV, respectively:");
871  for (size_t i_cut_eta=0; i_cut_eta<etaSize; ++i_cut_eta)
872  {
873  std::stringstream etaRangeBuffer;
874  etaRangeBuffer << std::setprecision(2) << std::fixed << m_vecEtaCutoffsForSctHitsPlusDeadCut[i_cut_eta] << " < |#eta| < ";
875  if(i_cut_eta!=etaSize-1) etaRangeBuffer << std::setprecision(2) << std::fixed << m_vecEtaCutoffsForSctHitsPlusDeadCut[i_cut_eta+1];
876  else etaRangeBuffer << std::setprecision(2) << std::fixed <<m_maxAbsEta;
877 
878  std::stringstream cutBuffer;
879  std::copy(m_vecvecMinSctHitsPlusDeadAboveEtaPt[i_cut_eta].begin(), m_vecvecMinSctHitsPlusDeadAboveEtaPt[i_cut_eta].end(), std::ostream_iterator<Double_t>(cutBuffer, ", "));
880  std::string cutString=cutBuffer.str();
881 
882  if constexpr(VERBOSE>0) ATH_MSG_INFO(" for "<<etaRangeBuffer.str()<<": "<<cutString.substr(0, cutString.size()-2));
883  }
884 
885  if (!checkOrder(m_vecEtaCutoffsForSctHitsPlusDeadCut.value())) {
886  ATH_MSG_ERROR( "Eta values not in ascending order." );
887  return StatusCode::FAILURE;
888  }
889  if (!checkOrder(m_vecPtCutoffsForSctHitsPlusDeadCut.value())) {
890  ATH_MSG_ERROR( "Pt values not in ascending order." );
891  return StatusCode::FAILURE;
892  }
893 
894  trackCuts["SctHits"].push_back([p_vecEtaCutoffsForSctHitsPlusDeadCut = &std::as_const(m_vecEtaCutoffsForSctHitsPlusDeadCut.value()),
895  p_vecPtCutoffsForSctHitsPlusDeadCut = &std::as_const(m_vecPtCutoffsForSctHitsPlusDeadCut.value()),
896  p_vecvecMinSctHitsPlusDeadAboveEtaPt = &std::as_const(m_vecvecMinSctHitsPlusDeadAboveEtaPt.value())] (Trk_Helper helper, const asg::AsgMessaging &msgHelper) {
897  double eta = helper.eta(msgHelper);
898  unsigned int bin_eta = findBin(*p_vecEtaCutoffsForSctHitsPlusDeadCut, std::fabs(eta));
899  double pt = helper.pt(msgHelper);
900  unsigned int bin_pt = findBin(*p_vecPtCutoffsForSctHitsPlusDeadCut, pt);
901  return bin_eta >= p_vecEtaCutoffsForSctHitsPlusDeadCut->size()
902  || bin_pt >= p_vecPtCutoffsForSctHitsPlusDeadCut->size()
903  || getSummarySum<2,Trk_Helper>(helper, msgHelper, {xAOD::numberOfSCTHits, xAOD::numberOfSCTDeadSensors}) >= (*p_vecvecMinSctHitsPlusDeadAboveEtaPt)[bin_eta][bin_pt];
904  });
905  }
906 
907  return StatusCode::SUCCESS;
908 }
909 
910 
911 template <class Trk_Helper>
913  const std::map< std::string, std::vector< std::function<bool(Trk_Helper helper, const asg::AsgMessaging &msgHelper)> > > &trackCuts) const {
914  if (!m_isInitialized) {
915  if (!m_warnInit) {
916  ATH_MSG_WARNING( "Tool is not initialized! Calling accept() will not be very helpful." );
917  m_warnInit = true;
918  }
919  }
920 
921  asg::AcceptData acceptData(&m_acceptInfo);
922  bool passAll = true;
923 
924  // loop over all cuts
925  UShort_t cutFamilyIndex = 0;
926  for ( const auto& cutFamily : trackCuts ) {
927  bool pass = true;
928 
929  for ( const auto& cut : cutFamily.second ) {
930  if (! cut(helper, *m_msgHelper) ) {
931  pass = false;
932  break;
933  }
934  }
935 
936  // @TODO really always run through all cuts even if passed is false ?
937  passAll &= pass;
938  acceptData.setCutResult( cutFamilyIndex, pass );
939  cutFamilyIndex++;
940  }
941 
942  {
943  // lock access to m_numTracksPassedCuts
944  std::lock_guard<std::mutex> lock(m_mutex);
945  for (unsigned int idx=0; idx < trackCuts.size(); ++idx) {
946  assert(idx<m_numTracksPassedCuts.size());
947  m_numTracksPassedCuts[idx] += acceptData.getCutResult(idx);
948  }
949  }
950  if (passAll) m_numTracksPassed++;
951  m_numTracksProcessed++;
952 
953  return acceptData;
954 
955 }
956 
957 
959 {
960  if (!m_isInitialized) {
961  ATH_MSG_ERROR( "You are attempting to finalize a tool that has not been initialized()." );
962  }
963 
964 #ifdef XAOD_ANALYSIS
965  if (m_numTracksProcessed == 0) {
966  ATH_MSG_INFO( "No tracks processed in selection tool." );
967  return StatusCode::SUCCESS;
968  }
969 
970  // Only printed out for analysis
971  ATH_MSG_INFO( m_numTracksPassed << " / " << m_numTracksProcessed << " = "
972  << m_numTracksPassed*100./m_numTracksProcessed << "% passed all cuts." );
973  for (const auto& cutFamily : m_trackParticleCuts) {
974  // lock(m_mutex) is not needed because this is inside of non-const finalize method.
975  ULong64_t numPassed = m_numTracksPassedCuts.at(m_acceptInfo.getCutPosition(cutFamily.first));
976  ATH_MSG_INFO( numPassed << " = " << numPassed*100./m_numTracksProcessed << "% passed "
977  << cutFamily.first << " cut." );
978  }
979 #endif
980 
981  return StatusCode::SUCCESS;
982 }
983 
984 
990 {
991  return m_acceptInfo;
992 }
993 
994 
1007 {
1008 
1009  asg::AcceptData acceptData(&m_acceptInfo);
1010  // Check if this is a track:
1011  if( p->type() != xAOD::Type::TrackParticle ) {
1012  ATH_MSG_ERROR( "accept(...) Function received a non-track" );
1013  return acceptData;
1014  }
1015 
1016  // Cast it to a track (we have already checked its type so we do not have to dynamic_cast):
1017  const xAOD::TrackParticle* trk = static_cast< const xAOD::TrackParticle* >( p );
1018 
1019  // Let the specific function do the work:
1020  return accept( *trk, nullptr );
1021 }
1022 
1023 
1050  const xAOD::Vertex* vtx ) const
1051 {
1052  asg::AcceptData acceptData(&m_acceptInfo);
1053  if (m_trackParticleCuts.empty()) {
1054  m_numTracksPassed++;
1055  m_numTracksProcessed++;
1056  return acceptData;
1057  }
1058 
1059  InDetAccessor::TrackParticleHelper track_helper(trk,vtx);
1060  return accept( track_helper, m_trackParticleCuts);
1061 }
1062 
1063 #ifndef XAOD_ANALYSIS
1073  const Trk::Vertex* vertex ) const
1074 {
1075  if (!m_isInitialized) ATH_MSG_WARNING( "Tool is not initialized! Calling accept() will not be very helpful." );
1076 
1077  asg::AcceptData acceptData(&m_acceptInfo);
1078  if (m_trkTrackCuts.empty()) {
1079  m_numTracksPassed++;
1080  m_numTracksProcessed++;
1081  return acceptData;
1082  }
1083 
1084  const Trk::TrackParameters* perigee = track.perigeeParameters();
1085 
1086  if ( perigee == nullptr || !perigee->covariance() ) {
1087  ATH_MSG_WARNING( "Track preselection: Zero pointer to parameterbase* received (most likely a track without perigee). This track will not pass any cuts." );
1088  return acceptData;
1089  }
1090 
1091  std::unique_ptr<const Trk::TrackParameters> paramsAtVertex;
1092  if (vertex) {
1093  Trk::PerigeeSurface perigeeSurface(vertex->position());
1094  paramsAtVertex =
1095  m_extrapolator->extrapolate(Gaudi::Hive::currentContext(),
1096  *perigee,
1097  perigeeSurface,
1099  true,
1100  track.info().particleHypothesis());
1101  perigee = paramsAtVertex.get();
1102  }
1103 
1104  if ( perigee == nullptr || !perigee->covariance() ) {
1105  ATH_MSG_INFO( "Track preselection: cannot make a measured perigee. This track will not pass any cuts." );
1106  if (!m_initTrkTools)
1107  ATH_MSG_INFO( "The user should set \"UseTrkTrackTools\" to true if they want the extrapolation tool to try to get a perigee." );
1108  return acceptData;
1109  }
1110 
1111 
1112  std::unique_ptr<Trk::TrackSummary> cleanup_summary;
1113  const Trk::TrackSummary* summary = track.trackSummary();
1114  if (summary == nullptr && m_trackSumToolAvailable) {
1115  cleanup_summary = m_trackSumTool->summary(Gaudi::Hive::currentContext(),track);
1116  summary = cleanup_summary.get();
1117  }
1118  if (summary == nullptr) {
1119  ATH_MSG_INFO( "Track preselection: cannot get a track summary. This track will not pass any cuts." );
1120  if (!m_initTrkTools)
1121  ATH_MSG_INFO( "The Trk::Track tools were not set to be initialized. The user should set the property \"UseTrkTrackTools\" to true if they wish to use the summary tool." );
1122  return acceptData;
1123  }
1124 
1125  InDetAccessor::TrkTrackHelper track_helper(track,*summary, perigee);
1126  acceptData = accept( track_helper, m_trkTrackCuts);
1127  return acceptData;
1128 }
1129 
1130 #endif // XAOD_ANALYSIS
1131 
1147 #ifdef __GNUC__
1148 #pragma GCC diagnostic push
1149 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1150 #endif
1152 {
1153 #ifndef XAOD_STANDALONE
1154  ATH_MSG_WARNING( "InDetTrackSelectionTool::setCutLevel() is not designed to be called manually in Athena." );
1155  ATH_MSG_WARNING( "It may not behave as intended. Instead, configure it in the job options through the CutLevel property." );
1156 #endif // XAOD_STANDALONE
1157  if (!m_cutLevel.empty()) {
1158  ATH_MSG_WARNING( "Cut level already set to " << m_cutLevel << ". Calling setCutLevel() is not expected." );
1159  }
1160  setCutLevelPrivate(level, overwrite);
1161 }
1162 #ifdef __GNUC__
1163 #pragma GCC diagnostic pop
1164 #endif
1165 
1167 {
1168  switch (level) {
1169  case CutLevel::NoCut :
1170  if (m_isInitialized) {
1171  // this check is in here so that it only happens once per call to setCutLevel,
1172  // but will still warn if only the private version is called somehow.
1173  ATH_MSG_WARNING( "Trying to set cut level while the tool is already initialized." );
1174  ATH_MSG_WARNING( "This will almost certainly not exhibit intended behavior." );
1175  }
1176  if (overwrite) {
1177  // minimum cuts will default to -1, so if a user wishes to remove a cut
1178  // from a preset level they can do so by setting the minimum to zero.
1179  // maximum cuts can be removed from a preset level by setting them negative.
1180  m_minPt = -1.; // in MeV
1181  m_minP = -1.;
1182  m_maxAbsEta = LOCAL_MAX_DOUBLE;
1183  m_maxZ0SinTheta = LOCAL_MAX_DOUBLE; // in mm
1184  m_maxZ0 = LOCAL_MAX_DOUBLE;
1185  m_maxD0 = LOCAL_MAX_DOUBLE;
1186  m_maxSigmaD0 = LOCAL_MAX_DOUBLE;
1187  m_maxSigmaZ0 = LOCAL_MAX_DOUBLE;
1188  m_maxSigmaZ0SinTheta = LOCAL_MAX_DOUBLE;
1189  m_maxD0overSigmaD0 = LOCAL_MAX_DOUBLE;
1190  m_maxZ0overSigmaZ0 = LOCAL_MAX_DOUBLE;
1191  m_maxZ0SinThetaoverSigmaZ0SinTheta = LOCAL_MAX_DOUBLE;
1192  m_minNInnermostLayerHits = -1;
1193  m_minNNextToInnermostLayerHits = -1;
1194  m_minNBothInnermostLayersHits = -1;
1195  m_maxNInnermostLayerSharedHits = LOCAL_MAX_INT;
1196  m_useMinBiasInnermostLayersCut = 0;
1197  m_minNPixelHits = -1;
1198  m_minNPixelHitsPhysical = -1;
1199  m_maxNPixelSharedHits = LOCAL_MAX_INT;
1200  m_maxNPixelHoles = LOCAL_MAX_INT;
1201  m_minNSctHits = -1;
1202  m_minNSctHitsPhysical = -1;
1203  m_maxNSctHoles = LOCAL_MAX_INT;
1204  m_maxNSctSharedHits = LOCAL_MAX_INT;
1205  m_maxNSctDoubleHoles = LOCAL_MAX_INT;
1206  m_minNSiHits = -1;
1207  m_minNSiHitsPhysical = -1;
1208  m_maxNSiSharedHits = LOCAL_MAX_INT;
1209  m_minNSiHitsIfSiSharedHits = -1;
1210  m_maxNSiHoles = LOCAL_MAX_INT;
1211  m_minEtaForStrictNSiHitsCut = LOCAL_MAX_DOUBLE;
1212  m_minNSiHitsAboveEtaCutoff = -1;
1213  m_maxOneSharedModule = false;
1214  m_maxTrtEtaAcceptance = LOCAL_MAX_DOUBLE;
1215  m_maxEtaForTrtHitCuts = -1.; // this is really a minimum eta above which cuts are not applied
1216  m_minNTrtHits = -1;
1217  m_minNTrtHitsPlusOutliers = -1;
1218  m_minNTrtHighThresholdHits = -1;
1219  m_minNTrtHighThresholdHitsPlusOutliers = -1;
1220  m_maxTrtHighEFraction = LOCAL_MAX_DOUBLE;
1221  m_maxTrtHighEFractionWithOutliers = LOCAL_MAX_DOUBLE;
1222  m_maxTrtOutlierFraction = LOCAL_MAX_DOUBLE;
1223  m_maxChiSq = LOCAL_MAX_DOUBLE;
1224  m_minProb = -1.;
1225  m_maxChiSqperNdf = LOCAL_MAX_DOUBLE;
1226  m_minPtForProbCut = LOCAL_MAX_DOUBLE;
1227  m_minProbAbovePtCutoff = -1.;
1228  m_useEtaDependentMaxChiSq = false;
1229  m_minNUsedHitsdEdx = -1;
1230  m_minNOverflowHitsdEdx = -1;
1231  m_minEProbabilityHT = -1.;
1232  m_eProbHTonlyForXe = false;
1233 #ifndef XAOD_ANALYSIS
1234  m_minNSiHitsMod = -1;
1235  m_minNSiHitsModTop = -1;
1236  m_minNSiHitsModBottom = -1;
1237 #endif
1238  m_vecEtaCutoffsForSiHitsCut = std::vector<double>();
1239  m_vecMinNSiHitsAboveEta = std::vector<int>();
1240  m_vecEtaCutoffsForPtCut = std::vector<double>();
1241  m_vecMinPtAboveEta = std::vector<double>();
1242  m_vecPtCutoffsForSctHitsCut = std::vector<double>();
1243  m_vecMinNSctHitsAbovePt = std::vector<int>();
1244  m_vecEtaCutoffsForZ0SinThetaCut = std::vector<double>();
1245  m_vecPtCutoffsForZ0SinThetaCut = std::vector<double>();
1246  m_vecvecMaxZ0SinThetaAboveEtaPt = std::vector<std::vector<double>>();
1247  m_vecEtaCutoffsForD0Cut = std::vector<double>();
1248  m_vecPtCutoffsForD0Cut = std::vector<double>();
1249  m_vecvecMaxD0AboveEtaPt = std::vector<std::vector<double>>();
1250  m_vecEtaCutoffsForSctHolesCut = std::vector<double>();
1251  m_vecPtCutoffsForSctHolesCut = std::vector<double>();
1252  m_vecvecMaxSctHolesAboveEtaPt = std::vector<std::vector<double>>();
1253  m_vecEtaCutoffsForSctHitsPlusDeadCut = std::vector<double>();
1254  m_vecPtCutoffsForSctHitsPlusDeadCut = std::vector<double>();
1255  m_vecvecMinSctHitsPlusDeadAboveEtaPt = std::vector<std::vector<double>>();
1256  }
1257  break;
1258  case CutLevel::Loose :
1259  setCutLevelPrivate(CutLevel::NoCut, overwrite); // if hard overwrite, reset all cuts first. will do nothing if !overwrite
1260  // change the cuts if a hard overwrite is asked for or if the cuts are unset
1261  if (overwrite || m_maxAbsEta >= LOCAL_MAX_DOUBLE) m_maxAbsEta = 2.5;
1262  if (overwrite || m_minNSiHits < 0) m_minNSiHits = 8;
1263  m_maxOneSharedModule = true;
1264  if (overwrite || m_maxNSiHoles >= LOCAL_MAX_INT) m_maxNSiHoles = 2;
1265  if (overwrite || m_maxNPixelHoles >= LOCAL_MAX_INT) m_maxNPixelHoles = 1;
1266  break;
1267  case CutLevel::LoosePrimary :
1268  setCutLevelPrivate(CutLevel::NoCut, overwrite); // implement loose cuts first
1269  if (overwrite || m_maxAbsEta >= LOCAL_MAX_DOUBLE) m_maxAbsEta = 2.5;
1270  if (overwrite || m_minNSiHits < 0) m_minNSiHits = 8;
1271  m_maxOneSharedModule = true;
1272  if (overwrite || m_maxNSiHoles >= LOCAL_MAX_INT) m_maxNSiHoles = 2;
1273  if (overwrite || m_maxNPixelHoles >= LOCAL_MAX_INT) m_maxNPixelHoles = 1;
1274  if (overwrite || m_minNSiHitsIfSiSharedHits < 0) m_minNSiHitsIfSiSharedHits = 10;
1275  break;
1276  case CutLevel::TightPrimary :
1277  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1278  if (overwrite || m_maxAbsEta >= LOCAL_MAX_DOUBLE) m_maxAbsEta = 2.5;
1279  if (overwrite || m_minNSiHits < 0) m_minNSiHits = 9;
1280  m_maxOneSharedModule = true;
1281  if (overwrite || m_maxNSiHoles >= LOCAL_MAX_INT) m_maxNSiHoles = 2;
1282  if (overwrite || m_maxNPixelHoles >= LOCAL_MAX_INT) m_maxNPixelHoles = 0;
1283  if (overwrite || m_minEtaForStrictNSiHitsCut >= LOCAL_MAX_DOUBLE) m_minEtaForStrictNSiHitsCut = 1.65;
1284  if (overwrite || m_minNSiHitsAboveEtaCutoff < 0) m_minNSiHitsAboveEtaCutoff = 11;
1285  if (overwrite || m_minNBothInnermostLayersHits < 0) m_minNBothInnermostLayersHits = 1;
1286  break;
1287  case CutLevel::LooseMuon :
1288  setCutLevelPrivate(CutLevel::NoCut, overwrite); // reset cuts unless we are doing a soft set
1289  if (overwrite || m_minNPixelHits < 0) m_minNPixelHits = 1;
1290  if (overwrite || m_minNSctHits < 0) m_minNSctHits = 5;
1291  if (overwrite || m_maxNSiHoles >= LOCAL_MAX_INT) m_maxNSiHoles = 2;
1292  if (overwrite || m_maxTrtEtaAcceptance >= LOCAL_MAX_DOUBLE ) m_maxTrtEtaAcceptance = 0.1;
1293  if (overwrite || m_maxEtaForTrtHitCuts < 0.) m_maxEtaForTrtHitCuts = 1.9;
1294  if (overwrite || m_minNTrtHitsPlusOutliers < 0) m_minNTrtHitsPlusOutliers = 6;
1295  if (overwrite || m_maxTrtOutlierFraction >= LOCAL_MAX_DOUBLE) m_maxTrtOutlierFraction = 0.9;
1296  break;
1297  case CutLevel::LooseElectron :
1298  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1299  if (overwrite || m_minNSiHits < 0) m_minNSiHits = 7;
1300  if (overwrite || m_minNPixelHits < 0) m_minNPixelHits = 1;
1301  break;
1302  case CutLevel::LooseTau :
1303  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1304  if (overwrite || m_minPt < 0.0) m_minPt = 1000.0;
1305  if (overwrite || m_minNSiHits < 0) m_minNSiHits = 7;
1306  if (overwrite || m_minNPixelHits < 0) m_minNPixelHits = 2;
1307  if (overwrite || m_maxD0 >= LOCAL_MAX_DOUBLE) m_maxD0 = 1.0;
1308  if (overwrite || m_maxZ0 >= LOCAL_MAX_DOUBLE) m_maxZ0 = 1.5;
1309  break;
1310  case CutLevel::MinBias :
1311  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1312  if (overwrite || m_useMinBiasInnermostLayersCut >= 0) m_useMinBiasInnermostLayersCut = 1; // if this is less than 0, it is turned off
1313  if (overwrite || m_minNPixelHits < 0) m_minNPixelHits = 1;
1314  if (overwrite || m_minNSctHits < 0) m_minNSctHits = 6;
1315  if (overwrite || m_minProbAbovePtCutoff < 0.) {
1316  m_minPtForProbCut = 10000.;
1317  m_minProbAbovePtCutoff = .01;
1318  }
1319  if (overwrite || m_maxD0 >= LOCAL_MAX_DOUBLE) m_maxD0 = 1.5;
1320  if (overwrite || m_maxZ0SinTheta >= LOCAL_MAX_DOUBLE) m_maxZ0SinTheta = 1.5;
1321  if (overwrite || m_maxAbsEta >= LOCAL_MAX_DOUBLE) m_maxAbsEta = 2.5;
1322  if (overwrite || m_minPt < 0.) m_minPt = 500.0;
1323  break;
1324  case CutLevel::HILoose:
1325  // HILoose is similar to MinBias, but not identical
1326  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1327  if (overwrite || m_maxAbsEta >= LOCAL_MAX_DOUBLE) m_maxAbsEta = 2.5;
1328  if (overwrite || m_useMinBiasInnermostLayersCut >= 0) m_useMinBiasInnermostLayersCut = 1;
1329  if (overwrite || m_minNPixelHits < 0) m_minNPixelHits = 1;
1330  if (overwrite || (m_vecPtCutoffsForSctHitsCut.empty()
1331  && m_vecMinNSctHitsAbovePt.empty())) {
1332  m_vecPtCutoffsForSctHitsCut = std::vector<double>({0.0, 300.0, 400.0});
1333  m_vecMinNSctHitsAbovePt = std::vector<int>({2, 4, 6});
1334  }
1335  if (overwrite || m_maxD0 >= LOCAL_MAX_DOUBLE) m_maxD0 = 1.5;
1336  if (overwrite || m_maxZ0SinTheta >= LOCAL_MAX_DOUBLE) m_maxZ0SinTheta = 1.5;
1337  break;
1338  case CutLevel::HITight:
1339  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1340  // HITight is like HILoose but we require 8 SCT hits and 2 pixel hits
1341  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1342  if (overwrite || m_maxAbsEta >= LOCAL_MAX_DOUBLE) m_maxAbsEta = 2.5;
1343  if (overwrite || m_useMinBiasInnermostLayersCut >= 0) m_useMinBiasInnermostLayersCut = 1;
1344  if (overwrite || m_minNPixelHits < 0) m_minNPixelHits = 2;
1345  if (overwrite || (m_vecPtCutoffsForSctHitsCut.empty()
1346  && m_vecMinNSctHitsAbovePt.empty())) {
1347  m_vecPtCutoffsForSctHitsCut = std::vector<double>({0.0, 300.0, 400.0});
1348  m_vecMinNSctHitsAbovePt = std::vector<int>({4, 6, 8});
1349  }
1350  if (overwrite || m_maxD0 >= LOCAL_MAX_DOUBLE) m_maxD0 = 1.0;
1351  if (overwrite || m_maxZ0SinTheta >= LOCAL_MAX_DOUBLE) m_maxZ0SinTheta = 1.0;
1352  if (overwrite || m_maxChiSqperNdf >= LOCAL_MAX_DOUBLE) m_maxChiSqperNdf = 6.0;
1353  break;
1354  case CutLevel::HILooseOptimized:
1355  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1356  if (overwrite || m_maxAbsEta >= LOCAL_MAX_DOUBLE) m_maxAbsEta = 2.5;
1357  if (overwrite || m_maxNPixelHoles >= LOCAL_MAX_INT) m_maxNPixelHoles = 0;
1358  if (overwrite || m_useMinBiasInnermostLayersCut >= 0) m_useMinBiasInnermostLayersCut = 1;
1359  if (overwrite || (m_vecEtaCutoffsForZ0SinThetaCut.empty() &&
1360  m_vecPtCutoffsForZ0SinThetaCut.empty() &&
1361  m_vecvecMaxZ0SinThetaAboveEtaPt.empty())){
1362  m_vecEtaCutoffsForZ0SinThetaCut = std::vector<double>({0.0, 1.1, 1.6, 2.0});
1363  m_vecPtCutoffsForZ0SinThetaCut =
1364  std::vector<double>({500, 600, 700, 800, 900, 1000, 1500,
1365  2000, 2500, 3000, 5000, 8000, 12000});
1366  m_vecvecMaxZ0SinThetaAboveEtaPt =
1367  std::vector<std::vector<double>>({{2.10, 2.15, 6.00, 5.00, 3.10, 2.00, 1.75, 1.60, 1.43, 1.40, 1.05, 0.65, 0.60},
1368  {1.44, 1.47, 1.50, 1.55, 1.62, 1.45, 1.45, 1.78, 1.73, 1.50, 1.20, 0.97, 0.53},
1369  {1.40, 1.45, 1.50, 1.46, 1.41, 1.37, 1.25, 1.50, 1.50, 1.36, 1.10, 0.85, 0.52},
1370  {1.51, 1.70, 1.70, 1.71, 1.71, 1.53, 1.54, 1.49, 1.36, 1.20, 0.95, 0.60, 0.55}});
1371  }
1372  if (overwrite || (m_vecEtaCutoffsForD0Cut.empty() &&
1373  m_vecPtCutoffsForD0Cut.empty() &&
1374  m_vecvecMaxD0AboveEtaPt.empty())){
1375  m_vecEtaCutoffsForD0Cut = std::vector<double>({0.0, 1.1, 1.6, 2.0});
1376  m_vecPtCutoffsForD0Cut =
1377  std::vector<double>({500, 600, 700, 800, 900, 1000, 1500,
1378  2000, 2500, 3000, 5000, 8000, 12000});
1379  m_vecvecMaxD0AboveEtaPt =
1380  std::vector<std::vector<double>>({{0.81, 0.90, 0.94, 0.92, 0.90, 0.75, 0.65, 0.63, 0.62, 0.60, 0.63, 0.50, 0.55},
1381  {1.00, 0.98, 0.98, 0.92, 0.90, 0.69, 0.67, 0.86, 0.88, 0.88, 0.88, 0.87, 1.06},
1382  {1.19, 1.15, 1.10, 1.08, 1.03, 0.94, 0.85, 0.97, 0.97, 0.96, 0.95, 0.92, 1.04},
1383  {1.33, 1.23, 1.21, 1.15, 1.15, 1.07, 0.94, 0.97, 0.97, 0.97, 0.98, 1.10, 1.10}});
1384  }
1385  break;
1386  case CutLevel::HITightOptimized:
1387  setCutLevelPrivate(CutLevel::NoCut, overwrite);
1388  if (overwrite || m_maxAbsEta >= LOCAL_MAX_DOUBLE) m_maxAbsEta = 2.5;
1389  if (overwrite || m_maxNPixelHoles >= LOCAL_MAX_INT) m_maxNPixelHoles = 0;
1390  if (overwrite || m_useMinBiasInnermostLayersCut >= 0) m_useMinBiasInnermostLayersCut = 1;
1391  if (overwrite || (m_vecEtaCutoffsForZ0SinThetaCut.empty() &&
1392  m_vecPtCutoffsForZ0SinThetaCut.empty() &&
1393  m_vecvecMaxZ0SinThetaAboveEtaPt.empty())){
1394  m_vecEtaCutoffsForZ0SinThetaCut = std::vector<double>({0.0, 1.1, 1.6, 2.0});
1395  m_vecPtCutoffsForZ0SinThetaCut = std::vector<double>({500, 600, 700, 800, 900, 1000, 1500,
1396  2000, 2500, 3000, 5000, 8000, 12000});
1397  m_vecvecMaxZ0SinThetaAboveEtaPt =
1398  std::vector<std::vector<double>>({{0.62, 0.70, 0.82, 0.87, 0.74, 0.61, 0.50, 0.48, 0.46, 0.45, 0.30, 0.24, 0.23},
1399  {0.51, 0.53, 0.53, 0.53, 0.52, 0.43, 0.28, 0.27, 0.28, 0.30, 0.24, 0.22, 0.13},
1400  {0.91, 0.89, 0.87, 0.55, 0.59, 0.37, 0.39, 0.31, 0.34, 0.35, 0.30, 0.30, 0.20},
1401  {0.76, 0.71, 0.69, 0.48, 0.48, 0.47, 0.46, 0.42, 0.38, 0.32, 0.28, 0.20, 0.15}});
1402  }
1403  if (overwrite || (m_vecEtaCutoffsForD0Cut.empty() &&
1404  m_vecPtCutoffsForD0Cut.empty() &&
1405  m_vecvecMaxD0AboveEtaPt.empty())){
1406  m_vecEtaCutoffsForD0Cut = std::vector<double>({0.0, 1.1, 1.6, 2.0});
1407  m_vecPtCutoffsForD0Cut = std::vector<double>({500, 600, 700, 800, 900, 1000, 1500,
1408  2000, 2500, 3000, 5000, 8000, 12000});
1409  m_vecvecMaxD0AboveEtaPt =
1410  std::vector<std::vector<double>>({{0.34, 0.39, 0.47, 0.49, 0.55, 0.47, 0.44, 0.21, 0.19, 0.17, 0.12, 0.14, 0.15},
1411  {0.32, 0.32, 0.33, 0.33, 0.33, 0.27, 0.16, 0.15, 0.13, 0.15, 0.13, 0.16, 0.20},
1412  {0.95, 0.91, 0.88, 0.35, 0.37, 0.24, 0.26, 0.22, 0.23, 0.24, 0.19, 0.19, 0.23},
1413  {0.68, 0.67, 0.65, 0.42, 0.42, 0.36, 0.35, 0.31, 0.27, 0.26, 0.27, 0.28, 0.30}});
1414  }
1415  if (overwrite || (m_vecEtaCutoffsForSctHolesCut.empty() &&
1416  m_vecPtCutoffsForSctHolesCut.empty() &&
1417  m_vecvecMaxSctHolesAboveEtaPt.empty())){
1418  m_vecEtaCutoffsForSctHolesCut = std::vector<double>({0.0, 1.1, 1.6, 2.0});
1419  m_vecPtCutoffsForSctHolesCut = std::vector<double>({500, 600, 700, 800, 900, 1000, 1500,
1420  2000, 2500, 3000, 5000, 8000, 12000});
1421  m_vecvecMaxSctHolesAboveEtaPt =
1422  std::vector<std::vector<double>>({{0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1},
1423  {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1},
1424  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
1425  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}});
1426  }
1427  if (overwrite || (m_vecEtaCutoffsForSctHitsPlusDeadCut.empty() &&
1428  m_vecPtCutoffsForSctHitsPlusDeadCut.empty() &&
1429  m_vecvecMinSctHitsPlusDeadAboveEtaPt.empty())){
1430  m_vecEtaCutoffsForSctHitsPlusDeadCut = std::vector<double>({0.0, 1.1, 1.6, 2.0});
1431  m_vecPtCutoffsForSctHitsPlusDeadCut = std::vector<double>({500, 600, 700, 800, 900, 1000, 1500,
1432  2000, 2500, 3000, 5000, 8000, 12000});
1433  m_vecvecMinSctHitsPlusDeadAboveEtaPt =
1434  std::vector<std::vector<double>>({{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1435  {0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 0, 0, 0},
1436  {8, 8, 8, 7, 7, 6, 6, 6, 6, 6, 0, 0, 0},
1437  {7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}});
1438  }
1439  break;
1440  default:
1441  ATH_MSG_ERROR("CutLevel not recognized. Cut selection will remain unchanged.");
1442  break;
1443  }
1444 }
1445 
1446 // initialize the map from strings to cut levels
1447 const std::unordered_map<std::string, InDet::CutLevel>
1449  {
1450  {"NoCut", InDet::CutLevel::NoCut},
1451  {"Loose", InDet::CutLevel::Loose},
1452  {"LoosePrimary", InDet::CutLevel::LoosePrimary},
1453  {"TightPrimary", InDet::CutLevel::TightPrimary},
1454  {"LooseMuon", InDet::CutLevel::LooseMuon},
1455  {"LooseElectron", InDet::CutLevel::LooseElectron},
1456  {"LooseTau", InDet::CutLevel::LooseTau},
1457  {"MinBias", InDet::CutLevel::MinBias},
1458  {"HILoose", InDet::CutLevel::HILoose},
1459  {"HITight", InDet::CutLevel::HITight},
1460  {"HILooseOptimized", InDet::CutLevel::HILooseOptimized},
1461  {"HITightOptimized", InDet::CutLevel::HITightOptimized}
1462  };
checkCorrelInHIST.getSummary
def getSummary(histos, correls, fractionNonZero)
Definition: checkCorrelInHIST.py:243
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
xAOD::numberOfPixelHoles
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
Definition: TrackingPrimitives.h:262
LikeEnum::Loose
@ Loose
Definition: LikelihoodEnums.h:12
Trk::Vertex
Definition: Tracking/TrkEvent/VxVertex/VxVertex/Vertex.h:26
InDetAccessor
Definition: InDetTrackSelectionTool.h:33
CalculateHighPtTerm.pT
pT
Definition: ICHEP2016/CalculateHighPtTerm.py:57
python.ConfigText_unitTest.checkOrder
checkOrder
Definition: ConfigText_unitTest.py:513
InDet::InDetTrackSelectionTool::getAcceptInfo
virtual const asg::AcceptInfo & getAcceptInfo() const override
Get an object describing the "selection steps" of the tool.
Definition: InDetTrackSelectionTool.cxx:989
Check.h
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
xAOD::numberOfSCTSharedHits
@ numberOfSCTSharedHits
number of SCT hits shared by several tracks [unit8_t].
Definition: TrackingPrimitives.h:273
InDet::InDetTrackSelectionTool::accept
virtual asg::AcceptData accept(const xAOD::IParticle *) const override
Get the decision using a generic IParticle pointer.
Definition: InDetTrackSelectionTool.cxx:1006
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:558
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
make_coralServer_rep.opt
opt
Definition: make_coralServer_rep.py:19
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
xAOD::numberOfTRTXenonHits
@ numberOfTRTXenonHits
number of TRT hits on track in straws with xenon [unit8_t].
Definition: TrackingPrimitives.h:285
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
InDetAccessor::getSummarySum
uint8_t getSummarySum(const T_TrkHelper helper, const asg::AsgMessaging &msgHelper, std::array< xAOD::SummaryType, n_summary_types > sumTypes)
Definition: InDetAccessor.h:145
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
asg
Definition: DataHandleTestTool.h:28
test_pyathena.pt
pt
Definition: test_pyathena.py:11
InDet::InDetTrackSelectionTool::initialize
virtual StatusCode initialize() override
Function initialising the tool.
Definition: InDetTrackSelectionTool.cxx:103
InDetAccessor::TrackParticleHelper
Definition: InDetAccessor.h:50
InDetAccessor::getSiHitsTopBottom
std::tuple< uint8_t, uint8_t > getSiHitsTopBottom(const Trk::Track &track, const asg::AsgMessaging &msgHelper)
Definition: InDetAccessor.cxx:11
athena.value
value
Definition: athena.py:124
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:260
xAOD::expectInnermostPixelLayerHit
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
Definition: TrackingPrimitives.h:237
xAOD::numberOfTRTHits
@ numberOfTRTHits
number of TRT hits [unit8_t].
Definition: TrackingPrimitives.h:276
python.RatesEmulationExample.lock
lock
Definition: RatesEmulationExample.py:148
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
InDet::InDetTrackSelectionTool::s_mapCutLevel
static const std::unordered_map< std::string, CutLevel > s_mapCutLevel
Definition: InDetTrackSelectionTool.h:359
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:560
InDet::InDetTrackSelectionTool::setupCuts
StatusCode setupCuts(std::map< std::string, std::vector< std::function< bool(Trk_Helper helper, const asg::AsgMessaging &msgHelper)> > > &trackCuts)
Definition: InDetTrackSelectionTool.cxx:180
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
ParamDefs.h
TauGNNUtils::Variables::Scalar::absEta
bool absEta(const xAOD::TauJet &tau, float &out)
Definition: TauGNNUtils.cxx:107
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
xAOD::numberOfTRTHighThresholdHits
@ numberOfTRTHighThresholdHits
number of TRT hits which pass the high threshold (only xenon counted) [unit8_t].
Definition: TrackingPrimitives.h:279
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
python.SystemOfUnits.MeV
float MeV
Definition: SystemOfUnits.py:172
Track.h
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:115
xAOD::TrackParticle
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Definition: Event/xAOD/xAODTracking/xAODTracking/TrackParticle.h:13
InDetAccessor.h
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
xAOD::numberOfTRTHighThresholdOutliers
@ numberOfTRTHighThresholdOutliers
number of TRT high threshold outliers (only xenon counted) [unit8_t].
Definition: TrackingPrimitives.h:282
InDetAccessor::getEProbabilityHT
float getEProbabilityHT(const Trk_Helper &helper, const asg::AsgMessaging &msgHelper)
InDet::InDetTrackSelectionTool::setCutLevelPrivate
void setCutLevelPrivate(InDet::CutLevel level, Bool_t overwrite=true)
Definition: InDetTrackSelectionTool.cxx:1166
xAOD::numberOfPixelSharedHits
@ numberOfPixelSharedHits
number of Pixel all-layer hits shared by several tracks [unit8_t].
Definition: TrackingPrimitives.h:263
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::expectNextToInnermostPixelLayerHit
@ expectNextToInnermostPixelLayerHit
Do we expect a 1st-layer barrel hit for this track?
Definition: TrackingPrimitives.h:248
InDetAccessor::getFitChiSquare
double getFitChiSquare(const Trk_Helper &helper, const asg::AsgMessaging &msgHelper)
asg::AcceptInfo
Definition: AcceptInfo.h:28
ParticleGun_EoverP_Config.momentum
momentum
Definition: ParticleGun_EoverP_Config.py:63
sqr
#define sqr(t)
Definition: PolygonTriangulator.cxx:110
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
BindingsTest.cut
cut
This script demonstrates how to call a C++ class from Python Also how to use PyROOT is shown.
Definition: BindingsTest.py:13
plotBeamSpotVert.cuts
string cuts
Definition: plotBeamSpotVert.py:92
InDetTrackSelectionTool.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
plotting.yearwise_luminosity_vs_mu.bins
bins
Definition: yearwise_luminosity_vs_mu.py:30
TrackSummary.h
Trk::ParametersBase
Definition: ParametersBase.h:55
xAOD::numberOfSCTHoles
@ numberOfSCTHoles
number of SCT holes [unit8_t].
Definition: TrackingPrimitives.h:271
InDetAccessor::getNumberOfUsedHitsdEdx
Int_t getNumberOfUsedHitsdEdx(Trk_Helper &helper, const asg::AsgMessaging &msgHelper)
InDet::InDetTrackSelectionTool::setCutLevel
virtual void setCutLevel(InDet::CutLevel level, Bool_t overwrite=true) override __attribute__((deprecated("For consistency with the athena interface
Function to set the cut level within standalone ROOT.
Definition: InDetTrackSelectionTool.cxx:1151
xAOD::numberOfNextToInnermostPixelLayerHits
@ numberOfNextToInnermostPixelLayerHits
these are the hits in the 1st pixel barrel layer
Definition: TrackingPrimitives.h:249
InDetAccessor::getFitNDoF
double getFitNDoF(const TrkHelper &helper, const asg::AsgMessaging &msgHelper)
InDet::InDetTrackSelectionTool::finalize
virtual StatusCode finalize() override
Function finalizing the tool.
Definition: InDetTrackSelectionTool.cxx:958
Trk::TrackSummary
A summary of the information contained by a track.
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:287
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
InDetAccessor::getNumberOfIBLOverflowsdEdx
Int_t getNumberOfIBLOverflowsdEdx(Trk_Helper &helper, const asg::AsgMessaging &msgHelper)
asg::AsgMessaging
Class mimicking the AthMessaging class from the offline software.
Definition: AsgMessaging.h:40
Ringer::NoCut
@ NoCut
Definition: RingerSelectorToolsEnums.h:121
Vertex.h
xAOD::numberOfTRTOutliers
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
Definition: TrackingPrimitives.h:277
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
Prompt::Def::Pt
@ Pt
Definition: VarHolder.h:76
a
TList * a
Definition: liststreamerinfos.cxx:10
asg::AcceptData::setCutResult
void setCutResult(const std::string &cutName, bool cutResult)
Set the result of a cut, based on the cut name (safer)
Definition: AcceptData.h:134
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
InDetAccessor::TrkTrackHelper
Definition: InDetAccessor.h:71
asg::AcceptData::getCutResult
bool getCutResult(const std::string &cutName) const
Get the result of a cut, based on the cut name (safer)
Definition: AcceptData.h:98
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::numberOfSCTDeadSensors
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
Definition: TrackingPrimitives.h:274
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
xAOD::numberOfInnermostPixelLayerSharedHits
@ numberOfInnermostPixelLayerSharedHits
number of Pixel 0th layer barrel hits shared by several tracks.
Definition: TrackingPrimitives.h:240
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:269
str
Definition: BTagTrackIpAccessor.cxx:11
xAOD::numberOfPixelDeadSensors
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
Definition: TrackingPrimitives.h:267
top
@ top
Definition: TruthClasses.h:64
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
calibdata.copy
bool copy
Definition: calibdata.py:26
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
xAOD::numberOfSCTDoubleHoles
@ numberOfSCTDoubleHoles
number of Holes in both sides of a SCT module [unit8_t].
Definition: TrackingPrimitives.h:272
FitQuality.h
asg::AcceptData
Definition: AcceptData.h:30
columnar::operator()
decltype(auto) operator()(ObjectId< CI, CM > id) const noexcept
Definition: ColumnAccessor.h:173
asg::AsgTool::initialize
virtual StatusCode initialize()
Dummy implementation of the initialisation function.
Definition: AsgTool.h:133
TrackingPrimitives.h
xAOD::numberOfInnermostPixelLayerHits
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer
Definition: TrackingPrimitives.h:238
InDet::CutLevel
CutLevel
Definition: IInDetTrackSelectionTool.h:40
SCT_Monitoring::summary
@ summary
Definition: SCT_MonitoringNumbers.h:65