Random Grid Snapping Error

Dear Matthias,

Hi, I am a PhD student currently working in a company in the Netherlands and I am using Klayout and Nazca for Photonic chip layout design. My main assignment is to investigate the grid snapping error when exporting the design from Nazca to Klayout.

It seems there is a random snapping of points when Klayout truncate floating coordinates after defining or moving polygons to the left or to the bottom. As you can see on the picture above, when the polygon is move to the left by 0.5nm, only the points on the left side is moved but not the points on the right, which effectively widen the polygons. Truncation of 0.5 to 1 nm didn’t happen for points on the right side. This happens for polygon of certain size and shape and the occurrence seems to be random.

I am wondering if there is an internal mechanism in Klayout that disable truncation in certain cases. Thank you very much for you time.

Best Regards,
Francis(Yu) Tian


  • @francistian Yes, there is.

    KLayout borrows the "database unit" concept from GDS2 and similar other formats. This means that all coordinates are represented as integer multiples of the database unit. Typically, the database unit is 1nm which would explain the snapping you observe.

    Snapping is not random, but follows strict rules. For the implementation see https://github.com/KLayout/klayout/blob/master/src/db/db/dbTypes.h (line 110). Snapping is per-point and does not necessarily preserve relative dimensions.

    To avoid snapping in general, just use a database unit which is small enough to represent your layout with the desired accuracy. You can set the database unit manually in Edit/Layout Properties.


  • Dear Matthias,

    Thank you very much for your speedy reply. I understand the snapping mechanism. What I was describing is a phenomenon that the snapping sometimes doesn't work for -0.5nm when i use nazca to define the structure. The code below is used to generate a polygon and you can see the snapping didn't happen for points on 1099.9995um

    import nazca as nd
    points = [(0, 0.0), (0, 166.66666666666666), (0, 333.3333333333333), (0.0, 500), (33.333333333333336, 500), (66.66666666666667, 500), (100, 500.0), (100, 333.33333333333337), (100, 166.66666666666669), (100.0, 0), (66.66666666666666, 0), (33.33333333333333, 0)]
    x_shift = 999.9995
    y_shift = 5000
    rotation = 0
    layer = (1,0)
    s = nd.Polygon(points,layer)
    s.put(x_shift, y_shift ,rotation)

    Best Regards,
    Francis Tian

  • I don't know what your desired, or your technology
    proper DBU may be.

    When I see this:
    (100, 333.33333333333337), (100, 166.66666666666669)
    I have to wonder whether you're asserting a number
    with precision beyond your DBU, and it's displayed at
    DBU precision but stored and acted upon (say) at double
    precision. Because you need "more bits" than any result
    in order to ensure the result (and input operands) are
    properly represented, right?

    A point that's just a hair off the snap-grid would act
    differently (snap-wise) moving to the left or to the right -
    one direction would round down (maybe to not snap)
    and one would round up (to snap).

  • @francistian I do not know what happens inside the nazca module. It's not maintained by me. If it internally uses a floating point representation and move is a transformation in floating point space, @dick_freebird is correct with his analysis.

    Maybe you could take this to the maintainers of the nazca Python module?

    Kind regards,


Sign In or Register to comment.