From 56a4e7c733c12e4013c9e763034c9dbfbe607cfc Mon Sep 17 00:00:00 2001
From: Nairit Sur <nairit.sur@cern.ch>
Date: Tue, 11 Oct 2022 16:35:26 +0200
Subject: [PATCH 1/3] Fix to select correct first sample of digits for raw
 channel building

---
 .../LArROD/python/LArNNChannelBuilder.py      |  3 ++-
 .../python/LArRawChannelBuilderAlgConfig.py   |  2 +-
 .../LArROD/src/LArNNRawChannelBuilder.cxx     | 20 +++++++++++++++----
 .../LArROD/src/LArRawChannelBuilderAlg.cxx    | 12 ++++++-----
 4 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/LArCalorimeter/LArROD/python/LArNNChannelBuilder.py b/LArCalorimeter/LArROD/python/LArNNChannelBuilder.py
index 0bde848020b5..3604563ad3bc 100644
--- a/LArCalorimeter/LArROD/python/LArNNChannelBuilder.py
+++ b/LArCalorimeter/LArROD/python/LArNNChannelBuilder.py
@@ -11,7 +11,8 @@ def LArNNRawChannelBuilderCfg(configFlags, name="LArNNRawChannelBuilder", **kwar
 
     acc = LArADC2MeVCondAlgCfg(configFlags)
 
-    kwargs.setdefault("firstSample", configFlags.LAr.ROD.FirstSample)
+    # the NN always requires 1 sample in the past
+    kwargs.setdefault("firstSample", (configFlags.LAr.ROD.nPreceedingSamples-1) if configFlags.LAr.ROD.nPreceedingSamples!=0 else configFlags.LAr.ROD.FirstSample)
 
     if configFlags.Input.isMC:
         kwargs.setdefault("LArRawChannelKey", "LArRawChannels")
diff --git a/LArCalorimeter/LArROD/python/LArRawChannelBuilderAlgConfig.py b/LArCalorimeter/LArROD/python/LArRawChannelBuilderAlgConfig.py
index e85901a6be0d..773b1eebc9a7 100644
--- a/LArCalorimeter/LArROD/python/LArRawChannelBuilderAlgConfig.py
+++ b/LArCalorimeter/LArROD/python/LArRawChannelBuilderAlgConfig.py
@@ -11,7 +11,7 @@ def LArRawChannelBuilderAlgCfg(configFlags, **kwargs):
     acc = LArADC2MeVCondAlgCfg(configFlags)
 
     kwargs.setdefault("name", "LArRawChannelBuilder")
-    kwargs.setdefault("firstSample", configFlags.LAr.ROD.FirstSample)
+    kwargs.setdefault("firstSample", configFlags.LAr.ROD.nPreceedingSamples if configFlags.LAr.ROD.nPreceedingSamples!=0 else configFlags.LAr.ROD.FirstSample)
     obj = "AthenaAttributeList"
     dspkey = 'Run2DSPThresholdsKey'
     from IOVDbSvc.IOVDbSvcConfig import addFolders
diff --git a/LArCalorimeter/LArROD/src/LArNNRawChannelBuilder.cxx b/LArCalorimeter/LArROD/src/LArNNRawChannelBuilder.cxx
index 77049e618c96..e9a991eb6e94 100644
--- a/LArCalorimeter/LArROD/src/LArNNRawChannelBuilder.cxx
+++ b/LArCalorimeter/LArROD/src/LArNNRawChannelBuilder.cxx
@@ -93,7 +93,19 @@ StatusCode LArNNRawChannelBuilder::execute(const EventContext& ctx) const {
     ATH_MSG_VERBOSE("Working on channel " << m_onlineId->channel_name(id));
 
     const std::vector<short>& samples = digit->samples();
-    const size_t nSamples = samples.size();
+    const size_t nSamples = 5; //hardcoded as the network always uses 5 samples
+
+    if ( (samples.size() - m_firstSample) < nSamples) {
+      ATH_MSG_ERROR("mismatched effective sample size: "<< samples.size() - m_firstSample << ", must be > " << nSamples); 
+      return StatusCode::FAILURE;
+    }
+
+    //The following creates a sub-sample vector of the correct size to be passed on to the NN
+    std::vector<short>subsamples(nSamples, 0.0);
+    for (size_t i = m_firstSample; i < m_firstSample+nSamples; ++i) {
+      subsamples.push_back(samples[i]);
+    }
+
     const int gain = digit->gain();
     const float p = peds->pedestal(id, gain);
 
@@ -122,8 +134,8 @@ StatusCode LArNNRawChannelBuilder::execute(const EventContext& ctx) const {
     // Check saturation AND discount pedestal
     std::vector<float>samp_no_ped(nSamples, 0.0);
     for (size_t i = 0; i < nSamples; ++i) {
-      if (samples[i] == 4096 || samples[i] == 0) saturated = true;
-      samp_no_ped[i] = samples[i]-p;
+      if (subsamples[i] == 4096 || subsamples[i] == 0) saturated = true;
+      samp_no_ped[i] = subsamples[i]-p;
     }
 
     // LWTNN configuration
@@ -139,7 +151,7 @@ StatusCode LArNNRawChannelBuilder::execute(const EventContext& ctx) const {
 
     nn_in.clear();
 
-    for (auto d : samples) {
+    for (auto d : subsamples) {
 
       nn_in.push_back((d-p)/4096.0);
 
diff --git a/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx b/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
index 7d9ffb29baa3..05de0ae4ef2e 100644
--- a/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
+++ b/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
@@ -115,6 +115,7 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
     }
   }
 
+  size_t firstSample=m_firstSample;
   //Loop over digits:
   for (const LArDigit* digit : *inputContainer) {
 
@@ -125,7 +126,6 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
     ATH_MSG_VERBOSE("Working on channel " << m_onlineId->channel_name(id));
 
     const std::vector<short>& samples=digit->samples();
-    const size_t nSamples=samples.size();
     const int gain=digit->gain();
     const float p=peds->pedestal(id,gain);
    
@@ -134,12 +134,15 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
     //The following autos will resolve either into vectors or vector-proxies
     const auto& ofca=ofcs->OFC_a(id,gain);
     const auto& adc2mev=adc2MeVs->ADC2MEV(id,gain);
+
+    // ensure that the size of the samples vector is compatible with ofc_a when preceeding samples are saved  
+    const size_t nSamples=firstSample>0 && (samples.size()-firstSample)>=ofca.size() ? ofca.size() : samples.size()-firstSample;
     
     //Sanity check on input conditions data:
     // FIXME: fix to get splash test running, should implement the iterations later
     size_t len=nSamples;
     if(!m_isSC && ATH_UNLIKELY(ofca.size()<nSamples)) {
-      if (!connected) continue; //No conditions for disconencted channel, who cares?
+      if (!connected) continue; //No conditions for disconnected channel, who cares?
       ATH_MSG_DEBUG("Number of OFC a's doesn't match number of samples for conencted channel " << m_onlineId->channel_name(id) 
 		    << " gain " << gain << ". OFC size=" << ofca.size() << ", nbr ADC samples=" << nSamples);
       len=ofca.size();
@@ -172,8 +175,8 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
     // Check saturation AND discount pedestal
     std::vector<float> samp_no_ped(nSamples,0.0);
     for (size_t i=0;i<nSamples;++i) {
-      if (samples[i]==4096 || samples[i]==0) saturated=true;
-      samp_no_ped[i]=samples[i]-p;
+      if (samples[i+firstSample]==4096 || samples[i+firstSample]==0) saturated=true; //choose the correct first sample
+      samp_no_ped[i]=samples[i+firstSample]-p;
     }
     if (!m_isSC){
       for (size_t i=0;i<len;++i) {
@@ -237,7 +240,6 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
       const auto& fullShape=shapes->Shape(id,gain);
       
       //Get Q-factor
-      size_t firstSample=m_firstSample;
       // fixing HEC to move +1 in case of 4 samples and firstSample 0 (copied from old LArRawChannelBuilder)
       if (fullShape.size()>nSamples && nSamples==4 && m_firstSample==0) {
 	if (m_onlineId->isHECchannel(id)) {
-- 
GitLab


From 9b6ba0800d69c49293b572f9724a094691aebdaf Mon Sep 17 00:00:00 2001
From: Nairit Sur <nairit.sur@cern.ch>
Date: Thu, 13 Oct 2022 18:28:44 +0200
Subject: [PATCH 2/3] Revert back to upstream/master

---
 .../LArROD/python/LArNNChannelBuilder.py      |  5 ++---
 .../python/LArRawChannelBuilderAlgConfig.py   |  2 +-
 .../LArROD/src/LArNNRawChannelBuilder.cxx     | 20 ++++---------------
 .../LArROD/src/LArRawChannelBuilderAlg.cxx    | 12 +++++------
 4 files changed, 12 insertions(+), 27 deletions(-)

diff --git a/LArCalorimeter/LArROD/python/LArNNChannelBuilder.py b/LArCalorimeter/LArROD/python/LArNNChannelBuilder.py
index 3604563ad3bc..3862aa22a6bd 100644
--- a/LArCalorimeter/LArROD/python/LArNNChannelBuilder.py
+++ b/LArCalorimeter/LArROD/python/LArNNChannelBuilder.py
@@ -11,8 +11,7 @@ def LArNNRawChannelBuilderCfg(configFlags, name="LArNNRawChannelBuilder", **kwar
 
     acc = LArADC2MeVCondAlgCfg(configFlags)
 
-    # the NN always requires 1 sample in the past
-    kwargs.setdefault("firstSample", (configFlags.LAr.ROD.nPreceedingSamples-1) if configFlags.LAr.ROD.nPreceedingSamples!=0 else configFlags.LAr.ROD.FirstSample)
+    kwargs.setdefault("firstSample", configFlags.LAr.ROD.FirstSample)
 
     if configFlags.Input.isMC:
         kwargs.setdefault("LArRawChannelKey", "LArRawChannels")
@@ -59,4 +58,4 @@ def LArNNRawChannelBuilderCfg(configFlags, name="LArNNRawChannelBuilder", **kwar
        
         acc.addEventAlgo(CompFactory.LArNNRawChannelBuilder(name, **kwargs))
 
-    return acc
\ No newline at end of file
+    return acc
diff --git a/LArCalorimeter/LArROD/python/LArRawChannelBuilderAlgConfig.py b/LArCalorimeter/LArROD/python/LArRawChannelBuilderAlgConfig.py
index 773b1eebc9a7..e85901a6be0d 100644
--- a/LArCalorimeter/LArROD/python/LArRawChannelBuilderAlgConfig.py
+++ b/LArCalorimeter/LArROD/python/LArRawChannelBuilderAlgConfig.py
@@ -11,7 +11,7 @@ def LArRawChannelBuilderAlgCfg(configFlags, **kwargs):
     acc = LArADC2MeVCondAlgCfg(configFlags)
 
     kwargs.setdefault("name", "LArRawChannelBuilder")
-    kwargs.setdefault("firstSample", configFlags.LAr.ROD.nPreceedingSamples if configFlags.LAr.ROD.nPreceedingSamples!=0 else configFlags.LAr.ROD.FirstSample)
+    kwargs.setdefault("firstSample", configFlags.LAr.ROD.FirstSample)
     obj = "AthenaAttributeList"
     dspkey = 'Run2DSPThresholdsKey'
     from IOVDbSvc.IOVDbSvcConfig import addFolders
diff --git a/LArCalorimeter/LArROD/src/LArNNRawChannelBuilder.cxx b/LArCalorimeter/LArROD/src/LArNNRawChannelBuilder.cxx
index e9a991eb6e94..77049e618c96 100644
--- a/LArCalorimeter/LArROD/src/LArNNRawChannelBuilder.cxx
+++ b/LArCalorimeter/LArROD/src/LArNNRawChannelBuilder.cxx
@@ -93,19 +93,7 @@ StatusCode LArNNRawChannelBuilder::execute(const EventContext& ctx) const {
     ATH_MSG_VERBOSE("Working on channel " << m_onlineId->channel_name(id));
 
     const std::vector<short>& samples = digit->samples();
-    const size_t nSamples = 5; //hardcoded as the network always uses 5 samples
-
-    if ( (samples.size() - m_firstSample) < nSamples) {
-      ATH_MSG_ERROR("mismatched effective sample size: "<< samples.size() - m_firstSample << ", must be > " << nSamples); 
-      return StatusCode::FAILURE;
-    }
-
-    //The following creates a sub-sample vector of the correct size to be passed on to the NN
-    std::vector<short>subsamples(nSamples, 0.0);
-    for (size_t i = m_firstSample; i < m_firstSample+nSamples; ++i) {
-      subsamples.push_back(samples[i]);
-    }
-
+    const size_t nSamples = samples.size();
     const int gain = digit->gain();
     const float p = peds->pedestal(id, gain);
 
@@ -134,8 +122,8 @@ StatusCode LArNNRawChannelBuilder::execute(const EventContext& ctx) const {
     // Check saturation AND discount pedestal
     std::vector<float>samp_no_ped(nSamples, 0.0);
     for (size_t i = 0; i < nSamples; ++i) {
-      if (subsamples[i] == 4096 || subsamples[i] == 0) saturated = true;
-      samp_no_ped[i] = subsamples[i]-p;
+      if (samples[i] == 4096 || samples[i] == 0) saturated = true;
+      samp_no_ped[i] = samples[i]-p;
     }
 
     // LWTNN configuration
@@ -151,7 +139,7 @@ StatusCode LArNNRawChannelBuilder::execute(const EventContext& ctx) const {
 
     nn_in.clear();
 
-    for (auto d : subsamples) {
+    for (auto d : samples) {
 
       nn_in.push_back((d-p)/4096.0);
 
diff --git a/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx b/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
index 05de0ae4ef2e..7d9ffb29baa3 100644
--- a/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
+++ b/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
@@ -115,7 +115,6 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
     }
   }
 
-  size_t firstSample=m_firstSample;
   //Loop over digits:
   for (const LArDigit* digit : *inputContainer) {
 
@@ -126,6 +125,7 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
     ATH_MSG_VERBOSE("Working on channel " << m_onlineId->channel_name(id));
 
     const std::vector<short>& samples=digit->samples();
+    const size_t nSamples=samples.size();
     const int gain=digit->gain();
     const float p=peds->pedestal(id,gain);
    
@@ -134,15 +134,12 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
     //The following autos will resolve either into vectors or vector-proxies
     const auto& ofca=ofcs->OFC_a(id,gain);
     const auto& adc2mev=adc2MeVs->ADC2MEV(id,gain);
-
-    // ensure that the size of the samples vector is compatible with ofc_a when preceeding samples are saved  
-    const size_t nSamples=firstSample>0 && (samples.size()-firstSample)>=ofca.size() ? ofca.size() : samples.size()-firstSample;
     
     //Sanity check on input conditions data:
     // FIXME: fix to get splash test running, should implement the iterations later
     size_t len=nSamples;
     if(!m_isSC && ATH_UNLIKELY(ofca.size()<nSamples)) {
-      if (!connected) continue; //No conditions for disconnected channel, who cares?
+      if (!connected) continue; //No conditions for disconencted channel, who cares?
       ATH_MSG_DEBUG("Number of OFC a's doesn't match number of samples for conencted channel " << m_onlineId->channel_name(id) 
 		    << " gain " << gain << ". OFC size=" << ofca.size() << ", nbr ADC samples=" << nSamples);
       len=ofca.size();
@@ -175,8 +172,8 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
     // Check saturation AND discount pedestal
     std::vector<float> samp_no_ped(nSamples,0.0);
     for (size_t i=0;i<nSamples;++i) {
-      if (samples[i+firstSample]==4096 || samples[i+firstSample]==0) saturated=true; //choose the correct first sample
-      samp_no_ped[i]=samples[i+firstSample]-p;
+      if (samples[i]==4096 || samples[i]==0) saturated=true;
+      samp_no_ped[i]=samples[i]-p;
     }
     if (!m_isSC){
       for (size_t i=0;i<len;++i) {
@@ -240,6 +237,7 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
       const auto& fullShape=shapes->Shape(id,gain);
       
       //Get Q-factor
+      size_t firstSample=m_firstSample;
       // fixing HEC to move +1 in case of 4 samples and firstSample 0 (copied from old LArRawChannelBuilder)
       if (fullShape.size()>nSamples && nSamples==4 && m_firstSample==0) {
 	if (m_onlineId->isHECchannel(id)) {
-- 
GitLab


From cd6888c5d99b9844c02b081517d03fc57ae3b2f2 Mon Sep 17 00:00:00 2001
From: Nairit Sur <nairit.sur@cern.ch>
Date: Mon, 7 Nov 2022 19:54:26 +0100
Subject: [PATCH 3/3] fix indices of shape derivative for non-zero firstSample

---
 LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx b/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
index 96951b1b2460..fec9ef6c0313 100644
--- a/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
+++ b/LArCalorimeter/LArROD/src/LArRawChannelBuilderAlg.cxx
@@ -217,10 +217,10 @@ StatusCode LArRawChannelBuilderAlg::execute(const EventContext& ctx) const {
       double q=0;
       if (m_useShapeDer) {
 	const auto& fullshapeDer=shapes->ShapeDer(id,gain);
-	if (ATH_UNLIKELY(fullshapeDer.size()<nSamples+firstSample)) {
+	if (ATH_UNLIKELY(fullshapeDer.size()<nOFC+firstSample)) {
 	  ATH_MSG_ERROR("No valid shape derivative for channel " <<  m_onlineId->channel_name(id) 
 			<< " gain " << gain);
-	  ATH_MSG_ERROR("Got size " << fullshapeDer.size() << ", expected at least " << nSamples+firstSample);
+	  ATH_MSG_ERROR("Got size " << fullshapeDer.size() << ", expected at least " << nOFC+firstSample);
 	  return StatusCode::FAILURE;
 	}
 
-- 
GitLab