mirror of https://github.com/Qiskit/qiskit.git
Add argument to ignore framechange only channels for schedules drawing (#3441)
* use update method of set() for readability * Add unittest test_schedule_matplotlib_drawer_show_framechange * Style and Lint * Style and Lint
This commit is contained in:
parent
bab3a8e553
commit
6f565d4741
|
@ -363,7 +363,8 @@ class Schedule(ScheduleComponent):
|
|||
scaling: float = None, channels_to_plot: Optional[List[Channel]] = None,
|
||||
plot_all: bool = False, plot_range: Optional[Tuple[float]] = None,
|
||||
interactive: bool = False, table: bool = True, label: bool = False,
|
||||
framechange: bool = True, channels: Optional[List[Channel]] = None):
|
||||
framechange: bool = True, channels: Optional[List[Channel]] = None,
|
||||
show_framechange_channels: bool = True):
|
||||
"""Plot the schedule.
|
||||
|
||||
Args:
|
||||
|
@ -381,6 +382,7 @@ class Schedule(ScheduleComponent):
|
|||
label: Label individual instructions
|
||||
framechange: Add framechange indicators
|
||||
channels: A list of channel names to plot
|
||||
show_framechange_channels: Plot channels with only framechanges
|
||||
|
||||
Returns:
|
||||
matplotlib.figure: A matplotlib figure object of the pulse schedule.
|
||||
|
@ -399,7 +401,8 @@ class Schedule(ScheduleComponent):
|
|||
scaling=scaling, plot_all=plot_all,
|
||||
plot_range=plot_range, interactive=interactive,
|
||||
table=table, label=label,
|
||||
framechange=framechange, channels=channels)
|
||||
framechange=framechange, channels=channels,
|
||||
show_framechange_channels=show_framechange_channels)
|
||||
|
||||
def __eq__(self, other: ScheduleComponent) -> bool:
|
||||
"""Test if two ScheduleComponents are equal.
|
||||
|
|
|
@ -34,6 +34,7 @@ from qiskit.pulse.channels import (DriveChannel, ControlChannel,
|
|||
SnapshotChannel)
|
||||
from qiskit.pulse import (SamplePulse, FrameChange, PersistentValue, Snapshot,
|
||||
Acquire, PulseError)
|
||||
from qiskit.pulse.commands.frame_change import FrameChangeInstruction
|
||||
|
||||
|
||||
class EventsOutputChannels:
|
||||
|
@ -281,17 +282,23 @@ class ScheduleDrawer:
|
|||
"""
|
||||
self.style = style or SchedStyle()
|
||||
|
||||
def _build_channels(self, schedule, channels, t0, tf):
|
||||
def _build_channels(self, schedule, channels, t0, tf, show_framechange_channels=True):
|
||||
# prepare waveform channels
|
||||
drive_channels = collections.OrderedDict()
|
||||
measure_channels = collections.OrderedDict()
|
||||
control_channels = collections.OrderedDict()
|
||||
acquire_channels = collections.OrderedDict()
|
||||
snapshot_channels = collections.OrderedDict()
|
||||
_channels = set()
|
||||
if show_framechange_channels:
|
||||
_channels.update(schedule.channels)
|
||||
# take channels that do not only contain framechanges
|
||||
else:
|
||||
for start_time, instruction in schedule.instructions:
|
||||
if not isinstance(instruction, FrameChangeInstruction):
|
||||
_channels.update(instruction.channels)
|
||||
|
||||
_channels = list(schedule.channels) + channels
|
||||
_channels = list(set(_channels))
|
||||
|
||||
_channels.update(channels)
|
||||
for chan in _channels:
|
||||
if isinstance(chan, DriveChannel):
|
||||
try:
|
||||
|
@ -550,7 +557,7 @@ class ScheduleDrawer:
|
|||
def draw(self, schedule, dt, interp_method, plot_range,
|
||||
scaling=None, channels_to_plot=None, plot_all=True,
|
||||
table=True, label=False, framechange=True,
|
||||
channels=None):
|
||||
channels=None, show_framechange_channels=True):
|
||||
"""Draw figure.
|
||||
|
||||
Args:
|
||||
|
@ -566,6 +573,7 @@ class ScheduleDrawer:
|
|||
label (bool): Label individual instructions
|
||||
framechange (bool): Add framechange indicators
|
||||
channels (list[OutputChannel]): channels to draw
|
||||
show_framechange_channels (bool): Plot channels with only framechanges
|
||||
|
||||
Returns:
|
||||
matplotlib.figure: A matplotlib figure object for the pulse schedule
|
||||
|
@ -600,7 +608,8 @@ class ScheduleDrawer:
|
|||
|
||||
# prepare waveform channels
|
||||
(schedule_channels, output_channels,
|
||||
snapshot_channels) = self._build_channels(schedule, channels, t0, tf)
|
||||
snapshot_channels) = self._build_channels(schedule, channels, t0, tf,
|
||||
show_framechange_channels)
|
||||
|
||||
# count numbers of valid waveform
|
||||
n_valid_waveform, v_max = self._count_valid_waveforms(output_channels, scaling=scaling,
|
||||
|
|
|
@ -31,7 +31,7 @@ def pulse_drawer(data, dt=1, style=None, filename=None,
|
|||
interp_method=None, scaling=None, channels_to_plot=None,
|
||||
plot_all=False, plot_range=None, interactive=False,
|
||||
table=True, label=False, framechange=True,
|
||||
channels=None):
|
||||
channels=None, show_framechange_channels=True):
|
||||
"""Plot the interpolated envelope of pulse
|
||||
|
||||
Args:
|
||||
|
@ -52,6 +52,7 @@ def pulse_drawer(data, dt=1, style=None, filename=None,
|
|||
label (bool): Label individual instructions
|
||||
framechange (bool): Add framechange indicators
|
||||
channels (list): A list of channel names to plot
|
||||
show_framechange_channels (bool): Plot channels with only framechanges
|
||||
|
||||
Returns:
|
||||
matplotlib.figure: A matplotlib figure object for the pulse envelope
|
||||
|
@ -74,7 +75,8 @@ def pulse_drawer(data, dt=1, style=None, filename=None,
|
|||
drawer = _matplotlib.ScheduleDrawer(style=style)
|
||||
image = drawer.draw(data, dt=dt, interp_method=interp_method, scaling=scaling,
|
||||
plot_range=plot_range, plot_all=plot_all, table=table,
|
||||
label=label, framechange=framechange, channels=channels)
|
||||
label=label, framechange=framechange, channels=channels,
|
||||
show_framechange_channels=show_framechange_channels)
|
||||
else:
|
||||
raise VisualizationError('This data cannot be visualized.')
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
|
@ -35,6 +35,7 @@ class TestPulseVisualizationImplementation(QiskitVisualizationTestCase):
|
|||
pulse_matplotlib_reference = path_to_diagram_reference('pulse_matplotlib_ref.png')
|
||||
instr_matplotlib_reference = path_to_diagram_reference('instruction_matplotlib_ref.png')
|
||||
schedule_matplotlib_reference = path_to_diagram_reference('schedule_matplotlib_ref.png')
|
||||
schedule_show_framechange_ref = path_to_diagram_reference('schedule_show_framechange_ref.png')
|
||||
|
||||
def setUp(self):
|
||||
self.schedule = Schedule()
|
||||
|
@ -120,6 +121,22 @@ class TestPulseVisualizationImplementation(QiskitVisualizationTestCase):
|
|||
# Check ValueError is not thrown
|
||||
sched.draw(plot_range=(0, 15))
|
||||
|
||||
# TODO: Enable for refactoring purposes and enable by default when we can
|
||||
# decide if the backend is available or not.
|
||||
@unittest.skipIf(not HAS_MATPLOTLIB, 'matplotlib not available.')
|
||||
@unittest.skip('Useful for refactoring purposes, skipping by default.')
|
||||
def test_schedule_drawer_show_framechange(self):
|
||||
filename = self._get_resource_path('current_show_framechange_ref.png')
|
||||
gp0 = pulse_lib.gaussian(duration=20, amp=1.0, sigma=1.0)
|
||||
sched = Schedule()
|
||||
sched = sched.append(gp0(DriveChannel(0)))
|
||||
sched = sched.insert(60, FrameChange(phase=-1.57)(DriveChannel(0)))
|
||||
sched = sched.insert(30, FrameChange(phase=-1.50)(DriveChannel(1)))
|
||||
sched = sched.insert(70, FrameChange(phase=1.50)(DriveChannel(1)))
|
||||
pulse_drawer(sched, filename=filename, show_framechange_channels=False)
|
||||
self.assertImagesAreEqual(filename, self.schedule_show_framechange_ref)
|
||||
os.remove(filename)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
||||
|
|
Loading…
Reference in New Issue