From 4c7912acea30515246b7704a9af447e76e92fb06 Mon Sep 17 00:00:00 2001
From: Noemi Calace <noemi.calace@cern.ch>
Date: Fri, 21 Oct 2016 14:41:38 +0200
Subject: [PATCH] fixing requirements (TrkG4UserActions-02-00-03-03)

	* fixing requirements
	* tagging TrkG4UserActions-02-00-03-03

2016-10-04  Peter Kluit
        * update the components to include the GeantFollower(MS)(Tool)
        * fix bug in GeantFollower.h and GeantFollowerMS.h
        * update share/joboptions to run with V2 UserActions
        * fix crash GeantFollowerMSHelper.cxx
        * tagging TrkG4UserActions-02-00-03-02

2016-10-04  John Chapman  <John.Chapman@cern.ch>

	* forward-porting V2 UserAction implmementations from the
	TrkG4UserActions-01-00-00-branch. Initially into a branch for
	testing.
	* tagging TrkG4UserActions-02-00-03-01

2016-08-08  John Chapman  <John.Chapman@cern.ch>

	* src/GeantFollowerMSHelper.cxx (trackParticle): fix for Coverity
...
(Long ChangeLog diff - truncated)


Former-commit-id: 88aa10c4eeef58a44872f60e006ff21f09a0bbbe
---
 .../TrkG4UserActions/CMakeLists.txt           |   5 +-
 .../TrkG4UserActions/EnergyLossRecorder.h     |  35 +++
 .../TrkG4UserActions/EnergyLossRecorderTool.h |  67 +++++
 .../TrkG4UserActions/GeantFollower.h          |  66 ++++-
 .../TrkG4UserActions/GeantFollowerMS.h        |  38 +++
 .../TrkG4UserActions/GeantFollowerMSTool.h    |  53 ++++
 .../TrkG4UserActions/GeantFollowerTool.h      |  53 ++++
 .../TrkG4UserActions/MaterialStepRecorder.h   |  48 ++++
 .../MaterialStepRecorderTool.h                |  52 ++++
 .../TrkG4UserActions/cmt/requirements         |   3 +-
 .../python/TrkG4UserActionsConfig.py          |  36 ---
 .../python/TrkG4UserActionsConfigDb.py        |   9 -
 .../share/GeantFollowingMS_jobOptions.py      |  78 +++--
 .../share/GeantFollowing_jobOptions.py        | 267 ++++++++++++------
 .../src/EnergyLossRecorder.cxx                | 103 ++++++-
 .../src/EnergyLossRecorderTool.cxx            |  62 ++++
 .../TrkG4UserActions/src/GeantFollower.cxx    | 104 ++++++-
 .../src/GeantFollowerHelper.cxx               |  10 +-
 .../TrkG4UserActions/src/GeantFollowerMS.cxx  |  94 +++++-
 .../src/GeantFollowerMSHelper.cxx             | 126 +++++++--
 .../src/GeantFollowerMSTool.cxx               |  48 ++++
 .../src/GeantFollowerTool.cxx                 |  47 +++
 .../src/MaterialStepRecorder.cxx              | 201 +++++++++++++
 .../src/MaterialStepRecorderTool.cxx          |  43 +++
 .../components/TrkG4UserActions_entries.cxx   |  29 +-
 25 files changed, 1444 insertions(+), 233 deletions(-)
 create mode 100644 Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/EnergyLossRecorderTool.h
 create mode 100644 Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerMSTool.h
 create mode 100644 Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerTool.h
 create mode 100644 Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/MaterialStepRecorderTool.h
 create mode 100644 Tracking/TrkG4Components/TrkG4UserActions/src/EnergyLossRecorderTool.cxx
 create mode 100644 Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMSTool.cxx
 create mode 100644 Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerTool.cxx
 create mode 100644 Tracking/TrkG4Components/TrkG4UserActions/src/MaterialStepRecorderTool.cxx

diff --git a/Tracking/TrkG4Components/TrkG4UserActions/CMakeLists.txt b/Tracking/TrkG4Components/TrkG4UserActions/CMakeLists.txt
index 6c184e6d507..8e41e64f8f3 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/CMakeLists.txt
+++ b/Tracking/TrkG4Components/TrkG4UserActions/CMakeLists.txt
@@ -8,7 +8,9 @@ atlas_subdir( TrkG4UserActions )
 # Declare the package's dependencies:
 atlas_depends_on_subdirs( PUBLIC
                           Control/AthenaBaseComps
+                          Control/StoreGate
                           GaudiKernel
+                          Simulation/G4Atlas/G4AtlasInterfaces
                           Simulation/G4Atlas/G4AtlasTools
                           Tracking/TrkDetDescr/TrkDetDescrInterfaces
                           Tracking/TrkDetDescr/TrkGeometry
@@ -16,7 +18,6 @@ atlas_depends_on_subdirs( PUBLIC
                           Tracking/TrkEvent/TrkParameters
                           PRIVATE
                           Control/CxxUtils
-                          Control/StoreGate
                           DetectorDescription/GeoPrimitives
                           Simulation/G4Sim/SimHelpers
                           Tracking/TrkDetDescr/TrkSurfaces
@@ -36,7 +37,7 @@ atlas_add_component( TrkG4UserActions
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} AthenaBaseComps GaudiKernel G4AtlasToolsLib TrkDetDescrInterfaces TrkGeometry TrkMaterialOnTrack TrkParameters CxxUtils StoreGateLib SGtests GeoPrimitives SimHelpers TrkSurfaces TrkExInterfaces TrkExUtils TrkValInterfaces )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${XERCESC_LIBRARIES} ${GEANT4_LIBRARIES} ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} AthenaBaseComps GaudiKernel G4AtlasInterfaces G4AtlasToolsLib TrkDetDescrInterfaces TrkGeometry TrkMaterialOnTrack TrkParameters CxxUtils StoreGateLib SGtests GeoPrimitives SimHelpers TrkSurfaces TrkExInterfaces TrkExUtils TrkValInterfaces )
 
 # Install files from the package:
 atlas_install_headers( TrkG4UserActions )
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/EnergyLossRecorder.h b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/EnergyLossRecorder.h
index c6547c12446..3b47acd01a3 100755
--- a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/EnergyLossRecorder.h
+++ b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/EnergyLossRecorder.h
@@ -51,4 +51,39 @@ class EnergyLossRecorder final: public UserActionBase {
   unsigned int                             m_entries;
 };
 
+
+#include "G4AtlasInterfaces/IBeginRunAction.h"
+#include "G4AtlasInterfaces/IEndRunAction.h"
+#include "G4AtlasInterfaces/IBeginEventAction.h"
+#include "G4AtlasInterfaces/IEndEventAction.h"
+#include "G4AtlasInterfaces/ISteppingAction.h"
+#include "AthenaBaseComps/AthMessaging.h"
+namespace G4UA{
+  
+  class EnergyLossRecorder:
+  public AthMessaging, public IBeginRunAction,  public IEndRunAction,  public IBeginEventAction,  public IEndEventAction,  public ISteppingAction
+  {
+    
+  public:
+    
+    struct Config
+    {
+      Trk::IPositionMomentumWriter *pmWriter=nullptr;
+    };
+    
+    EnergyLossRecorder(const Config& config);
+    virtual void beginOfRun(const G4Run*) override;
+    virtual void endOfRun(const G4Run*) override;
+    virtual void beginOfEvent(const G4Event*) override;
+    virtual void endOfEvent(const G4Event*) override;
+    virtual void processStep(const G4Step*) override;
+  private:
+    Config m_config;
+    unsigned int                             m_entries;
+  }; // class EnergyLossRecorder
+  
+  
+} // namespace G4UA 
+
+
 #endif
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/EnergyLossRecorderTool.h b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/EnergyLossRecorderTool.h
new file mode 100644
index 00000000000..d8dddc3f7e3
--- /dev/null
+++ b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/EnergyLossRecorderTool.h
@@ -0,0 +1,67 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRKG4USERACTIONS_G4UA__ENERGYLOSSRECORDERTOOL_H 
+#define TRKG4USERACTIONS_G4UA__ENERGYLOSSRECORDERTOOL_H 
+#include "G4AtlasInterfaces/IBeginRunActionTool.h"
+#include "G4AtlasInterfaces/IEndRunActionTool.h"
+#include "G4AtlasInterfaces/IBeginEventActionTool.h"
+#include "G4AtlasInterfaces/IEndEventActionTool.h"
+#include "G4AtlasInterfaces/ISteppingActionTool.h"
+#include "G4AtlasTools/ActionToolBase.h"
+#include "TrkG4UserActions/EnergyLossRecorder.h"
+namespace Trk {
+  class IPositionMomentumWriter;
+}
+
+namespace G4UA{ 
+
+
+  /// @class EnergyLossRecorderTool
+  /// @brief A class to manage EnergyLossRecorder actions
+  ///
+  /// creates one instance of the action per thread
+  ///
+  /// @author Andrea Di Simone
+
+  class EnergyLossRecorderTool: 
+
+  public ActionToolBase<EnergyLossRecorder>,
+    public IBeginRunActionTool,  public IEndRunActionTool,  public IBeginEventActionTool,  public IEndEventActionTool,  public ISteppingActionTool
+  {
+    
+  public:
+    /// standard tool ctor
+    EnergyLossRecorderTool(const std::string& type, const std::string& name,const IInterface* parent);
+    /// Athena initialize method
+    virtual StatusCode initialize() override final;
+    /// gets the BoR action
+    virtual IBeginRunAction* getBeginRunAction() override final 
+    { return static_cast<IBeginRunAction*>( getAction() ); }
+    /// gets the EoR action
+    virtual IEndRunAction* getEndRunAction() override final 
+    { return static_cast<IEndRunAction*>( getAction() ); }
+    /// gets the BoE action
+    virtual IBeginEventAction* getBeginEventAction() override final 
+    { return static_cast<IBeginEventAction*>( getAction() ); }
+    /// gets the EoE action
+    virtual IEndEventAction* getEndEventAction() override final 
+    { return static_cast<IEndEventAction*>( getAction() ); }
+    /// gets the stepping action
+    virtual ISteppingAction* getSteppingAction() override final 
+    { return static_cast<ISteppingAction*>( getAction() ); }
+    /// Gaudi interface manipulation
+    virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface) override;
+  protected:
+    /// creates the instance for this thread
+    virtual std::unique_ptr<EnergyLossRecorder> makeAction() override final;
+  private:
+    /// stores the config obtained from the python side
+    EnergyLossRecorder::Config m_config;
+    ToolHandle<Trk::IPositionMomentumWriter> m_pmWriter;
+  }; // class EnergyLossRecorderTool
+
+
+} // namespace G4UA 
+#endif
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollower.h b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollower.h
index 44f2e5ecab6..1ddcefa2ada 100755
--- a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollower.h
+++ b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollower.h
@@ -11,6 +11,7 @@
 
 #include "G4AtlasTools/UserActionBase.h"
 #include "GaudiKernel/ToolHandle.h"
+#include "TrkG4UserActions/IGeantFollowerHelper.h"
 #include <string>
 #include <vector>
 
@@ -20,30 +21,67 @@
 */
 
 namespace Trk {
-  class IGeantFollowerHelper;
+    class IGeantFollowerHelper;
 }
 
 class StoreGateSvc;
 
 class GeantFollower final: public UserActionBase {
 
- public:
-  /** Standard UserAction Constructor*/
-  GeantFollower(const std::string& type, const std::string& name, const IInterface* parent);
+  public:
+    /** Standard UsesAction */
+    GeantFollower(const std::string& type, const std::string& name, const IInterface* parent);
 
-  /** All G4 interface methods */
-  virtual void BeginOfEvent(const G4Event*) override;
-  virtual void EndOfEvent(const G4Event*) override;
-  virtual void Step(const G4Step*) override;
+    /** All G4 interface methods */
+    virtual void BeginOfEvent(const G4Event*) override;
+    virtual void EndOfEvent(const G4Event*) override;
+    virtual void Step(const G4Step*) override;
 
-  virtual StatusCode queryInterface(const InterfaceID&, void**) override;
-  virtual StatusCode initialize() override;
-
- private:
-  ToolHandle<Trk::IGeantFollowerHelper>     m_helper;
-  mutable const Trk::IGeantFollowerHelper*  m_helperPointer;
+    virtual StatusCode queryInterface(const InterfaceID&, void**) override;
+    virtual StatusCode initialize() override;
 
+  private:
+    std::string                                  m_name;
+    ToolHandle<Trk::IGeantFollowerHelper>     m_helper;
+    mutable const Trk::IGeantFollowerHelper*  m_helperPointer;
+    
 
 };
 
+
+#include "G4AtlasInterfaces/IBeginEventAction.h"
+#include "G4AtlasInterfaces/IEndEventAction.h"
+#include "G4AtlasInterfaces/IBeginRunAction.h"
+#include "G4AtlasInterfaces/ISteppingAction.h"
+#include "AthenaBaseComps/AthMessaging.h"
+namespace G4UA{
+
+
+  class GeantFollower:
+  public AthMessaging, public IBeginEventAction,  public IEndEventAction,  public IBeginRunAction,  public ISteppingAction
+  {
+    
+  public:
+    
+    struct Config
+    {
+      ToolHandle<Trk::IGeantFollowerHelper>  helper=ToolHandle<Trk::IGeantFollowerHelper>("Trk::GeantFollowerHelper/GeantFollowerHelper");
+    };
+    
+    GeantFollower(const Config& config);
+    virtual void beginOfEvent(const G4Event*) override;
+    virtual void endOfEvent(const G4Event*) override;
+    virtual void beginOfRun(const G4Run*) override;
+    virtual void processStep(const G4Step*) override;
+  private:
+    Config m_config;
+    std::string                                  m_name;
+    mutable const Trk::IGeantFollowerHelper*  m_helperPointer;
+
+  }; // class GeantFollower
+  
+  
+} // namespace G4UA 
+
 #endif
+
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerMS.h b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerMS.h
index 9e108955621..23cd6dc00eb 100755
--- a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerMS.h
+++ b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerMS.h
@@ -55,4 +55,42 @@ private:
 
 };
 
+
+#include "G4AtlasInterfaces/IBeginEventAction.h"
+#include "G4AtlasInterfaces/IEndEventAction.h"
+#include "G4AtlasInterfaces/IBeginRunAction.h"
+#include "G4AtlasInterfaces/ISteppingAction.h"
+#include "AthenaBaseComps/AthMessaging.h"
+namespace G4UA{
+
+
+  class GeantFollowerMS:
+  public AthMessaging, public IBeginEventAction,  public IEndEventAction,  public IBeginRunAction,  public ISteppingAction
+  {
+    
+  public:
+    
+    struct Config
+    {
+      ToolHandle<Trk::IGeantFollowerMSHelper>  helper=ToolHandle<Trk::IGeantFollowerMSHelper>("Trk::GeantFollowerMSHelper/GeantFollowerMSHelper");
+      ServiceHandle<Trk::ITrackingGeometrySvc> trackingGeometrySvc=ServiceHandle<Trk::ITrackingGeometrySvc>("AtlasTrackingGeometrySvc","GeantFollowerMS");
+    };
+    
+    GeantFollowerMS(const Config& config);
+    virtual void beginOfEvent(const G4Event*) override;
+    virtual void endOfEvent(const G4Event*) override;
+    virtual void beginOfRun(const G4Run*) override;
+    virtual void processStep(const G4Step*) override;
+  private:
+    Config m_config;
+    std::string                                  m_name;
+    /** tracking geometry */
+    mutable const Trk::TrackingGeometry*         m_trackingGeometry;
+    mutable const Trk::IGeantFollowerMSHelper*   m_helperPointer;
+
+  }; // class GeantFollowerMS
+  
+  
+} // namespace G4UA 
+
 #endif
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerMSTool.h b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerMSTool.h
new file mode 100644
index 00000000000..e1324c761cd
--- /dev/null
+++ b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerMSTool.h
@@ -0,0 +1,53 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRKG4USERACTIONS_G4UA__GEANTFOLLOWERMSTOOL_H
+#define TRKG4USERACTIONS_G4UA__GEANTFOLLOWERMSTOOL_H
+#include "G4AtlasInterfaces/IBeginEventActionTool.h"
+#include "G4AtlasInterfaces/IEndEventActionTool.h"
+#include "G4AtlasInterfaces/IBeginRunActionTool.h"
+#include "G4AtlasInterfaces/ISteppingActionTool.h"
+#include "G4AtlasTools/ActionToolBase.h"
+#include "TrkG4UserActions/GeantFollowerMS.h"
+
+namespace G4UA{
+
+  /// @class AthenaStackingActionTool
+  /// @brief Tool which manages the GeantFollowerMS action
+  ///
+  /// @author Andrea Di Simone
+  ///
+
+  class GeantFollowerMSTool:
+    public ActionToolBase<GeantFollowerMS>,
+    public IBeginEventActionTool,  public IEndEventActionTool,  public IBeginRunActionTool,  public ISteppingActionTool
+  {
+
+  public:
+    /// Standard constructor
+    GeantFollowerMSTool(const std::string& type, const std::string& name,const IInterface* parent);
+    /// Retrieve the BoE action
+    virtual IBeginEventAction* getBeginEventAction() override final
+    { return static_cast<IBeginEventAction*>( getAction() ); }
+    /// Retrieve the EoE action
+    virtual IEndEventAction* getEndEventAction() override final
+    { return static_cast<IEndEventAction*>( getAction() ); }
+    /// Retrieve the BoR action
+    virtual IBeginRunAction* getBeginRunAction() override final
+    { return static_cast<IBeginRunAction*>( getAction() ); }
+    /// Retrieve the stepping action
+    virtual ISteppingAction* getSteppingAction() override final
+    { return static_cast<ISteppingAction*>( getAction() ); }
+    virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface) override;
+  protected:
+    /// Create an action for this thread
+    virtual std::unique_ptr<GeantFollowerMS> makeAction() override final;
+  private:
+    /// Configuration parameters
+    GeantFollowerMS::Config m_config;
+  }; // class GeantFollowerMSTool
+
+
+} // namespace G4UA
+#endif
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerTool.h b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerTool.h
new file mode 100644
index 00000000000..c2bae8627b8
--- /dev/null
+++ b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/GeantFollowerTool.h
@@ -0,0 +1,53 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRKG4USERACTIONS_G4UA__GEANTFOLLOWERTOOL_H 
+#define TRKG4USERACTIONS_G4UA__GEANTFOLLOWERTOOL_H 
+#include "G4AtlasInterfaces/IBeginEventActionTool.h"
+#include "G4AtlasInterfaces/IEndEventActionTool.h"
+#include "G4AtlasInterfaces/IBeginRunActionTool.h"
+#include "G4AtlasInterfaces/ISteppingActionTool.h"
+#include "G4AtlasTools/ActionToolBase.h"
+#include "TrkG4UserActions/GeantFollower.h"
+
+namespace G4UA{ 
+
+  /// @class AthenaStackingActionTool
+  /// @brief Tool which manages the GeantFollower action
+  ///
+  /// @author Andrea Di Simone
+  ///
+  
+  class GeantFollowerTool: 
+  public ActionToolBase<GeantFollower>,
+    public IBeginEventActionTool,  public IEndEventActionTool,  public IBeginRunActionTool,  public ISteppingActionTool
+  {
+    
+  public:
+    /// Standard constructor
+    GeantFollowerTool(const std::string& type, const std::string& name,const IInterface* parent);
+    /// Retrieve the BoE action
+    virtual IBeginEventAction* getBeginEventAction() override final 
+    { return static_cast<IBeginEventAction*>( getAction() ); }
+    /// Retrieve the EoE action
+    virtual IEndEventAction* getEndEventAction() override final 
+    { return static_cast<IEndEventAction*>( getAction() ); }
+    /// Retrieve the BoR action
+    virtual IBeginRunAction* getBeginRunAction() override final 
+    { return static_cast<IBeginRunAction*>( getAction() ); }
+    /// Retrieve the stepping action
+    virtual ISteppingAction* getSteppingAction() override final 
+    { return static_cast<ISteppingAction*>( getAction() ); }
+    virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface) override;
+  protected:
+    /// Create an action for this thread
+    virtual std::unique_ptr<GeantFollower> makeAction() override final;
+  private:
+    /// Configuration parameters
+    GeantFollower::Config m_config;
+  }; // class GeantFollowerTool
+  
+  
+} // namespace G4UA 
+#endif
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/MaterialStepRecorder.h b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/MaterialStepRecorder.h
index dfb47108b01..f3cb8543538 100755
--- a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/MaterialStepRecorder.h
+++ b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/MaterialStepRecorder.h
@@ -61,4 +61,52 @@ class MaterialStepRecorder final: public UserActionBase {
 
 };
 
+#include "G4AtlasInterfaces/IBeginEventAction.h"
+#include "G4AtlasInterfaces/IEndEventAction.h"
+#include "G4AtlasInterfaces/IBeginRunAction.h"
+#include "G4AtlasInterfaces/ISteppingAction.h"
+#include "AthenaBaseComps/AthMessaging.h"
+
+#include "StoreGate/StoreGateSvc.h"
+#include "GaudiKernel/ServiceHandle.h"
+namespace G4UA{
+
+
+  class MaterialStepRecorder:
+    public AthMessaging, public IBeginEventAction,  public IEndEventAction,  public IBeginRunAction,  public ISteppingAction
+  {
+
+  public:
+    MaterialStepRecorder();
+    virtual void beginOfEvent(const G4Event*) override;
+    virtual void endOfEvent(const G4Event*) override;
+    virtual void beginOfRun(const G4Run*) override;
+    virtual void processStep(const G4Step*) override;
+  private:
+
+    typedef ServiceHandle<StoreGateSvc> StoreGateSvc_t;
+    /// Pointer to StoreGate (event store by default)
+    mutable StoreGateSvc_t m_evtStore;
+    /// Pointer to StoreGate (detector store by default)
+    mutable StoreGateSvc_t m_detStore;
+
+    Trk::MaterialStepCollection*    m_matStepCollection; //FIXME convert to a WriteHandle
+    std::string                     m_matStepCollectionName;
+
+    bool                            m_recordComposition;
+
+    double                          m_totalNbOfAtoms;
+    size_t                          m_totalSteps;
+    size_t                          m_eventID;
+
+    Trk::ElementTable*              m_elementTable;  //FIXME convert to a WriteHandle
+    std::string                     m_elementTableName;
+
+    Trk::ElementTable*              m_runElementTable;
+
+  }; // class MaterialStepRecorder
+
+
+} // namespace G4UA
+
 #endif
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/MaterialStepRecorderTool.h b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/MaterialStepRecorderTool.h
new file mode 100644
index 00000000000..95fd060f83c
--- /dev/null
+++ b/Tracking/TrkG4Components/TrkG4UserActions/TrkG4UserActions/MaterialStepRecorderTool.h
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRKG4USERACTIONS_G4UA__MATERIALSTEPRECORDERTOOL_H 
+#define TRKG4USERACTIONS_G4UA__MATERIALSTEPRECORDERTOOL_H 
+
+#include "G4AtlasInterfaces/IBeginEventActionTool.h"
+#include "G4AtlasInterfaces/IEndEventActionTool.h"
+#include "G4AtlasInterfaces/IBeginRunActionTool.h"
+#include "G4AtlasInterfaces/ISteppingActionTool.h"
+#include "G4AtlasTools/ActionToolBase.h"
+#include "TrkG4UserActions/MaterialStepRecorder.h"
+
+namespace G4UA{ 
+  
+  /// @class MaterialStepRecorderTool
+  /// @brief Tool which manages the MaterialStepRecorder action
+  ///
+  /// @author Andrea Di Simone
+  ///
+
+  class MaterialStepRecorderTool: 
+  public ActionToolBase<MaterialStepRecorder>,
+    public IBeginEventActionTool,  public IEndEventActionTool,  public IBeginRunActionTool,  public ISteppingActionTool
+  {
+    
+  public:
+    /// Standard constructor
+    MaterialStepRecorderTool(const std::string& type, const std::string& name,const IInterface* parent);
+    /// Retrieve the BoE action
+    virtual IBeginEventAction* getBeginEventAction() override final 
+    { return static_cast<IBeginEventAction*>( getAction() ); }
+    /// Retrieve the EoE action
+    virtual IEndEventAction* getEndEventAction() override final 
+    { return static_cast<IEndEventAction*>( getAction() ); }
+    /// Retrieve the BoR action
+    virtual IBeginRunAction* getBeginRunAction() override final 
+    { return static_cast<IBeginRunAction*>( getAction() ); }
+    /// Retrieve the stepping action
+    virtual ISteppingAction* getSteppingAction() override final 
+    { return static_cast<ISteppingAction*>( getAction() ); }
+    virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface) override;
+  protected:
+    /// Create an action for this thread
+    virtual std::unique_ptr<MaterialStepRecorder> makeAction() override final;
+  private:
+  }; // class MaterialStepRecorderTool
+  
+  
+} // namespace G4UA 
+#endif
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/cmt/requirements b/Tracking/TrkG4Components/TrkG4UserActions/cmt/requirements
index cb212035a09..d402f8942bb 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/cmt/requirements
+++ b/Tracking/TrkG4Components/TrkG4UserActions/cmt/requirements
@@ -13,12 +13,13 @@ use TrkParameters               TrkParameters-*         Tracking/TrkEvent
 use Geant4                      Geant4-*                External
 use TrkDetDescrInterfaces       TrkDetDescrInterfaces-* Tracking/TrkDetDescr
 use TrkMaterialOnTrack          TrkMaterialOnTrack-*    Tracking/TrkEvent
+use StoreGate                   StoreGate-*             Control
+use G4AtlasInterfaces           G4AtlasInterfaces-*     Simulation/G4Atlas
 
 private
 use AtlasROOT                   AtlasROOT-*             External
 use AtlasCLHEP                  AtlasCLHEP-*            External
 use CxxUtils                    CxxUtils-*              Control
-use StoreGate                   StoreGate-*             Control
 use GeoPrimitives               GeoPrimitives-*         DetectorDescription
 use SimHelpers                  SimHelpers-*            Simulation/G4Sim
 use TrkSurfaces                 TrkSurfaces-*           Tracking/TrkDetDescr
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/python/TrkG4UserActionsConfig.py b/Tracking/TrkG4Components/TrkG4UserActions/python/TrkG4UserActionsConfig.py
index 14ef617f5b9..9857b10511c 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/python/TrkG4UserActionsConfig.py
+++ b/Tracking/TrkG4Components/TrkG4UserActions/python/TrkG4UserActionsConfig.py
@@ -8,39 +8,3 @@ def getMaterialStepRecorderTool(name="G4UA::MaterialStepRecorderTool", **kwargs)
             kwargs.setdefault(prop,value)
     from TrkG4UserActions.TrkG4UserActionsConf import G4UA__MaterialStepRecorderTool
     return G4UA__MaterialStepRecorderTool(name, **kwargs)
-from AthenaCommon import CfgMgr
-
-#-------------------------------------------------------------------
-def getMaterialStepRecorder(name="MaterialStepRecorder", **kwargs):
-    return CfgMgr.MaterialStepRecorder(name, **kwargs)
-#-------------------------------------------------------------------
-def getPositionMomentumWriter(name="PosMomWriter", **kwargs):
-    return CfgMgr.Trk__PositionMomentumWriter(name, **kwargs)
-
-def getEnergyLossRecorder(name="EnergyLossRecorder", **kwargs):
-    kwargs.setdefault("PositionMomentumWriter", "PosMomWriter")
-    return CfgMgr.EnergyLossRecorder(name, **kwargs)
-#-------------------------------------------------------------------
-def getGeantFollowerHelper(name="GeantFollowerHelper", **kwargs):
-    from AthenaCommon.AppMgr import ToolSvc
-    kwargs.setdefault("Extrapolator", ToolSvc.TestExtrapolator) ##FIXME Assumes that this already exists..
-    kwargs.setdefault("ExtrapolateDirectly", True)
-    kwargs.setdefault("ExtrapolateIncrementally", True)
-    return CfgMgr.Trk__GeantFollowerHelper(name, **kwargs)
-
-def getGeantFollower(name="GeantFollower", **kwargs):
-    return CfgMgrGeantFollower.(name, **kwargs)
-#-------------------------------------------------------------------
-def getGeantFollowerMSHelper(name="GeantFollowerMSHelper", **kwargs):
-    from AthenaCommon.AppMgr import ToolSvc
-    kwargs.setdefault("Extrapolator", ToolSvc.TestExtrapolator) ##FIXME Assumes that this already exists..
-    kwargs.setdefault("ExtrapolateDirectly", False) # for geantinos ExtrapolateDirectly = True no Eloss is calculated
-    kwargs.setdefault("ExtrapolateIncrementally", False)
-    # SpeedUp False takes more CPU because it will stop at each G4 Step in the Muon Spectrometer
-    kwargs.setdefault("SpeedUp", True)
-    return CfgMgr.Trk__GeantFollowerMSHelper(name, **kwargs)
-
-def getGeantFollowerMS(name="GeantFollowerMS", **kwargs):
-    kwargs.setdefault("HelperTool", "GeantFollowerMSHelper")
-    return CfgMgr.GeantFollowerMS(name, **kwargs)
-#-------------------------------------------------------------------
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/python/TrkG4UserActionsConfigDb.py b/Tracking/TrkG4Components/TrkG4UserActions/python/TrkG4UserActionsConfigDb.py
index e43dc118bf3..7f7be15fc4b 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/python/TrkG4UserActionsConfigDb.py
+++ b/Tracking/TrkG4Components/TrkG4UserActions/python/TrkG4UserActionsConfigDb.py
@@ -3,12 +3,3 @@
 from AthenaCommon.CfgGetter import addTool
 addTool("TrkG4UserActions.TrkG4UserActionsConfig.getMaterialStepRecorderTool", "G4UA::MaterialStepRecorderTool")
 
-from AthenaCommon.CfgGetter import addTool
-addTool("TrkG4UserActions.TrkG4UserActionsConfig.getMaterialStepRecorder",  "MaterialStepRecorder"  )
-addTool("TrkG4UserActions.TrkG4UserActionsConfig.getPositionMomentumWriter","PosMomWriter"          )
-addTool("TrkG4UserActions.TrkG4UserActionsConfig.getEnergyLossRecorder"  ,  "EnergyLossRecorder"    )
-addTool("TrkG4UserActions.TrkG4UserActionsConfig.getGeantFollowerHelper",   "GeantFollowerHelper"   )
-addTool("TrkG4UserActions.TrkG4UserActionsConfig.getGeantFollower"       ,  "GeantFollower"         )
-addTool("TrkG4UserActions.TrkG4UserActionsConfig.getGeantFollowerMSHelper", "GeantFollowerMSHelper" )
-addTool("TrkG4UserActions.TrkG4UserActionsConfig.getGeantFollowerMS"     ,  "GeantFollowerMS"       )
-
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/share/GeantFollowingMS_jobOptions.py b/Tracking/TrkG4Components/TrkG4UserActions/share/GeantFollowingMS_jobOptions.py
index aa9114e3427..4ec549d621d 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/share/GeantFollowingMS_jobOptions.py
+++ b/Tracking/TrkG4Components/TrkG4UserActions/share/GeantFollowingMS_jobOptions.py
@@ -1,11 +1,10 @@
-#==============================================================
+#=============================================================
 #
 #
 #		This job option runs the G4 simulation
-#		of the ATLAS detector and the GeantinoMapping.
+#		of the ATLAS detector and the GeantFollower in the Muon Spectrometer 
 #		It can be run using athena.py
 #
-__version__="$Revision: 729147 $"
 #==============================================================
 
 
@@ -31,6 +30,7 @@ from AthenaCommon.GlobalFlags import globalflags
 #from G4AtlasApps import AtlasG4Eng
 #AtlasG4Eng.G4Eng._ctrl.fldMenu.UseStepper('NystromRK4')
 
+
 #--- Include JobSpecs.py --------------------------------------
 #include ('JobSpecs.py')
 
@@ -62,8 +62,11 @@ if 'myPt' not in dir() :
     myPt = 'p'  # values are 'p' or 'pt'
 
 if 'myGeo' not in dir() :
+# release 20
+    myGeo = 'ATLAS-R2-2015-03-01-00'
 #   this is release 19 like
-    myGeo = 'ATLAS-GEO-20-00-01'
+#     myGeo = 'ATLAS-R1-2012-02-00-00'
+#    myGeo = 'ATLAS-GEO-20-00-01'
 #   this is release 17 from Jochen
 #    myGeo = 'ATLAS-GEO-18-01-03'
 #    myGeo = 'ATLAS-GEO-18-01-00'
@@ -121,39 +124,34 @@ athenaCommonFlags.PoolEvgenInput.set_Off()   ### is this necessary?
 athenaCommonFlags.PoolHitsOutput.set_Off()
 athenaCommonFlags.EvtMax =  myMaxEvent
 
+
+#from AthenaCommon.AppMgr import AppMgr
+#AppMgr.EvtMax =  myMaxEvent
+
 #--- Simulation flags -----------------------------------------
 from G4AtlasApps.SimFlags import SimFlags
 SimFlags.load_atlas_flags() # Going to use an ATLAS layout
+SimFlags.SimLayout.set_On()
 SimFlags.SimLayout = myGeo
 SimFlags.EventFilter.set_Off()
+SimFlags.RunNumber = 222510
 
 include("GeneratorUtils/StdEvgenSetup.py")
 
-myMinEta =  0.2
-#myMinEta =  0.0
+myMinEta =  0.
 myMaxEta =  1.0
-
-#myMinEta =  0.8
-#myMaxEta =  1.8
-
-#myMinEta =  1.8
+myMinEta =  1.0
+myMaxEta =  1.8
+myMinEta =  1.8
 myMaxEta =  2.8
 
-#myMinEta =  0.2
-#myMaxEta =  2.8
-
-
-#myMinEta =  2.0
-#myMaxEta =  2.8
-#myMinEta =  0.8
-#myMaxEta =  2.0
-#myMinEta =  0.2
-#myMaxEta =  0.8
-
 myPDG = 13  # 998 = Charged Geantino 999 = neutral Geantino, 13 = Muon
 
 #myPDG = 998
 
+#from AthenaCommon.CfgGetter import getAlgorithm
+#topSeq += getAlgorithm("BeamEffectsAlg", tryDefaultConfigurable=True)
+
 # sept 2014 run ParticleGun
 import ParticleGun as PG
 pg = PG.ParticleGun(randomSvcName=SimFlags.RandomSvc.get_Value(), randomStream="SINGLE")
@@ -188,6 +186,7 @@ from AthenaCommon.AppMgr import ToolSvc
 
 from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
 from TrkDetDescrSvc.AtlasTrackingGeometrySvc import AtlasTrackingGeometrySvc
+
 #ToolSvc.AtlasGeometryBuilder.OutputLevel = VERBOSE
 #ToolSvc.CaloTrackingGeometryBuilder.OutputLevel = DEBUG
 #ToolSvc.MuonTrackingGeometryBuilder.OutputLevel = DEBUG
@@ -197,6 +196,7 @@ from TrkDetDescrSvc.AtlasTrackingGeometrySvc import AtlasTrackingGeometrySvc
 
 #DetFlags.simulate.Truth_setOn()   ### deprecated!
 
+ 
 
 #--------------------------------------------------------------
 # Assign the TrackingGeometry to the Algorithm
@@ -312,6 +312,26 @@ TestExtrapolator = Trk__Extrapolator('TestExtrapolator',\
                            SubMEUpdators = TestSubUpdators)
 ToolSvc += TestExtrapolator
 
+
+# Helper setup
+# for geantinos ExtrapolateDirectly = True no Eloss is calculated
+# SpeedUp False takes more CPU because it will stop at each G4 Step in the Muon Spectrometer
+
+from TrkG4UserActions.TrkG4UserActionsConf import Trk__GeantFollowerMSHelper
+GeantFollowerMSHelper = Trk__GeantFollowerMSHelper(name="GeantFollowerMSHelper")
+GeantFollowerMSHelper.Extrapolator             = TestExtrapolator
+GeantFollowerMSHelper.ExtrapolateDirectly      = False
+GeantFollowerMSHelper.ExtrapolateIncrementally = False
+GeantFollowerMSHelper.SpeedUp      = True
+GeantFollowerMSHelper.OutputLevel = INFO   
+ToolSvc += GeantFollowerMSHelper
+
+# higher precision for stepping
+SimFlags.TightMuonStepping=True
+
+SimFlags.UseV2UserActions = True
+SimFlags.OptionalUserActionList.addAction('G4UA::GeantFollowerMSTool',['Step','BeginOfEvent','EndOfEvent','BeginOfRun'])
+
 ############### The output collection #######################
 
 from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
@@ -329,14 +349,22 @@ ServiceMgr.THistSvc.Output += [ "val DATAFILE='GeantFollowing.root' TYPE='ROOT'
 
 ##############################################################
 
+
+from AthenaCommon.CfgGetter import getAlgorithm
+topSeq += getAlgorithm("BeamEffectsAlg", tryDefaultConfigurable=True)
+
 ## Populate alg sequence
 from G4AtlasApps.PyG4Atlas import PyG4AtlasAlg
 topSeq += PyG4AtlasAlg()
 
 #ServiceMgr.AthenaOutputStream.StreamHITS.ItemList                  = ['EventInfo#*']
 
+from AthenaCommon.AppMgr import AppMgr
+AppMgr.EvtMax =  myMaxEvent
+
 ToolSvc.MuonTrackingGeometryBuilder.BlendInertMaterial = False
 TestSTEP_Propagator.Straggling = False
+#ToolSvc.CaloTrackingGeometryBuilder.OutputLevel = VERBOSE
 
 #TestExtrapolator.OutputLevel = VERBOSE
 
@@ -344,11 +372,7 @@ if myPDG == 998 :
   TestSTEP_Propagator.MultipleScattering = False
   TestSTEP_Propagator.EnergyLoss = False
 
-from AthenaCommon.CfgGetter import getPublicTool
-ServiceMgr.UserActionSvc.BeginOfEventActions += [getPublicTool("GeantFollowerMS")]
-ServiceMgr.UserActionSvc.EndOfEventActions += [getPublicTool("GeantFollowerMS")]
-ServiceMgr.UserActionSvc.SteppingActions += [getPublicTool("GeantFollowerMS")]
 
 from AthenaCommon.ConfigurationShelve import saveToAscii
 saveToAscii("config.txt")
-#--- End jobOptions.GeantinoMapping.py file  ------------------------------
+#--- End jobOptions GeantFollowingMS_jobOptions.py file  ------------------------------
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/share/GeantFollowing_jobOptions.py b/Tracking/TrkG4Components/TrkG4UserActions/share/GeantFollowing_jobOptions.py
index 285102e012a..769f6d83c5c 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/share/GeantFollowing_jobOptions.py
+++ b/Tracking/TrkG4Components/TrkG4UserActions/share/GeantFollowing_jobOptions.py
@@ -2,10 +2,9 @@
 #
 #
 #		This job option runs the G4 simulation
-#		of the ATLAS detector and the GeantinoMapping.
+#		of the ATLAS detector and the GeantFollower in ID (and MS)
 #		It can be run using athena.py
 #
-__version__="$Revision: 467755 $"
 #==============================================================
 
 
@@ -13,6 +12,11 @@ __version__="$Revision: 467755 $"
 from AthenaCommon.AlgSequence import AlgSequence
 topSeq = AlgSequence()
 
+#topSeq.ContinueEventloopOnFPE = True
+from RecExConfig.RecFlags import rec as rec
+rec.doFloatingPointException.set_Value_and_Lock(True)
+rec.doNameAuditor = True
+
 #--- Output threshold (DEBUG, INFO, WARNING, ERROR, FATAL) ----
 #from AthenaCommon.AppMgr import ServiceMgr
 ServiceMgr.MessageSvc.OutputLevel  = INFO
@@ -22,15 +26,22 @@ ServiceMgr.MessageSvc.defaultLimit = 20000
 from AthenaCommon.DetFlags import DetFlags
 from AthenaCommon.GlobalFlags import globalflags
 
-from G4AtlasApps import AtlasG4Eng
-AtlasG4Eng.G4Eng._ctrl.fldMenu.UseStepper('NystromRK4')
+# Code crashes on NystromRK4 stepper NOW take default
+#from G4AtlasApps import AtlasG4Eng
+#AtlasG4Eng.G4Eng._ctrl.fldMenu.UseStepper('NystromRK4')
+
 
 #--- Include JobSpecs.py --------------------------------------
 #include ('JobSpecs.py')
 
 ### pass arguments with athena -c "..." ...jobOptions.py:
 if 'myMomentum' not in dir() :
-    myMomentum = 5000
+    myMomentum = 25000
+#    myMomentum = 50000
+#    myMomentum = 100000
+#    myMomentum = 500000
+#    myMomentum = 10000
+#    myMomentum = 5000
 
 if 'myRandomOffset' not in dir() :
     myRandomOffset = 0
@@ -42,23 +53,45 @@ if 'myRandomSeed2' not in dir() :
     myRandomSeed2 = 820189
 
 if 'myMaxEvent' not in dir() :
-    myMaxEvent = 25
+    myMaxEvent = 500
+    myMaxEvent = 5000
+#    myMaxEvent = 1000
+    myMaxEvent = 100
 
 if 'myPt' not in dir() :
-    myPt = 'pt'  # values are 'p' or 'pt'
+    myPt = 'p'  # values are 'p' or 'pt'
 
 if 'myGeo' not in dir() :
-    myGeo = 'ATLAS-GEO-18-01-00'
-
+# release 20
+    myGeo = 'ATLAS-R2-2015-03-01-00'
+#   this is release 19 like
+#    myGeo = 'ATLAS-GEO-20-00-01'
+#   this is release 17 from Jochen
+#    myGeo = 'ATLAS-GEO-18-01-03'
+#    myGeo = 'ATLAS-GEO-18-01-00'
+#    myGEO = 'ATLAS-R1-2012-02-01-00'
 
 # Set everything to ATLAS
 DetFlags.ID_setOn()
 DetFlags.Calo_setOn()
 DetFlags.Muon_setOn()
+
 # the global flags
+
+# select latest Muon lay out on top of GEO-20
+from GeoModelSvc.GeoModelSvcConf import GeoModelSvc
+GeoModelSvc = GeoModelSvc()
+#GeoModelSvc.MuonVersionOverride="MuonSpectrometer-R.07.00"
+#GeoModelSvc.MuonVersionOverride="MuonSpectrometer-R.06.04"
+
+
+from IOVDbSvc.CondDB import conddb
+
 if myGeo.split('-')[1] == 'GEO' :
     if myGeo.split('-')[2] > 16 :
         globalflags.ConditionsTag = 'OFLCOND-SDR-BS7T-05-02'
+        globalflags.ConditionsTag = 'OFLCOND-MC12-SDR-06'
+#        conddb.setGlobalTag("OFLCOND-MC12-SDR-06")
     else :
         globalflags.ConditionsTag = 'OFLCOND-SDR-BS7T-04-15'
     print globalflags.ConditionsTag
@@ -66,7 +99,7 @@ elif myGeo.split('-')[1] == 'IBL' :
     globalflags.ConditionsTag = 'OFLCOND-SDR-BS14T-IBL-03'
 else :
     globalflags.ConditionsTag = 'OFLCOND-SDR-BS7T-05-02'
-
+#    globalflags.ConditionsTag = 'OFLCOND-SIM-00-00-00'
 print globalflags.ConditionsTag
 
 #from AthenaCommon import AthenaCommonFlags
@@ -77,7 +110,7 @@ print globalflags.ConditionsTag
 #from IOVDbSvc.CondDB import conddb
 #conddb.addOverride('/GLOBAL/BField/Map','BFieldMap-FullAsym-09')
 
-#DetFlags.simulate.Truth_setOn()   ### deprecated!
+
 DetFlags.Truth_setOn()
 
 # specify your "/tmp/<username>/" directory here (output files may be large!)
@@ -86,8 +119,9 @@ outPath = ""  #"/tmp/wlukas/"
 #--- AthenaCommon flags ---------------------------------------
 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
 athenaCommonFlags.PoolEvgenInput.set_Off()   ### is this necessary?
-athenaCommonFlags.PoolHitsOutput = outPath + 'Hits.pool.root'
-athenaCommonFlags.EvtMax = myMaxEvent
+###athenaCommonFlags.PoolHitsOutput = outPath + 'Hits.pool.root'
+athenaCommonFlags.PoolHitsOutput.set_Off()
+athenaCommonFlags.EvtMax =  myMaxEvent
 
 #--- Simulation flags -----------------------------------------
 from G4AtlasApps.SimFlags import SimFlags
@@ -95,102 +129,126 @@ SimFlags.load_atlas_flags() # Going to use an ATLAS layout
 SimFlags.SimLayout = myGeo
 SimFlags.EventFilter.set_Off()
 
-myMinEta =  0.0
-myMaxEta =  0.0
-
-myPDG    = 998  # 999 = Geantinos, 13 = Muons, 0 diferently charged geantino
-
-## Run ParticleGenerator
-import AthenaCommon.AtlasUnixGeneratorJob
-spgorders = [ 'pdgcode:' + ' constant ' + str(myPDG),
-              'vertX:'   + ' constant 0.0',
-              'vertY:'   + ' constant 0.0',
-              'vertZ:'   + ' constant 0.0',
-              't:'       + ' constant 0.0',
-              'eta:'     + ' flat ' + str(myMinEta) + ' ' + str(myMaxEta),
-              'phi:'     + ' flat  0 6.2831853',
-              myPt + ':' + ' constant ' + str(myMomentum) ]
-from ParticleGenerator.ParticleGeneratorConf import ParticleGenerator
-topSeq += ParticleGenerator()
-topSeq.ParticleGenerator.orders = sorted(spgorders)
+include("GeneratorUtils/StdEvgenSetup.py")
 
-SimFlags.RandomSeedOffset = myRandomOffset
+myMinEta =  0.2
+#myMinEta =  0.0
+myMaxEta =  1.0
 
-### new rel17 (check Simulation/G4Atlas/G4AtlasApps/python/SimFlags.py for details)
-# SimFlags.RandomSeedList.addSeed( "SINGLE", myRandomSeed1, myRandomSeed2 )
+#myMinEta =  0.8
+#myMaxEta =  1.8
 
-### alternative for earlier rel17/rel16
-from AthenaServices.AthenaServicesConf import AtRanluxGenSvc
-ServiceMgr += AtRanluxGenSvc()
-ServiceMgr.AtRanluxGenSvc.Seeds = [ "SINGLE " + str(myRandomSeed1) + ' ' + str(myRandomSeed2) ]
-### alternative to previous line
-#ServiceMgr.AtRanluxGenSvc.Seeds = [ "SINGLE OFFSET " + str(myRandomOffset) + ' ' + str(myRandomSeed1) + ' ' + str(myRandomSeed2) ]
+#myMinEta =  1.8
+myMaxEta =  2.8
 
-### alternative for old rel16 versions and before (?)
-#SeedString = "SINGLE " + str(myRandomSeed1) + ' ' + str(myRandomSeed2)
-#SimFlags.Seeds.set_Value(SeedString)
+#myMinEta =  0.2
+#myMaxEta =  2.8
 
-#AtlasG4Eng.G4Eng._ctrl.fldMenu.UseStepper('AtlasRK4')
+
+#myMinEta =  2.0
+#myMaxEta =  2.8
+#myMinEta =  0.8
+#myMaxEta =  2.0
+#myMinEta =  0.2
+#myMaxEta =  0.8
+
+myPDG = 13  # 998 = Charged Geantino 999 = neutral Geantino, 13 = Muon
+
+myPDG = 998
+
+#from AthenaCommon.CfgGetter import getAlgorithm
+#topSeq += getAlgorithm("BeamEffectsAlg", tryDefaultConfigurable=True)
+
+# sept 2014 run ParticleGun
+import ParticleGun as PG
+pg = PG.ParticleGun(randomSvcName=SimFlags.RandomSvc.get_Value(), randomStream="SINGLE")
+#pg.sampler.pid = PG.CyclicSeqSampler([-13,13])
+pg.sampler.pid = myPDG
+pg.sampler.mom = PG.EEtaMPhiSampler(energy=myMomentum, eta=[myMinEta,myMaxEta])
+#pg.sampler.mom = PG.PtEtaMPhiSampler(pt=myMomentum, eta=[myMinEta,myMaxEta])
+topSeq += pg
+
+SimFlags.RandomSeedOffset = myRandomOffset
+
+### new rel17 (check Simulation/G4Atlas/G4AtlasApps/python/SimFlags.py for details)
+SimFlags.RandomSeedList.addSeed( "SINGLE", myRandomSeed1, myRandomSeed2 )
+
+from RngComps.RngCompsConf import AtRndmGenSvc
+myAtRndmGenSvc = AtRndmGenSvc()
+myAtRndmGenSvc.Seeds = ["SINGLE "+str(myRandomSeed1)+" "+str(myRandomSeed2) ]
+#myAtRndmGenSvc.OutputLevel          = VERBOSE
+myAtRndmGenSvc.EventReseeding   = False
+ServiceMgr += myAtRndmGenSvc
 
 # suppress the enormous amount of MC output
-from TruthExamples.TruthExamplesConf import DumpMC
-DumpMC.VerboseOutput = False
+# from TruthExamples.TruthExamplesConf import PrintMC
+# PrintMC.VerboseOutput = False
 
 # ToolSvc setup
 from AthenaCommon.AppMgr import ToolSvc
 
-# Estrapolator setup
-include('TrkDetDescrSvc/AtlasTrackingGeometrySvc.py')
-from AthenaCommon.AppMgr import ServiceMgr as svcMgr
-AtlasTrackingGeometrySvc = svcMgr.AtlasTrackingGeometrySvc
+# Tracking Geometry
+# from AthenaCommon.CfgGetter import getService
+# getService("AtlasTrackingGeometrySvc")
+
+from TrkDetDescrSvc.TrkDetDescrJobProperties import TrkDetFlags
+from TrkDetDescrSvc.AtlasTrackingGeometrySvc import AtlasTrackingGeometrySvc
+
+#ToolSvc.AtlasGeometryBuilder.OutputLevel = VERBOSE
+#ToolSvc.CaloTrackingGeometryBuilder.OutputLevel = DEBUG
+#ToolSvc.MuonTrackingGeometryBuilder.OutputLevel = DEBUG
+#ToolSvc.InDetTrackingGeometryBuilder.OutputLevel = DEBUG
+
+#ServiceMgr.AtlasTrackingGeometrySvc.OutputLevel = VERBOSE
+
+#DetFlags.simulate.Truth_setOn()   ### deprecated!
+
 
 #--------------------------------------------------------------
 # Assign the TrackingGeometry to the Algorithm
 #--------------------------------------------------------------
 
 # the layer material inspector
-from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__LayerMaterialInspector
+from TrkDetDescrTestTools.TrkDetDescrTestToolsConf import Trk__LayerMaterialInspector
 LayerMaterialInspector = Trk__LayerMaterialInspector(name= 'LayerMaterialInspector')
 LayerMaterialInspector.OutputLevel = INFO
-from AthenaCommon.AppMgr import ToolSvc
 ToolSvc += LayerMaterialInspector
 
+
+
 # the tracking volume displayer
-from TrkDetDescrTools.TrkDetDescrToolsConf import Trk__TrackingVolumeDisplayer
+from TrkDetDescrTestTools.TrkDetDescrTestToolsConf import Trk__TrackingVolumeDisplayer
 TrackingVolumeDisplayer = Trk__TrackingVolumeDisplayer(name= 'TrackingVolumeDisplayer')
 TrackingVolumeDisplayer.TrackingVolumeOutputFile = 'TrackingVolumes-'+TrkDetFlags.MaterialMagicTag()+'.C'
 TrackingVolumeDisplayer.LayerOutputFile          = 'Layers-'+TrkDetFlags.MaterialMagicTag()+'.C'
 TrackingVolumeDisplayer.SurfaceOutputFile        = 'Surfaces-'+TrkDetFlags.MaterialMagicTag()+'.C'
 ToolSvc += TrackingVolumeDisplayer
 
-# set up the Geometry Builder test
-from TrkDetDescrAlgs.TrkDetDescrAlgsConf import Trk__GeometryBuilderTest
-GeometryBuilderTest = Trk__GeometryBuilderTest(name ='GeometryBuilderTest')
-GeometryBuilderTest.TrackingGeometrySvc     = AtlasTrackingGeometrySvc
-GeometryBuilderTest.DisplayTrackingVolumes  = False
-GeometryBuilderTest.RecordLayerMaterial     = False
-GeometryBuilderTest.LayerMaterialInspector  = LayerMaterialInspector
-GeometryBuilderTest.TrackingVolumeDisplayer = TrackingVolumeDisplayer
-GeometryBuilderTest.WriteNtuple             = False
-GeometryBuilderTest.OutputLevel             = INFO
-topSeq += GeometryBuilderTest
 
 # PROPAGATOR DEFAULTS --------------------------------------------------------------------------------------
 
-TestPorpagators  = []
+TestEnergyLossUpdator  = []
+from TrkExTools.TrkExToolsConf import Trk__EnergyLossUpdator
+AtlasEnergyLossUpdator = Trk__EnergyLossUpdator(name="AtlasEnergyLossUpdator")
+ToolSvc  += AtlasEnergyLossUpdator
+ToolSvc.AtlasEnergyLossUpdator.DetailedEloss = True
+TestEnergyLossUpdator  += [AtlasEnergyLossUpdator]
+
+
+TestPropagators  = []
 
 from TrkExRungeKuttaPropagator.TrkExRungeKuttaPropagatorConf import Trk__RungeKuttaPropagator as Propagator
-#from TrkExSTEP_Propagator.TrkExSTEP_PropagatorConf import Trk__STEP_Propagator as Propagator
 TestPropagator = Propagator(name = 'TestPropagator')
 ToolSvc += TestPropagator
 
-TestPorpagators += [ TestPropagator ]
+TestPropagators += [ TestPropagator ]
 
 from TrkExSTEP_Propagator.TrkExSTEP_PropagatorConf import Trk__STEP_Propagator as STEP_Propagator
 TestSTEP_Propagator = STEP_Propagator(name = 'TestSTEP_Propagator')
 ToolSvc += TestSTEP_Propagator
+TestSTEP_Propagator.DetailedEloss = True
 
-TestPorpagators += [TestSTEP_Propagator]
+TestPropagators += [TestSTEP_Propagator]
 
 # UPDATOR DEFAULTS -----------------------------------------------------------------------------------------
 
@@ -198,24 +256,26 @@ TestUpdators    = []
 
 from TrkExTools.TrkExToolsConf import Trk__MaterialEffectsUpdator as MaterialEffectsUpdator
 TestMaterialEffectsUpdator = MaterialEffectsUpdator(name = 'TestMaterialEffectsUpdator')
-TestMaterialEffectsUpdator.EnergyLoss           = False
-TestMaterialEffectsUpdator.MultipleScattering   = False
 ToolSvc += TestMaterialEffectsUpdator
+if myPDG == 998 :
+ TestMaterialEffectsUpdator.EnergyLoss           = False
+ TestMaterialEffectsUpdator.MultipleScattering   = False
 
 TestUpdators    += [ TestMaterialEffectsUpdator ]
 
 TestMaterialEffectsUpdatorLandau = MaterialEffectsUpdator(name = 'TestMaterialEffectsUpdatorLandau')
 TestMaterialEffectsUpdatorLandau.LandauMode           = True
-TestMaterialEffectsUpdatorLandau.EnergyLoss           = False
-TestMaterialEffectsUpdatorLandau.MultipleScattering   = False
 ToolSvc += TestMaterialEffectsUpdatorLandau
+if myPDG == 998 :
+ TestMaterialEffectsUpdatorLandau.EnergyLoss           = False
+ TestMaterialEffectsUpdatorLandau.MultipleScattering   = False
 
-TestUpdators    += [ TestMaterialEffectsUpdatorLandau ]
+##TestUpdators    += [ TestMaterialEffectsUpdatorLandau ]
 
 # the UNIQUE NAVIGATOR ( === UNIQUE GEOMETRY) --------------------------------------------------------------
 from TrkExTools.TrkExToolsConf import Trk__Navigator
 TestNavigator = Trk__Navigator(name = 'TestNavigator')
-TestNavigator.TrackingGeometrySvc = AtlasTrackingGeometrySvc
+TestNavigator.TrackingGeometrySvc = "Trk::TrackingGeometrySvc/AtlasTrackingGeometrySvc"
 ToolSvc += TestNavigator
 
 # CONFIGURE PROPAGATORS/UPDATORS ACCORDING TO GEOMETRY SIGNATURE
@@ -230,31 +290,52 @@ TestSubUpdators    += [ TestMaterialEffectsUpdator.name() ]
 
 # default for Calo is (Rk,MatLandau)
 TestSubPropagators += [ TestPropagator.name() ]
-TestSubUpdators    += [ TestMaterialEffectsUpdatorLandau.name() ]
+TestSubUpdators    += [ TestMaterialEffectsUpdator.name() ]
+
+TestSubPropagators += [ TestPropagator.name() ]
+TestSubUpdators    += [ TestMaterialEffectsUpdator.name() ]
 
 # default for MS is (STEP,Mat)
 TestSubPropagators += [ TestSTEP_Propagator.name() ]
 TestSubUpdators    += [ TestMaterialEffectsUpdator.name() ]
+
+TestSubPropagators += [ TestSTEP_Propagator.name() ]
+TestSubUpdators    += [ TestMaterialEffectsUpdator.name() ]
+
+TestSubPropagators += [ TestPropagator.name() ]
+TestSubUpdators    += [ TestMaterialEffectsUpdator.name() ]
 # ----------------------------------------------------------------------------------------------------------
 
 # call the base class constructor
 from TrkExTools.TrkExToolsConf import Trk__Extrapolator
-TestExtrapolator = Trk__Extrapolator('TextExtrapolator',\
+TestExtrapolator = Trk__Extrapolator('TestExtrapolator',\
                            Navigator = TestNavigator,\
                            MaterialEffectsUpdators = TestUpdators,\
-                           Propagators = TestPorpagators,\
+                           Propagators = TestPropagators,\
+                           EnergyLossUpdators = TestEnergyLossUpdator,\
+                           STEP_Propagator = TestSTEP_Propagator.name(),\
                            SubPropagators = TestSubPropagators,\
-                           SubMEUpdators = TestSubUpdators,\
-                           DoCaloDynamic = False)
+                           SubMEUpdators = TestSubUpdators)
 ToolSvc += TestExtrapolator
 
+from TrkG4UserActions.TrkG4UserActionsConf import Trk__GeantFollowerHelper
+GeantFollowerHelper = Trk__GeantFollowerHelper(name="GeantFollowerHelper")
+GeantFollowerHelper.Extrapolator             = TestExtrapolator
+GeantFollowerHelper.ExtrapolateDirectly      = True
+GeantFollowerHelper.ExtrapolateIncrementally = True
+GeantFollowerHelper.OutputLevel = VERBOSE
+ToolSvc += GeantFollowerHelper
+
+SimFlags.UseV2UserActions = True
+SimFlags.OptionalUserActionList.addAction('G4UA::GeantFollowerTool',['Step','BeginOfEvent','EndOfEvent','BeginOfRun'])
+
 ############### The output collection #######################
 
 from AthenaPoolCnvSvc.WriteAthenaPool import AthenaPoolOutputStream
-# --- check dictionary
+## --- check dictionary
 ServiceMgr.AthenaSealSvc.CheckDictionary   = True
-# --- commit interval (test)
-ServiceMgr.AthenaPoolCnvSvc.OutputLevel = DEBUG
+## --- commit interval (test)
+#ServiceMgr.AthenaPoolCnvSvc.OutputLevel = DEBUG
 ServiceMgr.AthenaPoolCnvSvc.CommitInterval = 10
 
 from AthenaCommon.AppMgr import ServiceMgr
@@ -265,13 +346,25 @@ ServiceMgr.THistSvc.Output += [ "val DATAFILE='GeantFollowing.root' TYPE='ROOT'
 
 ##############################################################
 
+
+from AthenaCommon.CfgGetter import getAlgorithm
+topSeq += getAlgorithm("BeamEffectsAlg", tryDefaultConfigurable=True)
+
 ## Populate alg sequence
 from G4AtlasApps.PyG4Atlas import PyG4AtlasAlg
 topSeq += PyG4AtlasAlg()
 
-from AthenaCommon.CfgGetter import getPublicTool
-ServiceMgr.UserActionSvc.BeginOfEventActions += [getPublicTool("GeantFollower")]
-ServiceMgr.UserActionSvc.EndOfEventActions += [getPublicTool("GeantFollower")]
-ServiceMgr.UserActionSvc.SteppingActions += [getPublicTool("GeantFollower")]
+#ServiceMgr.AthenaOutputStream.StreamHITS.ItemList                  = ['EventInfo#*']
+
+ToolSvc.MuonTrackingGeometryBuilder.BlendInertMaterial = False
+TestSTEP_Propagator.Straggling = False
+
+#TestExtrapolator.OutputLevel = VERBOSE
+
+if myPDG == 998 :
+  TestSTEP_Propagator.MultipleScattering = False
+  TestSTEP_Propagator.EnergyLoss = False
 
-#--- End jobOptions.GeantinoMapping.py file  ------------------------------
+from AthenaCommon.ConfigurationShelve import saveToAscii
+saveToAscii("config.txt")
+#--- End jobOptions GeantFollowing_jobOptions.py file  ------------------------------
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/EnergyLossRecorder.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/EnergyLossRecorder.cxx
index 373f56a66ee..ba324c004d9 100755
--- a/Tracking/TrkG4Components/TrkG4UserActions/src/EnergyLossRecorder.cxx
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/EnergyLossRecorder.cxx
@@ -107,12 +107,99 @@ void EnergyLossRecorder::Step(const G4Step* aStep)
 
 StatusCode EnergyLossRecorder::queryInterface(const InterfaceID& riid, void** ppvInterface)
 {
-  if ( IUserAction::interfaceID().versionMatch(riid) ) {
-    *ppvInterface = dynamic_cast<IUserAction*>(this);
-    addRef();
-  } else {
-    // Interface is not directly available : try out a base class
-    return UserActionBase::queryInterface(riid, ppvInterface);
-  }
-  return StatusCode::SUCCESS;
+  if ( IUserAction::interfaceID().versionMatch(riid) )
+    {
+      *ppvInterface = dynamic_cast<IUserAction*>(this);
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+  // Interface is not directly available : try out a base class
+  return UserActionBase::queryInterface(riid, ppvInterface);
 }
+
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IMessageSvc.h"
+
+namespace G4UA
+{
+
+
+  EnergyLossRecorder::EnergyLossRecorder(const Config& config)
+    : AthMessaging(Gaudi::svcLocator()->service< IMessageSvc >( "MessageSvc" ),"EnergyLossRecorder")
+    , m_config(config)
+    , m_entries(0)
+  {
+
+  }
+
+  void EnergyLossRecorder::beginOfRun(const G4Run*)
+  {
+    return;
+  }
+
+  void EnergyLossRecorder::endOfRun(const G4Run*)
+  {
+    return;
+  }
+
+  void EnergyLossRecorder::beginOfEvent(const G4Event*)
+  {
+    return;
+  }
+
+  void EnergyLossRecorder::endOfEvent(const G4Event*)
+  {
+    if (m_config.pmWriter)
+      {
+        m_config.pmWriter->finalizeTrack();
+      }
+    m_entries = 0;
+    return;
+  }
+
+  void EnergyLossRecorder::processStep(const G4Step* aStep)
+  {
+    // kill secondary particles
+    if (aStep->GetTrack()->GetParentID())
+      {
+        aStep->GetTrack()->SetTrackStatus(fStopAndKill);
+        return;
+      }
+    if(!m_config.pmWriter) return;
+    // we require a minimum amount of material for recording the step
+
+    // the material information
+    G4TouchableHistory* touchHist = (G4TouchableHistory*)aStep->GetPreStepPoint()->GetTouchable();
+    // G4LogicalVolume
+    G4LogicalVolume *lv= touchHist ? touchHist->GetVolume()->GetLogicalVolume() : 0;
+    G4Material *mat    = lv ? lv->GetMaterial() : 0;
+
+    // log the information // cut off air
+    if (mat && mat->GetRadlen() < 200000.)
+      {
+        // keep primary particles - calculate the kinematics for them
+        G4ThreeVector pos   = aStep->GetPreStepPoint()->GetPosition();
+        double px = aStep->GetPreStepPoint()->GetMomentum().x();
+        double py = aStep->GetPreStepPoint()->GetMomentum().y();
+        double pz = aStep->GetPreStepPoint()->GetMomentum().z();
+        Amg::Vector3D position(pos.x(),pos.y(),pos.z());
+        Amg::Vector3D momentum(px ,py, pz);
+
+
+        // record the starting parameters at the first step
+        if (m_entries==0)
+          {
+            // increase the counter
+            ++m_entries;
+            double  m   = aStep->GetTrack()->GetDynamicParticle()->GetMass();
+            int pdgCode = aStep->GetTrack()->GetDynamicParticle()->GetPDGcode();
+            m_config.pmWriter->initializeTrack(position,momentum,m,pdgCode);
+          }
+        else
+          {
+            m_config.pmWriter->recordTrackState(position,momentum);
+          }
+      }
+  }
+} // namespace G4UA
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/EnergyLossRecorderTool.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/EnergyLossRecorderTool.cxx
new file mode 100644
index 00000000000..764d6c11f59
--- /dev/null
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/EnergyLossRecorderTool.cxx
@@ -0,0 +1,62 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "CxxUtils/make_unique.h"
+#include "TrkG4UserActions/EnergyLossRecorderTool.h"
+#include "TrkValInterfaces/IPositionMomentumWriter.h"
+
+namespace G4UA{ 
+  
+  
+  EnergyLossRecorderTool::EnergyLossRecorderTool(const std::string& type, const std::string& name,const IInterface* parent)
+    : ActionToolBase<EnergyLossRecorder>(type, name, parent), m_config()
+    , m_pmWriter("")
+  {
+    declareProperty("PositionMomentumWriter", m_pmWriter, "");
+  }
+  StatusCode EnergyLossRecorderTool::initialize()
+  {
+    if(!m_pmWriter.empty())
+      {
+        ATH_CHECK(m_pmWriter.retrieve());
+        m_config.pmWriter = &(*m_pmWriter);
+      }
+    return StatusCode::SUCCESS;
+  }
+  std::unique_ptr<EnergyLossRecorder>  EnergyLossRecorderTool::makeAction(){
+    ATH_MSG_DEBUG("makeAction");
+    auto action = CxxUtils::make_unique<EnergyLossRecorder>(m_config);
+    return std::move(action);
+  }
+  StatusCode EnergyLossRecorderTool::queryInterface(const InterfaceID& riid, void** ppvIf){
+    
+    if(riid == IBeginRunActionTool::interfaceID()) {
+      *ppvIf = (IBeginRunActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IEndRunActionTool::interfaceID()) {
+      *ppvIf = (IEndRunActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IBeginEventActionTool::interfaceID()) {
+      *ppvIf = (IBeginEventActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IEndEventActionTool::interfaceID()) {
+      *ppvIf = (IEndEventActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == ISteppingActionTool::interfaceID()) {
+      *ppvIf = (ISteppingActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    return ActionToolBase<EnergyLossRecorder>::queryInterface(riid, ppvIf);
+  }
+  
+} // namespace G4UA 
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollower.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollower.cxx
index 28099b4a4b0..275699180b4 100755
--- a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollower.cxx
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollower.cxx
@@ -24,30 +24,28 @@
 #include "G4DynamicParticle.hh"
 #include "G4Track.hh"
 
-
-GeantFollower::GeantFollower(const std::string& type, const std::string& name, const IInterface* parent) :
-  UserActionBase(type,name,parent),
-  m_helper("Trk::GeantFollowerHelper"),
-  m_helperPointer(0)
+GeantFollower::GeantFollower(const std::string& type, const std::string& name, const IInterface* parent)
+  : UserActionBase(type,name,parent)
+  , m_helper("Trk::GeantFollowerHelper")
+  , m_helperPointer(nullptr)
 {
   declareProperty("HelperTool",m_helper);
 }
 
+StatusCode GeantFollower::initialize(){
 
-StatusCode GeantFollower::initialize()
-{
   ATH_CHECK(m_helper.retrieve());
   m_helperPointer = (&(*m_helper));
+
   return StatusCode::SUCCESS;
 }
 
 
-
 void GeantFollower::BeginOfEvent(const G4Event*)
 {
-  // now initialize the helper
+
   m_helperPointer->beginEvent();
-  return;
+
 }
 
 
@@ -55,7 +53,6 @@ void GeantFollower::EndOfEvent(const G4Event*)
 {
   // release event
   m_helperPointer->endEvent();
-  return;
 }
 
 
@@ -101,6 +98,7 @@ void GeantFollower::Step(const G4Step* aStep)
 }
 
 
+
 StatusCode GeantFollower::queryInterface(const InterfaceID& riid, void** ppvInterface)
 {
   if ( IUserAction::interfaceID().versionMatch(riid) ) {
@@ -112,3 +110,87 @@ StatusCode GeantFollower::queryInterface(const InterfaceID& riid, void** ppvInte
   }
   return StatusCode::SUCCESS;
 }
+
+
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IMessageSvc.h"
+
+namespace G4UA{
+
+
+  GeantFollower::GeantFollower(const Config& config):
+    AthMessaging(Gaudi::svcLocator()->service< IMessageSvc >( "MessageSvc" ),"GeantFollower"),
+    m_config(config),
+    m_helperPointer(0){}
+
+  void GeantFollower::beginOfEvent(const G4Event*){
+    m_helperPointer->beginEvent();
+
+  }
+
+  void GeantFollower::endOfEvent(const G4Event*){
+
+    m_helperPointer->endEvent();
+
+
+  }
+
+  void GeantFollower::beginOfRun(const G4Run*){
+
+    if(m_config.helper.retrieve()!=StatusCode::SUCCESS){
+
+      ATH_MSG_FATAL("Cannot retrieve GeantFollower helper");
+      return;
+    }
+
+    m_helperPointer = (&(*m_config.helper));
+
+    return;
+
+  }
+
+  void GeantFollower::processStep(const G4Step* aStep){
+
+
+    // kill secondaries
+    if (aStep->GetTrack()->GetParentID()) {
+      aStep->GetTrack()->SetTrackStatus(fStopAndKill);
+      return;
+    }
+
+    // get the prestep point and follow this guy
+    G4StepPoint * g4PreStep  = aStep->GetPreStepPoint();
+    G4ThreeVector g4Momentum = g4PreStep->GetMomentum();
+    G4ThreeVector g4Position = g4PreStep->GetPosition();
+
+    G4Track* g4Track = aStep->GetTrack();
+    const G4DynamicParticle* g4DynParticle = g4Track->GetDynamicParticle();
+
+    // the material information
+    const G4TouchableHistory* touchHist = static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
+    if(ATH_LIKELY(touchHist)) {
+      // G4LogicalVolume
+      const G4LogicalVolume *lv= touchHist->GetVolume()->GetLogicalVolume();
+      if(ATH_LIKELY(lv)) {
+        const G4Material *mat    = lv->GetMaterial();
+        // the step information
+        double steplength     = aStep->GetStepLength();
+        // the position information
+        double X0             = mat->GetRadlen();
+        // update the track follower
+        m_helperPointer->trackParticle(g4Position,g4Momentum,g4DynParticle->GetPDGcode(),g4DynParticle->GetCharge(),steplength,X0);
+      }
+      else {
+        throw std::runtime_error("GeantFollower::SteppingAction NULL G4LogicalVolume pointer.");
+      }
+    }
+    else {
+      throw std::runtime_error("GeantFollower::SteppingAction NULL G4TouchableHistory pointer.");
+    }
+    return;
+
+
+  }
+
+} // namespace G4UA
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerHelper.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerHelper.cxx
index d37cc3d3f73..14e7cf456fd 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerHelper.cxx
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerHelper.cxx
@@ -144,11 +144,9 @@ void Trk::GeantFollowerHelper::beginEvent() const
 
 void Trk::GeantFollowerHelper::trackParticle(const G4ThreeVector& pos, const G4ThreeVector& mom, int pdg, double charge, float t, float X0) const
 {
-    
-    // construct the intial parameters
-    Amg::Vector3D npos(pos.x(),pos.y(),pos.z());
-    Amg::Vector3D nmom(mom.x(),mom.y(),mom.z());
-        
+  // construct the initial parameters
+  Amg::Vector3D npos(pos.x(),pos.y(),pos.z());
+  Amg::Vector3D nmom(mom.x(),mom.y(),mom.z());
     if (!m_g4_steps){
         ATH_MSG_INFO("Initial step ... preparing event cache.");
         m_t_x        = pos.x();        
@@ -183,7 +181,7 @@ void Trk::GeantFollowerHelper::trackParticle(const G4ThreeVector& pos, const G4T
     // destination surface
     const Trk::PlaneSurface& destinationSurface = g4Parameters->associatedSurface();
     // extrapolate to the destination surface
-    const Trk::TrackParameters* trkParameters = m_extrapolateDirectly ? 
+    const Trk::TrackParameters* trkParameters = m_extrapolateDirectly ?
         m_extrapolator->extrapolateDirectly(*m_parameterCache,destinationSurface,Trk::alongMomentum,false) :
         m_extrapolator->extrapolate(*m_parameterCache,destinationSurface,Trk::alongMomentum,false);
     // fill the geant information and the trk information
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMS.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMS.cxx
index d5ce67993bf..c5e110d6298 100755
--- a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMS.cxx
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMS.cxx
@@ -27,11 +27,11 @@
 
 GeantFollowerMS::GeantFollowerMS(const std::string& type, const std::string& name, const IInterface* parent) :
   UserActionBase(type,name,parent),
-    m_helper("Trk::GeantFollowerMSHelper"),
-    m_helperPointer(0),
-    m_trackingGeometry(0),
-    m_trackingGeometrySvc("AtlasTrackingGeometrySvc",name),
-    m_trackingGeometryName("AtlasTrackingGeometry")
+  m_helper("Trk::GeantFollowerMSHelper"),
+  m_helperPointer(0),
+  m_trackingGeometry(0),
+  m_trackingGeometrySvc("AtlasTrackingGeometrySvc",name),
+  m_trackingGeometryName("AtlasTrackingGeometry")
 {
   declareProperty("HelperTool",m_helper);
 }
@@ -118,3 +118,87 @@ StatusCode GeantFollowerMS::queryInterface(const InterfaceID& riid, void** ppvIn
   return StatusCode::SUCCESS;
 }
 
+
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IMessageSvc.h"
+
+namespace G4UA{
+
+
+  GeantFollowerMS::GeantFollowerMS(const Config& config)
+    : AthMessaging(Gaudi::svcLocator()->service< IMessageSvc >( "MessageSvc" ),"GeantFollowerMS")
+    , m_config(config)
+    , m_trackingGeometry(nullptr)
+    , m_helperPointer(nullptr)
+  {}
+
+  void GeantFollowerMS::beginOfEvent(const G4Event*)
+  {
+    m_helperPointer->beginEvent();
+  }
+
+  void GeantFollowerMS::endOfEvent(const G4Event*)
+  {
+    m_helperPointer->endEvent();
+  }
+
+  void GeantFollowerMS::beginOfRun(const G4Run*)
+  {
+    if(m_config.helper.retrieve()!=StatusCode::SUCCESS){
+
+      ATH_MSG_FATAL("Cannot retrieve GeantFollowerMS helper");
+      return;
+    }
+    m_helperPointer = (&(*m_config.helper));
+
+    if(m_config.trackingGeometrySvc.retrieve()!=StatusCode::SUCCESS) {
+      ATH_MSG_FATAL("Cannot retrieve TrackingGeometrySvc in GeantFollowerMS");
+      return;
+    }
+
+    return;
+  }
+
+  void GeantFollowerMS::processStep(const G4Step* aStep)
+  {
+    // kill secondaries
+    if (aStep->GetTrack()->GetParentID()) {
+      aStep->GetTrack()->SetTrackStatus(fStopAndKill);
+      return;
+    }
+
+    // get the prestep point and follow this guy
+    G4StepPoint * g4PreStep  = aStep->GetPreStepPoint();
+    G4ThreeVector g4Momentum = g4PreStep->GetMomentum();
+    G4ThreeVector g4Position = g4PreStep->GetPosition();
+
+    G4Track* g4Track = aStep->GetTrack();
+    const G4DynamicParticle* g4DynParticle = g4Track->GetDynamicParticle();
+
+    // the material information
+    const G4TouchableHistory* touchHist = static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
+    if(ATH_LIKELY(touchHist)) {
+      // G4LogicalVolume
+      const G4LogicalVolume *lv= touchHist->GetVolume()->GetLogicalVolume();
+      if(ATH_LIKELY(lv)) {
+        const G4Material *mat    = lv->GetMaterial();
+        // the step information
+        double steplength     = aStep->GetStepLength();
+        // the position information
+        double X0             = mat->GetRadlen();
+        // update the track follower
+        //std::cout << " particle PDG " << g4DynParticle->GetPDGcode() << " charge " << g4DynParticle->GetCharge() << std::endl;
+        m_helperPointer->trackParticle(g4Position,g4Momentum,g4DynParticle->GetPDGcode(),g4DynParticle->GetCharge(),steplength,X0);
+      }
+      else {
+        throw std::runtime_error("GeantFollowerMS::SteppingAction NULL G4LogicalVolume pointer.");
+      }
+    }
+    else {
+      throw std::runtime_error("GeantFollowerMS::SteppingAction NULL G4TouchableHistory pointer.");
+    }
+    return;
+  }
+
+} // namespace G4UA
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMSHelper.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMSHelper.cxx
index fe4a1bcd5db..b5205f49791 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMSHelper.cxx
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMSHelper.cxx
@@ -11,9 +11,6 @@
 #include "StoreGate/StoreGateSvc.h"
 #include "TTree.h"
 #include "GaudiKernel/ITHistSvc.h" 
-// CLHEP
-#include "CLHEP/Units/SystemOfUnits.h"
-#include "CLHEP/Geometry/Transform3D.h"
 // Trk
 #include "TrkExInterfaces/IExtrapolator.h"
 #include "TrkExInterfaces/IEnergyLossUpdator.h"
@@ -25,23 +22,101 @@
 #include "GeoPrimitives/GeoPrimitives.h"
 #include "TrkExUtils/ExtrapolationCache.h"
 
+
 // constructor
-Trk::GeantFollowerMSHelper::GeantFollowerMSHelper(const std::string& t, const std::string& n, const IInterface* p) :
-  AthAlgTool(t,n,p),
-  m_extrapolator(""),
-  m_elossupdator("Trk::EnergyLossUpdator/AtlasEnergyLossUpdator"),
-  m_extrapolateDirectly(false),
-  m_extrapolateIncrementally(false),
-  m_speedup(false),
-  m_parameterCache(0),
-  m_parameterCacheCov(0),
-  m_parameterCacheMS(0),
-  m_parameterCacheMSCov(0),
-  m_tX0Cache(0.),
-  m_validationTreeName("G4Follower"),
-  m_validationTreeDescription("Output of the G4Follower_"),
-  m_validationTreeFolder("/val/G4Follower"),
-  m_validationTree(0)
+Trk::GeantFollowerMSHelper::GeantFollowerMSHelper(const std::string& t, const std::string& n, const IInterface* p)
+ : AthAlgTool(t,n,p)
+ , m_extrapolator("")
+ , m_elossupdator("Trk::EnergyLossUpdator/AtlasEnergyLossUpdator")
+ , m_extrapolateDirectly(false)
+ , m_extrapolateIncrementally(false)
+ , m_speedup(false)
+ , m_parameterCache(nullptr)
+ , m_parameterCacheCov(nullptr)
+ , m_parameterCacheMS(nullptr)
+ , m_parameterCacheMSCov(nullptr)
+ , m_tX0Cache(0.)
+ , m_crossedMuonEntry(false)
+ , m_exitLayer(false)
+ , m_destinationSurface(nullptr)
+ , m_validationTreeName("G4Follower")
+ , m_validationTreeDescription("Output of the G4Follower_")
+ , m_validationTreeFolder("/val/G4Follower")
+ , m_validationTree(nullptr)
+ , m_t_x(0.)
+ , m_t_y(0.)
+ , m_t_z(0.)
+ , m_t_theta(0.)
+ , m_t_eta(0.)
+ , m_t_phi(0.)
+ , m_t_p(0.)
+ , m_t_charge(0.)
+ , m_t_pdg(0)
+ , m_m_x(0.)
+ , m_m_y(0.)
+ , m_m_z(0.)
+ , m_m_theta(0.)
+ , m_m_eta(0.)
+ , m_m_phi(0.)
+ , m_m_p(0.)
+ , m_b_x(0.)
+ , m_b_y(0.)
+ , m_b_z(0.)
+ , m_b_theta(0.)
+ , m_b_eta(0.)
+ , m_b_phi(0.)
+ , m_b_p(0.)
+ , m_b_X0(0.)
+ , m_b_Eloss(0.)
+ , m_g4_steps(-1)
+ , m_g4_p{0}
+ , m_g4_eta{0}
+ , m_g4_theta{0}
+ , m_g4_phi{0}
+ , m_g4_x{0}
+ , m_g4_y{0}
+ , m_g4_z{0}
+ , m_g4_tX0{0}
+ , m_g4_t{0}
+ , m_g4_X0{0}
+ , m_trk_status{0}
+ , m_trk_p{0}
+ , m_trk_eta{0}
+ , m_trk_theta{0}
+ , m_trk_phi{0}
+ , m_trk_x{0}
+ , m_trk_y{0}
+ , m_trk_z{0}
+ , m_trk_lx{0}
+ , m_trk_ly{0}
+ , m_trk_eloss{0}
+ , m_trk_eloss1{0}
+ , m_trk_eloss0{0}
+ , m_trk_eloss5{0}
+ , m_trk_eloss10{0}
+ , m_trk_scaleeloss{0}
+ , m_trk_scalex0{0}
+ , m_trk_x0{0}
+ , m_trk_erd0{0}
+ , m_trk_erz0{0}
+ , m_trk_erphi{0}
+ , m_trk_ertheta{0}
+ , m_trk_erqoverp{0}
+ , m_trk_scats(0)
+ , m_trk_sstatus{0}
+ , m_trk_sx{0}
+ , m_trk_sy{0}
+ , m_trk_sz{0}
+ , m_trk_sx0{0}
+ , m_trk_seloss{0}
+ , m_trk_smeanIoni{0}
+ , m_trk_ssigIoni{0}
+ , m_trk_smeanRad{0}
+ , m_trk_ssigRad{0}
+ , m_trk_ssigTheta{0}
+ , m_trk_ssigPhi{0}
+ , m_g4_stepsMS(-1)
+
 {
    declareInterface<IGeantFollowerMSHelper>(this);
    // properties
@@ -73,6 +148,11 @@ StatusCode Trk::GeantFollowerMSHelper::initialize()
        return StatusCode::FAILURE;
    }
     
+   if(m_speedup) {
+      ATH_MSG_INFO(" SpeedUp GeantFollowerMS ");
+   } else {
+      ATH_MSG_INFO(" NO SpeedUp GeantFollowerMS ");
+   }
    ATH_MSG_INFO("initialize()");
    
    // create the new Tree
@@ -159,6 +239,7 @@ StatusCode Trk::GeantFollowerMSHelper::initialize()
 
    // initialize
    //
+   m_t_x        = 0.;    
    m_t_y        = 0.; 
    m_t_z        = 0.; 
    m_t_theta    = 0.; 
@@ -287,6 +368,7 @@ void Trk::GeantFollowerMSHelper::trackParticle(const G4ThreeVector& pos, const G
         m_g4_steps   = 0;
         m_tX0Cache   = 0.;
         // construct the intial parameters
+        
         m_parameterCache = new Trk::CurvilinearParameters(npos, nmom, charge);
         AmgSymMatrix(5)* covMatrix = new AmgSymMatrix(5);;
         covMatrix->setZero();
@@ -325,6 +407,7 @@ void Trk::GeantFollowerMSHelper::trackParticle(const G4ThreeVector& pos, const G
         Trk::CurvilinearParameters* g4Parameters = new Trk::CurvilinearParameters(npos, nmom, m_t_charge);
 // Muon Entry
         m_destinationSurface = &(g4Parameters->associatedSurface());
+        delete g4Parameters;
     }
 
     
@@ -354,6 +437,7 @@ void Trk::GeantFollowerMSHelper::trackParticle(const G4ThreeVector& pos, const G
 //      if(fabs(npos.z())>zMuonEntry||npos.perp()>4255) crossedExitLayer = true;
       if(fabs(npos.z())>21800||npos.perp()>12500) crossedExitLayer = true;
       if(m_crossedMuonEntry&&m_g4_steps>=2&&!crossedExitLayer) return;
+      if(m_g4_steps>2) return;
       if(m_g4_steps>4) return;
     }
 
@@ -411,6 +495,9 @@ void Trk::GeantFollowerMSHelper::trackParticle(const G4ThreeVector& pos, const G
         m_extrapolator->extrapolate(*m_parameterCacheMS,destinationSurface,Trk::alongMomentum,false,Trk::muon);
 // Backwards from Exit to ME 
       if(trkParameters_FW) {
+       ATH_MSG_DEBUG (" forward extrapolation succeeded ");
+       bool doBackWard = false;
+       if(doBackWard) { 
         const Trk::TrackParameters* trkParameters_BACK = m_extrapolateDirectly ?
           m_extrapolator->extrapolateDirectly(*trkParameters_FW,*m_destinationSurface,Trk::oppositeMomentum,false,Trk::muon) :
           m_extrapolator->extrapolate(*trkParameters_FW,*m_destinationSurface,Trk::oppositeMomentum,false,Trk::muon);
@@ -495,6 +582,7 @@ void Trk::GeantFollowerMSHelper::trackParticle(const G4ThreeVector& pos, const G
           m_b_X0         =  x0;
           m_b_Eloss      =  Eloss;
           delete matvec_BACK;
+         }
         }
         delete trkParameters_FW;
       }
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMSTool.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMSTool.cxx
new file mode 100644
index 00000000000..aac628ea659
--- /dev/null
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerMSTool.cxx
@@ -0,0 +1,48 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "CxxUtils/make_unique.h"
+#include "TrkG4UserActions/GeantFollowerMSTool.h"
+#include "TrkG4UserActions/IGeantFollowerMSHelper.h"
+
+namespace G4UA{
+
+
+  GeantFollowerMSTool::GeantFollowerMSTool(const std::string& type, const std::string& name,const IInterface* parent):
+    ActionToolBase<GeantFollowerMS>(type, name, parent), m_config(){
+    declareProperty("HelperTool",m_config.helper);
+  }
+
+  std::unique_ptr<GeantFollowerMS>  GeantFollowerMSTool::makeAction(){
+    ATH_MSG_DEBUG("makeAction");
+    auto action = CxxUtils::make_unique<GeantFollowerMS>(m_config);
+    return std::move(action);
+  }
+
+  StatusCode GeantFollowerMSTool::queryInterface(const InterfaceID& riid, void** ppvIf){
+
+    if(riid == IBeginEventActionTool::interfaceID()) {
+      *ppvIf = (IBeginEventActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IEndEventActionTool::interfaceID()) {
+      *ppvIf = (IEndEventActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IBeginRunActionTool::interfaceID()) {
+      *ppvIf = (IBeginRunActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == ISteppingActionTool::interfaceID()) {
+      *ppvIf = (ISteppingActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    return ActionToolBase<GeantFollowerMS>::queryInterface(riid, ppvIf);
+  }
+
+} // namespace G4UA
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerTool.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerTool.cxx
new file mode 100644
index 00000000000..a4ec9ba79e8
--- /dev/null
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/GeantFollowerTool.cxx
@@ -0,0 +1,47 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "CxxUtils/make_unique.h"
+#include "TrkG4UserActions/GeantFollowerTool.h"
+
+namespace G4UA{
+
+
+  GeantFollowerTool::GeantFollowerTool(const std::string& type, const std::string& name,const IInterface* parent):
+    ActionToolBase<GeantFollower>(type, name, parent), m_config(){
+    declareProperty("HelperTool",m_config.helper);
+  }
+
+  std::unique_ptr<GeantFollower>  GeantFollowerTool::makeAction(){
+    ATH_MSG_DEBUG("makeAction");
+    auto action = CxxUtils::make_unique<GeantFollower>(m_config);
+    return std::move(action);
+  }
+
+  StatusCode GeantFollowerTool::queryInterface(const InterfaceID& riid, void** ppvIf){
+
+    if(riid == IBeginEventActionTool::interfaceID()) {
+      *ppvIf = (IBeginEventActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IEndEventActionTool::interfaceID()) {
+      *ppvIf = (IEndEventActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IBeginRunActionTool::interfaceID()) {
+      *ppvIf = (IBeginRunActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == ISteppingActionTool::interfaceID()) {
+      *ppvIf = (ISteppingActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    return ActionToolBase<GeantFollower>::queryInterface(riid, ppvIf);
+  }
+
+} // namespace G4UA
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/MaterialStepRecorder.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/MaterialStepRecorder.cxx
index 7db5a3866a3..97dee6f15e5 100755
--- a/Tracking/TrkG4Components/TrkG4UserActions/src/MaterialStepRecorder.cxx
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/MaterialStepRecorder.cxx
@@ -233,3 +233,204 @@ StatusCode MaterialStepRecorder::queryInterface(const InterfaceID& riid, void**
   }
   return StatusCode::SUCCESS;
 }
+
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IMessageSvc.h"
+
+namespace G4UA{
+
+
+  MaterialStepRecorder::MaterialStepRecorder():
+    AthMessaging(Gaudi::svcLocator()->service< IMessageSvc >( "MessageSvc" ),"MaterialStepRecorder"),
+    m_evtStore("StoreGateSvc/StoreGateSvc","MaterialStepRecorder"),
+    m_detStore("StoreGateSvc/DetectorStore","MaterialStepRecorder"),
+    m_matStepCollection(0),
+    m_matStepCollectionName("MaterialStepRecords"),
+    m_recordComposition(true),
+    m_totalNbOfAtoms(0),
+    m_totalSteps(0),
+    m_eventID(0),
+    m_elementTable(0),
+    m_elementTableName("ElementTable"),
+    m_runElementTable(0)
+  {
+  }
+
+  void MaterialStepRecorder::beginOfEvent(const G4Event*){
+
+
+    ATH_MSG_DEBUG(" BeginOfEventAction");
+
+    // create a new Collection
+    m_matStepCollection = new Trk::MaterialStepCollection;
+
+    //    m_eventStepLength = 0;
+
+  }
+
+  void MaterialStepRecorder::endOfEvent(const G4Event*){
+
+    ATH_MSG_DEBUG(" EndOfEventAction");
+
+    ++m_eventID;
+    // write the Collection to StoreGate
+    if(m_evtStore->record(m_matStepCollection, m_matStepCollectionName, false).isFailure())
+      {
+        ATH_MSG_ERROR("cannot record step collection to StoreGate");
+      }
+    // write out the ElementTable of this event
+    if ( m_evtStore->record(m_elementTable, m_elementTableName, false).isFailure() )
+      {
+        ATH_MSG_ERROR("EndOfEventAction : recording ElementTable in StoreGate FAILED");
+        delete m_elementTable;
+      }
+    m_elementTable = nullptr;
+
+  }
+
+  void MaterialStepRecorder::beginOfRun(const G4Run*){
+
+    ATH_MSG_DEBUG(" BeginOfRunAction");
+
+    // initialize
+    m_totalSteps = 0;
+    m_eventID = 0;
+
+  }
+
+  void MaterialStepRecorder::processStep(const G4Step* aStep)
+  {
+    // kill secondaries
+    if (aStep->GetTrack()->GetParentID()) {
+      aStep->GetTrack()->SetTrackStatus(fStopAndKill);
+      return;
+    }
+
+    // ElementTable preparation
+    if (m_recordComposition && !m_elementTable) {
+      m_elementTable = new Trk::ElementTable();
+      m_runElementTable = new Trk::ElementTable();
+    }
+
+    // the material information
+    G4TouchableHistory* touchHist = (G4TouchableHistory*)aStep->GetPreStepPoint()->GetTouchable();
+    // G4LogicalVolume
+    G4LogicalVolume *lv= touchHist ? touchHist->GetVolume()->GetLogicalVolume() : 0;
+    G4Material *mat    = lv ? lv->GetMaterial() : 0;
+
+    std::vector<unsigned char> elements;
+    std::vector<unsigned char> fractions;
+
+    // log the information // cut off air
+    if (mat && mat->GetRadlen() < 200000.) {
+
+      ++m_totalSteps;
+
+      // the step information
+      double steplength     = aStep->GetStepLength();
+
+      // the position information
+      G4ThreeVector pos     = aStep->GetPreStepPoint()->GetPosition();
+
+      double X0             = mat->GetRadlen();
+      double L0             = mat->GetNuclearInterLength();
+      double A              = 0.;
+      double Z              = 0.;
+      //        double totAtoms       = 0.;
+
+      double rho            = mat->GetDensity()*CLHEP::mm3/CLHEP::gram;
+
+      // get the number of Elements
+      size_t                 elNumber = mat->GetNumberOfElements();
+      const G4ElementVector* elVector = mat->GetElementVector();
+      double                 totAtoms = mat->GetTotNbOfAtomsPerVolume();
+
+      // reserve the right number of elements
+      elements.reserve(elNumber);
+      fractions.reserve(elNumber);
+
+      if (1 == elNumber) {
+
+        A   = mat->GetA()/CLHEP::gram;
+        Z   = mat->GetZ();
+
+        unsigned int Zint = (unsigned int)Z;
+        // the element and fraction vector
+        elements.push_back(static_cast<unsigned char>(Z));
+        fractions.push_back(UCHAR_MAX);
+        // record the Element
+        if (m_recordComposition && !m_elementTable->contains(Zint)){
+          // the element Material
+          Trk::Material elMat(X0,L0,A,Z,rho);
+          G4String      elName =  (*elVector)[0]->GetName();
+          // add it to the table
+          m_elementTable->addElement(elMat, elName);
+          m_runElementTable->addElement(elMat,elName);
+        }
+
+
+      } else {
+
+        const G4double*   atVector = mat->GetVecNbOfAtomsPerVolume();
+        double totalFrac           = 0.;
+        double totalFracChar       = 0.;
+
+        for (size_t iel = 0; iel < elNumber; ++iel) {
+
+          G4Element*  currentEl  = (*elVector)[iel];
+          double      currentNum = atVector ? atVector[iel] : 1.;
+          double      relNbAtoms = currentNum/totAtoms;
+
+          double currentZ = currentEl->GetZ();
+
+          A += relNbAtoms*currentEl->GetA()/CLHEP::gram;
+          Z += relNbAtoms*currentEl->GetZ();
+          unsigned int Zint = (unsigned int)(currentEl->GetZ());
+
+          // the element and fraction vector
+          elements.push_back(int(currentZ));
+          // calculate the fraction with a accuracy of 1/256.
+          unsigned int relNbAtomsChar = (unsigned int)(relNbAtoms*(UCHAR_MAX));
+          relNbAtomsChar = relNbAtomsChar > UCHAR_MAX ? UCHAR_MAX : relNbAtomsChar;
+
+          // smaller components than 0.5 % are automatically ignored
+          totalFrac     += relNbAtoms;
+          if (relNbAtomsChar) {
+            totalFracChar += double(relNbAtomsChar)/double(1.*UCHAR_MAX);
+            fractions.push_back(relNbAtomsChar);
+            // record composition
+            if (m_recordComposition && !m_elementTable->contains(Zint)){
+              double curA          =  currentEl->GetA()/CLHEP::gram;
+              double curZ          =  currentEl->GetZ();
+              // approximate formulas for X0 and L0
+              // X0 from : PH-EP-Tech-Note-2010-013 g/cm3 -> g/mm3
+              // L0 from :
+              double curX0         =  1432.8*curA/(curZ*(curZ+1)*(11.319-std::log(curZ)));
+              double curL0         =  0.;
+              double curRho        =  rho*relNbAtoms;
+              Trk::Material elMat(curX0,curL0,curA,curZ,curRho);
+              G4String      elName =  currentEl->GetName();
+              // add it to the table
+              m_elementTable->addElement(elMat, elName);
+              m_runElementTable->addElement(elMat,elName);
+            }
+          }
+        }
+        if ((totalFrac-1.)*(totalFrac-1.) > 10e-4 )
+          ATH_MSG_DEBUG("Total fractions do not add up to one at INPUT (" << totalFrac << ") !");
+      }
+
+      // is it a Geantino?
+      if (aStep->GetTrack()->GetParticleDefinition()->GetPDGEncoding() == 0) {
+        if (m_recordComposition)
+          m_matStepCollection->push_back(new Trk::MaterialStep(pos.x(), pos.y(), pos.z(), steplength, X0, L0, A, Z, rho, elements, fractions));
+        else
+          m_matStepCollection->push_back(new Trk::MaterialStep(pos.x(), pos.y(), pos.z(), steplength, X0, L0, A, Z, rho));
+      }
+    }
+    return;
+  }
+
+
+} // namespace G4UA
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/MaterialStepRecorderTool.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/MaterialStepRecorderTool.cxx
new file mode 100644
index 00000000000..ea99a1fb79f
--- /dev/null
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/MaterialStepRecorderTool.cxx
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "CxxUtils/make_unique.h"
+#include "TrkG4UserActions/MaterialStepRecorderTool.h"
+
+namespace G4UA{ 
+
+  MaterialStepRecorderTool::MaterialStepRecorderTool(const std::string& type, const std::string& name,const IInterface* parent):
+    ActionToolBase<MaterialStepRecorder>(type, name, parent){
+  }
+  std::unique_ptr<MaterialStepRecorder>  MaterialStepRecorderTool::makeAction(){
+    ATH_MSG_DEBUG("makeAction");
+    auto action = CxxUtils::make_unique<MaterialStepRecorder>();
+    return std::move(action);
+  }
+  StatusCode MaterialStepRecorderTool::queryInterface(const InterfaceID& riid, void** ppvIf){
+    
+    if(riid == IBeginEventActionTool::interfaceID()) {
+      *ppvIf = (IBeginEventActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IEndEventActionTool::interfaceID()) {
+      *ppvIf = (IEndEventActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == IBeginRunActionTool::interfaceID()) {
+      *ppvIf = (IBeginRunActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    if(riid == ISteppingActionTool::interfaceID()) {
+      *ppvIf = (ISteppingActionTool*) this;
+      addRef();
+      return StatusCode::SUCCESS;
+    }
+    return ActionToolBase<MaterialStepRecorder>::queryInterface(riid, ppvIf);
+  }
+  
+} // namespace G4UA 
diff --git a/Tracking/TrkG4Components/TrkG4UserActions/src/components/TrkG4UserActions_entries.cxx b/Tracking/TrkG4Components/TrkG4UserActions/src/components/TrkG4UserActions_entries.cxx
index 9726ac9faca..23547b045d7 100644
--- a/Tracking/TrkG4Components/TrkG4UserActions/src/components/TrkG4UserActions_entries.cxx
+++ b/Tracking/TrkG4Components/TrkG4UserActions/src/components/TrkG4UserActions_entries.cxx
@@ -1,14 +1,27 @@
 #include "GaudiKernel/DeclareFactoryEntries.h"
+#include "TrkG4UserActions/MaterialStepRecorder.h"
+#include "TrkG4UserActions/MaterialStepRecorderTool.h"
+
+//#include "TrkG4UserActions/EnergyLossRecorderTool.h"
+#include "TrkG4UserActions/GeantFollowerTool.h"
 #include "TrkG4UserActions/GeantFollowerHelper.h"
+#include "TrkG4UserActions/GeantFollowerMSTool.h"
 #include "TrkG4UserActions/GeantFollowerMSHelper.h"
-#include "TrkG4UserActions/MaterialStepRecorder.h"
-#include "TrkG4UserActions/EnergyLossRecorder.h"
-#include "TrkG4UserActions/GeantFollower.h"
-#include "TrkG4UserActions/GeantFollowerMS.h"
 
+DECLARE_TOOL_FACTORY( MaterialStepRecorder )
+DECLARE_TOOL_FACTORY( G4UA::MaterialStepRecorderTool )
+//DECLARE_TOOL_FACTORY( G4UA::EnergyLossRecorderTool )
 DECLARE_NAMESPACE_TOOL_FACTORY( Trk , GeantFollowerHelper )
+DECLARE_TOOL_FACTORY( G4UA::GeantFollowerTool )
 DECLARE_NAMESPACE_TOOL_FACTORY( Trk , GeantFollowerMSHelper )
-DECLARE_TOOL_FACTORY( MaterialStepRecorder )
-DECLARE_TOOL_FACTORY( EnergyLossRecorder )
-DECLARE_TOOL_FACTORY( GeantFollower )
-DECLARE_TOOL_FACTORY( GeantFollowerMS )
+DECLARE_TOOL_FACTORY( G4UA::GeantFollowerMSTool )
+
+DECLARE_FACTORY_ENTRIES( TrkG4UserActions ) {
+    DECLARE_TOOL( MaterialStepRecorder )
+    DECLARE_TOOL( G4UA::MaterialStepRecorderTool )
+    //    DECLARE_TOOL( G4UA::EnergyLossRecorderTool )
+    DECLARE_TOOL( G4UA::GeantFollowerTool )
+    DECLARE_NAMESPACE_TOOL( Trk , GeantFollowerHelper )
+    DECLARE_TOOL( G4UA::GeantFollowerMSTool )
+    DECLARE_NAMESPACE_TOOL( Trk , GeantFollowerMSHelper )
+}
-- 
GitLab