18 return StatusCode::SUCCESS;
26 for (
size_t i = 0;
i < matches.size(); ++
i ) {
27 if ( link.
key() == std::get<0>(matches[
i]).key() && link.
index() == std::get<0>(matches[
i]).index() )
31 matches.emplace_back( link, 0., 0. );
32 return matches.size() - 1;
38 std::vector<const xAOD::TruthVertex*> truthVerticesToMatch,
68 std::vector<VertexTruthMatchInfo> matchinfo;
71 size_t ntracks = trkParts.size();
72 const std::vector<float> & trkWeights = weightAcc( *vtx );
76 ATH_MSG_WARNING(
"trackParticles or trackWeights not available, vertex is missing info");
79 if ( trkWeights.size() != ntracks ) {
80 ATH_MSG_WARNING(
"Vertex without same number of tracks and trackWeights, vertex is missing info");
84 ATH_MSG_DEBUG(
"Matching new vertex at (" << vtx->x() <<
", " << vtx->y() <<
", " << vtx->z() <<
")" <<
" with " << ntracks <<
" tracks, at index: " << vtx->index());
86 float totalWeight = 0.;
92 for (
size_t t = 0;
t < ntracks; ++
t ) {
103 totalWeight += trkWeights[
t];
108 ATH_MSG_DEBUG(
"The truth particle link decoration isn't available.");
112 float prob = trk_truthProbAcc( trk );
119 const int ancestorVertexUniqueID =
checkProduction(truthPart, truthVerticesToMatch);
125 auto it = std::find_if(truthVerticesToMatch.begin(), truthVerticesToMatch.end(),
126 [&](
const auto& ele){ return HepMC::uniqueID(ele) == ancestorVertexUniqueID;} );
128 if(
it == truthVerticesToMatch.end()) {
129 ATH_MSG_WARNING(
"Truth vertex with unique ID " << ancestorVertexUniqueID <<
" not found!");
135 size_t matchIdx = indexOfMatchInfo( matchinfo, elLink );
137 std::get<1>(matchinfo[matchIdx]) += trkWeights[
t];
138 std::get<2>(matchinfo[matchIdx]) += trk.
pt();
155 std::get<1>(link) /= totalWeight;
156 std::get<2>(link) /= totalPt;
159 float fakeScore = fakePt/totalPt;
160 float otherScore = otherPt/totalPt;
162 matchInfoDecor ( *vtx ) = matchinfo;
163 fakeScoreDecor ( *vtx ) = fakeScore;
164 otherScoreDecor( *vtx ) = otherScore;
171 std::vector<bool> assignedType( recoVerticesToMatch.size(),
false );
175 for (
size_t i = 0;
i < recoVerticesToMatch.size(); ++
i ) {
177 int recoVertexMatchType = 0;
179 if ( assignedType[
i] ) {
184 std::vector<VertexTruthMatchInfo> &
info = matchInfoDecor( *recoVerticesToMatch[
i] );
185 float fakeScore = fakeScoreDecor( *recoVerticesToMatch[
i] );
190 }
else if (
info.size() == 1) {
192 ATH_MSG_DEBUG(
"One true decay vertices matched with sufficient weight. Vertex is matched.");
197 ATH_MSG_DEBUG(
"One true decay vertices matched with insufficient weight. Vertex is other.");
200 }
else if (
info.size() >= 2 ) {
201 ATH_MSG_DEBUG(
"Multiple true decay vertices matched. Vertex is merged.");
205 isMatched(**std::get<0>(link)) = true;
208 ATH_MSG_DEBUG(
"Vertex is neither fake nor LLP. Marking as OTHER.");
212 recoMatchTypeDecor(*recoVerticesToMatch[
i]) = recoVertexMatchType;
217 std::vector<size_t> foundSplits;
218 for (
size_t j =
i + 1; j < recoVerticesToMatch.size(); ++j ) {
219 std::vector<VertexTruthMatchInfo> & info2 = matchInfoDecor( *recoVerticesToMatch[j] );
224 if (!info2.empty() && std::get<0>(info2[0]).isValid() && std::get<0>(
info[0]).key() == std::get<0>(info2[0]).key() && std::get<0>(
info[0]).index() == std::get<0>(info2[0]).index() ) {
227 splitLink_ij.
setElement( recoVerticesToMatch[j] );
229 splitPartnerDecor( *recoVerticesToMatch[
i] ).emplace_back(splitLink_ij);
234 splitPartnerDecor( *recoVerticesToMatch[j] ).emplace_back(splitLink_ji);
237 for (
auto k : foundSplits ) {
239 splitLink_kj.
setElement( recoVerticesToMatch[j] );
241 splitPartnerDecor( *recoVerticesToMatch[
k] ).emplace_back(splitLink_kj);
246 splitPartnerDecor( *recoVerticesToMatch[j] ).emplace_back(splitLink_jk);
249 foundSplits.push_back(j);
253 assignedType[j] =
true;
268 std::vector<const xAOD::TruthParticle*> reconstructibleParticles;
273 std::vector<int> particleInfo = {0,0,0};
274 std::vector<int> vertexInfo = {0,0,0};
276 for(
size_t n = 0;
n < reconstructibleParticles.size();
n++){
283 for(
size_t h = 0;
h < particleInfo.size();
h++){
284 vertexInfo.at(
h) += particleInfo.at(
h);
289 int truthMatchType = 0;
290 if( vertexInfo.at(0) > 1 && truthVtx->perp() < 320 && abs(truthVtx->z()) < 1500){
291 ATH_MSG_DEBUG(
"Vertex is reconstructable and in Inner Det region");
299 ATH_MSG_DEBUG(
"Vertex is has at least two tracks passing track selection: " << vertexInfo.at(2));
303 ATH_MSG_DEBUG(
"Vertex is matched to a reconstructed secVtx");
310 truthMatchTypeDecor(*truthVtx) = truthMatchType;
314 return StatusCode::SUCCESS;
325 ATH_MSG_DEBUG(
"Insufficient pt to reconstruct the particle");
332 float matchProb = trk_truthProbAcc( *trkPart );
338 if(trackPass( *trkPart )) {
339 ATH_MSG_DEBUG(
"Particle has a track that passes track selection.");
342 ATH_MSG_DEBUG(
"Particle has a track, but did not pass track selection.");
346 ATH_MSG_DEBUG(
"Track selection decoration not available, calling the track selected");
375 if(
std::find(truthVerticesToMatch.begin(), truthVerticesToMatch.end(), parentVertex) != truthVerticesToMatch.end()) {
386 std::vector<const xAOD::TruthParticle*>&
set,
int counter)
const {
399 auto isInside = []( TVector3&
v ) {
return (
v.Perp() < 300. && std::abs(
v.z() ) < 1500. ); };
400 auto isOutside = []( TVector3&
v ) {
return (
v.Perp() > 563. || std::abs(
v.z() ) > 2720. ); };
402 const auto distance = (decayPos - prodPos).Mag();
405 ATH_MSG_WARNING(
"Vetoing particle that may be added recursively infinitely (potential loop in generator record");
412 }
else if( isInside ( prodPos ) && isOutside( decayPos ) &&
particle->isCharged() ) {
418 if( !(
particle->isCharged()) )
continue;