Пример #1
0
def save_multiple(shapes,
                  filename,
                  layers=None,
                  cell_name="POLYGON",
                  datatype=1000,
                  ignore_interiors=False,
                  **kw):
    if DO_RELOAD:
        reload(gdspy)
    poly_cell = gdspy.Cell(cell_name)
    for i, shape in enumerate(shapes):
        if not ignore_interiors and shape.has_interiors():
            raise ValueError(
                "Polygon contains interiors, which can not be represented"
                " in the GDS file format. To ignore, call with ignore_interiors=True"
            )

        vertex_lists = shape.get_exterior_vertex_lists()

        for vl in vertex_lists:
            if len(vl) > MAX_VERTICES:
                raise ValueError("Polygon contains {} vertices, more than the"
                                 " limit of {} vertices".format(
                                     len(vl), MAX_VERTICES))

            layer = 0
            if layers is not None:
                layer = layers[i]
            # shapely always duplicates the first vertex as the last vertex, get rid of that
            gds_poly = gdspy.Polygon(vl[:-1], datatype=datatype, layer=layer)
            poly_cell.add(gds_poly)

    gdspy.write_gds(filename, **kw)
Пример #2
0
    def test(self):
        ld_fulletch = {'layer': 91, 'datatype': 1}
        ld_partetch = {'layer': 2, 'datatype': 3}
        ld_liftoff = {'layer': 0, 'datatype': 7}

        # um        = 1
        # cm        = 10000*um
        # wafer_rad = 75*cm
        # die_size  = [2500*um, 2500*um]
        # shot_size = [  20,   20]
        main_cell = gdspy.Cell('MAIN')
        # shot_cell = gdspy.Cell('SHOT')
        die_cell = gdspy.Cell('DIE')
        # main_cell.add(die_cell)

        for die in self._gross_die:
            die_rect = gdspy.Rectangle(
                ((die.x()), (die.y())),
                ((die.x() + die.width()), (die.y() + die.height())),
                **ld_liftoff)
            die_cell.add(die_rect)

        # shot_cell.add(gdspy.CellArray(die_cell,  shot_size[0], shot_size[1], (die_size[0], die_size[1])))
        # main_cell.add(gdspy.CellArray(shot_cell, 20, 20, (die_size[0]*shot_size[0], die_size[1]*shot_size[1])))

        wafer_poly = gdspy.Polygon([((qp.x()), (qp.y()))
                                    for qp in self._wafer_pts], **ld_fulletch)
        ebr_poly = gdspy.Polygon([(qp.x(), qp.y()) for qp in self._ebr_pts],
                                 **ld_partetch)
        main_cell.add(wafer_poly)
        main_cell.add(ebr_poly)
        gdspy.write_gds('first.gds')
Пример #3
0
 def writeOut(self):
     """
     @brief write GDSII, Pin, Bin for file based version
     Need to setGDS() and setPinBB
     Should be removed in later versions
     """
     gdspy.write_gds(self.outGDS, [self.cell], unit=1.0e-6, precision=1.0e-9)
Пример #4
0
def corners2gds(corners, args):
    polyidx = []
    with open(args.corner_seq, 'r') as f:
        for line in f:
            line = line.strip().split(',')
            tmp = [int(x) for x in line]
            polyidx.append(tmp)
    poly_cell = gdspy.Cell('tmp')
    polyvertice = []
    for i, idx in enumerate(polyidx):
        polyvertice.append(idx2xy(corners, idx))
        # poly=gdspy.Polygon(polyvertice,1)
        # poly_cell.add(poly)
    poly = gdspy.PolygonSet(polyvertice, 1)
    # poly_cell.add(poly)
    xlength = max(corners[:, 0]) - min(corners[:, 0])
    ylength = max(corners[:, 1]) - min(corners[:, 1])
    nX = args.nX
    nY = args.nY
    xsep = max(xlength, ylength) * args.sep
    ysep = xsep
    for i in range(nX):
        for j in range(nY):
            xpos = (xlength + xsep) * (i + 1)
            ypos = (ylength + ysep) * (j + 1)
            trans = gdspy.copy(poly, xpos, ypos)
            poly_cell.add(trans)

    if args.out_file is not None:
        gdspy.write_gds(args.out_file,
                        unit=args.scale * 1.0e-9,
                        precision=1.0e-9)
Пример #5
0
 def writeDB(self, cktIdx, flipCell):
     """
     @brief write to GdsData. Current version GDS is file based
     Need to setGDS()
     Should write to layoutDB in future.
     """
     gdspy.write_gds(self.outGDS, [self.cell], unit=1.0e-6, precision=1.0e-9)
     ckt = self.dDB.subCkt(cktIdx)
     gdsData = ckt.GdsData()
     BB = basic.basic.BB(self.cell, flipCell)
     #bound = self.cell.cell.get_bounding_box()
     gdsData.setBBox(int(BB[0]), int(BB[1]), int(BB[2]), int(BB[3]))
     ckt.layout().setBoundary(int(BB[0]), int(BB[1]), int(BB[2]), int(BB[3]))
     gdsData.gdsFile = self.outGDS
     # Match pin name, current implementation is integer, bulk need to be ommited for res/cap/mos
     # Example, 0:drain, 1:gate, etc...
     nets = dict()
     for idx in range(ckt.numNets()):
         nets[int(ckt.net(idx).name)] = idx
     net_name = 0
     for pin in self.cell.pin():
         if net_name not in nets:
             net_name += 1
             continue
         shape = pin.normalize_shape()
         if shape[1] > shape[3]:
             ckt.net(nets[net_name]).setIoShape(shape[3], shape[2], shape[1], shape[4])
         else:
             ckt.net(nets[net_name]).setIoShape(shape[1], shape[2], shape[3], shape[4])
             assert shape[1] < shape[3], "Device_generator, xLo = xHi"
         assert shape[2] < shape[4], "Device_generator, yLo > yHi"
         ckt.net(nets[net_name]).ioLayer = shape[0]
         net_name += 1
Пример #6
0
def contour2gds(contour0, args):
    """transform contour list to gds """
    contour = [[ele[0] for ele in arr] for arr in contour0]
    if args.sharpen:
        contour = sharpenCorner(contour, args)
    flat_list = [item for sublist in contour for item in sublist]

    x = [arr[0] for arr in flat_list]
    y = [arr[1] for arr in flat_list]
    xlength = max(x) - min(x)
    ylength = max(y) - min(y)

    maxY = max(y)
    contour = [[[ele[0], maxY - ele[1]] for ele in arr] for arr in contour]

    poly_cell = gdspy.Cell('tmp')
    poly = gdspy.PolygonSet(contour, 1)

    nX = args.nX
    nY = args.nY
    xsep = max(xlength, ylength) * args.sep
    ysep = xsep
    for i in range(nX):
        for j in range(nY):
            xpos = (xlength + xsep) * (i + 1)
            ypos = (ylength + ysep) * (j + 1)
            trans = gdspy.copy(poly, xpos, ypos)
            poly_cell.add(trans)

    if args.out_file is not None:
        gdspy.write_gds(args.out_file,
                        unit=args.scale * 1.0e-9,
                        precision=1.0e-9)
Пример #7
0
 def generate_gds(self, file):
     for cell_name in self.gds_cells.keys():
         filename = file + '_%s.gds' % cell_name
         gdspy.write_gds(filename,
                         cells=[cell_name],
                         unit=1.0,
                         precision=1e-9)
Пример #8
0
    def write_gds(self,
                  filename,
                  unit=1e-6,
                  precision=1e-9,
                  auto_rename=True,
                  max_cellname_length=28):
        if filename[-4:] != '.gds': filename += '.gds'
        tempname = self.name
        referenced_cells = list(self.get_dependencies(recursive=True))
        all_cells = [self] + referenced_cells

        # Autofix names so there are no duplicates
        if auto_rename == True:
            all_cells_sorted = sorted(all_cells, key=lambda x: x.uid)
            used_names = {'toplevel': 1}
            for c in all_cells_sorted:
                if max_cellname_length is not None:
                    new_name = c._internal_name[:max_cellname_length]
                else:
                    new_name = c._internal_name
                if new_name not in used_names:
                    used_names[new_name] = 1
                    c.name = new_name
                else:
                    c.name = new_name + ('%0.3i' % used_names[new_name])
                    used_names[new_name] += 1
            self.name = 'toplevel'
        gdspy.write_gds(filename,
                        cells=all_cells,
                        name='library',
                        unit=unit,
                        precision=precision)
        self.name = tempname
        return filename
Пример #9
0
def test_robustpath_togds(tmpdir):
    cell = gdspy.Cell('robustpath')
    rp = gdspy.RobustPath((0, 0), 0.1, layer=[1])
    rp.segment((1, 1))
    rp.segment((2, 3), 0)
    cell.add(rp)
    rp = gdspy.RobustPath((2, 0), [0.1, 0.2],
                          0.2,
                          ends=['round', (0.2, 0.1)],
                          layer=4,
                          datatype=[1, 1],
                          gdsii_path=True)
    rp.segment((3, 1))
    cell.add(rp)
    rp = gdspy.RobustPath((0, 0),
                          0.1,
                          layer=5,
                          tolerance=1e-5,
                          max_points=0,
                          max_evals=1e6,
                          gdsii_path=True)
    rp.segment((10, 0))
    rp.turn(20, 'll')
    rp.turn(20, 'rr')
    rp.turn(20, 'll')
    cell.add(rp)
    fname = str(tmpdir.join('test.gds'))
    with pytest.warns(UserWarning):
        gdspy.write_gds(fname, unit=1, precision=1e-7)
    lib = gdspy.GdsLibrary(infile=fname, rename={'robustpath': 'file'})
    assertsame(lib.cell_dict['file'], cell, tolerance=1e-3)
    gdspy.current_library = gdspy.GdsLibrary()
Пример #10
0
def save(shape,
         filename,
         cell_name="POLYGON",
         datatype=1000,
         ignore_interiors=False,
         **kw):
    if DO_RELOAD:
        reload(gdspy)
    poly_cell = gdspy.Cell(cell_name)
    if not ignore_interiors and shape.has_interiors():
        raise ValueError(
            "Polygon contains interiors, which can not be represented"
            " in the GDS file format. To ignore, call with ignore_interiors=True"
        )

    vertex_lists = shape.get_exterior_vertex_lists()

    for vl in vertex_lists:
        if len(vl) > MAX_VERTICES:
            raise ValueError(
                f"Polygon contains {len(vl)} vertices, more than the limit of {MAX_VERTICES} vertices"
            )

        # shapely always duplicates the first vertex as the last vertex, get rid of that
        gds_poly = gdspy.Polygon(vl[:-1], datatype=datatype)
        poly_cell.add(gds_poly)

    gdspy.write_gds(filename, **kw)
Пример #11
0
def test_write_gds(library, tmpdir):
    gdspy.current_library = library
    fname1 = str(tmpdir.join('test1.gds'))
    gdspy.write_gds(fname1, name='lib', unit=2e-6, precision=1e-8)
    lib1 = gdspy.GdsLibrary(infile=fname1,
                            units='convert',
                            rename={'cell1': '1'},
                            layers={2: 4},
                            datatypes={4: 2},
                            texttypes={6: 7})
    assert lib1.name == 'lib'
    assert len(lib1.cell_dict) == 4
    assert set(lib1.cell_dict.keys()) == {'1', 'cell2', 'cell3', 'cell04'}
    c = lib1.cell_dict['1']
    assert len(c.polygons) == len(c.labels) == 1
    assert c.polygons[0].area() == 12.0
    assert c.polygons[0].layers == [4]
    assert c.polygons[0].datatypes == [2]
    assert c.labels[0].text == 'label'
    assert c.labels[0].position[0] == 2 and c.labels[0].position[1] == -2
    assert c.labels[0].anchor == 4
    assert c.labels[0].rotation == 45
    assert c.labels[0].magnification == 1.5
    assert c.labels[0].x_reflection == True
    assert c.labels[0].layer == 5
    assert c.labels[0].texttype == 7

    c = lib1.cell_dict['cell2']
    assert len(c.polygons) == 2
    assert isinstance(c.polygons[0], gdspy.Polygon) and isinstance(
        c.polygons[1], gdspy.Polygon)

    c = lib1.cell_dict['cell3']
    assert len(c.references) == 1
    assert c.references[0].ref_cell == lib1.cell_dict['1']
    assert c.references[0].origin[0] == 0 and c.references[0].origin[1] == 2
    assert c.references[0].rotation == -90
    assert c.references[0].magnification == 2
    assert c.references[0].x_reflection == True

    c = lib1.cell_dict['cell04']
    assert len(c.references) == 1
    assert c.references[0].ref_cell == lib1.cell_dict['cell2']
    assert c.references[0].origin[0] == -2 and c.references[0].origin[1] == -4
    assert c.references[0].rotation == 180
    assert c.references[0].magnification == 0.5
    assert c.references[0].x_reflection == True
    assert c.references[0].spacing[0] == 2 and c.references[0].spacing[1] == 8
    assert c.references[0].columns == 2
    assert c.references[0].rows == 3

    fname2 = str(tmpdir.join('test2.gds'))
    with open(fname2, 'wb') as fout:
        gdspy.write_gds(fout, name='lib2', unit=2e-3, precision=1e-5)
    with open(fname2, 'rb') as fin:
        lib2 = gdspy.GdsLibrary()
        lib2.read_gds(fin)
    assert lib2.name == 'lib2'
    assert len(lib2.cell_dict) == 4
    def write(self, filename=DEFAULT_FILENAME):
        """Saves the generated structures.
        
        Args:
            filename: name of the file to be saved ommiting the .gds extension.
        """

        gdspy.write_gds('{0}.gds'.format(filename), unit=self.unit, precision=self.precision)
Пример #13
0
 def klayout(self,filename):
     # Check if klayout is already running. If not, write gds and open klayout.
     # If it is, just update the gds file
     if("klayout" in (p.name() for p in psutil.process_iter())):
         #Write the pattern as a gds file
         gdspy.write_gds(filename, unit=1.0e-6, precision=1.0e-9)
     else:
         gdspy.write_gds(filename, unit=1.0e-6, precision=1.0e-9)
         kl = call('./klayout_viewer %s' %filename,shell=True)
Пример #14
0
    def generate_gds(self, file, max_points):
        for instance in self.gds_object_instances.keys():
            obj = self.gds_object_instances[instance]
            if isinstance(obj, gdspy.Polygon) or isinstance(obj, gdspy.PolygonSet):
                self.gds_object_instances[instance] = obj.fracture(max_points=max_points, precision=1e-9)

        for cell_name in self.gds_cells.keys():
            filename = file+'_%s.gds'%cell_name
            gdspy.write_gds(filename, cells=[cell_name],
                            unit=1.0, precision=1e-9)
Пример #15
0
def generate_hall_bar_array(title, width_list, length_xx_list, dx, dy, orientation=0, leg_type='default'):
    """
    Generates a gdspy cell populated with single nanowires with the specified parameters
    :param title: str. Also filename
    :param width_list: list of floats. In um
    :param length_xx_list: list of floats. In um
    :param dx: float. Distance in um between neighboring structures
    :param dy: float. Distance in um between neighboring structures
    :param orientation: float in degrees. 0deg is horizontal.
    :param leg_type: {'fishbone', 'default'}
    :return: gdspy viewer
    """

    cell = gdspy.Cell(title)
    tools.make_title(title, cell, y=2 * dy, text_size=20)

    for i, w in enumerate(width_list):
        for j, L in enumerate(length_xx_list):
            wire_list = []  # will contain a wire and eventually labels, SmartWalls...
            x = j * dx
            y = - i * dy

            # labels
            if y == 0:
                x_label = 'L_xx=' + str(L)
                tools.make_x_label(x_label, wire_list, y=dy)
            if x == 0:
                y_label = 'w=' + str(int(w * 1000)) + 'nm\n'
                tools.make_y_label(y_label, wire_list, x=-dx)

            length_S_to_junction = 1.5
            length_total = L + 2 * length_S_to_junction
            length_leg = 1

            if j % 2 == 0:
                reservoir_enable = True
            else:
                reservoir_enable = False

            struct = tools.modified_hall_bar(w, length_total=length_total, length_leg=length_leg, length_xx=L,
                                             leg_offset=0, orientation=orientation, leg_type=leg_type,
                                             reservoir_enable=reservoir_enable)

            wire_list.append(struct)

            tools.add_label('X{}Y{}'.format(str(j), str(i)), wire_list, text_size=2, layer=20)  # adds a number label to the wire_cell
            # tools.add_label('W{}L{}X{}Y{}'.format(str(int(w*1000)), str(L), str(j), str(i)), wire_list, text_size=2)  # adds a number label to the wire_cell
            
            tools.move_list(wire_list, x, y)  # translates the entire wire_cell
            cell.add(wire_list)

    gdspy.write_gds(os.path.join(pattern_directory, title + '.gds'), cells=[cell], unit=1.0e-6, precision=1e-11)
    # 1um unit, 1e-11 precision allows total cell area up to ~20mm*20mm
    return gdspy.LayoutViewer(cells=[cell])
Пример #16
0
def generate_gds_raster(lattice, raster, filename, unit=1e-6, tolerance=0.01, cell_bound=True, levels=[0.5]):
    """Traces a rasterization projected onto a lattice to generate a GDS file

    Note
    ----
    The ``gdspy`` and ``scikit-image`` packages are required for exporting rasterized GDS files.

    Parameters
    ----------
    lattice : Lattice
    raster : 2D array of floats
    filename : str
    unit : float, optional
        The GDS spatial units. 
        Default is 1e-6, or 1 um.
    tolerance : float , optional
        The GDS tolerance parameter. 
        Default is 0.01.
    cell_bound : bool, optional
        Whether a Polygon should be added to define the unit cell boundary.
        Default is True.
    levels : List[float], optional
        List of the raster levels to trace with ``skimage.measure.find_contours``.
        Default is [0.5].
    """

    contours = skimage.measure.find_contours(raster, levels)
    polygons = []

    T = np.hstack((lattice.a1[:, np.newaxis], lattice.a2[:, np.newaxis]))

    for contour in contours:
        #TODO(ian): make sure that this coord transform is correct
        #TODO(ian): generalize the 0.5 boundary
        coords = T @ (contour/(np.array(raster.shape)[np.newaxis,:]-1) - 0.5).T

        points = [(x, y) for (x, y) in zip(coords[0,:], coords[1,:])]
        poly = gdspy.Polygon(points, layer=0, datatype=0)
        polygons.append(poly)

    gdspy.current_library = gdspy.GdsLibrary()
    cell = gdspy.Cell('CELL')
    cell.add(polygons)

    # TODO(ian): Need to do a boolean operation here
    if cell_bound:
        bounds = T @ np.array([[-0.5, -0.5, +0.5, +0.5],[-0.5, +0.5, +0.5, -0.5]])
        points = [(x, y) for (x, y) in zip(bounds[0,:], bounds[1,:])]
        boundary = gdspy.Polygon(points, layer=0, datatype=1)

    cell.add(boundary)

    gdspy.write_gds(filename, unit=unit)
Пример #17
0
 def write_gds(self, filename, unit=1e-6, precision=1e-9):
     if filename[-4:] != '.gds': filename += '.gds'
     tempname = self.name
     self.name = 'toplevel'
     referenced_cells = list(self.get_dependencies(recursive=True))
     all_cells = [self] + referenced_cells
     gdspy.write_gds(filename,
                     cells=all_cells,
                     name='library',
                     unit=unit,
                     precision=precision)
     self.name = tempname
Пример #18
0
def test_flexpath_togds(tmpdir):
    cell = gdspy.Cell("flexpath")
    fp = gdspy.FlexPath([(0, 0), (0.5, 0.5), (1, 1)],
                        0.1,
                        layer=[1],
                        gdsii_path=True)
    cell.add(fp)
    fp = gdspy.FlexPath([(3, 0), (3.5, 0.5), (4, 1)], 0.1, layer=[21])
    cell.add(fp)
    fp = gdspy.FlexPath(
        [(1, 0), (2, 1)],
        0.1,
        [-0.1, 0.1],
        max_points=6,
        ends=["round", "extended"],
        layer=[2, 3],
        gdsii_path=True,
    )
    cell.add(fp)
    fp = gdspy.FlexPath(
        [(2, 0), (3, 1)],
        [0.1, 0.2],
        0.2,
        ends=(0.2, 0.1),
        layer=4,
        datatype=[10, 10],
        gdsii_path=True,
    )
    cell.add(fp)

    fp = gdspy.FlexPath(
        [(0, 0), (0.5, 0), (1, 0), (1, 1), (0, 1), (-1, -2), (-2, 0)],
        0.05,
        [0, -0.1, 0, 0.1],
        corners=["natural", "circular bend", "circular bend", "circular bend"],
        tolerance=1e-5,
        ends=["flush", "extended", (0.1, 0.2), "flush"],
        layer=[10, 11, 11, 12],
        bend_radius=[0, 0.3, 0.3, 0.2],
        gdsii_path=True,
    ).translate(-5, 0)
    cell.add(fp)
    fp = gdspy.FlexPath([(i, 2 + i**2) for i in numpy.linspace(0, 1, 8192)],
                        0.01,
                        gdsii_path=True)
    cell.add(fp)
    fname = str(tmpdir.join("test.gds"))
    with pytest.warns(UserWarning):
        gdspy.write_gds(fname, unit=1, precision=1e-7)
    lib = gdspy.GdsLibrary(infile=fname, rename={"flexpath": "file"})
    assertsame(lib.cell_dict["file"], cell, tolerance=1e-3)
    gdspy.current_library = gdspy.GdsLibrary()
Пример #19
0
def generate_2d_array(title, x_labels, y_labels, unit_function, arg_2d_list, dx=40, dy=40, preview=False):
    """
    Generates a 2D array of patterns with unique identifiers, a title, a column of labels on the left and a row of labels on top
    :param title: string, also filename
    :param x_labels: list of strings, each is the label for a column
    :param y_labels: list of strings, each is the label for a row
    :param unit_function: a function that takes each args tuple as parameters and returns a gdspy shape
    :param dx: float, x distance in um
    :param dy: float, y distance in um
    :return: writes a .gds file and launches the gdspy layout viewer
    """

    if len(x_labels) != len(arg_2d_list[0]) or len(y_labels) != len(arg_2d_list):
        print('Check dimensions of arg_2d_list and x/y_labels!')
        raise ValueError

    cell = gdspy.Cell(title)
    tools.make_title(title, cell, y=2 * dy, text_size=20)

    for y_count, arg_1d_list in enumerate(arg_2d_list):
        for x_count, args in enumerate(arg_1d_list):
            x = x_count * dx
            y = -y_count * dy
            wire_cell = []  # will contain a wire and eventually labels, SmartWalls...
            
            # labels
            if y == 0:
                x_label = x_labels[x_count]
                tools.make_x_label(x_label, wire_cell, y=dy, text_size=5)
            if x == 0:
                y_label = y_labels[y_count]
                tools.make_y_label(y_label, wire_cell, x=-dx/2, y=dy/2, text_size=4)

            wire_shape = unit_function(**args)
            if type(wire_shape) == tuple:
                for single_shape in wire_shape:
                    wire_cell.append(single_shape)
            else:
                wire_cell.append(wire_shape)

            if x_count != 0: # left most row can be labeled by the big X labels
                tools.add_label('X{}Y{}'.format(str(x_count), str(y_count)), wire_cell, x=-dx/2, y=dy/2, text_size=2, layer=11)  # adds a number label to the wire_cell
            
            tools.move_list(wire_cell, x, y)  # translates the entire wire_cell
            cell.add(wire_cell)
            
    gdspy.write_gds(os.path.join(pattern_directory, title + '.gds'), cells=[cell], unit=1.0e-6, precision=1e-11)
    # 1um unit, 1e-11 precision allows total cell area up to ~20mm*20mm
    if preview:
        return gdspy.LayoutViewer(cells=[cell])
Пример #20
0
def corners2gds(corners, args):
    poly_cell = gdspy.Cell('tmp')
    polyidx = [None] * 3
    polyidx[0] = [0, 1, 2, 5, 4, 3, 8, 7, 6]
    polyidx[1] = [
        18, 20, 19, 17, 28, 27, 12, 11, 26, 30, 10, 14, 13, 9, 29, 25, 22, 21,
        24, 23, 16, 15, 39, 40, 29, 31, 41, 42, 37, 38, 43, 44, 32, 44, 30, 45,
        46, 33, 34, 51, 49, 50, 52, 35, 36, 47, 48
    ]
    polyidx[2] = [53, 54, 55, 58, 56, 57, 59, 60, 58, 59, 60, 61, 62]
    for i, idx in enumerate(polyidx):
        polyvertice = idx2xy(corners, idx)
        poly = gdspy.Polygon(polyvertice, 1)
        poly_cell.add(poly)
    if args.out_file is not None:
        gdspy.write_gds(args.out_file, unit=1.0e-6, precision=1.0e-9)
Пример #21
0
def contour2gds(contour0, args):
    # print 'contour0',contour0
    contour = [[ele[0] for ele in arr] for arr in contour0]
    # print 'contour1',contour
    if args.sharpen:
        contour = sharpenCorner(contour, args)
    # print 'contour2',contour
    flat_list = [item for sublist in contour for item in sublist]
    # print 'flat_list',flat_list
    x = [arr[0] for arr in flat_list]
    y = [arr[1] for arr in flat_list]
    # print 'x', x
    # print 'y', y
    xlength = max(x) - min(x)
    ylength = max(y) - min(y)

    maxY = max(y)
    # contour=[[[ele[0][0],maxY-ele[0][1]] for ele in arr] for arr in contour0]
    contour = [[[ele[0], maxY - ele[1]] for ele in arr] for arr in contour]

    # for sublist in contour:
    #     for ele in sublist:
    #         ele[1]=maxY-ele[1]

    poly_cell = gdspy.Cell('tmp')
    poly = gdspy.PolygonSet(contour, 1)
    # poly_cell.add(poly)
    # print 'max/min x',max(x),min(x)
    # print 'max/min y',max(y),min(y)
    # print 'length',xlength,ylength
    nX = args.nX
    nY = args.nY
    xsep = max(xlength, ylength) * args.sep
    ysep = xsep
    for i in range(nX):
        for j in range(nY):
            xpos = (xlength + xsep) * (i + 1)
            ypos = (ylength + ysep) * (j + 1)
            trans = gdspy.copy(poly, xpos, ypos)
            poly_cell.add(trans)

    if args.out_file is not None:
        gdspy.write_gds(args.out_file,
                        unit=args.scale * 1.0e-9,
                        precision=1.0e-9)
Пример #22
0
def gen_gds(save_folder: str, sim_width: float) -> None:
    """Generates a GDS file of the grating.

    Args:
        save_folder: Location where log files are saved. It is assumed that
            the optimization plan is also saved there.
        sim width: width of the simulation
    """
    # Load the optimization plan.
    with open(os.path.join(save_folder, "optplan.json")) as fp:
        plan = optplan.loads(fp.read())
    dx = plan.transformations[-1].parametrization.simulation_space.mesh.dx

    # Load the data from the latest log file.
    with open(workspace.get_latest_log_file(save_folder), "rb") as fp:
        log_data = pickle.load(fp)
        if log_data["transformation"] != plan.transformations[-1].name:
            raise ValueError("Optimization did not run until completion.")

        coords = log_data["parametrization"]["vector"] * dx


#        if plan.transformations[-1].parametrization.inverted:
#            coords = np.insert(coords, 0, 0, axis=0)
#            coords = np.insert(coords, -1, sim_width, axis=0)

# TODO Not sure about this part below creating rectangles
# Change the variables and names here

# `coords` now contains the location of the grating edges. Now draw a
# series of rectangles to represent the grating.
    grating_poly = []
    for i in range(0, len(coords), 2):
        grating_poly.append(
            ((coords[i], -sim_width / 2), (coords[i], sim_width / 2),
             (coords[i - 1], sim_width / 2), (coords[i - 1], -sim_width / 2)))

    # Save the grating to `annulus.gds`.
    grating = gdspy.Cell("ANNULUS", exclude_from_current=True)
    grating.add(gdspy.PolygonSet(grating_poly, 100))
    gdspy.write_gds(os.path.join(save_folder, "annulus.gds"), [grating],
                    unit=1.0e-9,
                    precision=1.0e-9)
Пример #23
0
def bitmarker_2inch():
    dx = 20
    dy = 20 
    # text_size = 100
    nrows = 32
    ncols = 32
    output_dir = r'/Users/wgz/Downloads'
    title = 'BitmarkerArray'
    cell = gp.Cell(title)
    for x in range(ncols):
        for y in range(nrows):
            # x_label = string.ascii_uppercase[x]
            # y_label = str(y)
            # shape = gp.Text(x_label+y_label, text_size, position=(x*dx, -y*dy), layer=10)
            shape = tools.bitmarker(x, y)
            shape.translate(x*dx, -y*dy)
            cell.add(shape)
    gp.LayoutViewer(cells=[cell])
    gp.write_gds(os.path.join(output_dir, title + '.gds'), cells=[cell], unit=1.0e-6, 
    precision=1e-10)
Пример #24
0
    def klayout(self, filename):
        # Check if klayout is already running. If not, write gds and open klayout.
        # If it is, just update the gds file
        if ("klayout" in (p.name() for p in psutil.process_iter())):
            #Write the pattern as a gds file
            gdspy.write_gds(filename, unit=1.0e-6, precision=1.0e-9)
        else:
            gdspy.write_gds(filename, unit=1.0e-6, precision=1.0e-9)
            # kl = call('./klayout_viewer %s' %filename,shell=True)
            file = open("klayout_viewer", "w")
            file.write("#!/bin/bash")
            file.write("\n")
            file.write("\n")
            file.write("FOLDER=$PWD")
            file.write("\n")
            file.write("\n")
            file.write(
                "/Applications/klayout.scripts/KLayoutEditor.app/Contents/MacOS/KLayoutEditor.sh -s ${FOLDER}/${@}"
            )
            file.close()

            self.call_bash("klayout_viewer", filename)
Пример #25
0
def create_ring_gds(radius, width):
    # Reload the library each time to prevent gds library name clashes
    importlib.reload(gdspy)

    ringCell = gdspy.Cell("ring_resonator_r{}_w{}".format(radius, width))

    # Draw the ring
    ringCell.add(
        gdspy.Round((0, 0),
                    inner_radius=radius - width / 2,
                    radius=radius + width / 2,
                    layer=RING_LAYER))

    # Draw the first source
    ringCell.add(
        gdspy.Rectangle((radius - width, 0), (radius + width, 0),
                        SOURCE0_LAYER))

    # Draw the second source
    ringCell.add(
        gdspy.Rectangle((-radius - width, 0), (-radius + width, 0),
                        SOURCE1_LAYER))

    # Draw the monitor location
    ringCell.add(
        gdspy.Rectangle((radius - width / 2, 0), (radius + width / 2, 0),
                        MONITOR_LAYER))

    # Draw the simulation domain
    pad = 2  # padding between waveguide and edge of PML
    ringCell.add(
        gdspy.Rectangle((-radius - width / 2 - pad, -radius - width / 2 - pad),
                        (radius + width / 2 + pad, radius + width / 2 + pad),
                        SIMULATION_LAYER))

    filename = "ring_r{}_w{}.gds".format(radius, width)
    gdspy.write_gds(filename, unit=1.0e-6, precision=1.0e-9)

    return filename
Пример #26
0
def generate_gds(phc, filename, unit=1e-6, tolerance=0.01):
    """Export a GDS file for all layers of a photonic crystal

    Note
    ----
    The ``gdspy`` package is required for exporting GDS files.

    Parameters
    ----------
    phc : PhotCryst
    filename : str
    unit : float, optional
        The GDS spatial units. 
        Default is 1e-6, or 1 um.
    tolerance : float , optional
        The GDS tolerance parameter. 
        Default is 0.01.
    """

    gdspy.current_library = gdspy.GdsLibrary()
    cell = gdspy.Cell('CELL')

    # TODO: Can also add a `datatype`, ranging from 0-255, to each shape for use
    # by whatever program ends up reading the GDS

    for i, layer in enumerate(phc.layers):
        for shape in layer.shapes:
            if type(shape) in [Poly, Square, Hexagon]:
                points = [(x, y) for (x,y) in zip(shape.x_edges[:-1], shape.y_edges[:-1])]
                poly = gdspy.Polygon(points, layer=i, datatype=1)
                cell.add(poly)
            elif type(shape) == Circle:
                circle = gdspy.Round((shape.x_cent, shape.y_cent), shape.r, layer=i, datatype=1, tolerance=tolerance)
                cell.add(circle)
            else:
                raise RuntimeError("Unknown shape type, %s, found in layer %d of phc" % (type(shape), i))

    gdspy.write_gds(filename, unit=unit)
Пример #27
0
def svg2gds_bend(df: pd.DataFrame,
                 line_width: float = 0.125,
                 bend_radius: float = 5,
                 gds_filename: str = 'fiberBoard896bend.gds',
                 save_folder: str = './results/') -> None:
    gdspy.current_library = gdspy.GdsLibrary()
    # gdspy.unit=1e-3
    cell = gdspy.Cell('wiring896')
    for i in range(df.shape[0]):
        points = []
        for j in range(len(df["inflection_x"][i])):
            points = points + [
                tuple([df["inflection_x"][i][j], df["inflection_y"][i][j]])
            ]

        # multiply 1000 to convert mm to um
        sp = gdspy.FlexPath(points,
                            line_width,
                            corners="circular bend",
                            bend_radius=bend_radius,
                            gdsii_path=True)
        cell.add(sp)
    gdspy.write_gds(save_folder + gds_filename)
Пример #28
0
def poly2gds(polyvertice, corners, args):
    f = open('auto.seq', 'w')
    epsilon = 4
    for vset in polyvertice:
        # print('vset',vset)
        seqList = []
        for v in vset:
            for i, corner in enumerate(corners):
                dist = distance(v, corner)
                if dist <= epsilon:
                    # print('dist',dist)
                    seqList.append(i)
                    continue
        f.write(','.join(str(x) for x in seqList) + '\n')
        # print('seqList',seqList)
    f.close()
    poly_cell = gdspy.Cell('tmp')
    poly = gdspy.PolygonSet(polyvertice, 1)
    # poly_cell.add(poly)
    xlength = max(corners[:, 0]) - min(corners[:, 0])
    ylength = max(corners[:, 1]) - min(corners[:, 1])
    nX = args.nX
    nY = args.nY
    xsep = max(xlength, ylength) * args.sep
    ysep = xsep
    for i in range(nX):
        for j in range(nY):
            xpos = (xlength + xsep) * (i + 1)
            ypos = (ylength + ysep) * (j + 1)
            trans = gdspy.copy(poly, xpos, ypos)
            # print poly
            poly_cell.add(trans)

    if args.out_file is not None:
        gdspy.write_gds(args.out_file,
                        unit=args.scale * 1.0e-9,
                        precision=1.0e-9)
Пример #29
0
    # cdc = ContraDirectionalCoupler(wgt, length=30.0, gap=1.0, period=0.5, dc=0.5, angle=np.pi/12.0, width_top=3.0, width_bot=2.0, input_bot=True, **wg1.portlist["output"])
    # tk.add(top, cdc)

    # wg1=Waveguide([(0,0), (0,100), (50,200), (50, 215)], wgt)
    wg1=Waveguide([(0,0), (100,0)], wgt)
    tk.add(top, wg1)

    cdc2 = ContraDirectionalCoupler(wgt, length=30.0, gap=1.0, period=0.5, dc=0.5, angle=np.pi/12.0, width_top=3.0, width_bot=2.0, dw_top=0.4, dw_bot=0.2, input_bot=False, contradc_wgt=contradc_wgt, fins=True, **wg1.portlist["output"])
    tk.add(top, cdc2)

    # x0,y0 = cdc2.portlist["input_bot"]["port"]
    # wg2=Waveguide([(x0,y0), (x0,y0-15), (x0+50,y0-115), (x0+50, y0-215)], wgt)
    # tk.add(top, wg2)

    # dc1 = ContraDirectionalCoupler(wgt, length=30.0, gap=0.5, period=0.220, dc=0.5, angle=np.pi/6.0, width_top=2.0, width_bot=0.75, input_bot=False, **wg1.portlist["output"])
    # dc2 = ContraDirectionalCoupler(wgt, length=30.0, gap=0.5, period=0.220, dc=0.5, angle=np.pi/6.0, width_top=2.0, width_bot=0.75, input_bot=True, **dc1.portlist["output_top"])
    # dc3 = ContraDirectionalCoupler(wgt, length=30.0, gap=0.5, period=0.220, dc=0.5, angle=np.pi/6.0, width_top=2.0, width_bot=0.75, input_bot=False, **dc1.portlist["output_bot"])
    # dc4 = ContraDirectionalCoupler(wgt, length=30.0, gap=0.5, period=0.220, dc=0.5, angle=np.pi/6.0, width_top=2.0, width_bot=0.75, input_bot=False, **dc2.portlist["output_bot"])
    # dc5 = ContraDirectionalCoupler(wgt, length=30.0, gap=0.5, period=0.220, dc=0.5, angle=np.pi/6.0, width_top=2.0, width_bot=0.75, input_bot=True, **dc2.portlist["output_top"])
    # dc6 = ContraDirectionalCoupler(wgt, length=30.0, gap=0.5, period=0.220, dc=0.5, angle=np.pi/6.0, width_top=2.0, width_bot=0.75, input_bot=False, **dc3.portlist["output_bot"])
    # tk.add(top, dc1)
    # tk.add(top, dc2)
    # tk.add(top, dc3)
    # tk.add(top, dc4)
    # tk.add(top, dc5)
    # tk.add(top, dc6)

    # gdspy.LayoutViewer(cells=top)
    gdspy.write_gds('contradc.gds', unit=1.0e-6, precision=1.0e-9)
Пример #30
0
                      100,
                      ltail=100,
                      d_dots=d_dots,
                      constriction=False,
                      SQUID=False)
res4_x = 4500
res4_coarse = [
    rs.move(i, res4_x, feedline_bot - feedline_sep + feedline_y)
    for i in res4[0]
]
res4_fine = [
    rs.move(i, res4_x, feedline_bot - feedline_sep + feedline_y)
    for i in res4[1]
]
res4_remove = [
    rs.move(i, res4_x, feedline_bot - feedline_sep + feedline_y)
    for i in res4[2]
]
for i in res4_coarse:
    poly_cell.add(gdspy.Polygon(i, 4))
for i in res4_fine:
    poly_cell.add(gdspy.Polygon(i, 4))

DC = rs.DC_contacts_etch(4800, 5800, 10, 100, 300, 10)
for i in DC:
    poly_cell.add(gdspy.Polygon(i, 5))

#Write the pattern as a gds file
os.chdir(folder)
gdspy.write_gds('chip_test.gds', unit=1.0e-6, precision=1.0e-9)
# gdspy.LayoutViewer()
Пример #31
0
text2 = gdspy.copy(text1, 0, -20)
label1 = gdspy.Label(
    'Created with gdspy ' + gdspy.__version__, (-7, -36), 'nw', layer=6)
label2 = gdspy.copy(label1, 0, -20)
trans_cell.add(text1)
trans_cell.add(text2)
trans_cell.add(label1)
trans_cell.add(label2)

# ------------------------------------------------------------------ #
#      OUTPUT
# ------------------------------------------------------------------ #

# Output the layout to a GDSII file (default to all created cells).
# Set the units we used to micrometers and the precision to nanometers.
gdspy.write_gds('tutorial.gds', unit=1.0e-6, precision=1.0e-9)

# ------------------------------------------------------------------ #
#      IMPORT
# ------------------------------------------------------------------ #

# Import the file we just created, and extract the cell 'POLYGONS'. To
# avoid naming conflict, we will rename all cells.
gdsii = gdspy.GdsLibrary()
gdsii.read_gds(
    'tutorial.gds',
    rename={
        'POLYGONS': 'IMPORT_POLY',
        'PATHS': 'IMPORT_PATHS',
        'OPERATIONS': 'IMPORT_OPER',
        'SLICE': 'IMPORT_SLICE',
Пример #32
0
def test_write_gds(tmpdir):
    gdspy.current_library = gdspy.GdsLibrary()
    c1 = gdspy.Cell('fu_rw_gds_1')
    c1.add(gdspy.Rectangle((0, -1), (1, 2), 2, 4))
    c1.add(gdspy.Label('label', (1, -1), 'w', 45, 1.5, True, 5, 6))
    c2 = gdspy.Cell('fu_rw_gds_2')
    c2.add(gdspy.Round((0, 0), 1, number_of_points=32, max_points=20))
    c3 = gdspy.Cell('fu_rw_gds_3')
    c3.add(gdspy.CellReference(c1, (0, 1), -90, 2, True))
    c4 = gdspy.Cell('fu_rw_gds_4')
    c4.add(gdspy.CellArray(c2, 2, 3, (1, 4), (-1, -2), 180, 0.5, True))

    fname1 = str(tmpdir.join('test1.gds'))
    gdspy.write_gds(fname1, name='lib', unit=2e-6, precision=1e-8)
    lib1 = gdspy.GdsLibrary(
        infile=fname1,
        units='convert',
        rename={'fu_rw_gds_1': '1'},
        layers={2: 4},
        datatypes={4: 2},
        texttypes={6: 7})
    assert lib1.name == 'lib'
    assert len(lib1.cell_dict) == 4
    assert set(lib1.cell_dict.keys()) == {
        '1', 'fu_rw_gds_2', 'fu_rw_gds_3', 'fu_rw_gds_4'
    }
    c = lib1.cell_dict['1']
    assert len(c.elements) == len(c.labels) == 1
    assert c.elements[0].area() == 12.0
    assert c.elements[0].layers == [4]
    assert c.elements[0].datatypes == [2]
    assert c.labels[0].text == 'label'
    assert c.labels[0].position[0] == 2 and c.labels[0].position[1] == -2
    assert c.labels[0].anchor == 4
    assert c.labels[0].rotation == 45
    assert c.labels[0].magnification == 1.5
    assert c.labels[0].x_reflection == True
    assert c.labels[0].layer == 5
    assert c.labels[0].texttype == 7

    c = lib1.cell_dict['fu_rw_gds_2']
    assert len(c.elements) == 2
    assert isinstance(c.elements[0], gdspy.Polygon) \
           and isinstance(c.elements[1], gdspy.Polygon)

    c = lib1.cell_dict['fu_rw_gds_3']
    assert len(c.elements) == 1
    assert isinstance(c.elements[0], gdspy.CellReference)
    assert c.elements[0].ref_cell == lib1.cell_dict['1']
    assert c.elements[0].origin[0] == 0 and c.elements[0].origin[1] == 2
    assert c.elements[0].rotation == -90
    assert c.elements[0].magnification == 2
    assert c.elements[0].x_reflection == True

    c = lib1.cell_dict['fu_rw_gds_4']
    assert len(c.elements) == 1
    assert isinstance(c.elements[0], gdspy.CellArray)
    assert c.elements[0].ref_cell == lib1.cell_dict['fu_rw_gds_2']
    assert c.elements[0].origin[0] == -2 and c.elements[0].origin[1] == -4
    assert c.elements[0].rotation == 180
    assert c.elements[0].magnification == 0.5
    assert c.elements[0].x_reflection == True
    assert c.elements[0].spacing[0] == 2 and c.elements[0].spacing[1] == 8
    assert c.elements[0].columns == 2
    assert c.elements[0].rows == 3

    fname2 = str(tmpdir.join('test2.gds'))
    with open(fname2, 'wb') as fout:
        gdspy.write_gds(fout, name='lib2', unit=2e-3, precision=1e-5)
    with open(fname2, 'rb') as fin:
        lib2 = gdspy.GdsLibrary()
        lib2.read_gds(fin)
    assert lib2.name == 'lib2'
    assert len(lib2.cell_dict) == 4