00001
00002
00003 from DybPython.DybPythonAlg import DybPythonAlg, SUCCESS, FAILURE
00004 from DybPython.Control import nuwa
00005 from GaudiPython import gbl
00006 from ROOT import gRandom, TFile, TH1F, TH2F, TGraph
00007 import os
00008
00009 class DumpRandom(DybPythonAlg):
00010 '''
00011
00012 Dump random numbers to file
00013
00014 '''
00015
00016 def __init__(self, name = 'DumpRandom', filename = 'random.dump'):
00017 '''
00018
00019 Make a DumpRandom alg
00020
00021 Arguments:
00022 - "name":object name
00023 - "filename":name of file in to which random numbers will be written
00024 '''
00025 DybPythonAlg.__init__(self,name)
00026 self.fp = open(filename,'w')
00027 self.tfile = TFile(filename+'.root',"RECREATE")
00028 self.executions = 0
00029
00030 self.clhep_random = None
00031 self.rndm_svc = None
00032 self.rndm_engine = None
00033
00034 self.maximum = 100.0
00035 self.epsilon = 1.0/(int(nuwa.opts.executions)*self.maximum)
00036
00037 class Chaos(): pass
00038
00039 root = Chaos()
00040 root.last_seed = None
00041 root.lucky = 0
00042 root.tries = 0
00043 root.last_tries = []
00044 root.seed = self.root_seed
00045 root.number = self.root_number
00046 root.name = 'ROOT'
00047 root.hist = TH1F("rootran","ROOT randoms",1000,0,self.maximum)
00048 root.hused = TH2F("rootused","ROOT randoms",100,0,100,100,0,self.maximum)
00049 root.graf = TGraph()
00050 root.graf.SetName("rootrangraf")
00051 root.nused = 0
00052 self.root = root
00053
00054 clhep = Chaos()
00055 clhep.last_seed = None
00056 clhep.lucky = 0
00057 clhep.tries = 0
00058 clhep.last_tries = []
00059 clhep.seed = self.clhep_seed
00060 clhep.number = self.clhep_number
00061 clhep.name = 'CLHEP'
00062 clhep.hist = TH1F("clhepran","CLHEP randoms",1000,0,self.maximum)
00063 clhep.hused = TH2F("clhepused","CLHEP randoms",100,0,100,100,0,self.maximum)
00064 clhep.graf = TGraph()
00065 clhep.graf.SetName("clheprangraf")
00066 clhep.nused = 0
00067 self.clhep = clhep
00068
00069 return
00070
00071 def clhep_seed(self):
00072 'Return the current CLHEP seed'
00073 seeds = gbl.std.vector('long')();
00074 self.rndm_engine.seeds(seeds)
00075 return seeds[0]
00076
00077 def root_seed(self):
00078 'Return the current ROOT seed'
00079 return gRandom.GetSeed()
00080
00081 def clhep_number(self):
00082 'Return the next CLHEP random in [0,maximum)'
00083 if self.clhep_random is None:
00084 flat = gbl.Rndm.Flat(0,self.maximum)
00085 self.clhep_random = gbl.Rndm.Numbers(self.rndm_svc,flat)
00086 self.clhep.nused += 1
00087 num = self.clhep_random()
00088 self.clhep.hist.Fill(num)
00089 self.clhep.hused.Fill(self.clhep.nused,num)
00090 self.clhep.graf.SetPoint(self.executions,self.executions,num)
00091 return num
00092
00093 def root_number(self):
00094 'Return the next ROOT random in [0,maximum)'
00095 self.root.nused += 1
00096 num = gRandom.Uniform(0,self.maximum)
00097 self.root.hist.Fill(num)
00098 self.root.hused.Fill(self.root.nused,num)
00099 self.root.graf.SetPoint(self.executions,self.executions,num)
00100 return num
00101
00102
00103 def check_tries(self,who,tries):
00104 assert who.last_tries != tries, '%s is really boring using the same guesses: %s' % (who.name, str(tries))
00105
00106 if len(who.last_tries) != len(tries):
00107
00108 who.last_tries = tries
00109 return
00110
00111 for t1,t2 in zip(who.last_tries,tries):
00112
00113 assert abs(t1-t2) > self.epsilon, '%s does no pick fresh enough values (%f vs. %f)' % (who.name,t1,t2)
00114
00115 who.last_tries = tries
00116 return
00117
00118 def global_thermo_nuclear_war(self,who):
00119 'Exercise the random number stream'
00120 answer = who.number()
00121 nguesses = 50
00122 self.fp.write(who.name+": Seed = %d\n"%who.seed())
00123 self.fp.write(who.name+": Let's play guess my number\n")
00124 tries = []
00125 for n in range(nguesses):
00126 guess = who.number()
00127
00128 assert answer != guess, "No one is that lucky to get %f == %f !" % (answer,guess)
00129
00130 who.tries += 1
00131 tries.append(guess)
00132 if int(guess) == int(answer):
00133 self.fp.write(who.name+": Guess #%d: %f is close enough to %f, you win\n" % (n+1, guess,answer))
00134 if n == 0:
00135 who.lucky += 1
00136 print '%s got lucky %d times' % (who.name,who.lucky)
00137 return
00138 self.fp.write(who.name+": Guess #%d: %f is wrong\n" % (n+1,guess) )
00139 continue
00140 self.check_tries(who,tries)
00141 self.fp.write(who.name+": You failed! The right answer was %f\n" % answer)
00142 return
00143
00144 def play_game(self):
00145 self.global_thermo_nuclear_war(self.root)
00146 self.global_thermo_nuclear_war(self.clhep)
00147
00148 def initialize(self):
00149 sc = DybPythonAlg.initialize(self)
00150 if sc.isFailure(): return sc
00151
00152
00153 self.rndm_svc = self.svc('IRndmGenSvc','RndmGenSvc')
00154 self.rndm_engine = self.rndm_svc.engine()
00155 assert self.rndm_engine, 'Good not get random engine from random svc'
00156
00157 self.play_game()
00158
00159 return SUCCESS
00160
00161 def check_seed(self, who):
00162 'Do some checks on new seed against last seed, return new seed'
00163 if who.last_seed is None:
00164 who.last_seed = who.seed()
00165 return
00166 assert who.last_seed != who.seed(), 'Seed has not changed between executions!: %d'%who.seed()
00167
00168 def check_seeds(self):
00169
00170
00171 rs = self.root.seed()
00172 cs = self.clhep.seed()
00173 assert rs == cs, 'ROOT seed %d != CLHEP seed %d' % (rs,cs)
00174
00175
00176 self.check_seed(self.root)
00177 self.check_seed(self.clhep)
00178
00179 return
00180
00181 def execute(self):
00182 self.root.nused = 0
00183 self.clhep.nused = 0
00184 self.root.numbers = []
00185 self.clhep.numbers = []
00186 self.executions += 1
00187 try:
00188 self.check_seeds()
00189 self.play_game()
00190 except AssertionError,err:
00191 print err
00192 return FAILURE
00193
00194 return SUCCESS
00195
00196 def check_luck(self,who):
00197 msg = '%s is lucky %d out of %d = %.2f percent' % (who.name, who.lucky, who.tries,
00198 (100.0*who.lucky)/(1.0*who.tries))
00199 print msg
00200 assert who.lucky != who.tries, 'no one, not even %s'%msg
00201
00202 def finalize(self):
00203 import math
00204
00205 self.fp.close()
00206
00207 self.root.hist.Write()
00208 self.root.hused.Write()
00209 self.root.graf.Write()
00210 self.clhep.hist.Write()
00211 self.clhep.hused.Write()
00212 self.clhep.graf.Write()
00213 self.tfile.Close()
00214
00215 try:
00216 self.check_luck(self.root)
00217 self.check_luck(self.clhep)
00218 except AssertionError,err:
00219 print err
00220 return FAILURE
00221 return DybPythonAlg.finalize(self)
00222
00223 pass
00224
00225 filenames = []
00226
00227 def configure(argv=None):
00228 global filenames
00229
00230
00231 if not argv:
00232 if not filenames:
00233 filenames.append("test_shuffle.txt")
00234 return
00235 filenames.append(argv[0])
00236
00237 from DybAlg.DybAlgConf import DybShuffle
00238 rs = DybShuffle("random_seeder")
00239 try:
00240 burn = argv[1]
00241 except IndexError:
00242 print 'Using default burn count',rs.BurnCount
00243 else:
00244 rs.BurnCount = int(burn)
00245 print 'Setting burn to',rs.BurnCount
00246
00247
00248 return
00249
00250 def run(app):
00251 global filenames
00252 for fn in filenames:
00253 name = os.path.splitext(os.path.basename(fn))[0]
00254 alg = DumpRandom(name,fn)
00255 app.addAlgorithm(alg)
00256 print 'Added algorithm: DumpRandom("%s","%s")' % (name, fn)
00257 continue
00258 return
00259
00260