diff --git a/pycqed/instrument_drivers/meta_instrument/heterodyne.py b/pycqed/instrument_drivers/meta_instrument/heterodyne.py index 200cd24585..a19f62da28 100644 --- a/pycqed/instrument_drivers/meta_instrument/heterodyne.py +++ b/pycqed/instrument_drivers/meta_instrument/heterodyne.py @@ -196,6 +196,17 @@ def prepare(self, get_t_base=True, RO_length=2274e-9, trigger_separation=10e-6): allocated_buffers=buffers_per_acquisition, buffer_timeout=1000) + elif 'DDM' in self.acquisition_instr(): + + for i, channel in enumerate([1,2]): + eval("self._acquisition_instr.ch_pair1_weight{}_wint_intlength({})".format(channel, RO_length*500e6)) + self._acquisition_instr.ch_pair1_tvmode_naverages(self.nr_averages()) + self._acquisition_instr.ch_pair1_tvmode_nsegments(1) + self.scale_factor=1/(500e6*RO_length)/127 + + + + self.LO.on() # Changes are now incorporated in the awg seq @@ -230,6 +241,7 @@ def probe(self, demodulation_mode='double', **kw): dat = d[0][0]+1j*d[1][0] elif 'UHFQC' in self.acquisition_instr(): t0 = time.time() +<<<<<<< HEAD self._acquisition_instr.awgs_0_enable(1) try: temp = self._acquisition_instr.awgs_0_enable() @@ -246,13 +258,29 @@ def probe(self, demodulation_mode='double', **kw): "self._acquisition_instr.quex_rl_data_{}()".format(channel)) data[i] = dataset[0]['vector'] dat = data[0]+1j*data[1] +======= + #self._acquisition_instr.awgs_0_enable(1) #this was causing spikes + # NH: Reduced timeout to prevent hangups + dataset = self._acquisition_instr.acquisition_poll(samples=1, acquisition_time=0.001, timeout=10) + dat = (self.scale_factor*dataset[0][0]+self.scale_factor*1j*dataset[1][0]) +>>>>>>> e9951a9... updates UHFLI detectors and DDM detectors t1 = time.time() #print("time for UHFQC polling", t1-t0) elif 'ATS' in self.acquisition_instr(): - t0 = time.time() + # t0 = time.time() dat = self._acquisition_instr_controller.acquisition() - t1 = time.time() + # t1 = time.time() # print("time for ATS polling", t1-t0) + + elif 'DDM' in self.acquisition_instr(): + # t0 = time.time() + self._acquisition_instr.ch_pair1_tvmode_enable.set(1) + self._acquisition_instr.ch_pair1_run.set(1) + dataI = eval("self._acquisition_instr.ch_pair1_weight{}_tvmode_data()".format(1)) + dataQ = eval("self._acquisition_instr.ch_pair1_weight{}_tvmode_data()".format(2)) + dat = (self.scale_factor*dataI+self.scale_factor*1j*dataQ) + # t1 = time.time() + # print("time for DDM polling", t1-t0) return dat diff --git a/pycqed/instrument_drivers/meta_instrument/qubit_objects/Tektronix_driven_transmon.py b/pycqed/instrument_drivers/meta_instrument/qubit_objects/Tektronix_driven_transmon.py index 2fc40da0db..75ffdc703a 100644 --- a/pycqed/instrument_drivers/meta_instrument/qubit_objects/Tektronix_driven_transmon.py +++ b/pycqed/instrument_drivers/meta_instrument/qubit_objects/Tektronix_driven_transmon.py @@ -984,6 +984,24 @@ def _do_set_acquisition_instr(self, acquisition_instr): channels=[ self.RO_acq_weight_function_I(), self.RO_acq_weight_function_Q()], integration_length=self.RO_acq_integration_length()) + elif 'DDM' in acquisition_instr: + logging.info("setting DDM acquisition") + self.input_average_detector = det.DDM_input_average_detector( + DDM=self._acquisition_instr, + AWG=self.AWG, nr_averages=self.RO_acq_averages()) + + self.int_avg_det = det.DDM_integrated_average_detector( + DDM=self._acquisition_instr, AWG=self.AWG, + channels=[self.RO_acq_weight_function_I(), + self.RO_acq_weight_function_Q()], + nr_averages=self.RO_acq_averages(), + integration_length=self.RO_acq_integration_length()) + + self.int_log_det = det.DDM_integration_logging_det( + DDM=self._acquisition_instr, AWG=self.AWG, + channels=[ + self.RO_acq_weight_function_I(), self.RO_acq_weight_function_Q()], + integration_length=self.RO_acq_integration_length()) elif 'ATS' in acquisition_instr: logging.info("setting ATS acquisition") diff --git a/pycqed/instrument_drivers/physical_instruments/QuTech_DDM_module.py b/pycqed/instrument_drivers/physical_instruments/QuTech_DDM_module.py index 027c290924..60e9fd8521 100644 --- a/pycqed/instrument_drivers/physical_instruments/QuTech_DDM_module.py +++ b/pycqed/instrument_drivers/physical_instruments/QuTech_DDM_module.py @@ -385,7 +385,7 @@ def add_parameters(self): # vals=vals.Numbers(-128,127) ) ''' - Error fraction + Error fraction ''' serrfarcten_cmd = 'qutech:errorfraction{}:enable{}'.format( ch_pair, wNr) @@ -608,7 +608,7 @@ def _getTVBusy(self, ch_pair, wNr): def _getTVpercentage(self, ch_pair, wNr): return self.ask('qutech:tvmode{:d}:percentage{:d}? '.format(ch_pair, wNr)) ''' - Logging + Logging ''' def _getLoggingFinished(self, ch_pair, wNr): @@ -803,6 +803,31 @@ def connect_message(self, idn_param='IDN', begin_time=None): 'in {t:.2f}s'.format(t=t, **idn)) print(con_msg) + #initialization functions + def prepare_SSB_weight_and_rotation(self, IF, + weight_function_I=1, + weight_function_Q=2): + trace_length = 4096 + tbase = np.arange(0, trace_length/5e8, 1/5e8) + cosI = np.array(np.cos(2*np.pi*IF*tbase)) + sinI = np.array(np.sin(2*np.pi*IF*tbase)) + #first pair + eval('self.ch1_weight{}_data(np.array(cosI))'.format(weight_function_I)) + eval('self.ch2_weight{}_data(np.array(sinI))'.format(weight_function_I)) + #second pair + eval('self.ch1_weight{}_data(np.array(sinI))'.format(weight_function_Q)) + eval('self.ch2_weight{}_data(np.array(cosI))'.format(weight_function_Q)) + + #setting the rotation matrices... very danagerous + eval('self.ch_pair1_weight{}_rotmat_rotmat00(1)'.format(weight_function_I)) + eval('self.ch_pair1_weight{}_rotmat_rotmat01(1)'.format(weight_function_I)) + eval('self.ch_pair1_weight{}_rotmat_rotmat00(1)'.format(weight_function_Q)) + eval('self.ch_pair1_weight{}_rotmat_rotmat01(-1)'.format(weight_function_Q)) + + + + + # @ NIKITA LOOK HERE! class MyCustomValidator(vals.Validator): @@ -871,3 +896,5 @@ def __repr__(self): maxv = self._max_value if math.isfinite(self._max_value) else None return ''.format(range_str(minv, maxv, 'v'), self._shape) + + diff --git a/pycqed/measurement/composite_detector_functions.py b/pycqed/measurement/composite_detector_functions.py index e290549f9e..fce90cd306 100644 --- a/pycqed/measurement/composite_detector_functions.py +++ b/pycqed/measurement/composite_detector_functions.py @@ -312,7 +312,7 @@ def finish(self, **kw): class SSRO_Fidelity_Detector_CBox(det.Soft_Detector): ''' - Currently only for CBox. + Currently only for CBox, ''' def __init__(self, measurement_name, MC, AWG, CBox, @@ -376,7 +376,7 @@ def acquire_data_point(self, *args, **kw): class SSRO_Fidelity_Detector_Tek(det.Soft_Detector): ''' - For Qcodes. Readout with CBox, pulse generation with 5014 + For Qcodes. Readout with CBox, UHFLI, DDM, pulse generation with 5014 ''' def __init__(self, measurement_name, MC, AWG, acquisition_instr, @@ -416,6 +416,9 @@ def __init__(self, measurement_name, MC, AWG, acquisition_instr, self.CBox = self.acquisition_instr elif 'UHFQC' in str(self.acquisition_instr): self.UHFQC = self.acquisition_instr + elif 'DDM' in str(self.acquisition_instr): + self.DDM = self.acquisition_instr + self.nr_averages = nr_averages self.integration_length = integration_length self.weight_function_I = weight_function_I @@ -469,6 +472,28 @@ def prepare(self, **kw): IF=self.IF, weight_function_I=self.weight_function_I, weight_function_Q=self.weight_function_Q) + elif 'DDM' in str(self.acquisition_instr): + self.MC.set_detector_function( + det.DDM_integration_logging_det( + self.acquisition_instr, self.AWG, + channels=[ + self.weight_function_I, self.weight_function_Q], + integration_length=self.integration_length, + nr_shots=min(self.nr_shots, 8000))) + if self.SSB: + self.DDM.prepare_SSB_weight_and_rotation( + IF=self.IF, weight_function_I=self.weight_function_I, + weight_function_Q=self.weight_function_Q) + #not yet implemented + # else: + # if self.IF == None: + # raise ValueError( + # 'IF has to be provided when not using optimized weights') + # else: + # self.UHFQC.prepare_DSB_weight_and_rotation( + # IF=self.IF, + # weight_function_I=self.weight_function_I, + # weight_function_Q=self.weight_function_Q) def acquire_data_point(self, *args, **kw): self.time_start = time.time() diff --git a/pycqed/measurement/detector_functions.py b/pycqed/measurement/detector_functions.py index 1fe9dd9eaa..1f5b345eab 100644 --- a/pycqed/measurement/detector_functions.py +++ b/pycqed/measurement/detector_functions.py @@ -1724,3 +1724,198 @@ def prepare(self, sweep_points): def finish(self): pass + + +### DDM detector functions +class DDM_input_average_detector(Hard_Detector): + + ''' + Detector used for acquiring averaged input traces withe the DDM + + ''' + + ''' + Detector used for acquiring single points of the DDM while externally + triggered by the AWG. + Soft version of the regular integrated avg detector. + # not yet pair specific + ''' + + def __init__(self, DDM, AWG, channels=[1, 2], nr_averages=1024, nr_samples=1024, **kw): + super(DDM_input_average_detector, self).__init__() + + self.DDM = DDM + self.name = 'DDM_input_averaging_data' + self.channels = channels + self.value_names = ['']*len(self.channels) + self.value_units = ['']*len(self.channels) + for i, channel in enumerate(self.channels): + self.value_names[i] = 'ch{}'.format(channel) + self.value_units[i] = 'V' + self.AWG = AWG + self.nr_samples = nr_samples + self.nr_averages = nr_averages + + def prepare(self, sweep_points): + if self.AWG is not None: + self.AWG.stop() + self.DDM.ch_pair1_inavg_scansize.set(self.nr_samples) + self.DDM.ch_pair1_inavg_Navg(self.nr_averages) + self.nr_sweep_points = self.nr_samples + + def get_values(self): + #arming DDM trigger + self.DDM.ch_pair1_inavg_enable.set(1) + self.DDM.ch_pair1_run.set(1) + # starting AWG + if self.AWG is not None: + self.AWG.start() + # polling the data, function checks that measurement is finished + data = ['']*len(self.channels) + for i, channel in enumerate(self.channels): + data[i] = eval("self.DDM.ch{}_inavg_data()".format(channel))/127 + return data + + def finish(self): + if self.AWG is not None: + self.AWG.stop() + + +class DDM_integrated_average_detector(Hard_Detector): + + ''' + Detector used for integrated average results with the DDM + + ''' + + def __init__(self, DDM, AWG, integration_length=1e-6, nr_averages=1024, rotate=False, + channels=[1,2,3,4,5], cross_talk_suppression=False, + **kw): + super(DDM_integrated_average_detector, self).__init__() + self.DDM = DDM + self.name = 'DDM_integrated_average' + self.channels = channels + self.value_names = ['']*len(self.channels) + self.value_units = ['']*len(self.channels) + self.cal_points = kw.get('cal_points', None) + for i, channel in enumerate(self.channels): + self.value_names[i] = 'w{}'.format(channel) + self.value_units[i] = 'V' + self.rotate = rotate + self.AWG = AWG + self.nr_averages = nr_averages + self.integration_length = integration_length + self.rotate = rotate + self.cross_talk_suppression = cross_talk_suppression + self.scaling_factor=1/(500e6*integration_length)/127 + + def prepare(self, sweep_points=None): + if self.AWG is not None: + self.AWG.stop() + if sweep_points is None: + self.nr_sweep_points = 1 + else: + self.nr_sweep_points = len(sweep_points) + # this sets the result to integration and rotation outcome + for i, channel in enumerate(self.channels): + eval("self.DDM.ch_pair1_weight{}_wint_intlength({})".format(channel, self.integration_length*500e6)) + self.DDM.ch_pair1_tvmode_naverages(self.nr_averages) + self.DDM.ch_pair1_tvmode_nsegments(self.nr_sweep_points) + + def get_values(self): + #arming DDM trigger + self.DDM.ch_pair1_tvmode_enable.set(1) + self.DDM.ch_pair1_run.set(1) + # starting AWG + if self.AWG is not None: + self.AWG.start() + # polling the data, function checks that measurement is finished + data = ['']*len(self.channels) + for i, channel in enumerate(self.channels): + data[i] = eval("self.DDM.ch_pair1_weight{}_tvmode_data()".format(channel))*self.scaling_factor + if self.rotate: + return self.rotate_and_normalize(data) + else: + return data + + def acquire_data_point(self): + return self.get_values() + + def rotate_and_normalize(self, data): + """ + Rotates and normalizes + """ + if self.cal_points is None: + self.corr_data, self.zero_coord, self.one_coord = \ + a_tools.rotate_and_normalize_data( + data=data, + cal_zero_points=list(range(-4, -2)), + cal_one_points=list(range(-2, 0))) + else: + self.corr_data, self.zero_coord, self.one_coord = \ + a_tools.rotate_and_normalize_data( + data=self.measured_values[0:2], + cal_zero_points=self.cal_points[0], + cal_one_points=self.cal_points[1]) + return self.corr_data, self.corr_data + + def finish(self): + if self.AWG is not None: + self.AWG.stop() + + +class DDM_integration_logging_det(Hard_Detector): + + ''' + Detector used for integrated average results with the UHFQC + + ''' + + def __init__(self, DDM, AWG, integration_length=1e-6, + channels=[1, 2], nr_shots=4096, **kw): + super(DDM_integration_logging_det, self).__init__() + self.DDM = DDM + self.name = 'DDM_integration_logging_det' + self.channels = channels + self.value_names = ['']*len(self.channels) + self.value_units = ['']*len(self.channels) + for i, channel in enumerate(self.channels): + self.value_names[i] = 'w{}'.format(channel) + self.value_units[i] = 'V' + if len(self.channels) == 2: + self.value_names = ['I', 'Q'] + self.value_units = ['V', 'V'] + self.AWG = AWG + self.integration_length = integration_length + self.nr_shots = nr_shots + self.scaling_factor=1/(500e6*integration_length)/127 + + def prepare(self, sweep_points): + if self.AWG is not None: + self.AWG.stop() + if sweep_points is None: + self.nr_sweep_points = 1 + else: + self.nr_sweep_points = len(sweep_points) + # this sets the result to integration and rotation outcome + for i, channel in enumerate(self.channels): + eval("self.DDM.ch_pair1_weight{}_wint_intlength({})".format(channel, self.integration_length*500e6)) + self.DDM.ch_pair1_logging_nshots(self.nr_shots) + + + def get_values(self): + #arming DDM trigger + self.DDM.ch_pair1_logging_enable.set(1) + self.DDM.ch_pair1_run.set(1) + # starting AWG + if self.AWG is not None: + self.AWG.start() + # polling the data, function checks that measurement is finished + data = ['']*len(self.channels) + for i, channel in enumerate(self.channels): + data[i] = eval("self.DDM.ch_pair1_weight{}_logging_int()".format(channel))*self.scaling_factor + return data + + def finish(self): + if self.AWG is not None: + self.AWG.stop() \ No newline at end of file