You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### Summary
This PR modifies `ScatterTable` which is introduced in #1253.
This change resolves some code issues in #1315 and #1243.
### Details and comments
In the original design `ScatterTable` is tied to the fit models, and the
columns contains `model_name` (str) and `model_id` (int). Also the fit
module only allows to have three categorical data; "processed",
"formatted", "fitted". However, #1243 breaks this assumption, namely,
the `StarkRamseyXYAmpScanAnalysis` fitter defines two fit models which
are not directly mapped to the results data. The data fed into the
models is synthesized by consuming the input results data. The fitter
needs to manage four categorical data; "raw", "ramsey" (raw results),
"phase" (synthesized data for fit), and "fitted".
This PR relaxes the tight coupling of data to the fit model. In above
example, "raw" and "ramsey" category data can fill new fields `name`
(formally model_name) and `class_id` (model_id) without indicating a
particular fit model. Usually, raw category data is just classified
according to the `data_subfit_map` definition, and the map doesn't need
to match with the fit models. The connection to fit models is only
introduced in a particular category defined by new option value
`fit_category`. This option defaults to "formatted", but
`StarkRamseyXYAmpScanAnalysis` fitter would set "phase" instead. Thus
fit model assignment is effectively delayed until the formatter
function.
Also the original scatter table is designed to store all circuit
metadata which causes some problem in data formatting, especially when
it tries to average the data over the same x value in the group.
Non-numeric data is averaged by builtin set operation, but this assumes
the metadata value is hashable object, which is not generally true. This
PR also drops all metadata from the scatter table. Note that important
metadata fields for the curve analysis are one used for model
classification (classifier fields), and other fields just decorate the
table with unnecessary memory footprint requirements. The classifier
fields and `name` (`class_id`) are sort of duplicated information. This
implies the `name` and `class_id` fields are enough for end-users to
reuse the table data for further analysis once after it's saved as an
artifact.
---------
Co-authored-by: Will Shanks <[email protected]>
Copy file name to clipboardExpand all lines: docs/tutorials/curve_analysis.rst
+76-35Lines changed: 76 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,33 +23,12 @@ different sets of experiment results. A single experiment can define sub-experim
23
23
consisting of multiple circuits which are tagged with common metadata,
24
24
and curve analysis sorts the experiment results based on the circuit metadata.
25
25
26
-
This is an example of showing the abstract data structure of a typical curve analysis experiment:
26
+
This is an example showing the abstract data flow of a typical curve analysis experiment:
27
27
28
-
.. jupyter-input::
29
-
:emphasize-lines: 1,10,19
30
-
31
-
"experiment"
32
-
- circuits[0] (x=x1_A, "series_A")
33
-
- circuits[1] (x=x1_B, "series_B")
34
-
- circuits[2] (x=x2_A, "series_A")
35
-
- circuits[3] (x=x2_B, "series_B")
36
-
- circuits[4] (x=x3_A, "series_A")
37
-
- circuits[5] (x=x3_B, "series_B")
38
-
- ...
39
-
40
-
"experiment data"
41
-
- data[0] (y1_A, "series_A")
42
-
- data[1] (y1_B, "series_B")
43
-
- data[2] (y2_A, "series_A")
44
-
- data[3] (y2_B, "series_B")
45
-
- data[4] (y3_A, "series_A")
46
-
- data[5] (y3_B, "series_B")
47
-
- ...
48
-
49
-
"analysis"
50
-
- "series_A": y_A = f_A(x_A; p0, p1, p2)
51
-
- "series_B": y_B = f_B(x_B; p0, p1, p2)
52
-
- fixed parameters {p1: v}
28
+
.. figure:: images/curve_analysis_structure.png
29
+
:width:600
30
+
:align:center
31
+
:class:no-scaled-link
53
32
54
33
Here the experiment runs two subsets of experiments, namely, series A and series B.
55
34
The analysis defines corresponding fit models :math:`f_A(x_A)` and :math:`f_B(x_B)`.
@@ -289,21 +268,78 @@ A developer can override this method to perform initialization of analysis-speci
289
268
290
269
Curve analysis calls the :meth:`_run_data_processing` method, where
291
270
the data processor in the analysis option is internally called.
292
-
This consumes input experiment results and creates the :class:`.CurveData` dataclass.
293
-
Then the :meth:`_format_data` method is called with the processed dataset to format it.
271
+
This consumes input experiment results and creates the :class:`.ScatterTable` dataframe.
272
+
This table may look like:
273
+
274
+
.. code-block::
275
+
276
+
xval yval yerr name class_id category shots
277
+
0 0.1 0.153659 0.011258 A 0 raw 1024
278
+
1 0.1 0.590732 0.015351 B 1 raw 1024
279
+
2 0.1 0.315610 0.014510 A 0 raw 1024
280
+
3 0.1 0.376098 0.015123 B 1 raw 1024
281
+
4 0.2 0.937073 0.007581 A 0 raw 1024
282
+
5 0.2 0.323415 0.014604 B 1 raw 1024
283
+
6 0.2 0.538049 0.015565 A 0 raw 1024
284
+
7 0.2 0.530244 0.015581 B 1 raw 1024
285
+
8 0.3 0.143902 0.010958 A 0 raw 1024
286
+
9 0.3 0.261951 0.013727 B 1 raw 1024
287
+
10 0.3 0.830732 0.011707 A 0 raw 1024
288
+
11 0.3 0.874634 0.010338 B 1 raw 1024
289
+
290
+
where the experiment consists of two subset series A and B, and the experiment parameter (xval)
291
+
is scanned from 0.1 to 0.3 in each subset. In this example, the experiment is run twice
292
+
for each condition. The role of each column is as follows:
293
+
294
+
- ``xval``: Parameter scanned in the experiment. This value must be defined in the circuit metadata.
295
+
- ``yval``: Nominal part of the outcome. The outcome is something like expectation value, which is computed from the experiment result with the data processor.
296
+
- ``yerr``: Standard error of the outcome, which is mainly due to sampling error.
297
+
- ``name``: Unique identifier of the result class. This is defined by the ``data_subfit_map`` option.
298
+
- ``class_id``: Numerical index corresponding to the result class. This number is automatically assigned.
299
+
- ``category``: The attribute of data set. The "raw" category indicates an output from the data processing.
300
+
- ``shots``: Number of measurement shots used to acquire this result.
301
+
302
+
3. Formatting
303
+
^^^^^^^^^^^^^
304
+
305
+
Next, the processed dataset is converted into another format suited for the fitting and
306
+
every valid result is assigned a class corresponding to a fit model.
294
307
By default, the formatter takes average of the outcomes in the processed dataset
295
308
over the same x values, followed by the sorting in the ascending order of x values.
296
309
This allows the analysis to easily estimate the slope of the curves to
297
310
create algorithmic initial guess of fit parameters.
298
311
A developer can inject extra data processing, for example, filtering, smoothing,
299
312
or elimination of outliers for better fitting.
313
+
The new class_id is given here so that its value corresponds to the fit model object index
314
+
in this analysis class. This index mapping is done based upon the correspondence of
315
+
the data name and the fit model name.
316
+
317
+
This is done by calling :meth:`_format_data` method.
318
+
This may return new scatter table object with the addition of rows like the following below.
319
+
320
+
.. code-block::
321
+
322
+
12 0.1 0.234634 0.009183 A 0 formatted 2048
323
+
13 0.2 0.737561 0.008656 A 0 formatted 2048
324
+
14 0.3 0.487317 0.008018 A 0 formatted 2048
325
+
15 0.1 0.483415 0.010774 B 1 formatted 2048
326
+
16 0.2 0.426829 0.010678 B 1 formatted 2048
327
+
17 0.3 0.568293 0.008592 B 1 formatted 2048
328
+
329
+
The default :meth:`_format_data` method adds its output data with the category "formatted".
330
+
This category name must be also specified in the analysis option ``fit_category``.
331
+
If overriding this method to do additional processing after the default formatting,
332
+
the ``fit_category`` analysis option can be set to choose a different category name to use to
333
+
select the data to pass to the fitting routine.
334
+
The (x, y) value in each row is passed to the corresponding fit model object
335
+
to compute residual values for the least square optimization.
300
336
301
337
3. Fitting
302
338
^^^^^^^^^^
303
339
304
-
Curve analysis calls the :meth:`_run_curve_fit` method, which is the core functionality of the fitting.
305
-
Another method :meth:`_generate_fit_guesses` is internally called to
306
-
prepare the initial guess and parameter boundary with respect to the formatted data.
340
+
Curve analysis calls the :meth:`_run_curve_fit` method with the formatted subset of the scatter table.
341
+
This internally calls :meth:`_generate_fit_guesses` to prepare
342
+
the initial guess and parameter boundary with respect to the formatted dataset.
307
343
Developers usually override this method to provide better initial guesses
308
344
tailored to the defined fit model or type of the associated experiment.
309
345
See :ref:`curve_analysis_init_guess` for more details.
@@ -314,13 +350,18 @@ custom fitting algorithms. This method must return a :class:`.CurveFitResult` da
314
350
^^^^^^^^^^^^^^^^^^
315
351
316
352
Curve analysis runs several postprocessing against the fit outcome.
317
-
It calls :meth:`._create_analysis_results` to create the :class:`.AnalysisResultData` class
353
+
When the fit is successful, it calls :meth:`._create_analysis_results` to create the :class:`.AnalysisResultData` objects
318
354
for the fitting parameters of interest. A developer can inject custom code to
319
355
compute custom quantities based on the raw fit parameters.
320
356
See :ref:`curve_analysis_results` for details.
321
-
Afterwards, figure plotting is handed over to the :doc:`Visualization </tutorials/visualization>` module via
322
-
the :attr:`~.CurveAnalysis.plotter` attribute, and a list of created analysis results and the figure are returned.
323
-
357
+
Afterwards, fit curves are computed with the fit models and optimal parameters, and the scatter table is
358
+
updated with the computed (x, y) values. This dataset is stored under the "fitted" category.
359
+
360
+
Finally, the :meth:`._create_figures` method is called with the entire scatter table data
361
+
to initialize the curve plotter instance accessible via the :attr:`~.CurveAnalysis.plotter` attribute.
362
+
The visualization is handed over to the :doc:`Visualization </tutorials/visualization>` module,
363
+
which provides a standardized image format for curve fit results.
364
+
A developer can overwrite this method to draw custom images.
0 commit comments