diff --git a/Event/FaserByteStreamCnvSvc/python/FaserByteStreamCnvSvcConfig.py b/Event/FaserByteStreamCnvSvc/python/FaserByteStreamCnvSvcConfig.py
index 633017999803b3dda6eca426bc3acdf4689c92bb..e2315ae1c6f5ff50b973e6c08377a3cee9da9ef4 100644
--- a/Event/FaserByteStreamCnvSvc/python/FaserByteStreamCnvSvcConfig.py
+++ b/Event/FaserByteStreamCnvSvc/python/FaserByteStreamCnvSvcConfig.py
@@ -46,6 +46,10 @@ def FaserByteStreamCnvSvcCfg(configFlags, **kwargs):
     from FaserByteStreamCnvSvcBase.FaserByteStreamCnvSvcBaseConfig import FaserByteStreamCnvSvcBaseCfg
     result.merge(FaserByteStreamCnvSvcBaseCfg(configFlags))
 
+# Configure WaveformByteStream converter
+    from WaveByteStream.WaveByteStreamConfig import WaveByteStreamCfg
+    result.merge(WaveByteStreamCfg(configFlags))
+
 # Load ByteStreamEventStorageInputSvc
     bsInputSvc = CompFactory.FaserByteStreamInputSvc
     result.addService(bsInputSvc(name = "FaserByteStreamInputSvc"))
diff --git a/Waveform/WaveEventCnv/WaveByteStream/CMakeLists.txt b/Waveform/WaveEventCnv/WaveByteStream/CMakeLists.txt
index 6fc3d0b95846b2e395cccbbe6938336def278e4e..bdf35c03e86b0fbac4807da3f4ace952b81e2dc1 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/CMakeLists.txt
+++ b/Waveform/WaveEventCnv/WaveByteStream/CMakeLists.txt
@@ -13,7 +13,7 @@ atlas_subdir( WaveByteStream )
 atlas_add_component( WaveByteStream
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaKernel GaudiKernel FaserByteStreamCnvSvcBaseLib FaserEventStorageLib WaveRawEvent
+                     LINK_LIBRARIES Identifier ScintIdentifier FaserCaloIdentifier AthenaKernel GaudiKernel FaserByteStreamCnvSvcBaseLib FaserEventStorageLib WaveRawEvent
                      PRIVATE_LINK_LIBRARIES AthenaBaseComps )
 
 atlas_install_python_modules( python/*.py )
diff --git a/Waveform/WaveEventCnv/WaveByteStream/python/WaveByteStreamConfig.py b/Waveform/WaveEventCnv/WaveByteStream/python/WaveByteStreamConfig.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cc13137d8e59eef7801d0ffa8fa60230721b372f 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/python/WaveByteStreamConfig.py
+++ b/Waveform/WaveEventCnv/WaveByteStream/python/WaveByteStreamConfig.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+from AthenaConfiguration.ComponentFactory import CompFactory
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+
+def WaveByteStreamCfg(configFlags, **kwargs):
+
+    acc = ComponentAccumulator()
+
+    # Decide which waveform mapping to instantiate from Geo tag
+    
+    if configFlags.Input.isMC:
+        # Nothing to do for MC
+        print("WaveByteStreamConfig.WaveByteStreamCfg - Called for isMC True, nothing to do...")
+        return acc
+        
+    print("WaveByteStreamConfig.WaveByteStreamCfg - Found FaserVersion: ", configFlags.GeoModel.FaserVersion,)
+
+    # Channels are ordered front->back, bottom->top, right->left
+    if configFlags.GeoModel.FaserVersion == "FASER-TB00":
+        print(" - setting up testbeam detector")
+
+        waveform_tool = CompFactory.RawWaveformDecoderTool("RawWaveformDecoderTool")
+        waveform_tool.CaloChannels = [5, 3, 1, 4, 2, 0]
+        waveform_tool.VetoChannels = []
+        waveform_tool.TriggerChannels = [8, 9]
+        waveform_tool.PreshowerChannels = [6, 7]
+        acc.addPublicTool(waveform_tool)
+        
+    elif configFlags.GeoModel.FaserVersion == "FASER-01":
+        print(" - setting up TI12 detector")
+
+        waveform_tool = CompFactory.RawWaveformDecoderTool("RawWaveformDecoderTool")
+        waveform_tool.CaloChannels = [1, 0, 3, 2]
+        waveform_tool.VetoChannels = [4, 5, 6, 7]
+        waveform_tool.TriggerChannels = [9, 8, 11, 10]
+        waveform_tool.PreshowerChannels = [12, 13]
+        acc.addPublicTool(waveform_tool)
+
+    else:
+        print(" - unknown version: user must set up Waveform channel mapping by hand!")
+
+    return acc
diff --git a/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.cxx b/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.cxx
index 2081244c434b40e789bf268284a7b56b13a89929..ec7a6641e3df94a8ac0b3b989e5c99303e3b62d7 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.cxx
+++ b/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.cxx
@@ -20,31 +20,16 @@ RawWaveformDecoderTool::RawWaveformDecoderTool(const std::string& type,
 {
   declareInterface<RawWaveformDecoderTool>(this);
 
+  // These must be configured by job options
   declareProperty("CaloChannels", m_caloChannels);
-  m_caloChannels.push_back(0);
-  m_caloChannels.push_back(1);
-  m_caloChannels.push_back(2);
-  m_caloChannels.push_back(3);
-
   declareProperty("VetoChannels", m_vetoChannels);
-  m_vetoChannels.push_back(4);
-  m_vetoChannels.push_back(5);
-  m_vetoChannels.push_back(6);
-  m_vetoChannels.push_back(7);
-
   declareProperty("TriggerChannels", m_triggerChannels);
-  m_triggerChannels.push_back(8);
-  m_triggerChannels.push_back(9);
-  m_triggerChannels.push_back(10);
-  m_triggerChannels.push_back(11);
-
   declareProperty("PreshowerChannels", m_preshowerChannels);
-  m_preshowerChannels.push_back(12);
-  m_preshowerChannels.push_back(13);
 
+  // Test channels is provided for conveniene, not normally used
   declareProperty("TestChannels", m_testChannels);
-  m_testChannels.push_back(14);
 
+  // Clock should always be in channel 15
   declareProperty("ClockChannels", m_clockChannels);
   m_clockChannels.push_back(15);
 
@@ -58,6 +43,82 @@ StatusCode
 RawWaveformDecoderTool::initialize() 
 {
   ATH_MSG_DEBUG("RawWaveformDecoderTool::initialize()");
+
+  // Set up helpers
+  ATH_CHECK(detStore()->retrieve(m_ecalID, "EcalID"));
+  ATH_CHECK(detStore()->retrieve(m_vetoID, "VetoID"));
+  ATH_CHECK(detStore()->retrieve(m_triggerID, "TriggerID"));
+  ATH_CHECK(detStore()->retrieve(m_preshowerID, "PreshowerID"));
+
+  // Take each channel list and create identifiers
+
+  // Loop through digitizer channel lists creating Identifiers
+  m_identifierMap.clear();
+
+  // First, calorimeter.  Can either be 4 or 6 channels
+  // Bottom row first from left to right, then top row
+  int index=0;
+  int module=0;
+  int row=0;
+  int pmt=0;
+
+  int max_modules = m_caloChannels.size() / 2;
+  for (auto const& chan : m_caloChannels) {
+    row = index / max_modules;
+    module = index % max_modules;
+    index++;
+    // Only store in map if digitizer channel is valid
+    if (chan < 0) continue;
+    m_identifierMap[chan] = m_ecalID->pmt_id(row, module, pmt);
+    ATH_MSG_DEBUG("Mapped digitizer channel " << chan << " to calo ID: " << m_identifierMap[chan]);
+  }
+
+  // Next, veto detector.  Have station and plate here.
+  int station=0;
+  int plate=0;
+  pmt=0; 
+  index=0;
+
+  int max_stations=m_vetoChannels.size() / 2;
+  for (auto const& chan : m_vetoChannels) {
+    station = index / max_stations;
+    plate = index % max_stations;
+    index++;
+    // Only store in map if digitizer channel is valid
+    if (chan < 0) continue;
+    m_identifierMap[chan] = m_vetoID->pmt_id(station, plate, pmt);
+    ATH_MSG_DEBUG("Mapped digitizer channel " << chan << " to veto ID: " << m_identifierMap[chan]);
+  }
+
+  // Next, trigger detector.  Have pmt and plate.
+  pmt=0;
+  station=0;
+  index=0;
+  int max_plates=m_triggerChannels.size() / 2;
+  for (auto const& chan : m_triggerChannels) {
+    plate = index / max_plates;
+    pmt = index % max_plates;
+    index++;
+    // Only store in map if digitizer channel is valid
+    if (chan < 0) continue;
+    m_identifierMap[chan] = m_triggerID->pmt_id(station, plate, pmt);
+    ATH_MSG_DEBUG("Mapped dititizer channel " << chan << " to trigger ID: " << m_identifierMap[chan]);
+  }
+
+  // Finally, preshower detector.
+  pmt=0;
+  station=0;
+  plate=0;
+  index=0;
+  for (auto const& chan : m_preshowerChannels) {
+    plate = index;
+    index++;
+    // Only store in map if digitizer channel is valid
+    if (chan < 0) continue;
+    m_identifierMap[chan] = m_preshowerID->pmt_id(station, plate, pmt);
+    ATH_MSG_DEBUG("Mapped digitizer channel " << chan << " to preshower ID: " << m_identifierMap[chan]);
+  }
+
   return StatusCode::SUCCESS;
 }
 
@@ -111,7 +172,7 @@ RawWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
     ATH_MSG_DEBUG("Found valid digitizer fragment");
   }
 
-  std::vector<unsigned int>* channelList;
+  std::vector<int>* channelList;
 
   if (key == std::string("CaloWaveforms")) {
     channelList = &m_caloChannels;
@@ -130,7 +191,7 @@ RawWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
     return StatusCode::FAILURE;
   }
 
-  for (unsigned int channel: *channelList) {
+  for (int channel: *channelList) {
     ATH_MSG_DEBUG("Converting channel "+std::to_string(channel)+" for "+key);
 
     // Check if this has data
@@ -161,6 +222,11 @@ RawWaveformDecoderTool::convert(const DAQFormats::EventFull* re,
 		      << *frag);
     }
 
+    // Set ID if one exists (clock, for instance, doesn't have an identifier)
+    if (m_identifierMap.count(channel) == 1) {
+      wfm->setIdentifier(m_identifierMap[channel]);
+    }
+
     container->push_back(wfm);    
 
     // Sanity check
diff --git a/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.h b/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.h
index 252698c5fb975370945883d112a72c21ef7798a2..e2852f13772113d8e52a62c9655a18365cb80f61 100644
--- a/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.h
+++ b/Waveform/WaveEventCnv/WaveByteStream/src/RawWaveformDecoderTool.h
@@ -13,6 +13,12 @@
 #include "EventFormats/DAQFormats.hpp"
 #include "WaveRawEvent/RawWaveformContainer.h"
 
+#include "Identifier/Identifier.h"
+#include "FaserCaloIdentifier/EcalID.h"
+#include "ScintIdentifier/VetoID.h"
+#include "ScintIdentifier/TriggerID.h"
+#include "ScintIdentifier/PreshowerID.h"
+
 // This class provides conversion between bytestream and Waveform objects
 
 class RawWaveformDecoderTool : public AthAlgTool {
@@ -32,13 +38,48 @@ class RawWaveformDecoderTool : public AthAlgTool {
 
 private:
   // List of channels to include in each container
-  std::vector<unsigned int> m_caloChannels;
-  std::vector<unsigned int> m_vetoChannels;
-  std::vector<unsigned int> m_triggerChannels;
-  std::vector<unsigned int> m_preshowerChannels;
-  std::vector<unsigned int> m_testChannels;
-  std::vector<unsigned int> m_clockChannels;
+  // List order must correspond to offline channel order
+  // All L/R designations refer to looking at the detector from
+  // the beam direction.
+  //
+  // In general, the ordering is layer (longitudinal), row (vertical), module (horizontal)
+  // Layers increase with longitudianl position downstream
+  // Rows increase from bottom to top
+  // Modules increase from right to left
+  //
+  // For all lists, use invalid channel (-1) to indicate detectors
+  // missing in sequence (i.e. 3 of 4 veto counters)
+  // 
+  // TI12 detector:
+  // Calorimeter order:
+  //   bottom right, bottom left, top right, top left
+  // Veto 
+  //   front to back.  
+  // Trigger
+  //   bottom right PMT, bottom left PMT, top right PMT, top left PMT
+  // Preshower
+  //   front to back
+  //   
+  // 2021 Testbeam detector:
+  // Calo order:
+  //   bottom right, bottom center, bottom left, top R, top C, top L
+  // All others are just in order front to back 
+
+  std::vector<int> m_caloChannels;
+  std::vector<int> m_vetoChannels;
+  std::vector<int> m_triggerChannels;
+  std::vector<int> m_preshowerChannels;
+  std::vector<int> m_testChannels;
+  std::vector<int> m_clockChannels;
+
+  // Identifiers keyed by digitizer channel
+  std::map<unsigned int, Identifier> m_identifierMap;
 
+  // ID helpers
+  const EcalID* m_ecalID{nullptr};
+  const VetoID* m_vetoID{nullptr};
+  const TriggerID* m_triggerID{nullptr};
+  const PreshowerID* m_preshowerID{nullptr};
 
 };
 
diff --git a/Waveform/WaveEventCnv/WaveEventAthenaPool/WaveEventAthenaPool/RawWaveform_p0.h b/Waveform/WaveEventCnv/WaveEventAthenaPool/WaveEventAthenaPool/RawWaveform_p0.h
index e4721fefeec5ef7be0f945bca38a790c81151ae6..9eee456fbdae20d6b3619e7b99bb6ee640dc1ef1 100644
--- a/Waveform/WaveEventCnv/WaveEventAthenaPool/WaveEventAthenaPool/RawWaveform_p0.h
+++ b/Waveform/WaveEventCnv/WaveEventAthenaPool/WaveEventAthenaPool/RawWaveform_p0.h
@@ -9,6 +9,8 @@
 #include <iostream>
 #include <iomanip>
 
+#include "Identifier/Identifier32.h"
+
 class RawWaveform_p0 {
  public:
   RawWaveform_p0();
@@ -17,7 +19,7 @@ class RawWaveform_p0 {
   friend class RawWaveformCnv_p0;
 
  private:
-  unsigned int m_ID;
+  Identifier32::value_type m_ID;
   unsigned int m_channel;
   std::vector<unsigned int> m_adc_counts;
 
diff --git a/Waveform/WaveEventCnv/WaveEventAthenaPool/src/RawWaveformCnv_p0.cxx b/Waveform/WaveEventCnv/WaveEventAthenaPool/src/RawWaveformCnv_p0.cxx
index d298c0ff390393b6b8822bcc43167eee7c89ee9d..dedc71cbac77ccbdfa48dff63013cc6c16ab97f8 100644
--- a/Waveform/WaveEventCnv/WaveEventAthenaPool/src/RawWaveformCnv_p0.cxx
+++ b/Waveform/WaveEventCnv/WaveEventAthenaPool/src/RawWaveformCnv_p0.cxx
@@ -9,7 +9,8 @@ RawWaveformCnv_p0::persToTrans(const RawWaveform_p0* persObj, RawWaveform* trans
 
   // Just fill available data here
   // Rest of it patched up in RawWaveformContainerCnv_p0
-  transObj->setIdentifier(persObj->m_ID);
+  // Persistent object stores ID value, so instantiate Identifier here
+  transObj->setIdentifier(Identifier32(persObj->m_ID));
   transObj->setChannel(persObj->m_channel);
   transObj->setCounts(persObj->m_adc_counts);
 
@@ -23,7 +24,9 @@ RawWaveformCnv_p0::transToPers(const RawWaveform* transObj, RawWaveform_p0* pers
   // log << MSG::DEBUG << (*transObj) << endmsg;
   // log << MSG::DEBUG << "Persistent waveform (before):" << endmsg;
   // persObj->print();
-  persObj->m_ID = transObj->identify();
+
+  // Save actual ID number 
+  persObj->m_ID = transObj->identify32().get_compact();
   persObj->m_channel = transObj->channel();
 
   // Use copy here
diff --git a/Waveform/WaveRawEvent/CMakeLists.txt b/Waveform/WaveRawEvent/CMakeLists.txt
index 48473bf8813e27d85bd73a1c915ad16f34eabbc0..cf5334c539d23320189bf8d10a8466b9422cf440 100644
--- a/Waveform/WaveRawEvent/CMakeLists.txt
+++ b/Waveform/WaveRawEvent/CMakeLists.txt
@@ -16,12 +16,12 @@ atlas_add_library( WaveRawEvent
                    INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS}
                    PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
                    DEFINITIONS ${CLHEP_DEFINITIONS}
-                   LINK_LIBRARIES ${CLHEP_LIBRARIES} AthAllocators AthenaKernel CxxUtils StoreGateLib SGtests
+                   LINK_LIBRARIES ${CLHEP_LIBRARIES} AthAllocators AthenaKernel Identifier CxxUtils StoreGateLib SGtests
                    PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} ScintIdentifier EventFormats )
 
 atlas_add_dictionary( WaveRawEventDict
                       WaveRawEvent/WaveRawEventDict.h
                       WaveRawEvent/selection.xml
                       INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${GEANT4_INCLUDE_DIRS}
-                      LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthAllocators CxxUtils StoreGateLib ScintIdentifier WaveRawEvent )
+                      LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthAllocators Identifier CxxUtils StoreGateLib ScintIdentifier WaveRawEvent )
 
diff --git a/Waveform/WaveRawEvent/WaveRawEvent/RawWaveform.h b/Waveform/WaveRawEvent/WaveRawEvent/RawWaveform.h
index 6ea6d9037afe587ebe21d52eb9280b23e7a397c8..3770e05513a4d6f81ca16aa08785ea0c36a459cb 100644
--- a/Waveform/WaveRawEvent/WaveRawEvent/RawWaveform.h
+++ b/Waveform/WaveRawEvent/WaveRawEvent/RawWaveform.h
@@ -20,10 +20,13 @@
 #include <iomanip>
 
 #include "AthenaKernel/CLASS_DEF.h"
+#include "Identifier/Identifier.h"
+#include "Identifier/Identifier32.h"
+#include "Identifier/Identifiable.h"
 
 class DigitizerDataFragment;
 
-class RawWaveform  {
+class RawWaveform : public Identifiable {
 
   ///////////////////////////////////////////////////////////////////
   // Public methods:
@@ -60,7 +63,9 @@ public:
   unsigned int channel() const;
   const std::vector<unsigned int>& adc_counts() const;
 
-  unsigned int identify() const;
+  // Return channel identifier
+  Identifier identify() const;
+  Identifier32 identify32() const;
 
   // some print-out:
   void print() const;
@@ -69,7 +74,7 @@ public:
   {return m_ID < rhs.m_ID;}
 
   // Set functions
-  void setIdentifier (unsigned int id);
+  void setIdentifier (Identifier id);  // Identifier class
   void setHeader (const DigitizerDataFragment* frag);
   void setWaveform (unsigned int channel, const std::vector<uint16_t> waveform);
 
@@ -99,7 +104,7 @@ private:
   unsigned int m_channel;
   std::vector<unsigned int> m_adc_counts;
 
-  unsigned int m_ID;
+  Identifier32 m_ID;
 };
 
 
@@ -134,8 +139,11 @@ RawWaveform::n_samples() const { return m_samples; }
 inline const std::vector<unsigned int>&
 RawWaveform::adc_counts() const { return m_adc_counts; }
 
-inline unsigned int 
-RawWaveform::identify() const { return m_ID; }
+inline Identifier 
+RawWaveform::identify() const { return Identifier(m_ID); }
+
+inline Identifier32
+RawWaveform::identify32() const { return m_ID; }
 
 std::ostream 
 &operator<<(std::ostream &out, const RawWaveform &wfm);
diff --git a/Waveform/WaveRawEvent/src/RawWaveform.cxx b/Waveform/WaveRawEvent/src/RawWaveform.cxx
index 13700a735c3653867a7e7ab5df8037e3566664ae..d6ef63493018955a79d42eb2c4f7fe2eebc40de2 100644
--- a/Waveform/WaveRawEvent/src/RawWaveform.cxx
+++ b/Waveform/WaveRawEvent/src/RawWaveform.cxx
@@ -25,8 +25,8 @@ RawWaveform::RawWaveform( ) :
 RawWaveform::~RawWaveform() {}
 
 void
-RawWaveform::setIdentifier(unsigned int id) {
-  m_ID = id;
+RawWaveform::setIdentifier(Identifier id) {
+  m_ID = id.get_identifier32();
 }
 
 void
diff --git a/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx b/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx
index 934f20803d18a1786ace8dedf18062203db8ba56..d34a654f505243f5333de060c8e7da942ab01093 100644
--- a/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx
+++ b/Waveform/WaveRecTools/src/WaveformReconstructionTool.cxx
@@ -59,7 +59,10 @@ WaveformReconstructionTool::reconstruct(const RawWaveform& raw_wave,
   // We always want to create at least one hit, so create it here
   xAOD::WaveformHit* hit = new xAOD::WaveformHit();
   container->push_back(hit);
+
+  // Set digitizer channel and identifier
   hit->set_channel(raw_wave.channel());
+  hit->set_id(raw_wave.identify32().get_compact());
 
   //
   // Make some sanity checks on the waveform data
@@ -80,9 +83,6 @@ WaveformReconstructionTool::reconstruct(const RawWaveform& raw_wave,
     return StatusCode::SUCCESS;
   }
 
-  // Set channel
-  hit->set_channel(raw_wave.channel());
-
   //
   // Find baseline
   WaveformBaselineData baseline;
diff --git a/xAOD/xAODFaserWaveform/CMakeLists.txt b/xAOD/xAODFaserWaveform/CMakeLists.txt
index 1185251139a20ea833a672371173ad00c2987ccd..b5b6abf4398952c40739dab07f360785a9aecf0b 100644
--- a/xAOD/xAODFaserWaveform/CMakeLists.txt
+++ b/xAOD/xAODFaserWaveform/CMakeLists.txt
@@ -10,7 +10,7 @@ find_package( xAODUtilities )
 atlas_add_library( xAODFaserWaveform
    xAODFaserWaveform/*.h xAODFaserWaveform/versions/*.h Root/*.cxx
    PUBLIC_HEADERS xAODFaserWaveform
-   LINK_LIBRARIES xAODCore )
+   LINK_LIBRARIES Identifier xAODCore )
 
 atlas_add_xaod_smart_pointer_dicts(
    INPUT xAODFaserWaveform/selection.xml
@@ -21,6 +21,6 @@ atlas_add_xaod_smart_pointer_dicts(
 atlas_add_dictionary( xAODFaserWaveformDict
    xAODFaserWaveform/xAODFaserWaveformDict.h
    ${_selectionFile}
-   LINK_LIBRARIES xAODCore xAODFaserWaveform
+   LINK_LIBRARIES Identifier xAODCore xAODFaserWaveform
    EXTRA_FILES Root/dict/*.cxx )
 
diff --git a/xAOD/xAODFaserWaveform/Root/WaveformHitAuxContainer_v1.cxx b/xAOD/xAODFaserWaveform/Root/WaveformHitAuxContainer_v1.cxx
index 76aed56247567f13e39fbcbf7471950dc93b3c23..2cd4ffcf6859a6af5341683af8333e1ba57be1ed 100644
--- a/xAOD/xAODFaserWaveform/Root/WaveformHitAuxContainer_v1.cxx
+++ b/xAOD/xAODFaserWaveform/Root/WaveformHitAuxContainer_v1.cxx
@@ -11,6 +11,7 @@ namespace xAOD {
     : AuxContainerBase() {
 
     AUX_VARIABLE(channel);
+    AUX_VARIABLE(id);
     AUX_VARIABLE(localtime);
     AUX_VARIABLE(peak);
     AUX_VARIABLE(width);
diff --git a/xAOD/xAODFaserWaveform/Root/WaveformHit_v1.cxx b/xAOD/xAODFaserWaveform/Root/WaveformHit_v1.cxx
index 4d4ce278978e68024637c117bc1e9456c2e22730..8b26eebffaa1018193523608e0494ef5fcc29d44 100644
--- a/xAOD/xAODFaserWaveform/Root/WaveformHit_v1.cxx
+++ b/xAOD/xAODFaserWaveform/Root/WaveformHit_v1.cxx
@@ -15,6 +15,8 @@ namespace xAOD {
 
   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( WaveformHit_v1, unsigned int, channel, set_channel )
 
+  AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( WaveformHit_v1, unsigned int, id, set_id )
+
   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( WaveformHit_v1, float, localtime, set_localtime )
 
   AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( WaveformHit_v1, float, peak, set_peak )
diff --git a/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHitAuxContainer_v1.h b/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHitAuxContainer_v1.h
index 0ea61b39a567a61882a390aa35277363771e970f..c272fcd2c8d8ce8323b819ea8ca02ceeb02b45f9 100644
--- a/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHitAuxContainer_v1.h
+++ b/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHitAuxContainer_v1.h
@@ -29,6 +29,7 @@ namespace xAOD {
     /// @name Basic variables
     ///@ {
     std::vector<unsigned int> channel;
+    std::vector<unsigned int> id;
     std::vector<float> localtime;
     std::vector<float> peak;
     std::vector<float> width;
diff --git a/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHit_v1.h b/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHit_v1.h
index 8b69c776da83546cde3a787a25bcf2b3a830cf7f..9ea7b6dc573d53a533df44d02ff3edbf92c8a9ce 100644
--- a/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHit_v1.h
+++ b/xAOD/xAODFaserWaveform/xAODFaserWaveform/versions/WaveformHit_v1.h
@@ -16,6 +16,7 @@ extern "C" {
 
 // Core EDM include(s):
 #include "AthContainers/AuxElement.h"
+#include "Identifier/Identifier.h"
 
 namespace xAOD {
 
@@ -42,10 +43,18 @@ namespace xAOD {
     /// @name Access WaveformHit elements
     /// @{
 
-    /// Waveform channel
+    /// Waveform digitizer channel
     unsigned int channel() const;
     void set_channel(unsigned int value);
 
+    /// 32-bit version of channel identifier
+    unsigned int id() const;
+    void set_id(unsigned int value);
+
+    Identifier identify() const {
+      return Identifier(this->id());
+    }
+
     /// Best results
     float localtime() const;
     void set_localtime(float value);