From c0be8bba2f0bac5cf9ec3e3bd59db860a8b67e14 Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Tue, 21 Aug 2012 20:55:28 +0000
Subject: [PATCH] Add support for electric and magnetic fields

---
 DDG4/CMakeLists.txt                         |  9 +-
 DDG4/include/DDG4/Defs.h                    |  2 +-
 DDG4/include/DDG4/Factories.h               | 77 +++++++++++++++--
 DDG4/include/DDG4/Geant4Converter.h         |  6 ++
 DDG4/include/DDG4/Geant4Field.h             | 54 ++++++++++++
 DDG4/include/DDG4/Geant4SensitiveDetector.h |  2 +-
 DDG4/src/Geant4CalorimeterSD.cpp            |  8 +-
 DDG4/src/Geant4Converter.cpp                | 53 +++++++++++-
 DDG4/src/Geant4Field.cpp                    | 24 ++++++
 DDG4/src/Geant4SensitiveDetector.cpp        |  6 +-
 DDG4/src/Geant4Setup.cpp                    | 93 +++++++++++++++++++++
 DDG4/src/Geant4Steppers.cpp                 | 52 ++++++++++++
 DDG4/src/Geant4TrackerSD.cpp                |  2 +-
 DDG4/src/Geant4XML.cpp                      | 41 +++++++++
 14 files changed, 410 insertions(+), 19 deletions(-)
 create mode 100644 DDG4/include/DDG4/Geant4Field.h
 create mode 100644 DDG4/src/Geant4Field.cpp
 create mode 100644 DDG4/src/Geant4Setup.cpp
 create mode 100644 DDG4/src/Geant4Steppers.cpp
 create mode 100644 DDG4/src/Geant4XML.cpp

diff --git a/DDG4/CMakeLists.txt b/DDG4/CMakeLists.txt
index e5e250834..3d36251d6 100644
--- a/DDG4/CMakeLists.txt
+++ b/DDG4/CMakeLists.txt
@@ -6,13 +6,20 @@ if(NOT Geant4_clhep_FOUND)
   set(Geant4_LIBRARIES ${Geant4_LIBRARIES} ${CLHEP_LIBRARIES})
 endif()
 
+if(DD4HEP_USE_XERCESC)
+  add_definitions(-DDD4HEP_USE_XERCESC)
+  set(libraries ${libraries} Reflex)
+endif()
+
 #---Includedirs-------------------------------------------------------------------
 include_directories(${CMAKE_SOURCE_DIR}/DDCore/include
                     ${CMAKE_CURRENT_SOURCE_DIR}/include 
                     ${ROOT_INCLUDE_DIR}
-                    ${Geant4_INCLUDE_DIRS})
+                    ${Geant4_INCLUDE_DIRS}
+                    ${XERCESC_INCLUDE_DIR})
 
 #---Add Library-------------------------------------------------------------------
 file(GLOB sources src/*.cpp)
 add_library(DD4hepG4 SHARED ${sources})
 target_link_libraries(DD4hepG4 DD4hepCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES})
+#target_link_libraries(DD4hepG4 DD4hepCore ${ROOT_LIBRARIES} ${XERCESC_LIBRARIES} ${Geant4_LIBRARIES})
diff --git a/DDG4/include/DDG4/Defs.h b/DDG4/include/DDG4/Defs.h
index a898eb46d..de6fdd104 100644
--- a/DDG4/include/DDG4/Defs.h
+++ b/DDG4/include/DDG4/Defs.h
@@ -29,7 +29,7 @@ namespace DD4hep {
     typedef Geometry::LCDD                 LCDD;
     typedef Geometry::Readout              Readout;
     typedef Geometry::DetElement           DetElement;
-    typedef Geometry::SensitiveDetector    SensitiveDetector;
+    //typedef Geometry::SensitiveDetector    SensitiveDetector;
 
     template<class HIT> struct HitCompare;
     template<class HIT> struct HitPositionCompare;
diff --git a/DDG4/include/DDG4/Factories.h b/DDG4/include/DDG4/Factories.h
index c15e84491..1fc0ee131 100644
--- a/DDG4/include/DDG4/Factories.h
+++ b/DDG4/include/DDG4/Factories.h
@@ -17,25 +17,90 @@
 // Framework include files
 #include "DDG4/Defs.h"
 #include <string>
+#include <map>
 
 // Forward declarations
-class Geant4SensitiveDetector;
+class G4MagIntegratorStepper;
+class G4EquationOfMotion;
+class G4MagneticField;
+class G4Mag_EqRhs;
 
 namespace DD4hep { 
-  namespace Geometry   {  class LCDD; }
-  namespace Simulation {  class Geant4SensitiveDetector; }
+  namespace Geometry   {  
+    class LCDD; 
+  }
+  namespace Simulation {  
+    class Geant4Converter;
+    class Geant4SensitiveDetector; 
+    template <typename T> class Geant4SetupAction  {
+    public:
+      static long create(Geometry::LCDD& lcdd, const Geant4Converter& cnv, const std::map<std::string,std::string>& attrs);
+    };
+  }
 }
 
 namespace {
-  template < typename P > class Factory<P, DD4hep::Simulation::Geant4SensitiveDetector*(std::string,DD4hep::Geometry::LCDD*)> {
+
+  template < typename P > class Factory<P, long(DD4hep::Geometry::LCDD*,const DD4hep::Simulation::Geant4Converter*,const std::map<std::string,std::string>*)> {
+  public:
+    typedef DD4hep::Geometry::LCDD              LCDD;
+    typedef DD4hep::Simulation::Geant4Converter cnv_t;
+    typedef std::map<std::string,std::string>   attrs_t;
+    static void Func(void *retaddr, void*, const std::vector<void*>& arg, void*) {
+      LCDD*    lcdd = (LCDD* )arg[0];
+      cnv_t*   cnv  = (cnv_t*)arg[1];
+      attrs_t* attr = (attrs_t*)arg[2];
+      long ret = DD4hep::Simulation::Geant4SetupAction<P>::create(*lcdd,*cnv,*attr);
+      new(retaddr) (long)(ret);
+    }
+  };
+
+  /// Factory to create Geant4 sensitive detectors
+  template <typename P> class Factory<P, DD4hep::Simulation::Geant4SensitiveDetector*(std::string,DD4hep::Geometry::LCDD*)> {
   public:  typedef DD4hep::Simulation::Geant4SensitiveDetector SD;
     static void Func(void *retaddr, void*, const std::vector<void*>& arg, void*) 
       {  *(SD**)retaddr = (SD*)new P(*(std::string*)arg[0], *(DD4hep::Geometry::LCDD*)arg[1]);           }
   };
+
+  /// Factory to create Geant4 steppers
+  template <typename P> class Factory<P, G4MagIntegratorStepper*(G4EquationOfMotion*)> {
+  public: static void Func(void *retaddr, void*, const std::vector<void*>& arg, void*) {
+      P* stepper = new P((G4EquationOfMotion*)arg[0]);
+      *(G4MagIntegratorStepper**)retaddr = (G4MagIntegratorStepper*)stepper;
+    }
+  };
+
+  /// Factory to create Geant4 steppers
+  template <typename P> class Factory<P, G4MagIntegratorStepper*(G4Mag_EqRhs*)> {
+  public: static void Func(void *retaddr, void*, const std::vector<void*>& arg, void*) {
+      P* stepper = new P((G4Mag_EqRhs*)arg[0]);
+      *(G4MagIntegratorStepper**)retaddr = (G4MagIntegratorStepper*)stepper;
+    }
+  };
+
+  /// Factory to create Geant4 equations of motion for magnetic fields
+  template <typename P> class Factory<P, G4Mag_EqRhs*(G4MagneticField*)> {
+  public: static void Func(void *retaddr, void*, const std::vector<void*>& arg, void*) {
+      P* o = new P((G4MagneticField*)arg[0]);
+      *(G4Mag_EqRhs**)retaddr = (G4Mag_EqRhs*)o;
+    }
+  };
 }
 
-#define DECLARE_GEANT4SENSITIVEDETECTOR(name) namespace DD4hep { namespace Simulation { }}   \
-  using DD4hep::Simulation::name;					                     \
+/// Plugin definition to create Geant4 sensitive detectors
+#define DECLARE_GEANT4SENSITIVEDETECTOR(name) namespace DD4hep { namespace Simulation { }}  using DD4hep::Simulation::name; \
   PLUGINSVC_FACTORY_WITH_ID(name,std::string(#name),DD4hep::Simulation::Geant4SensitiveDetector*(std::string,DD4hep::Geometry::LCDD*))
 
+/// Plugin definition to create Geant4 stpper objects
+#define DECLARE_GEANT4_STEPPER(name)    PLUGINSVC_FACTORY_WITH_ID(G4##name,std::string(#name),G4MagIntegratorStepper*(G4EquationOfMotion*))
+#define DECLARE_GEANT4_MAGSTEPPER(name) PLUGINSVC_FACTORY_WITH_ID(G4##name,std::string(#name),G4MagIntegratorStepper*(G4Mag_EqRhs*))
+
+/// Plugin definition to create Geant4 equations of motion for magnetic fields
+#define DECLARE_GEANT4_MAGMOTION(name) PLUGINSVC_FACTORY_WITH_ID(G4##name,std::string(#name),G4Mag_EqRhs*(G4MagneticField*))
+
+#define DECLARE_GEANT4_SETUP(name,func) \
+  namespace DD4hep { namespace Simulation { namespace { struct xml_g4_setup_##name {}; }               \
+  using DD4hep::Simulation::xml_g4_setup_##name;					                     \
+  template <> long Geant4SetupAction<xml_g4_setup_##name>::create(LCDD& l,const DD4hep::Simulation::Geant4Converter& e, const std::map<std::string,std::string>& a) {return func(l,e,a);} }} \
+  PLUGINSVC_FACTORY_WITH_ID(xml_g4_setup_##name,std::string(#name "_Geant4_action"),long(DD4hep::Geometry::LCDD*,const DD4hep::Simulation::Geant4Converter*,const std::map<std::string,std::string>*))
 #endif // DDG4_FACTORIES_H
diff --git a/DDG4/include/DDG4/Geant4Converter.h b/DDG4/include/DDG4/Geant4Converter.h
index 3cf92fa00..2a883ba16 100644
--- a/DDG4/include/DDG4/Geant4Converter.h
+++ b/DDG4/include/DDG4/Geant4Converter.h
@@ -31,6 +31,8 @@ class G4VSolid;
 class G4LogicalVolume;
 class G4PVPlacement;
 class G4Region;
+class G4Field;
+class G4FieldManager;
 class Geant4SensitiveDetector;
 class G4UserLimits;
 
@@ -93,6 +95,8 @@ namespace DD4hep {
       virtual void* handleVolume(const std::string& name, const TGeoVolume* volume) const;
       /// Convert the geometry type volume placement into the corresponding Geant4 object(s).
       virtual void* handlePlacement(const std::string& name, const TGeoNode* node) const;
+      /// Convert the geometry type field into the corresponding Geant4 object(s).
+      ///virtual void* handleField(const std::string& name, Ref_t field) const;
 
       /// Convert the geometry type region into the corresponding Geant4 object(s).
       virtual void* handleRegion(const TNamed* region, const std::set<const TGeoVolume*>& volumes) const;
@@ -100,6 +104,8 @@ namespace DD4hep {
       virtual void* handleLimitSet(const TNamed* limitset, const std::set<const TGeoVolume*>& volumes) const;
       /// Convert the geometry type SensitiveDetector into the corresponding Geant4 object(s).
       virtual void* handleSensitive(const TNamed* sens_det, const std::set<const TGeoVolume*>& volumes) const;
+      /// Handle the geant 4 specific properties
+      void handleProperties(LCDD::Properties& prp) const;
     };
   }    // End namespace Simulation
 }      // End namespace DD4hep
diff --git a/DDG4/include/DDG4/Geant4Field.h b/DDG4/include/DDG4/Geant4Field.h
new file mode 100644
index 000000000..164bdaaae
--- /dev/null
+++ b/DDG4/include/DDG4/Geant4Field.h
@@ -0,0 +1,54 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_GEANT4FIELD_H
+#define DD4HEP_GEANT4FIELD_H
+
+// Framework include files
+#include "DD4hep/LCDD.h"
+
+// Geant 4 include files
+#include "G4ElectroMagneticField.hh"
+#include "G4MagneticField.hh"
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Simulation namespace declaration
+   */
+  namespace Simulation {
+
+    // Forward declarations
+    class Geant4Field;
+
+    /** @class Geant4Field Geant4Field.h DDG4/Geant4Field.h
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    struct Geant4Field : public G4MagneticField   {
+      /// Reference to the detector description field
+      Geometry::OverlayedField  m_field;
+
+      public:
+      /// Constructor. The sensitive detector element is identified by the detector name
+      Geant4Field(Geometry::OverlayedField field) : m_field(field) {}
+      /// Standard destructor
+      virtual ~Geant4Field() {}
+      /// Access field values at a given point
+      virtual void GetFieldValue(const double pos[4], double *arr) const;
+      /// Does field change energy ?
+      virtual G4bool DoesFieldChangeEnergy() const;
+    };
+
+  }    // End namespace Simulation
+}      // End namespace DD4hep
+#endif // DD4HEP_GEANT4FIELD_H
diff --git a/DDG4/include/DDG4/Geant4SensitiveDetector.h b/DDG4/include/DDG4/Geant4SensitiveDetector.h
index 7a830a06e..241f3f3a3 100644
--- a/DDG4/include/DDG4/Geant4SensitiveDetector.h
+++ b/DDG4/include/DDG4/Geant4SensitiveDetector.h
@@ -43,7 +43,7 @@ namespace DD4hep {
      */
     struct Geant4SensitiveDetector : public G4VSensitiveDetector  {
       public:      
-
+      typedef Geometry::SensitiveDetector  SensitiveDetector;
       typedef G4THitsCollection<Geant4Hit> HitCollection;
       typedef Geant4Hit::Contribution      HitContribution;
       typedef Geant4StepHandler            StepHandler;
diff --git a/DDG4/src/Geant4CalorimeterSD.cpp b/DDG4/src/Geant4CalorimeterSD.cpp
index 586d905fd..780fe34ef 100644
--- a/DDG4/src/Geant4CalorimeterSD.cpp
+++ b/DDG4/src/Geant4CalorimeterSD.cpp
@@ -15,6 +15,8 @@
 #include "G4OpticalPhoton.hh"
 #include "G4VProcess.hh"
 
+using namespace std;
+
 /*
  *   DD4hep::Simulation namespace declaration
  */
@@ -56,11 +58,11 @@ namespace DD4hep {  namespace Simulation {
   template <> class Geant4GenericSD<OpticalCalorimeter> : public Geant4GenericSD<Calorimeter>  {
   public:
     /// Constructor. The sensitive detector element is identified by the detector name
-    Geant4GenericSD(const std::string& name, LCDD& lcdd)
+    Geant4GenericSD(const string& name, LCDD& lcdd)
       : Geant4GenericSD<Calorimeter>(name,lcdd) {          }
-   
+
     /// Initialize the sensitive detector for the usage of a single hit collection
-    bool defineCollection(const std::string& coll_name) {
+    bool defineCollection(const string& coll_name) {
       Geant4SensitiveDetector::defineCollection("Edep_" + coll_name);
       Geant4SensitiveDetector::defineCollection("Ceren_" + coll_name);
       return true;
diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp
index 8e428209b..031fca75f 100644
--- a/DDG4/src/Geant4Converter.cpp
+++ b/DDG4/src/Geant4Converter.cpp
@@ -9,6 +9,7 @@
 
 #include "DD4hep/LCDD.h"
 #include "DD4hep/Volumes.h"
+#include "DDG4/Geant4Field.h"
 #include "DDG4/Geant4Converter.h"
 #include "DDG4/Geant4SensitiveDetector.h"
 
@@ -63,7 +64,8 @@
 #include "G4Transform3D.hh"
 #include "G4ThreeVector.hh"
 #include "G4PVPlacement.hh"
-
+#include "G4ElectroMagneticField.hh"
+#include "G4FieldManager.hh"
 
 using namespace DD4hep::Simulation;
 using namespace DD4hep::Geometry;
@@ -452,7 +454,7 @@ void* Geant4Converter::handleSensitive(const TNamed* sens_det, const set<const T
     g4->defineCollection(sd.hitsCollection());
     ConstVolumeSet& volset = info.sensitives[sens_det];
     for(ConstVolumeSet::iterator i=volset.begin(); i!=volset.end();++i)    {
-      std::map<const TGeoVolume*, G4LogicalVolume*>::iterator v = info.g4Volumes.find(*i);
+      map<const TGeoVolume*, G4LogicalVolume*>::iterator v = info.g4Volumes.find(*i);
       if ( v == info.g4Volumes.end() )  {
 	throw runtime_error("Geant4Converter<SensitiveDetector>: FATAL Missing converted "
 			    "Geant 4 logical volume");
@@ -475,6 +477,46 @@ void* Geant4Converter::handleSensitive(const TNamed* sens_det, const set<const T
   return g4;
 }
 
+/// Handle the geant 4 specific properties
+void Geant4Converter::handleProperties(LCDD::Properties& prp)   const {
+  map<string,string>  processors;
+  static int s_idd = 9999999;
+  string id;
+  for(LCDD::Properties::const_iterator i=prp.begin(); i!=prp.end(); ++i) {
+    const string& nam = (*i).first;
+    const LCDD::PropertyValues& vals = (*i).second;
+    if ( nam.substr(0,6) == "geant4" ) {
+      LCDD::PropertyValues::const_iterator id_it = vals.find("id");
+      if ( id_it != vals.end() )  {
+	id= (*id_it).second;
+      }
+      else {
+	char txt[32];
+	::sprintf(txt,"%d",++s_idd);
+	id = txt;
+      }
+      processors.insert(make_pair(id,nam));
+    }
+  }
+  for(map<string,string>::const_iterator i=processors.begin(); i!=processors.end(); ++i) {
+    const Geant4Converter* ptr = this;
+    string nam = (*i).second;
+    const LCDD::PropertyValues& vals = prp[nam];
+    string type = vals.find("type")->second;
+    string tag  = type + "_Geant4_action";
+    long result = ROOT::Reflex::PluginService::Create<long>(tag,&m_lcdd,ptr,&vals);
+    if ( 0 == result ) {
+      throw runtime_error("Failed to locate plugin to interprete files of type"
+			  " \""+tag+"\" - no factory:"+type);
+    }
+    result = *(long*)result;
+    if ( result != 1 ) {
+      throw runtime_error("Failed to invoke the plugin "+tag+" of type "+type);
+    }
+    cout << "+++++ Executed Successfully Geant4 setup module *" << type << "* ." << endl;
+  }
+}
+
 template <typename O, typename C, typename F> void handle(const O* o, const C& c, F pmf)  {
   for(typename C::const_iterator i=c.begin(); i != c.end(); ++i) {
     (o->*pmf)((*i)->GetName(),*i);
@@ -487,6 +529,7 @@ template <typename O, typename C, typename F> void handleMap(const O* o, const C
 }
 
 void Geant4Converter::create(DetElement top) {
+  LCDD& lcdd = m_lcdd;
   G4GeometryInfo& geo = *(m_dataPtr=new G4GeometryInfo);
   m_data->clear();
   collect(top,geo);
@@ -500,6 +543,9 @@ void Geant4Converter::create(DetElement top) {
   cout << "++ Handled " << geo.solids.size() << " solids." << endl;
   handle(this, geo.volumes,   &Geant4Converter::handleVolume);
   cout << "++ Handled " << geo.volumes.size() << " volumes." << endl;
+  //handleMap(this, lcdd.fields(),   &Geant4Converter::handleField);
+  //cout << "++ Handled " << geo.fields.size() << " field entries." << endl;
+
   handleMap(this, geo.limits, &Geant4Converter::handleLimitSet);
   cout << "++ Handled " << geo.limits.size() << " limit sets." << endl;
   handleMap(this, geo.regions, &Geant4Converter::handleRegion);
@@ -510,4 +556,7 @@ void Geant4Converter::create(DetElement top) {
   // Now place all this stuff appropriately
   for(Data::const_reverse_iterator i=m_data->rbegin(); i != m_data->rend(); ++i)
     handle(this, (*i).second, &Geant4Converter::handlePlacement);
+
+  //==================== Fields
+  handleProperties(m_lcdd.properties());
 }
diff --git a/DDG4/src/Geant4Field.cpp b/DDG4/src/Geant4Field.cpp
new file mode 100644
index 000000000..791999dc7
--- /dev/null
+++ b/DDG4/src/Geant4Field.cpp
@@ -0,0 +1,24 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+// Framework include files
+#include "DDG4/Geant4Field.h"
+
+using namespace DD4hep::Simulation;
+using namespace DD4hep::Geometry;
+using namespace DD4hep;
+using namespace std;
+
+G4bool Geant4Field::DoesFieldChangeEnergy() const {
+  return m_field.changesEnergy();
+}
+
+void Geant4Field::GetFieldValue(const double pos[4], double *field) const {
+  return m_field.magneticField(pos,field);
+}
+
diff --git a/DDG4/src/Geant4SensitiveDetector.cpp b/DDG4/src/Geant4SensitiveDetector.cpp
index a598f1ba9..4e5abd94a 100644
--- a/DDG4/src/Geant4SensitiveDetector.cpp
+++ b/DDG4/src/Geant4SensitiveDetector.cpp
@@ -51,13 +51,13 @@ const string& Geant4SensitiveDetector::hitCollectionName(int which) const      {
 }
 
 /// Create single hits collection
-Geant4SensitiveDetector::HitCollection* Geant4SensitiveDetector::createCollection(const std::string& coll_name)  const  {
+Geant4SensitiveDetector::HitCollection* Geant4SensitiveDetector::createCollection(const string& coll_name)  const  {
   return new G4THitsCollection<Geant4Hit>(GetName(), coll_name);
 }
 namespace DD4hep { namespace Simulation {
 template <> Geant4CalorimeterHit* 
 Geant4SensitiveDetector::find<Geant4CalorimeterHit>(const HitCollection* c,const HitCompare<Geant4CalorimeterHit>& cmp)   {
-  typedef std::vector<Geant4CalorimeterHit*> _V;
+  typedef vector<Geant4CalorimeterHit*> _V;
   const _V* v = (const _V*)c->GetVector();
   for(_V::const_iterator i=v->begin(); i !=v->end(); ++i) 
     if ( cmp(*i) ) return *i;
@@ -111,5 +111,3 @@ Geant4SensitiveDetector::HitCollection* Geant4SensitiveDetector::collection(int
 /// Method is invoked if the event abortion is occured.
 void Geant4SensitiveDetector::clear() {
 }
-
-//DECLARE_TRANSLATION(LCDD2Geant4,create_g4);
diff --git a/DDG4/src/Geant4Setup.cpp b/DDG4/src/Geant4Setup.cpp
new file mode 100644
index 000000000..2cec4907b
--- /dev/null
+++ b/DDG4/src/Geant4Setup.cpp
@@ -0,0 +1,93 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+// Framework include files
+#include "DDG4/Factories.h"
+#include "DDG4/Geant4Field.h"
+#include "DDG4/Geant4Converter.h"
+#include "DD4hep/Fields.h"
+
+
+#include "G4TransportationManager.hh"
+#include "G4MagIntegratorStepper.hh"
+#include "G4Mag_EqRhs.hh"
+#include "G4ChordFinder.hh"
+#include "G4PropagatorInField.hh"
+
+using namespace DD4hep::Simulation;
+using namespace DD4hep::Geometry;
+using namespace std;
+typedef DD4hep::Geometry::LCDD lcdd_t;
+
+struct PropertyMap {
+  const map<string,string>& vals;
+  PropertyMap(const map<string,string>& v) : vals(v) {}
+  string value(const string& key) const;
+  double toDouble(const string& key) const;
+  bool operator[](const string& key) const  { return vals.find(key) != vals.end(); }
+};
+
+string PropertyMap::value(const string& key) const {
+  lcdd_t::PropertyValues::const_iterator iV = vals.find(key);
+  return iV == vals.end() ? "" : (*iV).second;
+}
+
+double PropertyMap::toDouble(const string& key) const {
+  return _toDouble(value(key));
+}
+
+static long setup_fields(lcdd_t& lcdd, const Geant4Converter& cnv, const map<string,string>& vals) {
+  PropertyMap pm(vals);
+  DD4hep::Geometry::OverlayedField fld  = lcdd.field();
+  G4MagIntegratorStepper*  stepper = 0;
+  G4MagneticField*         field = 0;
+  G4FieldManager*          fieldMgr = 0;
+  G4TransportationManager* tr = 0;
+  G4PropagatorInField*     propagator = 0;
+  G4ChordFinder*           chordFinder = 0;  
+
+  lcdd_t::PropertyValues::const_iterator iV;
+
+  string eq_typ      = pm.value("equation");
+  string stepper_typ = pm.value("stepper");
+  double value;
+
+  field    = new Geant4Field(fld);
+  tr       = G4TransportationManager::GetTransportationManager();
+  fieldMgr = tr->GetFieldManager();
+
+  fieldMgr->SetFieldChangesEnergy(fld.changesEnergy());
+  fieldMgr->SetDetectorField(field);
+
+  G4Mag_EqRhs* equation = ROOT::Reflex::PluginService::Create<G4Mag_EqRhs*>(eq_typ,field);
+  stepper = ROOT::Reflex::PluginService::Create<G4MagIntegratorStepper*>(stepper_typ,equation);
+
+  iV = vals.find("min_chord_step");
+  value = _toDouble((iV == vals.end()) ? string("1.0e-2 * mm") : (*iV).second);
+  chordFinder  = new G4ChordFinder(field,value,stepper);
+  propagator   = tr->GetPropagatorInField();
+  fieldMgr->SetChordFinder(chordFinder);
+
+  if ( pm["delta_chord"] ) {
+    chordFinder->SetDeltaChord(pm.toDouble("delta_chord"));
+  }
+  if ( pm["delta_one_step"] ) {
+    fieldMgr->SetAccuraciesWithDeltaOneStep(pm.toDouble("delta_one_step"));
+  }
+  if ( pm["delta_intersection"] ) {
+    fieldMgr->SetDeltaIntersection(pm.toDouble("delta_intersection"));
+  }
+  if ( pm["eps_min"] ) {
+    propagator->SetMinimumEpsilonStep(pm.toDouble("eps_min"));
+  }
+  if ( pm["eps_max"] ) {
+    propagator->SetMaximumEpsilonStep(pm.toDouble("eps_max"));
+  }
+  return 1;
+}
+DECLARE_GEANT4_SETUP(Geant4FieldSetup,setup_fields);
diff --git a/DDG4/src/Geant4Steppers.cpp b/DDG4/src/Geant4Steppers.cpp
new file mode 100644
index 000000000..1dcebb0e9
--- /dev/null
+++ b/DDG4/src/Geant4Steppers.cpp
@@ -0,0 +1,52 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+// Framework include files
+#include "DDG4/Factories.h"
+
+// Geant 4 include files
+#include "G4ExplicitEuler.hh"
+#include "G4ImplicitEuler.hh"
+#include "G4SimpleRunge.hh"
+#include "G4SimpleHeum.hh"
+#include "G4ClassicalRK4.hh"
+#include "G4ConstRK4.hh"
+
+DECLARE_GEANT4_STEPPER(ImplicitEuler);
+DECLARE_GEANT4_STEPPER(ExplicitEuler);
+DECLARE_GEANT4_STEPPER(SimpleRunge);
+DECLARE_GEANT4_STEPPER(SimpleHeum);
+DECLARE_GEANT4_MAGSTEPPER(ConstRK4);
+DECLARE_GEANT4_STEPPER(ClassicalRK4);
+
+
+// Geant 4 include files
+#include "G4HelixExplicitEuler.hh"
+#include "G4HelixImplicitEuler.hh"
+#include "G4HelixMixedStepper.hh"
+#include "G4HelixSimpleRunge.hh"
+#include "G4HelixHeum.hh"
+
+DECLARE_GEANT4_MAGSTEPPER(HelixImplicitEuler);
+DECLARE_GEANT4_MAGSTEPPER(HelixExplicitEuler);
+DECLARE_GEANT4_MAGSTEPPER(HelixMixedStepper);
+DECLARE_GEANT4_MAGSTEPPER(HelixSimpleRunge);
+DECLARE_GEANT4_MAGSTEPPER(HelixHeum);
+
+
+// Geant 4 include files
+#include "G4Mag_EqRhs.hh"
+#include "G4Mag_SpinEqRhs.hh"
+#include "G4Mag_UsualEqRhs.hh"
+#include "G4KM_OpticalEqRhs.hh"
+#include "G4KM_NucleonEqRhs.hh"
+//Virtual: DECLARE_GEANT4_MAGMOTION(Mag_EqRhs);
+DECLARE_GEANT4_MAGMOTION(Mag_SpinEqRhs);
+DECLARE_GEANT4_MAGMOTION(Mag_UsualEqRhs);
+//DECLARE_GEANT4_MAGMOTION(KM_OpticalEqRhs);
+//DECLARE_GEANT4_MAGMOTION(KM_NucleonEqRhs);
diff --git a/DDG4/src/Geant4TrackerSD.cpp b/DDG4/src/Geant4TrackerSD.cpp
index 860228dfd..9270eb068 100644
--- a/DDG4/src/Geant4TrackerSD.cpp
+++ b/DDG4/src/Geant4TrackerSD.cpp
@@ -37,7 +37,7 @@ namespace DD4hep {  namespace Simulation {
     hit->position = position;
     hit->momentum = direction;
     hit->length   = hit_len;
-    if ( hit ) collection(0)->insert(hit);
+    collection(0)->insert(hit);
     return hit != 0;
   }
   typedef Geant4GenericSD<Tracker> Geant4Tracker;
diff --git a/DDG4/src/Geant4XML.cpp b/DDG4/src/Geant4XML.cpp
new file mode 100644
index 000000000..44d3cc17b
--- /dev/null
+++ b/DDG4/src/Geant4XML.cpp
@@ -0,0 +1,41 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#include "XML/Conversions.h"
+#include "DD4hep/DetFactoryHelper.h"
+
+namespace DD4hep {
+  struct Geant4;
+  namespace Geometry {
+    struct GdmlFile;
+    struct Property;
+    struct SensitiveDetector;
+  }
+}
+using namespace DD4hep;
+using namespace DD4hep::Geometry;
+
+namespace DD4hep {
+  template <> void Converter<Geant4>::operator()(const xml_h& e)  const;
+  template <> void Converter<Geometry::GdmlFile>::operator()(const xml_h& e)  const;
+  template <> void Converter<Geometry::Property>::operator()(const xml_h& e)  const;
+  template <> void Converter<Geometry::SensitiveDetector>::operator()(const xml_h& e)  const;
+}
+
+template <> void Converter<Geant4>::operator()(const xml_h& element)  const  {
+  xml_elt_t compact(element);
+  //xml_coll_t(compact,_X(includes) ).for_each(_X(gdmlFile), Converter<Geometry::GdmlFile>(lcdd,param));
+  xml_coll_t(compact,_X(properties) ).for_each(_X(attributes),Converter<Geometry::Property>(lcdd,param));
+  xml_coll_t(compact,_X(sensitive_detectors)).for_each(_X(sd),Converter<Geometry::SensitiveDetector>(lcdd,param));
+}
+
+static long create_Geant4(lcdd_t& lcdd, const xml_h& element) {
+  (Converter<Geant4>(lcdd))(element);
+  return 1;
+}
+DECLARE_XML_DOC_READER(geant4,create_Geant4);
-- 
GitLab