DD4hep  1.30.0
Detector Description Toolkit for High Energy Physics
BitFieldCoder.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 //==========================================================================
12 
13 #include <cmath>
14 #include <algorithm>
15 #include <stdexcept>
16 
17 namespace dd4hep{
18 
19  namespace DDSegmentation {
20 
21  BitFieldElement::BitFieldElement( const std::string& fieldName,
22  unsigned fieldOffset, int signedWidth ) :
23  _mask(0),
24  _offset( fieldOffset ),
25  _width( abs( signedWidth ) ),
26  _minVal(0),
27  _maxVal(0),
28  _isSigned( signedWidth < 0 ),
29  _name( fieldName ) {
30 
31  // sanity check
32  if( _offset > 63 || _offset+_width > 64 ) {
33 
34  std::stringstream s ;
35  s << " BitFieldElement '" << _name << "': out of range - offset : "
36  << _offset << " width " << _width ;
37 
38  throw( std::runtime_error( s.str() ) ) ;
39  }
40 
41  _mask = ( ( 0x0001LL << _width ) - 1 ) << _offset ;
42 
43 
44  // compute extreme values for later checks
45  if( _isSigned ){
46 
47  _minVal = ( 1LL << ( _width - 1 ) ) - ( 1LL << _width ) ;
48  _maxVal = ( 1LL << ( _width - 1 ) ) - 1 ;
49 
50  } else {
51  _maxVal = 0x0001<<_width ;
52  }
53  }
54 
56  if( _isSigned ) {
57  FieldID val = ( id & _mask ) >> _offset ;
58  if( ( val & ( 1LL << ( _width - 1 ) ) ) != 0 ) { // negative value
59  val -= ( 1LL << _width );
60  }
61  return val ;
62  } else {
63  return ( id & _mask ) >> _offset ;
64  }
65  }
66 
67  void BitFieldElement::set(CellID& field, FieldID in) const {
68 
69  // check range
70  if( in < _minVal || in > _maxVal ) {
71  std::stringstream s ;
72  s << " BitFieldElement '" << _name << "': out of range : " << in
73  << " for width " << _width ;
74  throw( std::runtime_error( s.str() ) );
75  }
76 
77  field &= ~_mask ; // zero out the field's range
78  field |= ( ( in << _offset ) & _mask ) ;
79  }
80 
81 
82 
83 
84  size_t BitFieldCoder::index( const std::string& name) const {
85 
86  IndexMap::const_iterator it = _map.find( name ) ;
87 
88  if( it != _map.end() )
89 
90  return it->second ;
91 
92  else
93  throw std::runtime_error(" BitFieldElement: unknown name: " + name ) ;
94  }
95 
96  unsigned BitFieldCoder::highestBit() const {
97 
98  unsigned hb(0) ;
99 
100  for(unsigned i=0;i<_fields.size();i++){
101 
102  if( hb < ( _fields[i].offset() + _fields[i].width() ) )
103  hb = _fields[i].offset() + _fields[i].width() ;
104  }
105  return hb ;
106  }
107 
108 
109  std::string BitFieldCoder::valueString(CellID bitfield) const {
110 
111  std::stringstream os ;
112 
113  for(unsigned i=0;i<_fields.size();i++){
114 
115  if( i != 0 ) os << "," ;
116 
117  os << _fields[i].name() << ":" << _fields[i].value(bitfield) ;
118 
119  }
120  return os.str() ;
121  }
122 
123  std::string BitFieldCoder::fieldDescription() const {
124 
125  std::stringstream os ;
126 
127  for(unsigned i=0;i<_fields.size();i++){
128 
129  if( i != 0 ) os << "," ;
130 
131  os << _fields[i].name() << ":"
132  << _fields[i].offset() << ":" ;
133 
134  if( _fields[i].isSigned() )
135  os << "-" ;
136 
137  os << _fields[i].width() ;
138 
139  }
140 
141  return os.str() ;
142  }
143 
144  void BitFieldCoder::addField( const std::string& name, unsigned offset, int width ){
145 
146 
147  _fields.emplace_back(name, offset, width);
148  BitFieldElement& bfv = _fields.back() ;
149 
150  _map[ name ] = _fields.size()-1 ;
151 
152  if( _joined & bfv.mask() ) {
153 
154  std::stringstream s ;
155  s << " BitFieldElement::addField(" << name << "): bits already used " << std::hex << _joined
156  << " for mask " << bfv.mask() ;
157 
158  throw( std::runtime_error( s.str() ) ) ;
159 
160  }
161 
162  _joined |= bfv.mask() ;
163 
164  }
165 
166  void BitFieldCoder::init( const std::string& initString) {
167 
168  unsigned offset = 0 ;
169 
170  // need to compute bit field masks and offsets ...
171  std::vector<std::string> fieldDescriptors ;
172  StringTokenizer t( fieldDescriptors ,',') ;
173 
174  std::for_each( initString.begin(), initString.end(), t ) ;
175 
176  for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){
177 
178  std::vector<std::string> subfields ;
179  StringTokenizer ts( subfields ,':') ;
180 
181  std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts );
182 
183  std::string name ;
184  int width ;
185  unsigned thisOffset ;
186 
187  switch( subfields.size() ){
188 
189  case 2:
190 
191  name = subfields[0] ;
192  width = atol( subfields[1].c_str() ) ;
193  thisOffset = offset ;
194 
195  offset += abs( width ) ;
196 
197  break ;
198 
199  case 3:
200  name = subfields[0] ;
201  thisOffset = atol( subfields[1].c_str() ) ;
202  width = atol( subfields[2].c_str() ) ;
203 
204  offset = thisOffset + abs( width ) ;
205 
206  break ;
207 
208  default:
209 
210  std::stringstream s ;
211  s << " BitFieldCoder: invalid number of subfields "
212  << fieldDescriptors[i] ;
213 
214  throw( std::runtime_error( s.str() ) ) ;
215  }
216 
217  addField( name , thisOffset, width ) ;
218  }
219  }
220 
221 
222 
223 
224  } // namespace
225 
226 } // namespace
dd4hep::DDSegmentation::BitFieldElement::_minVal
int _minVal
Definition: BitFieldCoder.h:86
dd4hep::DDSegmentation::BitFieldElement
Helper class for BitFieldCoder that corresponds to one field value.
Definition: BitFieldCoder.h:32
dd4hep::DDSegmentation::BitFieldElement::_name
std::string _name
Definition: BitFieldCoder.h:89
dd4hep::DDSegmentation::BitFieldElement::_mask
CellID _mask
Definition: BitFieldCoder.h:83
dd4hep::DDSegmentation::StringTokenizer
Helper class for string tokenization.
Definition: BitFieldCoder.h:253
dd4hep::DDSegmentation::BitFieldElement::value
FieldID value(CellID bitfield) const
calculate this field's value given an external 64 bit bitmap
Definition: BitFieldCoder.cpp:55
dd4hep::DDSegmentation::BitFieldElement::_isSigned
bool _isSigned
Definition: BitFieldCoder.h:88
dd4hep::DDSegmentation::BitFieldCoder::_map
IndexMap _map
Definition: BitFieldCoder.h:239
dd4hep::DDSegmentation::BitFieldCoder::_fields
std::vector< BitFieldElement > _fields
Definition: BitFieldCoder.h:238
dd4hep::DDSegmentation::BitFieldCoder::highestBit
unsigned highestBit() const
Definition: BitFieldCoder.cpp:96
dd4hep::DDSegmentation::BitFieldCoder::valueString
std::string valueString(CellID bitfield) const
Definition: BitFieldCoder.cpp:109
dd4hep::DDSegmentation::BitFieldCoder::addField
void addField(const std::string &name, unsigned offset, int width)
Definition: BitFieldCoder.cpp:144
dd4hep::DDSegmentation::FieldID
int64_t FieldID
Definition: BitFieldCoder.h:25
dd4hep::DDSegmentation::BitFieldElement::set
void set(CellID &bitfield, FieldID value) const
Definition: BitFieldCoder.cpp:67
BitFieldCoder.h
dd4hep::DDSegmentation::BitFieldElement::mask
CellID mask() const
Definition: BitFieldCoder.h:73
dd4hep::DDSegmentation::CellID
uint64_t CellID
Definition: BitFieldCoder.h:26
dd4hep::DDSegmentation::BitFieldCoder::index
size_t index(const std::string &name) const
Definition: BitFieldCoder.cpp:84
dd4hep::DDSegmentation::BitFieldElement::_maxVal
int _maxVal
Definition: BitFieldCoder.h:87
dd4hep::DDSegmentation::BitFieldElement::_width
unsigned _width
Definition: BitFieldCoder.h:85
dd4hep::DDSegmentation::BitFieldCoder::_joined
CellID _joined
Definition: BitFieldCoder.h:240
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::DDSegmentation::BitFieldCoder::init
void init(const std::string &initString)
Definition: BitFieldCoder.cpp:166
dd4hep::DDSegmentation::BitFieldCoder::fieldDescription
std::string fieldDescription() const
Definition: BitFieldCoder.cpp:123
dd4hep::DDSegmentation::BitFieldElement::BitFieldElement
BitFieldElement()=default
Default constructor.
dd4hep::DDSegmentation::BitFieldElement::_offset
unsigned _offset
Definition: BitFieldCoder.h:84