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): """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): """ 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_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(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(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_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_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): """Convert self.options into QGeometry.""" p = self.parse_options() # Parse the string options into numbers # draw the lower pad as a rectangle pad_lower = draw.rectangle(p.pad_width, p.pad_height, p.pad_pos_x, p.pad_pos_y) # draw the lower finger as a rectangle finger_lower = draw.rectangle( p.finger_width, p.finger_height, p.pad_pos_x, p.pad_pos_y + 0.49999 * (p.pad_height) + 0.49999 * (p.finger_height)) # draw the Josephson Junction as a LineString rect_jj = draw.LineString([ (0, 0.5 * p.pad_height + p.finger_height), (0, 0.5 * p.pad_height + p.finger_height + p.finger_space) ]) # draw the first comb to the right of the lower finger as a rectangle comb1_lower = draw.rectangle( p.comb_width, (2 * p.finger_height), (0.5 * p.finger_width + p.comb_space_hor + 0.5 * p.comb_width), (p.pad_pos_y + 0.5 * p.pad_height + 1.0 * p.finger_height)) # draw the second comb to the right of the lower finger by translating the first comb comb2_lower = draw.translate(comb1_lower, 2.0 * (p.comb_space_hor + p.comb_width), 0.0) # draw the first comb to the left of the lower finger comb3_lower = draw.rectangle( p.comb_width, (2 * p.finger_height), (-0.5 * p.finger_width - 2.0 * p.comb_space_hor - 1.5 * p.comb_width), (p.pad_pos_y + 0.5 * p.pad_height + 1.0 * p.finger_height)) # draw the second comb to the left of the lower finger comb4_lower = draw.translate(comb3_lower, -2.0 * (p.comb_space_hor + p.comb_width), 0.0) coupling_capacitor = draw.rectangle( p.cc_width, p.cc_height, p.pad_pos_x, p.pad_pos_y - 0.5 * (p.pad_height) - p.cc_space - 0.5 * p.cc_height) cc_topleft = draw.rectangle( p.cc_topleft_width, p.cc_topleft_height, p.pad_pos_x - 0.5 * p.pad_width + 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height) cc_topright = draw.translate( cc_topleft, p.pad_width - 0.5 * p.cc_topleft_width - 0.5 * p.cc_topright_width, 0.0) # merge the bottom elements bottom = draw.union(pad_lower, finger_lower, comb1_lower, comb2_lower, comb3_lower, comb4_lower) # create the top portion of the comb by translating and rotating # the bottom portion of the comb top = draw.translate(bottom, 0.0, p.pad_height + p.finger_space) top = draw.rotate(top, p.rotation_top_pad) # draw the transmon pocket bounding box pocket = draw.rectangle(1.5 * p.pad_width, 5.0 * p.pad_height) # the origin is originally set to the middle of the lower pad. # Let's move it to the center of the JJ. bottom = draw.translate( bottom, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) top = draw.translate( top, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) coupling_capacitor = draw.translate( coupling_capacitor, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) cc_topleft = draw.translate( cc_topleft, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) cc_topright = draw.translate( cc_topright, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) rect_jj = draw.translate( rect_jj, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) # now translate the final structure according to the user input bottom = draw.rotate(bottom, p.orientation, origin=(0, 0)) bottom = draw.translate(bottom, p.pos_x, p.pos_y) top = draw.rotate(top, p.orientation, origin=(0, 0)) top = draw.translate(top, p.pos_x, p.pos_y) coupling_capacitor = draw.rotate(coupling_capacitor, p.orientation, origin=(0, 0)) coupling_capacitor = draw.translate(coupling_capacitor, p.pos_x, p.pos_y) cc_topleft = draw.rotate(cc_topleft, p.orientation, origin=(0, 0)) cc_topleft = draw.translate(cc_topleft, p.pos_x, p.pos_y) cc_topright = draw.rotate(cc_topright, p.orientation, origin=(0, 0)) cc_topright = draw.translate(cc_topright, p.pos_x, p.pos_y) rect_jj = draw.rotate(rect_jj, p.orientation, origin=(0, 0)) rect_jj = draw.translate(rect_jj, p.pos_x, p.pos_y) pocket = draw.rotate(pocket, p.orientation, origin=(0, 0)) pocket = draw.translate(pocket, p.pos_x, p.pos_y) # add each shape separately geom1 = {'pad_bot': bottom} geom2 = {'pad_top': top} geom3 = {'readout': coupling_capacitor} geom4 = {'bus1': cc_topleft} geom5 = {'bus2': cc_topright} geom_pocket = {'pocket': pocket} geom_jj = {'design': rect_jj} # add to qgeometry self.add_qgeometry('poly', geom1, layer=p.layer, subtract=False) self.add_qgeometry('poly', geom2, layer=p.layer, subtract=False) self.add_qgeometry('poly', geom3, layer=p.layer, subtract=False) self.add_qgeometry('poly', geom4, layer=p.layer, subtract=False) self.add_qgeometry('poly', geom5, layer=p.layer, subtract=False) self.add_qgeometry('poly', geom_pocket, layer=p.layer, subtract=True) self.add_qgeometry('junction', geom_jj, layer=p.layer, subtract=False, width=p.inductor_width) ################################################################### # Add Qpin connections for coupling capacitors # define a function that both rotates and translates the # qpin coordinates def qpin_rotate_translate(x): """ This function rotates the coordinates of the three qpins according to the user inputs for "pos_x", "pos_y" and "orientation". """ 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 # Add Qpin connections for the bottom coupling capacitor qp1a = (0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp1b = (0.0, -0.5 * p.pad_height - p.cc_space - p.cc_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) # rotate and translate the qpin coordinates qp1a = qpin_rotate_translate(qp1a) qp1b = qpin_rotate_translate(qp1b) self.add_pin('readout', points=np.array([qp1a, qp1b]), width=0.01, input_as_norm=True) # Add Qpin connections for top left coupling capacitor qp2a = (p.pad_pos_x - 0.5 * p.pad_width + 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp2b = (p.pad_pos_x - 0.5 * p.pad_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp2a = qpin_rotate_translate(qp2a) qp2b = qpin_rotate_translate(qp2b) self.add_pin('bus1', points=np.array([qp2a, qp2b]), width=0.01, input_as_norm=True) # Add Qpin connections for top right coupling capacitor qp3a = (p.pad_pos_x + 0.5 * p.pad_width - 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp3b = (p.pad_pos_x + 0.5 * p.pad_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp3a = qpin_rotate_translate(qp3a) qp3b = qpin_rotate_translate(qp3b) self.add_pin('bus2', points=np.array([qp3a, qp3b]), width=0.01, 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_port_top = draw.rectangle(p.jj_w, p.gap) jj_t = jj_port_top jj_t = draw.translate(jj_t, xoff=0.0, yoff=(p.rad_i + 0.5 * p.gap)) # draw the bottom Josephson Junction jj_port_bottom = draw.rectangle(p.jj_w, p.gap) jj_b = jj_port_bottom jj_b = draw.translate(jj_b, xoff=0.0, yoff=(-(p.rad_i + 0.5 * 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.rotation, origin=(0, 0)) objects = draw.translate(objects, xoff=p.position_x, yoff=p.position_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.rotation * 3.14159 / 180) - y[1] * sin( p.rotation * 3.14159 / 180) z[1] = y[0] * sin(p.rotation * 3.14159 / 180) + y[1] * cos( p.rotation * 3.14159 / 180) z[0] = z[0] + p.position_x z[1] = z[1] + p.position_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('poly', geom_jjt, layer=1, subtract=False) self.add_qgeometry('poly', geom_jjb, layer=1, subtract=False) 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)
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 pad_lower = draw.rectangle(p.pad_width, p.pad_height, p.pad_pos_x, p.pad_pos_y) # draw the lower finger as a rectangle finger_lower = draw.rectangle( p.finger_width, p.finger_height, p.pad_pos_x, p.pad_pos_y + 0.49999 * (p.pad_height) + 0.49999 * (p.finger_height)) # draw the Josephson Junction rect_jj = draw.rectangle( p.jj_width, p.finger_space, p.pad_pos_x, 0.5 * (p.pad_height) + p.finger_height + 0.5 * (p.finger_space)) # draw the first comb to the right of the lower finger as a rectangle comb1_lower = draw.rectangle( p.comb_width, (2 * p.finger_height + p.finger_space - p.comb_space_vert), (0.5 * p.finger_width + p.comb_space_hor + 0.5 * p.comb_width), (0.5 * p.pad_height + 0.5 * (p.pad_pos_y + 0.5 * (p.pad_height) + 0.5 * (p.finger_height)))) # draw the second comb to the right of the lower finger by translating the first comb comb2_lower = draw.translate(comb1_lower, 2.0 * (p.comb_space_hor + p.comb_width), 0.0) # draw the first comb to the left of the lower finger comb3_lower = draw.rectangle( p.comb_width, (2 * p.finger_height + p.finger_space - p.comb_space_vert), (-0.5 * p.finger_width - 2.0 * p.comb_space_hor - 1.5 * p.comb_width), (0.5 * p.pad_height + 0.5 * (p.pad_pos_y + 0.5 * (p.pad_height) + 0.5 * (p.finger_height)))) # draw the second comb to the left of the lower finger comb4_lower = draw.translate(comb3_lower, -2.0 * (p.comb_space_hor + p.comb_width), 0.0) coupling_capacitor = draw.rectangle( p.cc_width, p.cc_height, p.pad_pos_x, p.pad_pos_y - 0.5 * (p.pad_height) - p.cc_space - 0.5 * p.cc_height) cc_topleft = draw.rectangle( p.cc_topleft_width, p.cc_topleft_height, p.pad_pos_x - 0.5 * p.pad_width + 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height) cc_topright = draw.translate( cc_topleft, p.pad_width - 0.5 * p.cc_topleft_width - 0.5 * p.cc_topright_width, 0.0) # merge the bottom elements bottom = draw.union(pad_lower, finger_lower, comb1_lower, comb2_lower, comb3_lower, comb4_lower) # create the top portion of the comb by translating and rotating # the bottom portion of the comb top = draw.translate(bottom, 0.0, p.pad_height + p.finger_space) top = draw.rotate(top, p.rotation_top_pad) # merge everything into a single design design = draw.union(bottom, top, rect_jj, coupling_capacitor, cc_topleft, cc_topright) # draw the transmon pocket bounding box pocket = draw.rectangle(1.5 * p.pad_width, 5.0 * p.pad_height) # the origin is originally set to the middle of the lower pad. # Let's move it to the center of the JJ. design = draw.translate( design, 0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) # now translate the final structure according to the user input design = draw.rotate(design, p.rotation, origin=(0, 0)) design = draw.translate(design, p.position_x, p.position_y) pocket = draw.rotate(pocket, p.rotation, origin=(0, 0)) pocket = draw.translate(pocket, p.position_x, p.position_y) geom = {'design': design} geom_pocket = {'pocket': pocket} self.add_qgeometry('poly', geom, layer=p.layer, subtract=False) self.add_qgeometry('poly', geom_pocket, layer=p.layer, subtract=True) ################################################################### # Add Qpin connections for coupling capacitors # define a function that both rotates and translates the # qpin coordinates def qpin_rotate_translate(x): """ This function rotates the coordinates of the three qpins according to the user inputs for "position_x", "position_y" and "rotation". """ y = list(x) z = [0.0, 0.0] z[0] = y[0] * cos(p.rotation * 3.14159 / 180) - y[1] * sin( p.rotation * 3.14159 / 180) z[1] = y[0] * sin(p.rotation * 3.14159 / 180) + y[1] * cos( p.rotation * 3.14159 / 180) z[0] = z[0] + p.position_x z[1] = z[1] + p.position_y x = (z[0], z[1]) return x # Add Qpin connections for the bottom coupling capacitor qp1a = (0.0, -0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp1b = (0.0, -0.5 * p.pad_height - p.cc_space - p.cc_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) # rotate and translate the qpin coordinates qp1a = qpin_rotate_translate(qp1a) qp1b = qpin_rotate_translate(qp1b) self.add_pin('pin1', points=np.array([qp1a, qp1b]), width=0.01, input_as_norm=True) # Add Qpin connections for top left coupling capacitor qp2a = (p.pad_pos_x - 0.5 * p.pad_width + 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp2b = (p.pad_pos_x - 0.5 * p.pad_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp2a = qpin_rotate_translate(qp2a) qp2b = qpin_rotate_translate(qp2b) self.add_pin('pin2', points=np.array([qp2a, qp2b]), width=0.01, input_as_norm=True) # Add Qpin connections for top right coupling capacitor qp3a = (p.pad_pos_x + 0.5 * p.pad_width - 0.5 * p.cc_topleft_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp3b = (p.pad_pos_x + 0.5 * p.pad_width, p.pad_pos_y + 1.5 * p.pad_height + 2.0 * p.finger_height + p.finger_space + p.cc_topleft_space + 0.5 * p.cc_topleft_height - 0.5 * p.pad_height - p.finger_height - 0.5 * p.finger_space) qp3a = qpin_rotate_translate(qp3a) qp3b = qpin_rotate_translate(qp3b) self.add_pin('pin3', points=np.array([qp3a, qp3b]), width=0.01, input_as_norm=True)