00001
00002
00003
00004 from FWCore.ParameterSet.Config import Service
00005 import FWCore.ParameterSet.Types as CfgTypes
00006
00007
00008 class RandomNumberServiceHelper(object):
00009 """
00010 _RandomNumberServiceHelper_
00011
00012 Helper class to hold and handle the Random number generator service.
00013
00014 Provide both user level and WM APIs.
00015
00016 Revision: "$Id: RandomServiceHelper.py,v 1.6 2012/10/30 11:18:57 fabiocos Exp $"
00017 Version "$Revision: 1.6 $"
00018 Author: Dave Evans
00019 Modified: Eric Vaandering
00020 """
00021
00022 def __init__(self,randService):
00023 self._randService = randService
00024 self._lockedSeeds = []
00025
00026
00027 def __containsSeed(self,psetInstance):
00028 """
00029 _keeper_
00030
00031 True/False if the psetInstance has seeds in it
00032
00033 """
00034 if psetInstance is None:
00035 return False
00036 if not isinstance(psetInstance,CfgTypes.PSet):
00037 return False
00038 seedList = getattr(psetInstance, "initialSeedSet", None)
00039 if seedList != None:
00040 return True
00041 seedVal = getattr(psetInstance, "initialSeed", None)
00042 if seedVal != None:
00043 return True
00044 return False
00045
00046
00047 def __psetsWithSeeds(self):
00048 """
00049 _psetsWithSeeds_
00050
00051 *private method*
00052
00053 return the list of PSet instances with seeds in them
00054
00055 """
00056 svcAttrs = [getattr(self._randService, item, None)
00057 for item in self._randService.parameters_()
00058 if item not in self._lockedSeeds]
00059
00060
00061
00062 return filter(self.__containsSeed, svcAttrs)
00063
00064
00065 def countSeeds(self):
00066 """
00067 _countSeeds_
00068
00069 Count the number of seeds required by this service by
00070 summing up the initialSeed and initialSeedSet entries
00071 in all PSets in the service that contain those parameters.
00072
00073 """
00074 count = 0
00075
00076 for itemRef in self.__psetsWithSeeds():
00077
00078
00079
00080 seedSet = getattr(itemRef, "initialSeedSet", None)
00081 if seedSet != None:
00082 count += len( seedSet.value())
00083 continue
00084
00085
00086
00087 seedVal = getattr(itemRef, "initialSeed", None)
00088 if seedVal != None:
00089 count += 1
00090
00091
00092
00093
00094 return count
00095
00096
00097 def setNamedSeed(self, psetName, *seeds):
00098 """
00099 _setNamedSeed_
00100
00101 If a specific set of seeds is needed for a PSet in this
00102 service, they can be set by name using this method.
00103
00104 - *psetName* : Name of the pset containing the seeds
00105
00106 - *seeds* : list of seeds to be added, should be a single seed
00107 for initialSeed values.
00108
00109 """
00110 pset = getattr(self._randService, psetName, None)
00111 if pset == None:
00112 msg = "No PSet named %s belongs to this instance of the" % (
00113 psetName,)
00114 msg += "Random Seed Service"
00115 raise RuntimeError, msg
00116
00117 seedVal = getattr(pset, "initialSeed", None)
00118 if seedVal != None:
00119 pset.initialSeed = CfgTypes.untracked(
00120 CfgTypes.uint32(seeds[0])
00121 )
00122
00123 return
00124 seedSet = getattr(pset, "initialSeedSet", None)
00125 if seedSet != None:
00126
00127
00128
00129
00130 pset.initialSeedSet = CfgTypes.untracked(
00131 CfgTypes.vuint32(*seeds))
00132 return
00133
00134
00135
00136 return
00137
00138
00139 def getNamedSeed(self, psetName):
00140 """
00141 _getNamedSeed_
00142
00143 This method returns the seeds in a PSet in this service. Returned
00144
00145 - *psetName* : Name of the pset containing the seeds
00146
00147 """
00148 pset = getattr(self._randService, psetName, None)
00149 if pset == None:
00150 msg = "No PSet named %s belongs to this instance of the" % (
00151 psetName,)
00152 msg += "Random Seed Service"
00153 raise RuntimeError, msg
00154
00155 seedVal = getattr(pset, "initialSeed", None)
00156 if seedVal != None:
00157 return [pset.initialSeed.value()]
00158
00159 seedSet = getattr(pset, "initialSeedSet", None)
00160 if seedSet != None:
00161 return pset.initialSeedSet
00162
00163
00164 def insertSeeds(self, *seeds):
00165 """
00166 _insertSeeds_
00167
00168 Given some list of specific seeds, insert them into the
00169 service.
00170
00171 Length of seed list is required to be same as the seed count for
00172 the service.
00173
00174 Usage: WM Tools.
00175
00176 """
00177 seeds = list(seeds)
00178 if len(seeds) < self.countSeeds():
00179 msg = "Not enough seeds provided\n"
00180 msg += "Service requires %s seeds, only %s provided\n"
00181 msg += "to RandomeService.insertSeeds method\n"
00182 raise RuntimeError, msg
00183
00184 for item in self.__psetsWithSeeds():
00185 seedSet = getattr(item, "initialSeedSet", None)
00186 if seedSet != None:
00187 numSeeds = len(seedSet.value())
00188 useSeeds = seeds[:numSeeds]
00189 seeds = seeds[numSeeds:]
00190 item.initialSeedSet = CfgTypes.untracked(
00191 CfgTypes.vuint32(*useSeeds))
00192 continue
00193 useSeed = seeds[0]
00194 seeds = seeds[1:]
00195 item.initialSeed = CfgTypes.untracked(
00196 CfgTypes.uint32(useSeed)
00197 )
00198 continue
00199 return
00200
00201
00202 def populate(self, *excludePSets):
00203 """
00204 _populate_
00205
00206 generate a bunch of seeds and stick them into this service
00207 This is the lazy user method.
00208
00209 Optional args are names of PSets to *NOT* alter seeds.
00210
00211 Eg:
00212 populate() will set all seeds
00213 populate("pset1", "pset2") will set all seeds but not those in
00214 psets named pset1 and pset2
00215
00216 """
00217
00218 import random
00219 from random import SystemRandom
00220 _inst = SystemRandom()
00221 _MAXINT = 900000000
00222
00223
00224
00225
00226 newSeeds = [ _inst.randint(1, _MAXINT)
00227 for i in range(self.countSeeds())]
00228
00229
00230 self._lockedSeeds = list(excludePSets)
00231 self.insertSeeds(*newSeeds)
00232 self._lockedSeeds = []
00233 return
00234
00235
00236 def resetSeeds(self, value):
00237 """
00238 _resetSeeds_
00239
00240 reset all seeds to given value
00241
00242 """
00243 newSeeds = [ value for i in range(self.countSeeds())]
00244 self.insertSeeds(*newSeeds)
00245 return
00246
00247
00248
00249 if __name__ == '__main__':
00250
00251
00252
00253 randSvc = Service("RandomNumberGeneratorService")
00254 randHelper = RandomNumberServiceHelper(randSvc)
00255
00256 randSvc.i1 = CfgTypes.untracked(CfgTypes.uint32(1))
00257 randSvc.t1 = CfgTypes.PSet()
00258 randSvc.t2 = CfgTypes.PSet()
00259 randSvc.t3 = CfgTypes.PSet()
00260
00261 randSvc.t1.initialSeed = CfgTypes.untracked(
00262 CfgTypes.uint32(123455678)
00263 )
00264
00265 randSvc.t2.initialSeedSet = CfgTypes.untracked(
00266 CfgTypes.vuint32(12345,234567,345677)
00267 )
00268
00269
00270 randSvc.t3.initialSeed = CfgTypes.untracked(
00271 CfgTypes.uint32(987654321)
00272 )
00273
00274 print "Inital PSet"
00275 print randSvc
00276
00277
00278
00279
00280
00281 print "Totally Random PSet"
00282 randHelper.populate()
00283 print randSvc
00284
00285
00286
00287
00288
00289 print "All seeds 9999"
00290 randHelper.resetSeeds(9999)
00291 print randSvc
00292
00293
00294
00295
00296 print "t1,t3 9998"
00297 randHelper.setNamedSeed("t1", 9998)
00298 randHelper.setNamedSeed("t3", 9998, 9998)
00299 print randSvc
00300
00301 print "t1 seed(s)",randHelper.getNamedSeed("t1")
00302 print "t2 seed(s)",randHelper.getNamedSeed("t2")
00303
00304
00305
00306
00307
00308 randHelper.populate("t1", "t3")
00309 print "t2 randomized"
00310 print randSvc