<?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>Sun, 11 Oct 2026 17:48:58 +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>Python Scripting for reading an Excel file and creating a polar array on Klayout Macro</title>
        <link>https://www.klayout.de/forum/discussion/1642/python-scripting-for-reading-an-excel-file-and-creating-a-polar-array-on-klayout-macro</link>
        <pubDate>Wed, 16 Sep 2020 14:37:32 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>dsenuka</dc:creator>
        <guid isPermaLink="false">1642@/forum/discussions</guid>
        <description><![CDATA[<p>Hi, <br />
I used the following python script to read an excel file (attached) and generate a text script as input for CNST (Java based nanofab toolbox developed by NIST) toolbox. This CNST toolbox is supposed to generate GDS2 file. However, for large size files, CNST toolbox stalls. <br />
My script first create a line array of circles where position and radii for individual circles are given in the Excel file. Then this script creates a polar array of this line array of circles; the final layout is a metalens of circular symmetry. <br />
Can someone either modify this python script (copied below)or guide me how to do this on Klayout Macro? <br />
Thanks a lot.<br />
KS</p>

<p>import csv<br />
import math</p>

<p>circles = []</p>

<h1>Open csv file</h1>

<p>with open('circles.csv') as csvfile:<br />
    circleReader = csv.reader(csvfile)<br />
    for num, row in enumerate(circleReader):<br />
        if num != 0:<br />
            circles.append((float(row[1]), float(row[2]), float(row[3])))</p>

<h1>Open file for output</h1>

<p>with open('metalens.cnst','w') as output:</p>

<pre><code># Header
output.write('# This file is created using metalens.py\n\n')
output.write('0.001 gdsReso\n')
output.write('0.001 shapeReso\n')
output.write('1 layer\n')


# create all circle structures
for num, circle in enumerate(circles, start=1):
    output.write(f'&lt;circle_{num} struct&gt;\n')
    output.write(f'0 0 {circle[1]/2} {circle[1]/2} 0 ellipseVector\n\n')

# create metalens
output.write('# Metalens structure comment\n')
output.write('&lt;metalens struct&gt;\n')

#create each ring of the metalens from the inside out
for num,circle in enumerate(circles, start=1):
    theta = 180*circle[2]/math.pi
    if num == 1:
        output.write(f'&lt;circle_{num} 0 0 N 0 0 instance&gt;\n')
    else:
        output.write(f'&lt;circle_{num} 0 359 {theta} {circle[0]} {circle[0]} 1 1 arrayPolar&gt;\n')
</code></pre>
]]>
        </description>
    </item>
    <item>
        <title>KLayout-klink: feedback on external KLayout API coverage</title>
        <link>https://www.klayout.de/forum/discussion/2887/klayout-klink-feedback-on-external-klayout-api-coverage</link>
        <pubDate>Wed, 09 Sep 2026 16:08:09 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Yanming_Liu</dc:creator>
        <guid isPermaLink="false">2887@/forum/discussions</guid>
        <description><![CDATA[<p>Hi Matthias and everyone,</p>

<p>I'd like to share <strong>KLayout-klink</strong>, an open-source external control layer for a running KLayout GUI, and ask for some feedback on its KLayout API coverage. (<a href="https://github.com/klinkdev2026/klayout-klink" rel="nofollow">https://github.com/klinkdev2026/klayout-klink</a>)</p>

<p>While developing it, I found some older discussions on this forum about controlling an already-running KLayout instance from an external application. In particular, Matthias suggested using socket-based IPC while keeping KLayout itself as the host application.</p>

<p><a href="https://www.klayout.de/forum/discussion/1001/how-to-send-a-ruby-script-for-execution-to-already-open-klayout-editor-instance" rel="nofollow">https://www.klayout.de/forum/discussion/1001/how-to-send-a-ruby-script-for-execution-to-already-open-klayout-editor-instance</a></p>

<p><a href="https://www.klayout.de/forum/discussion/254/call-reload-from-command-line" rel="nofollow">https://www.klayout.de/forum/discussion/254/call-reload-from-command-line</a></p>

<p>klink essentially follows this direction, but tries to turn the task-specific socket "glue code" into a reusable control interface.</p>

<p>Rather than simply providing a remote <code>eval</code>, I went through the KLayout <code>pya</code> and GUI APIs and tried to organize the operations useful for external control into stable, typed APIs.</p>

<p>Currently, the KLayout-facing control surface mainly covers:</p>

<ol>
<li><strong>Layout &amp; Cell</strong> — open/save layouts, cell creation/deletion, hierarchy, bbox, etc.</li>
<li><strong>Layers</strong> — layers/datatypes, layer properties and <code>.lyp</code></li>
<li><strong>Shapes &amp; Geometry</strong> — boxes, polygons, paths, text, batch insertion, transforms, boolean/fill</li>
<li><strong>Instances / PCells / Libraries</strong> — instances, arrays, PCell discovery/creation, libraries and flattening</li>
<li><strong>LayoutView / GUI</strong> — CellViews, tabs, active cell, viewport, zoom, hierarchy display, highlights and 2.5D view</li>
<li><strong>Selection</strong> — read/set selection, plus persistent "SEND" selections for external interaction</li>
<li><strong>Rulers / Annotations</strong> — access and manipulate native KLayout annotations and measurements</li>
<li><strong>Editing</strong> — grouped transactions, undo/redo</li>
<li><strong>DRC / LVS</strong> — DRC scripts, netlist extraction/comparison and LVS databases</li>
<li><strong>Events / Recording / Sessions</strong> — observe GUI/layout changes, record operations and control multiple running KLayout sessions</li>
</ol>

<p>For things that are not yet covered, <code>exec.python</code> remains an escape hatch to the native <code>pya</code> API.</p>

<p>My own layout background is mainly custom research devices and nanodevices. Although I have tried to systematically go through the KLayout APIs, I do not know all the important workflows in IC layout, mask preparation, MEMS, photonics, PDK-based design and other fields.</p>

<p>So my main question is:</p>

<p><strong>Which KLayout APIs or concepts am I still missing that you think are important enough to deserve a stable external control API?</strong></p>

<p>I do not intend to wrap every <code>pya</code> method individually. I am mainly trying to identify the common, high-value operations that are useful when KLayout is controlled by an external Python program, automation system or MCP/AI client.</p>

<p>Matthias, I would especially appreciate your opinion, since you have seen KLayout used across many more application domains than I have.</p>

<p>Any suggestions or criticism would be very welcome.</p>

<p>Best regards,<br />
Yanming</p>
]]>
        </description>
    </item>
    <item>
        <title>PEX ERROR: src/db/db/dbPLC.cc,543,false</title>
        <link>https://www.klayout.de/forum/discussion/2883/pex-error-src-db-db-dbplc-cc-543-false</link>
        <pubDate>Thu, 20 Aug 2026 13:46:09 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>jinxtopcs</dc:creator>
        <guid isPermaLink="false">2883@/forum/discussions</guid>
        <description><![CDATA[<p>Hi Mattias,<br />
I am using on PEX extraction and stuck on this error.<br />
Not sure why <code>min_b=0</code> in <code>region.delaunay</code> works but <code>extraction</code> keeps failing.<br />
And, in your opinion, when dealing with non-orthogonal shape in PEX, these statements are correct (assume we don't care the R result) ?<br />
       1. <code>min_b=0</code> is better than <code>min_b=0.3</code><br />
       2. <code>tessellation</code> is better than <code>squarecounting</code><br />
Sorry I try to read online but still cannot understand the functions completely.<br />
Since I cannot post too much information here. I hope you can reproduce the error using limited information below.</p>

<p>I installed klayout 0.30.9 in linux system.</p>

<pre><code>from typing import *
import klayout.db as kdb
import klayout.pex as klp


tech1 = klp.RExtractorTech()
tech2 = klp.RExtractorTech()

m1 = 10
m2 = 20
v1 = 15

for l in (m1, m2):
    m = klp.RExtractorTechConductor()
    m.layer = l
    m.resistance = 1
    m.algorithm = klp.Algorithm.Tesselation
    m.triangulation_max_area = 0
    m.triangulation_min_b = 0
    tech1.add_conductor(m)
    m.triangulation_min_b = 0.3
    tech2.add_conductor(m)

v = klp.RExtractorTechVia()
v.cut_layer = v1
v.bottom_conductor = m1
v.top_conductor = m2
v.resistance = 1
tech1.add_via(v)
tech2.add_via(v)

points = """-13025.42800    -33338.54100
-13127.95900    -33236.01000
-13132.73200    -33240.78300
-13135.91400    -33237.60100
-13026.13600    -33127.82300
-12923.60500    -33230.35400
-12920.42300    -33227.17200
-13022.95400    -33124.64100
-13014.99900    -33116.68600
-13011.81700    -33119.86800
-13016.59000    -33124.64100
-12914.05900    -33227.17200
-12923.60500    -33236.71800
-13026.13600    -33134.18700
-13029.31700    -33137.36900
-12926.78700    -33239.89900
-12936.33300    -33249.44500
-13038.86300    -33146.91500
-13042.04500    -33150.09700
-12939.51500    -33252.62700
-12949.06100    -33262.17300
-13051.59100    -33159.64300
-13054.77300    -33162.82500
-12952.24300    -33265.35500
-13012.70100    -33325.81300
-13115.23100    -33223.28300
-13118.41300    -33226.46400
-13015.88200    -33328.99500"""

points = points.split("\n")
points_kdb = []
for p in points:
    x, y = p.split()
    points_kdb.append(kdb.Point(round(float(x)/0.001), round(float(y)/0.001)))

polygon = kdb.Polygon(points_kdb)
region = kdb.Region([polygon])
geo: Dict[int, kdb.Region] = {m1: region}

x1, y1 = -13133, -33238.8
x2, y2 = -13015,-33120
port_a = kdb.Point(round(x1/0.001),round(y1/0.001))
port_b = kdb.Point(round(x2/0.001),round(y2/0.001))


vertex_ports: Dict[int, List[kdb.Point]] = { m1: [port_a, port_b] }
polygon_ports: Dict[int, List[kdb.Polygon]] = {}
rexer = klp.RNetExtractor(dbu=0.001)
try:
    network = rexer.extract(tech1, geo, vertex_ports, polygon_ports)
    print(f"PEX min_b=0 PASS: {network.to_s(with_coords=True)}\n")
except Exception as e:
    print(f"PEX min_b=0 ERROR: {e}\n")

try:
    network = rexer.extract(tech2, geo, vertex_ports, polygon_ports)
    print(f"PEX min_b=0.3 PASS: {network.to_s(with_coords=True)}\n")
except Exception as e:
    print(f"PEX min_b=0.3 ERROR: {e}\n")

try:
    m1_delaunay = region.delaunay(max_area=0, min_b=0)
    print(f"REGION min_b=0 PASS\n")
except Exception as e:
    print(f"REGION min_b=0 ERROR: {e}\n")

try:
    m1_delaunay = region.delaunay(max_area=0, min_b=0.3)
    print(f"REGION min_b=0.3 PASS\n")
except Exception as e:
    print(f"REGION min_b=0.3 ERROR: {e}\n")
</code></pre>

<blockquote><div>
  <p>ERROR: src/db/db/dbPLC.cc,543,false<br />
  PEX min_b=0 ERROR: Internal error: src/db/db/dbPLC.cc:543 false was not true in RNetExtractor.extract</p>
  
  <p>ERROR: src/db/db/dbPLC.cc,543,false<br />
  PEX min_b=0.3 ERROR: Internal error: src/db/db/dbPLC.cc:543 false was not true in RNetExtractor.extract</p>
  
  <p>REGION min_b=0 PASS</p>
  
  <p>ERROR: src/db/db/dbPLC.cc,543,false<br />
  REGION min_b=0.3 ERROR: Internal error: src/db/db/dbPLC.cc:543 false was not true in Region.delaunay</p>
</div></blockquote>
]]>
        </description>
    </item>
    <item>
        <title>Returning value of : cell_name vs filename</title>
        <link>https://www.klayout.de/forum/discussion/2865/returning-value-of-cell-name-vs-filename</link>
        <pubDate>Thu, 09 Apr 2026 00:12:57 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>alto</dc:creator>
        <guid isPermaLink="false">2865@/forum/discussions</guid>
        <description><![CDATA[<p>Based on the documentation<br />
<a href="https://www.klayout.de/doc-qt5/code/class_CellView.html#h2-138" rel="nofollow">https://www.klayout.de/doc-qt5/code/class_CellView.html#h2-138</a></p>

<pre><code> [const]    string  cell_name       Gets the name of the target cell currently addressed
 [const]    string  filename        Gets filename associated with the layout behind the cellview
</code></pre>

<p><code>pya.LayoutView().current().active_cellview().cell_name -&gt; "test"</code><br />
expected</p>

<p><code>pya.LayoutView().current().active_cellview().filename -&gt; &lt;built-in method filename of CellView object at 0x7f2ff9f280d0&gt;</code><br />
not what I expected !</p>

<p>both are  '[const]  string' should both return a string ?</p>

<p>However <br />
<code>pya.CellView().active().filename() -&gt; test.GDS</code><br />
does what I was expecting from <br />
pya.LayoutView().current().active_cellview().filename</p>

<p>feature, bugs or missing something ?</p>
]]>
        </description>
    </item>
    <item>
        <title>Reading Huge OASIS OOM</title>
        <link>https://www.klayout.de/forum/discussion/2861/reading-huge-oasis-oom</link>
        <pubDate>Mon, 30 Mar 2026 12:20:59 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>ryanke</dc:creator>
        <guid isPermaLink="false">2861@/forum/discussions</guid>
        <description><![CDATA[<p>Hi,</p>

<p>My current case would encounter OASIS &gt;500G, and for Klayout, when I do layout.read(), the memory basically uses &gt;10x the oasis file size.<br />
Is there a way to do streaming or another technique to deal with such huge memory usage scenario?</p>

<p>thx</p>
]]>
        </description>
    </item>
    <item>
        <title>How to get the current layer used in the GUI ?</title>
        <link>https://www.klayout.de/forum/discussion/2854/how-to-get-the-current-layer-used-in-the-gui</link>
        <pubDate>Tue, 17 Mar 2026 00:32:30 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>alto</dc:creator>
        <guid isPermaLink="false">2854@/forum/discussions</guid>
        <description><![CDATA[<p>I am trying to code a simple script that detect what is the active layer in the menu<br />
and use it to draw some polygon. (in this case it should be POLY1 )</p>

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

<p>I thought I can find something inside 'current_view()'</p>

<p>pya.Application.instance().main_window().current_view()</p>

<p>it seems I cannot find anything useful at this level</p>

<p>I tried to examine the content of</p>

<p>pya.Application.instance().main_window().current_view().begin_layers()</p>

<p>(with this simple script, that print some property of the layer, like : valid,.visible ...)</p>

<p>print("\n\nbegin_layers")<br />
ap=pya.Application.instance().main_window().current_view().begin_layers()<br />
while not ap.at_end() :<br />
 cur=ap.current()<br />
 print(cur)<br />
 print(cur.name,cur.valid,cur.visible)<br />
 ap.next()</p>

<p>Still nothing is telling what is the current active layer in the gui (may is there but I do not know how to access)<br />
I also trying a "promising" LayerInfo(),  pya.LayerInfo(), apparently intuition does not help.<br />
I am on the wrong track...</p>
]]>
        </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 fracture or decompose shapes into pure rectangles instead of trapezoids?</title>
        <link>https://www.klayout.de/forum/discussion/2855/how-to-fracture-or-decompose-shapes-into-pure-rectangles-instead-of-trapezoids</link>
        <pubDate>Wed, 18 Mar 2026 01:49:12 +0000</pubDate>
        <category>Python scripting</category>
        <dc:creator>Flyingmyd</dc:creator>
        <guid isPermaLink="false">2855@/forum/discussions</guid>
        <description><![CDATA[<p>Hi Matthias,</p>

<p>I am currently trying to fracture and decompose non-orthogonal shapes (such as circles or polygons with slanted edges) into purely orthogonal rectangles.</p>

<p>I have already tried using the decompose_trapezoids() and decompose_convex() methods via the Python API. However, they do not quite achieve what I am looking for.</p>

<p>What I actually want to achieve is a "staircase" approximation. As shown in the attached image, I am looking for a result where the shape is filled with a maximum inner rectangle (main field), and the curved edges are approximated by smaller, stepped rectangles (sub-fields).</p>

<p>(Please see the attached image for my desired output)</p>

<p>My questions are:<br />
Is there any built-in method or parameter in KLayout that can enforce decomposition into pure rectangles?<br />
If not natively supported, what would be the recommended approach or workaround using Python scripts?</p>

<p>Any guidance or code snippets would be greatly appreciated. Thank you in advance!</p>
]]>
        </description>
    </item>
    <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>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>
   </channel>
</rss>
