From c2ae4194e832cc31abba446bc7ea57828ddd91d9 Mon Sep 17 00:00:00 2001
From: Atlas-Software Librarian <Atlas-Software.Librarian@cern.ch>
Date: Fri, 8 Apr 2016 18:06:40 +0200
Subject: [PATCH] 'CMakeLists.txt' (TrkExEngine-00-00-34)

           * Found a bug in the initialization of the back extrapolation
           * tag TrkExEngine-00-00-34

2015-07-27 Andreas Salzburger < Andreas.Salzburger -at- cern.ch >
           * evaluation of approach surface in layer loop
           * tag TrkExEngine-00-00-33

2015-07-20 Noemi Calace <noemi.calace@cern.ch>
           * setting the initial radial direction
           * tag TrkExEngine-00-00-32

2015-07-14 Andreas Salzburger < Andreas.Salzburger -at- cern.ch >
           * introducing radialDirection concept
           * tag TrkExEngine-00-00-31

2015-07-08 Andreas Salzburger < Andreas.Salzburger -at- cern.ch >
           * removed commented-out lines
           * tag TrkExEngine-00-00-30

2015-07-07 Noemi Calace <noemi.calace@cern.ch>
...
(Long ChangeLog diff - truncated)
---
 .../TrkExEngine/CMakeLists.txt                |  38 +++
 .../TrkExEngine/ExtrapolationEngine.h         |  16 +-
 .../TrkExEngine/ExtrapolationEngine.icc       |  73 +++--
 .../TrkExEngine/ExtrapolationMacros.h         |  29 --
 .../TrkExEngine/MaterialEffectsEngine.h       |  12 +-
 .../TrkExEngine/PropagationEngine.h           |   4 +-
 .../TrkExEngine/TrkExEngine/StaticEngine.h    |   4 +-
 .../TrkExEngine/TrkExEngine/StaticEngine.icc  | 291 ++++++++++--------
 .../TrkExEngine/StaticNavigationEngine.h      |   4 +-
 .../TrkExEngine/StaticNavigationEngine.icc    |  46 ++-
 .../TrkExEngine/cmt/requirements              |   2 +-
 .../python/AtlasExtrapolationEngine.py        |   1 +
 .../TrkExEngine/src/ExtrapolationEngine.cxx   |  42 +--
 .../TrkExEngine/src/MaterialEffectsEngine.cxx | 129 ++++++--
 .../TrkExEngine/src/PropagationEngine.cxx     |  47 ++-
 .../TrkExEngine/src/StaticEngine.cxx          |  24 +-
 .../src/StaticNavigationEngine.cxx            |  17 +-
 17 files changed, 466 insertions(+), 313 deletions(-)
 create mode 100644 Tracking/TrkExtrapolation/TrkExEngine/CMakeLists.txt
 delete mode 100644 Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationMacros.h

diff --git a/Tracking/TrkExtrapolation/TrkExEngine/CMakeLists.txt b/Tracking/TrkExtrapolation/TrkExEngine/CMakeLists.txt
new file mode 100644
index 00000000000..054d1e7e788
--- /dev/null
+++ b/Tracking/TrkExtrapolation/TrkExEngine/CMakeLists.txt
@@ -0,0 +1,38 @@
+################################################################################
+# Package: TrkExEngine
+################################################################################
+
+# Declare the package name:
+atlas_subdir( TrkExEngine )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          Control/AthenaBaseComps
+                          DetectorDescription/GeoPrimitives
+                          GaudiKernel
+                          Tracking/TrkDetDescr/TrkDetDescrInterfaces
+                          Tracking/TrkDetDescr/TrkGeometry
+                          Tracking/TrkDetDescr/TrkSurfaces
+                          Tracking/TrkDetDescr/TrkVolumes
+                          Tracking/TrkEvent/TrkEventPrimitives
+                          Tracking/TrkEvent/TrkNeutralParameters
+                          Tracking/TrkEvent/TrkParameters
+                          Tracking/TrkExtrapolation/TrkExInterfaces
+                          Tracking/TrkExtrapolation/TrkExUtils
+                          PRIVATE
+                          Tracking/TrkDetDescr/TrkDetDescrUtils )
+
+# External dependencies:
+find_package( Eigen )
+
+# Component(s) in the package:
+atlas_add_component( TrkExEngine
+                     src/*.cxx
+                     src/components/*.cxx
+                     INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}
+                     LINK_LIBRARIES ${EIGEN_LIBRARIES} AthenaBaseComps GeoPrimitives GaudiKernel TrkDetDescrInterfaces TrkGeometry TrkSurfaces TrkVolumes TrkEventPrimitives TrkNeutralParameters TrkParameters TrkExInterfaces TrkExUtils TrkDetDescrUtils )
+
+# Install files from the package:
+atlas_install_headers( TrkExEngine )
+atlas_install_python_modules( python/*.py )
+
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.h
index 1ce41acc943..26e6b13c3dd 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.h
+++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.h
@@ -16,7 +16,7 @@
 // Trk
 #include "TrkDetDescrInterfaces/ITrackingGeometrySvc.h"
 #include "TrkExInterfaces/IExtrapolationEngine.h"
-#include "TrkExEngine/ExtrapolationMacros.h"
+#include "TrkExInterfaces/ExtrapolationMacros.h"
 #include "TrkExUtils/ExtrapolationCell.h"
 #include "TrkParameters/TrackParameters.h"
 #include "TrkNeutralParameters/NeutralParameters.h"
@@ -26,7 +26,8 @@
 namespace Trk {
   
   class TrackingGeometry;
-  
+  class IPropagationEngine;    
+
   /** @class ExtrapolationEngine 
       
       Master extrapolation engine for extrapolation through the TrackingGeometry,
@@ -62,13 +63,11 @@ namespace Trk {
         /** charged extrapolation - public interface */
         virtual ExtrapolationCode extrapolate(ExCellCharged& ecCharged,
                                               const Surface* sf = 0,
-                                              PropDirection dir=alongMomentum,
                                               BoundaryCheck bcheck = true) const;
 
         /** neutral extrapolation - public interface */
         virtual ExtrapolationCode extrapolate(ExCellNeutral& ecNeutral,
                                               const Surface* sf = 0,
-                                              PropDirection dir=alongMomentum,
                                               BoundaryCheck bcheck = true) const;
                          
                          
@@ -99,9 +98,10 @@ namespace Trk {
         std::string                                         m_trackingGeometryName;      //!< Name of the TrackingGeometry as given in Detector Store
         
         //!< the tool handle array for static / dense / detached
-        ToolHandleArray<IExtrapolationEngine>               m_extrapolationEngines;
-        std::vector<const IExtrapolationEngine*>            m_eeAccessor;     
-                                             
+        ToolHandleArray<IExtrapolationEngine>               m_extrapolationEngines;      //!< the extrapolation engines for retrieval
+        ToolHandle<IPropagationEngine>                      m_propagationEngine;         //!< the used propagation engine for navigation initialization
+        std::vector<const IExtrapolationEngine*>            m_eeAccessor;                //!< the extrapolation engines for 
+
         //!< forces a global search for the initialization, allows to switch TrackingGeometries in one job
         bool                                                m_forceSearchInit; 
     
@@ -113,7 +113,7 @@ namespace Trk {
 
   inline const Trk::TrackingGeometry& ExtrapolationEngine::trackingGeometry() const throw (GaudiException) {
       if (!m_trackingGeometry && updateTrackingGeometry().isFailure()){
-          ATH_MSG_ERROR("Could not load TrackingGeometry with name '" << m_trackingGeometryName << "'. Aborting." );
+          EX_MSG_FATAL("", "updateGeo", "", "Could not load TrackingGeometry with name '" << m_trackingGeometryName << "'. Aborting." );
           throw GaudiException("ExtrapolationEngine", "Problem with TrackingGeometry loading.", StatusCode::FAILURE);
       }
       return (*m_trackingGeometry);
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.icc b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.icc
index 5eb5ce6b792..ded0f6ed7cc 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.icc
+++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationEngine.icc
@@ -11,6 +11,7 @@
 #include "TrkGeometry/TrackingGeometry.h"
 #include "TrkGeometry/TrackingVolume.h"
 #include "TrkGeometry/Layer.h"
+#include "TrkExInterfaces/IPropagationEngine.h"
 #include <iostream>
 #include <iomanip>
 
@@ -20,19 +21,21 @@ template <class T> Trk::ExtrapolationCode Trk::ExtrapolationEngine::extrapolateT
                                                                                  Trk::BoundaryCheck bcheck) const
 {
                                                               
-    EX_MSG_DEBUG(++eCell.navigationStep, "starting extrapolation sequence."); 
+    EX_MSG_DEBUG(eCell.navigationStep, "extrapolate", "", "starting extrapolation sequence."); 
     // initialize the navigation
     Trk::ExtrapolationCode eCode = initNavigation<T>(eCell,sf,dir);
-    EX_MSG_VERBOSE(eCell.navigationStep, "initialize navigation return code : " << eCode.toString() );
+    EX_MSG_VERBOSE(eCell.navigationStep, "extrapolate", "", "initialize navigation with return code : " << eCode.toString() );
     // main loop over volumes 
     while (eCell.leadVolume && eCode == Trk::ExtrapolationCode::InProgress ){
+        // give output that you are in the master volume loop
+        EX_MSG_VERBOSE(eCell.navigationStep, "extrapolate", "loop", "processing volume : " << eCell.leadVolume->volumeName() );
         // get the appropriate IExtrapolationEngine
         const Trk::IExtrapolationEngine* iee = m_eeAccessor[eCell.leadVolume->geometryType()];
-        eCode = iee ? iee->extrapolate(eCell, sf, dir, bcheck) : Trk::ExtrapolationCode::FailureConfiguration;
+        eCode = iee ? iee->extrapolate(eCell, sf, bcheck) : Trk::ExtrapolationCode::FailureConfiguration;
         // give a message about what you have
-        EX_MSG_VERBOSE(eCell.navigationStep, "returned from volume return code : " << eCode.toString() );
+        EX_MSG_VERBOSE(eCell.navigationStep, "extrapolate", "", "returned from volume with return code : " << eCode.toString() );
     }
-    EX_MSG_DEBUG(eCell.navigationStep, "extrapolation finished return code : " << eCode.toString() );
+    EX_MSG_DEBUG(eCell.navigationStep, "extrapolate", "", "extrapolation finished with return code : " << eCode.toString() );
     // before you return, finalize: sets the leadParameters to endParameters and empties the garbage bin
     eCell.finalize(eCode);
     // return the code                                                               
@@ -48,12 +51,16 @@ template <class T> Trk::ExtrapolationCode Trk::ExtrapolationEngine::initNavigati
     //
     // this is the global initialization, it only associated direct objects
     // detailed navigation search needs to be done by the sub engines (since they know best)
-    EX_MSG_DEBUG(++eCell.navigationStep, "initialize the navigation stream."); 
+    EX_MSG_DEBUG(++eCell.navigationStep, "navigation", "", "initialize the navigation stream."); 
+    // initialization of the navigation requires that leadParameters to be the startParameters
+    eCell.leadParameters = eCell.startParameters;
+    // now check the tracking geometry and retrieve it if not existing
     if (!m_trackingGeometry && updateTrackingGeometry().isFailure()){
-	    EX_MSG_WARNING(eCell.navigationStep, "could not retrieve TrackingGeometry. Stopping."); 
-            return Trk::ExtrapolationCode::FailureConfiguration;
+	    EX_MSG_WARNING(eCell.navigationStep, "navigation", "", "could not retrieve geometry. Stopping."); 
+        // configuration error
+        return Trk::ExtrapolationCode::FailureConfiguration;
     } else
-      EX_MSG_DEBUG("navi", "successfully retrieved TrackingGeometry.");    
+      EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "geometry ready to use.");    
     // ---------- START initialization -----------------------------------------------------------------------------------------
     // initialize the start parameters - try association first
     eCell.startLayer  = eCell.startLayer ? eCell.startLayer : eCell.leadParameters->associatedSurface().associatedLayer();
@@ -62,42 +69,60 @@ template <class T> Trk::ExtrapolationCode Trk::ExtrapolationEngine::initNavigati
     // bail out of the start volume can not be resolved
     if (!eCell.startVolume) return Trk::ExtrapolationCode::FailureNavigation;
     // screen output
-    EX_MSG_VERBOSE( eCell.navigationStep, "start volume termined as '" << eCell.startVolume->volumeName() << "'." );
-    // check if the parameters are on a volume boundary - @TODO identify this case by something like eCell.leadParameters->associatedSurface().isBoundary()
+    EX_MSG_VERBOSE( eCell.navigationStep, "navigation", "", "start volume termined as : " << eCell.startVolume->volumeName() );
+    // check if the parameters are on a volume boundary 
+    // - @TODO identify this case by something like eCell.leadParameters->associatedSurface().isBoundary()
     if ( eCell.startVolume->onVolumeBoundary(*eCell.startParameters) ){
         // re-evaluate the volume by stepping out of the volume
-        EX_MSG_VERBOSE( eCell.navigationStep, "parameters are on volume boundary, stepping out of this TrackingVolume." );
+        EX_MSG_VERBOSE( eCell.navigationStep, "navigation", "", "parameters are on volume boundary, stepping out of this volume." );
         // stepping by one unit out of the volume
         eCell.startVolume = m_trackingGeometry->lowestTrackingVolume(eCell.leadParameters->position()+dir*eCell.leadParameters->momentum().unit());
-        // 
-        EX_MSG_VERBOSE( eCell.navigationStep, "start volume re-evaluated as '" << eCell.startVolume->volumeName() << "'." );
+        // screen output 
+        EX_MSG_VERBOSE( eCell.navigationStep, "navigation", "", "start volume re-evaluated as : " << eCell.startVolume->volumeName());
     }
     eCell.startLayer     = eCell.startLayer ? eCell.startLayer : eCell.startVolume->associatedLayer(eCell.leadParameters->position());
+    if (eCell.startLayer)
+       EX_MSG_VERBOSE( eCell.navigationStep, "navigation", "", "start layer termined with index : " << eCell.startLayer->layerIndex());
     // now you can assign the lead volume    
     eCell.leadVolume     = eCell.startVolume;  
+    eCell.setRadialDirection();      
     // ---------- END initialization -----------------------------------------------------------------------------------------
     if (sf){
       // keep track of the end surface    
       eCell.endSurface = sf;
+      // re-evaluate the radial direction if the end surface is given
+      // should not happen in FATRAS extrapolation mode
+      if ( !eCell.checkConfigurationMode(Trk::ExtrapolationMode::FATRAS) )
+          eCell.setRadialDirection();
       // trying association via the layer : associated layer of material layer 
       eCell.endLayer  = sf ? ( sf->associatedLayer() ? sf->associatedLayer() : sf->materialLayer() ) : 0;    
       eCell.endVolume = eCell.endLayer ? eCell.endLayer->enclosingTrackingVolume() : 0;
       // check if you found layer and volume
       if (!eCell.endVolume){
-          EX_MSG_VERBOSE( eCell.navigationStep, "end volume needs to be determinded by surface intersection." );
-          // make a straight line intersection
-          Trk::Intersection sfI = (dir == Trk::alongMomentum) ?
-                 sf->straightLineIntersection(eCell.leadParameters->position(), eCell.leadParameters->momentum().unit(), true) :
-                 sf->straightLineIntersection(eCell.leadParameters->position(), -1*(eCell.leadParameters->momentum().unit()), true);
-          // use this to find endVolume and endLayer
-          eCell.endVolume = trackingGeometry().lowestTrackingVolume(sfI.position);                 
-          eCell.endLayer  = eCell.endLayer ? eCell.endLayer : trackingGeometry().associatedLayer(sfI.position);
+          EX_MSG_VERBOSE( eCell.navigationStep, "navigation", "", "end volume needs to be determinded by surface intersection." );
+          // use a propagation to find the endVolume and endLayer
+          // - @TODO can be opmisied (straiht line for high momentum - use directly )
+          Trk::ExtrapolationCell<T> navCell(*eCell.leadParameters, dir);
+          navCell.addConfigurationMode(Trk::ExtrapolationMode::Direct);
+          // screen output
+          Trk::ExtrapolationCode eCode = m_propagationEngine->propagate(navCell,*eCell.endSurface,Trk::anyDirection,true,eCell.navigationCurvilinear);
+          // check for sucess to the destination
+          CHECK_ECODE_SUCCESS_NODEST(navCell, eCode);
+          // screen output 
+          EX_MSG_VERBOSE (eCell.navigationStep, "navigation", "", "found endVolume and andLayer through propagation - return code : " << eCode.toString() );
+          // take the lead parameters to find end volume and end layer
+	  eCell.endVolume = trackingGeometry().lowestTrackingVolume(navCell.endParameters->position());
+	  eCell.endLayer  = trackingGeometry().associatedLayer(navCell.endParameters->position());
+	  // memory cleanup
+          delete navCell.endParameters;
       } 
       // check the final end volume configuraiton - screen output
       if (eCell.endVolume)
-          EX_MSG_VERBOSE( eCell.navigationStep, "end volume termined as '" << eCell.endVolume->volumeName() << "'." );
+          EX_MSG_VERBOSE( eCell.navigationStep, "navigation", "", "end volume termined as : " << eCell.endVolume->volumeName());
+      if (eCell.endLayer)
+          EX_MSG_VERBOSE( eCell.navigationStep, "navigation", "", "end layer termined with index : " << eCell.endLayer->layerIndex());
     } else 
-        EX_MSG_VERBOSE( eCell.navigationStep, "no destination surface nor end volume provided, extrapolaiton has to stop on other means." );
+        EX_MSG_VERBOSE( eCell.navigationStep, "navigation", "", "no destination surface nor end volume provided, extrapolaiton has to stop on other means." );
     // return the progress call
     return Trk::ExtrapolationCode::InProgress;                                                          
                                                               
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationMacros.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationMacros.h
deleted file mode 100644
index bf1ab8d5e55..00000000000
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/ExtrapolationMacros.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-///////////////////////////////////////////////////////////////////
-// IExtrapolationMacros.h, (c) ATLAS Detector software
-///////////////////////////////////////////////////////////////////
-
-
-#ifndef EXSCREENOUTPUTDEFS
-#define EXSCREENOUTPUTDEFS 1
-#define EX_MSG_INFO(nav, x)    ATH_MSG_INFO(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x)
-#define EX_MSG_DEBUG(nav, x)   ATH_MSG_DEBUG(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x)
-#define EX_MSG_VERBOSE(nav, x) ATH_MSG_VERBOSE(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x)
-#define EX_MSG_WARNING(nav, x) ATH_MSG_WARNING(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x)
-#define EX_MSG_FATAL(nav, x)   ATH_MSG_FATAL(m_sopPrefix << std::setw(4) << nav << m_sopPostfix << x)
-#endif
-
-#ifndef TRKEXENINGE_OUTPUTHELPER 
-#define TRKEXENINGE_OUTPUTHELPER 
-#define OH_CHECKFOUND(object) ( object ? "found" : "not found")
-#endif
-
-#ifndef TRKEXENGINE_EXCODECHECKS
-#define TRKEXENGINE_EXCODECHECKS
-#define CHECK_ECODE_CONTINUE(ecell, ecode) if (!ecode.inProgress()) { EX_MSG_VERBOSE(ecell.navigationStep, ecode.toString() << " triggers return."); return ecode; }
-#define CHECK_ECODE_SUCCESS(ecell, ecode) if (ecode.isSuccess()) { EX_MSG_VERBOSE(ecell.navigationStep, ecode.toString() << " stops extrapolation sequence."); return ecode; }
-#endif
-
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/MaterialEffectsEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/MaterialEffectsEngine.h
index 11c2e70402f..0d4b0e2e5a4 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/MaterialEffectsEngine.h
+++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/MaterialEffectsEngine.h
@@ -13,7 +13,7 @@
 #include "AthenaBaseComps/AthAlgTool.h"
 // Trk
 #include "TrkExInterfaces/IMaterialEffectsEngine.h"
-#include "TrkExEngine/ExtrapolationMacros.h"
+#include "TrkExInterfaces/ExtrapolationMacros.h"
 #include "TrkExUtils/ExtrapolationCell.h"
 #include "TrkExUtils/MaterialInteraction.h"
 #include "TrkExUtils/MaterialUpdateMode.h"
@@ -56,9 +56,9 @@ namespace Trk {
                                                MaterialUpdateStage matupstage=fullUpdate) const;
 
       /** neutral extrapolation - only for Fatras, dummy implementation here */
-      virtual ExtrapolationCode handleMaterial(ExCellNeutral&,
-                                               PropDirection,
-                                               MaterialUpdateStage) const {return Trk::ExtrapolationCode::InProgress; }
+      virtual ExtrapolationCode handleMaterial(ExCellNeutral& ecNeutral,
+                                               PropDirection dir=alongMomentum,
+                                               MaterialUpdateStage matupstage=fullUpdate) const;
       
     protected:
       /** charged extrapolation */
@@ -69,7 +69,9 @@ namespace Trk {
         
       MaterialInteraction                          m_interactionFormulae;     //!< the formulas concentrated
       ParticleMasses                               m_particleMasses;          //!< struct of Particle masses   
-        
+      bool                                         m_eLossCorrection;         //!< apply the energy loss correction
+      bool                                         m_eLossMpv;                //!< apply the energy loss correction as most probable value
+      bool                                         m_mscCorrection;           //!< apply the multiple (coulomb) scattering correction
 
   };
       
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/PropagationEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/PropagationEngine.h
index 73fe210878d..793c5104a23 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/PropagationEngine.h
+++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/PropagationEngine.h
@@ -14,7 +14,7 @@
 #include "GaudiKernel/ToolHandle.h"
 // Trk
 #include "TrkExInterfaces/IPropagationEngine.h"
-#include "TrkExEngine/ExtrapolationMacros.h"
+#include "TrkExInterfaces/ExtrapolationMacros.h"
 #include "TrkExUtils/ExtrapolationCell.h"
 #include "TrkEventPrimitives/PropDirection.h"
 #include "TrkParameters/TrackParameters.h"
@@ -56,7 +56,7 @@ namespace Trk {
                                           const Surface& sf,
                                           PropDirection dir=alongMomentum,
                                           BoundaryCheck bcheck = true,
-                                          bool returnCurvilinear = true) const;                                                                                         
+                                          bool returnCurvilinear = true) const;  
 
       /** resolve the boundary situation - for neutral particles */
       virtual ExtrapolationCode propagate(ExCellNeutral& enCell,
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.h
index bc81f5102f4..325b6f96459 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.h
+++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.h
@@ -19,8 +19,8 @@
 #include "GaudiKernel/ToolHandle.h"
 // Trk
 #include "TrkExInterfaces/IExtrapolationEngine.h"
+#include "TrkExInterfaces/ExtrapolationMacros.h"
 #include "TrkExUtils/ExtrapolationCell.h"
-#include "TrkExEngine/ExtrapolationMacros.h"
 #include "TrkParameters/TrackParameters.h"
 #include "TrkNeutralParameters/NeutralParameters.h"
 
@@ -78,14 +78,12 @@ namespace Trk {
         /** charged extrapolation - public interface */
         virtual ExtrapolationCode extrapolate(ExCellCharged& ecCharged,
                                               const Surface* sf = 0,
-                                              PropDirection dir=alongMomentum,
                                               BoundaryCheck bcheck = true) const;
 
 
         /** neutral extrapolation - public interface */
         virtual ExtrapolationCode extrapolate(ExCellNeutral& ecNeutral,
                                               const Surface* sf = 0,
-                                              PropDirection dir=alongMomentum,
                                               BoundaryCheck bcheck = true) const;
                          
         /** define for which GeometrySignature this extrapolator is valid - this is GLOBAL */
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.icc b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.icc
index f41651fbac1..81540dca147 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.icc
+++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticEngine.icc
@@ -21,19 +21,18 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::extrapolateT(Trk::E
                                                                           Trk::PropDirection pDir,
                                                                           Trk::BoundaryCheck bcheck) const
 {
-                                                              
     Trk::ExtrapolationCode eCode = Trk::ExtrapolationCode::InProgress;
     // ---- [0] check the direct propagation exit
     // 
     //  obviously need a surface to exercise the fallback & need to be configured to do so
     if (sf && eCell.checkConfigurationMode(Trk::ExtrapolationMode::Direct)){
-        EX_MSG_DEBUG(++eCell.navigationStep, "direct extapolation in volume " << eCell.leadVolume->volumeName()); 
+        EX_MSG_DEBUG(++eCell.navigationStep, "extrapolate", "", "direct extapolation in volume : " << eCell.leadVolume->volumeName()); 
         // propagate to the surface, possible return codes are : SuccessPathLimit, SucessDestination, FailureDestination
         eCode = m_propagationEngine->propagate(eCell,*sf,pDir,bcheck,eCell.destinationCurvilinear);
         // eCode can be directly returned
         return eCode;
     }
-    EX_MSG_DEBUG(++eCell.navigationStep, "extrapolation in static environment in volume " << eCell.leadVolume->volumeName()); 
+    EX_MSG_DEBUG(++eCell.navigationStep, "extrapolate", "", "extrapolation in static environment in volume : " << eCell.leadVolume->volumeName()); 
     // evoke or finish the navigation initialization, possible return codes are: 
     // - InProgress        : everything is fine, extrapolation in static volume is in progress 
     // - FailureNavigation : navigation setup could not be resolved, but reovery was not configured
@@ -45,7 +44,7 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::extrapolateT(Trk::E
     // - this case does not need a layer to layer loop
     if (sf && eCell.leadLayer == eCell.endLayer && eCell.initialVolume()){
         // screen output for startLayer == endLayer 
-        EX_MSG_VERBOSE(eCell.navigationStep, "start and destination layer are identical -> jumping to final propagation."); 
+        EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "start and destination layer are identical -> jumping to final propagation."); 
         // set the leadLayerSurface to the parameters surface
         eCell.leadLayerSurface = &(eCell.leadParameters->associatedSurface()); 
         // resolve the layer, it is the final extrapolation 
@@ -61,7 +60,7 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::extrapolateT(Trk::E
                                   (eCell.leadLayer == eCell.startLayer && eCell.leadVolume == eCell.startVolume),
                                   true);
          // Success triggers a return
-         CHECK_ECODE_SUCCESS(eCell, eCode);
+         CHECK_ECODE_SUCCESS_NODEST(eCell, eCode);
          // extrapolation to destination was not successful
          // - handle the return as configured (e.g. fallback)                                           
          return handleReturnT<T>(eCode, eCell, sf, pDir, bcheck);        
@@ -69,31 +68,37 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::extrapolateT(Trk::E
     // ----- [2] now do the layer-to-layer loop 
     //
     // the volume returns the layers ordered by distance :
-    // -  give potential start and end layer (latter only for the final volume)
-    // - start and end layer will be part of the loop
+    // - give potential start and end layer (latter only for the final volume)
+    // - start and end layer will be part of the loop 
+    // - surface on approach is not yet resolved
     const Trk::Layer* fLayer = eCell.finalVolumeReached() ? eCell.endLayer  : 0;   
     auto layerIntersections = eCell.leadVolume->materialLayersOrdered(eCell.leadLayer, fLayer,
                                                                       *eCell.leadParameters,
                                                                       pDir,
-                                                                      true,
-                                                                      eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectSensitive));
-    EX_MSG_VERBOSE(eCell.navigationStep, "found a total of " << layerIntersections.size() << " layers for the layer-to-layer loop.");
+                                                                      true);
+                                                                      
+    EX_MSG_VERBOSE(eCell.navigationStep, "layer", "loop", "found " << layerIntersections.size() << " layers for the layer-to-layer loop.");
     // layer-to-layer loop starts here 
     for (auto& layerCandidate : layerIntersections ) {
          // assign the leadLayer 
          eCell.leadLayer        = layerCandidate.object;
          // screen output for layer-to-layer loop
-         EX_MSG_VERBOSE(eCell.navigationStep, "layer-to-layer loop - processing layer with index : " << eCell.leadLayer->layerIndex().value());
-         // assign also the leadLayer surface
-         // -  it is the approaching surface for all layers but the very first one (where it's the parameter surface)
-         eCell.leadLayerSurface = (eCell.leadLayer == eCell.startLayer) ? &(eCell.leadParameters->associatedSurface()) : layerCandidate.representation; 
+         EX_MSG_VERBOSE(eCell.navigationStep, "layer", "loop", "processing layer with index : " << eCell.leadLayer->layerIndex().value());
+         // resolve the approach surface situation
+         // -  it is the approaching surface for all layers but the very first one (where it's the parameter surface)         
+         eCell.leadLayerSurface = (eCell.leadLayer == eCell.startLayer) ? &(eCell.leadParameters->associatedSurface()) : 
+                                                                          &(eCell.leadLayer->surfaceOnApproach(eCell.leadParameters->position(),
+                                                                                                               eCell.leadParameters->momentum(),
+                                                                                                               pDir,
+                                                                                                               true,
+                                                                                                               true));
          // handle the layer, possible returns are :
          // - InProgress               : fine, whatever happened on the lead layer, may also be missed 
          // - SuccessWithPathLimit     : propagation towards layer exceeded path limit
          // - SuccessWithMaterialLimit : material interaction killed track
          // - FailureDestination       : destination was not hit appropriately
          eCode = handleLayerT<T>(eCell, sf, pDir, bcheck);
-         EX_MSG_VERBOSE(eCell.navigationStep, "handleLayerT returned extrapolation code " << eCode.toString());
+         EX_MSG_VERBOSE(eCell.navigationStep, "layer", layerCandidate.object->layerIndex().value(), "handleLayerT returned extrapolation code : " << eCode.toString());
          // Possibilities are:
          // - SuccessX  -> return (via handleReturnT)
          // - FailureX  -> return (via handleReturnT that might evoke a fallback)
@@ -109,7 +114,7 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::extrapolateT(Trk::E
     // - FailureLoop/Navigation       : problem in boundary resolving  
     eCode = m_navigationEngine->resolveBoundary(eCell, pDir);
     // SuccessX and FailureX trigger a return
-    CHECK_ECODE_SUCCESS(eCell, eCode);
+    CHECK_ECODE_SUCCESS_NODEST(eCell, eCode);
     // handle the return of the boudnary resolving                                                          
     return handleReturnT<T>(eCode, eCell, sf, pDir, bcheck);                                                                                                                 
 }
@@ -123,27 +128,27 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::initNavigationT(Trk
     //
     // this is the global initialization, it only associated direct objects
     // detailed navigation search needs to be done by the sub engines (since they know best)
-    EX_MSG_DEBUG(++eCell.navigationStep, "complete navigation initialization for static environment.");    
-    // [1] the initial volume 
+    EX_MSG_DEBUG(++eCell.navigationStep, "navigation", "", "complete for static environment.");    
+    // [A] the initial volume 
     if (eCell.startVolume == eCell.leadVolume && eCell.startLayer) {
         // - found the initial start layer through association
-        EX_MSG_VERBOSE(eCell.navigationStep, "initial volume, everything set up already.");
+        EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "this is the initial volume, everything set up already.");
         // assigning it to the leadLayer
         eCell.leadLayer = eCell.startLayer;
         // return progress
         return Trk::ExtrapolationCode::InProgress;
     }     
-    // [2] any volume if we don't have a leadLayer
+    // [B] any volume if we don't have a leadLayer
     if (!eCell.leadLayer){
         // - finding it through global search, never a boundary layer ... convention says that you update by exit
         eCell.leadLayer = eCell.leadVolume->associatedLayer(eCell.leadParameters->position());
-        EX_MSG_VERBOSE(eCell.navigationStep, "no start layer found yet, looking for it ..." << OH_CHECKFOUND(eCell.leadLayer) );
+        EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "no start layer found yet, looking for it ..." << OH_CHECKFOUND(eCell.leadLayer) );
     } 
-    // [3] the final volume - everything's fine 
+    // [C] the final volume - everything's fine 
     if (eCell.leadVolume == eCell.endVolume && sf) {
         if (eCell.endLayer) {
           // the end layer had been found already by association
-          EX_MSG_VERBOSE(eCell.navigationStep, "final volume, everything set up already.");
+	  EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "this is the final volume, everything set up already.");
           return Trk::ExtrapolationCode::InProgress;
         } else {
             // make a straight line intersection
@@ -165,14 +170,14 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::handleLayerT(Trk::E
                                                                           Trk::BoundaryCheck bcheck) const 
 {   
     Trk::ExtrapolationCode eCode = Trk::ExtrapolationCode::InProgress;
-    EX_MSG_DEBUG(++eCell.navigationStep, "handle a new layer with layer index " << eCell.leadLayer->layerIndex().value()); 
+    EX_MSG_DEBUG(++eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "handle this layer" ); 
     // layer has sub structure - this can be (and the layer will tell you):  
     //      - sensitive surface which should be tried to hit
     //      - material sub structure to be resolved (independent of sensitive surface)
     bool hasSubStructure = eCell.leadLayer->hasSubStructure(eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectSensitive));
     // [A] layer is a pure navigation layer and has no sub structure -> skip it, but only if it is not the final layer
     if (!hasSubStructure && !eCell.leadLayer->layerIndex().value() && eCell.leadLayer != eCell.endLayer){
-        EX_MSG_VERBOSE(eCell.navigationStep, "this layer is a navigation layer -> skipping it ...");   
+        EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "layer is a navigation layer -> skipping it ...");   
         return Trk::ExtrapolationCode::InProgress;
     }
     // [B] layer resolving is necessary -> resolve it 
@@ -180,47 +185,46 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::handleLayerT(Trk::E
     //      - sensitive surface which should be tried to hit
     //      - material sub structure to be resolved (independent of sensitive surface)
     // - (b) layer is start layer (can not be if there was a volume switch)
-        bool isStartLayer       = eCell.initialVolume() && eCell.leadLayer->onLayer(*eCell.leadParameters); 
+    bool isStartLayer       = eCell.initialVolume() && eCell.leadLayer->onLayer(*eCell.leadParameters); 
     // - (c) layer is destination layer 
     //      - final propagation to the layer and update if necessary
     bool isDestinationLayer = (sf && eCell.leadLayer == eCell.endLayer);
-    //      - postUpdate if necessary
+    //  sub structure, start and destination need resolving of the layer setp
     if (hasSubStructure || isStartLayer || isDestinationLayer ){
         // screen output for sub strucutred layer
-        EX_MSG_VERBOSE(eCell.navigationStep, "this layer has sub structure, is start layer, or destination layer -> resolving it ..." );
+        EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "has sub structure, is start layer, or destination layer -> resolving it ..." );
         // resolve the layer, it handles all possible return types and gives them directly to extrapolateT<T>
         // - InProgress           : layer resolving went without problem
         // - SuccessPathLimit     : path limit reached & configured to stop 
         // - SuccessMaterialLimit : material limit reached & configured to stop there
+        // - SuccessDestination   : destination reached & everything is fine
         return resolveLayerT<T>(eCell,sf,pDir,bcheck,hasSubStructure,isStartLayer,isDestinationLayer);
     }
     // [C] layer is a material layer without sub structure but material -> pass through
     // no resolving ob sub structure to be done, an intermediate layer to be crossed
-    EX_MSG_VERBOSE(eCell.navigationStep, "this layer is an intermediate layer without sub structure ->  passing through ...");   
+    EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "intermediate layer without sub structure ->  passing through ...");   
     //    propagate to it, possible return codes ( with the default of finalPropagation = false):
     //    - SuccessPathLimit       : propagation to layer exceeded path limit
     //    - InProgress             : layer was hit successfuly, try to handle the material and sub structure, these are new parameters
     //    - Recovered              : layer was not hit, so can be ignored in the layer to layer loop 
     eCode = m_propagationEngine->propagate(eCell,*eCell.leadLayerSurface,pDir,true,eCell.navigationCurvilinear);
-    // check if success was triggered through path limit reached on the way to the layer
-    CHECK_ECODE_SUCCESS(eCell, eCode);
+    CHECK_ECODE_SUCCESS_NODEST(eCell, eCode);
     // check if the layer was actually hit
     if (eCode.inProgress()){
         // successful layer hit 
-        EX_MSG_VERBOSE(eCell.navigationStep, "the layer has been succesful hit ");
+        EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "has been succesful hit, handling material update.");
         // layer has no sub-structure : it is an intermediate layer that just needs pass-throgh
         // return possbilities:
         // - InProgress            : material update performed or not (depending on material)
         // - SuccessMaterialLimit  : material limit reached & configured to stop there
         eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate);
-        // check if success was triggered through material limit reached when updating
         CHECK_ECODE_CONTINUE(eCell, eCode);
         // record the passive parameters
         eCell.stepParameters(eCell.leadParameters, Trk::ExtrapolationMode::CollectPassive);
         // return the progress eCode back to the extrapolateT
         return eCode;
     }    
-    // hit or not hit ... it's always in progress since we are in the layer to layer loop
+    // hit or not hit : it's always in progress since we are in the layer to layer loop
     return Trk::ExtrapolationCode::InProgress;                                                                             
 }  
 
@@ -235,91 +239,116 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::resolveLayerT(Trk::
                                                                            bool isDestinationLayer) const 
 {
     Trk::ExtrapolationCode eCode = Trk::ExtrapolationCode::InProgress;
-    EX_MSG_DEBUG(++eCell.navigationStep, "resolve layer with" << (hasSubStructure ? " " : "out ") << "sub structure" 
-       <<  (isDestinationLayer ? " -> destination layer." : "") ); 
-
-    // cache the leadLayer - needed for the layer-to-layer loop not to be broken
+    EX_MSG_DEBUG(++eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "resolve it with" << (hasSubStructure ? " " : "out ") << "sub structure" 
+       <<  (isDestinationLayer ? " -> destination layer." : (isStartLayer ? " -> start layer." : "") ) ); 
+    
+    // cache the leadLayer - this is needed for the layer-to-layer loop not to be broken
     const Trk::Layer* initialLayer = eCell.leadLayer;
-        
-    // [A] the sub structure of the layer needs to be resolved:
+    // ----- [0] the start situation on the layer needs to be resolved:
     // - either for sensitive parameters
     // - or for material substructure
-    if (hasSubStructure){
-        // if the layer is not the start layer - let us propagate to it
-        // - the surfaceOnApproach() call should have sorted out that this is actually an approaching representation
-        if (!isStartLayer){
-           EX_MSG_VERBOSE(eCell.navigationStep, "this is not the start layer, propagate to it."); 
-           // propagate to the representing surface of this layer
-           // - InProgress       : propagation to approaching surface worked - check material update
-           // - SuccessPathLimit : propagation to approaching surface reached the path limit
-           // - Recovered        : layer was not hit, so can be ignored in the layer to layer loop 
-           eCode =  m_propagationEngine->propagate(eCell,*eCell.leadLayerSurface,pDir,true,eCell.sensitiveCurvilinear);  
-           CHECK_ECODE_SUCCESS(eCell,eCode);
-           // the extrapolation to the initial layer did not succeed - skip this layer in the layer-to-layer loop 
-           if (eCode == Trk::ExtrapolationCode::Recovered) return Trk::ExtrapolationCode::InProgress;
-           // fill the corresponding parameters, the material effects updator can attach material to them
-           eCell.stepParameters(eCell.leadParameters, Trk::ExtrapolationMode::CollectPassive);
-           // the correct material layer needs to be assigned
-           if (eCell.leadLayerSurface->materialLayer()){
+    // [A] the layer is not the start layer and not the destination layer 
+    // - the surfaceOnApproach() call should have sorted out that this is actually an approaching representation
+    // - the destination layer is excluded from the propagation because it can lead to punch-through to the other side of layers
+    if (!isStartLayer && !isDestinationLayer){
+       EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "not the start layer (with sub structue), propagate to it."); 
+       // propagate to the representing surface of this layer
+       // - InProgress       : propagation to approaching surface worked - check material update
+       // - SuccessPathLimit : propagation to approaching surface reached the path limit
+       // - Recovered        : layer was not hit, so can be ignored in the layer to layer loop 
+       eCode =  m_propagationEngine->propagate(eCell,*eCell.leadLayerSurface,pDir,true,eCell.sensitiveCurvilinear);  
+       CHECK_ECODE_SUCCESS_NODEST(eCell,eCode);
+       // the extrapolation to the initial layer did not succeed - skip this layer in the layer-to-layer loop 
+       if (eCode == Trk::ExtrapolationCode::Recovered) {
+           EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "has not been hit, skipping it."); 
+           return Trk::ExtrapolationCode::InProgress;
+       } 
+       EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "successfuly hit."); 
+       // fill the corresponding parameters, the material effects updator can attach material to them
+       eCell.stepParameters(eCell.leadParameters, Trk::ExtrapolationMode::CollectPassive);
+       // the correct material layer needs to be assigned - in case of the approach surface not being hit, his can be the layer surface
+       if (eCell.leadLayerSurface->materialLayer() ||
+          (eCell.leadLayerSurface == &(eCell.leadLayer->surfaceRepresentation()) && eCell.leadLayer->layerMaterialProperties())  ){
+           // screen output for debugging
+           EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "needs material update."); 
+           // assign the right lead layer for the material update
+           if (eCell.leadLayerSurface->materialLayer()) 
                eCell.leadLayer = eCell.leadLayerSurface->materialLayer(); 
-               // now handle the material, return codes are:
-               // - SuccessMaterialLimit : material limit reached, return back
-               // - InProgress           : material update done or not (depending on the material description)
-               eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate);
-               CHECK_ECODE_CONTINUE(eCell, eCode);
-           }
-        } // @TODO check postUpdate for start surface in sub structure environment
-        // resolve the substructure - the surfaces given by the layer, needs to be searched for with anyDirection 
-        std::vector<Trk::SurfaceIntersection> cSurfaces;
-        // this will give you the compatible up to the endSurface (without the endSurface (sf) if given)
-        // - leadParameters->associatedSurface() are included or not, depending if it is the startLayer or not 
-        size_t ncSurfaces = eCell.leadLayer->compatibleSurfaces(cSurfaces,
-                                                                *eCell.leadParameters,
-                                                                pDir,
-                                                                bcheck,
-                                                                (!isStartLayer ? eCell.leadLayerSurface : 0),
-                                                                (isDestinationLayer ? sf : 0) );
-        
-        EX_MSG_VERBOSE(eCell.navigationStep, "found " <<  ncSurfaces << " candidate sensitive surfaces to test."); 
-        // check if you have to do something
-        if (ncSurfaces){
-            // now loop over the surfaces:
-            // the surfaces will be sorted @TODO integrate pathLength propagation into this
-            for (auto& csf : cSurfaces ) {
-                EX_MSG_VERBOSE(eCell.navigationStep, "trying candidate surfaces with straight line path length " << csf.intersection.pathLength); 
-                // propagate to the compatible surface, return types are (pathLimit failure is excluded by Trk::anyDirection for the moment):
-                // - InProgress : propagation to compatible surface worked
-                // - Recovered  : propagation to compatible surface did not work, leadParameters stay the same
-                // eCode =  m_propagationEngine->propagate(eCell,*(csf.object),pDir,true,eCell.sensitiveCurvilinear);
-                eCode =  m_propagationEngine->propagate(eCell,*(csf.object),pDir,true,eCell.sensitiveCurvilinear);
-                
-                // check if the propagation was successful 
-                if (eCode.inProgress()){
-                    EX_MSG_VERBOSE(eCell.navigationStep, "successfully hit sub structure surface."); 
-                    // record the parameters as sensitive or passive depending on the surface
-                    Trk::ExtrapolationMode::eMode emode =  csf.object->isActive() ? Trk::ExtrapolationMode::CollectSensitive : Trk::ExtrapolationMode::CollectPassive;
-                    // fill the corresponding parameters, the material effects updator can attach material to them
-                    eCell.stepParameters(eCell.leadParameters, emode);
-                    // check if the surface holds a material layer 
-                    // - yes  : it is a sub surface that has a material layer attached
-                    // - no 1 : it is a sub surface and has no material attached
-                    // - no 2 : it is the representing layer for the material integration (this case can be caught by surface pointer comparison)
-                    if (csf.object->materialLayer() || ( csf.object->associatedLayer() && csf.object == &(csf.object->associatedLayer()->surfaceRepresentation()) ) ) {
-                        // the resolved surface has material, set the leadLayer to 
-                        // - the materialLayer ( has higher priority than the associatedLayer() )
-                        // - the associatedLayer ( it is the representing layer )
-                        eCell.leadLayer      = csf.object->materialLayer() ? csf.object->materialLayer() : csf.object->associatedLayer();
-                        // now handle the material, return codes are:
-                        // - SuccessMaterialLimit : material limit reached,return back
-                        // - InProgress           : material update done or not (depending on the material description)
-                        eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate);
-                        CHECK_ECODE_CONTINUE(eCell, eCode);
-                    }
-                } 
-           } // loop over test surfaces done
-        } // there are compatible surfaces          
-    } 
-    
+           // now handle the material (full update when passing approach surface), return codes are:
+           // - SuccessMaterialLimit : material limit reached, return back
+           // - InProgress           : material update done or not (depending on the material description)
+           eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate);
+           CHECK_ECODE_CONTINUE(eCell, eCode);
+       }
+    } else if (isStartLayer) {
+       // [B] the layer is the start layer  
+       //  - let's check if a post update on the start surface has to be done 
+       EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "start layer (with sub structure), no propagation to be done."); 
+       // the start surface could have a material layer attached
+       if (eCell.leadParameters->associatedSurface().materialLayer()){
+           eCell.leadLayer = eCell.leadParameters->associatedSurface().materialLayer(); 
+           // now handle the material (post update on start layer), return codes are:
+           // - SuccessMaterialLimit : material limit reached, return back
+           // - InProgress           : material update done or not (depending on the material description)
+           eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::postUpdate);
+           CHECK_ECODE_CONTINUE(eCell, eCode);
+           // let's reset the lead layer
+           eCell.leadLayer = initialLayer;
+       }            
+     }
+    // ----- [1] the sub structure of the layer needs to be resolved:
+    // resolve the substructure
+    std::vector<Trk::SurfaceIntersection> cSurfaces;
+    // this will give you the compatible surfaces of the layer : provided start and destination surface are excluded
+    // - surfaces without material are only provided if they are active and CollectSensitive is configured
+    // - surfaces with material are provided in order to make the necessary material update
+    size_t ncSurfaces = eCell.leadLayer->compatibleSurfaces(cSurfaces,
+                                                            *eCell.leadParameters,
+                                                            pDir,
+                                                            bcheck,
+                                                            !eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectSensitive),
+                                                            (isStartLayer ? &(eCell.leadParameters->associatedSurface()) : eCell.leadLayerSurface),
+                                                            (isDestinationLayer ? sf : 0) );
+    // some screen output for the sub structure    
+    EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "found " <<  ncSurfaces << " sub structrue surfaces to test."); 
+    // check if you have to do something
+    if (ncSurfaces){
+        // now loop over the surfaces:
+        // the surfaces will be sorted
+        for (auto& csf : cSurfaces ) {
+            EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "trying candidate surfaces with straight line path length " << csf.intersection.pathLength); 
+            // propagate to the compatible surface, return types are 
+            // - InProgress       : propagation to compatible surface worked
+            // - Recovered        : propagation to compatible surface did not work, leadParameters stay the same
+            // - SuccessPathLimit : propagation to compatible surface reached the path limit
+            eCode =  m_propagationEngine->propagate(eCell,*(csf.object),pDir,true,eCell.sensitiveCurvilinear);
+            CHECK_ECODE_SUCCESS_NODEST(eCell,eCode);
+            // check if the propagation was successful 
+            if (eCode.inProgress()){
+                EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "successfully hit sub structure surface."); 
+                // record the parameters as sensitive or passive depending on the surface
+                Trk::ExtrapolationMode::eMode emode =  csf.object->isActive() ? Trk::ExtrapolationMode::CollectSensitive : Trk::ExtrapolationMode::CollectPassive;
+                // fill the corresponding parameters, the material effects updator can attach material to them
+                eCell.stepParameters(eCell.leadParameters, emode);
+                // check if the surface holds a material layer 
+                // - yes  : it is a sub surface that has a material layer attached
+                // - yes  : it is any other layer for the material integration
+                if (csf.object->materialLayer() || ( csf.object->associatedLayer() && csf.object == &(csf.object->associatedLayer()->surfaceRepresentation()) ) ) {
+                    // the resolved surface has material, set the leadLayer to 
+                    // - the materialLayer ( has higher priority than the associatedLayer() )
+                    // - the associatedLayer ( it is the representing layer )
+                    eCell.leadLayer      = csf.object->materialLayer() ? csf.object->materialLayer() : csf.object->associatedLayer();
+                    // now handle the material, return codes are:
+                    // - SuccessMaterialLimit : material limit reached,return back
+                    // - InProgress           : material update done or not (depending on the material description)
+                    eCode = m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::fullUpdate);
+                    CHECK_ECODE_CONTINUE(eCell, eCode);
+                }
+            } 
+       } // loop over test surfaces done
+    } // there are compatible surfaces          
+
+    // ----- [3] the destination situation on the layer needs to be resolved:
     // the layer is a destination layer
     // - the final propagation call is indepenent of whether sub structure was resolved or not
     // - the eCell.leadParameters are at the last possible parameters
@@ -333,21 +362,23 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::resolveLayerT(Trk::
         //  (b) the starting layer is not the same layer :
         // - apply the preUpdate on the parameters whein they reached the surface    
         // Possible return types:
-        // - SuccessDestion      : great, desintation surface hit
+        // - SuccessDestination  : great, desintation surface hit - but post-update needs to be done
         // - SuccessPathLimit    : pathlimit was reached on the way to the destination surface 
         eCode = m_propagationEngine->propagate(eCell,*sf,pDir,bcheck,eCell.destinationCurvilinear);
-        EX_MSG_VERBOSE(eCell.navigationStep, "attempt to hit destination surface resulted in " << eCode.toString() ); 
-        // preUpdate needed when the layer is NOT the startLayer - or if sub structure resolving happened
-        if ( (!isStartLayer || hasSubStructure) &&  (eCode != Trk::ExtrapolationCode::SuccessPathLimit) ){ 
+        // check for success return path limit
+        CHECK_ECODE_SUCCESS_NODEST(eCell,eCode);
+        EX_MSG_VERBOSE(eCell.navigationStep, "layer", eCell.leadLayer->layerIndex().value(), "attempt to hit destination surface resulted in " << eCode.toString() ); 
+        // check for a potential preUpdate 
+        // - in case teh destination surface has material and the surface was hit 
+        if ( sf->materialLayer() &&  eCode.isSuccess() ){ 
             // the resolved surface has material, set the leadLayer to 
-            // - the materialLayer ( has higher priority than the associatedLayer() )
-            // - the associatedLayer ( if no materialLayer is not there )
-            eCell.leadLayer      = sf->materialLayer() ? sf->materialLayer() : sf->associatedLayer();
+            eCell.leadLayer      = sf->materialLayer();
             // finally do the material update 
-            // - this is the final call, no need to check for SuccessMaterialLimit
-            // - however only do the preUpdate if the destination was successfully hit (and no path limit kicked in)
+            // - this is the final call - still check for SuccessMaterialLimit
             // the material effects updator usually returns inProgress, this needs to be ingored
             m_materialEffectsEngine->handleMaterial(eCell,pDir,Trk::preUpdate);
+            // check if success was triggered through path limit reached on the way to the layer
+            CHECK_ECODE_SUCCESS(eCell,eCode);
         }   
         // return what you have handleLayerT or extrapolateT will resolve that
         return eCode;        
@@ -366,19 +397,19 @@ template <class T> Trk::ExtrapolationCode Trk::StaticEngine::handleReturnT(Trk::
                                                                            Trk::PropDirection pDir,
                                                                            Trk::BoundaryCheck bcheck) const 
 {   
-    EX_MSG_DEBUG(++eCell.navigationStep, "handleReturnT with code " << eCode.toString() << " called." ); 
+    EX_MSG_DEBUG(++eCell.navigationStep, "return", "", "handleReturnT with code " << eCode.toString() << " called." ); 
     if (eCode.isSuccessOrRecovered() || eCode.inProgress() ){
-        EX_MSG_VERBOSE(eCell.navigationStep, "leaving static extrapolator successfully with code " << eCode.toString()); 
+        EX_MSG_VERBOSE(eCell.navigationStep, "return", "", "leaving static extrapolator successfully with code " << eCode.toString()); 
         return eCode;
     }
-    EX_MSG_VERBOSE(eCell.navigationStep, "failure detected as " << eCode.toString() << " - checking fallback configuration."); 
+    EX_MSG_VERBOSE(eCell.navigationStep, "return", "", "failure detected as " << eCode.toString() << " - checking fallback configuration."); 
     // obviously we need a surface to exercise the fallback    
     if (sf && !eCell.checkConfigurationMode(Trk::ExtrapolationMode::AvoidFallback)){
-        EX_MSG_VERBOSE(eCell.navigationStep, "fallback configured. Trying to hit destination surface from last valid parameters."); 
+        EX_MSG_VERBOSE(eCell.navigationStep, "return", "", "fallback configured. Trying to hit destination surface from last valid parameters."); 
         // check if you hit the surface, could still be stopped by PathLimit, but would also count as recovered
-        eCode = m_propagationEngine->propagate(eCell,*sf,pDir,bcheck,eCell.destinationCurvilinear);
+	eCode = m_propagationEngine->propagate(eCell,*sf,pDir,bcheck,eCell.destinationCurvilinear);
     }    
-    // nothing to try anynore
+   
     return eCode;                                                                                  
 }
   
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.h b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.h
index ddbf4b3ef1f..dd31e5f0b5d 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.h
+++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.h
@@ -14,7 +14,7 @@
 #include "GaudiKernel/ToolHandle.h"
 // Trk
 #include "TrkExInterfaces/INavigationEngine.h"
-#include "TrkExEngine/ExtrapolationMacros.h"
+#include "TrkExInterfaces/ExtrapolationMacros.h"
 #include "TrkExUtils/ExtrapolationCell.h"
 #include "TrkParameters/TrackParameters.h"
 #include "TrkNeutralParameters/NeutralParameters.h"
@@ -88,7 +88,7 @@ namespace Trk {
 
 inline const Trk::TrackingGeometry& StaticNavigationEngine::trackingGeometry() const throw (GaudiException) {
     if (!m_trackingGeometry && updateTrackingGeometry().isFailure()){
-        ATH_MSG_ERROR("Could not load TrackingGeometry with name '" << m_trackingGeometryName << "'. Aborting." );
+        EX_MSG_FATAL("", "updateGeo", "", "Could not load TrackingGeometry with name '" << m_trackingGeometryName << "'. Aborting." );
         throw GaudiException("StaticNavigationEngine", "Problem with TrackingGeometry loading.", StatusCode::FAILURE);
     }
     return (*m_trackingGeometry);
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.icc b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.icc
index 0924e1bcb67..ca6d15345c2 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.icc
+++ b/Tracking/TrkExtrapolation/TrkExEngine/TrkExEngine/StaticNavigationEngine.icc
@@ -17,7 +17,7 @@
 template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBoundaryT(Trk::ExtrapolationCell<T>& eCell,
                                                                                         Trk::PropDirection pDir) const 
 {   
-    EX_MSG_DEBUG(++eCell.navigationStep, "resolve boundary situation leaving '"<< eCell.leadVolume->volumeName() 
+    EX_MSG_DEBUG(++eCell.navigationStep, "navigation", "", "resolve boundary situation leaving '"<< eCell.leadVolume->volumeName() 
                 << (int(pDir) > 0 ? "' along momentum." : "' opposite momentum.") );
     // initialize the extrapolation code to progress
     Trk::ExtrapolationCode eCode = Trk::ExtrapolationCode::InProgress;
@@ -25,15 +25,16 @@ template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBo
     auto boundaryIntersections = eCell.leadVolume->boundarySurfacesOrdered(*eCell.leadParameters,
                                                                            pDir,
                                                                            eCell.onLastBoundary() );
-    EX_MSG_VERBOSE(eCell.navigationStep, "found " << boundaryIntersections.size() << " boundary surfaces to try"
+    EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "found " << boundaryIntersections.size() << " boundary surfaces to try"
                    << ( eCell.onLastBoundary() ? " - starting from last boundary." : "." ) );
     // remember them for the slow acces 
     std::map< const Trk::BoundarySurface<Trk::TrackingVolume>*, bool > bSurfacesTried;
+    
     for (auto& boundaryCandidate : boundaryIntersections){
         // the surface of the 
         const Trk::BoundarySurface<Trk::TrackingVolume>* bSurfaceTV = boundaryCandidate.object;
         // skip if it's the last boundary surface
-        if (eCell.onLastBoundary() && &bSurfaceTV->surfaceRepresentation() == eCell.lastBoundarySurface ) continue;
+        if ( eCell.onLastBoundary() && &bSurfaceTV->surfaceRepresentation() == eCell.lastBoundarySurface ) continue;
         // check this boudnary, possible return codes are:
         // - SuccessPathLimit     : propagation to boundary caused PathLimit to be fail @TODO implement protection againg far of tries
         // - SuccessMaterialLimit : boundary was reached and material update on boundary reached limit
@@ -44,27 +45,27 @@ template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBo
         CHECK_ECODE_SUCCESS(eCell, eCode);
         // Failure or Unset are not triggering a return, try more sophisticated navigation 
         if (!eCode.inProgress()){
-            EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface not reached with " << eCode.toString() << ", skipping.");
+            EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "boundary surface not reached with " << eCode.toString() << ", skipping.");
             // book keeping for the slow access not to try again the same stuff
             bSurfacesTried[bSurfaceTV] = false;
             // skip to the next surface if there's one
             continue;
         } 
-        EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface handling yielded code " << eCode.toString());
+        EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "boundary surface handling yielded code " << eCode.toString());
         // set that this was the last boundary surface
         eCell.lastBoundarySurface = &bSurfaceTV->surfaceRepresentation();
         // and return the code yielded by the handleBoundaryT 
         return eCode;
     }
     // [2] ------------------------ slow boundary access : take all boundary surfaces and simply try --------------
-    EX_MSG_VERBOSE(eCell.navigationStep, "fast boundary navigation did not succeeed - trying slow navigation now.");
+    EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "fast boundary navigation did not succeeed - trying slow navigation now.");
     // ignore the ones you have tried already 
     for (auto& bSurface : eCell.leadVolume->boundarySurfaces() ){
         // we tried this one already, no point to do it again
         if ( bSurfacesTried.size() && bSurfacesTried.find(bSurface.getPtr()) != bSurfacesTried.end() ) continue;
         // skip if it's the last boundary surface
         if ( &bSurface->surfaceRepresentation() == eCell.lastBoundarySurface ) continue;
-        EX_MSG_VERBOSE(eCell.navigationStep, "trying a boundary surface.");
+        EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "trying a boundary surface.");
         // there is now loop protection in the slow access, needs to be done by hand
         // check this boudnary, possible return codes are:
         // - SuccessPathLimit     : propagation to boundary caused PathLimit to be fail @TODO implement protection againg far of tries
@@ -75,18 +76,18 @@ template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBo
         CHECK_ECODE_SUCCESS(eCell, eCode);
         // Failure or Unset are not triggering a return, try more sophisticated navigation 
         if (!eCode.inProgress()){
-            EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface not reached with " << eCode.toString() << ", skipping.");
+            EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "boundary surface not reached with " << eCode.toString() << ", skipping.");
             // skip to the next surface if there's one
             continue;
         }
-        EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface handling yielded code " << eCode.toString());
+        EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "boundary surface handling yielded code " << eCode.toString());
         // set that this was the last boundary surface
         eCell.lastBoundarySurface = &bSurface->surfaceRepresentation();
         // and return the code yielded by the handleBoundaryT 
         return eCode;
     }
     // [3] ------------------------ slowest boundary access : step-out-of-volume approach -------------------------
-    EX_MSG_VERBOSE(eCell.navigationStep, "slow boundary navigation did not succeeed - trying step-out-of-volume approach now");
+    EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "slow boundary navigation did not succeeed - trying step-out-of-volume approach now");
     for (auto& boundaryCandidate : boundaryIntersections){
         // the surface of the 
         const Trk::BoundarySurface<Trk::TrackingVolume>* bSurfaceTV = boundaryCandidate.object;
@@ -100,18 +101,19 @@ template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBo
         CHECK_ECODE_SUCCESS(eCell, eCode);
         // Failure or Unset are not triggering a return, try more sophisticated navigation 
         if (!eCode.inProgress()){
-            EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface not reached with " << eCode.toString() << ", skipping.");
+            EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "boundary surface not reached with " << eCode.toString() << ", skipping.");
             // skip to the next surface if there's one
             continue;
         } 
-        EX_MSG_VERBOSE(eCell.navigationStep, "boundary surface handling yielded code " << eCode.toString());
+        EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "boundary surface handling yielded code " << eCode.toString());
         // set that this was the last boundary surface
         eCell.lastBoundarySurface = &bSurfaceTV->surfaceRepresentation();
         // and return the code yielded by the handleBoundaryT 
         return eCode;
     }   
     // return it back
-    EX_MSG_DEBUG(eCell.navigationStep, "could not resolve the boundary situation. Exiting.");
+    EX_MSG_DEBUG(eCell.navigationStep, "navigation", "", "could not resolve the boundary situation. Exiting.");
+    
     return Trk::ExtrapolationCode::FailureNavigation;                                                                                 
 }  
 
@@ -129,13 +131,24 @@ template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::handleBou
     // - Recovered        : boundary not reached
     Trk::ExtrapolationCode eCode = m_propagationEngine->propagate(eCell,bSurface,pDir,!stepout,eCell.destinationCurvilinear);
     CHECK_ECODE_SUCCESS(eCell, eCode);
+    EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "handleBoundaryT", "propagation with eCode " << eCode.toString());
     // check for progress 
     if (eCode.inProgress()){         
-        EX_MSG_VERBOSE(eCell.navigationStep, "parameters on boundary surface created, moving to next volume."); 
+        // check if the boundary solution is compatible with the radial direciton of the extrapolation
+	    if (!eCell.checkRadialCompatibility()) {
+            // screen output for the radial compatibility check
+            EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "handleBoundaryT", "radial compatbility check failed, radial direction is: " << eCell.radialDirection);
+            // it's not jump back to the last valid lead parameters and return Unset as a trigger
+	        eCell.leadParameters = eCell.lastLeadParameters;
+	        return Trk::ExtrapolationCode::Unset;
+        }
+        EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "parameters on boundary surface created, moving to next volume."); 
         // get the nextVolume - modify the position in case you have a step out trial, take attachment otherwise
         const Trk::TrackingVolume* nextVolume = stepout ?
                 trackingGeometry().lowestTrackingVolume(Amg::Vector3D(eCell.leadParameters->position()+pDir*eCell.leadParameters->momentum().unit())) :
                 bSurfaceTV.attachedVolume(eCell.leadParameters->position(), eCell.leadParameters->momentum(), pDir);
+        // check if we have no nextVolume : boundary rechaed @TODO it's not really a success
+        if (!nextVolume) return Trk::ExtrapolationCode::SuccessBoundaryReached;
         // check if it is a boundary reached case
         // - geometrySignature change and configuration to stop then triggers a Success 
         bool stopAtThisBoundary = eCell.checkConfigurationMode(Trk::ExtrapolationMode::StopAtBoundary) 
@@ -149,7 +162,7 @@ template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::handleBou
             // the start parameters where on the boundary already give a relaxed return code
             if (&bSurface == eCell.lastBoundarySurface) return Trk::ExtrapolationCode::Unset;
             // give some screen output as of why this happens
-            EX_MSG_VERBOSE(eCell.navigationStep, "loop detected while trying to leave TrackingVolume '" << nextVolume->volumeName() << ".");
+            EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "loop detected while trying to leave TrackingVolume '" << nextVolume->volumeName() << ".");
             // return a loop failure, parameter deletion will be done by cache
             return Trk::ExtrapolationCode::FailureLoop;
         }
@@ -165,7 +178,8 @@ template <class T> Trk::ExtrapolationCode Trk::StaticNavigationEngine::handleBou
         }
         // break if configured to break at volume boundary and signature change
         if (stopAtThisBoundary){
-            EX_MSG_VERBOSE(eCell.navigationStep, "geometry signature change from " << eCell.leadVolume->geometrySignature()  << " to " << nextVolume->geometrySignature());
+            EX_MSG_VERBOSE(eCell.navigationStep, "navigation", "", "geometry signature change from " << eCell.leadVolume->geometrySignature()  << " to " << nextVolume->geometrySignature());
+	        eCell.nextGeometrySignature = nextVolume->geometrySignature();
             // return the boundary reached     
             return Trk::ExtrapolationCode::SuccessBoundaryReached;
         } 
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/cmt/requirements b/Tracking/TrkExtrapolation/TrkExEngine/cmt/requirements
index 97ff8ce4999..986ad64bf50 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/cmt/requirements
+++ b/Tracking/TrkExtrapolation/TrkExEngine/cmt/requirements
@@ -33,4 +33,4 @@ apply_pattern component_library
 private
 #macro cppdebugflags '$(cppdebugflags_s)'
 #macro_remove componentshr_linkopts "-Wl,-s"
-macro DOXYGEN_IMAGE_PATH "../doc/images"
\ No newline at end of file
+macro DOXYGEN_IMAGE_PATH "../doc/images"
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/python/AtlasExtrapolationEngine.py b/Tracking/TrkExtrapolation/TrkExEngine/python/AtlasExtrapolationEngine.py
index 881ec2941d0..d537cdf342a 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/python/AtlasExtrapolationEngine.py
+++ b/Tracking/TrkExtrapolation/TrkExEngine/python/AtlasExtrapolationEngine.py
@@ -98,6 +98,7 @@ class AtlasExtrapolationEngine( ExEngine ):
         # call the base class constructor
         ExEngine.__init__(self, name=nameprefix+'Extrapolation',\
                           ExtrapolationEngines   = [ StaticExtrapolator ], \
+                          PropagationEngine      = StaticPropagator, \
                           TrackingGeometrySvc    = AtlasTrackingGeometrySvc, \
                           OutputPrefix           = '[ME] - ', \
                           OutputPostfix          = ' - ')
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/ExtrapolationEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/ExtrapolationEngine.cxx
index d8d583f569c..6fdfb5eed6f 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/src/ExtrapolationEngine.cxx
+++ b/Tracking/TrkExtrapolation/TrkExEngine/src/ExtrapolationEngine.cxx
@@ -18,16 +18,16 @@ Trk::ExtrapolationEngine::ExtrapolationEngine(const std::string& t, const std::s
   m_trackingGeometry(0),
   m_trackingGeometrySvc("AtlasTrackingGeometrySvc", n),
   m_trackingGeometryName("AtlasTrackingGeometry"),
+  m_propagationEngine(""),    
   m_forceSearchInit(false)
 {
     declareInterface<Trk::IExtrapolationEngine>(this);
-    
     // Geometry retrieval
     declareProperty("TrackingGeometrySvc"                   , m_trackingGeometrySvc);
     // Extrapolation Engine retrieval 
-    declareProperty("ExtrapolationEngines"                  , m_extrapolationEngines);
-    // Material Updator Engine retrival
-    
+    declareProperty("ExtrapolationEngines"                  , m_extrapolationEngines);    
+    // The Tools needed
+    declareProperty("PropagationEngine"                     , m_propagationEngine);
     // steering of the screen outoput (SOP)
     declareProperty("OutputPrefix"                          , m_sopPrefix);
     declareProperty("OutputPostfix"                         , m_sopPostfix);
@@ -43,17 +43,15 @@ Trk::ExtrapolationEngine::~ExtrapolationEngine()
 // the interface method initialize
 StatusCode Trk::ExtrapolationEngine::initialize()
 {
-
             
-    EX_MSG_INFO( "init", " starting initialize()" );
-
+    EX_MSG_DEBUG( "", "initialize", "", "starting initialize()" );
     // get the TrackingGeometrySvc
     if (m_trackingGeometrySvc.retrieve().isSuccess()){
-        EX_MSG_INFO( "init", "Successfully retrieved " << m_trackingGeometrySvc );
+        EX_MSG_DEBUG( "", "initialize", "", "successfully retrieved " << m_trackingGeometrySvc );
         m_trackingGeometryName = m_trackingGeometrySvc->trackingGeometryName();
     } else {
-        EX_MSG_WARNING( "init", "Couldn't retrieve " << m_trackingGeometrySvc << ". " );
-        EX_MSG_WARNING( "init", " -> Trying to retrieve default '" << m_trackingGeometryName << "' from DetectorStore. Abort." );
+        EX_MSG_WARNING( "", "initialize", "", "couldn't retrieve " << m_trackingGeometrySvc << ". " );
+        EX_MSG_WARNING( "", "initialize", "", " -> Trying to retrieve default '" << m_trackingGeometryName << "' from DetectorStore. Abort." );
         return StatusCode::FAILURE;
     }
     
@@ -61,15 +59,19 @@ StatusCode Trk::ExtrapolationEngine::initialize()
     if (m_extrapolationEngines.retrieve().isFailure()){
         
     } else {
-        EX_MSG_INFO( "init", "Successfully retrieved " << m_extrapolationEngines.size() << " ExtrapolationEngines. Ordering them now." );
+        EX_MSG_DEBUG( "", "initialize", "", "Successfully retrieved " << m_extrapolationEngines.size() << " ExtrapolationEngines. Ordering them now." );
         m_eeAccessor = std::vector<const Trk::IExtrapolationEngine*>(int(Trk::NumberOfGeometryTypes), (const Trk::IExtrapolationEngine*)NULL);
         for (auto& ee : m_extrapolationEngines){
-            EX_MSG_DEBUG( "init", "Registering " << ee->name() << " - for GeometryType : "  << ee->geometryType() );
+            EX_MSG_DEBUG( "", "initialize", "", "Registering " << ee->name() << " - for GeometryType : "  << ee->geometryType() );
             m_eeAccessor[ee->geometryType()] = (&*ee);
         }
     }
-    
-    
+
+    if (m_propagationEngine.retrieve().isFailure()){
+      EX_MSG_FATAL("", "initialize", "", "failed to retrieve propagation engine '"<< m_propagationEngine << "'. Aborting." );
+      return StatusCode::FAILURE;
+    } else 
+      EX_MSG_DEBUG("", "initialize", "", "successfully  propagation engine '" << m_propagationEngine << "'." );
     
     return StatusCode::SUCCESS;
 }    
@@ -77,7 +79,7 @@ StatusCode Trk::ExtrapolationEngine::initialize()
 // the interface method finalize
 StatusCode Trk::ExtrapolationEngine::finalize()
 {    
-    EX_MSG_INFO( "fini", "finalize() successful" );    
+    EX_MSG_DEBUG( "", "finalize", "", "successful" );    
     return StatusCode::SUCCESS;
 }
 
@@ -85,24 +87,22 @@ StatusCode Trk::ExtrapolationEngine::finalize()
 /** charged extrapolation */
 Trk::ExtrapolationCode Trk::ExtrapolationEngine::extrapolate(ExCellCharged& ecCharged,
                                                         const Surface* sf,
-                                                        PropDirection dir,
                                                         BoundaryCheck bcheck) const
-{ return extrapolateT<TrackParameters>(ecCharged,sf,dir,bcheck); }
+{ return extrapolateT<TrackParameters>(ecCharged,sf,ecCharged.propDirection,bcheck); }
 
 
 /** neutral extrapolation */
 Trk::ExtrapolationCode Trk::ExtrapolationEngine::extrapolate(ExCellNeutral& ecNeutral,
                                                         const Surface* sf,
-                                                        PropDirection dir,
                                                         BoundaryCheck bcheck) const
-{ return extrapolateT<NeutralParameters>(ecNeutral,sf,dir,bcheck); }
+{ return extrapolateT<NeutralParameters>(ecNeutral,sf,ecNeutral.propDirection,bcheck); }
                                            
 
 StatusCode Trk::ExtrapolationEngine::updateTrackingGeometry() const {
     // retrieve the TrackingGeometry from the detector store 
     if (detStore()->retrieve(m_trackingGeometry, m_trackingGeometryName).isFailure()){
-        EX_MSG_FATAL( "tgeo", "Could not retrieve TrackingGeometry '" << m_trackingGeometryName << "' from DetectorStore." );
-        EX_MSG_FATAL( "tgeo", "  - probably the chosen layout is not supported / no cool tag exists. "                     );
+        EX_MSG_FATAL( "", "updateGeom", "", "could not retrieve TrackingGeometry '" << m_trackingGeometryName << "' from DetectorStore." );
+        EX_MSG_FATAL( "", "updateGeom", "", "  - probably the chosen layout is not supported / no cool tag exists. "                     );
         return StatusCode::FAILURE;
     }
     return StatusCode::SUCCESS;
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/MaterialEffectsEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/MaterialEffectsEngine.cxx
index 158cd4dc8a7..d6d8a56387d 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/src/MaterialEffectsEngine.cxx
+++ b/Tracking/TrkExtrapolation/TrkExEngine/src/MaterialEffectsEngine.cxx
@@ -14,12 +14,19 @@
 
 // constructor
 Trk::MaterialEffectsEngine::MaterialEffectsEngine(const std::string& t, const std::string& n, const IInterface* p)
-: AthAlgTool(t,n,p)
+: AthAlgTool(t,n,p),
+  m_eLossCorrection(true),
+  m_eLossMpv(true),       
+  m_mscCorrection(true)   
 {
     declareInterface<Trk::IMaterialEffectsEngine>(this);
     // steering of the screen outoput (SOP)
     declareProperty("OutputPrefix"                          , m_sopPrefix);
     declareProperty("OutputPostfix"                         , m_sopPostfix);
+    // steering of the material effects engine behaviour
+    declareProperty("EnergyLossCorrection"                  , m_eLossCorrection); 
+    declareProperty("MostProbableEnergyLoss"                , m_eLossMpv);         
+    declareProperty("MultipleScatteringCorrection"          , m_mscCorrection);    
 }
 
 // destructor
@@ -30,17 +37,62 @@ Trk::MaterialEffectsEngine::~MaterialEffectsEngine()
 // the interface method initialize
 StatusCode Trk::MaterialEffectsEngine::initialize()
 {
-    EX_MSG_INFO( "init", " starting initialize()" );
+    EX_MSG_DEBUG( "", "initialize","",  "successful" );
     return StatusCode::SUCCESS;
 }    
 
 // the interface method finalize
 StatusCode Trk::MaterialEffectsEngine::finalize()
 {    
-    EX_MSG_INFO( "fini", "finalize() successful" );    
+    EX_MSG_DEBUG( "", "finalize","",  "successful" );
     return StatusCode::SUCCESS;
 }
 
+/** neutral extrapolation - just collect material */
+Trk::ExtrapolationCode Trk::MaterialEffectsEngine::handleMaterial(Trk::ExCellNeutral& eCell,
+                                                                  Trk::PropDirection dir,
+                                                                  Trk::MaterialUpdateStage matupstage) const
+{
+
+    // the Extrapolator made sure that the layer is the lead layer && the parameters are the lead parameters
+    if (eCell.leadLayer && eCell.leadLayer->layerMaterialProperties()){
+        EX_MSG_DEBUG( ++eCell.navigationStep, "layer",  eCell.leadLayer->layerIndex().value(), "handleMaterial for neutral parameters called - collect material."); 
+        // now calculate the pathCorrection from the layer surface - it is signed, gives you the relative direction to the layer
+        const Trk::Layer* layer = eCell.leadLayer;
+        // path correction 
+        double pathCorrection = layer->surfaceRepresentation().pathCorrection(eCell.leadParameters->position(),dir*(eCell.leadParameters->momentum()));
+        // the relative direction wrt with the layer
+        Trk::PropDirection rlDir = (pathCorrection > 0. ? Trk::alongMomentum : Trk::oppositeMomentum);
+        // multiply by the pre-and post-update factor
+        double mFactor = layer->layerMaterialProperties()->factor(rlDir, matupstage);
+        if (mFactor == 0.){
+            EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "material collection with "  << (matupstage > 0. ? "pre " : "post ")  << "factor 0."); 
+            // return the parameters untouched -
+            return Trk::ExtrapolationCode::InProgress;
+        }
+        pathCorrection = mFactor*pathCorrection;
+        // screen output
+        EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "material update with corr factor = " << pathCorrection); 
+        // get the actual material bin
+        const Trk::MaterialProperties* materialProperties = layer->layerMaterialProperties()->fullMaterial(eCell.leadParameters->position());
+        // and let's check if there's acutally something to do
+        if (materialProperties){
+            // thickness in X0 
+            double thicknessInX0          = materialProperties->thicknessInX0();
+            // check if material filling was requested
+            if (eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectMaterial)){
+                EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "collecting material of [t/X0] = " << thicknessInX0); 
+                eCell.stepMaterial(eCell.leadParameters->associatedSurface(), layer, eCell.leadParameters->position(), pathCorrection, materialProperties);
+            } else {
+                EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "adding material of [t/X0] = " << thicknessInX0); 
+                eCell.addMaterial(pathCorrection, materialProperties);
+            }
+        }    
+    }
+    // only in case of post update it should not return InProgress
+    return Trk::ExtrapolationCode::InProgress;
+}
+
 
 /** charged extrapolation */
 Trk::ExtrapolationCode Trk::MaterialEffectsEngine::handleMaterial(Trk::ExCellCharged& eCell,
@@ -50,10 +102,11 @@ Trk::ExtrapolationCode Trk::MaterialEffectsEngine::handleMaterial(Trk::ExCellCha
 
     // the Extrapolator made sure that the layer is the lead layer && the parameters are the lead parameters
     if (eCell.leadLayer && eCell.leadLayer->layerMaterialProperties()){
-        EX_MSG_DEBUG(++eCell.navigationStep, "handleMaterial for charged TrackParameters called."); 
+        EX_MSG_DEBUG( ++eCell.navigationStep, "layer",  eCell.leadLayer->layerIndex().value(), "handleMaterial for charged parameters called."); 
         // update the track parameters    
         eCell.leadParameters = updateTrackParameters(*eCell.leadParameters,eCell,dir,matupstage);
     }
+    // only in case of post update it should not return InProgress
     return Trk::ExtrapolationCode::InProgress;
 }
 
@@ -72,17 +125,19 @@ const Trk::TrackParameters* Trk::MaterialEffectsEngine::updateTrackParameters(co
     // multiply by the pre-and post-update factor
     double mFactor = layer->layerMaterialProperties()->factor(rlDir, matupstage);
     if (mFactor == 0.){
-        EX_MSG_VERBOSE(eCell.navigationStep, "material update with pre/post update factor 0. No update done."); 
+        EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "material update with "  << (matupstage > 0. ? "pre " : "post ")  << "factor 0. No update done."); 
         // return the parameters untouched -
         return (&parameters);
     }
     pathCorrection = mFactor*pathCorrection;
     // screen output
-    EX_MSG_VERBOSE(eCell.navigationStep, "material update on layer with index " << layer->layerIndex().value() << " - corr factor = " << pathCorrection); 
+    EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "material update with corr factor = " << pathCorrection); 
     // get the actual material bin
     const Trk::MaterialProperties* materialProperties = layer->layerMaterialProperties()->fullMaterial(parameters.position());
     // and let's check if there's acutally something to do
-    if (materialProperties){
+    if (materialProperties && ( m_eLossCorrection || m_mscCorrection || eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectMaterial)) ){
+        // and add them 
+        int sign = int(eCell.materialUpdateMode);
         // a simple cross-check if the parameters are the initial ones
         AmgVector(5)      uParameters = parameters.parameters();
         AmgSymMatrix(5)*  uCovariance = parameters.covariance() ? new AmgSymMatrix(5)(*parameters.covariance()) : 0;
@@ -95,40 +150,48 @@ const Trk::TrackParameters* Trk::MaterialEffectsEngine::updateTrackParameters(co
         double m      = m_particleMasses.mass[eCell.pHypothesis];
         double E      = sqrt(p*p+m*m);
         double beta   = p/E;
-        double sigmaP = 0.;
-        double kazL   = 0.;
-        /** dE/dl ionization energy loss per path unit */
-        double dEdX = m_interactionFormulae.dEdl_ionization(p, &material, eCell.pHypothesis, sigmaP, kazL);    
-        double dE   = dEdX*thickness*pathCorrection;
-        // calcuate the new momentum
-        double newP = sqrt((E+dE)*(E+dE)-m*m);
-        uParameters[Trk::qOverP] = parameters.charge()/newP;
-        // @TODO add straggling
-        
-        // update the covariance if needed
-        if (uCovariance){
-            /** multiple scattering as function of dInX0 */
-            double sigmaMS = m_interactionFormulae.sigmaMS(thicknessInX0*pathCorrection, p, beta);    
-            double sinTheta = sin(parameters.parameters()[Trk::theta]);
-            double sigmaDeltaPhiSq = sigmaMS*sigmaMS/(sinTheta*sinTheta);
-            double sigmaDeltaThetaSq = sigmaMS*sigmaMS;
-            // and add them 
-            int sign = int(eCell.materialUpdateMode);
-            // add or remove @TODO implement check for covariance matrix -> 0
-            (*uCovariance)(Trk::phi,Trk::phi)      += sign*sigmaDeltaPhiSq;
-            (*uCovariance)(Trk::theta, Trk::theta) += sign*sigmaDeltaThetaSq;
+        // (A) - energy loss correction
+        if (m_eLossCorrection){
+            double sigmaP = 0.;
+            double kazl   = 0.;
+            /** dE/dl ionization energy loss per path unit */
+            double dEdl = sign*m_interactionFormulae.dEdl_ionization(p, &material, eCell.pHypothesis, sigmaP, kazl);    
+            double dE   = thickness*pathCorrection*dEdl;
+            sigmaP *= thickness*pathCorrection;
+            // calcuate the new momentum
+            double newP = sqrt((E+dE)*(E+dE)-m*m);
+            uParameters[Trk::qOverP] = parameters.charge()/newP;
+            double sigmaDeltaE = thickness*pathCorrection*sigmaP;
+            double sigmaQoverP = sigmaDeltaE/std::pow(beta*p,2);
+            // update the covariance if needed
+            if (uCovariance)
+    	       (*uCovariance)(Trk::qOverP, Trk::qOverP) += sign*sigmaQoverP*sigmaQoverP;
+        }
+        // (B) - update the covariance if needed
+        if (uCovariance && m_mscCorrection){
+	        /** multiple scattering as function of dInX0 */
+	        double sigmaMS = m_interactionFormulae.sigmaMS(thicknessInX0*pathCorrection, p, beta);    
+	        double sinTheta = sin(parameters.parameters()[Trk::theta]);
+	        double sigmaDeltaPhiSq = sigmaMS*sigmaMS/(sinTheta*sinTheta);
+	        double sigmaDeltaThetaSq = sigmaMS*sigmaMS;
+	        // add or remove @TODO implement check for covariance matrix -> 0
+	        (*uCovariance)(Trk::phi,Trk::phi)      += sign*sigmaDeltaPhiSq;
+	        (*uCovariance)(Trk::theta, Trk::theta) += sign*sigmaDeltaThetaSq;
         }
         // check if material filling was requested
         if (eCell.checkConfigurationMode(Trk::ExtrapolationMode::CollectMaterial)){
-            EX_MSG_VERBOSE(eCell.navigationStep, "collecting material at layer " << layer->layerIndex().value() << " of - t/X0 = " << thicknessInX0); 
-            eCell.stepMaterial(parameters.associatedSurface(), layer, parameters.position(), pathCorrection, materialProperties);
+	        EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "collecting material of [t/X0] = " << thicknessInX0); 
+	        eCell.stepMaterial(parameters.associatedSurface(), layer, parameters.position(), pathCorrection, materialProperties);
+        } else {
+	        EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "adding material of [t/X0] = " << thicknessInX0); 
+	        eCell.addMaterial(pathCorrection, materialProperties);
         }
         // now either create new ones or update - only start parameters can not be updated
         if (eCell.leadParameters != eCell.startParameters ){
-            EX_MSG_VERBOSE(eCell.navigationStep, "material update on non-initial parameters."); 
+            EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "material update on non-initial parameters."); 
             parameters.updateParameters(uParameters,uCovariance);
         } else {
-            EX_MSG_VERBOSE(eCell.navigationStep, "material update on initial parameters, creating new ones."); 
+            EX_MSG_VERBOSE(eCell.navigationStep, "layer",  layer->layerIndex().value(), "material update on initial parameters, creating new ones."); 
             // create new parameters
             const Trk::Surface& tSurface = parameters.associatedSurface();
             const Trk::TrackParameters* tParameters = tSurface.createTrackParameters(uParameters[Trk::loc1],
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/PropagationEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/PropagationEngine.cxx
index 87973d6a19e..2fee90054e2 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/src/PropagationEngine.cxx
+++ b/Tracking/TrkExtrapolation/TrkExEngine/src/PropagationEngine.cxx
@@ -39,19 +39,19 @@ StatusCode Trk::PropagationEngine::initialize()
 {
     
     if (m_propagator.retrieve().isFailure()){
-        EX_MSG_FATAL( "init", "failed to retrieve propagator '"<< m_propagator << "'. Aborting." );
+        EX_MSG_FATAL( "", "initialize", "", "failed to retrieve propagator '"<< m_propagator << "'. Aborting." );
         return StatusCode::FAILURE;
     } else 
-        EX_MSG_INFO( "init", "successfully retrieved '" << m_propagator << "'." );
+        EX_MSG_DEBUG( "", "initialize", "", "successfully retrieved '" << m_propagator << "'." );
 
-    EX_MSG_INFO( "init", "initialize() successful" );
+    EX_MSG_DEBUG( "", "initialize", "", "successful" );
     return StatusCode::SUCCESS;
 }    
 
 // the interface method finalize
 StatusCode Trk::PropagationEngine::finalize()
 {    
-    EX_MSG_INFO( "fini", "finalize() successful" );    
+    EX_MSG_DEBUG( "", "finalize", "", "successful" );
     return StatusCode::SUCCESS;
 }
 
@@ -63,17 +63,17 @@ Trk::ExtrapolationCode Trk::PropagationEngine::propagate(Trk::ExCellCharged& eCe
                                                          Trk::BoundaryCheck bcheck,
                                                          bool returnCurvilinear) const
 {
-    EX_MSG_DEBUG(++eCell.navigationStep, "propagation engine called with charged parameters with propagation direciton " << pDir ); 
+    EX_MSG_DEBUG(++eCell.navigationStep, "propagate", "char", "propagation engine called with charged parameters with propagation direction " << pDir ); 
 
     double propLength = -1.;
     if (eCell.checkConfigurationMode(Trk::ExtrapolationMode::StopWithPathLimit)){
         // the path limit
         propLength = eCell.pathLimit > 0 ? (eCell.pathLimit-eCell.pathLength) : eCell.pathLimit;
-        EX_MSG_VERBOSE(eCell.navigationStep, "available step length for this propagation " << propLength ); 
+        EX_MSG_VERBOSE(eCell.navigationStep, "propagate", "char", "available step length for this propagation " << propLength ); 
     }
     // it is the final propagation if it is the endSurface
     bool finalPropagation = (eCell.endSurface == (&sf));
-    //
+
     Trk::TransportJacobian* tjac = 0;
     // we need to first fill the propagation parameters in order to be able to updates & fallbacks
     const Trk::TrackParameters* pParameters = m_propagator->propagate(*eCell.leadParameters, 
@@ -87,6 +87,8 @@ Trk::ExtrapolationCode Trk::PropagationEngine::propagate(Trk::ExCellCharged& eCe
                                                                       returnCurvilinear);
    // set the return type according to how the propagation went
    if (pParameters){
+       // cache the last lead parameters, useful in case a navigation error occured
+       eCell.lastLeadParameters = eCell.leadParameters;
        // assign the lead and end parameters
        eCell.leadParameters = pParameters;
        // check what to do with the path Length
@@ -95,10 +97,15 @@ Trk::ExtrapolationCode Trk::PropagationEngine::propagate(Trk::ExCellCharged& eCe
            eCell.pathLength += propLength;
            // check if Limit reached
            if (eCell.pathLimitReached(m_pathLimitTolerance)){
-               EX_MSG_VERBOSE(eCell.navigationStep, "path limit of " << eCell.pathLimit << " successfully reached -> stopping." ); 
+               EX_MSG_VERBOSE(eCell.navigationStep, "propagate", "char", "path limit of " << eCell.pathLimit << " successfully reached -> stopping." ); 
                return Trk::ExtrapolationCode::SuccessPathLimit;
            }
        }
+
+       // check if the propagation was called with directly, then lead parameters become end parameters
+       if (eCell.checkConfigurationMode(Trk::ExtrapolationMode::Direct)) 
+	 eCell.endParameters = eCell.leadParameters;
+	 
        // return Success only if it is the final propagation - the extrapolation engine knows that 
        return (finalPropagation ? Trk::ExtrapolationCode::SuccessDestination : Trk::ExtrapolationCode::InProgress);
    }                                                                      
@@ -113,10 +120,10 @@ Trk::ExtrapolationCode Trk::PropagationEngine::propagate(Trk::ExCellNeutral& eCe
                                                          Trk::BoundaryCheck bcheck,
                                                          bool returnCurvilinear) const
 { 
-    EX_MSG_DEBUG(++eCell.navigationStep, "propagation engine called with neutral parameters with propagation direciton " << pDir );     
+    EX_MSG_DEBUG(++eCell.navigationStep, "propagate", "neut", "propagation engine called with neutral parameters with propagation direction " << pDir );     
     // leave this for the moment, can re replaced by an appropriate propagator call later
     if (eCell.leadParameters->covariance()){
-        EX_MSG_VERBOSE(eCell.navigationStep, "propagation of neutral parameters with covariances requested. This is not supported for the moment."); 
+        EX_MSG_VERBOSE(eCell.navigationStep,"propagate", "neut", "propagation of neutral parameters with covariances requested. This is not supported for the moment."); 
     }
     // the pathLimit cache so far
     double cPath = eCell.pathLength;
@@ -134,30 +141,38 @@ Trk::ExtrapolationCode Trk::PropagationEngine::propagate(Trk::ExCellNeutral& eCe
         // fill the transport information - only if the propation direction is not 0
         if (pDir){
            double pLength = (sfIntersection.position-eCell.leadParameters->position()).mag(); 
-           EX_MSG_VERBOSE(eCell.navigationStep, "Path length of " << pLength << " added to the extrapolation cell (limit = " << eCell.pathLimit << ")" );    
+           EX_MSG_VERBOSE(eCell.navigationStep,"propagate", "neut", "path length of " << pLength << " added to the extrapolation cell (limit = " << eCell.pathLimit << ")" );    
            eCell.stepTransport(sf,pLength);
         }
         // now check if it is valud it's further away than the pathLimit
         if (eCell.pathLimitReached(m_pathLimitTolerance)){
-            // create new neutral curvilinear parameters at the path limit reached 
+	    // cache the last lead parameters
+	    eCell.lastLeadParameters = eCell.leadParameters;
+	    // create new neutral curvilinear parameters at the path limit reached 
             double pDiff = eCell.pathLimit - cPath;
             eCell.leadParameters = new Trk::NeutralCurvilinearParameters(eCell.leadParameters->position()+pDiff*eCell.leadParameters->momentum().unit(), 
                                                                          eCell.leadParameters->momentum(),
                                                                          0.);
-            EX_MSG_VERBOSE(eCell.navigationStep, "path limit of " << eCell.pathLimit << " reached. Stopping extrapolation."); 
+            EX_MSG_VERBOSE(eCell.navigationStep,"propagate", "neut", "path limit of " << eCell.pathLimit << " reached. Stopping extrapolation."); 
             return Trk::ExtrapolationCode::SuccessPathLimit;
         }  
+	// cache the last lead parameters
+	eCell.lastLeadParameters = eCell.leadParameters;
         // now exchange the lead parameters 
         // create the new curvilinear paramters at the surface intersection -> if so, trigger the success
         eCell.leadParameters = returnCurvilinear ? new Trk::NeutralCurvilinearParameters(sfIntersection.position, eCell.leadParameters->momentum(), 0.) :
                                                        sf.createNeutralParameters(sfIntersection.position, eCell.leadParameters->momentum(), 0.);
-
-        // return success for the final destination or in progress                                                                   
+                                                       
+        // check if the propagation was called with directly, then lead parameters become end parameters
+        if (eCell.checkConfigurationMode(Trk::ExtrapolationMode::Direct)) 
+	  eCell.endParameters = eCell.leadParameters;
+	
+	// return success for the final destination or in progress                                                                   
         return (finalPropagation ? Trk::ExtrapolationCode::SuccessDestination : Trk::ExtrapolationCode::InProgress);
 
     } else {
         // give some screen output
-        EX_MSG_VERBOSE(eCell.navigationStep, "intersection with the surface did not succeed.");
+        EX_MSG_VERBOSE(eCell.navigationStep,"propagate", "neut", "intersection with the surface did not succeed.");
     }                                                                     
    // return - recovered means that the leadParameters are the input ones 
    return (finalPropagation ? Trk::ExtrapolationCode::FailureDestination : Trk::ExtrapolationCode::Recovered) ;
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/StaticEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/StaticEngine.cxx
index 7a8b90113f0..416e39a4198 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/src/StaticEngine.cxx
+++ b/Tracking/TrkExtrapolation/TrkExEngine/src/StaticEngine.cxx
@@ -36,33 +36,32 @@ Trk::StaticEngine::~StaticEngine()
 // the interface method initialize
 StatusCode Trk::StaticEngine::initialize()
 {
-    EX_MSG_INFO( "init", "initialize()" );
-    
     if (m_propagationEngine.retrieve().isFailure()){
-        EX_MSG_FATAL( "init", "failed to retrieve propagation engine '"<< m_propagationEngine << "'. Aborting." );
+        EX_MSG_FATAL("", "initialize", "", "failed to retrieve propagation engine '"<< m_propagationEngine << "'. Aborting." );
         return StatusCode::FAILURE;
     } else 
-        EX_MSG_INFO( "init", "successfully  propagation engine '" << m_propagationEngine << "'." );
+        EX_MSG_DEBUG("", "initialize", "", "successfully  propagation engine '" << m_propagationEngine << "'." );
     
     if (m_navigationEngine.retrieve().isFailure()){
-        EX_MSG_FATAL( "init", "failed to retrieve navigation engine '"<< m_navigationEngine << "'. Aborting." );
+        EX_MSG_FATAL("", "initialize", "", "failed to retrieve navigation engine '"<< m_navigationEngine << "'. Aborting." );
         return StatusCode::FAILURE;
     } else 
-        EX_MSG_INFO( "init", "successfully retrieved '" << m_navigationEngine << "'." );
+        EX_MSG_DEBUG("", "initialize", "", "successfully retrieved '" << m_navigationEngine << "'." );
             
     if (m_materialEffectsEngine.retrieve().isFailure()){
-        EX_MSG_FATAL( "init", "failed to retrieve material effect engine '"<< m_materialEffectsEngine << "'. Aborting." );
+        EX_MSG_FATAL("", "initialize", "", "failed to retrieve material effect engine '"<< m_materialEffectsEngine << "'. Aborting." );
         return StatusCode::FAILURE;
     } else 
-        EX_MSG_INFO( "init", "successfully retrieved '" << m_materialEffectsEngine << "'." );
+        EX_MSG_DEBUG("", "initialize", "", "successfully retrieved '" << m_materialEffectsEngine << "'." );
     
+    EX_MSG_DEBUG("", "initialize", "", "successful." );
     return StatusCode::SUCCESS;
 }    
 
 // the interface method finalize
 StatusCode Trk::StaticEngine::finalize()
 {    
-    ATH_MSG_INFO( "finalize() successful" );    
+    EX_MSG_DEBUG("", "finalize", "", "successful." );
     return StatusCode::SUCCESS;
 }
 
@@ -70,15 +69,12 @@ StatusCode Trk::StaticEngine::finalize()
 /** charged extrapolation */
 Trk::ExtrapolationCode Trk::StaticEngine::extrapolate(ExCellCharged& ecCharged,
                                            const Surface* sf,
-                                           PropDirection dir,
                                            BoundaryCheck bcheck) const
-{ return extrapolateT<TrackParameters>(ecCharged,sf,dir,bcheck); }
+{ return extrapolateT<TrackParameters>(ecCharged,sf,ecCharged.propDirection,bcheck); }
 
 
 /** neutral extrapolation */
 Trk::ExtrapolationCode Trk::StaticEngine::extrapolate(ExCellNeutral& ecNeutral,
                                            const Surface* sf,
-                                           PropDirection dir,
                                            BoundaryCheck bcheck) const
-{ return extrapolateT<NeutralParameters>(ecNeutral,sf,dir,bcheck); }
-                                           
\ No newline at end of file
+{ return extrapolateT<NeutralParameters>(ecNeutral,sf,ecNeutral.propDirection,bcheck); }
diff --git a/Tracking/TrkExtrapolation/TrkExEngine/src/StaticNavigationEngine.cxx b/Tracking/TrkExtrapolation/TrkExEngine/src/StaticNavigationEngine.cxx
index 685aa5ccc65..a18d05c646e 100644
--- a/Tracking/TrkExtrapolation/TrkExEngine/src/StaticNavigationEngine.cxx
+++ b/Tracking/TrkExtrapolation/TrkExEngine/src/StaticNavigationEngine.cxx
@@ -38,27 +38,26 @@ Trk::StaticNavigationEngine::~StaticNavigationEngine()
 // the interface method initialize
 StatusCode Trk::StaticNavigationEngine::initialize()
 {
-    EX_MSG_INFO( "init", "initialize()" );
     
     if (m_propagationEngine.retrieve().isFailure()){
-        EX_MSG_FATAL( "init", "failed to retrieve propagation engine '"<< m_propagationEngine << "'. Aborting." );
+        EX_MSG_FATAL("", "initialize", "", "failed to retrieve propagation engine '"<< m_propagationEngine << "'. Aborting." );
         return StatusCode::FAILURE;
     } else 
-        EX_MSG_INFO( "init", "successfully retrieved '" << m_propagationEngine << "'." );
+        EX_MSG_DEBUG("", "initialize", "", "successfully retrieved '" << m_propagationEngine << "'." );
     
     if (m_materialEffectsEngine.retrieve().isFailure()){
-        EX_MSG_FATAL( "init", "failed to retrieve material effect engine '"<< m_materialEffectsEngine << "'. Aborting." );
+        EX_MSG_FATAL("", "initialize", "", "failed to retrieve material effect engine '"<< m_materialEffectsEngine << "'. Aborting." );
         return StatusCode::FAILURE;
     } else 
-        EX_MSG_INFO( "init", "successfully retrieved '" << m_materialEffectsEngine << "'." );
-    
+        EX_MSG_DEBUG("", "initialize", "", "successfully retrieved '" << m_materialEffectsEngine << "'." );
+    EX_MSG_DEBUG("", "initialize", "", "successful" );
     return StatusCode::SUCCESS;
 }    
 
 // the interface method finalize
 StatusCode Trk::StaticNavigationEngine::finalize()
 {    
-    ATH_MSG_INFO( "finalize() successful" );    
+    EX_MSG_DEBUG("", "finalize", "", "successful" );    
     return StatusCode::SUCCESS;
 }
 
@@ -73,8 +72,8 @@ Trk::ExtrapolationCode Trk::StaticNavigationEngine::resolveBoundary(Trk::ExCellN
 StatusCode Trk::StaticNavigationEngine::updateTrackingGeometry() const {
     // retrieve the TrackingGeometry from the detector store 
     if (detStore()->retrieve(m_trackingGeometry, m_trackingGeometryName).isFailure()){
-        EX_MSG_FATAL( "tgeo", "Could not retrieve TrackingGeometry '" << m_trackingGeometryName << "' from DetectorStore." );
-        EX_MSG_FATAL( "tgeo", "  - probably the chosen layout is not supported / no cool tag exists. "                     );
+        EX_MSG_FATAL( "", "updateGeo", "", "Could not retrieve TrackingGeometry '" << m_trackingGeometryName << "' from DetectorStore." );
+        EX_MSG_FATAL( "", "updateGeo", "", "  - probably the chosen layout is not supported / no cool tag exists. "                     );
         return StatusCode::FAILURE;
     }
     return StatusCode::SUCCESS;
-- 
GitLab