From 0c7e8cbc7b94c1be4a6ced4a6536cfe493022ab4 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Fri, 18 Nov 2022 16:04:28 +0100
Subject: [PATCH] Fix Geant4Particle charges. Remove python style errors. Fix
 DDDigi framework example

---
 DDDigi/include/DDDigi/DigiAction.h          |  2 +-
 DDDigi/include/DDDigi/DigiKernel.h          |  2 +-
 DDDigi/src/DigiAction.cpp                   |  6 +++--
 DDDigi/src/DigiKernel.cpp                   |  4 +--
 DDG4/CMakeLists.txt                         |  3 +--
 DDG4/hepmc/HepMC3EventReader.cpp            |  2 +-
 DDG4/include/DDG4/Geant4Particle.h          | 26 +++++++++---------
 DDG4/plugins/Geant4EventReaderGuineaPig.cpp |  5 ++--
 DDG4/plugins/Geant4EventReaderHepEvt.cpp    | 16 +++++++----
 DDG4/plugins/Geant4EventReaderHepMC.cpp     | 21 +++++++++------
 DDG4/src/Geant4InputHandling.cpp            |  4 +--
 DDG4/src/Geant4Output2ROOT.cpp              | 28 +++++++++----------
 DDG4/src/Geant4ParticleGenerator.cpp        |  2 +-
 DDG4/src/Geant4ParticleHandler.cpp          |  2 +-
 DDG4/src/Geant4PhysicsList.cpp              | 30 ++++++++++-----------
 examples/DDG4/scripts/TestUserCommands.py   |  6 ++---
 16 files changed, 85 insertions(+), 74 deletions(-)

diff --git a/DDDigi/include/DDDigi/DigiAction.h b/DDDigi/include/DDDigi/DigiAction.h
index 583f8c772..529d60b0c 100644
--- a/DDDigi/include/DDDigi/DigiAction.h
+++ b/DDDigi/include/DDDigi/DigiAction.h
@@ -172,7 +172,7 @@ namespace dd4hep {
       /// Access single property (CONST)
       const Property& property(const std::string& name)  const;
       /// Print the property values
-      virtual std::size_t printProperties() const;
+      virtual int printProperties() const;
 
       /// Adopt named property of another action for data processing
       virtual void adopt_property(DigiAction* action, const std::string& foreign_name, const std::string& local_name);
diff --git a/DDDigi/include/DDDigi/DigiKernel.h b/DDDigi/include/DDDigi/DigiKernel.h
index 125047778..23d6bfaf5 100644
--- a/DDDigi/include/DDDigi/DigiKernel.h
+++ b/DDDigi/include/DDDigi/DigiKernel.h
@@ -104,7 +104,7 @@ namespace dd4hep {
       
       /** Property access                            */
       /// Print the property values
-      virtual std::size_t printProperties() const  override;
+      virtual int printProperties() const  override;
 
       /** Client output level settings               */
       /// Fill cache with the global output level of a named object. Must be set before instantiation
diff --git a/DDDigi/src/DigiAction.cpp b/DDDigi/src/DigiAction.cpp
index b76216bab..f27732dd0 100644
--- a/DDDigi/src/DigiAction.cpp
+++ b/DDDigi/src/DigiAction.cpp
@@ -69,13 +69,15 @@ long DigiAction::release() {
 }
 
 /// Set DigiAction property
-std::size_t DigiAction::printProperties()   const {
+int DigiAction::printProperties()   const {
+  int count = 0;
   const auto& props = properties().properties();
   for( const auto& p : props )   {
     std::string pn = name()+"."+p.first;
     always("+++ %-32s = %-42s  [%s]", pn.c_str(), p.second.str().c_str(), p.second.type().c_str());
+    ++count;
   }
-  return props.size();
+  return count;
 }
 
 /// Adopt named property of another action for data processing
diff --git a/DDDigi/src/DigiKernel.cpp b/DDDigi/src/DigiKernel.cpp
index 566813ddc..431299db2 100644
--- a/DDDigi/src/DigiKernel.cpp
+++ b/DDDigi/src/DigiKernel.cpp
@@ -245,8 +245,8 @@ std::mutex& DigiKernel::global_io_lock()   const  {
 }
 
 /// Print the property values
-std::size_t DigiKernel::printProperties()  const  {
-  std::size_t count = this->DigiAction::printProperties();
+int DigiKernel::printProperties()  const  {
+  int count = this->DigiAction::printProperties();
   for( const auto& cl : internals->clientLevels )  {
     always("OutputLevel[%s]:  %d", cl.first.c_str(), cl.second);
     ++count;
diff --git a/DDG4/CMakeLists.txt b/DDG4/CMakeLists.txt
index c57166b36..49ac13684 100644
--- a/DDG4/CMakeLists.txt
+++ b/DDG4/CMakeLists.txt
@@ -115,9 +115,8 @@ ENDIF()
 IF(DD4HEP_USE_HEPMC3)
   dd4hep_add_plugin(DDG4HepMC3
     SOURCES hepmc/*.cpp
-    USES    DD4hep::DDG4
+    USES    DD4hep::DDG4 Geant4::Interface ${HEPMC3_LIBRARIES}
     INCLUDES $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/hepmc> $<BUILD_INTERFACE:${HEPMC3_INCLUDE_DIR}>
-    USES ${HEPMC3_LIBRARIES}
     )
   install(TARGETS DDG4HepMC3 EXPORT DD4hep LIBRARY DESTINATION lib)
   set_target_properties(DDG4HepMC3 PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION})
diff --git a/DDG4/hepmc/HepMC3EventReader.cpp b/DDG4/hepmc/HepMC3EventReader.cpp
index 67c576ff4..49d0d747b 100644
--- a/DDG4/hepmc/HepMC3EventReader.cpp
+++ b/DDG4/hepmc/HepMC3EventReader.cpp
@@ -93,7 +93,7 @@ HEPMC3EventReader::readParticles(int event_number, Vertices& vertices, Particles
     const int   pdg     = mcp->pid();
     PropertyMask status(p->status);
     p->pdgID        = pdg;
-    p->charge       = 0; // int(mcp->getCharge()*3.0); // FIXME
+    p->charge       = int(mcp->getCharge()*3.0);
     p->psx          = mom.get_component(0) * mom_unit;
     p->psy          = mom.get_component(1) * mom_unit;
     p->psz          = mom.get_component(2) * mom_unit;
diff --git a/DDG4/include/DDG4/Geant4Particle.h b/DDG4/include/DDG4/Geant4Particle.h
index dffe9a6c0..72aea0db2 100644
--- a/DDG4/include/DDG4/Geant4Particle.h
+++ b/DDG4/include/DDG4/Geant4Particle.h
@@ -54,17 +54,17 @@ namespace dd4hep {
 
     /// Track properties
     enum Geant4ParticleProperties {
-      G4PARTICLE_CREATED_HIT = 1<<1,
-      G4PARTICLE_PRIMARY = 1<<2,
-      G4PARTICLE_HAS_SECONDARIES = 1<<3,
+      G4PARTICLE_CREATED_HIT         = 1<<1,
+      G4PARTICLE_PRIMARY             = 1<<2,
+      G4PARTICLE_HAS_SECONDARIES     = 1<<3,
       G4PARTICLE_ABOVE_ENERGY_THRESHOLD = 1<<4,
-      G4PARTICLE_KEEP_PROCESS = 1<<5,
-      G4PARTICLE_KEEP_PARENT = 1<<6,
+      G4PARTICLE_KEEP_PROCESS        = 1<<5,
+      G4PARTICLE_KEEP_PARENT         = 1<<6,
       G4PARTICLE_CREATED_CALORIMETER_HIT = 1<<7,
       G4PARTICLE_CREATED_TRACKER_HIT = 1<<8,
-      G4PARTICLE_KEEP_USER = 1<<9,
-      G4PARTICLE_KEEP_ALWAYS = 1<<10,
-      G4PARTICLE_FORCE_KILL = 1<<11,
+      G4PARTICLE_KEEP_USER           = 1<<9,
+      G4PARTICLE_KEEP_ALWAYS         = 1<<10,
+      G4PARTICLE_FORCE_KILL          = 1<<11,
 
       // Generator status for a given particles: bit 0...4, agreed by many formats (HepMC, LCIO, ....):
       G4PARTICLE_GEN_EMPTY           = 1<<0,  // Empty line
@@ -111,11 +111,11 @@ namespace dd4hep {
       int originalG4ID = 0;  //! not persistent
       int g4Parent = 0, reason = 0, mask = 0;
       int steps  = 0, secondaries = 0, pdgID = 0;
-      int status = 0, colorFlow[2] {0,0};
-      unsigned short genStatus= 0;
-      char  charge = 0;
-      char  _spare[1] {0};
-      float spin[3] {0E0,0E0,0E0};
+      int status = 0, colorFlow[2] { 0, 0 };
+      unsigned short genStatus     { 0 };
+      char  charge                 { 0 };
+      char  _spare[1]              { 0 };
+      float spin[3]                { 0E0,0E0,0E0 };
       // 12 ints + 4 bytes + 3 floats should be aligned to 8 bytes....
       double vsx  = 0E0, vsy  = 0E0, vsz = 0E0;
       double vex  = 0E0, vey  = 0E0, vez = 0E0;
diff --git a/DDG4/plugins/Geant4EventReaderGuineaPig.cpp b/DDG4/plugins/Geant4EventReaderGuineaPig.cpp
index 92082b406..f8ba18c53 100644
--- a/DDG4/plugins/Geant4EventReaderGuineaPig.cpp
+++ b/DDG4/plugins/Geant4EventReaderGuineaPig.cpp
@@ -224,11 +224,12 @@ Geant4EventReaderGuineaPig::readParticles(int /* event_number */,
     PropertyMask status(p->status);
 
     //  PDGID: If Energy positive (negative) particle is electron (positron)
+    //         Remember: Geant4Particle charge is in units of 1/3 elementary/positron charge
     p->pdgID  = 11;
-    p->charge = -1;
+    p->charge = -1 * 3;
     if(Energy < 0.0) {
       p->pdgID = -11;
-      p->charge = +1;
+      p->charge = +1 * 3;
     }
 
     //  Momentum vector
diff --git a/DDG4/plugins/Geant4EventReaderHepEvt.cpp b/DDG4/plugins/Geant4EventReaderHepEvt.cpp
index 0fcb2c085..c8a773758 100644
--- a/DDG4/plugins/Geant4EventReaderHepEvt.cpp
+++ b/DDG4/plugins/Geant4EventReaderHepEvt.cpp
@@ -23,7 +23,7 @@
 
 
 // Framework include files
-#include "DDG4/Geant4InputAction.h"
+#include <DDG4/Geant4InputAction.h>
 
 // C/C++ include files
 #include <fstream>
@@ -80,10 +80,14 @@ namespace dd4hep {
 // #include "DDG4/Geant4EventReaderHepEvt"
 
 // Framework include files
-#include "DDG4/Factories.h"
-#include "DD4hep/Printout.h"
-#include "CLHEP/Units/SystemOfUnits.h"
-#include "CLHEP/Units/PhysicalConstants.h"
+#include <DDG4/Factories.h>
+#include <DD4hep/Printout.h>
+#include <CLHEP/Units/SystemOfUnits.h>
+#include <CLHEP/Units/PhysicalConstants.h>
+
+// Geant4 include files
+#include <G4GlobalConfig.hh>
+#include <G4ParticleTable.hh>
 
 // C/C++ include files
 #include <cerrno>
@@ -237,6 +241,8 @@ Geant4EventReaderHepEvt::readParticles(int /* event_number */,
     //
     //  PDGID
     p->pdgID = IDHEP;
+    auto* def = G4ParticleTable::GetParticleTable()->FindParticle(p->pdgID);
+    p->charge = int(3.0 * (def ? def->GetPDGCharge() : 1.0)); // Assume e-/pi-
     //
     //  Momentum vector
     p->pex = p->psx = PHEP1*CLHEP::GeV;
diff --git a/DDG4/plugins/Geant4EventReaderHepMC.cpp b/DDG4/plugins/Geant4EventReaderHepMC.cpp
index 8c7c3fe93..737ef7acb 100644
--- a/DDG4/plugins/Geant4EventReaderHepMC.cpp
+++ b/DDG4/plugins/Geant4EventReaderHepMC.cpp
@@ -21,10 +21,13 @@
 @}
  */
 
+// Geant4 include files
+#include <G4GlobalConfig.hh>
+#include <G4ParticleTable.hh>
 
 // Framework include files
-#include "DDG4/IoStreams.h"
-#include "DDG4/Geant4InputAction.h"
+#include <DDG4/IoStreams.h>
+#include <DDG4/Geant4InputAction.h>
 
 // C/C++ include files
 
@@ -81,14 +84,14 @@ namespace dd4hep {
 //--------------------------------------------------------------------
 //
 //====================================================================
-// #include "DDG4/Geant4EventReaderHepMC"
+// #include <DDG4/Geant4EventReaderHepMC"
 
 // Framework include files
-#include "DDG4/Factories.h"
-#include "DD4hep/Printout.h"
-#include "DDG4/Geant4Primary.h"
-#include "CLHEP/Units/SystemOfUnits.h"
-#include "CLHEP/Units/PhysicalConstants.h"
+#include <DDG4/Factories.h>
+#include <DD4hep/Printout.h>
+#include <DDG4/Geant4Primary.h>
+#include <CLHEP/Units/SystemOfUnits.h>
+#include <CLHEP/Units/PhysicalConstants.h>
 
 // C/C++ include files
 #include <cerrno>
@@ -444,6 +447,8 @@ int HepMC::read_particle(EventStream &info, istringstream& input, Geant4Particle
     cout << "Particle id: " << p->id << endl;
   }
 #endif
+  G4ParticleDefinition* def = G4ParticleTable::GetParticleTable()->FindParticle(p->pdgID);
+  p->charge = int(3.0 * (def ? def->GetPDGCharge() : -1.0)); // Assume e-/pi-
   p->psx *= info.mom_unit;
   p->psy *= info.mom_unit;
   p->psz *= info.mom_unit;
diff --git a/DDG4/src/Geant4InputHandling.cpp b/DDG4/src/Geant4InputHandling.cpp
index 882487109..ecbbf9142 100644
--- a/DDG4/src/Geant4InputHandling.cpp
+++ b/DDG4/src/Geant4InputHandling.cpp
@@ -76,7 +76,7 @@ dd4hep::sim::createPrimary(int particle_id,
   p->colorFlow[0] = 0;
   p->colorFlow[0] = 0;
   p->mass         = g4p->GetMass();
-  p->charge       = g4p->GetCharge();
+  p->charge       = int(3.0 * g4p->GetCharge());
   PropertyMask status(p->status);
   status.set(G4PARTICLE_GEN_STABLE);
   return p;
@@ -349,7 +349,7 @@ static G4PrimaryParticle* createG4Primary(const Geant4ParticleHandle p)  {
   else   {
     const G4ParticleDefinition* def = p.definition();
     g4 = new G4PrimaryParticle(def, p->psx, p->psy, p->psz, p.energy());
-    g4->SetCharge(p.charge());
+    g4->SetCharge(double(p.charge())/3.0);
   }
   // The particle is fully defined with the 4-vector set above, setting the mass isn't necessary, not
   // using the 4-vector, means the PDG mass is used, and the momentum is scaled if the mass is set here
diff --git a/DDG4/src/Geant4Output2ROOT.cpp b/DDG4/src/Geant4Output2ROOT.cpp
index d543eedef..0eb97bcf5 100644
--- a/DDG4/src/Geant4Output2ROOT.cpp
+++ b/DDG4/src/Geant4Output2ROOT.cpp
@@ -12,21 +12,22 @@
 //==========================================================================
 
 // Framework include files
-#include "DD4hep/Printout.h"
-#include "DD4hep/Primitives.h"
-#include "DD4hep/InstanceCount.h"
-#include "DDG4/Geant4HitCollection.h"
-#include "DDG4/Geant4Output2ROOT.h"
-#include "DDG4/Geant4Particle.h"
-#include "DDG4/Geant4Data.h"
+#include <DD4hep/Printout.h>
+#include <DD4hep/Primitives.h>
+#include <DD4hep/InstanceCount.h>
+#include <DDG4/Geant4HitCollection.h>
+#include <DDG4/Geant4Output2ROOT.h>
+#include <DDG4/Geant4Particle.h>
+#include <DDG4/Geant4Data.h>
+
 // Geant4 include files
-#include "G4HCofThisEvent.hh"
-#include "G4ParticleDefinition.hh"
+#include <G4HCofThisEvent.hh>
+#include <G4ParticleDefinition.hh>
 
 // ROOT include files
-#include "TFile.h"
-#include "TTree.h"
-#include "TBranch.h"
+#include <TFile.h>
+#include <TTree.h>
+#include <TBranch.h>
 
 using namespace dd4hep::sim;
 using namespace dd4hep;
@@ -154,9 +155,6 @@ void Geant4Output2ROOT::saveEvent(OutputContext<G4Event>& /* ctxt */) {
       vector<void*> particles;
       particles.reserve(pm.size());
       for ( const auto& i : pm )   {
-	const Geant4ParticleHandle p = i.second;
-	const G4ParticleDefinition* def = p.definition();
-	if ( def ) i.second->charge = 3.0*def->GetPDGCharge();
         particles.emplace_back((ParticleMap::mapped_type*)i.second);
       }
       fill("MCParticles",manipulator->vec_type,&particles);
diff --git a/DDG4/src/Geant4ParticleGenerator.cpp b/DDG4/src/Geant4ParticleGenerator.cpp
index 0be46c42b..f15ecbfed 100644
--- a/DDG4/src/Geant4ParticleGenerator.cpp
+++ b/DDG4/src/Geant4ParticleGenerator.cpp
@@ -158,7 +158,7 @@ void Geant4ParticleGenerator::operator()(G4Event*) {
     p->psy          = unit_direction.Y()*momentum;
     p->psz          = unit_direction.Z()*momentum;
     p->mass         = m_particle->GetPDGMass();
-    p->charge       = m_particle->GetPDGCharge();
+    p->charge       = 3 * m_particle->GetPDGCharge();
     p->spin[0]      = 0;
     p->spin[1]      = 0;
     p->spin[2]      = 0;
diff --git a/DDG4/src/Geant4ParticleHandler.cpp b/DDG4/src/Geant4ParticleHandler.cpp
index 691e87131..8295a97d5 100644
--- a/DDG4/src/Geant4ParticleHandler.cpp
+++ b/DDG4/src/Geant4ParticleHandler.cpp
@@ -251,7 +251,7 @@ void Geant4ParticleHandler::begin(const G4Track* track)   {
     m_currTrack.daughters.clear();
     m_currTrack.pdgID        = h.pdgID();
     m_currTrack.mass         = h.mass();
-    m_currTrack.charge       = h.charge();
+    m_currTrack.charge       = int(3.0 * h.charge());
     ++m_globalParticleID;
   }
   m_currTrack.steps       = 0;
diff --git a/DDG4/src/Geant4PhysicsList.cpp b/DDG4/src/Geant4PhysicsList.cpp
index fd505e7d0..a67405b8d 100644
--- a/DDG4/src/Geant4PhysicsList.cpp
+++ b/DDG4/src/Geant4PhysicsList.cpp
@@ -12,22 +12,22 @@
 //==========================================================================
 
 // Framework include files
-#include "DDG4/Geant4PhysicsList.h"
-#include "DDG4/Geant4UIMessenger.h"
-#include "DDG4/Geant4Particle.h"
-#include "DDG4/Geant4Kernel.h"
-#include "DD4hep/InstanceCount.h"
-#include "DD4hep/Printout.h"
-#include "DD4hep/Plugins.h"
+#include <DDG4/Geant4PhysicsList.h>
+#include <DDG4/Geant4UIMessenger.h>
+#include <DDG4/Geant4Particle.h>
+#include <DDG4/Geant4Kernel.h>
+#include <DD4hep/InstanceCount.h>
+#include <DD4hep/Printout.h>
+#include <DD4hep/Plugins.h>
 
 // Geant4 include files
-#include "G4VPhysicsConstructor.hh"
-#include "G4PhysListFactory.hh"
-#include "G4ProcessManager.hh"
-#include "G4ParticleTable.hh"
-#include "G4RunManager.hh"
-#include "G4VProcess.hh"
-#include "G4Decay.hh"
+#include <G4VPhysicsConstructor.hh>
+#include <G4PhysListFactory.hh>
+#include <G4ProcessManager.hh>
+#include <G4ParticleTable.hh>
+#include <G4RunManager.hh>
+#include <G4VProcess.hh>
+#include <G4Decay.hh>
 
 // C/C++ include files
 #include <stdexcept>
@@ -333,7 +333,7 @@ Geant4PhysicsListActionSequence::~Geant4PhysicsListActionSequence()  {
   InstanceCount::decrement(this);
 }
 
-#include "G4FastSimulationPhysics.hh"
+#include <G4FastSimulationPhysics.hh>
 
 
 /// Extend physics list from factory:
diff --git a/examples/DDG4/scripts/TestUserCommands.py b/examples/DDG4/scripts/TestUserCommands.py
index ed4074c87..97440baf7 100644
--- a/examples/DDG4/scripts/TestUserCommands.py
+++ b/examples/DDG4/scripts/TestUserCommands.py
@@ -41,9 +41,9 @@ def run():
     sys.exit(0)
 
   kernel = DDG4.Kernel()
-  kernel.loadGeometry(str("file:"
-                          + os.environ['DD4hepExamplesINSTALL']
-                          + "/examples/ClientTests/compact/BoxTrafos.xml"))
+  install = os.environ['DD4hepExamplesINSTALL']
+  geo_file = "file:" + install + "/examples/ClientTests/compact/BoxTrafos.xml"
+  kernel.loadGeometry(str(geo_file))
   geant4 = DDG4.Geant4(kernel)
   # Configure UI
   if args.macro:
-- 
GitLab