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