def test_text_data_with_abstract_coordinate(self):
        """Test for TextData with abstract coordinate."""
        xs = [types.AbstractCoordinate.RIGHT]
        ys = [types.AbstractCoordinate.TOP]

        data1 = drawing_objects.TextData(data_type='test',
                                         xvals=xs,
                                         yvals=ys,
                                         text='test1',
                                         latex=r'test_1',
                                         channels=self.ch_d0,
                                         meta=self.meta1,
                                         ignore_scaling=True,
                                         styles=self.style1)

        data2 = drawing_objects.TextData(data_type='test',
                                         xvals=xs,
                                         yvals=ys,
                                         text='test2',
                                         latex=r'test_2',
                                         channels=self.ch_d1,
                                         meta=self.meta2,
                                         ignore_scaling=True,
                                         styles=self.style2)

        self.assertEqual(data1, data2)
Exemple #2
0
    def test_text_data(self):
        """Test for TextData."""
        data1 = drawing_objects.TextData(data_type='pulse_label',
                                         channel=pulse.DriveChannel(0),
                                         x=0,
                                         y=0,
                                         text='my_text',
                                         meta={'test_val': 0},
                                         offset=0,
                                         scale=1,
                                         visible=True,
                                         styles={'color': 'red'})

        data2 = drawing_objects.TextData(data_type='pulse_label',
                                         channel=pulse.DriveChannel(0),
                                         x=0,
                                         y=0,
                                         text='my_text',
                                         meta={'test_val': 1},
                                         offset=1,
                                         scale=2,
                                         visible=False,
                                         styles={'color': 'blue'})

        self.assertEqual(data1, data2)
    def test_text_data(self):
        """Test for TextData."""
        xs = [0]
        ys = [1]

        data1 = drawing_objects.TextData(data_type='test',
                                         xvals=xs,
                                         yvals=ys,
                                         text='test1',
                                         latex=r'test_1',
                                         channels=self.ch_d0,
                                         meta=self.meta1,
                                         ignore_scaling=True,
                                         styles=self.style1)

        data2 = drawing_objects.TextData(data_type='test',
                                         xvals=xs,
                                         yvals=ys,
                                         text='test2',
                                         latex=r'test_2',
                                         channels=self.ch_d1,
                                         meta=self.meta2,
                                         ignore_scaling=True,
                                         styles=self.style2)

        self.assertEqual(data1, data2)
Exemple #4
0
def gen_snapshot_symbol(misc_data: types.NonPulseTuple) \
        -> List[drawing_objects.TextData]:
    r"""Generate a snapshot symbol with instruction meta data from provided snapshot instruction.

    The snapshot symbol is capped by the snapshot label.

    - The `snapshot` style is applied for snapshot symbol.
    - The `annotate` style is applied for label font size.

    The symbol type in unicode is specified in `formatter.unicode_symbol.snapshot`.
    The symbol type in latex is specified in `formatter.latex_symbol.snapshot`.

    Args:
        misc_data: Snapshot instruction data to draw.

    Returns:
        List of `TextData` drawing objects.
    """

    if not isinstance(misc_data.inst, pulse.instructions.Snapshot):
        return []

    symbol_style = {'zorder': PULSE_STYLE['formatter.layer.snapshot'],
                    'color': PULSE_STYLE['formatter.color.snapshot'],
                    'size': PULSE_STYLE['formatter.text_size.snapshot'],
                    'va': 'bottom',
                    'ha': 'center'}

    label_style = {'zorder': PULSE_STYLE['formatter.layer.snapshot'],
                   'color': PULSE_STYLE['formatter.color.snapshot'],
                   'size': PULSE_STYLE['formatter.text_size.annotate'],
                   'va': 'bottom',
                   'ha': 'center'}

    meta = {'snapshot type': misc_data.inst.type,
            't0 (cycle time)': misc_data.t0,
            't0 (sec)': misc_data.t0 * misc_data.dt if misc_data.dt else 'N/A'}

    uni_symbol = PULSE_STYLE['formatter.unicode_symbol.snapshot']
    latex = PULSE_STYLE['formatter.latex_symbol.snapshot']

    symbol_text = drawing_objects.TextData(data_type='Symbol',
                                           channel=misc_data.inst.channel,
                                           x=misc_data.t0,
                                           y=0,
                                           text=uni_symbol,
                                           latex=latex,
                                           meta=meta,
                                           styles=symbol_style)

    label_text = drawing_objects.TextData(data_type='Symbol',
                                          channel=misc_data.inst.channel,
                                          x=misc_data.t0,
                                          y=PULSE_STYLE['formatter.label_offset.snapshot'],
                                          text=misc_data.inst.label,
                                          styles=label_style)

    return [symbol_text, label_text]
Exemple #5
0
def gen_scaling_info(channel_data: types.ChannelTuple) \
        -> List[drawing_objects.TextData]:
    r"""Generate channel scaling factor of provided channel.

    The `axis_label` style is applied.
    The `annotate` style is partially applied for the font size.

    Args:
        channel_data: Channel data to draw.

    Returns:
        List of `TextData` drawing objects.
    """
    if channel_data.scaling == 1:
        return []

    style = {'zorder': PULSE_STYLE['formatter.layer.axis_label'],
             'color': PULSE_STYLE['formatter.color.axis_label'],
             'size': PULSE_STYLE['formatter.text_size.annotate'],
             'va': 'center',
             'ha': 'right'}
    value = r'x{:.1f}'.format(channel_data.scaling)

    text = drawing_objects.TextData(data_type='ChannelInfo',
                                    channel=channel_data.channel,
                                    x=0,
                                    y=PULSE_STYLE['formatter.label_offset.scale_factor'],
                                    text=value,
                                    styles=style)

    return [text]
Exemple #6
0
def gen_latex_channel_name(channel_data: types.ChannelTuple) \
        -> List[drawing_objects.TextData]:
    r"""Generate channel name of provided channel.

    The `axis_label` style is applied.

    Args:
        channel_data: Channel data to draw.

    Returns:
        List of `TextData` drawing objects.
    """
    style = {'zorder': PULSE_STYLE['formatter.layer.axis_label'],
             'color': PULSE_STYLE['formatter.color.axis_label'],
             'size': PULSE_STYLE['formatter.text_size.axis_label'],
             'va': 'center',
             'ha': 'right'}
    latex_name = r'{}_{}'.format(channel_data.channel.prefix.upper(),
                                 channel_data.channel.index)

    text = drawing_objects.TextData(data_type='ChannelInfo',
                                    channel=channel_data.channel,
                                    x=0,
                                    y=0,
                                    text=channel_data.channel.name.upper(),
                                    latex=latex_name,
                                    styles=style)

    return [text]
Exemple #7
0
def gen_chart_name(
        data: types.ChartAxis, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate the name of chart.

    Stylesheets:
        - The `axis_label` style is applied.

    Args:
        data: Chart axis data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    style = {
        'zorder': formatter['layer.axis_label'],
        'color': formatter['color.axis_label'],
        'size': formatter['text_size.axis_label'],
        'va': 'center',
        'ha': 'right'
    }

    text = drawing_objects.TextData(data_type=types.DrawingLabel.CH_NAME,
                                    channels=data.channels,
                                    xvals=[types.AbstractCoordinate.LEFT],
                                    yvals=[0],
                                    text=data.name,
                                    ignore_scaling=True,
                                    styles=style)

    return [text]
Exemple #8
0
def gen_raw_frame_operand_values(frame_data: types.InstructionTuple) \
        -> List[drawing_objects.TextData]:
    r"""Generate both phase and frequency change from provided frame instruction.

    Frequency change is expressed in scientific notation.

    For example:
        - A phase change 1.57 and frequency change 1,234,567 are written by `(1.57, 1.2e+06)`

    - The `frame_change` style is applied.
    - The `annotate` style is applied for font size.

    Args:
        frame_data: Frame instruction data to draw.

    Returns:
        List of `TextData` drawing objects.
    """

    style = {'zorder': PULSE_STYLE['formatter.layer.frame_change'],
             'color': PULSE_STYLE['formatter.color.frame_change'],
             'size': PULSE_STYLE['formatter.text_size.annotate'],
             'va': 'center',
             'ha': 'center'}

    frame_info = '({:.2f}, {:.1e})'.format(frame_data.frame.phase, frame_data.frame.freq)

    text = drawing_objects.TextData(data_type='FrameInfo',
                                    channel=frame_data.inst[0].channel,
                                    x=frame_data.t0,
                                    y=PULSE_STYLE['formatter.label_offset.frame_change'],
                                    text=frame_info,
                                    styles=style)

    return [text]
def gen_frame_symbol(
        data: types.PulseInstruction, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate a frame change symbol with instruction meta data from provided frame instruction.

    Stylesheets:
        - The `frame_change` style is applied.
        - The symbol type in unicode is specified in `formatter.unicode_symbol.frame_change`.
        - The symbol type in latex is specified in `formatter.latex_symbol.frame_change`.

    Args:
        data: Frame change instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """

    style = {
        'zorder': formatter['layer.frame_change'],
        'color': formatter['color.frame_change'],
        'size': formatter['text_size.frame_change'],
        'va': 'center',
        'ha': 'center'
    }

    program = []
    for inst in data.inst:
        if isinstance(
                inst,
            (instructions.SetFrequency, instructions.ShiftFrequency)):
            program.append('{}({:.2e} Hz)'.format(inst.__class__.__name__,
                                                  inst.frequency))
        elif isinstance(inst,
                        (instructions.SetPhase, instructions.ShiftPhase)):
            program.append('{}({:.2f} rad.)'.format(inst.__class__.__name__,
                                                    inst.phase))

    meta = {
        'total phase change': data.frame.phase,
        'total frequency change': data.frame.freq,
        'program': ', '.join(program),
        't0 (cycle time)': data.t0,
        't0 (sec)': data.t0 * data.dt if data.dt else 'N/A'
    }

    text = drawing_objects.TextData(
        data_type=types.DrawingSymbol.FRAME,
        channels=data.inst[0].channel,
        xvals=[data.t0],
        yvals=[0],
        text=formatter['unicode_symbol.frame_change'],
        latex=formatter['latex_symbol.frame_change'],
        ignore_scaling=True,
        meta=meta,
        styles=style)

    return [text]
Exemple #10
0
def gen_snapshot_name(
        data: types.SnapshotInstruction, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate the name of snapshot.

    Stylesheets:
        - The `snapshot` style is applied for snapshot symbol.
        - The `annotate` style is applied for label font size.

    Args:
        data: Snapshot instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    style = {
        'zorder': formatter['layer.snapshot'],
        'color': formatter['color.snapshot'],
        'size': formatter['text_size.annotate'],
        'va': 'bottom',
        'ha': 'center'
    }

    text = drawing_objects.TextData(data_type=types.DrawingLabel.SNAPSHOT,
                                    channels=data.inst.channel,
                                    xvals=[data.t0],
                                    yvals=[formatter['label_offset.snapshot']],
                                    text=data.inst.name,
                                    ignore_scaling=True,
                                    styles=style)

    return [text]
Exemple #11
0
def gen_frame_symbol(frame_data: types.InstructionTuple) \
        -> List[drawing_objects.TextData]:
    r"""Generate a frame change symbol with instruction meta data from provided frame instruction.

    The `frame_change` style is applied.

    The symbol type in unicode is specified in `formatter.unicode_symbol.frame_change`.
    The symbol type in latex is specified in `formatter.latex_symbol.frame_change`.

    Args:
        frame_data: Frame instruction data to draw.

    Returns:
        List of `TextData` drawing objects.
    """

    style = {
        'zorder': PULSE_STYLE['formatter.layer.frame_change'],
        'color': PULSE_STYLE['formatter.color.frame_change'],
        'size': PULSE_STYLE['formatter.text_size.frame_change'],
        'va': 'center',
        'ha': 'center'
    }

    program = []
    for inst in frame_data.inst:
        if isinstance(
                inst,
            (instructions.SetFrequency, instructions.ShiftFrequency)):
            program.append('{}({:.2e} Hz)'.format(inst.__class__.__name__,
                                                  inst.frequency))
        elif isinstance(inst,
                        (instructions.SetPhase, instructions.ShiftPhase)):
            program.append('{}({:.2f} rad.)'.format(inst.__class__.__name__,
                                                    inst.phase))

    meta = {
        'total phase change': frame_data.frame.phase,
        'total frequency change': frame_data.frame.freq,
        'program': program,
        't0 (cycle time)': frame_data.t0,
        't0 (sec)': frame_data.t0 * frame_data.dt if frame_data.dt else 'N/A'
    }

    uni_symbol = PULSE_STYLE['formatter.unicode_symbol.frame_change']
    latex = PULSE_STYLE['formatter.latex_symbol.frame_change']

    text = drawing_objects.TextData(data_type='Symbol',
                                    channel=frame_data.inst[0].channel,
                                    x=frame_data.t0,
                                    y=0,
                                    text=uni_symbol,
                                    latex=latex,
                                    meta=meta,
                                    styles=style)

    return [text]
Exemple #12
0
def gen_latex_vz_label(frame_data: types.InstructionTuple) \
        -> List[drawing_objects.TextData]:
    r"""Generate formatted virtual Z rotations from provided frame instruction.

    Rotation angle is expressed in units of pi.
    If the denominator of fraction is larger than 10, the angle is expressed in units of radian.

    For example:
        - A value -3.14 is converted into `VZ(\pi)`
        - A value 1.57 is converted into `VZ(-\frac{\pi}{2})`
        - A value 0.123 is converted into `VZ(-0.123 rad.)`

    - The `frame_change` style is applied.
    - The `annotate` style is applied for font size.

    Notes:
        The phase operand of `PhaseShift` instruction has opposite sign to the Z gate definition.
        Thus the sign of rotation angle is inverted.

    Args:
        frame_data: Frame instruction data to draw.

    Returns:
        List of `TextData` drawing objects.
    """
    _max_denom = 10

    style = {'zorder': PULSE_STYLE['formatter.layer.frame_change'],
             'color': PULSE_STYLE['formatter.color.frame_change'],
             'size': PULSE_STYLE['formatter.text_size.annotate'],
             'va': 'center',
             'ha': 'center'}

    frac = Fraction(np.abs(frame_data.frame.phase) / np.pi)
    if frac.denominator > _max_denom:
        angle = r'{:.2e}~{{\rm rad.}}'.format(frame_data.frame.phase)
    else:
        if frac.numerator == 1:
            if frac.denominator == 1:
                angle = r'\pi'
            else:
                angle = r'\frac{{\pi}}{{{}}}'.format(frac.denominator)
        else:
            angle = r'\frac{{{}}}{{{}}}\pi'.format(frac.numerator, frac.denominator)

    # Phase Shift is defined as negative value
    sign = '' if frame_data.frame.phase <= 0 else '-'

    text = drawing_objects.TextData(data_type='FrameInfo',
                                    channel=frame_data.inst[0].channel,
                                    x=frame_data.t0,
                                    y=PULSE_STYLE['formatter.label_offset.frame_change'],
                                    text=r'VZ({:.2f} rad.)'.format(-frame_data.frame.phase),
                                    latex=r'{{\rm VZ}}({}{})'.format(sign, angle),
                                    styles=style)

    return [text]
Exemple #13
0
def gen_formatted_phase(
        data: types.PulseInstruction, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate the formatted virtual Z rotation label from provided frame instruction.

    Rotation angle is expressed in units of pi.
    If the denominator of fraction is larger than 10, the angle is expressed in units of radian.

    For example:
        - A value -3.14 is converted into `VZ(\\pi)`
        - A value 1.57 is converted into `VZ(-\\frac{\\pi}{2})`
        - A value 0.123 is converted into `VZ(-0.123 rad.)`

    Stylesheets:
        - The `frame_change` style is applied.
        - The `annotate` style is applied for font size.

    Notes:
        The phase operand of `PhaseShift` instruction has opposite sign to the Z gate definition.
        Thus the sign of rotation angle is inverted.

    Args:
        data: Frame change instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    _max_denom = 10

    style = {
        'zorder': formatter['layer.frame_change'],
        'color': formatter['color.frame_change'],
        'size': formatter['text_size.annotate'],
        'va': 'bottom',
        'ha': 'center'
    }

    plain_phase, latex_phase = _phase_to_text(data.frame.phase,
                                              _max_denom,
                                              flip=True)

    text = drawing_objects.TextData(
        data_type=types.DrawingLabel.FRAME,
        channels=data.inst[0].channel,
        xvals=[data.t0],
        yvals=[formatter['label_offset.frame_change']],
        text='VZ({phase})'.format(phase=plain_phase),
        latex=r'{{\rm VZ}}({phase})'.format(phase=latex_phase),
        ignore_scaling=True,
        styles=style)

    return [text]
Exemple #14
0
def gen_channel_freqs(
        data: types.ChartAxis, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate the frequency values of associated channels.

    Stylesheets:
        - The `axis_label` style is applied.
        - The `annotate` style is partially applied for the font size.

    Args:
        data: Chart axis data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    style = {
        'zorder': formatter['layer.axis_label'],
        'color': formatter['color.axis_label'],
        'size': formatter['text_size.annotate'],
        'va': 'top',
        'ha': 'right'
    }

    if len(data.channels) > 1:
        sources = []
        for chan in data.channels:
            freq = device.get_channel_frequency(chan)
            if not freq:
                continue
            sources.append('{chan}: {val:.2f} GHz'.format(
                chan=chan.name.upper(), val=freq / 1e9))
        freq_text = ', '.join(sources)
    else:
        freq = device.get_channel_frequency(data.channels[0])
        if freq:
            freq_text = '{val:.2f} GHz'.format(val=freq / 1e9)
        else:
            freq_text = ''

    text = drawing_objects.TextData(
        data_type=types.DrawingLabel.CH_INFO,
        channels=data.channels,
        xvals=[types.AbstractCoordinate.LEFT],
        yvals=[formatter['label_offset.scale_factor']],
        text=freq_text or 'n/a',
        ignore_scaling=True,
        styles=style)

    return [text]
Exemple #15
0
def gen_formatted_freq_mhz(
        data: types.PulseInstruction, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate the formatted frequency change label from provided frame instruction.

    Frequency change is expressed in units of MHz.

    For example:
        - A value 1,234,567 is converted into `\\Delta f = 1.23 MHz`

    Stylesheets:
        - The `frame_change` style is applied.
        - The `annotate` style is applied for font size.

    Args:
        data: Frame change instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    _unit = 'MHz'

    style = {
        'zorder': formatter['layer.frame_change'],
        'color': formatter['color.frame_change'],
        'size': formatter['text_size.annotate'],
        'va': 'bottom',
        'ha': 'center'
    }

    plain_freq, latex_freq = _freq_to_text(data.frame.freq, _unit)

    text = drawing_objects.TextData(
        data_type=types.DrawingLabel.FRAME,
        channels=data.inst[0].channel,
        xvals=[data.t0],
        yvals=[formatter['label_offset.frame_change']],
        text=u'\u0394f = {freq}'.format(freq=plain_freq),
        latex=r'\Delta f = {freq}'.format(freq=latex_freq),
        ignore_scaling=True,
        styles=style)

    return [text]
Exemple #16
0
def gen_snapshot_symbol(
        data: types.SnapshotInstruction, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate a snapshot symbol with instruction meta data from provided snapshot instruction.

    Stylesheets:
        - The `snapshot` style is applied for snapshot symbol.
        - The symbol type in unicode is specified in `formatter.unicode_symbol.snapshot`.
        - The symbol type in latex is specified in `formatter.latex_symbol.snapshot`.

    Args:
        data: Snapshot instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    style = {
        'zorder': formatter['layer.snapshot'],
        'color': formatter['color.snapshot'],
        'size': formatter['text_size.snapshot'],
        'va': 'bottom',
        'ha': 'center'
    }

    meta = {
        'snapshot type': data.inst.type,
        't0 (cycle time)': data.t0,
        't0 (sec)': data.t0 * data.dt if data.dt else 'N/A',
        'name': data.inst.name,
        'label': data.inst.label
    }

    text = drawing_objects.TextData(data_type=types.DrawingSymbol.SNAPSHOT,
                                    channels=data.inst.channel,
                                    xvals=[data.t0],
                                    yvals=[0],
                                    text=formatter['unicode_symbol.snapshot'],
                                    latex=formatter['latex_symbol.snapshot'],
                                    ignore_scaling=True,
                                    meta=meta,
                                    styles=style)

    return [text]
Exemple #17
0
def gen_raw_operand_values_compact(
        data: types.PulseInstruction, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate the formatted virtual Z rotation label and the frequency change label
    from provided frame instruction.

    Raw operand values are shown in compact form. Frequency change is expressed
    in scientific notation. Values are shown in two lines.

    For example:
        - A phase change 1.57 and frequency change 1,234,567 are written by `1.57\\n1.2e+06`

    Stylesheets:
        - The `frame_change` style is applied.
        - The `annotate` style is applied for font size.

    Args:
        data: Frame change instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """

    style = {
        'zorder': formatter['layer.frame_change'],
        'color': formatter['color.frame_change'],
        'size': formatter['text_size.annotate'],
        'va': 'bottom',
        'ha': 'center'
    }

    frame_info = '{:.2f}\n{:.1e}'.format(data.frame.phase, data.frame.freq)

    text = drawing_objects.TextData(
        data_type=types.DrawingLabel.FRAME,
        channels=data.inst[0].channel,
        xvals=[data.t0],
        yvals=[formatter['label_offset.frame_change']],
        text=frame_info,
        ignore_scaling=True,
        styles=style)

    return [text]
Exemple #18
0
def gen_latex_frequency_mhz_value(frame_data: types.InstructionTuple) \
        -> List[drawing_objects.TextData]:
    r"""Generate formatted frequency change from provided frame instruction.

    Frequency change is expressed in units of MHz.

    For example:
        - A value 1,234,567 is converted into `\Delta f = 1.23 MHz`

    - The `frame_change` style is applied.
    - The `annotate` style is applied for font size.

    Args:
        frame_data: Frame instruction data to draw.

    Returns:
        List of `TextData` drawing objects.
    """

    style = {
        'zorder': PULSE_STYLE['formatter.layer.frame_change'],
        'color': PULSE_STYLE['formatter.color.frame_change'],
        'size': PULSE_STYLE['formatter.text_size.annotate'],
        'va': 'center',
        'ha': 'center'
    }

    text_df = u'\u0394' + 'f={:.2f} MHz'.format(frame_data.frame.freq / 1e6)
    latex_df = r'\Delta f = {:.2f} ~{{\rm MHz}}'.format(frame_data.frame.freq /
                                                        1e6)

    text = drawing_objects.TextData(
        data_type='FrameInfo',
        channel=frame_data.inst[0].channel,
        x=frame_data.t0,
        y=PULSE_STYLE['formatter.label_offset.frame_change'],
        text=text_df,
        latex=latex_df,
        styles=style)

    return [text]
Exemple #19
0
def gen_chart_scale(
        data: types.ChartAxis, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate the current scaling value of the chart.

    Stylesheets:
        - The `axis_label` style is applied.
        - The `annotate` style is partially applied for the font size.

    Args:
        data: Chart axis data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    style = {
        'zorder': formatter['layer.axis_label'],
        'color': formatter['color.axis_label'],
        'size': formatter['text_size.annotate'],
        'va': 'top',
        'ha': 'right'
    }

    scale_val = 'x{param}'.format(param=types.DynamicString.SCALE)

    text = drawing_objects.TextData(
        data_type=types.DrawingLabel.CH_INFO,
        channels=data.channels,
        xvals=[types.AbstractCoordinate.LEFT],
        yvals=[formatter['label_offset.scale_factor']],
        text=scale_val,
        ignore_scaling=True,
        styles=style)

    return [text]
Exemple #20
0
def gen_waveform_max_value(data: types.PulseInstruction,
                           formatter: Dict[str, Any],
                           device: device_info.DrawerBackendInfo
                           ) -> List[drawing_objects.TextData]:
    """Generate the annotation for the maximum waveform height for
    the real and the imaginary part of the waveform envelope.

    Maximum values smaller than the vertical resolution limit is ignored.

    Stylesheets:
        - The `annotate` style is applied.

    Args:
        data: Waveform instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    style = {'zorder': formatter['layer.annotate'],
             'color': formatter['color.annotate'],
             'size': formatter['text_size.annotate'],
             'ha': 'center'}

    # only pulses.
    if isinstance(data.inst, instructions.Play):
        # pulse
        operand = data.inst.pulse
        if isinstance(operand, pulse.ParametricPulse):
            pulse_data = operand.get_waveform()
        else:
            pulse_data = operand
        xdata = np.arange(pulse_data.duration) + data.t0
        ydata = pulse_data.samples
    else:
        return []

    # phase modulation
    if formatter['control.apply_phase_modulation']:
        ydata = np.asarray(ydata, dtype=np.complex) * np.exp(1j * data.frame.phase)
    else:
        ydata = np.asarray(ydata, dtype=np.complex)

    texts = []

    # max of real part
    re_maxind = np.argmax(np.abs(ydata.real))
    if np.abs(ydata.real[re_maxind]) > formatter['general.vertical_resolution']:
        if ydata.real[re_maxind] > 0:
            max_val = u'{val:.2f}\n\u25BE'.format(val=ydata.real[re_maxind])
            re_style = {'va': 'bottom'}
        else:
            max_val = u'{val:.2f}\n\u25B4'.format(val=ydata.real[re_maxind])
            re_style = {'va': 'top'}
        re_style.update(style)
        re_text = drawing_objects.TextData(data_type=types.DrawingLabel.PULSE_INFO,
                                           channels=data.inst.channel,
                                           xvals=[xdata[re_maxind]],
                                           yvals=[ydata.real[re_maxind]],
                                           text=max_val,
                                           ignore_scaling=True,
                                           styles=re_style)
        texts.append(re_text)

    # max of imag part
    im_maxind = np.argmax(np.abs(ydata.imag))
    if np.abs(ydata.imag[im_maxind]) > formatter['general.vertical_resolution']:
        if ydata.imag[im_maxind] > 0:
            max_val = u'{val:.2f}\n\u25BE'.format(val=ydata.imag[im_maxind])
            im_style = {'va': 'bottom'}
        else:
            max_val = u'{val:.2f}\n\u25B4'.format(val=ydata.imag[im_maxind])
            im_style = {'va': 'top'}
        im_style.update(style)
        im_text = drawing_objects.TextData(data_type=types.DrawingLabel.PULSE_INFO,
                                           channels=data.inst.channel,
                                           xvals=[xdata[im_maxind]],
                                           yvals=[ydata.imag[im_maxind]],
                                           text=max_val,
                                           ignore_scaling=True,
                                           styles=im_style)
        texts.append(im_text)

    return texts
Exemple #21
0
def gen_ibmq_latex_waveform_name(data: types.PulseInstruction,
                                 formatter: Dict[str, Any],
                                 device: device_info.DrawerBackendInfo
                                 ) -> List[drawing_objects.TextData]:
    r"""Generate the formatted instruction name associated with the waveform.

    Channel name and ID string are removed and the rotation angle is expressed in units of pi.
    The controlled rotation angle associated with the CR pulse name is divided by 2.

    Note that in many scientific articles the controlled rotation angle implies
    the actual rotation angle, but in IQX backend the rotation angle represents
    the difference between rotation angles with different control qubit states.

    For example:
        - 'X90p_d0_abcdefg' is converted into 'X(\frac{\pi}{2})'
        - 'CR90p_u0_abcdefg` is converted into 'CR(\frac{\pi}{4})'

    Stylesheets:
        - The `annotate` style is applied.

    Notes:
        This generator can convert pulse names used in the IQX backends.
        If pulses are provided by the third party providers or the user defined,
        the generator output may be the as-is pulse name.

    Args:
        data: Waveform instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    style = {'zorder': formatter['layer.annotate'],
             'color': formatter['color.annotate'],
             'size': formatter['text_size.annotate'],
             'va': 'top',
             'ha': 'center'}

    if isinstance(data.inst, pulse.instructions.Acquire):
        systematic_name = 'Acquire'
        latex_name = None
    elif isinstance(data.inst.channel, pulse.channels.MeasureChannel):
        systematic_name = 'Measure'
        latex_name = None
    else:
        systematic_name = data.inst.pulse.name

        template = r'(?P<op>[A-Z]+)(?P<angle>[0-9]+)?(?P<sign>[pm])_(?P<ch>[dum])[0-9]+'
        match_result = re.match(template, systematic_name)
        if match_result is not None:
            match_dict = match_result.groupdict()
            sign = '' if match_dict['sign'] == 'p' else '-'
            if match_dict['op'] == 'CR':
                # cross resonance
                if match_dict['ch'] == 'u':
                    op_name = r'{\rm CR}'
                else:
                    op_name = r'\overline{\rm CR}'
                # IQX name def is not standard. Echo CR is annotated with pi/4 rather than pi/2
                angle_val = match_dict['angle']
                frac = Fraction(int(int(angle_val)/2), 180)
                if frac.numerator == 1:
                    angle = r'\frac{{\pi}}{{{}}}'.format(frac.denominator)
                else:
                    angle = r'\frac{{{}}}{{{}}}\pi'.format(frac.numerator, frac.denominator)
            else:
                # single qubit pulse
                op_name = r'{{\rm {}}}'.format(match_dict['op'])
                angle_val = match_dict['angle']
                if angle_val is None:
                    angle = r'\pi'
                else:
                    frac = Fraction(int(angle_val), 180)
                    if frac.numerator == 1:
                        angle = r'\frac{{\pi}}{{{}}}'.format(frac.denominator)
                    else:
                        angle = r'\frac{{{}}}{{{}}}\pi'.format(frac.numerator, frac.denominator)
            latex_name = r'{}({}{})'.format(op_name, sign, angle)
        else:
            latex_name = None

    text = drawing_objects.TextData(data_type=types.DrawingLabel.PULSE_NAME,
                                    channels=data.inst.channel,
                                    xvals=[data.t0 + 0.5 * data.inst.duration],
                                    yvals=[formatter['label_offset.pulse_name']],
                                    text=systematic_name,
                                    latex=latex_name,
                                    ignore_scaling=True,
                                    styles=style)

    return [text]
Exemple #22
0
def gen_formatted_frame_values(
        data: types.PulseInstruction, formatter: Dict[str, Any],
        device: device_info.DrawerBackendInfo
) -> List[drawing_objects.TextData]:
    """Generate the formatted virtual Z rotation label and the frequency change label
    from provided frame instruction.

    Phase value is placed on top of the symbol, and frequency value is placed below the symbol.
    See :py:func:`gen_formatted_phase` and :py:func:`gen_formatted_freq_mhz` for details.

    Stylesheets:
        - The `frame_change` style is applied.
        - The `annotate` style is applied for font size.

    Args:
        data: Frame change instruction data to draw.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Returns:
        List of `TextData` drawing objects.
    """
    texts = []

    _max_denom = 10
    _unit = 'MHz'

    style = {
        'zorder': formatter['layer.frame_change'],
        'color': formatter['color.frame_change'],
        'size': formatter['text_size.annotate'],
        'ha': 'center'
    }

    # phase value
    if data.frame.phase != 0:
        plain_phase, latex_phase = _phase_to_text(data.frame.phase,
                                                  _max_denom,
                                                  flip=True)
        phase_style = {'va': 'bottom'}
        phase_style.update(style)

        phase = drawing_objects.TextData(
            data_type=types.DrawingLabel.FRAME,
            channels=data.inst[0].channel,
            xvals=[data.t0],
            yvals=[formatter['label_offset.frame_change']],
            text='VZ({phase})'.format(phase=plain_phase),
            latex=r'{{\rm VZ}}({phase})'.format(phase=latex_phase),
            ignore_scaling=True,
            styles=phase_style)
        texts.append(phase)

    # frequency value
    if data.frame.freq != 0:
        plain_freq, latex_freq = _freq_to_text(data.frame.freq, _unit)
        freq_style = {'va': 'top'}
        freq_style.update(style)

        freq = drawing_objects.TextData(
            data_type=types.DrawingLabel.FRAME,
            channels=data.inst[0].channel,
            xvals=[data.t0],
            yvals=[-formatter['label_offset.frame_change']],
            text=u'\u0394f = {freq}'.format(freq=plain_freq),
            latex=r'\Delta f = {freq}'.format(freq=latex_freq),
            ignore_scaling=True,
            styles=freq_style)
        texts.append(freq)

    return texts