CMS 3D CMS Logo

RandomServiceHelper.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 
4 from __future__ import print_function
5 from FWCore.ParameterSet.Config import Service
6 import FWCore.ParameterSet.Types as CfgTypes
7 
8 
10  """
11  _RandomNumberServiceHelper_
12 
13  Helper class to hold and handle the Random number generator service.
14 
15  Provide both user level and WM APIs.
16 
17  Author: Dave Evans
18  Modified: Eric Vaandering
19  """
20 
21  def __init__(self,randService):
22  self._randService = randService
23  self._lockedSeeds = []
24 
25 
26  def __containsSeed(self,psetInstance):
27  """
28  _keeper_
29 
30  True/False if the psetInstance has seeds in it
31 
32  """
33  if psetInstance is None:
34  return False
35  if not isinstance(psetInstance,CfgTypes.PSet):
36  return False
37  seedList = getattr(psetInstance, "initialSeedSet", None)
38  if seedList != None:
39  return True
40  seedVal = getattr(psetInstance, "initialSeed", None)
41  if seedVal != None:
42  return True
43  return False
44 
45 
46  def __psetsWithSeeds(self):
47  """
48  _psetsWithSeeds_
49 
50  *private method*
51 
52  return the list of PSet instances with seeds in them
53 
54  """
55  svcAttrs = [getattr(self._randService, item, None)
56  for item in self._randService.parameters_()
57  if item not in self._lockedSeeds]
58 
59  #print svcAttrs
60 
61  return list(filter(self.__containsSeed, svcAttrs))
62 
63 
64  def countSeeds(self):
65  """
66  _countSeeds_
67 
68  Count the number of seeds required by this service by
69  summing up the initialSeed and initialSeedSet entries
70  in all PSets in the service that contain those parameters.
71 
72  """
73  count = 0
74 
75  for itemRef in self.__psetsWithSeeds():
76  # //
77  # // PSet has list of seeds
78  #//
79  seedSet = getattr(itemRef, "initialSeedSet", None)
80  if seedSet != None:
81  count += len( seedSet.value())
82  continue
83  # //
84  # // PSet has single seed
85  #//
86  seedVal = getattr(itemRef, "initialSeed", None)
87  if seedVal != None:
88  count += 1
89 
90  # //
91  # // PSet has no recognisable seed, therfore do nothing
92  #// with it
93  return count
94 
95 
96  def setNamedSeed(self, psetName, *seeds):
97  """
98  _setNamedSeed_
99 
100  If a specific set of seeds is needed for a PSet in this
101  service, they can be set by name using this method.
102 
103  - *psetName* : Name of the pset containing the seeds
104 
105  - *seeds* : list of seeds to be added, should be a single seed
106  for initialSeed values.
107 
108  """
109  pset = getattr(self._randService, psetName, None)
110  if pset == None:
111  msg = "No PSet named %s belongs to this instance of the" % (
112  psetName,)
113  msg += "Random Seed Service"
114  raise RuntimeError(msg)
115 
116  seedVal = getattr(pset, "initialSeed", None)
117  if seedVal != None:
118  pset.initialSeed = CfgTypes.untracked(
119  CfgTypes.uint32(seeds[0])
120  )
121 
122  return
123  seedSet = getattr(pset, "initialSeedSet", None)
124  if seedSet != None:
125  # //
126  # // Do we want to check the number of seeds??
127  #//
128  #if len(seeds) != len( seedSet.value()): pass
129  pset.initialSeedSet = CfgTypes.untracked(
130  CfgTypes.vuint32(*seeds))
131  return
132  # //
133  # // No seeds for that PSet
134  #// Error throw?
135  return
136 
137 
138  def getNamedSeed(self, psetName):
139  """
140  _getNamedSeed_
141 
142  This method returns the seeds in a PSet in this service. Returned
143 
144  - *psetName* : Name of the pset containing the seeds
145 
146  """
147  pset = getattr(self._randService, psetName, None)
148  if pset == None:
149  msg = "No PSet named %s belongs to this instance of the" % (
150  psetName,)
151  msg += "Random Seed Service"
152  raise RuntimeError(msg)
153 
154  seedVal = getattr(pset, "initialSeed", None)
155  if seedVal != None:
156  return [pset.initialSeed.value()]
157 
158  seedSet = getattr(pset, "initialSeedSet", None)
159  if seedSet != None:
160  return pset.initialSeedSet
161 
162 
163  def insertSeeds(self, *seeds):
164  """
165  _insertSeeds_
166 
167  Given some list of specific seeds, insert them into the
168  service.
169 
170  Length of seed list is required to be same as the seed count for
171  the service.
172 
173  Usage: WM Tools.
174 
175  """
176  seeds = list(seeds)
177  if len(seeds) < self.countSeeds():
178  msg = "Not enough seeds provided\n"
179  msg += "Service requires %s seeds, only %s provided\n"
180  msg += "to RandomeService.insertSeeds method\n"
181  raise RuntimeError(msg)
182 
183  for item in self.__psetsWithSeeds():
184  seedSet = getattr(item, "initialSeedSet", None)
185  if seedSet != None:
186  numSeeds = len(seedSet.value())
187  useSeeds = seeds[:numSeeds]
188  seeds = seeds[numSeeds:]
189  item.initialSeedSet = CfgTypes.untracked(
190  CfgTypes.vuint32(*useSeeds))
191  continue
192  useSeed = seeds[0]
193  seeds = seeds[1:]
194  item.initialSeed = CfgTypes.untracked(
195  CfgTypes.uint32(useSeed)
196  )
197  continue
198  return
199 
200 
201  def populate(self, *excludePSets):
202  """
203  _populate_
204 
205  generate a bunch of seeds and stick them into this service
206  This is the lazy user method.
207 
208  Optional args are names of PSets to *NOT* alter seeds.
209 
210  Eg:
211  populate() will set all seeds
212  populate("pset1", "pset2") will set all seeds but not those in
213  psets named pset1 and pset2
214 
215  """
216 
217  import random
218  from random import SystemRandom
219  _inst = SystemRandom()
220  _MAXINT = 900000000
221 
222  # //
223  # // count seeds and create the required number of seeds
224  #//
225  newSeeds = [ _inst.randint(1, _MAXINT)
226  for i in range(self.countSeeds())]
227 
228 
229  self._lockedSeeds = list(excludePSets)
230  self.insertSeeds(*newSeeds)
231  self._lockedSeeds = []
232  return
233 
234 
235  def resetSeeds(self, value):
236  """
237  _resetSeeds_
238 
239  reset all seeds to given value
240 
241  """
242  newSeeds = [ value for i in range(self.countSeeds())]
243  self.insertSeeds(*newSeeds)
244  return
245 
246 
247 
248 if __name__ == '__main__':
249  # //
250  # // Setup a test service and populate it
251  #//
252  randSvc = Service("RandomNumberGeneratorService")
253  randHelper = RandomNumberServiceHelper(randSvc)
254 
255  randSvc.i1 = CfgTypes.untracked(CfgTypes.uint32(1))
256  randSvc.t1 = CfgTypes.PSet()
257  randSvc.t2 = CfgTypes.PSet()
258  randSvc.t3 = CfgTypes.PSet()
259 
260  randSvc.t1.initialSeed = CfgTypes.untracked(
261  CfgTypes.uint32(123455678)
262  )
263 
264  randSvc.t2.initialSeedSet = CfgTypes.untracked(
265  CfgTypes.vuint32(12345,234567,345677)
266  )
267 
268 
269  randSvc.t3.initialSeed = CfgTypes.untracked(
270  CfgTypes.uint32(987654321)
271  )
272 
273  print("Inital PSet")
274  print(randSvc)
275 
276 
277  # //
278  # // Autofill seeds
279  #//
280  print("Totally Random PSet")
281  randHelper.populate()
282  print(randSvc)
283 
284 
285  # //
286  # // Set all seeds with reset method
287  #//
288  print("All seeds 9999")
289  randHelper.resetSeeds(9999)
290  print(randSvc)
291 
292  # //
293  # // test setting named seeds
294  #//
295  print("t1,t3 9998")
296  randHelper.setNamedSeed("t1", 9998)
297  randHelper.setNamedSeed("t3", 9998, 9998)
298  print(randSvc)
299 
300  print("t1 seed(s)",randHelper.getNamedSeed("t1"))
301  print("t2 seed(s)",randHelper.getNamedSeed("t2"))
302 
303 
304  # //
305  # // Autofill seeds with exclusion list
306  #//
307  randHelper.populate("t1", "t3")
308  print("t2 randomized")
309  print(randSvc)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47