Multiple rectangles with a linearly increased spacing

Hello,

Since I'm new to Klayout, I'm learning from YouTube. I made multiple attempts to create a rectangle array with a single column and linearly variable spacing. I can create a column of rectangles with identical spacing by using an array function. I need guidance from someone to create single column rectangles with linearly variable spacing.

Thanks in advance
Krish

Comments

  • edited August 2024

    Hi @Krishp

    Try this out, it's a PCell that provides a variable that allows you to define custom spaced/rotated/mirrored/visibility for array elements, if such thing is still qualified as a array.

    Usecase

    Parameters

    This provides a interface that allows you to use python syntax to define it's geo location.

    • WIDTH and HEIGHT provides an access to current size setting
    • by using ROW and COL as variable to aquire current element sequence
    • and ROWS and COLS provides an access to row counts and column counts
    • Xpos , provides an access to current element X location
    • Ypos , provides an access to current element Y location
    • ROT , provides an access to current element Rotation angle
    • MIR, provides an access to current element Rotation angle
      , it should provide good enough degrees of freedom to play with.

    The parameters are calculated in a order from top to bottom, so each field does not have access to it self and parameters with lower priority.

    (Cannot do recursive calls, so invalid paramaters will be trimmed automatically when decleared)

    but since this PCELL uses evals to achieve this function, dangerous things can happen if you tried to access or assigning variables that is not ment to be changed.

    Now variable evaluation is done using ASTEVAL to parse the command, reduce the chance of uintentional system distructive code from running in the cell.

    Installation

    To enable this you need to unzip the attached file and place the content Lib_ArrayMagic into you ..\KLayout\pymacro folder, for instance mine on a Win system is at : C:\Users\RawrRanger\KLayout\pymacros

    After placing the file into pymacros folder please restart you application and you should able to see there' a new Library installed and can be accessed from :

    • Toolbar Instance
    • Editor options Dock Instance Tab
    • Select Library : ArrayMagic
    • Select Cell : FunctionArray

    layout examples will becoms a PCELL array once the library is installed correctly

  • edited August 2024

    For some special use cases and examples:

    Dounat pattern filling

    Width 10
    Height 10
    Row counts 50
    Col counts 50
    X position function COL * 20 - (COLS/2) * 20 + 10
    Y position function ROW * 20 - (ROWS/2) * 20 + 10
    Visibility function 200 < (Xpos ** 2 + Ypos ** 2)** (0.5) < 480

    Hex type array

    Width 10
    Height 10
    Row counts 10
    Col counts 10
    X position function COL * 20 + ( 10 if (ROW %2) == 0 else 0)
    Y position function ROW * 15

    Circular array

    Width 10
    Height 10
    Row counts 10
    Col counts 1
    X position function 50 * math.cos(2 * math.pi / ROWS * ROW)
    Y position function 50 * math.sin(2 * math.pi / ROWS * ROW)
    Rotation function 360 / ROWS * ROW

    Ring type array

    Width 3
    Height 1
    Row counts 100
    Col counts 4
    X position function (COL+1) * 25 * math.cos(2 * math.pi / ROWS * ROW + math.pi/3)
    Y position function (COL+1) * 20 * math.sin(2 * math.pi / ROWS * ROW)
    Rotation function math.atan(Ypos/Xpos) / math.pi * 180
    Visibility function (ROW % (COLS - COL)) ==0

    Polynomial array

    Width 30
    Height 30~~~~
    Row counts 1
    Col counts 65
    X position function COL * 15 - (COLS/2) * 15
    Y position function (1e-5) * Xpos **3 + 0.005 * Xpos ** 2 + 0.1 * Xpos + 5
    Mirror function Xpos > 0

    3x3 grouped Array

    Width 20
    Height 10
    Row counts 9
    Col counts 9
    X position function WIDTH * COL + (15 * int(COL/3))
    Y position function HEIGHT * ROW + (15 * int(ROW/3))
    Mirror function ROW % 2 == 0

    Crossed box array

    Width 10
    Height 10
    Row counts 9
    Col counts 9
    X position function COL * 20
    Y position function ROW * 20
    Visibility function (COL in [0, COLS-1]) or (ROW in [0, ROWS-1] or ROW==COL or (ROWS-1-ROW)==COL)

  • The array is actually not drawn individually, instead is done by placing PlaceHolder cells accroading to the scripted location.

    This approach allows you to do a cell replace of the PlaceHolder cell with something useful and then don't forgot to use Convert to static cell function to make the cell replacement becomes a permanent change.

    If Conver to static cell is not applied, the change will be revert everytime PCELL refreshes it self, to find out more about this limitation please check these disscussion.

  • Hey RawrRanger,

    This is very cool, thanks for sharing!

    Cheers,

    Tomas

  • Hi @RawrRanger,

    yes, this is definitely cool!

    I will not need matplotlib anymore :)

    A brief warning is in order I hope: If you use eval on a user string, the user string basically can do something malicious such as os.system(...). So eventually this is a way to sneak in malicious code into a GDS file. This is not the only way to do that and one should always be careful with files from external sources, but I just wanted to point this out.

    KLayout provides a simple expression parser internally, which maybe is easier to use:

    # compiles the expression
    > expr = pya.Expression("A + B", { "A": None, "B": None })
    # sets variable values
    > expr.var("A", 1)
    > expr.var("B", 17)
    # evaluate
    > expr.eval()
    18
    # change value and re-evaluate
    > expr.var("A", -5)
    > expr.eval()
    12
    

    One advantage is that Expressions cannot access variables of your script.
    However, it is not much safer as currently it has access to all Qt classes, including "QProcess" for example:

    > expr.text = "QProcess.new()"
    > expr.eval()
    <klayout.pyacore.QProcess object at 0x7f2d580f6500>
    

    Just imagine what you can do with that ...

    I think it is possible to create some kind of "safe mode", but there is always a tradeoff between security and functionality.

    The expression syntax is described here: https://www.klayout.de/doc-qt5/about/expressions.html

    There are some small differences. For example, "A**2" is written as "pow(A,2)".

    Execution times are better with KLayout Expressions:

    This takes 5.6s on my machine:

    sum = 0
    for i in range(0, 1000000):
      sum = eval("sum+1")
    print(sum)
    

    While the same with Expressions takes 2.3s:

    e = pya.Expression("sum+1", { "sum": 0 })
    sum = 0
    for i in range(0, 1000000):
      e.var("sum", sum)
      sum = e.eval()
    print(sum)
    

    Best regards,

    Matthias

  • edited August 2024

    Hi @RawrRanger, Thank you very much for taking the time to help! Your examples were incredibly clear and made all the difference in solving my problem. I greatly appreciate your help and knowledge.

  • edited August 2024

    Hi Matthias

    Thanks for the suggestion,

    Indeed having code running through eval directy could cause bad things, i've tried Expression and generic builtoin function AST but alot of functions and syntactic syrup that we love becoms not avaliable.

    Too keep the agility, I've switched to use ASTEVAL package, which seems to be able prevent most of the dangerous code from running through eval but also allows most of the basic math/list comprehension stuff.

    The down side is the execution time of ASTEVAL is around 5 times slower than the fastest while doing a a 1000000 cycle sum test :

    • pya.Expressions : 1.1s
    • python eval : 3.1s
    • ASTEVAL eval : 5.3s
Sign In or Register to comment.