def sweep_gates_2d(self, gates, sweep_ranges, period, resolution, width=0.9375, do_upload=True): """ Supplies sawtooth signals to a linear combination of gates, which effectively does a 2D scan. Arguments: gates (list[dict]): A list containing two dictionaries with both the the gate name keys and relative amplitude values. sweep_ranges (list): A list two overall amplitude of the sawtooth waves in millivolt in the x- and y-direction. period (float): The total period of the sawtooth signals in seconds. resolution (list): Two integer values with the number of sawtooth signal (pixels) in the x- and y-direction. width (float): Width of the rising sawtooth ramp as a proportion of the total cycle. Needs a value between 0 and 1. The value 1 producing a rising ramp, while 0 produces a falling ramp. do_upload (bool, Optional): Does not upload the waves to the AWG's when set to False. Returns: A dictionary with the properties of the sawtooth signals; the original sawtooth sequence, the sweep ranges, the marker properties and period of the sawtooth signals. Example: >> sec_period = 1e-6 >> resolution = [10, 10] >> mV_sweep_ranges = [100, 100] >> gates = [{'P4': 1}, {'P7': 0.1}] >> sweep_data = virtual_awg.sweep_gates_2d(gates, mV_sweep_ranges, period, resolution) """ sequences = {} base_period = period / np.prod(resolution) sequences.update(self.make_markers(period, repetitions=1)) period_x = resolution[0] * base_period for gate_name_x, rel_amplitude_x in gates[0].items(): amplitude_x = rel_amplitude_x * sweep_ranges[0] sweep_wave_x = Sequencer.make_sawtooth_wave(amplitude_x, period_x, width, resolution[1]) sequences.setdefault(gate_name_x, []).append(sweep_wave_x) period_y = resolution[0] * resolution[1] * base_period for gate_name_y, rel_amplitude_y in gates[1].items(): amplitude_y = rel_amplitude_y * sweep_ranges[1] sweep_wave_y = Sequencer.make_sawtooth_wave(amplitude_y, period_y, width) sequences.setdefault(gate_name_y, []).append(sweep_wave_y) sweep_data = self.sequence_gates(sequences, do_upload) sweep_data.update({'sweeprange_horz': sweep_ranges[0], 'sweeprange_vert': sweep_ranges[1], 'width_horz': width, 'width_vert': width, 'resolution': resolution, 'start_zero': True, 'period': period_y, 'period_horz': period_x, 'samplerate': self.awgs[0].retrieve_sampling_rate(), 'markerdelay': self.digitizer_marker_delay()}) return sweep_data
def test_serialize_deserialize_pulse(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning, message="qupulse") period = 1e-6 amplitude = 1.5 sawtooth = Sequencer.make_sawtooth_wave(amplitude, period) serialized_pulse = sawtooth['wave'] serialized_data = Sequencer.serialize(sawtooth) self.assertTrue( "qupulse.pulses.sequence_pulse_template.SequencePulseTemplate" in serialized_data) self.assertTrue( "qupulse.pulses.mapping_pulse_template.MappingPulseTemplate" in serialized_data) self.assertTrue("\"amplitude\": 0.75" in serialized_data) self.assertTrue("\"period\": 1000.0" in serialized_data) self.assertTrue("\"width\": 0.95" in serialized_data) self.assertTrue( "qupulse.pulses.table_pulse_template.TablePulseTemplate" in serialized_data) self.assertTrue("sawtooth" in serialized_data) deserialized_pulse = Sequencer.deserialize(serialized_data) self.assertEqual( serialized_pulse.subtemplates[0].parameter_mapping['period'], deserialized_pulse.subtemplates[0].parameter_mapping['period']) self.assertEqual( serialized_pulse.subtemplates[0]. parameter_mapping['amplitude'], deserialized_pulse. subtemplates[0].parameter_mapping['amplitude']) self.assertEqual( serialized_pulse.subtemplates[0].parameter_mapping['width'], deserialized_pulse.subtemplates[0].parameter_mapping['width'])
def test_qupulse_template_to_array_new_style_vs_values_old_style(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning, message="qupulse") warnings.filterwarnings( "ignore", category=DeprecationWarning, message="InstructionBlock API is deprecated") period = 1e-3 amplitude = 1.5 sampling_rate = 1e9 sequence = Sequencer.make_sawtooth_wave(amplitude, period) template = sequence['wave'] channels = template.defined_channels loop = template.create_program( parameters=dict(), measurement_mapping={w: w for w in template.measurement_names}, channel_mapping={ch: ch for ch in channels}, global_transformation=None, to_single_waveform=set()) (_, voltages_new, _) = render(loop, sampling_rate / 1e9) # the value to compare to are calculated using qupulse 0.4 Sequencer class self.assertTrue(1000001 == len(voltages_new['sawtooth'])) self.assertAlmostEqual(-amplitude / 2, np.min(voltages_new['sawtooth']), 12) self.assertAlmostEqual(amplitude / 2, np.max(voltages_new['sawtooth']), 12)
def sweep_gates(self, gates, sweep_range, period, width=0.95, do_upload=True): """ Sweep a set of gates with a sawtooth waveform. Example: >>> sweep_data = virtualawg.sweep_gates({'P4': 1, 'P7': 0.1}, 100, 1e-3) """ sequences = dict() sequences.update(self.__make_markers(period)) for gate_name, rel_amplitude in gates.items(): amplitude = rel_amplitude * sweep_range sequences[gate_name] = Sequencer.make_sawtooth_wave( amplitude, period, width) sweep_data = self.sequence_gates(sequences, do_upload) sweep_data.update({ 'sweeprange': sweep_range, 'period': period, 'width': width, 'markerdelay': self.digitizer_marker_delay() }) return sweep_data
def sweep_gates_2d(self, gates, sweep_ranges, period, resolution, width=0.95, do_upload=True): sequences = dict() sequences.update(self.__make_markers(period)) period_x = resolution[0] * period for gate_name_x, rel_amplitude_x in gates[0].items(): amplitude_x = rel_amplitude_x * sweep_ranges[0] sequences[gate_name_x] = Sequencer.make_sawtooth_wave( amplitude_x, period_x, width) period_y = resolution[0] * resolution[1] * period for gate_name_y, rel_amplitude_y in gates[1].items(): amplitude_y = rel_amplitude_y * sweep_ranges[1] sequences[gate_name_y] = Sequencer.make_sawtooth_wave( amplitude_y, period_y, width) sweep_data = self.sequence_gates(sequences, do_upload) sweep_data.update({ 'sweeprange_horz': sweep_ranges[0], 'sweeprange_vert': sweep_ranges[1], 'width_horz': 0.95, 'width_vert': 0.95, 'resolution': resolution, 'period': period_y, 'period_horz': period_x, 'samplerate': self.awgs[0].retrieve_setting('sampling_rate'), 'markerdelay': self.awg_marker_delay() }) return sweep_data
def test_qupulse_sawtooth_HasCorrectProperties(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning, message="qupulse") epsilon = 1e-14 period = 1e-3 amplitude = 1.5 sampling_rate = 1e9 sequence = Sequencer.make_sawtooth_wave(amplitude, period) raw_data = Sequencer.get_data(sequence, sampling_rate) self.assertTrue(len(raw_data) == sampling_rate * period + 1) self.assertTrue(np.abs(np.min(raw_data) + amplitude / 2) <= epsilon) self.assertTrue(np.abs(np.max(raw_data) - amplitude / 2) <= epsilon)
def sweep_gates(self, gates, sweep_range, period, width=0.9375, do_upload=True): """ Supplies a sawtooth wave to the given gates and returns the settings required for processing and constructing the readout times for the digitizer. Arguments: gates (dict): Contains the gate name keys with relative amplitude values. sweep_range (float): The peak-to-peak amplitude of the sawtooth waves in millivolt. period (float): The period of the pulse waves in seconds. width (float): Width of the rising sawtooth ramp as a proportion of the total cycle. Needs a value between 0 and 1. The value 1 producing a rising ramp, while 0 produces a falling ramp. do_upload (bool, Optional): Does not upload the waves to the AWG's when set to False. Returns: A dictionary with the properties of the pulse waves; the original sawtooth sequence, the sweep ranges and the marker properties and period of the sawtooth waves. Example: >> sec_period = 1e-6 >> mV_sweep_range = 100 >> gates = {'P4': 1, 'P7': 0.1} >> sweep_data = virtual_awg.sweep_gates(gates, 100, 1e-3) """ sequences = dict() sequences.update(self.make_markers(period)) for gate_name, rel_amplitude in gates.items(): amplitude = rel_amplitude * sweep_range sweep_wave = Sequencer.make_sawtooth_wave(amplitude, period, width) sequences.setdefault(gate_name, []).append(sweep_wave) sweep_data = self.sequence_gates(sequences, do_upload) sweep_data.update({ 'sweeprange': sweep_range, 'period': period, 'width': width, 'start_zero': True, '_gates': gates }) if VirtualAwg.__digitizer_name in self._settings.awg_map: sweep_data.update({'markerdelay': self.digitizer_marker_delay()}) return sweep_data
def test_qupulse_template_to_array_new_style_vs_old_style(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning, message="qupulse") warnings.filterwarnings( "ignore", category=DeprecationWarning, message="InstructionBlock API is deprecated") period = 1e-3 amplitude = 1.5 sampling_rate = 1e9 sequence = Sequencer.make_sawtooth_wave(amplitude, period) template = sequence['wave'] channels = template.defined_channels sequencer = Sequencing() sequencer.push( template, dict(), channel_mapping={ch: ch for ch in channels}, window_mapping={w: w for w in template.measurement_names}) instructions = sequencer.build() if not sequencer.has_finished(): raise PlottingNotPossibleException(template) (_, voltages_old, _) = render(instructions, sampling_rate / 1e9) loop = template.create_program( parameters=dict(), measurement_mapping={w: w for w in template.measurement_names}, channel_mapping={ch: ch for ch in channels}, global_transformation=None, to_single_waveform=set()) (_, voltages_new, _) = render(loop, sampling_rate / 1e9) self.assertTrue(len(voltages_old) == len(voltages_new)) self.assertTrue(np.min(voltages_old) == np.min(voltages_old)) self.assertTrue(np.max(voltages_old) == np.max(voltages_old))