def make(self):
        """The make function implements the logic that creates the geoemtry
        (poly, path, etc.) from the qcomponent.options dictionary of
        parameters, and the adds them to the design, using
        qcomponent.add_qgeometry(...), adding in extra needed information, such
        as layer, subtract, etc."""
        p = self.p  # p for parsed parameters. Access to the parsed options.
        n = int(p.n)
        # Create the geometry

        spiral_list = []

        #Formulat to determine the size of the spiral based on inputed length.
        x_n = (p.length / (2 * n)) - (p.height + 2 * (p.gap + p.line_width) *
                                      (2 * n - 1))

        if x_n <= p.gap + p.line_width:
            self._error_message = f'Inputted values results in the width of the spiral being too small.'
            self.logger.warning(self._error_message)
            return

        for step in range(n):
            x_point = x_n / 2 + step * (p.line_width + p.gap)
            y_point = p.height / 2 + step * (p.line_width + p.gap)

            spiral_list.append((-x_point, -y_point))
            spiral_list.append((x_point, -y_point))
            spiral_list.append((x_point, y_point))
            spiral_list.append((-x_point - (p.line_width + p.gap), y_point))

        x_point = (x_n / 2 + (step + 1) * (p.line_width + p.gap))
        y_point = (p.height / 2 + (step + 1) * (p.line_width + p.gap) -
                   p.line_width / 2)
        spiral_list.append((-x_point, -y_point))
        spiral_list = draw.LineString(spiral_list)

        spiral_etch = draw.shapely.geometry.box(
            -(x_point + p.line_width / 2 + p.gap), -y_point,
            x_point - p.line_width / 2, y_point)
        #Generates a linestring to track port location
        points = draw.LineString([
            (-x_point + p.line_width / 2, -y_point + p.coupler_distance),
            (-x_point - p.line_width / 2, -y_point + p.coupler_distance)
        ])

        c_items = [spiral_list, spiral_etch, points]
        c_items = draw.rotate(c_items, p.orientation, origin=(0, 0))
        c_items = draw.translate(c_items, p.pos_x, p.pos_y)
        [spiral_list, spiral_etch, points] = c_items
        ##############################################
        # add elements
        self.add_qgeometry('path', {'n_spiral': spiral_list},
                           width=p.line_width)
        self.add_qgeometry('poly', {'n_spira_etch': spiral_etch}, subtract=True)

        # NEW PIN SPOT
        self.add_pin('spiralPin',
                     points=np.array(points.coords),
                     width=p.line_width,
                     input_as_norm=True)
Beispiel #2
0
    def make(self):
        """Build the component."""
        p = self.p
        prime_cpw_length = p.t_length * 2

        #Primary CPW
        prime_cpw = draw.LineString([[-prime_cpw_length / 2, 0],
                                     [prime_cpw_length / 2, 0]])

        #Secondary CPW
        second_cpw = draw.LineString([[0, -p.prime_width / 2],
                                      [0, -p.t_length]])

        #Rotate and Translate
        c_items = [prime_cpw, second_cpw]
        c_items = draw.rotate(c_items, p.orientation, origin=(0, 0))
        c_items = draw.translate(c_items, p.pos_x, p.pos_y)
        [prime_cpw, second_cpw] = c_items

        #Add to qgeometry tables
        self.add_qgeometry('path', {'prime_cpw': prime_cpw},
                           width=p.prime_width,
                           layer=p.layer)
        self.add_qgeometry('path', {'prime_cpw_sub': prime_cpw},
                           width=p.prime_width + 2 * p.prime_gap,
                           subtract=True,
                           layer=p.layer)
        self.add_qgeometry('path', {'second_cpw': second_cpw},
                           width=p.second_width,
                           layer=p.layer)
        self.add_qgeometry('path', {'second_cpw_sub': second_cpw},
                           width=p.second_width + 2 * p.second_gap,
                           subtract=True,
                           layer=p.layer)

        #Add pins
        prime_pin_list = prime_cpw.coords
        second_pin_list = second_cpw.coords

        self.add_pin('prime_start',
                     points=np.array(prime_pin_list[::-1]),
                     width=p.prime_width,
                     input_as_norm=True)
        self.add_pin('prime_end',
                     points=np.array(prime_pin_list),
                     width=p.prime_width,
                     input_as_norm=True)
        self.add_pin('second_end',
                     points=np.array(second_pin_list),
                     width=p.second_width,
                     input_as_norm=True)
Beispiel #3
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)
Beispiel #4
0
    def make_elements(self, pts: np.ndarray):
        """Turns the CPW points into design elements, and add them to the design object.

        Arguments:
            pts (np.ndarray): Array of points
        """

        # prepare the routing track
        line = draw.LineString(pts)

        # compute actual final length
        p = self.p
        self.options._actual_length = str(
            line.length - self.length_excess_corner_rounding(line.coords)
        ) + ' ' + self.design.get_units()

        # expand the routing track to form the substrate core of the cpw
        self.add_qgeometry('path', {'trace': line},
                           width=p.trace_width,
                           fillet=p.fillet,
                           layer=p.layer)
        if self.type == "CPW":
            # expand the routing track to form the two gaps in the substrate
            # final gap will be form by this minus the trace above
            self.add_qgeometry('path', {'cut': line},
                               width=p.trace_width + 2 * p.trace_gap,
                               fillet=p.fillet,
                               layer=p.layer,
                               subtract=True)
    def generate_spiral_list(x: int, y: int):
        """Helper function to generate a sprital list.

        Args:
            x (int): x-coordinate
            y (int): y-coordinate

        Returns:
            list: A list of points
        """
        spiral_list = []

        for step in range(3):
            point_value = 20 + step * 5
            spiral_list.append((-point_value, -point_value))
            spiral_list.append((point_value, -point_value))
            spiral_list.append((point_value, point_value))
            spiral_list.append((-point_value - (1 + 4), point_value))

        point_value = 20 + (step + 1) * 5
        spiral_list.append((-point_value, -point_value))
        spiral_list = draw.LineString(spiral_list)

        spiral_list = draw.rotate(spiral_list, 0, origin=(x, y))
        spiral_list = draw.translate(spiral_list, x, y)

        return spiral_list
    def 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)
    def make_flux_line(self):
        """Creates the charge line if the user has charge line option to TRUE
        """

        # Grab option values
        pf = self.p.fl_options
        p = self.p
        #Make the T flux line
        h_line = draw.LineString([(-pf.t_top / 2, 0), (pf.t_top / 2, 0)])
        v_line = draw.LineString([(pf.t_offset, 0), (pf.t_offset, -0.03)])

        parts = [h_line, v_line]

        # Move the flux line down to the SQUID
        parts = draw.translate(
            parts, 0, -(p.cross_length + p.cross_gap + pf.t_inductive_gap +
                        pf.t_width / 2 + pf.t_gap))

        # Rotate and translate based on crossmon location
        parts = draw.rotate(parts, p.orientation, origin=(0, 0))
        parts = draw.translate(parts, p.pos_x, p.pos_y)

        [h_line, v_line] = parts

        # Adding to qgeometry table
        self.add_qgeometry('path', {
            'h_line': h_line,
            'v_line': v_line
        },
                           width=pf.t_width,
                           layer=p.layer)

        self.add_qgeometry('path', {
            'h_line_sub': h_line,
            'v_line_sub': v_line
        },
                           width=pf.t_width + 2 * pf.t_gap,
                           subtract=True,
                           layer=p.layer)

        # Generating pin
        pin_line = v_line.coords
        self.add_pin("flux_line",
                     points=pin_line,
                     width=pf.t_width,
                     gap=pf.t_gap,
                     input_as_norm=True)
    def make_pocket(self):
        """Makes a basic Crossmon, 4 arm cross."""

        # self.p allows us to directly access parsed values (string -> numbers) form the user option
        p = self.p

        cross_width = p.cross_width
        cross_length = p.cross_length
        cross_gap = p.cross_gap

        # access to chip name
        chip = p.chip

        # Creates the cross and the etch equivalent.
        cross_line = draw.shapely.ops.unary_union([
            draw.LineString([(0, cross_length), (0, -cross_length)]),
            draw.LineString([(cross_length, 0), (-cross_length, 0)])
        ])

        cross = cross_line.buffer(cross_width / 2, cap_style=2)
        cross_etch = cross.buffer(cross_gap, cap_style=3, join_style=2)

        # The junction/SQUID
        #rect_jj = draw.rectangle(cross_width, cross_gap)
        #rect_jj = draw.translate(rect_jj, 0, -cross_length-cross_gap/2)
        rect_jj = draw.LineString([(0, -cross_length),
                                   (0, -cross_length - cross_gap)])

        #rotate and translate
        polys = [cross, cross_etch, rect_jj]
        polys = draw.rotate(polys, p.orientation, origin=(0, 0))
        polys = draw.translate(polys, p.pos_x, p.pos_y)

        [cross, cross_etch, rect_jj] = polys

        # generate qgeometry
        self.add_qgeometry('poly', dict(cross=cross), chip=chip)
        self.add_qgeometry('poly',
                           dict(cross_etch=cross_etch),
                           subtract=True,
                           chip=chip)
        self.add_qgeometry('junction',
                           dict(rect_jj=rect_jj),
                           width=cross_width,
                           chip=chip)
    def make(self):
        """calculates the geometries of the QComponent"""
        p = self.parse_options()

        line = draw.LineString([(-p.width / 2, 0), (p.width / 2, 0)])
        line = draw.translate(line, p.pos_x, p.pos_y)
        self.add_qgeometry('path', {'trace': line},
                           width=p.height,
                           layer=p.layer,
                           subtract=False)
        line2 = draw.LineString([((-p.width / 2) - 2 * p.gap, 0),
                                 ((p.width / 2) + 2 * p.gap, 0)])
        line2 = draw.translate(line2, p.pos_x, p.pos_y)
        self.add_qgeometry('path', {'cut': line2},
                           width=p.height + 2 * p.gap,
                           layer=p.layer,
                           subtract=True)
        self.add_pin('in', line.coords[::-1], p.height, input_as_norm=True)
Beispiel #10
0
    def make_pin_coordinates(self):
        """This function creates the coordinates for the pins
        """
        p = self.p
        p_in = (0, p.radius)
        p_out = (0, 1.25 * (p.radius))
        pins = draw.LineString([p_in, p_out])

        return pins
Beispiel #11
0
    def make(self):
        """This is executed by the user to generate the qgeometry for the
        component."""

        p = self.p
        trace_width = p.trace_width
        trace_width_half = trace_width / 2
        lead_length = p.lead_length
        trace_gap = p.trace_gap
        #########################################################

        # Geometry of main launch structure
        launch_pad = draw.Polygon([(0, trace_width_half),
                                   (-.122, trace_width_half + .035),
                                   (-.202, trace_width_half + .035),
                                   (-.202, -trace_width_half - .035),
                                   (-.122, -trace_width_half - .035),
                                   (0, -trace_width_half),
                                   (lead_length, -trace_width_half),
                                   (lead_length, +trace_width_half),
                                   (0, trace_width_half)])

        # Geometry pocket (gap)
        pocket = draw.Polygon([(0, trace_width_half + trace_gap),
                               (-.122, trace_width_half + trace_gap + .087),
                               (-.25, trace_width_half + trace_gap + .087),
                               (-.25, -trace_width_half - trace_gap - .087),
                               (-.122, -trace_width_half - trace_gap - .087),
                               (0, -trace_width_half - trace_gap),
                               (lead_length, -trace_width_half - trace_gap),
                               (lead_length, +trace_width_half + trace_gap),
                               (0, trace_width_half + trace_gap)])

        # These variables are used to graphically locate the pin locations
        main_pin_line = draw.LineString([(lead_length, trace_width_half),
                                         (lead_length, -trace_width_half)])

        # Create polygon object list
        polys1 = [main_pin_line, launch_pad, pocket]

        # Rotates and translates all the objects as requested. Uses package functions in
        # 'draw_utility' for easy rotation/translation
        polys1 = draw.rotate(polys1, p.orientation, origin=(0, 0))
        polys1 = draw.translate(polys1, xoff=p.pos_x, yoff=p.pos_y)
        [main_pin_line, launch_pad, pocket] = polys1

        # Adds the object to the qgeometry table
        self.add_qgeometry('poly', dict(launch_pad=launch_pad), layer=p.layer)

        # Subtracts out ground plane on the layer its on
        self.add_qgeometry('poly',
                           dict(pocket=pocket),
                           subtract=True,
                           layer=p.layer)

        # Generates the pins
        self.add_pin('tie', main_pin_line.coords, trace_width)
Beispiel #12
0
    def make_charge_line(self):
        """Creates the charge line if the user has charge line option to TRUE.
        """

        # Grab option values
        name = 'Charge_Line'

        p = self.p

        cl_arm = draw.box(0, 0, -p.cl_width, p.cl_length)
        cl_cpw = draw.box(0, 0, -8 * p.cl_width, p.cl_width)
        cl_metal = draw.cascaded_union([cl_arm, cl_cpw])

        cl_etcher = draw.buffer(cl_metal, p.cl_gap)

        port_line = draw.LineString([(-8 * p.cl_width, 0),
                                     (-8 * p.cl_width, p.cl_width)])

        polys = [cl_metal, cl_etcher, port_line]

        # Move the charge line to the side user requested
        cl_rotate = 0
        if (abs(p.cl_pocket_edge) > 135) or (abs(p.cl_pocket_edge) < 45):
            polys = draw.translate(
                polys, -(p.pocket_width / 2 + p.cl_ground_gap + p.cl_gap),
                p.cl_off_center)
            if (abs(p.cl_pocket_edge) > 135):
                cl_rotate = 180
        else:
            polys = draw.translate(
                polys, -(p.pocket_height / 2 + p.cl_ground_gap + p.cl_gap),
                p.cl_off_center)
            cl_rotate = 90
            if (p.cl_pocket_edge < 0):
                cl_rotate = -90

        # Rotate it to the pockets orientation
        polys = draw.rotate(polys, p.orientation + cl_rotate, origin=(0, 0))

        # Move to the final position
        polys = draw.translate(polys, p.pos_x, p.pos_y)

        [cl_metal, cl_etcher, port_line] = polys

        # Generating pins
        points = list(draw.shapely.geometry.shape(port_line).coords)
        self.add_pin(name, points, p.cl_width)

        # Adding to qgeometry table
        self.add_qgeometry('poly', dict(cl_metal=cl_metal))
        self.add_qgeometry('poly', dict(cl_etcher=cl_etcher), subtract=True)
Beispiel #13
0
    def make(self):
        """Build the component."""
        p = self.p  # p for parsed parameters. Access to the parsed options.

        port_line = draw.LineString([(0, -p.width / 2), (0, p.width / 2)])

        # Rotates and translates the connector polygons (and temporary port_line)
        port_line = draw.rotate(port_line, p.orientation, origin=(0, 0))
        port_line = draw.translate(port_line, p.pos_x, p.pos_y)

        port_points = list(draw.shapely.geometry.shape(port_line).coords)

        #Generates the pin
        self.add_pin('short', port_points, p.width)
Beispiel #14
0
    def make(self):
        """
        The make function implements the logic that creates the geoemtry
        (poly, path, etc.) from the qcomponent.options dictionary of parameters,
        and the adds them to the design, using qcomponent.add_qgeometry(...),
        adding in extra needed information, such as layer, subtract, etc.
        """
        p = self.p  # p for parsed parameters. Access to the parsed options.
        n = int(p.n)
        # Create the geometry

        spiral_list = []

        for step in range(n):
            point_value = p.radius / 2 + step * (p.width + p.gap)
            spiral_list.append((-point_value, -point_value))
            spiral_list.append((point_value, -point_value))
            spiral_list.append((point_value, point_value))
            spiral_list.append((-point_value - (p.width + p.gap), point_value))

        point_value = p.radius / 2 + (step + 1) * (p.width + p.gap)
        spiral_list.append((-point_value, -point_value))
        spiral_list = draw.LineString(spiral_list)

        spiral_list = draw.rotate(spiral_list, p.rotation, origin=(0, 0))
        spiral_list = draw.translate(spiral_list, p.pos_x, p.pos_y)

        ##############################################
        # add qgeometry
        self.add_qgeometry('path', {'n_spiral': spiral_list},
                           width=p.width,
                           subtract=p.subtract,
                           helper=p.helper,
                           layer=p.layer,
                           chip=p.chip)

        points = np.array(spiral_list.coords)
        # FIX POINTS,
        self.add_pin('spiralPin',
                     points=points[-2:],
                     width=p.width,
                     input_as_norm=True)
    def make(self):
        """Build the component."""
        p = self.p  # p for parsed parameters. Access to the parsed options.

        port_line = draw.LineString([(0, -p.width / 2), (0, p.width / 2)])
        open_termination = draw.box(0, -(p.width / 2 + p.gap),
                                    p.termination_gap, (p.width / 2 + p.gap))
        # Rotates and translates the connector polygons (and temporary port_line)
        polys = [open_termination, port_line]
        polys = draw.rotate(polys, p.orientation, origin=(0, 0))
        polys = draw.translate(polys, p.pos_x, p.pos_y)
        [open_termination, port_line] = polys

        # Subtracts out ground plane on the layer its on
        self.add_qgeometry('poly', {'open_to_ground': open_termination},
                           subtract=True,
                           layer=p.layer)

        # Generates the pins
        self.add_pin('open', port_line.coords, p.width)
    def 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'), [])
Beispiel #17
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)
Beispiel #18
0
    def arc(self, coord_init, coord_center, angle):
        '''
        Generate x,y coordinates (in terms of shapely.geometry.Point()) of an arc with:
        a specified initial point, rotation center, and
        rotation direction (specified by angle in radian (float or integer), positive is ccw).

        coord_init, and coord_center should be shapely.geometry.Point object
        '''
        # access to parse values from the user option
        p = self.p

        # local variable
        r = p.readout_cpw_turnradius
        step = p.arc_step

        # determine step number
        step_angle = step / r if angle >= 0 else -step / r
        step_N = abs(int(angle / step_angle))
        #laststep_flag = True if angle % step_angle != 0 else False
        laststep_flag = bool(angle % step_angle != 0)

        # generate coordinate
        coord = [coord_init]
        point = coord_init
        for i in range(step_N):
            point = draw.rotate(point,
                                step_angle,
                                origin=coord_center,
                                use_radians=True)
            coord.append(point)
        if laststep_flag:
            point = draw.rotate(coord_init,
                                angle,
                                origin=coord_center,
                                use_radians=True)
            coord.append(point)
        coord = draw.LineString(coord)
        return coord
Beispiel #19
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': {}})
Beispiel #20
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)
    def make(self):
        """Build the component."""
        p = self.p
        N = int(p.finger_count)
        prime_cpw_length = p.cap_width * 2 * N

        #Primary CPW
        prime_cpw = draw.LineString([[-prime_cpw_length / 2, 0],
                                     [prime_cpw_length / 2, 0]])

        #Finger Capacitor
        cap_box = draw.rectangle(N * p.cap_width + (N - 1) * p.cap_gap,
                                 p.cap_gap + 2 * p.cap_width + p.finger_length,
                                 0, 0)
        make_cut_list = []
        make_cut_list.append([0, (p.finger_length) / 2])
        make_cut_list.append([(p.cap_width) + (p.cap_gap / 2),
                              (p.finger_length) / 2])
        flip = -1

        for i in range(1, N):
            make_cut_list.append([
                i * (p.cap_width) + (2 * i - 1) * (p.cap_gap / 2),
                flip * (p.finger_length) / 2
            ])
            make_cut_list.append([
                (i + 1) * (p.cap_width) + (2 * i + 1) * (p.cap_gap / 2),
                flip * (p.finger_length) / 2
            ])
            flip = flip * -1

        cap_cut = draw.LineString(make_cut_list).buffer(p.cap_gap / 2,
                                                        cap_style=2,
                                                        join_style=2)
        cap_cut = draw.translate(cap_cut,
                                 -(N * p.cap_width + (N - 1) * p.cap_gap) / 2,
                                 0)

        cap_body = draw.subtract(cap_box, cap_cut)
        cap_body = draw.translate(
            cap_body, 0, -p.cap_distance -
            (p.cap_gap + 2 * p.cap_width + p.finger_length) / 2)

        cap_etch = draw.rectangle(
            N * p.cap_width + (N - 1) * p.cap_gap + 2 * p.second_gap,
            p.cap_gap + 2 * p.cap_width + p.finger_length + 2 * p.second_gap,
            0, -p.cap_distance -
            (p.cap_gap + 2 * p.cap_width + p.finger_length) / 2)

        #Secondary CPW
        second_cpw_top = draw.LineString([[0, -p.prime_width / 2],
                                          [0, -p.cap_distance]])

        second_cpw_bottom = draw.LineString(
            [[
                0, -p.cap_distance -
                (p.cap_gap + 2 * p.cap_width + p.finger_length)
            ],
             [
                 0, -2 * p.cap_distance -
                 (p.cap_gap + 2 * p.cap_width + p.finger_length)
             ]])

        #Rotate and Translate
        c_items = [
            prime_cpw, second_cpw_top, second_cpw_bottom, cap_body, cap_etch
        ]
        c_items = draw.rotate(c_items, p.orientation, origin=(0, 0))
        c_items = draw.translate(c_items, p.pos_x, p.pos_y)
        [prime_cpw, second_cpw_top, second_cpw_bottom, cap_body,
         cap_etch] = c_items

        #Add to qgeometry tables
        self.add_qgeometry('path', {'prime_cpw': prime_cpw},
                           width=p.prime_width,
                           layer=p.layer)
        self.add_qgeometry('path', {'prime_cpw_sub': prime_cpw},
                           width=p.prime_width + 2 * p.prime_gap,
                           subtract=True,
                           layer=p.layer)
        self.add_qgeometry('path', {
            'second_cpw_top': second_cpw_top,
            'second_cpw_bottom': second_cpw_bottom
        },
                           width=p.second_width,
                           layer=p.layer)
        self.add_qgeometry('path', {
            'second_cpw_top_sub': second_cpw_top,
            'second_cpw_bottom_sub': second_cpw_bottom
        },
                           width=p.second_width + 2 * p.second_gap,
                           subtract=True,
                           layer=p.layer)

        self.add_qgeometry('poly', {'cap_body': cap_body}, layer=p.layer)
        self.add_qgeometry('poly', {'cap_etch': cap_etch},
                           layer=p.layer,
                           subtract=True)

        #Add pins
        prime_pin_list = prime_cpw.coords
        second_pin_list = second_cpw_bottom.coords

        self.add_pin('prime_start',
                     points=np.array(prime_pin_list[::-1]),
                     width=p.prime_width,
                     input_as_norm=True)
        self.add_pin('prime_end',
                     points=np.array(prime_pin_list),
                     width=p.prime_width,
                     input_as_norm=True)
        self.add_pin('second_end',
                     points=np.array(second_pin_list),
                     width=p.second_width,
                     input_as_norm=True)
    def make_pocket(self):
        """Makes standard transmon in a pocket."""

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

        # since we will reuse these options, parse them once and define them as variables
        pad_width = p.pad_width
        pad_height = p.pad_height
        pad_gap = p.pad_gap
        coupled_pad_height = p.coupled_pad_height
        coupled_pad_width = p.coupled_pad_width
        coupled_pad_gap = p.coupled_pad_gap

        # make the pads as rectangles (shapely polygons)
        pad = draw.rectangle(pad_width, pad_height)

        pad_top = draw.translate(pad, 0, +(pad_height + pad_gap) / 2.)
        # Here, you make your pads round. Not sharp shape on the left and right sides and also this should be the same for the bottom pad as the top pad.
        circ_left_top = draw.Point(-pad_width / 2., +(pad_height + pad_gap) /
                                   2.).buffer(pad_height / 2,
                                              resolution=16,
                                              cap_style=CAP_STYLE.round)
        circ_right_top = draw.Point(pad_width / 2., +(pad_height + pad_gap) /
                                    2.).buffer(pad_height / 2,
                                               resolution=16,
                                               cap_style=CAP_STYLE.round)
        # In here you create the teeth part and then you union them as one with the pad. Teeth only belong to top pad.
        coupled_pad = draw.rectangle(coupled_pad_width,
                                     coupled_pad_height + pad_height)
        coupler_pad_round = draw.Point(0., (coupled_pad_height + pad_height) /
                                       2).buffer(coupled_pad_width / 2,
                                                 resolution=16,
                                                 cap_style=CAP_STYLE.round)
        coupled_pad = draw.union(coupled_pad, coupler_pad_round)
        coupled_pad_left = draw.translate(
            coupled_pad, -(coupled_pad_width / 2. + coupled_pad_gap / 2.),
            +coupled_pad_height / 2. + pad_height + pad_gap / 2. -
            pad_height / 2)
        coupled_pad_right = draw.translate(
            coupled_pad, (coupled_pad_width / 2. + coupled_pad_gap / 2.),
            +coupled_pad_height / 2. + pad_height + pad_gap / 2. -
            pad_height / 2)
        pad_top_tmp = draw.union([circ_left_top, pad_top, circ_right_top])
        # The coupler pads are only created if low_W=0 and low_H=+1
        for name in self.options.connection_pads:
            if self.options.connection_pads[name][
                    'loc_W'] == 0 and self.options.connection_pads[name][
                        'loc_H'] == +1:
                pad_top_tmp = draw.union([
                    circ_left_top, coupled_pad_left, pad_top, coupled_pad_right,
                    circ_right_top
                ])
        pad_top = pad_top_tmp
        # Round part for the bottom pad. And again you should unite all of them.
        pad_bot = draw.translate(pad, 0, -(pad_height + pad_gap) / 2.)
        circ_left_bot = draw.Point(-pad_width / 2, -(pad_height + pad_gap) /
                                   2.).buffer(pad_height / 2,
                                              resolution=16,
                                              cap_style=CAP_STYLE.round)
        circ_right_bot = draw.Point(pad_width / 2, -(pad_height + pad_gap) /
                                    2.).buffer(pad_height / 2,
                                               resolution=16,
                                               cap_style=CAP_STYLE.round)
        pad_bot = draw.union([pad_bot, circ_left_bot, circ_right_bot])

        rect_jj = draw.LineString([(0, -pad_gap / 2), (0, +pad_gap / 2)])
        # the draw.rectangle representing the josephson junction
        # rect_jj = draw.rectangle(p.inductor_width, pad_gap)

        rect_pk = draw.rectangle(p.pocket_width, p.pocket_height)

        # Rotate and translate all qgeometry as needed.
        # Done with utility functions in Metal 'draw_utility' for easy rotation/translation
        # NOTE: Should modify so rotate/translate accepts qgeometry, would allow for
        # smoother implementation.
        polys = [rect_jj, pad_top, pad_bot, rect_pk]
        polys = draw.rotate(polys, p.orientation, origin=(0, 0))
        polys = draw.translate(polys, p.pos_x, p.pos_y)
        [rect_jj, pad_top, pad_bot, rect_pk] = polys

        # Use the geometry to create Metal qgeometry
        self.add_qgeometry('poly', dict(pad_top=pad_top, pad_bot=pad_bot))
        self.add_qgeometry('poly', dict(rect_pk=rect_pk), subtract=True)
        # self.add_qgeometry('poly', dict(
        #     rect_jj=rect_jj), helper=True)
        self.add_qgeometry('junction',
                           dict(rect_jj=rect_jj),
                           width=p.inductor_width)
    def make(self):
        """This is executed by the user to generate the qgeometry for the
        component."""

        p = self.p

        pad_width = p.pad_width
        pad_height = p.pad_height
        pad_gap = p.pad_gap
        trace_width = p.trace_width
        trace_width_half = trace_width / 2.
        pad_width_half = pad_width / 2.
        lead_length = p.lead_length
        taper_height = p.taper_height
        trace_gap = p.trace_gap

        pad_gap = p.pad_gap
        #########################################################

        # Geometry of main launch structure
        # The shape is a polygon and we prepare this point as orientation is 0 degree
        launch_pad = draw.Polygon([
            (0, trace_width_half), (-taper_height, pad_width_half),
            (-(pad_height + taper_height), pad_width_half),
            (-(pad_height + taper_height), -pad_width_half),
            (-taper_height, -pad_width_half), (0, -trace_width_half),
            (lead_length, -trace_width_half), (lead_length, trace_width_half),
            (0, trace_width_half)
        ])

        # Geometry pocket (gap)
        # Same way applied for pocket
        pocket = draw.Polygon([(0, trace_width_half + trace_gap),
                               (-taper_height, pad_width_half + pad_gap),
                               (-(pad_height + taper_height + pad_gap),
                                pad_width_half + pad_gap),
                               (-(pad_height + taper_height + pad_gap),
                                -(pad_width_half + pad_gap)),
                               (-taper_height, -(pad_width_half + pad_gap)),
                               (0, -(trace_width_half + trace_gap)),
                               (lead_length, -(trace_width_half + trace_gap)),
                               (lead_length, trace_width_half + trace_gap),
                               (0, trace_width_half + trace_gap)])

        # These variables are used to graphically locate the pin locations
        main_pin_line = draw.LineString([(lead_length, trace_width_half),
                                         (lead_length, -trace_width_half)])
        driven_pin_line = draw.LineString([
            (-(pad_height + taper_height + pad_gap), pad_width_half),
            (-(pad_height + taper_height + pad_gap), -pad_width_half)
        ])

        # Create polygon object list
        polys1 = [main_pin_line, driven_pin_line, launch_pad, pocket]

        # Rotates and translates all the objects as requested. Uses package functions in
        # 'draw_utility' for easy rotation/translation
        polys1 = draw.rotate(polys1, p.orientation, origin=(0, 0))
        polys1 = draw.translate(polys1, xoff=p.pos_x, yoff=p.pos_y)
        [main_pin_line, driven_pin_line, launch_pad, pocket] = polys1

        # Adds the object to the qgeometry table
        self.add_qgeometry('poly', dict(launch_pad=launch_pad), layer=p.layer)

        # Subtracts out ground plane on the layer its on
        self.add_qgeometry('poly',
                           dict(pocket=pocket),
                           subtract=True,
                           layer=p.layer)

        # Generates the pins
        self.add_pin('tie', main_pin_line.coords, trace_width)
        self.add_pin('in', driven_pin_line.coords, pad_width, gap=pad_gap)
    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)
Beispiel #25
0
    def make_ro(self):
        '''
        Create the head of the readout resonator.
        Contains: the circular patch for coupling,
            the 45 deg line,
            the 45 deg arc,
            a short straight segment (of length w) for smooth subtraction
        '''
        # access to parsed values from the user option
        p = self.p

        # access to chip name
        chip = p.chip

        # local variables
        r = p.readout_radius
        w = p.readout_cpw_width
        g = p.readout_cpw_gap
        turnradius = p.readout_cpw_turnradius
        l_1 = p.readout_l1
        l_2 = p.readout_l2
        l_3 = p.readout_l3
        l_4 = p.readout_l4
        l_5 = p.readout_l5

        # create the coupling patch in term of a circle
        cppatch = draw.Point(0, 0).buffer(r)

        # create the extended arm
        ## useful coordinates
        x_1, y_1 = l_1 * np.cos(np.pi / 4), -l_1 * np.sin(np.pi / 4)
        x_2, y_2 = x_1 + turnradius * (
            1 - np.cos(np.pi / 4)), y_1 - turnradius * np.sin(np.pi / 4)
        coord_init = draw.Point(x_1, y_1)
        coord_center = draw.Point(x_1 - turnradius * np.cos(np.pi / 4),
                                  y_1 - turnradius * np.sin(np.pi / 4))
        x_3, y_3 = x_2, y_2
        x_4, y_4 = x_3, y_3 - l_2
        x_5, y_5 = x_4 + turnradius, y_4
        coord_init1 = draw.Point(x_4, y_4)
        coord_center1 = draw.Point(x_5, y_5)
        x_6, y_6 = x_5, y_5 - turnradius
        x_7, y_7 = x_5 + l_3, y_6
        x_8, y_8 = x_7, y_7 + turnradius
        coord_init2 = draw.Point((x_7, y_7))
        coord_center2 = draw.Point((x_8, y_8))
        x_9, y_9 = x_8, y_8 + turnradius
        x_10, y_10 = x_8 - l_4, y_9
        x_11, y_11 = x_10, y_10 + turnradius
        coord_init3 = draw.Point((x_10, y_10))
        coord_center3 = draw.Point((x_11, y_11))
        arc3 = self.arc(coord_init3, coord_center3, -np.pi)
        x_12, y_12 = x_11, y_11 + turnradius
        x_13, y_13 = x_12 + l_5, y_12
        line12 = draw.LineString([(x_12, y_12), (x_13, y_13)])
        x_14, y_14 = x_13, y_13 + turnradius
        coord_init4 = draw.Point((x_13, y_13))
        coord_center4 = draw.Point((x_14, y_14))
        arc4 = self.arc(coord_init4, coord_center4, np.pi)
        ## line containing the 45deg line, 45 deg arc,
        ## and a short straight segment for smooth subtraction
        cparm_line = draw.shapely.ops.unary_union([
            draw.LineString([(0, 0), coord_init]),
            self.arc(coord_init, coord_center, -np.pi / 4),
            draw.LineString([(x_3, y_3), (x_4, y_4)]),
            self.arc(coord_init1, coord_center1, np.pi / 2),
            draw.LineString([(x_6, y_6), (x_7, y_7)]),
            self.arc(coord_init2, coord_center2, np.pi),
            draw.LineString([(x_9, y_9), (x_10, y_10)]), arc3, line12, arc4,
            draw.translate(line12, 0, 2 * turnradius),
            draw.translate(arc3, 0, 4 * turnradius),
            draw.translate(line12, 0, 4 * turnradius),
            draw.translate(arc4, 0, 4 * turnradius),
            draw.translate(line12, 0, 6 * turnradius),
            draw.translate(arc3, 0, 8 * turnradius),
            draw.translate(line12, 0, 8 * turnradius)
        ])
        cparm = cparm_line.buffer(w / 2, cap_style=2, join_style=1)
        ## fix the gap resulting from buffer
        eps = 1e-3
        cparm = draw.Polygon(cparm.exterior)
        cparm = cparm.buffer(eps, join_style=2).buffer(-eps, join_style=2)

        # create combined objects for the signal line and the etch
        ro = draw.shapely.ops.unary_union([cppatch, cparm])
        ro_etch = ro.buffer(g, cap_style=2, join_style=2)
        x_15, y_15 = x_14, y_14 + 7 * turnradius
        x_16, y_16 = x_15 + g / 2, y_15
        port_line = draw.LineString([(x_15, y_15 + w / 2),
                                     (x_15, y_15 - w / 2)])
        subtract_patch = draw.LineString([(x_16, y_16 - w / 2 - g - eps),
                                          (x_16, y_16 + w / 2 + g + eps)
                                          ]).buffer(g / 2, cap_style=2)
        ro_etch = ro_etch.difference(subtract_patch)

        # rotate and translate
        polys = [ro, ro_etch, port_line]
        polys = draw.rotate(polys, p.orientation, origin=(0, 0))
        polys = draw.translate(polys, p.pos_x, p.pos_y)

        # update each object
        [ro, ro_etch, port_line] = polys

        # generate QGeometry
        self.add_qgeometry('poly', dict(ro=ro), chip=chip, layer=p.layer)
        self.add_qgeometry('poly',
                           dict(ro_etch=ro_etch),
                           chip=chip,
                           layer=p.layer_subtract,
                           subtract=p.subtract)

        # generate pins
        self.add_pin('readout', port_line.coords, width=w, gap=g, chip=chip)
Beispiel #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)
    def make(self):
        """Build the component."""
        p = self.p

        prime_cpw_length = p.coupling_length * 2
        second_flip = 1
        if p.mirror:
            second_flip = -1

        #Primary CPW
        prime_cpw = draw.LineString([[-prime_cpw_length / 2, 0],
                                     [prime_cpw_length / 2, 0]])

        #Secondary CPW
        second_down_length = p.down_length
        second_y = -p.prime_width / 2 - p.prime_gap - p.coupling_space - p.second_gap - p.second_width / 2
        second_cpw = draw.LineString(
            [[second_flip * (-p.coupling_length / 2), second_y],
             [second_flip * (p.coupling_length / 2), second_y],
             [
                 second_flip * (p.coupling_length / 2),
                 second_y - second_down_length
             ]])

        second_termination = 0
        if p.open_termination:
            second_termination = p.second_gap

        second_cpw_etch = draw.LineString(
            [[
                second_flip * (-p.coupling_length / 2 - second_termination),
                second_y
            ], [second_flip * (p.coupling_length / 2), second_y],
             [
                 second_flip * (p.coupling_length / 2),
                 second_y - second_down_length
             ]])

        #Rotate and Translate
        c_items = [prime_cpw, second_cpw, second_cpw_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, second_cpw_etch] = c_items

        #Add to qgeometry tables
        self.add_qgeometry('path', {'prime_cpw': prime_cpw},
                           width=p.prime_width)
        self.add_qgeometry('path', {'prime_cpw_sub': prime_cpw},
                           width=p.prime_width + 2 * p.prime_gap,
                           subtract=True)
        self.add_qgeometry('path', {'second_cpw': second_cpw},
                           width=p.second_width,
                           fillet=p.fillet)
        self.add_qgeometry('path', {'second_cpw_sub': second_cpw_etch},
                           width=p.second_width + 2 * p.second_gap,
                           subtract=True,
                           fillet=p.fillet)

        #Add pins
        prime_pin_list = prime_cpw.coords
        second_pin_list = second_cpw.coords

        self.add_pin('prime_start',
                     points=np.array(prime_pin_list[::-1]),
                     width=p.prime_width,
                     input_as_norm=True)
        self.add_pin('prime_end',
                     points=np.array(prime_pin_list),
                     width=p.prime_width,
                     input_as_norm=True)
        self.add_pin('second_end',
                     points=np.array(second_pin_list[1:]),
                     width=p.second_width,
                     input_as_norm=True)
    def make(self):
        """This is executed by the user to generate the qgeometry for the
        component."""

        p = self.p
        lead_length = p.lead_length
        trace_width = p.trace_width
        trace_width_half = trace_width / 2
        trace_gap = p.trace_gap
        inner_finger_width = .001
        inner_finger_width_half = inner_finger_width / 2
        inner_finger_offset = .015
        finger_side_gap = .002
        outer_finger_tip_gap = .0075
        inner_finger_tip_gap = .05 + inner_finger_offset
        outer_finger_width = (trace_width - inner_finger_width -
                              2 * finger_side_gap) / 2
        coupler_length = p.coupler_length
        lead_offset = coupler_length + outer_finger_tip_gap
        #########################################################

        # Geometry of main launch structure
        launch_pad = draw.Polygon([
            (0, trace_width_half), (-.122, trace_width_half + .035),
            (-.202, trace_width_half + .035), (-.202,
                                               -trace_width_half - .035),
            (-.122, -trace_width_half - .035), (0, -trace_width_half),
            (coupler_length, -trace_width_half),
            (coupler_length, -trace_width_half + outer_finger_width),
            (-inner_finger_tip_gap + inner_finger_offset,
             -trace_width_half + outer_finger_width),
            (-inner_finger_tip_gap + inner_finger_offset,
             trace_width_half - outer_finger_width),
            (coupler_length, trace_width_half - outer_finger_width),
            (coupler_length, trace_width_half), (0, trace_width / 2)
        ])

        # Geometry of coupling structure
        ind_stub = draw.Polygon([
            (inner_finger_offset, -inner_finger_width_half),
            (lead_offset, -inner_finger_width_half),
            (lead_offset, -trace_width_half),
            (lead_offset + lead_length, -trace_width_half),
            (lead_offset + lead_length, trace_width_half),
            (lead_offset, trace_width_half),
            (lead_offset, +inner_finger_width_half),
            (inner_finger_offset, +inner_finger_width_half),
            (inner_finger_offset, -inner_finger_width_half)
        ])

        # Geometry pocket (gap)
        pocket = draw.Polygon([
            (0, trace_width_half + trace_gap),
            (-.122, trace_width_half + trace_gap + .087),
            (-.25, trace_width_half + trace_gap + .087),
            (-.25, -trace_width_half - trace_gap - .087),
            (-.122, -trace_width_half - trace_gap - .087),
            (0, -trace_width_half - trace_gap),
            (lead_offset + lead_length, -trace_width_half - trace_gap),
            (lead_offset + lead_length, +trace_width_half + trace_gap),
            (0, trace_width_half + trace_gap)
        ])

        # These variables are used to graphically locate the pin locations
        main_pin_line = draw.LineString([
            (lead_offset + lead_length, trace_width_half),
            (lead_offset + lead_length, -trace_width_half)
        ])

        # Create polygon object list
        polys1 = [main_pin_line, launch_pad, ind_stub, pocket]

        # Rotates and translates all the objects as requested. Uses package functions
        # in 'draw_utility' for easy rotation/translation
        polys1 = draw.rotate(polys1, p.orientation, origin=(0, 0))
        polys1 = draw.translate(polys1, xoff=p.pos_x, yoff=p.pos_y)
        [main_pin_line, launch_pad, ind_stub, pocket] = polys1

        # Adds the object to the qgeometry table
        self.add_qgeometry('poly',
                           dict(launch_pad=launch_pad, ind_stub=ind_stub),
                           layer=p.layer)

        # Subtracts out ground plane on the layer its on
        self.add_qgeometry('poly',
                           dict(pocket=pocket),
                           subtract=True,
                           layer=p.layer)

        # Generates the pins
        self.add_pin('tie', main_pin_line.coords, trace_width)
    def make(self):
        """Build the component."""
        p = self.p
        N = int(p.finger_count)

        #Finger Capacitor
        cap_box = draw.rectangle(N * p.cap_width + (N - 1) * p.cap_gap,
                                 p.cap_gap + 2 * p.cap_width + p.finger_length,
                                 0, 0)
        make_cut_list = []
        make_cut_list.append([0, (p.finger_length) / 2])
        make_cut_list.append([(p.cap_width) + (p.cap_gap / 2),
                              (p.finger_length) / 2])
        flip = -1

        for i in range(1, N):
            make_cut_list.append([
                i * (p.cap_width) + (2 * i - 1) * (p.cap_gap / 2),
                flip * (p.finger_length) / 2
            ])
            make_cut_list.append([
                (i + 1) * (p.cap_width) + (2 * i + 1) * (p.cap_gap / 2),
                flip * (p.finger_length) / 2
            ])
            flip = flip * -1

        cap_cut = draw.LineString(make_cut_list).buffer(p.cap_gap / 2,
                                                        cap_style=2,
                                                        join_style=2)
        cap_cut = draw.translate(cap_cut,
                                 -(N * p.cap_width + (N - 1) * p.cap_gap) / 2,
                                 0)

        cap_body = draw.subtract(cap_box, cap_cut)
        cap_body = draw.translate(
            cap_body, 0, -p.cap_distance -
            (p.cap_gap + 2 * p.cap_width + p.finger_length) / 2)

        cap_etch = draw.rectangle(
            N * p.cap_width + (N - 1) * p.cap_gap + 2 * p.cap_gap_ground,
            p.cap_gap + 2 * p.cap_width + p.finger_length +
            2 * p.cap_gap_ground, 0, -p.cap_distance -
            (p.cap_gap + 2 * p.cap_width + p.finger_length) / 2)

        #CPW
        north_cpw = draw.LineString([[0, 0], [0, -p.cap_distance]])

        south_cpw = draw.LineString(
            [[
                0, -p.cap_distance -
                (p.cap_gap + 2 * p.cap_width + p.finger_length)
            ],
             [
                 0, -2 * p.cap_distance -
                 (p.cap_gap + 2 * p.cap_width + p.finger_length)
             ]])

        #Rotate and Translate
        c_items = [north_cpw, south_cpw, cap_body, cap_etch]
        c_items = draw.rotate(c_items, p.orientation, origin=(0, 0))
        c_items = draw.translate(c_items, p.pos_x, p.pos_y)
        [north_cpw, south_cpw, cap_body, cap_etch] = c_items

        #Add to qgeometry tables
        self.add_qgeometry('path', {'north_cpw': north_cpw},
                           width=p.north_width,
                           layer=p.layer)
        self.add_qgeometry('path', {'north_cpw_sub': north_cpw},
                           width=p.north_width + 2 * p.north_gap,
                           layer=p.layer,
                           subtract=True)

        self.add_qgeometry('path', {'south_cpw': south_cpw},
                           width=p.south_width,
                           layer=p.layer)
        self.add_qgeometry('path', {'south_cpw_sub': south_cpw},
                           width=p.south_width + 2 * p.south_gap,
                           layer=p.layer,
                           subtract=True)

        self.add_qgeometry('poly', {'cap_body': cap_body}, layer=p.layer)
        self.add_qgeometry('poly', {'cap_etch': cap_etch},
                           layer=p.layer,
                           subtract=True)

        #Add pins
        north_pin_list = north_cpw.coords
        south_pin_list = south_cpw.coords

        self.add_pin('north_end',
                     points=np.array(north_pin_list[::-1]),
                     width=p.north_width,
                     input_as_norm=True)
        self.add_pin('south_end',
                     points=np.array(south_pin_list),
                     width=p.south_width,
                     input_as_norm=True)
    def make(self):
        """Builds the component."""
        p = self.p

        #Draw the charge island
        btm = draw.shapely.geometry.box(-p.c_width / 2, -p.l_width / 2, 0,
                                        p.l_width / 2)

        x_spot = p.c_width / 2 - p.l_width / 2

        arm1 = draw.shapely.geometry.box(-(x_spot + p.l_width / 2),
                                         p.l_width / 2,
                                         -(x_spot - p.l_width / 2), p.a_height)
        arm2 = draw.shapely.geometry.box(-((x_spot) * 3 / 5 + p.l_width / 2),
                                         p.l_width / 2,
                                         -((x_spot) * 3 / 5 - p.l_width / 2),
                                         p.a_height)
        arm3 = draw.shapely.geometry.box(-((x_spot) * 1 / 5 + p.l_width / 2),
                                         p.l_width / 2,
                                         -((x_spot) * 1 / 5 - p.l_width / 2),
                                         p.a_height)

        left_side = draw.shapely.ops.cascaded_union([btm, arm1, arm2, arm3])
        cap_island = draw.shapely.ops.cascaded_union([
            left_side,
            draw.shapely.affinity.scale(left_side,
                                        xfact=-1,
                                        yfact=1,
                                        origin=(0, 0))
        ])

        cap_subtract = cap_island.buffer(p.l_gap, cap_style=3, join_style=2)

        #Reference coordinates
        cpl_x = 1 / 5 * x_spot
        cpl_y = p.a_height + p.l_gap + p.cp_gap + p.cp_gspace
        fl_y = p.a_height + p.l_gap + p.fl_ground + p.fl_gap + p.fl_width / 2

        #Draw the junction and flux line
        rect_jj = draw.LineString([(-cpl_x * 3, p.a_height),
                                   (-cpl_x * 3, p.a_height + p.l_gap)])

        flux_line = draw.LineString([[-cpl_x * 3 - p.fl_length, fl_y],
                                     [-cpl_x * 3, fl_y],
                                     [-cpl_x * 3, fl_y + 0.01]])

        #Draw the connector
        cpl_x = 1 / 5 * x_spot
        cpl_y = p.a_height + p.l_gap + p.cp_gap + p.cp_gspace

        con_pad = draw.shapely.geometry.box(
            cpl_x - 1 / 5 * x_spot - p.cp_arm_width / 2, cpl_y,
            cpl_x + 1 / 5 * x_spot + p.cp_arm_width / 2, cpl_y + p.cp_height)

        con_arm_l = draw.shapely.geometry.box(
            cpl_x - 1 / 5 * x_spot - p.cp_arm_width / 2,
            cpl_y - p.cp_arm_length,
            cpl_x - 1 / 5 * x_spot + p.cp_arm_width / 2, cpl_y)

        con_arm_r = draw.shapely.geometry.box(
            cpl_x + 1 / 5 * x_spot - p.cp_arm_width / 2,
            cpl_y - p.cp_arm_length,
            cpl_x + 1 / 5 * x_spot + p.cp_arm_width / 2, cpl_y)

        con_body = draw.shapely.ops.cascaded_union(
            [con_pad, con_arm_l, con_arm_r])

        con_sub = con_body.buffer(p.cp_gap, cap_style=3, join_style=2)

        con_pin = draw.LineString([[cpl_x, cpl_y], [cpl_x,
                                                    cpl_y + p.cp_height]])

        #Rotate and translate.
        c_items = [
            cap_island, cap_subtract, rect_jj, con_body, con_sub, flux_line,
            con_pin
        ]
        c_items = draw.rotate(c_items, p.orientation, origin=(0, 0))
        c_items = draw.translate(c_items, p.pos_x, p.pos_y)
        [
            cap_island, cap_subtract, rect_jj, con_body, con_sub, flux_line,
            con_pin
        ] = c_items

        #Add to qgeometry
        self.add_qgeometry('poly', {
            'cap_island': cap_island,
            'connector_body': con_body
        },
                           layer=p.layer)
        self.add_qgeometry('poly', {
            'cap_subtract': cap_subtract,
            'connector_sub': con_sub
        },
                           layer=p.layer,
                           subtract=True)

        self.add_qgeometry('path', {'flux_line': flux_line},
                           width=p.fl_width,
                           layer=p.layer)
        self.add_qgeometry('path', {'flux_line_sub': flux_line},
                           width=p.fl_width + 2 * p.fl_gap,
                           subtract=True,
                           layer=p.layer)

        self.add_qgeometry('junction', dict(rect_jj=rect_jj), width=p.l_width)

        #Add pin
        self.add_pin('Control',
                     points=np.array(con_pin),
                     width=p.l_width,
                     input_as_norm=True)
        self.add_pin('Flux',
                     points=np.array(flux_line.coords[-2:]),
                     width=p.l_width,
                     input_as_norm=True)