def layout_donut(cell, layer, center, r1, r2): """ Layout donut shape. cell: layout cell to place the layout layer: which layer to use center: origin DPoint (not affected by ex) r1: internal radius r2: external radius """ assert r2 > r1 arc_function = lambda t: np.array( [center.x + r2 * np.cos(t), center.y + r2 * np.sin(t)]) t, coords = sample_function(arc_function, [0, 2 * np.pi - 0.001], tol=0.002 / r2) external_points = [pya.DPoint(x, y) for x, y in zip(*coords)] arc_function = lambda t: np.array( [center.x + r1 * np.cos(-t), center.y + r1 * np.sin(-t)]) t, coords = sample_function(arc_function, [0, 2 * np.pi - 0.001], tol=0.002 / r1) internal_points = [pya.DPoint(x, y) for x, y in zip(*coords)] dpoly = pya.DPolygon(external_points) dpoly.insert_hole(internal_points) insert_shape(cell, layer, dpoly) return dpoly
def layout_circle(cell, layer, center, r, ex=None, x_bounds=(-np.inf, np.inf), y_bounds=(-np.inf, np.inf)): """ function to produce the layout of a filled circle cell: layout cell to place the layout layer: which layer to use center: origin DPoint r: radius x_bounds and y_bounds relative to the center, before rotation by ex. units in microns optimal sampling """ arc_function = lambda t: np.array([r * np.cos(t), r * np.sin(t)]) t, coords = sample_function(arc_function, [0, 2 * np.pi - 0.001], tol=0.002 / r) # dbu = cell.layout().dbu dpolygon = pya.DSimplePolygon([pya.DPoint(x, y) for x, y in zip(*coords)]) # clip dpolygon to bounds dpolygon.clip(x_bounds=x_bounds, y_bounds=y_bounds) # Transform points (translation + rotation) dpolygon.transform_and_rotate(center, ex) dpolygon.compress(True) insert_shape(cell, layer, dpolygon) return dpolygon
def layout_section( cell, layer, center, r2, theta_start, theta_end, ex=None, x_bounds=(-np.inf, np.inf), y_bounds=(-np.inf, np.inf), ): """ Layout section of a circle. cell: layout cell to place the layout layer: which layer to use center: origin DPoint (not affected by ex) r2: radius theta_start, theta_end: angle in radians x_bounds and y_bounds relative to the center, before rotation by ex. units in microns returns a dpolygon """ assert r2 > 0 # optimal sampling arc_function = lambda t: np.array([r2 * np.cos(t), r2 * np.sin(t)]) t, coords = sample_function(arc_function, [theta_start, theta_end], tol=0.002 / r2) # # This yields a better polygon if theta_end < theta_start: theta_start, theta_end = theta_end, theta_start coords = np.insert(coords, 0, arc_function(theta_start - 0.001), axis=1) # start the waveguide a little bit before coords = np.append(coords, np.atleast_2d(arc_function(theta_end + 0.001)).T, axis=1) # finish the waveguide a little bit after # create original waveguide poligon prior to clipping and rotation dpoints_list = [pya.DPoint(x, y) for x, y in zip(*coords)] dpolygon = pya.DSimplePolygon(dpoints_list + [pya.DPoint(0, 0)]) # clip dpolygon to bounds dpolygon.clip(x_bounds=x_bounds, y_bounds=y_bounds) # Transform points (translation + rotation) dpolygon.transform_and_rotate(center, ex) dpolygon.compress(True) dpolygon.layout(cell, layer) return dpolygon
def layout_ring(cell, layer, center, r, w): """ function to produce the layout of a ring cell: layout cell to place the layout layer: which layer to use center: origin DPoint r: radius w: waveguide width units in microns """ # outer arc # optimal sampling assert r - w / 2 > 0 radius = r + w / 2 arc_function = lambda t: np.array([radius * np.cos(t), radius * np.sin(t)]) t, coords = sample_function(arc_function, [0, 2 * pi], tol=0.002 / radius) # create original waveguide poligon prior to clipping and rotation points_hull = [center + pya.DPoint(x, y) for x, y in zip(*coords)] del points_hull[-1] radius = r - w / 2 arc_function = lambda t: np.array([radius * np.cos(t), radius * np.sin(t)]) t, coords = sample_function(arc_function, [0, 2 * pi], tol=0.002 / radius) # create original waveguide poligon prior to clipping and rotation points_hole = [center + pya.DPoint(x, y) for x, y in zip(*coords)] del points_hole[-1] dpoly = pya.DPolygon(list(reversed(points_hull))) dpoly.insert_hole(points_hole) dpoly.compress(True) insert_shape(cell, layer, dpoly) return dpoly
def layout_circle(cell, layer, center, r): """ function to produce the layout of a filled circle cell: layout cell to place the layout layer: which layer to use center: origin DPoint r: radius w: waveguide width theta_start, theta_end: angle in radians units in microns optimal sampling """ arc_function = lambda t: np.array( [center.x + r * np.cos(t), center.y + r * np.sin(t)]) t, coords = sample_function(arc_function, [0, 2 * np.pi - 0.001], tol=0.002 / r) # dbu = cell.layout().dbu dpoly = pya.DSimplePolygon([pya.DPoint(x, y) for x, y in zip(*coords)]) # cell.shapes(layer).insert(dpoly.to_itype(dbu)) insert_shape(cell, layer, dpoly) return dpoly
def layout_arc( cell, layer, center, r, w, theta_start, theta_end, ex=None, x_bounds=(-np.inf, np.inf), y_bounds=(-np.inf, np.inf), ): """ function to produce the layout of an arc cell: layout cell to place the layout layer: which layer to use center: origin DPoint (not affected by ex) r: radius w: waveguide width theta_start, theta_end: angle in radians x_bounds and y_bounds relative to the center, before rotation by ex. units in microns returns a dpolygon """ # fetch the database parameters if r <= 0: raise RuntimeError(f"Please give me a positive radius. Bad r={r}") # optimal sampling if theta_end < theta_start: theta_start, theta_end = theta_end, theta_start arc_function = lambda t: np.array([r * np.cos(t), r * np.sin(t)]) t, coords = sample_function(arc_function, [theta_start, theta_end], tol=0.002 / r) dt = 0.0001 # # This yields a better polygon insert_at = np.argmax(theta_start + dt < t) t = np.insert(t, insert_at, theta_start + dt) coords = np.insert( coords, insert_at, arc_function(theta_start + dt), axis=1) # start the second point a little bit after the first insert_at = np.argmax(theta_end - dt < t) t = np.insert(t, insert_at, theta_end - dt) coords = np.insert( coords, insert_at, arc_function(theta_end - dt), axis=1) # start the second to last point a little bit before the final # create original waveguide poligon prior to clipping and rotation dpoints_list = [pya.DPoint(x, y) for x, y in zip(*coords)] from zeropdk.layout import waveguide_dpolygon dpolygon = waveguide_dpolygon(dpoints_list, w, cell.layout().dbu) # clip dpolygon to bounds dpolygon.clip(x_bounds=x_bounds, y_bounds=y_bounds) # Transform points (translation + rotation) dpolygon.transform_and_rotate(center, ex) dpolygon.compress(True) dpolygon.layout(cell, layer) return dpolygon