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) 
class BridgeFreeJunction(qiskit_metal.qlibrary.core.base.QComponent):
 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_options = {'width': '100um', 'height': '100um', 'wire_width': '5um', 'wire_x_offset': '5um', 'wire_y_offset': '5um', 'pos_x': '0um', 'pos_y': '0um', 'fillet': '0um', 'undercut': '25um', 'orientation': '0', 'origin': 'upper right', 'layer': '1', 'undercut_layer': '2'}

Default drawing options

component_metadata = {'short_name': 'bridgefreejunction', '_qgeometry_table_poly': 'True'}

Component metadata

def make(self):
 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.

def node(self, key):
173    def node(self, key): 
174        return self.nodes.get(key, None)