prefab 1.0.3__py3-none-any.whl → 1.0.4__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.0.3"
8
+ __version__ = "1.0.4"
9
9
 
10
10
  from . import compare, geometry, read, shapes
11
11
  from .device import BufferSpec, Device
prefab/device.py CHANGED
@@ -224,6 +224,7 @@ class Device(BaseModel):
224
224
  model: Model,
225
225
  model_type: str,
226
226
  binarize: bool,
227
+ gpu: bool = False,
227
228
  ) -> "Device":
228
229
  try:
229
230
  with open(os.path.expanduser("~/.prefab.toml")) as file:
@@ -245,6 +246,7 @@ class Device(BaseModel):
245
246
  "Signup/login and generate a new token.\n"
246
247
  "See https://www.prefabphotonics.com/docs/guides/quickstart."
247
248
  ) from None
249
+
248
250
  headers = {
249
251
  "Authorization": f"Bearer {access_token}",
250
252
  "X-Refresh-Token": refresh_token,
@@ -258,84 +260,99 @@ class Device(BaseModel):
258
260
  }
259
261
  json_data = json.dumps(predict_data)
260
262
 
261
- endpoint_url = "https://prefab-photonics--predict-v1.modal.run"
262
-
263
- with requests.post(
264
- endpoint_url, data=json_data, headers=headers, stream=True
265
- ) as response:
266
- response.raise_for_status()
267
- event_type = None
268
- model_descriptions = {"p": "Prediction", "c": "Correction", "s": "SEMulate"}
269
- progress_bar = tqdm(
270
- total=100,
271
- desc=f"{model_descriptions[model_type]}",
272
- unit="%",
273
- colour="green",
274
- bar_format="{l_bar}{bar:30}{r_bar}{bar:-10b}",
275
- )
263
+ endpoint_url = (
264
+ "https://prefab-photonics--predict-gpu-v1.modal.run"
265
+ if gpu
266
+ else "https://prefab-photonics--predict-v1.modal.run"
267
+ )
276
268
 
277
- for line in response.iter_lines():
278
- if line:
279
- decoded_line = line.decode("utf-8").strip()
280
- if decoded_line.startswith("event:"):
281
- event_type = decoded_line.split(":")[1].strip()
282
- elif decoded_line.startswith("data:"):
283
- try:
284
- data_content = json.loads(decoded_line.split("data: ")[1])
285
- if event_type == "progress":
286
- progress = round(100 * data_content["progress"])
287
- progress_bar.update(progress - progress_bar.n)
288
- elif event_type == "result":
289
- results = []
290
- for key in sorted(data_content.keys()):
291
- if key.startswith("result"):
292
- decoded_image = self._decode_array(
293
- data_content[key]
294
- )
295
- results.append(decoded_image)
269
+ try:
270
+ with requests.post(
271
+ endpoint_url, data=json_data, headers=headers, stream=True
272
+ ) as response:
273
+ response.raise_for_status()
274
+ event_type = None
275
+ model_descriptions = {
276
+ "p": "Prediction",
277
+ "c": "Correction",
278
+ "s": "SEMulate",
279
+ }
280
+ progress_bar = tqdm(
281
+ total=100,
282
+ desc=f"{model_descriptions[model_type]}",
283
+ unit="%",
284
+ colour="green",
285
+ bar_format="{l_bar}{bar:30}{r_bar}{bar:-10b}",
286
+ )
296
287
 
297
- if results:
298
- prediction = np.stack(results, axis=-1)
299
- if binarize:
300
- prediction = geometry.binarize_hard(prediction)
288
+ for line in response.iter_lines():
289
+ if line:
290
+ decoded_line = line.decode("utf-8").strip()
291
+ if decoded_line.startswith("event:"):
292
+ event_type = decoded_line.split(":")[1].strip()
293
+ elif decoded_line.startswith("data:"):
294
+ try:
295
+ data_content = json.loads(
296
+ decoded_line.split("data: ")[1]
297
+ )
298
+ if event_type == "progress":
299
+ progress = round(100 * data_content["progress"])
300
+ progress_bar.update(progress - progress_bar.n)
301
+ elif event_type == "result":
302
+ results = []
303
+ for key in sorted(data_content.keys()):
304
+ if key.startswith("result"):
305
+ decoded_image = self._decode_array(
306
+ data_content[key]
307
+ )
308
+ results.append(decoded_image)
309
+
310
+ if results:
311
+ prediction = np.stack(results, axis=-1)
312
+ if binarize:
313
+ prediction = geometry.binarize_hard(
314
+ prediction
315
+ )
316
+ progress_bar.close()
317
+ return prediction
318
+ elif event_type == "end":
319
+ print("Stream ended.")
301
320
  progress_bar.close()
302
- return prediction
303
- elif event_type == "end":
304
- print("Stream ended.")
305
- progress_bar.close()
306
- break
307
- elif event_type == "auth":
308
- if "new_refresh_token" in data_content["auth"]:
309
- prefab_file_path = os.path.expanduser(
310
- "~/.prefab.toml"
311
- )
312
- with open(
313
- prefab_file_path, "w", encoding="utf-8"
314
- ) as toml_file:
315
- toml.dump(
316
- {
317
- "access_token": data_content["auth"][
318
- "new_access_token"
319
- ],
320
- "refresh_token": data_content["auth"][
321
- "new_refresh_token"
322
- ],
323
- },
324
- toml_file,
321
+ break
322
+ elif event_type == "auth":
323
+ if "new_refresh_token" in data_content["auth"]:
324
+ prefab_file_path = os.path.expanduser(
325
+ "~/.prefab.toml"
325
326
  )
326
- elif event_type == "error":
327
- print(f"Error: {data_content['error']}")
328
- progress_bar.close()
329
- except json.JSONDecodeError:
330
- print(
331
- "Failed to decode JSON:",
332
- decoded_line.split("data: ")[1],
333
- )
327
+ with open(
328
+ prefab_file_path, "w", encoding="utf-8"
329
+ ) as toml_file:
330
+ toml.dump(
331
+ {
332
+ "access_token": data_content[
333
+ "auth"
334
+ ]["new_access_token"],
335
+ "refresh_token": data_content[
336
+ "auth"
337
+ ]["new_refresh_token"],
338
+ },
339
+ toml_file,
340
+ )
341
+ elif event_type == "error":
342
+ raise ValueError(f"{data_content['error']}")
343
+ except json.JSONDecodeError:
344
+ raise ValueError(
345
+ "Failed to decode JSON:",
346
+ decoded_line.split("data: ")[1],
347
+ ) from None
348
+ except requests.RequestException as e:
349
+ raise RuntimeError(f"Request failed: {e}") from e
334
350
 
335
351
  def predict(
336
352
  self,
337
353
  model: Model,
338
354
  binarize: bool = False,
355
+ gpu: bool = False,
339
356
  ) -> "Device":
340
357
  """
341
358
  Predict the nanofabrication outcome of the device using a specified model.
@@ -357,6 +374,10 @@ class Device(BaseModel):
357
374
  If True, the predicted device geometry will be binarized using a threshold
358
375
  method. This is useful for converting probabilistic predictions into binary
359
376
  geometries. Defaults to False.
377
+ gpu : bool, optional
378
+ If True, the prediction will be performed on a GPU. Defaults to False.
379
+ Note: The GPU option has more overhead and will take longer for small
380
+ devices, but will be faster for larger devices.
360
381
 
361
382
  Returns
362
383
  -------
@@ -373,6 +394,7 @@ class Device(BaseModel):
373
394
  model=model,
374
395
  model_type="p",
375
396
  binarize=binarize,
397
+ gpu=gpu,
376
398
  )
377
399
  return self.model_copy(update={"device_array": prediction_array})
378
400
 
@@ -380,6 +402,7 @@ class Device(BaseModel):
380
402
  self,
381
403
  model: Model,
382
404
  binarize: bool = True,
405
+ gpu: bool = False,
383
406
  ) -> "Device":
384
407
  """
385
408
  Correct the nanofabrication outcome of the device using a specified model.
@@ -403,6 +426,10 @@ class Device(BaseModel):
403
426
  If True, the corrected device geometry will be binarized using a threshold
404
427
  method. This is useful for converting probabilistic corrections into binary
405
428
  geometries. Defaults to True.
429
+ gpu : bool, optional
430
+ If True, the prediction will be performed on a GPU. Defaults to False.
431
+ Note: The GPU option has more overhead and will take longer for small
432
+ devices, but will be faster for larger devices.
406
433
 
407
434
  Returns
408
435
  -------
@@ -419,12 +446,14 @@ class Device(BaseModel):
419
446
  model=model,
420
447
  model_type="c",
421
448
  binarize=binarize,
449
+ gpu=gpu,
422
450
  )
423
451
  return self.model_copy(update={"device_array": correction_array})
424
452
 
425
453
  def semulate(
426
454
  self,
427
455
  model: Model,
456
+ gpu: bool = False,
428
457
  ) -> "Device":
429
458
  """
430
459
  Simulate the appearance of the device as if viewed under a scanning electron
@@ -444,6 +473,10 @@ class Device(BaseModel):
444
473
  in `models.py`. Each model is associated with a version and dataset that
445
474
  detail its creation and the data it was trained on, ensuring the SEMulation
446
475
  is tailored to specific fabrication parameters.
476
+ gpu : bool, optional
477
+ If True, the prediction will be performed on a GPU. Defaults to False.
478
+ Note: The GPU option has more overhead and will take longer for small
479
+ devices, but will be faster for larger devices.
447
480
 
448
481
  Returns
449
482
  -------
@@ -455,6 +488,7 @@ class Device(BaseModel):
455
488
  model=model,
456
489
  model_type="s",
457
490
  binarize=False,
491
+ gpu=gpu,
458
492
  )
459
493
  return self.model_copy(update={"device_array": semulated_array})
460
494
 
@@ -1259,3 +1293,5 @@ class Device(BaseModel):
1259
1293
  with higher values indicating greater uncertainty.
1260
1294
  """
1261
1295
  return 1 - 2 * np.abs(0.5 - self.device_array)
1296
+
1297
+ return 1 - 2 * np.abs(0.5 - self.device_array)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prefab
3
- Version: 1.0.3
3
+ Version: 1.0.4
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,12 +1,12 @@
1
- prefab/__init__.py,sha256=54JuP2jMRBoA7uWb9uoQ_VXXsi_V1ld_LM2A9wXiLkA,401
1
+ prefab/__init__.py,sha256=z7di6Rcufbv_haAVfAam3Q_EZaBWjv-DWpidsqLlBmc,401
2
2
  prefab/__main__.py,sha256=aAgt1WXa44k1nJqsiSD3uAfNeGpwtjWqMUYCHN5_Qrw,2759
3
3
  prefab/compare.py,sha256=AfLJ69DTqvt0mkMqNCTdn2KWKoclt_0htGVXvarEhkY,2709
4
- prefab/device.py,sha256=sWDL9xXjDs0LzL91oGu8JFvYCQcMF8msz7fjbxwDWEg,48397
4
+ prefab/device.py,sha256=qIPQNt3nqIpeZasBWHNFxdHC6EBt1_fgWdmeUVWDPlE,50109
5
5
  prefab/geometry.py,sha256=pXsVeu4Ycnq60bG6WqFNoUWnyiNStIaYQgbMIrEyndM,9614
6
6
  prefab/models.py,sha256=UMzYZzKouroxlwkXCMKIYozmQCMhNhvt8kQrZmwmZB4,3671
7
7
  prefab/read.py,sha256=HNuovvQx0Vg0X-z5-gUlL-T1M1RQf81Bmy0wDAdqO28,10782
8
8
  prefab/shapes.py,sha256=Hc6dc2Y5Wmb2mZAxhdjBNEJF7C7tF2o460HNvcqcQdo,24856
9
- prefab-1.0.3.dist-info/METADATA,sha256=yQgJ6qqL8WWfcZmVxRpmAvucNq1XSBYLQra4fmpH3T0,34796
10
- prefab-1.0.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
11
- prefab-1.0.3.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
12
- prefab-1.0.3.dist-info/RECORD,,
9
+ prefab-1.0.4.dist-info/METADATA,sha256=DI5SMrZH42zLQnaJlzzKkU5BU9KEpAJsSayAvIxIAk0,34796
10
+ prefab-1.0.4.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
11
+ prefab-1.0.4.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
12
+ prefab-1.0.4.dist-info/RECORD,,
File without changes