FiberFusing 1.5.0.post0__0-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.
Potentially problematic release.
This version of FiberFusing might be problematic. Click here for more details.
- FiberFusing/__init__.py +15 -0
- FiberFusing/_version.py +16 -0
- FiberFusing/background.py +92 -0
- FiberFusing/base_fused.py +520 -0
- FiberFusing/buffer.py +163 -0
- FiberFusing/components/__init__.py +0 -0
- FiberFusing/components/base_class.py +442 -0
- FiberFusing/components/linestring.py +106 -0
- FiberFusing/components/point.py +91 -0
- FiberFusing/components/polygon.py +228 -0
- FiberFusing/components/utils.py +59 -0
- FiberFusing/configuration/__init__.py +7 -0
- FiberFusing/configuration/line/__init__.py +10 -0
- FiberFusing/configuration/line/configuration_01x01.py +14 -0
- FiberFusing/configuration/line/configuration_02x02.py +18 -0
- FiberFusing/configuration/line/configuration_03x03.py +18 -0
- FiberFusing/configuration/line/configuration_04x04.py +18 -0
- FiberFusing/configuration/line/configuration_05x05.py +18 -0
- FiberFusing/configuration/ring/__init__.py +15 -0
- FiberFusing/configuration/ring/configuration_01x01.py +14 -0
- FiberFusing/configuration/ring/configuration_02x02.py +18 -0
- FiberFusing/configuration/ring/configuration_03x03.py +18 -0
- FiberFusing/configuration/ring/configuration_04x04.py +18 -0
- FiberFusing/configuration/ring/configuration_05x05.py +18 -0
- FiberFusing/configuration/ring/configuration_06x06.py +18 -0
- FiberFusing/configuration/ring/configuration_07x07.py +20 -0
- FiberFusing/configuration/ring/configuration_10x10.py +31 -0
- FiberFusing/configuration/ring/configuration_12x12.py +30 -0
- FiberFusing/configuration/ring/configuration_19x19.py +34 -0
- FiberFusing/connection.py +366 -0
- FiberFusing/connection_optimization.py +246 -0
- FiberFusing/coordinate_system.py +256 -0
- FiberFusing/directories.py +34 -0
- FiberFusing/fiber/__init__.py +0 -0
- FiberFusing/fiber/catalogue.py +165 -0
- FiberFusing/fiber/fiber_files/1550BHP.yaml +14 -0
- FiberFusing/fiber/fiber_files/DCF13.yaml +18 -0
- FiberFusing/fiber/fiber_files/DCF1300S_20.yaml +17 -0
- FiberFusing/fiber/fiber_files/DCF1300S_26.yaml +18 -0
- FiberFusing/fiber/fiber_files/DCF1300S_33.yaml +17 -0
- FiberFusing/fiber/fiber_files/DCF1300S_42.yaml +18 -0
- FiberFusing/fiber/fiber_files/F2028M12.yaml +18 -0
- FiberFusing/fiber/fiber_files/F2028M21.yaml +18 -0
- FiberFusing/fiber/fiber_files/F2028M24.yaml +18 -0
- FiberFusing/fiber/fiber_files/F2058G1.yaml +18 -0
- FiberFusing/fiber/fiber_files/F2058L1.yaml +18 -0
- FiberFusing/fiber/fiber_files/HI1060.yaml +14 -0
- FiberFusing/fiber/fiber_files/HP630.yaml +13 -0
- FiberFusing/fiber/fiber_files/SM1950.yaml +14 -0
- FiberFusing/fiber/fiber_files/SMF28.yaml +14 -0
- FiberFusing/fiber/fiber_files/fluorine_doped_1%_capillary.yaml +9 -0
- FiberFusing/fiber/fiber_files/fluorine_doped_2%_capillary.yaml +9 -0
- FiberFusing/fiber/fiber_files/test_fiber.yaml +14 -0
- FiberFusing/fiber/fiber_files/test_multimode_fiber.yaml +14 -0
- FiberFusing/fiber/generic_fiber.py +413 -0
- FiberFusing/fiber/loader.py +120 -0
- FiberFusing/fiber/structure_collection.py +173 -0
- FiberFusing/fiber_structure.py +210 -0
- FiberFusing/geometry.py +458 -0
- FiberFusing/helper.py +59 -0
- FiberFusing/optical_structure.py +96 -0
- FiberFusing/plottings.py +43 -0
- FiberFusing/utils.py +108 -0
- FiberFusing-1.5.0.0.post0.dist-info/LICENSE +21 -0
- FiberFusing-1.5.0.0.post0.dist-info/METADATA +193 -0
- FiberFusing-1.5.0.0.post0.dist-info/RECORD +68 -0
- FiberFusing-1.5.0.0.post0.dist-info/WHEEL +5 -0
- FiberFusing-1.5.0.0.post0.dist-info/top_level.txt +1 -0
FiberFusing/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .geometry import Geometry # noqa: F401
|
|
2
|
+
from .components.point import Point # noqa: F401
|
|
3
|
+
from .components.linestring import LineString # noqa: F401
|
|
4
|
+
from .components.polygon import Polygon, EmptyPolygon # noqa: F401
|
|
5
|
+
from .buffer import Circle, Square # noqa: F401
|
|
6
|
+
from .background import BackGround # noqa: F401
|
|
7
|
+
from .optical_structure import CircleOpticalStructure # noqa: F401
|
|
8
|
+
micro = 1e-6
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from ._version import version as __version__ # noqa: F401
|
|
13
|
+
|
|
14
|
+
except ImportError:
|
|
15
|
+
__version__ = "0.0.0"
|
FiberFusing/_version.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# file generated by setuptools_scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
TYPE_CHECKING = False
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from typing import Tuple, Union
|
|
6
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
|
+
else:
|
|
8
|
+
VERSION_TUPLE = object
|
|
9
|
+
|
|
10
|
+
version: str
|
|
11
|
+
__version__: str
|
|
12
|
+
__version_tuple__: VERSION_TUPLE
|
|
13
|
+
version_tuple: VERSION_TUPLE
|
|
14
|
+
|
|
15
|
+
__version__ = version = '1.5.0.0.post0'
|
|
16
|
+
__version_tuple__ = version_tuple = (1, 5, 0, 0)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from typing import Tuple, Optional
|
|
5
|
+
from pydantic.dataclasses import dataclass
|
|
6
|
+
from pydantic import ConfigDict
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from FiberFusing.coordinate_system import CoordinateSystem
|
|
10
|
+
from FiberFusing.helper import OverlayStructureBaseClass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class NameSpace:
|
|
14
|
+
"""
|
|
15
|
+
A flexible class that allows dynamic addition of attributes via keyword arguments.
|
|
16
|
+
"""
|
|
17
|
+
def __init__(self, **kwargs):
|
|
18
|
+
"""
|
|
19
|
+
Initializes an instance with attributes specified by keyword arguments.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
**kwargs : dict
|
|
24
|
+
Arbitrary keyword arguments to set as attributes.
|
|
25
|
+
"""
|
|
26
|
+
self.__dict__.update(kwargs)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(config=ConfigDict(extra='forbid', kw_only=True))
|
|
30
|
+
class BackGround(OverlayStructureBaseClass):
|
|
31
|
+
"""
|
|
32
|
+
Represents a background structure overlayed on a mesh, characterized by a circular shape.
|
|
33
|
+
|
|
34
|
+
Attributes
|
|
35
|
+
----------
|
|
36
|
+
index : float
|
|
37
|
+
Refractive index of the background.
|
|
38
|
+
radius : float, optional
|
|
39
|
+
Radius of the circular structure, by default 1000.
|
|
40
|
+
position : Optional[Tuple[float, float]], optional
|
|
41
|
+
A tuple (x, y) specifying the position of the circle's center, by default (0, 0).
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
index: float
|
|
45
|
+
radius: float = 1000
|
|
46
|
+
position: Optional[Tuple[float, float]] = (0, 0)
|
|
47
|
+
|
|
48
|
+
def __post_init__(self):
|
|
49
|
+
"""
|
|
50
|
+
Initializes the background structure by creating a circular polygon.
|
|
51
|
+
"""
|
|
52
|
+
from FiberFusing import Circle
|
|
53
|
+
|
|
54
|
+
polygon = Circle(position=self.position, radius=self.radius, index=self.index)
|
|
55
|
+
self.structure_list = [NameSpace(index=self.index, polygon=polygon, name='background')]
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def refractive_index_list(self) -> list:
|
|
59
|
+
"""
|
|
60
|
+
Returns the list of refractive indices for the structures.
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
list
|
|
65
|
+
A list containing the refractive index of the background.
|
|
66
|
+
"""
|
|
67
|
+
return [self.index]
|
|
68
|
+
|
|
69
|
+
def overlay_structures_on_mesh(self, mesh: np.ndarray, coordinate_system: CoordinateSystem) -> np.ndarray:
|
|
70
|
+
"""
|
|
71
|
+
Overlays all structures onto the given mesh using the specified coordinate system.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
mesh : np.ndarray
|
|
76
|
+
The mesh to overlay structures onto.
|
|
77
|
+
coordinate_system : CoordinateSystem
|
|
78
|
+
The coordinate system used for overlaying.
|
|
79
|
+
|
|
80
|
+
Returns
|
|
81
|
+
-------
|
|
82
|
+
np.ndarray
|
|
83
|
+
A numpy ndarray with the structures overlayed onto the original mesh.
|
|
84
|
+
"""
|
|
85
|
+
return self._overlay_structure_on_mesh_(
|
|
86
|
+
structure_list=self.structure_list,
|
|
87
|
+
mesh=mesh,
|
|
88
|
+
coordinate_system=coordinate_system
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def rotate(self, *args, **kwargs) -> None:
|
|
92
|
+
pass
|
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
from typing import Union, Optional, List, Dict, Tuple
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
import numpy as np
|
|
8
|
+
import logging
|
|
9
|
+
from FiberFusing.coordinate_system import CoordinateSystem
|
|
10
|
+
from FiberFusing.buffer import Circle
|
|
11
|
+
from FiberFusing.fiber_structure import FiberLine, FiberRing
|
|
12
|
+
from FiberFusing.utils import union_geometries
|
|
13
|
+
from FiberFusing.helper import _plot_helper, OverlayStructureBaseClass
|
|
14
|
+
|
|
15
|
+
logging.basicConfig(level=logging.INFO)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class NameSpace:
|
|
19
|
+
"""
|
|
20
|
+
A flexible class that allows the dynamic addition of attributes via keyword arguments.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, **kwargs):
|
|
24
|
+
"""
|
|
25
|
+
Initializes an instance with attributes specified by the keyword arguments.
|
|
26
|
+
|
|
27
|
+
:param kwargs: Arbitrary keyword arguments to set as attributes.
|
|
28
|
+
"""
|
|
29
|
+
for key, value in kwargs.items():
|
|
30
|
+
setattr(self, key, value)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BaseFused(OverlayStructureBaseClass):
|
|
34
|
+
"""
|
|
35
|
+
Base class for managing the fusion of optical fiber structures, allowing customization of fiber properties
|
|
36
|
+
and spatial configuration. This class facilitates the dynamic assembly of fiber optics structures and automates
|
|
37
|
+
the overlay of these structures on a given mesh.
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
fiber_radius : float
|
|
42
|
+
Radius of individual fibers in the structure.
|
|
43
|
+
index : float
|
|
44
|
+
Refractive index of the fibers' cladding.
|
|
45
|
+
tolerance_factor : float, optional
|
|
46
|
+
A tolerance value used in optimization algorithms to balance the area difference between added and removed
|
|
47
|
+
sections during the fusion process. Default is 1e-2.
|
|
48
|
+
fusion_degree : Union[float, str], optional
|
|
49
|
+
Specifies the degree of fusion, ranging from 0 (no fusion) to 1 (full fusion), or 'auto' to automatically
|
|
50
|
+
determine based on geometry. Default is 'auto'.
|
|
51
|
+
scale_down_position : float, optional
|
|
52
|
+
Scaling factor to adjust the overall size of the assembly. Default is 1.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
fiber_radius: float,
|
|
58
|
+
index: float,
|
|
59
|
+
tolerance_factor: Optional[float] = 1e-2,
|
|
60
|
+
fusion_degree: Optional[Union[float, str]] = 'auto',
|
|
61
|
+
scale_down_position: Optional[float] = 1):
|
|
62
|
+
"""
|
|
63
|
+
Initialize the fiber and core lists and other structures immediately after the dataclass fields
|
|
64
|
+
have been populated.
|
|
65
|
+
"""
|
|
66
|
+
self.fiber_radius = fiber_radius
|
|
67
|
+
self.index = index
|
|
68
|
+
self.tolerance_factor = tolerance_factor
|
|
69
|
+
|
|
70
|
+
self.scale_down_position = scale_down_position
|
|
71
|
+
self.fusion_degree = fusion_degree
|
|
72
|
+
|
|
73
|
+
self._compute_structure()
|
|
74
|
+
|
|
75
|
+
def _compute_structure(self) -> None:
|
|
76
|
+
self.fiber_list = []
|
|
77
|
+
self.core_list = []
|
|
78
|
+
self._clad_structure = None
|
|
79
|
+
self.structure_list = []
|
|
80
|
+
self.removed_section_list = []
|
|
81
|
+
self.added_section_list = []
|
|
82
|
+
|
|
83
|
+
self.initialize_structure()
|
|
84
|
+
|
|
85
|
+
def randomize_core_position(self, random_factor: float = 0) -> "BaseFused":
|
|
86
|
+
"""
|
|
87
|
+
Randomize the position of fiber cores to simulate real-world imperfections.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
random_factor : float, optional
|
|
92
|
+
Factor determining the randomness in position. Default is 0.
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
BaseFused
|
|
97
|
+
The updated BaseFused instance.
|
|
98
|
+
"""
|
|
99
|
+
if random_factor == 0:
|
|
100
|
+
return self
|
|
101
|
+
|
|
102
|
+
logging.info("Randomizing core positions.")
|
|
103
|
+
for fiber in self.fiber_list:
|
|
104
|
+
fiber.shifted_core = fiber.core
|
|
105
|
+
random_shift = np.random.rand(2) * random_factor
|
|
106
|
+
fiber.shifted_core.translate(random_shift, in_place=True)
|
|
107
|
+
|
|
108
|
+
return self
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def fusion_degree(self) -> float:
|
|
112
|
+
return self._fusion_degree
|
|
113
|
+
|
|
114
|
+
@fusion_degree.setter
|
|
115
|
+
def fusion_degree(self, value: float | str) -> None:
|
|
116
|
+
if isinstance(value, str) and value.lower() == 'auto':
|
|
117
|
+
if self.fusion_range is not None:
|
|
118
|
+
value = 0.8
|
|
119
|
+
self._fusion_degree = value
|
|
120
|
+
self.parametrized_fusion_degree = self.fusion_range[0] * (1 - value) + value * self.fusion_range[-1]
|
|
121
|
+
else:
|
|
122
|
+
self._fusion_degree = self.parametrized_fusion_degree = None
|
|
123
|
+
|
|
124
|
+
elif np.isscalar(value):
|
|
125
|
+
assert 0 <= value <= 1, f"Fusion degree [{value}] must be within the range [0, 1]."
|
|
126
|
+
self._fusion_degree = value
|
|
127
|
+
self.parametrized_fusion_degree = self.fusion_range[0] * (1 - value) + value * self.fusion_range[-1]
|
|
128
|
+
|
|
129
|
+
else:
|
|
130
|
+
f"Input for fusion_degree [{value}] is invalid."
|
|
131
|
+
|
|
132
|
+
self._compute_structure()
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def clad_structure(self):
|
|
136
|
+
"""
|
|
137
|
+
Get the clad structure, computing it if necessary.
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
-------
|
|
141
|
+
Polygon
|
|
142
|
+
The union of all structures in the assembly.
|
|
143
|
+
"""
|
|
144
|
+
if self._clad_structure is None:
|
|
145
|
+
self._clad_structure = union_geometries(*self.structure_list)
|
|
146
|
+
return self._clad_structure
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def structure_dictionary(self) -> Dict[str, Dict[str, object]]:
|
|
150
|
+
"""
|
|
151
|
+
Get a dictionary representation of the structure.
|
|
152
|
+
|
|
153
|
+
Returns
|
|
154
|
+
-------
|
|
155
|
+
dict
|
|
156
|
+
A dictionary with the structure's name, index, and polygon.
|
|
157
|
+
"""
|
|
158
|
+
return {'name': {'index': self.index, 'polygon': self.clad_structure}}
|
|
159
|
+
|
|
160
|
+
def overlay_structures_on_mesh(self, mesh: np.ndarray, coordinate_system: CoordinateSystem) -> np.ndarray:
|
|
161
|
+
"""
|
|
162
|
+
Apply the current fiber structure configuration onto a provided mesh.
|
|
163
|
+
|
|
164
|
+
Parameters
|
|
165
|
+
----------
|
|
166
|
+
mesh : np.ndarray
|
|
167
|
+
The mesh on which to overlay the structure.
|
|
168
|
+
coordinate_system : CoordinateSystem
|
|
169
|
+
The coordinate system to use for the overlay.
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
-------
|
|
173
|
+
np.ndarray
|
|
174
|
+
The mesh with fiber structures overlaid.
|
|
175
|
+
"""
|
|
176
|
+
structure_list = [NameSpace(index=self.index, polygon=self.clad_structure)]
|
|
177
|
+
return self._overlay_structure_on_mesh_(
|
|
178
|
+
structure_list=structure_list, mesh=mesh, coordinate_system=coordinate_system
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def get_structure_max_min_boundaries(self) -> Tuple[float, float, float, float]:
|
|
182
|
+
"""
|
|
183
|
+
Get the maximum and minimum boundaries of the clad structure.
|
|
184
|
+
|
|
185
|
+
Returns
|
|
186
|
+
-------
|
|
187
|
+
tuple
|
|
188
|
+
The bounding box of the clad structure.
|
|
189
|
+
"""
|
|
190
|
+
return self.clad_structure.bounds
|
|
191
|
+
|
|
192
|
+
def add_single_fiber(self, fiber_radius: float, position: Tuple[float, float] = (0, 0)) -> "BaseFused":
|
|
193
|
+
"""
|
|
194
|
+
Add a single fiber to the structure at the specified position.
|
|
195
|
+
|
|
196
|
+
Parameters
|
|
197
|
+
----------
|
|
198
|
+
fiber_radius : float
|
|
199
|
+
The radius of the fiber.
|
|
200
|
+
position : tuple, optional
|
|
201
|
+
The x, y coordinates for the fiber. Defaults to (0, 0).
|
|
202
|
+
|
|
203
|
+
Returns
|
|
204
|
+
-------
|
|
205
|
+
BaseFused
|
|
206
|
+
The updated BaseFused instance.
|
|
207
|
+
"""
|
|
208
|
+
fiber = Circle(radius=fiber_radius, position=position)
|
|
209
|
+
fiber.shifted_core = fiber.center
|
|
210
|
+
|
|
211
|
+
self.structure_list.append(fiber)
|
|
212
|
+
self.fiber_list.append(fiber)
|
|
213
|
+
|
|
214
|
+
return self
|
|
215
|
+
|
|
216
|
+
def add_center_fiber(self, fiber_radius: float) -> "BaseFused":
|
|
217
|
+
"""
|
|
218
|
+
Add a single fiber at the center of the structure.
|
|
219
|
+
|
|
220
|
+
Parameters
|
|
221
|
+
----------
|
|
222
|
+
fiber_radius : float
|
|
223
|
+
The radius of the fiber.
|
|
224
|
+
|
|
225
|
+
Returns
|
|
226
|
+
-------
|
|
227
|
+
BaseFused
|
|
228
|
+
The updated BaseFused instance.
|
|
229
|
+
"""
|
|
230
|
+
return self.add_single_fiber(fiber_radius=fiber_radius, position=(0, 0))
|
|
231
|
+
|
|
232
|
+
def add_center_structure(self, fiber_radius: float) -> "BaseFused":
|
|
233
|
+
"""
|
|
234
|
+
Add a single structure of a given radius at the center of the structure.
|
|
235
|
+
|
|
236
|
+
Parameters
|
|
237
|
+
----------
|
|
238
|
+
fiber_radius : float
|
|
239
|
+
The fiber radius.
|
|
240
|
+
|
|
241
|
+
Returns
|
|
242
|
+
-------
|
|
243
|
+
BaseFused
|
|
244
|
+
The updated BaseFused instance.
|
|
245
|
+
"""
|
|
246
|
+
return self.add_single_fiber(fiber_radius=fiber_radius, position=(0, 0))
|
|
247
|
+
|
|
248
|
+
def _add_structure_to_instance_(
|
|
249
|
+
self,
|
|
250
|
+
structure: Union[FiberRing, FiberLine],
|
|
251
|
+
fusion_degree: float = 0.0,
|
|
252
|
+
scale_position: float = 1.0,
|
|
253
|
+
position_shift: List[float] = [0, 0],
|
|
254
|
+
compute_fusing: bool = False
|
|
255
|
+
) -> "BaseFused":
|
|
256
|
+
"""
|
|
257
|
+
Internal method to add a fiber structure to the instance.
|
|
258
|
+
|
|
259
|
+
Parameters
|
|
260
|
+
----------
|
|
261
|
+
structure : Union[FiberRing, FiberLine]
|
|
262
|
+
The fiber structure to add.
|
|
263
|
+
fusion_degree : float, optional
|
|
264
|
+
The degree of fusion. Default is 0.0.
|
|
265
|
+
scale_position : float, optional
|
|
266
|
+
Factor to scale the position. Default is 1.0.
|
|
267
|
+
position_shift : list of float, optional
|
|
268
|
+
Shift vector for the position. Default is [0, 0].
|
|
269
|
+
compute_fusing : bool, optional
|
|
270
|
+
Whether to compute the fusing operation. Default is False.
|
|
271
|
+
|
|
272
|
+
Returns
|
|
273
|
+
-------
|
|
274
|
+
BaseFused
|
|
275
|
+
The updated BaseFused instance.
|
|
276
|
+
"""
|
|
277
|
+
if compute_fusing:
|
|
278
|
+
structure.set_fusion_degree(fusion_degree=fusion_degree)
|
|
279
|
+
|
|
280
|
+
structure.scale_position(factor=scale_position)
|
|
281
|
+
structure.shift_position(shift=position_shift)
|
|
282
|
+
structure.initialize_cores()
|
|
283
|
+
|
|
284
|
+
self.fiber_list.extend(structure.fiber_list)
|
|
285
|
+
|
|
286
|
+
if compute_fusing:
|
|
287
|
+
structure.init_connected_fibers()
|
|
288
|
+
structure.compute_optimal_structure()
|
|
289
|
+
self.removed_section_list.append(structure.removed_section)
|
|
290
|
+
self.added_section_list.append(structure.added_section)
|
|
291
|
+
self.structure_list.append(structure.fused_structure)
|
|
292
|
+
else:
|
|
293
|
+
self.structure_list.append(structure.unfused_structure)
|
|
294
|
+
|
|
295
|
+
return self
|
|
296
|
+
|
|
297
|
+
def add_structure(
|
|
298
|
+
self,
|
|
299
|
+
structure_type: str,
|
|
300
|
+
number_of_fibers: int,
|
|
301
|
+
fiber_radius: float,
|
|
302
|
+
fusion_degree: float = 0.0,
|
|
303
|
+
scale_position: float = 1.0,
|
|
304
|
+
position_shift: List[float] = [0, 0],
|
|
305
|
+
compute_fusing: bool = False,
|
|
306
|
+
angle_shift: float = 0.0
|
|
307
|
+
) -> "BaseFused":
|
|
308
|
+
"""
|
|
309
|
+
Add a predefined structure of fibers, such as a ring or line, with customizable properties and spatial configuration.
|
|
310
|
+
|
|
311
|
+
Parameters
|
|
312
|
+
----------
|
|
313
|
+
structure_type : str
|
|
314
|
+
The type of structure to add ('ring' or 'line').
|
|
315
|
+
number_of_fibers : int
|
|
316
|
+
Number of fibers in the structure.
|
|
317
|
+
fiber_radius : float
|
|
318
|
+
Radius of each fiber in the structure.
|
|
319
|
+
fusion_degree : float, optional
|
|
320
|
+
The degree of fusion for this structure. Default is 0.0.
|
|
321
|
+
scale_position : float, optional
|
|
322
|
+
Factor to scale the position of each fiber. Default is 1.0.
|
|
323
|
+
position_shift : list of float, optional
|
|
324
|
+
A 2D vector [x, y] to shift the entire structure. Default is [0, 0].
|
|
325
|
+
compute_fusing : bool, optional
|
|
326
|
+
Whether to compute the fusing operation for the structure. Default is False.
|
|
327
|
+
angle_shift : float, optional
|
|
328
|
+
The angle by which to rotate the structure. Default is 0.0.
|
|
329
|
+
|
|
330
|
+
Returns
|
|
331
|
+
-------
|
|
332
|
+
BaseFused
|
|
333
|
+
The updated BaseFused instance.
|
|
334
|
+
"""
|
|
335
|
+
|
|
336
|
+
if structure_type.lower() == 'ring':
|
|
337
|
+
structure = FiberRing(
|
|
338
|
+
number_of_fibers=number_of_fibers,
|
|
339
|
+
fiber_radius=fiber_radius,
|
|
340
|
+
angle_shift=angle_shift
|
|
341
|
+
)
|
|
342
|
+
else:
|
|
343
|
+
structure = FiberLine(
|
|
344
|
+
number_of_fibers=number_of_fibers,
|
|
345
|
+
fiber_radius=fiber_radius,
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
return self._add_structure_to_instance_(
|
|
349
|
+
structure=structure,
|
|
350
|
+
fusion_degree=fusion_degree,
|
|
351
|
+
scale_position=scale_position,
|
|
352
|
+
position_shift=position_shift,
|
|
353
|
+
compute_fusing=compute_fusing
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
def add_custom_fiber(self, *fibers) -> None:
|
|
357
|
+
"""
|
|
358
|
+
Add custom-defined fibers to the structure.
|
|
359
|
+
|
|
360
|
+
Parameters
|
|
361
|
+
----------
|
|
362
|
+
fibers : variable
|
|
363
|
+
Custom fiber objects to be added.
|
|
364
|
+
"""
|
|
365
|
+
self.fiber_list.extend(fibers)
|
|
366
|
+
|
|
367
|
+
@property
|
|
368
|
+
def cores(self) -> List:
|
|
369
|
+
return [fiber.shifted_core for fiber in self.fiber_list]
|
|
370
|
+
|
|
371
|
+
def get_core_positions(self) -> List[Tuple[float, float]]:
|
|
372
|
+
"""
|
|
373
|
+
Get a list of core positions for all fibers in the structure.
|
|
374
|
+
|
|
375
|
+
Returns
|
|
376
|
+
-------
|
|
377
|
+
list of tuple
|
|
378
|
+
A list of core positions.
|
|
379
|
+
"""
|
|
380
|
+
return [fiber.core for fiber in self.fiber_list]
|
|
381
|
+
|
|
382
|
+
def get_rasterized_mesh(self, coordinate_system: CoordinateSystem) -> np.ndarray:
|
|
383
|
+
"""
|
|
384
|
+
Generate a rasterized mesh of the structure.
|
|
385
|
+
|
|
386
|
+
Parameters
|
|
387
|
+
----------
|
|
388
|
+
coordinate_system : CoordinateSystem
|
|
389
|
+
The coordinate system to use.
|
|
390
|
+
|
|
391
|
+
Returns
|
|
392
|
+
-------
|
|
393
|
+
numpy.ndarray
|
|
394
|
+
The rasterized mesh.
|
|
395
|
+
"""
|
|
396
|
+
return self.clad_structure.get_rasterized_mesh(coordinate_system=coordinate_system)
|
|
397
|
+
|
|
398
|
+
def rotate(self, angle: float) -> "BaseFused":
|
|
399
|
+
"""
|
|
400
|
+
Rotate the entire structure, including fiber cores.
|
|
401
|
+
|
|
402
|
+
Returns
|
|
403
|
+
-------
|
|
404
|
+
BaseFused
|
|
405
|
+
The updated BaseFused instance.
|
|
406
|
+
"""
|
|
407
|
+
for fiber in self.fiber_list:
|
|
408
|
+
fiber.rotate(angle, in_place=True)
|
|
409
|
+
fiber.core.rotate(angle, in_place=True)
|
|
410
|
+
fiber.shifted_core.rotate(angle, in_place=True)
|
|
411
|
+
fiber.center.rotate(angle, in_place=True)
|
|
412
|
+
|
|
413
|
+
self.clad_structure.rotate(angle, in_place=True)
|
|
414
|
+
|
|
415
|
+
for element in self.removed_section_list:
|
|
416
|
+
element.rotate(angle, in_place=True)
|
|
417
|
+
|
|
418
|
+
for element in self.added_section_list:
|
|
419
|
+
element.rotate(angle, in_place=True)
|
|
420
|
+
|
|
421
|
+
return self
|
|
422
|
+
|
|
423
|
+
def translate(self, shift: Tuple[float, float]) -> "BaseFused":
|
|
424
|
+
"""
|
|
425
|
+
Translate the entire structure, including fiber cores.
|
|
426
|
+
|
|
427
|
+
Returns
|
|
428
|
+
-------
|
|
429
|
+
BaseFused
|
|
430
|
+
The updated BaseFused instance.
|
|
431
|
+
"""
|
|
432
|
+
for fiber in self.fiber_list:
|
|
433
|
+
fiber.translate(shift, in_place=True)
|
|
434
|
+
fiber.core.translate(shift, in_place=True)
|
|
435
|
+
fiber.shifted_core.translate(shift, in_place=True)
|
|
436
|
+
fiber.center.translate(shift, in_place=True)
|
|
437
|
+
|
|
438
|
+
self.clad_structure.translate(shift, in_place=True)
|
|
439
|
+
|
|
440
|
+
for element in self.removed_section_list:
|
|
441
|
+
element.translate(shift, in_place=True)
|
|
442
|
+
|
|
443
|
+
for element in self.added_section_list:
|
|
444
|
+
element.translate(shift, in_place=True)
|
|
445
|
+
|
|
446
|
+
return self
|
|
447
|
+
|
|
448
|
+
def scale_position(self, factor: float) -> "BaseFused":
|
|
449
|
+
"""
|
|
450
|
+
Scale the positions of fibers in the structure.
|
|
451
|
+
|
|
452
|
+
Parameters
|
|
453
|
+
----------
|
|
454
|
+
factor : float
|
|
455
|
+
Scaling factor for the positions.
|
|
456
|
+
|
|
457
|
+
Returns
|
|
458
|
+
-------
|
|
459
|
+
BaseFused
|
|
460
|
+
The updated BaseFused instance.
|
|
461
|
+
"""
|
|
462
|
+
for fiber in self.fiber_list:
|
|
463
|
+
fiber.scale_position(factor=factor)
|
|
464
|
+
|
|
465
|
+
return self
|
|
466
|
+
|
|
467
|
+
@property
|
|
468
|
+
def removed_section(self) -> object:
|
|
469
|
+
return union_geometries(*self.removed_section_list)
|
|
470
|
+
|
|
471
|
+
@property
|
|
472
|
+
def added_section(self) -> object:
|
|
473
|
+
return union_geometries(*self.added_section_list)
|
|
474
|
+
|
|
475
|
+
@_plot_helper
|
|
476
|
+
def plot(
|
|
477
|
+
self,
|
|
478
|
+
ax: plt.Axis = None,
|
|
479
|
+
show_structure: bool = True,
|
|
480
|
+
show_centers: bool = False,
|
|
481
|
+
show_cores: bool = True,
|
|
482
|
+
show_added: bool = True,
|
|
483
|
+
show_removed: bool = True) -> None:
|
|
484
|
+
"""
|
|
485
|
+
Plot the structure using matplotlib.
|
|
486
|
+
|
|
487
|
+
Parameters
|
|
488
|
+
----------
|
|
489
|
+
ax : matplotlib.axes.Axes
|
|
490
|
+
The axis to render on.
|
|
491
|
+
show_structure : bool, optional
|
|
492
|
+
Whether to show the fused structure. Default is True.
|
|
493
|
+
show_centers : bool, optional
|
|
494
|
+
Whether to show the unfused fibers. Default is False.
|
|
495
|
+
show_shifted_cores : bool, optional
|
|
496
|
+
Whether to show the shifted cores. Default is True.
|
|
497
|
+
show_added : bool, optional
|
|
498
|
+
Whether to show added sections. Default is True.
|
|
499
|
+
show_removed : bool, optional
|
|
500
|
+
Whether to show removed sections. Default is True.
|
|
501
|
+
"""
|
|
502
|
+
if show_structure:
|
|
503
|
+
self.clad_structure.plot(ax, show=False)
|
|
504
|
+
|
|
505
|
+
if show_added:
|
|
506
|
+
self.added_section.plot(ax=ax, facecolor='green', show=False)
|
|
507
|
+
|
|
508
|
+
if show_removed:
|
|
509
|
+
self.removed_section.plot(ax=ax, facecolor='red', show=False)
|
|
510
|
+
|
|
511
|
+
if show_cores:
|
|
512
|
+
for idx, fiber in enumerate(self.fiber_list):
|
|
513
|
+
fiber.shifted_core.plot(ax, marker='x', size=40, label=f'Core$_{idx}$', show=False)
|
|
514
|
+
|
|
515
|
+
if show_centers:
|
|
516
|
+
for idx, fiber in enumerate(self.fiber_list):
|
|
517
|
+
fiber.center.plot(ax, marker='o', size=40, label=f'Center$_{idx}$', show=False)
|
|
518
|
+
|
|
519
|
+
for fiber in self.fiber_list:
|
|
520
|
+
fiber.plot(ax, show=False)
|