21#include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
35 declareInterface<ITrackSelectorTool>(
this);
43 InDet::BeamSpotData temp(evt->beamStatus(), evt->beamPosX(), evt->beamPosY(), evt->beamPosZ(),
44 evt->beamPosSigmaX(), evt->beamPosSigmaY(), evt->beamPosSigmaZ(),
45 evt->beamTiltXZ(), evt->beamTiltYZ(), evt->beamPosSigmaXY());
48 ATH_MSG_WARNING(
" Cannot get beamSpot center from xAOD::EventInfo. Using (0,0,0)... " );
56 ATH_MSG_WARNING(
" Cannot get beamSpot center from BeamSpotData. Using (0,0,0)... " );
70 ATH_MSG_DEBUG(
"No TrackSummaryTool set. OK if running on AOD.");
76 ATH_MSG_DEBUG(
"No TrackParticleCreatorTool set but shared hit selection used. OK if running on AOD.");
86 ATH_MSG_ERROR(
" Eta dependent cut on number of TRT hits requested but TrtDCCutTool not specified. ");
87 return StatusCode::FAILURE;
90 return StatusCode::FAILURE;
94 ATH_MSG_DEBUG(
"Using eta dependent cut on number of TRT hits.");
97 ATH_MSG_DEBUG(
"Using eta dependent cut on number of TRT hits + outliers.");
110 ATH_MSG_ERROR(
"Number of cuts DOES NOT match the number of intervals to apply. Please check jobOptions. ");
111 return StatusCode::FAILURE;
113 ATH_MSG_ERROR(
"Zero vectors for number of cuts and pt intervals. Please check jobOptions. ");
114 return StatusCode::FAILURE;
117 return StatusCode::SUCCESS;
124 return StatusCode::SUCCESS;
131 const EventContext& ctx = Gaudi::Hive::currentContext();
138 if (!preselectionDecision) {
139 ATH_MSG_DEBUG(
"Track rejected because of preselection decision!");
143 ATH_MSG_DEBUG(
" Preselection was requested but cannot be made since no Perigee in Track is available. This is not an error." );
147 if (myVertex==
nullptr) {
152 for (
const auto *i : *track.trackParameters()){
153 if ( i->covariance() && !
dynamic_cast<const Trk::Perigee*
>(i)) {
161 firstmeaspar=track.perigeeParameters();
163 ATH_MSG_WARNING(
" First measurment on track is missing. Using perigee Parameters, but they are missing: 0 pointer! Track selection failed " );
165 if (myVertex!=vertex) {
177 track.info().particleHypothesis() ).release();
178 const Trk::Perigee* extrapolatedPerigee = extrapolatedParameters ?
dynamic_cast<const Trk::Perigee*
>(extrapolatedParameters) :
nullptr;
179 if (!extrapolatedPerigee || !extrapolatedPerigee->covariance() ) {
181 if (extrapolatedParameters) {
182 ATH_MSG_WARNING(
"The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" );
183 delete extrapolatedParameters;
184 extrapolatedParameters=
nullptr;
190 bool dec =
decision(extrapolatedPerigee, recVertex ? &recVertex->covariancePosition() :
nullptr );
191 if (myVertex!=vertex) {
195 bool isInTrtAcceptance=
true;
197 isInTrtAcceptance=
false;
199 if (extrapolatedPerigee!=track.perigeeParameters()) {
200 delete extrapolatedPerigee;
201 extrapolatedPerigee=
nullptr;
204 ATH_MSG_DEBUG(
"Track rejected because of perigee parameters!");
209 if (TrkQuality==
nullptr) {
210 ATH_MSG_WARNING(
"Requested cut on track quality was not possible. Track has no FitQuality object attached. Selection failed." );
220 std::unique_ptr<Trk::TrackSummary> summaryUniquePtr;
224 summary = summaryUniquePtr.get();
226 if (
nullptr==summary ) {
227 ATH_MSG_FATAL(
"Track preselection: cannot create a track summary (but useTrackSummary is true). Selection failed." );
234 ATH_MSG_FATAL(
"Track preselection: cannot create a track particle (but useSharedHitInfo is true). Selection failed." );
240 nHitTrt =
m_trtDCTool->minNumberDCs( (*track.trackParameters())[0] );
250 nHitTrtPlusOutliers =
m_trtDCTool->minNumberDCs( (*track.trackParameters())[0] );
259 nHitTrt, nHitTrtPlusOutliers)) {
270 const EventContext& ctx = Gaudi::Hive::currentContext();
278 if (!preselectionDecision) {
279 ATH_MSG_DEBUG(
"Track rejected because of preselection decision!");
283 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." );
285 bool isInTrtAcceptance=
true;
287 isInTrtAcceptance=
false;
291 if (TrkQuality==
nullptr) {
292 ATH_MSG_WARNING(
"Requested cut on track quality was not possible. TrackParticleBase has no FitQuality object attached. Selection failed." );
302 if (
nullptr==summary ) {
303 ATH_MSG_WARNING(
"Track preselection: cannot create a track summary (but useTrackSummary is true). Selection failed." );
309 ATH_MSG_ERROR(
"Use of InDetDetailedTrackSelectorTool with Trk::TrackParticleBase and useSharedHitInfo is not supported");
315 nHitTrt =
m_trtDCTool->minNumberDCs( (track.trackParameters())[0] );
324 nHitTrtPlusOutliers =
m_trtDCTool->minNumberDCs( (track.trackParameters())[0] );
332 if ((!perigeeBeforeExtrapolation) or
334 nHitTrt, nHitTrtPlusOutliers))) {
340 if (vertex==
nullptr) {
345 for (
const auto *i : track.trackParameters()) {
346 if (i->covariance() &&
353 if (!extrapolatedPerigee || !extrapolatedPerigee->covariance() ) {
354 ATH_MSG_DEBUG(
" Track Paraemters at first measurement not found. Perigee not found. Cannot do TrackSelection..." );
355 if (myVertex!=vertex) {
362 firstmeaspar=&(track.definingParameters());
374 extrapolatedPerigee = extrapolatedParameters ?
dynamic_cast<const Trk::Perigee*
>(extrapolatedParameters) :
nullptr;
375 if (extrapolatedPerigee==
nullptr || !extrapolatedPerigee->covariance()) {
377 if (extrapolatedParameters) {
378 ATH_MSG_WARNING(
"The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" );
379 delete extrapolatedParameters;
380 extrapolatedParameters =
nullptr;
383 if (extrapolatedParameters)
ATH_MSG_VERBOSE (
"Result: " << *extrapolatedParameters);
385 bool dec =
decision(extrapolatedPerigee, recVertex ? &recVertex->covariancePosition() :
nullptr );
386 if (myVertex!=vertex) {
390 if (extrapolatedPerigee!=&(track.definingParameters())) {
391 delete extrapolatedPerigee;
392 extrapolatedPerigee=
nullptr;
395 ATH_MSG_DEBUG(
"Track rejected because of perigee parameters!");
403 if(vertex)
return vertex->position();
407 InDet::BeamSpotData temp(evt->beamStatus(), evt->beamPosX(), evt->beamPosY(), evt->beamPosZ(),
408 evt->beamPosSigmaX(), evt->beamPosSigmaY(), evt->beamPosSigmaZ(),
409 evt->beamTiltXZ(), evt->beamTiltYZ(), evt->beamPosSigmaXY());
410 return temp.beamVtx().position();
412 ATH_MSG_WARNING(
" Cannot get beamSpot center from xAOD::EventInfo. Using (0,0,0)... " );
417 if (beamSpotHandle.
isValid()) {
418 return beamSpotHandle->beamVtx().position();
420 ATH_MSG_WARNING(
" Cannot get beamSpot center from BeamSpotData. Using (0,0,0)... " );
430 const EventContext& ctx = Gaudi::Hive::currentContext();
437 ATH_MSG_DEBUG(
"Track rejected because of preselection decision!");
458 nHitTrtPlusOutliers =
m_trtDCTool->minNumberDCs( &perigee );
480 ATH_MSG_DEBUG(
"Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ;
487 ATH_MSG_DEBUG(
"Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ;
499 ATH_MSG_DEBUG(
"and track rejected because at least one hit is expected in the innermost pixel layer") ;
501 }
else ATH_MSG_DEBUG(
"recovered track as no b-layer expected") ;
554 ATH_MSG_DEBUG(
"Track rejected because of nHitTrt "<<nh<<
" < "<<nHitTrt);
559 if (nhh<nHitTrtPlusOutliers) {
560 ATH_MSG_DEBUG(
"Track rejected because of nHitTrtPlusOutliers "<<nhh<<
" < "<<nHitTrtPlusOutliers);
589 if (nheh>1.) nheh=1.;
627 perigee,perigeeSurface,
629 const Trk::Perigee* extrapolatedPerigee = extrapolatedParameters ?
dynamic_cast<const Trk::Perigee*
>(extrapolatedParameters) :
nullptr;
630 if (extrapolatedPerigee==
nullptr) {
631 ATH_MSG_WARNING(
"Extrapolation to the vertex failed: " << perigeeSurface << std::endl << perigee );
632 if (extrapolatedParameters!=
nullptr) {
633 ATH_MSG_WARNING(
"The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" );
634 delete extrapolatedParameters;
635 extrapolatedParameters=
nullptr;
642 const AmgSymMatrix(3)& vertexError = vertex->covariancePosition();
643 dec =
decision(extrapolatedPerigee,&vertexError);
645 dec =
decision(extrapolatedPerigee,
nullptr);
648 delete extrapolatedPerigee;
651 ATH_MSG_DEBUG(
"Track rejected because of perigee parameters!");
663 if(
nullptr==track || !track->covariance()) {
664 ATH_MSG_WARNING(
"Decision on measured perigee: Zero pointer to measured perigee passed. Selection failed." );
668 const AmgVector(5)& perigeeParms = track->parameters();
671 const EventContext& ctx = Gaudi::Hive::currentContext();
674 if (fieldCondObj ==
nullptr) {
686 double p = std::fabs(1./perigeeParms[
Trk::qOverP]);
691 double pt = p*std::sin(perigeeParms[
Trk::theta]);
725 double sinTheta = std::sin(perigeeParms[
Trk::theta]);
726 double cosTheta = std::cos(perigeeParms[
Trk::theta]);
727 double d0wrtPriVtx = perigeeParms[
Trk::d0];
728 double deltaZ = perigeeParms[
Trk::z0];
729 double z0wrtPriVtx = deltaZ*sinTheta;
730 double testtrackSigD0 = sqrt( (*track->covariance())(
Trk::d0,
Trk::d0) );
731 double testtrackSigZ0 = sqrt( (*track->covariance())(
Trk::z0,
Trk::z0) );
734 double trackPhi = perigeeParms[
Trk::phi];
735 double dIPdx = std::sin(trackPhi);
736 double dIPdy = -std::cos(trackPhi);
737 double DD0 = testtrackSigD0*testtrackSigD0;
739 if (covariancePosition) {
740 double DXX = dIPdx*dIPdx* (*covariancePosition)(0,0);
741 double DYY = dIPdy*dIPdy* (*covariancePosition)(1,1);
742 double DXY = 2.*dIPdx*dIPdy* (*covariancePosition)(0,1);
743 newD0Err = DD0 + DXX + DYY + DXY;
748 double d0ErrwrtPriVtx = (newD0Err>0 ? sqrt(newD0Err) : -10e-9);
750 if (d0ErrwrtPriVtx<0) {
751 ATH_MSG_WARNING(
" error on d0 is negative: numeric error... (not expected. please report!)" );
764 double dZIPdTheta = deltaZ*cosTheta;
765 double dZIPdz0 = sinTheta;
766 double dZIPdzV = -sinTheta;
767 double DTheta2 = dZIPdTheta*dZIPdTheta*testtrackSigTh*testtrackSigTh;
768 double DZ02 = dZIPdz0*dZIPdz0*testtrackSigZ0*testtrackSigZ0;
769 double DThetaZ0 = 2.*dZIPdTheta*dZIPdz0*(*track->covariance())(
Trk::theta,
Trk::z0);
771 if (covariancePosition) {
772 double DZV2 = dZIPdzV*dZIPdzV* (*covariancePosition)(2,2);
773 newZ0Err = DTheta2 + DZ02 + DZV2 + DThetaZ0;
775 newZ0Err = DTheta2 + DZ02 + DThetaZ0;
778 double z0ErrwrtPriVtx = (newZ0Err>0 ? sqrt(newZ0Err) : -10e-9);
780 if (z0ErrwrtPriVtx<0) {
781 ATH_MSG_WARNING(
" error on z0 is negative: numeric error... (not expected. please report!)" );
792 if (std::fabs(track->momentum().eta())>
m_etaMax) {
793 ATH_MSG_DEBUG(
"Track rejected because of fabs(eta) " << std::fabs(track->momentum().eta()) <<
" > " <<
m_etaMax);
803 if(
nullptr == trkQuality) {
804 ATH_MSG_WARNING(
"Null FitQuality pointer passed. No track Quality cut possible. Selection failed." );
814 if(ndf>0 &&
chi2>=0.) {
815 Genfun::CumulativeChiSquare myCumulativeChiSquare(ndf);
816 proba = 1.-myCumulativeChiSquare(
chi2);
844 bool useSharedHitInfo,
848 const int nHitTrtPlusOutliers)
const
850 if (summary==
nullptr) {
851 ATH_MSG_WARNING(
"Null TrackSummary pointer passed. Selection failed." );
869 if (nhp < 0) nhp = 0;
872 if (nhs < 0) nhs = 0;
875 if (ndhs < 0) ndhs = 0;
883 const AmgVector(5)& perigeeParms = track->parameters();
884 double p = std::fabs(1./perigeeParms[
Trk::qOverP]);
885 double pt = p*std::sin(perigeeParms[
Trk::theta]);
890 ATH_MSG_DEBUG(
"Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ;
897 ATH_MSG_DEBUG(
"Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ;
910 ATH_MSG_DEBUG(
"and no blayer tool configured, so will not try to recover track");
913 ATH_MSG_DEBUG(
"and track rejected because at least one hit is expected in the innermost pixel layer") ;
915 }
else ATH_MSG_DEBUG(
"recovered track as no b-layer expected") ;
981 ATH_MSG_DEBUG(
"Track rejected because of nHitTrt "<<nh<<
" < "<<nHitTrt);
987 if (nhh<nHitTrtPlusOutliers) {
988 ATH_MSG_DEBUG(
"Track rejected because of nHitTrtPlusOutliers "<<nhh<<
" < "<<nHitTrtPlusOutliers);
993 if (nhthits<0) nhthits=0;
1000 if (nhthitsWithOutliers<0) nhthitsWithOutliers=0;
1006 if (summary->get( Trk :: numberOfTRTHits )>0) {
1015 if ( summary->get( Trk :: numberOfTRTHits ) + summary->get( Trk :: numberOfTRTOutliers ) > 0 ) {
1018 if(nheh<0.) nheh=0.;
1019 if (nheh>1.) nheh=1.;
1027 if (useSharedHitInfo) {
1029 ATH_MSG_DEBUG(
"Track rejected because xAOD::TrackParticle not available");
1034 if(nbs < 0) nbs = 0;
1042 if(nps < 0) nps = 0;
1049 if(nss < 0) nss = 0;
1055 int nst = nps + nss;
1069 const AmgVector(5)& perigeeParms = myPerigee.parameters();
1072 const EventContext& ctx = Gaudi::Hive::currentContext();
1075 if (fieldCondObj ==
nullptr) {
1084 ATH_MSG_DEBUG(
"Track rejected because of perigee qOverP == 0.");
1087 double p = std::fabs(1./perigeeParms[
Trk::qOverP]);
1092 double pt = p*std::sin(perigeeParms[
Trk::theta]);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define AmgSymMatrix(dim)
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
bool solenoidOn() const
status of the magnets
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
double chiSquared() const
returns the of the overall track fit
const Amg::Vector3D & momentum() const
Access method for the momentum.
Class describing the Line to which the Perigee refers to.
Trk::RecVertex inherits from Trk::Vertex.
A summary of the information contained by a track.
This class is a simplest representation of a vertex candidate.
const Amg::Vector3D & position() const
return position of vertex
float numberDoF() const
Returns the number of degrees of freedom of the overall track or vertex fit as float.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
float chiSquared() const
Returns the of the overall track fit.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, 3, 1 > Vector3D
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ numberOfSCTHits
number of SCT holes
@ numberOfPixelHits
number of pixel layers on track with absence of hits
@ numberOfTRTHighThresholdOutliers
number of dead TRT straws crossed
@ numberOfTRTOutliers
number of TRT holes
@ numberOfTRTHits
number of TRT outliers
@ numberOfInnermostPixelLayerHits
these are the hits in the 1st pixel layer
@ numberOfTRTHighThresholdHits
total number of TRT hits which pass the high threshold
@ numberOfSCTHoles
number of Holes in both sides of a SCT module
@ numberOfSCTDeadSensors
number of TRT hits
@ numberOfPixelHoles
number of pixels which have a ganged ambiguity.
@ numberOfPixelDeadSensors
number of pixel hits with broad errors (width/sqrt(12))
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
@ numberOfTRTHighThresholdOutliers
number of TRT high threshold outliers (only xenon counted) [unit8_t].
@ numberOfInnermostPixelLayerSharedHits
number of Pixel 0th layer barrel hits shared by several tracks.
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfSCTDeadSensors
number of dead SCT sensors crossed [unit8_t].
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfSCTDoubleHoles
number of Holes in both sides of a SCT module [unit8_t].
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfPixelSharedHits
number of Pixel all-layer hits shared by several tracks [unit8_t].
@ numberOfSCTSharedHits
number of SCT hits shared by several tracks [unit8_t].
@ numberOfTRTHighThresholdHits
number of TRT hits which pass the high threshold (only xenon counted) [unit8_t].
@ numberOfTRTOutliers
number of TRT outliers [unit8_t].
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
@ numberOfSCTHoles
number of SCT holes [unit8_t].