Skip to content

Added few methods to allow IFFT of SBR+ Frequency domain data #1013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8,816 changes: 8,816 additions & 0 deletions _unittest/example_models/poc_scat_small.aedt

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions _unittest/test_12_PostProcessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
test_project_name = "coax_setup_solved"
test_field_name = "Potter_Horn"
test_circuit_name = "Switching_Speed_FET_And_Diode"
sbr_file = "poc_scat_small"


class TestClass(BasisTest, object):
Expand All @@ -37,6 +38,7 @@ def setup_class(self):
self, project_name=test_circuit_name, design_name="Diode", application=Circuit
)
self.diff_test = Circuit(designname="diff", projectname=self.circuit_test.project_name)
self.sbr_test = BasisTest.add_app(self, project_name=sbr_file)

def teardown_class(self):
BasisTest.my_teardown(self)
Expand Down Expand Up @@ -381,3 +383,28 @@ def test_54_reload(self):
self.aedtapp.save_project()
app2 = Hfss(self.aedtapp.project_name)
assert len(app2.post.field_plots) == len(self.aedtapp.post.field_plots)

@pytest.mark.skipif(is_ironpython, reason="plot_scene method is not supported in ironpython")
def test_55_time_plot(self):
self.sbr_test.analyze_nominal()
solution_data = self.sbr_test.post.get_solution_data(
expressions=["NearEX", "NearEY", "NearEZ"],
variations={"_u": ["All"], "_v": ["All"], "Freq": ["All"]},
context="Near_Field",
report_category="Near Fields",
)
assert solution_data
t_matrix = solution_data.ifft("NearE", window=True)
assert t_matrix.any()
frames_list = solution_data.ifft_to_file(
coord_system_center=[-0.15, 0, 0], db_val=True, csv_dir=os.path.join(self.sbr_test.working_directory, "csv")
)
assert os.path.exists(frames_list)
self.sbr_test.post.plot_scene(
frames_list,
os.path.join(self.sbr_test.working_directory, "animation.gif"),
norm_index=5,
dy_rng=35,
show=False,
)
assert os.path.exists(os.path.join(self.sbr_test.working_directory, "animation.gif"))
1 change: 0 additions & 1 deletion _unittest/test_17_SBR.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ def test_09_add_doppler_sweep(self):
assert "PulseSweep" in sweep.name
assert setup.props["SbrRangeDopplerWaveformType"] == "PulseDoppler"
assert sweep.props["Sim. Setups"] == [setup.name]
assert sweep.props["Sim. Setups"] == [setup.name]

def test_10_add_chirp_sweep(self):
setup, sweep = self.aedtapp.create_sbr_chirp_i_doppler_setup(sweep_time_duration=20)
Expand Down
57 changes: 57 additions & 0 deletions examples/02-HFSS/SBR_Time_Plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
HFSS to SBR+ Time Plot
----------------------
This example shows how you can use PyAEDT to create an SBR+ time animation
and save to gif file. This example will work only on CPython.
"""

###############################################################################
# Import Packages
# ~~~~~~~~~~~~~~~
# For this example we will need Hfss package only

import os
from pyaedt import Hfss, examples

project_file = examples.download_sbr_time()

hfss = Hfss(project_file, specified_version="2022.1", non_graphical=True, new_desktop_session=True)

hfss.analyze_nominal()

###############################################################################
# Get Solution Data
# ~~~~~~~~~~~~~~~~~
# After Simulation is performed the solutions can be loaded in solution_data

solution_data = hfss.post.get_solution_data(expressions=["NearEX", "NearEY", "NearEZ"],
variations={"_u": ["All"], "_v": ["All"], "Freq": ["All"]},
context="Near_Field",
report_category="Near Fields")

###############################################################################
# Compute IFFT
# ~~~~~~~~~~~~
# Description
t_matrix = solution_data.ifft("NearE", window=True)


###############################################################################
# Export IFFT to csv files
# ~~~~~~~~~~~~~~~~~~~~~~~~
# Description
frames_list_file = solution_data.ifft_to_file(coord_system_center=[-0.15, 0, 0], db_val=True,
csv_dir=os.path.join(hfss.working_directory, "csv"))

###############################################################################
# Plot the Scene
# ~~~~~~~~~~~~~~
# Description

hfss.post.plot_scene(frames_list_file, os.path.join(hfss.working_directory, "animation.gif"), norm_index=15, dy_rng=35,
show=False)


hfss.release_desktop()


29 changes: 29 additions & 0 deletions pyaedt/examples/downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,35 @@ def download_sbr(destination=None):
return _download_file("sbr", "Cassegrain.aedt", destination)


def download_sbr_time(destination=None):
"""Download an example of SBR+ Time domain animation and return the def path.

Examples files are downloaded to a persistent cache to avoid
re-downloading the same file twice.

Parameters
----------
destination : str, optional
Path where files will be downloaded. Optional. Default is user temp folder.

Returns
-------
str
Path to the example file.

Examples
--------
Download an example result file and return the path of the file

>>> from pyaedt import examples
>>> path = examples.download_sbr_time()
>>> path
'C:/Users/user/AppData/local/temp/pyaedtexamples/sbr/poc_scat_small.aedt'
"""

return _download_file("sbr", "poc_scat_small.aedt", destination)


def download_icepak(destination=None):
"""Download an example of Icepak Array and return the def path.

Expand Down
1 change: 1 addition & 0 deletions pyaedt/generic/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def is_float(istring):
return 0


@pyaedt_function_handler()
def plot_polar_chart(
plot_data, size=(2000, 1000), show_legend=True, xlabel="", ylabel="", title="", snapshot_path=None
):
Expand Down
63 changes: 63 additions & 0 deletions pyaedt/modules/AdvancedPostProcessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,3 +693,66 @@ def create_3d_plot(
X, Y, Z, rstride=1, cstride=1, cmap=plt.get_cmap("jet"), linewidth=0, antialiased=True, alpha=0.5
)
fig1.set_size_inches(10, 10)

@pyaedt_function_handler()
def plot_scene(self, frames_list, output_gif_path, norm_index=0, dy_rng=0, fps=30, show=True):
"""Plot the current model 3D scene with overlapping animation coming from a file list and save the gif.


Parameters
----------
frames_list : list or str
File list containing animation frames to plot in csv format or
path to a txt index file containing full path to csv files.
output_gif_path : str
Full path to output gif file.
norm_index : int, optional
Pick the frame to use to normalize your images.
Data is already saved as dB : 100 for usual traffic scenes.
dy_rng : int, optional
Specify how many dB below you would like to specify the range_min.
Tweak this a couple of times with small number of frames.
fps : int, optional
Frames per Second.
show : bool, optional
Either if show or only export gif.

Returns
-------

"""
if isinstance(frames_list, str) and os.path.exists(frames_list):
with open(frames_list, "r") as f:
lines = f.read()
temp_list = lines.splitlines()
frames_paths_list = [i for i in temp_list]
elif isinstance(frames_list, str):
self.logger.error("Path doesn't exists")
return False
else:
frames_paths_list = frames_list
scene = self.plot_model_obj(show=False)

norm_data = np.loadtxt(frames_paths_list[norm_index], skiprows=1, delimiter=",")
norm_val = norm_data[:, -1]
v_max = np.max(norm_val)
v_min = v_max - dy_rng
scene.add_frames_from_file(frames_paths_list, log_scale=False, color_map="jet", header_lines=1, opacity=0.8)

# Specifying the attributes of the scene through the ModelPlotter object
scene.off_screen = not show
scene.isometric_view = False
scene.range_min = v_min
scene.range_max = v_max
scene.show_grid = False
scene.windows_size = [1920, 1080]
scene.show_legend = False
scene.show_bounding_box = False
scene.legend = False
scene.frame_per_seconds = fps
scene.camera_position = "yz"
scene.zoom = 2
scene.bounding_box = False
scene.color_bar = False
scene.gif_file = output_gif_path # This gif may be a bit slower so we can speed it up a bit
scene.animate()
Loading