67 const xAOD::TruthVertex* pv,
const std::vector<const xAOD::TruthVertex*>& truth_vertices,
68 float selection_distance = 0.001,
71 std::vector<const xAOD::TruthVertex*> matched_vertices;
73 float closest_distance = 1e9;
75 for(
const auto& vert : truth_vertices ) {
76 if ( !vert )
continue;
78 if(
r < selection_distance){
79 matched_vertices.push_back(vert);
80 if (
r < closest_distance) {
82 closest_vertex = vert;
83 }
else if ((
r == closest_distance) && closest_vertex) {
86 if ( std::abs(acc_uid(*vert)) < std::abs(acc_uid(*closest_vertex)) ) {
87 closest_vertex = vert;
93 if ( !matched_vertices.empty() && closest_vertex ) {
95 matched_vertices.erase(
96 std::remove(matched_vertices.begin(), matched_vertices.end(), closest_vertex),
97 matched_vertices.end()
100 matched_vertices.insert(matched_vertices.begin(), closest_vertex);
103 return matched_vertices;
177 ATH_MSG_DEBUG(
"Retrieved " << truth_particles->size() <<
" truth_particles...");
182 if ( truth_PVs->size() != 1 ) {
184 return StatusCode::FAILURE;
191 std::vector<const xAOD::TruthVertex*> all_truth_vertices;
192 for (
auto vert : *truth_vertices ) { all_truth_vertices.push_back(vert); }
196 return StatusCode::FAILURE;
200 std::vector<const xAOD::TruthParticle*> sorted_truth_particles;
201 for (
const auto tp : *truth_particles ) { sorted_truth_particles.push_back(tp); }
203 sorted_truth_particles.begin(), sorted_truth_particles.end(),
205 return p1->pt() < p2->pt();
222 for(
auto& fat_vertex : fat_vertices){
223 fat_vertex.doParentChildLinks(fat_vertices);
227 std::vector<FatVertex::FatVertex> hpt_fat_vertices;
228 for (
auto& fat_vertex : fat_vertices ) {
229 if ( fat_vertex.getPT() > 0 || fat_vertex.is_pv ) hpt_fat_vertices.push_back(fat_vertex);
249 std::vector<const xAOD::TruthParticle*> stable_neutrals;
250 std::vector<const xAOD::TruthParticle*> stable_charged;
251 std::unordered_map<int, int> barcode_to_other_id;
256 for (
const auto& truth_particle : sorted_truth_particles ) {
257 vertexValid(*truth_particle) = 0;
258 vertexType(*truth_particle) = -1;
259 vertexSimpleType(*truth_particle) = -1;
260 vertexDecayID(*truth_particle) = -1;
261 vertexDecayParentID(*truth_particle) = -1;
262 vertexDecayPVDistance(*truth_particle) = NAN;
263 vertexDecayDistance(*truth_particle) = NAN;
264 vertexDecayNCharged(*truth_particle) = -1;
265 vertexDecayNNeutral(*truth_particle) = -1;
266 vertexDecayAllNCharged(*truth_particle) = -1;
267 vertexDecayAllNNeutral(*truth_particle) = -1;
268 vertexIsVertex(*truth_particle) = 0;
271 std::unordered_map<int, int> barcode_to_vertex_id;
273 for (
auto fat_vertex : hpt_fat_vertices ) {
274 for (
auto part : fat_vertex.internal ) {
275 barcode_to_other_id[
m_acc_uid(*part)] = counter;
276 vertexDecayID(*part) = counter;
278 for (
auto part : fat_vertex.inparts ) {
288 vertexValid(*part) = 1;
289 vertexType(*part) = int(vt.detailedType);
290 vertexSimpleType(*part) = int(vt.getSimpleType());
291 vertexDecayID(*part) = counter;
295 vertexDecayAllNCharged(*part) = fat_vertex.getNumChargedDecays();
296 vertexDecayAllNNeutral(*part) = fat_vertex.getNumNeutralDecays();
298 vertexIsVertex(*part) = 1;
299 barcode_to_other_id[
m_acc_uid(*part)] = counter;
302 for (
auto part : fat_vertex.outparts ) {
304 ATH_MSG_ERROR(
"Found a null particle in the out parts of a fat vertex, skipping it - this should never happen");
308 vertexDecayParentID(*part) = counter;
309 barcode_to_vertex_id[
m_acc_uid(*part)] = counter;
319 vertexDecayPVDistance(*part) = pvDist;
321 if ( part->hasProdVtx() && part->prodVtx() ) {
328 if (part->isCharged()){
329 stable_charged.push_back(part);
331 vertexValid(*part) = 1;
335 stable_neutrals.push_back(part);
337 vertexValid(*part) = 1;
349 std::vector<const xAOD::TrackParticle*> tracks_vector(tracks->begin(), tracks->end());
360 for (
auto track : tracks_vector ) {
363 trackTPDecayVertexID(*track) = -1;
364 trackTPDecayVertexType(*track) = -1;
365 trackTPDecaySimpleVertexType(*track) = -1;
366 trackPDGID(*track) = 0;
367 trackParentPDGID(*track) = 0;
371 trackTPDecayVertexType(*track) = -2;
372 trackTPDecaySimpleVertexType(*track) = -2;
379 trackTPDecayVertexType(*track) = -3;
380 trackTPDecaySimpleVertexType(*track) = -3;
387 stable_charged.erase(
388 std::remove(stable_charged.begin(), stable_charged.end(), truth),
392 trackPDGID(*track) = truth->pdgId();
394 if ( truth->hasProdVtx() && truth->prodVtx() ) {
395 auto parent = truth->prodVtx()->incomingParticle(0);
397 trackParentPDGID(*track) = parent->pdgId();
402 if ( barcode_to_vertex_id.find(
m_acc_uid(*truth)) != barcode_to_vertex_id.end() ) {
403 int vertex_id = barcode_to_vertex_id[
m_acc_uid(*truth)];
404 trackTPDecayVertexID(*track) = vertex_id;
406 trackTPDecayVertexType(*track) = int(vt.detailedType);
407 trackTPDecaySimpleVertexType(*track) = int(vt.getSimpleType());
410 if(barcode_to_other_id.find(
m_acc_uid(*truth)) != barcode_to_other_id.end()){
411 ATH_MSG_DEBUG(
"Found a track which is truth matched to an internal particle, not an out part ");
412 int vertex_id = barcode_to_other_id[
m_acc_uid(*truth)];
413 trackTPDecayVertexID(*track) = vertex_id;
415 trackTPDecayVertexType(*track) = int(vt.detailedType);
416 trackTPDecaySimpleVertexType(*track) = int(vt.getSimpleType());
427 for(
auto stable_charged_tp : stable_charged){
428 vertexValid(*stable_charged_tp) = 1;
435 return StatusCode::SUCCESS;
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
bool hasDecayVtx() const
Check for a decay vertex on this particle.