DD4hep  1.35.0
Detector Description Toolkit for High Energy Physics
Geant4EventSeed.h
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 // Author : A.Sailer
11 //
12 //==========================================================================
13 #ifndef DDG4_PLUGINS_GEANT4EVENTSEED_H
14 #define DDG4_PLUGINS_GEANT4EVENTSEED_H
15 
16 // Framework include files
17 #include <DDG4/Geant4RunAction.h>
18 
19 
20 
22 namespace dd4hep {
23 
25  namespace sim {
26 
42  class Geant4EventSeed: public Geant4RunAction {
44 
45  protected:
46  unsigned int m_initialSeed;
47  unsigned int m_runID;
48  std::string m_type;
50  public:
52  Geant4EventSeed(Geant4Context*, const std::string& );
54  virtual ~Geant4EventSeed();
56  void begin(const G4Run*);
58  void beginEvent(const G4Event*);
59  };
60 
61  /*
62 
63  Hashing for random seed as used in Marlin EventSeeder processor
64 
65  Original source by Bob Jenkins
66 
67  http://www.burtleburtle.net/bob/hash/doobs.html
68 
69  Hash a variable-length key into a 32-bit value
70 
71  */
72 
73 #define hashsize(n) ( 1U << (n) )
74 #define hashmask(n) ( hashsize ( n ) - 1 )
75 
76 
77  /*
78  --------------------------------------------------------------------
79  mix -- mix 3 32-bit values reversibly.
80  For every delta with one or two bits set, and the deltas of all three
81  high bits or all three low bits, whether the original value of a,b,c
82  is almost all zero or is uniformly distributed,
83  * If mix() is run forward or backward, at least 32 bits in a,b,c
84  have at least 1/4 probability of changing.
85  * If mix() is run forward, every bit of c will change between 1/3 and
86  2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
87  mix() was built out of 36 single-cycle latency instructions in a
88  structure that could supported 2x parallelism, like so:
89  a -= b;
90  a -= c; x = (c>>13);
91  b -= c; a ^= x;
92  b -= a; x = (a<<8);
93  c -= a; b ^= x;
94  c -= b; x = (b>>13);
95  ...
96  Unfortunately, superscalar Pentiums and Sparcs can't take advantage
97  of that parallelism. They've also turned some of those single-cycle
98  latency instructions into multi-cycle latency instructions. Still,
99  this is the fastest good hash I could find. There were about 2^^68
100  to choose from. I only looked at a billion or so.
101  --------------------------------------------------------------------
102  */
103 #define mix(a,b,c) \
104  { \
105  a -= b; a -= c; a ^= (c>>13); \
106  b -= c; b -= a; b ^= (a<<8); \
107  c -= a; c -= b; c ^= (b>>13); \
108  a -= b; a -= c; a ^= (c>>12); \
109  b -= c; b -= a; b ^= (a<<16); \
110  c -= a; c -= b; c ^= (b>>5); \
111  a -= b; a -= c; a ^= (c>>3); \
112  b -= c; b -= a; b ^= (a<<10); \
113  c -= a; c -= b; c ^= (b>>15); \
114  }
115 
116  /*
117  --------------------------------------------------------------------
118  jenkins_hash() -- hash a variable-length key into a 32-bit value
119  k : the key (the unaligned variable-length array of bytes)
120  len : the length of the key, counting by bytes
121  initval : can be any 4-byte value
122  Returns a 32-bit value. Every bit of the key affects every bit of
123  the return value. Every 1-bit and 2-bit delta achieves avalanche.
124  About 6*len+35 instructions.
125 
126  The best hash table sizes are powers of 2. There is no need to do
127  mod a prime (mod is sooo slow!). If you need less than 32 bits,
128  use a bitmask. For example, if you need only 10 bits, do
129  h = (h & hashmask(10));
130  In which case, the hash table should have hashsize(10) elements.
131 
132  If you are hashing n strings (ub1 **)k, do it like this:
133  for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
134 
135  By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
136  code any way you wish, private, educational, or commercial. It's free.
137 
138  See http://burtleburtle.net/bob/hash/evahash.html
139  Use for hash table lookup, or anything where one collision in 2^^32 is
140  acceptable. Do NOT use for cryptographic purposes.
141  --------------------------------------------------------------------
142  */
143  unsigned jenkins_hash ( unsigned char *k, unsigned length, unsigned initval )
144  {
145  unsigned a, b;
146  unsigned c = initval;
147  unsigned len = length;
148 
149  a = b = 0x9e3779b9;
150 
151  while ( len >= 12 ) {
152  a += ( k[0] + ( (unsigned)k[1] << 8 )
153  + ( (unsigned)k[2] << 16 )
154  + ( (unsigned)k[3] << 24 ) );
155  b += ( k[4] + ( (unsigned)k[5] << 8 )
156  + ( (unsigned)k[6] << 16 )
157  + ( (unsigned)k[7] << 24 ) );
158  c += ( k[8] + ( (unsigned)k[9] << 8 )
159  + ( (unsigned)k[10] << 16 )
160  + ( (unsigned)k[11] << 24 ) );
161 
162  mix ( a, b, c );
163 
164  k += 12;
165  len -= 12;
166  }
167 
168  c += length;
169 
170  switch ( len ) {
171  case 11: c += ( (unsigned)k[10] << 24 ); [[fallthrough]];
172  case 10: c += ( (unsigned)k[9] << 16 ); [[fallthrough]];
173  case 9 : c += ( (unsigned)k[8] << 8 ); [[fallthrough]];
174  /* First byte of c reserved for length */
175  case 8 : b += ( (unsigned)k[7] << 24 ); [[fallthrough]];
176  case 7 : b += ( (unsigned)k[6] << 16 ); [[fallthrough]];
177  case 6 : b += ( (unsigned)k[5] << 8 ); [[fallthrough]];
178  case 5 : b += k[4]; [[fallthrough]];
179  case 4 : a += ( (unsigned)k[3] << 24 ); [[fallthrough]];
180  case 3 : a += ( (unsigned)k[2] << 16 ); [[fallthrough]];
181  case 2 : a += ( (unsigned)k[1] << 8 ); [[fallthrough]];
182  case 1 : a += k[0];
183  }
184 
185  mix ( a, b, c );
186 
187  return c;
188  }
189 
191  unsigned int hash( unsigned int initialSeed, unsigned int eventNumber, unsigned int runNumber ){
192  unsigned int seed = 0;
193  unsigned char * c = (unsigned char *) &eventNumber ;
194  seed = jenkins_hash( c, sizeof eventNumber, seed) ;
195 
196  c = (unsigned char *) &runNumber ;
197  seed = jenkins_hash( c, sizeof runNumber, seed) ;
198 
199  c = (unsigned char *) &initialSeed ;
200  seed = jenkins_hash( c, sizeof initialSeed, seed) ;
201 
202  return seed;
203  }
204 
205  } // End namespace sim
206 } // End namespace dd4hep
207 
208 #endif // DDG4_PLUGINS_GEANT4EVENTSEED_H
dd4hep::sim::Geant4EventSeed::begin
void begin(const G4Run *)
begin-of-run callback
Definition: Geant4EventSeed.cpp:51
Geant4RunAction.h
dd4hep::sim::Geant4EventSeed::~Geant4EventSeed
virtual ~Geant4EventSeed()
Default destructor.
Definition: Geant4EventSeed.cpp:46
dd4hep::sim::Geant4EventSeed::Geant4EventSeed
Geant4EventSeed(Geant4Context *, const std::string &)
Standard constructor with initializing arguments.
Definition: Geant4EventSeed.cpp:34
dd4hep::sim::Geant4EventSeed::m_initialSeed
unsigned int m_initialSeed
Definition: Geant4EventSeed.h:46
mix
#define mix(a, b, c)
Definition: Geant4EventSeed.h:103
dd4hep::sim::Geant4EventSeed::beginEvent
void beginEvent(const G4Event *)
begin-of-event callback
Definition: Geant4EventSeed.cpp:65
dd4hep::sim::Geant4EventSeed::m_runID
unsigned int m_runID
Definition: Geant4EventSeed.h:47
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::sim::hash
unsigned int hash(unsigned int initialSeed, unsigned int eventNumber, unsigned int runNumber)
calculate hash from initialSeed, eventID and runID
Definition: Geant4EventSeed.h:191
dd4hep::sim::Geant4EventSeed::m_type
std::string m_type
Definition: Geant4EventSeed.h:48
dd4hep::sim::jenkins_hash
unsigned jenkins_hash(unsigned char *k, unsigned length, unsigned initval)
Definition: Geant4EventSeed.h:143
dd4hep::sim::Geant4Context
Generic context to extend user, run and event information.
Definition: Geant4Context.h:201
dd4hep::sim::Geant4EventSeed::m_initialised
bool m_initialised
Definition: Geant4EventSeed.h:49