コード例 #1
0
    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
コード例 #2
0
    def apply(self, config: PythonJsonStructure) -> None:
        """ Applies configuration

        1. Apply configuration update for step, inter_delay.
        2. Apply configuration update for unit of dac parameters based on dac1 unit.
        3. Compares rest of the configuration values with setter command, to existing values and raises
           error in case of mismatch.

        Args:
            config: Containing the instrument configuration.

        """
        unit = config['dac1']['unit']
        self._instrument.set_dac_unit(unit)
        dac_parameters = {
            param: values
            for param, values in config.items() if param[0:3] == 'dac'
        }
        for dac, values in dac_parameters.items():
            self._instrument[dac].step = values['step']
            self._instrument[dac].inter_delay = values['inter_delay']
        super().apply(config)
コード例 #3
0
 def _filter_parameters(self, parameters: PythonJsonStructure) -> PythonJsonStructure:
     filter_items = ['_elf_data', '_waveform_descriptors', '_sequencer_program', '_sequencer_assembly', '_elf_name',
                     '_dio_data', '_waveform_waves_', 'system_nics_', 'triggers_streams_', 'features_code']
     filtered = {parameter: value for (parameter, value) in parameters.items()
                 if all(filter not in parameter for filter in filter_items)}
     return PythonJsonStructure(filtered)
コード例 #4
0
class InstrumentConfiguration:
    """ Associates a configuration with an InstrumentAdapter and allows it to be stored or retrieved from storage."""

    STORAGE_BASE_TAG = 'configuration'

    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 __repr__(self):
        repr_string = f'{self.__class__.__name__}({self._adapter_class_name!r}, {self._address!r}, {self._storage!r}, '\
            f'{self._tag!r}, {self._configuration!r}, {self._instrument_name!r})'
        return repr_string

    @property
    def tag(self) -> List[str]:
        """ A unique identifier for this instrument configuration set """
        return self._tag

    @property
    def storage(self) -> StorageInterface:
        """ The storage interface used """
        return self._storage

    @property
    def address(self) -> str:
        """ The address of the physical instrument """
        return self._address

    @property
    def configuration(self) -> PythonJsonStructure:
        """ The instrument configuration """
        return self._configuration

    @staticmethod
    def load(tag: List[str], storage: StorageInterface) -> 'InstrumentConfiguration':
        """ A factory that creates a new InstrumentConfiguration by loading from database.

        Args:
            tag: A unique identifier for a instrument configuration.
            storage: Default mongo database, but can optionally be any storage that implements the StorageInterface.

        Returns:
            A new InstrumentConfiguration loaded from database.

        """
        document = storage.load_data(tag)
        adapter_class_name = document['adapter_class_name']
        address = document['address']
        instrument_name = document.get('instrument_name', None)
        configuration = document['configuration']
        return InstrumentConfiguration(adapter_class_name, address, storage, tag, configuration, instrument_name)

    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 apply(self) -> None:
        """ Uploads the configuration to the instrument."""
        self._adapter.apply(self._configuration)

    def apply_delta(self, update: bool = True) -> None:
        """ Compare configuration with instrument and apply configuration that differs.

        Args:
            update: If True, request all parameter values from instrument, else use latest set values.

        """
        instrument_config = self._adapter.read(update=update)
        delta = self._get_configuration_delta(instrument_config)
        self._adapter.apply(delta)

    def _get_configuration_delta(self, instrument_config: PythonJsonStructure) -> PythonJsonStructure:
        delta = PythonJsonStructure()
        for parameter, configuration in self._configuration.items():
            if 'value' in configuration and configuration['value'] != instrument_config[parameter]['value']:
                delta[parameter] = configuration
        return delta

    def apply_delta_lazy(self) -> None:
        """ Compare configuration with instrument driver last known settings and apply configuration that differs."""
        self.apply_delta(update=False)

    def refresh(self) -> None:
        """ Read the settings from the instrument and updated configuration.

        If the settings read from the instrument differs from the configuration the tag is also updated.
        """
        instrument_config = self._adapter.read(update=True)
        delta = self._get_configuration_delta(instrument_config)
        if len(delta) > 0 or len(instrument_config) != len(self._configuration):
            self._configuration = instrument_config
            self._tag = [self.STORAGE_BASE_TAG, self._adapter_class_name, StorageInterface.datetag_part()]

    def accept(self, visitor: Visitor) -> None:
        """ Accept a visitor, run visit method with self as a parameter and propagate to instrument adapter.

        Args:
            visitor: An implementation of the Visitor interface.

        """
        visitor.visit(self)
        self._adapter.accept(visitor)