diff --git a/DDCore/include/DD4hep/Alignment.h b/DDCore/include/DD4hep/Alignment.h
new file mode 100644
index 0000000000000000000000000000000000000000..ccf71f992d3b18ae40e2517d5b46f838af1a679b
--- /dev/null
+++ b/DDCore/include/DD4hep/Alignment.h
@@ -0,0 +1,76 @@
+// $Id: Readout.h 951 2013-12-16 23:37:56Z Christian.Grefe@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_GEOMETRY_ALIGNMENT_H
+#define DD4HEP_GEOMETRY_ALIGNMENT_H
+
+// Framework include files
+#include "DD4hep/Objects.h"
+#include "DD4hep/Volumes.h"
+#include "TGeoPhysicalNode.h"
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Geometry namespace declaration
+   */
+  namespace Geometry {
+
+    class DetElement;
+
+    /** @class Alignment  Alignment.h DD4hep/Alignment.h
+     * 
+     *  See the documentation about the TGeoPhysicalNode for further
+     *  details.
+     *
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    class Alignment: public Handle<TGeoPhysicalNode> {
+    public:
+      /// Default constructor
+      Alignment();
+      /// Copy constructor
+      Alignment(const Alignment& c);
+      /// Constructor to be used when reading the already parsed object
+      template <typename Q> Alignment(const Handle<Q>& e)
+          : Handle<TGeoPhysicalNode>(e) {
+      }
+      /// Initializing constructor
+      Alignment(const std::string& path);
+      /// Assignment operator
+      Alignment& operator=(const Alignment& c);
+      /// Number of nodes in this branch
+      int numNodes() const;
+      /// Access the placement of this node
+      PlacedVolume placement()   const;
+      /// Access the placement of the mother of this node
+      PlacedVolume motherPlacement(int level_up = 1)   const;
+      /// Access the placement of a node in the chain of placements for this branch
+      /** Remeber the special cases:
+       *  nodePlacement(-1) == nodePlacement(numNodes()) = placement()
+       *  nodePlacement(numNodes()-1)  == motherPlacement() = TGeoPhysicalNode::GetMother()
+       *                    == direct mother of placement()
+       */
+      PlacedVolume nodePlacement(int level=-1)   const;
+
+      /// Align the PhysicalNode (translation only)
+      int align(const Position& pos, bool check = false, double overlap = 0.001);
+      /// Align the PhysicalNode (rotation only)
+      int align(const RotationZYX& rot, bool check = false, double overlap = 0.001);
+      /// Align the PhysicalNode (translation + rotation)
+      int align(const Position& pos, const RotationZYX& rot, bool check = false, double overlap = 0.001);
+    };
+
+  } /* End namespace Geometry               */
+} /* End namespace DD4hep                   */
+#endif    /* DD4HEP_GEOMETRY_ALIGNMENT_H    */
diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h
index 9bc66dde380552dd9e5e08972f8e4863ebcd94af..c5e0d91568f489bed88916cf10a4dcaf4e34def5 100644
--- a/DDCore/include/DD4hep/Detector.h
+++ b/DDCore/include/DD4hep/Detector.h
@@ -15,6 +15,7 @@
 #include "DD4hep/Objects.h"
 #include "DD4hep/Volumes.h"
 #include "DD4hep/Readout.h"
+#include "DD4hep/Alignment.h"
 #include "DD4hep/Segmentations.h"
 
 // C/C++ include files
diff --git a/DDCore/include/DD4hep/DetectorAlignment.h b/DDCore/include/DD4hep/DetectorAlignment.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c2b3d6737e229bc5bafd73e7e7db9b4a66d7893
--- /dev/null
+++ b/DDCore/include/DD4hep/DetectorAlignment.h
@@ -0,0 +1,49 @@
+// $Id: Readout.h 951 2013-12-16 23:37:56Z Christian.Grefe@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_GEOMETRY_DETECTORALIGNMENT_H
+#define DD4HEP_GEOMETRY_DETECTORALIGNMENT_H
+
+// Framework include files
+#include "DD4hep/Detector.h"
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Geometry namespace declaration
+   */
+  namespace Geometry {
+
+    class DetElement;
+
+    /** @class Alignment  Readoutn.h DD4hep/Alignment.h
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    class DetectorAlignment : public DetElement {
+    protected:
+    public:
+      /// Initializing constructor
+      DetectorAlignment(DetElement e);
+      /// Collect all placements from the detector element up to the world volume
+      void collectNodes(std::vector<PlacedVolume>& nodes);
+      /// Align the PhysicalNode of the placement of the detector element (translation only)
+      int align(const Position& pos, bool check = false, double overlap = 0.001);
+      /// Align the PhysicalNode of the placement of the detector element (rotation only)
+      int align(const RotationZYX& rot, bool check = false, double overlap = 0.001);
+      /// Align the PhysicalNode of the placement of the detector element (translation + rotation)
+      int align(const Position& pos, const RotationZYX& rot, bool check = false, double overlap = 0.001);
+    };
+
+  } /* End namespace Geometry                       */
+} /* End namespace DD4hep                           */
+#endif    /* DD4HEP_GEOMETRY_DETECTORALIGNMENT_H    */
diff --git a/DDCore/include/DD4hep/DetectorTools.h b/DDCore/include/DD4hep/DetectorTools.h
new file mode 100644
index 0000000000000000000000000000000000000000..d84cb7cf6a16782fc5271e962a2b67734b6ab50d
--- /dev/null
+++ b/DDCore/include/DD4hep/DetectorTools.h
@@ -0,0 +1,61 @@
+// $Id: Readout.h 951 2013-12-16 23:37:56Z Christian.Grefe@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_GEOMETRY_DETECTORTOOLS_H
+#define DD4HEP_GEOMETRY_DETECTORTOOLS_H
+
+// Framework include files
+#include "DD4hep/Detector.h"
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Geometry namespace declaration
+   */
+  namespace Geometry {
+
+    /** @class Detectortools  DetectorTools.h DD4hep/Detectortools.h
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    class DetectorTools {
+    public:
+      typedef std::vector<DetElement>   ElementPath;
+      typedef std::vector<PlacedVolume> PlacementPath;
+      /// Collect detector elements to the top detector element (world)
+      static void elementPath(DetElement elt, ElementPath& detectors);
+      /// Collect detector elements to any parent detector element
+      static void elementPath(DetElement parent, DetElement elt, ElementPath& detectors);
+      /// Collect detector elements placements to the top detector element (world) [fast, but may have holes!]
+      static void elementPath(DetElement elt, PlacementPath& nodes);
+
+      /// Collect detector elements placements to the top detector element (world) [no holes!]
+      static void placementPath(DetElement elt, PlacementPath& nodes);
+      /// Collect detector elements placements to the parent detector element [no holes!]
+      static void placementPath(DetElement parent, DetElement child, PlacementPath& nodes);
+      /// Find Child of PlacedVolume and assemble on the fly the path of PlacedVolumes
+      static bool findChild(PlacedVolume parent, PlacedVolume child, PlacementPath& path);
+      /// Create cached matrix to transform to positions to an upper level Placement
+      static TGeoMatrix* placementTrafo(const PlacementPath& nodes, bool inverse);
+
+      /// Find path between the child element and the parent element
+      static bool findParent(DetElement parent, DetElement child, ElementPath& detectors);
+      /// Assemble the path of the PlacedVolume selection
+      static std::string elementPath(const ElementPath& nodes);
+      /// Assemble the path of the PlacedVolume selection
+      static std::string nodePath(const PlacementPath& nodes);
+
+    };
+
+  } /* End namespace Geometry               */
+} /* End namespace DD4hep                   */
+#endif    /* DD4HEP_GEOMETRY_DETECTORTOOLS_H    */
diff --git a/DDCore/include/DD4hep/Printout.h b/DDCore/include/DD4hep/Printout.h
index bcfcf0ca2255aaa863b20d124eaf6cc87963ee9c..2f8f4251d4cb10f72ba32290a430b113d60fd439 100644
--- a/DDCore/include/DD4hep/Printout.h
+++ b/DDCore/include/DD4hep/Printout.h
@@ -39,7 +39,7 @@ namespace DD4hep {
   }
 
   enum PrintLevel {
-    NOLOG = 0, VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS
+    NOLOG = 0, VERBOSE=1, DEBUG=2, INFO=3, WARNING=4, ERROR=5, FATAL=6, ALWAYS
   };
 
   typedef size_t (*output_function_t)(void*, PrintLevel severity, const char*, const char*);
diff --git a/DDCore/include/DD4hep/Readout.h b/DDCore/include/DD4hep/Readout.h
index 9830fa13003e112dea43e3f6a5e1c0b080c1e53b..992ead8043368576b6dc756ce2403a72a3c294a0 100644
--- a/DDCore/include/DD4hep/Readout.h
+++ b/DDCore/include/DD4hep/Readout.h
@@ -74,35 +74,6 @@ namespace DD4hep {
       Segmentation segmentation() const;
     };
 
-    /** @class Alignment  Readoutn.h DD4hep/lcdd/Readout.h
-     *
-     * @author  M.Frank
-     * @version 1.0
-     */
-    struct Alignment: public Ref_t {
-      struct Object: public TNamed {
-        Volume volume;
-        /// Standard constructor
-        Object();
-        /// Default destructor
-        virtual ~Object();
-      };
-      /// Default constructor
-      Alignment()
-          : Ref_t() {
-      }
-      /// Constructor to be used when reading the already parsed object
-      template <typename Q> Alignment(const Handle<Q>& e)
-          : Ref_t(e) {
-      }
-      /// Initializing constructor
-      Alignment(const LCDD& doc, const std::string& name);
-      /// Additional data accessor
-      Object& _data() const {
-        return *data<Object>();
-      }
-    };
-
     /** @class Conditions  Readout.h DD4hep/lcdd/Readout.h
      *
      * @author  M.Frank
diff --git a/DDCore/include/DD4hep/VolumeManager.h b/DDCore/include/DD4hep/VolumeManager.h
index 31419cc42e446d228c43f66512aa41730351e4fb..4efa16e5215742f79fb30e9266a68fb6c934422b 100644
--- a/DDCore/include/DD4hep/VolumeManager.h
+++ b/DDCore/include/DD4hep/VolumeManager.h
@@ -268,7 +268,7 @@ namespace DD4hep {
       const TGeoMatrix& worldTransformation(VolumeID volume_id) const;
     };
 
-/// Enable printouts for debugging
+    /// Enable printouts for debugging
     std::ostream& operator<<(std::ostream& os, const VolumeManager& m);
 
   } /* End namespace Geometry               */
diff --git a/DDCore/src/Alignment.cpp b/DDCore/src/Alignment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9002451402923eecdee8240c64c817f28915137f
--- /dev/null
+++ b/DDCore/src/Alignment.cpp
@@ -0,0 +1,106 @@
+// $Id: Readout.cpp 985 2014-01-30 13:50:10Z markus.frank@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+// Framework include files
+#include "DD4hep/Alignment.h"
+#include "DD4hep/InstanceCount.h"
+#include "MatrixHelpers.h"
+
+// ROOT include files
+#include "TGeoMatrix.h"
+
+using namespace std;
+using namespace DD4hep;
+using namespace DD4hep::Geometry;
+
+namespace  {
+  int _align(TGeoPhysicalNode* n, TGeoMatrix* transform, bool check, double overlap) {
+    if ( n )  {
+      n->Align(transform, 0, check, overlap);
+      return 1;
+    }
+    throw runtime_error("DD4hep: Cannot align non existing physical node.");
+  }
+}
+
+/// Default constructor
+Alignment::Alignment() : Handle<TGeoPhysicalNode>() {
+}
+
+/// Copy constructor
+Alignment::Alignment(const Alignment& c) : Handle<TGeoPhysicalNode>(c) {
+}
+
+/// Initializing constructor to create a new object
+Alignment::Alignment(const string& path) {
+  //assign(new TGeoPhysicalNode(path.c_str()), path, "*");
+  m_element = new TGeoPhysicalNode(path.c_str());
+}
+
+/// Assignment operator
+Alignment& Alignment::operator=(const Alignment& c)  {
+  if ( &c != this )  {
+    m_element = c.ptr();
+  }
+  return *this;
+}
+
+/// Number of nodes in this branch
+int Alignment::numNodes() const  {
+  if ( isValid() )  {
+    return ptr()->GetLevel();
+  }
+  throw runtime_error("DD4hep: Attempt to access invalid aignment object. [Invalid Handle]");
+}
+
+/// Access the placement of this node
+PlacedVolume Alignment::placement()   const   {
+  if ( isValid() )  {
+    return PlacedVolume(ptr()->GetNode(0));
+  }
+  throw runtime_error("DD4hep: Attempt to access invalid aignment object. [Invalid Handle]");
+}
+
+/// Access the placement of a node in the chain of placements for this branch
+PlacedVolume Alignment::nodePlacement(int level)   const   {
+  if ( isValid() )  {
+    PlacedVolume pv = PlacedVolume(ptr()->GetNode(level));
+    if ( pv.isValid() ) return pv;
+    throw runtime_error("DD4hep: The object chain of "+string(placement().name())+
+			" is too short. [Invalid index]");
+  }
+  throw runtime_error("DD4hep: Attempt to access invalid aignment object. [Invalid Handle]");
+}
+
+/// Access the placement of the mother of this node
+PlacedVolume Alignment::motherPlacement(int level_up)   const    {
+  if ( isValid() )  {
+    Int_t ind = ptr()->GetLevel()-level_up;
+    if ( ind >= 0 )  {
+      return PlacedVolume(ptr()->GetMother(level_up));
+    }
+    throw runtime_error("DD4hep: This object "+string(placement().name())+" has not enough mothers. [Invalid index]");
+  }
+  throw runtime_error("DD4hep: Attempt to access invalid aignment object. [Invalid Handle]");
+}
+
+/// Align the PhysicalNode (translation only)
+int Alignment::align(const Position& pos, bool check, double overlap) {
+  return _align(ptr(),_translation(pos), check, overlap);
+}
+
+/// Align the PhysicalNode (rotation only)
+int Alignment::align(const RotationZYX& rot, bool check, double overlap) {
+  return _align(ptr(),_rotationZYX(rot), check, overlap);
+}
+
+/// Align the PhysicalNode (translation + rotation)
+int Alignment::align(const Position& pos, const RotationZYX& rot, bool check, double overlap) {
+  return _align(ptr(),_transform(pos,rot), check, overlap);
+}
diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp
index fbcadad981f2b4ab48b5afb458783072d4c5aaed..9f103ddd79056f7548ac6fed424abc6fecd8c9ca 100644
--- a/DDCore/src/Detector.cpp
+++ b/DDCore/src/Detector.cpp
@@ -9,6 +9,7 @@
 
 #include "DD4hep/InstanceCount.h"
 #include "DD4hep/IDDescriptor.h"
+#include "DD4hep/DetectorTools.h"
 #include "DD4hep/LCDD.h"
 #include "TGeoVolume.h"
 #include "TGeoMatrix.h"
@@ -17,6 +18,8 @@
 
 using namespace std;
 using namespace DD4hep::Geometry;
+typedef DetectorTools::PlacementPath PlacementPath;
+typedef DetectorTools::ElementPath   ElementPath;
 
 namespace {
   struct ExtensionEntry {
@@ -36,95 +39,6 @@ namespace {
   }
 }
 
-static bool find_child(TGeoNode* parent, TGeoNode* child, vector<TGeoNode*>& path) {
-  if (parent && child) {
-    if (parent == child) {
-      path.push_back(child);
-      return true;
-    }
-    TIter next(parent->GetVolume()->GetNodes());
-    for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
-      if (daughter == child) {
-        path.push_back(daughter);
-        return true;
-      }
-    }
-    next.Reset();
-    for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
-      bool res = find_child(daughter, child, path);
-      if (res) {
-        path.push_back(daughter);
-        return res;
-      }
-    }
-  }
-  return false;
-}
-
-static bool collect_detector_nodes(const vector<TGeoNode*>& det_nodes, vector<TGeoNode*>& nodes) {
-  if (det_nodes.size() < 1) {
-    return false;
-  }
-  if (det_nodes.size() < 2) {
-    return true;
-  }
-  for (size_t i = 0, n = det_nodes.size(); i < n - 1; ++i) {
-    if (!find_child(det_nodes[i + 1], det_nodes[i], nodes)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-/// Create cached matrix to transform to positions to an upper level DetElement
-static TGeoHMatrix* create_trafo(const vector<TGeoNode*>& det_nodes) {
-  if (det_nodes.size() < 2) {
-    return new TGeoHMatrix(*gGeoIdentity);
-  }
-  vector<TGeoNode*> nodes;
-  if (!collect_detector_nodes(det_nodes, nodes)) {
-    throw runtime_error(
-        "DD4hep: DetElement cannot connect " + string(det_nodes[0]->GetName()) + " to child "
-            + string(det_nodes[1]->GetName()));
-  }
-  TGeoHMatrix* mat = new TGeoHMatrix(*gGeoIdentity);
-  for (vector<TGeoNode*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
-    TGeoMatrix* m = (*i)->GetMatrix();
-    mat->MultiplyLeft(m);
-  }
-  return mat;
-}
-
-/// Top detector element
-static DetElement _top(DetElement o, vector<TGeoNode*>& det_nodes) {
-  DetElement par = o, pp = o;
-  while (par.isValid()) {
-    if (par.placement().isValid()) {
-      det_nodes.push_back(par.placement().ptr());
-      pp = par;
-    }
-    par = par.parent();
-  }
-  return pp;
-}
-
-/// Top detector element
-static DetElement _par(DetElement o, DetElement top, vector<TGeoNode*>& det_nodes) {
-  DetElement par = o, pp = o;
-  while (par.isValid()) {
-    if (par.placement().isValid()) {
-      det_nodes.push_back(par.placement().ptr());
-      pp = par;
-    }
-    if (par.ptr() == top.ptr())
-      break;
-    par = par.parent();
-  }
-  if (pp.ptr() == top.ptr())
-    return pp;
-  return DetElement();
-}
-
 /// Default constructor
 DetElement::Object::Object()
     : TNamed(), magic(magic_word()), id(0), combineHits(0),   // readout(),
@@ -208,10 +122,9 @@ DetElement::Object::operator Ref_t() {
 /// Create cached matrix to transform to world coordinates
 TGeoMatrix* DetElement::Object::worldTransformation() {
   if (!worldTrafo) {
-    vector<TGeoNode*> det_nodes;
-    _top(DetElement(asRef()), det_nodes);
-    TGeoHMatrix* mat = create_trafo(det_nodes);
-    worldTrafo = mat;
+    PlacementPath nodes;
+    DetectorTools::placementPath(DetElement(asRef()), nodes);
+    worldTrafo = DetectorTools::placementTrafo(nodes,true);
   }
   return worldTrafo;
 }
@@ -219,10 +132,9 @@ TGeoMatrix* DetElement::Object::worldTransformation() {
 /// Create cached matrix to transform to parent coordinates
 TGeoMatrix* DetElement::Object::parentTransformation() {
   if (!parentTrafo) {
-    vector<TGeoNode*> det_nodes;
-    det_nodes.push_back(placement.ptr());
-    det_nodes.push_back(DetElement(parent).placement().ptr());
-    parentTrafo = create_trafo(det_nodes);
+    PlacementPath nodes;
+    DetectorTools::placementPath(DetElement(parent), DetElement(asRef()), nodes);
+    parentTrafo = DetectorTools::placementTrafo(nodes,true);
   }
   return parentTrafo;
 }
@@ -230,25 +142,25 @@ TGeoMatrix* DetElement::Object::parentTransformation() {
 /// Create cached matrix to transform to reference coordinates
 TGeoMatrix* DetElement::Object::referenceTransformation() {
   if (!referenceTrafo) {
-    vector<TGeoNode*> nodes;
-    DetElement ref(reference);
-    DetElement self(asRef());
-    DetElement elt = _par(self, ref, nodes);
-    if (elt.isValid()) {
-      referenceTrafo = create_trafo(nodes);
+    ElementPath elements;
+    DetElement  ref(reference);
+    DetElement  self(asRef());
+    if ( ref.ptr() == self.ptr() )  {
+      referenceTrafo = new TGeoHMatrix(gGeoIdentity->Inverse());
     }
-    else {
-      nodes.clear();
-      DetElement me(this->asRef());
-      DetElement elt = _par(ref, me, nodes);
-      if (!elt.isValid()) {
-        throw runtime_error(
-            "DD4hep: referenceTransformation: No path from " + string(self.name()) + " to reference element "
-                + string(ref.name()) + " present!");
-      }
-      TGeoMatrix* m = create_trafo(nodes);
-      referenceTrafo = new TGeoHMatrix(m->Inverse());
-      delete m;
+    else if ( DetectorTools::findParent(ref,self,elements) ) {
+      PlacementPath nodes;
+      DetectorTools::placementPath(ref, self, nodes);
+      referenceTrafo = DetectorTools::placementTrafo(nodes,true);
+    }
+    else if ( DetectorTools::findParent(self,ref,elements) ) {
+      PlacementPath nodes;
+      DetectorTools::placementPath(self, ref, nodes);
+      referenceTrafo = DetectorTools::placementTrafo(nodes,true);
+    }
+    else  {
+      throw runtime_error("DD4hep: referenceTransformation: No path from " + string(self.name()) + 
+			  " to reference element " + string(ref.name()) + " present!");
     }
   }
   return referenceTrafo;
@@ -313,16 +225,9 @@ string DetElement::placementPath() const {
   if (isValid()) {
     Object& o = object<Object>();
     if (o.placementPath.empty()) {
-      string res = "";
-      vector<TGeoNode*> nodes, path;
-      _top(*this, nodes);
-      if (!collect_detector_nodes(nodes, path)) {
-        throw runtime_error("DD4hep: DetElement cannot determine placement path of " + string(name()));
-      }
-      path.push_back(gGeoManager->GetTopNode());
-      for (vector<TGeoNode*>::const_reverse_iterator i = path.rbegin(); i != path.rend(); ++i)
-        res += (string("/") + (*i)->GetName());
-      o.placementPath = res;
+      PlacementPath path;
+      DetectorTools::placementPath(*this, path);
+      o.placementPath = DetectorTools::nodePath(path);
     }
     return o.placementPath;
   }
@@ -454,7 +359,7 @@ DetElement& DetElement::setPlacement(const PlacedVolume& placement) {
       Object& o = object<Object>();
       o.placement = placement;
       //o.volume = placement.volume();
-      placement.setDetector(*this);
+      //placement.setDetector(*this);
       return *this;
     }
     throw runtime_error("DD4hep: DetElement::setPlacement: Placement is not defined [Invalid Handle]");
diff --git a/DDCore/src/DetectorAlignment.cpp b/DDCore/src/DetectorAlignment.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b7d58d2deea139ce58336d1a32262445b1b9d36d
--- /dev/null
+++ b/DDCore/src/DetectorAlignment.cpp
@@ -0,0 +1,135 @@
+// $Id: Readout.cpp 985 2014-01-30 13:50:10Z markus.frank@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#include "DD4hep/DetectorAlignment.h"
+#include "DD4hep/DetectorTools.h"
+#include "DD4hep/InstanceCount.h"
+
+using namespace std;
+using namespace DD4hep;
+using namespace DD4hep::Geometry;
+
+typedef DetectorTools::ElementPath   ElementPath;
+typedef DetectorTools::PlacementPath PlacementPath;
+typedef vector<pair<int,DetElement> > LevelElements;
+namespace {
+
+  Alignment& _alignment(DetectorAlignment& det)  {
+    DetElement::Object& e = det._data();
+    if ( !e.alignment.isValid() )  {
+      DetectorTools::PlacementPath nodes;
+      DetectorTools::placementPath(det,nodes);
+      string path = DetectorTools::nodePath(nodes);
+      //cout << "Align path:" << path << endl;
+      e.alignment = Alignment(path);
+    }
+    return e.alignment;
+  }
+  void _dumpParentElements(DetectorAlignment& det, LevelElements& elements)   {
+    PlacementPath nodes;
+    ElementPath   det_nodes;
+    DetectorTools::placementPath(det,nodes);
+    DetectorTools::elementPath(det,det_nodes);
+    ///    cout << "Placement path:";
+    int level = 0;
+    PlacementPath::const_reverse_iterator j=nodes.rbegin();
+    ElementPath::const_reverse_iterator   k=det_nodes.rbegin();
+    for(; j!=nodes.rend(); ++j, ++level)  {
+      //cout << "(" << level << ") " << (void*)((*j).ptr()) 
+      //	   << " " << string((*j)->GetName()) << " ";
+      if ( ::strcmp((*j).ptr()->GetName(),(*k).placement().ptr()->GetName()) )  {
+	//cout << "[DE]";
+	elements.push_back(make_pair(level,*k));
+	++k;
+      }
+      else  {
+	//elements.push_back(make_pair(level,DetElement()));
+      }
+      //cout << " ";
+    }
+    //cout << endl;
+  }
+  void _patchParentElements(DetectorAlignment& det)   {
+    DetElement::Object& obj = det._data();
+    Alignment a = obj.alignment;
+    TGeoPhysicalNode* n = a.ptr();
+    string path;
+    path.reserve(1024);
+    int level = -1;
+    
+    size_t path_len = ::strlen(a->GetName());
+    for(int i = 0; i <= n->GetLevel(); ++i)  {
+      path += "/";
+      path += n->GetNode(i)->GetName();
+      if ( path.length() == path_len && path == a->GetName() ) level = i;
+    }
+    //cout << "Physical node: " << path << endl;
+    PlacedVolume pv(n->GetNode(level));
+    det.setPlacement(pv);
+#if 0
+    cout << "Updated placement of DetElement[" << level << "] " << det.name() 
+	 << " Placement: " << (void*)det.placement().ptr()
+	 << " / " << n->GetNode(level)
+	 << endl;
+    cout << "Placement path:";
+    PlacementPath nodes;
+    DetectorTools::placementPath(det,nodes);
+    for(PlacementPath::const_reverse_iterator j=nodes.rbegin(); j!=nodes.rend(); ++j)
+      cout << (void*)((*j).ptr()) << "  " << (*j)->GetName() << "  ";
+    cout << endl;
+#endif
+    cout << " Path:";
+    for(int i = 0; i <= n->GetLevel(); ++i)
+      cout << (void*)(n->GetNode(i)) << "  " << n->GetNode(i)->GetName() << "  ";
+    cout << " / " << (void*)pv.ptr() << endl;
+
+    TGeoNode* p = n->GetNode(n->GetLevel()-1);
+    TGeoNode* d = n->GetNode(n->GetLevel());
+    if ( strcmp(d->GetName(),"MuonBarrel_layer9_slice1_0")==0 || 
+	 strcmp(d->GetName(),"MuonBarrel_layer9_slice9_8")==0) 
+      {
+      TIter next(p->GetVolume()->GetNodes());
+      // Now check next layer children
+      for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
+	cout << p->GetName() << " / " << (void*)p << " ---> " << daughter->GetName() << "  " << (void*)daughter << endl;
+      }
+    }
+  }
+}
+
+/// Initializing constructor
+DetectorAlignment::DetectorAlignment(DetElement e)
+  : DetElement(e)
+{
+}
+
+/// Collect all placements from the detector element up to the world volume
+void DetectorAlignment::collectNodes(vector<PlacedVolume>& nodes)   {
+  DetectorTools::placementPath(*this,nodes);
+}
+
+/// Align the PhysicalNode of the placement of the detector element (translation only)
+int DetectorAlignment::align(const Position& pos, bool check, double overlap) {
+  int result = _alignment(*this).align(pos,check,overlap);
+  _patchParentElements(*this);
+  return result;
+}
+
+/// Align the PhysicalNode of the placement of the detector element (rotation only)
+int DetectorAlignment::align(const RotationZYX& rot, bool check, double overlap) {
+  int result = _alignment(*this).align(rot,check,overlap);
+  _patchParentElements(*this);
+  return result;
+}
+
+/// Align the PhysicalNode of the placement of the detector element (translation + rotation)
+int DetectorAlignment::align(const Position& pos, const RotationZYX& rot, bool check, double overlap) {
+  int result = _alignment(*this).align(pos,rot,check,overlap);
+  _patchParentElements(*this);
+  return result;
+}
diff --git a/DDCore/src/DetectorTools.cpp b/DDCore/src/DetectorTools.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d919d46b18759ec686dc36b773f840726f0c3829
--- /dev/null
+++ b/DDCore/src/DetectorTools.cpp
@@ -0,0 +1,187 @@
+// $Id: Readout.cpp 985 2014-01-30 13:50:10Z markus.frank@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+// Framework include files
+#include "DD4hep/DetectorTools.h"
+#include "DD4hep/Printout.h"
+#include <stdexcept>
+#include <memory>
+
+// ROOT include files
+#include "TGeoMatrix.h"
+
+using namespace std;
+using namespace DD4hep;
+using namespace DD4hep::Geometry;
+
+/// Assemble the path of the PlacedVolume selection
+std::string DetectorTools::nodePath(const PlacementPath& nodes)  {
+  string s="";
+  for(PlacementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
+    s += "/" + string((*i)->GetName());
+  return s;
+}
+
+/// Assemble the path of the PlacedVolume selection
+std::string DetectorTools::elementPath(const ElementPath& nodes)  {
+  string s = "";
+  for(ElementPath::const_reverse_iterator i=nodes.rbegin();i!=nodes.rend();++i)
+    s += "/" + string((*i)->GetName());
+  return s;
+}
+
+/// Collect detector elements to any parent detector element
+bool DetectorTools::findParent(DetElement parent, DetElement elt, vector<DetElement>& detectors)  {
+  detectors.clear();
+  if ( parent.isValid() && elt.isValid() )  {
+    if ( parent.ptr() == elt.ptr() )  {
+      detectors.push_back(elt);
+      return true;
+    }
+    ElementPath elements;
+    for(DetElement par = elt; par.isValid(); par = par.parent())  {
+      elements.push_back(par);
+      if ( par.ptr() == parent.ptr() )  {
+	detectors = elements;
+	return true;
+      }
+    }
+  }
+  throw runtime_error("Search for parent detector element with invalid handles not allowed.");
+}
+
+/// Find Child of PlacedVolume and assemble on the fly the path of PlacedVolumes
+bool DetectorTools::findChild(PlacedVolume parent, PlacedVolume child, PlacementPath& path) {
+  if ( parent.isValid() && child.isValid() ) {
+    // Check self
+    if ( parent.ptr() == child.ptr() ) {
+      path.push_back(child);
+      return true;
+    }    
+    TIter next(parent->GetVolume()->GetNodes());
+    // Now check next layer children
+    for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
+      if ( daughter == child.ptr() ) {
+        path.push_back(daughter);
+        return true;
+      }
+    }
+    next.Reset();
+    // Finally crawl down the tree
+    for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
+      PlacementPath sub_path;
+      bool res = findChild(daughter, child, sub_path);
+      if (res) {
+	path.insert(path.end(), sub_path.begin(), sub_path.end());
+        path.push_back(daughter);
+        return res;
+      }
+    }
+  }
+  return false;
+}
+
+/// Find Child of PlacedVolume and assemble on the fly the path of PlacedVolumes
+static bool findChildByName(PlacedVolume parent, PlacedVolume child, DetectorTools::PlacementPath& path) {
+  if ( parent.isValid() && child.isValid() ) {
+    // Check self
+    if ( 0 == ::strcmp(parent.ptr()->GetName(),child.ptr()->GetName()) ) {
+      path.push_back(child);
+      return true;
+    }    
+    TIter next(parent->GetVolume()->GetNodes());
+    // Now check next layer children
+    for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
+      if ( 0 == ::strcmp(daughter->GetName(),child.ptr()->GetName()) ) {
+        path.push_back(daughter);
+        return true;
+      }
+    }
+    next.Reset();
+    // Finally crawl down the tree
+    for (TGeoNode *daughter = (TGeoNode*) next(); daughter; daughter = (TGeoNode*) next()) {
+      DetectorTools::PlacementPath sub_path;
+      bool res = findChildByName(daughter, child, sub_path);
+      if (res) {
+	path.insert(path.end(), sub_path.begin(), sub_path.end());
+        path.push_back(daughter);
+        return res;
+      }
+    }
+  }
+  return false;
+}
+
+/// Collect detector elements to the top detector element (world)
+void DetectorTools::elementPath(DetElement elt, vector<DetElement>& detectors) {
+  for(DetElement par = elt; par.isValid(); par = par.parent())
+    detectors.push_back(par);
+}
+
+/// Collect detector elements to any parent detector element
+void DetectorTools::elementPath(DetElement parent, DetElement elt, vector<DetElement>& detectors)  {
+  if ( findParent(parent,elt,detectors) ) 
+    return;
+  throw runtime_error(string("The detector element ")+parent.name()+string(" is no parent of ")+elt.name());
+}
+
+/// Collect detector elements placements to the top detector element (world) [fast, but may have holes!]
+void DetectorTools::elementPath(DetElement element, vector<PlacedVolume>& det_nodes) {
+  for(DetElement par = element; par.isValid(); par = par.parent())  {
+    PlacedVolume pv = par.placement();
+    if ( pv.isValid() ) {
+      det_nodes.push_back(pv);
+    }
+  }
+}
+
+/// Collect detector elements placements to the top detector element (world) [no holes!]
+void DetectorTools::placementPath(DetElement element, vector<PlacedVolume>& nodes)   {
+  PlacementPath det_nodes, all_nodes;
+  DetectorTools::elementPath(element,det_nodes);
+  for (size_t i = 0, n = det_nodes.size(); i < n-1; ++i)  {
+    if (!findChildByName(det_nodes[i + 1], det_nodes[i], nodes))  {
+      throw runtime_error("DD4hep: DetElement cannot determine placement path of " 
+			  + string(element.name()) + " [internal error]");
+    }
+  }
+  if ( det_nodes.size()>0 )   {
+    nodes.push_back(det_nodes.back());
+  }
+}
+
+/// Collect detector elements placements to the parent detector element [no holes!]
+void DetectorTools::placementPath(DetElement parent, DetElement child, PlacementPath& nodes)   {
+  ElementPath   det_nodes;
+  PlacementPath all_nodes;
+  DetectorTools::elementPath(parent,child,det_nodes);
+  for (size_t i = 0, n = det_nodes.size(); i < n-1; ++i) {
+    if (!findChild(det_nodes[i + 1], det_nodes[i], nodes)) {
+      throw runtime_error("Invalid placement path "+elementPath(det_nodes)+" [internal error]");
+    }
+  }
+  if ( det_nodes.size()>0 ) nodes.push_back(det_nodes.back());
+}
+
+/// Create cached matrix to transform to positions to an upper level Placement
+TGeoMatrix* DetectorTools::placementTrafo(const PlacementPath& nodes, bool inverse) {
+  if (nodes.size() < 2) {
+    return new TGeoHMatrix(*gGeoIdentity);
+  }
+  auto_ptr<TGeoHMatrix> mat(new TGeoHMatrix(*gGeoIdentity));
+  for (size_t i = 0, n=nodes.size(); n>0 && i < n-1; ++i)  {
+    const PlacedVolume& p = nodes[i];
+    TGeoMatrix* m = p->GetMatrix();
+    mat->MultiplyLeft(m);
+  }
+  if ( inverse )  {
+    auto_ptr<TGeoHMatrix> inv(new TGeoHMatrix(mat->Inverse()));
+    mat = inv;
+  }
+  return mat.release();
+}
diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp
index fa9e06c92c83d300f88eaa74c2cc130903407549..fe851d12558a35cf567e7540ceb923b43ec94dc0 100644
--- a/DDCore/src/Handle.cpp
+++ b/DDCore/src/Handle.cpp
@@ -396,7 +396,7 @@ INSTANTIATE(TGeoCompositeShape);
 
 // Volume Placements (needed by "Volumes.cpp")
 #include "TGeoPhysicalNode.h"
-INSTANTIATE_UNNAMED(TGeoPhysicalNode);
+INSTANTIATE(TGeoPhysicalNode);
 
 // Replicated Volumes (needed by "Volumes.cpp")
 #include "TGeoPatternFinder.h"
diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp
index ecc31e5ca98eee888be1d68d494d3227c1b6385d..9b3bc261b35a22f9b9a7ae7d867a02eecc46e02e 100644
--- a/DDCore/src/LCDDImp.cpp
+++ b/DDCore/src/LCDDImp.cpp
@@ -113,8 +113,8 @@ LCDDImp::LCDDImp()
   }
   {
     m_manager = gGeoManager;
-    m_manager->AddNavigator();
-    m_manager->SetCurrentNavigator(0);
+    //m_manager->AddNavigator();
+    //m_manager->SetCurrentNavigator(0);
     //cout << "Navigator:" << (void*)m_manager->GetCurrentNavigator() << endl;
   }
   //if ( 0 == gGeoIdentity )
diff --git a/DDCore/src/MatrixHelpers.cpp b/DDCore/src/MatrixHelpers.cpp
index 4e82874375b190eff43768901e2ac1ed1f45ecab..31f3e54d92d2f32481359d3898f2175dcd38dec6 100644
--- a/DDCore/src/MatrixHelpers.cpp
+++ b/DDCore/src/MatrixHelpers.cpp
@@ -31,12 +31,6 @@ TGeoRotation* DD4hep::Geometry::_rotation3D(const Rotation3D& rot3D) {
 }
 
 TGeoHMatrix* DD4hep::Geometry::_transform(const Transform3D& trans) {
-#if 0
-  TGeoHMatrix* tr = new TGeoHMatrix();
-  Double_t* t = tr->GetTranslation();
-  Double_t* r = tr->GetRotationMatrix();
-  trans.GetComponents(r[0],r[1],r[2],t[0],r[3],r[4],r[5],t[1],r[6],r[7],r[8],t[2]);
-#endif
   double t[3];
   RotationZYX rot;
   Position pos;
@@ -51,3 +45,16 @@ TGeoHMatrix* DD4hep::Geometry::_transform(const Transform3D& trans) {
   tr->SetDz(t[2]);
   return tr;
 }
+
+TGeoHMatrix* DD4hep::Geometry::_transform(const Position& pos, const RotationZYX& rot) {
+  double t[3];
+  TGeoHMatrix *tr = new TGeoHMatrix();
+  tr->RotateZ(rot.Phi() * RAD_2_DEGREE);
+  tr->RotateY(rot.Theta() * RAD_2_DEGREE);
+  tr->RotateX(rot.Psi() * RAD_2_DEGREE);
+  pos.GetCoordinates(t);
+  tr->SetDx(t[0]);
+  tr->SetDy(t[1]);
+  tr->SetDz(t[2]);
+  return tr;
+}
diff --git a/DDCore/src/MatrixHelpers.h b/DDCore/src/MatrixHelpers.h
index 41c6ff58f065352d4be26afb907961e72c7c1e1c..26c54b6c1449e92164d879ebc873477453dd85db 100644
--- a/DDCore/src/MatrixHelpers.h
+++ b/DDCore/src/MatrixHelpers.h
@@ -33,6 +33,7 @@ namespace DD4hep {
     TGeoRotation* _rotationZYX(const RotationZYX& rot);
     TGeoRotation* _rotation3D(const Rotation3D& rot);
     TGeoHMatrix* _transform(const Transform3D& trans);
+    TGeoHMatrix* _transform(const Position& pos, const RotationZYX& rot);
 
   } /* End namespace Geometry           */
 } /* End namespace DD4hep            */
diff --git a/DDCore/src/Readout.cpp b/DDCore/src/Readout.cpp
index d6c1471ea70cbb41758d778fa7a40c3611fd6128..9aa45cff8651125ddf88fded372f96435c30a833 100644
--- a/DDCore/src/Readout.cpp
+++ b/DDCore/src/Readout.cpp
@@ -79,21 +79,6 @@ Segmentation Readout::segmentation() const {
   return object<Object>().segmentation;
 }
 
-/// Standard constructor
-Alignment::Object::Object() {
-  InstanceCount::increment(this);
-}
-
-/// Default destructor
-Alignment::Object::~Object() {
-  InstanceCount::decrement(this);
-}
-
-/// Initializing constructor to create a new object
-Alignment::Alignment(const LCDD& /* lcdd */, const string& nam) {
-  assign(new Object(), nam, "alignment");
-}
-
 /// Standard constructor
 Conditions::Object::Object() {
   InstanceCount::increment(this);
diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp
index 7e2fae6db35a91e67f715f44ac80195da9adcb54..8ee4adaf328d347b885e27f0caeb8abc3cf5bbc6 100644
--- a/DDCore/src/VolumeManager.cpp
+++ b/DDCore/src/VolumeManager.cpp
@@ -453,23 +453,44 @@ bool VolumeManager::adoptPlacement(VolumeID /* sys_id */, Context* context) {
     o.volumes[vid] = context;
     o.detMask |= context->mask;
     //o.phys_volumes[pv.ptr()] = context;
-    err << "Inserted new volume:" << setw(6) << left << o.volumes.size() << " Ptr:" << (void*) context->placement.ptr() << " ["
-        << context->placement.name() << "]" << " ID:" << (void*) context->identifier << " Mask:" << (void*) context->mask;
+    err << "Inserted new volume:" << setw(6) << left << o.volumes.size() << " Ptr:" << (void*) pv.ptr() << " ["
+        << pv.name() << "]" << " ID:" << (void*) context->identifier << " Mask:" << (void*) context->mask;
     printout(DEBUG, "VolumeManager", err.str().c_str());
     return true;
   }
-  err << "Attempt to register twice volume with identical volID " << (void*) context->identifier << " Mask:"
-      << (void*) context->mask << " to detector " << o.detector.name() << " ptr:" << (void*) pv.ptr() << " -- "
-      << (*i).second->placement.ptr() << " pv:" << pv.name() << " clashes with " << (*i).second->placement.name()
+  err << "+++ Attempt to register duplicate volID " << (void*) context->identifier 
+      << " Mask:" << (void*) context->mask 
+      << " to detector " << o.detector.name() 
+      << " ptr:" << (void*) pv.ptr() 
+      << " Name:" << pv.name() 
       << " Sensitive:" << (pv.volume().isSensitive() ? "YES" : "NO") << endl;
+  printout(ERROR, "VolumeManager", "%s", err.str().c_str());
+  err.str("");
+  err << " !!!!!                      ++++ VolIDS ";
+  const PlacedVolume::VolIDs::Base& ids = context->volID;
+  for (PlacedVolume::VolIDs::Base::const_iterator vit = ids.begin(); vit != ids.end(); ++vit)
+    err << (*vit).first << "=" << (*vit).second << "; ";
+  printout(ERROR, "VolumeManager", "%s", err.str().c_str());
+  err.str("");
+  context = (*i).second;
+  pv = context->placement;
+  err << " !!!!!               +++ Clashing volID " << (void*) context->identifier 
+      << " Mask:" << (void*) context->mask 
+      << " to detector " << o.detector.name() 
+      << " ptr:" << (void*) pv.ptr() 
+      << " Name:" << pv.name() 
+      << " Sensitive:" << (pv.volume().isSensitive() ? "YES" : "NO") << endl;
+  printout(ERROR, "VolumeManager", "%s", err.str().c_str());
+  err.str("");
+
   goto Fail;
   Fail: {
-    err << "++++ VolIDS:";
+    err << " !!!!!                      ++++ VolIDS ";
     const PlacedVolume::VolIDs::Base& ids = context->volID;
     for (PlacedVolume::VolIDs::Base::const_iterator vit = ids.begin(); vit != ids.end(); ++vit)
       err << (*vit).first << "=" << (*vit).second << "; ";
   }
-  printout(ERROR, "VolumeManager", "++++[!!!] adoptPlacement: %s", err.str().c_str());
+  printout(ERROR, "VolumeManager", "%s", err.str().c_str());
   // throw runtime_error(err.str());
   return false;
 }