# DRC Reference: Layer Object

## "&" - Boolean AND operation

Usage:

- self & other

The method computes a boolean AND between self and other.

This method is available for polygon and edge layers. An alias is "and". See there for a description of the function.

## "+" - Join layers

Usage:

- self + other

The method includes the edges or polygons from the other layer into this layer. The "+" operator is an alias for the join method.

This method is available for polygon, edge and edge pair layers. An alias is "join". See there for a description of the function.

## "-" - Boolean NOT operation

Usage:

- self - other

The method computes a boolean NOT between self and other.

This method is available for polygon and edge layers. An alias is "not". See there for a description of the function.

## "^" - Boolean XOR operation

Usage:

- self ^ other

The method computes a boolean XOR between self and other.

This method is available for polygon and edge layers. An alias is "xor". See there for a description of the function.

## "and" - Boolean AND operation

Usage:

- layer.and(other)

The method computes a boolean AND between self and other. It is an alias for the "&" operator.

This method is available for polygon and edge layers. If the first operand is an edge layer and the second is a polygon layer, the result will be the edges of the first operand which are inside or on the borders of the polygons of the second operand.

The following images show the effect of the "and" method on polygons and edges (input1: red, input2: blue):

The AND operation can be applied between a text and a polygon layer. In this case, the texts inside or at the border of the polygons will be written to the output (labels: red, input2: blue):

## "andnot" - Computes Boolean AND and NOT results at the same time

Usage:

- layer.andnot(other)

This method returns a two-element array containing one layer for the AND result and one for the NOT result.

This method is available for polygon layers.

It can be used to initialize two variables with the AND and NOT results:

    (and_result, not_result) = l1.andnot(l2)

As the AND and NOT results are computed in the same sweep, calling this method is faster than calling AND and NOT separately.

## "area" - Returns the total area of the polygons in the region

Usage:

- layer.area

This method requires a polygon layer. It returns the total area of all polygons in square micron. Merged semantics applies, i.e. before computing the area, the polygons are merged unless raw mode is chosen (see raw). Hence, in clean mode, overlapping polygons are not counted twice.

The returned value gives the area in square micrometer units.

## "bbox" - Returns the overall bounding box of the layer

Usage:

- layer.bbox

The return value is a DBox object giving the bounding box in micrometer units.

## "centers" - Returns the center parts of the edges

Usage:

- layer.centers(length)
- layer.centers(length, fraction)

Similar to start_segments and end_segments, this method will return partial edges for each given edge in the input. For the description of the parameters see start_segments or end_segments.

The following images show the effect of the method:

## "clean" - Marks a layer as clean

Usage:

- layer.clean

A layer marked as clean will provide "merged" semantics, i.e. overlapping or touching polygons are considered as single polygons. Inner edges are removed and collinear edges are connected. Clean state is the default.

See raw for some remarks about how this state is propagated.

## "collect" - Transforms a layer

Usage:

- layer.collect { |object| ... }

This method evaluates the block for each object in the layer and returns a new layer with the objects returned from the block. It is available for edge, polygon and edge pair layers. The corresponding objects are DPolygon, DEdge or DEdgePair.

If the block evaluates to nil, no object is added to the output layer. If it returns an array, each of the objects in the array is added. The returned layer is of the original type and will only accept objects of the respective type. Hence, for polygon layers, DPolygon objects need to be returned. For edge layers those need to be DEdge and for edge pair layers, they need to be DEdgePair objects. For convenience, Polygon, Edge and EdgePair objects are accepted too and are scaled by the database unit to render micrometer-unit objects. Region, Edges and EdgePair objects are accepted as well and the corresponding content of that collections is inserted into the output layer.

Other versions are available that allow translation of objects into other types (collect_to_polygons, collect_to_edges and collect_to_edge_pairs).

Because this method executes inside the interpreter, it's inherently slow. Tiling does not apply to this method.

Here is a slow equivalent of the rotated method

    # Rotates by 45 degree
    t = DCplxTrans(1.0, 45.0, false, DVector::new)
    new_layer = layer.collect { |polygon| polygon.transformed(t) }

## "collect_to_edge_pairs" - Transforms a layer into edge pair objects

Usage:

- layer.collect { |object| ... }

This method is similar to collect, but creates an edge pair layer. It expects the block to deliver EdgePair, DEdgePair or EdgePairs objects.

## "collect_to_edges" - Transforms a layer into edge objects

Usage:

- layer.collect { |object| ... }

This method is similar to collect, but creates an edge layer. It expects the block to deliver objects that can be converted into edges. If polygon-like objects are returned, their contours will be turned into edge sequences.

## "collect_to_region" - Transforms a layer into polygon objects

Usage:

- layer.collect { |object| ... }

This method is similar to collect, but creates a polygon layer. It expects the block to deliver objects that can be converted into polygons. Such objects are of class DPolygon, DBox, DPath, Polygon, Path, Box and Region.

## "corners" - Selects corners of polygons

Usage:

- layer.corners([ options ])
- layer.corners(angle [, options ])
- layer.corners(amin .. amax [, options ])

This method produces markers on the corners of the polygons. An angle criterion can be given which selects corners based on the angle of the connecting edges. Positive angles indicate a left turn while negative angles indicate a right turn. Since polygons are oriented clockwise, positive angles indicate concave corners while negative ones indicate convex corners.

The markers generated can be point-like edges or small 2x2 DBU boxes. The latter is the default.

The options available are:

- as_boxes : with this option, small boxes will be produced as markers
- as_dots : with this option, point-like edges will be produced instead of small boxes

The following images show the effect of this method:

## "covering" - Selects shapes or regions of self which completely cover (enclose) one or more shapes from the other region

Usage:

- layer.covering(other)
- layer.covering(other, min_count)
- layer.covering(other, min_count, max_count)
- layer.covering(other, min_count .. max_count)

This method selects all shapes or regions from self which completly cover shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_covering.

This method is available for polygons only.

The following image shows the effect of the "covering" method:

A range of counts can be specified. If so, the shape from the primary layer is only selected when covering a given number of shapes from the other layer. For the interpretation of the count see interacting.

The "covering" attribute is sometimes called "enclosing", but this name is used for the respective DRC function (see enclosing).

## "data" - Gets the low-level data object

Usage:

- layer.data

This method returns a Region, Edges or EdgePairs object representing the underlying RBA object for the data. Access to these objects is provided to support low-level iteration and manipulation of the layer's data.

## "drc" - Provides a generic DRC function for use with DRC expressions

Usage:

- layer.drc(expression)

This method implements the universal DRC which offers enhanced abilities, improved performance in some applications and better readability.

The key concept for this method are DRC expressions. DRC expressions are formed by using predefined keywords like "width", operators like "&" and methods to build an abstract definition of the operations to perform within the DRC.

When the DRC function is executed, it will basically visit all shapes from the input layer (the layer, the "drc" method is called on)). While it does, it collects the neighbor shapes from all involved other inputs and runs the requested operations on each cluster. Currently, "drc" is only available for polygon layers.

This way, the nature of the "drc" operation is that of the loop over all (merged) input polygons. Within the operation executed on each shape, it's possible to make decisions such as "if the shape has an area larger than something, apply this operation" or similar. This often can be achieved with conventional DRC functions too, but involves potentially complex and heavy operations such as booleans, interact etc. For this reason, the "drc" function may provide a better performance.

In addition, within the loop a single shape from the input layer is presented to the execution engine which runs the operations. This allows using operations such as "size" without having to consider neighbor polygons growing into the area of the initial shape. In this sense, the "drc" function sees the layer as individual polygons rather than a global "sea of polygons". This enables new applications which are otherwise difficult to implement.

### Primaries and secondaries

An important concept in "drc" expressions is the "primary". The primary represents a single shape from the input layer. "Secondaries" are shapes from other inputs. Primaries guide the operation - secondaries without primaries are not seen. The "drc" operation will look for secondaries within a certain distance which is determined from the operations from the expression to execute. The secondaries collected in this step will not be merged, so the secondary polygons may be partial. This is important when using measurement operations like "area" on secondary polygons.

### Checks

Here is an example for a generic DRC operation which performs a width check for less than 0.5.um on the primary shapes. It uses the "width" operator:

    out = in.drc(width < 0.5.um)

Other single or double-bounded conditions are available too, for example:

    out = in.drc(width <= 0.5.um)
    out = in.drc(width > 0.5.um)
    out = in.drc(width == 0.5.um)
    out = in.drc(width != 0.5.um)
    out = in.drc(0.2.um < width < 0.5.um)

To specify the second input for a two-layer check, add it to the check function. This example shows how to use a two-layer separation check ("separation"):

    l1 = input(1, 0)
    l2 = input(2, 0)
    out = l1.drc(separation(l2) < 0.5.um)

The second input of this check function can be a computed expression. In this case the local loop will first evaluate the expression for the second input and then use the result as second input in the check. Note that this computation is performed locally and separately for each primary and its context.

Options for the checks are also specified inside the brackets. For example, to select projection metrics ("projection") for the "width" check use:

    out = in.drc(width(projection) < 0.5.um)

### Edges and edge pairs

Although the "drc" function operates on polygon layers, internally it is able to handle edge and edge pair types too. Some operations generate edge pairs, some other generate edges. As results from one operation can be processed further in the DRC expressions, methods are available to filter, process and convert these types.

For example, all checks produce edge pairs which can be converted into polygons using the "polygons" method:

    out = in.drc((width(projection) < 0.5.um).polygons)

Note a subtle detail: when putting the "polygons" method inside the "drc" brackets, it is executed locally on every visited primary polygon. The result in this case is identical to the global conversion:

    # same, but with "global" conversion:
    out = in.drc(width(projection) < 0.5.um).polygons

But having the check polygons inside the loop opens new opportunities and is more efficient in general. In the previous example, the local conversion will keep a few edge pairs after having converted them to polygons. In the global case, all edge pairs are collected first and then converted. If there are many edge pairs, this requires more memory and a larger computing overhead for managing the bigger number of shapes.

For the conversion of edges, edge pairs and polygons into other types, these methods are provided:

- "DRC#polygons": converts edge pairs to polygons
- "DRC#extended", "DRC#extended_in", "DRC#extended_out": converts edges to polygons
- "DRC#first_edges", DRC#second_edges": extracts edges from edge pairs
- "DRC#edges": decomposes edge pairs and polygons into edges
- "DRC#corners": can extract corners from polygons

The following example decomposes the primary polygons into edges:

    out = in.drc(primary.edges)

(for backward compatibility you cannot abbreviate "primary.edges" simply as "edges" like other functions).

The previous example isn't quite exciting as it is equivalent to

    # Same as above
    out = in.edges

But it gets more interesting, as within the loop, "edges" delivers the edge set for each individual polygon. It's possible to work with this distinct set, so for example this will give you the edges of polygons with more than four corners:

    out = in.drc(primary.edges.count > 4)

Explanation: "count" is a "quantifier" which takes any kind of set (edges, edge pairs, polygons) and returns the set if the number of inhabitants meets the given condition. Otherwise the set is skipped. So it will look at the edges and if there are more than four (per primary shape), it will forward this set.

The same result can be achieved with classic DRC with "interact" and a figure count, but at a much higher computation cost.

### Edge and edge/polygon operations

The "drc" framework supports the following edge and edge/polygon operations:

- Edge vs. edge and edge vs. polygon booleans
- Edge vs. polygon interactions ("DRC#interacting", "DRC#overlapping")
- Edge sampling ("DRC#start_segments", "DRC#centers", "DRC#end_segments")

### Filters

Filter operators select input polygons or edges based on their properties. These filters are provided:

- "DRC#area": selects polygons based on their area
- "DRC#perimeter": selects polygons based on their perimeter
- "DRC#area_ratio": selects polygons based on their bounding box to polygon area ratio
- "DRC#bbox_aspect_ratio": selects polygons based on their bounding box aspect ratio
- "DRC#relative_height": selects polygons based on their relative height
- "DRC#bbox_min", "bbox_max", "bbox_width", "bbox_height": selects polygons based on their bounding box properties
- "DRC#length": selects edges based on their length
- "DRC#angle": selects edges based on their orientation

For example, to select polygons with an area larger than one square micrometer, use:

    out = in.drc(area > 1.0)

For the condition, use the usual numerical bounds like:

    out = in.drc(area == 1.0)
    out = in.drc(area <= 1.0)
    out = in.drc(0.2 < area < 1.0)

The result of the area operation is the input polygon if the area condition is met.

In the same fashion, "perimeter" applies to the perimeter of the polygon. "bbox_min" etc. will evaluate a particular dimensions of the polygon's bounding box and use the respective dimension for filtering the polygon.

Note that it's basically possible to use the polygon filters on any input - computed and secondaries. In fact, plain "area" for example is a shortcut for "primary.area" indicating that the area of primary shapes are supposed to be computed. However, any input other than the primary is not necessarily complete or it may consist of multiple polygons. Hence the computed values may be too big or too small. It's recommended therefore to use the measurement functions on primary polygons unless you know what you're doing.

### Filter predicates

The "drc" feature also supports some predicates. "predicates" are boolean values indicating a certain condition. A predicate filter works in a way that it only passes the polygons if the condition is met.

The predicates available currently are:

- "rectangles": Filters rectangles
- "squares": Filters squares
- "rectilinear": Filters rectilinear ("Manhattan") polygons

For the same reason as explained above, it's recommended to use these predicates standalone, so they act on primary shapes. It's possible to use the predicates on computed shapes or secondaries, but that may not render the desired results.

### Logical NOT operator

The "!" operator will evaluate the expression behind it and return the current primary shape if the input is empty and return an empty polygon set if not. Hence the following filter will deliver all polygons which are not rectangles:

    out = in.drc(! rectangles)

### Logical combination operators

The logical "if_any" or "if_all" functions allow connecting multiple conditions and evaluate to "true" (means: a non-empty shape set) if either one input is a non-empty shape set ("if_any") or if all inputs are non-empty ("if_all").

For example, this will select all polygons which are rectangles and whose area is larger than 20 square micrometers:

    out = in.drc(if_all(rectangles, area > 20.0))

"if_all" delivers the primary shape if all of the input expressions render a non-empty result.

In contrast to this, the "if_any" operation will deliver the primary shape if one of the input expressions renders a non-empty result.

The "switch" function allows selecting one input based on the results of an expression. In the two-input form it's equivalent to "if". The first expression is the condition. If it evaluates to a non-empty shape set, the result of the second expression is taken. Otherwise, the result is empty.

Hence the following code delivers all rectangles sized by 100 nm. All other shapes are skipped:

    out = in.drc(switch(rectangles, primary.sized(100.nm)))

A third expression will be considered the "else" branch: the result of this expression will be taken if the first one is not taken. So this example will size all rectangles and leave other shapes untouched:

    out = in.drc(switch(rectangles, primary.sized(100.nm), primary))

If more expressions are given, they are considered as a sequence of condition/result chain (c1, e1, c2, e2, ...) in the sense of "if(c1) return(e1) else if(c2) return(e2) ...". So the e1 is taken if c1 is met, e2 is taken when c1 is not met, but c2 is and so forth. If there is an odd number of expressions, the last one will be the default expression which is taken if none of the conditions is met.

### Polygon manipulations

The "drc" operations feature polygon manipulations where the input is either the primary, secondaries or derived shapes. Manipulations include sizing ("sized"), corner rounding ("rounded_corners"), smoothing ("smoothed") and boolean operations.

This example computes a boolean AND between two layers before selecting the result polygons with an area larger than 1 square micrometer. Note that "primary" is a placeholder for the primary shape:

    l1 = input(1, 0)
    l2 = input(2, 0)
    out = l1.drc((primary & l2).area > 1.0)

This example demonstrates how the "drc" operation can improve performance: as the boolean operation is computed locally and the result is discarded when no longer required, less shapes need to be stored hence reducing the memory overhead and CPU time required to manage these shapes.

Note that the precise form of the example above is

    out = l1.drc((primary & secondary(l2)).area > 1.0)

The "secondary" operator indicates that "l2" is to be used as secondary input to the "drc" function. Only in this form, the operators of the boolean AND can be reversed:

    out = l1.drc((secondary(l2) & primary).area > 1.0)

### Quantifiers

Some filters operate on properties of the full, local, per-primary shape set. While the loop is executed, the DRC expressions will collect shapes, either from the primary, it's neighborhood (secondaries) or from deriving shape sets.

Obviously the primary is a simple one: it consists of a single shape, because this is how the loop operates. Derived shape sets however can be more complex. "Quantifiers" allow assessing properties of the complete, per-primary shape set. A simple one is "DRC#count" which checks if the number of shapes within a shape set is within a given range.

Obviously, "primary.count == 1" is always true. So using "count" primaries isn't much fun. So it's better to use it on derived sets. The following condition will select all primary shapes which have more than 13 corners:

    out = in.drc(if_any(primary.corners.count > 13))

Note an important detail here: the "if_any" function will make this statement render primary polygons, if the expression inside gives a non-empty result. Without "if_any", the result would be the output of "count" which is the set of all corners where the corner count is larger than 13.

### Expressions as objects

The expression inside the "drc" function is a Ruby object and can be stored in variables. If you need the same expression multiple times, it can be more efficient to use the same Ruby object. In this example, the same expression is used two times. Hence it's computed two times:

    out = l1.drc(((primary & l2).area == 1.0) + ((primary & l2).area == 2.0))

A more efficient version is:

    overlap_area = (primary & l2).area
    out = l1.drc((overlap_area == 1.0) + (overlap_area == 2.0))

Note that the first line prepares the operation, but does not execute the area computation or the boolean operation. But when the "drc" function executes the loop over the primaries it will only compute the area once per primary as it is represented by the same Ruby object.

### Outlook

DRC expressions are quite rich and powerful. They provide a more intuitive way of writing DRC expressions, are more efficient and open new opportunities. DRC development is likely to focus on this scheme in the future.

More formal details about the bits and pieces can be found in the "DRC" class documentation.

## "dup" - Duplicates a layer

Usage:

- layer.dup

Duplicates the layer. This basically will create a copy and modifications of the original layer will not affect the duplicate. Please note that just assigning the layer to another variable will not create a copy but rather a pointer to the original layer. Hence modifications will then be visible on the original and derived layer. Using the dup method will avoid that.

However, dup will double the memory required to hold the data and performing the deep copy may be expensive in terms of CPU time.

## "each" - Iterates over the objects from the layer

Usage:

- layer.each { |object| ... }

This method evaluates the block on each object of the layer. Depending on the layer type, these objects are of DPolygon, DEdge or DEdgePair type.

Because this method executes inside the interpreter, it's inherently slow. Tiling does not apply to this method.

## "edge_pairs?" - Returns true, if the layer is an edge pair collection

Usage:

- layer.edge_pairs?

## "edges" - Decomposes the layer into single edges

Edge pair collections are decomposed into the individual edges that make up the edge pairs. Polygon layers are decomposed into the edges making up the polygons. This method returns an edge layer but will not modify the layer it is called on.

Merged semantics applies, i.e. the result reflects merged polygons rather than individual ones unless raw mode is chosen.

## "edges?" - Returns true, if the layer is an edge layer

Usage:

- layer.edges?

## "enc" - An alias for "enclosing"

Usage:

- layer.enc(value [, options])

See enclosing for a description of that method

## "enclosing" - An enclosing check

Usage:

- layer.enclosing(other_layer, value [, options])
- layer.enc(other_layer, value [, options])

Note: "enclosing" and "enc" are available as operators for the "universal DRC" function drc within the DRC framework. These variants have more options and are more intuitive to use. See enclosing for more details.

This method checks whether layer encloses (is bigger than) other_layer by the given dimension. Locations, where this is not the case will be reported in form of edge pair error markers. Locations, where both edges coincide will be reported as errors as well. Formally such locations form an enclosure with a distance of 0. Locations, where other_layer extends outside layer will not be reported as errors. Such regions can be detected by not_inside or a boolean "not" operation.

"enc" is the short form of this method.

The options are the same as for separation.

The enclosing method can be applied to both edge or polygon layers. On edge layers the orientation of the edges matters and only edges looking into the same direction are checked.

As for the other DRC methods, merged semantics applies. The options available are the same than for width. Distance values can be given as floating-point values (in micron) or integer values (in database units). To explicitly specify the unit, use the unit denominators.

The following images show the effect of two enclosing checks (red: input1, blue: input2):

## "end_segments" - Returns the part at the end of each edge

Usage:

- layer.end_segments(length)
- layer.end_segments(length, fraction)

This method will return a partial edge for each edge in the input, located and the end of the original edge. The new edges will share the end point with the original edges, but not necessarily their start point. This method applies to edge layers only. The direction of edges is defined by the clockwise orientation of a polygon: the end point of the edges will be the terminal point of each edge when walking a polygon in clockwise direction. Or in other words: when looking from start to the end point of an edge, the filled part of the polygon is to the right.

The length of the new edge can be given in two ways: as a fixed length, or a fraction, or both. In the latter case, the length of the resulting edge will be either the fraction or the fixed length, whichever is larger. To specify a length only, omit the fraction argument or leave it at 0. To specify a fraction only, pass 0 to the length argument and specify the fraction in the second parameter. A fraction of 0.5 will result in edges which cover the end half of the edge.

The following images show the effect of the method:

## "extended" - Returns polygons describing an area along the edges of the input

Usage:

- layer.extended([:begin => b,] [:end => e,] [:out => o,] [:in => i], [:joined => true])
- layer.extended(b, e, o, i)
- layer.extended(b, e, o, i, joined)

This method is available for edge layers only. It will create a polygon for each edge tracing the edge with certain offsets to the edge. "o" is the offset applied to the outer side of the edge, "i" is the offset applied to the inner side of the edge. "b" is the offset applied at the beginning and "e" is the offset applied at the end.

When looking from start to end point, the "inside" side is to the right, while the "outside" side is to the left.

"joined" is a flag, which, if present, will make connected edges behave as a continuous line. Start and end offsets are applied to the first and last unconnected point respectively. Please note that in order to specify joined mode, you'll need to specify "joined" as a keyword in the third form of the method.

The following images show the effects of some parameters:

## "extended_in" - Returns polygons describing an area along the edges of the input

Usage:

- layer.extended_in(d)

This method applies to edge layers only. Polygons are generated for each edge describing the edge drawn with a certain width extending into the "inside" (the right side when looking from start to end). This method is basically equivalent to the extended method: "extended(0, 0, 0, dist)". A version extending to the outside is extended_out.

## "extended_out" - Returns polygons describing an area along the edges of the input

Usage:

- layer.extended_out(d)

This method applies to edge layers only. Polygons are generated for each edge describing the edge drawn with a certain width extending into the "outside" (the left side when looking from start to end). This method is basically equivalent to the extended method: "extended(0, 0, dist, 0)". A version extending to the inside is extended_in.

## "extent_refs" - Returns partial references to the boundings boxes of the polygons

Usage:

- layer.extent_refs(fx, fy [, options ])
- layer.extent_refs(fx1, fy1, fx2, fx2 [, options ])
- layer.extent_refs(ref_spec [, options ])

This method produces parts of the bounding box of the polygons. It can select either edges, certain points or partial boxes. It can be used the following ways:

- With a formal specification : This is an identifier like ":center" or ":left" to indicate which part will be produced.
- With two floating-point arguments : These arguments specify a point relative to the bounding box. The first argument is a relative x coordinate where 0.0 means "left side of the bounding box" and 1.0 is the right side. The second argument is a relative y coordinate where 0.0 means "bottom" and 1.0 means "top". The results will be small (2x2 DBU) boxes or point-like edges for edge output
- With four floating-point arguments : These arguments specify a box in relative coordinates: a pair of x/y relative coordinate for the first point and another pair for the second point. The results will be boxes or a tilted edge in case of edge output. If the range specifies a finite-area box (height and width are not zero), no adjustment of the boxes will happen for polygon output - i.e. the additional enlargement by 1 DBU which is applied for zero-area boxes does not happen.

The formal specifiers are for points:

- :center or :c : the center point
- :bottom_center or :bc : the bottom center point
- :bottom_left or :bl : the bottom left point
- :bottom_right or :br : the bottom right point
- :left or :l : the left point
- :right or :r : the right point
- :top_center or :tc : the top center point
- :top_left or :tl : the top left point
- :top_right or :tr : the top right point

The formal specifiers for lines are:

- :bottom or :b : the bottom line
- :top or :t : the top line
- :left or :l : the left line
- :right or :r : the right line

Dots are represented by small (2x2 DBU) boxes or point-like edges with edge output. Lines are represented by narrow or flat (2 DBU) boxes or edges for edge output. Edges will follow the orientation convention for the corresponding edges - i.e. "inside" of the bounding box is on the right side of the edge.

The following additional option controls the output format:

- as_boxes : with this option, small boxes will be produced as markers
- as_dots or as_edges : with this option, point-like edges will be produced for dots and edges will be produced for line-like selections

The following table shows a few applications:

## "extents" - Returns the bounding box of each input object

Usage:

- layer.extents([ enlargement ])

Applies to edge layers, polygon layers on edge pair collections. Returns a polygon layer consisting of boxes for each input object. The boxes enclose the original object.

Merged semantics applies, so the box encloses the merged polygons or edges unless raw mode is chosen (see raw).

The enlargement parameter specifies an optional enlargement which will make zero width/zero height object render valid polygons (i.e. horizontal/vertical edges).

The following images show the effect of the extents method:

## "first_edges" - Returns the first edges of an edge pair collection

Usage:

- layer.first_edges

Applies to edge pair collections only. Returns the first edges of the edge pairs in the collection.

Some checks deliver symmetric edge pairs (e.g. space, width, etc.) for which the edges are commutable. "first_edges" will deliver both edges for such edge pairs.

## "flatten" - Flattens the layer

Usage:

- layer.flatten

If the layer already is a flat one, this method does nothing. If the layer is a hierarchical layer (an original layer or a derived layer in deep mode), this method will convert it to a flat collection of texts, polygons, edges or edge pairs.

## "forget" - Cleans up memory for this layer

Usage:

- forget

KLayout's DRC engine is imperative. This means, every command is executed immediately rather than being compiled and executed later. The advantage of this approach is that it allows decisions to be taken depending on the content of a layer and to code functions that operate directly on the layer's content.

However, one drawback is that the engine cannot decide when a layer is no longer required - it may still be used later in the script. So a layer's data is not cleaned up automatically.

In order to save memory for DRC scripts intended for bigger layouts, the DRC script should clean up layers as soon as they are no longer required. The "forget" method will free the memory used for the layer's information.

The recommended approach is:

    l = ... # compute some layer
    ...
    # once you're done with l:
    l.forget
    l = nil

By setting the layer to nil, it is ensured that it can no longer be accessed.

## "holes" - Selects all polygon holes from the input

Usage:

- layer.holes

This method is available for polygon layers. It will create polygons from all holes inside polygons of the input. Although it is possible, running this method on raw polygon layers will usually not render the expected result, since raw layers do not contain polygons with holes in most cases.

The following image shows the effects of the holes method:

## "hulls" - Selects all polygon hulls from the input

Usage:

- layer.hulls

This method is available for polygon layers. It will remove all holes from the input and render the hull polygons only. Although it is possible, running this method on raw polygon layers will usually not render the expected result, since raw layers do not contain polygons with holes in most cases.

The following image shows the effects of the hulls method:

## "in" - Selects shapes or regions of self which are contained in the other layer

Usage:

- layer.in(other)

This method selects all shapes or regions from self which are contained the other region exactly. It will use individual shapes from self or other if the respective region is in raw mode. If not, it will use coherent regions or combined edges from self or other.

It will return a new layer containing the selected shapes. A method which selects all shapes not contained in the other layer is not_in.

This method is available for polygon and edge layers.

The following image shows the effect of the "in" method (input1: red, input2: blue):

## "insert" - Inserts one or many objects into the layer

Usage:

- insert(object, object ...)

Objects that can be inserted are Edge objects (into edge layers) or DPolygon, DSimplePolygon, Path, DBox (into polygon layers). Convenience methods exist to create such objects (edge, polygon, box and #global#path). However, RBA constructors can used as well.

The insert method is useful in combination with the polygon_layer or edge_layer functions:

    el = edge_layer
    el.insert(edge(0.0, 0.0, 100.0, 0.0)

    pl = polygon_layer
    pl.insert(box(0.0, 0.0, 100.0, 200.0)

## "inside" - Selects shapes or regions of self which are inside the other region

Usage:

- layer.inside(other)

This method selects all shapes or regions from self which are inside the other region. completely (completely covered by polygons from the other region). If self is in raw mode, this method will select individual shapes. Otherwise, this method will select coherent regions and no part of these regions may be outside the other region. It returns a new layer containing the selected shapes. A version which modifies self is select_inside.

This method is available for polygon layers.

The following image shows the effect of the "inside" method (input1: red, input2: blue):

## "inside_part" - Returns the parts of the edges inside the given region

Usage:

- layer.inside_part(region)

This method returns the parts of the edges which are inside the given region. This is similar to the "&" operator, but this method does not return edges that are exactly on the boundaries of the polygons of the region.

This method is available for edge layers. The argument must be a polygon layer.

## "interacting" - Selects shapes or regions of self which touch or overlap shapes from the other region

Usage:

- layer.interacting(other)
- layer.interacting(other, min_count)
- layer.interacting(other, min_count, max_count)
- layer.interacting(other, min_count .. max_count)

This method selects all shapes or regions from self which touch or overlap shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_interacting.

This method is available for polygon, text and edge layers. Edges can be selected with respect to other edges or polygons. Texts can be selected with respect to polygons. Polygons can be selected with respect to edges, texts and other polygons.

The following image shows the effect of the "interacting" method (input1: red, input2: blue):

If a single count is given, shapes from self are selected only if they do interact at least with the given number of (different) shapes from the other layer. If a min and max count is given, shapes from self are selected only if they interact with min_count or more, but a maximum of max_count different shapes from the other layer. Two polygons overlapping or touching at two locations are counted as single interactions.

## "intersections" - Returns the intersection points of intersecting edge segments for two edge collections

Usage:

- layer.intersections(edges)

This operation is similar to the "&" operator, but it does also report intersection points between non-colinear, but intersection edges. Such points are reported as point-like, degenerated edge objects.

This method is available for edge layers. The argument must be an edge layer.

## "is_box?" - Returns true, if the region contains a single box

Usage:

- layer.is_box?

The method returns true, if the region consists of a single box only. Merged semantics does not apply - if the region forms a box which is composed of multiple pieces, this method will not return true.

## "is_clean?" - Returns true, if the layer is clean state

Usage:

- layer.is_clean?

See clean for a discussion of the clean state.

## "is_deep?" - Returns true, if the layer is a deep (hierarchical) layer

Usage:

- layer.is_deep?

## "is_empty?" - Returns true, if the layer is empty

Usage:

- layer.is_empty?

## "is_merged?" - Returns true, if the polygons of the layer are merged

Usage:

- layer.is_merged?

This method will return true, if the polygons of this layer are merged, i.e. they don't overlap and form single continuous polygons. In clean mode, this is ensured implicitly. In raw mode (see raw), merging can be achieved by using the merge method. is_merged? tells, whether calling merge is necessary.

## "is_raw?" - Returns true, if the layer is raw state

Usage:

- layer.is_raw?

See clean for a discussion of the raw state.

## "iso" - An alias for "isolated"

Usage:

- layer.iso(value [, options])

See isolated for a description of that method

## "isolated" - An isolation check

Usage:

- layer.isolated(value [, options])
- layer.iso(value [, options])

Note: "isolated" and "iso" are available as operators for the "universal DRC" function Layer#drc within the DRC framework. These variants have more options and are more intuitive to use. See isolated for more details.

See space for a description of this method. In contrast to space, this method is available for polygon layers only, since only on such layers different polygons can be identified.

"iso" is the short form of this method.

The following image shows the effect of the isolated check:

## "join" - Joins the layer with another layer

Usage:

- layer.join(other)

The method includes the edges or polygons from the other layer into this layer. It is an alias for the "+" operator.

This method is available for polygon, edge and edge pair layers.

The following images show the effect of the "join" method on polygons and edges (input1: red, input2: blue):

## "length" - Returns the total length of the edges in the edge layer

Usage:

- layer.length

This method requires an edge layer. It returns the total length of all edges in micron. Merged semantics applies, i.e. before computing the length, the edges are merged unless raw mode is chosen (see raw). Hence in clean mode (see clean), overlapping edges are not counted twice.

## "merge" - Merges the layer (modifies the layer)

Usage:

- layer.merge([overlap_count])

Like merged, but modifies the input and returns a reference to the new layer.

## "merged" - Returns the merged layer

Usage:

- layer.merged([overlap_count])

Returns the merged input. Usually, merging is done implicitly using the clean state (which is default). However, in raw state, merging can be enforced by using this method. In addition, this method allows specification of a minimum overlap count, i.e. only where at least the given number of polygons overlap, output is produced. See sized for an application of that.

This method works both on edge or polygon layers. Edge merging forms single, continuous edges from coincident and connected individual edges.

A version that modifies the input layer is merge.

The following images show the effect of various forms of the "merged" method:

## "middle" - Returns the center points of the bounding boxes of the polygons

Usage:

- layer.middle([ options ])

This method produces markers on the centers of the polygon's bounding box centers. These markers can be point-like edges or small 2x2 DBU boxes. The latter is the default. A more generic function is extent_refs. "middle" is basically a synonym for "extent_refs(:center)".

The options available are:

- as_boxes : with this option, small boxes will be produced as markers
- as_dots : with this option, point-like edges will be produced instead of small boxes

The following image shows the effect of this method

## "move" - Moves (shifts, translates) a layer (modifies the layer)

Usage:

- layer.move(dx, dy)

Moved the input by the given distance. The layer that this method is called upon is modified and the modified version is returned for further processing.

Shift distances can be given as floating-point values (in micron) or integer values (in database units). To explicitly specify the unit, use the unit denominators.

## "moved" - Moves (shifts, translates) a layer

Usage:

- layer.moved(dx, dy)

Moves the input layer by the given distance (x, y) and returns the moved layer. The layer that this method is called upon is not modified.

Shift distances can be given as floating-point values (in micron) or integer values (in database units). To explicitly specify the unit, use the unit denominators.

The following images shows the effect of the "moved" method:

## "non_rectangles" - Selects all polygons from the input which are not rectangles

Usage:

- layer.non_rectangles

This method is available for polygon layers. By default "merged" semantics applies, i.e. all polygons are merged before non-rectangles are selected (see clean and raw).

## "non_rectilinear" - Selects all non-rectilinear polygons from the input

Usage:

- layer.non_rectilinear

This method is available for polygon layers. By default "merged" semantics applies, i.e. all polygons are merged before non-rectilinear polygons are selected (see clean and raw).

## "non_squares" - Selects all polygons from the input which are not squares

Usage:

- layer.non_rectangles

This method is available for polygon layers. By default "merged" semantics applies, i.e. all polygons are merged before non-squares are selected (see clean and raw).

## "non_strict" - Marks a layer for non-strict handling

Usage:

- layer.non_strict

See strict for details about this option.

This feature has been introduced in version 0.23.2.

## "not" - Boolean NOT operation

Usage:

- layer.not(other)

The method computes a boolean NOT between self and other. It is an alias for the "-" operator.

This method is available for polygon and edge layers. If the first operand is an edge layer and the second is an edge layer, the result will be the edges of the first operand which are outside the polygons of the second operand.

The following images show the effect of the "not" method on polygons and edges (input1: red, input2: blue):

The NOT operation can be applied between a text and a polygon layer. In this case, the texts outside the polygons will be written to the output (labels: red, input2: blue):

## "not_covering" - Selects shapes or regions of self which do not cover (enclose) one or more shapes from the other region

Usage:

- layer.not_covering(other)
- layer.not_covering(other, min_count)
- layer.not_covering(other, min_count, max_count)
- layer.not_covering(other, min_count .. max_count)

This method selects all shapes or regions from self which do not cover shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. This method returns the inverse of covering and provides the same options.

The following image shows the effect of the "not_covering" method:

This method is available for polygons only. It returns a new layer containing the selected shapes. A version which modifies self is select_not_covering.

## "not_in" - Selects shapes or regions of self which are not contained in the other layer

Usage:

- layer.not_in(other)

This method selects all shapes or regions from self which are not contained the other region exactly. It will use individual shapes from self or other if the respective region is in raw mode. If not, it will use coherent regions or combined edges from self or other.

It will return a new layer containing the selected shapes. A method which selects all shapes contained in the other layer is in.

This method is available for polygon and edge layers.

The following image shows the effect of the "not_in" method (input1: red, input2: blue):

## "not_inside" - Selects shapes or regions of self which are not inside the other region

Usage:

- layer.not_inside(other)

This method selects all shapes or regions from self which are not inside the other region. completely (completely covered by polygons from the other region). If self is in raw mode, this method will select individual shapes. Otherwise, this method will select coherent regions and no part of these regions may be outside the other region. It returns a new layer containing the selected shapes. A version which modifies self is select_not_inside.

This method is available for polygon layers.

The following image shows the effect of the "not_inside" method (input1: red, input2: blue):

## "not_interacting" - Selects shapes or regions of self which do not touch or overlap shapes from the other region

Usage:

- layer.not_interacting(other)
- layer.not_interacting(other, min_count)
- layer.not_interacting(other, min_count, max_count)
- layer.not_interacting(other, min_count .. max_count)

This method selects all shapes or regions from self which do not touch or overlap shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_not_interacting.

This method is available for polygon, text and edge layers. Edges can be selected with respect to other edges or polygons. Texts can be selected with respect to polygons. Polygons can be selected with respect to edges, texts and other polygons.

The following image shows the effect of the "not_interacting" method (input1: red, input2: blue):

If a single count is given, shapes from self are selected only if they interact with less than the given number of (different) shapes from the other layer. If a min and max count is given, shapes from self are selected only if they interact with less than min_count or more than max_count different shapes from the other layer. Two polygons overlapping or touching at two locations are counted as single interactions.

## "not_outside" - Selects shapes or regions of self which are not outside the other region

Usage:

- layer.not_outside(other)

This method selects all shapes or regions from self which are not completely outside the other region (part of these shapes or regions may be covered by shapes from the other region). If self is in raw mode, this method will select individual shapes. Otherwise, this method will select coherent regions and no part of these regions may overlap with shapes from the other region. It returns a new layer containing the selected shapes. A version which modifies self is select_not_outside.

This method is available for polygon layers.

The following image shows the effect of the "not_outside" method (input1: red, input2: blue):

## "not_overlapping" - Selects shapes or regions of self which do not overlap shapes from the other region

Usage:

- layer.not_overlapping(other)
- layer.not_overlapping(other, min_count)
- layer.not_overlapping(other, min_count, max_count)
- layer.not_overlapping(other, min_count .. max_count)

This method selects all shapes or regions from self which do not overlap shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. This method will return the inverse of overlapping and provides the same options.

The "not_overlapping" method is similar to the outside method. However, "outside" does not provide the option to specify counts.

This method is available for polygons only. It returns a new layer containing the selected shapes. A version which modifies self is select_not_overlapping.

## "notch" - An intra-region spacing check

Usage:

- layer.notch(value [, options])

Note: "notch" is available as an operator for the "universal DRC" function Layer#drc within the DRC framework. This variant has more options and is more intuitive to use. See notch for more details.

See space for a description of this method. In contrast to space, this method is available for polygon layers only, since only on such layers different polygons can be identified. Also, opposite and rectangle error filtering is not available for this method.

The following image shows the effect of the notch check:

## "odd_polygons" - Checks for odd polygons (self-overlapping, non-orientable)

Usage:

- layer.odd_polygons

Returns the parts of the polygons which are not orientable (i.e. "8" configuration) or self-overlapping. Merged semantics does not apply for this method. Always the raw polygons are taken (see raw).

The odd_polygons check is not available in deep mode currently. See deep_reject_odd_polygons for an alternative.

## "ongrid" - Checks for on-grid vertices

Usage:

- layer.ongrid(g)
- layer.ongrid(gx, gy)

Returns a single-vertex marker for each vertex whose x coordinate is not a multiple of g or gx or whose y coordinate is not a multiple of g or gy. The single-vertex markers are edge pair objects which describe a single point. When setting the grid to 0, no grid check is performed in that specific direction.

This method requires a polygon layer. Merged semantics applies (see raw and clean).

## "or" - Boolean OR operation

Usage:

- layer.or(other)

The method computes a boolean OR between self and other. It is an alias for the "|" operator.

This method is available for polygon and edge layers.

The following images show the effect of the "or" method on polygons and edges (input1: red, input2: blue):

## "output" - Outputs the content of the layer

Usage:

- layer.output(specs)

This method will copy the content of the layer to the specified output.

If a report database is selected for the output, the specification has to include a category name and optionally a category description.

If the layout is selected for the output, the specification can consist of one to three parameters: a layer number, a data type (optional, default is 0) and a layer name (optional). Alternatively, the output can be specified by a single LayerInfo object.

See report and target on how to configure output to a target layout or report database.

## "outside" - Selects shapes or regions of self which are outside the other region

Usage:

- layer.outside(other)

This method selects all shapes or regions from self which are completely outside the other region (no part of these shapes or regions may be covered by shapes from the other region). If self is in raw mode, this method will select individual shapes. Otherwise, this method will select coherent regions and no part of these regions may overlap with shapes from the other region. It returns a new layer containing the selected shapes. A version which modifies self is select_outside.

This method is available for polygon layers.

The following image shows the effect of the "outside" method (input1: red, input2: blue):

## "outside_part" - Returns the parts of the edges outside the given region

Usage:

- layer.outside_part(region)

This method returns the parts of the edges which are outside the given region. This is similar to the "&" operator, but this method does not remove edges that are exactly on the boundaries of the polygons of the region.

This method is available for edge layers. The argument must be a polygon layer.

## "overlap" - An overlap check

Usage:

- layer.overlap(other_layer, value [, options])

Note: "overlap" is available as an operator for the "universal DRC" function drc within the DRC framework. This variant has more options and is more intuitive to use. See overlap for more details.

This method checks whether layer and other_layer overlap by at least the given length. Locations, where this is not the case will be reported in form of edge pair error markers. Locations, where both layers touch will be reported as errors as well. Formally such locations form an overlap with a value of 0. Locations, where both regions do not overlap or touch will not be reported. Such regions can be detected with outside or by a boolean "not".

The options are the same as for separation.

Formally, the overlap method is a two-layer width check. In contrast to the single- layer width method (width), the zero value also triggers an error and separate polygons are checked against each other, while for the single-layer width, only single polygons are considered.

The overlap method can be applied to both edge or polygon layers. On edge layers the orientation of the edges matters: only edges which run back to back with their inside side pointing towards each other are checked for distance.

As for the other DRC methods, merged semantics applies. The options available are the same than for width. Distance values can be given as floating-point values (in micron) or integer values (in database units). To explicitly specify the unit, use the unit denominators.

The following images show the effect of the overlap check (input1: red, input2: blue):

## "overlapping" - Selects shapes or regions of self which overlap shapes from the other region

Usage:

- layer.overlapping(other)
- layer.overlapping(other, min_count)
- layer.overlapping(other, min_count, max_count)
- layer.overlapping(other, min_count .. max_count)

This method selects all shapes or regions from self which overlap shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_overlapping.

This method is available for polygons only.

The following image shows the effect of the "overlapping" method:

A range of counts can be specified. If so, the shape from the primary layer is only selected when overlapping a given number of shapes from the other layer. For the interpretation of the count see interacting.

## "perimeter" - Returns the total perimeter of the polygons in the region

Usage:

- layer.perimeter

This method requires a polygon layer. It returns the total perimeter of all polygons in micron. Merged semantics applies, i.e. before computing the perimeter, the polygons are merged unless raw mode is chosen (see raw).

The returned value gives the perimeter in micrometer units.

## "polygons" - Returns polygons from edge pairs

Usage:

- layer.polygons([ enlargement ])

This method applies to edge pair collections. The edge pairs will be converted into polygons connecting the edges the edge pairs are made of. In order to properly handle special edge pairs (coincident edges, point-like edges etc.) an enlargement parameter can be specified which will make the resulting polygon somewhat larger than the original edge pair. If the enlargement parameter is 0, special edge pairs with an area of 0 will be dropped.

## "polygons?" - Returns true, if the layer is a polygon layer

Usage:

- layer.polygons?

## "pull_inside" - Selects shapes or regions of other which are inside polygons from the this region

Usage:

- layer.pull_inside(other)

This method selects all shapes or regions from other which are inside polygons from this region. Unless other is in raw mode (see raw), coherent regions are selected from other, otherwise individual shapes are selected.

The functionality is similar to select_inside, but chosing shapes from other rather than from self. Because in deep mode the hierarchy reference comes from self, this method provides a way to pull shapes from other to the hierarchy to self.

This method is available for polygon layers. Other needs to be a polygon layer too.

## "pull_interacting" - Selects shapes or edges of other which touch or overlap shapes from the this region

Usage:

- layer.pull_interacting(other)

This method selects all shapes or regions from other which touch or overlap shapes from this region. Unless other is in raw mode (see raw), coherent regions are selected from other, otherwise individual shapes are selected.

The functionality is similar to select_interacting, but chosing shapes from other rather than from self. Because in deep mode the hierarchy reference comes from self, this method provides a way to pull shapes from other to the hierarchy to self.

This method will neither modify self nor other.

This method is available for polygon, edge and text layers, similar to interacting.

## "pull_overlapping" - Selects shapes or regions of other which overlap shapes from the this region

Usage:

- layer.pull_overlapping(other)

This method selects all shapes or regions from other which overlap shapes from this region. Unless other is in raw mode (see raw), coherent regions are selected from other, otherwise individual shapes are selected.

The functionality is similar to select_overlapping, but chosing shapes from other rather than from self. Because in deep mode the hierarchy reference comes from self, this method provides a way to pull shapes from other to the hierarchy to self.

This method is available for polygon layers. Other needs to be a polygon layer too.

## "raw" - Marks a layer as raw

Usage:

- layer.raw

A raw layer basically is the opposite of a "clean" layer (see clean). Polygons on a raw layer are considered "as is", i.e. overlapping polygons are not connected and inner edges may occur due to cut lines. Holes may not exists if the polygons are derived from a representation that does not allow holes (i.e. GDS2 files).

Note that this method will set the state of the layer. In combination with the fact, that copied layers are references to the original layer, this may lead to unexpected results:

    l = ...
    l2 = l1
    ... do something
    l.raw
    # now l2 is also a raw layer

To avoid that, use the dup method to create a real (deep) copy.

## "rectangles" - Selects all rectangles from the input

Usage:

- layer.rectangles

This method is available for polygon layers. By default "merged" semantics applies, i.e. all polygons are merged before rectangles are selected (see clean and raw). non_rectangles will select all non-rectangles.

## "rectilinear" - Selects all rectilinear polygons from the input

Usage:

- layer.rectilinear

This method is available for polygon layers. By default "merged" semantics applies, i.e. all polygons are merged before rectilinear polygons are selected (see clean and raw). non_rectilinear will select all non-rectangles.

## "rotate" - Rotates a layer (modifies the layer)

Usage:

- layer.rotate(a)

Rotates the input by the given angle (in degree). The layer that this method is called upon is modified and the modified version is returned for further processing.

## "rotated" - Rotates a layer

Usage:

- layer.rotated(a)

Rotates the input layer by the given angle (in degree) and returns the rotated layer. The layer that this method is called upon is not modified.

The following image shows the effect of the "rotated" method:

## "rounded_corners" - Applies corner rounding to each corner of the polygon

Usage:

- layer.rounded_corners(inner, outer, n)

Inner (concave) corners are replaced by circle segments with a radius given by the "inner" parameter. Outer (convex) corners are relaced by circle segments with a radius given by the "outer" parameter.

The circles are approximated by polygons. "n" segments are used to approximate a full circle.

This method return a layer wit the modified polygons. Merged semantics applies for this method (see raw and clean). If used with tiling, the rounded_corners function may render invalid results because in tiling mode, not the whole merged region may be captured. In that case, inner edges may appear as outer ones and their corners will receive rounding.

The following image shows the effect of the "rounded_corners" method. The upper ends of the vertical bars are rounded with a smaller radius automatically because their width does not allow a larger radius.

## "scale" - Scales a layer (modifies the layer)

Usage:

- layer.scale(f)

Scales the input. After scaling, features have a f times bigger dimension. The layer that this method is called upon is modified and the modified version is returned for further processing.

## "scaled" - Scales a layer

Usage:

- layer.scaled(f)

Scales the input layer and returns a new layer whose features have a f times bigger dimension. The layer that this method is called upon is not modified.

The following images shows the effect of the "scaled" method:

## "second_edges" - Returns the second edges of an edge pair collection

Usage:

- layer.second_edges

Applies to edge pair collections only. Returns the second edges of the edge pairs in the collection.

Some checks deliver symmetric edge pairs (e.g. space, width, etc.) for which the edges are commutable. "second_edges" will not deliver edges for such edge pairs. Instead, "first_edges" will deliver both.

## "select" - Selects edges, edge pairs or polygons based on evaluation of a block

Usage:

- layer.select { |object| ... }

This method evaluates the block and returns a new container with those objects for which the block evaluates to true. It is available for edge, polygon and edge pair layers. The corresponding objects are DPolygon, DEdge or DEdgePair.

Because this method executes inside the interpreter, it's inherently slow. Tiling does not apply to this method.

Here is a (slow) equivalent of the area selection method:

    new_layer = layer.select { |polygon| polygon.area >= 10.0 }

## "select_covering" - Selects shapes or regions of self which completely cover (enclose) one or more shapes from the other region

Usage:

- layer.select_covering(other)
- layer.select_covering(other, min_count)
- layer.select_covering(other, min_count, max_count)
- layer.select_covering(other, min_count .. max_count)

This method selects all shapes or regions from self which cover shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is covering.

This method is available for polygons only.

## "select_inside" - Selects shapes or regions of self which are inside the other region

Usage:

- layer.select_inside(other)

This method selects all shapes or regions from self which are inside the other region. completely (completely covered by polygons from the other region). If self is in raw mode, this method will select individual shapes. Otherwise, this method will select coherent regions and no part of these regions may be outside the other region. It modifies self to contain the selected shapes. A version which does not modify self is inside.

This method is available for polygon layers.

## "select_interacting" - Selects shapes or regions of self which touch or overlap shapes from the other region

Usage:

- layer.select_interacting(other)
- layer.select_interacting(other, min_count)
- layer.select_interacting(other, min_count, max_count)
- layer.select_interacting(other, min_count .. max_count)

This method selects all shapes or regions from self which touch or overlap shapes from the other layer. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is interacting.

This method is available for polygon, text and edge layers. Edges can be selected with respect to other edges or polygons. Texts can be selected with respect to polygons. Polygons can be selected with respect to edges, texts and other polygons.

If a single count is given, shapes from self are selected only if they do interact at least with the given number of (different) shapes from the other layer. If a min and max count is given, shapes from self are selected only if they interact with min_count or more, but a maximum of max_count different shapes from the other layer. Two polygons overlapping or touching at two locations are counted as single interactions.

## "select_not_covering" - Selects shapes or regions of self which do not cover (enclose) one or more shapes from the other region

Usage:

- layer.select_not_covering(other)
- layer.select_not_covering(other, min_count)
- layer.select_not_covering(other, min_count, max_count)
- layer.select_not_covering(other, min_count .. max_count)

This method selects all shapes or regions from self which do not cover shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is not_covering.

This method is available for polygons only.

## "select_not_inside" - Selects shapes or regions of self which are not inside the other region

Usage:

- layer.select_not_inside(other)

This method selects all shapes or regions from self which are not inside the other region. completely (completely covered by polygons from the other region). If self is in raw mode, this method will select individual shapes. Otherwise, this method will select coherent regions and no part of these regions may be outside the other region. It modifies self to contain the selected shapes. A version which does not modify self is not_inside.

This method is available for polygon layers.

## "select_not_interacting" - Selects shapes or regions of self which do not touch or overlap shapes from the other region

Usage:

- layer.select_not_interacting(other)
- layer.select_not_interacting(other, min_count)
- layer.select_not_interacting(other, min_count, max_count)
- layer.select_not_interacting(other, min_count .. max_count)

This method selects all shapes or regions from self which do not touch or overlap shapes from the other layer. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is not_interacting.

This method is available for polygon, text and edge layers. Edges can be selected with respect to other edges or polygons. Texts can be selected with respect to polygons. Polygons can be selected with respect to edges, texts and other polygons.

If a single count is given, shapes from self are selected only if they interact with less than the given number of (different) shapes from the other layer. If a min and max count is given, shapes from self are selected only if they interact with less than min_count or more than max_count different shapes from the other layer. Two polygons overlapping or touching at two locations are counted as single interactions.

## "select_not_outside" - Selects shapes or regions of self which are not outside the other region

Usage:

- layer.select_not_outside(other)

This method selects all shapes or regions from self which are not completely outside the other region (part of these shapes or regions may be covered by shapes from the other region). If self is in raw mode, this method will select individual shapes. Otherwise, this method will select coherent regions and no part of these regions may overlap with shapes from the other region. It modifies self to contain the selected shapes. A version which does not modify self is not_outside.

This method is available for polygon layers.

## "select_not_overlapping" - Selects shapes or regions of self which do not overlap shapes from the other region

Usage:

- layer.select_not_overlapping(other)
- layer.select_not_overlapping(other, min_count)
- layer.select_not_overlapping(other, min_count, max_count)
- layer.select_not_overlapping(other, min_count .. max_count)

This method selects all shapes or regions from self which do not overlap shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is not_overlapping.

This method is available for polygons only.

## "select_outside" - Selects shapes or regions of self which are outside the other region

Usage:

- layer.select_outside(other)

This method selects all shapes or regions from self which are completely outside the other region (no part of these shapes or regions may be covered by shapes from the other region). If self is in raw mode, this method will select individual shapes. Otherwise, this method will select coherent regions and no part of these regions may overlap with shapes from the other region. It modifies self to contain the selected shapes. A version which does not modify self is outside.

This method is available for polygon layers.

## "select_overlapping" - Selects shapes or regions of self which overlap shapes from the other region

Usage:

- layer.select_overlapping(other)
- layer.select_overlapping(other, min_count)
- layer.select_overlapping(other, min_count, max_count)
- layer.select_overlapping(other, min_count .. max_count)

This method selects all shapes or regions from self which overlap shapes from the other region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is overlapping.

This method is available for polygons only.

## "sep" - An alias for "separation"

Usage:

- layer.sep(value [, options])

See separation for a description of that method

## "separation" - A two-layer spacing check

Usage:

- layer.separation(other_layer, value [, options])
- layer.sep(other_layer, value [, options])

Note: "separation" and "sep" are available as operators for the "universal DRC" function drc within the DRC framework. These variants have more options and are more intuitive to use. See separation for more details.

This method performs a two-layer spacing check. Like space, this method can be applied to edge or polygon layers. Locations where edges of the layer are closer than the specified distance to the other layer are reported as edge pair error markers.

"sep" is the short form of this method.

In contrast to the space and related methods, locations where both layers touch are also reported. More specifically, the case of zero spacing will also trigger an error while for space it will not.

As for the other DRC methods, merged semantics applies. Distance values can be given as floating-point values (in micron) or integer values (in database units). To explicitly specify the unit, use the unit denominators.

The following image shows the effect of the separation check (input1: red, input2: blue):

### opposite and rectangle error filtering

The options for the separation check are those available for the width or space method plus opposite and rectangle error filtering.

Opposite error filtering will waive errors that are on opposite sides of the original figure. The inverse is selection of errors only when there is an error present on the opposite side of the original figure. Opposite error waiving or selection is achieved through these options inside the DRC function call:

- not_opposite will waive opposite errors
- only_opposite will select errors only if there is an opposite one

These modes imply partial waiving or selection if "opposite" only applies to a section of an error.

The following images shows the effect of these options:

Rectangle error filtering allows waiving errors based on how they cover the sides of an original rectangular figure. This selection only applies to errors covering the full edge of the rectangle. Errors covering parts of the rectangle edges are not considered in this scheme.

The rectangle filter option is enabled by these modes:

- one_side_allowed will waive errors when they appear on one side of the rectangle only
- two_sides_allowed will waive errors when they appear on two sides of the rectangle
- two_connected_sides_allowed will waive errors when they appear on two connected sides of the rectangle ("L" configuration)
- two_opposite_sides_allowed will waive errors when they appear on two opposite sides of the rectangle
- three_sides_allowed will waive errors when they appear on three sides of the rectangle
- four_sides_allowed will waive errors when they appear on four sides of the rectangle

Multiple of these options can be given, which will make errors waived if one of these conditions is met.

The following images shows the effect of some rectangle filter modes:

## "size" - Polygon sizing (per-edge biasing, modifies the layer)

Usage:

- layer.size(d [, mode])
- layer.size(dx, dy [, mode]))

See sized. The size method basically does the same but modifies the layer it is called on. The input layer is returned and available for further processing.

## "sized" - Polygon sizing (per-edge biasing)

Usage:

- layer.sized(d [, mode])
- layer.sized(dx, dy [, mode]))

This method requires a polygon layer. It will apply a bias per edge of the polygons and return the biased layer. The layer that this method is called on is not modified.

In the single-value form, that bias is applied both in horizontal or vertical direction. In the two-value form, the horizontal and vertical bias can be specified separately.

The mode defines how to handle corners. The following modes are available:

- diamond_limit : This mode will connect the shifted edges without corner interpolation
- octagon_limit : This mode will create octagon-shaped corners
- square_limit : This mode will leave 90 degree corners untouched but cut off corners with a sharper angle. This is the default mode.
- acute_limit : This mode will leave 45 degree corners untouched but cut off corners with a sharper angle
- no_limit : This mode will not cut off (only at extremely sharp angles

Merged semantics applies, i.e. polygons will be merged before the sizing is applied unless the layer was put into raw mode (see raw). On output, the polygons are not merged immediately, so it is possible to detect overlapping regions after a positive sizing using raw and merged with an overlap count, for example:

    layer.sized(300.nm).raw.merged(2)

Bias values can be given as floating-point values (in micron) or integer values (in database units). To explicitly specify the unit, use the unit denominators.

size is working like sized but modifies the layer it is called on.

The following images show the effect of various forms of the "sized" method:

## "smoothed" - Smoothes the polygons of the region

Usage:

- layer.smoothed(d)

"Smoothing" returns a simplified version of the polygons. Simplification is achieved by removing vertices unless the resulting polygon deviates by more than the given distance d from the original polygon.

This method return a layer wit the modified polygons. Merged semantics applies for this method (see raw and clean).

## "snap" - Brings each vertex on the given grid (g or gx/gy for x or y direction)

Usage:

- layer.snap(g)
- layer.snap(gx, gy)

Shifts each off-grid vertex to the nearest on-grid location. If one grid is given, this grid is applied to x and y coordinates. If two grids are given, gx is applied to the x coordinates and gy is applied to the y coordinates. If 0 is given as a grid, no snapping is performed in that direction.

This method modifies the layer. A version that returns a snapped version of the layer without modifying the layer is snapped.

This method requires a polygon layer. Merged semantics applies (see raw and clean).

## "snapped" - Returns a snapped version of the layer

Usage:

- layer.snapped(g)
- layer.snapped(gx, gy)

See snap for a description of the functionality. In contrast to snap, this method does not modify the layer but returns a snapped copy.

## "space" - A space check

Usage:

- layer.space(value [, options])

Note: "space" is available as an operator for the "universal DRC" function Layer#drc within the DRC framework. This variant has more options and is more intuitive to use. See space for more details.

This method performs a space check and returns a collection of edge pairs. A space check can be performed on polygon and edge layers. On edge layers, all edges are checked against all other edges. If two edges form a "face to face" relation (i.e. their outer sides face each other) and their distance is less than the specified value, an error shape is generated for that edge pair. On polygon layers, the polygons on each layer are checked for space against other polygons for locations where their space is less than the specified value. In that case, an edge pair error shape is generated. The space check will also check the polygons for space violations against themselves, i.e. notches violating the space condition are reported.

The notch method is similar, but will only report self-space violations. The isolated method will only report space violations to other polygons. separation is a two-layer space check where space is checked against polygons of another layer.

Like for the width method, merged semantics applies.

Distance values can be given as floating-point values (in micron) or integer values (in database units). To explicitly specify the unit, use the unit denominators.

For the manifold options of this function see the width method description.

The following image shows the effect of the space check:

## "split_covering" - Returns the results of covering and not_covering at the same time

Usage:

- (a, b) = layer.split_covering(other [, options ])

This method returns the polygons covering polygons from the other layer in one layer and all others in a second layer. This method is equivalent to calling covering and not_covering, but is faster than doing this in separate steps:

    (covering, not_covering) = l1.split_covering(l2)

The options of this method are the same than covering.

## "split_inside" - Returns the results of inside and not_inside at the same time

Usage:

- (a, b) = layer.split_inside(other)

This method returns the polygons inside of polygons from the other layer in one layer and all others in a second layer. This method is equivalent to calling inside and not_inside, but is faster than doing this in separate steps:

    (inside, not_inside) = l1.split_inside(l2)

## "split_interacting" - Returns the results of interacting and not_interacting at the same time

Usage:

- (a, b) = layer.split_interacting(other [, options ])

This method returns the polygons interacting with objects from the other container in one layer and all others in a second layer. This method is equivalent to calling interacting and not_interacting, but is faster than doing this in separate steps:

    (interacting, not_interacting) = l1.split_interacting(l2)

The options of this method are the same than interacting.

## "split_outside" - Returns the results of outside and not_outside at the same time

Usage:

- (a, b) = layer.split_outside(other)

This method returns the polygons outside of polygons from the other layer in one layer and all others in a second layer. This method is equivalent to calling outside and not_outside, but is faster than doing this in separate steps:

    (outside, not_outside) = l1.split_outside(l2)

## "split_overlapping" - Returns the results of overlapping and not_overlapping at the same time

Usage:

- (a, b) = layer.split_overlapping(other [, options ])

This method returns the polygons overlapping polygons from the other layer in one layer and all others in a second layer. This method is equivalent to calling overlapping and not_overlapping, but is faster than doing this in separate steps:

    (overlapping, not_overlapping) = l1.split_overlapping(l2)

The options of this method are the same than overlapping.

## "squares" - Selects all squares from the input

Usage:

- layer.squares

This method is available for polygon layers. By default "merged" semantics applies, i.e. all polygons are merged before squares are selected (see clean and raw). non_squares will select all non-rectangles.

## "start_segments" - Returns the part at the beginning of each edge

Usage:

- layer.start_segments(length)
- layer.start_segments(length, fraction)

This method will return a partial edge for each edge in the input, located and the end of the original edge. The new edges will share the start point with the original edges, but not necessarily their end points. For further details about the orientation of edges and the parameters of this method, see end_segments.

The following images show the effect of the method:

## "strict" - Marks a layer for strict handling

Usage:

- layer.strict

If a layer is marked for strict handling, some optimizations are disabled. Specifically for boolean operations, the results will also be merged if one input is empty. For boolean operations, strict handling should be enabled for both inputs. Strict handling is disabled by default.

See non_strict about how to reset this mode.

This feature has been introduced in version 0.23.2.

## "strict?" - Returns true, if strict handling is enabled for this layer

Usage:

- layer.is_strict?

See strict for a discussion of strict handling.

This feature has been introduced in version 0.23.2.

## "texts" - Selects texts from an original layer

Usage:

- layer.texts
- layer.texts(p)
- layer.texts([ options ])

This method can be applied to original layers - i.e. ones that have been created with input. By default, a small box (2x2 DBU) will be produced on each selected text. By using the "as_dots" option, degenerated point-like edges will be produced.

The preferred method however is to use true text layers created with labels. In this case, without specifying "as_dots" or "as_boxes" retains the text objects as such a text filtering is applied. In contrast to this, layers generated with input cannot maintain the text nature of the selected objects and produce dots or small polygon boxes in the texts method.

Texts can be selected either by exact match string or a pattern match with a glob-style pattern. By default, glob-style pattern are used. The options available are:

- pattern(p) : Use a pattern to match the string (this is the default)
- text(s) : Select the texts that exactly match the given string
- as_boxes : with this option, small boxes will be produced as markers
- as_dots : with this option, point-like edges will be produced instead of small boxes

Here are some examples:

    # Selects all texts
    t = labels(1, 0).texts
    # Selects all texts beginning with an "A"
    t = labels(1, 0).texts("A*")
    t = labels(1, 0).texts(pattern("A*"))
    # Selects all texts whose string is "ABC"
    t = labels(1, 0).texts(text("ABC"))

The effect of the operation is shown in these examples:

## "texts_not" - Selects texts from an original layer not matching a specific selection

Usage:

- layer.texts_not
- layer.texts_not(p)
- layer.texts_not([ options ])

This method can be applied to true text layers obtained with labels. In this case, without specifying "as_dots" or "as_boxes" retains the text objects as such. Only text filtering is applied.

Beside that this method acts like texts, but will select the text objects not matching the filter.

## "transform" - Transforms a layer (modifies the layer)

Usage:

- layer.transform(t)

Like transform, but modifies the input and returns a reference to it for further processing.

## "transformed" - Transforms a layer

Usage:

- layer.transformed(t)

Transforms the input layer by the given transformation and returns the moved layer. The layer that this method is called upon is not modified. This is the most generic method is transform a layer. The transformation is a DCplxTrans object which describes many different kinds of affine transformations except shear and anisotropic magnification.

The following image shows the effect of the "moved" method:

## "width" - A width check

Usage:

- layer.width(value [, options])

Note: "width" is available as an operator for the "universal DRC" function Layer#drc within the DRC framework. This variant has more options and is more intuitive to use. See width for more details.

This method performs a width check and returns a collection of edge pairs. A width check can be performed on polygon and edge layers. On edge layers, all edges are checked against all other edges. If two edges form a "back to back" relation (i.e. their inner sides face each other) and their distance is less than the specified value, an error shape is generated for that edge pair. On polygon layers, the polygons on each layer are checked for locations where their width is less than the specified value. In that case, an edge pair error shape is generated.

### Options

The options available are:

- euclidian : perform the check using Euclidian metrics (this is the default)
- square : perform the check using Square metrics
- projection : perform the check using projection metrics
- whole_edges : With this option, the check will return all of the edges, even if the criterion is violated only over a part of the edge
- angle_limit(a) : Specifies the angle above or equal to which no check is performed. The default value is 90, which means that for edges having an angle of 90 degree or more, no check is performed. Setting this value to 45 will make the check only consider edges enclosing angles of less than 45 degree.
- projection_limits(min, max) or projection_limits(min .. max) : this option makes the check only consider edge pairs whose projected length on each other is more or equal than min and less than max
- projecting (in condition) : This specification is equivalent to "projection_limits" but is more intuitive, as "projecting" is written with a condition, like "projecting < 2.um". Available operators are: "==", "<", "<=", ">" and ">=". Double-bounded ranges are also available, like: "0.5 <= projecting < 2.0".
- transparent : performs the check without shielding (polygon layers only)
- shielded : performs the check with shielding (polygon layers only)

Note that without the angle_limit, acute corners will always be reported, since two connected edges always violate the width in the corner. By adjusting the angle_limit, an acute corner check can be implemented.

Merge semantics applies to this method, i.e. disconnected polygons are merged before the width is checked unless "raw" mode is chosen.

The resulting edge pairs can be converted to polygons using the polygons method.

Distance values can be given as floating-point values (in micron) or integer values (in database units). To explicitly specify the unit, use the unit denominators, i.e.

    # width check for 1.5 micron:
    markers = in.width(1.5)
    # width check for 2 database units:
    markers = in.width(2)
    # width check for 2 micron:
    markers = in.width(2.um)
    # width check for 20 nanometers:
    markers = in.width(20.nm)

### Examples

The following images show the effect of various forms of the width check:

### Universal DRC function

There is an alternative notation for the check using the "universal DRC" function ("Layer#drc"). This notation is more intuitive and allows checking for widths bigger than a certain value or within a certain range. See "width" for details.

Apart from that it provides the same options than the plain width check. Follow this link for the documentation of this feature: width.

### Shielding

"shielding" is a concept where an internal or external distance is measured only if the opposite edge is not blocked by other edges between. Shielded mode makes a difference if very large distances are to be checked and the minimum distance is much smaller: in this case, a large distance violation may be blocked by features located between the edges which are checked. With shielding, large distance violations are not reported in this case. Shielding is also effective at zero distance which has an adverse effect: Consider a case, where one layer A is a subset of another layer B. If you try to check the distance between features of B vs. A, you cannot use shielding, because B features which are identical to A features will shield those entirely.

Shielding is enabled by default, but can be switched off with the "transparent" option.

## "with_angle" - Selects edges by their angle

Usage:

- layer.with_angle(min .. max)
- layer.with_angle(value)
- layer.with_angle(min, max)

When called on an edge layer, the method selects edges by their angle, measured against the horizontal axis in the mathematical sense.

For this measurement edges are considered without their direction and straight lines. A horizontal edge has an angle of zero degree. A vertical one has an angle of 90 degee. The angle range is from -90 (exclusive) to 90 degree (inclusive).

The first version of this method selects edges with a angle larger or equal to min and less than max (but not equal). The second version selects edges with exactly the given angle. The third version is identical to the first one.

When called on a polygon layer, this method selects corners which match the given angle or is within the given angle interval. The angle is measured between the edges forming the corner. For each corner, an edge pair containing the edges forming in the angle is returned.

A method delivering all objects not matching the angle criterion is without_angle.

The following images demonstrate some use cases of with_angle and without_angle:

## "with_area" - Selects polygons by area

Usage:

- layer.with_area(min .. max)
- layer.with_area(value)
- layer.with_area(min, max)

The first form will select all polygons with an area larger or equal to min and less (but not equal to) max. The second form will select the polygons with exactly the given area. The third form basically is equivalent to the first form, but allows specification of nil for min or max indicating no lower or upper limit.

## "with_area_ratio" - Selects polygons by the ratio of the bounding box area vs. polygon area

Usage:

- layer.with_area_ratio(min .. max)
- layer.with_area_ratio(value)
- layer.with_area_ratio(min, max)

The area ratio is a measure how far a polygon is approximated by it's bounding box. The value is always larger or equal to 1. Boxes have a area ratio of 1. Larger values mean more empty area inside the bounding box.

This method is available for polygon layers only.

## "with_bbox_aspect_ratio" - Selects polygons by the aspect ratio of their bounding box

Usage:

- layer.with_bbox_aspect_ratio(min .. max)
- layer.with_bbox_aspect_ratio(value)
- layer.with_bbox_aspect_ratio(min, max)

The method selects polygons similar to with_area or with_perimeter. However, the measured value is the aspect ratio of the bounding box. It is the larger dimensions divided by the smaller one. The "thinner" the polygon, the larger the aspect ratio. A square bounding box gives an aspect ratio of 1.

This method is available for polygon layers only.

## "with_bbox_height" - Selects polygons by the height of the bounding box

Usage:

- layer.with_bbox_height(min .. max)
- layer.with_bbox_height(value)
- layer.with_bbox_height(min, max)

The method selects polygons similar to with_area or with_perimeter. However, the measured dimension is the width of the bounding box.

This method is available for polygon layers only.

## "with_bbox_max" - Selects polygons by the maximum dimension of the bounding box

Usage:

- layer.with_bbox_max(min .. max)
- layer.with_bbox_max(value)
- layer.with_bbox_max(min, max)

The method selects polygons similar to with_area or with_perimeter. However, the measured dimension is the maximum dimension of the bounding box. The maximum dimension is either the width or height of the bounding box, whichever is larger.

This method is available for polygon layers only.

## "with_bbox_min" - Selects polygons by the minimum dimension of the bounding box

Usage:

- layer.with_bbox_min(min .. max)
- layer.with_bbox_min(value)
- layer.with_bbox_min(min, max)

The method selects polygons similar to with_area or with_perimeter. However, the measured dimension is the minimum dimension of the bounding box. The minimum dimension is either the width or height of the bounding box, whichever is smaller.

This method is available for polygon layers only.

## "with_bbox_width" - Selects polygons by the width of the bounding box

Usage:

- layer.with_bbox_width(min .. max)
- layer.with_bbox_width(value)
- layer.with_bbox_width(min, max)

The method selects polygons similar to with_area or with_perimeter. However, the measured dimension is the width of the bounding box.

This method is available for polygon layers only.

## "with_density" - Returns tiles whose density is within a given range

Usage:

- layer.with_density(min_value, max_value [, options ])
- layer.with_density(min_value .. max_value [, options ])

This method runs a tiled analysis over the current layout. It reports the tiles whose density is between "min_value" and "max_value". "min_value" and "max_value" are given in relative units, i.e. within the range of 0 to 1.0 corresponding to a density of 0 to 100%.

"min_value" or "max_value" can be nil or omitted in the ".." range notation. In this case, they are taken as "0" and "100%".

The tile size must be specified with the "tile_size" option:

    # reports areas where layer 1/0 density is below 10% on 20x20 um tiles
    low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um))

Anisotropic tiles can be specified by giving two values, like "tile_size(10.um, 20.um)". The first value is the horizontal tile dimension, the second value is the vertical tile dimension.

A tile overlap can be specified using "tile_step". If the tile step is less than the tile size, the tiles will overlap. The layout window given by "tile_size" is moved in increments of the tile step:

    # reports areas where layer 1/0 density is below 10% on 30x30 um tiles
    # with a tile step of 20x20 um:
    low_density = input(1, 0).density(0.0 .. 0.1, tile_size(30.um), tile_step(20.um))

For "tile_step", anisotropic values can be given as well by using two values: the first for the horizontal and the second for the vertical tile step.

Another option is "tile_origin" which specifies the location of the first tile's position. This is the lower left tile's lower left corner. If no origin is given, the tiles are centered over the area investigated.

By default, the tiles will cover the bounding box of the input layer. A separate layer can be used in addition. This way, the layout's dimensions can be derived from some drawn boundary layer. To specify a separate, additional layer included in the bounding box, use the "tile_boundary" option:

    # reports density of layer 1/0 below 10% on 20x20 um tiles. The layout's boundary is taken from
    # layer 0/0:
    cell_frame = input(0, 0)
    low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), tile_boundary(cell_frame))

Note that the layer given in "tile_boundary" adds to the input layer for computing the bounding box. The computed area is at least the area of the input layer.

Computation of the area can be skipped by explicitly giving a tile count in horizontal and vertical direction. With the "tile_origin" option this allows full control over the area covered:

    # reports density of layer 1/0 below 10% on 20x20 um tiles in the region 0,0 .. 2000,3000
    # (100 and 150 tiles of 20 um each are used in horizontal and vertical direction):
    low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), tile_origin(0.0, 0.0), tile_count(100, 150))

The complementary version of "with_density" is without_density.

## "with_holes" - Selects all polygons with the specified number of holes

Usage:

- layer.with_holes(count)
- layer.with_holes(min_count, max_count)
- layer.with_holes(min_count .. max_count)

This method is available for polygon layers. It will select all polygons from the input layer which have the specified number of holes.

## "with_length" - Selects edges by their length

Usage:

- layer.with_length(min .. max)
- layer.with_length(value)
- layer.with_length(min, max)

The method selects edges by their length. The first version selected edges with a length larger or equal to min and less than max (but not equal). The second version selects edges with exactly the given length. The third version is similar to the first one, but allows specification of nil for min or max indicating that there is no lower or upper limit.

This method is available for edge layers only.

## "with_perimeter" - Selects polygons by perimeter

Usage:

- layer.with_perimeter(min .. max)
- layer.with_perimeter(value)
- layer.with_perimeter(min, max)

The first form will select all polygons with an perimeter larger or equal to min and less (but not equal to) max. The second form will select the polygons with exactly the given perimeter. The third form basically is equivalent to the first form, but allows specification of nil for min or max indicating no lower or upper limit.

This method is available for polygon layers only.

## "with_relative_height" - Selects polygons by the ratio of the height vs. width of it's bounding box

Usage:

- layer.with_relative_height(min .. max)
- layer.with_relative_height(value)
- layer.with_relative_height(min, max)

The relative height is a measure how tall a polygon is. Tall polygons have values larger than 1, wide polygons have a value smaller than 1. Squares have a value of 1.

Don't use this method when you can use with_area_ratio, which provides a similar measure but is isotropic.

This method is available for polygon layers only.

## "without_angle" - Selects edges by the their angle

Usage:

- layer.without_angle(min .. max)
- layer.without_angle(value)
- layer.without_angle(min, max)

The method basically is the inverse of with_angle. It selects all edges of the edge layer or corners of the polygons which do not have the given angle (second form) or whose angle is not inside the given interval (first and third form).

## "without_area" - Selects polygons by area

Usage:

- layer.without_area(min .. max)
- layer.without_area(value)
- layer.without_area(min, max)

This method is the inverse of "with_area". It will select polygons without an area equal to the given one or outside the given interval.

This method is available for polygon layers only.

## "without_area_ratio" - Selects polygons by the aspect ratio of their bounding box

Usage:

- layer.without_area_ratio(min .. max)
- layer.without_area_ratio(value)
- layer.without_area_ratio(min, max)

The method provides the opposite filter for with_area_ratio.

This method is available for polygon layers only.

## "without_bbox_height" - Selects polygons by the aspect ratio of their bounding box

Usage:

- layer.without_bbox_aspect_ratio(min .. max)
- layer.without_bbox_aspect_ratio(value)
- layer.without_bbox_aspect_ratio(min, max)

The method provides the opposite filter for with_bbox_aspect_ratio.

This method is available for polygon layers only.

## "without_bbox_max" - Selects polygons by the maximum dimension of the bounding box

Usage:

- layer.without_bbox_max(min .. max)
- layer.without_bbox_max(value)
- layer.without_bbox_max(min, max)

The method selects polygons similar to without_area or without_perimeter. However, the measured dimension is the maximum dimension of the bounding box. The minimum dimension is either the width or height of the bounding box, whichever is larger.

This method is available for polygon layers only.

## "without_bbox_min" - Selects polygons by the minimum dimension of the bounding box

Usage:

- layer.without_bbox_min(min .. max)
- layer.without_bbox_min(value)
- layer.without_bbox_min(min, max)

The method selects polygons similar to without_area or without_perimeter. However, the measured dimension is the minimum dimension of the bounding box. The minimum dimension is either the width or height of the bounding box, whichever is smaller.

This method is available for polygon layers only.

## "without_bbox_width" - Selects polygons by the width of the bounding box

Usage:

- layer.without_bbox_width(min .. max)
- layer.without_bbox_width(value)
- layer.without_bbox_width(min, max)

The method selects polygons similar to without_area or without_perimeter. However, the measured dimension is the width of the bounding box.

This method is available for polygon layers only.

## "without_density" - Returns tiles whose density is not within a given range

Usage:

- layer.without_density(min_value, max_value [, options ])
- layer.without_density(min_value .. max_value [, options ])

For details about the operations and the operation see with_density. This version will return the tiles where the density is not within the given range.

## "without_holes" - Selects all polygons with the specified number of holes

Usage:

- layer.without_holes(count)
- layer.without_holes(min_count, max_count)
- layer.without_holes(min_count .. max_count)

This method is available for polygon layers. It will select all polygons from the input layer which do not have the specified number of holes.

## "without_length" - Selects edges by the their length

Usage:

- layer.without_length(min .. max)
- layer.without_length(value)
- layer.without_length(min, max)

The method basically is the inverse of with_length. It selects all edges of the edge layer which do not have the given length (second form) or are not inside the given interval (first and third form).

This method is available for edge layers only.

## "without_perimeter" - Selects polygons by perimeter

Usage:

- layer.without_perimeter(min .. max)
- layer.without_perimeter(value)
- layer.without_perimeter(min, max)

This method is the inverse of "with_perimeter". It will select polygons without a perimeter equal to the given one or outside the given interval.

This method is available for polygon layers only.

## "without_relative_height" - Selects polygons by the ratio of the height vs. width

Usage:

- layer.without_relative_height(min .. max)
- layer.without_relative_height(value)
- layer.without_relative_height(min, max)

The method provides the opposite filter for with_relative_height.

This method is available for polygon layers only.

## "xor" - Boolean XOR operation

Usage:

- layer.xor(other)

The method computes a boolean XOR between self and other. It is an alias for the "^" operator.

This method is available for polygon and edge layers.

The following images show the effect of the "xor" method on polygons and edges (input1: red, input2: blue):

## "|" - Boolean OR operation

Usage:

- self | other

The method computes a boolean OR between self and other. A similar operation is join which will basically gives the same result but won't merge the shapes.

This method is available for polygon and edge layers. An alias is "or". See there for a description of the function.