Skip to content

Commit 6dc4852

Browse files
anur7SMoraisAnsyspyansys-ci-botSamuelopez-ansys
authored
REFACTOR: Pathlib refactor: circuit.py (#5842)
Co-authored-by: Sébastien Morais <[email protected]> Co-authored-by: pyansys-ci-bot <[email protected]> Co-authored-by: Samuelopez-ansys <[email protected]>
1 parent cf1d873 commit 6dc4852

File tree

7 files changed

+104
-97
lines changed

7 files changed

+104
-97
lines changed

doc/changelog.d/5842.miscellaneous.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Pathlib refactor: circuit.py

src/ansys/aedt/core/application/analysis_hf.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,9 @@ def export_touchstone(
377377
----------
378378
>>> oDesign.ExportNetworkData
379379
"""
380+
if output_file is not None:
381+
output_file = str(output_file)
382+
380383
return self._app._export_touchstone(
381384
setup_name=setup,
382385
sweep_name=sweep,

src/ansys/aedt/core/circuit.py

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
import io
2828
import math
29-
import os
3029
from pathlib import Path
3130
import re
3231
import shutil
@@ -453,7 +452,7 @@ def get_ibis_model_from_file(self, input_file, is_ami=False):
453452
454453
Parameters
455454
----------
456-
input_file : str
455+
input_file : str or :class:`pathlib.Path`
457456
Path of the IBIS file.
458457
is_ami : bool, optional
459458
Whether the file to import is an IBIS AMI file. The
@@ -465,9 +464,9 @@ def get_ibis_model_from_file(self, input_file, is_ami=False):
465464
IBIS object exposing all data from the IBIS file.
466465
"""
467466
if is_ami:
468-
reader = ibis_reader.AMIReader(input_file, self)
467+
reader = ibis_reader.AMIReader(str(input_file), self)
469468
else:
470-
reader = ibis_reader.IbisReader(input_file, self)
469+
reader = ibis_reader.IbisReader(str(input_file), self)
471470
reader.parse_ibis_file()
472471
return reader.ibis_model
473472

@@ -862,7 +861,7 @@ def export_fullwave_spice(
862861
Name of the setup if it is a design. The default is ``None``.
863862
is_solution_file : bool, optional
864863
Whether it is an imported solution file. The default is ``False``.
865-
filename : str, optional
864+
filename : str or :class:`pathlib.Path`, optional
866865
Full path and name for exporting the HSpice file.
867866
The default is ``None``, in which case the file is exported to the working directory.
868867
passivity : bool, optional
@@ -891,13 +890,14 @@ def export_fullwave_spice(
891890
if not design:
892891
design = self.design_name
893892
if not filename:
894-
filename = os.path.join(self.working_directory, self.design_name + ".sp")
893+
filename = Path(self.working_directory) / f"{self.design_name}.sp"
895894
if is_solution_file:
896895
setup = design
897896
design = ""
898897
else:
899898
if not setup:
900899
setup = self.nominal_sweep
900+
file_path = Path(filename)
901901
self.onetwork_data_explorer.ExportFullWaveSpice(
902902
design,
903903
is_solution_file,
@@ -945,11 +945,11 @@ def export_fullwave_spice(
945945
"SYZDataInAutoMode:=",
946946
False,
947947
"ExportDirectory:=",
948-
os.path.dirname(filename) + "\\",
948+
str(file_path.parent) + "\\",
949949
"ExportSpiceFileName:=",
950-
os.path.basename(filename),
950+
file_path.name,
951951
"FullwaveSpiceFileName:=",
952-
os.path.basename(filename),
952+
file_path.name,
953953
"UseMultipleCores:=",
954954
True,
955955
"NumberOfCores:=",
@@ -1247,7 +1247,7 @@ def assign_voltage_frequency_dependent_excitation_to_ports(self, ports, input_fi
12471247
----------
12481248
ports : list
12491249
List of circuit ports to assign to the frequency dependent excitation.
1250-
input_file : str
1250+
input_file : str or :class:`pathlib.Path`
12511251
Path to the frequency dependent file.
12521252
12531253
Returns
@@ -1259,7 +1259,7 @@ def assign_voltage_frequency_dependent_excitation_to_ports(self, ports, input_fi
12591259
----------
12601260
>>> oDesign.UpdateSources
12611261
"""
1262-
if not os.path.exists(input_file) or os.path.splitext(input_file)[1] != ".fds":
1262+
if not Path(input_file).exists() or Path(input_file).suffix != ".fds":
12631263
self.logger.error("Introduced file is not correct. Check path and format.")
12641264
return False
12651265

@@ -1348,9 +1348,9 @@ def set_differential_pair(
13481348
arg.append("Pair:=")
13491349
arg.append(arg1)
13501350

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

13561356
old_arg = []
@@ -1381,7 +1381,7 @@ def set_differential_pair(
13811381
arg.append(arg2)
13821382

13831383
try:
1384-
os.remove(tmpfile1)
1384+
Path(tmpfile1).unlink()
13851385
except Exception: # pragma: no cover
13861386
self.logger.warning("ERROR: Cannot remove temp files.")
13871387

@@ -1400,7 +1400,7 @@ def load_diff_pairs_from_file(self, input_file):
14001400
14011401
Parameters
14021402
----------
1403-
input_file : str
1403+
input_file : str or :class:`pathlib.Path`
14041404
Full qualified name of the file containing the differential pairs definition.
14051405
14061406
Returns
@@ -1412,19 +1412,19 @@ def load_diff_pairs_from_file(self, input_file):
14121412
----------
14131413
>>> oDesign.LoadDiffPairsFromFile
14141414
"""
1415-
if not os.path.isfile(input_file): # pragma: no cover
1415+
if not Path(input_file).is_file(): # pragma: no cover
14161416
raise ValueError(f"{input_file}: The specified file could not be found.")
14171417

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

1426-
self.odesign.LoadDiffPairsFromFile(new_file)
1427-
os.remove(new_file)
1426+
self.odesign.LoadDiffPairsFromFile(str(new_file))
1427+
new_file.unlink()
14281428
except Exception: # pragma: no cover
14291429
return False
14301430
return True
@@ -1437,7 +1437,7 @@ def save_diff_pairs_to_file(self, output_file):
14371437
14381438
Parameters
14391439
----------
1440-
output_file : str
1440+
output_file : str or :class:`pathlib.Path`
14411441
Full qualified name of the file to save the differential pairs definition to.
14421442
14431443
Returns
@@ -1449,17 +1449,17 @@ def save_diff_pairs_to_file(self, output_file):
14491449
----------
14501450
>>> oDesign.SaveDiffPairsToFile
14511451
"""
1452-
self.odesign.SaveDiffPairsToFile(output_file)
1452+
self.odesign.SaveDiffPairsToFile(str(output_file))
14531453

1454-
return os.path.isfile(output_file)
1454+
return Path(output_file).is_file()
14551455

14561456
@pyaedt_function_handler(netlist_file="input_file", datablock_name="name")
14571457
def add_netlist_datablock(self, input_file, name=None):
14581458
"""Add a new netlist data block to the circuit schematic.
14591459
14601460
Parameters
14611461
----------
1462-
input_file : str
1462+
input_file : str or :class:`pathlib.Path`
14631463
Path to the netlist file.
14641464
name : str, optional
14651465
Name of the data block.
@@ -1469,15 +1469,15 @@ def add_netlist_datablock(self, input_file, name=None):
14691469
bool
14701470
``True`` when successful, ``False`` when failed.
14711471
"""
1472-
if not os.path.exists(input_file):
1472+
if not Path(input_file).exists():
14731473
self.logger.error("Netlist File doesn't exists")
14741474
return False
14751475
if not name:
14761476
name = generate_unique_name("Inc")
14771477

14781478
tmp_oModule = self.odesign.GetModule("DataBlock")
14791479
tmp_oModule.AddNetlistDataBlock(
1480-
["NAME:DataBlock", "name:=", name, "filename:=", input_file, "filelocation:=", 0]
1480+
["NAME:DataBlock", "name:=", name, "filename:=", str(input_file), "filelocation:=", 0]
14811481
)
14821482
return True
14831483

@@ -1487,41 +1487,43 @@ def browse_log_file(self, input_file=None):
14871487
14881488
Parameters
14891489
----------
1490-
input_file : str, optional
1490+
input_file : str or :class:`pathlib.Path`, optional
14911491
File path to save the new log file to. The default is the ``pyaedt`` folder.
14921492
14931493
Returns
14941494
-------
14951495
str
14961496
File Path.
14971497
"""
1498-
if input_file and not os.path.exists(os.path.normpath(input_file)):
1498+
if input_file and not Path(input_file).exists():
14991499
self.logger.error("Path does not exist.")
15001500
return None
15011501
elif not input_file:
1502-
input_file = os.path.join(os.path.normpath(self.working_directory), "logfile")
1503-
if not os.path.exists(input_file):
1504-
os.mkdir(input_file)
1502+
input_file = Path(self.working_directory) / "logfile"
1503+
if not Path(input_file).exists():
1504+
Path(input_file).mkdir()
15051505

1506-
results_path = os.path.join(os.path.normpath(self.results_directory), self.design_name)
1507-
results_temp_path = os.path.join(results_path, "temp")
1506+
results_path = Path(self.results_directory) / self.design_name
1507+
results_temp_path = Path(results_path) / "temp"
15081508

15091509
# Check if .log exist in temp folder
1510-
if os.path.exists(results_temp_path) and search_files(results_temp_path, "*.log"):
1510+
if Path(results_temp_path).exists() and search_files(str(results_temp_path), "*.log"):
15111511
# Check the most recent
1512-
files = search_files(results_temp_path, "*.log")
1513-
latest_file = max(files, key=os.path.getctime)
1514-
elif os.path.exists(results_path) and search_files(results_path, "*.log"):
1512+
files = search_files(str(results_temp_path), "*.log")
1513+
files = [Path(f) for f in files]
1514+
latest_file = max(files, key=lambda f: str(f.stat().st_ctime))
1515+
elif Path(results_path).exists() and search_files(str(results_path), "*.log"):
15151516
# Check the most recent
1516-
files = search_files(results_path, "*.log")
1517-
latest_file = max(files, key=os.path.getctime)
1517+
files = search_files(str(results_path), "*.log")
1518+
files = [Path(f) for f in files]
1519+
latest_file = max(files, key=lambda f: str(f.stat().st_ctime))
15181520
else:
15191521
self.logger.error("Design not solved")
15201522
return None
15211523

15221524
shutil.copy(latest_file, input_file)
1523-
filename = os.path.basename(latest_file)
1524-
return os.path.join(input_file, filename)
1525+
filename = Path(latest_file).name
1526+
return Path(input_file) / filename
15251527

15261528
@pyaedt_function_handler()
15271529
def connect_circuit_models_from_multi_zone_cutout(
@@ -1694,7 +1696,7 @@ def create_tdr_schematic_from_snp(
16941696
if isinstance(input_file, type(Hfss3dLayout)):
16951697
touchstone_path = input_file.export_touchstone()
16961698
else:
1697-
touchstone_path = input_file
1699+
touchstone_path = str(input_file)
16981700

16991701
sub = self.modeler.components.create_touchstone_component(touchstone_path)
17001702
center_x = sub.location[0]
@@ -1834,7 +1836,7 @@ def create_lna_schematic_from_snp(
18341836
if isinstance(input_file, type(Hfss3dLayout)):
18351837
touchstone_path = input_file.export_touchstone()
18361838
else:
1837-
touchstone_path = input_file
1839+
touchstone_path = str(input_file)
18381840

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

@@ -2089,11 +2091,11 @@ def create_ibis_schematic_from_snp(
20892091
if isinstance(input_file, type(Hfss3dLayout)):
20902092
touchstone_path = input_file.export_touchstone()
20912093
else:
2092-
touchstone_path = input_file
2094+
touchstone_path = str(input_file)
20932095

20942096
sub = self.modeler.components.create_touchstone_component(touchstone_path)
20952097
return self.create_ibis_schematic_from_pins(
2096-
ibis_tx_file=ibis_tx_file,
2098+
ibis_tx_file=str(ibis_tx_file),
20972099
ibis_rx_file=ibis_rx_file,
20982100
tx_buffer_name=tx_buffer_name,
20992101
rx_buffer_name=rx_buffer_name,
@@ -2441,7 +2443,7 @@ def create_schematic_from_asc_file(self, input_file, config_file=None):
24412443
24422444
Parameters
24432445
----------
2444-
input_file : str
2446+
input_file : str or :class:`pathlib.Path`
24452447
Path to asc file.
24462448
config_file : str, optional
24472449
Path to configuration file to map components. Default is None which uses internal mapping.
@@ -2455,7 +2457,7 @@ def create_schematic_from_asc_file(self, input_file, config_file=None):
24552457

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

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

24722474
if not config_file:
2473-
configuration = read_configuration_file(
2474-
os.path.join(os.path.dirname(__file__), "misc", "asc_circuit_mapping.json")
2475-
)
2475+
configuration = read_configuration_file(str(Path(__file__).parent / "misc" / "asc_circuit_mapping.json"))
24762476
else:
24772477
configuration = read_configuration_file(config_file)
24782478

@@ -2618,7 +2618,7 @@ def import_table(
26182618
26192619
Parameters
26202620
----------
2621-
input_file : str
2621+
input_file : str or :class:`pathlib.Path`
26222622
Full path to the file.
26232623
link : bool, optional
26242624
Whether to link the file to the solution. The default is ``False``.

src/ansys/aedt/core/modeler/circuits/primitives_circuit.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import math
2626
import os
27+
from pathlib import Path
2728
import secrets
2829
import warnings
2930

@@ -966,18 +967,21 @@ def create_touchstone_component(
966967
--------
967968
968969
>>> from ansys.aedt.core import Circuit
970+
>>> from pathlib import Path
969971
>>> cir = Circuit()
970972
>>> comps = cir.modeler.components
971-
>>> s_parameter_path = os.path.join("your_path", "s_param_file_name.s4p")
973+
>>> s_parameter_path = Path("your_path") / "s_param_file_name.s4p"
972974
>>> circuit_comp = comps.create_touchstone_component(s_parameter_path, location=[0.0, 0.0], show_bitmap=False)
973975
"""
974-
if not os.path.exists(model_name):
976+
if not Path(model_name):
975977
raise FileNotFoundError("File not found.")
976-
model_name = self.create_model_from_touchstone(model_name, show_bitmap=show_bitmap)
978+
model_name = self.create_model_from_touchstone(str(model_name), show_bitmap=show_bitmap)
977979
if location is None:
978980
location = []
979981
xpos, ypos = self._get_location(location)
980982
id = self.create_unique_id()
983+
if Path(model_name).exists():
984+
model_name = self.create_model_from_touchstone(str(model_name), show_bitmap=show_bitmap)
981985
arg1 = ["NAME:ComponentProps", "Name:=", model_name, "Id:=", str(id)]
982986
arg2 = ["NAME:Attributes", "Page:=", 1, "X:=", xpos, "Y:=", ypos, "Angle:=", angle, "Flip:=", False]
983987
id = self.oeditor.CreateComponent(arg1, arg2)
@@ -997,7 +1001,7 @@ def create_nexxim_state_space_component(
9971001
9981002
Parameters
9991003
----------
1000-
model_name : str
1004+
model_name : str, Path
10011005
Name of the Touchstone model or full path to touchstone file.
10021006
If full touchstone is provided then, new model will be created.
10031007
num_terminal : int
@@ -1020,14 +1024,14 @@ def create_nexxim_state_space_component(
10201024
>>> oEditor.CreateComponent
10211025
10221026
"""
1023-
if not os.path.exists(model_name):
1027+
if not Path(model_name):
10241028
raise FileNotFoundError("File not found.")
1025-
model_name = self.create_model_from_nexxim_state_space(model_name, num_terminal)
1029+
model_name = self.create_model_from_nexxim_state_space(str(model_name), num_terminal)
10261030
if location is None:
10271031
location = []
10281032
xpos, ypos = self._get_location(location)
10291033
id = self.create_unique_id()
1030-
arg1 = ["NAME:ComponentProps", "Name:=", model_name, "Id:=", str(id)]
1034+
arg1 = ["NAME:ComponentProps", "Name:=", str(model_name), "Id:=", str(id)]
10311035
arg2 = ["NAME:Attributes", "Page:=", 1, "X:=", xpos, "Y:=", ypos, "Angle:=", angle, "Flip:=", False]
10321036
self.oeditor.CreateComponent(arg1, arg2)
10331037
self.add_id_to_component(id)

0 commit comments

Comments
 (0)