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