emerge 0.5.1__py3-none-any.whl → 0.5.2__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 emerge might be problematic. Click here for more details.

Files changed (47) hide show
  1. emerge/_emerge/bc.py +11 -8
  2. emerge/_emerge/cs.py +2 -2
  3. emerge/_emerge/elements/femdata.py +14 -14
  4. emerge/_emerge/elements/index_interp.py +1 -1
  5. emerge/_emerge/elements/ned2_interp.py +1 -1
  6. emerge/_emerge/elements/nedelec2.py +4 -4
  7. emerge/_emerge/elements/nedleg2.py +9 -9
  8. emerge/_emerge/geo/horn.py +1 -1
  9. emerge/_emerge/geo/modeler.py +18 -19
  10. emerge/_emerge/geo/operations.py +13 -10
  11. emerge/_emerge/geo/pcb.py +70 -69
  12. emerge/_emerge/geo/pcb_tools/macro.py +14 -13
  13. emerge/_emerge/geo/pmlbox.py +1 -1
  14. emerge/_emerge/geometry.py +46 -32
  15. emerge/_emerge/logsettings.py +3 -3
  16. emerge/_emerge/material.py +11 -11
  17. emerge/_emerge/mesh3d.py +81 -59
  18. emerge/_emerge/mesher.py +26 -21
  19. emerge/_emerge/mth/pairing.py +2 -2
  20. emerge/_emerge/periodic.py +34 -31
  21. emerge/_emerge/physics/microwave/adaptive_freq.py +14 -11
  22. emerge/_emerge/physics/microwave/assembly/assembler.py +61 -57
  23. emerge/_emerge/physics/microwave/assembly/generalized_eigen.py +43 -8
  24. emerge/_emerge/physics/microwave/assembly/robinbc.py +5 -5
  25. emerge/_emerge/physics/microwave/microwave_3d.py +40 -20
  26. emerge/_emerge/physics/microwave/microwave_bc.py +114 -95
  27. emerge/_emerge/physics/microwave/microwave_data.py +33 -33
  28. emerge/_emerge/physics/microwave/simjob.py +12 -12
  29. emerge/_emerge/physics/microwave/sparam.py +12 -12
  30. emerge/_emerge/physics/microwave/touchstone.py +1 -1
  31. emerge/_emerge/plot/display.py +12 -6
  32. emerge/_emerge/plot/pyvista/display.py +44 -39
  33. emerge/_emerge/plot/pyvista/display_settings.py +1 -1
  34. emerge/_emerge/plot/simple_plots.py +15 -15
  35. emerge/_emerge/selection.py +35 -39
  36. emerge/_emerge/simmodel.py +29 -39
  37. emerge/_emerge/simulation_data.py +19 -14
  38. emerge/_emerge/solve_interfaces/pardiso_interface.py +24 -18
  39. emerge/_emerge/solver.py +52 -52
  40. emerge/lib.py +243 -243
  41. {emerge-0.5.1.dist-info → emerge-0.5.2.dist-info}/METADATA +1 -1
  42. emerge-0.5.2.dist-info/RECORD +81 -0
  43. emerge/_emerge/plot/grapher.py +0 -93
  44. emerge-0.5.1.dist-info/RECORD +0 -82
  45. {emerge-0.5.1.dist-info → emerge-0.5.2.dist-info}/WHEEL +0 -0
  46. {emerge-0.5.1.dist-info → emerge-0.5.2.dist-info}/entry_points.txt +0 -0
  47. {emerge-0.5.1.dist-info → emerge-0.5.2.dist-info}/licenses/LICENSE +0 -0
@@ -17,39 +17,39 @@
17
17
 
18
18
  import numpy as np
19
19
  import os
20
- from scipy.sparse import csr_matrix, save_npz, load_npz
20
+ from scipy.sparse import csr_matrix, save_npz, load_npz # type: ignore
21
21
  from ...solver import SolveReport
22
22
 
23
23
  class SimJob:
24
24
 
25
25
  def __init__(self,
26
26
  A: csr_matrix,
27
- b: np.ndarray,
27
+ b: np.ndarray | None,
28
28
  freq: float,
29
29
  cache_factorization: bool,
30
30
  B: csr_matrix = None
31
31
  ):
32
32
 
33
33
  self.A: csr_matrix = A
34
- self.B: csr_matrix = B
35
- self.b: np.ndarray = b
36
- self.P: csr_matrix = None
37
- self.Pd: csr_matrix = None
34
+ self.B: csr_matrix | None = B
35
+ self.b: np.ndarray | None = b
36
+ self.P: csr_matrix | None= None
37
+ self.Pd: csr_matrix | None = None
38
38
  self.has_periodic: bool = False
39
39
 
40
40
  self.freq: float = freq
41
41
  self.k0: float = 2*np.pi*freq/299792458
42
42
  self.cache_factorization: bool = cache_factorization
43
43
  self._fields: dict[int, np.ndarray] = dict()
44
- self.port_vectors: dict = None
45
- self.solve_ids = None
44
+ self.port_vectors: dict | None = None
45
+ self.solve_ids: np.ndarray | None = None
46
46
 
47
- self.store_limit = None
48
- self.relative_path = None
49
- self._store_location = {}
47
+ self.store_limit: int | None = None
48
+ self.relative_path: str | None = None
49
+ self._store_location: dict = {}
50
50
  self._stored: bool = False
51
51
 
52
- self._active_port: int = None
52
+ self._active_port: int = -1
53
53
  self.reports: list[SolveReport] = []
54
54
  self.id: int = -1
55
55
  self.store_if_needed()
@@ -15,14 +15,14 @@
15
15
  # along with this program; if not, see
16
16
  # <https://www.gnu.org/licenses/>.
17
17
 
18
- from .microwave_bc import RobinBC
18
+ from .microwave_bc import PortBC
19
19
  from ...mth.integrals import surface_integral
20
20
  import numpy as np
21
21
  from typing import Callable
22
22
 
23
23
  def sparam_waveport(nodes: np.ndarray,
24
24
  tri_vertices: np.ndarray,
25
- bc: RobinBC,
25
+ bc: PortBC,
26
26
  freq: float,
27
27
  fieldf: Callable,
28
28
  ndpts: int = 4):
@@ -62,18 +62,18 @@ def sparam_waveport(nodes: np.ndarray,
62
62
  Ex2, Ey2, Ez2 = modef_c(x,y,z)
63
63
  return Ex1*Ex2 + Ey1*Ey2 + Ez1*Ez2
64
64
 
65
- mode_dot_field = surface_integral(nodes, tri_vertices, inproduct1, ndpts=ndpts)
66
- norm = surface_integral(nodes, tri_vertices, inproduct2, ndpts=ndpts)
65
+ mode_dot_field = surface_integral(nodes, tri_vertices, inproduct1, gq_order=ndpts)
66
+ norm = surface_integral(nodes, tri_vertices, inproduct2, gq_order=ndpts)
67
67
 
68
68
  svec = mode_dot_field/norm
69
69
  return svec
70
70
 
71
71
  def sparam_mode_power(nodes: np.ndarray,
72
72
  tri_vertices: np.ndarray,
73
- bc: RobinBC,
73
+ bc: PortBC,
74
74
  k0: float,
75
75
  const: np.ndarray,
76
- ndpts: int = 4):
76
+ gq_order: int = 4):
77
77
  ''' Compute the S-parameters assuming a wave port mode
78
78
 
79
79
  Arguments:
@@ -83,7 +83,7 @@ def sparam_mode_power(nodes: np.ndarray,
83
83
  bc: RobinBC = The port boundary condition object
84
84
  freq: float = The frequency at which to do the calculation
85
85
  fielf: Callable = The interpolation fuction that computes the E-field from the simulation
86
- ndpts: int = 4 the number of Duvanant integration points to use (default = 4)
86
+ gq_order: int = 4 the Gauss-Quadrature order (default = 4)
87
87
  '''
88
88
 
89
89
  def modef(x, y, z):
@@ -94,17 +94,17 @@ def sparam_mode_power(nodes: np.ndarray,
94
94
  Ex2, Ey2, Ez2 = np.conj(modef(x,y,z))
95
95
  return (Ex1*Ex2 + Ey1*Ey2 + Ez1*Ez2)/(2*bc.Zmode(k0))
96
96
 
97
- norm = surface_integral(nodes, tri_vertices, inproduct2, const, gq_order=ndpts)
97
+ norm = surface_integral(nodes, tri_vertices, inproduct2, const, gq_order=gq_order)
98
98
 
99
99
  return norm
100
100
 
101
101
  def sparam_field_power(nodes: np.ndarray,
102
102
  tri_vertices: np.ndarray,
103
- bc: RobinBC,
103
+ bc: PortBC,
104
104
  k0: float,
105
105
  fieldf: Callable,
106
106
  const: np.ndarray,
107
- ndpts: int = 4):
107
+ gq_order: int = 4) -> complex:
108
108
  ''' Compute the S-parameters assuming a wave port mode
109
109
 
110
110
  Arguments:
@@ -114,7 +114,7 @@ def sparam_field_power(nodes: np.ndarray,
114
114
  bc: RobinBC = The port boundary condition object
115
115
  freq: float = The frequency at which to do the calculation
116
116
  fielf: Callable = The interpolation fuction that computes the E-field from the simulation
117
- ndpts: int = 4 the number of Duvanant integration points to use (default = 4)
117
+ gq_order: int = 4 the Gauss-Quadrature order (default = 4)
118
118
  '''
119
119
 
120
120
  def modef(x, y, z):
@@ -132,7 +132,7 @@ def sparam_field_power(nodes: np.ndarray,
132
132
  Ex2, Ey2, Ez2 = np.conj(modef(x,y,z))
133
133
  return (Ex1*Ex2 + Ey1*Ey2 + Ez1*Ez2) / (2*bc.Zmode(k0))
134
134
 
135
- mode_dot_field = surface_integral(nodes, tri_vertices, inproduct1, const, gq_order=ndpts)
135
+ mode_dot_field = surface_integral(nodes, tri_vertices, inproduct1, const, gq_order=gq_order)
136
136
 
137
137
  svec = mode_dot_field
138
138
  return svec
@@ -31,7 +31,7 @@ def generate_touchstone(filename: str,
31
31
  freq: np.ndarray,
32
32
  Smat: np.ndarray,
33
33
  data_format: Literal['RI','MA','DB'],
34
- custom_comments: list[str] = None,
34
+ custom_comments: list[str] | None = None,
35
35
  funit: Literal['HZ','KHZ','MHZ','GHZ'] = 'GHZ') -> None:
36
36
  """
37
37
  Export S-parameter data to a Touchstone file
@@ -18,7 +18,7 @@ class BaseDisplay:
18
18
  def show(self):
19
19
  raise NotImplementedError('This method is not implemented')
20
20
 
21
- def add_object(self, obj: GeoObject | Selection | Iterable,*args, **kwargs):
21
+ def add_object(self, obj: GeoObject | Selection,*args, **kwargs):
22
22
  """ Adds an object to the display
23
23
 
24
24
  Keyword arguments
@@ -352,14 +352,20 @@ class BaseDisplay:
352
352
  def add_scatter(self, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray):
353
353
  raise NotImplementedError('This method is not implemented')
354
354
 
355
- def add_portmode(self, port: PortBC, k0: float, Npoints: int = 10, dv=(0,0,0), XYZ=None,
356
- field: Literal['E','H'] = 'E'):
355
+ def add_portmode(self, port: PortBC,
356
+ Npoints: int = 10,
357
+ dv=(0,0,0),
358
+ XYZ=None,
359
+ field: Literal['E','H'] = 'E',
360
+ k0: float | None = None,
361
+ mode_number: int | None = None):
357
362
  raise NotImplementedError('This method is not implemented')
358
363
 
359
364
  def add_quiver(self, x: np.ndarray, y: np.ndarray, z: np.ndarray,
360
365
  dx: np.ndarray, dy: np.ndarray, dz: np.ndarray,
361
366
  scale: float = 1,
362
- scalemode: Literal['lin','log'] = 'lin'):
367
+ color: tuple[float, float, float] | None = None,
368
+ scalemode: Literal['lin','log'] = 'lin') -> None:
363
369
 
364
370
  raise NotImplementedError('This method is not implemented')
365
371
 
@@ -370,10 +376,10 @@ class BaseDisplay:
370
376
  field: np.ndarray,
371
377
  scale: Literal['lin','log','symlog'] = 'lin',
372
378
  cmap: cmap_names = 'coolwarm',
373
- clim: tuple[float, float] = None,
379
+ clim: tuple[float, float] | None = None,
374
380
  opacity: float = 1.0,
375
381
  symmetrize: bool = True,
376
- animate: bool = False,
382
+ _fieldname: str | None = None,
377
383
  **kwargs,):
378
384
  """Add a surface plot to the display
379
385
  The X,Y,Z coordinates must be a 2D grid of data points. The field must be a real field with the same size.
@@ -22,7 +22,7 @@ from ...selection import FaceSelection, DomainSelection, EdgeSelection, Selectio
22
22
  from ...physics.microwave.microwave_bc import PortBC, ModalPort
23
23
  import numpy as np
24
24
  import pyvista as pv
25
- from typing import Iterable, Literal, Callable
25
+ from typing import Iterable, Literal, Callable, Any
26
26
  from ..display import BaseDisplay
27
27
  from .display_settings import PVDisplaySettings
28
28
  from matplotlib.colors import ListedColormap
@@ -155,7 +155,7 @@ def _select(obj: GeoObject | Selection) -> Selection:
155
155
  return obj.select
156
156
  return obj
157
157
 
158
- def _merge(lst: list[GeoObject | Selection]) -> Selection:
158
+ def _merge(lst: Iterable[GeoObject | Selection]) -> Selection:
159
159
  selections = [_select(item) for item in lst]
160
160
  dim = selections[0].dim
161
161
  all_tags = []
@@ -168,6 +168,8 @@ def _merge(lst: list[GeoObject | Selection]) -> Selection:
168
168
  return FaceSelection(all_tags)
169
169
  elif dim==3:
170
170
  return DomainSelection(all_tags)
171
+ else:
172
+ return Selection(all_tags)
171
173
 
172
174
  class _AnimObject:
173
175
  """ A private class containing the required information for plot items in a view
@@ -199,7 +201,7 @@ class PVDisplay(BaseDisplay):
199
201
  self._stop: bool = False
200
202
  self._objs: list[_AnimObject] = []
201
203
  self._do_animate: bool = False
202
- self._Nsteps: int = None
204
+ self._Nsteps: int = 0
203
205
  self._fps: int = 25
204
206
  self._ruler: ScreenRuler = ScreenRuler(self, 0.001)
205
207
  self._selector: ScreenSelector = ScreenSelector(self)
@@ -208,10 +210,11 @@ class PVDisplay(BaseDisplay):
208
210
 
209
211
  self._plot = pv.Plotter()
210
212
 
211
- self._plot.add_key_event("m", self.activate_ruler)
212
- self._plot.add_key_event("f", self.activate_object)
213
+ self._plot.add_key_event("m", self.activate_ruler) # type: ignore
214
+ self._plot.add_key_event("f", self.activate_object) # type: ignore
213
215
 
214
216
  self._ctr: int = 0
217
+
215
218
  def activate_ruler(self):
216
219
  self._plot.disable_picking()
217
220
  self._selector.turn_off()
@@ -310,7 +313,7 @@ class PVDisplay(BaseDisplay):
310
313
  points = self._mesh.nodes.T
311
314
  return pv.UnstructuredGrid(cells, celltypes, points)
312
315
 
313
- def mesh(self, obj: GeoObject | Selection | Iterable) -> pv.UnstructuredGrid:
316
+ def mesh(self, obj: GeoObject | Selection | Iterable) -> pv.UnstructuredGrid | None:
314
317
  if isinstance(obj, Iterable):
315
318
  obj = _merge(obj)
316
319
  else:
@@ -320,11 +323,13 @@ class PVDisplay(BaseDisplay):
320
323
  return self.mesh_volume(obj)
321
324
  elif isinstance(obj, FaceSelection):
322
325
  return self.mesh_surface(obj)
326
+ else:
327
+ return None
323
328
 
324
329
  ## OBLIGATORY METHODS
325
- def add_object(self, obj: GeoObject | Selection | Iterable, *args, **kwargs):
326
- kwargs = setdefault(kwargs, color=obj.color_rgb, opacity=obj.opacity, silhouette=True)
327
- self._plot.add_mesh(self.mesh(obj), pickable=True, *args, **kwargs)
330
+ def add_object(self, obj: GeoObject | Selection, *args, **kwargs):
331
+ kwargs = setdefault(kwargs, color=obj.color_rgb, opacity=obj.opacity, silhouette=True, pickable=True)
332
+ self._plot.add_mesh(self.mesh(obj), *args, **kwargs)
328
333
 
329
334
  def add_scatter(self, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray):
330
335
  """Adds a scatter point cloud
@@ -342,8 +347,8 @@ class PVDisplay(BaseDisplay):
342
347
  dv=(0,0,0),
343
348
  XYZ=None,
344
349
  field: Literal['E','H'] = 'E',
345
- k0: float = None,
346
- mode_number: int = None) -> pv.UnstructuredGrid:
350
+ k0: float | None = None,
351
+ mode_number: int | None = None) -> None:
347
352
 
348
353
  if XYZ:
349
354
  X,Y,Z = XYZ
@@ -408,10 +413,10 @@ class PVDisplay(BaseDisplay):
408
413
  field: np.ndarray,
409
414
  scale: Literal['lin','log','symlog'] = 'lin',
410
415
  cmap: cmap_names = 'coolwarm',
411
- clim: tuple[float, float] = None,
416
+ clim: tuple[float, float] | None = None,
412
417
  opacity: float = 1.0,
413
418
  symmetrize: bool = True,
414
- _fieldname: str = None,
419
+ _fieldname: str | None = None,
415
420
  **kwargs,):
416
421
  """Add a surface plot to the display
417
422
  The X,Y,Z coordinates must be a 2D grid of data points. The field must be a real field with the same size.
@@ -460,11 +465,11 @@ class PVDisplay(BaseDisplay):
460
465
  kwargs = setdefault(kwargs, cmap=cmap, clim=clim, opacity=opacity, pickable=False, multi_colors=True)
461
466
  actor = self._plot.add_mesh(grid, scalars=name, **kwargs)
462
467
 
463
- if self._animate:
468
+ if self._do_animate:
464
469
  def on_update(obj: _AnimObject, phi: complex):
465
470
  field = obj.T(np.real(obj.field*phi))
466
471
  obj.grid['anim'] = field
467
- self._objs.append(_AnimObject(field_flat, T, grid, actor, on_update))
472
+ self._objs.append(_AnimObject(field_flat, T, grid, actor, on_update)) # type: ignore
468
473
 
469
474
 
470
475
  def add_title(self, title: str) -> None:
@@ -481,14 +486,14 @@ class PVDisplay(BaseDisplay):
481
486
  def add_text(self, text: str,
482
487
  color: str = 'black',
483
488
  position: Literal['lower_left', 'lower_right', 'upper_left', 'upper_right', 'lower_edge', 'upper_edge', 'right_edge', 'left_edge']='upper_right',
484
- abs_position: tuple[float, float, float] = None):
489
+ abs_position: tuple[float, float, float] | None = None):
485
490
  viewport = False
486
491
  if abs_position is not None:
487
- position = abs_position
492
+ final_position = abs_position
488
493
  viewport = True
489
494
  self._plot.add_text(
490
495
  text,
491
- position=position,
496
+ position=final_position,
492
497
  color=color,
493
498
  font_size=18,
494
499
  viewport=viewport)
@@ -496,7 +501,7 @@ class PVDisplay(BaseDisplay):
496
501
  def add_quiver(self, x: np.ndarray, y: np.ndarray, z: np.ndarray,
497
502
  dx: np.ndarray, dy: np.ndarray, dz: np.ndarray,
498
503
  scale: float = 1,
499
- color: tuple[float, float, float] = None,
504
+ color: tuple[float, float, float] | None = None,
500
505
  scalemode: Literal['lin','log'] = 'lin'):
501
506
  """Add a quiver plot to the display
502
507
 
@@ -562,18 +567,18 @@ class PVDisplay(BaseDisplay):
562
567
  grid = pv.StructuredGrid(X,Y,Z)
563
568
  field = V.flatten(order='F')
564
569
  grid['anim'] = np.real(field)
565
- levels = np.linspace(vmin, vmax, Nlevels)
570
+ levels = list(np.linspace(vmin, vmax, Nlevels))
566
571
  contour = grid.contour(isosurfaces=levels)
567
572
  actor = self._plot.add_mesh(contour, opacity=0.25, cmap=cmap, pickable=False)
568
573
 
569
- if self._animate:
574
+ if self._do_animate:
570
575
  def on_update(obj: _AnimObject, phi: complex):
571
576
  new_vals = np.real(obj.field * phi)
572
577
  obj.grid['anim'] = new_vals
573
578
  new_contour = obj.grid.contour(isosurfaces=levels)
574
- obj.actor.GetMapper().SetInputData(new_contour)
579
+ obj.actor.GetMapper().SetInputData(new_contour) # type: ignore
575
580
 
576
- self._objs.append(_AnimObject(field, lambda x: x, grid, actor, on_update))
581
+ self._objs.append(_AnimObject(field, lambda x: x, grid, actor, on_update)) # type: ignore
577
582
 
578
583
  def _add_aux_items(self) -> None:
579
584
  saved_camera = {
@@ -591,8 +596,8 @@ class PVDisplay(BaseDisplay):
591
596
  plane = pv.Plane(
592
597
  center=(0, 0, 0),
593
598
  direction=(1, 0, 0), # normal vector pointing along +X
594
- i_size=length,
595
- j_size=length,
599
+ i_size=length, # type: ignore
600
+ j_size=length, # type: ignore
596
601
  i_resolution=1,
597
602
  j_resolution=1
598
603
  )
@@ -617,8 +622,8 @@ class PVDisplay(BaseDisplay):
617
622
  plane = pv.Plane(
618
623
  center=(0, 0, 0),
619
624
  direction=(0, 1, 0), # normal vector pointing along +X
620
- i_size=length,
621
- j_size=length,
625
+ i_size=length, # type: ignore
626
+ j_size=length, # type: ignore
622
627
  i_resolution=1,
623
628
  j_resolution=1
624
629
  )
@@ -642,8 +647,8 @@ class PVDisplay(BaseDisplay):
642
647
  plane = pv.Plane(
643
648
  center=(0, 0, 0),
644
649
  direction=(0, 0, 1), # normal vector pointing along +X
645
- i_size=length,
646
- j_size=length,
650
+ i_size=length, # type: ignore
651
+ j_size=length, # type: ignore
647
652
  i_resolution=1,
648
653
  j_resolution=1
649
654
  )
@@ -776,11 +781,11 @@ class PVDisplay(BaseDisplay):
776
781
 
777
782
  if self.set.add_light:
778
783
  light = pv.Light()
779
- light.set_direction_angle(*self.set.light_angle)
784
+ light.set_direction_angle(*self.set.light_angle) # type: ignore
780
785
  self._plot.add_light(light)
781
786
 
782
- self._plot.set_background(self.set.background_bottom, top=self.set.background_top)
783
- self._plot.add_axes()
787
+ self._plot.set_background(self.set.background_bottom, top=self.set.background_top) # type: ignore
788
+ self._plot.add_axes() # type: ignore
784
789
 
785
790
  self._plot.camera.position = saved_camera["position"]
786
791
  self._plot.camera.focal_point = saved_camera["focal_point"]
@@ -837,7 +842,7 @@ class ScreenSelector:
837
842
  celltypes = np.full(ntris, fill_value=pv.CellType.TRIANGLE, dtype=np.uint8)
838
843
  points = self.disp._mesh.nodes.T
839
844
  grid = pv.UnstructuredGrid(cells, celltypes, points)
840
- grid._tag = key
845
+ grid._tag = key # type: ignore
841
846
  self.grids.append(grid)
842
847
  self.surfs[key] = points[nodes,:].T
843
848
 
@@ -856,14 +861,14 @@ class ScreenSelector:
856
861
  meany = np.mean(ys)
857
862
  meanz = np.mean(zs)
858
863
  data = (meanx, meany, meanz, min(xs), min(ys), min(zs), max(xs), max(ys), max(zs))
859
- encoded = encode_data(data)
864
+ encoded = encode_data(data) #type: ignore
860
865
  print(f'Face code key={key}: ', encoded)
861
866
 
862
867
  self.disp._plot.enable_mesh_picking(callback, style='surface', left_clicking=True, use_actor=True)
863
868
 
864
869
  def turn_off(self) -> None:
865
870
  for actor in self.select_actors:
866
- self.disp._plot.remove_actor(actor)
871
+ self.disp._plot.remove_actor(actor) # type: ignore
867
872
  self.select_actors = []
868
873
  for actor in self.original_actors:
869
874
  if isinstance(actor, pv.Text):
@@ -876,9 +881,9 @@ class ScreenRuler:
876
881
  def __init__(self, display: PVDisplay, min_length: float):
877
882
  self.disp: PVDisplay = display
878
883
  self.points: list[tuple] = [(0,0,0),(0,0,0)]
879
- self.text: pv.Text = None
880
- self.ruler = None
881
- self.state = False
884
+ self.text: pv.Text | None = None
885
+ self.ruler: Any = None
886
+ self.state: bool = False
882
887
  self.min_length: float = min_length
883
888
 
884
889
  @freeze
@@ -916,7 +921,7 @@ class ScreenRuler:
916
921
 
917
922
  def set_ruler(self) -> None:
918
923
  if self.ruler is None:
919
- self.ruler = self.disp._plot.add_ruler(self.points[0], self.points[1], title=f'{1000*self.dist:.2f}mm')
924
+ self.ruler = self.disp._plot.add_ruler(self.points[0], self.points[1], title=f'{1000*self.dist:.2f}mm') # type: ignore
920
925
  else:
921
926
  p1 = self.ruler.GetPositionCoordinate()
922
927
  p2 = self.ruler.GetPosition2Coordinate()
@@ -17,7 +17,7 @@ class PVDisplaySettings:
17
17
  self.show_zgrid: bool = True
18
18
  self.grid_line_width: float = 1.0
19
19
  self.add_light: bool = False
20
- self.light_angle: float = (20, -20)
20
+ self.light_angle: tuple[float, float] = (20., -20.)
21
21
  self.cast_shadows: bool = True
22
22
  self.background_bottom: str = "#c0d2e8"
23
23
  self.background_top: str = "#ffffff"
@@ -36,7 +36,7 @@ ggplot_styles = {
36
36
 
37
37
  plt.rcParams.update(ggplot_styles)
38
38
 
39
- def _gen_grid(xs: tuple, ys: tuple, N = 201) -> list[np.ndarray]:
39
+ def _gen_grid(xs: tuple, ys: tuple, N = 201) -> list[tuple[np.ndarray, np.ndarray]]:
40
40
  """Generate a grid of lines for the Smith Chart
41
41
 
42
42
  Args:
@@ -279,18 +279,18 @@ def smith(f: np.ndarray, S: np.ndarray) -> None:
279
279
  def plot_sp(f: np.ndarray, S: list[np.ndarray] | np.ndarray,
280
280
  dblim=[-40, 5],
281
281
  xunit="GHz",
282
- levelindicator: int | float =None,
282
+ levelindicator: int | float | None = None,
283
283
  noise_floor=-150,
284
- fill_areas: list[tuple]= None,
285
- spec_area: list[tuple[float]] = None,
284
+ fill_areas: list[tuple] | None = None,
285
+ spec_area: list[tuple[float,...]] | None = None,
286
286
  unwrap_phase=False,
287
287
  logx: bool = False,
288
- labels: list[str] = None,
289
- linestyles: list[str] = None,
290
- colorcycle: list[int] = None,
291
- filename: str = None,
288
+ labels: list[str] | None = None,
289
+ linestyles: list[str] | None = None,
290
+ colorcycle: list[int] | None = None,
291
+ filename: str | None = None,
292
292
  show_plot: bool = True,
293
- figdata: tuple = None) -> None:
293
+ figdata: tuple | None = None) -> tuple[plt.Figure, plt.Axes, plt.Axes]:
294
294
  """Plot S-parameters in dB and phase
295
295
 
296
296
  Args:
@@ -321,7 +321,7 @@ def plot_sp(f: np.ndarray, S: list[np.ndarray] | np.ndarray,
321
321
  if colorcycle is None:
322
322
  colorcycle = [i for i, S in enumerate(S)]
323
323
 
324
- unitdivider = {"MHz": 1e6, "GHz": 1e9, "kHz": 1e3}
324
+ unitdivider: dict[str, float] = {"MHz": 1e6, "GHz": 1e9, "kHz": 1e3}
325
325
  fnew = f / unitdivider[xunit]
326
326
 
327
327
  if figdata is None:
@@ -372,14 +372,14 @@ def plot_sp(f: np.ndarray, S: list[np.ndarray] | np.ndarray,
372
372
  # Configure magnitude plot (ax_mag)
373
373
  ax_mag.set_ylabel("Magnitude (dB)")
374
374
  ax_mag.set_xlabel(f"Frequency ({xunit})")
375
- ax_mag.axis([min(fnew), max(fnew), dblim[0], max(maxy*1.1,dblim[1])])
375
+ ax_mag.axis([min(fnew), max(fnew), dblim[0], max(maxy*1.1,dblim[1])]) # type: ignore
376
376
  ax_mag.axhline(y=0, color="k", linewidth=1)
377
377
  ax_mag.xaxis.set_minor_locator(tck.AutoMinorLocator(2))
378
378
  ax_mag.yaxis.set_minor_locator(tck.AutoMinorLocator(2))
379
379
  # Configure phase plot (ax_phase)
380
380
  ax_phase.set_ylabel("Phase (degrees)")
381
381
  ax_phase.set_xlabel(f"Frequency ({xunit})")
382
- ax_phase.axis([min(fnew), max(fnew), minphase, maxphase])
382
+ ax_phase.axis([min(fnew), max(fnew), minphase, maxphase]) # type: ignore
383
383
  ax_phase.xaxis.set_minor_locator(tck.AutoMinorLocator(2))
384
384
  ax_phase.yaxis.set_minor_locator(tck.AutoMinorLocator(2))
385
385
  if logx:
@@ -532,9 +532,9 @@ def plot_ff_polar(
532
532
  markers = _broadcast(markers, None) if markers is not None else [None] * n_series
533
533
 
534
534
  fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
535
- ax.set_theta_zero_location(zero_location)
536
- ax.set_theta_direction(-1 if clockwise else 1)
537
- ax.set_rlabel_position(rlabel_angle)
535
+ ax.set_theta_zero_location(zero_location) # type: ignore
536
+ ax.set_theta_direction(-1 if clockwise else 1) # type: ignore
537
+ ax.set_rlabel_position(rlabel_angle) # type: ignore
538
538
 
539
539
  for i, Ei in enumerate(E_list):
540
540
  mag = np.abs(Ei)