diff --git a/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/ChargeCalibParameters.h b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/ChargeCalibParameters.h
new file mode 100644
index 0000000000000000000000000000000000000000..bab279bcf10b5c1a745b10b4ba2c178141671749
--- /dev/null
+++ b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/ChargeCalibParameters.h
@@ -0,0 +1,63 @@
+/*
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file PixelChargeCalibParameters.h
+ * @author Shaun Roe
+ * @date June, 2023
+ * @brief Structs for holding charge calibration parameterisation and data
+ */
+ 
+namespace PixelChargeCalib{
+  
+  struct LegacyFitParameters{
+    float A = 0.f;
+    float E = 0.f;
+    float C = 0.f;
+    ///Return Time-over-threshold given charge Q
+    float ToT(float Q) const{
+      if ((C + Q) != 0.0) {
+        return A * (E + Q) / (C + Q);
+      }
+      return 0.f;
+    }
+    //return Charge, given time-over-Threshold
+    float Q(float tot) const{
+      if (std::fabs(A) != 0.0 && std::fabs(tot / A - 1.0) != 0.0) {
+        return  (C * tot / A - E) / (1.0 - tot / A);
+      }
+      return 0.f;
+    }
+    
+  };
+ 
+  struct LinearFitParameters{
+    float F = 0.f;
+    float G = 0.f;
+    float ToT(float Q) const{
+      if (F != 0.0f){
+        return (Q - G) / F;
+      }
+      return 0.f;
+    }
+    float Q(float tot) const {
+     return  F * tot + G;
+    }
+  };
+ 
+  struct Thresholds{
+    int value = 0;
+    int sigma = 0;
+    int noise = 0;
+    int inTimeValue = 0;
+  };
+  
+  struct Resolutions{
+    float res1 = 0.f;
+    float res2 = 0.f;
+    float total(float Q) const {
+      return res1 + res2 * Q;
+    }
+  };
+}
diff --git a/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelChargeCalibCondData.h b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelChargeCalibCondData.h
index bf5d8052ccbfcb447d5a1c5135d3988aba67bee5..2787b1ae20d365ed36faa036b91a3a5fcd28e924 100644
--- a/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelChargeCalibCondData.h
+++ b/InnerDetector/InDetConditions/PixelConditionsData/PixelConditionsData/PixelChargeCalibCondData.h
@@ -11,11 +11,17 @@
 #include <map>
 #include <vector>
 #include <array>
+namespace PixelChargeCalib{
+  class LegacyFitParameters;
+  class LinearFitParameters;
+  class Thresholds;
+  class Resolutions;
+}
 
 class PixelChargeCalibCondData
 {
   public:
-    PixelChargeCalibCondData();
+    PixelChargeCalibCondData() = default;
     PixelChargeCalibCondData(std::size_t max_module_hash);
 
     static constexpr size_t IBLCalibrationSize{16};
@@ -31,28 +37,51 @@ class PixelChargeCalibCondData
     };
 
     // Normal pixel
+    void 
+    setThresholds(InDetDD::PixelDiodeType type, unsigned int moduleHash, const std::vector<PixelChargeCalib::Thresholds> & thresholds);
+    //
     void setAnalogThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value);
     void setAnalogThresholdSigma(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value);
     void setAnalogThresholdNoise(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value);
     void setInTimeThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value);
-
+    //
+    //
+    void setLegacyFitParameters(InDetDD::PixelDiodeType type, unsigned int moduleHash, const std::vector<PixelChargeCalib::LegacyFitParameters> &parameters);
+    //
     void setQ2TotA(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value);
     void setQ2TotE(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value);
     void setQ2TotC(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value);
+    //
+    //
+    void setLinearFitParameters(InDetDD::PixelDiodeType type, unsigned int moduleHash, const std::vector<PixelChargeCalib::LinearFitParameters> &parameters);
+    //
     void setQ2TotF(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value);
     void setQ2TotG(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value);
-
+    //
+    //
+    void setTotResolutions(unsigned int moduleHash, const std::vector<PixelChargeCalib::Resolutions> &value);
+    //
     void setTotRes1(unsigned int moduleHash, std::vector<float> &&value);
     void setTotRes2(unsigned int moduleHash, std::vector<float> &&value);
-
+    //
+    //
+    PixelChargeCalib::Thresholds getThresholds(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
+    //
     int getAnalogThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
     int getAnalogThresholdSigma(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
     int getAnalogThresholdNoise(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
     int getInTimeThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
-
+    //
+    //
+    PixelChargeCalib::LegacyFitParameters getLegacyFitParameters(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
+    //
     float getQ2TotA(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
     float getQ2TotE(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
     float getQ2TotC(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
+    //
+    //
+    PixelChargeCalib::LinearFitParameters getLinearFitParameters(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
+    //
     float getQ2TotF(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
     float getQ2TotG(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const;
 
@@ -72,8 +101,7 @@ class PixelChargeCalibCondData
   private:
     std::size_t m_maxModuleHash = 0;
 
-    constexpr static std::size_t s_NPixelDiods = 4;
-    static unsigned short diodeIndex(InDetDD::PixelDiodeType type) { return static_cast<unsigned int>(type); }
+    constexpr static std::size_t s_NPixelDiodes = enum2uint(InDetDD::PixelDiodeType::N_DIODETYPES);
 
    template <typename T>
     static void resize(std::size_t idx, std::size_t max_size, T &container)  { if (idx >= container.size()) { container.resize(max_size); } }
@@ -85,14 +113,14 @@ class PixelChargeCalibCondData
 
     template <typename T, typename T_Value>
     static void setValue(std::size_t max_size, T &container, InDetDD::PixelDiodeType type, unsigned int moduleHash, T_Value &&value)  {
-       resize( moduleHash,max_size, container.at(diodeIndex(type)));
-       container.at(diodeIndex(type)).at(moduleHash) = std::move(value);
+       resize( moduleHash,max_size, container.at(enum2uint(type)));
+       container.at(enum2uint(type)).at(moduleHash) = std::move(value);
     }
 
     using chipThreshold = std::vector<std::vector<int>>;
     using chipCharge = std::vector<std::vector<float>>;
-    using chipThresholdMap = std::array<chipThreshold, s_NPixelDiods>;
-    using chipChargeMap = std::array<chipCharge, s_NPixelDiods>;
+    using chipThresholdMap = std::array<chipThreshold, s_NPixelDiodes>;
+    using chipChargeMap = std::array<chipCharge, s_NPixelDiodes>;
 
     chipThresholdMap m_analogThreshold;
     chipThresholdMap m_analogThresholdSigma;
diff --git a/InnerDetector/InDetConditions/PixelConditionsData/src/PixelChargeCalibCondData.cxx b/InnerDetector/InDetConditions/PixelConditionsData/src/PixelChargeCalibCondData.cxx
index e282ccf07e82202e4dabd77cf699ae769eb2649c..9eacf13f48c3813ac3fcef0b1f3e83e65c09bd49 100644
--- a/InnerDetector/InDetConditions/PixelConditionsData/src/PixelChargeCalibCondData.cxx
+++ b/InnerDetector/InDetConditions/PixelConditionsData/src/PixelChargeCalibCondData.cxx
@@ -3,293 +3,380 @@
 */
 
 #include "PixelConditionsData/PixelChargeCalibCondData.h"
-#include <cfloat>
+#include "PixelConditionsData/ChargeCalibParameters.h"
+#include <stdexcept>
+#include <sstream>
+#include <cfloat> //for FLT_MAX
 
+using namespace PixelChargeCalib;
+using InDetDD::enum2uint; //in PixelReadoutDefinitions.h; will use ADL anyway,but make it explicit
 
-PixelChargeCalibCondData::PixelChargeCalibCondData()
-{
-   static_assert(static_cast<std::size_t>(InDetDD::PixelDiodeType::NORMAL) < s_NPixelDiods);
-   static_assert(static_cast<std::size_t>(InDetDD::PixelDiodeType::LONG)   < s_NPixelDiods);
-   static_assert(static_cast<std::size_t>(InDetDD::PixelDiodeType::GANGED) < s_NPixelDiods);
-   static_assert(static_cast<std::size_t>(InDetDD::PixelDiodeType::LARGE)  < s_NPixelDiods);
+namespace{
+  const std::out_of_range 
+  generateError(const char * functionName, InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE){
+    std::stringstream error;
+    error << "PixelChargeCalibCondData::"<< functionName << "("<<enum2uint(type)<< ", " << moduleHash << ", " << FE << "): out of bounds";
+    return std::out_of_range(error.str());
+  }
+  const std::out_of_range 
+  generateError(const char * functionName, unsigned int moduleHash, unsigned int FE, unsigned int val){
+    std::stringstream error;
+    error << "PixelChargeCalibCondData::"<< functionName << "(" << moduleHash << ", " << FE << ", "<< val << "): out of bounds";
+    return std::out_of_range(error.str());
+  }
+  const std::out_of_range 
+  generateError(const char * functionName,  unsigned int moduleHash, unsigned int FE){
+    std::stringstream error;
+    error << "PixelChargeCalibCondData::"<< functionName << "(" << moduleHash << ", " << FE << "): out of bounds";
+    return std::out_of_range(error.str());
+  }
+  const std::out_of_range 
+  generateError(const char * functionName,  unsigned int moduleHash){
+    std::stringstream error;
+    error << "PixelChargeCalibCondData::"<< functionName << "(" << moduleHash << "): out of bounds";
+    return std::out_of_range(error.str());
+  }
+}
+
+PixelChargeCalibCondData::PixelChargeCalibCondData(std::size_t max_module_hash) : m_maxModuleHash(max_module_hash){
+  //nop
+}
+
+void 
+PixelChargeCalibCondData::setThresholds(InDetDD::PixelDiodeType type, unsigned int moduleHash, const std::vector<PixelChargeCalib::Thresholds> & thresholds){
+  const auto n  = thresholds.size();
+  std::vector<int> v1;
+  std::vector<int> v2;
+  std::vector<int> v3;
+  std::vector<int> v4;
+  v1.reserve(n);
+  v2.reserve(n);
+  v3.reserve(n);
+  v4.reserve(n);
+  for (const auto& th : thresholds){
+    v1.push_back(th.value); //values are copied here
+    v2.push_back(th.sigma);
+    v3.push_back(th.noise);
+    v4.push_back(th.inTimeValue);
+  }
+  setValue(m_maxModuleHash, m_analogThreshold, type, moduleHash, std::move(v1)); //...and then moved
+  setValue(m_maxModuleHash, m_analogThresholdSigma, type, moduleHash, std::move(v2));
+  setValue(m_maxModuleHash, m_analogThresholdNoise, type, moduleHash, std::move(v3));
+  setValue(m_maxModuleHash, m_inTimeThreshold,type, moduleHash, std::move(v4));
+}
+
+PixelChargeCalib::Thresholds 
+PixelChargeCalibCondData::getThresholds(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  auto idx = enum2uint(type);
+  const chipThreshold &typeMap1 = m_analogThreshold.at(idx);
+  const chipThreshold &typeMap2 = m_analogThresholdSigma.at(idx);
+  const chipThreshold &typeMap3 = m_analogThresholdNoise.at(idx);
+  const chipThreshold &typeMap4 = m_inTimeThreshold.at(idx);
+  //
+  const auto &val = typeMap1.at(moduleHash);
+  if (FE < val.size()) {
+    const auto &sig = typeMap2.at(moduleHash);
+    const auto &noi = typeMap3.at(moduleHash);
+    const auto &inT = typeMap4.at(moduleHash);
+    return PixelChargeCalib::Thresholds {val[FE],sig[FE],noi[FE], inT[FE]};
+  }
+  throw generateError(__func__, type, moduleHash, FE);
+}
+
+void 
+PixelChargeCalibCondData::setLegacyFitParameters(InDetDD::PixelDiodeType type, unsigned int moduleHash, const std::vector<PixelChargeCalib::LegacyFitParameters> &parameters){
+  const auto n  = parameters.size();
+  std::vector<float> v1;
+  std::vector<float> v2;
+  std::vector<float> v3;
+  v1.reserve(n);
+  v2.reserve(n);
+  v3.reserve(n);
+  for (const auto& par : parameters){
+    v1.push_back(par.A); //values are copied here
+    v2.push_back(par.E);
+    v3.push_back(par.C);
+  }
+  setValue(m_maxModuleHash, m_totA,type,moduleHash,std::move(v1));
+  setValue(m_maxModuleHash, m_totE,type,moduleHash,std::move(v2));
+  setValue(m_maxModuleHash, m_totC,type,moduleHash,std::move(v3));
 }
 
-PixelChargeCalibCondData::PixelChargeCalibCondData(std::size_t max_module_hash) : m_maxModuleHash(max_module_hash)
-{
-   static_assert(static_cast<std::size_t>(InDetDD::PixelDiodeType::NORMAL) < s_NPixelDiods);
-   static_assert(static_cast<std::size_t>(InDetDD::PixelDiodeType::LONG)   < s_NPixelDiods);
-   static_assert(static_cast<std::size_t>(InDetDD::PixelDiodeType::GANGED) < s_NPixelDiods);
-   static_assert(static_cast<std::size_t>(InDetDD::PixelDiodeType::LARGE)  < s_NPixelDiods);
+PixelChargeCalib::LegacyFitParameters 
+PixelChargeCalibCondData::getLegacyFitParameters(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  auto idx = enum2uint(type);
+  const chipCharge &typeMap1 = m_totA.at(idx);
+  const chipCharge &typeMap2 = m_totE.at(idx);
+  const chipCharge &typeMap3 = m_totC.at(idx);
+  //
+  const auto &A = typeMap1.at(moduleHash);
+  if (FE < A.size()) {
+    const auto &E = typeMap2.at(moduleHash);
+    const auto &C = typeMap3.at(moduleHash);
+    return {A[FE], E[FE], C[FE]};
+  }
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-void PixelChargeCalibCondData::setAnalogThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value)
-{
-   setValue(m_maxModuleHash, m_analogThreshold, type, moduleHash, std::move(value));
+void 
+PixelChargeCalibCondData::setLinearFitParameters(InDetDD::PixelDiodeType type, unsigned int moduleHash, const std::vector<PixelChargeCalib::LinearFitParameters> &parameters){
+  const auto n  = parameters.size();
+  std::vector<float> v1;
+  std::vector<float> v2;
+  v1.reserve(n);
+  v2.reserve(n);
+  for (const auto& par : parameters){
+    v1.push_back(par.F); //values are copied here
+    v2.push_back(par.G);
+  }
+  setValue(m_maxModuleHash, m_totF,type,moduleHash,std::move(v1));
+  setValue(m_maxModuleHash, m_totG,type,moduleHash,std::move(v2));
 }
 
-void PixelChargeCalibCondData::setAnalogThresholdSigma(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value)
-{
+
+
+PixelChargeCalib::LinearFitParameters 
+PixelChargeCalibCondData::getLinearFitParameters(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  auto idx = enum2uint(type);
+  const chipCharge &typeMap1 = m_totF.at(idx);
+  const chipCharge &typeMap2 = m_totG.at(idx);
+  //
+  const auto &F = typeMap1.at(moduleHash);
+  if (FE < F.size()) {
+    const auto &G = typeMap2.at(moduleHash);
+    return {F[FE], G[FE]};
+  }
+  throw generateError(__func__, type, moduleHash, FE);
+}
+
+void 
+PixelChargeCalibCondData::setTotResolutions(unsigned int moduleHash, const std::vector<PixelChargeCalib::Resolutions> &value){
+  const auto n = value.size();
+  std::vector<float> value1;
+  std::vector<float> value2;
+  value1.reserve(n);
+  value2.reserve(n);
+  for (const auto& v : value){
+    value1.push_back(v.res1); //values are copied here
+    value2.push_back(v.res2);
+  }
+  setValue(m_maxModuleHash, m_totRes1, moduleHash,std::move(value1));
+  setValue(m_maxModuleHash, m_totRes2, moduleHash,std::move(value2));
+}
+
+
+void 
+PixelChargeCalibCondData::setAnalogThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value){
+   setValue(m_maxModuleHash, m_analogThreshold, type, moduleHash, std::move(value));//no copying, just moved
+}
+
+void 
+PixelChargeCalibCondData::setAnalogThresholdSigma(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value){
    setValue(m_maxModuleHash, m_analogThresholdSigma, type, moduleHash, std::move(value));
 }
 
-void PixelChargeCalibCondData::setAnalogThresholdNoise(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value)
-{
+void 
+PixelChargeCalibCondData::setAnalogThresholdNoise(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value){
    setValue(m_maxModuleHash, m_analogThresholdNoise, type, moduleHash, std::move(value));
 }
 
-void PixelChargeCalibCondData::setInTimeThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value)
-{
+void 
+PixelChargeCalibCondData::setInTimeThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<int> &&value){
    setValue(m_maxModuleHash, m_inTimeThreshold,type, moduleHash, std::move(value));
 }
 
-void PixelChargeCalibCondData::setQ2TotA(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value)
-{
+void PixelChargeCalibCondData::setQ2TotA(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value){
    setValue(m_maxModuleHash, m_totA,type,moduleHash,std::move(value));
 }
 
-void PixelChargeCalibCondData::setQ2TotE(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value)
-{
+void PixelChargeCalibCondData::setQ2TotE(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value){
    setValue(m_maxModuleHash, m_totE, type, moduleHash,  std::move(value));
 }
 
-void PixelChargeCalibCondData::setQ2TotC(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value)
-{
+void 
+PixelChargeCalibCondData::setQ2TotC(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value){
    setValue(m_maxModuleHash, m_totC,type,moduleHash,  std::move(value));
 }
 
-void PixelChargeCalibCondData::setQ2TotF(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value)
-{
+void 
+PixelChargeCalibCondData::setQ2TotF(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value){
    setValue(m_maxModuleHash, m_totF, type, moduleHash,  std::move(value));
 }
 
-void PixelChargeCalibCondData::setQ2TotG(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value)
-{
+void 
+PixelChargeCalibCondData::setQ2TotG(InDetDD::PixelDiodeType type, unsigned int moduleHash, std::vector<float> &&value){
    setValue( m_maxModuleHash, m_totG, type, moduleHash, std::move(value) );
 }
 
-void PixelChargeCalibCondData::setTotRes1(unsigned int moduleHash, std::vector<float> &&value) {
+void 
+PixelChargeCalibCondData::setTotRes1(unsigned int moduleHash, std::vector<float> &&value) {
    setValue(m_maxModuleHash, m_totRes1, moduleHash,std::move(value));
 }
 
-void PixelChargeCalibCondData::setTotRes2(unsigned int moduleHash, std::vector<float> &&value) {
+void 
+PixelChargeCalibCondData::setTotRes2(unsigned int moduleHash, std::vector<float> &&value) {
    setValue(m_maxModuleHash, m_totRes2,moduleHash, std::move(value));
 }
 
-int PixelChargeCalibCondData::getAnalogThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipThreshold &typeMap = m_analogThreshold.at(diodeIndex(type));
+int 
+PixelChargeCalibCondData::getAnalogThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipThreshold &typeMap = m_analogThreshold.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
     return fe_vec[FE];
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getAnalogThreshold(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-int PixelChargeCalibCondData::getAnalogThresholdSigma(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipThreshold &typeMap = m_analogThresholdSigma.at(diodeIndex(type));
+int 
+PixelChargeCalibCondData::getAnalogThresholdSigma(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipThreshold &typeMap = m_analogThresholdSigma.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
      return fe_vec.at(FE);
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getAnalogThresholdSigma(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-int PixelChargeCalibCondData::getAnalogThresholdNoise(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipThreshold &typeMap = m_analogThresholdNoise.at(diodeIndex(type));
+int 
+PixelChargeCalibCondData::getAnalogThresholdNoise(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipThreshold &typeMap = m_analogThresholdNoise.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
     return fe_vec[FE];
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getAnalogThresholdNoise(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-int PixelChargeCalibCondData::getInTimeThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipThreshold &typeMap = m_inTimeThreshold.at(diodeIndex(type));
+int 
+PixelChargeCalibCondData::getInTimeThreshold(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipThreshold &typeMap = m_inTimeThreshold.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
     return fe_vec[FE];
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getInTimeThreshold(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-float PixelChargeCalibCondData::getQ2TotA(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipCharge &typeMap = m_totA.at(diodeIndex(type));
+float 
+PixelChargeCalibCondData::getQ2TotA(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipCharge &typeMap = m_totA.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
     return fe_vec[FE];
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getQ2TotA(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-float PixelChargeCalibCondData::getQ2TotE(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipCharge &typeMap = m_totE.at(diodeIndex(type));
+float 
+PixelChargeCalibCondData::getQ2TotE(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipCharge &typeMap = m_totE.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
     return fe_vec[FE];
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getQ2TotE(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-float PixelChargeCalibCondData::getQ2TotC(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipCharge &typeMap = m_totC.at(diodeIndex(type));
+float 
+PixelChargeCalibCondData::getQ2TotC(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipCharge &typeMap = m_totC.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
     return fe_vec[FE];
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getQ2TotC(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-float PixelChargeCalibCondData::getQ2TotF(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipCharge &typeMap = m_totF.at(diodeIndex(type));
+float 
+PixelChargeCalibCondData::getQ2TotF(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipCharge &typeMap = m_totF.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
     return fe_vec[FE];
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getQ2TotF(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-float PixelChargeCalibCondData::getQ2TotG(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
-{
-  const chipCharge &typeMap = m_totG.at(diodeIndex(type));
+float 
+PixelChargeCalibCondData::getQ2TotG(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const{
+  const chipCharge &typeMap = m_totG.at(enum2uint(type));
   const auto &fe_vec = typeMap.at(moduleHash);
   if (FE < fe_vec.size()) {
     return fe_vec[FE];
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getQ2TotG(" << static_cast<int>(type) << ", " << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, type, moduleHash, FE);
 }
 
-float PixelChargeCalibCondData::getTotRes(unsigned int moduleHash, unsigned int FE, float Q) const
-{
-  float res1{};
-  {
-  const auto &fe_vec = m_totRes1.at(moduleHash);
-  if (FE < fe_vec.size()) {
-    res1 = fe_vec[FE];
+float 
+PixelChargeCalibCondData::getTotRes(unsigned int moduleHash, unsigned int FE, float Q) const{
+  Resolutions r;
+  if (const auto &fe_vec = m_totRes1.at(moduleHash); FE < fe_vec.size()) {
+    r.res1 = fe_vec[FE];
   } else {
-    std::stringstream error;
-    error << "PixelChargeCalibCondData::getTotRes(" << moduleHash << ", " << FE << "): res1 array out of bounds";
-    throw std::out_of_range(error.str());
-  }
+    throw generateError(__func__, moduleHash, FE);
   }
-
-  float res2{};
-  {
-  const auto &fe_vec = m_totRes2.at(moduleHash);
-  if (FE < fe_vec.size()) {
-    res2 = fe_vec[FE];
+  //
+  
+  if (const auto &fe_vec = m_totRes2.at(moduleHash);FE < fe_vec.size()) {
+    r.res2 = fe_vec[FE];
   } else {
-    std::stringstream error;
-    error << "PixelChargeCalibCondData::getTotRes(" << moduleHash << ", " << FE << "): res2 array out of bounds";
-    throw std::out_of_range(error.str());
+    throw generateError(__func__, moduleHash, FE);
   }
-  }
-  return res1 + res2 * Q;
+  
+  return r.total(Q);
 }
 
-float PixelChargeCalibCondData::getToT(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float Q) const
-{
+float 
+PixelChargeCalibCondData::getToT(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float Q) const{
   if (getCalibrationStrategy(moduleHash) == CalibrationStrategy::LUTFEI4) {
     return getToTLUTFEI4(moduleHash, FE, Q);
   }
-
-  float paramA = getQ2TotA(type, moduleHash, FE);
-  float paramE = getQ2TotE(type, moduleHash, FE);
-  float paramC = getQ2TotC(type, moduleHash, FE);
-  float tot = 0.0;
-  if (paramC + Q != 0.0) {
-    tot = paramA * (paramE + Q) / (paramC + Q);
-  }
+  LegacyFitParameters legacy{getQ2TotA(type, moduleHash, FE), getQ2TotE(type, moduleHash, FE), getQ2TotC(type, moduleHash, FE)};
+  float tot = legacy.ToT(Q);
 
   // Protection for large charge
   float exth = 1e5;    // the calibration function is analytically connected at threshold exth.
   if (Q>exth && getCalibrationStrategy(moduleHash)==CalibrationStrategy::RUN3PIX) {
-    float paramF = getQ2TotF(type, moduleHash, FE);
-    float paramG = getQ2TotG(type, moduleHash, FE);
-    if (paramF != 0.0f){
-      tot = (Q-paramG)/paramF;
-    }
+    LinearFitParameters lin{getQ2TotF(type, moduleHash, FE), getQ2TotG(type, moduleHash, FE)};
+    tot = lin.ToT(Q);
   }
   return tot;
 }
 
-float PixelChargeCalibCondData::getCharge(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float ToT) const
-{
+float 
+PixelChargeCalibCondData::getCharge(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float ToT) const{
   if (getCalibrationStrategy(moduleHash) == CalibrationStrategy::LUTFEI4) {
     return getChargeLUTFEI4(moduleHash, FE, ToT);
   }
-
-  float paramA = getQ2TotA(type, moduleHash, FE);
-  float paramE = getQ2TotE(type, moduleHash, FE);
-  float paramC = getQ2TotC(type, moduleHash, FE);
-  float charge = 0.0;
-  if (std::fabs(paramA) > 0.0 && std::fabs(ToT / paramA - 1.0) > 0.0) {
-    charge = (paramC * ToT / paramA - paramE) / (1.0 - ToT / paramA);
-  }
+  LegacyFitParameters legacy{ getQ2TotA(type, moduleHash, FE), getQ2TotE(type, moduleHash, FE), getQ2TotC(type, moduleHash, FE)};
+ 
+  float charge = legacy.Q(ToT);
 
   // Protection for small charge
   float threshold = getAnalogThreshold(type,moduleHash,FE);
   if (charge<threshold && getCalibrationStrategy(moduleHash)==CalibrationStrategy::RUN3PIX) { charge=threshold; }
-
   // Protection for large charge
   float exth = 1e5;    // the calibration function is analytically connected at threshold exth.
   if (charge>exth && getCalibrationStrategy(moduleHash)==CalibrationStrategy::RUN3PIX) {
-    float paramF = getQ2TotF(type, moduleHash, FE);
-    float paramG = getQ2TotG(type, moduleHash, FE);
-    charge = paramF*ToT+paramG;
+    LinearFitParameters lin  = {getQ2TotF(type, moduleHash, FE), getQ2TotG(type, moduleHash, FE)};
+    charge = lin.Q(ToT);
   }
   return charge;
 }
 
-void PixelChargeCalibCondData::setCalibrationStrategy(unsigned int moduleHash, CalibrationStrategy strategy)
-{ 
+void 
+PixelChargeCalibCondData::setCalibrationStrategy(unsigned int moduleHash, CalibrationStrategy strategy){ 
   if (moduleHash > m_maxModuleHash) {
-    std::stringstream error;
-    error << "PixelChargeCalibCondData::setCalibrationStrategy(" << moduleHash << "): array out of bounds";
-    throw std::out_of_range(error.str());
+    throw generateError(__func__, moduleHash, static_cast<int>(strategy));
   }
   m_calibrationStrategy[moduleHash] = strategy;
 }
 
-PixelChargeCalibCondData::CalibrationStrategy PixelChargeCalibCondData::getCalibrationStrategy(unsigned int moduleHash) const
-{
+PixelChargeCalibCondData::CalibrationStrategy 
+PixelChargeCalibCondData::getCalibrationStrategy(unsigned int moduleHash) const{
   if (moduleHash > m_maxModuleHash){
-    std::stringstream error;
-    error << "PixelChargeCalibCondData::getCalibrationStrategy(" << moduleHash << "): array out of bounds";
-    throw std::out_of_range(error.str());
+    throw generateError(__func__, moduleHash);
   }
   auto itr = m_calibrationStrategy.find(moduleHash);
   if (itr != m_calibrationStrategy.end()) {
@@ -298,42 +385,35 @@ PixelChargeCalibCondData::CalibrationStrategy PixelChargeCalibCondData::getCalib
   return CalibrationStrategy::RUN1PIX;
 }
 
-void PixelChargeCalibCondData::setTot2Charges(unsigned int moduleHash, IBLModule charges)
-{ 
+void 
+PixelChargeCalibCondData::setTot2Charges(unsigned int moduleHash, IBLModule charges){ 
   if (moduleHash > m_maxModuleHash){
-    std::stringstream error;
-    error << "PixelChargeCalibCondData::setTot2Charges(" << moduleHash << ", vector<array<float, 16>>): array out of bounds";
-    throw std::out_of_range(error.str());
+    throw generateError(__func__, moduleHash);
   }
   m_tot2Charges[moduleHash] = std::move(charges);
 }
 
-const PixelChargeCalibCondData::IBLCalibration &PixelChargeCalibCondData::getTot2Charges(unsigned int moduleHash, unsigned int FE) const
-{
+const PixelChargeCalibCondData::IBLCalibration &
+PixelChargeCalibCondData::getTot2Charges(unsigned int moduleHash, unsigned int FE) const{
   auto it = m_tot2Charges.find(moduleHash);
   if (it != m_tot2Charges.end() && FE < it->second.size()) {
     return it->second.at(FE);
   }
-
-  std::stringstream error;
-  error << "PixelChargeCalibCondData::getTot2Charges(" << moduleHash << ", " << FE << "): array out of bounds";
-  throw std::out_of_range(error.str());
+  throw generateError(__func__, moduleHash,FE);
 }
 
-float PixelChargeCalibCondData::getChargeLUTFEI4(unsigned int moduleHash, unsigned int FE, unsigned int ToT) const
-{
+float 
+PixelChargeCalibCondData::getChargeLUTFEI4(unsigned int moduleHash, unsigned int FE, unsigned int ToT) const{
   if (ToT < 1 || ToT > IBLCalibrationSize) {
-    std::stringstream error;
-    error << "PixelChargeCalibCondData::getChargeLUTFEI4(" << moduleHash << ", " << FE << ", " << ToT << "): array out of bounds";
-    throw std::out_of_range(error.str());
+    throw generateError(__func__, moduleHash,FE, ToT);
   }
 
   const IBLCalibration &charges = getTot2Charges(moduleHash,FE);
   return charges[ToT - 1];
 }
 
-float PixelChargeCalibCondData::getToTLUTFEI4(unsigned int moduleHash, unsigned int FE, float Q) const
-{
+float 
+PixelChargeCalibCondData::getToTLUTFEI4(unsigned int moduleHash, unsigned int FE, float Q) const{
   int tot = -1;
   float minDiff = FLT_MAX;
   for (size_t t = 0; t < IBLCalibrationSize; t++) {
diff --git a/InnerDetector/InDetConditions/PixelConditionsData/test/PixelChargeCondData_test.cxx b/InnerDetector/InDetConditions/PixelConditionsData/test/PixelChargeCondData_test.cxx
index 0fabba4fd8bfd3871fdf46e084e327f14122bbcc..9b9b34ff09791df97b8f6887210927cde511d14d 100644
--- a/InnerDetector/InDetConditions/PixelConditionsData/test/PixelChargeCondData_test.cxx
+++ b/InnerDetector/InDetConditions/PixelConditionsData/test/PixelChargeCondData_test.cxx
@@ -18,6 +18,7 @@
 #include <boost/test/unit_test.hpp>
 //
 #include "PixelConditionsData/PixelChargeCalibCondData.h"
+#include "PixelConditionsData/ChargeCalibParameters.h"
 #include <vector>
 #include <stdexcept>
 #include <algorithm>
@@ -33,18 +34,34 @@ BOOST_AUTO_TEST_SUITE(PixelChargeCalibCondDataTest)
   }
   
   BOOST_AUTO_TEST_CASE( SetAndGet ){
-    std::vector<int> dummy(6,10);
-    std::vector<int> thresholds{0,20,40, 100, 4, 30};//normally 16 values, 1 for each chip
     size_t maxModuleHash(100); //normally given by the maximum hash
-    InDetDD::PixelDiodeType type = InDetDD::PixelDiodeType::NORMAL;
-    unsigned int moduleHash=10;
+    unsigned int hashTooBig=200;
     PixelChargeCalibCondData calib(maxModuleHash);
+    //arguments to set and get I will use:
+    unsigned int moduleHash=10;
+    unsigned int frontEndIdx=1;
+    unsigned int frontEndIdxTooBig=15;
+    InDetDD::PixelDiodeType type = InDetDD::PixelDiodeType::NORMAL;
+    //
+    //
+    PixelChargeCalib::Thresholds oneValue{0,3,6,9};// thresh, noise, sigma, intime
+    std::vector<PixelChargeCalib::Thresholds> allThresholds(5, oneValue);
+    BOOST_CHECK_NO_THROW(calib.setThresholds(type,moduleHash, allThresholds));
+    BOOST_CHECK_THROW(calib.setThresholds(type,hashTooBig, allThresholds), std::out_of_range);
+    //use old methods to get values
+    BOOST_CHECK(calib.getAnalogThreshold(type, moduleHash, frontEndIdx) == 0);
+    BOOST_CHECK(calib.getAnalogThresholdSigma(type, moduleHash, frontEndIdx) == 3);
+    //return struct in new method
+    BOOST_CHECK(calib.getThresholds(type, moduleHash, frontEndIdx).sigma == 3);
+    BOOST_CHECK(calib.getThresholds(type, moduleHash, frontEndIdx).noise == 6);
+    BOOST_CHECK_THROW(calib.getThresholds(type,hashTooBig,frontEndIdx), std::out_of_range);
+    BOOST_CHECK_THROW(calib.getThresholds(type,moduleHash,frontEndIdxTooBig), std::out_of_range);
+    //
+    std::vector<int> dummy(6,10);
+    std::vector<int> thresholds{0,20,40, 100, 4, 30};//normally 16 values, 1 for each chip
     BOOST_CHECK_NO_THROW(calib.setAnalogThreshold(type,moduleHash, std::move(thresholds)));
-    unsigned int hashTooBig=200;
     BOOST_CHECK_THROW(calib.setAnalogThreshold(type,hashTooBig, std::move(dummy)), std::out_of_range);
     //
-    unsigned int frontEndIdx=1;
-    unsigned int frontEndIdxTooBig=15;
     BOOST_CHECK(calib.getAnalogThreshold(type, moduleHash, frontEndIdx) == 20);
     BOOST_CHECK_THROW(calib.getAnalogThreshold(type, hashTooBig, frontEndIdx), std::out_of_range);
     BOOST_CHECK_THROW(calib.getAnalogThreshold(type, moduleHash, frontEndIdxTooBig), std::out_of_range);
@@ -64,6 +81,31 @@ BOOST_AUTO_TEST_SUITE(PixelChargeCalibCondDataTest)
     BOOST_CHECK_NO_THROW(calib.setInTimeThreshold(type,moduleHash, std::move(inTime)));
     BOOST_CHECK(calib.getInTimeThreshold(type, moduleHash, frontEndIdx) == 4);
     //
+    PixelChargeCalib::LegacyFitParameters oneFit{100.f, 300.f, 600.f};
+    std::vector< PixelChargeCalib::LegacyFitParameters > allParameters(4, oneFit);
+    BOOST_CHECK_NO_THROW(calib.setLegacyFitParameters(type,moduleHash, allParameters));
+    BOOST_CHECK_THROW(calib.setLegacyFitParameters(type,hashTooBig, allParameters), std::out_of_range);
+    BOOST_TEST(calib.getQ2TotA(type, moduleHash, frontEndIdx) == 100.f);
+    BOOST_TEST(calib.getLegacyFitParameters(type, moduleHash, frontEndIdx).C == 600.f);
+    BOOST_CHECK_THROW(calib.getLegacyFitParameters(type,hashTooBig,frontEndIdx), std::out_of_range);
+    BOOST_CHECK_THROW(calib.getLegacyFitParameters(type,moduleHash,frontEndIdxTooBig), std::out_of_range);
+    //
+    PixelChargeCalib::LinearFitParameters linFit{110.f, 120.f};
+    std::vector< PixelChargeCalib::LinearFitParameters > linParameters(4, linFit);
+    BOOST_CHECK_NO_THROW(calib.setLinearFitParameters(type,moduleHash, linParameters));
+    BOOST_CHECK_THROW(calib.setLinearFitParameters(type,hashTooBig, linParameters), std::out_of_range);
+    BOOST_TEST(calib.getQ2TotF(type, moduleHash, frontEndIdx) == 110.f);
+    BOOST_TEST(calib.getLinearFitParameters(type, moduleHash, frontEndIdx).G ==  120.f);
+    BOOST_CHECK_THROW(calib.getLinearFitParameters(type,hashTooBig,frontEndIdx), std::out_of_range);
+    BOOST_CHECK_THROW(calib.getLinearFitParameters(type,moduleHash,frontEndIdxTooBig), std::out_of_range);
+    //
+    float Q=5.f;
+    PixelChargeCalib::Resolutions oneResolution{20.f,30.f};
+    std::vector< PixelChargeCalib::Resolutions > resolutions(4, oneResolution);
+    BOOST_CHECK_NO_THROW(calib.setTotResolutions(moduleHash, resolutions));
+    BOOST_CHECK_THROW(calib.setTotResolutions(hashTooBig, resolutions), std::out_of_range);
+    BOOST_TEST(calib.getTotRes(moduleHash, frontEndIdx, Q) == (20.f + 5.f*30.f));
+    //
     std::vector<float> A(6);
     std::iota(A.begin(), A.end(), 0.);
     BOOST_CHECK_NO_THROW(calib.setQ2TotA(type, moduleHash, std::move(A)));
@@ -97,7 +139,7 @@ BOOST_AUTO_TEST_SUITE(PixelChargeCalibCondDataTest)
     std::iota(res2.begin(), res2.end(), 5.);
     BOOST_CHECK_NO_THROW(calib.setTotRes2(moduleHash, std::move(res2)));
     //
-    float Q=5.f;
+   
     float expectedResult = 6.f*Q + 6.f;
     BOOST_TEST(calib.getTotRes(moduleHash, frontEndIdx, Q) == expectedResult);
     //round trip calculation
diff --git a/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/CMakeLists.txt b/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/CMakeLists.txt
index bed383ff1d79bb8530e94e841a0c2d4c8cbd8c01..c2966fabe73c3d014149c3da6f39d3b8d03b4995 100644
--- a/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/CMakeLists.txt
+++ b/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/CMakeLists.txt
@@ -1,10 +1,18 @@
-# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
 
 # Declare the package name:
 atlas_subdir( PixelReadoutDefinitions )
 
+find_package( Boost COMPONENTS unit_test_framework)
+
 # Component(s) in the package:
 atlas_add_library( PixelReadoutDefinitionsLib
                    PixelReadoutDefinitions/*.h
                    INTERFACE
                    PUBLIC_HEADERS PixelReadoutDefinitions )
+                   
+atlas_add_test( PixelReadoutDefinitions_test
+  SOURCES test/PixelReadoutDefinitions_test.cxx
+  INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
+  LINK_LIBRARIES ${Boost_LIBRARIES} PixelReadoutDefinitionsLib
+  POST_EXEC_SCRIPT "nopost.sh" )
diff --git a/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/PixelReadoutDefinitions/PixelReadoutDefinitions.h b/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/PixelReadoutDefinitions/PixelReadoutDefinitions.h
index ca04b0cedfcdeb6e9ffcf28f0bb53fedc28190b8..8ebe3ac9ea9e2428dd9a658a2ac2fdc133a0b6d4 100644
--- a/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/PixelReadoutDefinitions/PixelReadoutDefinitions.h
+++ b/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/PixelReadoutDefinitions/PixelReadoutDefinitions.h
@@ -1,37 +1,43 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef PIXELREADOUTDEFINITIONS_H
 #define PIXELREADOUTDEFINITIONS_H
+#include <cstddef> //for size_t
 
-namespace InDetDD
-{
+namespace InDetDD{
 
-enum class PixelModuleType
-{
-  DBM,
-  IBL_PLANAR,
-  IBL_3D,
-  PIX_BARREL,
-  PIX_ENDCAP,
-  NONE
-};
+  enum class PixelModuleType{
+    DBM,
+    IBL_PLANAR,
+    IBL_3D,
+    PIX_BARREL,
+    PIX_ENDCAP,
+    NONE
+  };
 
-enum class PixelDiodeType
-{
-  NORMAL,
-  LONG,
-  GANGED,
-  LARGE
-};
+  enum class PixelDiodeType{
+    NORMAL,
+    LONG,
+    GANGED,
+    LARGE,
+    N_DIODETYPES
+  };
 
-enum class PixelReadoutTechnology
-{
-  FEI3,
-  FEI4,
-  RD53
-};
+  enum class PixelReadoutTechnology{
+    FEI3,
+    FEI4,
+    RD53,
+    N_TECHNOLOGIES
+  };
+  
+  ///Convert an enum class to size_t for use as an array index
+  template <typename T>
+  constexpr std::size_t
+  enum2uint(T n){
+    return static_cast<size_t>(n);
+  }
 
 }
 
diff --git a/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/test/PixelReadoutDefinitions_test.cxx b/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/test/PixelReadoutDefinitions_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9d4b884f91cb8216d1d34d31bb1e30cab5592375
--- /dev/null
+++ b/InnerDetector/InDetDetDescr/PixelReadoutDefinitions/test/PixelReadoutDefinitions_test.cxx
@@ -0,0 +1,29 @@
+/*
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file PixelReadoutDefinitions/test/PixelReadoutDefinitions_test.cxx
+ * @author Shaun Roe
+ * @date July, 2023
+ * @brief Some tests for PixelReadoutDefinitions  enum2uint
+ */
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MAIN
+#define BOOST_TEST_MODULE TEST_PIXELREADOUTDEFINITIONS
+
+
+#include <boost/test/unit_test.hpp>
+//
+
+#include "PixelReadoutDefinitions/PixelReadoutDefinitions.h"
+using namespace InDetDD;
+
+BOOST_AUTO_TEST_SUITE(PixelReadoutDefinitionsTest)
+  BOOST_AUTO_TEST_CASE(enum2uint_test){
+    BOOST_TEST(enum2uint(PixelModuleType::IBL_PLANAR) == 1);
+    BOOST_TEST(enum2uint(PixelDiodeType::LONG) == 1);
+    BOOST_TEST(enum2uint(PixelReadoutTechnology::FEI4) == 1);
+  }
+BOOST_AUTO_TEST_SUITE_END()