Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-01 07:50:46

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 // Author     : A.Sailer
0011 //
0012 //==========================================================================
0013 #ifndef DDG4_PLUGINS_GEANT4EVENTSEED_H
0014 #define DDG4_PLUGINS_GEANT4EVENTSEED_H
0015 
0016 // Framework include files
0017 #include <DDG4/Geant4RunAction.h>
0018 
0019 
0020 
0021 /// Namespace for the AIDA detector description toolkit
0022 namespace dd4hep {
0023 
0024   /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0025   namespace sim {
0026 
0027     /**
0028      * \addtogroup Geant4RunActions
0029      * @{
0030      * \package EventSeed
0031      * \brief   Set the event seed for each event
0032      *
0033      *  This plugins allows one to skip events and still be reproducible.
0034      *  We are using jenkins_hash from an intial seed, runID and eventID
0035      *  see http://burtleburtle.net/bob/hash/evahash.html
0036      *
0037      *  \author  A.Sailer
0038      *  \version 1.0
0039      *  \ingroup DD4HEP_SIMULATION
0040      * @}
0041      */
0042     /// Plugin class to set the event seed for each event
0043     class Geant4EventSeed: public Geant4RunAction {
0044 
0045     protected:
0046       unsigned int m_initialSeed;
0047       unsigned int m_runID;
0048       std::string m_type;
0049       bool m_initialised;
0050     public:
0051       /// Standard constructor with initializing arguments
0052       Geant4EventSeed(Geant4Context*, const std::string& );
0053       /// Default destructor
0054       virtual ~Geant4EventSeed();
0055       /// begin-of-run callback
0056       void begin(const G4Run*);
0057       /// begin-of-event callback
0058       void beginEvent(const G4Event*);
0059     };
0060 
0061     /*
0062 
0063       Hashing for random seed as used in Marlin EventSeeder processor
0064 
0065       Original source by Bob Jenkins
0066 
0067       http://www.burtleburtle.net/bob/hash/doobs.html
0068 
0069       Hash a variable-length key into a 32-bit value
0070 
0071     */
0072 
0073 #define hashsize(n) ( 1U << (n) )
0074 #define hashmask(n) ( hashsize ( n ) - 1 )
0075 
0076 
0077     /*
0078       --------------------------------------------------------------------
0079       mix -- mix 3 32-bit values reversibly.
0080       For every delta with one or two bits set, and the deltas of all three
0081       high bits or all three low bits, whether the original value of a,b,c
0082       is almost all zero or is uniformly distributed,
0083       * If mix() is run forward or backward, at least 32 bits in a,b,c
0084       have at least 1/4 probability of changing.
0085       * If mix() is run forward, every bit of c will change between 1/3 and
0086       2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
0087       mix() was built out of 36 single-cycle latency instructions in a
0088       structure that could supported 2x parallelism, like so:
0089       a -= b;
0090       a -= c; x = (c>>13);
0091       b -= c; a ^= x;
0092       b -= a; x = (a<<8);
0093       c -= a; b ^= x;
0094       c -= b; x = (b>>13);
0095       ...
0096       Unfortunately, superscalar Pentiums and Sparcs can't take advantage
0097       of that parallelism.  They've also turned some of those single-cycle
0098       latency instructions into multi-cycle latency instructions.  Still,
0099       this is the fastest good hash I could find.  There were about 2^^68
0100       to choose from.  I only looked at a billion or so.
0101       --------------------------------------------------------------------
0102     */
0103 #define mix(a,b,c)                              \
0104     {                                           \
0105       a -= b; a -= c; a ^= (c>>13);             \
0106       b -= c; b -= a; b ^= (a<<8);              \
0107       c -= a; c -= b; c ^= (b>>13);             \
0108       a -= b; a -= c; a ^= (c>>12);             \
0109       b -= c; b -= a; b ^= (a<<16);             \
0110       c -= a; c -= b; c ^= (b>>5);              \
0111       a -= b; a -= c; a ^= (c>>3);              \
0112       b -= c; b -= a; b ^= (a<<10);             \
0113       c -= a; c -= b; c ^= (b>>15);             \
0114     }
0115 
0116     /*
0117       --------------------------------------------------------------------
0118       jenkins_hash() -- hash a variable-length key into a 32-bit value
0119       k       : the key (the unaligned variable-length array of bytes)
0120       len     : the length of the key, counting by bytes
0121       initval : can be any 4-byte value
0122       Returns a 32-bit value.  Every bit of the key affects every bit of
0123       the return value.  Every 1-bit and 2-bit delta achieves avalanche.
0124       About 6*len+35 instructions.
0125 
0126       The best hash table sizes are powers of 2.  There is no need to do
0127       mod a prime (mod is sooo slow!).  If you need less than 32 bits,
0128       use a bitmask.  For example, if you need only 10 bits, do
0129       h = (h & hashmask(10));
0130       In which case, the hash table should have hashsize(10) elements.
0131 
0132       If you are hashing n strings (ub1 **)k, do it like this:
0133       for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
0134 
0135       By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.  You may use this
0136       code any way you wish, private, educational, or commercial.  It's free.
0137 
0138       See http://burtleburtle.net/bob/hash/evahash.html
0139       Use for hash table lookup, or anything where one collision in 2^^32 is
0140       acceptable.  Do NOT use for cryptographic purposes.
0141       --------------------------------------------------------------------
0142     */
0143     unsigned jenkins_hash ( unsigned char *k, unsigned length, unsigned initval )
0144     {
0145       unsigned a, b;
0146       unsigned c = initval;
0147       unsigned len = length;
0148 
0149       a = b = 0x9e3779b9;
0150 
0151       while ( len >= 12 ) {
0152         a += ( k[0] + ( (unsigned)k[1] << 8 )
0153                + ( (unsigned)k[2] << 16 )
0154                + ( (unsigned)k[3] << 24 ) );
0155         b += ( k[4] + ( (unsigned)k[5] << 8 )
0156                + ( (unsigned)k[6] << 16 )
0157                + ( (unsigned)k[7] << 24 ) );
0158         c += ( k[8] + ( (unsigned)k[9] << 8 )
0159                + ( (unsigned)k[10] << 16 )
0160                + ( (unsigned)k[11] << 24 ) );
0161 
0162         mix ( a, b, c );
0163 
0164         k += 12;
0165         len -= 12;
0166       }
0167 
0168       c += length;
0169 
0170       switch ( len ) {
0171       case 11: c += ( (unsigned)k[10] << 24 ); [[fallthrough]];
0172       case 10: c += ( (unsigned)k[9] << 16 ); [[fallthrough]];
0173       case 9 : c += ( (unsigned)k[8] << 8 ); [[fallthrough]];
0174         /* First byte of c reserved for length */
0175       case 8 : b += ( (unsigned)k[7] << 24 ); [[fallthrough]];
0176       case 7 : b += ( (unsigned)k[6] << 16 ); [[fallthrough]];
0177       case 6 : b += ( (unsigned)k[5] << 8 ); [[fallthrough]];
0178       case 5 : b += k[4]; [[fallthrough]];
0179       case 4 : a += ( (unsigned)k[3] << 24 ); [[fallthrough]];
0180       case 3 : a += ( (unsigned)k[2] << 16 ); [[fallthrough]];
0181       case 2 : a += ( (unsigned)k[1] << 8 ); [[fallthrough]];
0182       case 1 : a += k[0];
0183       }
0184 
0185       mix ( a, b, c );
0186 
0187       return c;
0188     }
0189 
0190     /// calculate hash from initialSeed, eventID and runID
0191     unsigned int hash( unsigned int initialSeed, unsigned int eventNumber, unsigned int runNumber ){
0192       unsigned int seed = 0;
0193       unsigned char * c = (unsigned char *) &eventNumber ;
0194       seed = jenkins_hash( c, sizeof eventNumber, seed) ;
0195 
0196       c = (unsigned char *) &runNumber ;
0197       seed = jenkins_hash( c, sizeof runNumber, seed) ;
0198 
0199       c = (unsigned char *) &initialSeed ;
0200       seed = jenkins_hash( c, sizeof initialSeed, seed) ;
0201 
0202       return seed;
0203     }
0204 
0205   }    // End namespace sim
0206 }      // End namespace dd4hep
0207 
0208 #endif // DDG4_PLUGINS_GEANT4EVENTSEED_H