DRC expression objects represent abstract recipes for the Layer#drc universal DRC function. For example, when using a universal DRC expression like this:

out = in.drc(width < 2.0)

"width < 2.0" forms a DRC expression object. DRC expression objects have methods which manipulate or evaluate the results of this expression. In addition, DRC expressions have a result type, which is either polygon, edge or edge pair. The result type is defined by the expression generating it. In the example above, "width < 2.0" is a DRC width check which renders edge pairs. To obtain polygons from these edge pairs, use the "polygons" method:

out = in.drc((width < 2.0).polygons)

The following global functions are relevant for the DRC expressions:

- angle
- area
- area_ratio
- bbox_area_ratio
- bbox_height
- bbox_max
- bbox_min
- bbox_width
- case
- corners
- covering
- enc
- enclosing
- extent_refs
- extents
- foreign
- holes
- hulls
- if_all
- if_any
- if_none
- inside
- interacting
- iso
- length
- middle
- notch
- outside
- overlap
- overlapping
- perimeter
- primary
- rectangles
- rectilinear
- relative_height
- rounded_corners
- secondary
- separation
- sep
- sized
- smoothed
- space
- squares
- width
- with_holes

The following documentation will list the methods available for DRC expression objects.

- "!" - Logical not
- "&" - Boolean AND between the results of two expressions
- "+" - Boolean OR between the results of two expressions
- "-" - Boolean NOT between the results of two expressions
- "angle" - Selects edges based on their angle
- "area" - Selects the primary shape if the area is meeting the condition
- "area_ratio" - Selects the input polygon according to its area ratio (bounding box area by polygon area)
- "area_sum" - Selects the input polygons if the sum of all areas meets the condition
- "bbox_aspect_ratio" - Selects the input polygon according to the aspect ratio of the bounding box
- "bbox_height" - Selects the input polygon if its bounding box height is meeting the condition
- "bbox_max" - Selects the input polygon if its bounding box larger dimension is meeting the condition
- "bbox_min" - Selects the input polygon if its bounding box smaller dimension is meeting the condition
- "bbox_width" - Selects the input polygon if its bounding box width is meeting the condition
- "centers" - Returns the part at the center of each edge of the input
- "corners (in condition)" - Applies smoothing
- "count" - Selects a expression result based on the number of (local) shapes
- "covering" - Selects shapes entirely covering other shapes
- "edges" - Converts the input shapes into edges
- "end_segments" - Returns the part at the end of each edge of the input
- "extended" - Returns polygons describing an area along the edges of the input
- "extended_in" - Returns polygons describing an area along the edges of the input
- "extended_out" - Returns polygons describing an area along the edges of the input
- "extent_refs" - Returns partial references to the bounding boxes of the polygons
- "extents" - Returns the bounding box of each input object
- "first_edges" - Returns the first edges of edge pairs
- "holes" - Selects all holes from the input polygons
- "hulls" - Selects all hulls from the input polygons
- "inside" - Selects shapes entirely inside other shapes
- "interacting" - Selects shapes interacting with other shapes
- "length" - Selects edges based on their length
- "length_sum" - Selects the input edges if the sum of their lengths meets the condition
- "merged" - Returns the merged input polygons, optionally selecting multi-overlap
- "middle" - Returns the centers of polygon bounding boxes
- "outside" - Selects shapes entirely outside other shapes
- "overlapping" - Selects shapes overlapping with other shapes
- "perimeter" - Selects the input polygon if the perimeter is meeting the condition
- "perimeter_sum" - Selects the input polygons if the sum of all perimeters meets the condition
- "polygons" - Converts the input shapes into polygons
- "rectangles" - Selects all polygons which are rectangles
- "rectilinear" - Selects all polygons which are rectilinear
- "relative_height" - Selects the input polygon according to the height vs. width of the bounding box
- "rounded_corners" - Applies corner rounding
- "second_edges" - Returns the second edges of edge pairs
- "sized" - Returns the sized version of the input
- "smoothed" - Applies smoothing
- "squares" - Selects all polygons which are squares
- "start_segments" - Returns the part at the beginning of each edge of the input
- "with_holes" - Selects all input polygons with the specified number of holes
- "|" - Boolean OR between the results of two expressions

Usage:

`! expression`

This operator will evaluate the expression after. If this expression renders an empty result, the operator will return the primary shape. Otherwise it will return an empty result.

This operator can be used together with predicates such a "rectangles" to invert their meaning. For example, this code selects all primary shapes which are not rectangles:

out = in.drc(! rectangles) out = in.drc(! primary.rectangles) # equivalent

Usage:

`expression & expression`

The & operator will compute the boolean AND between the results of two expressions. The expression types need to be edge or polygon.

The following example computes the partial edges where width is less than 0.3 micrometers and space is less than 0.2 micrometers:

out = in.drc((width < 0.3).edges & (space < 0.2).edges)

Usage:

`expression + expression`

The + operator will join the results of two expressions.

Usage:

`expression - expression`

The - operator will compute the difference between the results of two expressions. The NOT operation is defined for polygons, edges and polygons subtracted from edges (first argument edge, second argument polygon).

CAUTION: be careful not to take secondary input for the first argument. This will not render the desired results. Remember that the "drc" function will walk over all primary shapes and present single primaries to the NOT operation together with the secondaries of that single shape. So when you use secondary shapes as the first argument, they will not see all all the primaries required to compute the correct result. That's also why a XOR operation cannot be provided in the context of a generic DRC function.

The following example will produce edge markers where the width of is less then 0.3 micron but not inside polygons on the "waive" layer:

out = in.drc((width < 0.3).edges - secondary(waive))

Usage:

`expression.angle (in condition)`

This operation 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 degrees. The angle range is from -90 (exclusive) to 90 degree (inclusive).

If the input shapes are not polygons or edge pairs, they are converted to edges before the angle test is made.

For example, the following code selects all edges from the primary shape which are 45 degree (up) or 135 degree (down). The "+" will join the results:

out = in.drc((angle == 45) + (angle == 135)) out = in.drc((primary.angle == 45) + (primary.angle == 135)) # equivalent

Note that angle checks usually imply the need to rotation variant formation as cells which are placed non-rotated and rotated by 90 degree cannot be considered identical. This imposes a performance penalty in hierarchical mode. If possible, consider using DRC#rectilinear for example to detect shapes with non-manhattan geometry instead of using angle checks.

The "angle" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.angle".

Usage:

`expression.area (in condition)`

This operation is used in conditions to select shapes based on their area. It is applicable on polygon expressions. The result will be the input polygons if the area condition is met.

See Layer#drc for more details about comparison specs.

The following example will select all polygons with an area less than 2.0 square micrometers:

out = in.drc(area < 2.0) out = in.drc(primary.area < 2.0) # equivalent

The area method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.area".

Usage:

`expression.area_ratio (in condition)`

This operation is used in conditions to select shapes based on their area ratio. The area ratio is the ratio of bounding box vs. polygon area. It's a measure how "sparse" the polygons are and how good an approximation the bounding box is. The value is always larger or equal than 1. Boxes have a value of 1.

This filter is applicable on polygon expressions. The result will be the input polygon if the condition is met.

See Layer#drc for more details about comparison specs.

The following example will select all polygons whose area ratio is larger than 3:

out = in.drc(area_ratio > 3) out = in.drc(primary.area_ratio > 3) # equivalent

The "area_ratio" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.area_ratio".

Usage:

`expression.area_sum (in condition)`

Returns the input polygons if the sum of their areas meets the specified condition. This condition is evaluated on the total of all shapes generated in one step of the "drc" loop. As there is a single primary in each loop iteration, "primary.area_sum" is equivalent to "primary.area".

See Layer#drc for more details about comparison specs.

Usage:

`expression.bbox_aspect_ratio (in condition)`

This operation is used in conditions to select shapes based on aspect ratios of their bounding boxes. The aspect ratio is computed by dividing the larger of width and height by the smaller of both. The aspect ratio is always larger or equal to 1. Square or square-boxed shapes have a bounding box aspect ratio of 1.

This filter is applicable on polygon expressions. The result will be the input polygon if the bounding box condition is met.

See Layer#drc for more details about comparison specs.

The following example will select all polygons whose bounding box aspect ratio is larger than 3:

out = in.drc(bbox_aspect_ratio > 3) out = in.drc(primary.bbox_aspect_ratio > 3) # equivalent

The "bbox_aspect_ratio" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.bbox_aspect_ratio".

Usage:

`expression.bbox_height (in condition)`

This operation acts similar to DRC#bbox_min, but takes the height of the shape's bounding box. In general, it's more advisable to use DRC#bbox_min or DRC#bbox_max because bbox_height implies a certain orientation. This can imply variant formation in hierarchical contexts: cells rotated by 90 degree have to be treated differently from ones not rotated. This usually results in a larger computation effort and larger result files.

The "bbox_height" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.bbox_height".

Usage:

`expression.bbox_max (in condition)`

This operation acts similar to DRC#bbox_min, but takes the larger dimension of the shape's bounding box.

The "bbox_max" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.bbox_max".

Usage:

`expression.bbox_min (in condition)`

This operation is used in conditions to select shapes based on smaller dimension of their bounding boxes. It is applicable on polygon expressions. The result will be the input polygons if the bounding box condition is met.

See Layer#drc for more details about comparison specs.

The following example will select all polygons whose bounding box smaller dimension is larger than 200 nm:

out = in.drc(bbox_min > 200.nm) out = in.drc(primary.bbox_min > 200.nm) # equivalent

The "bbox_min" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.bbox_min".

Usage:

`expression.bbox_width (in condition)`

This operation acts similar to DRC#bbox_min, but takes the width of the shape's bounding box. In general, it's more advisable to use DRC#bbox_min or DRC#bbox_max because bbox_width implies a certain orientation. This can imply variant formation in hierarchical contexts: cells rotated by 90 degree have to be treated differently from ones not rotated. This usually results in a larger computation effort and larger result files.

The "bbox_width" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.bbox_width".

Usage:

`expression.centers(length)``expression.end_segments(length, fraction)`

This method acts on edge expressions and delivers a specific part of each edge. See layer#centers for details about this functionality.

Usage:

`expression.corners``expression.corners(as_dots)``expression.corners(as_boxes)`

This operation acts on polygons and selects the corners of the polygons. It can be put into a condition to select corners by their angles. The angle of a corner is positive for a turn to the left if walking a polygon counterclockwise and negative for the turn to the right. Angles take values between -180 and 180 degree.

When using "as_dots" for the argument, the operation will return single-point edges at the selected corners. With "as_boxes" (the default), small (2x2 DBU) rectangles will be produced at each selected corner.

The following example selects all corners:

out = in.drc(corners) out = in.drc(primary.corners) # equivalent

The following example selects all inner corners:

out = in.drc(corners < 0) out = in.drc(primary.corners < 0) # equivalent

The "corners" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.corners".

Usage:

`expression.count (in condition)`

This operation is used in conditions to select expression results based on their count. "count" is used as a method on a expression. It will evaluate the expression locally and return the original result if the shape count in the result is matching the condition.

See Layer#drc for more details about comparison specs.

Note that the expression is evaluated locally: for each primary shape, the expression is evaluated and the count of the resulting edge, edge pair or polygon set is taken. As the primary input will always have a single item (the local shape), using "count" on primary does not really make sense. It can be used on derived expressions however.

The following example selects triangles:

out = in.drc(if_any(corners.count == 3))

Note "if_any" which selects the primary shape if the argument evaluates to a non-empty result. Without "if_any" three corners are returned for each triangle.

Usage:

`expression.covering(other) (optionally in conditions)``covering(other) (optionally in conditions)`

This method represents the selector of primary shapes which entirely cover shapes from the other layer. This version can be put into a condition indicating how many shapes of the other layer need to be covered. Use this variant within DRC expressions (also see Layer#drc).

For example, the following statement selects all input shapes which entirely cover shapes from the "other" layer:

out = in.drc(covering(other))

This example selects all input shapes which entire cover shapes from the other layer and there are more than two shapes from "other" inside primary shapes:

out = in.drc(covering(other) > 2)

Usage:

`expression.edges`

Polygons will be separated into edges forming their contours. Edge pairs will be decomposed into individual edges.

Contrary most other operations, "edges" does not have a plain function equivalent as this is reserved for the function generating an edges layer. To generate the edges of the primary shapes, use "primary" explicit as the source for the edges:

out = in.drc(primary.edges)

Usage:

`expression.end_segments(length)``expression.end_segments(length, fraction)`

This method acts on edge expressions and delivers a specific part of each edge. See layer#end_segments for details about this functionality.

Usage:

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

This method acts on edge expressions. 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.

Usage:

`expression.extended_in(d)`

This method acts on edge expressions. 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.

Usage:

`expression.extended_out(d)`

This method acts on edge expressions. 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.

Usage:

`expression.extent_refs([ options ])`

The extent_refs operation acts on polygons and has the same effect than Layer#extent_refs. It takes the same arguments. It is available as a method on DRC expressions or as plain function, in which case it acts on the primary shapes.

Usage:

`expression.extents([ enlargement ])`

This method provides the same functionality as Layer#extents and takes the same arguments. It returns the bounding boxes of the input objects. It acts on edge edge pair and polygon expressions.

The "extents" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.extents".

Usage:

`expression.first_edges`

This method acts on edge pair expressions and returns the first edges of the edge pairs delivered by the expression.

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.

Usage:

`expression.holes`

This operation can be used as a plain function in which case it acts on primary shapes or can be used as method on another DRC expression. The following example selects all holes with an area larger than 2 square micrometers:

out = in.drc(holes.area > 2.um) out = in.drc(primary.holes.area > 2.um) # equivalent

Usage:

`expression.hulls`

The hulls are the outer contours of the input polygons. By selecting hulls only, all holes will be closed.

This operation can be used as a plain function in which case it acts on primary shapes or can be used as method on another DRC expression. The following example closes all holes:

out = in.drc(hulls) out = in.drc(primary.hulls) # equivalent

Usage:

`expression.inside(other)``inside(other)`

This method represents the selector of primary shapes which are entirely inside shapes from the other layer. Use this variant within DRC expressions (also see Layer#drc).

Usage:

`expression.interacting(other) (optionally in conditions)``interacting(other) (optionally in conditions)`

See covering for a description of the use cases for this function. When using "interacting", shapes are selected when the interact (overlap, touch) shapes from the other layer.

When using this method with a count, the operation may not render the correct results if the other input is not merged. By nature of the generic DRC feature, only those shapes that interact with the primary shape will be selected. If the other input is split into multiple polygons, not all components may be captured and the computed interaction count may be incorrect.

Usage:

`expression.length (in condition)`

This operation will select those edges which are meeting the length criterion. Non-edge shapes (polygons, edge pairs) will be converted to edges before.

For example, this code selects all edges from the primary shape which are longer or equal than 1 micrometer:

out = in.drc(length >= 1.um) out = in.drc(primary.length >= 1.um) # equivalent

The "length" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.length".

Usage:

`expression.length_sum (in condition)`

Returns the input edges if the sum of their lengths meets the specified condition. This condition is evaluated on the total of all edges generated in one step of the "drc" loop.

See Layer#drc for more details about comparison specs.

Usage:

`expression.merged``expression.merged(min_count)`

This operation will act on polygons. Without a min_count argument, the merged polygons will be returned.

With a min_count argument, the result will include only those parts where more than the given number of polygons overlap. As the primary input is merged already, it will always contribute as one.

The "merged" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.merged".

Usage:

`expression.middle([ options ])`

The middle operation acts on polygons and has the same effect than Layer#middle. It takes the same arguments. It is available as a method on DRC expressions or as plain function, in which case it acts on the primary shapes.

Usage:

`expression.outside(other)``outside(other)`

This method represents the selector of primary shapes which are entirely outside shapes from the other layer. Use this variant within DRC expressions (also see Layer#drc).

Usage:

`expression.overlapping(other) (optionally in conditions)``overlapping(other) (optionally in conditions)`

See covering for a description of the use cases for this function. When using "overlapping", shapes are selected when the overlap shapes from the other layer.

When using this method with a count, the operation may not render the correct results if the other input is not merged. By nature of the generic DRC feature, only those shapes that interact with the primary shape will be selected. If the other input is split into multiple polygons, not all components may be captured and the computed interaction count may be incorrect.

Usage:

`expression.perimeter (in condition)`

This operation is used in conditions to select shapes based on their perimeter. It is applicable on polygon expressions. The result will be the input polygons if the perimeter condition is met.

See Layer#drc for more details about comparison specs.

The following example will select all polygons with a perimeter less than 10 micrometers:

out = in.drc(perimeter < 10.0) out = in.drc(primary.perimeter < 10.0) # equivalent

The perimeter method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.perimeter".

Usage:

`expression.perimeter_sum (in condition)`

Returns the input polygons if the sum of their perimeters meets the specified condition. This condition is evaluated on the total of all shapes generated in one step of the "drc" loop. As there is a single primary in each loop iteration, "primary.perimeter_sum" is equivalent to "primary.perimeter".

See Layer#drc for more details about comparison specs.

Usage:

`expression.polygons([ enlargement ])`

Generates polygons from the input shapes. Polygons stay polygons. Edges and edge pairs are converted to polygons. For this, the enlargement parameter will specify the edge thickness or augmentation applied to edge pairs. With the default enlargement of zero edges will not be converted to valid polygons and degenerated edge pairs will not become valid polygons as well.

Contrary most other operations, "polygons" does not have a plain function equivalent as this is reserved for the function generating a polygon layer.

This method is useful for generating polygons from DRC violation markers as shown in the following example:

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

Usage:

`expression.rectangles`

This operation can be used as a plain function in which case it acts on primary shapes or can be used as method on another DRC expression. The following example selects all rectangles:

out = in.drc(rectangles) out = in.drc(primary.rectangles) # equivalent

Usage:

`expression.rectilinear`

Rectilinear polygons only have vertical and horizontal edges. Such polygons are also called manhattan polygons.

This operation can be used as a plain function in which case it acts on primary shapes or can be used as method on another DRC expression. The following example selects all manhattan polygons:

out = in.drc(rectilinear) out = in.drc(primary.rectilinear) # equivalent

Usage:

`expression.relative_height (in condition)`

This operation is used in conditions to select shapes based on the ratio of bounding box height vs. width. The taller the shape, the larger the value. Wide polygons have a value below 1. A square has a relative height of 1.

This filter is applicable on polygon expressions. The result will be the input polygon if the condition is met.

Don't use this method if you can use bbox_aspect_ratio, because the latter is isotropic and can be used hierarchically without generating rotation variants.

See Layer#drc for more details about comparison specs.

The following example will select all polygons whose relative height is larger than 3:

out = in.drc(relative_height > 3) out = in.drc(primary.relative_height > 3) # equivalent

The "relative_height" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.bbox_aspect_ratio".

Usage:

`expression.rounded_corners(inner, outer, n)`

This operation acts on polygons and applies corner rounding to the given inner and outer corner radius and the number of points n per full circle. See Layer#rounded_corners for more details.

The "rounded_corners" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.rounded_corners".

Usage:

`expression.second_edges`

This method acts on edge pair expressions and returns the second edges of the edge pairs delivered by the expression.

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.

Usage:

`expression.sized(d [, mode])``expression.sized(dx, dy [, mode]))`

This method provides the same functionality as Layer#sized and takes the same arguments. It acts on polygon expressions.

The "sized" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.sized".

Usage:

`expression.smoothed(d [, keep_hv ])`

This operation acts on polygons and applies polygon smoothing with the tolerance d. 'keep_hv' indicates whether horizontal and vertical edges are maintained. Default is 'no' which means such edges may be distorted. See Layer#smoothed for more details.

The "smoothed" method is available as a plain function or as a method on DRC expressions. The plain function is equivalent to "primary.smoothed".

Usage:

`expression.squares`

This operation can be used as a plain function in which case it acts on primary shapes or can be used as method on another DRC expression. The following example selects all squares:

out = in.drc(squares) out = in.drc(primary.squares) # equivalent

Usage:

`expression.start_segments(length)``expression.start_segments(length, fraction)`

This method acts on edge expressions and delivers a specific part of each edge. See layer#start_segments for details about this functionality.

Usage:

`expression.with_holes (in condition)`

This operation can be used as a plain function in which case it acts on primary shapes or can be used as method on another DRC expression. The following example selects all polygons with more than 2 holes:

out = in.drc(with_holes > 2) out = in.drc(primary.with_holes > 2) # equivalent

Usage:

`expression | expression`

The | operator will compute the boolean OR between the results of two expressions. '+' is basically a synonym. Both expressions must render the same type.