Skip to content
Merged
Show file tree
Hide file tree
Changes from 101 commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
d3af475
move from terra
jyu00 Jun 17, 2021
7506759
run black
jyu00 Jun 17, 2021
4503267
convert service exception to log
jyu00 Jun 17, 2021
5e97146
fix lint
jyu00 Jun 17, 2021
b5abffa
Integration with result database
yaelbh Jun 17, 2021
d94668f
some brief fixes
yaelbh Jun 17, 2021
6bd5c64
log post processing failure
jyu00 Jun 17, 2021
1780a37
remove data index
jyu00 Jun 17, 2021
1d408c9
Merge remote-tracking branch 'jessie/results-db' into integrate_resdb
jyu00 Jun 17, 2021
26b76df
fix t1 t2 tests
jyu00 Jun 17, 2021
e3a2d31
fix test can package typo
jyu00 Jun 17, 2021
9a0be50
Merge remote-tracking branch 'jessie/results-db' into integrate_resdb
jyu00 Jun 17, 2021
ce1c917
fix package typo
jyu00 Jun 17, 2021
b727010
Merge branch 'main' into results-db
yaelbh Jun 20, 2021
abb6f8d
Merge branch 'main' into integrate_resdb
yaelbh Jun 20, 2021
c066274
fixed errors in conlicts resolve
yaelbh Jun 20, 2021
e4bdbe6
adjusted a test to the new classes
yaelbh Jun 20, 2021
7100638
made test_spectroscopy_end2end_classified pass
yaelbh Jun 20, 2021
f031947
adjusted all spectro tests
yaelbh Jun 20, 2021
e83add3
test_curve_fit passes
yaelbh Jun 20, 2021
cf57d81
adjusted rabi
yaelbh Jun 20, 2021
a14144c
black
yaelbh Jun 20, 2021
efe028e
lint
yaelbh Jun 20, 2021
ad33800
fixed test_source
yaelbh Jun 20, 2021
557556e
fix doc build
jyu00 Jun 21, 2021
ad8ec3d
Merge branch 'main' into integrate_resdb
yaelbh Jun 22, 2021
b040f24
fix figure thread error
jyu00 Jun 22, 2021
12aa89d
run black
jyu00 Jun 23, 2021
bac561d
remove ResultDict
jyu00 Jun 23, 2021
d2482ac
Merge remote-tracking branch 'upstream/main' into results-db
jyu00 Jun 23, 2021
8139169
Merge remote-tracking branch 'origin/results-db' into results-db
jyu00 Jun 23, 2021
949cc89
Merge branch 'pr113' into integrate_resdb
yaelbh Jun 23, 2021
1fd9dd5
remove experiment_class and result_class
jyu00 Jun 23, 2021
404d7be
fix lint
jyu00 Jun 23, 2021
bab4294
Merge branch 'pr113' into integrate_resdb
yaelbh Jun 24, 2021
aa507c8
Merge branch 'main' into results-db
yaelbh Jun 24, 2021
ed1b4f3
Merge branch 'pr113' into integrate_resdb
yaelbh Jun 24, 2021
3c0fa26
fixes
yaelbh Jun 24, 2021
248f5aa
Merge branch 'main' into results-db
yaelbh Jun 24, 2021
7bc4b2a
adjusted tes_update_library
yaelbh Jun 24, 2021
34def38
lint
yaelbh Jun 24, 2021
b367355
Merge branch 'main' into results-db
yaelbh Jun 24, 2021
c09d010
Merge branch 'main' into results-db
yaelbh Jun 24, 2021
87f2355
Merge branch 'main' into results-db
yaelbh Jun 27, 2021
a0cd036
Merge branch 'pr113' into integrate_resdb
yaelbh Jun 27, 2021
84d339f
black
yaelbh Jun 27, 2021
f09667c
doc update
jyu00 Jun 28, 2021
c98e2c6
rename classes
jyu00 Jun 28, 2021
9070a89
review comments
jyu00 Jun 28, 2021
25c5156
Merge remote-tracking branch 'origin/results-db' into results-db
jyu00 Jun 28, 2021
5205ee6
fix lint
jyu00 Jun 28, 2021
ba0d38f
Merge branch 'pr113' into integrate_resdb
yaelbh Jun 29, 2021
d188beb
black
yaelbh Jun 29, 2021
11d392a
Merge branch 'main' into results-db
yaelbh Jun 29, 2021
3af7331
Merge branch 'pr113' into integrate_resdb
yaelbh Jun 29, 2021
d5bb8d0
black
yaelbh Jun 29, 2021
08aea6e
Merge branch 'main' into integrate_resdb
yaelbh Jul 7, 2021
e2b486c
catch failed analysis + black
yaelbh Jul 7, 2021
7208399
omit prefix computer_ from quality
yaelbh Jul 7, 2021
8ff3f11
removed debug print
yaelbh Jul 7, 2021
c9ad448
fix docs build
yaelbh Jul 7, 2021
539b723
added meas_level to mock iq backend header
yaelbh Jul 7, 2021
cafeb3e
Merge branch 'main' into integrate_resdb
yaelbh Jul 7, 2021
7f6e370
black
yaelbh Jul 7, 2021
724245b
removed the call to get_memory
yaelbh Jul 8, 2021
d5d0418
Merge branch 'main' into integrate_resdb
yaelbh Jul 8, 2021
a2163ef
adjusted test_rb_analysis
yaelbh Jul 8, 2021
e2d5d1d
fix analysis result __str__
jyu00 Jul 7, 2021
18ce8ab
add callable to encoder
jyu00 Jul 8, 2021
01ce067
fix lint
jyu00 Jul 8, 2021
7c3a274
fix lint again
jyu00 Jul 8, 2021
9933648
log all job failure
jyu00 Jul 8, 2021
859e83f
lint
jyu00 Jul 8, 2021
fb24bd3
Merge remote-tracking branch 'upstream/main' into integrate_resdb
jyu00 Jul 9, 2021
7dc8bbc
fix test
jyu00 Jul 9, 2021
8a50a45
return DbAnalysisResultV1 for t1 t2
jyu00 Jul 9, 2021
1013adb
Merge branch 'main' into integrate_resdb
yaelbh Jul 11, 2021
d29e8aa
Merge branch 'main' into integrate_resdb
yaelbh Jul 11, 2021
b82d134
Merge remote-tracking branch 'upstream/main' into integrate_resdb
jyu00 Jul 12, 2021
4791707
Merge branch 'main' into integrate_resdb
yaelbh Jul 13, 2021
e1b44b3
Merge branch 'main' into integrate_resdb
yaelbh Jul 13, 2021
1489331
Merge branch 'integrate_resdb' of https://github.com/yaelbh/qiskit-ex…
jyu00 Jul 13, 2021
0d6e3c9
review comments
jyu00 Jul 14, 2021
2a1981c
Add `load` method to `DbExperimentDataV1` and `DbAnalysisResultV1`
chriseclectic Jul 14, 2021
e150dad
Merge pull request #2 from chriseclectic/deserialize
yaelbh Jul 15, 2021
63e5ab7
Revert "Merge pull request #2 from chriseclectic/deserialize"
yaelbh Jul 15, 2021
fcace07
updated tomography qubits
yaelbh Jul 15, 2021
89391c2
Add `load` method to `DbExperimentDataV1` and `DbAnalysisResultV1`
chriseclectic Jul 14, 2021
fed136d
Rename `save` to `save_metadata`, `save_all` to `save`
chriseclectic Jul 15, 2021
5bbd07f
changed analysis result classes
yaelbh Jul 15, 2021
38799a6
black
yaelbh Jul 15, 2021
71d3a3c
lint
yaelbh Jul 15, 2021
6e656a6
fixes related to AnalysisResultData
yaelbh Jul 15, 2021
09538f7
allow all objects in encoder
jyu00 Jul 16, 2021
bb19b66
call save if auto save set
jyu00 Jul 16, 2021
793c20e
fix tests
jyu00 Jul 16, 2021
ee56d6e
Merge branch 'main' into integrate_resdb
yaelbh Jul 18, 2021
5f300f8
fixed test_fine_amplitude
yaelbh Jul 18, 2021
955b7f6
lint
yaelbh Jul 18, 2021
f96ce73
black
yaelbh Jul 18, 2021
16d7f6d
Merge branch 'main' into integrate_resdb
chriseclectic Jul 19, 2021
ce3b30e
Merge branch 'main' into integrate_resdb
yaelbh Jul 20, 2021
5f967e9
adjust to recent changes in main
yaelbh Jul 20, 2021
c5a3a64
fixes related to AnalysisResultData
yaelbh Jul 20, 2021
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
3 changes: 1 addition & 2 deletions qiskit_experiments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
:toctree: ../stubs/

ExperimentData
AnalysisResult


Experiment Base Classes
Expand All @@ -49,7 +48,7 @@
from .version import __version__

# Base Classes
from .experiment_data import ExperimentData, AnalysisResult
from .experiment_data import ExperimentData
from .base_analysis import BaseAnalysis
from .base_experiment import BaseExperiment

Expand Down
2 changes: 1 addition & 1 deletion qiskit_experiments/analysis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
from .curve_analysis import CurveAnalysis, SeriesDef, CurveData

from .curve_fitting import (
CurveAnalysisResult,
CurveAnalysisResultData,
curve_fit,
multi_curve_fit,
process_curve_data,
Expand Down
225 changes: 113 additions & 112 deletions qiskit_experiments/analysis/curve_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@
from qiskit.providers.options import Options

from qiskit_experiments.analysis import plotting
from qiskit_experiments.analysis.curve_fitting import multi_curve_fit, CurveAnalysisResult
from qiskit_experiments.analysis.curve_fitting import (
multi_curve_fit,
CurveAnalysisResultData,
)
from qiskit_experiments.analysis.utils import get_opt_value, get_opt_error
from qiskit_experiments.base_analysis import BaseAnalysis
from qiskit_experiments.data_processing import DataProcessor
from qiskit_experiments.data_processing.exceptions import DataProcessorError
from qiskit_experiments.exceptions import AnalysisError
from qiskit_experiments.experiment_data import AnalysisResult, ExperimentData
from qiskit_experiments.experiment_data import ExperimentData
from qiskit_experiments.matplotlib import requires_matplotlib
from qiskit_experiments.data_processing.processor_library import get_processor


Expand Down Expand Up @@ -322,7 +326,7 @@ def curve_fitter(
bounds: Optional[
Union[Dict[str, Tuple[float, float]], Tuple[ndarray, ndarray]]
],
) -> CurveAnalysisResult:
) -> CurveAnalysisResultData:

See :func:`~qiskit_experiment.analysis.multi_curve_fit` for example.
data_processor: A callback function to format experiment data.
Expand Down Expand Up @@ -361,125 +365,120 @@ def data_processor(data: Dict[str, Any]) -> Tuple[float, float]
return_data_points=False,
)

def _create_figures(self, analysis_results: CurveAnalysisResult) -> List["Figure"]:
@requires_matplotlib
def _create_figures(self, result_data: CurveAnalysisResultData) -> List["Figure"]:
"""Create new figures with the fit result and raw data.

Subclass can override this method to create different type of figures.
Subclass can override this method to create different type of figures, but
the ``requires_matplotlib`` decorator is needed to ensure this method
works with ``DbExperimentData``.

Args:
analysis_results: Analysis result containing fit parameters.
result_data: Result data containing fit parameters.

Returns:
List of figures.
"""
fit_available = all(key in analysis_results for key in ("popt", "popt_err", "xrange"))
fit_available = all(key in result_data for key in ("popt", "popt_err", "xrange"))

if plotting.HAS_MATPLOTLIB:
axis = self._get_option("axis")
if axis is None:
figure = plotting.pyplot.figure(figsize=(8, 5))
axis = figure.subplots(nrows=1, ncols=1)
else:
figure = axis.get_figure()

axis = self._get_option("axis")
if axis is None:
figure = plotting.pyplot.figure(figsize=(8, 5))
axis = figure.subplots(nrows=1, ncols=1)
else:
figure = axis.get_figure()
ymin, ymax = np.inf, -np.inf
for series_def in self.__series__:

ymin, ymax = np.inf, -np.inf
for series_def in self.__series__:
# plot raw data

# plot raw data
curve_data_raw = self._data(series_name=series_def.name, label="raw_data")
ymin = min(ymin, *curve_data_raw.y)
ymax = max(ymax, *curve_data_raw.y)
plotting.plot_scatter(xdata=curve_data_raw.x, ydata=curve_data_raw.y, ax=axis, zorder=0)

curve_data_raw = self._data(series_name=series_def.name, label="raw_data")
ymin = min(ymin, *curve_data_raw.y)
ymax = max(ymax, *curve_data_raw.y)
plotting.plot_scatter(
xdata=curve_data_raw.x, ydata=curve_data_raw.y, ax=axis, zorder=0
)
# plot formatted data

# plot formatted data
curve_data_fit = self._data(series_name=series_def.name, label="fit_ready")
if np.all(np.isnan(curve_data_fit.y_err)):
sigma = None
else:
sigma = np.nan_to_num(curve_data_fit.y_err)

plotting.plot_errorbar(
xdata=curve_data_fit.x,
ydata=curve_data_fit.y,
sigma=sigma,
ax=axis,
label=series_def.name,
marker=series_def.plot_symbol,
color=series_def.plot_color,
zorder=1,
linestyle="",
)

curve_data_fit = self._data(series_name=series_def.name, label="fit_ready")
if np.all(np.isnan(curve_data_fit.y_err)):
sigma = None
else:
sigma = np.nan_to_num(curve_data_fit.y_err)
# plot fit curve

plotting.plot_errorbar(
xdata=curve_data_fit.x,
ydata=curve_data_fit.y,
sigma=sigma,
if fit_available:
plotting.plot_curve_fit(
func=series_def.fit_func,
result=result_data,
ax=axis,
label=series_def.name,
marker=series_def.plot_symbol,
color=series_def.plot_color,
zorder=1,
linestyle="",
zorder=2,
fit_uncertainty=series_def.plot_fit_uncertainty,
)

# plot fit curve

if fit_available:
plotting.plot_curve_fit(
func=series_def.fit_func,
result=analysis_results,
ax=axis,
color=series_def.plot_color,
zorder=2,
fit_uncertainty=series_def.plot_fit_uncertainty,
)

# format axis
# format axis

if len(self.__series__) > 1:
axis.legend(loc="center right")
axis.set_xlabel(self._get_option("xlabel"), fontsize=16)
axis.set_ylabel(self._get_option("ylabel"), fontsize=16)
axis.tick_params(labelsize=14)
axis.grid(True)
if len(self.__series__) > 1:
axis.legend(loc="center right")
axis.set_xlabel(self._get_option("xlabel"), fontsize=16)
axis.set_ylabel(self._get_option("ylabel"), fontsize=16)
axis.tick_params(labelsize=14)
axis.grid(True)

# automatic scaling y axis by actual data point.
# note that y axis will be scaled by confidence interval by default.
# sometimes we cannot see any data point if variance of parameters is too large.
# automatic scaling y axis by actual data point.
# note that y axis will be scaled by confidence interval by default.
# sometimes we cannot see any data point if variance of parameters is too large.

height = ymax - ymin
axis.set_ylim(ymin - 0.1 * height, ymax + 0.1 * height)
height = ymax - ymin
axis.set_ylim(ymin - 0.1 * height, ymax + 0.1 * height)

# write analysis report
# write analysis report

fit_reports = self._get_option("fit_reports")
if fit_reports and fit_available:
# write fit status in the plot
analysis_description = ""
for par_name, label in fit_reports.items():
try:
# fit value
pval = get_opt_value(analysis_results, par_name)
perr = get_opt_error(analysis_results, par_name)
except ValueError:
# maybe post processed value
pval = analysis_results[par_name]
perr = analysis_results[f"{par_name}_err"]
analysis_description += f"{label} = {pval: .3e}\u00B1{perr: .3e}\n"
chisq = analysis_results["reduced_chisq"]
analysis_description += f"Fit \u03C7-squared = {chisq: .4f}"

report_handler = axis.text(
0.60,
0.95,
analysis_description,
ha="center",
va="top",
size=14,
transform=axis.transAxes,
)
fit_reports = self._get_option("fit_reports")
if fit_reports and fit_available:
# write fit status in the plot
analysis_description = ""
for par_name, label in fit_reports.items():
try:
# fit value
pval = get_opt_value(result_data, par_name)
perr = get_opt_error(result_data, par_name)
except ValueError:
# maybe post processed value
pval = result_data[par_name]
perr = result_data[f"{par_name}_err"]
analysis_description += f"{label} = {pval: .3e}\u00B1{perr: .3e}\n"
chisq = result_data["reduced_chisq"]
analysis_description += f"Fit \u03C7-squared = {chisq: .4f}"

report_handler = axis.text(
0.60,
0.95,
analysis_description,
ha="center",
va="top",
size=14,
transform=axis.transAxes,
)

bbox_props = dict(
boxstyle="square, pad=0.3", fc="white", ec="black", lw=1, alpha=0.8
)
report_handler.set_bbox(bbox_props)
bbox_props = dict(boxstyle="square, pad=0.3", fc="white", ec="black", lw=1, alpha=0.8)
report_handler.set_bbox(bbox_props)

return [figure]
else:
return list()
return [figure]

def _setup_fitting(self, **options) -> Union[Dict[str, Any], List[Dict[str, Any]]]:
"""An analysis subroutine that is called to set fitter options.
Expand Down Expand Up @@ -566,18 +565,18 @@ def _format_data(self, data: CurveData) -> CurveData:
metadata=data.metadata,
)

def _post_analysis(self, analysis_result: CurveAnalysisResult) -> CurveAnalysisResult:
def _post_analysis(self, result_data: CurveAnalysisResultData) -> CurveAnalysisResultData:
"""Calculate new quantity from the fit result.

Subclasses can override this method to do post analysis.

Args:
analysis_result: Analysis result containing fit result.
result_data: Result containing fit result.

Returns:
New CurveAnalysisResult instance containing the result of post analysis.
Updated result data containing the result of post analysis.
"""
return analysis_result
return result_data

def _extract_curves(
self, experiment_data: ExperimentData, data_processor: Union[Callable, DataProcessor]
Expand Down Expand Up @@ -904,7 +903,7 @@ def _get_option(self, arg_name: str) -> Any:

def _run_analysis(
self, experiment_data: ExperimentData, **options
) -> Tuple[List[AnalysisResult], List["pyplot.Figure"]]:
) -> Tuple[List["AnalysisResultData"], List["pyplot.Figure"]]:
"""Run analysis on circuit data.

Args:
Expand All @@ -914,14 +913,14 @@ def _run_analysis(
Returns:
tuple: A pair ``(analysis_results, figures)`` where
``analysis_results`` may be a single or list of
AnalysisResult objects, and ``figures`` is a list of any
CurveAnalysisResultData objects, and ``figures`` is a list of any
figures for the experiment.

Raises:
AnalysisError: if the analysis fails.
"""
analysis_result = CurveAnalysisResult()
analysis_result["analysis_type"] = self.__class__.__name__
result_data = CurveAnalysisResultData()
result_data["analysis_type"] = self.__class__.__name__
figures = list()

#
Expand Down Expand Up @@ -1021,7 +1020,7 @@ def _run_analysis(
sigma=formatted_data.y_err,
**fit_options,
)
analysis_result.update(**fit_result)
result_data.update(**fit_result)
else:
# Multiple initial guesses
fit_options_candidates = [
Expand All @@ -1048,24 +1047,26 @@ def _run_analysis(
)
# Sort by chi squared value
fit_results = sorted(fit_results, key=lambda r: r["reduced_chisq"])
analysis_result.update(**fit_results[0])
result_data.update(**fit_results[0])

result_data["success"] = True

except AnalysisError as ex:
analysis_result["error_message"] = str(ex)
analysis_result["success"] = False
result_data["error_message"] = str(ex)
result_data["success"] = False

else:
#
# 5. Post-process analysis data
#
analysis_result = self._post_analysis(analysis_result=analysis_result)
result_data = self._post_analysis(result_data=result_data)

finally:
#
# 6. Create figures
#
if self._get_option("plot"):
figures.extend(self._create_figures(analysis_results=analysis_result))
if self._get_option("plot") and plotting.HAS_MATPLOTLIB:
figures.extend(self._create_figures(result_data=result_data))

#
# 7. Optionally store raw data points
Expand All @@ -1079,6 +1080,6 @@ def _run_analysis(
"ydata": series_data.y,
"sigma": series_data.y_err,
}
analysis_result["raw_data"] = raw_data_dict
result_data["raw_data"] = raw_data_dict

return [analysis_result], figures
return [result_data], figures
Loading