diff --git a/Control/CalypsoExample/Reconstruction/CMakeLists.txt b/Control/CalypsoExample/Reconstruction/CMakeLists.txt
index dddd2f621013501750a82d0569e2714bbb20c9db..4bccc2d7de74eca17c5dada36a81dac720664028 100644
--- a/Control/CalypsoExample/Reconstruction/CMakeLists.txt
+++ b/Control/CalypsoExample/Reconstruction/CMakeLists.txt
@@ -20,7 +20,16 @@ atlas_install_scripts( scripts/*.sh scripts/*.py )
 atlas_add_test( ProdRecoTI12
     SCRIPT scripts/faser_reco.py ${CMAKE_CURRENT_SOURCE_DIR}/../rawdata/Faser-Physics-001920-filtered.raw TI12Data
     PROPERTIES TIMEOUT 300 )
+
 atlas_add_test( ProdRecoTestBeam
     SCRIPT scripts/faser_reco.py ${CMAKE_CURRENT_SOURCE_DIR}/../RAWDATA/Faser-Physics-003613-filtered.raw TestBeamData
     PROPERTIES TIMEOUT 300 )
 
+atlas_add_test( ProdRecoPilotTracks
+    SCRIPT scripts/faser_reco.py ${CMAKE_CURRENT_SOURCE_DIR}/../RAWDATA/Faser-Physics-pilot_tracks-filtered.raw TI12Data
+    PROPERTIES TIMEOUT 300 )
+
+atlas_add_test( ProdRecoTI12-2022
+    SCRIPT scripts/faser_reco.py ${CMAKE_CURRENT_SOURCE_DIR}/../rawdata/Faser-Physics-006525-filtered.raw TI12Data02
+    PROPERTIES TIMEOUT 300 )
+
diff --git a/Control/CalypsoExample/rawdata/Faser-Physics-006525-filtered.raw b/Control/CalypsoExample/rawdata/Faser-Physics-006525-filtered.raw
new file mode 100644
index 0000000000000000000000000000000000000000..e7e7da6e539a0f05a064c58c1b58d7c6a1081e7e
Binary files /dev/null and b/Control/CalypsoExample/rawdata/Faser-Physics-006525-filtered.raw differ
diff --git a/Control/CalypsoExample/rawdata/Faser-Physics-pilot_tracks-filtered.raw b/Control/CalypsoExample/rawdata/Faser-Physics-pilot_tracks-filtered.raw
new file mode 100644
index 0000000000000000000000000000000000000000..3079490b5b1d0110887cb2a7de7591e0bf2b0cc2
Binary files /dev/null and b/Control/CalypsoExample/rawdata/Faser-Physics-pilot_tracks-filtered.raw differ
diff --git a/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx b/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx
index 50884e7221086392e645855bd885e6f19ee821e0..cc2fca779acd953d177963424389477baa30c856 100644
--- a/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx
+++ b/DetectorDescription/DetDescrCnvSvc/src/DetDescrCnvSvc.cxx
@@ -125,6 +125,8 @@ DetDescrCnvSvc::initialize()     {
     if (status != StatusCode::SUCCESS) return status;
     status =  addToDetStore(55179317, "PreshowerID");
     if (status != StatusCode::SUCCESS) return status;
+    status =  addToDetStore(247779284, "VetoNuID");
+    if (status != StatusCode::SUCCESS) return status;
     status =  addToDetStore(205618430, "FaserSCT_ID");
     if (status != StatusCode::SUCCESS) return status;
     status =  addToDetStore(113753346, "EcalID");
diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetTechnology.h b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetTechnology.h
index 6c0a2b2919f4ef4bc8f16b4519bdd82dbc45bade..0ee1ecc5d64e53a1d5cd0e04ad969421f8344c59 100644
--- a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetTechnology.h
+++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetTechnology.h
@@ -35,20 +35,21 @@ namespace FaserDetDescr {
             fLastFaserNeutrinoTechnology  = 1,
         // Scintillator
             fFirstFaserScintillatorTechnology  = 2,
-            fFaserVeto                         = 2,
-            fFaserTrigger                      = 3,
-            fFaserPreshower                    = 4,
-            fLastFaserScintillatorTechnology   = 4,
+            fFaserVetoNu                       = 2,
+            fFaserVeto                         = 3,
+            fFaserTrigger                      = 4,
+            fFaserPreshower                    = 5,
+            fLastFaserScintillatorTechnology   = 5,
         // Tracker
-            fFirstFaserTrackerTechnology = 5,
-            fFaserSCT                    = 5,
-            fLastFaserTrackerTechnology  = 5,
+            fFirstFaserTrackerTechnology = 6,
+            fFaserSCT                    = 6,
+            fLastFaserTrackerTechnology  = 6,
         // Calorimeter
-            fFirstFaserCalorimeterTechnology    = 6,
-            fFaserECAL                          = 6,
-            fLastFaserCalorimeterTechnology     = 6,
+            fFirstFaserCalorimeterTechnology    = 7,
+            fFaserECAL                          = 7,
+            fLastFaserCalorimeterTechnology     = 7,
         // number of defined detector technologies
-            fNumFaserDetTechnologies    = 7
+            fNumFaserDetTechnologies    = 8
    };
 
 } // end of namespace
diff --git a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h
index 3de4b6428fa65ae333a6bebe92aef8334f78a7b8..3ac1160a9e0c12935f522b0750b09a74fe4d4983 100644
--- a/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h
+++ b/DetectorDescription/FaserDetDescr/FaserDetDescr/FaserDetectorID.h
@@ -82,6 +82,7 @@ public:
     /// @name Scintillator subsystem ids
     //@{
     Identifier          veto            (void) const;
+    Identifier          vetonu          (void) const;
     Identifier          trigger         (void) const;
     Identifier          preshower       (void) const;
     //@}
@@ -157,6 +158,7 @@ public:
     bool                is_calo         (Identifier id) const;
     bool                is_emulsion     (Identifier id) const;
     bool                is_veto         (Identifier id) const;
+    bool                is_vetonu       (Identifier id) const;
     bool                is_trigger      (Identifier id) const;
     bool                is_preshower    (Identifier id) const;
     bool                is_sct          (Identifier id) const;
@@ -172,6 +174,7 @@ public:
     bool                is_calo         (const ExpandedIdentifier& id) const;
     bool                is_emulsion     (const ExpandedIdentifier& id) const;
     bool                is_veto         (const ExpandedIdentifier& id) const;
+    bool                is_vetonu       (const ExpandedIdentifier& id) const;
     bool                is_trigger      (const ExpandedIdentifier& id) const;
     bool                is_preshower    (const ExpandedIdentifier& id) const;
     bool                is_sct          (const ExpandedIdentifier& id) const;
@@ -230,6 +233,7 @@ protected:
 
     /// Scintillator:
     ExpandedIdentifier          veto_exp            (void) const;
+    ExpandedIdentifier          vetonu_exp          (void) const;
     ExpandedIdentifier          trigger_exp         (void) const;
     ExpandedIdentifier          preshower_exp       (void) const;
 
@@ -247,6 +251,7 @@ protected:
     int                 calo_field_value         () const;
     int                 emulsion_field_value     () const;
     int                 veto_field_value         () const;     
+    int                 vetonu_field_value       () const;     
     int                 trigger_field_value      () const;       
     int                 preshower_field_value    () const;       
     int                 sct_field_value          () const;
@@ -306,6 +311,7 @@ private:
     int                 m_CALO_ID;
     int                 m_EMULSION_ID;
     int                 m_VETO_ID;     
+    int                 m_VETONU_ID;     
     int                 m_TRIGGER_ID;       
     int                 m_PRESHOWER_ID;       
     int                 m_SCT_ID;
@@ -382,6 +388,13 @@ FaserDetectorID::veto_exp           (void) const
     return (result << m_VETO_ID);
 }
 
+inline ExpandedIdentifier          
+FaserDetectorID::vetonu_exp           (void) const
+{
+    ExpandedIdentifier result(scint_exp());
+    return (result << m_VETONU_ID);
+}
+
 inline ExpandedIdentifier          
 FaserDetectorID::trigger_exp             (void) const
 {
@@ -428,6 +441,9 @@ FaserDetectorID::emulsion_field_value     () const {return (m_EMULSION_ID);}
 inline int                 
 FaserDetectorID::veto_field_value         () const {return (m_VETO_ID);}     
 
+inline int                 
+FaserDetectorID::vetonu_field_value       () const {return (m_VETONU_ID);}     
+
 inline int                 
 FaserDetectorID::trigger_field_value      () const {return (m_TRIGGER_ID);}       
 
@@ -484,6 +500,16 @@ FaserDetectorID::is_veto       (Identifier id) const
     return result;
 }
 
+inline bool               
+FaserDetectorID::is_vetonu     (Identifier id) const
+{
+    bool result = false;
+    if(is_scint(id)) {
+        result = (m_scint_part_impl.unpack(id) == m_VETONU_ID);
+    }
+    return result;
+}
+
 inline bool               
 FaserDetectorID::is_trigger     (Identifier id) const
 {
diff --git a/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx b/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx
index 9e8dfbb0dcf18ea616c4e35725b28cbb27e8151a..9653eb67aad080822c7354fbc2229a64693f0b1c 100644
--- a/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx
+++ b/DetectorDescription/FaserDetDescr/src/FaserDetectorID.cxx
@@ -44,6 +44,7 @@ FaserDetectorID::FaserDetectorID()
         m_VETO_ID(1),
         m_TRIGGER_ID(2),
         m_PRESHOWER_ID(3),
+	m_VETONU_ID(4),
         m_SCT_ID(1),
         m_ECAL_ID(1),
         m_isSLHC(false),
@@ -79,6 +80,7 @@ FaserDetectorID::FaserDetectorID(const FaserDetectorID& other)
         m_VETO_ID                 (other.m_VETO_ID),
         m_TRIGGER_ID              (other.m_TRIGGER_ID),
         m_PRESHOWER_ID            (other.m_PRESHOWER_ID),
+        m_VETONU_ID               (other.m_VETONU_ID),
         m_SCT_ID                  (other.m_SCT_ID),
         m_ECAL_ID                 (other.m_ECAL_ID),
         m_isSLHC                  (other.m_isSLHC),
@@ -122,6 +124,7 @@ FaserDetectorID::operator= (const FaserDetectorID& other)
         m_VETO_ID               = other.m_VETO_ID;
         m_TRIGGER_ID            = other.m_TRIGGER_ID;
         m_PRESHOWER_ID          = other.m_PRESHOWER_ID;
+        m_VETONU_ID             = other.m_VETONU_ID;
         m_SCT_ID                = other.m_SCT_ID;
         m_ECAL_ID               = other.m_ECAL_ID;
         m_faser_dict            = other.m_faser_dict;
@@ -204,6 +207,16 @@ FaserDetectorID::veto        (void) const
     return (result);
 }
 
+Identifier
+FaserDetectorID::vetonu      (void) const
+{
+    Identifier result((Identifier::value_type)0);
+    // Pack field
+    m_det_impl.pack       (scint_field_value(), result);
+    m_scint_part_impl.pack(m_VETONU_ID, result);
+    return (result);
+}
+
 Identifier
 FaserDetectorID::trigger          (void) const
 {
@@ -444,6 +457,16 @@ FaserDetectorID::is_veto       (const ExpandedIdentifier& id) const
     return result;
 }
 
+bool
+FaserDetectorID::is_vetonu       (const ExpandedIdentifier& id) const
+{
+    bool result = false;
+    if ( is_scint(id) && id.fields() > 1 ){
+        if ( id[1] == m_VETONU_ID ) result = true;
+    }
+    return result;
+}
+
 bool
 FaserDetectorID::is_trigger         (const ExpandedIdentifier& id) const
 {
@@ -729,6 +752,7 @@ FaserDetectorID::initLevelsFromDict(const IdDictMgr& dict_mgr)
     m_VETO_ID               = -1;
     m_TRIGGER_ID            = -1;
     m_PRESHOWER_ID          = -1;
+    m_VETONU_ID             = -1;
     m_SCT_ID                = -1;
     m_ECAL_ID               = -1;
 
@@ -935,6 +959,38 @@ FaserDetectorID::initLevelsFromDict(const IdDictMgr& dict_mgr)
             return (1);
         }
 
+        label = field->find_label("VetoNu");
+        if (label) {
+            if (label->m_valued) {
+                m_VETONU_ID = label->m_value;
+            }
+            else {
+                if(m_msgSvc) {
+                    MsgStream log(m_msgSvc, "FaserDetectorID" );
+                    log << MSG::ERROR << "initLevelsFromDict - label VetoNu does NOT have a value "
+                        << endmsg;
+                }
+                else {
+                    std::cout << "FaserDetectorID::initLevelsFromDict - label VetoNu does NOT have a value "
+                              << std::endl;
+                }
+                return (1);
+            }
+        }
+        else {
+            if(m_msgSvc) {
+                MsgStream log(m_msgSvc, "FaserDetectorID" );
+                log << MSG::ERROR << "initLevelsFromDict - unable to find 'VetoNu' label "
+                    << endmsg;
+            }
+            else {
+                std::cout << "FaserDetectorID::initLevelsFromDict - unable to find 'VetoNu' label "
+                          << std::endl;
+            }
+            return (1);
+        }
+
+
     }
 
     // Initialize ids for Tracker
diff --git a/Event/FaserByteStreamCnvSvcBase/python/FaserByteStreamCnvSvcBaseConfig.py b/Event/FaserByteStreamCnvSvcBase/python/FaserByteStreamCnvSvcBaseConfig.py
index 3a50a75d55c0c2a1e06d6edfa6d900722d5a83c1..3a87cc4c75388ff53954f9a75be77b9c5d1dc9cd 100644
--- a/Event/FaserByteStreamCnvSvcBase/python/FaserByteStreamCnvSvcBaseConfig.py
+++ b/Event/FaserByteStreamCnvSvcBase/python/FaserByteStreamCnvSvcBaseConfig.py
@@ -15,6 +15,7 @@ def FaserByteStreamCnvSvcBaseCfg(flags, **kwargs):
     adxProvider.TypeNames += [
         "RawWaveformContainer/CaloWaveforms",
         "RawWaveformContainer/VetoWaveforms",
+        "RawWaveformContainer/VetoNuWaveforms",
         "RawWaveformContainer/TriggerWaveforms",
         "RawWaveformContainer/PreshowerWaveforms",
         "RawWaveformContainer/ClockWaveforms",
diff --git a/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator.xml b/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator.xml
index 13d77e21372822bd19cbdb4c5b7ae3046d27693f..54552a212ae62ae33650c186ea6529c383524518 100644
--- a/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator.xml
+++ b/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator.xml
@@ -4,6 +4,7 @@
     <label name="Veto" value="1" />
     <label name="Trigger" value="2" />
     <label name="Preshower" value="3" />
+    <label name="VetoNu" value="4" />
   </field>
 
   <region>
@@ -26,4 +27,12 @@
     <range field="plate" minvalue="0" maxvalue="1" />
     <range field="pmt" minvalue="0" maxvalue="0" />
   </region>
-</IdDictionary>
\ No newline at end of file
+
+  <region>
+    <range field="part" value="VetoNu" />
+    <range field="station" minvalue="0" maxvalue="0" />
+    <range field="plate" minvalue="0" maxvalue="1" />
+    <range field="pmt" minvalue="0" maxvalue="0" />
+  </region>
+
+</IdDictionary>
diff --git a/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator_TB00.xml b/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator_TB00.xml
index a4b3f0c98f58f58bf64ef490bf6d6f446bb0256b..71fd8298645674dae3bd0d54c411d099742a6416 100644
--- a/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator_TB00.xml
+++ b/Scintillator/ScintDetDescr/ScintIdDictFiles/data/IdDictScintillator_TB00.xml
@@ -4,8 +4,8 @@
     <label name="Veto" value="1" />
     <label name="Trigger" value="2" />
     <label name="Preshower" value="3" />
+    <label name="VetoNu" value="4" />
   </field>
-
   <region>
     <range field="part" value="Veto" />
     <range field="station" minvalue="0" maxvalue="0" />
@@ -24,4 +24,10 @@
     <range field="plate" minvalue="0" maxvalue="1" />
     <range field="pmt" minvalue="0" maxvalue="0" />
   </region>
-</IdDictionary>
\ No newline at end of file
+  <region>
+    <range field="part" value="VetoNu" />
+    <range field="station" minvalue="0" maxvalue="0" />
+    <range field="plate" minvalue="0" maxvalue="1" />
+    <range field="pmt" minvalue="0" maxvalue="0" />
+  </region>
+</IdDictionary>
diff --git a/Scintillator/ScintDetDescr/ScintIdentifier/CMakeLists.txt b/Scintillator/ScintDetDescr/ScintIdentifier/CMakeLists.txt
index 6dc9408f8ffb04b6a32144d7d03dc338ab9ad8bb..5874ae0de68035f16d71d47887a95cdfb8f857a6 100644
--- a/Scintillator/ScintDetDescr/ScintIdentifier/CMakeLists.txt
+++ b/Scintillator/ScintDetDescr/ScintIdentifier/CMakeLists.txt
@@ -11,6 +11,7 @@ find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
 # Component(s) in the package:
 atlas_add_library( ScintIdentifier
                    src/VetoID.cxx
+		   src/VetoNuID.cxx
                    src/TriggerID.cxx
                    src/PreshowerID.cxx
 #                   src/ScintillatorID.cxx
diff --git a/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/ScintIdentifierDict.h b/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/ScintIdentifierDict.h
index 9f3832c16e73859facfe81aa17f4864cf63a9b19..0968f0b4136d48216bcea7305e4933dac7337e2d 100644
--- a/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/ScintIdentifierDict.h
+++ b/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/ScintIdentifierDict.h
@@ -16,5 +16,6 @@
 #include "ScintIdentifier/PreshowerID.h"
 #include "ScintIdentifier/TriggerID.h"
 #include "ScintIdentifier/VetoID.h"
+#include "ScintIdentifier/VetoNuID.h"
 
 #endif // SCINTIDENTIFIER_SCINTIDENTIFIERDICT_H 
diff --git a/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/VetoNuID.h b/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/VetoNuID.h
new file mode 100644
index 0000000000000000000000000000000000000000..064f9a132378b5cc5740103b402e88d32c48d84d
--- /dev/null
+++ b/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/VetoNuID.h
@@ -0,0 +1,541 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef SCINTIDENTIFIER_VETONUID_H
+#define SCINTIDENTIFIER_VETONUID_H
+/**
+ * @file VetoNuID.h
+ *
+ * @brief This is an Identifier helper class for the VetoNu
+ *  subdetector. This class is a factory for creating compact
+ *  Identifier objects and IdentifierHash or hash ids. And it also
+ *  allows decoding of these ids.
+ *
+ */
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "FaserDetDescr/FaserDetectorID.h"
+#include "Identifier/Identifier.h"
+#include "Identifier/IdentifierHash.h"
+#include "Identifier/Range.h"
+#include "Identifier/IdHelper.h"
+#include "IdDict/IdDictFieldImplementation.h"
+#include "AthenaKernel/CLASS_DEF.h"
+
+#include <string>
+#include <assert.h>
+#include <algorithm>
+
+//<<<<<< PUBLIC DEFINES                                                 >>>>>>
+//<<<<<< PUBLIC CONSTANTS                                               >>>>>>
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+
+class IdDictDictionary;
+
+//<<<<<< PUBLIC VARIABLES                                               >>>>>>
+//<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+
+/**
+ **  @class VetoNuID
+ **  
+ **  @brief This is an Identifier helper class for the VetoNu
+ **  subdetector. This class is a factory for creating compact
+ **  Identifier objects and IdentifierHash or hash ids. And it also
+ **  allows decoding of these ids.
+ **
+ **  Definition and the range of values for the levels of the
+ **  identifier are:
+ **
+ ** @verbatim
+ **    element           range              meaning
+ **    -------           -----              -------
+ **
+ **    station          0 to 1              longitudinal location
+ **    plate            0 to 1              two plates per station
+ **    pmt              0                   single pmt per plate
+ **
+ ** @endverbatim
+ **
+ */
+class VetoNuID : public FaserDetectorID
+{
+public:
+        
+    /// @name public typedefs
+    //@{
+    typedef Identifier::size_type                       size_type; 
+    typedef std::vector<Identifier>::const_iterator     const_id_iterator;
+    typedef MultiRange::const_identifier_factory        const_expanded_id_iterator;
+    //@}
+
+    /// @name strutors
+    //@{
+    VetoNuID(void);
+    virtual ~VetoNuID(void) = default;
+    //@}
+        
+    /// @name Creators for plate ids and pmt ids
+    //@{
+    /// For a single station
+    Identifier  station_id ( int station ) const;
+    Identifier  station_id ( int station,
+                             bool checks) const;
+
+    /// For a station from a plate id
+    Identifier  station_id ( const Identifier& plate_id ) const;
+
+    /// For a single plate
+    Identifier  plate_id ( int station, 
+                           int plate ) const;
+    Identifier  plate_id ( int station, 
+                           int plate,
+                           bool checks) const;
+
+    /// For a single plate from a pmt id
+    Identifier  plate_id ( const Identifier& pmt_id ) const;
+
+    /// From hash - optimized
+    Identifier  plate_id ( IdentifierHash plate_hash ) const;
+
+    /// For an individual pmt
+    Identifier  pmt_id ( int station, 
+                         int plate, 
+                         int pmt ) const; 
+
+    Identifier  pmt_id ( int station, 
+                         int plate, 
+                         int pmt,
+                         bool check ) const; 
+
+    Identifier  pmt_id ( const Identifier& plate_id, 
+                         int pmt ) const;
+
+    //@}
+
+
+    /// @name Hash table maximum sizes
+    //@{
+    size_type   plate_hash_max          (void) const;
+    size_type   pmt_hash_max            (void) const;
+    //@}
+
+    /// @name Access to all ids
+    //@{
+    /// Iterators over full set of ids. Plate iterator is sorted
+    const_id_iterator   plate_begin                     (void) const;
+    const_id_iterator   plate_end                       (void) const;
+    /// For pmt ids, only expanded id iterators are available. Use
+    /// following "pmt_id" method to obtain a compact identifier
+    const_expanded_id_iterator  pmt_begin             (void) const;  
+    const_expanded_id_iterator  pmt_end               (void) const;
+    //@}
+    
+
+    /// @name Optimized accessors  - ASSUMES id IS a vetonu id, i.e. NOT other
+    //@{
+    /// wafer hash from id - optimized
+    IdentifierHash      plate_hash      (Identifier plate_id) const;
+
+    /// Values of different levels (failure returns 0)
+    int         station       (const Identifier& id) const;  
+    int         plate         (const Identifier& id) const; 
+    int         pmt           (const Identifier& id) const; 
+
+    /// Max/Min values for each field (-999 == failure)
+    int         station_max  (const Identifier& id) const;
+    int         plate_max    (const Identifier& id) const;
+    int         pmt_max      (const Identifier& id) const;
+    //@}
+
+    /// @name module navigation
+    //@{
+        /// Previous plate in z
+        int get_prev_in_z(const IdentifierHash& id, IdentifierHash& prev) const;
+        /// Next plate in z
+        int get_next_in_z(const IdentifierHash& id, IdentifierHash& next) const;
+    // /// Previous wafer hash in phi (return == 0 for neighbor found)
+    // int         get_prev_in_phi (const IdentifierHash& id, IdentifierHash& prev) const;
+    // /// Next wafer hash in phi (return == 0 for neighbor found)
+    // int         get_next_in_phi (const IdentifierHash& id, IdentifierHash& next) const;
+    // /// Previous wafer hash in eta (return == 0 for neighbor found)
+    // int         get_prev_in_eta (const IdentifierHash& id, IdentifierHash& prev) const;
+    // /// Next wafer hash in eta (return == 0 for neighbor found)
+    // int         get_next_in_eta (const IdentifierHash& id, IdentifierHash& next) const;
+    // /// Wafer hash on other side
+    // int         get_other_side  (const IdentifierHash& id, IdentifierHash& other) const;
+    
+    // // To check for when phi wrap around may be needed, use
+    // bool        is_phi_module_max(const Identifier& id) const;
+    // /// For the barrel
+    // bool        is_eta_module_min(const Identifier& id) const;
+    // /// For the barrel
+    // bool        is_eta_module_max(const Identifier& id) const;
+    //@}
+
+    /// @name contexts to distinguish plate id from pixel id
+    //@{
+    IdContext   plate_context           (void) const;
+    IdContext   pmt_context             (void) const;
+    //@}
+
+    /// @name methods from abstract interface - slower than opt version
+    //@{
+    /// Create compact id from hash id (return == 0 for OK)
+    virtual int         get_id          (const IdentifierHash& hash_id,
+                                         Identifier& id,
+                                         const IdContext* context = 0) const;
+    
+    /// Create hash id from compact id (return == 0 for OK)
+    virtual int         get_hash        (const Identifier& id, 
+                                         IdentifierHash& hash_id,
+                                         const IdContext* context = 0) const;
+    //@}
+
+    /// Return the lowest bit position used in the channel id
+    int                 base_bit        (void) const;
+
+    /// Calculate a channel offset between the two identifiers.
+    Identifier::diff_type calc_offset(const Identifier& base,
+                                      const Identifier& target) const;
+
+    /// Create an identifier with a given base and channel offset
+    Identifier pmt_id_offset(const Identifier& base,
+                             Identifier::diff_type offset) const;
+
+    /// @name interaction with id dictionary
+    //@{
+    /// Create strip Identifier from expanded id, which is returned by the
+    /// id_iterators
+    Identifier          pmt_id        (const ExpandedIdentifier& pmt_id) const;
+
+    /// Create expanded id from compact id (return == 0 for OK)
+    void                get_expanded_id (const Identifier& id,
+                                         ExpandedIdentifier& exp_id,
+                                         const IdContext* context = 0) const;
+
+    /// Initialization from the identifier dictionary
+    virtual int         initialize_from_dictionary(const IdDictMgr& dict_mgr);
+
+    /// Tests of packing
+    void        test_plate_packing      (void) const;
+    //@}
+    
+private:
+        
+    enum {NOT_VALID_HASH        = 64000};
+
+    typedef std::vector<Identifier>     id_vec;
+    typedef id_vec::const_iterator      id_vec_it;
+    typedef std::vector<unsigned short> hash_vec;
+    typedef hash_vec::const_iterator    hash_vec_it;
+
+    void plate_id_checks ( int station, 
+                           int plate ) const; 
+
+    void pmt_id_checks ( int station, 
+                         int plate, 
+                         int pmt ) const;
+
+
+    int         initLevelsFromDict(void);
+
+    int         init_hashes(void);
+
+    int         init_neighbors(void);
+
+    // Temporary method for adapting an identifier for the MultiRange
+    // check - MR is missing the InnerDetector level
+    // Identifier  idForCheck      (const Identifier& id) const;
+
+    size_type                   m_vetonu_region_index;
+    size_type                   m_SCINT_INDEX;
+    size_type                   m_VETONU_INDEX;
+    size_type                   m_STATION_INDEX;
+    size_type                   m_PLATE_INDEX;
+    size_type                   m_PMT_INDEX;
+
+    const IdDictDictionary*     m_dict;
+    MultiRange                  m_full_plate_range;
+    MultiRange                  m_full_pmt_range;
+    size_type                   m_plate_hash_max;
+    size_type                   m_pmt_hash_max;
+    // Range::field                m_barrel_field;
+    id_vec                      m_plate_vec;
+    hash_vec                    m_prev_z_plate_vec;
+    hash_vec                    m_next_z_plate_vec;
+    // hash_vec                    m_prev_phi_wafer_vec;
+    // hash_vec                    m_next_phi_wafer_vec;
+    // hash_vec                    m_prev_eta_wafer_vec;
+    // hash_vec                    m_next_eta_wafer_vec;   
+    // bool 			m_hasRows	;
+
+    IdDictFieldImplementation   m_scint_impl	;
+    IdDictFieldImplementation   m_vetonu_impl	;
+    IdDictFieldImplementation   m_station_impl	;
+    IdDictFieldImplementation   m_plate_impl	;
+    IdDictFieldImplementation   m_pmt_impl	;
+};
+    
+
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+
+/////////////////////////////////////////////////////////////////////////////
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+/////////////////////////////////////////////////////////////////////////////
+
+//using the macros below we can assign an identifier (and a version)
+//This is required and checked at compile time when you try to record/retrieve
+CLASS_DEF(VetoNuID, 247779284, 1)
+
+//----------------------------------------------------------------------------
+inline Identifier  
+VetoNuID::station_id ( int station, 
+                     bool checks) const
+{
+    
+    // Build identifier
+    Identifier result((Identifier::value_type)0);
+
+    // Pack fields independently
+    m_scint_impl.pack       (scint_field_value(), result);
+    m_vetonu_impl.pack      (vetonu_field_value(),  result);
+    m_station_impl.pack     (station,             result);
+    // Do checks
+    if(checks) 
+    {
+        plate_id_checks ( station, 0 );
+    }
+
+    return result;
+}
+
+inline Identifier  
+VetoNuID::station_id ( int station ) const 
+{
+  return station_id (station, do_checks());
+}
+
+//----------------------------------------------------------------------------
+inline Identifier  
+VetoNuID::station_id ( const Identifier& plate_id ) const
+{
+    Identifier result(plate_id);
+    //  Reset the plate and pmt fields
+    m_plate_impl.reset(result);
+    m_pmt_impl.reset(result);
+    return (result);
+}
+
+//----------------------------------------------------------------------------
+inline Identifier
+VetoNuID::plate_id ( int station,  
+                   int plate, 
+                   bool checks) const
+{
+    // Build identifier
+    Identifier result((Identifier::value_type)0);
+
+    // Pack fields independently
+    m_scint_impl.pack    (scint_field_value(), result);
+    m_vetonu_impl.pack   (vetonu_field_value(),  result);
+    m_station_impl.pack  (station,             result);
+    m_plate_impl.pack    (plate,               result);
+
+    // Do checks
+    if(checks) 
+    {
+        plate_id_checks ( station, plate );
+    }
+    return result;
+}
+
+inline Identifier
+VetoNuID::plate_id ( int station,  
+                   int plate ) const
+{
+  return plate_id (station, plate, do_checks());
+}
+
+//----------------------------------------------------------------------------
+inline Identifier
+VetoNuID::plate_id ( const Identifier& pmt_id ) const
+{
+    Identifier result(pmt_id);
+    // reset the pmt field
+    m_pmt_impl.reset(result);
+    return (result);
+}
+
+//----------------------------------------------------------------------------
+inline Identifier  VetoNuID::plate_id ( IdentifierHash plate_hash ) const
+{
+    return (m_plate_vec[plate_hash]);
+}
+
+//----------------------------------------------------------------------------
+inline IdentifierHash      VetoNuID::plate_hash      (Identifier plate_id) const 
+{
+    // MsgStream log(m_msgSvc, "VetoNuID");
+    // log << MSG::VERBOSE << "m_plate_vec size: " << m_plate_vec.size() << endmsg;
+    // log << MSG::VERBOSE << "input id = " << plate_id << endmsg;
+    // for (size_t i = 0; i < m_plate_vec.size(); i++)
+    // {
+    //     log << MSG::VERBOSE << "Hash = " <<  i << " : ID = " << m_plate_vec[i] << endmsg;
+    // }
+    id_vec_it it = std::lower_bound(m_plate_vec.begin(), 
+                                    m_plate_vec.end(), 
+                                    plate_id);
+    // Require that plate_id matches the one in vector
+    if (it != m_plate_vec.end() && plate_id == (*it)) {
+        return (it - m_plate_vec.begin());
+    }
+    IdentifierHash result;
+    return (result); // return hash in invalid state
+}
+
+//----------------------------------------------------------------------------
+inline Identifier
+VetoNuID::pmt_id ( int station,  
+                 int plate, 
+                 int pmt,
+                 bool checks) const
+{
+    // Build identifier
+    Identifier result((Identifier::value_type)0);
+
+    // Pack fields independently
+    m_scint_impl.pack    (scint_field_value(), result);
+    m_vetonu_impl.pack   (vetonu_field_value(),result);
+    m_station_impl.pack  (station,             result);
+    m_plate_impl.pack    (plate,               result);
+    m_pmt_impl.pack      (pmt,                 result);
+
+    // Do checks
+    if(checks) {
+        pmt_id_checks ( station, plate, pmt );
+    }
+    return result;
+}
+
+inline Identifier
+VetoNuID::pmt_id ( int station,  
+                 int plate, 
+                 int pmt ) const
+{
+  return pmt_id (station, plate, pmt, do_checks());
+}
+
+//----------------------------------------------------------------------------
+inline Identifier               
+VetoNuID::pmt_id        (const ExpandedIdentifier& id) const
+{
+    // Build identifier
+    Identifier result((Identifier::value_type)0);
+
+    // Pack fields independently
+    m_scint_impl.pack    (scint_field_value(),    result);
+    m_vetonu_impl.pack   (vetonu_field_value(),   result);
+    m_station_impl.pack  (id[m_STATION_INDEX],    result);
+    m_plate_impl.pack    (id[m_PLATE_INDEX],      result);
+    m_pmt_impl.pack      (id[m_PMT_INDEX],        result);
+
+    // Do checks
+    if(m_do_checks) 
+    {
+       	pmt_id_checks ( id[m_STATION_INDEX],  
+                          id[m_PLATE_INDEX], 
+                       	  id[m_PMT_INDEX]);    
+    }
+    return result;
+}
+
+//----------------------------------------------------------------------------
+inline Identifier  
+VetoNuID::pmt_id ( const Identifier& plate_id, int pmt ) const
+{
+	// Build identifier
+    Identifier result(plate_id);
+  
+    // Reset strip and then add in value
+    m_pmt_impl.reset   (result);
+ 	m_pmt_impl.pack    (pmt, result);
+  
+    if(m_do_checks)
+    {          
+	    pmt_id_checks ( station(result), 
+		           		plate(result), 
+                        pmt );
+	}
+	return result;
+}
+
+//----------------------------------------------------------------------------
+inline Identifier::diff_type
+VetoNuID::calc_offset(const Identifier& base, const Identifier& target) const
+{
+  Identifier::diff_type tval = static_cast<Identifier::diff_type>(target.get_compact() >> base_bit());
+  Identifier::diff_type bval = static_cast<Identifier::diff_type>(base.get_compact() >> base_bit());
+  return (tval - bval);
+}
+
+//----------------------------------------------------------------------------
+inline Identifier
+VetoNuID::pmt_id_offset(const Identifier& base,
+                        Identifier::diff_type offset) const
+{
+  Identifier::value_type bval = base.get_compact() >> base_bit();
+  return Identifier((bval + offset) << base_bit());
+}
+
+//----------------------------------------------------------------------------
+inline int
+VetoNuID::base_bit ( void ) const
+{
+  int base = static_cast<int>(m_pmt_impl.shift()); // lowest field base
+  return (base > 32) ? 32 : base;
+  // max base is 32 so we can still read old strip id's and differences
+  // from non-SLHC releases.
+}
+
+//----------------------------------------------------------------------------
+inline IdContext        
+VetoNuID::plate_context           (void) const
+{
+    ExpandedIdentifier id;
+    return (IdContext(id, 0, m_PLATE_INDEX));
+}
+
+//----------------------------------------------------------------------------
+inline IdContext        
+VetoNuID::pmt_context   (void) const
+{
+    ExpandedIdentifier id;
+    return (IdContext(id, 0, m_PMT_INDEX));
+}
+
+//----------------------------------------------------------------------------
+inline int 
+VetoNuID::station       (const Identifier& id) const
+{
+    return (m_station_impl.unpack(id));
+}
+
+//----------------------------------------------------------------------------
+inline int 
+VetoNuID::plate     (const Identifier& id) const
+{
+    return (m_plate_impl.unpack(id));
+}
+
+//----------------------------------------------------------------------------
+inline int 
+VetoNuID::pmt           (const Identifier& id) const
+{
+    return (m_pmt_impl.unpack(id));
+}
+
+
+#endif // SCINTIDENTIFIER_VETONUID_H
diff --git a/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/selection.xml b/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/selection.xml
index 543856daa22bebedab8c75cff790f07b7f7468f5..bebeff9ec46d1ef9554a176ba64038033469d21b 100644
--- a/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/selection.xml
+++ b/Scintillator/ScintDetDescr/ScintIdentifier/ScintIdentifier/selection.xml
@@ -3,6 +3,7 @@
   <class name="ScintillatorID" />
 -->
   <class name="VetoID" />
+  <class name="VetoNuID" />
   <class name="TriggerID" />
   <class name="PreshowerID" />
 </lcgdict>
diff --git a/Scintillator/ScintDetDescr/ScintIdentifier/src/VetoNuID.cxx b/Scintillator/ScintDetDescr/ScintIdentifier/src/VetoNuID.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..837b3c892da1ec7a338bd1e6a7c0da18d9eeeeca
--- /dev/null
+++ b/Scintillator/ScintDetDescr/ScintIdentifier/src/VetoNuID.cxx
@@ -0,0 +1,1030 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ Scintillator identifier package
+ -------------------------------------------
+***************************************************************************/
+
+//<<<<<< INCLUDES                                                       >>>>>>
+#include "GaudiKernel/MsgStream.h"
+
+#include "ScintIdentifier/VetoNuID.h"
+#include "Identifier/IdentifierHash.h"
+#include "IdDict/IdDictDefs.h"  
+#include <set>
+#include <algorithm>
+#include <iostream>
+
+//<<<<<< PRIVATE DEFINES                                                >>>>>>
+//<<<<<< PRIVATE CONSTANTS                                              >>>>>>
+//<<<<<< PRIVATE TYPES                                                  >>>>>>
+//<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
+//<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
+//<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
+//<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
+
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+
+VetoNuID::VetoNuID(void)
+        :
+        m_vetonu_region_index(0),
+        m_SCINT_INDEX(0),
+        m_VETONU_INDEX(1),
+        m_STATION_INDEX(2),
+        m_PLATE_INDEX(3),
+        m_PMT_INDEX(4),
+        m_dict(0),
+        m_plate_hash_max(0),
+        m_pmt_hash_max(0)
+{
+}
+
+void
+VetoNuID::plate_id_checks ( int station,  
+                          int plate ) const
+{
+
+    // Check that id is within allowed range
+
+    // Fill expanded id
+    ExpandedIdentifier id;
+    id << scint_field_value() << vetonu_field_value()
+       << station << plate;
+
+    if (!m_full_plate_range.match(id)) {  // module range check is sufficient
+        MsgStream log(m_msgSvc, "VetoNuID");
+        log << MSG::ERROR << " VetoNuID::plate_id result is NOT ok. ID, range "
+            << (std::string)id <<  " " << (std::string)m_full_plate_range << endmsg;
+    }
+}
+
+void
+VetoNuID::pmt_id_checks ( int station,  
+                        int plate, 
+                        int pmt) const
+{
+
+    // Check that id is within allowed range
+
+    // Fill expanded id
+    ExpandedIdentifier id;
+    id << scint_field_value() << vetonu_field_value()
+       << station << plate << pmt;
+
+    if (!m_full_pmt_range.match(id)) {  
+        MsgStream log(m_msgSvc, "VetoNuID");
+        log << MSG::ERROR << " VetoNuID::pmt_id result is NOT ok. ID, range "
+            << (std::string)id << " " << (std::string)m_full_pmt_range << std::endl;
+    }
+}
+
+int 
+VetoNuID::station_max(const Identifier& id) const
+{
+    // get max from dictionary
+    ExpandedIdentifier expId;
+    IdContext plate_context1 = plate_context();
+    get_expanded_id(id, expId, &plate_context1);
+    for (unsigned int i = 0; i < m_full_plate_range.size(); ++i) {
+        const Range& range = m_full_plate_range[i];
+        if (range.match(expId)) {
+            const Range::field& station_field = range[m_STATION_INDEX];
+            if (station_field.has_maximum()) {
+                return (station_field.get_maximum());
+            }
+        }
+    }
+    return (-999);  // default
+}
+
+int     
+VetoNuID::pmt_max       (const Identifier& id) const
+{
+    ExpandedIdentifier expId;
+    IdContext station_context(expId, 0, m_STATION_INDEX);
+    get_expanded_id(id, expId, &station_context);
+    int result = -999;
+    for (unsigned int i = 0; i < m_full_pmt_range.size(); ++i) {
+        const Range& range = m_full_pmt_range[i];
+        if (range.match(expId)) {
+            const Range::field& pmt_field = range[m_PMT_INDEX];
+            if (pmt_field.has_maximum()) {
+                int pmt = pmt_field.get_maximum();
+                if (result < pmt) result = pmt;
+            }
+        }
+    }
+    return (result);
+}
+
+int 
+VetoNuID::plate_max(const Identifier& id) const
+{
+    // get max from dictionary
+    ExpandedIdentifier expId;
+    IdContext plate_context1 = plate_context();
+    get_expanded_id(id, expId, &plate_context1);
+    for (unsigned int i = 0; i < m_full_plate_range.size(); ++i) {
+        const Range& range = m_full_plate_range[i];
+        if (range.match(expId)) {
+            const Range::field& plate_field = range[m_PLATE_INDEX];
+            if (plate_field.has_maximum()) {
+                return (plate_field.get_maximum());
+            }
+        }
+    }
+    return -1;
+}
+
+int
+VetoNuID::initialize_from_dictionary(const IdDictMgr& dict_mgr)
+{
+    MsgStream log(m_msgSvc, "VetoNuID");
+    log << MSG::INFO << "Initialize from dictionary" << endmsg;
+  
+    // Check whether this helper should be reinitialized
+    if (!reinitialize(dict_mgr)) {
+        log << MSG::INFO << "Request to reinitialize not satisfied - tags have not changed" << endmsg;
+        return (0);
+    }
+    else {
+        if (m_msgSvc) {
+            log << MSG::DEBUG << "(Re)initialize" << endmsg;
+        }
+        else {
+            std::cout  << " DEBUG (Re)initialize" << std::endl;
+        }
+    }
+
+    // init base object
+    if(FaserDetectorID::initialize_from_dictionary(dict_mgr)) return (1);
+
+    // Register version of InnerDetector dictionary 
+    if (register_dict_tag(dict_mgr, "Scintillator")) return(1);
+
+    m_dict = dict_mgr.find_dictionary ("Scintillator"); 
+    if(!m_dict) {
+        log << MSG::ERROR << " VetoNuID::initialize_from_dict - cannot access Scintillator dictionary " << endmsg;
+        return 1;
+    }
+
+    // Initialize the field indices
+    if(initLevelsFromDict()) return (1);
+
+    //
+    // Build multirange for the valid set of identifiers
+    //
+
+
+    // Find value for the field Scintillator
+    const IdDictDictionary* faserDict = dict_mgr.find_dictionary ("FASER"); 
+    int scintField   = -1;
+    if (faserDict->get_label_value("subdet", "Scintillator", scintField)) {
+        log << MSG::ERROR << "Could not get value for label 'Scintillator' of field 'subdet' in dictionary " 
+            << faserDict->m_name
+            << endmsg;
+        return (1);
+    }
+
+    // Find value for the field VetoNu
+    int vetonuField   = -1;
+    if (m_dict->get_label_value("part", "VetoNu", vetonuField)) {
+        log << MSG::ERROR << "Could not get value for label 'VetoNu' of field 'part' in dictionary " 
+            << m_dict->m_name
+            << endmsg;
+        return (1);
+    }
+    if (m_msgSvc) {
+        log << MSG::DEBUG << " VetoNuID::initialize_from_dict " 
+            << "Found field values: VetoNu "  
+            << vetonuField
+            << std::endl;
+    }
+    else {
+        std::cout << " DEBUG VetoNuID::initialize_from_dict " 
+                  << "Found field values: VetoNu "  
+                  << vetonuField
+                  << std::endl;
+    }
+    
+    // Set up id for region and range prefix
+    ExpandedIdentifier region_id;
+    region_id.add(scintField);
+    region_id.add(vetonuField);
+    Range prefix;
+    m_full_plate_range = m_dict->build_multirange(region_id, prefix, "plate");
+    m_full_pmt_range = m_dict->build_multirange(region_id, prefix);
+
+    // Setup the hash tables
+    if(init_hashes()) return (1);
+
+    // Setup hash tables for finding neighbors
+    if(init_neighbors()) return (1);
+    
+    if (m_msgSvc) {
+        log << MSG::INFO << " VetoNuID::initialize_from_dict "  << endmsg;
+        log << MSG::DEBUG  
+            << "Plate range -> " << (std::string)m_full_plate_range
+            <<   endmsg;
+        log << MSG::DEBUG
+            << "Pmt range -> " << (std::string)m_full_pmt_range
+            << endmsg;
+    }
+    else {
+        std::cout << " INFO VetoNuID::initialize_from_dict "  << std::endl;
+        std::cout << " DEBUG  Plate range -> " << (std::string)m_full_plate_range
+                  <<   std::endl;
+        std::cout << " DEBUG Pmt range -> " << (std::string)m_full_pmt_range
+                  << std::endl;
+    }
+    
+    return 0;
+}
+
+int
+VetoNuID::init_hashes(void)
+{
+
+    //
+    // create a vector(s) to retrieve the hashes for compact ids. For
+    // the moment, we implement a hash for plates but NOT for pmts
+    //
+    MsgStream log(m_msgSvc, "VetoNuID");
+    // plate hash
+    m_plate_hash_max = m_full_plate_range.cardinality();
+    m_plate_vec.resize(m_plate_hash_max);
+    unsigned int nids = 0;
+    std::set<Identifier> ids;
+    for (unsigned int i = 0; i < m_full_plate_range.size(); ++i) {
+        const Range& range = m_full_plate_range[i];
+        Range::const_identifier_factory first = range.factory_begin();
+        Range::const_identifier_factory last  = range.factory_end();
+        for (; first != last; ++first) {
+            const ExpandedIdentifier& exp_id = (*first);
+            Identifier id = plate_id(exp_id[m_STATION_INDEX],
+                                     exp_id[m_PLATE_INDEX]); 
+            if(!(ids.insert(id)).second) {
+                log << MSG::ERROR << " VetoNuID::init_hashes "
+                    << " Error: duplicated id for plate id. nid " << nids
+                    << " compact id " << id.getString()
+                    << " id " << (std::string)exp_id << endmsg;
+                return (1);
+            }
+            nids++;
+        }
+    }
+    if(ids.size() != m_plate_hash_max) {
+        log << MSG::ERROR << " VetoNuID::init_hashes "
+            << " Error: set size NOT EQUAL to hash max. size " << ids.size()
+            << " hash max " << m_plate_hash_max 
+            << endmsg;
+        return (1);
+    }
+
+    nids = 0;
+    std::set<Identifier>::const_iterator first = ids.begin();
+    std::set<Identifier>::const_iterator last  = ids.end();
+    for (; first != last && nids < m_plate_vec.size(); ++first) {
+        m_plate_vec[nids] = (*first);
+        nids++;
+    }
+
+    // pmt hash - we do not keep a vec for the pmts
+    m_pmt_hash_max = m_full_pmt_range.cardinality();
+
+    return (0);
+}
+
+    int
+    VetoNuID::get_prev_in_z(const IdentifierHash& id, IdentifierHash& prev) const
+    {
+        unsigned short index = id;
+        if (index < m_prev_z_plate_vec.size())
+        {
+            if (m_prev_z_plate_vec[index] == NOT_VALID_HASH) return (1);
+            prev = m_prev_z_plate_vec[index];
+            return (0);
+        }
+        return (1);
+    }
+
+    int
+    VetoNuID::get_next_in_z(const IdentifierHash& id, IdentifierHash& next) const
+    {
+        unsigned short index = id;
+        if (index < m_next_z_plate_vec.size())
+        {
+            if (m_next_z_plate_vec[index] == NOT_VALID_HASH) return (1);
+            next = m_next_z_plate_vec[index];
+            return (0);
+        }
+        return (1);
+    }
+
+// int             
+// VetoNuID::get_prev_in_phi(const IdentifierHash& id, IdentifierHash& prev) const
+// {
+//     unsigned short index = id;
+//     if (index < m_prev_phi_wafer_vec.size()) {
+//         if (m_prev_phi_wafer_vec[index] == NOT_VALID_HASH) return (1);
+//         prev =  m_prev_phi_wafer_vec[index];
+//         return (0);
+//     }
+//     return (1);
+// }
+
+// int             
+// VetoNuID::get_next_in_phi(const IdentifierHash& id, IdentifierHash& next) const
+// {
+//     unsigned short index = id;
+//     if (index < m_next_phi_wafer_vec.size()) {
+//         if (m_next_phi_wafer_vec[index] == NOT_VALID_HASH) return (1);
+//         next =  m_next_phi_wafer_vec[index];
+//         return (0);
+//     }
+//     return (1);
+// }
+
+// int             
+// VetoNuID::get_prev_in_eta(const IdentifierHash& id, IdentifierHash& prev) const
+// {
+//     unsigned short index = id;
+//     if (index < m_prev_eta_wafer_vec.size()) {
+//         if (m_prev_eta_wafer_vec[index] == NOT_VALID_HASH) return (1);
+//         prev =  m_prev_eta_wafer_vec[index];
+//         return (0);
+//     }
+//     return (1);
+// }
+
+// int
+// VetoNuID::get_next_in_eta(const IdentifierHash& id, IdentifierHash& next) const
+// {
+//     unsigned short index = id;
+//     if (index < m_next_eta_wafer_vec.size()) {
+//         if (m_next_eta_wafer_vec[index] == NOT_VALID_HASH) return (1);
+//         next =  m_next_eta_wafer_vec[index];
+//         return (0);
+//     }
+//     return (1);
+// }
+
+// int
+// VetoNuID::get_other_side  (const IdentifierHash& hashId, IdentifierHash& other) const
+// {
+//     if (m_dict) {
+//         // get max from dictionary
+//         Identifier id;
+//         IdContext wafer_context1 = wafer_context();
+//         if(!get_id(hashId, id, &wafer_context1)) {
+//             other = side(id) ? hashId - 1 : hashId + 1;
+//             return (0);
+//         }
+//     }
+//     return (1);
+// }
+
+int
+VetoNuID::init_neighbors(void)
+{
+    //
+    // create a vector(s) to retrieve the hashes for compact ids for
+    // plate neighbors.
+    //
+    MsgStream log(m_msgSvc, "VetoNuID");
+
+    m_prev_z_plate_vec.resize(m_plate_hash_max, NOT_VALID_HASH);
+    m_next_z_plate_vec.resize(m_plate_hash_max, NOT_VALID_HASH);
+    for (unsigned int i = 0; i < m_full_plate_range.size(); i++)
+    {
+        const Range& range = m_full_plate_range[i];
+        const Range::field& station_field = range[m_STATION_INDEX];
+        const Range::field& plate_field   = range[m_PLATE_INDEX];
+        Range::const_identifier_factory first = range.factory_begin();
+        Range::const_identifier_factory last  = range.factory_end();
+        for (; first != last; ++first)
+        {
+            const ExpandedIdentifier& exp_id = (*first);
+            ExpandedIdentifier::element_type previous_plate;
+            ExpandedIdentifier::element_type next_plate;
+            ExpandedIdentifier::element_type previous_station;
+            ExpandedIdentifier::element_type next_station;
+            bool pplate = plate_field.get_previous(exp_id[m_PLATE_INDEX], previous_plate);
+            bool nplate = plate_field.get_next    (exp_id[m_PLATE_INDEX], next_plate);
+            bool pstation = station_field.get_previous(exp_id[m_STATION_INDEX], previous_station);
+            bool nstation = station_field.get_next    (exp_id[m_STATION_INDEX], next_station);
+
+            IdContext  pcontext = plate_context();
+
+            IdentifierHash hash_id;
+            Identifier originalId = plate_id(exp_id[m_STATION_INDEX],
+                                             exp_id[m_PLATE_INDEX]);
+
+            if (get_hash(originalId, hash_id, &pcontext)) 
+            {
+                log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get hash, exp/compact "
+                    << show_to_string(originalId, &pcontext)
+                    << " " << (std::string)m_full_plate_range << endmsg;
+                return (1);
+            }
+
+            // index for the subsequent arrays
+            unsigned short index = hash_id;
+            assert (hash_id < m_prev_z_plate_vec.size());
+            assert (hash_id < m_next_z_plate_vec.size());
+            
+            if (pplate) {
+                // Get previous plate hash id
+                ExpandedIdentifier expId = exp_id;
+                expId[m_PLATE_INDEX] = previous_plate;
+                Identifier id = plate_id(expId[m_STATION_INDEX],
+                                         expId[m_PLATE_INDEX]);
+
+                if (get_hash(id, hash_id, &pcontext)) {
+                    log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get previous plate hash, exp/compact " << id.getString() << " " 
+                        << endmsg;
+                    return (1);
+                }
+                m_prev_z_plate_vec[index] = hash_id;
+            }
+            else if (pstation)
+            {
+                ExpandedIdentifier expId = exp_id;
+                expId[m_STATION_INDEX] = previous_station;
+                ExpandedIdentifier stationId;
+                stationId.add(expId[m_SCINT_INDEX]);
+                stationId.add(expId[m_VETONU_INDEX]);
+                stationId.add(previous_station);
+                Range prefix;
+                MultiRange stationPlateRange = m_dict->build_multirange(stationId, prefix, "plate");
+                const Range::field& upstream_plate_field = range[m_PLATE_INDEX];
+                if (upstream_plate_field.has_maximum())
+                {
+                    expId[m_PLATE_INDEX] = upstream_plate_field.get_maximum();
+                    Identifier id = plate_id(expId[m_STATION_INDEX],
+                                             expId[m_PLATE_INDEX]);
+                    if (get_hash(id, hash_id, &pcontext)) {
+                        log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get last plate hash from previous station, exp/compact " << id.getString() << " " 
+                            << endmsg;
+                        return (1);
+                    }
+                    m_prev_z_plate_vec[index] = hash_id;
+                }
+                else
+                {
+                    log << MSG::ERROR << "VetoNuID::init_neighbors - unable to get plate_max for previous station, exp/compact " << originalId.getString() << " "
+                    << endmsg;
+                    return (1);
+                }
+            }
+
+            if (nplate) {
+                // Get next plate hash id
+                ExpandedIdentifier expId = exp_id;
+                expId[m_PLATE_INDEX] = next_plate;
+                Identifier id = plate_id(expId[m_STATION_INDEX],
+                                         expId[m_PLATE_INDEX]);
+
+                if (get_hash(id, hash_id, &pcontext)) {
+                    log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get next plate hash, exp/compact " << id.getString() << " " 
+                        << endmsg;
+                    return (1);
+                }
+                m_next_z_plate_vec[index] = hash_id;
+            }
+            else if (nstation)
+            {
+                ExpandedIdentifier expId = exp_id;
+                expId[m_STATION_INDEX] = next_station;
+                ExpandedIdentifier stationId;
+                stationId.add(expId[m_SCINT_INDEX]);
+                stationId.add(expId[m_VETONU_INDEX]);
+                stationId.add(next_station);
+                Range prefix;
+                MultiRange stationPlateRange = m_dict->build_multirange(stationId, prefix, "plate");
+                const Range::field& downstream_plate_field = range[m_PLATE_INDEX];
+                if (downstream_plate_field.has_minimum())
+                {
+                    expId[m_PLATE_INDEX] = downstream_plate_field.get_minimum();
+                    Identifier id = plate_id(expId[m_STATION_INDEX],
+                                             expId[m_PLATE_INDEX]);
+                    if (get_hash(id, hash_id, &pcontext)) {
+                        log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get previous plate hash from next station, exp/compact " << id.getString() << " " 
+                            << endmsg;
+                        return (1);
+                    }
+                    m_next_z_plate_vec[index] = hash_id;
+                }
+                else
+                {
+                    log << MSG::ERROR << "VetoNuID::init_neighbors - unable to get plate_min for next station, exp/compact " << originalId.getString() << " "
+                    << endmsg;
+                    return (1);
+                }
+            }
+
+        }
+    }
+
+    // m_prev_phi_wafer_vec.resize(m_wafer_hash_max, NOT_VALID_HASH);
+    // m_next_phi_wafer_vec.resize(m_wafer_hash_max, NOT_VALID_HASH);
+    // m_prev_eta_wafer_vec.resize(m_wafer_hash_max, NOT_VALID_HASH);
+    // m_next_eta_wafer_vec.resize(m_wafer_hash_max, NOT_VALID_HASH);
+
+    // for (unsigned int i = 0; i < m_full_wafer_range.size(); ++i) {
+    //     const Range& range = m_full_wafer_range[i];
+    //     const Range::field& phi_field = range[m_PHI_MODULE_INDEX];
+    //     const Range::field& eta_field = range[m_ETA_MODULE_INDEX];
+    //     Range::const_identifier_factory first = range.factory_begin();
+    //     Range::const_identifier_factory last  = range.factory_end();
+    //     for (; first != last; ++first) {
+    //         const ExpandedIdentifier& exp_id = (*first);
+    //         ExpandedIdentifier::element_type previous_phi;
+    //         ExpandedIdentifier::element_type next_phi;
+    //         ExpandedIdentifier::element_type previous_eta;
+    //         ExpandedIdentifier::element_type next_eta;
+    //         bool pphi = phi_field.get_previous(exp_id[m_PHI_MODULE_INDEX], previous_phi);
+    //         bool nphi = phi_field.get_next    (exp_id[m_PHI_MODULE_INDEX], next_phi);
+    //         bool peta = eta_field.get_previous(exp_id[m_ETA_MODULE_INDEX], previous_eta);
+    //         bool neta = eta_field.get_next    (exp_id[m_ETA_MODULE_INDEX], next_eta);
+
+    //         IdContext      wcontext = wafer_context();
+            
+    //         // First get primary hash id
+    //         IdentifierHash hash_id;
+    //         Identifier id = wafer_id(exp_id[m_BARREL_EC_INDEX],
+    //                                  exp_id[m_LAYER_DISK_INDEX], 
+    //                                  exp_id[m_PHI_MODULE_INDEX],
+    //                                  exp_id[m_ETA_MODULE_INDEX],
+    //                                  exp_id[m_SIDE_INDEX]);
+    //         if (get_hash(id, hash_id, &wcontext)) {
+    //             log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get hash, exp/compact "
+    //                 << show_to_string(id, &wcontext)
+    //                 << " " << (std::string)m_full_wafer_range << endmsg;
+    //             return (1);
+    //         }
+
+    //         // index for the subsequent arrays
+    //         unsigned short index = hash_id;
+    //         assert (hash_id < m_prev_phi_wafer_vec.size());
+    //         assert (hash_id < m_next_phi_wafer_vec.size());
+    //         assert (hash_id < m_prev_eta_wafer_vec.size());
+    //         assert (hash_id < m_next_eta_wafer_vec.size());
+            
+    //         if (pphi) {
+    //             // Get previous phi hash id
+    //             ExpandedIdentifier expId = exp_id;
+    //             expId[m_PHI_MODULE_INDEX] = previous_phi;
+    //             Identifier id = wafer_id(expId[m_BARREL_EC_INDEX],
+    //                                      expId[m_LAYER_DISK_INDEX], 
+    //                                      expId[m_PHI_MODULE_INDEX],
+    //                                      expId[m_ETA_MODULE_INDEX],
+    //                                      expId[m_SIDE_INDEX]);
+    //             if (get_hash(id, hash_id, &wcontext)) {
+    //                 log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get previous phi hash, exp/compact " << id.getString() << " " 
+    //                     << endmsg;
+    //                 return (1);
+    //             }
+    //             m_prev_phi_wafer_vec[index] = hash_id;
+    //         }
+            
+    //         if (nphi) {
+    //             // Get next phi hash id
+    //             ExpandedIdentifier expId = exp_id;
+    //             expId[m_PHI_MODULE_INDEX] = next_phi;
+    //             Identifier id = wafer_id(expId[m_BARREL_EC_INDEX],
+    //                                      expId[m_LAYER_DISK_INDEX], 
+    //                                      expId[m_PHI_MODULE_INDEX],
+    //                                      expId[m_ETA_MODULE_INDEX],
+    //                                      expId[m_SIDE_INDEX]);
+    //             if (get_hash(id, hash_id, &wcontext)) {
+    //                 log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get next phi hash, exp/compact " << id.getString() << 
+    //                     " " << MSG::hex << id.getString() << MSG::dec << endmsg;
+    //                 return (1);
+    //             }
+    //             m_next_phi_wafer_vec[index] = hash_id;
+    //         }
+            
+    //         if (peta) {
+    //             // Get previous eta hash id
+    //             ExpandedIdentifier expId = exp_id;
+    //             expId[m_ETA_MODULE_INDEX] = previous_eta;
+    //             Identifier id = wafer_id(expId[m_BARREL_EC_INDEX],
+    //                                      expId[m_LAYER_DISK_INDEX], 
+    //                                      expId[m_PHI_MODULE_INDEX],
+    //                                      expId[m_ETA_MODULE_INDEX],
+    //                                      expId[m_SIDE_INDEX]);
+    //             if (get_hash(id, hash_id, &wcontext)) {
+    //                 log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get previous eta hash, exp/compact " << id.getString() 
+    //                     << " " << std::endl;
+    //                 return (1);
+    //             }
+    //             m_prev_eta_wafer_vec[index] = hash_id;
+    //         }
+            
+    //         if (neta) {
+    //             // Get next eta hash id
+    //             ExpandedIdentifier expId = exp_id;
+    //             expId[m_ETA_MODULE_INDEX] = next_eta;
+    //             Identifier id = wafer_id(expId[m_BARREL_EC_INDEX],
+    //                                      expId[m_LAYER_DISK_INDEX], 
+    //                                      expId[m_PHI_MODULE_INDEX],
+    //                                      expId[m_ETA_MODULE_INDEX],
+    //                                      expId[m_SIDE_INDEX]);
+    //             if (get_hash(id, hash_id, &wcontext)) {
+    //                 log << MSG::ERROR << " VetoNuID::init_neighbors - unable to get next eta hash, exp/compact " << id.getString() 
+    //                     << " " << endmsg;
+    //                 return (1);
+    //             }
+    //             m_next_eta_wafer_vec[index] = hash_id;
+    //         }
+            
+
+//          std::cout << " VetoNuID::init_neighbors "
+//                    << " phi, previous, next " << id[m_PHI_MODULE_INDEX]
+//                    << " " << pphi
+//                    << " " << previous_phi
+//                    << " " << nphi
+//                    << " " << next_phi
+//                    << " eta, previous, next " << id[m_ETA_MODULE_INDEX]
+//                    << " " << peta
+//                    << " " << previous_eta
+//                    << " " << neta
+//                    << " " << next_eta
+//                    << " id " << (std::string)(*first) 
+//                    << std::endl;
+    //     }
+    // }
+    return (0);
+}
+
+
+
+int     
+VetoNuID::initLevelsFromDict()
+{
+
+
+    MsgStream log(m_msgSvc, "VetoNuID");
+    if(!m_dict) {
+        log << MSG::ERROR << " VetoNuID::initLevelsFromDict - dictionary NOT initialized " << endmsg;
+        return (1);
+    }
+    
+    // Find out which identifier field corresponds to each level. Use
+    // names to find each field/leve.
+
+    m_SCINT_INDEX               = 999;
+    m_VETONU_INDEX                = 999;
+    m_STATION_INDEX             = 999;
+    m_PLATE_INDEX               = 999;
+    m_PMT_INDEX                 = 999;    
+
+    // Save index to a VetoNu region for unpacking
+    ExpandedIdentifier id; 
+    id << scint_field_value() << vetonu_field_value();
+    if (m_dict->find_region(id, m_vetonu_region_index)) {
+        log << MSG::ERROR << "VetoNuID::initLevelsFromDict - unable to find vetonu region index: id, reg "  
+            << (std::string)id << " " << m_vetonu_region_index
+            << endmsg;
+        return (1);
+    }
+
+    // Find a VetoNu region
+    IdDictField* field = m_dict->find_field("subdet");
+    if (field) {
+        m_SCINT_INDEX = field->m_index;
+    }
+    else {
+        log << MSG::ERROR << "VetoNuID::initLevelsFromDict - unable to find 'subdet' field "  << endmsg;
+        return (1);
+    }
+    field = m_dict->find_field("part");
+    if (field) {
+        m_VETONU_INDEX = field->m_index;
+    }
+    else {
+        log << MSG::ERROR << "VetoNuID::initLevelsFromDict - unable to find 'part' field "  << endmsg;
+        return (1);
+    }
+    field = m_dict->find_field("station");
+    if (field) {
+        m_STATION_INDEX = field->m_index;
+    }
+    else {
+        log << MSG::ERROR << "VetoNuID::initLevelsFromDict - unable to find 'station' field "   << endmsg;
+        return (1);
+    }
+    field = m_dict->find_field("plate");
+    if (field) {
+        m_PLATE_INDEX = field->m_index;
+    }
+    else {
+        log << MSG::ERROR<< "VetoNuID::initLevelsFromDict - unable to find 'plate' field "  << endmsg;
+        return (1);
+    }
+    field = m_dict->find_field("pmt");
+    if (field) {
+        m_PMT_INDEX = field->m_index;
+    }
+    else {
+        log << MSG::ERROR << "VetoNuID::initLevelsFromDict - unable to find 'pmt' field " << endmsg;    
+        return (1);
+    }
+    
+    // Set the field implementations
+
+    const IdDictRegion& region = *m_dict->m_regions[m_vetonu_region_index];
+
+    m_scint_impl      = region.m_implementation[m_SCINT_INDEX]; 
+    m_vetonu_impl       = region.m_implementation[m_VETONU_INDEX]; 
+    m_station_impl    = region.m_implementation[m_STATION_INDEX]; 
+    m_plate_impl      = region.m_implementation[m_PLATE_INDEX];
+    m_pmt_impl        = region.m_implementation[m_PMT_INDEX]; 
+
+    if (m_msgSvc) {
+        log << MSG::DEBUG << "decode index and bit fields for each level: " << endmsg;
+        log << MSG::DEBUG << "scint    "  << m_scint_impl.show_to_string() << endmsg;
+        log << MSG::DEBUG << "vetonu     "  << m_vetonu_impl.show_to_string() << endmsg; 
+        log << MSG::DEBUG << "station  "  << m_station_impl.show_to_string() << endmsg; 
+        log << MSG::DEBUG << "plate    "  << m_plate_impl.show_to_string() << endmsg; 
+        log << MSG::DEBUG << "pmt      "  << m_pmt_impl.show_to_string() << endmsg; 
+    }
+    else {
+        std::cout << " DEBUG decode index and bit fields for each level: " << std::endl;
+        std::cout << " DEBUG scint    "  << m_scint_impl.show_to_string() << std::endl;
+        std::cout << " DEBUG vetonu     "  << m_vetonu_impl.show_to_string() << std::endl; 
+        std::cout << " DEBUG station  "  << m_station_impl.show_to_string() << std::endl; 
+        std::cout << " DEBUG plate    "  << m_plate_impl.show_to_string() << std::endl;
+        std::cout << " DEBUG pmt      "  << m_pmt_impl.show_to_string() << std::endl; 
+    }
+    
+    std::cout << "scint "  << m_scint_impl.decode_index() << " " 
+              <<   (std::string)m_scint_impl.ored_field() << " " 
+              << std::hex    << m_scint_impl.mask() << " " 
+              << m_scint_impl.zeroing_mask() << " " 
+              << std::dec    << m_scint_impl.shift() << " "
+              << m_scint_impl.bits() << " "
+              << m_scint_impl.bits_offset()
+              << std::endl;
+    std::cout << "vetonu"     << m_vetonu_impl.decode_index() << " " 
+              <<   (std::string)m_vetonu_impl.ored_field() << " " 
+              << std::hex    << m_vetonu_impl.mask() << " " 
+              << m_vetonu_impl.zeroing_mask() << " " 
+              << std::dec    << m_vetonu_impl.shift() << " "
+              << m_vetonu_impl.bits() << " "
+              << m_vetonu_impl.bits_offset()
+              << std::endl;
+    std::cout << "station"<< m_station_impl.decode_index() << " " 
+              <<   (std::string)m_station_impl.ored_field() << " " 
+              << std::hex    << m_station_impl.mask() << " " 
+              << m_station_impl.zeroing_mask() << " " 
+              << std::dec    << m_station_impl.shift() << " "
+              << m_station_impl.bits() << " "
+              << m_station_impl.bits_offset()
+              << std::endl;
+    std::cout << "plate"    << m_plate_impl.decode_index() << " " 
+              <<   (std::string)m_plate_impl.ored_field() << " " 
+              << std::hex    << m_plate_impl.mask() << " " 
+              << m_plate_impl.zeroing_mask() << " " 
+              << std::dec    << m_plate_impl.shift() << " "
+              << m_plate_impl.bits() << " "
+              << m_plate_impl.bits_offset()
+              << std::endl;
+    std::cout << "pmt"   << m_pmt_impl.decode_index() << " " 
+              <<   (std::string)m_pmt_impl.ored_field() << " " 
+              << std::hex    << m_pmt_impl.mask() << " " 
+              << m_pmt_impl.zeroing_mask() << " " 
+              << std::dec    << m_pmt_impl.shift() << " "
+              << m_pmt_impl.bits() << " "
+              << m_pmt_impl.bits_offset()
+              << std::endl;
+
+    return (0);
+}
+
+VetoNuID::size_type       
+VetoNuID::plate_hash_max (void) const
+{
+    return m_plate_hash_max;
+}
+
+VetoNuID::size_type       
+VetoNuID::pmt_hash_max (void) const
+{
+    return m_pmt_hash_max;
+}
+
+VetoNuID::const_id_iterator       VetoNuID::plate_begin             (void) const
+{
+    return (m_plate_vec.begin());
+}
+
+VetoNuID::const_id_iterator       VetoNuID::plate_end               (void) const
+{
+    return (m_plate_vec.end());
+}
+
+VetoNuID::const_expanded_id_iterator      VetoNuID::pmt_begin     (void) const
+{
+    return (m_full_pmt_range.factory_begin());
+}
+
+VetoNuID::const_expanded_id_iterator      VetoNuID::pmt_end       (void) const
+{
+    return (m_full_pmt_range.factory_end());
+}
+
+// From hash get Identifier
+int     
+VetoNuID::get_id          (const IdentifierHash& hash_id,
+                         Identifier& id,
+                         const IdContext* context) const
+{
+
+    int result = 1;
+    id.clear();
+
+    size_t begin = (context) ? context->begin_index(): 0;
+    // cannot get hash if end is 0:
+    size_t end   = (context) ? context->end_index()  : 0; 
+    if (0 == begin) { 
+        // No hashes yet for ids with prefixes
+        if (m_PLATE_INDEX == end) {
+            if (hash_id < (unsigned int)(m_plate_vec.end() - m_plate_vec.begin())) {
+                id = m_plate_vec[hash_id];
+                result = 0;
+            }
+        }
+        else if (m_PMT_INDEX == end) {
+            // Do not know how to calculate strip id from hash yet!!
+            std::cout << "Do not know how to calculate pmt id from hash yet!!" << std::endl;
+        }
+    }
+    return (result);
+}
+
+void
+VetoNuID::get_expanded_id (const Identifier& id,
+                         ExpandedIdentifier& exp_id,
+                         const IdContext* context) const
+{
+    exp_id.clear();
+    exp_id << scint_field_value()
+           << vetonu_field_value()
+           << station(id)
+           << plate(id);
+    if(!context || context->end_index() == m_PMT_INDEX) 
+    {
+       	exp_id << pmt(id);
+    }
+}
+
+int     
+VetoNuID::get_hash        (const Identifier& id, 
+                         IdentifierHash& hash_id,
+                         const IdContext* context) const
+{
+
+    // Get the hash code from either a vec (for plate) or calculate
+    // it (pmts). For the former, we convert to compact and call
+    // get_hash again. For the latter, we calculate the hash from the
+    // Identifier.
+
+    int result = 1;
+    hash_id = 0;
+    size_t begin = (context) ? context->begin_index(): 0;
+    size_t end   = (context) ? context->end_index()  : 0; 
+    if (0 == begin) {
+        // No hashes yet for ids with prefixes
+        if (m_PLATE_INDEX  == end) {
+            hash_id = plate_hash(id);
+            if (hash_id.is_valid()) result = 0;
+        }
+        else if (context && context->end_index() == m_PMT_INDEX) {
+            // Must calculate for strip hash
+            ExpandedIdentifier new_id;
+            get_expanded_id(id, new_id);
+            hash_id =  m_full_pmt_range.cardinalityUpTo(new_id);
+            result = 0;
+        }
+    }
+    return (result);
+}
+
+
+void    
+VetoNuID::test_plate_packing      (void) const
+{
+    MsgStream log(m_msgSvc, "VetoNuID");
+
+    if (m_dict) {
+        
+        int nids = 0;
+        int nerr = 0;
+        IdContext context = plate_context();
+        const_id_iterator first = m_plate_vec.begin();
+        const_id_iterator last  = m_plate_vec.end();
+        for (; first != last; ++first, ++nids) {
+            Identifier id = (*first);
+            ExpandedIdentifier exp_id;
+            get_expanded_id(id, exp_id, &context);
+            Identifier new_id = plate_id(exp_id[m_STATION_INDEX],
+                                         exp_id[m_PLATE_INDEX]);
+            if (id != new_id) {
+                log << MSG::ERROR << "VetoNuID::test_plate_packing: new and old compacts not equal. New/old/expanded ids " 
+                    << MSG::hex << show_to_string(id) << " " << show_to_string(new_id) << " " << MSG::dec 
+                    << (std::string)exp_id << endmsg;
+                nerr++;
+                continue;
+            }
+            // check station id
+            if (!exp_id[m_PLATE_INDEX]) {
+                
+                Identifier new_id1 = station_id(exp_id[m_STATION_INDEX]);
+                if (id != new_id1) {
+                    log << MSG::ERROR << "VetoNuID::test_plate_packing: new and old station ids not equal. New/old/expanded ids " 
+                        << MSG::hex << show_to_string(id) << " " << show_to_string(new_id1) << " " << MSG::dec 
+                        << (std::string)exp_id << endmsg;
+                    nerr++;
+                    continue;
+                }
+            }
+        }
+
+        if (m_msgSvc) { 
+            log << MSG::DEBUG << "VetoNuID::test_plate_packing: tested plate and station ids. nids, errors " 
+                << nids << " " << nerr << endmsg;
+        }
+        else {
+            std::cout << " DEBUG VetoNuID::test_plate_packing: tested plate and station ids. nids, errors " 
+                      << nids << " " << nerr << std::endl;
+        }
+        
+        nids = 0;
+        context = pmt_context();
+        const_expanded_id_iterator      first_vetonu = pmt_begin();  
+        const_expanded_id_iterator      last_vetonu  = pmt_end();
+        for (; first_vetonu != last_vetonu; ++first_vetonu, ++nids) {
+            // if (nids%10000 != 1) continue;
+            const ExpandedIdentifier& exp_id = *first_vetonu;
+            ExpandedIdentifier new_exp_id;
+
+            Identifier id = plate_id(exp_id[m_STATION_INDEX],
+                                     exp_id[m_PLATE_INDEX]);
+            get_expanded_id(id, new_exp_id, &context);
+            if (exp_id[0] != new_exp_id[0] ||
+                exp_id[1] != new_exp_id[1] ||
+                exp_id[2] != new_exp_id[2] ||
+                exp_id[3] != new_exp_id[3])
+            {
+                log << MSG::ERROR << "VetoNuID::test_plate_packing: new and old ids not equal. New/old/compact ids "
+                    << (std::string)new_exp_id << " " << (std::string)exp_id
+                    << " " << show_to_string(id) << endmsg;
+                continue;
+            }
+
+            Identifier pmtid	;
+	        Identifier pmtid1	;
+           	pmtid = pmt_id ( 
+                       exp_id[m_STATION_INDEX],
+					   exp_id[m_PLATE_INDEX],
+					   exp_id[m_PMT_INDEX]);
+
+    	   	pmtid1 = pmt_id (	    
+                        station(pmtid),
+                        plate(pmtid),
+                        pmt(pmtid));
+
+            if (pmtid != pmtid1) {
+                log << MSG::ERROR << "VetoNuID::test_plate_packing: new and old pixel ids not equal. New/old ids "
+                    << " " << show_to_string(pmtid1) << " " 
+                    << show_to_string(pmtid) << endmsg;
+            }
+        }
+
+        if (m_msgSvc) {
+            log << MSG::DEBUG << "VetoNuID::test_plate_packing: Successful tested " 
+                << nids << " ids. " 
+                << endmsg;
+        }
+        else {
+            std::cout << " DEBUG VetoNuID::test_plate_packing: Successful tested " 
+                      << nids << " ids. " 
+                      << std::endl;
+        }
+    }
+    else {
+        log << MSG::ERROR << "VetoNuID::test_plate_packing: Unable to test plate packing - no dictionary has been defined. " 
+            << endmsg;
+    }
+}
+
diff --git a/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/ScintIdCnv_entries.cxx b/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/ScintIdCnv_entries.cxx
index 18719ef20c15237f1febd9b268e819ce2b88f5e5..0b99ec46b38a725159e9ae7f914d7df3b99b2178 100644
--- a/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/ScintIdCnv_entries.cxx
+++ b/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/ScintIdCnv_entries.cxx
@@ -3,6 +3,7 @@
 // #include "SiliconIDDetDescrCnv.h"
 // #include "TRT_IDDetDescrCnv.h"
 #include "VetoIDDetDescrCnv.h"
+#include "VetoNuIDDetDescrCnv.h"
 #include "TriggerIDDetDescrCnv.h"
 #include "PreshowerIDDetDescrCnv.h"
 
@@ -11,5 +12,6 @@
 // DECLARE_CONVERTER(SiliconIDDetDescrCnv)
 // DECLARE_CONVERTER(TRT_IDDetDescrCnv)
 DECLARE_CONVERTER(VetoIDDetDescrCnv)
+DECLARE_CONVERTER(VetoNuIDDetDescrCnv)
 DECLARE_CONVERTER(TriggerIDDetDescrCnv)
 DECLARE_CONVERTER(PreshowerIDDetDescrCnv)
diff --git a/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/VetoNuIDDetDescrCnv.cxx b/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/VetoNuIDDetDescrCnv.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..82d3ab337ed23e70f62dd97bd5be675c656d7244
--- /dev/null
+++ b/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/VetoNuIDDetDescrCnv.cxx
@@ -0,0 +1,239 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ Scint DetDescrCnv package
+ -----------------------------------------
+ ***************************************************************************/
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "VetoNuIDDetDescrCnv.h"
+
+#include "DetDescrCnvSvc/DetDescrConverter.h"
+#include "DetDescrCnvSvc/DetDescrAddress.h"
+#include "GaudiKernel/MsgStream.h"
+#include "StoreGate/StoreGateSvc.h" 
+
+#include "IdDictDetDescr/IdDictManager.h"
+#include "ScintIdentifier/VetoNuID.h"
+
+
+//<<<<<< PRIVATE DEFINES                                                >>>>>>
+//<<<<<< PRIVATE CONSTANTS                                              >>>>>>
+//<<<<<< PRIVATE TYPES                                                  >>>>>>
+//<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
+//<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
+//<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
+//<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
+//<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
+
+//--------------------------------------------------------------------
+
+long int   
+VetoNuIDDetDescrCnv::repSvcType() const
+{
+  return (storageType());
+}
+
+//--------------------------------------------------------------------
+
+StatusCode 
+VetoNuIDDetDescrCnv::initialize()
+{
+    // First call parent init
+    StatusCode sc = DetDescrConverter::initialize();
+    MsgStream log(msgSvc(), "VetoNuIDDetDescrCnv");
+    log << MSG::DEBUG << "in initialize" << endmsg;
+
+    if (sc.isFailure()) {
+        log << MSG::ERROR << "DetDescrConverter::initialize failed" << endmsg;
+	return sc;
+    }
+    
+    // The following is an attempt to "bootstrap" the loading of a
+    // proxy for VetoNuID into the detector store. However,
+    // VetoNuIDDetDescrCnv::initialize is NOT called by the conversion
+    // service.  So for the moment, this cannot be use. Instead the
+    // DetDescrCnvSvc must do the bootstrap from a parameter list.
+
+
+//      // Add Scint_DetDescrManager proxy as entry point to the detector store
+//      // - this is ONLY needed for the manager of each system
+//      sc = addToDetStore(classID(), "VetoNuID");
+//      if (sc.isFailure()) {
+//  	log << MSG::FATAL << "Unable to add proxy for VetoNuID to the Detector Store!" << endmsg;
+//  	return StatusCode::FAILURE;
+//      } else {}
+
+    return StatusCode::SUCCESS; 
+}
+
+//--------------------------------------------------------------------
+
+StatusCode 
+VetoNuIDDetDescrCnv::finalize()
+{
+    MsgStream log(msgSvc(), "VetoNuIDDetDescrCnv");
+    log << MSG::DEBUG << "in finalize" << endmsg;
+
+    return StatusCode::SUCCESS; 
+}
+
+//--------------------------------------------------------------------
+
+StatusCode
+VetoNuIDDetDescrCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) 
+{
+    //StatusCode sc = StatusCode::SUCCESS;
+    MsgStream log(msgSvc(), "VetoNuIDDetDescrCnv");
+    log << MSG::INFO << "in createObj: creating a VetoNuID helper object in the detector store" << endmsg;
+
+    // Create a new VetoNuID
+
+    DetDescrAddress* ddAddr;
+    ddAddr = dynamic_cast<DetDescrAddress*> (pAddr);
+    if(!ddAddr) {
+	log << MSG::FATAL << "Could not cast to DetDescrAddress." << endmsg;
+	return StatusCode::FAILURE;
+    }
+
+    // Get the StoreGate key of this container.
+    std::string helperKey  = *( ddAddr->par() );
+    if ("" == helperKey) {
+	log << MSG::DEBUG << "No Helper key " << endmsg;
+    }
+    else {
+	log << MSG::DEBUG << "Helper key is " << helperKey << endmsg;
+    }
+    
+
+    // get DetectorStore service
+    StoreGateSvc * detStore;
+    StatusCode status = serviceLocator()->service("DetectorStore", detStore);
+    if (status.isFailure()) {
+	log << MSG::FATAL << "DetectorStore service not found !" << endmsg;
+	return StatusCode::FAILURE;
+    } else {}
+ 
+    // Get the dictionary manager from the detector store
+    const DataHandle<IdDictManager> idDictMgr;
+    status = detStore->retrieve(idDictMgr, "IdDict");
+    if (status.isFailure()) {
+	log << MSG::FATAL << "Could not get IdDictManager !" << endmsg;
+	return StatusCode::FAILURE;
+    } 
+    else {
+	log << MSG::DEBUG << " Found the IdDictManager. " << endmsg;
+    }
+
+    // Only create new helper if it is the first pass or if there is a
+    // change in the the file or tag
+    bool initHelper               = false;
+
+    const IdDictMgr* mgr          = idDictMgr->manager();
+
+    // Internal Scint id tag
+    std::string   scintIDTag      = mgr->tag();
+
+    // DoChecks flag
+    bool doChecks                 = mgr->do_checks();
+
+    IdDictDictionary* dict = mgr->find_dictionary("Scintillator");  
+    if (!dict) {
+	log << MSG::ERROR 
+	    << "unable to find idDict for Scintillator" 
+	    << endmsg;
+	return StatusCode::FAILURE;
+    }
+
+    // File to be read for Scint ids
+    std::string   scintIDFileName = dict->file_name();
+
+    // Tag of RDB record for Scint ids
+    std::string   scintIdDictTag  = dict->dict_tag();
+
+
+    if (m_vetonuId) {
+
+	// VetoNu id helper already exists - second pass. Check for a
+	// change 
+	if (scintIDTag != m_scintIDTag) { 
+	    // Internal Scint id tag
+	    initHelper = true;
+	    log << MSG::DEBUG << " Changed internal Scint id tag: " 
+		<< scintIDTag << endmsg;
+	}
+	if (scintIDFileName != m_scintIDFileName) {
+	    // File to be read for Scint ids
+	    initHelper = true;
+	    log << MSG::DEBUG << " Changed ScintFileName:" 
+		<< scintIDFileName << endmsg;
+	}
+	if (scintIdDictTag != m_scintIdDictTag) {
+	    // Tag of RDB record for Scint ids
+	    initHelper = true;
+	    log << MSG::DEBUG << " Changed ScintIdDictTag: "
+		<< scintIdDictTag 
+		<< endmsg;
+	}
+	if (doChecks != m_doChecks) {
+	    // DoChecks flag
+	    initHelper = true;
+	    log << MSG::DEBUG << " Changed doChecks flag: "
+		<< doChecks
+		<< endmsg;
+        }
+    }
+    else {
+	// create the helper
+	m_vetonuId = new VetoNuID;
+	initHelper = true;
+        // add in message service for printout
+        m_vetonuId->setMessageSvc(msgSvc());
+    }
+    
+    if (initHelper) {
+	if (idDictMgr->initializeHelper(*m_vetonuId)) {
+	    log << MSG::ERROR << "Unable to initialize VetoNuID" << endmsg;
+	    return StatusCode::FAILURE;
+	} 
+	// Save state:
+	m_scintIDTag      = scintIDTag;
+	m_scintIDFileName = scintIDFileName;
+	m_scintIdDictTag  = scintIdDictTag;
+	m_doChecks        = doChecks;
+    }
+
+    // Pass a pointer to the container to the Persistency service by reference.
+    pObj = StoreGateSvc::asStorable(m_vetonuId);
+
+    return StatusCode::SUCCESS; 
+
+}
+
+//--------------------------------------------------------------------
+
+long
+VetoNuIDDetDescrCnv::storageType()
+{
+    return DetDescr_StorageType;
+}
+
+//--------------------------------------------------------------------
+const CLID& 
+VetoNuIDDetDescrCnv::classID() { 
+    return ClassID_traits<VetoNuID>::ID(); 
+}
+
+//--------------------------------------------------------------------
+VetoNuIDDetDescrCnv::VetoNuIDDetDescrCnv(ISvcLocator* svcloc) 
+    :
+    DetDescrConverter(ClassID_traits<VetoNuID>::ID(), svcloc),
+    m_vetonuId(0),
+    m_doChecks(false)
+
+{}
+
diff --git a/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/VetoNuIDDetDescrCnv.h b/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/VetoNuIDDetDescrCnv.h
new file mode 100644
index 0000000000000000000000000000000000000000..784d518879aec982ebcb3a96cb73c7e8aded80c8
--- /dev/null
+++ b/Scintillator/ScintDetDescrCnv/ScintIdCnv/src/VetoNuIDDetDescrCnv.h
@@ -0,0 +1,71 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/***************************************************************************
+ Scint DetDescrCnv package
+ -----------------------------------------
+ ***************************************************************************/
+
+#ifndef SCINTIDCNV_VETONUIDDETDESCRCNV_H
+#define SCINTIDCNV_VETONUIDDETDESCRCNV_H
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "DetDescrCnvSvc/DetDescrConverter.h"
+
+//<<<<<< PUBLIC DEFINES                                                 >>>>>>
+//<<<<<< PUBLIC CONSTANTS                                               >>>>>>
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+
+class VetoNuID;
+
+//<<<<<< PUBLIC VARIABLES                                               >>>>>>
+//<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+
+
+/**
+ **  This class is a converter for the VetoNuID an IdHelper which is
+ **  stored in the detector store. This class derives from
+ **  DetDescrConverter which is a converter of the DetDescrCnvSvc.
+ **
+ **/
+
+class VetoNuIDDetDescrCnv: public DetDescrConverter {
+
+public:
+    virtual long int   repSvcType() const;
+    virtual StatusCode initialize();
+    virtual StatusCode finalize();
+    virtual StatusCode createObj(IOpaqueAddress* pAddr, DataObject*& pObj);
+
+    // Storage type and class ID (used by CnvFactory)
+    static long storageType();
+    static const CLID& classID();
+
+    VetoNuIDDetDescrCnv(ISvcLocator* svcloc);
+
+private:
+    /// The helper - only will create it once
+    VetoNuID*       m_vetonuId;
+
+    /// File to be read for Scint ids
+    std::string   m_scintIDFileName;
+
+    /// Tag of RDB record for Scint ids
+    std::string   m_scintIdDictTag;
+
+    /// Internal Scint id tag
+    std::string   m_scintIDTag;
+
+    /// Whether or not 
+    bool          m_doChecks;
+
+};
+
+
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+
+#endif // SCINTIDCNV_VETONUIDDETDESCRCNV_H
diff --git a/Waveform/WaveEventCnv/WaveByteStream/python/WaveByteStreamConfig.py b/Waveform/WaveEventCnv/WaveByteStream/python/WaveByteStreamConfig.py
index b3e1e73042c8d608c68865d1328572b1e5b98955..ad6bfcd1519674674ff7d101e320bc47176198ed 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/python/WaveByteStreamConfig.py
+++ b/Waveform/WaveEventCnv/WaveByteStream/python/WaveByteStreamConfig.py
@@ -2,8 +2,11 @@
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from WaveformConditionsTools.WaveformCableMappingConfig import WaveformCableMappingCfg
+from WaveformConditionsTools.WaveformRangeConfig import WaveformRangeCfg
 
 def WaveByteStreamCfg(configFlags, **kwargs):
-    acc = WaveformCableMappingCfg(configFlags, **kwargs)
+    acc = ComponentAccumulator()
+    acc.merge(WaveformCableMappingCfg(configFlags, **kwargs))
+    acc.merge(WaveformRangeCfg(configFlags, **kwargs))
     return acc
         
diff --git a/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.cxx b/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.cxx
index f3a9f9991fd0d926584727bc7546fb00ea52732d..852ae084edac08380e302ec3026548d667da70c2 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.cxx
+++ b/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.cxx
@@ -43,7 +43,8 @@ StatusCode
 RawWaveformDecoderTool::convert(const DAQFormats::EventFull* re, 
 				RawWaveformContainer* container,
 				const std::string key,
-				WaveformCableMap cable_map
+				WaveformCableMap cable_map,
+				WaveformRangeMap range_map
 )
 {
   ATH_MSG_DEBUG("RawWaveformDecoderTool::convert("+key+")");
@@ -90,6 +91,8 @@ RawWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
     det_type = std::string("calo");
   } else if (key == std::string("VetoWaveforms")) {
     det_type = std::string("veto");
+  } else if (key == std::string("VetoNuWaveforms")) {
+    det_type = std::string("vetonu");
   } else if (key == std::string("TriggerWaveforms")) {
     det_type = std::string("trigger");
   } else if (key == std::string("PreshowerWaveforms")) {
@@ -141,10 +144,13 @@ RawWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
     }
 
     // Set ID if one exists (clock, for instance, doesn't have an identifier)
-    if (cable_map[channel].second != -1) { // Identifier doesn't have operator>=
+    if (cable_map.at(channel).second != -1) { // Identifier doesn't have operator>=
       wfm->setIdentifier(cable_map[channel].second);
     }
 
+    // Set ADC range
+    wfm->setRange(range_map.at(channel));
+
     container->push_back(wfm);    
 
     // Sanity check
diff --git a/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.h b/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.h
index 1609d3ebacd3940bdfcd89f3c1af39b2a0a9c648..5d3ff24600e76a6d37c7e5bb60e0729e36bb71ac 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.h
+++ b/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.h
@@ -14,6 +14,7 @@
 #include "WaveRawEvent/RawWaveformContainer.h"
 
 #include "WaveformConditionsTools/IWaveformCableMappingTool.h"
+#include "WaveformConditionsTools/IWaveformRangeTool.h"
 
 // This class provides conversion between bytestream and Waveform objects
 
@@ -30,7 +31,7 @@ class RawWaveformDecoderTool : public AthAlgTool {
   virtual StatusCode initialize();
   virtual StatusCode finalize();
 
-  StatusCode convert(const DAQFormats::EventFull* re, RawWaveformContainer* wfm, std::string key, WaveformCableMap cable_map);
+  StatusCode convert(const DAQFormats::EventFull* re, RawWaveformContainer* wfm, std::string key, WaveformCableMap cable_map, WaveformRangeMap range_map);
 
 private:
 };
diff --git a/Waveform/WaveEventCnv/WaveByteStream/src/WaveByteStreamCnv.cxx b/Waveform/WaveEventCnv/WaveByteStream/src/WaveByteStreamCnv.cxx
index b40fc3bd8dda5469e52be5d297ad29cf4dc2e98b..38d1cc20c5240277d6a985c2ba8e57d064baa49f 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/src/WaveByteStreamCnv.cxx
+++ b/Waveform/WaveEventCnv/WaveByteStream/src/WaveByteStreamCnv.cxx
@@ -27,6 +27,7 @@ WaveByteStreamCnv::WaveByteStreamCnv(ISvcLocator* svcloc)
   , m_name("WaveByteStreamCnv")
   , m_tool("RawWaveformDecoderTool")
   , m_mappingTool("WaveformCableMappingTool")
+  , m_rangeTool("WaveformRangeTool")
   , m_rdpSvc("FaserROBDataProviderSvc", m_name)
 {
   ATH_MSG_DEBUG(m_name+"::initialize() called");
@@ -49,7 +50,7 @@ StatusCode WaveByteStreamCnv::initialize()
   CHECK(m_rdpSvc.retrieve());
   CHECK(m_tool.retrieve());
   CHECK(m_mappingTool.retrieve());
-
+  CHECK(m_rangeTool.retrieve());
   return StatusCode::SUCCESS;
 }
 
@@ -96,8 +97,11 @@ StatusCode WaveByteStreamCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj
   auto mapping = m_mappingTool->getCableMapping();
   ATH_MSG_DEBUG("Cable mapping contains " << mapping.size() << " entries");
 
+  auto range = m_rangeTool->getRangeMapping();
+  ATH_MSG_DEBUG("Range contains " << range.size() << " entries");
+
   // Convert selected channels
-  CHECK( m_tool->convert(re, wfmCont, key, mapping) );
+  CHECK( m_tool->convert(re, wfmCont, key, mapping, range) );
   
   pObj = SG::asStorable(wfmCont);
 
diff --git a/Waveform/WaveEventCnv/WaveByteStream/src/WaveByteStreamCnv.h b/Waveform/WaveEventCnv/WaveByteStream/src/WaveByteStreamCnv.h
index ce373326fd61a3ab9f8552b5a6f561b449cc6850..960b8759e2f72633eae58efb882d67848cdfee07 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/src/WaveByteStreamCnv.h
+++ b/Waveform/WaveEventCnv/WaveByteStream/src/WaveByteStreamCnv.h
@@ -15,6 +15,7 @@
 #include "AthenaBaseComps/AthMessaging.h"
 #include "FaserByteStreamCnvSvcBase/FaserByteStreamAddress.h"
 #include "WaveformConditionsTools/IWaveformCableMappingTool.h"
+#include "WaveformConditionsTools/IWaveformRangeTool.h"
 
 class RawWaveformDecoderTool;
 class IFaserROBDataProviderSvc;
@@ -41,6 +42,7 @@ private:
   std::string m_name;
   ToolHandle<RawWaveformDecoderTool> m_tool;
   ToolHandle<IWaveformCableMappingTool> m_mappingTool;
+  ToolHandle<IWaveformRangeTool> m_rangeTool;
   ServiceHandle<IFaserROBDataProviderSvc> m_rdpSvc;
 };
 
diff --git a/Waveform/WaveRawEvent/WaveRawEvent/RawWaveform.h b/Waveform/WaveRawEvent/WaveRawEvent/RawWaveform.h
index 3770e05513a4d6f81ca16aa08785ea0c36a459cb..9581de5530a2c65c8ddddeb870c971a14b988b34 100644
--- a/Waveform/WaveRawEvent/WaveRawEvent/RawWaveform.h
+++ b/Waveform/WaveRawEvent/WaveRawEvent/RawWaveform.h
@@ -67,6 +67,11 @@ public:
   Identifier identify() const;
   Identifier32 identify32() const;
 
+  // Full-scale range (in V) of 14-bit ADC reading
+  // mV per bit is given by range() / 16.384
+  float range() const;
+  float mv_per_bit() const {return m_range / 16.384;}
+
   // some print-out:
   void print() const;
 
@@ -89,6 +94,8 @@ public:
   void setSamples(unsigned int samp) {m_samples = samp;}
   void setCounts(const std::vector<unsigned int>& counts) {m_adc_counts = counts;}
 
+  void setRange(float range) {m_range = range;}
+
   ///////////////////////////////////////////////////////////////////
   // Private data:
   ///////////////////////////////////////////////////////////////////
@@ -105,6 +112,8 @@ private:
   std::vector<unsigned int> m_adc_counts;
 
   Identifier32 m_ID;
+
+  float m_range;  
 };
 
 
@@ -145,6 +154,9 @@ RawWaveform::identify() const { return Identifier(m_ID); }
 inline Identifier32
 RawWaveform::identify32() const { return m_ID; }
 
+inline float
+RawWaveform::range() const { return m_range; }
+
 std::ostream 
 &operator<<(std::ostream &out, const RawWaveform &wfm);
 
diff --git a/Waveform/WaveRawEvent/src/RawWaveform.cxx b/Waveform/WaveRawEvent/src/RawWaveform.cxx
index d6ef63493018955a79d42eb2c4f7fe2eebc40de2..64c401dfad6a9fe9794737a953eca31eff110bc1 100644
--- a/Waveform/WaveRawEvent/src/RawWaveform.cxx
+++ b/Waveform/WaveRawEvent/src/RawWaveform.cxx
@@ -17,7 +17,8 @@ RawWaveform::RawWaveform( ) :
   m_samples(0),
   m_channel(0),
   m_adc_counts(),
-  m_ID(0xffff)
+  m_ID(0xffff),
+  m_range(2.)
 {
 
 }
diff --git a/Waveform/WaveRecAlgs/python/WaveRecAlgsConfig.py b/Waveform/WaveRecAlgs/python/WaveRecAlgsConfig.py
index d38eb4fd0a7ce0c26ffa1a78fd52a91f0261ac94..fb1cc4d4261adc110578d959a9fa3c24801c8b77 100644
--- a/Waveform/WaveRecAlgs/python/WaveRecAlgsConfig.py
+++ b/Waveform/WaveRecAlgs/python/WaveRecAlgsConfig.py
@@ -28,6 +28,7 @@ def WaveformReconstructionCfg(flags, naive = False):
 
     acc.merge(WaveformHitRecCfg(flags, "TriggerWaveformRecAlg", "Trigger"))
     acc.merge(WaveformHitRecCfg(flags, "VetoWaveformRecAlg", "Veto"))
+    acc.merge(WaveformHitRecCfg(flags, "VetoNuWaveformRecAlg", "VetoNu"))
     acc.merge(WaveformHitRecCfg(flags, "PreshowerWaveformRecAlg", "Preshower"))
     acc.merge(WaveformHitRecCfg(flags, "CaloWaveformRecAlg", "Calo"))
 
@@ -49,7 +50,7 @@ def WaveformClockRecCfg(flags, name="ClockRecAlg", **kwargs):
     return acc
 
 # Return configured WaveformHit reconstruction algorithm
-# Specify data source (Veto, Trigger, Preshower, Calo, Test)
+# Specify data source (Veto, VetoNu, Trigger, Preshower, Calo, Test)
 def WaveformHitRecCfg(flags, name="WaveformRecAlg", source="", **kwargs):
 
     acc = ComponentAccumulator()
diff --git a/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx b/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx
index ce9504ee183b2a8c25694b62041f6929db6e8290..04f857e038fa4c84ca2cefd88b58a0f153758752 100644
--- a/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx
+++ b/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx
@@ -187,12 +187,13 @@ WaveformReconstructionTool::ensureHits(
     unsigned int hi_edge = peakHit->time_vector().back()/2.;
 
     ATH_MSG_DEBUG("Windowing waveform from " << lo_edge << " to " << hi_edge);
+
     std::vector<float> wtime(hi_edge-lo_edge+1);
     std::vector<float> wwave(hi_edge-lo_edge+1);
     for (unsigned int i=lo_edge; i<=hi_edge; i++) {
       unsigned int j = i-lo_edge;
-      wtime[j] = 2.*i;
-      wwave[j] = newhit->baseline_mean() - wave->adc_counts()[i];
+      wtime[j] = 2.*i; // 2 ns per sample at 500 MHz sampling
+      wwave[j] = newhit->baseline_mean() - wave->mv_per_bit()*wave->adc_counts()[i];
       //ATH_MSG_DEBUG(" Time: " << wtime[j] << " Wave: " << wwave[j]);
     }
 
@@ -245,8 +246,8 @@ WaveformReconstructionTool::findBaseline(const RawWaveform& raw_wave,
 
   } else {
     // Save baseline to hit collection object
-    hit->set_baseline_mean(baseline.mean);
-    hit->set_baseline_rms(baseline.rms);
+    hit->set_baseline_mean(raw_wave.mv_per_bit()*baseline.mean);
+    hit->set_baseline_rms(raw_wave.mv_per_bit()*baseline.rms);
   }
 
   return baseline;
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformCableMappingTool.h b/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformCableMappingTool.h
index 8886506e5a04efe269bb75ca91fc36c8fe283d85..596d2bd8ce45189063f4952f7630ca0de0847c3e 100644
--- a/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformCableMappingTool.h
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformCableMappingTool.h
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and FAsER collaborations
 */
 
-/** @file ISCT_CableMappingTool.h Interface file for SCT_CableMappingTool.
+/** @file IWaveformCableMappingTool.h Interface file for WaveformCableMappingTool.
  */
 
 // Multiple inclusion protection
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformRangeTool.h b/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformRangeTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..316d9c4953a100e83c4ec1a0a052714372e1fdaf
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/WaveformConditionsTools/IWaveformRangeTool.h
@@ -0,0 +1,41 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and FAsER collaborations
+*/
+
+/** @file IWaveformRangeTool.h Interface file for WaveformRangeTool.
+ */
+
+// Multiple inclusion protection
+#ifndef IWAVEFORMRANGETOOL
+#define IWAVEFORMRANGETOOL
+
+//STL includes
+#include <map>
+
+//Gaudi Includes
+#include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+
+// ADC range in volts indexed by digitizer channel number
+typedef std::map<int, float> WaveformRangeMap;
+
+class IWaveformRangeTool: virtual public IAlgTool {
+
+ public:
+  
+  //----------Public Member Functions----------//
+  // Structors
+  virtual ~IWaveformRangeTool() = default; //!< Destructor
+
+  /// Creates the InterfaceID and interfaceID() method
+  DeclareInterfaceID(IWaveformRangeTool, 1, 0);
+
+  // Methods to return cable-mapping data 
+  // Key is digitizer channel, pair is <type, identifier>
+  virtual WaveformRangeMap getRangeMapping(const EventContext& ctx) const = 0;
+  virtual WaveformRangeMap getRangeMapping(void) const = 0;
+
+};
+
+//---------------------------------------------------------------------- 
+#endif // WAVEFORMRANGETOOL
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/python/WaveformRangeConfig.py b/Waveform/WaveformConditions/WaveformConditionsTools/python/WaveformRangeConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..6450bcec88b3cb8c7194b01edeb59aa6b97e242f
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/python/WaveformRangeConfig.py
@@ -0,0 +1,27 @@
+""" Define methods to configure WaveformRangeTool
+
+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
+WaveformRangeTool=CompFactory.WaveformRangeTool
+
+def WaveformRangeToolCfg(flags, name="WaveformRangeTool", **kwargs):
+    """ Return a configured WaveformRangeTool"""
+    return WaveformRangeTool(name, **kwargs)
+
+def WaveformRangeCfg(flags, **kwargs):
+    """ Return configured ComponentAccumulator and tool for Waveform Range 
+
+    WaveformRangeTool may be provided in kwargs
+    """
+
+    acc = ComponentAccumulator()
+    # tool = kwargs.get("WaveformRangeTool", WaveformRangeTool(flags))
+    # Probably need to figure this out!
+    dbInstance = kwargs.get("dbInstance", "TDAQ_OFL")
+    dbFolder = kwargs.get("dbFolder", "/WAVE/DAQ/Range")
+    acc.merge(addFolders(flags, dbFolder, dbInstance, className="CondAttrListCollection"))
+    return acc
+
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformCableMappingTool.cxx b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformCableMappingTool.cxx
index a846fe8da6a51bd3293f02b73cd960439d8d77b5..102aae0e79bda0b19b22b1969dad0103bf748d0f 100644
--- a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformCableMappingTool.cxx
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformCableMappingTool.cxx
@@ -27,6 +27,7 @@ WaveformCableMappingTool::initialize() {
   // Set up helpers
   ATH_CHECK(detStore()->retrieve(m_ecalID, "EcalID"));
   ATH_CHECK(detStore()->retrieve(m_vetoID, "VetoID"));
+  ATH_CHECK(detStore()->retrieve(m_vetoNuID, "VetoNuID"));
   ATH_CHECK(detStore()->retrieve(m_triggerID, "TriggerID"));
   ATH_CHECK(detStore()->retrieve(m_preshowerID, "PreshowerID"));
 
@@ -98,6 +99,9 @@ WaveformCableMappingTool::getCableMapping(const EventContext& ctx) const {
       else if (det_type == "veto") {
 	identifier = m_vetoID->pmt_id(stationVal, plateVal, pmtVal);
       }
+      else if (det_type == "vetonu") {
+	identifier = m_vetoNuID->pmt_id(stationVal, plateVal, pmtVal);
+      }
       else if (det_type == "trigger") {
 	identifier = m_triggerID->pmt_id(stationVal, plateVal, pmtVal);
       }
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformCableMappingTool.h b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformCableMappingTool.h
index 19e6e6d9b5f294692ba0496b1594741494ef223a..19763d56e76bd1d5b18bcf74d20ad1b85d3c7acc 100644
--- a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformCableMappingTool.h
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformCableMappingTool.h
@@ -21,6 +21,7 @@
 #include "Identifier/Identifier.h"
 #include "FaserCaloIdentifier/EcalID.h"
 #include "ScintIdentifier/VetoID.h"
+#include "ScintIdentifier/VetoNuID.h"
 #include "ScintIdentifier/TriggerID.h"
 #include "ScintIdentifier/PreshowerID.h"
 
@@ -65,6 +66,7 @@ class WaveformCableMappingTool: public extends<AthAlgTool, IWaveformCableMapping
   // ID helpers
   const EcalID* m_ecalID{nullptr};
   const VetoID* m_vetoID{nullptr};
+  const VetoNuID* m_vetoNuID{nullptr};
   const TriggerID* m_triggerID{nullptr};
   const PreshowerID* m_preshowerID{nullptr};
 
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformRangeTool.cxx b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformRangeTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5c7670e3cbc2dcc9e967107b9f304743695987fc
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformRangeTool.cxx
@@ -0,0 +1,90 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and FASER collaborations
+*/
+
+/** @file WaveformRangeTool.cxx Implementation file for WaveformRangeTool.
+    @author Eric Torrence (05/02/22)
+*/
+
+#include "WaveformRangeTool.h"
+
+//----------------------------------------------------------------------
+WaveformRangeTool::WaveformRangeTool (const std::string& type, const std::string& name, const IInterface* parent) :
+  base_class(type, name, parent)
+{
+}
+
+//----------------------------------------------------------------------
+StatusCode 
+WaveformRangeTool::initialize() {
+  // Read Cond Handle Key
+
+  ATH_MSG_DEBUG("WaveformRangeTool::initialize()");
+
+  ATH_CHECK(m_readKey.initialize());
+
+  return StatusCode::SUCCESS;
+}
+
+//----------------------------------------------------------------------
+StatusCode
+WaveformRangeTool::finalize() {
+  // Print where you are
+  return StatusCode::SUCCESS;
+}
+
+//----------------------------------------------------------------------
+WaveformRangeMap
+WaveformRangeTool::getRangeMapping(const EventContext& ctx) const {
+  // Print where you are
+  ATH_MSG_DEBUG("in getRangeMapping()");
+  WaveformRangeMap mappingData;
+
+  // Read Cond Handle
+  SG::ReadCondHandle<CondAttrListCollection> readHandle{m_readKey, ctx};
+  const CondAttrListCollection* readCdo{*readHandle}; 
+  if (readCdo==nullptr) {
+    ATH_MSG_FATAL("Null pointer to the read conditions object");
+    return mappingData;
+  }
+  // Get the validitiy range
+  EventIDRange rangeW;
+  if (not readHandle.range(rangeW)) {
+    ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key());
+    return mappingData;
+  }
+  ATH_MSG_DEBUG("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size());
+  ATH_MSG_DEBUG("Range of input is " << rangeW);
+  
+  // Read range info
+
+  CondAttrListCollection::const_iterator attrList{readCdo->begin()};
+  CondAttrListCollection::const_iterator end{readCdo->end()};
+  // CondAttrListCollection doesn't support C++11 type loops, no generic 'begin'
+  for (; attrList!=end; ++attrList) {
+    // A CondAttrListCollection is a map of ChanNum and AttributeList
+    CondAttrListCollection::ChanNum channelNumber{attrList->first};
+    const CondAttrListCollection::AttributeList &payload{attrList->second};
+    if (payload.exists("range") and not payload["range"].isNull()) {
+
+      float range {payload["range"].data<float>()};
+
+      ATH_MSG_DEBUG("Found digitizer channel " << channelNumber << " range as " << range);
+
+      mappingData.emplace(std::make_pair(channelNumber, range));
+
+    }
+
+  } // End of loop over attributes
+
+  return mappingData;
+} 
+
+WaveformRangeMap
+WaveformRangeTool::getRangeMapping(void) const {
+  const EventContext& ctx{Gaudi::Hive::currentContext()};
+  return getRangeMapping(ctx);
+}
+
+
+
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformRangeTool.h b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformRangeTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..e33123f243a41e286f32cf09059e748306a1348c
--- /dev/null
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/WaveformRangeTool.h
@@ -0,0 +1,60 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS and CERN collaborations
+*/
+
+/** @file WaveformRangeTool.h Header file for WaveformRangeTool.
+    @author Eric Torrence, 20/04/22
+*/
+
+// Multiple inclusion protection
+#ifndef WAVEFORM_RANGE_TOOL
+#define WAVEFORM_RANGE_TOOL
+
+// Include interface class
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "WaveformConditionsTools/IWaveformRangeTool.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 range data and makes it available to 
+    other algorithms. The current implementation reads the data from a COOL database. 
+*/
+
+class WaveformRangeTool: public extends<AthAlgTool, IWaveformRangeTool> {
+
+ public:
+  //----------Public Member Functions----------//
+  // Structors
+  WaveformRangeTool(const std::string& type, const std::string& name, const IInterface* parent); //!< Constructor
+  virtual ~WaveformRangeTool() = default; //!< Destructor
+
+  // Standard Gaudi functions
+  virtual StatusCode initialize() override; //!< Gaudi initialiser
+  virtual StatusCode finalize() override; //!< Gaudi finaliser
+
+  // Methods to return calibration data
+  // Map indexed by digitizer channel number
+  // Returns full-scale ADC range as float
+  virtual WaveformRangeMap getRangeMapping(const EventContext& ctx) const override;
+  virtual WaveformRangeMap getRangeMapping(void) const override;
+
+ private:
+  // Read Cond Handle
+  SG::ReadCondHandleKey<CondAttrListCollection> m_readKey{this, "ReadKey", "/WAVE/DAQ/Range", "Key of range folder"};
+
+  ServiceHandle<ICondSvc> m_condSvc{this, "CondSvc", "CondSvc"};
+
+};
+
+//---------------------------------------------------------------------- 
+#endif // WAVEFORM_CABLE_MAPPING_TOOL
diff --git a/Waveform/WaveformConditions/WaveformConditionsTools/src/components/WaveformConditionsTools_entries.cxx b/Waveform/WaveformConditions/WaveformConditionsTools/src/components/WaveformConditionsTools_entries.cxx
index 1f6a41ac923beab0533fcd60066b86143f813b90..99371a2040253bcd84b16ff7a1886d922f2540af 100644
--- a/Waveform/WaveformConditions/WaveformConditionsTools/src/components/WaveformConditionsTools_entries.cxx
+++ b/Waveform/WaveformConditions/WaveformConditionsTools/src/components/WaveformConditionsTools_entries.cxx
@@ -1,3 +1,5 @@
+#include "../WaveformRangeTool.h"
 #include "../WaveformCableMappingTool.h"
 
+DECLARE_COMPONENT( WaveformRangeTool )
 DECLARE_COMPONENT( WaveformCableMappingTool )
diff --git a/faser-common b/faser-common
index 5124b0e78dbcc4a05c22f511700d5dbcdb4808df..c50e393f226a088188987d94372d193507a68af3 160000
--- a/faser-common
+++ b/faser-common
@@ -1 +1 @@
-Subproject commit 5124b0e78dbcc4a05c22f511700d5dbcdb4808df
+Subproject commit c50e393f226a088188987d94372d193507a68af3
diff --git a/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHit_v1.h b/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHit_v1.h
index 9ea7b6dc573d53a533df44d02ff3edbf92c8a9ce..182003d90ab7f018f8b9afcccf45212b4cebc188 100644
--- a/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHit_v1.h
+++ b/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHit_v1.h
@@ -55,6 +55,8 @@ namespace xAOD {
       return Identifier(this->id());
     }
 
+    /// All values are in units of ns and mV
+
     /// Best results
     float localtime() const;
     void set_localtime(float value);
@@ -102,7 +104,7 @@ namespace xAOD {
     float nval() const;
     void set_nval(float value);
 
-    /// Raw time and waveform data
+    /// Raw time and waveform data (in ns and mV)
     std::vector<float> time_vector() const;
     void set_time_vector(std::vector<float> value);