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]
def gen_channel_freqs( data: types.ChartAxis, formatter: Dict[str, Any], device: device_info.DrawerBackendInfo) -> List[drawings.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` drawings. """ style = { "zorder": formatter["layer.axis_label"], "color": formatter["color.axis_label"], "size": formatter["text_size.annotate"], "va": "center", "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 = drawings.TextData( data_type=types.LabelType.CH_INFO, channels=data.channels, xvals=[types.AbstractCoordinate.LEFT], yvals=[-formatter["label_offset.chart_info"]], text=freq_text or "no freq.", ignore_scaling=True, styles=style, ) return [text]
def qubit_index_sort( channels: List[pulse.channels.Channel], formatter: Dict[str, Any], device: DrawerBackendInfo ) -> Iterator[Tuple[str, List[pulse.channels.Channel]]]: """Layout function for the channel assignment to the chart instance. Assign multiple channels per chart. Channels associated with the same qubit are grouped in the same chart and sorted by qubit index in ascending order. Acquire channels are not shown. Stylesheet key: `chart_channel_map` For example: [D0, D2, C0, C2, M0, M2, A0, A2] -> [Q0, Q1, Q2] Args: channels: Channels to show. formatter: Dictionary of stylesheet settings. device: Backend configuration. Yields: Tuple of chart name and associated channels. """ _removed = ( pulse.channels.AcquireChannel, pulse.channels.MemorySlot, pulse.channels.RegisterSlot, ) qubit_channel_map = defaultdict(list) for chan in channels: if isinstance(chan, _removed): continue qubit_channel_map[device.get_qubit_index(chan)].append(chan) sorted_map = sorted(qubit_channel_map.items(), key=lambda x: x[0]) for qind, chans in sorted_map: yield f"Q{qind:d}", chans
def gen_filled_waveform_stepwise( data: types.PulseInstruction, formatter: Dict[str, Any], device: device_info.DrawerBackendInfo ) -> List[Union[drawings.LineData, drawings.BoxData, drawings.TextData]]: """Generate filled area objects of the real and the imaginary part of waveform envelope. The curve of envelope is not interpolated nor smoothed and presented as stepwise function at each data point. Stylesheets: - The `fill_waveform` style is applied. Args: data: Waveform instruction data to draw. formatter: Dictionary of stylesheet settings. device: Backend configuration. Returns: List of `LineData`, `BoxData`, or `TextData` drawings. Raises: VisualizationError: When the instruction parser returns invalid data format. """ # generate waveform data waveform_data = _parse_waveform(data) channel = data.inst.channel # update metadata meta = waveform_data.meta qind = device.get_qubit_index(channel) meta.update({"qubit": qind if qind is not None else "N/A"}) if isinstance(waveform_data, types.ParsedInstruction): # Draw waveform with fixed shape xdata = waveform_data.xvals ydata = waveform_data.yvals # phase modulation if formatter["control.apply_phase_modulation"]: ydata = np.asarray(ydata, dtype=complex) * np.exp( 1j * data.frame.phase) else: ydata = np.asarray(ydata, dtype=complex) return _draw_shaped_waveform(xdata=xdata, ydata=ydata, meta=meta, channel=channel, formatter=formatter) elif isinstance(waveform_data, types.OpaqueShape): # Draw parametric pulse with unbound parameters # parameter name unbound_params = [] for pname, pval in data.inst.pulse.parameters.items(): if isinstance(pval, circuit.ParameterExpression): unbound_params.append(pname) if hasattr(data.inst.pulse, "pulse_type"): pulse_shape = data.inst.pulse.pulse_type else: pulse_shape = data.inst.pulse.__class__.__name__ return _draw_opaque_waveform( init_time=data.t0, duration=waveform_data.duration, pulse_shape=pulse_shape, pnames=unbound_params, meta=meta, channel=channel, formatter=formatter, ) else: raise VisualizationError("Invalid data format is provided.")
def gen_filled_waveform_stepwise(data: types.PulseInstruction, formatter: Dict[str, Any], device: device_info.DrawerBackendInfo ) -> List[drawing_objects.LineData]: """Generate filled area objects of the real and the imaginary part of waveform envelope. The curve of envelope is not interpolated nor smoothed and presented as stepwise function at each data point. Stylesheets: - The `fill_waveform` style is applied. Args: data: Waveform instruction data to draw. formatter: Dictionary of stylesheet settings. device: Backend configuration. Returns: List of `LineData` drawing objects. """ fill_objs = [] # generate waveform data parsed = _parse_waveform(data) channel = data.inst.channel qubit = device.get_qubit_index(channel) if qubit is None: qubit = 'N/A' resolution = formatter['general.vertical_resolution'] # phase modulation if formatter['control.apply_phase_modulation']: ydata = np.asarray(parsed.yvals, dtype=np.complex) * np.exp(1j * data.frame.phase) else: ydata = np.asarray(parsed.yvals, dtype=np.complex) # stepwise interpolation xdata = np.concatenate((parsed.xvals, [parsed.xvals[-1] + 1])) ydata = np.repeat(ydata, 2) re_y = np.real(ydata) im_y = np.imag(ydata) time = np.concatenate(([xdata[0]], np.repeat(xdata[1:-1], 2), [xdata[-1]])) # setup style options style = {'alpha': formatter['alpha.fill_waveform'], 'zorder': formatter['layer.fill_waveform'], 'linewidth': formatter['line_width.fill_waveform'], 'linestyle': formatter['line_style.fill_waveform']} color_code = types.ComplexColors(*formatter[_fill_waveform_color(channel)]) # create real part if np.any(re_y): # data compression re_valid_inds = _find_consecutive_index(re_y, resolution) # stylesheet re_style = {'color': color_code.real} re_style.update(style) # metadata re_meta = {'data': 'real', 'qubit': qubit} re_meta.update(parsed.meta) # active xy data re_xvals = time[re_valid_inds] re_yvals = re_y[re_valid_inds] # object real = drawing_objects.LineData(data_type=types.DrawingWaveform.REAL, channels=channel, xvals=re_xvals, yvals=re_yvals, fill=True, meta=re_meta, styles=re_style) fill_objs.append(real) # create imaginary part if np.any(im_y): # data compression im_valid_inds = _find_consecutive_index(im_y, resolution) # stylesheet im_style = {'color': color_code.imaginary} im_style.update(style) # metadata im_meta = {'data': 'imag', 'qubit': qubit} im_meta.update(parsed.meta) # active xy data im_xvals = time[im_valid_inds] im_yvals = im_y[im_valid_inds] # object imag = drawing_objects.LineData(data_type=types.DrawingWaveform.IMAG, channels=channel, xvals=im_xvals, yvals=im_yvals, fill=True, meta=im_meta, styles=im_style) fill_objs.append(imag) return fill_objs