From 625d56a0b16976e1dd4651dd1f5fc09acaf17df3 Mon Sep 17 00:00:00 2001
From: Eric Torrence <eric.torrence@cern.ch>
Date: Sat, 13 Mar 2021 05:35:15 +0000
Subject: [PATCH] First commit of scintillator reconstruction code.

Code doesn't actually do anything, but this compiles and give the basic framework
for adding real algorithims.
---
 .../src/ScintWaveformDecoderTool.cxx               |  6 +++---
 .../src/ScintWaveformContainerCnv_p0.cxx           |  6 ++++++
 .../ScintRecAlgs/src/ScintWaveformRecAlg.cxx       | 14 ++++++++++----
 .../ScintRecTools/src/ClockReconstructionTool.cxx  | 13 +++++++++++--
 .../ScintRecTools/src/ClockReconstructionTool.h    |  8 ++++----
 .../src/WaveformReconstructionTool.cxx             |  3 ++-
 6 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx b/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
index 55c9bd96..d7012c13 100644
--- a/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
+++ b/Scintillator/ScintEventCnv/ScintByteStream/src/ScintWaveformDecoderTool.cxx
@@ -100,11 +100,11 @@ ScintWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
   }
 
   if (!digitizer) {
-    ATH_MSG_ERROR("Failed to find TLB fragment in raw event!");
-    return StatusCode::FAILURE;
+    ATH_MSG_WARNING("Failed to find digitizer fragment in raw event!");
+    return StatusCode::SUCCESS;
   }
 
-  // Check validity here
+  // Check validity here, try to continue, as perhaps not all channels are bad
   if (!digitizer->valid()) {
     ATH_MSG_WARNING("Found invalid digitizer fragment:\n" << *digitizer);
   } else {
diff --git a/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformContainerCnv_p0.cxx b/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformContainerCnv_p0.cxx
index 4312a030..55ce336f 100644
--- a/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformContainerCnv_p0.cxx
+++ b/Scintillator/ScintEventCnv/ScintEventAthenaPool/src/ScintWaveformContainerCnv_p0.cxx
@@ -39,6 +39,12 @@ ScintWaveformContainerCnv_p0::transToPers(const ScintWaveformContainer* transCon
 
   log << MSG::DEBUG << "ScintWaveformContainerCnv_p0::transToPers preparing " << transCont->size() << " waveforms" << endmsg;
 
+  // If trans container is empty, nothing else to do
+  if (!transCont->size()) {
+    log << MSG::DEBUG << "ScintWaveformContainerCnv_p0::transToPers found empty container, exiting!" << endmsg;
+    return;
+  }
+
   ScintWaveformCnv_p0 waveformCnv;
 
   typedef ScintWaveformContainer TRANS;
diff --git a/Scintillator/ScintRecAlgs/src/ScintWaveformRecAlg.cxx b/Scintillator/ScintRecAlgs/src/ScintWaveformRecAlg.cxx
index e3d42247..36d05aa3 100644
--- a/Scintillator/ScintRecAlgs/src/ScintWaveformRecAlg.cxx
+++ b/Scintillator/ScintRecAlgs/src/ScintWaveformRecAlg.cxx
@@ -52,9 +52,15 @@ ScintWaveformRecAlg::execute(const EventContext& ctx) const {
 
   // Also find the clock information
   SG::ReadHandle<xAOD::WaveformClock> clockHandle(m_clockKey, ctx);
-
-  ATH_CHECK( clockHandle.isValid() );
-  ATH_MSG_DEBUG("Found ReadHandle for WaveformClock");
+  const xAOD::WaveformClock* clockptr = NULL;
+
+  // Can survive without this, but make a note
+  if ( clockHandle.isValid() ) {
+    ATH_MSG_DEBUG("Found ReadHandle for WaveformClock");
+    clockptr = clockHandle.ptr();
+  } else {
+    ATH_MSG_WARNING("Didn't find ReadHandle for WaveformClock!");
+  }
 
   // Find the output waveform container
   SG::WriteHandle<xAOD::WaveformHitContainer> hitContainerHandle(m_waveformHitContainerKey, ctx);
@@ -69,7 +75,7 @@ ScintWaveformRecAlg::execute(const EventContext& ctx) const {
     ATH_MSG_DEBUG("Reconstruct waveform for channel " << wave->channel());
 
     // Reconstruct the hits, may be more than one, so pass container
-    CHECK( m_recoTool->reconstruct(*wave, clockHandle.ptr(), 
+    CHECK( m_recoTool->reconstruct(*wave, clockptr, 
 				   hitContainerHandle.ptr()) );
 
   }
diff --git a/Scintillator/ScintRecTools/src/ClockReconstructionTool.cxx b/Scintillator/ScintRecTools/src/ClockReconstructionTool.cxx
index 92442bed..15a3e5f3 100644
--- a/Scintillator/ScintRecTools/src/ClockReconstructionTool.cxx
+++ b/Scintillator/ScintRecTools/src/ClockReconstructionTool.cxx
@@ -41,13 +41,22 @@ ClockReconstructionTool::reconstruct(const ScintWaveform& raw_wave,
     return StatusCode::FAILURE;
   }
 
-  // Set the trigger time
+  // Invalid value until we know we are OK
+  clockdata->set_frequency(-1.);
+
+  // Can we determine the actual BCID we triggered in?
   //clockdata->setTriggerTime(raw_wave.trigger_time_tag());
   //ATH_MSG_DEBUG("Trigger time: " << raw_wave.trigger_time_tag());
 
   // Digitized clock data, sampled at 500 MHz (2 ns)
   auto counts = raw_wave.adc_counts();
 
+  // Check that we have some minimal amount of data to work with
+  if (int(counts.size()) <= m_minimumSamples.value()) {
+    ATH_MSG_WARNING("Found clock waveform with length " << counts.size() << "! Not enough data to continue!");
+    return StatusCode::SUCCESS;
+  }
+
   // Need a double array for FFT
   int N = counts.size();
   std::vector<double> wave(N);
@@ -55,7 +64,7 @@ ClockReconstructionTool::reconstruct(const ScintWaveform& raw_wave,
 
   ATH_MSG_DEBUG("Created double array with length " << wave.size() );
   ATH_MSG_DEBUG("First 10 elements:");
-  for (unsigned int i=0; i< 10; i++)
+  for (unsigned int i=0; i < std::min(10, N); i++)
     ATH_MSG_DEBUG(" " << i << " " << wave[i]);
 
   // delta_nu = 1/T where T is the total waveform length
diff --git a/Scintillator/ScintRecTools/src/ClockReconstructionTool.h b/Scintillator/ScintRecTools/src/ClockReconstructionTool.h
index c7f76d6b..0b52229e 100644
--- a/Scintillator/ScintRecTools/src/ClockReconstructionTool.h
+++ b/Scintillator/ScintRecTools/src/ClockReconstructionTool.h
@@ -40,10 +40,10 @@ class ClockReconstructionTool: public extends<AthAlgTool, IClockReconstructionTo
  private:
 
   //
-  // Baseline Estimation Parameters
-  //BooleanProperty m_useSimpleBaseline{this, "UseSimpleBaseline", false};
-  //IntegerProperty m_samplesForBaselineAverage{this, "SamplesForBaselineAverage", 40};
-  //FloatProperty m_baselineFitWindow{this, "BaselineFitWindow", 2.};
+  // Parameters
+
+  /// Minimum samples in the input waveform array to try FFT
+  IntegerProperty m_minimumSamples{this, "MinimumSamples", 40};
 
 };
 
diff --git a/Scintillator/ScintRecTools/src/WaveformReconstructionTool.cxx b/Scintillator/ScintRecTools/src/WaveformReconstructionTool.cxx
index 037cde51..65737116 100644
--- a/Scintillator/ScintRecTools/src/WaveformReconstructionTool.cxx
+++ b/Scintillator/ScintRecTools/src/WaveformReconstructionTool.cxx
@@ -206,8 +206,9 @@ WaveformReconstructionTool::reconstruct(const ScintWaveform& raw_wave,
 
     //
     // Find time from clock
-    if (!clock) {
+    if (!clock || (clock->frequency() <= 0.)) {
       hit->set_status_bit(xAOD::WaveformStatus::CLOCK_INVALID);
+      hit->set_bcid_time(-1.);
     } else {
       hit->set_bcid_time(clock->time_from_clock(hit->localtime()));
     }
-- 
GitLab