photonforge 1.3.1__cp310-cp310-win_amd64.whl → 1.3.2__cp310-cp310-win_amd64.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.
Files changed (39) hide show
  1. photonforge/__init__.py +17 -12
  2. photonforge/_backend/default_project.py +398 -22
  3. photonforge/circuit_base.py +5 -40
  4. photonforge/extension.cp310-win_amd64.pyd +0 -0
  5. photonforge/live_viewer.py +2 -2
  6. photonforge/{analytic_models.py → models/analytic.py} +47 -23
  7. photonforge/models/circuit.py +684 -0
  8. photonforge/{data_model.py → models/data.py} +4 -4
  9. photonforge/{tidy3d_model.py → models/tidy3d.py} +772 -10
  10. photonforge/parametric.py +60 -28
  11. photonforge/plotting.py +1 -1
  12. photonforge/pretty.py +1 -1
  13. photonforge/thumbnails/electrical_absolute.svg +8 -0
  14. photonforge/thumbnails/electrical_adder.svg +9 -0
  15. photonforge/thumbnails/electrical_amplifier.svg +5 -0
  16. photonforge/thumbnails/electrical_differential.svg +6 -0
  17. photonforge/thumbnails/electrical_integral.svg +8 -0
  18. photonforge/thumbnails/electrical_multiplier.svg +9 -0
  19. photonforge/thumbnails/filter.svg +8 -0
  20. photonforge/thumbnails/optical_amplifier.svg +5 -0
  21. photonforge/thumbnails.py +10 -38
  22. photonforge/time_steppers/amplifier.py +353 -0
  23. photonforge/{analytic_time_steppers.py → time_steppers/analytic.py} +191 -2
  24. photonforge/{circuit_time_stepper.py → time_steppers/circuit.py} +6 -5
  25. photonforge/time_steppers/filter.py +400 -0
  26. photonforge/time_steppers/math.py +331 -0
  27. photonforge/{modulator_time_steppers.py → time_steppers/modulator.py} +9 -20
  28. photonforge/{s_matrix_time_stepper.py → time_steppers/s_matrix.py} +3 -3
  29. photonforge/{sink_time_steppers.py → time_steppers/sink.py} +6 -8
  30. photonforge/{source_time_steppers.py → time_steppers/source.py} +20 -18
  31. photonforge/typing.py +5 -0
  32. photonforge/utils.py +89 -15
  33. {photonforge-1.3.1.dist-info → photonforge-1.3.2.dist-info}/METADATA +2 -2
  34. {photonforge-1.3.1.dist-info → photonforge-1.3.2.dist-info}/RECORD +37 -27
  35. photonforge/circuit_model.py +0 -335
  36. photonforge/eme_model.py +0 -816
  37. {photonforge-1.3.1.dist-info → photonforge-1.3.2.dist-info}/WHEEL +0 -0
  38. {photonforge-1.3.1.dist-info → photonforge-1.3.2.dist-info}/entry_points.txt +0 -0
  39. {photonforge-1.3.1.dist-info → photonforge-1.3.2.dist-info}/licenses/LICENSE +0 -0
photonforge/parametric.py CHANGED
@@ -10,9 +10,10 @@ import photonforge as _pf
10
10
 
11
11
  from . import extension as _ext
12
12
  from . import typing as _pft
13
- from .analytic_models import WaveguideModel as _WaveguideModel
14
- from .circuit_model import CircuitModel as _CircuitModel
15
- from .tidy3d_model import Tidy3DModel as _Tidy3DModel
13
+ from .models.analytic import WaveguideModel as _WaveguideModel
14
+ from .models.circuit import CircuitModel as _CircuitModel
15
+ from .models.circuit import DirectionalCouplerCircuitModel as _DirectionalCouplerCircuitModel
16
+ from .models.tidy3d import Tidy3DModel as _Tidy3DModel
16
17
 
17
18
  _OptDimension = _pft.annotate(_pft.Dimension, optional=True)
18
19
  _OptPositiveDimension = _pft.annotate(_pft.PositiveDimension, optional=True)
@@ -895,7 +896,7 @@ def ring_coupler(
895
896
  technology is used.
896
897
  name: Component name.
897
898
  model: Model to be used with this component. If ``None`` a
898
- :class:`photonforge.Tidy3DModel` is used.
899
+ :class:`photonforge.DirectionalCouplerCircuitModel` is used.
899
900
  tidy3d_model_kwargs: *(DEPRECATED)* Dictionary of keyword arguments
900
901
  passed to the component's :class:`photonforge.Tidy3DModel`.
901
902
 
@@ -931,7 +932,7 @@ def ring_coupler(
931
932
  coupling_length = _get_default(function, "coupling_length", coupling_length, 0)
932
933
  port_bends = _get_default(function, "port_bends", port_bends, False)
933
934
  name = _get_default(function, "name", name, "")
934
- model = _get_default(function, "model", model, _Tidy3DModel())
935
+ model = _get_default(function, "model", model, "default")
935
936
 
936
937
  if tidy3d_model_kwargs is not None:
937
938
  _warn.warn(
@@ -944,7 +945,6 @@ def ring_coupler(
944
945
 
945
946
  c = _pf.Component(name, technology=technology)
946
947
  c.properties.__thumbnail__ = "dc"
947
- c.add_model(model)
948
948
 
949
949
  xp = bus_length + 0.5 * coupling_length
950
950
  yp = -radius - coupling_distance
@@ -960,15 +960,29 @@ def ring_coupler(
960
960
  c.add(layer, path)
961
961
 
962
962
  if xp > 0:
963
- c.add_port(_pf.Port((-xp, yp), 0, port_spec[0]))
964
- p0 = c.add_port(_pf.Port((-xr, 0), -90, port_spec[1], inverted=True))
963
+ p0 = c.add_port(_pf.Port((-xp, yp), 0, port_spec[0]))
964
+ p1 = c.add_port(_pf.Port((-xr, 0), -90, port_spec[1], inverted=True))
965
965
  if xp > 0:
966
- c.add_port(_pf.Port((xp, yp), 180, port_spec[0], inverted=True))
967
- p1 = c.add_port(_pf.Port((xr, 0), -90, port_spec[1]))
966
+ p2 = c.add_port(_pf.Port((xp, yp), 180, port_spec[0], inverted=True))
967
+ p3 = c.add_port(_pf.Port((xr, 0), -90, port_spec[1]))
968
968
 
969
969
  if port_bends and euler_fraction == 0:
970
- c[p0].bend_radius = radius
971
- c[p1].bend_radius = -radius
970
+ c[p1].bend_radius = radius
971
+ c[p3].bend_radius = -radius
972
+
973
+ if model == "default":
974
+ if xp > 0:
975
+ model = _DirectionalCouplerCircuitModel(
976
+ arms_model={
977
+ p0: _WaveguideModel(),
978
+ p1: _Tidy3DModel(),
979
+ p2: _WaveguideModel(),
980
+ p3: _Tidy3DModel(),
981
+ }
982
+ )
983
+ else:
984
+ model = _Tidy3DModel()
985
+ c.add_model(model)
972
986
 
973
987
  return c
974
988
 
@@ -1012,7 +1026,7 @@ def s_bend_ring_coupler(
1012
1026
  technology is used.
1013
1027
  name: Component name.
1014
1028
  model: Model to be used with this component. If ``None`` a
1015
- :class:`photonforge.Tidy3DModel` is used.
1029
+ :class:`photonforge.DirectionalCouplerCircuitModel` is used.
1016
1030
  tidy3d_model_kwargs: *(DEPRECATED)* Dictionary of keyword arguments
1017
1031
  passed to the component's :class:`photonforge.Tidy3DModel`.
1018
1032
 
@@ -1055,7 +1069,7 @@ def s_bend_ring_coupler(
1055
1069
  coupling_length = _get_default(function, "coupling_length", coupling_length, 0)
1056
1070
  port_bends = _get_default(function, "port_bends", port_bends, False)
1057
1071
  name = _get_default(function, "name", name, "")
1058
- model = _get_default(function, "model", model, _Tidy3DModel())
1072
+ model = _get_default(function, "model", model, "default")
1059
1073
 
1060
1074
  if tidy3d_model_kwargs is not None:
1061
1075
  _warn.warn(
@@ -1068,7 +1082,6 @@ def s_bend_ring_coupler(
1068
1082
 
1069
1083
  c = _pf.Component(name, technology=technology)
1070
1084
  c.properties.__thumbnail__ = "dc"
1071
- c.add_model(model)
1072
1085
 
1073
1086
  xs = s_bend_length + 0.5 * coupling_length
1074
1087
  ys = -radius - coupling_distance - s_bend_offset
@@ -1088,14 +1101,25 @@ def s_bend_ring_coupler(
1088
1101
  path.arc(-90, -180, radius, endpoint=(-xr, 0), euler_fraction=euler_fraction)
1089
1102
  c.add(layer, path)
1090
1103
 
1091
- c.add_port(_pf.Port((-xs, ys), 0, port_spec[0]))
1092
- p0 = c.add_port(_pf.Port((-xr, 0), -90, port_spec[1], inverted=True))
1093
- c.add_port(_pf.Port((xs, ys), 180, port_spec[0], inverted=True))
1094
- p1 = c.add_port(_pf.Port((xr, 0), -90, port_spec[1]))
1104
+ p0 = c.add_port(_pf.Port((-xs, ys), 0, port_spec[0]))
1105
+ p1 = c.add_port(_pf.Port((-xr, 0), -90, port_spec[1], inverted=True))
1106
+ p2 = c.add_port(_pf.Port((xs, ys), 180, port_spec[0], inverted=True))
1107
+ p3 = c.add_port(_pf.Port((xr, 0), -90, port_spec[1]))
1095
1108
 
1096
1109
  if port_bends and euler_fraction == 0:
1097
- c[p0].bend_radius = radius
1098
- c[p1].bend_radius = -radius
1110
+ c[p1].bend_radius = radius
1111
+ c[p3].bend_radius = -radius
1112
+
1113
+ if model == "default":
1114
+ model = _DirectionalCouplerCircuitModel(
1115
+ arms_model={
1116
+ p0: _WaveguideModel(),
1117
+ p1: _Tidy3DModel(),
1118
+ p2: _WaveguideModel(),
1119
+ p3: _Tidy3DModel(),
1120
+ }
1121
+ )
1122
+ c.add_model(model)
1099
1123
 
1100
1124
  return c
1101
1125
 
@@ -1135,7 +1159,7 @@ def dual_ring_coupler(
1135
1159
  technology is used.
1136
1160
  name: Component name.
1137
1161
  model: Model to be used with this component. If ``None`` a
1138
- :class:`photonforge.Tidy3DModel` is used.
1162
+ :class:`photonforge.DirectionalCouplerCircuitModel` is used.
1139
1163
  tidy3d_model_kwargs: *(DEPRECATED)* Dictionary of keyword arguments
1140
1164
  passed to the component's :class:`photonforge.Tidy3DModel`.
1141
1165
 
@@ -1175,7 +1199,7 @@ def dual_ring_coupler(
1175
1199
  coupling_length = _get_default(function, "coupling_length", coupling_length, 0)
1176
1200
  port_bends = _get_default(function, "port_bends", port_bends, False)
1177
1201
  name = _get_default(function, "name", name, "")
1178
- model = _get_default(function, "model", model, _Tidy3DModel())
1202
+ model = _get_default(function, "model", model, _DirectionalCouplerCircuitModel())
1179
1203
 
1180
1204
  if tidy3d_model_kwargs is not None:
1181
1205
  _warn.warn(
@@ -1255,7 +1279,7 @@ def s_bend_coupler(
1255
1279
  technology is used.
1256
1280
  name: Component name.
1257
1281
  model: Model to be used with this component. If ``None`` a
1258
- :class:`photonforge.Tidy3DModel` is used.
1282
+ :class:`photonforge.DirectionalCouplerCircuitModel` is used.
1259
1283
  tidy3d_model_kwargs: *(DEPRECATED)* Dictionary of keyword arguments
1260
1284
  passed to the component's :class:`photonforge.Tidy3DModel`.
1261
1285
 
@@ -1297,7 +1321,9 @@ def s_bend_coupler(
1297
1321
  euler_fraction = _get_default(function, "euler_fraction", euler_fraction, 0)
1298
1322
  coupling_length = _get_default(function, "coupling_length", coupling_length, 0)
1299
1323
  name = _get_default(function, "name", name, "")
1300
- model = _get_default(function, "model", model, _Tidy3DModel())
1324
+ model = _get_default(
1325
+ function, "model", model, _DirectionalCouplerCircuitModel(arms_model=_WaveguideModel())
1326
+ )
1301
1327
 
1302
1328
  if tidy3d_model_kwargs is not None:
1303
1329
  _warn.warn(
@@ -1373,7 +1399,7 @@ def s_bend_straight_coupler(
1373
1399
  technology is used.
1374
1400
  name: Component name.
1375
1401
  model: Model to be used with this component. If ``None`` a
1376
- :class:`photonforge.Tidy3DModel` is used.
1402
+ :class:`photonforge.DirectionalCouplerCircuitModel` is used.
1377
1403
  tidy3d_model_kwargs: *(DEPRECATED)* Dictionary of keyword arguments
1378
1404
  passed to the component's :class:`photonforge.Tidy3DModel`.
1379
1405
 
@@ -1409,7 +1435,9 @@ def s_bend_straight_coupler(
1409
1435
  euler_fraction = _get_default(function, "euler_fraction", euler_fraction, 0)
1410
1436
  coupling_length = _get_default(function, "coupling_length", coupling_length, 0)
1411
1437
  name = _get_default(function, "name", name, "")
1412
- model = _get_default(function, "model", model, _Tidy3DModel())
1438
+ model = _get_default(
1439
+ function, "model", model, _DirectionalCouplerCircuitModel(arms_model=_WaveguideModel())
1440
+ )
1413
1441
 
1414
1442
  if tidy3d_model_kwargs is not None:
1415
1443
  _warn.warn(
@@ -2307,6 +2335,10 @@ def route_taper(
2307
2335
  size1 = max1 - min1
2308
2336
  size2 = max2 - min2
2309
2337
 
2338
+ ortho_1d = ((size1[0] < _pf.config.grid) and (size2[1] < _pf.config.grid)) or (
2339
+ (size1[1] < _pf.config.grid) and (size2[0] < _pf.config.grid)
2340
+ )
2341
+
2310
2342
  prefer_x = (size1[0] < _pf.config.grid) or (size2[0] < _pf.config.grid)
2311
2343
  prefer_y = (size1[1] < _pf.config.grid) or (size2[1] < _pf.config.grid)
2312
2344
 
@@ -2318,7 +2350,7 @@ def route_taper(
2318
2350
  overlap_x = not (max1[0] < min2[0] or max2[0] < min1[0])
2319
2351
  overlap_y = not (max1[1] < min2[1] or max2[1] < min1[1])
2320
2352
 
2321
- if (overlap_x and overlap_y) or not use_box:
2353
+ if ortho_1d or (overlap_x and overlap_y) or not use_box:
2322
2354
  taper = _pf.envelope([structure1, structure2])
2323
2355
  elif overlap_y or (not overlap_x and prefer_x):
2324
2356
  if max2[0] < min1[0]:
photonforge/plotting.py CHANGED
@@ -15,7 +15,7 @@ from .extension import (
15
15
  config,
16
16
  frequency_classification,
17
17
  )
18
- from .tidy3d_model import Tidy3DModel
18
+ from .models.tidy3d import Tidy3DModel
19
19
  from .utils import C_0
20
20
 
21
21
 
photonforge/pretty.py CHANGED
@@ -2,7 +2,7 @@ import html
2
2
  from collections.abc import Sequence
3
3
 
4
4
  from .extension import Z_MAX, Component, ExtrusionSpec, LayerSpec, PortSpec, Technology
5
- from .tidy3d_model import _tidy3d_to_str
5
+ from .models.tidy3d import _tidy3d_to_str
6
6
 
7
7
 
8
8
  class _Tree:
@@ -0,0 +1,8 @@
1
+ <svg fill="none" width="51" height="51" viewBox="0 0 51 51" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M.93 1.39h49v49h-49z" fill="#fff" stroke="#000"/>
3
+ <path d="M13.98 25.37H1m49.43.08h-9.41" stroke="#000"/>
4
+ <path d="m13.99 9.09 28.32 16.35L14 41.8z" fill="#C43C5B" stroke="#000" stroke-linecap="square" stroke-width=".99"/>
5
+ <path d="m18.359 30.095v-9.3" stroke="#000"/>
6
+ <path d="m26.94 30.095v-9.3" stroke="#000"/>
7
+ <circle cx="22.649" cy="25.5" r="1.3421" fill="#000"/>
8
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg fill="none" width="51" height="51" viewBox="0 0 51 51" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M.93 1.39h49v49h-49z" fill="#fff" stroke="#000"/>
3
+ <path d="m50.43 25.45h-9.41" stroke="#000"/>
4
+ <path d="m13.99 9.09 28.32 16.35L14 41.8z" fill="#C43C5B" stroke="#000" stroke-linecap="square" stroke-width=".99"/>
5
+ <path d="M 13.98,17.37 H 1" stroke="#000"/>
6
+ <path d="M 13.98,33.37 H 1" stroke="#000"/>
7
+ <path d="m27.841 25.445h-8.2276" stroke="#000"/>
8
+ <path d="m23.727 29.559v-8.2276" stroke="#000"/>
9
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg width="51" height="51" viewBox="0 0 51 51" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill="#fff" stroke="#000" d="M.93 1.39h49v49h-49z"/>
3
+ <path d="M13.98 25.37H1m49.43.08h-9.41" stroke="#000"/>
4
+ <path d="m13.99 9.09 28.32 16.35L14 41.8z" fill="#C43C5B" stroke-width=".99" stroke-linecap="square" stroke="#000"/>
5
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg fill="none" width="51" height="51" viewBox="0 0 51 51" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M.93 1.39h49v49h-49z" fill="#fff" stroke="#000"/>
3
+ <path d="M13.98 25.37H1m49.43.08h-9.41" stroke="#000"/>
4
+ <path d="m13.99 9.09 28.32 16.35L14 41.8z" fill="#C43C5B" stroke="#000" stroke-linecap="square" stroke-width=".99"/>
5
+ <path d="m18.932 21.549q0.24088-0.16927 0.47526-0.29948 0.23437-0.13021 0.48177-0.21484 0.2474-0.09115 0.52083-0.13672 0.27344-0.04557 0.59245-0.04557 0.5664 0 1.0286 0.23437 0.46875 0.23438 0.80078 0.67708 0.33203 0.4362 0.50781 1.0742 0.18229 0.63151 0.18229 1.4323 0 1.2695-0.23438 2.3307-0.22786 1.0612-0.6901 1.8294-0.46224 0.76172-1.1589 1.1849-0.69661 0.42318-1.6276 0.42318-0.54687 0-1.0026-0.17578-0.45573-0.18229-0.78776-0.52083-0.32552-0.33854-0.50781-0.8138-0.18229-0.47526-0.18229-1.0742 0-0.72916 0.24088-1.3607t0.67057-1.1003q0.42969-0.46875 1.0156-0.73568 0.59245-0.26693 1.2956-0.26693 0.65104 0 1.1263 0.27344 0.48177 0.27344 0.78776 0.80078 0.01302-0.22135 0.01302-0.42318 0.0065-0.20833 0.0065-0.37109 0-1.237-0.4362-1.8685-0.42969-0.63151-1.1979-0.63151-0.26693 0-0.48828 0.0651-0.22135 0.05859-0.40364 0.13672-0.17578 0.07813-0.30599 0.14323-0.13021 0.05859-0.21484 0.05859-0.07162 0-0.13021-0.03906-0.05859-0.03906-0.13021-0.14974zm1.0156 7.5911q0.41016 0 0.77474-0.16927 0.37109-0.16927 0.67057-0.51432 0.30599-0.35156 0.52734-0.8789 0.22135-0.53385 0.34505-1.2565-0.0651-0.27344-0.1888-0.53385-0.11719-0.26042-0.30599-0.45573-0.1888-0.20182-0.46224-0.31901-0.26693-0.1237-0.63151-0.1237-0.52734 0-0.93099 0.19531-0.40364 0.1888-0.68359 0.53385-0.27344 0.33854-0.41667 0.80729-0.13672 0.46224-0.13672 1.0091 0 0.8138 0.38411 1.263 0.39062 0.44271 1.0547 0.44271zm7.4327-0.01286q0.26667 0 0.54666-0.04 0.28-0.05333 0.45333-0.10667v0.89333q-0.18667 0.09333-0.53333 0.14667-0.34667 0.06667-0.66666 0.06667-0.56 0-1.04-0.18667-0.46667-0.2-0.76-0.68-0.29333-0.48-0.29333-1.3467v-4.16h-1.0133v-0.56l1.0267-0.46667 0.46667-1.52h0.69333v1.64h2.0667v0.90666h-2.0667v4.1333q0 0.65333 0.30667 0.97333 0.32 0.30667 0.81333 0.30667z" fill="#000"/>
6
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg fill="none" width="51" height="51" viewBox="0 0 51 51" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M.93 1.39h49v49h-49z" fill="#fff" stroke="#000"/>
3
+ <path d="M13.98 25.37H1m49.43.08h-9.41" stroke="#000"/>
4
+ <path d="m13.99 9.09 28.32 16.35L14 41.8z" fill="#C43C5B" stroke="#000" stroke-linecap="square" stroke-width=".99"/>
5
+ <path d="m25.43 15.695v-14.723" stroke="#000"/>
6
+ <path d="m21.336 21.656q0.07813-0.63802 0.27344-1.0937 0.20182-0.46224 0.5013-0.75521 0.30599-0.29948 0.69661-0.4362 0.39062-0.14323 0.85286-0.14323 0.20833 0 0.4362 0.03906 0.23438 0.03906 0.42318 0.14323l-0.07161 0.48177q-0.01302 0.07161-0.03906 0.11719-0.02604 0.03906-0.08464 0.05859-0.05859 0.01953-0.15625 0.02604-0.09766 0.0065-0.2474 0.0065-0.35156 0-0.61198 0.08463t-0.44271 0.26693q-0.18229 0.18229-0.28646 0.47526-0.10417 0.28646-0.14974 0.69661l-0.80078 7.6041q-0.0651 0.63802-0.26042 1.1003-0.19531 0.46224-0.5013 0.75521-0.29948 0.29948-0.69661 0.4362-0.39062 0.14323-0.85286 0.14323-0.20833 0-0.4362-0.03906-0.23437-0.03906-0.42318-0.14323l0.07161-0.48177q0.01302-0.07161 0.03906-0.11719 0.02604-0.03906 0.08463-0.05859t0.15625-0.02604q0.09766-0.0065 0.2539-0.0065 0.35156 0 0.60547-0.08463 0.26042-0.08464 0.4362-0.26693 0.18229-0.18229 0.28646-0.47526t0.14974-0.70312z" fill="#000"/>
7
+ </svg>
8
+
@@ -0,0 +1,9 @@
1
+ <svg fill="none" width="51" height="51" viewBox="0 0 51 51" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M.93 1.39h49v49h-49z" fill="#fff" stroke="#000"/>
3
+ <path d="m50.43 25.45h-9.41" stroke="#000"/>
4
+ <path d="m13.99 9.09 28.32 16.35L14 41.8z" fill="#C43C5B" stroke="#000" stroke-linecap="square" stroke-width=".99"/>
5
+ <path d="M 13.98,17.37 H 1" stroke="#000"/>
6
+ <path d="M 13.98,33.37 H 1" stroke="#000"/>
7
+ <path d="m26.636 28.354-5.8178-5.8178" stroke="#000"/>
8
+ <path d="m20.818 28.354 5.8178-5.8178" stroke="#000"/>
9
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill="#fff" stroke="#000" d="M.5.5h49v49H.5z"/>
3
+ <path stroke="#f3c90c" stroke-width="1.63" d="M29.27 32h15.02"/>
4
+ <path stroke="#f3c90c" stroke-width="1.98" d="m23.47 15.42 6.69 17.06"/>
5
+ <path stroke="#000" stroke-width="2" d="M7.89 8.4v35.01m-4.5-4.36h38.94"/>
6
+ <path stroke="#f3c90c" stroke-width="2" d="M7.12 16.05H24.4"/>
7
+ <path d="M10.37 8.4H5.4l2.49-4.3zm31.96 33.13v-4.97l4.3 2.49z" fill="#000"/>
8
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg width="51" height="51" viewBox="0 0 51 51" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill="#fff" stroke="#000" d="M.93 1.39h49v49h-49z"/>
3
+ <path d="M13.98 25.37H1m49.43.08h-9.41" stroke="#000"/>
4
+ <path d="m13.99 9.09 28.32 16.35L14 41.8z" fill="#2faa96" stroke-width=".99" stroke-linecap="square" stroke="#000"/>
5
+ </svg>
photonforge/thumbnails.py CHANGED
@@ -1,14 +1,9 @@
1
1
  from collections import defaultdict
2
2
 
3
3
  try:
4
- from importlib.resources import files
4
+ from importlib.resources import as_file, files
5
5
  except ImportError:
6
- from importlib_resources import files
7
-
8
-
9
- def _load(name):
10
- global thumbnails, _thumb_dir
11
- thumbnails[name.encode("utf-8")] = _thumb_dir.joinpath(name + ".svg").read_text()
6
+ from importlib_resources import as_file, files
12
7
 
13
8
 
14
9
  _thumb_dir = files("photonforge").joinpath("thumbnails")
@@ -17,34 +12,11 @@ _default = _thumb_dir.joinpath("black_box.svg").read_text()
17
12
 
18
13
  thumbnails = defaultdict(lambda: _default)
19
14
 
20
- _load("bend")
21
- _load("black_box")
22
- _load("bondpad")
23
- _load("connection")
24
- _load("crossing")
25
- _load("cw_laser")
26
- _load("dc")
27
- _load("dual_mrr")
28
- _load("edge_coupler")
29
- _load("electrical_termination")
30
- _load("eo_ps")
31
- _load("grating_coupler")
32
- _load("laser")
33
- _load("mmi1x2")
34
- _load("mmi2x2")
35
- _load("mrm")
36
- _load("mrr")
37
- _load("mzm")
38
- _load("photodiode")
39
- _load("psgc")
40
- _load("psr")
41
- _load("s-bend")
42
- _load("source")
43
- _load("taper")
44
- _load("termination")
45
- _load("to_ps")
46
- _load("transition")
47
- _load("u-bend")
48
- _load("wdm")
49
- _load("wg")
50
- _load("y-splitter")
15
+ for item in _thumb_dir.iterdir():
16
+ if not item.is_file():
17
+ continue
18
+ with as_file(item) as f:
19
+ if f.suffix != ".svg":
20
+ continue
21
+ name = f.stem.encode("utf-8")
22
+ thumbnails[name] = item.read_text()