def test_setitem_valid_arguments(self): settable_objects = { 'none': None, 'bool': False, 'int': 25, 'float': 3.141592, 'list': [1, 2, 3], 'str': 'some_string', 'bytes': b'1010101', 'json_object': PythonJsonStructure(), 'np.float32': np.float32(3.1415), 'np.float64': np.float64(-3.1415), 'np.int32': np.int32(4), 'np.in64': np.int64(-4), 'np.cfloat': np.random.rand(2, 4, 5, 3).astype(np.cfloat), 'tuple': (1, 2, 3), 'dict': { 'a': 1, 'b': 2, 'c': 3 }, 'ndarray': np.array([[1, 2], [3, 4]]) } json_object = PythonJsonStructure() for key, expected in settable_objects.items(): json_object[key] = expected np.testing.assert_array_equal(expected, json_object[key])
def test_configuration_helper_integration(self): storage = StorageMemory('some_name') configuration_1 = PythonJsonStructure(amper=0.005) configuration_2 = PythonJsonStructure(frequency='2.4 GHz') with patch('qilib.configuration_helper.instrument_configuration.InstrumentAdapterFactory'): instrument_1 = InstrumentConfiguration('DummyClass', 'fake-address-1', storage, tag=['instrument_1'], configuration=configuration_1) instrument_2 = InstrumentConfiguration('DummyClass', 'fake-address-2', storage, tag=['instrument_2'], configuration=configuration_2) instrument_configuration_set = InstrumentConfigurationSet(storage, tag=['set'], instrument_configurations=[instrument_1, instrument_2]) instrument_configuration_set.store() configuration_helper = ConfigurationHelper(storage) configuration_helper.retrieve_inactive_configuration_from_storage(['set']) inactive_configuration = configuration_helper.inactive_configuration self.assertListEqual(inactive_configuration.tag, ['set']) self.assertListEqual(inactive_configuration.instrument_configurations[0].tag, ['instrument_1']) self.assertListEqual(inactive_configuration.instrument_configurations[1].tag, ['instrument_2']) self.assertDictEqual(configuration_1, inactive_configuration.instrument_configurations[0].configuration) self.assertDictEqual(configuration_2, inactive_configuration.instrument_configurations[1].configuration) repr_str = r"ConfigurationHelper\(StorageMemory\('some_name'\), InstrumentConfigurationSet\(StorageMemory\(" \ r"'some_name'\), \['configuration_set', '.*'\], \[\]\), " \ r"InstrumentConfigurationSet\(StorageMemory\('some_name'\), \['set'\], \[InstrumentConfiguration\(" \ r"'DummyClass', 'fake-address-1', StorageMemory\('some_name'\), \['instrument_1'\], " \ r"\{'amper': 0.005\}, None\), InstrumentConfiguration\('DummyClass', 'fake-address-2', " \ r"StorageMemory\('some_name'\), \['instrument_2'\], \{'frequency': '2.4 GHz'\}, None\)\]\)\)" self.assertRegex(repr(configuration_helper), repr_str)
def test_apply_delta_lazy(self): with patch( 'qilib.configuration_helper.instrument_configuration.InstrumentAdapterFactory' ) as mock_factory: mock_adapter = MagicMock() mock_adapter.read.return_value = PythonJsonStructure( param1={'value': 1}, param2={'value': 2}, param3={'value': 3}, param4={'value': 4}) mock_factory.get_instrument_adapter.return_value = mock_adapter instrument_configuration = InstrumentConfiguration( 'DummyClass', 'fake-address', self._storage, configuration=PythonJsonStructure(param1={'value': 1}, param2={'value': 42}, param3={'value': 33})) instrument_configuration.apply_delta_lazy() mock_adapter.read.assert_called_once_with(update=False) mock_adapter.apply.assert_called_once_with({ 'param2': { 'value': 42 }, 'param3': { 'value': 33 } })
def test_apply(self): with patch.object(zhinst.utils, 'create_api_session', return_value=(MagicMock(), MagicMock(), MagicMock())), \ patch.object(qilib.configuration_helper.adapters.hdawg8_instrument_adapter.ZIHDAWG8, 'download_device_node_tree', return_value={}): config = PythonJsonStructure() config['instruments'] = PythonJsonStructure() config['instruments']['ZIHDAWG8InstrumentAdapter_DEV8048'] = PythonJsonStructure({ 'adapter_class_name': 'ZIHDAWG8InstrumentAdapter', 'address': 'DEV8048', 'config': {} }) config['settings'] = PythonJsonStructure({ 'awg_map': { 'P1': (0, 1), 'P2': (0, 2), 'dig_mk': (0, 1, 1) }, 'config': {} }) adapter = VirtualAwgInstrumentAdapter('') adapter.apply(config) self.assertEqual(adapter.instrument.settings.awg_map, {'P1': (0, 1), 'P2': (0, 2), 'dig_mk': (0, 1, 1) }) adapter.close_instrument()
def test_length(self): object_a = PythonJsonStructure() self.assertEqual(0, len(object_a), 0) object_b = PythonJsonStructure({'a': 1}) self.assertEqual(1, len(object_b)) object_b['b'] = 2 self.assertEqual(2, len(object_b))
def test_serialization_container_types(self): """ Creates a PythonJsonStucture with all the data-types. Serializes the object and directly afterwards unserializes. The unserialized object should equal the original created PythonJsonStructure. Note: Currently a PythonJsonStructure with a tuple is not tested. A tuple object can only be serialized to a list. """ settable_containers = { 'list': [1, 2, 3], 'dict': { 'a': 1, 'b': 2, 'c': 3 }, 'ndarray': np.random.rand(3, 2, 4, 5).astype(np.cfloat), # 'tuple': (1, 2, 3), 'json_object': PythonJsonStructure() } for key, expected in settable_containers.items(): json_object = PythonJsonStructure({key: expected}) serialized_object = serialize(json_object) unserialized_object = unserialize(serialized_object) np.testing.assert_equal(json_object, unserialized_object)
def __notify_and_remove_none_values( self, parameters: PythonJsonStructure) -> PythonJsonStructure: """ Return parameters from the QCoDeS snapshot which are not None. Takes the parameters of the QCoDeS instrument snapshot. Removes all parameters which have a value of None. Returns the parameter settings which have a value. All parameters with None value will be listed in the log as an error. Args: parameters: The parameters of a QCoDeS instrument snapshot. Returns: PythonJsonStructure: Contains the instrument snapshot parameters without the instrument parameters which a none value. """ valued_parameters = PythonJsonStructure() none_value_parameters = PythonJsonStructure() for parameter_name, settings in parameters.items(): if 'value' in settings and settings['value'] is None: none_value_parameters[parameter_name] = settings else: valued_parameters[parameter_name] = settings if none_value_parameters: parameter_names = list(none_value_parameters.keys()) error_message = f'Parameter values of {self._instrument_name} are None. Please set: {parameter_names}.' logging.error(error_message) return valued_parameters
def test_update_valid_data(self): json_object = PythonJsonStructure() expected = {'a': 1, 'b': 2} json_object.update(expected) self.assertDictEqual(expected, json_object) json_object = PythonJsonStructure() expected = {'c': 3, 'd': 4} json_object.update(c=3, d=4) self.assertDictEqual(expected, json_object)
def setUp(self): InstrumentAdapterFactory.adapter_instances = {} self.serial_port_settings = PythonJsonStructure(MagicMock(spec=dict())) self.mock_config = PythonJsonStructure({ 'version': 1.23, 'temperature': 293.4, 'battery': 'OK', 'serialport': self.serial_port_settings })
def read(self, update: bool = False) -> PythonJsonStructure: """ Additionally reads the gate_map, boundaries and configs of the nested dacs.""" config = PythonJsonStructure() config[CONFIG] = super().read(update) config[BOUNDARIES] = self._instrument.get_boundaries() config[GATE_MAP] = self._instrument.gate_map config[INSTRUMENTS] = PythonJsonStructure() for adapter_name, adapter in self._dac_adapters.items(): config[INSTRUMENTS][adapter_name] = PythonJsonStructure() config[INSTRUMENTS][adapter_name][CONFIG] = adapter.read(update) config[INSTRUMENTS][adapter_name][ADDRESS] = adapter.address config[INSTRUMENTS][adapter_name][ADAPTER_CLASS_NAME] = adapter.__class__.__name__ return config
def read(self, update: bool = False) -> PythonJsonStructure: config = super().read(update) config[INSTRUMENTS] = PythonJsonStructure() for adapter_name, adapter in self._adapters.items(): config[INSTRUMENTS][adapter_name] = PythonJsonStructure() config[INSTRUMENTS][adapter_name][ ADAPTER_CLASS_NAME] = adapter.__class__.__name__ config[INSTRUMENTS][adapter_name][ADDRESS] = adapter.address config[INSTRUMENTS][adapter_name][CONFIG] = adapter.read(update) config[SETTINGS] = PythonJsonStructure() config[SETTINGS][AWG_MAP] = self._instrument.settings.awg_map return config
def test_apply(self): qilib.configuration_helper.adapters.DummyInstrumentAdapter = DummyInstrumentAdapter dummy_adapter = InstrumentAdapterFactory.get_instrument_adapter('DummyInstrumentAdapter', 'some_address') dummy_adapter.instrument.amplitude(1) dummy_adapter.instrument.frequency(1) dummy_adapter.instrument.enable_output(False) mock_virtual_dac_instance = MagicMock() with patch('qtt.instrument_drivers.adapters.virtual_dac_instrument_adapter.VirtualDAC') as mock_virtual_dac: mock_virtual_dac.return_value = mock_virtual_dac_instance adapter = VirtualDACInstrumentAdapter('spirack3_module3') mock_virtual_dac.assert_called() config = PythonJsonStructure() config['config'] = snapshot['parameters'] config['boundaries'] = {'P1': (-10, 10)} config['gate_map'] = {'P1': (0, 1)} config['instruments'] = {dummy_adapter.name: {'address': 'some_address', 'adapter_class_name': 'DummyInstrumentAdapter', 'config': {'amplitude': {'value': 1e-3}, 'frequency': {'value': 130e6}, 'enable_output': {'value': True}}}} adapter.apply(config) mock_virtual_dac_instance.set_boundaries.assert_called_with({'P1': (-10, 10)}) mock_virtual_dac_instance.add_instruments.assert_called_with([dummy_adapter.instrument]) self.assertDictEqual({'P1': (0, 1)}, mock_virtual_dac_instance.gate_map) self.assertEqual(1e-3, dummy_adapter.instrument.amplitude()) self.assertEqual(130e6, dummy_adapter.instrument.frequency()) self.assertTrue(dummy_adapter.instrument.enable_output()) dummy_adapter.close_instrument()
def test_setdefault_dict_type(self): key = 'test' expected = {'a': 1, 'b': 2} json_object = PythonJsonStructure() return_value = json_object.setdefault(key, expected) self.assertEqual(expected, json_object[key]) self.assertEqual(expected, return_value)
def test_setdefault_default_present(self): key = 'test' expected = 12 json_object = PythonJsonStructure() return_value = json_object.setdefault(key, expected) self.assertEqual(expected, json_object[key]) self.assertEqual(expected, return_value)
def read(self, update: bool = True) -> PythonJsonStructure: parameters = { 'version': self._instrument.get_firmware_version(), 'temperature': self._instrument.get_temperature(), 'battery': self._instrument.get_battery(), 'serialport': self._instrument.get_settings() } return PythonJsonStructure(parameters)
def test_update_invalid_data(self): json_object = PythonJsonStructure() args_data = {'a': 1, 'b': object()} kwargs_data = {'c': 3, 'd': object()} self.assert_raises_invalid_data(json_object.update, args_data) self.assert_raises_invalid_data(json_object.update, **kwargs_data) with self.assert_raises_invalid_data(): json_object['bla'] = [[], [], [[], [[object()]]]]
def test_recursive_update(self): json_object = PythonJsonStructure() data = {'a1': [1, 2, 3], 'b1': {'a2': 2}} json_object.update(data) with self.assert_raises_invalid_data(): json_object['c1'] = object() with self.assert_raises_invalid_data(): json_object['b1']['b2'] = object()
def test_change_name_with_config(self): adapter = DummyInstrumentAdapter('dummy_address') self.assertEqual('DummyInstrumentAdapter_dummy_address', adapter.name) self.assertEqual('DummyInstrumentAdapter_dummy_address', adapter.instrument.name) config = PythonJsonStructure(name='new_name') adapter.apply(config) self.assertEqual('DummyInstrumentAdapter_dummy_address', adapter.name) adapter.close_instrument()
def test_initialize_applies_configuration(self): mock_address = 'dev2331' mock_config = PythonJsonStructure(a=1, b='2', c=3.1415) scope_mock, factory_mock = TestUhfliScopeReader.__patch_scope_reader( mock_address) self.assertEqual(mock_address, scope_mock.adapter.address) scope_mock.initialize(mock_config) factory_mock.get_instrument_adapter.assert_called_once_with( 'ZIUHFLIInstrumentAdapter', mock_address) scope_mock.adapter.apply.assert_called_once_with(mock_config) self.assertEqual(mock_address, scope_mock.adapter.address)
def test_refresh(self): with patch( 'qilib.configuration_helper.instrument_configuration.InstrumentAdapterFactory' ) as mock_factory: mock_adapter = MagicMock() instrument_settings = PythonJsonStructure(param1={'value': 1}, param2={'value': 2}, param3={'value': 3}, param4={'value': 4}) mock_adapter.read.return_value = instrument_settings mock_factory.get_instrument_adapter.return_value = mock_adapter instrument_configuration = InstrumentConfiguration( 'DummyClass', 'fake-address', self._storage, configuration=PythonJsonStructure(param1={'value': 11}, param2={'value': 22}, param3={'value': 33}, param4={'value': 444})) instrument_configuration.refresh() self.assertDictEqual(instrument_settings, instrument_configuration.configuration)
def test_setdefault_container_type(self): key = 'test' containers = [ [1, [2, 3], 2, [2, 3, [4, 5]]], (1, (2, 3), 8, (9, 10), (7, (1, 2))), np.random.rand(3, 2, 5, 1, 3), ] for expected in containers: json_object = PythonJsonStructure() return_value = json_object.setdefault(key, expected) np.testing.assert_equal(expected, json_object[key]) np.testing.assert_equal(expected, return_value)
def read(self, update: bool = True) -> PythonJsonStructure: """ Reads and returns all SPI rack module settings from the device. All module parameters will be collected, even if the parameter is write only. If the write only parameter has not been set, a None will be set as value. Args: update: Update the settings first before returning the settings configuration. Returns: A custom dictionary with all the SPI rack module settings. """ return PythonJsonStructure(super().read(update))
def load_configuration(file_path: str) -> PythonJsonStructure: """ Loads the instrument configuration from disk storage. Args: file_path: The store file location on disk. Returns: The loaded configuration from disk. """ with open(file_path, 'rb') as file_pointer: serialized_configuration = file_pointer.readlines() unserialized_configuration = dict( serialization.unserialize(serialized_configuration[0])) return PythonJsonStructure(unserialized_configuration)
def test_apply(self): with patch( 'qilib.configuration_helper.instrument_configuration.InstrumentAdapterFactory' ) as mock_factory: mock_adapter = MagicMock() mock_factory.get_instrument_adapter.return_value = mock_adapter instrument_configuration = InstrumentConfiguration( 'DummyClass', 'fake-address', self._storage, configuration=PythonJsonStructure( how_many_instruments='all_the_instruments')) instrument_configuration.apply() mock_adapter.apply.assert_called_once_with( {'how_many_instruments': 'all_the_instruments'})
def store(self) -> None: """ Saves object to storage. Raises: DuplicateTagError: If this object's tag is already in the database. """ if self._storage.tag_in_storage(self._tag): raise DuplicateTagError( f"InstrumentConfiguration for {self._adapter_class_name} with tag '{self._tag}' already in storage") document = PythonJsonStructure(adapter_class_name=self._adapter_class_name, address=self._address, instrument_name=self._instrument_name, configuration=self._configuration) self._storage.save_data(document, self._tag)
def test_constructor_full(self): config = PythonJsonStructure(voltage='low', current='lower', frequency='high-enough') with patch( 'qilib.configuration_helper.instrument_configuration.InstrumentAdapterFactory' ): instrument_configuration = InstrumentConfiguration( 'DummyClass', 'fake-address', self._storage, tag=['2019-05-09T11:29:51.523636'], configuration=config) self.assertDictEqual(config, instrument_configuration.configuration) self.assertListEqual(['2019-05-09T11:29:51.523636'], instrument_configuration.tag)
def read(self, update: bool = False) -> PythonJsonStructure: """ Obtains a full set of settings from the instrument. Returns: Part of the instrument snapshot, i.e., parameter values, without the instrument's parameters which are explicitly filtered out, and the instrument name. """ configuration = PythonJsonStructure() if self._instrument is not None: snapshot = self._instrument.snapshot(update) parameters = self._filter_parameters(snapshot['parameters']) valued_parameters = self.__notify_and_remove_none_values( parameters) configuration.update(valued_parameters) return configuration
def test_serialization_data_types(self): settable_objects = { 'none': None, 'bool': False, 'int': 25, 'float': 3.141592, 'str': 'some_string', 'bytes': b'1010101', 'np.float32': np.float32(3.1415), 'np.float64': np.float64(-3.1415), 'np.int32': np.int32(4), 'np.in64': np.int64(-4), 'np.cfloat': np.random.rand(2, 4, 5, 3).astype(np.cfloat), } for key, expected in settable_objects.items(): json_object = PythonJsonStructure({key: expected}) serialized_object = serialize(json_object) unserialized_object = unserialize(serialized_object) np.testing.assert_equal(json_object, unserialized_object)
def __init__(self, adapter_class_name: str, address: str, storage: StorageInterface, tag: Optional[List[str]] = None, configuration: Optional[PythonJsonStructure] = None, instrument_name: Optional[str] = None) -> None: """ A set of instrument configurations Args instrument_adapter_class_name: Name of the InstrumentAdapter subclass address: Address of the physical instrument storage: Any storage that implements the StorageInterface tag: A unique identifier for a instrument configuration set configuration: The instrument configuration instrument_name: User defined name for the instrument """ self._adapter_class_name = adapter_class_name self._address = address self._storage = storage self._instrument_name = instrument_name self._adapter = InstrumentAdapterFactory.get_instrument_adapter(adapter_class_name, address, instrument_name) self._configuration = PythonJsonStructure() if configuration is None else configuration self._tag = [self.STORAGE_BASE_TAG, adapter_class_name, StorageInterface.datetag_part()] if tag is None else tag
def test_metadata_triggers_update(self): name = 'Bobo' user_data = PythonJsonStructure(data='plata', snapshot=False) timestamp = datetime.datetime(2019, 12, 24) default_array_name = 'ThatsAGoodName' io_reader, io_writer = MemoryDataSetIOFactory.get_reader_writer_pair() data_set_consumer = DataSet(storage_reader=io_reader) data_set_producer = DataSet(storage_writer=io_writer) data_set_producer.name = name data_set_producer.user_data = user_data data_set_producer.time_stamp = timestamp data_set_producer.default_array_name = default_array_name data_set_consumer.sync_from_storage(-1) self.assertEqual(name, data_set_consumer.name) self.assertDictEqual(user_data, data_set_consumer.user_data) self.assertEqual(timestamp, data_set_consumer.time_stamp) self.assertEqual(default_array_name, data_set_consumer.default_array_name)