diff --git a/DDRec/include/DDRec/Surface.h b/DDRec/include/DDRec/Surface.h
index d41216f1851f4a399677b348ab8f468ed1656ff4..f5c3277fc2809fba16bae40d2ffbec01cf0eb9f4 100644
--- a/DDRec/include/DDRec/Surface.h
+++ b/DDRec/include/DDRec/Surface.h
@@ -158,6 +158,12 @@ namespace DD4hep {
       /** Get Origin of local coordinate system on surface */
       virtual const Vector3D& origin() const { return object<SurfaceData>()._o ;}
 
+      /** Convert the global position to the local position (u,v) on the surface */
+      virtual Vector2D globalToLocal( const Vector3D& point) const ;
+      
+      /** Convert the global position to the local position (u,v) on the surface */
+      virtual Vector3D localToGlobal( const Vector2D& point) const ;
+
       /// Access to the material in opposite direction of the normal
       virtual const IMaterial& innerMaterial() const{  return  object<SurfaceData>()._innerMat ;  }
 
@@ -396,6 +402,12 @@ namespace DD4hep {
       /** Get Origin of local coordinate system on surface */
       virtual const Vector3D& origin() const { return _o ;}
 
+      /** Convert the global position to the local position (u,v) on the surface */
+      virtual Vector2D globalToLocal( const Vector3D& point) const ;
+      
+      /** Convert the global position to the local position (u,v) on the surface */
+      virtual Vector3D localToGlobal( const Vector2D& point) const ;
+
       /** Thickness of inner material */
       virtual double innerThickness() const { return _volSurf.innerThickness() ; }
 
diff --git a/DDRec/src/Surface.cpp b/DDRec/src/Surface.cpp
index bdebf7b5c92e11ede7f8b71f0579af35fb93c866..604a840cd1c882df672596df82b8974a63983bed 100644
--- a/DDRec/src/Surface.cpp
+++ b/DDRec/src/Surface.cpp
@@ -66,6 +66,31 @@ namespace DD4hep {
     }      
     
 
+    ISurface::Vector2D VolSurface::globalToLocal( const Vector3D& point) const {
+
+      Vector3D p = point - origin() ;
+
+      // create new orthogonal unit vectors
+      // FIXME: these vectors should be cached really ... 
+
+      double uv = u() * v() ;
+      Vector3D uprime = ( u() - uv * v() ).unit() ; 
+      Vector3D vprime = ( v() - uv * u() ).unit() ; 
+      double uup = u() * uprime ;
+      double vvp = v() * vprime ;
+      
+      return  ISurface::Vector2D(   p*uprime / uup ,  p*vprime / vvp ) ;
+    }
+    
+    Vector3D VolSurface::localToGlobal( const ISurface::Vector2D& point) const {
+
+      Vector3D g = origin() + point[0] * u() + point[1] * v() ;
+
+      return g ;
+    }
+
+
+
     /** Distance to surface */
     double VolPlane::distance(const Vector3D& point ) const {
 
@@ -74,8 +99,7 @@ namespace DD4hep {
     
     /// Checks if the given point lies within the surface
     bool VolPlane::insideBounds(const Vector3D& point, double epsilon) const {
-
-
+      
 #if 0
       double dist = std::abs ( distance( point ) ) ;
       
@@ -320,6 +344,31 @@ namespace DD4hep {
       return  mat ;
     }          
 
+
+    ISurface::Vector2D Surface::globalToLocal( const Vector3D& point) const {
+
+    Vector3D p = point - origin() ;
+
+      // create new orthogonal unit vectors
+      // FIXME: these vectors should be cached really ... 
+
+      double uv = u() * v() ;
+      Vector3D uprime = ( u() - uv * v() ).unit() ; 
+      Vector3D vprime = ( v() - uv * u() ).unit() ; 
+      double uup = u() * uprime ;
+      double vvp = v() * vprime ;
+      
+      return  ISurface::Vector2D(   p*uprime / uup ,  p*vprime / vvp ) ;
+    }
+    
+    
+    Vector3D Surface::localToGlobal( const ISurface::Vector2D& point) const {
+
+      Vector3D g = origin() + point[0] * u() + point[1] * v() ;
+      return g ;
+    }
+
+
     double Surface::distance(const Vector3D& point ) const {
 
       double pa[3] ;
diff --git a/DDSurfaces/include/DDSurfaces/ISurface.h b/DDSurfaces/include/DDSurfaces/ISurface.h
index 1efd20a6d943e2c8a54d79bd8cc2d5e496fdc687..f33b54d112050154451c3f2524eff7b549cedc34 100644
--- a/DDSurfaces/include/DDSurfaces/ISurface.h
+++ b/DDSurfaces/include/DDSurfaces/ISurface.h
@@ -13,7 +13,8 @@ namespace DDSurfaces {
 
   typedef long long int long64 ;
 
- /** Interface for tracking surfaces. 
+
+  /** Interface for tracking surfaces. 
    * The surface provides access to vectors for u,v,n and the orgigin and
    * the inner and outer materials with corresponding thicknesses.
    *  
@@ -24,6 +25,18 @@ namespace DDSurfaces {
   class ISurface {
     
   public:
+
+    /** Helper class for 2d vectors */
+    struct Vector2D{
+      double _x,_y ;
+      Vector2D() : _x(0.),_y(0.) {}
+      Vector2D(double x, double y ) : _x(x),_y(y) {}
+      double operator[](unsigned i) const { return i==0 ? _x : _y ; }  
+      double x() const { return _x ; } 
+      double y() const { return _y ; } 
+    };
+
+
     /// Destructor
     virtual ~ISurface() {}
     
@@ -45,6 +58,12 @@ namespace DDSurfaces {
     /// Access to the normal direction at the given point
     virtual Vector3D normal(const Vector3D& point = Vector3D() ) const =0 ;
     
+    /** Convert the global position to the local position (u,v) on the surface */
+    virtual Vector2D globalToLocal( const Vector3D& point) const=0 ;
+
+    /** Convert the global position to the local position (u,v) on the surface */
+    virtual Vector3D localToGlobal( const Vector2D& point) const=0 ;
+
     /** Get Origin of local coordinate system on surface */
     virtual const Vector3D& origin() const =0 ;
     
diff --git a/DDTest/src/test_surface.cc b/DDTest/src/test_surface.cc
index 4fb1ddd5509f18b9d644e1929a6fc3a00f9e6153..05a28561c11fe756481279ddb629d5d429be52c3 100644
--- a/DDTest/src/test_surface.cc
+++ b/DDTest/src/test_surface.cc
@@ -93,6 +93,54 @@ int main(int argc, char** argv ){
     test( surf.insideBounds(  Vector3D(  0.00003 ,  .23 ,  .42  )  ) , true , " insideBounds Vector3D(   0.00003 ,  .23 ,  .42  )   " ) ; 
 
 
+    // === test global to local =====
+
+    Vector3D point = o + 34.3 * u - 42.7 * v ; 
+
+    ISurface::Vector2D lp = surf.globalToLocal( point ) ;
+    //    std::cout << " --- local coordinates of " << point << " : (" << lp[0] << "," << lp[1] << ")" << std::endl ;
+    test(  STR( lp[0] ) == STR( 34.3 ) , true , " local u coordinate is 34.4 "  ) ;  
+    test(  STR( lp[1] ) == STR( -42.7 ) , true , " local v coordinate is -42.7 "  ) ;  
+
+    Vector3D pointPrime = surf.localToGlobal( lp ) ;
+    test(  pointPrime.isEqual( point ) , true , " point after global to local to global is the same " ) ;
+
+    // ----- test with rotated coordinates
+    Vector3D ur,vr ; 
+    ur.fill( 0. ,  cos( 3.5/180.*M_PI  ) ,  sin( 3.5/180.*M_PI  ) ) ;
+    vr.fill( 0. , -sin( 3.5/180.*M_PI  ) ,  cos( 3.5/180.*M_PI  ) ) ;
+    VolPlane surfR( vol , SurfaceType( SurfaceType::Sensitive ), thick/2, thick/2 , ur,vr,n,o ) ;
+
+    Vector3D pointR = o + 34.3 * ur - 42.7 * vr ; 
+
+    lp = surfR.globalToLocal( pointR ) ;
+    //    std::cout << " --- local coordinates of " << pointR << " : (" << lp[0] << "," << lp[1] << ")" << std::endl ;
+    test(  STR( lp[0] ) == STR( 34.3 ) , true , " local u coordinate is 34.4 "  ) ;  
+    test(  STR( lp[1] ) == STR( -42.7 ) , true , " local v coordinate is -42.7 "  ) ;  
+
+    Vector3D pointPrimeR = surfR.localToGlobal( lp ) ;
+    test(  pointPrimeR.isEqual( pointR ) , true , " point after global to local to global is the same " ) ;
+
+    // ----- test with non-orthogonal rotated coordinates
+    Vector3D vr2 ; 
+    vr2.fill( 0. , -sin( 35./180.*M_PI  ) ,  cos( 35./180.*M_PI  ) ) ;
+    VolPlane surfR2( vol , SurfaceType( SurfaceType::Sensitive ), thick/2, thick/2 , ur,vr2,n,o ) ;
+
+    Vector3D pointR2 = o + 34.3 * ur - 42.7 * vr2 ; 
+
+    lp = surfR2.globalToLocal( pointR2 ) ;
+    //    std::cout << " --- local coordinates of " << pointR << " : (" << lp[0] << "," << lp[1] << ")" << std::endl ;
+    test(  STR( lp[0] ) == STR( 34.3 ) , true , " local u coordinate is 34.4 "  ) ;  
+    test(  STR( lp[1] ) == STR( -42.7 ) , true , " local v coordinate is -42.7 "  ) ;  
+
+    Vector3D pointPrimeR2 = surfR2.localToGlobal( lp ) ;
+    test(  pointPrimeR2.isEqual( pointR2 ) , true , " point after global to local to global is the same " ) ;
+
+
+    //==================================================
+
+
+
     // --- test SurfaceMaterial
     SurfaceMaterial sm( mat ) ;