Hello
I have used the instance tool to make an array of an object, but I now need to write a script to select some of the objects randomly and delete them.
I am unsure of how to approach this problem, does the array behave like a matrix with indexes?
Thank you!
Comments
Not really. An array is a fixed array (as stored in GDS/OAS databases), individual elements cannot be addressed and changed directly. However there is a workaround - Matthias has invented something called cell variants: http://www.klayout.de/doc/manual/create_variants.html. Well maybe someone else invented it, but at least I've never seen it in other tools. I think this is what you want. Let us know how you get on.
The second option is just to go Edit > Selection > Resolve arrays, to make each element an individual instance again, and therefore be able to edit each one. Not exactly what you asked for, but I mention it in case you weren't aware.
David
Now that I have each object in an individual cell how can I call upon them in a script? Do I call upon them by their cell name like I would with a variable?
Sorry, if my questions sound strange, I'm more of a matlab/matrix kind of person.
Oh. Hah. I see your title says "Coding..." -- sorry I should have offered a coding solution earlier but I just read the post content.
I too came to KL with mostly just Matlab experience. So I got a book out and learned Ruby, which is something I recommend as it will speed your coding up significantly later. Now I love Ruby (aside from a couple small niggles) and I despise Matlab (nothing but niggles). Of course they are not used equivalently, but just speaking to the languages themselves rather than what they are used for.
Anyhoo, try this. It's not the only way to do it, for example a more coding-efficient approach may be to instance an array and then resolve it. But at least with this approach here you have some more insight and flexibility I think.
=
That's exactly what I needed to understand, I will look more into the example you gave me to try to make the grating i need.
Thanks lots!
For example, I am trying to delete 500 random shapes out of 2025 (45X45) shapes in an instance but because they are random some indexes will occur more than once.
counter = 1
while counter <= 500
row = rand(1..nx)-1 #here nx=45
col = rand(1..ny)-1 #here ny=45
if inst[row][col].nil? == true then
redo
else
inst[row][col].delete
counter +=1
end
end
I have tried to add an if-loop that will redo the iteration if the inst[row][col] is empty (because it has already been deleted) but I don't think the line if inst[row][col].nil? == 0 is not being understood and I keep getting this error
inst->instances() != 0 was not true in Instance::delete
is there a way to tell it not to delete twice if there is no shape in the instance at that index?
Hi,
the
inst
array will holdRBA::Instance
objects which you can think of as pointers into the database. By calling their "delete
" method the original instance in the database is deleted.The pointers still exists, hence the
inst
members are stillRBA::Instance
objects. But after callingRBA::Instance#delete
they point to "nothing". Or in other words, they become invalid.They won't become nil, but their "
is_valid?
" method will return false. Any attempt to access their attributes will fail with an exception too.So you can easily avoid a duplicate deletes by doing this:
Matthias
I have tried the method ".is_valid" but even that gives me an error. It seems like it won't let me use any method on a deleted object.
> inst[0][0].is_valid?
true
> inst[0][0].delete
> inst[0][0].is_valid?
RuntimeError: Internal error: /Users/mhe/src/klayout-0.23.2/src/gsiDeclDbCell.cc:2109 inst->instances () != 0 was not true in Instance::is_valid?
(console eval):1:in `is_valid?'
(console eval):1:in `<main>'
Thanks everyone!!! This has been super informative.
Hi Ines,
Sorry for the confusion: "is_valid?" is actually giving that internal error in 0.23. This is already fixed in the upcoming 0.24 version.
"is_null?" is not a bad choice in your case.
But be aware that there is a subtle difference between "is_valid?" and "is_null?": "is_valid?" may be able to detect if the instance was deleted through another way, while "is_null?" only checks whether the instance was deleted by using this Instance object's delete method.
Deleting instances while keeping the pointer is somewhat risky: if you keep instances and delete the database instances behind it some other way, the pointer might become invalid without you noticing it. The technical reason is that the database, being an optimized system, does not keep track of the pointers referring to objects within it.
Here is an example demonstrating that effect:
So accessing b will probably result in a crash. "is_valid?" was meant to mitigate this problem somewhat, but that is only halfway true: if you delete the whole cell containing the instances, "is_valid?" won't be able to figure out what happened as well and a crash might happen. So better not keep Instance objects for a longer time except in simple cases like yours.
Thanks for mentioning this.
Matthias