<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Python scripting — KLayout</title>
        <link>https://www.klayout.de/forum/</link>
        <pubDate>Sat, 14 Mar 2026 05:23:18 +0000</pubDate>
        <language>en</language>
            <description>Python scripting — KLayout</description>
    <atom:link href="https://www.klayout.de/forum/categories/python-scripting/feed.rss" rel="self" type="application/rss+xml"/>
    <item>
        <title>Map layer and datatype before writing a GDS</title>
        <link>https://www.klayout.de/forum/discussion/2853/map-layer-and-datatype-before-writing-a-gds</link>
        <pubDate>Tue, 10 Mar 2026 08:43:00 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>klayanoob</dc:creator>
        <guid isPermaLink="false">2853@/forum/discussions</guid>
        <description><![CDATA[<p>Hi everyone,</p>

<p>I am asking some help, because there is something that I can do using the GUI of klayout but I want to do it using a python script.<br />
Using the GUI in edit mode, I read a GDS, I go to Edit/Layer/Edit Layer Specification and I update the layer number and datatype of some layer before writing down a new GDS.</p>

<p>However I did not success to do it using a script in batch mode.<br />
The first thing I tried was to use a 'layer_map' from 'LoadLayoutOptions' but I do not retrieve the new layer in the written GDS.<br />
Then I thought I need to copy the layer content in a newly created layer and then remove the old layer. It could works but the thing is I would like to map many datatype layers into the same datatype (for example layer 4.0, 4.1 and 4.2 became 16.0). In that case, does that mean I should perform a boolean operation to get that unique layer ?</p>

<p>Should I dig in the 'layer_map' solution ? Should I switch to OR operation solution ? Or is there another wy to do it ? <br />
Thank you for your help</p>

<p>Note : Here is a trial with layer map</p>

<pre><code>import pya as kl

ly = kl.Layout()
option = kl.LoadLayoutOptions()
option.layer_map.map("*/* : *+12/0", 0)
ly.read("my_file.gds", option)
## Display layer and datatype
for layer_idx in ly.layer_indexes():
  info = ly.get_info(layer_idx)
  print("Layer "+info.name+" : ",info.layer, info.datatype)

ly.write("my_new_file.gds.gz")
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Setters for the Netlist Database Browser</title>
        <link>https://www.klayout.de/forum/discussion/2851/setters-for-the-netlist-database-browser</link>
        <pubDate>Mon, 09 Mar 2026 13:12:55 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>openorchestrator_dev</dc:creator>
        <guid isPermaLink="false">2851@/forum/discussions</guid>
        <description><![CDATA[<p>Hi everyone,</p>

<p>I am currently working on a Python Macro that can receive probes for Nets or Cells from a Schematic Editor by the name specified in the netlist.</p>

<p>I am resolving the name using the .lvsdb and would theoretically only need to set the selection to the corresponding  NetlistObjectsPath.</p>

<p>The documentation tells me that both selected_paths and current_path are setters (moving either one would work for my purpose).</p>

<p>Is there any workaround that would allow me to set the selected path in the Netlist Database Browser like a mouse click would without altering the C++ code?</p>

<p>Thank you very much in advance!</p>
]]>
        </description>
    </item>
    <item>
        <title>How to get the transfom of each instance to its refered cell</title>
        <link>https://www.klayout.de/forum/discussion/2849/how-to-get-the-transfom-of-each-instance-to-its-refered-cell</link>
        <pubDate>Fri, 27 Feb 2026 07:17:18 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>sysubeing</dc:creator>
        <guid isPermaLink="false">2849@/forum/discussions</guid>
        <description><![CDATA[<p><img src="https://www.klayout.de/forum/uploads/editor/3s/kbs5pzck5hoj.jpg" alt="" title="" /><br />
I have a layout with such hierarchy. How can I get the transfom of each instance to its refered cell(e.g. K01, K02) in python script?</p>
]]>
        </description>
    </item>
    <item>
        <title>vscode and klayout</title>
        <link>https://www.klayout.de/forum/discussion/2846/vscode-and-klayout</link>
        <pubDate>Sat, 14 Feb 2026 11:33:10 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>99happyman80</dc:creator>
        <guid isPermaLink="false">2846@/forum/discussions</guid>
        <description><![CDATA[<p>Hi I'm Erik <br />
I want to do python coding by using vscode envirionment with Klayout <br />
How can i do for that?</p>
]]>
        </description>
    </item>
    <item>
        <title>Macro for L/S</title>
        <link>https://www.klayout.de/forum/discussion/2845/macro-for-l-s</link>
        <pubDate>Thu, 12 Feb 2026 04:49:37 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Ajaymoreb</dc:creator>
        <guid isPermaLink="false">2845@/forum/discussions</guid>
        <description><![CDATA[<p>can anyone suggest macro to generate equidistance trace which will maintain overall  L/S  same..  Eg  I need trace width of 4u and between 2 trace 4u gap</p>
]]>
        </description>
    </item>
    <item>
        <title>How to run a plugin in a secondary LayoutViewWidget</title>
        <link>https://www.klayout.de/forum/discussion/2843/how-to-run-a-plugin-in-a-secondary-layoutviewwidget</link>
        <pubDate>Mon, 09 Feb 2026 13:55:43 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>taylorn</dc:creator>
        <guid isPermaLink="false">2843@/forum/discussions</guid>
        <description><![CDATA[<p>I posted this in a different discussion, but it seems to be overshadowed by a different issue I raised.</p>

<p>The KLayout documentation <a rel="nofollow" href="https://www.klayout.de/doc-qt5/programming/application_api.html#k_11">here</a> mentions that every time a LayoutView is created, a copy of each plugin is created from its PluginFactory, and is activated when the button is pressed on the toolbar.  But when created with a LayoutViewWidget, when there is no toolbar, how do you activate the plugin in that particular LayoutView?</p>

<p>My example is the following:</p>

<pre><code>import pya as kl

class PluginTestFactory(kl.PluginFactory):
    def __init__(self):
        self.register(29318, "plugin_name", "test_plugin")
    def create_plugin(self, manager, dispatcher, view):
        return PluginTest(view)
class PluginTest(kl.Plugin):
    def __init__(self,view):
        print("Starting plugin")
        self.outside_view = (view != kl.Application.instance().main_window().current_view())
    def mouse_click_event(self, p, buttons, prio):
        if prio and self.outside_view:
            print("Mouse clicked inside secondary view!")
        elif prio:
            big_menu = kl.QDialog(kl.Application.instance().main_window())
            big_menu.layout = kl.QGridLayout()
            containing_layout = kl.QWidget()
            self.layoutwidg = kl.LayoutViewWidget(containing_layout)
            cv = self.layoutwidg.view().create_layout(True)
            viewing_layout = self.layoutwidg.view().cellview(cv).layout()
            big_menu.layout.addWidget(self.layoutwidg,0,0,1,1)
            big_menu.show()
if __name__ == "__main__":
    PluginTestFactory()
</code></pre>

<p>I can't figure out how to get the "Mouse clicked inside secondary view!" string to ever print.  How do I activate the plugin in the new LayoutView, so that it can be printed?</p>
]]>
        </description>
    </item>
    <item>
        <title>How to finding if a point lies inside a specified layer.</title>
        <link>https://www.klayout.de/forum/discussion/1660/how-to-finding-if-a-point-lies-inside-a-specified-layer</link>
        <pubDate>Tue, 20 Oct 2020 05:06:01 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Ege_Bey</dc:creator>
        <guid isPermaLink="false">1660@/forum/discussions</guid>
        <description><![CDATA[<p>Hello, I am looking for a function that returns true if a given point is inside a function.</p>

<p>The following function returns true if a point lies inside a polygon (specified by layer and a cell).<br />
However I don't want to use this method because I don't want to iterate over all the shapes.<br />
Is there a simpler way of finding if a point is inside or outside (touching or not touching) a specified layer.</p>

<pre><code>iter = pya.RecursiveShapeIterator.new(layout, cell, layer_index)
specified_region = iter.shape().polygon
is_point_inside = specified_region.inside(pya.Point(x, y))
</code></pre>

<p>Thanks for the help!</p>
]]>
        </description>
    </item>
    <item>
        <title>Making an array of cells using python</title>
        <link>https://www.klayout.de/forum/discussion/1114/making-an-array-of-cells-using-python</link>
        <pubDate>Sun, 02 Sep 2018 12:06:48 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Shovalzo</dc:creator>
        <guid isPermaLink="false">1114@/forum/discussions</guid>
        <description><![CDATA[<p>Hi everyone,</p>

<p>I am using Python to create a complicated layout.<br />
In it, I created a cell which contains a whole Die. This cell is inserted into the top cell which contains the entire wafer.</p>

<p>I can manually select the cell, go edit-&gt;selection-&gt;make array and duplicate it to cover the wafer. Can this be done in the Python script?</p>

<p>For simplifying, let's assume there's a cell named "Cell_Die" which has a single 2000x3000um box in it. I want it to be duplicated with dx=3000 and dy=4000 over the entire wafer (a cell named "Cell_Wafer"), and also be able to move it slightly (for example in the above scenario, I want the wafer end to be at x=1500 of the die that touches it).</p>

<p>Thanks for the help!<br />
Shoval.</p>
]]>
        </description>
    </item>
    <item>
        <title>Image to layout alignment using 3 landmarks registrartion</title>
        <link>https://www.klayout.de/forum/discussion/1434/image-to-layout-alignment-using-3-landmarks-registrartion</link>
        <pubDate>Fri, 07 Feb 2020 16:58:29 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>mikamar</dc:creator>
        <guid isPermaLink="false">1434@/forum/discussions</guid>
        <description><![CDATA[<p>Hello Matthias-</p>

<p>This question is more of a geometric question but I'm sure you will have a very short and simple code that can help a lot:<br />
Say I want to align an image to a layout. Both the image and the layout have a set of 3 matching respective landmarks.<br />
So the image landmarks set is: (Im1x,Im1y) (Im2x,Im2y) (Im3x,Im3y) and the layout landmark set is (La1x,La1y) (La2x,La2y) (La3x,La3y)</p>

<p>Can you suggest a code that will transpose the image to the layout using above landmarks coordinates?</p>

<p>Thanks for your time and effort! Itamar</p>
]]>
        </description>
    </item>
    <item>
        <title>switch layouts but without losing the handle</title>
        <link>https://www.klayout.de/forum/discussion/2823/switch-layouts-but-without-losing-the-handle</link>
        <pubDate>Thu, 27 Nov 2025 06:14:28 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>jonathan</dc:creator>
        <guid isPermaLink="false">2823@/forum/discussions</guid>
        <description><![CDATA[<p>Hi,</p>

<p>I would like to switch layouts but without losing the handle<br />
I have the following example code:</p>

<pre><code>mw = pya.Application.instance().main_window()
mw.create_view()
ly1 =  pya.Layout()
ly1.read( "design1.oas")
ly2 =  pya.Layout()
ly2.read( "design2.oas")
mw.current_view().show_layout(ly1, False)
mw.current_view().show_layout(ly2, False)
mw.current_view().show_layout(ly1, False)
</code></pre>

<p>on the last line I am getting the error: <strong><em>Object has been destroyed already for argument <a rel="nofollow" href="https://www.klayout.de/forum/search?Search=%231&amp;Mode=like">#1</a> ('layout') in LayoutViewBase.show_layout</em></strong></p>

<p>I understand from it that layoutview.show layout is then destroying the previous design<br />
is there a way to switch layouts views without destroying them?</p>
]]>
        </description>
    </item>
    <item>
        <title>Accessing &quot;List of Landmarks&quot; from Image import GUI</title>
        <link>https://www.klayout.de/forum/discussion/2815/accessing-list-of-landmarks-from-image-import-gui</link>
        <pubDate>Sat, 15 Nov 2025 10:00:25 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>LeoTrois</dc:creator>
        <guid isPermaLink="false">2815@/forum/discussions</guid>
        <description><![CDATA[<p>Hi all,<br />
I am trying to write some script that automatically aligns user given (GUI) landmarks to a predefined set of markers in the design. However after browsing the image classes for a while, I couldnt find any way to access/retrieve the "List of landmarks" seen in the Image import GUI. <br />
Does anybody know, whether this is possible and if so, how?<br />
Thanks <img src="https://www.klayout.de/forum/resources/emoji/smile.png" title=":)" alt=":)" height="20" /></p>
]]>
        </description>
    </item>
    <item>
        <title>Python thread safety (3.14 freethreading)</title>
        <link>https://www.klayout.de/forum/discussion/2808/python-thread-safety-3-14-freethreading</link>
        <pubDate>Fri, 17 Oct 2025 08:21:08 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>sebastian</dc:creator>
        <guid isPermaLink="false">2808@/forum/discussions</guid>
        <description><![CDATA[<p>Hi Matthias,</p>

<p>I know you are probably going to hate me for this <img src="https://www.klayout.de/forum/resources/emoji/smiley.png" title=":smiley:" alt=":smiley:" height="20" /></p>

<p>But do you have a somewhat comprehensive list of what is thread-safe in KLayout?</p>

<p>Out of interest (and because in some cases it would be somewhat useful) I made a kfactory version which in the new python 3.14 works with the  freethreading (i.e. no GIL). I know that you mentioned before that KLayout should be reasonably thread-safe if you are not modifying a cell or any of it's children while working on it.</p>

<p>But to me it even fails on <code>c.each_inst()</code> when another cell is currently being built. <code>each_inst()</code> even fails for an empty cell. This fails with a topological sort error.</p>

<p>Do you have any advice how I could fix this or what might cause this?</p>

<p>If you would like to test it, the branch is here <a href="https://github.com/gdsfactory/kfactory/tree/add-3.14-threading" rel="nofollow">https://github.com/gdsfactory/kfactory/tree/add-3.14-threading</a></p>

<p>Test case is the following:</p>

<pre><code>import time
from concurrent.futures import ThreadPoolExecutor
from threading import get_ident

import kfactory as kf

kf.config.logfilter.level = "DEBUG"


def busy_wait(duration: float) -&gt; None:
    """Actively burn CPU time for `duration` seconds."""
    start = time.perf_counter()
    while (time.perf_counter() - start) &lt; duration:
        pass  # no sleep, no yield — pure busy loop


@kf.cell
def straight(length: int) -&gt; kf.KCell:
    c = kf.KCell()
    layer = c.kcl.layer(1, 0)
    # c.shapes(layer).insert(kf.kdb.Box(length, 500))
    # busy_wait(1)
    # print(f"{length=}")
    return c

def test() -&gt; kf.kdb.Cell:
    c = ly.create_cell(name=f"{get_ident()}")
    c.name = str(c.cell_index())
    return c


def main() -&gt; None:
    with ThreadPoolExecutor(max_workers=32) as executor:
        start = time.perf_counter()

        futures = [executor.submit(straight, i * 1000 + 100) for i in range(2000)]

        for i, f in enumerate(futures):
            try:
                f.result()
            except Exception as e:
                raise RuntimeError(f"Failed to build for {i=!r}") from e
        end = time.perf_counter()

    print(f"Took {end - start:.2f} seconds")


if __name__ == "__main__":
    main()
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Behavior of Region object when source is modified</title>
        <link>https://www.klayout.de/forum/discussion/2802/behavior-of-region-object-when-source-is-modified</link>
        <pubDate>Wed, 08 Oct 2025 22:48:48 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>ocasta</dc:creator>
        <guid isPermaLink="false">2802@/forum/discussions</guid>
        <description><![CDATA[<p>Hello,<br />
I create a Region <code>r</code> with an iterator, and I later delete an instance that participated to create that Region. <br />
Surprisingly, I observe that <code>r</code> is modified, even though if I didn't operate on it:</p>

<ul>
<li>The Region became empty (see the debug file).</li>
<li>The area of the Region is non-zero even though it is empty (it remained to the value before the region vanished).</li>
</ul>

<p>Can you explain this behavior? Where is it documented? Is the Region holding data itself or is it a view in the memory of the database?<br />
Olivier</p>

<pre><code>import pya

mw = pya.MainWindow.instance()      # MainWindow
lv = pya.LayoutView.current()       # LayoutView
cv = lv.active_cellview()           # CellView
layout = cv.layout()                # Layout

cell = layout.cell("TOP")           # Cells
hole = layout.cell("Hole")

iter = cell.begin_shapes_rec(layout.find_layer(2,0))
iter.maxdepth = 0
r = pya.Region(iter)                # Create Region 'r'

print("(1) Area: ", r.area())

for inst in cell.each_inst():       # Delete a cell instance
  if inst.cell.name == "Hole":
    inst.delete()   

print("(2) Area: ", r.area())       # Check Region 'r'
r.write("debug.gds")

# Setup the display
lv.reload_layout(cv.index())            # Reload original file
mw.load_layout("debug.gds", mode=1)     # Display the debug file
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Region inserted in layout is empty / not shown</title>
        <link>https://www.klayout.de/forum/discussion/2799/region-inserted-in-layout-is-empty-not-shown</link>
        <pubDate>Sun, 05 Oct 2025 20:40:30 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>ocasta</dc:creator>
        <guid isPermaLink="false">2799@/forum/discussions</guid>
        <description><![CDATA[<p>Hello,<br />
At the end of the script below, I create a new Region from two different layouts. What happens is:</p>

<ul>
<li>A new layout is created and a new cell named "XOR" is created in this layout. <strong>--&gt; OK</strong></li>
<li>Region <code>r</code> is created, with the correct non-zero area (when <code>ra</code> and <code>rb</code> differ). <strong>--&gt; OK</strong></li>
<li>A layer is created with the expected layer number... <strong>but that layer remains empty!</strong></li>
</ul>

<p>Could you explain why the layer is not populated and what should be done to obtain the result?<br />
Oliver</p>

<pre><code>"""Compare designs."""
A_cell, B_cell = None, None

mv = pya.MainWindow.instance()

for lv_idx in range(mv.views()):
  lv = mv.view(lv_idx)
  print(f"Open LayoutView {lv_idx}: " + lv.title)

  for cv_idx in range(lv.cellviews()):
    cv = lv.cellview(cv_idx)
    print(f"Search cell in CellView {cv_idx}: " + cv.name)

    if cv.name == "Test_A.gds":
      A_ly = cv.layout()
      A_cell = A_ly.cell("TOP")
      print("-&gt; A_cell found.")

    if cv.name == "Test_B.gds":
      B_ly = cv.layout()
      B_cell = B_ly.cell("TOP")
      print("-&gt; B_cell found.")


if (A_cell is None) or (B_cell is None):
  raise RuntimeError("Error: Target cells were not found.")
else:
  print("--&gt; Target cells were found.")

LAYER_PAIRS =  [[ (19,0), (19,0) ]]

cv = mv.create_layout(mode=1)
ly = cv.layout()
cell = ly.create_cell("XOR")

for (a,b) in LAYER_PAIRS:
  a_idx = A_ly.find_layer(a)
  b_idx = B_ly.find_layer(b)

  ra = pya.Region(A_cell.begin_shapes_rec(a_idx))
  print("Region a: ", ra.area())
  rb = pya.Region(B_cell.begin_shapes_rec(b_idx))
  print("Region b: ", rb.area())
  r = ra ^ rb
  print("Region a^b: ", r.area())

  idx = ly.layer(a)
  cell.shapes(idx).insert(r)
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Importing .py files from technology directory</title>
        <link>https://www.klayout.de/forum/discussion/2790/importing-py-files-from-technology-directory</link>
        <pubDate>Tue, 23 Sep 2025 18:35:11 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>kevinz</dc:creator>
        <guid isPermaLink="false">2790@/forum/discussions</guid>
        <description><![CDATA[<p>I'm using KLayout 0.30.4 on FreeBSD and Windows.</p>

<p>I have a technology file for which I've set a custom base path (outside of <code>~/.klayout</code>). It follows the standard KLayout technology structure with a <code>pymacros/</code> subdirectory containing both a <code>.lym</code> (set to auto-run) that imports <code>.py</code> files.</p>

<p>KLayout does not seem to have trouble finding this <code>pymacros/</code> directory since they show up in the per-technology Python scripts in the Macro Editor. However, if I have e.g. <code>Disk.py</code> and try to <code>import Disk</code> from the <code>.lym</code> file, I get an error "No module named 'Disk' (Class ModuleNotFoundError)".</p>

<p>I have to add:</p>

<pre><code>import sys
sys.path.append("/path/to/my/tech/pymacros")
</code></pre>

<p>Before this will work.</p>

<p>The <a rel="nofollow" href="https://www.klayout.de/doc/about/macro_editor.html">macro editor documentation</a> suggests that "Technology folders: each technology folder can carry a "macros" or "pymacros" subfolder where technology-specific macros are kept" which seems to imply that the technology folder should automatically be added to the import path.</p>

<p>Is this the intended behavior? Would you consider automatically adding the technology path <code>pymacros/</code> folder so that it is importable?</p>
]]>
        </description>
    </item>
    <item>
        <title>Installation settings for Ubuntu 18.04</title>
        <link>https://www.klayout.de/forum/discussion/2795/installation-settings-for-ubuntu-18-04</link>
        <pubDate>Mon, 29 Sep 2025 16:46:10 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>taylorn</dc:creator>
        <guid isPermaLink="false">2795@/forum/discussions</guid>
        <description><![CDATA[<p>Hello,</p>

<p>I'm trying to install the most updated version of Klayout from source on an offline version of Ubuntu 18.04, and it has only Qt 5.9.5.  It therefore causes trouble when trying to install src/gsiqt/qt5/QtCore/gsiDeclQAbstractItemModel.cc (among other possible issue spots) because in Qt5.11 the CheckIndex function was added to QAbstractItemModel, and it appears Klayout added handling for that in commit 31aa45d.</p>

<p>My question is: when pre-building the .deb files for Ubuntu 18.04, how is this bindings issue handled?  I would like to use Qt bindings, and I'll update my Qt installation if I have to, but I'm just wondering what the current handling for this mismatch is.  Thanks!</p>

<p>-Noah</p>
]]>
        </description>
    </item>
    <item>
        <title>How to draw a circle with pcell rather than polygon points?</title>
        <link>https://www.klayout.de/forum/discussion/2789/how-to-draw-a-circle-with-pcell-rather-than-polygon-points</link>
        <pubDate>Tue, 23 Sep 2025 07:49:27 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Sunfove</dc:creator>
        <guid isPermaLink="false">2789@/forum/discussions</guid>
        <description><![CDATA[<p>How to draw a circle with pcell rather than polygon points?  I can realize it in klayout software by drawing a box and convert to pcell, but i don not know the which function I can use to realize directly in python.<br />
 And I wonder the different between pcell method and polygon points method.</p>
]]>
        </description>
    </item>
    <item>
        <title>KLayout version 0.30.4 doesn't let me import Plugin python class</title>
        <link>https://www.klayout.de/forum/discussion/2782/klayout-version-0-30-4-doesnt-let-me-import-plugin-python-class</link>
        <pubDate>Mon, 15 Sep 2025 08:40:27 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>PavelSmirnov</dc:creator>
        <guid isPermaLink="false">2782@/forum/discussions</guid>
        <description><![CDATA[<p>Hello!</p>

<p>I noticed that KLayout python package got updated over the weekend, so I tried to include it in our project, but it caused CI pipeline to fail. The problem boils down to trying to run this code in python:</p>

<pre><code>import klayout.lay
x = klayout.lay.Plugin()
</code></pre>

<p>With klayout==0.30.3 this executes just fine. With klayout==0.30.4 I get error:</p>

<pre><code>AttributeError: module 'klayout.lay' has no attribute 'Plugin'
</code></pre>

<p>I suspect this module got renamed or moved somewhere due to these changes?<img src="https://www.klayout.de/forum/uploads/editor/pp/sgciyskd9tga.png" alt="" title="" /></p>

<p>What would be the recommended way of using features under the <code>Plugin</code> and <code>PluginFactory</code> classes?</p>
]]>
        </description>
    </item>
    <item>
        <title>callback_impl pass through value changes</title>
        <link>https://www.klayout.de/forum/discussion/2785/callback-impl-pass-through-value-changes</link>
        <pubDate>Wed, 17 Sep 2025 12:36:19 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Tabra</dc:creator>
        <guid isPermaLink="false">2785@/forum/discussions</guid>
        <description><![CDATA[<p>Hello,</p>

<p>I was attempting on implementing a <code>TypeCallback</code> clickable button + <code>callback_impl(self, name)</code> function to trigger changes on the parameters of a PCell with a click (for example, setting defaults/specific parameters).</p>

<p>When going for it, <code>self.name = xx</code> wouldn't work, and <code>self.name.value=(xx)</code> only seems works within the scope of the function <code>callback_impl</code> (checking the value change with print(self.name.value)).</p>

<p>I thought that maybe this was the intended implementation, for callback_impl to only affect the UI with enabled, readonly, visible or icon.<br />
But then I found that using <code>self.name.value=(xx)</code> AND changing the state of any of the former properties, the changed value would pass through and materialize in the PCell itself.</p>

<p>I suppose it's a bug. An example:</p>

<pre><code>def callback_impl(self,name):

if name == "callbackButton":

self.propertyName.value=(4.0)

self.propertyName.readonly = not(self.propertyName.readonly)
</code></pre>

<p>Thank you,<br />
Gerard</p>

<hr />

<p>P.D. I'll describe what I'm actually trying to achieve with all this, just for context purposes:</p>

<p>I'm trying to use libraries (static or other PCells) within a PCell so that a layout can build itself by combining these hierarchical PCells.<br />
Segregating PCells is useful in case we want one of the building blocks for manual placement, and would also allow to implement external libraries compatible with the purpose of the PCell (maybe combining it with a metadata identifier), and still adjust the parent PCell to accommodate and perform any dependant operation for the child components.<br />
Ideally, the PCell library would use itself to build other entries of the same library. That would be doable by calling the definition of the required PCell in another script, or external cell within the definition assuming that it's already present somewhere when executing the PCell.<br />
This would allow to:</p>

<ul>
<li><u>Simplify PCell definitions</u>: Split PCells into managable pieces which are easier to maintain</li>
<li><u>Versatility</u>: Use one of the building blocks on its own for manual designs and without redundancy</li>
<li><u>Custom programatic grouping</u>: Call PCells within a PCell for ease of use/convenience</li>
<li><u>Build modifying other cells</u>: Use PCells to convert them as static and apply further transformations</li>
<li><u>Build on top of other cells</u>: Perform dependant operations on the child (like booleans/fill) and add extra polygons to make a next hierarchical step PCell parent while maintaining the original instance reference</li>
<li><u>Build with interacting cells</u>: Smart interaction between PCells with the usage of defined relationship properties or metadata inserted into the cell</li>
</ul>

<p>Hence I need to add any external source to a PCell and the only way I could think of is by specifying the name of the cell/pcell and look for it in embedded libraries or existing cells within the layout. The most convenient way to add one would be with a dropdown menu, but there's no <code>TypeLayer</code> equivalent for cells and/or library entries, and I don't know how to dynamically load the <code>choices</code> property of the <code>TypeList</code>. I assume that this is incompatible within the PCell definition as it is a segregated unit of sorts.<br />
Then I thought, what if I execute a function that opens a custom popup with a list populated with all the existing cells and library entries of the session, for then to return the string of the selected entry? And here is where I had trouble on changing the state of a <code>TypeString</code> on a callback event.</p>
]]>
        </description>
    </item>
    <item>
        <title>Trace net export with XML post-processing</title>
        <link>https://www.klayout.de/forum/discussion/2751/trace-net-export-with-xml-post-processing</link>
        <pubDate>Sun, 20 Jul 2025 08:06:28 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>dixit</dc:creator>
        <guid isPermaLink="false">2751@/forum/discussions</guid>
        <description><![CDATA[<p>Hi,</p>

<p>I don't know if it is possible to interactively trace a net (as usual) and to tie a post trigger (or something similar) to the 'Export To Net' button to post-process the XML output file? My main goal would be to save 'box' entities with their real layer name instead of gds number/datatype pair. Basically the same as 'polygon' entities. The coupled post-processing script would need access to the .lyp file, i think, to make the mapping. What could be a good approach to do this?</p>

<p>Thanks.</p>
]]>
        </description>
    </item>
    <item>
        <title>Multi-step OASIS stream file writer</title>
        <link>https://www.klayout.de/forum/discussion/2555/multi-step-oasis-stream-file-writer</link>
        <pubDate>Fri, 26 Jul 2024 09:42:31 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>dion</dc:creator>
        <guid isPermaLink="false">2555@/forum/discussions</guid>
        <description><![CDATA[<p>When a design is too large to be completely created in memory,  gdstk provide the method of Multi-step stream writer, like,</p>

<blockquote><div>
  <blockquote><div>
    <p>writer = gdstk.GdsWriter()<br />
    cell1 = some_function_that_creates_a_huge_cell()<br />
    writer.write(cell1)<br />
    del cell1<br />
    cell2 = some_function_that_creates_a_huge_cell()<br />
    writer.write(cell2)<br />
    del cell2<br />
    writer.close()</p>
  </div></blockquote>
</div></blockquote>

<p>How to do it in klayout ?</p>
]]>
        </description>
    </item>
    <item>
        <title>DRC - Comparison of widths of the largest areas of shapes in the two layers</title>
        <link>https://www.klayout.de/forum/discussion/2757/drc-comparison-of-widths-of-the-largest-areas-of-shapes-in-the-two-layers</link>
        <pubDate>Sat, 26 Jul 2025 07:33:54 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Apple</dc:creator>
        <guid isPermaLink="false">2757@/forum/discussions</guid>
        <description><![CDATA[<p>Hi,I am currently learning DRC using Python, but now I have encountered two problems related to DRC.Now I have three layers: layer 1 (red), layer 2 (green), and layer 3 (blue).. As shown in the figure: 1. The outer boundary of the largest polygon in layer 1 (RED) must be at least 10 um away from the outer boundary of the largest polygon in layer 2 (GRN) (that is, a &gt;= 10); if the distance is less than 10 um, a DRC error will be reported; 2. The inner boundary of the largest polygon in layer 2 (GRN) must be 5 um away from the inner boundary of the largest polygon in layer 3 (BLUE) (that is, b = 5 um); if the distance is not equal to 5 um, a DRC error will occur.<br />
<img src="https://www.klayout.de/forum/uploads/editor/wg/9mgz5umufa4z.png" alt="" title="" /></p>
]]>
        </description>
    </item>
    <item>
        <title>Open .gds file in KLayout by using Python</title>
        <link>https://www.klayout.de/forum/discussion/2643/open-gds-file-in-klayout-by-using-python</link>
        <pubDate>Tue, 24 Dec 2024 09:34:00 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>BigPanda</dc:creator>
        <guid isPermaLink="false">2643@/forum/discussions</guid>
        <description><![CDATA[<p>Once I write my structure(a lot of PCells) into a .gds file. How can I use Python code to open this .gds file in KLayout? I think this will be much eaiser for me to do visualization.</p>

<p>Is there a function in pya module can realise this.</p>
]]>
        </description>
    </item>
    <item>
        <title>Deleting Specific Objects within a Cell (Python Script/Macro)</title>
        <link>https://www.klayout.de/forum/discussion/2755/deleting-specific-objects-within-a-cell-python-script-macro</link>
        <pubDate>Thu, 24 Jul 2025 02:00:44 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Sharon</dc:creator>
        <guid isPermaLink="false">2755@/forum/discussions</guid>
        <description><![CDATA[<p>I'm quite new and still learning the ropes, so I appreciate any patience and guidance you can offer!<br />
I'm trying to figure out how to delete specific objects within a cell, and I'm hoping to get some help with a script.</p>

<p>If I delete an object from the red circle, the entire cell <a rel="nofollow" href="https://www.klayout.de/forum/search?Search=%231&amp;Mode=like">#1</a> is removed. I don't want to do that.</p>

<p>I found that when I double-click on cell <a rel="nofollow" href="https://www.klayout.de/forum/search?Search=%231&amp;Mode=like">#1</a>, the pillar shapes appear as black boxes within the red circle. When I selected those objects and pressed the 'Delete' key, they were successfully deleted.</p>

<p>I'd really like to automate this deletion process. So, my question is: How can I delete or remove the objects from the selected cell's pillars using a Python script (macro)?</p>

<p><img src="https://www.klayout.de/forum/uploads/editor/xq/ca63dvfc6jsl.png" alt="" title="" /></p>

<p>My Script:<br />
Here's the Python script I've tried so far, but it's leading to the whole cell being removed:</p>

<pre><code> import pya
import math

# Enter your Python code here ..
x = 583.6628
y = 348.6938
center_x = 0
center_y = 0
r = math.sqrt(x*x + y*y)

layout_view = pya.LayoutView.current()

cv = layout_view.active_cellview()
layout = cv.layout()
cell = cv.cell
dbu = layout.dbu
print("dbu unit: ", dbu)

object_selection = layout_view.each_object_selected()
i = 1
for instance in object_selection:
  print(f"--- the {i} pillars --")
  i = i+1;
  path_list = instance.path
  shape_list = instance.shape
  if path_list is not None:
    for path in path_list:
      instance = path.cell_inst()

      cplx_trans = instance.cplx_trans
      #reference_call = instance.cell_index
      instance_cell_index = instance.cell_index
      inst_cell = layout.cell(instance_cell_index)
      inst_cell_bbox = inst_cell.bbox()
      dimension = inst_cell_bbox.transformed(cplx_trans)
      dimension_height = (abs(dimension.bottom) - abs(dimension.top)) * dbu
      dimension_width = (abs(dimension.right) - abs(dimension.left)) * dbu
      print(f"instance of cell dimension: width {dimension_width}, height {dimension_height}")
      disp_x = cplx_trans.disp.x * dbu
      disp_y = cplx_trans.disp.y * dbu
      angle = cplx_trans.angle
      rot = cplx_trans.rot
      mag = cplx_trans.mag
      print(f"instance of Position: {disp_x} , {disp_y}")
      print("instance of the angle in units of 90 degree: ", angle)
      print("instance of the angle code:", rot())
      print("instance of scaling:", mag)

      test_r = math.sqrt(disp_x*disp_x + disp_y*disp_y)
      if test_r &gt; r:
        layout.delete_cells(instance_cell_index)
        print("Delete!!")
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>Design size variation when using Save layout options</title>
        <link>https://www.klayout.de/forum/discussion/2762/design-size-variation-when-using-save-layout-options</link>
        <pubDate>Thu, 31 Jul 2025 13:23:06 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>jonathan</dc:creator>
        <guid isPermaLink="false">2762@/forum/discussions</guid>
        <description><![CDATA[<p>Hello,</p>

<p>I have a design "test.oas" with a top cell that interest me "Top" and a bunch of other empty topcells.<br />
I try to get rid of other topcells using SaveLayoutOptions, but I am then getting a very large design</p>

<p>if I run the following script:</p>

<pre><code>ly=pya.Layout()
ly.read("test.oas")
lo = pya.SaveLayoutOptions()
lo.add_cell(ly.cell("Top").cell_index())
ly.write("test2.oas",lo)
ly.clear()
ly.read("test2.oas")
ly.write("test3.oas")
</code></pre>

<p>I have the following design sizes:<br />
test.oas is 199K<br />
test2.oas is 31M (too large file!)<br />
test3.oas is 174K (what I was hoping to have)</p>

<p>I also tried to change oasis compression level</p>

<pre><code>lo.oasis_compression_level = 10
</code></pre>

<p>but it did not change anything.<br />
would you have any idea what I am doing wrong when using Save layout options?</p>
]]>
        </description>
    </item>
    <item>
        <title>How to open the Console when it is closed?</title>
        <link>https://www.klayout.de/forum/discussion/2758/how-to-open-the-console-when-it-is-closed</link>
        <pubDate>Sun, 27 Jul 2025 11:40:48 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Apple</dc:creator>
        <guid isPermaLink="false">2758@/forum/discussions</guid>
        <description><![CDATA[<p>Hi <br />
Hello, my Klayout version is 0.30.1. Since I started using it, the console has never been displayed. How can I enable the console? I hope to check the accuracy of the script by looking at the output content displayed on the console.<br />
The interface in the Macros environment is as shown in Fig.but the console does not display anything.<br />
<img src="https://www.klayout.de/forum/uploads/editor/65/xlncsg3b5ugv.png" alt="" title="" /></p>
]]>
        </description>
    </item>
    <item>
        <title>DRC - How to obtain the length of one Box from multiple Boxes</title>
        <link>https://www.klayout.de/forum/discussion/2760/drc-how-to-obtain-the-length-of-one-box-from-multiple-boxes</link>
        <pubDate>Mon, 28 Jul 2025 15:34:32 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Apple</dc:creator>
        <guid isPermaLink="false">2760@/forum/discussions</guid>
        <description><![CDATA[<p>Hi<br />
In layer1/0, I have many shapes, namely polygons and boxes. All the boxes are of the same size and they are all squares. How can I obtain the side length of a box, such as the side length of the box in the red frame?</p>

<p><img src="https://www.klayout.de/forum/uploads/editor/tf/ftzrkpl8rgtw.png" alt="" title="" /></p>
]]>
        </description>
    </item>
    <item>
        <title>Macros don't work</title>
        <link>https://www.klayout.de/forum/discussion/2759/macros-dont-work</link>
        <pubDate>Mon, 28 Jul 2025 08:20:06 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>DGillam</dc:creator>
        <guid isPermaLink="false">2759@/forum/discussions</guid>
        <description><![CDATA[<p>Hi,</p>

<p>I'm having trouble getting started with writing macros. I started with the the basic example from <a href="https://www.klayout.de/doc/programming/python.html" rel="nofollow">https://www.klayout.de/doc/programming/python.html</a>. I pasted the code into a new python macro and was able to run it and have it draw the rectangle, but then, I maybe accidentally changed a setting that's made macros stop working. In the console it says the macro has been run, but it isn't drawing anything. Here's a screenshot of my macro IDE (link removed).</p>

<p>Sorry if this is a really silly question.</p>
]]>
        </description>
    </item>
    <item>
        <title>How to create and load TIFF images from klayout</title>
        <link>https://www.klayout.de/forum/discussion/2756/how-to-create-and-load-tiff-images-from-klayout</link>
        <pubDate>Fri, 25 Jul 2025 09:26:33 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Moongyu</dc:creator>
        <guid isPermaLink="false">2756@/forum/discussions</guid>
        <description><![CDATA[<p>Hello Mathias,</p>

<p>I have tried to create an image file with the TIFF format and open from the Klayout GUI by Edit &gt; Add Image, but it fails with the message "No data loaded for that image". The TIFF image is created by the PILLOW module as shown below.</p>

<p>def save_sdf_as_tiff(sdf_array, grid_bbox_dbu, dbu, resolution, output_dir="."):<br />
    """Saves the high-precision SDF data as a floating-point TIFF."""<br />
    if sdf_array is None: return<br />
    center_x_um = grid_bbox_dbu.center().x * dbu<br />
    center_y_um = grid_bbox_dbu.center().y * dbu<br />
    base_filename = f"sdf_data_center_{center_x_um:.3f}<em>{center_y_um:.3f}_pixelsize</em>{resolution:.3f}"<br />
    tiff_filepath = os.path.join(output_dir, f"{base_filename}.tif")<br />
    print(f"-&gt; Saving high-precision SDF data to '{tiff_filepath}'...")<br />
    img = Image.fromarray(sdf_array.astype(np.float32))<br />
    img.save(tiff_filepath, compression='tiff_uncompressed')<br />
    print("-&gt; Data TIFF file saved.")</p>

<p>where "Image" is from PIL. I have tried to load the save the image by another image viewer, then it succeeded. Is there a Caveat that I have missed in creating and loading the TIFF image?</p>
]]>
        </description>
    </item>
    <item>
        <title>make layout.read faster?</title>
        <link>https://www.klayout.de/forum/discussion/2753/make-layout-read-faster</link>
        <pubDate>Mon, 21 Jul 2025 12:03:40 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>jonathan</dc:creator>
        <guid isPermaLink="false">2753@/forum/discussions</guid>
        <description><![CDATA[<p>Hi, I have a python script going through large designs exploring cells, for this I open the designs using layout.read but the command takes 30s-1m to get through. <br />
I only need the cell informations (layout.top_cells() , layout.each_cell() , cell.name)</p>

<p>I wonder if there is any way to make it faster?</p>
]]>
        </description>
    </item>
   </channel>
</rss>
