Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions src/qce_circuit/structure/circuit_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,123 @@ def apply_flatten_to_self(self) -> ICircuitOperation:
# endregion


@dataclass(frozen=False, unsafe_hash=True)
class VirtualWait(SingleQubitOperation, ICircuitOperation):
"""
Virtual wait position (behaves as Wait).
Allow to wait on specific (qubit) channel.
Intended to display wait time.
"""
duration_strategy: IDurationStrategy = field(init=False, default=GlobalDurationStrategy(GlobalRegistryKey.MICROWAVE))
qubit_channel: QubitChannel = field(init=True, default=QubitChannel.ALL)
header_text: str = field(init=True, default="W")
body_text: str = field(init=True, default="")

# region Interface Properties
@property
def channel_identifiers(self) -> List[ChannelIdentifier]:
""":return: Array-like of channel identifiers to which this operation applies to."""
return [
ChannelIdentifier(_id=self.qubit_index, _channel=self.qubit_channel),
]
# endregion

# region Interface Methods
def copy(self, relation_transfer_lookup: Optional[Dict[ICircuitOperation, ICircuitOperation]] = None) -> 'VirtualWait':
"""
Creates a copy from self. Excluding any relation details.
:param relation_transfer_lookup: Lookup table used to transfer relation link.
:return: Copy of self with updated relation link.
"""
return VirtualWait(
qubit_index=self.qubit_index,
relation=self.relation.copy(relation_transfer_lookup=relation_transfer_lookup),
qubit_channel=self.qubit_channel,
header_text=self.header_text,
body_text=self.body_text,
)
# endregion


@dataclass(frozen=False, unsafe_hash=True)
class VirtualColorOverwrite(ICircuitOperation):
"""
Data class, containing single-qubit operation.
Acts as a visualization wrapper for coloring visualization.
"""
operation: SingleQubitOperation
color_overwrite: str = field(init=True, default="k")

# region Interface Properties
@property
def channel_identifiers(self) -> List[ChannelIdentifier]:
""":return: Array-like of channel identifiers to which this operation applies to."""
return self.operation.channel_identifiers

@property
def nr_of_repetitions(self) -> int:
""":return: Number of repetitions for this object."""
return self.operation.nr_of_repetitions

@property
def relation_link(self) -> IRelationLink[ICircuitOperation]:
""":return: Description of relation to other circuit node."""
return self.operation.relation

@relation_link.setter
def relation_link(self, link: IRelationLink[ICircuitOperation]):
""":sets: Description of relation to other circuit node."""
self.operation.relation = link

@property
def start_time(self) -> float:
""":return: Start time [a.u.]."""
return self.operation.start_time

@property
def duration(self) -> float:
""":return: Duration [ns]."""
return self.operation.duration
# endregion

# region Interface Methods
def copy(self, relation_transfer_lookup: Optional[Dict[ICircuitOperation, ICircuitOperation]] = None) -> 'VirtualColorOverwrite':
"""
Creates a copy from self. Excluding any relation details.
:param relation_transfer_lookup: Lookup table used to transfer relation link.
:return: Copy of self with updated relation link.
"""
return VirtualColorOverwrite(
operation=self.operation.copy(
relation_transfer_lookup=relation_transfer_lookup,
)
)

def apply_modifiers_to_self(self) -> ICircuitOperation:
"""
WARNING: Applies modifiers inplace.
Applies modifiers such as repetition and state-control.
:return: Modified self.
"""
return self

def decomposed_operations(self) -> List[ICircuitOperation]:
"""
Functions similar to a 'flatten' operation.
Mostly intended for composite-operations such that they can apply repetition and state-dependent registries.
:return: Array-like of decomposed operations.
"""
return [self]

def apply_flatten_to_self(self) -> ICircuitOperation:
"""
WARNING: Applies a flatten modification inplace.
:return: Modified self.
"""
return self
# endregion


if __name__ == '__main__':
from qce_circuit.structure.registry_duration import (
DurationRegistry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
VirtualVacant,
VirtualTwoQubitVacant,
VirtualEmpty,
VirtualWait,
VirtualOptional,
VirtualInjectedError,
VirtualColorOverwrite,
)
from qce_circuit.visualization.visualize_circuit.draw_components.annotation_components import (
HorizontalVariableIndicator,
Expand Down Expand Up @@ -110,8 +112,10 @@
VirtualVacantFactory,
VirtualTwoQubitVacantFactory,
VirtualEmptyFactory,
VirtualWaitFactory,
VirtualOptionalFactory,
VirtualInjectedErrorFactory,
VirtualColorOverwriteFactory,
)
from qce_circuit.visualization.visualize_circuit.draw_components.factory_multi_draw_components import \
MultiTwoQubitBlockFactory
Expand Down Expand Up @@ -220,12 +224,14 @@ def get_operation_draw_components(self) -> List[IDrawComponent]:
VirtualVacant: VirtualVacantFactory(),
VirtualTwoQubitVacant: VirtualTwoQubitVacantFactory(),
VirtualEmpty: VirtualEmptyFactory(),
VirtualWait: VirtualWaitFactory(),
}
)
callback_draw_manager = deepcopy(individual_component_factory)
individual_component_factory.factory_lookup.update({
VirtualOptional: VirtualOptionalFactory(callback_draw_manager=callback_draw_manager),
VirtualInjectedError: VirtualInjectedErrorFactory(callback_draw_manager=callback_draw_manager),
VirtualColorOverwrite: VirtualColorOverwriteFactory(callback_draw_manager=callback_draw_manager),
})

factory_manager: BulkDrawComponentFactoryManager = BulkDrawComponentFactoryManager(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
VirtualEmpty,
VirtualOptional,
VirtualInjectedError,
VirtualWait,
VirtualColorOverwrite,
)
from qce_circuit.visualization.visualize_circuit.intrf_draw_component import IDrawComponent
from qce_circuit.visualization.visualize_circuit.intrf_factory_draw_components import (
Expand All @@ -50,6 +52,7 @@
RectangleTextBlock,
RectangleVacantBlock,
BlockRotation,
BlockHeaderBody,
BlockMeasure,
RotationAxis,
RotationAngle,
Expand Down Expand Up @@ -439,6 +442,25 @@ def construct(self, operation: VirtualEmpty, transform_constructor: ITransformCo
# endregion


class VirtualWaitFactory(IOperationDrawComponentFactory[VirtualWait, IDrawComponent]):

# region Interface Methods
def construct(self, operation: VirtualWait, transform_constructor: ITransformConstructor) -> IDrawComponent:
""":return: Draw component based on operation type."""
transform: IRectTransform = transform_constructor.construct_transform(
identifier=operation.channel_identifiers[0],
time_component=operation,
)
return BlockHeaderBody(
pivot=transform.pivot,
height=transform.height,
alignment=transform.parent_alignment,
header_text=operation.header_text,
body_text=operation.body_text,
)
# endregion


class MeasureFactory(IOperationDrawComponentFactory[DispersiveMeasure, IDrawComponent]):

# region Interface Methods
Expand Down Expand Up @@ -581,4 +603,30 @@ def construct(self, operation: VirtualInjectedError, transform_constructor: ITra
transform_constructor=transform_constructor,
)
return draw_component
# endregion
# endregion


class VirtualColorOverwriteFactory(IOperationDrawComponentFactory[VirtualColorOverwrite, IDrawComponent]):
"""
Behaviour class, implementing construction of draw component with additional requirements.
"""

# region Class Constructor
def __init__(self, callback_draw_manager: IOperationDrawComponentFactoryManager):
self._factory_manager: IOperationDrawComponentFactoryManager = callback_draw_manager
# endregion

# region Interface Methods
def construct(self, operation: VirtualColorOverwrite, transform_constructor: ITransformConstructor) -> IDrawComponent:
""":return: Draw component based on operation type."""
with StyleManager.temporary_override(**dict(
color_text=operation.color_overwrite,
color_icon=operation.color_overwrite,
color_outline=operation.color_overwrite,
)):
draw_component: IDrawComponent = self._factory_manager.construct(
operation=operation.operation,
transform_constructor=transform_constructor,
)
return draw_component
# endregion
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ class RectangleBlock(IRectTransformComponent, IDrawComponent):
@property
def rectilinear_transform(self) -> IRectTransform:
""":return: 'Hard' rectilinear transform boundary. Should be treated as 'personal zone'."""
margin: float = self.style_settings.rectilinear_margin
margin_pivot_shift: Vec2D = Vec2D(x=margin/2, y=0.0)
return RectTransform(
_pivot_strategy=FixedPivot(self.pivot),
_width_strategy=FixedLength(self.width),
_height_strategy=FixedLength(self.height),
_pivot_strategy=FixedPivot(self.pivot + margin_pivot_shift),
_width_strategy=FixedLength(self.width - margin),
_height_strategy=FixedLength(self.height - margin),
_parent_alignment=self.alignment,
)
# endregion
Expand Down Expand Up @@ -118,6 +120,7 @@ def draw(self, axes: plt.Axes) -> plt.Axes:
y=self.text_center.y,
s=self.text_string,
fontsize=self.style_settings.font_size,
color=self.style_settings.text_color,
ha='center',
va='center',
)
Expand Down Expand Up @@ -280,6 +283,40 @@ def draw(self, axes: plt.Axes) -> plt.Axes:
y=self.text_center.y,
s=rf'$\mathtt{{R_{{{self.rotation_axes.value}}}^{{{self.rotation_angle.value}}}}}$',
fontsize=self.style_settings.font_size,
color=self.style_settings.text_color,
ha='center',
va='center',
)
return axes
# endregion


@dataclass(frozen=True)
class BlockHeaderBody(SquareTextBlock, IRectTransformComponent, IDrawComponent):
"""
Data class, containing dimension data for drawing schedule block.
"""
header_text: str = field(default="")
body_text: str = field(default="")

# region Class Methods
def draw(self, axes: plt.Axes) -> plt.Axes:
axes = self._base_block.draw(axes=axes)
axes.text(
x=self.text_center.x,
y=self.text_center.y,
s=self.header_text,
fontsize=self.style_settings.font_size,
color=self.style_settings.text_color,
ha='center',
va='center',
)
axes.text(
x=self.text_center.x,
y=(self.text_center.y + self.rectilinear_transform.bot_pivot.y) / 2,
s=self.body_text,
fontsize=self.style_settings.subtext_font_size,
color=self.style_settings.text_color,
ha='center',
va='center',
)
Expand Down
12 changes: 12 additions & 0 deletions src/qce_circuit/visualization/visualize_circuit/style_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class OperationStyleSettings:
border_line_style: str
dot_radius: float
font_size: float
subtext_font_size: float
rectilinear_margin: float
"""Margin variable used to shrink the drawn rectangle to allow for 'white-space'."""


@dataclass(frozen=True)
Expand Down Expand Up @@ -102,6 +105,9 @@ class StyleSettings:
# Line styles
line_style_border: str = field(default='-')

# Spacing
rectilinear_margin: float = field(default=0.0)

# region Class Properties
@property
def channel_style(self) -> ChannelStyleSettings:
Expand All @@ -123,6 +129,8 @@ def operation_style(self) -> OperationStyleSettings:
border_line_style=self.line_style_border,
dot_radius=self.radius_dot,
font_size=self.font_size,
subtext_font_size=self.font_size_small,
rectilinear_margin=self.rectilinear_margin,
)

@property
Expand All @@ -136,6 +144,8 @@ def vacant_operation_style(self) -> OperationStyleSettings:
border_line_style=self.line_style_border,
dot_radius=self.radius_dot,
font_size=self.font_size,
subtext_font_size=self.font_size_small,
rectilinear_margin=self.rectilinear_margin,
)

@property
Expand All @@ -149,6 +159,8 @@ def empty_operation_style(self) -> OperationStyleSettings:
border_line_style=self.line_style_border,
dot_radius=self.radius_dot,
font_size=self.font_size,
subtext_font_size=self.font_size_small,
rectilinear_margin=self.rectilinear_margin,
)

@property
Expand Down