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.

Files changed (68) hide show
  1. FiberFusing/__init__.py +15 -0
  2. FiberFusing/_version.py +16 -0
  3. FiberFusing/background.py +92 -0
  4. FiberFusing/base_fused.py +520 -0
  5. FiberFusing/buffer.py +163 -0
  6. FiberFusing/components/__init__.py +0 -0
  7. FiberFusing/components/base_class.py +442 -0
  8. FiberFusing/components/linestring.py +106 -0
  9. FiberFusing/components/point.py +91 -0
  10. FiberFusing/components/polygon.py +228 -0
  11. FiberFusing/components/utils.py +59 -0
  12. FiberFusing/configuration/__init__.py +7 -0
  13. FiberFusing/configuration/line/__init__.py +10 -0
  14. FiberFusing/configuration/line/configuration_01x01.py +14 -0
  15. FiberFusing/configuration/line/configuration_02x02.py +18 -0
  16. FiberFusing/configuration/line/configuration_03x03.py +18 -0
  17. FiberFusing/configuration/line/configuration_04x04.py +18 -0
  18. FiberFusing/configuration/line/configuration_05x05.py +18 -0
  19. FiberFusing/configuration/ring/__init__.py +15 -0
  20. FiberFusing/configuration/ring/configuration_01x01.py +14 -0
  21. FiberFusing/configuration/ring/configuration_02x02.py +18 -0
  22. FiberFusing/configuration/ring/configuration_03x03.py +18 -0
  23. FiberFusing/configuration/ring/configuration_04x04.py +18 -0
  24. FiberFusing/configuration/ring/configuration_05x05.py +18 -0
  25. FiberFusing/configuration/ring/configuration_06x06.py +18 -0
  26. FiberFusing/configuration/ring/configuration_07x07.py +20 -0
  27. FiberFusing/configuration/ring/configuration_10x10.py +31 -0
  28. FiberFusing/configuration/ring/configuration_12x12.py +30 -0
  29. FiberFusing/configuration/ring/configuration_19x19.py +34 -0
  30. FiberFusing/connection.py +366 -0
  31. FiberFusing/connection_optimization.py +246 -0
  32. FiberFusing/coordinate_system.py +256 -0
  33. FiberFusing/directories.py +34 -0
  34. FiberFusing/fiber/__init__.py +0 -0
  35. FiberFusing/fiber/catalogue.py +165 -0
  36. FiberFusing/fiber/fiber_files/1550BHP.yaml +14 -0
  37. FiberFusing/fiber/fiber_files/DCF13.yaml +18 -0
  38. FiberFusing/fiber/fiber_files/DCF1300S_20.yaml +17 -0
  39. FiberFusing/fiber/fiber_files/DCF1300S_26.yaml +18 -0
  40. FiberFusing/fiber/fiber_files/DCF1300S_33.yaml +17 -0
  41. FiberFusing/fiber/fiber_files/DCF1300S_42.yaml +18 -0
  42. FiberFusing/fiber/fiber_files/F2028M12.yaml +18 -0
  43. FiberFusing/fiber/fiber_files/F2028M21.yaml +18 -0
  44. FiberFusing/fiber/fiber_files/F2028M24.yaml +18 -0
  45. FiberFusing/fiber/fiber_files/F2058G1.yaml +18 -0
  46. FiberFusing/fiber/fiber_files/F2058L1.yaml +18 -0
  47. FiberFusing/fiber/fiber_files/HI1060.yaml +14 -0
  48. FiberFusing/fiber/fiber_files/HP630.yaml +13 -0
  49. FiberFusing/fiber/fiber_files/SM1950.yaml +14 -0
  50. FiberFusing/fiber/fiber_files/SMF28.yaml +14 -0
  51. FiberFusing/fiber/fiber_files/fluorine_doped_1%_capillary.yaml +9 -0
  52. FiberFusing/fiber/fiber_files/fluorine_doped_2%_capillary.yaml +9 -0
  53. FiberFusing/fiber/fiber_files/test_fiber.yaml +14 -0
  54. FiberFusing/fiber/fiber_files/test_multimode_fiber.yaml +14 -0
  55. FiberFusing/fiber/generic_fiber.py +413 -0
  56. FiberFusing/fiber/loader.py +120 -0
  57. FiberFusing/fiber/structure_collection.py +173 -0
  58. FiberFusing/fiber_structure.py +210 -0
  59. FiberFusing/geometry.py +458 -0
  60. FiberFusing/helper.py +59 -0
  61. FiberFusing/optical_structure.py +96 -0
  62. FiberFusing/plottings.py +43 -0
  63. FiberFusing/utils.py +108 -0
  64. FiberFusing-1.5.0.0.post0.dist-info/LICENSE +21 -0
  65. FiberFusing-1.5.0.0.post0.dist-info/METADATA +193 -0
  66. FiberFusing-1.5.0.0.post0.dist-info/RECORD +68 -0
  67. FiberFusing-1.5.0.0.post0.dist-info/WHEEL +5 -0
  68. FiberFusing-1.5.0.0.post0.dist-info/top_level.txt +1 -0
@@ -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"
@@ -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)