Skip to content

Commit

Permalink
PyPI KLayout compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasc-ubc committed Nov 17, 2023
1 parent 79bb182 commit 8b1a406
Show file tree
Hide file tree
Showing 18 changed files with 314 additions and 45 deletions.
Binary file added Examples/Python/a.oas
Binary file not shown.
Binary file added Examples/Python/a_static.oas
Binary file not shown.
82 changes: 82 additions & 0 deletions Examples/Python/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@

path_GitHub = '/Users/lukasc/Documents/GitHub/'

import klayout
import pya
from pya import *
import os, sys

path_siepic = os.path.join(path_GitHub, 'SiEPIC-Tools/klayout_dot_config/python')
if not path_siepic in sys.path:
sys.path.append(path_siepic)
import SiEPIC
import SiEPIC.extend

from SiEPIC._globals import Python_Env
print('KLayout running in mode: %s' % Python_Env)

path_ebeam = os.path.join(path_GitHub, 'SiEPIC_EBeam_PDK/klayout')
if not path_ebeam in sys.path:
sys.path.append(path_ebeam)
tech = pya.Technology().create_technology('EBeam')
tech = tech.load(os.path.join(path_GitHub, 'SiEPIC_EBeam_PDK/klayout/EBeam/EBeam.lyt'))
import EBeam # technology needs to be defined first.


from SiEPIC.utils.layout import new_layout, floorplan
from SiEPIC.scripts import zoom_out, export_layout

topcell, ly = new_layout(tech.name, "top", overwrite = True)

#topcell = ly.create_cell('top')

'''pcell = ly.create_cell('ebeam_dc_halfring_straight','EBeam', {})
t = Trans(Trans.R0, 0, 0)
topcell.insert(CellInstArray(pcell.cell_index(), t))
pcell = ly.create_cell('contra_directional_coupler','EBeam', {})
t = Trans(Trans.R0, 0, 0)
topcell.insert(CellInstArray(pcell.cell_index(), t))
'''

# all the libraries
x,y,xmax=0,0,0
for lib in pya.Library().library_ids():
li = pya.Library().library_by_id(lib)
if li.name() == 'Basic':
continue
print(li.layout().pcell_names())

# all the pcells
for n in li.layout().pcell_names():
print(li.name(), n)
pcell = ly.create_cell(n,li.name(), {})
if pcell:
t = Trans(Trans.R0, x-pcell.bbox().left, y-pcell.bbox().bottom)
topcell.insert(CellInstArray(pcell.cell_index(), t))
y += pcell.bbox().height()+2000
xmax = max(xmax, pcell.bbox().width()+2000)
else:
print('Error in: %s' % n)
x, y = xmax, 0
# all the fixed cells
for c in li.layout().each_top_cell():
# instantiate
if not li.layout().cell(c).is_pcell_variant():
print(li.name(), li.layout().cell(c).name)
pcell = ly.create_cell(li.layout().cell(c).name,li.name(), {})
if not pcell:
pcell = ly.create_cell(li.layout().cell(c).name,li.name())
if pcell:
t = Trans(Trans.R0, x-pcell.bbox().left, y-pcell.bbox().bottom)
topcell.insert(CellInstArray(pcell.cell_index(), t))
y += pcell.bbox().height()+2000
xmax = max(xmax, pcell.bbox().width()+2000)
else:
print('Error in: %s' % li.layout().cell(c).name)
x, y = xmax, 0

path_out = os.path.dirname(os.path.realpath(__file__))
ly.write(os.path.join(path_out,'a.oas'))
export_layout(topcell, path_out,'a_static',format='oas')
print('done')

7 changes: 7 additions & 0 deletions klayout/EBeam/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
print('SiEPIC-EBeam-PDK Python module: EBeam')

# from . import test

from . import pymacros


Binary file modified klayout/EBeam/gds/EBeam_SiN/ebeam_Polarizer_TM_1550_UQAM.gds
Binary file not shown.
192 changes: 192 additions & 0 deletions klayout/EBeam/pymacros/SiEPIC_EBeam_Library.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# Python script

"""
This file is part of the SiEPIC_EBeam_PDK
by Lukas Chrostowski (c) 2015-2023
This Python file implements a library called "SiEPIC_EBeam", consisting of mature components that
have Layouts and Compact Models for circuit simulations:
- Fixed GDS cell components: imported from SiEPIC-EBeam.gds
- PCells:
- ebeam_dc_halfring_straight
- ebeam_bragg_te1550: waveguide Bragg grating
- ebeam_taper_te1550: Waveguide Taper
- Waveguide_bump
-
- Waveguide_Bend
NOTE: after changing the code, the macro needs to be rerun to install the new
implementation. The macro is also set to "auto run" to install the PCell
when KLayout is run.
Crash warning:
https://www.klayout.de/forum/discussion/734
This library has nested PCells. Running this macro with a layout open may
cause it to crash. Close the layout first before running.
Version history:
Lukas Chrostowski 2015/11/05 - 2015/11/10
- Double-bus ring resonator
- waveguide bends
- PCell parameter functions
- polygon text
- PCell calling another PCell - TestStruct_DoubleBus_Ring
Lukas Chrostowski 2015/11/14
- fix for rounding error in "DoubleBus_Ring"
Lukas Chrostowski 2015/11/15
- fix for Python 3.4: print("xxx")
Lukas Chrostowski 2015/11/17
- update "layout_waveguide_rel" to use the calculated points_per_circle(radius)
Lukas Chrostowski 2015/11/xx
- Waveguide based on bends, straight waveguide.
Lukas Chrostowski 2015/12/3
- Bragg grating
Lukas Chrostowski 2016/01/17
- Taper, matching EBeam CML component
Lukas Chrostowski 2016/01/20
- (sinusoidal) Bragg grating
Lukas Chrostowski 2016/05/27
- SWG_waveguide
- SWG_to_strip_waveguide
S. Preble 2016/08/26
- Double Bus Ring Pin's shifted - text now is in the middle of the pin path
Lukas Chrostowski 2016/11/06
- waveguide bump, to provide a tiny path length increase
Lukas Chrostowski 2017/02/14
- renaming "SiEPIC" PCells library to "SiEPIC-EBeam PCells", update for Waveguide_Route
- code simplifications: Box -> Box
Lukas Chrostowski 2017/03/08
- S-Bend -
Lukas Chrostowski 2017/03/18
- ebeam_dc_halfring_straight, with TE/TM support. Zeqin Lu adding CML for this component.
Lukas Chrostowski 2017/12/16
- compatibility with KLayout 0.25 and SiEPIC-Tools
Lukas Chrostowski 2020/02/22
- contra directional coupler; moved from Dev library; now has a compact model generator
todo:
replace:
layout_arc_wg_dbu(self.cell, Layerm1N, x0,y0, r_m1_in, w_m1_in, angle_min_doping, angle_max_doping)
with:
self.cell.shapes(Layerm1N).insert(Polygon(arc(w_m1_in, angle_min_doping, angle_max_doping) +
[Point(0, 0)]).transformed(t))
Lukas Chrostowski 2020/06/21
- Waveguide update, cellName
Mustafa Hammood 2020/06/26
- major refactoring and splitting of individual classes into sub files
Lukas 2021/04/01
- fixing loading library (previous collisions with other PDKs)
"""


print('SiEPIC_EBeam_Library')

import pya
from pya import *
from SiEPIC.utils import get_technology_by_name
import os
import pathlib
import sys


from SiEPIC._globals import KLAYOUT_VERSION, KLAYOUT_VERSION_3
if KLAYOUT_VERSION < 28:
question = pya.QMessageBox()
question.setStandardButtons(pya.QMessageBox.Ok)
question.setText("SiEPIC-EBeam is no longer compatible with older versions (<0.28) of KLayout.")
KLayout_link0='https://www.klayout.de/build.html'
question.setInformativeText("\nSiEPIC-EBeam is no longer compatible with older versions (<0.28) of KLayout.\nPlease download an install the highest version of 0.28.x, from %s" % (KLayout_link0))
pya.QMessageBox_StandardButton(question.exec_())


dir_path = os.path.dirname(os.path.realpath(__file__))
if dir_path not in sys.path:
sys.path.append(dir_path)

files = [f for f in os.listdir(os.path.join(os.path.dirname(
os.path.realpath(__file__)),'pcells_EBeam')) if '.py' in pathlib.Path(f).suffixes and '__init__' not in f]
import pcells_EBeam ### folder name ###
import importlib
importlib.invalidate_caches()
pcells_=[]
for f in files:
module = 'pcells_EBeam.%s' % f.replace('.py','') ### folder name ###
print(' - found module: %s' % module)
m = importlib.import_module(module)
print(m)
pcells_.append(importlib.reload(m))


class SiEPIC_EBeam_Library(Library):
"""
The library where we will put the PCells and GDS into
"""

def __init__(self):

tech_name = 'EBeam'
library = tech_name
self.technology=tech_name

print("Initializing '%s' Library." % library)

# Set the description
self.description = "v0.3.58, Components with models"

# Save the path, used for loading WAVEGUIDES.XML
import os
self.path = os.path.dirname(os.path.realpath(__file__))

# Import all the GDS files from the tech folder
import os, fnmatch
dir_path = os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../gds/EBeam"))
print(' library path: %s' % dir_path)
search_str = '*.[Oo][Aa][Ss]' # OAS
for root, dirnames, filenames in os.walk(dir_path, followlinks=True):
for filename in fnmatch.filter(filenames, search_str):
file1=os.path.join(root, filename)
print(" - reading %s" % file1 )
self.layout().read(file1)
search_str = '*.[Gg][Dd][Ss]' # GDS
for root, dirnames, filenames in os.walk(dir_path, followlinks=True):
for filename in fnmatch.filter(filenames, search_str):
file1=os.path.join(root, filename)
print(" - reading %s" % file1 )
self.layout().read(file1)

# Create the PCell declarations
for m in pcells_:
mm = m.__name__.replace('pcells_EBeam.','')
mm2 = m.__name__+'.'+mm+'()'
print(' - register_pcell %s, %s' % (mm,mm2))
self.layout().register_pcell(mm, eval(mm2))

print(' done with pcells')

# Register us the library with the technology name
# If a library with that name already existed, it will be replaced then.
self.register(library)

# Instantiate and register the library
SiEPIC_EBeam_Library()
6 changes: 6 additions & 0 deletions klayout/EBeam/pymacros/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
print('SiEPIC-EBeam-PDK Python module: pymacros')

from . import SiEPIC_EBeam_Library



4 changes: 2 additions & 2 deletions klayout/EBeam/pymacros/pcells_EBeam/Waveguide_Bend.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from . import *
from pya import *

class Waveguide_Bend(pya.PCellDeclarationHelper):
class Waveguide_Bend(PCellDeclarationHelper):
"""
The PCell declaration for the waveguide bend.
"""
Expand All @@ -10,6 +9,7 @@ def __init__(self):

# Important: initialize the super class
super(Waveguide_Bend, self).__init__()
from SiEPIC.utils import get_technology_by_name
TECHNOLOGY = get_technology_by_name('EBeam')

# declare the parameters
Expand Down
6 changes: 3 additions & 3 deletions klayout/EBeam/pymacros/pcells_EBeam/Waveguide_SBend.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from . import *
from pya import *

class Waveguide_SBend(pya.PCellDeclarationHelper):
class Waveguide_SBend(PCellDeclarationHelper):
"""
Input:
"""
Expand All @@ -10,6 +9,7 @@ def __init__(self):

# Important: initialize the super class
super(Waveguide_SBend, self).__init__()
from SiEPIC.utils import get_technology_by_name
TECHNOLOGY = get_technology_by_name('EBeam')

# declare the parameters
Expand Down Expand Up @@ -54,7 +54,7 @@ def produce_impl(self):
h = to_itype(self.height,dbu)

# waveguide_length = layout_waveguide_sbend(self.cell, LayerSiN, pya.Trans(Trans.R0, 0,0), w, r, h, length)
waveguide_length = to_itype(layout_waveguide_sbend_bezier(self.cell, LayerSiN, pya.Trans(), self.wg_width, self.wg_width, self.height,self.length), dbu)
waveguide_length = to_itype(layout_waveguide_sbend_bezier(self.cell, LayerSiN, Trans(), self.wg_width, self.wg_width, self.height,self.length), dbu)

from SiEPIC._globals import PIN_LENGTH as pin_length

Expand Down
8 changes: 4 additions & 4 deletions klayout/EBeam/pymacros/pcells_EBeam/Waveguide_Straight.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from . import *
from pya import *

class Waveguide_Straight(pya.PCellDeclarationHelper):
class Waveguide_Straight(PCellDeclarationHelper):
"""
Input: length, width
draws a straight waveguide with pins. centred at the instantiation point.
Expand All @@ -12,6 +11,7 @@ def __init__(self):

# Important: initialize the super class
super(Waveguide_Straight, self).__init__()
from SiEPIC.utils import get_technology_by_name
TECHNOLOGY = get_technology_by_name('EBeam')

# declare the parameters
Expand Down Expand Up @@ -66,15 +66,15 @@ def produce_impl(self):
pin_length = 2

t = Trans(Trans.R0,-length/2,0)
pin = pya.Path([Point(pin_length/2, 0), Point(-pin_length/2, 0)], w)
pin = Path([Point(pin_length/2, 0), Point(-pin_length/2, 0)], w)
pin_t = pin.transformed(t)
shapes(LayerPinRecN).insert(pin_t)
text = Text ("pin1", t)
shape = shapes(LayerPinRecN).insert(text)
shape.text_size = 0.4/dbu

t = Trans(Trans.R0,length/2,0)
pin = pya.Path([Point(-pin_length/2, 0), Point(pin_length/2, 0)], w)
pin = Path([Point(-pin_length/2, 0), Point(pin_length/2, 0)], w)
pin_t = pin.transformed(t)
shapes(LayerPinRecN).insert(pin_t)
text = Text ("pin2", t)
Expand Down
5 changes: 3 additions & 2 deletions klayout/EBeam/pymacros/pcells_EBeam/Wireguide.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from . import *
from pya import *

class Wireguide(pya.PCellDeclarationHelper):
class Wireguide(PCellDeclarationHelper):
'''
RIT Integrated Photonics Group of Stefan Preble (Karl McNulty)
new wireguide class (essentially the metal path equivalent to a waveguide but no bend is allowed)
Expand All @@ -10,6 +9,7 @@ def __init__(self):
# Important: initialize the super class
super(Wireguide, self).__init__()
# declare the parameters
from SiEPIC.utils import get_technology_by_name
TECHNOLOGY = get_technology_by_name('EBeam')
self.param("path", self.TypeShape, "Path", default = DPath([DPoint(0,0), DPoint(10,0), DPoint(10,10)], 0.5))
self.radius = 0
Expand Down Expand Up @@ -44,6 +44,7 @@ def produce_impl(self):

# print("EBeam.Wireguide")

from SiEPIC.utils import get_technology_by_name
TECHNOLOGY = get_technology_by_name('EBeam')

dbu = self.layout.dbu
Expand Down
Loading

0 comments on commit 8b1a406

Please sign in to comment.