def tough_create(): layout = pya.Layout() ipc.trace_pyainsert(layout, debug_file) layout.dbu = 0.001 TOP = layout.create_cell('TOP') l1 = layout.insert_layer(pya.LayerInfo(1, 0)) l2 = layout.insert_layer(pya.LayerInfo(2, 0)) for i in range(51): for j in range(51): box = pya.DBox(0, 0, 10, 10) box.move(15 * i, 15 * j) TOP.shapes(l1).insert(box) TOP.shapes(l2).insert(pya.DBox(0, 0, 1000, 1000))
def read_fills(top): if config_file == '': print('WARNING: no fill config file specified') return # KLayout doesn't support FILL in DEF so we have to side load them :( cfg = read_cfg() in_fills = False units = None with open(in_def) as fp: for line in fp: if in_fills: if re.match('END FILLS', line): break # done with fills; don't care what follows m = re.match(rect_pat, line) if not m: raise Exception('Unrecognized fill: ' + line) opc_type = 'opc' if m.group('opc') else 'non-opc' mask = m.group('mask') if not mask: #uncolored just uses first entry mask = 0 else: mask = int(mask) - 1 # DEF is 1-based indexing layer = cfg[m.group('layer')][opc_type]['klayout'][mask] xlo = int(m.group('xlo')) / units ylo = int(m.group('ylo')) / units xhi = int(m.group('xhi')) / units yhi = int(m.group('yhi')) / units top.shapes(layer).insert(pya.DBox(xlo, ylo, xhi, yhi)) elif re.match('FILLS \d+ ;', line): in_fills = True elif not units: m = re.match('UNITS DISTANCE MICRONS (\d+)', line) if m: units = float(m.group(1))
def read_fills(top): if config_file == "": print("WARNING: no fill config file specified") return # KLayout doesn't support FILL in DEF so we have to side load them :( cfg = read_cfg() in_fills = False units = None with open(in_def) as fp: for line in fp: if in_fills: if re.match("END FILLS", line): break # done with fills; don't care what follows m = re.match(rect_pat, line) if not m: raise Exception("Unrecognized fill: " + line) opc_type = "opc" if m.group("opc") else "non-opc" mask = m.group("mask") if not mask: # uncolored just uses first entry mask = 0 else: mask = int(mask) - 1 # DEF is 1-based indexing layer = cfg[m.group("layer")][opc_type]["klayout"][mask] xlo = int(m.group("xlo")) / units ylo = int(m.group("ylo")) / units xhi = int(m.group("xhi")) / units yhi = int(m.group("yhi")) / units top.shapes(layer).insert(pya.DBox(xlo, ylo, xhi, yhi)) elif re.match("FILLS \d+ ;", line): in_fills = True elif not units: m = re.match("UNITS DISTANCE MICRONS (\d+)", line) if m: units = float(m.group(1))
def fill_holes(obj, dx=10e3, dy=8e3, width=5e3, height=5e3, d=0): if (obj.is_cell_inst()): return None poly = obj.shape.polygon 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 obj.shape.polygon = poly
class CHIP: dx = 0.6e6 dy = 2.5e6 nX = 300 # simulation box cells along X-axis nY = 1250 # simulation box cells along Y-axis # connections of the chip (not used in this file) gap = 150.e3 width = 260.e3 b = 2 * gap + width origin = DPoint(0, 0) box = pya.DBox(origin, origin + DPoint(dx, dy)) L1 = 220 # only 4 connections programmed by now connections = [ box.p1 + DPoint(L1 + b / 2, 0), box.p1 + DPoint(dx - (L1 + b / 2), 0), box.p2 - DPoint(L1 + b / 2, 0), box.p1 + DPoint(L1 + b / 2, dy) ] @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 draw_el_protection(self): protection_a = 300e3 for squid in (self.squids + self.test_squids): self.region_el_protection.insert(pya.Box().from_dbox( pya.DBox( squid.origin - 0.5 * DVector(protection_a, protection_a), squid.origin + 0.5 * DVector(protection_a, protection_a))))
def fill_poly(poly): bbox = poly.bbox() poly_reg = Region(poly) t_reg = Region() # Draw boundary around holes in the polygon for hole_i in range(0, poly.holes()): points = [p for p in poly.each_point_hole(hole_i)] points.append(points[0]) boundary = Path(points, 2 * d) poly_reg -= Region(boundary) # Draw boundary around the outer edge of the polygon points = [p for p in poly.each_point_hull()] points.append(points[0]) boundary = Path(points, 2 * d) poly_reg -= Region(boundary) # Fill the boundary box with holes 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.insert(box) y += dy # Select only inner holes holes_inside = t_reg.select_inside(poly_reg) for box in holes_inside.each(): poly.insert_hole(list(box.each_point_hull())) return poly
def _prepare_wall(self): self.wall = [] for Z0 in self.objects: if (isinstance(Z0, CPW) and Z0.dr.abs() != 0): for ny in range(0, self.Ny): for nx in range(0, self.Nx): x = nx * self.width y = ny * self.height w = Z0.width drLeft = DPoint(-Z0.dr.y, Z0.dr.x) * (1 / Z0.dr.abs()) box = pya.DBox(DPoint(x, y), DPoint(x + self.width, y + self.height)) if ((box.left - abs(drLeft.x) * 2 * Z0.b / 2) > Z0.end.x or (box.right + abs(drLeft.x) * 2 * Z0.b / 2) < Z0.start.x): continue if ((box.bottom - abs(drLeft.y) * 2 * Z0.b / 2) > Z0.end.y or (box.top + abs(drLeft.y) * 2 * Z0.b / 2) < Z0.start.y): continue self.wall.append(Point(nx, ny)) for pt in self.wall: self.field[pt.x, pt.y] = -2
def produce_impl(self): point_LL = pya.DPoint(-self.side_a/2, -self.side_a/2) point_TR = pya.DPoint(self.side_a/2, self.side_a/2) ourSquare = pya.DBox(point_LL, point_TR) self.cell.shapes(self.l_layer).insert(ourSquare)
def coerce_parameters_impl(self): if self.l1 < 0: self.l1 *= -1 if self.l2 < 0: self.l2 *= -1 if self.b1 < 0: self.b1 *= -1 if self.b2 < 0: self.b2 *= -1 if self.w < 0: self.w *= -1 if self.dx < 0: self.dx *= -1 if self.dy < 1: self.dy *= -1 if self.rw < 0: self.rw *= -1 if self.rh < 0: self.rh *= -1 if self.b1 < self.l1 * 2: self.b1 = self.l1 * 2 if self.b2 < self.l2 * 2: self.b2 = self.l2 * 2 if self.b1 < (self.w / 2 + self.dx + self.rw) * 2: self.b1 = (self.w / 2 + self.dx + self.rw) * 2 if self.b2 < (self.w / 2 + self.dy + self.rh) * 2: self.b2 = (self.w / 2 + self.dy + self.rh) * 2 if self.l1_ != self.l1 or self.l2_ != self.l2 or self.w_ != self.w or self.b1_ != self.b1 or self.b2_ != self.b2 or self.dx != self.dx_ or self.dy != self.dy_ or self.rw != self.rw_ or self.rh != self.rh_: # update handle self.hh = pya.DPoint(self.l1, self.w / 2) self.hv = pya.DPoint(0, self.l2) self.hb = pya.DPoint(self.b1 / 2, self.b2 / 2) self.hr = pya.DBox( pya.DPoint(self.w / 2 + self.dx, self.w / 2 + self.dy), pya.DPoint(self.w / 2 + self.dx + self.rw, self.w / 2 + self.dy + self.rh)) # fix params self.l1_ = self.l1 self.l2_ = self.l2 self.w_ = self.w self.b1_ = self.b1 self.b2_ = self.b2 self.dx_ = self.dx self.dy_ = self.dy self.rw_ = self.rw self.rh_ = self.rh else: # calc params from handle self.l1 = self.l1_ = abs(self.hh.x) self.l2 = self.l2_ = abs(self.hv.y) self.w = self.w_ = abs(self.hh.y * 2) self.b1 = self.b1_ = abs(self.hb.x * 2) self.b2 = self.b2_ = abs(self.hb.y * 2) self.dx = self.dx_ = abs(self.hr.p1.x) - self.w / 2 self.dy = self.dy_ = abs(self.hr.p1.y) - self.w / 2 self.rw = self.rw_ = abs(self.hr.p2.x) - self.w / 2 - self.dx self.rh = self.rh_ = abs(self.hr.p2.y) - self.w / 2 - self.dy
def __init__(self): # Important: initialize the super class super(CrossRectangle, self).__init__() # declare the parameters self.param("l", self.TypeLayer, "Layer", default=pya.LayerInfo(1, 0)) self.param("hh", self.TypeShape, "", default=pya.DPoint(10, 0.5)) self.param("hv", self.TypeShape, "", default=pya.DPoint(0, 10)) self.param("hb", self.TypeShape, "", default=pya.DPoint(20, 20)) self.param("hr", self.TypeShape, "", default=pya.DBox(pya.DPoint(2, 2), pya.DPoint(10, 10))) self.param("l1", self.TypeDouble, "Width", default=10) self.param("l2", self.TypeDouble, "Height", default=10) self.param("w", self.TypeDouble, "Line width", default=1) self.param("inv", self.TypeBoolean, "Inverted", default=False) self.param("b1", self.TypeDouble, "Boundary width", default=20) self.param("b2", self.TypeDouble, "Boundary height", default=20) self.param("dx", self.TypeDouble, "Distance X", default=1.5) self.param("dy", self.TypeDouble, "Distance Y", default=1.5) self.param("rw", self.TypeDouble, "Rectangle width", default=8) self.param("rh", self.TypeDouble, "Rectangle height", default=8) self.param("l1_", self.TypeDouble, "Width", default=10, hidden=True) self.param("l2_", self.TypeDouble, "Height", default=10, hidden=True) self.param("w_", self.TypeDouble, "Line width", default=1, hidden=True) self.param("b1_", self.TypeDouble, "Boundary width", default=20, hidden=True) self.param("b2_", self.TypeDouble, "Boundary height", default=20, hidden=True) self.param("dx_", self.TypeDouble, "Distance X", default=1.5, hidden=True) self.param("dy_", self.TypeDouble, "Distance Y", default=1.5, hidden=True) self.param("rw_", self.TypeDouble, "Rectangle width", default=8, hidden=True) self.param("rh_", self.TypeDouble, "Rectangle height", default=8, hidden=True)
class CHIP: dx = 10.1e6 dy = 5.1e6 L1 = 2466721 gap = 150e3 width = 260e3 b = 2*gap + width origin = DPoint( 0,0 ) box = pya.DBox( origin, origin + DPoint( dx,dy ) ) # only 4 connections programmed by now connections = [box.p1 + DPoint( L1 + b/2,0 ), box.p1 + DPoint( dx - (L1+b/2),0 ), box.p2 - DPoint( L1 + b/2,0 ), box.p1 + DPoint( L1 + b/2, dy )]
class CHIP: dx = 0.6e6 dy = 1.8e6 L1 = 2.5e6 gap = 150.e3 width = 260.e3 b = 2*gap + width origin = DPoint( 0,0 ) box = pya.DBox( origin, origin + DPoint( dx,dy ) ) # only 4 connections programmed by now connections = [box.p1 + DPoint( L1 + b/2,0 ), box.p1 + DPoint( dx - (L1+b/2),0 ), box.p2 - DPoint( L1 + b/2,0 ), box.p1 + DPoint( L1 + b/2, dy )]
class CHIP: dx = 10.0e6 dy = 5.0e6 L1 = 2.416721e6 gap = 150e3 width = 260e3 Z = CPW(width, gap, DPoint(0, 0), DPoint(1, 1)) b = 2 * gap + width origin = DPoint(0, 0) box = pya.DBox(origin, origin + DPoint(dx, dy)) # only 4 connections programmed by now connections = [box.p1 + DPoint(L1 + b / 2, 0), box.p1 + DPoint(dx - (L1 + b / 2), 0), box.p2 - DPoint(L1 + b / 2, 0), box.p1 + DPoint(L1 + b / 2, dy)]
def simple_create(grids=4): t0 = time.time() layout = pya.Layout() ipc.trace_pyainsert(layout, debug_file) layout.dbu = 0.001 TOP = layout.create_cell('TOP') l1 = layout.insert_layer(pya.LayerInfo(1, 0)) for i in range(grids): for j in range(grids): box = pya.DBox(0, 0, 10, 10) box.move(15 * i, 15 * j) TOP.shapes(l1).insert(box) print(time.time() - t0)
def test_2_DPolygon(self): pts = [pya.DPoint(0, 0)] p = pya.DPolygon(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.DPolygon(pya.DBox(0, 0, 100, 100)) p.insert_hole([pya.DPoint(0, 0), pya.DPoint(10, 0)], True) self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)") p.assign_hole(0, [pya.DPoint(0, 0), pya.DPoint(10, 0)]) self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)") p.assign_hole(0, [pya.DPoint(0, 0), pya.DPoint(10, 0)], True) self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)") pts = [pya.DPoint(0, 0), pya.DPoint(10, 0)] p = pya.DPolygon(pts, True) self.assertEqual(str(p), "(0,0;10,0)") self.assertEqual(str(pya.Polygon(p)), "(0,0;10,0)") p.hull = [] self.assertEqual(str(p), "()") p.hull = [pya.DPoint(0, 0), pya.DPoint(10, 0)] self.assertEqual(str(p), "(0,0;10,0)") p.assign_hull([pya.DPoint(0, 0), pya.DPoint(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.DTrans(pya.DTrans.R90))), "(0,0;0,10)") pp = p.dup() pp.transform(pya.DTrans(pya.DTrans.R90)) self.assertEqual(str(pp), "(0,0;0,10)")
def add_box(line): m = re.match(bbox_re, line) if not m: assert(line.strip() == ')') return False # covert DBU to microns # TODO: get conversion factor from KLayout lx = float(m.group(1)) / 2000.0 ly = float(m.group(2)) / 2000.0 ux = float(m.group(3)) / 2000.0 uy = float(m.group(4)) / 2000.0 layer = m.group(5) if layer not in categories: category = rdb.create_category(layer) categories[layer] = category category = categories[layer] item = rdb.create_item(cell, category) bbox = pya.DBox(lx, ly, ux, uy) item.add_value(bbox) return True
class CHIP: """ 10x10 mm chip PCB design located here: https://drive.google.com/drive/folders/1TGjD5wwC28ZiLln_W8M6gFJpl6MoqZWF?usp=sharing """ dx = 10e6 dy = 10e6 origin = DPoint(0, 0) box = pya.DBox(origin, origin + DPoint(dx, dy)) L1 = 220 # only 4 connections programmed by now @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 __init__(self, origin, params, trans_in=None): self.params = params self.a = params[0] self.b = params[1] self.jos1_b = params[2] self.jos1_a = params[3] self.f1 = params[4] self.d1 = params[5] self.jos2_b = params[6] self.jos2_a = params[7] self.f2 = params[8] self.d2 = params[9] self.w = params[10] self.B1_width = params[11] self.B1_height = params[12] self.B2_height = params[13] self.B5_height = params[14] self.B6_width = params[15] self.B6_height = params[16] self.B7_width = params[17] self.B7_height = params[18] self.dCap = params[19] self.gap = params[20] # calculated parameters self.B2_width = (self.gap - self.dCap - self.B6_width / 2 - 4 * self.w - self.jos1_a - self.jos2_a) / 2 self.B5_width = self.B2_width self.B3_width = self.a + self.jos1_a / 2 - self.jos2_a / 2 - self.w self.B4_width = self.a + self.jos2_a / 2 - self.jos1_a / 2 - self.w self._alpha_1 = 0.5 self._length1 = (self.b + 2 * self.w + self.jos1_b) self._alpha_2 = 0.5 self._length2 = (self.b + 2 * self.w - 2 * self.f2 - self.jos2_b ) #length self.p0 = DPoint(0, 0) self.p1 = self.p0 + DPoint(self.dCap, 0) self.p2 = self.p1 + DPoint(self.B1_width, (self.B1_height - self.B2_height) / 2) self.p3 = self.p2 + DPoint(self.B2_width, self.B2_height) self.p4 = self.p3 + DPoint(self.w, -self.w) self.p5 = self.p4 + DPoint(self.B3_width, self.w) self.p6 = self.p5 - DPoint(0, self.f2 + self._length2 * self._alpha_2) self.p7 = self.p6 + DPoint(2 * self.w + self.jos2_a, -self.jos2_b) self.p8 = self.p7 - DPoint( 0, self.f2 + (1 - self._alpha_2) * self._length2) self.p9 = self.p8 - DPoint(self.B4_width + self.w, 0) self.p10 = self.p8 + DPoint(self.B5_width, (self.B5_height - self.B6_height) / 2) self.p11 = self.p10 + DPoint(self.B6_width, (self.B6_height - self.B7_height) / 2) self.B1 = pya.DBox(self.p1, self.p1 + DPoint(self.B1_width, self.B1_height)) self.B2 = pya.DBox(self.p2, self.p3) self.B3 = pya.DBox(self.p4, self.p5) self.B4 = pya.DBox(self.p9, self.p9 + DPoint(self.B4_width, self.w)) self.B5 = pya.DBox(self.p8, self.p8 + DPoint(self.B5_width, self.B5_height)) self.B6 = pya.DBox(self.p10, self.p10 + DPoint(self.B6_width, self.B6_height)) self.B7 = pya.DBox(self.p11, self.p11 + DPoint(self.B7_width, self.B7_height)) self.poly_1 = self._make_polygon(self._length1 * self._alpha_1, self.w, self.d1, self.f1, self.jos1_b) self.poly_1.transform(DCplxTrans(1.0, 270, False, self.p3)) self.poly_2 = self._make_polygon(self._length1 * (1 - self._alpha_1), self.w, self.d1, self.f1, self.jos1_b) self.poly_2.transform(DCplxTrans(1.0, 90, False, self.p9)) self.poly_3 = self._make_polygon(self._length2 * self._alpha_2, self.w, self.d2, self.f2, self.jos2_b) self.poly_3.transform(DCplxTrans(1.0, 270, False, self.p5)) self.poly_4 = self._make_polygon(2 * self.jos2_b + self.f2, self.w, self.d2, self.f2, self.jos2_b) self.poly_4.transform(DCplxTrans(1.0, 90, False, self.p7)) self.poly_5 = self._make_polygon(2 * self.jos2_b + self.f2, self.w, self.d2, self.f2, self.jos2_b) self.poly_5.transform(DCplxTrans(1.0, 270, False, self.p6)) self.poly_6 = self._make_polygon((1 - self._alpha_2) * self._length2, self.w, self.d2, self.f2, self.jos2_b) self.poly_6.transform(DCplxTrans(1.0, 90, False, self.p8)) super().__init__(origin, trans_in)
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_1_DPolygon(self): a = pya.DPolygon() self.assertEqual( str(a), "()" ) self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) ) self.assertEqual( a.is_box(), False ) b = a.dup() a = pya.DPolygon( [ pya.DPoint( 0, 1 ), pya.DPoint( 1, 5 ), pya.DPoint( 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.DPolygon.from_s(str(a))), str(a) ) self.assertEqual( a.is_box(), False ) 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.DPolygon( pya.DBox( 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.Polygon(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.DPoint( 10, 0 ) ), True ) self.assertEqual( a.inside( pya.DPoint( 5, 0 ) ), True ) self.assertEqual( a.inside( pya.DPoint( 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.DPoint( 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.DPoint( 1, 0 ) ) self.assertEqual( str(a), "(6,-10;6,15;21,15;21,-10)" ) b = b.transformed( pya.DTrans( pya.DTrans.R0, pya.DPoint( 1, 0 )) ) self.assertEqual( str(b), "(6,-10;6,15;21,15;21,-10)" ) m = pya.DCplxTrans( pya.DTrans(), 1.5 ) self.assertEqual( type(a.transformed(m)).__name__, "DPolygon" ) self.assertEqual( str(a.transformed(m)), "(9,-15;9,22.5;31.5,22.5;31.5,-15)" ) m = pya.VCplxTrans( 1000.0 ) self.assertEqual( type(a.transformed(m)).__name__, "Polygon" ) self.assertEqual( str(a.transformed(m)), "(6000,-10000;6000,15000;21000,15000;21000,-10000)" ) a.hull = [ pya.DPoint( 0, 1 ), pya.DPoint( 1, 1 ), pya.DPoint( 1, 5 ) ] self.assertEqual( str(a.bbox()), "(0,1;1,5)" ) self.assertEqual( a.holes(), 0 ) a.insert_hole( [ pya.DPoint( 1, 2 ), pya.DPoint( 2, 2 ), pya.DPoint( 2, 6 ) ] ) self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" ) self.assertEqual( str(pya.DPolygon.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.DBox( 10, 20, 20, 60 )) self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60)" ) b.insert_hole(pya.DBox( 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)" ) self.assertEqual( b.is_box(), False ) b = a.dup() b.assign_hole(0, [ pya.DPoint( 10, 20 ), pya.DPoint( 20, 20 ), pya.DPoint( 20, 60 ) ]) self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" ) b.assign_hole(1, [ pya.DPoint( 15, 25 ), pya.DPoint( 25, 25 ), pya.DPoint( 25, 65 ) ]) self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" ) b.insert_hole( [ pya.DPoint( 1, 2 ), pya.DPoint( 2, 2 ), pya.DPoint( 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.DPoint( 15, 25 ), pya.DPoint( 25, 25 ), pya.DPoint( 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)"] ) # Ellipse constructor p = pya.DPolygon.ellipse( pya.DBox(-10000, -20000, 30000, 40000), 200 ) self.assertEqual(p.num_points(), 200) self.assertEqual(str(p.bbox()), "(-10000,-20000;30000,40000)") self.assertEqual(int(p.area()), 1884645544) # roughly box.area*PI/4 p = pya.DPolygon.ellipse( pya.DBox(-10000, -20000, 30000, 40000), 4 ) self.assertEqual(str(p), "(10000,-20000;-10000,10000;10000,40000;30000,10000)")
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 ###
info = pya.LayerInfo(1, 0) info2 = pya.LayerInfo(2, 0) 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,
def __init__(self, origin, params, trans_in=None): self.params = params self.a = params[0] self.b = params[1] self.jos1_b = params[2] self.jos1_a = params[3] self.f1 = params[4] self.d1 = params[5] self.jos2_b = params[6] self.jos2_a = params[7] self.f2 = params[8] self.d2 = params[9] self.w = params[10] self.dCap = params[11] self.gap = params[12] self.square_a = params[13] self.dSquares = params[14] self.alum_over = params[15] self.B1_width = params[16] # calculated parameters self.B2_width = self.a + self.jos1_a / 2 - self.jos2_a / 2 - self.w self.qbit_width = 2 * self.w + self.B2_width self.B3_width = self.a + self.jos2_a / 2 - self.jos1_a / 2 - self.w self.B1_height = (self.dSquares - 2 * self.w - self.b) / 2 self._alpha_1 = 0.5 self._length1 = (self.b + 2 * self.w + self.jos1_b) self._alpha_2 = 0.5 self._length2 = (self.b + 2 * self.w - 2 * self.f2 - self.jos2_b ) #length self.p0 = DPoint(0, 0) self.p1 = self.p0 - DPoint(0, self.dCap + self.square_a) self.p2 = self.p1 + DPoint(self.square_a / 2 - self.qbit_width / 2, -(self.dCap + self.B1_height)) self.p3 = self.p2 + DPoint(self.qbit_width - self.w, 0) self.p4 = self.p2 + DPoint(self.w, -self.w) self.p5 = self.p3 - DPoint(0, self.f2 + self._length2 * self._alpha_2) self.p6 = self.p5 + DPoint(2 * self.w + self.jos2_a, -self.jos2_b) self.p7 = self.p6 - DPoint( 0, self.f2 + (1 - self._alpha_2) * self._length2) self.p8 = self.p7 - DPoint(self.w + self.B3_width, 0) self.p9 = self.p7 - DPoint( self.w + (self.qbit_width + self.B3_width) / 2, self.B1_height) self.p10 = self.p1 - DPoint( 0, self.square_a + self.b + 2 * self.B1_height + 2 * self.w) self.SQ1 = pya.DBox(self.p1, self.p1 + DPoint(self.square_a, self.square_a)) self._B1p1 = self.p2 + DPoint(self.qbit_width / 2 - self.B1_width / 2, 0) self.B1 = pya.DBox( self._B1p1, self._B1p1 + DPoint(self.B1_width, self.B1_height + self.alum_over)) self.B2 = pya.DBox(self.p4, self.p3) self.B3 = pya.DBox(self.p8, self.p8 + DPoint(self.B3_width, self.w)) self._B4p1 = self.p9 + DPoint(self.qbit_width / 2 - self.B1_width / 2, -self.alum_over) self.B4 = pya.DBox( self._B4p1, self._B4p1 + DPoint(self.B1_width, self.B1_height + self.alum_over)) self.SQ2 = pya.DBox(self.p10, self.p10 + DPoint(self.square_a, self.square_a)) self.poly_1 = self._make_polygon(self._length1 * self._alpha_1, self.w, self.d1, self.f1, self.jos1_b) self.poly_1.transform(DCplxTrans(1.0, 270, False, self.p2)) self.poly_2 = self._make_polygon(self._length1 * (1 - self._alpha_1), self.w, self.d1, self.f1, self.jos1_b) self.poly_2.transform(DCplxTrans(1.0, 90, False, self.p8)) self.poly_3 = self._make_polygon(self._length2 * self._alpha_2, self.w, self.d2, self.f2, self.jos2_b) self.poly_3.transform(DCplxTrans(1.0, 270, False, self.p3)) self.poly_4 = self._make_polygon(2 * self.jos2_b + self.f2, self.w, self.d2, self.f2, self.jos2_b) self.poly_4.transform(DCplxTrans(1.0, 90, False, self.p6)) self.poly_5 = self._make_polygon(2 * self.jos2_b + self.f2, self.w, self.d2, self.f2, self.jos2_b) self.poly_5.transform(DCplxTrans(1.0, 270, False, self.p5)) self.poly_6 = self._make_polygon((1 - self._alpha_2) * self._length2, self.w, self.d2, self.f2, self.jos2_b) self.poly_6.transform(DCplxTrans(1.0, 90, False, self.p7)) super().__init__(origin, trans_in)
w = 0.2e3 dCap = 0 dSquares = 30e3 gap = 25e3 square_a = 150e3 alum_over = 20e3 B1_width = 3e3 qbit_params = [ a, b, jos1_b, jos1_a, f1, d1, jos2_b, jos2_a, f2, d2, w, dCap, gap, square_a, dSquares, alum_over, B1_width ] toLine = 25e3 dy = (worm.cop_tail.dr.abs() - square_a) / 2 qbit = QBit_Flux_Сshunted(worm.end + DPoint(toLine, dy), qbit_params, DCplxTrans(1, 90, False, 0, 0)) qbit.place(cell, layer_photo, layer_el) #empty polygon for qBit qbit_bbox = pya.DBox().from_ibox(qbit.metal_region.bbox()) empty = CPW( 0, qbit_bbox.height() / 2 + 2 * qbit.a, qbit_bbox.p1 + DPoint(0, qbit_bbox.height() / 2), qbit_bbox.p2 - DPoint(qbit.B4.width() + qbit.B3.width() / 2, qbit_bbox.height() / 2)) empty.place(cell, layer_photo) ## DRAWING SECTION END ## lv.zoom_fit()
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 __init__(self, origin, params, trans_in=None): self.params = params self.a = params[0] self.b = params[1] self.jos1_b = params[2] self.jos1_a = params[3] self.f1 = params[4] self.d1 = params[5] self.jos2_b = params[6] self.jos2_a = params[7] self.f2 = params[8] self.d2 = params[9] self.w = params[10] self.dCap = params[11] self.gap = params[12] self.square_a = params[13] self.dSquares = params[14] self.alum_over = params[15] self.B1_width = params[16] # calculated parameters self.B2_width = self.a + self.jos1_a / 2 - self.jos2_a / 2 - self.w self.qbit_width = 2 * self.w + self.B2_width self.B3_width = self.b - self.jos2_a / 2 - self.jos1_a / 2 - 2 * self.w self.B1_height = (self.dSquares - 2 * self.w - self.b) / 2 self._alpha_1 = 0.5 self._length1 = (self.b + 2 * self.w + self.jos1_b) self._alpha_2 = 0.5 self._length2 = (self.b + 2 * self.w - 2 * self.f2 - self.jos2_b ) #length self._length_right = (self.b + 2 * self.w - 2 * self.jos2_b) / 3 self.p0 = DPoint(0, 0) self.p1 = self.p0 - DPoint(0, self.dCap + self.square_a) self.p2 = self.p1 + DPoint(self.square_a / 2 - self.qbit_width / 2, -(self.dCap + self.B1_height)) self.p3 = self.p2 + DPoint(self.qbit_width - self.w, 0) self.p4 = self.p2 + DPoint(self.w, -self.w) self.p5 = self.p3 + DPoint(2 * self.w + self.jos2_a, -(2 * self._length_right + 2 * self.jos2_b)) self.p6 = self.p3 - DPoint(0, self.b + 2 * self.w) self.p7 = self.p6 - DPoint(self.B3_width, 0) self.p8 = self.p7 - DPoint(self.w, self.B1_height) self.p9 = self.p1 - DPoint( 0, self.square_a + self.b + 2 * self.B1_height + 2 * self.w) self.SQ1 = pya.DBox(self.p1, self.p1 + DPoint(self.square_a, self.square_a)) self._B1p1 = self.p2 + DPoint( (self.B2_width + 2 * self.w) / 2 - self.B1_width / 2, 0) self.B1 = pya.DBox( self._B1p1, self._B1p1 + DPoint(self.B1_width, self.B1_height + self.alum_over)) self.B2 = pya.DBox(self.p4, self.p3) self.B3 = pya.DBox(self.p7, self.p7 + DPoint(self.B3_width, self.w)) self._B4p1 = self.p8 + DPoint( (self.B3_width + 2 * self.w) / 2 - self.B1_width / 2, -self.alum_over) self.B4 = pya.DBox( self._B4p1, self._B4p1 + DPoint(self.B1_width, self.B1_height + self.alum_over)) self.SQ2 = pya.DBox(self.p9, self.p9 + DPoint(self.square_a, self.square_a)) self.poly_1 = self._make_polygon(self._length1 * self._alpha_1, self.w, self.d1, self.f1, self.jos1_b) self.poly_1.transform(DCplxTrans(1.0, 270, False, self.p2)) self.poly_2 = self._make_polygon(self._length1 * (1 - self._alpha_1), self.w, self.d1, self.f1, self.jos1_b) self.poly_2.transform(DCplxTrans(1.0, 90, False, self.p7)) self.poly_3 = self._make_polygon(self._length_right + self.jos2_b, self.w, self.d2, self.f2, self.jos2_b) self.poly_3.transform(DCplxTrans(1.0, 270, False, self.p3)) self.poly_4 = self._make_polygon( self._length_right + self.jos2_b - self.f2, self.w, self.d2, self.f2, self.jos2_b) self.poly_4.transform( DCplxTrans( 1.0, 270, True, self.p5 + DPoint(0, self._length_right + self.jos2_b - self.f2))) _poly_tmp = self._make_polygon( self._length_right + self.jos2_b - self.f2, self.w, self.d2, self.f2, self.jos2_b) _poly_tmp.transform( DCplxTrans(1.0, 90, False, self.p5 + DPoint(0, self.jos2_b + self.f2))) _reg_tmp4 = Region() _reg_tmp4.insert(SimplePolygon().from_dpoly(self.poly_4)) _reg_tmp = Region() _reg_tmp.insert(SimplePolygon().from_dpoly(_poly_tmp)) self._reg_tmp_to_metal = (_reg_tmp + _reg_tmp4).merged() self.poly_5 = self._make_polygon(self._length_right + self.jos2_b, self.w, self.d2, self.f2, self.jos2_b) self.poly_5.transform(DCplxTrans(1.0, 90, True, self.p6)) super().__init__(origin, trans_in)
def test_3_DTrans(self): c = pya.DCplxTrans(5.0, -7.0) self.assertEqual(str(c), "r0 *1 5,-7") c = pya.DCplxTrans(pya.DCplxTrans.M135) self.assertEqual(str(c), "m135 *1 0,0") self.assertEqual(c.is_unity(), False) self.assertEqual(c.is_ortho(), True) self.assertEqual(c.is_mag(), False) self.assertEqual(c.is_mirror(), True) self.assertEqual(c.rot(), pya.DCplxTrans.M135.rot()) self.assertEqual(str(c.s_trans()), "m135 0,0") self.assertAlmostEqual(c.angle, 270) self.assertEqual(str(c.trans(pya.DEdge(0, 1, 2, 3))), "(-3,-2;-1,0)") self.assertEqual(str((c * pya.DEdge(0, 1, 2, 3))), "(-3,-2;-1,0)") self.assertEqual(str(c.trans(pya.DBox(0, 1, 2, 3))), "(-3,-2;-1,0)") self.assertEqual(str((c * pya.DBox(0, 1, 2, 3))), "(-3,-2;-1,0)") self.assertEqual(str(c.trans(pya.DText("text", pya.DVector(0, 1)))), "('text',m135 -1,0)") self.assertEqual(str((c * pya.DText("text", pya.DVector(0, 1)))), "('text',m135 -1,0)") self.assertEqual( str( c.trans( pya.DPolygon([ pya.DPoint(0, 1), pya.DPoint(2, -3), pya.DPoint(4, 5) ]))), "(-5,-4;-1,0;3,-2)") self.assertEqual( str((c * pya.DPolygon( [pya.DPoint(0, 1), pya.DPoint(2, -3), pya.DPoint(4, 5)]))), "(-5,-4;-1,0;3,-2)") self.assertEqual( str(c.trans(pya.DPath( [pya.DPoint(0, 1), pya.DPoint(2, 3)], 10))), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false") self.assertEqual( str((c * pya.DPath( [pya.DPoint(0, 1), pya.DPoint(2, 3)], 10))), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false") c = pya.DCplxTrans.from_itrans(pya.CplxTrans.M135) self.assertEqual(str(c), "m135 *1 0,0") c = pya.DCplxTrans(1.5) self.assertEqual(str(c), "r0 *1.5 0,0") self.assertEqual(c.is_unity(), False) self.assertEqual(c.is_ortho(), True) self.assertEqual(c.is_mag(), True) self.assertEqual(c.is_mirror(), False) self.assertEqual(c.rot(), pya.DCplxTrans.R0.rot()) self.assertEqual(str(c.s_trans()), "r0 0,0") self.assertAlmostEqual(c.angle, 0) c = pya.DCplxTrans(0.75, 45, True, 2.5, -12.5) self.assertEqual(str(c), "m22.5 *0.75 2.5,-12.5") c = pya.DCplxTrans(0.75, 45, True, pya.DPoint(2.5, -12.5)) self.assertEqual(str(c), "m22.5 *0.75 2.5,-12.5") self.assertEqual(c.is_unity(), False) self.assertEqual(c.is_ortho(), False) self.assertEqual(c.is_mag(), True) self.assertEqual(c.rot(), pya.DCplxTrans.M0.rot()) self.assertEqual(str(c.s_trans()), "m0 2.5,-12.5") self.assertAlmostEqual(c.angle, 45) self.assertEqual(str(c.ctrans(5)), "3.75") self.assertEqual(str(c.trans(pya.DPoint(12, 16))), "17.3492424049,-14.6213203436") self.assertEqual(str(pya.DCplxTrans()), "r0 *1 0,0") self.assertEqual(pya.DCplxTrans().is_unity(), True) self.assertEqual((c * c.inverted()).is_unity(), True) c.mirror = False self.assertEqual(str(c), "r45 *0.75 2.5,-12.5") c.mag = 1.5 self.assertEqual(str(c), "r45 *1.5 2.5,-12.5") c.disp = pya.DPoint(-1.0, 5.5) self.assertEqual(str(c), "r45 *1.5 -1,5.5") self.assertEqual(c.mag, 1.5) c.angle = 60 self.assertEqual(str(c), "r60 *1.5 -1,5.5") self.assertEqual(("%g" % c.angle), "60") # Constructor variations self.assertEqual(str(pya.ICplxTrans()), "r0 *1 0,0") self.assertEqual(str(pya.ICplxTrans(1.5)), "r0 *1.5 0,0") self.assertEqual(str(pya.ICplxTrans(pya.Trans(1, False, 10, 20), 1.5)), "r90 *1.5 10,20") self.assertEqual(str(pya.ICplxTrans(pya.Trans(1, False, 10, 20))), "r90 *1 10,20") self.assertEqual( str(pya.ICplxTrans(1.5, 80, True, pya.Vector(100, 200))), "m40 *1.5 100,200") self.assertEqual(str(pya.ICplxTrans(1.5, 80, True, 100, 200)), "m40 *1.5 100,200") self.assertEqual(str(pya.ICplxTrans(pya.Vector(100, 200))), "r0 *1 100,200") self.assertEqual(str(pya.ICplxTrans(100, 200)), "r0 *1 100,200") self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans(100, 200))), "r0 *1 100,200") self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5)), "r0 *1.5 150,300") self.assertEqual( str( pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5, pya.Vector(10, 20))), "r0 *1.5 160,320") self.assertEqual( str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5, 10, 20)), "r0 *1.5 160,320") self.assertEqual(str(pya.DCplxTrans()), "r0 *1 0,0") self.assertEqual(str(pya.DCplxTrans(1.5)), "r0 *1.5 0,0") self.assertEqual( str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02), 1.5)), "r90 *1.5 0.01,0.02") self.assertEqual(str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02))), "r90 *1 0.01,0.02") self.assertEqual( str(pya.DCplxTrans(1.5, 80, True, pya.DVector(0.1, 0.2))), "m40 *1.5 0.1,0.2") self.assertEqual(str(pya.DCplxTrans(1.5, 80, True, 0.1, 0.2)), "m40 *1.5 0.1,0.2") self.assertEqual(str(pya.DCplxTrans(pya.DVector(0.1, 0.2))), "r0 *1 0.1,0.2") self.assertEqual(str(pya.DCplxTrans(0.1, 0.2)), "r0 *1 0.1,0.2") self.assertEqual(str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2))), "r0 *1 0.1,0.2") self.assertEqual(str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5)), "r0 *1.5 0.15,0.3") self.assertEqual( str( pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5, pya.DVector(0.01, 0.02))), "r0 *1.5 0.16,0.32") self.assertEqual( str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5, 0.01, 0.02)), "r0 *1.5 0.16,0.32")
worm = EMResonator_TL2Qbit_worm(Z_res, point, L_coupling[i], L1[i], r, L2, N) worm.place(cell, layer_photo) resonators.append(worm) dy_qbit = (worm.cop_tail.dr.abs() - square_a) / 2 qbit_params = [ a[i], b[i], jos1_b, jos1_a, f1, d1, jos2_b, jos2_a, f2, d2, w, dCap, gap, square_a, dSquares, alum_over, B1_width ] dy_qbit = (worm.cop_tail.dr.abs() - square_a) / 2 qbit_start = worm.end + DPoint(B1_width / 2, 0) qbit = QBit_Flux_Сshunted_3JJ( worm.end + DPoint(qbit_coupling_gap + Z_res.width / 2, dy_qbit), qbit_params, DCplxTrans(1, 90, False, 0, 0)) qbit_bbox = pya.DBox().from_ibox(qbit.metal_regions["photo"].bbox()) p1 = qbit.origin + DPoint(-qbit_coupling_gap, qbit.square_a / 2) p2 = p1 + DPoint(qbit_bbox.width() + qbit_coupling_gap + qbit_gnd_gap, 0) empty = CPW(0, (square_a + 2 * qbit_gnd_gap) / 2, p1, p2) empty.place(cell, layer_photo) empties.append(empty) qbit.place(cell, layer_photo, layer_el) qbits.append(qbit) # place top array of resonators with qBits N_top = N_bottom - 1 delta = 1e6 step_top = step_bot resonators = []
def init_regions(self): self.metal_regions["bridges_1"] = Region( ) # region with ground contacts self.empty_regions["bridges_1"] = Region() # remains empty self.metal_regions["bridges_2"] = Region() # remains empty self.empty_regions["bridges_2"] = Region( ) # region with erased bridge area center = DPoint(0, 0) self.connections = [center] self.angle_connections = [0] # init metal region of ground touching layer top_gnd_center = center + DPoint( 0, self.gnd2gnd_dy / 2 + self.gnd_touch_dy / 2) p1 = top_gnd_center + DPoint(-self.gnd_touch_dx / 2, -self.gnd_touch_dy / 2) p2 = p1 + DVector(self.gnd_touch_dx, self.gnd_touch_dy) top_gnd_touch_box = pya.DBox(p1, p2) self.metal_regions["bridges_1"].insert( pya.Box().from_dbox(top_gnd_touch_box)) bot_gnd_center = center + DPoint( 0, -(self.gnd2gnd_dy / 2 + self.gnd_touch_dy / 2)) p1 = bot_gnd_center + DPoint(-self.gnd_touch_dx / 2, -self.gnd_touch_dy / 2) p2 = p1 + DVector(self.gnd_touch_dx, self.gnd_touch_dy) bot_gnd_touch_box = pya.DBox(p1, p2) self.metal_regions["bridges_1"].insert( pya.Box().from_dbox(bot_gnd_touch_box)) # init empty region for second layout layer # points start from left-bottom corner and goes in clockwise direction p1 = bot_gnd_touch_box.p1 + DPoint(-self.surround_gap, -self.surround_gap) p2 = p1 + DPoint( 0, self.surround_gap + self.gnd_touch_dy + self.transition_len - self.surround_gap) # top left corner + `surrounding_gap` + `transition_length` p3 = bot_gnd_touch_box.p1 + DPoint(0, bot_gnd_touch_box.height()) + \ DPoint(0, self.transition_len) bl_pts_list = [p1, p2, p3] # bl stands for bottom-left ''' exploiting symmetry of reflection at x and y axes. ''' # reflecting at x-axis tl_pts_list = list(map(lambda x: DTrans.M0 * x, bl_pts_list)) # tl stands for top-left # preserving order tl_pts_list = reversed( list(tl_pts_list)) # preserving clockwise points order # converting iterator to list l_pts_list = list(itertools.chain(bl_pts_list, tl_pts_list)) # l stands for left # reflecting all points at y-axis r_pts_list = list(map(lambda x: DTrans.M90 * x, l_pts_list)) r_pts_list = list( reversed(r_pts_list)) # preserving clockwise points order # gathering points pts_list = l_pts_list + r_pts_list # concatenating proper ordered lists empty_polygon = DSimplePolygon(pts_list) self.empty_regions["bridges_2"].insert( SimplePolygon.from_dpoly(empty_polygon))