def test_final_variance_runs(self): exp = VarianceExperiment() printer_final = Print(name="Final") avgr = Averager('repeats', name="TestAverager") var_buff = DataBuffer(name='Variance Buffer') mean_buff = DataBuffer(name='Mean Buffer') edges = [(exp.chan1, avgr.sink), (avgr.final_variance, printer_final.sink), (avgr.final_variance, var_buff.sink), (avgr.source, mean_buff.sink)] exp.set_graph(edges) exp.run_sweeps() # var_data = var_buff.get_data()['Variance'].reshape(var_buff.descriptor.data_dims()) # mean_data = mean_buff.get_data()['chan1'].reshape(mean_buff.descriptor.data_dims()) var_data = var_buff.output_data.reshape( var_buff.descriptor.data_dims()) mean_data = mean_buff.output_data.reshape( mean_buff.descriptor.data_dims()) orig_data = exp.vals.reshape(exp.chan1.descriptor.data_dims()) self.assertTrue( np.abs(np.sum(mean_data - np.mean(orig_data, axis=0))) <= 1e-3) self.assertTrue( np.abs(np.sum(var_data - np.var(orig_data, axis=0, ddof=1))) <= 1e-3)
def test_correlator(self): exp = CorrelatorExperiment() corr = Correlator() buff = DataBuffer() edges = [(exp.chan1, corr.sink), (exp.chan2, corr.sink), (corr.source, buff.sink)] exp.set_graph(edges) exp.run_sweeps() corr_data = buff.get_data()['Correlator'] expected_data = exp.vals * exp.vals self.assertTrue(np.abs(np.sum(corr_data - expected_data)) <= 1e-4)
def test_buffer_metadata(self): exp = SweptTestExperimentMetadata() db = DataBuffer() edges = [(exp.voltage, db.sink)] exp.set_graph(edges) exp.add_sweep(exp.field, np.linspace(0, 100.0, 4)) exp.add_sweep(exp.freq, np.linspace(0, 10.0, 3)) exp.run_sweeps() data = db.get_data() self.assertTrue(len(data) == 4 * 3 * 5) self.assertTrue(len(data['samples_metadata']) == 4 * 3 * 5)
def test_buffer(self): exp = SweptTestExperiment() db = DataBuffer() edges = [(exp.voltage, db.sink)] exp.set_graph(edges) exp.add_sweep(exp.field, np.linspace(0,100.0,4)) exp.add_sweep(exp.freq, np.linspace(0,10.0,3)) exp.run_sweeps() data, desc = db.get_data() self.assertTrue(data.shape == (3, 4, 5)) self.assertTrue(np.all(desc['field'] == np.linspace(0,100.0,4)))
def test_correlator(self): exp = CorrelatorExperiment() corr = Correlator(name='corr') buff = DataBuffer() edges = [(exp.chan1, corr.sink), (exp.chan2, corr.sink), (corr.source, buff.sink)] exp.set_graph(edges) exp.run_sweeps() time.sleep(0.01) corr_data = buff.output_data expected_data = exp.vals * exp.vals self.assertAlmostEqual(np.sum(corr_data), np.sum(expected_data), places=0)
def test_buffer_multi(self): exp = SweptTestExperiment() db = DataBuffer() edges = [(exp.voltage, db.sink), (exp.current, db.sink)] exp.set_graph(edges) exp.add_sweep(exp.field, np.linspace(0, 100.0, 4)) exp.add_sweep(exp.freq, np.linspace(0, 10.0, 3)) exp.run_sweeps() data = db.get_data() self.assertTrue(len(data) == 4 * 3 * 5) self.assertTrue(len(data['current']) == 4 * 3 * 5) self.assertTrue(len(data['voltage']) == 4 * 3 * 5) self.assertTrue(len(data['field']) == 4 * 3 * 5)
def test_buffer_complex(self): exp = SweptTestExperiment() db = DataBuffer() exp.voltage.descriptor.dtype = np.complex128 exp.current.descriptor.dtype = np.complex128 exp.complex_data = True exp.update_descriptors() edges = [(exp.voltage, db.sink)] exp.set_graph(edges) exp.add_sweep(exp.field, np.linspace(0,100.0,4)) exp.add_sweep(exp.freq, np.linspace(0,10.0,3)) exp.run_sweeps() data, desc = db.get_data() self.assertAlmostEqual(np.mean(data.imag)/np.mean(data.real), 2.0, places=3)
await self.voltage.push(r) await asyncio.sleep(0.01) if __name__ == '__main__': exp = TestExperiment() exp.leave_plot_server_open = True # Create the plotter and the actual traces we'll need plt = ManualPlotter("Manual Plotting Test", x_label='X Thing', y_label='Y Thing') plt.add_data_trace("Example Data") plt.add_fit_trace("Example Fit") buff = DataBuffer() edges = [(exp.voltage, buff.sink)] exp.set_graph(edges) # Create a plotter callback def plot_me(plot): ys = buff.get_data()['voltage'] xs = buff.descriptor.axes[0].points plot["Example Data"] = (xs, ys) plot["Example Fit"] = (xs, ys + 0.1) exp.add_manual_plotter(plt, callback=plot_me) exp.add_sweep(exp.amplitude, np.linspace(-5.0, 5.0, 100)) exp.run_sweeps()
def calibrate_mixer(qubit, mixer="control", first_cal="phase", write_to_file=True, offset_range=(-0.2, 0.2), amp_range=(0.6, 1.4), phase_range=(-np.pi / 6, np.pi / 6), nsteps=51): """Calibrates IQ mixer offset, amplitude imbalanace, and phase skew. See Analog Devices Application note AN-1039. Parses instrument connectivity from the experiment settings YAML. Arguments: qubit: Qubit identifier string. mixer: One of ("control", "measure") to select which IQ channel is calibrated. first_cal: One of ("phase", "amplitude") to select which adjustment is attempted first. You should pick whichever the particular mixer is most sensitive to. For example, a mixer with -40dBc sideband supression at 1 degree of phase skew and 0.1 dB amplitude imbalance should calibrate the phase first. """ spm = auspex.config.single_plotter_mode auspex.config.single_plotter_mode = True def sweep_offset(name, pts): mce.clear_sweeps() mce.add_sweep(getattr(mce, name), pts) mce.keep_instruments_connected = True mce.run_sweeps() offset_pts = np.linspace(offset_range[0], offset_range[1], nsteps) amp_pts = np.linspace(amp_range[0], amp_range[1], nsteps) phase_pts = np.linspace(phase_range[0], phase_range[1], nsteps) buff = DataBuffer() plt = ManualPlotter(name="Mixer offset calibration", x_label='{} {} offset (V)'.format(qubit, mixer), y_label='Power (dBm)') plt.add_data_trace("I-offset", {'color': 'C1'}) plt.add_data_trace("Q-offset", {'color': 'C2'}) plt.add_fit_trace("Fit I-offset", {'color': 'C1'}) #TODO: fix axis labels plt.add_fit_trace("Fit Q-offset", {'color': 'C2'}) plt2 = ManualPlotter(name="Mixer amp/phase calibration", x_label='{} {} amplitude (V)/phase (rad)'.format( qubit, mixer), y_label='Power (dBm)') plt2.add_data_trace("phase_skew", {'color': 'C3'}) plt2.add_data_trace("amplitude_factor", {'color': 'C4'}) plt2.add_fit_trace("Fit phase_skew", {'color': 'C3'}) plt2.add_fit_trace("Fit amplitude_factor", {'color': 'C4'}) mce = MixerCalibrationExperiment(qubit, mixer=mixer) mce.add_manual_plotter(plt) mce.add_manual_plotter(plt2) mce.leave_plot_server_open = True QubitExpFactory.load_instruments(mce, mce.instruments_to_enable) edges = [(mce.amplitude, buff.sink)] mce.set_graph(edges) sweep_offset("I_offset", offset_pts) I1_amps = np.array([x[1] for x in buff.get_data()]) try: I1_offset, xpts, ypts = find_null_offset(offset_pts[1:], I1_amps[1:]) except: mce.extra_plot_server.stop() return plt["I-offset"] = (offset_pts, I1_amps) plt["Fit I-offset"] = (xpts, ypts) logger.info("Found first pass I offset of {}.".format(I1_offset)) mce.I_offset.value = I1_offset mce.first_exp = False # slight misnomer to indicate that no new plot is needed sweep_offset("Q_offset", offset_pts) Q1_amps = np.array([x[1] for x in buff.get_data()]) try: Q1_offset, xpts, ypts = find_null_offset(offset_pts[1:], Q1_amps[1:]) except: mce.extra_plot_server.stop() return plt["Q-offset"] = (offset_pts, Q1_amps) plt["Fit Q-offset"] = (xpts, ypts) logger.info("Found first pass Q offset of {}.".format(Q1_offset)) mce.Q_offset.value = Q1_offset sweep_offset("I_offset", offset_pts) I2_amps = np.array([x[1] for x in buff.get_data()]) try: I2_offset, xpts, ypts = find_null_offset(offset_pts[1:], I2_amps[1:]) except: mce.extra_plot_server.stop() return plt["I-offset"] = (offset_pts, I2_amps) plt["Fit I-offset"] = (xpts, ypts) logger.info("Found second pass I offset of {}.".format(I2_offset)) mce.I_offset.value = I2_offset #this is a bit hacky but OK... cals = {"phase": "phase_skew", "amplitude": "amplitude_factor"} cal_pts = {"phase": phase_pts, "amplitude": amp_pts} cal_defaults = {"phase": 0.0, "amplitude": 1.0} if first_cal not in cals.keys(): raise ValueError( "First calibration should be one of ('phase, amplitude'). Instead got {}" .format(first_cal)) second_cal = list(set(cals.keys()).difference({ first_cal, }))[0] mce.sideband_modulation = True sweep_offset(cals[first_cal], cal_pts[first_cal]) amps1 = np.array([x[1] for x in buff.get_data()]) try: offset1, xpts, ypts = find_null_offset( cal_pts[first_cal][1:], amps1[1:], default=cal_defaults[first_cal]) except: mce.extra_plot_server.stop() return plt2[cals[first_cal]] = (cal_pts[first_cal], amps1) plt2["Fit " + cals[first_cal]] = (xpts, ypts) logger.info("Found {} of {}.".format( str.replace(cals[first_cal], '_', ' '), offset1)) getattr(mce, cals[first_cal]).value = offset1 sweep_offset(cals[second_cal], cal_pts[second_cal]) amps2 = np.array([x[1] for x in buff.get_data()]) try: offset2, xpts, ypts = find_null_offset( cal_pts[second_cal][1:], amps2[1:], default=cal_defaults[second_cal]) except: mce.extra_plot_server.stop() return plt2[cals[second_cal]] = (cal_pts[second_cal], amps2) plt2["Fit " + cals[second_cal]] = (xpts, ypts) logger.info("Found {} of {}.".format( str.replace(cals[first_cal], '_', ' '), offset2)) getattr(mce, cals[second_cal]).value = offset2 mce.disconnect_instruments() try: mce.extra_plot_server.stop() except: logger.info('Mixer plot server was not successfully stopped.') if write_to_file: mce.write_to_file() logger.info(("Mixer calibration: I offset = {}, Q offset = {}, " "Amplitude Imbalance = {}, Phase Skew = {}").format( mce.I_offset.value, mce.Q_offset.value, mce.amplitude_factor.value, mce.phase_skew.value)) auspex.config.single_plotter_mode = spm