import csv
import math
import os
import time
from ansys_optical_automation.post_process.dpf_base import DataProcessingFramework
[docs]class DpfHdriViewer(DataProcessingFramework):
"""
Provides for launching Speos postprocessing software, Virtual reality lab.
This framework is used to interact with the software and automatically perform
analysis and postprocessing on the simulation results
"""
def __init__(self):
"""Initialize DPF as HDRIViewer."""
DataProcessingFramework.__init__(
self, extension=(".speos360", ".optisvr", ".xmp"), application="HDRIViewer.Application"
)
self.source_list = []
[docs] def get_source_list(self):
"""
Get the source list stored in the simulation result.
Returns
-------
list
List of sources available in the postprocessing file.
"""
self.source_list = []
if self.dpf_instance is not None:
total_sources = self.dpf_instance.GetNbSources
for layer in range(total_sources):
self.source_list.append(self.dpf_instance.GetSourceName(layer))
return self.source_list
else:
raise ImportError("Object is not a valid SpeosVRObject.")
def __export_vr_view(self, export_path, phi_angles=None, theta_angles=None):
"""
Export VR results for defined angles or all angles as image (JPG) files.
Parameters
----------
export_path : string
Path for exporting the set of JPG files. If this path does not exist,
it is created.
phi_angles : list of floats, optional
List of phi angles to export. The default is ``None``, in which case
all phi angles are exported.
theta_angles : list of floats, optional
List of theta angles to export. The default is ``None``, in which case
all theta angles are exported.
"""
if phi_angles is None and theta_angles is None:
"Export all angle combinations"
self.dpf_instance.Show(True)
self.dpf_instance.ExportAllObserverImages(export_path + "\\", 0)
else:
"Export angle combinations provided"
for count in range(len(phi_angles)):
try:
self.dpf_instance.SetSightDirection(phi_angles[count], theta_angles[count])
self.dpf_instance.Show(True)
self.dpf_instance.ExportObserverImage(
export_path
+ r"\image"
+ str(math.degrees([phi_angles[count]]))
+ str(math.degrees([theta_angles[count]]))
+ ".JPG"
)
except Exception as e:
raise TypeError(
str(phi_angles) + str(theta_angles) + " are not existing iin the file \n Details: " + e
)
[docs] def export_vr_views(self, export_path=None, phi_angles=None, theta_angles=None, config_ids=None):
"""
Export VR results for all or specific configurations for defined angles or all angles as image (JPG) files.
Parameters
----------
export_path : string
Path for exporting the JPG files. If this path does not exist,
it is created.
phi_angles : list of floats, optional
List of phi angles to export. The default is ``None``, in which case
all phi angles are exported.
theta_angles : list of floats, optional
List of theta angles to export. The default is ``None``, in which case
all theta angles are exported.
config_ids : list of positive integers or list of strings or a string or an integer, optional
List of configurations IDs to export. The default is ``None``, in which case all configuration
IDs are exported.
"""
if export_path is None:
export_path = os.path.dirname(self.file_path)
if config_ids is None:
"Export all configurations"
config_ids = self.dpf_instance.GetNbConfigurations
for config in range(config_ids):
self.dpf_instance.SetConfigurationById(config)
self.valid_dir(os.path.join(export_path, str(config)))
self.__export_vr_view(os.path.join(export_path, str(config)), phi_angles, theta_angles)
elif isinstance(config_ids, int):
try:
self.dpf_instance.SetConfigurationById(config_ids)
self.valid_dir(os.path.join(export_path, str(config_ids)))
self.__export_vr_view(os.path.join(export_path, str(config_ids)), phi_angles, theta_angles)
except Exception as e:
raise ValueError(str(config_ids) + " a non valid ID exists in the file \n Details: " + e)
elif isinstance(config_ids, str):
try:
self.dpf_instance.SetConfigurationByName(config_ids)
self.valid_dir(os.path.join(export_path, str(config_ids)))
self.__export_vr_view(os.path.join(export_path, str(config_ids)), phi_angles, theta_angles)
except Exception as e:
raise ValueError(config_ids + " does not exist in the file \n Details: " + e)
elif isinstance(config_ids, list):
for item in config_ids:
self.valid_dir(os.path.join(export_path, str(item)))
if isinstance(config_ids[0], int):
try:
self.dpf_instance.SetConfigurationById(item)
self.__export_vr_view(os.path.join(export_path, str(item)), phi_angles, theta_angles)
except Exception as e:
raise ValueError(str(item) + " a non valid ID exists in the file \n Details: " + e)
else:
try:
self.dpf_instance.SetConfigurationByName(item)
self.__export_vr_view(os.path.join(export_path, str(item)), phi_angles, theta_angles)
except Exception as e:
raise ValueError(item + " does not exist in the file \n Details: " + e)
[docs] def set_source_power(self, source, value):
"""
Set the source with power value provided.
Parameters
----------
source : int/str
source defined by id or name.
value : float
source power.
Returns
-------
"""
if len(self.source_list) == 0:
self.source_list = self.get_source_list()
if isinstance(source, int):
if source >= len(self.source_list):
msg = "source requested does not exist"
raise ValueError(msg)
self.dpf_instance.SetSourcePowerById(source, value)
else:
if source not in self.source_list:
msg = "source requested does not exist"
raise ValueError(msg)
self.dpf_instance.SetSourcePowerByName(source, value)
[docs] def set_source_ratio(self, source, value):
"""
Set the source with power ratio value provided.
Parameters
----------
source : int/str
source defined by id or name
value : float
source power ratio
Returns
-------
"""
if len(self.source_list) == 0:
self.source_list = self.get_source_list()
if isinstance(source, int):
if source >= len(self.source_list):
msg = "source requested does not exist"
raise ValueError(msg)
self.dpf_instance.SetSourceRatioById(source, value)
else:
if source not in self.source_list:
msg = "source requested does not exist"
raise ValueError(msg)
self.dpf_instance.SetSourceRatioByName(source, value)
[docs] def timeline_animation_run(self, csv_file):
"""
function to run animation in observer result.
Parameters
----------
csv_file : str
file path of time line csv file
Returns
-------
"""
source_list = self.source_list if len(self.source_list) != 0 else self.get_source_list()
csv_source_list = []
csv_source_animation = []
with open(csv_file) as file:
content = csv.reader(file, delimiter=",")
First_Row = True
for row in content:
if First_Row:
csv_source_list = [item for item in row][1:]
else:
csv_source_animation.append([float(item) for item in row])
First_Row = False
animation_time_step = csv_source_animation[1][0] - csv_source_animation[0][0]
if len(csv_source_list) != len(source_list):
msg = "selected timeline csv file does not match with the speos vr file"
raise ImportError(msg)
if set(csv_source_list) != set(source_list):
print("will assume source using index")
self.dpf_instance.Show(1)
while True:
for csv_source_config in csv_source_animation:
for source_idx, source in enumerate(csv_source_list):
self.set_source_power(source_idx, csv_source_config[source_idx + 1])
time.sleep(animation_time_step)
else:
print("will use name to set source in animation")
self.dpf_instance.Show(1)
while True:
for csv_source_config in csv_source_animation:
for source_idx, source in enumerate(csv_source_list):
self.set_source_power(source, csv_source_config[source_idx + 1])
time.sleep(animation_time_step)