def library(): lib = gdspy.GdsLibrary() c1 = gdspy.Cell("cell1") 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("cell2") c2.add(gdspy.Round((0, 0), 1, number_of_points=32, max_points=20)) c3 = gdspy.Cell("cell3") c3.add(gdspy.CellReference(c1, (0, 1), -90, 2, True)) c4 = gdspy.Cell("cell04") c4.add(gdspy.CellArray(c2, 2, 3, (1, 4), (-1, -2), 180, 0.5, True)) lib.add([c1, c2, c3, c4]) return lib
def label(self, text='hello', position=(0, 0), layer=255): if len(text) >= 1023: raise ValueError( '[DEVICE] label() error: Text too long (limit 1024 chars)') gds_layer, gds_datatype = _parse_layer(layer) if type(text) is not str: text = str(text) self.add( gdspy.Label(text=text, position=position, anchor='o', layer=gds_layer, texttype=gds_datatype)) return self
def commit_to_gdspy(self, cell): if self.__repr__() not in list(LabelAbstract.__committed__.keys()): L = gdspy.Label(self.text, deepcopy(self.position), anchor='o', rotation=self.rotation, magnification=self.magnification, x_reflection=self.reflection, layer=self.gdslayer.number, texttype=self.texttype ) cell.add(L) LabelAbstract.__committed__.update({self.__repr__():L}) else: cell.add(LabelAbstract.__committed__[self.__repr__()])
def bench_gdspy(output=None): c1 = gdspy.Cell("REF", exclude_from_current=True) c1.add(gdspy.Rectangle((0, 0), (10, 10))) c1.add( gdspy.FlexPath([(0, 0), (10, 0), (10, 10), (0, 10)], [0.1, 0.1], 0.3, layer=1)) c1.add(gdspy.Label("Label", (5, 5), anchor='o')) c2 = gdspy.Cell("MAIN", exclude_from_current=True) c2.add(gdspy.CellArray(c1, columns=3, rows=2, spacing=(20, 20))) c2.flatten() c1.remove_polygons(lambda *_: True) c1.remove_paths(lambda *_: True) c1.remove_labels(lambda *_: True) if output: c2.write_svg(output, 10)
def test_add_label_rotation(): # add a child cell with a label c1 = gdspy.Cell("child") label = gdspy.Label("label", (0, 0)) p = gdspy.Polygon(((0, 0), (1, 0), (0, 1))) c1.add(p) c1.add(label) # add parent with rotated cell rotation = 90 c2 = gdspy.Cell("parent") c1ref = gdspy.CellReference(ref_cell=c1, rotation=rotation) c2.add(c1ref) label_rotation = c2.get_labels(set_transform=True)[0].rotation assert label_rotation == rotation, [label_rotation, rotation]
def test_copy(): name = 'c_copy' p = gdspy.Polygon(((0, 0), (1, 0), (0, 1))) l = gdspy.Label('label', (0, 0)) c1 = gdspy.Cell(name) c1.add(p) c1.add(l) with pytest.raises(ValueError) as e: c2 = c1.copy(name) assert name in str(e.value) c3 = c1.copy(name, True) assert c3.elements == c1.elements and c3.elements is not c1.elements assert c3.labels == c1.labels and c3.labels is not c1.labels c4 = c1.copy('c_copy_1', False, True) assert c4.elements != c1.elements assert c4.labels != c1.labels
def test_copy(): name = "c_copy" p = gdspy.Polygon(((0, 0), (1, 0), (0, 1))) lbl = gdspy.Label("label", (0, 0)) c1 = gdspy.Cell(name) c1.add(p) c1.add(lbl) c3 = c1.copy(name, False) assert c3.polygons == c1.polygons and c3.polygons is not c1.polygons assert c3.labels == c1.labels and c3.labels is not c1.labels cref = gdspy.Cell("c_ref").add(gdspy.Rectangle((-1, -1), (-2, -2))) c1.add(gdspy.CellReference(cref)) c1.get_bounding_box() c4 = c1.copy("c_copy_1", True) assert c4.polygons != c1.polygons assert c4.labels != c1.labels assert c1._bb_valid assert cref._bb_valid assert not c4._bb_valid
def test_properties(tmpdir): lib = gdspy.GdsLibrary() c1 = lib.new_cell("POLY") rect = gdspy.Rectangle((0, 0), (2, 1)) rect.properties[1] = "test1" rect.properties[126] = "test_126" lbl = gdspy.Label("LABEL", (20, 20)) lbl.properties[2] = "test2" lbl.properties[22] = "test22" c1.add((rect, lbl)) c2 = lib.new_cell("REF") ref = gdspy.CellReference(c1, (0, 0)) ref.properties[6] = "test6" ref.properties[121] = "test_121" c2.add(ref) c3 = lib.new_cell("AREF") aref = gdspy.CellArray(c1, 1, 2, (30, 40), (0, 0)) aref.properties[4] = "test4" aref.properties[123] = "test_123" c3.add(aref) c4 = lib.new_cell("FP") fp = gdspy.FlexPath([(0, 0), (0, 1), (1, 1)], 0.01, gdsii_path=True) fp.properties[2] = "test2" fp.properties[125] = "test_125" c4.add(fp) c5 = lib.new_cell("RP") rp = gdspy.RobustPath((0, 0), [0.01, 0.01], 0.5, gdsii_path=True).segment( (1, 1)) rp.properties[3] = "test3" rp.properties[124] = "test_124" c5.add(rp) fname = str(tmpdir.join("test_properties.gds")) lib.write_gds(fname) lib1 = gdspy.GdsLibrary(infile=fname) assert rect.properties == lib1.cells["POLY"].polygons[0].properties assert lbl.properties == lib1.cells["POLY"].labels[0].properties assert ref.properties == lib1.cells["REF"].references[0].properties assert aref.properties == lib1.cells["AREF"].references[0].properties assert fp.properties == lib1.cells["FP"].paths[0].properties assert rp.properties == lib1.cells["RP"].paths[0].properties assert rp.properties == lib1.cells["RP"].paths[1].properties
def test_copy(): gdspy.current_library = gdspy.GdsLibrary() name = "c_copy" p = gdspy.Polygon(((0, 0), (1, 0), (0, 1))) lbl = gdspy.Label("label", (0, 0)) c1 = gdspy.Cell(name) c1.add(p) c1.add(lbl) with pytest.raises(ValueError) as e: c1.copy(name) assert name in str(e.value) c3 = c1.copy(name, True) assert c3.polygons == c1.polygons and c3.polygons is not c1.polygons assert c3.labels == c1.labels and c3.labels is not c1.labels cref = gdspy.Cell("c_ref").add(gdspy.Rectangle((-1, -1), (-2, -2))) c1.add(gdspy.CellReference(cref)) c1.get_bounding_box() c4 = c1.copy("c_copy_1", False, True) assert c4.polygons != c1.polygons assert c4.labels != c1.labels assert c1._bb_valid assert cref._bb_valid assert not c4._bb_valid
def export_content_list(self, content_lists: List["ContentList"], name_append: str = '', max_points_per_polygon: Optional[int] = None, write_gds: bool = True, ): """ Exports the physical design to GDS Parameters ---------- content_lists : List[ContentList] A list of ContentList objects that represent the layout. name_append : str A suffix to add to the end of the generated gds filename max_points_per_polygon : Optional[int] Maximum number of points allowed per polygon shape in the gds. Defaults to value set in the init of GDSPlugin if not specified. write_gds : bool Default True. True to write out the gds file. False to create the gdspy object, but not write out the gds. """ logging.info(f'In PhotonicTemplateDB._create_gds') tech_info = self.grid.tech_info lay_unit = tech_info.layout_unit res = tech_info.resolution if not max_points_per_polygon: max_points_per_polygon = self.max_points_per_polygon with open(self.gds_layermap, 'r') as f: lay_info = yaml.load(f) lay_map = lay_info['layer_map'] via_info = lay_info['via_info'] # TODO: fix out_fname = self.gds_filepath + f'{name_append}.gds' gds_lib = gdspy.GdsLibrary(name=self.lib_name, unit=lay_unit, precision=res * lay_unit) cell_dict = gds_lib.cell_dict logging.info(f'Instantiating gds layout') start = time.time() for content_list in content_lists: gds_cell = gdspy.Cell(content_list.cell_name, exclude_from_current=True) gds_lib.add(gds_cell) # add instances for inst_info in content_list.inst_list: # type: InstanceInfo if inst_info.params is not None: raise ValueError('Cannot instantiate PCells in GDS.') num_rows = inst_info.num_rows num_cols = inst_info.num_cols angle, reflect = inst_info.angle_reflect if num_rows > 1 or num_cols > 1: cur_inst = gdspy.CellArray(cell_dict[inst_info.cell], num_cols, num_rows, (inst_info.sp_cols, inst_info.sp_rows), origin=inst_info.loc, rotation=angle, x_reflection=reflect) else: cur_inst = gdspy.CellReference(cell_dict[inst_info.cell], origin=inst_info.loc, rotation=angle, x_reflection=reflect) gds_cell.add(cur_inst) # add rectangles for rect in content_list.rect_list: nx, ny = rect.get('arr_nx', 1), rect.get('arr_ny', 1) (x0, y0), (x1, y1) = rect['bbox'] lay_id, purp_id = lay_map[tuple(rect['layer'])] if nx > 1 or ny > 1: spx, spy = rect['arr_spx'], rect['arr_spy'] for xidx in range(nx): dx = xidx * spx for yidx in range(ny): dy = yidx * spy cur_rect = gdspy.Rectangle((x0 + dx, y0 + dy), (x1 + dx, y1 + dy), layer=lay_id, datatype=purp_id) gds_cell.add(cur_rect) else: cur_rect = gdspy.Rectangle((x0, y0), (x1, y1), layer=lay_id, datatype=purp_id) gds_cell.add(cur_rect) # add vias for via in content_list.via_list: # type: ViaInfo via_lay_info = via_info[via.id] nx, ny = via.arr_nx, via.arr_ny x0, y0 = via.loc if nx > 1 or ny > 1: spx, spy = via.arr_spx, via.arr_spy for xidx in range(nx): xc = x0 + xidx * spx for yidx in range(ny): yc = y0 + yidx * spy self._add_gds_via(gds_cell, via, lay_map, via_lay_info, xc, yc) else: self._add_gds_via(gds_cell, via, lay_map, via_lay_info, x0, y0) # add pins for pin in content_list.pin_list: # type: PinInfo lay_id, purp_id = lay_map[pin.layer] bbox = pin.bbox label = pin.label if pin.make_rect: cur_rect = gdspy.Rectangle((bbox.left, bbox.bottom), (bbox.right, bbox.top), layer=lay_id, datatype=purp_id) gds_cell.add(cur_rect) angle = 90 if bbox.height_unit > bbox.width_unit else 0 cur_lbl = gdspy.Label(label, (bbox.xc, bbox.yc), rotation=angle, layer=lay_id, texttype=purp_id) gds_cell.add(cur_lbl) for path in content_list.path_list: # Photonic paths should be treated like polygons lay_id, purp_id = lay_map[path['layer']] cur_path = gdspy.Polygon(path['polygon_points'], layer=lay_id, datatype=purp_id) gds_cell.add(cur_path.fracture(precision=res, max_points=max_points_per_polygon)) for blockage in content_list.blockage_list: pass for boundary in content_list.boundary_list: pass for polygon in content_list.polygon_list: lay_id, purp_id = lay_map[polygon['layer']] cur_poly = gdspy.Polygon(polygon['points'], layer=lay_id, datatype=purp_id) gds_cell.add(cur_poly.fracture(precision=res, max_points=max_points_per_polygon)) for round_obj in content_list.round_list: nx, ny = round_obj.get('arr_nx', 1), round_obj.get('arr_ny', 1) lay_id, purp_id = lay_map[tuple(round_obj['layer'])] x0, y0 = round_obj['center'] if nx > 1 or ny > 1: spx, spy = round_obj['arr_spx'], round_obj['arr_spy'] for xidx in range(nx): dx = xidx * spx for yidx in range(ny): dy = yidx * spy cur_round = gdspy.Round((x0 + dx, y0 + dy), radius=round_obj['rout'], inner_radius=round_obj['rin'], initial_angle=round_obj['theta0'] * pi / 180, final_angle=round_obj['theta1'] * pi / 180, tolerance=self.grid.resolution, layer=lay_id, datatype=purp_id) gds_cell.add(cur_round) else: cur_round = gdspy.Round((x0, y0), radius=round_obj['rout'], inner_radius=round_obj['rin'], initial_angle=round_obj['theta0'] * pi / 180, final_angle=round_obj['theta1'] * pi / 180, tolerance=self.grid.resolution, layer=lay_id, datatype=purp_id) gds_cell.add(cur_round) if write_gds: gds_lib.write_gds(out_fname) end = time.time() logging.info(f'Layout gds instantiation took {end - start:.4g}s') return gds_lib
def make_label(self, coords, text, layer): purpose = 'label' layer_num = self.get_layer_dtype_tuple(layer) # centroid = [round(((coords[0] + coords[2]) / 2), 3), round((coords[1] + coords[3]) / 2, 3)] name = text return gp.Label(text, coords, layer=layer_num)
def memory_benchmark(): proc = psutil.Process() total = 100000 print(f"\nMemory usage per object for {total} objects:\n") def print_row(*vals, hsep=False): columns = [20, 16, 16, 9] print( "|", vals[0].ljust(columns[0]), "|", " | ".join(v.center(c) for v, c in zip(vals[1:], columns[1:])), "|", ) if hsep: print( "|", ":" + "-" * (columns[0] - 1), "|", " | ".join(":" + "-" * (c - 2) + ":" for c in columns[1:]), "|", ) print_row( "Object", "Gdspy " + gdspy.__version__, "Gdstk " + gdstk.__version__, "Reduction", hsep=True, ) def mem_test(func): start_mem = proc.memory_info() r = [func(i) for i in range(total)] end_mem = proc.memory_info() return (end_mem.vms - start_mem.vms) / total, r data = [] gdspy_cell = gdspy.Cell("TEMP", exclude_from_current=True) gdstk_cell = gdstk.Cell("TEMP") for obj, gdspy_func, gdstk_func in [ ( "Rectangle", lambda i: gdspy.Rectangle((i, i), (i + 1, i + 1)), lambda i: gdstk.rectangle((i, i), (i + 1, i + 1)), ), ( "Circle (r = 10)", lambda i: gdspy.Round((0, 10 * i), 10), lambda i: gdstk.ellipse((0, 10 * i), 10), ), ( "FlexPath segment", lambda i: gdspy.FlexPath([(i, i + 1), (i + 1, i)], 0.1), lambda i: gdstk.FlexPath([(i, i + 1), (i + 1, i)], 0.1), ), ( "FlexPath arc", lambda i: gdspy.FlexPath([(10 * i, 0)], 0.1).arc(10, 0, numpy.pi), lambda i: gdstk.FlexPath([(10 * i, 0)], 0.1).arc(10, 0, numpy.pi), ), ( "RobustPath segment", lambda i: gdspy.RobustPath((i, i + 1), 0.1).segment((i + 1, i)), lambda i: gdstk.RobustPath((i, i + 1), 0.1).segment((i + 1, i)), ), ( "RobustPath arc", lambda i: gdspy.RobustPath((10 * i, 0), 0.1).arc(10, 0, numpy.pi), lambda i: gdstk.RobustPath((10 * i, 0), 0.1).arc(10, 0, numpy.pi), ), ( "Label", lambda i: gdspy.Label(str(i), (i, i)), lambda i: gdstk.Label(str(i), (i, i)), ), ( "Reference", lambda i: gdspy.CellReference(gdspy_cell, (0, 0)), lambda i: gdstk.Reference(gdstk_cell, (0, 0)), ), ( "Reference (array)", lambda i: gdspy.CellArray(gdspy_cell, (0, 0), 1, 1, (0, 0)), lambda i: gdstk.Reference(gdstk_cell, (0, 0), rows=1, columns=1), ), ( "Cell", lambda i: gdspy.Cell(str(i), exclude_from_current=True), lambda i: gdstk.Cell(str(i)), ), ]: gdspy_mem, gdspy_data = mem_test(gdspy_func) data.append(gdspy_data) gdstk_mem, gdstk_data = mem_test(gdstk_func) data.append(gdstk_data) print_row( obj, prefix_format(gdspy_mem, unit="B", base="bin"), prefix_format(gdstk_mem, unit="B", base="bin"), f"{100 - 100 * gdstk_mem / gdspy_mem:.0f}%", )
def test_rw_gds(tmpdir): lib = gdspy.GdsLibrary('lib') c1 = gdspy.Cell('gl_rw_gds_1', True) 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('gl_rw_gds_2', True) c2.add(gdspy.Round((0, 0), 1, number_of_points=32, max_points=20)) c3 = gdspy.Cell('gl_rw_gds_3', True) c3.add(gdspy.CellReference(c1, (0, 1), -90, 2, True)) c4 = gdspy.Cell('gl_rw_gds_4', True) c4.add(gdspy.CellArray(c2, 2, 3, (1, 4), (-1, -2), 180, 0.5, True)) lib.add((c1, c2, c3, c4)) fname1 = str(tmpdir.join('test1.gds')) lib.write_gds(fname1, unit=2e-3, precision=1e-5) lib1 = gdspy.GdsLibrary() lib1.read_gds(fname1, 1e-3, {'gl_rw_gds_1': '1'}, {2: 4}, {4: 2}, {6: 7}) assert lib1.name == 'lib' assert len(lib1.cell_dict) == 4 assert set(lib1.cell_dict.keys()) == { '1', 'gl_rw_gds_2', 'gl_rw_gds_3', 'gl_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].layer == 4 assert c.elements[0].datatype == 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['gl_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['gl_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['gl_rw_gds_4'] assert len(c.elements) == 1 assert isinstance(c.elements[0], gdspy.CellArray) assert c.elements[0].ref_cell == lib1.cell_dict['gl_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')) lib.name = 'lib2' with open(fname2, 'wb') as fout: lib.write_gds(fout, 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
# Fillet Operation multi_path = gdspy.Path(2, (-3, -2)) multi_path.segment(4, "+x") multi_path.turn(2, "l").turn(2, "r") multi_path.segment(4) # Create a copy with joined polygons and no fracturing joined = gdspy.boolean(multi_path, None, "or", max_points=0) joined.translate(0, -5) # Fillet applied to each polygon in the path multi_path.fillet(0.5) # Fillet applied to the joined copy joined.fillet(0.5) draw(gdspy.Cell("fillet_operation").add([joined, multi_path])) # Text # Label anchored at (1, 3) by its north-west corner label = gdspy.Label("Sample label", (1, 3), "nw") # Horizontal text with height 2.25 htext = gdspy.Text("12345", 2.25, (0.25, 6)) # Vertical text with height 1.5 vtext = gdspy.Text("ABC", 1.5, (10.5, 4), horizontal=False) rect = gdspy.Rectangle((0, 0), (10, 6), layer=10) draw(gdspy.Cell("text").add([htext, vtext, label, rect]))
gdspy.CellArray('OPERATIONS', 3, 2, (35, 30), (25, 10), magnification=1.5)) # Text are also sets of polygons. They have edges parallel to 'x' and # 'y' only. ref_cell.add( gdspy.Text('Created with gsdpy ' + gdspy.__version__, 7, (-7, -35), layer=6)) # Labels are special text objects which don't define any actual # geometry, but can be used to annotate the drawing. Rotation, # magnification and reflection of the text are not supported by the # included GUI, but they are included in the resulting GDSII file. ref_cell.add( gdspy.Label('Created with gdspy ' + gdspy.__version__, (-7, -36), 'nw', layer=6)) # ------------------------------------------------------------------ # # Translation # ------------------------------------------------------------------ # trans_cell = gdspy.Cell('TRANS') # Any geometric object can be translated by providing the distance to # translate in the x-direction and y-direction: translate(dx, dy) rect1 = gdspy.Rectangle((80, 0), (81, 1), 1) rect1.translate(2, 0) trans_cell.add(rect1) # Translatable objects can also be copied & translated in the same way.
def test_writer_gds(tmpdir): lib = gdspy.GdsLibrary() c1 = gdspy.Cell("gw_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("gw_rw_gds_2") c2.add(gdspy.Round((0, 0), 1, number_of_points=32, max_points=20)) c3 = gdspy.Cell("gw_rw_gds_3") c3.add(gdspy.CellReference(c1, (0, 1), -90, 2, True)) c4 = gdspy.Cell("gw_rw_gds_4") c4.add(gdspy.CellArray(c2, 2, 3, (1, 4), (-1, -2), 180, 0.5, True)) lib.add((c1, c2, c3, c4)) fname1 = str(tmpdir.join("test1.gds")) writer1 = gdspy.GdsWriter(fname1, name="lib", unit=2e-3, precision=1e-5) for c in lib.cells.values(): writer1.write_cell(c) writer1.close() lib1 = gdspy.GdsLibrary(unit=1e-3) lib1.read_gds( fname1, units="convert", rename={"gw_rw_gds_1": "1"}, layers={2: 4}, datatypes={4: 2}, texttypes={6: 7}, ) assert lib1.name == "lib" assert len(lib1.cells) == 4 assert set(lib1.cells.keys()) == {"1", "gw_rw_gds_2", "gw_rw_gds_3", "gw_rw_gds_4"} c = lib1.cells["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.cells["gw_rw_gds_2"] assert len(c.polygons) == 2 assert isinstance(c.polygons[0], gdspy.Polygon) and isinstance( c.polygons[1], gdspy.Polygon ) c = lib1.cells["gw_rw_gds_3"] assert len(c.references) == 1 assert isinstance(c.references[0], gdspy.CellReference) assert c.references[0].ref_cell == lib1.cells["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.cells["gw_rw_gds_4"] assert len(c.references) == 1 assert isinstance(c.references[0], gdspy.CellArray) assert c.references[0].ref_cell == lib1.cells["gw_rw_gds_2"] 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: writer2 = gdspy.GdsWriter(fout, name="lib2", unit=2e-3, precision=1e-5) for c in lib.cells.values(): writer2.write_cell(c) writer2.close() with open(fname2, "rb") as fin: lib2 = gdspy.GdsLibrary() lib2.read_gds(fin) assert lib2.name == "lib2" assert len(lib2.cells) == 4
# Fillet Operation multi_path = gdspy.Path(2, (-3, -2)) multi_path.segment(4, '+x') multi_path.turn(2, 'l').turn(2, 'r') multi_path.segment(4) # Create a copy with joined polygons and no fracturing joined = gdspy.boolean(multi_path, None, 'or', max_points=0) joined.translate(0, -5) # Fillet applied to each polygon in the path multi_path.fillet(0.5) # Fillet applied to the joined copy joined.fillet(0.5) draw(gdspy.Cell('fillet_operation').add([joined, multi_path])) # Text # Label anchored at (1, 3) by its north-west corner label = gdspy.Label('Sample label', (1, 3), 'nw') # Horizontal text with height 2.25 htext = gdspy.Text('12345', 2.25, (0.25, 6)) # Vertical text with height 1.5 vtext = gdspy.Text('ABC', 1.5, (10.5, 4), horizontal=False) rect = gdspy.Rectangle((0, 0), (10, 6), layer=10) draw(gdspy.Cell('text').add([htext, vtext, label, rect]))
def test_add_label(): l = gdspy.Label('label', (0, 0)) c = gdspy.Cell('c_add_label') assert c.add(l) is c assert c.add([l, l]) is c assert c.labels == [l, l, l]
def get_label(self): return gdspy.Label(self.text, self.position, rotation=0, layer=64)
def test_add_label(): lbl = gdspy.Label("label", (0, 0)) c = gdspy.Cell("c_add_label") assert c.add(lbl) is c assert c.add([lbl, lbl]) is c assert c.labels == [lbl, lbl, lbl]
c1.add(label) # add parent with rotated cell rotation = 90 c2 = gdspy.Cell("parent") c1ref = gdspy.CellReference(ref_cell=c1, rotation=rotation) c2.add(c1ref) label_rotation = c2.get_labels(set_transform=True)[0].rotation assert label_rotation == rotation, [label_rotation, rotation] if __name__ == "__main__": # add a child cell with a label c1 = gdspy.Cell("child") label = gdspy.Label("label", (0, 0)) p = gdspy.Polygon(((0, 0), (1, 0), (0, 1))) c1.add(p) c1.add(label) # add parent with rotated cell rotation = 90 dx = 5 dy = 10 c2 = gdspy.Cell("parent") c1ref = gdspy.CellReference(ref_cell=c1, rotation=rotation, x_reflection=True) c1ref.translate(dx, dy) c2.add(c1ref)