qiskit_metal.qlibrary.QNLMetal.inlineidc
InlineIDC (Interdigitated Capacitor).
`cpw0`
/
__ / __
/ / \
/ / \ \
/ / \
/__/__ _ _ _ ___\__\
| | | | | |
| |||||||| |
| ||||*||| |
| |||||||| |
| | | | | |
\‾‾\‾‾ ‾ ‾ ‾ ‾‾/‾‾/
\ \ / /
\ \ / /
\ \ / /
‾‾ / ‾‾
/
`cpw1'
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""" InlineIDC (Interdigitated Capacitor). 10 11.. code-block:: 12 13 `cpw0` 14 / 15 __ / __ 16 / / \ 17 / / \ \ 18 / / \ 19 /__/__ _ _ _ ___\__\ 20 | | | | | | 21 | |||||||| | 22 | ||||*||| | 23 | |||||||| | 24 | | | | | | 25 \‾‾\‾‾ ‾ ‾ ‾ ‾‾/‾‾/ 26 \ \ / / 27 \ \ / / 28 \ \ / / 29 ‾‾ / ‾‾ 30 / 31 `cpw1' 32 33""" 34 35import numpy as np 36from qiskit_metal import draw, Dict 37from qiskit_metal.qlibrary.core import QComponent 38from qiskit_metal.toolbox_python.utility_functions import rotate_point 39 40class InlineIDC(QComponent): 41 """ 42 Inherits `QComponent` Class. 43 44 Description: 45 Inline IDC (interdigitated capacitor) component. 46 47 Options: 48 * cpw_width: The width of the CPW trace 49 * cpw_gap : The CPW gap of the connected trace 50 * taper_length : The length of the taper segment 51 * taper_gap : The gap between inner trace & ground plane at widest point 52 * fingers_num : The number of fingers 53 * fingers_width : The finger width 54 * fingers.length: The finger length 55 * fingers_horizontal_gap : Horizontal gap between fingers 56 * fingers_vertical_gap : Vertical gap between fingers 57 * Note `Horizontal` & `Vertical` refer to default orientation 58 * pos_x/_y: position of the bandage on chip 59 * orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise 60 * layer: The layer for the Inline IDC 61 62 """ 63 64 # Default Drawing options 65 default_options = Dict( 66 cpw_width = '30um', 67 cpw_gap = '17.5um', 68 taper_length = '200um', 69 taper_gap = '87.5um', 70 fingers_num = '18', 71 fingers_width= '5um', 72 fingers_length = '200um', 73 fingers_horizontal_gap ='5um', 74 fingers_vertical_gap ='10um', 75 pos_x = '0um', 76 pos_y = '0um', 77 orientation = '0', 78 layer = '1', 79 ) 80 81 # Component metadata 82 # Name prefix for component, if user doesn't provide name 83 component_metadata = Dict( 84 short_name='InlineIDC', 85 _qgeometry_table_poly='True', 86 ) 87 88 def make(self): 89 """ Converts self.options into QGeometry. """ 90 p = self.parse_options() 91 nodes = Dict() 92 93 cpw_width = p.cpw_width 94 cpw_gap = p.cpw_gap 95 taper_length = p.taper_length 96 taper_gap = p.taper_gap 97 fingers_num = p.fingers_num 98 fingers_width = p.fingers_width 99 fingers_length = p.fingers_length 100 fingers_horizontal_gap = p.fingers_horizontal_gap 101 fingers_vertical_gap = p.fingers_vertical_gap 102 pos_x = p.pos_x 103 pos_y = p.pos_y 104 orientation = p.orientation 105 layer = p.layer 106 107 ## Meandering Portion 108 ## ------------------ 109 110 # Encompassing Central Box Dimensions 111 box_width = fingers_length 112 inner_box_length = fingers_num*fingers_horizontal_gap+(fingers_num-1)*fingers_width 113 outer_box_length = taper_gap 114 box_length = inner_box_length + 2*outer_box_length 115 116 # Build box and initialize CPW finger dimensions 117 box = draw.rectangle(box_length, box_width) 118 finger = draw.rectangle( 119 fingers_horizontal_gap, 120 fingers_length - fingers_vertical_gap, 121 ) 122 123 # X positions for each finger 124 finger_x_positions = [ 125 -inner_box_length/2+fingers_horizontal_gap/2+i*(fingers_horizontal_gap+fingers_width) 126 for i in range(int(fingers_num)) 127 ] 128 129 # Iteratively add each finger to list, alternating y-positions to create a meander 130 finger_list = [] 131 for idx in range(int(fingers_num)): 132 if idx%2 == 0: 133 finger_list.append( 134 draw.translate( 135 finger, 136 finger_x_positions[idx], 137 -fingers_vertical_gap/2, 138 ) 139 ) 140 else: 141 finger_list.append( 142 draw.translate( 143 finger, 144 finger_x_positions[idx], 145 +fingers_vertical_gap/2, 146 ) 147 ) 148 149 # Combine all unions into one component 150 fingers = draw.union(finger_list) 151 # Create the meandering inner portion of encompassing box 152 box = draw.subtract(box, fingers) 153 154 ## Tapering End Portion 155 ## -------------------- 156 157 # Building the cutoff triangles to create a taper 158 right_triangle = draw.Polygon([ 159 (-cpw_width/2, +box_width/2+taper_length), 160 (-cpw_width/2, +box_width/2), 161 (-inner_box_length/2, +box_width/2), 162 ]) 163 164 left_triangle = draw.Polygon([ 165 (-cpw_width/2-cpw_gap, +box_width/2+taper_length), 166 (-box_length/2, +box_width/2+taper_length), 167 (-box_length/2, +box_width/2), 168 ]) 169 cutoff_triangles = draw.union([left_triangle, right_triangle]) 170 171 # Initialize Encompassing Taper Box 172 taper = draw.rectangle(-cpw_width/2 + box_length/2, taper_length) 173 174 # Center of mass locations for taper 175 x_centroid = -cpw_width/2-0.25*(-cpw_width + box_length) 176 y_centroid = (taper_length + box_width)/2 177 taper = draw.translate(taper, x_centroid, y_centroid) 178 179 # Final Taper object 180 taper1 = draw.subtract(taper, cutoff_triangles) 181 182 # Placing tapers on edges with proper orientation 183 taper2 = draw.scale(taper1, xfact=-1, origin=(0,0)) 184 taper3 = draw.scale(taper1, yfact=-1, origin=(0,0)) 185 taper4 = draw.scale(taper1, xfact=-1, yfact=-1, origin=(0,0)) 186 tapers = draw.union([taper1, taper2, taper3, taper4]) 187 188 # Final InlineIDC component 189 inlineIDC = draw.union([box, tapers]) 190 191 # Translations \& Rotations 192 inlineIDC = draw.rotate(inlineIDC, orientation, origin=(0, 0)) 193 inlineIDC = draw.translate(inlineIDC, pos_x, pos_y) 194 195 # Converting to QGeometry 196 self.add_qgeometry('poly', {'InlineIDC': inlineIDC}, layer=layer) 197 198 ## Positioning Nodes 199 ## ----------------- 200 201 nodes.origin = np.zeros(2) 202 nodes.cpw0 = nodes.origin + [0, box_width/2 + taper_length] 203 nodes.cpw1 = -nodes.cpw0 204 205 # Moving nodes along with component 206 translation_vec = np.array((p.pos_x, p.pos_y)) 207 theta = np.deg2rad(p.orientation) 208 209 for key, point in nodes.items(): 210 rotated = rotate_point(point, theta) 211 nodes[key] = rotated + translation_vec 212 213 self.nodes = nodes 214 return 215 216 def node(self, key): 217 return self.nodes.get(key, None)
41class InlineIDC(QComponent): 42 """ 43 Inherits `QComponent` Class. 44 45 Description: 46 Inline IDC (interdigitated capacitor) component. 47 48 Options: 49 * cpw_width: The width of the CPW trace 50 * cpw_gap : The CPW gap of the connected trace 51 * taper_length : The length of the taper segment 52 * taper_gap : The gap between inner trace & ground plane at widest point 53 * fingers_num : The number of fingers 54 * fingers_width : The finger width 55 * fingers.length: The finger length 56 * fingers_horizontal_gap : Horizontal gap between fingers 57 * fingers_vertical_gap : Vertical gap between fingers 58 * Note `Horizontal` & `Vertical` refer to default orientation 59 * pos_x/_y: position of the bandage on chip 60 * orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise 61 * layer: The layer for the Inline IDC 62 63 """ 64 65 # Default Drawing options 66 default_options = Dict( 67 cpw_width = '30um', 68 cpw_gap = '17.5um', 69 taper_length = '200um', 70 taper_gap = '87.5um', 71 fingers_num = '18', 72 fingers_width= '5um', 73 fingers_length = '200um', 74 fingers_horizontal_gap ='5um', 75 fingers_vertical_gap ='10um', 76 pos_x = '0um', 77 pos_y = '0um', 78 orientation = '0', 79 layer = '1', 80 ) 81 82 # Component metadata 83 # Name prefix for component, if user doesn't provide name 84 component_metadata = Dict( 85 short_name='InlineIDC', 86 _qgeometry_table_poly='True', 87 ) 88 89 def make(self): 90 """ Converts self.options into QGeometry. """ 91 p = self.parse_options() 92 nodes = Dict() 93 94 cpw_width = p.cpw_width 95 cpw_gap = p.cpw_gap 96 taper_length = p.taper_length 97 taper_gap = p.taper_gap 98 fingers_num = p.fingers_num 99 fingers_width = p.fingers_width 100 fingers_length = p.fingers_length 101 fingers_horizontal_gap = p.fingers_horizontal_gap 102 fingers_vertical_gap = p.fingers_vertical_gap 103 pos_x = p.pos_x 104 pos_y = p.pos_y 105 orientation = p.orientation 106 layer = p.layer 107 108 ## Meandering Portion 109 ## ------------------ 110 111 # Encompassing Central Box Dimensions 112 box_width = fingers_length 113 inner_box_length = fingers_num*fingers_horizontal_gap+(fingers_num-1)*fingers_width 114 outer_box_length = taper_gap 115 box_length = inner_box_length + 2*outer_box_length 116 117 # Build box and initialize CPW finger dimensions 118 box = draw.rectangle(box_length, box_width) 119 finger = draw.rectangle( 120 fingers_horizontal_gap, 121 fingers_length - fingers_vertical_gap, 122 ) 123 124 # X positions for each finger 125 finger_x_positions = [ 126 -inner_box_length/2+fingers_horizontal_gap/2+i*(fingers_horizontal_gap+fingers_width) 127 for i in range(int(fingers_num)) 128 ] 129 130 # Iteratively add each finger to list, alternating y-positions to create a meander 131 finger_list = [] 132 for idx in range(int(fingers_num)): 133 if idx%2 == 0: 134 finger_list.append( 135 draw.translate( 136 finger, 137 finger_x_positions[idx], 138 -fingers_vertical_gap/2, 139 ) 140 ) 141 else: 142 finger_list.append( 143 draw.translate( 144 finger, 145 finger_x_positions[idx], 146 +fingers_vertical_gap/2, 147 ) 148 ) 149 150 # Combine all unions into one component 151 fingers = draw.union(finger_list) 152 # Create the meandering inner portion of encompassing box 153 box = draw.subtract(box, fingers) 154 155 ## Tapering End Portion 156 ## -------------------- 157 158 # Building the cutoff triangles to create a taper 159 right_triangle = draw.Polygon([ 160 (-cpw_width/2, +box_width/2+taper_length), 161 (-cpw_width/2, +box_width/2), 162 (-inner_box_length/2, +box_width/2), 163 ]) 164 165 left_triangle = draw.Polygon([ 166 (-cpw_width/2-cpw_gap, +box_width/2+taper_length), 167 (-box_length/2, +box_width/2+taper_length), 168 (-box_length/2, +box_width/2), 169 ]) 170 cutoff_triangles = draw.union([left_triangle, right_triangle]) 171 172 # Initialize Encompassing Taper Box 173 taper = draw.rectangle(-cpw_width/2 + box_length/2, taper_length) 174 175 # Center of mass locations for taper 176 x_centroid = -cpw_width/2-0.25*(-cpw_width + box_length) 177 y_centroid = (taper_length + box_width)/2 178 taper = draw.translate(taper, x_centroid, y_centroid) 179 180 # Final Taper object 181 taper1 = draw.subtract(taper, cutoff_triangles) 182 183 # Placing tapers on edges with proper orientation 184 taper2 = draw.scale(taper1, xfact=-1, origin=(0,0)) 185 taper3 = draw.scale(taper1, yfact=-1, origin=(0,0)) 186 taper4 = draw.scale(taper1, xfact=-1, yfact=-1, origin=(0,0)) 187 tapers = draw.union([taper1, taper2, taper3, taper4]) 188 189 # Final InlineIDC component 190 inlineIDC = draw.union([box, tapers]) 191 192 # Translations \& Rotations 193 inlineIDC = draw.rotate(inlineIDC, orientation, origin=(0, 0)) 194 inlineIDC = draw.translate(inlineIDC, pos_x, pos_y) 195 196 # Converting to QGeometry 197 self.add_qgeometry('poly', {'InlineIDC': inlineIDC}, layer=layer) 198 199 ## Positioning Nodes 200 ## ----------------- 201 202 nodes.origin = np.zeros(2) 203 nodes.cpw0 = nodes.origin + [0, box_width/2 + taper_length] 204 nodes.cpw1 = -nodes.cpw0 205 206 # Moving nodes along with component 207 translation_vec = np.array((p.pos_x, p.pos_y)) 208 theta = np.deg2rad(p.orientation) 209 210 for key, point in nodes.items(): 211 rotated = rotate_point(point, theta) 212 nodes[key] = rotated + translation_vec 213 214 self.nodes = nodes 215 return 216 217 def node(self, key): 218 return self.nodes.get(key, None)
Inherits QComponent
Class.
Description: Inline IDC (interdigitated capacitor) component.
Options:
* cpw_width: The width of the CPW trace
* cpw_gap : The CPW gap of the connected trace
* taper_length : The length of the taper segment
* taper_gap : The gap between inner trace & ground plane at widest point
* fingers_num : The number of fingers
* fingers_width : The finger width
* fingers.length: The finger length
* fingers_horizontal_gap : Horizontal gap between fingers
* fingers_vertical_gap : Vertical gap between fingers
* Note Horizontal
& Vertical
refer to default orientation
* pos_x/_y: position of the bandage on chip
* orientation : 0-> is parallel to x-axis, with orientation (in degrees) counterclockwise
* layer: The layer for the Inline IDC
Default drawing options
Component metadata
89 def make(self): 90 """ Converts self.options into QGeometry. """ 91 p = self.parse_options() 92 nodes = Dict() 93 94 cpw_width = p.cpw_width 95 cpw_gap = p.cpw_gap 96 taper_length = p.taper_length 97 taper_gap = p.taper_gap 98 fingers_num = p.fingers_num 99 fingers_width = p.fingers_width 100 fingers_length = p.fingers_length 101 fingers_horizontal_gap = p.fingers_horizontal_gap 102 fingers_vertical_gap = p.fingers_vertical_gap 103 pos_x = p.pos_x 104 pos_y = p.pos_y 105 orientation = p.orientation 106 layer = p.layer 107 108 ## Meandering Portion 109 ## ------------------ 110 111 # Encompassing Central Box Dimensions 112 box_width = fingers_length 113 inner_box_length = fingers_num*fingers_horizontal_gap+(fingers_num-1)*fingers_width 114 outer_box_length = taper_gap 115 box_length = inner_box_length + 2*outer_box_length 116 117 # Build box and initialize CPW finger dimensions 118 box = draw.rectangle(box_length, box_width) 119 finger = draw.rectangle( 120 fingers_horizontal_gap, 121 fingers_length - fingers_vertical_gap, 122 ) 123 124 # X positions for each finger 125 finger_x_positions = [ 126 -inner_box_length/2+fingers_horizontal_gap/2+i*(fingers_horizontal_gap+fingers_width) 127 for i in range(int(fingers_num)) 128 ] 129 130 # Iteratively add each finger to list, alternating y-positions to create a meander 131 finger_list = [] 132 for idx in range(int(fingers_num)): 133 if idx%2 == 0: 134 finger_list.append( 135 draw.translate( 136 finger, 137 finger_x_positions[idx], 138 -fingers_vertical_gap/2, 139 ) 140 ) 141 else: 142 finger_list.append( 143 draw.translate( 144 finger, 145 finger_x_positions[idx], 146 +fingers_vertical_gap/2, 147 ) 148 ) 149 150 # Combine all unions into one component 151 fingers = draw.union(finger_list) 152 # Create the meandering inner portion of encompassing box 153 box = draw.subtract(box, fingers) 154 155 ## Tapering End Portion 156 ## -------------------- 157 158 # Building the cutoff triangles to create a taper 159 right_triangle = draw.Polygon([ 160 (-cpw_width/2, +box_width/2+taper_length), 161 (-cpw_width/2, +box_width/2), 162 (-inner_box_length/2, +box_width/2), 163 ]) 164 165 left_triangle = draw.Polygon([ 166 (-cpw_width/2-cpw_gap, +box_width/2+taper_length), 167 (-box_length/2, +box_width/2+taper_length), 168 (-box_length/2, +box_width/2), 169 ]) 170 cutoff_triangles = draw.union([left_triangle, right_triangle]) 171 172 # Initialize Encompassing Taper Box 173 taper = draw.rectangle(-cpw_width/2 + box_length/2, taper_length) 174 175 # Center of mass locations for taper 176 x_centroid = -cpw_width/2-0.25*(-cpw_width + box_length) 177 y_centroid = (taper_length + box_width)/2 178 taper = draw.translate(taper, x_centroid, y_centroid) 179 180 # Final Taper object 181 taper1 = draw.subtract(taper, cutoff_triangles) 182 183 # Placing tapers on edges with proper orientation 184 taper2 = draw.scale(taper1, xfact=-1, origin=(0,0)) 185 taper3 = draw.scale(taper1, yfact=-1, origin=(0,0)) 186 taper4 = draw.scale(taper1, xfact=-1, yfact=-1, origin=(0,0)) 187 tapers = draw.union([taper1, taper2, taper3, taper4]) 188 189 # Final InlineIDC component 190 inlineIDC = draw.union([box, tapers]) 191 192 # Translations \& Rotations 193 inlineIDC = draw.rotate(inlineIDC, orientation, origin=(0, 0)) 194 inlineIDC = draw.translate(inlineIDC, pos_x, pos_y) 195 196 # Converting to QGeometry 197 self.add_qgeometry('poly', {'InlineIDC': inlineIDC}, layer=layer) 198 199 ## Positioning Nodes 200 ## ----------------- 201 202 nodes.origin = np.zeros(2) 203 nodes.cpw0 = nodes.origin + [0, box_width/2 + taper_length] 204 nodes.cpw1 = -nodes.cpw0 205 206 # Moving nodes along with component 207 translation_vec = np.array((p.pos_x, p.pos_y)) 208 theta = np.deg2rad(p.orientation) 209 210 for key, point in nodes.items(): 211 rotated = rotate_point(point, theta) 212 nodes[key] = rotated + translation_vec 213 214 self.nodes = nodes 215 return
Converts self.options into QGeometry.