diff --git a/InnerDetector/InDetValidation/InDetPhysValMonitoring/share/dcube_IDPVMPlots_ACTS_R22.xml b/InnerDetector/InDetValidation/InDetPhysValMonitoring/share/dcube_IDPVMPlots_ACTS_R22.xml
index 37c3460386a86c0b66cb37760d4ab56f5bd99f8c..5ee5298e2853a26f55e75ebb577544a87e97b16c 100644
--- a/InnerDetector/InDetValidation/InDetPhysValMonitoring/share/dcube_IDPVMPlots_ACTS_R22.xml
+++ b/InnerDetector/InDetValidation/InDetPhysValMonitoring/share/dcube_IDPVMPlots_ACTS_R22.xml
@@ -68,6 +68,10 @@
 	<hist1D name="eta_endcap" plotopts="" tests="KS" type="TH1F"/>
 	<hist1D name="perp_barrel" plotopts="" tests="KS" type="TH1F"/>
 	<hist1D name="perp_endcap" plotopts="" tests="KS" type="TH1F"/>
+	<hist1D name="total_charge_barrel" plotopts="logy" tests="KS" type="TH1F"/>
+	<hist1D name="total_charge_endcap" plotopts="logy" tests="KS" type="TH1F"/>
+	<hist1D name="total_tot_barrel" plotopts="logy" tests="KS" type="TH1F"/>
+	<hist1D name="total_tot_endcap" plotopts="logy" tests="KS" type="TH1F"/>
 	<hist1D name="global_x_barrel" plotopts="" tests="KS" type="TH1F"/>
 	<hist1D name="global_x_endcap" plotopts="" tests="KS" type="TH1F"/>
 	<hist1D name="global_y_barrel" plotopts="" tests="KS" type="TH1F"/>
diff --git a/Tracking/Acts/ActsConfig/python/ActsClusterizationConfig.py b/Tracking/Acts/ActsConfig/python/ActsClusterizationConfig.py
index 60ea6903d20fcd252176b91c705acde07e327b25..4083a585300d0c3732e522ae0943691f1412f351 100644
--- a/Tracking/Acts/ActsConfig/python/ActsClusterizationConfig.py
+++ b/Tracking/Acts/ActsConfig/python/ActsClusterizationConfig.py
@@ -8,12 +8,20 @@ def ActsPixelClusteringToolCfg(flags,
                                **kwargs) -> ComponentAccumulator:
     acc = ComponentAccumulator()
 
+    from PixelConditionsAlgorithms.ITkPixelConditionsConfig import ITkPixelChargeCalibCondAlgCfg, ITkPixelOfflineCalibCondAlgCfg
+    acc.merge(ITkPixelChargeCalibCondAlgCfg(flags))
+    acc.merge(ITkPixelOfflineCalibCondAlgCfg(flags))
+
+    from PixelReadoutGeometry.PixelReadoutGeometryConfig import ITkPixelReadoutManagerCfg
+    acc.merge(ITkPixelReadoutManagerCfg(flags))
+    
     if 'PixelRDOTool' not in kwargs:
         from InDetConfig.SiClusterizationToolConfig import ITkPixelRDOToolCfg
         kwargs.setdefault("PixelRDOTool", acc.popToolsAndMerge(ITkPixelRDOToolCfg(flags)))
-    if 'ClusterMakerTool' not in kwargs:
-        from InDetConfig.SiClusterizationToolConfig import ITkClusterMakerToolCfg
-        kwargs.setdefault("ClusterMakerTool", acc.popToolsAndMerge(ITkClusterMakerToolCfg(flags)))
+
+    if "PixelLorentzAngleTool" not in kwargs:
+        from SiLorentzAngleTool.ITkPixelLorentzAngleConfig import ITkPixelLorentzAngleToolCfg
+        kwargs.setdefault("PixelLorentzAngleTool", acc.popToolsAndMerge( ITkPixelLorentzAngleToolCfg(flags) ))
 
     kwargs.setdefault("PixelOfflineCalibData", "")
 
diff --git a/Tracking/Acts/ActsDataPreparation/src/PixelClusteringTool.cxx b/Tracking/Acts/ActsDataPreparation/src/PixelClusteringTool.cxx
index d15b475b83b7b47e8028727b666c3f561f3a7be4..bb768f93c61cf06a98c44d19e2b77968efaab4a2 100644
--- a/Tracking/Acts/ActsDataPreparation/src/PixelClusteringTool.cxx
+++ b/Tracking/Acts/ActsDataPreparation/src/PixelClusteringTool.cxx
@@ -10,125 +10,262 @@
 #include <xAODInDetMeasurement/PixelCluster.h>
 #include <xAODInDetMeasurement/PixelClusterContainer.h>
 #include <xAODInDetMeasurement/PixelClusterAuxContainer.h>
+#include <xAODInDetMeasurement/Utilities.h>
 
 #include <unordered_set>
 
+using CLHEP::micrometer;
+
 namespace ActsTrk {
+static inline double square(const double x){
+  return x*x;
+}  
+constexpr double ONE_TWELFTH = 1./12.;  
   
-void clusterAddCell(PixelClusteringTool::Cluster& cl, const PixelClusteringTool::Cell& cell)
+void clusterAddCell(PixelClusteringTool::Cluster& cl,
+		    const PixelClusteringTool::Cell& cell)
 {
-    cl.ids.push_back(cell.ID);
-    cl.tots.push_back(cell.TOT);
-    if (cell.LVL1 < cl.lvl1min)
-	cl.lvl1min = cell.LVL1;
+  cl.ids.push_back(cell.ID);
+  cl.tots.push_back(cell.TOT);
+  if (cell.LVL1 < cl.lvl1min)
+    cl.lvl1min = cell.LVL1;
 }
 
 StatusCode PixelClusteringTool::initialize()
 {
-    ATH_CHECK(m_pixelRDOTool.retrieve());
-
-    ATH_CHECK(m_clusterMakerTool.retrieve());
-    ATH_CHECK(m_chargeDataKey.initialize(SG::AllowEmpty));
-    ATH_CHECK(m_offlineCalibDataKey.initialize(SG::AllowEmpty));
-
-    ATH_MSG_DEBUG("Acts::PixelClusteringTool successfully initialized");
-    return StatusCode::SUCCESS;
+  ATH_MSG_DEBUG("Initializing " << name() << " ...");
+  ATH_CHECK(m_pixelRDOTool.retrieve());
+  ATH_CHECK(m_pixelLorentzAngleTool.retrieve());
+  if (not m_chargeDataKey.empty()) ATH_CHECK(m_pixelReadout.retrieve());
+  
+  ATH_CHECK(m_chargeDataKey.initialize(not m_chargeDataKey.empty()));
+  ATH_CHECK(m_offlineCalibDataKey.initialize(not m_offlineCalibDataKey.empty() and
+					     m_errorStrategy == 2));
+  
+  ATH_MSG_DEBUG(name() << " successfully initialized");
+  return StatusCode::SUCCESS;
 }
 
 PixelClusteringTool::PixelClusteringTool(
     const std::string& type, const std::string& name, const IInterface* parent)
     : base_class(type,name,parent)
-{
-}
+{}
 
 StatusCode
-PixelClusteringTool::makeCluster(const PixelClusteringTool::Cluster &cluster,
+PixelClusteringTool::makeCluster(const EventContext& ctx,
+				 const PixelClusteringTool::Cluster &cluster,
 				 const PixelID& pixelID,
 				 const InDetDD::SiDetectorElement* element,
 				 xAOD::PixelCluster& xaodcluster) const
-{
-    const InDetDD::PixelModuleDesign& design = 
-	dynamic_cast<const InDetDD::PixelModuleDesign&>(element->design());
-
-    InDetDD::SiLocalPosition pos_acc(0,0);
-    int tot_acc = 0;
-
-    int colmax = std::numeric_limits<int>::min();
-    int rowmax = std::numeric_limits<int>::min();
-    int colmin = std::numeric_limits<int>::max();
-    int rowmin = std::numeric_limits<int>::max();
-
-    bool hasGanged = false;
-
-    for (size_t i = 0; i < cluster.ids.size(); i++) {
-	Identifier id = cluster.ids.at(i);
-	hasGanged = hasGanged ||
-		    m_pixelRDOTool->isGanged(id, element).has_value();
-
-	const int row = pixelID.phi_index(id);
-	if (row > rowmax)
-	    rowmax = row;
-	if (row < rowmin)
-	    rowmin = row;
-
-	const int col = pixelID.eta_index(id);
-	if (col > colmax)
-	    colmax = col;
-	if (col < colmin)
-	    colmin = col;
-
-	InDetDD::SiCellId si_cell = element->cellIdFromIdentifier(id);
-	InDetDD::SiLocalPosition pos = design.localPositionOfCell(si_cell);
-	int tot = cluster.tots.at(i);
-	pos_acc += tot * pos;
-	tot_acc += tot;
-    }
-
-    if (tot_acc > 0)
-	pos_acc /= tot_acc;
+{ 
+  const PixelChargeCalibCondData *calibData = nullptr;
+  if (not m_chargeDataKey.empty()) {
+    SG::ReadCondHandle<PixelChargeCalibCondData> calibDataHandle(m_chargeDataKey, ctx);
+    calibData = calibDataHandle.cptr();
+  }
+  
+  const PixelCalib::PixelOfflineCalibData *offlineCalibData = nullptr;
+  if (not m_offlineCalibDataKey.empty() and m_errorStrategy == 2) {
+    SG::ReadCondHandle<PixelCalib::PixelOfflineCalibData> offlineCalibDataHandle(m_offlineCalibDataKey, ctx);
+    offlineCalibData = offlineCalibDataHandle.cptr();
+  }
 
-    const int colWidth = colmax - colmin + 1;
-    const int rowWidth = rowmax - rowmin + 1;
-    double etaWidth = design.widthFromColumnRange(colmin, colmax);
-    double phiWidth = design.widthFromRowRange(rowmin, rowmax);
-    InDet::SiWidth siWidth(Amg::Vector2D(rowWidth,colWidth), Amg::Vector2D(phiWidth,etaWidth));
+  const InDetDD::PixelModuleDesign& design = 
+	dynamic_cast<const InDetDD::PixelModuleDesign&>(element->design());
 
+  InDetDD::SiLocalPosition pos_acc(0,0);
+  int tot_acc = 0;
 
-    const PixelChargeCalibCondData *calibData = nullptr;
-    if (!m_chargeDataKey.empty()) {
-      SG::ReadCondHandle<PixelChargeCalibCondData> calibDataHandle(m_chargeDataKey);
-      calibData = *calibDataHandle;
+  std::vector<float> chargeList;
+  if (calibData) chargeList.reserve(cluster.ids.size());
+  
+  int colmax = std::numeric_limits<int>::min();
+  int rowmax = std::numeric_limits<int>::min();
+  int colmin = std::numeric_limits<int>::max();
+  int rowmin = std::numeric_limits<int>::max();
+
+  float qRowMin = 0.f;
+  float qRowMax = 0.f;
+  float qColMin = 0.f;
+  float qColMax = 0.f;
+  
+  bool hasGanged = false;
+  
+  for (size_t i = 0; i < cluster.ids.size(); i++) {
+    Identifier id = cluster.ids.at(i);
+    hasGanged = hasGanged ||
+      m_pixelRDOTool->isGanged(id, element).has_value();
+
+    int tot = cluster.tots.at(i);
+    float charge = tot;
+
+    if (calibData) {
+      Identifier moduleID = pixelID.wafer_id(id);
+      IdentifierHash moduleHash = pixelID.wafer_hash(moduleID);
+      charge = calibData->getCharge(m_pixelReadout->getDiodeType(id),
+				    moduleHash,
+				    m_pixelReadout->getFE(id, moduleID),
+				    tot);
+      // These numbers are taken from the Cluster Maker Tool
+      if (moduleHash < 12 or moduleHash > 2035) {
+        charge = tot/8.0*(8000.0-1200.0)+1200.0;
+      }
+      chargeList.push_back(charge);
     }
-
-    const PixelCalib::PixelOfflineCalibData *offlineCalibData = nullptr;
-    if (!m_offlineCalibDataKey.empty()) {
-      SG::ReadCondHandle<PixelCalib::PixelOfflineCalibData> offlineCalibDataHandle(m_offlineCalibDataKey);
-      offlineCalibData = *offlineCalibDataHandle;
+    
+    const int row = pixelID.phi_index(id);
+    if (row > rowmax) {
+      rowmax = row;
+      qRowMax =	charge;
+    } else if (row == rowmax) {
+      qRowMax += charge; 
     }
+    
+    if (row < rowmin) {  
+      rowmin = row;
+      qRowMin = charge;
+    } else if (row == rowmin) {
+      qRowMin += charge;
+    } 
+       
+    const int col = pixelID.eta_index(id);
+    if (col > colmax) {
+      colmax = col;
+      qColMax =	charge;
+    } else if (col == colmax) {
+      qColMax += charge;
+    }     
+
+    if (col < colmin) {
+      colmin = col;
+      qColMin = charge;
+    } else if (col == colmin) {
+      qColMin += charge;
+    } 
+    
+    InDetDD::SiCellId si_cell = element->cellIdFromIdentifier(id);
+    InDetDD::SiLocalPosition pos = design.localPositionOfCell(si_cell);
+    pos_acc += tot * pos;
+    tot_acc += tot;
+  }
+  
+  if (tot_acc > 0)
+    pos_acc /= tot_acc;
 
+  // Compute omega for charge interpolation correction (if required)
+  // Two pixels may have charge=0 (very rarely, hopefully)
+  float omegax = -1.f;
+  float omegay = -1.f;
+  if(qRowMin + qRowMax > 0) omegax = qRowMax/(qRowMin + qRowMax);
+  if(qColMin + qColMax > 0) omegay = qColMax/(qColMin + qColMax);
 
-
-    // N.B. the cluster is automatically added to the container
-    xAOD::PixelCluster *cl =
-	m_clusterMakerTool->xAODpixelCluster(
-	    xaodcluster,
-	    pos_acc,
-	    cluster.ids,
-	    cluster.lvl1min,
-	    cluster.tots,
-	    siWidth,
-	    element,
-	    hasGanged,
-	    m_errorStrategy,
-	    pixelID,
-      false,
-      0.0,
-      0.0,
-      calibData,
-      offlineCalibData
-	    );
-
-    return (cl != nullptr) ? StatusCode::SUCCESS : StatusCode::FAILURE;
+  
+  const int colWidth = colmax - colmin + 1;
+  const int rowWidth = rowmax - rowmin + 1;
+  double etaWidth = design.widthFromColumnRange(colmin, colmax);
+  double phiWidth = design.widthFromRowRange(rowmin, rowmax);
+  InDet::SiWidth siWidth(Amg::Vector2D(rowWidth,colWidth), Amg::Vector2D(phiWidth,etaWidth));
+
+  // ask for Lorentz correction, get global position
+  double shift = m_pixelLorentzAngleTool->getLorentzShift(element->identifyHash());
+  const Amg::Vector2D localPos = pos_acc;
+  Amg::Vector2D locpos(localPos[Trk::locX]+shift, localPos[Trk::locY]);
+  // find global position of element
+  const Amg::Transform3D& T = element->surface().transform();
+  double Ax[3] = {T(0,0),T(1,0),T(2,0)};
+  double Ay[3] = {T(0,1),T(1,1),T(2,1)};
+  double R [3] = {T(0,3),T(1,3),T(2,3)};
+  
+  const Amg::Vector2D&    M = locpos;
+  Amg::Vector3D globalPos(M[0]*Ax[0]+M[1]*Ay[0]+R[0],M[0]*Ax[1]+M[1]*Ay[1]+R[1],M[0]*Ax[2]+M[1]*Ay[2]+R[2]);
+
+  // Compute error matrix
+  auto errorMatrix = Amg::MatrixX(2,2);
+  errorMatrix.setIdentity();
+
+  const double eta = std::abs(globalPos.eta());
+  const Amg::Vector2D& colRow = siWidth.colRow();
+  const double zPitch = siWidth.z()/colRow.y();
+  const Identifier clusterID = Identifier(); // ???
+  const int layer = pixelID.layer_disk(clusterID);
+  const int phimod = pixelID.phi_module(clusterID);
+  
+  switch (m_errorStrategy) {
+  case 0:
+    errorMatrix.fillSymmetric(0,0, square(siWidth.phiR()) * ONE_TWELFTH);
+    errorMatrix.fillSymmetric(1,1, square(siWidth.z()) * ONE_TWELFTH);
+    break;
+    
+  case 2:
+    // use parameterization only if the cluster does not
+    // contain long pixels or ganged pixels
+    // Also require calibration service is available....
+    if (not hasGanged and
+	zPitch > 399 * micrometer and
+	zPitch < 401 * micrometer) {
+      if (offlineCalibData) {
+        if (element->isBarrel()) {
+          int ibin = offlineCalibData->getPixelClusterErrorData()->getBarrelBin(eta,
+										static_cast<int>(colRow.y()),
+										static_cast<int>(colRow.x()));
+          double phiError = offlineCalibData->getPixelClusterErrorData()->getPixelBarrelPhiError(ibin);
+          double etaError = offlineCalibData->getPixelClusterErrorData()->getPixelBarrelEtaError(ibin);
+          errorMatrix.fillSymmetric(0,0, pow(phiError,2));
+          errorMatrix.fillSymmetric(1,1, pow(etaError,2));
+        }
+        else {
+          int ibin = offlineCalibData->getPixelClusterErrorData()->getEndcapBin(static_cast<int>(colRow.y()),
+										static_cast<int>(colRow.x()));
+          double phiError = offlineCalibData->getPixelClusterErrorData()->getPixelEndcapPhiError(ibin);
+          double etaError = offlineCalibData->getPixelClusterErrorData()->getPixelEndcapRError(ibin);
+          errorMatrix.fillSymmetric(0,0, square(phiError));
+          errorMatrix.fillSymmetric(1,1, square(etaError));
+        }
+      }
+    } else {
+      // cluster with ganged and/or long pixels
+      errorMatrix.fillSymmetric(0,0, square(siWidth.phiR()/colRow.x()) * ONE_TWELFTH);
+      errorMatrix.fillSymmetric(1,1, square(zPitch) * ONE_TWELFTH);
+    }
+    break;
+   
+  case 10:
+    errorMatrix.fillSymmetric(0,0, square( getPixelCTBPhiError(layer, phimod, static_cast<int>(colRow.x())) ));
+    errorMatrix.fillSymmetric(1,1, square(siWidth.z()/colRow.y()) * ONE_TWELFTH);
+    break;
+    
+  case 1:
+  default:
+    errorMatrix.fillSymmetric(0,0, square(siWidth.phiR()/colRow.x()) * ONE_TWELFTH);
+    errorMatrix.fillSymmetric(1,1, square(siWidth.z()/colRow.y()) * ONE_TWELFTH);
+    break;
+  }
+
+
+  // Actually create the cluster (i.e. fill the values)
+  IdentifierHash idHash = element->identifyHash();
+
+  Eigen::Matrix<float,2,1> localPosition(locpos.x(), locpos.y());
+  Eigen::Matrix<float,2,2> localCovariance = Eigen::Matrix<float,2,2>::Zero();
+  localCovariance(0, 0) = errorMatrix(0, 0);
+  localCovariance(1, 1) = errorMatrix(1, 1);
+  
+  xaodcluster.setMeasurement<2>(idHash, localPosition, localCovariance);
+  xaodcluster.setRDOlist(cluster.ids);
+  xaodcluster.globalPosition() = globalPos.cast<float>();
+  xaodcluster.setToTlist(cluster.tots);
+  xaodcluster.setTotalToT( xAOD::xAODInDetMeasurement::Utilities::computeTotalToT(cluster.tots) );
+  xaodcluster.setChargelist(chargeList);
+  xaodcluster.setTotalCharge( xAOD::xAODInDetMeasurement::Utilities::computeTotalCharge(chargeList) );
+  xaodcluster.setLVL1A(cluster.lvl1min);
+  xaodcluster.setChannelsInPhiEta(siWidth.colRow()[0],
+				  siWidth.colRow()[1]);
+  xaodcluster.setWidthInEta(static_cast<float>(siWidth.widthPhiRZ()[1]));
+  xaodcluster.setOmegas(omegax, omegay);
+  xaodcluster.setIsSplit(false);
+  xaodcluster.setSplitProbabilities(0.0, 0.0);
+    
+  return StatusCode::SUCCESS;
 }
 
 
@@ -159,10 +296,36 @@ PixelClusteringTool::clusterize(const RawDataCollection& RDOs,
 
     for (std::size_t i(0); i<clusters.size(); ++i) {
       const Cluster& cluster = clusters[i];
-      ATH_CHECK(makeCluster(cluster, pixelID, element, *container[previousSizeContainer+i]));
+      ATH_CHECK(makeCluster(ctx, cluster, pixelID, element, *container[previousSizeContainer+i]));
     }
 
     return StatusCode::SUCCESS;
 }
 
+// CTB parameterization, B field off
+double PixelClusteringTool::getPixelCTBPhiError(int layer, int phi,
+						int phiClusterSize) const
+{
+  double sigmaL0Phi1[3] = { 8.2*micrometer,  9.7*micrometer, 14.6*micrometer};
+  double sigmaL1Phi1[3] = {14.6*micrometer,  9.3*micrometer, 14.6*micrometer};
+  double sigmaL2Phi1[3] = {14.6*micrometer,  8.6*micrometer, 14.6*micrometer};
+  double sigmaL0Phi0[3] = {14.6*micrometer, 13.4*micrometer, 13.0*micrometer};
+  double sigmaL1Phi0[3] = {14.6*micrometer,  8.5*micrometer, 11.0*micrometer};
+  double sigmaL2Phi0[3] = {14.6*micrometer, 11.6*micrometer,  9.3*micrometer};
+  
+  if(phiClusterSize > 3) return 14.6*micrometer;
+  
+  if(layer == 0 && phi == 0) return sigmaL0Phi0[phiClusterSize-1];
+  if(layer == 1 && phi == 0) return sigmaL1Phi0[phiClusterSize-1];
+  if(layer == 2 && phi == 0) return sigmaL2Phi0[phiClusterSize-1];
+  if(layer == 0 && phi == 1) return sigmaL0Phi1[phiClusterSize-1];
+  if(layer == 1 && phi == 1) return sigmaL1Phi1[phiClusterSize-1];
+  if(layer == 2 && phi == 1) return sigmaL2Phi1[phiClusterSize-1];
+  
+  // shouldn't really happen...
+  ATH_MSG_WARNING("Unexpected layer and phi numbers: layer = "
+		  << layer << " and phi = " << phi);
+  return 14.6*micrometer;  
+}
+  
 } // namespace ActsTrk
diff --git a/Tracking/Acts/ActsDataPreparation/src/PixelClusteringTool.h b/Tracking/Acts/ActsDataPreparation/src/PixelClusteringTool.h
index c82d474119e8c9fc406e294a75e15d5160c3aae4..e258be29094159ec6d8cd8af47263c790f1d98e0 100644
--- a/Tracking/Acts/ActsDataPreparation/src/PixelClusteringTool.h
+++ b/Tracking/Acts/ActsDataPreparation/src/PixelClusteringTool.h
@@ -10,9 +10,12 @@
 #include "InDetIdentifier/PixelID.h"
 #include "InDetRawData/InDetRawDataCollection.h"
 #include "InDetRawData/PixelRDORawData.h"
-#include "SiClusterizationTool/ClusterMakerTool.h"
 #include "SiClusterizationTool/PixelRDOTool.h"
 #include "xAODInDetMeasurement/PixelClusterContainer.h"
+#include "InDetCondTools/ISiLorentzAngleTool.h"
+#include "PixelReadoutGeometry/IPixelReadoutManager.h"
+#include "PixelConditionsData/PixelChargeCalibCondData.h"
+#include "PixelConditionsData/PixelOfflineCalibData.h"
 
 namespace InDet {
 
@@ -73,29 +76,31 @@ public:
 
 private:
     // N.B. the cluster is added to the container
-    StatusCode makeCluster(const PixelClusteringTool::Cluster &cluster,
-			   const PixelID& pixelID,
-			   const InDetDD::SiDetectorElement* element,
-			   xAOD::PixelCluster& container) const;
-
-
-    ToolHandle< InDet::PixelRDOTool > m_pixelRDOTool
-      {this, "PixelRDOTool", "InDet::PixelRDOTool"};
-    ToolHandle< InDet::ClusterMakerTool > m_clusterMakerTool
-      {this, "ClusterMakerTool", "InDet::ClusterMakerTool"};
-
-    Gaudi::Property<bool> m_addCorners{this, "AddCorners", true};
-    Gaudi::Property<int> m_errorStrategy{this, "ErrorStrategy", 1};
-
-    SG::ReadCondHandleKey<PixelChargeCalibCondData> m_chargeDataKey
-      {this, "PixelChargeCalibCondData", "ITkPixelChargeCalibCondData",
-       "Pixel charge calibration data"};
-
-    SG::ReadCondHandleKey<PixelCalib::PixelOfflineCalibData> m_offlineCalibDataKey
-      {this, "PixelOfflineCalibData", "ITkPixelOfflineCalibData",
-       "Pixel offline calibration data"};
+  StatusCode makeCluster(const EventContext& ctx,
+			 const PixelClusteringTool::Cluster &cluster,
+			 const PixelID& pixelID,
+			 const InDetDD::SiDetectorElement* element,
+			 xAOD::PixelCluster& container) const;
+
+  double getPixelCTBPhiError(int layer, int phi,
+			     int phiClusterSize) const;
+  
+private:  
+  ServiceHandle< InDetDD::IPixelReadoutManager > m_pixelReadout {this, "PixelReadoutManager", "ITkPixelReadoutManager",
+      "Pixel readout manager" };
+  
+  ToolHandle< InDet::PixelRDOTool > m_pixelRDOTool {this, "PixelRDOTool", "", "The Pixel RDO tool"};
+  ToolHandle< ISiLorentzAngleTool > m_pixelLorentzAngleTool {this, "PixelLorentzAngleTool", "", "Tool to retreive Lorentz angle of Pixel"};
+  
+  SG::ReadCondHandleKey<PixelChargeCalibCondData> m_chargeDataKey {this, "PixelChargeCalibCondData", "ITkPixelChargeCalibCondData",
+    "Pixel charge calibration data"};
+  SG::ReadCondHandleKey<PixelCalib::PixelOfflineCalibData> m_offlineCalibDataKey {this, "PixelOfflineCalibData", "ITkPixelOfflineCalibData",
+    "Pixel offline calibration data"};
+  
+  Gaudi::Property<bool> m_addCorners {this, "AddCorners", true};
+  Gaudi::Property<int> m_errorStrategy {this, "ErrorStrategy", 1};
 };
-
+  
 } // namespace ActsTrk 
 
 #endif // ACTS_PIXEL_CLUSTERING_TOOL_H
diff --git a/Tracking/Acts/ActsMonitoring/src/PixelClusterValidationPlots.cxx b/Tracking/Acts/ActsMonitoring/src/PixelClusterValidationPlots.cxx
index 903631e36afc74702025d1e064619080b58754ff..deab19ebe9a934fd937b98ddecf3d72be1915a39 100644
--- a/Tracking/Acts/ActsMonitoring/src/PixelClusterValidationPlots.cxx
+++ b/Tracking/Acts/ActsMonitoring/src/PixelClusterValidationPlots.cxx
@@ -33,6 +33,12 @@ namespace ActsTrk {
     m_perp_barrel = Book1D("perp_barrel", "PixelCluster_perp_barrel;r [mm];Entries;", 100, 0, 320, false);
     m_perp_endcap = Book1D("perp_endcap", "PixelCluster_perp_endcap;r [mm];Entries;", 100, 0, 320, false);
 
+    m_total_charge_barrel = Book1D("total_charge_barrel", "PixelCluster_totalCharge_barrel;charge;Entries;", 50, 0, 300000, false);
+    m_total_charge_endcap = Book1D("total_charge_endcap", "PixelCluster_totalCharge_endcap;charge;Entries;", 50, 0, 300000, false);
+
+    m_total_tot_barrel = Book1D("total_tot_barrel", "PixelCluster_totalTot_barrel;charge;Entries;", 50, 0, 5000, false);
+    m_total_tot_endcap = Book1D("total_tot_endcap", "PixelCluster_totalTot_endcap;charge;Entries;", 50, 0, 5000, false);
+
     m_global_x_barrel = Book1D("global_x_barrel", "PixelCluster_global_x_barrel;Global x [mm];Entries;", 64, -350, 350, false);
     m_global_x_endcap = Book1D("global_x_endcap", "PixelCluster_global_x_endcap;Global x [mm];Entries;", 64, -350, 350, false);
 
@@ -98,6 +104,9 @@ namespace ActsTrk {
       m_eta_barrel->Fill(globalPosition.eta(), beamSpotWeight);
       m_perp_barrel->Fill(globalPosition.perp(), beamSpotWeight);
 
+      m_total_charge_barrel->Fill(cluster->totalCharge(), beamSpotWeight);
+      m_total_tot_barrel->Fill(cluster->totalToT(), beamSpotWeight);
+    
       m_global_x_barrel->Fill(globalPos(0, 0), beamSpotWeight);
       m_global_y_barrel->Fill(globalPos(1, 0), beamSpotWeight);
       m_global_z_barrel->Fill(globalPos(2, 0), beamSpotWeight);
@@ -125,6 +134,9 @@ namespace ActsTrk {
       m_eta_endcap->Fill(globalPosition.eta(), beamSpotWeight);
       m_perp_endcap->Fill(globalPosition.perp(), beamSpotWeight);
 
+      m_total_charge_endcap->Fill(cluster->totalCharge(), beamSpotWeight);
+      m_total_tot_endcap->Fill(cluster->totalToT(), beamSpotWeight);
+       
       m_global_x_endcap->Fill(globalPos(0, 0), beamSpotWeight);
       m_global_y_endcap->Fill(globalPos(1, 0), beamSpotWeight);
       m_global_z_endcap->Fill(globalPos(2, 0), beamSpotWeight);
diff --git a/Tracking/Acts/ActsMonitoring/src/PixelClusterValidationPlots.h b/Tracking/Acts/ActsMonitoring/src/PixelClusterValidationPlots.h
index dbc6ffb84910f45422db8728d9eaa65bd330ca21..da68bceeab1fd0cda61afe3aec4085c7bf152e51 100644
--- a/Tracking/Acts/ActsMonitoring/src/PixelClusterValidationPlots.h
+++ b/Tracking/Acts/ActsMonitoring/src/PixelClusterValidationPlots.h
@@ -45,6 +45,12 @@ namespace ActsTrk {
     TH1* m_perp_barrel {};
     TH1* m_perp_endcap {};
 
+    TH1* m_total_charge_barrel {};
+    TH1* m_total_charge_endcap {};
+
+    TH1* m_total_tot_barrel {};
+    TH1* m_total_tot_endcap {};
+
     TH1* m_global_x_barrel {};
     TH1* m_global_x_endcap {};