From 4845de3248a68e96662b8116eb58d71393018d31 Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Tue, 6 Sep 2016 15:10:24 +0000
Subject: [PATCH] Implemented alignment mechanism. Transformations untested.

---
 DDAlign/CMakeLists.txt                        |   9 +-
 DDAlign/include/DDAlign/AlignmentsManager.h   |  88 +++++
 DDAlign/src/AlignmentWriter.cpp               |  34 +-
 DDAlign/src/AlignmentsManager.cpp             | 304 +++++++++++++++++
 DDAlign/src/{ => plugins}/AlignmentParser.cpp |   2 +-
 DDAlign/src/plugins/AlignmentPlugins.cpp      |  53 +++
 DDCond/CMakeLists.txt                         |   2 +-
 .../DDCond/ConditionsDependencyCollection.h   |   2 +-
 .../DDCond/ConditionsDependencyHandler.h      |   7 +-
 DDCond/include/DDCond/ConditionsManager.h     |   2 +
 DDCond/include/DDCond/ConditionsPool.h        |   2 +-
 DDCond/src/ConditionsDependencyCollection.cpp |   4 +-
 DDCond/src/ConditionsDependencyHandler.cpp    |   7 +-
 DDCond/src/plugins/ConditionsUserPool.cpp     |   6 +-
 DDCore/include/DD4hep/AlignmentData.h         |  86 ++---
 DDCore/include/DD4hep/AlignmentTools.h        |   3 +
 DDCore/include/DD4hep/Alignments.h            | 116 +++++--
 DDCore/include/DD4hep/ConditionDerived.h      | 136 ++++----
 DDCore/include/DD4hep/Conditions.h            |  15 +-
 DDCore/include/DD4hep/DetAlign.h              |   2 +
 DDCore/include/DD4hep/MatrixHelpers.h         |  27 +-
 .../DD4hep/objects/AlignmentsInterna.h        |  22 +-
 DDCore/include/XML/UriReader.h                |   8 +
 DDCore/src/AlignmentData.cpp                  |  16 +-
 DDCore/src/AlignmentTools.cpp                 |  21 ++
 DDCore/src/Alignments.cpp                     |  82 ++++-
 DDCore/src/AlignmentsInterna.cpp              |  22 +-
 DDCore/src/Detector.cpp                       |   5 +-
 DDCore/src/DetectorInterna.cpp                |   2 +
 DDCore/src/IOV.cpp                            |   2 +-
 DDCore/src/MatrixHelpers.cpp                  |  75 +++--
 DDCore/src/XML/DocumentHandler.cpp            |   4 +-
 DDCore/src/XML/UriReader.cpp                  |  15 +
 DDDB/CMakeLists.txt                           |   5 +-
 DDDB/include/DDDB/DDDBConversion.h            |   1 +
 DDDB/include/DDDB/DDDBReader.h                |   4 +
 DDDB/src/CondDB2DDDB.cpp                      |  23 +-
 DDDB/src/DDDBAlignmentTest.cpp                | 311 ++++++------------
 DDDB/src/DDDBConditionsLoader.cpp             |   2 +
 DDDB/src/DDDBDerivedCondTest.cpp              |  10 +-
 DDDB/src/DDDBFileReader.cpp                   |  23 ++
 DDDB/src/DDDBReader.cpp                       |  28 +-
 cmake/run_test_package.sh                     |  12 +-
 examples/DDDB/CMakeLists.txt                  |  11 +-
 examples/DDDB/scripts/run_dddb.sh             |   6 +-
 45 files changed, 1125 insertions(+), 492 deletions(-)
 create mode 100644 DDAlign/include/DDAlign/AlignmentsManager.h
 create mode 100644 DDAlign/src/AlignmentsManager.cpp
 rename DDAlign/src/{ => plugins}/AlignmentParser.cpp (99%)
 create mode 100644 DDAlign/src/plugins/AlignmentPlugins.cpp

diff --git a/DDAlign/CMakeLists.txt b/DDAlign/CMakeLists.txt
index e2e11e0d4..7d6c72fba 100644
--- a/DDAlign/CMakeLists.txt
+++ b/DDAlign/CMakeLists.txt
@@ -10,9 +10,12 @@
 #
 #==========================================================================
 dd4hep_package(    DDAlign
-  USES             DDCore
+  USES             DDCore DDCond
   INCLUDE_DIRS     include
   INSTALL_INCLUDES include/DDAlign)
 
-#---DDAlign library --------------------------------------------------------------
-dd4hep_add_plugin ( DDAlign SOURCES src/*.cpp )
+#---DDCond library --------------------------------------------------------------
+dd4hep_add_package_library(DDAlign SOURCES src/*.cpp )
+
+#---DDAlign plugins -------------------------------------------------------------
+dd4hep_add_plugin(DDAlignPlugins SOURCES src/plugins/*.cpp )
diff --git a/DDAlign/include/DDAlign/AlignmentsManager.h b/DDAlign/include/DDAlign/AlignmentsManager.h
new file mode 100644
index 000000000..4afc80f5c
--- /dev/null
+++ b/DDAlign/include/DDAlign/AlignmentsManager.h
@@ -0,0 +1,88 @@
+// $Id$
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+#ifndef DD4HEP_DDALIGN_ALIGNMENTMANAGER_H
+#define DD4HEP_DDALIGN_ALIGNMENTMANAGER_H
+
+// Framework include files
+#include "DD4hep/Memory.h"
+#include "DD4hep/Alignments.h"
+#include "DD4hep/ConditionDerived.h"
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the conditions part of the AIDA detector description toolkit
+  namespace Conditions   {
+    class UserPool;
+    class ConditionDependency;
+    class ConditionUpdateContext;
+    class ConditionsDependencyCollection;
+  }
+  
+  /// Namespace for the alignment part of the AIDA detector description toolkit
+  namespace Alignments {
+
+    /// Forward declarations
+    class AlignmentsManagerObject;
+    
+    /// Alignment manager instance to handle alignment dependencies
+    /**
+     *  \author   M.Frank
+     *  \version  1.0
+     *  \ingroup  DD4HEP_ALIGN
+     */
+    class AlignmentsManager : public Handle<AlignmentsManagerObject> {
+    public:
+      /// Standard object type
+      typedef AlignmentsManagerObject                    Object;
+      /// Conditions derivation context
+      typedef Conditions::ConditionUpdateContext         Context;
+      /// Alignments re-use conditions dependency definition from the conditions manager
+      typedef Conditions::ConditionDependency            Dependency;
+      /// Alignments re-use conditions dependency container def from the conditions manager
+      typedef Conditions::ConditionsDependencyCollection Dependencies;
+      
+    public:
+      /// Initializing constructor
+      AlignmentsManager(Object* p) : Handle<Object>(p) {}
+      /// Constructor to be used when reading the already parsed object
+      AlignmentsManager(const Handle<Object>& e) : Handle<Object>(e) {}
+      /// Constructor to be used when reading the already parsed object
+      template <typename Q> AlignmentsManager(const Handle<Q>& e) : Handle<Object>(e) {}
+      /// Initializing constructor. Creates the object!
+      AlignmentsManager(const std::string& name);
+      /// Initializing constructor. Creates the object!
+      AlignmentsManager(char const* name);
+      /// Default destructor
+      ~AlignmentsManager() {}
+      /// Delete the manager. Be careful: this affects all referencing handles!
+      void destroy();
+      /// Adopy alignment dependency for later recalculation
+      void adoptDependency(Dependency* dependency)  const;
+      /// Access all known dependencies
+      const Dependencies& knownDependencies()  const;
+      /// Compute all alignment conditions of the internal dependency list
+      void compute(dd4hep_ptr<UserPool>& user_pool)  const;
+      /// Compute all alignment conditions of the specified dependency list
+      void compute(dd4hep_ptr<UserPool>& user_pool, const Dependencies& deps)  const;
+      /// Register new updated derived alignment during the computation step
+      static void newEntry(const Context& parameter,
+                           DetElement& det,
+                           const Dependency* dep,
+                           AlignmentCondition& con);
+    };
+
+  }       /* End namespace Geometry                    */
+}         /* End namespace DD4hep                      */
+#endif    /* DD4HEP_DDALIGN_ALIGNMENTMANAGER_H         */
diff --git a/DDAlign/src/AlignmentWriter.cpp b/DDAlign/src/AlignmentWriter.cpp
index 829590d7b..d6d9cb032 100644
--- a/DDAlign/src/AlignmentWriter.cpp
+++ b/DDAlign/src/AlignmentWriter.cpp
@@ -15,11 +15,10 @@
 // Framework includes
 #include "DDAlign/AlignmentWriter.h"
 
+#include "DD4hep/LCDD.h"
 #include "DD4hep/Printout.h"
 #include "DD4hep/MatrixHelpers.h"
-#include "DD4hep/DetectorTools.h"
 #include "DD4hep/objects/DetectorInterna.h"
-#include "DD4hep/DetFactoryHelper.h"
 #include "XML/DocumentHandler.h"
 #include "DDAlign/AlignmentTags.h"
 #include "DDAlign/AlignmentCache.h"
@@ -30,7 +29,6 @@
 // C/C++ include files
 #include <stdexcept>
 
-namespace DetectorTools = DD4hep::Geometry::DetectorTools;
 using DD4hep::Geometry::Position;
 using DD4hep::Geometry::Translation3D;
 using namespace DD4hep::Alignments;
@@ -153,33 +151,3 @@ long AlignmentWriter::write(XML::Document doc, const string& output)   const {
   XML::DocumentHandler docH;
   return docH.output(doc, output);
 }
-
-static long create_alignment_file(LCDD& lcdd, int argc, char** argv)   {
-  DetElement top;
-  string output, path = "/world";
-  bool enable_transactions = false;
-  for(int i=1; i<argc;++i) {
-    if ( argv[i][0]=='-' || argv[i][0]=='/' ) {
-      const char* p = ::strchr(argv[i],'=');
-      if ( p && strncmp(argv[i]+1,"-output",7)==0 )
-        output = p+1;
-      else if ( p && strncmp(argv[i]+1,"-path",5)==0 )
-        path = p+1;
-      else if ( strncmp(argv[i]+1,"-transactions",5)==0 )
-        enable_transactions = true;
-      else
-        throw runtime_error("AlignmentWriter: Invalid argument:"+string(argv[i]));
-    }
-  }
-  printout(ALWAYS,"AlignmentWriter",
-           "++++ Writing DD4hep alignment constants of the \"%s\" DetElement tree to file \"%s\"",
-           path.c_str(), output.c_str());
-  top = DetectorTools::findDaughterElement(lcdd.world(),path);
-  if ( top.isValid() )   {
-    AlignmentWriter wr(lcdd);
-    return wr.write(wr.dump(top,enable_transactions), output);
-  }
-  throw runtime_error("AlignmentWriter: Invalid top level element name:"+path);
-}
-
-DECLARE_APPLY(DDAlignmentWriter, create_alignment_file)
diff --git a/DDAlign/src/AlignmentsManager.cpp b/DDAlign/src/AlignmentsManager.cpp
new file mode 100644
index 000000000..8eddd84f1
--- /dev/null
+++ b/DDAlign/src/AlignmentsManager.cpp
@@ -0,0 +1,304 @@
+// $Id$
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include "DD4hep/Handle.inl"
+#include "DD4hep/Printout.h"
+#include "DD4hep/MatrixHelpers.h"
+#include "DDCond/ConditionsPool.h"
+#include "DDAlign/AlignmentsManager.h"
+
+using namespace DD4hep;
+using namespace DD4hep::Alignments;
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the alignment part of the AIDA detector description toolkit
+  namespace Alignments {
+
+    typedef Conditions::ConditionDependency Dependency;
+
+    struct AlignContext {
+      struct Entry {
+        const Dependency*           dep;
+        DetElement::Object*         det;
+        AlignmentCondition::Object* cond;
+        unsigned int key, top;
+      };
+      struct PathOrdering {
+        bool operator()(const DetElement& a, const DetElement& b) const
+        { return a.path() < b.path(); }
+      };
+      typedef std::map<DetElement,size_t,PathOrdering>  DetectorMap;
+      typedef std::map<unsigned int,size_t>             Keys;
+      typedef std::vector<Entry>                        Entries;
+
+      DetectorMap  detectors;
+      Keys         keys;
+      Entries      entries;
+      unsigned long long int magic;
+      AlignContext() : magic(magic_word()) {}
+      void newEntry(DetElement det, const Dependency* dep, AlignmentCondition::Object* con) {
+        if ( det.isValid() )  {
+          Entry entry;
+          unsigned int key = det.key();
+          entry.top  = 0;
+          entry.cond = con;
+          entry.dep  = dep;
+          entry.det  = det.ptr();
+          entry.key  = key;
+          detectors.insert(std::make_pair(det, entries.size()));
+          keys.insert(std::make_pair(key, entries.size()));
+          entries.insert(entries.end(), entry);
+        }
+      }
+    };
+    
+    /// Alignment manager.
+    /**
+     *  Uses internally the conditions mechanism to manager the alignment conditions.
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_ALIGNMENTS
+     */
+    class AlignmentsManagerObject : public NamedObject {
+    public:
+      typedef AlignmentsManager::Dependencies Dependencies;
+      typedef Conditions::Condition Condition;
+      
+      /// Full list of alignment dependencies
+      Dependencies         dependencies;
+      /// References to all alignment possibilities known
+      AlignContext         all_alignments;
+    
+      /// Compute the transformation from the closest detector element of the alignment to the world system
+      void to_world(AlignContext& new_alignments, UserPool& pool, DetElement det, TGeoHMatrix& mat)  const;
+      /// Compute all alignment conditions of the lower levels
+      void compute(AlignContext& new_alignments, UserPool& pool, DetElement child, int level) const;
+
+    public:
+      /// Initializing constructor
+      AlignmentsManagerObject();
+      /// Default destructor
+      virtual ~AlignmentsManagerObject();
+      /// Compute all alignment conditions of the internal dependency list
+      void compute(UserPool& user_pool) const;
+      /// Compute all alignment conditions of the specified dependency list
+      void compute(UserPool& user_pool, const Dependencies& deps) const;
+    };
+    
+  }       /* End namespace Geometry                    */
+}         /* End namespace DD4hep                      */
+
+
+DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentsManagerObject);
+
+/// Initializing constructor
+AlignmentsManagerObject::AlignmentsManagerObject() : NamedObject() {
+}
+  
+/// Default destructor
+AlignmentsManagerObject::~AlignmentsManagerObject()   {
+  dependencies.clear();
+}
+  
+void AlignmentsManagerObject::to_world(AlignContext& new_alignments, UserPool& pool, DetElement det, TGeoHMatrix& mat)  const  {
+  DetElement par = det.parent();
+  while( par.isValid() )   {
+    // If we find that the parent also got updated, directly take this transformation.
+    // Since we compute top-down, it is already valid!
+    AlignContext::Keys::const_iterator i = new_alignments.keys.find(par.key());
+    if ( i != new_alignments.keys.end() )  {
+      const AlignContext::Entry& e = new_alignments.entries[(*i).second];
+      AlignmentCondition cond(e.cond);
+      AlignmentData&     align = cond.data();
+      mat.MultiplyLeft(&align.worldTransformation());
+      return;
+    }
+    // The parent did not get updated: We have to search the the conditions pool if
+    // there is a still valid condition, which we can use to build the world transformation
+    // The parent's alignment condition by defintiion must be present in the pool,
+    // since it got updated in the past!
+    i = all_alignments.keys.find(par.key());
+    if ( i != all_alignments.keys.end() )  {
+      const AlignContext::Entry& e = all_alignments.entries[(*i).second];
+      Condition::key_type key = e.dep->target.hash;
+      AlignmentCondition cond = pool.get(key);
+      AlignmentData&    align = cond.data();
+      mat.MultiplyLeft(&align.worldTransformation());
+      return;
+    }
+    // There is no special alignment for this detector element.
+    // Hence to nominal (relative) transformation to the parent is valid
+    mat.MultiplyLeft(&par.nominal().detectorTransformation());
+    par = par.parent();
+  }
+}
+
+/// Compute all alignment conditions of the internal dependency list
+void AlignmentsManagerObject::compute(UserPool& user_pool)  const  {
+  compute(user_pool, dependencies);
+}
+  
+/// Compute all alignment conditions of the specified dependency list
+void AlignmentsManagerObject::compute(UserPool& pool, const Dependencies& deps) const  {
+  AlignContext::DetectorMap::const_iterator i;
+  AlignContext new_alignments;
+  new_alignments.entries.reserve(deps.size());
+  pool.compute(deps, &new_alignments);
+  std::string prev = "-----";
+  for(i=new_alignments.detectors.begin(); i!=new_alignments.detectors.end(); ++i)  {
+    AlignContext::Entry& e = new_alignments.entries[(*i).second];
+    DetElement         det = e.det;
+    const std::string&   p = det.path();
+    size_t idx = p.find(prev);
+    if ( idx == 0 )  {
+      continue;
+    }
+    prev = p;
+    printout(DEBUG,"Alignment","Update top Node: Lvl:%d Key:%08X: %s", det.level(), det.key(), p.c_str());
+    e.top = 1;
+  }
+  // We got now the top nodes of the new_alignments. From the top nodes we have to
+  // recursively calculate all changes downwards the lower levels!
+  // Note: The upper levels are already correct and do not need to be updated!
+  printout(INFO,"Alignment","Working down the tree....");
+  for(i=new_alignments.detectors.begin(); i != new_alignments.detectors.end(); ++i)  {
+    AlignContext::Entry& e = new_alignments.entries[(*i).second];
+    if ( e.top )     {
+      compute(new_alignments, pool, e.det, 0);
+    }
+  }
+}
+/// Compute the alignment delta for one detector element and it's alignment condition
+void computeDelta(AlignmentCondition cond, TGeoHMatrix& tr_delta)  {
+  const AlignmentData& align = cond.data();
+  const Delta&         delta = align.delta;
+  const TGeoHMatrix&     nom = align.detectorTransformation();
+  const Position&        pos = delta.translation;
+  const Translation3D&   piv = delta.pivot;
+  const RotationZYX&     rot = delta.rotation;
+
+  switch(delta.flags)   {
+  case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION+Delta::HAVE_PIVOT:
+    Geometry::_transform(tr_delta, Transform3D(Translation3D(pos)*piv*rot*(piv.Inverse())));
+    break;
+  case Delta::HAVE_TRANSLATION+Delta::HAVE_ROTATION:
+    Geometry::_transform(tr_delta, Transform3D(rot,pos));
+    break;
+  case Delta::HAVE_ROTATION+Delta::HAVE_PIVOT:
+    Geometry::_transform(tr_delta, Transform3D(piv*rot*(piv.Inverse())));
+    break;
+  case Delta::HAVE_ROTATION:
+    Geometry::_transform(tr_delta, rot);
+    break;
+  case Delta::HAVE_TRANSLATION:
+    Geometry::_transform(tr_delta, pos);
+    break;
+  default:
+    break;
+  }
+  tr_delta.MultiplyLeft(&nom);
+  align.detectorTrafo = tr_delta;
+  align.worldTrafo    = tr_delta;
+}
+/// Compute all alignment conditions of the lower levels
+void AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, DetElement det, int level) const  {
+  AlignContext::Keys::const_iterator k=new_alignments.keys.find(det.key());
+  bool has_cond    = k != new_alignments.keys.end();
+  const AlignContext::Entry* ent = has_cond ? &new_alignments.entries[(*k).second] : 0;
+
+  if ( ent )  {
+    char fmt[128];
+    TGeoHMatrix        tr_delta;
+    AlignmentCondition cond(ent->cond);
+    AlignmentData&     align = cond.data();
+    computeDelta(cond, tr_delta);
+    to_world(new_alignments, pool, det, align.worldTrafo);
+    align.trToWorld = Geometry::_transform(&align.worldTrafo);
+    ::snprintf(fmt,sizeof(fmt),"%%d %%%ds %%s %%08X: %%s IOV:%%s",2*level);
+    printout(DEBUG,"ComputeAlignment",fmt,
+             det.level(), "", has_cond ? "NO " : "YES",
+             det.key(), det.path().c_str(), cond.iov().str().c_str());
+  }
+  else  {
+    // DetElement 'det' has no specific alignment. If any of the children has one
+    // and any of the parents, 'to_world' should pick up all the proper components
+    // to build the proper world-transformation of the child.
+    // Hence, we do not have to recompute it's value.
+    // We just continue to trickle down to the children.
+    //
+    // Alternatively we could inject 'special' alignment conditions, which would depend
+    // on the parent...
+    // Under circumstances, this might be cheaper to re-compute.
+  }
+  const DetElement::Children& children = det.children();
+  for(auto c=children.begin(); c!=children.end(); ++c)    {
+    DetElement child = (*c).second;
+    compute(new_alignments, pool, child, level+1);
+  }
+}
+
+/// Initializing constructor
+AlignmentsManager::AlignmentsManager(const std::string& nam)   {
+  assign(new AlignmentsManagerObject(), nam, "alignmentmanager");
+}
+
+/// Initializing constructor
+AlignmentsManager::AlignmentsManager(char const* nam)   {
+  assign(new AlignmentsManagerObject(), nam ? nam : "", "alignmentmanager");
+}
+
+/// Delete the manager.
+void AlignmentsManager::destroy()  {
+  deletePtr(m_element);
+}
+
+/// Adopy alignment dependency for later recalculation
+void AlignmentsManager::adoptDependency(Dependency* dependency) const  {
+  Object* o = access();
+  o->dependencies.insert(dependency);
+  o->all_alignments.newEntry(dependency->detector, dependency, 0);
+}
+
+/// Access all known dependencies
+const AlignmentsManager::Dependencies& AlignmentsManager::knownDependencies()  const   {
+  return access()->dependencies;
+}
+
+/// Compute all alignment conditions of the internal dependency list
+void AlignmentsManager::compute(dd4hep_ptr<UserPool>& user_pool) const   {
+  Object* o = access();
+  o->compute(*(user_pool.get()), o->dependencies);
+}
+
+/// Compute all alignment conditions of the specified dependency list
+void AlignmentsManager::compute(dd4hep_ptr<UserPool>& user_pool, const Dependencies& deps) const  {
+  access()->compute(*(user_pool.get()), deps);
+}
+
+/// Register new updated derived alignment during the computation step
+void AlignmentsManager::newEntry(const Context& context,
+                                 DetElement& det,
+                                 const Dependency* dep,
+                                 AlignmentCondition& con)    {
+  // It must be ensured this is a valid object! Check magic word
+  AlignContext* o = static_cast<AlignContext*>(context.parameter);
+  if ( o && o->magic == magic_word() )  {
+    o->newEntry(det, dep, con.ptr());
+    return;
+  }
+}
diff --git a/DDAlign/src/AlignmentParser.cpp b/DDAlign/src/plugins/AlignmentParser.cpp
similarity index 99%
rename from DDAlign/src/AlignmentParser.cpp
rename to DDAlign/src/plugins/AlignmentParser.cpp
index 9b0b9ba18..e0df8b57c 100644
--- a/DDAlign/src/AlignmentParser.cpp
+++ b/DDAlign/src/plugins/AlignmentParser.cpp
@@ -1,4 +1,4 @@
-// $Id: $
+// $Id$
 //==========================================================================
 //  AIDA Detector description implementation for LCD
 //--------------------------------------------------------------------------
diff --git a/DDAlign/src/plugins/AlignmentPlugins.cpp b/DDAlign/src/plugins/AlignmentPlugins.cpp
new file mode 100644
index 000000000..14318c2e0
--- /dev/null
+++ b/DDAlign/src/plugins/AlignmentPlugins.cpp
@@ -0,0 +1,53 @@
+// $Id$
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework includes
+#include "DD4hep/Printout.h"
+#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/DetectorTools.h"
+
+using namespace std;
+using namespace DD4hep;
+
+#include "DDAlign/AlignmentWriter.h"
+
+namespace DetectorTools = DD4hep::Geometry::DetectorTools;
+static long create_alignment_file(Geometry::LCDD& lcdd, int argc, char** argv)   {
+  Geometry::DetElement top;
+  string output, path = "/world";
+  bool enable_transactions = false;
+  for(int i=1; i<argc;++i) {
+    if ( argv[i][0]=='-' || argv[i][0]=='/' ) {
+      const char* p = ::strchr(argv[i],'=');
+      if ( p && strncmp(argv[i]+1,"-output",7)==0 )
+        output = p+1;
+      else if ( p && strncmp(argv[i]+1,"-path",5)==0 )
+        path = p+1;
+      else if ( strncmp(argv[i]+1,"-transactions",5)==0 )
+        enable_transactions = true;
+      else
+        throw runtime_error("AlignmentWriter: Invalid argument:"+string(argv[i]));
+    }
+  }
+  printout(ALWAYS,"AlignmentWriter",
+           "++++ Writing DD4hep alignment constants of the \"%s\" DetElement tree to file \"%s\"",
+           path.c_str(), output.c_str());
+  top = DetectorTools::findDaughterElement(lcdd.world(),path);
+  if ( top.isValid() )   {
+    Alignments::AlignmentWriter wr(lcdd);
+    return wr.write(wr.dump(top,enable_transactions), output);
+  }
+  throw runtime_error("AlignmentWriter: Invalid top level element name:"+path);
+}
+DECLARE_APPLY(DDAlignmentWriter, create_alignment_file)
diff --git a/DDCond/CMakeLists.txt b/DDCond/CMakeLists.txt
index 0b3c2e2de..c9f75c550 100644
--- a/DDCond/CMakeLists.txt
+++ b/DDCond/CMakeLists.txt
@@ -18,4 +18,4 @@ dd4hep_package(    DDCond
 dd4hep_add_package_library(DDCond SOURCES src/*.cpp )
 
 #---DDCond components -----------------------------------------------------------
-dd4hep_add_plugin ( DDCondPlugins  SOURCES  src/plugins/*.cpp )
+dd4hep_add_plugin(DDCondPlugins  SOURCES  src/plugins/*.cpp )
diff --git a/DDCond/include/DDCond/ConditionsDependencyCollection.h b/DDCond/include/DDCond/ConditionsDependencyCollection.h
index 75a234594..79a678b27 100644
--- a/DDCond/include/DDCond/ConditionsDependencyCollection.h
+++ b/DDCond/include/DDCond/ConditionsDependencyCollection.h
@@ -107,7 +107,7 @@ namespace DD4hep {
       /// Mini-container interface: insert element by key
       std::pair<iterator,bool> insert(const Dependencies::value_type& entry);
       /// Insert new element by key
-      std::pair<iterator,bool> insert(Condition::key_type key, Dependency* dep);
+      std::pair<iterator,bool> insert(Dependency* dep);
       /// Create view by application of functor
       template <typename T> void for_each(const T& function)  const
       {  std::for_each(dependencies.begin(),dependencies.end(),function); }
diff --git a/DDCond/include/DDCond/ConditionsDependencyHandler.h b/DDCond/include/DDCond/ConditionsDependencyHandler.h
index fbbcd3b8c..c8ac20b3c 100644
--- a/DDCond/include/DDCond/ConditionsDependencyHandler.h
+++ b/DDCond/include/DDCond/ConditionsDependencyHandler.h
@@ -46,7 +46,9 @@ namespace DD4hep {
       UserPool&                  m_pool;
       /// Dependency container to be resolved.
       const Dependencies&        m_dependencies;
-  
+      /// User defined optional processing parameter
+      void*                      m_userParam;
+      
       /// Internal call to trigger update callback
       Condition::Object* do_callback(const ConditionDependency& dep) const;
 
@@ -54,7 +56,8 @@ namespace DD4hep {
       /// Initializing constructor
       ConditionsDependencyHandler(ConditionsManager::Object* mgr,
                                   UserPool& pool, 
-                                  const Dependencies& dependencies);
+                                  const Dependencies& dependencies,
+                                  void* user_param);
       /// Default destructor
       ~ConditionsDependencyHandler();
       /// ConditionResolver implementation: Access to the conditions manager
diff --git a/DDCond/include/DDCond/ConditionsManager.h b/DDCond/include/DDCond/ConditionsManager.h
index 135409e62..336431d99 100644
--- a/DDCond/include/DDCond/ConditionsManager.h
+++ b/DDCond/include/DDCond/ConditionsManager.h
@@ -34,6 +34,7 @@ namespace DD4hep {
     class ConditionsIOVPool;
     class ConditionDependency;
     class ConditionsDataLoader;
+    class ConditionUpdateContext;
     class ConditionsManagerObject;
     
     /// Manager class for condition handles
@@ -51,6 +52,7 @@ namespace DD4hep {
       typedef std::vector<IOVType>               IOVTypes;
       typedef std::map<IOVType*,Container>       TypeConditions;
       typedef std::map<DetElement,Container>     DetectorConditions;
+      typedef ConditionDependency                Dependency;
       typedef ConditionsDependencyCollection     Dependencies;
 
     public:
diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h
index dca41bc4e..332a5e4a0 100644
--- a/DDCond/include/DDCond/ConditionsPool.h
+++ b/DDCond/include/DDCond/ConditionsPool.h
@@ -177,7 +177,7 @@ namespace DD4hep {
       /// Prepare user pool for usage (load, fill etc.) according to required IOV
       virtual long prepare(const IOV& required) = 0;
       /// Evaluate and register all derived conditions from the dependency list
-      virtual long compute(const Dependencies& dependencies) = 0;
+      virtual long compute(const Dependencies& dependencies, void* user_param=0) = 0;
     };
 
   } /* End namespace Conditions             */
diff --git a/DDCond/src/ConditionsDependencyCollection.cpp b/DDCond/src/ConditionsDependencyCollection.cpp
index 5b1c3fc24..32abd7bdb 100644
--- a/DDCond/src/ConditionsDependencyCollection.cpp
+++ b/DDCond/src/ConditionsDependencyCollection.cpp
@@ -52,7 +52,7 @@ ConditionsDependencyCollection::insert(const Dependencies::value_type& entry)
 
 /// Insert new element by key
 std::pair<ConditionsDependencyCollection::iterator,bool>
-ConditionsDependencyCollection::insert(Condition::key_type key, Dependency* dep)   {
+ConditionsDependencyCollection::insert(Dependency* dep)   {
   dep->addRef();
-  return dependencies.insert(std::make_pair(key,Holder(dep)));
+  return dependencies.insert(std::make_pair(dep->key(),Holder(dep)));
 }
diff --git a/DDCond/src/ConditionsDependencyHandler.cpp b/DDCond/src/ConditionsDependencyHandler.cpp
index 022f6b809..1be9b0b26 100644
--- a/DDCond/src/ConditionsDependencyHandler.cpp
+++ b/DDCond/src/ConditionsDependencyHandler.cpp
@@ -22,8 +22,9 @@ using namespace DD4hep::Conditions;
 /// Default constructor
 ConditionsDependencyHandler::ConditionsDependencyHandler(ConditionsManager::Object* mgr,
                                                          UserPool& pool,
-                                                         const Dependencies& dependencies)
-  : m_manager(mgr), m_pool(pool), m_dependencies(dependencies)
+                                                         const Dependencies& dependencies,
+                                                         void* user_param)
+  : m_manager(mgr), m_pool(pool), m_dependencies(dependencies), m_userParam(user_param)
 {
 }
 
@@ -61,7 +62,7 @@ Condition::Object*
 ConditionsDependencyHandler::do_callback(const ConditionDependency& dep)  const {
   try  {
     Condition::iov_type iov(m_pool.validity().iovType);
-    ConditionUpdateCall::Context ctxt(*this, dep, iov.reset().invert());
+    ConditionUpdateCall::Context ctxt(*this, dep, m_userParam, iov.reset().invert());
     Condition          cond = (*dep.callback)(dep.target, ctxt);
     Condition::Object* obj  = cond.ptr();
     if ( obj )  {
diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp
index 832de1ca5..8a53e6452 100644
--- a/DDCond/src/plugins/ConditionsUserPool.cpp
+++ b/DDCond/src/plugins/ConditionsUserPool.cpp
@@ -69,7 +69,7 @@ namespace DD4hep {
       /// Prepare user pool for usage (load, fill etc.) according to required IOV
       virtual long prepare(const IOV& required);
       /// Evaluate and register all derived conditions from the dependency list
-      virtual long compute(const Dependencies& dependencies);
+      virtual long compute(const Dependencies& dependencies, void* user_param);
     };
 
   } /* End namespace Conditions             */
@@ -237,11 +237,11 @@ long ConditionsMappedUserPool<MAPPING>::prepare(const IOV& required)   {
 
 /// Evaluate and register all derived conditions from the dependency list
 template<typename MAPPING>
-long ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps)  {
+long ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps, void* user_param)  {
   long num_updates = 0;
   if ( !deps.empty() )  {
     typedef Dependencies _D;
-    ConditionsDependencyHandler handler(m_manager.ptr(), *this, deps);
+    ConditionsDependencyHandler handler(m_manager.ptr(), *this, deps, user_param);
     ConditionsPool* pool = m_manager->registerIOV(*m_iov.iovType, m_iov.keyData);
     // Loop over the dependencies and check if they have to be upgraded
     for(_D::const_iterator i = deps.begin(); i!=deps.end(); ++i)  {
diff --git a/DDCore/include/DD4hep/AlignmentData.h b/DDCore/include/DD4hep/AlignmentData.h
index b61d13eb8..691ef1bd4 100644
--- a/DDCore/include/DD4hep/AlignmentData.h
+++ b/DDCore/include/DD4hep/AlignmentData.h
@@ -32,6 +32,7 @@ namespace DD4hep {
     using Geometry::DetElement;
     using Geometry::RotationZYX;
     using Geometry::Transform3D;
+    using Geometry::Translation3D;
     using Geometry::Position;
     using Geometry::LCDD;
 
@@ -47,12 +48,21 @@ namespace DD4hep {
      */
     class Delta   {
     public:
-      typedef Position    Pivot;
-      Pivot        pivot;
-      Position     translation;
-      RotationZYX  rotation;
+      typedef Translation3D Pivot;
+      Pivot         pivot;
+      Position      translation;
+      RotationZYX   rotation;
+      unsigned int  flags;
+
+      enum AlignmentFlags {
+        HAVE_NONE         = 0,
+        HAVE_TRANSLATION  = 1<<2,
+        HAVE_ROTATION     = 1<<3,
+        HAVE_PIVOT        = 1<<4,
+      };
+
       /// Default constructor
-      Delta();
+      Delta() : flags(0) {}
       /// Copy constructor
       Delta(const Delta& c);
       /// Default destructor
@@ -61,6 +71,12 @@ namespace DD4hep {
       Delta& operator=(const Delta& c);
       /// Reset information to identity
       void clear();
+      /// Access flags: Check if the delta operation contains a translation
+      bool hasTranslation() const  {  return (flags&HAVE_TRANSLATION) != 0; }
+      /// Access flags: Check if the delta operation contains a rotation
+      bool hasRotation() const     {  return (flags&HAVE_ROTATION) != 0;    }
+      /// Access flags: Check if the delta operation contains a pivot
+      bool hasPivot() const        {  return (flags&HAVE_PIVOT) != 0;       }
     };
 
     /// Derived condition data-object definition
@@ -125,19 +141,16 @@ namespace DD4hep {
       /// Assignment operator necessary due to copy constructor
       AlignmentData& operator=(const AlignmentData& copy);
       /// Data accessor for decorator
-      inline AlignmentData& alignmentData()     { return *this; }
+      inline AlignmentData& data()                       {  return *this;         }
 
       /// Access the ideal/nominal alignment/placement matrix
       Alignment nominal() const;
       /// Create cached matrix to transform to world coordinates
-      const TGeoHMatrix& worldTransformation()  const
-      {  return worldTrafo;                                                       }
+      const TGeoHMatrix& worldTransformation()  const    {  return worldTrafo;    }
       /// Access the alignment/placement matrix with respect to the world
-      const TGeoHMatrix& detectorTransformation() const
-      {  return detectorTrafo;                                                    }
+      const TGeoHMatrix& detectorTransformation() const  {  return detectorTrafo; }
       /// Access the currently applied alignment/placement matrix
-      const Transform3D& localToWorld() const   
-      {  return trToWorld;                                                        }
+      const Transform3D& localToWorld() const            {  return trToWorld;     }
 
       /** Aliases for the transformation from local coordinates to the world system  */
       /// Transformation from local coordinates of the placed volume to the world system
@@ -209,8 +222,7 @@ namespace DD4hep {
       ~AlignmentDecorator()  {                                  }
 
       /// Data accessor
-      const AlignmentData& data()   const
-      { return T::alignmentData();                              }
+      const AlignmentData& data()   const { return T::data();   }
       /// Access to the DetElement node
       DetElement detector()   const
       {  return data().detector;                                }
@@ -267,32 +279,47 @@ namespace DD4hep {
       {  return data().delta;                                   }
 
       /// Set the delta alignment information
-      void setDelta(const Delta& del)
-      {  data().delta = del;                                    }
+      void setDelta(const Delta& del)      {
+        AlignmentData& d = data();
+        d.delta = del;
+      }
       /// Set the delta alignment if only a single translation
-      void setDelta(const Position& translation)
-      {  data().delta.translation = translation;                }
+      void setDelta(const Position& translation)      {
+        AlignmentData& d = data();
+        d.delta.translation = translation;
+        d.delta.flags |= Delta::HAVE_TRANSLATION;
+      }
       /// Set the delta alignment if only a single rotation
-      void setDelta(const RotationZYX& rotation)
-      {  data().delta.rotation = rotation;                      }
+      void setDelta(const RotationZYX& rotation)  {
+        AlignmentData& d = data();
+        d.delta.rotation = rotation;
+        d.delta.flags |= Delta::HAVE_ROTATION;
+      }
       /// Set the delta alignment as a composite of a translation and a rotation
       void setDelta(const Position& translation, RotationZYX& rotation)     {
         AlignmentData& d = data();
         d.delta.rotation = rotation;
         d.delta.translation = translation;
+        d.delta.flags |= Delta::HAVE_ROTATION;
+        d.delta.flags |= Delta::HAVE_TRANSLATION;
       }
       /// Set the delta alignment if only a single rotation around a pivot point
-      void setDeltaPivot(const Position& pivot, const RotationZYX& rotation)  {
+      void setDeltaPivot(const Translation3D& pivot, const RotationZYX& rotation)  {
         AlignmentData& d = data();
         d.delta.pivot = pivot;
         d.delta.rotation = rotation;
+        d.delta.flags |= Delta::HAVE_PIVOT;
+        d.delta.flags |= Delta::HAVE_ROTATION;
       }
       /// Set the delta alignment if a translation and a rotation around pivot
-      void setDeltaPivot(const Position& translation, const Position& pivot, const RotationZYX& rotation)  {
+      void setDeltaPivot(const Position& translation, const Translation3D& pivot, const RotationZYX& rotation)  {
         AlignmentData& d = data();
         d.delta.pivot = pivot;
         d.delta.rotation = rotation;
         d.delta.translation = translation;
+        d.delta.flags |= Delta::HAVE_PIVOT;
+        d.delta.flags |= Delta::HAVE_ROTATION;
+        d.delta.flags |= Delta::HAVE_TRANSLATION;
       }
     };
 
@@ -305,21 +332,6 @@ namespace DD4hep {
     AlignmentDecorator<T>::AlignmentDecorator(const AlignmentDecorator& c) : T(c)  {}
 
 
-    /**
-     *
-     *  \author  M.Frank
-     *  \version 1.0
-     *  \ingroup DD4HEP_CONDITIONS
-     */
-    class NamedAlignmentObject : public NamedObject, public AlignmentData  {
-    public:
-      /// Default constructor
-      NamedAlignmentObject(const std::string& nam, const std::string& tit="")
-        : NamedObject(nam,tit), AlignmentData()  {}
-      /// Default destructor
-      virtual ~NamedAlignmentObject();
-    };
-
   } /* End namespace Aligments                  */
 } /* End namespace DD4hep                       */
 #endif    /* DD4HEP_ALIGMENTS_ALIGNMENTDATA_H   */
diff --git a/DDCore/include/DD4hep/AlignmentTools.h b/DDCore/include/DD4hep/AlignmentTools.h
index e5e4eebeb..84eb94a9b 100644
--- a/DDCore/include/DD4hep/AlignmentTools.h
+++ b/DDCore/include/DD4hep/AlignmentTools.h
@@ -25,6 +25,9 @@ namespace DD4hep {
 
     namespace AlignmentTools   {
 
+      /// Copy alignment object from source object
+      void copy(Alignment from, Alignment to);
+
       /// Compute the ideal/nominal to-world transformation from the detector element placement
       /**
        *  Note: Detector information of the alignment data is filled by the caller!
diff --git a/DDCore/include/DD4hep/Alignments.h b/DDCore/include/DD4hep/Alignments.h
index db96f00e6..20b39cc63 100644
--- a/DDCore/include/DD4hep/Alignments.h
+++ b/DDCore/include/DD4hep/Alignments.h
@@ -15,36 +15,47 @@
 #define DD4HEP_ALIGMENTS_ALIGNMENTS_H
 
 // Framework include files
+#include "DD4hep/IOV.h"
 #include "DD4hep/Volumes.h"
 
 /// Namespace for the AIDA detector description toolkit
 namespace DD4hep {
 
+  /// Forward declarations
   class IOV;
 
+  /// Namespace for the conditions part of the AIDA detector description toolkit
+  namespace Conditions   {
+    class UserPool;
+    /// Conditions internal namespace
+    namespace Interna  {
+      class ConditionObject;
+    }
+  }
+  
   /// Namespace for the alignment part of the AIDA detector description toolkit
   namespace Alignments {
 
     using Geometry::LCDD;
     using Geometry::DetElement;
     using Geometry::PlacedVolume;
-
+    using Conditions::UserPool;
+    
     /// Alignments internal namespace
     namespace Interna  {
       /// Forward declarations
       class AlignmentContainer;
+      class AlignmentNamedObject;
+      class AlignmentConditionObject;
     }
     class AlignmentsManagerObject;
     class AlignmentsLoader;
     class AlignmentData;
     class Alignment;
-    class UserPool;
     class Delta;
 
-    /// Main handle class to hold a TGeo alignment object of type TGeoPhysicalNode
+    /// Main handle class to hold an alignment object
     /**
-     *  See the ROOT documentation about the TGeoPhysicalNode for further details:
-     *  @see http://root.cern.ch/root/html/TGeoPhysicalNode.html
      *
      *  \author  M.Frank
      *  \version 1.0
@@ -55,6 +66,8 @@ namespace DD4hep {
     public:
       /// Forward definition of the base data object containing alignment data
       typedef AlignmentData             Object;
+      /// Forward definition of the base data object containing alignment data
+      typedef AlignmentData             Data;
       /// Forward definition of the geometry placement
       typedef Geometry::PlacedVolume    PlacedVolume;
       /// Forward definition of the nodelist leading to the world
@@ -68,43 +81,29 @@ namespace DD4hep {
 
     public:
       /// Default constructor
-      Alignment();
+      Alignment() : Handle<Object>()  {}
       /// Default constructor
-      Alignment(Object* p);
-      /// Copy constructor
-      Alignment(const Alignment& c);
+      Alignment(Object* p) : Handle<Object>(p)  {}
       /// Constructor to be used when reading the already parsed object
-      template <typename Q> Alignment(const Handle<Q>& e) : Handle<Object>(e) {}
+      template <typename Q> Alignment(const Handle<Q>& e) : Handle<Object>(e)  {}
       /// Object constructor for pure alignment objects
-      Alignment(const std::string& name);
+      template <typename Q=Interna::AlignmentNamedObject> Alignment(const std::string& name);
 
       /// Hash code generation from input string
       static key_type hashCode(const char* value);
       /// Hash code generation from input string
       static key_type hashCode(const std::string& value);
 
-      /// Assignment operator
-      Alignment& operator=(const Alignment& c);
       /// Data accessor for the use of decorators
-      AlignmentData& alignmentData()              {   return (*access()); }
+      Data& data()              {   return (*access()); }
       /// Data accessor for the use of decorators
-      const AlignmentData& alignmentData() const  {   return (*access()); }
+      const Data& data() const  {   return (*access()); }
+      /// Create cached matrix to transform to world coordinates
+      const TGeoHMatrix& worldTransformation()  const;
+      /// Access the alignment/placement matrix with respect to the world
+      const TGeoHMatrix& detectorTransformation() const;
     };
 
-    /// Default constructor
-    inline Alignment::Alignment(Object* p) : Handle<Object>(p)  {}
-
-    /// Copy constructor
-    inline Alignment::Alignment(const Alignment& c) : Handle<Object>(c.ptr()) {}
-
-    /// Assignment operator
-    inline Alignment& Alignment::operator=(const Alignment& c)  {
-      if ( &c != this )  {
-        m_element = c.ptr();
-      }
-      return *this;
-    }
-
     /// Hash code generation from input string
     inline Alignment::key_type Alignment::hashCode(const char* value)
     {   return hash32(value);    }
@@ -113,6 +112,63 @@ namespace DD4hep {
     inline Alignment::key_type Alignment::hashCode(const std::string& value)
     {   return hash32(value);    }
 
+    /// Main handle class to hold an alignment conditions object
+    /**
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_GEOMETRY
+     *  \ingroup DD4HEP_ALIGN
+     */
+    class AlignmentCondition : public Handle<Interna::AlignmentConditionObject>   {
+    public:
+      /// Forward definition of the base data object containing alignment data
+      typedef Interna::AlignmentConditionObject Object;
+      /// Forward definition of the base data object containing alignment data
+      typedef AlignmentData             Data;
+      /// Forward definition of the geometry placement
+      typedef Geometry::PlacedVolume    PlacedVolume;
+      /// Forward definition of the nodelist leading to the world
+      typedef std::vector<PlacedVolume> NodeList;
+      /// Forward definition of the alignment delta data
+      typedef Alignments::Delta         Delta;
+      /// Forward definition of the key type
+      typedef unsigned int              key_type;
+      /// Forward definition of the iov type
+      typedef IOV                       iov_type;
+
+    public:
+      /// Default constructor
+      AlignmentCondition() : Handle<Object>() {}
+      /// Default constructor
+      AlignmentCondition(Object* p) : Handle<Object>(p) {}
+      /// Assignment constructor from condition object
+      AlignmentCondition(Conditions::Interna::ConditionObject* p) : Handle<Object>(p) {}
+      /// Constructor to be used when reading the already parsed object
+      template <typename Q> AlignmentCondition(const Handle<Q>& e) : Handle<Object>(e) {}
+      /// Object constructor for pure alignment objects
+      template <typename Q=Object> AlignmentCondition(const std::string& name);
+
+      /** Interval of validity            */
+      /// Access the IOV type
+      const IOVType& iovType()  const;
+      /// Access the IOV block
+      const iov_type& iov()  const;
+
+      /** Data block (bound type)         */
+      /// Data accessor for the use of decorators
+      Data& data();
+      /// Data accessor for the use of decorators
+      const Data& data() const;
+      /// Create cached matrix to transform to world coordinates
+      const TGeoHMatrix& worldTransformation()  const;
+      /// Access the alignment/placement matrix with respect to the world
+      const TGeoHMatrix& detectorTransformation() const;
+      /// Check if object is already bound....
+      bool is_bound()  const;
+    };
+
+
     /// Container class for alignment handles aggregated by a detector element
     /**
      *  Note: The alignments container is owner by the detector element
@@ -131,7 +187,7 @@ namespace DD4hep {
       typedef Alignment::key_type key_type;
       /// Forward definition of the iov type
       typedef Alignment::iov_type iov_type;
-
+      
     public:
       /// Default constructor
       Container();
diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h
index 66c4c8d73..fb47115a3 100644
--- a/DDCore/include/DD4hep/ConditionDerived.h
+++ b/DDCore/include/DD4hep/ConditionDerived.h
@@ -33,7 +33,7 @@ namespace DD4hep {
     class ConditionDependency;
     class ConditionUpdateCall;
 
-    /// 
+    /// ConditionResolver class used by the derived conditions calculation mechanism
     /**
      *  \author  M.Frank
      *  \version 1.0
@@ -55,6 +55,66 @@ namespace DD4hep {
       virtual const IOV& requiredValidity()  const = 0;
     };
 
+    /// ConditionUpdateContext class used by the derived conditions calculation mechanism
+    /** 
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_CONDITIONS
+     */
+    struct ConditionUpdateContext  {
+      const ConditionResolver&   resolver;
+      const ConditionDependency& dependency;
+      Condition::iov_type*       iov;
+      void*                      parameter;
+      /// Initializing constructor
+      ConditionUpdateContext(const ConditionResolver& r,
+                             const ConditionDependency& d,
+                             void* parameter,
+                             Condition::iov_type& iov);
+      /// Access to dependency keys
+      const ConditionKey& key(size_t which)  const;
+      /// Access to condition object by dependency index
+      Condition condition(size_t which)  const;
+      /// Access to condition object by dependency key
+      Condition condition(const ConditionKey& key_value)  const;
+      /// Access user parameter
+      template<typename Q> Q* param()  const  {
+        return static_cast<Q*>(parameter);
+      }
+      /// Access of other conditions data from the resolver
+      template<typename T> T& get(const ConditionKey& key_value)  {
+        Condition cond = resolver.get(key_value);
+        if ( cond.isValid() )  {
+          T& data = cond.get<T>();	    /// Bind data to wanted type
+          /// Update result IOV according by and'ing the new iov structure
+          iov->iov_intersection(cond.iov());
+          return data;
+        }
+        throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name);
+      }
+      /// Access of other conditions data from the resolver
+      template<typename T> const T& get(const ConditionKey& key_value)  const {
+        Condition cond = resolver.get(key_value);
+        if ( cond.isValid() )  {
+          const T& data = cond.get<T>();  /// Bind data to wanted type
+          /// Update result IOV according by and'ing the new iov structure
+          iov->iov_intersection(cond.iov());
+          return data;
+        }
+        throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name);
+      }
+      /// Access of other conditions data from the resolver
+      template<typename T> T& get(size_t key_id)  {
+        const ConditionKey& key_value = this->key(key_id);
+        return this->get<T>(key_value);
+      }
+      /// Access of other conditions data from the resolver
+      template<typename T> const T& get(size_t key_id)  const {
+        const ConditionKey& key_value = this->key(key_id);
+        return this->get<T>(key_value);
+      }
+    };
+
     /// Callback interface
     /**
      *  \author  M.Frank
@@ -63,57 +123,7 @@ namespace DD4hep {
      */
     class ConditionUpdateCall  {
     public:
-      /**
-       *  \author  M.Frank
-       *  \version 1.0
-       *  \ingroup DD4HEP_CONDITIONS
-       */
-      struct Context  {
-        const ConditionResolver&   resolver;
-        const ConditionDependency& dependency;
-        Condition::iov_type*       iov;
-
-        /// Initializing constructor
-        Context(const ConditionResolver& r, const ConditionDependency& d, Condition::iov_type& iov);
-        /// Access to dependency keys
-        const ConditionKey& key(size_t which)  const;
-        /// Access to condition object by dependency index
-        Condition condition(size_t which)  const;
-        /// Access to condition object by dependency key
-        Condition condition(const ConditionKey& key_value)  const;
-        /// Access of other conditions data from the resolver
-        template<typename T> T& get(const ConditionKey& key_value)  {
-          Condition cond = resolver.get(key_value);
-          if ( cond.isValid() )  {
-            T& data = cond.get<T>();	    /// Bind data to wanted type
-            /// Update result IOV according by and'ing the new iov structure
-            iov->iov_intersection(cond.iov());
-            return data;
-          }
-          throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name);
-        }
-        /// Access of other conditions data from the resolver
-        template<typename T> const T& get(const ConditionKey& key_value)  const {
-          Condition cond = resolver.get(key_value);
-          if ( cond.isValid() )  {
-            const T& data = cond.get<T>();  /// Bind data to wanted type
-            /// Update result IOV according by and'ing the new iov structure
-            iov->iov_intersection(cond.iov());
-            return data;
-          }
-          throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing item:"+key_value.name);
-        }
-        /// Access of other conditions data from the resolver
-        template<typename T> T& get(size_t key_id)  {
-          const ConditionKey& key_value = this->key(key_id);
-          return this->get<T>(key_value);
-        }
-        /// Access of other conditions data from the resolver
-        template<typename T> const T& get(size_t key_id)  const {
-          const ConditionKey& key_value = this->key(key_id);
-          return this->get<T>(key_value);
-        }
-      };
+      typedef ConditionUpdateContext Context;
     protected:
       /// Reference count
       int  m_refCount;
@@ -148,6 +158,9 @@ namespace DD4hep {
       typedef Geometry::DetElement       DetElement;
       /// Defintion of the depencency container
       typedef std::vector<ConditionKey>  Dependencies;
+      /// Forward definition of the key type
+      typedef Condition::key_type        key_type;
+
       /// Reference to the target's detector element
       DetElement                         detector;
       /// Key to the condition to be updated
@@ -172,10 +185,12 @@ namespace DD4hep {
       ConditionDependency(const ConditionKey& tar, ConditionUpdateCall* call);
       /// Default constructor
       ConditionDependency();
+      /// Access the dependency key
+      key_type key()  const           {  return target.hash;         }
       /// Add use count to the object
       ConditionDependency* addRef()   {  ++m_refCount; return this;  }
       /// Release object. May not be used any longer
-      void release()  {  if ( --m_refCount <= 0 ) delete this;      }
+      void release()  {  if ( --m_refCount <= 0 ) delete this;       }
     };
 
     /// Condition dependency builder
@@ -202,27 +217,28 @@ namespace DD4hep {
     };
 
     /// Initializing constructor
-    inline ConditionUpdateCall::Context::Context(const ConditionResolver& resolv,
-                                                 const ConditionDependency& dep,
-                                                 Condition::iov_type& iov_ref)
-      : resolver(resolv), dependency(dep), iov(&iov_ref)
+    inline ConditionUpdateContext::ConditionUpdateContext(const ConditionResolver& resolv,
+                                                          const ConditionDependency& dep,
+                                                          void* user_param,
+                                                          Condition::iov_type& iov_ref)
+      : resolver(resolv), dependency(dep), iov(&iov_ref), parameter(user_param)
     {
     }
 
     /// Access to dependency keys
-    inline const ConditionKey& ConditionUpdateCall::Context::key(size_t which)  const  {
+    inline const ConditionKey& ConditionUpdateContext::key(size_t which)  const  {
       return dependency.dependencies[which];
     }
 
     /// Access to condition object by dependency key
-    inline Condition ConditionUpdateCall::Context::condition(const ConditionKey& key_value)  const  {
+    inline Condition ConditionUpdateContext::condition(const ConditionKey& key_value)  const  {
       Condition c = resolver.get(key_value);
       if ( c.isValid() ) return c;
       throw std::runtime_error("ConditionUpdateCall: Failed to access non-existing condition:"+key_value.name);
     }
 
     /// Access to condition object by dependency index
-    inline Condition ConditionUpdateCall::Context::condition(size_t which)  const   {
+    inline Condition ConditionUpdateContext::condition(size_t which)  const   {
       const ConditionKey& key_value = this->key(which);
       return this->condition(key_value);
     }
diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h
index 9605a5839..7fa8ab3e6 100644
--- a/DDCore/include/DD4hep/Conditions.h
+++ b/DDCore/include/DD4hep/Conditions.h
@@ -61,7 +61,7 @@ namespace DD4hep {
      *
      *  Note:
      *  Conditions may be shared between several DetElement objects.
-     *  Hence, the back-link to the DetElemetn structure cannot be
+     *  Hence, the back-link to the DetElement structure cannot be
      *  set - it would be ambiguous.
      *
      *  \author  M.Frank
@@ -93,7 +93,12 @@ namespace DD4hep {
         ACTIVE           = 1<<0,
         CHECKED          = 1<<2,
         DERIVED          = 1<<3,
-        USER_FLAGS_FIRST = 1<<10,
+        TEMPERATURE      = 1<<4,
+        PRESSURE         = 1<<5,
+        ALIGNMENT        = 1<<6,
+        // Keep bit 7-15 for other generic types
+        // Bit 16-31 is reserved for user classifications
+        USER_FLAGS_FIRST = 1<<16,
         USER_FLAGS_LAST  = 1<<31
       };
 
@@ -115,9 +120,7 @@ namespace DD4hep {
       /// Initializing constructor
       Condition(Object* p);
       /// Constructor to be used when reading the already parsed object
-      template <typename Q> Condition(const Handle<Q>& e)
-        : Handle<Object>(e) {
-      }
+      template <typename Q> Condition(const Handle<Q>& e) : Handle<Object>(e) {}
       /// Initializing constructor for a pure, undecorated conditions object
       Condition(const std::string& name, const std::string& type);
       /// Assignment operator
@@ -170,6 +173,8 @@ namespace DD4hep {
       template <typename T> T& get();
       /// Generic getter (const version). Specify the exact type, not a polymorph type
       template <typename T> const T& get() const;
+      /// Check if object is already bound....
+      bool is_bound()  const  {  return isValid() ? data().is_bound() : false;  }
     };
 
     /// Initializing constructor
diff --git a/DDCore/include/DD4hep/DetAlign.h b/DDCore/include/DD4hep/DetAlign.h
index a07228023..3a3b6ccd7 100644
--- a/DDCore/include/DD4hep/DetAlign.h
+++ b/DDCore/include/DD4hep/DetAlign.h
@@ -46,6 +46,8 @@ namespace DD4hep {
       typedef Geometry::DetElementObject Object;
       /// Definition of the base handle type
       typedef Handle<Object> RefObject;
+      /// Pool definition
+      typedef Conditions::UserPool UserPool;
 
     public:
 
diff --git a/DDCore/include/DD4hep/MatrixHelpers.h b/DDCore/include/DD4hep/MatrixHelpers.h
index 66abdcfa0..d03d7a738 100644
--- a/DDCore/include/DD4hep/MatrixHelpers.h
+++ b/DDCore/include/DD4hep/MatrixHelpers.h
@@ -31,25 +31,36 @@ namespace DD4hep {
 
     typedef Position XYZAngles;
   
-    /// Access the TGeo identity transformation  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    /// Access the TGeo identity transformation                \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoIdentity*    identityTransform();
-    /// Convert a Position object to a TGeoTranslation  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    /// Convert a Position object to a TGeoTranslation         \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoTranslation* _translation(const Geometry::Position& pos);
-    /// Convert a RotationZYX object to a TGeoRotation  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    /// Convert a RotationZYX object to a TGeoRotation         \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoRotation*    _rotationZYX(const Geometry::RotationZYX& rot);
-    /// Convert a Rotation3D object to a TGeoRotation  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    /// Convert a Rotation3D object to a TGeoRotation          \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoRotation*    _rotation3D(const Geometry::Rotation3D& rot);
-    /// Convert a Transform3D object to a TGeoHMatrix  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    /// Convert a Transform3D object to a TGeoHMatrix          \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoHMatrix*     _transform(const Geometry::Transform3D& trans);
-    /// Convert a Position object to a TGeoHMatrix  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    /// Convert a Position object to a TGeoHMatrix             \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoHMatrix*     _transform(const Geometry::Position& pos);
-    /// Convert a RotationZYX object to a TGeoHMatrix  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    /// Convert a RotationZYX object to a TGeoHMatrix          \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoHMatrix*     _transform(const Geometry::RotationZYX& rot);
-    /// Convert a Rotation3D object to a TGeoHMatrix  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    /// Convert a Rotation3D object to a TGeoHMatrix           \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoHMatrix*     _transform(const Geometry::Rotation3D& rot3D);
     /// Convert a Position followed by a RotationZYX to a TGeoHMatrix  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     TGeoHMatrix*     _transform(const Geometry::Position& pos, const Geometry::RotationZYX& rot);
 
+    /// Set a Transform3D object to a TGeoHMatrix            \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    TGeoHMatrix&     _transform(TGeoHMatrix& mat, const Geometry::Transform3D& trans);
+    /// Set a Position object (translation) to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    TGeoHMatrix&     _transform(TGeoHMatrix& mat, const Geometry::Position& pos);
+    /// Set a RotationZYX object to a TGeoHMatrix            \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    TGeoHMatrix&     _transform(TGeoHMatrix& mat, const Geometry::RotationZYX& rot);
+    /// Set a Rotation3D object to a TGeoHMatrix             \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    TGeoHMatrix&     _transform(TGeoHMatrix& mat, const Geometry::Rotation3D& rot3D);
+    /// Set a Position followed by a RotationZYX to a TGeoHMatrix  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+    TGeoHMatrix&     _transform(TGeoHMatrix& mat, const Geometry::Position& pos, const Geometry::RotationZYX& rot);
+
     /// Convert a TGeoMatrix object to a generic Transform3D  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
     Geometry::Transform3D      _transform(const TGeoMatrix* matrix);
 
diff --git a/DDCore/include/DD4hep/objects/AlignmentsInterna.h b/DDCore/include/DD4hep/objects/AlignmentsInterna.h
index f13a7afcb..64ec5eb98 100644
--- a/DDCore/include/DD4hep/objects/AlignmentsInterna.h
+++ b/DDCore/include/DD4hep/objects/AlignmentsInterna.h
@@ -89,12 +89,11 @@ namespace DD4hep {
        *  \version 1.0
        *  \ingroup DD4HEP_ALIGNMENTS
        */
-      class AlignmentConditionObject
-        : public Conditions::Interna::ConditionObject, public AlignmentData
+      class AlignmentConditionObject : public Conditions::Interna::ConditionObject
       {
       public:
-        // Make the conditions object type local!
-        typedef Conditions::Interna::ConditionObject ConditionObject;
+        /// Cached pointer to the bound conditions data, since these may be accessed very frequently
+        AlignmentData* alignment_data;
         /// Standard constructor
         AlignmentConditionObject(const std::string& nam,const std::string& tit="");
         /// Standard Destructor
@@ -155,6 +154,21 @@ namespace DD4hep {
         void addKey(const std::string& key_value, const std::string& data_value);
       };
 
+      /**
+       *
+       *  \author  M.Frank
+       *  \version 1.0
+       *  \ingroup DD4HEP_CONDITIONS
+       */
+      class AlignmentNamedObject : public NamedObject, public AlignmentData  {
+      public:
+        /// Default constructor
+        AlignmentNamedObject(const std::string& nam, const std::string& tit="")
+          : NamedObject(nam,tit), AlignmentData()  {}
+        /// Default destructor
+        virtual ~AlignmentNamedObject();
+      };
+      
     } /* End namespace Interna    */
 
   } /* End namespace Alignments             */
diff --git a/DDCore/include/XML/UriReader.h b/DDCore/include/XML/UriReader.h
index 072c677f5..a54fb33d7 100644
--- a/DDCore/include/XML/UriReader.h
+++ b/DDCore/include/XML/UriReader.h
@@ -51,6 +51,10 @@ namespace DD4hep {
       virtual bool load(const std::string& system_id, std::string& data);
       /// Resolve a given URI to a string containing the data with context
       virtual bool load(const std::string& system_id, UserContext* context, std::string& data) = 0;
+      /// Inform reader about a locally (e.g. by XercesC) handled source load
+      virtual void parserLoaded(const std::string& system_id);
+      /// Inform reader about a locally (e.g. by XercesC) handled source load
+      virtual void parserLoaded(const std::string& system_id, UserContext* ctxt) = 0;
     };
 
     /// Class supporting to read data given a URI
@@ -83,6 +87,10 @@ namespace DD4hep {
       virtual bool load(const std::string& system_id, std::string& data);
       /// Resolve a given URI to a string containing the data with context
       virtual bool load(const std::string& system_id, UserContext* context, std::string& data);
+      /// Inform reader about a locally (e.g. by XercesC) handled source load
+      virtual void parserLoaded(const std::string& system_id);
+      /// Inform reader about a locally (e.g. by XercesC) handled source load
+      virtual void parserLoaded(const std::string& system_id, UserContext* ctxt);
     };
 
   }       /* End namespace XML               */
diff --git a/DDCore/src/AlignmentData.cpp b/DDCore/src/AlignmentData.cpp
index 36ed3d958..dc7c1b28d 100644
--- a/DDCore/src/AlignmentData.cpp
+++ b/DDCore/src/AlignmentData.cpp
@@ -25,13 +25,9 @@ using namespace std;
 using namespace DD4hep;
 using namespace DD4hep::Alignments;
 
-/// Default constructor
-Delta::Delta()   {
-}
-
 /// Copy constructor
 Delta::Delta(const Delta& c)
-  : pivot(c.pivot), translation(c.translation), rotation(c.rotation)  
+  : pivot(c.pivot), translation(c.translation), rotation(c.rotation), flags(c.flags)
 {
 }
 
@@ -45,12 +41,14 @@ Delta& Delta::operator=(const Delta& c)   {
     pivot       = c.pivot;
     translation = c.translation;
     rotation    = c.rotation;
+    flags       = c.flags;
   }
   return *this;
 }
 
 /// Reset information to identity
 void Delta::clear()   {
+  flags       = 0;
   pivot       = Pivot();
   translation = Position();
   rotation    = RotationZYX();
@@ -202,14 +200,6 @@ Alignment AlignmentData::nominal() const   {
   return detector.nominal();
 }
 
-/// Default destructor
-NamedAlignmentObject::~NamedAlignmentObject()   {
-}
-
-#include "DD4hep/Handle.inl"
-DD4HEP_INSTANTIATE_HANDLE_NAMED(NamedAlignmentObject);
-DD4HEP_INSTANTIATE_HANDLE_UNNAMED(AlignmentData);
-
 #include "DD4hep/ToStream.h"
 #include "DD4hep/objects/ConditionsInterna.h"
 DD4HEP_DEFINE_CONDITIONS_TYPE_DUMMY(Delta)
diff --git a/DDCore/src/AlignmentTools.cpp b/DDCore/src/AlignmentTools.cpp
index 548bbc037..f11bafc09 100644
--- a/DDCore/src/AlignmentTools.cpp
+++ b/DDCore/src/AlignmentTools.cpp
@@ -30,6 +30,23 @@ using     DD4hep::Alignments::AlignmentData;
 namespace DetectorTools = DD4hep::Geometry::DetectorTools;
 typedef   AlignmentData::MaskManipulator MaskManipulator;
 
+/// Copy alignment object from source object
+void DD4hep::Alignments::AlignmentTools::copy(Alignment from, Alignment to)   {
+  Alignment::Object* f = from.ptr();
+  Alignment::Object* t = to.ptr();
+  if ( t != f )   {
+    t->flag          = f->flag;
+    t->detectorTrafo = f->detectorTrafo;
+    t->worldTrafo    = f->worldTrafo;
+    t->trToWorld     = f->trToWorld;
+    t->detector      = f->detector;
+    t->placement     = f->placement;
+    t->nodes         = f->nodes;
+    t->delta         = f->delta;
+    t->magic         = f->magic;
+  }
+}
+
 /// Compute the ideal/nominal to-world transformation from the detector element placement
 void DD4hep::Alignments::AlignmentTools::computeIdeal(Alignment alignment)   {
   Alignment::Object* a = alignment.ptr();
@@ -41,11 +58,15 @@ void DD4hep::Alignments::AlignmentTools::computeIdeal(Alignment alignment)   {
     for (size_t i = 0, n=path.size(); n>0 && i < n-1; ++i)  {
       const PlacedVolume& p = path[i];
       a->detectorTrafo.MultiplyLeft(p->GetMatrix());
+      a->nodes.push_back(p);
     }
     a->worldTrafo = parent.nominal()->worldTrafo;
     a->worldTrafo.MultiplyLeft(&a->detectorTrafo);
     a->trToWorld  = Geometry::_transform(&a->worldTrafo);
     a->placement  = a->detector.placement();
+    mask.clear();
+    mask.set(AlignmentData::HAVE_PARENT_TRAFO);
+    mask.set(AlignmentData::HAVE_WORLD_TRAFO);
     mask.set(AlignmentData::IDEAL);
   }
 }
diff --git a/DDCore/src/Alignments.cpp b/DDCore/src/Alignments.cpp
index 69288f595..0755d9ba6 100644
--- a/DDCore/src/Alignments.cpp
+++ b/DDCore/src/Alignments.cpp
@@ -15,6 +15,7 @@
 // Framework include files
 #include "DD4hep/AlignmentData.h"
 #include "DD4hep/objects/AlignmentsInterna.h"
+#include "DD4hep/objects/ConditionsInterna.h"
 
 // C/C++ include files
 #include <sstream>
@@ -22,13 +23,84 @@
 using namespace std;
 using namespace DD4hep::Alignments;
 
-/// Default constructor
-Alignment::Alignment() : Handle<Object>() {
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the alignment part of the AIDA detector description toolkit
+  namespace Alignments {
+
+    /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject)
+    template <> Alignment::Alignment<Alignment::Object>(const string& nam) {
+      assign(new Alignment::Object(), nam, "alignment");
+    }
+
+    /// Initializing constructor to create a new object (Specialized for AlignmentNamedObject)
+    template <> Alignment::Alignment<Interna::AlignmentNamedObject>(const string& nam) {
+      assign(new Interna::AlignmentNamedObject(nam, "alignment"), nam, "alignment");
+    }
+
+    /// Initializing constructor to create a new object (Specialized for AlignmentConditionObject)
+    template <> AlignmentCondition::AlignmentCondition<AlignmentCondition::Object>(const string& nam) {
+      assign(new Object(nam, "alignment"), nam, "alignment");
+    }
+  } /* End namespace Aligments                  */
+} /* End namespace DD4hep                       */
+
+
+/// Create cached matrix to transform to world coordinates
+const TGeoHMatrix& Alignment::worldTransformation()  const  {
+  return data().worldTransformation();
+}
+
+/// Access the alignment/placement matrix with respect to the world
+const TGeoHMatrix& Alignment::detectorTransformation() const   {
+  return data().detectorTransformation();
+}
+
+/// Access the IOV type
+const DD4hep::IOVType& AlignmentCondition::iovType() const   {
+  return *(access()->iovType());
+}
+
+/// Access the IOV block
+const DD4hep::IOV& AlignmentCondition::iov() const   {
+  return *(access()->iovData());
+}
+
+/// Data accessor for the use of decorators
+AlignmentCondition::Data& AlignmentCondition::data()              {
+  Object* o = access();
+  if ( o->alignment_data )
+    return *(o->alignment_data);
+  Conditions::Condition c(*this);
+  o->alignment_data = c.is_bound() ? &c.get<Data>() : &c.bind<Data>();
+  return *(o->alignment_data);
+}
+
+/// Data accessor for the use of decorators
+const AlignmentCondition::Data& AlignmentCondition::data() const  {
+  Object* o = access();
+  if ( o->alignment_data )
+    return *(o->alignment_data);
+  Conditions::Condition c(*this);
+  o->alignment_data = c.is_bound() ? &c.get<Data>() : &c.bind<Data>();
+  return *(o->alignment_data);
+}
+
+/// Check if object is already bound....
+bool AlignmentCondition::is_bound()  const  {
+  return isValid() ? ptr()->data.is_bound() : false;
+}
+
+/// Create cached matrix to transform to world coordinates
+const TGeoHMatrix& AlignmentCondition::worldTransformation()  const  {
+  return data().worldTransformation();
 }
 
-/// Initializing constructor to create a new object
-Alignment::Alignment(const string& nam) {
-  m_element = new NamedAlignmentObject(nam, "alignment");
+/// Access the alignment/placement matrix with respect to the world
+const TGeoHMatrix& AlignmentCondition::detectorTransformation() const   {
+  return data().detectorTransformation();
 }
 
 /// Access the number of conditons keys available for this detector element
diff --git a/DDCore/src/AlignmentsInterna.cpp b/DDCore/src/AlignmentsInterna.cpp
index 8683623f3..70366e0a3 100644
--- a/DDCore/src/AlignmentsInterna.cpp
+++ b/DDCore/src/AlignmentsInterna.cpp
@@ -27,13 +27,16 @@ using namespace DD4hep::Alignments;
 using namespace DD4hep::Alignments::Interna;
 
 DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentConditionObject);
+DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentNamedObject);
 DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentContainer);
+DD4HEP_INSTANTIATE_HANDLE_UNNAMED(AlignmentData);
 
 /// Standard constructor
 AlignmentConditionObject::AlignmentConditionObject(const string& nam, const string& tit)
-  : ConditionObject(nam, tit), AlignmentData()
+  : ConditionObject(nam, tit), alignment_data(0)
 {
   InstanceCount::increment(this);
+  flags = Conditions::Condition::ALIGNMENT;
 }
 
 /// Standard Destructor
@@ -43,11 +46,13 @@ AlignmentConditionObject::~AlignmentConditionObject()  {
 
 /// Clear data content on demand.
 void AlignmentConditionObject::clear()   {
-  trToWorld = Transform3D();
-  detectorTrafo.Clear();
-  worldTrafo.Clear();
-  nodes.clear();
-  flags = 0;
+  AlignmentCondition a(this);
+  Alignment::Data& d = a.data();
+  d.trToWorld = Transform3D();
+  d.detectorTrafo.Clear();
+  d.worldTrafo.Clear();
+  d.nodes.clear();
+  flags = Conditions::Condition::ALIGNMENT;
 }
 
 /// Standard constructor
@@ -134,3 +139,8 @@ Alignment AlignmentContainer::get(key_type hash_key, const UserPool& pool)   {
 /// Protected destructor
 AlignmentsLoader::~AlignmentsLoader()   {
 }
+
+/// Default destructor
+AlignmentNamedObject::~AlignmentNamedObject()   {
+}
+
diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp
index ec90438cd..49eb1ee15 100644
--- a/DDCore/src/Detector.cpp
+++ b/DDCore/src/Detector.cpp
@@ -188,7 +188,10 @@ Alignment DetElement::nominal() const   {
 /// Access to the survey alignment information
 Alignment DetElement::survey() const  {
   Object* o = access();
-  if ( !o->survey.isValid() ) return nominal();
+  if ( !o->survey.isValid() )   {
+    o->survey = Alignment("survey");
+    DD4hep::Alignments::AlignmentTools::copy(nominal(), o->survey);
+  }
   return o->survey;
 }
 
diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp
index a0ce8492b..83fad3846 100644
--- a/DDCore/src/DetectorInterna.cpp
+++ b/DDCore/src/DetectorInterna.cpp
@@ -89,6 +89,8 @@ DetElementObject::~DetElementObject() {
   deletePtr (referenceTrafo);
   destroyHandle (conditions);
   conditions = ConditionsContainer();
+  destroyHandle (nominal);
+  destroyHandle (survey);
   destroyHandle (alignments);
   alignments = AlignmentsContainer();
   placement.clear();
diff --git a/DDCore/src/IOV.cpp b/DDCore/src/IOV.cpp
index d2b4504e9..ae14a00e0 100644
--- a/DDCore/src/IOV.cpp
+++ b/DDCore/src/IOV.cpp
@@ -142,7 +142,7 @@ string IOV::str()  const  {
       struct tm time_buff;
       ::strftime(c_since,sizeof(c_since),"%d-%m-%Y %H:%M:%S",::gmtime_r(&since,&time_buff));
       ::strftime(c_until,sizeof(c_until),"%d-%m-%Y %H:%M:%S",::gmtime_r(&until,&time_buff));
-      ::snprintf(text,sizeof(text),"%s(%d):[%s-%s]",
+      ::snprintf(text,sizeof(text),"%s(%d):[%s - %s]",
 		 iovType->name.c_str(),iovType->type,
 		 c_since, c_until);
     }
diff --git a/DDCore/src/MatrixHelpers.cpp b/DDCore/src/MatrixHelpers.cpp
index 64bf2d70d..bd3d18ffa 100644
--- a/DDCore/src/MatrixHelpers.cpp
+++ b/DDCore/src/MatrixHelpers.cpp
@@ -37,48 +37,70 @@ TGeoRotation* DD4hep::Geometry::_rotation3D(const Rotation3D& rot3D) {
   return new TGeoRotation("", rot.Phi() * RAD_2_DEGREE, rot.Theta() * RAD_2_DEGREE, rot.Psi() * RAD_2_DEGREE);
 }
 
-TGeoHMatrix* DD4hep::Geometry::_transform(const Position& pos)   {
-  double t[3];
-  TGeoHMatrix *tr = new TGeoHMatrix();
-  pos.GetCoordinates(t);
-  tr->SetDx(t[0]);
-  tr->SetDy(t[1]);
-  tr->SetDz(t[2]);
+/// Set a RotationZYX object to a TGeoHMatrix            \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const RotationZYX& rot)   {
+  tr.RotateZ(rot.Phi()   * RAD_2_DEGREE);
+  tr.RotateY(rot.Theta() * RAD_2_DEGREE);
+  tr.RotateX(rot.Psi()   * RAD_2_DEGREE);
   return tr;
 }
 
-TGeoHMatrix* DD4hep::Geometry::_transform(const RotationZYX& rot)   {
-  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);
+/// Set a Position object (translation) to a TGeoHMatrix \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const Position& pos)   {
+  double t[3];
+  pos.GetCoordinates(t);
+  tr.SetDx(t[0]);
+  tr.SetDy(t[1]);
+  tr.SetDz(t[2]);
   return tr;
 }
 
-TGeoHMatrix* DD4hep::Geometry::_transform(const Rotation3D& rot)   {
-  TGeoHMatrix *tr = new TGeoHMatrix();
-  Double_t* r = tr->GetRotationMatrix();
+/// Set a Rotation3D object to a TGeoHMatrix           \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const Rotation3D& rot)   {
+  Double_t* r = tr.GetRotationMatrix();
   rot.GetComponents(r);
   return tr;
 }
 
-TGeoHMatrix* DD4hep::Geometry::_transform(const Transform3D& trans) {
+/// Set a Transform3D object to a TGeoHMatrix            \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const Transform3D& trans) {
   Position pos;
   RotationZYX rot;
   trans.GetDecomposition(rot, pos);
-  return _transform(pos,rot);
+  return _transform(tr, pos, rot);
+}
+
+/// Set a Position followed by a RotationZYX to a TGeoHMatrix  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix& DD4hep::Geometry::_transform(TGeoHMatrix& tr, const Position& pos, const RotationZYX& rot) {
+  return _transform(_transform(tr, rot), pos);
+}
+
+/// Convert a Position object to a TGeoTranslation         \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix* DD4hep::Geometry::_transform(const Position& pos)   {
+  return &_transform(*(new TGeoHMatrix()), pos);
 }
 
+/// Convert a RotationZYX object to a TGeoHMatrix          \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix* DD4hep::Geometry::_transform(const RotationZYX& rot)   {
+  return &_transform(*(new TGeoHMatrix()), rot);
+}
+
+/// Convert a Rotation3D object to a TGeoHMatrix           \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix* DD4hep::Geometry::_transform(const Rotation3D& rot)   {
+  return &_transform(*(new TGeoHMatrix()), rot);
+}
+
+/// Convert a Transform3D object to a TGeoHMatrix          \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
+TGeoHMatrix* DD4hep::Geometry::_transform(const Transform3D& trans) {
+  return &_transform(*(new TGeoHMatrix()), trans);
+}
+
+/// Convert a Position followed by a RotationZYX to a TGeoHMatrix  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
 TGeoHMatrix* DD4hep::Geometry::_transform(const Position& pos, const RotationZYX& rot) {
-  double t[3];
-  TGeoHMatrix *tr = _transform(rot);
-  pos.GetCoordinates(t);
-  tr->SetDx(t[0]);
-  tr->SetDy(t[1]);
-  tr->SetDz(t[2]);
-  return tr;
+  return &_transform(*(new TGeoHMatrix()), pos, rot);
 }
 
+/// Convert a TGeoMatrix object to a generic Transform3D  \ingroup DD4HEP \ingroup DD4HEP_GEOMETRY
 Transform3D DD4hep::Geometry::_transform(const TGeoMatrix* matrix)    {
   const Double_t* t = matrix->GetTranslation();
   if ( matrix->IsRotation() )  {
@@ -86,11 +108,6 @@ Transform3D DD4hep::Geometry::_transform(const TGeoMatrix* matrix)    {
     return Transform3D(r[0],r[1],r[2],t[0]*MM_2_CM,
                        r[3],r[4],r[5],t[1]*MM_2_CM,
                        r[6],r[7],r[8],t[2]*MM_2_CM);
-#if 0
-    return Transform3D(r[0],r[3],r[6],t[0]*MM_2_CM,
-                       r[1],r[4],r[7],t[1]*MM_2_CM,
-                       r[2],r[5],r[8],t[2]*MM_2_CM);
-#endif
   }
   return Transform3D(0e0,0e0,0e0,t[0]*MM_2_CM,
                      0e0,0e0,0e0,t[1]*MM_2_CM,
diff --git a/DDCore/src/XML/DocumentHandler.cpp b/DDCore/src/XML/DocumentHandler.cpp
index d959d9d8b..901b7d308 100644
--- a/DDCore/src/XML/DocumentHandler.cpp
+++ b/DDCore/src/XML/DocumentHandler.cpp
@@ -309,9 +309,10 @@ Document DocumentHandler::load(const string& fname, UriReader* reader) const   {
   try {
     if ( !path.empty() )  {
       parser->parse(path.c_str());
+      if ( reader ) reader->parserLoaded(path);
     }
     else   {
-      if ( reader->load(fname, path) )  {
+      if ( reader && reader->load(fname, path) )  {
         MemBufInputSource src((const XMLByte*)path.c_str(), path.length(), fname.c_str(), false);
         parser->parse(src);
         return (XmlDocument*)parser->adoptDocument();
@@ -323,6 +324,7 @@ Document DocumentHandler::load(const string& fname, UriReader* reader) const   {
     printout(ERROR,"DocumentHandler","+++ Exception(XercesC): parse(path):%s",e.what());
     try {
       parser->parse(fname.c_str());
+      if ( reader ) reader->parserLoaded(path);
     }
     catch (const exception& ex) {
       printout(FATAL,"DocumentHandler","+++ Exception(XercesC): parse(URI):%s",ex.what());
diff --git a/DDCore/src/XML/UriReader.cpp b/DDCore/src/XML/UriReader.cpp
index e78a8ba4d..5454211cd 100644
--- a/DDCore/src/XML/UriReader.cpp
+++ b/DDCore/src/XML/UriReader.cpp
@@ -24,6 +24,11 @@ bool DD4hep::XML::UriReader::load(const std::string& system_id, std::string& dat
   return this->load(system_id, context(), data);
 }
 
+/// Inform reader about a locally (e.g. by XercesC) handled source load
+void DD4hep::XML::UriReader::parserLoaded(const std::string& system_id)  {
+  this->parserLoaded(system_id, context());
+}
+
 /// Default constructor
 DD4hep::XML::UriContextReader::UriContextReader(UriReader* reader, UriReader::UserContext* ctxt)
   : m_reader(reader), m_context(ctxt)
@@ -49,3 +54,13 @@ bool DD4hep::XML::UriContextReader::load(const std::string& system_id, std::stri
 bool DD4hep::XML::UriContextReader::load(const std::string& system_id, UserContext* ctxt, std::string& data)   {
   return m_reader->load(system_id, ctxt, data);
 }
+
+/// Inform reader about a locally (e.g. by XercesC) handled source load
+void DD4hep::XML::UriContextReader::parserLoaded(const std::string& system_id)  {
+  m_reader->parserLoaded(system_id, context());
+}
+
+/// Inform reader about a locally (e.g. by XercesC) handled source load
+void DD4hep::XML::UriContextReader::parserLoaded(const std::string& system_id, UserContext* ctxt)  {
+  m_reader->parserLoaded(system_id, ctxt);
+}
diff --git a/DDDB/CMakeLists.txt b/DDDB/CMakeLists.txt
index bb3905e50..d1632c81d 100644
--- a/DDDB/CMakeLists.txt
+++ b/DDDB/CMakeLists.txt
@@ -18,9 +18,10 @@
 #=================================================================================
 
 dd4hep_package(    DDDB
-  USES             DDCore DDCond
+  USES             DDCore DDAlign DDCond
   INCLUDE_DIRS     include
   INSTALL_INCLUDES include/DDDB)
 
 #---DDDB plugin library -------------------------------------------------------
-dd4hep_add_plugin ( DDDB SOURCES src/*.cpp )
+dd4hep_add_plugin ( DDDB SOURCES src/*.cpp
+  USES  DDCore DDAlign DDCond )
diff --git a/DDDB/include/DDDB/DDDBConversion.h b/DDDB/include/DDDB/DDDBConversion.h
index 6a4298440..ac98f68e7 100644
--- a/DDDB/include/DDDB/DDDBConversion.h
+++ b/DDDB/include/DDDB/DDDBConversion.h
@@ -47,6 +47,7 @@ namespace DD4hep {
     using Geometry::Rotation3D;
     using Geometry::RotationZYX;
     using Geometry::Transform3D;
+    using Geometry::Translation3D;
     using Geometry::Position;
     using Geometry::LCDD;
 
diff --git a/DDDB/include/DDDB/DDDBReader.h b/DDDB/include/DDDB/DDDBReader.h
index c6e7d7815..0acac4be9 100644
--- a/DDDB/include/DDDB/DDDBReader.h
+++ b/DDDB/include/DDDB/DDDBReader.h
@@ -61,6 +61,10 @@ namespace DD4hep {
       virtual bool load(const std::string& system_id, std::string& buffer);
       /// Resolve a given URI to a string containing the data
       virtual bool load(const std::string& system_id, UserContext* ctxt, std::string& buffer);
+      /// Inform reader about a locally (e.g. by XercesC) handled source load
+      virtual void parserLoaded(const std::string& system_id);
+      /// Inform reader about a locally (e.g. by XercesC) handled source load
+      virtual void parserLoaded(const std::string& system_id, UserContext* ctxt);
       /// Read raw XML object from the database / file
       virtual int getObject(const std::string& system_id, UserContext* ctxt, std::string& data);
 
diff --git a/DDDB/src/CondDB2DDDB.cpp b/DDDB/src/CondDB2DDDB.cpp
index e36196faf..a5f1fa788 100644
--- a/DDDB/src/CondDB2DDDB.cpp
+++ b/DDDB/src/CondDB2DDDB.cpp
@@ -735,14 +735,21 @@ namespace DD4hep {
       Position pos;
       const BasicGrammar& g = BasicGrammar::instance<Position>();
       if ( !g.fromString(&pos,d) ) g.invalidConversion(d, g.type());
-      if ( nam == "dPosXYZ" )
+      if ( nam == "dPosXYZ" )  {
         a->translation = pos;
-      else if ( nam == "dRotXYZ" )
+        a->flags |= AlignmentDelta::HAVE_TRANSLATION;
+      }
+      else if ( nam == "dRotXYZ" )   {
         a->rotation = RotationZYX(pos.z(),pos.y(),pos.x());
-      else if ( nam == "pivotXYZ" )
-        a->pivot = pos;
-      else
-        printout(ERROR,"AlignmentDelta","++ Unknown alignment conditions tag: %s",nam.c_str());	
+        a->flags |= AlignmentDelta::HAVE_ROTATION;
+      }
+      else if ( nam == "pivotXYZ" )   {
+        a->pivot = Translation3D(pos.x(),pos.y(),pos.z());
+        a->flags |= AlignmentDelta::HAVE_PIVOT;
+      }
+      else   {
+        printout(ERROR,"AlignmentDelta","++ Unknown alignment conditions tag: %s",nam.c_str());
+      }
     }
 
     /// Specialized conversion of <condition/> entities
@@ -1684,6 +1691,7 @@ namespace DD4hep {
       xml_coll_t(e, _LBU(detelemref)).for_each(Conv<DetElemRef>(lcdd,context,catalog));
 
       xml_coll_t(e, _LBU(detelem)).for_each(Conv<DetElem>(lcdd,context,catalog));
+      // First handle the catalog. It may refer to local conditions!
       xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog));
       xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog));
     }
@@ -1697,8 +1705,9 @@ namespace DD4hep {
       xml_coll_t(e, _LBU(catalogref)).for_each(Conv<CatalogRef>(lcdd,context,catalog));
       {
         Context::PreservedLocals locals(context);
-        xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog));
+        // First handle the catalog. It may refer to local conditions!
         xml_coll_t(e, _LBU(catalog)).for_each(Conv<Catalog>(lcdd,context,catalog));
+        xml_coll_t(e, _LBU(condition)).for_each(Conv<Condition>(lcdd,context,catalog));
       }
     }
 
diff --git a/DDDB/src/DDDBAlignmentTest.cpp b/DDDB/src/DDDBAlignmentTest.cpp
index 5be4047c5..0802eda14 100644
--- a/DDDB/src/DDDBAlignmentTest.cpp
+++ b/DDDB/src/DDDBAlignmentTest.cpp
@@ -24,15 +24,10 @@
 #include "DD4hep/Printout.h"
 #include "DD4hep/Factories.h"
 #include "DD4hep/ConditionsData.h"
-#include "DD4hep/ConditionDerived.h"
-#include "DD4hep/Alignments.h"
-
-#include "DDCond/ConditionsAccess.h"
+#include "DD4hep/InstanceCount.h"
+#include "DDAlign/AlignmentsManager.h"
 #include "DDCond/ConditionsManager.h"
-#include "DDCond/ConditionsIOVPool.h"
 #include "DDCond/ConditionsPool.h"
-#include "DDCond/ConditionsInterna.h"
-#include "DDCond/ConditionsOperators.h"
 
 #include "DDDB/DDDBReader.h"
 #include "DDDB/DDDBConversion.h"
@@ -45,60 +40,16 @@ using namespace DD4hep::Conditions;
 using DDDB::Document;
 using Geometry::LCDD;
 using Geometry::DetElement;
+using Geometry::Position;
+using Geometry::RotationZYX;
+using Geometry::Transform3D;
+using Geometry::Translation3D;
 
 /// Anonymous namespace for plugins
 namespace  {
 
-  class AlignmentTypes  {
-  public:
-    typedef AbstractMap                      Map;
-    typedef Map::Params                      Params;
-    typedef Params::value_type::second_type  Param;
-    typedef Alignments::AlignmentData        Data;
-    typedef Alignments::Delta                Delta;
-    typedef DDDB::ConditionPrinter           _Printer;
-  };
+  using Alignments::AlignmentsManager;
 
-  struct UserData;
-  struct Entry {
-    UserData*            data;
-    DetElement::Object*  det;
-    DetElement::Object*  par;
-    ConditionDependency* dep;
-    int det_key, par_key, top;
-  };
-  struct UserData {
-    struct det_lexical_ordering {
-      bool operator()(const DetElement& a, const DetElement& b) const { return a.path() == b.path(); }
-    };
-    typedef std::map<DetElement,size_t,det_lexical_ordering>       DetectorMap;
-    typedef std::map<unsigned int,size_t>      DetectorKeys;
-    typedef std::vector<Entry>                 Entries;
-    DetectorMap  detectors;
-    DetectorKeys keys;
-    Entries      entries;
-  };
-  struct _Oper : public ConditionsDependencyCollection::Functor {
-    void operator()(UserData& data, const Dependencies::value_type& e) const  {
-      const Dependency* dep = e.second.get();
-      DetElement det = dep->detector;
-      if ( det.isValid() )  {
-        Entry entry;
-        unsigned int key = det.key();
-        entry.data = &data;
-        entry.top  = 0;
-        entry.dep  = e.second.get();
-        entry.det  = det.ptr();
-        entry.par  = det.parent().ptr();
-        entry.det_key = key;
-        entry.par_key = det.parent().key();
-        data.detectors.insert(make_pair(det,data.entries.size()));
-        data.keys.insert(make_pair(key,data.entries.size()));
-        data.entries.insert(data.entries.end(),entry);
-      }
-    }
-  };
-  
   /// Specialized conditions update callback for alignments
   /**
    *  Used by clients to update a condition.
@@ -107,55 +58,42 @@ namespace  {
    *  \version 1.0
    *  \ingroup DD4HEP_CONDITIONS
    */
-  class AlignmentUpdate : public ConditionUpdateCall, public AlignmentTypes  {
+  class AlignmentUpdate : public ConditionUpdateCall  {
+    typedef AbstractMap::Params::value_type::second_type Param;
+    typedef Alignments::AlignmentData Data;
   public:
-    AlignmentUpdate()   {    }
+    AlignmentUpdate()  {    }
     virtual ~AlignmentUpdate() {    }
     /// Interface to client Callback in order to update the condition
     virtual Condition operator()(const ConditionKey& key, const Context& context)  {
-      Condition    target(key.name,"Alignment");
-      Data&        data  = target.bind<Data>();
-      Condition    cond0 = context.condition(0);
-      const Map&   src0  = cond0.get<Map>();
-      const Param& par0  = src0.firstParam().second;
-      DetElement   det0  = context.dependency.detector;
-      printout(INFO,"AlignmentUpdate","++ Building dependent condition: %s Detector [%d]: %s ",
-               key.name.c_str(), det0.level(), det0.path().c_str());
-      if ( par0.typeInfo() == typeid(Delta) )  {
-        const Delta& delta = src0.first<Delta>();
-        data.delta         = delta;
-        data.flag          = Data::HAVE_NONE;
+      Alignments::AlignmentCondition target(key.name);
+      Data&        data = target.data();
+      Condition    cond = context.condition(0);
+      AbstractMap& src  = cond.get<AbstractMap>();
+      const Param& par  = src.firstParam().second;
+      DetElement   det  = context.dependency.detector;
+      printout(DEBUG,"AlignmentUpdate","++ Building dependent condition: %s Detector [%d]: %s ",
+               key.name.c_str(), det.level(), det.path().c_str());
+      if ( par.typeInfo() == typeid(Data::Delta) )  {
+        const Data::Delta& delta = src.first<Data::Delta>();
+        data.delta = delta;
+        data.flag  = Data::HAVE_NONE;
       }
       else  {
         printout(INFO,"AlignmentUpdate","++ Failed to access alignment-Delta from %s",
-                 cond0->value.c_str());
-        _Printer()(cond0);
+                 cond->value.c_str());
+        DDDB::ConditionPrinter()(cond);
       }
-      data.detector = context.dependency.detector;
-      //data.condition   = target;
+      data.detector = det;
+      AlignmentsManager::newEntry(context, det, &context.dependency, target);
+      // A callback returning no condition is illegal!
+      // Need to crosscheck though if the alignment IOV interval of parents may be
+      // smaller then the daughter IOV interval.
+      // I though expect, that this is a purely academic case.
       return target;
     }
   };
 
-  void __print(DetElement det,
-               UserData& data,
-               int level)
-  {
-    char fmt[128];
-    auto i=data.keys.find(det.key());
-    const char* has_alignment = i==data.keys.end() ? "NO " : "YES";
-    size_t siz =  i==data.keys.end() ? 0 : 1;
-    ::snprintf(fmt,sizeof(fmt),"%%d %%%ds %%p [%%d] %%s %%08X: %%s ",2*level);
-    printout(INFO,"Conditions",fmt,
-             det.level(), "", det.ptr(), siz, has_alignment,
-             det.key(), det.path().c_str());
-    const DetElement::Children& children = det.children();
-    for(auto c=children.begin(); c!=children.end(); ++c)    {
-      DetElement child = (*c).second;
-      __print(child, data, level+1);
-    }
-  }
-  
   /// DDDB Conditions analyser to select alignments.
   /**
    *   \author  M.Frank
@@ -166,153 +104,102 @@ namespace  {
   class AlignmentSelector  {
   public:
     typedef ConditionsManager::Dependencies Dependencies;
+    LCDD&             lcdd;
+    AlignmentUpdate*  updateCall;
+    long int          time;
     string            m_name;
-    RangeConditions   m_allConditions;
-    Dependencies      m_allDependencies;
-    ConditionsManager m_manager;
-    struct Counters {
-      size_t numAlignments;
-      size_t numNoCatalogs;
-      void reset() { numAlignments=numNoCatalogs=0; }
-    } m_counters;
 
     /// Initializing constructor
-    AlignmentSelector(ConditionsAccess mgr) : m_manager(mgr)    {
-      Operators::collectAllConditions(mgr, m_allConditions);
+    AlignmentSelector(LCDD& l, long t) : lcdd(l), time(t), m_name("Selector")   {
+      // The alignment update call can be re-used over and over. It has not state.
+      updateCall = new AlignmentUpdate();
     }
-
+    /// Default destructor
     virtual ~AlignmentSelector()   {
-      m_allDependencies.clear();
-    }
-
-    void addDependency(ConditionDependency* dependency)   {
-      m_allDependencies.insert(dependency->target.hash, dependency);
-    }
-
-    RangeConditions findCond(const string& match)   {
-      RangeConditions result;
-      if ( !match.empty() )  {
-        for(RangeConditions::iterator ic=m_allConditions.begin(); ic!=m_allConditions.end(); ++ic)  {
-          Condition cond = (*ic);
-          size_t idx = cond->value.find(match);
-          if ( idx == 0 )  {
-            if (cond->value.length() == match.length() )   {
-              result.push_back(cond);
-            }
-            else if ( cond->value[match.length()] == '/' )  {
-              size_t idq = cond->value.find('/',match.length()+1);
-              if ( idq == string::npos )  {
-                result.push_back(cond);
-              }
-            }
-          }
-        }
-      }
-      return result;
+      releasePtr(updateCall);
     }
-
-    AlignmentUpdate* m_update;
-    long collectDependencies(DetElement de, AlignmentUpdate* update, int level)  {
-      char fmt[64], text[256];
-      DDDB::Catalog* cat = 0;
-      DDDB::ConditionPrinter prt;
-      const DetElement::Children& c = de.children();
-
-      ::snprintf(fmt,sizeof(fmt),"%%-%ds-> ",2*level+5);
-      ::snprintf(text,sizeof(text),fmt,"");
-      prt.setPrefix(text);
-
+    /// Recursive alignment collector
+    long collect(DetElement de, dd4hep_ptr<UserPool>& user_pool, AlignmentsManager& am, int level)  {
+      char fmt[64];
       try  {
-        ::sprintf(fmt,"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p",level+1,2*level+1);
-        printout(INFO,m_name,fmt,"",de.path().c_str(),int(c.size()),(void*)de.volumeID());
-        cat = de.extension<DDDB::Catalog>();
-        ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3);
+        DDDB::Catalog* cat = de.extension<DDDB::Catalog>();
         if ( !cat->condition.empty() )  {
-          RangeConditions rc = findCond(cat->condition);
-          printout(INFO,m_name,fmt,"","Alignment:    ", 
-                   rc.empty() ? (cat->condition+"  !!!UNRESOLVED!!!").c_str() : cat->condition.c_str());
-          if ( !rc.empty() )   {
-            ConditionKey target1(cat->condition+"/derived_1");
-            DependencyBuilder build_1(target1, update->addRef());
-            build_1->detector = de;
-            for(RangeConditions::const_iterator ic=rc.begin(); ic!=rc.end(); ++ic)   {
-              Condition    cond = *ic;
-              ConditionKey key(cond->value);
-              build_1.add(key);
-            }
-            addDependency(build_1.release());
+          ConditionKey key(cat->condition);
+          Condition cond = user_pool->get(key.hash);
+          if ( cond.isValid() )   {
+            DependencyBuilder b(ConditionKey(cat->condition+"/Tranformations"), updateCall->addRef());
+            b->detector = de;
+            b.add(ConditionKey(cond->value));
+            am.adoptDependency(b.release());
+          }
+          else  {
+            ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3);
+            printout(INFO,m_name,fmt,"","Alignment:    ", 
+                     !cond.isValid() ? (cat->condition+"  !!!UNRESOLVED!!!").c_str() : cat->condition.c_str());
           }
-          ++m_counters.numAlignments;
         }
       }
       catch(...)  {
         ::sprintf(fmt,"%03d %%-%ds %%s%%-20s -> %%s",level+1,2*level+3);
         printout(INFO,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", "");
-        ++m_counters.numNoCatalogs;
       }
+      const DetElement::Children& c = de.children();
       for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i)
-        collectDependencies((*i).second, update, level+1);
+        collect((*i).second, user_pool, am, level+1);
       return 1;
     }
-
-    int computeDependencies(long time)  {
-      dd4hep_ptr<UserPool> user_pool;
-      const Dependencies& dependencies = m_allDependencies;
-      const IOVType* iovType = m_manager.iovType("epoch");
+    /// Initial collector call
+    long collect(ConditionsManager manager, AlignmentsManager& context)  {
+      const IOVType* iovType = manager.iovType("epoch");
       IOV  iov(iovType, IOV::Key(time,time));
-      long num_expired = m_manager.prepare(iov, user_pool, dependencies);
-      printout(INFO,"Conditions",
-               "+++ ConditionsUpdate: Updated %ld conditions... IOV:%s",
-               num_expired, iov.str().c_str());
-      
-      UserData data;
-      data.entries.reserve(dependencies.size());
-      dependencies.for_each(DependencyCollector<UserData,_Oper>(data,_Oper()));
-
-      string prev("-----");
-      for(auto i=data.detectors.begin(); i!=data.detectors.end(); ++i)  {
-        Entry& e = data.entries[(*i).second];
-        DetElement    det = e.det;
-        unsigned int  key = det.key();
-        const string& p   = det.path();
-        size_t idx = p.find(prev);
-        if ( idx == 0 )  {
-          //printout(INFO,"Conditions","***** %d %p %08X: %s ",
-          //         det.level(), det.ptr(), key, det.path().c_str());
-          continue;
-        }
-        prev = p;
-        printout(INFO,"Conditions","%d %p %08X: %s ",
-                 det.level(), det.ptr(), key, det.path().c_str());
-        e.top = 1;
-      }
-
-      printout(INFO,"Conditions","Working down the tree....");
-      for(auto i=data.detectors.begin(); i != data.detectors.end(); ++i)  {
-        Entry& e = data.entries[(*i).second];
-        if ( e.top )  {
-          DetElement det = e.det;
-          printout(INFO,"Conditions","%d %p %08X: %s ",
-                   det.level(), det.ptr(), det.key(), det.path().c_str());
-          __print(det, data, 0);
+      dd4hep_ptr<UserPool> user_pool;
+      manager.prepare(iov, user_pool);
+      return collect(lcdd.world(), user_pool, context, 0);
+    }
+    
+    int computeDependencies(ConditionsManager manager, AlignmentsManager& am)  {
+      const IOVType* iovType = manager.iovType("epoch");
+      for(int i=0; i<10; ++i)  {   {
+          int t = time + i*3600;
+          IOV  iov(iovType, IOV::Key(t,t));
+          dd4hep_ptr<UserPool> user_pool;
+          long num_expired = manager.prepare(iov, user_pool);
+          printout(INFO,"Conditions",
+                   "+++ ConditionsUpdate: Updated %ld conditions... IOV:%s",
+                   num_expired, iov.str().c_str());
+          am.compute(user_pool);
+          user_pool->clear();
         }
+        DD4hep::InstanceCount::dump();
       }
-      user_pool->clear();
       return 1;
     }
   };
 
   /// Plugin function
   long dddb_derived_alignments(LCDD& lcdd, int argc, char** argv) {
-    long int long init_time = argc>0 ? *(long*)argv[0] : 0;//DDDB::DDDBReader::makeTime(2016,4,1,12);
-    ConditionsManager manager = ConditionsManager::from(lcdd);
-    AlignmentSelector selector(manager);
-    AlignmentUpdate* update = new AlignmentUpdate();
-    int ret = selector.collectDependencies(lcdd.world(), update, 0);
-    if ( ret == 1 )  {
-      ret = selector.computeDependencies(init_time);
+    long int long init_time = DDDB::DDDBReader::makeTime(2016,4,1,12);
+    if ( argc>0 )  {
+      struct tm tm;
+      char* c = ::strptime(argv[0],"%d-%m-%Y %H:%M:%S",&tm);
+      if ( 0 == c )   {
+        except("DerivedAlignmentsTest","Invalid time format given for update:%s "
+               " should be: %d-%m-%Y %H:%M:%S", argv[0]);
+      }
+    }
+    AlignmentSelector selector(lcdd, init_time);
+    AlignmentsManager alig_manager("Test");
+    ConditionsManager cond_manager(ConditionsManager::from(lcdd));
+    int ret = 0;
+    try {
+      ret = selector.collect(cond_manager,alig_manager);
+      if ( ret == 1 )  {
+        ret = selector.computeDependencies(cond_manager,alig_manager);
+      }
+    }
+    catch(...)   {
     }
-    delete update;
+    alig_manager.destroy();
     return ret;
   }
 } /* End anonymous namespace  */
diff --git a/DDDB/src/DDDBConditionsLoader.cpp b/DDDB/src/DDDBConditionsLoader.cpp
index b06f5d1d7..409e2c662 100644
--- a/DDDB/src/DDDBConditionsLoader.cpp
+++ b/DDDB/src/DDDBConditionsLoader.cpp
@@ -206,8 +206,10 @@ size_t DDDBConditionsLoader::update(const iov_type& req_validity,
     Condition::Object* c = (*i).ptr();
     size_t idx = c->address.find('#');
     string url = (idx == string::npos) ? c->address : c->address.substr(0,idx);
+#if 0
     printout(INFO,"DDDB","++ Need to update: %-40s [%08X] --> %s",
              c->name.c_str(), c->hash, url.c_str());
+#endif
     urls.insert(make_pair(url,c));
   }
   /// Now load them. In the callbacks we can check if we got all required conditions
diff --git a/DDDB/src/DDDBDerivedCondTest.cpp b/DDDB/src/DDDBDerivedCondTest.cpp
index 2047ded71..13c518ad9 100644
--- a/DDDB/src/DDDBDerivedCondTest.cpp
+++ b/DDDB/src/DDDBDerivedCondTest.cpp
@@ -199,10 +199,6 @@ namespace  {
       m_allDependencies.clear();
     }
 
-    void addDependency(ConditionDependency* dependency)   {
-      m_allDependencies.insert(dependency->target.hash, dependency);
-    }
-
     RangeConditions findCond(const string& match)   {
       RangeConditions result;
       if ( !match.empty() )  {
@@ -266,9 +262,9 @@ namespace  {
               build_3.add(target1);
               build_3.add(target2);
             }
-            addDependency(build_1.release());
-            addDependency(build_2.release());
-            addDependency(build_3.release());
+            m_allDependencies.insert(build_1.release());
+            m_allDependencies.insert(build_2.release());
+            m_allDependencies.insert(build_3.release());
           }
           ++m_counters.numAlignments;
         }
diff --git a/DDDB/src/DDDBFileReader.cpp b/DDDB/src/DDDBFileReader.cpp
index 847a348e5..db99db44b 100644
--- a/DDDB/src/DDDBFileReader.cpp
+++ b/DDDB/src/DDDBFileReader.cpp
@@ -42,6 +42,10 @@ namespace DD4hep {
       virtual ~DDDBFileReader()  {}
       /// Read raw XML object from the database / file
       virtual int getObject(const std::string& system_id, UserContext* ctxt, std::string& data);
+      /// Resolve a given URI to a string containing the data
+      virtual bool load(const std::string& system_id, std::string& buffer);
+      /// Resolve a given URI to a string containing the data
+      virtual bool load(const std::string& system_id, UserContext* ctxt, std::string& buffer);
 
     };
   }    /* End namespace DDDB            */
@@ -85,6 +89,25 @@ int DD4hep::DDDB::DDDBFileReader::getObject(const std::string& system_id,
   return 0;
 }
 
+/// Resolve a given URI to a string containing the data
+bool DD4hep::DDDB::DDDBFileReader::load(const std::string& system_id, std::string& buffer)   {
+  return XML::UriReader::load(system_id, buffer);
+}
+
+/// Resolve a given URI to a string containing the data
+bool DD4hep::DDDB::DDDBFileReader::load(const std::string& system_id,
+                                        UserContext*  ctxt,
+                                        std::string& buffer)
+{
+  bool result = DDDBReader::load(system_id, ctxt, buffer);
+  if ( result )  {
+    DDDBReaderContext* context = (DDDBReaderContext*)ctxt;
+    context->valid_since = context->event_time;
+    context->valid_until = context->event_time;
+  }
+  return result;
+}
+
 namespace {
   void* create_dddb_xml_file_reader(const char* /* arg */) {
     return new DD4hep::DDDB::DDDBFileReader();
diff --git a/DDDB/src/DDDBReader.cpp b/DDDB/src/DDDBReader.cpp
index 251b38b07..58077de48 100644
--- a/DDDB/src/DDDBReader.cpp
+++ b/DDDB/src/DDDBReader.cpp
@@ -21,9 +21,6 @@
 // Framework includes
 #include "DDDB/DDDBReader.h"
 #include "DD4hep/Printout.h"
-//#include "DD4hep/LCDD.h"
-//#include "XML/DocumentHandler.h"
-//#include "XML/XMLElements.h"
 
 // C/C++ include files
 #include <ctime>
@@ -48,12 +45,13 @@ long long int DDDBReader::makeTime(int year, int month, int day,
 {
   struct tm tm_init;
   ::memset(&tm_init,0,sizeof(tm_init));
-  tm_init.tm_year = year;
-  tm_init.tm_mon  = month;
-  tm_init.tm_mday = day;
-  tm_init.tm_hour = hour;
-  tm_init.tm_min  = minutes;
-  tm_init.tm_sec  = seconds;
+  tm_init.tm_year  = year > 1900 ? year-1900 : year;
+  tm_init.tm_mon   = month;
+  tm_init.tm_mday  = day;
+  tm_init.tm_hour  = hour;
+  tm_init.tm_min   = minutes;
+  tm_init.tm_sec   = seconds;
+  tm_init.tm_isdst = -1;
   return ::mktime(&tm_init);
 }
 
@@ -88,6 +86,18 @@ bool DDDBReader::load(const string& system_id,
   return false;
 }
 
+/// Inform reader about a locally (e.g. by XercesC) handled source load
+void DDDBReader::parserLoaded(const std::string& system_id)  {
+  return XML::UriReader::parserLoaded(system_id);
+}
+
+/// Inform reader about a locally (e.g. by XercesC) handled source load
+void DDDBReader::parserLoaded(const std::string& system_id, UserContext* ctxt)  {
+  DDDBReaderContext* context = (DDDBReaderContext*)ctxt;
+  context->valid_since = context->event_time;
+  context->valid_until = context->event_time;
+}
+
 int DDDBReader::getObject(const string& sys_id, UserContext* /* ctxt */, string& /* out */)
 {
   except("DDDBReader","DDDBReader::getObject is a virtual method, "
diff --git a/cmake/run_test_package.sh b/cmake/run_test_package.sh
index e730b666e..10b7e06c1 100755
--- a/cmake/run_test_package.sh
+++ b/cmake/run_test_package.sh
@@ -5,10 +5,16 @@
 #   calls the command (given as first argument)
 #   with all following arguments
 #
-
+if [ ! ${DD4hep_DIR} ]; then
+    export DD4hep_DIR=@DD4hep_DIR@;
+fi;
+#
+source ${DD4hep_DIR}/bin/thisdd4hep.sh;
+dd4hep_parse_this ${BASH_ARGV[0]} @PackageName@;
+#
 #----- initialize environment for this package - including DD4hep 
-source @CMAKE_INSTALL_PREFIX@/bin/this@PackageName@.sh
-
+source ${THIS}/bin/this@PackageName@.sh
+#
 #----- parse command line - first argument is the 
 #      test to run
 command=$1
diff --git a/examples/DDDB/CMakeLists.txt b/examples/DDDB/CMakeLists.txt
index 42b64f781..a986586bd 100644
--- a/examples/DDDB/CMakeLists.txt
+++ b/examples/DDDB/CMakeLists.txt
@@ -120,6 +120,16 @@ if (DD4HEP_USE_XERCESC)
     -config DD4hep_ConditionsManagerInstaller
     -exec   DDDB_DerivedCondTest
     REGEX_PASS "Building dependent condition: /dd/Conditions/Alignment/TT/TTbVLayerR1Module3B/derived_3" )
+
+  #
+  #---Testing: Load the geometry + conditions + run basic derived alignments test
+  dd4hep_add_test_reg( test_DDDB_derived_alignments
+    COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
+    EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
+    -config DD4hep_ConditionsManagerInstaller
+    -exec   DDDB_DerivedAlignmentsTest
+    REGEX_PASS "|     24950| 24950|        0|DD4hep::Alignments::Interna::AlignmentConditionObject" )
+
   #
   #---Testing: Extract DDDB data from zip archive -------------------------------
   dd4hep_add_test_reg( test_DDDB_clean
@@ -127,5 +137,4 @@ if (DD4HEP_USE_XERCESC)
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/extract_dddb.sh -clean
     REGEX_PASS "DDDB Database successfully removed" )
 
-
 endif()
diff --git a/examples/DDDB/scripts/run_dddb.sh b/examples/DDDB/scripts/run_dddb.sh
index cf4779488..d58fbd171 100755
--- a/examples/DDDB/scripts/run_dddb.sh
+++ b/examples/DDDB/scripts/run_dddb.sh
@@ -83,4 +83,8 @@ done;
 export DD4HEP_TRACE=ON;
 ARGS=`echo -plugin DDDB_Executor ${loader} ${params} ${input} ${config} ${exec} ${vis}`;
 echo "Command: ${debug} `which geoPluginRun` -destroy $ARGS";
-${debug} `which geoPluginRun` -destroy ${ARGS};
+if test -z "${debug}";then
+    exec `which geoPluginRun` -destroy ${ARGS};
+else
+    ${debug} `which geoPluginRun` -destroy ${ARGS};
+fi;
-- 
GitLab