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 );
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() );
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++;
719 m_ntupleVars->get<
unsigned int>(
"PVType" ) = vertex->vertexType();
722 m_ntupleVars->get<
unsigned int>(
"NTrksPV" ) = vertex->nTrackParticles();
727 m_ntupleVars->get< vector<int> > (
"NdofTrksPV" ) .emplace_back( vertex->numberDoF() );
728 m_ntupleVars->get< vector<double> >(
"PVZpile" ) .emplace_back( vertex->position().z() );
732 << vertex->x() <<
","
733 << vertex->y() <<
","
734 << vertex->z() <<
","
735 << vertex->numberDoF() );
741 ATH_MSG_DEBUG(
"No Reconstructed PV was found. Using the dummy PV instead.");
753 m_ntupleVars->get<
unsigned int>(
"PVType" ) = vertex->vertexType();
756 m_ntupleVars->get<
unsigned int>(
"NTrksPV" ) = vertex->nTrackParticles();
765 return StatusCode::FAILURE;
770 return StatusCode::SUCCESS;
779 trackToVertexMap.clear();
781 for(
size_t iv = 0; iv<workVerticesContainer->size(); iv++ ) {
783 WrkVrt& vertex = workVerticesContainer->at(iv);
785 auto& trackIndices = vertex.selectedTrackIndices;
786 if( !vertex.isGood )
continue;
787 if( trackIndices.size() < 2 )
continue;
789 for(
auto&
index : trackIndices ) {
790 trackToVertexMap[
index].emplace_back( iv );
794 for(
auto& pair: trackToVertexMap ) {
795 std::string
msg = Form(
"track index [%ld]: vertices = (", pair.first);
796 for(
auto& v : pair.second ) {
797 msg += Form(
"%ld, ", v);
808 std::map<
long int, std::vector<long int> >& trackToVertexMap,
809 long int & maxSharedTrack,
810 long int & worstMatchingVertex)
816 auto maxSharedTrackToVertices = std::max_element( trackToVertexMap.begin(), trackToVertexMap.end(), [](
auto& p1,
auto& p2 ) { return p1.second.size() < p2.second.size(); } );
818 if( maxSharedTrackToVertices == trackToVertexMap.end() )
return worstChi2;
820 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": max-shared track index = " << maxSharedTrackToVertices->first <<
", number of shared vertices = " << maxSharedTrackToVertices->second.size() );
822 if( maxSharedTrackToVertices->second.size() < 2 )
return worstChi2;
825 std::map<long int, double> vrtChi2Map;
828 for(
auto& iv : maxSharedTrackToVertices->second ) {
829 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": loop over vertices: vertex index " << iv );
831 auto& wrkvrt = workVerticesContainer->at( iv );
832 auto& trackIndices = wrkvrt.selectedTrackIndices;
835 auto index = std::find_if( trackIndices.begin(), trackIndices.end(), [&](
auto&
index ) { return index == maxSharedTrackToVertices->first; } );
836 if(
index == trackIndices.end() ) {
837 ATH_MSG_WARNING(
" >> " << __FUNCTION__ <<
": index not found (algorithm inconsistent)" );
841 auto&
chi2 = wrkvrt.Chi2PerTrk.at(
index - trackIndices.begin() );
843 vrtChi2Map.emplace( std::pair<long int, double>(iv,
chi2) );
846 auto worstVrtChi2Pair = std::max_element( vrtChi2Map.begin(), vrtChi2Map.end(), [](
auto& p1,
auto& p2 ) { return p1.second < p2.second; } );
848 if( worstVrtChi2Pair == vrtChi2Map.end() ) {
849 ATH_MSG_WARNING(
" >> " << __FUNCTION__ <<
": max_element of vrtChi2Map not found" );
853 maxSharedTrack = maxSharedTrackToVertices->first;
854 worstMatchingVertex = worstVrtChi2Pair->first;
855 worstChi2 = worstVrtChi2Pair->second;
864 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": ===============================================================" );
865 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": " << name <<
": #vertices = " << workVerticesContainer->size() );
867 std::set<const xAOD::TrackParticle*> usedTracks;
869 auto concatenateIndicesToString = [](
auto indices,
auto& collection ) -> std::string {
870 if( 0 == indices.size() )
return "";
871 return std::accumulate( std::next(indices.begin()), indices.end(), std::to_string( indices.at(0) ),
872 [&collection](
const std::string&
str,
auto&
index ) { return str +
", " + std::to_string( collection.at(index)->index() ); } );
875 std::map<const xAOD::TruthVertex*, bool> previous;
877 for(
auto& pair :
m_matchMap ) { previous.emplace( pair.first, pair.second ); }
882 for(
size_t iv=0; iv<workVerticesContainer->size(); iv++) {
883 const auto& wrkvrt = workVerticesContainer->at(iv);
885 if( wrkvrt.nTracksTotal() < 2 )
continue;
887 std::string sels = concatenateIndicesToString( wrkvrt.selectedTrackIndices,
m_selectedTracks );
888 std::string assocs = concatenateIndicesToString( wrkvrt.associatedTrackIndices,
m_associatedTracks );
893 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": " << name <<
" vertex [" << iv <<
"]: " << &wrkvrt
894 <<
", isGood = " << (wrkvrt.isGood?
"true" :
"false")
895 <<
", #ntrks(tot, sel, assoc) = (" << wrkvrt.nTracksTotal() <<
", " << wrkvrt.selectedTrackIndices.size() <<
", " << wrkvrt.associatedTrackIndices.size() <<
"), "
896 <<
", chi2/ndof = " << wrkvrt.fitQuality()
897 <<
", (r, z) = (" << wrkvrt.vertex.perp()
898 <<
", " << wrkvrt.vertex.z() <<
")"
899 <<
", sels = { " << sels <<
" }"
900 <<
", assocs = { " << assocs <<
" }" );
906 Amg::Vector3D vTruth( truthVertex->x(), truthVertex->y(), truthVertex->z() );
907 Amg::Vector3D vReco ( wrkvrt.vertex.x(), wrkvrt.vertex.y(), wrkvrt.vertex.z() );
909 const auto distance = vReco - vTruth;
912 cov.fillSymmetric( 0, 0, wrkvrt.vertexCov.at(0) );
913 cov.fillSymmetric( 1, 0, wrkvrt.vertexCov.at(1) );
914 cov.fillSymmetric( 1, 1, wrkvrt.vertexCov.at(2) );
915 cov.fillSymmetric( 2, 0, wrkvrt.vertexCov.at(3) );
916 cov.fillSymmetric( 2, 1, wrkvrt.vertexCov.at(4) );
917 cov.fillSymmetric( 2, 2, wrkvrt.vertexCov.at(5) );
919 const double s2 = distance.transpose() * cov.inverse() * distance;
921 if( distance.norm() < 2.0 || s2 < 100. )
m_matchMap.at( truthVertex ) =
true;
927 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": number of used tracks = " << usedTracks.size() );
929 if( !previous.empty() && previous.size() ==
m_matchMap.size() ) {
931 if( previous.find( pair.first ) == previous.end() )
continue;
932 if( pair.second != previous.at( pair.first ) ) {
933 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": Match flag has changed: (r, z) = (" << pair.first->perp() <<
", " << pair.first->z() <<
")" );
945 for(
const auto* trk : usedTracks ) {
msg += Form(
"%ld, ", trk->index() ); }
948 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": ===============================================================" );
955 summary.numIBLHits = 0;
956 summary.numBLayerHits = 0;
957 summary.numPixelHits = 0;
958 summary.numSctHits = 0;
959 summary.numTrtHits = 0;
974 const EventContext& ctx = Gaudi::Hive::currentContext();
975 std::vector<std::unique_ptr<Trk::TrackParameters>> paramsVector =
982 for(
auto& params : paramsVector ) {
984 const TVector3 position( params->position().x(), params->position().y(), params->position().z() );
986 if( prevPos == position ) {
992 const auto* detElement = params->associatedSurface().associatedDetectorElement();
998 const auto&
id = detElement->identify();
1003 auto idHash =
m_pixelId->wafer_hash(
id );
1006 pattern->emplace_back( std::make_tuple( position,
Pixel,
m_pixelId->barrel_ec(
id),
m_pixelId->layer_disk(
id), good ) );
1010 auto idHash =
m_sctId->wafer_hash(
id );
1013 pattern->emplace_back( std::make_tuple( position,
SCT,
m_sctId->barrel_ec(
id),
m_sctId->layer_disk(
id), good ) );
1017 if( !pattern->empty() ) {
1019 ATH_MSG_VERBOSE(
" >> " << __FUNCTION__ <<
", track " << trk <<
": position = (" << position.Perp() <<
", " << position.z() <<
", " << position.Phi() <<
"), detElement ID = " <<
id <<
", good = " << good
1020 <<
": (det, bec, layer) = (" << std::get<1>( pattern->back() ) <<
", " << std::get<2>( pattern->back() ) <<
", " << std::get<3>( pattern->back() ) <<
")" );
1022 if( !good ) nDisabled++;
1030 m_hists[
"disabledCount"]->Fill( nDisabled );
1053 using LayerCombination = std::vector<int>;
1055 std::map<LayerCombination, unsigned> layerMap;
1056 if( layerMap.empty() ) {
1094 enum { position=0, detector=1, bec=2, layer=3, isGood=4 };
1099 const LayerCombination comb { std::get<detector>( point ), std::get<bec>( point ), std::get<layer>( point ) };
1101 for(
auto& pair : layerMap ) {
1102 if( pair.first == comb ) {
1110 enum { kShouldNotHaveHit, kShouldHaveHit, kMayHaveHit };
1116 auto& exPattern_along = *( exPattern.first );
1118 for(
auto itr = exPattern_along.begin(); itr != exPattern_along.end(); ++itr ) {
1119 if( std::next( itr ) == exPattern_along.end() )
continue;
1121 const auto& point = *itr;
1122 const auto& nextPoint = *( std::next( itr ) );
1124 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": isGood = " << std::get<isGood>( point ) );
1126 const auto& thisPos = std::get<position>( point );
1127 const auto& nextPos = std::get<position>( nextPoint );
1129 auto sectionVector = nextPos - thisPos;
1130 auto vertexVector = TVector3( vertex.x(), vertex.y(), vertex.z() ) - thisPos;
1133 const auto& detectorType = getDetectorType( point );
1135 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": detType = " << detectorType );
1141 if( vertexVector.Mag() < 10. ) {
1142 expectedHitPattern.at( detectorType ) = kMayHaveHit;
1148 if( !
static_cast<bool>(std::get<isGood>( point )) ) {
1149 expectedHitPattern.at( detectorType ) = kMayHaveHit;
1158 if( sectionVector.Mag() == 0. )
continue;
1161 <<
": hitPos = (" << thisPos.Perp() <<
", " << thisPos.z() <<
", " << thisPos.Phi() <<
")"
1162 <<
", sectionVec = (" << sectionVector.Perp() <<
", " << sectionVector.z() <<
", " << sectionVector.Phi() <<
")"
1163 <<
", vertexVec = (" << vertexVector.Perp() <<
", " << vertexVector.z() <<
", " << vertexVector.Phi() <<
")"
1164 <<
", cos(s,v) = " << sectionVector * vertexVector / ( sectionVector.Mag() * vertexVector.Mag() +
AlgConsts::infinitesimal ) );
1166 if( sectionVector * vertexVector > 0. )
continue;
1168 if( minExpectedRadius > thisPos.Perp() ) minExpectedRadius = thisPos.Perp();
1172 expectedHitPattern.at( detectorType ) = kShouldHaveHit;
1176 auto& exPattern_oppos = *( exPattern.second );
1177 bool oppositeFlag =
false;
1179 for(
auto itr = exPattern_oppos.begin(); itr != exPattern_oppos.end(); ++itr ) {
1180 if( std::next( itr ) == exPattern_oppos.end() )
continue;
1182 const auto& point = *itr;
1183 const auto& nextPoint = *( std::next( itr ) );
1185 const auto& thisPos = std::get<position>( point );
1186 const auto& nextPos = std::get<position>( nextPoint );
1188 auto sectionVector = nextPos - thisPos;
1189 auto vertexVector = TVector3( vertex.x(), vertex.y(), vertex.z() ) - thisPos;
1191 const auto& detectorType = getDetectorType( point );
1193 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": detType = " << detectorType );
1196 <<
": hitPos = (" << thisPos.Perp() <<
", " << thisPos.z() <<
", " << thisPos.Phi() <<
")"
1197 <<
", vertex = (" << vertex.perp() <<
", " << vertex.z() <<
", " << vertex.phi() <<
")"
1198 <<
", cos(s,v) = " << sectionVector * vertexVector / ( sectionVector.Mag() * vertexVector.Mag() +
AlgConsts::infinitesimal ) );
1203 if( sectionVector * vertexVector < 0. ) {
1204 oppositeFlag =
true;
1213 std::string
msg =
"Expected hit pattern: ";
1215 msg += Form(
"%s", expectedHitPattern.at(i) < kMayHaveHit? Form(
"%u", expectedHitPattern.at(i)) :
"X" );
1219 msg =
"Recorded hit pattern: ";
1225 std::vector<unsigned> matchedLayers;
1228 const unsigned recordedPattern = ( (trk->
hitPattern()>>i) & 1 );
1230 if( expectedHitPattern.at(i) == kMayHaveHit ) {
1231 matchedLayers.emplace_back( i );
1232 }
else if( expectedHitPattern.at(i) == kShouldHaveHit ) {
1233 if( expectedHitPattern.at(i) != recordedPattern ) {
1236 matchedLayers.emplace_back( i );
1239 if( expectedHitPattern.at(i) != recordedPattern ) {
1246 uint8_t PixelHits = 0;
1247 uint8_t SctHits = 0;
1248 uint8_t TRTHits = 0;
1253 auto dphi = trk->
phi() - vertex.phi();
1254 while( dphi > TMath::Pi() ) dphi -= TMath::TwoPi();
1255 while( dphi < -TMath::Pi() ) dphi += TMath::TwoPi();
1257 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vtx phi = " << vertex.phi() <<
", track phi = " << trk->
phi() <<
", dphi = " << dphi
1258 <<
", oppositeFlag = " << oppositeFlag
1259 <<
", nPixelHits = " <<
static_cast<int>(PixelHits)
1260 <<
", nSCTHits = " <<
static_cast<int>(SctHits)
1261 <<
", nTRTHits = " <<
static_cast<int>(TRTHits)
1262 <<
", nMatchedLayers = " << matchedLayers.size() );
1264 if( PixelHits == 0 && vertex.perp() > 300. ) {
1265 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertex r > 300 mm, w/o no pixel hits" );
1270 if( matchedLayers.size() < 2 )
return false;
1274 if( matchedLayers.size() < 4 )
return false;
1280 if( oppositeFlag )
return false;
1286 if( fabs( dphi ) > TMath::Pi()/2.0 )
return false;
1289 TVector3 trkP; trkP.SetPtEtaPhi( trk->
pt(), trk->
eta(), trk->
phi() );
1290 TVector3 vtx; vtx.SetXYZ( vertex.x(), vertex.y(), vertex.z() );
1291 if( trkP.Dot( vtx ) < 0. )
return false;
1310 const double rad = vertex.perp();
1311 const double absz = fabs( vertex.z() );
1320 outsidePixelBarrel0_and_insidePixelBarrel1,
1323 outsidePixelBarrel1_and_insidePixelBarrel2,
1326 outsidePixelBarrel2_and_insidePixelBarrel3,
1329 outsidePixelBarrel3_and_insideSctBarrel0,
1332 outsideSctBarrel0_and_insideSctBarrel1,
1337 int vertex_pattern = 0;
1339 vertex_pattern = insideBeamPipe;
1341 }
else if( rad < 31.0 && absz < 331.5 ) {
1342 vertex_pattern = insidePixelBarrel0;
1344 }
else if( rad < 38.4 && absz < 331.5 ) {
1345 vertex_pattern = aroundPixelBarrel0;
1347 }
else if( rad < 47.7 && absz < 400.5 ) {
1348 vertex_pattern = outsidePixelBarrel0_and_insidePixelBarrel1;
1350 }
else if( rad < 54.4 && absz < 400.5 ) {
1351 vertex_pattern = aroundPixelBarrel1;
1353 }
else if( rad < 85.5 && absz < 400.5 ) {
1354 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1356 }
else if( rad < 92.2 && absz < 400.5 ) {
1357 vertex_pattern = aroundPixelBarrel2;
1359 }
else if( rad < 119.3 && absz < 400.5 ) {
1360 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1362 }
else if( rad < 126.1 && absz < 400.5 ) {
1363 vertex_pattern = aroundPixelBarrel3;
1365 }
else if( rad < 290 && absz < 749.0 ) {
1366 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1368 }
else if( rad < 315 && absz < 749.0 ) {
1369 vertex_pattern = aroundSctBarrel0;
1371 }
else if( rad < 360 && absz < 749.0 ) {
1372 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1374 }
else if( rad < 390 && absz < 749.0 ) {
1375 vertex_pattern = aroundSctBarrel1;
1380 unsigned nPixelLayers { 0 };
1392 if( vertex_pattern == insideBeamPipe ) {
1395 if( nPixelLayers < 3 )
return false;
1398 }
else if( vertex_pattern == insidePixelBarrel0 ) {
1401 if( nPixelLayers < 3 )
return false;
1405 else if( vertex_pattern == aroundPixelBarrel0 ) {
1409 if( nPixelLayers < 2 )
return false;
1413 else if( vertex_pattern == outsidePixelBarrel0_and_insidePixelBarrel1 ) {
1417 if( nPixelLayers < 2 )
return false;
1421 else if( vertex_pattern == aroundPixelBarrel1 ) {
1426 if( nPixelLayers < 2 )
return false;
1430 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1435 if( nPixelLayers < 2 )
return false;
1439 else if( vertex_pattern == aroundPixelBarrel2 ) {
1448 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1456 else if( vertex_pattern == aroundPixelBarrel3 ) {
1466 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1476 else if( vertex_pattern == aroundSctBarrel0 ) {
1487 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
1498 else if( vertex_pattern == aroundSctBarrel1 ) {
1524 const double rad = vertex.perp();
1525 const double absz = fabs( vertex.z() );
1534 outsidePixelBarrel0_and_insidePixelBarrel1,
1537 outsidePixelBarrel1_and_insidePixelBarrel2,
1540 outsidePixelBarrel2_and_insidePixelBarrel3,
1543 outsidePixelBarrel3_and_insideSctBarrel0,
1546 outsideSctBarrel0_and_insideSctBarrel1,
1551 int vertex_pattern = 0;
1553 vertex_pattern = insideBeamPipe;
1555 }
else if( rad < 31.0 && absz < 331.5 ) {
1556 vertex_pattern = insidePixelBarrel0;
1558 }
else if( rad < 38.4 && absz < 331.5 ) {
1559 vertex_pattern = aroundPixelBarrel0;
1561 }
else if( rad < 47.7 && absz < 400.5 ) {
1562 vertex_pattern = outsidePixelBarrel0_and_insidePixelBarrel1;
1564 }
else if( rad < 54.4 && absz < 400.5 ) {
1565 vertex_pattern = aroundPixelBarrel1;
1567 }
else if( rad < 85.5 && absz < 400.5 ) {
1568 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1570 }
else if( rad < 92.2 && absz < 400.5 ) {
1571 vertex_pattern = aroundPixelBarrel2;
1573 }
else if( rad < 119.3 && absz < 400.5 ) {
1574 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1576 }
else if( rad < 126.1 && absz < 400.5 ) {
1577 vertex_pattern = aroundPixelBarrel3;
1579 }
else if( rad < 290 && absz < 749.0 ) {
1580 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1582 }
else if( rad < 315 && absz < 749.0 ) {
1583 vertex_pattern = aroundSctBarrel0;
1585 }
else if( rad < 360 && absz < 749.0 ) {
1586 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1588 }
else if( rad < 390 && absz < 749.0 ) {
1589 vertex_pattern = aroundSctBarrel1;
1595 unsigned nPixelLayers { 0 };
1607 if( vertex_pattern == insideBeamPipe ) {
1611 if( nPixelLayers < 3 )
return false;
1613 }
else if( vertex_pattern == insidePixelBarrel0 ) {
1617 if( nPixelLayers < 3 )
return false;
1622 else if( vertex_pattern == aroundPixelBarrel0 ) {
1627 if( nPixelLayers < 3 )
return false;
1631 else if( vertex_pattern == outsidePixelBarrel0_and_insidePixelBarrel1 ) {
1635 if( nPixelLayers < 3 )
return false;
1639 else if( vertex_pattern == aroundPixelBarrel1 ) {
1644 if( nPixelLayers < 2 )
return false;
1648 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1652 if( nPixelLayers < 2 )
return false;
1656 else if( vertex_pattern == aroundPixelBarrel2 ) {
1663 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1668 else if( vertex_pattern == aroundPixelBarrel3 ) {
1676 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1683 else if( vertex_pattern == aroundSctBarrel0 ) {
1691 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
1698 else if( vertex_pattern == aroundSctBarrel1 ) {
1718 const double rad = vertex.perp();
1719 const double absz = fabs( vertex.z() );
1728 outsidePixelBarrel1_and_insidePixelBarrel2,
1731 outsidePixelBarrel2_and_insidePixelBarrel3,
1734 outsidePixelBarrel3_and_insideSctBarrel0,
1737 outsideSctBarrel0_and_insideSctBarrel1,
1742 Int_t vertex_pattern = 0;
1744 vertex_pattern = insideBeamPipe;
1746 }
else if( rad < 47.7 && absz < 400.5 ) {
1747 vertex_pattern = insidePixelBarrel1;
1749 }
else if( rad < 54.4 && absz < 400.5 ) {
1750 vertex_pattern = aroundPixelBarrel1;
1752 }
else if( rad < 85.5 && absz < 400.5 ) {
1753 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1755 }
else if( rad < 92.2 && absz < 400.5 ) {
1756 vertex_pattern = aroundPixelBarrel2;
1758 }
else if( rad < 119.3 && absz < 400.5 ) {
1759 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1761 }
else if( rad < 126.1 && absz < 400.5 ) {
1762 vertex_pattern = aroundPixelBarrel3;
1764 }
else if( rad < 290 && absz < 749.0 ) {
1765 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1767 }
else if( rad < 315 && absz < 749.0 ) {
1768 vertex_pattern = aroundSctBarrel0;
1770 }
else if( rad < 360 && absz < 749.0 ) {
1771 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1773 }
else if( rad < 390 && absz < 749.0 ) {
1774 vertex_pattern = aroundSctBarrel1;
1781 if( vertex_pattern == insideBeamPipe ) {
1788 else if( vertex_pattern == insidePixelBarrel1 ) {
1794 else if( vertex_pattern == aroundPixelBarrel1 ) {
1801 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1808 else if( vertex_pattern == aroundPixelBarrel2 ) {
1816 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1823 else if( vertex_pattern == aroundPixelBarrel3 ) {
1832 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1841 else if( vertex_pattern == aroundSctBarrel0 ) {
1851 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
1861 else if( vertex_pattern == aroundSctBarrel1 ) {
1883 const double rad = vertex.perp();
1884 const double absz = fabs( vertex.z() );
1893 outsidePixelBarrel1_and_insidePixelBarrel2,
1896 outsidePixelBarrel2_and_insidePixelBarrel3,
1899 outsidePixelBarrel3_and_insideSctBarrel0,
1902 outsideSctBarrel0_and_insideSctBarrel1,
1907 Int_t vertex_pattern = 0;
1909 vertex_pattern = insideBeamPipe;
1911 }
else if( rad < 47.7 && absz < 400.5 ) {
1912 vertex_pattern = insidePixelBarrel1;
1914 }
else if( rad < 54.4 && absz < 400.5 ) {
1915 vertex_pattern = aroundPixelBarrel1;
1917 }
else if( rad < 85.5 && absz < 400.5 ) {
1918 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1920 }
else if( rad < 92.2 && absz < 400.5 ) {
1921 vertex_pattern = aroundPixelBarrel2;
1923 }
else if( rad < 119.3 && absz < 400.5 ) {
1924 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1926 }
else if( rad < 126.1 && absz < 400.5 ) {
1927 vertex_pattern = aroundPixelBarrel3;
1929 }
else if( rad < 290 && absz < 749.0 ) {
1930 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1932 }
else if( rad < 315 && absz < 749.0 ) {
1933 vertex_pattern = aroundSctBarrel0;
1935 }
else if( rad < 360 && absz < 749.0 ) {
1936 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1938 }
else if( rad < 390 && absz < 749.0 ) {
1939 vertex_pattern = aroundSctBarrel1;
1946 if( vertex_pattern == insideBeamPipe ) {
1953 else if( vertex_pattern == insidePixelBarrel1 ) {
1959 else if( vertex_pattern == aroundPixelBarrel1 ) {
1966 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1972 else if( vertex_pattern == aroundPixelBarrel2 ) {
1979 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1984 else if( vertex_pattern == aroundPixelBarrel3 ) {
1991 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1997 else if( vertex_pattern == aroundSctBarrel0 ) {
2004 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
2010 else if( vertex_pattern == aroundSctBarrel1 ) {
2079 if( vertex.perp() < 31.0 ) {
2080 double dphi = trk->
phi() - vertex.phi();
2081 while( dphi > TMath::Pi() ) { dphi -= TMath::TwoPi(); }
2082 while( dphi < -TMath::Pi() ) { dphi += TMath::TwoPi(); }
2083 if( cos(dphi) < -0.8 )
return false;
2088 using LayerCombination = std::vector<int>;
2090 std::map<LayerCombination, unsigned> layerMap;
2091 if( layerMap.empty() ) {
2129 enum { position=0, detector=1, bec=2, layer=3, isGood=4 };
2134 const LayerCombination comb { std::get<detector>( point ), std::get<bec>( point ), std::get<layer>( point ) };
2136 for(
auto& pair : layerMap ) {
2137 if( pair.first == comb ) {
2145 uint32_t disabledPattern { 0 };
2148 auto& exPattern_along = *( exPattern.first );
2150 for(
auto itr = exPattern_along.begin(); itr != exPattern_along.end(); ++itr ) {
2151 if( std::next( itr ) == exPattern_along.end() )
continue;
2153 const auto& point = *itr;
2155 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": isGood = " << std::get<isGood>( point ) );
2157 if( !std::get<isGood>( point ) ) {
2158 const auto& detectorType = getDetectorType( point );
2159 disabledPattern += (1 << detectorType);
2164 uint32_t modifiedPattern = disabledPattern | hitPattern;
2166 std::string
msg =
"Disabled hit pattern: ";
2168 msg += Form(
"%u", ( disabledPattern >> i ) & 1 );
2172 msg =
"Recorded hit pattern: ";
2174 msg += Form(
"%u", ( hitPattern >> i ) & 1 );
2192 return ( check_itrk && check_jtrk );
2201 const auto& vertex = wrkvrt.
vertex;
2203 std::map< std::deque<long int>*, std::vector<const xAOD::TrackParticle*>& > indexMap
2208 for(
auto& pair : indexMap ) {
2210 auto* indices = pair.first;
2211 auto& tracks = pair.second;
2214 [&](
auto&
index ) {
2215 bool isConsistent = (this->*m_patternStrategyFuncs[m_checkPatternStrategy] )( tracks.at(index), vertex );
2216 return !isConsistent;
2219 indices->erase( newEnd, indices->end() );
2233 auto sc0 =
evtStore()->retrieve( eventInfo,
"EventInfo" );
2234 if( sc0.isFailure() ) {
return; }
2240 auto sc1 =
evtStore()->retrieve( truthParticles,
"TruthParticles" );
2241 if( sc1.isFailure() ) {
return; }
2243 auto sc2 =
evtStore()->retrieve( truthVertices,
"TruthVertices" );
2244 if( sc2.isFailure() ) {
return; }
2246 if( !truthParticles ) {
return; }
2247 if( !truthVertices ) {
return; }
2251 std::vector<const xAOD::TruthParticle*> truthSvTracks;
2258 if( truthVertex->nIncomingParticles() != 1 )
return false;
2259 if( !truthVertex->incomingParticle(0) )
return false;
2260 if( abs(truthVertex->incomingParticle(0)->pdgId()) < 1000000 )
return false;
2261 if( abs(truthVertex->incomingParticle(0)->pdgId()) > 1000000000 )
return false;
2263 bool hasNeutralino =
false;
2264 for(
unsigned ip = 0; ip < truthVertex->nOutgoingParticles(); ip++ ) {
2265 const auto* p = truthVertex->outgoingParticle(ip);
2266 if( abs( p->pdgId() ) == 1000022 ) {
2267 hasNeutralino =
true;
2271 return hasNeutralino;
2275 if( truthVertex->nIncomingParticles() != 1 )
return false;
2276 if( !truthVertex->incomingParticle(0) )
return false;
2277 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 50 )
return false;
2282 if( truthVertex->nIncomingParticles() != 1 )
return false;
2283 if( !truthVertex->incomingParticle(0) )
return false;
2284 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 36 )
return false;
2289 if( truthVertex->nIncomingParticles() != 1 )
return false;
2290 if( !truthVertex->incomingParticle(0) )
return false;
2291 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 310 )
return false;
2296 if( truthVertex->nIncomingParticles() != 1 )
return false;
2297 if( !truthVertex->incomingParticle(0) )
return false;
2298 if( abs(truthVertex->incomingParticle(0)->pdgId()) <= 500 || abs(truthVertex->incomingParticle(0)->pdgId()) >= 600 )
return false;
2303 if( truthVertex->nIncomingParticles() != 1 )
return false;
2304 if( !truthVertex->incomingParticle(0) )
return false;
2306 const auto* parent = truthVertex->incomingParticle(0);
2307 if( parent->isLepton() )
return false;
2309 TLorentzVector p4sum_in;
2310 TLorentzVector p4sum_out;
2311 for(
unsigned ip = 0; ip < truthVertex->nIncomingParticles(); ip++ ) {
2312 const auto* particle = truthVertex->incomingParticle(ip);
2313 TLorentzVector p4; p4.SetPtEtaPhiM( particle->pt(), particle->eta(), particle->phi(), particle->m() );
2316 for(
unsigned ip = 0; ip < truthVertex->nOutgoingParticles(); ip++ ) {
2317 const auto* particle = truthVertex->outgoingParticle(ip);
2318 TLorentzVector p4; p4.SetPtEtaPhiM( particle->pt(), particle->eta(), particle->phi(), particle->m() );
2321 return p4sum_out.E() - p4sum_in.E() >= 100.;
2327 std::map<std::string, ParticleSelectFunc> selectFuncs { {
"", selectNone },
2328 {
"Kshort", selectKshort },
2329 {
"Bhadron", selectBhadron },
2330 {
"Rhadron", selectRhadron },
2331 {
"HNL", selectHNL },
2332 {
"Higgs", selectHiggs },
2333 {
"HadInt", selectHadInt } };
2344 for(
const auto *truthVertex : *truthVertices ) {
2345 if( selectFunc( truthVertex ) ) {
2348 msg += Form(
"pdgId = %d, (r, z) = (%.2f, %.2f), ", truthVertex->incomingParticle(0)->pdgId(), truthVertex->perp(), truthVertex->z());
2349 msg += Form(
"nOutgoing = %lu, ", truthVertex->nOutgoingParticles() );
2350 msg += Form(
"mass = %.3f GeV, pt = %.3f GeV", truthVertex->incomingParticle(0)->m()/1.e3, truthVertex->incomingParticle(0)->pt()/1.e3 );
2357 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)
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)
Gaudi::Property< std::string > m_truthParticleFilter
void removeInconsistentTracks(WrkVrt &)
Remove inconsistent tracks from vertices.
ToolHandle< IInDetConditionsTool > m_sctCondSummaryTool
Gaudi::Property< int > m_geoModel
unsigned m_vertexingAlgorithmStep
Gaudi::Property< bool > m_FillHist
bool checkTrackHitPatternToVertexOuterOnly(const xAOD::TrackParticle *trk, const Amg::Vector3D &vertex)
A classical method with hard-coded geometry.
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
Gaudi::Property< bool > m_FillNtuple
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.
Gaudi::Property< std::string > m_checkPatternStrategy
static void removeTrackFromVertex(std::vector< WrkVrt > *, std::vector< std::deque< long int > > *, const long int &, const long int &)
PublicToolHandle< Trk::IExtrapolator > m_extrapolator
StatusCode processPrimaryVertices()
Gaudi::Property< double > m_improveChi2ProbThreshold
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)
double(VrtSecInclusive::*)(const WrkVrt &, const WrkVrt &) const AlgForVerticesPair
bool patternCheckOuterOnly(const uint32_t &pattern, const Amg::Vector3D &vertex)
struct VKalVrtAthena::VrtSecInclusive::track_summary_properties track_summary
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