13 using namespace InDet;
17 m_compatibilityAccessor(
"TrackCompatibility" ),
18 m_tracksAccessor(
"VxTrackAtVertex" )
21 declareInterface< JetFitterV0FinderTool >(
this);
26 std::string sub =
toolname.substr(0, firstDelimiter);
27 std::string decoratorName = std::string(
"JetFitter_TrackCompatibility_") + sub;
38 ATH_MSG_ERROR(
"Cannot retrieve InDet::InDetJetFitterUtils/InDetJetFitterUtils" );
39 return StatusCode::FAILURE;
43 ATH_MSG_ERROR(
"Cannot retrieve Trk::Mode3dTo1dFinder/Mode3dTo1dFinder" );
44 return StatusCode::FAILURE;
56 return StatusCode::SUCCESS;
60 return StatusCode::SUCCESS;
66 const TLorentzVector& jetMomentum,
68 const std::vector< const xAOD::Vertex* >& vertexCandidates,
69 std::vector< const Trk::ITrackLink* >& tracksToUseInFirstFit,
70 std::vector< const Trk::ITrackLink* >& tracksToUseInSecondFit,
74 std::vector< Trk::PositionAndWeight > positionsOfSeedingVertices;
79 ATH_MSG_DEBUG(
"Found " << v0candidates.size() <<
" V0 candidates!" );
83 ATH_MSG_DEBUG(
"Analyzing two track vertices to select the best tracks" );
87 bool satisfyCriteriaFirstFitQuality =
checkCriteriaFirstFit( primaryVertex,jetMomentum,*v0candidate );
88 if ( not satisfyCriteriaFirstFitQuality ) {
89 ATH_MSG_DEBUG(
"Quality criteria for first fit not satisfied! skipping ... " );
95 std::vector< const Trk::ITrackLink* > vxTrackAtVertex =
m_tracksAccessor( *v0candidate );
100 bool secondTrackAlreadyStored =
m_jetFitterUtils->checkIfTrackIsInVector( secondTrack,tracksToUseInFirstFit );
101 if ( not secondTrackAlreadyStored )
102 tracksToUseInFirstFit.push_back( secondTrack );
105 bool firstTrackAlreadyStored =
m_jetFitterUtils->checkIfTrackIsInVector( firstTrack,tracksToUseInFirstFit );
106 if ( not firstTrackAlreadyStored )
107 tracksToUseInFirstFit.push_back( firstTrack );
109 positionsOfSeedingVertices.emplace_back( v0candidate->position(),1 );
114 ATH_MSG_DEBUG(
"Determine single good tracks to add in the fit in a second step" );
118 if ( not satisfyCriteriaSecondFitQuality ) {
119 ATH_MSG_DEBUG(
"Quality criteria for second fit not satisfied! skipping ... " );
123 bool alreadyUsed =
m_jetFitterUtils->checkIfTrackIsInVector( trackLink,tracksToUseInFirstFit );
129 bool trackAlreadyStored =
m_jetFitterUtils->checkIfTrackIsInVector( trackLink,tracksToUseInSecondFit );
130 if ( not trackAlreadyStored )
131 tracksToUseInSecondFit.push_back( trackLink );
145 std::vector< const Trk::TrackParticleBase* >() );
146 return twoTrackVerticesInJet;
150 const TLorentzVector& ,
151 std::vector< const Trk::ITrackLink* >& ,
152 const std::vector< const xAOD::Vertex* >& vertexCandidates )
const {
154 std::vector< const xAOD::Vertex* > v0candidates;
155 ATH_MSG_DEBUG(
"Looping over " << vertexCandidates.size() <<
" input candidates" );
157 for (
unsigned int indexA(0); indexA<vertexCandidates.size(); indexA++ ) {
158 const xAOD::Vertex* myCandidate = vertexCandidates.at( indexA );
170 v0candidates.push_back(
toAdd );
171 *
toAdd = *myCandidate;
178 const TLorentzVector& jetMomentum,
183 double vertexProb = TMath::Prob( v0candidate.
chiSquared(),
188 ATH_MSG_DEBUG(
"V0 candidate does not satisfy the vertex prob criteria!" );
195 const std::vector< const Trk::ITrackLink* > vxTrackAtVertex =
m_tracksAccessor( v0candidate );
199 if ( trackLink1 ==
nullptr || trackLink2 ==
nullptr ) {
200 ATH_MSG_DEBUG(
"Zero pointer (ITrackLink): skipping 2-track candidate" );
207 if ( !linkTrackA || !linkTrackB ) {
208 ATH_MSG_DEBUG(
"Zero pointer (LinkToXAODTrackParticle): skipping 2-track candidate" );
233 if ( !initialPerigee1 || !initialPerigee2 ) {
234 ATH_MSG_DEBUG(
"No refitted parameters available for 2-track vertex. Candidate not accepted..." );
246 primaryVertex.covariancePosition(),
250 std::pair<double,double> track1_IPd0z0 =
m_jetFitterUtils->getD0andZ0IP( *initialPerigee1,
251 primaryVertexRecVertex );
253 std::pair<double,double> track2_IPd0z0 =
m_jetFitterUtils->getD0andZ0IP(*initialPerigee2,
254 primaryVertexRecVertex);
270 ATH_MSG_DEBUG(
"Checking distance and error between two vertices..." );
271 std::pair<double,double> distanceAndError =
m_jetFitterUtils->getDistanceAndErrorBetweenTwoVertices( v0candidate,primaryVertexRecVertex );
273 Amg::Vector3D jetMomSpatial( jetMomentum.X(), jetMomentum.Y(), jetMomentum.Z() );
276 double signedDistance = distanceAndError.first;
277 if (
sign < 0 ) signedDistance = -signedDistance;
278 double significance = signedDistance/distanceAndError.second;
284 FirstSelectionFirstCriterium = -FirstSelectionFirstCriterium;
285 FirstSelectionSecondCriterium = -FirstSelectionSecondCriterium;
289 ( significance > FirstSelectionFirstCriterium );
291 ( significance > FirstSelectionSecondCriterium );
293 if ( not ( firstCriterium || secondCriterium ) )
299 ATH_MSG_DEBUG(
"Checking material interaction in layer..." );
302 bool matinteraction =
false;
312 matinteraction =
true;
315 if ( matinteraction ) {
320 if ( signifCutTight )
return false;
338 if ( linkTrack ==
nullptr ) {
339 ATH_MSG_DEBUG(
"Zero pointer (LinkToXAODTrackParticle): skipping 2-track candidate" );
347 const AmgSymMatrix(5) *measPerigee = perigee->covariance();
349 if ( measPerigee ==
nullptr ) {
350 ATH_MSG_DEBUG(
"Track parameters have no covariance. skipping single track candidate..." );
356 primaryVertex.covariancePosition(),
360 std::pair<double,double> track_IPd0z0 =
m_jetFitterUtils->getD0andZ0IP( *perigee,
361 primaryVertexRecVertex );
362 std::pair<double,double> track_IPd0z0Sig =
m_jetFitterUtils->getD0andZ0IPSig( *perigee,
363 primaryVertexRecVertex );
365 const double IPd0 = track_IPd0z0.first;
366 const double IPz0 = track_IPd0z0.second;
367 const double IPd0Sig = track_IPd0z0Sig.first;
368 const double IPz0Sig = track_IPd0z0Sig.second;
385 ( compatibilityTrack >= 0 && TMath::Prob( fabs(compatibilityTrack),2) > cutCompatibilityPrimaryVertexSinglePositiveLifetimeTrackForBSecondSelection ) ||
386 ( compatibilityTrack < 0 && TMath::Prob( fabs(compatibilityTrack),2) > cutCompatibilityPrimaryVertexSingleNegativeLifetimeTrackForBSecondSelection ) ||
389 ATH_MSG_DEBUG(
"Candidate didn't pass one of the selection cuts" );
397 const TLorentzVector& jetMomentum,
398 const std::vector< Trk::PositionAndWeight >& positionsOfSeedingVertices )
const {
400 Amg::Vector3D JFseedDirection( jetMomentum.X(),jetMomentum.Y(),jetMomentum.Z() );
401 JFseedDirection.normalize();
404 if ( positionsOfSeedingVertices.empty() )
405 return JFseedDirection;
408 double sign = ( theSeedVertex - primaryVertex.
position() ).
dot( JFseedDirection );
413 JFseedDirection = ( theSeedVertex - primaryVertex.
position() ).
unit();
414 ATH_MSG_DEBUG(
"Using twotrkvtx direction for start: " << JFseedDirection );
415 }
else ATH_MSG_DEBUG(
"NORMAL SEEDING: Seed vertex is on negative side... Using Jet Direction!" );
420 JFseedDirection = -( theSeedVertex - primaryVertex.
position() ).
unit();
421 ATH_MSG_DEBUG(
"Using twotrkvtx direction for start: " << JFseedDirection );
422 }
else ATH_MSG_DEBUG(
"REVERSE SEEDING: Seed vertex is on positive side... Using Jet Direction!" );
426 return JFseedDirection;