36 bool is_pv_associated =
false;
40 for(
const auto* vtx : *vertices ) {
41 for(
size_t iv = 0; iv < vtx->nTrackParticles(); iv++ ) {
42 const auto* pvtrk = vtx->trackParticle( iv );
43 if (pvtrk ==
nullptr)
continue;
45 if ( (trk_from_gsf == pvtrk) or (trk == pvtrk) ) {
46 is_pv_associated =
true;
51 return is_pv_associated;
56 return (v1-v2).norm();
63 const auto distance = v2.vertex - v1.
vertex;
66 sumCov.fillSymmetric(0, 0, v1.
vertexCov.at(0) + v2.vertexCov.at(0));
67 sumCov.fillSymmetric(1, 0, v1.
vertexCov.at(1) + v2.vertexCov.at(1));
68 sumCov.fillSymmetric(1, 1, v1.
vertexCov.at(2) + v2.vertexCov.at(2));
69 sumCov.fillSymmetric(2, 0, v1.
vertexCov.at(3) + v2.vertexCov.at(3));
70 sumCov.fillSymmetric(2, 1, v1.
vertexCov.at(4) + v2.vertexCov.at(4));
71 sumCov.fillSymmetric(2, 2, v1.
vertexCov.at(5) + v2.vertexCov.at(5));
73 const double s2 = distance.transpose() * sumCov.inverse() * distance;
77 ATH_MSG_WARNING(
" >>> " << __FUNCTION__ <<
": detected covariance matrix broken exception" );
85 trackTypes = { xAOD::Muon::Primary,
86 xAOD::Muon::InnerDetectorTrackParticle,
87 xAOD::Muon::MuonSpectrometerTrackParticle,
88 xAOD::Muon::CombinedTrackParticle,
89 xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle
95 for(
size_t i=0; i<electron->nTrackParticles(); i++ ) trackTypes.emplace_back( i );
102 return muon->trackParticle(
static_cast<xAOD::Muon::TrackParticleType
>( trackType ) );
107 return electron->trackParticle( trackType );
113 return (v2.vertex - v1.
vertex).norm();
121 auto& wrkvrt = workVerticesContainer->at(iv);
123 ATH_MSG_VERBOSE(
" >> disassembleVertex(): begin: disassembling vertex[" << iv <<
"], workVerticesContainer.size() = " << workVerticesContainer->size() );
124 ATH_MSG_VERBOSE(
" >> disassembleVertex(): Vertex: r = " << wrkvrt.vertex.perp() <<
", z = " << wrkvrt.vertex.z() );
127 const auto& ntrk = wrkvrt.selectedTrackIndices.size();
131 if( wrkvrt.selectedTrackIndices.size() <= 2 )
return StatusCode::SUCCESS;
133 for(
auto&
index : wrkvrt.selectedTrackIndices ) {
136 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > track at vertex[" << iv <<
"]: "
137 <<
"index = " << trk->
index()
138 <<
", pT = " << trk->
pt()
139 <<
", phi = " << trk->
phi()
140 <<
", d0 = " << trk->
d0()
141 <<
", z0 = " << trk->
z0());
145 const auto&
max = std::max_element( wrkvrt.Chi2PerTrk.begin(), wrkvrt.Chi2PerTrk.end() );
147 if(
max == wrkvrt.Chi2PerTrk.end() )
return StatusCode::SUCCESS;
149 maxChi2TrackIndex =
max - wrkvrt.Chi2PerTrk.begin();
156 vector<const xAOD::NeutralParticle*> dummyNeutrals;
158 vector<WrkVrt> new_vertices;
161 ATH_MSG_VERBOSE(
" >> disassembleVertex(): Loop over the tracks associated to the vertex other than the selected tracks.");
162 for(
size_t itrk=0; itrk<ntrk; itrk++) {
164 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > Loop itrk = " << itrk <<
" / " << ntrk );
167 if( itrk == maxChi2TrackIndex ) {
172 const size_t this_trk_id = wrkvrt.selectedTrackIndices[itrk];
173 const size_t selected_trk_id = wrkvrt.selectedTrackIndices[maxChi2TrackIndex];
175 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > this_trk_id = " << this_trk_id <<
", selected_trk_id = " << selected_trk_id <<
", alltrks_size = " <<
m_selectedTracks.size() );
177 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > this_trk_id is invalid. continue!" );
181 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > selected_trk_id is invalid. continue!" );
185 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > Storing tracks to ListBaseTracks" );
189 vector<const xAOD::TrackParticle*> ListBaseTracks;
193 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > ListBaseTracks was stored." );
202 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
209 m_fitSvc->setApproximateVertex( wrkvrt.vertex[0], wrkvrt.vertex[1], wrkvrt.vertex[2], *state );
217 StatusCode
sc =
m_fitSvc->VKalVrtFit(ListBaseTracks,
228 if(
sc.isFailure() )
continue;
234 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > register the new vertex to the vertex list" );
235 new_vertices.emplace_back( newvrt );
239 wrkvrt.selectedTrackIndices.erase( wrkvrt.selectedTrackIndices.begin() + maxChi2TrackIndex );
240 ATH_MSG_VERBOSE(
" >> disassembleVertex(): removed the selected track from the original vertex. wrkvrt.selectedTrackIndices.size = " << wrkvrt.selectedTrackIndices.size() );
243 ATH_MSG_VERBOSE(
" >> disassembleVertex(): refit the original vertex" );
246 if(
sc.isFailure() ) {
249 return StatusCode::SUCCESS;
253 for(
const auto& vertex : new_vertices ) {
254 ATH_MSG_VERBOSE(
" >> disassembleVertex(): > emplace_back new vertex" );
255 workVerticesContainer->emplace_back( vertex );
258 ATH_MSG_VERBOSE(
" >> disassembleVertex(): end. workVerticesContainer.size() = " << workVerticesContainer->size() );
259 return StatusCode::SUCCESS;
271 auto fitQuality_begin = vertex.fitQuality();
273 auto removeCounter = 0;
275 if( vertex.nTracksTotal() <= 2 )
return 0.;
280 if(
sc.isFailure() ) {
286 double chi2Probability = TMath::Prob( vertex.Chi2, vertex.ndof() );
288 while (chi2Probability <
m_jp.improveChi2ProbThreshold ) {
289 if( vertex.nTracksTotal() == 2 )
return chi2Probability;
291 WrkVrt vertex_backup = vertex;
293 auto maxChi2 = std::max_element( vertex.Chi2PerTrk.begin(), vertex.Chi2PerTrk.end() );
294 size_t index = maxChi2 - vertex.Chi2PerTrk.begin();
297 ATH_MSG_DEBUG(
" >>> " << __FUNCTION__ <<
": worst chi2 trk index = " <<
index <<
", #trks = " << vertex.Chi2PerTrk.size() );
299 if(
index < vertex.selectedTrackIndices.size() ) {
300 vertex.selectedTrackIndices.erase( vertex.selectedTrackIndices.begin() +
index );
303 index -= vertex.selectedTrackIndices.size();
304 if(
index >= vertex.associatedTrackIndices.size() ) {
308 vertex.associatedTrackIndices.erase( vertex.associatedTrackIndices.begin() +
index );
314 if(
sc.isFailure() || vertex_backup.
fitQuality() < vertex.fitQuality() ) {
315 vertex = vertex_backup;
320 chi2Probability = TMath::Prob( vertex.Chi2, vertex.ndof() );
323 auto fitQuality_end = vertex.fitQuality();
325 if( 0 == removeCounter ) {
326 ATH_MSG_DEBUG(
" >>> " << __FUNCTION__ <<
": no improvement was found." );
328 ATH_MSG_DEBUG(
" >>> " << __FUNCTION__ <<
": Removed " << removeCounter <<
" tracks; Fit quality improvement: " << fitQuality_begin <<
" ==> " << fitQuality_end );
331 return chi2Probability;
338 std::vector< std::deque<long int> > *TrkInVrt,
339 const long int & trackIndexToRemove,
340 const long int & SelectedVertex)
343 auto& wrkvrt = workVerticesContainer->at(SelectedVertex);
344 auto& tracks = wrkvrt.selectedTrackIndices;
347 auto end =
std::remove_if( tracks.begin(), tracks.end(), [&](
long int index) { return index == trackIndexToRemove; } );
348 tracks.erase( end, tracks.end() );
352 for(
auto& trks : *TrkInVrt ) {
353 auto end =
std::remove_if( trks.begin(), trks.end(), [&](
long int index) { return index == trackIndexToRemove; } );
354 trks.erase( end, trks.end() );
360 if( wrkvrt.selectedTrackIndices.size() == 1 ) {
362 const auto& leftTrackIndex = *( tracks.begin() );
363 auto& list = TrkInVrt->at(leftTrackIndex);
364 auto end =
std::remove_if( list.begin(), list.end(), [&](
long int index) { return index == trackIndexToRemove; } );
365 list.erase( end, list.end() );
380 for(
auto& workVertex : *workVerticesContainer ) {
382 workVertex.closestWrkVrtIndex = 0;
387 for(
auto iv = workVerticesContainer->begin(); iv != workVerticesContainer->end(); ++iv ) {
388 if( (*iv).selectedTrackIndices.size()< 2)
continue;
390 auto i_index = iv - workVerticesContainer->begin();
392 for(
auto jv = std::next(iv); jv != workVerticesContainer->end(); ++jv ) {
393 if( (*jv).selectedTrackIndices.size()< 2)
continue;
395 auto j_index = iv - workVerticesContainer->begin();
397 double value = (this->*algorithm)( (*iv), (*jv) );
401 indexPair.first = i_index;
402 indexPair.second = j_index;
404 if( value < (*iv).closestWrkVrtValue ) {(*iv).closestWrkVrtValue = value; (*iv).closestWrkVrtIndex = j_index; }
405 if( value < (*jv).closestWrkVrtValue ) {(*jv).closestWrkVrtValue = value; (*jv).closestWrkVrtIndex = i_index; }
421 indexPair.second = 0;
425 for(
unsigned iv=0; iv<workVerticesContainer->size()-1; iv++) {
426 auto& vertex = workVerticesContainer->at(iv);
428 if( vertex.selectedTrackIndices.size() < 2)
continue;
429 if( vertex.closestWrkVrtIndex == 0 )
continue;
431 if( vertex.closestWrkVrtValue <
minValue ) {
433 unsigned jv = vertex.closestWrkVrtIndex;
436 if( workVerticesContainer->at(jv).closestWrkVrtIndex == 0 )
continue;
438 minValue = vertex.closestWrkVrtValue;
440 indexPair.first = iv;
441 indexPair.second = jv;
465 deque<long int>::iterator TransfEnd;
471 v2.selectedTrackIndices.clear();
473 v2.closestWrkVrtIndex = 0;
481 if(
sc.isFailure() ) {
485 ATH_MSG_DEBUG(
" >>> " << __FUNCTION__ <<
": failure in merging" );
487 return StatusCode::FAILURE;
490 return StatusCode::SUCCESS;
498 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
510 vector<const xAOD::NeutralParticle*> dummyNeutrals;
515 workVertex.
isGood =
false;
516 return StatusCode::SUCCESS;
519 vector<const xAOD::TrackParticle*> ListBaseTracks;
533 auto& vertexPos = workVertex.
vertex;
535 m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), istate );
537 ATH_MSG_VERBOSE(
" >>> refitVertex: ListBaseTracks.size = " << ListBaseTracks.size()
540 for(
const auto *trk : ListBaseTracks ) {
548 StatusCode
sc =
m_fitSvc->VKalVrtFitFast( ListBaseTracks, initVertex, istate );
549 if(
sc.isFailure())
ATH_MSG_DEBUG(
" >>> refitVertex: fast crude estimation failed.");
550 ATH_MSG_VERBOSE(
" >>> refitVertex: Fast VKalVrtFit succeeded. vertex (r,z) = (" << initVertex.perp() <<
", " << initVertex.z() <<
", " <<
")" );
554 m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), istate );
558 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), istate );
562 ATH_MSG_VERBOSE(
" >>> refitVertex: approx vertex is set. Now going to perform fitting..." );
564 StatusCode SC=
m_fitSvc->VKalVrtFit(ListBaseTracks,dummyNeutrals,
576 if(SC.isFailure())
ATH_MSG_DEBUG(
" >>> refitVertex: SC in refitVertex returned failure ");
578 ATH_MSG_VERBOSE(
" >>> refitVertex: succeeded in fitting. New vertex pos (r,z) = (" << vertexPos.perp() <<
", " << vertexPos.z() <<
")" );
579 ATH_MSG_VERBOSE(
" >>> refitVertex: New vertex cov = (" << cov.at(0) <<
", " << cov.at(1) <<
", " << cov.at(2) <<
", " << cov.at(3) <<
", " << cov.at(4) <<
", " << cov.at(5) <<
")" );
587 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState();
599 vector<const xAOD::NeutralParticle*> dummyNeutrals;
604 workVertex.
isGood =
false;
605 return StatusCode::SUCCESS;
608 vector<const xAOD::TrackParticle*> ListBaseTracks;
622 auto& vertexPos = workVertex.
vertex;
624 m_fitSvc->setApproximateVertex( suggestedPosition.x(), suggestedPosition.y(), suggestedPosition.z(), istate );
626 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": ListBaseTracks.size = " << ListBaseTracks.size()
629 for(
const auto *trk : ListBaseTracks ) {
630 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": track index = " << trk->index() );
635 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": approx vertex is set. Now going to perform fitting..." );
637 StatusCode SC=
m_fitSvc->VKalVrtFit(ListBaseTracks,dummyNeutrals,
649 if( SC.isFailure() )
ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": SC in refitVertex returned failure ");
652 if( SC.isSuccess() ) {
653 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": succeeded in fitting. New vertex pos = (" << vertexPos.x() <<
", " << vertexPos.y() <<
", " << vertexPos.z() <<
")" );
654 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": New vertex cov = (" << cov.at(0) <<
", " << cov.at(1) <<
", " << cov.at(2) <<
", " << cov.at(3) <<
", " << cov.at(4) <<
", " << cov.at(5) <<
")" );
668 auto& trackIndices1 = workVerticesContainer->at( pairIndex.first ).selectedTrackIndices;
669 auto& trackIndices2 = workVerticesContainer->at( pairIndex.second ).selectedTrackIndices;
671 if( trackIndices1.size() < 2 )
return 0;
672 if( trackIndices2.size() < 2 )
return 0;
676 for(
auto&
index : trackIndices1 ) {
677 if( std::find(trackIndices2.begin(),trackIndices2.end(),
index) != trackIndices2.end()) nTrkCom++;
694 declareProperty(
"McParticleContainer",
m_jp.truthParticleContainerName =
"TruthParticles" );
699 declareProperty(
"All2trkVerticesContainerName",
m_jp.all2trksVerticesContainerName =
"All2TrksVertices" );
700 declareProperty(
"SecondaryVerticesContainerName",
m_jp.secondaryVerticesContainerName =
"SecondaryVertices" );
771 declareProperty(
"doMergeFinalVerticesDistance",
m_jp.doMergeFinalVerticesDistance =
false );
772 declareProperty(
"doAssociateNonSelectedTracks",
m_jp.doAssociateNonSelectedTracks =
false );
782 declareProperty(
"reassembleMaxImpactParameterD0",
m_jp.reassembleMaxImpactParameterD0 = 1. );
783 declareProperty(
"reassembleMaxImpactParameterZ0",
m_jp.reassembleMaxImpactParameterZ0 = 5. );
784 declareProperty(
"mergeByShufflingMaxSignificance",
m_jp.mergeByShufflingMaxSignificance = 100. );
798 declareProperty(
"doDisappearingTrackVertexing",
m_jp.doDisappearingTrackVertexing =
false );
808 declareProperty(
"doAugmentDVimpactParametersToMuons",
m_jp.doAugmentDVimpactParametersToMuons =
false );
809 declareProperty(
"doAugmentDVimpactParametersToElectrons",
m_jp.doAugmentDVimpactParametersToElectrons =
false );
851 if(
m_jp.FillNtuple ) {
858 m_ntupleVars->get<
unsigned int>(
"PVType" ) = vertex->vertexType();
861 m_ntupleVars->get<
unsigned int>(
"NTrksPV" ) = vertex->nTrackParticles();
866 m_ntupleVars->get< vector<int> > (
"NdofTrksPV" ) .emplace_back( vertex->numberDoF() );
867 m_ntupleVars->get< vector<double> >(
"PVZpile" ) .emplace_back( vertex->position().z() );
871 << vertex->x() <<
","
872 << vertex->y() <<
","
873 << vertex->z() <<
","
874 << vertex->numberDoF() );
880 ATH_MSG_DEBUG(
"No Reconstructed PV was found. Using the dummy PV instead.");
884 if(
m_jp.FillNtuple ) {
892 m_ntupleVars->get<
unsigned int>(
"PVType" ) = vertex->vertexType();
895 m_ntupleVars->get<
unsigned int>(
"NTrksPV" ) = vertex->nTrackParticles();
904 return StatusCode::FAILURE;
909 return StatusCode::SUCCESS;
918 trackToVertexMap.clear();
920 for(
size_t iv = 0; iv<workVerticesContainer->size(); iv++ ) {
922 WrkVrt& vertex = workVerticesContainer->at(iv);
924 auto& trackIndices = vertex.selectedTrackIndices;
925 if( !vertex.isGood )
continue;
926 if( trackIndices.size() < 2 )
continue;
928 for(
auto&
index : trackIndices ) {
929 trackToVertexMap[
index].emplace_back( iv );
933 for(
auto& pair: trackToVertexMap ) {
934 std::string
msg = Form(
"track index [%ld]: vertices = (", pair.first);
935 for(
auto& v : pair.second ) {
936 msg += Form(
"%ld, ", v);
947 std::map<
long int, std::vector<long int> >& trackToVertexMap,
948 long int & maxSharedTrack,
949 long int & worstMatchingVertex)
955 auto maxSharedTrackToVertices = std::max_element( trackToVertexMap.begin(), trackToVertexMap.end(), [](
auto& p1,
auto& p2 ) { return p1.second.size() < p2.second.size(); } );
957 if( maxSharedTrackToVertices == trackToVertexMap.end() )
return worstChi2;
959 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": max-shared track index = " << maxSharedTrackToVertices->first <<
", number of shared vertices = " << maxSharedTrackToVertices->second.size() );
961 if( maxSharedTrackToVertices->second.size() < 2 )
return worstChi2;
964 std::map<long int, double> vrtChi2Map;
967 for(
auto& iv : maxSharedTrackToVertices->second ) {
968 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": loop over vertices: vertex index " << iv );
970 auto& wrkvrt = workVerticesContainer->at( iv );
971 auto& trackIndices = wrkvrt.selectedTrackIndices;
974 auto index = std::find_if( trackIndices.begin(), trackIndices.end(), [&](
auto&
index ) { return index == maxSharedTrackToVertices->first; } );
975 if(
index == trackIndices.end() ) {
976 ATH_MSG_WARNING(
" >> " << __FUNCTION__ <<
": index not found (algorithm inconsistent)" );
980 auto&
chi2 = wrkvrt.Chi2PerTrk.at(
index - trackIndices.begin() );
982 vrtChi2Map.emplace( std::pair<long int, double>(iv,
chi2) );
985 auto worstVrtChi2Pair = std::max_element( vrtChi2Map.begin(), vrtChi2Map.end(), [](
auto& p1,
auto& p2 ) { return p1.second < p2.second; } );
987 if( worstVrtChi2Pair == vrtChi2Map.end() ) {
988 ATH_MSG_WARNING(
" >> " << __FUNCTION__ <<
": max_element of vrtChi2Map not found" );
992 maxSharedTrack = maxSharedTrackToVertices->first;
993 worstMatchingVertex = worstVrtChi2Pair->first;
994 worstChi2 = worstVrtChi2Pair->second;
1003 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": ===============================================================" );
1004 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": " << name <<
": #vertices = " << workVerticesContainer->size() );
1006 std::set<const xAOD::TrackParticle*> usedTracks;
1008 auto concatenateIndicesToString = [](
auto indices,
auto& collection ) -> std::string {
1009 if( 0 == indices.size() )
return "";
1010 return std::accumulate( std::next(indices.begin()), indices.end(), std::to_string( indices.at(0) ),
1011 [&collection](
const std::string&
str,
auto&
index ) { return str +
", " + std::to_string( collection.at(index)->index() ); } );
1014 std::map<const xAOD::TruthVertex*, bool> previous;
1016 for(
auto& pair :
m_matchMap ) { previous.emplace( pair.first, pair.second ); }
1021 for(
size_t iv=0; iv<workVerticesContainer->size(); iv++) {
1022 const auto& wrkvrt = workVerticesContainer->at(iv);
1024 if( wrkvrt.nTracksTotal() < 2 )
continue;
1026 std::string sels = concatenateIndicesToString( wrkvrt.selectedTrackIndices,
m_selectedTracks );
1027 std::string assocs = concatenateIndicesToString( wrkvrt.associatedTrackIndices,
m_associatedTracks );
1032 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": " << name <<
" vertex [" << iv <<
"]: " << &wrkvrt
1033 <<
", isGood = " << (wrkvrt.isGood?
"true" :
"false")
1034 <<
", #ntrks(tot, sel, assoc) = (" << wrkvrt.nTracksTotal() <<
", " << wrkvrt.selectedTrackIndices.size() <<
", " << wrkvrt.associatedTrackIndices.size() <<
"), "
1035 <<
", chi2/ndof = " << wrkvrt.fitQuality()
1036 <<
", (r, z) = (" << wrkvrt.vertex.perp()
1037 <<
", " << wrkvrt.vertex.z() <<
")"
1038 <<
", sels = { " << sels <<
" }"
1039 <<
", assocs = { " << assocs <<
" }" );
1045 Amg::Vector3D vTruth( truthVertex->x(), truthVertex->y(), truthVertex->z() );
1046 Amg::Vector3D vReco ( wrkvrt.vertex.x(), wrkvrt.vertex.y(), wrkvrt.vertex.z() );
1048 const auto distance = vReco - vTruth;
1051 cov.fillSymmetric( 0, 0, wrkvrt.vertexCov.at(0) );
1052 cov.fillSymmetric( 1, 0, wrkvrt.vertexCov.at(1) );
1053 cov.fillSymmetric( 1, 1, wrkvrt.vertexCov.at(2) );
1054 cov.fillSymmetric( 2, 0, wrkvrt.vertexCov.at(3) );
1055 cov.fillSymmetric( 2, 1, wrkvrt.vertexCov.at(4) );
1056 cov.fillSymmetric( 2, 2, wrkvrt.vertexCov.at(5) );
1058 const double s2 = distance.transpose() * cov.inverse() * distance;
1060 if( distance.norm() < 2.0 || s2 < 100. )
m_matchMap.at( truthVertex ) =
true;
1066 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": number of used tracks = " << usedTracks.size() );
1068 if( !previous.empty() && previous.size() ==
m_matchMap.size() ) {
1070 if( previous.find( pair.first ) == previous.end() )
continue;
1071 if( pair.second != previous.at( pair.first ) ) {
1072 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": Match flag has changed: (r, z) = (" << pair.first->perp() <<
", " << pair.first->z() <<
")" );
1077 if(
m_jp.FillHist ) {
1084 for(
const auto* trk : usedTracks ) {
msg += Form(
"%ld, ", trk->index() ); }
1087 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": ===============================================================" );
1094 summary.numIBLHits = 0;
1095 summary.numBLayerHits = 0;
1096 summary.numPixelHits = 0;
1097 summary.numSctHits = 0;
1098 summary.numTrtHits = 0;
1113 const EventContext& ctx = Gaudi::Hive::currentContext();
1114 std::vector<std::unique_ptr<Trk::TrackParameters>> paramsVector =
1121 for(
auto& params : paramsVector ) {
1123 const TVector3 position( params->position().x(), params->position().y(), params->position().z() );
1125 if( prevPos == position ) {
1131 const auto* detElement = params->associatedSurface().associatedDetectorElement();
1137 const auto&
id = detElement->identify();
1142 auto idHash =
m_pixelId->wafer_hash(
id );
1145 pattern->emplace_back( std::make_tuple( position,
Pixel,
m_pixelId->barrel_ec(
id),
m_pixelId->layer_disk(
id), good ) );
1149 auto idHash =
m_sctId->wafer_hash(
id );
1152 pattern->emplace_back( std::make_tuple( position,
SCT,
m_sctId->barrel_ec(
id),
m_sctId->layer_disk(
id), good ) );
1156 if( !pattern->empty() ) {
1158 ATH_MSG_VERBOSE(
" >> " << __FUNCTION__ <<
", track " << trk <<
": position = (" << position.Perp() <<
", " << position.z() <<
", " << position.Phi() <<
"), detElement ID = " <<
id <<
", good = " << good
1159 <<
": (det, bec, layer) = (" << std::get<1>( pattern->back() ) <<
", " << std::get<2>( pattern->back() ) <<
", " << std::get<3>( pattern->back() ) <<
")" );
1161 if( !good ) nDisabled++;
1168 if(
m_jp.FillHist ) {
1169 m_hists[
"disabledCount"]->Fill( nDisabled );
1192 using LayerCombination = std::vector<int>;
1194 std::map<LayerCombination, unsigned> layerMap;
1195 if( layerMap.empty() ) {
1233 enum { position=0, detector=1, bec=2, layer=3, isGood=4 };
1238 const LayerCombination comb { std::get<detector>( point ), std::get<bec>( point ), std::get<layer>( point ) };
1240 for(
auto& pair : layerMap ) {
1241 if( pair.first == comb ) {
1249 enum { kShouldNotHaveHit, kShouldHaveHit, kMayHaveHit };
1255 auto& exPattern_along = *( exPattern.first );
1257 for(
auto itr = exPattern_along.begin(); itr != exPattern_along.end(); ++itr ) {
1258 if( std::next( itr ) == exPattern_along.end() )
continue;
1260 const auto& point = *itr;
1261 const auto& nextPoint = *( std::next( itr ) );
1263 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": isGood = " << std::get<isGood>( point ) );
1265 const auto& thisPos = std::get<position>( point );
1266 const auto& nextPos = std::get<position>( nextPoint );
1268 auto sectionVector = nextPos - thisPos;
1269 auto vertexVector = TVector3( vertex.x(), vertex.y(), vertex.z() ) - thisPos;
1272 const auto& detectorType = getDetectorType( point );
1274 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": detType = " << detectorType );
1280 if( vertexVector.Mag() < 10. ) {
1281 expectedHitPattern.at( detectorType ) = kMayHaveHit;
1287 if( !
static_cast<bool>(std::get<isGood>( point )) ) {
1288 expectedHitPattern.at( detectorType ) = kMayHaveHit;
1297 if( sectionVector.Mag() == 0. )
continue;
1300 <<
": hitPos = (" << thisPos.Perp() <<
", " << thisPos.z() <<
", " << thisPos.Phi() <<
")"
1301 <<
", sectionVec = (" << sectionVector.Perp() <<
", " << sectionVector.z() <<
", " << sectionVector.Phi() <<
")"
1302 <<
", vertexVec = (" << vertexVector.Perp() <<
", " << vertexVector.z() <<
", " << vertexVector.Phi() <<
")"
1303 <<
", cos(s,v) = " << sectionVector * vertexVector / ( sectionVector.Mag() * vertexVector.Mag() +
AlgConsts::infinitesimal ) );
1305 if( sectionVector * vertexVector > 0. )
continue;
1307 if( minExpectedRadius > thisPos.Perp() ) minExpectedRadius = thisPos.Perp();
1311 expectedHitPattern.at( detectorType ) = kShouldHaveHit;
1315 auto& exPattern_oppos = *( exPattern.second );
1316 bool oppositeFlag =
false;
1318 for(
auto itr = exPattern_oppos.begin(); itr != exPattern_oppos.end(); ++itr ) {
1319 if( std::next( itr ) == exPattern_oppos.end() )
continue;
1321 const auto& point = *itr;
1322 const auto& nextPoint = *( std::next( itr ) );
1324 const auto& thisPos = std::get<position>( point );
1325 const auto& nextPos = std::get<position>( nextPoint );
1327 auto sectionVector = nextPos - thisPos;
1328 auto vertexVector = TVector3( vertex.x(), vertex.y(), vertex.z() ) - thisPos;
1330 const auto& detectorType = getDetectorType( point );
1332 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": detType = " << detectorType );
1335 <<
": hitPos = (" << thisPos.Perp() <<
", " << thisPos.z() <<
", " << thisPos.Phi() <<
")"
1336 <<
", vertex = (" << vertex.perp() <<
", " << vertex.z() <<
", " << vertex.phi() <<
")"
1337 <<
", cos(s,v) = " << sectionVector * vertexVector / ( sectionVector.Mag() * vertexVector.Mag() +
AlgConsts::infinitesimal ) );
1342 if( sectionVector * vertexVector < 0. ) {
1343 oppositeFlag =
true;
1352 std::string
msg =
"Expected hit pattern: ";
1354 msg += Form(
"%s", expectedHitPattern.at(i) < kMayHaveHit? Form(
"%u", expectedHitPattern.at(i)) :
"X" );
1358 msg =
"Recorded hit pattern: ";
1364 std::vector<unsigned> matchedLayers;
1367 const unsigned recordedPattern = ( (trk->
hitPattern()>>i) & 1 );
1369 if( expectedHitPattern.at(i) == kMayHaveHit ) {
1370 matchedLayers.emplace_back( i );
1371 }
else if( expectedHitPattern.at(i) == kShouldHaveHit ) {
1372 if( expectedHitPattern.at(i) != recordedPattern ) {
1375 matchedLayers.emplace_back( i );
1378 if( expectedHitPattern.at(i) != recordedPattern ) {
1385 uint8_t PixelHits = 0;
1386 uint8_t SctHits = 0;
1387 uint8_t TRTHits = 0;
1392 auto dphi = trk->
phi() - vertex.phi();
1393 while( dphi > TMath::Pi() ) dphi -= TMath::TwoPi();
1394 while( dphi < -TMath::Pi() ) dphi += TMath::TwoPi();
1396 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vtx phi = " << vertex.phi() <<
", track phi = " << trk->
phi() <<
", dphi = " << dphi
1397 <<
", oppositeFlag = " << oppositeFlag
1398 <<
", nPixelHits = " <<
static_cast<int>(PixelHits)
1399 <<
", nSCTHits = " <<
static_cast<int>(SctHits)
1400 <<
", nTRTHits = " <<
static_cast<int>(TRTHits)
1401 <<
", nMatchedLayers = " << matchedLayers.size() );
1403 if( PixelHits == 0 && vertex.perp() > 300. ) {
1404 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertex r > 300 mm, w/o no pixel hits" );
1409 if( matchedLayers.size() < 2 )
return false;
1413 if( matchedLayers.size() < 4 )
return false;
1419 if( oppositeFlag )
return false;
1425 if( fabs( dphi ) > TMath::Pi()/2.0 )
return false;
1428 TVector3 trkP; trkP.SetPtEtaPhi( trk->
pt(), trk->
eta(), trk->
phi() );
1429 TVector3 vtx; vtx.SetXYZ( vertex.x(), vertex.y(), vertex.z() );
1430 if( trkP.Dot( vtx ) < 0. )
return false;
1449 const double rad = vertex.perp();
1450 const double absz = fabs( vertex.z() );
1459 outsidePixelBarrel0_and_insidePixelBarrel1,
1462 outsidePixelBarrel1_and_insidePixelBarrel2,
1465 outsidePixelBarrel2_and_insidePixelBarrel3,
1468 outsidePixelBarrel3_and_insideSctBarrel0,
1471 outsideSctBarrel0_and_insideSctBarrel1,
1476 int vertex_pattern = 0;
1478 vertex_pattern = insideBeamPipe;
1480 }
else if( rad < 31.0 && absz < 331.5 ) {
1481 vertex_pattern = insidePixelBarrel0;
1483 }
else if( rad < 38.4 && absz < 331.5 ) {
1484 vertex_pattern = aroundPixelBarrel0;
1486 }
else if( rad < 47.7 && absz < 400.5 ) {
1487 vertex_pattern = outsidePixelBarrel0_and_insidePixelBarrel1;
1489 }
else if( rad < 54.4 && absz < 400.5 ) {
1490 vertex_pattern = aroundPixelBarrel1;
1492 }
else if( rad < 85.5 && absz < 400.5 ) {
1493 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1495 }
else if( rad < 92.2 && absz < 400.5 ) {
1496 vertex_pattern = aroundPixelBarrel2;
1498 }
else if( rad < 119.3 && absz < 400.5 ) {
1499 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1501 }
else if( rad < 126.1 && absz < 400.5 ) {
1502 vertex_pattern = aroundPixelBarrel3;
1504 }
else if( rad < 290 && absz < 749.0 ) {
1505 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1507 }
else if( rad < 315 && absz < 749.0 ) {
1508 vertex_pattern = aroundSctBarrel0;
1510 }
else if( rad < 360 && absz < 749.0 ) {
1511 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1513 }
else if( rad < 390 && absz < 749.0 ) {
1514 vertex_pattern = aroundSctBarrel1;
1519 unsigned nPixelLayers { 0 };
1531 if( vertex_pattern == insideBeamPipe ) {
1534 if( nPixelLayers < 3 )
return false;
1537 }
else if( vertex_pattern == insidePixelBarrel0 ) {
1540 if( nPixelLayers < 3 )
return false;
1544 else if( vertex_pattern == aroundPixelBarrel0 ) {
1548 if( nPixelLayers < 2 )
return false;
1552 else if( vertex_pattern == outsidePixelBarrel0_and_insidePixelBarrel1 ) {
1556 if( nPixelLayers < 2 )
return false;
1560 else if( vertex_pattern == aroundPixelBarrel1 ) {
1565 if( nPixelLayers < 2 )
return false;
1569 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1574 if( nPixelLayers < 2 )
return false;
1578 else if( vertex_pattern == aroundPixelBarrel2 ) {
1587 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1595 else if( vertex_pattern == aroundPixelBarrel3 ) {
1605 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1615 else if( vertex_pattern == aroundSctBarrel0 ) {
1626 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
1637 else if( vertex_pattern == aroundSctBarrel1 ) {
1663 const double rad = vertex.perp();
1664 const double absz = fabs( vertex.z() );
1673 outsidePixelBarrel0_and_insidePixelBarrel1,
1676 outsidePixelBarrel1_and_insidePixelBarrel2,
1679 outsidePixelBarrel2_and_insidePixelBarrel3,
1682 outsidePixelBarrel3_and_insideSctBarrel0,
1685 outsideSctBarrel0_and_insideSctBarrel1,
1690 int vertex_pattern = 0;
1692 vertex_pattern = insideBeamPipe;
1694 }
else if( rad < 31.0 && absz < 331.5 ) {
1695 vertex_pattern = insidePixelBarrel0;
1697 }
else if( rad < 38.4 && absz < 331.5 ) {
1698 vertex_pattern = aroundPixelBarrel0;
1700 }
else if( rad < 47.7 && absz < 400.5 ) {
1701 vertex_pattern = outsidePixelBarrel0_and_insidePixelBarrel1;
1703 }
else if( rad < 54.4 && absz < 400.5 ) {
1704 vertex_pattern = aroundPixelBarrel1;
1706 }
else if( rad < 85.5 && absz < 400.5 ) {
1707 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1709 }
else if( rad < 92.2 && absz < 400.5 ) {
1710 vertex_pattern = aroundPixelBarrel2;
1712 }
else if( rad < 119.3 && absz < 400.5 ) {
1713 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1715 }
else if( rad < 126.1 && absz < 400.5 ) {
1716 vertex_pattern = aroundPixelBarrel3;
1718 }
else if( rad < 290 && absz < 749.0 ) {
1719 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1721 }
else if( rad < 315 && absz < 749.0 ) {
1722 vertex_pattern = aroundSctBarrel0;
1724 }
else if( rad < 360 && absz < 749.0 ) {
1725 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1727 }
else if( rad < 390 && absz < 749.0 ) {
1728 vertex_pattern = aroundSctBarrel1;
1734 unsigned nPixelLayers { 0 };
1746 if( vertex_pattern == insideBeamPipe ) {
1750 if( nPixelLayers < 3 )
return false;
1752 }
else if( vertex_pattern == insidePixelBarrel0 ) {
1756 if( nPixelLayers < 3 )
return false;
1761 else if( vertex_pattern == aroundPixelBarrel0 ) {
1766 if( nPixelLayers < 3 )
return false;
1770 else if( vertex_pattern == outsidePixelBarrel0_and_insidePixelBarrel1 ) {
1774 if( nPixelLayers < 3 )
return false;
1778 else if( vertex_pattern == aroundPixelBarrel1 ) {
1783 if( nPixelLayers < 2 )
return false;
1787 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1791 if( nPixelLayers < 2 )
return false;
1795 else if( vertex_pattern == aroundPixelBarrel2 ) {
1802 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1807 else if( vertex_pattern == aroundPixelBarrel3 ) {
1815 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1822 else if( vertex_pattern == aroundSctBarrel0 ) {
1830 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
1837 else if( vertex_pattern == aroundSctBarrel1 ) {
1857 const double rad = vertex.perp();
1858 const double absz = fabs( vertex.z() );
1867 outsidePixelBarrel1_and_insidePixelBarrel2,
1870 outsidePixelBarrel2_and_insidePixelBarrel3,
1873 outsidePixelBarrel3_and_insideSctBarrel0,
1876 outsideSctBarrel0_and_insideSctBarrel1,
1881 Int_t vertex_pattern = 0;
1883 vertex_pattern = insideBeamPipe;
1885 }
else if( rad < 47.7 && absz < 400.5 ) {
1886 vertex_pattern = insidePixelBarrel1;
1888 }
else if( rad < 54.4 && absz < 400.5 ) {
1889 vertex_pattern = aroundPixelBarrel1;
1891 }
else if( rad < 85.5 && absz < 400.5 ) {
1892 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1894 }
else if( rad < 92.2 && absz < 400.5 ) {
1895 vertex_pattern = aroundPixelBarrel2;
1897 }
else if( rad < 119.3 && absz < 400.5 ) {
1898 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1900 }
else if( rad < 126.1 && absz < 400.5 ) {
1901 vertex_pattern = aroundPixelBarrel3;
1903 }
else if( rad < 290 && absz < 749.0 ) {
1904 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1906 }
else if( rad < 315 && absz < 749.0 ) {
1907 vertex_pattern = aroundSctBarrel0;
1909 }
else if( rad < 360 && absz < 749.0 ) {
1910 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1912 }
else if( rad < 390 && absz < 749.0 ) {
1913 vertex_pattern = aroundSctBarrel1;
1920 if( vertex_pattern == insideBeamPipe ) {
1927 else if( vertex_pattern == insidePixelBarrel1 ) {
1933 else if( vertex_pattern == aroundPixelBarrel1 ) {
1940 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1947 else if( vertex_pattern == aroundPixelBarrel2 ) {
1955 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1962 else if( vertex_pattern == aroundPixelBarrel3 ) {
1971 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1980 else if( vertex_pattern == aroundSctBarrel0 ) {
1990 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
2000 else if( vertex_pattern == aroundSctBarrel1 ) {
2022 const double rad = vertex.perp();
2023 const double absz = fabs( vertex.z() );
2032 outsidePixelBarrel1_and_insidePixelBarrel2,
2035 outsidePixelBarrel2_and_insidePixelBarrel3,
2038 outsidePixelBarrel3_and_insideSctBarrel0,
2041 outsideSctBarrel0_and_insideSctBarrel1,
2046 Int_t vertex_pattern = 0;
2048 vertex_pattern = insideBeamPipe;
2050 }
else if( rad < 47.7 && absz < 400.5 ) {
2051 vertex_pattern = insidePixelBarrel1;
2053 }
else if( rad < 54.4 && absz < 400.5 ) {
2054 vertex_pattern = aroundPixelBarrel1;
2056 }
else if( rad < 85.5 && absz < 400.5 ) {
2057 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
2059 }
else if( rad < 92.2 && absz < 400.5 ) {
2060 vertex_pattern = aroundPixelBarrel2;
2062 }
else if( rad < 119.3 && absz < 400.5 ) {
2063 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
2065 }
else if( rad < 126.1 && absz < 400.5 ) {
2066 vertex_pattern = aroundPixelBarrel3;
2068 }
else if( rad < 290 && absz < 749.0 ) {
2069 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
2071 }
else if( rad < 315 && absz < 749.0 ) {
2072 vertex_pattern = aroundSctBarrel0;
2074 }
else if( rad < 360 && absz < 749.0 ) {
2075 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
2077 }
else if( rad < 390 && absz < 749.0 ) {
2078 vertex_pattern = aroundSctBarrel1;
2085 if( vertex_pattern == insideBeamPipe ) {
2092 else if( vertex_pattern == insidePixelBarrel1 ) {
2098 else if( vertex_pattern == aroundPixelBarrel1 ) {
2105 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
2111 else if( vertex_pattern == aroundPixelBarrel2 ) {
2118 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
2123 else if( vertex_pattern == aroundPixelBarrel3 ) {
2130 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
2136 else if( vertex_pattern == aroundSctBarrel0 ) {
2143 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
2149 else if( vertex_pattern == aroundSctBarrel1 ) {
2218 if( vertex.perp() < 31.0 ) {
2219 double dphi = trk->
phi() - vertex.phi();
2220 while( dphi > TMath::Pi() ) { dphi -= TMath::TwoPi(); }
2221 while( dphi < -TMath::Pi() ) { dphi += TMath::TwoPi(); }
2222 if( cos(dphi) < -0.8 )
return false;
2227 using LayerCombination = std::vector<int>;
2229 std::map<LayerCombination, unsigned> layerMap;
2230 if( layerMap.empty() ) {
2268 enum { position=0, detector=1, bec=2, layer=3, isGood=4 };
2273 const LayerCombination comb { std::get<detector>( point ), std::get<bec>( point ), std::get<layer>( point ) };
2275 for(
auto& pair : layerMap ) {
2276 if( pair.first == comb ) {
2284 uint32_t disabledPattern { 0 };
2287 auto& exPattern_along = *( exPattern.first );
2289 for(
auto itr = exPattern_along.begin(); itr != exPattern_along.end(); ++itr ) {
2290 if( std::next( itr ) == exPattern_along.end() )
continue;
2292 const auto& point = *itr;
2294 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": isGood = " << std::get<isGood>( point ) );
2296 if( !std::get<isGood>( point ) ) {
2297 const auto& detectorType = getDetectorType( point );
2298 disabledPattern += (1 << detectorType);
2303 uint32_t modifiedPattern = disabledPattern | hitPattern;
2305 std::string
msg =
"Disabled hit pattern: ";
2307 msg += Form(
"%u", ( disabledPattern >> i ) & 1 );
2311 msg =
"Recorded hit pattern: ";
2313 msg += Form(
"%u", ( hitPattern >> i ) & 1 );
2331 return ( check_itrk && check_jtrk );
2340 const auto& vertex = wrkvrt.
vertex;
2342 std::map< std::deque<long int>*, std::vector<const xAOD::TrackParticle*>& > indexMap
2347 for(
auto& pair : indexMap ) {
2349 auto* indices = pair.first;
2350 auto& tracks = pair.second;
2353 [&](
auto&
index ) {
2354 bool isConsistent = (this->*m_patternStrategyFuncs[m_checkPatternStrategy] )( tracks.at(index), vertex );
2355 return !isConsistent;
2358 indices->erase( newEnd, indices->end() );
2372 auto sc0 =
evtStore()->retrieve( eventInfo,
"EventInfo" );
2373 if( sc0.isFailure() ) {
return; }
2379 auto sc1 =
evtStore()->retrieve( truthParticles,
"TruthParticles" );
2380 if( sc1.isFailure() ) {
return; }
2382 auto sc2 =
evtStore()->retrieve( truthVertices,
"TruthVertices" );
2383 if( sc2.isFailure() ) {
return; }
2385 if( !truthParticles ) {
return; }
2386 if( !truthVertices ) {
return; }
2390 std::vector<const xAOD::TruthParticle*> truthSvTracks;
2397 if( truthVertex->nIncomingParticles() != 1 )
return false;
2398 if( !truthVertex->incomingParticle(0) )
return false;
2399 if( abs(truthVertex->incomingParticle(0)->pdgId()) < 1000000 )
return false;
2400 if( abs(truthVertex->incomingParticle(0)->pdgId()) > 1000000000 )
return false;
2402 bool hasNeutralino =
false;
2403 for(
unsigned ip = 0; ip < truthVertex->nOutgoingParticles(); ip++ ) {
2404 const auto* p = truthVertex->outgoingParticle(ip);
2405 if( abs( p->pdgId() ) == 1000022 ) {
2406 hasNeutralino =
true;
2410 return hasNeutralino;
2414 if( truthVertex->nIncomingParticles() != 1 )
return false;
2415 if( !truthVertex->incomingParticle(0) )
return false;
2416 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 50 )
return false;
2421 if( truthVertex->nIncomingParticles() != 1 )
return false;
2422 if( !truthVertex->incomingParticle(0) )
return false;
2423 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 36 )
return false;
2428 if( truthVertex->nIncomingParticles() != 1 )
return false;
2429 if( !truthVertex->incomingParticle(0) )
return false;
2430 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 310 )
return false;
2435 if( truthVertex->nIncomingParticles() != 1 )
return false;
2436 if( !truthVertex->incomingParticle(0) )
return false;
2437 if( abs(truthVertex->incomingParticle(0)->pdgId()) <= 500 || abs(truthVertex->incomingParticle(0)->pdgId()) >= 600 )
return false;
2442 if( truthVertex->nIncomingParticles() != 1 )
return false;
2443 if( !truthVertex->incomingParticle(0) )
return false;
2445 const auto* parent = truthVertex->incomingParticle(0);
2446 if( parent->isLepton() )
return false;
2448 TLorentzVector p4sum_in;
2449 TLorentzVector p4sum_out;
2450 for(
unsigned ip = 0; ip < truthVertex->nIncomingParticles(); ip++ ) {
2451 const auto* particle = truthVertex->incomingParticle(ip);
2452 TLorentzVector p4; p4.SetPtEtaPhiM( particle->pt(), particle->eta(), particle->phi(), particle->m() );
2455 for(
unsigned ip = 0; ip < truthVertex->nOutgoingParticles(); ip++ ) {
2456 const auto* particle = truthVertex->outgoingParticle(ip);
2457 TLorentzVector p4; p4.SetPtEtaPhiM( particle->pt(), particle->eta(), particle->phi(), particle->m() );
2460 return p4sum_out.E() - p4sum_in.E() >= 100.;
2466 std::map<std::string, ParticleSelectFunc> selectFuncs { {
"", selectNone },
2467 {
"Kshort", selectKshort },
2468 {
"Bhadron", selectBhadron },
2469 {
"Rhadron", selectRhadron },
2470 {
"HNL", selectHNL },
2471 {
"Higgs", selectHiggs },
2472 {
"HadInt", selectHadInt } };
2475 if( selectFuncs.find(
m_jp.truthParticleFilter ) == selectFuncs.end() ) {
2476 ATH_MSG_WARNING(
" > " << __FUNCTION__ <<
": invalid function specification: " <<
m_jp.truthParticleFilter );
2480 auto selectFunc = selectFuncs.at(
m_jp.truthParticleFilter );
2483 for(
const auto *truthVertex : *truthVertices ) {
2484 if( selectFunc( truthVertex ) ) {
2487 msg += Form(
"pdgId = %d, (r, z) = (%.2f, %.2f), ", truthVertex->incomingParticle(0)->pdgId(), truthVertex->perp(), truthVertex->z());
2488 msg += Form(
"nOutgoing = %lu, ", truthVertex->nOutgoingParticles() );
2489 msg += Form(
"mass = %.3f GeV, pt = %.3f GeV", truthVertex->incomingParticle(0)->m()/1.e3, truthVertex->incomingParticle(0)->pt()/1.e3 );
2494 if(
m_jp.FillHist ) {
2496 m_hists[
"nMatchedTruths"]->Fill( 0., truthVertex->perp() );
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define minValue(current, test)
#define AmgSymMatrix(dim)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
size_t index() const
Return the index of this element within its container.
bool patternCheck(const uint32_t &pattern, const Amg::Vector3D &vertex)
std::map< std::string, PatternStrategyFunc > m_patternStrategyFuncs
const xAOD::Vertex * m_thePV
StatusCode refitVertexWithSuggestion(WrkVrt &, const Amg::Vector3D &)
refit the vertex with suggestion
bool passedFakeReject(const Amg::Vector3D &FitVertex, const xAOD::TrackParticle *itrk, const xAOD::TrackParticle *jtrk)
Flag false if the consistituent tracks are not consistent with the vertex position.
bool checkTrackHitPatternToVertex(const xAOD::TrackParticle *trk, const Amg::Vector3D &vertex)
A classical method with hard-coded geometry.
static bool patternCheckRun1(const uint32_t &pattern, const Amg::Vector3D &vertex)
bool checkTrackHitPatternToVertexByExtrapolationAssist(const xAOD::TrackParticle *trk, const Amg::Vector3D &vertex)
New method with track extrapolation.
void printWrkSet(const std::vector< WrkVrt > *WrkVrtSet, const std::string &name)
print the contents of reconstructed vertices
static bool patternCheckRun2(const uint32_t &pattern, const Amg::Vector3D &vertex)
bool checkTrackHitPatternToVertexByExtrapolation(const xAOD::TrackParticle *trk, const Amg::Vector3D &vertex)
New method with track extrapolation.
ToolHandle< IInDetConditionsTool > m_pixelCondSummaryTool
Condition service.
void trackClassification(std::vector< WrkVrt > *, std::map< long int, std::vector< long int > > &)
ExtrapolatedPattern * extrapolatedPattern(const xAOD::TrackParticle *, enum Trk::PropDirection)
double findWorstChi2ofMaximallySharedTrack(std::vector< WrkVrt > *, std::map< long int, std::vector< long int > > &, long int &, long int &)
std::unique_ptr< NtupleVars > m_ntupleVars
static bool patternCheckRun1OuterOnly(const uint32_t &pattern, const Amg::Vector3D &vertex)
void removeInconsistentTracks(WrkVrt &)
Remove inconsistent tracks from vertices.
ToolHandle< IInDetConditionsTool > m_sctCondSummaryTool
ToolHandle< Trk::IVertexMapper > m_vertexMapper
unsigned m_vertexingAlgorithmStep
bool checkTrackHitPatternToVertexOuterOnly(const xAOD::TrackParticle *trk, const Amg::Vector3D &vertex)
A classical method with hard-coded geometry.
ToolHandle< Trk::IExtrapolator > m_extrapolator
ToolHandle< Trk::ITrackToVertexIPEstimator > m_trackToVertexIPEstimatorTool
const PixelID * m_pixelId
std::map< std::string, TH1 * > m_hists
static void fillTrackSummary(track_summary &summary, const xAOD::TrackParticle *trk)
retrieve the track hit information
double improveVertexChi2(WrkVrt &)
attempt to improve the vertex chi2 by removing the most-outlier track one by one until the vertex chi...
double distanceBetweenVertices(const WrkVrt &, const WrkVrt &) const
calculate the physical distance
static size_t nTrkCommon(std::vector< WrkVrt > *WrkVrtSet, const std::pair< unsigned, unsigned > &pairIndex)
returns the number of tracks commonly present in both vertices
static double findMinVerticesNextPair(std::vector< WrkVrt > *, std::pair< unsigned, unsigned > &)
returns the next pair of vertices that give next-to-minimum distance significance
std::tuple< const TVector3, Detector, Bec, Layer, Flag > ExtrapolatedPoint
double findMinVerticesPair(std::vector< WrkVrt > *, std::pair< unsigned, unsigned > &, const AlgForVerticesPair &)
returns the pair of vertices that give minimum in terms of some observable (e.g.
const AtlasDetectorID * m_atlasId
StatusCode refitVertex(WrkVrt &)
refit the vertex.
static void removeTrackFromVertex(std::vector< WrkVrt > *, std::vector< std::deque< long int > > *, const long int &, const long int &)
ToolHandle< Reco::ITrackToVertex > m_trackToVertexTool
get a handle on the Track to Vertex tool
StatusCode processPrimaryVertices()
std::vector< ExtrapolatedPoint > ExtrapolatedPattern
const xAOD::VertexContainer * m_primaryVertices
StatusCode mergeVertices(WrkVrt &destination, WrkVrt &source)
the 2nd vertex is merged into the 1st vertex.
std::vector< const xAOD::TrackParticle * > m_associatedTracks
ToolHandle< Trk::ITrkVKalVrtFitter > m_fitSvc
std::vector< const xAOD::TrackParticle * > m_selectedTracks
StatusCode disassembleVertex(std::vector< WrkVrt > *, const unsigned &vertexIndex)
std::string m_checkPatternStrategy
double(VrtSecInclusive::*)(const WrkVrt &, const WrkVrt &) const AlgForVerticesPair
bool patternCheckOuterOnly(const uint32_t &pattern, const Amg::Vector3D &vertex)
struct JobProperties m_jp
struct VKalVrtAthena::VrtSecInclusive::track_summary_properties track_summary
ToolHandle< Trk::ITruthToTrack > m_truthToTrack
static bool patternCheckRun2OuterOnly(const uint32_t &pattern, const Amg::Vector3D &vertex)
PatternBank m_extrapolatedPatternBank
std::vector< const xAOD::TruthVertex * > m_tracingTruthVertices
void dumpTruthInformation()
double significanceBetweenVertices(const WrkVrt &, const WrkVrt &) const
calculate the significance (Mahalanobis distance) between two reconstructed vertices
std::map< const xAOD::TruthVertex *, bool > m_matchMap
bool eventType(EventType type) const
Check for one particular bitmask value.
@ IS_SIMULATION
true: simulation, false: data
float z0() const
Returns the parameter.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
float d0() const
Returns the parameter.
uint32_t hitPattern() const
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, 3, 1 > Vector3D
PropDirection
PropDirection, enum for direction of the propagation.
@ sctBarrel0
four sct barrel layers
@ pixelBarrel0
there are three or four pixel barrel layers (R1/R2)
@ sctEndCap0
and 9 sct discs (on each side)
@ pixelEndCap0
three pixel discs (on each side)
constexpr double chi2PerTrackInitValue
constexpr unsigned invalidUnsigned
constexpr double maxValue
constexpr double invalidFloat
constexpr double infinitesimal
const xAOD::TrackParticle * getLeptonTrackParticle(const xAOD::Muon *muon, const unsigned &trackType)
bool isAssociatedToVertices(const xAOD::TrackParticle *trk, const xAOD::VertexContainer *vertices)
double vtxVtxDistance(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
void genSequence(const xAOD::Muon *, std::vector< unsigned > &trackTypes)
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
const xAOD::TrackParticle * getOriginalTrackParticleFromGSF(const xAOD::TrackParticle *trkPar)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the GSF Track Particle...
@ NoVtx
Dummy vertex. TrackParticle was not used in vertex fit.
EventInfo_v1 EventInfo
Definition of the latest event info version.
TruthVertex_v1 TruthVertex
Typedef to implementation.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TruthVertexContainer_v1 TruthVertexContainer
Declare the latest version of the truth vertex container.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Muon_v1 Muon
Reference the current persistent version:
@ numberOfTRTHits
number of TRT hits [unit8_t].
@ numberOfNextToInnermostPixelLayerHits
these are the hits in the 1st pixel barrel layer
@ numberOfSCTHits
number of hits in SCT [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].
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.
Electron_v1 Electron
Definition of the current "egamma version".
double Chi2
VKalVrt fit covariance.
std::vector< double > vertexCov
VKalVrt fit vertex 4-momentum.
std::vector< double > Chi2PerTrk
VKalVrt fit chi2 result.
std::deque< long int > selectedTrackIndices
flagged true for good vertex candidates
std::deque< long int > associatedTrackIndices
list if indices in TrackParticleContainer for selectedBaseTracks
long int Charge
list of VKalVrt fit chi2 for each track
double fitQuality() const
Amg::Vector3D vertex
list if indices in TrackParticleContainer for associatedTracks
TLorentzVector vertexMom
VKalVrt fit vertex position.
double closestWrkVrtValue
stores the index of the closest WrkVrt in std::vector<WrkVrt>
std::vector< std::vector< double > > TrkAtVrt
total charge of the vertex
unsigned long closestWrkVrtIndex
list of track parameters wrt the reconstructed vertex