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(ctx);
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;
499 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState(ctx);
511 vector<const xAOD::NeutralParticle*> dummyNeutrals;
516 workVertex.
isGood =
false;
517 return StatusCode::SUCCESS;
520 vector<const xAOD::TrackParticle*> ListBaseTracks;
534 auto& vertexPos = workVertex.
vertex;
536 m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), istate );
538 ATH_MSG_VERBOSE(
" >>> refitVertex: ListBaseTracks.size = " << ListBaseTracks.size()
541 for(
const auto *trk : ListBaseTracks ) {
549 StatusCode
sc =
m_fitSvc->VKalVrtFitFast( ListBaseTracks, initVertex, istate );
550 if(
sc.isFailure())
ATH_MSG_DEBUG(
" >>> refitVertex: fast crude estimation failed.");
551 ATH_MSG_VERBOSE(
" >>> refitVertex: Fast VKalVrtFit succeeded. vertex (r,z) = (" << initVertex.perp() <<
", " << initVertex.z() <<
", " <<
")" );
555 m_fitSvc->setApproximateVertex( vertexPos.x(), vertexPos.y(), vertexPos.z(), istate );
559 m_fitSvc->setApproximateVertex( initVertex.x(), initVertex.y(), initVertex.z(), istate );
563 ATH_MSG_VERBOSE(
" >>> refitVertex: approx vertex is set. Now going to perform fitting..." );
565 StatusCode SC=
m_fitSvc->VKalVrtFit(ListBaseTracks,dummyNeutrals,
577 if(SC.isFailure())
ATH_MSG_DEBUG(
" >>> refitVertex: SC in refitVertex returned failure ");
579 ATH_MSG_VERBOSE(
" >>> refitVertex: succeeded in fitting. New vertex pos (r,z) = (" << vertexPos.perp() <<
", " << vertexPos.z() <<
")" );
580 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) <<
")" );
588 std::unique_ptr<Trk::IVKalState> state =
m_fitSvc->makeState(ctx);
600 vector<const xAOD::NeutralParticle*> dummyNeutrals;
605 workVertex.
isGood =
false;
606 return StatusCode::SUCCESS;
609 vector<const xAOD::TrackParticle*> ListBaseTracks;
623 auto& vertexPos = workVertex.
vertex;
625 m_fitSvc->setApproximateVertex( suggestedPosition.x(), suggestedPosition.y(), suggestedPosition.z(), istate );
627 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": ListBaseTracks.size = " << ListBaseTracks.size()
630 for(
const auto *trk : ListBaseTracks ) {
631 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": track index = " << trk->index() );
636 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": approx vertex is set. Now going to perform fitting..." );
638 StatusCode SC=
m_fitSvc->VKalVrtFit(ListBaseTracks,dummyNeutrals,
650 if( SC.isFailure() )
ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": SC in refitVertex returned failure ");
653 if( SC.isSuccess() ) {
654 ATH_MSG_VERBOSE(
" >>> " << __FUNCTION__ <<
": succeeded in fitting. New vertex pos = (" << vertexPos.x() <<
", " << vertexPos.y() <<
", " << vertexPos.z() <<
")" );
655 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) <<
")" );
669 auto& trackIndices1 = workVerticesContainer->at( pairIndex.first ).selectedTrackIndices;
670 auto& trackIndices2 = workVerticesContainer->at( pairIndex.second ).selectedTrackIndices;
672 if( trackIndices1.size() < 2 )
return 0;
673 if( trackIndices2.size() < 2 )
return 0;
677 for(
auto&
index : trackIndices1 ) {
678 if( std::find(trackIndices2.begin(),trackIndices2.end(),
index) != trackIndices2.end()) nTrkCom++;
720 m_ntupleVars->get<
unsigned int>(
"PVType" ) = vertex->vertexType();
723 m_ntupleVars->get<
unsigned int>(
"NTrksPV" ) = vertex->nTrackParticles();
728 m_ntupleVars->get< vector<int> > (
"NdofTrksPV" ) .emplace_back( vertex->numberDoF() );
729 m_ntupleVars->get< vector<double> >(
"PVZpile" ) .emplace_back( vertex->position().z() );
733 << vertex->x() <<
","
734 << vertex->y() <<
","
735 << vertex->z() <<
","
736 << vertex->numberDoF() );
742 ATH_MSG_DEBUG(
"No Reconstructed PV was found. Using the dummy PV instead.");
754 m_ntupleVars->get<
unsigned int>(
"PVType" ) = vertex->vertexType();
757 m_ntupleVars->get<
unsigned int>(
"NTrksPV" ) = vertex->nTrackParticles();
766 return StatusCode::FAILURE;
771 return StatusCode::SUCCESS;
780 trackToVertexMap.clear();
782 for(
size_t iv = 0; iv<workVerticesContainer->size(); iv++ ) {
784 WrkVrt& vertex = workVerticesContainer->at(iv);
786 auto& trackIndices = vertex.selectedTrackIndices;
787 if( !vertex.isGood )
continue;
788 if( trackIndices.size() < 2 )
continue;
790 for(
auto&
index : trackIndices ) {
791 trackToVertexMap[
index].emplace_back( iv );
795 for(
auto& pair: trackToVertexMap ) {
796 std::string
msg = Form(
"track index [%ld]: vertices = (", pair.first);
797 for(
auto& v : pair.second ) {
798 msg += Form(
"%ld, ", v);
809 std::map<
long int, std::vector<long int> >& trackToVertexMap,
810 long int & maxSharedTrack,
811 long int & worstMatchingVertex)
817 auto maxSharedTrackToVertices = std::max_element( trackToVertexMap.begin(), trackToVertexMap.end(), [](
auto& p1,
auto& p2 ) { return p1.second.size() < p2.second.size(); } );
819 if( maxSharedTrackToVertices == trackToVertexMap.end() )
return worstChi2;
821 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": max-shared track index = " << maxSharedTrackToVertices->first <<
", number of shared vertices = " << maxSharedTrackToVertices->second.size() );
823 if( maxSharedTrackToVertices->second.size() < 2 )
return worstChi2;
826 std::map<long int, double> vrtChi2Map;
829 for(
auto& iv : maxSharedTrackToVertices->second ) {
830 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": loop over vertices: vertex index " << iv );
832 auto& wrkvrt = workVerticesContainer->at( iv );
833 auto& trackIndices = wrkvrt.selectedTrackIndices;
836 auto index = std::find_if( trackIndices.begin(), trackIndices.end(), [&](
auto&
index ) { return index == maxSharedTrackToVertices->first; } );
837 if(
index == trackIndices.end() ) {
838 ATH_MSG_WARNING(
" >> " << __FUNCTION__ <<
": index not found (algorithm inconsistent)" );
842 auto&
chi2 = wrkvrt.Chi2PerTrk.at(
index - trackIndices.begin() );
844 vrtChi2Map.emplace( std::pair<long int, double>(iv,
chi2) );
847 auto worstVrtChi2Pair = std::max_element( vrtChi2Map.begin(), vrtChi2Map.end(), [](
auto& p1,
auto& p2 ) { return p1.second < p2.second; } );
849 if( worstVrtChi2Pair == vrtChi2Map.end() ) {
850 ATH_MSG_WARNING(
" >> " << __FUNCTION__ <<
": max_element of vrtChi2Map not found" );
854 maxSharedTrack = maxSharedTrackToVertices->first;
855 worstMatchingVertex = worstVrtChi2Pair->first;
856 worstChi2 = worstVrtChi2Pair->second;
865 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": ===============================================================" );
866 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": " << name <<
": #vertices = " << workVerticesContainer->size() );
868 std::set<const xAOD::TrackParticle*> usedTracks;
870 auto concatenateIndicesToString = [](
auto indices,
auto& collection ) -> std::string {
871 if( 0 == indices.size() )
return "";
872 return std::accumulate( std::next(indices.begin()), indices.end(), std::to_string( indices.at(0) ),
873 [&collection](
const std::string&
str,
auto&
index ) { return str +
", " + std::to_string( collection.at(index)->index() ); } );
876 std::map<const xAOD::TruthVertex*, bool> previous;
878 for(
auto& pair :
m_matchMap ) { previous.emplace( pair.first, pair.second ); }
883 for(
size_t iv=0; iv<workVerticesContainer->size(); iv++) {
884 const auto& wrkvrt = workVerticesContainer->at(iv);
886 if( wrkvrt.nTracksTotal() < 2 )
continue;
888 std::string sels = concatenateIndicesToString( wrkvrt.selectedTrackIndices,
m_selectedTracks );
889 std::string assocs = concatenateIndicesToString( wrkvrt.associatedTrackIndices,
m_associatedTracks );
894 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": " << name <<
" vertex [" << iv <<
"]: " << &wrkvrt
895 <<
", isGood = " << (wrkvrt.isGood?
"true" :
"false")
896 <<
", #ntrks(tot, sel, assoc) = (" << wrkvrt.nTracksTotal() <<
", " << wrkvrt.selectedTrackIndices.size() <<
", " << wrkvrt.associatedTrackIndices.size() <<
"), "
897 <<
", chi2/ndof = " << wrkvrt.fitQuality()
898 <<
", (r, z) = (" << wrkvrt.vertex.perp()
899 <<
", " << wrkvrt.vertex.z() <<
")"
900 <<
", sels = { " << sels <<
" }"
901 <<
", assocs = { " << assocs <<
" }" );
907 Amg::Vector3D vTruth( truthVertex->x(), truthVertex->y(), truthVertex->z() );
908 Amg::Vector3D vReco ( wrkvrt.vertex.x(), wrkvrt.vertex.y(), wrkvrt.vertex.z() );
910 const auto distance = vReco - vTruth;
913 cov.fillSymmetric( 0, 0, wrkvrt.vertexCov.at(0) );
914 cov.fillSymmetric( 1, 0, wrkvrt.vertexCov.at(1) );
915 cov.fillSymmetric( 1, 1, wrkvrt.vertexCov.at(2) );
916 cov.fillSymmetric( 2, 0, wrkvrt.vertexCov.at(3) );
917 cov.fillSymmetric( 2, 1, wrkvrt.vertexCov.at(4) );
918 cov.fillSymmetric( 2, 2, wrkvrt.vertexCov.at(5) );
920 const double s2 = distance.transpose() * cov.inverse() * distance;
922 if( distance.norm() < 2.0 || s2 < 100. )
m_matchMap.at( truthVertex ) =
true;
928 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": number of used tracks = " << usedTracks.size() );
930 if( !previous.empty() && previous.size() ==
m_matchMap.size() ) {
932 if( previous.find( pair.first ) == previous.end() )
continue;
933 if( pair.second != previous.at( pair.first ) ) {
934 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": Match flag has changed: (r, z) = (" << pair.first->perp() <<
", " << pair.first->z() <<
")" );
946 for(
const auto* trk : usedTracks ) {
msg += Form(
"%ld, ", trk->index() ); }
949 ATH_MSG_DEBUG(
" >> " << __FUNCTION__ <<
": ===============================================================" );
956 summary.numIBLHits = 0;
957 summary.numBLayerHits = 0;
958 summary.numPixelHits = 0;
959 summary.numSctHits = 0;
960 summary.numTrtHits = 0;
975 const EventContext& ctx = Gaudi::Hive::currentContext();
976 std::vector<std::unique_ptr<Trk::TrackParameters>> paramsVector =
983 for(
auto& params : paramsVector ) {
985 const TVector3 position( params->position().x(), params->position().y(), params->position().z() );
987 if( prevPos == position ) {
993 const auto* detElement = params->associatedSurface().associatedDetectorElement();
999 const auto&
id = detElement->identify();
1004 auto idHash =
m_pixelId->wafer_hash(
id );
1007 pattern->emplace_back( std::make_tuple( position,
Pixel,
m_pixelId->barrel_ec(
id),
m_pixelId->layer_disk(
id), good ) );
1011 auto idHash =
m_sctId->wafer_hash(
id );
1014 pattern->emplace_back( std::make_tuple( position,
SCT,
m_sctId->barrel_ec(
id),
m_sctId->layer_disk(
id), good ) );
1018 if( !pattern->empty() ) {
1020 ATH_MSG_VERBOSE(
" >> " << __FUNCTION__ <<
", track " << trk <<
": position = (" << position.Perp() <<
", " << position.z() <<
", " << position.Phi() <<
"), detElement ID = " <<
id <<
", good = " << good
1021 <<
": (det, bec, layer) = (" << std::get<1>( pattern->back() ) <<
", " << std::get<2>( pattern->back() ) <<
", " << std::get<3>( pattern->back() ) <<
")" );
1023 if( !good ) nDisabled++;
1031 m_hists[
"disabledCount"]->Fill( nDisabled );
1054 using LayerCombination = std::vector<int>;
1056 std::map<LayerCombination, unsigned> layerMap;
1057 if( layerMap.empty() ) {
1095 enum { position=0, detector=1, bec=2, layer=3, isGood=4 };
1100 const LayerCombination comb { std::get<detector>( point ), std::get<bec>( point ), std::get<layer>( point ) };
1102 for(
auto& pair : layerMap ) {
1103 if( pair.first == comb ) {
1111 enum { kShouldNotHaveHit, kShouldHaveHit, kMayHaveHit };
1117 auto& exPattern_along = *( exPattern.first );
1119 for(
auto itr = exPattern_along.begin(); itr != exPattern_along.end(); ++itr ) {
1120 if( std::next( itr ) == exPattern_along.end() )
continue;
1122 const auto& point = *itr;
1123 const auto& nextPoint = *( std::next( itr ) );
1125 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": isGood = " << std::get<isGood>( point ) );
1127 const auto& thisPos = std::get<position>( point );
1128 const auto& nextPos = std::get<position>( nextPoint );
1130 auto sectionVector = nextPos - thisPos;
1131 auto vertexVector = TVector3( vertex.x(), vertex.y(), vertex.z() ) - thisPos;
1134 const auto& detectorType = getDetectorType( point );
1136 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": detType = " << detectorType );
1142 if( vertexVector.Mag() < 10. ) {
1143 expectedHitPattern.at( detectorType ) = kMayHaveHit;
1149 if( !
static_cast<bool>(std::get<isGood>( point )) ) {
1150 expectedHitPattern.at( detectorType ) = kMayHaveHit;
1159 if( sectionVector.Mag() == 0. )
continue;
1162 <<
": hitPos = (" << thisPos.Perp() <<
", " << thisPos.z() <<
", " << thisPos.Phi() <<
")"
1163 <<
", sectionVec = (" << sectionVector.Perp() <<
", " << sectionVector.z() <<
", " << sectionVector.Phi() <<
")"
1164 <<
", vertexVec = (" << vertexVector.Perp() <<
", " << vertexVector.z() <<
", " << vertexVector.Phi() <<
")"
1165 <<
", cos(s,v) = " << sectionVector * vertexVector / ( sectionVector.Mag() * vertexVector.Mag() +
AlgConsts::infinitesimal ) );
1167 if( sectionVector * vertexVector > 0. )
continue;
1169 if( minExpectedRadius > thisPos.Perp() ) minExpectedRadius = thisPos.Perp();
1173 expectedHitPattern.at( detectorType ) = kShouldHaveHit;
1177 auto& exPattern_oppos = *( exPattern.second );
1178 bool oppositeFlag =
false;
1180 for(
auto itr = exPattern_oppos.begin(); itr != exPattern_oppos.end(); ++itr ) {
1181 if( std::next( itr ) == exPattern_oppos.end() )
continue;
1183 const auto& point = *itr;
1184 const auto& nextPoint = *( std::next( itr ) );
1186 const auto& thisPos = std::get<position>( point );
1187 const auto& nextPos = std::get<position>( nextPoint );
1189 auto sectionVector = nextPos - thisPos;
1190 auto vertexVector = TVector3( vertex.x(), vertex.y(), vertex.z() ) - thisPos;
1192 const auto& detectorType = getDetectorType( point );
1194 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": detType = " << detectorType );
1197 <<
": hitPos = (" << thisPos.Perp() <<
", " << thisPos.z() <<
", " << thisPos.Phi() <<
")"
1198 <<
", vertex = (" << vertex.perp() <<
", " << vertex.z() <<
", " << vertex.phi() <<
")"
1199 <<
", cos(s,v) = " << sectionVector * vertexVector / ( sectionVector.Mag() * vertexVector.Mag() +
AlgConsts::infinitesimal ) );
1204 if( sectionVector * vertexVector < 0. ) {
1205 oppositeFlag =
true;
1214 std::string
msg =
"Expected hit pattern: ";
1216 msg += Form(
"%s", expectedHitPattern.at(i) < kMayHaveHit? Form(
"%u", expectedHitPattern.at(i)) :
"X" );
1220 msg =
"Recorded hit pattern: ";
1226 std::vector<unsigned> matchedLayers;
1229 const unsigned recordedPattern = ( (trk->
hitPattern()>>i) & 1 );
1231 if( expectedHitPattern.at(i) == kMayHaveHit ) {
1232 matchedLayers.emplace_back( i );
1233 }
else if( expectedHitPattern.at(i) == kShouldHaveHit ) {
1234 if( expectedHitPattern.at(i) != recordedPattern ) {
1237 matchedLayers.emplace_back( i );
1240 if( expectedHitPattern.at(i) != recordedPattern ) {
1247 uint8_t PixelHits = 0;
1248 uint8_t SctHits = 0;
1249 uint8_t TRTHits = 0;
1254 auto dphi = trk->
phi() - vertex.phi();
1255 while( dphi > TMath::Pi() ) dphi -= TMath::TwoPi();
1256 while( dphi < -TMath::Pi() ) dphi += TMath::TwoPi();
1258 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vtx phi = " << vertex.phi() <<
", track phi = " << trk->
phi() <<
", dphi = " << dphi
1259 <<
", oppositeFlag = " << oppositeFlag
1260 <<
", nPixelHits = " <<
static_cast<int>(PixelHits)
1261 <<
", nSCTHits = " <<
static_cast<int>(SctHits)
1262 <<
", nTRTHits = " <<
static_cast<int>(TRTHits)
1263 <<
", nMatchedLayers = " << matchedLayers.size() );
1265 if( PixelHits == 0 && vertex.perp() > 300. ) {
1266 ATH_MSG_DEBUG(
" > " << __FUNCTION__ <<
": vertex r > 300 mm, w/o no pixel hits" );
1271 if( matchedLayers.size() < 2 )
return false;
1275 if( matchedLayers.size() < 4 )
return false;
1281 if( oppositeFlag )
return false;
1287 if( fabs( dphi ) > TMath::Pi()/2.0 )
return false;
1290 TVector3 trkP; trkP.SetPtEtaPhi( trk->
pt(), trk->
eta(), trk->
phi() );
1291 TVector3 vtx; vtx.SetXYZ( vertex.x(), vertex.y(), vertex.z() );
1292 if( trkP.Dot( vtx ) < 0. )
return false;
1311 const double rad = vertex.perp();
1312 const double absz = fabs( vertex.z() );
1321 outsidePixelBarrel0_and_insidePixelBarrel1,
1324 outsidePixelBarrel1_and_insidePixelBarrel2,
1327 outsidePixelBarrel2_and_insidePixelBarrel3,
1330 outsidePixelBarrel3_and_insideSctBarrel0,
1333 outsideSctBarrel0_and_insideSctBarrel1,
1338 int vertex_pattern = 0;
1340 vertex_pattern = insideBeamPipe;
1342 }
else if( rad < 31.0 && absz < 331.5 ) {
1343 vertex_pattern = insidePixelBarrel0;
1345 }
else if( rad < 38.4 && absz < 331.5 ) {
1346 vertex_pattern = aroundPixelBarrel0;
1348 }
else if( rad < 47.7 && absz < 400.5 ) {
1349 vertex_pattern = outsidePixelBarrel0_and_insidePixelBarrel1;
1351 }
else if( rad < 54.4 && absz < 400.5 ) {
1352 vertex_pattern = aroundPixelBarrel1;
1354 }
else if( rad < 85.5 && absz < 400.5 ) {
1355 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1357 }
else if( rad < 92.2 && absz < 400.5 ) {
1358 vertex_pattern = aroundPixelBarrel2;
1360 }
else if( rad < 119.3 && absz < 400.5 ) {
1361 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1363 }
else if( rad < 126.1 && absz < 400.5 ) {
1364 vertex_pattern = aroundPixelBarrel3;
1366 }
else if( rad < 290 && absz < 749.0 ) {
1367 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1369 }
else if( rad < 315 && absz < 749.0 ) {
1370 vertex_pattern = aroundSctBarrel0;
1372 }
else if( rad < 360 && absz < 749.0 ) {
1373 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1375 }
else if( rad < 390 && absz < 749.0 ) {
1376 vertex_pattern = aroundSctBarrel1;
1381 unsigned nPixelLayers { 0 };
1393 if( vertex_pattern == insideBeamPipe ) {
1396 if( nPixelLayers < 3 )
return false;
1399 }
else if( vertex_pattern == insidePixelBarrel0 ) {
1402 if( nPixelLayers < 3 )
return false;
1406 else if( vertex_pattern == aroundPixelBarrel0 ) {
1410 if( nPixelLayers < 2 )
return false;
1414 else if( vertex_pattern == outsidePixelBarrel0_and_insidePixelBarrel1 ) {
1418 if( nPixelLayers < 2 )
return false;
1422 else if( vertex_pattern == aroundPixelBarrel1 ) {
1427 if( nPixelLayers < 2 )
return false;
1431 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1436 if( nPixelLayers < 2 )
return false;
1440 else if( vertex_pattern == aroundPixelBarrel2 ) {
1449 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1457 else if( vertex_pattern == aroundPixelBarrel3 ) {
1467 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1477 else if( vertex_pattern == aroundSctBarrel0 ) {
1488 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
1499 else if( vertex_pattern == aroundSctBarrel1 ) {
1525 const double rad = vertex.perp();
1526 const double absz = fabs( vertex.z() );
1535 outsidePixelBarrel0_and_insidePixelBarrel1,
1538 outsidePixelBarrel1_and_insidePixelBarrel2,
1541 outsidePixelBarrel2_and_insidePixelBarrel3,
1544 outsidePixelBarrel3_and_insideSctBarrel0,
1547 outsideSctBarrel0_and_insideSctBarrel1,
1552 int vertex_pattern = 0;
1554 vertex_pattern = insideBeamPipe;
1556 }
else if( rad < 31.0 && absz < 331.5 ) {
1557 vertex_pattern = insidePixelBarrel0;
1559 }
else if( rad < 38.4 && absz < 331.5 ) {
1560 vertex_pattern = aroundPixelBarrel0;
1562 }
else if( rad < 47.7 && absz < 400.5 ) {
1563 vertex_pattern = outsidePixelBarrel0_and_insidePixelBarrel1;
1565 }
else if( rad < 54.4 && absz < 400.5 ) {
1566 vertex_pattern = aroundPixelBarrel1;
1568 }
else if( rad < 85.5 && absz < 400.5 ) {
1569 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1571 }
else if( rad < 92.2 && absz < 400.5 ) {
1572 vertex_pattern = aroundPixelBarrel2;
1574 }
else if( rad < 119.3 && absz < 400.5 ) {
1575 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1577 }
else if( rad < 126.1 && absz < 400.5 ) {
1578 vertex_pattern = aroundPixelBarrel3;
1580 }
else if( rad < 290 && absz < 749.0 ) {
1581 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1583 }
else if( rad < 315 && absz < 749.0 ) {
1584 vertex_pattern = aroundSctBarrel0;
1586 }
else if( rad < 360 && absz < 749.0 ) {
1587 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1589 }
else if( rad < 390 && absz < 749.0 ) {
1590 vertex_pattern = aroundSctBarrel1;
1596 unsigned nPixelLayers { 0 };
1608 if( vertex_pattern == insideBeamPipe ) {
1612 if( nPixelLayers < 3 )
return false;
1614 }
else if( vertex_pattern == insidePixelBarrel0 ) {
1618 if( nPixelLayers < 3 )
return false;
1623 else if( vertex_pattern == aroundPixelBarrel0 ) {
1628 if( nPixelLayers < 3 )
return false;
1632 else if( vertex_pattern == outsidePixelBarrel0_and_insidePixelBarrel1 ) {
1636 if( nPixelLayers < 3 )
return false;
1640 else if( vertex_pattern == aroundPixelBarrel1 ) {
1645 if( nPixelLayers < 2 )
return false;
1649 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1653 if( nPixelLayers < 2 )
return false;
1657 else if( vertex_pattern == aroundPixelBarrel2 ) {
1664 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1669 else if( vertex_pattern == aroundPixelBarrel3 ) {
1677 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1684 else if( vertex_pattern == aroundSctBarrel0 ) {
1692 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
1699 else if( vertex_pattern == aroundSctBarrel1 ) {
1719 const double rad = vertex.perp();
1720 const double absz = fabs( vertex.z() );
1729 outsidePixelBarrel1_and_insidePixelBarrel2,
1732 outsidePixelBarrel2_and_insidePixelBarrel3,
1735 outsidePixelBarrel3_and_insideSctBarrel0,
1738 outsideSctBarrel0_and_insideSctBarrel1,
1743 Int_t vertex_pattern = 0;
1745 vertex_pattern = insideBeamPipe;
1747 }
else if( rad < 47.7 && absz < 400.5 ) {
1748 vertex_pattern = insidePixelBarrel1;
1750 }
else if( rad < 54.4 && absz < 400.5 ) {
1751 vertex_pattern = aroundPixelBarrel1;
1753 }
else if( rad < 85.5 && absz < 400.5 ) {
1754 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1756 }
else if( rad < 92.2 && absz < 400.5 ) {
1757 vertex_pattern = aroundPixelBarrel2;
1759 }
else if( rad < 119.3 && absz < 400.5 ) {
1760 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1762 }
else if( rad < 126.1 && absz < 400.5 ) {
1763 vertex_pattern = aroundPixelBarrel3;
1765 }
else if( rad < 290 && absz < 749.0 ) {
1766 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1768 }
else if( rad < 315 && absz < 749.0 ) {
1769 vertex_pattern = aroundSctBarrel0;
1771 }
else if( rad < 360 && absz < 749.0 ) {
1772 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1774 }
else if( rad < 390 && absz < 749.0 ) {
1775 vertex_pattern = aroundSctBarrel1;
1782 if( vertex_pattern == insideBeamPipe ) {
1789 else if( vertex_pattern == insidePixelBarrel1 ) {
1795 else if( vertex_pattern == aroundPixelBarrel1 ) {
1802 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1809 else if( vertex_pattern == aroundPixelBarrel2 ) {
1817 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1824 else if( vertex_pattern == aroundPixelBarrel3 ) {
1833 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1842 else if( vertex_pattern == aroundSctBarrel0 ) {
1852 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
1862 else if( vertex_pattern == aroundSctBarrel1 ) {
1884 const double rad = vertex.perp();
1885 const double absz = fabs( vertex.z() );
1894 outsidePixelBarrel1_and_insidePixelBarrel2,
1897 outsidePixelBarrel2_and_insidePixelBarrel3,
1900 outsidePixelBarrel3_and_insideSctBarrel0,
1903 outsideSctBarrel0_and_insideSctBarrel1,
1908 Int_t vertex_pattern = 0;
1910 vertex_pattern = insideBeamPipe;
1912 }
else if( rad < 47.7 && absz < 400.5 ) {
1913 vertex_pattern = insidePixelBarrel1;
1915 }
else if( rad < 54.4 && absz < 400.5 ) {
1916 vertex_pattern = aroundPixelBarrel1;
1918 }
else if( rad < 85.5 && absz < 400.5 ) {
1919 vertex_pattern = outsidePixelBarrel1_and_insidePixelBarrel2;
1921 }
else if( rad < 92.2 && absz < 400.5 ) {
1922 vertex_pattern = aroundPixelBarrel2;
1924 }
else if( rad < 119.3 && absz < 400.5 ) {
1925 vertex_pattern = outsidePixelBarrel2_and_insidePixelBarrel3;
1927 }
else if( rad < 126.1 && absz < 400.5 ) {
1928 vertex_pattern = aroundPixelBarrel3;
1930 }
else if( rad < 290 && absz < 749.0 ) {
1931 vertex_pattern = outsidePixelBarrel3_and_insideSctBarrel0;
1933 }
else if( rad < 315 && absz < 749.0 ) {
1934 vertex_pattern = aroundSctBarrel0;
1936 }
else if( rad < 360 && absz < 749.0 ) {
1937 vertex_pattern = outsideSctBarrel0_and_insideSctBarrel1;
1939 }
else if( rad < 390 && absz < 749.0 ) {
1940 vertex_pattern = aroundSctBarrel1;
1947 if( vertex_pattern == insideBeamPipe ) {
1954 else if( vertex_pattern == insidePixelBarrel1 ) {
1960 else if( vertex_pattern == aroundPixelBarrel1 ) {
1967 else if( vertex_pattern == outsidePixelBarrel1_and_insidePixelBarrel2 ) {
1973 else if( vertex_pattern == aroundPixelBarrel2 ) {
1980 else if( vertex_pattern == outsidePixelBarrel2_and_insidePixelBarrel3 ) {
1985 else if( vertex_pattern == aroundPixelBarrel3 ) {
1992 else if( vertex_pattern == outsidePixelBarrel3_and_insideSctBarrel0 ) {
1998 else if( vertex_pattern == aroundSctBarrel0 ) {
2005 else if( vertex_pattern == outsideSctBarrel0_and_insideSctBarrel1 ) {
2011 else if( vertex_pattern == aroundSctBarrel1 ) {
2080 if( vertex.perp() < 31.0 ) {
2081 double dphi = trk->
phi() - vertex.phi();
2082 while( dphi > TMath::Pi() ) { dphi -= TMath::TwoPi(); }
2083 while( dphi < -TMath::Pi() ) { dphi += TMath::TwoPi(); }
2084 if( cos(dphi) < -0.8 )
return false;
2089 using LayerCombination = std::vector<int>;
2091 std::map<LayerCombination, unsigned> layerMap;
2092 if( layerMap.empty() ) {
2130 enum { position=0, detector=1, bec=2, layer=3, isGood=4 };
2135 const LayerCombination comb { std::get<detector>( point ), std::get<bec>( point ), std::get<layer>( point ) };
2137 for(
auto& pair : layerMap ) {
2138 if( pair.first == comb ) {
2146 uint32_t disabledPattern { 0 };
2149 auto& exPattern_along = *( exPattern.first );
2151 for(
auto itr = exPattern_along.begin(); itr != exPattern_along.end(); ++itr ) {
2152 if( std::next( itr ) == exPattern_along.end() )
continue;
2154 const auto& point = *itr;
2156 ATH_MSG_VERBOSE(
" > " << __FUNCTION__ <<
": isGood = " << std::get<isGood>( point ) );
2158 if( !std::get<isGood>( point ) ) {
2159 const auto& detectorType = getDetectorType( point );
2160 disabledPattern += (1 << detectorType);
2165 uint32_t modifiedPattern = disabledPattern | hitPattern;
2167 std::string
msg =
"Disabled hit pattern: ";
2169 msg += Form(
"%u", ( disabledPattern >> i ) & 1 );
2173 msg =
"Recorded hit pattern: ";
2175 msg += Form(
"%u", ( hitPattern >> i ) & 1 );
2193 return ( check_itrk && check_jtrk );
2202 const auto& vertex = wrkvrt.
vertex;
2204 std::map< std::deque<long int>*, std::vector<const xAOD::TrackParticle*>& > indexMap
2209 for(
auto& pair : indexMap ) {
2211 auto* indices = pair.first;
2212 auto& tracks = pair.second;
2215 [&](
auto&
index ) {
2216 bool isConsistent = (this->*m_patternStrategyFuncs[m_checkPatternStrategy] )( tracks.at(index), vertex );
2217 return !isConsistent;
2220 indices->erase( newEnd, indices->end() );
2234 auto sc0 =
evtStore()->retrieve( eventInfo,
"EventInfo" );
2235 if( sc0.isFailure() ) {
return; }
2241 auto sc1 =
evtStore()->retrieve( truthParticles,
"TruthParticles" );
2242 if( sc1.isFailure() ) {
return; }
2244 auto sc2 =
evtStore()->retrieve( truthVertices,
"TruthVertices" );
2245 if( sc2.isFailure() ) {
return; }
2247 if( !truthParticles ) {
return; }
2248 if( !truthVertices ) {
return; }
2252 std::vector<const xAOD::TruthParticle*> truthSvTracks;
2259 if( truthVertex->nIncomingParticles() != 1 )
return false;
2260 if( !truthVertex->incomingParticle(0) )
return false;
2261 if( abs(truthVertex->incomingParticle(0)->pdgId()) < 1000000 )
return false;
2262 if( abs(truthVertex->incomingParticle(0)->pdgId()) > 1000000000 )
return false;
2264 bool hasNeutralino =
false;
2265 for(
unsigned ip = 0; ip < truthVertex->nOutgoingParticles(); ip++ ) {
2266 const auto* p = truthVertex->outgoingParticle(ip);
2267 if( abs( p->pdgId() ) == 1000022 ) {
2268 hasNeutralino =
true;
2272 return hasNeutralino;
2276 if( truthVertex->nIncomingParticles() != 1 )
return false;
2277 if( !truthVertex->incomingParticle(0) )
return false;
2278 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 50 )
return false;
2283 if( truthVertex->nIncomingParticles() != 1 )
return false;
2284 if( !truthVertex->incomingParticle(0) )
return false;
2285 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 36 )
return false;
2290 if( truthVertex->nIncomingParticles() != 1 )
return false;
2291 if( !truthVertex->incomingParticle(0) )
return false;
2292 if( abs(truthVertex->incomingParticle(0)->pdgId()) != 310 )
return false;
2297 if( truthVertex->nIncomingParticles() != 1 )
return false;
2298 if( !truthVertex->incomingParticle(0) )
return false;
2299 if( abs(truthVertex->incomingParticle(0)->pdgId()) <= 500 || abs(truthVertex->incomingParticle(0)->pdgId()) >= 600 )
return false;
2304 if( truthVertex->nIncomingParticles() != 1 )
return false;
2305 if( !truthVertex->incomingParticle(0) )
return false;
2307 const auto* parent = truthVertex->incomingParticle(0);
2308 if( parent->isLepton() )
return false;
2310 TLorentzVector p4sum_in;
2311 TLorentzVector p4sum_out;
2312 for(
unsigned ip = 0; ip < truthVertex->nIncomingParticles(); ip++ ) {
2313 const auto* particle = truthVertex->incomingParticle(ip);
2314 TLorentzVector p4; p4.SetPtEtaPhiM( particle->pt(), particle->eta(), particle->phi(), particle->m() );
2317 for(
unsigned ip = 0; ip < truthVertex->nOutgoingParticles(); ip++ ) {
2318 const auto* particle = truthVertex->outgoingParticle(ip);
2319 TLorentzVector p4; p4.SetPtEtaPhiM( particle->pt(), particle->eta(), particle->phi(), particle->m() );
2322 return p4sum_out.E() - p4sum_in.E() >= 100.;
2328 std::map<std::string, ParticleSelectFunc> selectFuncs { {
"", selectNone },
2329 {
"Kshort", selectKshort },
2330 {
"Bhadron", selectBhadron },
2331 {
"Rhadron", selectRhadron },
2332 {
"HNL", selectHNL },
2333 {
"Higgs", selectHiggs },
2334 {
"HadInt", selectHadInt } };
2345 for(
const auto *truthVertex : *truthVertices ) {
2346 if( selectFunc( truthVertex ) ) {
2349 msg += Form(
"pdgId = %d, (r, z) = (%.2f, %.2f), ", truthVertex->incomingParticle(0)->pdgId(), truthVertex->perp(), truthVertex->z());
2350 msg += Form(
"nOutgoing = %lu, ", truthVertex->nOutgoingParticles() );
2351 msg += Form(
"mass = %.3f GeV, pt = %.3f GeV", truthVertex->incomingParticle(0)->m()/1.e3, truthVertex->incomingParticle(0)->pt()/1.e3 );
2358 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()
bool patternCheck(const uint32_t &pattern, const Amg::Vector3D &vertex)
std::map< std::string, PatternStrategyFunc > m_patternStrategyFuncs
const xAOD::Vertex * m_thePV
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
StatusCode refitVertexWithSuggestion(const EventContext &ctx, WrkVrt &, const Amg::Vector3D &)
refit the vertex with suggestion
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 distanceBetweenVertices(const WrkVrt &, const WrkVrt &) const
calculate the physical distance
double improveVertexChi2(const EventContext &, WrkVrt &)
attempt to improve the vertex chi2 by removing the most-outlier track one by one until the vertex chi...
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
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
StatusCode disassembleVertex(const EventContext &ctx, std::vector< WrkVrt > *, const unsigned &vertexIndex)
std::vector< ExtrapolatedPoint > ExtrapolatedPattern
const xAOD::VertexContainer * m_primaryVertices
std::vector< const xAOD::TrackParticle * > m_associatedTracks
ToolHandle< Trk::ITrkVKalVrtFitter > m_fitSvc
StatusCode refitVertex(const EventContext &, WrkVrt &)
refit the vertex.
std::vector< const xAOD::TrackParticle * > m_selectedTracks
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
StatusCode mergeVertices(const EventContext &ctx, WrkVrt &destination, WrkVrt &source)
the 2nd vertex is merged into the 1st vertex.
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