def produce_impl(self): squares = [2, 5, 10, 20] width = self.w * 1000 length = max(squares) * self.w * 1000 fox_bloat = 40000 ito_bloat = 10000 pad = pya.Box(pya.Point(0, 0), pya.Point(80000, 80000)) self.cell.shapes(self.nno_layer).insert(pad) pads = [pad] for s in squares: length = s * self.w * 1000 newpad = pad.moved(length + 80000, 0) pads.append(newpad) fox_extent_box = pya.Box(0, 0, 160000 + max(squares) * self.w * 1000, 80000).enlarge(pya.Point( fox_bloat, fox_bloat)) fox_box = pya.Polygon(fox_extent_box) fox_box_cutout = pya.Region( pya.Box(pya.Point(80000, 40000 - width / 2), pya.Point(80000 + length, 40000 + width / 2))) for p in pads: fox_box_cutout.insert(p) self.cell.shapes(self.nno_layer).insert(p) fox_box = pya.Region(fox_box) - fox_box_cutout self.cell.shapes(self.fox_layer).insert(fox_box) ito_extent_box = fox_extent_box.dup() ito_extent_box.enlarge(pya.Point(ito_bloat, ito_bloat)) ito_iso = pya.Polygon(ito_extent_box) ito_iso.insert_hole(fox_extent_box) self.cell.shapes(self.ito_layer).insert(ito_iso) self.cell.shapes(self.hfoetch_layer).insert(ito_extent_box)
def check_inclusion( gdspath: ComponentOrPath, layer_in: Tuple[int, int] = (1, 0), layer_out: Tuple[int, int] = (2, 0), min_inclusion: float = 0.150, dbu: float = 1e3, ignore_angle_deg: int = 80, whole_edges: bool = False, metrics: str = "Square", min_projection: None = None, max_projection: None = None, ) -> int: """reads layer from top cell and returns a the area that violates min inclusion if 0 no area violates exclusion Args: gdspath: path to GDS layer_in: tuple layer_out: tuple min_inclusion: in um dbu: database units (1000 um/nm) ignore_angle_deg: The angle above which no check is performed whole_edges: If true, deliver the whole edges metrics: Specify the metrics type min_projection: lower threshold of the projected length of one edge onto another max_projection: upper limit of the projected length of one edge onto another """ import klayout.db as pya from gdsfactory.component import Component if isinstance(gdspath, Component): gdspath.flatten() gdspath = gdspath.write_gds() layout = pya.Layout() layout.read(str(gdspath)) cell = layout.top_cell() a = pya.Region( cell.begin_shapes_rec(layout.layer(layer_in[0], layer_in[1]))) b = pya.Region( cell.begin_shapes_rec(layout.layer(layer_out[0], layer_out[1]))) valid_metrics = ["Square", "Euclidian"] if metrics not in valid_metrics: raise ValueError("metrics = {metrics!r} not in {valid_metrics}") metrics = getattr(pya.Region, metrics) d = b.inside_check( a, min_inclusion * dbu, whole_edges, metrics, ignore_angle_deg, min_projection, max_projection, ) return d.polygons().area()
def check_inclusion( gdspath, layer_in=(1, 0), layer_out=(2, 0), min_inclusion=0.150, dbu=1e3, ignore_angle_deg=80, whole_edges=False, metrics=None, min_projection=None, max_projection=None, ): """reads layer from top cell and returns a the area that violates min inclusion if 0 no area violates exclusion Args: gdspath: path to GDS layer_in: tuple layer_out: tuple min_inclusion: in um dbu: database units (1000 um/nm) ignore_angle_deg: The angle above which no check is performed other: The other region against which to check whole_edges: If true, deliver the whole edges metrics: Specify the metrics type min_projection The lower threshold of the projected length of one edge onto another max_projection The upper limit of the projected length of one edge onto another """ from pp.component import Component from pp.write_component import write_gds if isinstance(gdspath, Component): gdspath.flatten() gdspath = write_gds(gdspath) layout = pya.Layout() layout.read(str(gdspath)) cell = layout.top_cell() a = pya.Region( cell.begin_shapes_rec(layout.layer(layer_in[0], layer_in[1]))) b = pya.Region( cell.begin_shapes_rec(layout.layer(layer_out[0], layer_out[1]))) d = b.inside_check( a, min_inclusion * dbu, whole_edges, metrics, ignore_angle_deg, min_projection, max_projection, ) return d.polygons().area()
def check_width(gdspath, layer: Tuple[int, int] = (1, 0), min_width: float = 0.150, dbu: float = 1e3): """Reads layer from top cell and returns a number of edges violating min width Args: gdspath: path to GDS or Component layer: tuple (int, int) min_width: in um dbu: database units (1000 um/nm) """ from pp.component import Component from pp.write_component import write_gds if isinstance(gdspath, Component): gdspath.flatten() gdspath = write_gds(gdspath) layout = pya.Layout() layout.read(str(gdspath)) cell = layout.top_cell() region = pya.Region(cell.begin_shapes_rec(layout.layer(layer[0], layer[1]))) # print(region) # print(min_width*1e3) return len(region.width_check(min_width * dbu))
def demo(): a = pya.Region() a.insert(pya.Box(0, 0, 100, 1000)) b = pya.Region() b.insert(pya.Box(200, 0, 300, 1000)) c = pya.Region() c.insert(pya.Box(0, 0, 500, 500)) print("c", c.width_check(200)) # width check (w < 200 DBU) # simple version -> more options available for the complex variant of this method too_small = a.width_check(200) # space check (here: separation between a and b, s < 200 DBU) too_close = a.separation_check(b, 200) # NOTE: "too_small" and "too_close" are pya.EdgePairs collections of error markers print("too_small is: ", too_small) print("too_close is: ", too_close)
layout = pya.Layout() layout.dbu = 0.001 TOP = layout.create_cell("TOP") workingLayer = layout.layer(4, 0) chipBorder = layout.layer(7, 0) #computational layer maskBorder = layout.layer(10, 0) #nbtin layer outputLayer = layout.layer(1, 0) sourceLayer = layout.layer(3, 0) port1Layer = layout.layer(2, 0) port2Layer = layout.layer(5, 0) ex = pya.DVector(1, 0) ey = pya.DVector(0, 1) upperRegion = pya.Region() lowerRegion = pya.Region() feedlineRegion = pya.Region() lowZRegion = pya.Region() highZRegion = pya.Region() #insert chip/mask border chipWidth = 11000 chipLength = 19000 #layout_box(TOP, chipBorder, -chipWidth*ex-50000*ey, chipWidth*ex + 50000*ey, ex) maskWidth = 11600 maskHeight = 19600 #layout_box(TOP, maskBorder, -chipWidth/2*ex -300*ex - maskHeight/2*ey, chipWidth/2*ex+(300)*ex + maskHeight/2*ey, ex) upperWGBondPadHeight = 450
def check_space( gdspath: ComponentOrPath, layer: Tuple[int, int] = (1, 0), min_space: float = 0.150, dbu: float = 1e3, ignore_angle_deg: int = 80, whole_edges: bool = False, metrics: str = "Square", min_projection: None = None, max_projection: None = None, ) -> int: """Reads layer from top cell and returns a the area that violates min space. If "whole_edges" is true, the resulting EdgePairs collection will receive the whole edges which contribute in the space check. "metrics" can be one of the constants Euclidian, Square or Projection. See there for a description of these constants. Use nil for this value to select the default (Euclidian metrics). "ignore_angle" specifies the angle limit of two edges. If two edges form an angle equal or above the given value, they will not contribute in the check. Setting this value to 90 (the default) will exclude edges with an angle of 90 degree or more from the check. Use nil for this value to select the default. "min_projection" and "max_projection" allow selecting edges by their projected value upon each other. It is sufficient if the projection of on e edge on the other matches the specified condition. The projected length must be larger or equal to "min_projection" and less than "max_proje ction". If you don't want to specify one limit, pass nil to the respective value. Args: gdspath: path to GDS or Component layer: tuple min_space: in um dbu: database units (1000 um/nm) ignore_angle_deg: The angle above which no check is performed other: The other region against which to check whole_edges: If true, deliver the whole edges metrics: Specify the metrics type 'Euclidian, square' min_projection The lower threshold of the projected length of one edge onto another max_projection The upper limit of the projected length of one edge onto another """ if isinstance(gdspath, Component): gdspath.flatten() gdspath = gdspath.write_gds() layout = pya.Layout() layout.read(str(gdspath)) cell = layout.top_cell() region = pya.Region(cell.begin_shapes_rec(layout.layer(layer[0], layer[1]))) valid_metrics = ["Square", "Euclidian"] if metrics not in valid_metrics: raise ValueError("metrics = {metrics} not in {valid_metrics}") metrics = getattr(pya.Region, metrics) d = region.space_check( min_space * dbu, whole_edges, metrics, ignore_angle_deg, min_projection, max_projection, ) # print(d.polygons().area()) return d.polygons().area()
ignore_angle_deg, min_projection, max_projection, ) # print(d.polygons().area()) return d.polygons().area() if __name__ == "__main__": import gdsfactory as gf space = 0.12 min_space = 0.1 dbu = 1000 layer = gf.LAYER.WG gdspath = gf.components.straight_array(spacing=space) gf.show(gdspath) if isinstance(gdspath, Component): gdspath.flatten() gdspath = gdspath.write_gds() layout = pya.Layout() layout.read(str(gdspath)) cell = layout.top_cell() region = pya.Region(cell.begin_shapes_rec(layout.layer(layer[0], layer[1]))) print(region.corners().area()) metrics = "Square" metrics = getattr(pya.Region, metrics) d = region.space_check(min_space * dbu, False, metrics, 80, None, None)