prefab 1.1.4__py3-none-any.whl → 1.1.5__py3-none-any.whl

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.
prefab/__init__.py CHANGED
@@ -5,7 +5,7 @@ Usage:
5
5
  import prefab as pf
6
6
  """
7
7
 
8
- __version__ = "1.1.4"
8
+ __version__ = "1.1.5"
9
9
 
10
10
  from . import compare, geometry, predict, read, shapes
11
11
  from .device import BufferSpec, Device
prefab/compare.py CHANGED
@@ -24,7 +24,7 @@ def mean_squared_error(device_a: Device, device_b: Device) -> float:
24
24
  float
25
25
  The mean squared error between two devices.
26
26
  """
27
- return np.mean((device_a.device_array - device_b.device_array) ** 2)
27
+ return float(np.mean((device_a.device_array - device_b.device_array) ** 2))
28
28
 
29
29
 
30
30
  def intersection_over_union(device_a: Device, device_b: Device) -> float:
@@ -77,7 +77,7 @@ def hamming_distance(device_a: Device, device_b: Device) -> int:
77
77
  "One or both devices are not binarized.", UserWarning, stacklevel=2
78
78
  )
79
79
 
80
- return np.sum(device_a.device_array != device_b.device_array)
80
+ return int(np.sum(device_a.device_array != device_b.device_array))
81
81
 
82
82
 
83
83
  def dice_coefficient(device_a: Device, device_b: Device) -> float:
prefab/device.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Provides the Device class for representing photonic devices."""
2
2
 
3
- from typing import Optional
3
+ from typing import TYPE_CHECKING, Optional
4
4
 
5
5
  import cv2
6
6
  import gdstk
@@ -9,7 +9,7 @@ import numpy as np
9
9
  from matplotlib.axes import Axes
10
10
  from matplotlib.patches import Rectangle
11
11
  from PIL import Image
12
- from pydantic import BaseModel, Field, conint, root_validator, validator
12
+ from pydantic import BaseModel, Field, root_validator, validator
13
13
  from scipy.ndimage import distance_transform_edt
14
14
  from skimage import measure
15
15
 
@@ -17,6 +17,10 @@ from . import compare, geometry
17
17
  from .models import Model
18
18
  from .predict import predict_array
19
19
 
20
+ if TYPE_CHECKING:
21
+ import gdsfactory as gf
22
+ import tidy3d as td
23
+
20
24
  Image.MAX_IMAGE_PIXELS = None
21
25
 
22
26
 
@@ -36,7 +40,7 @@ class BufferSpec(BaseModel):
36
40
  ('top', 'bottom', 'left', 'right'), where 'constant' is used for isolated
37
41
  structures and 'edge' is utilized for preserving the edge, such as for waveguide
38
42
  connections.
39
- thickness : dict[str, conint(gt=0)]
43
+ thickness : dict[str, int]
40
44
  A dictionary that defines the thickness of the buffer zone for each side of the
41
45
  device ('top', 'bottom', 'left', 'right'). Each value must be greater than 0.
42
46
 
@@ -75,7 +79,7 @@ class BufferSpec(BaseModel):
75
79
  "right": "constant",
76
80
  }
77
81
  )
78
- thickness: dict[str, conint(gt=0)] = Field(
82
+ thickness: dict[str, int] = Field(
79
83
  default_factory=lambda: {
80
84
  "top": 128,
81
85
  "bottom": 128,
@@ -91,6 +95,12 @@ class BufferSpec(BaseModel):
91
95
  raise ValueError(f"Buffer mode must be one of {allowed_modes}, got '{v}'")
92
96
  return v
93
97
 
98
+ @validator("thickness")
99
+ def check_thickness(cls, v):
100
+ if not all(t > 0 for t in v.values()):
101
+ raise ValueError("All thickness values must be greater than 0")
102
+ return v
103
+
94
104
 
95
105
  class Device(BaseModel):
96
106
  device_array: np.ndarray = Field(...)
@@ -100,8 +110,8 @@ class Device(BaseModel):
100
110
  arbitrary_types_allowed = True
101
111
 
102
112
  @property
103
- def shape(self) -> tuple[int, int]:
104
- return self.device_array.shape
113
+ def shape(self) -> tuple[int, ...]:
114
+ return tuple(self.device_array.shape)
105
115
 
106
116
  def __init__(
107
117
  self, device_array: np.ndarray, buffer_spec: Optional[BufferSpec] = None
@@ -370,12 +380,14 @@ class Device(BaseModel):
370
380
  buffer_thickness = self.buffer_spec.thickness
371
381
  buffer_mode = self.buffer_spec.mode
372
382
 
373
- crop_top = buffer_thickness["top"] if buffer_mode["top"] == "edge" else 0
383
+ crop_top = buffer_thickness["top"] if buffer_mode["top"] == "constant" else 0
374
384
  crop_bottom = (
375
- buffer_thickness["bottom"] if buffer_mode["bottom"] == "edge" else 0
385
+ buffer_thickness["bottom"] if buffer_mode["bottom"] == "constant" else 0
386
+ )
387
+ crop_left = buffer_thickness["left"] if buffer_mode["left"] == "constant" else 0
388
+ crop_right = (
389
+ buffer_thickness["right"] if buffer_mode["right"] == "constant" else 0
376
390
  )
377
- crop_left = buffer_thickness["left"] if buffer_mode["left"] == "edge" else 0
378
- crop_right = buffer_thickness["right"] if buffer_mode["right"] == "edge" else 0
379
391
 
380
392
  ndarray = device_array[
381
393
  crop_top : device_array.shape[0] - crop_bottom,
@@ -529,8 +541,18 @@ class Device(BaseModel):
529
541
  polygons_to_process = hierarchy_polygons[level]
530
542
 
531
543
  if polygons_to_process:
532
- center_x_nm = self.device_array.shape[1] / 2
533
- center_y_nm = self.device_array.shape[0] / 2
544
+ buffer_thickness = self.buffer_spec.thickness
545
+
546
+ center_x_nm = (
547
+ self.device_array.shape[1]
548
+ - buffer_thickness["left"]
549
+ - buffer_thickness["right"]
550
+ ) / 2
551
+ center_y_nm = (
552
+ self.device_array.shape[0]
553
+ - buffer_thickness["top"]
554
+ - buffer_thickness["bottom"]
555
+ ) / 2
534
556
 
535
557
  center_x_um = center_x_nm / 1000
536
558
  center_y_um = center_y_nm / 1000
@@ -583,7 +605,7 @@ class Device(BaseModel):
583
605
  self,
584
606
  eps0: float,
585
607
  thickness: float,
586
- ) -> "td.Structure": # noqa: F821
608
+ ) -> "td.Structure":
587
609
  """
588
610
  Convert the device geometry to a Tidy3D Structure.
589
611
 
@@ -622,7 +644,10 @@ class Device(BaseModel):
622
644
  eps_dataset = SpatialDataArray(eps_array, coords=dict(x=X, y=Y, z=Z))
623
645
  medium = CustomMedium.from_eps_raw(eps_dataset)
624
646
  return Structure(
625
- geometry=Box(center=(0, 0, 0), size=(inf, inf, thickness)), medium=medium
647
+ geometry=Box(center=(0, 0, 0), size=(inf, inf, thickness), attrs={}),
648
+ medium=medium,
649
+ name="device",
650
+ attrs={},
626
651
  )
627
652
 
628
653
  def to_3d(self, thickness_nm: int) -> np.ndarray:
@@ -678,7 +703,7 @@ class Device(BaseModel):
678
703
  If the numpy-stl package is not installed.
679
704
  """
680
705
  try:
681
- from stl import mesh
706
+ from stl import mesh # type: ignore
682
707
  except ImportError:
683
708
  raise ImportError(
684
709
  "The stl package is required to use this function; "
@@ -764,7 +789,7 @@ class Device(BaseModel):
764
789
  self,
765
790
  show_buffer: bool = True,
766
791
  bounds: Optional[tuple[tuple[int, int], tuple[int, int]]] = None,
767
- level: int = None,
792
+ level: Optional[int] = None,
768
793
  ax: Optional[Axes] = None,
769
794
  **kwargs,
770
795
  ) -> Axes:
@@ -819,7 +844,7 @@ class Device(BaseModel):
819
844
  # label: Optional[str] = "Device contour",
820
845
  show_buffer: bool = True,
821
846
  bounds: Optional[tuple[tuple[int, int], tuple[int, int]]] = None,
822
- level: int = None,
847
+ level: Optional[int] = None,
823
848
  ax: Optional[Axes] = None,
824
849
  **kwargs,
825
850
  ):
@@ -893,7 +918,7 @@ class Device(BaseModel):
893
918
  self,
894
919
  show_buffer: bool = True,
895
920
  bounds: Optional[tuple[tuple[int, int], tuple[int, int]]] = None,
896
- level: int = None,
921
+ level: Optional[int] = None,
897
922
  ax: Optional[Axes] = None,
898
923
  **kwargs,
899
924
  ):
@@ -956,7 +981,7 @@ class Device(BaseModel):
956
981
  ref_device: "Device",
957
982
  show_buffer: bool = True,
958
983
  bounds: Optional[tuple[tuple[int, int], tuple[int, int]]] = None,
959
- level: int = None,
984
+ level: Optional[int] = None,
960
985
  ax: Optional[Axes] = None,
961
986
  **kwargs,
962
987
  ) -> Axes:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prefab
3
- Version: 1.1.4
3
+ Version: 1.1.5
4
4
  Summary: Artificial nanofabrication of integrated photonic circuits using deep learning
5
5
  Project-URL: Homepage, https://prefabphotonics.com
6
6
  Project-URL: Repository, https://github.com/PreFab-Photonics/PreFab
@@ -1,13 +1,13 @@
1
- prefab/__init__.py,sha256=7MmkG6X6FZ7c4lS8eAF5cNu_NYnwIeDVgwCiX9ysYPw,425
1
+ prefab/__init__.py,sha256=0QHTuxxeHo3xJIUq20iQCLiC2nk-rgf2C374l-Aby-g,425
2
2
  prefab/__main__.py,sha256=aAgt1WXa44k1nJqsiSD3uAfNeGpwtjWqMUYCHN5_Qrw,2759
3
- prefab/compare.py,sha256=2MKUT7N2A639tUGCnJHpfF9MmS-v3oARDkTqHbWJ9OM,3239
4
- prefab/device.py,sha256=l0etqB0559xa9Frb0IKl5N3kU56vWHlwHc-qehINTlw,52292
3
+ prefab/compare.py,sha256=iz0H5EvZFZ5O-N2QOQ6wFe-Hftkfyd6oMYpjfjnrMIw,3251
4
+ prefab/device.py,sha256=kKmud8QxfSBvadeZw56W_MNXqjRIyTA16jNTQ8v69U0,53048
5
5
  prefab/geometry.py,sha256=0sa6ietUWZGkxOnUPUzD3q2QpFuOpWkSANoopGpPd6s,11035
6
6
  prefab/models.py,sha256=JpBqNFIqbo1ymKEl0NWWF4ZkhvK23rEVVBEFl05TXCI,3671
7
7
  prefab/predict.py,sha256=upGTeNC6vY9Tdko6JEM0gKQH1PGUVYXACpep1OT8EVs,10593
8
8
  prefab/read.py,sha256=MuF-cugFQ7MWBJ8DOvQuwktIk0fJ8PXBeLye0ydrB8o,14734
9
9
  prefab/shapes.py,sha256=2qaqyNzu5WG3wVdk4oQzeNXmhwXRHcPnRZlgRrM4MoA,25576
10
- prefab-1.1.4.dist-info/METADATA,sha256=FDqQukBN09Eg4BDhn7Q7p46nWOoLwxjWk9CP2VeRoxo,34824
11
- prefab-1.1.4.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
12
- prefab-1.1.4.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
13
- prefab-1.1.4.dist-info/RECORD,,
10
+ prefab-1.1.5.dist-info/METADATA,sha256=tk_MMU6lQcjqt4FBDgjx87ziII0ulouu2zCj2Ayr-g8,34824
11
+ prefab-1.1.5.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
12
+ prefab-1.1.5.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
13
+ prefab-1.1.5.dist-info/RECORD,,
File without changes