Example #1
0
class PI(i3.PCell):
    _name_prefix = "PI"

    # Center of the structure
    position = i3.Coord2Property(default=(0.0, 0.0))

    # Layer
    layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW)
    layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC)

    # Mesa parameters
    length = i3.PositiveNumberProperty(default=7000.0)
    width = i3.PositiveNumberProperty(default=630.0)

    pocket = i3.BoolProperty(default=False)
    tilt = i3.BoolProperty(default=False)

    # Recess label
    label = i3.StringProperty(default="PI_")

    class Layout(i3.LayoutView):

        def _generate_elements(self, elems):
            # Center of the structure
            (x0, y0) = self.position

            elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500, y0 + 1000 + (3000 - self.width) / 4),
                                  box_size=(self.length, (3000 - self.width) / 2))

            elems += i3.Rectangle(layer=self.layer,
                                  center=(x0 + 6500, y0 + 1000 + self.width + (3000 - self.width) * 3 / 4),
                                  box_size=(self.length, (3000 - self.width) / 2))

            elems += i3.SRef(reference=Interface(pocket=self.pocket, tilt=self.tilt))

            for i in range(7):
                elems += i3.Rectangle(layer=self.layer,
                                      center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 185),
                                      box_size=(50, 50))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 185),
                                      box_size=(50, 50))
            if self.pocket:
                self.label += "WP"
            if self.tilt:
                self.label += "WT"
            elems += i3.PolygonText(layer=self.layer_bool,
                                    text=self.label,

                                    coordinate=(6000, 4000),
                                    # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                                    font=2,
                                    height=700.0)

            generated1 = self.layer - self.layer_bool
            mapping = {generated1: self.layer}
            elems = i3.get_elements_for_generated_layers(elems, mapping)

            return elems
Example #2
0
class Interface_mmi12(i3.PCell):
    _name_prefix = "INTERFACE_"

    # Center of the structure
    position = i3.Coord2Property(default=(0.0, 0.0))

    # Layer
    layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW)
    layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC)

    # Mesa parameters
    length = i3.PositiveNumberProperty(default=2500)  # shrink
    width = i3.PositiveNumberProperty(default=3000.0 * 0.6)

    pocket = i3.BoolProperty(default=False)
    tilt = i3.BoolProperty(default=False)

    class Layout(i3.LayoutView):

        def _generate_elements(self, elems):

            # Center of the structure
            (x0, y0) = self.position

            elems += i3.Rectangle(layer=self.layer, center=(x0 + 7500 + 2000+1500, y0 + 4500 - 1800+500),
                                  box_size=(10000, 1600))  # change

            # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.NONE.DOC, center=(x0 + 7500, y0 + 4500),
            #                       box_size=(15000, 1000))

            elems += i3.Rectangle(layer=self.layer, center=(x0 + 7500 + 2000+1500, y0 + 500 - 200-500),
                                  box_size=(10000, 1600))
            elems += i3.Rectangle(layer=self.layer, center=(x0 + 12500 + 1000 - 250, y0 + 2500 - 1000),  # change
                                  box_size=(self.length, self.width))
            elems +=i3.Rectangle(layer=self.layer, center=(x0+ 15250, y0+1500),box_size=(1500,1800)) #add

            if self.pocket:
                PO = i3.Rectangle(layer=self.layer_bool, center=(10001 + 2000, 2500 - 1000),
                                  box_size=(2, 160))  # change
                elems += PO
                generated1 = self.layer - self.layer_bool
                mapping = {generated1: self.layer}
                elems = i3.get_elements_for_generated_layers(elems, mapping)

            if self.tilt:
                # TI = i3.Rectangle(layer=self.layer_bool, center=(10001, 2500), box_size=(2, 160))
                # elems += TI
                TI_shape = i3.Shape(points=[(10000.0 + 2000, 2470.0 - 1000), (10010.58 + 2000, 2530.0 - 1000),
                                            (10000.0 + 2000, 2530.0 - 1000)], closed=True)  # change
                TI = i3.Boundary(layer=self.layer_bool, shape=TI_shape)
                elems += TI

            generated1 = self.layer - self.layer_bool
            mapping = {generated1: self.layer}
            elems = i3.get_elements_for_generated_layers(elems, mapping)

            return elems
Example #3
0
class SiN_NP(i3.PCell):
    _name_prefix = "SiN_NP"

    # Center of the structure
    position = i3.Coord2Property(default=(0.0, 0.0))

    # Layer
    layer = i3.LayerProperty(default=i3.TECH.PPLAYER.SIL.LINE)
    layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC)

    # Mesa parameters
    length = i3.PositiveNumberProperty(default=7000.0)
    width = i3.PositiveNumberProperty(default=330.0)

    pillar = i3.BoolProperty(default=False)
    tilt_0 = i3.BoolProperty(default=False)

    class Layout(i3.LayoutView):
        def _generate_elements(self, elems):

            # Center of the structure
            (x0, y0) = self.position

            elems += i3.Rectangle(layer=self.layer,
                                  center=(1500 - 20, 2500),
                                  box_size=(3000 - 40, 3000 - 40 * 2))

            if self.tilt_0:
                elems += i3.Rectangle(layer=self.layer,
                                      center=(x0 + 6500 - 40 + 20 + 7.5, 2500),
                                      box_size=(self.length + 40 + 15,
                                                self.width - 40 * 2))
            else:
                elems += i3.Rectangle(layer=self.layer,
                                      center=(x0 + 6500 - 40 + 20 + 5, 2500),
                                      box_size=(self.length + 40 + 10,
                                                self.width - 40 * 2))

            if self.pillar:
                for i in range(7):
                    elems += i3.Rectangle(
                        layer=self.layer_bool,
                        center=(10000 - 725 - i * 750,
                                1000 + (3000 - self.width) / 2 + 30),
                        box_size=(130, 140))
                    elems += i3.Rectangle(
                        layer=self.layer_bool,
                        center=(10000 - 725 - i * 750, 1000 +
                                (3000 - self.width) / 2 + self.width - 30),
                        box_size=(130, 140))

            generated1 = self.layer - self.layer_bool
            mapping = {generated1: self.layer}
            elems = i3.get_elements_for_generated_layers(elems, mapping)
            return elems
Example #4
0
    class Layout(i3.LayoutView):
        """
        Cross marker Layout view
        """

        inversion = i3.BoolProperty(
            default=False,
            doc="if True: open cross - white cross on black background")
        cross_bar_width = i3.PositiveNumberProperty(default=8,
                                                    doc="width of the cross")
        cross_boundary_width = i3.PositiveNumberProperty(
            default=50, doc="width the boundary box")

        #process = i3.ProcessProperty(default=i3.TECH.PPLAYER.CH2.TRENCH)#i3.TECH.PROCESS.WG, doc="Process Layer on which the cross is drawn")

        # Purpose Property cannot be set from outside
        #purpose = i3.PurposeProperty(locked=True, default=i3.TECH.PPLAYER.CH2.TRENCH)#i3.TECH.PURPOSE.DF.LINE, doc="Process Purpose of the cross")

        def _generate_elements(self, elems):

            rect_size = (self.cross_boundary_width - self.cross_bar_width) / 2
            rect_center = self.cross_bar_width / 2 + rect_size / 2

            if not self.inversion:  # Dark cross
                elems += i3.Cross(
                    layer=i3.TECH.PPLAYER.CH1.
                    TRENCH,  #i3.PPLayer(self.process,self.purpose),
                    center=(0, 0),
                    box_size=self.cross_boundary_width,
                    thickness=self.cross_bar_width)

            else:  # Open cross: formed by 4 dark squares at corners
                elems += i3.Rectangle(
                    layer=i3.TECH.PPLAYER.CH2.
                    TRENCH,  #i3.PPLayer(self.process, self.purpose),
                    center=(rect_center, rect_center),
                    box_size=(rect_size, rect_size))
                elems += i3.Rectangle(
                    layer=i3.TECH.PPLAYER.CH2.
                    TRENCH,  #i3.PPLayer(self.process, self.purpose),
                    center=(rect_center, -rect_center),
                    box_size=(rect_size, rect_size))
                elems += i3.Rectangle(
                    layer=i3.TECH.PPLAYER.CH2.
                    TRENCH,  #i3.PPLayer(self.process, self.purpose),
                    center=(-rect_center, rect_center),
                    box_size=(rect_size, rect_size))
                elems += i3.Rectangle(
                    layer=i3.TECH.PPLAYER.CH2.
                    TRENCH,  #i3.PPLayer(self.process, self.purpose),
                    center=(-rect_center, -rect_center),
                    box_size=(rect_size, rect_size))
            return elems
Example #5
0
class AlignmentMarker(i3.PCell):
    _name_prefix = "ALIGNMENT MARKER"

    # Center of the structure
    position = i3.Coord2Property(default=(0.0, 0.0))

    # Layer
    layer = i3.LayerProperty(required=True)

    # Complement
    complement = i3.BoolProperty(default=False)

    # Protection
    protection = i3.BoolProperty(default=False)

    # Marker parameters
    cross_length = i3.PositiveNumberProperty(default=150.0)
    cross_width = i3.PositiveNumberProperty(default=16.0)
    cross_margin = i3.PositiveNumberProperty(default=4.0)

    vernier_length = i3.PositiveNumberProperty(default=30.0)
    vernier_width = i3.PositiveNumberProperty(default=8.0)
    vernier_period = i3.PositiveNumberProperty(default=20.25)
    vernier_left_center = i3.Coord2Property(default=(-121.0, 24.0))
    vernier_top_center = i3.Coord2Property(default=(-6.0, 119.0))

    vernier_complement_length = i3.PositiveNumberProperty(default=18.0)
    vernier_complement_long_length = i3.PositiveNumberProperty(default=28.0)
    vernier_complement_width = i3.PositiveNumberProperty(default=10.0)
    vernier_complement_shift = i3.PositiveNumberProperty(default=9.0)
    vernier_complement_period = i3.PositiveNumberProperty(default=20)

    protection_length = i3.PositiveNumberProperty(default=300.0)
    protection_width = i3.PositiveNumberProperty(default=320.0)

    # Layer text
    layer_text = i3.StringProperty(default="Mesa")

    class Layout(i3.LayoutView):
        def _generate_elements(self, elems):

            # Center of the structure
            (x0, y0) = self.position

            shift = 0.5 * self.cross_width + self.cross_margin
            square_length = 0.5 * self.cross_length - shift

            if (self.complement == False and self.protection == False):

                # Add cross
                elems += i3.Rectangle(layer=self.layer,
                                      center=(x0, y0),
                                      box_size=(self.cross_length,
                                                self.cross_width))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(x0, y0),
                                      box_size=(self.cross_width,
                                                self.cross_length))

                # Add rectangles left VERNIER
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_left_center[0],
                                              self.vernier_left_center[1]),
                                      box_size=(self.vernier_length,
                                                self.vernier_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0],
                            self.vernier_left_center[1] + self.vernier_period),
                    box_size=(self.vernier_length, self.vernier_width))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_left_center[0],
                                              self.vernier_left_center[1] +
                                              2.0 * self.vernier_period),
                                      box_size=(self.vernier_length,
                                                self.vernier_width))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_left_center[0],
                                              self.vernier_left_center[1] +
                                              3.0 * self.vernier_period),
                                      box_size=(self.vernier_length,
                                                self.vernier_width))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_left_center[0],
                                              self.vernier_left_center[1] +
                                              4.0 * self.vernier_period),
                                      box_size=(self.vernier_length,
                                                self.vernier_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0],
                            self.vernier_left_center[1] - self.vernier_period),
                    box_size=(self.vernier_length, self.vernier_width))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_left_center[0],
                                              self.vernier_left_center[1] -
                                              2.0 * self.vernier_period),
                                      box_size=(self.vernier_length,
                                                self.vernier_width))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_left_center[0],
                                              self.vernier_left_center[1] -
                                              3.0 * self.vernier_period),
                                      box_size=(self.vernier_length,
                                                self.vernier_width))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_left_center[0],
                                              self.vernier_left_center[1] -
                                              4.0 * self.vernier_period),
                                      box_size=(self.vernier_length,
                                                self.vernier_width))

                # Add rectangles top VERNIER
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_top_center[0],
                                              self.vernier_top_center[1]),
                                      box_size=(self.vernier_width,
                                                self.vernier_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] + self.vernier_period,
                            self.vernier_top_center[1]),
                    box_size=(self.vernier_width, self.vernier_length))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_top_center[0] +
                                              2.0 * self.vernier_period,
                                              self.vernier_top_center[1]),
                                      box_size=(self.vernier_width,
                                                self.vernier_length))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_top_center[0] +
                                              3.0 * self.vernier_period,
                                              self.vernier_top_center[1]),
                                      box_size=(self.vernier_width,
                                                self.vernier_length))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_top_center[0] +
                                              4.0 * self.vernier_period,
                                              self.vernier_top_center[1]),
                                      box_size=(self.vernier_width,
                                                self.vernier_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] - self.vernier_period,
                            self.vernier_top_center[1]),
                    box_size=(self.vernier_width, self.vernier_length))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_top_center[0] -
                                              2.0 * self.vernier_period,
                                              self.vernier_top_center[1]),
                                      box_size=(self.vernier_width,
                                                self.vernier_length))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_top_center[0] -
                                              3.0 * self.vernier_period,
                                              self.vernier_top_center[1]),
                                      box_size=(self.vernier_width,
                                                self.vernier_length))
                elems += i3.Rectangle(layer=self.layer,
                                      center=(self.vernier_top_center[0] -
                                              4.0 * self.vernier_period,
                                              self.vernier_top_center[1]),
                                      box_size=(self.vernier_width,
                                                self.vernier_length))

                # Add TEXT
                elems += i3.PolygonText(layer=self.layer,
                                        coordinate=(x0, y0 - 100.0),
                                        text=self.layer_text,
                                        height=35.0)

            elif (self.complement == True and self.protection == False):

                # Add squares
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(x0 - 0.25 * self.cross_length - 0.5 * shift,
                            y0 + 0.25 * self.cross_length + 0.5 * shift),
                    box_size=(square_length, square_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(x0 + 0.25 * self.cross_length + 0.5 * shift,
                            y0 + 0.25 * self.cross_length + 0.5 * shift),
                    box_size=(square_length, square_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(x0 - 0.25 * self.cross_length - 0.5 * shift,
                            y0 - 0.25 * self.cross_length - 0.5 * shift),
                    box_size=(square_length, square_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(x0 + 0.25 * self.cross_length + 0.5 * shift,
                            y0 - 0.25 * self.cross_length - 0.5 * shift),
                    box_size=(square_length, square_length))

                # Add rectangles left VERNIER
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_long_length,
                            self.vernier_left_center[1]),
                    box_size=(self.vernier_complement_long_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_long_length,
                            self.vernier_left_center[1]),
                    box_size=(self.vernier_complement_long_length,
                              self.vernier_complement_width))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] +
                            self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] +
                            self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] +
                            2.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] +
                            2.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] +
                            3.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] +
                            3.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] +
                            4.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] +
                            4.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] -
                            self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] -
                            self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] -
                            2.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] -
                            2.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] -
                            3.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] -
                            3.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] -
                            4.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_left_center[0] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length,
                            self.vernier_left_center[1] -
                            4.0 * self.vernier_complement_period),
                    box_size=(self.vernier_complement_length,
                              self.vernier_complement_width))

                # Add rectangles top VERNIER
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0],
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_long_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_long_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0],
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_long_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_long_length))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] +
                            self.vernier_complement_period,
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] +
                            self.vernier_complement_period,
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] +
                            2.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] +
                            2.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] +
                            3.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] +
                            3.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] +
                            4.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] +
                            4.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] -
                            self.vernier_complement_period,
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] -
                            self.vernier_complement_period,
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] -
                            2.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] -
                            2.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] -
                            3.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] -
                            3.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))

                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] -
                            4.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] -
                            self.vernier_complement_shift -
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(self.vernier_top_center[0] -
                            4.0 * self.vernier_complement_period,
                            self.vernier_top_center[1] +
                            self.vernier_complement_shift +
                            0.5 * self.vernier_complement_length),
                    box_size=(self.vernier_complement_width,
                              self.vernier_complement_length))

            else:
                elems += i3.Rectangle(layer=self.layer,
                                      center=(x0 - 43.5, y0 + 11.5),
                                      box_size=(self.protection_length,
                                                self.protection_width))

            return elems
Example #6
0
class AlignmentMarkerSet(i3.PCell):
    _name_prefix = "ALIGNMENT MARKER SET"

    # Center of the structure
    position = i3.Coord2Property(default=(0.0, 0.0))

    # Orientation
    horizontal = i3.BoolProperty(default=True)

    # Spacing
    v_spacing = i3.PositiveNumberProperty(default=320.0)
    h_spacing = i3.PositiveNumberProperty(default=300.0)

    class Layout(i3.LayoutView):
        def _generate_elements(self, elems):

            # Center of the structure
            (x0, y0) = self.position

            if self.horizontal == False:

                # ADD RELEASE
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="Release"),
                                 transformation=i3.Translation(
                                     (x0 + 0.0 * self.h_spacing, y0)))
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.HFW, complement=True),
                                 transformation=i3.Translation(
                                     (x0 + 0.0 * self.h_spacing, y0)))

                # # ADD TETHER
                # elems += i3.SRef(reference=AlignmentMarker(layer=lay_island, layer_text="Tether"),
                #                  transformation=i3.Translation((x0 + 1.0 * self.h_spacing, y0)))
                # elems += i3.SRef(reference=AlignmentMarker(layer=lay_release, protection=True),
                #                  transformation=i3.Translation((x0 + 1.0 * self.h_spacing, y0)))
                # elems += i3.SRef(reference=AlignmentMarker(layer=lay_tether, complement=True),
                #                  transformation=i3.Translation((x0 + 1.0 * self.h_spacing, y0)))
                #
                # # ADD Dongbomesa
                # elems += i3.SRef(reference=AlignmentMarker(layer=lay_island, layer_text="Dongbomesa"),
                #                  transformation=i3.Translation((x0 + 2.0 * self.h_spacing, y0)))
                # elems += i3.SRef(reference=AlignmentMarker(layer=lay_release, protection=True),
                #                  transformation=i3.Translation((x0 + 2.0 * self.h_spacing, y0)))
                # elems += i3.SRef(reference=AlignmentMarker(layer=lay_tether, protection=True),
                #                  transformation=i3.Translation((x0 + 2.0 * self.h_spacing, y0)))
                # elems += i3.SRef(reference=AlignmentMarker(layer=lay_mesa, complement=True),
                #                  transformation=i3.Translation((x0 + 2.0 * self.h_spacing, y0)))

            else:

                # ADD RECESS
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="RECESS"),
                                 transformation=i3.Translation(
                                     (x0 + 0.0 * self.h_spacing, y0)))
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.HFW, complement=True),
                                 transformation=i3.Translation(
                                     (x0 + 0.0 * self.h_spacing, y0)))

                # ADD AL
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="AL"),
                                 transformation=i3.Translation(
                                     (x0, y0 - 1.0 * self.v_spacing)))
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.HFW, protection=True),
                                 transformation=i3.Translation(
                                     (x0, y0 - 1.0 * self.v_spacing)))
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.CONTACT.PILLAR, complement=True),
                                 transformation=i3.Translation(
                                     (x0, y0 - 1.0 * self.v_spacing)))

                # ADD SiN
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="SiN"),
                                 transformation=i3.Translation(
                                     (x0, y0 - 2.0 * self.v_spacing)))
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.HFW, protection=True),
                                 transformation=i3.Translation(
                                     (x0, y0 - 2.0 * self.v_spacing)))
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.SIL.LINE, complement=True),
                                 transformation=i3.Translation(
                                     (x0, y0 - 2.0 * self.v_spacing)))

                # ADD BackUp
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.WG.TEXT, layer_text="BackUp"),
                                 transformation=i3.Translation(
                                     (x0, y0 - 3.0 * self.v_spacing)))
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.HFW, protection=True),
                                 transformation=i3.Translation(
                                     (x0, y0 - 3.0 * self.v_spacing)))
                # elems += i3.SRef(reference=AlignmentMarker(layer=lay_tether, complement=True),
                #                  transformation=i3.Translation((x0, y0 - 3.0 * self.v_spacing)))

                # RECESS adjustment according to the mask
                elems += i3.SRef(reference=AlignmentMarker(
                    layer=i3.TECH.PPLAYER.NONE.DOC, protection=True),
                                 transformation=i3.Translation(
                                     (x0, y0 - 0.0 * self.v_spacing)))
                generated1 = i3.TECH.PPLAYER.NONE.DOC - i3.TECH.PPLAYER.HFW
                mapping = {generated1: i3.TECH.PPLAYER.V12.PILLAR}
                elems += i3.get_elements_for_generated_layers(elems, mapping)

            return elems
Example #7
0
class NP_mmi12(i3.PCell):
    _name_prefix = "NP_"

    # Center of the structure
    position = i3.Coord2Property(default=(0.0, 0.0))

    # Layer
    layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW)
    layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC)
    layer2 = i3.LayerProperty(default=i3.TECH.PPLAYER.WG.TEXT)

    # Mesa parameters
    length = i3.PositiveNumberProperty(default=160.0)
    width = i3.PositiveNumberProperty(default=120.0)

    pillar = i3.BoolProperty(default=False)
    pocket = i3.BoolProperty(default=False)
    tilt = i3.BoolProperty(default=False)
    double = i3.BoolProperty(default=True)

    # Recess label
    label = i3.StringProperty(default="NP")

    class Layout(i3.LayoutView):
        def _generate_elements(self, elems):

            # Center of the structure
            (x0, y0) = self.position
            width2 = 450.0
            elems += i3.Rectangle(layer=self.layer,
                                  center=(x0 + 6500 + 2000 + 2000,
                                          600 + (1800 - width2) / 4),
                                  box_size=(3000, (1800 - width2) / 2))

            elems += i3.Rectangle(layer=self.layer,
                                  center=(x0 + 6500 + 2000 + 2000, y0 + 600 +
                                          width2 + (1800 - width2) * 3 / 4),
                                  box_size=(3000, (1800 - width2) / 2))

            elems += i3.SRef(
                reference=Interface_mmi12(pocket=self.pocket, tilt=self.tilt))

            if self.pillar:
                self.label = "NO"
                for i in range(4):
                    elems += i3.Rectangle(
                        layer=self.layer,
                        center=(10000 - 725 - i * 750 + 2000 + 550,
                                1275 + self.width / 2),
                        box_size=(self.length, self.width))
                    elems += i3.Rectangle(
                        layer=self.layer,
                        center=(10000 - 725 - i * 750 + 2000 + 550,
                                1725 - self.width / 2),  # change
                        box_size=(self.length, self.width))

                    if self.double:
                        elems += i3.Rectangle(
                            layer=self.layer,
                            center=(10000 - 725 - i * 750 + 2000 + 550 - 400,
                                    1275 + self.width / 2),
                            box_size=(self.length, self.width))
                        elems += i3.Rectangle(
                            layer=self.layer,
                            center=(10000 - 725 - i * 750 + 2000 + 550 - 400,
                                    1725 - self.width / 2),
                            # change
                            box_size=(self.length, self.width))

            if self.width > 120:
                self.label += "W"
            if self.pocket:
                self.label += "_WP"
            if self.tilt:
                self.label += "WT"
            elems += i3.PolygonText(
                layer=self.layer_bool,
                text=self.label,
                coordinate=(10800, 2600),
                # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                font=2,
                height=400.0)

            generated1 = self.layer - self.layer_bool
            mapping = {generated1: self.layer}
            elems = i3.get_elements_for_generated_layers(elems, mapping)

            if self.pillar:
                for i in range(4):
                    elems += i3.Rectangle(
                        layer=self.layer2,
                        center=(10000 - 725 - i * 750 + 2000 + 550,
                                1275 + self.width / 2),
                        box_size=(self.length + 10, self.width + 10))
                    elems += i3.Rectangle(
                        layer=self.layer2,
                        center=(10000 - 725 - i * 750 + 2000 + 550,
                                1725 - self.width / 2),  # change
                        box_size=(self.length + 10, self.width + 10))

                    if self.double:
                        elems += i3.Rectangle(
                            layer=self.layer2,
                            center=(10000 - 725 - i * 750 + 2000 + 550 - 400,
                                    1275 + self.width / 2),
                            box_size=(self.length + 10, self.width + 10))
                        elems += i3.Rectangle(
                            layer=self.layer2,
                            center=(10000 - 725 - i * 750 + 2000 + 550 - 400,
                                    1725 - self.width / 2),
                            # change
                            box_size=(self.length + 10, self.width + 10))

            return elems
Example #8
0
class SiN_NP(i3.PCell):
    _name_prefix = "SiN_NP"

    # Center of the structure
    position = i3.Coord2Property(default=(0.0, 0.0))

    # Layer
    layer = i3.LayerProperty(default=i3.TECH.PPLAYER.SIL.LINE)
    layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC)

    # Mesa parameters
    length = i3.PositiveNumberProperty(default=180.0)
    width = i3.PositiveNumberProperty(default=79.0)
    tilt = i3.PositiveNumberProperty(default=10.0)

    pillar = i3.BoolProperty(default=True)
    double = i3.BoolProperty(default=True)

    class Layout(i3.LayoutView):
        def _generate_elements(self, elems):

            # Center of the structure
            (x0, y0) = self.position

            elems += i3.Rectangle(layer=self.layer,
                                  center=(8750 - 15 - 10 + 5, 1500),
                                  box_size=(500 - 40, 1800 - 100))

            elems += i3.Rectangle(layer=self.layer,
                                  center=(10500 - 15 - 10 + self.tilt / 2,
                                          1500),
                                  box_size=(3000 + 50 + self.tilt,
                                            450 - 15 * 2))

            elems += i3.Rectangle(layer=self.layer,
                                  center=(8750 - 15 - 10 + 5 + 2420 - 150,
                                          1000 - 120),
                                  box_size=(2000, 500 - 40))  # extra SiN pad

            # for i in range(4):
            #     elems += i3.Rectangle(layer=self.layer,
            #                           center=(
            #                               10000 - 725 - i * 750 + 2000 + 350, 1316+72.75),
            #                           box_size=(145, 77.5))
            #     elems += i3.Rectangle(layer=self.layer, center=(
            #         10000 - 725 - i * 750 + 2000 + 350, 1684-72.75),  # change
            #                           box_size=(145, 77.5))

            if self.pillar:
                for i in range(4):
                    elems += i3.Rectangle(
                        layer=self.layer_bool,
                        center=(10000 - 725 - i * 750 + 2000 + 550,
                                1316 + self.width / 2 - 11.0 / 2),
                        box_size=(self.length + 30, self.width + 30 + 11))
                    elems += i3.Rectangle(
                        layer=self.layer_bool,
                        center=(10000 - 725 - i * 750 + 2000 + 550,
                                1684 - self.width / 2 + 11.0 / 2),  # change
                        box_size=(self.length + 30, self.width + 30 + 11))
                    if self.double:
                        elems += i3.Rectangle(
                            layer=self.layer_bool,
                            center=(10000 - 725 - i * 750 + 2000 + 550 - 400,
                                    1316 + self.width / 2 - 11.0 / 2),
                            box_size=(self.length + 30, self.width + 30 + 11))
                        elems += i3.Rectangle(
                            layer=self.layer_bool,
                            center=(10000 - 725 - i * 750 + 2000 + 550 - 400,
                                    1684 - self.width / 2 + 11.0 / 2),
                            # change
                            box_size=(self.length + 30, self.width + 30 + 11))

            # if self.tilt_0:
            #     elems += i3.Rectangle(layer=self.layer,
            #                           center=(x0 + 6500 - 40 + 20 + 7.5, 2500),
            #                           box_size=(self.length + 40 + 15, self.width - 40 * 2))
            # else:
            #     elems += i3.Rectangle(layer=self.layer,
            #                           center=(x0 + 6500 - 40 + 20 + 5, 2500),
            #                           box_size=(self.length + 40 + 10, self.width - 40 * 2))
            #
            # if self.pillar:
            #     for i in range(7):
            #         elems += i3.Rectangle(layer=self.layer_bool,
            #                               center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 30),
            #                               box_size=(130, 140))
            #         elems += i3.Rectangle(layer=self.layer_bool, center=(
            #             10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 30),
            #                               box_size=(130, 140))

            generated1 = self.layer - self.layer_bool
            mapping = {generated1: self.layer}
            elems = i3.get_elements_for_generated_layers(elems, mapping)
            return elems
Example #9
0
class AL_NP(i3.PCell):
    _name_prefix = "AL_NP"

    # Center of the structure
    position = i3.Coord2Property(default=(0.0, 0.0))

    # Layer
    layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CONTACT.PILLAR)
    layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC)

    # Mesa parameters
    offset = i3.PositiveNumberProperty(default=20)
    # width = i3.PositiveNumberProperty(default=79)

    # pillar = i3.BoolProperty(default=False)
    reservoir = i3.BoolProperty(default=False)

    class Layout(i3.LayoutView):
        def _generate_elements(self, elems):

            # Center of the structure
            (x0, y0) = self.position
            # width2 = 338 + 15 + 15

            elems += i3.Rectangle(layer=self.layer,
                                  center=(8750 - 15 - 10 + 5, 1500),
                                  box_size=(500 - 40, 1800 - 100))

            elems += i3.Rectangle(layer=self.layer,
                                  center=(10500 - 15 - 10, 1500),
                                  box_size=(3000 + 50, 145))

            elems += i3.Rectangle(layer=self.layer,
                                  center=(8750 - 15 - 10 + 5 + 2420 - 150,
                                          1000 - 120),
                                  box_size=(2000, 500 - 40))  #extra pad

            elems += i3.Rectangle(
                layer=self.layer_bool,
                center=(8750 - 15 - 10 + 5 + 2420 - 150 + 998,
                        1000 - 120 + 620),
                box_size=(4, 145))  #extra shrink on the interface

            for i in range(4):
                elems += i3.Rectangle(layer=self.layer,
                                      center=(10000 - 725 - i * 750 + 2000 +
                                              350 + self.offset, 1316 + 72.75),
                                      box_size=(145, 77.5))
                elems += i3.Rectangle(
                    layer=self.layer,
                    center=(10000 - 725 - i * 750 + 2000 + 350 + self.offset,
                            1684 - 72.75),  # change
                    box_size=(145, 77.5))

            # Avoid solder spill on facet
            elems += i3.Rectangle(layer=self.layer_bool,
                                  center=(12000 - 20, 1500),
                                  box_size=(40, 50))
            elems += i3.Rectangle(layer=self.layer_bool,
                                  center=(12000 - 750 * 2, 1500),
                                  box_size=(80, 50))
            elems += i3.Rectangle(layer=self.layer_bool,
                                  center=(12000 - 750 * 3, 1500),
                                  box_size=(80, 50))
            elems += i3.Rectangle(layer=self.layer_bool,
                                  center=(12000 - 750 * 4, 1500),
                                  box_size=(80, 50))

            # reservoir
            if self.reservoir:
                for i in range(3):
                    elems += i3.Rectangle(layer=self.layer,
                                          center=(-750 * i + 12000 - 750,
                                                  1572.5 + 20),
                                          box_size=(149, 40))
                    elems += i3.Rectangle(layer=self.layer,
                                          center=(-750 * i + 12000 - 750,
                                                  1427.5 - 20),
                                          box_size=(149, 40))
                    elems += i3.Rectangle(layer=self.layer,
                                          center=(-750 * i + 12000 - 750,
                                                  1572.5 + 20),
                                          box_size=(149, 40))
                    elems += i3.Rectangle(layer=self.layer,
                                          center=(-750 * i + 12000 - 750,
                                                  1427.5 - 20),
                                          box_size=(149, 40))
                    elems += i3.Rectangle(layer=self.layer,
                                          center=(-750 * i + 12000 - 750,
                                                  1572.5 + 20),
                                          box_size=(149, 40))
                    elems += i3.Rectangle(layer=self.layer,
                                          center=(-750 * i + 12000 - 750,
                                                  1427.5 - 20),
                                          box_size=(149, 40))
                elems += i3.PolygonText(
                    layer=self.layer,
                    text="RE",
                    coordinate=(12000, 2600),
                    # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT),
                    font=2,
                    height=400.0)

            # Markers
            bigsquare = 16.5
            smallsquare = 11.5
            for i in range(-3, 0, 2):
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 78, 1568.75),
                                      box_size=(9, 9.5))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 49.5,
                                              1572 - 32),
                                      box_size=(9, 9))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 49.5 - 57,
                                              1572 - 32),
                                      box_size=(9, 9))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 78,
                                              1568.75 - 57.5),
                                      box_size=(9, 9.5))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75,
                                              1572.5 - 13.25),
                                      box_size=(smallsquare, smallsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 38.5,
                                              1572.5 - 13.25),
                                      box_size=(smallsquare, smallsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75,
                                              1572.5 - 13.25 - 38.5),
                                      box_size=(smallsquare, smallsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 38.5,
                                              1572.5 - 13.25 - 38.5),
                                      box_size=(smallsquare, smallsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75-80), box_size=(7, 7.5))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5, 1572 - 32-80), box_size=(7, 7))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57, 1572 - 32-80), box_size=(7, 7))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75 - 57.5-80), box_size=(7, 7.5))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-2.5, 1572.5 - 13.25-80-2.5), box_size=(bigsquare, bigsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5+2.5, 1572.5 - 13.25-80-2.5),
                #                       box_size=(bigsquare, bigsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-2.5, 1572.5 - 13.25 - 38.5-80+2.5),
                #                       box_size=(bigsquare, bigsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5+2.5, 1572.5 - 13.25 - 38.5-80+2.5),
                #                       box_size=(bigsquare, bigsquare))

                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75), box_size=(7, 7.5))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-594, 1572 - 32), box_size=(7, 7))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57-594, 1572 - 32), box_size=(7, 7))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 57.5), box_size=(7, 7.5))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-594-2.5, 1572.5 - 13.25-2.5), box_size=(bigsquare, bigsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5-594+2.5, 1572.5 - 13.25-2.5),
                #                       box_size=(bigsquare, bigsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-594-2.5, 1572.5 - 13.25 - 38.5+2.5),
                #                       box_size=(bigsquare, bigsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5-594+2.5, 1572.5 - 13.25 - 38.5+2.5),
                #                       box_size=(bigsquare, bigsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 78 - 594,
                                              1568.75 - 80),
                                      box_size=(9, 9.5))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 49.5 - 594,
                                              1572 - 32 - 80),
                                      box_size=(9, 9))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 49.5 - 57 -
                                              594, 1572 - 32 - 80),
                                      box_size=(9, 9))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 78 - 594,
                                              1568.75 - 57.5 - 80),
                                      box_size=(9, 9.5))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 594,
                                              1572.5 - 13.25 - 80),
                                      box_size=(smallsquare, smallsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 38.5 -
                                              594, 1572.5 - 13.25 - 80),
                                      box_size=(smallsquare, smallsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 594,
                                              1572.5 - 13.25 - 38.5 - 80),
                                      box_size=(smallsquare, smallsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 38.5 -
                                              594, 1572.5 - 13.25 - 38.5 - 80),
                                      box_size=(smallsquare, smallsquare))

            for i in range(-2, 1, 2):
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75), box_size=(7, 7.5))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5, 1572-32), box_size=(7, 7))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-57, 1572-32), box_size=(7, 7))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75-57.5), box_size=(7, 7.5))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75, 1572.5-13.25), box_size=(smallsquare, smallsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-38.5, 1572.5 - 13.25), box_size=(smallsquare, smallsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75, 1572.5 - 13.25-38.5), box_size=(smallsquare, smallsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-38.5, 1572.5 - 13.25-38.5), box_size=(smallsquare, smallsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 78,
                                              1568.75 - 80),
                                      box_size=(9, 9.5))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 49.5,
                                              1572 - 32 - 80),
                                      box_size=(9, 9))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 49.5 - 57,
                                              1572 - 32 - 80),
                                      box_size=(9, 9))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 78,
                                              1568.75 - 57.5 - 80),
                                      box_size=(9, 9.5))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 2.5,
                                              1572.5 - 13.25 - 80 - 2.5),
                                      box_size=(bigsquare, bigsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 38.5 +
                                              2.5, 1572.5 - 13.25 - 80 - 2.5),
                                      box_size=(bigsquare, bigsquare))
                elems += i3.Rectangle(
                    layer=self.layer_bool,
                    center=(750 * i + 12000 - 58.75 - 2.5,
                            1572.5 - 13.25 - 38.5 - 80 + 2.5),
                    box_size=(bigsquare, bigsquare))
                elems += i3.Rectangle(
                    layer=self.layer_bool,
                    center=(750 * i + 12000 - 58.75 - 38.5 + 2.5,
                            1572.5 - 13.25 - 38.5 - 80 + 2.5),
                    box_size=(bigsquare, bigsquare))

                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 78 - 594,
                                              1568.75),
                                      box_size=(9, 9.5))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 49.5 - 594,
                                              1572 - 32),
                                      box_size=(9, 9))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 49.5 - 57 -
                                              594, 1572 - 32),
                                      box_size=(9, 9))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 78 - 594,
                                              1568.75 - 57.5),
                                      box_size=(9, 9.5))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 594 -
                                              2.5, 1572.5 - 13.25 - 2.5),
                                      box_size=(bigsquare, bigsquare))
                elems += i3.Rectangle(layer=self.layer_bool,
                                      center=(750 * i + 12000 - 58.75 - 38.5 -
                                              594 + 2.5, 1572.5 - 13.25 - 2.5),
                                      box_size=(bigsquare, bigsquare))
                elems += i3.Rectangle(
                    layer=self.layer_bool,
                    center=(750 * i + 12000 - 58.75 - 594 - 2.5,
                            1572.5 - 13.25 - 38.5 + 2.5),
                    box_size=(bigsquare, bigsquare))
                elems += i3.Rectangle(
                    layer=self.layer_bool,
                    center=(750 * i + 12000 - 58.75 - 38.5 - 594 + 2.5,
                            1572.5 - 13.25 - 38.5 + 2.5),
                    box_size=(bigsquare, bigsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 80), box_size=(7, 7.5))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-594, 1572 - 32 - 80), box_size=(7, 7))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57-594, 1572 - 32 - 80), box_size=(7, 7))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 57.5 - 80), box_size=(7, 7.5))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 -594, 1572.5 - 13.25 - 80 ),
                #                       box_size=(smallsquare, smallsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5 -594, 1572.5 - 13.25 - 80 ),
                #                       box_size=(smallsquare, smallsquare))
                # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 -594, 1572.5 - 13.25 - 38.5 - 80 ),
                #                       box_size=(smallsquare, smallsquare))
                # elems += i3.Rectangle(layer=self.layer_bool,
                #                       center=(750*i+12000 - 58.75 - 38.5 -594, 1572.5 - 13.25 - 38.5 - 80 ),
                #                       box_size=(smallsquare, smallsquare))

            generated1 = self.layer - self.layer_bool
            mapping = {generated1: self.layer}
            elems = i3.get_elements_for_generated_layers(elems, mapping)
            return elems
    class Layout(i3.LayoutView):
        # specified parameters used for layout, lengths of various waveguides
        # using some default values if standard ring shape is used
        bend_radius_ring = i3.PositiveNumberProperty(default=10.,
                                                     doc="bend radius of ring")
        ring_x_straight = i3.PositiveNumberProperty(
            default=15., doc="straight between bends in x ring")
        ring_y_straight = i3.PositiveNumberProperty(
            default=25., doc="straight between bends in y ring")
        external_straights = i3.PositiveNumberProperty(
            default=10., doc="extra straight for outside structure")
        external_gap = i3.PositiveNumberProperty(
            default=0.5, doc="gap between outside waveguides and resonator")
        # external_radius = i3.PositiveNumberProperty(default=bend_radius_ring, doc="radius of outside coupler")
        use_rounding = i3.BoolProperty(default=False,
                                       doc="use non default bending algorithm")
        rounding_algorithm = i3.DefinitionProperty(
            default=SplineRoundingAlgorithm(),
            doc="secondary rounding algorithm")

        # define the layout of the internal coupler which we SRef below
        def _default_resonator(self):
            res_layout = self.cell.resonator.get_default_view(
                i3.LayoutView)  # Retrieve layout view following example

            # make the shape of the layout from the previous values. Assume (0, 0) is bottom middle!)
            # will do each corner for clarity
            # bottom_left = (-self.bend_radius_ring - self.ring_x_straight/2., 0.)
            # top_left = (-self.bend_radius_ring - self.ring_x_straight/2.,
            #             self.bend_radius_ring*2. + self.ring_y_straight)
            # top_right = (self.bend_radius_ring + self.ring_x_straight/2.,
            #              self.bend_radius_ring*2. + self.ring_y_straight)
            # bottom_right = (self.bend_radius_ring + self.ring_x_straight/2., 0.)
            # ring_shape = [bottom_left, top_left, top_right, bottom_right, bottom_left]
            # print ring_shape

            # tried to use generic round ring, but failed :P. Using ring rect instead
            # set the layout of the resonator. Stuck a bool for non default rounding algorithm
            if self.use_rounding is True:
                res_layout.set(bend_radius=self.bend_radius_ring,
                               straights=(self.ring_x_straight,
                                          self.ring_y_straight),
                               rounding_algorithm=self.rounding_algorithm)
            else:
                res_layout.set(
                    bend_radius=self.bend_radius_ring,
                    straights=(self.ring_x_straight,
                               self.ring_y_straight))  # , shape=ring_shape
            return res_layout

        # now we take the resonator which was just defined and stick it in the main *get components thing
        def _get_components(self):
            resonator = i3.SRef(name="another_res", reference=self.resonator)
            return resonator

        # setting the output shape of the access waveguides using a shape defined by ports from MMI (hopefully..)
        def _default_wgs(self):
            # bring in parts from rest of PCell Layout, used to grab positions
            resonator = self._get_components()
            wg_in_cell, wg_pass_cell = self.cell.wgs
            wg_template = self.wg_coupler_template
            wg_ring_template = self.wg_ring_template

            # using the ring radius for the external radius
            external_rad = self.bend_radius_ring
            external_str = self.external_straights

            # grabbing the position of the resonator to layout the rest of the coupler properly
            resonator_west_side = resonator.size_info().west
            resonator_south_side = resonator.size_info().south

            resonator_core_width = wg_ring_template.core_width
            resonator_clad_width = wg_ring_template.cladding_width
            coupler_core_width = wg_template.core_width

            # calculate the x position for center of input coupling waveguide when coupling, and make shape
            x_coup_spot = resonator_west_side + resonator_clad_width/2. - resonator_core_width/2. - self.external_gap \
                - coupler_core_width/2.

            # get bottom using the south and cladding information again
            bottom_left = (x_coup_spot - external_str - external_rad,
                           resonator_south_side + resonator_clad_width / 2.)
            bottom_right = (x_coup_spot,
                            resonator_south_side + resonator_clad_width / 2.)
            top_right = (x_coup_spot, bottom_right[1] + 2. * external_rad +
                         self.ring_y_straight)
            top_left = (bottom_left[0], top_right[1])

            wg_shape = [bottom_left, bottom_right, top_right, top_left]

            # now make the instance using this shape info
            wg_in_layout = wg_in_cell.get_default_view(i3.LayoutView)
            if self.use_rounding is True:
                wg_in_layout.set(trace_template=wg_template,
                                 shape=wg_shape,
                                 bend_radius=external_rad,
                                 rounding_algorithm=self.rounding_algorithm)
            else:
                wg_in_layout.set(trace_template=wg_template,
                                 shape=wg_shape,
                                 bend_radius=external_rad)

            wg_pass_layout = wg_pass_cell.get_default_view(i3.LayoutView)
            # wg_in_layout.set()
            return wg_in_layout, wg_pass_layout  # wg_ring_layout

        # A few functions for grabbing waveguide parameters to determine lengths for FSR checking
        # def wg_lengths(self):
        #     # grab the lengths of internal waveguides to use for calculations later
        #     wg_in_layout, wg_pass_layout, wg_ring_layout = self.wgs
        #
        #     straights_and_bends = wg_ring_layout.trace_length()
        #     return straights_and_bends

        def _generate_instances(self, insts):
            # includes the get components and the new waveguides
            insts += self._get_components()
            wg_in_layout, wg_pass_layout = self.wgs  #  wg_pass_layout, wg_ring_layout

            insts += i3.SRef(reference=wg_in_layout, name="wg_in")
            # insts += i3.SRef(reference=wg_pass_layout, name="wg_pass")
            # insts += i3.SRef(reference=wg_ring_layout, name="wg_ring")
            return insts

        def _generate_ports(self, prts):
            # try to reuse the output waveguides following the example and change the names, looks good
            instances = self.instances
            prts += instances["wg_in"].ports["in"].modified_copy(name="in")
            prts += instances["wg_in"].ports["out"].modified_copy(name="pass")
            return prts
    class Layout(i3.LayoutView):
        # specified parameters used for layout, lengths of various waveguides
        # using some default values if standard ring shape is used
        bend_radius_ring = i3.PositiveNumberProperty(default=10.,
                                                     doc="bend radius of ring")
        ring_x_straight = i3.PositiveNumberProperty(
            default=15., doc="straight between bends in x ring")
        ring_y_straight = i3.PositiveNumberProperty(
            default=25., doc="straight between bends in y ring")
        external_straights = i3.PositiveNumberProperty(
            default=10., doc="extra straight for outside structure")
        external_gap = i3.PositiveNumberProperty(
            default=1., doc="gap between outside waveguides and resonator")
        # external_radius = i3.PositiveNumberProperty(default=bend_radius_ring, doc="radius of outside coupler")
        rounding_algorithm = i3.DefinitionProperty(
            default=SplineRoundingAlgorithm(),
            doc="secondary rounding algorithm")

        # extra layouting for the CROW
        num_rings = i3.IntProperty(default=3, doc="number of rings")
        ring_gap = i3.PositiveNumberProperty(default=0.5,
                                             doc="gap between internal rings")

        use_gap_list = i3.BoolProperty(default=False,
                                       doc="use non default bending algorithm")
        ring_gap_list = i3.ListProperty(
            default=[], doc="list of gaps for manual swapping, default empty!")

        # define the layout of the internal coupler which we SRef below
        def _default_resonator(self):
            res_layout = self.cell.resonator.get_default_view(
                i3.LayoutView)  # Retrieve layout view following example

            # make the shape of the layout from the previous values. Assume (0, 0) is bottom middle!)
            # will do each corner for clarity
            # bottom_left = (-self.bend_radius_ring - self.ring_x_straight/2., 0.)
            # top_left = (-self.bend_radius_ring - self.ring_x_straight/2.,
            #             self.bend_radius_ring*2. + self.ring_y_straight)
            # top_right = (self.bend_radius_ring + self.ring_x_straight/2.,
            #              self.bend_radius_ring*2. + self.ring_y_straight)
            # bottom_right = (self.bend_radius_ring + self.ring_x_straight/2., 0.)
            # ring_shape = [bottom_left, top_left, top_right, bottom_right, bottom_left]
            # print ring_shape

            # tried to use generic round ring, but failed :P. Using ring rect instead
            # set the layout of the resonator. Stuck a bool for non default rounding algorithm

            res_layout.set(bend_radius=self.bend_radius_ring,
                           straights=(self.ring_x_straight,
                                      self.ring_y_straight),
                           rounding_algorithm=self.rounding_algorithm)

            return res_layout

        def _dummy_resonator(self):
            dummy_res = i3.SRef(name="just_a_dummy", reference=self.resonator)
            return dummy_res

        # make a function for determining the distance between core size and

        def _resonator_size_core_to_core(self):
            # calls the get components function and then does math on the pulled in layout
            resonator = self._dummy_resonator()
            wg_ring_template = self.wg_ring_template

            # grabbing the position of the resonator to layout the rest of the coupler properly
            resonator_west_side = resonator.size_info().west
            resonator_east_side = resonator.size_info().east

            resonator_core_width = wg_ring_template.core_width
            resonator_clad_width = wg_ring_template.cladding_width

            resonator_x_dim = (resonator_east_side -
                               resonator_west_side) - resonator_clad_width
            return resonator_x_dim

        # setting the output shape of the access waveguides using a shape defined by ports from MMI (hopefully..)
        def _default_wgs(self):
            # bring in parts from rest of PCell Layout, used dummy resonator to grab positions
            resonator = self._dummy_resonator()
            wg_in_cell, wg_pass_cell = self.cell.wgs
            wg_template = self.wg_coupler_template
            wg_ring_template = self.wg_ring_template

            # using the ring radius for the external radius
            external_rad = self.bend_radius_ring
            external_str = self.external_straights

            # grabbing the position of the resonator to layout the rest of the coupler properly
            resonator_west_side = resonator.size_info().west
            resonator_south_side = resonator.size_info().south

            resonator_core_width = wg_ring_template.core_width
            resonator_clad_width = wg_ring_template.cladding_width
            coupler_core_width = wg_template.core_width

            # calculate the x position for center of input coupling waveguide when coupling, and make shape
            x_coup_spot = resonator_west_side + resonator_clad_width/2. - resonator_core_width/2. - self.external_gap \
                - coupler_core_width/2.

            # get bottom using the south and cladding information again
            bottom_left = (x_coup_spot - external_str - external_rad,
                           resonator_south_side + resonator_clad_width / 2.)
            bottom_right = (x_coup_spot,
                            resonator_south_side + resonator_clad_width / 2.)
            top_right = (x_coup_spot, bottom_right[1] + 2. * external_rad +
                         self.ring_y_straight)
            top_left = (bottom_left[0], top_right[1])

            wg_shape = [bottom_left, bottom_right, top_right, top_left]

            # now make the instance using this shape info
            wg_in_layout = wg_in_cell.get_default_view(i3.LayoutView)

            wg_in_layout.set(trace_template=wg_template,
                             shape=wg_shape,
                             bend_radius=external_rad,
                             rounding_algorithm=self.rounding_algorithm)

            # other waveguide for reference, can put in shape or mirror later
            wg_pass_layout = wg_pass_cell.get_default_view(i3.LayoutView)
            # wg_in_layout.set()
            return wg_in_layout, wg_pass_layout  # wg_ring_layout

        # A few functions for grabbing waveguide parameters to determine lengths for FSR checking
        # def wg_lengths(self):
        #     # grab the lengths of internal waveguides to use for calculations later
        #     wg_in_layout, wg_pass_layout, wg_ring_layout = self.wgs
        #
        #     straights_and_bends = wg_ring_layout.trace_length()
        #     return straights_and_bends

        # now we take the resonator and perform multiple translations for the CROW
        def _get_components(self):
            res_x_dim = self._resonator_size_core_to_core()
            ring_gap = self.ring_gap
            ring_core_width = self.wg_ring_template.core_width
            ring_gap_list = self.ring_gap_list

            shifting_list = [0.] + ring_gap_list
            all_components = []
            # and now crank an SRef for each Ring in a loop
            for ring in range(self.num_rings):
                # will translate the original ring over to the correct position, and iterate for number of rings
                # use an if statement for external gap list or not. Need an error
                if self.use_gap_list is False:
                    this_transform = i3.Translation(
                        ((res_x_dim + ring_gap + ring_core_width) * ring, 0.))
                    this_resonator = i3.SRef(name="R_" + str(ring),
                                             reference=self.resonator,
                                             transformation=this_transform)
                    all_components.append(this_resonator)
                else:
                    # sum previous elements of the shifting list for correct relative translation
                    total_shift = sum(shifting_list[:(ring + 1)])

                    this_transform = i3.Translation(
                        ((res_x_dim + ring_core_width) * ring + total_shift,
                         0.))
                    this_resonator = i3.SRef(name="R_" + str(ring),
                                             reference=self.resonator,
                                             transformation=this_transform)
                    all_components.append(this_resonator)

            return all_components

        def _generate_instances(self, insts):
            # includes the get components and the waveguides
            the_rings = self._get_components()
            insts += the_rings
            wg_in_layout, wg_pass_layout = self.wgs  #  wg_pass_layout, wg_ring_layout
            insts += i3.SRef(reference=wg_in_layout, name="wg_in")

            # ok so now I grab the last ring from the rings and use it to determine its position
            last_ring = the_rings[-1]
            east_side_ring = last_ring.size_info().east

            # and I get the waveguide properties for ring and coupler, to give correct outside gap
            ring_core_width = self.wg_ring_template.core_width
            ring_clad_width = self.wg_ring_template.cladding_width

            bus_wg_core_width = self.wg_coupler_template.core_width
            bus_wg_clad_width = self.wg_coupler_template.cladding_width

            final_x_spot = (east_side_ring - ring_clad_width/2.) + ring_core_width/2. \
                           + self.external_gap + bus_wg_core_width/2.

            # rather than making a new waveguide we can mirror the previous structure into the final position
            # thus we need to determine the difference in the core position of the original structure
            # with the *negative* position of the final x position, and then the mirror will flip it around
            bus_core_pos = wg_in_layout.size_info(
            ).east - bus_wg_clad_width / 2.

            # now we translate the original structure to the desired negative position, and horizontally mirror around 0
            output_transformation = i3.HMirror() + i3.Translation(
                (-1. * (-final_x_spot - bus_core_pos), 0.))

            # finally we perform the SRef on the previous layout and transform it with a new name
            insts += i3.SRef(reference=wg_in_layout,
                             name="wg_out",
                             transformation=output_transformation)

            return insts

        def _generate_ports(self, prts):
            # try to reuse the output waveguides following the example and change the names, looks good
            instances = self.instances
            prts += instances["wg_in"].ports["in"].modified_copy(name="in1")
            prts += instances["wg_in"].ports["out"].modified_copy(name="in2")
            prts += instances["wg_out"].ports["in"].modified_copy(name="out1")
            prts += instances["wg_out"].ports["out"].modified_copy(name="out2")
            return prts
Example #12
0
    class Layout(Bent_Coupler_Symm.Layout):
        # booleans for bent or not bent
        in1_bent = i3.BoolProperty(default=True, doc="bending in1 or not")
        in2_bent = i3.BoolProperty(default=False, doc="bending in2 or not")
        out1_bent = i3.BoolProperty(default=False, doc="bending out1 or not")
        out2_bent = i3.BoolProperty(default=False, doc="bending out2 or not")

        # define default of tapered MMI child cell
        def _default_coupler(self):
            coupler = self.cell.coupler.get_default_view(
                i3.LayoutView)  # Retrieve layout view following example
            # coupler.set(coupler_spacing=1.0, coupler_length=10., trace_template=self.wg_template)
            return coupler

        # grabbing properties of child cell and setting appropriate transforms, by default do none
        def _get_components(self):
            coupler = i3.SRef(reference=self.coupler, name="coupler")
            return coupler

        # setting the output shape of the access waveguides using a shape defined by ports from MMI (hopefully..)
        def _default_wgs(self):

            # bring in parts from rest of PCell Layout, used to grab positions
            coupler = self._get_components()
            wg_in1_cell, wg_in2_cell, wg_out1_cell, wg_out2_cell = self.cell.wgs
            wg_template1 = self.wg_template1
            wg_template2 = self.wg_template2
            bend_radius = self.bend_radius
            # setting variable for
            round_alg = self.rounding_algorithm

            # defining bottom left waveguide, using port from MMI and bus length
            wg_in1_layout = wg_in1_cell.get_default_view(i3.LayoutView)
            in1_port_pos = coupler.ports["in1"].position
            in1_shape = [
                in1_port_pos, (in1_port_pos[0] - bend_radius, in1_port_pos[1]),
                (in1_port_pos[0] - bend_radius,
                 in1_port_pos[1] - 2. * bend_radius - self.in1_offset),
                (in1_port_pos[0] - 2. * bend_radius,
                 in1_port_pos[1] - 2. * bend_radius - self.in1_offset)
            ]
            # bool section
            in1_shape_straight = [
                in1_port_pos,
                (in1_port_pos[0] - 2. * bend_radius, in1_port_pos[1])
            ]

            if self.in1_bent is False:
                in1_arb_shape = in1_shape_straight
            else:
                in1_arb_shape = in1_shape

            wg_in1_layout.set(trace_template=wg_template1,
                              shape=in1_arb_shape,
                              rounding_algorithm=round_alg,
                              bend_radius=bend_radius)

            # repeat above for other ports, first in2
            wg_in2_layout = wg_in2_cell.get_default_view(i3.LayoutView)
            in2_port_pos = coupler.ports["in2"].position
            in2_shape = [
                in2_port_pos, (in2_port_pos[0] - bend_radius, in2_port_pos[1]),
                (in2_port_pos[0] - bend_radius,
                 in2_port_pos[1] + 2. * bend_radius + self.in2_offset),
                (in2_port_pos[0] - 2. * bend_radius,
                 in2_port_pos[1] + 2. * bend_radius + self.in2_offset)
            ]

            # bool section in2
            in2_shape_straight = [
                in2_port_pos,
                (in2_port_pos[0] - 2. * bend_radius, in2_port_pos[1])
            ]

            if self.in2_bent is False:
                in2_arb_shape = in2_shape_straight
            else:
                in2_arb_shape = in2_shape

            wg_in2_layout.set(trace_template=wg_template2,
                              shape=in2_arb_shape,
                              rounding_algorithm=round_alg,
                              bend_radius=bend_radius)

            # out1
            wg_out1_layout = wg_out1_cell.get_default_view(i3.LayoutView)
            out1_port_pos = coupler.ports["out1"].position
            out1_shape = [
                out1_port_pos,
                (out1_port_pos[0] + bend_radius, out1_port_pos[1]),
                (out1_port_pos[0] + bend_radius,
                 out1_port_pos[1] - 2. * bend_radius - self.out1_offset),
                (out1_port_pos[0] + 2. * bend_radius,
                 out1_port_pos[1] - 2. * bend_radius - self.out1_offset)
            ]

            # bool section out1
            out1_shape_straight = [
                out1_port_pos,
                (out1_port_pos[0] + 2. * bend_radius, out1_port_pos[1])
            ]

            if self.out1_bent is False:
                out1_arb_shape = out1_shape_straight
            else:
                out1_arb_shape = out1_shape

            wg_out1_layout.set(trace_template=wg_template1,
                               shape=out1_arb_shape,
                               rounding_algorithm=round_alg,
                               bend_radius=bend_radius)
            # and out2
            wg_out2_layout = wg_out2_cell.get_default_view(i3.LayoutView)
            out2_port_pos = coupler.ports["out2"].position
            out2_shape = [
                out2_port_pos,
                (out2_port_pos[0] + bend_radius, out2_port_pos[1]),
                (out2_port_pos[0] + bend_radius,
                 out2_port_pos[1] + 2. * bend_radius + self.out2_offset),
                (out2_port_pos[0] + 2. * bend_radius,
                 out2_port_pos[1] + 2. * bend_radius + self.out2_offset)
            ]

            # bool section out2
            out2_shape_straight = [
                out2_port_pos,
                (out2_port_pos[0] + 2. * bend_radius, out2_port_pos[1])
            ]

            if self.out2_bent is False:
                out2_arb_shape = out2_shape_straight
            else:
                out2_arb_shape = out2_shape

            wg_out2_layout.set(trace_template=wg_template2,
                               shape=out2_arb_shape,
                               rounding_algorithm=round_alg,
                               bend_radius=bend_radius)
            # returning layouts
            return wg_in1_layout, wg_in2_layout, wg_out1_layout, wg_out2_layout

        @i3.example_plot()
        def __example_layout(self):
            from technologies import silicon_photonics
            from picazzo3.traces.wire_wg.trace import WireWaveguideTemplate
            import ipkiss3.all as i3
            import numpy as np
            from euler_rounding_algorithm import Euler90Algorithm
            from SplittersAndCascades import Bent_Coupler_Symm
            # wg_t1: waveguide template of the south arm
            # wg_t2: waveguide template of the north arm
            # define the template, set the core waveguide width
            wg_t1 = WireWaveguideTemplate(name="south_arm")
            wg_t1.Layout(core_width=2.400,
                         cladding_width=i3.TECH.WG.CLADDING_WIDTH,
                         core_process=i3.TECH.PROCESS.WG)

            wg_t2 = WireWaveguideTemplate(name="north arm")
            wg_t2.Layout(core_width=1.500,
                         cladding_width=i3.TECH.WG.CLADDING_WIDTH,
                         core_process=i3.TECH.PROCESS.WG)
            DC = StraightDirectionalCoupler(name="Directional coupler",
                                            trace_template1=wg_t1,
                                            trace_template2=wg_t2,
                                            coupler_length=50.0)

            layout_DC = DC.Layout(coupler_spacing=10.0)

            C = Bent_Coupler(name="modal_coupler",
                             wg_template1=wg_t1,
                             wg_template2=wg_t2,
                             coupler=DC)
            # in1_bent...out2_bent booleans for bent control
            layout = C.Layout(bend_radius=30.0,
                              in1_bent=True,
                              in2_bent=True,
                              out1_bent=True,
                              out2_bent=True,
                              rounding_algorithm=ShapeRound)
            layout.visualize()
    class Layout(i3.LayoutView):

        from ipkiss.technology import get_technology
        TECH = get_technology()

        period = i3.PositiveNumberProperty(default=.3,
                                           doc="Period of sidewall grating")
        duty_cycle = i3.PositiveNumberProperty(
            default=.1,
            doc="Length of grating teeth (along periodic direction)")
        grating_amp = i3.NumberProperty(
            default=.01,
            doc=
            "Width/amplitude of grating teeth (normal to periodic direction)")
        wg_width = i3.PositiveNumberProperty(
            default=TECH.WG.CORE_WIDTH,
            doc="Width of waveguide core (if grating_amp=0 width of waveguide)"
        )
        length = i3.PositiveNumberProperty(default=100.0,
                                           doc="Length of waveguide")

        # Flag, set to True to draw grating on both sides of wg.
        both_sides = i3.BoolProperty(
            default=False, doc='set to true to draw grating on both sides')

        def validate_properties(self):
            """Check whether the combination of properties is valid."""
            if self.duty_cycle >= self.period:
                raise i3.PropertyValidationError(
                    self,
                    "Duty cycle is larger than/equal to the grating period",
                    {"duty_cyle": self.duty_cycle})

            return True

        def _generate_elements(self, elems):
            # Waveguide path
            wg_path = [(0.0, 0.0), (self.length, 0.0)]

            # Grating tooth path
            gt_path = [(0.0, 0.0), (self.duty_cycle, 0.0)]

            gap_cycle = self.period - self.duty_cycle
            numperiod = int(np.floor(self.length / self.period))

            # Add waveguide core
            elems += i3.Path(layer=i3.TECH.PPLAYER.WG.COR,
                             shape=wg_path,
                             line_width=self.wg_width)

            # Add grating teeth
            if self.grating_amp > 0.0:
                # grating amplitude has to be non-zero

                ytrans = i3.Translation(
                    (0.0, self.wg_width / 2 + self.grating_amp / 2))
                for ii in range(numperiod):
                    #Start with gap rather than tooth
                    xtrans = i3.Translation(
                        ((gap_cycle + ii * self.period), 0.0))
                    elems += i3.Path(layer=i3.TECH.PPLAYER.WG.COR,
                                     shape=gt_path,
                                     line_width=self.grating_amp,
                                     transformation=(xtrans + ytrans))

                    # draw bottom grating if desired
                    if self.both_sides == True:
                        elems += i3.Path(layer=i3.TECH.PPLAYER.WG.COR,
                                         shape=gt_path,
                                         line_width=self.grating_amp,
                                         transformation=(xtrans - ytrans))

            # Add block layers
            import block_layers as bl
            block_layers = bl.layers
            block_widths = bl.widths
            for ii in range(len(block_layers)):
                elems += i3.Path(layer=block_layers[ii],
                                 shape=wg_path,
                                 line_width=self.wg_width +
                                 2 * self.grating_amp + 2 * block_widths[ii])

            return elems

        def _generate_ports(self, ports):
            # ports += i3.OpticalPort(name="in", position=(0.0, 0.0), angle=180.0,
            #                         trace_template=StripWgTemplate().Layout(core_width=self.wg_width))
            # ports += i3.OpticalPort(name="out", position=(self.length, 0.0), angle=0.0,
            #                         trace_template=StripWgTemplate().Layout(core_width=self.wg_width))

            ports += i3.OpticalPort(name="in",
                                    position=(0.0, 0.0),
                                    angle=180.0)
            ports += i3.OpticalPort(name="out",
                                    position=(self.length, 0.0),
                                    angle=0.0)

            return ports