From b542734e90289e98da052fcd398094e9c9051b1e Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Mon, 4 May 2020 22:47:15 -0400 Subject: [PATCH 01/12] Add ShiftFrequency --- qiskit/pulse/__init__.py | 3 +- qiskit/pulse/instructions/__init__.py | 3 +- qiskit/pulse/instructions/frequency.py | 29 +++++++++++++ qiskit/qobj/converters/pulse_instruction.py | 43 +++++++++++++++++++ qiskit/visualization/pulse/matplotlib.py | 12 +++++- test/python/pulse/test_schedule.py | 25 ++++++++--- test/python/qobj/test_pulse_converter.py | 30 ++++++++++++- test/python/qobj/test_qobj.py | 6 ++- .../test_pulse_visualization_output.py | 3 +- 9 files changed, 139 insertions(+), 15 deletions(-) diff --git a/qiskit/pulse/__init__.py b/qiskit/pulse/__init__.py index ac8c4e25ac77..b01c1723c3da 100644 --- a/qiskit/pulse/__init__.py +++ b/qiskit/pulse/__init__.py @@ -136,7 +136,8 @@ from .configuration import LoConfig, LoRange, Kernel, Discriminator from .exceptions import PulseError from .instruction_schedule_map import InstructionScheduleMap -from .instructions import Acquire, Instruction, Delay, Play, ShiftPhase, Snapshot, SetFrequency +from .instructions import (Acquire, Instruction, Delay, Play, ShiftPhase, Snapshot, + SetFrequency, ShiftFrequency) from .interfaces import ScheduleComponent from .pulse_lib import (SamplePulse, Gaussian, GaussianSquare, Drag, Constant, ConstantPulse, ParametricPulse) diff --git a/qiskit/pulse/instructions/__init__.py b/qiskit/pulse/instructions/__init__.py index 11fbea361436..e26d7269f3e7 100644 --- a/qiskit/pulse/instructions/__init__.py +++ b/qiskit/pulse/instructions/__init__.py @@ -39,6 +39,7 @@ Delay Play SetFrequency + ShiftFrequency ShiftPhase Snapshot @@ -53,7 +54,7 @@ from .acquire import Acquire from .delay import Delay from .instruction import Instruction -from .frequency import SetFrequency +from .frequency import SetFrequency, ShiftFrequency from .phase import ShiftPhase from .play import Play from .snapshot import Snapshot diff --git a/qiskit/pulse/instructions/frequency.py b/qiskit/pulse/instructions/frequency.py index 3e603a83ebb1..efdd934f82d4 100644 --- a/qiskit/pulse/instructions/frequency.py +++ b/qiskit/pulse/instructions/frequency.py @@ -60,3 +60,32 @@ def channel(self) -> PulseChannel: scheduled on. """ return self._channel + + +class ShiftFrequency(Instruction): + r"""Shift the channel frequency away from the LO frequency.""" + def __init__(self, frequency: float, + channel: Optional[PulseChannel], + name: Optional[str] = None): + """Creates a new shift frequency instruction. + + Args: + frequency: Frequency shift of the channel in Hz. + channel: The channel this instruction operates on. + name: Name of this set channel frequency command. + """ + self._frequency = float(frequency) + self._channel = channel + super().__init__((frequency, channel), 0, (channel,), name=name) + + @property + def frequency(self) -> float: + """New frequency.""" + return self._frequency + + @property + def channel(self) -> PulseChannel: + """Return the :py:class:`~qiskit.pulse.channels.Channel` that this instruction is + scheduled on. + """ + return self._channel diff --git a/qiskit/qobj/converters/pulse_instruction.py b/qiskit/qobj/converters/pulse_instruction.py index 852a08aed2da..587ea8b1118d 100644 --- a/qiskit/qobj/converters/pulse_instruction.py +++ b/qiskit/qobj/converters/pulse_instruction.py @@ -273,6 +273,25 @@ def convert_set_frequency(self, shift, instruction): } return self._qobj_model(**command_dict) + @bind_instruction(instructions.ShiftFrequency) + def convert_set_frequency(self, shift, instruction): + """Return converted `ShiftFrequency`. + + Args: + shift (int): Offset time. + instruction (ShiftFrequency): Shift frequency instruction. + + Returns: + dict: Dictionary of required parameters. + """ + command_dict = { + 'name': 'shiftf', + 't0': shift+instruction.start_time, + 'ch': instruction.channel.name, + 'frequency': instruction.frequency + } + return self._qobj_model(**command_dict) + @bind_instruction(instructions.ShiftPhase) def convert_shift_phase(self, shift, instruction): """Return converted `ShiftPhase`. @@ -545,6 +564,30 @@ def gen_sf_schedule(*args, **kwargs): return instructions.SetFrequency(frequency, channel) << t0 + @bind_name('shiftf') + def convert_shift_frequency(self, instruction): + """Return converted `ShiftFrequency`. + + Args: + instruction (PulseQobjInstruction): set frequency qobj instruction + Returns: + Schedule: Converted and scheduled Instruction + """ + t0 = instruction.t0 + channel = self.get_channel(instruction.ch) + frequency = instruction.frequency + + if isinstance(frequency, str): + frequency_expr = parse_string_expr(frequency, partial_binding=False) + + def gen_sf_schedule(*args, **kwargs): + _frequency = frequency_expr(*args, **kwargs) + return instructions.ShiftFrequency(_frequency, channel) << t0 + + return ParameterizedSchedule(gen_sf_schedule, parameters=frequency_expr.params) + + return instructions.ShiftFrequency(frequency, channel) << t0 + @bind_name('pv') def convert_persistent_value(self, instruction): """Return converted `PersistentValueInstruction`. diff --git a/qiskit/visualization/pulse/matplotlib.py b/qiskit/visualization/pulse/matplotlib.py index c211059de173..9f4e24cea3de 100644 --- a/qiskit/visualization/pulse/matplotlib.py +++ b/qiskit/visualization/pulse/matplotlib.py @@ -36,7 +36,7 @@ from qiskit.pulse.commands import FrameChangeInstruction from qiskit.pulse import (SamplePulse, FrameChange, PersistentValue, Snapshot, Play, Acquire, PulseError, ParametricPulse, SetFrequency, ShiftPhase, - Instruction, ScheduleComponent) + Instruction, ScheduleComponent, ShiftFrequency) class EventsOutputChannels: @@ -105,6 +105,14 @@ def frequencychanges(self) -> Dict[int, SetFrequency]: return self._trim(self._frequencychanges) + @property + def frequencyshift(self) -> Dict[int, ShiftFrequency]: + """Set the frequency changes.""" + if self._frequencychanges is None: + self._build_waveform() + + return self._trim(self._frequencychanges) + @property def conditionals(self) -> Dict[int, str]: """Get conditionals.""" @@ -194,6 +202,8 @@ def _build_waveform(self): pv[time:] = 0 elif isinstance(command, SetFrequency): tmp_sf = command.frequency + elif isinstance(command, ShiftFrequency): + tmp_sf = command.frequency elif isinstance(command, Snapshot): self._snapshots[time] = command.name if tmp_fc != 0: diff --git a/test/python/pulse/test_schedule.py b/test/python/pulse/test_schedule.py index 146e02beda19..d3f071b6593b 100644 --- a/test/python/pulse/test_schedule.py +++ b/test/python/pulse/test_schedule.py @@ -20,7 +20,7 @@ from qiskit.pulse import (Play, SamplePulse, ShiftPhase, Instruction, SetFrequency, Acquire, pulse_lib, Snapshot, Delay, Gaussian, Drag, GaussianSquare, Constant, - functional_pulse) + functional_pulse, ShiftFrequency) from qiskit.pulse.channels import (MemorySlot, RegisterSlot, DriveChannel, AcquireChannel, SnapshotChannel, MeasureChannel) from qiskit.pulse.commands import PersistentValue, PulseInstruction @@ -611,6 +611,7 @@ class TestScheduleFilter(BaseTestSchedule): def test_filter_channels(self): """Test filtering over channels.""" lp0 = self.linear(duration=3, slope=0.2, intercept=0.1) + import ipdb; ipdb.set_trace() sched = Schedule(name='fake_experiment') sched = sched.insert(0, Play(lp0, self.config.drive(0))) sched = sched.insert(10, Play(lp0, self.config.drive(1))) @@ -653,6 +654,7 @@ def test_filter_inst_types(self): sched = sched.insert(10, Play(lp0, self.config.drive(1))) sched = sched.insert(30, ShiftPhase(-1.57, self.config.drive(0))) sched = sched.insert(40, SetFrequency(8.0, self.config.drive(0))) + sched = sched.insert(50, ShiftFrequency(4.0, self.config.drive(0))) for i in range(2): sched = sched.insert(60, Acquire(5, self.config.acquire(i), MemorySlot(i))) sched = sched.insert(90, Play(lp0, self.config.drive(0))) @@ -674,22 +676,31 @@ def test_filter_inst_types(self): for _, inst in no_pulse_and_fc.instructions: self.assertFalse(isinstance(inst, (Play, ShiftPhase))) self.assertEqual(len(only_pulse_and_fc.instructions), 4) - self.assertEqual(len(no_pulse_and_fc.instructions), 3) + self.assertEqual(len(no_pulse_and_fc.instructions), 4) # test on ShiftPhase only_fc, no_fc = \ self._filter_and_test_consistency(sched, instruction_types={ShiftPhase}) self.assertEqual(len(only_fc.instructions), 1) - self.assertEqual(len(no_fc.instructions), 6) + self.assertEqual(len(no_fc.instructions), 7) # test on SetFrequency - only_sf, no_sf = \ + only_setf, no_setf = \ self._filter_and_test_consistency(sched, instruction_types=[SetFrequency]) - for _, inst in only_sf.instructions: + for _, inst in only_setf.instructions: self.assertTrue(isinstance(inst, SetFrequency)) - self.assertEqual(len(only_sf.instructions), 1) - self.assertEqual(len(no_sf.instructions), 6) + self.assertEqual(len(only_setf.instructions), 1) + self.assertEqual(len(no_setf.instructions), 7) + + # test on ShiftFrequency + only_shiftf, no_shiftf = \ + self._filter_and_test_consistency(sched, + instruction_types=[ShiftFrequency]) + for _, inst in only_shiftf.instructions: + self.assertTrue(isinstance(inst, ShiftFrequency)) + self.assertEqual(len(only_shiftf.instructions), 1) + self.assertEqual(len(no_shiftf.instructions), 7) def test_filter_intervals(self): """Test filtering on intervals.""" diff --git a/test/python/qobj/test_pulse_converter.py b/test/python/qobj/test_pulse_converter.py index 56f94de8ed60..0ce52dc001ea 100644 --- a/test/python/qobj/test_pulse_converter.py +++ b/test/python/qobj/test_pulse_converter.py @@ -23,7 +23,7 @@ LoConfigConverter) from qiskit.pulse.commands import (SamplePulse, FrameChange, PersistentValue, Snapshot, Acquire, Gaussian, GaussianSquare, Constant, Drag) -from qiskit.pulse.instructions import ShiftPhase, SetFrequency, Play +from qiskit.pulse.instructions import ShiftPhase, SetFrequency, ShiftFrequency, Play from qiskit.pulse.channels import (DriveChannel, ControlChannel, MeasureChannel, AcquireChannel, MemorySlot, RegisterSlot) from qiskit.pulse.schedule import ParameterizedSchedule, Schedule @@ -157,6 +157,20 @@ def test_set_frequency(self): self.assertEqual(converter(0, instruction), valid_qobj) + def test_shift_frequency(self): + """Test converted qobj from ShiftFrequency.""" + converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) + instruction = ShiftFrequency(8.0, DriveChannel(0)) + + valid_qobj = PulseQobjInstruction( + name='shiftf', + ch='d0', + t0=0, + frequency=8.0 + ) + + self.assertEqual(converter(0, instruction), valid_qobj) + def test_persistent_value(self): """Test converted qobj from PersistentValueInstruction.""" converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) @@ -301,7 +315,7 @@ def test_frame_change(self): self.assertEqual(converted_instruction.instructions[0][-1], instruction) def test_set_frequency(self): - """Test converted qobj from FrameChangeInstruction.""" + """Test converted qobj from SetFrequency.""" instruction = SetFrequency(8.0, DriveChannel(0)) qobj = PulseQobjInstruction(name='setf', ch='d0', t0=0, frequency=8.0) @@ -312,6 +326,18 @@ def test_set_frequency(self): self.assertEqual(converted_instruction.instructions[0][-1], instruction) self.assertTrue('frequency' in qobj.to_dict()) + def test_shift_frequency(self): + """Test converted qobj from ShiftFrequency.""" + instruction = ShiftFrequency(8.0, DriveChannel(0)) + + qobj = PulseQobjInstruction(name='shiftf', ch='d0', t0=0, frequency=8.0) + converted_instruction = self.converter(qobj) + + self.assertEqual(converted_instruction.start_time, 0) + self.assertEqual(converted_instruction.duration, 0) + self.assertEqual(converted_instruction.instructions[0][-1], instruction) + self.assertTrue('frequency' in qobj.to_dict()) + def test_persistent_value(self): """Test converted qobj from PersistentValueInstruction.""" with self.assertWarns(DeprecationWarning): diff --git a/test/python/qobj/test_qobj.py b/test/python/qobj/test_qobj.py index 930882cf5438..bb26e2f00356 100644 --- a/test/python/qobj/test_qobj.py +++ b/test/python/qobj/test_qobj.py @@ -231,7 +231,8 @@ def setUp(self): PulseQobjInstruction(name='fc', t0=5, ch='d0', phase='P1'), PulseQobjInstruction(name='pv', t0=10, ch='d0', val=0.1 + 0.0j), PulseQobjInstruction(name='pv', t0=10, ch='d0', val='P1'), - PulseQobjInstruction(name='sf', t0=10, ch='d0', frequency=8.), + PulseQobjInstruction(name='setf', t0=10, ch='d0', frequency=8.), + PulseQobjInstruction(name='shiftf', t0=10, ch='d0', frequency=4.0), PulseQobjInstruction(name='acquire', t0=15, duration=5, qubits=[0], memory_slot=[0], kernels=[ @@ -265,7 +266,8 @@ def setUp(self): {'name': 'fc', 't0': 5, 'ch': 'd0', 'phase': 'P1'}, {'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 0.1+0j}, {'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 'P1'}, - {'name': 'sf', 't0': 10, 'ch': 'd0', 'frequency': 8.0}, + {'name': 'setf', 't0': 10, 'ch': 'd0', 'frequency': 8.0}, + {'name': 'shiftf', 't0': 10, 'ch': 'd0', 'frequency': 4.0}, {'name': 'acquire', 't0': 15, 'duration': 5, 'qubits': [0], 'memory_slot': [0], 'kernels': [{'name': 'boxcar', diff --git a/test/python/visualization/test_pulse_visualization_output.py b/test/python/visualization/test_pulse_visualization_output.py index 0a91143c030e..90e62b21e91b 100644 --- a/test/python/visualization/test_pulse_visualization_output.py +++ b/test/python/visualization/test_pulse_visualization_output.py @@ -23,7 +23,7 @@ from qiskit.pulse.channels import (DriveChannel, MeasureChannel, ControlChannel, AcquireChannel, MemorySlot, RegisterSlot) from qiskit.pulse.commands import FrameChange -from qiskit.pulse.instructions import SetFrequency, Play, Acquire, Delay, Snapshot +from qiskit.pulse.instructions import SetFrequency, Play, Acquire, Delay, Snapshot, ShiftFrequency from qiskit.pulse.schedule import Schedule from qiskit.tools.visualization import HAS_MATPLOTLIB from qiskit.visualization import pulse_drawer @@ -68,6 +68,7 @@ def sample_schedule(self): ControlChannel(0))) sched = sched.insert(60, FrameChange(phase=-1.57)(DriveChannel(0))) sched = sched.insert(60, SetFrequency(8.0, DriveChannel(0))) + sched = sched.insert(70, ShiftFrequency(4.0, DriveChannel(0))) sched = sched.insert(30, gp1(DriveChannel(1))) sched = sched.insert(60, gp0(ControlChannel(0))) sched = sched.insert(60, gs0(MeasureChannel(0))) From e8dd48689b1a2502e19f59785619a63f4de82d25 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Tue, 5 May 2020 12:51:49 -0400 Subject: [PATCH 02/12] Review suggestions --- qiskit/pulse/instructions/frequency.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qiskit/pulse/instructions/frequency.py b/qiskit/pulse/instructions/frequency.py index efdd934f82d4..f77ccb7edf54 100644 --- a/qiskit/pulse/instructions/frequency.py +++ b/qiskit/pulse/instructions/frequency.py @@ -63,9 +63,9 @@ def channel(self) -> PulseChannel: class ShiftFrequency(Instruction): - r"""Shift the channel frequency away from the LO frequency.""" + """Shift the channel frequency away from the set frequency.""" def __init__(self, frequency: float, - channel: Optional[PulseChannel], + channel: PulseChannel, name: Optional[str] = None): """Creates a new shift frequency instruction. @@ -80,7 +80,7 @@ def __init__(self, frequency: float, @property def frequency(self) -> float: - """New frequency.""" + """Frequency shift from the set frequency.""" return self._frequency @property From cd037d83e21f9c904ba218c1b2f3f9c7dedcbf95 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Tue, 5 May 2020 12:52:11 -0400 Subject: [PATCH 03/12] Lint --- qiskit/qobj/converters/pulse_instruction.py | 2 +- test/python/pulse/test_schedule.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/qiskit/qobj/converters/pulse_instruction.py b/qiskit/qobj/converters/pulse_instruction.py index 587ea8b1118d..fe0d6c0b70b2 100644 --- a/qiskit/qobj/converters/pulse_instruction.py +++ b/qiskit/qobj/converters/pulse_instruction.py @@ -274,7 +274,7 @@ def convert_set_frequency(self, shift, instruction): return self._qobj_model(**command_dict) @bind_instruction(instructions.ShiftFrequency) - def convert_set_frequency(self, shift, instruction): + def convert_shift_frequency(self, shift, instruction): """Return converted `ShiftFrequency`. Args: diff --git a/test/python/pulse/test_schedule.py b/test/python/pulse/test_schedule.py index d3f071b6593b..4a6ecbb666e7 100644 --- a/test/python/pulse/test_schedule.py +++ b/test/python/pulse/test_schedule.py @@ -611,7 +611,6 @@ class TestScheduleFilter(BaseTestSchedule): def test_filter_channels(self): """Test filtering over channels.""" lp0 = self.linear(duration=3, slope=0.2, intercept=0.1) - import ipdb; ipdb.set_trace() sched = Schedule(name='fake_experiment') sched = sched.insert(0, Play(lp0, self.config.drive(0))) sched = sched.insert(10, Play(lp0, self.config.drive(1))) From 1c50c8d3d234a8d02da18e35e632a752e8747b71 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Tue, 5 May 2020 13:10:27 -0400 Subject: [PATCH 04/12] remove unwanted newlines --- qiskit/qobj/converters/pulse_instruction.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/qiskit/qobj/converters/pulse_instruction.py b/qiskit/qobj/converters/pulse_instruction.py index c11d8be90c9d..3b6053095f55 100644 --- a/qiskit/qobj/converters/pulse_instruction.py +++ b/qiskit/qobj/converters/pulse_instruction.py @@ -604,8 +604,6 @@ def convert_delay(self, instruction): duration = instruction.duration return instructions.Delay(duration, channel) << t0 - - @bind_name('pv') def convert_persistent_value(self, instruction): """Return converted `PersistentValueInstruction`. From 2798eeddd7a3db4254fddf0edcaf0c3066d53784 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Tue, 5 May 2020 14:18:40 -0400 Subject: [PATCH 05/12] lint --- test/python/qobj/test_pulse_converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/qobj/test_pulse_converter.py b/test/python/qobj/test_pulse_converter.py index bbf0f333ddac..90e8c68da0a9 100644 --- a/test/python/qobj/test_pulse_converter.py +++ b/test/python/qobj/test_pulse_converter.py @@ -23,7 +23,7 @@ LoConfigConverter) from qiskit.pulse.commands import (SamplePulse, FrameChange, PersistentValue, Snapshot, Acquire, Gaussian, GaussianSquare, Constant, Drag) -from qiskit.pulse.instructions import ShiftPhase, SetFrequency, Play, Delay +from qiskit.pulse.instructions import ShiftPhase, SetFrequency, Play, Delay, ShiftFrequency from qiskit.pulse.channels import (DriveChannel, ControlChannel, MeasureChannel, AcquireChannel, MemorySlot, RegisterSlot) from qiskit.pulse.schedule import ParameterizedSchedule, Schedule From f679b06d8ead9752ae0c963f0bbbc49b2dbc8d0f Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Tue, 5 May 2020 15:06:05 -0400 Subject: [PATCH 06/12] add newline --- qiskit/pulse/instructions/frequency.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qiskit/pulse/instructions/frequency.py b/qiskit/pulse/instructions/frequency.py index f77ccb7edf54..ea8c7abc11a1 100644 --- a/qiskit/pulse/instructions/frequency.py +++ b/qiskit/pulse/instructions/frequency.py @@ -64,6 +64,7 @@ def channel(self) -> PulseChannel: class ShiftFrequency(Instruction): """Shift the channel frequency away from the set frequency.""" + def __init__(self, frequency: float, channel: PulseChannel, name: Optional[str] = None): From 7ecf5ab6be4f22c58b889b1969bfba31b34a4545 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Tue, 5 May 2020 17:43:18 -0400 Subject: [PATCH 07/12] Review suggestions and bugfix --- qiskit/pulse/instructions/frequency.py | 5 +++-- qiskit/qobj/converters/pulse_instruction.py | 8 ++++---- test/python/pulse/test_schedule.py | 5 ++--- test/python/qobj/test_pulse_converter.py | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/qiskit/pulse/instructions/frequency.py b/qiskit/pulse/instructions/frequency.py index ea8c7abc11a1..e5a90ec77cad 100644 --- a/qiskit/pulse/instructions/frequency.py +++ b/qiskit/pulse/instructions/frequency.py @@ -63,9 +63,10 @@ def channel(self) -> PulseChannel: class ShiftFrequency(Instruction): - """Shift the channel frequency away from the set frequency.""" + """Shift the channel frequency away from the current frequency.""" - def __init__(self, frequency: float, + def __init__(self, + frequency: float, channel: PulseChannel, name: Optional[str] = None): """Creates a new shift frequency instruction. diff --git a/qiskit/qobj/converters/pulse_instruction.py b/qiskit/qobj/converters/pulse_instruction.py index 3b6053095f55..4d682c188b3d 100644 --- a/qiskit/qobj/converters/pulse_instruction.py +++ b/qiskit/qobj/converters/pulse_instruction.py @@ -269,7 +269,7 @@ def convert_set_frequency(self, shift, instruction): 'name': 'setf', 't0': shift+instruction.start_time, 'ch': instruction.channel.name, - 'frequency': instruction.frequency + 'frequency': instruction.frequency * 1e9 } return self._qobj_model(**command_dict) @@ -288,7 +288,7 @@ def convert_shift_frequency(self, shift, instruction): 'name': 'shiftf', 't0': shift+instruction.start_time, 'ch': instruction.channel.name, - 'frequency': instruction.frequency + 'frequency': instruction.frequency * 1e9 } return self._qobj_model(**command_dict) @@ -551,7 +551,7 @@ def convert_set_frequency(self, instruction): """ t0 = instruction.t0 channel = self.get_channel(instruction.ch) - frequency = instruction.frequency + frequency = instruction.frequency / 1e9 if isinstance(frequency, str): frequency_expr = parse_string_expr(frequency, partial_binding=False) @@ -576,7 +576,7 @@ def convert_shift_frequency(self, instruction): """ t0 = instruction.t0 channel = self.get_channel(instruction.ch) - frequency = instruction.frequency + frequency = instruction.frequency / 1e9 if isinstance(frequency, str): frequency_expr = parse_string_expr(frequency, partial_binding=False) diff --git a/test/python/pulse/test_schedule.py b/test/python/pulse/test_schedule.py index 4a6ecbb666e7..d592ccdd3083 100644 --- a/test/python/pulse/test_schedule.py +++ b/test/python/pulse/test_schedule.py @@ -684,9 +684,8 @@ def test_filter_inst_types(self): self.assertEqual(len(no_fc.instructions), 7) # test on SetFrequency - only_setf, no_setf = \ - self._filter_and_test_consistency(sched, - instruction_types=[SetFrequency]) + only_setf, no_setf = self._filter_and_test_consistency( + sched, instruction_types=[SetFrequency]) for _, inst in only_setf.instructions: self.assertTrue(isinstance(inst, SetFrequency)) self.assertEqual(len(only_setf.instructions), 1) diff --git a/test/python/qobj/test_pulse_converter.py b/test/python/qobj/test_pulse_converter.py index 90e8c68da0a9..b9dc1b3d0aae 100644 --- a/test/python/qobj/test_pulse_converter.py +++ b/test/python/qobj/test_pulse_converter.py @@ -152,7 +152,7 @@ def test_set_frequency(self): name='setf', ch='d0', t0=0, - frequency=8.0 + frequency=8e9 ) self.assertEqual(converter(0, instruction), valid_qobj) @@ -166,7 +166,7 @@ def test_shift_frequency(self): name='shiftf', ch='d0', t0=0, - frequency=8.0 + frequency=8e9 ) self.assertEqual(converter(0, instruction), valid_qobj) @@ -318,7 +318,7 @@ def test_set_frequency(self): """Test converted qobj from SetFrequency.""" instruction = SetFrequency(8.0, DriveChannel(0)) - qobj = PulseQobjInstruction(name='setf', ch='d0', t0=0, frequency=8.0) + qobj = PulseQobjInstruction(name='setf', ch='d0', t0=0, frequency=8e9) converted_instruction = self.converter(qobj) self.assertEqual(converted_instruction.start_time, 0) @@ -330,7 +330,7 @@ def test_shift_frequency(self): """Test converted qobj from ShiftFrequency.""" instruction = ShiftFrequency(8.0, DriveChannel(0)) - qobj = PulseQobjInstruction(name='shiftf', ch='d0', t0=0, frequency=8.0) + qobj = PulseQobjInstruction(name='shiftf', ch='d0', t0=0, frequency=8e9) converted_instruction = self.converter(qobj) self.assertEqual(converted_instruction.start_time, 0) From 72117001570e32c388a61eadeb4e0076ed331669 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Wed, 6 May 2020 08:16:40 -0400 Subject: [PATCH 08/12] Reno --- .../implement-shift-frequency-46d4ea16d8be2f58.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 releasenotes/notes/implement-shift-frequency-46d4ea16d8be2f58.yaml diff --git a/releasenotes/notes/implement-shift-frequency-46d4ea16d8be2f58.yaml b/releasenotes/notes/implement-shift-frequency-46d4ea16d8be2f58.yaml new file mode 100644 index 000000000000..0dae4a3a2867 --- /dev/null +++ b/releasenotes/notes/implement-shift-frequency-46d4ea16d8be2f58.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + The :py:class:`~qiskit.pulse.instructions.ShiftFrequency` instruction allows users + to shift the frequency from the set frequency. For example:: + + sched += ShiftFrequency(8.0, DriveChannel(0)) + + In this example, all the pulses applied to ``DriveChannel(0)`` after the + ``ShiftFrequency`` command will have a frequency of 8.0 Hz. From b6d5e8457844a1ee1074b52a4d2539c4f4138858 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Wed, 6 May 2020 08:24:00 -0400 Subject: [PATCH 09/12] Hz -> GHz conversion for ShiftFrequency -> PulseQobjInstruction --- qiskit/qobj/converters/pulse_instruction.py | 4 ++-- test/python/qobj/test_pulse_converter.py | 4 ++-- test/python/qobj/test_qobj.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qiskit/qobj/converters/pulse_instruction.py b/qiskit/qobj/converters/pulse_instruction.py index 4d682c188b3d..edc34699a01b 100644 --- a/qiskit/qobj/converters/pulse_instruction.py +++ b/qiskit/qobj/converters/pulse_instruction.py @@ -269,7 +269,7 @@ def convert_set_frequency(self, shift, instruction): 'name': 'setf', 't0': shift+instruction.start_time, 'ch': instruction.channel.name, - 'frequency': instruction.frequency * 1e9 + 'frequency': instruction.frequency } return self._qobj_model(**command_dict) @@ -551,7 +551,7 @@ def convert_set_frequency(self, instruction): """ t0 = instruction.t0 channel = self.get_channel(instruction.ch) - frequency = instruction.frequency / 1e9 + frequency = instruction.frequency if isinstance(frequency, str): frequency_expr = parse_string_expr(frequency, partial_binding=False) diff --git a/test/python/qobj/test_pulse_converter.py b/test/python/qobj/test_pulse_converter.py index b9dc1b3d0aae..a659cf6c6893 100644 --- a/test/python/qobj/test_pulse_converter.py +++ b/test/python/qobj/test_pulse_converter.py @@ -152,7 +152,7 @@ def test_set_frequency(self): name='setf', ch='d0', t0=0, - frequency=8e9 + frequency=8.0 ) self.assertEqual(converter(0, instruction), valid_qobj) @@ -318,7 +318,7 @@ def test_set_frequency(self): """Test converted qobj from SetFrequency.""" instruction = SetFrequency(8.0, DriveChannel(0)) - qobj = PulseQobjInstruction(name='setf', ch='d0', t0=0, frequency=8e9) + qobj = PulseQobjInstruction(name='setf', ch='d0', t0=0, frequency=8.0) converted_instruction = self.converter(qobj) self.assertEqual(converted_instruction.start_time, 0) diff --git a/test/python/qobj/test_qobj.py b/test/python/qobj/test_qobj.py index bb26e2f00356..4da3fbf1ef2c 100644 --- a/test/python/qobj/test_qobj.py +++ b/test/python/qobj/test_qobj.py @@ -232,7 +232,7 @@ def setUp(self): PulseQobjInstruction(name='pv', t0=10, ch='d0', val=0.1 + 0.0j), PulseQobjInstruction(name='pv', t0=10, ch='d0', val='P1'), PulseQobjInstruction(name='setf', t0=10, ch='d0', frequency=8.), - PulseQobjInstruction(name='shiftf', t0=10, ch='d0', frequency=4.0), + PulseQobjInstruction(name='shiftf', t0=10, ch='d0', frequency=4e9), PulseQobjInstruction(name='acquire', t0=15, duration=5, qubits=[0], memory_slot=[0], kernels=[ @@ -267,7 +267,7 @@ def setUp(self): {'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 0.1+0j}, {'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 'P1'}, {'name': 'setf', 't0': 10, 'ch': 'd0', 'frequency': 8.0}, - {'name': 'shiftf', 't0': 10, 'ch': 'd0', 'frequency': 4.0}, + {'name': 'shiftf', 't0': 10, 'ch': 'd0', 'frequency': 4e9}, {'name': 'acquire', 't0': 15, 'duration': 5, 'qubits': [0], 'memory_slot': [0], 'kernels': [{'name': 'boxcar', From 65c75d4b6504483821c6cc01725ab0827e3e6bfc Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Wed, 6 May 2020 12:06:54 -0400 Subject: [PATCH 10/12] Logic fixes --- qiskit/qobj/converters/pulse_instruction.py | 4 ++-- test/python/qobj/test_pulse_converter.py | 4 ++-- test/python/qobj/test_qobj.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qiskit/qobj/converters/pulse_instruction.py b/qiskit/qobj/converters/pulse_instruction.py index edc34699a01b..cb3bcffa3dce 100644 --- a/qiskit/qobj/converters/pulse_instruction.py +++ b/qiskit/qobj/converters/pulse_instruction.py @@ -288,7 +288,7 @@ def convert_shift_frequency(self, shift, instruction): 'name': 'shiftf', 't0': shift+instruction.start_time, 'ch': instruction.channel.name, - 'frequency': instruction.frequency * 1e9 + 'frequency': instruction.frequency / 1e9 } return self._qobj_model(**command_dict) @@ -576,7 +576,7 @@ def convert_shift_frequency(self, instruction): """ t0 = instruction.t0 channel = self.get_channel(instruction.ch) - frequency = instruction.frequency / 1e9 + frequency = instruction.frequency * 1e9 if isinstance(frequency, str): frequency_expr = parse_string_expr(frequency, partial_binding=False) diff --git a/test/python/qobj/test_pulse_converter.py b/test/python/qobj/test_pulse_converter.py index a659cf6c6893..8e2eebd73726 100644 --- a/test/python/qobj/test_pulse_converter.py +++ b/test/python/qobj/test_pulse_converter.py @@ -166,7 +166,7 @@ def test_shift_frequency(self): name='shiftf', ch='d0', t0=0, - frequency=8e9 + frequency=8e-9 ) self.assertEqual(converter(0, instruction), valid_qobj) @@ -330,7 +330,7 @@ def test_shift_frequency(self): """Test converted qobj from ShiftFrequency.""" instruction = ShiftFrequency(8.0, DriveChannel(0)) - qobj = PulseQobjInstruction(name='shiftf', ch='d0', t0=0, frequency=8e9) + qobj = PulseQobjInstruction(name='shiftf', ch='d0', t0=0, frequency=8e-9) converted_instruction = self.converter(qobj) self.assertEqual(converted_instruction.start_time, 0) diff --git a/test/python/qobj/test_qobj.py b/test/python/qobj/test_qobj.py index 4da3fbf1ef2c..5a6cdd0f72f0 100644 --- a/test/python/qobj/test_qobj.py +++ b/test/python/qobj/test_qobj.py @@ -232,7 +232,7 @@ def setUp(self): PulseQobjInstruction(name='pv', t0=10, ch='d0', val=0.1 + 0.0j), PulseQobjInstruction(name='pv', t0=10, ch='d0', val='P1'), PulseQobjInstruction(name='setf', t0=10, ch='d0', frequency=8.), - PulseQobjInstruction(name='shiftf', t0=10, ch='d0', frequency=4e9), + PulseQobjInstruction(name='shiftf', t0=10, ch='d0', frequency=4e-9), PulseQobjInstruction(name='acquire', t0=15, duration=5, qubits=[0], memory_slot=[0], kernels=[ @@ -267,7 +267,7 @@ def setUp(self): {'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 0.1+0j}, {'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 'P1'}, {'name': 'setf', 't0': 10, 'ch': 'd0', 'frequency': 8.0}, - {'name': 'shiftf', 't0': 10, 'ch': 'd0', 'frequency': 4e9}, + {'name': 'shiftf', 't0': 10, 'ch': 'd0', 'frequency': 4e-9}, {'name': 'acquire', 't0': 15, 'duration': 5, 'qubits': [0], 'memory_slot': [0], 'kernels': [{'name': 'boxcar', From efd2ebaa4456ecc73d8d8324cfbedc629112fc68 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Fri, 8 May 2020 15:17:08 -0400 Subject: [PATCH 11/12] review suggestion --- test/python/qobj/test_pulse_converter.py | 8 ++++---- test/python/qobj/test_qobj.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/python/qobj/test_pulse_converter.py b/test/python/qobj/test_pulse_converter.py index 8e2eebd73726..9776160ce5ac 100644 --- a/test/python/qobj/test_pulse_converter.py +++ b/test/python/qobj/test_pulse_converter.py @@ -160,13 +160,13 @@ def test_set_frequency(self): def test_shift_frequency(self): """Test converted qobj from ShiftFrequency.""" converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) - instruction = ShiftFrequency(8.0, DriveChannel(0)) + instruction = ShiftFrequency(8e9, DriveChannel(0)) valid_qobj = PulseQobjInstruction( name='shiftf', ch='d0', t0=0, - frequency=8e-9 + frequency=8.0 ) self.assertEqual(converter(0, instruction), valid_qobj) @@ -328,9 +328,9 @@ def test_set_frequency(self): def test_shift_frequency(self): """Test converted qobj from ShiftFrequency.""" - instruction = ShiftFrequency(8.0, DriveChannel(0)) + instruction = ShiftFrequency(8e9, DriveChannel(0)) - qobj = PulseQobjInstruction(name='shiftf', ch='d0', t0=0, frequency=8e-9) + qobj = PulseQobjInstruction(name='shiftf', ch='d0', t0=0, frequency=8.0) converted_instruction = self.converter(qobj) self.assertEqual(converted_instruction.start_time, 0) diff --git a/test/python/qobj/test_qobj.py b/test/python/qobj/test_qobj.py index 5a6cdd0f72f0..bb26e2f00356 100644 --- a/test/python/qobj/test_qobj.py +++ b/test/python/qobj/test_qobj.py @@ -232,7 +232,7 @@ def setUp(self): PulseQobjInstruction(name='pv', t0=10, ch='d0', val=0.1 + 0.0j), PulseQobjInstruction(name='pv', t0=10, ch='d0', val='P1'), PulseQobjInstruction(name='setf', t0=10, ch='d0', frequency=8.), - PulseQobjInstruction(name='shiftf', t0=10, ch='d0', frequency=4e-9), + PulseQobjInstruction(name='shiftf', t0=10, ch='d0', frequency=4.0), PulseQobjInstruction(name='acquire', t0=15, duration=5, qubits=[0], memory_slot=[0], kernels=[ @@ -267,7 +267,7 @@ def setUp(self): {'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 0.1+0j}, {'name': 'pv', 't0': 10, 'ch': 'd0', 'val': 'P1'}, {'name': 'setf', 't0': 10, 'ch': 'd0', 'frequency': 8.0}, - {'name': 'shiftf', 't0': 10, 'ch': 'd0', 'frequency': 4e-9}, + {'name': 'shiftf', 't0': 10, 'ch': 'd0', 'frequency': 4.0}, {'name': 'acquire', 't0': 15, 'duration': 5, 'qubits': [0], 'memory_slot': [0], 'kernels': [{'name': 'boxcar', From 1ba4b5b9d26a151fdfc466184f958ecebadad1c8 Mon Sep 17 00:00:00 2001 From: SooluThomas Date: Mon, 11 May 2020 13:08:27 -0400 Subject: [PATCH 12/12] review suggestions --- .../notes/implement-shift-frequency-46d4ea16d8be2f58.yaml | 4 ++-- test/python/pulse/test_schedule.py | 2 +- test/python/qobj/test_pulse_converter.py | 4 ++-- test/python/visualization/test_pulse_visualization_output.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/releasenotes/notes/implement-shift-frequency-46d4ea16d8be2f58.yaml b/releasenotes/notes/implement-shift-frequency-46d4ea16d8be2f58.yaml index 0dae4a3a2867..c5e264ab3c74 100644 --- a/releasenotes/notes/implement-shift-frequency-46d4ea16d8be2f58.yaml +++ b/releasenotes/notes/implement-shift-frequency-46d4ea16d8be2f58.yaml @@ -4,7 +4,7 @@ features: The :py:class:`~qiskit.pulse.instructions.ShiftFrequency` instruction allows users to shift the frequency from the set frequency. For example:: - sched += ShiftFrequency(8.0, DriveChannel(0)) + sched += ShiftFrequency(-340e6, DriveChannel(0)) In this example, all the pulses applied to ``DriveChannel(0)`` after the - ``ShiftFrequency`` command will have a frequency of 8.0 Hz. + ``ShiftFrequency`` command will have the envelope a frequency decremented by 340MHz. diff --git a/test/python/pulse/test_schedule.py b/test/python/pulse/test_schedule.py index d592ccdd3083..49a6960ad829 100644 --- a/test/python/pulse/test_schedule.py +++ b/test/python/pulse/test_schedule.py @@ -653,7 +653,7 @@ def test_filter_inst_types(self): sched = sched.insert(10, Play(lp0, self.config.drive(1))) sched = sched.insert(30, ShiftPhase(-1.57, self.config.drive(0))) sched = sched.insert(40, SetFrequency(8.0, self.config.drive(0))) - sched = sched.insert(50, ShiftFrequency(4.0, self.config.drive(0))) + sched = sched.insert(50, ShiftFrequency(4.0e6, self.config.drive(0))) for i in range(2): sched = sched.insert(60, Acquire(5, self.config.acquire(i), MemorySlot(i))) sched = sched.insert(90, Play(lp0, self.config.drive(0))) diff --git a/test/python/qobj/test_pulse_converter.py b/test/python/qobj/test_pulse_converter.py index 9776160ce5ac..3c86ce7ab810 100644 --- a/test/python/qobj/test_pulse_converter.py +++ b/test/python/qobj/test_pulse_converter.py @@ -160,7 +160,7 @@ def test_set_frequency(self): def test_shift_frequency(self): """Test converted qobj from ShiftFrequency.""" converter = InstructionToQobjConverter(PulseQobjInstruction, meas_level=2) - instruction = ShiftFrequency(8e9, DriveChannel(0)) + instruction = ShiftFrequency(8.0e9, DriveChannel(0)) valid_qobj = PulseQobjInstruction( name='shiftf', @@ -328,7 +328,7 @@ def test_set_frequency(self): def test_shift_frequency(self): """Test converted qobj from ShiftFrequency.""" - instruction = ShiftFrequency(8e9, DriveChannel(0)) + instruction = ShiftFrequency(8.0e9, DriveChannel(0)) qobj = PulseQobjInstruction(name='shiftf', ch='d0', t0=0, frequency=8.0) converted_instruction = self.converter(qobj) diff --git a/test/python/visualization/test_pulse_visualization_output.py b/test/python/visualization/test_pulse_visualization_output.py index 90e62b21e91b..24761c7bb3c5 100644 --- a/test/python/visualization/test_pulse_visualization_output.py +++ b/test/python/visualization/test_pulse_visualization_output.py @@ -68,7 +68,7 @@ def sample_schedule(self): ControlChannel(0))) sched = sched.insert(60, FrameChange(phase=-1.57)(DriveChannel(0))) sched = sched.insert(60, SetFrequency(8.0, DriveChannel(0))) - sched = sched.insert(70, ShiftFrequency(4.0, DriveChannel(0))) + sched = sched.insert(70, ShiftFrequency(4.0e6, DriveChannel(0))) sched = sched.insert(30, gp1(DriveChannel(1))) sched = sched.insert(60, gp0(ControlChannel(0))) sched = sched.insert(60, gs0(MeasureChannel(0)))