Skip to content

Commit 8d727b6

Browse files
committed
Improvements to python configuration syntax
- Can now use tuples to set parameters that take multiple values - Improved validation of values passed to V* parameters
1 parent 4df3aa7 commit 8d727b6

File tree

1 file changed

+184
-26
lines changed

1 file changed

+184
-26
lines changed

FWCore/ParameterSet/python/Types.py

Lines changed: 184 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,26 @@ def __init__(self, run, *args):
431431
self.__event = args[1]
432432
else:
433433
raise RuntimeError('EventID ctor must have 2 or 3 arguments')
434+
def setValue(self, value):
435+
if isinstance(value, str):
436+
self.__run = self._valueFromString(value).__run
437+
self.__luminosityBlock = self._valueFromString(value).__luminosityBlock
438+
self.__event = self._valueFromString(value).__event
439+
else:
440+
try:
441+
iter(value)
442+
self.__run = value[0]
443+
if len(value) == 2:
444+
self.__luminosityBlock = 0
445+
self.__event = value[1]
446+
elif len(value) == 3:
447+
self.__luminosityBlock = value[1]
448+
self.__event = value[2]
449+
else:
450+
raise RuntimeError('EventID setValue takes container of 2 or 3 elements')
451+
except TypeError:
452+
#value is not iterable
453+
raise RuntimeError('EventID setValue takes container of 2 or 3 elements')
434454
def run(self) -> int:
435455
return self.__run
436456
def luminosityBlock(self) -> int:
@@ -439,7 +459,7 @@ def event(self) -> int:
439459
return self.__event
440460
@staticmethod
441461
def _isValid(value) -> builtins.bool:
442-
return True
462+
return isinstance(value, str) or isinstance(value, EventID) or len(value) == 2 or len(value) == 3
443463
@staticmethod
444464
def _valueFromString(value:str):
445465
parts = value.split(":")
@@ -468,13 +488,20 @@ def __init__(self, run, block=None):
468488
else:
469489
self.__run = run
470490
self.__block = block
491+
def setValue(self, value):
492+
if isinstance(value, str):
493+
self.__run = self._valueFromString(value).__run
494+
self.__block = self._valueFromString(value).__block
495+
else:
496+
self.__run = value[0]
497+
self.__block = value[1]
471498
def run(self) -> int:
472499
return self.__run
473500
def luminosityBlock(self) -> int:
474501
return self.__block
475502
@staticmethod
476503
def _isValid(value) -> builtins.bool:
477-
return True
504+
return isinstance(value,str) or isinstance(value, LuminosityBlockID) or len(value) == 2
478505
@staticmethod
479506
def _valueFromString(value:str):
480507
"""only used for cfg-parsing"""
@@ -498,15 +525,30 @@ def __init__(self, start, startSub=None, end=None, endSub=None):
498525
self.__end = parsed.__end
499526
self.__endSub = parsed.__endSub
500527
else:
501-
self.__start = start
502-
self.__startSub = startSub
503-
self.__end = end
504-
self.__endSub = endSub
528+
if startSub is not None and end is None:
529+
self._valueFromContainer((start, startSub))
530+
else:
531+
self._valueFromContainer(( start, startSub, end, endSub))
505532
if self.__end < self.__start:
506533
raise RuntimeError('LuminosityBlockRange '+str(self.__start)+':'+str(self.__startSub)+'-'+str(self.__end)+':'+str(self.__endSub)+' out of order')
507534
# 0 luminosity block number is a special case that means no limit
508535
if self.__end == self.__start and (self.__endSub != 0 and self.__endSub < self.__startSub):
509536
raise RuntimeError('LuminosityBlockRange '+str(self.__start)+':'+str(self.__startSub)+'-'+str(self.__end)+':'+str(self.__endSub)+' out of order')
537+
def setValue(self,value):
538+
if isinstance(value, str):
539+
parsed = self._valueFromString(value)
540+
self.__start = parsed.__start
541+
self.__startSub = parsed.__startSub
542+
self.__end = parsed.__end
543+
self.__endSub = parsed.__endSub
544+
else:
545+
self._valueFromContainer(value)
546+
if self.__end < self.__start:
547+
raise RuntimeError('LuminosityBlockRange '+str(self.__start)+':'+str(self.__startSub)+'-'+str(self.__end)+':'+str(self.__endSub)+' out of order')
548+
# 0 luminosity block number is a special case that means no limit
549+
if self.__end == self.__start and (self.__endSub != 0 and self.__endSub < self.__startSub):
550+
raise RuntimeError('LuminosityBlockRange '+str(self.__start)+':'+str(self.__startSub)+'-'+str(self.__end)+':'+str(self.__endSub)+' out of order')
551+
510552
def start(self) -> int:
511553
return self.__start
512554
def startSub(self) -> int:
@@ -517,7 +559,33 @@ def endSub(self) -> int:
517559
return self.__endSub
518560
@staticmethod
519561
def _isValid(value) -> builtins.bool:
520-
return True
562+
if isinstance(value, str):
563+
return True
564+
if isinstance(value, LuminosityBlockRange):
565+
return True
566+
try:
567+
if len(value) == 2:
568+
return len(value[0])==2 and len(value[1])==2
569+
return len(value) == 4
570+
except:
571+
return False
572+
return False
573+
def _valueFromContainer(self, value):
574+
if len(value) == 2:
575+
if len(value[0]) != 2 or len(value[1]) != 2:
576+
raise RuntimeError('LuminosityBlockRange set by a container must then contain elements which are len == 2')
577+
self.__start = value[0][0]
578+
self.__startSub = value[0][1]
579+
self.__end = value[1][0]
580+
self.__endSub = value[1][1]
581+
else:
582+
self.__start = value[0]
583+
self.__startSub = value[1]
584+
self.__end = value[2]
585+
self.__endSub = value[3]
586+
587+
588+
>>>>>>> 999d50d388e (Improvements to python configuration syntax)
521589
@staticmethod
522590
def _valueFromString(value:str):
523591
"""only used for cfg-parsing"""
@@ -561,26 +629,34 @@ def __init__(self, start, *args):
561629
self.__endLumi = parsed.__endLumi
562630
self.__endSub = parsed.__endSub
563631
else:
564-
self.__start = start
565-
if len(args) == 3:
566-
self.__startLumi = 0
567-
self.__startSub = args[0]
568-
self.__end = args[1]
569-
self.__endLumi = 0
570-
self.__endSub = args[2]
571-
elif len(args) == 5:
572-
self.__startLumi = args[0]
573-
self.__startSub = args[1]
574-
self.__end = args[2]
575-
self.__endLumi = args[3]
576-
self.__endSub = args[4]
632+
if len(args) == 0:
633+
self._valueFromContainer(start)
577634
else:
578-
raise RuntimeError('EventRange ctor must have 4 or 6 arguments')
635+
v = [start]
636+
v.extend(args)
637+
self._valueFromContainer(v)
638+
if self.__end < self.__start or (self.__end == self.__start and self.__endLumi < self.__startLumi):
639+
raise RuntimeError('EventRange '+str(self.__start)+':'+str(self.__startLumi)+':'+str(self.__startSub)+'-'+str(self.__end)+':'+str(self.__endLumi)+':'+str(self.__endSub)+' out of order')
640+
# 0 event number is a special case that means no limit
641+
if self.__end == self.__start and self.__endLumi == self.__startLumi and (self.__endSub != 0 and self.__endSub < self.__startSub):
642+
raise RuntimeError('EventRange '+str(self.__start)+':'+str(self.__startLumi)+':'+str(self.__startSub)+'-'+str(self.__end)+':'+str(self.__endLumi)+':'+str(self.__endSub)+' out of order')
643+
def setValue(self, value):
644+
if isinstance(value, str):
645+
parsed = self._valueFromString(value)
646+
self.__start = parsed.__start
647+
self.__startLumi = parsed.__startLumi
648+
self.__startSub = parsed.__startSub
649+
self.__end = parsed.__end
650+
self.__endLumi = parsed.__endLumi
651+
self.__endSub = parsed.__endSub
652+
else:
653+
self._valueFromContainer(value)
579654
if self.__end < self.__start or (self.__end == self.__start and self.__endLumi < self.__startLumi):
580655
raise RuntimeError('EventRange '+str(self.__start)+':'+str(self.__startLumi)+':'+str(self.__startSub)+'-'+str(self.__end)+':'+str(self.__endLumi)+':'+str(self.__endSub)+' out of order')
581656
# 0 event number is a special case that means no limit
582657
if self.__end == self.__start and self.__endLumi == self.__startLumi and (self.__endSub != 0 and self.__endSub < self.__startSub):
583658
raise RuntimeError('EventRange '+str(self.__start)+':'+str(self.__startLumi)+':'+str(self.__startSub)+'-'+str(self.__end)+':'+str(self.__endLumi)+':'+str(self.__endSub)+' out of order')
659+
584660
def start(self) -> int:
585661
return self.__start
586662
def startLumi(self) -> int:
@@ -596,6 +672,35 @@ def endSub(self) -> int:
596672
@staticmethod
597673
def _isValid(value) -> builtins.bool:
598674
return True
675+
def _valueFromContainer(self, value):
676+
length = len(value)
677+
if length == 2:
678+
if len(value[0]) != 3 or len(value[1]) != 3:
679+
raise RuntimeError('EventRange set with 2 arguments require the arguments to be a container with 3 elements')
680+
else:
681+
self.__start = value[0][0]
682+
self.__startLumi = value[0][1]
683+
self.__startSub = value[0][2]
684+
self.__end = value[1][0]
685+
self.__endLumi = value[1][1]
686+
self.__endSub = value[1][2]
687+
elif length == 4:
688+
self.__start = value[0]
689+
self.__startLumi = 0
690+
self.__startSub = value[1]
691+
self.__end = value[2]
692+
self.__endLumi = 0
693+
self.__endSub = value[3]
694+
elif len(value) == 6:
695+
self.__start = value[0]
696+
self.__startLumi = value[1]
697+
self.__startSub = value[2]
698+
self.__end = value[3]
699+
self.__endLumi = value[4]
700+
self.__endSub = value[5]
701+
else:
702+
raise RuntimeError('EventRange setValue must be set using 2, 4, or 6 arguments')
703+
599704
@staticmethod
600705
def _valueFromString(value:str):
601706
"""only used for cfg-parsing"""
@@ -1084,7 +1189,12 @@ def _itemIsValid(cls,item):
10841189
def configValueForItem(self,item,options:PrintOptions) -> str:
10851190
return LuminosityBlockID.formatValueForConfig(item)
10861191
def pythonValueForItem(self,item, options:PrintOptions) -> str:
1087-
return item.dumpPython(options)
1192+
if isinstance(item,str):
1193+
return '"'+item+'"'
1194+
elif isinstance(item, _Parameterizable):
1195+
return item.dumpPython(options)
1196+
return str(item)
1197+
>>>>>>> 999d50d388e (Improvements to python configuration syntax)
10881198
@staticmethod
10891199
def _valueFromString(value:str):
10901200
return VLuminosityBlockID(*_ValidatingParameterListBase._itemsFromStrings(value,LuminosityBlockID._valueFromString))
@@ -1210,11 +1320,12 @@ def configValueForItem(self,item,options:PrintOptions) -> str:
12101320
def pythonValueForItem(self,item, options:PrintOptions) -> str:
12111321
if isinstance(item, str):
12121322
return '"'+item+'"'
1213-
else:
1323+
elif isinstance(item, _Parameterizable):
12141324
return item.dumpPython(options)
1325+
return str(item)
12151326
@staticmethod
12161327
def _valueFromString(value:str):
1217-
return VLuminosityBlockRange(*_ValidatingParameterListBase._itemsFromStrings(value,VLuminosityBlockRange._valueFromString))
1328+
return VLuminosityBlockRange(*_ValidatingParameterListBase._itemsFromStrings(value,LuminosityBlockRange._valueFromString))
12181329
def insertInto(self, parameterSet, myname:str):
12191330
cppIDs = list()
12201331
for i in self:
@@ -1236,11 +1347,12 @@ def configValueForItem(self,item,options:PrintOptions) -> str:
12361347
def pythonValueForItem(self,item, options:PrintOptions) -> str:
12371348
if isinstance(item, str):
12381349
return '"'+item+'"'
1239-
else:
1350+
elif isinstance(item, _Parameterizable):
12401351
return item.dumpPython(options)
1352+
return str(item)
12411353
@staticmethod
12421354
def _valueFromString(value:str):
1243-
return VEventRange(*_ValidatingParameterListBase._itemsFromStrings(value,VEventRange._valueFromString))
1355+
return VEventRange(*_ValidatingParameterListBase._itemsFromStrings(value,EventRange._valueFromString))
12441356
def insertInto(self, parameterSet, myname:str):
12451357
cppIDs = list()
12461358
for i in self:
@@ -1627,6 +1739,7 @@ def testvstring(self):
16271739
self.assertEqual(len(a), 5)
16281740
self.assertEqual(a[0], "")
16291741
self.assertEqual(a[3], "Sarah")
1742+
self.assertEqual(a.dumpPython(), "cms.vstring(\n '',\n 'Barack',\n 'John',\n 'Sarah',\n 'Joe'\n)")
16301743
ps = PSet(v = vstring('a', 'b'))
16311744
ps.v = ['loose']
16321745
def testUntracked(self):
@@ -2212,6 +2325,13 @@ def testEventID(self):
22122325
eid.insertInto(pset,'foo')
22132326
eid2 = EventID._valueFromString('3:4')
22142327
eid2.insertInto(pset,'foo2')
2328+
eid = EventID(0,0,0)
2329+
eid.setValue("2:0:3")
2330+
self.assertEqual( repr(eid), "cms.EventID(2, 0, 3)" )
2331+
eid.setValue( (4,1))
2332+
self.assertEqual( repr(eid), "cms.EventID(4, 0, 1)" )
2333+
eid.setValue( (5,1,2))
2334+
self.assertEqual( repr(eid), "cms.EventID(5, 1, 2)" )
22152335
def testVEventID(self):
22162336
veid = VEventID(EventID(2, 0, 3))
22172337
veid2 = VEventID("1:2", "3:4")
@@ -2228,14 +2348,31 @@ def testLuminosityBlockID(self):
22282348
lid.insertInto(pset,'foo')
22292349
lid2 = LuminosityBlockID._valueFromString('3:4')
22302350
lid2.insertInto(pset,'foo2')
2351+
lid3 = LuminosityBlockID(1)
2352+
lid3.setValue((2,3))
2353+
self.assertEqual(repr(lid3), "cms.LuminosityBlockID(2, 3)")
22312354

22322355
def testVLuminosityBlockID(self):
22332356
vlid = VLuminosityBlockID(LuminosityBlockID(2, 3))
22342357
vlid2 = VLuminosityBlockID("1:2", "3:4")
22352358
self.assertEqual( repr(vlid[0]), "cms.LuminosityBlockID(2, 3)" )
22362359
self.assertEqual( repr(vlid2[0]), "'1:2'" )
2360+
self.assertEqual( vlid2.dumpPython(), 'cms.VLuminosityBlockID("1:2", "3:4")')
2361+
vlid3 = VLuminosityBlockID((1,2),(3,4))
2362+
self.assertEqual( repr(vlid3[0]), '(1, 2)' )
2363+
self.assertEqual( vlid3.dumpPython(), 'cms.VLuminosityBlockID((1, 2), (3, 4))')
22372364
pset = PSetTester()
22382365
vlid.insertInto(pset,'foo')
2366+
vlid4 = VLuminosityBlockID()
2367+
vlid4.setValue(["1:2"])
2368+
self.assertEqual( vlid4.dumpPython(), 'cms.VLuminosityBlockID("1:2")' )
2369+
p = PSet(v = VLuminosityBlockID())
2370+
p.v = VLuminosityBlockID()
2371+
p.v = ["1:2"]
2372+
self.assertEqual( p.v.dumpPython(), 'cms.VLuminosityBlockID("1:2")' )
2373+
p = PSet( v = VLuminosityBlockID())
2374+
p.v = [(3,1)]
2375+
self.assertEqual( p.v.dumpPython(), 'cms.VLuminosityBlockID((3, 1))' )
22392376

22402377
def testEventRange(self):
22412378
range1 = EventRange(1, 0, 2, 3, 0, 4)
@@ -2246,12 +2383,20 @@ def testEventRange(self):
22462383
pset = PSetTester()
22472384
range1.insertInto(pset,'foo')
22482385
range2.insertInto(pset,'bar')
2386+
range4 = EventRange((1,2,3), (4,5,6))
2387+
self.assertEqual(repr(range4), "cms.EventRange(1, 2, 3, 4, 5, 6)")
22492388
def testVEventRange(self):
22502389
v1 = VEventRange(EventRange(1, 0, 2, 3, 0, 4))
22512390
v2 = VEventRange("1:2-3:4", "5:MIN-7:MAX")
2391+
self.assertEqual( v2.dumpPython(), 'cms.VEventRange("1:2-3:4", "5:MIN-7:MAX")')
22522392
self.assertEqual( repr(v1[0]), "cms.EventRange(1, 0, 2, 3, 0, 4)" )
22532393
pset = PSetTester()
22542394
v2.insertInto(pset,'foo')
2395+
v3 = VEventRange(((1,2,3), (4,5,6)), ((7,1,1),(8,0,0)))
2396+
self.assertEqual(v3.dumpPython(), "cms.VEventRange(((1, 2, 3), (4, 5, 6)), ((7, 1, 1), (8, 0, 0)))")
2397+
p = PSet(v = VEventRange())
2398+
p.v = [((3,2,1), (7,8,9))]
2399+
self.assertEqual(p.v[0], ((3,2,1), (7,8,9)))
22552400

22562401
def testLuminosityBlockRange(self):
22572402
range1 = LuminosityBlockRange(1, 2, 3, 4)
@@ -2262,12 +2407,25 @@ def testLuminosityBlockRange(self):
22622407
pset = PSetTester()
22632408
range1.insertInto(pset,'foo')
22642409
range2.insertInto(pset,'bar')
2410+
range4 = LuminosityBlockRange(1, 2, 3, 4)
2411+
range4.setValue((2,3,4,5))
2412+
self.assertEqual(repr(range4), "cms.LuminosityBlockRange(2, 3, 4, 5)")
2413+
range5 = LuminosityBlockRange((1,2), (3,4))
2414+
self.assertEqual(repr(range5), "cms.LuminosityBlockRange(1, 2, 3, 4)")
22652415
def testVLuminosityBlockRange(self):
22662416
v1 = VLuminosityBlockRange(LuminosityBlockRange(1, 2, 3, 4))
22672417
v2 = VLuminosityBlockRange("1:2-3:4", "5:MIN-7:MAX")
22682418
self.assertEqual( repr(v1[0]), "cms.LuminosityBlockRange(1, 2, 3, 4)" )
22692419
pset = PSetTester()
22702420
v2.insertInto(pset,'foo')
2421+
v3 = VLuminosityBlockRange(((1,2), (3,4)), ((5,6), (7,8)))
2422+
self.assertEqual( v3.dumpPython(), "cms.VLuminosityBlockRange(((1, 2), (3, 4)), ((5, 6), (7, 8)))")
2423+
p = PSet(v = VLuminosityBlockRange())
2424+
p.v = [((3,2), (7,8))]
2425+
self.assertEqual(p.v[0], ((3,2), (7,8)))
2426+
self.assertRaises(TypeError, lambda x: VLuminosityBlockRange(x), 1)
2427+
2428+
self.assertRaises(TypeError, lambda x: VLuminosityBlockRange(x), ((1,2,3),(1,2)))
22712429

22722430
def testPSetConversion(self):
22732431
p = PSet(a = untracked.int32(7),

0 commit comments

Comments
 (0)