def Start(mod="guiopen"): if mod == "gds": IO.layout = pya.Layout() elif mod == "guinew": IO.main_window = pya.Application.instance().main_window() IO.layout = IO.main_window.create_layout(1).layout() IO.layout_view = IO.main_window.current_view() IO.layout_view.rename_cellview("pythonout", 0) elif mod == "guiopen": IO.main_window = pya.Application.instance().main_window() IO.layout_view = IO.main_window.current_view() try: IO.layout = IO.layout_view.cellview( IO.layout_view.active_cellview_index()).layout() except AttributeError as _: return IO.Start("guinew") if len(IO.layout.top_cells()) > 0: IO.top = IO.layout.top_cells()[0] else: IO.top = IO.layout.create_cell("TOP") # IO.auxiliary = IO.layout.create_cell("auxiliary") IO.top.insert(pya.CellInstArray(IO.auxiliary.cell_index(), pya.Trans())) # IO.link = IO.layout.create_cell("link") IO.auxiliary.insert( pya.CellInstArray(IO.link.cell_index(), pya.Trans())) # IO.layer = IO.layout.layer(0, 0) for li1, li2 in [(0, 1), (0, 2)]: IO.layout.layer(li1, li2) return IO.layout, IO.top
def setup_top(): top_name = 'top' print('INFO: Creating new top cell: ' + top_name) design_top = main_layout.top_cell() top = main_layout.create_cell('top') fill_top_cell = main_layout.create_cell('fill') top.insert(pya.CellInstArray(design_top.cell_index(), pya.Trans())) top.insert(pya.CellInstArray(fill_top_cell.cell_index(), pya.Trans())) return fill_top_cell, design_top
def setup_top(): top_name = 'top' print('INFO: Creating new top cell: ' + top_name) design_top = main_layout.top_cell() top = main_layout.create_cell('top') fill_top_cell = main_layout.create_cell('fill') top.insert(pya.CellInstArray(design_top.cell_index(), pya.Trans())) top.insert(pya.CellInstArray(fill_top_cell.cell_index(), pya.Trans())) print('INFO: Flattening top cell') top.move_tree(fill_top_cell) fill_top_cell.copy_tree(design_top) fill_top_cell.flatten(True) return fill_top_cell
def test_13(self): n = 100 w = 10000 ly = pya.Layout() l1 = ly.layer(1, 0) top = ly.create_cell("TOP") ix = 0 while ix < n: sys.stdout.write(str(ix) + "/" + str(n) + "\n") sys.stdout.flush() iy = 0 while iy < n: x = ix * w y = iy * w cell = ly.create_cell("X" + str(ix) + "Y" + str(iy)) cell.shapes(l1).insert(pya.Box(0, 0, w, w)) top.insert( pya.CellInstArray(cell.cell_index(), pya.Trans(pya.Point(ix * w, iy * w)))) iy += 1 ix += 1 ly._destroy()
def place_cell(parent_cell, cell, placement_origin, params=None, relative_to=None): """ Places a cell and return ports Args: parent_cell: cell to place into cell: cell to be placed placement_origin: pya.Point object to be used as origin relative_to: port name Returns: ports(dict): key:port.name, value: geometry.Port with positions relative to parent_cell's origin """ layout = parent_cell.layout() pcell, ports = cell.pcell(layout, params=params) if relative_to is not None: offset = next((port.position for port in ports if port.name == relative_to), None) placement_origin = placement_origin - offset parent_cell.insert( pya.CellInstArray( pcell.cell_index(), pya.Trans(pya.Trans.R0, placement_origin.to_itype(layout.dbu)))) for port in ports: port.position += placement_origin return {port.name: port for port in ports}
def add_pcells(self, instance_list: list): """Creates list of instances of PCells. These are the effective Klayout cell instances. :param instance_list: list of :class:`kppc.photonics.InstanceHolder` :return: list of instantiated pya.CellInstArray """ id = 0 insts = [] for inst_port in instance_list: if type(inst_port) is InstanceHolder: inst_port.id = id id += 1 insts.append(inst_port) elif type(inst_port) is list: for iinst_port in inst_port: if type(iinst_port) is InstanceHolder: iinst_port.id = id id += 1 insts.append(iinst_port) else: raise ValueError( "Expected type instances (InstanceHolder), ports (PortCreation) or a list of instances,ports. Instead got {}" .format(str(type(inst_port)))) trans = self.get_transformations() instances = [] for i, inst in enumerate(insts): pcell_var = self.layout.add_pcell_variant(inst.pcell_decl.id(), inst.params_mod) instances.append( self.cell.insert(pya.CellInstArray(pcell_var, trans[i]))) return instances
def DrawAirbridge(self, cell, centerlinelist, newcellname="Airbige"): IO.layout.read(self.filename) for icell in IO.layout.top_cells(): if (icell.name == self.insertcellname): icell.name = newcellname for cpts in centerlinelist: distance = 0 if not hasattr(self.airbridgedistance, '__call__'): distance = self.airbridgedistance * 0.25 dt_int = 0 for i, pt in enumerate(cpts[1:-1], 1): distance = distance + pt.distance(cpts[i - 1]) if hasattr(self.airbridgedistance, '__call__'): calt_int = self.airbridgedistance(distance) else: calt_int = distance // self.airbridgedistance if calt_int != dt_int: dx = cpts[i + 1].x - cpts[i - 1].x dy = cpts[i + 1].y - cpts[i - 1].y tr = pya.CplxTrans(1, atan2(dy, dx) / pi * 180, False, pt.x, pt.y) new_instance = pya.CellInstArray( icell.cell_index(), tr) cell.insert(new_instance) dt_int = dt_int + 1 for icell in IO.layout.top_cells(): if (icell.name == self.insertcellname): icell.flatten(True) icell.delete()
def layout_pgtext(cell, layer, x, y, text, mag, inv=False): pcell = cell.layout().create_cell("TEXT", "Basic", {"text": text, "layer": layer, "mag": mag, "inverse": inv}) dbu = cell.layout().dbu cell.insert(pya.CellInstArray(pcell.cell_index(), pya.Trans(pya.Trans.R0, x / dbu, y / dbu)))
def test_2(self): # instantiate and register the library tl = PCellTestLib() ly = pya.Layout(True) ly.dbu = 0.01 ci1 = ly.add_cell("c1") c1 = ly.cell(ci1) lib = pya.Library.library_by_name("PCellTestLib") pcell_decl_id = lib.layout().pcell_id("Box") param = [ pya.LayerInfo(1, 0), 10.0, 2.0 ] pcell_var_id = ly.add_pcell_variant(lib, pcell_decl_id, param) pcell_var = ly.cell(pcell_var_id) pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans())) li1 = find_layer(ly, "1/0") self.assertEqual(li1 != None, True) self.assertEqual(ly.is_valid_layer(li1), True) self.assertEqual(str(ly.get_info(li1)), "1/0") self.assertEqual(pcell_inst.is_pcell(), True) self.assertEqual(ly.begin_shapes(pcell_inst.cell_index, li1).shape().__str__(), "box (-500,-100;500,100)") pcell_inst.convert_to_static() self.assertEqual(pcell_inst.is_pcell(), False) self.assertEqual(ly.begin_shapes(pcell_inst.cell_index, li1).shape().__str__(), "box (-500,-100;500,100)") pcell_inst.convert_to_static() self.assertEqual(pcell_inst.is_pcell(), False) self.assertEqual(ly.begin_shapes(pcell_inst.cell_index, li1).shape().__str__(), "box (-500,-100;500,100)")
def next_level(self): self.level += 1 print("Drawing Hilbert Level %g" % self.level) newcell = self.layout.create_cell(self.cell_prefix + "level_" + str(self.level)) transll = pya.Trans(0, 0) translr = pya.Trans(self.box_size + self.length, 0) transul = pya.Trans(1, False, self.box_size + self.cd, self.box_size + self.length) transur = pya.Trans(3, False, self.box_size + self.length, self.box_size * 2 + self.length + self.cd) print(" Placing Cells...") ll_inst = pya.CellInstArray(self.cell.cell_index(), transll) lr_inst = pya.CellInstArray(self.cell.cell_index(), translr) ul_inst = pya.CellInstArray(self.cell.cell_index(), transul) ur_inst = pya.CellInstArray(self.cell.cell_index(), transur) newcell.insert(ll_inst) newcell.insert(lr_inst) newcell.insert(ur_inst) newcell.insert(ul_inst) print(" Connecting Quadrants...") p11 = pya.Point(self.box_size + self.cd / 2, self.box_size + self.cd / 2) p12 = pya.Point(self.box_size + self.cd / 2 + self.length, self.box_size + self.cd / 2) p21 = pya.Point(self.cd / 2, self.cd / 2 + self.box_size) p22 = pya.Point(self.cd / 2, self.cd / 2 + self.box_size + self.length) p31 = pya.Point(self.box_size * 2 + self.length + self.cd / 2, self.cd / 2 + self.box_size) p32 = pya.Point(self.box_size * 2 + self.length + self.cd / 2, self.cd / 2 + self.box_size + self.length) path1 = pya.Path([p11, p12], self.cd, self.cd / 2, self.cd / 2).polygon() path2 = pya.Path([p21, p22], self.cd, self.cd / 2, self.cd / 2).polygon() path3 = pya.Path([p31, p32], self.cd, self.cd / 2, self.cd / 2).polygon() newcell.shapes(self.layer).insert(path1) newcell.shapes(self.layer).insert(path2) newcell.shapes(self.layer).insert(path3) print(" Updating Box Size...") self.box_size = self.box_size * 2 + self.length self.cell = newcell print("Done!")
def DrawMark(self, cell, pts, newcellname="Mark"): IO.layout.read(self.filename) for i in IO.layout.top_cells(): if (i.name == self.insertcellname): i.name = newcellname for pt in pts: tr = pya.Trans(pt.x, pt.y) new_instance = pya.CellInstArray(i.cell_index(), tr) cell.insert(new_instance)
def test_1a(self): # instantiate and register the library tl = PCellTestLib2() ly = pya.Layout(True) ly.dbu = 0.01 li1 = find_layer(ly, "1/0") self.assertEqual(li1 == None, True) ci1 = ly.add_cell("c1") c1 = ly.cell(ci1) lib = pya.Library.library_by_name("PCellTestLib2") self.assertEqual(lib != None, True) pcell_decl = lib.layout().pcell_declaration("Box2") param = [ pya.LayerInfo(1, 0) ] # rest is filled with defaults pcell_var_id = ly.add_pcell_variant(lib, pcell_decl.id(), param) pcell_var = ly.cell(pcell_var_id) pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans())) self.assertEqual(pcell_var.basic_name(), "Box2") self.assertEqual(pcell_var.pcell_parameters().__repr__(), "[<1/0>, 1.0, 1.0]") self.assertEqual(pcell_var.display_title(), "PCellTestLib2.Box2(L=1/0,W=1.000,H=1.000)") self.assertEqual(nh(pcell_var.pcell_parameters_by_name()), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") self.assertEqual(pcell_var.pcell_parameter("height").__repr__(), "1.0") self.assertEqual(c1.pcell_parameters(pcell_inst).__repr__(), "[<1/0>, 1.0, 1.0]") self.assertEqual(nh(c1.pcell_parameters_by_name(pcell_inst)), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") self.assertEqual(c1.pcell_parameter(pcell_inst, "height").__repr__(), "1.0") self.assertEqual(nh(pcell_inst.pcell_parameters_by_name()), "{'height': 1.0, 'layer': <1/0>, 'width': 1.0}") self.assertEqual(pcell_inst["height"].__repr__(), "1.0") self.assertEqual(pcell_inst.pcell_parameter("height").__repr__(), "1.0") self.assertEqual(pcell_var.pcell_declaration().__repr__(), pcell_decl.__repr__()) self.assertEqual(c1.pcell_declaration(pcell_inst).__repr__(), pcell_decl.__repr__()) self.assertEqual(pcell_inst.pcell_declaration().__repr__(), pcell_decl.__repr__()) li1 = find_layer(ly, "1/0") self.assertEqual(li1 == None, False) pcell_inst.change_pcell_parameter("height", 2.0) self.assertEqual(nh(pcell_inst.pcell_parameters_by_name()), "{'height': 2.0, 'layer': <1/0>, 'width': 1.0}") self.assertEqual(ly.begin_shapes(c1.cell_index(), li1).shape().__str__(), "box (-50,-100;50,100)") param = { "layer": pya.LayerInfo(2, 0), "width": 2, "height": 1 } li2 = ly.layer(2, 0) c1.change_pcell_parameters(pcell_inst, param) self.assertEqual(ly.begin_shapes(c1.cell_index(), li2).shape().__str__(), "box (-100,-50;100,50)") l10 = ly.layer(10, 0) c1.shapes(l10).insert(pya.Box(0, 10, 100, 210)) l11 = ly.layer(11, 0) c1.shapes(l11).insert(pya.Text("hello", pya.Trans())) self.assertEqual(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l11).shape(), l10), False) self.assertEqual(pcell_decl.can_create_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10), True) self.assertEqual(repr(pcell_decl.parameters_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10)), "[<10/0>, 1.0, 2.0]") self.assertEqual(str(pcell_decl.transformation_from_shape(ly, ly.begin_shapes(c1.cell_index(), l10).shape(), l10)), "r0 50,110")
def main(): # Loop each cut map, & export each GDS as unique name for key in cut_d: filename = "2_" + key # Add prefix to the filename print("\nfilename : ", filename) # Get 1_UNIT (no cuts as a reference) & create SINGLE instance for i in gdsFiles: layout.read(i) for cell in layout.top_cells(): # we don't want to insert the topcell itself if (cell.name != "1_UNIT_CUTS"): print("Adding : " + cell.name) cell_index = cell.cell_index() new_instance = pya.CellInstArray( cell_index, pya.Trans(pya.Point(0, 0))) UNIT.insert(new_instance) # Define imported metal as a region (for boolean) region_metal = pya.Region(layout.top_cell().begin_shapes_rec(l_metal)) # Define cut area & make as region for ind, each_cut in enumerate(cut_d[key]): cut_box_coord = get_cut_coord(each_cut, d) UNIT.shapes(l_cut_box).insert(cut_box_coord) region_cut_box = pya.Region(cut_box_coord) # Do boolean (XOR) # For more than 1 cuts, need to loop and take XOR of previous XOR results if ind == 0: region_xor = region_metal ^ region_cut_box else: region_xor = region_xor ^ region_cut_box # Remove existings metal layer + cut boxes # (!!! SKIP THIS TO CHECK CUT BOXES IN GDS !!!) layout.clear_layer(l_metal) layout.clear_layer(l_cut_box) # INSERT BOOLEAN RESULT AS ORIGINAL METAL LAYER UNIT.shapes(l_metal).insert(region_xor) # Check if filename gds exists -> If so skip "write" if os.path.isfile(root + "/" + filename + ".gds"): print("**** GDS name by : " + filename + ".gds already exists!") print("**** SKIPPING GDS WRITE!!!") else: # Export GDS layout.write(filename + ".gds") # Check if this cell can be used as another at different coordinate dup_l = get_dup_names(filename + ".gds") if dup_l[0] != '': for each in dup_l: print("Create copy as : ", each, " <-----------------------------------------") layout.write(each)
def DrawGds(self, cell, newcellname, DCplxTrans1): #tr=pya.DCplxTrans(1,0,False,0,0) #倍数,逆时针度数,是否绕x翻转,平移x,平移y tr = pya.CplxTrans.from_dtrans(DCplxTrans1) IO.layout.read(self.filename) for i in IO.layout.top_cells(): if (i.name == self.insertcellname): i.name = newcellname new_instance = pya.CellInstArray(i.cell_index(), tr) cell.insert(new_instance)
def trans_cell(in_cell, angle=0, mirror=0, x=0, y=0, scale=1): bbx = in_cell.bbox() x_0 = bbx.left y_0 = bbx.bottom # print x_0,y_0 #x= x-x_0 #y= y-y_0 # print scale, angle, mirror, x, y trans = pya.CplxTrans(scale, angle, mirror, x, y) tmp_inst = pya.CellInstArray(in_cell.cell_index(), trans) return tmp_inst
def main(): # Loop each cut locations, & assign GDS name from key for key in cut_loc: filename = key print("\nfilename : ", filename) # Read 1_UNIT (no cuts as a reference) & create SINGLE instance for each_gds in gds_files: KLAYOUT.read(each_gds) # Read Top Cell for each GDS file for top_cell_read in KLAYOUT.top_cells(): if (top_cell_read.name != "1_UNIT_CUTS" ): # Don't insert TOP_CELL("1_UNIT_CUTS") on itself # print ( "Adding " + top_cell_read.name ) cell_index = top_cell_read.cell_index() new_instance = pya.CellInstArray( cell_index, pya.Trans(pya.Point(0, 0))) # pya.Trans(pya.Point(0,0)) --> defines the LOCATION at which instance should be placed TOP_CELL.insert(new_instance) # Define imported metal as a region (for boolean) region_metal = pya.Region(KLAYOUT.top_cell().begin_shapes_rec(l_metal)) # Define cut area & make as region for ind, each_cut in enumerate(cut_loc[key]): cut_box_coord = get_cut_coord(each_cut, dim) TOP_CELL.shapes(l_cut_box).insert(cut_box_coord) region_cut_box = pya.Region(cut_box_coord) # Do boolean (XOR) # For more than 1 cuts, need to loop and take XOR of previous XOR results if ind == 0: region_xor = region_metal ^ region_cut_box else: region_xor = region_xor ^ region_cut_box # Remove existings metal layer + cut boxes # (!!! SKIP THIS TO CHECK CUT BOXES IN GDS !!!) KLAYOUT.clear_layer(l_metal) KLAYOUT.clear_layer(l_cut_box) # INSERT BOOLEAN RESULT AS ORIGINAL METAL LAYER TOP_CELL.shapes(l_metal).insert(region_xor) # Check if filename gds exists -> If so skip "write" if os.path.isfile(root + "/" + filename + ".gds"): print("**** GDS name by : " + filename + ".gds already exists!") print("**** SKIPPING GDS WRITE!!!") else: # Export GDS KLAYOUT.write(filename + ".gds")
def test_6_Layout_props2(self): ly = pya.Layout(True) pv = [[17, "a"], ["b", [1, 5, 7]]] pid = ly.properties_id(pv) # does not work? @@@ # pv = { 17: "a", "b": [ 1, 5, 7 ] } # pid2 = ly.properties_id( pv ) # self.assertEqual( pid, pid2 ) ci1 = ly.add_cell("c1") ci2 = ly.add_cell("c2") linfo = pya.LayerInfo() linfo.layer = 16 linfo.datatype = 1 lindex = ly.insert_layer(linfo) c1 = ly.cell(ci1) c2 = ly.cell(ci2) tr = pya.Trans() inst = c2.insert(pya.CellInstArray(c1.cell_index(), tr)) self.assertEqual(inst.parent_cell.name, c2.name) self.assertEqual(inst.cell.name, c1.name) self.assertEqual(repr(inst.layout()), repr(ly)) s1 = c1.shapes(lindex).insert(pya.Box(10, -10, 50, 40), pid) s2 = c1.shapes(lindex).insert(pya.Box(10, -10, 50, 40)) self.assertEqual(repr(s1.property(17)), "\'a\'") s1.set_property(5, 23) s1.delete_property(17) self.assertEqual(repr(s1.property(17)), "None") self.assertEqual(str(s1.property(5)), "23") self.assertEqual(repr(s2.property(17)), "None") self.assertEqual(repr(inst.property("a")), "None") inst.set_property("a", 33) self.assertEqual(str(inst.property("a")), "33") inst.delete_property("a") self.assertEqual(repr(inst.property("a")), "None") # cell properties self.assertEqual(repr(c1.property(17)), "None") c1.prop_id = pid self.assertEqual(c1.prop_id, pid) self.assertEqual(repr(c1.property(17)), "\'a\'") c1.set_property(5, 23) c1.delete_property(17) self.assertEqual(repr(c1.property(17)), "None") self.assertEqual(str(c1.property(5)), "23")
def DrawMark(self, cell, pts, newcellname="Mark"): IO.layout.read(self.filename) for icell in IO.layout.top_cells(): if (icell.name == self.insertcellname): icell.name = newcellname break for pt in pts: tr = pya.Trans(int(pt.x), int(pt.y)) new_instance = pya.CellInstArray(icell.cell_index(), tr) cell.insert(new_instance) for icell in IO.layout.top_cells(): if (icell.name == self.insertcellname): icell.flatten(True) icell.delete()
def scanBoxes(cellList=None, layerList=None, layermod='in', position='leftdown'): if cellList == None: cellList = [IO.top] if layerList == None: layerList = [(0, 1)] _layerlist = [] for ii in layerList: if type(ii) == str: if IO.layout.find_layer(ii) != None: _layerlist.append(IO.layout.find_layer(ii)) else: if IO.layout.find_layer(ii[0], ii[1]) != None: _layerlist.append(IO.layout.find_layer(ii[0], ii[1])) layers = [ index for index in IO.layout.layer_indices() if index in _layerlist ] if layermod == 'in' else [ index for index in IO.layout.layer_indices() if index not in _layerlist ] region = pya.Region() for cell in cellList: for layer in layers: s = cell.begin_shapes_rec(layer) region.insert(s) region.merge() pts = [] for polygon in region.each(): print(polygon) try: polygon = polygon.bbox() finally: pass print(polygon) pt = polygon.p1 if position == 'leftdown' else polygon.center() pts.append(pt) output = [] layer = IO.layout.layer(0, 2) cell = IO.layout.create_cell("boxMarks") IO.auxiliary.insert(pya.CellInstArray(cell.cell_index(), pya.Trans())) painter = PcellPainter() for index, pt in enumerate(pts, 1): name = "M" + str(index) painter.DrawText(cell, layer, name, pya.DCplxTrans(100, 0, False, pt.x, pt.y)) output.append([name, {"x": pt.x, "y": pt.y}]) return output
def create(ly, li, text, mag, bias=0, flatten=False): """Add text. ly: Layout object li: layer index text: text content mag: magnification flatten: False: return CellInstArray object (default) True: return Region object """ # finding the PCell declaration object ... lib = pya.Library.library_by_name("Basic") if lib == None: raise Exception("Unknown lib 'Basic'") pcell_decl = lib.layout().pcell_declaration("TEXT") if pcell_decl == None: raise Exception("Unknown PCell 'TEXT'") # translating named parameters into an ordered sequence ... # named parameters param = { "text": text, "layer": ly.get_info(li), # target layer of the text "mag": mag, "bias": bias } # translate to array (to pv) pv = [] for p in pcell_decl.get_parameters(): if p.name in param: pv.append(param[p.name]) else: pv.append(p.default) # create the PCell variant cell pcell_var = ly.add_pcell_variant(lib, pcell_decl.id(), pv) if not flatten: # transformation t = pya.Trans() # insert into "top_cell" (must be provided by the caller) return pya.CellInstArray(pcell_var, t) else: # collect shapes reg = pya.Region(ly.cell(pcell_var).begin_shapes_rec(li)) return reg
def make_layer_cells(): #Load View app = pya.Application.instance() mw = app.main_window() lv = mw.current_view() ly = lv.active_cellview().layout() dbu = ly.dbu if lv == None: raise Exception("No view selected") cv = lv.cellview(lv.active_cellview_index()) #Loop through layers for layer in [1, 2, 3]: new_cell = ly.create_cell(cv.cell.display_title() + "L" + str(layer)) # Loop through instances for inst in cv.cell.each_inst(): #Calculate location of instances itrans = pya.ICplxTrans.from_trans(pya.CplxTrans()) box = inst.bbox().transformed(itrans) x = box.center().x y = box.center().y #Create new cell to represent given layer new_subcell = ly.create_cell(inst.cell.display_title() + "L" + str(layer)) #Map Bounding box and shape layers to new layer lm = pya.LayerMapping() lm.map(ly.layer(1, 3), ly.layer(1, 3)) lm.map(ly.layer(layer, 0), ly.layer(layer, 0)) lm.map(ly.layer(layer, 1), ly.layer(layer, 0)) #Create Instance Array to place into cell array = pya.CellInstArray() #Copy shapes, place, and insert array.cell_index = new_subcell.cell_index() new_subcell.copy_shapes(inst.cell, lm) array.trans = pya.Trans(pya.Point(x, y)) new_cell.insert(array)
def DrawGds(self,cell,newcellname,DCplxTrans1): #tr=pya.DCplxTrans(1,0,False,0,0) #倍数,逆时针度数,是否绕x翻转,平移x,平移y tr=pya.CplxTrans.from_dtrans(DCplxTrans1) resultcell=None IO.layout.read(self.filename) for i in IO.layout.top_cells(): if (i.name == self.insertcellname): i.name=newcellname resultcell=i new_instance=pya.CellInstArray(i.cell_index(),tr) cell.insert(new_instance) for i in IO.layout.top_cells(): if (i.name == self.insertcellname): i.flatten(True) i.delete() return resultcell
def test_3(self): # instantiate and register the library tl = PCellTestLib() ly = pya.Layout(True) ly.dbu = 0.01 c1 = ly.create_cell("c1") lib = pya.Library.library_by_name("PCellTestLib") pcell_decl_id = lib.layout().pcell_id("Box") param = { "w": 4.0, "h": 8.0, "l": pya.LayerInfo(1, 0) } pcell_var_id = ly.add_pcell_variant(lib, pcell_decl_id, param) pcell_var = ly.cell(pcell_var_id) pcell_inst = c1.insert(pya.CellInstArray(pcell_var_id, pya.Trans())) self.assertEqual(ly.begin_shapes(c1.cell_index(), ly.layer(1, 0)).shape().__str__(), "box (-200,-400;200,400)")
def _merge_and_draw(outregion, inregion, tr_to=None, cutbool=True): #region=outregion-inregion if cutbool: region = outregion - inregion else: region = outregion - ( outregion - inregion ) #outregion-inregion#outregion-(outregion-inregion)# if type(tr_to) == type(None): center = outregion.bbox().center() region.transform(pya.Trans(-center.x, -center.y)) tr = pya.Trans(center.x, center.y) else: tr = tr_to cut = IO.layout.create_cell("cut") IO.auxiliary.insert(pya.CellInstArray(cut.cell_index(), tr)) BasicPainter.Draw(cut, IO.layer, region) return region, cut
def DrawText(self, cell, layer1, textstr, DCplxTrans1): #左下角坐标,每个字宽0.6*倍数高0.7*倍数线宽0.1*倍数 #tr=pya.DCplxTrans(10,0,False,0,0) #倍数,逆时针度数,是否绕x翻转,平移x,平移y tr = pya.CplxTrans.from_dtrans(DCplxTrans1) textstr = "%s" % (textstr) param = {"text": textstr, "layer": layer1, "mag": 1} pv = [] for p in self.TEXT_decl.get_parameters(): if p.name in param: pv.append(param[p.name]) else: pv.append(p.default) text_cell = IO.layout.create_cell("TEXT(\"%s\")" % (textstr)) self.TEXT_decl.produce(IO.layout, [layer1], pv, text_cell) cell.insert(pya.CellInstArray(text_cell.cell_index(), tr)) edge1 = pya.DEdge(len(textstr) * 0.6, 0, len(textstr) * 0.6, 0.7).transformed(DCplxTrans1) return [edge1.p1, edge1.p2]
def layout_waveguide_rel(cell, layer, start_point, points, w, radius): # create a path, then convert to a polygon waveguide with bends # cell: cell into which to place the waveguide # layer: layer to draw on # start_point: starting vertex for the waveguide # points: array of vertices, relative to start_point # w: waveguide width # example usage: # cell = pya.Application.instance().main_window().current_view().active_cellview().cell # LayerSi = LayerInfo(1, 0) # points = [ [15, 2.75], [30, 2.75] ] # units of microns. # layout_waveguide_rel(cell, LayerSi, [0,0], points, 0.5, 10) #print("* layout_waveguide_rel(%s, %s, %s, %s)" % (cell.name, layer, w, radius) ) ly = cell.layout() dbu = cell.layout().dbu start_point = [start_point[0] / dbu, start_point[1] / dbu] a1 = [] for p in points: a1.append(pya.DPoint(float(p[0]), float(p[1]))) wg_path = pya.DPath(a1, w) npoints = points_per_circle(radius / dbu) param = { "npoints": npoints, "radius": float(radius), "path": wg_path, "layer": layer } pcell = ly.create_cell("ROUND_PATH", "Basic", param) # Configure the cell location trans = Trans(Point(start_point[0], start_point[1])) # Place the PCell cell.insert(pya.CellInstArray(pcell.cell_index(), trans))
def DrawAirbridge(self, cell, centerlinelist, newcellname="Airbige"): #CavityPainter生成的centerline未测试 for cpts in centerlinelist: IO.layout.read(self.filename) #每个腔用一个不同的cell装airbridge原型 for icell in IO.layout.top_cells(): if (icell.name == self.insertcellname): icell.name = newcellname distance = self.airbridgedistance // 2 dt_int = 0 for i, pt in enumerate(cpts[1:-1], 1): distance = distance + pt.distance(cpts[i - 1]) if distance // self.airbridgedistance != dt_int: dx = cpts[i + 1].x - cpts[i - 1].x dy = cpts[i + 1].y - cpts[i - 1].y tr = pya.CplxTrans(1, atan2(dy, dx) / pi * 180, False, pt.x, pt.y) new_instance = pya.CellInstArray( icell.cell_index(), tr) cell.insert(new_instance) dt_int = dt_int + 1
def DrawText(self, textstr, DCplxTrans1, cell, layer1, layout): #左下角坐标,每个字宽0.6*倍数高0.7*倍数 #tr=pya.DCplxTrans(1,0,False,0,0) #倍数,逆时针度数,是否绕x翻转,平移x,平移y tr = pya.CplxTrans.from_dtrans(DCplxTrans1) param = {"text": textstr, "layer": layer1, "mag": 1} pv = [] for p in self.TEXT_decl.get_parameters(): if p.name in param: pv.append(param[p.name]) else: pv.append(p.default) text_cell = layout.create_cell(textstr) self.TEXT_decl.produce(layout, [layer1], pv, text_cell) cell.insert(pya.CellInstArray(text_cell.cell_index(), tr)) return list( pya.DPolygon([ pya.DPoint(0, 0), pya.DPoint(0, 0.7), pya.DPoint(len(textstr) * 0.6, 0.7), pya.DPoint(len(textstr) * 0.6, 0) ]).transformed(DCplxTrans1).each_point_hull())
def DrawBoxes(cell, layer, dlength, dgap, radius, number, layerlist=None, layermod='not in', box=None, cutbool=True, dx=0, dy=0, filterfunc=None): ''' filterfunc=lambda pp:pp.area()>=20000 则只保留面积大于20000的部分, filterfunc为None时不检查 ''' fillCell = IO.layout.create_cell("fill") IO.auxiliary.insert( pya.CellInstArray(fillCell.cell_index(), pya.Trans())) fillRegion = SpecialPainter.DrawFillRegion(cell=fillCell, layer=IO.layer, radius=radius, number=number, layerlist=layerlist, layermod=layermod, box=box, cutbool=cutbool) boxesRegion = SpecialPainter.DrawBoxesInRegion(cell=cell, layer=layer, region=fillRegion, dlength=dlength, dgap=dgap, dx=dx, dy=dy, filterfunc=filterfunc) return fillCell, fillRegion, boxesRegion
def main(): # [1] Create TOP layout (LAYOUT_TOP, where layouts A,B,... would be merged) import pya LAYOUT_TOP = pya.Layout() CELL_TOP = LAYOUT_TOP.create_cell("CELL_TOP") # Create layer #'s import layer_numbers as lm l_TP_outline = LAYOUT_TOP.layer(lm.layer_num_TP_outline, 0) # One touch pixel Outline # Insert box outline for unit touch pixel dimensions CELL_TOP.shapes(l_TP_outline).insert(pya.Box(0, 0, p * 14, p * 14)) for ind, (k, v) in enumerate(gds_files_d.items()): print("\nProcessing ... : ", ind, k, v) # 0 | 2_unit_1_7.gds | [1, 7] # [2] Loop over each GDS, create separate layouts (LAYOUT_A, LAYOUT_B, ...), and read each GDS files LAYOUT_A = pya.Layout() LAYOUT_A.read(k) # From GDS name, get # of repeats in x-y dir [nx, ny] = get_nx_ny(k) #[nx, ny] = [1, 1] # [3] In TOP layout, create (empty) target cells (ta, tb, ...) CELL_TA = LAYOUT_TOP.create_cell("CELL_" + str(v[0]) + "_" + str(v[1])) # CELL_2_7, CELL_14_5, ... CELL_TOP.insert( pya.CellInstArray( CELL_TA.cell_index(), pya.Trans(pya.Point(p * (v[1] - 1), p * (v[0] - 1))), pya.Vector(p, 0), pya.Vector(0, p), nx, ny)) # v : value (e.g. [1, 7]) --> x = v[1], y = v[0] # [4] From [3], copy over the layouts from A to TA, using ta.move_tree(layout_A.top_cell() ) CELL_TA.move_tree(LAYOUT_A.top_cell()) # Export GDS LAYOUT_TOP.write("3_PANEL_wip.gds")