Skip to content

Commit

Permalink
REFACTOR: Pathlib refactor: circuit.py (#5842)
Browse files Browse the repository at this point in the history
Co-authored-by: Sébastien Morais <[email protected]>
Co-authored-by: pyansys-ci-bot <[email protected]>
Co-authored-by: Samuelopez-ansys <[email protected]>
  • Loading branch information
4 people authored Mar 7, 2025
1 parent cf1d873 commit 6dc4852
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 97 deletions.
1 change: 1 addition & 0 deletions doc/changelog.d/5842.miscellaneous.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pathlib refactor: circuit.py
3 changes: 3 additions & 0 deletions src/ansys/aedt/core/application/analysis_hf.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ def export_touchstone(
----------
>>> oDesign.ExportNetworkData
"""
if output_file is not None:
output_file = str(output_file)

return self._app._export_touchstone(
setup_name=setup,
sweep_name=sweep,
Expand Down
102 changes: 51 additions & 51 deletions src/ansys/aedt/core/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

import io
import math
import os
from pathlib import Path
import re
import shutil
Expand Down Expand Up @@ -453,7 +452,7 @@ def get_ibis_model_from_file(self, input_file, is_ami=False):
Parameters
----------
input_file : str
input_file : str or :class:`pathlib.Path`
Path of the IBIS file.
is_ami : bool, optional
Whether the file to import is an IBIS AMI file. The
Expand All @@ -465,9 +464,9 @@ def get_ibis_model_from_file(self, input_file, is_ami=False):
IBIS object exposing all data from the IBIS file.
"""
if is_ami:
reader = ibis_reader.AMIReader(input_file, self)
reader = ibis_reader.AMIReader(str(input_file), self)
else:
reader = ibis_reader.IbisReader(input_file, self)
reader = ibis_reader.IbisReader(str(input_file), self)
reader.parse_ibis_file()
return reader.ibis_model

Expand Down Expand Up @@ -862,7 +861,7 @@ def export_fullwave_spice(
Name of the setup if it is a design. The default is ``None``.
is_solution_file : bool, optional
Whether it is an imported solution file. The default is ``False``.
filename : str, optional
filename : str or :class:`pathlib.Path`, optional
Full path and name for exporting the HSpice file.
The default is ``None``, in which case the file is exported to the working directory.
passivity : bool, optional
Expand Down Expand Up @@ -891,13 +890,14 @@ def export_fullwave_spice(
if not design:
design = self.design_name
if not filename:
filename = os.path.join(self.working_directory, self.design_name + ".sp")
filename = Path(self.working_directory) / f"{self.design_name}.sp"
if is_solution_file:
setup = design
design = ""
else:
if not setup:
setup = self.nominal_sweep
file_path = Path(filename)
self.onetwork_data_explorer.ExportFullWaveSpice(
design,
is_solution_file,
Expand Down Expand Up @@ -945,11 +945,11 @@ def export_fullwave_spice(
"SYZDataInAutoMode:=",
False,
"ExportDirectory:=",
os.path.dirname(filename) + "\\",
str(file_path.parent) + "\\",
"ExportSpiceFileName:=",
os.path.basename(filename),
file_path.name,
"FullwaveSpiceFileName:=",
os.path.basename(filename),
file_path.name,
"UseMultipleCores:=",
True,
"NumberOfCores:=",
Expand Down Expand Up @@ -1247,7 +1247,7 @@ def assign_voltage_frequency_dependent_excitation_to_ports(self, ports, input_fi
----------
ports : list
List of circuit ports to assign to the frequency dependent excitation.
input_file : str
input_file : str or :class:`pathlib.Path`
Path to the frequency dependent file.
Returns
Expand All @@ -1259,7 +1259,7 @@ def assign_voltage_frequency_dependent_excitation_to_ports(self, ports, input_fi
----------
>>> oDesign.UpdateSources
"""
if not os.path.exists(input_file) or os.path.splitext(input_file)[1] != ".fds":
if not Path(input_file).exists() or Path(input_file).suffix != ".fds":
self.logger.error("Introduced file is not correct. Check path and format.")
return False

Expand Down Expand Up @@ -1348,9 +1348,9 @@ def set_differential_pair(
arg.append("Pair:=")
arg.append(arg1)

tmpfile1 = os.path.join(self.working_directory, generate_unique_name("tmp"))
self.odesign.SaveDiffPairsToFile(tmpfile1)
with open_file(tmpfile1, "r") as fh:
tmpfile1 = Path(self.working_directory) / generate_unique_name("tmp")
self.odesign.SaveDiffPairsToFile(str(tmpfile1))
with open_file(str(tmpfile1), "r") as fh:
lines = fh.read().splitlines()

old_arg = []
Expand Down Expand Up @@ -1381,7 +1381,7 @@ def set_differential_pair(
arg.append(arg2)

try:
os.remove(tmpfile1)
Path(tmpfile1).unlink()
except Exception: # pragma: no cover
self.logger.warning("ERROR: Cannot remove temp files.")

Expand All @@ -1400,7 +1400,7 @@ def load_diff_pairs_from_file(self, input_file):
Parameters
----------
input_file : str
input_file : str or :class:`pathlib.Path`
Full qualified name of the file containing the differential pairs definition.
Returns
Expand All @@ -1412,19 +1412,19 @@ def load_diff_pairs_from_file(self, input_file):
----------
>>> oDesign.LoadDiffPairsFromFile
"""
if not os.path.isfile(input_file): # pragma: no cover
if not Path(input_file).is_file(): # pragma: no cover
raise ValueError(f"{input_file}: The specified file could not be found.")

try:
new_file = os.path.join(os.path.dirname(input_file), generate_unique_name("temp") + ".txt")
new_file = Path(input_file).parent / str(generate_unique_name("temp") + ".txt")
with open_file(input_file, "r") as file:
filedata = file.read().splitlines()
with io.open(new_file, "w", newline="\n") as fh:
for line in filedata:
fh.write(line + "\n")

self.odesign.LoadDiffPairsFromFile(new_file)
os.remove(new_file)
self.odesign.LoadDiffPairsFromFile(str(new_file))
new_file.unlink()
except Exception: # pragma: no cover
return False
return True
Expand All @@ -1437,7 +1437,7 @@ def save_diff_pairs_to_file(self, output_file):
Parameters
----------
output_file : str
output_file : str or :class:`pathlib.Path`
Full qualified name of the file to save the differential pairs definition to.
Returns
Expand All @@ -1449,17 +1449,17 @@ def save_diff_pairs_to_file(self, output_file):
----------
>>> oDesign.SaveDiffPairsToFile
"""
self.odesign.SaveDiffPairsToFile(output_file)
self.odesign.SaveDiffPairsToFile(str(output_file))

return os.path.isfile(output_file)
return Path(output_file).is_file()

@pyaedt_function_handler(netlist_file="input_file", datablock_name="name")
def add_netlist_datablock(self, input_file, name=None):
"""Add a new netlist data block to the circuit schematic.
Parameters
----------
input_file : str
input_file : str or :class:`pathlib.Path`
Path to the netlist file.
name : str, optional
Name of the data block.
Expand All @@ -1469,15 +1469,15 @@ def add_netlist_datablock(self, input_file, name=None):
bool
``True`` when successful, ``False`` when failed.
"""
if not os.path.exists(input_file):
if not Path(input_file).exists():
self.logger.error("Netlist File doesn't exists")
return False
if not name:
name = generate_unique_name("Inc")

tmp_oModule = self.odesign.GetModule("DataBlock")
tmp_oModule.AddNetlistDataBlock(
["NAME:DataBlock", "name:=", name, "filename:=", input_file, "filelocation:=", 0]
["NAME:DataBlock", "name:=", name, "filename:=", str(input_file), "filelocation:=", 0]
)
return True

Expand All @@ -1487,41 +1487,43 @@ def browse_log_file(self, input_file=None):
Parameters
----------
input_file : str, optional
input_file : str or :class:`pathlib.Path`, optional
File path to save the new log file to. The default is the ``pyaedt`` folder.
Returns
-------
str
File Path.
"""
if input_file and not os.path.exists(os.path.normpath(input_file)):
if input_file and not Path(input_file).exists():
self.logger.error("Path does not exist.")
return None
elif not input_file:
input_file = os.path.join(os.path.normpath(self.working_directory), "logfile")
if not os.path.exists(input_file):
os.mkdir(input_file)
input_file = Path(self.working_directory) / "logfile"
if not Path(input_file).exists():
Path(input_file).mkdir()

results_path = os.path.join(os.path.normpath(self.results_directory), self.design_name)
results_temp_path = os.path.join(results_path, "temp")
results_path = Path(self.results_directory) / self.design_name
results_temp_path = Path(results_path) / "temp"

# Check if .log exist in temp folder
if os.path.exists(results_temp_path) and search_files(results_temp_path, "*.log"):
if Path(results_temp_path).exists() and search_files(str(results_temp_path), "*.log"):
# Check the most recent
files = search_files(results_temp_path, "*.log")
latest_file = max(files, key=os.path.getctime)
elif os.path.exists(results_path) and search_files(results_path, "*.log"):
files = search_files(str(results_temp_path), "*.log")
files = [Path(f) for f in files]
latest_file = max(files, key=lambda f: str(f.stat().st_ctime))
elif Path(results_path).exists() and search_files(str(results_path), "*.log"):
# Check the most recent
files = search_files(results_path, "*.log")
latest_file = max(files, key=os.path.getctime)
files = search_files(str(results_path), "*.log")
files = [Path(f) for f in files]
latest_file = max(files, key=lambda f: str(f.stat().st_ctime))
else:
self.logger.error("Design not solved")
return None

shutil.copy(latest_file, input_file)
filename = os.path.basename(latest_file)
return os.path.join(input_file, filename)
filename = Path(latest_file).name
return Path(input_file) / filename

@pyaedt_function_handler()
def connect_circuit_models_from_multi_zone_cutout(
Expand Down Expand Up @@ -1694,7 +1696,7 @@ def create_tdr_schematic_from_snp(
if isinstance(input_file, type(Hfss3dLayout)):
touchstone_path = input_file.export_touchstone()
else:
touchstone_path = input_file
touchstone_path = str(input_file)

sub = self.modeler.components.create_touchstone_component(touchstone_path)
center_x = sub.location[0]
Expand Down Expand Up @@ -1834,7 +1836,7 @@ def create_lna_schematic_from_snp(
if isinstance(input_file, type(Hfss3dLayout)):
touchstone_path = input_file.export_touchstone()
else:
touchstone_path = input_file
touchstone_path = str(input_file)

sub = self.modeler.components.create_touchstone_component(touchstone_path)

Expand Down Expand Up @@ -2089,11 +2091,11 @@ def create_ibis_schematic_from_snp(
if isinstance(input_file, type(Hfss3dLayout)):
touchstone_path = input_file.export_touchstone()
else:
touchstone_path = input_file
touchstone_path = str(input_file)

sub = self.modeler.components.create_touchstone_component(touchstone_path)
return self.create_ibis_schematic_from_pins(
ibis_tx_file=ibis_tx_file,
ibis_tx_file=str(ibis_tx_file),
ibis_rx_file=ibis_rx_file,
tx_buffer_name=tx_buffer_name,
rx_buffer_name=rx_buffer_name,
Expand Down Expand Up @@ -2441,7 +2443,7 @@ def create_schematic_from_asc_file(self, input_file, config_file=None):
Parameters
----------
input_file : str
input_file : str or :class:`pathlib.Path`
Path to asc file.
config_file : str, optional
Path to configuration file to map components. Default is None which uses internal mapping.
Expand All @@ -2455,7 +2457,7 @@ def create_schematic_from_asc_file(self, input_file, config_file=None):

scale = 2.54e-3 / (16 / factor)

flag, wire_xy, symbol = self._parse_asc_file(input_file=input_file, l_scale=scale, c_scale=scale)
flag, wire_xy, symbol = self._parse_asc_file(input_file=str(input_file), l_scale=scale, c_scale=scale)
for i in flag:
if i[2] == "0":
angle = 0
Expand All @@ -2470,9 +2472,7 @@ def create_schematic_from_asc_file(self, input_file, config_file=None):
self.modeler.schematic.create_interface_port(name=i[2], location=[i[0], i[1]])

if not config_file:
configuration = read_configuration_file(
os.path.join(os.path.dirname(__file__), "misc", "asc_circuit_mapping.json")
)
configuration = read_configuration_file(str(Path(__file__).parent / "misc" / "asc_circuit_mapping.json"))
else:
configuration = read_configuration_file(config_file)

Expand Down Expand Up @@ -2618,7 +2618,7 @@ def import_table(
Parameters
----------
input_file : str
input_file : str or :class:`pathlib.Path`
Full path to the file.
link : bool, optional
Whether to link the file to the solution. The default is ``False``.
Expand Down
18 changes: 11 additions & 7 deletions src/ansys/aedt/core/modeler/circuits/primitives_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import math
import os
from pathlib import Path
import secrets
import warnings

Expand Down Expand Up @@ -966,18 +967,21 @@ def create_touchstone_component(
--------
>>> from ansys.aedt.core import Circuit
>>> from pathlib import Path
>>> cir = Circuit()
>>> comps = cir.modeler.components
>>> s_parameter_path = os.path.join("your_path", "s_param_file_name.s4p")
>>> s_parameter_path = Path("your_path") / "s_param_file_name.s4p"
>>> circuit_comp = comps.create_touchstone_component(s_parameter_path, location=[0.0, 0.0], show_bitmap=False)
"""
if not os.path.exists(model_name):
if not Path(model_name):
raise FileNotFoundError("File not found.")
model_name = self.create_model_from_touchstone(model_name, show_bitmap=show_bitmap)
model_name = self.create_model_from_touchstone(str(model_name), show_bitmap=show_bitmap)
if location is None:
location = []
xpos, ypos = self._get_location(location)
id = self.create_unique_id()
if Path(model_name).exists():
model_name = self.create_model_from_touchstone(str(model_name), show_bitmap=show_bitmap)
arg1 = ["NAME:ComponentProps", "Name:=", model_name, "Id:=", str(id)]
arg2 = ["NAME:Attributes", "Page:=", 1, "X:=", xpos, "Y:=", ypos, "Angle:=", angle, "Flip:=", False]
id = self.oeditor.CreateComponent(arg1, arg2)
Expand All @@ -997,7 +1001,7 @@ def create_nexxim_state_space_component(
Parameters
----------
model_name : str
model_name : str, Path
Name of the Touchstone model or full path to touchstone file.
If full touchstone is provided then, new model will be created.
num_terminal : int
Expand All @@ -1020,14 +1024,14 @@ def create_nexxim_state_space_component(
>>> oEditor.CreateComponent
"""
if not os.path.exists(model_name):
if not Path(model_name):
raise FileNotFoundError("File not found.")
model_name = self.create_model_from_nexxim_state_space(model_name, num_terminal)
model_name = self.create_model_from_nexxim_state_space(str(model_name), num_terminal)
if location is None:
location = []
xpos, ypos = self._get_location(location)
id = self.create_unique_id()
arg1 = ["NAME:ComponentProps", "Name:=", model_name, "Id:=", str(id)]
arg1 = ["NAME:ComponentProps", "Name:=", str(model_name), "Id:=", str(id)]
arg2 = ["NAME:Attributes", "Page:=", 1, "X:=", xpos, "Y:=", ypos, "Angle:=", angle, "Flip:=", False]
self.oeditor.CreateComponent(arg1, arg2)
self.add_id_to_component(id)
Expand Down
Loading

0 comments on commit 6dc4852

Please sign in to comment.