• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

feihoo87 / waveforms / 6862429923

14 Nov 2023 10:37AM UTC coverage: 42.467% (-0.3%) from 42.813%
6862429923

push

github

feihoo87
add auto save state for dht

0 of 4 new or added lines in 1 file covered. (0.0%)

223 existing lines in 3 files now uncovered.

7289 of 17164 relevant lines covered (42.47%)

2.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/waveforms/visualization/plot_layout.py
1
import functools
×
2
import operator
×
3

4
import matplotlib.pyplot as plt
×
5
import numpy as np
×
UNCOV
6
from matplotlib import cm
×
7
from matplotlib.colors import Normalize
×
8

UNCOV
9
layout_example = {
×
10
    'qubits': {
11
        'Q0': {
12
            'pos': (0, 1)
13
        },
14
        'Q1': {
15
            'pos': (1, 0)
16
        },
17
        'Q2': {
18
            'pos': (0, -1)
19
        },
20
        'Q3': {
21
            'pos': (-1, 0)
22
        }
23
    },
24
    'couplers': {
25
        'C0': {
26
            'qubits': ['Q0', 'Q1'],
27
        },
28
        'C1': {
29
            'qubits': ['Q1', 'Q2'],
30
        },
31
        'C2': {
32
            'qubits': ['Q2', 'Q3'],
33
        },
34
        'C3': {
35
            'qubits': ['Q0', 'Q3'],
36
        }
37
    }
38
}
39

40

41
def complete_layout(layout):
×
42
    for c in layout['couplers']:
×
43
        qubits = layout['couplers'][c]['qubits']
×
44
        for q in qubits:
×
45
            if q not in layout['qubits']:
×
46
                raise ValueError('qubit {} not found'.format(q))
×
47
            if 'couplers' not in layout['qubits'][q]:
×
48
                layout['qubits'][q]['couplers'] = []
×
49
            if c not in layout['qubits'][q]['couplers']:
×
UNCOV
50
                layout['qubits'][q]['couplers'].append(c)
×
UNCOV
51
    return layout
×
52

53

54
def get_shared_coupler(layout, q1, q2):
×
55
    for c in layout['qubits'][q1]['couplers']:
×
56
        if q2 in layout['couplers'][c]['qubits']:
×
UNCOV
57
            return c
×
UNCOV
58
    return None
×
59

60

UNCOV
61
def get_neighbours(layout,
×
62
                   qubit_or_coupler,
63
                   distance=1,
64
                   type='qubit',
65
                   inrange=False):
66

67
    def _qubits(couplers):
×
68
        ret = set()
×
69
        for c in couplers:
×
UNCOV
70
            ret = ret | set(layout['couplers'][c]['qubits'])
×
71
        return ret
×
72

73
    def _couplers(qubits):
×
74
        ret = set()
×
75
        for q in qubits:
×
UNCOV
76
            ret = ret | set(layout['qubits'][q]['couplers'])
×
77
        return ret
×
78

UNCOV
79
    couplers = []
×
80
    neighbors = []
×
81

82
    if qubit_or_coupler in layout['qubits']:
×
83
        couplers.append(set(layout['qubits'][qubit_or_coupler]['couplers']))
×
84
        neighbors.append(_qubits(couplers[0]) - {qubit_or_coupler})
×
85
    elif qubit_or_coupler in layout['couplers']:
×
86
        if type == 'coupler':
×
87
            distance += 1
×
UNCOV
88
        neighbors.append(set(layout['couplers'][qubit_or_coupler]['qubits']))
×
89
        couplers.append({qubit_or_coupler})
×
90
    else:
UNCOV
91
        raise ValueError(f'qubit or coupler {qubit_or_coupler!r} not found')
×
92
    distance -= 1
×
93

94
    while distance > 0:
×
95
        couplers.append(_couplers(neighbors[-1]) - couplers[-1])
×
UNCOV
96
        neighbors.append(_qubits(couplers[-1]) - neighbors[-1])
×
97
        distance -= 1
×
98

99
    if type == 'qubit':
×
UNCOV
100
        if inrange:
×
101
            return list(functools.reduce(operator.or_, neighbors, set()))
×
102
        else:
103
            return list(neighbors[-1])
×
104
    elif type == 'coupler':
×
105
        if inrange:
×
106
            if qubit_or_coupler in couplers[0]:
×
UNCOV
107
                couplers = couplers[1:]
×
108
            return list(functools.reduce(operator.or_, couplers, set()))
×
109
        else:
110
            return list(couplers[-1])
×
111
    else:
UNCOV
112
        raise ValueError("type must be 'qubit' or 'coupler'")
×
113

114

UNCOV
115
def plot_range(ax,
×
116
               path,
117
               text='',
118
               color=None,
119
               text_color='k',
120
               bounder_color='k',
121
               lw=0.5,
122
               fontsize=9):
UNCOV
123
    x, y = path
×
124
    center = x.mean(), y.mean()
×
125

UNCOV
126
    if color:
×
127
        ax.fill(x, y, color=color, lw=0)
×
128

UNCOV
129
    if lw is not None and lw > 0:
×
UNCOV
130
        ax.plot(np.hstack([x, [x[0]]]),
×
131
                np.hstack([y, [y[0]]]),
132
                color=bounder_color,
133
                lw=lw)
134

UNCOV
135
    if text:
×
UNCOV
136
        ax.text(center[0],
×
137
                center[1],
138
                text,
139
                ha='center',
140
                va='center',
141
                color=text_color,
142
                fontsize=fontsize)
143

144

145
def circle_path(pos, r, n=40):
×
146
    x, y = pos
×
147
    t = 2 * np.pi * np.linspace(0, 1, n, endpoint=False)
×
148
    xx = r * np.cos(t) + x
×
UNCOV
149
    yy = r * np.sin(t) + y
×
UNCOV
150
    return xx, yy
×
151

152

UNCOV
153
def circle_link_path(pos1, pos2, r1, r2, width, n=20):
×
154
    width = min(2 * max(r1, r2), width)
×
155

UNCOV
156
    x1, y1 = pos1
×
157
    x2, y2 = pos2
×
158

159
    phi = np.arctan2(y2 - y1, x2 - x1)
×
160

UNCOV
161
    theta1 = np.arcsin(width / 2 / r1)
×
162
    theta2 = np.arcsin(width / 2 / r2)
×
163

164
    t = np.linspace(-theta1, theta1, n) + phi
×
UNCOV
165
    xx1 = r1 * np.cos(t) + x1
×
166
    yy1 = r1 * np.sin(t) + y1
×
167

168
    t = np.linspace(-theta2, theta2, n) + phi + np.pi
×
UNCOV
169
    xx2 = r2 * np.cos(t) + x2
×
170
    yy2 = r2 * np.sin(t) + y2
×
171

UNCOV
172
    return np.hstack([xx2[-1], xx1,
×
173
                      xx2[:-1]]), np.hstack([yy2[-1], yy1, yy2[:-1]])
174

175

UNCOV
176
def circle_half_directed_link_path(pos1, pos2, r1, r2, width, n=20):
×
177
    width = min(max(r1, r2), width)
×
178

UNCOV
179
    x1, y1 = pos1
×
180
    x2, y2 = pos2
×
181

182
    phi = np.arctan2(y2 - y1, x2 - x1)
×
183

UNCOV
184
    theta1 = np.arcsin(width / r1)
×
185
    theta2 = np.arcsin(width / r2)
×
186

187
    t = np.linspace(0.2 * theta1, theta1, n) + phi
×
UNCOV
188
    xx1 = r1 * np.cos(t) + x1
×
189
    yy1 = r1 * np.sin(t) + y1
×
190

191
    t = np.linspace(-theta2, -0.2 * theta2, n) + phi + np.pi
×
UNCOV
192
    xx2 = r2 * np.cos(t) + x2
×
193
    yy2 = r2 * np.sin(t) + y2
×
194

UNCOV
195
    v = (xx2[0] - xx1[-1]) + 1j * (yy2[0] - yy1[-1])
×
196
    c = (xx2[0] + xx1[-1]) / 2 + 1j * (yy2[0] + yy1[-1]) / 2
×
197

UNCOV
198
    a = np.array([1 / 6, 1 / 12]) + 1j * np.array([0, 0.4 * width / np.abs(v)])
×
199
    a = a * v + c
×
200

UNCOV
201
    return np.hstack([xx2[-1], xx1, a.real,
×
202
                      xx2[:-1]]), np.hstack([yy2[-1], yy1, a.imag, yy2[:-1]])
203

204

205
def draw(layout, ax=None, qubit_cbar=True, coupler_cbar=True):
×
UNCOV
206
    if ax is None:
×
207
        ax = plt.gca()
×
208

209
    for qubit in layout['qubits'].values():
×
210
        pos = qubit['pos']
×
UNCOV
211
        path = circle_path(pos, qubit.get('radius', 0.5))
×
UNCOV
212
        plot_range(ax,
×
213
                   path,
214
                   qubit.get('text', ''),
215
                   qubit.get('color', None),
216
                   lw=qubit.get('lw', 0.5),
217
                   fontsize=qubit.get('fontsize', 9),
218
                   text_color=qubit.get('text_color', 'k'),
219
                   bounder_color=qubit.get('bounder_color', 'k'))
220

221
    for coupler in layout['couplers'].values():
×
222
        q1, q2 = coupler['qubits']
×
223
        pos1 = layout['qubits'][q1]['pos']
×
224
        pos2 = layout['qubits'][q2]['pos']
×
225
        r1 = layout['qubits'][q1].get('radius', 0.5)
×
226
        r2 = layout['qubits'][q2].get('radius', 0.5)
×
UNCOV
227
        width = coupler.get('width', 0.5)
×
228
        lw = coupler.get('lw', 0.5)
×
229

UNCOV
230
        path = circle_link_path(pos1, pos2, r1, r2, width)
×
UNCOV
231
        plot_range(ax,
×
232
                   path,
233
                   coupler.get('text', ''),
234
                   color=coupler.get('color', None),
235
                   lw=0,
236
                   fontsize=coupler.get('fontsize', 9),
237
                   text_color=coupler.get('text_color', 'k'))
238
        if lw > 0:
×
UNCOV
239
            x, y = circle_link_path(pos1, pos2, r1, r2, width, n=2)
×
UNCOV
240
            ax.plot(x[:2],
×
241
                    y[:2],
242
                    lw=lw,
243
                    color=coupler.get('bounder_color', 'k'))
UNCOV
244
            ax.plot(x[2:],
×
245
                    y[2:],
246
                    lw=lw,
247
                    color=coupler.get('bounder_color', 'k'))
248

UNCOV
249
    ax.axis('equal')
×
UNCOV
250
    ax.set_axis_off()
×
251

UNCOV
252
    if qubit_cbar and layout['__colorbar__']['qubit']['norm'] is not None:
×
UNCOV
253
        cbar = plt.colorbar(cm.ScalarMappable(
×
254
            norm=layout['__colorbar__']['qubit']['norm'],
255
            cmap=layout['__colorbar__']['qubit']['cmap']),
256
                            ax=ax,
257
                            location='bottom',
258
                            orientation='horizontal',
259
                            pad=0.01,
260
                            shrink=0.5)
UNCOV
261
        cbar.set_label(layout['__colorbar__']['qubit']['label'])
×
UNCOV
262
    if coupler_cbar and layout['__colorbar__']['coupler']['norm'] is not None:
×
UNCOV
263
        cbar = plt.colorbar(cm.ScalarMappable(
×
264
            norm=layout['__colorbar__']['coupler']['norm'],
265
            cmap=layout['__colorbar__']['coupler']['cmap']),
266
                            ax=ax,
267
                            location='bottom',
268
                            orientation='horizontal',
269
                            pad=0.01,
270
                            shrink=0.5)
271
        cbar.set_label(layout['__colorbar__']['coupler']['label'])
×
272

273

274
def get_norm(params, elms, vmin=None, vmax=None):
×
275
    data = []
×
276
    for elm in elms:
×
277
        if elm in params:
×
278
            if isinstance(params[elm], (int, float)):
×
279
                data.append(params[elm])
×
280
            elif 'value' in params[elm] and params[elm]['value'] is not None:
×
UNCOV
281
                data.append(params[elm]['value'])
×
282
    if data:
×
UNCOV
283
        if vmin is None:
×
UNCOV
284
            vmin = min(data)
×
285
        if vmax is None:
×
286
            vmax = max(data)
×
287
        return Normalize(vmin=vmin, vmax=vmax)
×
288
    else:
UNCOV
289
        return None
×
290

291

292
def fill_layout(layout,
×
293
                params,
294
                qubit_size=0.5,
295
                coupler_size=0.5,
296
                qubit_fontsize=9,
297
                coupler_fontsize=9,
298
                qubit_color=None,
299
                coupler_color=None,
300
                qubit_cmap='hot',
301
                qubit_vmax=None,
302
                qubit_vmin=None,
303
                coupler_cmap='binary',
304
                coupler_vmax=None,
305
                coupler_vmin=None,
306
                bounder_color='k',
307
                lw=0.5):
308

309
    qubit_cmap = plt.get_cmap(qubit_cmap)
×
310
    coupler_cmap = plt.get_cmap(coupler_cmap)
×
311

312
    qubit_norm = get_norm(params,
×
313
                          layout['qubits'].keys(),
314
                          vmin=qubit_vmin,
315
                          vmax=qubit_vmax)
UNCOV
316
    coupler_norm = get_norm(params,
×
317
                            layout['couplers'].keys(),
318
                            vmin=coupler_vmin,
319
                            vmax=coupler_vmax)
320
    layout['__colorbar__'] = {
×
321
        'coupler': {
322
            'cmap': coupler_cmap,
323
            'norm': coupler_norm,
324
            'label': ''
325
        },
326
        'qubit': {
327
            'cmap': qubit_cmap,
328
            'norm': qubit_norm,
329
            'label': ''
330
        }
331
    }
332

UNCOV
333
    for qubit in layout['qubits']:
×
334
        layout['qubits'][qubit]['radius'] = qubit_size
×
335
        layout['qubits'][qubit]['fontsize'] = qubit_fontsize
×
UNCOV
336
        if qubit in params:
×
337
            layout['qubits'][qubit]['lw'] = 0
×
UNCOV
338
            if not isinstance(params[qubit], dict):
×
UNCOV
339
                params[qubit] = {'value': params[qubit]}
×
UNCOV
340
            if 'color' in params[qubit]:
×
UNCOV
341
                layout['qubits'][qubit]['color'] = params[qubit]['color']
×
UNCOV
342
            elif 'value' in params[qubit] and params[qubit][
×
343
                    'value'] is not None:
UNCOV
344
                layout['qubits'][qubit]['color'] = qubit_cmap(
×
345
                    qubit_norm(params[qubit]['value']))
346
            else:
UNCOV
347
                layout['qubits'][qubit]['color'] = qubit_color
×
UNCOV
348
                if qubit_color is None:
×
UNCOV
349
                    layout['qubits'][qubit]['lw'] = lw
×
UNCOV
350
            layout['qubits'][qubit]['radius'] = params[qubit].get(
×
351
                'radius', qubit_size)
UNCOV
352
            layout['qubits'][qubit]['fontsize'] = params[qubit].get(
×
353
                'fontsize', qubit_fontsize)
UNCOV
354
            layout['qubits'][qubit]['text'] = params[qubit].get('text', '')
×
UNCOV
355
            layout['qubits'][qubit]['text_color'] = params[qubit].get(
×
356
                'text_color', 'k')
357
        else:
UNCOV
358
            layout['qubits'][qubit]['color'] = qubit_color
×
UNCOV
359
            if qubit_color is None:
×
UNCOV
360
                layout['qubits'][qubit]['lw'] = lw
×
361
            else:
UNCOV
362
                layout['qubits'][qubit]['lw'] = 0
×
UNCOV
363
            layout['qubits'][qubit]['bounder_color'] = bounder_color
×
364

UNCOV
365
    for coupler in layout['couplers']:
×
UNCOV
366
        layout['couplers'][coupler]['width'] = coupler_size
×
UNCOV
367
        layout['couplers'][coupler]['fontsize'] = coupler_fontsize
×
UNCOV
368
        layout['couplers'][coupler]['bounder_color'] = bounder_color
×
UNCOV
369
        if coupler in params:
×
UNCOV
370
            layout['couplers'][coupler]['lw'] = 0
×
UNCOV
371
            if not isinstance(params[coupler], dict):
×
UNCOV
372
                params[coupler] = {'value': params[coupler]}
×
UNCOV
373
            if 'color' in params[coupler]:
×
UNCOV
374
                layout['couplers'][coupler]['color'] = params[coupler]['color']
×
UNCOV
375
            elif 'value' in params[coupler] and params[coupler][
×
376
                    'value'] is not None:
UNCOV
377
                layout['couplers'][coupler]['color'] = coupler_cmap(
×
378
                    coupler_norm(params[coupler]['value']))
379
            else:
UNCOV
380
                layout['couplers'][coupler]['color'] = coupler_color
×
UNCOV
381
                if coupler_color is None:
×
UNCOV
382
                    layout['couplers'][qubit]['lw'] = lw
×
UNCOV
383
            layout['couplers'][coupler]['width'] = params[coupler].get(
×
384
                'width', coupler_size)
UNCOV
385
            layout['couplers'][coupler]['fontsize'] = params[coupler].get(
×
386
                'fontsize', coupler_fontsize)
UNCOV
387
            layout['couplers'][coupler]['text'] = params[coupler].get(
×
388
                'text', '')
UNCOV
389
            layout['couplers'][coupler]['text_color'] = params[coupler].get(
×
390
                'text_color', 'k')
391
        else:
UNCOV
392
            layout['couplers'][coupler]['color'] = coupler_color
×
UNCOV
393
            if coupler_color is None:
×
UNCOV
394
                layout['couplers'][coupler]['lw'] = lw
×
395
            else:
UNCOV
396
                layout['couplers'][coupler]['lw'] = 0
×
UNCOV
397
            layout['couplers'][coupler]['bounder_color'] = bounder_color
×
398

UNCOV
399
    return layout
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc