Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-03 08:34:28

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 
0012 #ifndef DDSEGMENTATION_BITFIELDCODER_H
0013 #define DDSEGMENTATION_BITFIELDCODER_H 1
0014 
0015 #include <map>
0016 #include <string>
0017 #include <vector>
0018 #include <cstdint>
0019 
0020 namespace dd4hep {
0021 
0022   namespace DDSegmentation {
0023 
0024     typedef int64_t  FieldID;
0025     typedef uint64_t CellID;
0026     typedef uint64_t VolumeID;
0027 
0028     class StringTokenizer ; 
0029 
0030     /// Helper class for BitFieldCoder that corresponds to one field value. 
0031     class BitFieldElement   {
0032   
0033     public :
0034       /// Default constructor
0035       BitFieldElement() = default ;
0036       /// Copy constructor
0037       BitFieldElement(const BitFieldElement&) = default ;
0038       /// Move constructor
0039       BitFieldElement(BitFieldElement&&) = default ;
0040 
0041       /** The standard c'tor.
0042        * @param  name          name of the field
0043        * @param  offset        offset of field
0044        * @param  signedWidth   width of field, negative if field is signed
0045        */
0046       BitFieldElement( const std::string& name, unsigned offset, int signedWidth ) ; 
0047       /// Default destructor
0048       ~BitFieldElement() = default ;
0049 
0050       /// Assignment operator
0051       BitFieldElement& operator=(const BitFieldElement&) = default ;
0052 
0053       /// calculate this field's value given an external 64 bit bitmap 
0054       FieldID value(CellID bitfield) const;
0055 
0056       // assign the given value to the bit field
0057       void set(CellID& bitfield, FieldID value) const ;
0058 
0059       /** The field's name */
0060       const std::string& name() const { return _name ; }
0061 
0062       /** The field's offset */
0063       unsigned offset() const { return _offset ; }
0064 
0065       /** The field's width */
0066       unsigned width() const  { return _width ; }
0067 
0068       /** True if field is interpreted as signed */
0069       bool isSigned() const   { return _isSigned ; }
0070 
0071       /** The field's mask */
0072       CellID mask() const     { return _mask ; }
0073 
0074       /** Minimal value  */
0075       int  minValue()  const  { return _minVal;  }
0076 
0077       /** Maximal value  */
0078       int  maxValue()  const  { return _maxVal;  }
0079 
0080     protected:
0081   
0082       CellID _mask      {};
0083       unsigned _offset  {};
0084       unsigned _width   {};
0085       int _minVal       {};
0086       int _maxVal       {};
0087       bool _isSigned    {};
0088       std::string _name;
0089     };
0090 
0091 
0092   
0093     /// Helper class for decoding and encoding a bit field of 64bits for convenient declaration
0094     /** and manipulation of sub fields of various widths.<br>
0095      *  This is a thread safe re-implementation of the functionality in the deprected BitField64.
0096      *  
0097      *  Example:<br>
0098      *    BitFieldCoder bc("layer:7,system:-3,barrel:3,theta:32:11,phi:11" ) ; <br> 
0099      *    bc.set( field,  "layer"  , 123 );         <br> 
0100      *    bc.set( field,  "system" , -4  );         <br> 
0101      *    bc.set( field,  "barrel" , 7   );         <br> 
0102      *    bc.set( field,  "theta"  , 180 );         <br> 
0103      *    bc.set( field,  "phi"    , 270 );         <br> 
0104      *    ...                                       <br>
0105      *    int theta = bc.get( field, "theta" ) ;                    <br>
0106      *    ...                                       <br>
0107      *    unsigned phiIndex = bc.index("phi") ;     <br>
0108      *    int phi = bc.get( field, phiIndex ) ;                <br>
0109      *
0110      *    @author F.Gaede, DESY
0111      *    @date  2017-09
0112      */  
0113     class BitFieldCoder{
0114     public :
0115       typedef std::map<std::string, unsigned int> IndexMap ;
0116 
0117     public :
0118       /// Default constructor
0119       BitFieldCoder() = default ;
0120       /// Copy constructor
0121       BitFieldCoder(const BitFieldCoder&) = default ;
0122       /// Move constructor
0123       BitFieldCoder(BitFieldCoder&&) = default ;
0124       /// Default destructor
0125       ~BitFieldCoder() = default ;
0126 
0127       /// Assignment operator
0128       BitFieldCoder& operator=(const BitFieldCoder&) = default ;
0129     
0130       /** The c'tor takes an initialization string of the form:<br>
0131        *  \<fieldDesc\>[,\<fieldDesc\>...]<br>
0132        *  fieldDesc = name:[start]:[-]length<br>
0133        *  where:<br>
0134        *  name: The name of the field<br>
0135        *  start: The start bit of the field. If omitted assumed to start 
0136        *  immediately following previous field, or at the least significant 
0137        *  bit if the first field.<br>
0138        *  length: The number of bits in the field. If preceeded by '-' 
0139        *  the field is signed, otherwise unsigned.<br>
0140        *  Bit numbering is from the least significant bit (bit 0) to the most 
0141        *  significant (bit 63). <br>
0142        *  Example: "layer:7,system:-3,barrel:3,theta:32:11,phi:11"
0143        */
0144       BitFieldCoder( const std::string& initString ) : _joined(0){
0145         init( initString ) ;
0146       }
0147 
0148       /** return a new 64bit value given as high and low 32bit words.
0149        */
0150       static CellID toLong(unsigned low_Word, unsigned high_Word ) {
0151         return (  ( low_Word & 0xffffffffULL ) |  ( ( high_Word & 0xffffffffULL ) << 32 ) ) ; 
0152       }
0153     
0154       /** The low  word, bits 0-31
0155        */
0156       static unsigned lowWord(CellID bitfield)  { return unsigned( bitfield &  0xffffFFFFUL ); } 
0157 
0158       /** The high  word, bits 32-63
0159        */
0160       static unsigned highWord(CellID bitfield) { return unsigned( bitfield >> 32); }
0161 
0162       /** get value of sub-field specified by index 
0163        */
0164       FieldID get(CellID bitfield, size_t idx) const { 
0165         return _fields.at(idx).value( bitfield )  ;
0166       }
0167     
0168       /** Access to field through name .
0169        */
0170       FieldID get(CellID bitfield, const std::string& name) const {
0171         return _fields.at( index( name ) ).value( bitfield ) ;
0172       }
0173 
0174       /** set value of sub-field specified by index 
0175        */
0176       void set(CellID& bitfield, size_t idx, FieldID value) const { 
0177         _fields.at(idx).set( bitfield , value )  ;
0178       }
0179     
0180       /** Access to field through name .
0181        */
0182       void set(CellID& bitfield, const std::string& name, FieldID value) const {
0183         _fields.at( index( name ) ).set( bitfield, value ) ;
0184       }
0185 
0186       /** Highest bit used in fields [0-63]
0187        */
0188       unsigned highestBit() const ;
0189 
0190       /** Number of values */
0191       size_t size() const { return _fields.size() ; }
0192 
0193       /** Index for field named 'name' 
0194        */
0195       size_t index( const std::string& name) const ;
0196 
0197       /** Const Access to field through name .
0198        */
0199       const BitFieldElement& operator[](const std::string& name) const { 
0200         return _fields[ index( name ) ] ;
0201       }
0202 
0203       /** Const Access to field through index .
0204        */
0205       const BitFieldElement& operator[](unsigned idx) const { 
0206         return _fields[ idx ] ;
0207       }
0208 
0209       /** Return a valid description string of all fields
0210        */
0211       std::string fieldDescription() const ;
0212 
0213       /** Return a string with a comma separated list of the current sub field values 
0214        */
0215       std::string valueString(CellID bitfield) const ;
0216 
0217       const std::vector<BitFieldElement>& fields()  const  {
0218         return _fields;
0219       }
0220     
0221       /** the mask of all the bits used in the description */
0222       CellID mask() const { return _joined ; }
0223 
0224     protected:
0225 
0226       /** Add an additional field to the list 
0227        */
0228       void addField( const std::string& name,  unsigned offset, int width ); 
0229 
0230       /** Decode the initialization string as described in the constructor.
0231        *  @see BitFieldCoder( const std::string& initString )
0232        */
0233       void init( const std::string& initString) ;
0234 
0235     protected:
0236       // -------------- data members:--------------
0237       std::vector<BitFieldElement> _fields{} ;
0238       IndexMap  _map{} ;
0239       CellID    _joined{} ;
0240     };
0241 
0242 
0243     /// Helper class  for string tokenization.
0244     /**  Usage:<br>
0245      *    std::vector<std::string> tokens ; <br>
0246      *    StringTokenizer t( tokens ,',') ; <br>
0247      *    std::for_each( aString.begin(), aString.end(), t ) ;  <br>
0248      *
0249      *    @author F.Gaede, DESY
0250      *    @date  2013-06
0251      */
0252     class StringTokenizer{
0253       std::vector< std::string >& _tokens ;
0254       char _del ;
0255       char _last ;
0256 
0257     public:
0258     
0259       /** Only c'tor, give (empty) token vector and delimeter character */
0260       StringTokenizer( std::vector< std::string >& tokens, char del ) 
0261         : _tokens(tokens) 
0262         , _del(del), 
0263           _last(del) {
0264       }
0265     
0266       /** Operator for use with algorithms, e.g. for_each */
0267       void operator()(const char& c) { 
0268         if( c != _del  ) {
0269           if( _last == _del  ) {
0270             _tokens.emplace_back("") ; 
0271           }
0272           _tokens.back() += c ;
0273         }
0274         _last = c ;
0275       } 
0276     };
0277 
0278   } // end namespace
0279 } // end namespace
0280 #endif
0281 
0282 
0283 
0284