Browse Source

Removed all visualization related stuff

Visualization server is now in a separate project and runnng on
peteshadbolt.co.uk. Still need to update examples, tests and docs.
master
Pete Shadbolt 4 years ago
parent
commit
7a84c0fd08
26 changed files with 1 additions and 2521 deletions
  1. +0
    -1
      MANIFEST.in
  2. +0
    -0
      Makefile
  3. +0
    -0
      abp/static/__init__.py
  4. BIN
      abp/static/img/ball.png
  5. +0
    -91
      abp/static/img/ball.svg
  6. +0
    -3
      abp/static/img/make_figs.sh
  7. BIN
      abp/static/img/tip.png
  8. +0
    -91
      abp/static/img/tip.svg
  9. +0
    -47
      abp/static/index.html
  10. +0
    -105
      abp/static/main.css
  11. +0
    -1
      abp/static/scripts/.gitignore
  12. +0
    -73
      abp/static/scripts/anders_briegel.js
  13. +0
    -190
      abp/static/scripts/editor.js
  14. +0
    -76
      abp/static/scripts/graph.js
  15. +0
    -80
      abp/static/scripts/gui.js
  16. +0
    -58
      abp/static/scripts/interaction.js
  17. +0
    -10
      abp/static/scripts/main.js
  18. +0
    -38
      abp/static/scripts/materials.js
  19. +0
    -0
      abp/static/scripts/message.js
  20. +0
    -73
      abp/static/scripts/mouse.js
  21. +0
    -412
      abp/static/scripts/orbitcontrols.js
  22. +0
    -990
      abp/static/scripts/three.js
  23. +0
    -36
      abp/static/scripts/websocket.js
  24. +0
    -35
      abp/vizclient.py
  25. +0
    -105
      bin/abpserver
  26. +1
    -6
      setup.py

+ 0
- 1
MANIFEST.in View File

@@ -1 +0,0 @@
recursive-include abp/static *

makefile → Makefile View File


+ 0
- 0
abp/static/__init__.py View File


BIN
abp/static/img/ball.png View File

Before After
Width: 64  |  Height: 64  |  Size: 2.8KB

+ 0
- 91
abp/static/img/ball.svg View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="New document 1">
<defs
id="defs4">
<linearGradient
id="linearGradient3763">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3765" />
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="1"
id="stop3767" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3763"
id="radialGradient3771"
cx="38.780914"
cy="23.33404"
fx="38.780914"
fy="23.33404"
r="32.661938"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1215552,0.13870084,-0.14202472,1.1484324,1.1779947,-9.189628)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="-12.465613"
inkscape:cy="8.3918647"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-page="false"
inkscape:window-width="1366"
inkscape:window-height="721"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-988.36218)">
<path
sodipodi:type="arc"
style="fill:url(#radialGradient3771);fill-opacity:1;stroke:#000000;stroke-width:1.32387710000000003;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path2993"
sodipodi:cx="32"
sodipodi:cy="32"
sodipodi:rx="32"
sodipodi:ry="32"
d="M 64,32 A 32,32 0 1 1 0,32 32,32 0 1 1 64,32 z"
transform="matrix(0.94419643,0,0,0.94419643,1.7857143,990.14789)" />
</g>
</svg>

+ 0
- 3
abp/static/img/make_figs.sh View File

@@ -1,3 +0,0 @@
#!/bin/bash
inkscape -z -e ball.png -w 64 -h 64 ball.svg
inkscape -z -e tip.png -w 64 -h 64 tip.svg

BIN
abp/static/img/tip.png View File

Before After
Width: 64  |  Height: 64  |  Size: 1.0KB

+ 0
- 91
abp/static/img/tip.svg View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="tip.svg">
<defs
id="defs4">
<linearGradient
id="linearGradient3763">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3765" />
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="1"
id="stop3767" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="5.4453989"
inkscape:cy="4.9448826"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-page="true"
inkscape:window-width="1366"
inkscape:window-height="721"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:snap-center="true"
inkscape:object-nodes="true" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-988.36218)">
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.32387710000000003;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;opacity:0.29302326"
id="path2993"
sodipodi:cx="32"
sodipodi:cy="32"
sodipodi:rx="32"
sodipodi:ry="32"
d="M 64,32 A 32,32 0 1 1 0,32 32,32 0 1 1 64,32 z"
transform="matrix(0.94419643,0,0,0.94419643,1.7857143,990.14789)" />
<path
style="color:#000000;fill:none;stroke:#000000;stroke-width:9.65;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 32,996.21932 0,48.28568"
id="path3811"
inkscape:connector-curvature="0" />
<path
style="color:#000000;fill:none;stroke:#000000;stroke-width:9.65;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 7.8571427,1020.3622 48.2857143,0"
id="path3813"
inkscape:connector-curvature="0" />
</g>
</svg>

+ 0
- 47
abp/static/index.html View File

@@ -1,47 +0,0 @@
<!DOCTYPE html>

<html lang="en">
<head>
<title>abp</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=1" />
<link rel="stylesheet" href="main.css">
<script src="scripts/three.js"></script>
<script src="scripts/orbitcontrols.js"></script>
<script src="scripts/anders_briegel.js"></script>
<script src="scripts/mouse.js"></script>
<script src="scripts/materials.js"></script>
<script src="scripts/graph.js"></script>
<script src="scripts/gui.js"></script>
<script src="scripts/editor.js"></script>
<script src="scripts/websocket.js"></script>
<script src="scripts/main.js"></script>
</head>

<body>
<img id=ball src="img/ball.png" style=display:none;>
<img id=tip src="img/tip.png" style=display:none;>
<div id=node_info class=hidden> nothing </div>
<div id=server_info class=hidden> </div>

<div id=version>Version 0.4.27</div>

<div id=node_data class=hidden>
<div id=node_name></div>
<ul>
<li id=node_vop></li>
<li>Measure in
<a href="#" onclick="editor.measureX()">X</a> /
<a href="#" onclick="editor.measureY()">Y</a> /
<a href="#" onclick="editor.measureZ()">Z</a></li>
<li>Act
<a href="#" onclick="editor.hadamard()">Hadamard</a> /
<a href="#" onclick="editor.phase()">Phase</a></li>
<li><a href="#" onclick="editor.localComplementation()">Invert neighbourhood</a></li>
<li><a href="#" onclick="editor.deleteNode()">Delete</a></li>
</ul>
</div>


</body>
</html>

+ 0
- 105
abp/static/main.css View File

@@ -1,105 +0,0 @@
html, body { margin: 0; padding: 0; overflow: hidden; font-size: 10pt; font-family: monospace; }
#node_info {
background: rgba(0, 0, 0, .8);
color:white;
padding: 5px;
margin:0px;
position: absolute;
top:5px;
left:5px;
font-family: monospace;
text-align: center;
font-size:9pt;
/*height:15px;*/
border-radius:3px;
pointer-events: none;
}

#server_info {
background-color: black;
color:white;
padding: 10px;
font-family: monospace;
position: absolute;
top: 10px;
right: 10px;
font-size: 9pt;
}

#node_name {
font-size: 12pt;
}

#node_data {
background-color: black;
color:white;
padding: 10px;
font-family: monospace;
position: absolute;
top: 10px;
left: 10px;
font-size: 9pt;
}

#options {
background-color: rgba(256, 256, 256, .5);
color: black;
padding: 10px;
font-family: monospace;
position: absolute;
text-align: right;
bottom: 10px;
right: 10px;
font-size: 9pt;
}


#version {
color:black;
padding: 10px;
font-family: monospace;
position: absolute;
bottom: 10px;
left: 10px;
font-size: 9pt;
}



ul {
list-style-type: none;
padding: 0px;
margin: 0px;
}

li{
padding:3px;
padding-left: 0em;
}



.visible {
visibility: visible;
opacity: 1;
transform: scale(1);
transition: opacity .08s linear, transform .08s linear;
}

.hidden {
visibility: hidden;
opacity: 0;
transform: scale(.5);
transition: visibility .08s, opacity .08s linear, transform .08s linear;
}

a {
color: yellow;
}

h3 {
padding-top: 0px;
padding-bottom: 0px;
margin-top: 2px;
margin-bottom: 2px;
}

+ 0
- 1
abp/static/scripts/.gitignore View File

@@ -1 +0,0 @@
qcengine

+ 0
- 73
abp/static/scripts/anders_briegel.js View File

@@ -1,73 +0,0 @@
var abj = {};
abj.node = {};
abj.adj = {};

abj.add_node = function(node, meta) {
if (meta === undefined){meta = {};}
abj.adj[node] = {};
abj.node[node] = {};
abj.node[node].vop = tables.clifford.hadamard;
Object.assign(abj.node[node], meta);
};

abj.add_nodes = function(nodes) {
nodes.forEach(add_node);
};

abj.del_node = function(node) {
for (var i in abj.adj[node]) {
abj.del_edge(node, i);
}
delete abj.node[node];
};

abj.add_edge = function(a, b) {
abj.adj[a][b] = {};
abj.adj[b][a] = {};
};

abj.add_edges = function(edges) {
edges.forEach(function(e) {
add_edge(e[0], e[1]);
});
};

abj.del_edge = function(a, b) {
delete abj.adj[a][b];
delete abj.adj[b][a];
};

abj.has_edge = function(a, b) {
return Object.prototype.hasOwnProperty.call(abj.adj[a], b);
};

abj.is_sole_member = function(group, node) {
// TODO: this is slow as heck
var keys = Object.keys(group);
return keys.length == 1 && keys[0] == node;
};

abj.update = function(newState) {
abj.node = newState.node;
abj.adj = newState.adj;
};

abj.order = function(){
return Object.keys(abj.node).length;
};

abj.edgelist = function() {
var seen = {};
var output = [];
for (var i in abj.adj) {
for (var j in abj.adj[i]) {
if (!Object.prototype.hasOwnProperty.call(seen, j)) {
output.push([i, j]);
}
}
seen[i] = true;
}
return output;
};



+ 0
- 190
abp/static/scripts/editor.js View File

@@ -1,190 +0,0 @@
var editor = {};
var pi2 = Math.PI / 2;

editor.selection = undefined;
editor.mouseOver = undefined;

editor.orientations = [
new THREE.Euler(pi2, 0, 0),
new THREE.Euler(0, 0, 0),
new THREE.Euler(pi2, 0, pi2),
];


editor.onFreeMove = function() {
var found = editor.findNodeOnRay(mouse.ray);
if (editor.mouseOver !== found) {
editor.mouseOver = found;
if (found) {
var n = abj.node[found];
var s = "Node " + found + "<br/> ";
for (var i in n) {
if (i!="position"){
s += i + ":" + n[i] + " ";
}
}
s += "";
gui.nodeMessage(s);
} else {
gui.hideNodeMessage();
}
}
};

editor.focus = function(node) {
gui.hideNodeMessage();
editor.selection = node;

//gui.serverMessage("Selected node " + node + ".");
};

editor.addQubitAtPoint = function(point) {
if (point === null) {
return;
}
point.round();
var new_node = Math.floor(point.x) + "," + Math.floor(point.y) + "," + Math.floor(point.z);
if (Object.prototype.hasOwnProperty.call(abj.node, new_node)) {
gui.serverMessage("Node " + new_node +" already exists.");
return;
}
websocket.edit({action:"create", name:new_node, position: point});
editor.focus(new_node);
gui.serverMessage("Created node " + new_node +".");
};

editor.onClick = function() {
var found = editor.findNodeOnRay(mouse.ray);
if (found) {
editor.focus(found);
var node=found;
//editor.grid.position.copy(abj.node[node].position);
gui.controls.target.copy(abj.node[node].position);
node_name.innerHTML = "Node " + node;
node_data.className = "visible";
node_vop.innerHTML = "VOP: " + abj.node[node].vop;
} else {
var intersection = mouse.ray.intersectPlane(editor.plane);
if (intersection !== null) {
editor.addQubitAtPoint(intersection);
}
}
};

editor.onShiftClick = function() {
var found = editor.findNodeOnRay(mouse.ray);
if (found === undefined){ return; }
if (editor.selection === undefined){ return; }
if (found === editor.selection){ return; }
//abj.act_cz(found, editor.selection);
websocket.edit({action:"cz", start:found, end:editor.selection});
gui.serverMessage("Acted CZ between " + found + " & " + editor.selection + ".");
editor.focus(found);
};

editor.onCtrlClick = function() {
var found = editor.findNodeOnRay(mouse.ray);
if (found === undefined){ return; }
if (editor.selection === undefined){ return; }
editor.focus(found);
websocket.edit({action:"hadamard", node:found});
gui.serverMessage("Acted H on node " + found + ".");
};


editor.prepare = function() {
mouse.onFreeMove = editor.onFreeMove;
mouse.onClick = editor.onClick;
mouse.onShiftClick = editor.onShiftClick;
mouse.onCtrlClick = editor.onCtrlClick;
document.addEventListener("keydown", editor.onKey, false);
//editor.makeGrid();
};

editor.onKey = function(evt) {
if (evt.keyCode === 32) {
editor.setOrientation((editor.orientation + 1) % 3);
}
if (evt.keyCode === 46 || evt.keyCode === 68) {
editor.deleteNode();
}
};

editor.setOrientation = function(orientation) {
editor.orientation = orientation;
var rotation = editor.orientations[orientation];
var normal = new THREE.Vector3(0, 1, 0);
normal.applyEuler(rotation);
editor.grid.rotation.copy(rotation);
editor.plane = new THREE.Plane();
editor.plane.setFromNormalAndCoplanarPoint(normal, editor.grid.position);
gui.render();
};

editor.makeGrid = function() {
editor.grid = new THREE.GridHelper(10, 1);
editor.grid.setColors(0xbbbbbb, 0xeeeeee);
editor.grid.renderOrder = 1000;
editor.setOrientation(0);
gui.scene.add(editor.grid);
gui.scene.children[0].renderOrder = -3000;
};

editor.update = function() {};

// Gets a reference to the node nearest to the mouse cursor
editor.findNodeOnRay = function(ray) {
for (var n in abj.node) {
if (ray.distanceSqToPoint(abj.node[n].position) < 0.012) {
return n;
}
}
return undefined;
};

editor.deleteNode = function() {
if (editor.selection === undefined){ return; }
websocket.edit({action:"delete", node:editor.selection});
gui.serverMessage("Deleted node " + editor.selection + ".");
editor.selection = undefined;
node_data.className = "hidden";
};

//TODO: loadsa space for DRY here

editor.hadamard = function() {
if (editor.selection === undefined){ return; }
websocket.edit({action:"hadamard", node:editor.selection});
gui.serverMessage("Acted Hadamard on node " + editor.selection + ".");
};

editor.phase = function() {
if (editor.selection === undefined){ return; }
websocket.edit({action:"phase", node:editor.selection});
gui.serverMessage("Acted phase on node " + editor.selection + ".");
};

editor.measureX = function() {
if (editor.selection === undefined){ return; }
websocket.edit({action:"measure", node:editor.selection, basis:"x"});
gui.serverMessage("Measured node " + editor.selection + " in X.");
};

editor.measureY = function() {
if (editor.selection === undefined){ return; }
websocket.edit({action:"measure", node:editor.selection, basis:"y"});
gui.serverMessage("Measured node " + editor.selection + " in Y.");
};

editor.measureZ = function() {
if (editor.selection === undefined){ return; }
websocket.edit({action:"measure", node:editor.selection, basis:"z"});
gui.serverMessage("Measured node " + editor.selection + " in z.");
};

editor.localComplementation = function() {
if (editor.selection === undefined){ return; }
websocket.edit({action:"localcomplementation", node:editor.selection});
abj.local_complementation(editor.selection);
gui.serverMessage("Inverted neighbourhood of " + editor.selection + ".");
};

+ 0
- 76
abp/static/scripts/graph.js View File

@@ -1,76 +0,0 @@
var graph = {};
graph.colors = ["red", "green"];

graph.prepare = function() {
materials.prepare();
websocket.connect(graph.update);
};

graph.center = function() {
var middle = new THREE.Vector3(0, 0, 0);
for (var i in abj.node) {
middle = middle.add(abj.node[i].position);
}
middle = middle.multiplyScalar(1.0/abj.order());
return middle;
};

graph.update = function(newState) {
if (newState){abj.update(newState);}

var gs = gui.scene.getObjectByName("graphstate");
if (gs){ gui.scene.remove(gs); }

var geometry = new THREE.Geometry();
geometry.colors = [];
for (var i in abj.node) {
var color = graph.colors[abj.node[i].vop % graph.colors.length];
if (abj.node[i].color !== undefined){
color = abj.node[i].color;
}
geometry.vertices.push(abj.node[i].position);
geometry.colors.push(new THREE.Color(color));
}

graph.center();
gui.controls.target.copy(graph.center());

var edges = new THREE.Object3D();
var my_edges = abj.edgelist();
for (i = 0; i < my_edges.length; ++i) {
var edge = my_edges[i];
var start = abj.node[edge[0]].position;
var startpos = new THREE.Vector3(start.x, start.y, start.z);
var end = abj.node[edge[1]].position;
var endpos = new THREE.Vector3(end.x, end.y, end.z);
var newEdge = materials.makeCurve(startpos, endpos);
edges.add(newEdge);
}

if (editor.selection) {
console.log(editor.selection);
var node = editor.selection;
if (Object.prototype.hasOwnProperty.call(abj.node, node)) {
editor.grid.position.copy(abj.node[node].position);
gui.controls.target.copy(abj.node[node].position);
node_name.innerHTML = "Node " + node;
node_data.className = "visible";
node_vop.innerHTML = "VOP: " + abj.node[node].vop;
} else {
editor.selection = undefined;
node_data.className = "hidden";
}
} else {
node_data.className = "hidden";
}

var particles = new THREE.Points(geometry, materials.qubit);
var object = new THREE.Object3D();
object.name = "graphstate";
object.add(particles);
object.add(edges);
gui.scene.add(object);
gui.render();

};


+ 0
- 80
abp/static/scripts/gui.js View File

@@ -1,80 +0,0 @@
var gui = {};
gui.prepare = function() {
gui.renderer = new THREE.WebGLRenderer({
"antialias": true
});
gui.renderer.setSize(window.innerWidth, window.innerHeight);
gui.renderer.setClearColor(0xffffff, 1);
document.querySelector("body").appendChild(gui.renderer.domElement);
window.addEventListener("resize", gui.onWindowResize, false);

gui.makeScene();

gui.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.3, 1000);
gui.controls = new THREE.OrbitControls(gui.camera);
gui.controls.addEventListener("change", gui.render);
gui.controls.center.set(0, 0, 0);
gui.controls.target.set(0, 0, 0);
gui.controls.rotateSpeed = 0.2;
gui.controls.userPanSpeed = 0.1;
gui.camera.position.set(0, 0, 10);
gui.controls.autoRotate = true;
gui.controls.autoRotateSpeed = 0.1;
};

// Someone resized the window
gui.onWindowResize = function(evt) {
gui.camera.aspect = window.innerWidth / window.innerHeight;
gui.camera.updateProjectionMatrix();
gui.renderer.setSize(window.innerWidth, window.innerHeight);
gui.render();
};

// Render the current frame to the screen
gui.render = function() {
requestAnimationFrame(function() {
gui.renderer.render(gui.scene, gui.camera);
});
};

// Make the extra bits of gui
gui.makeScene = function() {
gui.scene = new THREE.Scene();
};

// Put an HTML message to the screen
// TODO: write a generic messaging class?
gui.serverMessage = function(msgtext, persist) {
if (persist === undefined) {persist = false;}
server_info.innerHTML = msgtext;
server_info.className = "visible";
clearInterval(gui.ki);
if (!persist){
gui.ki = setInterval(function(){server_info.className="hidden";}, 3000);
}
};

gui.nodeMessage = function(msgtext) {
node_info.innerHTML = msgtext;
node_info.className = "visible";
};

gui.hideNodeMessage = function(){
node_info.className = "hidden";
};

// Set the position of the info popup
gui.setInfoPosition = function(position){
w = node_info.offsetWidth;
h = node_info.offsetHeight;
node_info.style.left = position.x - w/2 + "px";
node_info.style.top = position.y - h -10 + "px";
};

// The main loop
gui.loop = function() {
gui.controls.update();
editor.update();
requestAnimationFrame(gui.loop);
};


+ 0
- 58
abp/static/scripts/interaction.js View File

@@ -1,58 +0,0 @@
var mouse = {};
var interaction = {};

interaction.raycaster = new THREE.Raycaster();
interaction.xyplane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);

// Gets a reference to the node nearest to the mouse cursor
interaction.nearestNode = function() {
this.raycaster.setFromCamera(mouse, camera);
for (var i = 0; i < nodeGeometry.vertices.length; ++i) {
var v = nodeGeometry.vertices[i];
if (this.raycaster.ray.distanceSqToPoint(v) < 0.01) {
return i;
}
}
return undefined;
};


// Find out: what is the mouse pointing at?
interaction.checkIntersections = function() {
var new_selection = nearestNode();
if (new_selection != this.selection) {
this.selection = new_selection;
info.className = this.selection ? "visible" : "hidden";
info.innerHTML = this.selection ? nodeGeometry.labels[new_selection] : info.innerHTML;
render();
}
};

// Update the mouse position tracker
interaction.onMouseMove = function(event) {
mouse.wasClick = false;
mouse.absx = event.clientX;
mouse.absy = event.clientY;
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
//w = 200; //h = 15; //info.style.top = mouse.absy - h - 40 + "px"; //info.style.left = mouse.absx - w / 2 + "px"; //checkIntersections();
};

// Try to add a qubit at the current mouse position
interaction.addQubitAtMouse = function(event) {
this.raycaster.setFromCamera(mouse, camera);
var intersection = this.raycaster.ray.intersectPlane(this.plane);
intersection.x = Math.round(intersection.x);
intersection.y = Math.round(intersection.y);
abj.add_node(Object.keys(vops).length, {
"position": intersection
});
updateScene();
}

interaction.bind = function() {
var el = renderer.domElement;
el.addEventListener("mousedown", this.onMouseDown);
el.addEventListener("mouseup", this.onMouseDown);
el.addEventListener("mousemove", this.onMouseMove);
};

+ 0
- 10
abp/static/scripts/main.js View File

@@ -1,10 +0,0 @@
console.log("abp v0.4.27");

window.onload = function() {
graph.prepare();
materials.prepare();
gui.prepare();
mouse.prepare();
editor.prepare();
gui.loop();
};

+ 0
- 38
abp/static/scripts/materials.js View File

@@ -1,38 +0,0 @@
var materials = {};

var curveProperties = {
splineDensity: 10,
curvature: 20
};

// Is called on boot
materials.prepare = function() {
var ballSprite = new THREE.Texture(document.getElementById("ball"));
ballSprite.needsUpdate = true;
materials.edge = new THREE.LineBasicMaterial({
color: "gray",
transparent: false,
linewidth: 5
});
materials.edge.depthTest = false;
materials.qubit = new THREE.PointsMaterial({
size: 0.6,
map: ballSprite,
alphaTest: 0.5,
transparent: true,
vertexColors: THREE.VertexColors
});
};


materials.makeCurve = function(a, b) {
var length = new THREE.Vector3().subVectors(a, b).length();
var bend = new THREE.Vector3(length / curveProperties.curvature, length / curveProperties.curvature, 0);
var mid = new THREE.Vector3().add(a).add(b).multiplyScalar(0.5).add(bend);
var spline = new THREE.CatmullRomCurve3([a, mid, b]);
var geometry = new THREE.Geometry();
var splinePoints = spline.getPoints(curveProperties.splineDensity);
Array.prototype.push.apply(geometry.vertices, splinePoints);
return new THREE.Line(geometry, materials.edge);
};


+ 0
- 0
abp/static/scripts/message.js View File


+ 0
- 73
abp/static/scripts/mouse.js View File

@@ -1,73 +0,0 @@
var mouse = {};
mouse.wasClick = true;
mouse.pressed = false;
mouse.leniency = 4;

mouse.raycaster = new THREE.Raycaster();

mouse.onFreeMove = function() {
console.log("Free move");
};
mouse.onDrag = function() {
//console.log("Drag");
};
mouse.onClick = function() {
console.log("Click");
};
mouse.onCtrlClick = function() {
console.log("Ctrl-click");
};
mouse.onShiftClick = function() {
console.log("Shift-click");
};

mouse.prepare = function() {
var el = gui.renderer.domElement;
el.addEventListener("mousedown", mouse.onDown);
el.addEventListener("mouseup", mouse.onUp);
el.addEventListener("mousemove", mouse.onMove);
};

mouse.onDown = function(event) {
mouse.wasClick = true;
mouse.pressed = true;
mouse.startX = event.clientX;
mouse.startY = event.clientY;
};

mouse.onUp = function(event) {
mouse.pressed = false;
if (!mouse.wasClick) {
return;
}
if (event.ctrlKey) {
mouse.onCtrlClick();
} else if (event.shiftKey) {
mouse.onShiftClick();
} else {
mouse.onClick();
}
};

mouse.onMove = function(event) {
// TODO: wasclick sux
if (Math.abs(event.clientX - mouse.startX)>mouse.leniency || Math.abs(event.clientY - mouse.startY)>mouse.leniency){
mouse.wasClick = false;
}
mouse.position_absolute = {
x: event.clientX,
y: event.clientY
};
mouse.position_relative = {
x: (event.clientX / window.innerWidth) * 2 - 1,
y: -(event.clientY / window.innerHeight) * 2 + 1
};
gui.setInfoPosition(mouse.position_absolute);
mouse.raycaster.setFromCamera(mouse.position_relative, gui.camera);
mouse.ray = mouse.raycaster.ray;
if (mouse.pressed) {
mouse.onDrag();
} else {
mouse.onFreeMove();
}
};

+ 0
- 412
abp/static/scripts/orbitcontrols.js View File

@@ -1,412 +0,0 @@
// three.js - http://github.com/mrdoob/three.js


/**
* @author qiao / https://github.com/qiao
* @author mrdoob / http://mrdoob.com
* @author alteredq / http://alteredqualia.com/
* @author WestLangley / http://github.com/WestLangley
*/

THREE.OrbitControls = function ( object, domElement ) {

this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document;

// API

this.enabled = true;

this.center = new THREE.Vector3();
this.target = new THREE.Vector3();

this.userZoom = true;
this.userZoomSpeed = 1.0;

this.userRotate = true;
this.userRotateSpeed = 1.0;

this.userPan = true;
this.userPanSpeed = 0.1;

this.autoRotate = false;
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60

this.minPolarAngle = 0; // radians
this.maxPolarAngle = Math.PI; // radians

this.minDistance = 0;
this.maxDistance = Infinity;

// 65 /*A*/, 83 /*S*/, 68 /*D*/
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40, ROTATE: 65, ZOOM: 83, PAN: 68 };

// internals

var scope = this;

var EPS = 0.000001;
var PIXELS_PER_ROUND = 1800;

var rotateStart = new THREE.Vector2();
var rotateEnd = new THREE.Vector2();
var rotateDelta = new THREE.Vector2();

var zoomStart = new THREE.Vector2();
var zoomEnd = new THREE.Vector2();
var zoomDelta = new THREE.Vector2();

var phiDelta = 0;
var thetaDelta = 0;
var scale = 1;

var lastPosition = new THREE.Vector3();

var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2 };
var state = STATE.NONE;

// events

var changeEvent = { type: 'change' };


this.rotateLeft = function ( angle ) {

if ( angle === undefined ) {

angle = getAutoRotationAngle();

}

thetaDelta -= angle;

};

this.rotateRight = function ( angle ) {

if ( angle === undefined ) {

angle = getAutoRotationAngle();

}

thetaDelta += angle;

};

this.rotateUp = function ( angle ) {

if ( angle === undefined ) {

angle = getAutoRotationAngle();

}

phiDelta -= angle;

};

this.rotateDown = function ( angle ) {

if ( angle === undefined ) {

angle = getAutoRotationAngle();

}

phiDelta += angle;

};

this.zoomIn = function ( zoomScale ) {

if ( zoomScale === undefined ) {

zoomScale = getZoomScale();

}

scale /= zoomScale;

};

this.zoomOut = function ( zoomScale ) {

if ( zoomScale === undefined ) {

zoomScale = getZoomScale();

}

scale *= zoomScale;

};

this.pan = function ( distance ) {

distance.transformDirection( this.object.matrix );
distance.multiplyScalar( scope.userPanSpeed );

this.object.position.add( distance );
this.center.add( distance );
this.target.add( distance );

};

this.update = function () {

var position = this.object.position;
var offset = position.clone().sub( this.center );

var diff = this.center.clone().sub( this.target ).multiplyScalar(0.2);
this.center.sub(diff);

// angle from z-axis around y-axis

var theta = Math.atan2( offset.x, offset.z );

// angle from y-axis

var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );

if ( this.autoRotate ) {

this.rotateLeft( getAutoRotationAngle() );

}

theta += thetaDelta;
phi += phiDelta;

// restrict phi to be between desired limits
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );

// restrict phi to be betwee EPS and PI-EPS
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );

var radius = offset.length() * scale;

// restrict radius to be between desired limits
radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );

offset.x = radius * Math.sin( phi ) * Math.sin( theta );
offset.y = radius * Math.cos( phi );
offset.z = radius * Math.sin( phi ) * Math.cos( theta );

position.copy( this.center ).add( offset );

this.object.lookAt( this.center );

thetaDelta /= 1.5;
phiDelta /= 1.5;
scale = 1;

if ( lastPosition.distanceTo( this.object.position ) > 0.01 ) {

this.dispatchEvent( changeEvent );

lastPosition.copy( this.object.position );

}

};


function getAutoRotationAngle() {

return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;

}

function getZoomScale() {

return Math.pow( 0.95, scope.userZoomSpeed );

}

function onMouseDown( event ) {

if ( scope.enabled === false ) return;
if ( scope.userRotate === false ) return;


event.preventDefault();

if ( state === STATE.NONE )
{
if ( event.button === 0 )
state = STATE.ROTATE;
if ( event.button === 1 )
state = STATE.ZOOM;
if ( event.button === 2 )
state = STATE.PAN;
}
if ( state === STATE.ROTATE ) {

//state = STATE.ROTATE;

rotateStart.set( event.clientX, event.clientY );

} else if ( state === STATE.ZOOM ) {

//state = STATE.ZOOM;

zoomStart.set( event.clientX, event.clientY );

} else if ( state === STATE.PAN ) {

//state = STATE.PAN;

}

document.addEventListener( 'mousemove', onMouseMove, false );
document.addEventListener( 'mouseup', onMouseUp, false );

}

function onMouseMove( event ) {

if ( scope.enabled === false ) return;

event.preventDefault();

if ( state === STATE.ROTATE ) {

rotateEnd.set( event.clientX, event.clientY );
rotateDelta.subVectors( rotateEnd, rotateStart );

scope.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed );
scope.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed );

rotateStart.copy( rotateEnd );

} else if ( state === STATE.ZOOM ) {

zoomEnd.set( event.clientX, event.clientY );
zoomDelta.subVectors( zoomEnd, zoomStart );

if ( zoomDelta.y > 0 ) {

scope.zoomIn();

} else {

scope.zoomOut();

}

zoomStart.copy( zoomEnd );

} else if ( state === STATE.PAN ) {

var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;

scope.pan( new THREE.Vector3( - movementX, movementY, 0 ) );

}

}

function onMouseUp( event ) {

if ( scope.enabled === false ) return;
if ( scope.userRotate === false ) return;

document.removeEventListener( 'mousemove', onMouseMove, false );
document.removeEventListener( 'mouseup', onMouseUp, false );

state = STATE.NONE;

}

function onMouseWheel( event ) {

if ( scope.enabled === false ) return;
if ( scope.userZoom === false ) return;

var delta = 0;

if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9

delta = event.wheelDelta;

} else if ( event.detail ) { // Firefox

delta = - event.detail;

}

if ( delta > 0 ) {

scope.zoomOut();

} else {

scope.zoomIn();

}

}

function onKeyDown( event ) {

if ( scope.enabled === false ) return;
if ( scope.userPan === false ) return;

switch ( event.keyCode ) {

/*case scope.keys.UP:
scope.pan( new THREE.Vector3( 0, 1, 0 ) );
break;
case scope.keys.BOTTOM:
scope.pan( new THREE.Vector3( 0, - 1, 0 ) );
break;
case scope.keys.LEFT:
scope.pan( new THREE.Vector3( - 1, 0, 0 ) );
break;
case scope.keys.RIGHT:
scope.pan( new THREE.Vector3( 1, 0, 0 ) );
break;
*/
case scope.keys.ROTATE:
state = STATE.ROTATE;
break;
case scope.keys.ZOOM:
state = STATE.ZOOM;
break;
case scope.keys.PAN:
state = STATE.PAN;
break;
}

}
function onKeyUp( event ) {

switch ( event.keyCode ) {

case scope.keys.ROTATE:
case scope.keys.ZOOM:
case scope.keys.PAN:
state = STATE.NONE;
break;
}

}

this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
window.addEventListener( 'keydown', onKeyDown, false );
window.addEventListener( 'keyup', onKeyUp, false );

};

THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );

+ 0
- 990
abp/static/scripts/three.js
File diff suppressed because it is too large
View File


+ 0
- 36
abp/static/scripts/websocket.js View File

@@ -1,36 +0,0 @@
var websocket = {};
websocket.update = undefined;

websocket.connect = function(update) {
websocket.ws = new WebSocket("ws://localhost:5000");
if (update){
websocket.update = update;
}
websocket.ws.onopen = function(evt) {
gui.serverMessage("Connected to server.");
};

websocket.ws.onerror = function(err) {
gui.serverMessage("Could not connect to server.");
};

websocket.ws.onmessage = function(evt) {
json = JSON.parse(evt.data);
for (var i in json.node) {
var pos = json.node[i].position;
json.node[i].position = new THREE.Vector3(pos.x, pos.y, pos.z);
if (json.node[i].vop === undefined){
json.node[i].vop = 0;
}
}
websocket.update(json);
};

websocket.ws.onclose = function(evt) {
gui.serverMessage("No connection to server. <a href='#' onclick='javascript:websocket.connect()'>Reconnect</a>.", true);
};
};

websocket.edit = function (data) {
websocket.ws.send("edit:"+JSON.stringify(data));
};

+ 0
- 35
abp/vizclient.py View File

@@ -1,35 +0,0 @@
import time, atexit, json
import networkx as nx
import numpy as np
import websocket
from socket import error as socket_error
from . import clifford
from . import util
from . import nxgraphstate

class VizClient(object):
def __init__(self, uri = "ws://localhost:5000"):
self.ws = websocket.create_connection(uri, timeout=0.1)
atexit.register(self.shutdown)

def shutdown(self):
""" Close the connection to the websocket """
self.ws.close()

def update(self, graph, delay = 0.5):
""" Call this function when you are ready to send data to the browser """
g = nxgraphstate.NXGraphState(graph)

# Automatically perform layout if position is not provided
if not all(("position" in node) for node in list(g.node.values())):
g.layout()

# Send data to browser and rate-limit
try:
self.ws.send(json.dumps(g.to_json(stringify=True)))
self.ws.recv()
except websocket._exceptions.WebSocketTimeoutException:
print("Timed out ... you might be pushing a bit hard")
time.sleep(delay)



+ 0
- 105
bin/abpserver View File

@@ -1,105 +0,0 @@
#!/usr/bin/python
"""
This is a simple websocket relay server that facilitates realtime visualization of GraphStates.
It doesn't do much except echo websocket messages to all connected clients, and serve some static content over HTTP.
"""

from websocket_server import WebsocketServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
from BaseHTTPServer import HTTPServer
from SocketServer import ThreadingMixIn
import os, sys, threading
import webbrowser
import argparse
import abp
import json
from pkg_resources import resource_filename
from pprint import pprint
import time

abp.DETERMINISTIC = True
clients = []
local_state = abp.GraphState()

def process_edit(edit, client, server):
action = edit["action"]

print action.upper()
for key, value in edit.items():
if key!="action":
print " {}: {}".format(key, value)
print

if action == "create":
local_state.add_qubit(edit["name"], position=edit["position"], vop=0)
elif action == "cz":
local_state.act_cz(edit["start"], edit["end"])
elif action == "hadamard":
local_state.act_hadamard(edit["node"])
elif action == "phase":
local_state.act_local_rotation(edit["node"], "phase")
elif action == "delete":
local_state._del_node(edit["node"])
elif action == "localcomplementation":
local_state.local_complementation(edit["node"])
elif action == "measure":
local_state.measure(edit["node"], "p"+edit["basis"])
else:
pass

#server.send_message(client, json.dumps(local_state.to_json()))
server.send_message_to_all(json.dumps(local_state.to_json()))

def new_message(client, server, message):
if message.startswith("edit:"):
edit = json.loads(message[5:])
process_edit(edit, client, server)
else:
print "Received update from python {}.".format(client["id"])
# print message
local_state.from_json(json.loads(message))
# print local_state
server.send_message_to_all(message)

def new_client(client, server):
print "Client {} connected.".format(client["id"])
clients.append(client)
print "Sent state of {} nodes to client {}".format(local_state.order(), client["id"])
server.send_message(client, json.dumps(local_state.to_json()))

def client_left(client, server):
print "Client {} disconnected.".format(client["id"])
clients.remove(client)

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
""" Handle requests in a separate thread """

if __name__ == '__main__':
parser = argparse.ArgumentParser(description = "ABP websocket server")
parser.add_argument("-v", action="store_true", help="Launch browser")
args = parser.parse_args()

# Change to the right working dir
where = os.path.abspath(resource_filename("abp.static", ""))
print "abpserver 0.4.27"
print where
print "Open http://localhost:5001 in a browser!"
os.chdir(where)

# Start the HTTP server
httpserver = ThreadedHTTPServer(('', 5001), SimpleHTTPRequestHandler)
thread = threading.Thread(target = httpserver.serve_forever)
thread.daemon = True
thread.start()

if args.v:
webbrowser.open("http://localhost:5001/")

# Start the websocket server
server = WebsocketServer(5000)
server.set_fn_new_client(new_client)
server.set_fn_message_received(new_message)
server.set_fn_client_left(client_left)
server.run_forever()
httpserver.shutdown()


+ 1
- 6
setup.py View File

@@ -2,12 +2,10 @@ from setuptools import setup
from glob import glob
from os import path

STATIC = glob("abp/static/*.*")+glob("abp/static/img/*.*")+glob("abp/static/scripts/*.*")

setup(
name = "abp",
version = "0.4.27",
packages = ["abp", "abp.static"],
packages = ["abp"],
test_suite = "tests",
author = "Pete Shadbolt",
author_email = "hello@peteshadbolt.co.uk",
@@ -15,8 +13,5 @@ setup(
description = "Port of C++ due to Simon Anders and Hans J Briegel",
keywords = "quantum",
setup_requires = ["numpy"],
scripts = ["bin/abpserver"],
install_requires = ["numpy", "networkx", "websocket-client", "websocket-server"],
package_data = {"abp.static": STATIC},
include_package_data=True
)

Loading…
Cancel
Save