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;
135 if (!preselectionDecision) {
136 ATH_MSG_DEBUG(
"Track rejected because of preselection decision!");
140 ATH_MSG_DEBUG(
" Preselection was requested but cannot be made since no Perigee in Track is available. This is not an error." );
144 if (myVertex==
nullptr) {
145 myVertex =
getBeamSpot(Gaudi::Hive::currentContext());
149 for (
const auto *i : *track.trackParameters()){
150 if ( i->covariance() && !
dynamic_cast<const Trk::Perigee*
>(i)) {
158 firstmeaspar=track.perigeeParameters();
160 ATH_MSG_WARNING(
" First measurment on track is missing. Using perigee Parameters, but they are missing: 0 pointer! Track selection failed " );
162 if (myVertex!=vertex) {
174 track.info().particleHypothesis() ).release();
175 const Trk::Perigee* extrapolatedPerigee = extrapolatedParameters ?
dynamic_cast<const Trk::Perigee*
>(extrapolatedParameters) :
nullptr;
176 if (!extrapolatedPerigee || !extrapolatedPerigee->covariance() ) {
178 if (extrapolatedParameters) {
179 ATH_MSG_WARNING(
"The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" );
180 delete extrapolatedParameters;
181 extrapolatedParameters=
nullptr;
187 bool dec =
decision(extrapolatedPerigee, recVertex ? &recVertex->covariancePosition() :
nullptr );
188 if (myVertex!=vertex) {
192 bool isInTrtAcceptance=
true;
194 isInTrtAcceptance=
false;
196 if (extrapolatedPerigee!=track.perigeeParameters()) {
197 delete extrapolatedPerigee;
198 extrapolatedPerigee=
nullptr;
201 ATH_MSG_DEBUG(
"Track rejected because of perigee parameters!");
206 if (TrkQuality==
nullptr) {
207 ATH_MSG_WARNING(
"Requested cut on track quality was not possible. Track has no FitQuality object attached. Selection failed." );
217 std::unique_ptr<Trk::TrackSummary> summaryUniquePtr;
220 summaryUniquePtr =
m_trackSumTool->summary(Gaudi::Hive::currentContext(), track);
221 summary = summaryUniquePtr.get();
223 if (
nullptr==summary ) {
224 ATH_MSG_FATAL(
"Track preselection: cannot create a track summary (but useTrackSummary is true). Selection failed." );
231 ATH_MSG_FATAL(
"Track preselection: cannot create a track particle (but useSharedHitInfo is true). Selection failed." );
237 nHitTrt =
m_trtDCTool->minNumberDCs( (*track.trackParameters())[0] );
247 nHitTrtPlusOutliers =
m_trtDCTool->minNumberDCs( (*track.trackParameters())[0] );
256 nHitTrt, nHitTrtPlusOutliers)) {
272 if (!preselectionDecision) {
273 ATH_MSG_DEBUG(
"Track rejected because of preselection decision!");
277 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." );
279 bool isInTrtAcceptance=
true;
281 isInTrtAcceptance=
false;
285 if (TrkQuality==
nullptr) {
286 ATH_MSG_WARNING(
"Requested cut on track quality was not possible. TrackParticleBase has no FitQuality object attached. Selection failed." );
296 if (
nullptr==summary ) {
297 ATH_MSG_WARNING(
"Track preselection: cannot create a track summary (but useTrackSummary is true). Selection failed." );
303 ATH_MSG_ERROR(
"Use of InDetDetailedTrackSelectorTool with Trk::TrackParticleBase and useSharedHitInfo is not supported");
309 nHitTrt =
m_trtDCTool->minNumberDCs( (track.trackParameters())[0] );
318 nHitTrtPlusOutliers =
m_trtDCTool->minNumberDCs( (track.trackParameters())[0] );
326 if ((!perigeeBeforeExtrapolation) or
328 nHitTrt, nHitTrtPlusOutliers))) {
334 if (vertex==
nullptr) {
335 myVertex =
getBeamSpot(Gaudi::Hive::currentContext());
339 for (
const auto *i : track.trackParameters()) {
340 if (i->covariance() &&
347 if (!extrapolatedPerigee || !extrapolatedPerigee->covariance() ) {
348 ATH_MSG_DEBUG(
" Track Paraemters at first measurement not found. Perigee not found. Cannot do TrackSelection..." );
349 if (myVertex!=vertex) {
356 firstmeaspar=&(track.definingParameters());
368 extrapolatedPerigee = extrapolatedParameters ?
dynamic_cast<const Trk::Perigee*
>(extrapolatedParameters) :
nullptr;
369 if (extrapolatedPerigee==
nullptr || !extrapolatedPerigee->covariance()) {
371 if (extrapolatedParameters) {
372 ATH_MSG_WARNING(
"The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" );
373 delete extrapolatedParameters;
374 extrapolatedParameters =
nullptr;
377 if (extrapolatedParameters)
ATH_MSG_VERBOSE (
"Result: " << *extrapolatedParameters);
379 bool dec =
decision(extrapolatedPerigee, recVertex ? &recVertex->covariancePosition() :
nullptr );
380 if (myVertex!=vertex) {
384 if (extrapolatedPerigee!=&(track.definingParameters())) {
385 delete extrapolatedPerigee;
386 extrapolatedPerigee=
nullptr;
389 ATH_MSG_DEBUG(
"Track rejected because of perigee parameters!");
397 if(vertex)
return vertex->position();
401 InDet::BeamSpotData temp(evt->beamStatus(), evt->beamPosX(), evt->beamPosY(), evt->beamPosZ(),
402 evt->beamPosSigmaX(), evt->beamPosSigmaY(), evt->beamPosSigmaZ(),
403 evt->beamTiltXZ(), evt->beamTiltYZ(), evt->beamPosSigmaXY());
404 return temp.beamVtx().position();
406 ATH_MSG_WARNING(
" Cannot get beamSpot center from xAOD::EventInfo. Using (0,0,0)... " );
411 if (beamSpotHandle.
isValid()) {
412 return beamSpotHandle->beamVtx().position();
414 ATH_MSG_WARNING(
" Cannot get beamSpot center from BeamSpotData. Using (0,0,0)... " );
429 ATH_MSG_DEBUG(
"Track rejected because of preselection decision!");
450 nHitTrtPlusOutliers =
m_trtDCTool->minNumberDCs( &perigee );
472 ATH_MSG_DEBUG(
"Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ;
479 ATH_MSG_DEBUG(
"Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ;
491 ATH_MSG_DEBUG(
"and track rejected because at least one hit is expected in the innermost pixel layer") ;
493 }
else ATH_MSG_DEBUG(
"recovered track as no b-layer expected") ;
546 ATH_MSG_DEBUG(
"Track rejected because of nHitTrt "<<nh<<
" < "<<nHitTrt);
551 if (nhh<nHitTrtPlusOutliers) {
552 ATH_MSG_DEBUG(
"Track rejected because of nHitTrtPlusOutliers "<<nhh<<
" < "<<nHitTrtPlusOutliers);
581 if (nheh>1.) nheh=1.;
618 Gaudi::Hive::currentContext(),
619 perigee,perigeeSurface,
621 const Trk::Perigee* extrapolatedPerigee = extrapolatedParameters ?
dynamic_cast<const Trk::Perigee*
>(extrapolatedParameters) :
nullptr;
622 if (extrapolatedPerigee==
nullptr) {
623 ATH_MSG_WARNING(
"Extrapolation to the vertex failed: " << perigeeSurface << std::endl << perigee );
624 if (extrapolatedParameters!=
nullptr) {
625 ATH_MSG_WARNING(
"The return object of the extrapolator was not a perigee even if a perigeeSurface was used!" );
626 delete extrapolatedParameters;
627 extrapolatedParameters=
nullptr;
634 const AmgSymMatrix(3)& vertexError = vertex->covariancePosition();
635 dec =
decision(extrapolatedPerigee,&vertexError);
637 dec =
decision(extrapolatedPerigee,
nullptr);
640 delete extrapolatedPerigee;
643 ATH_MSG_DEBUG(
"Track rejected because of perigee parameters!");
655 if(
nullptr==track || !track->covariance()) {
656 ATH_MSG_WARNING(
"Decision on measured perigee: Zero pointer to measured perigee passed. Selection failed." );
660 const AmgVector(5)& perigeeParms = track->parameters();
663 const EventContext& ctx = Gaudi::Hive::currentContext();
666 if (fieldCondObj ==
nullptr) {
678 double p = std::fabs(1./perigeeParms[
Trk::qOverP]);
683 double pt = p*std::sin(perigeeParms[
Trk::theta]);
717 double sinTheta = std::sin(perigeeParms[
Trk::theta]);
718 double cosTheta = std::cos(perigeeParms[
Trk::theta]);
719 double d0wrtPriVtx = perigeeParms[
Trk::d0];
720 double deltaZ = perigeeParms[
Trk::z0];
721 double z0wrtPriVtx = deltaZ*sinTheta;
722 double testtrackSigD0 = sqrt( (*track->covariance())(
Trk::d0,
Trk::d0) );
723 double testtrackSigZ0 = sqrt( (*track->covariance())(
Trk::z0,
Trk::z0) );
726 double trackPhi = perigeeParms[
Trk::phi];
727 double dIPdx = std::sin(trackPhi);
728 double dIPdy = -std::cos(trackPhi);
729 double DD0 = testtrackSigD0*testtrackSigD0;
731 if (covariancePosition) {
732 double DXX = dIPdx*dIPdx* (*covariancePosition)(0,0);
733 double DYY = dIPdy*dIPdy* (*covariancePosition)(1,1);
734 double DXY = 2.*dIPdx*dIPdy* (*covariancePosition)(0,1);
735 newD0Err = DD0 + DXX + DYY + DXY;
740 double d0ErrwrtPriVtx = (newD0Err>0 ? sqrt(newD0Err) : -10e-9);
742 if (d0ErrwrtPriVtx<0) {
743 ATH_MSG_WARNING(
" error on d0 is negative: numeric error... (not expected. please report!)" );
756 double dZIPdTheta = deltaZ*cosTheta;
757 double dZIPdz0 = sinTheta;
758 double dZIPdzV = -sinTheta;
759 double DTheta2 = dZIPdTheta*dZIPdTheta*testtrackSigTh*testtrackSigTh;
760 double DZ02 = dZIPdz0*dZIPdz0*testtrackSigZ0*testtrackSigZ0;
761 double DThetaZ0 = 2.*dZIPdTheta*dZIPdz0*(*track->covariance())(
Trk::theta,
Trk::z0);
763 if (covariancePosition) {
764 double DZV2 = dZIPdzV*dZIPdzV* (*covariancePosition)(2,2);
765 newZ0Err = DTheta2 + DZ02 + DZV2 + DThetaZ0;
767 newZ0Err = DTheta2 + DZ02 + DThetaZ0;
770 double z0ErrwrtPriVtx = (newZ0Err>0 ? sqrt(newZ0Err) : -10e-9);
772 if (z0ErrwrtPriVtx<0) {
773 ATH_MSG_WARNING(
" error on z0 is negative: numeric error... (not expected. please report!)" );
784 if (std::fabs(track->momentum().eta())>
m_etaMax) {
785 ATH_MSG_DEBUG(
"Track rejected because of fabs(eta) " << std::fabs(track->momentum().eta()) <<
" > " <<
m_etaMax);
795 if(
nullptr == trkQuality) {
796 ATH_MSG_WARNING(
"Null FitQuality pointer passed. No track Quality cut possible. Selection failed." );
806 if(ndf>0 &&
chi2>=0.) {
807 Genfun::CumulativeChiSquare myCumulativeChiSquare(ndf);
808 proba = 1.-myCumulativeChiSquare(
chi2);
836 bool useSharedHitInfo,
840 const int nHitTrtPlusOutliers)
const
842 if (summary==
nullptr) {
843 ATH_MSG_WARNING(
"Null TrackSummary pointer passed. Selection failed." );
861 if (nhp < 0) nhp = 0;
864 if (nhs < 0) nhs = 0;
867 if (ndhs < 0) ndhs = 0;
875 const AmgVector(5)& perigeeParms = track->parameters();
876 double p = std::fabs(1./perigeeParms[
Trk::qOverP]);
877 double pt = p*std::sin(perigeeParms[
Trk::theta]);
882 ATH_MSG_DEBUG(
"Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ;
889 ATH_MSG_DEBUG(
"Track rejected because of Pt-Dependent SCT Hit cut (CAREFUL! Excludes dead modules)") ;
902 ATH_MSG_DEBUG(
"and no blayer tool configured, so will not try to recover track");
905 ATH_MSG_DEBUG(
"and track rejected because at least one hit is expected in the innermost pixel layer") ;
907 }
else ATH_MSG_DEBUG(
"recovered track as no b-layer expected") ;
973 ATH_MSG_DEBUG(
"Track rejected because of nHitTrt "<<nh<<
" < "<<nHitTrt);
979 if (nhh<nHitTrtPlusOutliers) {
980 ATH_MSG_DEBUG(
"Track rejected because of nHitTrtPlusOutliers "<<nhh<<
" < "<<nHitTrtPlusOutliers);
985 if (nhthits<0) nhthits=0;
992 if (nhthitsWithOutliers<0) nhthitsWithOutliers=0;
998 if (summary->get( Trk :: numberOfTRTHits )>0) {
1007 if ( summary->get( Trk :: numberOfTRTHits ) + summary->get( Trk :: numberOfTRTOutliers ) > 0 ) {
1010 if(nheh<0.) nheh=0.;
1011 if (nheh>1.) nheh=1.;
1019 if (useSharedHitInfo) {
1021 ATH_MSG_DEBUG(
"Track rejected because xAOD::TrackParticle not available");
1026 if(nbs < 0) nbs = 0;
1034 if(nps < 0) nps = 0;
1041 if(nss < 0) nss = 0;
1047 int nst = nps + nss;
1061 const AmgVector(5)& perigeeParms = myPerigee.parameters();
1064 const EventContext& ctx = Gaudi::Hive::currentContext();
1067 if (fieldCondObj ==
nullptr) {
1076 ATH_MSG_DEBUG(
"Track rejected because of perigee qOverP == 0.");
1079 double p = std::fabs(1./perigeeParms[
Trk::qOverP]);
1084 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
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].