Skip to content

Commit

Permalink
Merge pull request #137 from nwittler/log-reader
Browse files Browse the repository at this point in the history
Updated log reader and added docs.
  • Loading branch information
nwittler authored Aug 19, 2021
2 parents dcdb2be + a2771fa commit 2b4625f
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 29 deletions.
68 changes: 39 additions & 29 deletions c3/utils/log_reader.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
#!/usr/bin/python -u
#!/usr/bin/env python3

import time
import argparse
import hjson
from c3.c3objs import hjson_decode
from typing import Any, Dict

from c3.utils.utils import num3str
from rich.console import Console
from rich.table import Table


parser = argparse.ArgumentParser()
parser.add_argument("log_file")
parser.add_argument("-w", "--watch", action="store_true")
args = parser.parse_args()

log = None

try:
with open(args.log_file) as file:
log = hjson.load(file, object_pairs_hook=hjson_decode)
except FileNotFoundError:
print("Logfile not found.")
def show_table(log: Dict[str, Any], console: Console) -> None:
"""Generate a rich table from an optimization status and display it on the console.

def show_table():
Parameters
----------
log : Dict
Dictionary read from a json log file containing a c3-toolset optimization status.
console : Console
Rich console for output.
"""
if log:
opt_map = log["opt_map"]
optim_status = log["optim_status"]
Expand All @@ -35,19 +31,16 @@ def show_table():
table.add_column("Parameter")
table.add_column("Value", justify="right")
table.add_column("Gradient", justify="right")
for ii in range(len(opt_map)):
equiv_ids = opt_map[ii]
for ii, equiv_ids in enumerate(opt_map):
par = params[ii]
grad = grads[ii]
par = num3str(par)
grad = num3str(grad)
par_id = equiv_ids[0]
nice_id = "-".join(par_id)
table.add_row(nice_id, par + units[ii], grad + units[ii])
table.add_row(par_id, par + units[ii], grad + units[ii])
if len(equiv_ids) > 1:
for par_id in equiv_ids[1:]:
nice_id = "-".join(par_id)
table.add_row(nice_id, "''", "''")
table.add_row(par_id, "''", "''")

console.clear()
print(
Expand All @@ -56,10 +49,27 @@ def show_table():
console.print(table)


console = Console()
if args.watch:
while True:
show_table()
time.sleep(5)
else:
show_table()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("log_file")
parser.add_argument(
"-w",
"--watch",
type=int,
default=0,
help="Update the table every WATCH seconds.",
)
args = parser.parse_args()

try:
with open(args.log_file) as file:
log = hjson.load(file)
console = Console()
if args.watch:
while True:
show_table(log, console)
time.sleep(args.watch)
else:
show_table(log, console)
except FileNotFoundError:
print("Logfile not found. Quiting...")
Empty file removed c3/utils/parsers.py
Empty file.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ When combined in sequence, these three procedures represent a recipe for system
optimal_control
Simulated_calibration
Simulated_Model_Learning
log_reader
c3_qiskit_example
c3

Expand Down
48 changes: 48 additions & 0 deletions docs/log_reader.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Logs and current optimization status
====================================

During optimizations (optimal control, calibration, model learning), a
current best point is stored in the log folder to monitor progress.
Called on a log file it will print a
`rich <https://github.com/willmcgugan/rich>`__ table of the current
status. With the ``-w`` or ``-- watch`` options the table will keep
updating.

.. code:: bash
c3/utils/log_reader.py -h
.. code-block::
usage: log_reader.py [-h] [-w WATCH] log_file
positional arguments:
log_file
optional arguments:
-h, --help show this help message and exit
-w WATCH, --watch WATCH
Update the table every WATCH seconds.
Using the example log from the test folder:

.. code:: bash
c3/utils/log_reader.py test/sample_optim_log.c3log
.. parsed-literal::
Optimization reached 0.00462 at Tue Aug 17 15:28:09 2021
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
┃ Parameter ┃ Value ┃ Gradient ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
│ rx90p[0]-d1-gauss-amp │ 497.311 mV │ 18.720 mV │
│ rx90p[0]-d1-gauss-freq_offset │ -52.998 MHz 2pi │ -414.237 µHz 2pi │
│ rx90p[0]-d1-gauss-xy_angle │ -47.409 mrad │ 2.904 mrad │
│ rx90p[0]-d1-gauss-delta │ -1.077 │ 6.648 m │
└───────────────────────────────┴─────────────────┴──────────────────┘
1 change: 1 addition & 0 deletions test/sample_optim_log.c3log
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"opt_map": [["rx90p[0]-d1-gauss-amp"], ["rx90p[0]-d1-gauss-freq_offset"], ["rx90p[0]-d1-gauss-xy_angle"], ["rx90p[0]-d1-gauss-delta"]], "units": ["V", "Hz 2pi", "rad", ""], "optim_status": {"params": [0.49731057256150457, -52997604.24565414, -0.0474089606329513, -1.0765842275871154], "goal": 0.004623751716391289, "time": "Tue Aug 17 15:28:09 2021", "gradient": [0.018719753658557353, -0.00041423747880565335, 0.0029041996681835715, 0.006648118709775015]}}
23 changes: 23 additions & 0 deletions test/test_cli_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
Tests for command line utilities.
"""

import pytest
import hjson
from rich.console import Console

from c3.c3objs import hjson_decode
from c3.utils.log_reader import show_table

SAMPLE_LOG = "test/sample_optim_log.c3log"


@pytest.mark.unit
def test_log_viewer():
"""
Check that the log is read and processed without error. This does not check if
the output is correct.
"""
console = Console()
with open(SAMPLE_LOG) as logfile:
show_table(hjson.load(logfile, object_pairs_hook=hjson_decode), console)

0 comments on commit 2b4625f

Please sign in to comment.