qiskit_metal.qlibrary.QNLMetal.junctionlead

JunctionLead.

`lead_1
 |‾‾‾‾‾‾‾‾‾‾‾‾|‾‾‾ --- ___          | 
 |            |            ‾‾‾|‾‾‾‾‾|‾‾∖
*|            |               |  /‾‾|   |- `lead_0`
 |            |               | /   |  /
 |            |    ___ --- ‾‾‾ /‾‾‾‾|‾‾
  ‾‾‾‾‾‾‾‾‾‾‾‾ ‾‾‾            /  `lead_2` 
                             /     
                       `inner_lead`
  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""" JunctionLead. 
 10
 11.. code-block:: 
 12
 13
 14                                           `lead_1
 15            |‾‾‾‾‾‾‾‾‾‾‾‾|‾‾‾ --- ___          | 
 16            |            |            ‾‾‾|‾‾‾‾‾|‾‾∖
 17           *|            |               |  /‾‾|   |- `lead_0`
 18            |            |               | /   |  /
 19            |            |    ___ --- ‾‾‾ /‾‾‾‾|‾‾
 20             ‾‾‾‾‾‾‾‾‾‾‾‾ ‾‾‾            /  `lead_2` 
 21                                        /     
 22                                  `inner_lead`
 23"""
 24
 25import numpy as np 
 26from qiskit_metal import draw, Dict 
 27from qiskit_metal.qlibrary.core import QComponent 
 28from qiskit_metal.toolbox_python.utility_functions import rotate_point
 29
 30
 31
 32class JunctionLead(QComponent): 
 33    """ 
 34    Inherits `QComponent` Class. 
 35
 36    Description: 
 37        Large Junction leads. 
 38        These are the large junction leads that connect the SQUID loop or junction wires to 
 39        the capacitor pads.  
 40
 41    Options: 
 42        * outer_length : The length of the wide section.
 43                         will be computed from the total length and the lengths of the other segments
 44        * outer_width  : The width of the wide section 
 45        * inner_length : The length of the narrow section 
 46        * inner_width  : The width of the narrow section 
 47        * taper_length : The length of the taper 
 48        * pos_x/_y     : `origin` position of junction lead on chip 
 49                         `origin` is the left-edge-center of the wide-section 
 50        * fillet : The radius of the fillet. Only the two corners at the end of the narrow section 
 51                   will be filleted. 
 52        * extension    : The length of the narrow section past the junction wires. 
 53        * orientation  : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise 
 54        * layer: the layer number for the JunctionLead
 55
 56
 57    """ 
 58
 59    # Default drawing options 
 60    default_options = Dict( 
 61        outer_length='500um', 
 62        outer_width='250um', 
 63        inner_length='250um', 
 64        inner_width='125um', 
 65        taper_length='700um', 
 66        fillet='0um', 
 67        extension='0um', 
 68    )
 69
 70    # Component metadata 
 71    # Name prefix for component, if user doesn't provide name 
 72    component_metadata = Dict( 
 73        short_name='JunctionLead', 
 74        _qgeometry_table_poly='True', 
 75    )
 76
 77    def make(self): 
 78        """ Convert self.options into QGeometry. """ 
 79        p = self.parse_options() 
 80        nodes = Dict() 
 81
 82        # Wide section 
 83        wide_rect = draw.rectangle(p.outer_length, p.outer_width) 
 84
 85        # Tapered section -- Built via subtract
 86        tapered_rect = draw.rectangle(p.taper_length, p.outer_width) 
 87
 88        upper_triangle = draw.Polygon([
 89            (-p.taper_length/2, +p.outer_width/2), 
 90            (+p.taper_length/2, +p.outer_width/2), 
 91            (+p.taper_length/2, +p.inner_width/2), 
 92        ]) 
 93        lower_triangle = draw.Polygon([
 94            (-p.taper_length/2, -p.outer_width/2), 
 95            (+p.taper_length/2, -p.outer_width/2), 
 96            (+p.taper_length/2, -p.inner_width/2), 
 97        ]) 
 98        
 99        tapered_rect = draw.subtract(tapered_rect, upper_triangle) 
100        tapered_rect = draw.subtract(tapered_rect, lower_triangle) 
101        
102        # Inner section 
103        inner_rect = draw.rectangle(p.inner_length, p.inner_width) 
104        
105        def fillet_right_corners(L, W, r, num_points=10): 
106            """ 
107            Returns a shapely polyon for a rectangle of (`L` x `W`) centered at 
108            (0, 0), where only the two right corners are filleted with radius `r`. 
109
110            This is for the filleted-narrow-end of the JunctionLead. 
111
112            """ 
113
114            if r > W/2 or r > L/2: 
115                raise ValueError('Fillet radius is too large for the provided rectangle dimensions.') 
116
117            # Non-filleted corners 
118            top_left    = (-L/2, +W/2) 
119            bottom_left = (-L/2, -W/2) 
120
121            # Tangent points where the fillets begin/end 
122            top_right_straight = (L/2-r, W/2) 
123            bottom_right_straight = (L/2, -W/2) 
124
125            # Top right fillet 
126            center_tr = (L/2 - r, W/2 - r) 
127            arc_tr = [] 
128            for i in range(num_points + 1): 
129                theta = np.pi/2 * (1 - i/num_points) 
130                x = center_tr[0] + r * np.cos(theta) 
131                y = center_tr[1] + r * np.sin(theta) 
132                arc_tr.append((x, y))
133
134            # Bottom right fillet 
135            center_br = (L/2 - r, -W/2 + r) 
136            arc_br = [] 
137            for i in range(num_points + 1): 
138                theta = 0 - (np.pi/2) * (i/num_points) 
139                x = center_br[0] + r * np.cos(theta) 
140                y = center_br[1] + r * np.sin(theta) 
141                arc_br.append((x, y)) 
142
143            coords = []
144            coords.append(bottom_left)                
145            coords.append(top_left)                    
146            coords.append(top_right_straight)          
147            coords.extend(arc_tr)                      
148            coords.append((L/2, -W/2 + r))
149            coords.extend(arc_br)                      
150            coords.append(bottom_left)
151
152            return draw.Polygon(coords)
153            
154        if p.extension != 0.0: 
155            extended_rect = draw.rectangle(p.extension, p.inner_width)  
156            extended_rect = fillet_right_corners(p.extension, p.inner_width, p.fillet) 
157        else: 
158            inner_rect = fillet_right_corners(p.inner_length, p.inner_width, p.fillet)
159            extended_rect = draw.rectangle(0, 0) # default to null rectangle
160
161        # Positioning all sections correctly 
162        tapered_rect = draw.translate(tapered_rect, (p.outer_length + p.taper_length)/2, 0) 
163        inner_rect = draw.translate(inner_rect, p.taper_length + (p.outer_length + p.inner_length)/2, 0)
164        extended_rect = draw.translate(extended_rect, p.taper_length + p.inner_length + (p.outer_length + p.extension)/2, 0)
165            
166        # Translations & Rotations 
167        junction_lead = draw.union([wide_rect, tapered_rect, inner_rect, extended_rect] )
168        junction_lead = draw.rotate(junction_lead, p.orientation)
169        junction_lead = draw.translate(junction_lead, p.pos_x + p.outer_length/2, p.pos_y) 
170
171        # Converting drawing to qgeometry  
172        self.add_qgeometry('poly', {'junction_lead': junction_lead}, layer = p.layer) 
173
174        # Positioning nodes 
175        nodes.origin = np.zeros(2)
176        nodes.lead_0 = nodes.origin + [p.outer_length+p.taper_length+p.inner_length+p.extension, 0]
177        nodes.lead_1 = nodes.lead_0 + [-p.extension, p.inner_width/2] 
178        nodes.lead_2 = nodes.lead_0 + [-p.extension, -p.inner_width/2]
179        nodes.inner_lead = nodes.lead_0 + [-p.extension, 0] 
180
181        # Moving nodes along with component 
182        # pivot necessary as origin is not defined at center of object
183        pivot = np.array([(p.outer_length + p.taper_length + p.inner_length + p.extension)/2, 0])
184        theta = np.deg2rad(p.orientation)
185        translation_vec = np.array((p.pos_x, p.pos_y)) 
186        for key, point in nodes.items(): 
187            relative = point - pivot
188            rotated_relative = rotate_point(relative, theta)
189            rotated = pivot + rotated_relative
190            nodes[key] = rotated + translation_vec
191
192        self.nodes = nodes
193        return  
194
195    def node(self, key): 
196        return self.nodes.get(key, None) 
class JunctionLead(qiskit_metal.qlibrary.core.base.QComponent):
 33class JunctionLead(QComponent): 
 34    """ 
 35    Inherits `QComponent` Class. 
 36
 37    Description: 
 38        Large Junction leads. 
 39        These are the large junction leads that connect the SQUID loop or junction wires to 
 40        the capacitor pads.  
 41
 42    Options: 
 43        * outer_length : The length of the wide section.
 44                         will be computed from the total length and the lengths of the other segments
 45        * outer_width  : The width of the wide section 
 46        * inner_length : The length of the narrow section 
 47        * inner_width  : The width of the narrow section 
 48        * taper_length : The length of the taper 
 49        * pos_x/_y     : `origin` position of junction lead on chip 
 50                         `origin` is the left-edge-center of the wide-section 
 51        * fillet : The radius of the fillet. Only the two corners at the end of the narrow section 
 52                   will be filleted. 
 53        * extension    : The length of the narrow section past the junction wires. 
 54        * orientation  : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise 
 55        * layer: the layer number for the JunctionLead
 56
 57
 58    """ 
 59
 60    # Default drawing options 
 61    default_options = Dict( 
 62        outer_length='500um', 
 63        outer_width='250um', 
 64        inner_length='250um', 
 65        inner_width='125um', 
 66        taper_length='700um', 
 67        fillet='0um', 
 68        extension='0um', 
 69    )
 70
 71    # Component metadata 
 72    # Name prefix for component, if user doesn't provide name 
 73    component_metadata = Dict( 
 74        short_name='JunctionLead', 
 75        _qgeometry_table_poly='True', 
 76    )
 77
 78    def make(self): 
 79        """ Convert self.options into QGeometry. """ 
 80        p = self.parse_options() 
 81        nodes = Dict() 
 82
 83        # Wide section 
 84        wide_rect = draw.rectangle(p.outer_length, p.outer_width) 
 85
 86        # Tapered section -- Built via subtract
 87        tapered_rect = draw.rectangle(p.taper_length, p.outer_width) 
 88
 89        upper_triangle = draw.Polygon([
 90            (-p.taper_length/2, +p.outer_width/2), 
 91            (+p.taper_length/2, +p.outer_width/2), 
 92            (+p.taper_length/2, +p.inner_width/2), 
 93        ]) 
 94        lower_triangle = draw.Polygon([
 95            (-p.taper_length/2, -p.outer_width/2), 
 96            (+p.taper_length/2, -p.outer_width/2), 
 97            (+p.taper_length/2, -p.inner_width/2), 
 98        ]) 
 99        
100        tapered_rect = draw.subtract(tapered_rect, upper_triangle) 
101        tapered_rect = draw.subtract(tapered_rect, lower_triangle) 
102        
103        # Inner section 
104        inner_rect = draw.rectangle(p.inner_length, p.inner_width) 
105        
106        def fillet_right_corners(L, W, r, num_points=10): 
107            """ 
108            Returns a shapely polyon for a rectangle of (`L` x `W`) centered at 
109            (0, 0), where only the two right corners are filleted with radius `r`. 
110
111            This is for the filleted-narrow-end of the JunctionLead. 
112
113            """ 
114
115            if r > W/2 or r > L/2: 
116                raise ValueError('Fillet radius is too large for the provided rectangle dimensions.') 
117
118            # Non-filleted corners 
119            top_left    = (-L/2, +W/2) 
120            bottom_left = (-L/2, -W/2) 
121
122            # Tangent points where the fillets begin/end 
123            top_right_straight = (L/2-r, W/2) 
124            bottom_right_straight = (L/2, -W/2) 
125
126            # Top right fillet 
127            center_tr = (L/2 - r, W/2 - r) 
128            arc_tr = [] 
129            for i in range(num_points + 1): 
130                theta = np.pi/2 * (1 - i/num_points) 
131                x = center_tr[0] + r * np.cos(theta) 
132                y = center_tr[1] + r * np.sin(theta) 
133                arc_tr.append((x, y))
134
135            # Bottom right fillet 
136            center_br = (L/2 - r, -W/2 + r) 
137            arc_br = [] 
138            for i in range(num_points + 1): 
139                theta = 0 - (np.pi/2) * (i/num_points) 
140                x = center_br[0] + r * np.cos(theta) 
141                y = center_br[1] + r * np.sin(theta) 
142                arc_br.append((x, y)) 
143
144            coords = []
145            coords.append(bottom_left)                
146            coords.append(top_left)                    
147            coords.append(top_right_straight)          
148            coords.extend(arc_tr)                      
149            coords.append((L/2, -W/2 + r))
150            coords.extend(arc_br)                      
151            coords.append(bottom_left)
152
153            return draw.Polygon(coords)
154            
155        if p.extension != 0.0: 
156            extended_rect = draw.rectangle(p.extension, p.inner_width)  
157            extended_rect = fillet_right_corners(p.extension, p.inner_width, p.fillet) 
158        else: 
159            inner_rect = fillet_right_corners(p.inner_length, p.inner_width, p.fillet)
160            extended_rect = draw.rectangle(0, 0) # default to null rectangle
161
162        # Positioning all sections correctly 
163        tapered_rect = draw.translate(tapered_rect, (p.outer_length + p.taper_length)/2, 0) 
164        inner_rect = draw.translate(inner_rect, p.taper_length + (p.outer_length + p.inner_length)/2, 0)
165        extended_rect = draw.translate(extended_rect, p.taper_length + p.inner_length + (p.outer_length + p.extension)/2, 0)
166            
167        # Translations & Rotations 
168        junction_lead = draw.union([wide_rect, tapered_rect, inner_rect, extended_rect] )
169        junction_lead = draw.rotate(junction_lead, p.orientation)
170        junction_lead = draw.translate(junction_lead, p.pos_x + p.outer_length/2, p.pos_y) 
171
172        # Converting drawing to qgeometry  
173        self.add_qgeometry('poly', {'junction_lead': junction_lead}, layer = p.layer) 
174
175        # Positioning nodes 
176        nodes.origin = np.zeros(2)
177        nodes.lead_0 = nodes.origin + [p.outer_length+p.taper_length+p.inner_length+p.extension, 0]
178        nodes.lead_1 = nodes.lead_0 + [-p.extension, p.inner_width/2] 
179        nodes.lead_2 = nodes.lead_0 + [-p.extension, -p.inner_width/2]
180        nodes.inner_lead = nodes.lead_0 + [-p.extension, 0] 
181
182        # Moving nodes along with component 
183        # pivot necessary as origin is not defined at center of object
184        pivot = np.array([(p.outer_length + p.taper_length + p.inner_length + p.extension)/2, 0])
185        theta = np.deg2rad(p.orientation)
186        translation_vec = np.array((p.pos_x, p.pos_y)) 
187        for key, point in nodes.items(): 
188            relative = point - pivot
189            rotated_relative = rotate_point(relative, theta)
190            rotated = pivot + rotated_relative
191            nodes[key] = rotated + translation_vec
192
193        self.nodes = nodes
194        return  
195
196    def node(self, key): 
197        return self.nodes.get(key, None) 

Inherits QComponent Class.

Description: Large Junction leads. These are the large junction leads that connect the SQUID loop or junction wires to the capacitor pads.

Options: * outer_length : The length of the wide section. will be computed from the total length and the lengths of the other segments * outer_width : The width of the wide section * inner_length : The length of the narrow section * inner_width : The width of the narrow section * taper_length : The length of the taper * pos_x/_y : origin position of junction lead on chip origin is the left-edge-center of the wide-section * fillet : The radius of the fillet. Only the two corners at the end of the narrow section will be filleted. * extension : The length of the narrow section past the junction wires. * orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise * layer: the layer number for the JunctionLead

default_options = {'outer_length': '500um', 'outer_width': '250um', 'inner_length': '250um', 'inner_width': '125um', 'taper_length': '700um', 'fillet': '0um', 'extension': '0um'}

Default drawing options

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

Component metadata

def make(self):
 78    def make(self): 
 79        """ Convert self.options into QGeometry. """ 
 80        p = self.parse_options() 
 81        nodes = Dict() 
 82
 83        # Wide section 
 84        wide_rect = draw.rectangle(p.outer_length, p.outer_width) 
 85
 86        # Tapered section -- Built via subtract
 87        tapered_rect = draw.rectangle(p.taper_length, p.outer_width) 
 88
 89        upper_triangle = draw.Polygon([
 90            (-p.taper_length/2, +p.outer_width/2), 
 91            (+p.taper_length/2, +p.outer_width/2), 
 92            (+p.taper_length/2, +p.inner_width/2), 
 93        ]) 
 94        lower_triangle = draw.Polygon([
 95            (-p.taper_length/2, -p.outer_width/2), 
 96            (+p.taper_length/2, -p.outer_width/2), 
 97            (+p.taper_length/2, -p.inner_width/2), 
 98        ]) 
 99        
100        tapered_rect = draw.subtract(tapered_rect, upper_triangle) 
101        tapered_rect = draw.subtract(tapered_rect, lower_triangle) 
102        
103        # Inner section 
104        inner_rect = draw.rectangle(p.inner_length, p.inner_width) 
105        
106        def fillet_right_corners(L, W, r, num_points=10): 
107            """ 
108            Returns a shapely polyon for a rectangle of (`L` x `W`) centered at 
109            (0, 0), where only the two right corners are filleted with radius `r`. 
110
111            This is for the filleted-narrow-end of the JunctionLead. 
112
113            """ 
114
115            if r > W/2 or r > L/2: 
116                raise ValueError('Fillet radius is too large for the provided rectangle dimensions.') 
117
118            # Non-filleted corners 
119            top_left    = (-L/2, +W/2) 
120            bottom_left = (-L/2, -W/2) 
121
122            # Tangent points where the fillets begin/end 
123            top_right_straight = (L/2-r, W/2) 
124            bottom_right_straight = (L/2, -W/2) 
125
126            # Top right fillet 
127            center_tr = (L/2 - r, W/2 - r) 
128            arc_tr = [] 
129            for i in range(num_points + 1): 
130                theta = np.pi/2 * (1 - i/num_points) 
131                x = center_tr[0] + r * np.cos(theta) 
132                y = center_tr[1] + r * np.sin(theta) 
133                arc_tr.append((x, y))
134
135            # Bottom right fillet 
136            center_br = (L/2 - r, -W/2 + r) 
137            arc_br = [] 
138            for i in range(num_points + 1): 
139                theta = 0 - (np.pi/2) * (i/num_points) 
140                x = center_br[0] + r * np.cos(theta) 
141                y = center_br[1] + r * np.sin(theta) 
142                arc_br.append((x, y)) 
143
144            coords = []
145            coords.append(bottom_left)                
146            coords.append(top_left)                    
147            coords.append(top_right_straight)          
148            coords.extend(arc_tr)                      
149            coords.append((L/2, -W/2 + r))
150            coords.extend(arc_br)                      
151            coords.append(bottom_left)
152
153            return draw.Polygon(coords)
154            
155        if p.extension != 0.0: 
156            extended_rect = draw.rectangle(p.extension, p.inner_width)  
157            extended_rect = fillet_right_corners(p.extension, p.inner_width, p.fillet) 
158        else: 
159            inner_rect = fillet_right_corners(p.inner_length, p.inner_width, p.fillet)
160            extended_rect = draw.rectangle(0, 0) # default to null rectangle
161
162        # Positioning all sections correctly 
163        tapered_rect = draw.translate(tapered_rect, (p.outer_length + p.taper_length)/2, 0) 
164        inner_rect = draw.translate(inner_rect, p.taper_length + (p.outer_length + p.inner_length)/2, 0)
165        extended_rect = draw.translate(extended_rect, p.taper_length + p.inner_length + (p.outer_length + p.extension)/2, 0)
166            
167        # Translations & Rotations 
168        junction_lead = draw.union([wide_rect, tapered_rect, inner_rect, extended_rect] )
169        junction_lead = draw.rotate(junction_lead, p.orientation)
170        junction_lead = draw.translate(junction_lead, p.pos_x + p.outer_length/2, p.pos_y) 
171
172        # Converting drawing to qgeometry  
173        self.add_qgeometry('poly', {'junction_lead': junction_lead}, layer = p.layer) 
174
175        # Positioning nodes 
176        nodes.origin = np.zeros(2)
177        nodes.lead_0 = nodes.origin + [p.outer_length+p.taper_length+p.inner_length+p.extension, 0]
178        nodes.lead_1 = nodes.lead_0 + [-p.extension, p.inner_width/2] 
179        nodes.lead_2 = nodes.lead_0 + [-p.extension, -p.inner_width/2]
180        nodes.inner_lead = nodes.lead_0 + [-p.extension, 0] 
181
182        # Moving nodes along with component 
183        # pivot necessary as origin is not defined at center of object
184        pivot = np.array([(p.outer_length + p.taper_length + p.inner_length + p.extension)/2, 0])
185        theta = np.deg2rad(p.orientation)
186        translation_vec = np.array((p.pos_x, p.pos_y)) 
187        for key, point in nodes.items(): 
188            relative = point - pivot
189            rotated_relative = rotate_point(relative, theta)
190            rotated = pivot + rotated_relative
191            nodes[key] = rotated + translation_vec
192
193        self.nodes = nodes
194        return  

Convert self.options into QGeometry.

def node(self, key):
196    def node(self, key): 
197        return self.nodes.get(key, None)