Пример #1
0
def connect_lineShape(cell, pos_start, len):
    path = gdspy.Path(w_wg, pos_start)
    path.segment(len, **layer_FETCH_COR)
    cell.add(path)
    path = gdspy.Path(w_wg_cld, pos_start)
    path.segment(len, **layer_FETCH_CLD)
    cell.add(path)
Пример #2
0
def Heater(l_heater2):
    # define  heater
    w_heater = 3
    w_port = 10
    w_wire = w_port * 2
    cell = lib.new_cell('heater')
    # add middle long rect
    heater = gdspy.Rectangle((0, w_heater / 2), (l_heater2, -w_heater / 2),
                             **layer_heater)
    cell.add(heater)
    # add left rect and wire
    heater = gdspy.Rectangle((-w_port / 2, w_port / 2),
                             (w_port / 2, -w_port / 2), **layer_heater)
    cell.add(heater)
    heater = gdspy.Rectangle((-w_wire / 2, w_wire / 2),
                             (w_wire / 2, -w_wire / 2), **layer_wire)
    cell.add(heater)
    # add right rect and wire
    heater = gdspy.Rectangle((l_heater2 - w_port / 2, w_port / 2),
                             (l_heater2 + w_port / 2, -w_port / 2),
                             **layer_heater)
    cell.add(heater)
    heater = gdspy.Rectangle((l_heater2 - w_wire / 2, w_wire / 2),
                             (l_heater2 + w_wire / 2, -w_wire / 2),
                             **layer_wire)
    cell.add(heater)

    path1 = gdspy.Path(w_wg)
    path1.segment(l_heater2)
    path2 = gdspy.Path(w_wg_cld)
    path2.segment(l_heater2)
    cell.add(gdspy.boolean(path2, path1, 'xor', **layer_FETCH_COR))

    return cell
Пример #3
0
 def endgap(self):
     gapwid = self.gapwid
     tracewid = self.tracewid
     if (self.x == self.paths[0].x) & (self.y == self.paths[0].y):
         dirction = self.paths[0].direction
         endctrpt = (self.paths[0].x, self.paths[0].y)
         rightend = addtup(
             addtup(
                 endctrpt,
                 scalartup(0.5 * gapwid, (numpy.cos(dirction + numpy.pi),
                                          numpy.sin(dirction + numpy.pi)))),
             scalartup(0.5 * (tracewid + 2 * gapwid),
                       (numpy.cos(dirction - numpy.pi / 2),
                        numpy.sin(dirction - numpy.pi / 2))))
         endcap = gdspy.Path(gapwid, rightend)
         endcap.segment(tracewid + 2 * gapwid, dirction + numpy.pi / 2)
         self.paths.append(endcap)
     else:
         dirction = self.paths[0].direction
         endctrpt = (self.paths[0].x, self.paths[0].y)
         rightend = addtup(
             addtup(
                 endctrpt,
                 scalartup(0.5 * gapwid,
                           (numpy.cos(dirction), numpy.sin(dirction)))),
             scalartup(0.5 * (tracewid + 2 * gapwid),
                       (numpy.cos(dirction - numpy.pi / 2),
                        numpy.sin(dirction - numpy.pi / 2))))
         endcap = gdspy.Path(gapwid, rightend)
         endcap.segment(tracewid + 2 * gapwid, dirction + numpy.pi / 2)
         self.paths.append(endcap)
Пример #4
0
 def __init__(self,
              leaddist,
              leadlen,
              leadwid,
              squidheight,
              layer=0,
              datatype=1):
     self.spec_side = {'layer': layer, 'datatype': datatype}
     self.spec_mid = {'layer': layer + 1, 'datatype': datatype}
     self.LeadDist = leaddist
     self.LeadWid = leadwid
     self.SquidHeight = squidheight
     self.LeadLen = leadlen
     midlead = gdspy.Path(leadwid, (0, 0))
     midlead.segment(leadlen, -numpy.pi / 2, **(self.spec_mid))
     midlead.segment(leadlen,
                     -numpy.pi / 2,
                     final_width=0,
                     **(self.spec_mid))
     sideleads = gdspy.Path(leadwid, (0, -squidheight),
                            number_of_paths=2,
                            distance=leaddist)
     sideleads.segment(leadlen, numpy.pi / 2, **(self.spec_side))
     sideleads.segment(leadlen,
                       numpy.pi / 2,
                       final_width=0,
                       **(self.spec_side))
     self.paths = [midlead, sideleads]
Пример #5
0
    def __build_cell(self):
        # Sequentially build all the geometric shapes using gdspy path functions
        # for waveguide, then add it to the Cell

        # Add waveguide s-bend
        wg = gdspy.Path(self.wgt.wg_width, (0, 0))
        wg.parametric(
            self.__sine_function,
            tolerance=self.wgt.grid / 2.0,
            max_points=199,
            **self.wg_spec
        )
        self.add(wg)

        # Add cladding s-bend
        for i in range(len(self.wgt.waveguide_stack) - 1):
            cur_width = self.wgt.waveguide_stack[i + 1][0]
            cur_spec = {
                "layer": self.wgt.waveguide_stack[i + 1][1][0],
                "datatype": self.wgt.waveguide_stack[i + 1][1][1],
            }

            clad = gdspy.Path(cur_width, (0, 0))
            clad.parametric(
                self.__sine_function,
                tolerance=self.wgt.grid / 2.0,
                max_points=199,
                **cur_spec
            )
            self.add(clad)
Пример #6
0
def DC(lib, cellName='DC', l_Coupler=20, spacing=0.6, radius_bend=10, l_ver=10, w_wg=0.5):
    l_PortIn = 10
    cell = lib.new_cell(cellName)
    
    path_dc = gdspy.Path(w_wg, (0,0))
    path_dc.segment(l_PortIn)
    path_dc.turn(radius_bend,'r')
    path_dc.segment(l_ver)
    path_dc.turn(radius_bend,'l')
    path_dc.segment(l_Coupler)
    path_dc.turn(radius_bend,'l')
    path_dc.segment(l_ver)
    path_dc.turn(radius_bend,'r')
    path_dc.segment(l_PortIn)
    cell.add(path_dc)

    path_dc = gdspy.Path(w_wg, (0, -(l_ver*2+radius_bend*4+spacing)))
    path_dc.segment(l_PortIn)
    path_dc.turn(radius_bend,'l')
    path_dc.segment(l_ver)
    path_dc.turn(radius_bend,'r')
    path_dc.segment(l_Coupler)
    path_dc.turn(radius_bend,'r')
    path_dc.segment(l_ver)
    path_dc.turn(radius_bend,'l')
    path_dc.segment(l_PortIn)
    cell.add(path_dc)

    return cell
Пример #7
0
    def __build_cell(self):
        # Sequentially build all the geometric shapes using gdspy path functions
        # then add it to the Cell
        num_teeth = int(self.length // self.period)
        """ Create a straight grating GratingCoupler
        """
        gap = self.period - (self.period * self.dc)
        path = gdspy.Path(self.wgt.wg_width, (0, 0))
        path.segment(self.taper_length,
                     direction="+x",
                     final_width=self.width,
                     **self.wg_spec)
        teeth = gdspy.L1Path((
            gap + self.taper_length + 0.5 *
            (num_teeth - 1 + self.dc) * self.period,
            -0.5 * self.width,
        ), "+y", self.period * self.dc, [self.width], [], num_teeth,
                             self.period, **self.wg_spec)

        clad_path = gdspy.Path(self.wgt.wg_width + 2 * self.wgt.clad_width,
                               (0, 0))
        clad_path.segment(self.taper_length,
                          direction="+x",
                          final_width=self.width + 2 * self.wgt.clad_width,
                          **self.clad_spec)
        clad_path.segment(self.length, direction="+x", **self.clad_spec)

        self.add(teeth)
        self.add(path)
        self.add(clad_path)
Пример #8
0
def spiral(cell, w=0.5, pitch=2, r_min=10, r_max=40):
    """ 
    cell: is the reference of cell \n
    w is the width of waveguide \n
    pitch is the min distance between two waveguides. \n

    """
    path1 = gdspy.Path(w, (0, 0))
    path2 = gdspy.Path(w, (0, 0))
    path3 = gdspy.Path(w, (-r_min, 0))

    a = r_min
    k = r_max - r_min
    N = k/pitch
    

    def spiral1(u):
        theta = N * numpy.pi * u
        r = a + k*theta/( N * numpy.pi)
        x = r * numpy.cos(theta)
        y = r * numpy.sin(theta)
        return (x, y)

    def spiral2(u):
        theta = (N+1) * numpy.pi * u
        r = -( a + k*theta/( N * numpy.pi) )
        x = r * numpy.cos(theta)
        y = r * numpy.sin(theta)
        return (x, y)

    def dspiral_dt(u):
        theta = N * numpy.pi * u
        dx_dt = -numpy.sin(theta)
        dy_dt = numpy.cos(theta)
        # dx_dt = k*numpy.cos(theta) - (a + k*u)*N*numpy.pi*numpy.sin(theta)
        # dy_dt = k*numpy.sin(theta) + (a + k*u)*N*numpy.pi*numpy.cos(theta)
        return (dx_dt, dy_dt)
    
    def dspiral_dt2(u):
        theta = (N+1) * numpy.pi * u
        dx_dt = -numpy.sin(theta)
        dy_dt = numpy.cos(theta)
        # dx_dt = k*numpy.cos(theta) - (a + k*u)*N*numpy.pi*numpy.sin(theta)
        # dy_dt = k*numpy.sin(theta) + (a + k*u)*N*numpy.pi*numpy.cos(theta)
        return (dx_dt, dy_dt)

    # Add the parametric spiral to the path
    path1.parametric(spiral1, dspiral_dt)
    path2.parametric(spiral2, dspiral_dt2)
    path3.turn(r_min/2, 'rr')
    path3.turn(r_min/2, 'll')
    path3.rotate(numpy.pi/2, (-r_min, 0))

    cell.add(path1)
    cell.add(path2)
    cell.add(path3)
Пример #9
0
    def build_cell(self):
        # Sequentially build all the geometric shapes using gdspy path functions
        # then add it to the Cell

        num_teeth = int(self.length//self.period)
        if self.focus_distance < self.width/2.0 - self.period:
            raise ValueError("Warning! The focus_distance is smaller than the allowed value of width/2.0 - period.")
        neff = self.wavelength / float(self.period) + self.sin_theta
        qmin = int(self.focus_distance / float(self.period) + 0.5)
        max_points = 199
        c3 = neff**2 - self.sin_theta**2
        w = 0.5 * self.width
        path = gdspy.Path(self.wgt.clad_width, self.port, number_of_paths=2,
                          distance=self.wgt.wg_width + self.wgt.clad_width)

        teeth = gdspy.Path(self.period * self.dc, self.port)
        for q in range(qmin, qmin + num_teeth):
            c1 = q * self.wavelength * self.sin_theta
            c2 = (q * self.wavelength)**2
            teeth.parametric(lambda t: (self.width * t - w, (c1 + neff
                            * np.sqrt(c2 - c3 * (self.width * t - w)**2)) / c3),
                            number_of_evaluations=self.evaluations,
                            max_points=max_points,
                            **self.wg_spec)
            teeth.x = self.port[0]
            teeth.y = self.port[1]
        teeth.polygons[0] = np.vstack(
            (teeth.polygons[0][:self.evaluations, :],
             ([(self.port[0] + 0.5 * self.wgt.wg_width, self.port[1]),
               (self.port[0] - 0.5 * self.wgt.wg_width, self.port[1])])))
        teeth.fracture()

        clad_path = gdspy.Path(self.wgt.wg_width + 2*self.wgt.clad_width, self.port)
        clad_path.segment(self.focus_distance, direction='+y',
                     final_width=self.width+2*self.wgt.clad_width, **self.clad_spec)
        clad_path.segment(self.length, direction='+y', **self.clad_spec)

        if self.direction=="WEST":
            teeth.rotate(np.pi/2.0, self.port)
            path.rotate(np.pi/2.0, self.port)
            clad_path.rotate(np.pi/2.0, self.port)
        if self.direction=="SOUTH":
            teeth.rotate(np.pi, self.port)
            path.rotate(np.pi, self.port)
            clad_path.rotate(np.pi, self.port)
        if self.direction=="EAST":
            teeth.rotate(-np.pi/2.0, self.port)
            path.rotate(-np.pi/2.0, self.port)
            clad_path.rotate(-np.pi/2.0, self.port)
        elif isinstance(self.direction, float):
            teeth.rotate(self.direction - np.pi/2.0, self.port)
            path.rotate(self.direction -np.pi/2.0, self.port)
            clad_path.rotate(self.direction-np.pi/2.0, self.port)
        self.add(teeth)
        self.add(path)
        self.add(clad_path)
Пример #10
0
def test_slice():
    poly = gdspy.Path(1, (1, 0), 2, 3).segment(2, "-x")
    left = gdspy.Path(1, (0, 0), 2, 3).segment(1, "-x")
    right = gdspy.Path(1, (1, 0), 2, 3).segment(1, "-x")
    result = gdspy.slice(poly, 0, 0)
    assert equals(result[0], left)
    assert equals(result[1], right)
    bot = gdspy.Path(1, (1, -1.5)).segment(2, "-x")
    top = gdspy.Path(1, (1, 1.5)).segment(2, "-x")
    result = gdspy.slice(poly, [0.1, -0.1], 1)
    assert equals(result[0], bot)
    assert equals(result[2], top)
    assert result[1] is None
Пример #11
0
def gc_line(cell, gc, origin=(0, 0), l=200):
    cell.add(gdspy.CellReference(gc, origin))
    cell.add(gdspy.CellReference(gc, (l + origin[0], origin[1]), rotation=180))
    path_connect = gdspy.Path(w_wg)
    path_connect.segment(l)
    path_connect2 = gdspy.Path(w_wg + 6)
    path_connect2.segment(l)
    path_connect_positive = gdspy.boolean(path_connect,
                                          path_connect2,
                                          'xor',
                                          layer=1,
                                          datatype=1)
    cell.add(path_connect_positive)
    return cell
Пример #12
0
def connect_zShape(cell,
                   pos_start=(0, 0),
                   pos_end=(0, 0),
                   direction=1,
                   w=w_wg,
                   layer=1,
                   datatype=1):
    '''
            pos_end is relative to the pos_start
        '''
    path = gdspy.Path(w, pos_start)
    path.segment(len_port_ext, layer=layer, datatype=datatype)
    if direction == 1:
        path.turn(radius, 'r', layer=layer, datatype=datatype)
    else:
        path.turn(radius, 'l', layer=layer, datatype=datatype)
    path.segment(abs(pos_end[1] - pos_start[1]) - 2 * radius,
                 layer=layer,
                 datatype=datatype)
    if direction == 1:
        path.turn(radius, 'l', layer=layer, datatype=datatype)
    else:
        path.turn(radius, 'r', layer=layer, datatype=datatype)
    path.segment(pos_end[0] - 2 * radius - len_port_ext,
                 layer=layer,
                 datatype=datatype)
    # cell.add(path)
    return path
Пример #13
0
    def build_cell(self):
        # Sequentially build all the geometric shapes using gdspy path functions
        # for waveguide, then add it to the Cell
        angle = tk.get_angle(self.trace[0], self.trace[1])
        # Add waveguide taper
        path = gdspy.Path(self.wgt.wg_width, self.trace[0])
        path.segment(tk.dist(self.trace[0], self.trace[1]),
                     direction=angle, final_width=self.end_width, **self.wg_spec)
        # Cladding for waveguide taper
        path2 = gdspy.Path(2*self.wgt.clad_width+self.wgt.wg_width, self.trace[0])
        path2.segment(tk.dist(self.trace[0], self.trace[1]), direction=angle,
                     final_width=2*self.end_clad_width+self.end_width, **self.clad_spec)
        path2.segment(self.extra_clad_length, **self.clad_spec)

        self.add(path)
        self.add(path2)
Пример #14
0
def dose_test(geometry, wf_size, biggest_feature=0.1):
    """ generate a dose test for the given geometry 

    Args:
        geometry:           gdspy.PolygonSet
        wf_size:            target writefield size
        biggest_feature:    largest feature as a percentage of the writefield size
    """
    smlfeats = []

    for i, p in enumerate(geometry.polygons):
        if p.shape[0] == 4:  # only use rectangular features
            X, Y = np.sort(p[:, 0]), np.sort(p[:, 1])
            smlfeats += [np.abs(X[-1] - X[0]), np.abs(Y[-1] - Y[0])]

    smallest_feature = np.min(smlfeats)

    N_tests = round(1.0 / biggest_feature)
    tests = []
    for i in range(N_tests):
        test_atom = gdspy.Path(width = wf_size*biggest_feature)\
                        .segment(0.1*wf_size, '+y')\
                        .translate(wf_size*biggest_feature/2, 0)\
                        .segment(0.3*wf_size, '+y', final_width = smallest_feature)\
                        .segment(0.1*wf_size, '+y')\
                        .translate(i*wf_size/N_tests, 0)
        if i % 2:
            tests.append(test_atom.mirror((1, 0)).translate(0, wf_size))
        else:
            tests.append(test_atom)

    pattern = union(tests)
    change_layer(pattern, 10)

    return pattern
Пример #15
0
def test_gather():
    def same_points(x, y):
        for px, py in zip(x, y):
            for ptx, pty in zip(px, py):
                for cx, cy in zip(ptx, pty):
                    if cx != cy:
                        return False
        return True

    pts = [(0, 0), (1, 1), (1, 0)]
    ps1 = gdspy.Round((10, 10), 1, inner_radius=0.2)
    ps2 = gdspy.Path(0.1, (-1, -1), 2, 1).segment(2, "-x")
    c = gdspy.Cell("C1").add(gdspy.Rectangle((-4, 3), (-5, 4)))
    cr = gdspy.CellReference(c, (10, -10))
    ca = gdspy.CellArray(c, 2, 1, (2, 0))
    assert gdspy.operation._gather_polys(None) == []
    assert same_points(gdspy.operation._gather_polys([pts]), [pts])
    assert same_points(gdspy.operation._gather_polys(ps1), ps1.polygons)
    assert same_points(gdspy.operation._gather_polys(ps2), ps2.polygons)
    assert same_points(gdspy.operation._gather_polys(cr), cr.get_polygons())
    assert same_points(gdspy.operation._gather_polys(ca), ca.get_polygons())
    result = [pts]
    result.extend(ps2.polygons)
    result.extend(cr.get_polygons())
    assert same_points(gdspy.operation._gather_polys([pts, ps2, cr]), result)
Пример #16
0
def build_DC(w, laayer=1, datatype=1):
    path_dc = gdspy.Path(w, (0, 0))
    path_dc.segment(l_PortIn)
    path_dc.turn(radius_bend, 'r')
    path_dc.segment(spacing_FA / 2 - gap / 2 - w_wg / 2 - 2 * radius_bend)
    path_dc.turn(radius_bend, 'l')
    path_dc.segment(l_DC)
    path_dc.turn(radius_bend, 'l')
    path_dc.segment(l_ver)
    path_dc.turn(radius_bend, 'r')
    path_dc.segment(l_heater)
    path_dc.turn(radius_bend, 'r')
    path_dc.segment(l_ver)
    path_dc.turn(radius_bend, 'l')
    path_dc.segment(l_DC)
    path_dc.turn(radius_bend, 'l')
    path_dc.segment(l_ver)
    path_dc.turn(radius_bend, 'r')
    path_dc.segment(l_heater)
    path_dc.turn(radius_bend, 'r')
    path_dc.segment(l_ver)
    path_dc.turn(radius_bend, 'l')
    path_dc.segment(l_DC)
    path_dc.turn(radius_bend, 'l')
    path_dc.segment(l_ver + spacing_wg)
    path_dc.turn(radius_bend, 'l')
    path_dc.segment(l_MZIs)
    path_dc.turn(radius_bend, 'l')
    path_dc.segment(l_ver + spacing_wg + gap / 2 + w_wg / 2 -
                    spacing_FA * 3 / 2)
    path_dc.turn(radius_bend, 'r')
    path_dc.segment(l_PortOut)

    return path_dc
Пример #17
0
    def gds(self, filename=None, view=False, extra=0, units='nms'):
        #check to make sure the geometry isn't an array
        if len(self.clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == 'nms':
            scale = 1
        elif units == 'microns':
            scale = 10**-3
        else:
            raise ValueError('Invalid units')

        #scale to proper units
        sc_radius = self.radius * scale
        sc_gap = self.gap * scale
        sc_width = self.width * scale
        sc_length = self.length * scale

        #write to GDS
        pathTop = gdspy.Path(sc_width,
                             (sc_radius + sc_length / 2,
                              sc_radius + sc_width / 2 + sc_gap / 2 + extra))
        pathTop.segment(extra, '-y')
        pathTop.arc(sc_radius, 0, -np.pi / 2)
        pathTop.segment(sc_length, '-x')
        pathTop.arc(sc_radius, -np.pi / 2, -np.pi)
        pathTop.segment(extra, '+y')

        pathBottom = gdspy.Path(sc_width,
                                (-sc_radius - sc_width / 2 - sc_length / 2 -
                                 extra, -sc_gap / 2 - sc_width / 2))
        pathBottom.segment(
            2 * (sc_radius + sc_width / 2) + sc_length + 2 * extra, '+x')

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell('C0')
        path_cell.add(pathTop)
        path_cell.add(pathBottom)

        if view:
            gdspy.LayoutViewer(cells='C0')

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
Пример #18
0
 def addlauncher(self, final_TraceWid, final_GapWid, final_Length,
                 tran_Length):
     if (self.x == self.paths[0].x) & (self.y == self.paths[0].y):
         dirction = self.paths[0].direction
         self.addsegment(dirction + numpy.pi, tran_Length, final_TraceWid,
                         final_GapWid)
         self.addsegment(dirction + numpy.pi, final_Length)
         endctrpt = (self.paths[0].x, self.paths[0].y)
         rightend = addtup(
             addtup(
                 endctrpt,
                 scalartup(0.5 * final_GapWid,
                           (numpy.cos(dirction + numpy.pi),
                            numpy.sin(dirction + numpy.pi)))),
             scalartup(0.5 * (final_TraceWid + 2 * final_GapWid),
                       (numpy.cos(dirction - numpy.pi / 2),
                        numpy.sin(dirction - numpy.pi / 2))))
         pathlaunch = gdspy.Path(final_GapWid, rightend)
         pathlaunch.segment(final_TraceWid + 2 * final_GapWid,
                            dirction + numpy.pi / 2)
         self.paths[0].x = self.x
         self.paths[0].y = self.y
         self.paths[0].distance = self.tracewid + self.gapwid
         self.paths[0].w = self.gapwid / 2
         self.paths.append(pathlaunch)
     else:
         self.finalx = self.paths[0].x
         self.finaly = self.paths[0].y
         dirction = self.paths[0].direction
         self.addsegment(dirction, tran_Length, final_TraceWid,
                         final_GapWid)
         self.addsegment(dirction, final_Length)
         endctrpt = (self.paths[0].x, self.paths[0].y)
         rightend = addtup(
             addtup(
                 endctrpt,
                 scalartup(0.5 * final_GapWid,
                           (numpy.cos(dirction), numpy.sin(dirction)))),
             scalartup(0.5 * (final_TraceWid + 2 * final_GapWid),
                       (numpy.cos(dirction - numpy.pi / 2),
                        numpy.sin(dirction - numpy.pi / 2))))
         pathlaunch = gdspy.Path(final_GapWid, rightend)
         pathlaunch.segment(final_TraceWid + 2 * final_GapWid,
                            dirction + numpy.pi / 2)
         self.paths[0].x = self.finalx
         self.paths[0].y = self.finaly
         self.paths.append(pathlaunch)
Пример #19
0
    def build_cell(self):
        # Sequentially build all the geometric shapes using gdspy path functions
        # for waveguide, then add it to the Cell

        angle = tk.get_exact_angle(self.trace[0], self.trace[1])
        angle_opp = tk.get_exact_angle(self.trace[1], self.trace[0])

        # Add strip waveguide taper
        path_strip = gdspy.Path(self.wgt_strip.wg_width, self.trace[0])
        path_strip.segment(self.length,
                           final_width=self.end_strip_width,
                           direction=angle,
                           **self.wg_spec)

        # Add slot waveguide taper
        path_slot = gdspy.Path(self.wgt_slot.rail,
                               self.trace[1],
                               number_of_paths=2,
                               distance=self.wgt_slot.rail_dist)
        path_slot.segment(self.length,
                          final_width=self.end_slot_width,
                          final_distance=(self.wgt_strip.wg_width +
                                          2 * self.d + self.end_slot_width),
                          direction=angle_opp,
                          **self.wg_spec)

        # Cladding for waveguide taper
        path_clad = gdspy.Path(
            2 * self.wgt_strip.clad_width + self.wgt_strip.wg_width,
            self.trace[0])
        path_clad.segment(self.length,
                          final_width=2 * self.wgt_slot.clad_width +
                          self.wgt_slot.wg_width,
                          direction=angle,
                          **self.clad_spec)

        if not self.input_strip:
            center_pt = ((self.trace[0][0] + self.trace[1][0]) / 2.0,
                         (self.trace[0][1] + self.trace[1][1]) / 2.0)
            path_strip.rotate(np.pi, center_pt)
            path_slot.rotate(np.pi, center_pt)
            path_clad.rotate(np.pi, center_pt)

        self.add(path_strip)
        self.add(path_slot)
        self.add(path_clad)
Пример #20
0
 def addwires(self, wirewids, extralen=0):
     squidheight = self.SquidHeight
     midlead = gdspy.Path(wirewids[0],
                          (-self.LeadDist / 2 - extralen,
                           -2 * self.LeadLen + wirewids[0] / 2))
     midlead.segment(self.LeadDist + extralen * 2, 0, **(self.spec_mid))
     sidelead1 = gdspy.Path(
         wirewids[1], (-self.LeadDist / 2, -squidheight + 1 * self.LeadLen))
     sidelead1.segment(
         self.SquidHeight - 4 * self.LeadLen + self.LeadLen + extralen,
         numpy.pi / 2, **(self.spec_side))
     sidelead2 = gdspy.Path(
         wirewids[2], (self.LeadDist / 2, -squidheight + 1 * self.LeadLen))
     sidelead2.segment(
         self.SquidHeight - 4 * self.LeadLen + self.LeadLen + extralen,
         numpy.pi / 2, **(self.spec_side))
     self.paths = self.paths + [midlead, sidelead1, sidelead2]
Пример #21
0
def create_cavity(x,y,width,separation_of_first,width_of_first):
	length=(width_of_first*separation_of_first)/width
	cavity_pair.add(gdspy.Rectangle((-Op_Cav_Width/2+x,-Op_Cav_Len/2+y),(Op_Cav_Width/2+x,Op_Cav_Len/2+y),**spec1))
	ynew=length+Pill_Cav_Len/2+Op_Cav_Len/2
	cavity_pair.add(gdspy.Rectangle((-Op_Cav_Width/2+x,-Op_Cav_Len/2+y+ynew),(Op_Cav_Width/2+x,Op_Cav_Len/2+y+ynew),**spec1))
	path1=gdspy.Path(width,(x,y+Op_Cav_Len/2))
	path1.segment(length,'+y',**spec1)
	cavity_pair.add(path1)
Пример #22
0
 def __init__(self, w, d):
     # w is the width of center conductor, d is the width of gap
     self.w = w
     self.d = d
     self.D = d + w
     self.path1 = gs.Path(d, (0, 0), number_of_paths=2, distance=self.D)
     # self.path2=gs.Path(d)
     self.length = 0
Пример #23
0
def gc_line(cell, gc, origin=(0,0), l=200, w_wg=0.5, w_etch=3):
    """
    cell: cell in Gdspy \n
    
    w_gc: width of grating coupler \n
    w_wg: width of waveguide\n
    w_etch: width of etch
    """
    cell.add(gdspy.CellReference(gc, origin))
    cell.add(gdspy.CellReference(gc, (l+origin[0], origin[1]), rotation=180))
    path_connect = gdspy.Path(w_wg)
    path_connect.segment(l)
    path_connect2 = gdspy.Path(w_wg+w_etch*2)
    path_connect2.segment(l)
    path_connect_positive = gdspy.boolean(path_connect, path_connect2,'xor',layer=1, datatype=1)
    cell.add(path_connect_positive)
    return cell
Пример #24
0
def RouteStraight(p1, p2, layer, path_type='straight', width_type='straight'):
    """ Routes a straight polygon between two ports.

    Example
    -------
    >>> R = RouteStraight()
    """

    point_a = p1.midpoint
    point_b = p2.midpoint
    width_input = p1.width
    width_output = p2.width

    if ug.angle_diff(p2.orientation, p1.orientation) != 180:
        raise ValueError('Ports do not face eachother.')

    separation = np.array([point_b[0], point_b[1]]) - np.array(
        [point_a[0], point_a[1]])
    distance = norm(separation)
    rotation = np.arctan2(separation[1], separation[0]) * constants.RAD2DEG
    angle = rotation - p1.orientation
    xf = distance * np.cos(angle * constants.DEG2RAD)
    yf = distance * np.sin(angle * constants.DEG2RAD)

    if path_type == 'straight':
        curve_fun = lambda t: [xf * t, yf * t]
        curve_deriv_fun = lambda t: [xf + t * 0, 0 + t * 0]
    if path_type == 'sine':
        curve_fun = lambda t: [xf * t, yf * (1 - np.cos(t * np.pi)) / 2]
        curve_deriv_fun = lambda t: [
            xf + t * 0, yf * (np.sin(t * np.pi) * np.pi) / 2
        ]

    if width_type == 'straight':
        width_fun = lambda t: (width_output - width_input) * t + width_input
    if width_type == 'sine':
        width_fun = lambda t: (width_output - width_input) * (1 - np.cos(
            t * np.pi)) / 2 + width_input

    route_path = gdspy.Path(width=width_input, initial_point=(0, 0))
    route_path.parametric(curve_fun, curve_deriv_fun, final_width=width_fun)

    port1 = Port(name='I1',
                 midpoint=(0, 0),
                 width=width_input,
                 orientation=180,
                 process=layer.process)
    port2 = Port(name='I2',
                 midpoint=(xf, yf),
                 width=width_output,
                 orientation=0,
                 process=layer.process)

    route_shape = RouteShape(path=route_path)
    R = Route(shape=route_shape, p1=port1, p2=port2, layer=layer)
    T = vector_match_transform(v1=R.ports[0], v2=p1)
    R.transform(T)
    return R
Пример #25
0
    def build_cell(self):
        #Sequentially build all the geometric shapes using gdspy path functions
        #then add it to the Cell
        num_teeth = int(self.length // self.period)
        """ Create a straight grating GratingCoupler
        """
        gap = self.period - (self.period * self.dc)
        path = gdspy.Path(self.wgt.wg_width, self.port)
        path.segment(self.taper_length,
                     direction='+y',
                     final_width=self.width,
                     **self.wg_spec)
        teeth = gdspy.L1Path(
            (self.port[0] - 0.5 * self.width, gap + self.taper_length +
             self.port[1] + 0.5 * (num_teeth - 1 + self.dc) * self.period),
            '+x', self.period * self.dc, [self.width], [], num_teeth,
            self.period, **self.wg_spec)

        clad_path = gdspy.Path(self.wgt.wg_width + 2 * self.wgt.clad_width,
                               self.port)
        clad_path.segment(self.taper_length,
                          direction='+y',
                          final_width=self.width + 2 * self.wgt.clad_width,
                          **self.clad_spec)
        clad_path.segment(self.length, direction='+y', **self.clad_spec)

        if self.direction == "WEST":
            teeth.rotate(np.pi / 2.0, self.port)
            path.rotate(np.pi / 2.0, self.port)
            clad_path.rotate(np.pi / 2.0, self.port)
        elif self.direction == "SOUTH":
            teeth.rotate(np.pi, self.port)
            path.rotate(np.pi, self.port)
            clad_path.rotate(np.pi, self.port)
        elif self.direction == "EAST":
            teeth.rotate(-np.pi / 2.0, self.port)
            path.rotate(-np.pi / 2.0, self.port)
            clad_path.rotate(-np.pi / 2.0, self.port)
        elif isinstance(self.direction, float):
            teeth.rotate(self.direction - np.pi / 2.0, self.port)
            path.rotate(self.direction - np.pi / 2.0, self.port)
            clad_path.rotate(self.direction - np.pi / 2.0, self.port)
        self.add(teeth)
        self.add(path)
        self.add(clad_path)
Пример #26
0
def bc(w_wg=0.5, l_bc=100, w_bc=127 / 2, tolerance=0.01):
    ''' w_wg is the width of waveguide \n
        l_bc is length of bezier curve \n
        w_bc is the width of bezier curve'''
    path = gdspy.Path(w_wg, (0, 0))
    v = [(l_bc / 2, 0), (l_bc / 2, w_bc),
         (l_bc, w_bc)]  # the first point (0, 0) is omiited
    path.bezier(v, tolerance=tolerance)
    return path
Пример #27
0
 def __init__(self, ct, ch, fillet=0, layer=0, datatype=0):
     self.spec = {'layer': layer, 'datatype': datatype}
     Harm = gdspy.Path(ct, (-ch / 2, 0))
     Harm.segment(ch, 0, **(self.spec))
     Varm = gdspy.Path(ct, (0, -ch / 2))
     Varm.segment(ch, numpy.pi / 2, **(self.spec))
     self.paths = [Harm, Varm]
     if (fillet != 0):
         filletwid = fillet * numpy.sqrt(2)
         filletlen = filletwid / 2 + fillet
         for psign in [-1, 1]:
             for qsign in [-1, 1]:
                 for len1 in [ct / 2, ch / 2]:
                     for len2 in [ct / 2, ch / 2]:
                         pt = (psign * len1, qsign * len2)
                         if (len1 == ch / 2) & (len2 == ch / 2):
                             continue
                         elif (len1 == ct / 2) & (len2 == ct / 2):
                             direction = (-psign / numpy.sqrt(2),
                                          -qsign / numpy.sqrt(2))
                             p = gdspy.Path(
                                 filletwid,
                                 (pt[0] - direction[0] * filletwid / 2,
                                  pt[1] - direction[1] * filletwid / 2))
                             #p=gdspy.Path(filletwid,pt)
                             p.segment(filletlen,
                                       numpy.arctan2(
                                           direction[1], direction[0]),
                                       final_width=0)
                             self.paths.append(p)
                         else:
                             direction = (psign / numpy.sqrt(2),
                                          qsign / numpy.sqrt(2))
                             p = gdspy.Path(
                                 filletwid,
                                 (pt[0] - direction[0] * filletwid / 2,
                                  pt[1] - direction[1] * filletwid / 2))
                             #p=gdspy.Path(filletwid,pt)
                             p.segment(filletlen,
                                       numpy.arctan2(
                                           direction[1], direction[0]),
                                       final_width=0)
                             self.paths.append(p)
Пример #28
0
    def __build_cell(self):
        # Sequentially build all the geometric shapes using gdspy path functions
        # for waveguide, then add it to the Cell

        # Uncomment below to plot the function (useful for debugging)
        #        import matplotlib.pyplot as plt
        #        tvals = np.linspace(0,1,5000)
        #        xy = [self.__euler_s_function(tv) for tv in tvals]
        #        plt.scatter(*zip(*xy))
        #        plt.show()

        if self.wgt.wg_type == "strip":
            wg = gdspy.Path(self.start_width, (0, 0))
        elif self.wgt.wg_type == "slot":
            wg = gdspy.Path(
                self.wgt.rail, (0, 0), number_of_paths=2, distance=self.wgt.rail_dist
            )

        wg.parametric(
            self.__euler_s_function,
            final_width=self.end_width,
            tolerance=self.wgt.grid / 2.0,
            max_points=199,
            **self.wg_spec
        )
        self.add(wg)

        # Add cladding
        for i in range(len(self.wgt.waveguide_stack) - 1):
            cur_width = self.wgt.waveguide_stack[i + 1][0]
            cur_spec = {
                "layer": self.wgt.waveguide_stack[i + 1][1][0],
                "datatype": self.wgt.waveguide_stack[i + 1][1][1],
            }

            clad = gdspy.Path(cur_width, (0, 0))
            clad.parametric(
                self.__euler_s_function,
                tolerance=self.wgt.grid / 2.0,
                max_points=199,
                **cur_spec
            )
            self.add(clad)
Пример #29
0
    def __build_cell(self):
        # Sequentially build all the geometric shapes using gdspy path functions
        # for waveguide, then add it to the Cell

        # Add strip waveguide taper
        path_strip = gdspy.Path(self.wgt_strip.wg_width, (0, 0))
        path_strip.segment(self.length,
                           final_width=self.end_strip_width,
                           direction=0,
                           **self.wg_spec)

        # Add slot waveguide taper
        path_slot = gdspy.Path(
            self.wgt_slot.rail,
            (self.length, 0),
            number_of_paths=2,
            distance=self.wgt_slot.rail_dist,
        )
        path_slot.segment(self.length,
                          final_width=self.end_slot_width,
                          final_distance=(self.wgt_strip.wg_width +
                                          2 * self.d + self.end_slot_width),
                          direction=np.pi,
                          **self.wg_spec)

        # Cladding for waveguide taper
        path_clad = gdspy.Path(
            2 * self.wgt_strip.clad_width + self.wgt_strip.wg_width, (0, 0))
        path_clad.segment(self.length,
                          final_width=2 * self.wgt_slot.clad_width +
                          self.wgt_slot.wg_width,
                          direction=0,
                          **self.clad_spec)

        if not self.input_strip:
            center_pt = (self.length / 2.0, 0)
            path_strip.rotate(np.pi, center_pt)
            path_slot.rotate(np.pi, center_pt)
            path_clad.rotate(np.pi, center_pt)

        self.add(path_strip)
        self.add(path_slot)
        self.add(path_clad)
Пример #30
0
 def start(self, start = [0, 0], direction = None):
     ### Start a CPW path specified by start coordinates and a direction
     ### direction: {+x, -x, +y, -y} or angle (in radians)
     if direction is not None:
         # Get direction from CPW class
         self.initalDirection = direction
     # Define the distance
     d = self.width + self.gap
     self.path = gdspy.Path(self.gap,(start[0],start[1]),number_of_paths = 2,
                                                         distance=d)