Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-01 23:40:27

0001 #!/usr/bin/env python
0002 
0003 
0004 from FWCore.ParameterSet.Config import Service
0005 import FWCore.ParameterSet.Types as CfgTypes
0006 
0007 
0008 class RandomNumberServiceHelper(object):
0009     """
0010     _RandomNumberServiceHelper_
0011 
0012     Helper class to hold and handle the Random number generator service.
0013 
0014     Provide both user level and WM APIs.
0015 
0016     Author:   Dave Evans
0017     Modified: Eric Vaandering
0018     """
0019 
0020     def __init__(self,randService):
0021         self._randService = randService
0022         self._lockedSeeds = []
0023 
0024 
0025     def __containsSeed(self,psetInstance):
0026         """
0027         _keeper_
0028 
0029         True/False if the psetInstance has seeds in it
0030 
0031         """
0032         if psetInstance is None:
0033             return False
0034         if not isinstance(psetInstance,CfgTypes.PSet):
0035             return False
0036         seedList = getattr(psetInstance, "initialSeedSet", None)
0037         if seedList != None:
0038             return True
0039         seedVal = getattr(psetInstance, "initialSeed", None)
0040         if seedVal != None:
0041             return True
0042         return False
0043 
0044 
0045     def __psetsWithSeeds(self):
0046         """
0047         _psetsWithSeeds_
0048 
0049         *private method*
0050 
0051         return the list of PSet instances with seeds in them
0052 
0053         """
0054         svcAttrs = [getattr(self._randService, item, None)
0055                     for item in self._randService.parameters_()
0056                     if item not in self._lockedSeeds]
0057 
0058         #print svcAttrs
0059 
0060         return list(filter(self.__containsSeed, svcAttrs))
0061 
0062 
0063     def countSeeds(self):
0064         """
0065         _countSeeds_
0066 
0067         Count the number of seeds required by this service by
0068         summing up the initialSeed and initialSeedSet entries
0069         in all PSets in the service that contain those parameters.
0070 
0071         """
0072         count = 0
0073 
0074         for itemRef in self.__psetsWithSeeds():
0075             #  //
0076             # // PSet has list of seeds
0077             #//
0078             seedSet = getattr(itemRef, "initialSeedSet", None)
0079             if seedSet != None:
0080                 count += len( seedSet.value())
0081                 continue
0082             #  //
0083             # // PSet has single seed
0084             #//
0085             seedVal =  getattr(itemRef, "initialSeed", None)
0086             if seedVal != None:
0087                 count += 1
0088 
0089             #  //
0090             # // PSet has no recognisable seed, therfore do nothing
0091             #//  with it
0092         return count
0093 
0094 
0095     def setNamedSeed(self, psetName, *seeds):
0096         """
0097         _setNamedSeed_
0098 
0099         If a specific set of seeds is needed for a PSet in this
0100         service, they can be set by name using this method.
0101 
0102         - *psetName* : Name of the pset containing the seeds
0103 
0104         - *seeds*    : list of seeds to be added, should be a single seed
0105         for initialSeed values.
0106 
0107         """
0108         pset = getattr(self._randService, psetName, None)
0109         if pset == None:
0110             msg = "No PSet named %s belongs to this instance of the" % (
0111                 psetName,)
0112             msg += "Random Seed Service"
0113             raise RuntimeError(msg)
0114 
0115         seedVal = getattr(pset, "initialSeed", None)
0116         if seedVal != None:
0117             pset.initialSeed = CfgTypes.untracked(
0118                 CfgTypes.uint32(seeds[0])
0119                 )
0120 
0121             return
0122         seedSet = getattr(pset, "initialSeedSet", None)
0123         if seedSet != None:
0124             #  //
0125             # // Do we want to check the number of seeds??
0126             #//
0127             #if len(seeds) != len( seedSet.value()): pass
0128             pset.initialSeedSet = CfgTypes.untracked(
0129                 CfgTypes.vuint32(*seeds))
0130             return
0131         #  //
0132         # // No seeds for that PSet
0133         #//  Error throw?
0134         return
0135 
0136 
0137     def getNamedSeed(self, psetName):
0138         """
0139         _getNamedSeed_
0140 
0141         This method returns the seeds in a PSet in this service. Returned
0142 
0143         - *psetName* : Name of the pset containing the seeds
0144 
0145         """
0146         pset = getattr(self._randService, psetName, None)
0147         if pset == None:
0148             msg = "No PSet named %s belongs to this instance of the" % (
0149                 psetName,)
0150             msg += "Random Seed Service"
0151             raise RuntimeError(msg)
0152 
0153         seedVal = getattr(pset, "initialSeed", None)
0154         if seedVal != None:
0155             return [pset.initialSeed.value()]
0156 
0157         seedSet = getattr(pset, "initialSeedSet", None)
0158         if seedSet != None:
0159             return pset.initialSeedSet
0160 
0161 
0162     def insertSeeds(self, *seeds):
0163         """
0164         _insertSeeds_
0165 
0166         Given some list of specific seeds, insert them into the
0167         service.
0168 
0169         Length of seed list is required to be same as the seed count for
0170         the service.
0171 
0172         Usage: WM Tools.
0173 
0174         """
0175         seeds = list(seeds)
0176         if len(seeds) < self.countSeeds():
0177             msg = "Not enough seeds provided\n"
0178             msg += "Service requires %s seeds, only %s provided\n"
0179             msg += "to RandomeService.insertSeeds method\n"
0180             raise RuntimeError(msg)
0181 
0182         for item in self.__psetsWithSeeds():
0183             seedSet = getattr(item, "initialSeedSet", None)
0184             if seedSet != None:
0185                 numSeeds = len(seedSet.value())
0186                 useSeeds = seeds[:numSeeds]
0187                 seeds = seeds[numSeeds:]
0188                 item.initialSeedSet = CfgTypes.untracked(
0189                     CfgTypes.vuint32(*useSeeds))
0190                 continue
0191             useSeed = seeds[0]
0192             seeds = seeds[1:]
0193             item.initialSeed = CfgTypes.untracked(
0194                 CfgTypes.uint32(useSeed)
0195                 )
0196             continue
0197         return
0198 
0199 
0200     def populate(self, *excludePSets):
0201         """
0202         _populate_
0203 
0204         generate a bunch of seeds and stick them into this service
0205         This is the lazy user method.
0206 
0207         Optional args are names of PSets to *NOT* alter seeds.
0208 
0209         Eg:
0210         populate() will set all seeds
0211         populate("pset1", "pset2") will set all seeds but not those in
0212         psets named pset1 and pset2
0213 
0214         """
0215 
0216         import random
0217         from random import SystemRandom
0218         _inst = SystemRandom()
0219         _MAXINT = 900000000
0220 
0221         #  //
0222         # // count seeds and create the required number of seeds
0223         #//
0224         newSeeds = [ _inst.randint(1, _MAXINT)
0225                      for i in range(self.countSeeds())]
0226 
0227 
0228         self._lockedSeeds = list(excludePSets)
0229         self.insertSeeds(*newSeeds)
0230         self._lockedSeeds = []
0231         return
0232 
0233 
0234     def resetSeeds(self, value):
0235         """
0236         _resetSeeds_
0237 
0238         reset all seeds to given value
0239 
0240         """
0241         newSeeds = [ value for i in range(self.countSeeds())]
0242         self.insertSeeds(*newSeeds)
0243         return
0244 
0245 
0246 
0247 if __name__ == '__main__':
0248     #  //
0249     # // Setup a test service and populate it
0250     #//
0251     randSvc = Service("RandomNumberGeneratorService")
0252     randHelper = RandomNumberServiceHelper(randSvc)
0253 
0254     randSvc.i1 =  CfgTypes.untracked(CfgTypes.uint32(1))
0255     randSvc.t1 = CfgTypes.PSet()
0256     randSvc.t2 = CfgTypes.PSet()
0257     randSvc.t3 = CfgTypes.PSet()
0258 
0259     randSvc.t1.initialSeed = CfgTypes.untracked(
0260         CfgTypes.uint32(123455678)
0261         )
0262 
0263     randSvc.t2.initialSeedSet = CfgTypes.untracked(
0264         CfgTypes.vuint32(12345,234567,345677)
0265         )
0266 
0267 
0268     randSvc.t3.initialSeed = CfgTypes.untracked(
0269         CfgTypes.uint32(987654321)
0270         )
0271 
0272     print("Inital PSet")
0273     print(randSvc)
0274 
0275 
0276     #  //
0277     # // Autofill seeds
0278     #//
0279     print("Totally Random PSet")
0280     randHelper.populate()
0281     print(randSvc)
0282 
0283 
0284     #  //
0285     # // Set all seeds with reset method
0286     #//
0287     print("All seeds 9999")
0288     randHelper.resetSeeds(9999)
0289     print(randSvc)
0290 
0291     #  //
0292     # // test setting named seeds
0293     #//
0294     print("t1,t3 9998")
0295     randHelper.setNamedSeed("t1", 9998)
0296     randHelper.setNamedSeed("t3", 9998, 9998)
0297     print(randSvc)
0298 
0299     print("t1 seed(s)",randHelper.getNamedSeed("t1"))
0300     print("t2 seed(s)",randHelper.getNamedSeed("t2"))
0301 
0302 
0303     #  //
0304     # // Autofill seeds with exclusion list
0305     #//
0306     randHelper.populate("t1", "t3")
0307     print("t2 randomized")
0308     print(randSvc)