prefab 0.5.1__py3-none-any.whl → 1.1.7__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 +15 -38
- prefab/__main__.py +17 -16
- prefab/compare.py +126 -0
- prefab/device.py +1486 -0
- prefab/geometry.py +394 -0
- prefab/models.py +114 -0
- prefab/predict.py +337 -0
- prefab/read.py +503 -0
- prefab/shapes.py +773 -0
- {prefab-0.5.1.dist-info → prefab-1.1.7.dist-info}/METADATA +38 -36
- prefab-1.1.7.dist-info/RECORD +13 -0
- {prefab-0.5.1.dist-info → prefab-1.1.7.dist-info}/WHEEL +1 -1
- prefab/io.py +0 -214
- prefab/predictor.py +0 -231
- prefab/processor.py +0 -248
- prefab-0.5.1.dist-info/RECORD +0 -9
- {prefab-0.5.1.dist-info → prefab-1.1.7.dist-info}/licenses/LICENSE +0 -0
prefab/__init__.py
CHANGED
|
@@ -1,47 +1,24 @@
|
|
|
1
1
|
"""
|
|
2
|
-
The
|
|
3
|
-
device layouts, and utilities for interacting with GDSII files.
|
|
2
|
+
The prefab module predicts and corrects nanofabrication variations in photonic devices.
|
|
4
3
|
|
|
5
4
|
Usage:
|
|
6
5
|
import prefab as pf
|
|
7
6
|
"""
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
from prefab.predictor import predict
|
|
11
|
-
from prefab.predictor import correct
|
|
8
|
+
__version__ = "1.1.7"
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
from
|
|
16
|
-
load_device_img, # Load device from an image file
|
|
17
|
-
load_device_gds, # Load device from a GDSII file
|
|
18
|
-
device_to_cell, # Convert a device layout to a gdstk cell
|
|
19
|
-
)
|
|
10
|
+
from . import compare, geometry, predict, read, shapes
|
|
11
|
+
from .device import BufferSpec, Device
|
|
12
|
+
from .models import models
|
|
20
13
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
binarize_hard, # Hard binarization of grayscale images
|
|
26
|
-
ternarize, # Ternarization of grayscale images
|
|
27
|
-
remove_padding, # Trims excess padding from device images
|
|
28
|
-
zero_boundary, # Applies zero boundary to device images
|
|
29
|
-
generate_device_contour, # Generates contour of device images
|
|
30
|
-
calculate_prediction_uncertainty, # Computes prediction uncertainty for device images
|
|
31
|
-
mse, # Computes mean squared error between two images
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
__all__ = (
|
|
14
|
+
__all__ = [
|
|
15
|
+
"Device",
|
|
16
|
+
"BufferSpec",
|
|
17
|
+
"geometry",
|
|
35
18
|
"predict",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
"remove_padding",
|
|
43
|
-
"zero_boundary",
|
|
44
|
-
"generate_device_contour",
|
|
45
|
-
"calculate_prediction_uncertainty",
|
|
46
|
-
"mse",
|
|
47
|
-
)
|
|
19
|
+
"read",
|
|
20
|
+
"shapes",
|
|
21
|
+
"compare",
|
|
22
|
+
"models",
|
|
23
|
+
"__version__",
|
|
24
|
+
]
|
prefab/__main__.py
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Provides the main entry point for the Prefab authentication CLI."""
|
|
2
|
+
|
|
2
3
|
import argparse
|
|
3
4
|
import os
|
|
4
5
|
import threading
|
|
5
6
|
import webbrowser
|
|
7
|
+
from contextlib import suppress
|
|
6
8
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
7
9
|
|
|
8
10
|
import toml
|
|
9
11
|
|
|
10
12
|
|
|
11
|
-
def
|
|
12
|
-
"""
|
|
13
|
-
Store the JWT and refresh token securely in a TOML file.
|
|
14
|
-
"""
|
|
13
|
+
def store_jwt(jwt, refresh_token):
|
|
14
|
+
"""Store the JWT and refresh token in a TOML file."""
|
|
15
15
|
prefab_file_path = os.path.expanduser("~/.prefab.toml")
|
|
16
16
|
with open(prefab_file_path, "w", encoding="utf-8") as toml_file:
|
|
17
17
|
toml.dump({"access_token": jwt, "refresh_token": refresh_token}, toml_file)
|
|
18
|
-
print(
|
|
18
|
+
print(
|
|
19
|
+
f"Token successfully stored in {prefab_file_path}.\n\n"
|
|
20
|
+
"🎉 Welcome to PreFab!.\n"
|
|
21
|
+
"See our examples at https://docs.prefabphotonics.com/examples to start.\n"
|
|
22
|
+
"Reach out to us at hi@prefabphotonics.com if you have any questions."
|
|
23
|
+
)
|
|
19
24
|
|
|
20
25
|
|
|
21
26
|
class GracefulHTTPServer(HTTPServer):
|
|
@@ -28,9 +33,7 @@ class GracefulHTTPServer(HTTPServer):
|
|
|
28
33
|
|
|
29
34
|
|
|
30
35
|
class CallbackHandler(BaseHTTPRequestHandler):
|
|
31
|
-
"""
|
|
32
|
-
A request handler for the HTTP server that handles the OAuth callback.
|
|
33
|
-
"""
|
|
36
|
+
"""A request handler for the HTTP server that handles the JWT-auth callback."""
|
|
34
37
|
|
|
35
38
|
def do_GET(self):
|
|
36
39
|
if self.path.startswith("/callback"):
|
|
@@ -42,8 +45,8 @@ class CallbackHandler(BaseHTTPRequestHandler):
|
|
|
42
45
|
jwt_token = params.get("token")
|
|
43
46
|
refresh_token = params.get("refresh_token")
|
|
44
47
|
if jwt_token and refresh_token:
|
|
45
|
-
print("Token verified
|
|
46
|
-
|
|
48
|
+
print("Token verified.")
|
|
49
|
+
store_jwt(jwt_token, refresh_token)
|
|
47
50
|
self.send_response_only(200, "OK")
|
|
48
51
|
self.send_header("Content-type", "text/html")
|
|
49
52
|
self.end_headers()
|
|
@@ -56,22 +59,20 @@ class CallbackHandler(BaseHTTPRequestHandler):
|
|
|
56
59
|
|
|
57
60
|
|
|
58
61
|
def main():
|
|
59
|
-
|
|
62
|
+
"""Main function for the Prefab authentication CLI."""
|
|
63
|
+
parser = argparse.ArgumentParser(description="PreFab Auth CLI")
|
|
60
64
|
parser.add_argument("command", help="The command to run", choices=["setup"])
|
|
61
65
|
parser.add_argument(
|
|
62
66
|
"--port", help="Port number for the HTTP server", type=int, default=8000
|
|
63
67
|
)
|
|
64
|
-
|
|
65
68
|
args = parser.parse_args()
|
|
66
69
|
|
|
67
70
|
if args.command == "setup":
|
|
68
71
|
webbrowser.open("https://www.prefabphotonics.com/token-flow")
|
|
69
72
|
httpd = GracefulHTTPServer(("localhost", args.port), CallbackHandler)
|
|
70
73
|
print("Started token authentication flow on the web browser...")
|
|
71
|
-
|
|
74
|
+
with suppress(KeyboardInterrupt):
|
|
72
75
|
httpd.serve_forever()
|
|
73
|
-
except KeyboardInterrupt:
|
|
74
|
-
pass
|
|
75
76
|
httpd.server_close()
|
|
76
77
|
else:
|
|
77
78
|
print(f"Command {args.command} not recognized.")
|
prefab/compare.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Functions to measure the structural similarity between devices."""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
from .device import Device
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def mean_squared_error(device_a: Device, device_b: Device) -> float:
|
|
11
|
+
"""
|
|
12
|
+
Calculate the mean squared error (MSE) between two devices. A lower value indicates
|
|
13
|
+
more similarity.
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
device_a : Device
|
|
18
|
+
The first device.
|
|
19
|
+
device_b : Device
|
|
20
|
+
The second device.
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
float
|
|
25
|
+
The mean squared error between two devices.
|
|
26
|
+
"""
|
|
27
|
+
return float(np.mean((device_a.device_array - device_b.device_array) ** 2))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def intersection_over_union(device_a: Device, device_b: Device) -> float:
|
|
31
|
+
"""
|
|
32
|
+
Calculates the Intersection over Union (IoU) between two binary devices. A value
|
|
33
|
+
closer to 1 indicates more similarity (more overlap).
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
device_a : Device
|
|
38
|
+
The first device (binarized).
|
|
39
|
+
device_b : Device
|
|
40
|
+
The second device (binarized).
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
float
|
|
45
|
+
The Intersection over Union between two devices.
|
|
46
|
+
|
|
47
|
+
Warnings
|
|
48
|
+
--------
|
|
49
|
+
UserWarning
|
|
50
|
+
If one or both devices are not binarized.
|
|
51
|
+
"""
|
|
52
|
+
if not device_a.is_binary or not device_b.is_binary:
|
|
53
|
+
warnings.warn(
|
|
54
|
+
"One or both devices are not binarized.", UserWarning, stacklevel=2
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return np.sum(
|
|
58
|
+
np.logical_and(device_a.device_array, device_b.device_array)
|
|
59
|
+
) / np.sum(np.logical_or(device_a.device_array, device_b.device_array))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def hamming_distance(device_a: Device, device_b: Device) -> int:
|
|
63
|
+
"""
|
|
64
|
+
Calculates the Hamming distance between two binary devices. A lower value indicates
|
|
65
|
+
more similarity. The Hamming distance is calculated as the number of positions at
|
|
66
|
+
which the corresponding pixels are different.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
device_a : Device
|
|
71
|
+
The first device (binarized).
|
|
72
|
+
device_b : Device
|
|
73
|
+
The second device (binarized).
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
int
|
|
78
|
+
The Hamming distance between two devices.
|
|
79
|
+
|
|
80
|
+
Warnings
|
|
81
|
+
--------
|
|
82
|
+
UserWarning
|
|
83
|
+
If one or both devices are not binarized.
|
|
84
|
+
"""
|
|
85
|
+
if not device_a.is_binary or not device_b.is_binary:
|
|
86
|
+
warnings.warn(
|
|
87
|
+
"One or both devices are not binarized.", UserWarning, stacklevel=2
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return int(np.sum(device_a.device_array != device_b.device_array))
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def dice_coefficient(device_a: Device, device_b: Device) -> float:
|
|
94
|
+
"""
|
|
95
|
+
Calculates the Dice coefficient between two binary devices. A value closer to 1
|
|
96
|
+
indicates more similarity. The Dice coefficient is calculated as twice the number of
|
|
97
|
+
pixels in common divided by the total number of pixels in the two devices.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
device_a : Device
|
|
102
|
+
The first device (binarized).
|
|
103
|
+
device_b : Device
|
|
104
|
+
The second device (binarized).
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
float
|
|
109
|
+
The Dice coefficient between two devices.
|
|
110
|
+
|
|
111
|
+
Warnings
|
|
112
|
+
--------
|
|
113
|
+
UserWarning
|
|
114
|
+
If one or both devices are not binarized.
|
|
115
|
+
"""
|
|
116
|
+
if not device_a.is_binary or not device_b.is_binary:
|
|
117
|
+
warnings.warn(
|
|
118
|
+
"One or both devices are not binarized.", UserWarning, stacklevel=2
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
intersection = 2.0 * np.sum(
|
|
122
|
+
np.logical_and(device_a.device_array, device_b.device_array)
|
|
123
|
+
)
|
|
124
|
+
size_a = np.sum(device_a.device_array)
|
|
125
|
+
size_b = np.sum(device_b.device_array)
|
|
126
|
+
return intersection / (size_a + size_b)
|