def test_set_to_none_for_not_captured_parameter_but_instrument_has_value(): # representing instrument here instr_value = 'something' set_counter = 0 def set_instr_value(value): nonlocal instr_value, set_counter instr_value = value set_counter += 1 # make a parameter that is linked to an instrument p = Parameter('p', set_cmd=set_instr_value, get_cmd=lambda: instr_value, val_mapping={'foo': 'something', None: 'nothing'}) # pre-conditions assert p.cache._value is None assert p.cache._raw_value is None assert p.cache.timestamp is None assert set_counter == 0 with p.set_to(None): # assertions after entering the context assert set_counter == 1 assert instr_value == 'nothing' assert p.cache._value is None assert p.cache._raw_value == 'nothing' assert p.cache.timestamp is not None # assertions after exiting the context assert set_counter == 2 assert instr_value == 'something' assert p.cache._value == 'foo' assert p.cache._raw_value == 'something' assert p.cache.timestamp is not None
def test_get_on_parameter_marked_as_non_gettable_raises(): a = Parameter("param") a._gettable = False with pytest.raises( TypeError, match="Trying to get a parameter that is not gettable."): a.get()
def __init__(self, name: str = "dummy", **kwargs: Any): """ Create a dummy instrument that can be used for testing. This instrument has its parameters declared as attributes and does not use add_parameter. """ super().__init__(name, **kwargs) self.ch1 = Parameter( "ch1", instrument=self, initial_value=0, label="Gate ch1", unit="V", vals=Numbers(-800, 400), get_cmd=None, set_cmd=None, ) self.ch2 = Parameter( "ch2", instrument=self, initial_value=0, label="Gate ch2", unit="V", vals=Numbers(-800, 400), get_cmd=None, set_cmd=None, )
def test_delegate_parameter_with_changed_source_snapshot_matches_value( value, scale, offset): delegate_param = DelegateParameter(name="delegate", source=None, scale=scale, offset=offset) source_parameter = Parameter(name="source", get_cmd=None, set_cmd=None, initial_value=value) _assert_none_source_is_correct(delegate_param) delegate_param.source = source_parameter calc_value = (value - offset) / scale assert delegate_param.cache.get(get_if_invalid=False) == calc_value assert delegate_param.source.cache.get(get_if_invalid=False) == value snapshot = delegate_param.snapshot() # disregard timestamp that might be slightly different snapshot["source_parameter"].pop("ts") source_snapshot = source_parameter.snapshot() source_snapshot.pop("ts") assert snapshot["source_parameter"] == source_snapshot assert snapshot["value"] == calc_value assert delegate_param.get() == calc_value # now remove the source again delegate_param.source = None _assert_none_source_is_correct(delegate_param) _assert_delegate_cache_none_source(delegate_param)
def test_has_set_get(): # Create parameter that has no set_cmd, and get_cmd returns last value gettable_parameter = Parameter('one', set_cmd=False, get_cmd=None) assert hasattr(gettable_parameter, 'get') assert gettable_parameter.gettable assert not hasattr(gettable_parameter, 'set') assert not gettable_parameter.settable with pytest.raises(NotImplementedError): gettable_parameter(1) # Initial value is None if not explicitly set assert gettable_parameter() is None # Assert the ``cache.set`` still works for non-settable parameter gettable_parameter.cache.set(1) assert gettable_parameter() == 1 # Create parameter that saves value during set, and has no get_cmd settable_parameter = Parameter('two', set_cmd=None, get_cmd=False) assert not hasattr(settable_parameter, 'get') assert not settable_parameter.gettable assert hasattr(settable_parameter, 'set') assert settable_parameter.settable with pytest.raises(NotImplementedError): settable_parameter() settable_parameter(42) settable_gettable_parameter = Parameter('three', set_cmd=None, get_cmd=None) assert hasattr(settable_gettable_parameter, 'set') assert settable_gettable_parameter.settable assert hasattr(settable_gettable_parameter, 'get') assert settable_gettable_parameter.gettable assert settable_gettable_parameter() is None settable_gettable_parameter(22) assert settable_gettable_parameter() == 22
def test_bad_name(): with pytest.raises(ValueError): Parameter('p with space') with pytest.raises(ValueError): Parameter('⛄') with pytest.raises(ValueError): Parameter('1')
def setUpClass(cls): cls.p1 = Parameter('p1', get_cmd=None, set_cmd=None, vals=Numbers(-10, 10)) cls.p2 = Parameter('p2', get_cmd=None, set_cmd=None, vals=Numbers(-10, 10)) cls.p3 = Parameter('p3', get_cmd=None, set_cmd=None, vals=Numbers(-10, 10)) cls.instr = DummyInstrument('dummy_bunny') cls.p4_crazy = NanReturningParameter('p4_crazy', instrument=cls.instr) Station()
def test_setting_non_gettable_parameter_with_finite_step(caplog): initial_value = 0 step_size = 0.1 set_value = 1.0 # when the parameter is initially set from # the initial_value the starting point is unknown # so this should cause a warning but the parameter should still be set with caplog.at_level(logging.WARNING): x = Parameter('x', initial_value=initial_value, step=step_size, set_cmd=None) assert len(caplog.records) == 1 assert f"cannot sweep x from None to {initial_value}" in str( caplog.records[0]) assert x.cache.get() == 0 # afterwards the stepping should work as expected. with caplog.at_level(logging.WARNING): caplog.clear() assert_array_almost_equal( np.array(x.get_ramp_values(set_value, step_size)), (np.arange( initial_value + step_size, set_value + step_size, step_size))) x.set(set_value) assert x.cache.get() == set_value assert len(caplog.records) == 0
def test_delegate_parameter_get_and_snapshot_with_none_source(): """ Test that a delegate parameter returns None on get and snapshot if the source has a value of None and an offset or scale is used. And returns a value if the source is remapped to a real parameter. """ none_param = Parameter("None") source_param = Parameter('source', get_cmd=None, set_cmd=None, initial_value=2) delegate_param = DelegateParameter(name='delegate', source=none_param) delegate_param.offset = 4 assert delegate_param.get() is None assert delegate_param.snapshot()['value'] is None delegate_param.offset = None delegate_param.scale = 2 assert delegate_param.get() is None assert delegate_param.snapshot()['value'] is None assert delegate_param.cache._parameter.source.cache is none_param.cache delegate_param.source = source_param assert delegate_param.get() == 1 assert delegate_param.snapshot()['value'] == 1 assert delegate_param.cache._parameter.source.cache is source_param.cache
def test_validation_wrong_validator(): """ If the validator does not match the actual content the validation should fail """ n_points_1 = Parameter('n_points_1', set_cmd=None, vals=vals.Ints()) n_points_2 = Parameter('n_points_2', set_cmd=None, vals=vals.Ints()) n_points_1.set(10) n_points_2.set(20) setpoints_1 = Parameter('setpoints_1', get_cmd=lambda: rand(n_points_1()), vals=vals.Arrays(shape=(n_points_1, ))) # output is not consistent with validator param_with_wrong_validator = ParameterWithSetpoints( 'param_2', get_cmd=lambda: rand(n_points_2()), setpoints=(setpoints_1, ), vals=vals.Arrays(shape=(n_points_1, ))) # this does not raise because the validator shapes are consistent param_with_wrong_validator.validate_consistent_shape() # but the output is not consistent with the validator with pytest.raises(ValueError, match=r'does not have expected shape' r' \(10,\), ' r'it has shape \(20,\); ' r'Parameter: param_2'): param_with_wrong_validator.validate(param_with_wrong_validator())
def test_validation_inconsistent_shape(): """ Parameters with shapes inconsistent with their setpoints should not validate """ n_points_1 = Parameter('n_points_1', set_cmd=None, vals=vals.Ints()) n_points_2 = Parameter('n_points_2', set_cmd=None, vals=vals.Ints()) n_points_1.set(10) n_points_2.set(20) setpoints_1 = Parameter('setpoints_1', get_cmd=lambda: rand(n_points_1()), vals=vals.Arrays(shape=(n_points_1, ))) param_with_diff_length = ParameterWithSetpoints( 'param_1', get_cmd=lambda: rand(n_points_2()), setpoints=(setpoints_1, ), vals=vals.Arrays(shape=(n_points_2, ))) # inconsistent shapes expected_err_msg = ( r"Shape of output is not consistent " r"with setpoints. Output is shape " r"\(<qcodes.parameters.parameter.Parameter: n_points_2 at [0-9]+>,\) " r"and setpoints are shape " r"\(<qcodes.parameters.parameter.Parameter: n_points_1 at [0-9]+>,\)") with pytest.raises(ValueError, match=expected_err_msg): param_with_diff_length.validate_consistent_shape() with pytest.raises(ValueError, match=expected_err_msg): param_with_diff_length.validate(param_with_diff_length.get())
def test_validation_one_sp_dim_missing(): """ If one or more setpoint validators has no shape the validation will fail. """ n_points_1 = Parameter('n_points_1', set_cmd=None, vals=vals.Ints()) n_points_2 = Parameter('n_points_2', set_cmd=None, vals=vals.Ints()) n_points_1.set(10) n_points_2.set(20) setpoints_1 = Parameter( "setpoints_1", get_cmd=lambda: rand(n_points_1()), vals=vals.Arrays(shape=(n_points_1, None)), ) param_sp_without_shape = ParameterWithSetpoints( "param_6", get_cmd=lambda: rand(n_points_1()), setpoints=(setpoints_1, ), vals=vals.Arrays(shape=(n_points_1, n_points_2)), ) expected_err_msg = ( r"One or more dimensions have unknown shape " r"when comparing output: \(<qcodes.parameters.parameter.Parameter: n_points_1 at [0-9]+>, <qcodes.parameters.parameter.Parameter: n_points_2 at [0-9]+>\) to setpoints: " r"\(<qcodes.parameters.parameter.Parameter: n_points_1 at [0-9]+>, None\)" ) with pytest.raises(ValueError, match=expected_err_msg): param_sp_without_shape.validate_consistent_shape() with pytest.raises(ValueError, match=expected_err_msg): param_sp_without_shape.validate(param_sp_without_shape.get())
def test_scale_raw_value(): p = Parameter(name='test_scale_raw_value', set_cmd=None) p(42) assert p.raw_value == 42 p.scale = 2 assert p.raw_value == 42 # No set/get cmd performed assert p() == 21 p(10) assert p.raw_value == 20 assert p() == 10
def test_setting_numpy_array_valued_param_if_scale_and_offset_are_not_none(): param = Parameter(name='test_param', set_cmd=None, get_cmd=None) values = np.array([1, 2, 3, 4, 5]) param.scale = 100 param.offset = 10 param(values) assert isinstance(param.raw_value, np.ndarray)
def test_number_of_validations_for_set_cache(): p = Parameter('p', set_cmd=None, vals=BookkeepingValidator()) assert p.vals.values_validated == [] p.cache.set(1) assert p.vals.values_validated == [1] p.cache.set(4) assert p.vals.values_validated == [1, 4] p.step = 1 p.cache.set(10) assert p.vals.values_validated == [1, 4, 10]
def test_numpy_array_valued_parameter_preserves_type_if_scale_and_offset_are_set( ): def rands(): return np.random.randn(5) param = Parameter(name='test_param', set_cmd=None, get_cmd=rands) param.scale = 10 param.offset = 7 values = param() assert isinstance(values, np.ndarray)
def test_set_via_function(): # not a use case we want to promote, but it's there... p = Parameter('test', get_cmd=None, set_cmd=None) def doubler(x): p.set(x * 2) f = Function('f', call_cmd=doubler, args=[vals.Numbers(-10, 10)]) f(4) assert p.get() == 8 with pytest.raises(ValueError): f(20)
def test_set_on_parameter_marked_as_non_settable_raises(): a = Parameter("param", set_cmd=None) a.set(2) assert a.get() == 2 a._settable = False with pytest.raises( TypeError, match="Trying to set a parameter that is not settable."): a.set(1) assert a.get() == 2
def test_number_of_validations(): p = Parameter('p', set_cmd=None, initial_value=0, vals=BookkeepingValidator()) # in the set wrapper the final value is validated # and then subsequently each step is validated. # in this case there is one step so the final value # is validated twice. assert p.vals.values_validated == [0, 0] p.step = 1 p.set(10) assert p.vals.values_validated == [0, 0, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def test_setpoints_non_parameter_raises(): """ Test that putting some random function as a setpoint parameter will raise as expected. """ n_points_1 = Parameter('n_points_1', set_cmd=None, vals=vals.Ints()) n_points_2 = Parameter('n_points_2', set_cmd=None, vals=vals.Ints()) n_points_1.set(10) n_points_2.set(20) err_msg = (r"Setpoints is of type <class 'function'> " r"expcected a QCoDeS parameter") with pytest.raises(TypeError, match=err_msg): param_with_setpoints_1 = ParameterWithSetpoints( 'param_1', get_cmd=lambda: rand(n_points_1()), setpoints=(lambda x: x, ), vals=vals.Arrays(shape=(n_points_1, ))) param_with_setpoints_1 = ParameterWithSetpoints( 'param_1', get_cmd=lambda: rand(n_points_1()), vals=vals.Arrays(shape=(n_points_1, ))) with pytest.raises(TypeError, match=err_msg): param_with_setpoints_1.setpoints = (lambda x: x, )
def testLoopCombinedParameterPrintTask(self, npoints, x_start_stop, y_start_stop, z_start_stop): x_set = np.linspace(x_start_stop[0], x_start_stop[1], npoints) y_set = np.linspace(y_start_stop[0], y_start_stop[1], npoints) z_set = np.linspace(z_start_stop[0], z_start_stop[1], npoints) setpoints = np.hstack( (x_set.reshape(npoints, 1), y_set.reshape(npoints, 1), z_set.reshape(npoints, 1))) parameters = [ Parameter(name, get_cmd=None, set_cmd=None) for name in ["X", "Y", "Z"] ] sweep_values = combine(*parameters, name="combined").sweep(setpoints) def ataskfunc(): a = 1 + 1 def btaskfunc(): b = 1 + 2 atask = Task(ataskfunc) btask = Task(btaskfunc) loc_fmt = 'data/{date}/#{counter}_{name}_{date}_{time}' rcd = {'name': 'printTask'} loc_provider = FormatLocation(fmt=loc_fmt, record=rcd) loop = Loop(sweep_values).each(atask, btask) data = loop.run(location=loc_provider, quiet=True) np.testing.assert_array_equal(data.arrays['X'].ndarray, x_set) np.testing.assert_array_equal(data.arrays['Y'].ndarray, y_set) np.testing.assert_array_equal(data.arrays['Z'].ndarray, z_set)
def test_gettable_settable_attributes_with_get_set_cmd(get_cmd, set_cmd): a = Parameter(name='foo', get_cmd=get_cmd, set_cmd=set_cmd) expected_gettable = get_cmd is not False expected_settable = set_cmd is not False assert a.gettable is expected_gettable assert a.settable is expected_settable
def test_no_get_max_val_age(): """ Test that get_latest on a parameter with max_val_age set and no get cmd raises correctly. """ value = 1 with pytest.raises(SyntaxError): _ = Parameter('test_param', set_cmd=None, get_cmd=False, max_val_age=1, initial_value=value) # ParameterBase does not have this check on creation time since get_cmd # could be added in a subclass. Here we create a subclass that does add a # get command and also does not implement the check for max_val_age class LocalParameter(ParameterBase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_raw = lambda x: x self.set = self._wrap_set(self.set_raw) localparameter = LocalParameter('test_param', None, max_val_age=1) with pytest.raises(RuntimeError): localparameter.get_latest()
def test_delegate_parameter_change_source_reflected_in_label_and_unit(): delegate_param = DelegateParameter("delegate", source=None) source_param_1 = Parameter("source1", label="source 1", unit="unit1") source_param_2 = Parameter("source2", label="source 2", unit="unit2") assert delegate_param.label == "delegate" assert delegate_param.unit == "" delegate_param.source = source_param_1 assert delegate_param.label == "source 1" assert delegate_param.unit == "unit1" delegate_param.source = source_param_2 assert delegate_param.label == "source 2" assert delegate_param.unit == "unit2" delegate_param.source = None assert delegate_param.label == "delegate" assert delegate_param.unit == ""
def test_setting_initial_cache_delegate_parameter(): value = 10 p = Parameter('testparam', set_cmd=None, get_cmd=None) d = DelegateParameter('test_delegate_parameter', p, initial_cache_value=value) assert p.cache.get(get_if_invalid=False) == value assert d.cache.get(get_if_invalid=False) == value
def test_get_latest_raw_value(): # To have a simple distinction between raw value and value of the # parameter lets create a parameter with an offset p = Parameter('p', set_cmd=None, get_cmd=None, offset=42) assert p.get_latest.get_timestamp() is None # Initially, the parameter's raw value is None assert p.get_latest.get_raw_value() is None # After setting the parameter to some value, the # ``.get_latest.get_raw_value()`` call should return the new raw value # of the parameter p(3) assert p.get_latest.get_timestamp() is not None assert p.get_latest.get() == 3 assert p.get_latest() == 3 assert p.get_latest.get_raw_value() == 3 + 42
def test_scale_and_offset_raw_value_iterable_for_set_cache( values, offsets, scales): p = Parameter(name='test_scale_and_offset_raw_value', set_cmd=None) # test that scale and offset does not change the default behaviour p.cache.set(values) assert p.raw_value == values # test setting scale and offset does not change anything p.scale = scales p.offset = offsets assert p.raw_value == values np_values = np.array(values) np_offsets = np.array(offsets) np_scales = np.array(scales) np_get_latest_values = np.array(p.get_latest()) # Without a call to ``get``, ``get_latest`` will just return old # cached values without applying the set scale and offset np.testing.assert_allclose(np_get_latest_values, np_values) np_get_values = np.array(p.get()) # Now that ``get`` is called, the returned values are the result of # application of the scale and offset. Obviously, calling # ``get_latest`` now will also return the values with the applied # scale and offset np.testing.assert_allclose(np_get_values, (np_values - np_offsets) / np_scales) np_get_latest_values_after_get = np.array(p.get_latest()) np.testing.assert_allclose(np_get_latest_values_after_get, (np_values - np_offsets) / np_scales) # test ``cache.set`` for scalar values if not isinstance(values, Iterable): p.cache.set(values) np.testing.assert_allclose(np.array(p.raw_value), np_values * np_scales + np_offsets) # No set/get cmd performed # testing conversion back and forth p.cache.set(values) np_get_latest_values = np.array(p.get_latest()) # No set/get cmd performed np.testing.assert_allclose(np_get_latest_values, np_values) # adding statistics if isinstance(offsets, Iterable): event('Offset is array') if isinstance(scales, Iterable): event('Scale is array') if isinstance(values, Iterable): event('Value is array') if isinstance(scales, Iterable) and isinstance(offsets, Iterable): event('Scale is array and also offset') if isinstance(scales, Iterable) and not isinstance(offsets, Iterable): event('Scale is array but not offset')
def test_snapshot(): p = Parameter('testparam', set_cmd=None, get_cmd=None, offset=1, scale=2, initial_value=1) d = DelegateParameter('test_delegate_parameter', p, offset=3, scale=5, initial_value=2) delegate_snapshot = d.snapshot() source_snapshot = delegate_snapshot.pop('source_parameter') assert source_snapshot == p.snapshot() assert delegate_snapshot['value'] == 2 assert source_snapshot['value'] == 13
def array_in_str_dataset(experiment, request): meas = Measurement() scalar_param = Parameter('textparam', set_cmd=None) param = ArraySetPointParam() meas.register_parameter(scalar_param, paramtype='text') meas.register_parameter(param, setpoints=(scalar_param, ), paramtype=request.param) with meas.run() as datasaver: for i in ['A', 'B', 'C']: scalar_param.set(i) datasaver.add_result((scalar_param, scalar_param.get()), (param, param.get())) try: yield datasaver.dataset finally: datasaver.dataset.conn.close()
def simple_param(numeric_val): yield Parameter('testparam', set_cmd=None, get_cmd=None, scale=2, offset=17, label='Test Parameter', unit='V', initial_value=numeric_val)