def make(self): """Build the component.""" face = draw.shapely.geometry.Point(0, 0).buffer(1) eye = draw.shapely.geometry.Point(0, 0).buffer(0.2) eye_l = draw.translate(eye, -0.4, 0.4) eye_r = draw.translate(eye, 0.4, 0.4) smile = draw.shapely.geometry.Point(0, 0).buffer(0.8) cut_sq = draw.shapely.geometry.box(-1, -0.3, 1, 1) smile = draw.subtract(smile, cut_sq) frown = draw.rotate(smile, 180) frown = draw.translate(frown, 0, 0.3) frown = draw.subtract(frown, draw.shapely.geometry.Point(0, -0.8).buffer(0.7)) face = draw.subtract(face, eye_l) if self.p.happy: face = draw.subtract(face, smile) else: face = draw.subtract(face, frown) if self.p.wink: face = draw.subtract( face, draw.shapely.geometry.LineString([(0.2, 0.4), (0.6, 0.4)]).buffer(0.02)) else: face = draw.subtract(face, eye_r) face = draw.rotate(face, self.p.orientation, origin=(0, 0)) self.add_qgeometry('poly', {'Smiley': face})
def make_inner_star(self): """This function creates the coordinates for the pins """ p = self.p # Extracting coordinated from the user input values coords = self.make_coordinates_trap() coords1 = self.make_resonator_coordinates() trap_0 = draw.Polygon(coords) traps = self.make_rotation(trap_0, 5) # Define the final structure based on use input if (p.number_of_connectors) == 0: traps = traps[2] elif (p.number_of_connectors) == 1: traps = draw.union(traps[0], traps[2]) elif (p.number_of_connectors) == 2: traps = draw.union(traps[0], traps[1], traps[2]) elif (p.number_of_connectors) == 3: traps = draw.union(traps[0], traps[1], traps[2], traps[3]) elif (p.number_of_connectors) == 4: traps = draw.union(traps[0], traps[1], traps[2], traps[3], traps[4]) # Subtract from circle circle = self.make_circle() total1 = draw.subtract(circle, traps) # create rectangular connectors to junction pockets = self.make_pockets() rect1 = draw.rectangle(pockets[2], pockets[3]) rect1 = draw.translate(rect1, xoff=coords1[0][0] * 1.1, yoff=p.radius) rect1 = draw.rotate(rect1, p.rotation_cpl1, origin=(0, 0)) rect2 = draw.rectangle(pockets[2], pockets[3]) rect2 = draw.translate(rect2, xoff=coords1[1][0] * 1.1, yoff=p.radius) rect2 = draw.rotate(rect2, p.rotation_cpl1, origin=(0, 0)) #junction jjunction = draw.LineString([[0, 0], [0, coords[1][0]]]) jjunction = draw.translate(jjunction, yoff=(1.15 * (p.radius))) jjunction = draw.rotate(jjunction, p.rotation_cpl1, origin=(0, 0)) # Add connection to the junction total = draw.union(total1, rect1, rect2) objects = [total, jjunction] objects = draw.rotate(objects, p.orientation, origin=(0, 0)) objects = draw.translate(objects, p.pos_x, p.pos_y) [total, jjunction] = objects self.add_qgeometry('poly', {'circle_inner': total}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip) self.add_qgeometry('junction', {'poly': jjunction}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip, width=p.junc_h)
def make(self): """The make function implements the logic that creates the geoemtry (poly, path, etc.) from the qcomponent.options dictionary of parameters, and the adds them to the design, using qcomponent.add_qgeometry(...), adding in extra needed information, such as layer, subtract, etc.""" p = self.p # p for parsed parameters. Access to the parsed options. n = int(p.n) # Create the geometry # Generates a list of points n_polygon = [(p.radius * np.cos(2 * np.pi * x / n), p.radius * np.sin(2 * np.pi * x / n)) for x in range(n)] # Converts said list into a shapely polygon n_polygon = draw.Polygon(n_polygon) n_polygon = draw.rotate(n_polygon, p.rotation, origin=(0, 0)) n_polygon = draw.translate(n_polygon, p.pos_x, p.pos_y) ############################################## # add qgeometry self.add_qgeometry('poly', {'n_polygon': n_polygon}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip)
def make(self): """ The make function implements the logic that creates the geoemtry (poly, path, etc.) from the qcomponent.options dictionary of parameters, and the adds them to the design, using qcomponent.add_qgeometry(...), adding in extra needed information, such as layer, subtract, etc. """ p = self.p # p for parsed parameters. Access to the parsed options. # create the geometry caterpillar = [ draw.Point(p.pos_x - p.radius * i * p.distance, p.pos_y).buffer( p.radius, resolution=int(p.resolution), cap_style=getattr(CAP_STYLE, p.cap_style), #join_style = getattr(JOIN_STYLE, p.join_style) ) for i in range(int(p.segments)) ] caterpillar = draw.union(caterpillar) poly = draw.Polygon([(0, 0), (0.5, 0), (0.25, 0.5)]) poly = draw.translate(poly, p.pos_x, p.pos_y) poly = draw.rotate(poly, angle=65) caterpillar = draw.subtract(caterpillar, poly) # rect = draw.rectangle(p.radius*0.75, p.radius*0.23, # xoff=p.pos_x+p.radius*0.3, # yoff=p.pos_y+p.radius*0.4) #caterpillar = draw.subtract(caterpillar, rect) # print(caterpillar) # add qgeometry #self.add_qgeometry('poly', {'mount': rect}) self.add_qgeometry('poly', {'caterpillar': caterpillar})
def make_rotation(self, obj, num): """This function rotates objects. """ p = self.p if num == 1: rotation = [p.rotation_rdout] x = 1 elif num == 2: rotation = [p.rotation_rdout + 180] x = 1 elif num == 3: rotation = [ p.rotation_cpl1 + 180, p.rotation_cpl2 + 180, p.rotation_cpl3 + 180, p.rotation_cpl4 + 180 ] x = 4 elif num == 4: rotation = [ p.rotation_cpl1, p.rotation_cpl2, p.rotation_cpl3, p.rotation_cpl4 ] x = 4 elif num == 5: rotation = [ p.rotation_cpl1, p.rotation_cpl2, p.rotation_rdout, p.rotation_cpl3, p.rotation_cpl4 ] x = 5 obj_array = [0] * x for i in range(x): obj_array[i] = draw.rotate(obj, rotation[i], origin=(0, 0)) return obj_array
def make(self): """The make function implements the logic that creates the geoemtry (poly, path, etc.) from the qcomponent.options dictionary of parameters, and the adds them to the design, using qcomponent.add_qgeometry(...), adding in extra needed information, such as layer, subtract, etc.""" p = self.p # p for parsed parameters. Access to the parsed options. n = int(p.n) # Create the geometry spiral_list = [] #Formulat to determine the size of the spiral based on inputed length. x_n = (p.length / (2 * n)) - (p.height + 2 * (p.gap + p.line_width) * (2 * n - 1)) if x_n <= p.gap + p.line_width: self._error_message = f'Inputted values results in the width of the spiral being too small.' self.logger.warning(self._error_message) return for step in range(n): x_point = x_n / 2 + step * (p.line_width + p.gap) y_point = p.height / 2 + step * (p.line_width + p.gap) spiral_list.append((-x_point, -y_point)) spiral_list.append((x_point, -y_point)) spiral_list.append((x_point, y_point)) spiral_list.append((-x_point - (p.line_width + p.gap), y_point)) x_point = (x_n / 2 + (step + 1) * (p.line_width + p.gap)) y_point = (p.height / 2 + (step + 1) * (p.line_width + p.gap) - p.line_width / 2) spiral_list.append((-x_point, -y_point)) spiral_list = draw.LineString(spiral_list) spiral_etch = draw.shapely.geometry.box( -(x_point + p.line_width / 2 + p.gap), -y_point, x_point - p.line_width / 2, y_point) #Generates a linestring to track port location points = draw.LineString([ (-x_point + p.line_width / 2, -y_point + p.coupler_distance), (-x_point - p.line_width / 2, -y_point + p.coupler_distance) ]) c_items = [spiral_list, spiral_etch, points] c_items = draw.rotate(c_items, p.orientation, origin=(0, 0)) c_items = draw.translate(c_items, p.pos_x, p.pos_y) [spiral_list, spiral_etch, points] = c_items ############################################## # add elements self.add_qgeometry('path', {'n_spiral': spiral_list}, width=p.line_width) self.add_qgeometry('poly', {'n_spira_etch': spiral_etch}, subtract=True) # NEW PIN SPOT self.add_pin('spiralPin', points=np.array(points.coords), width=p.line_width, input_as_norm=True)
def generate_spiral_list(x: int, y: int): """Helper function to generate a sprital list. Args: x (int): x-coordinate y (int): y-coordinate Returns: list: A list of points """ spiral_list = [] for step in range(3): point_value = 20 + step * 5 spiral_list.append((-point_value, -point_value)) spiral_list.append((point_value, -point_value)) spiral_list.append((point_value, point_value)) spiral_list.append((-point_value - (1 + 4), point_value)) point_value = 20 + (step + 1) * 5 spiral_list.append((-point_value, -point_value)) spiral_list = draw.LineString(spiral_list) spiral_list = draw.rotate(spiral_list, 0, origin=(x, y)) spiral_list = draw.translate(spiral_list, x, y) return spiral_list
def make(self): """Convert self.options into QGeometry.""" p = self.parse_options() # Parse the string options into numbers # draw the lower pad as a rectangle JJ_pad_lower = draw.rectangle(p.JJ_pad_lower_width, p.JJ_pad_lower_height, p.JJ_pad_lower_pos_x, p.JJ_pad_lower_pos_y) finger_lower = draw.rectangle( p.finger_lower_width, p.finger_lower_height, p.JJ_pad_lower_pos_x, 0.5 * (p.JJ_pad_lower_height + p.finger_lower_height)) # merge the lower pad and the finger into a single object design = draw.union(JJ_pad_lower, finger_lower) # copy the pad/finger and rotate it by 90 degrees design2 = draw.rotate(design, 90.0) # translate the second pad/finger to achieve the desired extension # for a Manhattan-like configuration design2 = draw.translate( design2, 0.5 * (p.JJ_pad_lower_height + p.finger_lower_height) - 0.5 * p.finger_lower_width - p.extension, 0.5 * (p.JJ_pad_lower_height + p.finger_lower_height) - 0.5 * p.finger_lower_width - p.extension) # now translate the second pad/finger to achieve the desired offset # from the first pad/finger design2 = draw.translate(design2, p.extension + p.finger_lower_width + p.offset) final_design = draw.union(design, design2) second_metal = draw.rectangle( p.second_metal_width, p.second_metal_length, p.JJ_pad_lower_pos_x + p.offset + 0.5 * p.finger_lower_width, 0.5 * p.JJ_pad_lower_height + p.finger_lower_height - 0.5 * p.second_metal_length) # translate everything so that the bottom left corner of the lower # pad is at the origin final_design = draw.translate(final_design, 0.5 * p.JJ_pad_lower_width, 0.5 * p.JJ_pad_lower_height) second_metal = draw.translate(second_metal, 0.5 * p.JJ_pad_lower_width, 0.5 * p.JJ_pad_lower_height) # now translate so that the bottom left corner is at the # user-defined coordinates (pos_x, pos_y) final_design = draw.translate(final_design, p.pos_x, p.pos_y) second_metal = draw.translate(second_metal, p.pos_x, p.pos_y) geom1 = {'design': final_design} self.add_qgeometry('poly', geom1, layer=p.layer, subtract=False) geom2 = {'design': second_metal} self.add_qgeometry('poly', geom2, layer=2.0, subtract=False)
def make(self): """This is executed by the user to generate the qgeometry for the component.""" p = self.p trace_width = p.trace_width trace_width_half = trace_width / 2 lead_length = p.lead_length trace_gap = p.trace_gap ######################################################### # Geometry of main launch structure launch_pad = draw.Polygon([(0, trace_width_half), (-.122, trace_width_half + .035), (-.202, trace_width_half + .035), (-.202, -trace_width_half - .035), (-.122, -trace_width_half - .035), (0, -trace_width_half), (lead_length, -trace_width_half), (lead_length, +trace_width_half), (0, trace_width_half)]) # Geometry pocket (gap) pocket = draw.Polygon([(0, trace_width_half + trace_gap), (-.122, trace_width_half + trace_gap + .087), (-.25, trace_width_half + trace_gap + .087), (-.25, -trace_width_half - trace_gap - .087), (-.122, -trace_width_half - trace_gap - .087), (0, -trace_width_half - trace_gap), (lead_length, -trace_width_half - trace_gap), (lead_length, +trace_width_half + trace_gap), (0, trace_width_half + trace_gap)]) # These variables are used to graphically locate the pin locations main_pin_line = draw.LineString([(lead_length, trace_width_half), (lead_length, -trace_width_half)]) # Create polygon object list polys1 = [main_pin_line, launch_pad, pocket] # Rotates and translates all the objects as requested. Uses package functions in # 'draw_utility' for easy rotation/translation polys1 = draw.rotate(polys1, p.orientation, origin=(0, 0)) polys1 = draw.translate(polys1, xoff=p.pos_x, yoff=p.pos_y) [main_pin_line, launch_pad, pocket] = polys1 # Adds the object to the qgeometry table self.add_qgeometry('poly', dict(launch_pad=launch_pad), layer=p.layer) # Subtracts out ground plane on the layer its on self.add_qgeometry('poly', dict(pocket=pocket), subtract=True, layer=p.layer) # Generates the pins self.add_pin('tie', main_pin_line.coords, trace_width)
def make(self): """Convert self.options into QGeometry.""" p = self.parse_options() # Parse the string options into numbers # EDIT HERE - Replace the following with your code # Create some raw geometry # Use autocompletion for the `draw.` module (use tab key) rect = draw.rectangle(p.width, p.height, p.pos_x, p.pos_y) rect = draw.rotate(rect, p.rotation) geom = {'my_polygon': rect} self.add_qgeometry('poly', geom, layer=p.layer, subtract=False)
def make(self): """Build the component.""" p = self.p prime_cpw_length = p.t_length * 2 #Primary CPW prime_cpw = draw.LineString([[-prime_cpw_length / 2, 0], [prime_cpw_length / 2, 0]]) #Secondary CPW second_cpw = draw.LineString([[0, -p.prime_width / 2], [0, -p.t_length]]) #Rotate and Translate c_items = [prime_cpw, second_cpw] c_items = draw.rotate(c_items, p.orientation, origin=(0, 0)) c_items = draw.translate(c_items, p.pos_x, p.pos_y) [prime_cpw, second_cpw] = c_items #Add to qgeometry tables self.add_qgeometry('path', {'prime_cpw': prime_cpw}, width=p.prime_width, layer=p.layer) self.add_qgeometry('path', {'prime_cpw_sub': prime_cpw}, width=p.prime_width + 2 * p.prime_gap, subtract=True, layer=p.layer) self.add_qgeometry('path', {'second_cpw': second_cpw}, width=p.second_width, layer=p.layer) self.add_qgeometry('path', {'second_cpw_sub': second_cpw}, width=p.second_width + 2 * p.second_gap, subtract=True, layer=p.layer) #Add pins prime_pin_list = prime_cpw.coords second_pin_list = second_cpw.coords self.add_pin('prime_start', points=np.array(prime_pin_list[::-1]), width=p.prime_width, input_as_norm=True) self.add_pin('prime_end', points=np.array(prime_pin_list), width=p.prime_width, input_as_norm=True) self.add_pin('second_end', points=np.array(second_pin_list), width=p.second_width, input_as_norm=True)
def make_charge_line(self): """Creates the charge line if the user has charge line option to TRUE. """ # Grab option values name = 'Charge_Line' p = self.p cl_arm = draw.box(0, 0, -p.cl_width, p.cl_length) cl_cpw = draw.box(0, 0, -8 * p.cl_width, p.cl_width) cl_metal = draw.cascaded_union([cl_arm, cl_cpw]) cl_etcher = draw.buffer(cl_metal, p.cl_gap) port_line = draw.LineString([(-8 * p.cl_width, 0), (-8 * p.cl_width, p.cl_width)]) polys = [cl_metal, cl_etcher, port_line] # Move the charge line to the side user requested cl_rotate = 0 if (abs(p.cl_pocket_edge) > 135) or (abs(p.cl_pocket_edge) < 45): polys = draw.translate( polys, -(p.pocket_width / 2 + p.cl_ground_gap + p.cl_gap), p.cl_off_center) if (abs(p.cl_pocket_edge) > 135): cl_rotate = 180 else: polys = draw.translate( polys, -(p.pocket_height / 2 + p.cl_ground_gap + p.cl_gap), p.cl_off_center) cl_rotate = 90 if (p.cl_pocket_edge < 0): cl_rotate = -90 # Rotate it to the pockets orientation polys = draw.rotate(polys, p.orientation + cl_rotate, origin=(0, 0)) # Move to the final position polys = draw.translate(polys, p.pos_x, p.pos_y) [cl_metal, cl_etcher, port_line] = polys # Generating pins points = list(draw.shapely.geometry.shape(port_line).coords) self.add_pin(name, points, p.cl_width) # Adding to qgeometry table self.add_qgeometry('poly', dict(cl_metal=cl_metal)) self.add_qgeometry('poly', dict(cl_etcher=cl_etcher), subtract=True)
def arc(self, coord_init, coord_center, angle): ''' Generate x,y coordinates (in terms of shapely.geometry.Point()) of an arc with: a specified initial point, rotation center, and rotation direction (specified by angle in radian (float or integer), positive is ccw). coord_init, and coord_center should be shapely.geometry.Point object ''' # access to parse values from the user option p = self.p # local variable r = p.readout_cpw_turnradius step = p.arc_step # determine step number step_angle = step / r if angle >= 0 else -step / r step_N = abs(int(angle / step_angle)) #laststep_flag = True if angle % step_angle != 0 else False laststep_flag = bool(angle % step_angle != 0) # generate coordinate coord = [coord_init] point = coord_init for i in range(step_N): point = draw.rotate(point, step_angle, origin=coord_center, use_radians=True) coord.append(point) if laststep_flag: point = draw.rotate(coord_init, angle, origin=coord_center, use_radians=True) coord.append(point) coord = draw.LineString(coord) return coord
def make(self): """The make function implements the logic that creates the geoemtry (poly, path, etc.) from the qcomponent.options dictionary of parameters, and the adds them to the design, using qcomponent.add_qgeometry(...), adding in extra needed information, such as layer, subtract, etc.""" p = self.p # p for parsed parameters. Access to the parsed options. # create the geometry rect = draw.rectangle(p.width, p.height, p.pos_x, p.pos_y) rec1 = draw.rectangle(p.inner.width, p.inner.height, p.pos_x + p.inner.offset_x, p.pos_y + p.inner.offset_y) rec1 = draw.rotate(rec1, p.inner.orientation) rect = draw.subtract(rect, rec1) rect = draw.rotate(rect, p.orientation) # add qgeometry self.add_qgeometry('poly', {'rect': rect}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip)
def make(self): """Build the component.""" p = self.p # p for parsed parameters. Access to the parsed options. port_line = draw.LineString([(0, -p.width / 2), (0, p.width / 2)]) # Rotates and translates the connector polygons (and temporary port_line) port_line = draw.rotate(port_line, p.orientation, origin=(0, 0)) port_line = draw.translate(port_line, p.pos_x, p.pos_y) port_points = list(draw.shapely.geometry.shape(port_line).coords) #Generates the pin self.add_pin('short', port_points, p.width)
def make(self): """Convert self.options into QGeometry.""" p = self.parse_options() # Parse the string options into numbers # draw the lower pad as a rectangle plate1 = draw.rectangle(p.plate1_width, p.plate1_height, p.plate1_pos_x, p.plate1_pos_y) segment_a = draw.rectangle(p.segment_a_length, p.segment_a_width, 0.5 * (p.plate1_width + p.segment_a_length), 0.5 * (p.squid_gap + p.segment_a_width)) segment_a_lower = draw.translate( segment_a, 0.0, -1.0 * (p.squid_gap + p.segment_a_width)) segment_b = draw.rectangle( p.segment_b_length, p.segment_b_width, 0.5 * (p.plate1_width + p.segment_b_length) + p.JJ_gap + p.segment_a_length, 0.5 * (p.squid_gap + p.segment_b_width)) segment_b_lower = draw.translate( segment_b, 0.0, -1.0 * (p.squid_gap + p.segment_b_width)) segment_c = draw.rectangle( p.segment_c_width, p.squid_gap + p.segment_a_width + p.segment_b_width, 0.5 * (p.plate1_width + p.segment_c_width) + p.segment_a_length + p.segment_b_length + p.JJ_gap, p.plate1_pos_y) segment_d = draw.rectangle( p.segment_d_length, p.segment_d_width, 0.5 * (p.plate1_width + p.segment_d_length) + p.segment_a_length + p.segment_b_length + p.JJ_gap + p.segment_c_width, p.plate1_pos_y) plate2 = draw.rectangle( p.plate2_width, p.plate2_height, 0.5 * (p.plate1_width + p.plate2_width) + p.segment_a_length + p.JJ_gap + p.segment_b_length + p.segment_c_width + p.segment_d_length, p.plate1_pos_y) design1 = draw.union(plate1, segment_a, segment_a_lower, segment_b, segment_b_lower, segment_c, segment_d, plate2) # now translate and rotate the final structure design1 = draw.rotate(design1, p.orientation, origin=(0, 0)) design1 = draw.translate(design1, p.pos_x, p.pos_y) geom = {'design': design1} self.add_qgeometry('poly', geom, layer=p.layer, subtract=False)
def make_flux_line(self): """Creates the charge line if the user has charge line option to TRUE """ # Grab option values pf = self.p.fl_options p = self.p #Make the T flux line h_line = draw.LineString([(-pf.t_top / 2, 0), (pf.t_top / 2, 0)]) v_line = draw.LineString([(pf.t_offset, 0), (pf.t_offset, -0.03)]) parts = [h_line, v_line] # Move the flux line down to the SQUID parts = draw.translate( parts, 0, -(p.cross_length + p.cross_gap + pf.t_inductive_gap + pf.t_width / 2 + pf.t_gap)) # Rotate and translate based on crossmon location parts = draw.rotate(parts, p.orientation, origin=(0, 0)) parts = draw.translate(parts, p.pos_x, p.pos_y) [h_line, v_line] = parts # Adding to qgeometry table self.add_qgeometry('path', { 'h_line': h_line, 'v_line': v_line }, width=pf.t_width, layer=p.layer) self.add_qgeometry('path', { 'h_line_sub': h_line, 'v_line_sub': v_line }, width=pf.t_width + 2 * pf.t_gap, subtract=True, layer=p.layer) # Generating pin pin_line = v_line.coords self.add_pin("flux_line", points=pin_line, width=pf.t_width, gap=pf.t_gap, input_as_norm=True)
def make_outer_circle(self): """This function draws the outer circle. """ p = self.p coords = self.make_coordinates_trap() circle_outer = draw.Point(0, 0).buffer( p.radius * (1 + (p.connector_length / p.radius)), resolution=int(p.resolution), cap_style=getattr(CAP_STYLE, p.cap_style)) #Connectors for the ground plane pockets = self.make_pockets() pocket_z = draw.rectangle(pockets[0] * 1.4, pockets[1]) pocket_z = draw.translate(pocket_z, xoff=0, yoff=(coords[2][1])) pockets_ground = self.make_rotation(pocket_z, 5) if (p.number_of_connectors) == 0: circle_outer = draw.union(circle_outer, pockets_ground[2]) elif (p.number_of_connectors) == 1: circle_outer = draw.union(circle_outer, pockets_ground[0], pockets_ground[2]) elif (p.number_of_connectors) == 2: circle_outer = draw.union(circle_outer, pockets_ground[0], pockets_ground[1], pockets_ground[2]) elif (p.number_of_connectors) == 3: circle_outer = draw.union(circle_outer, pockets_ground[0], pockets_ground[1], pockets_ground[2], pockets_ground[3]) elif (p.number_of_connectors) == 4: circle_outer = draw.union(circle_outer, pockets_ground[0], pockets_ground[1], pockets_ground[2], pockets_ground[3], pockets_ground[4]) ################################################################## # Add geometry and Qpin connections objects = [circle_outer] objects = draw.rotate(objects, p.orientation, origin=(0, 0)) objects = draw.translate(objects, p.pos_x, p.pos_y) [circle_outer] = objects self.add_qgeometry('poly', {'circle_outer': circle_outer}, subtract=True, helper=p.helper, layer=p.layer, chip=p.chip)
def make_pocket(self): """Makes a basic Crossmon, 4 arm cross.""" # self.p allows us to directly access parsed values (string -> numbers) form the user option p = self.p cross_width = p.cross_width cross_length = p.cross_length cross_gap = p.cross_gap # access to chip name chip = p.chip # Creates the cross and the etch equivalent. cross_line = draw.shapely.ops.unary_union([ draw.LineString([(0, cross_length), (0, -cross_length)]), draw.LineString([(cross_length, 0), (-cross_length, 0)]) ]) cross = cross_line.buffer(cross_width / 2, cap_style=2) cross_etch = cross.buffer(cross_gap, cap_style=3, join_style=2) # The junction/SQUID #rect_jj = draw.rectangle(cross_width, cross_gap) #rect_jj = draw.translate(rect_jj, 0, -cross_length-cross_gap/2) rect_jj = draw.LineString([(0, -cross_length), (0, -cross_length - cross_gap)]) #rotate and translate polys = [cross, cross_etch, rect_jj] polys = draw.rotate(polys, p.orientation, origin=(0, 0)) polys = draw.translate(polys, p.pos_x, p.pos_y) [cross, cross_etch, rect_jj] = polys # generate qgeometry self.add_qgeometry('poly', dict(cross=cross), chip=chip) self.add_qgeometry('poly', dict(cross_etch=cross_etch), subtract=True, chip=chip) self.add_qgeometry('junction', dict(rect_jj=rect_jj), width=cross_width, chip=chip)
def make(self): """Convert self.options into QGeometry.""" p = self.parse_options() # Parse the string options into numbers # draw the lower pad as a rectangle JJ_pad_lower = draw.rectangle(p.JJ_pad_lower_width, p.JJ_pad_lower_height, p.JJ_pad_lower_pos_x, p.JJ_pad_lower_pos_y) finger_lower = draw.rectangle( p.finger_lower_width, p.finger_lower_height, p.JJ_pad_lower_pos_x, 0.5 * (p.JJ_pad_lower_height + p.finger_lower_height)) # fudge factor to merge the two options finger_lower = draw.translate(finger_lower, 0.0, -0.0001) # merge the lower pad and the finger into a single object design = draw.union(JJ_pad_lower, finger_lower) # copy the pad/finger and rotate it by 90 degrees design2 = draw.rotate(design, 90.0) # translate the second pad/finger to achieve the desired extension design2 = draw.translate( design2, 0.5 * (p.JJ_pad_lower_height + p.finger_lower_height) - 0.5 * p.finger_lower_width - p.extension, 0.5 * (p.JJ_pad_lower_height + p.finger_lower_height) - 0.5 * p.finger_lower_width - p.extension) final_design = draw.union(design, design2) # translate the final design so that the bottom left # corner of the lower pad is at the origin final_design = draw.translate(final_design, 0.5 * p.JJ_pad_lower_width, 0.5 * p.JJ_pad_lower_height) # now translate so that the design is centered on the # user-defined coordinates (x_pos, y_pos) final_design = draw.translate(final_design, p.x_pos, p.y_pos) geom = {'design': final_design} self.add_qgeometry('poly', geom, layer=p.layer, subtract=False)
def make_readout_resonator(self): """This function draws the readout resonator. Adds pins. And adds the drawn geometry to qgeomtery table. """ p = self.p coords_readout = self.make_readout_coordinates() circle = self.make_circle() pockets = self.make_pockets() coords = self.make_coordinates_trap() # Make the readout resonator with the pocket contact_rdout = draw.Polygon(coords_readout) contact_rdout = draw.subtract(circle, contact_rdout) contact_rdout = self.make_rotation(contact_rdout, 1) # Define contacts pocket0 = draw.rectangle(pockets[0], pockets[1]) pocket0 = draw.translate(pocket0, xoff=0, yoff=(coords[3][1])) pocket0 = self.make_rotation(pocket0, 1) # Join the coupler and contact contact_rdout = draw.union(contact_rdout[0], pocket0[0]) pins = self.make_pin_coordinates() pins_rdout = self.make_rotation(pins, 2) objects = [contact_rdout, pins_rdout] objects = draw.rotate(objects, p.orientation, origin=(0, 0)) objects = draw.translate(objects, p.pos_x, p.pos_y) [contact_rdout, pins_rdout] = objects ################################################################## # Add geometry and Qpin connections self.add_qgeometry('poly', {'contact_rdout': contact_rdout}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip) self.add_pin('pin_rdout', pins_rdout[0].coords, width=p.cpw_width, input_as_norm=True)
def make(self): """ The make function implements the logic that creates the geoemtry (poly, path, etc.) from the qcomponent.options dictionary of parameters, and the adds them to the design, using qcomponent.add_qgeometry(...), adding in extra needed information, such as layer, subtract, etc. """ p = self.p # p for parsed parameters. Access to the parsed options. n = int(p.n) # Create the geometry spiral_list = [] for step in range(n): point_value = p.radius / 2 + step * (p.width + p.gap) spiral_list.append((-point_value, -point_value)) spiral_list.append((point_value, -point_value)) spiral_list.append((point_value, point_value)) spiral_list.append((-point_value - (p.width + p.gap), point_value)) point_value = p.radius / 2 + (step + 1) * (p.width + p.gap) spiral_list.append((-point_value, -point_value)) spiral_list = draw.LineString(spiral_list) spiral_list = draw.rotate(spiral_list, p.rotation, origin=(0, 0)) spiral_list = draw.translate(spiral_list, p.pos_x, p.pos_y) ############################################## # add qgeometry self.add_qgeometry('path', {'n_spiral': spiral_list}, width=p.width, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip) points = np.array(spiral_list.coords) # FIX POINTS, self.add_pin('spiralPin', points=points[-2:], width=p.width, input_as_norm=True)
def make(self): """Build the component.""" p = self.p # p for parsed parameters. Access to the parsed options. port_line = draw.LineString([(0, -p.width / 2), (0, p.width / 2)]) open_termination = draw.box(0, -(p.width / 2 + p.gap), p.termination_gap, (p.width / 2 + p.gap)) # Rotates and translates the connector polygons (and temporary port_line) polys = [open_termination, port_line] polys = draw.rotate(polys, p.orientation, origin=(0, 0)) polys = draw.translate(polys, p.pos_x, p.pos_y) [open_termination, port_line] = polys # Subtracts out ground plane on the layer its on self.add_qgeometry('poly', {'open_to_ground': open_termination}, subtract=True, layer=p.layer) # Generates the pins self.add_pin('open', port_line.coords, p.width)
def make_pocket(self): """Makes standard transmon in a pocket.""" # self.p allows us to directly access parsed values (string -> numbers) form the user option p = self.p # since we will reuse these options, parse them once and define them as variables pad_width = p.pad_width pad_height = p.pad_height pad_gap = p.pad_gap # make the pads as rectangles (shapely polygons) pad = draw.rectangle(pad_width, pad_height) pad_top = draw.translate(pad, 0, +(pad_height + pad_gap) / 2.) pad_bot = draw.translate(pad, 0, -(pad_height + pad_gap) / 2.) rect_jj = draw.LineString([(0, -pad_gap / 2), (0, +pad_gap / 2)]) # the draw.rectangle representing the josephson junction # rect_jj = draw.rectangle(p.inductor_width, pad_gap) rect_pk = draw.rectangle(p.pocket_width, p.pocket_height) # Rotate and translate all qgeometry as needed. # Done with utility functions in Metal 'draw_utility' for easy rotation/translation # NOTE: Should modify so rotate/translate accepts qgeometry, would allow for # smoother implementation. polys = [rect_jj, pad_top, pad_bot, rect_pk] polys = draw.rotate(polys, p.orientation, origin=(0, 0)) polys = draw.translate(polys, p.pos_x, p.pos_y) [rect_jj, pad_top, pad_bot, rect_pk] = polys # Use the geometry to create Metal qgeometry self.add_qgeometry('poly', dict(pad_top=pad_top, pad_bot=pad_bot)) self.add_qgeometry('poly', dict(rect_pk=rect_pk), subtract=True) # self.add_qgeometry('poly', dict( # rect_jj=rect_jj), helper=True) self.add_qgeometry('junction', dict(rect_jj=rect_jj), width=p.inductor_width)
def make_ro(self): ''' Create the head of the readout resonator. Contains: the circular patch for coupling, the 45 deg line, the 45 deg arc, a short straight segment (of length w) for smooth subtraction ''' # access to parsed values from the user option p = self.p # access to chip name chip = p.chip # local variables r = p.readout_radius w = p.readout_cpw_width g = p.readout_cpw_gap turnradius = p.readout_cpw_turnradius l_1 = p.readout_l1 l_2 = p.readout_l2 l_3 = p.readout_l3 l_4 = p.readout_l4 l_5 = p.readout_l5 # create the coupling patch in term of a circle cppatch = draw.Point(0, 0).buffer(r) # create the extended arm ## useful coordinates x_1, y_1 = l_1 * np.cos(np.pi / 4), -l_1 * np.sin(np.pi / 4) x_2, y_2 = x_1 + turnradius * ( 1 - np.cos(np.pi / 4)), y_1 - turnradius * np.sin(np.pi / 4) coord_init = draw.Point(x_1, y_1) coord_center = draw.Point(x_1 - turnradius * np.cos(np.pi / 4), y_1 - turnradius * np.sin(np.pi / 4)) x_3, y_3 = x_2, y_2 x_4, y_4 = x_3, y_3 - l_2 x_5, y_5 = x_4 + turnradius, y_4 coord_init1 = draw.Point(x_4, y_4) coord_center1 = draw.Point(x_5, y_5) x_6, y_6 = x_5, y_5 - turnradius x_7, y_7 = x_5 + l_3, y_6 x_8, y_8 = x_7, y_7 + turnradius coord_init2 = draw.Point((x_7, y_7)) coord_center2 = draw.Point((x_8, y_8)) x_9, y_9 = x_8, y_8 + turnradius x_10, y_10 = x_8 - l_4, y_9 x_11, y_11 = x_10, y_10 + turnradius coord_init3 = draw.Point((x_10, y_10)) coord_center3 = draw.Point((x_11, y_11)) arc3 = self.arc(coord_init3, coord_center3, -np.pi) x_12, y_12 = x_11, y_11 + turnradius x_13, y_13 = x_12 + l_5, y_12 line12 = draw.LineString([(x_12, y_12), (x_13, y_13)]) x_14, y_14 = x_13, y_13 + turnradius coord_init4 = draw.Point((x_13, y_13)) coord_center4 = draw.Point((x_14, y_14)) arc4 = self.arc(coord_init4, coord_center4, np.pi) ## line containing the 45deg line, 45 deg arc, ## and a short straight segment for smooth subtraction cparm_line = draw.shapely.ops.unary_union([ draw.LineString([(0, 0), coord_init]), self.arc(coord_init, coord_center, -np.pi / 4), draw.LineString([(x_3, y_3), (x_4, y_4)]), self.arc(coord_init1, coord_center1, np.pi / 2), draw.LineString([(x_6, y_6), (x_7, y_7)]), self.arc(coord_init2, coord_center2, np.pi), draw.LineString([(x_9, y_9), (x_10, y_10)]), arc3, line12, arc4, draw.translate(line12, 0, 2 * turnradius), draw.translate(arc3, 0, 4 * turnradius), draw.translate(line12, 0, 4 * turnradius), draw.translate(arc4, 0, 4 * turnradius), draw.translate(line12, 0, 6 * turnradius), draw.translate(arc3, 0, 8 * turnradius), draw.translate(line12, 0, 8 * turnradius) ]) cparm = cparm_line.buffer(w / 2, cap_style=2, join_style=1) ## fix the gap resulting from buffer eps = 1e-3 cparm = draw.Polygon(cparm.exterior) cparm = cparm.buffer(eps, join_style=2).buffer(-eps, join_style=2) # create combined objects for the signal line and the etch ro = draw.shapely.ops.unary_union([cppatch, cparm]) ro_etch = ro.buffer(g, cap_style=2, join_style=2) x_15, y_15 = x_14, y_14 + 7 * turnradius x_16, y_16 = x_15 + g / 2, y_15 port_line = draw.LineString([(x_15, y_15 + w / 2), (x_15, y_15 - w / 2)]) subtract_patch = draw.LineString([(x_16, y_16 - w / 2 - g - eps), (x_16, y_16 + w / 2 + g + eps) ]).buffer(g / 2, cap_style=2) ro_etch = ro_etch.difference(subtract_patch) # rotate and translate polys = [ro, ro_etch, port_line] polys = draw.rotate(polys, p.orientation, origin=(0, 0)) polys = draw.translate(polys, p.pos_x, p.pos_y) # update each object [ro, ro_etch, port_line] = polys # generate QGeometry self.add_qgeometry('poly', dict(ro=ro), chip=chip, layer=p.layer) self.add_qgeometry('poly', dict(ro_etch=ro_etch), chip=chip, layer=p.layer_subtract, subtract=p.subtract) # generate pins self.add_pin('readout', port_line.coords, width=w, gap=g, chip=chip)
def make(self): """Build the component.""" p = self.p N = int(p.finger_count) prime_cpw_length = p.cap_width * 2 * N #Primary CPW prime_cpw = draw.LineString([[-prime_cpw_length / 2, 0], [prime_cpw_length / 2, 0]]) #Finger Capacitor cap_box = draw.rectangle(N * p.cap_width + (N - 1) * p.cap_gap, p.cap_gap + 2 * p.cap_width + p.finger_length, 0, 0) make_cut_list = [] make_cut_list.append([0, (p.finger_length) / 2]) make_cut_list.append([(p.cap_width) + (p.cap_gap / 2), (p.finger_length) / 2]) flip = -1 for i in range(1, N): make_cut_list.append([ i * (p.cap_width) + (2 * i - 1) * (p.cap_gap / 2), flip * (p.finger_length) / 2 ]) make_cut_list.append([ (i + 1) * (p.cap_width) + (2 * i + 1) * (p.cap_gap / 2), flip * (p.finger_length) / 2 ]) flip = flip * -1 cap_cut = draw.LineString(make_cut_list).buffer(p.cap_gap / 2, cap_style=2, join_style=2) cap_cut = draw.translate(cap_cut, -(N * p.cap_width + (N - 1) * p.cap_gap) / 2, 0) cap_body = draw.subtract(cap_box, cap_cut) cap_body = draw.translate( cap_body, 0, -p.cap_distance - (p.cap_gap + 2 * p.cap_width + p.finger_length) / 2) cap_etch = draw.rectangle( N * p.cap_width + (N - 1) * p.cap_gap + 2 * p.second_gap, p.cap_gap + 2 * p.cap_width + p.finger_length + 2 * p.second_gap, 0, -p.cap_distance - (p.cap_gap + 2 * p.cap_width + p.finger_length) / 2) #Secondary CPW second_cpw_top = draw.LineString([[0, -p.prime_width / 2], [0, -p.cap_distance]]) second_cpw_bottom = draw.LineString( [[ 0, -p.cap_distance - (p.cap_gap + 2 * p.cap_width + p.finger_length) ], [ 0, -2 * p.cap_distance - (p.cap_gap + 2 * p.cap_width + p.finger_length) ]]) #Rotate and Translate c_items = [ prime_cpw, second_cpw_top, second_cpw_bottom, cap_body, cap_etch ] c_items = draw.rotate(c_items, p.orientation, origin=(0, 0)) c_items = draw.translate(c_items, p.pos_x, p.pos_y) [prime_cpw, second_cpw_top, second_cpw_bottom, cap_body, cap_etch] = c_items #Add to qgeometry tables self.add_qgeometry('path', {'prime_cpw': prime_cpw}, width=p.prime_width, layer=p.layer) self.add_qgeometry('path', {'prime_cpw_sub': prime_cpw}, width=p.prime_width + 2 * p.prime_gap, subtract=True, layer=p.layer) self.add_qgeometry('path', { 'second_cpw_top': second_cpw_top, 'second_cpw_bottom': second_cpw_bottom }, width=p.second_width, layer=p.layer) self.add_qgeometry('path', { 'second_cpw_top_sub': second_cpw_top, 'second_cpw_bottom_sub': second_cpw_bottom }, width=p.second_width + 2 * p.second_gap, subtract=True, layer=p.layer) self.add_qgeometry('poly', {'cap_body': cap_body}, layer=p.layer) self.add_qgeometry('poly', {'cap_etch': cap_etch}, layer=p.layer, subtract=True) #Add pins prime_pin_list = prime_cpw.coords second_pin_list = second_cpw_bottom.coords self.add_pin('prime_start', points=np.array(prime_pin_list[::-1]), width=p.prime_width, input_as_norm=True) self.add_pin('prime_end', points=np.array(prime_pin_list), width=p.prime_width, input_as_norm=True) self.add_pin('second_end', points=np.array(second_pin_list), width=p.second_width, input_as_norm=True)
def make_pocket(self): """Makes standard transmon in a pocket.""" # self.p allows us to directly access parsed values (string -> numbers) form the user option p = self.p # pcop = self.p.coupled_pads[name] # parser on connector options # since we will reuse these options, parse them once and define them as variables pad_width = p.pad_width pad_height = p.pad_height pad_gap = p.pad_gap coupled_pad_height = p.coupled_pad_height coupled_pad_width = p.coupled_pad_width coupled_pad_gap = p.coupled_pad_gap # make the pads as rectangles (shapely polygons) pad = draw.rectangle(pad_width, pad_height) pad_top = draw.translate(pad, 0, +(pad_height + pad_gap) / 2.) # Here, you make your pads round. Not sharp shape on the left and right sides and also this should be the same for the bottom pad as the top pad. circ_left_top = draw.Point(-pad_width / 2., +(pad_height + pad_gap) / 2.).buffer(pad_height / 2, resolution=16, cap_style=CAP_STYLE.round) circ_right_top = draw.Point(pad_width / 2., +(pad_height + pad_gap) / 2.).buffer(pad_height / 2, resolution=16, cap_style=CAP_STYLE.round) # In here you create the teeth part and then you union them as one with the pad. Teeth only belong to top pad. coupled_pad = draw.rectangle(coupled_pad_width, coupled_pad_height + pad_height) coupler_pad_round = draw.Point(0., (coupled_pad_height + pad_height) / 2).buffer(coupled_pad_width / 2, resolution=16, cap_style=CAP_STYLE.round) coupled_pad = draw.union(coupled_pad, coupler_pad_round) coupled_pad_left = draw.translate( coupled_pad, -(coupled_pad_width / 2. + coupled_pad_gap / 2.), +coupled_pad_height / 2. + pad_height + pad_gap / 2. - pad_height / 2) coupled_pad_right = draw.translate( coupled_pad, (coupled_pad_width / 2. + coupled_pad_gap / 2.), +coupled_pad_height / 2. + pad_height + pad_gap / 2. - pad_height / 2) pad_top_tmp = draw.union([circ_left_top, pad_top, circ_right_top]) # The coupler pads are only created if low_W=0 and low_H=+1 for name in self.options.connection_pads: if self.options.connection_pads[name][ 'loc_W'] == 0 and self.options.connection_pads[name][ 'loc_H'] == +1: pad_top_tmp = draw.union([ circ_left_top, coupled_pad_left, pad_top, coupled_pad_right, circ_right_top ]) pad_top = pad_top_tmp # Round part for the bottom pad. And again you should unite all of them. pad_bot = draw.translate(pad, 0, -(pad_height + pad_gap) / 2.) circ_left_bot = draw.Point(-pad_width / 2, -(pad_height + pad_gap) / 2.).buffer(pad_height / 2, resolution=16, cap_style=CAP_STYLE.round) circ_right_bot = draw.Point(pad_width / 2, -(pad_height + pad_gap) / 2.).buffer(pad_height / 2, resolution=16, cap_style=CAP_STYLE.round) pad_bot = draw.union([pad_bot, circ_left_bot, circ_right_bot]) rect_jj = draw.LineString([(0, -pad_gap / 2), (0, +pad_gap / 2)]) # the draw.rectangle representing the josephson junction # rect_jj = draw.rectangle(p.inductor_width, pad_gap) rect_pk = draw.rectangle(p.pocket_width, p.pocket_height) # Rotate and translate all qgeometry as needed. # Done with utility functions in Metal 'draw_utility' for easy rotation/translation # NOTE: Should modify so rotate/translate accepts qgeometry, would allow for # smoother implementation. polys = [rect_jj, pad_top, pad_bot, rect_pk] polys = draw.rotate(polys, p.orientation, origin=(0, 0)) polys = draw.translate(polys, p.pos_x, p.pos_y) [rect_jj, pad_top, pad_bot, rect_pk] = polys # Use the geometry to create Metal qgeometry self.add_qgeometry('poly', dict(pad_top=pad_top, pad_bot=pad_bot)) self.add_qgeometry('poly', dict(rect_pk=rect_pk), subtract=True) # self.add_qgeometry('poly', dict( # rect_jj=rect_jj), helper=True) self.add_qgeometry('junction', dict(rect_jj=rect_jj), width=p.inductor_width)
def make_coupling_resonators(self, num): """This function draws the coulping resonators. Adds pins. And adds the drawn geometry to qgeomtery table. """ p = self.p # rotate these trapezoids to form the contacts coords = self.make_coordinates_trap() coords1 = self.make_resonator_coordinates() trap_z = draw.Polygon(coords1) traps_connection = self.make_rotation(trap_z, 4) # Define contacts pockets = self.make_pockets() pocket0 = draw.rectangle(pockets[0], pockets[1]) pocket0 = draw.translate(pocket0, xoff=0, yoff=(coords[3][1])) pockets = self.make_rotation(pocket0, 4) # Define the connectors circle = self.make_circle() contacts = [0] * num for i in range(num): contacts[i] = draw.subtract(circle, traps_connection[i]) contacts[i] = draw.union(contacts[i], pockets[i]) pins = self.make_pin_coordinates() pins_cpl = self.make_rotation(pins, 3) objects = [contacts, pins_cpl] objects = draw.rotate(objects, p.orientation, origin=(0, 0)) objects = draw.translate(objects, p.pos_x, p.pos_y) [contacts, pins_cpl] = objects ################################################################## # Add geometry and Qpin connections if (p.number_of_connectors) >= 1: self.add_qgeometry('poly', {'contact_cpl1': contacts[0]}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip) # Add pin connections self.add_pin('pin_cpl1', pins_cpl[0].coords, width=p.cpw_width, input_as_norm=True) if (p.number_of_connectors) >= 2: self.add_qgeometry('poly', {'contact_cpl2': contacts[1]}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip) # Add pin connections self.add_pin('pin_cpl2', pins_cpl[1].coords, width=p.cpw_width, input_as_norm=True) if (p.number_of_connectors) >= 3: self.add_qgeometry('poly', {'contact_cpl3': contacts[2]}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip) # Add pin connections self.add_pin('pin_cpl3', pins_cpl[2].coords, width=p.cpw_width, input_as_norm=True) if (p.number_of_connectors) >= 4: self.add_qgeometry('poly', {'contact_cpl4': contacts[3]}, subtract=p.subtract, helper=p.helper, layer=p.layer, chip=p.chip) # Add pin connections self.add_pin('pin_cpl4', pins_cpl[3].coords, width=p.cpw_width, input_as_norm=True)
def make(self): """Build the component.""" p = self.p N = int(p.finger_count) #Finger Capacitor cap_box = draw.rectangle(N * p.cap_width + (N - 1) * p.cap_gap, p.cap_gap + 2 * p.cap_width + p.finger_length, 0, 0) make_cut_list = [] make_cut_list.append([0, (p.finger_length) / 2]) make_cut_list.append([(p.cap_width) + (p.cap_gap / 2), (p.finger_length) / 2]) flip = -1 for i in range(1, N): make_cut_list.append([ i * (p.cap_width) + (2 * i - 1) * (p.cap_gap / 2), flip * (p.finger_length) / 2 ]) make_cut_list.append([ (i + 1) * (p.cap_width) + (2 * i + 1) * (p.cap_gap / 2), flip * (p.finger_length) / 2 ]) flip = flip * -1 cap_cut = draw.LineString(make_cut_list).buffer(p.cap_gap / 2, cap_style=2, join_style=2) cap_cut = draw.translate(cap_cut, -(N * p.cap_width + (N - 1) * p.cap_gap) / 2, 0) cap_body = draw.subtract(cap_box, cap_cut) cap_body = draw.translate( cap_body, 0, -p.cap_distance - (p.cap_gap + 2 * p.cap_width + p.finger_length) / 2) cap_etch = draw.rectangle( N * p.cap_width + (N - 1) * p.cap_gap + 2 * p.cap_gap_ground, p.cap_gap + 2 * p.cap_width + p.finger_length + 2 * p.cap_gap_ground, 0, -p.cap_distance - (p.cap_gap + 2 * p.cap_width + p.finger_length) / 2) #CPW north_cpw = draw.LineString([[0, 0], [0, -p.cap_distance]]) south_cpw = draw.LineString( [[ 0, -p.cap_distance - (p.cap_gap + 2 * p.cap_width + p.finger_length) ], [ 0, -2 * p.cap_distance - (p.cap_gap + 2 * p.cap_width + p.finger_length) ]]) #Rotate and Translate c_items = [north_cpw, south_cpw, cap_body, cap_etch] c_items = draw.rotate(c_items, p.orientation, origin=(0, 0)) c_items = draw.translate(c_items, p.pos_x, p.pos_y) [north_cpw, south_cpw, cap_body, cap_etch] = c_items #Add to qgeometry tables self.add_qgeometry('path', {'north_cpw': north_cpw}, width=p.north_width, layer=p.layer) self.add_qgeometry('path', {'north_cpw_sub': north_cpw}, width=p.north_width + 2 * p.north_gap, layer=p.layer, subtract=True) self.add_qgeometry('path', {'south_cpw': south_cpw}, width=p.south_width, layer=p.layer) self.add_qgeometry('path', {'south_cpw_sub': south_cpw}, width=p.south_width + 2 * p.south_gap, layer=p.layer, subtract=True) self.add_qgeometry('poly', {'cap_body': cap_body}, layer=p.layer) self.add_qgeometry('poly', {'cap_etch': cap_etch}, layer=p.layer, subtract=True) #Add pins north_pin_list = north_cpw.coords south_pin_list = south_cpw.coords self.add_pin('north_end', points=np.array(north_pin_list[::-1]), width=p.north_width, input_as_norm=True) self.add_pin('south_end', points=np.array(south_pin_list), width=p.south_width, input_as_norm=True)
def make(self): """Convert self.options into QGeometry.""" p = self.parse_options() # Parse the string options into numbers # draw the concentric pad regions outer_pad = draw.Point(0, 0).buffer(p.rad_o) space = draw.Point(0, 0).buffer((p.gap + p.rad_i)) outer_pad = draw.subtract(outer_pad, space) inner_pad = draw.Point(0, 0).buffer(p.rad_i) #gap = draw.subtract(space, inner_pad) #pads = draw.union(outer_pad, inner_pad) # draw the top Josephson Junction jj_t = draw.LineString([(0.0, p.rad_i), (0.0, p.rad_i + p.gap)]) # draw the bottom Josephson Junction jj_b = draw.LineString([(0.0, -1.0 * p.rad_i), (0.0, -1.0 * p.rad_i - 1.0 * p.gap)]) # draw the readout resonator qp1a = (-0.5 * p.pocket_w, p.rad_o + p.res_s ) # the first (x,y) coordinate is qpin #1 qp1b = (p.res_ext, p.rad_o + p.res_s ) # the second (x,y) coordinate is qpin #1 rr = draw.LineString([qp1a, qp1b]) # draw the flux bias line a = (0.5 * p.pocket_w, -0.5 * p.fbl_gap) b = (0.5 * p.pocket_w - p.fbl_ext, -0.5 * p.fbl_gap) c = (p.rad_o + p.fbl_sp + p.fbl_rad, -1.0 * p.fbl_rad) d = (p.rad_o + p.fbl_sp + 0.2929 * p.fbl_rad, 0.0 - 0.7071 * p.fbl_rad) e = (p.rad_o + p.fbl_sp, 0.0) f = (p.rad_o + p.fbl_sp + 0.2929 * p.fbl_rad, 0.0 + 0.7071 * p.fbl_rad) g = (p.rad_o + p.fbl_sp + p.fbl_rad, p.fbl_rad) h = (0.5 * p.pocket_w - p.fbl_ext, 0.5 * p.fbl_gap) i = (0.5 * p.pocket_w, 0.5 * p.fbl_gap) fbl = draw.LineString([a, b, c, d, e, f, g, h, i]) # draw the transmon pocket bounding box pocket = draw.rectangle(p.pocket_w, p.pocket_h) # Translate and rotate all shapes objects = [outer_pad, inner_pad, jj_t, jj_b, pocket, rr, fbl] objects = draw.rotate(objects, p.orientation, origin=(0, 0)) objects = draw.translate(objects, xoff=p.pos_x, yoff=p.pos_y) [outer_pad, inner_pad, jj_t, jj_b, pocket, rr, fbl] = objects # define a function that both rotates and translates the qpin coordinates def qpin_rotate_translate(x): y = list(x) z = [0.0, 0.0] z[0] = y[0] * cos(p.orientation * 3.14159 / 180) - y[1] * sin( p.orientation * 3.14159 / 180) z[1] = y[0] * sin(p.orientation * 3.14159 / 180) + y[1] * cos( p.orientation * 3.14159 / 180) z[0] = z[0] + p.pos_x z[1] = z[1] + p.pos_y x = (z[0], z[1]) return x # rotate and translate the qpin coordinates qp1a = qpin_rotate_translate(qp1a) qp1b = qpin_rotate_translate(qp1b) a = qpin_rotate_translate(a) b = qpin_rotate_translate(b) h = qpin_rotate_translate(h) i = qpin_rotate_translate(i) ############################################################## # Use the geometry to create Metal QGeometry geom_rr = {'path1': rr} geom_fbl = {'path2': fbl} geom_outer = {'poly1': outer_pad} geom_inner = {'poly2': inner_pad} geom_jjt = {'poly4': jj_t} geom_jjb = {'poly5': jj_b} geom_pocket = {'poly6': pocket} self.add_qgeometry('path', geom_rr, layer=1, subtract=False, width=p.cpw_width) self.add_qgeometry('path', geom_fbl, layer=1, subtract=False, width=p.cpw_width) self.add_qgeometry('poly', geom_outer, layer=1, subtract=False) self.add_qgeometry('poly', geom_inner, layer=1, subtract=False) self.add_qgeometry('junction', geom_jjt, layer=1, subtract=False, width=p.inductor_width) self.add_qgeometry('junction', geom_jjb, layer=1, subtract=False, width=p.inductor_width) self.add_qgeometry('poly', geom_pocket, layer=1, subtract=True) ########################################################################### # Add Qpin connections self.add_pin('pin1', points=np.array([qp1b, qp1a]), width=0.01, input_as_norm=True) self.add_pin('pin2', points=np.array([b, a]), width=0.01, input_as_norm=True) self.add_pin('pin3', points=np.array([h, i]), width=0.01, input_as_norm=True)