qiskit_metal.qlibrary.QNLMetal.bridgefreejunction
BridgeFreeJunction.
`+y`
________|_____
/ | | ∖
| ___|_|_* |
| | |____|
| `+x_+y`|____|- `+x`
| | | |
| | | |
| ‾‾‾‾‾‾‾‾ |
∖ /
‾‾‾‾‾‾‾‾‾‾‾‾‾‾
1# This code was written by Deval Deliwala. 2# 3# This code is to be used by QNL. 4# 5# Any modifications or derivative works of this code must retain this 6# notice, and modified files need to carry a notice indicating 7# that they have been altered from the originals. 8 9""" BridgeFreeJunction. 10 11.. code-block:: 12 13 `+y` 14 ________|_____ 15 / | | ∖ 16 | ___|_|_* | 17 | | |____| 18 | `+x_+y`|____|- `+x` 19 | | | | 20 | | | | 21 | ‾‾‾‾‾‾‾‾ | 22 ∖ / 23 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 24 25""" 26 27import numpy as np 28from qiskit_metal import draw, Dict 29from qiskit_metal.qlibrary.core import QComponent 30from qiskit_metal.toolbox_python.utility_functions import rotate_point 31 32 33class BridgeFreeJunction(QComponent): 34 """ 35 Inherits `QComponent` Class. 36 37 Description: 38 A bridge-free junction design similar to the manhattan style junctions. 39 40 Options: 41 * width : The width of the junction overlap rectangle 42 * height : The height of the junction overlap rectangle 43 * wire_width : The width of the junction wires 44 * wire_x_offset: The offset in x direction w.r.t origin -- sign doesn't matter 45 * wire_y_offset: The offset in y direction w.r.t origin -- sign doesn't matter 46 * pos_x/_y : position of junction on chip 47 * fillet : The fillet radius of the corners of the junction overlap rectangle 48 * undercut : The size of the undercut region around the junction overlap rectangle 49 * orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise 50 * origin: A string representing the corner of the rectangle the wires will be placed next to 51 Valid Options: 52 * 'upper right' DEFAULT 53 * 'upper left' 54 * 'lower right' 55 * 'lower left' 56 * layer: the layer number for the junction 57 * undercut_layer: the layer number for the undercut 58 59 60 """ 61 62 # Default drawing options 63 default_options = Dict( 64 width='100um', 65 height='100um', 66 wire_width='5um', 67 wire_x_offset='5um', 68 wire_y_offset='5um', 69 pos_x='0um', 70 pos_y='0um', 71 fillet='0um', 72 undercut='25um', 73 orientation='0', 74 origin='upper right', 75 layer='1', 76 undercut_layer='2', 77 ) 78 79 # Component metadata 80 # Name prefix for component, if user doesn't provide name 81 component_metadata = Dict( 82 short_name='bridgefreejunction', 83 _qgeometry_table_poly='True', 84 ) 85 86 def make(self): 87 """ Convert self.options into QGeometry. """ 88 p = self.parse_options() # string options -> numbers 89 nodes = Dict() 90 91 # junction overlap rectangle 92 junc_rect = draw.rectangle(p.width, p.height) 93 94 # surrounding undercut 95 undercut = draw.rectangle(p.width+2*p.undercut, p.height+2*p.undercut) 96 undercut = undercut.buffer(p.fillet) 97 98 if p.origin == 'upper right': 99 nodes.origin = np.array((+p.width/2, +p.height/2)) 100 p.wire_x_offset = -abs(p.wire_x_offset) 101 p.wire_y_offset = -abs(p.wire_y_offset) 102 x_translation = nodes.origin + [p.wire_x_offset, p.undercut/2+p.fillet/2] 103 y_translation = nodes.origin + [p.undercut/2+p.fillet/2, p.wire_y_offset] 104 elif p.origin == 'upper left': 105 nodes.origin = np.array((-p.width/2, +p.height/2)) 106 p.wire_x_offset = +abs(p.wire_x_offset) 107 p.wire_y_offset = -abs(p.wire_y_offset) 108 x_translation = nodes.origin + [p.wire_x_offset, p.undercut/2+p.fillet/2] 109 y_translation = nodes.origin + [-p.undercut/2-p.fillet/2, p.wire_y_offset] 110 elif p.origin == 'lower right': 111 nodes.origin = np.array((+p.width/2, -p.height/2)) 112 p.wire_x_offset = -abs(p.wire_x_offset) 113 p.wire_y_offset = +abs(p.wire_y_offset) 114 x_translation = nodes.origin + [p.wire_x_offset, -p.undercut/2-p.fillet/2] 115 y_translation = nodes.origin + [p.undercut/2+p.fillet/2, p.wire_y_offset] 116 elif p.origin == 'lower left': 117 nodes.origin = np.array((-p.width/2, -p.height/2)) 118 p.wire_x_offset = +abs(p.wire_x_offset) 119 p.wire_y_offset = +abs(p.wire_y_offset) 120 x_translation = nodes.origin + [p.wire_x_offset, -p.undercut/2-p.fillet/2] 121 y_translation = nodes.origin + [-p.undercut/2-p.fillet/2, p.wire_y_offset] 122 else: 123 raise Exception('`origin` option not defined correctly') 124 125 # Wires 126 # `wire_x` is the wire that gets offset translated along x-direction 127 # `wire_y` is the wire that gets offset translated along y-direction 128 wire_x = draw.rectangle(p.wire_width, p.undercut+p.fillet) 129 wire_y = draw.rectangle(p.undercut+p.fillet, p.wire_width) 130 131 wire_x = draw.translate(wire_x, *x_translation) 132 wire_y = draw.translate(wire_y, *y_translation) 133 134 junction = draw.union([junc_rect, wire_x, wire_y]) 135 undercut = draw.subtract(undercut, junction) 136 137 # Translations & Rotations 138 geom_list = [junction, undercut] 139 geom_list = draw.rotate(geom_list, p.orientation, origin=(0, 0)) 140 geom_list = draw.translate(geom_list, p.pos_x, p.pos_y) 141 [junction, undercut] = geom_list 142 143 # Converting drawing to qgeometry 144 self.add_qgeometry('poly', {'junction': junction}, layer=p.layer) 145 self.add_qgeometry('poly', {'undercut': undercut}, layer=p.undercut_layer) 146 147 # Positioning nodes 148 nodes['+x_+y'] = nodes.origin + [p.wire_x_offset, p.wire_y_offset] 149 if p.origin == 'upper right': 150 nodes['+x'] = nodes.origin + [p.undercut, p.wire_y_offset] 151 nodes['+y'] = nodes.origin + [p.wire_x_offset, p.undercut] 152 if p.origin == 'upper left': 153 nodes['+x'] = nodes.origin + [-p.undercut, p.wire_y_offset] 154 nodes['+y'] = nodes.origin + [p.wire_x_offset, p.undercut] 155 if p.origin == 'lower right': 156 nodes['+x'] = nodes.origin + [p.undercut, p.wire_y_offset] 157 nodes['+y'] = nodes.origin + [p.wire_x_offset, -p.undercut] 158 if p.origin == 'lower left': 159 nodes['+x'] = nodes.origin + [-p.undercut, p.wire_y_offset] 160 nodes['+y'] = nodes.origin + [p.wire_x_offset, -p.undercut] 161 162 # Moving nodes along with component 163 translation_vec = np.array((p.pos_x, p.pos_y)) 164 theta = np.deg2rad(p.orientation) 165 for key, point in nodes.items(): 166 rotated = rotate_point(point, theta) 167 nodes[key] = rotated + translation_vec 168 169 self.nodes = nodes 170 return 171 172 def node(self, key): 173 return self.nodes.get(key, None)
34class BridgeFreeJunction(QComponent): 35 """ 36 Inherits `QComponent` Class. 37 38 Description: 39 A bridge-free junction design similar to the manhattan style junctions. 40 41 Options: 42 * width : The width of the junction overlap rectangle 43 * height : The height of the junction overlap rectangle 44 * wire_width : The width of the junction wires 45 * wire_x_offset: The offset in x direction w.r.t origin -- sign doesn't matter 46 * wire_y_offset: The offset in y direction w.r.t origin -- sign doesn't matter 47 * pos_x/_y : position of junction on chip 48 * fillet : The fillet radius of the corners of the junction overlap rectangle 49 * undercut : The size of the undercut region around the junction overlap rectangle 50 * orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise 51 * origin: A string representing the corner of the rectangle the wires will be placed next to 52 Valid Options: 53 * 'upper right' DEFAULT 54 * 'upper left' 55 * 'lower right' 56 * 'lower left' 57 * layer: the layer number for the junction 58 * undercut_layer: the layer number for the undercut 59 60 61 """ 62 63 # Default drawing options 64 default_options = Dict( 65 width='100um', 66 height='100um', 67 wire_width='5um', 68 wire_x_offset='5um', 69 wire_y_offset='5um', 70 pos_x='0um', 71 pos_y='0um', 72 fillet='0um', 73 undercut='25um', 74 orientation='0', 75 origin='upper right', 76 layer='1', 77 undercut_layer='2', 78 ) 79 80 # Component metadata 81 # Name prefix for component, if user doesn't provide name 82 component_metadata = Dict( 83 short_name='bridgefreejunction', 84 _qgeometry_table_poly='True', 85 ) 86 87 def make(self): 88 """ Convert self.options into QGeometry. """ 89 p = self.parse_options() # string options -> numbers 90 nodes = Dict() 91 92 # junction overlap rectangle 93 junc_rect = draw.rectangle(p.width, p.height) 94 95 # surrounding undercut 96 undercut = draw.rectangle(p.width+2*p.undercut, p.height+2*p.undercut) 97 undercut = undercut.buffer(p.fillet) 98 99 if p.origin == 'upper right': 100 nodes.origin = np.array((+p.width/2, +p.height/2)) 101 p.wire_x_offset = -abs(p.wire_x_offset) 102 p.wire_y_offset = -abs(p.wire_y_offset) 103 x_translation = nodes.origin + [p.wire_x_offset, p.undercut/2+p.fillet/2] 104 y_translation = nodes.origin + [p.undercut/2+p.fillet/2, p.wire_y_offset] 105 elif p.origin == 'upper left': 106 nodes.origin = np.array((-p.width/2, +p.height/2)) 107 p.wire_x_offset = +abs(p.wire_x_offset) 108 p.wire_y_offset = -abs(p.wire_y_offset) 109 x_translation = nodes.origin + [p.wire_x_offset, p.undercut/2+p.fillet/2] 110 y_translation = nodes.origin + [-p.undercut/2-p.fillet/2, p.wire_y_offset] 111 elif p.origin == 'lower right': 112 nodes.origin = np.array((+p.width/2, -p.height/2)) 113 p.wire_x_offset = -abs(p.wire_x_offset) 114 p.wire_y_offset = +abs(p.wire_y_offset) 115 x_translation = nodes.origin + [p.wire_x_offset, -p.undercut/2-p.fillet/2] 116 y_translation = nodes.origin + [p.undercut/2+p.fillet/2, p.wire_y_offset] 117 elif p.origin == 'lower left': 118 nodes.origin = np.array((-p.width/2, -p.height/2)) 119 p.wire_x_offset = +abs(p.wire_x_offset) 120 p.wire_y_offset = +abs(p.wire_y_offset) 121 x_translation = nodes.origin + [p.wire_x_offset, -p.undercut/2-p.fillet/2] 122 y_translation = nodes.origin + [-p.undercut/2-p.fillet/2, p.wire_y_offset] 123 else: 124 raise Exception('`origin` option not defined correctly') 125 126 # Wires 127 # `wire_x` is the wire that gets offset translated along x-direction 128 # `wire_y` is the wire that gets offset translated along y-direction 129 wire_x = draw.rectangle(p.wire_width, p.undercut+p.fillet) 130 wire_y = draw.rectangle(p.undercut+p.fillet, p.wire_width) 131 132 wire_x = draw.translate(wire_x, *x_translation) 133 wire_y = draw.translate(wire_y, *y_translation) 134 135 junction = draw.union([junc_rect, wire_x, wire_y]) 136 undercut = draw.subtract(undercut, junction) 137 138 # Translations & Rotations 139 geom_list = [junction, undercut] 140 geom_list = draw.rotate(geom_list, p.orientation, origin=(0, 0)) 141 geom_list = draw.translate(geom_list, p.pos_x, p.pos_y) 142 [junction, undercut] = geom_list 143 144 # Converting drawing to qgeometry 145 self.add_qgeometry('poly', {'junction': junction}, layer=p.layer) 146 self.add_qgeometry('poly', {'undercut': undercut}, layer=p.undercut_layer) 147 148 # Positioning nodes 149 nodes['+x_+y'] = nodes.origin + [p.wire_x_offset, p.wire_y_offset] 150 if p.origin == 'upper right': 151 nodes['+x'] = nodes.origin + [p.undercut, p.wire_y_offset] 152 nodes['+y'] = nodes.origin + [p.wire_x_offset, p.undercut] 153 if p.origin == 'upper left': 154 nodes['+x'] = nodes.origin + [-p.undercut, p.wire_y_offset] 155 nodes['+y'] = nodes.origin + [p.wire_x_offset, p.undercut] 156 if p.origin == 'lower right': 157 nodes['+x'] = nodes.origin + [p.undercut, p.wire_y_offset] 158 nodes['+y'] = nodes.origin + [p.wire_x_offset, -p.undercut] 159 if p.origin == 'lower left': 160 nodes['+x'] = nodes.origin + [-p.undercut, p.wire_y_offset] 161 nodes['+y'] = nodes.origin + [p.wire_x_offset, -p.undercut] 162 163 # Moving nodes along with component 164 translation_vec = np.array((p.pos_x, p.pos_y)) 165 theta = np.deg2rad(p.orientation) 166 for key, point in nodes.items(): 167 rotated = rotate_point(point, theta) 168 nodes[key] = rotated + translation_vec 169 170 self.nodes = nodes 171 return 172 173 def node(self, key): 174 return self.nodes.get(key, None)
Inherits QComponent
Class.
Description: A bridge-free junction design similar to the manhattan style junctions.
Options: * width : The width of the junction overlap rectangle * height : The height of the junction overlap rectangle * wire_width : The width of the junction wires * wire_x_offset: The offset in x direction w.r.t origin -- sign doesn't matter * wire_y_offset: The offset in y direction w.r.t origin -- sign doesn't matter * pos_x/_y : position of junction on chip * fillet : The fillet radius of the corners of the junction overlap rectangle * undercut : The size of the undercut region around the junction overlap rectangle * orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise * origin: A string representing the corner of the rectangle the wires will be placed next to Valid Options: * 'upper right' DEFAULT * 'upper left' * 'lower right' * 'lower left' * layer: the layer number for the junction * undercut_layer: the layer number for the undercut
Default drawing options
Component metadata
87 def make(self): 88 """ Convert self.options into QGeometry. """ 89 p = self.parse_options() # string options -> numbers 90 nodes = Dict() 91 92 # junction overlap rectangle 93 junc_rect = draw.rectangle(p.width, p.height) 94 95 # surrounding undercut 96 undercut = draw.rectangle(p.width+2*p.undercut, p.height+2*p.undercut) 97 undercut = undercut.buffer(p.fillet) 98 99 if p.origin == 'upper right': 100 nodes.origin = np.array((+p.width/2, +p.height/2)) 101 p.wire_x_offset = -abs(p.wire_x_offset) 102 p.wire_y_offset = -abs(p.wire_y_offset) 103 x_translation = nodes.origin + [p.wire_x_offset, p.undercut/2+p.fillet/2] 104 y_translation = nodes.origin + [p.undercut/2+p.fillet/2, p.wire_y_offset] 105 elif p.origin == 'upper left': 106 nodes.origin = np.array((-p.width/2, +p.height/2)) 107 p.wire_x_offset = +abs(p.wire_x_offset) 108 p.wire_y_offset = -abs(p.wire_y_offset) 109 x_translation = nodes.origin + [p.wire_x_offset, p.undercut/2+p.fillet/2] 110 y_translation = nodes.origin + [-p.undercut/2-p.fillet/2, p.wire_y_offset] 111 elif p.origin == 'lower right': 112 nodes.origin = np.array((+p.width/2, -p.height/2)) 113 p.wire_x_offset = -abs(p.wire_x_offset) 114 p.wire_y_offset = +abs(p.wire_y_offset) 115 x_translation = nodes.origin + [p.wire_x_offset, -p.undercut/2-p.fillet/2] 116 y_translation = nodes.origin + [p.undercut/2+p.fillet/2, p.wire_y_offset] 117 elif p.origin == 'lower left': 118 nodes.origin = np.array((-p.width/2, -p.height/2)) 119 p.wire_x_offset = +abs(p.wire_x_offset) 120 p.wire_y_offset = +abs(p.wire_y_offset) 121 x_translation = nodes.origin + [p.wire_x_offset, -p.undercut/2-p.fillet/2] 122 y_translation = nodes.origin + [-p.undercut/2-p.fillet/2, p.wire_y_offset] 123 else: 124 raise Exception('`origin` option not defined correctly') 125 126 # Wires 127 # `wire_x` is the wire that gets offset translated along x-direction 128 # `wire_y` is the wire that gets offset translated along y-direction 129 wire_x = draw.rectangle(p.wire_width, p.undercut+p.fillet) 130 wire_y = draw.rectangle(p.undercut+p.fillet, p.wire_width) 131 132 wire_x = draw.translate(wire_x, *x_translation) 133 wire_y = draw.translate(wire_y, *y_translation) 134 135 junction = draw.union([junc_rect, wire_x, wire_y]) 136 undercut = draw.subtract(undercut, junction) 137 138 # Translations & Rotations 139 geom_list = [junction, undercut] 140 geom_list = draw.rotate(geom_list, p.orientation, origin=(0, 0)) 141 geom_list = draw.translate(geom_list, p.pos_x, p.pos_y) 142 [junction, undercut] = geom_list 143 144 # Converting drawing to qgeometry 145 self.add_qgeometry('poly', {'junction': junction}, layer=p.layer) 146 self.add_qgeometry('poly', {'undercut': undercut}, layer=p.undercut_layer) 147 148 # Positioning nodes 149 nodes['+x_+y'] = nodes.origin + [p.wire_x_offset, p.wire_y_offset] 150 if p.origin == 'upper right': 151 nodes['+x'] = nodes.origin + [p.undercut, p.wire_y_offset] 152 nodes['+y'] = nodes.origin + [p.wire_x_offset, p.undercut] 153 if p.origin == 'upper left': 154 nodes['+x'] = nodes.origin + [-p.undercut, p.wire_y_offset] 155 nodes['+y'] = nodes.origin + [p.wire_x_offset, p.undercut] 156 if p.origin == 'lower right': 157 nodes['+x'] = nodes.origin + [p.undercut, p.wire_y_offset] 158 nodes['+y'] = nodes.origin + [p.wire_x_offset, -p.undercut] 159 if p.origin == 'lower left': 160 nodes['+x'] = nodes.origin + [-p.undercut, p.wire_y_offset] 161 nodes['+y'] = nodes.origin + [p.wire_x_offset, -p.undercut] 162 163 # Moving nodes along with component 164 translation_vec = np.array((p.pos_x, p.pos_y)) 165 theta = np.deg2rad(p.orientation) 166 for key, point in nodes.items(): 167 rotated = rotate_point(point, theta) 168 nodes[key] = rotated + translation_vec 169 170 self.nodes = nodes 171 return
Convert self.options into QGeometry.