# This code is part of Qiskit.
#
# (C) Copyright IBM 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
r"""
Stylesheet for pulse drawer.
The stylesheet `QiskitPulseStyle` is initialized with the hard-corded default values in
`default_style`. This instance is generated when the pulse drawer module is loaded so that
every lower modules can access to the information.
The `QiskitPulseStyle` is a wrapper class of python dictionary with the structured keys
such as `formatter.color.fill_waveform_d` to represent a color code of the drive channel.
This key representation and initialization framework are the imitative of
`rcParams` of `matplotlib`. However, the `QiskitPulseStyle` is not compatible with the `rcParams`
because the pulse stylesheet is heavily specialized to the context of the pulse program.
The settings of stylesheet are broadly separated into `formatter`, `generator` and `layout`.
The formatter is a nested dictionary of drawing parameters to control the appearance of
each visualization element. This takes similar data structure to the `rcParams` of `matplotlib`.
The generator is a list of callback functions that generates drawing objects from
given program and device data. The layout is a callback function that determines
the appearance of the output image.
"""
import warnings
from typing import Dict, Any, Mapping
from qiskit.visualization.pulse_v2 import generators, layouts
class QiskitPulseStyle(dict):
"""Stylesheet for pulse drawer."""
_deprecated_keys = {}
def __init__(self):
super().__init__()
# to inform which stylesheet is applied. some plotter may not support specific style.
self.stylesheet = None
self.update(default_style())
def update(self, __m: Mapping[str, Any], **kwargs) -> None:
super().update(__m, **kwargs)
for key, value in __m.items():
if key in self._deprecated_keys:
warnings.warn(
f"{key} is deprecated. Use {self._deprecated_keys[key]} instead.",
DeprecationWarning,
)
self.__setitem__(self._deprecated_keys[key], value)
else:
self.__setitem__(key, value)
self.stylesheet = __m.__class__.__name__
@property
def formatter(self):
"""Return formatter field of style dictionary."""
sub_dict = {}
for key, value in self.items():
sub_keys = key.split(".")
if sub_keys[0] == "formatter":
sub_dict[".".join(sub_keys[1:])] = value
return sub_dict
@property
def generator(self):
"""Return generator field of style dictionary."""
sub_dict = {}
for key, value in self.items():
sub_keys = key.split(".")
if sub_keys[0] == "generator":
sub_dict[".".join(sub_keys[1:])] = value
return sub_dict
@property
def layout(self):
"""Return layout field of style dictionary."""
sub_dict = {}
for key, value in self.items():
sub_keys = key.split(".")
if sub_keys[0] == "layout":
sub_dict[".".join(sub_keys[1:])] = value
return sub_dict
[ドキュメント]class IQXStandard(dict):
"""Standard pulse stylesheet.
- Generate stepwise waveform envelope with latex pulse names.
- Apply phase modulation to waveforms.
- Plot frame change symbol with formatted operand values.
- Show chart name with scaling factor.
- Show snapshot and barrier.
- Do not show acquire channels.
- Channels are sorted by index and control channels are added to the end.
"""
def __init__(self, **kwargs):
super().__init__()
style = {
"formatter.control.apply_phase_modulation": True,
"formatter.control.show_snapshot_channel": True,
"formatter.control.show_acquire_channel": False,
"formatter.control.show_empty_channel": False,
"formatter.control.auto_chart_scaling": True,
"formatter.control.axis_break": True,
"generator.waveform": [
generators.gen_filled_waveform_stepwise,
generators.gen_ibmq_latex_waveform_name,
],
"generator.frame": [generators.gen_frame_symbol, generators.gen_formatted_frame_values],
"generator.chart": [
generators.gen_chart_name,
generators.gen_baseline,
generators.gen_channel_freqs,
],
"generator.snapshot": [generators.gen_snapshot_symbol],
"generator.barrier": [generators.gen_barrier],
"layout.chart_channel_map": layouts.channel_index_grouped_sort_u,
"layout.time_axis_map": layouts.time_map_in_ns,
"layout.figure_title": layouts.detail_title,
}
style.update(**kwargs)
self.update(style)
def __repr__(self):
return "Standard Pulse style sheet."
[ドキュメント]class IQXSimple(dict):
"""Simple pulse stylesheet without channel notation.
- Generate stepwise waveform envelope with latex pulse names.
- Apply phase modulation to waveforms.
- Do not show frame changes.
- Show chart name.
- Do not show snapshot and barrier.
- Do not show acquire channels.
- Channels are sorted by qubit index.
"""
def __init__(self, **kwargs):
super().__init__()
style = {
"formatter.general.fig_chart_height": 5,
"formatter.control.apply_phase_modulation": True,
"formatter.control.show_snapshot_channel": True,
"formatter.control.show_acquire_channel": False,
"formatter.control.show_empty_channel": False,
"formatter.control.auto_chart_scaling": False,
"formatter.control.axis_break": True,
"generator.waveform": [
generators.gen_filled_waveform_stepwise,
generators.gen_ibmq_latex_waveform_name,
],
"generator.frame": [],
"generator.chart": [generators.gen_chart_name, generators.gen_baseline],
"generator.snapshot": [],
"generator.barrier": [],
"layout.chart_channel_map": layouts.qubit_index_sort,
"layout.time_axis_map": layouts.time_map_in_ns,
"layout.figure_title": layouts.empty_title,
}
style.update(**kwargs)
self.update(style)
def __repr__(self):
return "Simple pulse style sheet for publication."
[ドキュメント]class IQXDebugging(dict):
"""Pulse stylesheet for pulse programmers. Show details of instructions.
# TODO: add more generators
- Generate stepwise waveform envelope with latex pulse names.
- Generate annotation for waveform height.
- Apply phase modulation to waveforms.
- Plot frame change symbol with raw operand values.
- Show chart name and channel frequency.
- Show snapshot and barrier.
- Show acquire channels.
- Channels are sorted by index and control channels are added to the end.
"""
def __init__(self, **kwargs):
super().__init__()
style = {
"formatter.control.apply_phase_modulation": True,
"formatter.control.show_snapshot_channel": True,
"formatter.control.show_acquire_channel": True,
"formatter.control.show_empty_channel": False,
"formatter.control.auto_chart_scaling": True,
"formatter.control.axis_break": True,
"generator.waveform": [
generators.gen_filled_waveform_stepwise,
generators.gen_ibmq_latex_waveform_name,
generators.gen_waveform_max_value,
],
"generator.frame": [
generators.gen_frame_symbol,
generators.gen_raw_operand_values_compact,
],
"generator.chart": [
generators.gen_chart_name,
generators.gen_baseline,
generators.gen_channel_freqs,
],
"generator.snapshot": [generators.gen_snapshot_symbol, generators.gen_snapshot_name],
"generator.barrier": [generators.gen_barrier],
"layout.chart_channel_map": layouts.channel_index_grouped_sort_u,
"layout.time_axis_map": layouts.time_map_in_ns,
"layout.figure_title": layouts.detail_title,
}
style.update(**kwargs)
self.update(style)
def __repr__(self):
return "Pulse style sheet for pulse programmers."
def default_style() -> Dict[str, Any]:
"""Define default values of the pulse stylesheet."""
return {
"formatter.general.fig_width": 13,
"formatter.general.fig_chart_height": 1.5,
"formatter.general.vertical_resolution": 1e-6,
"formatter.general.max_scale": 100,
"formatter.color.waveforms": {
"W": ["#648fff", "#002999"],
"D": ["#648fff", "#002999"],
"U": ["#ffb000", "#994A00"],
"M": ["#dc267f", "#760019"],
"A": ["#dc267f", "#760019"],
},
"formatter.color.baseline": "#000000",
"formatter.color.barrier": "#222222",
"formatter.color.background": "#f2f3f4",
"formatter.color.fig_title": "#000000",
"formatter.color.annotate": "#222222",
"formatter.color.frame_change": "#000000",
"formatter.color.snapshot": "#000000",
"formatter.color.axis_label": "#000000",
"formatter.color.opaque_shape": ["#f2f3f4", "#000000"],
"formatter.alpha.fill_waveform": 0.3,
"formatter.alpha.baseline": 1.0,
"formatter.alpha.barrier": 0.7,
"formatter.alpha.opaque_shape": 0.7,
"formatter.layer.fill_waveform": 2,
"formatter.layer.baseline": 1,
"formatter.layer.barrier": 1,
"formatter.layer.annotate": 5,
"formatter.layer.axis_label": 5,
"formatter.layer.frame_change": 4,
"formatter.layer.snapshot": 3,
"formatter.layer.fig_title": 6,
"formatter.margin.top": 0.5,
"formatter.margin.bottom": 0.5,
"formatter.margin.left_percent": 0.05,
"formatter.margin.right_percent": 0.05,
"formatter.margin.between_channel": 0.5,
"formatter.label_offset.pulse_name": 0.3,
"formatter.label_offset.chart_info": 0.3,
"formatter.label_offset.frame_change": 0.3,
"formatter.label_offset.snapshot": 0.3,
"formatter.text_size.axis_label": 15,
"formatter.text_size.annotate": 12,
"formatter.text_size.frame_change": 20,
"formatter.text_size.snapshot": 20,
"formatter.text_size.fig_title": 15,
"formatter.text_size.axis_break_symbol": 15,
"formatter.line_width.fill_waveform": 0,
"formatter.line_width.axis_break": 6,
"formatter.line_width.baseline": 1,
"formatter.line_width.barrier": 1,
"formatter.line_width.opaque_shape": 1,
"formatter.line_style.fill_waveform": "-",
"formatter.line_style.baseline": "-",
"formatter.line_style.barrier": ":",
"formatter.line_style.opaque_shape": "--",
"formatter.channel_scaling.drive": 1.0,
"formatter.channel_scaling.control": 1.0,
"formatter.channel_scaling.measure": 1.0,
"formatter.channel_scaling.acquire": 1.0,
"formatter.channel_scaling.pos_spacing": 0.1,
"formatter.channel_scaling.neg_spacing": -0.1,
"formatter.box_width.opaque_shape": 150,
"formatter.box_height.opaque_shape": 0.5,
"formatter.axis_break.length": 3000,
"formatter.axis_break.max_length": 1000,
"formatter.control.fill_waveform": True,
"formatter.control.apply_phase_modulation": True,
"formatter.control.show_snapshot_channel": True,
"formatter.control.show_acquire_channel": True,
"formatter.control.show_empty_channel": True,
"formatter.control.auto_chart_scaling": True,
"formatter.control.axis_break": True,
"formatter.unicode_symbol.frame_change": "\u21BA",
"formatter.unicode_symbol.snapshot": "\u21AF",
"formatter.unicode_symbol.phase_parameter": "\u03b8",
"formatter.unicode_symbol.freq_parameter": "f",
"formatter.latex_symbol.frame_change": r"\circlearrowleft",
"formatter.latex_symbol.snapshot": "",
"formatter.latex_symbol.phase_parameter": r"\theta",
"formatter.latex_symbol.freq_parameter": "f",
"generator.waveform": [],
"generator.frame": [],
"generator.chart": [],
"generator.snapshot": [],
"generator.barrier": [],
"layout.chart_channel_map": None,
"layout.time_axis_map": None,
"layout.figure_title": None,
}