Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Raith MBMS Paths #255

Closed
wants to merge 12 commits into from
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.9.53 - 2025-06-06
### Added
- Raith MBMS Paths as an extension of the GDSII spec.
- Add more type hints in gdstk.pyi file
-
## 0.9.52 - 2024-04-18
### Fixed
- Infinite loop in `Cell::remap_tags` (#246, thanks dtzitkas!)
Expand Down
99 changes: 61 additions & 38 deletions gdstk/_gdstk.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pathlib
import datetime
import sys
from typing import Optional, Iterable
from typing import Optional, Iterable, Any
from collections.abc import Callable, Sequence

if sys.version_info >= (3, 8):
Expand All @@ -15,7 +15,7 @@ else:
from typing_extensions import Self

import numpy
from numpy.typing import ArrayLike
from numpy.typing import ArrayLike # type: ignore

class Cell:
labels: list[Label]
Expand All @@ -24,11 +24,11 @@ class Cell:
polygons: list[Polygon]
properties: list[list[str | bytes | float]]
references: list[Reference]
def __init__(self, name: str): ...
def __init__(self, name: str) -> None: ...
def add(self, *elements: Polygon | FlexPath | RobustPath | Label | Reference) -> Self: ...
def area(self, by_spec: bool = False) -> float | dict[tuple[int, int], float]: ...
def bounding_box(self) -> Optional[tuple[tuple[float, float], tuple[float, float]]]: ...
def convex_hull(self) -> numpy.ndarray: ...
def convex_hull(self) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def copy(
self,
name: str,
Expand Down Expand Up @@ -90,7 +90,7 @@ class Cell:

class Curve:
tolerance: float
def __init__(self, xy: tuple[float, float] | complex, tolerance: float = 0.01): ...
def __init__(self, xy: tuple[float, float] | complex, tolerance: float = 0.01) -> None: ...
def arc(
self,
radius: float | tuple[float, float],
Expand Down Expand Up @@ -125,7 +125,7 @@ class Curve:
curve_function: Callable[[float], tuple[float, float] | complex],
relative: bool = True,
) -> Self: ...
def points(self) -> numpy.ndarray: ...
def points(self) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def quadratic(
self, xy: Sequence[tuple[float, float] | complex], relative: bool = False
) -> Self: ...
Expand All @@ -140,6 +140,25 @@ class Curve:
def turn(self, radius: float, angle: float) -> Self: ...
def vertical(self, y: float | Sequence[float], relative: bool = False) -> Self: ...

class RaithData:
dwelltime_selection: int
pitch_parallel_to_path: float
pitch_perpendicular_to_path: float
pitch_scale: float
periods: int
grating_type: int
dots_per_cycle: int
def __init__(
self,
dwelltime_selection: int,
pitch_parallel_to_path: float,
pitch_perpendicular_to_path: float,
pitch_scale: float,
periods: int,
grating_type: int,
dots_per_cycle: int,
) -> None: ...

class FlexPath:
bend_function: tuple[
Optional[Callable[[float, float, float, float], list[tuple[float, float]]]], ...
Expand All @@ -165,6 +184,8 @@ class FlexPath:
simple_path: bool
size: int
tolerance: float
raith_data: RaithData
base_cell_name: str
def __init__(
self,
points: tuple[float, float] | complex | Sequence[tuple[float, float] | complex],
Expand Down Expand Up @@ -200,8 +221,8 @@ class FlexPath:
scale_width: bool = True,
layer: int | Sequence[int] = 0,
datatype: int | Sequence[int] = 0,
): ...
def apply_repetition(self) -> list: ...
) -> None: ...
def apply_repetition(self) -> list[Self]: ...
def arc(
self,
radius: float | tuple[float, float],
Expand Down Expand Up @@ -261,15 +282,15 @@ class FlexPath:
def mirror(
self, p1: tuple[float, float] | complex, p2: tuple[float, float] | complex = (0, 0)
) -> Self: ...
def offsets(self) -> numpy.ndarray: ...
def offsets(self) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def parametric(
self,
path_function: Callable[[float], tuple[float, float] | complex],
width: Optional[float] | Sequence[float] = None,
offset: Optional[float] | Sequence[float] = None,
relative: bool = True,
) -> Self: ...
def path_spines(self) -> list[numpy.ndarray]: ...
def path_spines(self) -> list[numpy.ndarray[Any, numpy.dtype[numpy.float64]]]: ...
def quadratic(
self,
xy: Sequence[tuple[float, float] | complex],
Expand Down Expand Up @@ -317,7 +338,7 @@ class FlexPath:
def set_property(
self, name: str, value: str | bytes | float | Sequence[str | bytes | float]
) -> Self: ...
def spine(self) -> numpy.ndarray: ...
def spine(self) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def to_polygons(self) -> list[Polygon]: ...
def translate(
self, dx: float | tuple[float, float] | complex, dy: Optional[float] = None
Expand All @@ -336,7 +357,7 @@ class FlexPath:
offset: Optional[float] | Sequence[float] = None,
relative: bool = False,
) -> Self: ...
def widths(self) -> numpy.ndarray: ...
def widths(self) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...

class GdsWriter:
def __init__(
Expand All @@ -347,8 +368,8 @@ class GdsWriter:
precision: float = 1e-9,
max_points: int = 199,
timestamp: Optional[datetime.datetime] = None,
): ...
def close(self): ...
) -> None: ...
def close(self) -> None: ...
def write(self, *cells: Cell | RawCell) -> Self: ...

class Label:
Expand All @@ -372,7 +393,7 @@ class Label:
x_reflection: bool = False,
layer: int = 0,
texttype: int = 0,
): ...
) -> None: ...
def apply_repetition(self) -> list[Self]: ...
def copy(self) -> Self: ...
def delete_gds_property(self, attr: int) -> Self: ...
Expand All @@ -390,7 +411,9 @@ class Library:
precision: float
properties: list[list[str | bytes | float]]
unit: float
def __init__(self, name: str = "library", unit: float = 1e-6, precision: float = 1e-9): ...
def __init__(
self, name: str = "library", unit: float = 1e-6, precision: float = 1e-9
) -> None: ...
def add(self, *cells: Cell | RawCell) -> Self: ...
def delete_property(self, name: str) -> Self: ...
def get_property(self, name: str) -> Optional[list[list[str | bytes | float]]]: ...
Expand All @@ -409,7 +432,7 @@ class Library:
outfile: str | pathlib.Path,
max_points: int = 199,
timestamp: Optional[datetime.datetime] = None,
): ...
) -> None: ...
def write_oas(
self,
outfile: str | pathlib.Path,
Expand All @@ -419,7 +442,7 @@ class Library:
circletolerance: float = 0,
standard_properties: bool = False,
validation: Optional[Literal["crc32", "checksum32"]] = None,
): ...
) -> None: ...

class Polygon:
datatype: int
Expand All @@ -430,7 +453,7 @@ class Polygon:
size: int
def __init__(
self, points: Sequence[tuple[float, float] | complex], layer: int = 0, datatype: int = 0
): ...
)-> None: ...
def apply_repetition(self) -> list[Self]: ...
def area(self) -> float: ...
def perimeter(self) -> float: ...
Expand Down Expand Up @@ -462,7 +485,7 @@ class Polygon:
x_reflection: bool = False,
rotation: float = 0,
translation: Optional[tuple[float, float] | complex] = None,
matrix: Optional[ArrayLike] = None,
matrix: Optional[ArrayLike] = None, # type: ignore
) -> Self: ...
def translate(
self, dx: float | tuple[float, float] | complex, dy: Optional[float] = None
Expand All @@ -471,7 +494,7 @@ class Polygon:
class RawCell:
name: str
size: int
def __init__(self, name: str): ...
def __init__(self, name: str)-> None: ...
def dependencies(self, recursive: bool) -> list[RawCell]: ...

class Reference:
Expand All @@ -493,10 +516,10 @@ class Reference:
columns: int = 1,
rows: int = 1,
spacing: Optional[Sequence[float]] = ...,
): ...
)-> None: ...
def apply_repetition(self) -> list[Self]: ...
def bounding_box(self) -> tuple[tuple[float, float], tuple[float, float]]: ...
def convex_hull(self) -> numpy.ndarray: ...
def convex_hull(self) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def copy(self) -> Self: ...
def delete_gds_property(self, attr: int) -> Self: ...
def delete_property(self, name: str) -> Self: ...
Expand Down Expand Up @@ -531,14 +554,14 @@ class Reference:

class Repetition:
columns: Optional[int]
offsets: Optional[numpy.ndarray]
offsets: Optional[numpy.ndarray[Any, numpy.dtype[numpy.float64]]]
rows: Optional[int]
size: int
spacing: Optional[tuple[float, float]]
v1: Optional[tuple[float, float]]
v2: Optional[tuple[float, float]]
x_offsets: Optional[numpy.ndarray]
y_offsets: Optional[numpy.ndarray]
x_offsets: Optional[numpy.ndarray[Any, numpy.dtype[numpy.float64]]]
y_offsets: Optional[numpy.ndarray[Any, numpy.dtype[numpy.float64]]]
def __init__(
self,
columns: Optional[int] = None,
Expand All @@ -549,8 +572,8 @@ class Repetition:
offsets: Optional[Sequence[tuple[float, float] | complex]] = None,
x_offsets: Optional[Sequence[float]] = None,
y_offsets: Optional[Sequence[float]] = None,
): ...
def get_offsets(self) -> numpy.ndarray: ...
)-> None: ...
def get_offsets(self) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...

class RobustPath:
datatypes: tuple[int, ...]
Expand Down Expand Up @@ -588,7 +611,7 @@ class RobustPath:
scale_width: bool = True,
layer: int | list[int] = 0,
datatype: int | list[int] = 0,
): ...
)->None: ...
def apply_repetition(self) -> list[Self]: ...
def arc(
self,
Expand Down Expand Up @@ -666,7 +689,7 @@ class RobustPath:
def delete_property(self, name: str) -> Self: ...
def get_gds_property(self, attr: int) -> Optional[str]: ...
def get_property(self, name: str) -> Optional[list[list[str | bytes | float]]]: ...
def gradient(self, u: float, from_below: bool = True) -> numpy.ndarray: ...
def gradient(self, u: float, from_below: bool = True) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def horizontal(
self,
x: float,
Expand Down Expand Up @@ -710,7 +733,7 @@ class RobustPath:
def mirror(
self, p1: tuple[float, float] | complex, p2: tuple[float, float] | complex = (0, 0)
) -> Self: ...
def offsets(self, u: float, from_below: bool = True) -> numpy.ndarray: ...
def offsets(self, u: float, from_below: bool = True) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def parametric(
self,
path_function: Callable[[float], tuple[float, float] | complex],
Expand All @@ -729,8 +752,8 @@ class RobustPath:
] = None,
relative: bool = True,
) -> Self: ...
def path_spines(self) -> list[numpy.ndarray]: ...
def position(self, u: float, from_below: bool = True) -> numpy.ndarray: ...
def path_spines(self) -> list[numpy.ndarray[Any, numpy.dtype[numpy.float64]]]: ...
def position(self, u: float, from_below: bool = True) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def quadratic(
self,
xy: Sequence[tuple[float, float] | complex],
Expand Down Expand Up @@ -796,7 +819,7 @@ class RobustPath:
def set_property(
self, name: str, value: str | bytes | float | Sequence[str | bytes | float]
) -> Self: ...
def spine(self) -> numpy.ndarray: ...
def spine(self) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...
def to_polygons(self) -> list[Polygon]: ...
def translate(
self, dx: float | tuple[float, float] | complex, dy: Optional[float] = None
Expand Down Expand Up @@ -825,7 +848,7 @@ class RobustPath:
] = None,
relative: bool = False,
) -> Self: ...
def widths(self, u: float, from_below: bool = True) -> numpy.ndarray: ...
def widths(self, u: float, from_below: bool = True) -> numpy.ndarray[Any, numpy.dtype[numpy.float64]]: ...

def all_inside(
points: Sequence[tuple[float, float] | complex],
Expand Down Expand Up @@ -860,7 +883,7 @@ def boolean(
datatype: int = 0,
) -> list[Polygon]: ...
def contour(
data: ArrayLike,
data: ArrayLike, # type: ignore
level: int = 0,
length_scale: float = 1,
precision: float = 0.01,
Expand All @@ -884,7 +907,7 @@ def ellipse(
layer: int = 0,
datatype: int = 0,
) -> Polygon: ...
def gds_info(infile: str | pathlib.Path) -> dict: ...
def gds_info(infile: str | pathlib.Path) -> dict[str, Any]: ...

# def gds_timestamp(filename: str | pathlib.Path, timestamp:Optional[datetime.datetime]=None) -> datetime.datetime: ...
def gds_units(infile: str | pathlib.Path) -> tuple[float, float]: ...
Expand Down Expand Up @@ -929,7 +952,7 @@ def read_gds(
filter: Optional[Iterable[tuple[int, int]]] = None,
) -> Library: ...
def read_oas(infile: str | pathlib.Path, unit: float = 0, tolerance: float = 0) -> Library: ...
def read_rawcells(infile: str | pathlib.Path) -> dict: ...
def read_rawcells(infile: str | pathlib.Path) -> dict[str, RawCell]: ...
def rectangle(
corner1: tuple[float, float] | complex,
corner2: tuple[float, float] | complex,
Expand Down
5 changes: 5 additions & 0 deletions include/gdstk/flexpath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>
#include "pathcommon.hpp"
#include "polygon.hpp"
#include "property.hpp"
#include "raithdata.hpp"
#include "repetition.hpp"
#include "utils.hpp"

Expand Down Expand Up @@ -72,6 +73,10 @@ struct FlexPath {

Repetition repetition;
Property* properties;

RaithData raith_data;
char* base_cell_name;

// Used by the python interface to store the associated PyObject* (if any).
// No functions in gdstk namespace should touch this value!
void* owner;
Expand Down
4 changes: 3 additions & 1 deletion include/gdstk/gdsii.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ enum struct GdsiiRecord : uint8_t {
ENDMASKS = 0X38,
LIBDIRSIZE = 0X39,
SRFNAME = 0X3A,
LIBSECUR = 0X3B
LIBSECUR = 0X3B,
RaithMBMPath = 0x5A,
RaithPXXData = 0x62,
};

enum struct GdsiiDataType : uint8_t {
Expand Down
1 change: 1 addition & 0 deletions include/gdstk/gdstk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ LICENSE file or <http://www.boost.org/LICENSE_1_0.txt>
#include "oasis.hpp"
#include "pathcommon.hpp"
#include "polygon.hpp"
#include "raithdata.hpp"
#include "rawcell.hpp"
#include "reference.hpp"
#include "repetition.hpp"
Expand Down
Loading
Loading