Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    def test_qgeometry_q_element_delete_component_id(self):
        """Test delete_component_id in QGeometryTables class in
        element_handler.py."""
        design = designs.DesignPlanar()
        qgt = QGeometryTables(design)
        qgt.clear_all_tables()

        transmon_pocket = TransmonPocket(design, 'my_id')
        transmon_pocket.make()
        transmon_pocket.get_template_options(design)
        a_linestring = draw.LineString([[0, 0], [0, 1]])
        a_poly = draw.rectangle(2, 2, 0, 0)
        qgt.add_qgeometry('path',
                          'my_id', {'n_sprial': a_linestring},
                          width=4000)
        qgt.add_qgeometry('poly',
                          'my_id', {'n_spira_etch': a_poly},
                          subtract=True)

        self.assertEqual(len(qgt.tables['path']), 1)
        self.assertEqual(len(qgt.tables['poly']), 1)

        qgt.delete_component_id('my_id')

        self.assertEqual(len(qgt.tables['path']), 0)
        self.assertEqual(len(qgt.tables['poly']), 0)
Exemplo n.º 4
0
    def test_qgeometry_q_element_get_component(self):
        """Test get_component in QGeometryTables class in
        element_handler.py."""
        design = designs.DesignPlanar()
        qgt = QGeometryTables(design)
        qgt.clear_all_tables()
        TransmonPocket(design, 'Q1')

        rect = draw.rectangle(500, 300, 0, 0)
        geom = {'my_polygon': rect}
        qgt.add_qgeometry('poly', 'Q1', geom)

        # success results
        actual = qgt.get_component('Q1')
        self.assertEqual(len(actual), 3)
        self.assertTrue(isinstance(actual['path'], GeoDataFrame))
        self.assertTrue(isinstance(actual['poly'], GeoDataFrame))
        self.assertTrue(isinstance(actual['junction'], GeoDataFrame))

        # failure results
        actual = qgt.get_component('not-real')
        self.assertEqual(len(actual), 3)
        self.assertEqual(actual['path'], None)
        self.assertEqual(actual['poly'], None)
        self.assertEqual(actual['junction'], None)
Exemplo n.º 5
0
 def make(self):
     """calculates the geometries of the QComponent"""
     rect = draw.rectangle(0.5, 0.1, 0, 0)  #width, height, pos_x, pos_y
     # add_geometry() expects shapely, thus the use of drawn module above
     self.add_qgeometry('poly', {'my_polygon': rect},
                        layer=1,
                        subtract=False)
     self.add_pin('in', rect.exterior.coords[:-3:-1],
                  0.1)  #name, tangent, width
Exemplo n.º 6
0
    def make(self):
        """calculates the geometries of the QComponent"""
        p = self.parse_options()  # short-handle alias. Options interpreter

        rect = draw.rectangle(p.width, p.height, p.pos_x, p.pos_y)
        self.add_qgeometry('poly', {'my_polygon': rect},
                           layer=p.layer,
                           subtract=False)
        self.add_pin('in', rect.exterior.coords[:-3:-1], p.height)
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    def test_qgeometry_q_element_clear_all_tables(self):
        """Test clear_all_tables in QGeometryTables class in
        element_handler.py."""
        design = designs.DesignPlanar()
        qgt = QGeometryTables(design)
        qgt.clear_all_tables()

        # add something to the tables to check for after clear
        a_poly = draw.rectangle(2, 2, 0, 0)
        qgt.add_qgeometry('poly', 'my_id', dict(cl_metal=a_poly))

        qgt.clear_all_tables()
        self.assertEqual(len(qgt.tables['poly'].geometry), 0)
Exemplo n.º 10
0
    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(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)
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    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)
Exemplo n.º 14
0
    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)
Exemplo n.º 15
0
    def test_qgeometry_q_element_add_qgeometry(self):
        """Test add_qgeometry in QGeometryTables class in
        element_handler.py."""
        design = designs.DesignPlanar()
        qgt = QGeometryTables(design)
        qgt.clear_all_tables()

        a_poly = draw.rectangle(2, 2, 0, 0)
        qgt.add_qgeometry('poly', 'my_id', dict(cl_metal=a_poly))
        table = qgt.tables

        self.assertTrue('poly' in table)
        self.assertEqual(table['poly']['component'][0], 'my_id')
        self.assertEqual(table['poly']['name'][0], 'cl_metal')
        self.assertEqual(table['poly']['geometry'][0], a_poly)
        self.assertEqual(table['poly']['layer'][0], 1)
        self.assertEqual(table['poly']['subtract'][0], False)
        self.assertEqual(table['poly']['helper'][0], False)
        self.assertEqual(table['poly']['chip'][0], 'main')
        self.assertEqual(str(table['poly']['fillet'][0]), str(np.nan))
Exemplo n.º 16
0
    def test_qgeometry_get_all_unique_layers(self):
        """Test get_all_unique_layers functionality in elment_handler.py."""
        design = designs.DesignPlanar()
        qgt = QGeometryTables(design)
        qgt.clear_all_tables()

        transmon_pocket = TransmonPocket(design, 'my_id')
        transmon_pocket.make()
        transmon_pocket.get_template_options(design)
        a_linestring = draw.LineString([[0, 0], [0, 1]])
        a_poly = draw.rectangle(2, 2, 0, 0)
        qgt.add_qgeometry('path',
                          'my_id', {'n_sprial': a_linestring},
                          width=4000)
        qgt.add_qgeometry('poly',
                          'my_id', {'n_spira_etch': a_poly},
                          subtract=True)

        self.assertEqual(qgt.get_all_unique_layers('main'), [1])
        self.assertEqual(qgt.get_all_unique_layers('fake'), [])
Exemplo n.º 17
0
    def test_renderer_get_chip_names(self):
        """Test functionality of get_chip_names in gds_renderer.py."""
        design = designs.DesignPlanar()
        renderer = QGDSRenderer(design)

        qgt = QGeometryTables(design)
        qgt.clear_all_tables()

        transmon_pocket_1 = TransmonPocket(design, 'my_id')
        transmon_pocket_1.make()
        transmon_pocket_1.get_template_options(design)

        a_linestring = draw.LineString([[0, 0], [0, 1]])
        a_poly = draw.rectangle(2, 2, 0, 0)
        qgt.add_qgeometry('path',
                          'my_id', {'n_sprial': a_linestring},
                          width=4000)
        qgt.add_qgeometry('poly',
                          'my_id', {'n_spira_etch': a_poly},
                          subtract=True)

        result = renderer._get_chip_names()
        self.assertEqual(result, {'main': {}})
Exemplo n.º 18
0
    def make_connection_pad(self, name: str):
        """Makes n individual connector.

        Args:
            name (str) : Name of the connector
        """

        # self.p allows us to directly access parsed values (string -> numbers) form the user option
        p = self.p
        pc = self.p.connection_pads[name]  # parser on connector options

        # define commonly used variables once
        cpw_width = pc.cpw_width
        cpw_extend = pc.cpw_extend
        pad_width = pc.pad_width
        pad_height = pc.pad_height
        pad_cpw_shift = pc.pad_cpw_shift
        pocket_rise = pc.pocket_rise
        pocket_extent = pc.pocket_extent

        loc_W = float(pc.loc_W)
        loc_W, loc_H = float(pc.loc_W), float(pc.loc_H)
        if float(loc_W) not in [-1., +1., 0] or float(loc_H) not in [-1., +1.]:
            self.logger.info(
                'Warning: Did you mean to define a transmon qubit with loc_W and'
                ' loc_H that are not +1, -1, or 0? Are you sure you want to do this?'
            )

        # Define the geometry
        # Connector pad

        if float(loc_W) != 0:
            connector_pad = draw.rectangle(pad_width, pad_height,
                                           -pad_width / 2, pad_height / 2)
            # Connector CPW wire
            connector_wire_path = draw.wkt.loads(f"""LINESTRING (\
                0 {pad_cpw_shift+cpw_width/2}, \
                {pc.pad_cpw_extent}                           {pad_cpw_shift+cpw_width/2}, \
                {(p.pocket_width-p.pad_width)/2-pocket_extent} {pad_cpw_shift+cpw_width/2+pocket_rise}, \
                {(p.pocket_width-p.pad_width)/2+cpw_extend}    {pad_cpw_shift+cpw_width/2+pocket_rise}\
                                            )""")
        else:
            connector_pad = draw.rectangle(pad_width, pad_height, 0,
                                           pad_height / 2)
            connector_wire_path = draw.LineString(
                [[0, pad_height],
                 [
                     0,
                     (p.pocket_width / 2 - p.pad_height - p.pad_gap / 2 -
                      pc.pad_gap) + cpw_extend
                 ]])

        # Position the connector, rotate and translate
        objects = [connector_pad, connector_wire_path]

        if loc_W == 0:
            loc_Woff = 1
        else:
            loc_Woff = loc_W

        objects = draw.scale(objects, loc_Woff, loc_H, origin=(0, 0))
        objects = draw.translate(
            objects,
            loc_W * (p.pad_width) / 2.,
            loc_H * (p.pad_height + p.pad_gap / 2 + pc.pad_gap))
        objects = draw.rotate_position(objects, p.orientation,
                                       [p.pos_x, p.pos_y])
        [connector_pad, connector_wire_path] = objects

        self.add_qgeometry('poly', {f'{name}_connector_pad': connector_pad})
        self.add_qgeometry('path', {f'{name}_wire': connector_wire_path},
                           width=cpw_width)
        self.add_qgeometry('path', {f'{name}_wire_sub': connector_wire_path},
                           width=cpw_width + 2 * pc.cpw_gap,
                           subtract=True)

        ############################################################

        # add pins
        points = np.array(connector_wire_path.coords)
        self.add_pin(name,
                     points=points[-2:],
                     width=cpw_width,
                     input_as_norm=True)
Exemplo n.º 19
0
    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)
Exemplo n.º 20
0
    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)
Exemplo n.º 21
0
    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)
Exemplo n.º 22
0
    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)
Exemplo n.º 23
0
    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_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)
Exemplo n.º 25
0
    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)
Exemplo n.º 26
0
    def make(self):
        """This is executed by the user to generate the qgeometry for the
        component."""
        p = self.p
        #########################################################

        # Make the shapely polygons for the main cap structure
        pad = draw.rectangle(p.trace_width * 5, p.trace_width)
        pad_top = draw.translate(pad, 0,
                                 +(p.trace_width * 2 + p.finger_length) / 2)
        pad_bot = draw.translate(pad, 0,
                                 -(p.trace_width * 2 + p.finger_length) / 2)
        finger = draw.rectangle(p.trace_width, p.finger_length)
        cent_finger = draw.translate(finger, 0, +(p.trace_width) / 2)
        left_finger = draw.translate(finger, -(p.trace_width * 2),
                                     -(p.trace_width) / 2)
        right_finger = draw.translate(finger, +(p.trace_width * 2),
                                      -(p.trace_width) / 2)

        # Make the shapely polygons for the leads in the pocket (length=pocket_buffer_width_y)
        trace_temp_1 = draw.rectangle(p.trace_width, p.pocket_buffer_width_y)
        trace_top = draw.translate(
            trace_temp_1, 0,
            +(p.finger_length + p.trace_width * 3 + p.pocket_buffer_width_y * 2)
            / 2 - p.pocket_buffer_width_y / 2)
        trace_bot = draw.translate(
            trace_temp_1, 0,
            -(p.finger_length + p.trace_width * 3 + p.pocket_buffer_width_y * 2)
            / 2 + p.pocket_buffer_width_y / 2)

        # Make the shapely polygons for pocket ground plane cuttout
        pocket = draw.rectangle(
            p.trace_width * 5 + p.pocket_buffer_width_x * 2,
            p.finger_length + p.trace_width * 3 + p.pocket_buffer_width_y * 2)

        # These variables are used to graphically locate the pin locations
        top_pin_line = draw.LineString([
            (-p.trace_width / 2,
             (p.finger_length + p.trace_width * 3 + p.pocket_buffer_width_y * 2)
             / 2),
            (+p.trace_width / 2,
             (p.finger_length + p.trace_width * 3 + p.pocket_buffer_width_y * 2)
             / 2)
        ])
        bot_pin_line = draw.LineString([(
            -p.trace_width / 2,
            -(p.finger_length + p.trace_width * 3 + p.pocket_buffer_width_y * 2)
            / 2),
                                        (+p.trace_width / 2,
                                         -(p.finger_length + p.trace_width * 3 +
                                           p.pocket_buffer_width_y * 2) / 2)])

        # Create polygon object list
        polys1 = [
            top_pin_line, bot_pin_line, pad_top, pad_bot, cent_finger,
            left_finger, right_finger, pocket, trace_top, trace_bot
        ]

        # 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)
        [
            top_pin_line, bot_pin_line, pad_top, pad_bot, cent_finger,
            left_finger, right_finger, pocket, trace_top, trace_bot
        ] = polys1

        # Adds the object to the qgeometry table
        self.add_qgeometry('poly',
                           dict(pad_top=pad_top,
                                pad_bot=pad_bot,
                                cent_finger=cent_finger,
                                left_finger=left_finger,
                                right_finger=right_finger,
                                trace_top=trace_top,
                                trace_bot=trace_bot),
                           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 its own pins
        self.add_pin('a', top_pin_line.coords, p.trace_width)
        self.add_pin('b', bot_pin_line.coords[::-1], p.trace_width)