コード例 #1
0
    def _format_plot(hop_result: AnalysisResultData,
                     ax: Optional["matplotlib.pyplot.AxesSubplot"] = None):
        """Format the QV plot

        Args:
            hop_result: the heavy output probability analysis result.
            ax: matplotlib axis to add plot to.

        Returns:
            AxesSubPlot: the matplotlib axes containing the plot.
        """
        trials = hop_result.extra["trials"]
        heavy_probs = hop_result.extra["HOPs"]
        trial_list = np.arange(1, trials + 1)  # x data

        hop_accumulative = np.cumsum(heavy_probs) / trial_list
        two_sigma = 2 * (hop_accumulative *
                         (1 - hop_accumulative) / trial_list)**0.5

        # Plot individual HOP as scatter
        ax = plot_scatter(
            trial_list,
            heavy_probs,
            ax=ax,
            s=3,
            zorder=3,
            label="Individual HOP",
        )
        # Plot accumulative HOP
        ax.plot(trial_list,
                hop_accumulative,
                color="r",
                label="Cumulative HOP")

        # Plot two-sigma shaded area
        ax = plot_errorbar(
            trial_list,
            hop_accumulative,
            two_sigma,
            ax=ax,
            fmt="none",
            ecolor="lightgray",
            elinewidth=20,
            capsize=0,
            alpha=0.5,
            label="2$\\sigma$",
        )
        # Plot 2/3 success threshold
        ax.axhline(2 / 3,
                   color="k",
                   linestyle="dashed",
                   linewidth=1,
                   label="Threshold")

        ax.set_ylim(
            max(hop_accumulative[-1] - 4 * two_sigma[-1], 0),
            min(hop_accumulative[-1] + 4 * two_sigma[-1], 1),
        )

        ax.set_xlabel("Number of Trials", fontsize=14)
        ax.set_ylabel("Heavy Output Probability", fontsize=14)

        ax.set_title(
            "Quantum Volume experiment for depth " +
            str(hop_result.extra["depth"]) + " - accumulative hop",
            fontsize=14,
        )

        # Re-arrange legend order
        handles, labels = ax.get_legend_handles_labels()
        handles = [handles[1], handles[2], handles[0], handles[3]]
        labels = [labels[1], labels[2], labels[0], labels[3]]
        ax.legend(handles, labels)
        return ax
コード例 #2
0
    def _run_analysis(
        self,
        experiment_data: ExperimentData,
        user_p0: Optional[Dict[str, float]] = None,
        user_bounds: Optional[Tuple[List[float], List[float]]] = None,
        plot: bool = False,
        ax: Optional["AxesSubplot"] = None,
        **kwargs,
    ) -> Tuple[List[AnalysisResultData], List["matplotlib.figure.Figure"]]:
        r"""Calculate T2Ramsey experiment.

        Args:
            experiment_data (ExperimentData): the experiment data to analyze
            user_p0: contains initial values given by the user, for the
            fit parameters :math:`(a, t2ramsey, f, \phi, b)`
            user_bounds: lower and upper bounds on the parameters in p0,
                         given by the user.
                         The first tuple is the lower bounds,
                         The second tuple is the upper bounds.
                         For both params, the order is :math:`a, t2ramsey, f, \phi, b`.
            plot: if True, create the plot, otherwise, do not create the plot.
            ax: the plot object
            **kwargs: additional parameters for curve fit.

        Returns:
            The analysis result with the estimated :math:`t2ramsey` and 'f' (frequency)
            The graph of the function.
        """
        def osc_fit_fun(x, a, t2ramsey, f, phi, c):
            """Decay cosine fit function"""
            return a * np.exp(
                -x / t2ramsey) * np.cos(2 * np.pi * f * x + phi) + c

        def _format_plot(ax, unit, fit_result, conversion_factor):
            """Format curve fit plot"""
            # Formatting
            ax.tick_params(labelsize=14)
            ax.set_xlabel("Delay (s)", fontsize=12)
            ax.ticklabel_format(axis="x", style="sci", scilimits=(0, 0))
            ax.set_ylabel("Probability of measuring 0", fontsize=12)
            t2ramsey = fit_result["popt"][1] / conversion_factor
            t2_err = fit_result["popt_err"][1] / conversion_factor
            box_text = "$T_2Ramsey$ = {:.2f} \u00B1 {:.2f} {}".format(
                t2ramsey, t2_err, unit)
            bbox_props = dict(boxstyle="square,pad=0.3",
                              fc="white",
                              ec="black",
                              lw=1)
            ax.text(
                0.6,
                0.9,
                box_text,
                ha="center",
                va="center",
                size=12,
                bbox=bbox_props,
                transform=ax.transAxes,
            )
            return ax

        # implementation of  _run_analysis

        data = experiment_data.data()
        circ_metadata = data[0]["metadata"]
        unit = circ_metadata["unit"]
        conversion_factor = circ_metadata.get("dt_factor", None)
        osc_freq = circ_metadata.get("osc_freq", None)
        if conversion_factor is None:
            conversion_factor = 1 if unit in ("s",
                                              "dt") else apply_prefix(1, unit)

        xdata, ydata, sigma = process_curve_data(
            data, lambda datum: level2_probability(datum, "0"))

        t2ramsey_estimate = np.mean(xdata)
        p0, bounds = self._t2ramsey_default_params(conversion_factor, user_p0,
                                                   user_bounds,
                                                   t2ramsey_estimate, osc_freq)
        xdata *= conversion_factor
        fit_result = curve_fit(osc_fit_fun,
                               xdata,
                               ydata,
                               p0=list(p0.values()),
                               sigma=sigma,
                               bounds=bounds)
        fit_result = dataclasses.asdict(fit_result)
        fit_result["circuit_unit"] = unit
        if osc_freq is not None:
            fit_result["osc_freq"] = osc_freq
        if unit == "dt":
            fit_result["dt"] = conversion_factor
        quality = self._fit_quality(fit_result["popt"], fit_result["popt_err"],
                                    fit_result["reduced_chisq"])
        chisq = fit_result["reduced_chisq"]

        if plot:
            ax = plot_curve_fit(osc_fit_fun, fit_result, ax=ax)
            ax = plot_scatter(xdata, ydata, ax=ax)
            ax = plot_errorbar(xdata, ydata, sigma, ax=ax)
            _format_plot(ax, unit, fit_result, conversion_factor)
            figures = [ax.get_figure()]
        else:
            figures = None

        # Output unit is 'sec', regardless of the unit used in the input
        result_t2star = AnalysisResultData(
            "T2star",
            value=FitVal(fit_result["popt"][1], fit_result["popt_err"][1],
                         "s"),
            quality=quality,
            chisq=chisq,
            extra=fit_result,
        )
        result_freq = AnalysisResultData(
            "Frequency",
            value=FitVal(fit_result["popt"][2], fit_result["popt_err"][2],
                         "Hz"),
            quality=quality,
            chisq=chisq,
            extra=fit_result,
        )

        return [result_t2star, result_freq], figures