It looks like you're new here. If you want to get involved, click one of these buttons!
Hello,
I am looking into changing PCells via Ruby scripting. The following minimal test case should be run with a layout which holds a TEXT PCell from the Basic library. This instance has to be selected in the LayoutView
.
module PCellTest1
include RBA
lv = Application::instance.main_window.current_view
lv.each_object_selected do |sel|
if sel.is_cell_inst?
inst = sel.inst
cell = inst.cell
if cell.is_pcell_variant?(inst)
if "#{cell.library.name}.#{cell.name}".start_with?("Basic.TEXT")
inst.cell.change_pcell_parameter(inst, "text", "HELLO PCELL")
end
end
end
end
end
When I run this code, it raises an error Trying to replace an object in a list that it does not belong to in Cell::change_pcell_parameter.
The Basic.TEXT instance in the current cell is obviously unchanged, but I do see that this script has created a new Basic.TEXT cell in the database, which does have the text
parameter set to HELLO PCELL
.
Seems like the only thing missing is to replace the current inst
with this new cell. Do I have to do that manually?
Comments
As I was unable to build klayout-r2739, today I tried using the klayout-0.24-python-eval version (which by the way built fine on my Ubuntu VM), on both Windows 7 and the Ubuntu VM.
The script from above led to the very same error on both platforms, so I also tried the Python version of it:
This also failed with the same error, on both platforms.
However if you instead do the following process it will work. (You alluded to this.) If you get stuck, let me know and I can work up a sample script.
1. Get all the information from the selected PCell (transformation, 'text', layer, etc)
2. Instantiate the new PCell with same information but changed 'text'
3. Erase the former PCell
Hi all,
well, I guess there is some explanation required :-(
"cell.change_pcell_parameters(inst, ...)" will adjust the PCell parameters if the instance within cell, not of the instance of the cell. That is an important difference: the cell is the container for the instances and it's the provider for the method to change the instance's parameters. For that, the instance passed to "change_pcell_parameters" as the first argument has to be a instance in the cell.
Your code uses the cell the instance points to which is not the cell which holds the instance and that's why you get this error message. Confused? I guess so and I admit that's a bit strange.
You could fix that by using:
which looks a bit redundant. Therefore there is a more convenient method: you can simply use
But: in general, modifying the properties of selected objects is not the strength of the scripting API. You can change the PCell parameters of the instance, but that bears the risk of invalidating the selection, it will not automatically update the display and leave unused PCell variants in the layout which are not cleaned up automatically. Deleting the instances and creating new ones works a little better, but still not perfect. Supporting the case you look for will require some enhancements in the engine.
Matthias
Hi Matthias,
Thank you for this explanation! Now the error message makes more sense to me :-)
The line
now works, for both the 0.24-python-eval version on Windows and the r2739 build on my Ubuntu 14.04 VM.
For the sake of others trying this as well, the cleaner version
worked for me only on my r2739 Ubuntu build (it also didn't show up in the Assistant yet), so I believe this is a brand new feature :-)
You're right, the script leaves behind old (and unused) PCell variants. I am trying to write a script doing the same thing as the Object Properties dialog when changing a parameter and clicking "Apply", so the only thing missing now would be the "cleaning up" stage - which IMO is a bit less important than getting the main functionality working as it does now.
I guess the Object Properties dialog also has to deal with the selection invalidation issues internally?
Hi friendfx,
Regarding the properties dialogs and the selection invalidation: it's true, the dialogs do a little more - they update the selection to reflect the new situation.
But right now, the selection cannot be modified inside a script, so that option is not available in scripts. The script feature was not designed initially to substitute the user interface functionality. You can only clear the selection currently in order to stay on the safe side.
Matthias
Hi Matthias,
Am I correct in that the current implementation of
RBA::Cell.change_pcell_parameter
doesn't callcoerce_parameters
beforeproduce
?Thanks, Chris
Hi Chris,
Oh yes ... it looks like I was somewhat off track regarding my own code.
When digging through the implementation, I find the following
coerce_parameters
is only called when editing the parameters in the user interface. Not when changing them through script methods.I admit that is somewhat contrary to what I mentioned in the other posts. But considering these discussion I guess that makes like a bit easier, since one does not have to consider the implications. Plus, I'd not like to change that because that will substantially modify the behaviour.
But what's definitely missing is an easy way to enforce
coerce_parameters
. How about something like "Cell#coerce_pcell_parameters" or "Instance#coerce_pcell_parameters"?Matthias
Hi Matthias,
I guess that's fine as there is already a workaround: calling
coerce_parameters
like it is done in thepcell_variant
code.That would make the scripts a bit shorter (and maybe faster to run?), but since we already have a solution, this wouldn't be too high on my priority list.
Thanks for clearing that up, regards Chris
EDIT:
Just for completeness, I think the
coerce_parameters
method is also called when opening a GDS file while the PCell library containing the PCells is already in memory?Hi Chris,
I hardly dare to make any statements now, trying not to add to the confusion I created before.
But looking at the code, there is no
coerce_parameters
call in the GDS reader. Basically, the GDS (and OASIS) reader will simply recover the parameter set that was present when the PCell's have been saved. So if the parameters have been coerced before, the will be consistent after recovering them from GDS. But if the code has changed in between,coerce_parameters
should not be called once again.Do you see any calls of
coerce_parameters
when loading a GDS file?To be frank, I have not considered the case of substantial modifications of PCell code in a non-backward compatible way. I'd suggest to stay backward compatible as far as possible. The only provision that is made is that new parameters get initialized with their default values.
If the PCell code is going to develop substantially, maybe it's a good practice to include a hidden version number parameter which allows the code to detect whether parameters have been saved for a previous version. When the implementation changes considerably, the version number could be increased indicating a new interpretation.
Matthias
Hi Matthias,
I really appreciate your comments, even if they may cause a bit of confusion sometimes... (I do too).
Investigating a bit more I found that the
coerce_parameters
call I saw when loading a GDS file was done by apcell_variant
call from within another PCell'sproduce
call.Or in other words:
produce
method.pcell_variant
method I had posted.pcell_variant
method calls thecoerce_parameters
method of the child PCell.I guess am just a bit surprised to see a PCell's
produce
method being called (point 1), but now that I know that, it all makes sense.Thanks for the suggestions regarding the PCell's backward compatibility. Thinking some more about this, I agree that the PCells will probably be developed once and that after an initial phase of uncertainty, they will (have to) be backwards compatible anyway, otherwise it would be very difficult to re-run old layout generation scripts which used an older version of the same PCell. My colleagues and I are already dealing with similar cases anyway and instead of changing an existing cell in an incompatible manner, we simply have to come up with a new name. This solves all such issues.
Best regards, Chris