Skip to content

Commit d7500f4

Browse files
Split SiEPIC in separate packages for Si and SiN
Signed-off-by: Lucas Heitzmann Gabrielli <lucas@flexcompute.com>
1 parent 5696392 commit d7500f4

74 files changed

Lines changed: 1575 additions & 966 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build-packages.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@ on:
88

99
jobs:
1010
build:
11-
name: Build wheels on manylinux2014
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
package_dir: [si, sin]
15+
name: Build wheels on manylinux2014 (${{ matrix.package_dir }})
1216
runs-on: ubuntu-latest
1317
steps:
1418
- uses: actions/checkout@v4
1519
- uses: actions/setup-python@v5
1620
- name: Install pypa/build
1721
run: python3 -m pip install build --user
1822
- name: Build a binary wheel and a source tarball
23+
working-directory: ${{ matrix.package_dir }}
1924
run: python3 -m build
2025
- uses: actions/upload-artifact@v4
2126
with:
22-
path: ./dist/*
23-
name: artifact
27+
path: ./${{ matrix.package_dir }}/dist/*
28+
name: artifact-${{ matrix.package_dir }}
2429

2530
upload_pypi:
2631
name: Upload wheel to PyPI
@@ -31,6 +36,7 @@ jobs:
3136
steps:
3237
- uses: actions/download-artifact@v4
3338
with:
39+
pattern: artifact-*
3440
path: dist
3541
merge-multiple: true
3642
- uses: pypa/gh-action-pypi-publish@v1.12.4

.github/workflows/run-tests.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,28 @@ jobs:
99
matrix:
1010
os: [ubuntu-latest, macos-latest]
1111
python-version: ['3.10', '3.14']
12-
name: Test for ${{ matrix.python-version }} on ${{ matrix.os }}
12+
package_dir: [si, sin]
13+
name: Test ${{ matrix.package_dir }} for ${{ matrix.python-version }} on ${{ matrix.os }}
1314
runs-on: ${{ matrix.os }}
1415
steps:
1516
- uses: actions/checkout@v4
1617
- uses: actions/setup-python@v5
1718
with:
1819
python-version: ${{ matrix.python-version }}
1920
cache: 'pip'
21+
cache-dependency-path: ${{ matrix.package_dir }}/pyproject.toml
2022
- name: Install Python dependencies
23+
working-directory: ${{ matrix.package_dir }}
2124
run: |
2225
python -m pip install --upgrade pip
2326
pip install --upgrade setuptools wheel pip-tools
2427
python -m piptools compile --resolver=backtracking --extra=test -o requirements.txt pyproject.toml
2528
pip install -r requirements.txt
2629
- name: Build and install
30+
working-directory: ${{ matrix.package_dir }}
2731
run: pip install .
2832
- name: Test
33+
working-directory: ${{ matrix.package_dir }}
2934
run: |
3035
export SIMCLOUD_APIKEY=${{ secrets.SIMCLOUD_APIKEY }}
3136
pytest

README.md

Lines changed: 1 addition & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,6 @@
11
# SiEPIC Forge
22

3-
This python module implements the [SiEPIC EBeam
3+
Main repository for the [SiEPIC EBeam
44
PDK](https://github.com/SiEPIC/SiEPIC_EBeam_PDK) for Si and SiN processes as
55
components and technology specifications for
66
[PhotonForge](https://docs.flexcompute.com/projects/photonforge/)
7-
8-
9-
## Installation
10-
11-
### Python interface
12-
13-
Installation via `pip`:
14-
15-
pip install siepic-forge
16-
17-
18-
## Usage
19-
20-
The simplest way to use the this PDK in PhotonForge is to set its technology as
21-
default:
22-
23-
import photonforge as pf
24-
import siepic_forge as siepic
25-
26-
tech = siepic.ebeam_si()
27-
pf.config.default_technology = tech
28-
29-
30-
The `ebeam_si` function creates a parametric technology and accepts a number of
31-
parameters to fine-tune the technology. The EBeam SiN process is available
32-
through the `ebeam_sin` parametric technology.
33-
34-
PDK components are available through the `component` function, which takes a
35-
component name as first argument. The list of component names is available as a
36-
set `component_names`:
37-
38-
print(siepic.component_names)
39-
40-
pdk_component = siepic.component("ebeam_y_1550")
41-
42-
43-
More information can be obtained in the documentation for each function:
44-
45-
help(siepic.ebeam_si)
46-
47-
help(siepic.ebeam_sin)
48-
49-
help(siepic.component)
50-
51-
52-
## Warnings
53-
54-
Please note that the 3D structures obtained by extrusion through this module's
55-
technologies are a best approximation of the intended fabricated structures,
56-
but the actual final dimensions may differ due to several fabrication-specific
57-
effects. In particular, doping profiles are represented with hard-boundary,
58-
homogeneous solids, but, in practice will present process-dependent variations
59-
with smooth boundaries.
60-
61-
62-
## References
63-
64-
Process stack and other information obtained from [ANT
65-
NanoSOI](https://www.appliednt.com/nanosoi/).
66-
67-
The GDSII cell library comes from the main PDK repository.
68-
69-
70-
## Third-Party Licenses
71-
72-
- [`SiEPIC_EBeam_PDK`](https://github.com/SiEPIC/SiEPIC_EBeam_PDK)
73-
74-
> This project is licensed under the terms of the MIT license.
75-
>
76-
> Copyright (c) 2016-2020, Lukas Chrostowski and contributors
77-
>
78-
> Permission is hereby granted, free of charge, to any person obtaining a
79-
> copy of this software and associated documentation files (the "Software"),
80-
> to deal in the Software without restriction, including without limitation
81-
> the rights to use, copy, modify, merge, publish, distribute, sublicense,
82-
> and/or sell copies of the Software, and to permit persons to whom the
83-
> Software is furnished to do so, subject to the following conditions:
84-
>
85-
> The above copyright notice and this permission notice shall be included in
86-
> all copies or substantial portions of the Software.
87-
>
88-
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
89-
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
90-
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
91-
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
92-
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
93-
> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
94-
> DEALINGS IN THE SOFTWARE.

component_converter.py

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,78 @@
1-
import photonforge as pf
2-
import siepic_forge as siepic
31
import pathlib
2+
import subprocess
3+
import sys
4+
45
import numpy
6+
import photonforge as pf
7+
8+
sys.path.append("./si")
9+
sys.path.append("./sin")
10+
11+
import siepic_si_forge as siepic_si
12+
import siepic_sin_forge as siepic_sin
13+
14+
preambles = {
15+
"si": """import math
16+
17+
_symmetries_3port = [("P1", "P2", {"P0": "P0", "P2": "P1"})]
18+
19+
_symmetries_crossing = [
20+
("P0", "P1", {"P1": "P0", "P2": "P3", "P3": "P2"}),
21+
("P0", "P2", {"P1": "P3", "P2": "P1", "P3": "P0"}),
22+
("P0", "P3", {"P1": "P2", "P2": "P0", "P3": "P1"}),
23+
]
24+
25+
_waist = 5.0
26+
27+
_angle = 8 * math.pi / 180
28+
_vx8 = math.sin(_angle)
29+
_vy8 = -math.cos(_angle)
30+
31+
_angle = 7 * math.pi / 180
32+
_tm1550_vx = math.sin(_angle)
33+
_tm1550_vy = -math.cos(_angle)
534
35+
_angle = -21 * math.pi / 180
36+
_te1550_vx = math.sin(_angle)
37+
_te1550_vy = -math.cos(_angle)
638
7-
for path in pathlib.Path("siepic_forge/library").iterdir():
8-
family = path.stem
9-
technology = siepic.ebeam_sin() if "SiN" in family else siepic.ebeam_si()
39+
_component_data = {
40+
""",
41+
"sin": """import math
42+
43+
_symmetries_3port = [("P1", "P2", {"P0": "P0", "P2": "P1"})]
44+
45+
_symmetries_crossing = [
46+
("P0", "P1", {"P1": "P0", "P2": "P3", "P3": "P2"}),
47+
("P2", "P3", {"P0": "P1", "P1": "P0", "P3": "P2"}),
48+
]
49+
50+
_symmetries_directional_coupler = [
51+
("P0", "P1", {"P1": "P0", "P2": "P3", "P3": "P2"}),
52+
("P0", "P2", {"P1": "P3", "P2": "P0", "P3": "P1"}),
53+
("P0", "P3", {"P1": "P2", "P2": "P1", "P3": "P0"}),
54+
]
55+
56+
_symmetries_mmi22 = _symmetries_directional_coupler
57+
58+
_waist = 5.0
59+
60+
_angle = 8 * math.pi / 180
61+
_vx8 = math.sin(_angle)
62+
_vy8 = -math.cos(_angle)
63+
64+
_angle = 10 * math.pi / 180
65+
_te895_vx = math.sin(_angle)
66+
_te895_vy = -math.cos(_angle)
67+
68+
_component_data = {
69+
""",
70+
}
71+
72+
for family, preamble in preambles.items():
73+
lines = []
74+
technology = siepic_sin.ebeam() if family == "sin" else siepic_si.ebeam()
75+
path = pathlib.Path(f"{family}/siepic_{family}_forge/library")
1076
for gds_name in sorted(path.glob("*.gds")):
1177
components = pf.load_layout(gds_name, technology=technology)
1278
for comp_name in sorted(c.name for c in pf.find_top_level(*components.values())):
@@ -28,7 +94,9 @@
2894
for spec in technology.ports:
2995
for port in comp.detect_ports([spec], (pin - 0.005, pin + 0.005)):
3096
if numpy.allclose(port.center, pin):
31-
candidates.append((tuple(float(x) for x in pin), int(port.input_direction), spec))
97+
candidates.append(
98+
(tuple(float(x) for x in pin), int(port.input_direction), spec)
99+
)
32100
if len(candidates) == 0:
33101
print(f"# WARN: Missing port {tuple(float(x) for x in pin)}.")
34102
ports.extend(candidates)
@@ -38,11 +106,8 @@
38106

39107
model = "None" if len(ports) < 2 or comp.name.endswith("BB") else "{}"
40108

41-
print(
42-
f"""{comp.name!r}: (
43-
{family!r},
44-
{gds_name.stem!r},
45-
[{ports}],
46-
{model},
47-
),"""
48-
)
109+
lines.append(f"{comp.name!r}: ({gds_name.stem!r}, [{ports}], {model}),")
110+
111+
output = pathlib.Path(__file__).parent / family / f"siepic_{family}_forge" / "_component_data.py"
112+
output.write_text(preamble + "\n".join(lines) + "\n}")
113+
subprocess.run(["ruff", "format", output], check=True)

extrusion_profile.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*-
3+
import sys
34

4-
import siepic_forge as siepic
5+
sys.path.append("./si")
6+
sys.path.append("./sin")
7+
8+
import siepic_si_forge as siepic_si
9+
import siepic_sin_forge as siepic_sin
510
from matplotlib import pyplot
611

7-
siepic.plot_cross_section()
12+
siepic_si.plot_cross_section()
813

9-
siepic.plot_cross_section(siepic.ebeam_sin())
14+
siepic_sin.plot_cross_section()
1015

1116
pyplot.show()

layer_converter.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def parse(layers, node, description=""):
113113
if __name__ == "__main__":
114114
if len(sys.argv) < 2:
115115
raise RuntimeError(
116-
"Please run the script providing the path for the layer properties file: EBeam.lyp"
116+
"Please run the script providing the path for the layer properties file: NanoSOI_layers.lyp"
117117
)
118118

119119
layers = {}
@@ -152,14 +152,17 @@ def parse(layers, node, description=""):
152152
layers[k][0] = f"{n} {names[n]}"
153153
names[n] += 1
154154

155-
lines = [
156-
"import photonforge as pf",
157-
"_layers = {",
158-
] + [
159-
"\t{!r} : pf.LayerSpec({}, {!r}, {!r}, {!r}),".format(*v) for _, v in sorted(layers.items())
160-
]
161-
lines.append("}")
162-
163-
output = pathlib.Path(__file__).parent / "siepic_forge" / "_layers.py"
164-
output.write_text("\n".join(lines))
165-
subprocess.run(["ruff", "format", output], check=True)
155+
for family, skip_layers in (("si", [(4, 0)]), ("sin", [(1, 0), (2, 0)])):
156+
lines = [
157+
"import photonforge as pf",
158+
"_layers = {",
159+
] + [
160+
"\t{!r} : pf.LayerSpec({}, {!r}, {!r}, {!r}),".format(*v)
161+
for k, v in sorted(layers.items())
162+
if k not in skip_layers
163+
]
164+
lines.append("}")
165+
166+
output = pathlib.Path(__file__).parent / family / f"siepic_{family}_forge" / "_layers.py"
167+
output.write_text("\n".join(lines))
168+
subprocess.run(["ruff", "format", output], check=True)

pyproject.toml

Lines changed: 0 additions & 27 deletions
This file was deleted.
File renamed without changes.

0 commit comments

Comments
 (0)