From 1e6439abd505c4c8d64426d15d57b5a2d89ef9a7 Mon Sep 17 00:00:00 2001
From: Eric Torrence <eric.torrence@cern.ch>
Date: Tue, 6 Dec 2022 09:10:45 +0100
Subject: [PATCH] Add WaveformDigiConditionsTool and use this to set
 digitization parameters

---
 .../CaloDigiAlgs/python/CaloDigiAlgsConfig.py |  24 ++-
 .../CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx  |  41 +++--
 .../CaloDigiAlgs/src/CaloWaveformDigiAlg.h    |  28 +--
 .../Digitization/scripts/faser_digi.py        |   7 +-
 .../python/ScintDigiAlgsConfig.py             |  46 ++---
 .../src/ScintWaveformDigiAlg.cxx              |  37 ++--
 .../ScintDigiAlgs/src/ScintWaveformDigiAlg.h  |  25 ++-
 .../WaveCondUtils/scripts/makeDigiDB.py       | 156 ++++++++++++++++
 .../IWaveformDigiConditionsTool.h             |  63 +++++++
 .../python/WaveformDigitizationConfig.py      |  21 +++
 .../src/WaveformDigiConditionsTool.cxx        | 173 ++++++++++++++++++
 .../src/WaveformDigiConditionsTool.h          |  95 ++++++++++
 .../src/WaveformTimingTool.h                  |   2 +-
 .../WaveformConditionsTools_entries.cxx       |   2 +
 14 files changed, 616 insertions(+), 104 deletions(-)
 create mode 100755 Waveform/WaveformConditions/WaveCondUtils/scripts/makeDigiDB.py
 create mode 100644 Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformDigiConditionsTool.h
 create mode 100644 Waveform/WaveformConditions/WaveformConditionsTools/python/WaveformDigitizationConfig.py
 create mode 100644 Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformDigiConditionsTool.cxx
 create mode 100644 Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformDigiConditionsTool.h

diff --git a/Calorimeter/CaloDigiAlgs/python/CaloDigiAlgsConfig.py b/Calorimeter/CaloDigiAlgs/python/CaloDigiAlgsConfig.py
index c9ae1487..816da133 100644
--- a/Calorimeter/CaloDigiAlgs/python/CaloDigiAlgsConfig.py
+++ b/Calorimeter/CaloDigiAlgs/python/CaloDigiAlgsConfig.py
@@ -7,6 +7,7 @@ from AthenaConfiguration.ComponentFactory import CompFactory
 from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
 
 from WaveformConditionsTools.WaveformCableMappingConfig import WaveformCableMappingCfg
+#from WaveformConditionsTools.WaveformDigitizationConfig import WaveformDigitizationCfg
 
 # One stop shopping for normal FASER data
 def CaloWaveformDigitizationCfg(flags, **kwargs):
@@ -19,6 +20,13 @@ def CaloWaveformDigitizationCfg(flags, **kwargs):
     acc.merge(CaloWaveformDigiCfg(flags, "CaloWaveformDigiAlg", **kwargs))
     acc.merge(CaloWaveformDigitizationOutputCfg(flags))
     acc.merge(WaveformCableMappingCfg(flags))
+    #acc.merge(WaveformDigitizationCfg(flags))
+
+    # Just do this here for now
+    dbInstance = kwargs.get("dbInstance", "TRIGGER_OFL")
+    dbFolder = kwargs.get("dbFolder", "/WAVE/Digitization")
+    from IOVDbSvc.IOVDbSvcConfig import addFolders
+    acc.merge(addFolders(flags, dbFolder, dbInstance, className="CondAttrListCollection"))
 
     return acc
 
@@ -29,24 +37,14 @@ def CaloWaveformDigiCfg(flags, name="CaloWaveformDigiAlg", **kwargs):
 
     tool = CompFactory.WaveformDigitisationTool(name="CaloWaveformDigtisationTool")
     kwargs.setdefault("WaveformDigitisationTool", tool)
+
+    tool = CompFactory.WaveformDigiConditionsTool(name="CaloDigiConditionsTool", Detector="Calo")
+    kwargs.setdefault("DigiConditionsTool", tool)
     
     kwargs.setdefault("CaloHitContainerKey", "EcalHits")
     kwargs.setdefault("WaveformContainerKey", "CaloWaveforms")
 
-    kwargs.setdefault("CB_alpha", -0.32)
-    kwargs.setdefault("CB_n", 1000)
-    kwargs.setdefault("CB_sigma", 3.67)
-    kwargs.setdefault("CB_mean", 820) # Time in ns
-    # This number is over-ridden in the digitization script, so change it there!
-    kwargs.setdefault("CB_norm", 5.0)  # Low gain default without filters, use x5? for high gain
-
-    kwargs.setdefault("base_mean", 15650)
-    kwargs.setdefault("base_rms", 3)
-
     digiAlg = CompFactory.CaloWaveformDigiAlg(name, **kwargs)
-    print(f"CaloWaveformDigiAlg normalization: {digiAlg.CB_norm}")
-    print(f"CaloWaveformDigiAlg mean time: {digiAlg.CB_mean}")
-
     acc.addEventAlgo(digiAlg)
 
     return acc
diff --git a/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx b/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx
index 3e10288e..a44c0d2b 100644
--- a/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx
+++ b/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx
@@ -16,11 +16,12 @@ CaloWaveformDigiAlg::CaloWaveformDigiAlg(const std::string& name,
 
 StatusCode 
 CaloWaveformDigiAlg::initialize() {
-  ATH_MSG_INFO(name() << "::initalize()" );
+  ATH_MSG_INFO(name() << "::initalize()");
 
   // Initalize tools
   ATH_CHECK( m_digiTool.retrieve() );
   ATH_CHECK( m_mappingTool.retrieve() );
+  ATH_CHECK( m_digiCondTool.retrieve() );
 
   // Set key to read waveform from
   ATH_CHECK( m_caloHitContainerKey.initialize() );
@@ -31,16 +32,8 @@ CaloWaveformDigiAlg::initialize() {
   // Set up  helper
   ATH_CHECK(detStore()->retrieve(m_ecalID, "EcalID"));
 
-  // Create CB time kernel and pre-evaluate for number of samples
-  m_kernel = new TF1("PDF", "[4] * ROOT::Math::crystalball_pdf(x, [0],[1],[2],[3])", 0, 1200);
-  m_kernel->SetParameter(0, m_CB_alpha);
-  m_kernel->SetParameter(1, m_CB_n);
-  m_kernel->SetParameter(2, m_CB_sigma);
-  m_kernel->SetParameter(3, m_CB_mean);
-  m_kernel->SetParameter(4, m_CB_norm);
-
-  // Pre-evaluate time kernel for each bin
-  m_timekernel = m_digiTool->evaluate_timekernel(m_kernel);
+  // Need to set this on first event
+  m_kernel = 0;
 
   return StatusCode::SUCCESS;
 }
@@ -49,7 +42,8 @@ StatusCode
 CaloWaveformDigiAlg::finalize() {
   ATH_MSG_INFO(name() << "::finalize()");
 
-  delete m_kernel;
+  if (m_kernel)
+    delete m_kernel;
 
   return StatusCode::SUCCESS;
 }
@@ -60,7 +54,7 @@ CaloWaveformDigiAlg::execute(const EventContext& ctx) const {
   ATH_MSG_DEBUG("Run: " << ctx.eventID().run_number() << " Event: " << ctx.eventID().event_number());
 
   // Find the input HIT collection
-   SG::ReadHandle<CaloHitCollection> caloHitHandle(m_caloHitContainerKey, ctx);
+  SG::ReadHandle<CaloHitCollection> caloHitHandle(m_caloHitContainerKey, ctx);
 
   ATH_CHECK( caloHitHandle.isValid() );
   ATH_MSG_DEBUG("Found ReadHandle for CaloHitCollection " << m_caloHitContainerKey);
@@ -76,6 +70,27 @@ CaloWaveformDigiAlg::execute(const EventContext& ctx) const {
     return StatusCode::SUCCESS;
   }
 
+  if (!m_kernel) {
+
+    ATH_MSG_INFO("Setting up calo digitization kernel");
+
+    // Set up waveform shape
+    m_kernel = new TF1("PDF", "[4] * ROOT::Math::crystalball_pdf(x, [0],[1],[2],[3])", 0, 1200);
+
+    m_kernel->SetParameter(0, m_digiCondTool->cb_alpha(ctx));
+    m_kernel->SetParameter(1, m_digiCondTool->cb_n(ctx));
+    m_kernel->SetParameter(2, m_digiCondTool->cb_sigma(ctx));
+    m_kernel->SetParameter(3, m_digiCondTool->cb_mean(ctx));
+    m_kernel->SetParameter(4, m_digiCondTool->cb_norm(ctx));
+    
+    // Pre-evaluate time kernel for each bin
+    m_timekernel = m_digiTool->evaluate_timekernel(m_kernel);
+
+    // Also save the baseline parameters
+    m_base_mean = m_digiCondTool->base_mean(ctx); 
+    m_base_rms  = m_digiCondTool->base_rms(ctx); 
+  }
+
   // Create structure to store pulse for each channel
   std::map<Identifier, std::vector<uint16_t>> waveforms = m_digiTool->create_waveform_map(m_ecalID);
 
diff --git a/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.h b/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.h
index 25111bc9..7ee25a27 100644
--- a/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.h
+++ b/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.h
@@ -11,6 +11,7 @@
 // Tool classes
 #include "WaveDigiTools/IWaveformDigitisationTool.h"
 #include "WaveformConditionsTools/IWaveformCableMappingTool.h"
+#include "WaveformConditionsTools/IWaveformDigiConditionsTool.h"
 
 // Handles
 #include "StoreGate/ReadHandleKey.h"
@@ -30,7 +31,7 @@
 #include <string>
 #include <vector>
 
-class CaloWaveformDigiAlg : public AthReentrantAlgorithm {
+class CaloWaveformDigiAlg: public AthReentrantAlgorithm {
 
  public:
   // Constructor
@@ -53,22 +54,15 @@ class CaloWaveformDigiAlg : public AthReentrantAlgorithm {
   CaloWaveformDigiAlg &operator=(const CaloWaveformDigiAlg&) = delete;
   //@}
 
-  /** @name Steerable pameters for crystal ball and baseline **/
-  //@{
-  Gaudi::Property<double> m_CB_alpha {this, "CB_alpha", 0, "Alpha of the crystal ball function"};
-  Gaudi::Property<double> m_CB_n {this, "CB_n", 0, "n of the crystal ball function"};
-  Gaudi::Property<double> m_CB_mean {this, "CB_mean", 0, "Mean of the crystal ball function"};
-  Gaudi::Property<double> m_CB_sigma {this, "CB_sigma", 0, "Sigma of the crystal ball function"};
-  Gaudi::Property<double> m_CB_norm {this, "CB_norm", 0, "Norm of the crystal ball function"};
-
-  Gaudi::Property<double> m_base_mean {this, "base_mean", 0, "Mean of the baseline"};
-  Gaudi::Property<double> m_base_rms {this, "base_rms", 0, "RMS of the baseline"};
-  //@}
+  // We use these a lot, so read them once from the conditions tool
+  mutable float m_base_mean;
+  mutable float m_base_rms;
 
   /** Kernel PDF and evaluated values **/
+  // Mark these mutable, as they must be changed on first event...
   //@{
-  TF1*                            m_kernel;
-  std::vector<float>              m_timekernel;
+  mutable TF1*                            m_kernel;
+  mutable std::vector<float>              m_timekernel;
   //@}
 
   /// Detector ID helper
@@ -86,6 +80,12 @@ class CaloWaveformDigiAlg : public AthReentrantAlgorithm {
   ToolHandle<IWaveformCableMappingTool> m_mappingTool
     {this, "WaveformCableMappingTool", "WaveformCableMappingTool"};
 
+  /**
+   * @name Digitization parameters tool
+   */
+  ToolHandle<IWaveformDigiConditionsTool> m_digiCondTool
+    {this, "DigiConditionsTool", "CaloDigiConditionsTool"};
+
   /**
    * @name Input HITS using SG::ReadHandleKey
    */
diff --git a/Control/CalypsoExample/Digitization/scripts/faser_digi.py b/Control/CalypsoExample/Digitization/scripts/faser_digi.py
index 40fb1915..2405432c 100755
--- a/Control/CalypsoExample/Digitization/scripts/faser_digi.py
+++ b/Control/CalypsoExample/Digitization/scripts/faser_digi.py
@@ -126,12 +126,9 @@ acc.merge(FaserGeometryCfg(ConfigFlags))
 from FaserSCT_Digitization.FaserSCT_DigitizationConfigNew import FaserSCT_DigitizationCfg
 acc.merge(FaserSCT_DigitizationCfg(ConfigFlags))
 
+# Pass something to set folder tag
 from CaloDigiAlgs.CaloDigiAlgsConfig import CaloWaveformDigitizationCfg
-if args.highCaloGain:
-    calo_norm = 25.
-else:
-    calo_norm = 5.
-acc.merge(CaloWaveformDigitizationCfg(ConfigFlags, CB_norm=calo_norm))
+acc.merge(CaloWaveformDigitizationCfg(ConfigFlags))
 
 from ScintDigiAlgs.ScintDigiAlgsConfig import ScintWaveformDigitizationCfg
 acc.merge(ScintWaveformDigitizationCfg(ConfigFlags))
diff --git a/Scintillator/ScintDigiAlgs/python/ScintDigiAlgsConfig.py b/Scintillator/ScintDigiAlgs/python/ScintDigiAlgsConfig.py
index 407ab913..7f65467a 100644
--- a/Scintillator/ScintDigiAlgs/python/ScintDigiAlgsConfig.py
+++ b/Scintillator/ScintDigiAlgs/python/ScintDigiAlgsConfig.py
@@ -7,29 +7,8 @@ from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
 
 from WaveformConditionsTools.WaveformCableMappingConfig import WaveformCableMappingCfg
 
-# Crystallball parameter dictionary used in simulated digitized wave reconstruction.
-# Crystalball function Parameters estimated from Deion's slides uploaded at
-# https://indico.cern.ch/event/1099652/contributions/4626975/attachments/2352595/4013927/Faser-Physics-run3933-plots.pdf  (20/01/2022)
-# Parameters are per scintillator source, but not per channel.
-# Updated aamplitudes (norm) to match testbeam response
-# Make everything except VetoNu look like the preshower
-dict_CB_param = {}
-dict_CB_param["Trigger"]=dict(CB_alpha=-0.424, CB_n=6.14, CB_mean=815, CB_sigma=3.21, CB_norm = 4240) 
-dict_CB_param["Timing"] =dict(CB_alpha=-0.424, CB_n=6.14, CB_mean=846, CB_sigma=3.21, CB_norm = 4240) 
-dict_CB_param["Veto"]   =dict(CB_alpha=-0.32,  CB_n=9.0,  CB_mean=815, CB_sigma=3.35, CB_norm = 6840) 
-dict_CB_param["VetoNu"] =dict(CB_alpha=-0.28,  CB_n=1000, CB_mean=815, CB_sigma=5.00, CB_norm = 7040) 
-dict_CB_param["Preshower"]=dict(CB_alpha=-0.32, CB_n=1000, CB_mean=846, CB_sigma=4.0, CB_norm =  400)
-
-dict_baseline_params = {
-    "Trigger"   : {"mean" : 15650, "rms" : 3},
-    "Timing"    : {"mean" : 15650, "rms" : 3},
-    "Veto"      : {"mean" : 15650, "rms" : 3},
-    "VetoNu"    : {"mean" : 15650, "rms" : 3},
-    "Preshower" : {"mean" : 15650, "rms" : 3},        
-    }
-
 # One stop shopping for normal FASER data
-def ScintWaveformDigitizationCfg(flags):
+def ScintWaveformDigitizationCfg(flags, **kwargs):
     """ Return all algorithms and tools for Waveform digitization """
     acc = ComponentAccumulator()
 
@@ -47,6 +26,13 @@ def ScintWaveformDigitizationCfg(flags):
 
     acc.merge(ScintWaveformDigitizationOutputCfg(flags))
     acc.merge(WaveformCableMappingCfg(flags))
+
+    # Just do this here for now
+    dbInstance = kwargs.get("dbInstance", "TRIGGER_OFL")
+    dbFolder = kwargs.get("dbFolder", "/WAVE/Digitization")
+    from IOVDbSvc.IOVDbSvcConfig import addFolders
+    acc.merge(addFolders(flags, dbFolder, dbInstance, className="CondAttrListCollection"))
+
     return acc
 
 # Return configured digitization algorithm from SIM hits
@@ -56,27 +42,19 @@ def ScintWaveformDigiCfg(flags, name="ScintWaveformDigiAlg", source="", **kwargs
     acc = ComponentAccumulator()
 
     tool = CompFactory.WaveformDigitisationTool(name=source+"WaveformDigtisationTool", **kwargs)
+    kwargs.setdefault("WaveformDigitisationTool", tool)
     
     kwargs.setdefault("ScintHitContainerKey", source+"Hits")
     kwargs.setdefault("WaveformContainerKey", source+"Waveforms")
 
-    digiAlg = CompFactory.ScintWaveformDigiAlg(name, **kwargs)
-
     if "TB" in flags.GeoModel.FaserVersion and source == "Veto":
         # The testbeam counters were actually VetoNu, so use those parameters 
         source = "VetoNu"
 
-    digiAlg.CB_alpha = dict_CB_param[source]["CB_alpha"]
-    digiAlg.CB_n = dict_CB_param[source]["CB_n"]
-    digiAlg.CB_mean = dict_CB_param[source]["CB_mean"]
-    digiAlg.CB_sigma = dict_CB_param[source]["CB_sigma"]
-    digiAlg.CB_norm = dict_CB_param[source]["CB_norm"]    
-
-    digiAlg.base_mean = dict_baseline_params[source]["mean"]
-    digiAlg.base_rms = dict_baseline_params[source]["rms"]
-     
-    kwargs.setdefault("WaveformDigitisationTool", tool)
+    tool = CompFactory.WaveformDigiConditionsTool(name=source+"CaloDigiConditionsTool", Detector=source)
+    kwargs.setdefault("DigiConditionsTool", tool)
 
+    digiAlg = CompFactory.ScintWaveformDigiAlg(name, **kwargs)     
     acc.addEventAlgo(digiAlg)
 
     return acc
diff --git a/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.cxx b/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.cxx
index 7eb12286..cacda620 100644
--- a/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.cxx
+++ b/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.cxx
@@ -18,6 +18,7 @@ ScintWaveformDigiAlg::initialize() {
   // Initalize tools
   ATH_CHECK( m_digiTool.retrieve() );
   ATH_CHECK( m_mappingTool.retrieve() );
+  ATH_CHECK( m_digiCondTool.retrieve() );
 
   // Set key to read waveform from
   ATH_CHECK( m_scintHitContainerKey.initialize() );
@@ -31,16 +32,8 @@ ScintWaveformDigiAlg::initialize() {
   ATH_CHECK(detStore()->retrieve(m_triggerID, "TriggerID"));
   ATH_CHECK(detStore()->retrieve(m_preshowerID, "PreshowerID"));
 
-  // Create CB time kernel and pre-evaluate for number of samples
-  m_kernel = new TF1("PDF", "[4] * ROOT::Math::crystalball_pdf(x, [0],[1],[2],[3])", 0, 1200);
-  m_kernel->SetParameter(0, m_CB_alpha);
-  m_kernel->SetParameter(1, m_CB_n);
-  m_kernel->SetParameter(2, m_CB_sigma);
-  m_kernel->SetParameter(3, m_CB_mean);
-  m_kernel->SetParameter(4, m_CB_norm);
-
-  // Pre-evaluate time kernel for each bin
-  m_timekernel = m_digiTool->evaluate_timekernel(m_kernel);
+  // Need to set this on first event
+  m_kernel = 0;
 
   return StatusCode::SUCCESS;
 }
@@ -49,7 +42,8 @@ StatusCode
 ScintWaveformDigiAlg::finalize() {
   ATH_MSG_INFO(name() << "::finalize()");
 
-  delete m_kernel;
+  if (m_kernel)
+    delete m_kernel;
 
   return StatusCode::SUCCESS;
 }
@@ -75,6 +69,27 @@ ScintWaveformDigiAlg::execute(const EventContext& ctx) const {
     ATH_MSG_DEBUG("ScintHitCollection found with zero length!");
     return StatusCode::SUCCESS;
   }
+
+  if (!m_kernel) {
+
+    ATH_MSG_INFO("Setting up digitization kernel");
+
+    // Set up waveform shape
+    m_kernel = new TF1("PDF", "[4] * ROOT::Math::crystalball_pdf(x, [0],[1],[2],[3])", 0, 1200);
+
+    m_kernel->SetParameter(0, m_digiCondTool->cb_alpha(ctx));
+    m_kernel->SetParameter(1, m_digiCondTool->cb_n(ctx));
+    m_kernel->SetParameter(2, m_digiCondTool->cb_sigma(ctx));
+    m_kernel->SetParameter(3, m_digiCondTool->cb_mean(ctx));
+    m_kernel->SetParameter(4, m_digiCondTool->cb_norm(ctx));
+    
+    // Pre-evaluate time kernel for each bin
+    m_timekernel = m_digiTool->evaluate_timekernel(m_kernel);
+
+    // Also save the baseline parameters
+    m_base_mean = m_digiCondTool->base_mean(ctx); 
+    m_base_rms  = m_digiCondTool->base_rms(ctx); 
+  }
   
   // Create structure to store pulse for each channel
   std::map<Identifier, std::vector<uint16_t>> waveforms;
diff --git a/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.h b/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.h
index 52832562..99c374f5 100644
--- a/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.h
+++ b/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.h
@@ -11,6 +11,7 @@
 // Tool classes
 #include "WaveDigiTools/IWaveformDigitisationTool.h"
 #include "WaveformConditionsTools/IWaveformCableMappingTool.h"
+#include "WaveformConditionsTools/IWaveformDigiConditionsTool.h"
 
 // Handles
 #include "StoreGate/ReadHandleKey.h"
@@ -63,23 +64,15 @@ class ScintWaveformDigiAlg : public AthReentrantAlgorithm {
 
   /// 
 
-  /** @name Steerable pameters for crystal ball and baseline **/
-  //@{
-  Gaudi::Property<double> m_CB_alpha {this, "CB_alpha", 0, "Alpha of the crystal ball function"};
-  Gaudi::Property<double> m_CB_n {this, "CB_n", 0, "n of the crystal ball function"};
-  Gaudi::Property<double> m_CB_mean {this, "CB_mean", 0, "Mean of the crystal ball function"};  
-  Gaudi::Property<double> m_CB_sigma {this, "CB_sigma", 0, "Sigma of the crystal ball function"};
-  Gaudi::Property<double> m_CB_norm {this, "CB_norm", 0, "Norm of the crystal ball function"};
-
-  Gaudi::Property<double> m_base_mean {this, "base_mean", 0, "Mean of the baseline"};
-  Gaudi::Property<double> m_base_rms {this, "base_rms", 0, "RMS of the baseline"};
-  //@}
+  // We use these a lot, so read them once from the conditions tool
+  mutable float m_base_mean;
+  mutable float m_base_rms;
 
 
   /** Kernel PDF and evaluated values **/
   //@{
-  TF1*                            m_kernel;
-  std::vector<float>              m_timekernel;
+  mutable TF1*                            m_kernel;
+  mutable std::vector<float>              m_timekernel;
   //@}
   
 
@@ -101,6 +94,12 @@ class ScintWaveformDigiAlg : public AthReentrantAlgorithm {
   ToolHandle<IWaveformCableMappingTool> m_mappingTool
     {this, "WaveformCableMappingTool", "WaveformCableMappingTool"};
 
+  /**
+   * @name Digitization parameters tool
+   */
+  ToolHandle<IWaveformDigiConditionsTool> m_digiCondTool
+    {this, "DigiConditionsTool", ""};
+
   /**
    * @name Input HITS using SG::ReadHandleKey
    */
diff --git a/Waveform/WaveformConditions/WaveCondUtils/scripts/makeDigiDB.py b/Waveform/WaveformConditions/WaveCondUtils/scripts/makeDigiDB.py
new file mode 100755
index 00000000..202c5e26
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveCondUtils/scripts/makeDigiDB.py
@@ -0,0 +1,156 @@
+#!/bin/env python
+#
+# Create digitization DB 
+#
+# Can test results with
+# AtlCoolConsole.py "sqlite://;schema=waveform_digi.db;dbname=OFLP200"
+#
+# Can merge with ALLP200.db with
+# AtlCoolCopy "sqlite://;schema=waveform_digi.db;dbname=OFLP200" "sqlite://;schema=ALLP200.db;dbname=OFLP200"
+
+filename = "waveform_digi.db"
+
+import os
+import sys
+from PyCool import cool
+
+# Useful utilities for manipulating COOL files
+# See https://gitlab.cern.ch/atlas/athena/-/blob/master/Database/CoolConvUtilities/python/AtlCoolLib.py
+import CoolConvUtilities.AtlCoolLib as AtlCoolLib
+
+# Delete file if it exists
+if os.path.exists(filename):
+    print(f"File {filename} exists, deleting...")
+    os.remove(filename)
+
+# Open new DB (forceOpen will create if it doesn't exist)
+connect_string = f'sqlite://;schema={filename};dbname=OFLP200'
+db = AtlCoolLib.forceOpen(connect_string)
+
+if not db:
+    print(f"Error opening {connect_string}")
+    sys.exit(1)
+
+# Description creates type of folder (run/lumi keyed, list of channels)
+description = AtlCoolLib.athenaDesc(runLumi=True, datatype="CondAttrListCollection")
+
+# Define the folder payload
+spec = cool.RecordSpecification()
+spec.extend("base_mean", cool.StorageType.Float)
+spec.extend("base_rms",  cool.StorageType.Float)
+spec.extend("cb_norm", cool.StorageType.Float)
+spec.extend("cb_mean", cool.StorageType.Float)
+spec.extend("cb_sigma", cool.StorageType.Float)
+spec.extend("cb_alpha", cool.StorageType.Float)
+spec.extend("cb_n", cool.StorageType.Float)
+
+# ensureFolder creates as needed
+wave_folder = db.createFolderSet("/WAVE")
+folder = AtlCoolLib.ensureFolder(db, '/WAVE/Digitization', spec, description, 
+                                 version=cool.FolderVersioning.MULTI_VERSION)
+
+if not folder:
+    print("Could not access or create folders!")
+    print(e)
+    sys.exit(1)
+
+# Crystalball function Parameters estimated from Deion's slides uploaded at
+# https://indico.cern.ch/event/1099652/contributions/4626975/attachments/2352595/4013927/Faser-Physics-run3933-plots.pdf  (20/01/2022)
+
+# Fill values into record
+# Values in ADC counts
+base_mean = 15650.
+base_rms = 3.
+
+# Calorimeter default (low gain/filters)
+calo_record = cool.Record(spec)
+calo_record['base_mean'] = base_mean
+calo_record['base_rms'] = base_rms
+calo_record['cb_norm'] = 0.56
+calo_record['cb_mean'] =  820 # Time in ns
+calo_record['cb_sigma'] = 3.67
+calo_record['cb_alpha'] = -0.32
+calo_record['cb_n'] = 1000.
+
+vetonu_record = cool.Record(spec)
+vetonu_record['base_mean'] = base_mean
+vetonu_record['base_rms'] = base_rms
+vetonu_record['cb_norm'] = 7040
+vetonu_record['cb_mean'] =  815 # Time in ns
+vetonu_record['cb_sigma'] = 5.0
+vetonu_record['cb_alpha'] = -0.28
+vetonu_record['cb_n'] = 1000.
+
+veto_record = cool.Record(spec)
+veto_record['base_mean'] = base_mean
+veto_record['base_rms'] = base_rms
+veto_record['cb_norm'] = 6840
+veto_record['cb_mean'] =  815 # Time in ns
+veto_record['cb_sigma'] = 3.35
+veto_record['cb_alpha'] = -0.32
+veto_record['cb_n'] = 9.
+
+timing_record = cool.Record(spec)
+timing_record['base_mean'] = base_mean
+timing_record['base_rms'] = base_rms
+timing_record['cb_norm'] = 4240
+timing_record['cb_mean'] =  815 # Time in ns
+timing_record['cb_sigma'] = 3.21
+timing_record['cb_alpha'] = -0.424
+timing_record['cb_n'] = 6.14
+
+preshower_record = cool.Record(spec)
+preshower_record['base_mean'] = base_mean
+preshower_record['base_rms'] = base_rms
+preshower_record['cb_norm'] = 400
+preshower_record['cb_mean'] =  846 # Time in ns
+preshower_record['cb_sigma'] = 4.0
+preshower_record['cb_alpha'] = -0.32
+preshower_record['cb_n'] = 1000.
+
+# Low gain, filters in default
+tag = "WAVE-Digitization-01-LG"
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, calo_record, 0, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, vetonu_record, 1, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, veto_record, 2, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, timing_record, 3, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, preshower_record, 4, tag)
+folder.createTagRelation("WAVE-01", tag)
+
+# Also associate this default with all of the global tags
+# We will use a folder override to set other conditions
+wave_folder.createTagRelation("OFLCOND-FASER-TB00", "WAVE-01")
+wave_folder.createTagRelation("OFLCOND-FASER-01", "WAVE-01")
+wave_folder.createTagRelation("OFLCOND-FASER-02", "WAVE-01")
+wave_folder.createTagRelation("OFLCOND-FASER-03", "WAVE-01")
+
+# Low gain, filters out
+tag = "WAVE-Digitization-01-LG-nofilt"
+calo_record['cb_norm'] = 5.6
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, calo_record, 0, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, vetonu_record, 1, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, veto_record, 2, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, timing_record, 3, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, preshower_record, 4, tag)
+
+# High gain
+tag = "WAVE-Digitization-01-HG"
+calo_record['cb_norm'] = 16.8
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, calo_record, 0, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, vetonu_record, 1, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, veto_record, 2, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, timing_record, 3, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, preshower_record, 4, tag)
+
+# High gain, filters out
+tag = "WAVE-Digitization-01-HG-nofilt"
+calo_record['cb_norm'] = 168
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, calo_record, 0, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, vetonu_record, 1, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, veto_record, 2, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, timing_record, 3, tag)
+folder.storeObject( cool.ValidityKeyMin, cool.ValidityKeyMax, preshower_record, 4, tag)
+
+# All done
+db.closeDatabase()
+print('Database completed')
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformDigiConditionsTool.h b/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformDigiConditionsTool.h
new file mode 100644
index 00000000..1bfaf0dd
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformDigiConditionsTool.h
@@ -0,0 +1,63 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and FAsER collaborations
+*/
+
+/** @file IWaveformDigiTool.h Interface file for WaveformDigiTool.
+ * 
+ * Provides times and offsets (in ns) for different channels in the
+ * waveform digitizer.  This aligns the input signals for different
+ * path lengths and cable delays.
+ *
+ */
+
+// Multiple inclusion protection
+#ifndef IWAVEFORMDIGICONDITIONSTOOL
+#define IWAVEFORMDIGICONDITIONSTOOL
+
+//STL includes
+#include <map>
+
+//Gaudi Includes
+#include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+
+
+class IWaveformDigiConditionsTool: virtual public IAlgTool {
+
+ public:
+  
+  //----------Public Member Functions----------//
+  // Structors
+  virtual ~IWaveformDigiConditionsTool() = default; //!< Destructor
+
+  /// Creates the InterfaceID and interfaceID() method
+  DeclareInterfaceID(IWaveformDigiConditionsTool, 1, 0);
+
+  // Methods to return digitization parameters
+
+  // Baseline parameters
+  virtual float base_mean(void) const = 0;
+  virtual float base_mean(const EventContext& ctx) const = 0;
+
+  virtual float base_rms(void) const = 0;
+  virtual float base_rms(const EventContext& ctx) const = 0;
+
+  // Crystal Ball parameters
+  virtual float cb_mean(void) const = 0;
+  virtual float cb_mean(const EventContext& ctx) const = 0;
+
+  virtual float cb_sigma(void) const = 0;
+  virtual float cb_sigma(const EventContext& ctx) const = 0;
+
+  virtual float cb_norm(void) const = 0;
+  virtual float cb_norm(const EventContext& ctx) const = 0;
+
+  virtual float cb_alpha(void) const = 0;
+  virtual float cb_alpha(const EventContext& ctx) const = 0;
+
+  virtual float cb_n(void) const = 0;
+  virtual float cb_n(const EventContext& ctx) const = 0;
+};
+
+//---------------------------------------------------------------------- 
+#endif // WAVEFORMDIGITOOL
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/python/WaveformDigitizationConfig.py b/Waveform/WaveformConditions/WaveformConditionsTools/python/WaveformDigitizationConfig.py
new file mode 100644
index 00000000..7eb07444
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/python/WaveformDigitizationConfig.py
@@ -0,0 +1,21 @@
+""" Define methods to configure WaveformCableMapping
+
+Copyright (C) 2022 CERN for the benefit of the FASER collaboration
+"""
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from AthenaConfiguration.ComponentFactory import CompFactory
+from IOVDbSvc.IOVDbSvcConfig import addFolders
+
+def WaveformDititizationCfg(flags, **kwargs):
+    """ Return configured ComponentAccumulator for Waveform Dititization 
+
+    """
+
+    acc = ComponentAccumulator()
+    # tool = kwargs.get("WaveformCableMappingTool", WaveformCableMappingTool(flags))
+    # Probably need to figure this out!
+    dbInstance = kwargs.get("dbInstance", "TRIGGER_OFL")
+    dbFolder = kwargs.get("dbFolder", "/WAVE/Digitization")
+    acc.merge(addFolders(flags, dbFolder, dbInstance, className="CondAttrListCollection"))
+    return acc
+
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformDigiConditionsTool.cxx b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformDigiConditionsTool.cxx
new file mode 100644
index 00000000..4e2fedd9
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformDigiConditionsTool.cxx
@@ -0,0 +1,173 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+/** @file WaveformDigiConditionsTool.cxx Implementation file for WaveformDigiConditionsTool.
+    @author Eric Torrence (04/05/22)
+*/
+
+#include "WaveformDigiConditionsTool.h"
+
+//----------------------------------------------------------------------
+WaveformDigiConditionsTool::WaveformDigiConditionsTool (const std::string& type, const std::string& name, const IInterface* parent) :
+  base_class(type, name, parent)
+{
+}
+
+//----------------------------------------------------------------------
+StatusCode 
+WaveformDigiConditionsTool::initialize() {
+  // Read Cond Handle Key
+
+  ATH_MSG_DEBUG("WaveformDigiConditionsTool::initialize()");
+
+  ATH_CHECK(m_digiReadKey.initialize());
+
+  // Deal with COOL channel
+  if (m_detector == "Calo") {
+    m_cool_channel = COOL_Calo;
+  }
+  else if (m_detector == "VetoNu") {
+    m_cool_channel = COOL_VetoNu;
+  } 
+  else if (m_detector == "Veto") {
+    m_cool_channel = COOL_Veto;
+  } 
+  else if (m_detector == "Trigger") {
+    m_cool_channel = COOL_Timing;
+  } 
+  else if (m_detector == "Timing") {
+    m_cool_channel = COOL_Timing;
+  } 
+  else if (m_detector == "Preshower") {
+    m_cool_channel = COOL_Preshower;
+  } 
+  else {
+    ATH_MSG_FATAL("Unknown detector: " << m_detector);
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//----------------------------------------------------------------------
+StatusCode
+WaveformDigiConditionsTool::finalize() {
+  // Print where you are
+  return StatusCode::SUCCESS;
+}
+
+//----------------------------------------------------------------------
+float
+WaveformDigiConditionsTool::base_mean(const EventContext& ctx) const {
+  return get_value(ctx, "base_mean");
+}
+
+float
+WaveformDigiConditionsTool::base_rms(const EventContext& ctx) const {
+  return get_value(ctx, "base_rms");
+}
+
+float
+WaveformDigiConditionsTool::cb_mean(const EventContext& ctx) const {
+  return get_value(ctx, "cb_mean");
+}
+
+float
+WaveformDigiConditionsTool::cb_sigma(const EventContext& ctx) const {
+  return get_value(ctx, "cb_sigma");
+}
+
+float
+WaveformDigiConditionsTool::cb_norm(const EventContext& ctx) const {
+  return get_value(ctx, "cb_norm");
+}
+
+float
+WaveformDigiConditionsTool::cb_alpha(const EventContext& ctx) const {
+  return get_value(ctx, "cb_alpha");
+}
+
+float
+WaveformDigiConditionsTool::cb_n(const EventContext& ctx) const {
+  return get_value(ctx, "cb_n");
+}
+
+//----------------------------------------------------------------------
+float
+WaveformDigiConditionsTool::base_mean(void) const {
+  const EventContext& ctx(Gaudi::Hive::currentContext());
+  return base_mean(ctx);
+}
+
+float
+WaveformDigiConditionsTool::base_rms(void) const {
+  const EventContext& ctx(Gaudi::Hive::currentContext());
+  return base_rms(ctx);
+}
+
+float
+WaveformDigiConditionsTool::cb_mean(void) const {
+  const EventContext& ctx(Gaudi::Hive::currentContext());
+  return cb_mean(ctx);
+}
+
+float
+WaveformDigiConditionsTool::cb_sigma(void) const {
+  const EventContext& ctx(Gaudi::Hive::currentContext());
+  return cb_sigma(ctx);
+}
+
+float
+WaveformDigiConditionsTool::cb_norm(void) const {
+  const EventContext& ctx(Gaudi::Hive::currentContext());
+  return cb_norm(ctx);
+}
+
+float
+WaveformDigiConditionsTool::cb_alpha(void) const {
+  const EventContext& ctx(Gaudi::Hive::currentContext());
+  return cb_alpha(ctx);
+}
+
+float
+WaveformDigiConditionsTool::cb_n(void) const {
+  const EventContext& ctx(Gaudi::Hive::currentContext());
+  return cb_n(ctx);
+}
+
+
+//----------------------------------------------------------------------
+float 
+WaveformDigiConditionsTool::get_value(const EventContext& ctx, std::string arg) const {
+
+  float val = -1.;
+
+  // Read Cond Handle
+  SG::ReadCondHandle<CondAttrListCollection> readHandle{m_digiReadKey, ctx};
+  const CondAttrListCollection* readCdo{*readHandle}; 
+  if (readCdo==nullptr) {
+    ATH_MSG_FATAL("Null pointer to the read conditions object");
+    return val;
+  }
+
+  // Read value for specific channel
+  const CondAttrListCollection::AttributeList& payload{readCdo->attributeList(m_cool_channel)};
+
+  if (payload.exists(arg) and not payload[arg].isNull()) {
+    val = payload[arg].data<float>();
+    ATH_MSG_DEBUG("Found digi COOL channel " << m_cool_channel << " " << arg << " as " << val);
+  } else {
+    ATH_MSG_WARNING("No valid " << arg << " value found for digi COOL channel "<< m_cool_channel<<"!");
+  }
+
+  return val;
+
+}
+
+
+
+
+
+
+
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformDigiConditionsTool.h b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformDigiConditionsTool.h
new file mode 100644
index 00000000..e5e82320
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformDigiConditionsTool.h
@@ -0,0 +1,95 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and CERN collaborations
+*/
+
+/** @file WaveformDigiConditionsTool.h Header file for WaveformDigiConditionsTool.
+    @author Eric Torrence, 20/04/22
+*/
+
+// Multiple inclusion protection
+#ifndef WAVEFORM_DIGI_CONDITIONS_TOOL
+#define WAVEFORM_DIGI_CONDITIONS_TOOL
+
+// Include interface class
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "WaveformConditionsTools/IWaveformDigiConditionsTool.h"
+
+// Include Athena stuff
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+#include "StoreGate/ReadCondHandleKey.h"
+
+#include "GaudiKernel/ICondSvc.h"
+#include "Gaudi/Property.h"
+
+// Include Gaudi classes
+#include "GaudiKernel/EventContext.h"
+
+/** This class contains a Tool that reads Waveform digi data and makes it available 
+    to other algorithms. 
+*/
+
+class WaveformDigiConditionsTool: public extends<AthAlgTool, IWaveformDigiConditionsTool> {
+
+ public:
+  //----------Public Member Functions----------//
+  // Structors
+  WaveformDigiConditionsTool(const std::string& type, const std::string& name, const IInterface* parent); //!< Constructor
+  virtual ~WaveformDigiConditionsTool() = default; //!< Destructor
+
+  // Standard Gaudi functions
+  virtual StatusCode initialize() override; //!< Gaudi initialiser
+  virtual StatusCode finalize() override; //!< Gaudi finaliser
+
+  // Methods to return digigitization data
+
+  // Baseline parameters
+  virtual float base_mean(void) const override;
+  virtual float base_mean(const EventContext& ctx) const override;
+
+  virtual float base_rms(void) const override;
+  virtual float base_rms(const EventContext& ctx) const override;
+
+  // Crystal ball parameters
+  virtual float cb_mean(void) const override;
+  virtual float cb_mean(const EventContext& ctx) const override;
+
+  virtual float cb_sigma(void) const override;
+  virtual float cb_sigma(const EventContext& ctx) const override;
+
+  virtual float cb_norm(void) const override;
+  virtual float cb_norm(const EventContext& ctx) const override;
+
+  virtual float cb_alpha(void) const override;
+  virtual float cb_alpha(const EventContext& ctx) const override;
+
+  virtual float cb_n(void) const override;
+  virtual float cb_n(const EventContext& ctx) const override;
+
+
+ private:
+
+  // COOL channel specifier (Calo, VetoNu, Veto, Trigger or Timing, Preshower)
+  Gaudi::Property<std::string> m_detector{this, "Detector", "", "Detector type"};
+
+  // Read Cond Handle
+  SG::ReadCondHandleKey<CondAttrListCollection> m_digiReadKey{this, "DigiReadKey", "/WAVE/Digitization", "Key of digi conditions folder"};
+
+  // COOL channel specifier in channel id
+  int m_cool_channel;
+
+  float get_value(const EventContext& ctx, std::string argument) const;
+
+  enum COOL_Channel {
+    COOL_Calo,
+    COOL_VetoNu,
+    COOL_Veto,
+    COOL_Timing,
+    COOL_Preshower
+  };
+  
+};
+
+//---------------------------------------------------------------------- 
+#endif // WAVEFORM_DIGI_CONDITIONS_TOOL
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformTimingTool.h b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformTimingTool.h
index b69e52b2..63a5b2b6 100644
--- a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformTimingTool.h
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformTimingTool.h
@@ -61,7 +61,7 @@ class WaveformTimingTool: public extends<AthAlgTool, IWaveformTimingTool> {
   SG::ReadCondHandleKey<AthenaAttributeList> m_timingReadKey{this, "TimingReadKey", "/WAVE/DAQ/Timing", "Key of timing folder"};
   SG::ReadCondHandleKey<CondAttrListCollection> m_offsetReadKey{this, "OffsetReadKey", "/WAVE/DAQ/TimingOffset", "Key of timing offset folder"};
 
-  ServiceHandle<ICondSvc> m_condSvc{this, "CondSvc", "CondSvc"};
+  //ServiceHandle<ICondSvc> m_condSvc{this, "CondSvc", "CondSvc"};
 
 };
 
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/components/WaveformConditionsTools_entries.cxx b/Waveform/WaveformConditions/WaveformConditionsTools/src/components/WaveformConditionsTools_entries.cxx
index f694fef6..a37ff174 100644
--- a/Waveform/WaveformConditions/WaveformConditionsTools/src/components/WaveformConditionsTools_entries.cxx
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/components/WaveformConditionsTools_entries.cxx
@@ -1,7 +1,9 @@
 #include "../WaveformRangeTool.h"
 #include "../WaveformTimingTool.h"
 #include "../WaveformCableMappingTool.h"
+#include "../WaveformDigiConditionsTool.h"
 
 DECLARE_COMPONENT( WaveformRangeTool )
 DECLARE_COMPONENT( WaveformTimingTool )
 DECLARE_COMPONENT( WaveformCableMappingTool )
+DECLARE_COMPONENT( WaveformDigiConditionsTool )
-- 
GitLab