Packaging - the .lumpdk format
A .lumpdk is a zip archive containing a generated manifest.json, the Python source inside one PDK package, declared model resources, package-local GDS assets, and an optional drc.json. Load the archive into a Lumicron project using File > Load PDK or Change PDK.
You do not need a .lumpdk to publish a PDK to PyPI. Use a wheel for ordinary Python installation and a .lumpdk for one-click installation in the Mac app; both can be produced from the same source package.
Anatomy
lumicron_pdk.packaging writes the contents of the imported package at the archive root:
tinyphot.lumpdk
├── manifest.json # generated by pack_pdk
├── __init__.py # package root after app extraction
├── all.py
├── meta.py # META: display/import identity + version
├── layers.py
├── profiles.py
├── components.py
├── transitions.py
├── pcells/ # optional Python subpackages are retained
│ └── ring.py
├── models/ # declared compact-model / optical data files
│ └── mmi.csv
├── layouts/ # package-local .gds / .gdsii resources
│ └── bend.gds
└── drc.json # optional; generated from DRC or copied from JSON
Do not wrap these files in source/tinyphot/ inside the archive. The app already creates the destination directory named by package-name in its private cache. Use package-relative imports and resource paths so the package remains portable after extraction.
The packer includes Python source, declared compact-model data, source CSVs used by declared TabulatedIndex models, all package-local .gds / .gdsii assets, and optional root drc.json. Arbitrary documentation and unrelated data files are not copied automatically. Referenced model resources must stay inside the package. Optical CSV and GDS resources are checked against their recorded content hashes; rebuild after changing them.
The archive filename must be exactly <package-name>.lumpdk; store release versions in META["version"] and, if needed, versioned release directories. A filename such as tinyphot-0.1.0.lumpdk is rejected when package-name is tinyphot.
Declare both PDK names
Put a META dictionary in meta.py:
META = {
"name": "TinyPhot Research PDK",
"package-name": "tinyphot",
"version": "0.1.0",
"vendor": "Example Lab",
"description": "Compact silicon photonics PDK for tutorials.",
"units": "um",
}name- Human-facing identity shown in project PDK panels. Spaces and capitalization are fine.
package-name-
Python identifier used for the extracted folder and
import lumicron.pdks.tinyphot.all as pdk. It must satisfy Python’s identifier rules.package_nameis rejected; use the canonicalpackage-namekey. version- PDK release version displayed by Lumicron and used by your release process.
Declare both identities explicitly. If package-name is absent, the packer uses the source package directory name. An invalid identifier, a Python keyword, or the legacy package_name key causes packing to fail; no display-name sanitization is performed by the packer.
Build the archive
The package must be importable in the Python environment that runs the packer:
python -m lumicron_pdk.packaging tinyphot --output-directory distOr from Python:
from lumicron_pdk.packaging import pack_pdk
pack_pdk("tinyphot", output_directory="dist")For a src/-layout repository, install the package editable or add src/ to sys.path in a small build script before calling pack_pdk. Pass the package itself, not its .all re-export module.
The packer imports these public namespaces when available:
METAfrom<package>.meta;LAYERandSTACKfrom the package root;RPfrom the package root;- decorated factories from
<package>.components, or the root when that module is absent; - ports and named circuit-model declarations from constructed component cells;
- declared data resources and package-local GDS files;
- optional
DRCdeck exported at the package root, ordrc.jsonbeside__init__.py; - layer display declarations in
LAYER, or legacydisplay.json.
It serializes them into top-level manifest sections: meta, layers, stack, route_profiles, simulation, and components, with component_schema_version: 1. Appendix A documents that generated schema. The app reads this packaged component contract; it does not reconstruct the schematic library by guessing from Python source.
Watch out
The packer imports the PDK. Keep package import deterministic and free of network access, GUI startup, or file-writing side effects. It also evaluates component defaults and bounded boolean parameter variants to collect ports and models. Factories must construct cells without opening windows, writing exports, or launching simulations. Registration imports such as transitions are fine.
Loading in Lumicron
Load the package through File > Load PDK or Change PDK in the project inspector. Verify its displayed identity, component catalog, layer map, and explicit Python import. Test upgrades against a copy of a representative project and retain the previous archive. The archive’s metadata does not by itself prove that its Python components are executable.
Compression
Use ZIP stored entries or ordinary Deflate. Python’s zipfile.ZIP_DEFLATED is the default used by pack_pdk. The app’s bounded reader does not support BZIP2 or LZMA entries.
What can go wrong
| Symptom | Likely cause / fix |
|---|---|
| PDK appears but scripts cannot import it | Declare a valid META["package-name"], use relative internal imports, and test the extracted package. |
| Import uses the display name with spaces | Import by package-name, never by name. |
| Installed source or model data is missing | Keep required code and declared model resources inside the imported package; unrelated files are not copied automatically. |
| An old PDK version is still active | Load the intended archive into the project and verify its version; runtime extraction is cached by archive content. |
| Layers have generic colors | Export LAYER from the package root and use LayerTable entries with colors. |
| DRC tool reports no installed deck | Export a drc.Deck as DRC from the package root, retain drc.json, or pass an explicit deck. |
| A component is unavailable in the schematic library | Inspect its packaged parameters, ports, and model-resolution errors; displaying layer colors does not validate component execution. |
Before release, install the .lumpdk in Lumicron and run a clean script containing the canonical long import. A successful import plus one generated GDS is the minimum end-to-end packaging gate.