Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:21:10

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