Skip to content

Commit 54193e6

Browse files
jenshnielsenWilliamHPNielsen
authored andcommitted
set_parser for seq element setting added (#832)
* set_parser for seq element setting added * Add Permissive int validator To be used for parameters that may be set as floats but should be cast to int * Still validate this and parse it too
1 parent 7ddae2b commit 54193e6

File tree

4 files changed

+80
-2
lines changed

4 files changed

+80
-2
lines changed

qcodes/instrument_drivers/tektronix/AWG5014.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ def __init__(self, name, address, timeout=180, num_channels=4, **kwargs):
212212
label='Sequence position',
213213
get_cmd='AWGControl:SEQuencer:POSition?',
214214
set_cmd='SEQuence:JUMP:IMMediate {}',
215-
vals=vals.Ints(1)
215+
vals=vals.PermissiveInts(1),
216+
set_parser=lambda x: int(round(x))
216217
)
217218

218219
# Trigger parameters #

qcodes/tests/test_parameter.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from unittest import TestCase
66
from time import sleep
77

8+
import numpy as np
9+
810
from qcodes import Function
911
from qcodes.instrument.parameter import (
1012
Parameter, ArrayParameter, MultiParameter,
@@ -250,6 +252,35 @@ def test_latest_value(self):
250252
self.assertEqual(p.get_latest(), 21)
251253
self.assertEqual(p.get_values, [21])
252254

255+
256+
class TestValsandParseParameter(TestCase):
257+
258+
def setUp(self):
259+
self.parameter = Parameter(name='foobar',
260+
set_cmd=None, get_cmd=None,
261+
set_parser=lambda x: int(round(x)),
262+
vals=vals.PermissiveInts(0))
263+
264+
def test_setting_int_with_float(self):
265+
266+
a = 0
267+
b = 10
268+
values = np.linspace(a, b, b-a+1)
269+
for i in values:
270+
self.parameter(i)
271+
a = self.parameter()
272+
assert isinstance(a, int)
273+
274+
def test_setting_int_with_float_not_close(self):
275+
276+
a = 0
277+
b = 10
278+
values = np.linspace(a, b, b-a+2)
279+
for i in values[1:-2]:
280+
with self.assertRaises(TypeError):
281+
self.parameter(i)
282+
283+
253284
class SimpleArrayParam(ArrayParameter):
254285
def __init__(self, return_val, *args, **kwargs):
255286
self._return_val = return_val

qcodes/tests/test_validators.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import numpy as np
44

55
from qcodes.utils.validators import (Validator, Anything, Bool, Strings,
6-
Numbers, Ints, Enum, MultiType,
6+
Numbers, Ints, PermissiveInts,
7+
Enum, MultiType,
78
Arrays, Multiples, Lists, Callable, Dict)
89

910

@@ -351,6 +352,30 @@ def test_failed_numbers(self):
351352
Ints(min_value=val)
352353

353354

355+
class TestPermissiveInts(TestCase):
356+
357+
358+
def test_close_to_ints(self):
359+
validator = PermissiveInts()
360+
a = 0
361+
b = 10
362+
values = np.linspace(a, b, b-a+1)
363+
for i in values:
364+
validator.validate(i)
365+
366+
def test_bad_values(self):
367+
validator = PermissiveInts(0, 10)
368+
a = 0
369+
b = 10
370+
values = np.linspace(a, b, b-a+2)
371+
for j,i in enumerate(values):
372+
if j == 0 or j == 11:
373+
validator.validate(i)
374+
else:
375+
with self.assertRaises(TypeError):
376+
validator.validate(i)
377+
378+
354379
class TestEnum(TestCase):
355380
enums = [
356381
[True, False],

qcodes/utils/validators.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,27 @@ def __repr__(self):
217217
maxv = self._max_value if self._max_value < BIGINT else None
218218
return '<Ints{}>'.format(range_str(minv, maxv, 'v'))
219219

220+
class PermissiveInts(Ints):
221+
"""
222+
requires an integer or a float close to an integer
223+
optional parameters min_value and max_value enforce
224+
min_value <= value <= max_value
225+
Note that you probably always want to use this with a
226+
set_parser that converts the float repr to an actual int
227+
"""
228+
def validate(self, value, context=''):
229+
if isinstance(value, (float, np.floating)):
230+
intrepr = int(round(value))
231+
remainder = abs(value - intrepr)
232+
if remainder < 1e-05:
233+
castvalue = intrepr
234+
else:
235+
raise TypeError('{} is not an int or close to an int'
236+
'; {}'.format(repr(value), context))
237+
else:
238+
castvalue = value
239+
super().validate(castvalue, context=context)
240+
220241

221242
class Enum(Validator):
222243
"""

0 commit comments

Comments
 (0)