Circuit rendering skins

When rendering a Circuit, an Experiment or a Processor, you can select a skin which will change how the components are displayed.

>>> import perceval as pcvl
>>> c = pcvl.Circuit(4).add(0, pcvl.BS.H()).add(2, pcvl.BS.H())
>>> pcvl.pdisplay(c, skin = pcvl.SymbSkin(compact_display = True))
../../_images/symb_skin_example.png

Perceval provides two skins for an easy usage:

  • SymbSkin: a sober black and white skin

  • PhysSkin: a more colorful “real-life” skin (default one)

Both share the same init signature, with an optional boolean kwarg compact_display that makes the circuit components smaller and closer to each other.

Skin classes can be selected to be used across several perceval runs using the DisplayConfig.

>>> from perceval.rendering import DisplayConfig, SymbSkin
>>> DisplayConfig.select_skin(SymbSkin) # SymbSkin will be used by default by pdisplay if no other skin is defined.
>>> DisplayConfig.save() # Will save the current DisplayConfig into your Perceval persistent configuration.

Note that since the DisplayConfig class stores a skin class and not an instance, the compact_display attribute needs to be given again each time.

It’s also possible to hack an existing skin to fit your needs or even create a new one by subclassing the ASkin abstract class, though it will not be easy to save it.

Perceval also provides a DebugSkin that builds on PhysSkin, but that also displays the heralded modes of an Experiment, and highlights whether phase shifters are defined or not. As its name suggests, this skin should only be used when debugging as it is not made for a pretty and readable display.

Skin code reference

All skins follow the ASkin interface, except for the __init__() where subclasses already have their own style:

class perceval.rendering.circuit.abstract_skin.ASkin(photonic_style, style_subcircuit, compact_display=False)
A skin is required in the use of pdisplay for the following formats:
  • Format.HTML

  • Format.MPLOT

  • Format.LATEX

A skin has three major responsibilities:
  • measuring the display size of a component / composite circuit

  • providing shape functions to draw individual components

  • exposing style data (stroke style, colors, etc.)

Parameters:
  • photonic_style (dict) – photonic mode style, containing stroke specifications {“stroke”: color_str, “stroke_width”: int}

  • style_subcircuit (dict) – subcircuit style specifications {“width”: int, “stroke_style”: {“stroke”: color_str, “stroke_width”: int}, “fill”: color_str}

  • compact_display (bool) – whether to display some large components in a more compact way, to use less screen space

abstract default_shape(c, canvas, mode_style)

Define a fallback shape for unknown components

Parameters:
  • c – the component to draw

  • canvas – the canvas on which to draw

  • mode_style – the style for all modes

abstract get_shape(c)

Returns a callable able to draw the shape of a given component on a canvas

Parameters:

c – the component to draw

Return type:

callable

abstract get_width(c)

Returns the width of a component

Parameters:

c – the component to measure

Return type:

int

measure(c)

Returns the measure (in arbitrary unit (AU) where the space between two modes = 1 AU) of a single component treated as a block (meaning that a composite circuit will not be measured recursively. Use get_size() instead)

Return type:

tuple[int, int]