Error when using change_pcell_parameter

edited April 2015 in General

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

  • edited November -1

    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:

    import pya
    
    lv = pya.Application.instance().main_window().current_view()
    for sel in lv.each_object_selected():
      if sel.is_cell_inst():
        inst = sel.inst()
        cell = inst.cell
        if cell.is_pcell_variant(inst):
          cell_name = "%s.%s" % (cell.library().name(), cell.name)
          if cell_name.startswith("Basic.TEXT"):
            cell.change_pcell_parameter(inst, "text", "HELLO PCELL")
    

    This also failed with the same error, on both platforms.

  • edited November -1
    This may be an unhelpful comment, but I will just mention that I too was unable to see why that's not working. Well at least you know someone else had the problem!

    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
  • edited November -1

    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:

    inst.parent_cell.change_pcell_parameters(inst, "text", "HELLO_PCELL")
    

    which looks a bit redundant. Therefore there is a more convenient method: you can simply use

    inst.change_pcell_parameters("text", "HELLO_PCELL")
    

    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

  • edited November -1

    Hi Matthias,

    Thank you for this explanation! Now the error message makes more sense to me :-)

    The line

    inst.parent_cell.change_pcell_parameters(inst, "text", "HELLO_PCELL")
    

    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

    inst.change_pcell_parameters("text", "HELLO_PCELL")
    

    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?

  • edited November -1

    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

  • edited May 2015

    Hi Matthias,

    Am I correct in that the current implementation of RBA::Cell.change_pcell_parameter doesn't call coerce_parameters before produce?

    Thanks, Chris

  • edited November -1

    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

  • edited June 2015

    Hi Matthias,

    I'd not like to change that because that will substantially modify the behaviour.

    I guess that's fine as there is already a workaround: calling coerce_parameters like it is done in the pcell_variant code.

    How about something like "Cell#coerce_pcell_parameters" or "Instance#coerce_pcell_parameters"?

    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?

  • edited November -1

    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

  • edited November -1

    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 a pcell_variant call from within another PCell's produce call.

    Or in other words:

    1. Loading a GDS file with a PCell variant will call the PCell's produce method.
    2. My specific PCell instantiates another PCell variant, using the pcell_variant method I had posted.
    3. This the pcell_variant method calls the coerce_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

Sign In or Register to comment.