diff --git a/README.md b/README.md
index 5574bd1..1442cb3 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
-# AutoDepGraph
+# AutoDepGraph
-[![PyPI](https://img.shields.io/pypi/v/adaptive.svg)](https://pypi.python.org/pypi/autodepgraph)
+[![PyPI](https://img.shields.io/pypi/v/autodepgraph.svg)](https://pypi.python.org/pypi/autodepgraph)
[![Build Status](https://travis-ci.org/AdriaanRol/AutoDepGraph.svg?branch=master)](https://travis-ci.org/AdriaanRol/AutoDepGraph)
-[![Codacy Badge](https://api.codacy.com/project/badge/Grade/ae46c58617ff45df9ac98446b3dc34ac)](https://www.codacy.com/app/adriaan-rol/AutoDepGraph?utm_source=github.com&utm_medium=referral&utm_content=AdriaanRol/AutoDepGraph&utm_campaign=Badge_Grade)
+[![Codacy Badge](https://api.codacy.com/project/badge/Grade/ae46c58617ff45df9ac98446b3dc34ac)](https://www.codacy.com/app/adriaan-rol/AutoDepGraph?utm_source=github.com&utm_medium=referral&utm_content=AdriaanRol/AutoDepGraph&utm_campaign=Badge_Grade)
[![Coverage Status](https://coveralls.io/repos/github/AdriaanRol/AutoDepGraph/badge.svg?branch=master)](https://coveralls.io/github/AdriaanRol/AutoDepGraph?branch=master)
[![DOI](https://zenodo.org/badge/85987885.svg)](https://zenodo.org/badge/latestdoi/85987885)
-AutoDepGraph is a framework for using dependency graphs to calibrate a system. It is heavily inspired by ["Physical qubit calibration on a directed acyclic graph"](https://arxiv.org/abs/1803.03226).
+AutoDepGraph is a framework for using dependency graphs to calibrate a system. It is heavily inspired by ["Physical qubit calibration on a directed acyclic graph"](https://arxiv.org/abs/1803.03226).
## Overview
AutoDepGraph consists of two main classes, the CalibrationNode and the Graph.
@@ -21,11 +21,11 @@ A CalibrationNode contains:
+ Bad (red): calibration or check has failed
+ unknown (grayed): checks of the node should be run
+ active (blue): calibration or check in progress
- - parents: the nodes it depends on
+ - parents: the nodes it depends on
- children: nodes that depend on this node
- check_function : name of function to be executed when check is called. This can be a method of another instrument.
- calibrate_function : name of function to be executed when calibrate is called. This can be a method of another instrument.
- - calibration_timeout: time in (s) after which a calibration times out.
+ - calibration_timeout: time in (s) after which a calibration times out.
- function
- execute or call
@@ -35,8 +35,8 @@ A CalibrationNode contains:
- calibrate
+ Executes the calibration routines of the node
-A Graph is a container of nodes, it is used for:
-- new graphs can be created by instantiating a graph and then using the add_node method to define new nodes.
+A Graph is a container of nodes, it is used for:
+- new graphs can be created by instantiating a graph and then using the add_node method to define new nodes.
- loading and saving the graph
- real-time visualization using pyqtgraph
- state of the node determines color of a node
@@ -45,7 +45,7 @@ A Graph is a container of nodes, it is used for:
![Example calibration graph](docs/example_graph.png)
-## Examples
+## Examples
For an introductory example see the example notebook. If you want to see how to use a specific function, see the tests located in the autodepgraph/tests folder.
## Installation
@@ -54,8 +54,8 @@ For an introductory example see the example notebook. If you want to see how to
- navigate to the repository and run `pip install -e .`
- verify success of installation by running `py.test`
-#### N.B. windows can be "problematic"
-Installation on windows is a bit more difficult, this relates mostly to the installation of pygraphviz. To install graphviz and pygraphviz on windows follow these steps:
+#### N.B. windows can be "problematic"
+Installation on windows is a bit more difficult, this relates mostly to the installation of pygraphviz. To install graphviz and pygraphviz on windows follow these steps:
- get the 64 bit version of ![graphviz for windows](https://github.com/mahkoCosmo/GraphViz_x64/), copy it to e.g., program files and add the bin folder to the system path.
- the 64 bit version lacks the libxml2.dll, you most likely have this from some other program. You can find this by searching for `libxml2.dll` in the program files folder. After that just copy paste it to the bin folder of graphviz.
@@ -69,4 +69,4 @@ python setup.py install --include-path="C:\Program Files\graphviz-2.38_x64\inclu
- then install autodepgraph and test the installation using `py.test`
## Acknowledgements
-I would like to thank Julian Kelly for the idea of using a dependency graph for calibrations and for early discussions. I would like to thank Joe Weston for discussions and help in working out the initial design. I would like to acknowledge Livio Ciorciaro for disucssions and as a coauthor of this project.
+I would like to thank Julian Kelly for the idea of using a dependency graph for calibrations and for early discussions. I would like to thank Joe Weston for discussions and help in working out the initial design. I would like to acknowledge Livio Ciorciaro for disucssions and as a coauthor of this project.
diff --git a/autodepgraph/graph.py b/autodepgraph/graph.py
index 5f92ef9..6058474 100644
--- a/autodepgraph/graph.py
+++ b/autodepgraph/graph.py
@@ -26,12 +26,12 @@
class AutoDepGraph_DAG(nx.DiGraph):
"""
-
+
Attributes:
node_states: Allowed states for the nodes
matplotlib_edge_properties: Properties passed to networkx plotting of edges
matplotlib_label_properties: Properties passed to networkx plotting of labels
-
+
"""
node_states : List[str] = ['good', 'needs calibration',
'bad', 'unknown', 'active']
@@ -52,9 +52,6 @@ def __init__(self, name, cfg_plot_mode='svg',
self.cfg_plot_mode = cfg_plot_mode
self.cfg_plot_mode_args = {'fig': None}
- _path_name = split(__file__)[:-1][0]
- self.cfg_svg_filename = join(_path_name, 'svg_viewer', 'adg_graph.svg')
-
super().__init__(incoming_graph_data, **attr)
# internal attributes
@@ -66,7 +63,15 @@ def __init__(self, name, cfg_plot_mode='svg',
self._exec_cnt = 0
self._calib_cnt = 0
self._check_cnt = 0
-
+
+
+ @property
+ def cfg_svg_filename(self):
+ """
+ Default location for storing svg based visualizations of the DAG.
+ """
+ _path_name = split(__file__)[:-1][0]
+ return join(_path_name, 'svg_viewer', 'adg_graph.svg')
def fresh_copy(self):
return AutoDepGraph_DAG(name=self.name,
@@ -96,9 +101,6 @@ def add_node(self, node_for_adding, **attr):
'autodepgraph.node_functions.calibration_functions' +
'.NotImplementedCalibration')
- attr.setdefault('calibrate_function_kwargs', {})
- 'calibrate_function_kwargs', {})
-
attr['check_function'] = attr.get(
'check_function',
'autodepgraph.node_functions.check_functions' +
@@ -283,10 +285,8 @@ def calibrate_node(self, node : str, verbose : bool =False):
self.set_node_state(node, 'active')
func = _get_function(self.nodes[node]['calibrate_function'])
- func_kwargs = self.nodes[node]['calibrate_function_kwargs']
-
try:
- result = func(**func_kwargs)
+ result = func()
except Exception as e:
self.set_node_state(node, 'bad')
logging.warning(e)
@@ -311,8 +311,6 @@ def set_all_node_states(self, state):
def update_monitor(self):
if self.cfg_plot_mode == 'matplotlib':
self.update_monitor_mpl()
- # elif self.cfg_plot_mode == 'pyqtgraph':
- # self.draw_pg()
elif self.cfg_plot_mode == 'svg':
self.draw_svg()
elif self.cfg_plot_mode is None or self.cfg_plot_mode == 'None':
@@ -337,8 +335,7 @@ def _generate_node_positions(self, node_positions : Optional[dict] = None):
nodes=self.nodes()
if node_positions is None:
- node_positions = {}
-
+ node_positions = {}
def position_generator(N=10, centre=[0,5]):
""" Generate circle of positions around centre """
idx=0
@@ -350,9 +347,8 @@ def position_generator(N=10, centre=[0,5]):
positions=position_generator(len(nodes))
pos=dict([ (node, node_positions.get(node, next(positions)) ) for node in nodes] )
- return pos
-
-
+ return pos
+
def draw_mpl(self, ax=None):
if ax is None:
f, ax = plt.subplots()
@@ -376,17 +372,6 @@ def _format_mpl_plot(ax):
ax.set_xticks([])
ax.set_yticks([])
- # def draw_pg(self, DiGraphWindow=None):
- # """
- # draws the graph using an interactive pyqtgraph window
- # """
- # if DiGraphWindow is None:
- # DiGraphWindow = self._DiGraphWindow
- # self._DiGraphWindow = vis.draw_graph_pyqt(
- # self, DiGraphWindow=DiGraphWindow,
- # window_title=self.name)
- # return self._DiGraphWindow
-
def draw_svg(self, filename: str=None):
"""
"""
@@ -446,7 +431,7 @@ def set_node_description(self, node, description):
def calibration_state(self):
""" Return dictionary with current calibration state """
- return dict(self.node)
+ return dict(self.nodes)
def _update_drawing_attrs(self):
for node_name, node_attrs in self.nodes(True):
diff --git a/examples/Example notebook.ipynb b/examples/Example notebook.ipynb
index ad1b221..cbebb4f 100644
--- a/examples/Example notebook.ipynb
+++ b/examples/Example notebook.ipynb
@@ -18,16 +18,7 @@
"cell_type": "code",
"execution_count": 1,
"metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/Users/Adriaan/anaconda/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n",
- " from ._conv import register_converters as _register_converters\n"
- ]
- }
- ],
+ "outputs": [],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
@@ -49,24 +40,47 @@
},
{
"cell_type": "code",
- "execution_count": 48,
+ "execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
- "test_graph.add_node?"
+ "cal_True_delayed= 'autodepgraph.node_functions.calibration_functions.test_calibration_True_delayed'\n",
+ "test_graph = AutoDepGraph_DAG('test graph')\n",
+ "for node in ['A', 'B', 'C', 'D', 'E']:\n",
+ " test_graph.add_node(node, \n",
+ " calibrate_function=cal_True_delayed)"
]
},
{
"cell_type": "code",
- "execution_count": 41,
+ "execution_count": 3,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "\u001b[0;31mSignature:\u001b[0m \u001b[0mtest_graph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnode_for_adding\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mDocstring:\u001b[0m\n",
+ "Adds a node to the graph, including starting attributes.\n",
+ "\n",
+ "attr:\n",
+ " name (type) = default_value\n",
+ "\n",
+ " calibrate_function = 'NotImplementedCalibration'\n",
+ " check_functions = 'return_fixed_value'\n",
+ " tolerance (float) = 0\n",
+ " timeout (float) = np.inf\n",
+ " state (str) = 'unknown'\n",
+ "\u001b[0;31mFile:\u001b[0m ~/GitHubRepos/Personal/AutoDepGraph/autodepgraph/graph.py\n",
+ "\u001b[0;31mType:\u001b[0m method\n"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
- "cal_True_delayed= 'autodepgraph.node_functions.calibration_functions.test_calibration_True_delayed'\n",
- "test_graph = AutoDepGraph_DAG('test graph')\n",
- "for node in ['A', 'B', 'C', 'D', 'E']:\n",
- " test_graph.add_node(node, \n",
- " calibrate_function=cal_True_delayed)"
+ "test_graph.add_node?"
]
},
{
@@ -78,7 +92,7 @@
},
{
"cell_type": "code",
- "execution_count": 42,
+ "execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
@@ -108,16 +122,16 @@
},
{
"cell_type": "code",
- "execution_count": 43,
+ "execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "'/Users/Adriaan/GitHubRepos/DiCarloLab_Repositories/AutoDepGraph/autodepgraph/svg_viewer/adg_graph.svg'"
+ "'/Users/adriaanrol/GitHubRepos/Personal/AutoDepGraph/autodepgraph/svg_viewer/adg_graph.svg'"
]
},
- "execution_count": 43,
+ "execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
@@ -129,13 +143,100 @@
"test_graph.update_monitor()\n",
"\n",
"# Updating the monitor overwrites an svg file whose location is determined by the attribute:\n",
- "test_graph.cfg_svg_filename\n",
- "# This attribute can safely be overwritten"
+ "test_graph.cfg_svg_filename"
]
},
{
"cell_type": "code",
- "execution_count": 44,
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": [
+ ""
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from IPython.display import display, SVG\n",
+ "display(SVG(test_graph.cfg_svg_filename))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
"metadata": {
"scrolled": true
},
@@ -144,7 +245,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "/Users/Adriaan/GitHubRepos/DiCarloLab_Repositories/AutoDepGraph/autodepgraph/svg_viewer/svgviewer-6t2tj5gh.html\n"
+ "/Users/adriaanrol/GitHubRepos/Personal/AutoDepGraph/autodepgraph/svg_viewer/svgviewer-etruszyd.html\n"
]
}
],
@@ -164,12 +265,12 @@
},
{
"cell_type": "code",
- "execution_count": 45,
+ "execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
- "image/png": "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\n",
+ "image/png": "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\n",
"text/plain": [
"