def test_common_options(self): opt = pya.LoadLayoutOptions() lm = pya.LayerMap() lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17)) opt.set_layer_map(lm, True) self.assertEqual(opt.layer_map.to_string(), "1/0 : 42/17\n") self.assertEqual(opt.create_other_layers, True) opt.create_other_layers = False self.assertEqual(opt.create_other_layers, False) opt.select_all_layers() self.assertEqual(opt.layer_map.to_string(), "") self.assertEqual(opt.create_other_layers, True) opt.text_enabled = True self.assertEqual(opt.text_enabled, True) opt.text_enabled = False self.assertEqual(opt.text_enabled, False) opt.properties_enabled = True self.assertEqual(opt.properties_enabled, True) opt.properties_enabled = False self.assertEqual(opt.properties_enabled, False)
def test_cif_options(self): opt = pya.LoadLayoutOptions() lm = pya.LayerMap() lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17)) opt.cif_set_layer_map(lm, True) self.assertEqual(opt.cif_layer_map.to_string(), "1/0 : 42/17\n") self.assertEqual(opt.cif_create_other_layers, True) opt.cif_create_other_layers = False self.assertEqual(opt.cif_create_other_layers, False) opt.cif_select_all_layers() self.assertEqual(opt.cif_layer_map.to_string(), "") self.assertEqual(opt.cif_create_other_layers, True) opt.cif_keep_layer_names = True self.assertEqual(opt.cif_keep_layer_names, True) opt.cif_keep_layer_names = False self.assertEqual(opt.cif_keep_layer_names, False) opt.cif_wire_mode = 2 self.assertEqual(opt.cif_wire_mode, 2) opt.cif_wire_mode = 4 self.assertEqual(opt.cif_wire_mode, 4) opt.cif_dbu = 0.5 self.assertEqual(opt.cif_dbu, 0.5)
def test_gds2_options(self): opt = pya.LoadLayoutOptions() lm = pya.LayerMap() lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17)) opt.set_layer_map(lm, True) opt.gds2_allow_multi_xy_records = True self.assertEqual(opt.gds2_allow_multi_xy_records, True) opt.gds2_allow_multi_xy_records = False self.assertEqual(opt.gds2_allow_multi_xy_records, False) opt.gds2_resolve_skew_arrays = True self.assertEqual(opt.gds2_resolve_skew_arrays, True) opt.gds2_resolve_skew_arrays = False self.assertEqual(opt.gds2_resolve_skew_arrays, False) opt.gds2_allow_big_records = True self.assertEqual(opt.gds2_allow_big_records, True) opt.gds2_allow_big_records = False self.assertEqual(opt.gds2_allow_big_records, False) opt.gds2_box_mode = 1 self.assertEqual(opt.gds2_box_mode, 1) opt.gds2_box_mode = 2 self.assertEqual(opt.gds2_box_mode, 2)
def test_dxf_options(self): opt = pya.LoadLayoutOptions() lm = pya.LayerMap() lm.map(pya.LayerInfo(1, 0), 2, pya.LayerInfo(42, 17)) opt.dxf_set_layer_map(lm, True) self.assertEqual(opt.dxf_layer_map.to_string(), "1/0 : 42/17\n") self.assertEqual(opt.dxf_create_other_layers, True) opt.dxf_create_other_layers = False self.assertEqual(opt.dxf_create_other_layers, False) opt.dxf_select_all_layers() self.assertEqual(opt.dxf_layer_map.to_string(), "") self.assertEqual(opt.dxf_create_other_layers, True) opt.dxf_dbu = 0.5 self.assertEqual(opt.dxf_dbu, 0.5) opt.dxf_unit = 42 self.assertEqual(opt.dxf_unit, 42) opt.dxf_text_scaling = 0.25 self.assertEqual(opt.dxf_text_scaling, 0.25) opt.dxf_circle_points = 142 self.assertEqual(opt.dxf_circle_points, 142) opt.dxf_circle_accuracy = 1.5 self.assertEqual(opt.dxf_circle_accuracy, 1.5) opt.dxf_contour_accuracy = 0.75 self.assertEqual(opt.dxf_contour_accuracy, 0.75) opt.dxf_render_texts_as_polygons = True self.assertEqual(opt.dxf_render_texts_as_polygons, True) opt.dxf_render_texts_as_polygons = False self.assertEqual(opt.dxf_render_texts_as_polygons, False) opt.dxf_keep_layer_names = True self.assertEqual(opt.dxf_keep_layer_names, True) opt.dxf_keep_layer_names = False self.assertEqual(opt.dxf_keep_layer_names, False) opt.dxf_keep_other_cells = True self.assertEqual(opt.dxf_keep_other_cells, True) opt.dxf_keep_other_cells = False self.assertEqual(opt.dxf_keep_other_cells, False) opt.dxf_polyline_mode = 2 self.assertEqual(opt.dxf_polyline_mode, 2) opt.dxf_polyline_mode = 4 self.assertEqual(opt.dxf_polyline_mode, 4)
def read_layout(layout, gds_filename): global layer_map_dict load_options = pya.LoadLayoutOptions() load_options.text_enabled = True load_options.set_layer_map(layer_map_dict[layout], True) # store and take away the cell names of all cells read so far # (by setting the cell name to "" the cells basically become invisible for # the following read) # take out the pcells cell_list = [cell for cell in layout.each_cell()] cell_indices = {cell.name: cell.cell_index() for cell in cell_list} for i in cell_indices.values(): layout.rename_cell(i, "") lmap = layout.read(gds_filename, load_options) # in the new layout, get all cells names cell_names2 = [(cell.cell_index(), cell.name) for cell in layout.each_cell()] # make those cells point to older cells prune_cells_indices = [] for i_duplicate, name_cached_cell in cell_names2: if name_cached_cell in cell_indices.keys(): if name_cached_cell.startswith('cache_'): for parent_inst_array in layout.cell(i_duplicate).each_parent_inst(): cell_instance = parent_inst_array.child_inst() cell_instance.cell = layout.cell( cell_indices[name_cached_cell]) prune_cells_indices.append(i_duplicate) else: # print('RENAME', name_cached_cell) k = 1 while (name_cached_cell + f"_{k}") in cell_indices.keys(): k += 1 layout.rename_cell(i_duplicate, name_cached_cell + f"_{k}") for i_pruned in prune_cells_indices: # print('deleting cell', layout.cell(i_pruned).name) layout.prune_cell(i_pruned, -1) # every conflict should have been caught above for name, i in cell_indices.items(): layout.rename_cell(i, name) layer_map_dict[layout] = lmap return lmap
def test_3(self): app = pya.Application.instance() mw = app.main_window() mw.close_all() mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", pya.LoadLayoutOptions(), "", 1) mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", pya.LoadLayoutOptions(), "", 2) cv = mw.current_view() self.assertEqual(self.lnodes_str("", cv.begin_layers()), "1/0@1\n2/0@1\n1/0@2\n2/0@2\n3/0@2\n3/1@2\n4/0@2\n5/0@2\n6/0@2\n6/1@2\n7/0@2\n8/0@2\n8/1@2\n") cv.clear_layers() pos = cv.end_layers() self.assertEqual(pos.current().is_valid(), False) cv.insert_layer(pos, pya.LayerProperties()) self.assertEqual(pos.current().is_valid(), True) self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n") self.assertEqual(self.lnodes_str2(cv), "*/*@*") self.assertEqual(cv.begin_layers().current().name, "") self.assertEqual(cv.begin_layers().current().visible, True) self.assertEqual(cv.begin_layers().current().dither_pattern, -1) self.assertEqual(cv.begin_layers().current().line_style, -1) self.assertEqual(cv.begin_layers().current().valid, True) self.assertEqual(cv.begin_layers().current().transparent, False) # test LayerPropertiesNodeRef pos.current().name = "NAME" pos.current().visible = False pos.current().fill_color = 0xff012345 pos.current().frame_color = 0xff123456 pos.current().fill_brightness = 42 pos.current().frame_brightness = 17 pos.current().dither_pattern = 4 pos.current().line_style = 3 pos.current().valid = False pos.current().transparent = True pos.current().marked = False pos.current().xfill = False pos.current().width = 2 pos.current().animation = 2 self.assertEqual(cv.begin_layers().current().name, "NAME") self.assertEqual(cv.begin_layers().current().visible, False) self.assertEqual(cv.begin_layers().current().fill_color, 0xff012345) self.assertEqual(cv.begin_layers().current().frame_color, 0xff123456) self.assertEqual(cv.begin_layers().current().fill_brightness, 42) self.assertEqual(cv.begin_layers().current().frame_brightness, 17) self.assertEqual(cv.begin_layers().current().dither_pattern, 4) self.assertEqual(cv.begin_layers().current().line_style, 3) self.assertEqual(cv.begin_layers().current().valid, False) self.assertEqual(cv.begin_layers().current().transparent, True) self.assertEqual(cv.begin_layers().current().marked, False) self.assertEqual(cv.begin_layers().current().xfill, False) self.assertEqual(cv.begin_layers().current().width, 2) self.assertEqual(cv.begin_layers().current().animation, 2) pos.current().valid = True new_p = pya.LayerProperties() new_p.source = "1/0@1" self.assertEqual(new_p.flat().source, "1/0@1") self.assertEqual(new_p == new_p.flat(), True) self.assertEqual(new_p != new_p.flat(), False) new_p_ref = pos.current().add_child(new_p) self.assertEqual(new_p_ref.layer_index(), cv.cellview(0).layout().layer(1, 0)) self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n") self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1") p = pos.current().add_child() p.source = "1/0@2" self.assertEqual(p.is_valid(), True) self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n") self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n1/0@2") self.assertEqual(p.layer_index(), cv.cellview(1).layout().layer(1, 0)) self.assertEqual(str(p.bbox()), "(-1.4,1.8;25.16,3.8)") self.assertEqual(p.view() == cv, True) self.assertEqual(p.list_index(), 0) l12_new = pya.LayerProperties() l12_new.source = "@* #1..2" self.assertEqual(l12_new.flat().source, "*/*@* #1..2") self.assertEqual(pos.first_child().current().source, "1/0@1") self.assertEqual(pos.first_child().current().is_valid(), True) self.assertEqual(pos.last_child().current().is_valid(), False) pos.first_child().next().current().assign(l12_new) self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n */*@* #1..2\n") self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n*/*@* #1..2") pos.first_child().next_sibling(1).current().source = "@* #3..4" self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n */*@* #3..4\n") self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n*/*@* #3..4") pos.first_child().to_sibling(1).next_sibling(-1).current().source = "7/0" self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 7/0@1\n */*@* #3..4\n") self.assertEqual(self.lnodes_str2(cv), "*/*@*\n7/0@1\n*/*@* #3..4") self.assertEqual(self.lnodes_str3(cv, 0), "*/*@*\n7/0@1\n*/*@* #3..4") self.assertEqual(self.lnodes_str3(cv, 1), "") nn = pya.LayerPropertiesNode() nn.source = "TOP" nn1 = pya.LayerPropertiesNode() nn1.source = "nn1" nn2 = pya.LayerProperties() nn2.source = "nn1" nn1.add_child(nn2) nn.add_child(nn1) pos.current().assign(nn) self.assertEqual(pos.current().id(), nn.id()) self.assertEqual(self.lnodes_str("", cv.begin_layers()), "TOP@1\n nn1@1\n nn1@1\n") self.assertEqual(self.lnodes_str2(cv), "TOP@1\nnn1@1\nnn1@1") mw.close_all()
def save_separate_layers(fname, box_size_pixel, layers_merged=None, save_all_layers=True): """Loads a layout file and saves its layers as separate files. The layout file format can be GDSII or Oasis. A PNG image sides of box_size_pixel will also be saved. The resulting folderstructure of 'mapv3.gds' with 2 layers will be: |-- map9v3 | |-- map9v3_layer_00 |-- map9v3_layer_00.gds | |-- map9v3_layer_01 |-- map9v3_layer_01.gds Optionally, the mask layers consisting of multiple layers are also saved if 'layers_merged' is passed. Args: fname: File name of layout (string) box_size_pixel: Length of the sides of the PNG image in pixels (int) layers_merged: List of layers per layerObjName e.g. [["mask1", [0, 1]], ["mask2", [2, 3]]] ([[string[int]]]) save_all_layers: Whether all layers should also be saved as single files (Bool) Returns: fnames_layer: List of saved layers (strings) """ # Create a folder structure for the many files we will be creating (fname_path, fname_title, fname_ending) = split_file_name(fname) new_folder_path = create_folder_structure(fname_path, fname_title) fname_path = new_folder_path # Klayout class Layout contains cell hierarchy # and manages cell and layout names layout = pya.Layout() # Controls reading of layout files load_opt = pya.LoadLayoutOptions() dbu = layout.dbu # Data base unit print("The data base unit(dbu) of layout", fname_title + "." + fname_ending, "is", str(dbu), "micro meters.") # Settings for loading of layout file load_opt.select_all_layers() # Map logical layer indices to phyical layer names. layer_map = layout.read(fname, load_opt) # Get list of logical layers detected in the file. layer_indices = layout.layer_indices() fnames_layer = [] if save_all_layers: layer_mappings = [] for i in layer_indices: # Two digits with leading zero layer_index_str = "{:02d}".format(layer_indices[i]) fname_layer = fname_path + fname_title + \ "_layer_" + layer_index_str + "." + fname_ending fnames_layer.append(fname_layer) # Get LayerInfo object for current layer with physical layer properties = layout.get_info(i) save_opt = pya.SaveLayoutOptions() save_opt.deselect_all_layers() # Save only one layer (i) save_opt.add_layer(layer_indices[i], properties) layout.write(fname_layer, save_opt) # Save the physical layer mapped to logical layer i as a string layer_map_str_i = layer_map.mapping_str(layer_indices[i]) # The first part contains the information about # the physical layer (layer number/type) layer_phy = layer_map_str_i.split(" ")[0] layer_mappings.append(str(layer_indices[i]) + "," + layer_phy) print("Saving the physical layer", layer_phy, "mapped to logical layer", str(layer_indices[i]), "as", fname_layer) # Load the saved layout files from disk and save as PNG: fname_layer_png = fname_path + fname_title + \ "_layer_" + layer_index_str + ".png" save_as_png(fname_layer, fname_layer_png, box_size_pixel) # Save mapping to text file # Save layer map in same directory as original layout file. fname_layer_map = fname_path + fname_title + "_layermap.csv" with open(fname_layer_map, 'w') as f: f.write("Logical layer, Physical layer\n") for m in layer_mappings: f.write(m + "\n") print("The mappings from logical to physical layer were saved in", fname_layer_map) if layers_merged is not None: # Save all layers corresponding to a certain mask # as one merged layout file # TODO Solve without unnecessary copy/paste for lm in layers_merged: layerObjName = lm[0] fname_layer_merged = fname_path + fname_title + \ "_layer_" + layerObjName + "." + fname_ending fnames_layer.append(fname_layer_merged) # Get LayerInfo object for current layer with physical layer save_opt = pya.SaveLayoutOptions() save_opt.deselect_all_layers() for i in lm[1]: properties = layout.get_info(i) save_opt.add_layer(layer_indices[i], properties) layout.write(fname_layer_merged, save_opt) # Load the saved layout files from disk and save as PNG: fname_layer_merged_png = fname_path + fname_title + \ "_layer_" + layerObjName + ".png" save_as_png(fname_layer_merged, fname_layer_merged_png, box_size_pixel) return fnames_layer # String[]
main_window = current_application.main_window() main_window.close_current_view() #print(help(main_window.create_layout)) cell_view = main_window.create_layout("StarkIndustry", 1) #tech name, mode current_view_index = main_window.current_view_index() print("current view index: " + str(current_view_index)) global_grid = main_window.grid_micron() print("global grid in micron : " + str(global_grid)) #help(main_window.load_layout) cell_view1 = main_window.load_layout(r"C:\Localdata\temp\temp.oas", 1) load_layout_options = pya.LoadLayoutOptions() load_layout_options.cif_dbu = 0.003 #help(pya.LoadLayoutOptions) cell_view2 = main_window.load_layout(r"C:\Localdata\temp\temp.oas", 1) main_window.close_all() main_window.create_view() layout_view = main_window.current_view() image = pya.Image(r"C:\Users\wzhao\Desktop\IronMan.png") layout_view.insert_image(image) marker = pya.Marker.new(layout_view) marker.set(pya.DBox(-200, -300, -100, -200))