It looks like you're new here. If you want to get involved, click one of these buttons!
Hi Guys,
I am making a PCell library where the PCells have external dependencies and I need some way to trigger a re-draw of the placed PCells in a layout. How can I do this from Python?
Thanks,
Robert
Comments
The method to do this is "Cell#refresh". But you will need to call it in the "proxy cell".
If you have a layout which instantiates a PCell, KLayout generates a "proxy cell" which is basically linked to the PCell but provides a mirror of the current layout. So if the Library goes away, KLayout still has a copy of the layout.
This is the proxy cell. It lives inside the layout you place the PCell and this is the cell you need to call "refresh" on. As a simple solution, you can simply call "refresh" on all cells of your layout:
Matthias
Thanks Matthias,
I tried this, but seems my hackish-solution cannot work with this approach. I get this error message:
I guess this has to do with this context-dependent thing with the proxy cell you try to explain to me, but I cannot quite figure it out. What I did was I use the
self.layout()
object in mypya.Library
's__init__
-function and when I trigger an external change (which comes from apya.QFileSystemWatcher()
and an external file) I runAnd get above error. What am I not getting?
"layout" was mean to be the client layout which is using the library, not the layout inside that library.
You cannot trigger a refresh from inside the library currently. The only thing that triggers a refresh currently is the re-registration of a library. However registering the same library again will probably crash the application. You can only create a new library with the new layout and register it under the same name than the existing library. This will replace the old library and trigger a refresh.
Matthias
Thanks Mattias,
Can you point me to some documentation for me to understand where to put this code then? I have not understood I think where to execute that code.
Thanks,
Robert
@ravn The code must be some on your side. You have somewhere declared a library class with the PCell code. There must be something like this example of mine:
Eventuall all you need to do is to execute the "TestLib2::new" again to create a new library object and re-register it.
Or you wait until I release 0.27.8, because it gets this: https://github.com/KLayout/klayout/issues/996
Matthias
This is super! I will wait for 0.27.8.
0.27.8 is released. Let's see whether it works for you
Matthias
Hi @Matthias,
I tried this feature now. Unfortunately, it does not seem to work as I expected (I'm sure I misunderstood something). I am not sure what
refresh
does under the hood, but in my case, I could not see any change in the layout in the used PCells. As described above, my PCells have external dependency on a file and I am using a file-watcher from QT to trigger when that file has changed. That part works and I get a notification. However, when runningrefresh
in the library, I cannot see the reflected in the rendered shapes.I would have expected the library
refresh
-function to call all PCellsproduce_impl
, but perhaps I am mistaking?Thanks,
Robert
You need to call "refresh" on the Library. As explained above, you cannot call it on the layout inside the library, because that is not the client layout which uses the PCell.
Please paste some code - I don't want to guess what you're actually doing.
Matthias
Here is the code from the example Python PCell. Only changed where it is marked by
<===========
Then I make a small script to refresh:
Here I try to refresh in two ways, using the cells refresh and using the library. Non of them show any change in the circle radius. If I just re-run the MyLib-code, I can clearly see that the circle radius is changing from run to run due to the
rand()
call.Hope this illustrates my issue.
Kr,
Robert
Hi Robert,
Thanks a lot. Such code is very helpful indeed.
So I see. You want to force a "re-computation". Sorry for the nit-picking, but that is something slightly different. Well, I admit it's also a bit confusing.
So refresh just restores the connection between library and clients. But it does not force a re-computation of the PCells (well, that can be added later). PCells are cached inside the library and the implementation assumes that the PCells do not change geometry spontaneously and as long as neither the library object nor the parameters change there is no need for an update.
But you can force an update by calling refresh also on the library cells. The library cells represent incarnations of the PCells and calling refresh on them triggers the recomputation. So the code to trigger a recomputation is:
The first loop will trigger the re-computation, the final refresh will transfer those recomputed cells into the client layouts.
As this is probably a common use model, I will consider incorporating the per-cell refresh into the library refresh (https://github.com/KLayout/klayout/issues/1057), so finally a single "ml.refresh()" call is sufficient.
Matthias
Thanks for all support @Matthias!
Now it works almost as expected I have some issue when creating a new library object, that is when I re-run the -lym-file. Not sure exactly how to describe the problem - it looks like the shapes generated from my PCell in some cases loose it's connection to the library. I'll look around and perhaps file another post here if I understand it better. One thing I noted is that the python
__del__
-method of the library does not seem to be run, so I'm guessing the python library object is not deleted. Maybe this is a memory leak?The library I have been working on is starting to show some functionality and if you would be interested, I could give you a demonstration of the features. It might be of interest for others, despite still being under heavy development.
Kr,
Robert
@ravn Very good
BTW: Are you planning to make the library available to others as open source? In that case you may want to put it on a public repository and let others have a look at it.
Regarding the
__del__
I could not readily reproduce it. I used the Python PCell sample and added__del__
like this:In my case,
__del__
was called whenever I reran the .lym file.Kind regards,
Matthias
@Matthias : Thanks. Our code is probably not ready for to public yet, there is still too much that needs to be polished, but we are aiming at FOSS'ing it once it has matured a bit more.
It uses this feature that I explained in an earlier post (and you were skeptical to where parameters are actually not numbers but rather Python code. This has some clear advantages, I think especially for researchers where you often have to test stuff and need to change things in a flexible manner over time.
I see. Do worry if I am sceptical - but I am curious about your application. And thanks for considering FOSS!
Matthias
If you want a short demonstration, send me and email and we can book a Zoom call. The library is for designing quantum processors.
R.
That may sound somewhat funny, but I do not see your mail adress
But I'm curious. Maybe you can send me a mail to contact "at" klayout.de ? I will get back to you then.
Matthias