Forum Replies Created

Viewing 20 posts - 121 through 140 (of 194 total)
  • Author
    Posts
  • in reply to: Bent Taper #5635
    Ronald
    Keymaster

    Hi Douglas,

    Note that since Nazca-0.5.1 there is the viper() method:

    viper() method

    and since Nazca-0.5.2 also a cobra_p2p() interconnect with tapering functionality.

    Ronald

    in reply to: Need to define periodic holes next to the waveguide #5631
    Ronald
    Keymaster

    Dear Paul,

    That is a good first step. The question is what accuracy do you need? Reusing available modules may save you time and you may, therefore, look into computer vision and animation where arc length on a parametric curve is common (to determine the speed of a camera or other object for example).

    See for example opencv:
    https://pypi.org/project/opencv-python/
    https://opencv.org/opencv-2-4-8/

    Ronald

    in reply to: _trapezoid() in nd.util #5629
    Ronald
    Keymaster

    Dear Paul,

    The _trapezoid draws a symmetrical trapezoid with base width w0 and top width w1, The central axis between the base and top runs between points xy0 = (x0, y0) and xy1 = (x1, y1). Note that the trapezoid can, therefore, have any orientation in the xy coordinate system. The “top-left” terminology in de docs string (version 0.5.2) is, therefore, relative and depends on the actual start xy0 and end xy1 coordinates. The ‘counter clockwise’ in the doc is also relative and it seems better to remove it. This may be a more clear doc string:

    def _trapezoid(xy0, xy1, w0, w1):
        """Calculate the four coordinates of the trapezoid that is defined by the
        line segment through two points xy0 and xy1 with widths w0 and w1.
    
        Args:
            xy0 (float, float): point (x,y), segment start
            xy1 (float, float): point (x,y), segment end
            w0 (float): width of line segment start
            w1 (float): width of line segment end
    
        Returns:
            list of (float, float): list of 4 (float, float) point coordinates (x, y)
            tracing the outline of the trapezoid.
        """

    Ronald

    in reply to: Need to define periodic holes next to the waveguide #5617
    Ronald
    Keymaster

    Dear Paul,

    If you have a parametric curve p(t) = (x(t), y(t)), then for periodic placement (of cells) along the curve you would have to
    reparameterize the curve by arc length. A pdf on this can be found e.g. here or here.

    Ronald

    in reply to: Error in defining width #5597
    Ronald
    Keymaster

    The cell (building block) like the phase shifter is defined by a foundry (in a PDK), you can not change which parameters is has (unless you define your own building block, which may require advanced knowledge of a technology/process). You can change, however, how you connect to a building block.

    For an example on connecting (building blocks) see https://nazca-design.org/connecting-to-a-building-block/
    For an interconnect taper use e.g. demofab.deep.taper(length=50, width2=3.0).put(...)
    A taper has keywords width1 and width2, but if not provided it defaults to the interconnect width.

    Ronald

    in reply to: Error in defining width #5595
    Ronald
    Keymaster

    Dear AleksandarK,

    This is not a design “error”, but as Python indicates a TypeError: The phase shifter here does not have a keyword parameter “width”.

    In building blocks you basically never set the cell width directly, but possibly other parameters that may affect the cell width.

    Note that all interconnects do have a “width” keyword. Hence, if needed, adapt the interconnect to the building block pin width when connecting, e.g. with a “taper” or “ptaper”. See also here

    Ronald

    Ronald
    Keymaster

    Good to hear, thanks. I will keep this “optional” record added in exports after 0.5.1 as some tools/settings seem to expect it, while in other cases where it is considered optional it should not harm beyond a slightly larger gds file.

    Ronald
    Keymaster

    Dear Andreas,

    That seems indeed to point to the “optional” strans record.

    A simple fix for your case is to replace in gds.py line 129 (0.5.1) or 127 (0.5) elif adeg != 0 and array is not None: with else:.

    Ronald

    Ronald
    Keymaster

    Dear Andreas,

    The class structure does not make a difference and to simplify things, the code below should give the exact same output file as your example in the initial question with 180 degrees:

    import nazca as nd
    import nazca.demofab as demofab
    
    ic = demofab.deep
    
    with nd.Cell(name='WG', instantiate=True) as wg:
        ic.strt(length=100, arrow=False).put()
    
    ic.strt(length=20, arrow=False).put(200, 0, 180)
    wg.put()
    
    nd.export_gds(filename='stdin.gds', ascii=True)

    The problem at the record at offset 282 seems to be the angle record of the sref. If you set instantiate=False in de code above you get the example that you posted as stdin that did not have a Calibre problem. I still do not see why the angle in the sref should be an issue. It is a 8-byte real as it is supposed to be. There is an optional strans record in gds before the angle record. Nazca leaves it out when there is none needed. A wild try is to see if it loads in Calibre in your situation with a strans record added using wg.put(flip=True).

    Alternatively, see what happens when you load the gds in KLayout and save it there to gds again or save the file to OASIS, load it again, and save to gds. After that try to load in Calibre.

    Ronald
    Keymaster

    edit: I see you already found this solution before this post.

    Dear Andreas,

    The most straight forward way to try the ‘utf-8’encoding on your system for ascii output is to go to file gds_import.py in your Nazca installation and replace in line 777 with open(filename, 'w') as f: with with open(filename, 'w', encoding='utf-8') as f:. It has also been updated for the next release.

    Ronald

    Ronald
    Keymaster

    Dear Andreas,

    Code ā€˜\u250c’ is for some ascii art to visualize structures: ā”Œ
    I guess the encoding error is related to settings in Anaconda on Windows.
    I’ll see if enforcing an encode(“utf-8”) in the ascii export will help out.

    Considering the different behaviour of the two gds exports it may indeed be helpful to checkout the ascii.

    Ronald

    Ronald
    Keymaster

    Dear AleksandarK,

    Pins are added at cell level. A good example you may have been looking at as you mention is in getting started part “7 Creating a parametrized DBR laser”. After a cell is closed (after leaving the with-context), you can’t add stuff to the cell any more and pin positions and properties are fixed (which is intended). Parameters to add to a pin at definition time are described here.

    Ronald

    Ronald
    Keymaster

    Dear Andreas,

    If the issue is not resolved yet, could you post the resulting .asc file generated by your example above with “ascii=True” in export_gds()?

    Being picky on naming, note that the method named “_generate_instances” in the example returns a Cell object rather than an Instance object.

    Ronald

    Ronald
    Keymaster

    Dear AlexsandarK,

    This link to getting started may be helpful to start connecting components, as well as this topic on cells and instances.

    In your specific case you want to connect the phase shifter (electro-optical phase modulator) to pin[‘b0’] of the coupler you placed:

    C = coupler.put(0)
    demo.eopm_dc().put(C.pin['b0'])

    Ronald

    Ronald
    Keymaster

    Dear Andreas,

    That’s quite a class structure for drawing a waveguide, but I guess you have bigger plans with that.
    The question is if those extra structures are changing anything in the gds that you are generating, but I don’t see how that would be possible.

    I can view both gds cases you describe without a problem in KLayout, so the gds files seem okay from that perspective.

    I am aware there have been crashes in Calibre several years ago due extensive use of curved waveguide structures as they may occur in photonics, e.g. in AWGs. That was fixed in Calibre. In this case I don’t see immediately how the 180 degree would change anything significant.

    A way forward is to export the gds in ascii format and see if it provides hints:
    nd.export_gds(filename='GDS_test\\stdin.gds', ascii=True)

    A second thing to try is to replace WaveguideInClass(L=100, ic=ic).put() by demofab.deep.strt(lenght=100).put(), which should give you the same gds, and check whether Calibre thinks the same.

    Ronald

    in reply to: Identify Cells already created #5552
    Ronald
    Keymaster

    Dear Daneel,

    Using the @hashme decorator should work for you as discussed in this topic

    import nazca as nd
    
    @nd.bb_util.hashme('rectangle', 'length', 'width') # gives default cell name 'rectangle_80_80'
    def rectangles(length=80, width=80):
        with nd.Cell(hashme=True) as rectangle:
            rect = geom.box(length=length, width=width)
            nd.Polygon(points=rect).put(0, 0)
        return rectangle

    In case you still want to know which cells have been defined you can try the following code to print all cell names:

    import nazca as nd
    
    for name in nd.cfg.cellnames.keys():
        print(name)

    Ronald

    in reply to: Changing GDS database units #5549
    Ronald
    Keymaster

    Dear David,

    Your solution will work. To avoid hacking in the modules directly, setting database units can be done more flexible using the following script lines:

    import nazca.gds_base as base
    base.gds_db_unit = 0.00001
    base.gds_db_user = 0.0001

    Ronald

    in reply to: Directional Coupler in Nazca #5548
    Ronald
    Keymaster

    To make it more robust Xaveer’s example can be parametrized and pins can be set by reference:

    import nazca as nd
    import nazca.demofab as demo
    
    def coupler(length=20, sep=100, gap=20):
        with nd.Cell("Coupler") as C:
            # Upper arm
            u1 = demo.shallow.sinebend(distance=100, offset=-0.5*(sep-gap)).put(0, 0.5*sep)
            demo.shallow.strt(length=length).put()
            u2 = demo.shallow.sinebend(distance=100, offset=0.5*(sep-gap)).put()
    
            # Lower arm
            l1 = demo.shallow.sinebend(distance=100, offset=0.5*(sep-gap)).put(0, -0.5*sep)
            demo.shallow.strt(length=length).put()
            l2 = demo.shallow.sinebend(distance=100, offset=-0.5*(sep-gap)).put()
    
            # Add pins
            nd.Pin("a0", pin=u1.pin['a0']).put()
            nd.Pin("a1", pin=l1.pin['a0']).put()
            nd.Pin("b0", pin=u2.pin['b0']).put()
            nd.Pin("b1", pin=l2.pin['b0']).put()
        return C
    
    coupler().put(0, 0)
    coupler(length=40, gap=5, sep=50).put(0, 100, 10)
    
    nd.export_plt()

    Note that setting pins by reference can be done using the ‘pin’ keyword. This will automatically copy all pin properties to the new pin.

    # p is pin
    nd.Pin("a0").put(p) # set the new pin at the position of p
    nd.Pin("a0", pin=p).put() # copy all properties of p and put it on the position of p

    Ronald

    in reply to: Caching non-parametric cells #5538
    Ronald
    Keymaster

    Dear Dima,

    You indeed already found the hashme.
    Note that nd.Cell(hashme=True) is sufficient. The cellname is taken from the first hashme argument.

    The use of hashme=True of coarse assumes that the hashme decorator is applied to the function your cell definition resides in in the first place, as shown in the examples.

    Regards,
    Ronald

    in reply to: Caching non-parametric cells #5535
    Ronald
    Keymaster

    Dear Dima,

    There are two ways around the renaming.
    (Note the renaming by default guarantees that cells are always unique.)

    1) Nazca can recognize if cells (parametric or not) have been called before by applying the hashme decorator:

    import nazca as nd
    
    @nd.bb_util.hashme('cellname')
    def sh_to_dp():
        with nd.Cell(hashme=True) as C:
            nd.strt(length=10).put(0)
        return C
    
    for i in range(10):
        sh_to_dp().put(0, 10*i)
    
    nd.export_gds()

    2) Assign the cell in the first call to a variable name and avoid the extra function calls all together:

    C = sh_to_dp()
    for i in range(10):
        C.put(0, 10*i)

    Ronald

Viewing 20 posts - 121 through 140 (of 194 total)