Skip to content

Commit

Permalink
Merge pull request #714 from qiboteam/qq_compare
Browse files Browse the repository at this point in the history
qq compare command to compare two qibocal reports
  • Loading branch information
andrea-pasquale authored Aug 13, 2024
2 parents d5c0f2d + c8984c2 commit 760b740
Show file tree
Hide file tree
Showing 11 changed files with 678 additions and 46 deletions.
18 changes: 16 additions & 2 deletions doc/source/getting-started/interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ regarding the protocols executed.
^^^^^^^^^^^

The previous commands are put together using ``qq auto`` which will perform data acquisition, post-processing and report generation.
When executing multiple protocols they are executed following the graph described in the action runcard.
The report is generated iteratively as soon as each protocol finished.
When executing multiple protocols they are executed following the actions specified in the runcard.

.. code-block::
Expand Down Expand Up @@ -103,3 +102,18 @@ your public ssh key (from the machine(s) you are planning to upload the report)
use the ``qq upload <output_folder>`` command.
You can also add a tag to be displayed on the server using ``qq upload <output_folder> --tag <tag_name>``.
This program will upload your report to the server and generate an unique URL.


``qq compare``
^^^^^^^^^^^^^


Using ``qq compare`` it is possible to compare together two ``Qibocal`` reports.

.. code-block::
qq compare <output_folder_1> <output_folder_2>
The folder with the report comparison can be specified with the option ``-o``, otherwise a default
name will be assigned similarly to the ``qq acquire`` command.
304 changes: 266 additions & 38 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ qibolab = "^0.1.8"
qibo = "^0.2.6"
numpy = "^1.26.4"
scipy = "^1.10.1"
pandas = "^1.4.3"
pandas = { version = "^2.2.2", extras = ["html"] }
pydantic = "^2.8.0"
click = "^8.1.3"
jinja2 = "^3.1.2"
Expand Down
13 changes: 13 additions & 0 deletions src/qibocal/auto/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,16 @@ def flush(self, output: Optional[Path] = None):
completed.flush()

# TODO: implement time_travel()


class DummyHistory:
"""Empty History object, used by `qq compare`.
Used for comparing multiple reports, as their history is not saved.
"""

def flush(self, output=None):
pass

def items(self):
return tuple()
28 changes: 28 additions & 0 deletions src/qibocal/cli/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ..auto.runcard import Runcard
from .acquisition import acquire as acquisition
from .autocalibration import autocalibrate
from .compare import compare_reports
from .fit import fit as fitting
from .report import report as reporting
from .update import update as updating
Expand Down Expand Up @@ -208,3 +209,30 @@ def upload(path, tag, author):
- FOLDER: input folder.
"""
upload_report(path, tag, author)


@command.command(context_settings=CONTEXT_SETTINGS)
@click.argument(
"report_1_path",
metavar="RUNCARD_1_PATH",
type=click.Path(exists=True, path_type=pathlib.Path),
)
@click.argument(
"report_2_path",
metavar="RUNCARD_2_PATH",
type=click.Path(exists=True, path_type=pathlib.Path),
)
@click.option(
"folder",
"-o",
type=click.Path(path_type=pathlib.Path),
help="Output folder. If not provided a standard name will generated.",
)
@click.option(
"force",
"-f",
is_flag=True,
help="Use --force option to overwrite the output folder.",
)
def compare(report_1_path, report_2_path, folder, force):
compare_reports(folder, report_1_path, report_2_path, force)
65 changes: 65 additions & 0 deletions src/qibocal/cli/compare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from pathlib import Path

from jinja2 import Environment, FileSystemLoader

from qibocal.auto.history import DummyHistory
from qibocal.auto.output import Output
from qibocal.web.compared_report import ComparedReport
from qibocal.web.report import STYLES, TEMPLATES, report_css_styles


def initialize_combined_report(
report_path: Path, output_folder: Path, force: bool
) -> tuple[Output, Path]:
"""Initialisation of the output.
Create the report directory and set up start-finish time, report title.
Args:
report_path (pathlib.Path): path of the folder containing one of the initial reports.
output_folder (pathlib.Path): path of the folder containing the combined report.
force (bool): if set to true, overwrites output_folder (if it already exists).
"""
combined_meta = Output.load(report_path).meta
combined_meta.start()
combined_report = Output(history=DummyHistory(), meta=combined_meta)
combined_report_path = combined_report.mkdir(output_folder, force)
combined_meta.title = combined_report_path.name
combined_meta.end()
combined_report.meta = combined_meta
return combined_report, combined_report_path


def compare_reports(folder: Path, path_1: Path, path_2: Path, force: bool):
"""Report comparison generation.
Currently only two reports can be combined together. Only tasks with the same id can be merged.
Tables display data from both reports side by side.
Plots display data from both reports.
Args:
folder (pathlib.Path): path of the folder containing the combined report.
path_1 (pathlib.Path): path of the first report to be compared.
path_2 (pathlib.Path): path of the second report to be compared.
force (bool): if set to true, overwrites folder (if it already exists).
"""
paths = [path_1, path_2]
env = Environment(loader=FileSystemLoader(TEMPLATES))
template = env.get_template("template.html")
combined_report, combined_report_path = initialize_combined_report(
path_1, output_folder=folder, force=force
)

html = template.render(
is_static=True,
css_styles=report_css_styles(STYLES),
path=combined_report_path,
title=combined_report.meta.title,
report=ComparedReport(
report_paths=paths,
folder=combined_report_path,
meta=combined_report.meta.dump(),
),
)
combined_report.dump(combined_report_path)
(combined_report_path / "index.html").write_text(html)
6 changes: 2 additions & 4 deletions src/qibocal/cli/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from qibocal.auto.output import Output
from qibocal.auto.task import Completed
from qibocal.config import log
from qibocal.web.report import STYLES, TEMPLATES, Report
from qibocal.web.report import STYLES, TEMPLATES, Report, report_css_styles

ReportOutcome = tuple[str, list[go.Figure]]
"""Report produced by protocol."""
Expand Down Expand Up @@ -70,13 +70,11 @@ def report(path: pathlib.Path, history: Optional[History] = None):
if history is None:
history = output.history

css_styles = f"<style>\n{pathlib.Path(STYLES).read_text()}\n</style>"

env = Environment(loader=FileSystemLoader(TEMPLATES))
template = env.get_template("template.html")
html = template.render(
is_static=True,
css_styles=css_styles,
css_styles=report_css_styles(STYLES),
path=path,
title=path.name,
report=Report(
Expand Down
Loading

0 comments on commit 760b740

Please sign in to comment.