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)
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 drawing options
Component metadata
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.