/
visualise_layout.py
129 lines (103 loc) · 5.22 KB
/
visualise_layout.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'''
This class takes a layout
'''
import layout as la
import operationcollection as opc
class VisualiseLayout:
def __init__(self):
print("visual debug")
def get_color(self, op_type):
if op_type == opc.OperationTypes.NOOP:
return "white"
elif op_type == opc.OperationTypes.USE_DISTILLATION:
return "magenta"
elif op_type == opc.OperationTypes.USE_QUBIT:
return "red"
elif op_type == opc.OperationTypes.USE_ANCILLA:
return "yellow"
elif op_type == opc.OperationTypes.USE_S_GATE:
return "green"
elif op_type == opc.OperationTypes.MOVE_PATCH:
return "orange"
elif op_type == opc.OperationTypes.HADAMARD_QUBIT:
return "cyan"
elif op_type == opc.OperationTypes.MX_QUBIT:
return "cyan"
elif op_type == opc.OperationTypes.MZ_QUBIT:
return "cyan"
def remove_if_in_distillery_core(self, layout, i, j, t):
# use this cube only if at least one neighbouring coordinate is not of the same type
# effectively removes core of large boxes... eases the viualisation
same_type_nghs = 0
for mi in range(-1, 2):
for mj in range(-1, 2):
for mt in range(-1, 2):
if (mi != 0) and (mj != 0) and (mt != 0):
ni = i + mi
nj = j + mj
nt = t + mt
valid_coord = ni in range(layout.get_isize())
valid_coord = valid_coord and (nj in range(layout.get_jsize()))
valid_coord = valid_coord and (nt in range(layout.get_tsize()))
if valid_coord and (layout.coordinates[ni][nj][nt] is not None):
n_op_id = layout.coordinates[ni][nj][nt].operations[0]
n_op_type = layout.operations_dictionary[n_op_id].op_type
if n_op_type == opc.OperationTypes.USE_DISTILLATION:
same_type_nghs += 1
# print(same_type_nghs)
return (same_type_nghs == 8)
def visualise_cube(self, layout, remove_noop):
json2 = {"nodes": [], "links": []}
# simple type checking
if not isinstance(layout, la.CubeLayout):
print("ERROR: This is not a layout!\n")
return
for i in range(layout.get_isize()):
for j in range(layout.get_jsize()):
for t in range(layout.get_tsize()):
ops_collection = layout.coordinates[i][j][t]
# take each operation from the collection and make a cube out of it
# filter
if ops_collection is None:
continue
for op_id in ops_collection.operations:
op_type = layout.operations_dictionary[op_id].op_type
if op_type == opc.OperationTypes.USE_DISTILLATION:
if self.remove_if_in_distillery_core(layout, i, j, t):
# this cell should not be considered
break
cell_id = layout.get_cell_id(i, j, t)
color = self.get_color(op_type)
decorator = "."
dec_set = [opc.OperationTypes.HADAMARD_QUBIT,
opc.OperationTypes.MX_QUBIT,
opc.OperationTypes.MZ_QUBIT]
if ops_collection.get_zero_length_ops(layout.operations_dictionary) in dec_set:
# force all decorators to behave the same
# hard coded ...
decorator = "H"
# # filter
# if ops_collection.has_single_noop(layout.operations_dictionary) and remove_noop:
# continue
sides = ops_collection.sides_integer_value
# sides = 60
# # when default this means that the volume is not used
# # ancillas do not rotate their X or Z?
# if op_type in [opc.OperationTypes.NOOP, opc.OperationTypes.USE_ANCILLA]:
# sides = 63
node_value = {"id": cell_id,
"fy": i, "fx": j, "fz": t,
"c": color,
"op": str(op_type) + "_" + str(op_id),
"s": sides,
"d": decorator}
json2["nodes"].append(node_value)
# for each operation in the collection of 3D cells
# determine which operations touch which
for op_id in layout.operations_dictionary:
operation = layout.operations_dictionary[op_id]
# for touch_id in operation["touches"]:
for touch_id in operation.touches:
touch_link = {"source": touch_id, "target": operation.touches[touch_id], "c": "blue"}
json2["links"].append(touch_link)
return json2