diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoAlignableTransform.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoAlignableTransform.h
index 009919232450427121dd7dba213bdc1256c77588..3af0c03752dbdce76a62b1778177c19841bb4436 100644
--- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoAlignableTransform.h
+++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoAlignableTransform.h
@@ -7,6 +7,7 @@
 
 #include "GeoModelKernel/GeoTransform.h"
 #include <vector>
+#include <mutex>
 
 class GeoVAlignmentStore;
 
@@ -45,6 +46,10 @@ class GeoAlignableTransform final : public GeoTransform
   // the memory is unallocated.
   GeoTrf::Transform3D* m_delta;
 
+  // We need to protext m_delta with a mutex in order to avoid
+  // memory corruption in multithreaded applications
+  mutable std::mutex m_deltaMutex;
+  
   // A list of parents who use this alignable target.  They
   // must all be notified when the alignment changes!
   std::vector<GeoGraphNode*>  m_parentList;
diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVFullPhysVol.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVFullPhysVol.h
index 795ac30700019a3038eac1e42bf4ea3ed0c4af3f..04c09c66b5d1fb51921e0951b5633426881d585f 100644
--- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVFullPhysVol.h
+++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoVFullPhysVol.h
@@ -7,6 +7,7 @@
 
 #include "GeoModelKernel/GeoVPhysVol.h"
 #include "GeoModelKernel/GeoAbsPositionInfo.h"
+#include <mutex>
 
 class GeoVAlignmentStore;
 
@@ -51,6 +52,11 @@ class GeoVFullPhysVol : public GeoVPhysVol
  protected:
   virtual ~GeoVFullPhysVol() override;
 
+  /// Mutex serving dual purpose:
+  ///  1. To protect the absolute position info
+  ///  2. To protect m_daughters container in the derived GeoFullPhysVol
+  mutable std::mutex m_mutex;
+
  private:
   /// The absolute name of this volume.
   std::string m_absName;
diff --git a/GeoModelCore/GeoModelKernel/src/GeoAlignableTransform.cxx b/GeoModelCore/GeoModelKernel/src/GeoAlignableTransform.cxx
index 9542340bbe9d10bde31de88b14d769fd8bf9bb0f..b5c0a0e0b1aeb4ef280d29e0c0ec6ec1c01e6161 100755
--- a/GeoModelCore/GeoModelKernel/src/GeoAlignableTransform.cxx
+++ b/GeoModelCore/GeoModelKernel/src/GeoAlignableTransform.cxx
@@ -29,20 +29,29 @@ __attribute__ ((flatten))
 #endif
 GeoTrf::Transform3D GeoAlignableTransform::getTransform(const GeoVAlignmentStore* store) const
 {
-  const GeoTrf::Transform3D* delta = (store==nullptr ? m_delta : store->getDelta(this));
-  return GeoTransform::getTransform(nullptr) * (delta==nullptr ? GeoTrf::Transform3D(GeoTrf::Transform3D::Identity()) : *delta);
+  if(store) {
+    const GeoTrf::Transform3D* delta = store->getDelta(this);
+    return GeoTransform::getTransform(nullptr) * (delta==nullptr ? GeoTrf::Transform3D(GeoTrf::Transform3D::Identity()) : *delta);
+  }
+  else {
+    std::scoped_lock<std::mutex> guard(m_deltaMutex);
+    return GeoTransform::getTransform(nullptr) * (m_delta==nullptr ? GeoTrf::Transform3D(GeoTrf::Transform3D::Identity()) : *m_delta);
+  }
 }
 
 void GeoAlignableTransform::setDelta (const GeoTrf::Transform3D& delta, GeoVAlignmentStore* store)
 {
   if(store==nullptr) {
-    if(m_delta && (m_delta->isApprox(delta))) return;
-    
-    if(m_delta) {
-      (*m_delta) = delta;
-    }
-    else {
-      m_delta = new GeoTrf::Transform3D(delta);
+    {
+      std::scoped_lock<std::mutex> guard(m_deltaMutex);
+      if(m_delta && (m_delta->isApprox(delta))) return;
+      
+      if(m_delta) {
+	(*m_delta) = delta;
+      }
+      else {
+	m_delta = new GeoTrf::Transform3D(delta);
+      }
     }
 
     std::set<GeoGraphNode*> uniqueParents;
@@ -63,9 +72,11 @@ void GeoAlignableTransform::clearDelta(GeoVAlignmentStore* store)
 {
   // Does not make sence to clear deltas inside Alignment Store
   if(store!=nullptr) return;
-
-  delete m_delta;
-  m_delta = nullptr;
+  {
+    std::scoped_lock<std::mutex> guard(m_deltaMutex);
+    delete m_delta;
+    m_delta = nullptr;
+  }
   
   std::set<GeoGraphNode*> uniqueParents;
   for(GeoGraphNode* parent : m_parentList) {
diff --git a/GeoModelCore/GeoModelKernel/src/GeoFullPhysVol.cxx b/GeoModelCore/GeoModelKernel/src/GeoFullPhysVol.cxx
index 9b69ade67c96f5a8cc9ea3e963154b49403bcd3b..0521c9659945cdbcdbd6ac1325c6f6dfdffeebf2 100755
--- a/GeoModelCore/GeoModelKernel/src/GeoFullPhysVol.cxx
+++ b/GeoModelCore/GeoModelKernel/src/GeoFullPhysVol.cxx
@@ -26,7 +26,7 @@ GeoFullPhysVol::~GeoFullPhysVol()
 void GeoFullPhysVol::add(GeoGraphNode* graphNode)
 {
   if(m_cloneOrigin) throw std::runtime_error("Attempt to modify contents of a cloned FPV");
-
+  std::scoped_lock<std::mutex> guard(m_mutex);
   m_daughters.push_back(graphNode);
   graphNode->ref();
   graphNode->dockTo(this);
@@ -235,15 +235,18 @@ GeoTrf::Transform3D GeoFullPhysVol::getDefX(const GeoVAlignmentStore* store) con
 
 unsigned int GeoFullPhysVol::getNChildNodes() const 
 {
+  std::scoped_lock<std::mutex> guard(m_mutex);
   return m_daughters.size();
 }
 
 const GeoGraphNode * const * GeoFullPhysVol::getChildNode(unsigned int i) const 
 {
+  std::scoped_lock<std::mutex> guard(m_mutex);
   return &(m_daughters[i]);
 }
 const GeoGraphNode * const * GeoFullPhysVol::findChildNode(const GeoGraphNode * n) const 
 {
+  std::scoped_lock<std::mutex> guard(m_mutex);
   std::vector<const GeoGraphNode *>::const_iterator i = std::find(m_daughters.begin(),m_daughters.end(),n);
   if (i==m_daughters.end()) {
     return nullptr;
diff --git a/GeoModelCore/GeoModelKernel/src/GeoPhysVol.cxx b/GeoModelCore/GeoModelKernel/src/GeoPhysVol.cxx
index cbc44e3ef1a362d4b60373e5bc36572cf6d787db..7b6161be085854086be3704e9a8d9981129714aa 100755
--- a/GeoModelCore/GeoModelKernel/src/GeoPhysVol.cxx
+++ b/GeoModelCore/GeoModelKernel/src/GeoPhysVol.cxx
@@ -19,13 +19,13 @@ GeoPhysVol::GeoPhysVol(const GeoLogVol* LogVol)
 
 GeoPhysVol::~GeoPhysVol()
 {
-  std::lock_guard<std::mutex> lk(m_muxVec);
+  std::scoped_lock<std::mutex> lk(m_muxVec);
   for(const GeoGraphNode* daughter : m_daughters) daughter->unref();
 }
 
 void GeoPhysVol::add(GeoGraphNode* graphNode)
 {
-  std::lock_guard<std::mutex> lk(m_muxVec);
+  std::scoped_lock<std::mutex> lk(m_muxVec);
   m_daughters.push_back(graphNode);
   graphNode->ref();
   graphNode->dockTo(this);
@@ -88,7 +88,7 @@ void GeoPhysVol::exec(GeoNodeAction *action) const
   }
   else {
     // FIXME: m_daughters access is now protected in other methods, but having the lock here makes a deadlock
-    // std::lock_guard<std::mutex> lk(m_muxVec);
+    // std::scoped_lock<std::mutex> lk(m_muxVec);
     // TODO: Think more thouroughly about thread-safe of this class...!!
     for(size_t c = 0; c < m_daughters.size (); c++) {
       m_daughters[c]->exec(action);
@@ -195,19 +195,19 @@ GeoTrf::Transform3D GeoPhysVol::getDefX(const GeoVAlignmentStore* store) const {
 
 unsigned int GeoPhysVol::getNChildNodes() const 
 {
-  std::lock_guard<std::mutex> lk(m_muxVec);
+  std::scoped_lock<std::mutex> lk(m_muxVec);
   return m_daughters.size();
 }
 
 const GeoGraphNode * const * GeoPhysVol::getChildNode(unsigned int i) const 
 {
-  std::lock_guard<std::mutex> lk(m_muxVec);
+  std::scoped_lock<std::mutex> lk(m_muxVec);
   return &(m_daughters[i]);
 }
 
 const GeoGraphNode * const * GeoPhysVol::findChildNode(const GeoGraphNode * n) const 
 {
-  std::lock_guard<std::mutex> lk(m_muxVec);
+  std::scoped_lock<std::mutex> lk(m_muxVec);
   std::vector<const GeoGraphNode *>::const_iterator i = std::find(m_daughters.begin(),m_daughters.end(),n);
   if (i==m_daughters.end()) {
     return nullptr;
diff --git a/GeoModelCore/GeoModelKernel/src/GeoVFullPhysVol.cxx b/GeoModelCore/GeoModelKernel/src/GeoVFullPhysVol.cxx
index 6555d46344900f5b0f492c587e0746342648ff53..598484f7970f04c462653a3912e3997e977ebb86 100755
--- a/GeoModelCore/GeoModelKernel/src/GeoVFullPhysVol.cxx
+++ b/GeoModelCore/GeoModelKernel/src/GeoVFullPhysVol.cxx
@@ -30,6 +30,8 @@ const GeoTrf::Transform3D & GeoVFullPhysVol::getAbsoluteTransform(GeoVAlignmentS
   //------------------------------------------------------------------------------------------------//     
   if(isShared()) throw std::runtime_error(errorMessage);
 
+  std::scoped_lock<std::mutex> guard(m_mutex);
+  
   if(store==nullptr && !m_absPosInfo) m_absPosInfo = new GeoAbsPositionInfo();
 
   //
@@ -78,6 +80,7 @@ const GeoTrf::Transform3D & GeoVFullPhysVol::getAbsoluteTransform(GeoVAlignmentS
 const GeoTrf::Transform3D& GeoVFullPhysVol::getCachedAbsoluteTransform(const GeoVAlignmentStore* store) const
 {
   if(store==nullptr) {
+    std::scoped_lock<std::mutex> guard(m_mutex);
     if(m_absPosInfo->getAbsTransform()) return *m_absPosInfo->getAbsTransform();
   }
   else {
@@ -90,6 +93,7 @@ const GeoTrf::Transform3D& GeoVFullPhysVol::getCachedAbsoluteTransform(const Geo
 
 void GeoVFullPhysVol::clearPositionInfo() const
 {
+  std::scoped_lock<std::mutex> guard(m_mutex);
   delete m_absPosInfo;
   m_absPosInfo = nullptr;
 }
@@ -105,6 +109,8 @@ const GeoTrf::Transform3D& GeoVFullPhysVol::getDefAbsoluteTransform(GeoVAlignmen
   //------------------------------------------------------------------------------------------------//     
   if(isShared()) throw std::runtime_error(errorMessage);
 
+  std::scoped_lock<std::mutex> guard(m_mutex);
+  
   if(store==nullptr && !m_absPosInfo) m_absPosInfo = new GeoAbsPositionInfo();
 
   //
@@ -153,6 +159,7 @@ const GeoTrf::Transform3D& GeoVFullPhysVol::getDefAbsoluteTransform(GeoVAlignmen
 const GeoTrf::Transform3D& GeoVFullPhysVol::getCachedDefAbsoluteTransform(const GeoVAlignmentStore* store) const
 {
   if(store==nullptr) {
+    std::scoped_lock<std::mutex> guard(m_mutex);
     if(m_absPosInfo->getDefAbsTransform()) return *m_absPosInfo->getDefAbsTransform();
   }
   else {