FiberFusing 1.9.3__tar.gz → 1.9.4__tar.gz
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.
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/__init__.py +1 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/_version.py +3 -3
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/generic_fiber.py +9 -38
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/loader.py +0 -81
- fiberfusing-1.9.4/FiberFusing/geometries/__init__.py +13 -0
- fiberfusing-1.9.4/FiberFusing/geometries/base_class.py +173 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/geometries/linestring.py +70 -21
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/geometries/point.py +56 -22
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/geometries/polygon.py +273 -9
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/geometries/utils.py +9 -9
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/geometry.py +0 -3
- fiberfusing-1.9.4/FiberFusing/graded_index.py +16 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/optical_structure.py +3 -9
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/shapes/ellipse.py +0 -1
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing.egg-info/PKG-INFO +1 -1
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing.egg-info/SOURCES.txt +1 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/PKG-INFO +1 -1
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/extra/custom_graded_index_fiber.py +8 -4
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/test_fiber.py +8 -4
- fiberfusing-1.9.3/FiberFusing/geometries/__init__.py +0 -3
- fiberfusing-1.9.3/FiberFusing/geometries/base_class.py +0 -442
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/.flake8 +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/.github/dependabot.yml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/.github/workflows/deploy_PyPi.yml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/.github/workflows/deploy_anaconda.yml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/.github/workflows/deploy_coverage.yml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/.github/workflows/deploy_documentation.yml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/.gitignore +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/background.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/connection/__init__.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/connection/connection.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/connection/connection_optimization.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/connection/utils.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/coordinate_system.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/directories.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/__init__.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/1550BHP.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/DCF13.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/DCF1300S_20.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/DCF1300S_26.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/DCF1300S_33.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/DCF1300S_42.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/F2028M12.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/F2028M21.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/F2028M24.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/F2058G1.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/F2058L1.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/HI1060.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/HP630.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/SM1950.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/SMF28.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/fluorine_doped_1%_capillary.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/fluorine_doped_2%_capillary.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/test_fiber.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/fiber/fiber_files/test_multimode_fiber.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/helper.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/plottings.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/profile.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/shapes/__init__.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/shapes/base.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/shapes/circle.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/shapes/square.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/structures.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing/utils.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing.egg-info/dependency_links.txt +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing.egg-info/requires.txt +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/FiberFusing.egg-info/top_level.txt +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/LICENSE +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/README.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/Makefile +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/README.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/extra/README.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/extra/custom_step_index_fiber.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/extra/loading_fiber.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/extra/randomize_core.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/extra/structure_shift.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/README.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_line_3.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_line_4.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_line_5.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_ring_10.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_ring_2.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_ring_3.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_ring_4.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_ring_5.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_ring_7.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/examples/geometry/plot_single.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/images/example_3x3.png +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/images/logo.png +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/make.bat +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/_static/default.css +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/_static/thumbnail.png +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/code/components.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/code/coordinate_system.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/code/geometry.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/code/shapes.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/code/utils.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/code.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/conf.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/gallery/index.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/index.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/references.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/sg_execution_times.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/docs/source/theory.rst +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/meta.yaml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/notebook.ipynb +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/pyproject.toml +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/setup.cfg +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/__init__.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/fiber_loader.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/test_boundaries.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/test_cooordinate_system.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/test_fused_structure.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/test_generic_fiber.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/test_geometries.py +0 -0
- {fiberfusing-1.9.3 → fiberfusing-1.9.4}/tests/test_polygon.py +0 -0
|
@@ -5,6 +5,7 @@ from .geometries.polygon import Polygon, EmptyPolygon # noqa: F401
|
|
|
5
5
|
from .shapes import Circle, Square # noqa: F401
|
|
6
6
|
from .background import BackGround # noqa: F401
|
|
7
7
|
from .optical_structure import CircleOpticalStructure # noqa: F401
|
|
8
|
+
from .graded_index import GradedIndex # noqa: F401
|
|
8
9
|
micro = 1e-6
|
|
9
10
|
|
|
10
11
|
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.9.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 9,
|
|
31
|
+
__version__ = version = '1.9.4'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 9, 4)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g4851a65b0'
|
|
@@ -12,7 +12,7 @@ from FiberFusing.geometries.point import Point
|
|
|
12
12
|
from FiberFusing.coordinate_system import CoordinateSystem
|
|
13
13
|
from FiberFusing.plottings import plot_polygon
|
|
14
14
|
from FiberFusing.helper import _plot_helper
|
|
15
|
-
|
|
15
|
+
from FiberFusing.graded_index import GradedIndex
|
|
16
16
|
|
|
17
17
|
pp = pprint.PrettyPrinter(indent=4, sort_dicts=False, compact=True, width=1)
|
|
18
18
|
|
|
@@ -110,7 +110,7 @@ class GenericFiber():
|
|
|
110
110
|
|
|
111
111
|
return fiber_copy
|
|
112
112
|
|
|
113
|
-
def create_and_add_new_structure(self, refractive_index: float = None, NA: float = None, **kwargs) -> None:
|
|
113
|
+
def create_and_add_new_structure(self, refractive_index: float | GradedIndex = None, NA: float = None, **kwargs) -> None:
|
|
114
114
|
"""
|
|
115
115
|
Adds a new circular structure to the collection.
|
|
116
116
|
|
|
@@ -136,32 +136,6 @@ class GenericFiber():
|
|
|
136
136
|
setattr(self, new_structure.name, new_structure)
|
|
137
137
|
self.structure_list.append(new_structure)
|
|
138
138
|
|
|
139
|
-
def create_and_add_new_graded_index_structure(self, refractive_index_in: float, refractive_index_out: float, **kwargs) -> None:
|
|
140
|
-
"""
|
|
141
|
-
Adds a new graded index structure to the collection.
|
|
142
|
-
|
|
143
|
-
Parameters
|
|
144
|
-
----------
|
|
145
|
-
refractive_index : float, optional
|
|
146
|
-
The refractive index of the new structure. If provided, NA should be None.
|
|
147
|
-
NA : float, optional
|
|
148
|
-
The numerical aperture of the new structure. If provided, refractive_index should be None.
|
|
149
|
-
|
|
150
|
-
Raises
|
|
151
|
-
------
|
|
152
|
-
ValueError
|
|
153
|
-
If both refractive_index and NA are provided or if neither is provided.
|
|
154
|
-
"""
|
|
155
|
-
new_structure = CircleOpticalStructure(
|
|
156
|
-
**kwargs,
|
|
157
|
-
refractive_index_in=refractive_index_in,
|
|
158
|
-
refractive_index_out=refractive_index_out,
|
|
159
|
-
position=self.position
|
|
160
|
-
)
|
|
161
|
-
setattr(self, new_structure.name, new_structure)
|
|
162
|
-
self.structure_list.append(new_structure)
|
|
163
|
-
|
|
164
|
-
|
|
165
139
|
def _interpret_index_or_NA_to_index(self, refractive_index: float, NA: float) -> float:
|
|
166
140
|
"""
|
|
167
141
|
Interprets and converts NA or index to a refractive index.
|
|
@@ -232,12 +206,11 @@ class GenericFiber():
|
|
|
232
206
|
raster = structure.polygon.get_rasterized_mesh(coordinate_system=coordinate_system)
|
|
233
207
|
mesh[numpy.where(raster != 0)] = 0
|
|
234
208
|
|
|
235
|
-
if structure.
|
|
209
|
+
if isinstance(structure.refractive_index, GradedIndex):
|
|
236
210
|
refractive_index = self.get_graded_index_mesh(
|
|
237
211
|
coordinate_system=coordinate_system,
|
|
238
212
|
polygon=structure.polygon,
|
|
239
|
-
|
|
240
|
-
max_index=structure.refractive_index_out
|
|
213
|
+
refractive_index=structure.refractive_index,
|
|
241
214
|
)
|
|
242
215
|
else:
|
|
243
216
|
refractive_index = structure.refractive_index
|
|
@@ -429,7 +402,7 @@ class GenericFiber():
|
|
|
429
402
|
|
|
430
403
|
return distance
|
|
431
404
|
|
|
432
|
-
def get_graded_index_mesh(self, coordinate_system: CoordinateSystem, polygon,
|
|
405
|
+
def get_graded_index_mesh(self, coordinate_system: CoordinateSystem, polygon, refractive_index: GradedIndex) -> numpy.ndarray:
|
|
433
406
|
"""
|
|
434
407
|
Compute the graded index mesh for a given polygon within the coordinate system.
|
|
435
408
|
|
|
@@ -443,10 +416,8 @@ class GenericFiber():
|
|
|
443
416
|
The coordinate system defining the spatial grid where the index profile will be computed.
|
|
444
417
|
polygon : Polygon
|
|
445
418
|
The polygon object representing the area for which the graded index mesh is computed.
|
|
446
|
-
|
|
447
|
-
The
|
|
448
|
-
max_index : float
|
|
449
|
-
The maximum refractive index value, typically at the center of the polygon.
|
|
419
|
+
refractive_index : GradedIndex
|
|
420
|
+
The graded index object containing the minimum and maximum refractive index values.
|
|
450
421
|
|
|
451
422
|
Returns
|
|
452
423
|
-------
|
|
@@ -485,8 +456,8 @@ class GenericFiber():
|
|
|
485
456
|
normalized_distance_mesh = masked_distance_mesh
|
|
486
457
|
|
|
487
458
|
# Scale the normalized mesh to the index range [min_index, max_index]
|
|
488
|
-
delta_n =
|
|
489
|
-
graded_index_mesh = normalized_distance_mesh * delta_n +
|
|
459
|
+
delta_n = refractive_index.outside - refractive_index.inside
|
|
460
|
+
graded_index_mesh = normalized_distance_mesh * delta_n + refractive_index.inside
|
|
490
461
|
|
|
491
462
|
return graded_index_mesh
|
|
492
463
|
|
|
@@ -235,84 +235,3 @@ class FiberLoader:
|
|
|
235
235
|
processed_layers = self.reorder_layers_if_needed(processed_layers, order)
|
|
236
236
|
|
|
237
237
|
return {'layers': processed_layers}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
# =============================================================================
|
|
241
|
-
# CONVENIENCE FUNCTIONS FOR BACKWARD COMPATIBILITY
|
|
242
|
-
# =============================================================================
|
|
243
|
-
|
|
244
|
-
# Global loader instance
|
|
245
|
-
_default_loader = FiberLoader()
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
def load_fiber(fiber_name: str, clad_refractive_index: float, position: Tuple[float, float] = (0, 0), remove_cladding: bool = False) -> GenericFiber:
|
|
249
|
-
"""
|
|
250
|
-
Convenience function to load a fiber using the default loader.
|
|
251
|
-
|
|
252
|
-
Parameters
|
|
253
|
-
----------
|
|
254
|
-
fiber_name : str
|
|
255
|
-
The name of the fiber to load.
|
|
256
|
-
clad_refractive_index : float
|
|
257
|
-
The refractive index of the cladding material.
|
|
258
|
-
position : Tuple[float, float], optional
|
|
259
|
-
The spatial position of the fiber, defaulting to (0, 0).
|
|
260
|
-
remove_cladding : bool, optional
|
|
261
|
-
Whether to exclude the cladding layer from the fiber configuration.
|
|
262
|
-
|
|
263
|
-
Returns
|
|
264
|
-
-------
|
|
265
|
-
GenericFiber
|
|
266
|
-
A configured GenericFiber object with the specified properties.
|
|
267
|
-
"""
|
|
268
|
-
return _default_loader.load_fiber(fiber_name, clad_refractive_index, position, remove_cladding)
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
def make_fiber(structure_list: List[Dict], clad_refractive_index: float, position: Tuple[float, float] = (0, 0)) -> GenericFiber:
|
|
272
|
-
"""
|
|
273
|
-
Convenience function to make a fiber using the default loader.
|
|
274
|
-
|
|
275
|
-
Parameters
|
|
276
|
-
----------
|
|
277
|
-
structure_list : List[Dict]
|
|
278
|
-
A list of dictionaries, each containing the parameters for a fiber structure.
|
|
279
|
-
clad_refractive_index : float
|
|
280
|
-
The refractive index of the cladding material.
|
|
281
|
-
position : Tuple[float, float], optional
|
|
282
|
-
The spatial position of the fiber.
|
|
283
|
-
|
|
284
|
-
Returns
|
|
285
|
-
-------
|
|
286
|
-
GenericFiber
|
|
287
|
-
The newly created GenericFiber object populated with specified structures.
|
|
288
|
-
"""
|
|
289
|
-
return _default_loader.make_fiber(structure_list, clad_refractive_index, position)
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
def load_fiber_as_dict(fiber_name: str, clad_refractive_index: float = None, order: str = 'in-to-out') -> dict:
|
|
293
|
-
"""
|
|
294
|
-
Convenience function to load fiber configuration as dictionary using the default loader.
|
|
295
|
-
|
|
296
|
-
Parameters
|
|
297
|
-
----------
|
|
298
|
-
fiber_name : str
|
|
299
|
-
Name of the fiber file without extension.
|
|
300
|
-
clad_refractive_index : float, optional
|
|
301
|
-
Refractive index to use for material index calculation.
|
|
302
|
-
order : str, optional
|
|
303
|
-
Layer order in the output dictionary; 'in-to-out' or 'out-to-in' (for backward compatibility).
|
|
304
|
-
|
|
305
|
-
Returns
|
|
306
|
-
-------
|
|
307
|
-
dict
|
|
308
|
-
Dictionary containing the processed fiber configuration.
|
|
309
|
-
"""
|
|
310
|
-
# Convert string to enum for backward compatibility
|
|
311
|
-
if order == 'out-to-in':
|
|
312
|
-
layer_order = LayerOrder.OUT_TO_IN
|
|
313
|
-
else:
|
|
314
|
-
layer_order = LayerOrder.IN_TO_OUT
|
|
315
|
-
|
|
316
|
-
return _default_loader.load_fiber_as_dict(fiber_name, clad_refractive_index, layer_order)
|
|
317
|
-
|
|
318
|
-
# -
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from pydantic import ConfigDict
|
|
2
|
+
|
|
3
|
+
config_dict = ConfigDict(
|
|
4
|
+
extra='forbid',
|
|
5
|
+
arbitrary_types_allowed=True,
|
|
6
|
+
kw_only=True
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from .base_class import Alteration # noqa: F401
|
|
10
|
+
from .point import Point # noqa: F401
|
|
11
|
+
from .linestring import LineString # noqa: F401
|
|
12
|
+
from .polygon import Polygon, EmptyPolygon # noqa: F401
|
|
13
|
+
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from typing import Tuple, Callable, Self
|
|
5
|
+
import copy
|
|
6
|
+
from shapely import affinity
|
|
7
|
+
|
|
8
|
+
import FiberFusing as ff
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Alteration:
|
|
12
|
+
def in_place_copy(function: Callable) -> Callable:
|
|
13
|
+
"""
|
|
14
|
+
Decorator to manage in-place operations.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
function : Callable
|
|
19
|
+
The function to wrap.
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
Callable
|
|
24
|
+
Wrapped function that optionally modifies the object in-place.
|
|
25
|
+
"""
|
|
26
|
+
def wrapper(self, *args, in_place=False, **kwargs):
|
|
27
|
+
instance = self if in_place else self.copy()
|
|
28
|
+
return function(self, instance, *args, **kwargs)
|
|
29
|
+
|
|
30
|
+
return wrapper
|
|
31
|
+
|
|
32
|
+
def copy(self) -> Self:
|
|
33
|
+
"""
|
|
34
|
+
Create a deep copy of the object.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
Alteration
|
|
39
|
+
A new instance that is a deep copy of the current object.
|
|
40
|
+
"""
|
|
41
|
+
return copy.deepcopy(self)
|
|
42
|
+
|
|
43
|
+
def __repr__(self) -> str:
|
|
44
|
+
"""
|
|
45
|
+
Return the string representation of the shapely object.
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
str
|
|
50
|
+
The string representation of the shapely object.
|
|
51
|
+
"""
|
|
52
|
+
return repr(self._shapely_object)
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def is_empty(self) -> bool:
|
|
56
|
+
"""
|
|
57
|
+
Check if the shapely object is empty.
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
bool
|
|
62
|
+
True if the object is empty, False otherwise.
|
|
63
|
+
"""
|
|
64
|
+
return self._shapely_object.is_empty
|
|
65
|
+
|
|
66
|
+
@in_place_copy
|
|
67
|
+
def union(self, output, *others) -> 'Alteration':
|
|
68
|
+
"""
|
|
69
|
+
Perform the union operation with other geometries.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
output : Alteration
|
|
74
|
+
The object to store the result.
|
|
75
|
+
*others : Alteration
|
|
76
|
+
Other geometries to union with.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
Alteration
|
|
81
|
+
The union of the geometries.
|
|
82
|
+
"""
|
|
83
|
+
other_shapes = (o._shapely_object for o in others)
|
|
84
|
+
output._shapely_object = self._shapely_object.union(*other_shapes)
|
|
85
|
+
return output
|
|
86
|
+
|
|
87
|
+
@in_place_copy
|
|
88
|
+
def intersection(self, output, *others) -> Self:
|
|
89
|
+
"""
|
|
90
|
+
Perform the intersection operation with other geometries.
|
|
91
|
+
|
|
92
|
+
Parameters
|
|
93
|
+
----------
|
|
94
|
+
output : Alteration
|
|
95
|
+
The object to store the result.
|
|
96
|
+
*others : Alteration
|
|
97
|
+
Other geometries to intersect with.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
Alteration
|
|
102
|
+
The intersection of the geometries.
|
|
103
|
+
"""
|
|
104
|
+
other_shapes = (o._shapely_object for o in others)
|
|
105
|
+
output._shapely_object = self._shapely_object.intersection(*other_shapes)
|
|
106
|
+
return output
|
|
107
|
+
|
|
108
|
+
@in_place_copy
|
|
109
|
+
def scale(self, output, factor: float, origin: Tuple[float, float] = (0, 0)) -> Self:
|
|
110
|
+
"""
|
|
111
|
+
Scale the geometry by a given factor.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
output : Alteration
|
|
116
|
+
The object to store the result.
|
|
117
|
+
factor : float
|
|
118
|
+
The scaling factor.
|
|
119
|
+
origin : tuple of float, optional
|
|
120
|
+
The origin point for scaling, by default (0, 0).
|
|
121
|
+
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
Alteration
|
|
125
|
+
The scaled geometry.
|
|
126
|
+
"""
|
|
127
|
+
origin_point = ff.geometries.utils.interpret_to_point(origin)
|
|
128
|
+
output._shapely_object = affinity.scale(self._shapely_object, xfact=factor, yfact=factor, origin=origin_point._shapely_object)
|
|
129
|
+
return output
|
|
130
|
+
|
|
131
|
+
@in_place_copy
|
|
132
|
+
def translate(self, output, shift: Tuple[float, float]) -> Self:
|
|
133
|
+
"""
|
|
134
|
+
Translate the geometry by a given shift.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
output : Alteration
|
|
139
|
+
The object to store the result.
|
|
140
|
+
shift : tuple of float
|
|
141
|
+
The (x, y) shift values.
|
|
142
|
+
|
|
143
|
+
Returns
|
|
144
|
+
-------
|
|
145
|
+
Alteration
|
|
146
|
+
The translated geometry.
|
|
147
|
+
"""
|
|
148
|
+
shift_point = ff.geometries.utils.interpret_to_point(shift)
|
|
149
|
+
output._shapely_object = affinity.translate(self._shapely_object, shift_point.x, shift_point.y)
|
|
150
|
+
return output
|
|
151
|
+
|
|
152
|
+
@in_place_copy
|
|
153
|
+
def rotate(self, output, angle: float, origin: Tuple[float, float] = (0, 0)) -> Self:
|
|
154
|
+
"""
|
|
155
|
+
Rotate the geometry by a specified angle around an origin.
|
|
156
|
+
|
|
157
|
+
Parameters
|
|
158
|
+
----------
|
|
159
|
+
output : Alteration
|
|
160
|
+
The object to store the result.
|
|
161
|
+
angle : float
|
|
162
|
+
The rotation angle in degrees.
|
|
163
|
+
origin : tuple of float, optional
|
|
164
|
+
The origin point for rotation, by default (0, 0).
|
|
165
|
+
|
|
166
|
+
Returns
|
|
167
|
+
-------
|
|
168
|
+
Alteration
|
|
169
|
+
The rotated geometry.
|
|
170
|
+
"""
|
|
171
|
+
origin_point = ff.geometries.utils.interpret_to_point(origin)
|
|
172
|
+
output._shapely_object = affinity.rotate(self._shapely_object, angle=angle, origin=origin_point._shapely_object)
|
|
173
|
+
return output
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
-
from typing import Optional, Tuple
|
|
4
|
+
from typing import Optional, Tuple, Self
|
|
5
5
|
import numpy as np
|
|
6
6
|
from pydantic.dataclasses import dataclass
|
|
7
7
|
from dataclasses import field
|
|
8
|
-
from pydantic import ConfigDict
|
|
9
8
|
from shapely.affinity import scale
|
|
10
9
|
import shapely.geometry as geo
|
|
11
|
-
from FiberFusing.geometries.base_class import Alteration
|
|
12
|
-
import FiberFusing as ff
|
|
13
10
|
|
|
11
|
+
from FiberFusing.geometries.base_class import Alteration
|
|
12
|
+
from FiberFusing import geometries
|
|
14
13
|
|
|
15
|
-
@dataclass(config=
|
|
14
|
+
@dataclass(config=geometries.config_dict)
|
|
16
15
|
class LineString(Alteration):
|
|
17
16
|
coordinates: Optional[Tuple] = field(default=None, repr=False)
|
|
18
17
|
instance: Optional[geo.LineString] = field(default=None, repr=False)
|
|
@@ -44,51 +43,92 @@ class LineString(Alteration):
|
|
|
44
43
|
return self._shapely_object.centroid
|
|
45
44
|
|
|
46
45
|
@property
|
|
47
|
-
def mid_point(self) -> '
|
|
46
|
+
def mid_point(self) -> 'geometries.Point':
|
|
48
47
|
""" Returns the midpoint of the line string as a Shapely Point object. """
|
|
49
48
|
P0, P1 = self.boundary
|
|
50
|
-
return
|
|
49
|
+
return geometries.Point(position=[(P0.x + P1.x) / 2, (P0.y + P1.y) / 2])
|
|
51
50
|
|
|
52
51
|
@property
|
|
53
52
|
def length(self) -> float:
|
|
54
53
|
""" Returns the length of the line string. """
|
|
55
54
|
return self._shapely_object.length
|
|
56
55
|
|
|
57
|
-
def intersect(self, other:
|
|
58
|
-
"""
|
|
56
|
+
def intersect(self, other: Self) -> None:
|
|
57
|
+
"""
|
|
58
|
+
Intersects this line string with another, updating the shapely object in place.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
other : LineString
|
|
63
|
+
The other line string to intersect with.
|
|
64
|
+
|
|
65
|
+
"""
|
|
59
66
|
self._shapely_object = self._shapely_object.intersection(other._shapely_object)
|
|
60
67
|
|
|
61
|
-
def get_perpendicular(self) ->
|
|
68
|
+
def get_perpendicular(self) -> Self:
|
|
62
69
|
""" Returns a new LineString object that is perpendicular to this one. """
|
|
63
70
|
mid = self.mid_point
|
|
64
71
|
p0, p1 = self.boundary
|
|
65
72
|
dx, dy = p1.x - p0.x, p1.y - p0.y
|
|
66
|
-
new_coords =
|
|
73
|
+
new_coords = geometries.Point(position=(mid.x - dy, mid.y + dx)), geometries.Point(position=(mid.x + dy, mid.y - dx))
|
|
67
74
|
return LineString(coordinates=new_coords)
|
|
68
75
|
|
|
69
|
-
def get_position_parametrization(self, t: float) -> '
|
|
70
|
-
"""
|
|
76
|
+
def get_position_parametrization(self, t: float) -> 'geometries.Point':
|
|
77
|
+
"""
|
|
78
|
+
Returns the point at parameter t along the line. 0 <= t <= 1.
|
|
79
|
+
|
|
80
|
+
Parameters
|
|
81
|
+
----------
|
|
82
|
+
t : float
|
|
83
|
+
The parameter along the line, where 0 <= t <= 1.
|
|
84
|
+
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
geometries.Point
|
|
88
|
+
The point at parameter t along the line.
|
|
89
|
+
"""
|
|
71
90
|
p0, p1 = self.boundary
|
|
72
91
|
x = p0.x * (1 - t) + p1.x * t
|
|
73
92
|
y = p0.y * (1 - t) + p1.y * t
|
|
74
|
-
return
|
|
93
|
+
return geometries.Point(position=(x, y))
|
|
75
94
|
|
|
76
95
|
def render_on_axis(self, ax, **kwargs) -> None:
|
|
77
|
-
"""
|
|
96
|
+
"""
|
|
97
|
+
Renders the line string on a given matplotlib axis.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
ax : matplotlib.axes.Axes
|
|
102
|
+
The axes to render the line string on.
|
|
103
|
+
**kwargs : keyword arguments
|
|
104
|
+
Additional keyword arguments to pass to the plot function.
|
|
105
|
+
"""
|
|
78
106
|
x, y = self._shapely_object.xy
|
|
79
107
|
ax.plot(x, y, **kwargs)
|
|
80
108
|
|
|
81
|
-
def make_length(self, length: float) ->
|
|
109
|
+
def make_length(self, length: float) -> Self:
|
|
82
110
|
""" Returns a new LineString scaled to the specified length. """
|
|
83
111
|
return self.extend(factor=length / self.length)
|
|
84
112
|
|
|
85
|
-
def centering(self, center: geo.Point) ->
|
|
86
|
-
"""
|
|
113
|
+
def centering(self, center: geo.Point) -> Self:
|
|
114
|
+
"""
|
|
115
|
+
Centers the line string at a given point.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
center : geo.Point
|
|
120
|
+
The point to center the line string around.
|
|
121
|
+
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
LineString
|
|
125
|
+
A new LineString centered at the specified point.
|
|
126
|
+
"""
|
|
87
127
|
p0, p1 = self.boundary
|
|
88
128
|
mid = self.mid_point
|
|
89
129
|
dx, dy = center.x - mid.x, center.y - mid.y
|
|
90
130
|
new_coords = [(p.x + dx, p.y + dy) for p in [p0, p1]]
|
|
91
|
-
new_coords =
|
|
131
|
+
new_coords = geometries.Point(position=new_coords[0]), geometries.Point(position=new_coords[1])
|
|
92
132
|
return LineString(coordinates=tuple(new_coords))
|
|
93
133
|
|
|
94
134
|
def get_vector(self) -> np.ndarray:
|
|
@@ -98,8 +138,17 @@ class LineString(Alteration):
|
|
|
98
138
|
norm = np.sqrt(dx**2 + dy**2)
|
|
99
139
|
return np.array([dx, dy]) / norm if norm != 0 else np.array([0, 0])
|
|
100
140
|
|
|
101
|
-
def extend(self, factor: float = 1) ->
|
|
102
|
-
"""
|
|
141
|
+
def extend(self, factor: float = 1) -> Self:
|
|
142
|
+
"""
|
|
143
|
+
Returns a new LineString scaled by the specified factor.
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
factor : float
|
|
148
|
+
The scaling factor to apply to the line string.
|
|
149
|
+
|
|
150
|
+
Returns
|
|
151
|
+
"""
|
|
103
152
|
scaled_string = scale(self._shapely_object, xfact=factor, yfact=factor, origin='center')
|
|
104
153
|
return LineString(instance=scaled_string)
|
|
105
154
|
|
|
@@ -2,19 +2,17 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Built-in imports
|
|
5
|
-
from typing import Optional, Tuple
|
|
5
|
+
from typing import Optional, Tuple, Self
|
|
6
6
|
import numpy
|
|
7
7
|
from pydantic.dataclasses import dataclass
|
|
8
|
-
from pydantic import ConfigDict
|
|
9
|
-
from FiberFusing.geometries.base_class import Alteration
|
|
10
8
|
import shapely.geometry as geo
|
|
11
9
|
import matplotlib.pyplot as plt
|
|
12
|
-
import FiberFusing as ff
|
|
13
|
-
from FiberFusing.helper import _plot_helper
|
|
14
10
|
|
|
11
|
+
from FiberFusing.helper import _plot_helper
|
|
12
|
+
from FiberFusing import geometries
|
|
15
13
|
|
|
16
|
-
@dataclass(config=
|
|
17
|
-
class Point(Alteration):
|
|
14
|
+
@dataclass(config=geometries.config_dict)
|
|
15
|
+
class Point(geometries.base_class.Alteration):
|
|
18
16
|
position: Optional[Tuple[float, float]] = None
|
|
19
17
|
instance: Optional[geo.Point] = None
|
|
20
18
|
index: Optional[float] = None
|
|
@@ -38,54 +36,90 @@ class Point(Alteration):
|
|
|
38
36
|
"""Returns the y-coordinate of the point."""
|
|
39
37
|
return self._shapely_object.y
|
|
40
38
|
|
|
41
|
-
def shift_position(self, shift: Tuple[float, float]) ->
|
|
39
|
+
def shift_position(self, shift: Tuple[float, float]) -> Self:
|
|
42
40
|
"""
|
|
43
41
|
Shifts the point by a given offset and returns a new Point instance.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
shift : tuple of float
|
|
46
|
+
The (x, y) offset to shift the point by.
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
50
|
+
Point
|
|
51
|
+
A new Point instance representing the shifted position.
|
|
44
52
|
"""
|
|
45
|
-
point_shift =
|
|
53
|
+
point_shift = geometries.utils.interpret_to_point(shift)
|
|
46
54
|
return self.__add__(point_shift)
|
|
47
55
|
|
|
48
|
-
def __add__(self, other) ->
|
|
56
|
+
def __add__(self, other) -> Self:
|
|
49
57
|
"""
|
|
50
58
|
Adds the coordinates of another point to this one and returns a new Point instance.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
other : Point
|
|
63
|
+
The other point to add.
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
Point
|
|
68
|
+
A new Point instance representing the sum of the two points.
|
|
51
69
|
"""
|
|
52
|
-
other =
|
|
70
|
+
other = geometries.utils.interpret_to_point(other)
|
|
53
71
|
|
|
54
72
|
return Point(position=(self.x + other.x, self.y + other.y))
|
|
55
73
|
|
|
56
|
-
def __sub__(self, other) ->
|
|
74
|
+
def __sub__(self, other) -> Self:
|
|
57
75
|
"""
|
|
58
76
|
Subtracts the coordinates of another point from this one and returns a new Point instance.
|
|
59
77
|
"""
|
|
60
|
-
other =
|
|
78
|
+
other = geometries.utils.interpret_to_point(other)
|
|
61
79
|
return Point(position=(self.x - other.x, self.y - other.y))
|
|
62
80
|
|
|
63
|
-
def __neg__(self) ->
|
|
81
|
+
def __neg__(self) -> Self:
|
|
64
82
|
"""
|
|
65
83
|
Negates the coordinates of this point and returns a new Point instance.
|
|
66
84
|
"""
|
|
67
85
|
return Point(position=[-self.x, -self.y])
|
|
68
86
|
|
|
69
|
-
def __mul__(self, factor: float) ->
|
|
87
|
+
def __mul__(self, factor: float) -> Self:
|
|
70
88
|
"""
|
|
71
89
|
Multiplies the coordinates of this point by a scalar and returns a new Point instance.
|
|
72
90
|
"""
|
|
73
91
|
return Point(position=[self.x * factor, self.y * factor])
|
|
74
92
|
|
|
75
|
-
def distance(self, other:
|
|
93
|
+
def distance(self, other: Self) -> float:
|
|
76
94
|
"""
|
|
77
95
|
Computes the Euclidean distance between this point and another point.
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
other : Point
|
|
100
|
+
The other point to compute the distance to.
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
float
|
|
105
|
+
The Euclidean distance between the two points.
|
|
78
106
|
"""
|
|
79
107
|
return numpy.sqrt((self.x - other.x)**2 + (self.y - other.y)**2)
|
|
80
108
|
|
|
81
109
|
@_plot_helper
|
|
82
|
-
def plot(
|
|
83
|
-
self,
|
|
84
|
-
ax: plt.Axes = None,
|
|
85
|
-
marker: str = 'x',
|
|
86
|
-
size: int = 20,
|
|
87
|
-
label: str = None) -> None:
|
|
110
|
+
def plot(self, ax: plt.Axes = None, marker: str = 'x', size: int = 20, label: str = None) -> None:
|
|
88
111
|
"""
|
|
89
112
|
Renders this point on the given axis, optionally with text.
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
ax : plt.Axes
|
|
117
|
+
The Matplotlib axis to render the point on.
|
|
118
|
+
marker : str
|
|
119
|
+
The marker style for the point.
|
|
120
|
+
size : int
|
|
121
|
+
The size of the point marker.
|
|
122
|
+
label : str
|
|
123
|
+
The label for the point, if any.
|
|
90
124
|
"""
|
|
91
125
|
ax.scatter(self.x, self.y, label=label, marker=marker, s=size)
|