Beispiel #1
0
    def produce_impl(self):

        from SiEPIC.utils import arc_xy, arc_bezier, angle_vector, angle_b_vectors, inner_angle_b_vectors, translate_from_normal
        from math import cos, sin, pi, sqrt
        import pya
        from SiEPIC.extend import to_itype

        print("GSiP.Wireguide")

        TECHNOLOGY = get_technology_by_name(
            'GSiP') if op_tag == "GUI" else Tech.load_from_xml(
                lyp_filepath).layers
        dbu = self.layout.dbu
        wg_width = to_itype(self.width, dbu)
        path = self.path.to_itype(dbu)

        if not (len(self.layers) == len(self.widths)
                and len(self.layers) == len(self.offsets)
                and len(self.offsets) == len(self.widths)):
            raise Exception(
                "There must be an equal number of layers, widths and offsets")
        path.unique_points()
        turn = 0
        for lr in range(0, len(self.layers)):
            layer = self.layout.layer(TECHNOLOGY[self.layers[lr]])

            width = to_itype(self.widths[lr], dbu)
            offset = to_itype(self.offsets[lr], dbu)

            pts = path.get_points()
            wg_pts = [pts[0]]
            for i in range(1, len(pts) - 1):
                turn = ((angle_b_vectors(pts[i] - pts[i - 1], pts[i + 1] -
                                         pts[i]) + 90) % 360 - 90) / 90
                dis1 = pts[i].distance(pts[i - 1])
                dis2 = pts[i].distance(pts[i + 1])
                angle = angle_vector(pts[i] - pts[i - 1]) / 90
                pt_radius = self.radius
                # determine the radius, based on how much space is available
                if len(pts) == 3:
                    pt_radius = min(dis1, dis2, pt_radius)
                else:
                    if i == 1:
                        if dis1 <= pt_radius:
                            pt_radius = dis1
                    elif dis1 < 2 * pt_radius:
                        pt_radius = dis1 / 2
                    if i == len(pts) - 2:
                        if dis2 <= pt_radius:
                            pt_radius = dis2
                    elif dis2 < 2 * pt_radius:
                        pt_radius = dis2 / 2
                # wireguide bends:
                if (self.adiab):
                    wg_pts += Path(
                        arc_bezier(
                            pt_radius,
                            270,
                            270 + inner_angle_b_vectors(
                                pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                            self.bezier,
                            DevRec='DevRec' in self.layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()
                else:
                    wg_pts += Path(
                        arc_xy(-pt_radius,
                               pt_radius,
                               pt_radius,
                               270,
                               270 + inner_angle_b_vectors(
                                   pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                               DevRec='DevRec' in self.layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()
            wg_pts += [pts[-1]]
            wg_pts = pya.Path(wg_pts, 0).unique_points().get_points()
            wg_polygon = Path(wg_pts, wg_width)
            self.cell.shapes(layer).insert(wg_polygon)  # insert the wireguide

            #if self.layout.layer(TECHNOLOGY['Wireguide']) == layer:
            waveguide_length = wg_polygon.area() / self.width * dbu**2

        pts = path.get_points()
        LayerPinRecN = self.layout.layer(TECHNOLOGY['PinRecM'])

        # insert pins to wireguide
        t1 = Trans(angle_vector(pts[0] - pts[1]) / 90, False, pts[0])
        self.cell.shapes(LayerPinRecN).insert(
            Path([Point(-50, 0), Point(50, 0)], wg_width).transformed(t1))
        self.cell.shapes(LayerPinRecN).insert(Text("pin1", t1, 0.3 / dbu, -1))

        t = Trans(angle_vector(pts[-1] - pts[-2]) / 90, False, pts[-1])
        self.cell.shapes(LayerPinRecN).insert(
            Path([Point(-50, 0), Point(50, 0)], wg_width).transformed(t))
        self.cell.shapes(LayerPinRecN).insert(Text("pin2", t, 0.3 / dbu, -1))

        LayerDevRecN = self.layout.layer(TECHNOLOGY['DevRec'])

        # Compact model information
        angle_vec = angle_vector(pts[0] - pts[1]) / 90
        halign = 0  # left
        angle = 0
        pt2 = pts[0]
        pt3 = pts[0]
        if angle_vec == 0:  # horizontal
            halign = 2  # right
            angle = 0
            pt2 = pts[0] + Point(0, wg_width)
            pt3 = pts[0] + Point(0, -wg_width)
        if angle_vec == 2:  # horizontal
            halign = 0  # left
            angle = 0
            pt2 = pts[0] + Point(0, wg_width)
            pt3 = pts[0] + Point(0, -wg_width)
        if angle_vec == 1:  # vertical
            halign = 2  # right
            angle = 1
            pt2 = pts[0] + Point(wg_width, 0)
            pt3 = pts[0] + Point(-wg_width, 0)
        if angle_vec == -1:  # vertical
            halign = 0  # left
            angle = 1
            pt2 = pts[0] + Point(wg_width, 0)
            pt3 = pts[0] + Point(-wg_width, 0)
Beispiel #2
0
def layout_waveguide2(TECHNOLOGY, layout, cell, layers, widths, offsets, pts, radius, adiab, bezier):
  '''
    Create a waveguide, in a specific technology
    inputs
    - TECHNOLOGY, layout, cell:
        from SiEPIC.utils import get_layout_variables
        TECHNOLOGY, lv, layout, cell = get_layout_variables()
    - layers: list of text names, e.g., ['Waveguide']
    - widths: list of floats in units Microns, e.g., [0.50]
    - offsets: list of floats in units Microns, e.g., [0]
    - pts: a list of pya.Points, e.g. 
        L=15/dbu
        pts = [Point(0,0), Point(L,0), Point(L,L)]
    - radius: in Microns, e.g., 5
    - adiab: 1 = Bezier curve, 0 = radial bend (arc)
    - bezier: the bezier parameter, between 0 and 0.45 (almost a radial bend)

    Note: bezier parameters need to be simulated and optimized, and will depend on 
        wavelength, polarization, width, etc.  TM and rib waveguides don't benefit from bezier curves
        most useful for TE 
  '''
  from SiEPIC.utils import arc_xy, arc_bezier, angle_vector, angle_b_vectors, inner_angle_b_vectors, translate_from_normal
  from SiEPIC.extend import to_itype
  from pya import Path, Polygon, Trans
  dbu = layout.dbu

  width=widths[0]
  turn=0
  waveguide_length = 0
  for lr in range(0, len(layers)):
    wg_pts = [pts[0]]
    layer = layout.layer(TECHNOLOGY[layers[lr]])
    width = to_itype(widths[lr],dbu)
    offset = to_itype(offsets[lr],dbu)
    for i in range(1,len(pts)-1):
      turn = ((angle_b_vectors(pts[i]-pts[i-1],pts[i+1]-pts[i])+90)%360-90)/90
      dis1 = pts[i].distance(pts[i-1])
      dis2 = pts[i].distance(pts[i+1])
      angle = angle_vector(pts[i]-pts[i-1])/90
      pt_radius = to_itype(radius,dbu)
      # determine the radius, based on how much space is available
      if len(pts)==3:
        pt_radius = min (dis1, dis2, pt_radius)
      else:
        if i==1:
          if dis1 <= pt_radius:
            pt_radius = dis1
        elif dis1 < 2*pt_radius:
          pt_radius = dis1/2
        if i==len(pts)-2:
          if dis2 <= pt_radius:
            pt_radius = dis2
        elif dis2 < 2*pt_radius:
          pt_radius = dis2/2
      # waveguide bends:
      if abs(turn)==1:
        if(adiab):
          wg_pts += Path(arc_bezier(pt_radius, 270, 270 + inner_angle_b_vectors(pts[i-1]-pts[i], pts[i+1]-pts[i]), bezier, DevRec='DevRec' in layers[lr]), 0).transformed(Trans(angle, turn < 0, pts[i])).get_points()
        else:
          wg_pts += Path(arc_xy(-pt_radius, pt_radius, pt_radius, 270, 270 + inner_angle_b_vectors(pts[i-1]-pts[i], pts[i+1]-pts[i]),DevRec='DevRec' in layers[lr]), 0).transformed(Trans(angle, turn < 0, pts[i])).get_points()
        
    wg_pts += [pts[-1]]
    wg_pts = pya.Path(wg_pts, 0).unique_points().get_points()
    wg_polygon = Polygon(translate_from_normal(wg_pts, width/2 + (offset if turn > 0 else - offset))+translate_from_normal(wg_pts, -width/2 + (offset if turn > 0 else - offset))[::-1])
    cell.shapes(layer).insert(wg_polygon)
  
    if layout.layer(TECHNOLOGY['Waveguide']) == layer:
      waveguide_length = wg_polygon.area() / width * dbu
  return waveguide_length
Beispiel #3
0
def layout_waveguide2(TECHNOLOGY, layout, cell, layers, widths, offsets, pts,
                      radius, adiab, bezier):
    from SiEPIC.utils import arc_xy, arc_bezier, angle_vector, angle_b_vectors, inner_angle_b_vectors, translate_from_normal
    from SiEPIC.extend import to_itype
    from pya import Path, Polygon, Trans
    dbu = layout.dbu

    if 'Errors' in TECHNOLOGY:
        error_layer = layout.layer(TECHNOLOGY['Errors'])
    else:
        error_layer = None

    width = widths[0]
    turn = 0
    waveguide_length = 0
    for lr in range(0, len(layers)):
        wg_pts = [pts[0]]
        layer = layout.layer(TECHNOLOGY[layers[lr]])
        width = to_itype(widths[lr], dbu)
        offset = to_itype(offsets[lr], dbu)
        for i in range(1, len(pts) - 1):
            turn = (
                (angle_b_vectors(pts[i] - pts[i - 1], pts[i + 1] - pts[i]) +
                 90) % 360 - 90) / 90
            dis1 = pts[i].distance(pts[i - 1])
            dis2 = pts[i].distance(pts[i + 1])
            angle = angle_vector(pts[i] - pts[i - 1]) / 90
            pt_radius = to_itype(radius, dbu)
            error_seg1 = False
            error_seg2 = False
            # determine the radius, based on how much space is available
            if len(pts) == 3:
                # simple corner, limit radius by the two edges
                if dis1 < pt_radius:
                    error_seg1 = True
                if dis2 < pt_radius:
                    error_seg2 = True
                pt_radius = min(dis1, dis2, pt_radius)
            else:
                if i == 1:
                    # first corner, limit radius by first edge, or 1/2 of second one
                    if dis1 < pt_radius:
                        error_seg1 = True
                    if dis2 / 2 < pt_radius:
                        error_seg2 = True
                    pt_radius = min(dis1, dis2 / 2, pt_radius)
                elif i == len(pts) - 2:
                    # last corner, limit radius by second edge, or 1/2 of first one
                    if dis1 / 2 < pt_radius:
                        error_seg1 = True
                    if dis2 < pt_radius:
                        error_seg2 = True
                    pt_radius = min(dis1 / 2, dis2, pt_radius)
                else:
                    if dis1 / 2 < pt_radius:
                        error_seg1 = True
                    if dis2 / 2 < pt_radius:
                        error_seg2 = True
                    pt_radius = min(dis1 / 2, dis2 / 2, pt_radius)

            if error_seg1 or error_seg2:
                if not error_layer:
                    # we have an error, but no Error layer
                    print('- SiEPIC:layout_waveguide2: missing Error layer')
                # and pt_radius < to_itype(radius,dbu):
                elif layer == layout.layer(TECHNOLOGY['Waveguide']):
                    # add an error polygon to flag the incorrect bend
                    if error_seg1:
                        error_pts = pya.Path([pts[i - 1], pts[i]], width)
                        cell.shapes(error_layer).insert(error_pts)
                    if error_seg2:
                        error_pts = pya.Path([pts[i], pts[i + 1]], width)
                        cell.shapes(error_layer).insert(error_pts)
    #                error_pts = pya.Path([pts[i-1], pts[i], pts[i+1]], width)
    #                cell.shapes(error_layer).insert(error_pts)
    # waveguide bends:
            if abs(turn) == 1:
                if (adiab):
                    wg_pts += Path(
                        arc_bezier(
                            pt_radius,
                            270,
                            270 + inner_angle_b_vectors(
                                pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                            float(bezier),
                            DevRec='DevRec' in layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()
                else:
                    wg_pts += Path(
                        arc_xy(-pt_radius,
                               pt_radius,
                               pt_radius,
                               270,
                               270 + inner_angle_b_vectors(
                                   pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                               DevRec='DevRec' in layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()

        wg_pts += [pts[-1]]
        wg_pts = pya.Path(wg_pts, 0).unique_points().get_points()
        wg_polygon = Polygon(
            translate_from_normal(
                wg_pts, width / 2 + (offset if turn > 0 else -offset)) +
            translate_from_normal(
                wg_pts, -width / 2 + (offset if turn > 0 else -offset))[::-1])
        cell.shapes(layer).insert(wg_polygon)

        if layout.layer(TECHNOLOGY['Waveguide']) == layer:
            waveguide_length = wg_polygon.area() / width * dbu

    return waveguide_length
Beispiel #4
0
def layout_waveguide2(TECHNOLOGY, layout, cell, layers, widths, offsets, pts,
                      radius, adiab, bezier):
    from SiEPIC.utils import arc_xy, arc_bezier, angle_vector, angle_b_vectors, inner_angle_b_vectors, translate_from_normal
    from SiEPIC.extend import to_itype
    from pya import Path, Polygon, Trans
    dbu = layout.dbu

    width = widths[0]
    turn = 0
    waveguide_length = 0
    for lr in range(0, len(layers)):
        wg_pts = [pts[0]]
        layer = layout.layer(TECHNOLOGY[layers[lr]])
        width = to_itype(widths[lr], dbu)
        offset = to_itype(offsets[lr], dbu)
        for i in range(1, len(pts) - 1):
            turn = (
                (angle_b_vectors(pts[i] - pts[i - 1], pts[i + 1] - pts[i]) +
                 90) % 360 - 90) / 90
            dis1 = pts[i].distance(pts[i - 1])
            dis2 = pts[i].distance(pts[i + 1])
            angle = angle_vector(pts[i] - pts[i - 1]) / 90
            pt_radius = to_itype(radius, dbu)
            # determine the radius, based on how much space is available
            if len(pts) == 3:
                pt_radius = min(dis1, dis2, pt_radius)
            else:
                if i == 1:
                    if dis1 <= pt_radius:
                        pt_radius = dis1
                elif dis1 < 2 * pt_radius:
                    pt_radius = dis1 / 2
                if i == len(pts) - 2:
                    if dis2 <= pt_radius:
                        pt_radius = dis2
                elif dis2 < 2 * pt_radius:
                    pt_radius = dis2 / 2
            # waveguide bends:
            if abs(turn) == 1:
                if (adiab):
                    wg_pts += Path(
                        arc_bezier(
                            pt_radius,
                            270,
                            270 + inner_angle_b_vectors(
                                pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                            float(bezier),
                            DevRec='DevRec' in layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()
                else:
                    wg_pts += Path(
                        arc_xy(-pt_radius,
                               pt_radius,
                               pt_radius,
                               270,
                               270 + inner_angle_b_vectors(
                                   pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                               DevRec='DevRec' in layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()

        wg_pts += [pts[-1]]
        wg_pts = pya.Path(wg_pts, 0).unique_points().get_points()
        wg_polygon = Polygon(
            translate_from_normal(
                wg_pts, width / 2 + (offset if turn > 0 else -offset)) +
            translate_from_normal(
                wg_pts, -width / 2 + (offset if turn > 0 else -offset))[::-1])
        cell.shapes(layer).insert(wg_polygon)

        if layout.layer(TECHNOLOGY['Waveguide']) == layer:
            waveguide_length = wg_polygon.area() / width * dbu
    return waveguide_length
Beispiel #5
0
    def produce_impl(self):
        # This is the main part of the implementation: create the layout

        from math import pi, cos, sin
        from SiEPIC.utils import arc_wg, arc_wg_xy, arc_xy
        from SiEPIC._globals import PIN_LENGTH
        from SiEPIC.extend import to_itype, to_dtype

        # fetch the parameters
        dbu = self.layout.dbu
        ly = self.layout
        shapes = self.cell.shapes

        LayerSiN = ly.layer(self.silayer)
        LayerSiRibN = ly.layer(self.siriblayer)
        LayerNN = ly.layer(self.nlayer)
        LayerNPPN = ly.layer(self.npplayer)
        LayerVCN = ly.layer(self.vclayer)
        LayerMN = ly.layer(self.mlayer)
        LayerPinRecN = ly.layer(self.pinrec)
        LayerDevRecN = ly.layer(self.devrec)
        TextLayerN = ly.layer(self.textl)

        w = to_itype(self.w, dbu)
        r = to_itype(self.r, dbu)
        g = to_itype(self.g, dbu)

        n_w = to_itype(self.n_w, dbu)
        npp_si = to_itype(self.npp_si, dbu)
        npp_w = to_itype(self.npp_w, dbu)
        theta_start = self.n_theta_start
        theta_stop = self.n_theta_stop

        vc_cw = to_itype(self.vc_cw, dbu)
        vc_aw = to_itype(self.vc_aw, dbu)
        overlay_ebl = to_itype(self.overlay_ebl, dbu)

        m_cw = to_itype(self.m_cw, dbu)
        m_aw = to_itype(self.m_aw, dbu)
        x = 0
        y = 0

        #draw ring
        self.cell.shapes(LayerSiN).insert(arc_wg_xy(x, y, r, w, 0, 360))

        #draw bus waveguides
        #bottom waveguide
        xtop = -2 / 3 * r
        ytop = -1 * (r + g + w / 2)
        xbottom = 4 / 3 * r
        ybottom = ytop - w
        wg1 = Box(xtop, ytop, xbottom, ybottom)
        shapes(LayerSiN).insert(wg1)
        #left waveguide
        wg1 = Box(ytop, xtop, ybottom, xbottom)
        shapes(LayerSiN).insert(wg1)

        # Pins on the bottom waveguide side:
        pin = Path([
            Point(xtop + PIN_LENGTH, ytop - w / 2),
            Point(xtop - PIN_LENGTH, ytop - w / 2)
        ], w)
        shapes(LayerPinRecN).insert(pin)
        text = Text("pin1", Trans(Trans.R0, xtop, ytop - w / 2))
        shape = shapes(LayerPinRecN).insert(text)
        shape.text_size = 0.4 / dbu

        pin = Path([
            Point(xbottom - PIN_LENGTH, ytop - w / 2),
            Point(xbottom + PIN_LENGTH, ytop - w / 2)
        ], w)
        shapes(LayerPinRecN).insert(pin)
        text = Text("pin2", Trans(Trans.R0, xbottom, ytop - w / 2))
        shape = shapes(LayerPinRecN).insert(text)
        shape.text_size = 0.4 / dbu

        # Pins on the left waveguide side:
        pin = Path([
            Point(ytop - w / 2, xtop + PIN_LENGTH),
            Point(ytop - w / 2, xtop - PIN_LENGTH)
        ], w)
        shapes(LayerPinRecN).insert(pin)
        text = Text("pin3", Trans(Trans.R0, ytop - w / 2, xtop))
        shape = shapes(LayerPinRecN).insert(text)
        shape.text_size = 0.4 / dbu

        pin = Path([
            Point(ybottom + w / 2, xbottom - PIN_LENGTH),
            Point(ybottom + w / 2, xbottom + PIN_LENGTH)
        ], w)
        shapes(LayerPinRecN).insert(pin)
        text = Text("pin4", Trans(Trans.R0, ybottom + w / 2, xbottom))
        shape = shapes(LayerPinRecN).insert(text)
        shape.text_size = 0.4 / dbu

        #draw N
        arc_pts = arc_xy(x, y, n_w, theta_start, theta_stop)
        arc_pts.append(pya.Point.from_dpoint(pya.DPoint(
            0, 0)))  #adding center point for polygon
        shapes(LayerNN).insert(pya.Polygon(arc_pts))

        #draw NPP
        #center
        arc_pts = arc_xy(x, y, r - npp_si - w / 2, 0, 360)
        arc_pts.append(pya.Point.from_dpoint(pya.DPoint(
            0, 0)))  #adding center point for polygon
        shapes(LayerNPPN).insert(pya.Polygon(arc_pts))
        #outer donut
        shapes(LayerNPPN).insert(
            arc_wg_xy(x, y, r + w / 2 + npp_si + npp_w / 2, npp_w, theta_start,
                      theta_stop))

        #draw via
        #center
        arc_pts = arc_xy(x, y, vc_cw, 0, 360)
        arc_pts.append(pya.Point.from_dpoint(pya.DPoint(
            0, 0)))  #adding center point for polygon
        shapes(LayerVCN).insert(pya.Polygon(arc_pts))

        #outer donut
        shapes(LayerVCN).insert(
            arc_wg_xy(x, y, 4 / dbu + r + npp_w / 2, vc_aw, theta_start + 10,
                      theta_stop - 10))

        #draw metal
        #center
        arc_pts = arc_xy(x, y, m_cw, 0, 360)
        arc_pts.append(pya.Point.from_dpoint(pya.DPoint(
            0, 0)))  #adding center point for polygon
        shapes(LayerMN).insert(pya.Polygon(arc_pts))
        #outer donut
        shapes(LayerMN).insert(
            arc_wg_xy(x, y, 4 / dbu + r + npp_w / 2, m_aw, theta_start,
                      theta_stop))

        #devrec layer
        xtop = -2 / 3 * r
        ytop = -1 * (r + g + w)
        xbottom = 4 / 3 * r
        ybottom = ytop
        dev_array = [
            Point(ytop + 3.5 * w, xbottom + npp_w),
            Point(ytop + 3.5 * w, xbottom),
            Point(ytop - 3.5 * w, xbottom),
            Point(ytop - 3.5 * w, xtop),
            Point(ytop + 3.5 * w, xtop),
            Point(xtop, ybottom + 3.5 * w),
            Point(xtop, ybottom - 3 * w),
            Point(xbottom, ybottom - 3.5 * w),
            Point(xbottom, ybottom + 3.5 * w),
            Point(xbottom + npp_w, ybottom + 3.5 * w),
            Point(xbottom + npp_w, xbottom + npp_w)
        ]

        shapes(LayerDevRecN).insert(pya.Polygon(dev_array))

        if self.io_wg_type == 0:  # strip converter
            taper_long = to_itype(10, dbu)
            taper_short = to_itype(3, dbu)
            dev_array = [
                Point(ytop + 3.5 * w, xbottom + npp_w),
                Point(ytop + 3.5 * w, xbottom - taper_long),
                Point(ytop + 2.5 * w, xbottom - taper_long),
                Point(ytop + w / 2 - overlay_ebl * 2, xbottom),
                Point(ytop - w / 2 + overlay_ebl * 2, xbottom),
                Point(ytop - 2.5 * w, xbottom - taper_long),
                Point(ytop - 3.5 * w, xbottom - taper_long),
                Point(ytop - 3.5 * w, xtop + taper_short),
                Point(ytop - 1.5 * w, xtop + taper_short),
                Point(ytop - w / 2 + overlay_ebl * 2, xtop),
                Point(ytop + w / 2 - overlay_ebl * 2, xtop),
                Point(ytop + 1.5 * w, xtop + taper_short),
                Point(ytop + 3.5 * w, xtop + taper_short),
                Point((ytop + 3.5 * w + xtop) / 2,
                      (xtop + ybottom + 3.5 * w) / 2),
                Point(xtop + taper_short, ybottom + 3.5 * w),
                Point(xtop + taper_short, ybottom + 1.5 * w),
                Point(xtop, ybottom + w / 2 - overlay_ebl * 2),
                Point(xtop, ybottom - w / 2 + overlay_ebl * 2),
                Point(xtop + taper_short, ybottom - 1.5 * w),
                Point(xtop + taper_short, ybottom - 3.5 * w),
                Point(xbottom - taper_long, ybottom - 3.5 * w),
                Point(xbottom - taper_long, ybottom - 2.5 * w),
                Point(xbottom, ybottom - w / 2 + overlay_ebl * 2),
                Point(xbottom, ybottom + w / 2 - overlay_ebl * 2),
                Point(xbottom - taper_long, ybottom + 2.5 * w),
                Point(xbottom - taper_long, ybottom + 3.5 * w),
                Point(xbottom + npp_w, ybottom + 3.5 * w),
                Point(xbottom + npp_w, xbottom + npp_w)
            ]
        # Si rib layer
        shapes(LayerSiRibN).insert(pya.Polygon(dev_array))

        t = Trans(Trans.R0, 0, 0)
        text = Text('Component=ebeam_irph_mrr', t)
        shape = shapes(LayerDevRecN).insert(text)
        shape.text_size = self.r * 0.07 / dbu

        print("Done drawing the layout for - ebeam_IRPH_MRR: %.3f-%g" %
              (self.r, self.g))