Marlin  01.17.01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ProcessorEventSeeder.cc
Go to the documentation of this file.
2 #include "marlin/Processor.h"
3 #include "marlin/Global.h"
4 
5 #include "jenkinsHash.h"
6 
7 #include <stdlib.h>
8 #include <limits>
9 #include <algorithm>
10 
11 namespace marlin{
12 
13 
14  ProcessorEventSeeder::ProcessorEventSeeder() : _global_seed(0), _global_seed_set(false), _eventProcessingStarted(false), _vector_pair_proc_seed()
15  {
16  }
17 
18 
20 
21 
22  if( _global_seed_set == false ) {
23  _global_seed = Global::parameters->getIntVal("RandomSeed" ) ;
24  _global_seed_set = true;
25  }
26 
27  if ( _eventProcessingStarted ) { // event processing started, so disallow any more calls to registerProcessor
28  streamlog_out(ERROR) << "ProcessorEventSeeder:registerProcessor( Processor* proc ) called from Processor: "
29  << proc->name() << std::endl << "The method registerProcessor( Processor* proc ) must be called in the init() method of the Processor"
30  << std::endl;
31 
32  throw Exception("ProcessorEventSeeder: Event Processing has already started. registerProcessor( Processor* proc ) must be called in the init() method");
33  }
34 
35  // just in case any body has called rand since we set the seed
36  srand( _global_seed );
37  streamlog_out(DEBUG) << "ProcessorEventSeeder: srand initialised with global seed " << _global_seed << std::endl;
38 
39  _vector_pair_proc_seed.push_back( std::make_pair( proc, rand() ) );
40  streamlog_out(DEBUG) << "ProcessorEventSeeder: Processor " << proc->name()
41  << " registered for random seed service. Allocated "
42  << _vector_pair_proc_seed.back().second << " as initial seed." << std::endl;
43 
44  }
45 
46  void ProcessorEventSeeder::refreshSeeds( LCEvent * evt ) {
47 
48  _eventProcessingStarted = true; // event processing started so disallow any more calls to registerProcessor
49 
50  // get hashed seed using jenkins_hash
51  unsigned int seed = 0 ; // initial state
52  unsigned int eventNumber = evt->getEventNumber() ;
53  unsigned int runNumber = evt->getRunNumber() ;
54 
55  unsigned char * c = (unsigned char *) &eventNumber ;
56  seed = jenkins_hash( c, sizeof eventNumber, seed) ;
57 
58  c = (unsigned char *) &runNumber ;
59  seed = jenkins_hash( c, sizeof runNumber, seed) ;
60 
61  c = (unsigned char *) &_global_seed ;
62  seed = jenkins_hash( c, sizeof _global_seed, seed) ;
63 
64  // set the seed for rand() for this event
65  if ( seed == 1 ) seed = 123456789 ; // can't used a seed value of 1 as srand(1) sets rand() back the state of the last call to srand( seed ).
66 
67  streamlog_out(DEBUG) << "ProcessorEventSeeder: Refresh Seeds using " << seed << " as seed for srand( seed )" << std::endl;
68  srand( seed );
69 
70  // fill map with seeds for each registered processor using rand()
71  for (auto& pairProcSeed : _vector_pair_proc_seed ) {
72  pairProcSeed.second = rand();
73  }
74 
75  }
76 
77  unsigned int ProcessorEventSeeder::getSeed( Processor* proc ) {
78 
80 
81  auto it = find_if( _vector_pair_proc_seed.begin(), _vector_pair_proc_seed.end(), [&](Pair const& pair){ return pair.first == proc; } );
82 
83  return ( it != _vector_pair_proc_seed.end() ? it->second : throw ) ;
84 
85  }
86 
87 } // namespace marlin
std::vector< std::pair< Processor *, unsigned int > > _vector_pair_proc_seed
vector to hold pair of pointers to the registered processors and their assigned seeds ...
virtual const std::string & name() const
Return name of this processor.
Definition: Processor.h:132
T endl(T...args)
int _global_seed
Global seed for current Job.
unsigned jenkins_hash(unsigned char *k, unsigned length, unsigned initval)
Definition: jenkinsHash.h:84
bool _global_seed_set
Global seed has been set for current Job.
void refreshSeeds(LCEvent *evt)
Create new set of seeds for registered Processors for the given event.
static StringParameters * parameters
Definition: Global.h:27
unsigned int getSeed(Processor *proc)
Called by Processors to obtain seed assigned to it for the current event.
int getIntVal(const std::string &key)
T make_pair(T...args)
bool _eventProcessingStarted
bool to ensure no calls of registerProcessor( Processor* proc ) after Event Processesing has started ...
void registerProcessor(Processor *proc)
Called by Processors to register themselves for the seeding service.
Base class for Marlin processors.
Definition: Processor.h:64