diff --git a/DDCore/include/DDSegmentation/BitFieldCoder.h b/DDCore/include/DDSegmentation/BitFieldCoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e3b9acdea1a7c0a23fb502d2acfb8c6d3cb5850
--- /dev/null
+++ b/DDCore/include/DDSegmentation/BitFieldCoder.h
@@ -0,0 +1,281 @@
+#ifndef DDSegmentation_BitFieldCoder_H
+#define DDSegmentation_BitFieldCoder_H 1
+
+
+#include <string>
+#include <vector>
+#include <map>
+#include <sstream>
+
+
+namespace dd4hep {
+
+typedef long long int long64 ;
+typedef unsigned long long ulong64 ;
+
+namespace DDSegmentation {
+
+  class BitFieldValue ;
+  class StringTokenizer ; 
+
+
+  /** Helper class for decoding and encoding a bit field of 64bits for convenient declaration and 
+   *  manipulation of sub fields of various widths.<br>
+   *  This is a thread safe re-implementation of the functionality in the deprected BitField64.
+   *  
+   *  Example:<br>
+   *    BitFieldCoder bc("layer:7,system:-3,barrel:3,theta:32:11,phi:11" ) ; <br> 
+   *    bc.set( field,  "layer"  , 123 );         <br> 
+   *    bc.set( field,  "system" , -4  );         <br> 
+   *    bc.set( field,  "barrel" , 7   );         <br> 
+   *    bc.set( field,  "theta"  , 180 );         <br> 
+   *    bc.set( field,  "phi"    , 270 );         <br> 
+   *    ...                                       <br>
+   *    int theta = bc.get( field, "theta" ) ;                    <br>
+   *    ...                                       <br>
+   *    unsigned phiIndex = bc.index("phi") ;     <br>
+   *    int phi = bc.get( field, phiIndex ) ;                <br>
+   *
+   *    @author F.Gaede, DESY
+   *    @date  2017-09
+   */  
+  class BitFieldCoder{
+    
+
+    /** Helper class for BitFieldCoder that corresponds to one field value. 
+     */
+
+    class BitFieldValue{
+  
+    public :
+      virtual ~BitFieldValue() {}
+  
+      /** The default c'tor.
+       * @param  name          name of the field
+       * @param  offset        offset of field
+       * @param  signedWidth   width of field, negative if field is signed
+       */
+      BitFieldValue( const std::string& name, 
+		     unsigned offset, int signedWidth ) ; 
+
+      /// calculate this field's value given an external 64 bit bitmap 
+      long64 value(long64 bitfield) const;
+
+
+      // assign the given value to the bit field
+      void set(long64& bitfield, long64 value) ;
+
+
+      /** The field's name */
+      const std::string& name() const { return _name ; }
+
+      /** The field's offset */
+      unsigned offset() const { return _offset ; }
+
+      /** The field's width */
+      unsigned width() const { return _width ; }
+
+      /** True if field is interpreted as signed */
+      bool isSigned() const { return _isSigned ; }
+
+      /** The field's mask */
+      ulong64 mask() const { return _mask ; }
+
+      /** Minimal value  */
+      int  minValue()  const  { return _minVal;  }
+
+      /** Maximal value  */
+      int  maxValue()  const  { return _maxVal;  }
+
+    protected:
+  
+      ulong64 _mask{} ;
+      unsigned _offset{} ;
+      unsigned _width{} ;
+      int _minVal{} ;
+      int _maxVal{} ;
+      bool _isSigned{} ;
+      std::string _name{} ;
+
+    };
+
+
+  public :
+    
+    typedef std::map<std::string, unsigned int> IndexMap ;
+
+    /** No default c'tor */
+    BitFieldCoder() = delete ;
+
+    ~BitFieldCoder() {  // clean up
+      for(unsigned i=0;i<_fields.size();i++){
+	delete _fields[i] ;
+      }
+  }
+    
+    /** The c'tor takes an initialization string of the form:<br>
+     *  \<fieldDesc\>[,\<fieldDesc\>...]<br>
+     *  fieldDesc = name:[start]:[-]length<br>
+     *  where:<br>
+     *  name: The name of the field<br>
+     *  start: The start bit of the field. If omitted assumed to start 
+     *  immediately following previous field, or at the least significant 
+     *  bit if the first field.<br>
+     *  length: The number of bits in the field. If preceeded by '-' 
+     *  the field is signed, otherwise unsigned.<br>
+     *  Bit numbering is from the least significant bit (bit 0) to the most 
+     *  significant (bit 63). <br>
+     *  Example: "layer:7,system:-3,barrel:3,theta:32:11,phi:11"
+     */
+    BitFieldCoder( const std::string& initString ) : _joined(0){
+    
+      init( initString ) ;
+    }
+
+    /** return a new 64bit value given as high and low 32bit words.
+     */
+    static long64 toLong(unsigned low_Word, unsigned high_Word ) {
+      return (  ( low_Word & 0xffffffffULL ) |  ( ( high_Word & 0xffffffffULL ) << 32 ) ) ; 
+    }
+    
+    /** The low  word, bits 0-31
+     */
+    static unsigned lowWord(long64 bitfield) { return unsigned( bitfield &  0xffffFFFFUL )  ; } 
+
+    /** The high  word, bits 32-63
+     */
+    static unsigned highWord(long64 bitfield) { return unsigned( bitfield >> 32) ; } 
+
+
+    /** get value of sub-field specified by index 
+     */
+    long64 get(long64 bitfield, size_t index) const { 
+      return _fields.at(index)->value( bitfield )  ; 
+    }
+    
+    /** Access to field through name .
+     */
+    long64 get(long64 bitfield, const std::string& name) const {
+
+      return _fields.at( index( name ) )->value( bitfield ) ;
+    }
+
+    /** set value of sub-field specified by index 
+     */
+    void set(long64& bitfield, size_t index, ulong64 value) const { 
+      _fields.at(index)->set( bitfield , value )  ; 
+    }
+    
+    /** Access to field through name .
+     */
+    void set(long64& bitfield, const std::string& name, ulong64 value) const {
+
+      _fields.at( index( name ) )->set( bitfield, value ) ;
+    }
+
+
+
+    /** Highest bit used in fields [0-63]
+     */
+    unsigned highestBit() const ;
+    
+
+    /** Number of values */
+    size_t size() const { return _fields.size() ; }
+
+    /** Index for field named 'name' 
+     */
+    size_t index( const std::string& name) const ;
+
+
+    /** Const Access to field through name .
+     */
+    const BitFieldValue& operator[](const std::string& name) const { 
+
+      return *_fields[ index( name ) ] ;
+    }
+
+    /** Return a valid description string of all fields
+     */
+    std::string fieldDescription() const ;
+
+    /** Return a string with a comma separated list of the current sub field values 
+     */
+    std::string valueString(ulong64 bitfield) const ;
+
+    const std::vector<BitFieldValue*>& fields()  const  {
+      return _fields;
+    }
+    
+  protected:
+
+    /** Add an additional field to the list 
+     */
+    void addField( const std::string& name,  unsigned offset, int width ); 
+
+    /** Decode the initialization string as described in the constructor.
+     *  @see BitFieldCoder( const std::string& initString )
+     */
+    void init( const std::string& initString) ;
+
+  public:
+
+  protected:
+
+    // -------------- data members:--------------
+
+    std::vector<BitFieldValue*> _fields{} ;
+    IndexMap  _map{} ;
+    long64    _joined{} ;
+
+
+  };
+
+
+ /** Helper class  for string tokenization. Usage:<br>
+   *    std::vector<std::string> tokens ; <br>
+   *    StringTokenizer t( tokens ,',') ; <br>
+   *    std::for_each( aString.begin(), aString.end(), t ) ;  <br>
+   *
+   *    @author F.Gaede, DESY
+   *    @date  2013-06
+   */
+  class StringTokenizer{
+    
+    std::vector< std::string >& _tokens ;
+    char _del ;
+    char _last ;
+
+  public:
+    
+    /** Only c'tor, give (empty) token vector and delimeter character */
+    StringTokenizer( std::vector< std::string >& tokens, char del ) 
+      : _tokens(tokens) 
+	, _del(del), 
+	_last(del) {
+    }
+    
+    /** Operator for use with algorithms, e.g. for_each */
+    void operator()(const char& c) { 
+      
+      if( c != _del  ) {
+	
+	if( _last == _del  ) {
+	  _tokens.push_back("") ; 
+	}
+	_tokens.back() += c ;
+      }
+      _last = c ;
+    } 
+    
+  };
+
+} // end namespace
+
+} // end namespace
+
+#endif
+
+
+
+
diff --git a/DDCore/src/segmentations/BitFieldCoder.cpp b/DDCore/src/segmentations/BitFieldCoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..02f2e334e62593630bf5e8df3d8e7cf6d88b4ced
--- /dev/null
+++ b/DDCore/src/segmentations/BitFieldCoder.cpp
@@ -0,0 +1,246 @@
+#include "DDSegmentation/BitFieldCoder.h"
+
+#include <cmath>
+#include <algorithm>
+#include <stdexcept>
+
+namespace dd4hep{
+
+namespace DDSegmentation {
+  
+  BitFieldCoder::BitFieldValue::BitFieldValue( const std::string& fieldName,
+				unsigned fieldOffset, int signedWidth ) :
+    _mask(0), 
+    _offset( fieldOffset ),
+    _width( abs( signedWidth ) ),
+    _minVal(0),
+    _maxVal(0),
+    _isSigned( signedWidth < 0 ),
+    _name( fieldName ) {
+    
+    // sanity check
+    if( _offset > 63 || _offset+_width > 64 ) {
+      
+      std::stringstream s ;
+      s << " BitFieldValue '" << _name << "': out of range -  offset : " 
+	<< _offset  << " width " << _width  ;
+      
+      throw( std::runtime_error( s.str() ) ) ;
+    }
+    
+    _mask = ( ( 0x0001LL << _width ) - 1 ) << _offset ;
+    
+    
+    // compute extreme values for later checks
+    if( _isSigned ){
+      
+      _minVal =  ( 1LL << ( _width - 1 ) ) - ( 1LL << _width )  ;
+      _maxVal =  ( 1LL << ( _width - 1 ) ) - 1 ;
+      
+    } else {
+      
+      _maxVal = 0x0001<<_width  ;
+    }
+    
+  }
+  
+
+  long64 BitFieldCoder::BitFieldValue::value(long64 id) const { 
+      
+    if(  _isSigned   ) {
+
+      long64 val = ( id & _mask ) >> _offset ;
+      
+      if( ( val  & ( 1LL << ( _width - 1 ) ) ) != 0 ) { // negative value
+	  
+	val -= ( 1LL << _width );
+      }
+	
+      return val ;
+
+    } else { 
+      
+      return  ( id & _mask ) >> _offset ;
+    }
+  }
+
+  void BitFieldCoder::BitFieldValue::set(long64& field, long64 in) {
+    
+    // check range 
+    if( in < _minVal || in > _maxVal  ) {
+      
+      std::stringstream s ;
+      s << " BitFieldValue '" << _name << "': out of range : " << in 
+	<< " for width " << _width  ; 
+      
+      throw( std::runtime_error( s.str() ) );
+    }
+    
+    field &= ~_mask ;  // zero out the field's range
+    
+    field |=  ( (  in  << _offset )  & _mask  ) ; 
+
+  }
+  
+
+
+
+  size_t BitFieldCoder::index( const std::string& name) const {
+    
+    IndexMap::const_iterator it = _map.find( name ) ;
+    
+    if( it != _map.end() ) 
+      
+      return it->second  ;
+    
+    else
+      throw std::runtime_error(" BitFieldValue: unknown name: " + name ) ;
+  }
+  
+  unsigned BitFieldCoder::highestBit() const {
+    
+    unsigned hb(0) ;
+    
+    for(unsigned i=0;i<_fields.size();i++){
+      
+      if( hb < ( _fields[i]->offset() + _fields[i]->width() ) )
+	hb = _fields[i]->offset() + _fields[i]->width()  ;
+    }    
+    return hb ;
+  }
+
+
+  std::string BitFieldCoder::valueString(ulong64 bitfield) const {
+
+    std::stringstream  os ;
+
+    for(unsigned i=0;i<_fields.size();i++){
+      
+      if( i != 0 )   os << "," ;
+
+      os << _fields[i]->name() <<  ":" << _fields[i]->value(bitfield) ;
+
+    }
+    return os.str() ;
+  }
+  
+  std::string BitFieldCoder::fieldDescription() const {
+    
+    std::stringstream  os ;
+    
+    for(unsigned i=0;i<_fields.size();i++){
+      
+      if( i != 0 )   os << "," ;
+      
+      os << _fields[i]->name() <<  ":"
+	 << _fields[i]->offset() << ":" ;
+      
+      if(  _fields[i]->isSigned()  )  
+	os << "-" ;
+      
+      os  << _fields[i]->width() ;
+      
+    }
+//     for( IndexMap::const_iterator it = _map.begin()  ;
+// 	 it !=  _map.end() ; ++it ){
+
+//       if( it !=  _map.begin() )
+// 	os << "," ;
+      
+//       os << it->first <<  ":"
+// 	 << _fields[ it->second ]->offset() << ":" ;
+      
+//       if(  _fields[ it->second ]->isSigned()  )  
+// 	os << "-" ;
+
+//       os  << _fields[ it->second ]->width() ;
+
+//     }
+    
+    return os.str() ;
+  }
+
+  void BitFieldCoder::addField( const std::string& name,  unsigned offset, int width ){
+
+      
+    BitFieldValue* bfv =  new  BitFieldValue( name, offset, width ) ;
+
+    _fields.push_back(  bfv ) ;
+    
+    _map[ name ] = _fields.size()-1 ;
+
+    if( _joined & bfv->mask()  ) {
+      
+      std::stringstream s ;
+      s << " BitFieldValue::addField(" << name << "): bits already used " << std::hex << _joined
+	<< " for mask " <<  bfv->mask()   ; 
+
+      throw( std::runtime_error( s.str() ) ) ;
+      
+    }
+
+    _joined |= _fields.back()->mask() ;
+
+  }
+
+  void BitFieldCoder::init( const std::string& initString) {
+
+    unsigned offset = 0  ;
+    
+    // need to compute bit field masks and offsets ...
+    std::vector<std::string> fieldDescriptors ;
+    StringTokenizer t( fieldDescriptors ,',') ;
+
+    std::for_each( initString.begin(), initString.end(), t ) ; 
+
+    for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){
+      
+      std::vector<std::string> subfields ;
+      StringTokenizer ts( subfields ,':') ;
+      
+      std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts );
+
+      std::string name ; 
+      int  width ; 
+      unsigned thisOffset ;
+
+      switch( subfields.size() ){
+	
+      case 2: 
+
+	name = subfields[0] ; 
+	width = atol( subfields[1].c_str()  ) ;
+	thisOffset = offset ;
+
+	offset += abs( width ) ;
+	
+	break ;
+	
+      case 3: 
+	name = subfields[0] ;
+	thisOffset = atol( subfields[1].c_str()  ) ;
+	width = atol( subfields[2].c_str()  ) ;
+
+	offset = thisOffset + abs( width ) ;
+
+	break ;
+	
+      default:
+
+	std::stringstream s ;
+	s << " BitFieldCoder: invalid number of subfields " 
+	  <<  fieldDescriptors[i] ;
+
+	throw( std::runtime_error( s.str() ) ) ;
+      }
+
+      addField( name , thisOffset, width ) ;
+    }
+  }
+
+
+
+
+} // namespace
+
+} // namespace
diff --git a/DDTest/CMakeLists.txt b/DDTest/CMakeLists.txt
index 9f164540288e94acbce66cfaae815bb4c57d0419..52859d728fe6560667bb1986aee52f7429fe84e2 100644
--- a/DDTest/CMakeLists.txt
+++ b/DDTest/CMakeLists.txt
@@ -21,6 +21,7 @@ dd4hep_add_test_reg ( test_surface             BUILD_EXEC REGEX_FAIL "TEST_FAILE
   EXEC_ARGS file:${CMAKE_CURRENT_SOURCE_DIR}/units.xml )
 
 dd4hep_add_test_reg ( test_bitfield64          BUILD_EXEC REGEX_FAIL "TEST_FAILED" )
+dd4hep_add_test_reg ( test_bitfieldcoder       BUILD_EXEC REGEX_FAIL "TEST_FAILED" )
 dd4hep_add_test_reg ( test_DetType             BUILD_EXEC REGEX_FAIL "TEST_FAILED" )
 dd4hep_add_test_reg ( test_PolarGridRPhi2      BUILD_EXEC REGEX_FAIL "TEST_FAILED" )
 dd4hep_add_test_reg ( test_cellDimensions      BUILD_EXEC REGEX_FAIL "TEST_FAILED" )