From de6d51d61a15bd1b0f913beb8d82b73489f34c27 Mon Sep 17 00:00:00 2001
From: Andrii Verbytskyi <andrii.verbytskyi@cern.ch>
Date: Thu, 2 Jul 2020 15:13:02 +0000
Subject: [PATCH] Migrate some generator filters to Hepmc3  part3

---
 .../GeneratorFilters/XtoVVDecayFilter.h       |  2 +-
 .../XtoVVDecayFilterExtended.h                |  6 +--
 .../src/DecayLengthFilter.cxx                 | 40 ++++++++++++++--
 .../src/TruthJetWeightFilter.cxx              | 45 +++++++++++------
 .../GeneratorFilters/src/VHtoVVFilter.cxx     | 48 +++++++++++++++++++
 .../src/WMultiLeptonFilter.cxx                | 36 ++++++++++++++
 .../GeneratorFilters/src/XtoVVDecayFilter.cxx |  2 +-
 .../src/XtoVVDecayFilterExtended.cxx          | 12 ++---
 .../GeneratorFilters/src/ZtoLeptonFilter.cxx  | 18 +++++++
 9 files changed, 181 insertions(+), 28 deletions(-)

diff --git a/Generators/GeneratorFilters/GeneratorFilters/XtoVVDecayFilter.h b/Generators/GeneratorFilters/GeneratorFilters/XtoVVDecayFilter.h
index 6a52d6c9ade..168e9e5ab1f 100644
--- a/Generators/GeneratorFilters/GeneratorFilters/XtoVVDecayFilter.h
+++ b/Generators/GeneratorFilters/GeneratorFilters/XtoVVDecayFilter.h
@@ -32,7 +32,7 @@ private:
   int m_nHtoVV;
   int m_nGoodHtoVV;
 
-  void FindAncestor(const HepMC::GenVertexPtr searchvertex,
+  void FindAncestor(HepMC::ConstGenVertexPtr searchvertex,
                     int targetPDGID, bool& okPDGChild1, bool& okPDGChild2);
 
 };
diff --git a/Generators/GeneratorFilters/GeneratorFilters/XtoVVDecayFilterExtended.h b/Generators/GeneratorFilters/GeneratorFilters/XtoVVDecayFilterExtended.h
index a76fe1ad07d..9ab0c0741a3 100644
--- a/Generators/GeneratorFilters/GeneratorFilters/XtoVVDecayFilterExtended.h
+++ b/Generators/GeneratorFilters/GeneratorFilters/XtoVVDecayFilterExtended.h
@@ -35,10 +35,10 @@ private:
   int m_nHtoVV;
   int m_nGoodHtoVV;
 
-  void FindAncestor(const HepMC::GenVertexPtr searchvertex,
+  void FindAncestor(HepMC::ConstGenVertexPtr searchvertex,
                     int targetPDGID, bool& okPDGChild1, bool& okPDGChild2);
-  HepMC::GenParticlePtr CheckGrandparent(HepMC::GenParticlePtr pitr, int &);
-  bool RunHistory(HepMC::GenParticlePtr pitr);
+  HepMC::ConstGenParticlePtr CheckGrandparent(HepMC::ConstGenParticlePtr pitr, int &);
+  bool RunHistory(HepMC::ConstGenParticlePtr pitr);
 };
 
 #endif
diff --git a/Generators/GeneratorFilters/src/DecayLengthFilter.cxx b/Generators/GeneratorFilters/src/DecayLengthFilter.cxx
index 24044ba21a6..292fe5f50a2 100644
--- a/Generators/GeneratorFilters/src/DecayLengthFilter.cxx
+++ b/Generators/GeneratorFilters/src/DecayLengthFilter.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "GeneratorFilters/DecayLengthFilter.h"
@@ -30,6 +30,40 @@ StatusCode DecayLengthFilter::filterEvent() {
   CHECK(evtStore()->retrieve( McEventCollection, m_McEventCollectionName));
 
   const HepMC::GenEvent* theGenEvent = *(McEventCollection->begin()); //supose ther is only one, no pile-up
+#ifdef HEPMC3
+  setFilterPassed(false);
+
+  //First, find special vertices
+  int nFound(0);
+  for(auto  vtx_iter:  theGenEvent->vertices()) {
+
+    // now look for displaced vertices
+    if(vtx_iter->particles_in().size()!=1) continue; // chi decays have only one in particle (the chi)
+    if(vtx_iter->particles_out().size()<2) continue; // we don't want replication entries
+    if(vtx_iter->position().x()==0 && vtx_iter->position().y()==0 && vtx_iter->position().z()==0) continue;
+
+    auto inParticle = vtx_iter->particles_in().front();
+    if(inParticle->pdg_id()!=m_particle_id) continue;
+
+    nFound++;
+
+    if(nFound>2) {
+      ATH_MSG_WARNING("More than 2 displaced vertices found !!!"); //should never happen
+      break;
+    }
+
+    auto decayVertex = vtx_iter;
+    auto creationVertex = inParticle->production_vertex();
+
+    double distR = std::sqrt( std::pow(creationVertex->position().x() - decayVertex->position().x(),2) + std::pow(creationVertex->position().y() - decayVertex->position().y(),2) );
+    double distZ = creationVertex->position().z() - decayVertex->position().z();
+    ATH_MSG_DEBUG("distR " << distR << ", distZ " << distZ);
+
+    //accept all events with at least one of the two decays in the orimeter
+    if( isAccepted( distR, distZ) )
+      setFilterPassed(true);
+  }
+#else
   HepMC::GenEvent::vertex_const_iterator vtx_iter = theGenEvent->vertices_begin();
   HepMC::GenEvent::vertex_const_iterator vtx_end = theGenEvent->vertices_end();
 
@@ -48,7 +82,6 @@ StatusCode DecayLengthFilter::filterEvent() {
     if((*inParticle)->pdg_id()!=m_particle_id) continue;
 
     nFound++;
-    //std::cout << "found the chi " << nFound << std::endl;
 
     if(nFound>2) {
       ATH_MSG_WARNING("More than 2 displaced vertices found !!!"); //should never happen
@@ -58,7 +91,7 @@ StatusCode DecayLengthFilter::filterEvent() {
     HepMC::GenVertexPtr decayVertex = *vtx_iter;
     HepMC::GenVertexPtr creationVertex = (*inParticle)->production_vertex();
 
-    float distR = sqrt( pow(creationVertex->position().x() - decayVertex->position().x(),2) + pow(creationVertex->position().y() - decayVertex->position().y(),2) );
+    float distR = std::sqrt( std::pow(creationVertex->position().x() - decayVertex->position().x(),2) + std::pow(creationVertex->position().y() - decayVertex->position().y(),2) );
     float distZ = creationVertex->position().z() - decayVertex->position().z();
     ATH_MSG_DEBUG("distR " << distR << ", distZ " << distZ);
 
@@ -66,6 +99,7 @@ StatusCode DecayLengthFilter::filterEvent() {
     if( isAccepted( distR, distZ) )
       setFilterPassed(true);
   }
+#endif
 
   return StatusCode::SUCCESS;
 }
diff --git a/Generators/GeneratorFilters/src/TruthJetWeightFilter.cxx b/Generators/GeneratorFilters/src/TruthJetWeightFilter.cxx
index 0e6b7251ab0..c842faf69e0 100644
--- a/Generators/GeneratorFilters/src/TruthJetWeightFilter.cxx
+++ b/Generators/GeneratorFilters/src/TruthJetWeightFilter.cxx
@@ -212,16 +212,16 @@ double TruthJetWeightFilter::getRescaledJetPt(const CLHEP::HepLorentzVector &jet
   McEventCollection::const_iterator itr;
   for (itr = events()->begin(); itr!=events()->end(); ++itr) {
     const HepMC::GenEvent* genEvt = (*itr);
-    for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin(); pitr != genEvt->particles_end(); ++pitr) {
-      if ((*pitr)->status() != 1) continue;
-      HepMC::FourVector tmp = (*pitr)->momentum();
+    for (auto pitr: *genEvt) {
+      if (pitr->status() != 1) continue;
+      HepMC::FourVector tmp = pitr->momentum();
       CLHEP::HepLorentzVector genpart(tmp.x(), tmp.y(), tmp.z(), tmp.t());
       if (jet.deltaR(genpart) > 0.4) continue;
 
       // Separate EM particles (including K0short here!) and hadronic
-      if (abs((*pitr)->pdg_id()) == 11 || abs((*pitr)->pdg_id()) == 22 || abs((*pitr)->pdg_id()) == 310) {
+      if (std::abs(pitr->pdg_id()) == 11 || std::abs(pitr->pdg_id()) == 22 || std::abs(pitr->pdg_id()) == 310) {
         empart += genpart.perp();
-      } else if (abs((*pitr)->pdg_id()) > 100) {
+      } else if (std::abs(pitr->pdg_id()) > 100) {
         hadpart += genpart.perp();
       }
     }
@@ -249,12 +249,12 @@ void TruthJetWeightFilter::getLeadTruthParts(const CLHEP::HepLorentzVector& jet,
   McEventCollection::const_iterator itr;
   for (itr = events()->begin(); itr!=events()->end(); ++itr) {
     const HepMC::GenEvent* genEvt = (*itr);
-    for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin(); pitr != genEvt->particles_end(); ++pitr ) {
-      if ((*pitr)->status() != 1) continue;
-      int pdgid = (*pitr)->pdg_id();
-      if (abs(pdgid) == 12 || abs(pdgid) == 14 || abs(pdgid) == 16) continue;
+    for (auto pitr: *genEvt ) {
+      if (pitr->status() != 1) continue;
+      int pdgid = pitr->pdg_id();
+      if (std::abs(pdgid) == 12 || std::abs(pdgid) == 14 || std::abs(pdgid) == 16) continue;
 
-      HepMC::FourVector tmp = (*pitr)->momentum();
+      HepMC::FourVector tmp = pitr->momentum();
       CLHEP::HepLorentzVector genpart(tmp.x(), tmp.y(), tmp.z(), tmp.t());
       if (jet.deltaR(genpart) > 0.4) continue;
 
@@ -336,9 +336,9 @@ CLHEP::HepLorentzVector TruthJetWeightFilter::getJetSubcomponent(const CLHEP::He
   McEventCollection::const_iterator itr;
   for (itr = events()->begin(); itr != events()->end(); ++itr) {
     const HepMC::GenEvent* genEvt = (*itr);
-    for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin(); pitr != genEvt->particles_end(); ++pitr) {
-      if ((*pitr)->status() != 1) continue;
-      int pdgid = (*pitr)->pdg_id();
+    for (auto  pitr: *genEvt) {
+      if (pitr->status() != 1) continue;
+      int pdgid = pitr->pdg_id();
 
       // Only add specific components
       /// @todo Check that it's ok to use loop continues in a switch -- "break" certainly wouldn't work.
@@ -363,7 +363,7 @@ CLHEP::HepLorentzVector TruthJetWeightFilter::getJetSubcomponent(const CLHEP::He
         continue;
       }
 
-      HepMC::FourVector tmp = (*pitr)->momentum();
+      HepMC::FourVector tmp = pitr->momentum();
       CLHEP::HepLorentzVector genpart(tmp.x(), tmp.y(), tmp.z(), tmp.t());
       if (genpart.perp()/Gaudi::Units::GeV < ptcutoff) continue;
       if (axis.deltaR(genpart) > maxdr) continue;
@@ -385,6 +385,22 @@ StatusCode TruthJetWeightFilter::saveWeight(double weight) {
   McEventCollection::iterator itr = mymccoll->begin();
   for (int ii = 0; itr!=mymccoll->end(); ++itr, ii++) {
     HepMC::GenEvent* genEvt = (*itr);
+#ifdef HEPMC3
+    auto wgtsC = genEvt->weights();
+
+    // Only the event weight #0 is read by CopyEventWeight.
+    // Remaining (Pythia) weights are usually all one, but anyway multiply them all here.
+    for (size_t iw = 0; iw < (size_t) wgtsC.size(); iw++) {
+      if (wgtsC[iw] != 0) weight *= wgtsC[iw];
+    }
+
+    // Then put my weight on first place
+    wgtsC[0] = weight;
+    ATH_MSG_DEBUG("McEventCollection #" << ii << " WeightContainer size " << wgtsC.size());
+    for (size_t iii = 0; iii < (size_t) wgtsC.size(); iii++) {
+      ATH_MSG_DEBUG("Weight #" << iii << " " << wgtsC[iii]);
+    }
+#else
     HepMC::WeightContainer& wgtsC = genEvt->weights();
 
     // Only the event weight #0 is read by CopyEventWeight.
@@ -399,6 +415,7 @@ StatusCode TruthJetWeightFilter::saveWeight(double weight) {
     for (size_t iii = 0; iii < (size_t) wgtsC.size(); iii++) {
       ATH_MSG_DEBUG("Weight #" << iii << " " << wgtsC[iii]);
     }
+#endif
   }
   return StatusCode::SUCCESS;
 }
diff --git a/Generators/GeneratorFilters/src/VHtoVVFilter.cxx b/Generators/GeneratorFilters/src/VHtoVVFilter.cxx
index 6a7a9c2b95a..2e7ad43d5d5 100644
--- a/Generators/GeneratorFilters/src/VHtoVVFilter.cxx
+++ b/Generators/GeneratorFilters/src/VHtoVVFilter.cxx
@@ -60,6 +60,53 @@ StatusCode VHtoVVFilter::filterEvent() {
   for (itr = events()->begin(); itr != events()->end(); ++itr) {
     // Loop over all particles in the event
     const HepMC::GenEvent* genEvt = (*itr);
+#ifdef HEPMC3
+    for (auto pitr: genEvt->particles()) {
+      // Loop over particles from the primary interaction that match the PDG Parent
+      if ( std::abs(pitr->pdg_id()) != m_PDGParent || pitr->status() != 3) continue;
+        bool isGrandParentHiggs = false;
+        bool isGrandParentV = false;
+        for ( auto thisMother: pitr->production_vertex()->particles_in()) { //loop over chain of grandparents
+          ATH_MSG_DEBUG(" Parent " << pitr->pdg_id() << " barcode = "   << HepMC::barcode(pitr) << " status = "  << pitr->status());
+          ATH_MSG_DEBUG(" a Parent mother "  << thisMother->pdg_id()<< " barc = " << HepMC::barcode(thisMother));
+          if ( thisMother->pdg_id() == m_PDGGrandParent ) isGrandParentHiggs = true; else isGrandParentV = true;
+        }
+        ATH_MSG_DEBUG(" Grand Parent is Higgs? " << isGrandParentHiggs);
+        ATH_MSG_DEBUG(" Grand Parent is V? " << isGrandParentV);
+
+        if (!isGrandParentHiggs && !isGrandParentV) continue;
+
+        if (isGrandParentHiggs) {
+          ++nHiggsParent;
+          for (auto thisChild:pitr->end_vertex()->particles_out()) {
+            ATH_MSG_DEBUG(" child " << thisChild->pdg_id());
+            if (!okPDGHVChild1) {
+              for (size_t i = 0; i < m_PDGHVChild1.size(); ++i)
+                if (abs(thisChild->pdg_id()) == m_PDGHVChild1[i]) okPDGHVChild1 = true;
+              if (okPDGHVChild1) break;
+            }
+            if (!okPDGHVChild2) {
+              for (size_t i = 0; i < m_PDGHVChild2.size(); ++i)
+                if (std::abs(thisChild->pdg_id()) == m_PDGHVChild2[i]) okPDGHVChild2 = true;
+              if (okPDGHVChild2) break;
+            }
+          }
+        } //end of higgs grandparent loop
+
+        if (isGrandParentV) {
+          ++nVParent;
+          for (auto thisChild: pitr->end_vertex()->particles_out()) {
+            ATH_MSG_DEBUG(" child " << thisChild->pdg_id());
+            if (!okPDGAssocVChild) {
+              for (unsigned int i=0;i<m_PDGAssocVChild.size();++i)
+                if (std::abs(thisChild->pdg_id()) == m_PDGAssocVChild[i]) okPDGAssocVChild = true;
+              if (okPDGAssocVChild) break;
+            }
+
+          }
+      }     
+   }
+#else
     for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin(); pitr != genEvt->particles_end(); ++pitr ) {
       // Loop over particles from the primary interaction that match the PDG Parent
       if ( abs((*pitr)->pdg_id()) == m_PDGParent && (*pitr)->status() == 3) {
@@ -117,6 +164,7 @@ StatusCode VHtoVVFilter::filterEvent() {
 
       } //end good parent loop
     }
+#endif    
   }
 
   ATH_MSG_DEBUG("Result " << nHiggsParent << " " << okPDGHVChild1 << " " << okPDGHVChild2);
diff --git a/Generators/GeneratorFilters/src/WMultiLeptonFilter.cxx b/Generators/GeneratorFilters/src/WMultiLeptonFilter.cxx
index 7019ecaa09e..c45165ff448 100644
--- a/Generators/GeneratorFilters/src/WMultiLeptonFilter.cxx
+++ b/Generators/GeneratorFilters/src/WMultiLeptonFilter.cxx
@@ -42,6 +42,41 @@ StatusCode WMultiLeptonFilter::filterEvent() {
   for (itr = events()->begin(); itr!=events()->end(); ++itr) {
     // Loop over all particles in the event
     const HepMC::GenEvent* genEvt = (*itr);
+#ifdef HEPMC3
+    for (auto pitr: genEvt->particles()) {
+      if ( std::abs(pitr->pdg_id())!= 24 || pitr->status() != 3) continue;
+        bool fromhiggs = false;
+        bool fromtop   = false;
+        for( auto thisMother: pitr->production_vertex()->particles_in()) {
+          ATH_MSG_DEBUG(" W barcode "   << HepMC::barcode(pitr) << "  status = "  << pitr->status());
+          ATH_MSG_DEBUG(" a W mother "  << thisMother->pdg_id()<< " barcode = " << HepMC::barcode(thisMother));
+          if ( thisMother->pdg_id() == 25 )     fromhiggs  = true;
+          if ( std::abs(thisMother->pdg_id()) == 6 ) fromtop    = true;
+          ATH_MSG_DEBUG(" W from " << fromhiggs << "  "  << fromtop);
+        }
+        for (auto thisChild: pitr->end_vertex()->particles_out()) {
+          if   (std::abs(thisChild->pdg_id()) == 11)  {
+            if (fromhiggs) NLeptonsH++;
+            if (fromtop)   NLeptonsT++;
+            if (fromhiggs && (thisChild->pdg_id() == -11) )  m_H_WPlus_e++;
+            if (fromhiggs && (thisChild->pdg_id() ==  11) )  m_H_WMinus_e++;
+            if (fromtop   && (thisChild->pdg_id() == -11) )  m_T_WPlus_e++;
+            if (fromtop   && (thisChild->pdg_id() ==  11) )  m_T_WMinus_e++;
+            ATH_MSG_DEBUG(" electron from W ");
+          }
+
+          if   (std::abs(thisChild->pdg_id()) == 13)  {
+            if (fromhiggs) NLeptonsH++;
+            if (fromtop)   NLeptonsT++;
+            if (fromhiggs && (thisChild->pdg_id() == -13) )  m_H_WPlus_m++;
+            if (fromhiggs && (thisChild->pdg_id() ==  13) )  m_H_WMinus_m++;
+            if (fromtop   && (thisChild->pdg_id() == -13) )  m_T_WPlus_m++;
+            if (fromtop   && (thisChild->pdg_id() ==  13) )  m_T_WMinus_m++;
+            ATH_MSG_DEBUG(" muon from W ");
+          }
+        }
+	}
+#else
     for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin(); pitr != genEvt->particles_end(); ++pitr) {
       if ( abs((*pitr)->pdg_id()) == 24 && (*pitr)->status() == 3) {
         HepMC::GenVertex::particle_iterator firstMother = (*pitr)->production_vertex()->particles_begin(HepMC::parents);
@@ -82,6 +117,7 @@ StatusCode WMultiLeptonFilter::filterEvent() {
         }
       }
     }
+#endif
   }
   // NB. no taus!
 
diff --git a/Generators/GeneratorFilters/src/XtoVVDecayFilter.cxx b/Generators/GeneratorFilters/src/XtoVVDecayFilter.cxx
index 9e671c2a090..0d496ff7815 100644
--- a/Generators/GeneratorFilters/src/XtoVVDecayFilter.cxx
+++ b/Generators/GeneratorFilters/src/XtoVVDecayFilter.cxx
@@ -91,7 +91,7 @@ StatusCode XtoVVDecayFilter::filterEvent() {
 }
 
 
-void XtoVVDecayFilter::FindAncestor(const HepMC::GenVertexPtr searchvertex,
+void XtoVVDecayFilter::FindAncestor(HepMC::ConstGenVertexPtr searchvertex,
                                     int targetPDGID, bool& okPDGChild1, bool& okPDGChild2) {
   if (!searchvertex) return;
 #ifdef HEPMC3
diff --git a/Generators/GeneratorFilters/src/XtoVVDecayFilterExtended.cxx b/Generators/GeneratorFilters/src/XtoVVDecayFilterExtended.cxx
index 747e6ed9c1a..5470286fdc5 100644
--- a/Generators/GeneratorFilters/src/XtoVVDecayFilterExtended.cxx
+++ b/Generators/GeneratorFilters/src/XtoVVDecayFilterExtended.cxx
@@ -83,7 +83,7 @@ StatusCode XtoVVDecayFilterExtended::filterEvent() {
 
 // Runs the history of ancestors and returns TRUE if it finds the
 // m_PDGGrandParent in the list of ansestors
-bool XtoVVDecayFilterExtended::RunHistory(HepMC::GenParticlePtr pitr) {
+bool XtoVVDecayFilterExtended::RunHistory(HepMC::ConstGenParticlePtr pitr) {
   if (! pitr->production_vertex()) {
     ATH_MSG_DEBUG("No History for this case");
     return false;
@@ -96,7 +96,7 @@ bool XtoVVDecayFilterExtended::RunHistory(HepMC::GenParticlePtr pitr) {
     return false;
   }
   int result = 999;
-  HepMC::GenParticle *pitr_current = (*firstMother);
+  HepMC::ConstGenParticlePtr pitr_current = (*firstMother);
   while ( result >= 0 ) {
     pitr_current = CheckGrandparent(pitr_current, result);
     if (result == m_PDGGrandParent) return true;
@@ -108,7 +108,7 @@ bool XtoVVDecayFilterExtended::RunHistory(HepMC::GenParticlePtr pitr) {
 
 // checks whether the grandparent of a given particle is m_PDGGrandParent
 // it returns the first mother
-HepMC::GenParticlePtr  XtoVVDecayFilterExtended::CheckGrandparent(HepMC::GenParticlePtr pitr, int &result) {
+HepMC::ConstGenParticlePtr  XtoVVDecayFilterExtended::CheckGrandparent(HepMC::ConstGenParticlePtr pitr, int &result) {
 
   if (! pitr->production_vertex()) {
     ATH_MSG_DEBUG("No ancestor for this case");
@@ -135,7 +135,7 @@ HepMC::GenParticlePtr  XtoVVDecayFilterExtended::CheckGrandparent(HepMC::GenPart
 }
 
 
-void XtoVVDecayFilterExtended::FindAncestor(const HepMC::GenVertexPtr searchvertex,
+void XtoVVDecayFilterExtended::FindAncestor(HepMC::ConstGenVertexPtr searchvertex,
                                     int targetPDGID, bool& okPDGChild1, bool& okPDGChild2) {
   if (!searchvertex) return;
   const HepMC::GenVertex::particles_out_const_iterator firstAncestor = searchvertex->particles_out_const_begin();
@@ -143,7 +143,7 @@ void XtoVVDecayFilterExtended::FindAncestor(const HepMC::GenVertexPtr searchvert
   HepMC::GenVertex::particles_out_const_iterator thisAncestor = firstAncestor;
   for (; thisAncestor != endAncestor; ++thisAncestor){
     //ATH_MSG_DEBUG(" child " << (*thisAncestor)->pdg_id());
-    if (abs((*thisAncestor)->pdg_id()) == targetPDGID) { //same particle as parent
+    if (std::abs((*thisAncestor)->pdg_id()) == targetPDGID) { //same particle as parent
       FindAncestor((*thisAncestor)->end_vertex(), targetPDGID, okPDGChild1, okPDGChild2);
     } else {
       if (!okPDGChild1) {
@@ -157,7 +157,7 @@ void XtoVVDecayFilterExtended::FindAncestor(const HepMC::GenVertexPtr searchvert
       }
       if (!okPDGChild2) {
         for (size_t i = 0; i < m_PDGChild2.size(); ++i) {
-          if (abs((*thisAncestor)->pdg_id()) == m_PDGChild2[i]) {
+          if (std::abs((*thisAncestor)->pdg_id()) == m_PDGChild2[i]) {
             okPDGChild2 = true;
             break;
           }
diff --git a/Generators/GeneratorFilters/src/ZtoLeptonFilter.cxx b/Generators/GeneratorFilters/src/ZtoLeptonFilter.cxx
index 548267dedfd..882883ddefd 100644
--- a/Generators/GeneratorFilters/src/ZtoLeptonFilter.cxx
+++ b/Generators/GeneratorFilters/src/ZtoLeptonFilter.cxx
@@ -16,6 +16,23 @@ StatusCode ZtoLeptonFilter::filterEvent() {
   McEventCollection::const_iterator itr;
   for (itr = events()->begin(); itr!=events()->end(); ++itr) {
     const HepMC::GenEvent* genEvt = (*itr);
+#ifdef HEPMC3
+    for ( auto pitr: genEvt->particles()) {
+      if (pitr->pdg_id() == 23) {
+        if ( !pitr->end_vertex() && pitr->status()==3) continue; // Allow status 3 Zs with no end vertex
+        else if (!pitr->end_vertex() ){
+          // Found a Z boson with no end vertex and status!=3 .  Something is sick about this event
+          break;
+        }
+        // Z children
+        for (auto thisChild: pitr->end_vertex()->particles_out()) {
+          if (abs(thisChild->pdg_id()) == 11 || abs(thisChild->pdg_id()) == 13 || abs(thisChild->pdg_id()) == 15) {
+            return StatusCode::SUCCESS;
+          }
+        }
+      }
+    }
+#else
     for (HepMC::GenEvent::particle_const_iterator pitr = genEvt->particles_begin();	pitr != genEvt->particles_end(); ++pitr) {
       if (((*pitr)->pdg_id()) == 23) {
         if ( !(*pitr)->end_vertex() && (*pitr)->status()==3) continue; // Allow status 3 Zs with no end vertex
@@ -34,6 +51,7 @@ StatusCode ZtoLeptonFilter::filterEvent() {
         }
       }
     }
+#endif
   }
   setFilterPassed(false);
   return StatusCode::SUCCESS;
-- 
GitLab