Example #1
0
    def get_constraints(self):
        """
        Retrieve the hardware constrains from the Pulsing device.

        @return constraints object: object with pulser constraints as attributes.

        Provides all the constraints (e.g. sample_rate, amplitude, total_length_bins,
        channel_config, ...) related to the pulse generator hardware to the caller.

            SEE PulserConstraints CLASS IN pulser_interface.py FOR AVAILABLE CONSTRAINTS!!!

        If you are not sure about the meaning, look in other hardware files to get an impression.
        If still additional constraints are needed, then they have to be added to the
        PulserConstraints class.

        Each scalar parameter is an ScalarConstraints object defined in cor.util.interfaces.
        Essentially it contains min/max values as well as min step size, default value and unit of
        the parameter.

        PulserConstraints.activation_config differs, since it contain the channel
        configuration/activation information of the form:
            {<descriptor_str>: <channel_set>,
             <descriptor_str>: <channel_set>,
             ...}

        If the constraints cannot be set in the pulsing hardware (e.g. because it might have no
        sequence mode) just leave it out so that the default is used (only zeros).
        """
        constraints = PulserConstraints()

        if self.interleave:
            constraints.sample_rate.min = 12.0e9
            constraints.sample_rate.max = 24.0e9
            constraints.sample_rate.step = 4.0e8
            constraints.sample_rate.default = 24.0e9
        else:
            constraints.sample_rate.min = 10.0e6
            constraints.sample_rate.max = 12.0e9
            constraints.sample_rate.step = 10.0e6
            constraints.sample_rate.default = 12.0e9

        constraints.a_ch_amplitude.min = 0.02
        constraints.a_ch_amplitude.max = 2.0
        constraints.a_ch_amplitude.step = 0.001
        constraints.a_ch_amplitude.default = 2.0

        constraints.a_ch_offset.min = -1.0
        constraints.a_ch_offset.max = 1.0
        constraints.a_ch_offset.step = 0.001
        constraints.a_ch_offset.default = 0.0

        constraints.d_ch_low.min = -1.0
        constraints.d_ch_low.max = 4.0
        constraints.d_ch_low.step = 0.01
        constraints.d_ch_low.default = 0.0

        constraints.d_ch_high.min = 0.0
        constraints.d_ch_high.max = 5.0
        constraints.d_ch_high.step = 0.01
        constraints.d_ch_high.default = 5.0

        constraints.waveform_length.min = 80
        constraints.waveform_length.max = 64800000
        constraints.waveform_length.step = 1
        constraints.waveform_length.default = 80

        constraints.waveform_num.min = 1
        constraints.waveform_num.max = 32000
        constraints.waveform_num.step = 1
        constraints.waveform_num.default = 1

        constraints.sequence_num.min = 1
        constraints.sequence_num.max = 8000
        constraints.sequence_num.step = 1
        constraints.sequence_num.default = 1

        constraints.subsequence_num.min = 1
        constraints.subsequence_num.max = 4000
        constraints.subsequence_num.step = 1
        constraints.subsequence_num.default = 1

        # If sequencer mode is available then these should be specified
        constraints.repetitions.min = 0
        constraints.repetitions.max = 65539
        constraints.repetitions.step = 1
        constraints.repetitions.default = 0

        constraints.event_triggers = ['A', 'B']
        constraints.flags = ['A', 'B', 'C', 'D']

        constraints.sequence_steps.min = 0
        constraints.sequence_steps.max = 8000
        constraints.sequence_steps.step = 1
        constraints.sequence_steps.default = 0

        # the name a_ch<num> and d_ch<num> are generic names, which describe UNAMBIGUOUSLY the
        # channels. Here all possible channel configurations are stated, where only the generic
        # names should be used. The names for the different configurations can be customary chosen.
        activation_config = OrderedDict()
        activation_config['config0'] = frozenset(
            {'a_ch1', 'd_ch1', 'd_ch2', 'a_ch2', 'd_ch3', 'd_ch4'})
        activation_config['config1'] = frozenset(
            {'a_ch2', 'd_ch1', 'd_ch2', 'a_ch3', 'd_ch3', 'd_ch4'})
        # Usage of channel 1 only:
        activation_config['config2'] = frozenset({'a_ch2', 'd_ch1', 'd_ch2'})
        # Usage of channel 2 only:
        activation_config['config3'] = frozenset({'a_ch3', 'd_ch3', 'd_ch4'})
        # Usage of Interleave mode:
        activation_config['config4'] = frozenset({'a_ch1', 'd_ch1', 'd_ch2'})
        # Usage of only digital channels:
        activation_config['config5'] = frozenset(
            {'d_ch1', 'd_ch2', 'd_ch3', 'd_ch4', 'd_ch5', 'd_ch6', 'd_ch7', 'd_ch8'})
        # Usage of only one analog channel:
        activation_config['config6'] = frozenset({'a_ch1'})
        activation_config['config7'] = frozenset({'a_ch2'})
        activation_config['config8'] = frozenset({'a_ch3'})
        # Usage of only the analog channels:
        activation_config['config9'] = frozenset({'a_ch2', 'a_ch3'})
        constraints.activation_config = activation_config

        constraints.sequence_option = SequenceOption.FORCED if self.force_sequence_option else SequenceOption.OPTIONAL

        return constraints
Example #2
0
    def on_activate(self):
        self.analog_amplitudes = {}
        self.analog_offsets = {}
        # loaded sequence
        self.last_sequence = None
        # loaded waveforms, channel -> waveform name
        self.loaded_waveforms = {}
        # uploaded waveforms, waveform name -> instrument wfm number
        self.written_waveforms = {}

        self.chcfg = {
            'a_ch1': M3202ChannelCfg(),
            'a_ch2': M3202ChannelCfg(),
            'a_ch3': M3202ChannelCfg(),
            'a_ch4': M3202ChannelCfg(),
        }

        constraints = PulserConstraints()

        constraints.sample_rate.min = 4e8
        constraints.sample_rate.max = 1e9
        constraints.sample_rate.step = 1.0
        constraints.sample_rate.default = 1e9

        constraints.a_ch_amplitude.min = 0
        constraints.a_ch_amplitude.max = 1.5
        constraints.a_ch_amplitude.step = 0.01
        constraints.a_ch_amplitude.default = 1.5
        constraints.a_ch_offset.min = 0
        constraints.a_ch_offset.max = 1.5
        constraints.a_ch_offset.step = 0.01
        constraints.a_ch_offset.default = 0.0
        # FIXME: Enter the proper digital channel low constraints:
        constraints.d_ch_low.min = 0.0
        constraints.d_ch_low.max = 0.0
        constraints.d_ch_low.step = 0.0
        constraints.d_ch_low.default = 0.0
        # FIXME: Enter the proper digital channel high constraints:
        constraints.d_ch_high.min = 0.0
        constraints.d_ch_high.max = 0.0
        constraints.d_ch_high.step = 0.0
        constraints.d_ch_high.default = 0.0

        constraints.waveform_length.min = 30
        constraints.waveform_length.max = 1e9
        constraints.waveform_length.step = 10
        constraints.waveform_length.default = 1000

        # FIXME: Check the proper number for your device
        constraints.waveform_num.min = 1
        constraints.waveform_num.max = 1024
        constraints.waveform_num.step = 1
        constraints.waveform_num.default = 1
        # FIXME: Check the proper number for your device
        constraints.sequence_num.min = 1
        constraints.sequence_num.max = 1
        constraints.sequence_num.step = 1
        constraints.sequence_num.default = 1
        # FIXME: Check the proper number for your device
        constraints.subsequence_num.min = 0
        constraints.subsequence_num.max = 0
        constraints.subsequence_num.step = 0
        constraints.subsequence_num.default = 0

        # If sequencer mode is available then these should be specified
        constraints.repetitions.min = 0
        constraints.repetitions.max = 65536
        constraints.repetitions.step = 1
        constraints.repetitions.default = 0
        # ToDo: Check how many external triggers are available
        constraints.event_triggers = ['SOFT', 'EXT', 'SOFT_CYCLE', 'EXT_CYCLE']
        constraints.flags = []

        constraints.sequence_steps.min = 1
        constraints.sequence_steps.max = 1024
        constraints.sequence_steps.step = 1
        constraints.sequence_steps.default = 1

        activation_config = OrderedDict()
        activation_config['all'] = frozenset({'a_ch1', 'a_ch2', 'a_ch3', 'a_ch4'})
        activation_config['one'] = frozenset({'a_ch1'})
        activation_config['two'] = frozenset({'a_ch1', 'a_ch2'})
        activation_config['three'] = frozenset({'a_ch1', 'a_ch2', 'a_ch3'})
        constraints.activation_config = activation_config
        # FIXME: additional constraint really necessary?
        constraints.dac_resolution = {'min': 14, 'max': 14, 'step': 1, 'unit': 'bit'}
        constraints.sequence_option = SequenceOption.FORCED

        self._constraints = constraints

        self.awg = ksd1.SD_AOU()
        aouID = self.awg.openWithSerialNumberCompatibility(
            'M3202A', self.serial, ksd1.SD_Compatibility.KEYSIGHT)

        # Check AWG Connection for errors
        if aouID < 0:
            self.awg.close()
            raise Exception('AWG Error: {0} {1}'.format(aouID, ksd1.SD_Error.getErrorMessage(aouID)))

        self.ser = self.awg.getSerialNumber()
        self.model = self.awg.getProductName()
        self.fwver = self.awg.getFirmwareVersion()
        self.hwver = self.awg.getHardwareVersion()
        self.chassis = self.awg.getChassis()
        self.ch_slot = self.awg.getSlot()

        self.reset()

        self.log.info('Keysight AWG Model: {} serial: {} '
                      'FW Ver: {} HW Ver: {} Chassis: {} Slot: {}'
                      ''.format(self.model, self.ser, self.fwver, self.hwver, self.chassis,
                                self.ch_slot))
Example #3
0
    def get_constraints(self):
        """
        Retrieve the hardware constrains from the Pulsing device.

        @return constraints object: object with pulser constraints as attributes.

        Provides all the constraints (e.g. sample_rate, amplitude, total_length_bins,
        channel_config, ...) related to the pulse generator hardware to the caller.

            SEE PulserConstraints CLASS IN pulser_interface.py FOR AVAILABLE CONSTRAINTS!!!

        If you are not sure about the meaning, look in other hardware files to get an impression.
        If still additional constraints are needed, then they have to be added to the
        PulserConstraints class.

        Each scalar parameter is an ScalarConstraints object defined in cor.util.interfaces.
        Essentially it contains min/max values as well as min step size, default value and unit of
        the parameter.

        PulserConstraints.activation_config differs, since it contain the channel
        configuration/activation information of the form:
            {<descriptor_str>: <channel_list>,
             <descriptor_str>: <channel_list>,
             ...}

        If the constraints cannot be set in the pulsing hardware (e.g. because it might have no
        sequence mode) just leave it out so that the default is used (only zeros).
        """
        # Example for configuration with default values:
        constraints = PulserConstraints()

        constraints.sample_rate.min = 50e3
        constraints.sample_rate.max = 3.35e9
        constraints.sample_rate.step = 1e3
        constraints.sample_rate.default = 12.0e9

        constraints.a_ch_amplitude.min = 0.0
        constraints.a_ch_amplitude.max = 0.0
        constraints.a_ch_amplitude.step = 0.0
        constraints.a_ch_amplitude.default = 0.0

        constraints.a_ch_offset.min = 0.0
        constraints.a_ch_offset.max = 0.0
        constraints.a_ch_offset.step = 0.0
        constraints.a_ch_offset.default = 0.0

        constraints.d_ch_low.min = -2.0
        constraints.d_ch_low.max = 2.44
        constraints.d_ch_low.step = 0.05
        constraints.d_ch_low.default = 0.0

        constraints.d_ch_high.min = -1.0
        constraints.d_ch_high.max = 2.47
        constraints.d_ch_high.step = 0.05
        constraints.d_ch_high.default = 2.4

        constraints.waveform_length.min = 80
        constraints.waveform_length.max = 64800000
        constraints.waveform_length.step = 1
        constraints.waveform_length.default = 80

        constraints.waveform_num.min = 1
        constraints.waveform_num.max = 32000
        constraints.waveform_num.step = 1
        constraints.waveform_num.default = 1

        constraints.sequence_num.min = 1
        constraints.sequence_num.max = 8000
        constraints.sequence_num.step = 1
        constraints.sequence_num.default = 1

        constraints.subsequence_num.min = 1
        constraints.subsequence_num.max = 4000
        constraints.subsequence_num.step = 1
        constraints.subsequence_num.default = 1

        # If sequencer mode is available then these should be specified
        constraints.repetitions.min = 0
        constraints.repetitions.max = 65539
        constraints.repetitions.step = 1
        constraints.repetitions.default = 0

        constraints.event_triggers = ['A', 'B']
        constraints.flags = list()

        constraints.sequence_steps.min = 0
        constraints.sequence_steps.max = 8000
        constraints.sequence_steps.step = 1
        constraints.sequence_steps.default = 0

        # the name a_ch<num> and d_ch<num> are generic names, which describe UNAMBIGUOUSLY the
        # channels. Here all possible channel configurations are stated, where only the generic
        # names should be used. The names for the different configurations can be customary chosen.
        activation_conf = OrderedDict()
        activation_conf['A'] = {'d_ch1', 'd_ch2'}
        activation_conf['B'] = {'d_ch3', 'd_ch4'}
        activation_conf['C'] = {'d_ch5', 'd_ch6'}
        activation_conf['D'] = {'d_ch7', 'd_ch8'}
        activation_conf['AB'] = {'d_ch1', 'd_ch2', 'd_ch3', 'd_ch4'}
        activation_conf['ABC'] = {'d_ch1', 'd_ch2', 'd_ch3', 'd_ch4', 'd_ch5', 'd_ch6'}
        activation_conf['all'] = {
            'd_ch1', 'd_ch2', 'd_ch3', 'd_ch4', 'd_ch5', 'd_ch6', 'd_ch7', 'd_ch8'
        }
        constraints.activation_config = activation_conf
        return constraints
Example #4
0
    def get_constraints(self):
        """
        Retrieve the hardware constrains from the Pulsing device.

        @return constraints object: object with pulser constraints as attributes.

        Provides all the constraints (e.g. sample_rate, amplitude, total_length_bins,
        channel_config, ...) related to the pulse generator hardware to the caller.

            SEE PulserConstraints CLASS IN pulser_interface.py FOR AVAILABLE CONSTRAINTS!!!

        If you are not sure about the meaning, look in other hardware files to get an impression.
        If still additional constraints are needed, then they have to be added to the
        PulserConstraints class.

        Each scalar parameter is an ScalarConstraints object defined in cor.util.interfaces.
        Essentially it contains min/max values as well as min step size, default value and unit of
        the parameter.

        PulserConstraints.activation_config differs, since it contain the channel
        configuration/activation information of the form:
            {<descriptor_str>: <channel_list>,
             <descriptor_str>: <channel_list>,
             ...}

        If the constraints cannot be set in the pulsing hardware (e.g. because it might have no
        sequence mode) just leave it out so that the default is used (only zeros).
        """
        # Example for configuration with default values:
        constraints = PulserConstraints()

        constraints.sample_rate.min = 50e3
        constraints.sample_rate.max = 3.35e9
        constraints.sample_rate.step = 1e3
        constraints.sample_rate.default = 12.0e9

        constraints.a_ch_amplitude.min = 0.0
        constraints.a_ch_amplitude.max = 0.0
        constraints.a_ch_amplitude.step = 0.0
        constraints.a_ch_amplitude.default = 0.0

        constraints.a_ch_offset.min = 0.0
        constraints.a_ch_offset.max = 0.0
        constraints.a_ch_offset.step = 0.0
        constraints.a_ch_offset.default = 0.0

        constraints.d_ch_low.min = -2.0
        constraints.d_ch_low.max = 2.44
        constraints.d_ch_low.step = 0.05
        constraints.d_ch_low.default = 0.0

        constraints.d_ch_high.min = -1.0
        constraints.d_ch_high.max = 2.47
        constraints.d_ch_high.step = 0.05
        constraints.d_ch_high.default = 2.4

        constraints.waveform_length.min = 80
        constraints.waveform_length.max = 64800000
        constraints.waveform_length.step = 1
        constraints.waveform_length.default = 80

        constraints.waveform_num.min = 1
        constraints.waveform_num.max = 32000
        constraints.waveform_num.step = 1
        constraints.waveform_num.default = 1

        constraints.sequence_num.min = 1
        constraints.sequence_num.max = 8000
        constraints.sequence_num.step = 1
        constraints.sequence_num.default = 1

        constraints.subsequence_num.min = 1
        constraints.subsequence_num.max = 4000
        constraints.subsequence_num.step = 1
        constraints.subsequence_num.default = 1

        # If sequencer mode is available then these should be specified
        constraints.repetitions.min = 0
        constraints.repetitions.max = 65539
        constraints.repetitions.step = 1
        constraints.repetitions.default = 0

        constraints.event_triggers = ['A', 'B']
        constraints.flags = list()

        constraints.sequence_steps.min = 0
        constraints.sequence_steps.max = 8000
        constraints.sequence_steps.step = 1
        constraints.sequence_steps.default = 0

        # the name a_ch<num> and d_ch<num> are generic names, which describe UNAMBIGUOUSLY the
        # channels. Here all possible channel configurations are stated, where only the generic
        # names should be used. The names for the different configurations can be customary chosen.
        activation_conf = OrderedDict()
        activation_conf['A'] = {'d_ch1', 'd_ch2'}
        activation_conf['B'] = {'d_ch3', 'd_ch4'}
        activation_conf['C'] = {'d_ch5', 'd_ch6'}
        activation_conf['D'] = {'d_ch7', 'd_ch8'}
        activation_conf['AB'] = {'d_ch1', 'd_ch2', 'd_ch3', 'd_ch4'}
        activation_conf['ABC'] = {
            'd_ch1', 'd_ch2', 'd_ch3', 'd_ch4', 'd_ch5', 'd_ch6'
        }
        activation_conf['all'] = {
            'd_ch1', 'd_ch2', 'd_ch3', 'd_ch4', 'd_ch5', 'd_ch6', 'd_ch7',
            'd_ch8'
        }
        constraints.activation_config = activation_conf
        return constraints
Example #5
0
    def on_activate(self):
        self.analog_amplitudes = {}
        self.analog_offsets = {}
        # loaded sequence
        self.last_sequence = None
        # loaded waveforms, channel -> waveform name
        self.loaded_waveforms = {}
        # uploaded waveforms, waveform name -> instrument wfm number
        self.written_waveforms = {}

        self.chcfg = {
            'a_ch1': M3202ChannelCfg(),
            'a_ch2': M3202ChannelCfg(),
            'a_ch3': M3202ChannelCfg(),
            'a_ch4': M3202ChannelCfg(),
        }

        constraints = PulserConstraints()

        constraints.sample_rate.min = 4e8
        constraints.sample_rate.max = 1e9
        constraints.sample_rate.step = 1.0
        constraints.sample_rate.default = 1e9

        constraints.a_ch_amplitude.min = 0
        constraints.a_ch_amplitude.max = 1.5
        constraints.a_ch_amplitude.step = 0.01
        constraints.a_ch_amplitude.default = 1.5
        constraints.a_ch_offset.min = 0
        constraints.a_ch_offset.max = 1.5
        constraints.a_ch_offset.step = 0.01
        constraints.a_ch_offset.default = 0.0
        # FIXME: Enter the proper digital channel low constraints:
        constraints.d_ch_low.min = 0.0
        constraints.d_ch_low.max = 0.0
        constraints.d_ch_low.step = 0.0
        constraints.d_ch_low.default = 0.0
        # FIXME: Enter the proper digital channel high constraints:
        constraints.d_ch_high.min = 0.0
        constraints.d_ch_high.max = 0.0
        constraints.d_ch_high.step = 0.0
        constraints.d_ch_high.default = 0.0

        constraints.waveform_length.min = 30
        constraints.waveform_length.max = 1e9
        constraints.waveform_length.step = 10
        constraints.waveform_length.default = 1000

        # FIXME: Check the proper number for your device
        constraints.waveform_num.min = 1
        constraints.waveform_num.max = 1024
        constraints.waveform_num.step = 1
        constraints.waveform_num.default = 1
        # FIXME: Check the proper number for your device
        constraints.sequence_num.min = 1
        constraints.sequence_num.max = 1
        constraints.sequence_num.step = 1
        constraints.sequence_num.default = 1
        # FIXME: Check the proper number for your device
        constraints.subsequence_num.min = 0
        constraints.subsequence_num.max = 0
        constraints.subsequence_num.step = 0
        constraints.subsequence_num.default = 0

        # If sequencer mode is available then these should be specified
        constraints.repetitions.min = 0
        constraints.repetitions.max = 65536
        constraints.repetitions.step = 1
        constraints.repetitions.default = 0
        # ToDo: Check how many external triggers are available
        constraints.event_triggers = ['EXT', 'CYCLE']
        constraints.flags = []

        constraints.sequence_steps.min = 1
        constraints.sequence_steps.max = 1024
        constraints.sequence_steps.step = 1
        constraints.sequence_steps.default = 1

        activation_config = OrderedDict()
        activation_config['all'] = {'a_ch1', 'a_ch2', 'a_ch3', 'a_ch4'}
        constraints.activation_config = activation_config
        # FIXME: additional constraint really necessary?
        constraints.dac_resolution = {'min': 14, 'max': 14, 'step': 1, 'unit': 'bit'}
        self._constraints = constraints

        self.awg = ksd1.SD_AOU()
        aouID = self.awg.openWithSerialNumberCompatibility(
            'M3202A', self.serial, ksd1.SD_Compatibility.KEYSIGHT)

        # Check AWG Connection for errors
        if aouID < 0:
            self.awg.close()
            raise Exception('AWG Error: {0} {1}'.format(aouID, ksd1.SD_Error.getErrorMessage(aouID)))

        self.ser = self.awg.getSerialNumber()
        self.model = self.awg.getProductName()
        self.fwver = self.awg.getFirmwareVersion()
        self.hwver = self.awg.getHardwareVersion()
        self.chassis = self.awg.getChassis()
        self.ch_slot = self.awg.getSlot()

        self.reset()

        self.log.info('Keysight AWG Model: {} serial: {} '
                      'FW Ver: {} HW Ver: {} Chassis: {} Slot: {}'
                      ''.format(self.model, self.ser, self.fwver, self.hwver, self.chassis,
                                self.ch_slot))