<commit_before># This is a virtual instrument abstracting a homodyne
# source which controls RF and LO sources

import logging
import numpy as np
from time import time
from qcodes.instrument.base import Instrument
from qcodes.utils import validators as vals
from qcodes.instrument.parameter import ManualParameter
# Used for uploading the right AWG sequences
from pycqed.measurement.pulse_sequences import standard_sequences as st_seqs
import time


class HeterodyneInstrument(Instrument):
    '''
    This is a virtual instrument for a homodyne source

    Instrument is CBox and UHFQC compatible

    Todo:
        - Add power settings
        - Add integration time settings
        - Build test suite
        - Add parameter Heterodyne voltage (that returns a complex value/ 2 values)
        - Add different demodulation settings.
        - Add fading plots that shows the last measured avg transients
          and points in the IQ-plane in the second window
        - Add option to use CBox integration averaging mode and verify
           identical results
    '''
    shared_kwargs = ['RF', 'LO', 'AWG']

    def __init__(self, name,  RF, LO, AWG, acquisition_instr='CBox',
                 single_sideband_demod=False, **kw):
        logging.info(__name__ + ' : Initializing instrument')
        Instrument.__init__(self, name, **kw)

        self.LO = LO
        self.RF = RF
        self.AWG = AWG

        self.add_parameter('frequency',
                           label='Heterodyne frequency',
                           units='Hz',
                           get_cmd=self.do_get_frequency,
                           set_cmd=self.do_set_frequency,
                           vals=vals.Numbers(9e3, 40e9))
        self.add_parameter('f_RO_mod', parameter_class=ManualParameter,
                           vals=vals.Numbers(-600e6, 600e6),
                           label='Intermodulation frequency',
                           units='Hz', initial_value=10e6)
        self.add_parameter('RF_power', label='RF power',
                           units='dBm',
                           set_cmd=self.do_set_RF_power,
                           get_cmd=self.do_get_RF_power)
        self.add_parameter('single_sideband_demod',
                           label='Single sideband demodulation',
                           parameter_class=ManualParameter)
        self.add_parameter('acquisition_instr',
                           set_cmd=self._do_set_acquisition_instr,
                           get_cmd=self._do_get_acquisition_instr,
                           vals=vals.Strings())
        self.add_parameter('nr_averages',
                            parameter_class=ManualParameter,
                           initial_value=1024,
                           vals=vals.Numbers(min_value=0, max_value=1e6))

        self.set('single_sideband_demod', single_sideband_demod)
        self._awg_seq_filename = 'Heterodyne_marker_seq_RF_mod'
        self._disable_auto_seq_loading = False
        self.acquisition_instr(acquisition_instr)

    def set_sources(self, status):
        self.RF.set('status', status)
        self.LO.set('status', status)

    def do_set_frequency(self, val):
        self._frequency = val
        # this is the definition agreed upon in issue 131
        self.RF.set('frequency', val)
        self.LO.set('frequency', val-self.f_RO_mod.get())

    def do_get_frequency(self):
        freq = self.RF.frequency()
        LO_freq = self.LO.frequency()
        if LO_freq != freq-self.f_RO_mod():
            logging.warning('f_RO_mod between RF and LO is not set correctly')
        return freq


    def do_set_RF_power(self, val):
        self.RF.power(val)
        self._RF_power = val
        # internally stored to allow setting RF from stored setting

    def do_get_RF_power(self):
        return self._RF_power

    def do_set_status(self, val):
        self.state = val
        if val == 'On':
            self.LO.on()
            self.RF.on()
        else:
            self.LO.off()
            self.RF.off()

    def do_get_status(self):
        if (self.LO.get('status').startswith('On')and
                self.RF.get('status').startswith('On')):
            return 'On'
        elif (self.LO.get('status').startswith('Off') and
                self.RF.get('status').startswith('Off')):
            return 'Off'
        else:
            return 'LO: %s, RF: %s' % (self.LO.get('status'),
                                       self.RF.get('status'))

    def on(self):
        self.set('status', 'On')

    def off(self):
        self.set('status', 'Off')
        return

    def prepare(self, get_t_base=True, RO_length=500e-9, trigger_separation=20e-6):
        '''
        This function needs to be overwritten for the ATS based version of this
        driver
        '''

        if ((self._awg_seq_filename not in self.AWG.get('setup_filename')) and
                not self._disable_auto_seq_loading):
            self.seq_name = st_seqs.generate_and_upload_marker_sequence(
                RO_length, trigger_separation, RF_mod=False,
                IF=self.get('f_RO_mod'), mod_amp=0.5)

        self.AWG.run()

        if get_t_base is True:
            if 'CBox' in self.acquisition_instr():
                trace_length = 512
                tbase = np.arange(0, 5*trace_length, 5)*1e-9
                self.cosI = np.floor(127.*np.cos(2*np.pi*self.get('f_RO_mod')*tbase))
                self.sinI = np.floor(127.*np.sin(2*np.pi*self.get('f_RO_mod')*tbase))
                self._acquisition_instr.sig0_integration_weights(self.cosI)
                self._acquisition_instr.sig1_integration_weights(self.sinI)
                self._acquisition_instr.set('nr_samples', 1)  # because using integrated avg
                self._acquisition_instr.nr_averages(int(self.nr_averages()))

            elif 'UHFQC' in self.acquisition_instr():
                print("f_RO_mod", self.get('f_RO_mod'))
                #self._acquisition_instr.prepare_SSB_weight_and_rotation(IF=self.get('f_RO_mod'),
                #                                        weight_function_I=0, weight_function_Q=1)
                self._acquisition_instr.prepare_DSB_weight_and_rotation(IF=self.get('f_RO_mod'),
                                                        weight_function_I=0, weight_function_Q=1)
                self._acquisition_instr.quex_rl_source(2) #this sets the result to integration and rotation outcome
                self._acquisition_instr.quex_rl_length(1) #only one sample to average over
                self._acquisition_instr.quex_rl_avgcnt(int(np.log2(self.nr_averages())))
                print("preparing UHFQ with avg", self._acquisition_instr.quex_rl_avgcnt())
                self._acquisition_instr.quex_wint_length(int(RO_length*(1.8e9)))
                # Configure the result logger to not do any averaging
                # The AWG program uses userregs/0 to define the number o iterations in the loop
                self._acquisition_instr.awgs_0_userregs_0(int(self.nr_averages()))

        self.LO.on()
        # Changes are now incorporated in the awg seq
        self._awg_seq_parameters_changed = False


        # self.CBox.set('acquisition_mode', 'idle') # aded with xiang

    def probe(self, demodulation_mode=0, **kw):
        '''
        Starts acquisition and returns the data
            'COMP' : returns data as a complex point in the I-Q plane in Volts
        '''
        if 'CBox' in self.acquisition_instr():
            t0 = time.time()
            self._acquisition_instr.set('acquisition_mode', 'idle')
            self._acquisition_instr.set('acquisition_mode', 'integration averaging')
            self._acquisition_instr.demodulation_mode(demodulation_mode)
            # d = self.CBox.get_integrated_avg_results()
            # quick fix for spec units. Need to properrly implement it later
            # after this, output is in mV
            scale_factor_dacmV = 1000.*0.75/128.
            # scale_factor_integration = 1./float(self.f_RO_mod()*self.CBox.nr_samples()*5e-9)
            scale_factor_integration = 1./(64.*self._acquisition_instr.integration_length())
            factor = scale_factor_dacmV*scale_factor_integration
            d = np.double(self._acquisition_instr.get_integrated_avg_results())*np.double(factor)
            # print(np.size(d))
            dat = d[0][0]+1j*d[1][0]
            t1 = time.time()
            print("time for CBox polling", t1-t0)
        elif 'UHFQC' in self.acquisition_instr():
            t0 = time.time()
            self._acquisition_instr.awgs_0_single(1)
            self._acquisition_instr.awgs_0_enable(1)
            temp = self._acquisition_instr.awgs_0_enable()  #probing the values to be sure communication is finished before starting AWG
            temp = self._acquisition_instr.awgs_0_single()
            del temp
            # self.AWG.start()

            while self._acquisition_instr.awgs_0_enable() == 1:
                time.sleep(0.01)
            time.sleep(0.2)
            channels=[0,1]
            data = ['']*len(channels)
            for i, channel in enumerate(channels):
                dataset = eval("self._acquisition_instr.quex_rl_data_{}()".format(channel))
                data[i] = dataset[0]['vector']
            print(np.size(data))
            dat=data[0]+1j*data[1]
            t1 = time.time()
            print("time for UHFQC polling", t1-t0)
        return dat


        # return s21

    def get_demod_array(self):
        return self.cosI, self.sinI<commit_msg>hs minor update<commit_after># This is a virtual instrument abstracting a homodyne
# source which controls RF and LO sources

import logging
import numpy as np
from time import time
from qcodes.instrument.base import Instrument
from qcodes.utils import validators as vals
from qcodes.instrument.parameter import ManualParameter
# Used for uploading the right AWG sequences
from pycqed.measurement.pulse_sequences import standard_sequences as st_seqs
import time


class HeterodyneInstrument(Instrument):
    '''
    This is a virtual instrument for a homodyne source

    Instrument is CBox and UHFQC compatible

    Todo:
        - Add power settings
        - Add integration time settings
        - Build test suite
        - Add parameter Heterodyne voltage (that returns a complex value/ 2 values)
        - Add different demodulation settings.
        - Add fading plots that shows the last measured avg transients
          and points in the IQ-plane in the second window
        - Add option to use CBox integration averaging mode and verify
           identical results
    '''
    shared_kwargs = ['RF', 'LO', 'AWG']

    def __init__(self, name,  RF, LO, AWG, acquisition_instr='CBox',
                 single_sideband_demod=False, **kw):
        logging.info(__name__ + ' : Initializing instrument')
        Instrument.__init__(self, name, **kw)

        self.LO = LO
        self.RF = RF
        self.AWG = AWG

        self.add_parameter('frequency',
                           label='Heterodyne frequency',
                           units='Hz',
                           get_cmd=self.do_get_frequency,
                           set_cmd=self.do_set_frequency,
                           vals=vals.Numbers(9e3, 40e9))
        self.add_parameter('f_RO_mod', parameter_class=ManualParameter,
                           vals=vals.Numbers(-600e6, 600e6),
                           label='Intermodulation frequency',
                           units='Hz', initial_value=10e6)
        self.add_parameter('RF_power', label='RF power',
                           units='dBm',
                           set_cmd=self.do_set_RF_power,
                           get_cmd=self.do_get_RF_power)
        self.add_parameter('single_sideband_demod',
                           label='Single sideband demodulation',
                           parameter_class=ManualParameter)
        self.add_parameter('acquisition_instr',
                           set_cmd=self._do_set_acquisition_instr,
                           get_cmd=self._do_get_acquisition_instr,
                           vals=vals.Strings())
        self.add_parameter('nr_averages',
                            parameter_class=ManualParameter,
                           initial_value=1024,
                           vals=vals.Numbers(min_value=0, max_value=1e6))

        self.set('single_sideband_demod', single_sideband_demod)
        self._awg_seq_filename = 'Heterodyne_marker_seq_RF_mod'
        self._disable_auto_seq_loading = False
        self.acquisition_instr(acquisition_instr)

    def set_sources(self, status):
        self.RF.set('status', status)
        self.LO.set('status', status)

    def do_set_frequency(self, val):
        self._frequency = val
        # this is the definition agreed upon in issue 131
        self.RF.set('frequency', val)
        self.LO.set('frequency', val-self.f_RO_mod.get())

    def do_get_frequency(self):
        freq = self.RF.frequency()
        LO_freq = self.LO.frequency()
        if LO_freq != freq-self.f_RO_mod():
            logging.warning('f_RO_mod between RF and LO is not set correctly')
        return freq


    def do_set_RF_power(self, val):
        self.RF.power(val)
        self._RF_power = val
        # internally stored to allow setting RF from stored setting

    def do_get_RF_power(self):
        return self._RF_power

    def do_set_status(self, val):
        self.state = val
        if val == 'On':
            self.LO.on()
            self.RF.on()
        else:
            self.LO.off()
            self.RF.off()

    def do_get_status(self):
        if (self.LO.get('status').startswith('On')and
                self.RF.get('status').startswith('On')):
            return 'On'
        elif (self.LO.get('status').startswith('Off') and
                self.RF.get('status').startswith('Off')):
            return 'Off'
        else:
            return 'LO: %s, RF: %s' % (self.LO.get('status'),
                                       self.RF.get('status'))

    def on(self):
        self.set('status', 'On')

    def off(self):
        self.set('status', 'Off')
        return

    def prepare(self, get_t_base=True, RO_length=500e-9, trigger_separation=20e-6):
        '''
        This function needs to be overwritten for the ATS based version of this
        driver
        '''

        if ((self._awg_seq_filename not in self.AWG.get('setup_filename')) and
                not self._disable_auto_seq_loading):
            self.seq_name = st_seqs.generate_and_upload_marker_sequence(
                RO_length, trigger_separation, RF_mod=False,
                IF=self.get('f_RO_mod'), mod_amp=0.5)

        self.AWG.run()

        if get_t_base is True:
            if 'CBox' in self.acquisition_instr():
                trace_length = 512
                tbase = np.arange(0, 5*trace_length, 5)*1e-9
                self.cosI = np.floor(127.*np.cos(2*np.pi*self.get('f_RO_mod')*tbase))
                self.sinI = np.floor(127.*np.sin(2*np.pi*self.get('f_RO_mod')*tbase))
                self._acquisition_instr.sig0_integration_weights(self.cosI)
                self._acquisition_instr.sig1_integration_weights(self.sinI)
                self._acquisition_instr.set('nr_samples', 1)  # because using integrated avg
                self._acquisition_instr.nr_averages(int(self.nr_averages()))

            elif 'UHFQC' in self.acquisition_instr():
                print("f_RO_mod", self.get('f_RO_mod'))
                #self._acquisition_instr.prepare_SSB_weight_and_rotation(IF=self.get('f_RO_mod'),
                #                                        weight_function_I=0, weight_function_Q=1)
                self._acquisition_instr.prepare_DSB_weight_and_rotation(IF=self.get('f_RO_mod'),
                                                        weight_function_I=0, weight_function_Q=1)
                self._acquisition_instr.quex_rl_source(2) #this sets the result to integration and rotation outcome
                self._acquisition_instr.quex_rl_length(1) #only one sample to average over
                self._acquisition_instr.quex_rl_avgcnt(int(np.log2(self.nr_averages())))
                print("preparing UHFQ with avg", self._acquisition_instr.quex_rl_avgcnt())
                self._acquisition_instr.quex_wint_length(int(RO_length*(1.8e9)))
                # Configure the result logger to not do any averaging
                # The AWG program uses userregs/0 to define the number o iterations in the loop
                self._acquisition_instr.awgs_0_userregs_0(int(self.nr_averages()))

        self.LO.on()
        # Changes are now incorporated in the awg seq
        self._awg_seq_parameters_changed = False


        # self.CBox.set('acquisition_mode', 'idle') # aded with xiang

    def probe(self, demodulation_mode=0, **kw):
        '''
        Starts acquisition and returns the data
            'COMP' : returns data as a complex point in the I-Q plane in Volts
        '''
        if 'CBox' in self.acquisition_instr():
            self._acquisition_instr.set('acquisition_mode', 'idle')
            self._acquisition_instr.set('acquisition_mode', 'integration averaging')
            self._acquisition_instr.demodulation_mode(demodulation_mode)
            # d = self.CBox.get_integrated_avg_results()
            # quick fix for spec units. Need to properrly implement it later
            # after this, output is in mV
            scale_factor_dacmV = 1000.*0.75/128.
            # scale_factor_integration = 1./float(self.f_RO_mod()*self.CBox.nr_samples()*5e-9)
            scale_factor_integration = 1./(64.*self._acquisition_instr.integration_length())
            factor = scale_factor_dacmV*scale_factor_integration
            d = np.double(self._acquisition_instr.get_integrated_avg_results())*np.double(factor)
            # print(np.size(d))
            dat = d[0][0]+1j*d[1][0]
        elif 'UHFQC' in self.acquisition_instr():
            t0 = time.time()
            self._acquisition_instr.awgs_0_single(1)
            self._acquisition_instr.awgs_0_enable(1)
            temp = self._acquisition_instr.awgs_0_enable()  #probing the values to be sure communication is finished before starting AWG
            temp = self._acquisition_instr.awgs_0_single()
            del temp
            # self.AWG.start()

            while self._acquisition_instr.awgs_0_enable() == 1:
                time.sleep(0.01)
            time.sleep(0.2)
            channels=[0,1]
            data = ['']*len(channels)
            for i, channel in enumerate(channels):
                dataset = eval("self._acquisition_instr.quex_rl_data_{}()".format(channel))
                data[i] = dataset[0]['vector']
            print(np.size(data))
            dat=data[0]+1j*data[1]
            t1 = time.time()
            print("time for UHFQC polling", t1-t0)
        return dat


        # return s21

    def get_demod_array(self):
        return self.cosI, self.sinI
{'fraction_non_alphanumeric': 0.09663512092534174, 'fraction_numerical': 0.012302839116719243, 'mean_word_length': 2.0370429506626215, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1367882', 'n_tokens_mistral': 5836, 'n_tokens_neox': 5466, 'n_words': 1148}