CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/IOMC/RandomEngine/python/RandomServiceHelper.py

Go to the documentation of this file.
00001 #!/usr/bin/env python2.4
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.4 2008/06/10 19:49:49 ewv Exp $"
00017     Version   "$Revision: 1.4 $"
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 == 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         #print svcAttrs
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             # // PSet has list of seeds
00079             #//
00080             seedSet = getattr(itemRef, "initialSeedSet", None)
00081             if seedSet != None:
00082                 count += len( seedSet.value())
00083                 continue
00084             #  //
00085             # // PSet has single seed
00086             #//
00087             seedVal =  getattr(itemRef, "initialSeed", None)
00088             if seedVal != None:
00089                 count += 1
00090 
00091             #  //
00092             # // PSet has no recognisable seed, therfore do nothing
00093             #//  with it
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             # // Do we want to check the number of seeds??
00128             #//
00129             #if len(seeds) != len( seedSet.value()): pass
00130             pset.initialSeedSet = CfgTypes.untracked(
00131                 CfgTypes.vuint32(*seeds))
00132             return
00133         #  //
00134         # // No seeds for that PSet
00135         #//  Error throw?
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         # // count seeds and create the required number of seeds
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     # // Setup a test service and populate it
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     # // Autofill seeds
00280     #//
00281     print "Totally Random PSet"
00282     randHelper.populate()
00283     print randSvc
00284 
00285 
00286     #  //
00287     # // Set all seeds with reset method
00288     #//
00289     print "All seeds 9999"
00290     randHelper.resetSeeds(9999)
00291     print randSvc
00292 
00293     #  //
00294     # // test setting named seeds
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     # // Autofill seeds with exclusion list
00307     #//
00308     randHelper.populate("t1", "t3")
00309     print "t2 randomized"
00310     print randSvc