Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 09:36:48

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 //==========================================================================
0011 #include <DDSegmentation/BitFieldCoder.h>
0012 
0013 #include <cmath>
0014 #include <algorithm>
0015 #include <stdexcept>
0016 
0017 namespace dd4hep{
0018 
0019   namespace DDSegmentation {
0020   
0021     BitFieldElement::BitFieldElement( const std::string& fieldName,
0022                                       unsigned fieldOffset, int signedWidth ) :
0023       _mask(0), 
0024       _offset( fieldOffset ),
0025       _width( abs( signedWidth ) ),
0026       _minVal(0),
0027       _maxVal(0),
0028       _isSigned( signedWidth < 0 ),
0029       _name( fieldName ) {
0030     
0031       // sanity check
0032       if( _offset > 63 || _offset+_width > 64 ) {
0033       
0034         std::stringstream s ;
0035         s << " BitFieldElement '" << _name << "': out of range -  offset : " 
0036           << _offset  << " width " << _width  ;
0037       
0038         throw( std::runtime_error( s.str() ) ) ;
0039       }
0040     
0041       _mask = ( ( 0x0001LL << _width ) - 1 ) << _offset ;
0042     
0043     
0044       // compute extreme values for later checks
0045       if( _isSigned ){
0046       
0047         _minVal =  ( 1LL << ( _width - 1 ) ) - ( 1LL << _width )  ;
0048         _maxVal =  ( 1LL << ( _width - 1 ) ) - 1 ;
0049       
0050       } else {
0051         _maxVal = 0x0001<<_width  ;
0052       }
0053     }
0054   
0055     FieldID BitFieldElement::value(CellID id) const { 
0056       if(  _isSigned   ) {
0057         FieldID val = ( id & _mask ) >> _offset ;
0058         if( ( val  & ( 1LL << ( _width - 1 ) ) ) != 0 ) { // negative value
0059           val -= ( 1LL << _width );
0060         }
0061         return val ;
0062       } else { 
0063         return  ( id & _mask ) >> _offset ;
0064       }
0065     }
0066 
0067     void BitFieldElement::set(CellID& field, FieldID in) const {
0068     
0069       // check range 
0070       if( in < _minVal || in > _maxVal  ) {
0071         std::stringstream s ;
0072         s << " BitFieldElement '" << _name << "': out of range : " << in 
0073           << " for width " << _width  ; 
0074         throw( std::runtime_error( s.str() ) );
0075       }
0076     
0077       field &= ~_mask ;  // zero out the field's range
0078       field |=  ( (  in  << _offset )  & _mask  ) ; 
0079     }
0080   
0081 
0082 
0083 
0084     size_t BitFieldCoder::index( const std::string& name) const {
0085     
0086       IndexMap::const_iterator it = _map.find( name ) ;
0087     
0088       if( it != _map.end() ) 
0089       
0090         return it->second  ;
0091     
0092       else
0093         throw std::runtime_error(" BitFieldElement: unknown name: " + name ) ;
0094     }
0095   
0096     unsigned BitFieldCoder::highestBit() const {
0097     
0098       unsigned hb(0) ;
0099     
0100       for(unsigned i=0;i<_fields.size();i++){
0101       
0102         if( hb < ( _fields[i].offset() + _fields[i].width() ) )
0103           hb = _fields[i].offset() + _fields[i].width()  ;
0104       }    
0105       return hb ;
0106     }
0107 
0108 
0109     std::string BitFieldCoder::valueString(CellID bitfield) const {
0110 
0111       std::stringstream  os ;
0112 
0113       for(unsigned i=0;i<_fields.size();i++){
0114       
0115         if( i != 0 )   os << "," ;
0116 
0117         os << _fields[i].name() <<  ":" << _fields[i].value(bitfield) ;
0118 
0119       }
0120       return os.str() ;
0121     }
0122   
0123     std::string BitFieldCoder::fieldDescription() const {
0124     
0125       std::stringstream  os ;
0126     
0127       for(unsigned i=0;i<_fields.size();i++){
0128       
0129         if( i != 0 )   os << "," ;
0130       
0131         os << _fields[i].name() <<  ":"
0132            << _fields[i].offset() << ":" ;
0133       
0134         if(  _fields[i].isSigned()  )
0135           os << "-" ;
0136       
0137         os  << _fields[i].width() ;
0138       
0139       }
0140 
0141       return os.str() ;
0142     }
0143 
0144     void BitFieldCoder::addField( const std::string& name,  unsigned offset, int width ){
0145 
0146       
0147       _fields.emplace_back(name, offset, width);
0148       BitFieldElement& bfv = _fields.back() ;
0149 
0150       _map[ name ] = _fields.size()-1 ;
0151 
0152       if( _joined & bfv.mask()  ) {
0153       
0154         std::stringstream s ;
0155         s << " BitFieldElement::addField(" << name << "): bits already used " << std::hex << _joined
0156           << " for mask " <<  bfv.mask() ;
0157 
0158         throw( std::runtime_error( s.str() ) ) ;
0159       
0160       }
0161 
0162       _joined |= bfv.mask() ;
0163 
0164     }
0165 
0166     void BitFieldCoder::init( const std::string& initString) {
0167 
0168       unsigned offset = 0  ;
0169     
0170       // need to compute bit field masks and offsets ...
0171       std::vector<std::string> fieldDescriptors ;
0172       StringTokenizer t( fieldDescriptors ,',') ;
0173 
0174       std::for_each( initString.begin(), initString.end(), t ) ; 
0175 
0176       for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){
0177       
0178         std::vector<std::string> subfields ;
0179         StringTokenizer ts( subfields ,':') ;
0180       
0181         std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts );
0182 
0183         std::string name ; 
0184         int  width ; 
0185         unsigned thisOffset ;
0186 
0187         switch( subfields.size() ){
0188     
0189         case 2: 
0190 
0191           name = subfields[0] ; 
0192           width = atol( subfields[1].c_str()  ) ;
0193           thisOffset = offset ;
0194 
0195           offset += abs( width ) ;
0196     
0197           break ;
0198     
0199         case 3: 
0200           name = subfields[0] ;
0201           thisOffset = atol( subfields[1].c_str()  ) ;
0202           width = atol( subfields[2].c_str()  ) ;
0203 
0204           offset = thisOffset + abs( width ) ;
0205 
0206           break ;
0207     
0208         default:
0209 
0210           std::stringstream s ;
0211           s << " BitFieldCoder: invalid number of subfields " 
0212             <<  fieldDescriptors[i] ;
0213 
0214           throw( std::runtime_error( s.str() ) ) ;
0215         }
0216 
0217         addField( name , thisOffset, width ) ;
0218       }
0219     }
0220 
0221 
0222 
0223 
0224   } // namespace
0225 
0226 } // namespace