From aeb4e15866fab450a163c1cf6ec976bcd23529f0 Mon Sep 17 00:00:00 2001 From: Andrii Verbytskyi <averbyts@cern.ch> Date: Thu, 23 Jul 2020 20:25:11 +0200 Subject: [PATCH 1/4] Migrate EvgenProdTools to HepMC3 --- .../EvgenProdTools/EvgenProdTools/TestHepMC.h | 1 + Generators/EvgenProdTools/src/FixHepMC.cxx | 77 ++++++++++++++++--- Generators/EvgenProdTools/src/TestHepMC.cxx | 13 ++-- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/Generators/EvgenProdTools/EvgenProdTools/TestHepMC.h b/Generators/EvgenProdTools/EvgenProdTools/TestHepMC.h index fc661c193f70..ae8306628f92 100644 --- a/Generators/EvgenProdTools/EvgenProdTools/TestHepMC.h +++ b/Generators/EvgenProdTools/EvgenProdTools/TestHepMC.h @@ -13,6 +13,7 @@ #include "TFile.h" #include "TH1.h" #include "AtlasHepMC/GenEvent.h" +#include "AtlasHepMC/Relatives.h" #include<cmath> #include<fstream> diff --git a/Generators/EvgenProdTools/src/FixHepMC.cxx b/Generators/EvgenProdTools/src/FixHepMC.cxx index cee6992cfa65..c16e7ee7a6ac 100644 --- a/Generators/EvgenProdTools/src/FixHepMC.cxx +++ b/Generators/EvgenProdTools/src/FixHepMC.cxx @@ -27,6 +27,68 @@ StatusCode FixHepMC::execute() { for (McEventCollection::const_iterator ievt = events()->begin(); ievt != events()->end(); ++ievt) { // FIXME: const_cast HepMC::GenEvent* evt = const_cast<HepMC::GenEvent*>(*ievt); +#ifdef HEPMC3 + // Add a unit entry to the event weight vector if it's currently empty + if (evt->weights().empty()) { + ATH_MSG_DEBUG("Adding a unit weight to empty event weight vector"); + evt->weights().push_back(1); + } + // Set a (0,0,0) vertex to be the signal vertex if not already set + if (!HepMC::signal_process_vertex(evt)) { + const HepMC::FourVector nullpos; + for (auto iv: evt->vertices()) { + if (iv->position() == nullpos) { + ATH_MSG_DEBUG("Setting representative event position vertex"); + HepMC::set_signal_process_vertex(evt,iv); + break; + } + } + } + // Event particle content cleaning -- remove "bad" structures + std::vector<HepMC::GenParticlePtr> toremove; + long seenThisEvent = 0; + /// @todo Use nicer particles accessor from TruthUtils / HepMC3 when it exists + for (auto ip: evt->particles()) { + // Skip this particle if (somehow) its pointer is null + if (!ip) continue; + m_totalSeen += 1; + seenThisEvent += 1; + // Flag to declare if a particle should be removed + bool bad_particle = false; + // Check for loops + if ( m_killLoops && isLoop(ip) ) { + bad_particle = true; + m_loopKilled += 1; + ATH_MSG_DEBUG( "Found a looper : " ); + if ( msgLvl( MSG::DEBUG ) ) HepMC::Print::line(ip); + } + // Check on PDG ID 0 + if ( m_killPDG0 && isPID0(ip) ) { + bad_particle = true; + m_pdg0Killed += 1; + ATH_MSG_DEBUG( "Found PDG ID 0 : " ); + if ( msgLvl( MSG::DEBUG ) )HepMC::Print::line(ip); + } + // Clean decays + if ( m_cleanDecays && isNonTransportableInDecayChain(ip) ) { + bad_particle = true; + m_decayCleaned += 1; + ATH_MSG_DEBUG( "Found a bad particle in a decay chain : " ); + if ( msgLvl( MSG::DEBUG ) ) HepMC::Print::line(ip); + } + // Only add to the toremove vector once, even if multiple tests match + if (bad_particle) toremove.push_back(ip); + } + // Escape here if there's nothing more to do, otherwise do the cleaning + if (toremove.empty()) continue; + ATH_MSG_DEBUG("Cleaning event record of " << toremove.size() << " bad particles"); + // Properties before cleaning + const int num_particles_orig = evt->particles().size(); + for (auto part: toremove) evt->remove_particle(part); + const int num_particles_filt = evt->particles().size(); + // Write out the change in the number of particles + ATH_MSG_INFO("Particles filtered: " << num_particles_orig << " -> " << num_particles_filt); + #else // Add a unit entry to the event weight vector if it's currently empty if (evt->weights().empty()) { @@ -120,6 +182,7 @@ StatusCode FixHepMC::execute() { if (num_nochild_vtxs_filt != num_nochild_vtxs_orig) ATH_MSG_WARNING("Change in no-parent vertices: " << num_nochild_vtxs_orig << " -> " << num_nochild_vtxs_filt); +#endif } return StatusCode::SUCCESS; } @@ -143,7 +206,7 @@ bool FixHepMC::isPID0(const HepMC::GenParticlePtr p) { // Identify non-transportable stuff _after_ hadronisation bool FixHepMC::isNonTransportableInDecayChain(const HepMC::GenParticlePtr p) { - return !MC::isTransportable(p) && MC::fromDecay(p); + return !MC::isTransportable(p->pdg_id()) && MC::fromDecay(p); } // Identify internal "loop" particles @@ -151,22 +214,12 @@ bool FixHepMC::isLoop(const HepMC::GenParticlePtr p) { if (p->production_vertex() == p->end_vertex() && p->end_vertex() != NULL) return true; if (m_loopByBC && p->production_vertex()) { /// @todo Use new particle MC::parents(...) tool -#ifdef HEPMC3 - for (auto itrParent: p->production_vertex()->particles_out()) { + for (auto itrParent: *(p->production_vertex())) { if ( HepMC::barcode(itrParent) > HepMC::barcode(p) ) { ATH_MSG_VERBOSE("Found a loop (a la Sherpa sample) via barcode."); return true; // Cannot vectorize, but this is a pretty short loop } // Check on barcodes } // Loop over parent particles -#else - for (HepMC::GenVertex::particle_iterator itrParent = p->production_vertex()->particles_begin(HepMC::parents); - itrParent != p->production_vertex()->particles_end(HepMC::parents); ++itrParent) { - if ( (*itrParent)->barcode() > p->barcode() ) { - ATH_MSG_VERBOSE("Found a loop (a la Sherpa sample) via barcode."); - return true; // Cannot vectorize, but this is a pretty short loop - } // Check on barcodes - } // Loop over parent particles -#endif } // Has a production vertex return false; } diff --git a/Generators/EvgenProdTools/src/TestHepMC.cxx b/Generators/EvgenProdTools/src/TestHepMC.cxx index c8dd06ff725e..f1ca2e1b0e09 100644 --- a/Generators/EvgenProdTools/src/TestHepMC.cxx +++ b/Generators/EvgenProdTools/src/TestHepMC.cxx @@ -541,8 +541,12 @@ StatusCode TestHepMC::execute() { auto vtx = pitr->end_vertex(); if (vtx) { double p_energy = 0; +#ifdef HEPMC3 + for (auto desc: HepMC::descendant_particles(vtx)) { +#else for (auto desc_it = vtx->particles_begin(HepMC::descendants); desc_it != vtx->particles_end(HepMC::descendants); ++desc_it) { auto desc=(*desc_it); +#endif if (std::abs(desc->pdg_id()) == m_pdg) tau_child = 1; if (desc->status() == 1) p_energy += desc->momentum().e(); } @@ -572,14 +576,7 @@ StatusCode TestHepMC::execute() { const HepMC::FourVector decaypos = decayvtx->position(); const double displacement = decaypos.x()*decaypos.x() + decaypos.y()*decaypos.y() + decaypos.z()*decaypos.z(); if (displacement > 1e-6) { -#ifdef HEPMC3 - for (auto ip:decayvtx->particles_out()) { -#else - HepMC::GenVertex::particle_iterator ipbegin = decayvtx->particles_begin(HepMC::children); - HepMC::GenVertex::particle_iterator ipend = decayvtx->particles_end(HepMC::children); - for (HepMC::GenVertex::particle_iterator ip_it = ipbegin; ip_it != ipend; ++ip_it) { - auto ip=(*ip_it); -#endif + for (auto ip: *decayvtx const HepMC::FourVector pos2 = ip->production_vertex()->position(); const double displacement2 = pos2.x()*pos2.x() + pos2.y()*pos2.y() + pos2.z()*pos2.z(); if (displacement2 < 1e-6) { -- GitLab From 9d7dd8e47ce2f3af04add65ff4988329cf933996 Mon Sep 17 00:00:00 2001 From: Andrii Verbytskyi <averbyts@cern.ch> Date: Thu, 23 Jul 2020 20:27:05 +0200 Subject: [PATCH 2/4] Migrate EvgenProdTools to HepMC3 --- Generators/AtlasHepMC/AtlasHepMC/Relatives.h | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Generators/AtlasHepMC/AtlasHepMC/Relatives.h diff --git a/Generators/AtlasHepMC/AtlasHepMC/Relatives.h b/Generators/AtlasHepMC/AtlasHepMC/Relatives.h new file mode 100644 index 000000000000..261c4f48690a --- /dev/null +++ b/Generators/AtlasHepMC/AtlasHepMC/Relatives.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + Author: Andrii Verbytskyi andrii.verbytskyi@mpp.mpg.de +*/ +#ifndef ATLASHEPMC_RELATIVES_H +#define ATLASHEPMC_RELATIVES_H +#ifdef HEPMC3 +#include "HepMC3/Relatives.h" +namespace HepMC { +typedef HepMC3::Relatives Relatives; +using HepMC3::children_particles; +using HepMC3::children_vertices; +using HepMC3::grandchildren_particles; +using HepMC3::grandchildren_vertices; +using HepMC3::parent_particles; +using HepMC3::parent_vertices; +using HepMC3::grandparent_particles; +using HepMC3::grandparent_vertices; +using HepMC3::descendant_particles; +using HepMC3::descendant_vertices; +using HepMC3::ancestor_particles; +using HepMC3::ancestor_vertices; +} +#endif +#endif \ No newline at end of file -- GitLab From e5d82b9588adee66fbfd8fa9e07154578304d54e Mon Sep 17 00:00:00 2001 From: Andrii Verbytskyi <averbyts@cern.ch> Date: Fri, 24 Jul 2020 01:09:13 +0200 Subject: [PATCH 3/4] Fix --- Generators/EvgenProdTools/src/TestHepMC.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Generators/EvgenProdTools/src/TestHepMC.cxx b/Generators/EvgenProdTools/src/TestHepMC.cxx index f1ca2e1b0e09..1aa5f8906c44 100644 --- a/Generators/EvgenProdTools/src/TestHepMC.cxx +++ b/Generators/EvgenProdTools/src/TestHepMC.cxx @@ -576,7 +576,7 @@ StatusCode TestHepMC::execute() { const HepMC::FourVector decaypos = decayvtx->position(); const double displacement = decaypos.x()*decaypos.x() + decaypos.y()*decaypos.y() + decaypos.z()*decaypos.z(); if (displacement > 1e-6) { - for (auto ip: *decayvtx + for (auto ip: *decayvtx) { const HepMC::FourVector pos2 = ip->production_vertex()->position(); const double displacement2 = pos2.x()*pos2.x() + pos2.y()*pos2.y() + pos2.z()*pos2.z(); if (displacement2 < 1e-6) { -- GitLab From 6a6fc95a36381f5be010557b19dc7030f9a75494 Mon Sep 17 00:00:00 2001 From: Andrii Verbytskyi <averbyts@cern.ch> Date: Fri, 24 Jul 2020 01:11:01 +0200 Subject: [PATCH 4/4] Fix --- Generators/EvgenProdTools/src/FixHepMC.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Generators/EvgenProdTools/src/FixHepMC.cxx b/Generators/EvgenProdTools/src/FixHepMC.cxx index c16e7ee7a6ac..a6e4c42216c0 100644 --- a/Generators/EvgenProdTools/src/FixHepMC.cxx +++ b/Generators/EvgenProdTools/src/FixHepMC.cxx @@ -206,7 +206,7 @@ bool FixHepMC::isPID0(const HepMC::GenParticlePtr p) { // Identify non-transportable stuff _after_ hadronisation bool FixHepMC::isNonTransportableInDecayChain(const HepMC::GenParticlePtr p) { - return !MC::isTransportable(p->pdg_id()) && MC::fromDecay(p); + return !MC::PID::isTransportable(p->pdg_id()) && MC::fromDecay(p); } // Identify internal "loop" particles -- GitLab