Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:25

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