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 test_steppeing_from_invalid_starting_point(self): the_value = -10 def set_function(value): nonlocal the_value the_value = value def get_function(): return the_value a = Parameter('test', set_cmd=set_function, get_cmd=get_function, vals=Numbers(0, 100), step=5) # We start out by setting the parameter to an # invalid value. This is not possible using initial_value # as the validator will catch that but perhaps this may happen # if the instrument can return out of range values. assert a.get() == -10 with pytest.raises(ValueError): # trying to set to 10 should raise even with 10 valid # as the steps demand that we first step to -5 which is not a.set(10) # afterwards the value should still be the same assert a.get() == -10
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.instrument.parameter.Parameter: n_points_2 at [0-9]+>,\) ' r'and setpoints are shape ' r'\(<qcodes.instrument.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_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_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.instrument.parameter.Parameter: n_points_1 at [0-9]+>, <qcodes.instrument.parameter.Parameter: n_points_2 at [0-9]+>\) to setpoints: " r"\(<qcodes.instrument.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_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_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 create_parameter(snapshot_get: bool, snapshot_value: bool, cache_is_valid: bool, get_cmd: Optional[Union[Callable[..., Any], bool]], offset: Union[str, float] = NOT_PASSED): kwargs: Dict[str, Any] = dict(set_cmd=None, label='Parameter', unit='a.u.', docstring='some docs') if offset != NOT_PASSED: kwargs.update(offset=offset) if snapshot_get != NOT_PASSED: kwargs.update(snapshot_get=snapshot_get) if snapshot_value != NOT_PASSED: kwargs.update(snapshot_value=snapshot_value) if get_cmd != NOT_PASSED: kwargs.update(get_cmd=get_cmd) p = Parameter('p', **kwargs) if get_cmd is not False: def wrap_in_call_counter(get_func): call_count = 0 def wrapped_func(*args, **kwargs): nonlocal call_count call_count += 1 return get_func(*args, **kwargs) wrapped_func.call_count = lambda: call_count return wrapped_func p.get = wrap_in_call_counter(p.get) # pre-condition assert p.get.call_count() == 0 # type: ignore[attr-defined] else: # pre-condition assert not hasattr(p, 'get') assert not p.gettable if cache_is_valid: p.set(42) return p
def test_number_of_validations(self): p = Parameter('p', set_cmd=None, initial_value=0, vals=BookkeepingValidator()) self.assertEqual(p.vals.values_validated, [0]) p.step = 1 p.set(10) self.assertEqual(p.vals.values_validated, [0, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9])
def test_number_of_validations(self): 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. self.assertEqual(p.vals.values_validated, [0, 0]) p.step = 1 p.set(10) self.assertEqual(p.vals.values_validated, [0, 0, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
def test_get_latest(self): # Create a gettable parameter local_parameter = Parameter('test_param', set_cmd=None, get_cmd=None) before_set = datetime.now() local_parameter.set(1) after_set = datetime.now() # Check we return last set value, with the correct timestamp self.assertEqual(local_parameter.get_latest(), 1) self.assertTrue(before_set <= local_parameter.get_latest.get_timestamp() <= after_set) # Check that updating the value updates the timestamp local_parameter.set(2) self.assertEqual(local_parameter.get_latest(), 2) self.assertGreaterEqual(local_parameter.get_latest.get_timestamp(), after_set)
def array_in_scalar_dataset_unrolled(experiment): meas = Measurement() scalar_param = Parameter('scalarparam', set_cmd=None) param = ArraySetPointParam() meas.register_parameter(scalar_param) meas.register_parameter(param, setpoints=(scalar_param,), paramtype='numeric') with meas.run() as datasaver: for i in range(1, 10): 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 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 test_ramp_scaled(self, scale, value): p = Parameter('p', set_cmd=self.set_p, get_cmd=self.get_p, scale=scale, initial_value=0) assert p() == 0.0 # first set a step size p.step = 0.1 # and a wait time p.inter_delay = 1e-9 # in seconds expected_output = np.linspace(0.1, 10, 100) np.testing.assert_allclose(p.get_ramp_values(10, p.step), expected_output) p.set(value) np.testing.assert_allclose(p.get(), value) assert p.raw_value == value * scale
def varlen_array_in_scalar_dataset(experiment): meas = Measurement() scalar_param = Parameter('scalarparam', set_cmd=None) param = ArraySetPointParam() meas.register_parameter(scalar_param) meas.register_parameter(param, setpoints=(scalar_param,), paramtype='array') np.random.seed(0) with meas.run() as datasaver: for i in range(1, 10): scalar_param.set(i) param.setpoints = (np.arange(i),) datasaver.add_result((scalar_param, scalar_param.get()), (param, np.random.rand(i))) try: yield datasaver.dataset finally: datasaver.dataset.conn.close()
def test_validation_without_shape(): """ If the Arrays validator does not have a shape the validation will fail """ n_points_1 = Parameter('n_points_1', set_cmd=None, vals=vals.Ints()) n_points_1.set(10) setpoints_1 = Parameter('setpoints_1', get_cmd=lambda: rand(n_points_1()), vals=vals.Arrays(shape=(n_points_1, ))) with pytest.raises(RuntimeError, match=r"A ParameterWithSetpoints must " r"have a shape defined " r"for its validator."): param_without_shape = ParameterWithSetpoints( 'param_5', get_cmd=lambda: rand(n_points_1()), setpoints=(setpoints_1, ), vals=vals.Arrays())
def test_validation_no_validator(): """ If a parameter does not use array validators it cannot be validated. """ n_points_1 = Parameter('n_points_1', set_cmd=None, vals=vals.Ints()) n_points_1.set(10) setpoints_1 = Parameter('setpoints_1', get_cmd=lambda: rand(n_points_1()), vals=vals.Arrays(shape=(n_points_1, ))) # output does not have a validator with pytest.raises(ValueError, match=r"A ParameterWithSetpoints must have " r"an Arrays validator got " r"<class 'NoneType'>"): param_without_validator = ParameterWithSetpoints( 'param_3', get_cmd=lambda: rand(n_points_1()), setpoints=(setpoints_1, ))
def test_get_cache(): time_resolution = time.get_clock_info('time').resolution sleep_delta = 2 * time_resolution # Create a gettable parameter local_parameter = Parameter('test_param', set_cmd=None, get_cmd=None) before_set = datetime.now() time.sleep(sleep_delta) local_parameter.set(1) time.sleep(sleep_delta) after_set = datetime.now() # Check we return last set value, with the correct timestamp assert local_parameter.cache.get() == 1 assert before_set < local_parameter.cache.timestamp < after_set # Check that updating the value updates the timestamp time.sleep(sleep_delta) local_parameter.set(2) assert local_parameter.cache.get() == 2 assert local_parameter.cache.timestamp > after_set
def test_validation_shapes(): """ Test that various parameters with setpoints and shape combinations validate correctly. """ 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, ))) setpoints_2 = Parameter('setpoints_2', get_cmd=lambda: rand(n_points_2()), vals=vals.Arrays(shape=(n_points_2, ))) param_with_setpoints_1 = ParameterWithSetpoints( 'param_1', get_cmd=lambda: rand(n_points_1()), setpoints=(setpoints_1, ), vals=vals.Arrays(shape=(n_points_1, ))) assert "<Arrays, shape: (<qcodes.instrument.parameter." \ "Parameter: n_points_1 at" in param_with_setpoints_1.__doc__ # the two shapes are the same so validation works param_with_setpoints_1.validate_consistent_shape() param_with_setpoints_1.validate(param_with_setpoints_1.get()) param_with_setpoints_2 = ParameterWithSetpoints( 'param_2', get_cmd=lambda: rand(n_points_1(), n_points_2()), vals=vals.Arrays(shape=(n_points_1, n_points_2))) param_with_setpoints_2.setpoints = (setpoints_1, setpoints_2) # 2d param_with_setpoints_2.validate_consistent_shape() param_with_setpoints_2.validate(param_with_setpoints_2.get())
def test_get_cache_no_get(): """ Test that cache.get on a parameter that does not have get is handled correctly. """ local_parameter = Parameter('test_param', set_cmd=None, get_cmd=False) # The parameter does not have a get method. with pytest.raises(AttributeError): local_parameter.get() # get_latest will fail as get cannot be called and no cache # is available with pytest.raises(RuntimeError): local_parameter.cache.get() value = 1 local_parameter.set(value) assert local_parameter.cache.get() == value local_parameter2 = Parameter('test_param2', set_cmd=None, get_cmd=False, initial_value=value) with pytest.raises(AttributeError): local_parameter2.get() assert local_parameter2.cache.get() == value
class TestMeasure(TestCase): def setUp(self): self.p1 = Parameter('P1', initial_value=1, get_cmd=None, set_cmd=None) def test_simple_scalar(self): data = Measure(self.p1).run_temp() self.assertEqual(data.single_set.tolist(), [0]) self.assertEqual(data.P1.tolist(), [1]) self.assertEqual(len(data.arrays), 2, data.arrays) self.assertNotIn('loop', data.metadata) meta = data.metadata['measurement'] self.assertEqual(meta['__class__'], 'qcodes.measure.Measure') self.assertEqual(len(meta['actions']), 1) self.assertFalse(meta['use_threads']) ts_start = datetime.strptime(meta['ts_start'], '%Y-%m-%d %H:%M:%S') ts_end = datetime.strptime(meta['ts_end'], '%Y-%m-%d %H:%M:%S') self.assertGreaterEqual(ts_end, ts_start) def test_simple_array(self): data = Measure(MultiGetter(arr=(1.2, 3.4))).run_temp() self.assertEqual(data.index0_set.tolist(), [0, 1]) self.assertEqual(data.arr.tolist(), [1.2, 3.4]) self.assertEqual(len(data.arrays), 2, data.arrays) def test_array_and_scalar(self): self.p1.set(42) data = Measure(MultiGetter(arr=(5, 6)), self.p1).run_temp() self.assertEqual(data.single_set.tolist(), [0]) self.assertEqual(data.P1.tolist(), [42]) self.assertEqual(data.index0_set.tolist(), [0, 1]) self.assertEqual(data.arr.tolist(), [5, 6]) self.assertEqual(len(data.arrays), 4, data.arrays)
def test_validation_sp_no_validator(): """ If the setpoints do not have an Arrays validator validation will fail. """ n_points_2 = Parameter('n_points_2', set_cmd=None, vals=vals.Ints()) n_points_2.set(20) # setpoints do not have a validator setpoints_2 = Parameter('setpoints_2', get_cmd=lambda: rand(n_points_2())) param_sp_without_validator = ParameterWithSetpoints( 'param_4', get_cmd=lambda: rand(n_points_2()), setpoints=(setpoints_2, ), vals=vals.Arrays(shape=(n_points_2, ))) expected_err_msg = (r"Can only validate shapes for " r"parameters with Arrays validator. " r"setpoints_2 is a setpoint") with pytest.raises(ValueError, match=expected_err_msg): param_sp_without_validator.validate_consistent_shape() with pytest.raises(ValueError, match=expected_err_msg): param_sp_without_validator.validate(param_sp_without_validator.get())
def array_in_scalar_dataset_unrolled(experiment): """ This fixture yields a dataset where an array-valued parameter is registered as a 'numeric' type and has an additional single-valued setpoint. We expect data to be saved as individual scalars, with the scalar setpoint repeated. """ meas = Measurement() scalar_param = Parameter('scalarparam', set_cmd=None) param = ArraySetPointParam() meas.register_parameter(scalar_param) meas.register_parameter(param, setpoints=(scalar_param, ), paramtype='numeric') with meas.run() as datasaver: for i in range(1, 10): 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 test_get_latest(self): time_resolution = time.get_clock_info('time').resolution sleep_delta = 2 * time_resolution # Create a gettable parameter local_parameter = Parameter('test_param', set_cmd=None, get_cmd=None) before_set = datetime.now() time.sleep(sleep_delta) local_parameter.set(1) time.sleep(sleep_delta) after_set = datetime.now() # Check we return last set value, with the correct timestamp self.assertEqual(local_parameter.get_latest(), 1) self.assertTrue( before_set < local_parameter.get_latest.get_timestamp() < after_set ) # Check that updating the value updates the timestamp time.sleep(sleep_delta) local_parameter.set(2) self.assertEqual(local_parameter.get_latest(), 2) self.assertGreater(local_parameter.get_latest.get_timestamp(), after_set)
def parameters(): 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_3 = Parameter('n_points_3', set_cmd=None, vals=vals.Ints()) n_points_1.set(10) n_points_2.set(20) n_points_3.set(15) setpoints_1 = Parameter('setpoints_1', get_cmd=lambda: np.arange(n_points_1()), vals=vals.Arrays(shape=(n_points_1, ))) setpoints_2 = Parameter('setpoints_2', get_cmd=lambda: np.arange(n_points_2()), vals=vals.Arrays(shape=(n_points_2, ))) setpoints_3 = Parameter('setpoints_3', get_cmd=lambda: np.arange(n_points_3()), vals=vals.Arrays(shape=(n_points_3, ))) yield (n_points_1, n_points_2, n_points_3, setpoints_1, setpoints_2, setpoints_3)