00001
00002
00003
00004
00005
00006
00007 #include "DybShuffle.h"
00008 #include "GaudiKernel/IRndmEngine.h"
00009
00010 #include "TRandom.h"
00011
00012 #include <boost/functional/hash.hpp>
00013
00014 #include <bitset>
00015
00017
00018 DybShuffle::DybShuffle(const std::string& name, ISvcLocator* pSvcLocator)
00019 : DybAlgorithm<DayaBay::RandomHeader>(name, pSvcLocator)
00020 , m_hostid(0)
00021 , m_run(1)
00022 , m_countOffset(0)
00023 , m_burnCount(100)
00024 , m_dohash(true)
00025 {
00026
00027 declareProperty("HostID", m_hostid, "The systems Host 'ID'entification number");
00028 declareProperty("Run",m_run,"The run number");
00029 declareProperty("ExecCountOffset",m_countOffset,"Number to add to the execution count");
00030 declareProperty("BurnCount",m_burnCount,"Number of random numbers to burn with a new seed");
00031 declareProperty("SeedVec", m_seedvec, "Random seed vector manually");
00032 declareProperty("Hash", m_dohash, "Hash the seed");
00033 }
00034
00035
00036
00037 StatusCode DybShuffle::initialize(){
00038
00039
00040 verbose() << " DybShuffle initialize()" << endreq;
00041
00042
00043 m_rndSvc = randSvc();
00044 m_engine = m_rndSvc->engine();
00045
00046 IProperty* prop=0;
00047 StatusCode sc = m_rndSvc->queryInterface(IProperty::interfaceID(),(void**)&prop);
00048 if (sc.isFailure()) return sc;
00049
00050 m_engineName = prop->getProperty("Engine").toString();
00051
00052 if (m_uni.initialize(m_rndSvc, Rndm::Flat(0,1)).isFailure()) {
00053 fatal() << "Failed to initialize uniform random numbers" << endreq;
00054 return StatusCode::FAILURE;
00055 }
00056
00057 this->seed();
00058
00059 return StatusCode::SUCCESS;
00060 }
00061
00062
00063
00064 StatusCode DybShuffle::execute() {
00065
00066 verbose() << "DybShuffle execute()" << endreq;
00067
00068
00069 DayaBay::RandomHeader* RndmHead = MakeHeaderObject();
00070
00071
00072
00073 RndmHead->setEarliest(TimeStamp::GetBOT());
00074 RndmHead->setLatest(TimeStamp::GetBOT());
00075
00076
00077 RndmHead->setHEPEngine(m_engineName);
00078
00079
00080 if (this->getExecNum() > 1) {
00081 std::vector<long> NewSeeds = this->seed();
00082 RndmHead->setRndmSeeds(NewSeeds);
00083 }
00084
00085 return StatusCode::SUCCESS;
00086 }
00087
00088 std::vector<long> DybShuffle::seed()
00089 {
00090
00091 std::vector<long> NewSeeds;
00092 std::vector<long> CurrSeeds;
00093
00094 if(m_seedvec.size())
00095 {
00096 NewSeeds=m_seedvec;
00097 }
00098
00099 else
00100 {
00101
00102
00103 if (m_hostid == 0)
00104 {
00105 m_hostid = (long) gethostid();
00106 }
00107
00108 std::bitset<32> a ((long) 0);
00109 std::bitset<32> site ((long) 0);
00110 std::bitset<32> run ((long) 0);
00111 std::bitset<32> evt ((long) 0);
00112 std::bitset<32> seed ((long) 0);
00113
00114 site = (long)m_hostid;
00115 run = m_run;
00116
00117
00118
00119
00120 evt = m_countOffset + this->getExecNum();
00121
00122 for ( int i = 32-1-1; i >= 0 ; i-- )
00123 {
00124 if ( run.test(i) ) a.set(31-1-i) ;
00125 }
00126
00127 seed = (a|evt)^site;
00128
00129 if ( seed.test(31) ) seed.reset(31);
00130 int MySeed = seed.to_ulong();
00131
00132 if (m_dohash) {
00133 boost::hash<int> hasher;
00134 MySeed = hasher(MySeed);
00135 }
00136
00137 NewSeeds.push_back(MySeed);
00138
00139 debug () << "Run " << m_run
00140 << ", exec# = " << evt.to_ulong()
00141 << ", host = " << (void*)site.to_ulong()
00142 << ", seeds:";
00143 std::vector<long>::iterator it, done = NewSeeds.end();
00144 for (it=NewSeeds.begin(); it != done; ++it) {
00145 debug () << " " << *it;
00146 }
00147 debug () << endreq;
00148
00149 }
00150
00151
00152 m_engine->setSeeds(NewSeeds);
00153 m_engine->seeds(CurrSeeds);
00154 gRandom->SetSeed(NewSeeds[0]);
00155
00156
00157 int irndm;
00158 double b;
00159 for(irndm=0;irndm<m_burnCount;irndm++)
00160 {
00161 b=m_uni();
00162 }
00163
00164 return NewSeeds;
00165 }
00166
00167
00168
00169 StatusCode DybShuffle::finalize() {
00170
00171
00172 verbose() << "DybShuffle finalize()" << endreq;
00173
00174 return StatusCode::SUCCESS;
00175 }
00176
00177
00178
00179
00180