How to read polygons from GDS into numpy arrays?

Hi, I'm a beginner using klayout.db in python. How would I read polygons from a GDS into numpy arrays using klayout.db?

Comments

  • Hi @bertwa,

    Just for your info.

    Playing with ChatGPT

    <ChatGPT 4o Prompt>
    Using the KLayout Python module installed by 'python3 -m pip install klayout', I want to:
    1. Read a GDS2/OASIS file
    2. Iterate over all layers and polygons (including boxes)
    3. Store the vertices of each polygon in a numpy array
    4. Each numpy array needs to be stored in a dictionary, where the key is (layer, datatype, polygon_number)
    5. Finally, dump the dictionary. If the vertex list is long, truncate it appropriately.
    Suggest a sample code.
    

    The suggested code is not perfect in the beginning, as shown below, but it's a good starting point.

    MacBookPro2{sekigawa} Forum2694 (1)% ./f2694.py
    Traceback (most recent call last):
      File "/Users/sekigawa/GitWork/ForumKLayout/Forum/Forum2694/./f2694.py", line 41, in <module>
        for layer_index in range(layout.layer_indices()):
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: 'list' object cannot be interpreted as an integer
    

    Debugged Code

    import klayout.db as db
    import numpy as np
    
    # === Parameters ===
    filename = "inv2.gds"  # Replace with your actual GDS/OASIS file
    truncate_vertices = 10      # Max number of vertices to show when dumping
    
    # === Load layout ===
    layout = db.Layout()
    layout.read(filename)
    
    # === Dictionary to store polygons ===
    polygon_dict = {}
    
    # === Iterate through all cells and shapes ===
    for cell in layout.each_cell():
        for layer_index in layout.layer_indices():
            layer_info = layout.get_info(layer_index)
            layer_shapes = cell.shapes(layer_index)
    
            polygon_number = 0
            for shape in layer_shapes.each():
                if shape.is_box():
                    # Convert box to DPolygon
                    dbox = db.DBox(shape.box)
                    poly = db.DPolygon(dbox)
                elif shape.is_polygon():
                    poly = db.DPolygon(shape.polygon)
                else:
                    continue  # Skip non-polygonal shapes (e.g., paths, texts)
    
                # Extract vertices as a numpy array
                points = np.array([[pt.x, pt.y] for pt in poly.each_point_hull()])
                key = (layer_info.layer, layer_info.datatype, polygon_number)
                polygon_dict[key] = points
                polygon_number += 1
    
    # === Dump dictionary ===
    print(f"### Total number of Polygons/Boxes in {filename} = {len(polygon_dict)} ###")
    for key, vertices in polygon_dict.items():
        v_short = vertices if len(vertices) <= truncate_vertices else vertices[:truncate_vertices]
        print(f"{key}: {v_short.tolist()} {'... (truncated)' if len(vertices) > truncate_vertices else ''}")
    

    Sample Run


    MacBookPro2{sekigawa} Forum2694 (2)% ./f2694.py
    ### Total number of Polygons/Boxes in inv2.gds = 47 ###
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    (1, 0, 0): [[0.0, 2950.0], [0.0, 6150.0], [3000.0, 6150.0], [3000.0, 2950.0]]
    (2, 0, 0): [[450.0, 4200.0], [450.0, 5700.0], [1600.0, 5700.0], [1600.0, 4200.0]]
    (2, 0, 1): [[1950.0, 200.0], [1950.0, 1400.0], [2550.0, 1400.0], [2550.0, 200.0]]
    :
    :
    (8, 0, 7): [[2150.0, 5550.0], [2150.0, 5750.0], [2350.0, 5750.0], [2350.0, 5550.0]]
    (9, 0, 0): [[0.0, 0.0], [0.0, 1000.0], [3000.0, 1000.0], [3000.0, 0.0]]
    (9, 0, 1): [[0.0, 4900.0], [0.0, 5900.0], [3000.0, 5900.0], [3000.0, 4900.0]]
    
Sign In or Register to comment.