pyedb 0.41.0__py3-none-any.whl → 0.43.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 pyedb might be problematic. Click here for more details.

Files changed (31) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/configuration/cfg_boundaries.py +149 -63
  3. pyedb/configuration/cfg_components.py +333 -97
  4. pyedb/configuration/cfg_general.py +30 -12
  5. pyedb/configuration/cfg_modeler.py +161 -67
  6. pyedb/configuration/cfg_nets.py +33 -17
  7. pyedb/configuration/cfg_operations.py +63 -31
  8. pyedb/configuration/cfg_package_definition.py +72 -51
  9. pyedb/configuration/cfg_pin_groups.py +78 -26
  10. pyedb/configuration/cfg_s_parameter_models.py +95 -70
  11. pyedb/configuration/cfg_setup.py +230 -185
  12. pyedb/configuration/cfg_stackup.py +122 -90
  13. pyedb/configuration/configuration.py +342 -194
  14. pyedb/dotnet/database/cell/terminal/padstack_instance_terminal.py +5 -0
  15. pyedb/dotnet/database/cell/terminal/point_terminal.py +12 -0
  16. pyedb/dotnet/database/cell/terminal/terminal.py +0 -14
  17. pyedb/dotnet/database/dotnet/database.py +2 -0
  18. pyedb/dotnet/database/edb_data/padstacks_data.py +7 -2
  19. pyedb/dotnet/database/sim_setup_data/data/sweep_data.py +63 -10
  20. pyedb/dotnet/database/siwave.py +4 -1
  21. pyedb/dotnet/database/utilities/simulation_setup.py +15 -16
  22. pyedb/dotnet/edb.py +77 -110
  23. pyedb/grpc/database/components.py +1 -2
  24. pyedb/grpc/database/hierarchy/component.py +9 -1
  25. pyedb/grpc/database/hierarchy/s_parameter_model.py +2 -2
  26. pyedb/grpc/database/hierarchy/spice_model.py +4 -0
  27. pyedb/grpc/database/utility/hfss_extent_info.py +31 -20
  28. {pyedb-0.41.0.dist-info → pyedb-0.43.0.dist-info}/METADATA +1 -1
  29. {pyedb-0.41.0.dist-info → pyedb-0.43.0.dist-info}/RECORD +31 -31
  30. {pyedb-0.41.0.dist-info → pyedb-0.43.0.dist-info}/LICENSE +0 -0
  31. {pyedb-0.41.0.dist-info → pyedb-0.43.0.dist-info}/WHEEL +0 -0
@@ -19,7 +19,7 @@
19
19
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
-
22
+ import re
23
23
  import warnings
24
24
 
25
25
 
@@ -524,23 +524,76 @@ class SweepData(object):
524
524
 
525
525
  def add(self, sweep_type, start, stop, increment):
526
526
  sweep_type = sweep_type.replace(" ", "_")
527
- start = start.upper().replace("Z", "z") if isinstance(start, str) else str(start)
528
- stop = stop.upper().replace("Z", "z") if isinstance(stop, str) else str(stop)
529
- increment = increment.upper().replace("Z", "z") if isinstance(increment, str) else int(increment)
530
- if sweep_type in ["linear_count", "linear_scale"]:
531
- freqs = list(self._edb_object.SetFrequencies(start, stop, increment))
532
- elif sweep_type == "log_scale":
533
- freqs = list(self._edb_object.SetLogFrequencies(start, stop, increment))
527
+ start = f"{self._pedb.edb_value(start).ToDouble() / 1e9}GHz"
528
+ stop = f"{self._pedb.edb_value(stop).ToDouble() / 1e9}GHz"
529
+
530
+ if sweep_type == "linear_scale":
531
+ increment = f"{self._pedb.edb_value(increment).ToDouble() / 1e9}GHz"
532
+ frequencty_string = f"LIN {start} {stop} {increment}"
534
533
  else:
535
- raise ValueError("sweep_type must be either 'linear_count', 'linear_scale' or 'log_scale")
536
- return self.add_frequencies(freqs)
534
+ increment = int(increment)
535
+ if sweep_type == "log_scale":
536
+ frequencty_string = f"DEC {start} {stop} {increment}"
537
+ elif sweep_type == "linear_count":
538
+ frequencty_string = f"LINC {start} {stop} {increment}"
539
+ else:
540
+ raise ValueError("sweep_type must be either 'linear_count', 'linear_scale' or 'log_scale")
541
+ temp = self.frequency_string
542
+ temp.append(frequencty_string)
543
+ self.frequency_string = temp
544
+ return self.frequencies
545
+
546
+ @property
547
+ def frequency_string(self):
548
+ """A string describing the frequency sweep. Below is an example.
549
+ ['LIN 0GHz 20GHz 0.05GHz', 'LINC 20GHz 30GHz 10', 'DEC 40GHz 50GHz 10']
550
+ """
551
+ pattern = r"(?:LIN[C]?|DEC) [^ ]+ [^ ]+ [^ ]+"
552
+ grouped = re.findall(pattern, self._edb_object.FrequencyString)
553
+ return grouped
554
+
555
+ @frequency_string.setter
556
+ def frequency_string(self, value):
557
+ value = value if isinstance(value, list) else [value]
558
+ temp = []
559
+ for i in value:
560
+ sweep_type, start, stop, increment = i.split(" ")
561
+ start = start.replace("k", "K").replace("h", "H").replace("Z", "z").replace("g", "G")
562
+ stop = stop.replace("k", "K").replace("h", "H").replace("Z", "z").replace("g", "G")
563
+ temp.append(" ".join([sweep_type, start, stop, increment]))
564
+ value = temp
565
+ self._edb_object.FrequencyString = " ".join(value)
566
+
567
+ frequencies = []
568
+ for i in value:
569
+ sweep_type, start, stop, increment = i.split(" ")
570
+ if sweep_type == "LIN":
571
+ frequencies.extend(self._edb_object.SetFrequencies(start, stop, increment))
572
+ else:
573
+ increment = int(increment)
574
+ if sweep_type == "DEC":
575
+ frequencies.extend(self._edb_object.SetLogFrequencies(start, stop, increment))
576
+ elif sweep_type == "LINC":
577
+ frequencies.extend(self._edb_object.SetFrequencies(start, stop, increment))
578
+
579
+ self.clear()
580
+ self.add_frequencies(frequencies)
537
581
 
538
582
  def add_frequencies(self, frequencies):
539
583
  if not isinstance(frequencies, list):
540
584
  frequencies = [frequencies]
585
+
586
+ temp = []
587
+ for i in frequencies:
588
+ i = self._pedb.edb_value(i).ToDouble()
589
+ if i not in temp and i not in self.frequencies:
590
+ temp.append(i)
591
+ frequencies = temp
592
+
541
593
  for i in frequencies:
542
594
  i = self._pedb.edb_value(i).ToString()
543
595
  self._edb_object.Frequencies.Add(i)
596
+ self._update_sweep()
544
597
  return list(self._edb_object.Frequencies)
545
598
 
546
599
  def clear(self):
@@ -811,6 +811,7 @@ class EdbSiwave(object):
811
811
 
812
812
  def add_siwave_syz_analysis(
813
813
  self,
814
+ name=None,
814
815
  accuracy_level=1,
815
816
  decade_count=10,
816
817
  sweeptype=1,
@@ -823,6 +824,8 @@ class EdbSiwave(object):
823
824
 
824
825
  Parameters
825
826
  ----------
827
+ name : str optional
828
+ Setup name.
826
829
  accuracy_level : int, optional
827
830
  Level of accuracy of SI slider. The default is ``1``.
828
831
  decade_count : int
@@ -849,7 +852,7 @@ class EdbSiwave(object):
849
852
  :class:`pyedb.dotnet.database.edb_data.siwave_simulation_setup_data.SiwaveSYZSimulationSetup`
850
853
  Setup object class.
851
854
  """
852
- setup = self._pedb.create_siwave_syz_setup()
855
+ setup = self._pedb.create_siwave_syz_setup(name=name)
853
856
  sweep = "linear count"
854
857
  if sweeptype == 2:
855
858
  sweep = "log scale"
@@ -239,7 +239,7 @@ class SimulationSetup(object):
239
239
  """List of frequency sweeps."""
240
240
  return {i.name: i for i in self.sim_setup_info.sweep_data_list}
241
241
 
242
- def add_sweep(self, name, frequency_set: list = None, **kwargs):
242
+ def add_sweep(self, name, frequency_set: list = None, sweep_type: str = "interpolation", **kwargs):
243
243
  """Add frequency sweep.
244
244
 
245
245
  Parameters
@@ -248,7 +248,8 @@ class SimulationSetup(object):
248
248
  Name of the frequency sweep. The default is ``None``.
249
249
  frequency_set : list, optional
250
250
  List of frequency points. The default is ``None``.
251
-
251
+ sweep_type : str, optional
252
+ Sweep type. The default is ``"interpolation"``. Options are ``"discrete"``,"discrete"``.
252
253
  Returns
253
254
  -------
254
255
 
@@ -265,26 +266,24 @@ class SimulationSetup(object):
265
266
  for k, v in kwargs.items():
266
267
  if k in dir(sweep_data):
267
268
  setattr(sweep_data, k, v)
268
- sweep_data.freq_sweep_type = kwargs.get("sweep_type") if kwargs.get("sweep_type") else "interpolation"
269
+ sweep_data.type = sweep_type
269
270
 
270
- if frequency_set is None:
271
+ if frequency_set in [None, []]:
271
272
  sweep_type = "linear_scale"
272
273
  start, stop, increment = "50MHz", "5GHz", "50MHz"
274
+ frequency_set = [[sweep_type, start, stop, increment]]
275
+ elif not isinstance(frequency_set[0], list):
276
+ frequency_set = [frequency_set]
277
+
278
+ for fs in frequency_set:
279
+ sweep_type, start, stop, increment = fs
273
280
  sweep_data.add(sweep_type, start, stop, increment)
274
- elif len(frequency_set) == 0:
275
- pass
276
- else:
277
- if not isinstance(frequency_set[0], list):
278
- frequency_set = [frequency_set]
279
- for fs in frequency_set:
280
- sweep_data.add(*fs)
281
-
282
- ss_info = self.sim_setup_info
283
- ss_info.add_sweep_data(sweep_data)
284
- self.set_sim_setup_info(ss_info)
285
- self._update_setup()
286
281
  return sweep_data
287
282
 
283
+ def delete(self):
284
+ """Delete current simulation setup."""
285
+ self._pedb.layout.cell.DeleteSimulationSetup(self.name)
286
+
288
287
  def _add_frequency_sweep(self, sweep_data):
289
288
  """Add a frequency sweep.
290
289
 
pyedb/dotnet/edb.py CHANGED
@@ -32,7 +32,6 @@ import re
32
32
  import shutil
33
33
  import subprocess
34
34
  import sys
35
- import tempfile
36
35
  import time
37
36
  import traceback
38
37
  from typing import Union
@@ -48,10 +47,7 @@ from pyedb.dotnet.database.cell.terminal.terminal import Terminal
48
47
  from pyedb.dotnet.database.components import Components
49
48
  import pyedb.dotnet.database.dotnet.database
50
49
  from pyedb.dotnet.database.dotnet.database import Database
51
- from pyedb.dotnet.database.edb_data.control_file import (
52
- ControlFile,
53
- convert_technology_file,
54
- )
50
+ from pyedb.dotnet.database.edb_data.control_file import convert_technology_file
55
51
  from pyedb.dotnet.database.edb_data.design_options import EdbDesignOptions
56
52
  from pyedb.dotnet.database.edb_data.edbvalue import EdbValue
57
53
  from pyedb.dotnet.database.edb_data.ports import (
@@ -243,7 +239,7 @@ class Edb(Database):
243
239
  else:
244
240
  control_file = convert_technology_file(technology_file, edbversion=edbversion)
245
241
  self.logger.info("Translating ODB++ to EDB...")
246
- self.import_layout_pcb(edbpath[:-4], working_dir, use_ppe=use_ppe, control_file=control_file)
242
+ self.import_layout_file(edbpath[:-4], working_dir, use_ppe=use_ppe, control_file=control_file)
247
243
  if settings.enable_local_log_file and self.log_name:
248
244
  self._logger.add_file_logger(self.log_name, "Edb")
249
245
  self.logger.info("EDB %s was created correctly from %s file.", self.edbpath, edbpath)
@@ -256,7 +252,7 @@ class Edb(Database):
256
252
  control_file = technology_file
257
253
  else:
258
254
  control_file = convert_technology_file(technology_file, edbversion=edbversion)
259
- self.import_layout_pcb(edbpath, working_dir, use_ppe=use_ppe, control_file=control_file)
255
+ self.import_layout_file(edbpath, working_dir, use_ppe=use_ppe, control_file=control_file)
260
256
  if settings.enable_local_log_file and self.log_name:
261
257
  self._logger.add_file_logger(self.log_name, "Edb")
262
258
  self.logger.info("EDB %s was created correctly from %s file.", self.edbpath, edbpath[-2:])
@@ -278,7 +274,7 @@ class Edb(Database):
278
274
  if self.active_cell:
279
275
  self.logger.info("EDB initialized.")
280
276
  else:
281
- self.logger.info("Failed to initialize DLLs.")
277
+ raise AttributeError("Failed to initialize DLLs.")
282
278
 
283
279
  def __enter__(self):
284
280
  return self
@@ -549,10 +545,7 @@ class Edb(Database):
549
545
  self.run_as_standalone(self.standalone)
550
546
 
551
547
  # self.logger.info("EDB Standalone %s", self.standalone)
552
- try:
553
- self.open(self.edbpath, self.isreadonly)
554
- except Exception as e:
555
- self.logger.error("Builder is not Initialized.")
548
+ self.open(self.edbpath, self.isreadonly)
556
549
  if not self.active_db:
557
550
  self.logger.warning("Error Opening db")
558
551
  self._active_cell = None
@@ -613,6 +606,65 @@ class Edb(Database):
613
606
  anstranslator_full_path="",
614
607
  use_ppe=False,
615
608
  control_file=None,
609
+ map_file=None,
610
+ tech_file=None,
611
+ layer_filter=None,
612
+ ):
613
+ """Import a board file and generate an ``edb.def`` file in the working directory.
614
+
615
+ .. deprecated:: 0.42.0
616
+ Use :func:`import_layout_file` method instead.
617
+
618
+ This function supports all AEDT formats, including DXF, GDS, SML (IPC2581), BRD, MCM, SIP, ZIP and TGZ.
619
+
620
+ Parameters
621
+ ----------
622
+ input_file : str
623
+ Full path to the board file.
624
+ working_dir : str, optional
625
+ Directory in which to create the ``aedb`` folder. The name given to the AEDB file
626
+ is the same as the name of the board file.
627
+ anstranslator_full_path : str, optional
628
+ Full path to the Ansys translator. The default is ``""``.
629
+ use_ppe : bool
630
+ Whether to use the PPE License. The default is ``False``.
631
+ control_file : str, optional
632
+ Path to the XML file. The default is ``None``, in which case an attempt is made to find
633
+ the XML file in the same directory as the board file. To succeed, the XML file and board file
634
+ must have the same name. Only the extension differs.
635
+ tech_file : str, optional
636
+ Technology file. The file can be *.ircx, *.vlc.tech, or *.itf
637
+ map_file : str, optional
638
+ Layer map .map file.
639
+ layer_filter:str,optional
640
+ Layer filter .txt file.
641
+
642
+ Returns
643
+ -------
644
+ Full path to the AEDB file : str
645
+ """
646
+ self.logger.warning("import_layout_pcb method is deprecated, use import_layout_file instead.")
647
+ return self.import_layout_file(
648
+ input_file,
649
+ working_dir,
650
+ anstranslator_full_path,
651
+ use_ppe,
652
+ control_file,
653
+ map_file,
654
+ tech_file,
655
+ layer_filter,
656
+ )
657
+
658
+ def import_layout_file(
659
+ self,
660
+ input_file,
661
+ working_dir="",
662
+ anstranslator_full_path="",
663
+ use_ppe=False,
664
+ control_file=None,
665
+ map_file=None,
666
+ tech_file=None,
667
+ layer_filter=None,
616
668
  ):
617
669
  """Import a board file and generate an ``edb.def`` file in the working directory.
618
670
 
@@ -633,6 +685,12 @@ class Edb(Database):
633
685
  Path to the XML file. The default is ``None``, in which case an attempt is made to find
634
686
  the XML file in the same directory as the board file. To succeed, the XML file and board file
635
687
  must have the same name. Only the extension differs.
688
+ tech_file : str, optional
689
+ Technology file. The file can be *.ircx, *.vlc.tech, or *.itf
690
+ map_file : str, optional
691
+ Layer map .map file.
692
+ layer_filter:str,optional
693
+ Layer filter .txt file.
636
694
 
637
695
  Returns
638
696
  -------
@@ -669,6 +727,12 @@ class Edb(Database):
669
727
  cmd_translator.append("-c={}".format(control_file))
670
728
  else:
671
729
  cmd_translator.append('-c="{}"'.format(control_file))
730
+ if map_file:
731
+ cmd_translator.append('-g="{}"'.format(map_file))
732
+ if tech_file:
733
+ cmd_translator.append('-t="{}"'.format(tech_file))
734
+ if layer_filter:
735
+ cmd_translator.append('-f="{}"'.format(layer_filter))
672
736
  p = subprocess.Popen(cmd_translator)
673
737
  p.wait()
674
738
  if not os.path.exists(os.path.join(working_dir, aedb_name)):
@@ -1469,7 +1533,7 @@ class Edb(Database):
1469
1533
  ``True`` when successful, ``False`` when failed.
1470
1534
 
1471
1535
  """
1472
- if self.import_layout_pcb(
1536
+ if self.import_layout_file(
1473
1537
  inputBrd,
1474
1538
  working_dir=WorkDir,
1475
1539
  anstranslator_full_path=anstranslator_full_path,
@@ -1479,103 +1543,6 @@ class Edb(Database):
1479
1543
  else:
1480
1544
  return False
1481
1545
 
1482
- def import_gds_file(
1483
- self,
1484
- inputGDS,
1485
- anstranslator_full_path="",
1486
- use_ppe=False,
1487
- control_file=None,
1488
- tech_file=None,
1489
- map_file=None,
1490
- layer_filter=None,
1491
- ):
1492
- """Import a GDS file and generate an ``edb.def`` file in the working directory.
1493
-
1494
- ..note::
1495
- `ANSYSLMD_LICENSE_FILE` is needed to run the translator.
1496
-
1497
- Parameters
1498
- ----------
1499
- inputGDS : str
1500
- Full path to the GDS file.
1501
- anstranslator_full_path : str, optional
1502
- Full path to the Ansys translator.
1503
- use_ppe : bool, optional
1504
- Whether to use the PPE License. The default is ``False``.
1505
- control_file : str, optional
1506
- Path to the XML file. The default is ``None``, in which case an attempt is made to find
1507
- the XML file in the same directory as the GDS file. To succeed, the XML file and GDS file must
1508
- have the same name. Only the extension differs.
1509
- tech_file : str, optional
1510
- Technology file. For versions<2024.1 it uses Helic to convert tech file to xml and then imports
1511
- the gds. Works on Linux only.
1512
- For versions>=2024.1 it can directly parse through supported foundry tech files.
1513
- map_file : str, optional
1514
- Layer map file.
1515
- layer_filter:str,optional
1516
- Layer filter file.
1517
-
1518
- """
1519
- control_file_temp = os.path.join(tempfile.gettempdir(), os.path.split(inputGDS)[-1][:-3] + "xml")
1520
- if float(self.edbversion) < 2024.1:
1521
- if not is_linux and tech_file:
1522
- self.logger.error("Technology files are supported only in Linux. Use control file instead.")
1523
- return False
1524
-
1525
- ControlFile(xml_input=control_file, tecnhology=tech_file, layer_map=map_file).write_xml(control_file_temp)
1526
- if self.import_layout_pcb(
1527
- inputGDS,
1528
- anstranslator_full_path=anstranslator_full_path,
1529
- use_ppe=use_ppe,
1530
- control_file=control_file_temp,
1531
- ):
1532
- return True
1533
- else:
1534
- return False
1535
- else:
1536
- if anstranslator_full_path and os.path.exists(anstranslator_full_path):
1537
- path = anstranslator_full_path
1538
- else:
1539
- path = os.path.join(self.base_path, "anstranslator")
1540
- if is_windows:
1541
- path += ".exe"
1542
-
1543
- temp_map_file = os.path.splitext(inputGDS)[0] + ".map"
1544
- temp_layermap_file = os.path.splitext(inputGDS)[0] + ".layermap"
1545
-
1546
- if map_file is None:
1547
- if os.path.isfile(temp_map_file):
1548
- map_file = temp_map_file
1549
- elif os.path.isfile(temp_layermap_file):
1550
- map_file = temp_layermap_file
1551
- else:
1552
- self.logger.error("Unable to define map file.")
1553
-
1554
- if tech_file is None:
1555
- if control_file is None:
1556
- temp_control_file = os.path.splitext(inputGDS)[0] + ".xml"
1557
- if os.path.isfile(temp_control_file):
1558
- control_file = temp_control_file
1559
- else:
1560
- self.logger.error("Unable to define control file.")
1561
-
1562
- command = [path, inputGDS, f'-g="{map_file}"', f'-c="{control_file}"']
1563
- else:
1564
- command = [
1565
- path,
1566
- inputGDS,
1567
- f'-o="{control_file_temp}"' f'-t="{tech_file}"',
1568
- f'-g="{map_file}"',
1569
- f'-f="{layer_filter}"',
1570
- ]
1571
-
1572
- result = subprocess.run(command, capture_output=True, text=True, shell=True)
1573
- print(result.stdout)
1574
- print(command)
1575
- temp_inputGDS = inputGDS.split(".gds")[0]
1576
- self.edbpath = temp_inputGDS + ".aedb"
1577
- return self.open_edb()
1578
-
1579
1546
  def _create_extent(
1580
1547
  self,
1581
1548
  net_signals,
@@ -2274,8 +2274,7 @@ class Components(object):
2274
2274
  pingroup = PinGroup.create(self._active_layout, group_name, pins)
2275
2275
 
2276
2276
  if pingroup.is_null: # pragma: no cover
2277
- self._logger.error(f"Failed to create pin group {group_name}.")
2278
- return False
2277
+ raise RuntimeError(f"Failed to create pin group {group_name}.")
2279
2278
  else:
2280
2279
  for pin in pins:
2281
2280
  if not pin.net.is_null:
@@ -41,6 +41,7 @@ from ansys.edb.core.hierarchy.pin_pair_model import PinPairModel as GrpcPinPairM
41
41
  from ansys.edb.core.hierarchy.sparameter_model import (
42
42
  SParameterModel as GrpcSParameterModel,
43
43
  )
44
+ from ansys.edb.core.hierarchy.spice_model import SPICEModel as GrpcSPICEModel
44
45
  from ansys.edb.core.primitive.primitive import PadstackInstance as GrpcPadstackInstance
45
46
  from ansys.edb.core.terminal.terminals import (
46
47
  PadstackInstanceTerminal as GrpcPadstackInstanceTerminal,
@@ -49,6 +50,7 @@ from ansys.edb.core.utility.rlc import Rlc as GrpcRlc
49
50
  from ansys.edb.core.utility.value import Value as GrpcValue
50
51
 
51
52
  from pyedb.grpc.database.hierarchy.pin_pair_model import PinPairModel
53
+ from pyedb.grpc.database.hierarchy.s_parameter_model import SparamModel
52
54
  from pyedb.grpc.database.hierarchy.spice_model import SpiceModel
53
55
  from pyedb.grpc.database.layers.stackup_layer import StackupLayer
54
56
  from pyedb.grpc.database.primitive.padstack_instance import PadstackInstance
@@ -204,7 +206,13 @@ class Component(GrpcComponentGroup):
204
206
  :class:`Model <ansys.edb.core.hierarchy.model.Model>`
205
207
 
206
208
  """
207
- return self.component_property.model
209
+
210
+ if isinstance(self.component_property.model, GrpcSPICEModel):
211
+ return SpiceModel(edb_object=self.component_property.model.msg)
212
+ elif isinstance(self.component_property.model, GrpcSParameterModel):
213
+ return SparamModel(edb_object=self.component_property.model.msg)
214
+ else:
215
+ return self.component_property.model
208
216
 
209
217
  @model.setter
210
218
  def model(self, value):
@@ -28,6 +28,6 @@ from ansys.edb.core.hierarchy.sparameter_model import (
28
28
  class SparamModel(GrpcSParameterModel): # pragma: no cover
29
29
  """Manage :class:`SParameterModel <ansys.edb.core.hierarchy.sparameter_model.SParameterModel>`"""
30
30
 
31
- def __init__(self, edb_model):
31
+ def __init__(self, edb_object):
32
32
  super().__init__(self.msg)
33
- self._edb_model = edb_model
33
+ self._edb_model = edb_object
@@ -46,3 +46,7 @@ class SpiceModel(GrpcSpiceModel): # pragma: no cover
46
46
 
47
47
  """
48
48
  return self.model_name
49
+
50
+ @property
51
+ def spice_file_path(self):
52
+ return self.model_path
@@ -81,12 +81,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
81
81
  float
82
82
  Air box horizontal extent value.
83
83
  """
84
- return self._hfss_extent_info.air_box_horizontal_extent[0]
84
+ return self._hfss_extent_info.airbox_horizontal[0]
85
85
 
86
86
  @air_box_horizontal_extent.setter
87
87
  def air_box_horizontal_extent(self, value):
88
88
  hfss_extent = self._hfss_extent_info
89
- hfss_extent.air_box_horizontal_extent = float(value)
89
+ hfss_extent.airbox_horizontal = (float(value), True)
90
90
  self._update_hfss_extent_info(hfss_extent)
91
91
 
92
92
  @property
@@ -98,12 +98,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
98
98
  bool.
99
99
 
100
100
  """
101
- return self._hfss_extent_info.air_box_positive_vertical_extent[1]
101
+ return self._hfss_extent_info.airbox_vertical_positive[1]
102
102
 
103
103
  @air_box_positive_vertical_extent_enabled.setter
104
104
  def air_box_positive_vertical_extent_enabled(self, value):
105
105
  hfss_exent = self._hfss_extent_info
106
- hfss_exent.air_box_positive_vertical_extent = value
106
+ hfss_exent.airbox_vertical_positive = (0.15, value)
107
107
  self._update_hfss_extent_info(hfss_exent)
108
108
 
109
109
  @property
@@ -116,12 +116,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
116
116
  Air box positive vertical extent value.
117
117
 
118
118
  """
119
- return self._hfss_extent_info.air_box_positive_vertical_extent[0]
119
+ return self._hfss_extent_info.airbox_vertical_positive[0]
120
120
 
121
121
  @air_box_positive_vertical_extent.setter
122
122
  def air_box_positive_vertical_extent(self, value):
123
123
  hfss_extent = self._hfss_extent_info
124
- hfss_extent.air_box_positive_vertical_extent = float(value)
124
+ hfss_extent.airbox_vertical_positive = (float(value), True)
125
125
  self._update_hfss_extent_info(hfss_extent)
126
126
 
127
127
  @property
@@ -133,12 +133,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
133
133
  bool.
134
134
 
135
135
  """
136
- return self._hfss_extent_info.air_box_negative_vertical_extent[1]
136
+ return self._hfss_extent_info.airbox_vertical_negative[1]
137
137
 
138
138
  @air_box_negative_vertical_extent_enabled.setter
139
139
  def air_box_negative_vertical_extent_enabled(self, value):
140
140
  hfss_extent = self._hfss_extent_info
141
- hfss_extent.air_box_negative_vertical_extent = value
141
+ hfss_extent.airbox_vertical_negative = (0.15, value)
142
142
  self._update_hfss_extent_info(hfss_extent)
143
143
 
144
144
  @property
@@ -151,12 +151,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
151
151
  Air box negative vertical extent value.
152
152
 
153
153
  """
154
- return self._hfss_extent_info.air_box_negative_vertical_extent[0]
154
+ return self._hfss_extent_info.airbox_vertical_negative[0]
155
155
 
156
156
  @air_box_negative_vertical_extent.setter
157
157
  def air_box_negative_vertical_extent(self, value):
158
158
  hfss_extent = self._hfss_extent_info
159
- hfss_extent.air_box_negative_vertical_extent = float(value)
159
+ hfss_extent.airbox_vertical_negative = (float(value), True)
160
160
  self._update_hfss_extent_info(hfss_extent)
161
161
 
162
162
  @property
@@ -183,7 +183,7 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
183
183
  -------
184
184
  :class:`Polygon <pyedb.grpc.database.primitive.polygon.Polygon>`
185
185
  """
186
- return self._hfss_extent_info.dielectric_base_polygon
186
+ return super().dielectric_base_polygon
187
187
 
188
188
  @dielectric_base_polygon.setter
189
189
  def dielectric_base_polygon(self, value):
@@ -216,12 +216,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
216
216
  float
217
217
  Dielectric extent size value.
218
218
  """
219
- return self._hfss_extent_info.dielectric_extent_size[0]
219
+ return self._hfss_extent_info.dielectric[0]
220
220
 
221
221
  @dielectric_extent_size.setter
222
222
  def dielectric_extent_size(self, value):
223
223
  hfss_extent = self._hfss_extent_info
224
- hfss_extent.dielectric_extent_size = value
224
+ hfss_extent.dielectric = (value, True)
225
225
  self._update_hfss_extent_info(hfss_extent)
226
226
 
227
227
  @property
@@ -256,6 +256,17 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
256
256
  @extent_type.setter
257
257
  def extent_type(self, value):
258
258
  hfss_extent = self._hfss_extent_info
259
+ if isinstance(value, str):
260
+ if value.lower() == "bounding_box":
261
+ value = GrpcHfssExtentInfo.HFSSExtentInfoType.BOUNDING_BOX
262
+ elif value.lower() == "conforming":
263
+ value = GrpcHfssExtentInfo.HFSSExtentInfoType.CONFORMING
264
+ elif value.lower() == "convex_hul":
265
+ value = GrpcHfssExtentInfo.HFSSExtentInfoType.CONVEX_HUL
266
+ elif value.lower() == "polygon":
267
+ value = GrpcHfssExtentInfo.HFSSExtentInfoType.POLYGON
268
+ else:
269
+ raise f"Invalid extent type : {value}"
259
270
  hfss_extent.extent_type = value
260
271
  self._update_hfss_extent_info(hfss_extent)
261
272
 
@@ -328,7 +339,7 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
328
339
  self._update_hfss_extent_info(hfss_extent)
329
340
 
330
341
  @property
331
- def radiation_level(self):
342
+ def pml_radiation_factor(self):
332
343
  """PML Radiation level to calculate the thickness of boundary.
333
344
 
334
345
  Returns
@@ -337,12 +348,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
337
348
  Boundary thickness value.
338
349
 
339
350
  """
340
- return GrpcValue(self._hfss_extent_info.radiation_level).value
351
+ return self._hfss_extent_info.radiation_level.value
341
352
 
342
- @radiation_level.setter
343
- def radiation_level(self, value):
353
+ @pml_radiation_factor.setter
354
+ def pml_radiation_factor(self, value):
344
355
  hfss_extent = self._hfss_extent_info
345
- hfss_extent.RadiationLevel = GrpcValue(value)
356
+ hfss_extent.radiation_level = GrpcValue(value)
346
357
  self._update_hfss_extent_info(hfss_extent)
347
358
 
348
359
  @property
@@ -373,12 +384,12 @@ class HfssExtentInfo(GrpcHfssExtentInfo):
373
384
  Truncate air box at ground.
374
385
 
375
386
  """
376
- return self._hfss_extent_info.truncate_air_box_at_ground
387
+ return self._hfss_extent_info.airbox_truncate_at_ground
377
388
 
378
389
  @truncate_air_box_at_ground.setter
379
390
  def truncate_air_box_at_ground(self, value):
380
391
  hfss_extent = self._hfss_extent_info
381
- hfss_extent.truncate_air_box_at_ground = value
392
+ hfss_extent.airbox_truncate_at_ground = value
382
393
  self._update_hfss_extent_info(hfss_extent)
383
394
 
384
395
  @property
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyedb
3
- Version: 0.41.0
3
+ Version: 0.43.0
4
4
  Summary: Higher-Level Pythonic Ansys Electronics Data Base
5
5
  Author-email: "ANSYS, Inc." <pyansys.core@ansys.com>
6
6
  Maintainer-email: PyEDB developers <simon.vandenbrouck@ansys.com>