def test_5_Layout(self): ly = pya.Layout() ci1 = ly.add_cell( "c1" ) ci2 = ly.add_cell( "c2" ) linfo = pya.LayerInfo() linfo.layer = 16 linfo.datatype = 1 lindex = ly.insert_layer( linfo ) linfo = pya.LayerInfo() linfo.layer = 16 linfo.datatype = 2 ldummy = ly.insert_layer( linfo ) c1 = ly.cell( ci1 ) c2 = ly.cell( ci2 ) c1.shapes( lindex ).insert( pya.Box( 10, -10, 50, 40 ) ) self.assertEqual( c1.bbox().to_s(), "(10,-10;50,40)" ) self.assertEqual( c1.bbox_per_layer( lindex ).to_s(), "(10,-10;50,40)" ) self.assertEqual( c1.bbox_per_layer( ldummy ).to_s(), "()" ) c1.swap( lindex, ldummy ) self.assertEqual( c1.bbox_per_layer( lindex ).to_s(), "()" ) self.assertEqual( c1.bbox_per_layer( ldummy ).to_s(), "(10,-10;50,40)" ) c1.clear( lindex ) c1.clear( ldummy ) self.assertEqual( c1.bbox_per_layer( lindex ).to_s(), "()" ) self.assertEqual( c1.bbox_per_layer( ldummy ).to_s(), "()" ) c1.shapes( lindex ).insert( pya.Box( 10, -10, 50, 40 ) ) self.assertEqual( c1.bbox_per_layer( lindex ).to_s(), "(10,-10;50,40)" ) self.assertEqual( c1.bbox_per_layer( ldummy ).to_s(), "()" ) c1.clear_shapes() self.assertEqual( c1.bbox_per_layer( lindex ).to_s(), "()" ) self.assertEqual( c1.bbox_per_layer( ldummy ).to_s(), "()" )
def init_regions(self): self.connections = [DPoint(0, 0), self.dr] self.start = DPoint(0, 0) self.end = self.start + self.dr alpha = atan2(self.dr.y, self.dr.x) self.angle_connections = [alpha, alpha] alpha_trans = ICplxTrans().from_dtrans( DCplxTrans(1, alpha * 180 / pi, False, self.start)) self.metal_region.insert( pya.Box(Point().from_dpoint(DPoint(0, -self.width / 2)), Point().from_dpoint(DPoint(self.dr.abs(), self.width / 2)))) self.empty_region.insert( pya.Box( Point().from_dpoint(DPoint(0, self.width / 2)), Point().from_dpoint( DPoint(self.dr.abs(), self.width / 2 + self.gap)))) self.empty_region.insert( pya.Box( Point().from_dpoint(DPoint(0, -self.width / 2 - self.gap)), Point().from_dpoint(DPoint(self.dr.abs(), -self.width / 2)))) self.metal_region.transform(alpha_trans) self.empty_region.transform(alpha_trans)
def get_cut_coord(each_cut_s, dim): # First, get COL number from name ("2_l") if "1" in each_cut_s or "4" in each_cut_s or "7" in each_cut_s: col = 0 elif "2" in each_cut_s or "5" in each_cut_s or "8" in each_cut_s: col = 1 elif "3" in each_cut_s or "6" in each_cut_s or "9" in each_cut_s: col = 2 # Next, get ROW number from name ("2_l") if "1" in each_cut_s or "2" in each_cut_s or "3" in each_cut_s: row = 0 elif "4" in each_cut_s or "5" in each_cut_s or "6" in each_cut_s: row = 1 elif "7" in each_cut_s or "8" in each_cut_s or "9" in each_cut_s: row = 2 # Get location info from name ("2_l") # (pre-define some of re-used coordinates here) l_x1 = dim["pitch"] * col l_x2 = dim["pitch"] * col + dim["cut_width"] l_y1 = dim["pitch"] * row + (dim["pitch"] / 2 - dim["cut_width"] / 2) l_y2 = dim["pitch"] * row + (dim["pitch"] / 2 + dim["cut_width"] / 2) t_x1 = dim["pitch"] * col + (dim["pitch"] / 2 - dim["cut_width"] / 2) t_x2 = dim["pitch"] * col + (dim["pitch"] / 2 + dim["cut_width"] / 2) t_y1 = dim["pitch"] * row + (dim["pitch"] - dim["cut_width"]) t_y2 = dim["pitch"] * row + dim["pitch"] if "l" in each_cut_s: cut_box = pya.Box(l_x1, l_y1, l_x2, l_y2) elif "t" in each_cut_s: cut_box = pya.Box(t_x1, t_y1, t_x2, t_y2) else: print("NO cut name such as : ", each_cut_s) return cut_box
def draw_wire_column(cell, layer, cd, min_length, max_length, min_t2t, max_t2t, t2t_grid, max_y, location=[0, 0]): offset_x = location[0] offset_y = location[1] total_x = 0 total_y = 0 while total_y < max_y: wire_left = total_x wire_lower = total_y # print min_length, max_length, max_y try: tmp = min(max_length, max_y - wire_lower) wire_length = rd.randint(min_length, tmp) # print "wire length", wire_length except: # print "escape wire" break wire_upper = wire_lower + wire_length wire_right = wire_left + cd # print(wire_left+offset_x,wire_lower+offset_y,wire_lower,wire_right) wire_ll = pya.Point(wire_left + offset_x, wire_lower + offset_y) wire_ur = pya.Point(wire_right + offset_x, wire_upper + offset_y) wire = pya.Box(wire_ll, wire_ur) cell.shapes(layer).insert(wire) # print wire_ll, wire_ur # quit() try: if max_t2t > min_t2t: tmp = min(max_t2t, max_y - wire_upper) # print min_t2t, tmp, t2t_grid t2t = rd.randrange(min_t2t, tmp, t2t_grid) # print "t2t", t2t else: t2t = max_t2t except: # print "escape t2t" break # print total_x, max_x, max_length, wire_left total_y = total_y + wire_length + t2t
def __init__(self): # set the description self.description = "PCell test lib" # create the PCell declarations self.layout().register_pcell("Box", BoxPCell()) sb_index = self.layout().add_cell("StaticBox") l10 = self.layout().insert_layer(pya.LayerInfo(10, 0)) sb_cell = self.layout().cell(sb_index) sb_cell.shapes(l10).insert(pya.Box(0, 0, 100, 200)) # register us with the name "MyLib" self.register("PCellTestLib")
def init_regions(self): self.metal_region.insert(pya.Box().from_dbox(self.B1)) self.metal_region.insert(pya.Box().from_dbox(self.B2)) self.metal_region.insert(pya.Box().from_dbox(self.B3)) self.metal_region.insert(pya.Box().from_dbox(self.B4)) self.metal_region.insert(pya.Box().from_dbox(self.B5)) self.metal_region.insert(pya.Box().from_dbox(self.B6)) self.metal_region.insert(pya.Box().from_dbox(self.B7)) self.metal_region.insert(SimplePolygon().from_dpoly(self.poly_1)) self.metal_region.insert(SimplePolygon().from_dpoly(self.poly_2)) self.metal_region.insert(SimplePolygon().from_dpoly(self.poly_3)) self.metal_region.insert(SimplePolygon().from_dpoly(self.poly_4)) self.metal_region.insert(SimplePolygon().from_dpoly(self.poly_5)) self.metal_region.insert(SimplePolygon().from_dpoly(self.poly_6))
def _Rasterized(size, box, region): ''' size double unit nm box pya.Box region pya.Region return area[x][y] :int[][] xyToAreaxy :lambda double,double:int,int ''' dx = 0 dy = 0 dx = dx % size dy = dy % size left = ceil((box.left-dx)/size) bottom = ceil((box.bottom-dy)/size) right = floor((box.right-dx)/size) top = floor((box.top-dy)/size) x0 = left*size+dx y0 = bottom*size+dy area = [] for ii in range(right-left): thisline = [] for jj in range(top-bottom): x1 = x0+ii*size y1 = y0+jj*size check_box = pya.Box(x1, y1, x1+size, y1+size) empty = (pya.Region(check_box) & region).is_empty() thisline.append(0 if empty else 1) thisline[0] = 1 thisline[-1] = 1 area.append(thisline) area[0] = [1 for ii in area[0]] area[-1] = [1 for ii in area[-1]] def xyToAreaxy(px, py): px -= x0 py -= y0 if px < 0 or py < 0 or px > size*(right-left) or py > size*(top-bottom): return -1, -1 return floor(px/size), floor(py/size) def areaxyToXy(x, y): return x0+(x+0.5)*size, y0+(y+0.5)*size return area, xyToAreaxy, areaxyToXy
def test_bug109(self): testtmp = os.getenv("TESTTMP_WITH_NAME", os.getenv("TESTTMP", ".")) file_gds = os.path.join(testtmp, "bug109.gds") file_oas = os.path.join(testtmp, "bug109.oas") ly = pya.Layout() top = ly.create_cell("TOP") l1 = ly.layer(1, 0) shape = top.shapes(l1).insert(pya.Box(0, 10, 20, 30)) shape.set_property(2, "hello, world") shape.set_property("42", "the answer") ly.write(file_gds) ly.write(file_oas) ly2 = pya.Layout() ly2.read(file_gds) l2 = ly2.layer(1, 0) shape = None for s in ly2.top_cell().shapes(l2).each(): shape = s self.assertEqual(shape.property(2), "hello, world") self.assertEqual(shape.property("2"), None) self.assertEqual(shape.property(2.0), "hello, world") self.assertEqual(shape.property(22), None) self.assertEqual(shape.property(42), "the answer") self.assertEqual(shape.property("42"), None) self.assertEqual(shape.property(42.0), "the answer") ly2 = pya.Layout() ly2.read(file_oas) l2 = ly2.layer(1, 0) shape = None for s in ly2.top_cell().shapes(l2).each(): shape = s self.assertEqual(shape.property(2), "hello, world") self.assertEqual(shape.property("2"), None) self.assertEqual(shape.property(2.0), "hello, world") self.assertEqual(shape.property(22), None) self.assertEqual(shape.property("42"), "the answer") self.assertEqual(shape.property(42), None) self.assertEqual(shape.property(42.0), None)
def create_fill_cell_large(metal): cell = main_layout.create_cell("metal" + str(metal + 1) + "_large") mw = metal_widths[metal] # Row 1 cell.shapes(metal_layers[i]).insert(pya.Box( 0, 0, 1.0*mw, 1.0*mw)) cell.shapes(metal_layers[i]).insert(pya.Box(2.0*mw, 0.5*mw, 3.0*mw, 1.5*mw)) cell.shapes(metal_layers[i]).insert(pya.Box(4.0*mw, 1.0*mw, 5.0*mw, 2.0*mw)) # Row 2 cell.shapes(metal_layers[i]).insert(pya.Box( 0, 2.0*mw, 1.0*mw, 3.0*mw)) cell.shapes(metal_layers[i]).insert(pya.Box(2.0*mw, 2.5*mw, 3.0*mw, 3.5*mw)) cell.shapes(metal_layers[i]).insert(pya.Box(4.0*mw, 3.0*mw, 5.0*mw, 4.0*mw)) return cell
def fill_holes( poly, dx=10e3, dy=8e3, width=5e3, height=5e3, d=0 ): bbox = poly.bbox() poly_reg = Region( poly ) t_reg = Region() y = bbox.p1.y + height while( y < bbox.p2.y - height ): x = bbox.p1.x + width while( x < bbox.p2.x - width ): box = pya.Box().from_dbox( pya.DBox(DPoint(x,y), DPoint(x + width,y + height)) ) x += dx t_reg.clear() t_reg.insert( box ) qwe = t_reg.select_inside( poly_reg ) if( qwe.is_empty() ): continue edge_pairs = qwe.inside_check( poly_reg, d ) if( edge_pairs.is_empty() ): poly.insert_hole( box ) y += dy return poly
def biggest_bounding_box(fname): """Finds the bounding box enclosing all cells in all layers of a layout. This dimension of the whole layout and its data base unit is returned. Args: fname: Layout file name (string) Returns: biggest_bounding_box: Box enclosing the whole layout (pya.Box()) dbu: Data base unit of the layout (double) """ layout = pya.Layout() layout.read(fname) biggest_bounding_box = pya.Box() for top_cell_index in layout.each_top_cell(): top_cell = layout.cell(top_cell_index) # Cell object from index bbox = top_cell.bbox() # Bounding box of pya.Cell object # + operator joins Boxes into Box enclosing both inputs. biggest_bounding_box = biggest_bounding_box + bbox dbu = layout.dbu # Data base unit return (biggest_bounding_box, dbu)
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")
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 init_regions( self ): # photolitography regions self.metal_regions["photo"] = Region() self.empty_regions["el"] = Region() # electron-beam litography regions self.metal_regions["el"] = Region() self.empty_regions["photo"] = Region() self.metal_regions["photo"].insert( pya.Box().from_dbox(self.SQ1) ) self.metal_regions["el"].insert( pya.Box().from_dbox(self.B1) ) self.metal_regions["el"].insert( pya.Box().from_dbox(self.B2) ) self.metal_regions["el"].insert( pya.Box().from_dbox(self.B3) ) self.metal_regions["el"].insert( pya.Box().from_dbox(self.B4) ) self.metal_regions["photo"].insert( pya.Box().from_dbox(self.SQ2) ) self.metal_regions["el"].insert( SimplePolygon(self.poly_1) ) self.metal_regions["el"].insert( SimplePolygon(self.poly_2) ) self.metal_regions["el"].insert( SimplePolygon(self.poly_3) ) self.metal_regions["el"].insert( SimplePolygon(self.poly_4) ) self.metal_regions["el"].insert( SimplePolygon(self.poly_5) ) self.metal_regions["el"].insert( SimplePolygon(self.poly_6) )
class CHIP: """ 10x10 mm chip PCB design located here: https://drive.google.com/drive/folders/1TGjD5wwC28ZiLln_W8M6gFJpl6MoqZWF?usp=sharing """ dx = 5e6 dy = 5e6 origin = DPoint(0, 0) box = pya.Box().from_dbox(pya.DBox(origin, origin + DPoint(dx, dy))) pcb_width = 260e3 # 0.26 mm pcb_gap = 190e3 # (0.64 - 0.26) / 2 = 0.19 mm pcb_feedline_d = 2500e3 # 2.5 mm pcb_Z = CPWParameters(pcb_width, pcb_gap) cpw_width = 24.1e3 cpw_gap = 12.95e3 chip_Z = CPWParameters(cpw_width, cpw_gap) @staticmethod def get_contact_pads(): dx = CHIP.dx dy = CHIP.dy pcb_feedline_d = CHIP.pcb_feedline_d pcb_Z = CHIP.pcb_Z chip_Z = CHIP.chip_Z contact_pads_left = [ ContactPad(DPoint(0, dy - pcb_feedline_d * (i + 1)), pcb_Z, chip_Z, back_metal_width=50e3, back_metal_gap=100e3) for i in range(3) ] contact_pads_bottom = [ ContactPad(DPoint(pcb_feedline_d * (i + 1), 0), pcb_Z, chip_Z, back_metal_width=50e3, back_metal_gap=100e3, trans_in=Trans.R90) for i in range(3) ] contact_pads_right = [ ContactPad(DPoint(dx, pcb_feedline_d * (i + 1)), pcb_Z, chip_Z, back_metal_width=50e3, back_metal_gap=100e3, trans_in=Trans.R180) for i in range(3) ] contact_pads_top = [ ContactPad(DPoint(dx - pcb_feedline_d * (i + 1), dy), pcb_Z, chip_Z, back_metal_width=50e3, back_metal_gap=100e3, trans_in=Trans.R270) for i in range(3) ] # contact pads are ordered starting with top-left corner in counter-clockwise direction contact_pads = itertools.chain(contact_pads_left, contact_pads_bottom, contact_pads_right, contact_pads_top) return list(contact_pads) @staticmethod def get_geometry_params_dict(prefix="", postfix=""): from collections import OrderedDict geometry_params = OrderedDict([("dx, um", CHIP.dx / 1e3), ("dy, um", CHIP.dy / 1e3), ("nX", CHIP.nX), ("nY", CHIP.nY)]) modified_dict = OrderedDict() for key, val in geometry_params.items(): modified_dict[prefix + key + postfix] = val return modified_dict
def test_touches(self): p1 = pya.Polygon(pya.Box(10, 20, 30, 40)) self.assertEqual(p1.touches(pya.Polygon(pya.Box(30, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.Polygon(pya.Box(31, 20, 40, 50))), False) self.assertEqual(p1.touches(pya.Polygon(pya.Box(29, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(30, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(31, 20, 40, 50))), False) self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(29, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.Box(30, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.Box(31, 20, 40, 50)), False) self.assertEqual(p1.touches(pya.Box(29, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.Edge(30, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.Edge(31, 20, 40, 50)), False) self.assertEqual(p1.touches(pya.Edge(29, 20, 40, 50)), True) p1 = pya.SimplePolygon(pya.Box(10, 20, 30, 40)) self.assertEqual(p1.touches(pya.Polygon(pya.Box(30, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.Polygon(pya.Box(31, 20, 40, 50))), False) self.assertEqual(p1.touches(pya.Polygon(pya.Box(29, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(30, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(31, 20, 40, 50))), False) self.assertEqual(p1.touches(pya.SimplePolygon(pya.Box(29, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.Box(30, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.Box(31, 20, 40, 50)), False) self.assertEqual(p1.touches(pya.Box(29, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.Edge(30, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.Edge(31, 20, 40, 50)), False) self.assertEqual(p1.touches(pya.Edge(29, 20, 40, 50)), True) p1 = pya.DPolygon(pya.DBox(10, 20, 30, 40)) self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(30, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(31, 20, 40, 50))), False) self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(29, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(30, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(31, 20, 40, 50))), False) self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(29, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.DBox(30, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.DBox(31, 20, 40, 50)), False) self.assertEqual(p1.touches(pya.DBox(29, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.DEdge(30, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.DEdge(31, 20, 40, 50)), False) self.assertEqual(p1.touches(pya.DEdge(29, 20, 40, 50)), True) p1 = pya.DSimplePolygon(pya.DBox(10, 20, 30, 40)) self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(30, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(31, 20, 40, 50))), False) self.assertEqual(p1.touches(pya.DPolygon(pya.DBox(29, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(30, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(31, 20, 40, 50))), False) self.assertEqual(p1.touches(pya.DSimplePolygon(pya.DBox(29, 20, 40, 50))), True) self.assertEqual(p1.touches(pya.DBox(30, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.DBox(31, 20, 40, 50)), False) self.assertEqual(p1.touches(pya.DBox(29, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.DEdge(30, 20, 40, 50)), True) self.assertEqual(p1.touches(pya.DEdge(31, 20, 40, 50)), False) self.assertEqual(p1.touches(pya.DEdge(29, 20, 40, 50)), True)
def test_IsConvex(self): self.assertEqual(pya.Polygon(pya.Box(0, 0, 10, 10)).is_convex(), True) p = pya.Polygon.from_s("(0,0;0,40;40,40;40,0/10,10;30,10;30,30;10,30)") self.assertEqual(p.is_convex(), False)
def test_2_Polygon(self): pts = [ pya.Point(0, 0) ] p = pya.Polygon(pts, False) self.assertEqual(str(p), "()") pts = [ pya.Point(0, 0) ] p = pya.Polygon(pts) self.assertEqual(str(p), "()") pts = [ pya.Point(0, 0) ] p = pya.Polygon(pts, True) self.assertEqual(str(p), "(0,0)") arr = [] for e in p.each_edge(): arr.append(str(e)) self.assertEqual( arr, ["(0,0;0,0)"] ) p = pya.Polygon(pya.Box(0, 0, 100, 100)) self.assertEqual(str(p), "(0,0;0,100;100,100;100,0)") p.insert_hole( [ pya.Point(0, 0), pya.Point(10, 0) ] ) # TODO: this isn't nice (empty hole): self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/)") p = pya.Polygon(pya.Box(0, 0, 100, 100)) p.insert_hole( [ pya.Point(0, 0), pya.Point(10, 0) ], True ) self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)") p.assign_hole(0, [ pya.Point(0, 0), pya.Point(10, 0) ] ) self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/)") p.assign_hole(0, [ pya.Point(0, 0), pya.Point(10, 0) ], True ) self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)") pts = [ pya.Point(0, 0), pya.Point(10, 0) ] p = pya.Polygon(pts, True) self.assertEqual(str(p), "(0,0;10,0)") # conversion of degenerated polygon to simple polygon is not supported currently: self.assertEqual(str(p.to_simple_polygon()), "()") self.assertEqual(str(pya.DPolygon(p)), "(0,0;10,0)") p.hull = [] self.assertEqual(str(p), "()") p.hull = [ pya.Point(0, 0), pya.Point(10, 0) ] self.assertEqual(str(p), "(0,0;10,0)") p.assign_hull([ pya.Point(0, 0), pya.Point(10, 0) ], False) self.assertEqual(str(p), "()") p.assign_hull([ pya.Point(0, 0), pya.Point(10, 0) ], True) self.assertEqual(str(p), "(0,0;10,0)") arr = [] for e in p.each_edge(): arr.append(str(e)) self.assertEqual( arr, ["(0,0;10,0)", "(10,0;0,0)"] ) self.assertEqual(str(p.moved(1, 2)), "(1,2;11,2)") self.assertEqual(str(p.sized(2)), "(0,-2;0,2;10,2;10,-2)") self.assertEqual(str(p * 2), "(0,0;20,0)") self.assertEqual(str(p.transformed(pya.Trans(pya.Trans.R90))), "(0,0;0,10)") pp = p.dup() pp.transform(pya.Trans(pya.Trans.R90)) self.assertEqual(str(pp), "(0,0;0,10)") p = pya.Polygon([ pya.Point(0, 0), pya.Point(0, 10) ], True) q = pya.Polygon([ pya.Point(1, 1), pya.Point(-9, 1) ], True) self.assertEqual(str(p.minkowsky_sum(q, False)), "(-9,1;-9,11;1,11;1,1)")
def test_1_Polygon(self): a = pya.Polygon() self.assertEqual( str(a), "()" ) self.assertEqual( str(pya.Polygon.from_s(str(a))), str(a) ) self.assertEqual( a.is_box(), False ) b = a.dup() a = pya.Polygon( [ pya.Point( 0, 1 ), pya.Point( 1, 5 ), pya.Point( 5, 5 ) ] ) self.assertEqual( str(a), "(0,1;1,5;5,5)" ) self.assertEqual( str(a * 2), "(0,2;2,10;10,10)" ) self.assertEqual( str(pya.Polygon.from_s(str(a))), str(a) ) self.assertEqual( a.num_points_hull(), 3 ) c = a.dup() self.assertEqual( a == b, False ) self.assertEqual( a == c, True ) self.assertEqual( a != b, True ) self.assertEqual( a != c, False ) a = pya.Polygon( pya.Box( 5, -10, 20, 15 ) ) self.assertEqual( a.is_box(), True ) self.assertEqual( str(a), "(5,-10;5,15;20,15;20,-10)" ) self.assertEqual( str(pya.DPolygon(a)), "(5,-10;5,15;20,15;20,-10)" ) self.assertEqual( a.num_points_hull(), 4 ) self.assertEqual( a.area(), 15*25 ) self.assertEqual( a.perimeter(), 80 ) self.assertEqual( a.inside( pya.Point( 10, 0 ) ), True ) self.assertEqual( a.inside( pya.Point( 5, 0 ) ), True ) self.assertEqual( a.inside( pya.Point( 30, 0 ) ), False ) arr = [] for p in a.each_point_hull(): arr.append(str(p)) self.assertEqual( arr, ["5,-10", "5,15", "20,15", "20,-10"] ) b = a.dup() self.assertEqual( str(a.moved( pya.Point( 0, 1 ) )), "(5,-9;5,16;20,16;20,-9)" ) self.assertEqual( str(a.moved( 0, 1 )), "(5,-9;5,16;20,16;20,-9)" ) aa = a.dup() aa.move( 1, 0 ) self.assertEqual( str(aa), "(6,-10;6,15;21,15;21,-10)" ) a.move( pya.Point( 1, 0 ) ) self.assertEqual( str(a), "(6,-10;6,15;21,15;21,-10)" ) b = b.transformed( pya.Trans( pya.Trans.R0, pya.Point( 1, 0 )) ) self.assertEqual( str(b), "(6,-10;6,15;21,15;21,-10)" ) m = pya.CplxTrans( pya.Trans(), 1.5 ) self.assertEqual( str(a.transformed(m)), "(9,-15;9,22.5;31.5,22.5;31.5,-15)" ) self.assertEqual( str(a.transformed(pya.ICplxTrans(m))), "(9,-15;9,23;32,23;32,-15)" ) a.hull = [ pya.Point( 0, 1 ), pya.Point( 1, 1 ), pya.Point( 1, 5 ) ] self.assertEqual( str(a.bbox()), "(0,1;1,5)" ) self.assertEqual( a.holes(), 0 ) a.insert_hole( [ pya.Point( 1, 2 ), pya.Point( 2, 2 ), pya.Point( 2, 6 ) ] ) self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" ) self.assertEqual( str(pya.Polygon.from_s(str(a))), str(a) ) self.assertEqual( a.area(), 0 ) self.assertEqual( a.num_points_hole(0), 3 ) self.assertEqual( a.holes(), 1 ) self.assertEqual( str(a.point_hull(1)), "1,5" ) self.assertEqual( str(a.point_hull(0)), "0,1" ) self.assertEqual( str(a.point_hull(100)), "0,0" ) self.assertEqual( str(a.point_hole(0, 100)), "0,0" ) self.assertEqual( str(a.point_hole(0, 1)), "2,2" ) self.assertEqual( str(a.point_hole(1, 1)), "0,0" ) a.compress(False); self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" ) a.compress(True); self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" ) b = a.dup() b.assign_hole(0, pya.Box( 10, 20, 20, 60 )) self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60)" ) self.assertEqual( b.is_box(), False ) b.insert_hole(pya.Box( 10, 20, 20, 60 )) self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60/10,20;20,20;20,60;10,60)" ) b = a.dup() b.assign_hole(0, [ pya.Point( 10, 20 ), pya.Point( 20, 20 ), pya.Point( 20, 60 ) ]) self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" ) b.assign_hole(1, [ pya.Point( 15, 25 ), pya.Point( 25, 25 ), pya.Point( 25, 65 ) ]) self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" ) b.insert_hole( [ pya.Point( 1, 2 ), pya.Point( 2, 2 ), pya.Point( 2, 6 ) ] ) self.assertEqual( str(b), "(0,1;1,5;1,1/1,2;2,2;2,6/10,20;20,20;20,60)" ) b.assign_hole(0, [ pya.Point( 15, 25 ), pya.Point( 25, 25 ), pya.Point( 25, 65 ) ]) self.assertEqual( str(b), "(0,1;1,5;1,1/15,25;25,25;25,65/10,20;20,20;20,60)" ) arr = [] for p in a.each_point_hole(0): arr.append(str(p)) self.assertEqual( arr, ["1,2", "2,2", "2,6"] ) arr = [] for p in a.each_edge(): arr.append(str(p)) self.assertEqual( arr, ["(0,1;1,5)", "(1,5;1,1)", "(1,1;0,1)", "(1,2;2,2)", "(2,2;2,6)", "(2,6;1,2)"] ) a = pya.Polygon( [ pya.Point( 0, 1 ), pya.Point( 1, 5 ), pya.Point( 5, 5 ) ] ) self.assertEqual( str(a), "(0,1;1,5;5,5)" ) self.assertEqual( str(a.sized(2)), "(0,-2;-2,0;-1,7;7,7;8,5)" ) self.assertEqual( str(a.sized(2, 2)), "(0,-2;-2,0;-1,7;7,7;8,5)" ) aa = a.dup() a.size(2, 2) self.assertEqual( str(a), "(0,-2;-2,0;-1,7;7,7;8,5)" ) a = aa.dup() a.size(2) self.assertEqual( str(a), "(0,-2;-2,0;-1,7;7,7;8,5)" ) a = pya.Polygon( [ pya.Point( 0, 1 ), pya.Point( 1, 5 ), pya.Point( 5, 5 ) ] ) self.assertEqual( str(a), "(0,1;1,5;5,5)" ) self.assertEqual( str(a.sized(2, 0, 2)), "(-2,1;-1,5;7,5;2,1)" ) a.size(2, 0, 2); self.assertEqual( str(a), "(-2,1;-1,5;7,5;2,1)" ) a = pya.Polygon() self.assertEqual( str(a), "()" ) # corner rounding a = pya.Polygon( [ pya.Point(0, 0), pya.Point(0, 2000), pya.Point(4000, 2000), pya.Point(4000, 1000), pya.Point(2000, 1000), pya.Point(2000, 0) ] ) ar = a.round_corners(100, 200, 8) self.assertEqual( str(ar), "(117,0;0,117;0,1883;117,2000;3883,2000;4000,1883;4000,1117;3883,1000;2059,1000;2000,941;2000,117;1883,0)" ) ar = a.round_corners(200, 100, 32) self.assertEqual( str(ar), "(90,0;71,4;53,11;36,22;22,36;11,53;4,71;0,90;0,1910;4,1929;11,1947;22,1964;36,1978;53,1989;71,1996;90,2000;3910,2000;3929,1996;3947,1989;3964,1978;3978,1964;3989,1947;3996,1929;4000,1910;4000,1090;3996,1071;3989,1053;3978,1036;3964,1022;3947,1011;3929,1004;3910,1000;2180,1000;2142,992;2105,977;2073,955;2045,927;2023,895;2008,858;2000,820;2000,90;1996,71;1989,53;1978,36;1964,22;1947,11;1929,4;1910,0)" ) # Minkowsky sums p = pya.Polygon( [ pya.Point.new(0, -100), pya.Point.new(0, -50), pya.Point.new(-100, -75), pya.Point.new(0, 100), pya.Point.new(50, 50), pya.Point.new(100, 75), pya.Point.new(100, 0), pya.Point.new(100, -50) ] ) self.assertEqual(str(p.minkowsky_sum(pya.Edge.new(pya.Point.new(10, 10), pya.Point.new(210, 110)), True)), "(10,-90;10,-40;-90,-65;10,110;210,210;260,160;310,185;310,60)") self.assertEqual(str(p.minkowsky_sum([pya.Point.new(10, 10), pya.Point.new(10, 310), pya.Point.new(510, 310), pya.Point.new(510, 10), pya.Point.new(10, 10) ], False)), "(10,-90;10,-65;-90,-65;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90/110,110;410,110;410,210;110,210)") self.assertEqual(str(p.minkowsky_sum([pya.Point.new(10, 10), pya.Point.new(10, 310), pya.Point.new(510, 310), pya.Point.new(510, 10), pya.Point.new(10, 10) ], True)), "(10,-90;10,-65;-90,-65;-90,210;110,210;110,110;410,110;410,210;-90,210;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)") self.assertEqual(str(p.minkowsky_sum(pya.Box.new(pya.Point.new(10, 10), pya.Point.new(210, 110)), True)), "(10,-90;10,-65;-90,-65;-90,35;10,210;210,210;235,185;310,185;310,-40;210,-90)") self.assertEqual(str(p.minkowsky_sum(pya.Box.new(pya.Point.new(10, 10), pya.Point.new(210, 10)), True)), "(10,-90;10,-65;-90,-65;10,110;210,110;235,85;310,85;310,-40;210,-90)") self.assertEqual(str(p.minkowsky_sum(pya.Polygon.new(pya.Box.new(pya.Point.new(10, 10), pya.Point.new(210, 110))), True)), "(10,-90;10,-65;-90,-65;-90,35;10,210;210,210;235,185;310,185;310,-40;210,-90)") # Smoothing p = pya.Polygon( [ pya.Point.new(0, 0), pya.Point.new(10, 50), pya.Point.new(0, 100), pya.Point.new(200, 100), pya.Point.new(200, 0) ]) self.assertEqual(str(p.smooth(5)), "(0,0;10,50;0,100;200,100;200,0)") self.assertEqual(str(p.smooth(15)), "(0,0;0,100;200,100;200,0)") # Ellipse constructor p = pya.Polygon.ellipse( pya.Box(-10000, -20000, 30000, 40000), 200 ) self.assertEqual(p.num_points(), 200) self.assertEqual(str(p.bbox()), "(-10000,-20000;30000,40000)") self.assertEqual(p.area(), 1884651158) # roughly box.area*PI/4 p = pya.Polygon.ellipse( pya.Box(-10000, -20000, 30000, 40000), 4 ) self.assertEqual(str(p), "(10000,-20000;-10000,10000;10000,40000;30000,10000)")
layer_photo = layout.layer(_PROG_SETTINGS.LAYERS.photo) layer_el = layout.layer(_PROG_SETTINGS.LAYERS.ebeam) layer_negative = layout.layer(_PROG_SETTINGS.LAYERS.photo_neg) layer_crystal = layout.layer(_PROG_SETTINGS.LAYERS.crystal) layer_bridges = layout.layer(_PROG_SETTINGS.LAYERS.bridges) layer_bridge_patches = layout.layer(_PROG_SETTINGS.LAYERS.bridge_patches) lv.add_missing_layers() # clear this cell and layer # setting layout view # lv.select_cell(cell.cell_index(), 0) # Constants crystal_bounds = pya.Box(Point(-12.5e6, -12.5e6), Point(12.5e6, 12.5e6)) cell.shapes(layer_crystal).insert(Region(crystal_bounds)) ground = pya.Box(Point(-CHIP.dx / 2, -CHIP.dy / 2), Point(CHIP.dx / 2, CHIP.dy / 2)) canvas = Region(ground) negative = Region() ebeam = Region() bridges = Region() bridge_patches = Region() invert_region = Region( pya.Box(Point(-CHIP.dx / 2 - 50e3, -CHIP.dy / 2 - 50e3), Point(CHIP.dx / 2 + 50e3, CHIP.dy / 2 + 50e3))) feed_cpw_params = CPWParameters(20e3, 10e3)
origin = DPoint(0, 0) width = 20e3 gap = 25e3 Z0 = CPW(width, gap, origin + DPoint(0.5e6, 0.5e6), origin + DPoint(1e6, 0.5e6)) Z0.place(cell, layer_i) start = DPoint(0, 0) end = DPoint(1e6, 1e6) ## pathfinding START ## pf = Path_finder(Z0, bbox=CHIP.box) path = pf.find_path_mur(start, end, 100, 100) ## pathfinding END ## ### DRAW SECTION START ### for y in range(0, pf.Ny): for x in range(0, pf.Nx): if (pf.field[x, y] == -2): cell.shapes(layer_j).insert(pya.Box().from_dbox( pya.DBox(DPoint(x * pf.width, y * pf.height), DPoint((x + 1) * pf.width, (y + 1) * pf.height)))) if (Point(x, y) not in path): cell.shapes(layer_i).insert(pya.Box().from_dbox( pya.DBox(DPoint(x * pf.width, y * pf.height), DPoint((x + 1) * pf.width, (y + 1) * pf.height)))) ### DRAW SECTION END ### lv.zoom_fit() ### MAIN FUNCTION END ###
layer_photo = layout.layer(info) layer_el = layout.layer(info2) # clear this cell and layer cell.clear() # setting layout view lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() ### DRAW SECTION START ### origin = DPoint(0, 0) # Chip drwaing START # chip = pya.DBox(DPoint(-CHIP.dx / 2, -CHIP.dy / 2), DPoint(CHIP.dx / 2, CHIP.dy / 2)) cell.shapes(layer_photo).insert(pya.Box(chip)) # Chip drawing END # cp_coords = [ DPoint(-CHIP.dx / 4, -CHIP.dy / 2), DPoint(0, -CHIP.dy / 2), DPoint(CHIP.dx / 4, -CHIP.dy / 2), DPoint(-CHIP.dx / 4, +CHIP.dy / 2), DPoint(0, +CHIP.dy / 2), DPoint(CHIP.dx / 4, +CHIP.dy / 2), DPoint(-CHIP.dx / 2, 0), DPoint(CHIP.dx / 2, 0), ] cp_trans = [ DTrans.R90, DTrans.R90, DTrans.R90,
def produce_impl(self): # fetch the parameters dbu = self.layout.dbu ly = self.layout LayerSi = self.layer LayerSiN = ly.layer(self.layer) LayerPinRecN = ly.layer(self.pinrec) LayerDevRecN = ly.layer(self.devrec) LayerTextN = ly.layer(self.textl) # Fetch all the parameters: a = self.a / dbu r = self.r / dbu wg_dis = self.wg_dis + 1 n_vertices = self.n_vertices n_bus = self.n_bus n = int(math.ceil(self.n / 2)) Sx = [self.S1x, self.S2x, self.S3x, self.S4x, self.S5x] Sy = [self.S1y, 0, self.S2y] if n_bus == 1: Sx = [0, 0, 0, 0, 0] Sy = [0, 0, 0] if wg_dis % 2 == 0: length_slab_x = (2 * n - 1) * a else: length_slab_x = 2 * n * a length_slab_y = 2 * (wg_dis + 15) * a * math.sqrt(3) / 2 n_x = n n_y = wg_dis + 10 # Define Si slab and hole region for future subtraction Si_slab = pya.Region() Si_slab.insert( pya.Box(-length_slab_x / 2, -length_slab_y / 2, length_slab_x / 2, length_slab_y / 2)) hole = pya.Region() hole_r = r # function to generate points to create a circle def circle(x, y, r): npts = n_vertices theta = 2 * math.pi / npts # increment, in radians pts = [] for i in range(0, npts): pts.append( Point.from_dpoint( pya.DPoint((x + r * math.cos(i * theta)) / 1, (y + r * math.sin(i * theta)) / 1))) return pts # raster through all holes with shifts and waveguide hole_cell = circle(0, 0, hole_r) hole_poly = pya.Polygon(hole_cell) for j in range(-n_y, n_y + 1): if j % 2 == 0 and j != wg_dis: for i in range(-n_x, n_x + 1): if j == -wg_dis and i > 3 and n_bus == 2: None elif j == 0 and i in (1, -1, 2, -2, 3, -3, 4, -4, 5, -5): hole_x = abs(i) / i * (abs(i) - 0.5 + Sx[abs(i) - 1]) * a hole_y = 0 hole_trans = pya.Trans(Trans.R0, hole_x, hole_y) hole_t = hole_poly.transformed(hole_trans) hole.insert(hole_t) elif i != 0: hole_x = abs(i) / i * (abs(i) - 0.5) * a hole_y = j * a * math.sqrt(3) / 2 hole_trans = pya.Trans(Trans.R0, hole_x, hole_y) hole_t = hole_poly.transformed(hole_trans) hole.insert(hole_t) elif j % 2 == 1 and j != wg_dis: for i in range(-n_x, n_x + 1): if j == -wg_dis and i > 3 and n_bus == 2: None elif i == 0 and j in (1, -1, 3, -3): hole_x = 0 hole_y = j * a * (math.sqrt(3) / 2) + abs(j) / j * a * Sy[abs(j) - 1] hole_trans = pya.Trans(Trans.R0, hole_x, hole_y) hole_t = hole_poly.transformed(hole_trans) hole.insert(hole_t) else: hole_x = i * a hole_y = j * a * math.sqrt(3) / 2 hole_trans = pya.Trans(Trans.R0, hole_x, hole_y) hole_t = hole_poly.transformed(hole_trans) hole.insert(hole_t) phc = Si_slab - hole self.cell.shapes(LayerSiN).insert(phc) # Pins on the waveguide: pin_length = 200 pin_w = a wg_pos = a * math.sqrt(3) / 2 * wg_dis t = pya.Trans(Trans.R0, -length_slab_x / 2, wg_pos) pin = pya.Path( [pya.Point(pin_length / 2, 0), pya.Point(-pin_length / 2, 0)], pin_w) pin_t = pin.transformed(t) self.cell.shapes(LayerPinRecN).insert(pin_t) text = pya.Text("pin1", t) shape = self.cell.shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu t = pya.Trans(Trans.R0, length_slab_x / 2, wg_pos) pin = pya.Path( [pya.Point(-pin_length / 2, 0), pya.Point(pin_length / 2, 0)], pin_w) pin_t = pin.transformed(t) self.cell.shapes(LayerPinRecN).insert(pin_t) text = pya.Text("pin2", t) shape = self.cell.shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu #pin for drop waveguide if n_bus == 2: t = pya.Trans(Trans.R0, length_slab_x / 2, -wg_pos) pin_t = pin.transformed(t) self.cell.shapes(LayerPinRecN).insert(pin_t) text = pya.Text("pin3", t) shape = self.cell.shapes(LayerPinRecN).insert(text) shape.text_size = 0.4 / dbu # Create the device recognition layer -- make it 1 * wg_width away from the waveguides. points = [[-length_slab_x / 2, 0], [length_slab_x / 2, 0]] points = [Point(each[0], each[1]) for each in points] path = Path(points, length_slab_y) self.cell.shapes(LayerDevRecN).insert(path.simple_polygon())
cross_lens = [125e3] cross_gnd_gaps = [20e3] xmon_dX = 2 * cross_lens[0] + cross_widths[0] + 2 * cross_gnd_gaps[0] xmon_distances = [1e3 * x for x in range(393, 394, 10)] from itertools import product pars = product(cross_widths, cross_lens, cross_gnd_gaps, xmon_distances) for cross_width, cross_len, cross_gnd_gap, xmon_distance in pars: # clear this cell and layer cell.clear() xmon_dX = 2 * cross_len + cross_width + 2 * cross_gnd_gap CHIP.dx = 5 * xmon_dX + xmon_distance CHIP.dy = 5 * xmon_dX + xmon_distance CHIP.center = DPoint(CHIP.dx / 2, CHIP.dy / 2) chip_box = pya.Box(Point(0, 0), Point(CHIP.dx, CHIP.dy)) cell.shapes(layer_photo).insert(chip_box) xmon_cross1 = Xmon_cross(CHIP.center + DPoint(-xmon_distance / 2, 0), cross_width, cross_len, cross_gnd_gap) xmon_cross1.place(cell, layer_photo) xmon_cross2 = Xmon_cross(CHIP.center + DPoint(xmon_distance / 2, 0), cross_width, cross_len, cross_gnd_gap) xmon_cross2.place(cell, layer_photo) ## DRAWING SECTION END ## # lv.zoom_fit() ### MATLAB COMMANDER SECTION START ### ml_terminal = SonnetLab()
# -*- coding: utf-8 -*- #测试pcell import pya from math import * #.insert(pya.Polygon.from_dpoly(x)) layout = pya.Layout() top = layout.create_cell("TOP") l1 = layout.layer(1, 0) #Basic.CIRCLE DONUT ELLIESP ROUND_POLYGON #Basic.STROKED_BOX STROKED_POLYGON #ARC CIRCLE DONUT ELLIPSE PIE ROUND_PATH #ROUND_POLYGON STROKED_BOX STROKED_POLYGON TEXT #Box box1 = pya.Box(70, 70, 200, 200) top.shapes(l1).insert(box1) #Polygon pts = [ pya.Point(0, 0), pya.Point(50, 0), pya.Point(50, 50), pya.Point(40, 60), pya.Point(0, 50) ] polygon1 = pya.Polygon(pts) top.shapes(l1).insert(polygon1) #DPath dpts = [ pya.DPoint(0.4, 0), pya.DPoint(50, 0),
worm_x = CHIP.dx / 2 - L_coupling / 2 worm = EMResonator_TL2Qbit_worm3_XmonFork(Z_res, DPoint(worm_x, y - to_line), L_coupling, L0, L1, r, L2, N, fork_x_span, fork_y_span, fork_metal_width, fork_gnd_gap) xmon_center = (worm.fork_y_cpw1.end + worm.fork_y_cpw2.end) / 2 xmon_center += DPoint( 0, -(cross_len + cross_width / 2) + xmon_fork_penetration) xmonCross = XmonCross(xmon_center, cross_width, cross_len, cross_gnd_gap) # calculate simulation box dimensions chip_box = pya.Box(DPoint(0, 0), DPoint(CHIP.dx, CHIP.dy)) # placing all objects in proper order and translating them to origin cell.shapes(layer_photo).insert(chip_box) # translating all objects so that chip.p1 at coordinate origin xmonCross.place(cell, layer_photo) worm.place(cell, layer_photo) xmonCross_corrected = XmonCross(xmon_center, cross_width, cross_len, xmon_fork_gnd_gap) xmonCross_corrected.place(cell, layer_photo) Z0.place(cell, layer_photo) # delete Xmon cross
layer_info_photo = pya.LayerInfo(10, 0) layer_info_el = pya.LayerInfo(1, 0) layer_photo = layout.layer(layer_info_photo) layer_el = layout.layer(layer_info_el) # clear this cell and layer cell.clear() # setting layout view lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() ## DRAWING SECTION START ## cell.shapes(layer_photo).insert( pya.Box(Point(0, 0), Point(CHIP.dx, CHIP.dy))) origin = DPoint(0, 0) contact_L = 1e6 # main drive line coplanar width = 24.1e3 gap = 12.95e3 p1 = DPoint(0 + contact_L, CHIP.dy / 2) p2 = DPoint(CHIP.dx - contact_L, CHIP.dy / 2) Z0 = CPW(width, gap, p1, p2) Z0.place(cell, layer_photo) # left contact pad width1 = CHIP.width * 2 gap1 = CHIP.gap * 2
# clear this cell and layer cell.clear() # setting layout view lv.select_cell(cell.cell_index(), 0) lv.add_missing_layers() ### DRAW SECTION START ### origin = DPoint(0, 0) X_SIZE = 100e3 Y_SIZE = 100e3 # Chip drwaing START # cpw_pars = CPWParameters(14.5e3, 6.7e3) box = pya.Box(0, 0, X_SIZE, Y_SIZE) cell.shapes(layer_ph).insert(box) cop = CPW_RL_Path(DPoint(0, Y_SIZE / 2), "LRL", cpw_pars, 10e3, [X_SIZE / 2, Y_SIZE / 2], np.pi / 2) cop.place(cell, layer_ph) ports = [ SonnetPort(cop.start, PORT_TYPES.BOX_WALL), SonnetPort(cop.end, PORT_TYPES.BOX_WALL) ] ### DRAW SECTION END ### lv.zoom_fit() from sonnetSim.cMD import CMD ### MATLAB COMMANDER SECTION START ### ml_terminal = SonnetLab()
paintlib.CavityBrush(pointc=pya.DPoint(10012000, 17202000 - 1347000 * (5 + ii)), angle=-180, widout=20000, widin=10000, bgn_ext=0) for ii in range(10) ] brushs = zip(brush1, brush2) cell = celllines layer = layerlines size = 150000 cellList = [top] brushs = brushs layerList = [] box = pya.Box(-12787000, -11127000, 12063000, 18757000) layermod = 'not in' order = None err, lengths, paths = paintlib.AutoRoute.autoRoute(cell, layer, size, cellList, brushs, layerList, box, layermod, order) if not err: print(lengths) args = { "brush1": paintlib.CavityBrush(pointc=pya.DPoint(-4564152, -5268197), angle=0, widout=20000, widin=10000,
def test_2_Expression(self): box1 = pya.Box(0, 100, 200, 300) box2 = pya.Box(50, 150, 250, 350) expr = pya.Expression("a", {"a": box1, "b": box2}) res = expr.eval() self.assertEqual(str(res), "(0,100;200,300)") # boxes are non-managed objects -> passing the object through the expression does not persist their ID self.assertNotEqual(id(res), id(box1)) self.assertNotEqual(id(res), id(box2)) # ------------------------------------------------- box1 = pya.Box(0, 100, 200, 300) box2 = pya.Box(50, 150, 250, 350) expr = pya.Expression("a&b", {"a": box1, "b": box2}) res = expr.eval() self.assertEqual(str(res), "(50,150;200,300)") # computed objects are entirely new ones self.assertNotEqual(id(res), id(box1)) self.assertNotEqual(id(res), id(box2)) # ------------------------------------------------- box1 = pya.Box(0, 100, 200, 300) box2 = pya.Box(50, 150, 250, 350) expr = pya.Expression("x=a&b; y=x; z=y; [x,y,z]", { "a": box1, "b": box2, "x": None, "y": None, "z": None }) res = expr.eval() self.assertEqual( str(res), "[(50,150;200,300), (50,150;200,300), (50,150;200,300)]") # all objects are individual copies self.assertNotEqual(id(res[0]), id(box1)) self.assertNotEqual(id(res[0]), id(box2)) self.assertNotEqual(id(res[1]), id(res[0])) self.assertNotEqual(id(res[2]), id(res[0])) # ------------------------------------------------- box1 = pya.Box(0, 100, 200, 300) box2 = pya.Box(50, 150, 250, 350) expr = pya.Expression("var x=a&b; var y=x; var z=y; [x,y,z]", { "a": box1, "b": box2 }) res = expr.eval() self.assertEqual( str(res), "[(50,150;200,300), (50,150;200,300), (50,150;200,300)]") # all objects are individual copies self.assertNotEqual(id(res[0]), id(box1)) self.assertNotEqual(id(res[0]), id(box2)) self.assertNotEqual(id(res[1]), id(res[0])) self.assertNotEqual(id(res[2]), id(res[0])) # destruction of the expression's object space does not matter since we have copies expr._destroy() self.assertEqual( str(res), "[(50,150;200,300), (50,150;200,300), (50,150;200,300)]") # ------------------------------------------------- region1 = pya.Region() region1 |= pya.Box(0, 100, 200, 300) region2 = pya.Region() region2 |= pya.Box(50, 150, 250, 350) expr = pya.Expression("a", {"a": region1, "b": region2}) res = expr.eval() # regions are managed objects -> passing the object through the expression persists it's object ID self.assertEqual(id(res), id(region1)) self.assertNotEqual(id(res), id(region2)) # ------------------------------------------------- region1 = pya.Region() region1 |= pya.Box(0, 100, 200, 300) region2 = pya.Region() region2 |= pya.Box(50, 150, 250, 350) expr = pya.Expression("a&b", { "a": region1, "b": region2, "x": None, "y": None, "z": None }) res = expr.eval() self.assertEqual(str(res), "(50,150;50,300;200,300;200,150)") # The returned object (as a new one) is an entirely fresh one self.assertNotEqual(id(res), id(region1)) self.assertNotEqual(id(res), id(region2)) # ------------------------------------------------- region1 = pya.Region() region1 |= pya.Box(0, 100, 200, 300) region2 = pya.Region() region2 |= pya.Box(50, 150, 250, 350) expr = pya.Expression("x=a&b; y=x; z=y; [x,y,z]", { "a": region1, "b": region2, "x": None, "y": None, "z": None }) res = expr.eval() self.assertEqual( str(res), "[(50,150;50,300;200,300;200,150), (50,150;50,300;200,300;200,150), (50,150;50,300;200,300;200,150)]" ) # regions are managed objects -> passing the object through the expression persists it's object ID self.assertNotEqual(id(res[0]), id(region1)) self.assertNotEqual(id(res[0]), id(region2)) self.assertEqual(id(res[1]), id(res[0])) self.assertEqual(id(res[2]), id(res[0])) # ------------------------------------------------- region1 = pya.Region() region1 |= pya.Box(0, 100, 200, 300) region2 = pya.Region() region2 |= pya.Box(50, 150, 250, 350) expr = pya.Expression("var x=a&b; var y=x; var z=y; [x,y,z]", { "a": region1, "b": region2 }) res = expr.eval() self.assertEqual( str(res), "[(50,150;50,300;200,300;200,150), (50,150;50,300;200,300;200,150), (50,150;50,300;200,300;200,150)]" ) # regions are managed objects -> passing the object through the expression persists it's object ID self.assertNotEqual(id(res[0]), id(region1)) self.assertNotEqual(id(res[0]), id(region2)) self.assertEqual(id(res[1]), id(res[0])) self.assertEqual(id(res[2]), id(res[0])) # the result objects live in the expression object space and are destroyed with the expression expr._destroy() self.assertEqual(len(res), 3) self.assertEqual(res[0].destroyed(), True) self.assertEqual(res[1].destroyed(), True) self.assertEqual(res[2].destroyed(), True)