diff --git a/.flake8 b/.flake8
index 4292f9a9fc..6827ce59b0 100644
--- a/.flake8
+++ b/.flake8
@@ -1,5 +1,5 @@
[flake8]
-exclude = venv, __init__.py, doc/_build, doc/source/examples, pyaedt/third_party/**/*
+exclude = venv, __init__.py, doc/_build, doc/source/examples
select = W191, W291, W293, W391, E115, E117, E122, E124, E125, E225, E231, E301, E303, E501, F401, F403
count = True
max-complexity = 10
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index d720048319..5e7962748e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,7 +1 @@
-.github/* @MaxJPRey @maxcapodi78 @Samuelopez-ansys
-
-/_unittest/test_26_emit.py @jsalant22 @myoung301
-/pyaedt/emit.py @jsalant22 @myoung301
-/pyaedt/emit_core/ @jsalant22 @myoung301
-/pyaedt/modeler/circuits/PrimitivesEmit.py @jsalant22 @myoung301
-/examples/07-EMIT/ @jsalant22 @myoung301
\ No newline at end of file
+.github/* @svandenb-dev @ring630 @SMoraisAnsys
diff --git a/.github/workflows/legacy_examples.yml b/.github/workflows/legacy_examples.yml
index 741c9b85bd..78eae672e4 100644
--- a/.github/workflows/legacy_examples.yml
+++ b/.github/workflows/legacy_examples.yml
@@ -36,7 +36,7 @@ jobs:
cache: 'pip'
python-version: '3.10'
- - name: Install pyedb with tests dependencies
+ - name: Install pyedb
run: |
pip install .
diff --git a/.gitignore b/.gitignore
index 3217264818..f85ed91560 100644
--- a/.gitignore
+++ b/.gitignore
@@ -393,6 +393,9 @@ model.index.bak
model.index.tmp
model.index\+
+# Pytest coverage
+.cov
+
# local environment settings used by e.g. Visual Studio Code
/.env
/doc/source/local_config.json
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index ce7ff27051..25557e97a9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,51 +1,50 @@
-files: |
- (?x)(
- ^pyaedt/|
- _unittest/|
- requirements/requirements_docs.txt|
- requirements/requirements_test.txt
- )
-exclude: |
- (?x)(
- ^pyaedt/dlls/|
- ^pyaedt/rpc/|
- ^pyaedt/sbrplus/matlab/|
- ^pyaedt/third_party/|
- pyaedt/conftest.py|
- _unittest/example_models/
- )
+fail_fast: True
repos:
+
- repo: https://github.com/psf/black
- rev: 23.9.1 # IF VERSION CHANGES --> MODIFY "blacken-docs" MANUALLY AS WELL!!
+ rev: 23.10.1 # IF VERSION CHANGES --> MODIFY "blacken-docs" MANUALLY AS WELL!!
hooks:
- id: black
args:
- - --line-length=120
+ - --line-length=88
+
+- repo: https://github.com/adamchainz/blacken-docs
+ rev: 1.16.0
+ hooks:
+ - id: blacken-docs
+ additional_dependencies: [black==23.10.1]
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
- name: isort (python)
- args: ['--force-single-line-imports', '--profile', 'black']
- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
hooks:
- id: flake8
- args:
- - --max-line-length=120
+ args: [
+ --max-line-length, "88",
+ ansys, codegen, doc, examples, tests
+ ]
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
- id: codespell
- additional_dependencies:
- - tomli
+ args: ["--toml", "pyproject.toml"]
+ additional_dependencies: [tomli]
+
+- repo: https://github.com/PyCQA/docformatter
+ rev: v1.7.5
+ hooks:
+ - id: docformatter
+ stages: [manual]
+ args: ["--config", "pyproject.toml"]
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.4.0
+ rev: v4.5.0
hooks:
- id: requirements-txt-fixer
- id: debug-statements
@@ -57,13 +56,6 @@ repos:
hooks:
- id: check-github-workflows
-- repo: https://github.com/asottile/blacken-docs
- rev: 1.16.0
- hooks:
- - id: blacken-docs
- additional_dependencies: [black==23.9.1]
-
-
# - repo: https://github.com/numpy/numpydoc
# rev: v1.6.0
# hooks:
diff --git a/LICENSE b/LICENSE
index a9d9a2ef7e..07381af77c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2021 ANSYS, Inc. All rights reserved.
+Copyright (c) 2023 ANSYS, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/Makefile b/Makefile
index 7338baaf41..213e95b239 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
# Simple makefile to simplify repetitive build env management tasks under posix
-CODESPELL_DIRS ?= ./pyaedt
-CODESPELL_SKIP ?= "*.pyc,*.aedt,*.xml,*.txt,*.gif,*.png,*.jpg,*.js,*.html,*.doctree,*.ttf,*.woff,*.woff2,*.eot,*.mp4,*.inv,*.pickle,*.ipynb,flycheck*,./.git/*,./.hypothesis/*,*.yml,./docs/build/*,./docs/images/*,./dist/*,*~,.hypothesis*,./pyaedt/third_party,./docs/source/examples/*,*cover,*.dat,*.mac,\#*,PKG-INFO,*.mypy_cache/*,*.xml,*.aedt,*.svg"
-CODESPELL_IGNORE ?= "ignore_words.txt"
+CODESPELL_DIRS ?= ./src
+CODESPELL_SKIP ?= "*.pyc,*.aedt,*.xml,*.txt,*.gif,*.png,*.jpg,*.js,*.html,*.doctree,*.ttf,*.woff,*.woff2,*.eot,*.mp4,*.inv,*.pickle,*.ipynb,flycheck*,./.git/*,./.hypothesis/*,*.yml,./docs/build/*,./docs/images/*,./dist/*,*~,.hypothesis*,./docs/source/examples/*,*cover,*.dat,*.mac,\#*,PKG-INFO,*.mypy_cache/*,*.xml,*.aedt,*.svg"
+CODESPELL_IGNORE ?= "doc/styles/Vocab/ANSYS/accept.txt"
all: doctest flake8
diff --git a/README.md b/README.md
index db72a08a63..30aa5df868 100644
--- a/README.md
+++ b/README.md
@@ -12,13 +12,8 @@
[![PyAnsys](https://img.shields.io/badge/Py-Ansys-ffc107.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABDklEQVQ4jWNgoDfg5mD8vE7q/3bpVyskbW0sMRUwofHD7Dh5OBkZGBgW7/3W2tZpa2tLQEOyOzeEsfumlK2tbVpaGj4N6jIs1lpsDAwMJ278sveMY2BgCA0NFRISwqkhyQ1q/Nyd3zg4OBgYGNjZ2ePi4rB5loGBhZnhxTLJ/9ulv26Q4uVk1NXV/f///////69du4Zdg78lx//t0v+3S88rFISInD59GqIH2esIJ8G9O2/XVwhjzpw5EAam1xkkBJn/bJX+v1365hxxuCAfH9+3b9/+////48cPuNehNsS7cDEzMTAwMMzb+Q2u4dOnT2vWrMHu9ZtzxP9vl/69RVpCkBlZ3N7enoDXBwEAAA+YYitOilMVAAAAAElFTkSuQmCC)](https://docs.pyansys.com/)
-[![pypi](https://img.shields.io/pypi/v/pyaedt.svg?logo=python&logoColor=white)](https://pypi.org/project/pyaedt/)
-[![PyPIact](https://static.pepy.tech/badge/pyaedt/month)](https://www.pepy.tech/projects/pyaedt)
[![PythonVersion](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
-[![GH-CI](https://github.com/ansys/pyaedt/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/ansys/pyaedt/actions/workflows/unit_tests.yml)
-[![codecov](https://codecov.io/gh/ansys/pyaedt/branch/main/graph/badge.svg)](https://codecov.io/gh/ansys/pyaedt)
-[![MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)[![black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat)](https://github.com/psf/black)[![Anaconda](https://anaconda.org/conda-forge/pyaedt/badges/version.svg)](https://anaconda.org/conda-forge/pyaedt)
-[![pre-commit](https://results.pre-commit.ci/badge/github/ansys/pyaedt/main.svg)](https://results.pre-commit.ci/latest/github/ansys/pyaedt/main)
+[![MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)[!
## What is PyEDB ?
@@ -67,10 +62,9 @@ and most efficient way to handle large and complex layout.
AEDB can also been parsed with and Electromagnetic simulator command line like HFSS or SIwave in bacth.
Therefore completely non graphical flows can be deployed from layout translation up to simulatiom results.
-AEDB can also be imported in ANSYS AEDT with PyAEDT for example to display the project, combining 3D design
-or performing simulation post-processing. AEDB also supports 3D component models.
+AEDB can also be imported in ANSYS AEDT with PyAEDT for example to display the project, combining 3D design or performing simulation post-processing. AEDB also supports 3D component models.
-`PyEDB` is licensed under the [MIT License](https://github.com/ansys/pyaedt/blob/main/LICENSE)
+`PyEDB` is licensed under the [MIT License](https://github.com/ansys/pyedb/blob/main/LICENSE)
PyEDB includes functionality for interacting with the following AEDT tools and Ansys products:
@@ -81,8 +75,8 @@ PyEDB includes functionality for interacting with the following AEDT tools and A
## Documentation and issues
-Documentation for the latest stable release of PyAEDT is hosted at
-[PyEDB documentation](https://aedt.docs.pyansys.com/version/stable/).
+Documentation for the latest stable release of PyEDB is hosted at
+[PyEDB documentation](https://aedb.docs.pyansys.com/version/stable/).
In the upper right corner of the documentation's title bar, there is an option
for switching from viewing the documentation for the latest stable release
@@ -97,9 +91,9 @@ providing syntax rules and commands for using the PyEDB API:
PyEDB API cheat sheet.
-On the [PyEDB Issues](https://github.com/ansys-internal/pyansys-edb/issues) page, you can
+On the [PyEDB Issues](https://github.com/ansys/pyansys-edb/issues) page, you can
create issues to report bugs and request new features. On the
-[PyAEDT Discussions](https://github.com/ansys/pyaedt/discussions) page or the
+[PyEDB Discussions](https://github.com/ansys/pyansys-edb/discussions) page or the
[Discussions](https://discuss.ansys.com/) page on the Ansys Developer portal,
you can post questions, share ideas, and get community feedback.
diff --git a/codecov.yml b/codecov.yml
index a658463bcc..1f7fdf5cd4 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -14,15 +14,6 @@ coverage:
if_no_uploads: error
ignore:
- "examples" # ignore folders and all its contents
- - "_unittest" # ignore folders and all its contents
- - "_unittest_ironpython" # ignore folders and all its contents
- - "legacy/third_party/**/*.py" # ignore folders and all its contents
- - "legacy/rpc/**/*.py" # ignore folders and all its contents
- - "legacy/generic/toolkit.py" # ignore folders and all its contents
- - "legacy/doctest_fixtures/*.py" # ignore folders and all its contents
- - "legacy/siwave.py" # ignore folders and all its contents
- - "legacy/setup.py" # ignore folders and all its contents
- - "legacy/setup-distutils.py" # ignore folders and all its contents
- - "legacy/_setup_common.py" # ignore folders and all its contents
- - "legacy/misc/*.py" # ignore folders and all its contents
- - "legacy/sbrplus/hdm_utils.py" # ignore folder and all its contents
+ - "tests" # ignore folders and all its contents
+ - "src/pyedb/legacy/edb_core/siwave.py" # ignore folders and all its contents
+ - "src/pyedb/misc/*.py" # ignore folders and all its contents
diff --git a/doc/styles/Vocab/ANSYS/accept.txt b/doc/styles/Vocab/ANSYS/accept.txt
index 16e7708252..646b9f7367 100644
--- a/doc/styles/Vocab/ANSYS/accept.txt
+++ b/doc/styles/Vocab/ANSYS/accept.txt
@@ -1,37 +1,46 @@
-ANSYS
-Ansys
-ansys
-AEDB
2D Extractor
+2D modeler
+3D modeler
+_static
+AEDB
+AEDT
airbox
airgap
+(?i)Ansys
+API
autosave
busbar
busbars
Bz
-circuit
-Circuit
+[Cc]ircuit
+codecov
+[Cc]om
+COM interface
+[Cc]omponents
+Conda
CPython
DesignXploration
docstring
-Docstrings
-docstrings
+[Dd]ocstrings
doppler
EDB
+EDT
efields
EMIT
getters
globals
-HFSS 3D Layout
+[Gg]gRPC
+HFSS
Huray
Icepak
IronPython
+[Ll]ayout
limitilines
matplotlib
Maxwell 2D
Maxwell 3D
Maxwell Circuit
-Mechanical
+[Mm]echanical
multiphysics
multiplot
namespaces
@@ -39,48 +48,39 @@ netlist
Nexxim
numpy
numpydoc
-optimetrics
-Optimetrics
+[Oo]ptimetrics
padstack
padstacks
parametrics
-polyline
+PMs
+[Pp]olyline
polylines
-Polyline
Postprocessing
-PMs
+pwl
pyaedt
PyAEDT
-PyPI
+(?i)PyAnsys
+[Pp]y[Pp][Ii]
Python
+Python.NET
pyvista
Q2D Extractor
+Q3D
Q3D Extractor
RC
+reusability
RF
RMXprt
scipy
-Siwave
setters
+Siwave
+Slurm
Spyder
+Stackup 3D
stackups
stripline
subcircuit
+[Tt]oolkits
Twin Builder
Uncomment
-vias
-_static
-pwl
-Conda
-PyAnsys
-codecov
-mechanical
-reusability
-pypi
-EDT
-pyansys
-Slurm
-Python.NET
-Toolkits
-toolkits
-
+vias
\ No newline at end of file
diff --git a/examples/00-EDB/00_EDB_Create_VIA.py b/examples/00-EDB/00_EDB_Create_VIA.py
deleted file mode 100644
index 6a7f694750..0000000000
--- a/examples/00-EDB/00_EDB_Create_VIA.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""
-EDB: geometry creation
-----------------------
-This example shows how you can use EDB to create a layout.
-"""
-######################################################################
-# Final expected project
-# ~~~~~~~~~~~~~~~~~~~~~~
-#
-# .. image:: ../../_static/diff_via.png
-# :width: 600
-# :alt: Differential Vias.
-######################################################################
-
-######################################################################
-# Import EDB layout object
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Import the EDB layout object and initialize it on version 2023 R2.
-######################################################################
-
-import time
-import os
-import pyedb
-
-start = time.time()
-
-aedb_path = os.path.join(pyedb.generate_unique_folder_name(), pyedb.generate_unique_name("pcb") + ".aedb")
-print(aedb_path)
-edb = pyedb.Edb(edbpath=aedb_path, edbversion="2023.2")
-
-####################
-# Add stackup layers
-# ~~~~~~~~~~~~~~~~~~
-# Add stackup layers.
-# A stackup can be created layer by layer or imported from a csv file or xml file.
-#
-
-edb.stackup.add_layer("GND")
-edb.stackup.add_layer("Diel", "GND", layer_type="dielectric", thickness="0.1mm", material="FR4_epoxy")
-edb.stackup.add_layer("TOP", "Diel", thickness="0.05mm")
-
-#####################################
-# Create signal net and ground planes
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Create a signal net and ground planes.
-
-points = [
- [0.0, 0],
- [100e-3, 0.0],
-]
-edb.modeler.create_trace(points, "TOP", width=1e-3)
-points = [[0.0, 1e-3], [0.0, 10e-3], [100e-3, 10e-3], [100e-3, 1e-3], [0.0, 1e-3]]
-edb.modeler.create_polygon(points, "TOP")
-
-points = [[0.0, -1e-3], [0.0, -10e-3], [100e-3, -10e-3], [100e-3, -1e-3], [0.0, -1e-3]]
-edb.modeler.create_polygon(points, "TOP")
-
-#######################################
-# Create vias with parametric positions
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Create vias with parametric positions.
-
-edb.padstacks.create("MyVia")
-edb.padstacks.place([5e-3, 5e-3], "MyVia")
-edb.padstacks.place([15e-3, 5e-3], "MyVia")
-edb.padstacks.place([35e-3, 5e-3], "MyVia")
-edb.padstacks.place([45e-3, 5e-3], "MyVia")
-edb.padstacks.place([5e-3, -5e-3], "MyVia")
-edb.padstacks.place([15e-3, -5e-3], "MyVia")
-edb.padstacks.place([35e-3, -5e-3], "MyVia")
-edb.padstacks.place([45e-3, -5e-3], "MyVia")
-
-
-#######################################
-# Geometry Plot
-# ~~~~~~~~~~~~~
-#
-edb.nets.plot(None, color_by_net=True)
-
-#######################################
-# Stackup Plot
-# ~~~~~~~~~~~~
-#
-edb.stackup.plot(plot_definitions="MyVia")
-
-
-####################
-# Save and close EDB
-# ~~~~~~~~~~~~~~~~~~
-# Save and close EDB.
-
-if edb:
- edb.save_edb()
- edb.close_edb()
-print("EDB saved correctly to {}. You can import in AEDT.".format(aedb_path))
-end = time.time() - start
-print(end)
diff --git a/examples/00-EDB/01_edb_example.py b/examples/00-EDB/01_edb_example.py
deleted file mode 100644
index d5a4e6624f..0000000000
--- a/examples/00-EDB/01_edb_example.py
+++ /dev/null
@@ -1,173 +0,0 @@
-"""
-EDB: Siwave analysis from EDB setup
------------------------------------
-This example shows how you can use EDB to interact with a layout.
-"""
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Perform required imports.
-
-import shutil
-
-import os
-import time
-import pyedb
-
-temp_folder = pyedb.generate_unique_folder_name()
-targetfile = pyedb.downloads.download_file('edb/ANSYS-HSD_V1.aedb', destination=temp_folder)
-
-siwave_file = os.path.join(os.path.dirname(targetfile), "ANSYS-HSD_V1.siw")
-print(targetfile)
-aedt_file = targetfile[:-4] + "aedt"
-
-
-###############################################################################
-# Launch EDB
-# ~~~~~~~~~~
-# Launch the :class:`legacy.Edb` class, using EDB 2023 R2 and SI units.
-edb_version = "2023.2"
-if os.path.exists(aedt_file):
- os.remove(aedt_file)
-edb = pyedb.Edb(edbpath=targetfile, edbversion=edb_version)
-
-###############################################################################
-# Compute nets and components
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Computes nets and components.
-# There are queries for nets, stackups, layers, components, and geometries.
-
-print("Nets {}".format(len(edb.nets.netlist)))
-start = time.time()
-print("Components {}".format(len(edb.components.components.keys())))
-print("elapsed time = ", time.time() - start)
-
-###############################################################################
-# Get pin position
-# ~~~~~~~~~~~~~~~~
-# Get the position for a specific pin.
-# The next section shows how to get all pins for a specific component and
-# the positions of each of them.
-# Each pin is a list of ``[X, Y]`` coordinate positions.
-
-pins = edb.components["U2"].pins
-for pin in edb.components["U2"].pins.values():
- print(pin.position)
-
-###############################################################################
-# Get all nets connected to a component
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Get all nets connected to a specific component.
-
-edb.components.get_component_net_connection_info("U2")
-
-###############################################################################
-# Compute rats
-# ~~~~~~~~~~~~
-# Computes rats.
-
-rats = edb.components.get_rats()
-
-###############################################################################
-# Get all DC-connected net lists through inductance
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Get all DC-connected net lists through inductance.
-# The inputs needed are ground net lists. The returned list contains all nets
-# connected to a ground through an inductor.
-
-GROUND_NETS = ["GND", "GND_DP"]
-dc_connected_net_list = edb.nets.get_dcconnected_net_list(GROUND_NETS)
-print(dc_connected_net_list)
-
-###############################################################################
-# Get power tree based on a specific net
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Get the power tree based on a specific net.
-
-VRM = "U1"
-OUTPUT_NET = "AVCC_1V3"
-powertree_df, component_list_columns, net_group = edb.nets.get_powertree(OUTPUT_NET, GROUND_NETS)
-for el in powertree_df:
- print(el)
-
-###############################################################################
-# Delete all RLCs with only one pin
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Delete all RLCs with only one pin. This method provides a useful way of
-# removing components not needed in the simulation.
-
-edb.components.delete_single_pin_rlc()
-
-###############################################################################
-# Delete components
-# ~~~~~~~~~~~~~~~~~
-# Delete manually one or more components.
-
-edb.components.delete("C380")
-
-###############################################################################
-# Delete nets
-# ~~~~~~~~~~~
-# Delete manually one or more nets.
-
-edb.nets.delete("PDEN")
-
-###############################################################################
-# Get stackup limits
-# ~~~~~~~~~~~~~~~~~~
-# Get the stackup limits (top and bottom layers and elevations).
-
-print(edb.stackup.limits())
-
-
-
-###############################################################################
-# Create voltage source and Siwave DCIR analysis
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Create a voltage source and then set up a DCIR analysis.
-
-edb.siwave.create_voltage_source_on_net("U1", "AVCC_1V3", "U1", "GND", 1.3, 0, "V1")
-edb.siwave.create_current_source_on_net("IC2", "NetD3_2", "IC2", "GND", 1.0, 0, "I1")
-setup = edb.siwave.add_siwave_dc_analysis("myDCIR_4")
-setup.use_dc_custom_settings = True
-setup.dc_slider_position = 0
-setup.add_source_terminal_to_ground("V1", 1)
-
-
-
-###############################################################################
-# Save modifications
-# ~~~~~~~~~~~~~~~~~~
-# Save modifications.
-
-edb.save_edb()
-edb.nets.plot(None, "1_Top",plot_components_on_top=True)
-
-siw_file = edb.solve_siwave()
-
-###############################################################################
-# Export Siwave Reports
-# ~~~~~~~~~~~~~~~~~~~~~
-# Export all DC Reports quantities.
-outputs = edb.export_siwave_dc_results(siw_file, setup.name, )
-
-###############################################################################
-# Close EDB
-# ~~~~~~~~~
-# Close EDB. After EDB is closed, it can be opened by AEDT.
-
-edb.close_edb()
-
-###############################################################################
-# Postprocess in Siwave
-# ~~~~~~~~~~~~~~~~~~~~~
-# Open Siwave and generate a report. This works on Window only.
-
-# from legacy import Siwave
-# siwave = Siwave("2023.2")
-# siwave.open_project(siwave_file)
-# report_file = os.path.join(temp_folder,'Ansys.htm')
-#
-# siwave.export_siwave_report("myDCIR_4", report_file)
-# siwave.close_project()
-# siwave.quit_application()
diff --git a/examples/00-EDB/02_edb_to_ipc2581.py b/examples/00-EDB/02_edb_to_ipc2581.py
deleted file mode 100644
index 97ee008977..0000000000
--- a/examples/00-EDB/02_edb_to_ipc2581.py
+++ /dev/null
@@ -1,85 +0,0 @@
-"""
-EDB: IPC2581 export
--------------------
-This example shows how you can use PyAEDT to export an IPC2581 file.
-"""
-
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Perform required imports, which includes importing a section.
-
-import os
-import pyedb
-
-###############################################################################
-# Download file
-# ~~~~~~~~~~~~~
-# Download the AEDB file and copy it in the temporary folder.
-
-
-temp_folder = pyedb.generate_unique_folder_name()
-targetfile = pyedb.downloads.download_file('edb/ANSYS-HSD_V1.aedb', destination=temp_folder)
-
-
-ipc2581_file = os.path.join(temp_folder, "Ansys_Hsd.xml")
-
-print(targetfile)
-
-
-###############################################################################
-# Launch EDB
-# ~~~~~~~~~~
-# Launch the :class:`legacy.Edb` class, using EDB 2023 R2 and SI units.
-
-edb = pyedb.Edb(edbpath=targetfile, edbversion="2023.2")
-
-
-###############################################################################
-# Parametrize net
-# ~~~~~~~~~~~~~~~
-# Parametrize a net.
-
-edb.modeler.parametrize_trace_width(
- "A0_N", parameter_name=pyedb.generate_unique_name("Par"), variable_value="0.4321mm"
-)
-
-###############################################################################
-# Cutout
-# ~~~~~~
-# Create a cutout.
-signal_list = []
-for net in edb.nets.netlist:
- if "PCIe" in net:
- signal_list.append(net)
-power_list = ["GND"]
-edb.cutout(signal_list=signal_list, reference_list=power_list, extent_type="ConvexHull",
- expansion_size=0.002,
- use_round_corner=False,
- number_of_threads=4,
- remove_single_pin_components=True,
- use_pyaedt_extent_computing=True,
- extent_defeature=0,
- )
-
-###############################################################################
-# Plot cutout
-# ~~~~~~~~~~~
-# Plot cutout before exporting to IPC2581 file.
-
-edb.nets.plot(None, None, color_by_net=True)
-
-###############################################################################
-# Create IPC2581 file
-# ~~~~~~~~~~~~~~~~~~~
-# Create the IPC2581 file.
-
-edb.export_to_ipc2581(ipc2581_file, "inch")
-print("IPC2581 File has been saved to {}".format(ipc2581_file))
-
-###############################################################################
-# Close EDB
-# ~~~~~~~~~
-# Close EDB.
-
-edb.close_edb()
diff --git a/examples/00-EDB/03_5G_antenna_example.py b/examples/00-EDB/03_5G_antenna_example.py
deleted file mode 100644
index 2a72c0ea1a..0000000000
--- a/examples/00-EDB/03_5G_antenna_example.py
+++ /dev/null
@@ -1,281 +0,0 @@
-"""
-EDB: 5G linear array antenna
-----------------------------
-This example shows how you can use HFSS 3D Layout to create and solve a 5G linear array antenna.
-"""
-
-##########################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Perform required imports.
-
-import tempfile
-import pyedb
-import os
-
-##########################################################
-# Set non-graphical mode
-# ~~~~~~~~~~~~~~~~~~~~~~
-# Set non-graphical mode. The default is ``False``.
-
-non_graphical = False
-
-
-class Patch:
- def __init__(self, width=0.0, height=0.0, position=0.0):
- self.width = width
- self.height = height
- self.position = position
-
- @property
- def points(self):
- return [
- [self.position, -self.height / 2],
- [self.position + self.width, -self.height / 2],
- [self.position + self.width, self.height / 2],
- [self.position, self.height / 2],
- ]
-
-
-class Line:
- def __init__(self, length=0.0, width=0.0, position=0.0):
- self.length = length
- self.width = width
- self.position = position
-
- @property
- def points(self):
- return [
- [self.position, -self.width / 2],
- [self.position + self.length, -self.width / 2],
- [self.position + self.length, self.width / 2],
- [self.position, self.width / 2],
- ]
-
-
-class LinearArray:
- def __init__(self, nb_patch=1, array_length=10e-3, array_width=5e-3):
- self.nbpatch = nb_patch
- self.length = array_length
- self.width = array_width
-
- @property
- def points(self):
- return [
- [-1e-3, -self.width / 2 - 1e-3],
- [self.length + 1e-3, -self.width / 2 - 1e-3],
- [self.length + 1e-3, self.width / 2 + 1e-3],
- [-1e-3, self.width / 2 + 1e-3],
- ]
-
-
-tmpfold = tempfile.gettempdir()
-aedb_path = os.path.join(tmpfold, pyedb.generate_unique_name("pcb") + ".aedb")
-print(aedb_path)
-edb = pyedb.Edb(edbpath=aedb_path, edbversion="2023.2")
-
-
-###############################################################################
-# Add stackup layers
-# ~~~~~~~~~~~~~~~~~~
-# Add the stackup layers.
-#
-if edb:
- edb.stackup.add_layer("Virt_GND")
- edb.stackup.add_layer("Gap", "Virt_GND", layer_type="dielectric", thickness="0.05mm", material="Air")
- edb.stackup.add_layer("GND", "Gap")
- edb.stackup.add_layer("Substrat", "GND", layer_type="dielectric", thickness="0.5mm", material="Duroid (tm)")
- edb.stackup.add_layer("TOP", "Substrat")
-
-###############################################################################
-# Create linear array
-# ~~~~~~~~~~~~~~~~~~~
-# Create the first patch of the linear array.
-
-first_patch = Patch(width=1.4e-3, height=1.2e-3, position=0.0)
-edb.modeler.create_polygon(first_patch.points, "TOP", net_name="Array_antenna")
-# First line
-first_line = Line(length=2.4e-3, width=0.3e-3, position=first_patch.width)
-edb.modeler.create_polygon(first_line.points, "TOP", net_name="Array_antenna")
-
-###############################################################################
-# Patch linear array
-# ~~~~~~~~~~~~~~~~~~
-# Patch the linear array.
-
-patch = Patch(width=2.29e-3, height=3.3e-3)
-line = Line(length=1.9e-3, width=0.2e-3)
-linear_array = LinearArray(nb_patch=8, array_width=patch.height)
-
-current_patch = 1
-current_position = first_line.position + first_line.length
-
-while current_patch <= linear_array.nbpatch:
- patch.position = current_position
- edb.modeler.create_polygon(patch.points, "TOP", net_name="Array_antenna")
- current_position += patch.width
- if current_patch < linear_array.nbpatch:
- line.position = current_position
- edb.modeler.create_polygon(line.points, "TOP", net_name="Array_antenna")
- current_position += line.length
- current_patch += 1
-
-linear_array.length = current_position
-
-
-###############################################################################
-# Add ground
-# ~~~~~~~~~~
-# Add a ground.
-
-edb.modeler.create_polygon(linear_array.points, "GND", net_name="GND")
-
-
-###############################################################################
-# Add connector pin
-# ~~~~~~~~~~~~~~~~~
-# Add a central connector pin.
-
-edb.padstacks.create(padstackname="Connector_pin", holediam="100um", paddiam="0", antipaddiam="200um")
-con_pin = edb.padstacks.place(
- [first_patch.width / 4, 0],
- "Connector_pin",
- net_name="Array_antenna",
- fromlayer="TOP",
- tolayer="GND",
- via_name="coax",
-)
-
-
-###############################################################################
-# Add connector ground
-# ~~~~~~~~~~~~~~~~~~~~
-# Add a connector ground.
-
-edb.modeler.create_polygon(first_patch.points, "Virt_GND", net_name="GND")
-edb.padstacks.create("gnd_via", "100um", "0", "0")
-con_ref1 = edb.padstacks.place(
- [first_patch.points[0][0] + 0.2e-3, first_patch.points[0][1] + 0.2e-3],
- "gnd_via",
- fromlayer="GND",
- tolayer="Virt_GND",
- net_name="GND",
-)
-con_ref2 = edb.padstacks.place(
- [first_patch.points[1][0] - 0.2e-3, first_patch.points[1][1] + 0.2e-3],
- "gnd_via",
- fromlayer="GND",
- tolayer="Virt_GND",
- net_name="GND",
-)
-con_ref3 = edb.padstacks.place(
- [first_patch.points[2][0] - 0.2e-3, first_patch.points[2][1] - 0.2e-3],
- "gnd_via",
- fromlayer="GND",
- tolayer="Virt_GND",
- net_name="GND",
-)
-con_ref4 = edb.padstacks.place(
- [first_patch.points[3][0] + 0.2e-3, first_patch.points[3][1] - 0.2e-3],
- "gnd_via",
- fromlayer="GND",
- tolayer="Virt_GND",
- net_name="GND",
-)
-
-
-###############################################################################
-# Add excitation port
-# ~~~~~~~~~~~~~~~~~~~
-# Add an excitation port.
-
-edb.padstacks.set_solderball(con_pin, "Virt_GND", isTopPlaced=False, ballDiam=0.1e-3)
-port_name = edb.padstacks.create_coax_port(con_pin)
-
-
-###############################################################################
-# Plot geometry
-# ~~~~~~~~~~~~~
-# Plot the geometry.
-
-edb.nets.plot(None)
-
-###############################################################################
-# Save and close Edb instance prior to opening it in Electronics Desktop.
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Save EDB.
-
-edb.save_edb()
-edb.close_edb()
-print("EDB saved correctly to {}. You can import in AEDT.".format(aedb_path))
-###############################################################################
-# Launch HFSS 3D Layout and open EDB
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Launch HFSS 3D Layout and open EDB.
-
-h3d = pyedb.Hfss3dLayout(projectname=aedb_path, specified_version="2023.2", new_desktop_session=True,
- non_graphical=non_graphical)
-
-###############################################################################
-# Plot geometry
-# ~~~~~~~~~~~~~~~~~
-# Plot the geometry. The EDB methods are also accessible from the ``Hfss3dlayout`` class.
-
-h3d.modeler.edb.nets.plot(None)
-
-###############################################################################
-# Create setup and sweeps
-# ~~~~~~~~~~~~~~~~~~~~~~~
-# Getters and setters facilitate the settings on the nested property dictionary.
-# Previously, you had to use these commands:
-#
-# - ``setup.props["AdaptiveSettings"]["SingleFrequencyDataList"]["AdaptiveFrequencyData"]["AdaptiveFrequency"] = "20GHz"``
-# - ``setup.props["AdaptiveSettings"]["SingleFrequencyDataList"]["AdaptiveFrequencyData"]["MaxPasses"] = 4``
-#
-# You can now use the simpler approach that follows.
-
-setup = h3d.create_setup()
-
-setup["AdaptiveFrequency"] = "20GHz"
-setup["AdaptiveSettings/SingleFrequencyDataList/AdaptiveFrequencyData/MaxPasses"] = 4
-h3d.create_linear_count_sweep(
- setupname=setup.name,
- unit="GHz",
- freqstart=20,
- freqstop=50,
- num_of_freq_points=1001,
- sweepname="sweep1",
- sweep_type="Interpolating",
- interpolation_tol_percent=1,
- interpolation_max_solutions=255,
- save_fields=False,
- use_q3d_for_dc=False,
-)
-
-
-###############################################################################
-# Solve setup and create report
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Solve the project and create a report.
-
-h3d.analyze()
-h3d.post.create_report(["db(S({0},{1}))".format(port_name, port_name)])
-
-
-###############################################################################
-# Plot results outside AEDT
-# ~~~~~~~~~~~~~~~~~~~~~~~~~
-# Plot results using Matplotlib.
-
-solution = h3d.post.get_solution_data(["S({0},{1})".format(port_name, port_name)])
-solution.plot()
-
-###############################################################################
-# Close AEDT
-# ~~~~~~~~~~
-# After the simulation completes, you can close AEDT or release it using the
-# :func:`legacy.Desktop.release_desktop` method.
-# All methods provide for saving the project before closing AEDT.
-
-h3d.save_project()
-h3d.release_desktop()
diff --git a/examples/00-EDB/03_5G_antenna_example_parametrics.py b/examples/00-EDB/03_5G_antenna_example_parametrics.py
deleted file mode 100644
index 4bdb1af808..0000000000
--- a/examples/00-EDB/03_5G_antenna_example_parametrics.py
+++ /dev/null
@@ -1,399 +0,0 @@
-"""
-EDB: Layout Components
-----------------------
-This example shows how you can use EDB to create a layout component parametrics and use it in HFSS 3D.
-"""
-
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Perform required imports, which includes importing the ``Hfss3dlayout`` object
-# and initializing it on version 2023 R2.
-
-import tempfile
-import pyedb
-import os
-
-
-##########################################################
-# Set non-graphical mode
-# ~~~~~~~~~~~~~~~~~~~~~~
-# Set non-graphical mode. The default is ``False``.
-
-
-
-non_graphical = False
-
-##########################################################
-# Creating data classes
-# ~~~~~~~~~~~~~~~~~~~~~
-# Data classes are useful to do calculations and store variables.
-# We create 3 Data classes for Patch, Line and Array
-
-class Patch:
- def __init__(self, width=0.0, height=0.0, position=0.0):
- self.width = width
- self.height = height
- self.position = position
-
- @property
- def points(self):
- return [
- [self.position, "-{}/2".format(self.height)],
- ["{} + {}".format(self.position, self.width), "-{}/2".format(self.height)],
- ["{} + {}".format(self.position, self.width), "{}/2".format(self.height)],
- [self.position, "{}/2".format(self.height)],
- ]
-
-
-class Line:
- def __init__(self, length=0.0, width=0.0, position=0.0):
- self.length = length
- self.width = width
- self.position = position
-
- @property
- def points(self):
- return [
- [self.position, "-{}/2".format(self.width)],
- ["{} + {}".format(self.position, self.length), "-{}/2".format(self.width)],
- ["{} + {}".format(self.position, self.length), "{}/2".format(self.width)],
- [self.position, "{}/2".format(self.width)],
- ]
-
-
-class LinearArray:
- def __init__(self, nb_patch=1, array_length=10e-3, array_width=5e-3):
- self.nbpatch = nb_patch
- self.length = array_length
- self.width = array_width
-
- @property
- def points(self):
- return [
- [-1e-3, "-{}/2-1e-3".format(self.width)],
- ["{}+1e-3".format(self.length), "-{}/2-1e-3".format(self.width)],
- ["{}+1e-3".format(self.length), "{}/2+1e-3".format(self.width)],
- [-1e-3, "{}/2+1e-3".format(self.width)],
- ]
-
-###############################################################################
-# Launch EDB
-# ~~~~~~~~~~
-# PyAEDT.Edb allows to open existing Edb project or create a new empty project.
-
-
-tmpfold = tempfile.gettempdir()
-aedb_path = os.path.join(tmpfold, pyedb.generate_unique_name("pcb") + ".aedb")
-print(aedb_path)
-edb = pyedb.Edb(edbpath=aedb_path, edbversion="2023.2")
-
-###############################################################################
-# Add stackup layers
-# ~~~~~~~~~~~~~~~~~~
-# Add the stackup layers.
-
-
-
-edb.stackup.add_layer("Virt_GND")
-edb.stackup.add_layer("Gap", "Virt_GND", layer_type="dielectric", thickness="0.05mm", material="Air")
-edb.stackup.add_layer("GND", "Gap")
-edb.stackup.add_layer("Substrat", "GND", layer_type="dielectric", thickness="0.5mm", material="Duroid (tm)")
-edb.stackup.add_layer("TOP", "Substrat")
-
-###############################################################################
-# Create linear array
-# ~~~~~~~~~~~~~~~~~~~
-# Create the first patch of the linear array.
-
-
-
-edb["w1"] = 1.4e-3
-edb["h1"] = 1.2e-3
-edb["initial_position"] = 0.0
-edb["l1"] = 2.4e-3
-edb["trace_w"] = 0.3e-3
-first_patch = Patch(width="w1", height="h1", position="initial_position")
-edb.modeler.create_polygon(first_patch.points, "TOP", net_name="Array_antenna")
-# First line
-
-first_line = Line(length="l1", width="trace_w", position=first_patch.width)
-edb.modeler.create_polygon(first_line.points, "TOP", net_name="Array_antenna")
-
-###############################################################################
-# Patch linear array
-# ~~~~~~~~~~~~~~~~~~
-# Patch the linear array.
-
-
-edb["w2"] = 2.29e-3
-edb["h2"] = 3.3e-3
-edb["l2"] = 1.9e-3
-edb["trace_w2"] = 0.2e-3
-
-patch = Patch(width="w2", height="h2")
-line = Line(length="l2", width="trace_w2")
-linear_array = LinearArray(nb_patch=8, array_width=patch.height)
-
-current_patch = 1
-current_position = "{} + {}".format(first_line.position, first_line.length)
-
-while current_patch <= linear_array.nbpatch:
- patch.position = current_position
- edb.modeler.create_polygon(patch.points, "TOP", net_name="Array_antenna")
- current_position = "{} + {}".format(current_position, patch.width)
- if current_patch < linear_array.nbpatch:
- line.position = current_position
- edb.modeler.create_polygon(line.points, "TOP", net_name="Array_antenna")
- current_position = "{} + {}".format(current_position, line.length)
- current_patch += 1
-
-linear_array.length = current_position
-
-###############################################################################
-# Add ground
-# ~~~~~~~~~~
-# Add a ground.
-
-
-edb.modeler.create_polygon(linear_array.points, "GND", net_name="GND")
-
-###############################################################################
-# Add connector pin
-# ~~~~~~~~~~~~~~~~~
-# Add a central connector pin.
-
-
-edb.padstacks.create(padstackname="Connector_pin", holediam="100um", paddiam="0", antipaddiam="200um")
-con_pin = edb.padstacks.place(
- ["{}/4.0".format(first_patch.width), 0],
- "Connector_pin",
- net_name="Array_antenna",
- fromlayer="TOP",
- tolayer="GND",
- via_name="coax",
-)
-
-###############################################################################
-# Add connector ground
-# ~~~~~~~~~~~~~~~~~~~~
-# Add a connector ground.
-
-
-edb.modeler.create_polygon(first_patch.points, "Virt_GND", net_name="GND")
-edb.padstacks.create("gnd_via", "100um", "0", "0")
-edb["via_spacing"] = 0.2e-3
-con_ref1 = edb.padstacks.place(
- ["{} + {}".format(first_patch.points[0][0], "via_spacing"), "{} + {}".format(first_patch.points[0][1], "via_spacing")],
- "gnd_via",
- fromlayer="GND",
- tolayer="Virt_GND",
- net_name="GND",
-)
-con_ref2 = edb.padstacks.place(
- ["{} + {}".format(first_patch.points[1][0], "-via_spacing"), "{} + {}".format(first_patch.points[1][1], "via_spacing")],
- "gnd_via",
- fromlayer="GND",
- tolayer="Virt_GND",
- net_name="GND",
-)
-con_ref3 = edb.padstacks.place(
- ["{} + {}".format(first_patch.points[2][0], "-via_spacing"), "{} + {}".format(first_patch.points[2][1], "-via_spacing")],
- "gnd_via",
- fromlayer="GND",
- tolayer="Virt_GND",
- net_name="GND",
-)
-con_ref4 = edb.padstacks.place(
- ["{} + {}".format(first_patch.points[3][0], "via_spacing"), "{} + {}".format(first_patch.points[3][1], "-via_spacing")],
- "gnd_via",
- fromlayer="GND",
- tolayer="Virt_GND",
- net_name="GND",
-)
-
-
-################################################################################
-# Add excitation port
-# ~~~~~~~~~~~~~~~~~~~
-# Add an excitation port.
-
-
-edb.padstacks.set_solderball(con_pin, "Virt_GND", isTopPlaced=False, ballDiam=0.1e-3)
-port_name = edb.padstacks.create_coax_port(con_pin)
-
-
-###############################################################################
-# Plot geometry
-# ~~~~~~~~~~~~~
-# Plot the geometry.
-
-
-edb.nets.plot()
-
-
-###############################################################################
-# Save and close Edb instance prior to opening it in Electronics Desktop.
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Save EDB.
-
-
-edb.save_edb()
-edb.close_edb()
-print("EDB saved correctly to {}. You can import in AEDT.".format(aedb_path))
-
-
-###############################################################################
-# Launch HFSS 3D
-# ~~~~~~~~~~~~~~
-# Launch HFSS 3D.
-
-h3d = pyedb.Hfss(specified_version="2023.2", new_desktop_session=True, close_on_exit=True, solution_type="Terminal")
-
-
-###############################################################################
-# Add the layout component
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Hfss allows user to add Layout components (aedb) or 3D Components into a 3D Design
-# and benefit of different functionalities like parametrization, mesh fusion and others.
-
-
-component = h3d.modeler.insert_layout_component(aedb_path, parameter_mapping=True)
-
-###############################################################################
-# Edit Parameters
-# ~~~~~~~~~~~~~~~
-# If a layout component is parametric, parameters can be exposed and changed in HFSS
-
-
-component.parameters
-
-w1_name = "{}_{}".format("w1", h3d.modeler.user_defined_component_names[0])
-h3d[w1_name]= 0.0015
-
-###############################################################################
-# Boundaries
-# ~~~~~~~~~~
-# To run the simulation we need an airbox to which apply radiation boundaries.
-# We don't need to create ports because are embedded in layout component.
-
-
-h3d.modeler.fit_all()
-
-
-h3d.modeler.create_air_region(130,400,1000, 130,400,300)
-h3d.assign_radiation_boundary_to_objects("Region")
-
-###############################################################################
-# Create setup and sweeps
-# ~~~~~~~~~~~~~~~~~~~~~~~
-# Getters and setters facilitate the settings on the nested property dictionary.
-#
-# - ``setup.props['Frequency']="20GHz"``
-#
-#
-# You can now use the simpler approach that follows.
-#
-#
-
-
-setup = h3d.create_setup()
-
-setup.props['Frequency']="20GHz"
-setup.props['MaximumPasses'] = 2
-
-sweep1 = setup.add_sweep()
-sweep1.props["RangeStart"]="20GHz"
-sweep1.props["RangeEnd"]="50GHz"
-sweep1.update()
-
-###############################################################################
-# Solve setup and create report
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Solve the project and create a report.
-
-
-
-h3d.analyze()
-
-
-
-
-###############################################################################
-# Plot results outside AEDT
-# ~~~~~~~~~~~~~~~~~~~~~~~~~
-# Plot results using Matplotlib.
-
-trace = h3d.get_traces_for_plot()
-solution = h3d.post.get_solution_data(trace[0])
-solution.plot()
-
-
-################################################################################
-# Plot Far Fields in AEDT
-# ~~~~~~~~~~~~~~~~~~~~~~~
-# Plot Radiation patterns in AEDT.
-
-
-variations = {}
-variations["Freq"] = ["20GHz"]
-variations["Theta"] = ["All"]
-variations["Phi"] = ["All"]
-h3d.insert_infinite_sphere( name="3D")
-
-
-new_report = h3d.post.reports_by_category.far_field("db(RealizedGainTotal)", h3d.nominal_adaptive, "3D")
-new_report.variations = variations
-new_report.primary_sweep = "Theta"
-new_report.create("Realized2D")
-
-
-################################################################################
-# Plot Far Fields in AEDT
-# ~~~~~~~~~~~~~~~~~~~~~~~
-# Plot Radiation patterns in AEDT.
-
-
-
-new_report.report_type = "3D Polar Plot"
-new_report.secondary_sweep = "Phi"
-new_report.create("Realized3D")
-
-
-################################################################################
-# Plot Far Fields outside AEDT
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Plot Radiation patterns outside AEDT.
-
-
-
-solutions_custom = new_report.get_solution_data()
-solutions_custom.plot_3d()
-
-################################################################################
-# Plot E Field on nets and layers
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Plot E Field on nets and layers in AEDT.
-
-
-h3d.post.create_fieldplot_layers_nets(
- [["TOP","Array_antenna"]],
- "Mag_E",
- intrinsics={"Freq":"20GHz", "Phase": "0deg"},
- plot_name="E_Layers",
- )
-
-
-###############################################################################
-# Close AEDT
-# ~~~~~~~~~~
-# After the simulation completes, you can close AEDT or release it using the
-# :func:`legacy.Desktop.release_desktop` method.
-# All methods provide for saving the project before closing AEDT.
-
-
-h3d.save_project(os.path.join(tmpfold, "test_layout.aedt"))
-h3d.release_desktop()
-
-
-
diff --git a/examples/00-EDB/04_edb_parametrized_design.py b/examples/00-EDB/04_edb_parametrized_design.py
deleted file mode 100644
index a120f65899..0000000000
--- a/examples/00-EDB/04_edb_parametrized_design.py
+++ /dev/null
@@ -1,342 +0,0 @@
-"""
-EDB: fully parametrized design
-------------------------------
-This example shows how you can use HFSS 3D Layout to create and solve a parametric design.
-"""
-
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Perform required imports, which includes importing the ``Hfss3dlayout`` object
-# and initializing it on version 2023 R2.
-
-import pyedb
-import os
-
-##########################################################
-# Set non-graphical mode
-# ~~~~~~~~~~~~~~~~~~~~~~
-# Set non-graphical mode. The default is ``False``.
-
-non_graphical = False
-
-##########################################################
-# Launch EDB
-# ~~~~~~~~~~
-# Launch EDB.
-
-aedb_path = os.path.join(pyedb.generate_unique_folder_name(), pyedb.generate_unique_name("pcb") + ".aedb")
-print(aedb_path)
-edb = pyedb.Edb(edbpath=aedb_path, edbversion="2023.2")
-
-######################################################################
-# Define parameters
-# ~~~~~~~~~~~~~~~~~
-# Define the parameters.
-
-params = {"$ms_width": "0.4mm",
- "$sl_width": "0.2mm",
- "$ms_spacing": "0.2mm",
- "$sl_spacing": "0.1mm",
- "$via_spacing": "0.5mm",
- "$via_diam": "0.3mm",
- "$pad_diam": "0.6mm",
- "$anti_pad_diam": "0.7mm",
- "$pcb_len": "30mm",
- "$pcb_w": "5mm",
- "$x_size": "1.2mm",
- "$y_size": "1mm",
- "$corner_rad": "0.5mm"}
-
-for par_name in params:
- edb.add_project_variable(par_name, params[par_name])
-
-######################################################################
-# Define stackup layers
-# ~~~~~~~~~~~~~~~~~~~~~
-# Define the stackup layers from bottom to top.
-
-
-layers = [{"name": "bottom", "layer_type": "signal", "thickness": "35um", "material": "copper"},
- {"name": "diel_3", "layer_type": "dielectric", "thickness": "275um", "material": "FR4_epoxy"},
- {"name": "sig_2", "layer_type": "signal", "thickness": "35um", "material": "copper"},
- {"name": "diel_2", "layer_type": "dielectric", "thickness": "275um", "material": "FR4_epoxy"},
- {"name": "sig_1", "layer_type": "signal", "thickness": "35um", "material": "copper"},
- {"name": "diel_1", "layer_type": "dielectric", "thickness": "275um", "material": "FR4_epoxy"},
- {"name": "top", "layer_type": "signal", "thickness": "35um", "material": "copper"}]
-
-
-# Create EDB stackup.
-# Bottom layer
-prev = None
-for layer in layers:
- edb.stackup.add_layer(layer["name"], base_layer=prev, layer_type=layer["layer_type"], thickness=layer["thickness"],
- material=layer["material"])
- prev = layer["name"]
-
-###############################################################################
-# Create padstack for signal via
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Create a parametrized padstack for the signal via.
-
-signal_via_padstack = "automated_via"
-edb.padstacks.create(
- padstackname=signal_via_padstack,
- holediam="$via_diam",
- paddiam="$pad_diam",
- antipaddiam="",
- antipad_shape="Bullet",
- x_size="$x_size",
- y_size="$y_size",
- corner_radius="$corner_rad",
- start_layer=layers[-1]["name"],
- stop_layer=layers[-3]["name"]
- )
-
-###############################################################################
-# Assign net names
-# ~~~~~~~~~~~~~~~~
-# # Assign net names. There are only two signal nets.
-
-net_p = "p"
-net_n = "n"
-
-###############################################################################
-# Place signal vias
-# ~~~~~~~~~~~~~~~~~
-# Place signal vias.
-
-edb.padstacks.place(
- position=["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"],
- definition_name=signal_via_padstack,
- net_name=net_p,
- via_name="",
- rotation=90.0
-)
-
-edb.padstacks.place(
- position=["2*$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"],
- definition_name=signal_via_padstack,
- net_name=net_p,
- via_name="",
- rotation=90.0,
-)
-
-edb.padstacks.place(
- position=["$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"],
- definition_name=signal_via_padstack,
- net_name=net_n,
- via_name="",
- rotation=-90.0,
-)
-
-edb.padstacks.place(
- position=["2*$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"],
- definition_name=signal_via_padstack,
- net_name=net_n,
- via_name="",
- rotation=-90.0,
-)
-
-
-# ###############################################################################
-# Draw parametrized traces
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Draw parametrized traces.
-# Trace the width and the routing (Microstrip-Stripline-Microstrip).
-# Applies to both p and n nets.
-
-width = ["$ms_width", "$sl_width", "$ms_width"] # Trace width, n and p
-route_layer = [layers[-1]["name"], layers[4]["name"], layers[-1]["name"]] # Routing layer, n and p
-
-# Define points for three traces in the "p" net
-
-points_p = [
- [["0.0", "($ms_width+$ms_spacing)/2"],
- ["$pcb_len/3-2*$via_spacing", "($ms_width+$ms_spacing)/2"],
- ["$pcb_len/3-$via_spacing", "($ms_width+$ms_spacing+$via_spacing)/2"],
- ["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"],
- ],
- [["$pcb_len/3", "($ms_width+$sl_spacing+$via_spacing)/2"],
- ["$pcb_len/3+$via_spacing", "($ms_width+$sl_spacing+$via_spacing)/2"],
- ["$pcb_len/3+2*$via_spacing", "($sl_width+$sl_spacing)/2"],
- ["2*$pcb_len/3-2*$via_spacing", "($sl_width+$sl_spacing)/2"],
- ["2*$pcb_len/3-$via_spacing", "($ms_width+$sl_spacing+$via_spacing)/2"],
- ["2*$pcb_len/3", "($ms_width+$sl_spacing+$via_spacing)/2"],
- ],
- [["2*$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing)/2"],
- ["2*$pcb_len/3+$via_spacing", "($ms_width+$ms_spacing+$via_spacing)/2"],
- ["2*$pcb_len/3+2*$via_spacing", "($ms_width+$ms_spacing)/2"],
- ["$pcb_len", "($ms_width+$ms_spacing)/2"],
- ],
- ]
-
-# Define points for three traces in the "n" net
-
-points_n = [
- [["0.0", "-($ms_width+$ms_spacing)/2"],
- ["$pcb_len/3-2*$via_spacing", "-($ms_width+$ms_spacing)/2"],
- ["$pcb_len/3-$via_spacing", "-($ms_width+$ms_spacing+$via_spacing)/2"],
- ["$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"],
- ],
- [["$pcb_len/3", "-($ms_width+$sl_spacing+$via_spacing)/2"],
- ["$pcb_len/3+$via_spacing", "-($ms_width+$sl_spacing+$via_spacing)/2"],
- ["$pcb_len/3+2*$via_spacing", "-($ms_width+$sl_spacing)/2"],
- ["2*$pcb_len/3-2*$via_spacing", "-($ms_width+$sl_spacing)/2"],
- ["2*$pcb_len/3-$via_spacing", "-($ms_width+$sl_spacing+$via_spacing)/2"],
- ["2*$pcb_len/3", "-($ms_width+$sl_spacing+$via_spacing)/2"],
- ],
- [["2*$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing)/2"],
- ["2*$pcb_len/3 + $via_spacing", "-($ms_width+$ms_spacing+$via_spacing)/2"],
- ["2*$pcb_len/3 + 2*$via_spacing", "-($ms_width+$ms_spacing)/2"],
- ["$pcb_len", "-($ms_width + $ms_spacing)/2"],
- ],
- ]
-# ###############################################################################
-# Add traces to EDB
-# ~~~~~~~~~~~~~~~~~
-# Add traces to EDB.
-
-trace_p = []
-trace_n = []
-for n in range(len(points_p)):
- trace_p.append(edb.modeler.create_trace(points_p[n], route_layer[n], width[n], net_p, "Flat", "Flat"))
- trace_n.append(edb.modeler.create_trace(points_n[n], route_layer[n], width[n], net_n, "Flat", "Flat"))
-
-###############################################################################
-# Create wave ports
-# ~~~~~~~~~~~~~~~~~
-# Create wave ports:
-
-edb.hfss.create_differential_wave_port(trace_p[0].id, ["0.0", "($ms_width+$ms_spacing)/2"],
- trace_n[0].id, ["0.0", "-($ms_width+$ms_spacing)/2"],
- "wave_port_1")
-edb.hfss.create_differential_wave_port(trace_p[2].id, ["$pcb_len", "($ms_width+$ms_spacing)/2"],
- trace_n[2].id, ["$pcb_len", "-($ms_width + $ms_spacing)/2"],
- "wave_port_2")
-
-###############################################################################
-# Draw ground polygons
-# ~~~~~~~~~~~~~~~~~~~~
-# Draw ground polygons.
-
-gnd_poly = [[0.0, "-$pcb_w/2"],
- ["$pcb_len", "-$pcb_w/2"],
- ["$pcb_len", "$pcb_w/2"],
- [0.0, "$pcb_w/2"]]
-gnd_shape = edb.modeler.Shape("polygon", points=gnd_poly)
-
-# Void in ground for traces on the signal routing layer
-
-void_poly = [["$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2"],
- ["$pcb_len/3 + $via_spacing", "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2"],
- ["$pcb_len/3 + 2*$via_spacing",
- "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"],
- ["2*$pcb_len/3 - 2*$via_spacing",
- "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"],
- ["2*$pcb_len/3 - $via_spacing",
- "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2"],
- ["2*$pcb_len/3", "-($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2-$via_spacing/2"],
- ["2*$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2"],
- ["2*$pcb_len/3 - $via_spacing", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2"],
- ["2*$pcb_len/3 - 2*$via_spacing", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"],
- ["$pcb_len/3 + 2*$via_spacing", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"],
- ["$pcb_len/3 + $via_spacing", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2"],
- ["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2+$via_spacing/2"],
- ["$pcb_len/3", "($ms_width+$ms_spacing+$via_spacing+$anti_pad_diam)/2"]]
-
-void_shape = edb.modeler.Shape("polygon", points=void_poly)
-
-# Add ground layers
-
-for layer in layers[:-1:2]:
-
- # add void if the layer is the signal routing layer.
- void = [void_shape] if layer["name"] == route_layer[1] else []
-
- edb.modeler.create_polygon(main_shape=gnd_shape,
- layer_name=layer["name"],
- voids=void,
- net_name="gnd")
-
-
-###############################################################################
-# Plot EDB
-# ~~~~~~~~
-# Plot EDB.
-
-edb.nets.plot(None)
-
-###############################################################################
-# Save EDB
-# ~~~~~~~~
-# Save EDB.
-
-edb.save_edb()
-edb.close_edb()
-
-
-###############################################################################
-# Open EDB in AEDT
-# ~~~~~~~~~~~~~~~~
-# Open EDB in AEDT.
-
-h3d = pyedb.Hfss3dLayout(projectname=aedb_path, specified_version="2023.2",
- non_graphical=non_graphical, new_desktop_session=True)
-
-###############################################################################
-# Add HFSS simulation setup
-# ~~~~~~~~~~~~~~~~~~~~~~~~~
-# Add HFSS simulation setup.
-
-setup = h3d.create_setup()
-setup.props["AdaptiveSettings"]["SingleFrequencyDataList"]["AdaptiveFrequencyData"]["MaxPasses"] = 3
-
-h3d.create_linear_count_sweep(
- setupname=setup.name,
- unit="GHz",
- freqstart=0,
- freqstop=10,
- num_of_freq_points=1001,
- sweepname="sweep1",
- sweep_type="Interpolating",
- interpolation_tol_percent=1,
- interpolation_max_solutions=255,
- save_fields=False,
- use_q3d_for_dc=False,
-)
-
-###############################################################################
-# Set Differential Pairs.
-# ~~~~~~~~~~~~~~~~~~~~~~
-# Define the differential pairs to be used in the postprocessing.
-h3d.set_differential_pair(diff_name="In", positive_terminal="wave_port_1:T1", negative_terminal="wave_port_1:T2")
-h3d.set_differential_pair(diff_name="Out", positive_terminal="wave_port_2:T1", negative_terminal="wave_port_2:T2")
-
-###############################################################################
-# Start HFSS solver
-# ~~~~~~~~~~~~~~~~~
-# Start the HFSS solver by uncommenting the ``h3d.analyze()`` command.
-
-h3d.analyze()
-
-
-###############################################################################
-# Generate Plot
-# ~~~~~~~~~~~~~
-# Generate the plot of differential pairs.
-
-solutions = h3d.post.get_solution_data(["dB(S(In,In))", "dB(S(In,Out))"], context="Differential Pairs")
-solutions.plot()
-
-
-
-
-
-h3d.release_desktop()
-
-###############################################################################
-# Note that the ground nets are only connected to each other due
-# to the wave ports. The problem with poor grounding can be seen in the
-# S-parameters. Try to modify this script to add ground vias and eliminate
-# the resonance.
diff --git a/examples/00-EDB/05_Plot_nets.py b/examples/00-EDB/05_Plot_nets.py
deleted file mode 100644
index c9decc887e..0000000000
--- a/examples/00-EDB/05_Plot_nets.py
+++ /dev/null
@@ -1,64 +0,0 @@
-"""
-EDB: plot nets with Matplotlib
-------------------------------
-This example shows how you can use the ``Edb`` class to plot a net or a layout.
-"""
-
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Perform required imports, which includes importing a section.
-
-import pyedb
-
-###############################################################################
-# Download file
-# ~~~~~~~~~~~~~
-# Download the AEDT file and copy it into the temporary folder.
-
-temp_folder = pyedb.generate_unique_folder_name()
-
-targetfolder = pyedb.downloads.download_file('edb/ANSYS-HSD_V1.aedb', destination=temp_folder)
-
-
-###############################################################################
-# Launch EDB
-# ~~~~~~~~~~
-# Launch the :class:`legacy.Edb` class, using EDB 2023 R2 and SI units.
-
-edb = pyedb.Edb(edbpath=targetfolder, edbversion="2023.2")
-
-###############################################################################
-# Plot custom set of nets colored by layer
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Plot a custom set of nets colored by layer (default).
-
-edb.nets.plot("AVCC_1V3")
-
-###############################################################################
-# Plot custom set of nets colored by nets
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Plot a custom set of nets colored by nets.
-
-edb.nets.plot(["GND", "GND_DP", "AVCC_1V3"], color_by_net=True)
-
-###############################################################################
-# Plot all nets on a layer colored by nets
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Plot all nets on a layer colored by nets
-
-edb.nets.plot(None, ["1_Top"], color_by_net=True, plot_components_on_top=True)
-
-###############################################################################
-# Plot stackup and some padstack definition
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Plot all nets on a layer colored by nets
-
-edb.stackup.plot(scale_elevation=False,plot_definitions=["c100hn140", "c35"])
-
-###############################################################################
-# Close EDB
-# ~~~~~~~~~
-# Close EDB.
-
-edb.close_edb()
diff --git a/examples/00-EDB/06_Advanced_EDB.py b/examples/00-EDB/06_Advanced_EDB.py
deleted file mode 100644
index 7f4e01194d..0000000000
--- a/examples/00-EDB/06_Advanced_EDB.py
+++ /dev/null
@@ -1,179 +0,0 @@
-"""
-EDB: parametric via creation
-----------------------------
-This example shows how you can use EDB to create a layout.
-"""
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Perform required imports.
-
-import os
-import numpy as np
-import pyedb
-
-
-aedb_path = os.path.join(pyedb.generate_unique_folder_name(), pyedb.generate_unique_name("via_opt") + ".aedb")
-
-###############################################################################
-# Create stackup
-# ~~~~~~~~~~~~~~
-# The ``StackupSimple`` class creates a stackup based on few inputs. This stackup
-# is used later.
-
-
-###############################################################################
-# Create ground plane
-# ~~~~~~~~~~~~~~~~~~~
-# Create a ground plane on specific layers.
-
-def _create_ground_planes(edb, layers):
- plane = edb.modeler.Shape("rectangle", pointA=["-3mm", "-3mm"], pointB=["3mm", "3mm"])
- for i in layers:
- edb.modeler.create_polygon(plane, i, net_name="GND")
-
-
-##################################################################################
-# Create EDB
-# ~~~~~~~~~~
-# Create EDB. If the path doesn't exist, PyAEDT automatically generates a new AEDB folder.
-
-edb = pyedb.Edb(edbpath=aedb_path, edbversion="2023.2")
-
-##################################################################################
-# Create stackup layers
-# ~~~~~~~~~~~~~~~~~~~~~
-# Create stackup layers.
-
-layout_count = 12
-diel_material_name = "FR4_epoxy"
-diel_thickness = "0.15mm"
-cond_thickness_outer = "0.05mm"
-cond_thickness_inner = "0.017mm"
-soldermask_thickness = "0.05mm"
-trace_in_layer = "TOP"
-trace_out_layer = "L10"
-gvia_num = 10
-gvia_angle = 30
-edb.stackup.create_symmetric_stackup(layer_count=layout_count, inner_layer_thickness=cond_thickness_inner,
- outer_layer_thickness=cond_thickness_outer,
- soldermask_thickness=soldermask_thickness, dielectric_thickness=diel_thickness,
- dielectric_material=diel_material_name)
-
-
-##################################################################################
-# Create variables
-# ~~~~~~~~~~~~~~~~
-# Create all variables. If a variable has a ``$`` prefix, it is a project variable.
-# Otherwise, is a design variable.
-
-giva_angle_rad = gvia_angle / 180 * np.pi
-
-edb["$via_hole_size"] = "0.3mm"
-edb["$antipaddiam"] = "0.7mm"
-edb["$paddiam"] = "0.5mm"
-edb.add_design_variable("via_pitch", "1mm", is_parameter=True)
-edb.add_design_variable("trace_in_width", "0.2mm", is_parameter=True)
-edb.add_design_variable("trace_out_width", "0.1mm", is_parameter=True)
-
-##################################################################################
-# Create definitions
-# ~~~~~~~~~~~~~~~~~~
-# Create two definitions, one for the ground and one for the signal. The definitions
-# are parametric.
-
-edb.padstacks.create(padstackname="SVIA",
- holediam="$via_hole_size",
- antipaddiam="$antipaddiam",
- paddiam="$paddiam",
- start_layer=trace_in_layer,
- stop_layer=trace_out_layer
-)
-edb.padstacks.create(padstackname="GVIA", holediam="0.3mm", antipaddiam="0.7mm", paddiam="0.5mm")
-
-##################################################################################
-# Place padstack for signal
-# ~~~~~~~~~~~~~~~~~~~~~~~~~
-# Place the padstack for the signal.
-
-edb.padstacks.place([0, 0], "SVIA", net_name="RF")
-
-##################################################################################
-# Place padstack for ground
-# ~~~~~~~~~~~~~~~~~~~~~~~~~
-# Place the padstack for the ground. A loop iterates and places multiple ground
-# vias on different positions.
-
-gvia_num_side = gvia_num / 2
-
-if gvia_num_side % 2:
-
- # Even number of ground vias on each side
- edb.padstacks.place(["via_pitch", 0], "GVIA", net_name="GND")
- edb.padstacks.place(["via_pitch*-1", 0], "GVIA", net_name="GND")
- for i in np.arange(1, gvia_num_side / 2):
- xloc = "{}*{}".format(np.cos(giva_angle_rad * i), "via_pitch")
- yloc = "{}*{}".format(np.sin(giva_angle_rad * i), "via_pitch")
- edb.padstacks.place([xloc, yloc], "GVIA", net_name="GND")
- edb.padstacks.place([xloc, yloc + "*-1"], "GVIA", net_name="GND")
-
- edb.padstacks.place([xloc + "*-1", yloc], "GVIA", net_name="GND")
- edb.padstacks.place([xloc + "*-1", yloc + "*-1"], "GVIA", net_name="GND")
-else:
-
- # Odd number of ground vias on each side
- for i in np.arange(0, gvia_num_side / 2):
- xloc = "{}*{}".format(np.cos(giva_angle_rad * (i + 0.5)), "via_pitch")
- yloc = "{}*{}".format(np.sin(giva_angle_rad * (i + 0.5)), "via_pitch")
- edb.padstacks.place([xloc, yloc], "GVIA", net_name="GND")
- edb.padstacks.place([xloc, yloc + "*-1"], "GVIA", net_name="GND")
-
- edb.padstacks.place([xloc + "*-1", yloc], "GVIA", net_name="GND")
- edb.padstacks.place([xloc + "*-1", yloc + "*-1"], "GVIA", net_name="GND")
-
-##################################################################################
-# Generate traces
-# ~~~~~~~~~~~~~~~
-# Generate and place parametric traces.
-
-edb.modeler.create_trace(
- [[0, 0], [0, "-3mm"]], layer_name=trace_in_layer, net_name="RF", width="trace_in_width", start_cap_style="Flat", end_cap_style="Flat"
-)
-
-edb.modeler.create_trace(
- [[0, 0], [0, "3mm"]],
- layer_name=trace_out_layer,
- net_name="RF",
- width="trace_out_width",
- start_cap_style="Flat",
- end_cap_style="Flat",
-)
-
-##################################################################################
-# Generate ground layers
-# ~~~~~~~~~~~~~~~~~~~~~~
-# Generate and place ground layers.
-
-ground_layers = [i for i in edb.stackup.signal_layers.keys()]
-ground_layers.remove(trace_in_layer)
-ground_layers.remove(trace_out_layer)
-_create_ground_planes(edb=edb, layers=ground_layers)
-
-##################################################################################
-# Plot Layout
-# ~~~~~~~~~~~
-# Generate and plot the layout.
-
-#edb.nets.plot(layers=["TOP", "L10"])
-edb.stackup.plot(plot_definitions=["GVIA", "SVIA"])
-
-
-##################################################################################
-# Save EDB and close
-# ~~~~~~~~~~~~~~~~~~
-# Save EDB and close.
-
-edb.save_edb()
-edb.close_edb()
-
-print("aedb Saved in {}".format(aedb_path))
diff --git a/examples/00-EDB/08_CPWG.py b/examples/00-EDB/08_CPWG.py
deleted file mode 100644
index 6053078439..0000000000
--- a/examples/00-EDB/08_CPWG.py
+++ /dev/null
@@ -1,197 +0,0 @@
-"""
-EDB: fully parametrized CPWG design
------------------------------------
-This example shows how you can use HFSS 3D Layout to create a parametric design
-for a CPWG (coplanar waveguide with ground).
-"""
-
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Peform required imports. Importing the ``Hfss3dlayout`` object initializes it
-# on version 2023 R2.
-
-import pyedb
-import os
-import numpy as np
-
-###############################################################################
-# Set non-graphical mode
-# ~~~~~~~~~~~~~~~~~~~~~~
-# Set non-graphical mode. The default is ``False``.
-
-non_graphical = False
-
-###############################################################################
-# Launch EDB
-# ~~~~~~~~~~
-# Launch EDB.
-
-aedb_path = os.path.join(pyedb.generate_unique_folder_name(), pyedb.generate_unique_name("pcb") + ".aedb")
-print(aedb_path)
-edbapp = pyedb.Edb(edbpath=aedb_path, edbversion="2023.2")
-
-###############################################################################
-# Define parameters
-# ~~~~~~~~~~~~~~~~~
-# Define parameters.
-
-params = {"$ms_width": "0.4mm",
- "$ms_clearance": "0.3mm",
- "$ms_length": "20mm",
- }
-for par_name in params:
- edbapp.add_project_variable(par_name, params[par_name])
-
-###############################################################################
-# Create stackup
-# ~~~~~~~~~~~~~~
-# Create a symmetric stackup.
-
-edbapp.stackup.create_symmetric_stackup(2)
-edbapp.stackup.plot()
-
-###############################################################################
-# Draw planes
-# ~~~~~~~~~~~
-# Draw planes.
-
-plane_lw_pt = ["0mm", "-3mm"]
-plane_up_pt = ["$ms_length", "3mm"]
-
-top_layer_obj = edbapp.modeler.create_rectangle("TOP", net_name="gnd",
- lower_left_point=plane_lw_pt,
- upper_right_point=plane_up_pt)
-bot_layer_obj = edbapp.modeler.create_rectangle("BOTTOM", net_name="gnd",
- lower_left_point=plane_lw_pt,
- upper_right_point=plane_up_pt)
-layer_dict = {"TOP": top_layer_obj,
- "BOTTOM": bot_layer_obj}
-
-###############################################################################
-# Draw trace
-# ~~~~~~~~~~
-# Draw a trace.
-
-trace_path = [["0", "0"], ["$ms_length", "0"]]
-edbapp.modeler.create_trace(trace_path,
- layer_name="TOP",
- width="$ms_width",
- net_name="sig",
- start_cap_style="Flat",
- end_cap_style="Flat"
- )
-
-###############################################################################
-# Create trace to plane clearance
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Create a trace to the plane clearance.
-
-poly_void = edbapp.modeler.create_trace(trace_path, layer_name="TOP", net_name="gnd",
- width="{}+2*{}".format("$ms_width", "$ms_clearance"),
- start_cap_style="Flat",
- end_cap_style="Flat")
-edbapp.modeler.add_void(layer_dict["TOP"], poly_void)
-
-###############################################################################
-# Create ground via padstack and place ground stitching vias
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# Create a ground via padstack and place ground stitching vias.
-
-edbapp.padstacks.create(padstackname="GVIA",
- holediam="0.3mm",
- paddiam="0.5mm",
- )
-
-yloc_u = "$ms_width/2+$ms_clearance+0.25mm"
-yloc_l = "-$ms_width/2-$ms_clearance-0.25mm"
-
-for i in np.arange(1, 20):
- edbapp.padstacks.place([str(i) + "mm", yloc_u], "GVIA", net_name="GND")
- edbapp.padstacks.place([str(i) + "mm", yloc_l], "GVIA", net_name="GND")
-
-###############################################################################
-# Save and close EDB
-# ~~~~~~~~~~~~~~~~~~
-# Save and close EDB.
-
-edbapp.save_edb()
-edbapp.close_edb()
-
-###############################################################################
-# Open EDB in AEDT
-# ~~~~~~~~~~~~~~~~
-# Open EDB in AEDT.
-
-h3d = pyedb.Hfss3dLayout(projectname=aedb_path, specified_version="2023.2",
- non_graphical=non_graphical, new_desktop_session=True)
-
-###############################################################################
-# Create wave ports
-# ~~~~~~~~~~~~~~~~~
-# Create wave ports.
-
-h3d.create_edge_port("line_3", 0, iswave=True, wave_vertical_extension=10, wave_horizontal_extension=10)
-h3d.create_edge_port("line_3", 2, iswave=True, wave_vertical_extension=10, wave_horizontal_extension=10)
-
-###############################################################################
-# Edit airbox extents
-# ~~~~~~~~~~~~~~~~~~~
-# Edit airbox extents.
-
-h3d.edit_hfss_extents(air_vertical_positive_padding="10mm",
- air_vertical_negative_padding="1mm")
-
-###############################################################################
-# Create setup
-# ~~~~~~~~~~~~
-# Create an HFSS simulation setup.
-
-setup = h3d.create_setup()
-setup["MaxPasses"]=2
-setup["AdaptiveFrequency"]="3GHz"
-setup["SaveAdaptiveCurrents"]=True
-h3d.create_linear_count_sweep(
- setupname=setup.name,
- unit="GHz",
- freqstart=0,
- freqstop=5,
- num_of_freq_points=1001,
- sweepname="sweep1",
- sweep_type="Interpolating",
- interpolation_tol_percent=1,
- interpolation_max_solutions=255,
- save_fields=False,
- use_q3d_for_dc=False,
-)
-
-###############################################################################
-# Plot layout
-# ~~~~~~~~~~~
-# Plot layout
-
-h3d.modeler.edb.nets.plot(None, None, color_by_net=True)
-
-cp_name = h3d.modeler.clip_plane()
-
-h3d.save_project()
-
-###############################################################################
-# Start HFSS solver
-# ~~~~~~~~~~~~~~~~~
-# Start the HFSS solver by uncommenting the ``h3d.analyze()`` command.
-
-h3d.analyze()
-
-# Save AEDT
-aedt_path = aedb_path.replace(".aedb", ".aedt")
-h3d.logger.info("Your AEDT project is saved to {}".format(aedt_path))
-solutions = h3d.get_touchstone_data()[0]
-solutions.log_x = False
-solutions.plot()
-
-h3d.post.create_fieldplot_cutplane(cp_name, "Mag_E", h3d.nominal_adaptive, intrinsincDict={"Freq":"3GHz", "Phase":"0deg"})
-
-# Release AEDT.
-h3d.release_desktop()
-
diff --git a/examples/00-EDB/09_Configuration.py b/examples/00-EDB/09_Configuration.py
deleted file mode 100644
index bf69940a8a..0000000000
--- a/examples/00-EDB/09_Configuration.py
+++ /dev/null
@@ -1,202 +0,0 @@
-"""
-EDB: Pin to Pin project
------------------------
-This example shows how you can create a project using a BOM file and configuration files.
-run anlasyis and get results.
-
-"""
-
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Peform required imports. Importing the ``Hfss3dlayout`` object initializes it
-# on version 2023 R2.
-
-import os
-import pyedb
-
-##########################################################
-# Set non-graphical mode
-# ~~~~~~~~~~~~~~~~~~~~~~
-# Set non-graphical mode. The default is ``True``.
-
-non_graphical = True
-
-###############################################################################
-# Download file
-# ~~~~~~~~~~~~~
-# Download the AEDB file and copy it in the temporary folder.
-
-
-project_path = pyedb.generate_unique_folder_name()
-target_aedb = pyedb.downloads.download_file('edb/ANSYS-HSD_V1.aedb', destination=project_path)
-print("Project folder will be", target_aedb)
-
-###############################################################################
-# Launch EDB
-# ~~~~~~~~~~
-# Launch the :class:`legacy.Edb` class, using EDB 2023 R2 and SI units.
-
-edbapp = pyedb.Edb(target_aedb, edbversion="2023.2")
-###############################################################################
-# Import Definitions
-# ~~~~~~~~~~~~~~~~~~
-# A definitions file is a json containing, for each part name the model associated.
-# Model can be RLC, Sparameter or Spice.
-# Once imported the definition is applied to the board.
-# In this example the json file is stored for convenience in aedb folder and has the following format:
-# {
-# "SParameterModel": {
-# "GRM32_DC0V_25degC_series": "./GRM32_DC0V_25degC_series.s2p"
-# },
-# "SPICEModel": {
-# "GRM32_DC0V_25degC": "./GRM32_DC0V_25degC.mod"
-# },
-# "Definitions": {
-# "CAPC1005X05N": {
-# "Component_type": "Capacitor",
-# "Model_type": "RLC",
-# "Res": 1,
-# "Ind": 2,
-# "Cap": 3,
-# "Is_parallel": false
-# },
-# "'CAPC3216X180X55ML20T25": {
-# "Component_type": "Capacitor",
-# "Model_type": "SParameterModel",
-# "Model_name": "GRM32_DC0V_25degC_series"
-# },
-# "'CAPC3216X180X20ML20": {
-# "Component_type": "Capacitor",
-# "Model_type": "SPICEModel",
-# "Model_name": "GRM32_DC0V_25degC"
-# }
-# }
-# }
-
-edbapp.components.import_definition(os.path.join(target_aedb, "1_comp_definition.json"))
-
-###############################################################################
-# Import BOM
-# ~~~~~~~~~~
-# This step imports a BOM file in CSV format. The BOM contains the
-# reference designator, part name, component type, and default value.
-# Components not in the BOM are deactivated.
-# In this example the csv file is stored for convenience in aedb folder.
-#
-# +------------+-----------------------+-----------+------------+
-# | RefDes | Part name | Type | Value |
-# +============+=======================+===========+============+
-# | C380 | CAPC1005X55X25LL05T10 | Capacitor | 11nF |
-# +------------+-----------------------+-----------+------------+
-
-
-edbapp.components.import_bom(os.path.join(target_aedb, "0_bom.csv"),
- refdes_col=0,
- part_name_col=1,
- comp_type_col=2,
- value_col=3)
-
-
-
-###############################################################################
-# Check Component Values
-# ~~~~~~~~~~~~~~~~~~~~~~
-# Component property allows to access all components instances and their property with getters and setters.
-
-comp = edbapp.components["C1"]
-comp.model_type, comp.value
-
-
-###############################################################################
-# Check Component Definition
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~
-# When an s-parameter model is associated to a component it will be available in nport_comp_definition property.
-
-edbapp.components.nport_comp_definition
-
-###############################################################################
-# Save Edb
-# ~~~~~~~~
-edbapp.save_edb()
-
-###############################################################################
-# Configure Setup
-# ~~~~~~~~~~~~~~~
-# This step allows to define the project. It includes:
-# - Definition of nets to be included into the cutout,
-# - Cutout details,
-# - Components on which to create the ports,
-# - Simulation settings.
-
-sim_setup = edbapp.new_simulation_configuration()
-sim_setup.solver_type = sim_setup.SOLVER_TYPE.SiwaveSYZ
-sim_setup.batch_solve_settings.cutout_subdesign_expansion = 0.003
-sim_setup.batch_solve_settings.do_cutout_subdesign = True
-sim_setup.batch_solve_settings.use_pyaedt_cutout = True
-sim_setup.ac_settings.max_arc_points = 6
-sim_setup.ac_settings.max_num_passes = 5
-
-sim_setup.batch_solve_settings.signal_nets = ['PCIe_Gen4_TX2_CAP_P',
- 'PCIe_Gen4_TX2_CAP_N',
- 'PCIe_Gen4_TX2_P',
- 'PCIe_Gen4_TX2_N']
-sim_setup.batch_solve_settings.components = ["U1", "X1"]
-sim_setup.batch_solve_settings.power_nets = ["GND", "GND_DP"]
-sim_setup.ac_settings.start_freq = "100Hz"
-sim_setup.ac_settings.stop_freq = "6GHz"
-sim_setup.ac_settings.step_freq = "10MHz"
-
-###############################################################################
-# Run Setup
-# ~~~~~~~~~
-# This step allows to create the cutout and apply all settings.
-
-sim_setup.export_json(os.path.join(project_path, "configuration.json"))
-edbapp.build_simulation_project(sim_setup)
-
-###############################################################################
-# Plot Cutout
-# ~~~~~~~~~~~
-# Plot cutout once finished.
-
-edbapp.nets.plot(None,None)
-
-###############################################################################
-# Save and Close EDB
-# ~~~~~~~~~~~~~~~~~~
-# Edb will be saved and closed in order to be opened by Hfss 3D Layout and solved.
-
-edbapp.save_edb()
-edbapp.close_edb()
-
-###############################################################################
-# Open Aedt
-# ~~~~~~~~~
-# Project folder aedb will be opened in AEDT Hfss3DLayout and loaded.
-h3d = pyedb.Hfss3dLayout(specified_version="2023.2", projectname=target_aedb, non_graphical=non_graphical, new_desktop_session=True)
-
-###############################################################################
-# Analyze
-# ~~~~~~~
-# Project will be solved.
-h3d.analyze()
-
-###############################################################################
-# Get Results
-# ~~~~~~~~~~~
-# S Parameter data will be loaded at the end of simulation.
-solutions = h3d.post.get_solution_data()
-
-###############################################################################
-# Plot Results
-# ~~~~~~~~~~~~
-# Plot S Parameter data.
-solutions.plot(solutions.expressions, "db20")
-
-###############################################################################
-# Save and Close AEDT
-# ~~~~~~~~~~~~~~~~~~~
-# Hfss3dLayout is saved and closed.
-h3d.save_project()
-h3d.release_desktop()
diff --git a/examples/00-EDB/10_GDS_workflow.py b/examples/00-EDB/10_GDS_workflow.py
deleted file mode 100644
index a4d5797c3c..0000000000
--- a/examples/00-EDB/10_GDS_workflow.py
+++ /dev/null
@@ -1,104 +0,0 @@
-"""
-EDB: Edit Control File and import gds
--------------------------------------
-This example shows how you can use PyAEDT to import a gds from an IC file.
-"""
-
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Perform required imports, which includes importing a section.
-
-import os
-import tempfile
-import pyedb
-import shutil
-from pyedb.edb_core.edb_data.control_file import ControlFile
-
-###############################################################################
-# Download file
-# ~~~~~~~~~~~~~
-# Download the AEDB file and copy it in the temporary folder.
-temppath = tempfile.gettempdir()
-local_path = pyedb.downloads.download_file('gds')
-c_file_in = os.path.join(
- local_path, "sky130_fictitious_dtc_example_control_no_map.xml"
-)
-c_map = os.path.join(local_path, "dummy_layermap.map")
-gds_in = os.path.join(local_path, "sky130_fictitious_dtc_example.gds")
-gds_out = os.path.join(temppath, "example.gds")
-shutil.copy2(gds_in,gds_out )
-###############################################################################
-# Control file
-# ~~~~~~~~~~~~
-# A Control file is an xml file which purpose if to provide additional
-# information during import phase. It can include, materials, stackup, setup, boundaries and settings.
-# In this example we will import an exising xml, integrate it with a layer mapping file of gds
-# and then adding setup and boundaries.
-
-c = ControlFile(c_file_in, layer_map=c_map)
-
-
-###############################################################################
-# Simulation setup
-# ~~~~~~~~~~~~~~~~
-# Here we setup simulation with HFSS and add a frequency sweep.
-setup = c.setups.add_setup("Setup1", "1GHz")
-setup.add_sweep("Sweep1", "0.01GHz", "5GHz", "0.1GHz")
-
-###############################################################################
-# Additional stackup settings
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-# After import user can change stackup settings and add/remove layers or materials.
-c.stackup.units = "um"
-c.stackup.dielectrics_base_elevation = -100
-c.stackup.metal_layer_snapping_tolerance = "10nm"
-for via in c.stackup.vias:
- via.create_via_group = True
- via.snap_via_group = True
-
-
-###############################################################################
-# Boundaries settings
-# ~~~~~~~~~~~~~~~~~~~
-# Boundaries can include ports, components and boundary extent.
-
-c.boundaries.units = "um"
-c.boundaries.add_port("P1", x1=223.7, y1=222.6, layer1="Metal6", x2=223.7, y2=100, layer2="Metal6")
-c.boundaries.add_extent()
-comp = c.components.add_component("B1", "BGA", "IC", "Flip chip", "Cylinder")
-comp.solder_diameter = "65um"
-comp.add_pin("1", "81.28", "84.6", "met2")
-comp.add_pin("2", "211.28", "84.6", "met2")
-comp.add_pin("3", "211.28", "214.6", "met2")
-comp.add_pin("4", "81.28", "214.6", "met2")
-c.import_options.import_dummy_nets = True
-
-###############################################################################
-# Write xml
-# ~~~~~~~~~
-# After all settings are ready we can write xml.
-
-c.write_xml(os.path.join(temppath, "output.xml"))
-
-###############################################################################
-# Open Edb
-# ~~~~~~~~~
-# Import the gds and open the edb.
-
-from pyedb import Edb
-
-edb = Edb(gds_out, edbversion="2023.2", technology_file=os.path.join(temppath, "output.xml"))
-
-###############################################################################
-# Plot Stackup
-# ~~~~~~~~~~~~
-# Stackup plot.
-edb.stackup.plot(first_layer="met1")
-
-###############################################################################
-# Close Edb
-# ~~~~~~~~~
-# Close the project.
-
-edb.close_edb()
\ No newline at end of file
diff --git a/examples/00-EDB/11_post_layout_parameterization.py b/examples/00-EDB/11_post_layout_parameterization.py
deleted file mode 100644
index df9c747888..0000000000
--- a/examples/00-EDB/11_post_layout_parameterization.py
+++ /dev/null
@@ -1,91 +0,0 @@
-"""
-EDB: post-layout parameterization
----------------------------------
-This example shows you how to parameterize the signal net in post-layout.
-"""
-
-###############################################################################
-# Define input parameters
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-signal_net_name = "DDR4_ALERT3"
-coplanar_plane_net_name = "1V0" # Specify coplanar plane net name for adding clearance
-layers = ["16_Bottom"] # Specify layers to be parameterized
-
-###############################################################################
-# Perform required imports
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-import os
-import pyedb
-
-from pyedb import Edb
-
-temppath = pyedb.generate_unique_folder_name()
-
-###############################################################################
-# Download and open example layout file in edb format
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-edb_fpath = pyedb.downloads.download_file('edb/ANSYS-HSD_V1.aedb', destination=temppath)
-appedb = Edb(edb_fpath, edbversion="2023.2")
-
-###############################################################################
-# Cutout
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-appedb.cutout([signal_net_name], [coplanar_plane_net_name, "GND"],
- remove_single_pin_components=True)
-
-###############################################################################
-# Get all trace segments from the signal net
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-net = appedb.nets[signal_net_name]
-trace_segments = []
-for p in net.primitives:
- if p.layer_name not in layers:
- continue
- if not p.type == "Path":
- continue
- trace_segments.append(p)
-
-###############################################################################
-# Create and assign delta w variable per layer
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-for p in trace_segments:
- vname = f"{p.net_name}_{p.layer_name}_dw"
- if vname not in appedb.variables:
- appedb[vname] = "0mm"
- new_w = f"{p.width}+{vname}"
- p.width = new_w
-
-###############################################################################
-# Delete existing clearance
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-for p in trace_segments:
- for g in appedb.modeler.get_polygons_by_layer(p.layer_name, coplanar_plane_net_name):
- for v in g.voids:
- if p.is_intersecting(v):
- v.delete()
-
-###############################################################################
-# Create and assign clearance variable per layer
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-for p in trace_segments:
- clr = f"{p.net_name}_{p.layer_name}_clr"
- if clr not in appedb.variables:
- appedb[clr] = "0.5mm"
- path = p.get_center_line()
- for g in appedb.modeler.get_polygons_by_layer(p.layer_name, coplanar_plane_net_name):
- void = appedb.modeler.create_trace(path, p.layer_name, f"{p.width}+{clr}*2")
- g.add_void(void)
-
-###############################################################################
-# Plot
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-appedb.nets.plot(layers=layers[0], size=2000)
-
-###############################################################################
-# Save and close Edb
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-save_edb_fpath = os.path.join(temppath, pyedb.generate_unique_name("post_layout_parameterization") + ".aedb")
-appedb.save_edb_as(save_edb_fpath)
-print("Edb is saved to ", save_edb_fpath)
-appedb.close_edb()
diff --git a/examples/00-EDB/12_edb_sma_connector_on_board.py b/examples/00-EDB/12_edb_sma_connector_on_board.py
deleted file mode 100644
index f416ac8cc9..0000000000
--- a/examples/00-EDB/12_edb_sma_connector_on_board.py
+++ /dev/null
@@ -1,198 +0,0 @@
-"""
-EDB: geometry creation
-----------------------
-This example shows how to
-1, Create a parameterized PCB layout design.
-2, Place 3D component on PCB.
-3, Create HFSS setup and frequency sweep with a mesh operation.
-4, Create return loss plot
-"""
-######################################################################
-#
-# Final expected project
-# ~~~~~~~~~~~~~~~~~~~~~~
-#
-# .. image:: ../../_static/edb_example_12_sma_connector_on_board.png
-# :width: 600
-# :alt: Differential Vias.
-######################################################################
-
-######################################################################
-# Create parameterized PCB
-# ~~~~~~~~~~~~~~~~~~~~~~~~
-# Initialize an empty EDB layout object on version 2023 R2.
-######################################################################
-
-import os
-import numpy as np
-import pyedb
-
-ansys_version = "2023.2"
-
-aedb_path = os.path.join(pyedb.generate_unique_folder_name(), pyedb.generate_unique_name("pcb") + ".aedb")
-edb = pyedb.Edb(edbpath=aedb_path, edbversion=ansys_version)
-print("EDB is located at {}".format(aedb_path))
-
-#####################
-# Create FR4 material
-# ~~~~~~~~~~~~~~~~~~~
-
-edb.materials.add_dielectric_material("ANSYS_FR4", 3.5, 0.005)
-
-################
-# Create stackup
-# ~~~~~~~~~~~~~~
-# A stackup can be created by importing from a csv/xml file or adding layer by layer.
-#
-
-edb.add_design_variable("$DIEL_T", "0.15mm")
-edb.stackup.add_layer("BOT")
-edb.stackup.add_layer("D5", "GND", layer_type="dielectric", thickness="$DIEL_T", material="ANSYS_FR4")
-edb.stackup.add_layer("L5", "Diel", thickness="0.05mm")
-edb.stackup.add_layer("D4", "GND", layer_type="dielectric", thickness="$DIEL_T", material="ANSYS_FR4")
-edb.stackup.add_layer("L4", "Diel", thickness="0.05mm")
-edb.stackup.add_layer("D3", "GND", layer_type="dielectric", thickness="$DIEL_T", material="ANSYS_FR4")
-edb.stackup.add_layer("L3", "Diel", thickness="0.05mm")
-edb.stackup.add_layer("D2", "GND", layer_type="dielectric", thickness="$DIEL_T", material="ANSYS_FR4")
-edb.stackup.add_layer("L2", "Diel", thickness="0.05mm")
-edb.stackup.add_layer("D1", "GND", layer_type="dielectric", thickness="$DIEL_T", material="ANSYS_FR4")
-edb.stackup.add_layer("TOP", "Diel", thickness="0.05mm")
-
-######################
-# Create ground planes
-# ~~~~~~~~~~~~~~~~~~~~
-#
-
-edb.add_design_variable("PCB_W", "20mm")
-edb.add_design_variable("PCB_L", "20mm")
-
-gnd_dict = {}
-for layer_name in edb.stackup.signal_layers.keys():
- gnd_dict[layer_name] = edb.modeler.create_rectangle(layer_name, "GND", [0, "PCB_W/-2"], ["PCB_L", "PCB_W/2"])
-
-###################
-# Create signal net
-# ~~~~~~~~~~~~~~~~~
-# Create signal net on layer 3, and add clearance to the ground plane.
-
-edb.add_design_variable("SIG_L", "10mm")
-edb.add_design_variable("SIG_W", "0.1mm")
-edb.add_design_variable("SIG_C", "0.3mm")
-
-signal_path = (["5mm", 0], ["SIG_L+5mm", 0])
-signal_trace = edb.modeler.create_trace(signal_path, "L3", "SIG_W", "SIG", "Flat", "Flat")
-
-signal_path = (["5mm", 0], ["PCB_L", 0])
-clr = edb.modeler.create_trace(signal_path, "L3", "SIG_C*2+SIG_W", "SIG", "Flat", "Flat")
-gnd_dict["L3"].add_void(clr)
-
-####################
-# Create signal vias
-# ~~~~~~~~~~~~~~~~~~
-# Create via padstack definition. Place the signal vias.
-
-edb.add_design_variable("SG_VIA_D", "1mm")
-
-edb.add_design_variable("$VIA_AP_D", "1.2mm")
-
-edb.padstacks.create("ANSYS_VIA", "0.3mm", "0.5mm", "$VIA_AP_D")
-
-edb.padstacks.place(["5mm", 0], "ANSYS_VIA", "SIG")
-
-######################################
-# Create ground vias around signal via
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-for i in np.arange(30, 331, 30):
- px = np.cos(i / 180 * np.pi)
- py = np.sin(i / 180 * np.pi)
- edb.padstacks.place(["{}*{}+5mm".format("SG_VIA_D", px), "{}*{}".format("SG_VIA_D", py)], "ANSYS_VIA", "GND")
-
-#######################################
-# Create ground vias along signal trace
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-for i in np.arange(2e-3, edb.variables["SIG_L"].value - 2e-3, 2e-3):
- edb.padstacks.place(["{}+5mm".format(i), "1mm"], "ANSYS_VIA", "GND")
- edb.padstacks.place(["{}+5mm".format(i), "-1mm"], "ANSYS_VIA", "GND")
-
-###################################################
-# Create a wave port at the end of the signal trace
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-signal_trace.create_edge_port("port_1", "End", "Wave", horizontal_extent_factor=10)
-
-##################
-# Set hfss options
-# ~~~~~~~~~~~~~~~~
-
-edb.design_options.antipads_always_on = True
-edb.hfss.hfss_extent_info.air_box_horizontal_extent = 0.01
-edb.hfss.hfss_extent_info.air_box_positive_vertical_extent = 2
-edb.hfss.hfss_extent_info.air_box_negative_vertical_extent = 2
-
-##############
-# Create setup
-# ~~~~~~~~~~~~
-
-setup = edb.create_hfss_setup("Setup1")
-setup.set_solution_single_frequency("5GHz", max_num_passes=2, max_delta_s="0.01")
-setup.hfss_solver_settings.order_basis = "first"
-
-#############################
-# Add mesh operation to setup
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-edb.setups["Setup1"].add_length_mesh_operation({"SIG": ["L3"]}, "m1", max_length="0.1mm")
-
-##############################
-# Add frequency sweep to setup
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-setup.add_frequency_sweep(
- "Sweep1",
- frequency_sweep=[
- ["linear count", "0", "1KHz", 1],
- ["log scale", "1KHz", "0.1GHz", 10],
- ["linear scale", "0.1GHz", "5GHz", "0.1GHz"],
- ],
-)
-
-####################
-# Save and close EDB
-# ~~~~~~~~~~~~~~~~~~
-
-edb.save_edb()
-edb.close_edb()
-
-#####################
-# Launch Hfss3dLayout
-# ~~~~~~~~~~~~~~~~~~~
-
-h3d = pyedb.Hfss3dLayout(aedb_path, specified_version=ansys_version, new_desktop_session=True)
-
-####################
-# Place 3D component
-# ~~~~~~~~~~~~~~~~~~
-
-component3d = pyedb.downloads.download_file("component_3d", "SMA_RF_SURFACE_MOUNT.a3dcomp", )
-
-comp = h3d.modeler.place_3d_component(
- component_path=component3d, number_of_terminals=1, placement_layer="TOP", component_name="my_connector",
- pos_x="5mm", pos_y=0.000)
-
-##########
-# Analysis
-# ~~~~~~~~
-h3d.analyze(num_cores=4)
-
-#########################
-# Create return loss plot
-# ~~~~~~~~~~~~~~~~~~~~~~~
-h3d.post.create_report("dB(S(port_1, port_1))")
-
-############################
-# Save and close the project
-# ~~~~~~~~~~~~~~~~~~~~~~~~~~
-h3d.save_project()
-print("Project is saved to {}".format(h3d.project_path))
-h3d.release_desktop(True, True)
diff --git a/examples/00-EDB/Readme.txt b/examples/00-EDB/Readme.txt
deleted file mode 100644
index c7104afa4d..0000000000
--- a/examples/00-EDB/Readme.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-EDB examples
-~~~~~~~~~~~~
-These examples use EDB (Electronics Database) with PyAEDT.
-EDB is a powerful API that allows to control PCB data efficently.
-You can either use EDB standalone or embedded in HFSS 3D Layout in AEDT.
diff --git a/examples/Readme.txt b/examples/Readme.txt
index 088894ba49..54132d7ab7 100644
--- a/examples/Readme.txt
+++ b/examples/Readme.txt
@@ -2,7 +2,7 @@
Examples
========
-End-to-end examples show how you can use PyAEDT. If PyAEDT is installed
+End-to-end examples show how you can use PyAEDB. If PyAEDB is installed
on your machine, you can download these examples as Python files or Jupyter
notebooks and run them locally.
diff --git a/examples/legacy/01_edb_example.py b/examples/legacy/01_edb_example.py
index e64e208e99..dfdbffb980 100644
--- a/examples/legacy/01_edb_example.py
+++ b/examples/legacy/01_edb_example.py
@@ -28,7 +28,7 @@
###############################################################################
# Launch EDB
# ~~~~~~~~~~
-# Launch the :class:`pyaedt.Edb` class, using EDB 2023 R2 and SI units.
+# Launch the :class:`pyedb.Edb` class, using EDB 2023 R2 and SI units.
edb_version = "2023.2"
if os.path.exists(aedt_file):
os.remove(aedt_file)
@@ -160,17 +160,3 @@
# Close EDB. After EDB is closed, it can be opened by AEDT.
edb.close_edb()
-
-###############################################################################
-# Postprocess in Siwave
-# ~~~~~~~~~~~~~~~~~~~~~
-# Open Siwave and generate a report. This works on Window only.
-
-# from pyaedt import Siwave
-# siwave = Siwave("2023.2")
-# siwave.open_project(siwave_file)
-# report_file = os.path.join(temp_folder,'Ansys.htm')
-#
-# siwave.export_siwave_report("myDCIR_4", report_file)
-# siwave.close_project()
-# siwave.quit_application()
diff --git a/examples/legacy/02_edb_to_ipc2581.py b/examples/legacy/02_edb_to_ipc2581.py
index b97dc96f9a..d384e7fa64 100644
--- a/examples/legacy/02_edb_to_ipc2581.py
+++ b/examples/legacy/02_edb_to_ipc2581.py
@@ -1,7 +1,7 @@
"""
EDB: IPC2581 export
-------------------
-This example shows how you can use PyAEDT to export an IPC2581 file.
+This example shows how you can use PyEDB to export an IPC2581 file.
"""
###############################################################################
@@ -33,7 +33,7 @@
###############################################################################
# Launch EDB
# ~~~~~~~~~~
-# Launch the :class:`pyaedt.Edb` class, using EDB 2023 R2 and SI units.
+# Launch the :class:`pyedb.Edb` class, using EDB 2023 R2 and SI units.
edb = pyedb.Edb(edbpath=targetfile, edbversion="2023.2")
diff --git a/examples/legacy/05_Plot_nets.py b/examples/legacy/05_Plot_nets.py
index 6277d61874..bc5c1888fa 100644
--- a/examples/legacy/05_Plot_nets.py
+++ b/examples/legacy/05_Plot_nets.py
@@ -26,7 +26,7 @@
###############################################################################
# Launch EDB
# ~~~~~~~~~~
-# Launch the :class:`pyaedt.Edb` class, using EDB 2023 R2 and SI units.
+# Launch the :class:`pyedb.Edb` class, using EDB 2023 R2 and SI units.
edb = pyedb.Edb(edbpath=targetfolder, edbversion="2023.2")
diff --git a/examples/legacy/pyaedt_integration/09_Configuration.py b/examples/legacy/pyaedt_integration/09_Configuration.py
index 72fc43fecf..dccb4915b3 100644
--- a/examples/legacy/pyaedt_integration/09_Configuration.py
+++ b/examples/legacy/pyaedt_integration/09_Configuration.py
@@ -39,7 +39,7 @@
###############################################################################
# Launch EDB
# ~~~~~~~~~~
-# Launch the :class:`pyaedt.Edb` class, using EDB 2023 R2 and SI units.
+# Launch the :class:`pyedb.Edb` class, using EDB 2023 R2 and SI units.
edbapp = pyedb.Edb(target_aedb, edbversion="2023.2")
###############################################################################
diff --git a/pyproject.toml b/pyproject.toml
index c3d6d01981..aa91c069b8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,7 @@ readme = "README.md"
requires-python = ">=3.8,<4"
license = {file = "LICENSE"}
authors = [{name = "ANSYS, Inc.", email = "pyansys.core@ansys.com"}]
-maintainers = [{name = "PyAEDT developers", email = "simon.vandenbrouck@ansys.com"}]
+maintainers = [{name = "PyEDB developers", email = "simon.vandenbrouck@ansys.com"}]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
@@ -101,24 +101,6 @@ doc = [
"sphinx_jinja",
]
full = [
- "imageio",
- "matplotlib==3.5.3; python_version == '3.7'",
- "matplotlib==3.7.3; python_version == '3.8'",
- "matplotlib==3.8.0; python_version > '3.8'",
- "numpy==1.21.6; python_version <= '3.9'",
- "numpy==1.26.0; python_version > '3.9'",
- "pandas==1.3.5; python_version == '3.7'",
- "pandas==2.0.3; python_version == '3.8'",
- "pandas==2.1.1; python_version > '3.9'",
- "osmnx",
- "pyvista==0.42.2; python_version > '3.7'",
- "pyvista==0.38.0; python_version <= '3.7'",
- "SRTM.py",
- "utm",
- "scikit-rf",
- "openpyxl==3.1.2",
-]
-all = [
"imageio",
"matplotlib==3.5.3; python_version == '3.7'",
"matplotlib==3.7.3; python_version == '3.8'",
@@ -127,7 +109,6 @@ all = [
"numpy==1.26.0; python_version > '3.9'",
"pandas==1.3.5; python_version == '3.7'",
"pandas==2.0.3; python_version == '3.9'",
- "pandas==2.0.3; python_version == '3.8'",
"pandas==2.1.1; python_version > '3.9'",
"osmnx",
"pyvista==0.42.2; python_version > '3.7'",
@@ -137,48 +118,54 @@ all = [
"scikit-rf",
"openpyxl==3.1.2",
]
+grpc = ["ansys-edb@git+ssh://git@github.com/ansys/pyedb-core"]
[tool.flit.module]
name = "pyedb"
-[project.urls]
-Bugs = "https://github.com/ansys/pyansys-edb/issues"
+# TODO: update once the repo is public
+# [project.urls]
+# Bugs = "https://github.com/ansys/pyansys-edb/issues"
# Documentation = "https://aedt.docs.pyansys.com"
-Source = "https://github.com/ansys/pyansys-edb"
-Discussions = "https://github.com/ansys/pyansys-edb/discussions"
-Releases = "https://github.com/ansys/pyansys-edb/releases"
+# Source = "https://github.com/ansys/pyansys-edb"
+# Discussions = "https://github.com/ansys/pyansys-edb/discussions"
+# Releases = "https://github.com/ansys/pyansys-edb/releases"
[tool.black]
-line-length = 120
+line-length = 88
[tool.isort]
profile = "black"
force_sort_within_sections = true
-line_length = 120
default_section = "THIRDPARTY"
-src_paths = ["doc", "src", "_unittests"]
+src_paths = ["doc", "src", "tests"]
[tool.codespell]
-ignore-words = "ignore_words.txt"
-skip = """
-*.pyc,*.aedt,*.xml,*.txt,*.gif,*.png,*.jpg,*.js,*.html,*.doctree,*.ttf,*.woff,*.woff2,*.eot,*.mp4,*.inv,*.pickle,\
-*.ipynb,flycheck*,./.git/*,./.hypothesis/*,*.yml,./docs/build/*,./docs/images/*,./dist/*,*~,.hypothesis*,\
-./pyaedt/third_party,./docs/source/examples/*,*cover,*.dat,*.mac,PKG-INFO,*.mypy_cache/*,*.xml,*.aedt,*.svg
-"""
+skip = '*.pyc,*.txt,*.gif,*.png,*.jpg,*.js,*.html,*.doctree,*.ttf,*.woff,*.woff2,*.eot,*.mp4,*.inv,*.pickle,*.ipynb,flycheck*,./.git/*,./.hypothesis/*,*.yml,./doc/build/*,./doc/images/*,./dist/*,*~,.hypothesis*,./doc/source/examples/*,*cover,*.dat,*.mac,*.cdb,*.CDB,build,./docker/mapdl/v*,./factory/*,./ansys/mapdl/core/mapdl_functions.py,PKG-INFO,*.mypy_cache/*,./docker/mapdl/*,./_unused/*'
+ignore-words = "doc/styles/Vocab/ANSYS/accept.txt"
enable-colors = true
[tool.coverage.run]
-source = ["pyaedt"]
+source = ["pyedb"]
[tool.coverage.report]
show_missing = true
[tool.pytest.ini_options]
minversion = "7.1"
-addopts = "-ra --cov=pyaedt --cov-report html:.cov/html --cov-report xml:.cov/xml --cov-report term -vv"
-testpaths = [
- "tests"
+filterwarnings = [
+ "ignore::DeprecationWarning",
]
+markers = [
+ "legacy: mark test as related to the legacy API.",
+ "unit: mark test as an unit test.",
+ "integration: mark test as an integration test.",
+ "system: mark test as a system test.",
+ "slow: mark test as slow.",
+ "no_licence: mark test that do not need a licence.",
+]
+testpaths = "tests"
+addopts = "-ra --cov=src/pyedb --cov-report html:.cov/html --cov-report xml:.cov/xml --cov-report term -vv"
[tool.numpydoc_validation]
checks = [
@@ -200,9 +187,3 @@ checks = [
"PR10", # Parameter "{param_name}" requires a space before the colon
# separating the parameter name and type",
]
-exclude = [
- '\.AEDTMessageManager.add_message$', # bad SS05
- '\.Modeler3D\.create_choke$', # bad RT05
- '\._unittest\', # missing docstring for tests
- 'HistoryProps.', # bad RT05 because of the base class named OrderedDict
-]
diff --git a/pytest.ini b/pytest.ini
deleted file mode 100644
index 720f2b0362..0000000000
--- a/pytest.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[pytest]
-filterwarnings =
- ignore::DeprecationWarning:pyaedt.*
-markers =
- legacy: mark test as related to the legacy API.
- unit: mark test as an unit test.
- integration: mark test as an integration test.
- system: mark test as a system test.
- slow: mark test as slow.
- no_licence: mark test that do not need a licence.
\ No newline at end of file
diff --git a/src/pyedb/edb_logger.py b/src/pyedb/edb_logger.py
index c8a20ba84f..35126578ed 100644
--- a/src/pyedb/edb_logger.py
+++ b/src/pyedb/edb_logger.py
@@ -95,11 +95,11 @@ def remove_file_logger(self, project_name):
"""Remove a file from the logger handlers list."""
handlers = [i for i in self._global.handlers]
for handler in self._files_handlers:
- if "pyaedt_{}.log".format(project_name) in str(handler):
+ if "pyedb_{}.log".format(project_name) in str(handler):
handler.close()
if handler in handlers:
self._global.removeHandler(handler)
- self.info("logger file pyaedt_{}.log removed from handlers.".format(project_name))
+ self.info("logger file pyedb_{}.log removed from handlers.".format(project_name))
@property
def _log_on_file(self):
@@ -253,7 +253,7 @@ def enable_stdout_log(self):
if not self._std_out_handler:
self._std_out_handler = logging.StreamHandler(sys.stdout)
self._std_out_handler.setLevel(self.level)
- _logger_stdout_formatter = logging.Formatter("pyaedt %(levelname)s: %(message)s")
+ _logger_stdout_formatter = logging.Formatter("pyedb %(levelname)s: %(message)s")
self._std_out_handler.setFormatter(_logger_stdout_formatter)
self._global.addHandler(self._std_out_handler)
diff --git a/src/pyedb/generic/LoadAEDTFile.py b/src/pyedb/generic/LoadAEDTFile.py
deleted file mode 100644
index be5944745f..0000000000
--- a/src/pyedb/generic/LoadAEDTFile.py
+++ /dev/null
@@ -1,447 +0,0 @@
-# -*- coding: utf-8 -*-
-import os.path
-import re
-
-from pyedb.generic.general_methods import settings
-from pyaedt.generic.general_methods import open_file
-# from pyaedt.generic.general_methods import settings
-
-# --------------------------------------------------------------------
-# public interface
-
-
-def load_entire_aedt_file(filename):
- """Load the entire AEDT file and return the dictionary
-
- Parameters
- ----------
- filename :
- AEDT filename with path
-
- Returns
- -------
- dict
- dictionary containing the decoded AEDT file
-
- """
- return _load_entire_aedt_file(os.path.normpath(filename))
-
-
-def load_keyword_in_aedt_file(filename, keyword):
- """Load s specific keyword in the AEDT file and return the dictionary
-
- Parameters
- ----------
- filename :
- AEDT filename with path
- keyword :
- keyword to search and load
-
- Returns
- -------
- dict
- dictionary containing the decoded AEDT file
-
- """
- return _load_keyword_in_aedt_file(filename, keyword)
-
-
-# --------------------------------------------------------------------
-# internals
-
-
-# precompile all Regular expressions
-_remove_quotes = re.compile(r"^'(.*?)'$")
-_split_list_elements = re.compile(",(?=(?:[^']*'[^']*')*[^']*$)")
-_round_bracket_list = re.compile(r"^(?P[^\s=]+?)\((?P.+)\)|^'(?P.+?\s.+)'(?<=')\((?P.+)\)")
-_square_bracket_list = re.compile(
- r"^(?P\S+?)\[\d+:(?P.+)\]|^'(?P.+?\s.+)'(?<=')\[\d+:(?P.+)\]"
-)
-_key_parse = re.compile(r"(^'(?P.+?)')(?<=')=(?P.+$)|(?P^.+?)=(?P.+$)")
-_value_parse1 = re.compile(r"\s")
-_value_parse2 = re.compile(r"^'([^']*\s[^']*)(?=')")
-_begin_search = re.compile(r"\$begin '(.+)'")
-
-# set recognized keywords
-_recognized_keywords = ["CurvesInfo", "Sweep Operations", "PropDisplayMap"]
-_recognized_subkeys = ["simple(", "IDMap(", "WireSeg(", "PC("]
-
-# global variables
-_all_lines = []
-_len_all_lines = 0
-_count = 0
-
-
-def _parse_value(v):
- """
-
- Parameters
- ----------
- v :
-
-
- Returns
- -------
-
- """
- # duck typing parse of the value 'v'
- if v is None:
- pv = v
- elif v == "true":
- pv = True
- elif v == "false":
- pv = False
- else:
- try:
- pv = int(v)
- except ValueError:
- try:
- pv = float(v)
- except ValueError:
- m = _remove_quotes.search(v)
- if m:
- pv = m.group(1)
- else:
- pv = v
- return pv
-
-
-def _separate_list_elements(v):
- """
-
- Parameters
- ----------
- v :
-
-
- Returns
- -------
-
- """
- if "(" in v or "=" in v:
- l1 = _split_list_elements.split(v)
- else:
- l1 = v.split(",")
- l2 = [_parse_value(i.strip()) for i in l1]
- return l2
-
-
-def _decode_recognized_subkeys(sk, d):
- """Special decodings for sub-keys belonging to _recognized_subkeys
-
- Parameters
- ----------
- sk : str
- dictionary sub-key recognized
-
- d : dict
- Active dictionary.
-
- Returns
- -------
- bool
- Returns ``True`` if it finds and decode a recognized value.
-
- """
- if sk.startswith(_recognized_subkeys[0]): # 'simple(' is at the beginning of the value
- m = _round_bracket_list.search(sk)
- if m and m.group("SKEY1") == "simple": # extra verification. SKEY2 is with spaces, so it's not considered here.
- elems = _separate_list_elements(m.group("LIST1"))
- if elems[0] == "thermal_expansion_coeffcient":
- elems[0] = "thermal_expansion_coefficient" # fix a typo in the amat files. AEDT supports both strings!
- d[elems[0]] = str(elems[1]) # convert to string as it is dedicated to material props
- return True
- elif re.search(r"^\w+IDMap\(.*\)$", sk, re.IGNORECASE): # check if the format is AAKeyIDMap('10'=56802, '7'=56803)
- m = re.search(r"^(?P[^\s=]+?)\((?P.*)\)", sk)
- if m and "idmap" in m.group("SKEY").lower(): # extra verification.
- k = m.group("SKEY")
- if m.group("LIST"):
- elems = m.group("LIST").split(",")
- else:
- elems = None
- d[k] = elems
- return True
- if sk.startswith(_recognized_subkeys[2]):
- wire_seg_list = [_parse_value(i) for i in sk.lstrip("WireSeg(").rstrip(")").split(", ")]
- if "WireSeg" in d.keys():
- d["WireSeg"].append(wire_seg_list)
- else:
- d["WireSeg"] = []
- d["WireSeg"].append(wire_seg_list)
- return True
- if sk.startswith(_recognized_subkeys[3]):
- pclist = [i for i in sk.lstrip("PC(").rstrip(")").split(", ")]
- if "PC" in d.keys():
- d["PC"].append(pclist)
- else:
- d["PC"] = []
- d["PC"].append(pclist)
- return True
- return False
-
-
-def _decode_recognized_key(keyword, line, d):
- """Special decodings for keys belonging to _recognized_keywords
-
- Parameters
- ----------
- keyword : str
- dictionary key recognized
-
- line : str
- Line.
-
- d : dict
- Active dictionary.
-
- -------
-
- """
- if keyword == _recognized_keywords[0]: # 'CurvesInfo'
- m = re.search(r"\'(\d+)\'\((.*)\)$", line)
- if m:
- k = m.group(1)
- v = m.group(2)
- v2 = v.replace("\\'", '"')
- v3 = _separate_list_elements(v2)
- d[k] = v3
- elif keyword == _recognized_keywords[1]: # 'Sweep Operations'
- d["add"] = []
- global _count
- line = _all_lines[_count + 1]
- while line.startswith("add("):
- d["add"].append(line.replace("add", "").translate({ord(i): None for i in " ()'"}).split(","))
- _count += 1
- line = _all_lines[_count + 1]
- elif keyword == _recognized_keywords[2]: # PropDisplayMap
- pattern = ".+\((.+) Text\((.+) ExtentRect\((.+)\)\)\)"
- match = re.search(pattern, line)
- d["Name"] = []
- for i in match.group(1).split(", "):
- d["Name"].append(_parse_value(i))
- d["Name"].append("Text:=")
- temp_list = []
- for i in match.group(2).split(", "):
- temp_list.append(_parse_value(i))
- temp_list.append("ExtentRect:=")
- temp_list.append([_parse_value(i) for i in match.group(3).split(", ")])
- d["Name"].append(temp_list)
- else: # pragma: no cover
- raise AttributeError("Keyword {} is supposed to be in the recognized_keywords list".format(keyword))
-
-
-def _decode_subkey(line, d):
- """
-
- Parameters
- ----------
- line : str
- Line.
-
- d : dict
- Active dictionary.
-
- -------
-
- """
- # send recognized sub-keys to _decode_recognized_subkeys (Case insensitive search, detailed search is inside)
- for rsk in _recognized_subkeys:
- if rsk.lower() in line.lower(): # here we simply search if one of the _recognized_subkeys is in line
- if _decode_recognized_subkeys(line, d): # the exact search is done inside the _decode_recognized_subkeys
- return # if there is a match we stop the _decode_key, otherwise we keep going
-
- # create a list for subkey(l1, l2, l3)
- m = _round_bracket_list.search(line)
- if m and m.group("SKEY1"):
- v = _separate_list_elements(m.group("LIST1"))
- k = m.group("SKEY1")
- d[k] = v
- return # if there is a match we stop the _decode_key, otherwise we keep going
- elif m and m.group("SKEY2"):
- v = _separate_list_elements(m.group("LIST2"))
- k = m.group("SKEY2")
- d[k] = v
- return # if there is a match we stop the _decode_key, otherwise we keep going
-
- # create a list for subkey[n: 1, 2, ...n]
- m = _square_bracket_list.search(line)
- if m and m.group("SKEY1"):
- v = _separate_list_elements(m.group("LIST1"))
- k = m.group("SKEY1")
- d[k] = v
- return # if there is a match we stop the _decode_key, otherwise we keep going
- elif m and m.group("SKEY2"):
- v = _separate_list_elements(m.group("LIST2"))
- k = m.group("SKEY2")
- d[k] = v
- return # if there is a match we stop the _decode_key, otherwise we keep going
-
- # search for equal sign
- m = _key_parse.search(line)
- if m and m.group("KEY1"): # key btw ''
- v = m.group("VAL1")
- if "\\'" in v:
- v2 = v.replace("\\'", '"')
- else:
- v2 = v
- # if there are no spaces in value or values with spaces are between quotes
- if not _value_parse1.search(v2) or _value_parse2.search(v2):
- k = m.group("KEY1")
- d[k] = _parse_value(v)
- else: # spaces in value without quotes
- k = line # save the line as a whole
- d[k] = None
- elif m and m.group("KEY2"): # key without ''
- v = m.group("VAL2")
- if "\\'" in v:
- v2 = v.replace("\\'", '"')
- else:
- v2 = v
- # if there are no spaces in value or values with spaces are between quotes
- if not _value_parse1.search(v2) or _value_parse2.search(v2):
- k = m.group("KEY2")
- d[k] = _parse_value(v)
- else: # spaces in value without quotes
- k = line # save the line as a whole
- d[k] = None
- else: # no = sign found
- k = line # save the line as a whole
- d[k] = None
-
-
-def _walk_through_structure(keyword, save_dict):
- """
-
- Parameters
- ----------
- keyword :
-
- save_dict :
-
-
- Returns
- -------
-
- """
- global _count
- begin_key = "$begin '{}'".format(keyword)
- end_key = "$end '{}'".format(keyword)
- found = False
- saved_value = None
- while _count < _len_all_lines:
- line = _all_lines[_count]
- # begin_key is found
- if begin_key == line:
- found = True
- saved_value = save_dict.get(keyword) # if the keyword is already present, save it
- save_dict[keyword] = {}
- _count += 1
- continue
- # end_key is found
- if end_key == line:
- break
- # between begin_key and end_key
- if found:
- b = _begin_search.search(line)
- if b: # walk down a level
- nextlvl_begin_key = b.group(1)
- _walk_through_structure(nextlvl_begin_key, save_dict[keyword])
- elif keyword in _recognized_keywords:
- _decode_recognized_key(keyword, line, save_dict[keyword])
- else: # decode key
- _decode_subkey(line, save_dict[keyword])
- _count += 1
- # recompose value if list
- if saved_value:
- # makes the value a list, if it's not already
- if type(saved_value) is not list:
- saved_value = [saved_value]
- saved_value.append(save_dict[keyword])
- save_dict[keyword] = saved_value
- return _count
-
-
-def _read_aedt_file(filename):
- """Read the entire AEDT file discard binary and put ascii line in a list
-
- Parameters
- ----------
- filename :
- AEDT filename with path
-
- Returns
- -------
-
- """
- global _all_lines
- global _len_all_lines
- global _count
-
- # read the AEDT file
- with open_file(filename, "rb") as aedt_fh:
- raw_lines = aedt_fh.read().splitlines()
- ascii_lines = []
- for raw_line in raw_lines:
- try:
- ascii_lines.append(raw_line.decode("utf-8").lstrip(" \t"))
- except UnicodeDecodeError:
- continue
- ascii_content = "\n".join(ascii_lines)
- # combine subsequent lines when the line ends in \
- _all_lines = ascii_content.replace("\\\n", "").splitlines()
- _len_all_lines = len(_all_lines)
- _count = 0
-
-
-def _load_entire_aedt_file(filename):
- """Load the entire AEDT file and return the dictionary
-
- Parameters
- ----------
- filename :
- AEDT filename with path
-
- Returns
- -------
- type
- dictionary containing the decoded AEDT file
-
- """
- global _count
- _read_aedt_file(filename)
- main_dict = {}
- # load the aedt file
- while _count < _len_all_lines:
- line = _all_lines[_count]
- m = _begin_search.search(line)
- if m:
- _walk_through_structure(m.group(1), main_dict)
- _count += 1
- if settings.aedt_version and settings.aedt_version > "2022.2":
- project_preview = load_keyword_in_aedt_file(filename, "ProjectPreview")
- if project_preview and "ProjectPreview" in project_preview:
- main_dict["ProjectPreview"] = project_preview["ProjectPreview"]
- return main_dict
-
-
-def _load_keyword_in_aedt_file(filename, keyword):
- """Load a specific keyword in the AEDT file and return the dictionary
-
- Parameters
- ----------
- filename :
- AEDT filename with path
- keyword :
- keyword to search and load
-
- Returns
- -------
- type
- dictionary containing the decoded AEDT file
-
- """
- _read_aedt_file(filename)
- # load the aedt file
- main_dict = {}
- _walk_through_structure(keyword, main_dict)
- return main_dict
diff --git a/src/pyedb/generic/data_handlers.py b/src/pyedb/generic/data_handlers.py
index 0678bc3562..2712a0f801 100644
--- a/src/pyedb/generic/data_handlers.py
+++ b/src/pyedb/generic/data_handlers.py
@@ -7,11 +7,8 @@
import re
import string
-from pyaedt.generic.general_methods import pyedb_function_handler
-from pyaedt.generic.general_methods import settings
-from pyaedt.modeler.cad.elements3d import EdgePrimitive
-from pyaedt.modeler.cad.elements3d import FacePrimitive
-from pyaedt.modeler.cad.elements3d import VertexPrimitive
+from pyedb.generic.general_methods import pyedb_function_handler
+from pyedb.generic.general_methods import settings
@pyedb_function_handler()
@@ -53,63 +50,6 @@ def _tuple2dict(t, d):
d[k] = v
-@pyedb_function_handler()
-def _dict2arg(d, arg_out):
- """Create a valid string of name-value pairs for the native AEDT API.
-
- Prepend the argument string in `arg_out` using the dictionary ``d``
- to create a valid input string as an argument for the native AEDT API.
-
- Parameters
- ----------
- d : dict
- Dictionary to use for prepending to the argument string being built
- for the native AEDT API.
-
- arg_out : str.
- String of the name/value pair to be built as an argument
- for the native AEDT API.
-
- """
- for k, v in d.items():
- if "_pyaedt" in k:
- continue
- if k == "Point" or k == "DimUnits":
- if isinstance(v[0], (list, tuple)):
- for e in v:
- arg = ["NAME:" + k, e[0], e[1]]
- arg_out.append(arg)
- else:
- arg = ["NAME:" + k, v[0], v[1]]
- arg_out.append(arg)
- elif k == "Range":
- if isinstance(v[0], (list, tuple)):
- for e in v:
- arg_out.append(k + ":=")
- arg_out.append([i for i in e])
- else:
- arg_out.append(k + ":=")
- arg_out.append([i for i in v])
- elif isinstance(v, (OrderedDict, dict)):
- arg = ["NAME:" + k]
- _dict2arg(v, arg)
- arg_out.append(arg)
- elif v is None:
- arg_out.append(["NAME:" + k])
- elif type(v) is list and len(v) > 0 and isinstance(v[0], (OrderedDict, dict)):
- for el in v:
- arg = ["NAME:" + k]
- _dict2arg(el, arg)
- arg_out.append(arg)
-
- else:
- arg_out.append(k + ":=")
- if type(v) is EdgePrimitive or type(v) is FacePrimitive or type(v) is VertexPrimitive:
- arg_out.append(v.id)
- else:
- arg_out.append(v)
-
-
@pyedb_function_handler()
def _arg2dict(arg, dict_out):
if arg[0] == "NAME:DimUnits" or "NAME:Point" in arg[0]:
diff --git a/src/pyedb/generic/design_types.py b/src/pyedb/generic/design_types.py
index 8ee4a899c5..ddac9a74dc 100644
--- a/src/pyedb/generic/design_types.py
+++ b/src/pyedb/generic/design_types.py
@@ -44,13 +44,13 @@ def Edb(
Returns
-------
- :class:`pyaedt.edb.Edb`
+ :class:`pyedb.legacy.edb.EdbLegacy`, :class:`pyedb.grpc.edb.EdbLegacy`
Examples
--------
Create an ``Edb`` object and a new EDB cell.
- >>> from pyaedt import Edb
+ >>> from pyedb import Edb
>>> app = Edb()
Add a new variable named "s1" to the ``Edb`` instance.
diff --git a/src/pyedb/legacy/generic/filesystem.py b/src/pyedb/generic/filesystem.py
similarity index 98%
rename from src/pyedb/legacy/generic/filesystem.py
rename to src/pyedb/generic/filesystem.py
index 5f1af71b88..3d45ccd6d2 100644
--- a/src/pyedb/legacy/generic/filesystem.py
+++ b/src/pyedb/generic/filesystem.py
@@ -16,7 +16,7 @@ def search_files(dirname, pattern="*"):
-------
list
"""
- from pyaedt.generic.general_methods import is_ironpython
+ from pyedb.generic.general_methods import is_ironpython
if is_ironpython:
import glob
diff --git a/src/pyedb/generic/general_methods.py b/src/pyedb/generic/general_methods.py
index 95f2f0f601..0cc1fc54e8 100644
--- a/src/pyedb/generic/general_methods.py
+++ b/src/pyedb/generic/general_methods.py
@@ -602,7 +602,7 @@ def generate_unique_folder_name(rootname=None, folder_name=None):
else:
rootname = tempfile.gettempdir()
if folder_name is None:
- folder_name = generate_unique_name("pyaedt_prj", n=3)
+ folder_name = generate_unique_name("pyedb_prj", n=3)
temp_folder = os.path.join(rootname, folder_name)
if settings.remote_rpc_session and not settings.remote_rpc_session.filemanager.pathexists(temp_folder):
settings.remote_rpc_session.filemanager.makedirs(temp_folder)
@@ -1813,22 +1813,22 @@ def search(self, keywords, app_name=None, search_in_examples_only=False):
self._launch_ur(url)
def getting_started(self):
- """Open the PyAEDT User guide page."""
+ """Open the PyEDB User guide page."""
url = self._base_path + "/User_guide/index.html"
self._launch_ur(url)
def examples(self):
- """Open the PyAEDT Examples page."""
+ """Open the PyEDB Examples page."""
url = self._base_path + "/examples/index.html"
self._launch_ur(url)
def github(self):
- """Open the PyAEDT GitHub page."""
- url = "https://github.com/ansys/pyaedt"
+ """Open the PyEDB GitHub page."""
+ url = "https://github.com/ansys/pyedb"
self._launch_ur(url)
def changelog(self, release=None):
- """Open the PyAEDT GitHub Changelog for a given release.
+ """Open the PyEDB GitHub Changelog for a given release.
Parameters
----------
@@ -1836,18 +1836,18 @@ def changelog(self, release=None):
Release to get the changelog for. For example, ``"0.6.70"``.
"""
if release is None:
- from pyaedt import __version__ as release
- url = "https://github.com/ansys/pyaedt/releases/tag/v" + release
+ from pyedb import __version__ as release
+ url = "https://github.com/ansys/pyedb/releases/tag/v" + release
self._launch_ur(url)
def issues(self):
- """Open the PyAEDT GitHub Issues page."""
- url = "https://github.com/ansys/pyaedt/issues"
+ """Open the PyEDB GitHub Issues page."""
+ url = "https://github.com/ansys/pyedb/issues"
self._launch_ur(url)
def ansys_forum(self):
- """Open the PyAEDT GitHub Issues page."""
- url = "https://discuss.ansys.com/discussions/tagged/pyaedt"
+ """Open the PyEDB GitHub Issues page."""
+ url = "https://discuss.ansys.com/discussions/tagged/pyedb"
self._launch_ur(url)
def developer_forum(self):
diff --git a/src/pyedb/generic/plot.py b/src/pyedb/generic/plot.py
index ea0d0445a0..6a1356970b 100644
--- a/src/pyedb/generic/plot.py
+++ b/src/pyedb/generic/plot.py
@@ -72,7 +72,7 @@ def get_structured_mesh(theta, phi, ff_data):
def is_notebook():
- """Check if pyaedt is running in Jupyter or not.
+ """Check if pyedb is running in Jupyter or not.
Returns
-------
@@ -1071,7 +1071,7 @@ class ModelPlotter(CommonPlotter):
Examples
--------
- This Class can be instantiated within Pyaedt (with plot_model_object or different field plots
+ This Class can be instantiated within PyEDB (with plot_model_object or different field plots
and standalone).
Here an example of standalone project
diff --git a/src/pyedb/generic/settings.py b/src/pyedb/generic/settings.py
index 5b4c4d83ba..81e21a84e5 100644
--- a/src/pyedb/generic/settings.py
+++ b/src/pyedb/generic/settings.py
@@ -4,7 +4,7 @@
class Settings(object):
- """Manages all PyAEDT environment variables and global settings."""
+ """Manages all PyEDB environment variables and global settings."""
def __init__(self):
# TODO: Remove this (not always sure)
@@ -65,7 +65,7 @@ def aedt_version(self, value):
@property
def global_log_file_size(self):
- """Global PyAEDT log file size in MB. The default value is ``10``."""
+ """Global PyEDB log file size in MB. The default value is ``10``."""
return self._global_log_file_size
@global_log_file_size.setter
@@ -74,7 +74,7 @@ def global_log_file_size(self, value):
@property
def enable_global_log_file(self):
- """Flag for enabling and disabling the global PyAEDT log file located in the global temp folder.
+ """Flag for enabling and disabling the global PyEDB log file located in the global temp folder.
The default is ``True``."""
return self._enable_global_log_file
@@ -84,8 +84,8 @@ def enable_global_log_file(self, value):
@property
def enable_local_log_file(self):
- """Flag for enabling and disabling the local PyAEDT log file located
- in the ``projectname.pyaedt`` project folder. The default is ``True``."""
+ """Flag for enabling and disabling the local PyEDB log file located
+ in the ``projectname.pyedb`` project folder. The default is ``True``."""
return self._enable_local_log_file
@enable_local_log_file.setter
@@ -94,7 +94,7 @@ def enable_local_log_file(self, value):
@property
def global_log_file_name(self):
- """Global PyAEDT log file path. The default is ``pyaedt_username.log``."""
+ """Global PyEDB log file path. The default is ``pyedb_username.log``."""
return self._global_log_file_name
@global_log_file_name.setter
@@ -121,7 +121,7 @@ def logger(self):
@property
def enable_error_handler(self):
- """Flag for enabling and disabling the internal PyAEDT error handling."""
+ """Flag for enabling and disabling the internal PyEDB error handling."""
return self._enable_error_handler
@enable_error_handler.setter
@@ -148,7 +148,7 @@ def enable_logger(self, val):
@property
def logger_file_path(self):
- """PyAEDT log file path."""
+ """PyEDB log file path."""
return self._logger_file_path
@logger_file_path.setter
diff --git a/src/pyedb/ipc2581/history_record.py b/src/pyedb/ipc2581/history_record.py
index 18d6477315..30c5b44b0a 100644
--- a/src/pyedb/ipc2581/history_record.py
+++ b/src/pyedb/ipc2581/history_record.py
@@ -7,7 +7,7 @@ class HistoryRecord(object):
def __init__(self):
self.number = "1"
self.origination = date.today()
- self.software = "Ansys Pyaedt"
+ self.software = "Ansys PyEDB"
self.last_changes = date.today()
self.file_revision = "1"
self.comment = ""
diff --git a/src/pyedb/ipc2581/logistic_header.py b/src/pyedb/ipc2581/logistic_header.py
index 6f8054e6cd..742a990a35 100644
--- a/src/pyedb/ipc2581/logistic_header.py
+++ b/src/pyedb/ipc2581/logistic_header.py
@@ -3,13 +3,13 @@
class LogisticHeader(object):
def __init__(self):
- self.owner = "Pyaedt"
+ self.owner = "PyEDB"
self.sender = "Ansys"
self.enterprise = "Ansys"
self.code = "UNKNOWN"
self.person_name = "eba"
self.enterprise_ref = "UNKNOWN"
- self.role_ref = "Pyaedt"
+ self.role_ref = "PyEDB"
def write_xml(self, root): # pragma no cover
logistic_header = ET.SubElement(root, "LogisticHeader")
diff --git a/src/pyedb/legacy/__init__.py b/src/pyedb/legacy/__init__.py
index 984e10de8c..33948ec105 100644
--- a/src/pyedb/legacy/__init__.py
+++ b/src/pyedb/legacy/__init__.py
@@ -1,17 +1,2 @@
-# # -*- coding: utf-8 -*-
-# import os
-
-# if os.name == "nt":
-# os.environ["PYTHONMALLOC"] = "malloc"
-
-# pyaedt_path = os.path.dirname(__file__)
-
-# # __version__ = "0.8.dev0"
-
-# # version = __version__
-
-# try:
-# from pyedb.generic.design_types import Hfss3dLayout
-# except:
-# from pyedb.generic.design_types import Hfss3dLayout
-
+"""Legacy code.
+"""
\ No newline at end of file
diff --git a/src/pyedb/legacy/aedt_logger.py b/src/pyedb/legacy/aedt_logger.py
deleted file mode 100644
index bd91aa3f0e..0000000000
--- a/src/pyedb/legacy/aedt_logger.py
+++ /dev/null
@@ -1,738 +0,0 @@
-# -*- coding: utf-8 -*-
-import logging
-from logging.handlers import RotatingFileHandler
-import os
-import shutil
-import sys
-import tempfile
-import time
-
-from pyedb import settings
-
-message_levels = {"Global": 0, "Project": 1, "Design": 2}
-
-
-class Msg:
- (INFO, WARNING, ERROR, FATAL) = range(4)
-
-
-class MessageList:
- """
- Collects and returns messages from the AEDT message manager for a specified project name and design name.
-
- Parameters
- ----------
- msg_list : list
- List of messages extracted from AEDT.
- project_name : str
- Name of the project. The default is the active project.
- design_name : str
- Name of the design within the specified project. The default is the active design.
-
-
- Attributes
- ----------
- global_level : list of str
- List of strings representing the message content at the global level of the message manager.
-
- project_level : list of str
- List of strings representing the message content within the specified project.
-
- design_level : list of str
- List of strings representing the message content for the specified design within the specified project.
-
- """
-
- def __init__(self, msg_list, project_name, design_name):
- self.global_level = []
- self.project_level = []
- self.design_level = []
- global_label = "Project: *Global - Messages, "
- project_label = "Project: {}, ".format(project_name)
- design_label = "Project: {}, Design: {} (".format(project_name, design_name)
- for line in msg_list:
- # Find the first instance of '[' to get the message context
- loc = line.find("[")
- if loc < 0:
- # Format is not clear - append to global
- self.global_level.append(line)
- else:
- line_label = line[0:loc]
- msg_txt = line[loc:].strip()
- if design_label in line_label:
- self.design_level.append(msg_txt)
- elif project_label in line_label:
- self.project_level.append(msg_txt)
- elif global_label in line_label:
- self.global_level.append(msg_txt)
-
-
-class AppFilter(logging.Filter):
- """Specifies the destination of the logger.
-
- AEDT exposes three different loggers, which are the global, project, and design loggers.
-
- Parameters
- ----------
- destination : str, optional
- Logger to write to. Options are ``"Global"`, ``"Project"``, and ``"Design"``.
- The default is ``"Global"``.
- extra : str, optional
- Name of the design or project. The default is ``""``.
- """
-
- def __init__(self, destination="Global", extra=""):
- self._destination = destination
- self._extra = extra
-
- def filter(self, record):
- """
- Modify the record sent to the logger.
-
- Parameters
- ----------
- record : class:`logging.LogRecord`
- Contains information related to the event being logged.
- """
- record.destination = self._destination
-
- # This will avoid the extra '::' for Global that does not have any extra info.
- if not self._extra:
- record.extra = self._extra
- else:
- record.extra = self._extra + ":"
- return True
-
-
-class AedtLogger(object):
- """
- Specifies the logger to use for each AEDT logger.
-
- This class allows you to add a handler to write messages to a file and to indicate
- whether to write mnessages to the standard output (stdout).
-
- Parameters
- ----------
- level : int, optional
- Logging level to filter the message severity allowed in the logger.
- The default is ``logging.DEBUG``.
- filename : str, optional
- Name of the file to write messages to. The default is ``None``.
- to_stdout : bool, optional
- Whether to write log messages to stdout. The default is ``False``.
- """
-
- def __init__(self, level=logging.DEBUG, filename=None, to_stdout=False):
- self._std_out_handler = None
- self._files_handlers = []
- self.level = level
- self.filename = filename or settings.logger_file_path
- settings.logger_file_path = self.filename
-
- self._global = logging.getLogger("Global")
- if not settings.enable_logger:
- self._global.addHandler(logging.NullHandler())
- return
-
- self._projects = {}
-
- self._global.setLevel(level)
- self._global.addFilter(AppFilter())
-
- if settings.formatter:
- self.formatter = settings.formatter
- else:
- self.formatter = logging.Formatter(settings.logger_formatter, datefmt=settings.logger_datefmt)
- global_handler = False
- if settings.enable_global_log_file:
- for handler in self._global.handlers:
- if settings.global_log_file_name in str(handler):
- global_handler = True
- break
- log_file = os.path.join(tempfile.gettempdir(), settings.global_log_file_name)
- my_handler = RotatingFileHandler(
- log_file,
- mode="a",
- maxBytes=float(settings.global_log_file_size) * 1024 * 1024,
- backupCount=2,
- encoding=None,
- delay=0,
- )
- my_handler.setFormatter(self.formatter)
- my_handler.setLevel(self.level)
- if not global_handler and settings.global_log_file_name:
- self._global.addHandler(my_handler)
- self._files_handlers.append(my_handler)
- if self.filename and os.path.exists(self.filename):
- shutil.rmtree(self.filename, ignore_errors=True)
- if self.filename and settings.enable_local_log_file:
- self.add_file_logger(self.filename, "Global", level)
-
- if to_stdout:
- settings.enable_screen_logs = True
- self._std_out_handler = logging.StreamHandler(sys.stdout)
- self._std_out_handler.setLevel(level)
- _logger_stdout_formatter = logging.Formatter("PyAEDT %(levelname)s: %(message)s")
-
- self._std_out_handler.setFormatter(_logger_stdout_formatter)
- self._global.addHandler(self._std_out_handler)
- self._timer = time.time()
-
- def add_file_logger(self, filename, project_name, level=None):
- """Add a new file to the logger handlers list."""
- _project = logging.getLogger(project_name)
- _project.setLevel(level if level else self.level)
- _project.addFilter(AppFilter("Project", project_name))
- _file_handler = logging.FileHandler(filename)
- _file_handler.setLevel(level if level else self.level)
- _file_handler.setFormatter(self.formatter)
- _project.addHandler(_file_handler)
- if self._std_out_handler is not None:
- _project.addHandler(self._std_out_handler)
- for handler in self._global.handlers:
- if settings.global_log_file_name in str(handler):
- _project.addHandler(handler)
- break
- self.info("New logger file {} added to handlers.".format(filename))
- self._files_handlers.append(_file_handler)
- _project.info_timer = self.info_timer
- _project.reset_timer = self.reset_timer
- _project._timer = time.time()
-
- return _project
-
- def remove_file_logger(self, project_name):
- """Remove a file from the logger handlers list."""
- handlers = [i for i in self._global.handlers]
- for handler in self._files_handlers:
- if "pyaedt_{}.log".format(project_name) in str(handler):
- handler.close()
- if handler in handlers:
- self._global.removeHandler(handler)
- self.info("logger file pyaedt_{}.log removed from handlers.".format(project_name))
-
- def remove_all_project_file_logger(self):
- """Remove all the local files from the logger handlers list."""
- handlers = [i for i in self._global.handlers]
- for handler in handlers:
- if "pyaedt_" in str(handler):
- handler.close()
- self._global.removeHandler(handler)
- self.info("Project files removed from handlers.")
-
- @property
- def _desktop(self):
- if "oDesktop" in dir(sys.modules["__main__"]):
- MainModule = sys.modules["__main__"]
- return MainModule.oDesktop
- return None # pragma: no cover
-
- @property
- def _log_on_desktop(self):
- try:
- if self._desktop and not self._desktop.GetIsNonGraphical() and settings.enable_desktop_logs:
- return True
- else:
- return False
- except: # pragma: no cover
- return False
-
- @_log_on_desktop.setter
- def _log_on_desktop(self, val):
- settings.enable_desktop_logs = val
-
- @property
- def _log_on_file(self):
- return settings.enable_file_logs
-
- @_log_on_file.setter
- def _log_on_file(self, val):
- settings.enable_file_logs = val
-
- @property
- def _log_on_screen(self):
- return settings.enable_screen_logs
-
- @_log_on_screen.setter
- def _log_on_screen(self, val):
- settings.enable_screen_logs = val
-
- @property
- def logger(self):
- """AEDT logger object."""
- if self._log_on_file:
- return logging.getLogger("Global")
- else:
- return None # pragma: no cover
-
- @property
- def messages(self):
- """Message manager content for the active project and design.
-
- Returns
- -------
- list of str
- List of messages for the active project and design.
-
- """
- return self.get_messages(self._project_name, self._design_name)
-
- def reset_timer(self, time_val=None):
- """ "Reset actual timer to actual time or specified time.
-
- Parameters
- ----------
- time_val : float, optional
- Value time to apply.
-
- Returns
- -------
-
- """
- if time_val:
- self._timer = time_val
- else:
- self._timer = time.time()
- return self._timer
-
- def get_messages(self, project_name=None, design_name=None, level=0, aedt_messages=False):
- """Get the message manager content for a specified project and design.
-
- If the specified project and design names are invalid, they are ignored.
-
- Parameters
- ----------
- project_name : str
- Name of the project to read messages from. Leave empty string to get Desktop level messages.
- design_name : str
- Name of the design to read messages from. Leave empty string to get Desktop level messages.
- level : int
- Level of messages to read. 0 – info and above, 1 – warning and above, 2 – error and fatal
- aedt_messages : bool
- Read content of message manager even if logger is disabled.
-
-
- Returns
- -------
- list of str
- List of messages for the specified project and design.
-
- """
- project_name = project_name or self._project_name
- design_name = design_name or self._design_name
- if self._log_on_desktop or aedt_messages:
- global_message_data = self._desktop.GetMessages("", "", level)
- # if a 3d component is open, GetMessages without the project name argument returns messages with
- # "(3D Component)" appended to project name
- if not any(msg in global_message_data for msg in self._desktop.GetMessages(project_name, "", 0)):
- project_name = project_name + " (3D Component)"
- return MessageList(global_message_data, project_name, design_name)
- return MessageList([], project_name, design_name)
-
- def add_error_message(self, message_text, level=None):
- """
- Add a type 2 "Error" message to the message manager tree.
-
- Also add an error message to the logger if the handler is present.
-
- Parameters
- ----------
- message_text : str
- Text to display as the error message.
- level : str, optional
- Level to add the error message to. Options are ``"Global"``,
- ``"Project"``, and ``"Design"``. The default is ``None``,
- in which case the error message gets added to the ``"Design"``
- level.
-
- Examples
- --------
- Add an error message to the AEDT message manager.
-
- >>> hfss.logger.project.error("Project Error Message", "Project")
-
- """
- self.add_message(2, message_text, level)
-
- def add_warning_message(self, message_text, level=None):
- """
- Add a type 1 "Warning" message to the message manager tree.
-
- Also add a warning message to the logger if the handler is present.
-
- Parameters
- ----------
- message_text : str
- Text to display as the warning message.
- level : str, optional
- Level to add the warning message to. Options are ``"Global"``,
- ``"Project"``, and ``"Design"``. The default is ``None``,
- in which case the warning message gets added to the ``"Design"``
- level.
-
- Examples
- --------
- Add a warning message to the AEDT message manager.
-
- >>> hfss.logger.warning("Global warning message")
-
- """
- self.add_message(1, message_text, level)
-
- def add_info_message(self, message_text, level=None):
- """Add a type 0 "Info" message to the active design level of the message manager tree.
-
- Also add an info message to the logger if the handler is present.
-
- Parameters
- ----------
- message_text : str
- Text to display as the info message.
- level : str, optional
- Level to add the info message to. Options are ``"Global"``,
- ``"Project"``, and ``"Design"``. The default is ``None``,
- in which case the info message gets added to the ``"Design"``
- level.
-
- Examples
- --------
- Add an info message at the global level.
-
- >>> hfss.logger.info("Global warning message", "Global")
-
- """
- self.add_message(0, message_text, level)
-
- def add_debug_message(self, message_text, level=None):
- """
- Parameterized message to the message manager to specify the type and project or design level.
-
- Parameters
- ----------
- message_text : str
- Text to display as the message.
- level : str, optional
- Level to add the info message to. Options are ``"Global"``,
- ``"Project"``, and ``"Design"``. The default value is ``None``,
- in which case the info message gets added to the ``"Design"``
- level.
- """
-
- return self.add_message(3, message_text, level=level)
-
- def add_message(self, message_type, message_text, level=None, proj_name=None, des_name=None):
- """Add a message to the message manager to specify the type and project or design level.
-
- Parameters
- ----------
- message_type : int
- Type of the message. Options are:
- * ``0`` : Info
- * ``1`` : Warning
- * ``2`` : Error
- * ``3`` : Debug
- message_text : str
- Text to display as the message.
- level : str, optional
- Level to add the message to. Options are ``"Global"``,
- ``"Project"``, and ``"Design"``. The default is ``None``,
- in which case the message gets added to the
- ``"Design"`` level.
- proj_name : str, optional
- Name of the project.
- des_name : str, optional
- Name of the design.
- """
- self._log_on_dekstop(
- message_type=message_type, message_text=message_text, level=level, proj_name=proj_name, des_name=des_name
- )
-
- self._log_on_handler(message_type, message_text)
-
- def _log_on_dekstop(self, message_type, message_text, level=None, proj_name=None, des_name=None):
- if not proj_name:
- proj_name = ""
-
- if not des_name:
- des_name = ""
-
- if not level:
- level = "Design"
-
- assert level in message_levels, "Message level must be `Design', 'Project', or 'Global'."
-
- if self._log_on_desktop and self._desktop:
- if not proj_name and message_levels[level] > 0:
- proj_name = self._project_name
- if not des_name and message_levels[level] > 1:
- des_name = self._design_name
- if des_name and ";" in des_name:
- des_name = des_name[des_name.find(";") + 1 :]
- try:
- self._desktop.AddMessage(proj_name, des_name, message_type, message_text)
- except:
- print("PyAEDT INFO: Failed in Adding Desktop Message")
-
- def _log_on_handler(self, message_type, message_text, *args, **kwargs):
- if not (self._log_on_file or self._log_on_screen) or not self._global:
- return
- if len(message_text) > 250:
- message_text = message_text[:250] + "..."
- if message_type == 0:
- self._global.info(message_text, *args, **kwargs)
- elif message_type == 1:
- self._global.warning(message_text, *args, **kwargs)
- elif message_type == 2:
- self._global.error(message_text, *args, **kwargs)
- elif message_type == 3:
- self._global.debug(message_text, *args, **kwargs)
-
- def clear_messages(self, proj_name=None, des_name=None, level=2):
- """Clear all messages.
-
- Parameters
- ----------
- proj_name : str, optional
- Name of project. The default is ``None``, in which case messages
- are cleared for the current project. If blank, messages are cleared
- for all projects.
- des_name : str, optional
- Name of the design within the specified project. The default
- is ``None,`` in which case the current design is used.
- If blank, all designs are used.
- level : int, optional
- Level of the messages to clear. Options are:
-
- * ``0`` : Clear all info messages.
- * ``1`` : Clear all info and warning messages.
- * ``2`` : Clear all info, warning, and error messages.
- * ``3`` : Clear all messages, which include info, warning,
- error, and fatal-error messages.
-
- The default is ``2.``
-
- Examples
- --------
- Clear all messages in the current design and project.
-
- >>> hfss.clear_messages(level=3)
-
- """
- if self._log_on_desktop:
- if proj_name is None:
- proj_name = self._project_name
- if des_name is None:
- des_name = self._design_name
- self._desktop.ClearMessages(proj_name, des_name, level)
-
- @property
- def _oproject(self):
- if self._desktop:
- return self._desktop.GetActiveProject()
-
- @property
- def _odesign(self):
- if self._oproject:
- return self._oproject.GetActiveDesign()
-
- @property
- def _design_name(self):
- try:
- return self._odesign.GetName()
- except AttributeError:
- return ""
-
- @property
- def _project_name(self):
- try:
- return self._oproject.GetName()
- except AttributeError:
- return ""
-
- def add_logger(self, destination, level=logging.DEBUG):
- """
- Add a logger for either the active project or active design.
-
- Parameters
- ----------
- destination : str
- Logger to write to. Options are ``"Project"`` and ``"Design"``.
- level : int, optional
- Logging level enum. The default is ``logging.DEBUG``.
- """
-
- if destination == "Project":
- project_name = self._project_name
- self._project = logging.getLogger(project_name)
- self._project.setLevel(level)
- self._project.addFilter(AppFilter("Project", project_name))
- if self._files_handlers:
- for handler in self._files_handlers:
- self._project.addHandler(handler)
- if self._std_out_handler is not None:
- self._project.addHandler(self._std_out_handler)
- return self._project
- elif destination == "Design":
- project_name = self._project_name
- design_name = self._design_name
- self._design = logging.getLogger(project_name + ":" + design_name)
- self._design.setLevel(level)
- self._design.addFilter(AppFilter("Design", design_name))
- if self._files_handlers:
- for handler in self._files_handlers:
- self._design.addHandler(handler)
- if self._std_out_handler is not None:
- self._design.addHandler(self._std_out_handler)
- return self._design
- else:
- raise ValueError("The destination must be either 'Project' or 'Design'.")
-
- def disable_desktop_log(self):
- """Disable the log in AEDT."""
- self._log_on_desktop = False
- self.info("Log on Desktop Message Manager is disabled")
-
- def enable_desktop_log(self):
- """Enable the log in AEDT."""
- self._log_on_desktop = True
- self.info("Log on Desktop Message Manager is enabled")
-
- def disable_stdout_log(self):
- """Disable printing log messages to stdout."""
- self._log_on_screen = False
- self._global.removeHandler(self._std_out_handler)
- self.info("StdOut is disabled")
-
- def enable_stdout_log(self):
- """Enable printing log messages to stdout."""
- self._log_on_screen = True
- if not self._std_out_handler:
- self._std_out_handler = logging.StreamHandler(sys.stdout)
- self._std_out_handler.setLevel(self.level)
- _logger_stdout_formatter = logging.Formatter("legacy %(levelname)s: %(message)s")
-
- self._std_out_handler.setFormatter(_logger_stdout_formatter)
- self._global.addHandler(self._std_out_handler)
- self._global.addHandler(self._std_out_handler)
- self.info("StdOut is enabled")
-
- def disable_log_on_file(self):
- """Disable writing log messages to an output file."""
- self._log_on_file = False
- for _file_handler in self._files_handlers:
- _file_handler.close()
- self._global.removeHandler(_file_handler)
- self.info("Log on file is disabled")
-
- def enable_log_on_file(self):
- """Enable writing log messages to an output file."""
- self._log_on_file = True
- for _file_handler in self._files_handlers:
- self._global.addHandler(_file_handler)
- self.info("Log on file is enabled")
-
- def info(self, msg, *args, **kwargs):
- """Write an info message to the global logger."""
- if not settings.enable_logger:
- return
- if args:
- try:
- msg1 = msg % tuple(str(i) for i in args)
- except TypeError:
- msg1 = msg
- else:
- msg1 = msg
- self._log_on_dekstop(0, msg1, "Global")
- return self._log_on_handler(0, msg, *args, **kwargs)
-
- def info_timer(self, msg, start_time=None, *args, **kwargs):
- """Write an info message to the global logger with elapsed time.
- Message will have an appendix of type Elapsed time: time."""
- if not settings.enable_logger:
- return
- if not start_time:
- start_time = self._timer
- td = time.time() - start_time
- m, s = divmod(td, 60)
- h, m = divmod(m, 60)
- d, h = divmod(h, 24)
- if d > 0:
- msg += " Elapsed time: {}days {}h {}m {}sec".format(round(d), round(h), round(m), round(s))
- elif h > 0:
- msg += " Elapsed time: {}h {}m {}sec".format(round(h), round(m), round(s))
- else:
- msg += " Elapsed time: {}m {}sec".format(round(m), round(s))
- if args:
- try:
- msg1 = msg % tuple(str(i) for i in args)
- except TypeError:
- msg1 = msg
- else:
- msg1 = msg
- self._log_on_dekstop(0, msg1, "Global")
- return self._log_on_handler(0, msg, *args, **kwargs)
-
- def warning(self, msg, *args, **kwargs):
- """Write a warning message to the global logger."""
- if not settings.enable_logger:
- return
- if args:
- try:
- msg1 = msg % tuple(str(i) for i in args)
- except TypeError:
- msg1 = msg
- else:
- msg1 = msg
- self._log_on_dekstop(1, msg1, "Global")
- return self._log_on_handler(1, msg, *args, **kwargs)
-
- def error(self, msg, *args, **kwargs):
- """Write an error message to the global logger."""
- if args:
- try:
- msg1 = msg % tuple(str(i) for i in args)
- except TypeError:
- msg1 = msg
- else:
- msg1 = msg
- self._log_on_dekstop(2, msg1, "Global")
- return self._log_on_handler(2, msg, *args, **kwargs)
-
- def debug(self, msg, *args, **kwargs):
- """Write a debug message to the global logger."""
- if not settings.enable_debug_logger or not settings.enable_logger:
- return
- if args:
- try:
- msg1 = msg % tuple(str(i) for i in args)
- except TypeError:
- msg1 = msg
- else:
- msg1 = msg
- self._log_on_dekstop(0, msg1, "Global")
- return self._log_on_handler(3, msg, *args, **kwargs)
-
- @property
- def glb(self):
- """Global logger."""
- self._global = logging.getLogger("Global")
- return self._global
-
- @property
- def project(self):
- """Project logger."""
- self._project = logging.getLogger(self._project_name)
- if not self._project.handlers:
- self.add_logger("Project")
- return self._project
-
- @property
- def design(self):
- """Design logger."""
- self._design = logging.getLogger(self._project_name + ":" + self._design_name)
- if not self._design.handlers:
- self.add_logger("Design")
- return self._design
-
-
-pyaedt_logger = AedtLogger(to_stdout=settings.enable_screen_logs)
diff --git a/src/pyedb/legacy/application/Variables.py b/src/pyedb/legacy/application/Variables.py
index 10b8fc9280..2d183fd78b 100644
--- a/src/pyedb/legacy/application/Variables.py
+++ b/src/pyedb/legacy/application/Variables.py
@@ -348,7 +348,7 @@ class VariableManager(object):
This class provides access to all variables or a subset of the
variables. Manipulation of the numerical or string definitions of
variable values is provided in the
- :class:`pyaedt.application.Variables.Variable` class.
+ :class:`pyedb.legacy.application.Variables.Variable` class.
Parameters
----------
@@ -390,7 +390,7 @@ class VariableManager(object):
See Also
--------
- pyaedt.application.Variables.Variable
+ pyedb.legacy.application.Variables.Variable
Examples
--------
@@ -414,23 +414,23 @@ class VariableManager(object):
Get a dictionary of all project and design variables.
>>> v.variables
- {'Var1': ,
- 'Var2': ,
- 'Var3': ,
- '$PrjVar1': }
+ {'Var1': ,
+ 'Var2': ,
+ 'Var3': ,
+ '$PrjVar1': }
Get a dictionary of only the design variables.
>>> v.design_variables
- {'Var1': ,
- 'Var2': ,
- 'Var3': }
+ {'Var1': ,
+ 'Var2': ,
+ 'Var3': }
Get a dictionary of only the independent design variables.
>>> v.independent_design_variables
- {'Var1': ,
- 'Var2': }
+ {'Var1': ,
+ 'Var2': }
"""
@@ -1275,7 +1275,7 @@ class Variable(object):
Examples
--------
- >>> from pyaedt.application.Variables import Variable
+ >>> from pyedb.legacy.application.Variables import Variable
Define a variable using a string value consistent with the AEDT properties.
@@ -1712,7 +1712,7 @@ def rescale_to(self, units):
Examples
--------
- >>> from pyaedt.application.Variables import Variable
+ >>> from pyedb.legacy.application.Variables import Variable
>>> v = Variable("10W")
>>> assert v.numeric_value == 10
@@ -1746,7 +1746,7 @@ def format(self, format):
Examples
--------
- >>> from pyaedt.application.Variables import Variable
+ >>> from pyedb.legacy.application.Variables import Variable
>>> v = Variable("10W")
>>> assert v.format("f") == '10.000000W'
@@ -1772,7 +1772,7 @@ def __mul__(self, other):
Examples
--------
- >>> from pyaedt.application.Variables import Variable
+ >>> from pyedb.legacy.application.Variables import Variable
Multiply ``'Length1'`` by unitless ``'None'``` to obtain ``'Length'``.
A numerical value is also considered to be unitless.
@@ -1821,7 +1821,7 @@ def __add__(self, other):
Parameters
----------
- other : class:`pyaedt.application.Variables.Variable`
+ other : class:`pyedb.legacy.application.Variables.Variable`
Object to be multiplied.
Returns
@@ -1831,7 +1831,7 @@ def __add__(self, other):
Examples
--------
- >>> from pyaedt.application.Variables import Variable
+ >>> from pyedb.legacy.application.Variables import Variable
>>> import pyaedt.generic.constants
>>> v1 = Variable("3mA")
>>> v2 = Variable("10A")
@@ -1862,7 +1862,7 @@ def __sub__(self, other):
Parameters
----------
- other : class:`pyaedt.application.Variables.Variable`
+ other : class:`pyedb.legacy.application.Variables.Variable`
Object to be subtracted.
Returns
@@ -1874,7 +1874,7 @@ def __sub__(self, other):
--------
>>> import pyaedt.generic.constants
- >>> from pyaedt.application.Variables import Variable
+ >>> from pyedb.legacy.application.Variables import Variable
>>> v3 = Variable("3mA")
>>> v4 = Variable("10A")
>>> result_2 = v3 - v4
@@ -1918,7 +1918,7 @@ def __truediv__(self, other):
Divide a variable with units ``"W"`` by a variable with units ``"V"`` and automatically
resolve the new units to ``"A"``.
- >>> from pyaedt.application.Variables import Variable
+ >>> from pyedb.legacy.application.Variables import Variable
>>> import pyaedt.generic.constants
>>> v1 = Variable("10W")
>>> v2 = Variable("40V")
@@ -1963,7 +1963,7 @@ def __rtruediv__(self, other):
the result is in ``"Hz"``.
>>> import pyaedt.generic.constants
- >>> from pyaedt.application.Variables import Variable
+ >>> from pyedb.legacy.application.Variables import Variable
>>> v = Variable("1s")
>>> result = 3.0 / v
>>> assert result.numeric_value == 3.0
diff --git a/src/pyedb/legacy/generic/clr_module.py b/src/pyedb/legacy/clr_module.py
similarity index 67%
rename from src/pyedb/legacy/generic/clr_module.py
rename to src/pyedb/legacy/clr_module.py
index 553a535771..165511fe93 100644
--- a/src/pyedb/legacy/generic/clr_module.py
+++ b/src/pyedb/legacy/clr_module.py
@@ -4,12 +4,19 @@
import warnings
modules = [tup[1] for tup in pkgutil.iter_modules()]
-pyaedt_path = os.path.dirname(os.path.dirname(__file__))
cpython = "IronPython" not in sys.version and ".NETFramework" not in sys.version
is_linux = os.name == "posix"
is_windows = not is_linux
is_clr = False
-sys.path.append(os.path.join(pyaedt_path, "dlls", "PDFReport"))
+
+try:
+ import pyaedt
+ pyaedt_path = os.path.dirname(os.path.abspath(pyaedt.__file__))
+ sys.path.append(os.path.join(pyaedt_path, "dlls", "PDFReport"))
+except ImportError:
+ pyaedt_path = None
+ warnings.warn("Cannot import pyaedt.")
+
if is_linux and cpython: # pragma: no cover
try:
if os.environ.get("DOTNET_ROOT") is None:
@@ -27,17 +34,20 @@
from pythonnet import load
- json_file = os.path.abspath(os.path.join(pyaedt_path, "misc", "pyaedt.runtimeconfig.json"))
- load("coreclr", runtime_config=json_file, dotnet_root=os.environ["DOTNET_ROOT"])
- print("DotNet Core correctly loaded.")
- if "mono" not in os.getenv("LD_LIBRARY_PATH", ""):
- warnings.warn("LD_LIBRARY_PATH needs to be setup to use pyaedt.")
- warnings.warn("export ANSYSEM_ROOT232=/path/to/AnsysEM/v232/Linux64")
- msg = "export LD_LIBRARY_PATH="
- msg += "$ANSYSEM_ROOT232/common/mono/Linux64/lib64:$LD_LIBRARY_PATH"
- msg += "If PyAEDT will run on AEDT<2023.2 then $ANSYSEM_ROOT222/Delcross should be added to LD_LIBRARY_PATH"
- warnings.warn(msg)
- is_clr = True
+ if pyaedt_path is not None:
+ json_file = os.path.abspath(os.path.join(pyaedt_path, "misc", "pyaedt.runtimeconfig.json"))
+ load("coreclr", runtime_config=json_file, dotnet_root=os.environ["DOTNET_ROOT"])
+ print("DotNet Core correctly loaded.")
+ if "mono" not in os.getenv("LD_LIBRARY_PATH", ""):
+ warnings.warn("LD_LIBRARY_PATH needs to be setup to use pyaedt.")
+ warnings.warn("export ANSYSEM_ROOT232=/path/to/AnsysEM/v232/Linux64")
+ msg = "export LD_LIBRARY_PATH="
+ msg += "$ANSYSEM_ROOT232/common/mono/Linux64/lib64:$LD_LIBRARY_PATH"
+ msg += "If PyAEDT will run on AEDT<2023.2 then $ANSYSEM_ROOT222/Delcross should be added to LD_LIBRARY_PATH"
+ warnings.warn(msg)
+ is_clr = True
+ else:
+ print("DotNet Core not correctly loaded.")
except ImportError:
msg = "pythonnet or dotnetcore not installed. Pyaedt will work only in client mode."
warnings.warn(msg)
diff --git a/src/pyedb/legacy/downloads.py b/src/pyedb/legacy/downloads.py
index fd07c9a260..29a314be34 100644
--- a/src/pyedb/legacy/downloads.py
+++ b/src/pyedb/legacy/downloads.py
@@ -127,12 +127,12 @@ def _retrieve_folder(url, directory, destination=None, local_paths=[]):
def _download_file(directory, filename=None, destination=None, local_paths=[]):
if not filename:
- # TODO: Remove this once pyedb is available in public
+ # TODO: Update this once pyedb is available in public
if not directory.startswith("pyaedt/"):
directory = "pyaedt/" + directory
_retrieve_folder(EXAMPLE_REPO, directory, destination, local_paths)
else:
- # TODO: Remove this once pyedb is available in public
+ # TODO: Update this once pyedb is available in public
if directory.startswith("pyaedt/"):
url = _get_file_url(directory, filename)
directory = directory[7:]
@@ -245,7 +245,7 @@ def download_netlist(destination=None):
>>> import legacy
>>> path = legacy.downloads.download_netlist()
>>> path
- 'C:/Users/user/AppData/local/temp/pyaedtexamples/netlist_small.cir'
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/netlist_small.cir'
"""
local_paths = []
_download_file("legacy/netlist", "netlist_small.cir", destination, local_paths)
@@ -276,7 +276,7 @@ def download_antenna_array(destination=None):
>>> import legacy
>>> path = legacy.downloads.download_antenna_array()
>>> path
- 'C:/Users/user/AppData/local/temp/pyaedtexamples/FiniteArray_Radome_77GHz_3D_CADDM.aedt'
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/FiniteArray_Radome_77GHz_3D_CADDM.aedt'
"""
local_paths = []
@@ -307,7 +307,7 @@ def download_sbr(destination=None):
>>> import legacy
>>> path = legacy.downloads.download_antenna_array()
>>> path
- 'C:/Users/user/AppData/local/temp/pyaedtexamples/FiniteArray_Radome_77GHz_3D_CADDM.aedt'
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/FiniteArray_Radome_77GHz_3D_CADDM.aedt'
"""
local_paths = []
@@ -338,7 +338,7 @@ def download_sbr_time(destination=None):
>>> import legacy
>>> path = legacy.downloads.download_sbr_time()
>>> path
- 'C:/Users/user/AppData/local/temp/pyaedtexamples/sbr/poc_scat_small.aedt'
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/sbr/poc_scat_small.aedt'
"""
return _download_file("legacy/sbr", "poc_scat_small.aedt", destination)
@@ -367,7 +367,7 @@ def download_icepak(destination=None):
>>> import legacy
>>> path = legacy.downloads.download_icepak()
>>> pathavoid
- 'C:/Users/user/AppData/local/temp/pyaedtexamples/Graphic_Card.aedt'
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/Graphic_Card.aedt'
"""
_download_file("legacy/icepak", "Graphics_card.aedt", destination)
return _download_file("legacy/icepak", "Graphics_card.aedt", destination)
@@ -398,7 +398,7 @@ def download_icepak_3d_component(destination=None): # pragma: no cover
>>> import legacy
>>> path1, path2 = legacy.downloads.download_icepak_3d_component()
>>> path1
- 'C:/Users/user/AppData/local/temp/pyaedtexamples/PCBAssembly.aedt',
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/PCBAssembly.aedt',
"""
local_paths = []
_download_file("legacy/icepak_3dcomp//PCBAssembly.aedb", destination=destination)
@@ -430,7 +430,7 @@ def download_via_wizard(destination=None):
>>> import legacy
>>> path = legacy.downloads.download_via_wizard()
>>> path
- 'C:/Users/user/AppData/local/temp/pyaedtexamples/Graphic_Card.aedt'
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/Graphic_Card.aedt'
"""
return _download_file("legacy/via_wizard", "viawizard_vacuum_FR4.aedt", destination)
@@ -458,7 +458,7 @@ def download_touchstone(destination=None):
>>> import legacy
>>> path = legacy.downloads.download_touchstone()
>>> path
- 'C:/Users/user/AppData/local/temp/pyaedtexamples/ssn_ssn.s6p'
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/ssn_ssn.s6p'
"""
local_paths = []
_download_file("legacy/touchstone", "SSN_ssn.s6p", destination, local_paths)
@@ -746,7 +746,7 @@ def download_file(directory, filename=None, destination=None):
>>> import legacy
>>> path = legacy.downloads.download_file("motorcad", "IPM_Vweb_Hairpin.mot")
>>> path
- 'C:/Users/user/AppData/local/temp/PyAEDTExamples/motorcad'
+ 'C:/Users/user/AppData/local/temp/pyedbtexamples/motorcad'
"""
local_paths = []
_download_file(directory, filename, destination, local_paths)
diff --git a/src/pyedb/legacy/edb.py b/src/pyedb/legacy/edb.py
index ba8dfa6401..667351e7a5 100644
--- a/src/pyedb/legacy/edb.py
+++ b/src/pyedb/legacy/edb.py
@@ -178,7 +178,7 @@ def __init__(
self.log_name = None
if edbpath:
self.log_name = os.path.join(
- os.path.dirname(edbpath), "pyaedt_" + os.path.splitext(os.path.split(edbpath)[-1])[0] + ".log"
+ os.path.dirname(edbpath), "pyedb_" + os.path.splitext(os.path.split(edbpath)[-1])[0] + ".log"
)
if isaedtowned and (inside_desktop or settings.remote_api or settings.remote_rpc_session):
@@ -234,7 +234,7 @@ def __getitem__(self, variable_name):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.variables.Variable`
+ :class:`pyedb.legacy.edb_core.edb_data.variables.Variable`
"""
if self.variable_exists(variable_name)[0]:
@@ -704,7 +704,7 @@ def components(self):
Returns
-------
- :class:`pyaedt.edb_core.components.Components`
+ :class:`pyedb.legacy.edb_core.components.Components`
Examples
--------
@@ -886,7 +886,7 @@ def hfss(self):
Returns
-------
- :class:`pyaedt.edb_core.hfss.EdbHfss`
+ :class:`pyedb.legacy.edb_core.hfss.EdbHfss`
Examples
--------
@@ -906,7 +906,7 @@ def core_nets(self): # pragma: no cover
Returns
-------
- :class:`pyaedt.edb_core.nets.EdbNets`
+ :class:`pyedb.legacy.edb_core.nets.EdbNets`
Examples
--------
@@ -923,7 +923,7 @@ def nets(self):
Returns
-------
- :class:`pyaedt.edb_core.nets.EdbNets`
+ :class:`pyedb.legacy.edb_core.nets.EdbNets`
Examples
--------
@@ -1296,7 +1296,7 @@ def save_edb_as(self, fname):
self._logger = self._global_logger
self.log_name = os.path.join(
- os.path.dirname(fname), "pyaedt_" + os.path.splitext(os.path.split(fname)[-1])[0] + ".log"
+ os.path.dirname(fname), "pyedb_" + os.path.splitext(os.path.split(fname)[-1])[0] + ".log"
)
if settings.enable_local_log_file:
self._logger = self._global_logger.add_file_logger(self.log_name, "Edb")
@@ -2905,7 +2905,7 @@ def get_variable(self, variable_name):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.edbvalue.EdbValue`
+ :class:`pyedb.legacy.edb_core.edb_data.edbvalue.EdbValue`
"""
var_server = self.variable_exists(variable_name)
if var_server[0]:
@@ -3044,7 +3044,7 @@ def build_simulation_project(self, simulation_setup):
Parameters
----------
- simulation_setup : :class:`pyaedt.edb_core.edb_data.simulation_configuration.SimulationConfiguration` object.
+ simulation_setup : :class:`pyedb.legacy.edb_core.edb_data.simulation_configuration.SimulationConfiguration` object.
SimulationConfiguration object that can be instantiated or directly loaded with a
configuration file.
@@ -3308,7 +3308,7 @@ def new_simulation_configuration(self, filename=None):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.simulation_configuration.SimulationConfiguration`
+ :class:`pyedb.legacy.edb_core.edb_data.simulation_configuration.SimulationConfiguration`
"""
return SimulationConfiguration(filename, self)
@@ -3374,7 +3374,7 @@ def create_hfss_setup(self, name=None):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.HfssSimulationSetup`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.HfssSimulationSetup`
Examples
--------
@@ -3398,7 +3398,7 @@ def create_siwave_syz_setup(self, name=None):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.siwave_simulation_setup_data.SiwaveSYZSimulationSetup`
+ :class:`pyedb.legacy.edb_core.edb_data.siwave_simulation_setup_data.SiwaveSYZSimulationSetup`
Examples
--------
@@ -3430,7 +3430,7 @@ def create_siwave_dc_setup(self, name=None):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.siwave_simulation_setup_data.SiwaveSYZSimulationSetup`
+ :class:`pyedb.legacy.edb_core.edb_data.siwave_simulation_setup_data.SiwaveSYZSimulationSetup`
Examples
--------
@@ -3648,15 +3648,15 @@ def create_port(self, terminal, ref_terminal=None, is_circuit_port=False):
"""Create a port between two terminals.
Parameters
----------
- terminal : class:`pyaedt.edb_core.edb_data.terminals.EdgeTerminal`,
- class:`pyaedt.edb_core.edb_data.terminals.PadstackInstanceTerminal`,
- class:`pyaedt.edb_core.edb_data.terminals.PointTerminal`,
- class:`pyaedt.edb_core.edb_data.terminals.PinGroupTerminal`,
+ terminal : class:`pyedb.legacy.edb_core.edb_data.terminals.EdgeTerminal`,
+ class:`pyedb.legacy.edb_core.edb_data.terminals.PadstackInstanceTerminal`,
+ class:`pyedb.legacy.edb_core.edb_data.terminals.PointTerminal`,
+ class:`pyedb.legacy.edb_core.edb_data.terminals.PinGroupTerminal`,
Positive terminal of the port.
- ref_terminal : class:`pyaedt.edb_core.edb_data.terminals.EdgeTerminal`,
- class:`pyaedt.edb_core.edb_data.terminals.PadstackInstanceTerminal`,
- class:`pyaedt.edb_core.edb_data.terminals.PointTerminal`,
- class:`pyaedt.edb_core.edb_data.terminals.PinGroupTerminal`,
+ ref_terminal : class:`pyedb.legacy.edb_core.edb_data.terminals.EdgeTerminal`,
+ class:`pyedb.legacy.edb_core.edb_data.terminals.PadstackInstanceTerminal`,
+ class:`pyedb.legacy.edb_core.edb_data.terminals.PointTerminal`,
+ class:`pyedb.legacy.edb_core.edb_data.terminals.PinGroupTerminal`,
optional
Negative terminal of the port.
is_circuit_port : bool, optional
diff --git a/src/pyedb/legacy/edb_core/components.py b/src/pyedb/legacy/edb_core/components.py
index 6ee0266c39..5efbde1f05 100644
--- a/src/pyedb/legacy/edb_core/components.py
+++ b/src/pyedb/legacy/edb_core/components.py
@@ -15,8 +15,8 @@
from pyedb.legacy.edb_core.edb_data.sources import SourceType
from pyedb.legacy.edb_core.general import convert_py_list_to_net_list
from pyedb.legacy.edb_core.padstack import EdbPadstacks
-from pyedb.legacy.generic.clr_module import String
-from pyedb.legacy.generic.clr_module import _clr
+from pyedb.legacy.clr_module import String
+from pyedb.legacy.clr_module import _clr
from pyedb.generic.general_methods import get_filename_without_extension
from pyedb.generic.general_methods import is_ironpython
from pyedb.generic.general_methods import pyedb_function_handler
@@ -56,7 +56,7 @@ class Components(object):
Parameters
----------
- edb_class : :class:`pyaedt.edb.Edb`
+ edb_class : :class:`pyedb.legacy.edb.Edb`
Examples
--------
@@ -75,7 +75,7 @@ def __getitem__(self, name):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`
+ :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`
"""
if name in self.instances:
@@ -151,7 +151,7 @@ def components(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
Default dictionary for the EDB component.
Examples
@@ -171,7 +171,7 @@ def instances(self):
Returns
-------
- Dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ Dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
Default dictionary for the EDB component.
Examples
@@ -192,7 +192,7 @@ def definitions(self):
Returns
-------
- dict of :class:`pyaedt.edb_core.edb_data.components_data.EDBComponentDef`"""
+ dict of :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponentDef`"""
return {l.GetName(): EDBComponentDef(self._pedb, l) for l in list(self._pedb.component_defs)}
@property
@@ -303,7 +303,7 @@ def resistors(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
Dictionary of resistors.
Examples
@@ -325,7 +325,7 @@ def capacitors(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
Dictionary of capacitors.
Examples
@@ -347,7 +347,7 @@ def inductors(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
Dictionary of inductors.
Examples
@@ -370,7 +370,7 @@ def ICs(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
Dictionary of integrated circuits.
Examples
@@ -393,7 +393,7 @@ def IOs(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
Dictionary of circuit inputs and outputs.
Examples
@@ -416,7 +416,7 @@ def Others(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
Dictionary of other core components.
Examples
diff --git a/src/pyedb/legacy/edb_core/dotnet/database.py b/src/pyedb/legacy/edb_core/dotnet/database.py
index 5697afcd72..c2111979ec 100644
--- a/src/pyedb/legacy/edb_core/dotnet/database.py
+++ b/src/pyedb/legacy/edb_core/dotnet/database.py
@@ -141,7 +141,7 @@ def create_from_bbox(self, points):
----------
points : list or `Edb.Geometry.PointData`
"""
- from pyedb.legacy.generic.clr_module import Tuple
+ from pyedb.legacy.clr_module import Tuple
if isinstance(points, (tuple, list)):
points = Tuple[self._pedb.edb_api.Geometry.PointData, self._pedb.edb_api.Geometry.PointData](
@@ -655,7 +655,7 @@ def cell(self):
Returns
-------
- :class:`pyaedt.edb_core.dotnet.database.CellClassDotNet`"""
+ :class:`pyedb.legacy.edb_core.dotnet.database.CellClassDotNet`"""
return CellClassDotNet(self._app)
@property
@@ -664,7 +664,7 @@ def utility(self):
Returns
-------
- :class:`pyaedt.edb_core.dotnet.database.UtilityDotNet`"""
+ :class:`pyedb.legacy.edb_core.dotnet.database.UtilityDotNet`"""
return UtilityDotNet(self._app)
@@ -674,7 +674,7 @@ def geometry(self):
Returns
-------
- :class:`pyaedt.edb_core.dotnet.database.GeometryDotNet`"""
+ :class:`pyedb.legacy.edb_core.dotnet.database.GeometryDotNet`"""
return GeometryDotNet(self._app)
@@ -693,8 +693,8 @@ def __init__(self, edbversion, student_version=False):
self.edbversion = edbversion
self.student_version = student_version
"""Initialize DLLs."""
- from pyedb.legacy.generic.clr_module import _clr
- from pyedb.legacy.generic.clr_module import edb_initialized
+ from pyedb.legacy.clr_module import _clr
+ from pyedb.legacy.clr_module import edb_initialized
if settings.enable_screen_logs:
self._logger.enable_stdout_log()
@@ -770,7 +770,7 @@ def logger(self):
Returns
-------
- :class:`pyaedt.aedt_logger.AedtLogger`
+ :class:`pyedb.edb_logger.EDBLogger`
"""
return self._logger
@@ -780,7 +780,7 @@ def edb_api(self):
Returns
-------
- :class:`pyaedt.edb_core.dotnet.database.CellDotNet`
+ :class:`pyedb.legacy.edb_core.dotnet.database.CellDotNet`
"""
return CellDotNet(self)
diff --git a/src/pyedb/legacy/edb_core/dotnet/primitive.py b/src/pyedb/legacy/edb_core/dotnet/primitive.py
index 92a2cd6417..823febd9d3 100644
--- a/src/pyedb/legacy/edb_core/dotnet/primitive.py
+++ b/src/pyedb/legacy/edb_core/dotnet/primitive.py
@@ -366,7 +366,7 @@ def create(self, layout, layer, net, rep_type, param1, param2, param3, param4, c
Returns
-------
- :class:`pyaedt.edb_core.dotnet.primitive.RectangleDotNet`
+ :class:`pyedb.legacy.edb_core.dotnet.primitive.RectangleDotNet`
Rectangle that was created.
"""
@@ -490,7 +490,7 @@ def create(self, layout, layer, net, center_x, center_y, radius):
Returns
-------
- :class:`pyaedt.edb_core.dotnet.primitive.CircleDotNet`
+ :class:`pyedb.legacy.edb_core.dotnet.primitive.CircleDotNet`
Circle object created.
"""
if isinstance(net, NetDotNet):
@@ -581,7 +581,7 @@ def create(self, layout, layer, center_x, center_y, text):
Returns
-------
- :class:`pyaedt.edb_core.dotnet.primitive.TextDotNet`
+ :class:`pyedb.legacy.edb_core.dotnet.primitive.TextDotNet`
The text Object that was created.
"""
return TextDotNet(
@@ -658,7 +658,7 @@ def create(self, layout, layer, net, polygon_data):
Returns
-------
- :class:`pyaedt.edb_core.dotnet.primitive.PolygonDotNet`
+ :class:`pyedb.legacy.edb_core.dotnet.primitive.PolygonDotNet`
Polygon object created.
"""
if isinstance(net, NetDotNet):
@@ -704,7 +704,7 @@ def create(self, layout, layer, net, width, end_cap1, end_cap2, corner_style, po
Returns
-------
- :class:`pyaedt.edb_core.dotnet.primitive.PathDotNet`
+ :class:`pyedb.legacy.edb_core.dotnet.primitive.PathDotNet`
Path object created.
"""
if isinstance(net, NetDotNet):
@@ -892,7 +892,7 @@ def create(
Returns
-------
- :class:`pyaedt.edb_core.dotnet.primitive.BondwireDotNet`
+ :class:`pyedb.legacy.edb_core.dotnet.primitive.BondwireDotNet`
Bondwire object created.
"""
if isinstance(net, NetDotNet):
@@ -1145,7 +1145,7 @@ def create(
Returns
-------
- :class:`pyaedt.edb_core.dotnet.primitive.PadstackInstanceDotNet`
+ :class:`pyedb.legacy.edb_core.dotnet.primitive.PadstackInstanceDotNet`
Padstack instance object created.
"""
if isinstance(net, NetDotNet):
diff --git a/src/pyedb/legacy/edb_core/edb_data/components_data.py b/src/pyedb/legacy/edb_core/edb_data/components_data.py
index 450d74b52b..d91e237a82 100644
--- a/src/pyedb/legacy/edb_core/edb_data/components_data.py
+++ b/src/pyedb/legacy/edb_core/edb_data/components_data.py
@@ -23,7 +23,7 @@ class EDBComponentDef(object):
Parameters
----------
- parent : :class:`pyaedt.edb_core.components.Components`
+ parent : :class:`pyedb.legacy.edb_core.components.Components`
Inherited AEDT object.
comp_def : object
Edb ComponentDef Object
@@ -73,7 +73,7 @@ def components(self):
Returns
-------
- dict of :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`
+ dict of :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`
"""
comp_list = [
EDBComponent(self._pedb, l)
@@ -145,7 +145,7 @@ class EDBComponent(object):
Parameters
----------
- parent : :class:`pyaedt.edb_core.components.Components`
+ parent : :class:`pyedb.legacy.edb_core.components.Components`
Inherited AEDT object.
component : object
Edb Component Object
diff --git a/src/pyedb/legacy/edb_core/edb_data/connectable.py b/src/pyedb/legacy/edb_core/edb_data/connectable.py
index e2befc2cf6..8bef21f794 100644
--- a/src/pyedb/legacy/edb_core/edb_data/connectable.py
+++ b/src/pyedb/legacy/edb_core/edb_data/connectable.py
@@ -84,7 +84,7 @@ def net(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.nets_data.EDBNetsData`
+ :class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBNetsData`
"""
from pyedb.legacy.edb_core.edb_data.nets_data import EDBNetsData
diff --git a/src/pyedb/legacy/edb_core/edb_data/control_file.py b/src/pyedb/legacy/edb_core/edb_data/control_file.py
index 6ce759d186..b90edb5c07 100644
--- a/src/pyedb/legacy/edb_core/edb_data/control_file.py
+++ b/src/pyedb/legacy/edb_core/edb_data/control_file.py
@@ -45,7 +45,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
base_path = env_path(edbversion)
sys.path.append(base_path)
else:
- pyaedt_logger.error("No Edb installation found. Check environment variables")
+ pyedb_logger.error("No Edb installation found. Check environment variables")
return False
os.environ["HELIC_ROOT"] = os.path.join(base_path, "helic")
if os.getenv("ANSYSLMD_LICENCE_FILE", None) is None:
@@ -58,7 +58,7 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
os.environ["ANSYSLMD_LICENSE_FILE"] = line.split("=")[1]
break
else:
- pyaedt_logger.error("ANSYSLMD_LICENSE_FILE is not defined.")
+ pyedb_logger.error("ANSYSLMD_LICENSE_FILE is not defined.")
vlc_file_name = os.path.splitext(tech_file)[0]
if not control_file:
control_file = vlc_file_name + ".xml"
@@ -92,9 +92,9 @@ def convert_technology_file(tech_file, edbversion=None, control_file=None):
p = subprocess.Popen(command, env=my_env)
p.wait()
if os.path.exists(control_file):
- pyaedt_logger.info("Xml file created.")
+ pyedb_logger.info("Xml file created.")
return control_file
- pyaedt_logger.error("Technology files are supported only in Linux. Use control file instead.")
+ pyedb_logger.error("Technology files are supported only in Linux. Use control file instead.")
return False
@@ -246,7 +246,7 @@ def vias(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.control_file.ControlFileVia`
+ list of :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileVia`
"""
return self._vias
@@ -257,7 +257,7 @@ def materials(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.control_file.ControlFileMaterial`
+ list of :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileMaterial`
"""
return self._materials
@@ -268,7 +268,7 @@ def dielectrics(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.control_file.ControlFileLayer`
+ list of :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileLayer`
"""
return self._dielectrics
@@ -279,7 +279,7 @@ def layers(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.control_file.ControlFileLayer`
+ list of :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileLayer`
"""
return self._layers
@@ -313,7 +313,7 @@ def add_material(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.control_file.ControlFileMaterial`
+ :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileMaterial`
"""
if isinstance(properties, dict):
self._materials[material_name] = ControlFileMaterial(material_name, properties)
@@ -367,7 +367,7 @@ def add_layer(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.control_file.ControlFileLayer`
+ :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileLayer`
"""
if isinstance(properties, dict):
self._layers.append(ControlFileLayer(layer_name, properties))
@@ -420,7 +420,7 @@ def add_dielectric(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.control_file.ControlFileDielectric`
+ :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileDielectric`
"""
if isinstance(properties, dict):
self._dielectrics.append(ControlFileDielectric(layer_name, properties))
@@ -498,7 +498,7 @@ def add_via(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.control_file.ControlFileVia`
+ :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileVia`
"""
if isinstance(properties, dict):
self._vias.append(ControlFileVia(layer_name, properties))
@@ -784,7 +784,7 @@ def add_port(self, name, x1, y1, layer1, x2, y2, layer2, z0=50):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.control_file.ControlCircuitPt`
+ :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlCircuitPt`
"""
self.ports[name] = ControlCircuitPt(name, str(x1), str(y1), layer1, str(x2), str(y2), layer2, str(z0))
return self.ports[name]
@@ -971,7 +971,7 @@ def add_sweep(self, name, start, stop, step, sweep_type="Interpolating", step_ty
Returns
-------
- :class:`pyaedt.edb_core.edb_data.control_file.ControlFileSweep`
+ :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileSweep`
"""
self.sweeps.append(ControlFileSweep(name, start, stop, step, sweep_type, step_type, use_q3d))
return self.sweeps[-1]
@@ -992,7 +992,7 @@ def add_mesh_operation(self, name, region, type, nets_layers):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.control_file.ControlFileMeshOp`
+ :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileMeshOp`
"""
mop = ControlFileMeshOp(name, region, type, nets_layers)
@@ -1062,7 +1062,7 @@ def add_setup(self, name, frequency):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.control_file.ControlFileSetup`
+ :class:`pyedb.legacy.edb_core.edb_data.control_file.ControlFileSetup`
"""
setup = ControlFileSetup(name)
setup.frequency = frequency
diff --git a/src/pyedb/legacy/edb_core/edb_data/hfss_extent_info.py b/src/pyedb/legacy/edb_core/edb_data/hfss_extent_info.py
index 3b8c75e136..fbae9514e1 100644
--- a/src/pyedb/legacy/edb_core/edb_data/hfss_extent_info.py
+++ b/src/pyedb/legacy/edb_core/edb_data/hfss_extent_info.py
@@ -10,8 +10,8 @@ class HfssExtentInfo:
Parameters
----------
- pedb : :class:`pyaedt.edb.Edb`
- Inherited AEDT object.
+ pedb : :class:`pyedb.edb.Edb`
+ Inherited EDB object.
"""
def __init__(self, pedb):
@@ -232,7 +232,7 @@ def operating_freq(self):
Returns
-------
- pyaedt.edb_core.edb_data.edbvalue.EdbValue
+ pyedb.legacy.edb_core.edb_data.edbvalue.EdbValue
"""
return EdbValue(self._edb_hfss_extent_info.OperatingFreq)
diff --git a/src/pyedb/legacy/edb_core/edb_data/hfss_simulation_setup_data.py b/src/pyedb/legacy/edb_core/edb_data/hfss_simulation_setup_data.py
index 8817dfaad5..e0679d3ebe 100644
--- a/src/pyedb/legacy/edb_core/edb_data/hfss_simulation_setup_data.py
+++ b/src/pyedb/legacy/edb_core/edb_data/hfss_simulation_setup_data.py
@@ -1,5 +1,5 @@
from pyedb.legacy.edb_core.general import convert_py_list_to_net_list
-from pyedb.legacy.generic.clr_module import Tuple
+from pyedb.legacy.clr_module import Tuple
from pyedb.generic.general_methods import generate_unique_name
from pyedb.generic.general_methods import pyedb_function_handler
@@ -992,7 +992,7 @@ def adaptive_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.AdaptiveSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.AdaptiveSettings`
"""
return self._parent._edb_sim_setup_info.SimulationSettings.AdaptiveSettings
@@ -1002,7 +1002,7 @@ def adaptive_frequency_data_list(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.AdaptiveFrequencyData`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.AdaptiveFrequencyData`
"""
return [AdaptiveFrequencyData(i) for i in list(self.adaptive_settings.AdaptiveFrequencyDataList)]
@@ -1827,7 +1827,7 @@ def hfss_solver_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.HfssSolverSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.HfssSolverSettings`
"""
return HfssSolverSettings(self)
@@ -1838,7 +1838,7 @@ def adaptive_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.AdaptiveSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.AdaptiveSettings`
"""
return AdaptiveSettings(self)
@@ -1849,7 +1849,7 @@ def defeature_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.DefeatureSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.DefeatureSettings`
"""
return DefeatureSettings(self)
@@ -1860,7 +1860,7 @@ def via_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.ViaSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.ViaSettings`
"""
return ViaSettings(self)
@@ -1871,7 +1871,7 @@ def advanced_mesh_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.AdvancedMeshSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.AdvancedMeshSettings`
"""
return AdvancedMeshSettings(self)
@@ -1882,7 +1882,7 @@ def curve_approx_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.CurveApproxSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.CurveApproxSettings`
"""
return CurveApproxSettings(self)
@@ -1893,7 +1893,7 @@ def dcr_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.DcrSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.DcrSettings`
"""
return DcrSettings(self)
@@ -1904,7 +1904,7 @@ def hfss_port_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.HfssPortSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.HfssPortSettings`
"""
return HfssPortSettings(self)
@@ -2051,7 +2051,7 @@ def add_frequency_sweep(self, name=None, frequency_sweep=None):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.hfss_simulation_setup_data.EdbFrequencySweep`
+ :class:`pyedb.legacy.edb_core.edb_data.hfss_simulation_setup_data.EdbFrequencySweep`
Examples
--------
diff --git a/src/pyedb/legacy/edb_core/edb_data/nets_data.py b/src/pyedb/legacy/edb_core/edb_data/nets_data.py
index ed2e980f2f..d25c8e2acd 100644
--- a/src/pyedb/legacy/edb_core/edb_data/nets_data.py
+++ b/src/pyedb/legacy/edb_core/edb_data/nets_data.py
@@ -43,7 +43,7 @@ def primitives(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ list of :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
"""
return [cast(i, self._app) for i in self.net_object.Primitives]
@@ -53,7 +53,7 @@ def padstack_instances(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.padstacks_data.EDBPadstackInstance`"""
+ list of :class:`pyedb.legacy.edb_core.edb_data.padstacks_data.EDBPadstackInstance`"""
name = self.name
return [
EDBPadstackInstance(i, self._app) for i in self.net_object.PadstackInstances if i.GetNet().GetName() == name
@@ -65,7 +65,7 @@ def components(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`]
"""
comps = {}
for p in self.padstack_instances:
@@ -150,7 +150,7 @@ def extended_net(self):
Returns
-------
- :class:` :class:`pyaedt.edb_core.edb_data.nets_data.EDBExtendedNetData`
+ :class:` :class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBExtendedNetData`
Examples
--------
diff --git a/src/pyedb/legacy/edb_core/edb_data/padstacks_data.py b/src/pyedb/legacy/edb_core/edb_data/padstacks_data.py
index 48106b1fd8..382fa6f4c8 100644
--- a/src/pyedb/legacy/edb_core/edb_data/padstacks_data.py
+++ b/src/pyedb/legacy/edb_core/edb_data/padstacks_data.py
@@ -3,14 +3,14 @@
import re
import warnings
-from pyedb.legacy.generic.general_methods import is_ironpython
+from pyedb.generic.general_methods import is_ironpython
from pyedb.legacy.edb_core.dotnet.database import PolygonDataDotNet
from pyedb.legacy.edb_core.edb_data.edbvalue import EdbValue
from pyedb.legacy.edb_core.edb_data.primitives_data import EDBPrimitivesMain
from pyedb.legacy.edb_core.general import PadGeometryTpe
from pyedb.legacy.edb_core.general import convert_py_list_to_net_list
-from pyedb.legacy.generic.clr_module import String
-from pyedb.legacy.generic.clr_module import _clr
+from pyedb.legacy.clr_module import String
+from pyedb.legacy.clr_module import _clr
from pyedb.generic.general_methods import generate_unique_name
from pyedb.generic.general_methods import pyedb_function_handler
@@ -1031,9 +1031,9 @@ def create_port(self, name=None, reference=None, is_circuit_port=False):
----------
name : str, optional
Name of the port. The default is ``None``, in which case a name is automatically assigned.
- reference : class:`pyaedt.edb_core.edb_data.nets_data.EDBNetsData`,
- class:`pyaedt.edb_core.edb_data.padstacks_data.EDBPadstackInstance`,
- class:`pyaedt.edb_core.edb_data.sources.PinGroup`, optional
+ reference : class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBNetsData`,
+ class:`pyedb.legacy.edb_core.edb_data.padstacks_data.EDBPadstackInstance`,
+ class:`pyedb.legacy.edb_core.edb_data.sources.PinGroup`, optional
Negative terminal of the port.
is_circuit_port : bool, optional
Whether it is a circuit port.
@@ -1399,7 +1399,7 @@ def net_name(self):
str
Name of the net.
"""
- return self._edb_padstackinstance.net.name
+ return self._edb_padstackinstance.GetNet().GetName()
@net_name.setter
def net_name(self, val):
@@ -1705,7 +1705,7 @@ def create_rectangle_in_pad(self, layer_name, return_points=False, partition_max
Returns
-------
- bool, List, :class:`pyaedt.edb_core.edb_data.primitives.EDBPrimitives`
+ bool, List, :class:`pyedb.legacy.edb_core.edb_data.primitives.EDBPrimitives`
Polygon when successful, ``False`` when failed, list of list if `return_points=True`.
Examples
diff --git a/src/pyedb/legacy/edb_core/edb_data/ports.py b/src/pyedb/legacy/edb_core/edb_data/ports.py
index 46a3c29339..6715e98cea 100644
--- a/src/pyedb/legacy/edb_core/edb_data/ports.py
+++ b/src/pyedb/legacy/edb_core/edb_data/ports.py
@@ -9,7 +9,7 @@ class GapPort(EdgeTerminal):
Parameters
----------
- pedb : pyaedt.edb.Edb
+ pedb : pyedb.edb.Edb
EDB object from the ``Edblib`` library.
edb_object : Ansys.Ansoft.Edb.Cell.Terminal.EdgeTerminal
Edge terminal instance from EDB.
@@ -58,7 +58,7 @@ class CircuitPort(GapPort):
"""Manages gap port properties.
Parameters
----------
- pedb : pyaedt.edb.Edb
+ pedb : pyedb.edb.Edb
EDB object from the ``Edblib`` library.
edb_object : Ansys.Ansoft.Edb.Cell.Terminal.EdgeTerminal
Edge terminal instance from EDB.
@@ -76,7 +76,7 @@ class WavePort(EdgeTerminal):
Parameters
----------
- pedb : pyaedt.edb.Edb
+ pedb : pyedb.edb.Edb
EDB object from the ``Edblib`` library.
edb_object : Ansys.Ansoft.Edb.Cell.Terminal.EdgeTerminal
Edge terminal instance from EDB.
@@ -154,7 +154,7 @@ class ExcitationSources(Terminal):
Parameters
----------
- pedb : pyaedt.edb.Edb
+ pedb : pyedb.edb.Edb
Edb object from Edblib.
edb_terminal : Ansys.Ansoft.Edb.Cell.Terminal.EdgeTerminal
Edge terminal instance from Edb.
@@ -198,7 +198,7 @@ class BundleWavePort(BundleTerminal):
Parameters
----------
- pedb : pyaedt.edb.Edb
+ pedb : pyedb.edb.Edb
EDB object from the ``Edblib`` library.
edb_object : Ansys.Ansoft.Edb.Cell.Terminal.BundleTerminal
BundleTerminal instance from EDB.
@@ -263,7 +263,7 @@ class CoaxPort(PadstackInstanceTerminal):
Parameters
----------
- pedb : pyaedt.edb.Edb
+ pedb : pyedb.edb.Edb
EDB object from the ``Edblib`` library.
edb_object : Ansys.Ansoft.Edb.Cell.Terminal.PadstackInstanceTerminal
PadstackInstanceTerminal instance from EDB.
diff --git a/src/pyedb/legacy/edb_core/edb_data/simulation_configuration.py b/src/pyedb/legacy/edb_core/edb_data/simulation_configuration.py
index b927aa4175..f2851db770 100644
--- a/src/pyedb/legacy/edb_core/edb_data/simulation_configuration.py
+++ b/src/pyedb/legacy/edb_core/edb_data/simulation_configuration.py
@@ -5,7 +5,7 @@
from pyedb.generic.general_methods import generate_unique_name
from pyedb.legacy.edb_core.edb_data.sources import Source
from pyedb.legacy.edb_core.edb_data.sources import SourceType
-from pyedb.legacy.generic.clr_module import Dictionary
+from pyedb.legacy.clr_module import Dictionary
from pyedb.generic.constants import BasisOrder
from pyedb.generic.constants import CutoutSubdesignType
from pyedb.generic.constants import RadiationBoxType
@@ -491,7 +491,7 @@ def sources(self): # pragma: no cover
Returns
-------
- :class:`pyaedt.edb_core.edb_data.sources.Source`
+ :class:`pyedb.legacy.edb_core.edb_data.sources.Source`
"""
return self._sources
@@ -509,7 +509,7 @@ def add_source(self, source=None): # pragma: no cover
Parameters
----------
- source : :class:`pyaedt.edb_core.edb_data.sources.Source`
+ source : :class:`pyedb.legacy.edb_core.edb_data.sources.Source`
"""
if isinstance(source, Source):
@@ -2260,7 +2260,7 @@ def dc_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.simulation_configuration.SimulationConfigurationDc`
+ :class:`pyedb.legacy.edb_core.edb_data.simulation_configuration.SimulationConfigurationDc`
"""
return self._dc_settings
@@ -2271,7 +2271,7 @@ def ac_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.simulation_configuration.SimulationConfigurationAc`
+ :class:`pyedb.legacy.edb_core.edb_data.simulation_configuration.SimulationConfigurationAc`
"""
return self._ac_settings
@@ -2282,7 +2282,7 @@ def batch_solve_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.simulation_configuration.SimulationConfigurationBatch`
+ :class:`pyedb.legacy.edb_core.edb_data.simulation_configuration.SimulationConfigurationBatch`
"""
return self._batch_solve_settings
diff --git a/src/pyedb/legacy/edb_core/edb_data/siwave_simulation_setup_data.py b/src/pyedb/legacy/edb_core/edb_data/siwave_simulation_setup_data.py
index 63385fe0e0..dad9f62f2c 100644
--- a/src/pyedb/legacy/edb_core/edb_data/siwave_simulation_setup_data.py
+++ b/src/pyedb/legacy/edb_core/edb_data/siwave_simulation_setup_data.py
@@ -724,7 +724,7 @@ def dc_settings(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.siwave_simulation_setup_data.SiwaveDCAdvancedSettings`
+ :class:`pyedb.legacy.edb_core.edb_data.siwave_simulation_setup_data.SiwaveDCAdvancedSettings`
"""
return SiwaveDCAdvancedSettings(self)
diff --git a/src/pyedb/legacy/edb_core/edb_data/sources.py b/src/pyedb/legacy/edb_core/edb_data/sources.py
index ec8ea80741..14c34a9b04 100644
--- a/src/pyedb/legacy/edb_core/edb_data/sources.py
+++ b/src/pyedb/legacy/edb_core/edb_data/sources.py
@@ -293,7 +293,7 @@ def _create_terminal(self, name=None):
automatically assigned.
Returns
-------
- :class:`pyaedt.edb_core.edb_data.terminals.PinGroupTerminal`
+ :class:`pyedb.legacy.edb_core.edb_data.terminals.PinGroupTerminal`
"""
pg_term = self.terminal
if not name:
diff --git a/src/pyedb/legacy/edb_core/edb_data/terminals.py b/src/pyedb/legacy/edb_core/edb_data/terminals.py
index 23c2d82fc8..cb9d272771 100644
--- a/src/pyedb/legacy/edb_core/edb_data/terminals.py
+++ b/src/pyedb/legacy/edb_core/edb_data/terminals.py
@@ -187,7 +187,7 @@ def reference_object(self): # pragma : no cover
Returns
-------
:class:`legacy.edb_core.edb_data.padstacks_data.EDBPadstackInstance` or
- :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
"""
if not self._reference_object:
term = self._edb_object
@@ -286,7 +286,7 @@ def get_edge_terminal_reference_primitive(self): # pragma : no cover
Returns
-------
- :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
"""
ref_layer = self._edb_object.GetReferenceLayer()
@@ -310,7 +310,7 @@ def get_point_terminal_reference_primitive(self): # pragma : no cover
Returns
-------
:class:`legacy.edb_core.edb_data.padstacks_data.EDBPadstackInstance` or
- :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
"""
ref_term = self._edb_object.GetReferenceTerminal() # return value is type terminal
@@ -345,7 +345,7 @@ def get_pad_edge_terminal_reference_pin(self, gnd_net_name_preference=None):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.padstacks_data.EDBPadstackInstance`
+ :class:`pyedb.legacy.edb_core.edb_data.padstacks_data.EDBPadstackInstance`
"""
comp_inst = self._edb_object.GetComponent()
pins = self._pedb.components.get_pin_from_component(comp_inst.GetName())
@@ -420,7 +420,7 @@ class BundleTerminal(Terminal):
Parameters
----------
- pedb : pyaedt.edb.Edb
+ pedb : pyedb.edb.Edb
EDB object from the ``Edblib`` library.
edb_object : Ansys.Ansoft.Edb.Cell.Terminal.BundleTerminal
BundleTerminal instance from EDB.
@@ -515,7 +515,7 @@ def create(self, name, net, location, layer, is_ref=False):
Whether it is a reference terminal.
Returns
-------
- :class:`pyaedt.edb_core.edb_data.terminals.PointTerminal`
+ :class:`pyedb.legacy.edb_core.edb_data.terminals.PointTerminal`
"""
terminal = self._pedb.edb_api.cell.terminal.PointTerminal.Create(
self._pedb.active_layout,
@@ -578,7 +578,7 @@ def create(self, name, net_name, pin_group_name, is_ref=False):
Whether it is a reference terminal. The default is ``False``.
Returns
-------
- :class:`pyaedt.edb_core.edb_data.terminals.PinGroupTerminal`
+ :class:`pyedb.legacy.edb_core.edb_data.terminals.PinGroupTerminal`
"""
term = self._pedb.edb_api.cell.terminal.PinGroupTerminal.Create(
self._pedb.active_layout,
diff --git a/src/pyedb/legacy/edb_core/edb_data/variables.py b/src/pyedb/legacy/edb_core/edb_data/variables.py
index 4730e4f242..da68a28010 100644
--- a/src/pyedb/legacy/edb_core/edb_data/variables.py
+++ b/src/pyedb/legacy/edb_core/edb_data/variables.py
@@ -42,7 +42,7 @@ def value_object(self):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.edbvalue.EdbValue`
+ :class:`pyedb.legacy.edb_core.edb_data.edbvalue.EdbValue`
"""
return self._pedb.get_variable(self.name)
diff --git a/src/pyedb/legacy/edb_core/general.py b/src/pyedb/legacy/edb_core/general.py
index a536986e71..b80cff090c 100644
--- a/src/pyedb/legacy/edb_core/general.py
+++ b/src/pyedb/legacy/edb_core/general.py
@@ -7,10 +7,10 @@
import logging
-from pyedb.legacy.generic.general_methods import is_ironpython
-from pyedb.legacy.generic.clr_module import Dictionary
-from pyedb.legacy.generic.clr_module import List
-from pyedb.legacy.generic.clr_module import Tuple
+from pyedb.generic.general_methods import is_ironpython
+from pyedb.legacy.clr_module import Dictionary
+from pyedb.legacy.clr_module import List
+from pyedb.legacy.clr_module import Tuple
from pyedb.generic.general_methods import pyedb_function_handler
diff --git a/src/pyedb/legacy/edb_core/layout.py b/src/pyedb/legacy/edb_core/layout.py
index 01c5bfe898..73d0da2cf7 100644
--- a/src/pyedb/legacy/edb_core/layout.py
+++ b/src/pyedb/legacy/edb_core/layout.py
@@ -80,7 +80,7 @@ def primitives(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ list of :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
List of primitives.
"""
_prims = []
@@ -142,7 +142,7 @@ def rectangles(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ list of :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
List of rectangles.
"""
@@ -154,7 +154,7 @@ def circles(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ list of :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
List of circles.
"""
@@ -166,7 +166,7 @@ def paths(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ list of :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
List of paths.
"""
return [i for i in self.primitives if isinstance(i, PathDotNet)]
@@ -177,7 +177,7 @@ def bondwires(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ list of :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
List of bondwires.
"""
return [i for i in self.primitives if isinstance(i, BondwireDotNet)]
@@ -188,7 +188,7 @@ def polygons(self):
Returns
-------
- list of :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ list of :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
List of polygons.
"""
return [i for i in self.primitives if isinstance(i, PolygonDotNet)]
@@ -419,7 +419,7 @@ def _create_path(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
``True`` when successful, ``False`` when failed.
"""
net = self._pedb.nets.find_or_create_net(net_name)
@@ -497,7 +497,7 @@ def create_trace(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
"""
path = self.Shape("Polygon", points=path_list)
primitive = self._create_path(
@@ -602,7 +602,7 @@ def create_polygon_from_points(self, point_list, layer_name, net_name=""):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
"""
warnings.warn(
"Use :func:`create_polygon` method instead. It now supports point lists as arguments.", DeprecationWarning
@@ -651,7 +651,7 @@ def create_rectangle(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
Rectangle when successful, ``False`` when failed.
"""
edb_net = self._pedb.nets.find_or_create_net(net_name)
@@ -707,7 +707,7 @@ def create_circle(self, layer_name, x, y, radius, net_name=""):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.primitives_data.EDBPrimitives`
+ :class:`pyedb.legacy.edb_core.edb_data.primitives_data.EDBPrimitives`
Objects of the circle created when successful.
"""
edb_net = self._pedb.nets.find_or_create_net(net_name)
@@ -851,7 +851,7 @@ def shape_to_polygon_data(self, shape):
Parameters
----------
- shape : :class:`pyaedt.edb_core.layout.EdbLayout.Shape`
+ shape : :class:`pyedb.legacy.edb_core.layout.EdbLayout.Shape`
Type of the shape to convert. Options are ``"rectangle"`` and ``"polygon"``.
"""
if shape.type == "polygon":
diff --git a/src/pyedb/legacy/edb_core/materials.py b/src/pyedb/legacy/edb_core/materials.py
index a347c6dabb..c1f4b7b405 100644
--- a/src/pyedb/legacy/edb_core/materials.py
+++ b/src/pyedb/legacy/edb_core/materials.py
@@ -7,9 +7,9 @@
import re
import warnings
-from pyedb.legacy.generic.general_methods import is_ironpython
+from pyedb.generic.general_methods import is_ironpython
from pyedb.legacy.edb_core.general import convert_py_list_to_net_list
-from pyedb.legacy.generic.clr_module import _clr
+from pyedb.legacy.clr_module import _clr
from pyedb.generic.general_methods import pyedb_function_handler
diff --git a/src/pyedb/legacy/edb_core/net_class.py b/src/pyedb/legacy/edb_core/net_class.py
index 41b34c689c..15b52ddb00 100644
--- a/src/pyedb/legacy/edb_core/net_class.py
+++ b/src/pyedb/legacy/edb_core/net_class.py
@@ -19,7 +19,7 @@ def _layout(self):
Returns
-------
- :class:` :class:`pyaedt.edb_core.dotnet.layout.LayoutDotNet`
+ :class:` :class:`pyedb.legacy.edb_core.dotnet.layout.LayoutDotNet`
"""
return self._pedb.layout
@@ -66,7 +66,7 @@ def items(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.nets_data.EDBDifferentialPairData`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBDifferentialPairData`]
Dictionary of extended nets.
"""
net_classes = {}
@@ -88,7 +88,7 @@ def create(self, name, net):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.nets_data.EDBNetClassData`
+ :class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBNetClassData`
"""
if name in self.items:
self._pedb.logger.error("{} already exists.".format(name))
@@ -251,7 +251,7 @@ def items(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.nets_data.EDBDifferentialPairData`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBDifferentialPairData`]
Dictionary of extended nets.
"""
diff_pairs = {}
@@ -275,7 +275,7 @@ def create(self, name, net_p, net_n):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.nets_data.EDBDifferentialPairData`
+ :class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBDifferentialPairData`
"""
if name in self.items:
self._pedb.logger.error("{} already exists.".format(name))
diff --git a/src/pyedb/legacy/edb_core/nets.py b/src/pyedb/legacy/edb_core/nets.py
index 9c470c0c44..d5c5d45cea 100644
--- a/src/pyedb/legacy/edb_core/nets.py
+++ b/src/pyedb/legacy/edb_core/nets.py
@@ -35,7 +35,7 @@ def __getitem__(self, name):
Returns
-------
- :class:` :class:`pyaedt.edb_core.edb_data.nets_data.EDBNetsData`
+ :class:` :class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBNetsData`
"""
if name in self.nets:
@@ -100,7 +100,7 @@ def nets(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.nets_data.EDBNetsData`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.nets_data.EDBNetsData`]
Dictionary of nets.
"""
diff --git a/src/pyedb/legacy/edb_core/padstack.py b/src/pyedb/legacy/edb_core/padstack.py
index 036ac709d3..cf0ff39360 100644
--- a/src/pyedb/legacy/edb_core/padstack.py
+++ b/src/pyedb/legacy/edb_core/padstack.py
@@ -7,7 +7,7 @@
from pyedb.legacy.edb_core.edb_data.padstacks_data import EDBPadstack
from pyedb.legacy.edb_core.edb_data.padstacks_data import EDBPadstackInstance
from pyedb.legacy.edb_core.general import convert_py_list_to_net_list
-from pyedb.legacy.generic.clr_module import Array
+from pyedb.legacy.clr_module import Array
from pyedb.generic.general_methods import generate_unique_name
from pyedb.generic.general_methods import pyedb_function_handler
@@ -34,7 +34,7 @@ def __getitem__(self, name):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.components_data.EDBComponent`
+ :class:`pyedb.legacy.edb_core.edb_data.components_data.EDBComponent`
"""
if name in self.instances:
@@ -190,7 +190,7 @@ def instances(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.padstacks_data.EDBPadstackInstance`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.padstacks_data.EDBPadstackInstance`]
List of padstack instances.
"""
@@ -250,7 +250,7 @@ def padstack_instances(self):
Returns
-------
- dict[str, :class:`pyaedt.edb_core.edb_data.padstacks_data.EDBPadstackInstance`]
+ dict[str, :class:`pyedb.legacy.edb_core.edb_data.padstacks_data.EDBPadstackInstance`]
List of padstack instances.
"""
@@ -1069,7 +1069,7 @@ def place(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.padstacks_data.EDBPadstackInstance`
+ :class:`pyedb.legacy.edb_core.edb_data.padstacks_data.EDBPadstackInstance`
"""
padstack = None
for pad in list(self.definitions.keys()):
diff --git a/src/pyedb/legacy/edb_core/siwave.py b/src/pyedb/legacy/edb_core/siwave.py
index 3a1ae2d12f..01989d2475 100644
--- a/src/pyedb/legacy/edb_core/siwave.py
+++ b/src/pyedb/legacy/edb_core/siwave.py
@@ -29,7 +29,7 @@ class EdbSiwave(object):
Parameters
----------
- edb_class : :class:`pyaedt.edb.Edb`
+ edb_class : :class:`pyedb.edb.Edb`
Inherited parent object.
Examples
@@ -825,7 +825,7 @@ def add_siwave_syz_analysis(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.siwave_simulation_setup_data.SiwaveSYZSimulationSetup`
+ :class:`pyedb.legacy.edb_core.edb_data.siwave_simulation_setup_data.SiwaveSYZSimulationSetup`
Setup object class.
"""
setup = self._pedb.create_siwave_syz_setup()
@@ -868,7 +868,7 @@ def add_siwave_dc_analysis(self, name=None):
Returns
-------
- :class:`pyaedt.edb_core.edb_data.siwave_simulation_setup_data.SiwaveDCSimulationSetup`
+ :class:`pyedb.legacy.edb_core.edb_data.siwave_simulation_setup_data.SiwaveDCSimulationSetup`
Setup object class.
Examples
@@ -1184,7 +1184,7 @@ def create_rlc_component(
Returns
-------
- class:`pyaedt.edb_core.components.Components`
+ class:`pyedb.legacy.edb_core.components.Components`
Created EDB component.
"""
diff --git a/src/pyedb/legacy/edb_core/stackup.py b/src/pyedb/legacy/edb_core/stackup.py
index a5559b9d39..dd7443edcb 100644
--- a/src/pyedb/legacy/edb_core/stackup.py
+++ b/src/pyedb/legacy/edb_core/stackup.py
@@ -652,7 +652,7 @@ def add_layer(
Returns
-------
- :class:`pyaedt.edb_core.edb_data.layer_data.LayerEdbClass`
+ :class:`pyedb.legacy.edb_core.edb_data.layer_data.LayerEdbClass`
"""
if layer_name in self.layers:
logger.error("layer {} exists.".format(layer_name))
@@ -2191,9 +2191,9 @@ def plot(
plot_definitions : str, list, optional
List of padstack definitions to plot on the stackup.
It is supported only for Laminate mode.
- first_layer : str or :class:`pyaedt.edb_core.edb_data.layer_data.LayerEdbClass`
+ first_layer : str or :class:`pyedb.legacy.edb_core.edb_data.layer_data.LayerEdbClass`
First layer to plot from the bottom. Default is `None` to start plotting from bottom.
- last_layer : str or :class:`pyaedt.edb_core.edb_data.layer_data.LayerEdbClass`
+ last_layer : str or :class:`pyedb.legacy.edb_core.edb_data.layer_data.LayerEdbClass`
Last layer to plot from the bottom. Default is `None` to plot up to top layer.
scale_elevation : bool, optional
The real layer thickness is scaled so that max_thickness = 3 * min_thickness.
diff --git a/src/pyedb/legacy/generic/DataHandlers.py b/src/pyedb/legacy/generic/DataHandlers.py
deleted file mode 100644
index 96345466ba..0000000000
--- a/src/pyedb/legacy/generic/DataHandlers.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*- coding: utf-8 -*-
-from collections import OrderedDict
-from decimal import Decimal
-import json
-import math
-import random
-import re
-import string
-
-from pyaedt.generic.general_methods import pyedb_function_handler
-from pyaedt.generic.general_methods import settings
-from pyaedt.modeler.cad.elements3d import EdgePrimitive
-from pyaedt.modeler.cad.elements3d import FacePrimitive
-from pyaedt.modeler.cad.elements3d import VertexPrimitive
-
-
-def create_list_for_csharp(input_list, return_strings=False):
- """
-
- Parameters
- ----------
- input_list :
-
- return_strings :
- (Default value = False)
-
- Returns
- -------
-
- """
- from pyaedt.generic.clr_module import Double
- from pyaedt.generic.clr_module import List
-
- if return_strings:
- col = List[str]()
- else:
- col = List[Double]()
-
- for el in input_list:
- if return_strings:
- col.Add(str(el))
- else:
- col.Add(el)
- return col
-
-
-@pyedb_function_handler()
-def create_table_for_csharp(input_list_of_list, return_strings=True):
- """
-
- Parameters
- ----------
- input_list_of_list :
-
- return_strings :
- (Default value = True)
-
- Returns
- -------
-
- """
- from pyaedt.generic.clr_module import List
-
- new_table = List[List[str]]()
- for col in input_list_of_list:
- newcol = create_list_for_csharp(col, return_strings)
- new_table.Add(newcol)
- return new_table
diff --git a/src/pyedb/legacy/generic/__init__.py b/src/pyedb/legacy/generic/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/src/pyedb/legacy/generic/general_methods.py b/src/pyedb/legacy/generic/general_methods.py
deleted file mode 100644
index 6485688292..0000000000
--- a/src/pyedb/legacy/generic/general_methods.py
+++ /dev/null
@@ -1,1898 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import absolute_import
-
-import ast
-import codecs
-from collections import OrderedDict
-import csv
-import datetime
-import difflib
-import fnmatch
-from functools import update_wrapper
-import inspect
-import itertools
-import json
-import logging
-import math
-import os
-import random
-import re
-import string
-import sys
-import tempfile
-import time
-import traceback
-
-from pyedb.generic.constants import CSS4_COLORS
-from pyedb.generic.settings import settings
-
-is_ironpython = "IronPython" in sys.version or ".NETFramework" in sys.version
-is_linux = os.name == "posix"
-is_windows = not is_linux
-_pythonver = sys.version_info[0]
-inside_desktop = True if is_ironpython and "4.0.30319.42000" in sys.version else False
-
-if not is_ironpython:
- import psutil
-
-try:
- import xml.etree.cElementTree as ET
-
- ET.VERSION
-except ImportError:
- ET = None
-
-
-class GrpcApiError(Exception):
- """ """
-
- pass
-
-
-class MethodNotSupportedError(Exception):
- """ """
-
- pass
-
-
-def _write_mes(mes_text):
- mes_text = str(mes_text)
- parts = [mes_text[i : i + 250] for i in range(0, len(mes_text), 250)]
- for el in parts:
- settings.logger.error(el)
-
-
-def _get_args_dicts(func, args, kwargs):
- if int(sys.version[0]) > 2:
- args_name = list(OrderedDict.fromkeys(inspect.getfullargspec(func)[0] + list(kwargs.keys())))
- args_dict = OrderedDict(list(itertools.zip_longest(args_name, args)) + list(kwargs.items()))
- else:
- args_name = list(OrderedDict.fromkeys(inspect.getargspec(func)[0] + list(kwargs.keys())))
- args_dict = OrderedDict(list(itertools.izip(args_name, args)) + list(kwargs.iteritems()))
- return args_dict
-
-
-def _exception(ex_info, func, args, kwargs, message="Type Error"):
- """Write the trace stack to the desktop when a Python error occurs.
-
- Parameters
- ----------
- ex_info :
-
- func :
-
- args :
-
- kwargs :
-
- message :
- (Default value = "Type Error")
-
- Returns
- -------
-
- """
-
- tb_data = ex_info[2]
- tb_trace = traceback.format_tb(tb_data)
- _write_mes("{} on {}".format(message.upper(), func.__name__))
- try:
- _write_mes(ex_info[1].args[0])
- except (IndexError, AttributeError):
- pass
- for trace in traceback.format_stack():
- if func.__name__ in trace:
- for el in trace.split("\n"):
- _write_mes(el)
- for trace in tb_trace:
- tblist = trace.split("\n")
- for el in tblist:
- if func.__name__ in el:
- _write_mes(el)
-
- message_to_print = ""
- messages = ""
- try:
- messages = list(sys.modules["__main__"].oDesktop.GetMessages("", "", 2))[-1].lower()
- except (GrpcApiError, AttributeError, TypeError, IndexError):
- pass
- if "error" in messages:
- message_to_print = messages[messages.index("[error]") :]
- # _write_mes("{} - {} - {}.".format(ex_info[1], func.__name__, message.upper()))
-
- if message_to_print:
- _write_mes("Last Electronics Desktop Message - " + message_to_print)
-
- args_name = []
- try:
- args_dict = _get_args_dicts(func, args, kwargs)
- first_time_log = True
-
- for el in args_dict:
- if el != "self" and args_dict[el]:
- if first_time_log:
- _write_mes("Method arguments: ")
- first_time_log = False
- _write_mes(" {} = {} ".format(el, args_dict[el]))
- except:
- pass
- args = [func.__name__] + [i for i in args_name if i not in ["self"]]
- if not func.__name__.startswith("_"):
- _write_mes(
- "Check Online documentation on: https://aedt.docs.pyansys.com/version/stable/search.html?q={}".format(
- "+".join(args)
- )
- )
-
-
-def normalize_path(path_in, sep=None):
- """Normalize path separators.
-
- Parameters
- ----------
- path_in : str
- Path to normalize.
- sep : str, optional
- Separator.
-
- Returns
- -------
- str
- Path normalized to new separator.
- """
- if sep is None:
- sep = os.sep
- return path_in.replace("\\", sep).replace("/", sep)
-
-
-def _check_types(arg):
- if "netref.builtins.list" in str(type(arg)):
- return "list"
- elif "netref.builtins.dict" in str(type(arg)):
- return "dict"
- elif "netref.__builtin__.list" in str(type(arg)):
- return "list"
- elif "netref.__builtin__.dict" in str(type(arg)):
- return "dict"
- return ""
-
-
-def _function_handler_wrapper(user_function):
- def wrapper(*args, **kwargs):
- if not settings.enable_error_handler:
- result = user_function(*args, **kwargs)
- return result
- else:
- try:
- settings.time_tick = time.time()
- out = user_function(*args, **kwargs)
- if settings.enable_debug_logger or settings.enable_debug_edb_logger:
- _log_method(user_function, args, kwargs)
- return out
- except TypeError:
- _exception(sys.exc_info(), user_function, args, kwargs, "Type Error")
- return False
- except ValueError:
- _exception(sys.exc_info(), user_function, args, kwargs, "Value Error")
- return False
- except AttributeError:
- _exception(sys.exc_info(), user_function, args, kwargs, "Attribute Error")
- return False
- except KeyError:
- _exception(sys.exc_info(), user_function, args, kwargs, "Key Error")
- return False
- except IndexError:
- _exception(sys.exc_info(), user_function, args, kwargs, "Index Error")
- return False
- except AssertionError:
- _exception(sys.exc_info(), user_function, args, kwargs, "Assertion Error")
- return False
- except NameError:
- _exception(sys.exc_info(), user_function, args, kwargs, "Name Error")
- return False
- except IOError:
- _exception(sys.exc_info(), user_function, args, kwargs, "IO Error")
- return False
- except MethodNotSupportedError:
- message = "This Method is not supported in current AEDT Design Type."
- if settings.enable_screen_logs:
- print("**************************************************************")
- print("pyaedt error on Method {}: {}. Please Check again".format(user_function.__name__, message))
- print("**************************************************************")
- print("")
- if settings.enable_file_logs:
- settings.logger.error(message)
- return False
- except GrpcApiError:
- _exception(sys.exc_info(), user_function, args, kwargs, "AEDT grpc API call Error")
- return False
- except BaseException:
- _exception(sys.exc_info(), user_function, args, kwargs, "General or AEDT Error")
- return False
-
- return wrapper
-
-
-def pyedb_function_handler(direct_func=None):
- """Provides an exception handler, logging mechanism, and argument converter for client-server
- communications.
-
- This method returns the function itself if correctly executed. Otherwise, it returns ``False``
- and displays errors.
-
- """
- if callable(direct_func):
- user_function = direct_func
- wrapper = _function_handler_wrapper(user_function)
- return update_wrapper(wrapper, user_function)
- elif direct_func is not None:
- raise TypeError("Expected first argument to be a callable, or None")
-
- def decorating_function(user_function):
- wrapper = _function_handler_wrapper(user_function)
- return update_wrapper(wrapper, user_function)
-
- return decorating_function
-
-
-@pyedb_function_handler()
-def check_numeric_equivalence(a, b, relative_tolerance=1e-7):
- """Check if two numeric values are equivalent to within a relative tolerance.
-
- Paraemters
- ----------
- a : int, float
- Reference value to compare to.
- b : int, float
- Secondary value for the comparison.
- relative_tolerance : float, optional
- Relative tolerance for the equivalence test. The difference is relative to the first value.
- The default is ``1E-7``.
-
- Returns
- -------
- bool
- ``True`` if the two passed values are equivalent.
- """
- if abs(a) > 0.0:
- reldiff = abs(a - b) / a
- else:
- reldiff = abs(b)
- return True if reldiff < relative_tolerance else False
-
-
-@pyedb_function_handler()
-def check_and_download_file(local_path, remote_path, overwrite=True):
- """Check if a file is remote and either download it or return the path.
-
- Parameters
- ----------
- local_path : str
- Local path to save the file to.
- remote_path : str
- Path to the remote file.
- overwrite : bool
- Whether to overwrite the file if it already exits locally.
- The default is ``True``.
-
- Returns
- -------
- str
- """
- if settings.remote_rpc_session:
- remote_path = remote_path.replace("\\", "/") if remote_path[0] != "\\" else remote_path
- settings.remote_rpc_session.filemanager.download_file(remote_path, local_path, overwrite=overwrite)
- return local_path
- return remote_path
-
-
-def check_if_path_exists(path):
- """Check whether a path exists or not local or remote machine (for remote sessions only).
-
- Parameters
- ----------
- path : str
- Local or remote path to check.
-
- Returns
- -------
- bool
- """
- if settings.remote_rpc_session:
- return settings.remote_rpc_session.filemanager.pathexists(path)
- return os.path.exists(path)
-
-
-@pyedb_function_handler()
-def check_and_download_folder(local_path, remote_path, overwrite=True):
- """Check if a folder is remote and either download it or return the path.
-
- Parameters
- ----------
- local_path : str
- Local path to save the folder to.
- remote_path : str
- Path to the remote folder.
- overwrite : bool
- Whether to overwrite the folder if it already exits locally.
- The default is ``True``.
-
- Returns
- -------
- str
- """
- if settings.remote_rpc_session:
- remote_path = remote_path.replace("\\", "/") if remote_path[0] != "\\" else remote_path
- settings.remote_rpc_session.filemanager.download_folder(remote_path, local_path, overwrite=overwrite)
- return local_path
- return remote_path
-
-
-def open_file(file_path, file_options="r"):
- """Open a file and return the object.
-
- Parameters
- ----------
- file_path : str
- Full absolute path to the file (either local or remote).
- file_options : str, optional
- Options for opening the file.
-
- Returns
- -------
- object
- Opened file.
- """
- file_path = file_path.replace("\\", "/") if file_path[0] != "\\" else file_path
- dir_name = os.path.dirname(file_path)
- if "r" in file_options:
- if os.path.exists(file_path):
- return open(file_path, file_options)
- elif settings.remote_rpc_session and settings.remote_rpc_session.filemanager.pathexists(
- file_path
- ): # pragma: no cover
- local_file = os.path.join(tempfile.gettempdir(), os.path.split(file_path)[-1])
- settings.remote_rpc_session.filemanager.download_file(file_path, local_file)
- return open(local_file, file_options)
- elif os.path.exists(dir_name):
- return open(file_path, file_options)
- else:
- settings.logger.error("The file or folder %s does not exist", dir_name)
-
-
-def _log_method(func, new_args, new_kwargs):
- if not settings.enable_debug_internal_methods_logger and str(func.__name__)[0] == "_":
- return
- if not settings.enable_debug_geometry_operator_logger and "GeometryOperators" in str(func):
- return
- if (
- not settings.enable_debug_edb_logger
- and "Edb" in str(func) + str(new_args)
- or "edb_core" in str(func) + str(new_args)
- ):
- return
- line_begin = "ARGUMENTS: "
- message = []
- delta = time.time() - settings.time_tick
- m, s = divmod(delta, 60)
- h, m = divmod(m, 60)
- d, h = divmod(h, 24)
- msec = (s - int(s)) * 1000
- if d > 0:
- time_msg = " {}days {}h {}m {}sec.".format(d, h, m, int(s))
- elif h > 0:
- time_msg = " {}h {}m {}sec.".format(h, m, int(s))
- else:
- time_msg = " {}m {}sec {}msec.".format(m, int(s), int(msec))
- if settings.enable_debug_methods_argument_logger:
- args_dict = _get_args_dicts(func, new_args, new_kwargs)
- id = 0
- if new_args:
- object_name = str([new_args[0]])[1:-1]
- id = object_name.find(" object at ")
- if id > 0:
- object_name = object_name[1:id]
- message.append("'{}' was run in {}".format(object_name + "." + str(func.__name__), time_msg))
- else:
- message.append("'{}' was run in {}".format(str(func.__name__), time_msg))
- message.append(line_begin)
- for k, v in args_dict.items():
- if k != "self":
- message.append(" {} = {}".format(k, v))
- for m in message:
- settings.logger.debug(m)
-
-
-@pyedb_function_handler()
-def get_version_and_release(input_version):
- version = int(input_version[2:4])
- release = int(input_version[5])
- if version < 20:
- if release < 3:
- version -= 1
- else:
- release -= 2
- return (version, release)
-
-
-@pyedb_function_handler()
-def get_string_version(input_version):
- output_version = input_version
- if isinstance(input_version, float):
- output_version = str(input_version)
- if len(output_version) == 4:
- output_version = "20" + output_version
- elif isinstance(input_version, int):
- output_version = str(input_version)
- output_version = "20{}.{}".format(output_version[:2], output_version[-1])
- elif isinstance(input_version, str):
- if len(input_version) == 3:
- output_version = "20{}.{}".format(input_version[:2], input_version[-1])
- elif len(input_version) == 4:
- output_version = "20" + input_version
- return output_version
-
-
-@pyedb_function_handler()
-def env_path(input_version):
- """Get the path of the version environment variable for an AEDT version.
-
- Parameters
- ----------
- input_version : str
- AEDT version.
-
- Returns
- -------
- str
- Path for the version environment variable.
-
- Examples
- --------
- >>> env_path_student("2021.2")
- "C:/Program Files/ANSYSEM/ANSYSEM2021.2/Win64"
- """
- return os.getenv(
- "ANSYSEM_ROOT{0}{1}".format(
- get_version_and_release(input_version)[0], get_version_and_release(input_version)[1]
- ),
- "",
- )
-
-
-@pyedb_function_handler()
-def env_value(input_version):
- """Get the name of the version environment variable for an AEDT version.
-
- Parameters
- ----------
- input_version : str
- AEDT version.
-
- Returns
- -------
- str
- Name for the version environment variable.
-
- Examples
- --------
- >>> env_value("2021.2")
- "ANSYSEM_ROOT211"
- """
- return "ANSYSEM_ROOT{0}{1}".format(
- get_version_and_release(input_version)[0], get_version_and_release(input_version)[1]
- )
-
-
-@pyedb_function_handler()
-def env_path_student(input_version):
- """Get the path of the version environment variable for an AEDT student version.
-
- Parameters
- ----------
- input_version : str
- AEDT student version.
-
- Returns
- -------
- str
- Path for the student version environment variable.
-
- Examples
- --------
- >>> env_path_student("2021.2")
- "C:/Program Files/ANSYSEM/ANSYSEM2021.2/Win64"
- """
- return os.getenv(
- "ANSYSEMSV_ROOT{0}{1}".format(
- get_version_and_release(input_version)[0], get_version_and_release(input_version)[1]
- ),
- "",
- )
-
-
-@pyedb_function_handler()
-def env_value_student(input_version):
- """Get the name of the version environment variable for an AEDT student version.
-
- Parameters
- ----------
- input_version : str
- AEDT student version.
-
- Returns
- -------
- str
- Name for the student version environment variable.
-
- Examples
- --------
- >>> env_value_student("2021.2")
- "ANSYSEMSV_ROOT211"
- """
- return "ANSYSEMSV_ROOT{0}{1}".format(
- get_version_and_release(input_version)[0], get_version_and_release(input_version)[1]
- )
-
-
-@pyedb_function_handler()
-def get_filename_without_extension(path):
- """Get the filename without its extension.
-
- Parameters
- ----------
- path : str
- Path for the file.
-
-
- Returns
- -------
- str
- Name for the file, excluding its extension.
-
- """
- return os.path.splitext(os.path.split(path)[1])[0]
-
-
-@pyedb_function_handler()
-def generate_unique_name(rootname, suffix="", n=6):
- """Generate a new name given a root name and optional suffix.
-
- Parameters
- ----------
- rootname :
- Root name to add random characters to.
- suffix : string
- Suffix to add. The default is ``''``.
- n : int
- Number of random characters to add to the name. The default value is ``6``.
-
- Returns
- -------
- str
- Newly generated name.
-
- """
- char_set = string.ascii_uppercase + string.digits
- uName = "".join(random.choice(char_set) for _ in range(n))
- unique_name = rootname + "_" + uName
- if suffix:
- unique_name += "_" + suffix
- return unique_name
-
-
-@pyedb_function_handler()
-def generate_unique_folder_name(rootname=None, folder_name=None):
- """Generate a new AEDT folder name given a rootname.
-
- Parameters
- ----------
- rootname : str, optional
- Root name for the new folder. The default is ``None``.
- folder_name : str, optional
- Name for the new AEDT folder if one must be created.
-
- Returns
- -------
- str
- """
- if not rootname:
- if settings.remote_rpc_session:
- rootname = settings.remote_rpc_session_temp_folder
- else:
- rootname = tempfile.gettempdir()
- if folder_name is None:
- folder_name = generate_unique_name("pyaedt_prj", n=3)
- temp_folder = os.path.join(rootname, folder_name)
- if settings.remote_rpc_session and not settings.remote_rpc_session.filemanager.pathexists(temp_folder):
- settings.remote_rpc_session.filemanager.makedirs(temp_folder)
- elif not os.path.exists(temp_folder):
- os.makedirs(temp_folder)
-
- return temp_folder
-
-
-@pyedb_function_handler()
-def generate_unique_project_name(rootname=None, folder_name=None, project_name=None, project_format="aedt"):
- """Generate a new AEDT project name given a rootname.
-
- Parameters
- ----------
- rootname : str, optional
- Root name where the new project is to be created.
- folder_name : str, optional
- Name of the folder to create. The default is ``None``, in which case a random folder
- is created. Use ``""`` if you do not want to create a subfolder.
- project_name : str, optional
- Name for the project. The default is ``None``, in which case a random project is
- created. If a project with this name already exists, a new suffix is added.
- project_format : str, optional
- Project format. The default is ``"aedt"``. Options are ``"aedt"`` and ``"aedb"``.
-
- Returns
- -------
- str
- """
- if not project_name:
- project_name = generate_unique_name("Project", n=3)
- name_with_ext = project_name + "." + project_format
- folder_path = generate_unique_folder_name(rootname, folder_name=folder_name)
- prj = os.path.join(folder_path, name_with_ext)
- if check_if_path_exists(prj):
- name_with_ext = generate_unique_name(project_name, n=3) + "." + project_format
- prj = os.path.join(folder_path, name_with_ext)
- return prj
-
-
-def _retry_ntimes(n, function, *args, **kwargs):
- """
-
- Parameters
- ----------
- n :
-
- function :
-
- *args :
-
- **kwargs :
-
-
- Returns
- -------
-
- """
- func_name = None
- if function.__name__ == "InvokeAedtObjMethod":
- func_name = args[1]
- retry = 0
- ret_val = None
- inclusion_list = [
- "CreateVia",
- "PasteDesign",
- "Paste",
- "PushExcitations",
- "Rename",
- "RestoreProjectArchive",
- "ImportGerber",
- ]
- # if func_name and func_name not in inclusion_list and not func_name.startswith("Get"):
- if func_name and func_name not in inclusion_list:
- n = 1
- while retry < n:
- try:
- ret_val = function(*args, **kwargs)
- except:
- retry += 1
- time.sleep(settings.retry_n_times_time_interval)
- else:
- return ret_val
- if retry == n:
- if "__name__" in dir(function):
- raise AttributeError("Error in Executing Method {}.".format(function.__name__))
- else:
- raise AttributeError("Error in Executing Method.")
-
-
-def time_fn(fn, *args, **kwargs):
- start = datetime.datetime.now()
- results = fn(*args, **kwargs)
- end = datetime.datetime.now()
- fn_name = fn.__module__ + "." + fn.__name__
- delta = (end - start).microseconds * 1e-6
- print(fn_name + ": " + str(delta) + "s")
- return results
-
-
-def isclose(a, b, rel_tol=1e-9, abs_tol=0.0):
- return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
-
-
-def is_number(a):
- if isinstance(a, float) or isinstance(a, int):
- return True
- elif isinstance(a, str):
- try:
- float(a)
- return True
- except ValueError:
- return False
- else:
- return False
-
-
-def is_array(a):
- try:
- v = list(ast.literal_eval(a))
- except (ValueError, TypeError, NameError, SyntaxError):
- return False
- else:
- if type(v) is list:
- return True
- else:
- return False
-
-
-def is_project_locked(project_path):
- """Check if an AEDT project lock file exists.
-
- Parameters
- ----------
- project_path : str
- Path for the AEDT project.
-
- Returns
- -------
- bool
- ``True`` when successful, ``False`` when failed.
- """
- return check_if_path_exists(project_path + ".lock")
-
-
-@pyedb_function_handler()
-def remove_project_lock(project_path):
- """Check if an AEDT project exists and try to remove the lock file.
-
- .. note::
- This operation is risky because the file could be opened in another AEDT instance.
-
- Parameters
- ----------
- project_path : str
- Path for the AEDT project.
-
- Returns
- -------
- bool
- ``True`` when successful, ``False`` when failed.
- """
- if os.path.exists(project_path + ".lock"):
- os.remove(project_path + ".lock")
- return True
-
-
-@pyedb_function_handler()
-def read_csv(filename, encoding="utf-8"):
- """Read information from a CSV file and return a list.
-
- Parameters
- ----------
- filename : str
- Full path and name for the CSV file.
- encoding : str, optional
- File encoding for the CSV file. The default is ``"utf-8"``.
-
- Returns
- -------
- list
-
- """
-
- lines = []
- with codecs.open(filename, "rb", encoding) as csvfile:
- reader = csv.reader(csvfile, delimiter=",")
- for row in reader:
- lines.append(row)
- return lines
-
-
-@pyedb_function_handler()
-def read_csv_pandas(filename, encoding="utf-8"):
- """Read information from a CSV file and return a list.
-
- Parameters
- ----------
- filename : str
- Full path and name for the CSV file.
- encoding : str, optional
- File encoding for the CSV file. The default is ``"utf-8"``.
-
- Returns
- -------
- :class:`pandas.DataFrame`
-
- """
- try:
- import pandas as pd
-
- return pd.read_csv(filename, encoding=encoding, header=0, na_values=".")
- except ImportError:
- logging.error("Pandas is not available. Install it.")
- return None
-
-
-@pyedb_function_handler()
-def read_tab(filename):
- """Read information from a TAB file and return a list.
-
- Parameters
- ----------
- filename : str
- Full path and name for the TAB file.
-
- Returns
- -------
- list
-
- """
- with open(filename) as my_file:
- lines = my_file.readlines()
- return lines
-
-
-@pyedb_function_handler()
-def read_xlsx(filename):
- """Read information from an XLSX file and return a list.
-
- Parameters
- ----------
- filename : str
- Full path and name for the XLSX file.
-
- Returns
- -------
- list
-
- """
- try:
- import pandas as pd
-
- lines = pd.read_excel(filename)
- return lines
- except ImportError:
- lines = []
- return lines
-
-
-@pyedb_function_handler()
-def write_csv(output, list_data, delimiter=",", quotechar="|", quoting=csv.QUOTE_MINIMAL):
- if is_ironpython:
- f = open(output, "wb")
- else:
- f = open(output, "w", newline="")
- writer = csv.writer(f, delimiter=delimiter, quotechar=quotechar, quoting=quoting)
- for data in list_data:
- writer.writerow(data)
- f.close()
- return True
-
-
-@pyedb_function_handler()
-def filter_tuple(value, search_key1, search_key2):
- """Filter a tuple of two elements with two search keywords."""
- ignore_case = True
-
- def _create_pattern(k1, k2):
- k1a = re.sub(r"\?", r".", k1)
- k1b = re.sub(r"\*", r".*?", k1a)
- k2a = re.sub(r"\?", r".", k2)
- k2b = re.sub(r"\*", r".*?", k2a)
- pattern = r".*\({},{}\)".format(k1b, k2b)
- return pattern
-
- if ignore_case:
- compiled_re = re.compile(_create_pattern(search_key1, search_key2), re.IGNORECASE)
- else:
- compiled_re = re.compile(_create_pattern(search_key1, search_key2))
-
- m = compiled_re.search(value)
- if m:
- return True
- return False
-
-
-@pyedb_function_handler()
-def filter_string(value, search_key1):
- """Filter a string"""
- ignore_case = True
-
- def _create_pattern(k1):
- k1a = re.sub(r"\?", r".", k1.replace("\\", "\\\\"))
- k1b = re.sub(r"\*", r".*?", k1a)
- pattern = r"^{}$".format(k1b)
- return pattern
-
- if ignore_case:
- compiled_re = re.compile(_create_pattern(search_key1), re.IGNORECASE)
- else:
- compiled_re = re.compile(_create_pattern(search_key1)) # pragma: no cover
-
- m = compiled_re.search(value)
- if m:
- return True
- return False
-
-
-@pyedb_function_handler()
-def recursive_glob(startpath, filepattern):
- """Get a list of files matching a pattern, searching recursively from a start path.
-
- Keyword Arguments:
- startpath -- starting path (directory)
- filepattern -- fnmatch-style filename pattern
- """
- if settings.remote_rpc_session:
- files = []
- for i in settings.remote_rpc_session.filemanager.listdir(startpath):
- if settings.remote_rpc_session.filemanager.isdir(os.path.join(startpath, i)):
- files.extend(recursive_glob(os.path.join(startpath, i), filepattern))
- elif fnmatch.fnmatch(i, filepattern):
- files.append(os.path.join(startpath, i))
- return files
- else:
- return [
- os.path.join(dirpath, filename)
- for dirpath, _, filenames in os.walk(startpath)
- for filename in filenames
- if fnmatch.fnmatch(filename, filepattern)
- ]
-
-
-@pyedb_function_handler()
-def number_aware_string_key(s):
- """Get a key for sorting strings that treats embedded digit sequences as integers.
-
- Parameters
- ----------
- s : str
- String to calculate the key from.
-
- Returns
- -------
- tuple
- Tuple of key entries.
- """
-
- def is_digit(c):
- return "0" <= c and c <= "9"
-
- result = []
- i = 0
- while i < len(s):
- if is_digit(s[i]):
- j = i + 1
- while j < len(s) and is_digit(s[j]):
- j += 1
- key = int(s[i:j])
- result.append(key)
- i = j
- else:
- j = i + 1
- while j < len(s) and not is_digit(s[j]):
- j += 1
- key = s[i:j]
- result.append(key)
- i = j
- return tuple(result)
-
-
-@pyedb_function_handler()
-def _create_json_file(json_dict, full_json_path):
- if not os.path.exists(os.path.dirname(full_json_path)):
- os.makedirs(os.path.dirname(full_json_path))
- if not is_ironpython:
- with open(full_json_path, "w") as fp:
- json.dump(json_dict, fp, indent=4)
- else:
- temp_path = full_json_path.replace(".json", "_temp.json")
- with open(temp_path, "w") as fp:
- json.dump(json_dict, fp, indent=4)
- with open(temp_path, "r") as file:
- filedata = file.read()
- filedata = filedata.replace("True", "true")
- filedata = filedata.replace("False", "false")
- with open(full_json_path, "w") as file:
- file.write(filedata)
- os.remove(temp_path)
- return True
-
-
-# @pyedb_function_handler()
-# def com_active_sessions(version=None, student_version=False, non_graphical=False):
-# """Get information for the active COM AEDT sessions.
-#
-# Parameters
-# ----------
-# version : str, optional
-# Version to check. The default is ``None``, in which case all versions are checked.
-# When specifying a version, you can use a three-digit format like ``"222"`` or a
-# five-digit format like ``"2022.2"``.
-# student_version : bool, optional
-# Whether to check for student version sessions. The default is ``False``.
-# non_graphical : bool, optional
-# Whether to check only for active non-graphical sessions. The default is ``False``.
-#
-# Returns
-# -------
-# list
-# List of AEDT PIDs.
-# """
-# if student_version:
-# keys = ["ansysedtsv.exe"]
-# else:
-# keys = ["ansysedt.exe"]
-# long_version = None
-# if len(version) > 6:
-# version = version[-6:]
-# if version and "." in version:
-# long_version = version
-# version = version[-4:].replace(".", "")
-# if version < "221":
-# version = version[:2] + "." + version[2]
-# long_version = "20{}".format(version)
-# sessions = []
-# for p in psutil.process_iter():
-# try:
-# if p.name() in keys:
-# if long_version and _check_installed_version(os.path.dirname(p.exe()), long_version):
-# sessions.append(p.pid)
-# continue
-# cmd = p.cmdline()
-# if non_graphical and "-ng" in cmd or not non_graphical:
-# if not version or (version and version in cmd[0]):
-# sessions.append(p.pid)
-# except:
-# pass
-# return sessions
-#
-#
-# @pyedb_function_handler()
-# def grpc_active_sessions(version=None, student_version=False, non_graphical=False):
-# """Get information for the active gRPC AEDT sessions.
-#
-# Parameters
-# ----------
-# version : str, optional
-# Version to check. The default is ``None``, in which case all versions are checked.
-# When specififying a version, you can use a three-digit format like ``"222"`` or a
-# five-digit format like ``"2022.2"``.
-# student_version : bool, optional
-# Whether to check for student version sessions. The default is ``False``.
-# non_graphical : bool, optional
-# Whether to check only for active non-graphical sessions. The default is ``False``.
-#
-# Returns
-# -------
-# list
-# List of gRPC ports.
-# """
-# if student_version:
-# keys = ["ansysedtsv.exe", "ansysedtsv"]
-# else:
-# keys = ["ansysedt.exe", "ansysedt"]
-# if version and "." in version:
-# version = version[-4:].replace(".", "")
-# sessions = []
-# for p in psutil.process_iter():
-# try:
-# if p.name() in keys:
-# cmd = p.cmdline()
-# if "-grpcsrv" in cmd:
-# if non_graphical and "-ng" in cmd or not non_graphical:
-# if not version or (version and version in cmd[0]):
-# try:
-# sessions.append(
-# int(cmd[cmd.index("-grpcsrv") + 1]),
-# )
-# except (IndexError, ValueError):
-# # default desktop grpc port.
-# sessions.append(50051)
-# except:
-# pass
-# return sessions
-#
-#
-# def active_sessions(version=None, student_version=False, non_graphical=False):
-# """Get information for the active AEDT sessions.
-#
-# Parameters
-# ----------
-# version : str, optional
-# Version to check. The default is ``None``, in which case all versions are checked.
-# When specifying a version, you can use a three-digit format like ``"222"`` or a
-# five-digit format like ``"2022.2"``.
-# student_version : bool, optional
-# non_graphical : bool, optional
-#
-#
-# Returns
-# -------
-# list
-# List of tuple (AEDT PIDs, port).
-# """
-# if student_version:
-# keys = ["ansysedtsv.exe", "ansysedtsv"]
-# else:
-# keys = ["ansysedt.exe", "ansysedt"]
-# if version and "." in version:
-# version = version[-4:].replace(".", "")
-# if version and version < "222":
-# version = version[:2] + "." + version[2]
-# sessions = []
-# for p in psutil.process_iter():
-# try:
-# if p.name() in keys:
-# cmd = p.cmdline()
-# if non_graphical and "-ng" in cmd or not non_graphical:
-# if not version or (version and version in cmd[0]):
-# if "-grpcsrv" in cmd:
-# if not version or (version and version in cmd[0]):
-# try:
-# sessions.append(
-# [
-# p.pid,
-# int(cmd[cmd.index("-grpcsrv") + 1]),
-# ]
-# )
-# except (IndexError, ValueError):
-# # default desktop grpc port.
-# sessions.append(
-# [
-# p.pid,
-# 50051,
-# ]
-# )
-# else:
-# sessions.append(
-# [
-# p.pid,
-# -1,
-# ]
-# )
-# except:
-# pass
-# return sessions
-
-
-@pyedb_function_handler()
-def active_sessions(version=None, student_version=False, non_graphical=False):
- """Get information for the active AEDT sessions.
-
- Parameters
- ----------
- version : str, optional
- Version to check. The default is ``None``, in which case all versions are checked.
- When specifying a version, you can use a three-digit format like ``"222"`` or a
- five-digit format like ``"2022.2"``.
- student_version : bool, optional
- non_graphical : bool, optional
-
-
- Returns
- -------
- dict
- {AEDT PID: port}
- If the PID corresponds to a COM session port is set to -1
- """
- return_dict = {}
- if student_version:
- keys = ["ansysedtsv.exe", "ansysedtsv"]
- else:
- keys = ["ansysedt.exe", "ansysedt"]
- if version and "." in version:
- version = version[-4:].replace(".", "")
- if version and version < "221":
- version = version[:2] + "." + version[2]
- for p in psutil.process_iter():
- try:
- if p.name() in keys:
- cmd = p.cmdline()
- if non_graphical and "-ng" in cmd or not non_graphical:
- if not version or (version and version in cmd[0]):
- if "-grpcsrv" in cmd:
- if not version or (version and version in cmd[0]):
- try:
- return_dict[p.pid] = int(cmd[cmd.index("-grpcsrv") + 1])
- except (IndexError, ValueError):
- # default desktop grpc port.
- return_dict[p.pid] = 50051
- else:
- return_dict[p.pid] = -1
- for i in psutil.net_connections():
- if i.pid == p.pid and (i.laddr.port > 50050 and i.laddr.port < 50200):
- return_dict[p.pid] = i.laddr.port
- break
- except:
- pass
- return return_dict
-
-
-@pyedb_function_handler()
-def com_active_sessions(version=None, student_version=False, non_graphical=False):
- """Get information for the active COM AEDT sessions.
-
- Parameters
- ----------
- version : str, optional
- Version to check. The default is ``None``, in which case all versions are checked.
- When specifying a version, you can use a three-digit format like ``"222"`` or a
- five-digit format like ``"2022.2"``.
- student_version : bool, optional
- Whether to check for student version sessions. The default is ``False``.
- non_graphical : bool, optional
- Whether to check only for active non-graphical sessions. The default is ``False``.
-
- Returns
- -------
- List
- List of AEDT process IDs.
- """
-
- all_sessions = active_sessions(version, student_version, non_graphical)
-
- return_list = []
- for s, p in all_sessions.items():
- if p == -1:
- return_list.append(s)
- return return_list
-
-
-@pyedb_function_handler()
-def grpc_active_sessions(version=None, student_version=False, non_graphical=False):
- """Get information for the active gRPC AEDT sessions.
-
- Parameters
- ----------
- version : str, optional
- Version to check. The default is ``None``, in which case all versions are checked.
- When specififying a version, you can use a three-digit format like ``"222"`` or a
- five-digit format like ``"2022.2"``.
- student_version : bool, optional
- Whether to check for student version sessions. The default is ``False``.
- non_graphical : bool, optional
- Whether to check only for active non-graphical sessions. The default is ``False``.
-
- Returns
- -------
- List
- List of gRPC ports.
- """
- all_sessions = active_sessions(version, student_version, non_graphical)
-
- return_list = []
- for _, p in all_sessions.items():
- if p > -1:
- return_list.append(p)
- return return_list
-
-
-@pyedb_function_handler()
-def compute_fft(time_vals, value): # pragma: no cover
- """Compute FFT of input transient data.
-
- Parameters
- ----------
- time_vals : `pandas.Series`
- value : `pandas.Series`
-
- Returns
- -------
- tuple
- Frequency and Values.
- """
- try:
- import numpy as np
- except ImportError:
- logging.error("NumPy is not available. Install it.")
- return False
-
- deltaT = time_vals[-1] - time_vals[0]
- num_points = len(time_vals)
- valueFFT = np.fft.fft(value, num_points)
- Npoints = int(len(valueFFT) / 2)
- valueFFT = valueFFT[1 : Npoints + 1]
- valueFFT = valueFFT / len(valueFFT)
- n = np.arange(num_points)
- freq = n / deltaT
- return freq, valueFFT
-
-
-def parse_excitation_file(
- file_name,
- is_time_domain=True,
- x_scale=1,
- y_scale=1,
- impedance=50,
- data_format="Power",
- encoding="utf-8",
- out_mag="Voltage",
-):
- """Parse a csv file and convert data in list that can be applied to Hfss and Hfss3dLayout sources.
-
- Parameters
- ----------
- file_name : str
- Full name of the input file.
- is_time_domain : bool, optional
- Either if the input data is Time based or Frequency Based. Frequency based data are Mag/Phase (deg).
- x_scale : float, optional
- Scaling factor for x axis.
- y_scale : float, optional
- Scaling factor for y axis.
- data_format : str, optional
- Either `"Power"`, `"Current"` or `"Voltage"`.
- impedance : float, optional
- Excitation impedance. Default is `50`.
- encoding : str, optional
- Csv file encoding.
- out_mag : str, optional
- Output magnitude format. It can be `"Voltage"` or `"Power"` depending on Hfss solution.
-
- Returns
- -------
- tuple
- Frequency, magnitude and phase.
- """
- try:
- import numpy as np
- except ImportError:
- logging.error("NumPy is not available. Install it.")
- return False
- df = read_csv_pandas(file_name, encoding=encoding)
- if is_time_domain:
- time = df[df.keys()[0]].values * x_scale
- val = df[df.keys()[1]].values * y_scale
- freq, fval = compute_fft(time, val)
-
- if data_format.lower() == "current":
- if out_mag == "Voltage":
- fval = fval * impedance
- else:
- fval = fval * fval * impedance
- elif data_format.lower() == "voltage":
- if out_mag == "Power":
- fval = fval * fval / impedance
- else:
- if out_mag == "Voltage":
- fval = np.sqrt(fval * impedance)
- mag = list(np.abs(fval))
- phase = [math.atan2(j, i) * 180 / math.pi for i, j in zip(list(fval.real), list(fval.imag))]
-
- else:
- freq = list(df[df.keys()[0]].values * x_scale)
- if data_format.lower() == "current":
- mag = df[df.keys()[1]].values * df[df.keys()[1]].values * impedance * y_scale * y_scale
- elif data_format.lower() == "voltage":
- mag = df[df.keys()[1]].values * df[df.keys()[1]].values / impedance * y_scale * y_scale
- else:
- mag = df[df.keys()[1]].values * y_scale
- mag = list(mag)
- phase = list(df[df.keys()[2]].values)
- return freq, mag, phase
-
-
-def tech_to_control_file(tech_path, unit="nm", control_path=None):
- """Convert a TECH file to an XML file for use in a GDS or DXF import.
-
- Parameters
- ----------
- tech_path : str
- Full path to the TECH file.
- unit : str, optional
- Tech units. If specified in tech file this parameter will not be used. Default is ``"nm"``.
- control_path : str, optional
- Path for outputting the XML file.
-
- Returns
- -------
- str
- Out xml file.
- """
- result = []
- with open(tech_path) as f:
- vals = list(CSS4_COLORS.values())
- id_layer = 0
- for line in f:
- line_split = line.split()
- if len(line_split) == 5:
- layerID, layer_name, _, elevation, layer_height = line.split()
- x = ' '
- result.append(x)
- id_layer += 1
- elif len(line_split) > 1 and "UNIT" in line_split[0]:
- unit = line_split[1]
- if not control_path:
- control_path = os.path.splitext(tech_path)[0] + ".xml"
- with open(control_path, "w") as f:
- f.write('\n')
- f.write(' \n')
- f.write("\n")
- f.write(' \n')
- f.write(' \n'.format(unit))
- for res in result:
- f.write(res + "\n")
-
- f.write(" \n")
- f.write(" \n")
- f.write("\n")
- f.write(' \n')
- f.write("\n")
- f.write("\n")
-
- return control_path
-
-
-class PropsManager(object):
- def __getitem__(self, item):
- """Get the `self.props` key value.
-
- Parameters
- ----------
- item : str
- Key to search
- """
- item_split = item.split("/")
- if len(item_split) == 1:
- item_split = item_split[0].split("__")
- props = self.props
- found_el = []
- matching_percentage = 1
- while matching_percentage >= 0.4:
- for item_value in item_split:
- found_el = self._recursive_search(props, item_value, matching_percentage)
- # found_el = difflib.get_close_matches(item_value, list(props.keys()), 1, matching_percentage)
- if found_el:
- props = found_el[1][found_el[2]]
- # props = props[found_el[0]]
- if found_el:
- return props
- else:
- matching_percentage -= 0.02
- self._app.logger.warning("Key %s not found.Check one of available keys in self.available_properties", item)
- return None
-
- def __setitem__(self, key, value):
- """Set the `self.props` key value.
-
- Parameters
- ----------
- key : str
- Key to apply.
- value : int, float, bool, str, dict
- Value to apply.
- """
- item_split = key.split("/")
- if len(item_split) == 1:
- item_split = item_split[0].split("__")
- found_el = []
- props = self.props
- matching_percentage = 1
- key_path = []
- while matching_percentage >= 0.4:
- for item_value in item_split:
- found_el = self._recursive_search(props, item_value, matching_percentage)
- if found_el:
- props = found_el[1][found_el[2]]
- key_path.append(found_el[2])
- if found_el:
- if matching_percentage < 1:
- self._app.logger.info(
- "Key %s matched internal key '%s' with confidence of %s.",
- key,
- "/".join(key_path),
- round(matching_percentage * 100),
- )
- matching_percentage = 0
-
- else:
- matching_percentage -= 0.02
- if found_el:
- found_el[1][found_el[2]] = value
- self.update()
- else:
- props[key] = value
- self.update()
- self._app.logger.warning("Key %s not found. Trying to applying new key ", key)
-
- @pyedb_function_handler()
- def _recursive_search(self, dict_in, key="", matching_percentage=0.8):
- f = difflib.get_close_matches(key, list(dict_in.keys()), 1, matching_percentage)
- if f:
- return True, dict_in, f[0]
- else:
- for v in list(dict_in.values()):
- if isinstance(v, (dict, OrderedDict)):
- out_val = self._recursive_search(v, key, matching_percentage)
- if out_val:
- return out_val
- elif isinstance(v, list) and isinstance(v[0], (dict, OrderedDict)):
- for val in v:
- out_val = self._recursive_search(val, key, matching_percentage)
- if out_val:
- return out_val
- return False
-
- @pyedb_function_handler()
- def _recursive_list(self, dict_in, prefix=""):
- available_list = []
- for k, v in dict_in.items():
- if prefix:
- name = prefix + "/" + k
- else:
- name = k
- available_list.append(name)
- if isinstance(v, (dict, OrderedDict)):
- available_list.extend(self._recursive_list(v, name))
- return available_list
-
- @property
- def available_properties(self):
- """Available properties.
-
- Returns
- -------
- list
- """
- if self.props:
- return self._recursive_list(self.props)
- return []
-
- @pyedb_function_handler()
- def update(self):
- """Update method."""
- pass
-
-
-clamp = lambda n, minn, maxn: max(min(maxn, n), minn)
-rgb_color_codes = {
- "Black": (0, 0, 0),
- "Green": (0, 128, 0),
- "White": (255, 255, 255),
- "Red": (255, 0, 0),
- "Lime": (0, 255, 0),
- "Blue": (0, 0, 255),
- "Yellow": (255, 255, 0),
- "Cyan": (0, 255, 255),
- "Magenta": (255, 0, 255),
- "Silver": (192, 192, 192),
- "Gray": (128, 128, 128),
- "Maroon": (128, 0, 0),
- "Olive": (128, 128, 0),
- "Purple": (128, 0, 128),
- "Teal": (0, 128, 128),
- "Navy": (0, 0, 128),
- "copper": (184, 115, 51),
- "stainless steel": (224, 223, 219),
-}
-
-
-@pyedb_function_handler()
-def _arg2dict(arg, dict_out):
- if arg[0] == "NAME:DimUnits" or "NAME:Point" in arg[0]:
- if arg[0][5:] in dict_out:
- if isinstance(dict_out[arg[0][5:]][0], (list, tuple)):
- dict_out[arg[0][5:]].append(list(arg[1:]))
- else:
- dict_out[arg[0][5:]] = [dict_out[arg[0][5:]]]
- dict_out[arg[0][5:]].append(list(arg[1:]))
- else:
- dict_out[arg[0][5:]] = list(arg[1:])
- elif arg[0][:5] == "NAME:":
- top_key = arg[0][5:]
- dict_in = OrderedDict()
- i = 1
- while i < len(arg):
- if arg[i][0][:5] == "NAME:" and (
- isinstance(arg[i], (list, tuple)) or str(type(arg[i])) == r""
- ):
- _arg2dict(list(arg[i]), dict_in)
- i += 1
- elif arg[i][-2:] == ":=":
- if str(type(arg[i + 1])) == r"":
- if arg[i][:-2] in dict_in:
- dict_in[arg[i][:-2]].append(list(arg[i + 1]))
- else:
- dict_in[arg[i][:-2]] = list(arg[i + 1])
- else:
- if arg[i][:-2] in dict_in:
- if isinstance(dict_in[arg[i][:-2]], list):
- dict_in[arg[i][:-2]].append(arg[i + 1])
- else:
- dict_in[arg[i][:-2]] = [dict_in[arg[i][:-2]]]
- dict_in[arg[i][:-2]].append(arg[i + 1])
- else:
- dict_in[arg[i][:-2]] = arg[i + 1]
-
- i += 2
- else:
- raise ValueError("Incorrect data argument format")
- if top_key in dict_out:
- if isinstance(dict_out[top_key], list):
- dict_out[top_key].append(dict_in)
- else:
- dict_out[top_key] = [dict_out[top_key], dict_in]
- else:
- dict_out[top_key] = dict_in
- else:
- raise ValueError("Incorrect data argument format")
-
-
-def _uname(name=None):
- """Append a 6-digit hash code to a specified name.
-
- Parameters
- ----------
- name : str
- Name to append the hash code to. The default is ``"NewObject_"``.
-
- Returns
- -------
- str
-
- """
- char_set = string.ascii_uppercase + string.digits
- unique_name = "".join(random.sample(char_set, 6))
- if name:
- return name + unique_name
- else:
- return "NewObject_" + unique_name
-
-
-@pyedb_function_handler()
-def _to_boolean(val):
- """Retrieve the Boolean value of the provided input.
-
- If the value is a Boolean, return the value.
- Otherwise check to see if the value is in
- ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]
- and return True if the value is not in the list.
-
- Parameters
- ----------
- val : bool or str
- Input value to test for True/False condition.
-
- Returns
- -------
- bool
-
- """
-
- if val is True or val is False:
- return val
-
- false_items = ["false", "f", "no", "n", "none", "0", "[]", "{}", ""]
-
- return not str(val).strip().lower() in false_items
-
-
-@pyedb_function_handler()
-def _dim_arg(value, units):
- """Concatenate a specified units string to a numerical input.
-
- Parameters
- ----------
- value : str or number
- Valid expression string in the AEDT modeler. For example, ``"5mm"``.
- units : str
- Valid units string in the AEDT modeler. For example, ``"mm"``.
-
- Returns
- -------
- str
-
- """
- try:
- val = float(value)
- if isinstance(value, int):
- val = value
- return str(val) + units
- except:
- return value
-
-
-@pyedb_function_handler()
-def _check_installed_version(install_path, long_version):
- """Check installation folder to determine if it is for specified Ansys EM version.
-
- Parameters
- ----------
- install_path: str
- Installation folder to check. For example, ``"C:\\Program Files\\AnsysEM\\v231\\Win64"``.
- long_version: str
- Long form of version number. For example, ``"2023.1"``.
-
- Returns
- -------
- bool
-
- """
- product_list_path = os.path.join(install_path, "config", "ProductList.txt")
- if os.path.isfile(product_list_path):
- try:
- with open(product_list_path, "r") as f:
- install_version = f.readline().strip()[-6:]
- if install_version == long_version:
- return True
- except:
- pass
- return False
-
-
-def install_with_pip(package_name, package_path=None, upgrade=False, uninstall=False): # pragma: no cover
- """Install a new package using pip.
- This method is useful for installing a package from the AEDT Console without launching the Python environment.
-
- Parameters
- ----------
- package_name : str
- Name of the package to install.
- package_path : str, optional
- Path for the GitHub package to download and install. For example, ``git+https://.....``.
- upgrade : bool, optional
- Whether to upgrade the package. The default is ``False``.
- uninstall : bool, optional
- Whether to install the package or uninstall the package.
- """
- if is_linux and is_ironpython:
- import subprocessdotnet as subprocess
- else:
- import subprocess
- executable = '"{}"'.format(sys.executable) if is_windows else sys.executable
-
- commands = []
- if uninstall:
- commands.append([executable, "-m", "pip", "uninstall", "--yes", package_name])
- else:
- if package_path and upgrade:
- commands.append([executable, "-m", "pip", "uninstall", "--yes", package_name])
- command = [executable, "-m", "pip", "install", package_path]
- else:
- command = [executable, "-m", "pip", "install", package_name]
- if upgrade:
- command.append("-U")
-
- commands.append(command)
- for command in commands:
- if is_linux:
- p = subprocess.Popen(command)
- else:
- p = subprocess.Popen(" ".join(command))
- p.wait()
-
-
-class Help: # pragma: no cover
- def __init__(self):
- self._base_path = "https://aedt.docs.pyansys.com/version/stable"
- self.browser = "default"
-
- def _launch_ur(self, url):
- import webbrowser
-
- if self.browser != "default":
- webbrowser.get(self.browser).open_new_tab(url)
- else:
- webbrowser.open_new_tab(url)
-
- def search(self, keywords, app_name=None, search_in_examples_only=False):
- """Search for one or more keywords.
-
- Parameters
- ----------
- keywords : str or list
- app_name : str, optional
- Name of a PyAEDT app. For example, ``"Hfss"``, ``"Circuit"``, ``"Icepak"``, or any other available app.
- search_in_examples_only : bool, optional
- Whether to search for the one or more keywords only in the PyAEDT examples.
- The default is ``False``.
- """
- if isinstance(keywords, str):
- keywords = [keywords]
- if search_in_examples_only:
- keywords.append("This example")
- if app_name:
- keywords.append(app_name)
- url = self._base_path + "/search.html?q={}".format("+".join(keywords))
- self._launch_ur(url)
-
- def getting_started(self):
- """Open the PyAEDT User guide page."""
- url = self._base_path + "/User_guide/index.html"
- self._launch_ur(url)
-
- def examples(self):
- """Open the PyAEDT Examples page."""
- url = self._base_path + "/examples/index.html"
- self._launch_ur(url)
-
- def github(self):
- """Open the PyAEDT GitHub page."""
- url = "https://github.com/ansys/pyaedt"
- self._launch_ur(url)
-
- def changelog(self, release=None):
- """Open the PyAEDT GitHub Changelog for a given release.
-
- Parameters
- ----------
- release : str, optional
- Release to get the changelog for. For example, ``"0.6.70"``.
- """
- if release is None:
- from pyaedt import __version__ as release
- url = "https://github.com/ansys/pyaedt/releases/tag/v" + release
- self._launch_ur(url)
-
- def issues(self):
- """Open the PyAEDT GitHub Issues page."""
- url = "https://github.com/ansys/pyaedt/issues"
- self._launch_ur(url)
-
- def ansys_forum(self):
- """Open the PyAEDT GitHub Issues page."""
- url = "https://discuss.ansys.com/discussions/tagged/pyaedt"
- self._launch_ur(url)
-
- def developer_forum(self):
- """Open the Discussions page on the Ansys Developer site."""
- url = "https://developer.ansys.com/"
- self._launch_ur(url)
-
-
-# class Property(property):
-#
-# @pyedb_function_handler()
-# def getter(self, fget):
-# """Property getter."""
-# return self.__class__.__base__(fget, self.fset, self.fdel, self.__doc__)
-#
-# @pyedb_function_handler()
-# def setter(self, fset):
-# """Property setter."""
-# return self.__class__.__base__(self.fget, fset, self.fdel, self.__doc__)
-#
-# @pyedb_function_handler()
-# def deleter(self, fdel):
-# """Property deleter."""
-# return self.__class__.__base__(self.fget, self.fset, fdel, self.__doc__)
-
-# property = Property
-
-online_help = Help()
diff --git a/src/pyedb/legacy/generic/settings.py b/src/pyedb/legacy/generic/settings.py
deleted file mode 100644
index b44371eac5..0000000000
--- a/src/pyedb/legacy/generic/settings.py
+++ /dev/null
@@ -1,315 +0,0 @@
-import logging
-import os
-import time
-
-is_linux = os.name == "posix"
-
-
-class Settings(object):
- """Manages all PyAEDT environment variables and global settings."""
-
- def __init__(self):
- self._enable_logger = True
- self._enable_desktop_logs = True
- self._enable_screen_logs = True
- self._enable_file_logs = True
- self.pyaedt_server_path = ""
- self._logger_file_path = None
- self._logger_formatter = "%(asctime)s:%(destination)s:%(extra)s%(levelname)-8s:%(message)s"
- self._logger_datefmt = "%Y/%m/%d %H.%M.%S"
- self._enable_debug_edb_logger = False
- self._enable_debug_grpc_api_logger = False
- self._enable_debug_methods_argument_logger = False
- self._enable_debug_geometry_operator_logger = False
- self._enable_debug_internal_methods_logger = False
- self._enable_debug_logger = False
- self._enable_error_handler = True
- self._aedt_version = None
- self.remote_api = False
- self._use_grpc_api = None
- self.formatter = None
- self.remote_rpc_session = None
- self.remote_rpc_session_temp_folder = ""
- self.remote_rpc_service_manager_port = 17878
- self._project_properties = {}
- self._project_time_stamp = 0
- self._disable_bounding_box_sat = False
- self._force_error_on_missing_project = False
- self._enable_pandas_output = False
- self.time_tick = time.time()
- self._global_log_file_name = "pyaedt_{}.log".format(os.path.split(os.path.expanduser("~"))[-1])
- self._enable_global_log_file = True
- self._enable_local_log_file = False
- self._global_log_file_size = 10
- self._edb_dll_path = None
- self._lsf_num_cores = 2
- self._lsf_ram = 1000
- self._use_lsf_scheduler = False
- self._lsf_aedt_command = "ansysedt"
- self._lsf_timeout = 3600
- self._lsf_queue = None
- self._aedt_environment_variables = {
- "ANS_MESHER_PROC_DUMP_PREPOST_BEND_SM3": "1",
- "ANSYSEM_FEATURE_SF6694_NON_GRAPHICAL_COMMAND_EXECUTION_ENABLE": "1",
- "ANSYSEM_FEATURE_SF159726_SCRIPTOBJECT_ENABLE": "1",
- "ANSYSEM_FEATURE_SF222134_CABLE_MODELING_ENHANCEMENTS_ENABLE": "1",
- "ANSYSEM_FEATURE_F395486_RIGID_FLEX_BENDING_ENABLE": "1",
- "ANSYSEM_FEATURE_S432616_LAYOUT_COMPONENT_IN_3D_ENABLE": "1",
- "ANSYSEM_FEATURE_F545177_ECAD_INTEGRATION_WITH_APHI_ENABLE": "1",
- "ANSYSEM_FEATURE_F650636_MECH_LAYOUT_COMPONENT_ENABLE": "1",
- "ANSYSEM_FEATURE_F538630_MECH_TRANSIENT_THERMAL_ENABLE": "1",
- "ANSYSEM_FEATURE_F335896_MECHANICAL_STRUCTURAL_SOLN_TYPE_ENABLE": "1",
- }
- if is_linux:
- self._aedt_environment_variables["ANS_NODEPCHECK"] = "1"
- self._desktop_launch_timeout = 90
- self._number_of_grpc_api_retries = 6
- self._retry_n_times_time_interval = 0.1
-
- @property
- def retry_n_times_time_interval(self):
- """Time interval between the retries by the ``_retry_n_times`` method."""
- return self._retry_n_times_time_interval
-
- @retry_n_times_time_interval.setter
- def retry_n_times_time_interval(self, value):
- self._retry_n_times_time_interval = float(value)
-
- @property
- def edb_dll_path(self):
- """Optional path for the EDB DLL file."""
- return self._edb_dll_path
-
- @edb_dll_path.setter
- def edb_dll_path(self, value):
- if os.path.exists(value):
- self._edb_dll_path = value
-
- @property
- def global_log_file_size(self):
- """Global PyAEDT log file size in MB. The default value is ``10``."""
- return self._global_log_file_size
-
- @global_log_file_size.setter
- def global_log_file_size(self, value):
- self._global_log_file_size = value
-
- @property
- def enable_global_log_file(self):
- """Flag for enabling and disabling the global PyAEDT log file located in the global temp folder.
- The default is ``True``."""
- return self._enable_global_log_file
-
- @enable_global_log_file.setter
- def enable_global_log_file(self, value):
- self._enable_global_log_file = value
-
- @property
- def enable_local_log_file(self):
- """Flag for enabling and disabling the local PyAEDT log file located
- in the ``projectname.pyaedt`` project folder. The default is ``True``."""
- return self._enable_local_log_file
-
- @enable_local_log_file.setter
- def enable_local_log_file(self, value):
- self._enable_local_log_file = value
-
- @property
- def global_log_file_name(self):
- """Global PyAEDT log file path. The default is ``pyaedt_username.log``."""
- return self._global_log_file_name
-
- @global_log_file_name.setter
- def global_log_file_name(self, value):
- self._global_log_file_name = value
-
- @property
- def enable_pandas_output(self):
- """Flag for whether Pandas is being used to export dictionaries and lists. This attribute
- applies to Solution data output. The default is ``False``. If ``True``, the property or
- method returns a Pandas object. This property is valid only in the CPython environment."""
- return self._enable_pandas_output
-
- @enable_pandas_output.setter
- def enable_pandas_output(self, val):
- self._enable_pandas_output = val
-
- @property
- def enable_debug_methods_argument_logger(self):
- """Flag for whether to write out the method's arguments in the debug logger.
- The default is ``False``."""
- return self._enable_debug_methods_argument_logger
-
- @enable_debug_methods_argument_logger.setter
- def enable_debug_methods_argument_logger(self, val):
- self._enable_debug_methods_argument_logger = val
-
- @property
- def force_error_on_missing_project(self):
- """Flag for whether to check the project path. The default is ``False``. If
- ``True``, when passing a project path, the project has to exist. Otherwise, an
- error is raised."""
- return self._force_error_on_missing_project
-
- @force_error_on_missing_project.setter
- def force_error_on_missing_project(self, val):
- self._force_error_on_missing_project = val
-
- @property
- def disable_bounding_box_sat(self):
- """Flag for enabling and disabling bounding box evaluation by exporting a SAT file."""
- return self._disable_bounding_box_sat
-
- @disable_bounding_box_sat.setter
- def disable_bounding_box_sat(self, val):
- self._disable_bounding_box_sat = val
-
- @property
- def use_grpc_api(self):
- """Flag for whether to use the gRPC API or legacy COM object."""
- return self._use_grpc_api
-
- @use_grpc_api.setter
- def use_grpc_api(self, val):
- self._use_grpc_api = val
-
- @property
- def logger(self):
- """Active logger."""
- try:
- return logging.getLogger("Global")
- except: # pragma: no cover
- return logging.getLogger(__name__)
-
- @property
- def enable_error_handler(self):
- """Flag for enabling and disabling the internal PyAEDT error handling."""
- return self._enable_error_handler
-
- @enable_error_handler.setter
- def enable_error_handler(self, val):
- self._enable_error_handler = val
-
- @property
- def enable_desktop_logs(self):
- """Flag for enabling and disabling the logging to the AEDT message window."""
- return self._enable_desktop_logs
-
- @enable_desktop_logs.setter
- def enable_desktop_logs(self, val):
- self._enable_desktop_logs = val
-
- @property
- def enable_screen_logs(self):
- """Flag for enabling and disabling the logging to STDOUT."""
- return self._enable_screen_logs
-
- @enable_screen_logs.setter
- def enable_screen_logs(self, val):
- self._enable_screen_logs = val
-
- @property
- def pyaedt_server_path(self):
- """``PYAEDT_SERVER_AEDT_PATH`` environment variable."""
- return os.getenv("PYAEDT_SERVER_AEDT_PATH", "")
-
- @pyaedt_server_path.setter
- def pyaedt_server_path(self, val):
- os.environ["PYAEDT_SERVER_AEDT_PATH"] = str(val)
-
- @property
- def enable_file_logs(self):
- """Flag for enabling and disabling the logging to a file."""
- return self._enable_file_logs
-
- @enable_file_logs.setter
- def enable_file_logs(self, val):
- self._enable_file_logs = val
-
- @property
- def enable_logger(self):
- """Flag for enabling and disabling the logging overall."""
- return self._enable_logger
-
- @enable_logger.setter
- def enable_logger(self, val):
- self._enable_logger = val
-
- @property
- def logger_file_path(self):
- """PyAEDT log file path."""
- return self._logger_file_path
-
- @logger_file_path.setter
- def logger_file_path(self, val):
- self._logger_file_path = val
-
- @property
- def logger_formatter(self):
- """Message format of the log entries.
- The default is ``'%(asctime)s:%(destination)s:%(extra)s%(levelname)-8s:%(message)s'``"""
- return self._logger_formatter
-
- @logger_formatter.setter
- def logger_formatter(self, val):
- self._logger_formatter = val
-
- @property
- def logger_datefmt(self):
- """Date format of the log entries.
- The default is ``'%Y/%m/%d %H.%M.%S'``"""
- return self._logger_datefmt
-
- @logger_datefmt.setter
- def logger_datefmt(self, val):
- self._logger_datefmt = val
-
- @property
- def enable_debug_edb_logger(self):
- """Flag for enabling and disabling the logger for any EDB API methods."""
- return self._enable_debug_edb_logger
-
- @enable_debug_edb_logger.setter
- def enable_debug_edb_logger(self, val):
- self._enable_debug_edb_logger = val
-
- @property
- def enable_debug_grpc_api_logger(self):
- """Flag for enabling and disabling the logging for the gRPC API calls."""
- return self._enable_debug_grpc_api_logger
-
- @enable_debug_grpc_api_logger.setter
- def enable_debug_grpc_api_logger(self, val):
- self._enable_debug_grpc_api_logger = val
-
- @property
- def enable_debug_geometry_operator_logger(self):
- """Flag for enabling and disabling the logging for the geometry operators.
- This setting is useful for debug purposes."""
- return self._enable_debug_geometry_operator_logger
-
- @enable_debug_geometry_operator_logger.setter
- def enable_debug_geometry_operator_logger(self, val):
- self._enable_debug_geometry_operator_logger = val
-
- @property
- def enable_debug_internal_methods_logger(self):
- """Flag for enabling and disabling the logging for internal methods.
- This setting is useful for debug purposes."""
- return self._enable_debug_internal_methods_logger
-
- @enable_debug_internal_methods_logger.setter
- def enable_debug_internal_methods_logger(self, val):
- self._enable_debug_internal_methods_logger = val
-
- @property
- def enable_debug_logger(self):
- """Flag for enabling and disabling the debug level logger."""
- return self._enable_debug_logger
-
- @enable_debug_logger.setter
- def enable_debug_logger(self, val):
- self._enable_debug_logger = val
-
-
-settings = Settings()
diff --git a/src/pyedb/legacy/modeler/__init__.py b/src/pyedb/legacy/modeler/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/src/pyedb/legacy/modeler/geometry_operators.py b/src/pyedb/legacy/modeler/geometry_operators.py
deleted file mode 100644
index 069556a734..0000000000
--- a/src/pyedb/legacy/modeler/geometry_operators.py
+++ /dev/null
@@ -1,2086 +0,0 @@
-# -*- coding: utf-8 -*-
-import math
-import re
-import sys
-
-from pyedb.generic.constants import AXIS
-from pyedb.generic.constants import PLANE
-from pyedb.generic.constants import SWEEPDRAFT
-from pyedb.generic.constants import scale_units
-from pyedb.generic.general_methods import pyedb_function_handler
-
-
-
-class GeometryOperators(object):
- """Manages geometry operators."""
-
- @staticmethod
- @pyedb_function_handler()
- def List2list(input_list):
- """Convert a C# list object to a Python list.
-
- This function performs a deep conversion.
-
- Parameters
- ----------
- input_list : List
- C# list to convert to a Python list.
-
- Returns
- -------
- List
- Converted Python list.
-
- """
- output_list = []
- for i in input_list:
- if "List" in str(type(i)):
- output_list.append(GeometryOperators.List2list(list(i)))
- else:
- output_list.append(i)
- return output_list
-
- @staticmethod
- @pyedb_function_handler()
- def parse_dim_arg(string, scale_to_unit=None, variable_manager=None):
- """Convert a number and unit to a float.
- Angles are converted in radians.
-
- Parameters
- ----------
- string : str, optional
- String to convert. For example, ``"2mm"``. The default is ``None``.
- scale_to_unit : str, optional
- Units for the value to convert. For example, ``"mm"``.
- variable_manager : :class:`pyaedt.application.Variables.VariableManager`, optional
- Try to parse formula and returns numeric value.
- The default is ``None``.
-
- Returns
- -------
- float
- Value for the converted value and units. For example, ``0.002``.
-
- Examples
- --------
- Parse `'"2mm"'`.
-
- >>> from legacy.modeler.geometry_operators import GeometryOperators as go
- >>> go.parse_dim_arg('2mm')
- >>> 0.002
-
- Use the optional argument ``scale_to_unit`` to specify the destination unit.
-
- >>> go.parse_dim_arg('2mm', scale_to_unit='mm')
- >>> 2.0
-
- """
- if type(string) is not str:
- try:
- return float(string)
- except ValueError: # pragma: no cover
- raise TypeError("Input argument is not string nor number")
- sunit = 1.0
- if scale_to_unit:
- sunit = scale_units(scale_to_unit)
-
- pattern = r"(?P[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?)\s*(?P[a-z_A-Z]*)"
- m = re.search(pattern, string)
- if m:
- if m.group(0) != string:
- if variable_manager:
- variable_manager["temp_var"] = string
- value = variable_manager["temp_var"].numeric_value
- del variable_manager["temp_var"]
- return value
- else:
- return string
- elif not m.group("unit"):
- return float(m.group("number"))
- else:
- scaling_factor = scale_units(m.group("unit"))
- return float(m.group("number")) * scaling_factor / sunit
- else:
- if variable_manager:
- if not variable_manager.set_variable("temp_var", string):
- if not variable_manager.set_variable("temp_var", string, postprocessing=True):
- return string
- value = variable_manager["temp_var"].value / sunit
- del variable_manager["temp_var"]
- return value
-
- @staticmethod
- @pyedb_function_handler()
- def cs_plane_to_axis_str(val):
- """Retrieve a string for a coordinate system plane.
-
- Parameters
- ----------
- val : int
- ``PLANE`` enum vélo.
-
- Returns
- -------
- str
- String for the coordinate system plane.
-
- """
- if val == PLANE.XY or val == "XY":
- return "Z"
- elif val == PLANE.YZ or val == "YZ":
- return "X"
- else:
- return "Y"
-
- @staticmethod
- @pyedb_function_handler()
- def cs_plane_to_plane_str(val):
- """Retrieve a string for a coordinate system plane.
-
- Parameters
- ----------
- val :
-
-
- Returns
- -------
- str
- String for the coordinate system plane.
-
- """
- if val == PLANE.XY or val == "XY":
- return "XY"
- elif val == PLANE.YZ or val == "YZ":
- return "YZ"
- else:
- return "ZX"
-
- @staticmethod
- @pyedb_function_handler()
- def cs_axis_str(val):
- """Retrieve a string for a coordinate system axis.
-
- Parameters
- ----------
- val : int
- ``AXIS`` enum value.
-
-
- Returns
- -------
- str
- String for the coordinate system axis.
-
- """
- if val == AXIS.X or val == "X":
- return "X"
- elif val == AXIS.Y or val == "Y":
- return "Y"
- else:
- return "Z"
-
- @staticmethod
- @pyedb_function_handler()
- def draft_type_str(val):
- """Retrieve the draft type.
-
- Parameters
- ----------
- val : int
- ``SWEEPDRAFT`` enum value.
-
- Returns
- -------
- str
- Type of the draft.
-
- """
- if val == SWEEPDRAFT.Extended:
- return "Extended"
- elif val == SWEEPDRAFT.Round:
- return "Round"
- else:
- return "Natural"
-
- @staticmethod
- @pyedb_function_handler()
- def get_mid_point(v1, v2):
- """Evaluate the midpoint between two points.
-
- Parameters
- ----------
- v1 : List
- List of ``[x, y, z]`` coordinates for the first point.
- v2 : List
- List of ``[x, y, z]`` coordinates for the second point.
-
- Returns
- -------
- List
- List of ``[x, y, z]`` coordinates for the midpoint.
-
- """
- m = [((i + j) / 2.0) for i, j in zip(v1, v2)]
- return m
-
- @staticmethod
- @pyedb_function_handler()
- def get_triangle_area(v1, v2, v3):
- """Evaluate the area of a triangle defined by its three vertices.
-
- Parameters
- ----------
- v1 : List
- List of ``[x, y, z]`` coordinates for the first vertex.
- v2 : List
- List of ``[x, y, z]`` coordinates for the second vertex.
- v3 : List
- List of ``[x, y, z]`` coordinates for the third vertex.
-
- Returns
- -------
- float
- Area of the triangle.
-
- """
- a = ((v1[0] - v2[0]) ** 2 + (v1[1] - v2[1]) ** 2 + (v1[2] - v2[2]) ** 2) ** 0.5
- b = ((v2[0] - v3[0]) ** 2 + (v2[1] - v3[1]) ** 2 + (v2[2] - v3[2]) ** 2) ** 0.5
- c = ((v3[0] - v1[0]) ** 2 + (v3[1] - v1[1]) ** 2 + (v3[2] - v1[2]) ** 2) ** 0.5
- s = 0.5 * (a + b + c)
- area = (s * (s - a) * (s - b) * (s - c)) ** 0.5
- if isinstance(area, complex):
- area = area.real
- return area
-
- @staticmethod
- @pyedb_function_handler()
- def v_cross(a, b):
- """Evaluate the cross product of two geometry vectors.
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the first vector.
- b : List
- List of ``[x, y, z]`` coordinates for the second vector.
-
- Returns
- -------
- List
- List of ``[x, y, z]`` coordinates for the result vector.
- """
- c = [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]
- return c
-
- @staticmethod
- @pyedb_function_handler()
- def _v_dot(a, b):
- """Evaluate the dot product between two geometry vectors.
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the first vector.
- b : List
- List of ``[x, y, z]`` coordinates for the second vector.
-
- Returns
- -------
- float
- Result of the dot product.
-
- """
- if len(a) == 3:
- c = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
- return c
- elif len(a) == 2:
- c = a[0] * b[0] + a[1] * b[1]
- return c
- return False
-
- @staticmethod
- @pyedb_function_handler()
- def v_dot(a, b):
- """Evaluate the dot product between two geometry vectors.
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the first vector.
- b : List
- List of ``[x, y, z]`` coordinates for the second vector.
-
- Returns
- -------
- float
- Result of the dot product.
-
- """
- return GeometryOperators._v_dot(a, b)
-
- @staticmethod
- @pyedb_function_handler()
- def v_prod(s, v):
- """Evaluate the product between a scalar value and a vector.
-
- Parameters
- ----------
- s : float
- Scalar value.
- v : List
- List of values for the vector in the format ``[v1, v2,..., vn]``.
- The vector can be any length.
-
- Returns
- -------
- List
- List of values for the result vector. This list is the
- same length as the list for the input vector.
-
- """
- r = [s * i for i in v]
- return r
-
- @staticmethod
- @pyedb_function_handler()
- def v_rotate_about_axis(vector, angle, radians=False, axis="z"):
- """Evaluate rotation of a vector around an axis.
-
- Parameters
- ----------
- vector : list
- List of the three component of the vector.
- angle : float
- Angle by which the vector is to be rotated (radians or degree).
- radians : bool, optional
- Whether the angle is expressed in radians. Default is ``False``.
- axis : str, optional
- Axis about which to rotate the vector. Default is ``"z"``.
-
- Returns
- -------
- list
- List of values for the result vector.
-
- """
- if not radians:
- angle = math.radians(angle)
- x, y, z = vector
- axis = axis.lower()
- if axis == "z":
- rotated_x = x * math.cos(angle) - y * math.sin(angle)
- rotated_y = x * math.sin(angle) + y * math.cos(angle)
- rotated_z = z
- elif axis == "y":
- rotated_x = x * math.cos(angle) + z * math.sin(angle)
- rotated_y = y
- rotated_z = -x * math.sin(angle) + z * math.cos(angle)
- elif axis == "x":
- rotated_x = x
- rotated_y = y * math.cos(angle) - z * math.sin(angle)
- rotated_z = y * math.sin(angle) + z * math.cos(angle)
- else: # pragma: no cover
- raise ValueError("Invalid axis. Choose 'x', 'y', or 'z'.")
- return rotated_x, rotated_y, rotated_z
-
- @staticmethod
- @pyedb_function_handler()
- def v_sub(a, b):
- """Evaluate two geometry vectors by subtracting them (a-b).
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the first vector.
- b : List
- List of ``[x, y, z]`` coordinates for the second vector.
-
- Returns
- -------
- List
- List of ``[x, y, z]`` coordinates for the result vector.
-
- """
- c = [i - j for i, j in zip(a, b)]
- return c
-
- @staticmethod
- @pyedb_function_handler()
- def v_sum(a, b):
- """Evaluate two geometry vectors by adding them (a+b).
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the first vector.
- b : List
- List of ``[x, y, z]`` coordinates for the second vector.
-
- Returns
- -------
- List
- List of ``[x, y, z]`` coordinates for the result vector.
-
- """
- c = [i + j for i, j in zip(a, b)]
- return c
-
- @staticmethod
- @pyedb_function_handler()
- def v_norm(a):
- """Evaluate the Euclidean norm of a geometry vector.
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the vector.
-
- Returns
- -------
- float
- Evaluated norm in the same unit as the coordinates for the input vector.
-
- """
- t = 0
- for i in a:
- t += i**2
- m = t**0.5
- return m
-
- @staticmethod
- @pyedb_function_handler()
- def normalize_vector(v):
- """Normalize a geometry vector.
-
- Parameters
- ----------
- v : List
- List of ``[x, y, z]`` coordinates for vector.
-
- Returns
- -------
- List
- List of ``[x, y, z]`` coordinates for the normalized vector.
-
- """
- # normalize a vector to its norm
- norm = GeometryOperators.v_norm(v)
- vn = [i / norm for i in v]
- return vn
-
- @staticmethod
- @pyedb_function_handler()
- def v_points(p1, p2):
- """Vector from one point to another point.
-
- Parameters
- ----------
- p1 : List
- Coordinates ``[x1,y1,z1]`` for the first point.
- p2 : List
- Coordinates ``[x2,y2,z2]`` for second point.
-
- Returns
- -------
- List
- Coordinates ``[vx, vy, vz]`` for the vector from the first point to the second point.
- """
- return GeometryOperators.v_sub(p2, p1)
-
- @staticmethod
- @pyedb_function_handler()
- def points_distance(p1, p2):
- """Evaluate the distance between two points expressed as their Cartesian coordinates.
-
- Parameters
- ----------
- p1 : List
- List of ``[x1,y1,z1]`` coordinates for the first point.
- p2 : List
- List of ``[x2,y2,z2]`` coordinates for the second ppint.
-
- Returns
- -------
- float
- Distance between the two points in the same unit as the coordinates for the points.
-
- """
- # fmt: off
- if len(p1) == 3:
- return math.sqrt((p2[0]-p1[0])**2 + (p2[1]-p1[1])**2 + (p2[2]-p1[2])**2)
- elif len(p1) == 2:
- return math.sqrt((p2[0]-p1[0])**2 + (p2[1]-p1[1])**2)
- return False
- # fmt: on
-
- @staticmethod
- @pyedb_function_handler()
- def find_point_on_plane(pointlists, direction=0):
- """Find a point on a plane.
-
- Parameters
- ----------
- pointlists : List
- List of points.
- direction : int, optional
- The default is ``0``.
-
- Returns
- -------
- List
-
- """
- if direction <= 2:
- point = 1e6
- for p in pointlists:
- if p[direction] < point:
- point = p[direction]
- else:
- point = -1e6
- for p in pointlists:
- if p[direction - 3] > point:
- point = p[direction - 3]
- return point
-
- @staticmethod
- @pyedb_function_handler()
- def distance_vector(p, a, b):
- """Evaluate the vector distance between point ``p`` and a line defined by two points, ``a`` and ``b``.
-
- .. note::
- he formula is ``d = (a-p)-((a-p)dot p)n``, where ``a`` is a point of the line (either ``a`` or ``b``)
- and ``n`` is the unit vector in the direction of the line.
-
- Parameters
- ----------
- p : List
- List of ``[x, y, z]`` coordinates for the reference point.
- a : List
- List of ``[x, y, z]`` coordinates for the first point of the segment.
- b : List
- List of ``[x, y, z]`` coordinates for the second point of the segment.
-
- Returns
- -------
- List
- List of ``[x, y, z]`` coordinates for the distance vector.
-
- """
- v1 = GeometryOperators.v_points(a, b)
- n = [i / GeometryOperators.v_norm(v1) for i in v1]
- v2 = GeometryOperators.v_sub(a, p)
- s1 = GeometryOperators._v_dot(v2, n)
- v3 = [i * s1 for i in n]
- vd = GeometryOperators.v_sub(v2, v3)
- return vd
-
- @staticmethod
- @pyedb_function_handler()
- def is_between_points(p, a, b, tol=1e-6):
- """Check if a point lies on the segment defined by two points.
-
- Parameters
- ----------
- p : List
- List of ``[x, y, z]`` coordinates for the reference point ``p``.
- a : List
- List of ``[x, y, z]`` coordinates for the first point of the segment.
- b : List
- List of ``[x, y, z]`` coordinates for the second point of the segment.
- tol : float
- Linear tolerance. The default value is ``1e-6``.
-
- Returns
- -------
- bool
- ``True`` when the point lies on the segment defined by the two points, ``False`` otherwise.
-
- """
- v1 = GeometryOperators.v_points(a, b)
- v2 = GeometryOperators.v_points(a, p)
- if abs(GeometryOperators.v_norm(GeometryOperators.v_cross(v1, v2))) > tol:
- return False # not collinear
- t1 = GeometryOperators._v_dot(v1, v2)
- t2 = GeometryOperators._v_dot(v1, v1)
- if t1 < 0 or t1 > t2:
- return False
- else:
- return True
-
- @staticmethod
- @pyedb_function_handler()
- def is_parallel(a1, a2, b1, b2, tol=1e-6):
- """Check if a segment defined by two points is parallel to a segment defined by two other points.
-
- Parameters
- ----------
- a1 : List
- List of ``[x, y, z]`` coordinates for the first point of the fiirst segment.
- a2 : List
- List of ``[x, y, z]`` coordinates for the second point of the first segment.
- b1 : List
- List of ``[x, y, z]`` coordinates for the first point of the second segment.
- b2 : List
- List of ``[x, y, z]`` coordinates for the second point of the second segment.
- tol : float
- Linear tolerance. The default value is ``1e-6``.
-
- Returns
- -------
- bool
- ``True`` when successful, ``False`` when failed.
-
- """
- if 1.0 - GeometryOperators.parallel_coeff(a1, a2, b1, b2) < tol * tol:
- return True
- else:
- return False
-
- @staticmethod
- @pyedb_function_handler()
- def parallel_coeff(a1, a2, b1, b2):
- """ADD DESCRIPTION.
-
- Parameters
- ----------
- a1 : List
- List of ``[x, y, z]`` coordinates for the first point of the first segment.
- a2 : List
- List of ``[x, y, z]`` coordinates for the second point of the first segment.
- b1 : List
- List of ``[x, y, z]`` coordinates for the first point of the second segment.
- b2 : List
- List of ``[x, y, z]`` coordinates for the second point of the second segment.
-
- Returns
- -------
- float
- _vdot of 4 vertices of 2 segments.
- """
- va = GeometryOperators.v_points(a1, a2)
- vb = GeometryOperators.v_points(b1, b2)
- an = GeometryOperators.v_norm(va)
- bn = GeometryOperators.v_norm(vb)
- var = GeometryOperators._v_dot(va, vb) / (an * bn)
- return abs(var)
-
- @staticmethod
- @pyedb_function_handler()
- def is_collinear(a, b, tol=1e-6):
- """Check if two vectors are collinear (parallel or anti-parallel).
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the first vector.
- b : List
- List of ``[x, y, z]`` coordinates for the second vector.
- tol : float
- Linear tolerance. The default value is ``1e-6``.
-
- Returns
- -------
- bool
- ``True`` if vectors are collinear, ``False`` otherwise.
-
- """
- an = GeometryOperators.v_norm(a)
- bn = GeometryOperators.v_norm(b)
- var = GeometryOperators._v_dot(a, b) / (an * bn)
- if 1.0 - abs(var) < tol * tol:
- return True
- else:
- return False
-
- @staticmethod
- @pyedb_function_handler()
- def is_projection_inside(a1, a2, b1, b2):
- """Project a segment onto another segment and check if the projected segment is inside it.
-
- Parameters
- ----------
- a1 : List
- List of ``[x, y, z]`` coordinates for the first point of the projected segment.
- a2 : List
- List of ``[x, y, z]`` coordinates for the second point of the projected segment.
- b1 : List
- List of ``[x, y, z]`` coordinates for the first point of the other segment.
- b2 : List
- List of ``[x, y, z]`` coordinates for the second point of the other segment.
-
- Returns
- -------
- bool
- ``True`` when the projected segment is inside the other segmennt, ``False`` otherwise.
-
- """
- if not GeometryOperators.is_parallel(a1, a2, b1, b2):
- return False
- d = GeometryOperators.distance_vector(a1, b1, b2)
- a1n = GeometryOperators.v_sum(a1, d)
- a2n = GeometryOperators.v_sum(a2, d)
- if not GeometryOperators.is_between_points(a1n, b1, b2):
- return False
- if not GeometryOperators.is_between_points(a2n, b1, b2):
- return False
- return True
-
- @staticmethod
- @pyedb_function_handler()
- def arrays_positions_sum(vertlist1, vertlist2):
- """Return the sum of two vertices lists.
-
- Parameters
- ----------
- vertlist1 : List
-
- vertlist2 : List
-
- Returns
- -------
- float
-
- """
- s = 0
- for el in vertlist1:
- for el1 in vertlist2:
- s += GeometryOperators.points_distance(el, el1)
- return s / (len(vertlist1) + len(vertlist2))
-
- @staticmethod
- @pyedb_function_handler()
- def v_angle(a, b):
- """Evaluate the angle between two geometry vectors.
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the first vector.
- b : List
- List of ``[x, y, z]`` coordinates for the second vector.
-
- Returns
- -------
- float
- Angle in radians.
-
- """
- d = GeometryOperators.v_dot(a, b)
- an = GeometryOperators.v_norm(a)
- bn = GeometryOperators.v_norm(b)
- if (an * bn) == 0.0:
- return 0.0
- else:
- return math.acos(d / (an * bn))
-
- @staticmethod
- @pyedb_function_handler()
- def pointing_to_axis(x_pointing, y_pointing):
- """Retrieve the axes from the HFSS X axis and Y pointing axis as per
- the definition of the AEDT interface coordinate system.
-
- Parameters
- ----------
- x_pointing : List
- List of ``[x, y, z]`` coordinates for the X axis.
-
- y_pointing : List
- List of ``[x, y, z]`` coordinates for the Y pointing axis.
-
- Returns
- -------
- tuple
- ``[Xx, Xy, Xz], [Yx, Yy, Yz], [Zx, Zy, Zz]`` of the three axes (normalized).
- """
- zpt = GeometryOperators.v_cross(x_pointing, y_pointing)
- ypt = GeometryOperators.v_cross(zpt, x_pointing)
-
- xp = GeometryOperators.normalize_vector(x_pointing)
- zp = GeometryOperators.normalize_vector(zpt)
- yp = GeometryOperators.normalize_vector(ypt)
-
- return xp, yp, zp
-
- @staticmethod
- @pyedb_function_handler()
- def axis_to_euler_zxz(x, y, z):
- """Retrieve Euler angles of a frame following the rotation sequence ZXZ.
-
- Provides assumption for the gimbal lock problem.
-
- Parameters
- ----------
- x : List
- List of ``[Xx, Xy, Xz]`` coordinates for the X axis.
- y : List
- List of ``[Yx, Yy, Yz]`` coordinates for the Y axis.
- z : List
- List of ``[Zx, Zy, Zz]`` coordinates for the Z axis.
-
- Returns
- -------
- tuple
- (phi, theta, psi) containing the Euler angles in radians.
-
- """
- tol = 1e-16
- x1 = x[0]
- x2 = x[1]
- x3 = x[2]
- y3 = y[2]
- z1 = z[0]
- z2 = z[1]
- z3 = z[2]
- if GeometryOperators.v_norm(GeometryOperators.v_sub(z, [0, 0, 1])) < tol:
- phi = GeometryOperators.atan2(x2, x1)
- theta = 0.0
- psi = 0.0
- elif GeometryOperators.v_norm(GeometryOperators.v_sub(z, [0, 0, -1])) < tol:
- phi = GeometryOperators.atan2(x2, x1)
- theta = math.pi
- psi = 0.0
- else:
- phi = GeometryOperators.atan2(z1, -z2)
- theta = math.acos(z3)
- psi = GeometryOperators.atan2(x3, y3)
- return phi, theta, psi
-
- @staticmethod
- @pyedb_function_handler()
- def axis_to_euler_zyz(x, y, z):
- """Retrieve Euler angles of a frame following the rotation sequence ZYZ.
-
- Provides assumption for the gimbal lock problem.
-
- Parameters
- ----------
- x : List
- List of ``[Xx, Xy, Xz]`` coordinates for the X axis.
- y : List
- List of ``[Yx, Yy, Yz]`` coordinates for the Y axis.
- z : List
- List of ``[Zx, Zy, Zz]`` coordinates for the Z axis.
-
- Returns
- -------
- tuple
- (phi, theta, psi) containing the Euler angles in radians.
-
- """
- tol = 1e-16
- x1 = x[0]
- x2 = x[1]
- x3 = x[2]
- y3 = y[2]
- z1 = z[0]
- z2 = z[1]
- z3 = z[2]
- if GeometryOperators.v_norm(GeometryOperators.v_sub(z, [0, 0, 1])) < tol:
- phi = GeometryOperators.atan2(-x1, x2)
- theta = 0.0
- psi = math.pi / 2
- elif GeometryOperators.v_norm(GeometryOperators.v_sub(z, [0, 0, -1])) < tol:
- phi = GeometryOperators.atan2(-x1, x2)
- theta = math.pi
- psi = math.pi / 2
- else:
- phi = GeometryOperators.atan2(z2, z1)
- theta = math.acos(z3)
- psi = GeometryOperators.atan2(y3, -x3)
- return phi, theta, psi
-
- @staticmethod
- @pyedb_function_handler()
- def quaternion_to_axis(q):
- """Convert a quaternion to a rotated frame defined by X, Y, and Z axes.
-
- Parameters
- ----------
- q : List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- Returns
- -------
- tuple
- [Xx, Xy, Xz], [Yx, Yy, Yz], [Zx, Zy, Zz] of the three axes (normalized).
-
- """
- q1 = q[0]
- q2 = q[1]
- q3 = q[2]
- q4 = q[3]
-
- m11 = q1 * q1 + q2 * q2 - q3 * q3 - q4 * q4
- m12 = 2.0 * (q2 * q3 - q1 * q4)
- m13 = 2.0 * (q2 * q4 + q1 * q3)
-
- m21 = 2.0 * (q2 * q3 + q1 * q4)
- m22 = q1 * q1 - q2 * q2 + q3 * q3 - q4 * q4
- m23 = 2.0 * (q3 * q4 - q1 * q2)
-
- m31 = 2.0 * (q2 * q4 - q1 * q3)
- m32 = 2.0 * (q3 * q4 + q1 * q2)
- m33 = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4
-
- x = GeometryOperators.normalize_vector([m11, m21, m31])
- y = GeometryOperators.normalize_vector([m12, m22, m32])
- z = GeometryOperators.normalize_vector([m13, m23, m33])
-
- return x, y, z
-
- @staticmethod
- @pyedb_function_handler()
- def quaternion_to_axis_angle(q):
- """Convert a quaternion to the axis angle rotation formulation.
-
- Parameters
- ----------
- q : List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- Returns
- -------
- tuple
- ([ux, uy, uz], theta) containing the rotation axes expressed as X, Y, Z components of
- the unit vector ``u`` and the rotation angle theta expressed in radians.
-
- """
- q1 = q[0]
- q2 = q[1]
- q3 = q[2]
- q4 = q[3]
- n = (q2 * q2 + q3 * q3 + q4 * q4) ** 0.5
- u = [q2 / n, q3 / n, q4 / n]
- theta = 2.0 * GeometryOperators.atan2(n, q1)
- return u, theta
-
- @staticmethod
- @pyedb_function_handler()
- def axis_angle_to_quaternion(u, theta):
- """Convert the axis angle rotation formulation to a quaternion.
-
- Parameters
- ----------
- u : List
- List of ``[ux, uy, uz]`` coordinates for the rotation axis.
-
- theta : float
- Angle of rotation in radians.
-
- Returns
- -------
- List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- """
- un = GeometryOperators.normalize_vector(u)
- s = math.sin(theta * 0.5)
- q1 = math.cos(theta * 0.5)
- q2 = un[0] * s
- q3 = un[1] * s
- q4 = un[2] * s
- return [q1, q2, q3, q4]
-
- @staticmethod
- @pyedb_function_handler()
- def quaternion_to_euler_zxz(q):
- """Convert a quaternion to Euler angles following rotation sequence ZXZ.
-
- Parameters
- ----------
- q : List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- Returns
- -------
- tuple
- (phi, theta, psi) containing the Euler angles in radians.
-
- """
- q1 = q[0]
- q2 = q[1]
- q3 = q[2]
- q4 = q[3]
- m13 = 2.0 * (q2 * q4 + q1 * q3)
- m23 = 2.0 * (q3 * q4 - q1 * q2)
- m33 = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4
- m31 = 2.0 * (q2 * q4 - q1 * q3)
- m32 = 2.0 * (q3 * q4 + q1 * q2)
- phi = GeometryOperators.atan2(m13, -m23)
- theta = GeometryOperators.atan2((1.0 - m33 * m33) ** 0.5, m33)
- psi = GeometryOperators.atan2(m31, m32)
- return phi, theta, psi
-
- @staticmethod
- @pyedb_function_handler()
- def euler_zxz_to_quaternion(phi, theta, psi):
- """Convert the Euler angles following rotation sequence ZXZ to a quaternion.
-
- Parameters
- ----------
- phi : float
- Euler angle psi in radians.
- theta : float
- Euler angle theta in radians.
- psi : float
- Euler angle phi in radians.
-
- Returns
- -------
- List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- """
- t1 = phi
- t2 = theta
- t3 = psi
- c = math.cos(t2 * 0.5)
- s = math.sin(t2 * 0.5)
- q1 = c * math.cos((t1 + t3) * 0.5)
- q2 = s * math.cos((t1 - t3) * 0.5)
- q3 = s * math.sin((t1 - t3) * 0.5)
- q4 = c * math.sin((t1 + t3) * 0.5)
- return [q1, q2, q3, q4]
-
- @staticmethod
- @pyedb_function_handler()
- def quaternion_to_euler_zyz(q):
- """Convert a quaternion to Euler angles following rotation sequence ZYZ.
-
- Parameters
- ----------
- q : List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- Returns
- -------
- tuple
- (phi, theta, psi) containing the Euler angles in radians.
-
- """
- q1 = q[0]
- q2 = q[1]
- q3 = q[2]
- q4 = q[3]
- m13 = 2.0 * (q2 * q4 + q1 * q3)
- m23 = 2.0 * (q3 * q4 - q1 * q2)
- m33 = q1 * q1 - q2 * q2 - q3 * q3 + q4 * q4
- m31 = 2.0 * (q2 * q4 - q1 * q3)
- m32 = 2.0 * (q3 * q4 + q1 * q2)
- phi = GeometryOperators.atan2(m23, m13)
- theta = GeometryOperators.atan2((1.0 - m33 * m33) ** 0.5, m33)
- psi = GeometryOperators.atan2(m32, -m31)
- return phi, theta, psi
-
- @staticmethod
- @pyedb_function_handler()
- def euler_zyz_to_quaternion(phi, theta, psi):
- """Convert the Euler angles following rotation sequence ZYZ to a quaternion.
-
- Parameters
- ----------
- phi : float
- Euler angle psi in radians.
- theta : float
- Euler angle theta in radians.
- psi : float
- Euler angle phi in radians.
-
- Returns
- -------
- List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- """
- t1 = phi
- t2 = theta
- t3 = psi
- c = math.cos(t2 * 0.5)
- s = math.sin(t2 * 0.5)
- q1 = c * math.cos((t1 + t3) * 0.5)
- q2 = -s * math.sin((t1 - t3) * 0.5)
- q3 = s * math.cos((t1 - t3) * 0.5)
- q4 = c * math.sin((t1 + t3) * 0.5)
- return [q1, q2, q3, q4]
-
- @staticmethod
- @pyedb_function_handler()
- def deg2rad(angle):
- """Convert the angle from degrees to radians.
-
- Parameters
- ----------
- angle : float
- Angle in degrees.
-
- Returns
- -------
- float
- Angle in radians.
-
- """
- pi = math.pi
- return angle / 180.0 * pi
-
- @staticmethod
- @pyedb_function_handler()
- def rad2deg(angle):
- """Convert the angle from radians to degrees.
-
- Parameters
- ----------
- angle : float
- Angle in radians.
-
- Returns
- -------
- float
- Angle in degrees.
-
- """
- pi = math.pi
- return angle * 180.0 / pi
-
- @staticmethod
- @pyedb_function_handler()
- def atan2(y, x):
- """Implementation of atan2 that does not suffer from the following issues:
- math.atan2(0.0, 0.0) = 0.0
- math.atan2(-0.0, 0.0) = -0.0
- math.atan2(0.0, -0.0) = 3.141592653589793
- math.atan2(-0.0, -0.0) = -3.141592653589793
- and returns always 0.0.
-
- Parameters
- ----------
- y : float
- Y-axis value for atan2.
-
- x : float
- X-axis value for atan2.
-
- Returns
- -------
- float
-
- """
- eps = 7.0 / 3.0 - 4.0 / 3.0 - 1.0
- if abs(y) < eps:
- y = 0.0
- if abs(x) < eps:
- x = 0.0
- return math.atan2(y, x)
-
- @staticmethod
- @pyedb_function_handler()
- def q_prod(p, q):
- """Evaluate the product of two quaternions, ``p`` and ``q``, defined as:
- p = p0 + p' = p0 + ip1 + jp2 + kp3.
- q = q0 + q' = q0 + iq1 + jq2 + kq3.
- r = pq = p0q0 - p' • q' + p0q' + q0p' + p' x q'.
-
- Parameters
- ----------
- p : List
- List of ``[p1, p2, p3, p4]`` coordinates for quaternion ``p``.
-
- q : List
- List of ``[p1, p2, p3, p4]`` coordinates for quaternion ``q``.
-
- Returns
- -------
- List
- List of [r1, r2, r3, r4] coordinates for the result quaternion.
-
- """
- p0 = p[0]
- pv = p[1:4]
- q0 = q[0]
- qv = q[1:4]
-
- r0 = p0 * q0 - GeometryOperators.v_dot(pv, qv)
-
- t1 = GeometryOperators.v_prod(p0, qv)
- t2 = GeometryOperators.v_prod(q0, pv)
- t3 = GeometryOperators.v_cross(pv, qv)
- rv = GeometryOperators.v_sum(t1, GeometryOperators.v_sum(t2, t3))
-
- return [r0, rv[0], rv[1], rv[2]]
-
- @staticmethod
- @pyedb_function_handler()
- def q_rotation(v, q):
- """Evaluate the rotation of a vector, defined by a quaternion.
- Evaluated as:
- ``"q = q0 + q' = q0 + iq1 + jq2 + kq3"``,
- ``"w = qvq* = (q0^2 - |q'|^2)v + 2(q' • v)q' + 2q0(q' x v)"``.
-
- Parameters
- ----------
- v : List
- List of ``[v1, v2, v3]`` coordinates for the vector.
- q : List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- Returns
- -------
- List
- List of ``[w1, w2, w3]`` coordinates for the result vector ``w``.
- """
- q0 = q[0]
- qv = q[1:4]
-
- c1 = q0 * q0 - (qv[0] * qv[0] + qv[1] * qv[1] + qv[2] * qv[2])
- t1 = GeometryOperators.v_prod(c1, v)
-
- c2 = 2.0 * GeometryOperators.v_dot(qv, v)
- t2 = GeometryOperators.v_prod(c2, qv)
-
- t3 = GeometryOperators.v_cross(qv, v)
- t4 = GeometryOperators.v_prod(2.0 * q0, t3)
-
- w = GeometryOperators.v_sum(t1, GeometryOperators.v_sum(t2, t4))
-
- return w
-
- @staticmethod
- @pyedb_function_handler()
- def q_rotation_inv(v, q):
- """Evaluate the inverse rotation of a vector that is defined by a quaternion.
-
- It can also be the rotation of the coordinate frame with respect to the vector.
-
- q = q0 + q' = q0 + iq1 + jq2 + kq3
- q* = q0 - q' = q0 - iq1 - jq2 - kq3
- w = q*vq
-
- Parameters
- ----------
- v : List
- List of ``[v1, v2, v3]`` coordinates for the vector.
-
- q : List
- List of ``[q1, q2, q3, q4]`` coordinates for the quaternion.
-
- Returns
- -------
- List
- List of ``[w1, w2, w3]`` coordinates for the vector.
-
- """
- q1 = [q[0], -q[1], -q[2], -q[3]]
- return GeometryOperators.q_rotation(v, q1)
-
- @staticmethod
- @pyedb_function_handler()
- def get_polygon_centroid(pts):
- """Evaluate the centroid of a polygon defined by its points.
-
- Parameters
- ----------
- pts : List
- List of points, with each point defined by its ``[x,y,z]`` coordinates.
-
- Returns
- -------
- List
- List of [x,y,z] coordinates for the centroid of the polygon.
-
- """
- if len(pts) == 0: # pragma: no cover
- raise ValueError("pts must contain at list one point")
- sx = sy = sz = sl = sl2 = 0
- x1, y1, z1 = pts[0]
- for i in range(len(pts)): # counts from 0 to len(points)-1
- x0, y0, z0 = pts[i - 1] # in Python points[-1] is last element of points
- x1, y1, z1 = pts[i]
- L = ((x1 - x0) ** 2 + (y1 - y0) ** 2) ** 0.5
- sx += (x0 + x1) / 2 * L
- sy += (y0 + y1) / 2 * L
- L2 = ((z1 - z0) ** 2 + (x1 - x0) ** 2) ** 0.5
- sz += (z0 + z1) / 2 * L2
- sl += L
- sl2 += L2
- xc = sx / sl if sl != 0.0 else x1
- yc = sy / sl if sl != 0.0 else y1
- zc = sz / sl2 if sl2 != 0.0 else z1
-
- return [xc, yc, zc]
-
- @staticmethod
- @pyedb_function_handler()
- def cs_xy_pointing_expression(yaw, pitch, roll):
- """Return x_pointing and y_pointing vectors as expressions from
- the yaw, ptich, and roll input (as strings).
-
- Parameters
- ----------
- yaw : str, required
- String expression for the yaw angle (rotation about Z-axis)
- pitch : str
- String expression for the pitch angle (rotation about Y-axis)
- roll : str
- String expression for the roll angle (rotation about X-axis)
-
- Returns
- -------
- [x_pointing, y_pointing] vector expressions.
- """
- # X-Pointing
- xx = "cos(" + yaw + ")*cos(" + pitch + ")"
- xy = "sin(" + yaw + ")*cos(" + pitch + ")"
- xz = "sin(" + pitch + ")"
-
- # Y-Pointing
- yx = "sin(" + roll + ")*sin(" + pitch + ")*cos(" + yaw + ") - "
- yx += "sin(" + yaw + ")*cos(" + roll + ")"
-
- yy = "sin(" + roll + ")*sin(" + yaw + ")*sin(" + pitch + ") + "
- yy += "cos(" + roll + ")*cos(" + yaw + ")"
-
- yz = "sin(" + roll + " + pi)*cos(" + pitch + ")" # use pi to avoid negative sign.
-
- # x, y pointing vectors for CS
- x_pointing = [xx, xy, xz]
- y_pointing = [yx, yy, yz]
-
- return [x_pointing, y_pointing]
-
- @staticmethod
- @pyedb_function_handler()
- def get_numeric(s):
- """Convert a string to a numeric value. Discard the suffix."""
- if type(s) == str:
- if s == "Global":
- return 0.0
- else:
- return float("".join(c for c in s if c.isdigit() or c == "."))
- elif s is None:
- return 0.0
- else:
- return float(s)
-
- @staticmethod
- @pyedb_function_handler()
- def is_small(s):
- """Return ``True`` if the number represented by s is zero (i.e very small).
-
- Parameters
- ----------
- s : numeric or str
- Variable value.
-
- Returns
- -------
- bool
-
- """
- n = GeometryOperators.get_numeric(s)
- return True if math.fabs(n) < 2.0 * abs(sys.float_info.epsilon) else False
-
- @staticmethod
- @pyedb_function_handler()
- def numeric_cs(cs_in):
- """Return a list of [x,y,z] numeric values given a coordinate system as input.
-
- Parameters
- ----------
- cs_in : List of str or str
- ``["x", "y", "z"]`` or "Global".
- """
- if type(cs_in) is str:
- if cs_in == "Global":
- return [0.0, 0.0, 0.0]
- else:
- return None
- elif type(cs_in) is list:
- if len(cs_in) == 3:
- return [GeometryOperators.get_numeric(s) if type(s) is str else s for s in cs_in]
- else:
- return [0, 0, 0]
-
- @staticmethod
- @pyedb_function_handler()
- def orient_polygon(x, y, clockwise=True):
- """
- Orient a polygon clockwise or counterclockwise. The vertices should be already ordered either way.
- Use this function to change the orientation.
- The polygon is represented by its vertices coordinates.
-
-
- Parameters
- ----------
- x : List
- List of x coordinates of the vertices. Length must be >= 1.
- Degenerate polygon with only 2 points is also accepted, in this case the points are returned unchanged.
- y : List
- List of y coordinates of the vertices. Must be of the same length as x.
- clockwise : bool
- If ``True`` the polygon is oriented clockwise, if ``False`` it is oriented counterclockwise.
- Default is ``True``.
-
- Returns
- -------
- List of List
- Lists of oriented vertices.
- """
- x_ret = x[:]
- y_ret = y[:]
- if len(x) < 2: # pragma: no cover
- raise ValueError("'x' length must be >= 2")
- if len(y) != len(x): # pragma: no cover
- raise ValueError("'y' must be same length as 'x'")
- if len(x) == 2:
- return x_ret, y_ret
- # fmt: off
- # select a vertex on the hull
- xmin = min(x)
- ixmin = [i for i, el in enumerate(x) if xmin == el]
- if len(ixmin) == 1:
- imin = ixmin[0]
- else: # searching for the minimum y
- tmpy = [(i, el) for i, el in enumerate(y) if i in ixmin]
- min_tmpy = min(tmpy, key=lambda t: t[1])
- imin = min_tmpy[0]
- ymin = y[imin]
- if imin == 0: # the minimum is the first point of the polygon
- xa = x[-1]
- ya = y[-1]
- xb = xmin
- yb = ymin
- xc = x[1]
- yc = y[1]
- elif imin == len(x)-1: # the minimum is the last point of the polygon
- xa = x[imin-1]
- ya = y[imin-1]
- xb = xmin
- yb = ymin
- xc = x[0]
- yc = y[0]
- else:
- xa = x[imin-1]
- ya = y[imin-1]
- xb = xmin
- yb = ymin
- xc = x[imin+1]
- yc = y[imin+1]
- det = (xb-xa) * (yc-ya) - (xc-xa) * (yb-ya)
- if det > 0: # counterclockwise
- is_CW = False
- else: # clockwise
- is_CW = True
- # fmt: on
- if (clockwise and not is_CW) or (not clockwise and is_CW):
- x_ret.reverse()
- y_ret.reverse()
- return x_ret, y_ret
-
- @staticmethod
- @pyedb_function_handler()
- def v_angle_sign(va, vb, vn, right_handed=True):
- """Evaluate the signed angle between two geometry vectors.
- The sign is evaluated respect to the normal to the plane containing the two vectors as per the following rule.
- In case of opposite vectors, it returns an angle equal to 180deg (always positive).
- Assuming that the plane normal is normalized (vb == 1), the signed angle is simplified.
- For the right-handed rotation from Va to Vb:
- - atan2((va x Vb) . vn, va . vb).
- For the left-handed rotation from Va to Vb:
- - atan2((Vb x va) . vn, va . vb).
-
- Parameters
- ----------
- va : List
- List of ``[x, y, z]`` coordinates for the first vector.
- vb : List
- List of ``[x, y, z]`` coordinates for the second vector.
- vn : List
- List of ``[x, y, z]`` coordinates for the plane normal.
- right_handed : bool
- Whether to consider the right-handed rotation from va to vb. The default is ``True``.
- When ``False``, left-hand rotation from va to vb is considered.
-
- Returns
- -------
- float
- Angle in radians.
-
- """
- tol = 1e-12
- cross = GeometryOperators.v_cross(va, vb)
- if GeometryOperators.v_norm(cross) < tol:
- return math.pi
- assert GeometryOperators.is_collinear(cross, vn), (
- "vn must be the normal to the " "plane containing va and vb."
- ) # pragma: no cover
-
- vnn = GeometryOperators.normalize_vector(vn)
- if right_handed:
- return math.atan2(GeometryOperators.v_dot(cross, vnn), GeometryOperators.v_dot(va, vb))
- else:
- mcross = GeometryOperators.v_cross(vb, va)
- return math.atan2(GeometryOperators.v_dot(mcross, vnn), GeometryOperators.v_dot(va, vb))
-
- @staticmethod
- @pyedb_function_handler()
- def v_angle_sign_2D(va, vb, right_handed=True):
- """Evaluate the signed angle between two 2D geometry vectors.
- Iit the 2D version of the ``GeometryOperators.v_angle_sign`` considering vn = [0,0,1].
- In case of opposite vectors, it returns an angle equal to 180deg (always positive).
-
- Parameters
- ----------
- va : List
- List of ``[x, y]`` coordinates for the first vector.
- vb : List
- List of ``[x, y]`` coordinates for the second vector.
- right_handed : bool
- Whether to consider the right-handed rotation from Va to Vb. The default is ``True``.
- When ``False``, left-hand rotation from Va to Vb is considered.
-
- Returns
- -------
- float
- Angle in radians.
-
- """
- c = va[0] * vb[1] - va[1] * vb[0]
-
- if right_handed:
- return math.atan2(c, GeometryOperators.v_dot(va, vb))
- else:
- return math.atan2(-c, GeometryOperators.v_dot(va, vb))
-
- @staticmethod
- @pyedb_function_handler()
- def point_in_polygon(point, polygon, tolerance=1e-8):
- """Determine if a point is inside, outside the polygon or at exactly at the border.
-
- The method implements the radial algorithm (https://es.wikipedia.org/wiki/Algoritmo_radial)
-
- point : List
- List of ``[x, y]`` coordinates.
- polygon : List
- [[x1, x2, ..., xn],[y1, y2, ..., yn]]
- tolerance : float
- tolerance used for the algorithm. Default value is 1e-8.
-
- Returns
- -------
- int
- - ``-1`` When the point is outside the polygon.
- - ``0`` When the point is exactly on one of the sides of the polygon.
- - ``1`` When the point is inside the polygon.
- """
- # fmt: off
- tol = tolerance
- if len(point) != 2: # pragma: no cover
- raise ValueError("Point must be a list in the form [x, y].")
- pl = len(polygon[0])
- if len(polygon[1]) != pl: # pragma: no cover
- raise ValueError("Polygon x and y lists must be the same length")
- asum = 0
- for i in range(pl):
- vj = [polygon[0][i-1], polygon[1][i-1]]
- vi = [polygon[0][i], polygon[1][i]]
- if GeometryOperators.points_distance(point, vi) < tol:
- return 0 # point is one of polyline vertices
- vpj = GeometryOperators.v_points(point, vj)
- vpi = GeometryOperators.v_points(point, vi)
- a = GeometryOperators.v_angle_sign_2D(vpj, vpi)
- if abs(abs(a) - math.pi) < tol:
- return 0
- asum += a
- if abs(asum) < tol:
- return -1
- elif abs(abs(asum) - 2*math.pi) < tol:
- return 1
- else: # pragma: no cover
- raise Exception("Unexpected error!")
- # fmt: on
-
- @staticmethod
- @pyedb_function_handler()
- def is_point_in_polygon(point, polygon):
- """Determine if a point is inside or outside a polygon, both located on the same plane.
-
- The method implements the radial algorithm (https://es.wikipedia.org/wiki/Algoritmo_radial)
-
- point : List
- List of ``[x, y]`` coordinates.
- polygon : List
- [[x1, x2, ..., xn],[y1, y2, ..., yn]]
-
- Returns
- -------
- bool
- ``True`` if the point is inside the polygon or exactly on one of its sides.
- ``False`` otherwise.
- """
- r = GeometryOperators.point_in_polygon(point, polygon)
- if r == -1:
- return False
- else:
- return True
-
- @staticmethod
- @pyedb_function_handler()
- def are_segments_intersecting(a1, a2, b1, b2, include_collinear=True):
- """
- Determine if the two segments a and b are intersecting.
-
- a1 : List
- First point of segment a. List of ``[x, y]`` coordinates.
- a2 : List
- Second point of segment a. List of ``[x, y]`` coordinates.
- b1 : List
- First point of segment b. List of ``[x, y]`` coordinates.
- b2 : List
- Second point of segment b. List of ``[x, y]`` coordinates.
- include_collinear : bool
- If ``True`` two segments are considered intersecting also if just one end lies on the other segment.
- Default is ``True``.
-
- Returns
- -------
- bool
- ``True`` if the segments are intersecting.
- ``False`` otherwise.
- """
- # fmt: off
- def on_segment(p, q, r):
- # Given three collinear points p, q, r, the function checks if point q lies on line-segment 'pr'
- if ((q[0] <= max(p[0], r[0])) and (q[0] >= min(p[0], r[0])) and
- (q[1] <= max(p[1], r[1])) and (q[1] >= min(p[1], r[1]))):
- return True
- return False
-
- def orientation(p, q, r):
- # Find the orientation of an ordered triplet (p,q,r) using the slope evaluation.
- # The function returns the following values:
- # 0 : Collinear points
- # 1 : Clockwise points
- # -1 : Counterclockwise
- val = float(q[1]-p[1]) * float(r[0]-q[0]) - float(q[0]-p[0]) * float(r[1]-q[1])
- if val > 0:
- return 1 # Clockwise orientation
- elif val < 0:
- return -1 # Counterclockwise orientation
- else:
- return 0 # Collinear orientation
-
- # MAIN
- # Find the 4 orientations
- o1 = orientation(a1, a2, b1)
- o2 = orientation(a1, a2, b2)
- o3 = orientation(b1, b2, a1)
- o4 = orientation(b1, b2, a2)
-
- # General case
- if (o1 != o2) and (o3 != o4):
- if include_collinear:
- return True
- else:
- # a1 , a2 and b1 are collinear and b1 lies on segment a1a2
- if (o1 == 0) and on_segment(a1, b1, a2):
- return False
- # a1 , a2 and b2 are collinear and b2 lies on segment a1a2
- if (o2 == 0) and on_segment(a1, b2, a2):
- return False
- # b1 , b2 and a1 are collinear and a1 lies on segment b1b2
- if (o3 == 0) and on_segment(b1, a1, b2):
- return False
- # b1 , b2 and a2 are collinear and a2 lies on segment b1b2
- if (o4 == 0) and on_segment(b1, a2, b2):
- return False
- return True
-
- # Special Cases
- # a1 , a2 and b1 are collinear and b1 lies on segment a1a2
- if (o1 == 0) and on_segment(a1, b1, a2):
- return include_collinear
- # a1 , a2 and b2 are collinear and b2 lies on segment a1a2
- if (o2 == 0) and on_segment(a1, b2, a2):
- return include_collinear
- # b1 , b2 and a1 are collinear and a1 lies on segment b1b2
- if (o3 == 0) and on_segment(b1, a1, b2):
- return include_collinear
- # b1 , b2 and a2 are collinear and a2 lies on segment b1b2
- if (o4 == 0) and on_segment(b1, a2, b2):
- return include_collinear
- # If none of the cases
- return False
- # fmt: on
-
- @staticmethod
- @pyedb_function_handler()
- def is_segment_intersecting_polygon(a, b, polygon):
- """
- Determine if a segment defined by two points ``a`` and ``b`` intersects a polygon.
- Points on the vertices and on the polygon boundaries are not considered intersecting.
-
- a : List
- First point of the segment. List of ``[x, y]`` coordinates.
- b : List
- Second point of the segment. List of ``[x, y]`` coordinates.
- polygon : List
- [[x1, x2, ..., xn],[y1, y2, ..., yn]]
-
- Returns
- -------
- float
- ``True`` if the segment intersect the polygon. ``False`` otherwise.
- """
- assert len(a) == 2, "point must be a list in the form [x, y]"
- assert len(b) == 2, "point must be a list in the form [x, y]"
- pl = len(polygon[0])
- assert len(polygon[1]) == pl, "Polygon x and y lists must be the same length"
-
- a_in = GeometryOperators.is_point_in_polygon(a, polygon)
- b_in = GeometryOperators.is_point_in_polygon(b, polygon)
- if a_in != b_in:
- return True # one point is inside and one is outside, no need for further investigation.
- for i in range(pl):
- vj = [polygon[0][i - 1], polygon[1][i - 1]]
- vi = [polygon[0][i], polygon[1][i]]
- if GeometryOperators.are_segments_intersecting(a, b, vi, vj, include_collinear=False):
- return True
- return False
-
- @staticmethod
- @pyedb_function_handler()
- def is_perpendicular(a, b, tol=1e-6):
- """Check if two vectors are perpendicular.
-
- Parameters
- ----------
- a : List
- List of ``[x, y, z]`` coordinates for the first vector.
- b : List
- List of ``[x, y, z]`` coordinates for the second vector.
- tol : float
- Linear tolerance. The default value is ``1e-6``.
-
- Returns
- -------
- bool
- ``True`` if vectors are perpendicular, ``False`` otherwise.
-
- """
- var = GeometryOperators._v_dot(a, b)
- if abs(var) < tol * tol:
- return True
- else:
- return False
-
- @staticmethod
- @pyedb_function_handler()
- def is_point_projection_in_segment(p, a, b):
- """Check if a point projection lies on the segment defined by two points.
-
- Parameters
- ----------
- p : List
- List of ``[x, y, z]`` coordinates for the reference point ``p``.
- a : List
- List of ``[x, y, z]`` coordinates for the first point of the segment.
- b : List
- List of ``[x, y, z]`` coordinates for the second point of the segment.
-
- Returns
- -------
- bool
- ``True`` when the projection point lies on the segment defined by the two points, ``False`` otherwise.
-
- """
- # fmt: off
- dx = b[0]-a[0]
- dy = b[1]-a[1]
- inner_product = (p[0]-a[0])*dx + (p[1]-a[1])*dy
- return 0 <= inner_product <= dx*dx + dy*dy
- # fmt: on
-
- @staticmethod
- @pyedb_function_handler()
- def point_segment_distance(p, a, b):
- """Calculate the distance between a point ``p`` and a segment defined by two points ``a`` and ``b``.
-
- Parameters
- ----------
- p : List
- List of ``[x, y, z]`` coordinates for the reference point ``p``.
- a : List
- List of ``[x, y, z]`` coordinates for the first point of the segment.
- b : List
- List of ``[x, y, z]`` coordinates for the second point of the segment.
-
- Returns
- -------
- float
- Distance between the point and the segment.
- """
- # fmt: off
- den = math.sqrt((b[0] - a[0])**2 + (b[1] - a[1])**2)
- num = (b[0] - a[0])*(a[1] - p[1]) - (a[0] - p[0])*(b[1] - a[1])
- d = abs(num)/den
- return d
- # fmt: on
-
- @staticmethod
- @pyedb_function_handler()
- def find_largest_rectangle_inside_polygon(polygon, partition_max_order=16):
- """Find the largest area rectangles of arbitrary orientation in a polygon.
-
- Implements the algorithm described by Rubén Molano, et al.
- *"Finding the largest area rectangle of arbitrary orientation in a closed contour"*, published in
- *Applied Mathematics and Computation*.
- https://doi.org/10.1016/j.amc.2012.03.063.
- (https://www.sciencedirect.com/science/article/pii/S0096300312003207)
-
- Parameters
- ----------
- polygon : List
- [[x1, x2, ..., xn],[y1, y2, ..., yn]]
- partition_max_order : float, optional
- Order of the lattice partition used to find the quasi-lattice polygon that approximates ``polygon``.
- Default is ``16``.
-
- Returns
- -------
- List of List
- List containing the rectangles points. Return all rectangles found.
- List is in the form: [[[x1, y1],[x2, y2],...],[[x1, y1],[x2, y2],...],...].
- """
-
- # fmt: off
- def evaluate_partition_size(polygon, partition_max_order):
- x, y = polygon
- max_size = max(max(x)-min(x), max(y)-min(y))
- L = max_size/partition_max_order
- return L
-
- def build_s_ploygon_points(vertices, L):
- x, y = vertices
-
- # build the lattice
- xmin = min(x)
- r = int(math.ceil(float(max(x)-xmin)/L))
- ymin = min(y)
- s = int(math.ceil(float(max(y)-ymin)/L))
-
- # get the lattice points S inside the polygon
- Spoints = []
- for i in range(r + 1):
- xi = xmin + L * i
- for j in range(s + 1):
- yj = ymin + L * j
- if GeometryOperators.is_point_in_polygon([xi, yj], [x, y]):
- Spoints.append([xi, yj])
- return Spoints
-
- def build_u_matrix(S, polygon):
- N = len(S)
- # preallocate the matrix
- Umatrix = [[None for j in range(N)] for i in range(N)]
- for i in range(N):
- for j in range(N):
- if i >= j:
- Umatrix[i][j] = 0
- else:
- if GeometryOperators.is_segment_intersecting_polygon(S[i], S[j], polygon):
- Umatrix[i][j] = 0
- else:
- p = GeometryOperators.get_mid_point(S[i], S[j])
- if not GeometryOperators.is_point_in_polygon(p, polygon):
- Umatrix[i][j] = 0
- else:
- Umatrix[i][j] = GeometryOperators.v_points(S[i], S[j])
- return Umatrix
-
- def inside(i, j):
- if U[i][j] == 0 and isinstance(U[i][j], int):
- return False
- else:
- return True
-
- def compute_largest_rectangle(S):
- max_area = 0
- rectangles = []
- N = len(S)
- for i in range(N-3):
- for j in range(i+1, N-2):
- if inside(i, j):
- for k in range(j+1, N-1):
- if inside(i, k) and GeometryOperators.is_perpendicular(U[i][j], U[i][k]):
- ps = GeometryOperators.v_sum(GeometryOperators.v_sub(S[j], S[i]), S[k])
- try:
- s = S.index(ps)
- except ValueError:
- break
- if inside(k, s) and inside(j, s):
- area = GeometryOperators.v_norm(U[i][j]) * GeometryOperators.v_norm(U[i][k])
- if area > max_area:
- max_area = area
- R = [S[i], S[j], S[s], S[k]]
- rectangles = [R]
- elif area == max_area:
- R = [S[i], S[j], S[s], S[k]]
- rectangles.append(R)
- return rectangles
-
- L = evaluate_partition_size(polygon, partition_max_order=partition_max_order)
- S = build_s_ploygon_points(polygon, L)
- U = build_u_matrix(S, polygon)
- R = compute_largest_rectangle(S)
- return R
- # fmt: on
-
- @staticmethod
- @pyedb_function_handler()
- def degrees_over_rounded(angle, digits):
- """Ceil of angle.
-
- Parameters
- ----------
- angle : float
- Angle in radians which will be converted to degrees and will be over-rounded to the next "digits" decimal.
- digits : int
- Integer number which is the number of decimals.
-
- Returns
- -------
- float
-
- """
- return math.ceil(math.degrees(angle) * 10**digits) / (10**digits)
-
- @staticmethod
- @pyedb_function_handler()
- def radians_over_rounded(angle, digits):
- """Radian angle ceiling.
-
- Parameters
- ----------
- angle : float
- Angle in degrees which will be converted to radians and will be over-rounded to the next "digits" decimal.
- digits : int
- Integer number which is the number of decimals.
-
- Returns
- -------
- float
-
- """
- return math.ceil(math.radians(angle) * 10**digits) / (10**digits)
-
- @staticmethod
- @pyedb_function_handler()
- def degrees_default_rounded(angle, digits):
- """Convert angle to degree with given digits rounding.
-
- Parameters
- ----------
- angle : float
- Angle in radians which will be converted to degrees and will be under-rounded to the next "digits" decimal.
- digits : int
- Integer number which is the number of decimals.
-
- Returns
- -------
- float
-
- """
- return math.floor(math.degrees(angle) * 10**digits) / (10**digits)
-
- @staticmethod
- @pyedb_function_handler()
- def radians_default_rounded(angle, digits):
- """Convert to radians with given round.
-
- Parameters
- ----------
- angle : float
- Angle in degrees which will be converted to radians and will be under-rounded to the next "digits" decimal.
- digits : int
- Integer number which is the number of decimals.
-
- Returns
- -------
- float
-
- """
- return math.floor(math.radians(angle) * 10**digits) / (10**digits)
-
- @staticmethod
- @pyedb_function_handler()
- def find_closest_points(points_list, reference_point, tol=1e-6):
- """Given a list of points, finds the closest points to a reference point.
- It returns a list of points because more than one can be found.
- It works with 2D or 3D points. The tolerance used to evaluate the distance
- to the reference point can be specified.
-
- Parameters
- ----------
- points_list : List of List
- List of points. The points can be defined in 2D or 3D space.
- reference_point : List
- The reference point. The point can be defined in 2D or 3D space (same as points_list).
- tol : float, optional
- The tolerance used to evaluate the distance. Default is ``1e-6``.
-
- Returns
- -------
- List of List
-
- """
- # fmt: off
- if not isinstance(points_list, list) or not isinstance(points_list[0], list):
- raise AttributeError("points_list must be a list of points")
- if len(points_list[0]) < 2 or len(points_list[0]) > 3:
- raise AttributeError("points must be defined in either 2D or 3D space.")
- if len(points_list[0]) != len(reference_point):
- raise AttributeError("Points in points_list attribute and reference_point must have the same length.")
- # make copy of the input points
- pl = [i[:] for i in points_list]
- pr = reference_point[:]
- # find the closest points
- dm = 1e12
- close_points = []
- for p in pl:
- d = GeometryOperators.points_distance(p, pr)
- if abs(d-dm) < tol:
- close_points.append(p)
- elif d < dm:
- dm = d
- close_points = [p]
- if close_points:
- return close_points
- else: # pragma: no cover
- return False
- # fmt: on
-
- @staticmethod
- @pyedb_function_handler()
- def mirror_point(start, reference, vector):
- """Mirror point about a plane defining by a point on the plane and a normal point.
-
- Parameters
- ----------
- start : list
- Point to be mirrored
- reference : list
- The reference point. Point on the plane around which you want to mirror the object.
- vector : list
- Normalized vector used for the mirroring.
-
- Returns
- -------
- List
- List of the reflected point.
-
- """
- distance = [start[i] - reference[i] for i in range(3)]
- vector_norm = GeometryOperators.v_norm(vector)
- vector = [vector[i] / vector_norm for i in range(3)]
- dot_product = sum([distance[i] * vector[i] for i in range(3)])
- reflection = [-dot_product * vector[i] * 2 + start[i] for i in range(3)]
- return reflection
diff --git a/src/pyedb/misc/misc.py b/src/pyedb/misc/misc.py
index 8f5f0f7f17..9b582fc865 100644
--- a/src/pyedb/misc/misc.py
+++ b/src/pyedb/misc/misc.py
@@ -1,4 +1,4 @@
-"""Miscellaneous Methods for PyAEDT."""
+"""Miscellaneous Methods for PyEDB."""
import os
import warnings
diff --git a/src/pyedb/modeler/geometry_operators.py b/src/pyedb/modeler/geometry_operators.py
index 981e1936fc..826a069496 100644
--- a/src/pyedb/modeler/geometry_operators.py
+++ b/src/pyedb/modeler/geometry_operators.py
@@ -51,7 +51,7 @@ def parse_dim_arg(string, scale_to_unit=None, variable_manager=None):
String to convert. For example, ``"2mm"``. The default is ``None``.
scale_to_unit : str, optional
Units for the value to convert. For example, ``"mm"``.
- variable_manager : :class:`pyaedt.application.Variables.VariableManager`, optional
+ variable_manager : :class:`pyedb.legacy.application.Variables.VariableManager`, optional
Try to parse formula and returns numeric value.
The default is ``None``.
@@ -64,7 +64,7 @@ def parse_dim_arg(string, scale_to_unit=None, variable_manager=None):
--------
Parse `'"2mm"'`.
- >>> from pyaedt.modeler.geometry_operators import GeometryOperators as go
+ >>> from pyedb.modeler.geometry_operators import GeometryOperators as go
>>> go.parse_dim_arg('2mm')
>>> 0.002
diff --git a/tests/conftest.py b/tests/conftest.py
index da36c2fb7b..05c9b09167 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -17,28 +17,20 @@
# }
# """
-import json
import os
import random
import shutil
import string
-import sys
import tempfile
-import time
import pytest
from pyedb.edb_logger import pyedb_logger
-from pyedb.legacy.generic.filesystem import Scratch
+from pyedb.generic.filesystem import Scratch
from pyedb.generic.general_methods import generate_unique_name
from pyedb.misc.misc import list_installed_ansysem
-from pyedb.grpc.edb import EdbGrpc
-
logger = pyedb_logger
-# import os
-
-
local_path = os.path.dirname(os.path.realpath(__file__))
# Initialize default desktop configuration
@@ -82,24 +74,3 @@ def local_scratch(init_scratch):
scratch = Scratch(tmp_path)
yield scratch
scratch.remove()
-
-
-@pytest.fixture(scope="module")
-def add_edb(local_scratch):
- def _method(project_name=None, subfolder=""):
- if project_name:
- example_folder = os.path.join(local_path, "example_models", subfolder, project_name + ".aedb")
- if os.path.exists(example_folder):
- target_folder = os.path.join(local_scratch.path, project_name + ".aedb")
- local_scratch.copyfolder(example_folder, target_folder)
- else:
- target_folder = os.path.join(local_scratch.path, project_name + ".aedb")
- else:
- target_folder = os.path.join(local_scratch.path, generate_unique_name("TestEdb") + ".aedb")
- return EdbGrpc(
- target_folder,
- edbversion=desktop_version,
- )
-
- return _method
-
diff --git a/tests/grpc/system/conftest.py b/tests/grpc/system/conftest.py
index 41826fbe51..661f97f139 100644
--- a/tests/grpc/system/conftest.py
+++ b/tests/grpc/system/conftest.py
@@ -1,32 +1,52 @@
"""
"""
-import sys
-import os
+import os
+from os.path import dirname
import pytest
-
-# from pyedb import Edb
-# from pyedb.legacy.edb_core.components import resistor_value_parser
-# from pyedb.legacy.edb_core.edb_data.edbvalue import EdbValue
-# from pyedb.legacy.edb_core.edb_data.simulation_configuration import SimulationConfiguration
-# from pyedb.legacy.edb_core.edb_data.sources import Source
-# from pyedb.generic.constants import RadiationBoxType
-# from pyedb.generic.general_methods import check_numeric_equivalence
-
-# from pyedb.generic.constants import SolverType
-# from pyedb.generic.constants import SourceType
-# from tests.conftest import config
from tests.conftest import local_path
-# from tests.conftest import edb_version
+
+from pyedb.generic.general_methods import generate_unique_name
+from pyedb.misc.misc import list_installed_ansysem
+
+example_models_path = os.path.join(
+ dirname(dirname(dirname(os.path.realpath(__file__)))), "example_models")
+
+# Initialize default desktop configuration
+desktop_version = "2023.2"
+if "ANSYSEM_ROOT{}".format(desktop_version[2:].replace(".", "")) not in list_installed_ansysem():
+ desktop_version = list_installed_ansysem()[0][12:].replace(".", "")
+ desktop_version = "20{}.{}".format(desktop_version[:2], desktop_version[-1])
test_subfolder = "TEDB"
test_project_name = "ANSYS-HSD_V1"
bom_example = "bom_example.csv"
+@pytest.fixture(scope="module")
+def add_grpc_edb(local_scratch):
+ from pyedb.grpc.edb import EdbGrpc
+
+ def _method(project_name=None, subfolder=""):
+ if project_name:
+ example_folder = os.path.join(local_path, "example_models", subfolder, project_name + ".aedb")
+ if os.path.exists(example_folder):
+ target_folder = os.path.join(local_scratch.path, project_name + ".aedb")
+ local_scratch.copyfolder(example_folder, target_folder)
+ else:
+ target_folder = os.path.join(local_scratch.path, project_name + ".aedb")
+ else:
+ target_folder = os.path.join(local_scratch.path, generate_unique_name("TestEdb") + ".aedb")
+ return EdbGrpc(
+ target_folder,
+ edbversion=desktop_version,
+ )
+
+ return _method
+
@pytest.fixture(scope="class")
-def edbapp(add_edb):
- app = add_edb(test_project_name, subfolder=test_subfolder)
+def grpc_edb_app(add_grpc_edb):
+ app = add_grpc_edb(test_project_name, subfolder=test_subfolder)
return app
diff --git a/tests/grpc/system/test_edb.py b/tests/grpc/system/test_edb.py
index 25afc7d217..3cda5f3889 100644
--- a/tests/grpc/system/test_edb.py
+++ b/tests/grpc/system/test_edb.py
@@ -6,7 +6,13 @@
#from pyedb.legacy.edb_core.edb_data.simulation_configuration import SimulationConfiguration
import pytest
-from pyedb.grpc.edb import EdbGrpc
+try:
+ from pyedb.grpc.edb import EdbGrpc
+except ImportError:
+ def pytest_collection_modifyitems(items, config):
+ for item in items:
+ item.add_marker(pytest.mark.xfail)
+
from pyedb.generic.constants import RadiationBoxType, SourceType
from pyedb.generic.constants import SolverType
from pyedb.generic.general_methods import is_linux
@@ -19,8 +25,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, grpc_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = grpc_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/grpc/system/test_edb_components.py b/tests/grpc/system/test_edb_components.py
deleted file mode 100644
index fb41eba639..0000000000
--- a/tests/grpc/system/test_edb_components.py
+++ /dev/null
@@ -1,464 +0,0 @@
-"""Tests related to Edb components
-"""
-import os
-import pytest
-import math
-
-# from pyedb import Edb
-from pyedb.legacy.edb import EdbLegacy
-
-from tests.conftest import local_path
-from tests.conftest import desktop_version
-from tests.legacy.system.conftest import test_subfolder
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-bom_example = "bom_example.csv"
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path2 = target_path2
- self.target_path4 = target_path4
-
- def test_components_get_pin_from_component(self):
- """Evaluate access to a pin from a component."""
- comp = self.edbapp.components.get_component_by_name("J1")
- assert comp is not None
- pin = self.edbapp.components.get_pin_from_component("J1", pinName="1")
- assert pin is not False
-
- def test_components_create_coax_port_on_component(self):
- """Create a coaxial port on a component from its pin."""
- coax_port = self.edbapp.components["U6"].pins["R3"].create_coax_port("coax_port")
- coax_port.radial_extent_factor = 3
- assert coax_port.radial_extent_factor == 3
- assert coax_port.component
- assert self.edbapp.components["U6"].pins["R3"].terminal
- assert self.edbapp.components["U6"].pins["R3"].id
- assert self.edbapp.terminals
- assert self.edbapp.ports
- assert self.edbapp.components["U6"].pins["R3"].get_connected_objects()
-
- def test_components_properties(self):
- """Access components properties."""
- assert len(self.edbapp.components.components) > 2
- assert len(self.edbapp.components.inductors) > 0
- assert len(self.edbapp.components.resistors) > 0
- assert len(self.edbapp.components.capacitors) > 0
- assert len(self.edbapp.components.ICs) > 0
- assert len(self.edbapp.components.IOs) > 0
- assert len(self.edbapp.components.Others) > 0
-
- def test_components_rlc_components_values(self):
- """Update values of an RLC component."""
- assert self.edbapp.components.set_component_rlc("C1", res_value=1e-3, cap_value="10e-6", isparallel=False)
- assert self.edbapp.components.set_component_rlc("L10", res_value=1e-3, ind_value="10e-6", isparallel=True)
-
- def test_components_R1_queries(self):
- """Evaluate queries over component R1."""
- assert "R1" in list(self.edbapp.components.components.keys())
- assert not self.edbapp.components.components["R1"].is_null
- assert self.edbapp.components.components["R1"].res_value
- assert self.edbapp.components.components["R1"].placement_layer
- assert isinstance(self.edbapp.components.components["R1"].lower_elevation, float)
- assert isinstance(self.edbapp.components.components["R1"].upper_elevation, float)
- assert self.edbapp.components.components["R1"].top_bottom_association == 2
- assert self.edbapp.components.components["R1"].pinlist
- assert self.edbapp.components.components["R1"].pins
- assert self.edbapp.components.components["R1"].pins["1"].pin_number
- assert self.edbapp.components.components["R1"].pins["1"].component
- assert (
- self.edbapp.components.components["R1"].pins["1"].lower_elevation
- == self.edbapp.components.components["R1"].lower_elevation
- )
- assert (
- self.edbapp.components.components["R1"].pins["1"].placement_layer
- == self.edbapp.components.components["R1"].placement_layer
- )
- assert (
- self.edbapp.components.components["R1"].pins["1"].upper_elevation
- == self.edbapp.components.components["R1"].upper_elevation
- )
- assert (
- self.edbapp.components.components["R1"].pins["1"].top_bottom_association
- == self.edbapp.components.components["R1"].top_bottom_association
- )
- assert self.edbapp.components.components["R1"].pins["1"].position
- assert self.edbapp.components.components["R1"].pins["1"].rotation
-
- def test_components_create_clearance_on_component(self):
- """Evaluate the creation of a clearance on soldermask."""
- comp = self.edbapp.components.components["U1"]
- assert comp.create_clearance_on_component()
-
- def test_components_get_components_from_nets(self):
- """Access to components from nets."""
- assert self.edbapp.components.get_components_from_nets("DDR4_DQS0_P")
-
- def test_components_resistors(self):
- """Evaluate the components resistors."""
- assert "R1" in list(self.edbapp.components.resistors.keys())
- assert "C1" not in list(self.edbapp.components.resistors.keys())
-
- def test_components_capacitors(self):
- """Evaluate the components capacitors."""
- assert "C1" in list(self.edbapp.components.capacitors.keys())
- assert "R1" not in list(self.edbapp.components.capacitors.keys())
-
- def test_components_inductors(self):
- """Evaluate the components inductors."""
- assert "L10" in list(self.edbapp.components.inductors.keys())
- assert "R1" not in list(self.edbapp.components.inductors.keys())
-
- def test_components_integrated_circuits(self):
- """Evaluate the components integrated circuits."""
- assert "U1" in list(self.edbapp.components.ICs.keys())
- assert "R1" not in list(self.edbapp.components.ICs.keys())
-
- def test_components_inputs_outputs(self):
- """Evaluate the components inputs and outputs."""
- assert "X1" in list(self.edbapp.components.IOs.keys())
- assert "R1" not in list(self.edbapp.components.IOs.keys())
-
- def test_components_others(self):
- """Evaluate the components other core components."""
- assert "B1" in self.edbapp.components.Others
- assert "R1" not in self.edbapp.components.Others
-
- def test_components_components_by_partname(self):
- """Evaluate the components by partname"""
- comp = self.edbapp.components.components_by_partname
- assert "ALTR-FBGA24_A-130" in comp
- assert len(comp["ALTR-FBGA24_A-130"]) == 1
-
- def test_components_get_through_resistor_list(self):
- """Evaluate the components retrieve through resistors."""
- assert self.edbapp.components.get_through_resistor_list(10)
-
- def test_components_get_rats(self):
- """Retrieve a list of dictionaries of the reference designator, pin names, and net names."""
- assert len(self.edbapp.components.get_rats()) > 0
-
- def test_components_get_component_net_connections_info(self):
- """Evaluate net connection information."""
- assert len(self.edbapp.components.get_component_net_connection_info("U1")) > 0
-
- def test_components_get_pin_name_and_position(self):
- """Retrieve components name and position."""
- cmp_pinlist = self.edbapp.padstacks.get_pinlist_from_component_and_net("U6", "GND")
- pin_name = self.edbapp.components.get_aedt_pin_name(cmp_pinlist[0])
- assert type(pin_name) is str
- assert len(pin_name) > 0
- assert len(cmp_pinlist[0].position) == 2
- assert len(self.edbapp.components.get_pin_position(cmp_pinlist[0])) == 2
-
- def test_components_get_pins_name_from_net(self):
- """Retrieve pins belonging to a net."""
- cmp_pinlist = self.edbapp.components.get_pin_from_component("U6")
- assert len(self.edbapp.components.get_pins_name_from_net(cmp_pinlist, "GND")) > 0
- assert len(self.edbapp.components.get_pins_name_from_net(cmp_pinlist, "5V")) == 0
-
- def test_components_delete_single_pin_rlc(self):
- """Delete all RLC components with a single pin."""
- assert len(self.edbapp.components.delete_single_pin_rlc()) == 0
-
- def test_components_set_component_rlc(self):
- """Update values for an RLC component."""
- assert self.edbapp.components.set_component_rlc("R1", 30, 1e-9, 1e-12)
-
- def test_components_disable_rlc_component(self):
- """Disable a RLC component."""
- assert self.edbapp.components.disable_rlc_component("R1")
-
- def test_components_delete(self):
- """Delete a component."""
- assert self.edbapp.components.delete("R1")
-
- def test_components_set_model(self):
- """Assign component model."""
- assert self.edbapp.components.set_component_model(
- "C10",
- modelpath=os.path.join(
- local_path,
- "example_models",
- test_subfolder,
- "GRM32ER72A225KA35_25C_0V.sp",
- ),
- modelname="GRM32ER72A225KA35_25C_0V",
- )
- assert not self.edbapp.components.set_component_model(
- "C100000",
- modelpath=os.path.join(
- local_path,
- test_subfolder,
- "GRM32ER72A225KA35_25C_0V.sp",
- ),
- modelname="GRM32ER72A225KA35_25C_0V",
- )
-
- # TODO: Maybe rework this test if #25 is accepted
- def test_modeler_parametrize_layout(self):
- """Parametrize a polygon"""
- assert len(self.edbapp.modeler.polygons) > 0
- for el in self.edbapp.modeler.polygons:
- if el.GetId() == 5953:
- poly = el
- for el in self.edbapp.modeler.polygons:
- if el.GetId() == 5954:
- selection_poly = el
-
- assert self.edbapp.modeler.parametrize_polygon(poly, selection_poly)
-
- def test_components_update_from_bom(self):
- """Update components with values coming from a BOM file."""
- assert self.edbapp.components.update_rlc_from_bom(
- os.path.join(local_path, "example_models", test_subfolder, bom_example),
- delimiter=",",
- valuefield="Value",
- comptype="Prod name",
- refdes="RefDes",
- )
- assert not self.edbapp.components.components["R2"].is_enabled
- self.edbapp.components.components["R2"].is_enabled = True
- assert self.edbapp.components.components["R2"].is_enabled
-
- def test_components_export_bom(self):
- """Export Bom file from layout."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "ANSYS-HSD_V1_bom.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- edbapp.components.import_bom(os.path.join(local_path, "example_models", test_subfolder, "bom_example_2.csv"))
- assert not edbapp.components.instances["R2"].is_enabled
- assert edbapp.components.instances["U13"].partname == "SLAB-QFN-24-2550x2550TP_V"
-
- export_bom_path = os.path.join(self.local_scratch.path, "export_bom.csv")
- assert edbapp.components.export_bom(export_bom_path)
- edbapp.close()
-
- def test_components_create_component_from_pins(self):
- """Create a component from a pin."""
- pins = self.edbapp.components.get_pin_from_component("R13")
- component = self.edbapp.components.create(pins, "newcomp")
- assert component
- assert component.part_name == "newcomp"
- assert len(component.pins) == 2
-
- def test_convert_resistor_value(self):
- """Convert a resistor value."""
- from pyedb.legacy.edb_core.components import resistor_value_parser
- assert resistor_value_parser("100meg")
-
- def test_components_create_solder_ball_on_component(self):
- """Set cylindrical solder balls on a given component"""
- assert self.edbapp.components.set_solder_ball("U1")
-
- def test_components_short_component(self):
- """Short pins of component with a trace."""
- assert self.edbapp.components.short_component_pins("U12", width=0.2e-3)
- assert self.edbapp.components.short_component_pins("U10", ["2", "5"])
-
- def test_components_type(self):
- """Retrieve components type."""
- comp = self.edbapp.components["R4"]
- comp.type = "Resistor"
- assert comp.type == "Resistor"
- comp.type = "Inductor"
- assert comp.type == "Inductor"
- comp.type = "Capacitor"
- assert comp.type == "Capacitor"
- comp.type = "IO"
- assert comp.type == "IO"
- comp.type = "IC"
- assert comp.type == "IC"
- comp.type = "Other"
- assert comp.type == "Other"
-
- def test_componenets_deactivate_rlc(self):
- """Deactivate RLC component and convert to a circuit port."""
- assert self.edbapp.components.deactivate_rlc_component(component="C1", create_circuit_port=True)
- assert self.edbapp.components["C1"].is_enabled is False
- self.edbapp.components["C2"].is_enabled = False
- assert self.edbapp.components["C2"].is_enabled is False
- self.edbapp.components["C2"].is_enabled = True
- assert self.edbapp.components["C2"].is_enabled is True
-
- def test_components_definitions(self):
- """Evaluate components definition."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_0126.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- assert edbapp.components.components
- assert edbapp.components.definitions
- comp_def = edbapp.components.definitions["CAPC2012X12N"]
- assert comp_def
- comp_def.part_name = "CAPC2012X12N_new"
- assert comp_def.part_name == "CAPC2012X12N_new"
- assert len(comp_def.components) > 0
- cap = edbapp.components.definitions["CAPC2012X12N_new"]
- assert cap.type == "Capacitor"
- cap.type = "Resistor"
- assert cap.type == "Resistor"
-
- export_path = os.path.join(self.local_scratch.path, "comp_definition.csv")
- assert edbapp.components.export_definition(export_path)
- assert edbapp.components.import_definition(export_path)
-
- assert edbapp.components.definitions["CAPC3216X180X20ML20"].assign_rlc_model(1, 2, 3)
- sparam_path = os.path.join(local_path, "example_models", test_subfolder, "GRM32_DC0V_25degC_series.s2p")
- assert edbapp.components.definitions["CAPC3216X180X55ML20T25"].assign_s_param_model(sparam_path)
- spice_path = os.path.join(local_path, "example_models", test_subfolder, "GRM32_DC0V_25degC.mod")
- assert edbapp.components.definitions["CAPMP7343X31N"].assign_spice_model(spice_path)
- edbapp.close()
-
- def test_rlc_component_values_getter_setter(self):
- """Evaluate component values getter and setter."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_0136.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- components_to_change = [res for res in list(edbapp.components.Others.values()) if res.partname == "A93549-027"]
- for res in components_to_change:
- res.type = "Resistor"
- res.res_value = [25, 0, 0]
- res.res_value = 10
- assert res.res_value == 10
- res.rlc_values = [20, 1e-9, 1e-12]
- assert res.res_value == 20
- assert res.ind_value == 1e-9
- assert res.cap_value == 1e-12
- res.res_value = 12.5
- assert res.res_value == 12.5 and res.ind_value == 1e-9 and res.cap_value == 1e-12
- res.ind_value = 5e-9
- assert res.res_value == 12.5 and res.ind_value == 5e-9 and res.cap_value == 1e-12
- res.cap_value = 8e-12
- assert res.res_value == 12.5 and res.ind_value == 5e-9 and res.cap_value == 8e-12
- edbapp.close()
-
- def test_create_port_on_pin(self):
- """Create port on pins."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_0134b.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- pin = "A24"
- ref_pins = [pin for pin in list(edbapp.components["U1"].pins.values()) if pin.net_name == "GND"]
- assert edbapp.components.create_port_on_pins(refdes="U1", pins=pin, reference_pins=ref_pins)
- assert edbapp.components.create_port_on_pins(refdes="U1", pins="C1", reference_pins=["A11"])
- assert edbapp.components.create_port_on_pins(refdes="U1", pins="C2", reference_pins=["A11"])
- assert edbapp.components.create_port_on_pins(refdes="U1", pins=["A24"], reference_pins=["A11", "A16"])
- assert edbapp.components.create_port_on_pins(refdes="U1", pins=["A26"], reference_pins=["A11", "A16", "A17"])
- assert edbapp.components.create_port_on_pins(refdes="U1", pins=["A28"], reference_pins=["A11", "A16"])
- edbapp.close()
-
- def test_replace_rlc_by_gap_boundaries(self):
- """Replace RLC component by RLC gap boundaries."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "ANSYS-HSD_V1_boundaries.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- for refdes, cmp in edbapp.components.components.items():
- edbapp.components.replace_rlc_by_gap_boundaries(refdes)
- rlc_list = [
- term for term in list(edbapp.active_layout.Terminals) if str(term.GetBoundaryType()) == "RlcBoundary"
- ]
- assert len(rlc_list) == 944
- edbapp.close()
-
- def test_components_get_component_placement_vector(self):
- """Get the placement vector between 2 components."""
- edb2 = EdbLegacy(self.target_path4, edbversion=desktop_version)
- for _, cmp in edb2.components.instances.items():
- assert isinstance(cmp.solder_ball_placement, int)
- mounted_cmp = edb2.components.get_component_by_name("BGA")
- hosting_cmp = self.edbapp.components.get_component_by_name("U1")
- (
- result,
- vector,
- rotation,
- solder_ball_height,
- ) = self.edbapp.components.get_component_placement_vector(
- mounted_component=mounted_cmp,
- hosting_component=hosting_cmp,
- mounted_component_pin1="A10",
- mounted_component_pin2="A12",
- hosting_component_pin1="A2",
- hosting_component_pin2="A4",
- )
- assert result
- assert abs(abs(rotation) - math.pi / 2) < 1e-9
- assert solder_ball_height == 0.00033
- assert len(vector) == 2
- (
- result,
- vector,
- rotation,
- solder_ball_height,
- ) = self.edbapp.components.get_component_placement_vector(
- mounted_component=mounted_cmp,
- hosting_component=hosting_cmp,
- mounted_component_pin1="A10",
- mounted_component_pin2="A12",
- hosting_component_pin1="A2",
- hosting_component_pin2="A4",
- flipped=True,
- )
- assert result
- assert abs(rotation + math.pi / 2) < 1e-9
- assert solder_ball_height == 0.00033
- assert len(vector) == 2
- edb2.close()
-
- def test_components_assign(self):
- """Assign RLC model, S-parameter model and spice model."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_17.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- sparam_path = os.path.join(local_path, "example_models", test_subfolder, "GRM32_DC0V_25degC_series.s2p")
- spice_path = os.path.join(local_path, "example_models", test_subfolder, "GRM32_DC0V_25degC.mod")
-
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- comp = edbapp.components.instances["R2"]
- assert not comp.assign_rlc_model()
- comp.assign_rlc_model(1, None, 3, False)
- assert (
- not comp.is_parallel_rlc
- and float(comp.res_value) == 1
- and float(comp.ind_value) == 0
- and float(comp.cap_value) == 3
- )
- comp.assign_rlc_model(1, 2, 3, True)
- assert comp.is_parallel_rlc
- assert (
- comp.is_parallel_rlc
- and float(comp.res_value) == 1
- and float(comp.ind_value) == 2
- and float(comp.cap_value) == 3
- )
- assert comp.value
- assert not comp.spice_model and not comp.s_param_model and not comp.netlist_model
- assert comp.assign_s_param_model(sparam_path) and comp.value
- assert comp.s_param_model
- assert edbapp.components.nport_comp_definition
- assert comp.assign_spice_model(spice_path) and comp.value
- assert comp.spice_model
- comp.type = "Inductor"
- comp.value = 10 # This command set the model back to ideal RLC
- assert comp.type == "Inductor" and comp.value == 10 and float(comp.ind_value) == 10
- edbapp.close()
-
- def test_components_bounding_box(self):
- """Get component's bounding box."""
- target_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- out_edb = os.path.join(self.local_scratch.path, "get_comp_bbox.aedb")
- self.local_scratch.copyfolder(target_path, out_edb)
- edbapp = EdbLegacy(out_edb, edbversion=desktop_version)
- component = edbapp.components.instances["U1"]
- assert component.bounding_box
- assert isinstance(component.rotation, float)
- edbapp.close()
diff --git a/tests/grpc/system/test_edb_differential_pairs.py b/tests/grpc/system/test_edb_differential_pairs.py
deleted file mode 100644
index 25ab89f149..0000000000
--- a/tests/grpc/system/test_edb_differential_pairs.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""Tests related to Edb differential pairs
-"""
-
-import pytest
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path2 = target_path2
- self.target_path4 = target_path4
-
- def test_differential_pairs_queries(self):
- """Evaluate differential pairs queries"""
- self.edbapp.differential_pairs.auto_identify()
- diff_pair = self.edbapp.differential_pairs.create("new_pair1", "PCIe_Gen4_RX1_P", "PCIe_Gen4_RX1_N")
- assert diff_pair.positive_net.name == "PCIe_Gen4_RX1_P"
- assert diff_pair.negative_net.name == "PCIe_Gen4_RX1_N"
- assert self.edbapp.differential_pairs.items
diff --git a/tests/grpc/system/test_edb_extended_nets.py b/tests/grpc/system/test_edb_extended_nets.py
deleted file mode 100644
index 1b7eaa62c6..0000000000
--- a/tests/grpc/system/test_edb_extended_nets.py
+++ /dev/null
@@ -1,27 +0,0 @@
-"""Tests related to Edb extended nets
-"""
-
-import pytest
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path2 = target_path2
- self.target_path4 = target_path4
-
- def test_nets_queries(self):
- """Evaluate nets queries"""
- assert self.edbapp.extended_nets.auto_identify_signal()
- assert self.edbapp.extended_nets.auto_identify_power()
- extended_net_name, _ = next(iter(self.edbapp.extended_nets.items.items()))
- assert self.edbapp.extended_nets[extended_net_name]
- assert self.edbapp.extended_nets[extended_net_name].nets
- assert self.edbapp.extended_nets[extended_net_name].components
- assert self.edbapp.extended_nets[extended_net_name].rlc
- assert self.edbapp.extended_nets[extended_net_name].serial_rlc
- assert self.edbapp.extended_nets.create("new_ex_net", "DDR4_A1")
diff --git a/tests/grpc/system/test_edb_ipc.py b/tests/grpc/system/test_edb_ipc.py
deleted file mode 100644
index 91b3a87eaf..0000000000
--- a/tests/grpc/system/test_edb_ipc.py
+++ /dev/null
@@ -1,62 +0,0 @@
-"""Tests related to the interaction between Edb and Ipc2581
-"""
-
-import os
-import pytest
-
-from pyedb.legacy.edb import EdbLegacy
-from tests.legacy.system.conftest import test_subfolder
-from tests.legacy.system.conftest import local_path
-from tests.conftest import desktop_version
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path2 = target_path2
- self.target_path4 = target_path4
-
- def test_export_to_ipc2581_0(self):
- """Export of a loaded aedb file to an XML IPC2581 file"""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1_cut.aedb")
- target_path = os.path.join(self.local_scratch.path, "ANSYS-HSD_V1_ipc.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- xml_file = os.path.join(self.local_scratch.path, "test.xml")
- edbapp.export_to_ipc2581(xml_file)
- assert os.path.exists(xml_file)
-
- # Export should be made with units set to default -millimeter-.
- edbapp.export_to_ipc2581(xml_file, "mm")
- assert os.path.exists(xml_file)
- edbapp.close()
-
- def test_146_export_ipc_1(self):
- """Export of a loaded aedb file to an XML IPC2581 file"""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_ipc", "ANSYS-HSD_V1_boundaries.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- xml_file = os.path.join(target_path, "test.xml")
- edbapp.export_to_ipc2581(xml_file)
- assert os.path.isfile(xml_file)
- ipc_edb = EdbLegacy(xml_file, edbversion=desktop_version)
- ipc_stats = ipc_edb.get_statistics()
- assert ipc_stats.layout_size == (0.1492, 0.0837)
- assert ipc_stats.num_capacitors == 380
- assert ipc_stats.num_discrete_components == 31
- assert ipc_stats.num_inductors == 10
- assert ipc_stats.num_layers == 15
- assert ipc_stats.num_nets == 348
- assert ipc_stats.num_polygons == 138
- assert ipc_stats.num_resistors == 82
- assert ipc_stats.num_traces == 1565
- assert ipc_stats.num_traces == 1565
- assert ipc_stats.num_vias == 4730
- assert ipc_stats.stackup_thickness == 0.001748
- edbapp.close()
- ipc_edb.close()
diff --git a/tests/grpc/system/test_edb_materials.py b/tests/grpc/system/test_edb_materials.py
deleted file mode 100644
index 54eb13eb96..0000000000
--- a/tests/grpc/system/test_edb_materials.py
+++ /dev/null
@@ -1,113 +0,0 @@
-"""Tests related to Edb
-"""
-
-import os
-from pyedb.legacy.edb_core.edb_data.simulation_configuration import SimulationConfiguration
-import pytest
-
-from pyedb.legacy.edb import EdbLegacy
-from tests.conftest import local_path
-from tests.conftest import desktop_version
-from tests.legacy.system.conftest import test_subfolder
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
-
- def test_material_properties(self):
- """Evaluate materials properties."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_0127.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- assert isinstance(edbapp.materials.materials, dict)
- edbapp.materials["FR4_epoxy"].conductivity = 1
- assert edbapp.materials["FR4_epoxy"].conductivity == 1
- edbapp.materials["FR4_epoxy"].permittivity = 1
- assert edbapp.materials["FR4_epoxy"].permittivity == 1
- edbapp.materials["FR4_epoxy"].loss_tangent = 1
- assert edbapp.materials["FR4_epoxy"].loss_tangent == 1
- edbapp.materials.add_conductor_material("new_conductor", 1)
- assert not edbapp.materials.add_conductor_material("new_conductor", 1)
- edbapp.materials.add_dielectric_material("new_dielectric", 1, 2)
- assert not edbapp.materials.add_dielectric_material("new_dielectric", 1, 2)
- edbapp.materials["FR4_epoxy"].magnetic_loss_tangent = 0.01
- assert edbapp.materials["FR4_epoxy"].magnetic_loss_tangent == 0.01
- edbapp.materials["FR4_epoxy"].youngs_modulus = 5000
- assert edbapp.materials["FR4_epoxy"].youngs_modulus == 5000
- edbapp.materials["FR4_epoxy"].mass_density = 50
-
- assert edbapp.materials["FR4_epoxy"].mass_density == 50
- edbapp.materials["FR4_epoxy"].thermal_conductivity = 1e-5
-
- assert edbapp.materials["FR4_epoxy"].thermal_conductivity == 1e-5
- edbapp.materials["FR4_epoxy"].thermal_expansion_coefficient = 1e-7
-
- assert edbapp.materials["FR4_epoxy"].thermal_expansion_coefficient == 1e-7
- edbapp.materials["FR4_epoxy"].poisson_ratio = 1e-3
- assert edbapp.materials["FR4_epoxy"].poisson_ratio == 1e-3
- assert edbapp.materials["new_conductor"]
- assert edbapp.materials.duplicate("FR4_epoxy", "FR41")
- assert edbapp.materials["FR41"]
- assert edbapp.materials["FR4_epoxy"].conductivity == edbapp.materials["FR41"].conductivity
- assert edbapp.materials["FR4_epoxy"].permittivity == edbapp.materials["FR41"].permittivity
- assert edbapp.materials["FR4_epoxy"].loss_tangent == edbapp.materials["FR41"].loss_tangent
- assert edbapp.materials["FR4_epoxy"].magnetic_loss_tangent == edbapp.materials["FR41"].magnetic_loss_tangent
- assert edbapp.materials["FR4_epoxy"].youngs_modulus == edbapp.materials["FR41"].youngs_modulus
- assert edbapp.materials["FR4_epoxy"].mass_density == edbapp.materials["FR41"].mass_density
- assert edbapp.materials["FR4_epoxy"].thermal_conductivity == edbapp.materials["FR41"].thermal_conductivity
- assert (
- edbapp.materials["FR4_epoxy"].thermal_expansion_coefficient
- == edbapp.materials["FR41"].thermal_expansion_coefficient
- )
- assert edbapp.materials["FR4_epoxy"].poisson_ratio == edbapp.materials["FR41"].poisson_ratio
- assert edbapp.materials.add_debye_material("My_Debye2", 5, 3, 0.02, 0.05, 1e5, 1e9)
- assert edbapp.materials.add_djordjevicsarkar_material("MyDjord2", 3.3, 0.02, 3.3)
- freq = [0, 2, 3, 4, 5, 6]
- rel_perm = [1e9, 1.1e9, 1.2e9, 1.3e9, 1.5e9, 1.6e9]
- loss_tan = [0.025, 0.026, 0.027, 0.028, 0.029, 0.030]
- assert edbapp.materials.add_multipole_debye_material("My_MP_Debye2", freq, rel_perm, loss_tan)
- edbapp.close()
- edbapp = EdbLegacy(edbversion=desktop_version)
- assert "air" in edbapp.materials.materials
- edbapp.close()
-
- def test_material_load_syslib_amat(self):
- """Load material from an amat file."""
- assert self.edbapp.materials.load_syslib_amat()
- material_list = list(self.edbapp.materials.materials.keys())
- assert material_list
- assert len(material_list) > 0
- assert self.edbapp.materials.materials["Rogers RO3003 (tm)"].loss_tangent == 0.0013
- assert self.edbapp.materials.materials["Rogers RO3003 (tm)"].permittivity == 3.0
-
- def test_materials_read_materials(self):
- """Read materials."""
- path = os.path.join(local_path, "example_models", "syslib", "Materials.amat")
- mats = self.edbapp.materials.read_materials(path)
- key = "FC-78"
- assert key in mats
- assert mats[key]["thermal_conductivity"] == 0.062
- assert mats[key]["mass_density"] == 1700
- assert mats[key]["specific_heat"] == 1050
- assert mats[key]["thermal_expansion_coeffcient"] == 0.0016
- key = "Polyflon CuFlon (tm)"
- assert key in mats
- assert mats[key]["permittivity"] == 2.1
- assert mats[key]["tangent_delta"] == 0.00045
- key = "Water(@360K)"
- assert key in mats
- assert mats[key]["thermal_conductivity"] == 0.6743
- assert mats[key]["mass_density"] == 967.4
- assert mats[key]["specific_heat"] == 4206
- assert mats[key]["thermal_expansion_coeffcient"] == 0.0006979
- key = "steel_stainless"
- assert mats[key]["conductivity"] == 1100000
- assert mats[key]["thermal_conductivity"] == 13.8
- assert mats[key]["mass_density"] == 8055
- assert mats[key]["specific_heat"] == 480
- assert mats[key]["thermal_expansion_coeffcient"] == 1.08e-005
diff --git a/tests/grpc/system/test_edb_modeler.py b/tests/grpc/system/test_edb_modeler.py
deleted file mode 100644
index b6f35ddf2e..0000000000
--- a/tests/grpc/system/test_edb_modeler.py
+++ /dev/null
@@ -1,274 +0,0 @@
-"""Tests related to Edb modeler
-"""
-
-from pyedb.legacy.edb import EdbLegacy
-import pytest
-from pyedb.generic.settings import settings
-from tests.conftest import local_path
-from tests.conftest import desktop_version
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path2 = target_path2
- self.target_path4 = target_path4
-
- def test_modeler_polygons(self):
- """Evaluate modeler polygons"""
- assert len(self.edbapp.modeler.polygons) > 0
- assert self.edbapp.modeler.polygons[0].is_void == self.edbapp.modeler.polygons[0].IsVoid()
-
- poly0 = self.edbapp.modeler.polygons[0]
- assert self.edbapp.modeler.polygons[0].clone()
- assert isinstance(poly0.voids, list)
- assert isinstance(poly0.points_raw(), list)
- assert isinstance(poly0.points(), tuple)
- assert isinstance(poly0.points()[0], list)
- assert poly0.points()[0][0] >= 0.0
- assert poly0.points_raw()[0].X.ToDouble() >= 0.0
- assert poly0.type == "Polygon"
- assert not poly0.is_arc(poly0.points_raw()[0])
- assert isinstance(poly0.voids, list)
- assert isinstance(poly0.get_closest_point([0, 0]), list)
- assert isinstance(poly0.get_closest_arc_midpoint([0, 0]), list)
- assert isinstance(poly0.arcs, list)
- assert isinstance(poly0.longest_arc.length, float)
- assert isinstance(poly0.shortest_arc.length, float)
- assert not poly0.in_polygon([0, 0])
- assert isinstance(poly0.arcs[0].center, list)
- assert isinstance(poly0.arcs[0].radius, float)
- assert poly0.arcs[0].is_segment
- assert not poly0.arcs[0].is_point
- assert not poly0.arcs[0].is_ccw
- assert isinstance(poly0.arcs[0].points_raw, list)
- assert isinstance(poly0.arcs[0].points, tuple)
- assert isinstance(poly0.intersection_type(poly0), int)
- assert poly0.is_intersecting(poly0)
-
- def test_modeler_paths(self):
- """Evaluate modeler paths"""
- assert len(self.edbapp.modeler.paths) > 0
- assert self.edbapp.modeler.paths[0].type == "Path"
- assert self.edbapp.modeler.paths[0].clone()
- assert isinstance(self.edbapp.modeler.paths[0].width, float)
- self.edbapp.modeler.paths[0].width = "1mm"
- assert self.edbapp.modeler.paths[0].width == 0.001
-
- def test_modeler_primitives_by_layer(self):
- """Evaluate modeler primitives by layer"""
- assert self.edbapp.modeler.primitives_by_layer["1_Top"][0].layer_name == "1_Top"
- assert self.edbapp.modeler.primitives_by_layer["1_Top"][0].layer.GetName() == "1_Top"
- assert not self.edbapp.modeler.primitives_by_layer["1_Top"][0].is_negative
- assert not self.edbapp.modeler.primitives_by_layer["1_Top"][0].is_void
- self.edbapp.modeler.primitives_by_layer["1_Top"][0].is_negative = True
- assert self.edbapp.modeler.primitives_by_layer["1_Top"][0].is_negative
- self.edbapp.modeler.primitives_by_layer["1_Top"][0].is_negative = False
- assert not self.edbapp.modeler.primitives_by_layer["1_Top"][0].has_voids
- assert not self.edbapp.modeler.primitives_by_layer["1_Top"][0].is_parameterized
- assert isinstance(self.edbapp.modeler.primitives_by_layer["1_Top"][0].get_hfss_prop(), tuple)
- assert not self.edbapp.modeler.primitives_by_layer["1_Top"][0].is_zone_primitive
- assert self.edbapp.modeler.primitives_by_layer["1_Top"][0].can_be_zone_primitive
-
- def test_modeler_primitives(self):
- """Evaluate modeler primitives"""
- assert len(self.edbapp.modeler.rectangles) > 0
- assert len(self.edbapp.modeler.circles) > 0
- assert len(self.edbapp.modeler.bondwires) == 0
- assert "1_Top" in self.edbapp.modeler.polygons_by_layer.keys()
- assert len(self.edbapp.modeler.polygons_by_layer["1_Top"]) > 0
- assert len(self.edbapp.modeler.polygons_by_layer["DE1"]) == 0
- assert self.edbapp.modeler.rectangles[0].type == "Rectangle"
- assert self.edbapp.modeler.circles[0].type == "Circle"
-
- def test_modeler_get_polygons_bounding(self):
- """Retrieve polygons bounding box."""
- polys = self.edbapp.modeler.get_polygons_by_layer("GND")
- for poly in polys:
- bounding = self.edbapp.modeler.get_polygon_bounding_box(poly)
- assert len(bounding) == 4
-
- def test_modeler_get_polygons_by_layer_and_nets(self):
- """Retrieve polygons by layer and nets."""
- nets = ["GND", "1V0"]
- polys = self.edbapp.modeler.get_polygons_by_layer("16_Bottom", nets)
- assert polys
-
-
- def test_modeler_get_polygons_points(self):
- """Retrieve polygons points."""
- polys = self.edbapp.modeler.get_polygons_by_layer("GND")
- for poly in polys:
- points = self.edbapp.modeler.get_polygon_points(poly)
- assert points
-
- def test_modeler_create_polygon(self):
- """Create a polygon based on a shape or points."""
- settings.enable_error_handler = True
- points = [
- [-0.025, -0.02],
- [0.025, -0.02],
- [0.025, 0.02],
- [-0.025, 0.02],
- [-0.025, -0.02],
- ]
- plane = self.edbapp.modeler.Shape("polygon", points=points)
- points = [
- [-0.001, -0.001],
- [0.001, -0.001, "ccw", 0.0, -0.0012],
- [0.001, 0.001],
- [0.0015, 0.0015, 0.0001],
- [-0.001, 0.0015],
- [-0.001, -0.001],
- ]
- void1 = self.edbapp.modeler.Shape("polygon", points=points)
- void2 = self.edbapp.modeler.Shape("rectangle", [-0.002, 0.0], [-0.015, 0.0005])
- assert self.edbapp.modeler.create_polygon(plane, "1_Top", [void1, void2])
- self.edbapp["polygon_pts_x"] = -1.025
- self.edbapp["polygon_pts_y"] = -1.02
- points = [
- ["polygon_pts_x", "polygon_pts_y"],
- [1.025, -1.02],
- [1.025, 1.02],
- [-1.025, 1.02],
- [-1.025, -1.02],
- ]
- assert self.edbapp.modeler.create_polygon(points, "1_Top")
- settings.enable_error_handler = False
-
- def test_modeler_create_trace(self):
- """Create a trace based on a list of points."""
- points = [
- [-0.025, -0.02],
- [0.025, -0.02],
- [0.025, 0.02],
- ]
- trace = self.edbapp.modeler.create_trace(points, "1_Top")
- assert trace
- assert isinstance(trace.get_center_line(), list)
- assert isinstance(trace.get_center_line(True), list)
- self.edbapp["delta_x"] = "1mm"
- assert trace.add_point("delta_x", "1mm", True)
- assert trace.get_center_line(True)[-1][0] == "(delta_x)+(0.025)"
- assert trace.add_point(0.001, 0.002)
- assert trace.get_center_line()[-1] == [0.001, 0.002]
-
- def test_modeler_add_void(self):
- """Add a void into a shape."""
- plane_shape = self.edbapp.modeler.Shape("rectangle", pointA=["-5mm", "-5mm"], pointB=["5mm", "5mm"])
- plane = self.edbapp.modeler.create_polygon(plane_shape, "1_Top", net_name="GND")
- void = self.edbapp.modeler.create_trace([["0", "0"], ["0", "1mm"]], layer_name="1_Top", width="0.1mm")
- assert self.edbapp.modeler.add_void(plane, void)
- assert plane.add_void(void)
-
- def test_modeler_fix_circle_void(self):
- """Fix issues when circle void are clipped due to a bug in EDB."""
- assert self.edbapp.modeler.fix_circle_void_for_clipping()
-
- def test_modeler_primitives_area(self):
- """Access primitives total area."""
- i = 0
- while i < 10:
- assert self.edbapp.modeler.primitives[i].area(False) > 0
- assert self.edbapp.modeler.primitives[i].area(True) > 0
- i += 1
- assert self.edbapp.modeler.primitives[i].bbox
- assert self.edbapp.modeler.primitives[i].center
- assert self.edbapp.modeler.primitives[i].get_closest_point((0, 0))
- assert self.edbapp.modeler.primitives[i].polygon_data
- assert self.edbapp.modeler.paths[0].length
-
- def test_modeler_create_rectangle(self):
- """Create rectangle."""
- rect = self.edbapp.modeler.create_rectangle("1_Top", "SIG1", ["0", "0"], ["2mm", "3mm"])
- assert rect
- rect.is_negative = True
- assert rect.is_negative
- rect.is_negative = False
- assert not rect.is_negative
- assert self.edbapp.modeler.create_rectangle(
- "1_Top",
- "SIG2",
- center_point=["0", "0"],
- width="4mm",
- height="5mm",
- representation_type="CenterWidthHeight",
- )
-
- def test_modeler_create_circle(self):
- """Create circle."""
- poly = self.edbapp.modeler.create_polygon_from_points([[0, 0], [100, 0], [100, 100], [0, 100]], "1_Top")
- assert poly
- poly.add_void([[20, 20], [20, 30], [100, 30], [100, 20]])
- poly2 = self.edbapp.modeler.create_polygon_from_points([[60, 60], [60, 150], [150, 150], [150, 60]], "1_Top")
- new_polys = poly.subtract(poly2)
- assert len(new_polys) == 1
- circle = self.edbapp.modeler.create_circle("1_Top", 40, 40, 15)
- assert circle
- intersection = new_polys[0].intersect(circle)
- assert len(intersection) == 1
- circle2 = self.edbapp.modeler.create_circle("1_Top", 20, 20, 15)
- assert circle2.unite(intersection)
-
- def test_modeler_defeature(self):
- """Defeature the polygon."""
- assert self.edbapp.modeler.defeature_polygon(self.edbapp.modeler.primitives_by_net["GND"][-1], 0.01)
-
- def test_modeler_primitives_boolean_operation(self):
- """Evaluate modeler primitives boolean operations."""
- from pyedb.legacy.edb import EdbLegacy
- edb = EdbLegacy()
- edb.stackup.add_layer(layer_name="test")
- x = edb.modeler.create_polygon(
- layer_name="test", main_shape=[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0]]
- )
- assert x
- x_hole1 = edb.modeler.create_polygon(
- layer_name="test", main_shape=[[1.0, 1.0], [4.5, 1.0], [4.5, 9.0], [1.0, 9.0]]
- )
- x_hole2 = edb.modeler.create_polygon(
- layer_name="test", main_shape=[[4.5, 1.0], [9.0, 1.0], [9.0, 9.0], [4.5, 9.0]]
- )
- x = x.subtract([x_hole1, x_hole2])[0]
- assert x
- y = edb.modeler.create_polygon(layer_name="foo", main_shape=[[4.0, 3.0], [6.0, 3.0], [6.0, 6.0], [4.0, 6.0]])
- z = x.subtract(y)
- assert z
- edb.stackup.add_layer(layer_name="foo")
- x = edb.modeler.create_polygon(
- layer_name="foo", main_shape=[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0]]
- )
- x_hole = edb.modeler.create_polygon(
- layer_name="foo", main_shape=[[1.0, 1.0], [9.0, 1.0], [9.0, 9.0], [1.0, 9.0]]
- )
- y = x.subtract(x_hole)[0]
- z = edb.modeler.create_polygon(
- layer_name="foo", main_shape=[[-15.0, 5.0], [15.0, 5.0], [15.0, 6.0], [-15.0, 6.0]]
- )
- assert y.intersect(z)
-
- edb.stackup.add_layer(layer_name="test2")
- x = edb.modeler.create_polygon(
- layer_name="test2", main_shape=[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0]]
- )
- x_hole = edb.modeler.create_polygon(
- layer_name="test2", main_shape=[[1.0, 1.0], [9.0, 1.0], [9.0, 9.0], [1.0, 9.0]]
- )
- y = x.subtract(x_hole)[0]
- assert y.voids
- y_clone = y.clone()
- assert y_clone.voids
- edb.close()
-
- def test_modeler_path_convert_to_polygon(self):
- import os
- target_path = os.path.join(local_path, "example_models", "convert_and_merge_path.aedb")
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- for path in edbapp.modeler.paths:
- assert path.convert_to_polygon()
- assert edbapp.nets.merge_nets_polygons("test")
- edbapp.close()
diff --git a/tests/grpc/system/test_edb_net_classes.py b/tests/grpc/system/test_edb_net_classes.py
deleted file mode 100644
index e5df180f8f..0000000000
--- a/tests/grpc/system/test_edb_net_classes.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""Tests related to Edb net classes
-"""
-
-import pytest
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path2 = target_path2
- self.target_path4 = target_path4
-
- def test_net_classes_queries(self):
- """Evaluate net classes queries"""
- assert self.edbapp.net_classes.items
- assert self.edbapp.net_classes.create("DDR4_ADD", ["DDR4_A0", "DDR4_A1"])
- assert self.edbapp.net_classes["DDR4_ADD"].name == "DDR4_ADD"
- assert self.edbapp.net_classes["DDR4_ADD"].nets
- self.edbapp.net_classes["DDR4_ADD"].name = "DDR4_ADD_RENAMED"
- assert not self.edbapp.net_classes["DDR4_ADD_RENAMED"].is_null
-
diff --git a/tests/grpc/system/test_edb_nets.py b/tests/grpc/system/test_edb_nets.py
deleted file mode 100644
index 23b93f6088..0000000000
--- a/tests/grpc/system/test_edb_nets.py
+++ /dev/null
@@ -1,121 +0,0 @@
-"""Tests related to Edb nets
-"""
-
-import os
-import pytest
-from pyedb.legacy.edb import EdbLegacy
-from tests.conftest import desktop_version
-from tests.conftest import local_path
-from tests.legacy.system.conftest import test_subfolder
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path2 = target_path2
- self.target_path4 = target_path4
-
-
- def test_nets_queries(self):
- """Evaluate nets queries"""
- assert len(self.edbapp.nets.netlist) > 0
- signalnets = self.edbapp.nets.signal
- assert not signalnets[list(signalnets.keys())[0]].is_power_ground
- assert not signalnets[list(signalnets.keys())[0]].IsPowerGround()
- assert len(list(signalnets[list(signalnets.keys())[0]].primitives)) > 0
- assert len(signalnets) > 2
-
- powernets = self.edbapp.nets.power
- assert len(powernets) > 2
- assert powernets["AVCC_1V3"].is_power_ground
- powernets["AVCC_1V3"].is_power_ground = False
- assert not powernets["AVCC_1V3"].is_power_ground
- powernets["AVCC_1V3"].is_power_ground = True
- assert powernets["AVCC_1V3"].name == "AVCC_1V3"
- assert powernets["AVCC_1V3"].IsPowerGround()
- assert len(list(powernets["AVCC_1V3"].components.keys())) > 0
- assert len(powernets["AVCC_1V3"].primitives) > 0
-
- assert self.edbapp.nets.find_or_create_net("GND")
- assert self.edbapp.nets.find_or_create_net(start_with="gn")
- assert self.edbapp.nets.find_or_create_net(start_with="g", end_with="d")
- assert self.edbapp.nets.find_or_create_net(end_with="d")
- assert self.edbapp.nets.find_or_create_net(contain="usb")
- assert self.edbapp.nets["AVCC_1V3"].extended_net is None
- self.edbapp.extended_nets.auto_identify_power()
- assert self.edbapp.nets["AVCC_1V3"].extended_net
-
- def test_nets_get_power_tree(self):
- """Evaluate nets get powertree."""
- OUTPUT_NET = "5V"
- GROUND_NETS = ["GND", "PGND"]
- (
- component_list,
- component_list_columns,
- net_group,
- ) = self.edbapp.nets.get_powertree(OUTPUT_NET, GROUND_NETS)
- assert component_list
- assert component_list_columns
- assert net_group
-
- def test_nets_delete(self):
- """Delete a net."""
- assert "JTAG_TDI" in self.edbapp.nets
- self.edbapp.nets["JTAG_TCK"].delete()
- nets_deleted = self.edbapp.nets.delete("JTAG_TDI")
- assert "JTAG_TDI" in nets_deleted
- assert "JTAG_TDI" not in self.edbapp.nets
-
- def test_nets_classify_nets(self):
- """Reassign power based on list of nets."""
- assert "SFPA_SDA" in self.edbapp.nets.signal
- assert "SFPA_SCL" in self.edbapp.nets.signal
- assert "SFPA_VCCR" in self.edbapp.nets.power
-
- assert self.edbapp.nets.classify_nets(["SFPA_SDA", "SFPA_SCL"], ["SFPA_VCCR"])
- assert "SFPA_SDA" in self.edbapp.nets.power
- assert "SFPA_SDA" not in self.edbapp.nets.signal
- assert "SFPA_SCL" in self.edbapp.nets.power
- assert "SFPA_SCL" not in self.edbapp.nets.signal
- assert "SFPA_VCCR" not in self.edbapp.nets.power
- assert "SFPA_VCCR" in self.edbapp.nets.signal
-
- assert self.edbapp.nets.classify_nets(["SFPA_VCCR"], ["SFPA_SDA", "SFPA_SCL"])
- assert "SFPA_SDA" in self.edbapp.nets.signal
- assert "SFPA_SCL" in self.edbapp.nets.signal
- assert "SFPA_VCCR" in self.edbapp.nets.power
-
- def test_nets_arc_data(self):
- """Evaluate primitive arc data."""
- assert len(self.edbapp.nets["1.2V_DVDDL"].primitives[0].arcs) > 0
- assert self.edbapp.nets["1.2V_DVDDL"].primitives[0].arcs[0].start
- assert self.edbapp.nets["1.2V_DVDDL"].primitives[0].arcs[0].end
- assert self.edbapp.nets["1.2V_DVDDL"].primitives[0].arcs[0].height
-
- @pytest.mark.slow
- def test_nets_dc_shorts(self):
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_dc_shorts", "ANSYS-HSD_V1_dc_shorts.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- dc_shorts = edbapp.layout_validation.dc_shorts()
- assert dc_shorts
- edbapp.nets.nets["DDR4_A0"].name = "DDR4$A0"
- edbapp.layout_validation.illegal_net_names(True)
-
- # assert len(dc_shorts) == 20
- assert ["LVDS_CH09_N", "GND"] in dc_shorts
- assert ["LVDS_CH09_N", "DDR4_DM3"] in dc_shorts
- assert ["DDR4_DM3", "LVDS_CH07_N"] in dc_shorts
- assert len(edbapp.nets["DDR4_DM3"].find_dc_short()) > 0
- edbapp.nets["DDR4_DM3"].find_dc_short(True)
- assert len(edbapp.nets["DDR4_DM3"].find_dc_short()) == 0
- edbapp.close()
-
- def test_nets_eligible_power_nets(self):
- """Evaluate eligible power nets."""
- assert "GND" in [i.name for i in self.edbapp.nets.eligible_power_nets()]
diff --git a/tests/grpc/system/test_edb_padstacks.py b/tests/grpc/system/test_edb_padstacks.py
deleted file mode 100644
index effdee566f..0000000000
--- a/tests/grpc/system/test_edb_padstacks.py
+++ /dev/null
@@ -1,306 +0,0 @@
-"""Tests related to Edb padstacks
-"""
-import os
-import pytest
-
-from pyedb.legacy.edb import EdbLegacy
-from tests.conftest import local_path
-from tests.conftest import desktop_version
-from tests.legacy.system.conftest import target_path3
-from tests.legacy.system.conftest import test_subfolder
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path3, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path3 = target_path3
- self.target_path4 = target_path4
-
- def test_get_pad_parameters(self):
- """Access to pad parameters."""
- pin = self.edbapp.components.get_pin_from_component("J1", pinName="1")
- parameters = self.edbapp.padstacks.get_pad_parameters(
- pin[0], "1_Top", self.edbapp.padstacks.pad_type.RegularPad
- )
- assert isinstance(parameters[1], list)
- assert isinstance(parameters[0], int)
-
- def test_get_vias_from_nets(self):
- """Use padstacks' get_via_instance_from_net method."""
- assert self.edbapp.padstacks.get_via_instance_from_net("GND")
- assert not self.edbapp.padstacks.get_via_instance_from_net(["GND2"])
-
- def test_create_with_packstack_name(self):
- """Create a padstack"""
- # Create myVia
- self.edbapp.padstacks.create(padstackname="myVia")
- assert "myVia" in list(self.edbapp.padstacks.definitions.keys())
- self.edbapp.padstacks.definitions["myVia"].hole_range = "begin_on_upper_pad"
- assert self.edbapp.padstacks.definitions["myVia"].hole_range == "begin_on_upper_pad"
- self.edbapp.padstacks.definitions["myVia"].hole_range = "through"
- assert self.edbapp.padstacks.definitions["myVia"].hole_range == "through"
- # Create myVia_vullet
- self.edbapp.padstacks.create(padstackname="myVia_bullet", antipad_shape="Bullet")
- assert "myVia_bullet" in list(self.edbapp.padstacks.definitions.keys())
-
- self.edbapp.add_design_variable("via_x", 5e-3)
- self.edbapp["via_y"] = "1mm"
- assert self.edbapp["via_y"].value == 1e-3
- assert self.edbapp["via_y"].value_string == "1mm"
- assert self.edbapp.padstacks.place(["via_x", "via_x+via_y"], "myVia", via_name="via_test1")
- assert self.edbapp.padstacks.place(["via_x", "via_x+via_y*2"], "myVia_bullet")
- self.edbapp.padstacks["via_test1"].net_name = "GND"
- assert self.edbapp.padstacks["via_test1"].net_name == "GND"
- padstack = self.edbapp.padstacks.place(["via_x", "via_x+via_y*3"], "myVia", is_pin=True)
- for test_prop in (self.edbapp.padstacks.padstack_instances, self.edbapp.padstacks.instances):
- padstack_instance = test_prop[padstack.id]
- assert padstack_instance.is_pin
- assert padstack_instance.position
- assert padstack_instance.start_layer in padstack_instance.layer_range_names
- assert padstack_instance.stop_layer in padstack_instance.layer_range_names
- padstack_instance.position = [0.001, 0.002]
- assert padstack_instance.position == [0.001, 0.002]
- assert padstack_instance.parametrize_position()
- assert isinstance(padstack_instance.rotation, float)
- self.edbapp.padstacks.create_circular_padstack(padstackname="mycircularvia")
- assert "mycircularvia" in list(self.edbapp.padstacks.definitions.keys())
- assert not padstack_instance.backdrill_top
- assert not padstack_instance.backdrill_bottom
- assert padstack_instance.delete()
- via = self.edbapp.padstacks.place([0, 0], "myVia")
- assert via.set_backdrill_top("Inner4(Sig2)", 0.5e-3)
- assert via.backdrill_top
- assert via.set_backdrill_bottom("16_Bottom", 0.5e-3)
- assert via.backdrill_bottom
-
- def test_padstacks_get_nets_from_pin_list(self):
- """Retrieve pin list from component and net."""
- cmp_pinlist = self.edbapp.padstacks.get_pinlist_from_component_and_net("U1", "GND")
- assert cmp_pinlist[0].GetNet().GetName()
-
- def test_padstack_properties_getter(self):
- """Evaluate properties"""
- for el in self.edbapp.padstacks.definitions:
- padstack = self.edbapp.padstacks.definitions[el]
- assert padstack.hole_plating_thickness is not None or False
- assert padstack.hole_properties is not None or False
- assert padstack.hole_plating_thickness is not None or False
- assert padstack.hole_plating_ratio is not None or False
- assert padstack.via_start_layer is not None or False
- assert padstack.via_stop_layer is not None or False
- assert padstack.material is not None or False
- assert padstack.hole_finished_size is not None or False
- assert padstack.hole_rotation is not None or False
- assert padstack.hole_offset_x is not None or False
- assert padstack.hole_offset_y is not None or False
- assert padstack.hole_type is not None or False
- pad = padstack.pad_by_layer[padstack.via_stop_layer]
- if not pad.shape == "NoGeometry":
- assert pad.parameters is not None or False
- assert pad.parameters_values is not None or False
- assert pad.offset_x is not None or False
- assert pad.offset_y is not None or False
- assert isinstance(pad.geometry_type, int)
- polygon = pad.polygon_data
- if polygon:
- assert polygon.GetBBox()
-
- def test_padstack_properties_setter(self):
- """Set padstack properties"""
- pad = self.edbapp.padstacks.definitions["c180h127"]
- hole_pad = 8
- tol = 1e-12
- pad.hole_properties = hole_pad
- pad.hole_offset_x = 0
- pad.hole_offset_y = 1
- pad.hole_rotation = 0
- pad.hole_plating_ratio = 90
- assert pad.hole_plating_ratio == 90
- pad.hole_plating_thickness = 0.3
- assert abs(pad.hole_plating_thickness - 0.3) <= tol
- pad.material = "copper"
- assert abs(pad.hole_properties[0] - hole_pad) < tol
- offset_x = 7
- offset_y = 1
- pad.pad_by_layer[pad.via_stop_layer].shape = "Circle"
- pad.pad_by_layer[pad.via_stop_layer].parameters = 7
- pad.pad_by_layer[pad.via_stop_layer].offset_x = offset_x
- pad.pad_by_layer[pad.via_stop_layer].offset_y = offset_y
- assert pad.pad_by_layer[pad.via_stop_layer].parameters["Diameter"].tofloat == 7
- assert pad.pad_by_layer[pad.via_stop_layer].offset_x == str(offset_x)
- assert pad.pad_by_layer[pad.via_stop_layer].offset_y == str(offset_y)
- pad.pad_by_layer[pad.via_stop_layer].parameters = {"Diameter": 8}
- assert pad.pad_by_layer[pad.via_stop_layer].parameters["Diameter"].tofloat == 8
- pad.pad_by_layer[pad.via_stop_layer].parameters = {"Diameter": 1}
- pad.pad_by_layer[pad.via_stop_layer].shape = "Square"
- pad.pad_by_layer[pad.via_stop_layer].parameters = {"Size": 1}
- pad.pad_by_layer[pad.via_stop_layer].shape = "Rectangle"
- pad.pad_by_layer[pad.via_stop_layer].parameters = {"XSize": 1, "YSize": 1}
- pad.pad_by_layer[pad.via_stop_layer].shape = "Oval"
- pad.pad_by_layer[pad.via_stop_layer].parameters = {"XSize": 1, "YSize": 1, "CornerRadius": 1}
- pad.pad_by_layer[pad.via_stop_layer].parameters = {"XSize": 1, "YSize": 1, "CornerRadius": 1}
- pad.pad_by_layer[pad.via_stop_layer].parameters = [1, 1, 1]
-
- def test_padstack_get_instance_by_name(self):
- """Access padstack instance by name."""
- padstack_instances = self.edbapp.padstacks.get_padstack_instance_by_net_name("GND")
- assert len(padstack_instances)
- padstack_1 = padstack_instances[0]
- assert padstack_1.id
- assert isinstance(padstack_1.bounding_box, list)
- for v in padstack_instances:
- if not v.is_pin:
- v.name = "TestInst"
- assert v.name == "TestInst"
- break
-
- def test_padstack_duplicate_padstack(self):
- """Duplicate a padstack."""
- self.edbapp.padstacks.duplicate(
- target_padstack_name="c180h127",
- new_padstack_name="c180h127_NEW",
- )
- assert self.edbapp.padstacks.definitions["c180h127_NEW"]
-
- def test_padstack_set_pad_property(self):
- """Set pad and antipad properties of the padstack."""
- self.edbapp.padstacks.set_pad_property(
- padstack_name="c180h127",
- layer_name="new",
- pad_shape="Circle",
- pad_params="800um",
- )
- assert self.edbapp.padstacks.definitions["c180h127"].pad_by_layer["new"]
-
- def test_microvias(self):
- """Convert padstack to microvias 3D objects."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "padstacks.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_128_microvias.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- assert edbapp.padstacks.definitions["Padstack_Circle"].convert_to_3d_microvias(False)
- assert edbapp.padstacks.definitions["Padstack_Rectangle"].convert_to_3d_microvias(False, hole_wall_angle=10)
- assert edbapp.padstacks.definitions["Padstack_Polygon_p12"].convert_to_3d_microvias(False)
- edbapp.close()
-
- def test_split_microvias(self):
- """Convert padstack definition to multiple microvias definitions."""
- edbapp = EdbLegacy(self.target_path4, edbversion=desktop_version)
- assert len(edbapp.padstacks.definitions["C4_POWER_1"].split_to_microvias()) > 0
- edbapp.close()
-
- def test_padstack_plating_ratio_fixing(self):
- """Fix hole plating ratio."""
- assert self.edbapp.padstacks.check_and_fix_via_plating()
-
- def test_padstack_search_reference_pins(self):
- """Search for reference pins using given criteria."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "ANSYS-HSD_V1_boundaries.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- pin = edbapp.components.instances["J5"].pins["19"]
- assert pin
- ref_pins = pin.get_reference_pins(reference_net="GND", search_radius=5e-3, max_limit=0, component_only=True)
- assert len(ref_pins) == 3
- reference_pins = edbapp.padstacks.get_reference_pins(
- positive_pin=pin, reference_net="GND", search_radius=5e-3, max_limit=0, component_only=True
- )
- assert len(reference_pins) == 3
- reference_pins = edbapp.padstacks.get_reference_pins(
- positive_pin=pin, reference_net="GND", search_radius=5e-3, max_limit=2, component_only=True
- )
- assert len(reference_pins) == 2
- reference_pins = edbapp.padstacks.get_reference_pins(
- positive_pin=pin, reference_net="GND", search_radius=5e-3, max_limit=0, component_only=False
- )
- assert len(reference_pins) == 11
- edbapp.close()
-
- def test_vias_metal_volume(self):
- """Metal volume of the via hole instance."""
- vias = [
- via
- for via in list(self.edbapp.padstacks.padstack_instances.values())
- if not via.start_layer == via.stop_layer
- ]
- assert vias[0].metal_volume
- assert vias[1].metal_volume
-
- def test_padstacks_create_rectangle_in_pad(self):
- """Create a rectangle inscribed inside a padstack instance pad."""
- example_model = os.path.join(local_path, "example_models", test_subfolder, "padstacks.aedb")
- self.local_scratch.copyfolder(
- example_model,
- os.path.join(self.local_scratch.path, "padstacks2.aedb"),
- )
- edb = EdbLegacy(
- edbpath=os.path.join(self.local_scratch.path, "padstacks2.aedb"),
- edbversion=desktop_version,
- isreadonly=True,
- )
- for test_prop in (edb.padstacks.instances, edb.padstacks.padstack_instances):
- padstack_instances = list(test_prop.values())
- for padstack_instance in padstack_instances:
- result = padstack_instance.create_rectangle_in_pad("s", partition_max_order=8)
- if padstack_instance.padstack_definition != "Padstack_None":
- assert result
- else:
- assert not result
- edb.close()
-
- def test_padstaks_plot_on_matplotlib(self):
- """Plot a Net to Matplotlib 2D Chart."""
- edb_plot = EdbLegacy(self.target_path3, edbversion=desktop_version)
-
- local_png1 = os.path.join(self.local_scratch.path, "test1.png")
- edb_plot.nets.plot(
- nets=None,
- layers=None,
- save_plot=local_png1,
- plot_components_on_top=True,
- plot_components_on_bottom=True,
- outline=[[-10e-3, -10e-3], [110e-3, -10e-3], [110e-3, 70e-3], [-10e-3, 70e-3]],
- )
- assert os.path.exists(local_png1)
-
- local_png2 = os.path.join(self.local_scratch.path, "test2.png")
- edb_plot.nets.plot(
- nets="V3P3_S5",
- layers=None,
- save_plot=local_png2,
- plot_components_on_top=True,
- plot_components_on_bottom=True,
- )
- assert os.path.exists(local_png2)
-
- local_png3 = os.path.join(self.local_scratch.path, "test3.png")
- edb_plot.nets.plot(
- nets=["LVL_I2C_SCL", "V3P3_S5", "GATE_V5_USB"],
- layers="TOP",
- color_by_net=True,
- save_plot=local_png3,
- plot_components_on_top=True,
- plot_components_on_bottom=True,
- )
- assert os.path.exists(local_png3)
-
- local_png4 = os.path.join(self.local_scratch.path, "test4.png")
- edb_plot.stackup.plot(
- save_plot=local_png4,
- plot_definitions=list(edb_plot.padstacks.definitions.keys())[0],
- )
- assert os.path.exists(local_png4)
-
- local_png5 = os.path.join(self.local_scratch.path, "test5.png")
- edb_plot.stackup.plot(
- scale_elevation=False,
- save_plot=local_png5,
- plot_definitions=list(edb_plot.padstacks.definitions.keys())[0],
- )
- assert os.path.exists(local_png4)
- edb_plot.close()
diff --git a/tests/grpc/system/test_edb_stackup.py b/tests/grpc/system/test_edb_stackup.py
deleted file mode 100644
index a6a8826307..0000000000
--- a/tests/grpc/system/test_edb_stackup.py
+++ /dev/null
@@ -1,1030 +0,0 @@
-"""Tests related to Edb stackup
-"""
-
-import os
-import math
-import pytest
-from pyedb.legacy.edb import EdbLegacy
-from tests.conftest import desktop_version
-from tests.conftest import local_path
-from tests.legacy.system.conftest import test_subfolder
-
-pytestmark = [pytest.mark.system, pytest.mark.legacy]
-
-class TestClass:
- @pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
- self.local_scratch = local_scratch
- self.target_path = target_path
- self.target_path2 = target_path2
- self.target_path4 = target_path4
-
- def test_stackup_get_signal_layers(self):
- """Report residual copper area per layer."""
- assert self.edbapp.stackup.residual_copper_area_per_layer()
-
- def test_stackup_limits(self):
- """Retrieve stackup limits."""
- assert self.edbapp.stackup.limits()
-
- def test_stackup_add_outline(self):
- """Add an outline layer named ``"Outline1"`` if it is not present."""
- edbapp = EdbLegacy(
- edbversion=desktop_version,
- )
- assert edbapp.stackup.add_outline_layer("Outline1")
- assert not edbapp.stackup.add_outline_layer("Outline1")
- edbapp.stackup.add_layer("1_Top")
- assert edbapp.stackup.layers["1_Top"].thickness == 3.5e-05
- edbapp.stackup.layers["1_Top"].thickness = 4e-5
- assert edbapp.stackup.layers["1_Top"].thickness == 4e-05
- edbapp.close()
-
- def test_stackup_create_symmetric_stackup(self):
- """Create a symmetric stackup."""
- app_edb = EdbLegacy(edbversion=desktop_version)
- assert not app_edb.stackup.create_symmetric_stackup(9)
- assert app_edb.stackup.create_symmetric_stackup(8)
- app_edb.close()
-
- app_edb = EdbLegacy(edbversion=desktop_version)
- assert app_edb.stackup.create_symmetric_stackup(8, soldermask=False)
- app_edb.close()
-
- def test_stackup_place_a3dcomp_3d_placement(self):
- """Place a 3D Component into current layout."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "lam_for_bottom_place.aedb")
- target_path = os.path.join(self.local_scratch.path, "output.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- laminate_edb = EdbLegacy(target_path, edbversion=desktop_version)
- chip_a3dcomp = os.path.join(local_path, "example_models", test_subfolder, "chip.a3dcomp")
- try:
- layout = laminate_edb.active_layout
- cell_instances = list(layout.CellInstances)
- assert len(cell_instances) == 0
- assert laminate_edb.stackup.place_a3dcomp_3d_placement(
- chip_a3dcomp,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- place_on_top=True,
- )
- cell_instances = list(layout.CellInstances)
- assert len(cell_instances) == 1
- cell_instance = cell_instances[0]
- assert cell_instance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- local_origin,
- rotation_axis_from,
- rotation_axis_to,
- angle,
- loc,
- _,
- ) = cell_instance.Get3DTransformation()
- else:
- (
- res,
- local_origin,
- rotation_axis_from,
- rotation_axis_to,
- angle,
- loc,
- ) = cell_instance.Get3DTransformation()
- assert res
- zero_value = laminate_edb.edb_value(0)
- one_value = laminate_edb.edb_value(1)
- origin_point = laminate_edb.edb_api.geometry.point3d_data(zero_value, zero_value, zero_value)
- x_axis_point = laminate_edb.edb_api.geometry.point3d_data(one_value, zero_value, zero_value)
- assert local_origin.IsEqual(origin_point)
- assert rotation_axis_from.IsEqual(x_axis_point)
- assert rotation_axis_to.IsEqual(x_axis_point)
- assert angle.IsEqual(zero_value)
- assert loc.IsEqual(
- laminate_edb.edb_api.geometry.point3d_data(zero_value, zero_value, laminate_edb.edb_value(170e-6))
- )
- assert laminate_edb.save_edb()
- finally:
- laminate_edb.close()
-
- def test_stackup_place_a3dcomp_3d_placement_on_bottom(self):
- """Place a 3D Component into current layout."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "lam_for_bottom_place.aedb")
- target_path = os.path.join(self.local_scratch.path, "output.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- laminate_edb = EdbLegacy(target_path, edbversion=desktop_version)
- chip_a3dcomp = os.path.join(local_path, "example_models", test_subfolder, "chip.a3dcomp")
- try:
- layout = laminate_edb.active_layout
- cell_instances = list(layout.CellInstances)
- assert len(cell_instances) == 0
- assert laminate_edb.stackup.place_a3dcomp_3d_placement(
- chip_a3dcomp,
- angle=90.0,
- offset_x=0.5e-3,
- offset_y=-0.5e-3,
- place_on_top=False,
- )
- cell_instances = list(layout.CellInstances)
- assert len(cell_instances) == 1
- cell_instance = cell_instances[0]
- assert cell_instance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- local_origin,
- rotation_axis_from,
- rotation_axis_to,
- angle,
- loc,
- mirror,
- ) = cell_instance.Get3DTransformation()
- else:
- (
- res,
- local_origin,
- rotation_axis_from,
- rotation_axis_to,
- angle,
- loc,
- ) = cell_instance.Get3DTransformation()
- assert res
- zero_value = laminate_edb.edb_value(0)
- one_value = laminate_edb.edb_value(1)
- flip_angle_value = laminate_edb.edb_value("180deg")
- origin_point = laminate_edb.edb_api.geometry.point3d_data(zero_value, zero_value, zero_value)
- x_axis_point = laminate_edb.edb_api.geometry.point3d_data(one_value, zero_value, zero_value)
- assert local_origin.IsEqual(origin_point)
- assert rotation_axis_from.IsEqual(x_axis_point)
- assert rotation_axis_to.IsEqual(
- laminate_edb.edb_api.geometry.point3d_data(zero_value, laminate_edb.edb_value(-1.0), zero_value)
- )
- assert angle.IsEqual(flip_angle_value)
- assert loc.IsEqual(
- laminate_edb.edb_api.geometry.point3d_data(
- laminate_edb.edb_value(0.5e-3),
- laminate_edb.edb_value(-0.5e-3),
- zero_value,
- )
- )
- assert laminate_edb.save_edb()
- finally:
- laminate_edb.close()
-
- def test_stackup_properties_0(self):
- """Evaluate various stackup properties."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_0124.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- assert isinstance(edbapp.stackup.layers, dict)
- assert isinstance(edbapp.stackup.signal_layers, dict)
- assert isinstance(edbapp.stackup.dielectric_layers, dict)
- assert isinstance(edbapp.stackup.stackup_layers, dict)
- assert isinstance(edbapp.stackup.non_stackup_layers, dict)
- assert not edbapp.stackup["Outline"].is_stackup_layer
- assert edbapp.stackup["1_Top"].conductivity
- assert edbapp.stackup["DE1"].permittivity
- assert edbapp.stackup.add_layer("new_layer")
- new_layer = edbapp.stackup["new_layer"]
- assert new_layer.is_stackup_layer
- assert not new_layer.is_negative
- new_layer.name = "renamed_layer"
- assert new_layer.name == "renamed_layer"
- rename_layer = edbapp.stackup["renamed_layer"]
- rename_layer.thickness = 50e-6
- assert rename_layer.thickness == 50e-6
- rename_layer.etch_factor = 0
- rename_layer.etch_factor = 2
- assert rename_layer.etch_factor == 2
- assert rename_layer.material
- assert rename_layer.type
- assert rename_layer.dielectric_fill
-
- rename_layer.roughness_enabled = True
- assert rename_layer.roughness_enabled
- rename_layer.roughness_enabled = False
- assert not rename_layer.roughness_enabled
- assert rename_layer.assign_roughness_model("groisse", groisse_roughness="2um")
- assert rename_layer.assign_roughness_model(apply_on_surface="1_Top")
- assert rename_layer.assign_roughness_model(apply_on_surface="bottom")
- assert rename_layer.assign_roughness_model(apply_on_surface="side")
- assert edbapp.stackup.add_layer("new_above", "1_Top", "insert_above")
- assert edbapp.stackup.add_layer("new_below", "1_Top", "insert_below")
- assert edbapp.stackup.add_layer("new_bottom", "1_Top", "add_on_bottom", "dielectric")
- assert edbapp.stackup.remove_layer("new_bottom")
- assert "new_bottom" not in edbapp.stackup.layers
-
- assert edbapp.stackup["1_Top"].color
- edbapp.stackup["1_Top"].color = [0, 120, 0]
- assert edbapp.stackup["1_Top"].color == (0, 120, 0)
- edbapp.stackup["1_Top"].transparency = 10
- assert edbapp.stackup["1_Top"].transparency == 10
- assert edbapp.stackup.mode == "Laminate"
- edbapp.stackup.mode = "Overlapping"
- assert edbapp.stackup.mode == "Overlapping"
- edbapp.stackup.mode = "MultiZone"
- assert edbapp.stackup.mode == "MultiZone"
- edbapp.stackup.mode = "Overlapping"
- assert edbapp.stackup.mode == "Overlapping"
- assert edbapp.stackup.add_layer("new_bottom", "1_Top", "add_at_elevation", "dielectric", elevation=0.0003)
- edbapp.close()
-
- def test_stackup_properties_1(self):
- """Evaluate various stackup properties."""
- edbapp = EdbLegacy(edbversion=desktop_version)
- import_method = edbapp.stackup.load
- export_method = edbapp.stackup.export
-
- assert import_method(os.path.join(local_path, "example_models", test_subfolder, "ansys_pcb_stackup.xml"))
- assert "17_Bottom" in edbapp.stackup.layers.keys()
- xml_export = os.path.join(self.local_scratch.path, "stackup.xml")
- assert export_method(xml_export)
- assert os.path.exists(xml_export)
- assert import_method(os.path.join(local_path, "example_models", test_subfolder, "ansys_pcb_stackup.csv"))
- assert "18_Bottom" in edbapp.stackup.layers.keys()
- assert edbapp.stackup.add_layer("19_Bottom", None, "add_on_top", material="iron")
- export_stackup_path = os.path.join(self.local_scratch.path, "export_galileo_stackup.csv")
- assert export_method(export_stackup_path)
- assert os.path.exists(export_stackup_path)
-
- edbapp.close()
-
- def test_stackup_properties_2(self):
- """Evaluate various stackup properties."""
- edbapp = EdbLegacy(edbversion=desktop_version)
- import_method = edbapp.stackup.import_stackup
- export_method = edbapp.stackup.export_stackup
-
- assert import_method(os.path.join(local_path, "example_models", test_subfolder, "ansys_pcb_stackup.xml"))
- assert "17_Bottom" in edbapp.stackup.layers.keys()
- xml_export = os.path.join(self.local_scratch.path, "stackup.xml")
- assert export_method(xml_export)
- assert os.path.exists(xml_export)
- assert import_method(os.path.join(local_path, "example_models", test_subfolder, "ansys_pcb_stackup.csv"))
- assert "18_Bottom" in edbapp.stackup.layers.keys()
- assert edbapp.stackup.add_layer("19_Bottom", None, "add_on_top", material="iron")
- export_stackup_path = os.path.join(self.local_scratch.path, "export_galileo_stackup.csv")
- assert export_method(export_stackup_path)
- assert os.path.exists(export_stackup_path)
- edbapp.close()
-
- def test_stackup_layer_properties(self):
- """Evaluate various layer properties."""
- source_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- target_path = os.path.join(self.local_scratch.path, "test_0126.aedb")
- self.local_scratch.copyfolder(source_path, target_path)
- edbapp = EdbLegacy(target_path, edbversion=desktop_version)
- edbapp.stackup.load(os.path.join(local_path, "example_models", test_subfolder, "ansys_pcb_stackup.xml"))
- layer = edbapp.stackup["1_Top"]
- layer.name = "TOP"
- assert layer.name == "TOP"
- layer.type = "dielectric"
- assert layer.type == "dielectric"
- layer.type = "signal"
- layer.color = (0, 0, 0)
- assert layer.color == (0, 0, 0)
- layer.transparency = 0
- assert layer.transparency == 0
- layer.etch_factor = 2
- assert layer.etch_factor == 2
- layer.thickness = 50e-6
- assert layer.thickness == 50e-6
- assert layer.lower_elevation
- assert layer.upper_elevation
- layer.is_negative = True
- assert layer.is_negative
- assert not layer.is_via_layer
- assert layer.material == "copper"
- edbapp.close()
-
- def test_stackup_load(self):
- """Import stackup from a file."""
- import json
- fpath = os.path.join(local_path, "example_models", test_subfolder, "stackup.json")
- stackup_json = json.load(open(fpath, "r"))
-
- edbapp = EdbLegacy(edbversion=desktop_version)
- edbapp.stackup.load(fpath)
- edbapp.close()
-
- edbapp = EdbLegacy(edbversion=desktop_version)
- edbapp.stackup.load(stackup_json)
- edbapp.close()
-
- def test_stackup_place_in_3d_with_flipped_stackup(self):
- """Place into another cell using 3d placement method with and
- without flipping the current layer stackup.
- """
- edb_path = os.path.join(self.target_path2, "edb.def")
- edb1 = EdbLegacy(edb_path, edbversion=desktop_version)
-
- edb2 = EdbLegacy(self.target_path, edbversion=desktop_version)
- assert edb2.stackup.place_in_layout_3d_placement(
- edb1,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=False,
- place_on_top=False,
- solder_height=0.0,
- )
- edb2.close()
- edb2 = EdbLegacy(self.target_path, edbversion=desktop_version)
- assert edb2.stackup.place_in_layout_3d_placement(
- edb1,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=True,
- place_on_top=False,
- solder_height=0.0,
- )
- edb2.close()
- edb2 = EdbLegacy(self.target_path, edbversion=desktop_version)
- assert edb2.stackup.place_in_layout_3d_placement(
- edb1,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=False,
- place_on_top=True,
- solder_height=0.0,
- )
- edb2.close()
- edb2 = EdbLegacy(self.target_path, edbversion=desktop_version)
- assert edb2.stackup.place_in_layout_3d_placement(
- edb1,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=True,
- place_on_top=True,
- solder_height=0.0,
- )
- edb2.close()
- edb1.close()
-
- def test_stackup_place_instance_with_flipped_stackup(self):
- """Place into another cell using 3d placement method with and
- without flipping the current layer stackup.
- """
- edb_path = os.path.join(self.target_path2, "edb.def")
- edb1 = EdbLegacy(edb_path, edbversion=desktop_version)
-
- edb2 = EdbLegacy(self.target_path, edbversion=desktop_version)
- assert edb1.stackup.place_instance(
- edb2,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=False,
- place_on_top=False,
- solder_height=0.0,
- )
- assert edb1.stackup.place_instance(
- edb2,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=True,
- place_on_top=False,
- solder_height=0.0,
- )
- assert edb1.stackup.place_instance(
- edb2,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=False,
- place_on_top=True,
- solder_height=0.0,
- )
- assert edb1.stackup.place_instance(
- edb2,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=True,
- place_on_top=True,
- solder_height=0.0,
- )
- edb2.close()
- edb1.close()
-
- def test_stackup_place_in_layout_with_flipped_stackup(self):
- """Place into another cell using layer placement method with and
- without flipping the current layer stackup.
- """
- edb2 = EdbLegacy(self.target_path, edbversion=desktop_version)
- assert edb2.stackup.place_in_layout(
- self.edbapp,
- angle=0.0,
- offset_x="41.783mm",
- offset_y="35.179mm",
- flipped_stackup=True,
- place_on_top=True,
- )
- edb2.close()
-
- def test_stackup_place_on_top_of_lam_with_mold(self):
- """Place on top lam with mold using 3d placement method"""
- laminateEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "lam_with_mold.aedb"),
- edbversion=desktop_version,
- )
- chipEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "chip.aedb"),
- edbversion=desktop_version,
- )
- try:
- cellInstances = laminateEdb.layout.cell_instances
- assert len(cellInstances) == 0
- assert chipEdb.stackup.place_in_layout_3d_placement(
- laminateEdb,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- flipped_stackup=False,
- place_on_top=True,
- )
- merged_cell = chipEdb.edb_api.cell.cell.FindByName(
- chipEdb.active_db, chipEdb.edb_api.cell.CellType.CircuitCell, "lam_with_mold"
- )
- assert not merged_cell.IsNull()
- layout = merged_cell.GetLayout()
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 1
- cellInstance = cellInstances[0]
- assert cellInstance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- _,
- ) = cellInstance.Get3DTransformation()
- else:
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- ) = cellInstance.Get3DTransformation()
- assert res
- zeroValue = chipEdb.edb_value(0)
- originPoint = chipEdb.point_3d(0.0, 0.0, 0.0)
- xAxisPoint = chipEdb.point_3d(1.0, 0.0, 0.0)
- assert localOrigin.IsEqual(originPoint)
- assert rotAxisFrom.IsEqual(xAxisPoint)
- assert rotAxisTo.IsEqual(xAxisPoint)
- assert angle.IsEqual(zeroValue)
- assert loc.IsEqual(chipEdb.point_3d(0.0, 0.0, chipEdb.edb_value(170e-6)))
- finally:
- chipEdb.close()
- laminateEdb.close()
-
- def test_stackup_place_on_bottom_of_lam_with_mold(self):
- """Place on lam with mold using 3d placement method"""
-
- laminateEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "lam_with_mold.aedb"),
- edbversion=desktop_version,
- )
- chipEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "chip_flipped_stackup.aedb"),
- edbversion=desktop_version,
- )
- try:
- layout = laminateEdb.active_layout
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 0
- assert chipEdb.stackup.place_in_layout_3d_placement(
- laminateEdb,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- flipped_stackup=False,
- place_on_top=False,
- )
- merged_cell = chipEdb.edb_api.cell.cell.FindByName(
- chipEdb.active_db, chipEdb.edb_api.cell.CellType.CircuitCell, "lam_with_mold"
- )
- assert not merged_cell.IsNull()
- layout = merged_cell.GetLayout()
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 1
- cellInstance = cellInstances[0]
- assert cellInstance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- _,
- ) = cellInstance.Get3DTransformation()
- else:
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- ) = cellInstance.Get3DTransformation()
- assert res
- zeroValue = chipEdb.edb_value(0)
- originPoint = chipEdb.point_3d(0.0, 0.0, 0.0)
- xAxisPoint = chipEdb.point_3d(1.0, 0.0, 0.0)
- assert localOrigin.IsEqual(originPoint)
- assert rotAxisFrom.IsEqual(xAxisPoint)
- assert rotAxisTo.IsEqual(xAxisPoint)
- assert angle.IsEqual(zeroValue)
- assert loc.IsEqual(chipEdb.point_3d(0.0, 0.0, chipEdb.edb_value(-90e-6)))
- finally:
- chipEdb.close()
- laminateEdb.close()
-
- def test_stackup_place_on_top_of_lam_with_mold_solder(self):
- """Place on top of lam with mold solder using 3d placement method."""
- laminateEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "lam_with_mold.aedb"),
- edbversion=desktop_version,
- )
- chipEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "chip_solder.aedb"),
- edbversion=desktop_version,
- )
- try:
- layout = laminateEdb.active_layout
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 0
- assert chipEdb.stackup.place_in_layout_3d_placement(
- laminateEdb,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- flipped_stackup=False,
- place_on_top=True,
- )
- merged_cell = chipEdb.edb_api.cell.cell.FindByName(
- chipEdb.active_db, chipEdb.edb_api.cell.CellType.CircuitCell, "lam_with_mold"
- )
- assert not merged_cell.IsNull()
- layout = merged_cell.GetLayout()
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 1
- cellInstance = cellInstances[0]
- assert cellInstance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- _,
- ) = cellInstance.Get3DTransformation()
- else:
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- ) = cellInstance.Get3DTransformation()
- assert res
- zeroValue = chipEdb.edb_value(0)
- oneValue = chipEdb.edb_value(1)
- originPoint = chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, zeroValue)
- xAxisPoint = chipEdb.edb_api.geometry.point3d_data(oneValue, zeroValue, zeroValue)
- assert localOrigin.IsEqual(originPoint)
- assert rotAxisFrom.IsEqual(xAxisPoint)
- assert rotAxisTo.IsEqual(xAxisPoint)
- assert angle.IsEqual(zeroValue)
- assert loc.IsEqual(chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, chipEdb.edb_value(190e-6)))
- finally:
- chipEdb.close()
- laminateEdb.close()
-
- def test_stackup_place_on_bottom_of_lam_with_mold_solder(self):
- """Place on bottom of lam with mold solder using 3d placement method."""
-
- laminateEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "lam_with_mold.aedb"),
- edbversion=desktop_version,
- )
- chipEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "chip_solder.aedb"),
- edbversion=desktop_version,
- )
- try:
- layout = laminateEdb.active_layout
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 0
- assert chipEdb.stackup.place_in_layout_3d_placement(
- laminateEdb,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- flipped_stackup=True,
- place_on_top=False,
- )
- merged_cell = chipEdb.edb_api.cell.cell.FindByName(
- chipEdb.active_db, chipEdb.edb_api.cell.CellType.CircuitCell, "lam_with_mold"
- )
- assert not merged_cell.IsNull()
- layout = merged_cell.GetLayout()
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 1
- cellInstance = cellInstances[0]
- assert cellInstance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- _,
- ) = cellInstance.Get3DTransformation()
- else:
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- ) = cellInstance.Get3DTransformation()
- assert res
- zeroValue = chipEdb.edb_value(0)
- oneValue = chipEdb.edb_value(1)
- originPoint = chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, zeroValue)
- xAxisPoint = chipEdb.edb_api.geometry.point3d_data(oneValue, zeroValue, zeroValue)
- assert localOrigin.IsEqual(originPoint)
- assert rotAxisFrom.IsEqual(xAxisPoint)
- assert rotAxisTo.IsEqual(xAxisPoint)
- assert angle.IsEqual(chipEdb.edb_value(math.pi))
- assert loc.IsEqual(chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, chipEdb.edb_value(-20e-6)))
- finally:
- chipEdb.close()
- laminateEdb.close()
-
- def test_stackup_place_on_top_with_zoffset_chip(self):
- """Place on top of lam with mold chip zoffset using 3d placement method."""
- laminateEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "lam_with_mold.aedb"),
- edbversion=desktop_version,
- )
- chipEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "chip_zoffset.aedb"),
- edbversion=desktop_version,
- )
- try:
- layout = laminateEdb.active_layout
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 0
- assert chipEdb.stackup.place_in_layout_3d_placement(
- laminateEdb,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- flipped_stackup=False,
- place_on_top=True,
- )
- merged_cell = chipEdb.edb_api.cell.cell.FindByName(
- chipEdb.active_db, chipEdb.edb_api.cell.CellType.CircuitCell, "lam_with_mold"
- )
- assert not merged_cell.IsNull()
- layout = merged_cell.GetLayout()
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 1
- cellInstance = cellInstances[0]
- assert cellInstance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- _,
- ) = cellInstance.Get3DTransformation()
- else:
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- ) = cellInstance.Get3DTransformation()
- assert res
- zeroValue = chipEdb.edb_value(0)
- oneValue = chipEdb.edb_value(1)
- originPoint = chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, zeroValue)
- xAxisPoint = chipEdb.edb_api.geometry.point3d_data(oneValue, zeroValue, zeroValue)
- assert localOrigin.IsEqual(originPoint)
- assert rotAxisFrom.IsEqual(xAxisPoint)
- assert rotAxisTo.IsEqual(xAxisPoint)
- assert angle.IsEqual(zeroValue)
- assert loc.IsEqual(chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, chipEdb.edb_value(160e-6)))
- finally:
- chipEdb.close()
- laminateEdb.close()
-
- def test_stackup_place_on_bottom_with_zoffset_chip(self):
- """Place on bottom of lam with mold chip zoffset using 3d placement method."""
-
- laminateEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "lam_with_mold.aedb"),
- edbversion=desktop_version,
- )
- chipEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "chip_zoffset.aedb"),
- edbversion=desktop_version,
- )
- try:
- layout = laminateEdb.active_layout
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 0
- assert chipEdb.stackup.place_in_layout_3d_placement(
- laminateEdb,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- flipped_stackup=True,
- place_on_top=False,
- )
- merged_cell = chipEdb.edb_api.cell.cell.FindByName(
- chipEdb.active_db, chipEdb.edb_api.cell.CellType.CircuitCell, "lam_with_mold"
- )
- assert not merged_cell.IsNull()
- layout = merged_cell.GetLayout()
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 1
- cellInstance = cellInstances[0]
- assert cellInstance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- _,
- ) = cellInstance.Get3DTransformation()
- else:
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- ) = cellInstance.Get3DTransformation()
- assert res
- zeroValue = chipEdb.edb_value(0)
- oneValue = chipEdb.edb_value(1)
- originPoint = chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, zeroValue)
- xAxisPoint = chipEdb.edb_api.geometry.point3d_data(oneValue, zeroValue, zeroValue)
- assert localOrigin.IsEqual(originPoint)
- assert rotAxisFrom.IsEqual(xAxisPoint)
- assert rotAxisTo.IsEqual(xAxisPoint)
- assert angle.IsEqual(chipEdb.edb_value(math.pi))
- assert loc.IsEqual(chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, chipEdb.edb_value(10e-6)))
- finally:
- chipEdb.close()
- laminateEdb.close()
-
- def test_stackup_place_on_top_with_zoffset_solder_chip(self):
- """Place on top of lam with mold chip zoffset using 3d placement method."""
- laminateEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "lam_with_mold.aedb"),
- edbversion=desktop_version,
- )
- chipEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "chip_zoffset_solder.aedb"),
- edbversion=desktop_version,
- )
- try:
- layout = laminateEdb.active_layout
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 0
- assert chipEdb.stackup.place_in_layout_3d_placement(
- laminateEdb,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- flipped_stackup=False,
- place_on_top=True,
- )
- merged_cell = chipEdb.edb_api.cell.cell.FindByName(
- chipEdb.active_db, chipEdb.edb_api.cell.CellType.CircuitCell, "lam_with_mold"
- )
- assert not merged_cell.IsNull()
- layout = merged_cell.GetLayout()
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 1
- cellInstance = cellInstances[0]
- assert cellInstance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- _,
- ) = cellInstance.Get3DTransformation()
- else:
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- ) = cellInstance.Get3DTransformation()
- assert res
- zeroValue = chipEdb.edb_value(0)
- oneValue = chipEdb.edb_value(1)
- originPoint = chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, zeroValue)
- xAxisPoint = chipEdb.edb_api.geometry.point3d_data(oneValue, zeroValue, zeroValue)
- assert localOrigin.IsEqual(originPoint)
- assert rotAxisFrom.IsEqual(xAxisPoint)
- assert rotAxisTo.IsEqual(xAxisPoint)
- assert angle.IsEqual(zeroValue)
- assert loc.IsEqual(chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, chipEdb.edb_value(150e-6)))
- finally:
- chipEdb.close()
- laminateEdb.close()
-
- def test_stackup_place_on_bottom_with_zoffset_solder_chip(self):
- """Place on bottom of lam with mold chip zoffset using 3d placement method."""
-
- laminateEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "lam_with_mold.aedb"),
- edbversion=desktop_version,
- )
- chipEdb = EdbLegacy(
- os.path.join(local_path, "example_models", test_subfolder, "chip_zoffset_solder.aedb"),
- edbversion=desktop_version,
- )
- try:
- layout = laminateEdb.active_layout
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 0
- assert chipEdb.stackup.place_in_layout_3d_placement(
- laminateEdb,
- angle=0.0,
- offset_x=0.0,
- offset_y=0.0,
- flipped_stackup=True,
- place_on_top=False,
- )
- merged_cell = chipEdb.edb_api.cell.cell.FindByName(
- chipEdb.active_db, chipEdb.edb_api.cell.CellType.CircuitCell, "lam_with_mold"
- )
- assert not merged_cell.IsNull()
- layout = merged_cell.GetLayout()
- cellInstances = list(layout.CellInstances)
- assert len(cellInstances) == 1
- cellInstance = cellInstances[0]
- assert cellInstance.Is3DPlacement()
- if desktop_version > "2023.1":
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- _,
- ) = cellInstance.Get3DTransformation()
- else:
- (
- res,
- localOrigin,
- rotAxisFrom,
- rotAxisTo,
- angle,
- loc,
- ) = cellInstance.Get3DTransformation()
- assert res
- zeroValue = chipEdb.edb_value(0)
- oneValue = chipEdb.edb_value(1)
- originPoint = chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, zeroValue)
- xAxisPoint = chipEdb.edb_api.geometry.point3d_data(oneValue, zeroValue, zeroValue)
- assert localOrigin.IsEqual(originPoint)
- assert rotAxisFrom.IsEqual(xAxisPoint)
- assert rotAxisTo.IsEqual(xAxisPoint)
- assert angle.IsEqual(chipEdb.edb_value(math.pi))
- assert loc.IsEqual(chipEdb.edb_api.geometry.point3d_data(zeroValue, zeroValue, chipEdb.edb_value(20e-6)))
- finally:
- chipEdb.close()
- laminateEdb.close()
-
- def test_18_stackup(self):
- def validate_material(pedb_materials, material, delta):
- pedb_mat = pedb_materials[material["name"]]
- if not material["dielectric_model_frequency"]:
- assert (pedb_mat.conductivity - material["conductivity"]) < delta
- assert (pedb_mat.permittivity - material["permittivity"]) < delta
- assert (pedb_mat.loss_tangent - material["loss_tangent"]) < delta
- assert (pedb_mat.permeability - material["permeability"]) < delta
- assert (pedb_mat.magnetic_loss_tangent - material["magnetic_loss_tangent"]) < delta
- assert (pedb_mat.mass_density - material["mass_density"]) < delta
- assert (pedb_mat.poisson_ratio - material["poisson_ratio"]) < delta
- assert (pedb_mat.specific_heat - material["specific_heat"]) < delta
- assert (pedb_mat.thermal_conductivity - material["thermal_conductivity"]) < delta
- assert (pedb_mat.youngs_modulus - material["youngs_modulus"]) < delta
- assert (pedb_mat.thermal_expansion_coefficient - material["thermal_expansion_coefficient"]) < delta
- if material["dc_conductivity"] is not None:
- assert (pedb_mat.dc_conductivity - material["dc_conductivity"]) < delta
- else:
- assert pedb_mat.dc_conductivity == material["dc_conductivity"]
- if material["dc_permittivity"] is not None:
- assert (pedb_mat.dc_permittivity - material["dc_permittivity"]) < delta
- else:
- assert pedb_mat.dc_permittivity == material["dc_permittivity"]
- if material["dielectric_model_frequency"] is not None:
- assert (pedb_mat.dielectric_model_frequency - material["dielectric_model_frequency"]) < delta
- else:
- assert pedb_mat.dielectric_model_frequency == material["dielectric_model_frequency"]
- if material["loss_tangent_at_frequency"] is not None:
- assert (pedb_mat.loss_tangent_at_frequency - material["loss_tangent_at_frequency"]) < delta
- else:
- assert pedb_mat.loss_tangent_at_frequency == material["loss_tangent_at_frequency"]
- if material["permittivity_at_frequency"] is not None:
- assert (pedb_mat.permittivity_at_frequency - material["permittivity_at_frequency"]) < delta
- else:
- assert pedb_mat.permittivity_at_frequency == material["permittivity_at_frequency"]
- return 0
- import json
-
- target_path = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1.aedb")
- out_edb = os.path.join(self.local_scratch.path, "ANSYS-HSD_V1_test.aedb")
- self.local_scratch.copyfolder(target_path, out_edb)
- json_path = os.path.join(local_path, "example_models", test_subfolder, "test_mat.json")
- edbapp = EdbLegacy(out_edb, edbversion=desktop_version)
- edbapp.stackup.import_stackup(json_path)
- edbapp.save_edb()
- delta = 1e-6
- f = open(json_path)
- json_dict = json.load(f)
- for k, v in json_dict.items():
- if k == "materials":
- for material in v.values():
- assert 0 == validate_material(edbapp.materials, material, delta)
- for k, v in json_dict.items():
- if k == "layers":
- for layer_name, layer in v.items():
- pedb_lay = edbapp.stackup.layers[layer_name]
- assert list(pedb_lay.color) == layer["color"]
- assert pedb_lay.type == layer["type"]
- if isinstance(layer["material"], str):
- assert pedb_lay.material == layer["material"]
- else:
- assert 0 == validate_material(edbapp.materials, layer["material"], delta)
- if isinstance(layer["dielectric_fill"], str) or layer["dielectric_fill"] is None:
- assert pedb_lay.dielectric_fill == layer["dielectric_fill"]
- else:
- assert 0 == validate_material(edbapp.materials, layer["dielectric_fill"], delta)
- assert (pedb_lay.thickness - layer["thickness"]) < delta
- assert (pedb_lay.etch_factor - layer["etch_factor"]) < delta
- assert pedb_lay.roughness_enabled == layer["roughness_enabled"]
- if layer["roughness_enabled"]:
- assert (pedb_lay.top_hallhuray_nodule_radius - layer["top_hallhuray_nodule_radius"]) < delta
- assert (pedb_lay.top_hallhuray_surface_ratio - layer["top_hallhuray_surface_ratio"]) < delta
- assert (
- pedb_lay.bottom_hallhuray_nodule_radius - layer["bottom_hallhuray_nodule_radius"]
- ) < delta
- assert (
- pedb_lay.bottom_hallhuray_surface_ratio - layer["bottom_hallhuray_surface_ratio"]
- ) < delta
- assert (pedb_lay.side_hallhuray_nodule_radius - layer["side_hallhuray_nodule_radius"]) < delta
- assert (pedb_lay.side_hallhuray_surface_ratio - layer["side_hallhuray_surface_ratio"]) < delta
- edbapp.close()
- edbapp = EdbLegacy(edbversion=desktop_version)
- json_path = os.path.join(local_path, "example_models", test_subfolder, "test_mat2.json")
- assert edbapp.stackup.import_stackup(json_path)
- assert "SOLDER" in edbapp.stackup.stackup_layers
- edbapp.close()
diff --git a/tests/grpc/unit/test_edb.py b/tests/grpc/unit/test_edb.py
index 34af88e9d0..b96e9710e5 100644
--- a/tests/grpc/unit/test_edb.py
+++ b/tests/grpc/unit/test_edb.py
@@ -2,7 +2,12 @@
import pytest
from tests.conftest import desktop_version
-from pyedb.grpc.edb import EdbGrpc
+try:
+ from pyedb.grpc.edb import EdbGrpc
+except ImportError:
+ def pytest_collection_modifyitems(items, config):
+ for item in items:
+ item.add_marker(pytest.mark.xfail)
pytestmark = [pytest.mark.unit, pytest.mark.grpc]
diff --git a/tests/grpc/unit/test_edbsiwave.py b/tests/grpc/unit/test_edbsiwave.py
index 8925aa3421..f38b1ee890 100644
--- a/tests/grpc/unit/test_edbsiwave.py
+++ b/tests/grpc/unit/test_edbsiwave.py
@@ -1,7 +1,13 @@
import os
import pytest
from mock import Mock
-from pyedb.grpc.siwave import EdbSiwave
+
+try:
+ from pyedb.grpc.siwave import EdbSiwave
+except ImportError:
+ def pytest_collection_modifyitems(items, config):
+ for item in items:
+ item.add_marker(pytest.mark.xfail)
pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.grpc]
diff --git a/tests/grpc/unit/test_materials.py b/tests/grpc/unit/test_materials.py
index 2e56888d1f..eb99903c13 100644
--- a/tests/grpc/unit/test_materials.py
+++ b/tests/grpc/unit/test_materials.py
@@ -2,9 +2,15 @@
from unittest.mock import mock_open
import pytest
from mock import patch, MagicMock
-from pyedb.grpc.materials import Materials
-pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.legacy]
+try:
+ from pyedb.grpc.materials import Materials
+except ImportError:
+ def pytest_collection_modifyitems(items, config):
+ for item in items:
+ item.add_marker(pytest.mark.xfail)
+
+pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.grpc]
MATERIALS = """
$begin 'Polyflon CuFlon (tm)'
diff --git a/tests/grpc/unit/test_padstack.py b/tests/grpc/unit/test_padstack.py
index 6c7d9e431b..2788074486 100644
--- a/tests/grpc/unit/test_padstack.py
+++ b/tests/grpc/unit/test_padstack.py
@@ -1,8 +1,14 @@
import pytest
from mock import PropertyMock, patch, MagicMock
-from pyedb.grpc.padstack import EdbPadstacks
-pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.legacy]
+try:
+ from pyedb.grpc.padstack import EdbPadstacks
+except ImportError:
+ def pytest_collection_modifyitems(items, config):
+ for item in items:
+ item.add_marker(pytest.mark.xfail)
+
+pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.grpc]
class TestClass:
@pytest.fixture(autouse=True)
diff --git a/tests/grpc/unit/test_simulation_configuration.py b/tests/grpc/unit/test_simulation_configuration.py
index 02586fbdf8..2dfbd8aac9 100644
--- a/tests/grpc/unit/test_simulation_configuration.py
+++ b/tests/grpc/unit/test_simulation_configuration.py
@@ -1,9 +1,15 @@
import os
from pyedb.generic.constants import SourceType
-from pyedb.legacy.edb_core.edb_data.simulation_configuration import SimulationConfiguration
import pytest
-pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.legacy]
+try:
+ from pyedb.grpc.edb_core.edb_data.simulation_configuration import SimulationConfiguration
+except ImportError:
+ def pytest_collection_modifyitems(items, config):
+ for item in items:
+ item.add_marker(pytest.mark.xfail)
+
+pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.grpc]
class TestClass:
@pytest.fixture(autouse=True)
diff --git a/tests/grpc/unit/test_source.py b/tests/grpc/unit/test_source.py
index 611e18d496..1cf243899a 100644
--- a/tests/grpc/unit/test_source.py
+++ b/tests/grpc/unit/test_source.py
@@ -1,9 +1,13 @@
-import os
-from pyedb.legacy.edb_core.edb_data.simulation_configuration import SimulationConfiguration
-from pyedb.legacy.edb_core.edb_data.sources import Source
import pytest
-pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.legacy]
+try:
+ from pyedb.legacy.edb_core.edb_data.sources import Source
+except ImportError:
+ def pytest_collection_modifyitems(items, config):
+ for item in items:
+ item.add_marker(pytest.mark.xfail)
+
+pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.grpc]
class TestClass:
# @pytest.fixture(autouse=True)
diff --git a/tests/grpc/unit/test_stackup.py b/tests/grpc/unit/test_stackup.py
index eb01a591fb..a8e0f0223c 100644
--- a/tests/grpc/unit/test_stackup.py
+++ b/tests/grpc/unit/test_stackup.py
@@ -1,8 +1,14 @@
import pytest
from mock import PropertyMock, patch, MagicMock
-from pyedb.legacy.edb_core.stackup import Stackup
-pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.legacy]
+try:
+ from pyedb.legacy.edb_core.stackup import Stackup
+except ImportError:
+ def pytest_collection_modifyitems(items, config):
+ for item in items:
+ item.add_marker(pytest.mark.xfail)
+
+pytestmark = [pytest.mark.unit, pytest.mark.no_licence, pytest.mark.grpc]
class TestClass:
@pytest.fixture(autouse=True)
diff --git a/tests/legacy/system/conftest.py b/tests/legacy/system/conftest.py
index 41826fbe51..87ce454563 100644
--- a/tests/legacy/system/conftest.py
+++ b/tests/legacy/system/conftest.py
@@ -1,38 +1,57 @@
"""
"""
-import sys
-import os
+import os
+from os.path import dirname
import pytest
-
-# from pyedb import Edb
-# from pyedb.legacy.edb_core.components import resistor_value_parser
-# from pyedb.legacy.edb_core.edb_data.edbvalue import EdbValue
-# from pyedb.legacy.edb_core.edb_data.simulation_configuration import SimulationConfiguration
-# from pyedb.legacy.edb_core.edb_data.sources import Source
-# from pyedb.generic.constants import RadiationBoxType
-# from pyedb.generic.general_methods import check_numeric_equivalence
-
-# from pyedb.generic.constants import SolverType
-# from pyedb.generic.constants import SourceType
-# from tests.conftest import config
from tests.conftest import local_path
-# from tests.conftest import edb_version
+
+from pyedb.legacy.edb import EdbLegacy
+from pyedb.generic.general_methods import generate_unique_name
+from pyedb.misc.misc import list_installed_ansysem
+
+example_models_path = os.path.join(
+ dirname(dirname(dirname(os.path.realpath(__file__)))), "example_models")
+
+# Initialize default desktop configuration
+desktop_version = "2023.2"
+if "ANSYSEM_ROOT{}".format(desktop_version[2:].replace(".", "")) not in list_installed_ansysem():
+ desktop_version = list_installed_ansysem()[0][12:].replace(".", "")
+ desktop_version = "20{}.{}".format(desktop_version[:2], desktop_version[-1])
test_subfolder = "TEDB"
test_project_name = "ANSYS-HSD_V1"
bom_example = "bom_example.csv"
+@pytest.fixture(scope="module")
+def add_legacy_edb(local_scratch):
+ def _method(project_name=None, subfolder=""):
+ if project_name:
+ example_folder = os.path.join(example_models_path, subfolder, project_name + ".aedb")
+ if os.path.exists(example_folder):
+ target_folder = os.path.join(local_scratch.path, project_name + ".aedb")
+ local_scratch.copyfolder(example_folder, target_folder)
+ else:
+ target_folder = os.path.join(local_scratch.path, project_name + ".aedb")
+ else:
+ target_folder = os.path.join(local_scratch.path, generate_unique_name("TestEdb") + ".aedb")
+ return EdbLegacy(
+ target_folder,
+ edbversion=desktop_version,
+ )
+
+ return _method
+
@pytest.fixture(scope="class")
-def edbapp(add_edb):
- app = add_edb(test_project_name, subfolder=test_subfolder)
+def legacy_edb_app(add_legacy_edb):
+ app = add_legacy_edb(test_project_name, subfolder=test_subfolder)
return app
@pytest.fixture(scope="class", autouse=True)
def target_path(local_scratch):
- example_project = os.path.join(local_path, "example_models", test_subfolder, "example_package.aedb")
+ example_project = os.path.join(example_models_path, test_subfolder, "example_package.aedb")
target_path = os.path.join(local_scratch.path, "example_package.aedb")
local_scratch.copyfolder(example_project, target_path)
return target_path
@@ -40,14 +59,14 @@ def target_path(local_scratch):
@pytest.fixture(scope="class", autouse=True)
def target_path2(local_scratch):
- example_project2 = os.path.join(local_path, "example_models", test_subfolder, "simple.aedb")
+ example_project2 = os.path.join(example_models_path, test_subfolder, "simple.aedb")
target_path2 = os.path.join(local_scratch.path, "simple_00.aedb")
local_scratch.copyfolder(example_project2, target_path2)
return target_path2
@pytest.fixture(scope="class", autouse=True)
def target_path3(local_scratch):
- example_project3 = os.path.join(local_path, "example_models", test_subfolder, "ANSYS-HSD_V1_cut.aedb")
+ example_project3 = os.path.join(example_models_path, test_subfolder, "ANSYS-HSD_V1_cut.aedb")
target_path3 = os.path.join(local_scratch.path, "test_plot.aedb")
local_scratch.copyfolder(example_project3, target_path3)
return target_path3
@@ -55,7 +74,7 @@ def target_path3(local_scratch):
@pytest.fixture(scope="class", autouse=True)
def target_path4(local_scratch):
- example_project4 = os.path.join(local_path, "example_models", test_subfolder, "Package.aedb")
+ example_project4 = os.path.join(example_models_path, test_subfolder, "Package.aedb")
target_path4 = os.path.join(local_scratch.path, "Package_00.aedb")
local_scratch.copyfolder(example_project4, target_path4)
return target_path4
diff --git a/tests/legacy/system/test_edb.py b/tests/legacy/system/test_edb.py
index 0c05a66989..d752e81d2c 100644
--- a/tests/legacy/system/test_edb.py
+++ b/tests/legacy/system/test_edb.py
@@ -18,8 +18,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/legacy/system/test_edb_components.py b/tests/legacy/system/test_edb_components.py
index 20d5268cb9..e264747f4e 100644
--- a/tests/legacy/system/test_edb_components.py
+++ b/tests/legacy/system/test_edb_components.py
@@ -17,8 +17,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/legacy/system/test_edb_differential_pairs.py b/tests/legacy/system/test_edb_differential_pairs.py
index fc4ad2c77c..2bcb2b5dce 100644
--- a/tests/legacy/system/test_edb_differential_pairs.py
+++ b/tests/legacy/system/test_edb_differential_pairs.py
@@ -7,8 +7,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/legacy/system/test_edb_extended_nets.py b/tests/legacy/system/test_edb_extended_nets.py
index 1b7eaa62c6..c9b16452a5 100644
--- a/tests/legacy/system/test_edb_extended_nets.py
+++ b/tests/legacy/system/test_edb_extended_nets.py
@@ -7,8 +7,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/legacy/system/test_edb_ipc.py b/tests/legacy/system/test_edb_ipc.py
index 940307e2b4..8f87f48c4d 100644
--- a/tests/legacy/system/test_edb_ipc.py
+++ b/tests/legacy/system/test_edb_ipc.py
@@ -13,8 +13,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/legacy/system/test_edb_materials.py b/tests/legacy/system/test_edb_materials.py
index 54eb13eb96..17ddd19d48 100644
--- a/tests/legacy/system/test_edb_materials.py
+++ b/tests/legacy/system/test_edb_materials.py
@@ -14,8 +14,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
def test_material_properties(self):
diff --git a/tests/legacy/system/test_edb_modeler.py b/tests/legacy/system/test_edb_modeler.py
index b6f35ddf2e..ec1907a9de 100644
--- a/tests/legacy/system/test_edb_modeler.py
+++ b/tests/legacy/system/test_edb_modeler.py
@@ -11,8 +11,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/legacy/system/test_edb_net_classes.py b/tests/legacy/system/test_edb_net_classes.py
index e5df180f8f..a70bf78469 100644
--- a/tests/legacy/system/test_edb_net_classes.py
+++ b/tests/legacy/system/test_edb_net_classes.py
@@ -7,8 +7,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/legacy/system/test_edb_nets.py b/tests/legacy/system/test_edb_nets.py
index bf15e79135..a7fb20a84d 100644
--- a/tests/legacy/system/test_edb_nets.py
+++ b/tests/legacy/system/test_edb_nets.py
@@ -12,8 +12,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2
diff --git a/tests/legacy/system/test_edb_padstacks.py b/tests/legacy/system/test_edb_padstacks.py
index effdee566f..b3e5d95948 100644
--- a/tests/legacy/system/test_edb_padstacks.py
+++ b/tests/legacy/system/test_edb_padstacks.py
@@ -13,8 +13,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path3, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path3, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path3 = target_path3
diff --git a/tests/legacy/system/test_edb_stackup.py b/tests/legacy/system/test_edb_stackup.py
index a6a8826307..6b90578ac4 100644
--- a/tests/legacy/system/test_edb_stackup.py
+++ b/tests/legacy/system/test_edb_stackup.py
@@ -13,8 +13,8 @@
class TestClass:
@pytest.fixture(autouse=True)
- def init(self, edbapp, local_scratch, target_path, target_path2, target_path4):
- self.edbapp = edbapp
+ def init(self, legacy_edb_app, local_scratch, target_path, target_path2, target_path4):
+ self.edbapp = legacy_edb_app
self.local_scratch = local_scratch
self.target_path = target_path
self.target_path2 = target_path2