diff --git a/Event/xAOD/xAODTau/Root/TauJet_v3.cxx b/Event/xAOD/xAODTau/Root/TauJet_v3.cxx
index 7f5670867d92fc08f16c0f69bf9aeff0fbe869c5..b6f641c4e37126a3787074cb9d13afdd0fdbf1ed 100644
--- a/Event/xAOD/xAODTau/Root/TauJet_v3.cxx
+++ b/Event/xAOD/xAODTau/Root/TauJet_v3.cxx
@@ -628,41 +628,11 @@ namespace xAOD {
   }
 
 
-  std::vector<const IParticle*> TauJet_v3::clusters(double dRMax) const {
+  std::vector<const IParticle*> TauJet_v3::clusters() const {
     std::vector<const IParticle*> particleList;
 
     for (const auto& link : clusterAcc(*this)) {
       const IParticle* particle = *link;
-
-      if (dRMax > 0.0) {
-        const xAOD::CaloCluster* cluster = static_cast<const xAOD::CaloCluster*>(particle);
-        const xAOD::Vertex* vertex = nullptr;
-        TLorentzVector clusterP4;
-        TLorentzVector tauP4;
-        
-        // Apply the vertex correction if there is a vertex
-        if (this->vertexLink().isValid()) {
-          vertex = this->vertex();
-          tauP4 = this->p4(xAOD::TauJetParameters::IntermediateAxis);  
-        }
-        else {
-          const xAOD::Jet* jet = this->jet();
-          bool isAvailable = jet->getAssociatedObject("OriginVertex", vertex);
-          if (!isAvailable) vertex = nullptr;
-          tauP4 = this->p4(xAOD::TauJetParameters::DetectorAxis);
-        }
-
-        if (vertex) {
-          clusterP4 = xAOD::CaloVertexedTopoCluster(*cluster, vertex->position()).p4();
-        }
-        else {
-          clusterP4 = cluster->p4();
-        }
-
-        double dR = clusterP4.DeltaR(tauP4);
-        if (dR > dRMax) continue;
-      }
-
       particleList.push_back(particle);
     }
 
@@ -694,6 +664,11 @@ namespace xAOD {
     clusterAcc( *this ).clear();
   }
 
+  static const SG::AuxElement::Accessor< std::vector< xAOD::CaloVertexedTopoCluster > > vertexedClustersAcc( "VertexedClusters" );
+
+  std::vector<xAOD::CaloVertexedTopoCluster> TauJet_v3::vertexedClusters() const {
+    return vertexedClustersAcc(*this);
+  }
 
   // setters and getters for the pi0 links
   AUXSTORE_OBJECT_SETTER_AND_GETTER( TauJet_v3,
diff --git a/Event/xAOD/xAODTau/Root/TauxAODHelpers.cxx b/Event/xAOD/xAODTau/Root/TauxAODHelpers.cxx
index 5c2826cab2b02a3b1408535a9ebba7826f1caff3..5a851e42ec16d40ec7887fbabdc26528eb2ba2a2 100644
--- a/Event/xAOD/xAODTau/Root/TauxAODHelpers.cxx
+++ b/Event/xAOD/xAODTau/Root/TauxAODHelpers.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "xAODTau/TauxAODHelpers.h"
@@ -86,3 +86,45 @@ std::vector<xAOD::TauTrack*> xAOD::TauHelpers::allTauTracksNonConst( const xAOD:
   xAOD::TauTrack::TrackFlagType mask=0;
   return tauTracksNonConstWithMask(tau, trackCont, mask);
 }
+
+
+
+std::vector<const xAOD::IParticle*> 
+xAOD::TauHelpers::clusters(const xAOD::TauJet& tau, double dRMax) {
+  auto vertexedClusterList = xAOD::TauHelpers::vertexedClusters(tau, dRMax);
+
+  std::vector<const xAOD::IParticle*> clusterList;
+  for (const auto& vertexedCluster : vertexedClusterList) {
+    const xAOD::CaloCluster& cluster = vertexedCluster.clust();
+    clusterList.push_back(&cluster);
+  }
+
+  return clusterList;
+}
+
+
+
+std::vector<xAOD::CaloVertexedTopoCluster> 
+xAOD::TauHelpers::vertexedClusters(const xAOD::TauJet& tau, double dRMax) {
+  TLorentzVector tauAxis;
+  if (tau.vertexLink().isValid()) {
+    tauAxis = tau.p4(xAOD::TauJetParameters::IntermediateAxis); 
+  }
+  else {
+    tauAxis = tau.p4(xAOD::TauJetParameters::DetectorAxis);
+  }
+
+  auto vertexedClusterList = tau.vertexedClusters();
+  
+  std::vector<xAOD::CaloVertexedTopoCluster> selectedList;
+  for (const auto& vertexedCluster : vertexedClusterList) {
+    TLorentzVector clusterP4 = vertexedCluster.p4();
+    
+    double dR = clusterP4.DeltaR(tauAxis);
+    if (dR > dRMax) continue;
+
+    selectedList.push_back(vertexedCluster);
+  }
+
+  return selectedList;
+}
diff --git a/Event/xAOD/xAODTau/xAODTau/TauxAODHelpers.h b/Event/xAOD/xAODTau/xAODTau/TauxAODHelpers.h
index 257ae9f6b69027129d926f6ac7cd30b9f3fd26fb..73500e727886937ab87cdcc518aeb8208e484c6a 100644
--- a/Event/xAOD/xAODTau/xAODTau/TauxAODHelpers.h
+++ b/Event/xAOD/xAODTau/xAODTau/TauxAODHelpers.h
@@ -44,8 +44,12 @@ namespace xAOD {
     std::vector<xAOD::TauTrack*> tauTracksNonConst( const xAOD::TauJet* tau, xAOD::TauTrackContainer* trackCont, xAOD::TauJetParameters::TauTrackFlag flag=xAOD::TauJetParameters::TauTrackFlag::classifiedCharged );
     std::vector<xAOD::TauTrack*> tauTracksNonConstWithMask( const xAOD::TauJet* tau, xAOD::TauTrackContainer* trackCont, xAOD::TauTrack::TrackFlagType mask );
     std::vector<xAOD::TauTrack*> allTauTracksNonConst( const xAOD::TauJet* tau, xAOD::TauTrackContainer* trackCont );
+    
+    //* @brief Obtain the CaloCluster within dRMax of the tau candidate */
+    std::vector<const xAOD::IParticle*> clusters(const xAOD::TauJet& tau, double dRMax);
 
-
+    //* @brief Obtain the CaloVertexedTopoCluster within dRMax of the tau candidate */
+    std::vector<xAOD::CaloVertexedTopoCluster> vertexedClusters(const xAOD::TauJet& tau, double dRMax);
 
   }// TauHelpers
 
diff --git a/Event/xAOD/xAODTau/xAODTau/versions/TauJet_v3.h b/Event/xAOD/xAODTau/xAODTau/versions/TauJet_v3.h
index 48e52104518c417ec4a22a791fdd89bac0fa6b2a..15c871eb5206fd608e62ef64ee6600bc222ed1e5 100644
--- a/Event/xAOD/xAODTau/xAODTau/versions/TauJet_v3.h
+++ b/Event/xAOD/xAODTau/xAODTau/versions/TauJet_v3.h
@@ -23,6 +23,7 @@
 #include "xAODTracking/VertexContainer.h"
 #include "xAODJet/JetContainer.h"
 #include "xAODPFlow/PFOContainer.h"
+#include "xAODCaloEvent/CaloVertexedTopoCluster.h"
 
 // ROOT include(s):
 #include "Math/Vector4D.h"
@@ -292,8 +293,8 @@ namespace xAOD {
     /// Get the pointer to a given cluster associated with this tau
     const IParticle* cluster( size_t i) const;
     
-    //* @brief Get the clusters within dR cone of the tau candidate */
-    std::vector<const IParticle*> clusters(double dR = 0.2) const;
+    //* @brief Get the clusters */
+    std::vector<const IParticle*> clusters() const;
     
     /// Get TLV to a given cluster in calibrated state
     FourMom_t calibratedCluster( size_t i, xAOD::CaloCluster::State state=xAOD::CaloCluster::State::CALIBRATED) const;
@@ -304,6 +305,9 @@ namespace xAOD {
     /// Remove all clusters from the tau
     void clearClusterLinks();
 
+    //* @brief Get the clusters corrected to poinst at tau vertex*/
+    std::vector<xAOD::CaloVertexedTopoCluster> vertexedClusters() const;
+
     const IParticleLinks_t& pi0Links() const;
 
     void setPi0Links( const IParticleLinks_t& pi0s );
diff --git a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
index d1f1316fd1477d2a9306cae12eafecce979169c1..149e97afa359376d4903b95d647db5785074776b 100644
--- a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
@@ -21,6 +21,7 @@
 // Tau EDM
 #include "xAODTau/TauJetContainer.h"
 #include "xAODTau/TauTrack.h"
+#include "xAODTau/TauxAODHelpers.h"
 
 // Tracking EDM
 #include "xAODTracking/Vertex.h"
@@ -107,11 +108,7 @@ namespace met {
                                                    const met::METAssociator::ConstitHolder& /*tcCont*/) const
   {
     const TauJet* tau = static_cast<const TauJet*>(obj);
-
-    for (const xAOD::IParticle* particle : tau->clusters(0.2)) {
-      const CaloCluster* cluster = static_cast<const CaloCluster*>(particle);
-      tclist.push_back(cluster);
-    }
+    tclist = xAOD::TauHelpers::clusters(*tau, 0.2);
 
     return StatusCode::SUCCESS;
   }
diff --git a/Reconstruction/tauRec/python/TauAlgorithmsHolder.py b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py
index b0f0ec23f4db82d349f7c8a088f30c5fd81b54fa..6583d4f1c674db8df7ca7a07002089756ea0250b 100644
--- a/Reconstruction/tauRec/python/TauAlgorithmsHolder.py
+++ b/Reconstruction/tauRec/python/TauAlgorithmsHolder.py
@@ -1035,6 +1035,29 @@ def getTauVertexCorrection():
     cached_instances[_name] = myTauVertexCorrection
     return myTauVertexCorrection
 
+def getTauVertexedClusterDecorator():
+    from tauRec.tauRecFlags import tauFlags
+    from tauRecTools.tauRecToolsConf import TauVertexedClusterDecorator
+    from JetRec.JetRecFlags import jetFlags
+
+    _name = sPrefix + 'TauVertexedClusterDecorator'
+    
+    if _name in cached_instances:
+        return cached_instances[_name]
+  
+    doJetVertexCorrection = False
+    if tauFlags.isStandalone:
+        doJetVertexCorrection = True
+    if jetFlags.useVertices() and jetFlags.useTracks():
+        doJetVertexCorrection = True
+
+    myTauVertexedClusterDecorator = TauVertexedClusterDecorator(name = _name,
+                                                                SeedJet = tauFlags.tauRecSeedJetCollection(), 
+                                                                VertexCorrection = True,
+                                                                JetVertexCorrection = doJetVertexCorrection)
+    
+    cached_instances[_name] = myTauVertexedClusterDecorator
+    return myTauVertexedClusterDecorator
 
 def getParticleCache():
     #If reading from ESD we not create a cache of extrapolations to the calorimeter, so we should signify this by setting the cache key to a null string
diff --git a/Reconstruction/tauRec/python/TauRecBuilder.py b/Reconstruction/tauRec/python/TauRecBuilder.py
index a62c51da435843ff2a5dd2c90ef7e1b1c5ed1efd..b52f311840479b641b5d78d15006c3a570cef0a9 100644
--- a/Reconstruction/tauRec/python/TauRecBuilder.py
+++ b/Reconstruction/tauRec/python/TauRecBuilder.py
@@ -59,6 +59,7 @@ class TauRecCoreBuilder ( TauRecConfigured ) :
             tools.append(taualgs.getTauAxis())
             tools.append(taualgs.getTauTrackFinder(removeDuplicateTracks=(tauFlags.removeDuplicateCoreTracks() ) ))
             tools.append(taualgs.getTauClusterFinder())
+            tools.append(taualgs.getTauVertexedClusterDecorator())
 
             if doRNNTrackClassification:
                 tools.append(taualgs.getTauTrackRNNClassifier())
diff --git a/Reconstruction/tauRec/share/TauAODList.py b/Reconstruction/tauRec/share/TauAODList.py
index 19dea7073b01a1c1984c373f3719304f5fdd9527..f2df499687a70222c155abbf0a12ff85cce2b235 100644
--- a/Reconstruction/tauRec/share/TauAODList.py
+++ b/Reconstruction/tauRec/share/TauAODList.py
@@ -14,7 +14,7 @@ TauAODList = []
 # Taus
 #------------------------------------------------------------------------------
 TauAODList += [ "xAOD::TauJetContainer#TauJets" ]
-TauAODList += [ "xAOD::TauJetAuxContainer#TauJetsAux.-mu.-nVtxPU.-ABS_ETA_LEAD_TRACK.-TAU_ABSDELTAPHI.-TAU_ABSDELTAETA.-absipSigLeadTrk" ]
+TauAODList += [ "xAOD::TauJetAuxContainer#TauJetsAux.-VertexedClusters.-mu.-nVtxPU.-ABS_ETA_LEAD_TRACK.-TAU_ABSDELTAPHI.-TAU_ABSDELTAETA.-absipSigLeadTrk" ]
 
 #------------------------------------------------------------------------------
 # Tau tracks
diff --git a/Reconstruction/tauRec/share/TauESDList.py b/Reconstruction/tauRec/share/TauESDList.py
index de81e842a59a1ea3485855ac7e1b2ac5cf2bc6b2..2d04f1c40f04c30d322db4527a59d74b91ad8eba 100644
--- a/Reconstruction/tauRec/share/TauESDList.py
+++ b/Reconstruction/tauRec/share/TauESDList.py
@@ -14,7 +14,7 @@ TauESDList = []
 # Taus
 #------------------------------------------------------------------------------
 TauESDList += [ "xAOD::TauJetContainer#TauJets" ]
-TauESDList += [ "xAOD::TauJetAuxContainer#TauJetsAux." ]
+TauESDList += [ "xAOD::TauJetAuxContainer#TauJetsAux.-VertexedClusters" ]
 
 #------------------------------------------------------------------------------
 # Tau tracks
diff --git a/Reconstruction/tauRecTools/CMakeLists.txt b/Reconstruction/tauRecTools/CMakeLists.txt
index 952f9e745c286326b6cc7067f43e36f449e4dd43..7a97d9b240ae0a68d07060ffc889fc2d01f0f367 100644
--- a/Reconstruction/tauRecTools/CMakeLists.txt
+++ b/Reconstruction/tauRecTools/CMakeLists.txt
@@ -27,6 +27,7 @@ atlas_add_root_dictionary( tauRecToolsLib tauRecToolsLibCintDict
   tauRecTools/TauIDVarCalculator.h
   tauRecTools/TauDecayModeNNClassifier.h
   tauRecTools/TauVertexCorrection.h
+  tauRecTools/TauVertexedClusterDecorator.h
   Root/LinkDef.h
   EXTERNAL_PACKAGES ROOT
   )
diff --git a/Reconstruction/tauRecTools/Root/TauVertexedClusterDecorator.cxx b/Reconstruction/tauRecTools/Root/TauVertexedClusterDecorator.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..59bfe77f7235e9adf2fd9d6aea94c71ca3461122
--- /dev/null
+++ b/Reconstruction/tauRecTools/Root/TauVertexedClusterDecorator.cxx
@@ -0,0 +1,91 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "tauRecTools/TauVertexedClusterDecorator.h"
+
+#include "xAODCaloEvent/CaloVertexedTopoCluster.h"
+
+TauVertexedClusterDecorator::TauVertexedClusterDecorator(const std::string& name):
+  TauRecToolBase(name) {
+  declareProperty("SeedJet", m_seedJet = ""); 
+  declareProperty("VertexCorrection", m_doVertexCorrection = true);
+  declareProperty("JetVertexCorrection", m_doJetVertexCorrection = true);
+}
+
+
+
+StatusCode TauVertexedClusterDecorator::initialize() {  
+  
+  if (std::string(m_seedJet).find("LC") != std::string::npos) {
+    ATH_MSG_INFO("Set the cluster state to CALIBRATED");
+    m_clusterState = xAOD::CaloCluster::State::CALIBRATED; 
+  }
+  else if (std::string(m_seedJet).find("EM") != std::string::npos) {
+    ATH_MSG_INFO("Set the cluster state to UNCALIBRATED");
+    m_clusterState = xAOD::CaloCluster::State::UNCALIBRATED;
+  } 
+  else {
+    ATH_MSG_ERROR("Seed jet " << m_seedJet << " not supported !");
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+  
+const xAOD::Vertex* TauVertexedClusterDecorator::getJetVertex(const xAOD::Jet& jet) const {
+  
+  const xAOD::Vertex* jetVertex = nullptr;
+  
+  if (m_doJetVertexCorrection && !inTrigger()) {
+    bool isAvailable = jet.getAssociatedObject("OriginVertex", jetVertex);
+    if (!isAvailable) {
+      ATH_MSG_WARNING("OriginVertex not available !");
+      jetVertex = nullptr;
+    }
+  }
+
+  return jetVertex;
+}
+
+
+
+StatusCode TauVertexedClusterDecorator::execute(xAOD::TauJet& tau) const {
+  if (! tau.jetLink().isValid()) {
+    ATH_MSG_WARNING("Link to the seed jet is invalid");
+    return StatusCode::FAILURE;
+  }
+  
+  // Obtain the vertex to correct the cluster
+  const xAOD::Vertex* vertex = nullptr;
+  if (m_doVertexCorrection) {
+    if (tau.vertexLink().isValid()) {
+      vertex = tau.vertex();
+    }
+  }
+  else {
+    const xAOD::Jet* jetSeed = tau.jet();
+    vertex = getJetVertex(*jetSeed);
+  }
+
+  std::vector<const xAOD::IParticle*> particleList = tau.clusters();
+  
+  std::vector<xAOD::CaloVertexedTopoCluster> vertexedClusterList;
+  for (const xAOD::IParticle* particle : particleList) {
+    const xAOD::CaloCluster* cluster = static_cast<const xAOD::CaloCluster*>(particle);
+
+    if (vertex) {
+      vertexedClusterList.emplace_back(*cluster, m_clusterState, vertex->position());
+    }
+    else {
+      vertexedClusterList.emplace_back(*cluster, m_clusterState);
+    }
+  }
+
+  SG::AuxElement::Accessor<std::vector<xAOD::CaloVertexedTopoCluster>> vertexedClustersAcc("VertexedClusters");
+  vertexedClustersAcc(tau) = vertexedClusterList;
+
+  return StatusCode::SUCCESS;
+} 
diff --git a/Reconstruction/tauRecTools/src/components/tauRecTools_entries.cxx b/Reconstruction/tauRecTools/src/components/tauRecTools_entries.cxx
index 4bee4c3b26a0e96ca2bb0e674bcae5eed8734af8..2a2d8a9a02b06940e3bff744bd016a3360b958f8 100644
--- a/Reconstruction/tauRecTools/src/components/tauRecTools_entries.cxx
+++ b/Reconstruction/tauRecTools/src/components/tauRecTools_entries.cxx
@@ -29,6 +29,7 @@
 #include "tauRecTools/TauJetRNNEvaluator.h"
 #include "tauRecTools/TauDecayModeNNClassifier.h"
 #include "tauRecTools/TauVertexCorrection.h"
+#include "tauRecTools/TauVertexedClusterDecorator.h"
 
 #ifndef XAOD_ANALYSIS
 DECLARE_COMPONENT( JetSeedBuilder )
@@ -63,3 +64,4 @@ DECLARE_COMPONENT( TauIDVarCalculator )
 DECLARE_COMPONENT( TauJetRNNEvaluator )
 DECLARE_COMPONENT( TauDecayModeNNClassifier )
 DECLARE_COMPONENT( TauVertexCorrection )
+DECLARE_COMPONENT( TauVertexedClusterDecorator )
diff --git a/Reconstruction/tauRecTools/tauRecTools/TauVertexedClusterDecorator.h b/Reconstruction/tauRecTools/tauRecTools/TauVertexedClusterDecorator.h
new file mode 100644
index 0000000000000000000000000000000000000000..f48bfa3eac23fc2e98e7e372b658d6474f919efc
--- /dev/null
+++ b/Reconstruction/tauRecTools/tauRecTools/TauVertexedClusterDecorator.h
@@ -0,0 +1,49 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TAURECTOOLS_TAUVERTEXEDCLUSTERDECORATOR_H
+#define TAURECTOOLS_TAUVERTEXEDCLUSTERDECORATOR_H
+
+#include "tauRecTools/TauRecToolBase.h"
+
+#include "xAODJet/Jet.h"
+
+/** 
+ * @brief Decorate CaloVertexedTopoCluster to the tau candidate.
+ * 
+ * @author Xiaozhong Huang <xiaozhong.huang@cern.ch>
+ */
+
+class TauVertexedClusterDecorator : public TauRecToolBase {
+
+public:
+
+  ASG_TOOL_CLASS2(TauVertexedClusterDecorator, TauRecToolBase, ITauToolBase)
+  
+  TauVertexedClusterDecorator(const std::string& name);
+ 
+  virtual ~TauVertexedClusterDecorator() = default;
+
+  virtual StatusCode initialize() override;
+
+  virtual StatusCode execute(xAOD::TauJet& tau) const override;
+  
+private:
+  //* Get the vertex used in jet reconstruction */
+  const xAOD::Vertex* getJetVertex(const xAOD::Jet& jet) const;
+
+  /// Name of the seed jet
+  std::string m_seedJet;  
+  
+  /// Switch of the tau vertex correction
+  bool m_doVertexCorrection;
+  
+  /// Switch of the jet vertex correction
+  bool m_doJetVertexCorrection;
+
+  /// Calibration state of cluster
+  xAOD::CaloCluster::State m_clusterState; //!
+};
+
+#endif //TAURECTOOLS_TAUVERTEXEDCLUSTERDECORATOR_H