samplemaker-sparrow 5.4.5__tar.gz → 5.4.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. samplemaker_sparrow-5.4.7/.github/ISSUE_TEMPLATE/config.yml +1 -0
  2. samplemaker_sparrow-5.4.7/.github/ISSUE_TEMPLATE/fault.yml +81 -0
  3. samplemaker_sparrow-5.4.7/.github/ISSUE_TEMPLATE/feature_request.yml +42 -0
  4. samplemaker_sparrow-5.4.7/.github/ISSUE_TEMPLATE/improvement.yml +34 -0
  5. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/.gitignore +4 -1
  6. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/BUILD.md +22 -2
  7. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/PKG-INFO +13 -7
  8. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/README.md +7 -1
  9. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/pyproject.toml +16 -6
  10. samplemaker_sparrow-5.4.7/src/samplemaker/__init__.py +48 -0
  11. samplemaker_sparrow-5.4.7/src/samplemaker/baselib/__init__.py +3 -0
  12. samplemaker_sparrow-5.4.7/src/samplemaker/baselib/devices.py +295 -0
  13. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/baselib/waveguides.py +151 -112
  14. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/devices.py +614 -527
  15. samplemaker_sparrow-5.4.7/src/samplemaker/gdsreader.py +274 -0
  16. samplemaker_sparrow-5.4.7/src/samplemaker/gdswriter.py +437 -0
  17. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/layout.py +463 -340
  18. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/makers.py +258 -158
  19. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/phc.py +231 -185
  20. samplemaker_sparrow-5.4.7/src/samplemaker/routers.py +352 -0
  21. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/sequencer.py +150 -127
  22. samplemaker_sparrow-5.4.7/src/samplemaker/shapes.py +2362 -0
  23. samplemaker_sparrow-5.4.7/src/samplemaker/viewers.py +248 -0
  24. samplemaker_sparrow-5.4.7/tests/fixtures.py +19 -0
  25. samplemaker_sparrow-5.4.7/tests/test_gdsreader.py +246 -0
  26. samplemaker_sparrow-5.4.7/tests/test_gdswriter.py +253 -0
  27. samplemaker_sparrow-5.4.7/tests/test_makers.py +519 -0
  28. samplemaker_sparrow-5.4.7/tests/test_shapes.py +2005 -0
  29. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/00_Tutorial_BasicDrawing.py +13 -12
  30. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/01_Tutorial_Shapes.py +34 -34
  31. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/02_Tutorial_CellReferences.py +26 -24
  32. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/03_Tutorial_GroupManipulation.py +24 -23
  33. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/04_Tutorial_Boolean.py +23 -21
  34. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/05_Tutorial_Devices.py +53 -43
  35. samplemaker_sparrow-5.4.7/tutorials/06_Tutorial_DeviceTables.py +66 -0
  36. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/07_Tutorial_Waveguides.py +45 -34
  37. samplemaker_sparrow-5.4.7/tutorials/08_Tutorial_WaveguideDevices.py +124 -0
  38. samplemaker_sparrow-5.4.7/tutorials/09_Tutorial_Circuits.py +105 -0
  39. samplemaker_sparrow-5.4.7/tutorials/10_Tutorial_ElectricalPorts.py +126 -0
  40. samplemaker_sparrow-5.4.7/tutorials/11_Tutorial_LayoutAssembly.py +74 -0
  41. samplemaker_sparrow-5.4.7/tutorials/12_Tutorial_ImportingCircuits.py +36 -0
  42. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/TutorialCollection.py +27 -21
  43. samplemaker_sparrow-5.4.7/uv.lock +606 -0
  44. samplemaker_sparrow-5.4.5/src/samplemaker/__init__.py +0 -36
  45. samplemaker_sparrow-5.4.5/src/samplemaker/baselib/__init__.py +0 -4
  46. samplemaker_sparrow-5.4.5/src/samplemaker/baselib/devices.py +0 -160
  47. samplemaker_sparrow-5.4.5/src/samplemaker/gdsreader.py +0 -251
  48. samplemaker_sparrow-5.4.5/src/samplemaker/gdswriter.py +0 -367
  49. samplemaker_sparrow-5.4.5/src/samplemaker/routers.py +0 -339
  50. samplemaker_sparrow-5.4.5/src/samplemaker/shapes.py +0 -2263
  51. samplemaker_sparrow-5.4.5/src/samplemaker/viewers.py +0 -234
  52. samplemaker_sparrow-5.4.5/tutorials/06_Tutorial_DeviceTables.py +0 -60
  53. samplemaker_sparrow-5.4.5/tutorials/08_Tutorial_WaveguideDevices.py +0 -93
  54. samplemaker_sparrow-5.4.5/tutorials/09_Tutorial_Circuits.py +0 -96
  55. samplemaker_sparrow-5.4.5/tutorials/10_Tutorial_ElectricalPorts.py +0 -114
  56. samplemaker_sparrow-5.4.5/tutorials/11_Tutorial_LayoutAssembly.py +0 -74
  57. samplemaker_sparrow-5.4.5/tutorials/12_Tutorial_ImportingCircuits.py +0 -39
  58. samplemaker_sparrow-5.4.5/uv.lock +0 -588
  59. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/.github/workflows/build_wheels.yml +0 -0
  60. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/LICENSE.md +0 -0
  61. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/boopy/CMakeLists.txt +0 -0
  62. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/boopy/boopy.cpp +0 -0
  63. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/documentation.md +0 -0
  64. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/resources/__init__.py +0 -0
  65. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/resources/boopy.pyi +0 -0
  66. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/src/samplemaker/resources/sm_stencil_font.txt +0 -0
  67. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/.pylint.d/12_Tutorial_LayoutAssembly1.stats +0 -0
  68. {samplemaker_sparrow-5.4.5 → samplemaker_sparrow-5.4.7}/tutorials/CircuitFile.txt +0 -0
@@ -0,0 +1 @@
1
+ blank_issues_enabled: false
@@ -0,0 +1,81 @@
1
+ name: Fault
2
+ description: Report a bug or unexpected behavior
3
+ title: "Fault: "
4
+ labels: ["fault", "needs-triage"]
5
+ body:
6
+ - type: checkboxes
7
+ id: preflight
8
+ attributes:
9
+ label: Before filing
10
+ options:
11
+ - label: I have searched existing issues and this is not a duplicate
12
+ required: true
13
+
14
+ - type: textarea
15
+ id: what
16
+ attributes:
17
+ label: What is broken?
18
+ description: Which tool, system, or process is affected?
19
+ placeholder: "e.g. The data export stops partway through and shows an error"
20
+ validations:
21
+ required: true
22
+
23
+ - type: dropdown
24
+ id: regression
25
+ attributes:
26
+ label: Is this a regression?
27
+ description: Did this work correctly before?
28
+ options:
29
+ - "Unknown"
30
+ - "Yes - it worked before"
31
+ - "No - it has never worked"
32
+ validations:
33
+ required: false
34
+
35
+ - type: textarea
36
+ id: environment
37
+ attributes:
38
+ label: Where did this happen?
39
+ placeholder: |
40
+ - Computer / OS:
41
+ - Software version:
42
+ - Equipment:
43
+ validations:
44
+ required: true
45
+
46
+ - type: textarea
47
+ id: reproduce
48
+ attributes:
49
+ label: What were you doing when it happened?
50
+ description: Step by step if possible.
51
+ placeholder: |
52
+ 1.
53
+ 2.
54
+ 3.
55
+ validations:
56
+ required: true
57
+
58
+ - type: textarea
59
+ id: expected
60
+ attributes:
61
+ label: What did you expect to happen?
62
+ placeholder: "e.g. The export completed and a file appeared in the output folder"
63
+ validations:
64
+ required: true
65
+
66
+ - type: textarea
67
+ id: actual
68
+ attributes:
69
+ label: What actually happened?
70
+ placeholder: "e.g. The program showed an error message and closed"
71
+ validations:
72
+ required: true
73
+
74
+ - type: textarea
75
+ id: logs
76
+ attributes:
77
+ label: Error messages (if any)
78
+ description: Copy and paste any error text here.
79
+ render: shell
80
+ validations:
81
+ required: false
@@ -0,0 +1,42 @@
1
+ name: Feature request
2
+ description: Suggest an idea for this project
3
+ title: "Feature: "
4
+ labels: ["feature", "needs-triage"]
5
+ body:
6
+ - type: textarea
7
+ id: need
8
+ attributes:
9
+ label: What problem does this solve?
10
+ description: Focus on the need, not the solution.
11
+ placeholder: "e.g. We have to manually copy files after every run, which takes time and is easy to forget"
12
+ validations:
13
+ required: true
14
+ - type: textarea
15
+ id: proposal
16
+ attributes:
17
+ label: What would you like it to do?
18
+ placeholder: "e.g. Automatically save results to a shared folder at the end of each run"
19
+ validations:
20
+ required: true
21
+ - type: textarea
22
+ id: constraints
23
+ attributes:
24
+ label: Any requirements or limitations?
25
+ placeholder: "e.g. Must work without an internet connection; needs to support existing file formats"
26
+ validations:
27
+ required: false
28
+ - type: textarea
29
+ id: acceptance
30
+ attributes:
31
+ label: How will we know it is done?
32
+ placeholder: |
33
+ - [ ]
34
+ - [ ]
35
+ validations:
36
+ required: true
37
+ - type: textarea
38
+ id: context
39
+ attributes:
40
+ label: Anything else?
41
+ validations:
42
+ required: false
@@ -0,0 +1,34 @@
1
+ name: Improvement
2
+ description: Suggest an improvement to this project
3
+ title: "Improvement: "
4
+ labels: ["improvement", "needs-triage"]
5
+ body:
6
+ - type: textarea
7
+ id: current
8
+ attributes:
9
+ label: What is the problem with how it works today?
10
+ placeholder: "e.g. The search only matches exact words, so it is easy to miss results with slightly different names"
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: proposed
15
+ attributes:
16
+ label: What would better look like?
17
+ placeholder: "e.g. Search should still find results when words are partially typed or spelled differently"
18
+ validations:
19
+ required: true
20
+ - type: textarea
21
+ id: acceptance
22
+ attributes:
23
+ label: How will we know it is done?
24
+ placeholder: |
25
+ - [ ]
26
+ - [ ]
27
+ validations:
28
+ required: true
29
+ - type: textarea
30
+ id: context
31
+ attributes:
32
+ label: Anything else?
33
+ validations:
34
+ required: false
@@ -26,6 +26,9 @@ dist/
26
26
  # JetBrains IDE
27
27
  .idea/
28
28
 
29
+ # Visual Studio Code
30
+ .vscode/
31
+
29
32
  # Unit test reports
30
33
  TEST*.xml
31
34
 
@@ -54,7 +57,7 @@ Thumbs.db
54
57
  *.gds
55
58
  src/boopy/*.pro.user
56
59
  html/
57
- tests/
60
+
58
61
  # Python build artifacts
59
62
  build/
60
63
  *.egg-info/
@@ -45,7 +45,19 @@ pip install -e .
45
45
  ```
46
46
 
47
47
  ### macOS
48
- Work in progress...
48
+
49
+ Install the required packages using Homebrew:
50
+ ```bash
51
+ brew install cmake boost
52
+ ```
53
+
54
+ Navigate to the project directory and build:
55
+ ```bash
56
+ # Using Astral uv (recommended)
57
+ uv sync
58
+ # Using pip
59
+ pip install -e .
60
+ ```
49
61
 
50
62
  ### Windows
51
63
  To build on Windows, ensure you have Visual Studio with C++ build tools installed.
@@ -113,7 +125,15 @@ cibuildwheel .
113
125
  ```
114
126
 
115
127
  ### macOS
116
- Work in progress...
128
+ On macOS, you can build wheels directly without Docker. Run the following command in the project directory:
129
+ ```bash
130
+ # Using Astral uv (recommended)
131
+ uvx cibuildwheel .
132
+
133
+ # Using pip
134
+ pip install cibuildwheel
135
+ cibuildwheel .
136
+ ```
117
137
 
118
138
  ### Windows
119
139
  To build Windows wheels locally, the correct version of `vcpkg` must be added to the PATH environment variable.
@@ -1,25 +1,25 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: samplemaker-sparrow
3
- Version: 5.4.5
3
+ Version: 5.4.7
4
4
  Summary: Lithographic mask design package
5
- Author-Email: Leonardo Midolo <midolo@nbi.ku.dk>
5
+ Author-Email: Leonardo Midolo <midolo@nbi.ku.dk>, Jeppe Roulund <jeppe.roulund@sparrowquantum.com>
6
6
  License-Expression: BSD-3-Clause
7
7
  License-File: LICENSE.md
8
8
  Classifier: Programming Language :: C++
9
9
  Classifier: Programming Language :: Python
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3 :: Only
12
- Classifier: Programming Language :: Python :: 3.10
13
12
  Classifier: Programming Language :: Python :: 3.11
14
13
  Classifier: Programming Language :: Python :: 3.12
15
14
  Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
16
  Classifier: Operating System :: Microsoft :: Windows
17
17
  Classifier: Operating System :: MacOS
18
18
  Classifier: Operating System :: Unix
19
19
  Classifier: Operating System :: POSIX :: Linux
20
- Project-URL: Repository, https://github.com/lmidolo/samplemaker.git
21
- Requires-Python: <3.14,>=3.10
22
- Requires-Dist: matplotlib>=3.7.5
20
+ Project-URL: Repository, https://github.com/SparrowQuantum/samplemaker.git
21
+ Requires-Python: <3.15,>=3.11
22
+ Requires-Dist: matplotlib>=3.10.5
23
23
  Requires-Dist: numpy==2.*
24
24
  Description-Content-Type: text/markdown
25
25
 
@@ -37,4 +37,10 @@ the European Research Council (ERC) under the European Union’s Horizon 2020 re
37
37
 
38
38
  ### How do I get set up?
39
39
 
40
- * For local development build instructions, please refer to [BUILD.md](BUILD.md).
40
+ The package can be installed on most platforms via pip:
41
+
42
+ ```bash
43
+ pip install samplemaker-sparrow
44
+ ```
45
+
46
+ For local development build instructions, please refer to [BUILD.md](https://github.com/SparrowQuantum/samplemaker/blob/master/BUILD.md).
@@ -12,4 +12,10 @@ the European Research Council (ERC) under the European Union’s Horizon 2020 re
12
12
 
13
13
  ### How do I get set up?
14
14
 
15
- * For local development build instructions, please refer to [BUILD.md](BUILD.md).
15
+ The package can be installed on most platforms via pip:
16
+
17
+ ```bash
18
+ pip install samplemaker-sparrow
19
+ ```
20
+
21
+ For local development build instructions, please refer to [BUILD.md](https://github.com/SparrowQuantum/samplemaker/blob/master/BUILD.md).
@@ -5,16 +5,17 @@ build-backend = "scikit_build_core.build"
5
5
  [project]
6
6
  name = "samplemaker-sparrow"
7
7
  authors = [
8
- { name = "Leonardo Midolo", email = "midolo@nbi.ku.dk"}
8
+ { name = "Leonardo Midolo", email = "midolo@nbi.ku.dk"},
9
+ { name = "Jeppe Roulund", email = "jeppe.roulund@sparrowquantum.com"}
9
10
  ]
10
11
  description = "Lithographic mask design package"
11
12
  readme = "README.md"
12
- requires-python = ">=3.10,<3.14"
13
+ requires-python = ">=3.11,<3.15"
13
14
  license-files = ["LICENSE.md"]
14
15
  license = "BSD-3-Clause"
15
- version = "5.4.5"
16
+ version = "5.4.7"
16
17
  dependencies = [
17
- "matplotlib>=3.7.5",
18
+ "matplotlib>=3.10.5",
18
19
  "numpy==2.*",
19
20
  ]
20
21
  classifiers = [
@@ -22,10 +23,10 @@ classifiers = [
22
23
  "Programming Language :: Python",
23
24
  "Programming Language :: Python :: 3",
24
25
  "Programming Language :: Python :: 3 :: Only",
25
- "Programming Language :: Python :: 3.10",
26
26
  "Programming Language :: Python :: 3.11",
27
27
  "Programming Language :: Python :: 3.12",
28
28
  "Programming Language :: Python :: 3.13",
29
+ "Programming Language :: Python :: 3.14",
29
30
  "Operating System :: Microsoft :: Windows",
30
31
  "Operating System :: MacOS",
31
32
  "Operating System :: Unix",
@@ -33,7 +34,7 @@ classifiers = [
33
34
  ]
34
35
 
35
36
  [project.urls]
36
- Repository = "https://github.com/lmidolo/samplemaker.git"
37
+ Repository = "https://github.com/SparrowQuantum/samplemaker.git"
37
38
 
38
39
  [tool.scikit-build]
39
40
  minimum-version = "0.11.6"
@@ -44,6 +45,9 @@ wheel.packages = ["src/samplemaker"]
44
45
 
45
46
  [tool.cibuildwheel]
46
47
  skip = ["*-musllinux*", "*-win32*"]
48
+ test-requires = "pytest"
49
+ test-sources = ["tests"]
50
+ test-command = "pytest {project}/tests"
47
51
 
48
52
  [tool.cibuildwheel.linux]
49
53
  before-all = "yum install -y boost-devel"
@@ -56,3 +60,9 @@ environment = { BOOST_ROOT = "C:/vcpkg/installed/x64-windows" }
56
60
  before-all = [
57
61
  "vcpkg install boost-polygon:x64-windows",
58
62
  ]
63
+
64
+ [dependency-groups]
65
+ dev = [
66
+ "pytest==9.0.2",
67
+ "ruff==0.15.1",
68
+ ]
@@ -0,0 +1,48 @@
1
+ """
2
+
3
+ This is the Python version of Sample Maker, a scripting tool for designing lithographic
4
+ masks in the GDSII format. Package `samplemaker` comes with different tools and
5
+ submodules for the creation and manipulation of basic shapes, periodic shapes, sequences
6
+ (e.g. waveguides), circuits, and complex devices.
7
+
8
+ The code has been developed primarily for nanophotonics, but it can be easily extended
9
+ to different applications in micro and nano device fabrication.
10
+
11
+ Sample Maker is developed and maintained by Leonardo Midolo (Niels Bohr Institute,
12
+ University of Copenhagen). It is based on the MATLAB(R) code developed by Leonardo
13
+ Midolo between 2013 and 2019. The first version of the rewritten Python code has been
14
+ released in October 2021.
15
+
16
+ This software has been realized with the financial support from
17
+ the European Research Council (ERC) under the European Union’s Horizon 2020 research and
18
+ innovation programme (Grant agreement No. 949043, NANOMEQ).
19
+
20
+ .. include:: ./documentation.md
21
+ """
22
+
23
+ __pdoc__: dict[str, bool | str] = {
24
+ "samplemaker.Tutorials": False,
25
+ "samplemaker.tests": False,
26
+ "samplemaker.resources": False,
27
+ "samplemaker.gdsreader": False,
28
+ "samplemaker.devices.DevicePort": False,
29
+ }
30
+
31
+ # The LayoutPool contains all the current layout, this class should generally not
32
+ # be used directly, but only through the Mask class.
33
+ LayoutPool = {} # connects a SREF name to a particular geomgroup in the current memory
34
+
35
+ # Additional cache pool:
36
+
37
+ # _DevicePool Connects a device hash to a SREF to be instantiated:
38
+ _DevicePool = {}
39
+
40
+ # _DeviceLocalParamPool connects a device hash to local parameters created by the call
41
+ # to geom():
42
+ _DeviceLocalParamPool = {}
43
+
44
+ # _DeviceCountPool connects a device name to a device count
45
+ _DeviceCountPool = {}
46
+
47
+ # _BoundingBoxPool connects a SREF name to its bounding box
48
+ _BoundingBoxPool = {}
@@ -0,0 +1,3 @@
1
+ import samplemaker.baselib.devices # noqa: F401
2
+
3
+ print("Base library loaded")
@@ -0,0 +1,295 @@
1
+ """
2
+ Base device library.
3
+
4
+ This is a collection of some simple demo devices distributed with the base version of
5
+ `samplemaker`. It can be used as template for creating new libraries or to learn how to
6
+ design them.
7
+
8
+ Note that individual device methods are not documented but should be readable and
9
+ self-explanatory.
10
+ """
11
+
12
+ import math
13
+
14
+ import numpy as np
15
+
16
+ import samplemaker.makers as sm
17
+ from samplemaker.baselib.waveguides import BaseWaveguidePort, BaseWaveguideSequencer
18
+ from samplemaker.devices import Device, registerDevicesInModule
19
+
20
+
21
+ class CrossMark(Device):
22
+ def initialize(self):
23
+ self.set_name("BASELIB_CMARK")
24
+ self.set_description("Generic cross marker for mask alignment.")
25
+
26
+ def parameters(self):
27
+ self.addparameter(
28
+ param_name="length1",
29
+ default_value=20,
30
+ param_description="Length of inner cross",
31
+ param_type=float,
32
+ )
33
+ self.addparameter(
34
+ param_name="length2",
35
+ default_value=10,
36
+ param_description="Length of outer cross",
37
+ param_type=float,
38
+ )
39
+ self.addparameter(
40
+ param_name="width1",
41
+ default_value=0.5,
42
+ param_description="Width of inner cross",
43
+ param_type=float,
44
+ )
45
+ self.addparameter(
46
+ param_name="width2",
47
+ default_value=2,
48
+ param_description="width of outer cross",
49
+ param_type=float,
50
+ )
51
+ self.addparameter(
52
+ param_name="layer",
53
+ default_value=4,
54
+ param_description="Layer to use for cross",
55
+ param_type=int,
56
+ param_range=(0, 255),
57
+ )
58
+ self.addparameter(
59
+ param_name="mark_number",
60
+ default_value=0,
61
+ param_description="Places a square in the corner, use 0 to remove",
62
+ param_type=float,
63
+ param_range=(0, 4),
64
+ )
65
+ self.addparameter(
66
+ param_name="square_size",
67
+ default_value=10,
68
+ param_description="Size of the square in the corner",
69
+ param_type=float,
70
+ )
71
+
72
+ def geom(self):
73
+ p = self.get_params()
74
+ cross = sm.make_rect(0, 0, p["length1"], p["width1"], layer=1)
75
+ cross += sm.make_rect(0, 0, p["width1"], p["length1"], layer=1)
76
+ cross.boolean_union(1)
77
+ ocross = sm.make_rect(p["length1"] / 2, 0, p["length2"], p["width2"], numkey=4)
78
+ for i in range(4):
79
+ c = ocross.copy()
80
+ c.rotate(0, 0, 90 * i)
81
+ cross += c
82
+ if p["mark_number"] > 0:
83
+ rot = 90 * (p["mark_number"] - 1)
84
+ sq_dim = p["length1"] / 2 + p["length2"]
85
+ sq_size = p["square_size"]
86
+ square = sm.make_rect(sq_dim, sq_dim, sq_size, sq_size, numkey=1)
87
+ square.rotate(0, 0, rot)
88
+ cross += square
89
+
90
+ cross.set_layer(p["layer"])
91
+ return cross
92
+
93
+
94
+ class DirectionalCoupler(Device):
95
+ def initialize(self):
96
+ self.set_name("BASELIB_DCPL")
97
+ self.set_description("Simple symmetric directional coupler")
98
+
99
+ def parameters(self):
100
+ self.addparameter("length", 20, "Coupling length", float)
101
+ self.addparameter(
102
+ param_name="width",
103
+ default_value=0.3,
104
+ param_description="Width of the waveguides in the coupling section",
105
+ param_type=float,
106
+ param_range=(0.01, 1),
107
+ )
108
+ self.addparameter(
109
+ param_name="gap",
110
+ default_value=0.5,
111
+ param_description="Distance between waveguides in the coupling section",
112
+ param_type=float,
113
+ )
114
+ self.addparameter(
115
+ param_name="input_dist",
116
+ default_value=5,
117
+ param_description="Distance between waveguides at input",
118
+ param_type=float,
119
+ param_range=(0.01, np.inf),
120
+ )
121
+ self.addparameter(
122
+ param_name="input_len",
123
+ default_value=7,
124
+ param_description="Length of the input section from input to coupling",
125
+ param_type=float,
126
+ param_range=(3, np.inf),
127
+ )
128
+
129
+ def geom(self):
130
+ p = self.get_params()
131
+ # Draw the upper arm, then mirror
132
+ off = p["input_dist"] / 2
133
+ clen = (p["input_len"] - 1) / 2
134
+ ltot = p["length"] + p["input_len"] * 2
135
+ seq = [["T", 1, p["width"]], ["C", -off, clen], ["S", p["length"] / 2]]
136
+ ss = BaseWaveguideSequencer(seq)
137
+ dc = ss.run()
138
+ dc2 = dc.copy()
139
+ dc2.mirrorX(ltot / 2)
140
+ dc += dc2
141
+ dc.translate(-ltot / 2, off + p["gap"] / 2 + p["width"] / 2)
142
+ dc3 = dc.copy()
143
+ dc3.mirrorY(0)
144
+ dc += dc3
145
+
146
+ # Add ports
147
+ xp = ltot / 2
148
+ yp = off + p["gap"] / 2 + p["width"] / 2
149
+ nw_port = BaseWaveguidePort(-xp, yp, "west", ss.options["defaultWidth"], "p1")
150
+ ne_port = BaseWaveguidePort(xp, yp, "east", ss.options["defaultWidth"], "p2")
151
+ sw_port = BaseWaveguidePort(-xp, -yp, "west", ss.options["defaultWidth"], "p3")
152
+ se_port = BaseWaveguidePort(xp, -yp, "east", ss.options["defaultWidth"], "p4")
153
+ for port in (nw_port, ne_port, sw_port, se_port):
154
+ self.addlocalport(port)
155
+
156
+ return dc
157
+
158
+
159
+ class FocusingGratingCoupler(Device):
160
+ def initialize(self):
161
+ self.set_name("BASELIB_FGC")
162
+ self.set_description("Grating coupler demo.")
163
+
164
+ def parameters(self):
165
+ self.addparameter(
166
+ param_name="w0",
167
+ default_value=0.3,
168
+ param_description="Width of the waveguide at the start",
169
+ param_type=float,
170
+ )
171
+ self.addparameter(
172
+ param_name="pitch",
173
+ default_value=0.355,
174
+ param_description="Grating default pitch",
175
+ param_type=float,
176
+ )
177
+ self.addparameter(
178
+ param_name="ff",
179
+ default_value=0.5,
180
+ param_description="Fill factor",
181
+ param_type=float,
182
+ )
183
+ self.addparameter(
184
+ param_name="theta",
185
+ default_value=10,
186
+ param_description="Emission angle at central wavelength",
187
+ param_type=float,
188
+ )
189
+ self.addparameter(
190
+ param_name="lambda0",
191
+ default_value=0.94,
192
+ param_description="Central wavelength",
193
+ param_type=float,
194
+ )
195
+ self.addparameter(
196
+ param_name="nr_Apo",
197
+ default_value=11,
198
+ param_description="nr of the 1st arc with pitch and ff",
199
+ param_type=int,
200
+ )
201
+ self.addparameter(
202
+ param_name="ff_coef",
203
+ default_value=0.5,
204
+ param_description="min ff_apod = ff_coef*ff",
205
+ param_type=float,
206
+ )
207
+ self.addparameter(
208
+ param_name="order_start",
209
+ default_value=10,
210
+ param_description="Starting period",
211
+ param_type=int,
212
+ )
213
+ self.addparameter(
214
+ param_name="order",
215
+ default_value=15,
216
+ param_description="Number of periods",
217
+ param_type=int,
218
+ )
219
+ self.addparameter(
220
+ param_name="diverg_angle",
221
+ default_value=20,
222
+ param_description="GRT divergence angle/2, deg",
223
+ param_type=float,
224
+ )
225
+ self.addparameter(
226
+ param_name="pre_split",
227
+ default_value=True,
228
+ param_description="Split in quads = false",
229
+ param_type=bool,
230
+ )
231
+
232
+ def geom(self):
233
+ # Grating first
234
+ p = self.get_params()
235
+ theta = math.radians(p["theta"])
236
+ div_angle = p["diverg_angle"]
237
+ q0 = p["order_start"]
238
+ qn = q0 + p["order"] + 1
239
+ lambda0 = p["lambda0"]
240
+ pitch = p["pitch"]
241
+ n = math.sin(theta) + lambda0 / pitch # Effective refractive index
242
+ p0 = lambda0 / math.sqrt(n * n - np.power(math.sin(theta), 2))
243
+ ff = p["ff"]
244
+ nr_apo = p["nr_Apo"]
245
+ ff_coef = p["ff_coef"]
246
+
247
+ g = sm.GeomGroup()
248
+ for q in range(q0, qn):
249
+ b = q * p0
250
+ x0 = b * b * math.sin(theta) / (q * lambda0)
251
+ a = b * b * n / (q * lambda0)
252
+ if q <= q0 + nr_apo - 1:
253
+ ff_chi = ff - (1 - ff_coef) * ff / (nr_apo - 2) * (q0 + nr_apo - q)
254
+ else:
255
+ ff_chi = ff
256
+
257
+ w = ff_chi * pitch
258
+ g += sm.make_arc(
259
+ x0=x0,
260
+ y0=0,
261
+ rX=a,
262
+ rY=b,
263
+ rot=0,
264
+ w=w,
265
+ a1=-div_angle - 5,
266
+ a2=div_angle + 5,
267
+ layer=3,
268
+ to_poly=True,
269
+ vertices=40,
270
+ split=p["pre_split"],
271
+ )
272
+
273
+ # waveguide
274
+ l_taper = 1
275
+ g_taper = qn * pitch
276
+ w_taper = g_taper * math.tan(math.radians(div_angle)) * 2
277
+
278
+ seq = [
279
+ ["T", l_taper, p["w0"]],
280
+ ["CENTER", 0, 0],
281
+ ["T", g_taper, w_taper],
282
+ ["STATE", "w", 2.5],
283
+ ["S", 1],
284
+ ]
285
+
286
+ ss = BaseWaveguideSequencer(seq)
287
+ g += ss.run()
288
+
289
+ self.addlocalport(BaseWaveguidePort(-l_taper, 0, "west", p["w0"], "p1"))
290
+
291
+ return g
292
+
293
+
294
+ # Register all devices here in this module
295
+ registerDevicesInModule(__name__)