5#include "GaudiKernel/ISvcLocator.h"
6#include "GaudiKernel/IIncidentSvc.h"
7#include "GaudiKernel/Incident.h"
8#include "GaudiKernel/DataIncident.h"
9#include "GaudiKernel/ServiceHandle.h"
11#include "CLHEP/Random/Ranlux64Engine.h"
12#include "CLHEP/Random/RandGauss.h"
30 : base_class(name,svc),
49 while (i != e)
delete (i++)->second;
57 (
"Initializing " << name()
58 <<
"\n INITIALISING RANDOM NUMBER STREAMS. ");
67 static const int PRIORITY = 100;
68 pIncSvc->addListener(
this,
"EndEvent", PRIORITY);
69 pIncSvc->addListener(
this,
"AfterReseedIncident", PRIORITY);
74 pIncSvc->addListener(
this,
"BeginEvent", PRIORITY);
75 pIncSvc->addListener(
this,
"ReseedIncident", PRIORITY);
77 pIncSvc.release().ignore();
88 return StatusCode::FAILURE;
91 while (std::getline(infile, buffer)) {
93 std::vector<uint32_t> seeds;
97 <<
" INITIALISING " << stream <<
" stream with seeds ";
98 for (std::vector<uint32_t>::const_iterator i = seeds.begin(); i != seeds.end(); ++i){
106 msg() << ((*i) & 0xffffffffu) <<
" ";
111 << stream <<
" stream initialized succesfully" <<
endmsg;
114 << stream <<
" stream FAILED to initialize" <<
endmsg;
115 return StatusCode::FAILURE;
119 <<
"bad line\n" << buffer
121 return StatusCode::FAILURE;
131 uint32_t seed1, seed2, offset(0);
136 <<
" seeds " << seed1 <<
' ' << seed2
137 <<
", luxury level " << ll
138 <<
", reseeding offset " << offset);
141 return StatusCode::FAILURE;
145 bool not_found(
true);
148 while (sf !=
end() && (not_found=((*sf).first != stream))) ++sf;
153 (
" INITIALISING " << stream <<
" stream with seeds "
154 << seed1 <<
" " << seed2);
160 " to stream " << stream);
166 return StatusCode::SUCCESS;
173 if ( inc.type() ==
"EndEvent" ||
174 inc.type() ==
"AfterReseedIncident" )
180 CLHEP::HepRandomEngine* engine =
GetEngine(iE->first);
181 std::vector<unsigned long> v = engine->put();
182 std::vector<uint32_t> tseeds(v.size());
183 for (
size_t i=0; i<v.size(); ++i) {
191 tseeds[i] = (v[i] & 0xffffffffu);
198 }
else if (inc.type() ==
"BeginEvent") {
200 EventContext context = inc.context();
201 const EventIDBase& ei = context.eventID();
203 CLHEP::RandGauss::setFlag(
false);
212 throw GaudiException(
"can not reseed all streams ", name(), StatusCode::FAILURE);
215 const string& strName(*i++);
219 throw GaudiException(
string(
"can not reseed stream ") + strName,
220 name(), StatusCode::FAILURE);
222 msg() << MSG::VERBOSE <<
"Reseeded stream " << strName
223 <<
" for random service " <<
endmsg;
228 else if (inc.type() ==
"ReseedIncident") {
229 typedef ContextIncident<std::pair<unsigned,unsigned> > Ctxt;
230 const Ctxt* incident =
dynamic_cast<const Ctxt*
>(&inc);
232 throw GaudiException(
string(
"can not cast to ContextIncident "),
233 name(), StatusCode::FAILURE);
235 const std::pair<unsigned,unsigned>&
data = incident->tag();
237 CLHEP::RandGauss::setFlag(
false);
246 throw GaudiException(
"can not reseed all streams ", name(), StatusCode::FAILURE);
249 const string& strName(*i++);
253 throw GaudiException(
string(
"can not reseed stream ") + strName,
254 name(), StatusCode::FAILURE);
256 msg() << MSG::VERBOSE <<
"Reseeded stream " << strName
257 <<
" for random service " <<
endmsg;
275 for (std::map<std::string, std::vector<uint32_t> >::const_iterator i =
m_engines_copy.begin();
278 outfile << (*i).first <<
" ";
279 for (std::vector<uint32_t>::const_iterator j = (*i).second.begin(); j !=(*i).second.end(); ++j){
280 outfile << (*j) <<
" ";
288 return StatusCode::SUCCESS;
291CLHEP::HepRandomEngine*
302 return (CLHEP::HepRandomEngine*)(*iter).second;
307 const std::string& streamName) {
313 const std::string& streamName,
short luxLevel )
315 uint32_t seeds[2] = { seed1, seed2 };
316 const uint32_t* s = seeds;
320 new CLHEP::Ranlux64Engine(s[0], luxLevel)));
322 ((*iter).second)->setSeed(s[0], luxLevel);
327 const std::string& streamName)
332 new CLHEP::Ranlux64Engine() ) );
334 std::vector<unsigned long> longSeeds(seeds.size());
335 for (
size_t i=0; i<seeds.size(); ++i) longSeeds[i]=seeds[i];
336 return (((*iter).second)->getState( longSeeds ));
344 if (StreamName ==
"PYTHIA")
349 else if (StreamName ==
"HERWIG")
360 (
" INITIALISING " << StreamName <<
" stream with DEFAULT seeds "
361 << seed1 <<
" " << seed2);
363 uint32_t seeds[2] = { seed1, seed2 };
364 const uint32_t* s = seeds;
366 ((*iter).second)->setSeed(s[0]);
376 std::vector<unsigned long> v = ((*citer).second)->put();
377 msg(MSG::INFO) <<
" Stream = " << StreamName <<
" ";
378 for (std::vector<unsigned long>::const_iterator i = v.begin(); i != v.end(); ++i){
386 msg() << ((*i) & 0xffffffffu) <<
" ";
399CLHEP::HepRandomEngine*
401 const std::string& streamName)
406 uint32_t theHash(eventNumber);
409 if (hasOffset) theHash=
crc_combine(theHash, citer->second);
413 <<
" with eventNumber " << eventNumber
414 <<
" runNumber " << runNumber);
419CLHEP::HepRandomEngine*
421 const std::string& streamName){
429 new CLHEP::Ranlux64Engine() ) );
433 ATH_MSG_DEBUG(
"Reseeding stream " << streamName <<
" with " << theSeed);
434 CLHEP::Ranlux64Engine* eng = (*iter).second;
438 eng->setSeed( (int32_t)theSeed, eng->getLuxury() );
443CLHEP::HepRandomEngine*
445 const std::string& streamName)
452 long seeds[2] = { (long)(1000*runNumber + hashedStream),
454 assert( seeds[0] > 0 );
455 assert( seeds[1] > 0 );
456 const long* s = seeds;
458 return (CLHEP::HepRandomEngine*)(*iter).second;
461CLHEP::HepRandomEngine*
463 const std::string& streamName){
469 long seeds[2] = { (long)(hashedStream % (theSeed+13)),
471 assert( seeds[0] > 0 );
472 assert( seeds[1] > 0 );
473 const long* s = seeds;
475 return (CLHEP::HepRandomEngine*)(*iter).second;
The default ATLAS random number engine manager, based on Ranlux64.
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
uint32_t crc_combine(uint32_t seed, uint32_t v)
using crc32 for architecture independence in combining the seeds
char data[hepevt_bytes_allocation_ATLAS]
uint32_t m_PYTHIA_default_seed2
uint32_t m_HERWIG_default_seed1
virtual void CreateStream(uint32_t seed1, uint32_t seed2, const std::string &streamName) override
void SetStreamSeeds(const std::string &streamName)
AtRanluxGenSvc(const std::string &name, ISvcLocator *svc)
Standard Gaudi Constructor.
unsigned int number_of_streams(void) const
engineConstIter end(void) const
std::map< std::string, uint32_t > m_reseedingOffsets
optional offsets to combine to run/evt no when reseeding.
short m_defaultLuxLevel
Ranlux luxury level to be used by default.
virtual ~AtRanluxGenSvc()
Standard Destructor.
Gaudi::Property< std::string > m_file_to_read
name of the file to read the engine status from
virtual bool setAllOnDefinedSeeds(uint32_t theSeed) override
seed all streams we manage, combining theSeed and the stream names
virtual StatusCode initialize() override
StringArrayProperty m_reseedStreamNames
streams to be reseeded for every event
void createStream(uint32_t seed1, uint32_t seed2, const std::string &streamName, short luxLevel)
allows to specify luxLevel
std::map< std::string, std::vector< uint32_t > > m_engines_copy
Random engine copy (for output to a file)
engineConstIter begin(void) const
engineMap::iterator engineIter
CLHEP::HepRandomEngine * oldSetOnDefinedSeeds(uint32_t theSeed, const std::string &streamName)
broken, temporarily keep for backward compatibility
virtual StatusCode finalize() override
StringArrayProperty m_streams_seeds
seeds for the engines, this is a vector of strings of the form "EnginName Seed1 Seed2"
virtual CLHEP::HepRandomEngine * setOnDefinedSeeds(uint32_t theSeed, const std::string &streamName) override
Gaudi::Property< bool > m_eventReseed
reseed for every event
Gaudi::Property< std::string > m_file_to_write
name of the file to save the engine status to.
engineMap::const_iterator engineConstIter
uint32_t m_HERWIG_default_seed2
virtual CLHEP::HepRandomEngine * GetEngine(const std::string &streamName) override
engineMap::value_type engineValType
Gaudi::Property< bool > m_read_from_file
read engine status from file
virtual void print(void) override
Gaudi::Property< bool > m_save_to_file
should current engine status be saved to file ?
uint32_t m_PYTHIA_default_seed1
Gaudi::Property< bool > m_useOldBrokenSeeding
backward compatibility only, broken 32/64 bits
virtual void handle(const Incident &) override
IIncidentListener implementation. Handles EndEvent incident.
bool interpretSeeds(const std::string &buffer, std::string &stream, uint32_t &seed1, uint32_t &seed2, short &luxury, uint32_t &offset)
int simpleStringHash(const std::string &str, int maxInt=0xFFFF)
simple hash function derived from Sedgewick Algorithms in C++ 3rd ed