Layout queries are an advanced feature of KLayout which provides a very generic method to manipulate or search the geometrical or cell information of a layout. The basic concept of custom queries is borrowed from SQL, the language widely used for accessing databases. Instead of working on linear tables with rows and columns, KLayout's queries work on the layout structure which basically a cell tree, a layer set orthogonal to that and per-cell/per-layer geometrical information which itself is divided into shape classes.
Layout queries have a layered structure, like an onion: the core of the query is a cell query which selects one or many cells with or without their children. The cell query can be wrapped by a shape query which addresses the shapes of the selected cells or instances, optionally confined to specific layers. The last layer is formed by the action: this is the activity that KLayout will perform on the selected objects. The default action is simply to report the results. It is also possible to delete the selected objects or to perform a custom operation on them.
On cell and shape level, conditions can be specified which will restrict the operation on a subset of the selected objects. Reports can be sorted by a arbitrary key derived from the current object.
On cell level three different relationship models are supported:
Expressions play an important part in layout queries, both as actions (assignment type expressions) as well as conditions or for the derivation of sorting keys. See About Expressions for details about expressions. Within expressions, RBA objects are used to represent shapes or instances (see Class Index for a list of classes available). Depending on the context of the query, a variety of functions is available to access the properties of the current item and context.
The key to layout queries is the "Search and Replace" feature: this dialog uses custom queries to emulate simple search and replace functionality on the first three tabs of the dialog ("Delete" is regarded as a special kind of "replacement" here). However, the true power is revealed on the forth page: here you can enter all kind of custom queries. Clicking on "Execute" will run the query and display the results in the right panel.
If a search or replace action is specified on the first three tabs, the corresponding custom layout query will be shown in the entry box of the forth one. That way it is very easy to create a first query using the standard functions, switch to the custom query page and adjust it to fit the specific requirements.
The very core of a query is a cell expression. The most simple form of a cell expression is a simple cell name. This expression will select the cell called "RINGO":
RINGO
Cell expressions can contain wildcard in the "glob" form made popular by the Unix and Windows command line. "*" is for an arbitrary sequence of zero to many characters, "?" for any single character. "{A,B,C}" is for either the character sequence "A", "B" or "C", "[ABC]" is any of the characters "A", "B" or "C" and "[^ABC]" is for any character not "A", "B" or "C". Round brackets can be used to group parts of the string for later reference. If brackets of any kind are used inside a match string, either single or double quotes should be used around match strings in order to avoid ambiguities with other parts of the query syntax.
This expression will select all cells starting with "T":
T*
Although it is not necessary to do so, it is recommended to mark a cell query explicitly as such using the optional "cells" or "cell" keyword. This query has the same effect than the previous one but is somewhat more robust if used in nested queries we will learn about later:
cells T*
A cell expression can already be used by its own. The report of such a query will simply contain the cells selected by that expression. If combined with an action, such expressions already provide useful manipulation functionality.
The "delete ..." action will delete the given cells:
delete cells T*
The "with .. do ..." action can be used to manipulate the cell. This example will rename the cell by replacing the "T" prefix with a "S". The part after "do" is an expression which is evaluated for each hit. Note that "$1" is used to refer to the first matching bracket in the last match. "cell.name" is a method call on the object "cell" which is provided by the query in the context of a cell query. "cell" is a "Cell" object (see Cell) and setting the name will basically rename the cell. The expression used for the assignment will put an "S" in front of the rear part of the name, hence replace "T" by "S":
with cells "T(*)" do cell.name = "S"+$1
Note the quotes around the "T(*)" match expression. They are necessary to make the brackets part of the match expression rather than the cell query. It is usually a good idea to put the match expression inside quotes to avoid ambiguities.
The last example already demonstrates how a combination of two simple concepts - simple cell queries and expressions - form a new and very generic feature. We will soon learn about the power of that concept.
Cell queries are the most simple form of core queries. The next level is entered by extending the concept to hierarchies. Cell hierarchies come on two flavors: a parent-to-child relationship tree (the cell tree) and the instantiation tree. In the cell tree, each cell is at most present once in the context of a parent cell, independent of the number of times a cell is used inside a parent cell. The cell tree just describes the fact that a cell is a child cell of another, not how the cell is used. The instance tree adds this detailed information as well: how many times a cell is used and what transformations are applied per such instance.
The cell tree can be accessed within cell queries using the "." operator to separate parent and child cell. The following cell query returns all cells which are children of a cell "A":
cells A.*
Multiple levels may be nested, for example the following query lists all cells which are second-level children of the "A" cell:
cells A.*.*
Such expressions form a "path" leading from an initial cell to some cell, which is returned by the query. The "." separates the path elements like the slash or backslash does in a file path.
Top cells can be addressed by a leading "." similar to the leading slash of an absolute file path in Unix. The following query will return all top cells:
cells .*
Brackets can be used to group parts of the path. That has no immediate effect, but it can be usedful in combination with quantifiers and branches as we will see soon. The following queries are equivalent:
cells TOP.*.A cells TOP(.*.A) cells TOP(.*)(.A)
Please note that brackets can only be put between the dot and the previous element. A query like "cells TOP.(*.A)" is invalid since the opening bracket is after the dot.
Alternative paths can be specified by separating them with a comma. Such alternatives must be put inside brackets. For example, this query selects all cells that are children of "TOP" and start with an "A" or which are second-level children and start with an "E":
cells TOP(.A*,.*.E*)
Path elements can be made optional with a "?" symbol and expanded an variable number of times using quantifiers like "*" (0 to many) and "+" (one to many) or "{n,m}" (n to m times). Note that you'll have to put the expression subject to the quantifier in brackets in order to avoid ambiguities of the star operator. The following expression will return the A cell in every possible child context of "TOP", i.e. as direct child, second-level child and so on:
cells TOP(.*)*.A
To understand that query, note that the "*" inside the brackets is forming the match string while the outer star is forming the quantifier. That query reads in expanded form "TOP.A", "TOP.*.A", "TOP.*.*.A" etc.
There is a useful abbreviation for the above case. The following query will also produce "A" in every child context of "TOP":
cells TOP..A
The double dot operator matches an arbitrary part of the instantiation path before and after a cell even without being anchored at one end. Used before a cell name, it will return all contexts a cell is used in (including top cells and all child contexts). Used after a cell, it will return the cell plus all child cells in each possible context. Used before a cell it will deliver all contexts that cell is used in every top cells. The following query will deliver "TOP" plus all its direct and indirect children:
cells TOP..
Note that the previous query may deliver the same cell multiple times - once for each context (call path from TOP) it is used in. Hence "TOP.." will basically expand into the cell tree with "TOP" as the root.
In order to get the names of all cells called from a given cell, you can use the "select" action with the cell name and the "sorted by .. unique" output selector to remove duplicates of cell names:
select cell_name of cells TOP.. sorted by cell_name unique
See below for a description of the "select" action.
Within a path, dynamically computed components can be inserted using the "$(..)" notation which wraps an expression. That expression is evaluated in the context of the previous path component. For example, the following query selects all child cells which are named like their parent with an "A" prefix:
cells *.$("A"+cell_name)
Cell trees can be expanded into instance trees simply by prepending "instances". This will deliver all direct instances of "TOP":
instances of TOP.*
When asking for instances, more information is available inside the query. For example, the instance's orientation and position is available. With the "instances" specification, array references are expanded into single instances. To keep arrays as such, use "arrays" instead of "instances":
arrays of TOP.*
Cell or instance queries can be filtered using the "where" clause. After the "where" an expression is expected with a number of predefined variables that reflect the context (see below for the variables available). The following query selects all child cells of "A" where the cell name has a length of 5 characters:
cells A.* where len(cell_name)==5
So far we have dealt with cells and their instantiations. We enter the next level now by introducing shapes.
Shape queries are built atop of the cell/instance level. A simple example selects all shapes of the cell "TOP":
shapes of cell TOP
Shape queries can be confined to certain shape types. For example, this confines the query to boxes:
boxes from cell TOP
Allowed shape type are "boxes", "polygons", "texts" and "paths". In the context of a shape query additional variables are available for expressions. The most important one is "shape" which is a Shape object (see Shape) That objects provides access to the shape addressed in a generic way. Specialization to a specific shape type is possible through the shape specific accessor methods (i.e. "shape.box_width") or the specific objects (i.e. "shape.box").
Multiple shape types can be given with "or" or a comma:
boxes or polygons from cell TOP
Shape queries can be confined to certain layers. This query will report all shapes from layer 8, datatype 0:
shapes on layer 8/0 from cell TOP
Intervals can be specified with the hyphen ("-") and multiple layers or intervals can be listed with a comma or semicolon. The following will list the shapes from layer 8, datatype 0 to 10 and layer 9, datatype 0 only (note that "no datatype" is interpreted as datatype 0):
shapes on layer 8/0-10, 9 from cell TOP
For formats that support named layers only (i.e. DXF), the layer name can be given. The following query lists shapes from layers METAL and POLY (case sensitive!):
shapes on layer METAL, POLY from cell TOP
Any kind of cell query can be used inside the shape query. If a cell query renders multiple cells, the shape query will be applied to each of the cells returned. If instances are selected by the cell query, the shapes will be reported for each instance. Since the cumulated transformation of a specific instance into the top cell is available through the "path_trans" (database units) or "path_dtrans" (micrometer units) variable, it is possible to transform each shape into the top cell in the instance case. The following expression combines a "with .. do" action with a shape query to flatten all shapes below "TOP":
with shapes on layer 6 from instances of TOP.. do initial_cell.shapes(<10/0>).insert(shape).transform(path_trans)
That expression reads all shapes of cell "TOP" and its children, inserts them into a new layer 10, datatype 0 and transforms the shape after it has been inserted. This expression makes use of the variables "initial_cell" (a Cell object representing the root cell of the cell query), "shape" (a pointer to the currently selected shape and "path_trans" (a Trans object representing the transformation of the current shape into the root cell of the query). It also employs the angle bracket layer constant notation which specifies a layer in the target notation and can be used in place of the layer index value usually used inside the API. Note that the target layer must exist already, i.e. must have been created in "Edit/Layer/New Layer" for example.
Shape queries can be confined with conditions. A condition is entered with a "where" clause plus an expression that selects the shapes. This condition selects shapes with an area of more than 4 square micron (note that the "um2" unit must be given, since it will cause the value to be converted into the database units used internally):
shapes from cell TOP where shape.area < 4 um2
Shape conditions can be combined with cell conditions. To avoid ambiguities, the cell query must be put into brackets in that case:
shapes from (cells * where len(cell_name)==4) where shape.area < 4 um2
Actions specify operations that are to be performed on the results of a query. The default action is to just list the results. In the "Search and replace" dialog, the results will be listed right to the query entry box as a table. Depending on the context of the query, cell names, cell names plus parent cell, cell instances or shapes are listed.
The "select" action will compute one or more results from each item returned by the query and present the computed value in a table. The general form is:
select expr1, expr2, ... from query
"expr1", "expr2" ... are expressions. For example this action computes area and perimeter for all shapes of cell "TOP":
select shape.area, shape.perimeter from shapes of cell TOP
The "select" action offers sorting with optional reduction to unique values:
select expr1, expr2, ... from query sorted by sort_key
select expr1, expr2, ... from query sorted by sort_key unique
Here "sort_key" is an expression which delivers the value by which the output will be sorted. If "unique" is specified, items with identical sort key are reduced to a single output.
The "with" action executes an expression on each item returned by the expression. In that sense it is basically equivalent to the "select" action but the results of the operation are discarded and the intention of the expression is to modify the results. The general form of that action is this:
with query do expr
For example, this action will move all shapes of cell "TOP" from layer 6 to layer 10, datatype 0:
with shapes on layer 6 of cell TOP do shape.layer = <10/0>
This action will simply delete the objects selected by the query:
delete query
For example, this query deletes all shapes from layer 6, datatype 0 on cell TOP:
delete shapes on layer 6 of cell TOP
The following variables are available in all queries:
Name | Value type | Description |
---|---|---|
layout | Layout | The layout object that this query runs on. |
In the plain cell and cell tree context, the following variables are available:
Name | Value type | Description |
---|---|---|
path | Array | Array with the indexes of the cells in that path. For a plain cell, this array will have length 1 and contain the index of the selected cell only. |
path_names | Array | Array with the names of the cells in that path. For a plain cell, this array will have length 1 and contain the name of the selected cell only. |
initial_cell | Cell | Object representing the initial cell (first of path) |
initial_cell_index | Integer | Index of initial cell (first of path) |
initial_cell_name | String | Name of initial cell (first of path) |
cell | Cell | Object representing the current cell (last of path) |
cell_index | Integer | Index of current cell (last of path) |
cell_name | String | Name of current cell (last of path) |
hier_levels | Integer | Number of hierarchy levels in path (length of path - 1) |
references | Integer | The number of instances of this cell in the parent cell. Array references count as 1. For plain cells, this value is 0. |
weight | Integer | The number of instances of this cell in the parent cell. Array references count as multiple instances. For plain cells, this value is 0. |
tot_weight | Integer | The number of instances of this cell in the initial cell along the given path. Array references count as multiple instances. for plain cells, this value is 0. |
instances | Integer | Equivalent to "weight", but also available for plain cells. For plain cells, the value represents the number of times, the cell is used in all top cells. |
bbox | Box | The cell's bounding box. |
dbbox | DBox | The cell's bounding box in micrometer units. |
cell_bbox | Box | Same as "bbox" (disambiguator from shape and instance bounding boxes). |
cell_dbbox | DBox | Same as "dbbox" (disambiguator from shape and instance bounding boxes). |
In an instance query context, the properties of the current instance are available as variables in addition to most of the ones provided by the cell query context. These variables are not available in instance context: "weight", "references" and "tot_weight". Apart from that these additional variable are provided:
Name | Value type | Description |
---|---|---|
path_trans | ICplxTrans | The transformation of that instance into the top cell. For a plain cell that is a unit transformation. |
path_dtrans | DCplxTrans | The transformation of that instance into the top cell in micrometer units. For a plain cell that is a unit transformation. |
trans | ICplxTrans | The transformation of that instance (first instance if an array). |
dtrans | DCplxTrans | The transformation of that instance (first instance if an array) in micrometer units. |
inst_bbox | Box | The instance bounding box in the initial cell. |
inst_dbbox | DBox | The instance bounding box in the initial cell in micrometer units. |
inst | Instance | The instance object of the current instance. |
array_a | Vector | The a vector for an array instance or nil if the instance is not an array. |
array_da | DVector | The a vector for an array instance in micrometer units or nil if the instance is not an array. |
array_na | Integer | The a axis array dimension or nil if the instance is not an array. |
array_b | Vector | The b vector for an array instance or nil if the instance is not an array. |
array_db | DVector | The b vector for an array instance in micrometer units or nil if the instance is not an array. |
array_nb | Integer | The b axis array dimension or nil if the instance is not an array. |
array_ia | Integer | The a index when an array is iterated (0 to array_na). Not available with instance queries with "arrays of ...". |
array_ib | Integer | he b index when an array is iterated (0 to array_nb). Not available with instance queries with "arrays of ...". |
In the context of the shape query, the following variables are available in addition to the variables made available by the inner cell query. The inner cell query is either a instance query or a cell query:
Name | Value type | Description |
---|---|---|
bbox | DBox | The shape's bounding box |
dbbox | DBox | The shape's bounding box in micrometer units |
shape_bbox | Box | Same as "bbox" (disambiguator for cell or instance bounding boxes) |
shape_dbbox | DBox | Same as "dbbox" (disambiguator for cell or instance bounding boxes) |
shape | Shape | The shape object |
layer_info | LayerInfo | The layer description of the current shape's layer |
layer_index | Integer | The layer index of the current shape |