From ebaf1d5f2db17618e23fce33e33d8d4cf91a7bac Mon Sep 17 00:00:00 2001 From: Carl Gwilliam <gwilliam@hep.ph.liv.ac.uk> Date: Fri, 18 Feb 2022 18:40:16 +0000 Subject: [PATCH] Update digitisation to have realistic normalisation and baseline. Update reco with --isMC arg to run on digitised MC --- .../CaloDigiAlgs/python/CaloDigiAlgsConfig.py | 4 +++ .../CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx | 7 ++++-- .../CaloDigiAlgs/src/CaloWaveformDigiAlg.h | 6 ++--- .../Reconstruction/scripts/faser_reco.py | 25 +++++++++++++------ .../python/ScintDigiAlgsConfig.py | 14 +++++++---- .../src/ScintWaveformDigiAlg.cxx | 8 +++--- .../ScintDigiAlgs/src/ScintWaveformDigiAlg.h | 3 +++ .../WaveDigiTools/IWaveformDigitisationTool.h | 10 +++++++- .../IWaveformDigitisationTool.icc | 16 +++++++++--- .../src/WaveformDigitisationTool.cxx | 1 + .../src/WaveformReconstructionTool.cxx | 1 + 11 files changed, 70 insertions(+), 25 deletions(-) diff --git a/Calorimeter/CaloDigiAlgs/python/CaloDigiAlgsConfig.py b/Calorimeter/CaloDigiAlgs/python/CaloDigiAlgsConfig.py index cd0c9a45..ce45e625 100644 --- a/Calorimeter/CaloDigiAlgs/python/CaloDigiAlgsConfig.py +++ b/Calorimeter/CaloDigiAlgs/python/CaloDigiAlgsConfig.py @@ -36,6 +36,10 @@ def CaloWaveformDigiCfg(flags, name="CaloWaveformDigiAlg", **kwargs): digiAlg.CB_n = 10 digiAlg.CB_sigma = 4 digiAlg.CB_mean = 820 + digiAlg.CB_norm = 2 + + digiAlg.base_mean = 15000 + digiAlg.base_rms = 3 acc.addEventAlgo(digiAlg) diff --git a/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx b/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx index 8e60aefa..1abfcf9f 100644 --- a/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx +++ b/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.cxx @@ -4,6 +4,7 @@ #include <vector> #include <map> +#include <utility> CaloWaveformDigiAlg::CaloWaveformDigiAlg(const std::string& name, ISvcLocator* pSvcLocator) @@ -30,12 +31,13 @@ CaloWaveformDigiAlg::initialize() { // TODO: Change params compared to scint // m_kernel = new TF1("PDF", " ROOT::Math::crystalball_pdf(x, -0.9, 10, 4, 900)", 0, 1200); - m_kernel = new TF1("PDF", "ROOT::Math::crystalball_pdf(x, [0],[1],[2],[3])", 0, 1200); + m_kernel = new TF1("PDF", "[4] * ROOT::Math::crystalball_pdf(x, [0],[1],[2],[3])", 0, 1200); //m_kernel->SetParameters(-0.25,10,4,900); 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); return StatusCode::SUCCESS; @@ -76,7 +78,8 @@ CaloWaveformDigiAlg::execute(const EventContext& ctx) const { // Digitise the hits CHECK( m_digiTool->digitise<CaloHitCollection>(caloHitHandle.ptr(), - waveformContainerHandle.ptr(), m_kernel) ); + waveformContainerHandle.ptr(), m_kernel, + std::pair<float, float>(m_base_mean, m_base_rms)) ); ATH_MSG_DEBUG("WaveformsHitContainer " << waveformContainerHandle.name() << "' filled with "<< waveformContainerHandle->size() <<" items"); diff --git a/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.h b/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.h index 9de68257..f99d13b5 100644 --- a/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.h +++ b/Calorimeter/CaloDigiAlgs/src/CaloWaveformDigiAlg.h @@ -52,10 +52,10 @@ class CaloWaveformDigiAlg : public AthReentrantAlgorithm { 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"}; /// Kernel PDF TF1* m_kernel; diff --git a/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py b/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py index 9810f960..1579f4c1 100755 --- a/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py +++ b/Control/CalypsoExample/Reconstruction/scripts/faser_reco.py @@ -30,6 +30,9 @@ parser.add_argument("-v", "--verbose", action='store_true', help="Turn on DEBUG output") parser.add_argument("--clusterFit", action='store_true', help="Use ClusterFit (old) track finder - default: SegmentFit(new)") +parser.add_argument("--isMC", action='store_true', + help="Running on digitised MC rather than data") + args = parser.parse_args() @@ -86,7 +89,7 @@ from CalypsoConfiguration.AllConfigFlags import ConfigFlags Configurable.configurableRun3Behavior = True # Flags for this job -ConfigFlags.Input.isMC = False # Needed to bypass autoconfig +ConfigFlags.Input.isMC = args.isMC # Needed to bypass autoconfig ConfigFlags.IOVDb.DatabaseInstance = "OFLP200" # Use MC conditions for now ConfigFlags.Input.ProjectName = "data20" @@ -139,8 +142,13 @@ acc.merge(PoolWriteCfg(ConfigFlags)) # # Set up RAW data access -from FaserByteStreamCnvSvc.FaserByteStreamCnvSvcConfig import FaserByteStreamCnvSvcCfg -acc.merge(FaserByteStreamCnvSvcCfg(ConfigFlags)) + +if args.isMC: + from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg + acc.merge(PoolReadCfg(ConfigFlags)) +else: + from FaserByteStreamCnvSvc.FaserByteStreamCnvSvcConfig import FaserByteStreamCnvSvcCfg + acc.merge(FaserByteStreamCnvSvcCfg(ConfigFlags)) # # Needed, or move to MainServicesCfg? @@ -204,11 +212,12 @@ print( "Writing out xAOD objects:" ) print( acc.getEventAlgo("OutputStreamxAOD").ItemList ) # Hack to avoid problem with our use of MC databases when isMC = False -replicaSvc = acc.getService("DBReplicaSvc") -replicaSvc.COOLSQLiteVetoPattern = "" -replicaSvc.UseCOOLSQLite = True -replicaSvc.UseCOOLFrontier = False -replicaSvc.UseGeomSQLite = True +if not args.isMC: + replicaSvc = acc.getService("DBReplicaSvc") + replicaSvc.COOLSQLiteVetoPattern = "" + replicaSvc.UseCOOLSQLite = True + replicaSvc.UseCOOLFrontier = False + replicaSvc.UseGeomSQLite = True # Configure verbosity # ConfigFlags.dump() diff --git a/Scintillator/ScintDigiAlgs/python/ScintDigiAlgsConfig.py b/Scintillator/ScintDigiAlgs/python/ScintDigiAlgsConfig.py index 243e4493..7f2ba853 100644 --- a/Scintillator/ScintDigiAlgs/python/ScintDigiAlgsConfig.py +++ b/Scintillator/ScintDigiAlgs/python/ScintDigiAlgsConfig.py @@ -10,10 +10,10 @@ from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg # 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. dict_CB_param = {} -dict_CB_param["Trigger"]=dict(CB_alpha=-0.38, CB_n=25, CB_mean=815, CB_sigma=7.7) -dict_CB_param["Timing"]=dict(CB_alpha=-0.32, CB_n=65, CB_mean=846, CB_sigma=5.3) # copy from Preshower; Timing was not in TestBeam -dict_CB_param["Veto"]=dict(CB_alpha=-0.38, CB_n=25, CB_mean=815, CB_sigma=7.7) # copy from Trigger; Veto was not in TestBeam, but in sim "Veto" is the TestBeam Trigger component -dict_CB_param["Preshower"]=dict(CB_alpha=-0.32, CB_n=65, CB_mean=846, CB_sigma=5.3) +dict_CB_param["Trigger"]=dict(CB_alpha=-0.38, CB_n=25, CB_mean=815, CB_sigma=7.7, CB_norm = 500 ) +dict_CB_param["Timing"]=dict(CB_alpha=-0.32, CB_n=65, CB_mean=846, CB_sigma=5.3, CB_norm = 500) # copy from Preshower; Timing was not in TestBeam +dict_CB_param["Veto"]=dict(CB_alpha=-0.38, CB_n=25, CB_mean=815, CB_sigma=7.7, CB_norm = 1000) # copy from Trigger; Veto was not in TestBeam, but in sim "Veto" is the TestBeam Trigger component +dict_CB_param["Preshower"]=dict(CB_alpha=-0.32, CB_n=65, CB_mean=846, CB_sigma=5.3, CB_norm = 500) # One stop shopping for normal FASER data def ScintWaveformDigitizationCfg(flags): @@ -46,7 +46,11 @@ def ScintWaveformDigiCfg(flags, name="ScintWaveformDigiAlg", source="", **kwargs 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 = 15000 + digiAlg.base_rms = 3 + kwargs.setdefault("WaveformDigitisationTool", tool) acc.addEventAlgo(digiAlg) diff --git a/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.cxx b/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.cxx index b2508041..91cffd93 100644 --- a/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.cxx +++ b/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.cxx @@ -5,6 +5,7 @@ #include <vector> #include <map> +#include <utility> ScintWaveformDigiAlg::ScintWaveformDigiAlg(const std::string& name, @@ -33,12 +34,12 @@ ScintWaveformDigiAlg::initialize() { - m_kernel = new TF1("PDF", "ROOT::Math::crystalball_pdf(x, [0],[1],[2],[3])", 0, 1200); + 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); return StatusCode::SUCCESS; } @@ -77,7 +78,8 @@ ScintWaveformDigiAlg::execute(const EventContext& ctx) const { // Digitise the hits CHECK( m_digiTool->digitise<ScintHitCollection>(scintHitHandle.ptr(), - waveformContainerHandle.ptr(), m_kernel) ); + waveformContainerHandle.ptr(), m_kernel, + std::pair<float, float>(m_base_mean, m_base_rms)) ); ATH_MSG_DEBUG("WaveformsHitContainer " << waveformContainerHandle.name() << "' filled with "<< waveformContainerHandle->size() <<" items"); diff --git a/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.h b/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.h index af60e02d..9bf7843a 100644 --- a/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.h +++ b/Scintillator/ScintDigiAlgs/src/ScintWaveformDigiAlg.h @@ -54,7 +54,10 @@ class ScintWaveformDigiAlg : public AthReentrantAlgorithm { 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"}; /// Kernel PDF TF1* m_kernel; diff --git a/Waveform/WaveDigiTools/WaveDigiTools/IWaveformDigitisationTool.h b/Waveform/WaveDigiTools/WaveDigiTools/IWaveformDigitisationTool.h index 3e85ff83..7241e816 100644 --- a/Waveform/WaveDigiTools/WaveDigiTools/IWaveformDigitisationTool.h +++ b/Waveform/WaveDigiTools/WaveDigiTools/IWaveformDigitisationTool.h @@ -24,6 +24,9 @@ #include "WaveRawEvent/RawWaveform.h" #include "TF1.h" +#include "TRandom3.h" + +#include <utility> ///Interface for waveform digitisation tools class IWaveformDigitisationTool : virtual public IAlgTool @@ -42,11 +45,16 @@ public: // Digitise HITS to Raw waveform template<class CONT> StatusCode digitise(const CONT* hitCollection, - RawWaveformContainer* waveContainer, TF1* kernel) const; + RawWaveformContainer* waveContainer, + TF1* kernel, std::pair<float, float> base + ) const; private: ServiceHandle<IMessageSvc> m_msgSvc; +protected: + TRandom3* m_random; + }; #include "WaveDigiTools/IWaveformDigitisationTool.icc" diff --git a/Waveform/WaveDigiTools/WaveDigiTools/IWaveformDigitisationTool.icc b/Waveform/WaveDigiTools/WaveDigiTools/IWaveformDigitisationTool.icc index 57d4839b..8d9a466d 100644 --- a/Waveform/WaveDigiTools/WaveDigiTools/IWaveformDigitisationTool.icc +++ b/Waveform/WaveDigiTools/WaveDigiTools/IWaveformDigitisationTool.icc @@ -3,7 +3,8 @@ template<class CONT> StatusCode IWaveformDigitisationTool::digitise(const CONT* hitCollection, - RawWaveformContainer* container, TF1* kernel) const { + RawWaveformContainer* container, TF1* kernel, + std::pair<float, float> base) const { // Check the container @@ -18,12 +19,16 @@ StatusCode IWaveformDigitisationTool::digitise(const CONT* hitCollection, for (unsigned int i=0; i<size; i++) time[i] = 2.*i; std::map<unsigned int, std::vector<uint16_t>> waveforms; - unsigned int baseline = 8000; // TODO: vary this + add noise + //unsigned int baseline = 800; + + // TODO: varying time to centre of edge of bin (odd = centre, even = edge) // Loop over time samples for (const auto& t : time) { std::map<unsigned int, float> counts; + unsigned int baseline = m_random->Gaus(base.first, base.second); + // Convolve hit energy with kernel and sum for each ID (i.e. channel) for (const auto& hit : *hitCollection) { counts[hit.identify()] += kernel->Eval(t) * hit.energyLoss(); @@ -32,7 +37,12 @@ StatusCode IWaveformDigitisationTool::digitise(const CONT* hitCollection, // Add count to correct waveform vec for (const auto& c : counts) { - waveforms[c.first].push_back(baseline - c.second); + int value = baseline - c.second; + if (value < 0) { + log << MSG::WARNING << "Found pulse " << c.second << " larger than baseline " << c.first << endmsg; + value = 0; // Protect against scaling signal above baseline + } + waveforms[c.first].push_back(value); //std::cout << "ADC " << c.first << " @ " << t << ": " << baseline - c.second << std::endl; } } diff --git a/Waveform/WaveDigiTools/src/WaveformDigitisationTool.cxx b/Waveform/WaveDigiTools/src/WaveformDigitisationTool.cxx index e4776da3..1c71fe19 100644 --- a/Waveform/WaveDigiTools/src/WaveformDigitisationTool.cxx +++ b/Waveform/WaveDigiTools/src/WaveformDigitisationTool.cxx @@ -20,6 +20,7 @@ WaveformDigitisationTool::WaveformDigitisationTool(const std::string& type, cons StatusCode WaveformDigitisationTool::initialize() { ATH_MSG_INFO( name() << "::initalize()" ); + m_random = new TRandom3(); return StatusCode::SUCCESS; } diff --git a/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx b/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx index 7e564dae..ce9504ee 100644 --- a/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx +++ b/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx @@ -646,6 +646,7 @@ WaveformReconstructionTool::findRawHitValues(const std::vector<float> time, cons double sum = 0.; double sum2 = 0.; for (unsigned int i=0; i<time.size(); i++) { + //ATH_MSG_DEBUG("findRawHitValues Time: " << time[i] << " Wave: " << wave[i]); tot += wave[i]; sum += time[i] * wave[i]; sum2 += time[i] * time[i] * wave[i]; -- GitLab